diff --git a/AssetProcessorPlatformConfig.setreg b/AssetProcessorPlatformConfig.setreg deleted file mode 100644 index d3cf6d6272..0000000000 --- a/AssetProcessorPlatformConfig.setreg +++ /dev/null @@ -1,611 +0,0 @@ -{ - // ---- Enable/Disable platforms for the entire project. AssetProcessor will automatically add the current platform by default. - - // PLATFORM DEFINITIONS - // [Platform (unique identifier)] - // tags=(comma-seperated-tags) - // - // note: the 'identifier' of a platform is the word(s) following the "Platform" keyword (so [Platform pc] means identifier - // is 'pc' for example. This is used to name its assets folder in the cache and should be used in your bootstrap.cfg - // or your main.cpp to choose what assets to load for that particular platform. - // Its primary use is to enable additional non-host platforms (Ios, android...) that are not the current platform. - // note: 'tags' is a comma-seperated list of tags to tag the platform with that builders can inspect to decide what to do. - - // while builders can accept any tags you add in order to make decisions, common tags are - // tools - this platform can host the tools and editor and such - // renderer - this platform runs the client engine and renders on a GPU. If missing we could be on a server-only platform - // mobile - a mobile platform such as a set top box or phone with limited resources - // console - a console platform - // server - a server platform of some kind, usually headless, no renderer. - - "Amazon": { - "AssetProcessor": { - "Settings": { - "Platform pc": { - "tags": "tools,renderer,dx12,vulkan,null" - }, - "Platform es3": { - "tags": "android,mobile,renderer,vulkan" - }, - "Platform ios": { - "tags": "mobile,renderer,metal" - }, - "Platform osx_gl": { - "tags": "tools,renderer,metal,null" - }, - // this is an example of a headless platform that has no renderer. - // To use this you would still need to make sure 'assetplatform' in your startup params in your main() chooses this 'server' platform as your server 'assets' flavor - "Platform server": { - "tags": "server,dx12,vulkan" - }, - // this section allows you to turn on various platforms in addition to the host platform you're running on - // 'enabled' is AUTOMATICALLY TRUE for the current platform that you are running on, so it is not necessary to force it to true for that platform - // To enable any additional platform, just uncomment the appropriate line below. - "Platforms": { - //"pc": "enabled", - //"es3": "enabled", - //"ios": "enabled", - //"osx_gl": "enabled", - //"server": "enabled" - }, - // ---- The number of worker jobs, 0 means use the number of Logical Cores - "Jobs": { - "minJobs": 1, - "maxJobs": 0 - }, - // cacheServerAddress is the location of the asset server cache. - // Currently for a network share server this would be the absolute file path to the network share folder. - "Server": { - //"cacheServerAddress": "" - }, - - // ---- add any metadata file type here that needs to be monitored by the AssetProcessor. - // Modifying these meta file will cause the source asset to re-compile again. - // They are specified in the following format - // metadata extension=original extension to replace - // if the metadata extension does not replace the original, then the original can be blank - // so for example if your normal file is blah.tif and your metafile for that file is blah.tif.exportsettings - // then your declaration would be exportsettings= ; ie, it would be blank - // however if your metafile REPLACES the extension (for example, if you have the file blah.i_caf and its metafile is blah.exportsettings) - // then you specify the original extension here to narrow the scope. - // If a relative path to a specific file is provided instead of an extension, a change to the file will change all files - // with the associated extension (e.g. Animations/SkeletonList.xml=i_caf will cause all i_caf files to recompile when - // Animations/SkeletonList.xml within the current game project changes) - - "MetaDataTypes": { - "animsettings": "i_caf", - "Animations/SkeletonList.xml": "i_caf", - "cbc": "abc", - "fbx.assetinfo": "fbx" - }, - - // ---- add any folders to scan here. The priority order is the order they appear here - // available macros are - // @ROOT@ - the location of asset root - // @PROJECTROOT@ - the location of the project root, for example 'Q:\MyProjects\RPGSample' - // note that they are sorted by their 'order' value, and the lower the order the more important an asset is - // lower order numbers override higher ones. - // If specified, output will be prepended to every path found in that recognizer's watch folder. - // Note that you can also make the scan folder platform specific by using the keywords include and exclude. - // Both include and exclude can contain either platform tags, platform identifiers or both. - // if no include is specified, all currently enabled platforms are included by default. - // If includes ARE specified, it will be filtered down by the list of currently enabled platforms. - // "ScanFolder (unique identifier)": { - // "include": "(comma seperated platform tags or identifiers)", - // "exclude": "(comma seperated platform tags or identifiers)" - // } - // For example if you want to include a scan folder only for platforms that have the platform tags tools and renderer - // but omit it for platform osx_gl, you will have a scanfolder rule like - // "ScanFolder (unique identifier)": { - // "watch": "@ROOT@/foo", - // "include": "tools, renderer", - // "exclude": "osx_gl" - // } - - "ScanFolder Game": { - "watch": "@PROJECTROOT@", - "display": "@PROJECTNAME@", - "recursive": 1, - "order": 0 - }, - // gems will be auto-added from 100 onwards - "ScanFolder Root": { - "watch": "@ROOT@", - "recursive": 0, - "order": 10000 - }, - "ScanFolder Engine": { - "watch": "@ENGINEROOT@/Engine", - "recursive": 1, - "order": 20000 - }, - "ScanFolder Editor": { - "watch": "@ENGINEROOT@/Editor", - "output": "editor", - "recursive": 1, - "order": 30000, - "include": "tools,renderer" - }, - - // Excludes files that match the pattern or glob - // if you use a pattern, remember to escape your backslashes (\\) - "Exclude _LevelBackups": { - "pattern": ".*\\\\/Levels\\\\/.*\\\\/_savebackup\\\\/.*" - }, - "Exclude _LevelAutoBackups": { - "pattern": ".*\\\\/Levels\\\\/.*\\\\/_autobackup\\\\/.*" - }, - "Exclude HoldFiles": { - "pattern": ".*\\\\/Levels\\\\/.*_hold\\\\/.*" - }, - // note that $ has meaning to regex, so we escape it. - "Exclude TempFiles": { - "pattern": ".*\\\\/\\\\$tmp[0-9]*_.*" - }, - "Exclude AlembicCompressionTemplates": { - "pattern": ".*\\\\/Presets\\\\/GeomCache\\\\/.*" - }, - "Exclude TmpAnimationCompression": { - "pattern": ".*\\\\/Editor\\\\/Tmp\\\\/AnimationCompression\\\\/.*" - }, - "Exclude EventLog": { - "pattern": ".*\\\\/Editor\\\\/.*eventlog\\\\.xml" - }, - "Exclude GameGemsCode": { - "pattern": ".*\\\\/Gem\\\\/Code\\\\/.*" - }, - "Exclude GameGemsResources": { - "pattern": ".*\\\\/Gem\\\\/Resources\\\\/.*" - }, - "Exclude Private Certs": { - "pattern": ".*\\DynamicContent\\\\/Certificates\\\\/Private\\\\/.*" - }, - "Exclude CMakeLists": { - "pattern": ".*\\\\/CMakeLists.txt" - }, - "Exclude CMakeFiles": { - "pattern": ".*\\\\/.*\\\\.cmake" - }, - "Exclude User": { - "pattern": ".*/[Uu]ser/.*" - }, - "Exclude Build": { - "pattern": ".*/[Bb]uild/.*" - }, - "Exclude UserSettings": { - "pattern": ".*/UserSettings.xml" - }, - - // ------------------------------------------------------------------------------ - // Large Worlds Test - // ------------------------------------------------------------------------------ - "Exclude Work In Progress Folders": { - "pattern": ".*\\\\/WIP\\\\/.*" - }, - "Exclude Content Source Folders": { - "pattern": ".*\\\\/CONTENT_SOURCE\\\\/.*" - }, - "Exclude Art Source Folders": { - "pattern": ".*\\\\/ArtSource\\\\/.*" - }, - //------------------------------------------------------------------------------ - // RC params mapping examples - //------------------------------------------------------------------------------ - - // note that productAssetType is a means of setting the output asset Type (as in AZ::Data::AssetType) of a simple job - // and is the recommended way to specify that a certain kind of file (such as '*.myextension') becomes registered as the - // actual UUID of that type in the engine itself. - - // Use a regex for matching files, same params for all platforms - // "RC TGAs": { - // "pattern": ".+\\\\.tga$", - // "params": "/tga /texture" - //} - - // Use a glob, have special params for es3 platform - // "RC TIFFs": { - // "glob": "*.tif", - // "params": "/texture", - // "es3": "/pvrt" - //} - - // You can also modify a version to compile all matching files again - // By default the version is empty - // "RC tif": { - // "glob": "*.tif", - // "params": "\\someparams", - // "version": 1.0 - //} - // This will make the AssetProcessor compile all the .tif files again - - // you can also optionally supply a priority. - // this is used to sort jobs when no other external circumstance sorts them - // for example, copy jobs will be higher in priority than other jobs that are not copy jobs - // however if they're both copy jobs or both not, and no other circumstances apply, then priority will be used. - // default priority is zero if not specified - - // you can specify an option to skip processing for a file type based on the platform. - // for example, if you dont want to process tif files for ios, you can make tif files - // process on any platform except for ios: - // "RC tif": { - // "glob": "*.tif", - // "params": "\\someparams", - // "ios": "skip" - //} - - // you can specify an option to output product dependencies for a copy job. - // please note that you only need to set this option when cry code is required to parse the asset. - // otherwise product dependencies will be output automatically by the CopyDependencyBuilder. - // for example, if you want to output the product dependencies for font assets: - // "RC font": { - // "glob": "*.font", - // "params": "copy", - // "outputProductDependencies": true - //} - - // you can also specify an option to make all jobs critical that matches some pattern/glob. - // for example, if you want to make all png files critical than set critical to true. - // Note that by default all copy jobs are critical. - // Critical jobs are processed before non critical jobs and also prevent the runtime or editor from starting until they are all complete. - // "RC png": { - // "glob": "*.png", - // "params": "\\someparams", - // "critical": true - //} - - // you can also specify an option to make all the job store in the asset server cache location if you are running AP in server mode. - // For example, if you want to store all png jobs in the asset server cache location including their logs, you can set checkServer = true. - // The client(i.e if you are running AP in non-server mode) will also check for this flag to know which jobs to fetch from the asset server cache location. - // if unsucessful, it will process the job locally as usual. - // "RC png": { - // "glob": "*.png", - // "params": "\\someparams", - // "critical": true, - // "checkServer": true - //} - - // note that the FULL PATH to the file will be used as the match, not the relative path - // so ensure start your patterns with .* or as appropriate. - // Also, any rules which match will apply - so if you have two rules which both apply to PNG files for example - // but you only want one, you might want to use exclusion patterns: - - //Example: process everything EXCEPT the ones in the libs/ui folder with these params - // "RC png-normal": { - // "pattern": "(?!.*libs\\\\/ui\\\\/).*\\.png", - // "params": "/imagecompressor=CTSquish /streaming=0", - // "lockSource": true - //} - - //Example: Process everything in the libs/ui folder with linear color space - // "RC png-ui": { - // "pattern": "(.*libs\\\\/ui\\\\/).*\\.png", - // "params": "/imagecompressor=CTSquish /streaming=0 /colorspace=linear,linear", - // "lockSource": true - //} - - // More example Regexes: - // "pattern": "(?!(.*libs\\\\/ui\\\\/)|(.*editor\\\\/).*\\\\.png" - // This pattern will not match anything with editor/ or libs/ui/ in it - // "pattern": "((.*libs\\\\/ui\\\\/)|(.*editor\\\\/).*\\\\.png" - // This pattern will only match anything with editor/ or libs/ui/ in it - - // Give every [Section Name] its own unique Name or else they will overwrite each other! - "RC i_caf": { - "glob": "*.i_caf", - "params": "/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1", - // force server to send the 'pc' platform to RC.EXE so it compiles the same as PC. - "server": "/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1 /p=pc", - "priority": 5, - "productAssetType": "{6023CFF8-FCBA-4528-A8BF-6E0E10B9AB9C}" - }, - "RC caf": { - "glob": "*.caf", - "params": "copy", - "productAssetType": "{6023CFF8-FCBA-4528-A8BF-6E0E10B9AB9C}" - }, - "RC mp4": { - "glob": "*.mp4", - "params": "copy", - "productAssetType": "{DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}" - }, - "RC mkv": { - "glob": "*.mkv", - "params": "copy", - "productAssetType": "{DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}" - }, - "RC webm": { - "glob": "*.webm", - "params": "copy", - "productAssetType": "{DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}" - }, - "RC mov": { - "glob": "*.mov", - "params": "copy", - "productAssetType": "{DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}" - }, - "RC bk2": { - "glob": "*.bk2", - "params": "copy", - "productAssetType": "{BF4879B9-B893-41D2-80E9-24A7BDCD2B50}" - }, - "RC img": { - "glob": "*.img", - "params": "copy" - }, - "RC dba": { - "glob": "*.dba", - "params": "copy", - "productAssetType": "{511562BE-65A5-4538-A5F1-AC685366243E}", - "version": 2 - }, - "RC cgf": { - "glob": "*.cgf", - "params": "/VertexPositionFormat=exporter /VertexIndexFormat=u32", - // on server, feed rc.exe the param /p=pc to force it to compile assets for server platform in pc format. - "server": "/VertexPositionFormat=exporter /VertexIndexFormat=u32 /p=pc", - "lockSource": true, - "priority": 10 - // allow CGF files to compile first, so untextured models appear before their textures for faster startup - // other available params: /SplitLODs=1 - }, - "RC surfaceTagNameList": { - "glob": "*.surfaceTagNameList", - "params": "copy", - "productAssetType": "{A471B2A9-85FC-4993-842D-1881CBC03A2B}" - }, - "RC gradImageSettings": { - "glob": "*.gradimagesettings", - "params": "copy", - "productAssetType": "{B36FEB5C-41B6-4B58-A212-21EF5AEF523C}" - }, - "RC fbx": { - "glob": "*.fbx", - // Priority set to 9 so its "before" things like materials but after things like actors and motions (which build using a proper AssetBuilderSDK builder and thus are not in this file) - "priority": 9, - "version": 5 - }, - "RC chr": { - "glob": "*.chr", - "params": "copy", - "productAssetType": "{60161B46-21F0-4396-A4F0-F2CCF0664CDE}", - "version": 2 - }, - "RC skin": { - "glob": "*.skin", - "params": "copy" - }, - "RC cfi": { - "glob": "*.cfi", - "params": "copy" - }, - "RC cfx": { - "glob": "*.cfx", - "params": "copy" - }, - "RC cfr": { - "glob": "*.cfr", - "params": "copy" - }, - // Warning: If you change the VertexIndexFormat, make sure you update the vtx_idx typedef in Code\CryEngine\CryCommon\ProjectDefines.h - "RC abc": { - "glob": "*.abc", - "params": "/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u32", - "console": "/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u32", - "mobile": "/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u16", - "version": 3, - "server": "skip" - }, - "RC png-entityicon": { - "pattern": "(.*EntityIcons\\\\/).*\\\\.png", - "productAssetType": "{3436C30E-E2C5-4C3B-A7B9-66C94A28701B}", - "params": "skip", - "tools": "copy" - }, - "RC usm": { - "glob": "*.usm", - "params": "copy", - "server": "skip" - }, - "RC animevents": { - "glob": "*.animevents", - "params": "copy", - "productAssetType": "{C1D209C1-F81A-4586-A34E-1615995F9F3F}", - "version": 2 - }, - "RC adb": { - "glob": "*.adb", - "params": "copy", - "productAssetType": "{50908273-CA36-4668-9828-15DD5092F973}" - }, - "RC bspace": { - "glob": "*.bspace", - "params": "copy" - }, - "RC cdf": { - "glob": "*.cdf", - "params": "copy", - "productAssetType": "{DF036C63-9AE6-4AC3-A6AC-8A1D76126C01}" - }, - // note - this used to be skinnedMeshAsset but its now Character Definition File specific. - // .skin has its own type. - - "RC chrparams": { - "glob": "*.chrparams", - "params": "copy", - "productAssetType": "{4BBB785A-6824-4803-A607-F9323E7BEEF1}", - "version": 2 - }, - "RC comb": { - "glob": "*.comb", - "params": "copy" - }, - "RC dlg": { - "glob": "*.dlg", - "params": "copy" - }, - "RC csv": { - "glob": "*.csv", - "params": "copy" - }, - "RC json": { - "glob": "*.json", - "params": "copy" - }, - "RC lmg": { - "glob": "*.lmg", - "params": "copy" - }, - "RC smtl": { - "glob": "*.smtl", - "params": "copy" - }, - "RC sub": { - "glob": "*.sub", - "params": "copy", - "productAssetType": "{71F9D30E-13F7-40D6-A3C9-E5358004B31F}", - "version": 2 - }, - "RC sbsar": { - "glob": "*.sbsar", - "params": "copy" - }, - "RC loc.agsxml": { - "glob": "*.loc.agsxml", - "params": "copy", - "version": 1 - }, - "RC node": { - "glob": "*.node", - "params": "copy" - }, - "RC veg": { - "glob": "*.veg", - "params": "copy" - }, - "RC dat": { - "glob": "*.dat", - "params": "copy" - }, - "RC lut": { - "glob": "*.lut", - "params": "copy" - }, - "RC txt": { - "pattern": "^(?!.*PreloadLibs.txt).*\\\\.txt", - "params": "copy" - }, - "RC cal": { - "glob": "*.cal", - "params": "copy" - }, - "RC grp": { - "glob": "*.grp", - "params": "copy", - "productAssetType": "{7629EDD3-A361-49A2-B271-252127097D81}", - "version": 2 - }, - "RC xls": { - "glob": "*.xls", - "params": "copy" - }, - "RC ini": { - "glob": "*.ini", - "params": "copy" - }, - "RC ttf": { - "glob": "*.ttf", - "params": "copy" - }, - "RC otf": { - "glob": "*.otf", - "params": "copy" - }, - "RC ext": { - "glob": "*.ext", - "params": "copy" - }, - // Copy all pak files except level.pak, level.pak has its own builder. - "RC pak": { - "pattern": "^((?!\\\\/level\\\\.pak).)*\\\\.pak$", - "params": "copy" - }, - "RC ctc": { - "glob": "*.ctc", - "params": "copy" - }, - "RC uiprefab": { - "glob": "*.uiprefab", - "params": "copy", - "server": "skip" - }, - "RC sprite": { - "glob": "*.sprite", - "params": "copy", - "server": "skip" - }, - "RC bin": { - "glob": "*.bin", - "params": "copy" - }, - "RC inputbindings": { - "glob": "*.inputbindings", - "params": "copy", - "productAssetType": "{25971C7A-26E2-4D08-A146-2EFCC1C36B0C}" - }, - "RC physmaterial": { - "glob": "*.physmaterial", - "params": "copy", - "productAssetType": "{9E366D8C-33BB-4825-9A1F-FA3ADBE11D0F}" - }, - "RC ocm": { - "glob": "*.ocm", - "params": "copy" - }, - // Feature tests use the raw .tif files for the golden image comparison - "RC goldenimages": { - "pattern": ".*GoldenImages\\\\/.*\\\\.tif", - "params": "copy", - "server": "skip" - }, - // Copy over certificates for use with FileDataSource - "RC CertificatePEM": { - "glob": "*.pem", - "params": "copy" - }, - // Copy over certificates for use with Dynamic Content - "RC CertificateDER": { - "glob": "*.der", - "params": "copy" - }, - "RC PhysXMeshAsset": { - "glob": "*.pxmesh", - "params": "copy", - "productAssetType": "{7A2871B9-5EAB-4DE0-A901-B0D2C6920DDB}" - }, - // Copy over cooked PhysX heightfield - "RC PhysX HeightField": { - "glob": "*.pxheightfield", - "params": "copy", - "productAssetType": "{B61189FE-B2D7-4AF1-8951-CB5C0F7834FC}" - }, - "RC filetag": { - "glob": "*.filetag", - "params": "copy", - "productAssetType": "{F3BE5CAB-85B7-44B7-9495-863863F6B267}" - }, - // Precompiled shader srg - "RC azsrg": { - "glob": "*.azsrg", - "params": "copy", - "productAssetType": "{F8C9F4AE-3F6A-45AD-B4FB-0CA415FCC2E1}" - }, - // Precompiled shader variant - "RC azshadervariant": { - "glob": "*.azshadervariant", - "params": "copy", - "productAssetType": "{9F4D654B-4439-4C61-8DCD-F1C7C5560768}" - } - } - } - } -} diff --git a/Editor/CryDesigner_TimeOfDay.xml b/Assets/Editor/CryDesigner_TimeOfDay.xml similarity index 100% rename from Editor/CryDesigner_TimeOfDay.xml rename to Assets/Editor/CryDesigner_TimeOfDay.xml diff --git a/Editor/Editor.tip b/Assets/Editor/Editor.tip similarity index 100% rename from Editor/Editor.tip rename to Assets/Editor/Editor.tip diff --git a/Gems/ScriptCanvas/Assets/Editor/Icons/AssetBrowser/ScriptCanvas_16.png b/Assets/Editor/Editor/Icons/AssetBrowser/ScriptCanvas_16.png similarity index 100% rename from Gems/ScriptCanvas/Assets/Editor/Icons/AssetBrowser/ScriptCanvas_16.png rename to Assets/Editor/Editor/Icons/AssetBrowser/ScriptCanvas_16.png diff --git a/Editor/EditorParticlePanels.xml b/Assets/Editor/EditorParticlePanels.xml similarity index 100% rename from Editor/EditorParticlePanels.xml rename to Assets/Editor/EditorParticlePanels.xml diff --git a/Editor/EditorParticlePanelsDefault.xml b/Assets/Editor/EditorParticlePanelsDefault.xml similarity index 100% rename from Editor/EditorParticlePanelsDefault.xml rename to Assets/Editor/EditorParticlePanelsDefault.xml diff --git a/Editor/Fonts/Open_Sans/LICENSE.txt b/Assets/Editor/Fonts/Open_Sans/LICENSE.txt similarity index 100% rename from Editor/Fonts/Open_Sans/LICENSE.txt rename to Assets/Editor/Fonts/Open_Sans/LICENSE.txt diff --git a/Editor/Fonts/Open_Sans/OpenSans-Bold.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-Bold.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-Bold.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-Bold.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-BoldItalic.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-BoldItalic.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-BoldItalic.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-BoldItalic.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-ExtraBold.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-ExtraBold.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-ExtraBold.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-ExtraBold.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-Italic.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-Italic.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-Italic.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-Italic.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-Light.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-Light.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-Light.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-Light.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-LightItalic.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-LightItalic.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-LightItalic.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-LightItalic.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-Regular.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-Regular.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-Regular.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-Regular.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-Semibold.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-Semibold.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-Semibold.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-Semibold.ttf diff --git a/Editor/Fonts/Open_Sans/OpenSans-SemiboldItalic.ttf b/Assets/Editor/Fonts/Open_Sans/OpenSans-SemiboldItalic.ttf similarity index 100% rename from Editor/Fonts/Open_Sans/OpenSans-SemiboldItalic.ttf rename to Assets/Editor/Fonts/Open_Sans/OpenSans-SemiboldItalic.ttf diff --git a/Editor/Icons/AssetBrowser/ABC_16.svg b/Assets/Editor/Icons/AssetBrowser/ABC_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/ABC_16.svg rename to Assets/Editor/Icons/AssetBrowser/ABC_16.svg diff --git a/Editor/Icons/AssetBrowser/Audio_16.svg b/Assets/Editor/Icons/AssetBrowser/Audio_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Audio_16.svg rename to Assets/Editor/Icons/AssetBrowser/Audio_16.svg diff --git a/Editor/Icons/AssetBrowser/CaretClosed_16.svg b/Assets/Editor/Icons/AssetBrowser/CaretClosed_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/CaretClosed_16.svg rename to Assets/Editor/Icons/AssetBrowser/CaretClosed_16.svg diff --git a/Editor/Icons/AssetBrowser/CaretOpen_16.svg b/Assets/Editor/Icons/AssetBrowser/CaretOpen_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/CaretOpen_16.svg rename to Assets/Editor/Icons/AssetBrowser/CaretOpen_16.svg diff --git a/Editor/Icons/AssetBrowser/DefaultProduct_16.svg b/Assets/Editor/Icons/AssetBrowser/DefaultProduct_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/DefaultProduct_16.svg rename to Assets/Editor/Icons/AssetBrowser/DefaultProduct_16.svg diff --git a/Editor/Icons/AssetBrowser/Default_16.svg b/Assets/Editor/Icons/AssetBrowser/Default_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Default_16.svg rename to Assets/Editor/Icons/AssetBrowser/Default_16.svg diff --git a/Editor/Icons/AssetBrowser/FBX_16.svg b/Assets/Editor/Icons/AssetBrowser/FBX_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/FBX_16.svg rename to Assets/Editor/Icons/AssetBrowser/FBX_16.svg diff --git a/Editor/Icons/AssetBrowser/Folder_16.svg b/Assets/Editor/Icons/AssetBrowser/Folder_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Folder_16.svg rename to Assets/Editor/Icons/AssetBrowser/Folder_16.svg diff --git a/Editor/Icons/AssetBrowser/Font_16.svg b/Assets/Editor/Icons/AssetBrowser/Font_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Font_16.svg rename to Assets/Editor/Icons/AssetBrowser/Font_16.svg diff --git a/Editor/Icons/AssetBrowser/GemFolder_16.svg b/Assets/Editor/Icons/AssetBrowser/GemFolder_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/GemFolder_16.svg rename to Assets/Editor/Icons/AssetBrowser/GemFolder_16.svg diff --git a/Editor/Icons/AssetBrowser/Image_16.svg b/Assets/Editor/Icons/AssetBrowser/Image_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Image_16.svg rename to Assets/Editor/Icons/AssetBrowser/Image_16.svg diff --git a/Editor/Icons/AssetBrowser/InputBindings_16.svg b/Assets/Editor/Icons/AssetBrowser/InputBindings_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/InputBindings_16.svg rename to Assets/Editor/Icons/AssetBrowser/InputBindings_16.svg diff --git a/Editor/Icons/AssetBrowser/LegacyAnimation_16.svg b/Assets/Editor/Icons/AssetBrowser/LegacyAnimation_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/LegacyAnimation_16.svg rename to Assets/Editor/Icons/AssetBrowser/LegacyAnimation_16.svg diff --git a/Editor/Icons/AssetBrowser/LegacyMesh_16.svg b/Assets/Editor/Icons/AssetBrowser/LegacyMesh_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/LegacyMesh_16.svg rename to Assets/Editor/Icons/AssetBrowser/LegacyMesh_16.svg diff --git a/Editor/Icons/AssetBrowser/LegacySkin_16.svg b/Assets/Editor/Icons/AssetBrowser/LegacySkin_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/LegacySkin_16.svg rename to Assets/Editor/Icons/AssetBrowser/LegacySkin_16.svg diff --git a/Editor/Icons/AssetBrowser/LensFlare_16.svg b/Assets/Editor/Icons/AssetBrowser/LensFlare_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/LensFlare_16.svg rename to Assets/Editor/Icons/AssetBrowser/LensFlare_16.svg diff --git a/Editor/Icons/AssetBrowser/Lua_16.svg b/Assets/Editor/Icons/AssetBrowser/Lua_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Lua_16.svg rename to Assets/Editor/Icons/AssetBrowser/Lua_16.svg diff --git a/Editor/Icons/AssetBrowser/Material_16.svg b/Assets/Editor/Icons/AssetBrowser/Material_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Material_16.svg rename to Assets/Editor/Icons/AssetBrowser/Material_16.svg diff --git a/Editor/Icons/AssetBrowser/NonWritable_16.svg b/Assets/Editor/Icons/AssetBrowser/NonWritable_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/NonWritable_16.svg rename to Assets/Editor/Icons/AssetBrowser/NonWritable_16.svg diff --git a/Editor/Icons/AssetBrowser/Particle_16.svg b/Assets/Editor/Icons/AssetBrowser/Particle_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Particle_16.svg rename to Assets/Editor/Icons/AssetBrowser/Particle_16.svg diff --git a/Editor/Icons/AssetBrowser/Slice_16.svg b/Assets/Editor/Icons/AssetBrowser/Slice_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Slice_16.svg rename to Assets/Editor/Icons/AssetBrowser/Slice_16.svg diff --git a/Editor/Icons/AssetBrowser/Writable_16.svg b/Assets/Editor/Icons/AssetBrowser/Writable_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/Writable_16.svg rename to Assets/Editor/Icons/AssetBrowser/Writable_16.svg diff --git a/Editor/Icons/AssetBrowser/XML_16.svg b/Assets/Editor/Icons/AssetBrowser/XML_16.svg similarity index 100% rename from Editor/Icons/AssetBrowser/XML_16.svg rename to Assets/Editor/Icons/AssetBrowser/XML_16.svg diff --git a/Editor/Icons/AssetBrowser/in_progress.gif b/Assets/Editor/Icons/AssetBrowser/in_progress.gif similarity index 100% rename from Editor/Icons/AssetBrowser/in_progress.gif rename to Assets/Editor/Icons/AssetBrowser/in_progress.gif diff --git a/Editor/Icons/AssetImporter/animation.png b/Assets/Editor/Icons/AssetImporter/animation.png similarity index 100% rename from Editor/Icons/AssetImporter/animation.png rename to Assets/Editor/Icons/AssetImporter/animation.png diff --git a/Editor/Icons/AssetImporter/animation_on.png b/Assets/Editor/Icons/AssetImporter/animation_on.png similarity index 100% rename from Editor/Icons/AssetImporter/animation_on.png rename to Assets/Editor/Icons/AssetImporter/animation_on.png diff --git a/Editor/Icons/AssetImporter/group_icon.png b/Assets/Editor/Icons/AssetImporter/group_icon.png similarity index 100% rename from Editor/Icons/AssetImporter/group_icon.png rename to Assets/Editor/Icons/AssetImporter/group_icon.png diff --git a/Editor/Icons/AssetImporter/mesh.png b/Assets/Editor/Icons/AssetImporter/mesh.png similarity index 100% rename from Editor/Icons/AssetImporter/mesh.png rename to Assets/Editor/Icons/AssetImporter/mesh.png diff --git a/Editor/Icons/AssetImporter/mesh_on.png b/Assets/Editor/Icons/AssetImporter/mesh_on.png similarity index 100% rename from Editor/Icons/AssetImporter/mesh_on.png rename to Assets/Editor/Icons/AssetImporter/mesh_on.png diff --git a/Editor/Icons/AssetImporter/skeleton.png b/Assets/Editor/Icons/AssetImporter/skeleton.png similarity index 100% rename from Editor/Icons/AssetImporter/skeleton.png rename to Assets/Editor/Icons/AssetImporter/skeleton.png diff --git a/Editor/Icons/AssetImporter/skeleton_on.png b/Assets/Editor/Icons/AssetImporter/skeleton_on.png similarity index 100% rename from Editor/Icons/AssetImporter/skeleton_on.png rename to Assets/Editor/Icons/AssetImporter/skeleton_on.png diff --git a/Editor/Icons/AssetImporter/skin.png b/Assets/Editor/Icons/AssetImporter/skin.png similarity index 100% rename from Editor/Icons/AssetImporter/skin.png rename to Assets/Editor/Icons/AssetImporter/skin.png diff --git a/Editor/Icons/AssetImporter/skin_on.png b/Assets/Editor/Icons/AssetImporter/skin_on.png similarity index 100% rename from Editor/Icons/AssetImporter/skin_on.png rename to Assets/Editor/Icons/AssetImporter/skin_on.png diff --git a/Editor/Icons/AssetImporter/tree.png b/Assets/Editor/Icons/AssetImporter/tree.png similarity index 100% rename from Editor/Icons/AssetImporter/tree.png rename to Assets/Editor/Icons/AssetImporter/tree.png diff --git a/Editor/Icons/Assets/InputBindings.png b/Assets/Editor/Icons/Assets/InputBindings.png similarity index 100% rename from Editor/Icons/Assets/InputBindings.png rename to Assets/Editor/Icons/Assets/InputBindings.png diff --git a/Editor/Icons/Assets/Lua.png b/Assets/Editor/Icons/Assets/Lua.png similarity index 100% rename from Editor/Icons/Assets/Lua.png rename to Assets/Editor/Icons/Assets/Lua.png diff --git a/Editor/Icons/Assets/PhysicsMaterial.png b/Assets/Editor/Icons/Assets/PhysicsMaterial.png similarity index 100% rename from Editor/Icons/Assets/PhysicsMaterial.png rename to Assets/Editor/Icons/Assets/PhysicsMaterial.png diff --git a/Editor/Icons/Components/AreaLight.svg b/Assets/Editor/Icons/Components/AreaLight.svg similarity index 100% rename from Editor/Icons/Components/AreaLight.svg rename to Assets/Editor/Icons/Components/AreaLight.svg diff --git a/Editor/Icons/Components/Attachment.svg b/Assets/Editor/Icons/Components/Attachment.svg similarity index 100% rename from Editor/Icons/Components/Attachment.svg rename to Assets/Editor/Icons/Components/Attachment.svg diff --git a/Editor/Icons/Components/AudioAnimation.svg b/Assets/Editor/Icons/Components/AudioAnimation.svg similarity index 100% rename from Editor/Icons/Components/AudioAnimation.svg rename to Assets/Editor/Icons/Components/AudioAnimation.svg diff --git a/Editor/Icons/Components/AudioAnimationEventsProxy.svg b/Assets/Editor/Icons/Components/AudioAnimationEventsProxy.svg similarity index 100% rename from Editor/Icons/Components/AudioAnimationEventsProxy.svg rename to Assets/Editor/Icons/Components/AudioAnimationEventsProxy.svg diff --git a/Editor/Icons/Components/AudioArea.png b/Assets/Editor/Icons/Components/AudioArea.png similarity index 100% rename from Editor/Icons/Components/AudioArea.png rename to Assets/Editor/Icons/Components/AudioArea.png diff --git a/Editor/Icons/Components/AudioAreaEnvironment.svg b/Assets/Editor/Icons/Components/AudioAreaEnvironment.svg similarity index 100% rename from Editor/Icons/Components/AudioAreaEnvironment.svg rename to Assets/Editor/Icons/Components/AudioAreaEnvironment.svg diff --git a/Editor/Icons/Components/AudioEnvironment.svg b/Assets/Editor/Icons/Components/AudioEnvironment.svg similarity index 100% rename from Editor/Icons/Components/AudioEnvironment.svg rename to Assets/Editor/Icons/Components/AudioEnvironment.svg diff --git a/Editor/Icons/Components/AudioListener.svg b/Assets/Editor/Icons/Components/AudioListener.svg similarity index 100% rename from Editor/Icons/Components/AudioListener.svg rename to Assets/Editor/Icons/Components/AudioListener.svg diff --git a/Editor/Icons/Components/AudioMultiPosition.png b/Assets/Editor/Icons/Components/AudioMultiPosition.png similarity index 100% rename from Editor/Icons/Components/AudioMultiPosition.png rename to Assets/Editor/Icons/Components/AudioMultiPosition.png diff --git a/Editor/Icons/Components/AudioPreload.svg b/Assets/Editor/Icons/Components/AudioPreload.svg similarity index 100% rename from Editor/Icons/Components/AudioPreload.svg rename to Assets/Editor/Icons/Components/AudioPreload.svg diff --git a/Editor/Icons/Components/AudioProxy.svg b/Assets/Editor/Icons/Components/AudioProxy.svg similarity index 100% rename from Editor/Icons/Components/AudioProxy.svg rename to Assets/Editor/Icons/Components/AudioProxy.svg diff --git a/Editor/Icons/Components/AudioRtpc.svg b/Assets/Editor/Icons/Components/AudioRtpc.svg similarity index 100% rename from Editor/Icons/Components/AudioRtpc.svg rename to Assets/Editor/Icons/Components/AudioRtpc.svg diff --git a/Editor/Icons/Components/AudioSwitch.svg b/Assets/Editor/Icons/Components/AudioSwitch.svg similarity index 100% rename from Editor/Icons/Components/AudioSwitch.svg rename to Assets/Editor/Icons/Components/AudioSwitch.svg diff --git a/Editor/Icons/Components/AudioTrigger.svg b/Assets/Editor/Icons/Components/AudioTrigger.svg similarity index 100% rename from Editor/Icons/Components/AudioTrigger.svg rename to Assets/Editor/Icons/Components/AudioTrigger.svg diff --git a/Editor/Icons/Components/BehaviorTree.svg b/Assets/Editor/Icons/Components/BehaviorTree.svg similarity index 100% rename from Editor/Icons/Components/BehaviorTree.svg rename to Assets/Editor/Icons/Components/BehaviorTree.svg diff --git a/Editor/Icons/Components/Box.png b/Assets/Editor/Icons/Components/Box.png similarity index 100% rename from Editor/Icons/Components/Box.png rename to Assets/Editor/Icons/Components/Box.png diff --git a/Editor/Icons/Components/Box_Shape.svg b/Assets/Editor/Icons/Components/Box_Shape.svg similarity index 100% rename from Editor/Icons/Components/Box_Shape.svg rename to Assets/Editor/Icons/Components/Box_Shape.svg diff --git a/Editor/Icons/Components/Capsule_Shape.svg b/Assets/Editor/Icons/Components/Capsule_Shape.svg similarity index 100% rename from Editor/Icons/Components/Capsule_Shape.svg rename to Assets/Editor/Icons/Components/Capsule_Shape.svg diff --git a/Editor/Icons/Components/CharacterPhysics.svg b/Assets/Editor/Icons/Components/CharacterPhysics.svg similarity index 100% rename from Editor/Icons/Components/CharacterPhysics.svg rename to Assets/Editor/Icons/Components/CharacterPhysics.svg diff --git a/Editor/Icons/Components/Cloth.svg b/Assets/Editor/Icons/Components/Cloth.svg similarity index 100% rename from Editor/Icons/Components/Cloth.svg rename to Assets/Editor/Icons/Components/Cloth.svg diff --git a/Editor/Icons/Components/CloudGemMessageOfTheDay.svg b/Assets/Editor/Icons/Components/CloudGemMessageOfTheDay.svg similarity index 100% rename from Editor/Icons/Components/CloudGemMessageOfTheDay.svg rename to Assets/Editor/Icons/Components/CloudGemMessageOfTheDay.svg diff --git a/Editor/Icons/Components/ColliderBox.png b/Assets/Editor/Icons/Components/ColliderBox.png similarity index 100% rename from Editor/Icons/Components/ColliderBox.png rename to Assets/Editor/Icons/Components/ColliderBox.png diff --git a/Editor/Icons/Components/ColliderCapsule.png b/Assets/Editor/Icons/Components/ColliderCapsule.png similarity index 100% rename from Editor/Icons/Components/ColliderCapsule.png rename to Assets/Editor/Icons/Components/ColliderCapsule.png diff --git a/Editor/Icons/Components/ColliderCylinder.png b/Assets/Editor/Icons/Components/ColliderCylinder.png similarity index 100% rename from Editor/Icons/Components/ColliderCylinder.png rename to Assets/Editor/Icons/Components/ColliderCylinder.png diff --git a/Editor/Icons/Components/ColliderMesh.svg b/Assets/Editor/Icons/Components/ColliderMesh.svg similarity index 100% rename from Editor/Icons/Components/ColliderMesh.svg rename to Assets/Editor/Icons/Components/ColliderMesh.svg diff --git a/Editor/Icons/Components/ColliderSphere.png b/Assets/Editor/Icons/Components/ColliderSphere.png similarity index 100% rename from Editor/Icons/Components/ColliderSphere.png rename to Assets/Editor/Icons/Components/ColliderSphere.png diff --git a/Editor/Icons/Components/Comment.svg b/Assets/Editor/Icons/Components/Comment.svg similarity index 100% rename from Editor/Icons/Components/Comment.svg rename to Assets/Editor/Icons/Components/Comment.svg diff --git a/Editor/Icons/Components/Component_Placeholder.svg b/Assets/Editor/Icons/Components/Component_Placeholder.svg similarity index 100% rename from Editor/Icons/Components/Component_Placeholder.svg rename to Assets/Editor/Icons/Components/Component_Placeholder.svg diff --git a/Editor/Icons/Components/Compound_Shape.svg b/Assets/Editor/Icons/Components/Compound_Shape.svg similarity index 100% rename from Editor/Icons/Components/Compound_Shape.svg rename to Assets/Editor/Icons/Components/Compound_Shape.svg diff --git a/Editor/Icons/Components/Cylinder.png b/Assets/Editor/Icons/Components/Cylinder.png similarity index 100% rename from Editor/Icons/Components/Cylinder.png rename to Assets/Editor/Icons/Components/Cylinder.png diff --git a/Editor/Icons/Components/Cylinder_Shape.svg b/Assets/Editor/Icons/Components/Cylinder_Shape.svg similarity index 100% rename from Editor/Icons/Components/Cylinder_Shape.svg rename to Assets/Editor/Icons/Components/Cylinder_Shape.svg diff --git a/Editor/Icons/Components/DebugDrawLine.svg b/Assets/Editor/Icons/Components/DebugDrawLine.svg similarity index 100% rename from Editor/Icons/Components/DebugDrawLine.svg rename to Assets/Editor/Icons/Components/DebugDrawLine.svg diff --git a/Editor/Icons/Components/DebugDrawObb.svg b/Assets/Editor/Icons/Components/DebugDrawObb.svg similarity index 100% rename from Editor/Icons/Components/DebugDrawObb.svg rename to Assets/Editor/Icons/Components/DebugDrawObb.svg diff --git a/Editor/Icons/Components/DebugDrawRay.svg b/Assets/Editor/Icons/Components/DebugDrawRay.svg similarity index 100% rename from Editor/Icons/Components/DebugDrawRay.svg rename to Assets/Editor/Icons/Components/DebugDrawRay.svg diff --git a/Editor/Icons/Components/DebugDrawSphere.svg b/Assets/Editor/Icons/Components/DebugDrawSphere.svg similarity index 100% rename from Editor/Icons/Components/DebugDrawSphere.svg rename to Assets/Editor/Icons/Components/DebugDrawSphere.svg diff --git a/Editor/Icons/Components/DebugDrawText.svg b/Assets/Editor/Icons/Components/DebugDrawText.svg similarity index 100% rename from Editor/Icons/Components/DebugDrawText.svg rename to Assets/Editor/Icons/Components/DebugDrawText.svg diff --git a/Editor/Icons/Components/Decal.svg b/Assets/Editor/Icons/Components/Decal.svg similarity index 100% rename from Editor/Icons/Components/Decal.svg rename to Assets/Editor/Icons/Components/Decal.svg diff --git a/Editor/Icons/Components/Disabled/Animation_white.png b/Assets/Editor/Icons/Components/Disabled/Animation_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Animation_white.png rename to Assets/Editor/Icons/Components/Disabled/Animation_white.png diff --git a/Editor/Icons/Components/Disabled/Attachment_white.png b/Assets/Editor/Icons/Components/Disabled/Attachment_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Attachment_white.png rename to Assets/Editor/Icons/Components/Disabled/Attachment_white.png diff --git a/Editor/Icons/Components/Disabled/AudioAreaEnvironment_white.png b/Assets/Editor/Icons/Components/Disabled/AudioAreaEnvironment_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioAreaEnvironment_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioAreaEnvironment_white.png diff --git a/Editor/Icons/Components/Disabled/AudioArea_white.png b/Assets/Editor/Icons/Components/Disabled/AudioArea_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioArea_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioArea_white.png diff --git a/Editor/Icons/Components/Disabled/AudioEnvironment_white.png b/Assets/Editor/Icons/Components/Disabled/AudioEnvironment_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioEnvironment_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioEnvironment_white.png diff --git a/Editor/Icons/Components/Disabled/AudioListener_white.png b/Assets/Editor/Icons/Components/Disabled/AudioListener_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioListener_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioListener_white.png diff --git a/Editor/Icons/Components/Disabled/AudioRtpc_white.png b/Assets/Editor/Icons/Components/Disabled/AudioRtpc_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioRtpc_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioRtpc_white.png diff --git a/Editor/Icons/Components/Disabled/AudioSwitch_white.png b/Assets/Editor/Icons/Components/Disabled/AudioSwitch_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioSwitch_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioSwitch_white.png diff --git a/Editor/Icons/Components/Disabled/AudioTrigger_white.png b/Assets/Editor/Icons/Components/Disabled/AudioTrigger_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/AudioTrigger_white.png rename to Assets/Editor/Icons/Components/Disabled/AudioTrigger_white.png diff --git a/Editor/Icons/Components/Disabled/BehaviorTree_white.png b/Assets/Editor/Icons/Components/Disabled/BehaviorTree_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/BehaviorTree_white.png rename to Assets/Editor/Icons/Components/Disabled/BehaviorTree_white.png diff --git a/Editor/Icons/Components/Disabled/Box_Shape_white.png b/Assets/Editor/Icons/Components/Disabled/Box_Shape_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Box_Shape_white.png rename to Assets/Editor/Icons/Components/Disabled/Box_Shape_white.png diff --git a/Editor/Icons/Components/Disabled/Box_collider_white.png b/Assets/Editor/Icons/Components/Disabled/Box_collider_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Box_collider_white.png rename to Assets/Editor/Icons/Components/Disabled/Box_collider_white.png diff --git a/Editor/Icons/Components/Disabled/Box_white.png b/Assets/Editor/Icons/Components/Disabled/Box_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Box_white.png rename to Assets/Editor/Icons/Components/Disabled/Box_white.png diff --git a/Editor/Icons/Components/Disabled/Capsule_Shape_white.png b/Assets/Editor/Icons/Components/Disabled/Capsule_Shape_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Capsule_Shape_white.png rename to Assets/Editor/Icons/Components/Disabled/Capsule_Shape_white.png diff --git a/Editor/Icons/Components/Disabled/Capsule_white.png b/Assets/Editor/Icons/Components/Disabled/Capsule_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Capsule_white.png rename to Assets/Editor/Icons/Components/Disabled/Capsule_white.png diff --git a/Editor/Icons/Components/Disabled/CharacterPhysics_white.png b/Assets/Editor/Icons/Components/Disabled/CharacterPhysics_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/CharacterPhysics_white.png rename to Assets/Editor/Icons/Components/Disabled/CharacterPhysics_white.png diff --git a/Editor/Icons/Components/Disabled/Comment.png b/Assets/Editor/Icons/Components/Disabled/Comment.png similarity index 100% rename from Editor/Icons/Components/Disabled/Comment.png rename to Assets/Editor/Icons/Components/Disabled/Comment.png diff --git a/Editor/Icons/Components/Disabled/ComponentPlaceholder_white.png b/Assets/Editor/Icons/Components/Disabled/ComponentPlaceholder_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/ComponentPlaceholder_white.png rename to Assets/Editor/Icons/Components/Disabled/ComponentPlaceholder_white.png diff --git a/Editor/Icons/Components/Disabled/Component_Placeholder_white.png b/Assets/Editor/Icons/Components/Disabled/Component_Placeholder_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Component_Placeholder_white.png rename to Assets/Editor/Icons/Components/Disabled/Component_Placeholder_white.png diff --git a/Editor/Icons/Components/Disabled/Cylinder_Shape_white.png b/Assets/Editor/Icons/Components/Disabled/Cylinder_Shape_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Cylinder_Shape_white.png rename to Assets/Editor/Icons/Components/Disabled/Cylinder_Shape_white.png diff --git a/Editor/Icons/Components/Disabled/Cylinder_white.png b/Assets/Editor/Icons/Components/Disabled/Cylinder_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Cylinder_white.png rename to Assets/Editor/Icons/Components/Disabled/Cylinder_white.png diff --git a/Editor/Icons/Components/Disabled/Decal_white.png b/Assets/Editor/Icons/Components/Disabled/Decal_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Decal_white.png rename to Assets/Editor/Icons/Components/Disabled/Decal_white.png diff --git a/Editor/Icons/Components/Disabled/DynamicContent_white.png b/Assets/Editor/Icons/Components/Disabled/DynamicContent_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/DynamicContent_white.png rename to Assets/Editor/Icons/Components/Disabled/DynamicContent_white.png diff --git a/Editor/Icons/Components/Disabled/DynamicMesh_white.png b/Assets/Editor/Icons/Components/Disabled/DynamicMesh_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/DynamicMesh_white.png rename to Assets/Editor/Icons/Components/Disabled/DynamicMesh_white.png diff --git a/Editor/Icons/Components/Disabled/EntityInSlice_white.png b/Assets/Editor/Icons/Components/Disabled/EntityInSlice_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/EntityInSlice_white.png rename to Assets/Editor/Icons/Components/Disabled/EntityInSlice_white.png diff --git a/Editor/Icons/Components/Disabled/Entity_white.png b/Assets/Editor/Icons/Components/Disabled/Entity_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Entity_white.png rename to Assets/Editor/Icons/Components/Disabled/Entity_white.png diff --git a/Editor/Icons/Components/Disabled/FogVolume_white.png b/Assets/Editor/Icons/Components/Disabled/FogVolume_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/FogVolume_white.png rename to Assets/Editor/Icons/Components/Disabled/FogVolume_white.png diff --git a/Editor/Icons/Components/Disabled/ForceVolume_white.png b/Assets/Editor/Icons/Components/Disabled/ForceVolume_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/ForceVolume_white.png rename to Assets/Editor/Icons/Components/Disabled/ForceVolume_white.png diff --git a/Editor/Icons/Components/Disabled/GeometryCache_white.png b/Assets/Editor/Icons/Components/Disabled/GeometryCache_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/GeometryCache_white.png rename to Assets/Editor/Icons/Components/Disabled/GeometryCache_white.png diff --git a/Editor/Icons/Components/Disabled/HttpClientComponent_white.png b/Assets/Editor/Icons/Components/Disabled/HttpClientComponent_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/HttpClientComponent_white.png rename to Assets/Editor/Icons/Components/Disabled/HttpClientComponent_white.png diff --git a/Editor/Icons/Components/Disabled/LensFlare_white.png b/Assets/Editor/Icons/Components/Disabled/LensFlare_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/LensFlare_white.png rename to Assets/Editor/Icons/Components/Disabled/LensFlare_white.png diff --git a/Editor/Icons/Components/Disabled/Light_white.png b/Assets/Editor/Icons/Components/Disabled/Light_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Light_white.png rename to Assets/Editor/Icons/Components/Disabled/Light_white.png diff --git a/Editor/Icons/Components/Disabled/LightningArc_white.png b/Assets/Editor/Icons/Components/Disabled/LightningArc_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/LightningArc_white.png rename to Assets/Editor/Icons/Components/Disabled/LightningArc_white.png diff --git a/Editor/Icons/Components/Disabled/Lightning_white.png b/Assets/Editor/Icons/Components/Disabled/Lightning_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Lightning_white.png rename to Assets/Editor/Icons/Components/Disabled/Lightning_white.png diff --git a/Editor/Icons/Components/Disabled/LookAt_white.png b/Assets/Editor/Icons/Components/Disabled/LookAt_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/LookAt_white.png rename to Assets/Editor/Icons/Components/Disabled/LookAt_white.png diff --git a/Editor/Icons/Components/Disabled/MannequinScopeContext_white.png b/Assets/Editor/Icons/Components/Disabled/MannequinScopeContext_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/MannequinScopeContext_white.png rename to Assets/Editor/Icons/Components/Disabled/MannequinScopeContext_white.png diff --git a/Editor/Icons/Components/Disabled/Mannequin_white.png b/Assets/Editor/Icons/Components/Disabled/Mannequin_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Mannequin_white.png rename to Assets/Editor/Icons/Components/Disabled/Mannequin_white.png diff --git a/Editor/Icons/Components/Disabled/Mesh_collidaer_white 2.png b/Assets/Editor/Icons/Components/Disabled/Mesh_collidaer_white 2.png similarity index 100% rename from Editor/Icons/Components/Disabled/Mesh_collidaer_white 2.png rename to Assets/Editor/Icons/Components/Disabled/Mesh_collidaer_white 2.png diff --git a/Editor/Icons/Components/Disabled/NavigationArea_white.png b/Assets/Editor/Icons/Components/Disabled/NavigationArea_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/NavigationArea_white.png rename to Assets/Editor/Icons/Components/Disabled/NavigationArea_white.png diff --git a/Editor/Icons/Components/Disabled/NavigationSeed_white.png b/Assets/Editor/Icons/Components/Disabled/NavigationSeed_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/NavigationSeed_white.png rename to Assets/Editor/Icons/Components/Disabled/NavigationSeed_white.png diff --git a/Editor/Icons/Components/Disabled/Navigation_white.png b/Assets/Editor/Icons/Components/Disabled/Navigation_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Navigation_white.png rename to Assets/Editor/Icons/Components/Disabled/Navigation_white.png diff --git a/Editor/Icons/Components/Disabled/NetBinding_white.png b/Assets/Editor/Icons/Components/Disabled/NetBinding_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/NetBinding_white.png rename to Assets/Editor/Icons/Components/Disabled/NetBinding_white.png diff --git a/Editor/Icons/Components/Disabled/ObjectAvoidance_white.png b/Assets/Editor/Icons/Components/Disabled/ObjectAvoidance_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/ObjectAvoidance_white.png rename to Assets/Editor/Icons/Components/Disabled/ObjectAvoidance_white.png diff --git a/Editor/Icons/Components/Disabled/Particle_white.png b/Assets/Editor/Icons/Components/Disabled/Particle_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Particle_white.png rename to Assets/Editor/Icons/Components/Disabled/Particle_white.png diff --git a/Editor/Icons/Components/Disabled/PhysicsConstraint_white.png b/Assets/Editor/Icons/Components/Disabled/PhysicsConstraint_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/PhysicsConstraint_white.png rename to Assets/Editor/Icons/Components/Disabled/PhysicsConstraint_white.png diff --git a/Editor/Icons/Components/Disabled/PolygonPrism_white.png b/Assets/Editor/Icons/Components/Disabled/PolygonPrism_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/PolygonPrism_white.png rename to Assets/Editor/Icons/Components/Disabled/PolygonPrism_white.png diff --git a/Editor/Icons/Components/Disabled/PrimitiveCollider_white.png b/Assets/Editor/Icons/Components/Disabled/PrimitiveCollider_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/PrimitiveCollider_white.png rename to Assets/Editor/Icons/Components/Disabled/PrimitiveCollider_white.png diff --git a/Editor/Icons/Components/Disabled/Ragdoll.png b/Assets/Editor/Icons/Components/Disabled/Ragdoll.png similarity index 100% rename from Editor/Icons/Components/Disabled/Ragdoll.png rename to Assets/Editor/Icons/Components/Disabled/Ragdoll.png diff --git a/Editor/Icons/Components/Disabled/Ragdoll_white.png b/Assets/Editor/Icons/Components/Disabled/Ragdoll_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Ragdoll_white.png rename to Assets/Editor/Icons/Components/Disabled/Ragdoll_white.png diff --git a/Editor/Icons/Components/Disabled/RandomTimedSpawner_white.png b/Assets/Editor/Icons/Components/Disabled/RandomTimedSpawner_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/RandomTimedSpawner_white.png rename to Assets/Editor/Icons/Components/Disabled/RandomTimedSpawner_white.png diff --git a/Editor/Icons/Components/Disabled/RigidPhysics_white.png b/Assets/Editor/Icons/Components/Disabled/RigidPhysics_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/RigidPhysics_white.png rename to Assets/Editor/Icons/Components/Disabled/RigidPhysics_white.png diff --git a/Editor/Icons/Components/Disabled/Script_white.png b/Assets/Editor/Icons/Components/Disabled/Script_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Script_white.png rename to Assets/Editor/Icons/Components/Disabled/Script_white.png diff --git a/Editor/Icons/Components/Disabled/SequenceAgent_white.png b/Assets/Editor/Icons/Components/Disabled/SequenceAgent_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/SequenceAgent_white.png rename to Assets/Editor/Icons/Components/Disabled/SequenceAgent_white.png diff --git a/Editor/Icons/Components/Disabled/Sequence_white.png b/Assets/Editor/Icons/Components/Disabled/Sequence_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Sequence_white.png rename to Assets/Editor/Icons/Components/Disabled/Sequence_white.png diff --git a/Editor/Icons/Components/Disabled/Shadow.png b/Assets/Editor/Icons/Components/Disabled/Shadow.png similarity index 100% rename from Editor/Icons/Components/Disabled/Shadow.png rename to Assets/Editor/Icons/Components/Disabled/Shadow.png diff --git a/Editor/Icons/Components/Disabled/SimpleState_white.png b/Assets/Editor/Icons/Components/Disabled/SimpleState_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/SimpleState_white.png rename to Assets/Editor/Icons/Components/Disabled/SimpleState_white.png diff --git a/Editor/Icons/Components/Disabled/SkinnedMesh_white.png b/Assets/Editor/Icons/Components/Disabled/SkinnedMesh_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/SkinnedMesh_white.png rename to Assets/Editor/Icons/Components/Disabled/SkinnedMesh_white.png diff --git a/Editor/Icons/Components/Disabled/SkyHighlight_white.png b/Assets/Editor/Icons/Components/Disabled/SkyHighlight_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/SkyHighlight_white.png rename to Assets/Editor/Icons/Components/Disabled/SkyHighlight_white.png diff --git a/Editor/Icons/Components/Disabled/Snow_white.png b/Assets/Editor/Icons/Components/Disabled/Snow_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Snow_white.png rename to Assets/Editor/Icons/Components/Disabled/Snow_white.png diff --git a/Editor/Icons/Components/Disabled/Spawner_white.png b/Assets/Editor/Icons/Components/Disabled/Spawner_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Spawner_white.png rename to Assets/Editor/Icons/Components/Disabled/Spawner_white.png diff --git a/Editor/Icons/Components/Disabled/Sphere_Shape_white.png b/Assets/Editor/Icons/Components/Disabled/Sphere_Shape_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Sphere_Shape_white.png rename to Assets/Editor/Icons/Components/Disabled/Sphere_Shape_white.png diff --git a/Editor/Icons/Components/Disabled/Sphere_white.png b/Assets/Editor/Icons/Components/Disabled/Sphere_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Sphere_white.png rename to Assets/Editor/Icons/Components/Disabled/Sphere_white.png diff --git a/Editor/Icons/Components/Disabled/Spline_white.png b/Assets/Editor/Icons/Components/Disabled/Spline_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Spline_white.png rename to Assets/Editor/Icons/Components/Disabled/Spline_white.png diff --git a/Editor/Icons/Components/Disabled/StaticData_white.png b/Assets/Editor/Icons/Components/Disabled/StaticData_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/StaticData_white.png rename to Assets/Editor/Icons/Components/Disabled/StaticData_white.png diff --git a/Editor/Icons/Components/Disabled/StaticMesh_white.png b/Assets/Editor/Icons/Components/Disabled/StaticMesh_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/StaticMesh_white.png rename to Assets/Editor/Icons/Components/Disabled/StaticMesh_white.png diff --git a/Editor/Icons/Components/Disabled/StaticPhysics_white.png b/Assets/Editor/Icons/Components/Disabled/StaticPhysics_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/StaticPhysics_white.png rename to Assets/Editor/Icons/Components/Disabled/StaticPhysics_white.png diff --git a/Editor/Icons/Components/Disabled/Tag_white.png b/Assets/Editor/Icons/Components/Disabled/Tag_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Tag_white.png rename to Assets/Editor/Icons/Components/Disabled/Tag_white.png diff --git a/Editor/Icons/Components/Disabled/Transform_white.png b/Assets/Editor/Icons/Components/Disabled/Transform_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Transform_white.png rename to Assets/Editor/Icons/Components/Disabled/Transform_white.png diff --git a/Editor/Icons/Components/Disabled/Trigger_white.png b/Assets/Editor/Icons/Components/Disabled/Trigger_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/Trigger_white.png rename to Assets/Editor/Icons/Components/Disabled/Trigger_white.png diff --git a/Editor/Icons/Components/Disabled/UiCanvasOnMesh_white.png b/Assets/Editor/Icons/Components/Disabled/UiCanvasOnMesh_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/UiCanvasOnMesh_white.png rename to Assets/Editor/Icons/Components/Disabled/UiCanvasOnMesh_white.png diff --git a/Editor/Icons/Components/Disabled/UiCanvasRef_white.png b/Assets/Editor/Icons/Components/Disabled/UiCanvasRef_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/UiCanvasRef_white.png rename to Assets/Editor/Icons/Components/Disabled/UiCanvasRef_white.png diff --git a/Editor/Icons/Components/Disabled/WaterVolume_white.png b/Assets/Editor/Icons/Components/Disabled/WaterVolume_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/WaterVolume_white.png rename to Assets/Editor/Icons/Components/Disabled/WaterVolume_white.png diff --git a/Editor/Icons/Components/Disabled/WindVolume_white.png b/Assets/Editor/Icons/Components/Disabled/WindVolume_white.png similarity index 100% rename from Editor/Icons/Components/Disabled/WindVolume_white.png rename to Assets/Editor/Icons/Components/Disabled/WindVolume_white.png diff --git a/Editor/Icons/Components/Disk_Shape.svg b/Assets/Editor/Icons/Components/Disk_Shape.svg similarity index 100% rename from Editor/Icons/Components/Disk_Shape.svg rename to Assets/Editor/Icons/Components/Disk_Shape.svg diff --git a/Editor/Icons/Components/DynamicContent.png b/Assets/Editor/Icons/Components/DynamicContent.png similarity index 100% rename from Editor/Icons/Components/DynamicContent.png rename to Assets/Editor/Icons/Components/DynamicContent.png diff --git a/Editor/Icons/Components/DynamicMesh.png b/Assets/Editor/Icons/Components/DynamicMesh.png similarity index 100% rename from Editor/Icons/Components/DynamicMesh.png rename to Assets/Editor/Icons/Components/DynamicMesh.png diff --git a/Editor/Icons/Components/Entity.png b/Assets/Editor/Icons/Components/Entity.png similarity index 100% rename from Editor/Icons/Components/Entity.png rename to Assets/Editor/Icons/Components/Entity.png diff --git a/Editor/Icons/Components/EntityInSlice.png b/Assets/Editor/Icons/Components/EntityInSlice.png similarity index 100% rename from Editor/Icons/Components/EntityInSlice.png rename to Assets/Editor/Icons/Components/EntityInSlice.png diff --git a/Editor/Icons/Components/EnvironmentProbe.svg b/Assets/Editor/Icons/Components/EnvironmentProbe.svg similarity index 100% rename from Editor/Icons/Components/EnvironmentProbe.svg rename to Assets/Editor/Icons/Components/EnvironmentProbe.svg diff --git a/Editor/Icons/Components/Flipbook.png b/Assets/Editor/Icons/Components/Flipbook.png similarity index 100% rename from Editor/Icons/Components/Flipbook.png rename to Assets/Editor/Icons/Components/Flipbook.png diff --git a/Editor/Icons/Components/FogVolume.svg b/Assets/Editor/Icons/Components/FogVolume.svg similarity index 100% rename from Editor/Icons/Components/FogVolume.svg rename to Assets/Editor/Icons/Components/FogVolume.svg diff --git a/Editor/Icons/Components/Footstep1.svg b/Assets/Editor/Icons/Components/Footstep1.svg similarity index 100% rename from Editor/Icons/Components/Footstep1.svg rename to Assets/Editor/Icons/Components/Footstep1.svg diff --git a/Editor/Icons/Components/ForceRegion.png b/Assets/Editor/Icons/Components/ForceRegion.png similarity index 100% rename from Editor/Icons/Components/ForceRegion.png rename to Assets/Editor/Icons/Components/ForceRegion.png diff --git a/Editor/Icons/Components/ForceVolume.svg b/Assets/Editor/Icons/Components/ForceVolume.svg similarity index 100% rename from Editor/Icons/Components/ForceVolume.svg rename to Assets/Editor/Icons/Components/ForceVolume.svg diff --git a/Editor/Icons/Components/GeometryCache.svg b/Assets/Editor/Icons/Components/GeometryCache.svg similarity index 100% rename from Editor/Icons/Components/GeometryCache.svg rename to Assets/Editor/Icons/Components/GeometryCache.svg diff --git a/Editor/Icons/Components/HttpClientComponent.png b/Assets/Editor/Icons/Components/HttpClientComponent.png similarity index 100% rename from Editor/Icons/Components/HttpClientComponent.png rename to Assets/Editor/Icons/Components/HttpClientComponent.png diff --git a/Editor/Icons/Components/Layers.svg b/Assets/Editor/Icons/Components/Layers.svg similarity index 100% rename from Editor/Icons/Components/Layers.svg rename to Assets/Editor/Icons/Components/Layers.svg diff --git a/Editor/Icons/Components/LegacyTerrain.svg b/Assets/Editor/Icons/Components/LegacyTerrain.svg similarity index 100% rename from Editor/Icons/Components/LegacyTerrain.svg rename to Assets/Editor/Icons/Components/LegacyTerrain.svg diff --git a/Editor/Icons/Components/LensFlare.svg b/Assets/Editor/Icons/Components/LensFlare.svg similarity index 100% rename from Editor/Icons/Components/LensFlare.svg rename to Assets/Editor/Icons/Components/LensFlare.svg diff --git a/Editor/Icons/Components/Light.png b/Assets/Editor/Icons/Components/Light.png similarity index 100% rename from Editor/Icons/Components/Light.png rename to Assets/Editor/Icons/Components/Light.png diff --git a/Editor/Icons/Components/Lightning.svg b/Assets/Editor/Icons/Components/Lightning.svg similarity index 100% rename from Editor/Icons/Components/Lightning.svg rename to Assets/Editor/Icons/Components/Lightning.svg diff --git a/Editor/Icons/Components/LightningArc.svg b/Assets/Editor/Icons/Components/LightningArc.svg similarity index 100% rename from Editor/Icons/Components/LightningArc.svg rename to Assets/Editor/Icons/Components/LightningArc.svg diff --git a/Editor/Icons/Components/LookAt.png b/Assets/Editor/Icons/Components/LookAt.png similarity index 100% rename from Editor/Icons/Components/LookAt.png rename to Assets/Editor/Icons/Components/LookAt.png diff --git a/Editor/Icons/Components/LuaScript.svg b/Assets/Editor/Icons/Components/LuaScript.svg similarity index 100% rename from Editor/Icons/Components/LuaScript.svg rename to Assets/Editor/Icons/Components/LuaScript.svg diff --git a/Editor/Icons/Components/Mannequin.svg b/Assets/Editor/Icons/Components/Mannequin.svg similarity index 100% rename from Editor/Icons/Components/Mannequin.svg rename to Assets/Editor/Icons/Components/Mannequin.svg diff --git a/Editor/Icons/Components/MannequinScopeContext.svg b/Assets/Editor/Icons/Components/MannequinScopeContext.svg similarity index 100% rename from Editor/Icons/Components/MannequinScopeContext.svg rename to Assets/Editor/Icons/Components/MannequinScopeContext.svg diff --git a/Editor/Icons/Components/MotionParameterSmoothing.svg b/Assets/Editor/Icons/Components/MotionParameterSmoothing.svg similarity index 100% rename from Editor/Icons/Components/MotionParameterSmoothing.svg rename to Assets/Editor/Icons/Components/MotionParameterSmoothing.svg diff --git a/Editor/Icons/Components/Navigation.svg b/Assets/Editor/Icons/Components/Navigation.svg similarity index 100% rename from Editor/Icons/Components/Navigation.svg rename to Assets/Editor/Icons/Components/Navigation.svg diff --git a/Editor/Icons/Components/NavigationArea.svg b/Assets/Editor/Icons/Components/NavigationArea.svg similarity index 100% rename from Editor/Icons/Components/NavigationArea.svg rename to Assets/Editor/Icons/Components/NavigationArea.svg diff --git a/Editor/Icons/Components/NavigationSeed.svg b/Assets/Editor/Icons/Components/NavigationSeed.svg similarity index 100% rename from Editor/Icons/Components/NavigationSeed.svg rename to Assets/Editor/Icons/Components/NavigationSeed.svg diff --git a/Editor/Icons/Components/NetBinding.svg b/Assets/Editor/Icons/Components/NetBinding.svg similarity index 100% rename from Editor/Icons/Components/NetBinding.svg rename to Assets/Editor/Icons/Components/NetBinding.svg diff --git a/Editor/Icons/Components/ObjectAvoidance.png b/Assets/Editor/Icons/Components/ObjectAvoidance.png similarity index 100% rename from Editor/Icons/Components/ObjectAvoidance.png rename to Assets/Editor/Icons/Components/ObjectAvoidance.png diff --git a/Editor/Icons/Components/Particle.svg b/Assets/Editor/Icons/Components/Particle.svg similarity index 100% rename from Editor/Icons/Components/Particle.svg rename to Assets/Editor/Icons/Components/Particle.svg diff --git a/Editor/Icons/Components/PhysXCharacter.svg b/Assets/Editor/Icons/Components/PhysXCharacter.svg similarity index 100% rename from Editor/Icons/Components/PhysXCharacter.svg rename to Assets/Editor/Icons/Components/PhysXCharacter.svg diff --git a/Editor/Icons/Components/PhysXCollider.svg b/Assets/Editor/Icons/Components/PhysXCollider.svg similarity index 100% rename from Editor/Icons/Components/PhysXCollider.svg rename to Assets/Editor/Icons/Components/PhysXCollider.svg diff --git a/Editor/Icons/Components/PhysXRagdoll.svg b/Assets/Editor/Icons/Components/PhysXRagdoll.svg similarity index 100% rename from Editor/Icons/Components/PhysXRagdoll.svg rename to Assets/Editor/Icons/Components/PhysXRagdoll.svg diff --git a/Editor/Icons/Components/PhysXRigidBody.svg b/Assets/Editor/Icons/Components/PhysXRigidBody.svg similarity index 100% rename from Editor/Icons/Components/PhysXRigidBody.svg rename to Assets/Editor/Icons/Components/PhysXRigidBody.svg diff --git a/Editor/Icons/Components/PhysXTerrain.svg b/Assets/Editor/Icons/Components/PhysXTerrain.svg similarity index 100% rename from Editor/Icons/Components/PhysXTerrain.svg rename to Assets/Editor/Icons/Components/PhysXTerrain.svg diff --git a/Editor/Icons/Components/Physics.png b/Assets/Editor/Icons/Components/Physics.png similarity index 100% rename from Editor/Icons/Components/Physics.png rename to Assets/Editor/Icons/Components/Physics.png diff --git a/Editor/Icons/Components/PhysicsConstraint.svg b/Assets/Editor/Icons/Components/PhysicsConstraint.svg similarity index 100% rename from Editor/Icons/Components/PhysicsConstraint.svg rename to Assets/Editor/Icons/Components/PhysicsConstraint.svg diff --git a/Editor/Icons/Components/PointLight.svg b/Assets/Editor/Icons/Components/PointLight.svg similarity index 100% rename from Editor/Icons/Components/PointLight.svg rename to Assets/Editor/Icons/Components/PointLight.svg diff --git a/Editor/Icons/Components/PolygonPrism.svg b/Assets/Editor/Icons/Components/PolygonPrism.svg similarity index 100% rename from Editor/Icons/Components/PolygonPrism.svg rename to Assets/Editor/Icons/Components/PolygonPrism.svg diff --git a/Editor/Icons/Components/PrimitiveCollider.svg b/Assets/Editor/Icons/Components/PrimitiveCollider.svg similarity index 100% rename from Editor/Icons/Components/PrimitiveCollider.svg rename to Assets/Editor/Icons/Components/PrimitiveCollider.svg diff --git a/Editor/Icons/Components/ProjectorLight.svg b/Assets/Editor/Icons/Components/ProjectorLight.svg similarity index 100% rename from Editor/Icons/Components/ProjectorLight.svg rename to Assets/Editor/Icons/Components/ProjectorLight.svg diff --git a/Editor/Icons/Components/Quad_Shape.svg b/Assets/Editor/Icons/Components/Quad_Shape.svg similarity index 100% rename from Editor/Icons/Components/Quad_Shape.svg rename to Assets/Editor/Icons/Components/Quad_Shape.svg diff --git a/Editor/Icons/Components/Ragdoll.png b/Assets/Editor/Icons/Components/Ragdoll.png similarity index 100% rename from Editor/Icons/Components/Ragdoll.png rename to Assets/Editor/Icons/Components/Ragdoll.png diff --git a/Editor/Icons/Components/RandomTimedSpawner.svg b/Assets/Editor/Icons/Components/RandomTimedSpawner.svg similarity index 100% rename from Editor/Icons/Components/RandomTimedSpawner.svg rename to Assets/Editor/Icons/Components/RandomTimedSpawner.svg diff --git a/Editor/Icons/Components/RigidPhysics.svg b/Assets/Editor/Icons/Components/RigidPhysics.svg similarity index 100% rename from Editor/Icons/Components/RigidPhysics.svg rename to Assets/Editor/Icons/Components/RigidPhysics.svg diff --git a/Editor/Icons/Components/ScriptEventAssetReference.png b/Assets/Editor/Icons/Components/ScriptEventAssetReference.png similarity index 100% rename from Editor/Icons/Components/ScriptEventAssetReference.png rename to Assets/Editor/Icons/Components/ScriptEventAssetReference.png diff --git a/Editor/Icons/Components/Sequence.png b/Assets/Editor/Icons/Components/Sequence.png similarity index 100% rename from Editor/Icons/Components/Sequence.png rename to Assets/Editor/Icons/Components/Sequence.png diff --git a/Editor/Icons/Components/SequenceAgent.png b/Assets/Editor/Icons/Components/SequenceAgent.png similarity index 100% rename from Editor/Icons/Components/SequenceAgent.png rename to Assets/Editor/Icons/Components/SequenceAgent.png diff --git a/Editor/Icons/Components/Shadow.svg b/Assets/Editor/Icons/Components/Shadow.svg similarity index 100% rename from Editor/Icons/Components/Shadow.svg rename to Assets/Editor/Icons/Components/Shadow.svg diff --git a/Editor/Icons/Components/SimpleAnimation.svg b/Assets/Editor/Icons/Components/SimpleAnimation.svg similarity index 100% rename from Editor/Icons/Components/SimpleAnimation.svg rename to Assets/Editor/Icons/Components/SimpleAnimation.svg diff --git a/Editor/Icons/Components/SimpleLODDistance.svg b/Assets/Editor/Icons/Components/SimpleLODDistance.svg similarity index 100% rename from Editor/Icons/Components/SimpleLODDistance.svg rename to Assets/Editor/Icons/Components/SimpleLODDistance.svg diff --git a/Editor/Icons/Components/SimpleMotion.svg b/Assets/Editor/Icons/Components/SimpleMotion.svg similarity index 100% rename from Editor/Icons/Components/SimpleMotion.svg rename to Assets/Editor/Icons/Components/SimpleMotion.svg diff --git a/Editor/Icons/Components/SimpleState.svg b/Assets/Editor/Icons/Components/SimpleState.svg similarity index 100% rename from Editor/Icons/Components/SimpleState.svg rename to Assets/Editor/Icons/Components/SimpleState.svg diff --git a/Editor/Icons/Components/SkinnedMesh.svg b/Assets/Editor/Icons/Components/SkinnedMesh.svg similarity index 100% rename from Editor/Icons/Components/SkinnedMesh.svg rename to Assets/Editor/Icons/Components/SkinnedMesh.svg diff --git a/Editor/Icons/Components/SkyHighlight.svg b/Assets/Editor/Icons/Components/SkyHighlight.svg similarity index 100% rename from Editor/Icons/Components/SkyHighlight.svg rename to Assets/Editor/Icons/Components/SkyHighlight.svg diff --git a/Editor/Icons/Components/Snow.svg b/Assets/Editor/Icons/Components/Snow.svg similarity index 100% rename from Editor/Icons/Components/Snow.svg rename to Assets/Editor/Icons/Components/Snow.svg diff --git a/Editor/Icons/Components/Spawner.svg b/Assets/Editor/Icons/Components/Spawner.svg similarity index 100% rename from Editor/Icons/Components/Spawner.svg rename to Assets/Editor/Icons/Components/Spawner.svg diff --git a/Editor/Icons/Components/Sphere.png b/Assets/Editor/Icons/Components/Sphere.png similarity index 100% rename from Editor/Icons/Components/Sphere.png rename to Assets/Editor/Icons/Components/Sphere.png diff --git a/Editor/Icons/Components/Sphere_Shape.svg b/Assets/Editor/Icons/Components/Sphere_Shape.svg similarity index 100% rename from Editor/Icons/Components/Sphere_Shape.svg rename to Assets/Editor/Icons/Components/Sphere_Shape.svg diff --git a/Editor/Icons/Components/Spline.svg b/Assets/Editor/Icons/Components/Spline.svg similarity index 100% rename from Editor/Icons/Components/Spline.svg rename to Assets/Editor/Icons/Components/Spline.svg diff --git a/Editor/Icons/Components/StaticData.png b/Assets/Editor/Icons/Components/StaticData.png similarity index 100% rename from Editor/Icons/Components/StaticData.png rename to Assets/Editor/Icons/Components/StaticData.png diff --git a/Editor/Icons/Components/StaticMesh.svg b/Assets/Editor/Icons/Components/StaticMesh.svg similarity index 100% rename from Editor/Icons/Components/StaticMesh.svg rename to Assets/Editor/Icons/Components/StaticMesh.svg diff --git a/Editor/Icons/Components/StaticPhysics.svg b/Assets/Editor/Icons/Components/StaticPhysics.svg similarity index 100% rename from Editor/Icons/Components/StaticPhysics.svg rename to Assets/Editor/Icons/Components/StaticPhysics.svg diff --git a/Editor/Icons/Components/Tag.svg b/Assets/Editor/Icons/Components/Tag.svg similarity index 100% rename from Editor/Icons/Components/Tag.svg rename to Assets/Editor/Icons/Components/Tag.svg diff --git a/Editor/Icons/Components/Transform.svg b/Assets/Editor/Icons/Components/Transform.svg similarity index 100% rename from Editor/Icons/Components/Transform.svg rename to Assets/Editor/Icons/Components/Transform.svg diff --git a/Editor/Icons/Components/TriggerArea.svg b/Assets/Editor/Icons/Components/TriggerArea.svg similarity index 100% rename from Editor/Icons/Components/TriggerArea.svg rename to Assets/Editor/Icons/Components/TriggerArea.svg diff --git a/Editor/Icons/Components/Tube_Shape.svg b/Assets/Editor/Icons/Components/Tube_Shape.svg similarity index 100% rename from Editor/Icons/Components/Tube_Shape.svg rename to Assets/Editor/Icons/Components/Tube_Shape.svg diff --git a/Editor/Icons/Components/UICanvasAssetRef.svg b/Assets/Editor/Icons/Components/UICanvasAssetRef.svg similarity index 100% rename from Editor/Icons/Components/UICanvasAssetRef.svg rename to Assets/Editor/Icons/Components/UICanvasAssetRef.svg diff --git a/Editor/Icons/Components/UICanvasOnMesh.svg b/Assets/Editor/Icons/Components/UICanvasOnMesh.svg similarity index 100% rename from Editor/Icons/Components/UICanvasOnMesh.svg rename to Assets/Editor/Icons/Components/UICanvasOnMesh.svg diff --git a/Editor/Icons/Components/UICanvasProxyRef.svg b/Assets/Editor/Icons/Components/UICanvasProxyRef.svg similarity index 100% rename from Editor/Icons/Components/UICanvasProxyRef.svg rename to Assets/Editor/Icons/Components/UICanvasProxyRef.svg diff --git a/Editor/Icons/Components/VRPreview.svg b/Assets/Editor/Icons/Components/VRPreview.svg similarity index 100% rename from Editor/Icons/Components/VRPreview.svg rename to Assets/Editor/Icons/Components/VRPreview.svg diff --git a/Editor/Icons/Components/Viewport/Animation.png b/Assets/Editor/Icons/Components/Viewport/Animation.png similarity index 100% rename from Editor/Icons/Components/Viewport/Animation.png rename to Assets/Editor/Icons/Components/Viewport/Animation.png diff --git a/Editor/Icons/Components/Viewport/AreaLight.png b/Assets/Editor/Icons/Components/Viewport/AreaLight.png similarity index 100% rename from Editor/Icons/Components/Viewport/AreaLight.png rename to Assets/Editor/Icons/Components/Viewport/AreaLight.png diff --git a/Editor/Icons/Components/Viewport/Attachment.png b/Assets/Editor/Icons/Components/Viewport/Attachment.png similarity index 100% rename from Editor/Icons/Components/Viewport/Attachment.png rename to Assets/Editor/Icons/Components/Viewport/Attachment.png diff --git a/Editor/Icons/Components/Viewport/AudioArea.png b/Assets/Editor/Icons/Components/Viewport/AudioArea.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioArea.png rename to Assets/Editor/Icons/Components/Viewport/AudioArea.png diff --git a/Editor/Icons/Components/Viewport/AudioAreaEnvironment.png b/Assets/Editor/Icons/Components/Viewport/AudioAreaEnvironment.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioAreaEnvironment.png rename to Assets/Editor/Icons/Components/Viewport/AudioAreaEnvironment.png diff --git a/Editor/Icons/Components/Viewport/AudioEnvironment.png b/Assets/Editor/Icons/Components/Viewport/AudioEnvironment.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioEnvironment.png rename to Assets/Editor/Icons/Components/Viewport/AudioEnvironment.png diff --git a/Editor/Icons/Components/Viewport/AudioListener.png b/Assets/Editor/Icons/Components/Viewport/AudioListener.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioListener.png rename to Assets/Editor/Icons/Components/Viewport/AudioListener.png diff --git a/Editor/Icons/Components/Viewport/AudioMultiPosition.png b/Assets/Editor/Icons/Components/Viewport/AudioMultiPosition.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioMultiPosition.png rename to Assets/Editor/Icons/Components/Viewport/AudioMultiPosition.png diff --git a/Editor/Icons/Components/Viewport/AudioRtpc.png b/Assets/Editor/Icons/Components/Viewport/AudioRtpc.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioRtpc.png rename to Assets/Editor/Icons/Components/Viewport/AudioRtpc.png diff --git a/Editor/Icons/Components/Viewport/AudioSwitch.png b/Assets/Editor/Icons/Components/Viewport/AudioSwitch.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioSwitch.png rename to Assets/Editor/Icons/Components/Viewport/AudioSwitch.png diff --git a/Editor/Icons/Components/Viewport/AudioTrigger.png b/Assets/Editor/Icons/Components/Viewport/AudioTrigger.png similarity index 100% rename from Editor/Icons/Components/Viewport/AudioTrigger.png rename to Assets/Editor/Icons/Components/Viewport/AudioTrigger.png diff --git a/Editor/Icons/Components/Viewport/BehaviorTree.png b/Assets/Editor/Icons/Components/Viewport/BehaviorTree.png similarity index 100% rename from Editor/Icons/Components/Viewport/BehaviorTree.png rename to Assets/Editor/Icons/Components/Viewport/BehaviorTree.png diff --git a/Editor/Icons/Components/Viewport/Box.png b/Assets/Editor/Icons/Components/Viewport/Box.png similarity index 100% rename from Editor/Icons/Components/Viewport/Box.png rename to Assets/Editor/Icons/Components/Viewport/Box.png diff --git a/Editor/Icons/Components/Viewport/Box_Shape.png b/Assets/Editor/Icons/Components/Viewport/Box_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Box_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Box_Shape.png diff --git a/Editor/Icons/Components/Viewport/Capsule.png b/Assets/Editor/Icons/Components/Viewport/Capsule.png similarity index 100% rename from Editor/Icons/Components/Viewport/Capsule.png rename to Assets/Editor/Icons/Components/Viewport/Capsule.png diff --git a/Editor/Icons/Components/Viewport/Capsule_Shape.png b/Assets/Editor/Icons/Components/Viewport/Capsule_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Capsule_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Capsule_Shape.png diff --git a/Editor/Icons/Components/Viewport/CharacterPhysics.png b/Assets/Editor/Icons/Components/Viewport/CharacterPhysics.png similarity index 100% rename from Editor/Icons/Components/Viewport/CharacterPhysics.png rename to Assets/Editor/Icons/Components/Viewport/CharacterPhysics.png diff --git a/Editor/Icons/Components/Viewport/Comment.png b/Assets/Editor/Icons/Components/Viewport/Comment.png similarity index 100% rename from Editor/Icons/Components/Viewport/Comment.png rename to Assets/Editor/Icons/Components/Viewport/Comment.png diff --git a/Editor/Icons/Components/Viewport/ComponentPlaceholder.png b/Assets/Editor/Icons/Components/Viewport/ComponentPlaceholder.png similarity index 100% rename from Editor/Icons/Components/Viewport/ComponentPlaceholder.png rename to Assets/Editor/Icons/Components/Viewport/ComponentPlaceholder.png diff --git a/Editor/Icons/Components/Viewport/Component_Placeholder.png b/Assets/Editor/Icons/Components/Viewport/Component_Placeholder.png similarity index 100% rename from Editor/Icons/Components/Viewport/Component_Placeholder.png rename to Assets/Editor/Icons/Components/Viewport/Component_Placeholder.png diff --git a/Editor/Icons/Components/Viewport/Cylinder.png b/Assets/Editor/Icons/Components/Viewport/Cylinder.png similarity index 100% rename from Editor/Icons/Components/Viewport/Cylinder.png rename to Assets/Editor/Icons/Components/Viewport/Cylinder.png diff --git a/Editor/Icons/Components/Viewport/Cylinder_Shape.png b/Assets/Editor/Icons/Components/Viewport/Cylinder_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Cylinder_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Cylinder_Shape.png diff --git a/Editor/Icons/Components/Viewport/Decal.png b/Assets/Editor/Icons/Components/Viewport/Decal.png similarity index 100% rename from Editor/Icons/Components/Viewport/Decal.png rename to Assets/Editor/Icons/Components/Viewport/Decal.png diff --git a/Editor/Icons/Components/Viewport/Disk_Shape.png b/Assets/Editor/Icons/Components/Viewport/Disk_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Disk_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Disk_Shape.png diff --git a/Editor/Icons/Components/Viewport/DynamicContent.png b/Assets/Editor/Icons/Components/Viewport/DynamicContent.png similarity index 100% rename from Editor/Icons/Components/Viewport/DynamicContent.png rename to Assets/Editor/Icons/Components/Viewport/DynamicContent.png diff --git a/Editor/Icons/Components/Viewport/DynamicMesh.png b/Assets/Editor/Icons/Components/Viewport/DynamicMesh.png similarity index 100% rename from Editor/Icons/Components/Viewport/DynamicMesh.png rename to Assets/Editor/Icons/Components/Viewport/DynamicMesh.png diff --git a/Editor/Icons/Components/Viewport/Entity.png b/Assets/Editor/Icons/Components/Viewport/Entity.png similarity index 100% rename from Editor/Icons/Components/Viewport/Entity.png rename to Assets/Editor/Icons/Components/Viewport/Entity.png diff --git a/Editor/Icons/Components/Viewport/EntityInSlice.png b/Assets/Editor/Icons/Components/Viewport/EntityInSlice.png similarity index 100% rename from Editor/Icons/Components/Viewport/EntityInSlice.png rename to Assets/Editor/Icons/Components/Viewport/EntityInSlice.png diff --git a/Editor/Icons/Components/Viewport/EnvironmentProbe.png b/Assets/Editor/Icons/Components/Viewport/EnvironmentProbe.png similarity index 100% rename from Editor/Icons/Components/Viewport/EnvironmentProbe.png rename to Assets/Editor/Icons/Components/Viewport/EnvironmentProbe.png diff --git a/Editor/Icons/Components/Viewport/Flipbook.png b/Assets/Editor/Icons/Components/Viewport/Flipbook.png similarity index 100% rename from Editor/Icons/Components/Viewport/Flipbook.png rename to Assets/Editor/Icons/Components/Viewport/Flipbook.png diff --git a/Editor/Icons/Components/Viewport/FogVolume.png b/Assets/Editor/Icons/Components/Viewport/FogVolume.png similarity index 100% rename from Editor/Icons/Components/Viewport/FogVolume.png rename to Assets/Editor/Icons/Components/Viewport/FogVolume.png diff --git a/Editor/Icons/Components/Viewport/ForceVolume.png b/Assets/Editor/Icons/Components/Viewport/ForceVolume.png similarity index 100% rename from Editor/Icons/Components/Viewport/ForceVolume.png rename to Assets/Editor/Icons/Components/Viewport/ForceVolume.png diff --git a/Editor/Icons/Components/Viewport/GeometryCache.png b/Assets/Editor/Icons/Components/Viewport/GeometryCache.png similarity index 100% rename from Editor/Icons/Components/Viewport/GeometryCache.png rename to Assets/Editor/Icons/Components/Viewport/GeometryCache.png diff --git a/Editor/Icons/Components/Viewport/HttpClientComponent.png b/Assets/Editor/Icons/Components/Viewport/HttpClientComponent.png similarity index 100% rename from Editor/Icons/Components/Viewport/HttpClientComponent.png rename to Assets/Editor/Icons/Components/Viewport/HttpClientComponent.png diff --git a/Editor/Icons/Components/Viewport/LensFlare.png b/Assets/Editor/Icons/Components/Viewport/LensFlare.png similarity index 100% rename from Editor/Icons/Components/Viewport/LensFlare.png rename to Assets/Editor/Icons/Components/Viewport/LensFlare.png diff --git a/Editor/Icons/Components/Viewport/Light.png b/Assets/Editor/Icons/Components/Viewport/Light.png similarity index 100% rename from Editor/Icons/Components/Viewport/Light.png rename to Assets/Editor/Icons/Components/Viewport/Light.png diff --git a/Editor/Icons/Components/Viewport/Lightning.png b/Assets/Editor/Icons/Components/Viewport/Lightning.png similarity index 100% rename from Editor/Icons/Components/Viewport/Lightning.png rename to Assets/Editor/Icons/Components/Viewport/Lightning.png diff --git a/Editor/Icons/Components/Viewport/LightningArc.png b/Assets/Editor/Icons/Components/Viewport/LightningArc.png similarity index 100% rename from Editor/Icons/Components/Viewport/LightningArc.png rename to Assets/Editor/Icons/Components/Viewport/LightningArc.png diff --git a/Editor/Icons/Components/Viewport/LookAt.png b/Assets/Editor/Icons/Components/Viewport/LookAt.png similarity index 100% rename from Editor/Icons/Components/Viewport/LookAt.png rename to Assets/Editor/Icons/Components/Viewport/LookAt.png diff --git a/Editor/Icons/Components/Viewport/Mannequin.png b/Assets/Editor/Icons/Components/Viewport/Mannequin.png similarity index 100% rename from Editor/Icons/Components/Viewport/Mannequin.png rename to Assets/Editor/Icons/Components/Viewport/Mannequin.png diff --git a/Editor/Icons/Components/Viewport/MannequinScopeContext.png b/Assets/Editor/Icons/Components/Viewport/MannequinScopeContext.png similarity index 100% rename from Editor/Icons/Components/Viewport/MannequinScopeContext.png rename to Assets/Editor/Icons/Components/Viewport/MannequinScopeContext.png diff --git a/Editor/Icons/Components/Viewport/MeshCollider.png b/Assets/Editor/Icons/Components/Viewport/MeshCollider.png similarity index 100% rename from Editor/Icons/Components/Viewport/MeshCollider.png rename to Assets/Editor/Icons/Components/Viewport/MeshCollider.png diff --git a/Editor/Icons/Components/Viewport/MotionParameterSmoothing.png b/Assets/Editor/Icons/Components/Viewport/MotionParameterSmoothing.png similarity index 100% rename from Editor/Icons/Components/Viewport/MotionParameterSmoothing.png rename to Assets/Editor/Icons/Components/Viewport/MotionParameterSmoothing.png diff --git a/Editor/Icons/Components/Viewport/Navigation.png b/Assets/Editor/Icons/Components/Viewport/Navigation.png similarity index 100% rename from Editor/Icons/Components/Viewport/Navigation.png rename to Assets/Editor/Icons/Components/Viewport/Navigation.png diff --git a/Editor/Icons/Components/Viewport/NavigationArea.png b/Assets/Editor/Icons/Components/Viewport/NavigationArea.png similarity index 100% rename from Editor/Icons/Components/Viewport/NavigationArea.png rename to Assets/Editor/Icons/Components/Viewport/NavigationArea.png diff --git a/Editor/Icons/Components/Viewport/NavigationSeed.png b/Assets/Editor/Icons/Components/Viewport/NavigationSeed.png similarity index 100% rename from Editor/Icons/Components/Viewport/NavigationSeed.png rename to Assets/Editor/Icons/Components/Viewport/NavigationSeed.png diff --git a/Editor/Icons/Components/Viewport/NetBinding.png b/Assets/Editor/Icons/Components/Viewport/NetBinding.png similarity index 100% rename from Editor/Icons/Components/Viewport/NetBinding.png rename to Assets/Editor/Icons/Components/Viewport/NetBinding.png diff --git a/Editor/Icons/Components/Viewport/Nova.png b/Assets/Editor/Icons/Components/Viewport/Nova.png similarity index 100% rename from Editor/Icons/Components/Viewport/Nova.png rename to Assets/Editor/Icons/Components/Viewport/Nova.png diff --git a/Editor/Icons/Components/Viewport/ObjectAvoidance.png b/Assets/Editor/Icons/Components/Viewport/ObjectAvoidance.png similarity index 100% rename from Editor/Icons/Components/Viewport/ObjectAvoidance.png rename to Assets/Editor/Icons/Components/Viewport/ObjectAvoidance.png diff --git a/Editor/Icons/Components/Viewport/Particle.png b/Assets/Editor/Icons/Components/Viewport/Particle.png similarity index 100% rename from Editor/Icons/Components/Viewport/Particle.png rename to Assets/Editor/Icons/Components/Viewport/Particle.png diff --git a/Editor/Icons/Components/Viewport/Physics.png b/Assets/Editor/Icons/Components/Viewport/Physics.png similarity index 100% rename from Editor/Icons/Components/Viewport/Physics.png rename to Assets/Editor/Icons/Components/Viewport/Physics.png diff --git a/Editor/Icons/Components/Viewport/PhysicsConstraint.png b/Assets/Editor/Icons/Components/Viewport/PhysicsConstraint.png similarity index 100% rename from Editor/Icons/Components/Viewport/PhysicsConstraint.png rename to Assets/Editor/Icons/Components/Viewport/PhysicsConstraint.png diff --git a/Editor/Icons/Components/Viewport/PointLight.png b/Assets/Editor/Icons/Components/Viewport/PointLight.png similarity index 100% rename from Editor/Icons/Components/Viewport/PointLight.png rename to Assets/Editor/Icons/Components/Viewport/PointLight.png diff --git a/Editor/Icons/Components/Viewport/PolygonPrism.png b/Assets/Editor/Icons/Components/Viewport/PolygonPrism.png similarity index 100% rename from Editor/Icons/Components/Viewport/PolygonPrism.png rename to Assets/Editor/Icons/Components/Viewport/PolygonPrism.png diff --git a/Editor/Icons/Components/Viewport/Primitive Collider.png b/Assets/Editor/Icons/Components/Viewport/Primitive Collider.png similarity index 100% rename from Editor/Icons/Components/Viewport/Primitive Collider.png rename to Assets/Editor/Icons/Components/Viewport/Primitive Collider.png diff --git a/Editor/Icons/Components/Viewport/PrimitiveCollider.png b/Assets/Editor/Icons/Components/Viewport/PrimitiveCollider.png similarity index 100% rename from Editor/Icons/Components/Viewport/PrimitiveCollider.png rename to Assets/Editor/Icons/Components/Viewport/PrimitiveCollider.png diff --git a/Editor/Icons/Components/Viewport/ProjectorLight.png b/Assets/Editor/Icons/Components/Viewport/ProjectorLight.png similarity index 100% rename from Editor/Icons/Components/Viewport/ProjectorLight.png rename to Assets/Editor/Icons/Components/Viewport/ProjectorLight.png diff --git a/Editor/Icons/Components/Viewport/Quad_Shape.png b/Assets/Editor/Icons/Components/Viewport/Quad_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Quad_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Quad_Shape.png diff --git a/Editor/Icons/Components/Viewport/Ragdoll.png b/Assets/Editor/Icons/Components/Viewport/Ragdoll.png similarity index 100% rename from Editor/Icons/Components/Viewport/Ragdoll.png rename to Assets/Editor/Icons/Components/Viewport/Ragdoll.png diff --git a/Editor/Icons/Components/Viewport/RandomTimedSpawner.png b/Assets/Editor/Icons/Components/Viewport/RandomTimedSpawner.png similarity index 100% rename from Editor/Icons/Components/Viewport/RandomTimedSpawner.png rename to Assets/Editor/Icons/Components/Viewport/RandomTimedSpawner.png diff --git a/Editor/Icons/Components/Viewport/RigidPhysics.png b/Assets/Editor/Icons/Components/Viewport/RigidPhysics.png similarity index 100% rename from Editor/Icons/Components/Viewport/RigidPhysics.png rename to Assets/Editor/Icons/Components/Viewport/RigidPhysics.png diff --git a/Editor/Icons/Components/Viewport/Script.png b/Assets/Editor/Icons/Components/Viewport/Script.png similarity index 100% rename from Editor/Icons/Components/Viewport/Script.png rename to Assets/Editor/Icons/Components/Viewport/Script.png diff --git a/Editor/Icons/Components/Viewport/ScriptEventAssetReference.png b/Assets/Editor/Icons/Components/Viewport/ScriptEventAssetReference.png similarity index 100% rename from Editor/Icons/Components/Viewport/ScriptEventAssetReference.png rename to Assets/Editor/Icons/Components/Viewport/ScriptEventAssetReference.png diff --git a/Editor/Icons/Components/Viewport/Sequence.png b/Assets/Editor/Icons/Components/Viewport/Sequence.png similarity index 100% rename from Editor/Icons/Components/Viewport/Sequence.png rename to Assets/Editor/Icons/Components/Viewport/Sequence.png diff --git a/Editor/Icons/Components/Viewport/SequenceAgent.png b/Assets/Editor/Icons/Components/Viewport/SequenceAgent.png similarity index 100% rename from Editor/Icons/Components/Viewport/SequenceAgent.png rename to Assets/Editor/Icons/Components/Viewport/SequenceAgent.png diff --git a/Editor/Icons/Components/Viewport/Shadow.png b/Assets/Editor/Icons/Components/Viewport/Shadow.png similarity index 100% rename from Editor/Icons/Components/Viewport/Shadow.png rename to Assets/Editor/Icons/Components/Viewport/Shadow.png diff --git a/Editor/Icons/Components/Viewport/SimpleState.png b/Assets/Editor/Icons/Components/Viewport/SimpleState.png similarity index 100% rename from Editor/Icons/Components/Viewport/SimpleState.png rename to Assets/Editor/Icons/Components/Viewport/SimpleState.png diff --git a/Editor/Icons/Components/Viewport/SkinnedMesh.png b/Assets/Editor/Icons/Components/Viewport/SkinnedMesh.png similarity index 100% rename from Editor/Icons/Components/Viewport/SkinnedMesh.png rename to Assets/Editor/Icons/Components/Viewport/SkinnedMesh.png diff --git a/Editor/Icons/Components/Viewport/SkyHighlight.png b/Assets/Editor/Icons/Components/Viewport/SkyHighlight.png similarity index 100% rename from Editor/Icons/Components/Viewport/SkyHighlight.png rename to Assets/Editor/Icons/Components/Viewport/SkyHighlight.png diff --git a/Editor/Icons/Components/Viewport/Snow.png b/Assets/Editor/Icons/Components/Viewport/Snow.png similarity index 100% rename from Editor/Icons/Components/Viewport/Snow.png rename to Assets/Editor/Icons/Components/Viewport/Snow.png diff --git a/Editor/Icons/Components/Viewport/Spawner.png b/Assets/Editor/Icons/Components/Viewport/Spawner.png similarity index 100% rename from Editor/Icons/Components/Viewport/Spawner.png rename to Assets/Editor/Icons/Components/Viewport/Spawner.png diff --git a/Editor/Icons/Components/Viewport/Sphere.png b/Assets/Editor/Icons/Components/Viewport/Sphere.png similarity index 100% rename from Editor/Icons/Components/Viewport/Sphere.png rename to Assets/Editor/Icons/Components/Viewport/Sphere.png diff --git a/Editor/Icons/Components/Viewport/Sphere_Shape.png b/Assets/Editor/Icons/Components/Viewport/Sphere_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Sphere_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Sphere_Shape.png diff --git a/Editor/Icons/Components/Viewport/Spline.png b/Assets/Editor/Icons/Components/Viewport/Spline.png similarity index 100% rename from Editor/Icons/Components/Viewport/Spline.png rename to Assets/Editor/Icons/Components/Viewport/Spline.png diff --git a/Editor/Icons/Components/Viewport/StaticData.png b/Assets/Editor/Icons/Components/Viewport/StaticData.png similarity index 100% rename from Editor/Icons/Components/Viewport/StaticData.png rename to Assets/Editor/Icons/Components/Viewport/StaticData.png diff --git a/Editor/Icons/Components/Viewport/StaticMesh.png b/Assets/Editor/Icons/Components/Viewport/StaticMesh.png similarity index 100% rename from Editor/Icons/Components/Viewport/StaticMesh.png rename to Assets/Editor/Icons/Components/Viewport/StaticMesh.png diff --git a/Editor/Icons/Components/Viewport/StaticPhysics.png b/Assets/Editor/Icons/Components/Viewport/StaticPhysics.png similarity index 100% rename from Editor/Icons/Components/Viewport/StaticPhysics.png rename to Assets/Editor/Icons/Components/Viewport/StaticPhysics.png diff --git a/Editor/Icons/Components/Viewport/Tag.png b/Assets/Editor/Icons/Components/Viewport/Tag.png similarity index 100% rename from Editor/Icons/Components/Viewport/Tag.png rename to Assets/Editor/Icons/Components/Viewport/Tag.png diff --git a/Editor/Icons/Components/Viewport/TerrainPhysics.png b/Assets/Editor/Icons/Components/Viewport/TerrainPhysics.png similarity index 100% rename from Editor/Icons/Components/Viewport/TerrainPhysics.png rename to Assets/Editor/Icons/Components/Viewport/TerrainPhysics.png diff --git a/Editor/Icons/Components/Viewport/Transform.png b/Assets/Editor/Icons/Components/Viewport/Transform.png similarity index 100% rename from Editor/Icons/Components/Viewport/Transform.png rename to Assets/Editor/Icons/Components/Viewport/Transform.png diff --git a/Editor/Icons/Components/Viewport/Trigger.png b/Assets/Editor/Icons/Components/Viewport/Trigger.png similarity index 100% rename from Editor/Icons/Components/Viewport/Trigger.png rename to Assets/Editor/Icons/Components/Viewport/Trigger.png diff --git a/Editor/Icons/Components/Viewport/Tube_Shape.png b/Assets/Editor/Icons/Components/Viewport/Tube_Shape.png similarity index 100% rename from Editor/Icons/Components/Viewport/Tube_Shape.png rename to Assets/Editor/Icons/Components/Viewport/Tube_Shape.png diff --git a/Editor/Icons/Components/Viewport/UiCanvasOnMesh.png b/Assets/Editor/Icons/Components/Viewport/UiCanvasOnMesh.png similarity index 100% rename from Editor/Icons/Components/Viewport/UiCanvasOnMesh.png rename to Assets/Editor/Icons/Components/Viewport/UiCanvasOnMesh.png diff --git a/Editor/Icons/Components/Viewport/UiCanvasRef.png b/Assets/Editor/Icons/Components/Viewport/UiCanvasRef.png similarity index 100% rename from Editor/Icons/Components/Viewport/UiCanvasRef.png rename to Assets/Editor/Icons/Components/Viewport/UiCanvasRef.png diff --git a/Editor/Icons/Components/Viewport/VRPreview.png b/Assets/Editor/Icons/Components/Viewport/VRPreview.png similarity index 100% rename from Editor/Icons/Components/Viewport/VRPreview.png rename to Assets/Editor/Icons/Components/Viewport/VRPreview.png diff --git a/Editor/Icons/Components/Viewport/WaterVolume.png b/Assets/Editor/Icons/Components/Viewport/WaterVolume.png similarity index 100% rename from Editor/Icons/Components/Viewport/WaterVolume.png rename to Assets/Editor/Icons/Components/Viewport/WaterVolume.png diff --git a/Editor/Icons/Components/Viewport/WindVolume.png b/Assets/Editor/Icons/Components/Viewport/WindVolume.png similarity index 100% rename from Editor/Icons/Components/Viewport/WindVolume.png rename to Assets/Editor/Icons/Components/Viewport/WindVolume.png diff --git a/Editor/Icons/Components/WaterRippleGenerator.svg b/Assets/Editor/Icons/Components/WaterRippleGenerator.svg similarity index 100% rename from Editor/Icons/Components/WaterRippleGenerator.svg rename to Assets/Editor/Icons/Components/WaterRippleGenerator.svg diff --git a/Editor/Icons/Components/WaterVolume.svg b/Assets/Editor/Icons/Components/WaterVolume.svg similarity index 100% rename from Editor/Icons/Components/WaterVolume.svg rename to Assets/Editor/Icons/Components/WaterVolume.svg diff --git a/Editor/Icons/Components/WindVolume.svg b/Assets/Editor/Icons/Components/WindVolume.svg similarity index 100% rename from Editor/Icons/Components/WindVolume.svg rename to Assets/Editor/Icons/Components/WindVolume.svg diff --git a/Editor/Icons/PhysX/Move.svg b/Assets/Editor/Icons/PhysX/Move.svg similarity index 100% rename from Editor/Icons/PhysX/Move.svg rename to Assets/Editor/Icons/PhysX/Move.svg diff --git a/Editor/Icons/PhysX/Rotate.svg b/Assets/Editor/Icons/PhysX/Rotate.svg similarity index 100% rename from Editor/Icons/PhysX/Rotate.svg rename to Assets/Editor/Icons/PhysX/Rotate.svg diff --git a/Editor/Icons/PhysX/Scale.svg b/Assets/Editor/Icons/PhysX/Scale.svg similarity index 100% rename from Editor/Icons/PhysX/Scale.svg rename to Assets/Editor/Icons/PhysX/Scale.svg diff --git a/Editor/Icons/PropertyEditor/Browse.png b/Assets/Editor/Icons/PropertyEditor/Browse.png similarity index 100% rename from Editor/Icons/PropertyEditor/Browse.png rename to Assets/Editor/Icons/PropertyEditor/Browse.png diff --git a/Editor/Icons/PropertyEditor/Browse_on.png b/Assets/Editor/Icons/PropertyEditor/Browse_on.png similarity index 100% rename from Editor/Icons/PropertyEditor/Browse_on.png rename to Assets/Editor/Icons/PropertyEditor/Browse_on.png diff --git a/Editor/Icons/PropertyEditor/add.png b/Assets/Editor/Icons/PropertyEditor/add.png similarity index 100% rename from Editor/Icons/PropertyEditor/add.png rename to Assets/Editor/Icons/PropertyEditor/add.png diff --git a/Editor/Icons/PropertyEditor/cross-circle-small.png b/Assets/Editor/Icons/PropertyEditor/cross-circle-small.png similarity index 100% rename from Editor/Icons/PropertyEditor/cross-circle-small.png rename to Assets/Editor/Icons/PropertyEditor/cross-circle-small.png diff --git a/Editor/Icons/PropertyEditor/cross-small.png b/Assets/Editor/Icons/PropertyEditor/cross-small.png similarity index 100% rename from Editor/Icons/PropertyEditor/cross-small.png rename to Assets/Editor/Icons/PropertyEditor/cross-small.png diff --git a/Editor/Icons/PropertyEditor/error_icon.png b/Assets/Editor/Icons/PropertyEditor/error_icon.png similarity index 100% rename from Editor/Icons/PropertyEditor/error_icon.png rename to Assets/Editor/Icons/PropertyEditor/error_icon.png diff --git a/Editor/Icons/PropertyEditor/group_closed.png b/Assets/Editor/Icons/PropertyEditor/group_closed.png similarity index 100% rename from Editor/Icons/PropertyEditor/group_closed.png rename to Assets/Editor/Icons/PropertyEditor/group_closed.png diff --git a/Editor/Icons/PropertyEditor/group_open.png b/Assets/Editor/Icons/PropertyEditor/group_open.png similarity index 100% rename from Editor/Icons/PropertyEditor/group_open.png rename to Assets/Editor/Icons/PropertyEditor/group_open.png diff --git a/Editor/Icons/PropertyEditor/image_icon.svg b/Assets/Editor/Icons/PropertyEditor/image_icon.svg similarity index 100% rename from Editor/Icons/PropertyEditor/image_icon.svg rename to Assets/Editor/Icons/PropertyEditor/image_icon.svg diff --git a/Editor/Icons/PropertyEditor/list-add-small.png b/Assets/Editor/Icons/PropertyEditor/list-add-small.png similarity index 100% rename from Editor/Icons/PropertyEditor/list-add-small.png rename to Assets/Editor/Icons/PropertyEditor/list-add-small.png diff --git a/Editor/Icons/PropertyEditor/open_in.png b/Assets/Editor/Icons/PropertyEditor/open_in.png similarity index 100% rename from Editor/Icons/PropertyEditor/open_in.png rename to Assets/Editor/Icons/PropertyEditor/open_in.png diff --git a/Editor/Icons/PropertyEditor/point_hand.png b/Assets/Editor/Icons/PropertyEditor/point_hand.png similarity index 100% rename from Editor/Icons/PropertyEditor/point_hand.png rename to Assets/Editor/Icons/PropertyEditor/point_hand.png diff --git a/Editor/Icons/PropertyEditor/remove.png b/Assets/Editor/Icons/PropertyEditor/remove.png similarity index 100% rename from Editor/Icons/PropertyEditor/remove.png rename to Assets/Editor/Icons/PropertyEditor/remove.png diff --git a/Editor/Icons/PropertyEditor/reset_icon.png b/Assets/Editor/Icons/PropertyEditor/reset_icon.png similarity index 100% rename from Editor/Icons/PropertyEditor/reset_icon.png rename to Assets/Editor/Icons/PropertyEditor/reset_icon.png diff --git a/Editor/Icons/PropertyEditor/tool_cancel.png b/Assets/Editor/Icons/PropertyEditor/tool_cancel.png similarity index 100% rename from Editor/Icons/PropertyEditor/tool_cancel.png rename to Assets/Editor/Icons/PropertyEditor/tool_cancel.png diff --git a/Editor/Icons/PropertyEditor/tool_cancel_highlight.png b/Assets/Editor/Icons/PropertyEditor/tool_cancel_highlight.png similarity index 100% rename from Editor/Icons/PropertyEditor/tool_cancel_highlight.png rename to Assets/Editor/Icons/PropertyEditor/tool_cancel_highlight.png diff --git a/Editor/Icons/PropertyEditor/tool_cancel_hover.png b/Assets/Editor/Icons/PropertyEditor/tool_cancel_hover.png similarity index 100% rename from Editor/Icons/PropertyEditor/tool_cancel_hover.png rename to Assets/Editor/Icons/PropertyEditor/tool_cancel_hover.png diff --git a/Editor/Icons/PropertyEditor/trash-small.png b/Assets/Editor/Icons/PropertyEditor/trash-small.png similarity index 100% rename from Editor/Icons/PropertyEditor/trash-small.png rename to Assets/Editor/Icons/PropertyEditor/trash-small.png diff --git a/Editor/Icons/PropertyEditor/tree_closed.png b/Assets/Editor/Icons/PropertyEditor/tree_closed.png similarity index 100% rename from Editor/Icons/PropertyEditor/tree_closed.png rename to Assets/Editor/Icons/PropertyEditor/tree_closed.png diff --git a/Editor/Icons/PropertyEditor/tree_open.png b/Assets/Editor/Icons/PropertyEditor/tree_open.png similarity index 100% rename from Editor/Icons/PropertyEditor/tree_open.png rename to Assets/Editor/Icons/PropertyEditor/tree_open.png diff --git a/Editor/Icons/RotationWarning.png b/Assets/Editor/Icons/RotationWarning.png similarity index 100% rename from Editor/Icons/RotationWarning.png rename to Assets/Editor/Icons/RotationWarning.png diff --git a/Editor/Icons/ScaleWarning.png b/Assets/Editor/Icons/ScaleWarning.png similarity index 100% rename from Editor/Icons/ScaleWarning.png rename to Assets/Editor/Icons/ScaleWarning.png diff --git a/Editor/Icons/ScriptCanvas/Add.png b/Assets/Editor/Icons/ScriptCanvas/Add.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Add.png rename to Assets/Editor/Icons/ScriptCanvas/Add.png diff --git a/Editor/Icons/ScriptCanvas/And.png b/Assets/Editor/Icons/ScriptCanvas/And.png similarity index 100% rename from Editor/Icons/ScriptCanvas/And.png rename to Assets/Editor/Icons/ScriptCanvas/And.png diff --git a/Editor/Icons/ScriptCanvas/Boolean.png b/Assets/Editor/Icons/ScriptCanvas/Boolean.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Boolean.png rename to Assets/Editor/Icons/ScriptCanvas/Boolean.png diff --git a/Editor/Icons/ScriptCanvas/Breakpoint.png b/Assets/Editor/Icons/ScriptCanvas/Breakpoint.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Breakpoint.png rename to Assets/Editor/Icons/ScriptCanvas/Breakpoint.png diff --git a/Editor/Icons/ScriptCanvas/Bus.png b/Assets/Editor/Icons/ScriptCanvas/Bus.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Bus.png rename to Assets/Editor/Icons/ScriptCanvas/Bus.png diff --git a/Editor/Icons/ScriptCanvas/Connect.png b/Assets/Editor/Icons/ScriptCanvas/Connect.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Connect.png rename to Assets/Editor/Icons/ScriptCanvas/Connect.png diff --git a/Editor/Icons/ScriptCanvas/Delay.png b/Assets/Editor/Icons/ScriptCanvas/Delay.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Delay.png rename to Assets/Editor/Icons/ScriptCanvas/Delay.png diff --git a/Editor/Icons/ScriptCanvas/Disabled/ScriptCanvas_white.png b/Assets/Editor/Icons/ScriptCanvas/Disabled/ScriptCanvas_white.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Disabled/ScriptCanvas_white.png rename to Assets/Editor/Icons/ScriptCanvas/Disabled/ScriptCanvas_white.png diff --git a/Editor/Icons/ScriptCanvas/Disconnect.png b/Assets/Editor/Icons/ScriptCanvas/Disconnect.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Disconnect.png rename to Assets/Editor/Icons/ScriptCanvas/Disconnect.png diff --git a/Editor/Icons/ScriptCanvas/Divide.png b/Assets/Editor/Icons/ScriptCanvas/Divide.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Divide.png rename to Assets/Editor/Icons/ScriptCanvas/Divide.png diff --git a/Editor/Icons/ScriptCanvas/EntityRef.png b/Assets/Editor/Icons/ScriptCanvas/EntityRef.png similarity index 100% rename from Editor/Icons/ScriptCanvas/EntityRef.png rename to Assets/Editor/Icons/ScriptCanvas/EntityRef.png diff --git a/Editor/Icons/ScriptCanvas/Libraries/All.png b/Assets/Editor/Icons/ScriptCanvas/Libraries/All.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Libraries/All.png rename to Assets/Editor/Icons/ScriptCanvas/Libraries/All.png diff --git a/Editor/Icons/ScriptCanvas/Libraries/Core.png b/Assets/Editor/Icons/ScriptCanvas/Libraries/Core.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Libraries/Core.png rename to Assets/Editor/Icons/ScriptCanvas/Libraries/Core.png diff --git a/Editor/Icons/ScriptCanvas/Libraries/Entity.png b/Assets/Editor/Icons/ScriptCanvas/Libraries/Entity.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Libraries/Entity.png rename to Assets/Editor/Icons/ScriptCanvas/Libraries/Entity.png diff --git a/Editor/Icons/ScriptCanvas/Libraries/Logic.png b/Assets/Editor/Icons/ScriptCanvas/Libraries/Logic.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Libraries/Logic.png rename to Assets/Editor/Icons/ScriptCanvas/Libraries/Logic.png diff --git a/Editor/Icons/ScriptCanvas/Libraries/Math.png b/Assets/Editor/Icons/ScriptCanvas/Libraries/Math.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Libraries/Math.png rename to Assets/Editor/Icons/ScriptCanvas/Libraries/Math.png diff --git a/Editor/Icons/ScriptCanvas/Multiply.png b/Assets/Editor/Icons/ScriptCanvas/Multiply.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Multiply.png rename to Assets/Editor/Icons/ScriptCanvas/Multiply.png diff --git a/Editor/Icons/ScriptCanvas/Not.png b/Assets/Editor/Icons/ScriptCanvas/Not.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Not.png rename to Assets/Editor/Icons/ScriptCanvas/Not.png diff --git a/Editor/Icons/ScriptCanvas/Number.png b/Assets/Editor/Icons/ScriptCanvas/Number.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Number.png rename to Assets/Editor/Icons/ScriptCanvas/Number.png diff --git a/Editor/Icons/ScriptCanvas/Or.png b/Assets/Editor/Icons/ScriptCanvas/Or.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Or.png rename to Assets/Editor/Icons/ScriptCanvas/Or.png diff --git a/Editor/Icons/ScriptCanvas/Placeholder.png b/Assets/Editor/Icons/ScriptCanvas/Placeholder.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Placeholder.png rename to Assets/Editor/Icons/ScriptCanvas/Placeholder.png diff --git a/Editor/Icons/ScriptCanvas/Print.png b/Assets/Editor/Icons/ScriptCanvas/Print.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Print.png rename to Assets/Editor/Icons/ScriptCanvas/Print.png diff --git a/Editor/Icons/ScriptCanvas/Random.png b/Assets/Editor/Icons/ScriptCanvas/Random.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Random.png rename to Assets/Editor/Icons/ScriptCanvas/Random.png diff --git a/Editor/Icons/ScriptCanvas/Rotate.png b/Assets/Editor/Icons/ScriptCanvas/Rotate.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Rotate.png rename to Assets/Editor/Icons/ScriptCanvas/Rotate.png diff --git a/Editor/Icons/ScriptCanvas/ScriptCanvas.svg b/Assets/Editor/Icons/ScriptCanvas/ScriptCanvas.svg similarity index 100% rename from Editor/Icons/ScriptCanvas/ScriptCanvas.svg rename to Assets/Editor/Icons/ScriptCanvas/ScriptCanvas.svg diff --git a/Editor/Icons/ScriptCanvas/Start.png b/Assets/Editor/Icons/ScriptCanvas/Start.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Start.png rename to Assets/Editor/Icons/ScriptCanvas/Start.png diff --git a/Editor/Icons/ScriptCanvas/Step In.png b/Assets/Editor/Icons/ScriptCanvas/Step In.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Step In.png rename to Assets/Editor/Icons/ScriptCanvas/Step In.png diff --git a/Editor/Icons/ScriptCanvas/Step Over.png b/Assets/Editor/Icons/ScriptCanvas/Step Over.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Step Over.png rename to Assets/Editor/Icons/ScriptCanvas/Step Over.png diff --git a/Editor/Icons/ScriptCanvas/String.png b/Assets/Editor/Icons/ScriptCanvas/String.png similarity index 100% rename from Editor/Icons/ScriptCanvas/String.png rename to Assets/Editor/Icons/ScriptCanvas/String.png diff --git a/Editor/Icons/ScriptCanvas/Subtract.png b/Assets/Editor/Icons/ScriptCanvas/Subtract.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Subtract.png rename to Assets/Editor/Icons/ScriptCanvas/Subtract.png diff --git a/Editor/Icons/ScriptCanvas/Sum.png b/Assets/Editor/Icons/ScriptCanvas/Sum.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Sum.png rename to Assets/Editor/Icons/ScriptCanvas/Sum.png diff --git a/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png b/Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png rename to Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png diff --git a/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png b/Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png rename to Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png diff --git a/Editor/Icons/ScriptCanvas/Xor.png b/Assets/Editor/Icons/ScriptCanvas/Xor.png similarity index 100% rename from Editor/Icons/ScriptCanvas/Xor.png rename to Assets/Editor/Icons/ScriptCanvas/Xor.png diff --git a/Editor/Icons/ScriptCanvas/settings.png b/Assets/Editor/Icons/ScriptCanvas/settings.png similarity index 100% rename from Editor/Icons/ScriptCanvas/settings.png rename to Assets/Editor/Icons/ScriptCanvas/settings.png diff --git a/Editor/Icons/WhiteBox/Move.svg b/Assets/Editor/Icons/WhiteBox/Move.svg similarity index 100% rename from Editor/Icons/WhiteBox/Move.svg rename to Assets/Editor/Icons/WhiteBox/Move.svg diff --git a/Editor/Icons/WhiteBox/RestoreMode.svg b/Assets/Editor/Icons/WhiteBox/RestoreMode.svg similarity index 100% rename from Editor/Icons/WhiteBox/RestoreMode.svg rename to Assets/Editor/Icons/WhiteBox/RestoreMode.svg diff --git a/Editor/Icons/WhiteBox/Rotate.svg b/Assets/Editor/Icons/WhiteBox/Rotate.svg similarity index 100% rename from Editor/Icons/WhiteBox/Rotate.svg rename to Assets/Editor/Icons/WhiteBox/Rotate.svg diff --git a/Editor/Icons/WhiteBox/Scale.svg b/Assets/Editor/Icons/WhiteBox/Scale.svg similarity index 100% rename from Editor/Icons/WhiteBox/Scale.svg rename to Assets/Editor/Icons/WhiteBox/Scale.svg diff --git a/Editor/Icons/WhiteBox/SketchMode.svg b/Assets/Editor/Icons/WhiteBox/SketchMode.svg similarity index 100% rename from Editor/Icons/WhiteBox/SketchMode.svg rename to Assets/Editor/Icons/WhiteBox/SketchMode.svg diff --git a/Editor/Icons/animation/add.png b/Assets/Editor/Icons/animation/add.png similarity index 100% rename from Editor/Icons/animation/add.png rename to Assets/Editor/Icons/animation/add.png diff --git a/Editor/Icons/animation/animation.png b/Assets/Editor/Icons/animation/animation.png similarity index 100% rename from Editor/Icons/animation/animation.png rename to Assets/Editor/Icons/animation/animation.png diff --git a/Editor/Icons/animation/animation_additive.png b/Assets/Editor/Icons/animation/animation_additive.png similarity index 100% rename from Editor/Icons/animation/animation_additive.png rename to Assets/Editor/Icons/animation/animation_additive.png diff --git a/Editor/Icons/animation/animation_aimpose.png b/Assets/Editor/Icons/animation/animation_aimpose.png similarity index 100% rename from Editor/Icons/animation/animation_aimpose.png rename to Assets/Editor/Icons/animation/animation_aimpose.png diff --git a/Editor/Icons/animation/animation_bspace.png b/Assets/Editor/Icons/animation/animation_bspace.png similarity index 100% rename from Editor/Icons/animation/animation_bspace.png rename to Assets/Editor/Icons/animation/animation_bspace.png diff --git a/Editor/Icons/animation/animation_comb.png b/Assets/Editor/Icons/animation/animation_comb.png similarity index 100% rename from Editor/Icons/animation/animation_comb.png rename to Assets/Editor/Icons/animation/animation_comb.png diff --git a/Editor/Icons/animation/animation_lookpose.png b/Assets/Editor/Icons/animation/animation_lookpose.png similarity index 100% rename from Editor/Icons/animation/animation_lookpose.png rename to Assets/Editor/Icons/animation/animation_lookpose.png diff --git a/Editor/Icons/animation/animation_offline.png b/Assets/Editor/Icons/animation/animation_offline.png similarity index 100% rename from Editor/Icons/animation/animation_offline.png rename to Assets/Editor/Icons/animation/animation_offline.png diff --git a/Editor/Icons/animation/attachment.png b/Assets/Editor/Icons/animation/attachment.png similarity index 100% rename from Editor/Icons/animation/attachment.png rename to Assets/Editor/Icons/animation/attachment.png diff --git a/Editor/Icons/animation/audio_event_16.png b/Assets/Editor/Icons/animation/audio_event_16.png similarity index 100% rename from Editor/Icons/animation/audio_event_16.png rename to Assets/Editor/Icons/animation/audio_event_16.png diff --git a/Editor/Icons/animation/back_16.png b/Assets/Editor/Icons/animation/back_16.png similarity index 100% rename from Editor/Icons/animation/back_16.png rename to Assets/Editor/Icons/animation/back_16.png diff --git a/Editor/Icons/animation/bind_pose.png b/Assets/Editor/Icons/animation/bind_pose.png similarity index 100% rename from Editor/Icons/animation/bind_pose.png rename to Assets/Editor/Icons/animation/bind_pose.png diff --git a/Editor/Icons/animation/bone.png b/Assets/Editor/Icons/animation/bone.png similarity index 100% rename from Editor/Icons/animation/bone.png rename to Assets/Editor/Icons/animation/bone.png diff --git a/Editor/Icons/animation/build.png b/Assets/Editor/Icons/animation/build.png similarity index 100% rename from Editor/Icons/animation/build.png rename to Assets/Editor/Icons/animation/build.png diff --git a/Editor/Icons/animation/character.png b/Assets/Editor/Icons/animation/character.png similarity index 100% rename from Editor/Icons/animation/character.png rename to Assets/Editor/Icons/animation/character.png diff --git a/Editor/Icons/animation/close.png b/Assets/Editor/Icons/animation/close.png similarity index 100% rename from Editor/Icons/animation/close.png rename to Assets/Editor/Icons/animation/close.png diff --git a/Editor/Icons/animation/close_highlight.png b/Assets/Editor/Icons/animation/close_highlight.png similarity index 100% rename from Editor/Icons/animation/close_highlight.png rename to Assets/Editor/Icons/animation/close_highlight.png diff --git a/Editor/Icons/animation/create_cdf.png b/Assets/Editor/Icons/animation/create_cdf.png similarity index 100% rename from Editor/Icons/animation/create_cdf.png rename to Assets/Editor/Icons/animation/create_cdf.png diff --git a/Editor/Icons/animation/display_options.png b/Assets/Editor/Icons/animation/display_options.png similarity index 100% rename from Editor/Icons/animation/display_options.png rename to Assets/Editor/Icons/animation/display_options.png diff --git a/Editor/Icons/animation/filter_16.png b/Assets/Editor/Icons/animation/filter_16.png similarity index 100% rename from Editor/Icons/animation/filter_16.png rename to Assets/Editor/Icons/animation/filter_16.png diff --git a/Editor/Icons/animation/footsteps.png b/Assets/Editor/Icons/animation/footsteps.png similarity index 100% rename from Editor/Icons/animation/footsteps.png rename to Assets/Editor/Icons/animation/footsteps.png diff --git a/Editor/Icons/animation/force_recompile.png b/Assets/Editor/Icons/animation/force_recompile.png similarity index 100% rename from Editor/Icons/animation/force_recompile.png rename to Assets/Editor/Icons/animation/force_recompile.png diff --git a/Editor/Icons/animation/forward_16.png b/Assets/Editor/Icons/animation/forward_16.png similarity index 100% rename from Editor/Icons/animation/forward_16.png rename to Assets/Editor/Icons/animation/forward_16.png diff --git a/Editor/Icons/animation/gizmo_location.png b/Assets/Editor/Icons/animation/gizmo_location.png similarity index 100% rename from Editor/Icons/animation/gizmo_location.png rename to Assets/Editor/Icons/animation/gizmo_location.png diff --git a/Editor/Icons/animation/grid.png b/Assets/Editor/Icons/animation/grid.png similarity index 100% rename from Editor/Icons/animation/grid.png rename to Assets/Editor/Icons/animation/grid.png diff --git a/Editor/Icons/animation/group.png b/Assets/Editor/Icons/animation/group.png similarity index 100% rename from Editor/Icons/animation/group.png rename to Assets/Editor/Icons/animation/group.png diff --git a/Editor/Icons/animation/import.png b/Assets/Editor/Icons/animation/import.png similarity index 100% rename from Editor/Icons/animation/import.png rename to Assets/Editor/Icons/animation/import.png diff --git a/Editor/Icons/animation/in_folder_16.png b/Assets/Editor/Icons/animation/in_folder_16.png similarity index 100% rename from Editor/Icons/animation/in_folder_16.png rename to Assets/Editor/Icons/animation/in_folder_16.png diff --git a/Editor/Icons/animation/in_folder_and_pak_16.png b/Assets/Editor/Icons/animation/in_folder_and_pak_16.png similarity index 100% rename from Editor/Icons/animation/in_folder_and_pak_16.png rename to Assets/Editor/Icons/animation/in_folder_and_pak_16.png diff --git a/Editor/Icons/animation/in_pak_16.png b/Assets/Editor/Icons/animation/in_pak_16.png similarity index 100% rename from Editor/Icons/animation/in_pak_16.png rename to Assets/Editor/Icons/animation/in_pak_16.png diff --git a/Editor/Icons/animation/lock_16.png b/Assets/Editor/Icons/animation/lock_16.png similarity index 100% rename from Editor/Icons/animation/lock_16.png rename to Assets/Editor/Icons/animation/lock_16.png diff --git a/Editor/Icons/animation/new_animation.png b/Assets/Editor/Icons/animation/new_animation.png similarity index 100% rename from Editor/Icons/animation/new_animation.png rename to Assets/Editor/Icons/animation/new_animation.png diff --git a/Editor/Icons/animation/physics.png b/Assets/Editor/Icons/animation/physics.png similarity index 100% rename from Editor/Icons/animation/physics.png rename to Assets/Editor/Icons/animation/physics.png diff --git a/Editor/Icons/animation/playback_options.png b/Assets/Editor/Icons/animation/playback_options.png similarity index 100% rename from Editor/Icons/animation/playback_options.png rename to Assets/Editor/Icons/animation/playback_options.png diff --git a/Editor/Icons/animation/redo.png b/Assets/Editor/Icons/animation/redo.png similarity index 100% rename from Editor/Icons/animation/redo.png rename to Assets/Editor/Icons/animation/redo.png diff --git a/Editor/Icons/animation/revert.png b/Assets/Editor/Icons/animation/revert.png similarity index 100% rename from Editor/Icons/animation/revert.png rename to Assets/Editor/Icons/animation/revert.png diff --git a/Editor/Icons/animation/rig.png b/Assets/Editor/Icons/animation/rig.png similarity index 100% rename from Editor/Icons/animation/rig.png rename to Assets/Editor/Icons/animation/rig.png diff --git a/Editor/Icons/animation/save.png b/Assets/Editor/Icons/animation/save.png similarity index 100% rename from Editor/Icons/animation/save.png rename to Assets/Editor/Icons/animation/save.png diff --git a/Editor/Icons/animation/selection_16.png b/Assets/Editor/Icons/animation/selection_16.png similarity index 100% rename from Editor/Icons/animation/selection_16.png rename to Assets/Editor/Icons/animation/selection_16.png diff --git a/Editor/Icons/animation/show_in_explorer.png b/Assets/Editor/Icons/animation/show_in_explorer.png similarity index 100% rename from Editor/Icons/animation/show_in_explorer.png rename to Assets/Editor/Icons/animation/show_in_explorer.png diff --git a/Editor/Icons/animation/skeleton.png b/Assets/Editor/Icons/animation/skeleton.png similarity index 100% rename from Editor/Icons/animation/skeleton.png rename to Assets/Editor/Icons/animation/skeleton.png diff --git a/Editor/Icons/animation/skin.png b/Assets/Editor/Icons/animation/skin.png similarity index 100% rename from Editor/Icons/animation/skin.png rename to Assets/Editor/Icons/animation/skin.png diff --git a/Editor/Icons/animation/source_asset_16.png b/Assets/Editor/Icons/animation/source_asset_16.png similarity index 100% rename from Editor/Icons/animation/source_asset_16.png rename to Assets/Editor/Icons/animation/source_asset_16.png diff --git a/Editor/Icons/animation/tool_move.png b/Assets/Editor/Icons/animation/tool_move.png similarity index 100% rename from Editor/Icons/animation/tool_move.png rename to Assets/Editor/Icons/animation/tool_move.png diff --git a/Editor/Icons/animation/tool_rotate.png b/Assets/Editor/Icons/animation/tool_rotate.png similarity index 100% rename from Editor/Icons/animation/tool_rotate.png rename to Assets/Editor/Icons/animation/tool_rotate.png diff --git a/Editor/Icons/animation/tool_scale.png b/Assets/Editor/Icons/animation/tool_scale.png similarity index 100% rename from Editor/Icons/animation/tool_scale.png rename to Assets/Editor/Icons/animation/tool_scale.png diff --git a/Editor/Icons/animation/tool_select.png b/Assets/Editor/Icons/animation/tool_select.png similarity index 100% rename from Editor/Icons/animation/tool_select.png rename to Assets/Editor/Icons/animation/tool_select.png diff --git a/Editor/Icons/animation/undo.png b/Assets/Editor/Icons/animation/undo.png similarity index 100% rename from Editor/Icons/animation/undo.png rename to Assets/Editor/Icons/animation/undo.png diff --git a/Editor/Icons/checkmark_checked.png b/Assets/Editor/Icons/checkmark_checked.png similarity index 100% rename from Editor/Icons/checkmark_checked.png rename to Assets/Editor/Icons/checkmark_checked.png diff --git a/Editor/Icons/checkmark_checked_hover.png b/Assets/Editor/Icons/checkmark_checked_hover.png similarity index 100% rename from Editor/Icons/checkmark_checked_hover.png rename to Assets/Editor/Icons/checkmark_checked_hover.png diff --git a/Editor/Icons/checkmark_unchecked_hover.png b/Assets/Editor/Icons/checkmark_unchecked_hover.png similarity index 100% rename from Editor/Icons/checkmark_unchecked_hover.png rename to Assets/Editor/Icons/checkmark_unchecked_hover.png diff --git a/Editor/Icons/close.png b/Assets/Editor/Icons/close.png similarity index 100% rename from Editor/Icons/close.png rename to Assets/Editor/Icons/close.png diff --git a/Editor/Icons/float.png b/Assets/Editor/Icons/float.png similarity index 100% rename from Editor/Icons/float.png rename to Assets/Editor/Icons/float.png diff --git a/Editor/Icons/lc_camera.png b/Assets/Editor/Icons/lc_camera.png similarity index 100% rename from Editor/Icons/lc_camera.png rename to Assets/Editor/Icons/lc_camera.png diff --git a/Editor/Icons/lc_exportandlaunch.png b/Assets/Editor/Icons/lc_exportandlaunch.png similarity index 100% rename from Editor/Icons/lc_exportandlaunch.png rename to Assets/Editor/Icons/lc_exportandlaunch.png diff --git a/Editor/Icons/lc_pc.png b/Assets/Editor/Icons/lc_pc.png similarity index 100% rename from Editor/Icons/lc_pc.png rename to Assets/Editor/Icons/lc_pc.png diff --git a/Editor/Icons/lc_power.png b/Assets/Editor/Icons/lc_power.png similarity index 100% rename from Editor/Icons/lc_power.png rename to Assets/Editor/Icons/lc_power.png diff --git a/Editor/Icons/lc_sshot.png b/Assets/Editor/Icons/lc_sshot.png similarity index 100% rename from Editor/Icons/lc_sshot.png rename to Assets/Editor/Icons/lc_sshot.png diff --git a/Editor/Icons/lc_sync.png b/Assets/Editor/Icons/lc_sync.png similarity index 100% rename from Editor/Icons/lc_sync.png rename to Assets/Editor/Icons/lc_sync.png diff --git a/Editor/Icons/reset.png b/Assets/Editor/Icons/reset.png similarity index 100% rename from Editor/Icons/reset.png rename to Assets/Editor/Icons/reset.png diff --git a/Editor/Icons/split.png b/Assets/Editor/Icons/split.png similarity index 100% rename from Editor/Icons/split.png rename to Assets/Editor/Icons/split.png diff --git a/Editor/LambdaFunctions/LwALambdaFunction.js b/Assets/Editor/LambdaFunctions/LwALambdaFunction.js similarity index 100% rename from Editor/LambdaFunctions/LwALambdaFunction.js rename to Assets/Editor/LambdaFunctions/LwALambdaFunction.js diff --git a/Editor/LambdaFunctions/LwFacebookLambdaFunction.js b/Assets/Editor/LambdaFunctions/LwFacebookLambdaFunction.js similarity index 100% rename from Editor/LambdaFunctions/LwFacebookLambdaFunction.js rename to Assets/Editor/LambdaFunctions/LwFacebookLambdaFunction.js diff --git a/Editor/LambdaFunctions/LwGenericOpenIdConnectLambdaFunction.js b/Assets/Editor/LambdaFunctions/LwGenericOpenIdConnectLambdaFunction.js similarity index 100% rename from Editor/LambdaFunctions/LwGenericOpenIdConnectLambdaFunction.js rename to Assets/Editor/LambdaFunctions/LwGenericOpenIdConnectLambdaFunction.js diff --git a/Editor/LambdaFunctions/LwGoogleLambdaFunction.js b/Assets/Editor/LambdaFunctions/LwGoogleLambdaFunction.js similarity index 100% rename from Editor/LambdaFunctions/LwGoogleLambdaFunction.js rename to Assets/Editor/LambdaFunctions/LwGoogleLambdaFunction.js diff --git a/Editor/LevelTemplates.xml b/Assets/Editor/LevelTemplates.xml similarity index 100% rename from Editor/LevelTemplates.xml rename to Assets/Editor/LevelTemplates.xml diff --git a/Editor/MapScreenshotSettings.xml b/Assets/Editor/MapScreenshotSettings.xml similarity index 100% rename from Editor/MapScreenshotSettings.xml rename to Assets/Editor/MapScreenshotSettings.xml diff --git a/Editor/Materials/ShaderList.xml b/Assets/Editor/Materials/ShaderList.xml similarity index 100% rename from Editor/Materials/ShaderList.xml rename to Assets/Editor/Materials/ShaderList.xml diff --git a/Editor/Materials/Stripes.tif b/Assets/Editor/Materials/Stripes.tif similarity index 100% rename from Editor/Materials/Stripes.tif rename to Assets/Editor/Materials/Stripes.tif diff --git a/Editor/Materials/Stripes.tif.exportsettings b/Assets/Editor/Materials/Stripes.tif.exportsettings similarity index 100% rename from Editor/Materials/Stripes.tif.exportsettings rename to Assets/Editor/Materials/Stripes.tif.exportsettings diff --git a/Editor/Materials/areasolid.dds b/Assets/Editor/Materials/areasolid.dds similarity index 100% rename from Editor/Materials/areasolid.dds rename to Assets/Editor/Materials/areasolid.dds diff --git a/Editor/Materials/areasolid.mtl b/Assets/Editor/Materials/areasolid.mtl similarity index 100% rename from Editor/Materials/areasolid.mtl rename to Assets/Editor/Materials/areasolid.mtl diff --git a/Editor/Materials/crydesigner_selection.mtl b/Assets/Editor/Materials/crydesigner_selection.mtl similarity index 100% rename from Editor/Materials/crydesigner_selection.mtl rename to Assets/Editor/Materials/crydesigner_selection.mtl diff --git a/Editor/Materials/default_rope.mtl b/Assets/Editor/Materials/default_rope.mtl similarity index 100% rename from Editor/Materials/default_rope.mtl rename to Assets/Editor/Materials/default_rope.mtl diff --git a/Assets/Editor/Materials/lodgen_template.mtl b/Assets/Editor/Materials/lodgen_template.mtl new file mode 100644 index 0000000000..761eff9154 --- /dev/null +++ b/Assets/Editor/Materials/lodgen_template.mtl @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Editor/Materials/refpicture.mtl b/Assets/Editor/Materials/refpicture.mtl similarity index 100% rename from Editor/Materials/refpicture.mtl rename to Assets/Editor/Materials/refpicture.mtl diff --git a/Editor/Materials/voxel_editor.mtl b/Assets/Editor/Materials/voxel_editor.mtl similarity index 100% rename from Editor/Materials/voxel_editor.mtl rename to Assets/Editor/Materials/voxel_editor.mtl diff --git a/Editor/Materials/voxel_editor.png b/Assets/Editor/Materials/voxel_editor.png similarity index 100% rename from Editor/Materials/voxel_editor.png rename to Assets/Editor/Materials/voxel_editor.png diff --git a/Editor/Materials/voxel_editor.png.exportsettings b/Assets/Editor/Materials/voxel_editor.png.exportsettings similarity index 100% rename from Editor/Materials/voxel_editor.png.exportsettings rename to Assets/Editor/Materials/voxel_editor.png.exportsettings diff --git a/Editor/MissionTemplate.lua b/Assets/Editor/MissionTemplate.lua similarity index 100% rename from Editor/MissionTemplate.lua rename to Assets/Editor/MissionTemplate.lua diff --git a/Editor/ModellingPanel.xml b/Assets/Editor/ModellingPanel.xml similarity index 100% rename from Editor/ModellingPanel.xml rename to Assets/Editor/ModellingPanel.xml diff --git a/Editor/NewEntityTemplate.ent_template b/Assets/Editor/NewEntityTemplate.ent_template similarity index 100% rename from Editor/NewEntityTemplate.ent_template rename to Assets/Editor/NewEntityTemplate.ent_template diff --git a/Editor/NewEntityTemplate.lua_template b/Assets/Editor/NewEntityTemplate.lua_template similarity index 100% rename from Editor/NewEntityTemplate.lua_template rename to Assets/Editor/NewEntityTemplate.lua_template diff --git a/Editor/ObjectIcons/AreaTrigger.bmp b/Assets/Editor/ObjectIcons/AreaTrigger.bmp similarity index 100% rename from Editor/ObjectIcons/AreaTrigger.bmp rename to Assets/Editor/ObjectIcons/AreaTrigger.bmp diff --git a/Editor/ObjectIcons/AudioAreaAmbience.bmp b/Assets/Editor/ObjectIcons/AudioAreaAmbience.bmp similarity index 100% rename from Editor/ObjectIcons/AudioAreaAmbience.bmp rename to Assets/Editor/ObjectIcons/AudioAreaAmbience.bmp diff --git a/Editor/ObjectIcons/AudioAreaEntity.bmp b/Assets/Editor/ObjectIcons/AudioAreaEntity.bmp similarity index 100% rename from Editor/ObjectIcons/AudioAreaEntity.bmp rename to Assets/Editor/ObjectIcons/AudioAreaEntity.bmp diff --git a/Editor/ObjectIcons/AudioAreaRandom.bmp b/Assets/Editor/ObjectIcons/AudioAreaRandom.bmp similarity index 100% rename from Editor/ObjectIcons/AudioAreaRandom.bmp rename to Assets/Editor/ObjectIcons/AudioAreaRandom.bmp diff --git a/Editor/ObjectIcons/Camera.bmp b/Assets/Editor/ObjectIcons/Camera.bmp similarity index 100% rename from Editor/ObjectIcons/Camera.bmp rename to Assets/Editor/ObjectIcons/Camera.bmp diff --git a/Editor/ObjectIcons/Checkpoint.bmp b/Assets/Editor/ObjectIcons/Checkpoint.bmp similarity index 100% rename from Editor/ObjectIcons/Checkpoint.bmp rename to Assets/Editor/ObjectIcons/Checkpoint.bmp diff --git a/Editor/ObjectIcons/ClipVolume.bmp b/Assets/Editor/ObjectIcons/ClipVolume.bmp similarity index 100% rename from Editor/ObjectIcons/ClipVolume.bmp rename to Assets/Editor/ObjectIcons/ClipVolume.bmp diff --git a/Editor/ObjectIcons/Clock.bmp b/Assets/Editor/ObjectIcons/Clock.bmp similarity index 100% rename from Editor/ObjectIcons/Clock.bmp rename to Assets/Editor/ObjectIcons/Clock.bmp diff --git a/Editor/ObjectIcons/Clouds.bmp b/Assets/Editor/ObjectIcons/Clouds.bmp similarity index 100% rename from Editor/ObjectIcons/Clouds.bmp rename to Assets/Editor/ObjectIcons/Clouds.bmp diff --git a/Editor/ObjectIcons/Comment.bmp b/Assets/Editor/ObjectIcons/Comment.bmp similarity index 100% rename from Editor/ObjectIcons/Comment.bmp rename to Assets/Editor/ObjectIcons/Comment.bmp diff --git a/Editor/ObjectIcons/DeadBody.bmp b/Assets/Editor/ObjectIcons/DeadBody.bmp similarity index 100% rename from Editor/ObjectIcons/DeadBody.bmp rename to Assets/Editor/ObjectIcons/DeadBody.bmp diff --git a/Editor/ObjectIcons/Decal.bmp b/Assets/Editor/ObjectIcons/Decal.bmp similarity index 100% rename from Editor/ObjectIcons/Decal.bmp rename to Assets/Editor/ObjectIcons/Decal.bmp diff --git a/Editor/ObjectIcons/Dialog.bmp b/Assets/Editor/ObjectIcons/Dialog.bmp similarity index 100% rename from Editor/ObjectIcons/Dialog.bmp rename to Assets/Editor/ObjectIcons/Dialog.bmp diff --git a/Editor/ObjectIcons/Flash.bmp b/Assets/Editor/ObjectIcons/Flash.bmp similarity index 100% rename from Editor/ObjectIcons/Flash.bmp rename to Assets/Editor/ObjectIcons/Flash.bmp diff --git a/Editor/ObjectIcons/Fog.bmp b/Assets/Editor/ObjectIcons/Fog.bmp similarity index 100% rename from Editor/ObjectIcons/Fog.bmp rename to Assets/Editor/ObjectIcons/Fog.bmp diff --git a/Editor/ObjectIcons/FogVolume.bmp b/Assets/Editor/ObjectIcons/FogVolume.bmp similarity index 100% rename from Editor/ObjectIcons/FogVolume.bmp rename to Assets/Editor/ObjectIcons/FogVolume.bmp diff --git a/Editor/ObjectIcons/GravitySphere.bmp b/Assets/Editor/ObjectIcons/GravitySphere.bmp similarity index 100% rename from Editor/ObjectIcons/GravitySphere.bmp rename to Assets/Editor/ObjectIcons/GravitySphere.bmp diff --git a/Editor/ObjectIcons/Item.bmp b/Assets/Editor/ObjectIcons/Item.bmp similarity index 100% rename from Editor/ObjectIcons/Item.bmp rename to Assets/Editor/ObjectIcons/Item.bmp diff --git a/Editor/ObjectIcons/Ladder.bmp b/Assets/Editor/ObjectIcons/Ladder.bmp similarity index 100% rename from Editor/ObjectIcons/Ladder.bmp rename to Assets/Editor/ObjectIcons/Ladder.bmp diff --git a/Editor/ObjectIcons/Light.bmp b/Assets/Editor/ObjectIcons/Light.bmp similarity index 100% rename from Editor/ObjectIcons/Light.bmp rename to Assets/Editor/ObjectIcons/Light.bmp diff --git a/Editor/ObjectIcons/LightPropagationVolume.bmp b/Assets/Editor/ObjectIcons/LightPropagationVolume.bmp similarity index 100% rename from Editor/ObjectIcons/LightPropagationVolume.bmp rename to Assets/Editor/ObjectIcons/LightPropagationVolume.bmp diff --git a/Editor/ObjectIcons/Lightning.bmp b/Assets/Editor/ObjectIcons/Lightning.bmp similarity index 100% rename from Editor/ObjectIcons/Lightning.bmp rename to Assets/Editor/ObjectIcons/Lightning.bmp diff --git a/Editor/ObjectIcons/Magnet.bmp b/Assets/Editor/ObjectIcons/Magnet.bmp similarity index 100% rename from Editor/ObjectIcons/Magnet.bmp rename to Assets/Editor/ObjectIcons/Magnet.bmp diff --git a/Editor/ObjectIcons/MultiTrigger.bmp b/Assets/Editor/ObjectIcons/MultiTrigger.bmp similarity index 100% rename from Editor/ObjectIcons/MultiTrigger.bmp rename to Assets/Editor/ObjectIcons/MultiTrigger.bmp diff --git a/Editor/ObjectIcons/ODD.bmp b/Assets/Editor/ObjectIcons/ODD.bmp similarity index 100% rename from Editor/ObjectIcons/ODD.bmp rename to Assets/Editor/ObjectIcons/ODD.bmp diff --git a/Editor/ObjectIcons/Particles.bmp b/Assets/Editor/ObjectIcons/Particles.bmp similarity index 100% rename from Editor/ObjectIcons/Particles.bmp rename to Assets/Editor/ObjectIcons/Particles.bmp diff --git a/Editor/ObjectIcons/PrecacheCamera.bmp b/Assets/Editor/ObjectIcons/PrecacheCamera.bmp similarity index 100% rename from Editor/ObjectIcons/PrecacheCamera.bmp rename to Assets/Editor/ObjectIcons/PrecacheCamera.bmp diff --git a/Editor/ObjectIcons/Prefab.bmp b/Assets/Editor/ObjectIcons/Prefab.bmp similarity index 100% rename from Editor/ObjectIcons/Prefab.bmp rename to Assets/Editor/ObjectIcons/Prefab.bmp diff --git a/Editor/ObjectIcons/Prompt.bmp b/Assets/Editor/ObjectIcons/Prompt.bmp similarity index 100% rename from Editor/ObjectIcons/Prompt.bmp rename to Assets/Editor/ObjectIcons/Prompt.bmp diff --git a/Editor/ObjectIcons/SavePoint.bmp b/Assets/Editor/ObjectIcons/SavePoint.bmp similarity index 100% rename from Editor/ObjectIcons/SavePoint.bmp rename to Assets/Editor/ObjectIcons/SavePoint.bmp diff --git a/Editor/ObjectIcons/Seed.bmp b/Assets/Editor/ObjectIcons/Seed.bmp similarity index 100% rename from Editor/ObjectIcons/Seed.bmp rename to Assets/Editor/ObjectIcons/Seed.bmp diff --git a/Editor/ObjectIcons/Sound.bmp b/Assets/Editor/ObjectIcons/Sound.bmp similarity index 100% rename from Editor/ObjectIcons/Sound.bmp rename to Assets/Editor/ObjectIcons/Sound.bmp diff --git a/Editor/ObjectIcons/SpawnPoint.bmp b/Assets/Editor/ObjectIcons/SpawnPoint.bmp similarity index 100% rename from Editor/ObjectIcons/SpawnPoint.bmp rename to Assets/Editor/ObjectIcons/SpawnPoint.bmp diff --git a/Editor/ObjectIcons/T.bmp b/Assets/Editor/ObjectIcons/T.bmp similarity index 100% rename from Editor/ObjectIcons/T.bmp rename to Assets/Editor/ObjectIcons/T.bmp diff --git a/Editor/ObjectIcons/TagPoint.bmp b/Assets/Editor/ObjectIcons/TagPoint.bmp similarity index 100% rename from Editor/ObjectIcons/TagPoint.bmp rename to Assets/Editor/ObjectIcons/TagPoint.bmp diff --git a/Editor/ObjectIcons/Trigger.bmp b/Assets/Editor/ObjectIcons/Trigger.bmp similarity index 100% rename from Editor/ObjectIcons/Trigger.bmp rename to Assets/Editor/ObjectIcons/Trigger.bmp diff --git a/Editor/ObjectIcons/UiCanvasRefEntity.bmp b/Assets/Editor/ObjectIcons/UiCanvasRefEntity.bmp similarity index 100% rename from Editor/ObjectIcons/UiCanvasRefEntity.bmp rename to Assets/Editor/ObjectIcons/UiCanvasRefEntity.bmp diff --git a/Editor/ObjectIcons/User.bmp b/Assets/Editor/ObjectIcons/User.bmp similarity index 100% rename from Editor/ObjectIcons/User.bmp rename to Assets/Editor/ObjectIcons/User.bmp diff --git a/Editor/ObjectIcons/VVVArea.bmp b/Assets/Editor/ObjectIcons/VVVArea.bmp similarity index 100% rename from Editor/ObjectIcons/VVVArea.bmp rename to Assets/Editor/ObjectIcons/VVVArea.bmp diff --git a/Editor/ObjectIcons/W.bmp b/Assets/Editor/ObjectIcons/W.bmp similarity index 100% rename from Editor/ObjectIcons/W.bmp rename to Assets/Editor/ObjectIcons/W.bmp diff --git a/Editor/ObjectIcons/Water.bmp b/Assets/Editor/ObjectIcons/Water.bmp similarity index 100% rename from Editor/ObjectIcons/Water.bmp rename to Assets/Editor/ObjectIcons/Water.bmp diff --git a/Editor/ObjectIcons/animobject.bmp b/Assets/Editor/ObjectIcons/animobject.bmp similarity index 100% rename from Editor/ObjectIcons/animobject.bmp rename to Assets/Editor/ObjectIcons/animobject.bmp diff --git a/Editor/ObjectIcons/bird.bmp b/Assets/Editor/ObjectIcons/bird.bmp similarity index 100% rename from Editor/ObjectIcons/bird.bmp rename to Assets/Editor/ObjectIcons/bird.bmp diff --git a/Editor/ObjectIcons/bug.bmp b/Assets/Editor/ObjectIcons/bug.bmp similarity index 100% rename from Editor/ObjectIcons/bug.bmp rename to Assets/Editor/ObjectIcons/bug.bmp diff --git a/Editor/ObjectIcons/character.bmp b/Assets/Editor/ObjectIcons/character.bmp similarity index 100% rename from Editor/ObjectIcons/character.bmp rename to Assets/Editor/ObjectIcons/character.bmp diff --git a/Editor/ObjectIcons/death.bmp b/Assets/Editor/ObjectIcons/death.bmp similarity index 100% rename from Editor/ObjectIcons/death.bmp rename to Assets/Editor/ObjectIcons/death.bmp diff --git a/Editor/ObjectIcons/door.bmp b/Assets/Editor/ObjectIcons/door.bmp similarity index 100% rename from Editor/ObjectIcons/door.bmp rename to Assets/Editor/ObjectIcons/door.bmp diff --git a/Editor/ObjectIcons/elevator.bmp b/Assets/Editor/ObjectIcons/elevator.bmp similarity index 100% rename from Editor/ObjectIcons/elevator.bmp rename to Assets/Editor/ObjectIcons/elevator.bmp diff --git a/Editor/ObjectIcons/environmentProbe.bmp b/Assets/Editor/ObjectIcons/environmentProbe.bmp similarity index 100% rename from Editor/ObjectIcons/environmentProbe.bmp rename to Assets/Editor/ObjectIcons/environmentProbe.bmp diff --git a/Editor/ObjectIcons/explosion.bmp b/Assets/Editor/ObjectIcons/explosion.bmp similarity index 100% rename from Editor/ObjectIcons/explosion.bmp rename to Assets/Editor/ObjectIcons/explosion.bmp diff --git a/Editor/ObjectIcons/fish.bmp b/Assets/Editor/ObjectIcons/fish.bmp similarity index 100% rename from Editor/ObjectIcons/fish.bmp rename to Assets/Editor/ObjectIcons/fish.bmp diff --git a/Editor/ObjectIcons/forbiddenarea.bmp b/Assets/Editor/ObjectIcons/forbiddenarea.bmp similarity index 100% rename from Editor/ObjectIcons/forbiddenarea.bmp rename to Assets/Editor/ObjectIcons/forbiddenarea.bmp diff --git a/Editor/ObjectIcons/hazard.bmp b/Assets/Editor/ObjectIcons/hazard.bmp similarity index 100% rename from Editor/ObjectIcons/hazard.bmp rename to Assets/Editor/ObjectIcons/hazard.bmp diff --git a/Editor/ObjectIcons/health.bmp b/Assets/Editor/ObjectIcons/health.bmp similarity index 100% rename from Editor/ObjectIcons/health.bmp rename to Assets/Editor/ObjectIcons/health.bmp diff --git a/Editor/ObjectIcons/ledge.bmp b/Assets/Editor/ObjectIcons/ledge.bmp similarity index 100% rename from Editor/ObjectIcons/ledge.bmp rename to Assets/Editor/ObjectIcons/ledge.bmp diff --git a/Editor/ObjectIcons/mine.bmp b/Assets/Editor/ObjectIcons/mine.bmp similarity index 100% rename from Editor/ObjectIcons/mine.bmp rename to Assets/Editor/ObjectIcons/mine.bmp diff --git a/Editor/ObjectIcons/physicsobject.bmp b/Assets/Editor/ObjectIcons/physicsobject.bmp similarity index 100% rename from Editor/ObjectIcons/physicsobject.bmp rename to Assets/Editor/ObjectIcons/physicsobject.bmp diff --git a/Editor/ObjectIcons/prefabbuilding.bmp b/Assets/Editor/ObjectIcons/prefabbuilding.bmp similarity index 100% rename from Editor/ObjectIcons/prefabbuilding.bmp rename to Assets/Editor/ObjectIcons/prefabbuilding.bmp diff --git a/Editor/ObjectIcons/proceduralbuilding.bmp b/Assets/Editor/ObjectIcons/proceduralbuilding.bmp similarity index 100% rename from Editor/ObjectIcons/proceduralbuilding.bmp rename to Assets/Editor/ObjectIcons/proceduralbuilding.bmp diff --git a/Editor/ObjectIcons/proceduralobject.bmp b/Assets/Editor/ObjectIcons/proceduralobject.bmp similarity index 100% rename from Editor/ObjectIcons/proceduralobject.bmp rename to Assets/Editor/ObjectIcons/proceduralobject.bmp diff --git a/Editor/ObjectIcons/proximitytrigger.bmp b/Assets/Editor/ObjectIcons/proximitytrigger.bmp similarity index 100% rename from Editor/ObjectIcons/proximitytrigger.bmp rename to Assets/Editor/ObjectIcons/proximitytrigger.bmp diff --git a/Editor/ObjectIcons/river.bmp b/Assets/Editor/ObjectIcons/river.bmp similarity index 100% rename from Editor/ObjectIcons/river.bmp rename to Assets/Editor/ObjectIcons/river.bmp diff --git a/Editor/ObjectIcons/road.bmp b/Assets/Editor/ObjectIcons/road.bmp similarity index 100% rename from Editor/ObjectIcons/road.bmp rename to Assets/Editor/ObjectIcons/road.bmp diff --git a/Editor/ObjectIcons/rope.bmp b/Assets/Editor/ObjectIcons/rope.bmp similarity index 100% rename from Editor/ObjectIcons/rope.bmp rename to Assets/Editor/ObjectIcons/rope.bmp diff --git a/Editor/ObjectIcons/sequence.bmp b/Assets/Editor/ObjectIcons/sequence.bmp similarity index 100% rename from Editor/ObjectIcons/sequence.bmp rename to Assets/Editor/ObjectIcons/sequence.bmp diff --git a/Editor/ObjectIcons/shake.bmp b/Assets/Editor/ObjectIcons/shake.bmp similarity index 100% rename from Editor/ObjectIcons/shake.bmp rename to Assets/Editor/ObjectIcons/shake.bmp diff --git a/Editor/ObjectIcons/smartobject.bmp b/Assets/Editor/ObjectIcons/smartobject.bmp similarity index 100% rename from Editor/ObjectIcons/smartobject.bmp rename to Assets/Editor/ObjectIcons/smartobject.bmp diff --git a/Editor/ObjectIcons/spawngroup.bmp b/Assets/Editor/ObjectIcons/spawngroup.bmp similarity index 100% rename from Editor/ObjectIcons/spawngroup.bmp rename to Assets/Editor/ObjectIcons/spawngroup.bmp diff --git a/Editor/ObjectIcons/spectator.bmp b/Assets/Editor/ObjectIcons/spectator.bmp similarity index 100% rename from Editor/ObjectIcons/spectator.bmp rename to Assets/Editor/ObjectIcons/spectator.bmp diff --git a/Editor/ObjectIcons/switch.bmp b/Assets/Editor/ObjectIcons/switch.bmp similarity index 100% rename from Editor/ObjectIcons/switch.bmp rename to Assets/Editor/ObjectIcons/switch.bmp diff --git a/Editor/ObjectIcons/territory.bmp b/Assets/Editor/ObjectIcons/territory.bmp similarity index 100% rename from Editor/ObjectIcons/territory.bmp rename to Assets/Editor/ObjectIcons/territory.bmp diff --git a/Editor/ObjectIcons/tornado.bmp b/Assets/Editor/ObjectIcons/tornado.bmp similarity index 100% rename from Editor/ObjectIcons/tornado.bmp rename to Assets/Editor/ObjectIcons/tornado.bmp diff --git a/Editor/ObjectIcons/vehicle.bmp b/Assets/Editor/ObjectIcons/vehicle.bmp similarity index 100% rename from Editor/ObjectIcons/vehicle.bmp rename to Assets/Editor/ObjectIcons/vehicle.bmp diff --git a/Editor/ObjectIcons/voxel.bmp b/Assets/Editor/ObjectIcons/voxel.bmp similarity index 100% rename from Editor/ObjectIcons/voxel.bmp rename to Assets/Editor/ObjectIcons/voxel.bmp diff --git a/Editor/ObjectIcons/wave.bmp b/Assets/Editor/ObjectIcons/wave.bmp similarity index 100% rename from Editor/ObjectIcons/wave.bmp rename to Assets/Editor/ObjectIcons/wave.bmp diff --git a/Editor/ObjectTemplates.xml b/Assets/Editor/ObjectTemplates.xml similarity index 100% rename from Editor/ObjectTemplates.xml rename to Assets/Editor/ObjectTemplates.xml diff --git a/Editor/Objects/Arrow.cgf b/Assets/Editor/Objects/Arrow.cgf similarity index 100% rename from Editor/Objects/Arrow.cgf rename to Assets/Editor/Objects/Arrow.cgf diff --git a/Editor/Objects/Axis.cgf b/Assets/Editor/Objects/Axis.cgf similarity index 100% rename from Editor/Objects/Axis.cgf rename to Assets/Editor/Objects/Axis.cgf diff --git a/Editor/Objects/Clock.cgf b/Assets/Editor/Objects/Clock.cgf similarity index 100% rename from Editor/Objects/Clock.cgf rename to Assets/Editor/Objects/Clock.cgf diff --git a/Editor/Objects/Comment.cgf b/Assets/Editor/Objects/Comment.cgf similarity index 100% rename from Editor/Objects/Comment.cgf rename to Assets/Editor/Objects/Comment.cgf diff --git a/Editor/Objects/CryDesigner_camera.grp b/Assets/Editor/Objects/CryDesigner_camera.grp similarity index 100% rename from Editor/Objects/CryDesigner_camera.grp rename to Assets/Editor/Objects/CryDesigner_camera.grp diff --git a/Editor/Objects/M.cgf b/Assets/Editor/Objects/M.cgf similarity index 100% rename from Editor/Objects/M.cgf rename to Assets/Editor/Objects/M.cgf diff --git a/Editor/Objects/MtlBox.cgf b/Assets/Editor/Objects/MtlBox.cgf similarity index 100% rename from Editor/Objects/MtlBox.cgf rename to Assets/Editor/Objects/MtlBox.cgf diff --git a/Editor/Objects/MtlObjects.max b/Assets/Editor/Objects/MtlObjects.max similarity index 100% rename from Editor/Objects/MtlObjects.max rename to Assets/Editor/Objects/MtlObjects.max diff --git a/Editor/Objects/MtlPlane.cgf b/Assets/Editor/Objects/MtlPlane.cgf similarity index 100% rename from Editor/Objects/MtlPlane.cgf rename to Assets/Editor/Objects/MtlPlane.cgf diff --git a/Editor/Objects/MtlSphere.cgf b/Assets/Editor/Objects/MtlSphere.cgf similarity index 100% rename from Editor/Objects/MtlSphere.cgf rename to Assets/Editor/Objects/MtlSphere.cgf diff --git a/Editor/Objects/MtlSwatch.cgf b/Assets/Editor/Objects/MtlSwatch.cgf similarity index 100% rename from Editor/Objects/MtlSwatch.cgf rename to Assets/Editor/Objects/MtlSwatch.cgf diff --git a/Editor/Objects/MtlTeapot.cgf b/Assets/Editor/Objects/MtlTeapot.cgf similarity index 100% rename from Editor/Objects/MtlTeapot.cgf rename to Assets/Editor/Objects/MtlTeapot.cgf diff --git a/Editor/Objects/MusicTheme.cgf b/Assets/Editor/Objects/MusicTheme.cgf similarity index 100% rename from Editor/Objects/MusicTheme.cgf rename to Assets/Editor/Objects/MusicTheme.cgf diff --git a/Editor/Objects/Particles.cgf b/Assets/Editor/Objects/Particles.cgf similarity index 100% rename from Editor/Objects/Particles.cgf rename to Assets/Editor/Objects/Particles.cgf diff --git a/Editor/Objects/Pyramid.cgf b/Assets/Editor/Objects/Pyramid.cgf similarity index 100% rename from Editor/Objects/Pyramid.cgf rename to Assets/Editor/Objects/Pyramid.cgf diff --git a/Editor/Objects/S.cgf b/Assets/Editor/Objects/S.cgf similarity index 100% rename from Editor/Objects/S.cgf rename to Assets/Editor/Objects/S.cgf diff --git a/Editor/Objects/Sound.cgf b/Assets/Editor/Objects/Sound.cgf similarity index 100% rename from Editor/Objects/Sound.cgf rename to Assets/Editor/Objects/Sound.cgf diff --git a/Editor/Objects/Sphere.cgf b/Assets/Editor/Objects/Sphere.cgf similarity index 100% rename from Editor/Objects/Sphere.cgf rename to Assets/Editor/Objects/Sphere.cgf diff --git a/Editor/Objects/T.cgf b/Assets/Editor/Objects/T.cgf similarity index 100% rename from Editor/Objects/T.cgf rename to Assets/Editor/Objects/T.cgf diff --git a/Editor/Objects/Vis.cgf b/Assets/Editor/Objects/Vis.cgf similarity index 100% rename from Editor/Objects/Vis.cgf rename to Assets/Editor/Objects/Vis.cgf diff --git a/Editor/Objects/W.cgf b/Assets/Editor/Objects/W.cgf similarity index 100% rename from Editor/Objects/W.cgf rename to Assets/Editor/Objects/W.cgf diff --git a/Editor/Objects/ai_hide_point.cgf b/Assets/Editor/Objects/ai_hide_point.cgf similarity index 100% rename from Editor/Objects/ai_hide_point.cgf rename to Assets/Editor/Objects/ai_hide_point.cgf diff --git a/Editor/Objects/anchor.cgf b/Assets/Editor/Objects/anchor.cgf similarity index 100% rename from Editor/Objects/anchor.cgf rename to Assets/Editor/Objects/anchor.cgf diff --git a/Editor/Objects/assaultspawn.cgf b/Assets/Editor/Objects/assaultspawn.cgf similarity index 100% rename from Editor/Objects/assaultspawn.cgf rename to Assets/Editor/Objects/assaultspawn.cgf diff --git a/Editor/Objects/border.cgf b/Assets/Editor/Objects/border.cgf similarity index 100% rename from Editor/Objects/border.cgf rename to Assets/Editor/Objects/border.cgf diff --git a/Editor/Objects/box.cgf b/Assets/Editor/Objects/box.cgf similarity index 100% rename from Editor/Objects/box.cgf rename to Assets/Editor/Objects/box.cgf diff --git a/Editor/Objects/box_nodraw.cgf b/Assets/Editor/Objects/box_nodraw.cgf similarity index 100% rename from Editor/Objects/box_nodraw.cgf rename to Assets/Editor/Objects/box_nodraw.cgf diff --git a/Editor/Objects/buyzone.cgf b/Assets/Editor/Objects/buyzone.cgf similarity index 100% rename from Editor/Objects/buyzone.cgf rename to Assets/Editor/Objects/buyzone.cgf diff --git a/Editor/Objects/c2_car_jump_cross.cgf b/Assets/Editor/Objects/c2_car_jump_cross.cgf similarity index 100% rename from Editor/Objects/c2_car_jump_cross.cgf rename to Assets/Editor/Objects/c2_car_jump_cross.cgf diff --git a/Editor/Objects/c2_crawl_h150.cgf b/Assets/Editor/Objects/c2_crawl_h150.cgf similarity index 100% rename from Editor/Objects/c2_crawl_h150.cgf rename to Assets/Editor/Objects/c2_crawl_h150.cgf diff --git a/Editor/Objects/c2_duck_v125.cgf b/Assets/Editor/Objects/c2_duck_v125.cgf similarity index 100% rename from Editor/Objects/c2_duck_v125.cgf rename to Assets/Editor/Objects/c2_duck_v125.cgf diff --git a/Editor/Objects/c2_jump_h1200.cgf b/Assets/Editor/Objects/c2_jump_h1200.cgf similarity index 100% rename from Editor/Objects/c2_jump_h1200.cgf rename to Assets/Editor/Objects/c2_jump_h1200.cgf diff --git a/Editor/Objects/c2_jump_h500.cgf b/Assets/Editor/Objects/c2_jump_h500.cgf similarity index 100% rename from Editor/Objects/c2_jump_h500.cgf rename to Assets/Editor/Objects/c2_jump_h500.cgf diff --git a/Editor/Objects/c2_jump_h900.cgf b/Assets/Editor/Objects/c2_jump_h900.cgf similarity index 100% rename from Editor/Objects/c2_jump_h900.cgf rename to Assets/Editor/Objects/c2_jump_h900.cgf diff --git a/Editor/Objects/c2_jump_h900_v150.cgf b/Assets/Editor/Objects/c2_jump_h900_v150.cgf similarity index 100% rename from Editor/Objects/c2_jump_h900_v150.cgf rename to Assets/Editor/Objects/c2_jump_h900_v150.cgf diff --git a/Editor/Objects/c2_jump_v150.cgf b/Assets/Editor/Objects/c2_jump_v150.cgf similarity index 100% rename from Editor/Objects/c2_jump_v150.cgf rename to Assets/Editor/Objects/c2_jump_v150.cgf diff --git a/Editor/Objects/c2_jump_v300.cgf b/Assets/Editor/Objects/c2_jump_v300.cgf similarity index 100% rename from Editor/Objects/c2_jump_v300.cgf rename to Assets/Editor/Objects/c2_jump_v300.cgf diff --git a/Editor/Objects/c2_jump_v450.cgf b/Assets/Editor/Objects/c2_jump_v450.cgf similarity index 100% rename from Editor/Objects/c2_jump_v450.cgf rename to Assets/Editor/Objects/c2_jump_v450.cgf diff --git a/Editor/Objects/c2_jumpdown_v900.cgf b/Assets/Editor/Objects/c2_jumpdown_v900.cgf similarity index 100% rename from Editor/Objects/c2_jumpdown_v900.cgf rename to Assets/Editor/Objects/c2_jumpdown_v900.cgf diff --git a/Editor/Objects/c2_jumpwindow_combo_v550.cgf b/Assets/Editor/Objects/c2_jumpwindow_combo_v550.cgf similarity index 100% rename from Editor/Objects/c2_jumpwindow_combo_v550.cgf rename to Assets/Editor/Objects/c2_jumpwindow_combo_v550.cgf diff --git a/Editor/Objects/c2_jumpwindow_v550.cgf b/Assets/Editor/Objects/c2_jumpwindow_v550.cgf similarity index 100% rename from Editor/Objects/c2_jumpwindow_v550.cgf rename to Assets/Editor/Objects/c2_jumpwindow_v550.cgf diff --git a/Editor/Objects/c2_jumpzigzag_v300_v750_lft.cgf b/Assets/Editor/Objects/c2_jumpzigzag_v300_v750_lft.cgf similarity index 100% rename from Editor/Objects/c2_jumpzigzag_v300_v750_lft.cgf rename to Assets/Editor/Objects/c2_jumpzigzag_v300_v750_lft.cgf diff --git a/Editor/Objects/c2_jumpzigzag_v300_v750_rgt.cgf b/Assets/Editor/Objects/c2_jumpzigzag_v300_v750_rgt.cgf similarity index 100% rename from Editor/Objects/c2_jumpzigzag_v300_v750_rgt.cgf rename to Assets/Editor/Objects/c2_jumpzigzag_v300_v750_rgt.cgf diff --git a/Editor/Objects/c2_slide_h400.cgf b/Assets/Editor/Objects/c2_slide_h400.cgf similarity index 100% rename from Editor/Objects/c2_slide_h400.cgf rename to Assets/Editor/Objects/c2_slide_h400.cgf diff --git a/Editor/Objects/c2_slidedown_v1800.cgf b/Assets/Editor/Objects/c2_slidedown_v1800.cgf similarity index 100% rename from Editor/Objects/c2_slidedown_v1800.cgf rename to Assets/Editor/Objects/c2_slidedown_v1800.cgf diff --git a/Editor/Objects/c2_vault_v125.cgf b/Assets/Editor/Objects/c2_vault_v125.cgf similarity index 100% rename from Editor/Objects/c2_vault_v125.cgf rename to Assets/Editor/Objects/c2_vault_v125.cgf diff --git a/Editor/Objects/c2_vault_v800.cgf b/Assets/Editor/Objects/c2_vault_v800.cgf similarity index 100% rename from Editor/Objects/c2_vault_v800.cgf rename to Assets/Editor/Objects/c2_vault_v800.cgf diff --git a/Editor/Objects/c2_wall_jump_h900_v450.cgf b/Assets/Editor/Objects/c2_wall_jump_h900_v450.cgf similarity index 100% rename from Editor/Objects/c2_wall_jump_h900_v450.cgf rename to Assets/Editor/Objects/c2_wall_jump_h900_v450.cgf diff --git a/Editor/Objects/c2_wall_run_h900_v300.cgf b/Assets/Editor/Objects/c2_wall_run_h900_v300.cgf similarity index 100% rename from Editor/Objects/c2_wall_run_h900_v300.cgf rename to Assets/Editor/Objects/c2_wall_run_h900_v300.cgf diff --git a/Editor/Objects/c3_dive_h900.cgf b/Assets/Editor/Objects/c3_dive_h900.cgf similarity index 100% rename from Editor/Objects/c3_dive_h900.cgf rename to Assets/Editor/Objects/c3_dive_h900.cgf diff --git a/Editor/Objects/c3_doorbreak_human.cgf b/Assets/Editor/Objects/c3_doorbreak_human.cgf similarity index 100% rename from Editor/Objects/c3_doorbreak_human.cgf rename to Assets/Editor/Objects/c3_doorbreak_human.cgf diff --git a/Editor/Objects/c3_doorframe.cgf b/Assets/Editor/Objects/c3_doorframe.cgf similarity index 100% rename from Editor/Objects/c3_doorframe.cgf rename to Assets/Editor/Objects/c3_doorframe.cgf diff --git a/Editor/Objects/c3_jump_v150_large.cgf b/Assets/Editor/Objects/c3_jump_v150_large.cgf similarity index 100% rename from Editor/Objects/c3_jump_v150_large.cgf rename to Assets/Editor/Objects/c3_jump_v150_large.cgf diff --git a/Editor/Objects/c3_jump_v300_large.cgf b/Assets/Editor/Objects/c3_jump_v300_large.cgf similarity index 100% rename from Editor/Objects/c3_jump_v300_large.cgf rename to Assets/Editor/Objects/c3_jump_v300_large.cgf diff --git a/Editor/Objects/c3_jump_v450_large.cgf b/Assets/Editor/Objects/c3_jump_v450_large.cgf similarity index 100% rename from Editor/Objects/c3_jump_v450_large.cgf rename to Assets/Editor/Objects/c3_jump_v450_large.cgf diff --git a/Editor/Objects/c3_repeldown_v2600.cgf b/Assets/Editor/Objects/c3_repeldown_v2600.cgf similarity index 100% rename from Editor/Objects/c3_repeldown_v2600.cgf rename to Assets/Editor/Objects/c3_repeldown_v2600.cgf diff --git a/Editor/Objects/c3_repeldown_v900.cgf b/Assets/Editor/Objects/c3_repeldown_v900.cgf similarity index 100% rename from Editor/Objects/c3_repeldown_v900.cgf rename to Assets/Editor/Objects/c3_repeldown_v900.cgf diff --git a/Editor/Objects/c3_so_cornerPopOutSearchLeft.cgf b/Assets/Editor/Objects/c3_so_cornerPopOutSearchLeft.cgf similarity index 100% rename from Editor/Objects/c3_so_cornerPopOutSearchLeft.cgf rename to Assets/Editor/Objects/c3_so_cornerPopOutSearchLeft.cgf diff --git a/Editor/Objects/c3_so_cornerPopOutSearchRight.cgf b/Assets/Editor/Objects/c3_so_cornerPopOutSearchRight.cgf similarity index 100% rename from Editor/Objects/c3_so_cornerPopOutSearchRight.cgf rename to Assets/Editor/Objects/c3_so_cornerPopOutSearchRight.cgf diff --git a/Editor/Objects/c3_vault_v125_large.cgf b/Assets/Editor/Objects/c3_vault_v125_large.cgf similarity index 100% rename from Editor/Objects/c3_vault_v125_large.cgf rename to Assets/Editor/Objects/c3_vault_v125_large.cgf diff --git a/Editor/Objects/c3_zipline_7500_15.cgf b/Assets/Editor/Objects/c3_zipline_7500_15.cgf similarity index 100% rename from Editor/Objects/c3_zipline_7500_15.cgf rename to Assets/Editor/Objects/c3_zipline_7500_15.cgf diff --git a/Editor/Objects/collision_dummy_100x50.cgf b/Assets/Editor/Objects/collision_dummy_100x50.cgf similarity index 100% rename from Editor/Objects/collision_dummy_100x50.cgf rename to Assets/Editor/Objects/collision_dummy_100x50.cgf diff --git a/Editor/Objects/collision_dummy_25x50.cgf b/Assets/Editor/Objects/collision_dummy_25x50.cgf similarity index 100% rename from Editor/Objects/collision_dummy_25x50.cgf rename to Assets/Editor/Objects/collision_dummy_25x50.cgf diff --git a/Editor/Objects/collision_dummy_50x50.cgf b/Assets/Editor/Objects/collision_dummy_50x50.cgf similarity index 100% rename from Editor/Objects/collision_dummy_50x50.cgf rename to Assets/Editor/Objects/collision_dummy_50x50.cgf diff --git a/Editor/Objects/corner270.cgf b/Assets/Editor/Objects/corner270.cgf similarity index 100% rename from Editor/Objects/corner270.cgf rename to Assets/Editor/Objects/corner270.cgf diff --git a/Editor/Objects/editor_helpers.max b/Assets/Editor/Objects/editor_helpers.max similarity index 100% rename from Editor/Objects/editor_helpers.max rename to Assets/Editor/Objects/editor_helpers.max diff --git a/Editor/Objects/energypoint.cgf b/Assets/Editor/Objects/energypoint.cgf similarity index 100% rename from Editor/Objects/energypoint.cgf rename to Assets/Editor/Objects/energypoint.cgf diff --git a/Editor/Objects/entrypoint.cgf b/Assets/Editor/Objects/entrypoint.cgf similarity index 100% rename from Editor/Objects/entrypoint.cgf rename to Assets/Editor/Objects/entrypoint.cgf diff --git a/Editor/Objects/envcube.cgf b/Assets/Editor/Objects/envcube.cgf similarity index 100% rename from Editor/Objects/envcube.cgf rename to Assets/Editor/Objects/envcube.cgf diff --git a/Editor/Objects/envcube.max b/Assets/Editor/Objects/envcube.max similarity index 100% rename from Editor/Objects/envcube.max rename to Assets/Editor/Objects/envcube.max diff --git a/Editor/Objects/envcube.mtl b/Assets/Editor/Objects/envcube.mtl similarity index 100% rename from Editor/Objects/envcube.mtl rename to Assets/Editor/Objects/envcube.mtl diff --git a/Editor/Objects/factory.cgf b/Assets/Editor/Objects/factory.cgf similarity index 100% rename from Editor/Objects/factory.cgf rename to Assets/Editor/Objects/factory.cgf diff --git a/Editor/Objects/flock.cgf b/Assets/Editor/Objects/flock.cgf similarity index 100% rename from Editor/Objects/flock.cgf rename to Assets/Editor/Objects/flock.cgf diff --git a/Editor/Objects/forbiddenarea.cgf b/Assets/Editor/Objects/forbiddenarea.cgf similarity index 100% rename from Editor/Objects/forbiddenarea.cgf rename to Assets/Editor/Objects/forbiddenarea.cgf diff --git a/Editor/Objects/gradb.dds b/Assets/Editor/Objects/gradb.dds similarity index 100% rename from Editor/Objects/gradb.dds rename to Assets/Editor/Objects/gradb.dds diff --git a/Editor/Objects/gradf.dds b/Assets/Editor/Objects/gradf.dds similarity index 100% rename from Editor/Objects/gradf.dds rename to Assets/Editor/Objects/gradf.dds diff --git a/Editor/Objects/helper.mtl b/Assets/Editor/Objects/helper.mtl similarity index 100% rename from Editor/Objects/helper.mtl rename to Assets/Editor/Objects/helper.mtl diff --git a/Editor/Objects/helper_illum.mtl b/Assets/Editor/Objects/helper_illum.mtl similarity index 100% rename from Editor/Objects/helper_illum.mtl rename to Assets/Editor/Objects/helper_illum.mtl diff --git a/Editor/Objects/hidepoint.cgf b/Assets/Editor/Objects/hidepoint.cgf similarity index 100% rename from Editor/Objects/hidepoint.cgf rename to Assets/Editor/Objects/hidepoint.cgf diff --git a/Editor/Objects/hidepoint_sec.cgf b/Assets/Editor/Objects/hidepoint_sec.cgf similarity index 100% rename from Editor/Objects/hidepoint_sec.cgf rename to Assets/Editor/Objects/hidepoint_sec.cgf diff --git a/Editor/Objects/highvault.cgf b/Assets/Editor/Objects/highvault.cgf similarity index 100% rename from Editor/Objects/highvault.cgf rename to Assets/Editor/Objects/highvault.cgf diff --git a/Editor/Objects/hq.cgf b/Assets/Editor/Objects/hq.cgf similarity index 100% rename from Editor/Objects/hq.cgf rename to Assets/Editor/Objects/hq.cgf diff --git a/Editor/Objects/invisiblebox.cgf b/Assets/Editor/Objects/invisiblebox.cgf similarity index 100% rename from Editor/Objects/invisiblebox.cgf rename to Assets/Editor/Objects/invisiblebox.cgf diff --git a/Editor/Objects/invisibleobstruct.cgf b/Assets/Editor/Objects/invisibleobstruct.cgf similarity index 100% rename from Editor/Objects/invisibleobstruct.cgf rename to Assets/Editor/Objects/invisibleobstruct.cgf diff --git a/Editor/Objects/invisibleocclude.cgf b/Assets/Editor/Objects/invisibleocclude.cgf similarity index 100% rename from Editor/Objects/invisibleocclude.cgf rename to Assets/Editor/Objects/invisibleocclude.cgf diff --git a/Editor/Objects/invisiblewall.cgf b/Assets/Editor/Objects/invisiblewall.cgf similarity index 100% rename from Editor/Objects/invisiblewall.cgf rename to Assets/Editor/Objects/invisiblewall.cgf diff --git a/Editor/Objects/jump_150.cgf b/Assets/Editor/Objects/jump_150.cgf similarity index 100% rename from Editor/Objects/jump_150.cgf rename to Assets/Editor/Objects/jump_150.cgf diff --git a/Editor/Objects/jump_300.cgf b/Assets/Editor/Objects/jump_300.cgf similarity index 100% rename from Editor/Objects/jump_300.cgf rename to Assets/Editor/Objects/jump_300.cgf diff --git a/Editor/Objects/jump_450.cgf b/Assets/Editor/Objects/jump_450.cgf similarity index 100% rename from Editor/Objects/jump_450.cgf rename to Assets/Editor/Objects/jump_450.cgf diff --git a/Editor/Objects/leap_1000.cgf b/Assets/Editor/Objects/leap_1000.cgf similarity index 100% rename from Editor/Objects/leap_1000.cgf rename to Assets/Editor/Objects/leap_1000.cgf diff --git a/Editor/Objects/leap_500.cgf b/Assets/Editor/Objects/leap_500.cgf similarity index 100% rename from Editor/Objects/leap_500.cgf rename to Assets/Editor/Objects/leap_500.cgf diff --git a/Editor/Objects/light_omni.cgf b/Assets/Editor/Objects/light_omni.cgf similarity index 100% rename from Editor/Objects/light_omni.cgf rename to Assets/Editor/Objects/light_omni.cgf diff --git a/Editor/Objects/light_spot.cgf b/Assets/Editor/Objects/light_spot.cgf similarity index 100% rename from Editor/Objects/light_spot.cgf rename to Assets/Editor/Objects/light_spot.cgf diff --git a/Editor/Objects/lightsphere.cgf b/Assets/Editor/Objects/lightsphere.cgf similarity index 100% rename from Editor/Objects/lightsphere.cgf rename to Assets/Editor/Objects/lightsphere.cgf diff --git a/Editor/Objects/measurehelper_A.cgf b/Assets/Editor/Objects/measurehelper_A.cgf similarity index 100% rename from Editor/Objects/measurehelper_A.cgf rename to Assets/Editor/Objects/measurehelper_A.cgf diff --git a/Editor/Objects/measurehelper_B.cgf b/Assets/Editor/Objects/measurehelper_B.cgf similarity index 100% rename from Editor/Objects/measurehelper_B.cgf rename to Assets/Editor/Objects/measurehelper_B.cgf diff --git a/Editor/Objects/mtlbox.mtl b/Assets/Editor/Objects/mtlbox.mtl similarity index 100% rename from Editor/Objects/mtlbox.mtl rename to Assets/Editor/Objects/mtlbox.mtl diff --git a/Editor/Objects/mtlobjects.mtl b/Assets/Editor/Objects/mtlobjects.mtl similarity index 100% rename from Editor/Objects/mtlobjects.mtl rename to Assets/Editor/Objects/mtlobjects.mtl diff --git a/Editor/Objects/objective.cgf b/Assets/Editor/Objects/objective.cgf similarity index 100% rename from Editor/Objects/objective.cgf rename to Assets/Editor/Objects/objective.cgf diff --git a/Editor/Objects/phoenix.cgf b/Assets/Editor/Objects/phoenix.cgf similarity index 100% rename from Editor/Objects/phoenix.cgf rename to Assets/Editor/Objects/phoenix.cgf diff --git a/Editor/Objects/refpicture.cgf b/Assets/Editor/Objects/refpicture.cgf similarity index 100% rename from Editor/Objects/refpicture.cgf rename to Assets/Editor/Objects/refpicture.cgf diff --git a/Editor/Objects/refpicture.max b/Assets/Editor/Objects/refpicture.max similarity index 100% rename from Editor/Objects/refpicture.max rename to Assets/Editor/Objects/refpicture.max diff --git a/Editor/Objects/reinforcement_point.cgf b/Assets/Editor/Objects/reinforcement_point.cgf similarity index 100% rename from Editor/Objects/reinforcement_point.cgf rename to Assets/Editor/Objects/reinforcement_point.cgf diff --git a/Editor/Objects/smartobject_helper.max b/Assets/Editor/Objects/smartobject_helper.max similarity index 100% rename from Editor/Objects/smartobject_helper.max rename to Assets/Editor/Objects/smartobject_helper.max diff --git a/Editor/Objects/spawngroup.cgf b/Assets/Editor/Objects/spawngroup.cgf similarity index 100% rename from Editor/Objects/spawngroup.cgf rename to Assets/Editor/Objects/spawngroup.cgf diff --git a/Editor/Objects/spawnpointhelper.cgf b/Assets/Editor/Objects/spawnpointhelper.cgf similarity index 100% rename from Editor/Objects/spawnpointhelper.cgf rename to Assets/Editor/Objects/spawnpointhelper.cgf diff --git a/Editor/Objects/spawnpointhelper.mtl b/Assets/Editor/Objects/spawnpointhelper.mtl similarity index 100% rename from Editor/Objects/spawnpointhelper.mtl rename to Assets/Editor/Objects/spawnpointhelper.mtl diff --git a/Editor/Objects/stayOnWallFire_left.cgf b/Assets/Editor/Objects/stayOnWallFire_left.cgf similarity index 100% rename from Editor/Objects/stayOnWallFire_left.cgf rename to Assets/Editor/Objects/stayOnWallFire_left.cgf diff --git a/Editor/Objects/suit_jump_300.cgf b/Assets/Editor/Objects/suit_jump_300.cgf similarity index 100% rename from Editor/Objects/suit_jump_300.cgf rename to Assets/Editor/Objects/suit_jump_300.cgf diff --git a/Editor/Objects/suit_jump_800.cgf b/Assets/Editor/Objects/suit_jump_800.cgf similarity index 100% rename from Editor/Objects/suit_jump_800.cgf rename to Assets/Editor/Objects/suit_jump_800.cgf diff --git a/Editor/Objects/suit_leap_800.cgf b/Assets/Editor/Objects/suit_leap_800.cgf similarity index 100% rename from Editor/Objects/suit_leap_800.cgf rename to Assets/Editor/Objects/suit_leap_800.cgf diff --git a/Editor/Plugins/ParticleEditorPlugin/defaults/DefaultParticleEmitters.xml b/Assets/Editor/Plugins/ParticleEditorPlugin/defaults/DefaultParticleEmitters.xml similarity index 100% rename from Editor/Plugins/ParticleEditorPlugin/defaults/DefaultParticleEmitters.xml rename to Assets/Editor/Plugins/ParticleEditorPlugin/defaults/DefaultParticleEmitters.xml diff --git a/Editor/Plugins/ParticleEditorPlugin/defaults/defaultParticle.dds b/Assets/Editor/Plugins/ParticleEditorPlugin/defaults/defaultParticle.dds similarity index 100% rename from Editor/Plugins/ParticleEditorPlugin/defaults/defaultParticle.dds rename to Assets/Editor/Plugins/ParticleEditorPlugin/defaults/defaultParticle.dds diff --git a/Editor/Plugins/ParticleEditorPlugin/defaults/feather01.tif b/Assets/Editor/Plugins/ParticleEditorPlugin/defaults/feather01.tif similarity index 100% rename from Editor/Plugins/ParticleEditorPlugin/defaults/feather01.tif rename to Assets/Editor/Plugins/ParticleEditorPlugin/defaults/feather01.tif diff --git a/Editor/Plugins/ParticleEditorPlugin/defaults/puffup01.tif b/Assets/Editor/Plugins/ParticleEditorPlugin/defaults/puffup01.tif similarity index 100% rename from Editor/Plugins/ParticleEditorPlugin/defaults/puffup01.tif rename to Assets/Editor/Plugins/ParticleEditorPlugin/defaults/puffup01.tif diff --git a/Editor/Plugins/ParticleEditorPlugin/settings/ToolTips.xml b/Assets/Editor/Plugins/ParticleEditorPlugin/settings/ToolTips.xml similarity index 100% rename from Editor/Plugins/ParticleEditorPlugin/settings/ToolTips.xml rename to Assets/Editor/Plugins/ParticleEditorPlugin/settings/ToolTips.xml diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Left.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_TopLeft.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Anchor_Whole.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Selected.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Border_Unselected.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Canvas_Background.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/DottedLine.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Pivot.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Center_Square.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Circle.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_X.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Square_Y.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_X.tif diff --git a/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif b/Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif similarity index 100% rename from Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif rename to Assets/Editor/Plugins/UiCanvasEditor/CanvasIcons/Transform_Gizmo_Line_Triangle_Y.tif diff --git a/Editor/Presets/GeomCache/game.cbc b/Assets/Editor/Presets/GeomCache/game.cbc similarity index 100% rename from Editor/Presets/GeomCache/game.cbc rename to Assets/Editor/Presets/GeomCache/game.cbc diff --git a/Editor/Presets/GeomCache/game_lz4hc.cbc b/Assets/Editor/Presets/GeomCache/game_lz4hc.cbc similarity index 100% rename from Editor/Presets/GeomCache/game_lz4hc.cbc rename to Assets/Editor/Presets/GeomCache/game_lz4hc.cbc diff --git a/Editor/Presets/GeomCache/game_z_up.cbc b/Assets/Editor/Presets/GeomCache/game_z_up.cbc similarity index 100% rename from Editor/Presets/GeomCache/game_z_up.cbc rename to Assets/Editor/Presets/GeomCache/game_z_up.cbc diff --git a/Editor/Presets/GeomCache/game_z_up_lz4hc.cbc b/Assets/Editor/Presets/GeomCache/game_z_up_lz4hc.cbc similarity index 100% rename from Editor/Presets/GeomCache/game_z_up_lz4hc.cbc rename to Assets/Editor/Presets/GeomCache/game_z_up_lz4hc.cbc diff --git a/Editor/Presets/GeomCache/prerendered.cbc b/Assets/Editor/Presets/GeomCache/prerendered.cbc similarity index 100% rename from Editor/Presets/GeomCache/prerendered.cbc rename to Assets/Editor/Presets/GeomCache/prerendered.cbc diff --git a/Editor/Presets/GeomCache/prerendered_z_up.cbc b/Assets/Editor/Presets/GeomCache/prerendered_z_up.cbc similarity index 100% rename from Editor/Presets/GeomCache/prerendered_z_up.cbc rename to Assets/Editor/Presets/GeomCache/prerendered_z_up.cbc diff --git a/Editor/Presets/GeomCache/rigids_only.cbc b/Assets/Editor/Presets/GeomCache/rigids_only.cbc similarity index 100% rename from Editor/Presets/GeomCache/rigids_only.cbc rename to Assets/Editor/Presets/GeomCache/rigids_only.cbc diff --git a/Editor/Presets/GeomCache/rigids_only_z_up.cbc b/Assets/Editor/Presets/GeomCache/rigids_only_z_up.cbc similarity index 100% rename from Editor/Presets/GeomCache/rigids_only_z_up.cbc rename to Assets/Editor/Presets/GeomCache/rigids_only_z_up.cbc diff --git a/Editor/Presets/GeomCache/uncompressed.cbc b/Assets/Editor/Presets/GeomCache/uncompressed.cbc similarity index 100% rename from Editor/Presets/GeomCache/uncompressed.cbc rename to Assets/Editor/Presets/GeomCache/uncompressed.cbc diff --git a/Editor/Presets/GeomCache/uncompressed_z_up.cbc b/Assets/Editor/Presets/GeomCache/uncompressed_z_up.cbc similarity index 100% rename from Editor/Presets/GeomCache/uncompressed_z_up.cbc rename to Assets/Editor/Presets/GeomCache/uncompressed_z_up.cbc diff --git a/Editor/Presets/MobileSettings/GPUAndDriverLists.json b/Assets/Editor/Presets/MobileSettings/GPUAndDriverLists.json similarity index 100% rename from Editor/Presets/MobileSettings/GPUAndDriverLists.json rename to Assets/Editor/Presets/MobileSettings/GPUAndDriverLists.json diff --git a/Editor/Presets/MobileSettings/IPhone7.lms b/Assets/Editor/Presets/MobileSettings/IPhone7.lms similarity index 100% rename from Editor/Presets/MobileSettings/IPhone7.lms rename to Assets/Editor/Presets/MobileSettings/IPhone7.lms diff --git a/Editor/Presets/MobileSettings/IpadPro.lms b/Assets/Editor/Presets/MobileSettings/IpadPro.lms similarity index 100% rename from Editor/Presets/MobileSettings/IpadPro.lms rename to Assets/Editor/Presets/MobileSettings/IpadPro.lms diff --git a/Editor/Presets/MobileSettings/MobileFeatureBlackList.json b/Assets/Editor/Presets/MobileSettings/MobileFeatureBlackList.json similarity index 100% rename from Editor/Presets/MobileSettings/MobileFeatureBlackList.json rename to Assets/Editor/Presets/MobileSettings/MobileFeatureBlackList.json diff --git a/Editor/Presets/MobileSettings/Nexus9.lms b/Assets/Editor/Presets/MobileSettings/Nexus9.lms similarity index 100% rename from Editor/Presets/MobileSettings/Nexus9.lms rename to Assets/Editor/Presets/MobileSettings/Nexus9.lms diff --git a/Editor/Presets/MobileSettings/SamsungGalaxyS7_Mali.lms b/Assets/Editor/Presets/MobileSettings/SamsungGalaxyS7_Mali.lms similarity index 100% rename from Editor/Presets/MobileSettings/SamsungGalaxyS7_Mali.lms rename to Assets/Editor/Presets/MobileSettings/SamsungGalaxyS7_Mali.lms diff --git a/Editor/Presets/MobileSettings/SamsungGalaxyS7_Qualcomm.lms b/Assets/Editor/Presets/MobileSettings/SamsungGalaxyS7_Qualcomm.lms similarity index 100% rename from Editor/Presets/MobileSettings/SamsungGalaxyS7_Qualcomm.lms rename to Assets/Editor/Presets/MobileSettings/SamsungGalaxyS7_Qualcomm.lms diff --git a/Editor/PropertyEnumerations.xml b/Assets/Editor/PropertyEnumerations.xml similarity index 100% rename from Editor/PropertyEnumerations.xml rename to Assets/Editor/PropertyEnumerations.xml diff --git a/Editor/Scripts/Shelves/icons/Albedo.png b/Assets/Editor/Scripts/Shelves/icons/Albedo.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Albedo.png rename to Assets/Editor/Scripts/Shelves/icons/Albedo.png diff --git a/Editor/Scripts/Shelves/icons/Diffuse_Lighting.png b/Assets/Editor/Scripts/Shelves/icons/Diffuse_Lighting.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Diffuse_Lighting.png rename to Assets/Editor/Scripts/Shelves/icons/Diffuse_Lighting.png diff --git a/Editor/Scripts/Shelves/icons/Diffuse_Texture_Res_360.png b/Assets/Editor/Scripts/Shelves/icons/Diffuse_Texture_Res_360.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Diffuse_Texture_Res_360.png rename to Assets/Editor/Scripts/Shelves/icons/Diffuse_Texture_Res_360.png diff --git a/Editor/Scripts/Shelves/icons/Empty_Wireframe.png b/Assets/Editor/Scripts/Shelves/icons/Empty_Wireframe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Empty_Wireframe.png rename to Assets/Editor/Scripts/Shelves/icons/Empty_Wireframe.png diff --git a/Editor/Scripts/Shelves/icons/Exit.png b/Assets/Editor/Scripts/Shelves/icons/Exit.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Exit.png rename to Assets/Editor/Scripts/Shelves/icons/Exit.png diff --git a/Editor/Scripts/Shelves/icons/Fuzziness.png b/Assets/Editor/Scripts/Shelves/icons/Fuzziness.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Fuzziness.png rename to Assets/Editor/Scripts/Shelves/icons/Fuzziness.png diff --git a/Editor/Scripts/Shelves/icons/Gloss.png b/Assets/Editor/Scripts/Shelves/icons/Gloss.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Gloss.png rename to Assets/Editor/Scripts/Shelves/icons/Gloss.png diff --git a/Editor/Scripts/Shelves/icons/Normal_Texture_Res_360.png b/Assets/Editor/Scripts/Shelves/icons/Normal_Texture_Res_360.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Normal_Texture_Res_360.png rename to Assets/Editor/Scripts/Shelves/icons/Normal_Texture_Res_360.png diff --git a/Editor/Scripts/Shelves/icons/PrefabAddLibrary.png b/Assets/Editor/Scripts/Shelves/icons/PrefabAddLibrary.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabAddLibrary.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabAddLibrary.png diff --git a/Editor/Scripts/Shelves/icons/PrefabAddSelection.png b/Assets/Editor/Scripts/Shelves/icons/PrefabAddSelection.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabAddSelection.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabAddSelection.png diff --git a/Editor/Scripts/Shelves/icons/PrefabBreak.png b/Assets/Editor/Scripts/Shelves/icons/PrefabBreak.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabBreak.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabBreak.png diff --git a/Editor/Scripts/Shelves/icons/PrefabConvert.png b/Assets/Editor/Scripts/Shelves/icons/PrefabConvert.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabConvert.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabConvert.png diff --git a/Editor/Scripts/Shelves/icons/PrefabCreate.png b/Assets/Editor/Scripts/Shelves/icons/PrefabCreate.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabCreate.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabCreate.png diff --git a/Editor/Scripts/Shelves/icons/PrefabIsolate.png b/Assets/Editor/Scripts/Shelves/icons/PrefabIsolate.png similarity index 100% rename from Editor/Scripts/Shelves/icons/PrefabIsolate.png rename to Assets/Editor/Scripts/Shelves/icons/PrefabIsolate.png diff --git a/Editor/Scripts/Shelves/icons/Scattering.png b/Assets/Editor/Scripts/Shelves/icons/Scattering.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Scattering.png rename to Assets/Editor/Scripts/Shelves/icons/Scattering.png diff --git a/Editor/Scripts/Shelves/icons/Solid_Wireframe.png b/Assets/Editor/Scripts/Shelves/icons/Solid_Wireframe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Solid_Wireframe.png rename to Assets/Editor/Scripts/Shelves/icons/Solid_Wireframe.png diff --git a/Editor/Scripts/Shelves/icons/Spec_Amount.png b/Assets/Editor/Scripts/Shelves/icons/Spec_Amount.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Spec_Amount.png rename to Assets/Editor/Scripts/Shelves/icons/Spec_Amount.png diff --git a/Editor/Scripts/Shelves/icons/Spec_Lighting.png b/Assets/Editor/Scripts/Shelves/icons/Spec_Lighting.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Spec_Lighting.png rename to Assets/Editor/Scripts/Shelves/icons/Spec_Lighting.png diff --git a/Editor/Scripts/Shelves/icons/Texel_Per_Meter_1024.png b/Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_1024.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Texel_Per_Meter_1024.png rename to Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_1024.png diff --git a/Editor/Scripts/Shelves/icons/Texel_Per_Meter_256.png b/Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_256.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Texel_Per_Meter_256.png rename to Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_256.png diff --git a/Editor/Scripts/Shelves/icons/Texel_Per_Meter_512.png b/Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_512.png similarity index 100% rename from Editor/Scripts/Shelves/icons/Texel_Per_Meter_512.png rename to Assets/Editor/Scripts/Shelves/icons/Texel_Per_Meter_512.png diff --git a/Editor/Scripts/Shelves/icons/all.png b/Assets/Editor/Scripts/Shelves/icons/all.png similarity index 100% rename from Editor/Scripts/Shelves/icons/all.png rename to Assets/Editor/Scripts/Shelves/icons/all.png diff --git a/Editor/Scripts/Shelves/icons/beams.png b/Assets/Editor/Scripts/Shelves/icons/beams.png similarity index 100% rename from Editor/Scripts/Shelves/icons/beams.png rename to Assets/Editor/Scripts/Shelves/icons/beams.png diff --git a/Editor/Scripts/Shelves/icons/blanker.png b/Assets/Editor/Scripts/Shelves/icons/blanker.png similarity index 100% rename from Editor/Scripts/Shelves/icons/blanker.png rename to Assets/Editor/Scripts/Shelves/icons/blanker.png diff --git a/Editor/Scripts/Shelves/icons/bounding_box.png b/Assets/Editor/Scripts/Shelves/icons/bounding_box.png similarity index 100% rename from Editor/Scripts/Shelves/icons/bounding_box.png rename to Assets/Editor/Scripts/Shelves/icons/bounding_box.png diff --git a/Editor/Scripts/Shelves/icons/brushes.png b/Assets/Editor/Scripts/Shelves/icons/brushes.png similarity index 100% rename from Editor/Scripts/Shelves/icons/brushes.png rename to Assets/Editor/Scripts/Shelves/icons/brushes.png diff --git a/Editor/Scripts/Shelves/icons/cloud.png b/Assets/Editor/Scripts/Shelves/icons/cloud.png similarity index 100% rename from Editor/Scripts/Shelves/icons/cloud.png rename to Assets/Editor/Scripts/Shelves/icons/cloud.png diff --git a/Editor/Scripts/Shelves/icons/cloud_dark.png b/Assets/Editor/Scripts/Shelves/icons/cloud_dark.png similarity index 100% rename from Editor/Scripts/Shelves/icons/cloud_dark.png rename to Assets/Editor/Scripts/Shelves/icons/cloud_dark.png diff --git a/Editor/Scripts/Shelves/icons/cloud_dark_rain.png b/Assets/Editor/Scripts/Shelves/icons/cloud_dark_rain.png similarity index 100% rename from Editor/Scripts/Shelves/icons/cloud_dark_rain.png rename to Assets/Editor/Scripts/Shelves/icons/cloud_dark_rain.png diff --git a/Editor/Scripts/Shelves/icons/collisions.png b/Assets/Editor/Scripts/Shelves/icons/collisions.png similarity index 100% rename from Editor/Scripts/Shelves/icons/collisions.png rename to Assets/Editor/Scripts/Shelves/icons/collisions.png diff --git a/Editor/Scripts/Shelves/icons/create_ao_volume_box.png b/Assets/Editor/Scripts/Shelves/icons/create_ao_volume_box.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_ao_volume_box.png rename to Assets/Editor/Scripts/Shelves/icons/create_ao_volume_box.png diff --git a/Editor/Scripts/Shelves/icons/create_both_vis_box_envprobe.png b/Assets/Editor/Scripts/Shelves/icons/create_both_vis_box_envprobe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_both_vis_box_envprobe.png rename to Assets/Editor/Scripts/Shelves/icons/create_both_vis_box_envprobe.png diff --git a/Editor/Scripts/Shelves/icons/create_envprobe.png b/Assets/Editor/Scripts/Shelves/icons/create_envprobe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_envprobe.png rename to Assets/Editor/Scripts/Shelves/icons/create_envprobe.png diff --git a/Editor/Scripts/Shelves/icons/create_portal_box.png b/Assets/Editor/Scripts/Shelves/icons/create_portal_box.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_portal_box.png rename to Assets/Editor/Scripts/Shelves/icons/create_portal_box.png diff --git a/Editor/Scripts/Shelves/icons/create_vis_box.png b/Assets/Editor/Scripts/Shelves/icons/create_vis_box.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_vis_box.png rename to Assets/Editor/Scripts/Shelves/icons/create_vis_box.png diff --git a/Editor/Scripts/Shelves/icons/create_vis_box_and_portal_box.png b/Assets/Editor/Scripts/Shelves/icons/create_vis_box_and_portal_box.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_vis_box_and_portal_box.png rename to Assets/Editor/Scripts/Shelves/icons/create_vis_box_and_portal_box.png diff --git a/Editor/Scripts/Shelves/icons/create_vis_box_env_probe_and_portal.png b/Assets/Editor/Scripts/Shelves/icons/create_vis_box_env_probe_and_portal.png similarity index 100% rename from Editor/Scripts/Shelves/icons/create_vis_box_env_probe_and_portal.png rename to Assets/Editor/Scripts/Shelves/icons/create_vis_box_env_probe_and_portal.png diff --git a/Editor/Scripts/Shelves/icons/cubemap.png b/Assets/Editor/Scripts/Shelves/icons/cubemap.png similarity index 100% rename from Editor/Scripts/Shelves/icons/cubemap.png rename to Assets/Editor/Scripts/Shelves/icons/cubemap.png diff --git a/Editor/Scripts/Shelves/icons/decals.png b/Assets/Editor/Scripts/Shelves/icons/decals.png similarity index 100% rename from Editor/Scripts/Shelves/icons/decals.png rename to Assets/Editor/Scripts/Shelves/icons/decals.png diff --git a/Editor/Scripts/Shelves/icons/default_material.png b/Assets/Editor/Scripts/Shelves/icons/default_material.png similarity index 100% rename from Editor/Scripts/Shelves/icons/default_material.png rename to Assets/Editor/Scripts/Shelves/icons/default_material.png diff --git a/Editor/Scripts/Shelves/icons/default_material_with_normals.png b/Assets/Editor/Scripts/Shelves/icons/default_material_with_normals.png similarity index 100% rename from Editor/Scripts/Shelves/icons/default_material_with_normals.png rename to Assets/Editor/Scripts/Shelves/icons/default_material_with_normals.png diff --git a/Editor/Scripts/Shelves/icons/designer.png b/Assets/Editor/Scripts/Shelves/icons/designer.png similarity index 100% rename from Editor/Scripts/Shelves/icons/designer.png rename to Assets/Editor/Scripts/Shelves/icons/designer.png diff --git a/Editor/Scripts/Shelves/icons/diff_acc.png b/Assets/Editor/Scripts/Shelves/icons/diff_acc.png similarity index 100% rename from Editor/Scripts/Shelves/icons/diff_acc.png rename to Assets/Editor/Scripts/Shelves/icons/diff_acc.png diff --git a/Editor/Scripts/Shelves/icons/display_info.png b/Assets/Editor/Scripts/Shelves/icons/display_info.png similarity index 100% rename from Editor/Scripts/Shelves/icons/display_info.png rename to Assets/Editor/Scripts/Shelves/icons/display_info.png diff --git a/Editor/Scripts/Shelves/icons/dual_layer_mask.png b/Assets/Editor/Scripts/Shelves/icons/dual_layer_mask.png similarity index 100% rename from Editor/Scripts/Shelves/icons/dual_layer_mask.png rename to Assets/Editor/Scripts/Shelves/icons/dual_layer_mask.png diff --git a/Editor/Scripts/Shelves/icons/dynamiclights.png b/Assets/Editor/Scripts/Shelves/icons/dynamiclights.png similarity index 100% rename from Editor/Scripts/Shelves/icons/dynamiclights.png rename to Assets/Editor/Scripts/Shelves/icons/dynamiclights.png diff --git a/Editor/Scripts/Shelves/icons/entities.png b/Assets/Editor/Scripts/Shelves/icons/entities.png similarity index 100% rename from Editor/Scripts/Shelves/icons/entities.png rename to Assets/Editor/Scripts/Shelves/icons/entities.png diff --git a/Editor/Scripts/Shelves/icons/eye_adaptation_speed.png b/Assets/Editor/Scripts/Shelves/icons/eye_adaptation_speed.png similarity index 100% rename from Editor/Scripts/Shelves/icons/eye_adaptation_speed.png rename to Assets/Editor/Scripts/Shelves/icons/eye_adaptation_speed.png diff --git a/Editor/Scripts/Shelves/icons/fog.png b/Assets/Editor/Scripts/Shelves/icons/fog.png similarity index 100% rename from Editor/Scripts/Shelves/icons/fog.png rename to Assets/Editor/Scripts/Shelves/icons/fog.png diff --git a/Editor/Scripts/Shelves/icons/fogvolumes.png b/Assets/Editor/Scripts/Shelves/icons/fogvolumes.png similarity index 100% rename from Editor/Scripts/Shelves/icons/fogvolumes.png rename to Assets/Editor/Scripts/Shelves/icons/fogvolumes.png diff --git a/Editor/Scripts/Shelves/icons/freeze_particles.png b/Assets/Editor/Scripts/Shelves/icons/freeze_particles.png similarity index 100% rename from Editor/Scripts/Shelves/icons/freeze_particles.png rename to Assets/Editor/Scripts/Shelves/icons/freeze_particles.png diff --git a/Editor/Scripts/Shelves/icons/full_shading.png b/Assets/Editor/Scripts/Shelves/icons/full_shading.png similarity index 100% rename from Editor/Scripts/Shelves/icons/full_shading.png rename to Assets/Editor/Scripts/Shelves/icons/full_shading.png diff --git a/Editor/Scripts/Shelves/icons/gamma.png b/Assets/Editor/Scripts/Shelves/icons/gamma.png similarity index 100% rename from Editor/Scripts/Shelves/icons/gamma.png rename to Assets/Editor/Scripts/Shelves/icons/gamma.png diff --git a/Editor/Scripts/Shelves/icons/gi.png b/Assets/Editor/Scripts/Shelves/icons/gi.png similarity index 100% rename from Editor/Scripts/Shelves/icons/gi.png rename to Assets/Editor/Scripts/Shelves/icons/gi.png diff --git a/Editor/Scripts/Shelves/icons/lens_flare.png b/Assets/Editor/Scripts/Shelves/icons/lens_flare.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lens_flare.png rename to Assets/Editor/Scripts/Shelves/icons/lens_flare.png diff --git a/Editor/Scripts/Shelves/icons/lighting_only.png b/Assets/Editor/Scripts/Shelves/icons/lighting_only.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lighting_only.png rename to Assets/Editor/Scripts/Shelves/icons/lighting_only.png diff --git a/Editor/Scripts/Shelves/icons/lods.png b/Assets/Editor/Scripts/Shelves/icons/lods.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lods.png rename to Assets/Editor/Scripts/Shelves/icons/lods.png diff --git a/Editor/Scripts/Shelves/icons/lsao.png b/Assets/Editor/Scripts/Shelves/icons/lsao.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lsao.png rename to Assets/Editor/Scripts/Shelves/icons/lsao.png diff --git a/Editor/Scripts/Shelves/icons/lsao_toggle.png b/Assets/Editor/Scripts/Shelves/icons/lsao_toggle.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lsao_toggle.png rename to Assets/Editor/Scripts/Shelves/icons/lsao_toggle.png diff --git a/Editor/Scripts/Shelves/icons/lsro.png b/Assets/Editor/Scripts/Shelves/icons/lsro.png similarity index 100% rename from Editor/Scripts/Shelves/icons/lsro.png rename to Assets/Editor/Scripts/Shelves/icons/lsro.png diff --git a/Editor/Scripts/Shelves/icons/normals.png b/Assets/Editor/Scripts/Shelves/icons/normals.png similarity index 100% rename from Editor/Scripts/Shelves/icons/normals.png rename to Assets/Editor/Scripts/Shelves/icons/normals.png diff --git a/Editor/Scripts/Shelves/icons/normals_x.png b/Assets/Editor/Scripts/Shelves/icons/normals_x.png similarity index 100% rename from Editor/Scripts/Shelves/icons/normals_x.png rename to Assets/Editor/Scripts/Shelves/icons/normals_x.png diff --git a/Editor/Scripts/Shelves/icons/normals_y.png b/Assets/Editor/Scripts/Shelves/icons/normals_y.png similarity index 100% rename from Editor/Scripts/Shelves/icons/normals_y.png rename to Assets/Editor/Scripts/Shelves/icons/normals_y.png diff --git a/Editor/Scripts/Shelves/icons/normals_z.png b/Assets/Editor/Scripts/Shelves/icons/normals_z.png similarity index 100% rename from Editor/Scripts/Shelves/icons/normals_z.png rename to Assets/Editor/Scripts/Shelves/icons/normals_z.png diff --git a/Editor/Scripts/Shelves/icons/ocean.png b/Assets/Editor/Scripts/Shelves/icons/ocean.png similarity index 100% rename from Editor/Scripts/Shelves/icons/ocean.png rename to Assets/Editor/Scripts/Shelves/icons/ocean.png diff --git a/Editor/Scripts/Shelves/icons/particles.png b/Assets/Editor/Scripts/Shelves/icons/particles.png similarity index 100% rename from Editor/Scripts/Shelves/icons/particles.png rename to Assets/Editor/Scripts/Shelves/icons/particles.png diff --git a/Editor/Scripts/Shelves/icons/particles_bounds.png b/Assets/Editor/Scripts/Shelves/icons/particles_bounds.png similarity index 100% rename from Editor/Scripts/Shelves/icons/particles_bounds.png rename to Assets/Editor/Scripts/Shelves/icons/particles_bounds.png diff --git a/Editor/Scripts/Shelves/icons/particles_off.png b/Assets/Editor/Scripts/Shelves/icons/particles_off.png similarity index 100% rename from Editor/Scripts/Shelves/icons/particles_off.png rename to Assets/Editor/Scripts/Shelves/icons/particles_off.png diff --git a/Editor/Scripts/Shelves/icons/particles_overdraw.png b/Assets/Editor/Scripts/Shelves/icons/particles_overdraw.png similarity index 100% rename from Editor/Scripts/Shelves/icons/particles_overdraw.png rename to Assets/Editor/Scripts/Shelves/icons/particles_overdraw.png diff --git a/Editor/Scripts/Shelves/icons/particles_screen_coverage.png b/Assets/Editor/Scripts/Shelves/icons/particles_screen_coverage.png similarity index 100% rename from Editor/Scripts/Shelves/icons/particles_screen_coverage.png rename to Assets/Editor/Scripts/Shelves/icons/particles_screen_coverage.png diff --git a/Editor/Scripts/Shelves/icons/placeholder.png b/Assets/Editor/Scripts/Shelves/icons/placeholder.png similarity index 100% rename from Editor/Scripts/Shelves/icons/placeholder.png rename to Assets/Editor/Scripts/Shelves/icons/placeholder.png diff --git a/Editor/Scripts/Shelves/icons/prefab.png b/Assets/Editor/Scripts/Shelves/icons/prefab.png similarity index 100% rename from Editor/Scripts/Shelves/icons/prefab.png rename to Assets/Editor/Scripts/Shelves/icons/prefab.png diff --git a/Editor/Scripts/Shelves/icons/reflections.png b/Assets/Editor/Scripts/Shelves/icons/reflections.png similarity index 100% rename from Editor/Scripts/Shelves/icons/reflections.png rename to Assets/Editor/Scripts/Shelves/icons/reflections.png diff --git a/Editor/Scripts/Shelves/icons/reset.png b/Assets/Editor/Scripts/Shelves/icons/reset.png similarity index 100% rename from Editor/Scripts/Shelves/icons/reset.png rename to Assets/Editor/Scripts/Shelves/icons/reset.png diff --git a/Editor/Scripts/Shelves/icons/selfocc.png b/Assets/Editor/Scripts/Shelves/icons/selfocc.png similarity index 100% rename from Editor/Scripts/Shelves/icons/selfocc.png rename to Assets/Editor/Scripts/Shelves/icons/selfocc.png diff --git a/Editor/Scripts/Shelves/icons/shaded_wireframe.png b/Assets/Editor/Scripts/Shelves/icons/shaded_wireframe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/shaded_wireframe.png rename to Assets/Editor/Scripts/Shelves/icons/shaded_wireframe.png diff --git a/Editor/Scripts/Shelves/icons/shadows.png b/Assets/Editor/Scripts/Shelves/icons/shadows.png similarity index 100% rename from Editor/Scripts/Shelves/icons/shadows.png rename to Assets/Editor/Scripts/Shelves/icons/shadows.png diff --git a/Editor/Scripts/Shelves/icons/showlines.png b/Assets/Editor/Scripts/Shelves/icons/showlines.png similarity index 100% rename from Editor/Scripts/Shelves/icons/showlines.png rename to Assets/Editor/Scripts/Shelves/icons/showlines.png diff --git a/Editor/Scripts/Shelves/icons/sky.png b/Assets/Editor/Scripts/Shelves/icons/sky.png similarity index 100% rename from Editor/Scripts/Shelves/icons/sky.png rename to Assets/Editor/Scripts/Shelves/icons/sky.png diff --git a/Editor/Scripts/Shelves/icons/spec_acc.png b/Assets/Editor/Scripts/Shelves/icons/spec_acc.png similarity index 100% rename from Editor/Scripts/Shelves/icons/spec_acc.png rename to Assets/Editor/Scripts/Shelves/icons/spec_acc.png diff --git a/Editor/Scripts/Shelves/icons/spec_lum.png b/Assets/Editor/Scripts/Shelves/icons/spec_lum.png similarity index 100% rename from Editor/Scripts/Shelves/icons/spec_lum.png rename to Assets/Editor/Scripts/Shelves/icons/spec_lum.png diff --git a/Editor/Scripts/Shelves/icons/spec_occ.png b/Assets/Editor/Scripts/Shelves/icons/spec_occ.png similarity index 100% rename from Editor/Scripts/Shelves/icons/spec_occ.png rename to Assets/Editor/Scripts/Shelves/icons/spec_occ.png diff --git a/Editor/Scripts/Shelves/icons/ssao.png b/Assets/Editor/Scripts/Shelves/icons/ssao.png similarity index 100% rename from Editor/Scripts/Shelves/icons/ssao.png rename to Assets/Editor/Scripts/Shelves/icons/ssao.png diff --git a/Editor/Scripts/Shelves/icons/ssdo.png b/Assets/Editor/Scripts/Shelves/icons/ssdo.png similarity index 100% rename from Editor/Scripts/Shelves/icons/ssdo.png rename to Assets/Editor/Scripts/Shelves/icons/ssdo.png diff --git a/Editor/Scripts/Shelves/icons/ssdo_toggle.png b/Assets/Editor/Scripts/Shelves/icons/ssdo_toggle.png similarity index 100% rename from Editor/Scripts/Shelves/icons/ssdo_toggle.png rename to Assets/Editor/Scripts/Shelves/icons/ssdo_toggle.png diff --git a/Editor/Scripts/Shelves/icons/sun.big.png b/Assets/Editor/Scripts/Shelves/icons/sun.big.png similarity index 100% rename from Editor/Scripts/Shelves/icons/sun.big.png rename to Assets/Editor/Scripts/Shelves/icons/sun.big.png diff --git a/Editor/Scripts/Shelves/icons/tangents.png b/Assets/Editor/Scripts/Shelves/icons/tangents.png similarity index 100% rename from Editor/Scripts/Shelves/icons/tangents.png rename to Assets/Editor/Scripts/Shelves/icons/tangents.png diff --git a/Editor/Scripts/Shelves/icons/terrain.png b/Assets/Editor/Scripts/Shelves/icons/terrain.png similarity index 100% rename from Editor/Scripts/Shelves/icons/terrain.png rename to Assets/Editor/Scripts/Shelves/icons/terrain.png diff --git a/Editor/Scripts/Shelves/icons/time_scale_double.png b/Assets/Editor/Scripts/Shelves/icons/time_scale_double.png similarity index 100% rename from Editor/Scripts/Shelves/icons/time_scale_double.png rename to Assets/Editor/Scripts/Shelves/icons/time_scale_double.png diff --git a/Editor/Scripts/Shelves/icons/time_scale_frozen.png b/Assets/Editor/Scripts/Shelves/icons/time_scale_frozen.png similarity index 100% rename from Editor/Scripts/Shelves/icons/time_scale_frozen.png rename to Assets/Editor/Scripts/Shelves/icons/time_scale_frozen.png diff --git a/Editor/Scripts/Shelves/icons/time_scale_half.png b/Assets/Editor/Scripts/Shelves/icons/time_scale_half.png similarity index 100% rename from Editor/Scripts/Shelves/icons/time_scale_half.png rename to Assets/Editor/Scripts/Shelves/icons/time_scale_half.png diff --git a/Editor/Scripts/Shelves/icons/time_scale_quarter.png b/Assets/Editor/Scripts/Shelves/icons/time_scale_quarter.png similarity index 100% rename from Editor/Scripts/Shelves/icons/time_scale_quarter.png rename to Assets/Editor/Scripts/Shelves/icons/time_scale_quarter.png diff --git a/Editor/Scripts/Shelves/icons/time_scale_tenth.png b/Assets/Editor/Scripts/Shelves/icons/time_scale_tenth.png similarity index 100% rename from Editor/Scripts/Shelves/icons/time_scale_tenth.png rename to Assets/Editor/Scripts/Shelves/icons/time_scale_tenth.png diff --git a/Editor/Scripts/Shelves/icons/tod.png b/Assets/Editor/Scripts/Shelves/icons/tod.png similarity index 100% rename from Editor/Scripts/Shelves/icons/tod.png rename to Assets/Editor/Scripts/Shelves/icons/tod.png diff --git a/Editor/Scripts/Shelves/icons/translucency.png b/Assets/Editor/Scripts/Shelves/icons/translucency.png similarity index 100% rename from Editor/Scripts/Shelves/icons/translucency.png rename to Assets/Editor/Scripts/Shelves/icons/translucency.png diff --git a/Editor/Scripts/Shelves/icons/transparency.png b/Assets/Editor/Scripts/Shelves/icons/transparency.png similarity index 100% rename from Editor/Scripts/Shelves/icons/transparency.png rename to Assets/Editor/Scripts/Shelves/icons/transparency.png diff --git a/Editor/Scripts/Shelves/icons/valid_albedo.png b/Assets/Editor/Scripts/Shelves/icons/valid_albedo.png similarity index 100% rename from Editor/Scripts/Shelves/icons/valid_albedo.png rename to Assets/Editor/Scripts/Shelves/icons/valid_albedo.png diff --git a/Editor/Scripts/Shelves/icons/valid_spec_lum.png b/Assets/Editor/Scripts/Shelves/icons/valid_spec_lum.png similarity index 100% rename from Editor/Scripts/Shelves/icons/valid_spec_lum.png rename to Assets/Editor/Scripts/Shelves/icons/valid_spec_lum.png diff --git a/Editor/Scripts/Shelves/icons/vegetation.png b/Assets/Editor/Scripts/Shelves/icons/vegetation.png similarity index 100% rename from Editor/Scripts/Shelves/icons/vegetation.png rename to Assets/Editor/Scripts/Shelves/icons/vegetation.png diff --git a/Editor/Scripts/Shelves/icons/vertex_normals.png b/Assets/Editor/Scripts/Shelves/icons/vertex_normals.png similarity index 100% rename from Editor/Scripts/Shelves/icons/vertex_normals.png rename to Assets/Editor/Scripts/Shelves/icons/vertex_normals.png diff --git a/Editor/Scripts/Shelves/icons/vis_area.png b/Assets/Editor/Scripts/Shelves/icons/vis_area.png similarity index 100% rename from Editor/Scripts/Shelves/icons/vis_area.png rename to Assets/Editor/Scripts/Shelves/icons/vis_area.png diff --git a/Editor/Scripts/Shelves/icons/water_volume.png b/Assets/Editor/Scripts/Shelves/icons/water_volume.png similarity index 100% rename from Editor/Scripts/Shelves/icons/water_volume.png rename to Assets/Editor/Scripts/Shelves/icons/water_volume.png diff --git a/Editor/Scripts/Shelves/icons/wind.png b/Assets/Editor/Scripts/Shelves/icons/wind.png similarity index 100% rename from Editor/Scripts/Shelves/icons/wind.png rename to Assets/Editor/Scripts/Shelves/icons/wind.png diff --git a/Editor/Scripts/Shelves/icons/wireframe.png b/Assets/Editor/Scripts/Shelves/icons/wireframe.png similarity index 100% rename from Editor/Scripts/Shelves/icons/wireframe.png rename to Assets/Editor/Scripts/Shelves/icons/wireframe.png diff --git a/Editor/Scripts/TrackView/example.py b/Assets/Editor/Scripts/TrackView/example.py similarity index 100% rename from Editor/Scripts/TrackView/example.py rename to Assets/Editor/Scripts/TrackView/example.py diff --git a/Editor/Scripts/editor_script_validation.py b/Assets/Editor/Scripts/editor_script_validation.py similarity index 100% rename from Editor/Scripts/editor_script_validation.py rename to Assets/Editor/Scripts/editor_script_validation.py diff --git a/Editor/Scripts/export_all_project_levels.py b/Assets/Editor/Scripts/export_all_project_levels.py similarity index 100% rename from Editor/Scripts/export_all_project_levels.py rename to Assets/Editor/Scripts/export_all_project_levels.py diff --git a/Editor/Scripts/generatelod.py b/Assets/Editor/Scripts/generatelod.py similarity index 100% rename from Editor/Scripts/generatelod.py rename to Assets/Editor/Scripts/generatelod.py diff --git a/Editor/Scripts/rename_cgf.py b/Assets/Editor/Scripts/rename_cgf.py similarity index 100% rename from Editor/Scripts/rename_cgf.py rename to Assets/Editor/Scripts/rename_cgf.py diff --git a/Editor/Scripts/select_story_anim_objects.py b/Assets/Editor/Scripts/select_story_anim_objects.py similarity index 100% rename from Editor/Scripts/select_story_anim_objects.py rename to Assets/Editor/Scripts/select_story_anim_objects.py diff --git a/Editor/Scripts/tools_shelf_actions.py b/Assets/Editor/Scripts/tools_shelf_actions.py similarity index 100% rename from Editor/Scripts/tools_shelf_actions.py rename to Assets/Editor/Scripts/tools_shelf_actions.py diff --git a/Editor/SoundTemplates.xml b/Assets/Editor/SoundTemplates.xml similarity index 100% rename from Editor/SoundTemplates.xml rename to Assets/Editor/SoundTemplates.xml diff --git a/Editor/Styles/AssetImporterWindow.qss b/Assets/Editor/Styles/AssetImporterWindow.qss similarity index 100% rename from Editor/Styles/AssetImporterWindow.qss rename to Assets/Editor/Styles/AssetImporterWindow.qss diff --git a/Editor/Styles/AssetProcessor.qss b/Assets/Editor/Styles/AssetProcessor.qss similarity index 100% rename from Editor/Styles/AssetProcessor.qss rename to Assets/Editor/Styles/AssetProcessor.qss diff --git a/Editor/Styles/AssetProcessorGlobalStyleSheet.qss b/Assets/Editor/Styles/AssetProcessorGlobalStyleSheet.qss similarity index 100% rename from Editor/Styles/AssetProcessorGlobalStyleSheet.qss rename to Assets/Editor/Styles/AssetProcessorGlobalStyleSheet.qss diff --git a/Editor/Styles/AssetProcessorGlobalStyleSheetVariables.json b/Assets/Editor/Styles/AssetProcessorGlobalStyleSheetVariables.json similarity index 100% rename from Editor/Styles/AssetProcessorGlobalStyleSheetVariables.json rename to Assets/Editor/Styles/AssetProcessorGlobalStyleSheetVariables.json diff --git a/Editor/Styles/CryDark.cjstyles b/Assets/Editor/Styles/CryDark.cjstyles similarity index 100% rename from Editor/Styles/CryDark.cjstyles rename to Assets/Editor/Styles/CryDark.cjstyles diff --git a/Editor/Styles/CryLight.cjstyles b/Assets/Editor/Styles/CryLight.cjstyles similarity index 100% rename from Editor/Styles/CryLight.cjstyles rename to Assets/Editor/Styles/CryLight.cjstyles diff --git a/Editor/Styles/MultiMeshSelectionPane.qss b/Assets/Editor/Styles/MultiMeshSelectionPane.qss similarity index 100% rename from Editor/Styles/MultiMeshSelectionPane.qss rename to Assets/Editor/Styles/MultiMeshSelectionPane.qss diff --git a/Editor/Styles/Office2007.dll b/Assets/Editor/Styles/Office2007.dll similarity index 100% rename from Editor/Styles/Office2007.dll rename to Assets/Editor/Styles/Office2007.dll diff --git a/Editor/Styles/Office2007Black.dll b/Assets/Editor/Styles/Office2007Black.dll similarity index 100% rename from Editor/Styles/Office2007Black.dll rename to Assets/Editor/Styles/Office2007Black.dll diff --git a/Editor/Styles/Office2007Silver.dll b/Assets/Editor/Styles/Office2007Silver.dll similarity index 100% rename from Editor/Styles/Office2007Silver.dll rename to Assets/Editor/Styles/Office2007Silver.dll diff --git a/Editor/Styles/StyleSheetImages/Validation_icon.png b/Assets/Editor/Styles/StyleSheetImages/Validation_icon.png similarity index 100% rename from Editor/Styles/StyleSheetImages/Validation_icon.png rename to Assets/Editor/Styles/StyleSheetImages/Validation_icon.png diff --git a/Editor/Styles/StyleSheetImages/about_dark.png b/Assets/Editor/Styles/StyleSheetImages/about_dark.png similarity index 100% rename from Editor/Styles/StyleSheetImages/about_dark.png rename to Assets/Editor/Styles/StyleSheetImages/about_dark.png diff --git a/Editor/Styles/StyleSheetImages/about_light.png b/Assets/Editor/Styles/StyleSheetImages/about_light.png similarity index 100% rename from Editor/Styles/StyleSheetImages/about_light.png rename to Assets/Editor/Styles/StyleSheetImages/about_light.png diff --git a/Editor/Styles/StyleSheetImages/arrow_down_V2.png b/Assets/Editor/Styles/StyleSheetImages/arrow_down_V2.png similarity index 100% rename from Editor/Styles/StyleSheetImages/arrow_down_V2.png rename to Assets/Editor/Styles/StyleSheetImages/arrow_down_V2.png diff --git a/Editor/Styles/StyleSheetImages/arrow_left_V2.png b/Assets/Editor/Styles/StyleSheetImages/arrow_left_V2.png similarity index 100% rename from Editor/Styles/StyleSheetImages/arrow_left_V2.png rename to Assets/Editor/Styles/StyleSheetImages/arrow_left_V2.png diff --git a/Editor/Styles/StyleSheetImages/arrow_right_V2.png b/Assets/Editor/Styles/StyleSheetImages/arrow_right_V2.png similarity index 100% rename from Editor/Styles/StyleSheetImages/arrow_right_V2.png rename to Assets/Editor/Styles/StyleSheetImages/arrow_right_V2.png diff --git a/Editor/Styles/StyleSheetImages/arrow_up_V2.png b/Assets/Editor/Styles/StyleSheetImages/arrow_up_V2.png similarity index 100% rename from Editor/Styles/StyleSheetImages/arrow_up_V2.png rename to Assets/Editor/Styles/StyleSheetImages/arrow_up_V2.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_checked.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_checked.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_checked.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_checked.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_checked_disabled.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_checked_disabled.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_checked_disabled.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_checked_disabled.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_checked_hover.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_checked_hover.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_checked_hover.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_checked_hover.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_checked_pressed.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_checked_pressed.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_checked_pressed.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_checked_pressed.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_indeterminate_hover .png b/Assets/Editor/Styles/StyleSheetImages/checkbox_indeterminate_hover .png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_indeterminate_hover .png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_indeterminate_hover .png diff --git a/Editor/Styles/StyleSheetImages/checkbox_indeterminate_pressed.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_indeterminate_pressed.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_indeterminate_pressed.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_indeterminate_pressed.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_unchecked.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_unchecked.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_unchecked_disabled.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_disabled.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_unchecked_disabled.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_disabled.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_unchecked_hover.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_hover.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_unchecked_hover.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_hover.png diff --git a/Editor/Styles/StyleSheetImages/checkbox_unchecked_pressed.png b/Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_pressed.png similarity index 100% rename from Editor/Styles/StyleSheetImages/checkbox_unchecked_pressed.png rename to Assets/Editor/Styles/StyleSheetImages/checkbox_unchecked_pressed.png diff --git a/Editor/Styles/StyleSheetImages/dropdown_arrow.png b/Assets/Editor/Styles/StyleSheetImages/dropdown_arrow.png similarity index 100% rename from Editor/Styles/StyleSheetImages/dropdown_arrow.png rename to Assets/Editor/Styles/StyleSheetImages/dropdown_arrow.png diff --git a/Editor/Styles/StyleSheetImages/error_icon.png b/Assets/Editor/Styles/StyleSheetImages/error_icon.png similarity index 100% rename from Editor/Styles/StyleSheetImages/error_icon.png rename to Assets/Editor/Styles/StyleSheetImages/error_icon.png diff --git a/Editor/Styles/StyleSheetImages/help.png b/Assets/Editor/Styles/StyleSheetImages/help.png similarity index 100% rename from Editor/Styles/StyleSheetImages/help.png rename to Assets/Editor/Styles/StyleSheetImages/help.png diff --git a/Editor/Styles/StyleSheetImages/info_icon.png b/Assets/Editor/Styles/StyleSheetImages/info_icon.png similarity index 100% rename from Editor/Styles/StyleSheetImages/info_icon.png rename to Assets/Editor/Styles/StyleSheetImages/info_icon.png diff --git a/Editor/Styles/StyleSheetImages/radiobutton_checked.png b/Assets/Editor/Styles/StyleSheetImages/radiobutton_checked.png similarity index 100% rename from Editor/Styles/StyleSheetImages/radiobutton_checked.png rename to Assets/Editor/Styles/StyleSheetImages/radiobutton_checked.png diff --git a/Editor/Styles/StyleSheetImages/radiobutton_checked_disabled.png b/Assets/Editor/Styles/StyleSheetImages/radiobutton_checked_disabled.png similarity index 100% rename from Editor/Styles/StyleSheetImages/radiobutton_checked_disabled.png rename to Assets/Editor/Styles/StyleSheetImages/radiobutton_checked_disabled.png diff --git a/Editor/Styles/StyleSheetImages/radiobutton_unchecked.png b/Assets/Editor/Styles/StyleSheetImages/radiobutton_unchecked.png similarity index 100% rename from Editor/Styles/StyleSheetImages/radiobutton_unchecked.png rename to Assets/Editor/Styles/StyleSheetImages/radiobutton_unchecked.png diff --git a/Editor/Styles/StyleSheetImages/radiobutton_unchecked_disabled.png b/Assets/Editor/Styles/StyleSheetImages/radiobutton_unchecked_disabled.png similarity index 100% rename from Editor/Styles/StyleSheetImages/radiobutton_unchecked_disabled.png rename to Assets/Editor/Styles/StyleSheetImages/radiobutton_unchecked_disabled.png diff --git a/Editor/Styles/StyleSheetImages/spinbox_down.png b/Assets/Editor/Styles/StyleSheetImages/spinbox_down.png similarity index 100% rename from Editor/Styles/StyleSheetImages/spinbox_down.png rename to Assets/Editor/Styles/StyleSheetImages/spinbox_down.png diff --git a/Editor/Styles/StyleSheetImages/spinbox_up.png b/Assets/Editor/Styles/StyleSheetImages/spinbox_up.png similarity index 100% rename from Editor/Styles/StyleSheetImages/spinbox_up.png rename to Assets/Editor/Styles/StyleSheetImages/spinbox_up.png diff --git a/Editor/Styles/StyleSheetImages/treeview_arrow_down.png b/Assets/Editor/Styles/StyleSheetImages/treeview_arrow_down.png similarity index 100% rename from Editor/Styles/StyleSheetImages/treeview_arrow_down.png rename to Assets/Editor/Styles/StyleSheetImages/treeview_arrow_down.png diff --git a/Editor/Styles/StyleSheetImages/treeview_arrow_right.png b/Assets/Editor/Styles/StyleSheetImages/treeview_arrow_right.png similarity index 100% rename from Editor/Styles/StyleSheetImages/treeview_arrow_right.png rename to Assets/Editor/Styles/StyleSheetImages/treeview_arrow_right.png diff --git a/Editor/Styles/stylesheet_Dark.qss b/Assets/Editor/Styles/stylesheet_Dark.qss similarity index 100% rename from Editor/Styles/stylesheet_Dark.qss rename to Assets/Editor/Styles/stylesheet_Dark.qss diff --git a/Editor/Styles/stylesheet_Light.qss b/Assets/Editor/Styles/stylesheet_Light.qss similarity index 100% rename from Editor/Styles/stylesheet_Light.qss rename to Assets/Editor/Styles/stylesheet_Light.qss diff --git a/Editor/ToolBox.xml b/Assets/Editor/ToolBox.xml similarity index 100% rename from Editor/ToolBox.xml rename to Assets/Editor/ToolBox.xml diff --git a/Editor/Translation/scriptcanvas_en_us.ts b/Assets/Editor/Translation/scriptcanvas_en_us.ts similarity index 100% rename from Editor/Translation/scriptcanvas_en_us.ts rename to Assets/Editor/Translation/scriptcanvas_en_us.ts diff --git a/Editor/UI/AssetBrowserRibbon.xml b/Assets/Editor/UI/AssetBrowserRibbon.xml similarity index 100% rename from Editor/UI/AssetBrowserRibbon.xml rename to Assets/Editor/UI/AssetBrowserRibbon.xml diff --git a/Editor/UI/Icons/AddSel.png b/Assets/Editor/UI/Icons/AddSel.png similarity index 100% rename from Editor/UI/Icons/AddSel.png rename to Assets/Editor/UI/Icons/AddSel.png diff --git a/Editor/UI/Icons/AlObjGrid.png b/Assets/Editor/UI/Icons/AlObjGrid.png similarity index 100% rename from Editor/UI/Icons/AlObjGrid.png rename to Assets/Editor/UI/Icons/AlObjGrid.png diff --git a/Editor/UI/Icons/AlObjSurf.png b/Assets/Editor/UI/Icons/AlObjSurf.png similarity index 100% rename from Editor/UI/Icons/AlObjSurf.png rename to Assets/Editor/UI/Icons/AlObjSurf.png diff --git a/Editor/UI/Icons/AlSelect.png b/Assets/Editor/UI/Icons/AlSelect.png similarity index 100% rename from Editor/UI/Icons/AlSelect.png rename to Assets/Editor/UI/Icons/AlSelect.png diff --git a/Editor/UI/Icons/Animation Graph.png b/Assets/Editor/UI/Icons/Animation Graph.png similarity index 100% rename from Editor/UI/Icons/Animation Graph.png rename to Assets/Editor/UI/Icons/Animation Graph.png diff --git a/Editor/UI/Icons/Asset Browser.png b/Assets/Editor/UI/Icons/Asset Browser.png similarity index 100% rename from Editor/UI/Icons/Asset Browser.png rename to Assets/Editor/UI/Icons/Asset Browser.png diff --git a/Editor/UI/Icons/AssetBrowserCheckers.png b/Assets/Editor/UI/Icons/AssetBrowserCheckers.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserCheckers.png rename to Assets/Editor/UI/Icons/AssetBrowserCheckers.png diff --git a/Editor/UI/Icons/AssetBrowserFilterPresets.png b/Assets/Editor/UI/Icons/AssetBrowserFilterPresets.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserFilterPresets.png rename to Assets/Editor/UI/Icons/AssetBrowserFilterPresets.png diff --git a/Editor/UI/Icons/AssetBrowserFromViewportSel.png b/Assets/Editor/UI/Icons/AssetBrowserFromViewportSel.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserFromViewportSel.png rename to Assets/Editor/UI/Icons/AssetBrowserFromViewportSel.png diff --git a/Editor/UI/Icons/AssetBrowserRefresh.png b/Assets/Editor/UI/Icons/AssetBrowserRefresh.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserRefresh.png rename to Assets/Editor/UI/Icons/AssetBrowserRefresh.png diff --git a/Editor/UI/Icons/AssetBrowserSelectInViewport.png b/Assets/Editor/UI/Icons/AssetBrowserSelectInViewport.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserSelectInViewport.png rename to Assets/Editor/UI/Icons/AssetBrowserSelectInViewport.png diff --git a/Editor/UI/Icons/AssetBrowserSound.png b/Assets/Editor/UI/Icons/AssetBrowserSound.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserSound.png rename to Assets/Editor/UI/Icons/AssetBrowserSound.png diff --git a/Editor/UI/Icons/AssetBrowserThumbInvalid.png b/Assets/Editor/UI/Icons/AssetBrowserThumbInvalid.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserThumbInvalid.png rename to Assets/Editor/UI/Icons/AssetBrowserThumbInvalid.png diff --git a/Editor/UI/Icons/AssetBrowserThumbLoading.png b/Assets/Editor/UI/Icons/AssetBrowserThumbLoading.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserThumbLoading.png rename to Assets/Editor/UI/Icons/AssetBrowserThumbLoading.png diff --git a/Editor/UI/Icons/AssetBrowserTooltipShadow.png b/Assets/Editor/UI/Icons/AssetBrowserTooltipShadow.png similarity index 100% rename from Editor/UI/Icons/AssetBrowserTooltipShadow.png rename to Assets/Editor/UI/Icons/AssetBrowserTooltipShadow.png diff --git a/Editor/UI/Icons/AssetFav.png b/Assets/Editor/UI/Icons/AssetFav.png similarity index 100% rename from Editor/UI/Icons/AssetFav.png rename to Assets/Editor/UI/Icons/AssetFav.png diff --git a/Editor/UI/Icons/AssetTag.png b/Assets/Editor/UI/Icons/AssetTag.png similarity index 100% rename from Editor/UI/Icons/AssetTag.png rename to Assets/Editor/UI/Icons/AssetTag.png diff --git a/Editor/UI/Icons/Attach.png b/Assets/Editor/UI/Icons/Attach.png similarity index 100% rename from Editor/UI/Icons/Attach.png rename to Assets/Editor/UI/Icons/Attach.png diff --git a/Editor/UI/Icons/AutoSync.png b/Assets/Editor/UI/Icons/AutoSync.png similarity index 100% rename from Editor/UI/Icons/AutoSync.png rename to Assets/Editor/UI/Icons/AutoSync.png diff --git a/Editor/UI/Icons/Character Tool.png b/Assets/Editor/UI/Icons/Character Tool.png similarity index 100% rename from Editor/UI/Icons/Character Tool.png rename to Assets/Editor/UI/Icons/Character Tool.png diff --git a/Editor/UI/Icons/Clone.png b/Assets/Editor/UI/Icons/Clone.png similarity index 100% rename from Editor/UI/Icons/Clone.png rename to Assets/Editor/UI/Icons/Clone.png diff --git a/Editor/UI/Icons/CloseGroup.png b/Assets/Editor/UI/Icons/CloseGroup.png similarity index 100% rename from Editor/UI/Icons/CloseGroup.png rename to Assets/Editor/UI/Icons/CloseGroup.png diff --git a/Editor/UI/Icons/Cloud.png b/Assets/Editor/UI/Icons/Cloud.png similarity index 100% rename from Editor/UI/Icons/Cloud.png rename to Assets/Editor/UI/Icons/Cloud.png diff --git a/Editor/UI/Icons/ConOpt.png b/Assets/Editor/UI/Icons/ConOpt.png similarity index 100% rename from Editor/UI/Icons/ConOpt.png rename to Assets/Editor/UI/Icons/ConOpt.png diff --git a/Editor/UI/Icons/ConvertSelToBrushes.png b/Assets/Editor/UI/Icons/ConvertSelToBrushes.png similarity index 100% rename from Editor/UI/Icons/ConvertSelToBrushes.png rename to Assets/Editor/UI/Icons/ConvertSelToBrushes.png diff --git a/Editor/UI/Icons/ConvertSelToDesigner.png b/Assets/Editor/UI/Icons/ConvertSelToDesigner.png similarity index 100% rename from Editor/UI/Icons/ConvertSelToDesigner.png rename to Assets/Editor/UI/Icons/ConvertSelToDesigner.png diff --git a/Editor/UI/Icons/ConvertSelToSimpleEntity.png b/Assets/Editor/UI/Icons/ConvertSelToSimpleEntity.png similarity index 100% rename from Editor/UI/Icons/ConvertSelToSimpleEntity.png rename to Assets/Editor/UI/Icons/ConvertSelToSimpleEntity.png diff --git a/Editor/UI/Icons/ConvertSelToStaticEntity.png b/Assets/Editor/UI/Icons/ConvertSelToStaticEntity.png similarity index 100% rename from Editor/UI/Icons/ConvertSelToStaticEntity.png rename to Assets/Editor/UI/Icons/ConvertSelToStaticEntity.png diff --git a/Editor/UI/Icons/Database View.png b/Assets/Editor/UI/Icons/Database View.png similarity index 100% rename from Editor/UI/Icons/Database View.png rename to Assets/Editor/UI/Icons/Database View.png diff --git a/Editor/UI/Icons/DelSel.png b/Assets/Editor/UI/Icons/DelSel.png similarity index 100% rename from Editor/UI/Icons/DelSel.png rename to Assets/Editor/UI/Icons/DelSel.png diff --git a/Editor/UI/Icons/Delete.png b/Assets/Editor/UI/Icons/Delete.png similarity index 100% rename from Editor/UI/Icons/Delete.png rename to Assets/Editor/UI/Icons/Delete.png diff --git a/Editor/UI/Icons/Detach.png b/Assets/Editor/UI/Icons/Detach.png similarity index 100% rename from Editor/UI/Icons/Detach.png rename to Assets/Editor/UI/Icons/Detach.png diff --git a/Editor/UI/Icons/Dialog Editor.png b/Assets/Editor/UI/Icons/Dialog Editor.png similarity index 100% rename from Editor/UI/Icons/Dialog Editor.png rename to Assets/Editor/UI/Icons/Dialog Editor.png diff --git a/Editor/UI/Icons/Edit Terrain Lighting.png b/Assets/Editor/UI/Icons/Edit Terrain Lighting.png similarity index 100% rename from Editor/UI/Icons/Edit Terrain Lighting.png rename to Assets/Editor/UI/Icons/Edit Terrain Lighting.png diff --git a/Editor/UI/Icons/Edit Vegetation.png b/Assets/Editor/UI/Icons/Edit Vegetation.png similarity index 100% rename from Editor/UI/Icons/Edit Vegetation.png rename to Assets/Editor/UI/Icons/Edit Vegetation.png diff --git a/Editor/UI/Icons/Editor Settings Manager.png b/Assets/Editor/UI/Icons/Editor Settings Manager.png similarity index 100% rename from Editor/UI/Icons/Editor Settings Manager.png rename to Assets/Editor/UI/Icons/Editor Settings Manager.png diff --git a/Editor/UI/Icons/Error Report.png b/Assets/Editor/UI/Icons/Error Report.png similarity index 100% rename from Editor/UI/Icons/Error Report.png rename to Assets/Editor/UI/Icons/Error Report.png diff --git a/Editor/UI/Icons/Export Block.png b/Assets/Editor/UI/Icons/Export Block.png similarity index 100% rename from Editor/UI/Icons/Export Block.png rename to Assets/Editor/UI/Icons/Export Block.png diff --git a/Editor/UI/Icons/Facial Editor.png b/Assets/Editor/UI/Icons/Facial Editor.png similarity index 100% rename from Editor/UI/Icons/Facial Editor.png rename to Assets/Editor/UI/Icons/Facial Editor.png diff --git a/Editor/UI/Icons/Fetch.png b/Assets/Editor/UI/Icons/Fetch.png similarity index 100% rename from Editor/UI/Icons/Fetch.png rename to Assets/Editor/UI/Icons/Fetch.png diff --git a/Editor/UI/Icons/Flatten Terrain.png b/Assets/Editor/UI/Icons/Flatten Terrain.png similarity index 100% rename from Editor/UI/Icons/Flatten Terrain.png rename to Assets/Editor/UI/Icons/Flatten Terrain.png diff --git a/Editor/UI/Icons/Follow.png b/Assets/Editor/UI/Icons/Follow.png similarity index 100% rename from Editor/UI/Icons/Follow.png rename to Assets/Editor/UI/Icons/Follow.png diff --git a/Editor/UI/Icons/FollowSnap.png b/Assets/Editor/UI/Icons/FollowSnap.png similarity index 100% rename from Editor/UI/Icons/FollowSnap.png rename to Assets/Editor/UI/Icons/FollowSnap.png diff --git a/Editor/UI/Icons/ForceSyncLevelToConsole.png b/Assets/Editor/UI/Icons/ForceSyncLevelToConsole.png similarity index 100% rename from Editor/UI/Icons/ForceSyncLevelToConsole.png rename to Assets/Editor/UI/Icons/ForceSyncLevelToConsole.png diff --git a/Editor/UI/Icons/Freeze.png b/Assets/Editor/UI/Icons/Freeze.png similarity index 100% rename from Editor/UI/Icons/Freeze.png rename to Assets/Editor/UI/Icons/Freeze.png diff --git a/Editor/UI/Icons/Front.png b/Assets/Editor/UI/Icons/Front.png similarity index 100% rename from Editor/UI/Icons/Front.png rename to Assets/Editor/UI/Icons/Front.png diff --git a/Editor/UI/Icons/GetPhysics.png b/Assets/Editor/UI/Icons/GetPhysics.png similarity index 100% rename from Editor/UI/Icons/GetPhysics.png rename to Assets/Editor/UI/Icons/GetPhysics.png diff --git a/Editor/UI/Icons/GoToObj.png b/Assets/Editor/UI/Icons/GoToObj.png similarity index 100% rename from Editor/UI/Icons/GoToObj.png rename to Assets/Editor/UI/Icons/GoToObj.png diff --git a/Editor/UI/Icons/GotoTagPoint.png b/Assets/Editor/UI/Icons/GotoTagPoint.png similarity index 100% rename from Editor/UI/Icons/GotoTagPoint.png rename to Assets/Editor/UI/Icons/GotoTagPoint.png diff --git a/Editor/UI/Icons/Group.png b/Assets/Editor/UI/Icons/Group.png similarity index 100% rename from Editor/UI/Icons/Group.png rename to Assets/Editor/UI/Icons/Group.png diff --git a/Editor/UI/Icons/Hide.png b/Assets/Editor/UI/Icons/Hide.png similarity index 100% rename from Editor/UI/Icons/Hide.png rename to Assets/Editor/UI/Icons/Hide.png diff --git a/Editor/UI/Icons/Hold.png b/Assets/Editor/UI/Icons/Hold.png similarity index 100% rename from Editor/UI/Icons/Hold.png rename to Assets/Editor/UI/Icons/Hold.png diff --git a/Editor/UI/Icons/Import Block.png b/Assets/Editor/UI/Icons/Import Block.png similarity index 100% rename from Editor/UI/Icons/Import Block.png rename to Assets/Editor/UI/Icons/Import Block.png diff --git a/Editor/UI/Icons/ImportExport Terrain Texture.png b/Assets/Editor/UI/Icons/ImportExport Terrain Texture.png similarity index 100% rename from Editor/UI/Icons/ImportExport Terrain Texture.png rename to Assets/Editor/UI/Icons/ImportExport Terrain Texture.png diff --git a/Editor/UI/Icons/Invert.png b/Assets/Editor/UI/Icons/Invert.png similarity index 100% rename from Editor/UI/Icons/Invert.png rename to Assets/Editor/UI/Icons/Invert.png diff --git a/Editor/UI/Icons/LNM Editor.png b/Assets/Editor/UI/Icons/LNM Editor.png similarity index 100% rename from Editor/UI/Icons/LNM Editor.png rename to Assets/Editor/UI/Icons/LNM Editor.png diff --git a/Editor/UI/Icons/LaunchLevel.png b/Assets/Editor/UI/Icons/LaunchLevel.png similarity index 100% rename from Editor/UI/Icons/LaunchLevel.png rename to Assets/Editor/UI/Icons/LaunchLevel.png diff --git a/Editor/UI/Icons/Layer Editor.png b/Assets/Editor/UI/Icons/Layer Editor.png similarity index 100% rename from Editor/UI/Icons/Layer Editor.png rename to Assets/Editor/UI/Icons/Layer Editor.png diff --git a/Editor/UI/Icons/Layer.png b/Assets/Editor/UI/Icons/Layer.png similarity index 100% rename from Editor/UI/Icons/Layer.png rename to Assets/Editor/UI/Icons/Layer.png diff --git a/Editor/UI/Icons/Left.png b/Assets/Editor/UI/Icons/Left.png similarity index 100% rename from Editor/UI/Icons/Left.png rename to Assets/Editor/UI/Icons/Left.png diff --git a/Editor/UI/Icons/Lighting Tool.png b/Assets/Editor/UI/Icons/Lighting Tool.png similarity index 100% rename from Editor/UI/Icons/Lighting Tool.png rename to Assets/Editor/UI/Icons/Lighting Tool.png diff --git a/Editor/UI/Icons/Link.png b/Assets/Editor/UI/Icons/Link.png similarity index 100% rename from Editor/UI/Icons/Link.png rename to Assets/Editor/UI/Icons/Link.png diff --git a/Editor/UI/Icons/LoadGameLevel.png b/Assets/Editor/UI/Icons/LoadGameLevel.png similarity index 100% rename from Editor/UI/Icons/LoadGameLevel.png rename to Assets/Editor/UI/Icons/LoadGameLevel.png diff --git a/Editor/UI/Icons/LoadGameLevel_16x16.png b/Assets/Editor/UI/Icons/LoadGameLevel_16x16.png similarity index 100% rename from Editor/UI/Icons/LoadGameLevel_16x16.png rename to Assets/Editor/UI/Icons/LoadGameLevel_16x16.png diff --git a/Editor/UI/Icons/LoadLevel.png b/Assets/Editor/UI/Icons/LoadLevel.png similarity index 100% rename from Editor/UI/Icons/LoadLevel.png rename to Assets/Editor/UI/Icons/LoadLevel.png diff --git a/Editor/UI/Icons/LoadSelObj.png b/Assets/Editor/UI/Icons/LoadSelObj.png similarity index 100% rename from Editor/UI/Icons/LoadSelObj.png rename to Assets/Editor/UI/Icons/LoadSelObj.png diff --git a/Editor/UI/Icons/LoadSelObj_16x16.png b/Assets/Editor/UI/Icons/LoadSelObj_16x16.png similarity index 100% rename from Editor/UI/Icons/LoadSelObj_16x16.png rename to Assets/Editor/UI/Icons/LoadSelObj_16x16.png diff --git a/Editor/UI/Icons/MakePref.png b/Assets/Editor/UI/Icons/MakePref.png similarity index 100% rename from Editor/UI/Icons/MakePref.png rename to Assets/Editor/UI/Icons/MakePref.png diff --git a/Editor/UI/Icons/Mannequin Editor.png b/Assets/Editor/UI/Icons/Mannequin Editor.png similarity index 100% rename from Editor/UI/Icons/Mannequin Editor.png rename to Assets/Editor/UI/Icons/Mannequin Editor.png diff --git a/Editor/UI/Icons/Mannequin.png b/Assets/Editor/UI/Icons/Mannequin.png similarity index 100% rename from Editor/UI/Icons/Mannequin.png rename to Assets/Editor/UI/Icons/Mannequin.png diff --git a/Editor/UI/Icons/Map.png b/Assets/Editor/UI/Icons/Map.png similarity index 100% rename from Editor/UI/Icons/Map.png rename to Assets/Editor/UI/Icons/Map.png diff --git a/Editor/UI/Icons/Material Editor.png b/Assets/Editor/UI/Icons/Material Editor.png similarity index 100% rename from Editor/UI/Icons/Material Editor.png rename to Assets/Editor/UI/Icons/Material Editor.png diff --git a/Editor/UI/Icons/Material_Editor_16x16.png b/Assets/Editor/UI/Icons/Material_Editor_16x16.png similarity index 100% rename from Editor/UI/Icons/Material_Editor_16x16.png rename to Assets/Editor/UI/Icons/Material_Editor_16x16.png diff --git a/Editor/UI/Icons/Measurement System Tool.png b/Assets/Editor/UI/Icons/Measurement System Tool.png similarity index 100% rename from Editor/UI/Icons/Measurement System Tool.png rename to Assets/Editor/UI/Icons/Measurement System Tool.png diff --git a/Editor/UI/Icons/Missing Asset Resolver.png b/Assets/Editor/UI/Icons/Missing Asset Resolver.png similarity index 100% rename from Editor/UI/Icons/Missing Asset Resolver.png rename to Assets/Editor/UI/Icons/Missing Asset Resolver.png diff --git a/Editor/UI/Icons/Model Preview.png b/Assets/Editor/UI/Icons/Model Preview.png similarity index 100% rename from Editor/UI/Icons/Model Preview.png rename to Assets/Editor/UI/Icons/Model Preview.png diff --git a/Editor/UI/Icons/Modular Editor.png b/Assets/Editor/UI/Icons/Modular Editor.png similarity index 100% rename from Editor/UI/Icons/Modular Editor.png rename to Assets/Editor/UI/Icons/Modular Editor.png diff --git a/Editor/UI/Icons/Move.png b/Assets/Editor/UI/Icons/Move.png similarity index 100% rename from Editor/UI/Icons/Move.png rename to Assets/Editor/UI/Icons/Move.png diff --git a/Editor/UI/Icons/NavContinuousUpdate.png b/Assets/Editor/UI/Icons/NavContinuousUpdate.png similarity index 100% rename from Editor/UI/Icons/NavContinuousUpdate.png rename to Assets/Editor/UI/Icons/NavContinuousUpdate.png diff --git a/Editor/UI/Icons/NavContinuousUpdate2.png b/Assets/Editor/UI/Icons/NavContinuousUpdate2.png similarity index 100% rename from Editor/UI/Icons/NavContinuousUpdate2.png rename to Assets/Editor/UI/Icons/NavContinuousUpdate2.png diff --git a/Editor/UI/Icons/NavDebugDisplay.png b/Assets/Editor/UI/Icons/NavDebugDisplay.png similarity index 100% rename from Editor/UI/Icons/NavDebugDisplay.png rename to Assets/Editor/UI/Icons/NavDebugDisplay.png diff --git a/Editor/UI/Icons/NavNewArea.png b/Assets/Editor/UI/Icons/NavNewArea.png similarity index 100% rename from Editor/UI/Icons/NavNewArea.png rename to Assets/Editor/UI/Icons/NavNewArea.png diff --git a/Editor/UI/Icons/NavNewSeed.png b/Assets/Editor/UI/Icons/NavNewSeed.png similarity index 100% rename from Editor/UI/Icons/NavNewSeed.png rename to Assets/Editor/UI/Icons/NavNewSeed.png diff --git a/Editor/UI/Icons/NavShowAreas.png b/Assets/Editor/UI/Icons/NavShowAreas.png similarity index 100% rename from Editor/UI/Icons/NavShowAreas.png rename to Assets/Editor/UI/Icons/NavShowAreas.png diff --git a/Editor/UI/Icons/NavShowAreas2.png b/Assets/Editor/UI/Icons/NavShowAreas2.png similarity index 100% rename from Editor/UI/Icons/NavShowAreas2.png rename to Assets/Editor/UI/Icons/NavShowAreas2.png diff --git a/Editor/UI/Icons/OpenGroup.png b/Assets/Editor/UI/Icons/OpenGroup.png similarity index 100% rename from Editor/UI/Icons/OpenGroup.png rename to Assets/Editor/UI/Icons/OpenGroup.png diff --git a/Editor/UI/Icons/Perspective.png b/Assets/Editor/UI/Icons/Perspective.png similarity index 100% rename from Editor/UI/Icons/Perspective.png rename to Assets/Editor/UI/Icons/Perspective.png diff --git a/Editor/UI/Icons/QCollapsePanel/collapsed.png b/Assets/Editor/UI/Icons/QCollapsePanel/collapsed.png similarity index 100% rename from Editor/UI/Icons/QCollapsePanel/collapsed.png rename to Assets/Editor/UI/Icons/QCollapsePanel/collapsed.png diff --git a/Editor/UI/Icons/QCollapsePanel/open.png b/Assets/Editor/UI/Icons/QCollapsePanel/open.png similarity index 100% rename from Editor/UI/Icons/QCollapsePanel/open.png rename to Assets/Editor/UI/Icons/QCollapsePanel/open.png diff --git a/Editor/UI/Icons/QEditorCollapseGroup/arrow_down_V2.png b/Assets/Editor/UI/Icons/QEditorCollapseGroup/arrow_down_V2.png similarity index 100% rename from Editor/UI/Icons/QEditorCollapseGroup/arrow_down_V2.png rename to Assets/Editor/UI/Icons/QEditorCollapseGroup/arrow_down_V2.png diff --git a/Editor/UI/Icons/QEditorCollapseGroup/arrow_right_V2.png b/Assets/Editor/UI/Icons/QEditorCollapseGroup/arrow_right_V2.png similarity index 100% rename from Editor/UI/Icons/QEditorCollapseGroup/arrow_right_V2.png rename to Assets/Editor/UI/Icons/QEditorCollapseGroup/arrow_right_V2.png diff --git a/Editor/UI/Icons/Redo.png b/Assets/Editor/UI/Icons/Redo.png similarity index 100% rename from Editor/UI/Icons/Redo.png rename to Assets/Editor/UI/Icons/Redo.png diff --git a/Editor/UI/Icons/RefCoord.png b/Assets/Editor/UI/Icons/RefCoord.png similarity index 100% rename from Editor/UI/Icons/RefCoord.png rename to Assets/Editor/UI/Icons/RefCoord.png diff --git a/Editor/UI/Icons/Reload Terrain-.png b/Assets/Editor/UI/Icons/Reload Terrain-.png similarity index 100% rename from Editor/UI/Icons/Reload Terrain-.png rename to Assets/Editor/UI/Icons/Reload Terrain-.png diff --git a/Editor/UI/Icons/Reload Terrain.png b/Assets/Editor/UI/Icons/Reload Terrain.png similarity index 100% rename from Editor/UI/Icons/Reload Terrain.png rename to Assets/Editor/UI/Icons/Reload Terrain.png diff --git a/Editor/UI/Icons/ReloadAll.png b/Assets/Editor/UI/Icons/ReloadAll.png similarity index 100% rename from Editor/UI/Icons/ReloadAll.png rename to Assets/Editor/UI/Icons/ReloadAll.png diff --git a/Editor/UI/Icons/Rename.png b/Assets/Editor/UI/Icons/Rename.png similarity index 100% rename from Editor/UI/Icons/Rename.png rename to Assets/Editor/UI/Icons/Rename.png diff --git a/Editor/UI/Icons/ResetPhysics.png b/Assets/Editor/UI/Icons/ResetPhysics.png similarity index 100% rename from Editor/UI/Icons/ResetPhysics.png rename to Assets/Editor/UI/Icons/ResetPhysics.png diff --git a/Editor/UI/Icons/Resize Terrain.png b/Assets/Editor/UI/Icons/Resize Terrain.png similarity index 100% rename from Editor/UI/Icons/Resize Terrain.png rename to Assets/Editor/UI/Icons/Resize Terrain.png diff --git a/Editor/UI/Icons/Rotate.png b/Assets/Editor/UI/Icons/Rotate.png similarity index 100% rename from Editor/UI/Icons/Rotate.png rename to Assets/Editor/UI/Icons/Rotate.png diff --git a/Editor/UI/Icons/Ruler.png b/Assets/Editor/UI/Icons/Ruler.png similarity index 100% rename from Editor/UI/Icons/Ruler.png rename to Assets/Editor/UI/Icons/Ruler.png diff --git a/Editor/UI/Icons/Save as Geometry.png b/Assets/Editor/UI/Icons/Save as Geometry.png similarity index 100% rename from Editor/UI/Icons/Save as Geometry.png rename to Assets/Editor/UI/Icons/Save as Geometry.png diff --git a/Editor/UI/Icons/SaveGameLevel.png b/Assets/Editor/UI/Icons/SaveGameLevel.png similarity index 100% rename from Editor/UI/Icons/SaveGameLevel.png rename to Assets/Editor/UI/Icons/SaveGameLevel.png diff --git a/Editor/UI/Icons/SaveSelObj.png b/Assets/Editor/UI/Icons/SaveSelObj.png similarity index 100% rename from Editor/UI/Icons/SaveSelObj.png rename to Assets/Editor/UI/Icons/SaveSelObj.png diff --git a/Editor/UI/Icons/SaveTagPoint.png b/Assets/Editor/UI/Icons/SaveTagPoint.png similarity index 100% rename from Editor/UI/Icons/SaveTagPoint.png rename to Assets/Editor/UI/Icons/SaveTagPoint.png diff --git a/Editor/UI/Icons/Scale.png b/Assets/Editor/UI/Icons/Scale.png similarity index 100% rename from Editor/UI/Icons/Scale.png rename to Assets/Editor/UI/Icons/Scale.png diff --git a/Editor/UI/Icons/SelObjType.png b/Assets/Editor/UI/Icons/SelObjType.png similarity index 100% rename from Editor/UI/Icons/SelObjType.png rename to Assets/Editor/UI/Icons/SelObjType.png diff --git a/Editor/UI/Icons/Select Objects.png b/Assets/Editor/UI/Icons/Select Objects.png similarity index 100% rename from Editor/UI/Icons/Select Objects.png rename to Assets/Editor/UI/Icons/Select Objects.png diff --git a/Editor/UI/Icons/Select.png b/Assets/Editor/UI/Icons/Select.png similarity index 100% rename from Editor/UI/Icons/Select.png rename to Assets/Editor/UI/Icons/Select.png diff --git a/Editor/UI/Icons/SelectAll.png b/Assets/Editor/UI/Icons/SelectAll.png similarity index 100% rename from Editor/UI/Icons/SelectAll.png rename to Assets/Editor/UI/Icons/SelectAll.png diff --git a/Editor/UI/Icons/SelectNone.png b/Assets/Editor/UI/Icons/SelectNone.png similarity index 100% rename from Editor/UI/Icons/SelectNone.png rename to Assets/Editor/UI/Icons/SelectNone.png diff --git a/Editor/UI/Icons/SelectObjects.png b/Assets/Editor/UI/Icons/SelectObjects.png similarity index 100% rename from Editor/UI/Icons/SelectObjects.png rename to Assets/Editor/UI/Icons/SelectObjects.png diff --git a/Editor/UI/Icons/SelectTerrainArea.png b/Assets/Editor/UI/Icons/SelectTerrainArea.png similarity index 100% rename from Editor/UI/Icons/SelectTerrainArea.png rename to Assets/Editor/UI/Icons/SelectTerrainArea.png diff --git a/Editor/UI/Icons/SelectionMask.bmp b/Assets/Editor/UI/Icons/SelectionMask.bmp similarity index 100% rename from Editor/UI/Icons/SelectionMask.bmp rename to Assets/Editor/UI/Icons/SelectionMask.bmp diff --git a/Editor/UI/Icons/SetHeight.png b/Assets/Editor/UI/Icons/SetHeight.png similarity index 100% rename from Editor/UI/Icons/SetHeight.png rename to Assets/Editor/UI/Icons/SetHeight.png diff --git a/Editor/UI/Icons/ShowRollup.png b/Assets/Editor/UI/Icons/ShowRollup.png similarity index 100% rename from Editor/UI/Icons/ShowRollup.png rename to Assets/Editor/UI/Icons/ShowRollup.png diff --git a/Editor/UI/Icons/SimObj.png b/Assets/Editor/UI/Icons/SimObj.png similarity index 100% rename from Editor/UI/Icons/SimObj.png rename to Assets/Editor/UI/Icons/SimObj.png diff --git a/Editor/UI/Icons/Smart Objects Editor.png b/Assets/Editor/UI/Icons/Smart Objects Editor.png similarity index 100% rename from Editor/UI/Icons/Smart Objects Editor.png rename to Assets/Editor/UI/Icons/Smart Objects Editor.png diff --git a/Editor/UI/Icons/Smooth Terrain.png b/Assets/Editor/UI/Icons/Smooth Terrain.png similarity index 100% rename from Editor/UI/Icons/Smooth Terrain.png rename to Assets/Editor/UI/Icons/Smooth Terrain.png diff --git a/Editor/UI/Icons/SnapAngle.png b/Assets/Editor/UI/Icons/SnapAngle.png similarity index 100% rename from Editor/UI/Icons/SnapAngle.png rename to Assets/Editor/UI/Icons/SnapAngle.png diff --git a/Editor/UI/Icons/SnapGrid.png b/Assets/Editor/UI/Icons/SnapGrid.png similarity index 100% rename from Editor/UI/Icons/SnapGrid.png rename to Assets/Editor/UI/Icons/SnapGrid.png diff --git a/Editor/UI/Icons/SyncCamera.png b/Assets/Editor/UI/Icons/SyncCamera.png similarity index 100% rename from Editor/UI/Icons/SyncCamera.png rename to Assets/Editor/UI/Icons/SyncCamera.png diff --git a/Editor/UI/Icons/SyncData.png b/Assets/Editor/UI/Icons/SyncData.png similarity index 100% rename from Editor/UI/Icons/SyncData.png rename to Assets/Editor/UI/Icons/SyncData.png diff --git a/Editor/UI/Icons/Terrain Editor.png b/Assets/Editor/UI/Icons/Terrain Editor.png similarity index 100% rename from Editor/UI/Icons/Terrain Editor.png rename to Assets/Editor/UI/Icons/Terrain Editor.png diff --git a/Editor/UI/Icons/Terrain Texture Layers.png b/Assets/Editor/UI/Icons/Terrain Texture Layers.png similarity index 100% rename from Editor/UI/Icons/Terrain Texture Layers.png rename to Assets/Editor/UI/Icons/Terrain Texture Layers.png diff --git a/Editor/UI/Icons/Time of Day.png b/Assets/Editor/UI/Icons/Time of Day.png similarity index 100% rename from Editor/UI/Icons/Time of Day.png rename to Assets/Editor/UI/Icons/Time of Day.png diff --git a/Editor/UI/Icons/Top.png b/Assets/Editor/UI/Icons/Top.png similarity index 100% rename from Editor/UI/Icons/Top.png rename to Assets/Editor/UI/Icons/Top.png diff --git a/Editor/UI/Icons/Track View.png b/Assets/Editor/UI/Icons/Track View.png similarity index 100% rename from Editor/UI/Icons/Track View.png rename to Assets/Editor/UI/Icons/Track View.png diff --git a/Editor/UI/Icons/UI Emulator.png b/Assets/Editor/UI/Icons/UI Emulator.png similarity index 100% rename from Editor/UI/Icons/UI Emulator.png rename to Assets/Editor/UI/Icons/UI Emulator.png diff --git a/Editor/UI/Icons/Undo.png b/Assets/Editor/UI/Icons/Undo.png similarity index 100% rename from Editor/UI/Icons/Undo.png rename to Assets/Editor/UI/Icons/Undo.png diff --git a/Editor/UI/Icons/Unfreeze.png b/Assets/Editor/UI/Icons/Unfreeze.png similarity index 100% rename from Editor/UI/Icons/Unfreeze.png rename to Assets/Editor/UI/Icons/Unfreeze.png diff --git a/Editor/UI/Icons/Ungroup.png b/Assets/Editor/UI/Icons/Ungroup.png similarity index 100% rename from Editor/UI/Icons/Ungroup.png rename to Assets/Editor/UI/Icons/Ungroup.png diff --git a/Editor/UI/Icons/UnhideAll.png b/Assets/Editor/UI/Icons/UnhideAll.png similarity index 100% rename from Editor/UI/Icons/UnhideAll.png rename to Assets/Editor/UI/Icons/UnhideAll.png diff --git a/Editor/UI/Icons/UnhideAll_32.png b/Assets/Editor/UI/Icons/UnhideAll_32.png similarity index 100% rename from Editor/UI/Icons/UnhideAll_32.png rename to Assets/Editor/UI/Icons/UnhideAll_32.png diff --git a/Editor/UI/Icons/Unlink.png b/Assets/Editor/UI/Icons/Unlink.png similarity index 100% rename from Editor/UI/Icons/Unlink.png rename to Assets/Editor/UI/Icons/Unlink.png diff --git a/Editor/UI/Icons/UploadFilesToConsole.png b/Assets/Editor/UI/Icons/UploadFilesToConsole.png similarity index 100% rename from Editor/UI/Icons/UploadFilesToConsole.png rename to Assets/Editor/UI/Icons/UploadFilesToConsole.png diff --git a/Editor/UI/Icons/Vehicle Editor.png b/Assets/Editor/UI/Icons/Vehicle Editor.png similarity index 100% rename from Editor/UI/Icons/Vehicle Editor.png rename to Assets/Editor/UI/Icons/Vehicle Editor.png diff --git a/Editor/UI/Icons/VertexSnapping.png b/Assets/Editor/UI/Icons/VertexSnapping.png similarity index 100% rename from Editor/UI/Icons/VertexSnapping.png rename to Assets/Editor/UI/Icons/VertexSnapping.png diff --git a/Editor/UI/Icons/Visual Log Viewer.png b/Assets/Editor/UI/Icons/Visual Log Viewer.png similarity index 100% rename from Editor/UI/Icons/Visual Log Viewer.png rename to Assets/Editor/UI/Icons/Visual Log Viewer.png diff --git a/Editor/UI/Icons/VisualBudgetSystemAnalyzeOne.png b/Assets/Editor/UI/Icons/VisualBudgetSystemAnalyzeOne.png similarity index 100% rename from Editor/UI/Icons/VisualBudgetSystemAnalyzeOne.png rename to Assets/Editor/UI/Icons/VisualBudgetSystemAnalyzeOne.png diff --git a/Editor/UI/Icons/VisualBudgetSystemShow.png b/Assets/Editor/UI/Icons/VisualBudgetSystemShow.png similarity index 100% rename from Editor/UI/Icons/VisualBudgetSystemShow.png rename to Assets/Editor/UI/Icons/VisualBudgetSystemShow.png diff --git a/Editor/UI/Icons/VisualizeNavigationAccessibility.png b/Assets/Editor/UI/Icons/VisualizeNavigationAccessibility.png similarity index 100% rename from Editor/UI/Icons/VisualizeNavigationAccessibility.png rename to Assets/Editor/UI/Icons/VisualizeNavigationAccessibility.png diff --git a/Editor/UI/Icons/XAxis.png b/Assets/Editor/UI/Icons/XAxis.png similarity index 100% rename from Editor/UI/Icons/XAxis.png rename to Assets/Editor/UI/Icons/XAxis.png diff --git a/Editor/UI/Icons/XYAxis.png b/Assets/Editor/UI/Icons/XYAxis.png similarity index 100% rename from Editor/UI/Icons/XYAxis.png rename to Assets/Editor/UI/Icons/XYAxis.png diff --git a/Editor/UI/Icons/YAxis.png b/Assets/Editor/UI/Icons/YAxis.png similarity index 100% rename from Editor/UI/Icons/YAxis.png rename to Assets/Editor/UI/Icons/YAxis.png diff --git a/Editor/UI/Icons/Z View.png b/Assets/Editor/UI/Icons/Z View.png similarity index 100% rename from Editor/UI/Icons/Z View.png rename to Assets/Editor/UI/Icons/Z View.png diff --git a/Editor/UI/Icons/ZAxis.png b/Assets/Editor/UI/Icons/ZAxis.png similarity index 100% rename from Editor/UI/Icons/ZAxis.png rename to Assets/Editor/UI/Icons/ZAxis.png diff --git a/Editor/UI/Icons/asset_animated_geom.png b/Assets/Editor/UI/Icons/asset_animated_geom.png similarity index 100% rename from Editor/UI/Icons/asset_animated_geom.png rename to Assets/Editor/UI/Icons/asset_animated_geom.png diff --git a/Editor/UI/Icons/asset_character.png b/Assets/Editor/UI/Icons/asset_character.png similarity index 100% rename from Editor/UI/Icons/asset_character.png rename to Assets/Editor/UI/Icons/asset_character.png diff --git a/Editor/UI/Icons/asset_material.png b/Assets/Editor/UI/Icons/asset_material.png similarity index 100% rename from Editor/UI/Icons/asset_material.png rename to Assets/Editor/UI/Icons/asset_material.png diff --git a/Editor/UI/Icons/asset_missing_thumb.png b/Assets/Editor/UI/Icons/asset_missing_thumb.png similarity index 100% rename from Editor/UI/Icons/asset_missing_thumb.png rename to Assets/Editor/UI/Icons/asset_missing_thumb.png diff --git a/Editor/UI/Icons/asset_model.png b/Assets/Editor/UI/Icons/asset_model.png similarity index 100% rename from Editor/UI/Icons/asset_model.png rename to Assets/Editor/UI/Icons/asset_model.png diff --git a/Editor/UI/Icons/asset_sound.png b/Assets/Editor/UI/Icons/asset_sound.png similarity index 100% rename from Editor/UI/Icons/asset_sound.png rename to Assets/Editor/UI/Icons/asset_sound.png diff --git a/Editor/UI/Icons/asset_texture.png b/Assets/Editor/UI/Icons/asset_texture.png similarity index 100% rename from Editor/UI/Icons/asset_texture.png rename to Assets/Editor/UI/Icons/asset_texture.png diff --git a/Editor/UI/Icons/mann_clip.png b/Assets/Editor/UI/Icons/mann_clip.png similarity index 100% rename from Editor/UI/Icons/mann_clip.png rename to Assets/Editor/UI/Icons/mann_clip.png diff --git a/Editor/UI/Icons/mann_folder.png b/Assets/Editor/UI/Icons/mann_folder.png similarity index 100% rename from Editor/UI/Icons/mann_folder.png rename to Assets/Editor/UI/Icons/mann_folder.png diff --git a/Editor/UI/Icons/mann_tag.png b/Assets/Editor/UI/Icons/mann_tag.png similarity index 100% rename from Editor/UI/Icons/mann_tag.png rename to Assets/Editor/UI/Icons/mann_tag.png diff --git a/Editor/UI/Icons/toolbar/Load_Icon.png b/Assets/Editor/UI/Icons/toolbar/Load_Icon.png similarity index 100% rename from Editor/UI/Icons/toolbar/Load_Icon.png rename to Assets/Editor/UI/Icons/toolbar/Load_Icon.png diff --git a/Editor/UI/Icons/toolbar/itemAdd.png b/Assets/Editor/UI/Icons/toolbar/itemAdd.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemAdd.png rename to Assets/Editor/UI/Icons/toolbar/itemAdd.png diff --git a/Editor/UI/Icons/toolbar/itemAssign.png b/Assets/Editor/UI/Icons/toolbar/itemAssign.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemAssign.png rename to Assets/Editor/UI/Icons/toolbar/itemAssign.png diff --git a/Editor/UI/Icons/toolbar/itemClone.png b/Assets/Editor/UI/Icons/toolbar/itemClone.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemClone.png rename to Assets/Editor/UI/Icons/toolbar/itemClone.png diff --git a/Editor/UI/Icons/toolbar/itemGetProperties.png b/Assets/Editor/UI/Icons/toolbar/itemGetProperties.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemGetProperties.png rename to Assets/Editor/UI/Icons/toolbar/itemGetProperties.png diff --git a/Editor/UI/Icons/toolbar/itemReload.png b/Assets/Editor/UI/Icons/toolbar/itemReload.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemReload.png rename to Assets/Editor/UI/Icons/toolbar/itemReload.png diff --git a/Editor/UI/Icons/toolbar/itemRemove.png b/Assets/Editor/UI/Icons/toolbar/itemRemove.png similarity index 100% rename from Editor/UI/Icons/toolbar/itemRemove.png rename to Assets/Editor/UI/Icons/toolbar/itemRemove.png diff --git a/Editor/UI/Icons/toolbar/libraryAdd.png b/Assets/Editor/UI/Icons/toolbar/libraryAdd.png similarity index 100% rename from Editor/UI/Icons/toolbar/libraryAdd.png rename to Assets/Editor/UI/Icons/toolbar/libraryAdd.png diff --git a/Editor/UI/Icons/toolbar/libraryLoad.png b/Assets/Editor/UI/Icons/toolbar/libraryLoad.png similarity index 100% rename from Editor/UI/Icons/toolbar/libraryLoad.png rename to Assets/Editor/UI/Icons/toolbar/libraryLoad.png diff --git a/Editor/UI/Icons/toolbar/libraryReload.png b/Assets/Editor/UI/Icons/toolbar/libraryReload.png similarity index 100% rename from Editor/UI/Icons/toolbar/libraryReload.png rename to Assets/Editor/UI/Icons/toolbar/libraryReload.png diff --git a/Editor/UI/Icons/toolbar/libraryRemove.png b/Assets/Editor/UI/Icons/toolbar/libraryRemove.png similarity index 100% rename from Editor/UI/Icons/toolbar/libraryRemove.png rename to Assets/Editor/UI/Icons/toolbar/libraryRemove.png diff --git a/Editor/UI/Icons/toolbar/librarySave.png b/Assets/Editor/UI/Icons/toolbar/librarySave.png similarity index 100% rename from Editor/UI/Icons/toolbar/librarySave.png rename to Assets/Editor/UI/Icons/toolbar/librarySave.png diff --git a/Editor/UI/Icons/toolbar/particleSpecialActivate.png b/Assets/Editor/UI/Icons/toolbar/particleSpecialActivate.png similarity index 100% rename from Editor/UI/Icons/toolbar/particleSpecialActivate.png rename to Assets/Editor/UI/Icons/toolbar/particleSpecialActivate.png diff --git a/Editor/UI/Icons/toolbar/particleSpecialReset.png b/Assets/Editor/UI/Icons/toolbar/particleSpecialReset.png similarity index 100% rename from Editor/UI/Icons/toolbar/particleSpecialReset.png rename to Assets/Editor/UI/Icons/toolbar/particleSpecialReset.png diff --git a/Editor/UI/Icons/toolbar/standardCopy.png b/Assets/Editor/UI/Icons/toolbar/standardCopy.png similarity index 100% rename from Editor/UI/Icons/toolbar/standardCopy.png rename to Assets/Editor/UI/Icons/toolbar/standardCopy.png diff --git a/Editor/UI/Icons/toolbar/standardPaste.png b/Assets/Editor/UI/Icons/toolbar/standardPaste.png similarity index 100% rename from Editor/UI/Icons/toolbar/standardPaste.png rename to Assets/Editor/UI/Icons/toolbar/standardPaste.png diff --git a/Editor/UI/Icons/toolbar/standardRedo.png b/Assets/Editor/UI/Icons/toolbar/standardRedo.png similarity index 100% rename from Editor/UI/Icons/toolbar/standardRedo.png rename to Assets/Editor/UI/Icons/toolbar/standardRedo.png diff --git a/Editor/UI/Icons/toolbar/standardUndo.png b/Assets/Editor/UI/Icons/toolbar/standardUndo.png similarity index 100% rename from Editor/UI/Icons/toolbar/standardUndo.png rename to Assets/Editor/UI/Icons/toolbar/standardUndo.png diff --git a/Editor/UI/Icons/treeview/ParticleEditor/empty_icon.png b/Assets/Editor/UI/Icons/treeview/ParticleEditor/empty_icon.png similarity index 100% rename from Editor/UI/Icons/treeview/ParticleEditor/empty_icon.png rename to Assets/Editor/UI/Icons/treeview/ParticleEditor/empty_icon.png diff --git a/Editor/UI/Icons/treeview/ParticleEditor/group_icon.png b/Assets/Editor/UI/Icons/treeview/ParticleEditor/group_icon.png similarity index 100% rename from Editor/UI/Icons/treeview/ParticleEditor/group_icon.png rename to Assets/Editor/UI/Icons/treeview/ParticleEditor/group_icon.png diff --git a/Editor/UI/Icons/treeview/ParticleEditor/group_with_lod_icon.png b/Assets/Editor/UI/Icons/treeview/ParticleEditor/group_with_lod_icon.png similarity index 100% rename from Editor/UI/Icons/treeview/ParticleEditor/group_with_lod_icon.png rename to Assets/Editor/UI/Icons/treeview/ParticleEditor/group_with_lod_icon.png diff --git a/Editor/UI/Icons/treeview/ParticleEditor/lod_icon.png b/Assets/Editor/UI/Icons/treeview/ParticleEditor/lod_icon.png similarity index 100% rename from Editor/UI/Icons/treeview/ParticleEditor/lod_icon.png rename to Assets/Editor/UI/Icons/treeview/ParticleEditor/lod_icon.png diff --git a/Editor/UI/Icons/treeview/group.png b/Assets/Editor/UI/Icons/treeview/group.png similarity index 100% rename from Editor/UI/Icons/treeview/group.png rename to Assets/Editor/UI/Icons/treeview/group.png diff --git a/Editor/UI/Icons/treeview/group_inactive.png b/Assets/Editor/UI/Icons/treeview/group_inactive.png similarity index 100% rename from Editor/UI/Icons/treeview/group_inactive.png rename to Assets/Editor/UI/Icons/treeview/group_inactive.png diff --git a/Editor/UI/Icons/treeview/item.png b/Assets/Editor/UI/Icons/treeview/item.png similarity index 100% rename from Editor/UI/Icons/treeview/item.png rename to Assets/Editor/UI/Icons/treeview/item.png diff --git a/Editor/UI/Icons/treeview/item_inactive.png b/Assets/Editor/UI/Icons/treeview/item_inactive.png similarity index 100% rename from Editor/UI/Icons/treeview/item_inactive.png rename to Assets/Editor/UI/Icons/treeview/item_inactive.png diff --git a/Editor/UI/WipFeatures.xml b/Assets/Editor/UI/WipFeatures.xml similarity index 100% rename from Editor/UI/WipFeatures.xml rename to Assets/Editor/UI/WipFeatures.xml diff --git a/Editor/UI/releaseTranslations.py b/Assets/Editor/UI/releaseTranslations.py similarity index 100% rename from Editor/UI/releaseTranslations.py rename to Assets/Editor/UI/releaseTranslations.py diff --git a/Editor/UI/removeTranslationFiles.py b/Assets/Editor/UI/removeTranslationFiles.py similarity index 100% rename from Editor/UI/removeTranslationFiles.py rename to Assets/Editor/UI/removeTranslationFiles.py diff --git a/Editor/UI/updateTranslatableText.py b/Assets/Editor/UI/updateTranslatableText.py similarity index 100% rename from Editor/UI/updateTranslatableText.py rename to Assets/Editor/UI/updateTranslatableText.py diff --git a/Editor/UserTools.xml b/Assets/Editor/UserTools.xml similarity index 100% rename from Editor/UserTools.xml rename to Assets/Editor/UserTools.xml diff --git a/Editor/asset_thumbnail.tod b/Assets/Editor/asset_thumbnail.tod similarity index 100% rename from Editor/asset_thumbnail.tod rename to Assets/Editor/asset_thumbnail.tod diff --git a/Editor/default_time_of_day.xml b/Assets/Editor/default_time_of_day.xml similarity index 100% rename from Editor/default_time_of_day.xml rename to Assets/Editor/default_time_of_day.xml diff --git a/Editor/uiCanvasEditorResolutionPresets.xml b/Assets/Editor/uiCanvasEditorResolutionPresets.xml similarity index 100% rename from Editor/uiCanvasEditorResolutionPresets.xml rename to Assets/Editor/uiCanvasEditorResolutionPresets.xml diff --git a/Engine/Config/AutoTestChain.cfg b/Assets/Engine/Config/AutoTestChain.cfg similarity index 100% rename from Engine/Config/AutoTestChain.cfg rename to Assets/Engine/Config/AutoTestChain.cfg diff --git a/Engine/Config/AutoTestTimeDemo.cfg b/Assets/Engine/Config/AutoTestTimeDemo.cfg similarity index 100% rename from Engine/Config/AutoTestTimeDemo.cfg rename to Assets/Engine/Config/AutoTestTimeDemo.cfg diff --git a/Engine/Config/AutotestPlaythrough.cfg b/Assets/Engine/Config/AutotestPlaythrough.cfg similarity index 100% rename from Engine/Config/AutotestPlaythrough.cfg rename to Assets/Engine/Config/AutotestPlaythrough.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Full.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Full.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Full.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_GameEffects.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_GameEffects.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_ObjectDetail.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Particles.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Particles.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Particles.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Particles.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Physics.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Physics.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Physics.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Physics.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_PostProcessing.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Quality.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Quality.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Quality.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Quality.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Shading.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Shading.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Shading.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Shading.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Shadows.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Shadows.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Shadows.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Shadows.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Sound.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Sound.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Sound.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Sound.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Texture.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Texture.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Texture.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Texture.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_TextureResolution.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_VolumetricEffects.cfg diff --git a/Engine/Config/CVarGroups/sys_spec_Water.cfg b/Assets/Engine/Config/CVarGroups/sys_spec_Water.cfg similarity index 100% rename from Engine/Config/CVarGroups/sys_spec_Water.cfg rename to Assets/Engine/Config/CVarGroups/sys_spec_Water.cfg diff --git a/Engine/Config/HDD_cache.xml b/Assets/Engine/Config/HDD_cache.xml similarity index 100% rename from Engine/Config/HDD_cache.xml rename to Assets/Engine/Config/HDD_cache.xml diff --git a/Engine/Config/PerfHud_PC.xml b/Assets/Engine/Config/PerfHud_PC.xml similarity index 100% rename from Engine/Config/PerfHud_PC.xml rename to Assets/Engine/Config/PerfHud_PC.xml diff --git a/Engine/Config/aidebug.cfg b/Assets/Engine/Config/aidebug.cfg similarity index 100% rename from Engine/Config/aidebug.cfg rename to Assets/Engine/Config/aidebug.cfg diff --git a/Engine/Config/artprof.cfg b/Assets/Engine/Config/artprof.cfg similarity index 100% rename from Engine/Config/artprof.cfg rename to Assets/Engine/Config/artprof.cfg diff --git a/Engine/Config/artprof_user.cfg b/Assets/Engine/Config/artprof_user.cfg similarity index 100% rename from Engine/Config/artprof_user.cfg rename to Assets/Engine/Config/artprof_user.cfg diff --git a/Engine/Config/benchmark_cpu.cfg b/Assets/Engine/Config/benchmark_cpu.cfg similarity index 100% rename from Engine/Config/benchmark_cpu.cfg rename to Assets/Engine/Config/benchmark_cpu.cfg diff --git a/Engine/Config/benchmark_gpu.cfg b/Assets/Engine/Config/benchmark_gpu.cfg similarity index 100% rename from Engine/Config/benchmark_gpu.cfg rename to Assets/Engine/Config/benchmark_gpu.cfg diff --git a/Engine/Config/config.dat b/Assets/Engine/Config/config.dat similarity index 100% rename from Engine/Config/config.dat rename to Assets/Engine/Config/config.dat diff --git a/Engine/Config/engine_core.thread_config b/Assets/Engine/Config/engine_core.thread_config similarity index 100% rename from Engine/Config/engine_core.thread_config rename to Assets/Engine/Config/engine_core.thread_config diff --git a/Engine/Config/engine_sandbox.thread_config b/Assets/Engine/Config/engine_sandbox.thread_config similarity index 100% rename from Engine/Config/engine_sandbox.thread_config rename to Assets/Engine/Config/engine_sandbox.thread_config diff --git a/Engine/Config/gpu/amd.txt b/Assets/Engine/Config/gpu/amd.txt similarity index 100% rename from Engine/Config/gpu/amd.txt rename to Assets/Engine/Config/gpu/amd.txt diff --git a/Engine/Config/gpu/android_gpus.xml b/Assets/Engine/Config/gpu/android_gpus.xml similarity index 100% rename from Engine/Config/gpu/android_gpus.xml rename to Assets/Engine/Config/gpu/android_gpus.xml diff --git a/Engine/Config/gpu/android_models.xml b/Assets/Engine/Config/gpu/android_models.xml similarity index 100% rename from Engine/Config/gpu/android_models.xml rename to Assets/Engine/Config/gpu/android_models.xml diff --git a/Engine/Config/gpu/intel.txt b/Assets/Engine/Config/gpu/intel.txt similarity index 100% rename from Engine/Config/gpu/intel.txt rename to Assets/Engine/Config/gpu/intel.txt diff --git a/Engine/Config/gpu/ios_models.xml b/Assets/Engine/Config/gpu/ios_models.xml similarity index 100% rename from Engine/Config/gpu/ios_models.xml rename to Assets/Engine/Config/gpu/ios_models.xml diff --git a/Engine/Config/gpu/nvidia.txt b/Assets/Engine/Config/gpu/nvidia.txt similarity index 100% rename from Engine/Config/gpu/nvidia.txt rename to Assets/Engine/Config/gpu/nvidia.txt diff --git a/Engine/Config/mgpu.cfg b/Assets/Engine/Config/mgpu.cfg similarity index 100% rename from Engine/Config/mgpu.cfg rename to Assets/Engine/Config/mgpu.cfg diff --git a/Engine/Config/multiplayer.cfg b/Assets/Engine/Config/multiplayer.cfg similarity index 100% rename from Engine/Config/multiplayer.cfg rename to Assets/Engine/Config/multiplayer.cfg diff --git a/Engine/Config/multiplayer_console.cfg b/Assets/Engine/Config/multiplayer_console.cfg similarity index 100% rename from Engine/Config/multiplayer_console.cfg rename to Assets/Engine/Config/multiplayer_console.cfg diff --git a/Engine/Config/multiplayer_pc.cfg b/Assets/Engine/Config/multiplayer_pc.cfg similarity index 100% rename from Engine/Config/multiplayer_pc.cfg rename to Assets/Engine/Config/multiplayer_pc.cfg diff --git a/Engine/Config/performance.cfg b/Assets/Engine/Config/performance.cfg similarity index 100% rename from Engine/Config/performance.cfg rename to Assets/Engine/Config/performance.cfg diff --git a/Engine/Config/recording.cfg b/Assets/Engine/Config/recording.cfg similarity index 100% rename from Engine/Config/recording.cfg rename to Assets/Engine/Config/recording.cfg diff --git a/Engine/Config/singleplayer.cfg b/Assets/Engine/Config/singleplayer.cfg similarity index 100% rename from Engine/Config/singleplayer.cfg rename to Assets/Engine/Config/singleplayer.cfg diff --git a/Engine/Config/sketch_off.cfg b/Assets/Engine/Config/sketch_off.cfg similarity index 100% rename from Engine/Config/sketch_off.cfg rename to Assets/Engine/Config/sketch_off.cfg diff --git a/Engine/Config/sketch_on.cfg b/Assets/Engine/Config/sketch_on.cfg similarity index 100% rename from Engine/Config/sketch_on.cfg rename to Assets/Engine/Config/sketch_on.cfg diff --git a/Engine/Config/spec/android_MaliT760.cfg b/Assets/Engine/Config/spec/android_MaliT760.cfg similarity index 100% rename from Engine/Config/spec/android_MaliT760.cfg rename to Assets/Engine/Config/spec/android_MaliT760.cfg diff --git a/Engine/Config/spec/android_high.cfg b/Assets/Engine/Config/spec/android_high.cfg similarity index 100% rename from Engine/Config/spec/android_high.cfg rename to Assets/Engine/Config/spec/android_high.cfg diff --git a/Engine/Config/spec/android_high_nogmem.cfg b/Assets/Engine/Config/spec/android_high_nogmem.cfg similarity index 100% rename from Engine/Config/spec/android_high_nogmem.cfg rename to Assets/Engine/Config/spec/android_high_nogmem.cfg diff --git a/Engine/Config/spec/android_low.cfg b/Assets/Engine/Config/spec/android_low.cfg similarity index 100% rename from Engine/Config/spec/android_low.cfg rename to Assets/Engine/Config/spec/android_low.cfg diff --git a/Engine/Config/spec/android_medium.cfg b/Assets/Engine/Config/spec/android_medium.cfg similarity index 100% rename from Engine/Config/spec/android_medium.cfg rename to Assets/Engine/Config/spec/android_medium.cfg diff --git a/Engine/Config/spec/android_veryhigh.cfg b/Assets/Engine/Config/spec/android_veryhigh.cfg similarity index 100% rename from Engine/Config/spec/android_veryhigh.cfg rename to Assets/Engine/Config/spec/android_veryhigh.cfg diff --git a/Engine/Config/spec/ios_high.cfg b/Assets/Engine/Config/spec/ios_high.cfg similarity index 100% rename from Engine/Config/spec/ios_high.cfg rename to Assets/Engine/Config/spec/ios_high.cfg diff --git a/Engine/Config/spec/ios_low.cfg b/Assets/Engine/Config/spec/ios_low.cfg similarity index 100% rename from Engine/Config/spec/ios_low.cfg rename to Assets/Engine/Config/spec/ios_low.cfg diff --git a/Engine/Config/spec/ios_medium.cfg b/Assets/Engine/Config/spec/ios_medium.cfg similarity index 100% rename from Engine/Config/spec/ios_medium.cfg rename to Assets/Engine/Config/spec/ios_medium.cfg diff --git a/Engine/Config/spec/ios_veryhigh.cfg b/Assets/Engine/Config/spec/ios_veryhigh.cfg similarity index 100% rename from Engine/Config/spec/ios_veryhigh.cfg rename to Assets/Engine/Config/spec/ios_veryhigh.cfg diff --git a/Engine/Config/spec/osx_metal_high.cfg b/Assets/Engine/Config/spec/osx_metal_high.cfg similarity index 100% rename from Engine/Config/spec/osx_metal_high.cfg rename to Assets/Engine/Config/spec/osx_metal_high.cfg diff --git a/Engine/Config/spec/osx_metal_low.cfg b/Assets/Engine/Config/spec/osx_metal_low.cfg similarity index 100% rename from Engine/Config/spec/osx_metal_low.cfg rename to Assets/Engine/Config/spec/osx_metal_low.cfg diff --git a/Engine/Config/spec/osx_metal_medium.cfg b/Assets/Engine/Config/spec/osx_metal_medium.cfg similarity index 100% rename from Engine/Config/spec/osx_metal_medium.cfg rename to Assets/Engine/Config/spec/osx_metal_medium.cfg diff --git a/Engine/Config/spec/osx_metal_veryhigh.cfg b/Assets/Engine/Config/spec/osx_metal_veryhigh.cfg similarity index 100% rename from Engine/Config/spec/osx_metal_veryhigh.cfg rename to Assets/Engine/Config/spec/osx_metal_veryhigh.cfg diff --git a/Engine/Config/spec/pc_high.cfg b/Assets/Engine/Config/spec/pc_high.cfg similarity index 100% rename from Engine/Config/spec/pc_high.cfg rename to Assets/Engine/Config/spec/pc_high.cfg diff --git a/Engine/Config/spec/pc_low.cfg b/Assets/Engine/Config/spec/pc_low.cfg similarity index 100% rename from Engine/Config/spec/pc_low.cfg rename to Assets/Engine/Config/spec/pc_low.cfg diff --git a/Engine/Config/spec/pc_medium.cfg b/Assets/Engine/Config/spec/pc_medium.cfg similarity index 100% rename from Engine/Config/spec/pc_medium.cfg rename to Assets/Engine/Config/spec/pc_medium.cfg diff --git a/Engine/Config/spec/pc_veryhigh.cfg b/Assets/Engine/Config/spec/pc_veryhigh.cfg similarity index 100% rename from Engine/Config/spec/pc_veryhigh.cfg rename to Assets/Engine/Config/spec/pc_veryhigh.cfg diff --git a/Engine/Config/statoscope.cfg b/Assets/Engine/Config/statoscope.cfg similarity index 100% rename from Engine/Config/statoscope.cfg rename to Assets/Engine/Config/statoscope.cfg diff --git a/Engine/Config/user.cfg b/Assets/Engine/Config/user.cfg similarity index 100% rename from Engine/Config/user.cfg rename to Assets/Engine/Config/user.cfg diff --git a/Engine/Config/vid_capture_reset.cfg b/Assets/Engine/Config/vid_capture_reset.cfg similarity index 100% rename from Engine/Config/vid_capture_reset.cfg rename to Assets/Engine/Config/vid_capture_reset.cfg diff --git a/Engine/Config/vid_capture_setup.cfg b/Assets/Engine/Config/vid_capture_setup.cfg similarity index 100% rename from Engine/Config/vid_capture_setup.cfg rename to Assets/Engine/Config/vid_capture_setup.cfg diff --git a/Engine/Config/vid_capture_start.cfg b/Assets/Engine/Config/vid_capture_start.cfg similarity index 100% rename from Engine/Config/vid_capture_start.cfg rename to Assets/Engine/Config/vid_capture_start.cfg diff --git a/Engine/Config/vid_capture_stop.cfg b/Assets/Engine/Config/vid_capture_stop.cfg similarity index 100% rename from Engine/Config/vid_capture_stop.cfg rename to Assets/Engine/Config/vid_capture_stop.cfg diff --git a/Engine/Config/vr.cfg b/Assets/Engine/Config/vr.cfg similarity index 100% rename from Engine/Config/vr.cfg rename to Assets/Engine/Config/vr.cfg diff --git a/Engine/EngineAssets/Animated/WaterVolume.dds b/Assets/Engine/EngineAssets/Animated/WaterVolume.dds similarity index 100% rename from Engine/EngineAssets/Animated/WaterVolume.dds rename to Assets/Engine/EngineAssets/Animated/WaterVolume.dds diff --git a/Engine/EngineAssets/CodeCoverage/hit.tif b/Assets/Engine/EngineAssets/CodeCoverage/hit.tif similarity index 100% rename from Engine/EngineAssets/CodeCoverage/hit.tif rename to Assets/Engine/EngineAssets/CodeCoverage/hit.tif diff --git a/Engine/EngineAssets/CodeCoverage/hit.tif.exportsettings b/Assets/Engine/EngineAssets/CodeCoverage/hit.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/CodeCoverage/hit.tif.exportsettings rename to Assets/Engine/EngineAssets/CodeCoverage/hit.tif.exportsettings diff --git a/Engine/EngineAssets/CodeCoverage/pbar.tif b/Assets/Engine/EngineAssets/CodeCoverage/pbar.tif similarity index 100% rename from Engine/EngineAssets/CodeCoverage/pbar.tif rename to Assets/Engine/EngineAssets/CodeCoverage/pbar.tif diff --git a/Engine/EngineAssets/CodeCoverage/pbar.tif.exportsettings b/Assets/Engine/EngineAssets/CodeCoverage/pbar.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/CodeCoverage/pbar.tif.exportsettings rename to Assets/Engine/EngineAssets/CodeCoverage/pbar.tif.exportsettings diff --git a/Engine/EngineAssets/CodeCoverage/unexpected.tif b/Assets/Engine/EngineAssets/CodeCoverage/unexpected.tif similarity index 100% rename from Engine/EngineAssets/CodeCoverage/unexpected.tif rename to Assets/Engine/EngineAssets/CodeCoverage/unexpected.tif diff --git a/Engine/EngineAssets/CodeCoverage/unexpected.tif.exportsettings b/Assets/Engine/EngineAssets/CodeCoverage/unexpected.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/CodeCoverage/unexpected.tif.exportsettings rename to Assets/Engine/EngineAssets/CodeCoverage/unexpected.tif.exportsettings diff --git a/Engine/EngineAssets/GeomCaches/defaultGeomCache.abc b/Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.abc similarity index 100% rename from Engine/EngineAssets/GeomCaches/defaultGeomCache.abc rename to Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.abc diff --git a/Engine/EngineAssets/GeomCaches/defaultGeomCache.cbc b/Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.cbc similarity index 100% rename from Engine/EngineAssets/GeomCaches/defaultGeomCache.cbc rename to Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.cbc diff --git a/Engine/EngineAssets/GeomCaches/defaultGeomCache.ma b/Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.ma similarity index 100% rename from Engine/EngineAssets/GeomCaches/defaultGeomCache.ma rename to Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.ma diff --git a/Engine/EngineAssets/GeomCaches/defaultGeomCache.mtl b/Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.mtl similarity index 100% rename from Engine/EngineAssets/GeomCaches/defaultGeomCache.mtl rename to Assets/Engine/EngineAssets/GeomCaches/defaultGeomCache.mtl diff --git a/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF b/Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF similarity index 100% rename from Engine/EngineAssets/Icons/AverageMemoryUsage.TIF rename to Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF diff --git a/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings rename to Assets/Engine/EngineAssets/Icons/AverageMemoryUsage.TIF.exportsettings diff --git a/Engine/EngineAssets/Icons/HighMemoryUsage.TIF b/Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF similarity index 100% rename from Engine/EngineAssets/Icons/HighMemoryUsage.TIF rename to Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF diff --git a/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings rename to Assets/Engine/EngineAssets/Icons/HighMemoryUsage.TIF.exportsettings diff --git a/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif b/Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif similarity index 100% rename from Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif rename to Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif diff --git a/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/LevelShaderCacheMiss.tif.exportsettings diff --git a/Engine/EngineAssets/Icons/LivePreview.TIF b/Assets/Engine/EngineAssets/Icons/LivePreview.TIF similarity index 100% rename from Engine/EngineAssets/Icons/LivePreview.TIF rename to Assets/Engine/EngineAssets/Icons/LivePreview.TIF diff --git a/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings rename to Assets/Engine/EngineAssets/Icons/LivePreview.TIF.exportsettings diff --git a/Engine/EngineAssets/Icons/LowMemoryUsage.TIF b/Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF similarity index 100% rename from Engine/EngineAssets/Icons/LowMemoryUsage.TIF rename to Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF diff --git a/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings b/Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings rename to Assets/Engine/EngineAssets/Icons/LowMemoryUsage.TIF.exportsettings diff --git a/Engine/EngineAssets/Icons/NavigationProcessing.tif b/Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif similarity index 100% rename from Engine/EngineAssets/Icons/NavigationProcessing.tif rename to Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif diff --git a/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/NavigationProcessing.tif.exportsettings diff --git a/Engine/EngineAssets/Icons/NullSoundSystem.tif b/Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif similarity index 100% rename from Engine/EngineAssets/Icons/NullSoundSystem.tif rename to Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif diff --git a/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/NullSoundSystem.tif.exportsettings diff --git a/Engine/EngineAssets/Icons/ShaderCompiling.tif b/Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif similarity index 100% rename from Engine/EngineAssets/Icons/ShaderCompiling.tif rename to Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif diff --git a/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/ShaderCompiling.tif.exportsettings diff --git a/Engine/EngineAssets/Icons/Streaming.tif b/Assets/Engine/EngineAssets/Icons/Streaming.tif similarity index 100% rename from Engine/EngineAssets/Icons/Streaming.tif rename to Assets/Engine/EngineAssets/Icons/Streaming.tif diff --git a/Engine/EngineAssets/Icons/Streaming.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/Streaming.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/Streaming.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/Streaming.tif.exportsettings diff --git a/Engine/EngineAssets/Icons/StreamingTerrain.tif b/Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif similarity index 100% rename from Engine/EngineAssets/Icons/StreamingTerrain.tif rename to Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif diff --git a/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings b/Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings rename to Assets/Engine/EngineAssets/Icons/StreamingTerrain.tif.exportsettings diff --git a/Engine/EngineAssets/LevelForSliceEditing/LevelForSliceEditing.ly b/Assets/Engine/EngineAssets/LevelForSliceEditing/LevelForSliceEditing.ly similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/LevelForSliceEditing.ly rename to Assets/Engine/EngineAssets/LevelForSliceEditing/LevelForSliceEditing.ly diff --git a/Engine/EngineAssets/LevelForSliceEditing/filelist.xml b/Assets/Engine/EngineAssets/LevelForSliceEditing/filelist.xml similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/filelist.xml rename to Assets/Engine/EngineAssets/LevelForSliceEditing/filelist.xml diff --git a/Engine/EngineAssets/LevelForSliceEditing/level.pak b/Assets/Engine/EngineAssets/LevelForSliceEditing/level.pak similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/level.pak rename to Assets/Engine/EngineAssets/LevelForSliceEditing/level.pak diff --git a/Engine/EngineAssets/LevelForSliceEditing/leveldata/environment.xml b/Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/environment.xml similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/leveldata/environment.xml rename to Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/environment.xml diff --git a/Engine/EngineAssets/LevelForSliceEditing/leveldata/heightmap.dat b/Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/heightmap.dat similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/leveldata/heightmap.dat rename to Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/heightmap.dat diff --git a/Engine/EngineAssets/LevelForSliceEditing/leveldata/terraintexture.xml b/Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/terraintexture.xml similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/leveldata/terraintexture.xml rename to Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/terraintexture.xml diff --git a/Engine/EngineAssets/LevelForSliceEditing/leveldata/timeofday.xml b/Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/timeofday.xml similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/leveldata/timeofday.xml rename to Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/timeofday.xml diff --git a/Engine/EngineAssets/LevelForSliceEditing/leveldata/vegetationmap.dat b/Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/vegetationmap.dat similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/leveldata/vegetationmap.dat rename to Assets/Engine/EngineAssets/LevelForSliceEditing/leveldata/vegetationmap.dat diff --git a/Engine/EngineAssets/LevelForSliceEditing/tags.txt b/Assets/Engine/EngineAssets/LevelForSliceEditing/tags.txt similarity index 100% rename from Engine/EngineAssets/LevelForSliceEditing/tags.txt rename to Assets/Engine/EngineAssets/LevelForSliceEditing/tags.txt diff --git a/Engine/EngineAssets/Materials/Fog/FogVolumeBox.mtl b/Assets/Engine/EngineAssets/Materials/Fog/FogVolumeBox.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/FogVolumeBox.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/FogVolumeBox.mtl diff --git a/Engine/EngineAssets/Materials/Fog/FogVolumeEllipsoid.mtl b/Assets/Engine/EngineAssets/Materials/Fog/FogVolumeEllipsoid.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/FogVolumeEllipsoid.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/FogVolumeEllipsoid.mtl diff --git a/Engine/EngineAssets/Materials/Fog/OceanInto.mtl b/Assets/Engine/EngineAssets/Materials/Fog/OceanInto.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/OceanInto.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/OceanInto.mtl diff --git a/Engine/EngineAssets/Materials/Fog/OceanIntoLowSpec.mtl b/Assets/Engine/EngineAssets/Materials/Fog/OceanIntoLowSpec.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/OceanIntoLowSpec.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/OceanIntoLowSpec.mtl diff --git a/Engine/EngineAssets/Materials/Fog/OceanOutof.mtl b/Assets/Engine/EngineAssets/Materials/Fog/OceanOutof.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/OceanOutof.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/OceanOutof.mtl diff --git a/Engine/EngineAssets/Materials/Fog/OceanOutofLowSpec.mtl b/Assets/Engine/EngineAssets/Materials/Fog/OceanOutofLowSpec.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/OceanOutofLowSpec.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/OceanOutofLowSpec.mtl diff --git a/Engine/EngineAssets/Materials/Fog/WaterFogVolumeInto.mtl b/Assets/Engine/EngineAssets/Materials/Fog/WaterFogVolumeInto.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/WaterFogVolumeInto.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/WaterFogVolumeInto.mtl diff --git a/Engine/EngineAssets/Materials/Fog/WaterFogVolumeOutof.mtl b/Assets/Engine/EngineAssets/Materials/Fog/WaterFogVolumeOutof.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Fog/WaterFogVolumeOutof.mtl rename to Assets/Engine/EngineAssets/Materials/Fog/WaterFogVolumeOutof.mtl diff --git a/Engine/EngineAssets/Materials/PhysProxyTooBig.mtl b/Assets/Engine/EngineAssets/Materials/PhysProxyTooBig.mtl similarity index 100% rename from Engine/EngineAssets/Materials/PhysProxyTooBig.mtl rename to Assets/Engine/EngineAssets/Materials/PhysProxyTooBig.mtl diff --git a/Engine/EngineAssets/Materials/Water/WaterOceanBottom.mtl b/Assets/Engine/EngineAssets/Materials/Water/WaterOceanBottom.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Water/WaterOceanBottom.mtl rename to Assets/Engine/EngineAssets/Materials/Water/WaterOceanBottom.mtl diff --git a/Engine/EngineAssets/Materials/Water/ocean_default.mtl b/Assets/Engine/EngineAssets/Materials/Water/ocean_default.mtl similarity index 100% rename from Engine/EngineAssets/Materials/Water/ocean_default.mtl rename to Assets/Engine/EngineAssets/Materials/Water/ocean_default.mtl diff --git a/Engine/EngineAssets/Materials/collision_proxy_entitiesonly.mtl b/Assets/Engine/EngineAssets/Materials/collision_proxy_entitiesonly.mtl similarity index 100% rename from Engine/EngineAssets/Materials/collision_proxy_entitiesonly.mtl rename to Assets/Engine/EngineAssets/Materials/collision_proxy_entitiesonly.mtl diff --git a/Engine/EngineAssets/Materials/decals/default.mtl b/Assets/Engine/EngineAssets/Materials/decals/default.mtl similarity index 100% rename from Engine/EngineAssets/Materials/decals/default.mtl rename to Assets/Engine/EngineAssets/Materials/decals/default.mtl diff --git a/Engine/EngineAssets/Materials/lens_optics.mtl b/Assets/Engine/EngineAssets/Materials/lens_optics.mtl similarity index 100% rename from Engine/EngineAssets/Materials/lens_optics.mtl rename to Assets/Engine/EngineAssets/Materials/lens_optics.mtl diff --git a/Engine/EngineAssets/Materials/sky/sky.mtl b/Assets/Engine/EngineAssets/Materials/sky/sky.mtl similarity index 100% rename from Engine/EngineAssets/Materials/sky/sky.mtl rename to Assets/Engine/EngineAssets/Materials/sky/sky.mtl diff --git a/Engine/EngineAssets/Materials/test/Holotest/hologram.mtl b/Assets/Engine/EngineAssets/Materials/test/Holotest/hologram.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/hologram.mtl rename to Assets/Engine/EngineAssets/Materials/test/Holotest/hologram.mtl diff --git a/Engine/EngineAssets/Materials/test/Holotest/test2.tif b/Assets/Engine/EngineAssets/Materials/test/Holotest/test2.tif similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/test2.tif rename to Assets/Engine/EngineAssets/Materials/test/Holotest/test2.tif diff --git a/Engine/EngineAssets/Materials/test/Holotest/test2.tif.exportsettings b/Assets/Engine/EngineAssets/Materials/test/Holotest/test2.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/test2.tif.exportsettings rename to Assets/Engine/EngineAssets/Materials/test/Holotest/test2.tif.exportsettings diff --git a/Engine/EngineAssets/Materials/test/Holotest/tews1.tif b/Assets/Engine/EngineAssets/Materials/test/Holotest/tews1.tif similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/tews1.tif rename to Assets/Engine/EngineAssets/Materials/test/Holotest/tews1.tif diff --git a/Engine/EngineAssets/Materials/test/Holotest/tews1.tif.exportsettings b/Assets/Engine/EngineAssets/Materials/test/Holotest/tews1.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/tews1.tif.exportsettings rename to Assets/Engine/EngineAssets/Materials/test/Holotest/tews1.tif.exportsettings diff --git a/Engine/EngineAssets/Materials/test/Holotest/tile1.cgf b/Assets/Engine/EngineAssets/Materials/test/Holotest/tile1.cgf similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/tile1.cgf rename to Assets/Engine/EngineAssets/Materials/test/Holotest/tile1.cgf diff --git a/Engine/EngineAssets/Materials/test/Holotest/tile1.max b/Assets/Engine/EngineAssets/Materials/test/Holotest/tile1.max similarity index 100% rename from Engine/EngineAssets/Materials/test/Holotest/tile1.max rename to Assets/Engine/EngineAssets/Materials/test/Holotest/tile1.max diff --git a/Engine/EngineAssets/Materials/test/chromium.mtl b/Assets/Engine/EngineAssets/Materials/test/chromium.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/chromium.mtl rename to Assets/Engine/EngineAssets/Materials/test/chromium.mtl diff --git a/Engine/EngineAssets/Materials/test/glass2.mtl b/Assets/Engine/EngineAssets/Materials/test/glass2.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/glass2.mtl rename to Assets/Engine/EngineAssets/Materials/test/glass2.mtl diff --git a/Engine/EngineAssets/Materials/test/hologram.mtl b/Assets/Engine/EngineAssets/Materials/test/hologram.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/hologram.mtl rename to Assets/Engine/EngineAssets/Materials/test/hologram.mtl diff --git a/Engine/EngineAssets/Materials/test/lightbeam.mtl b/Assets/Engine/EngineAssets/Materials/test/lightbeam.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/lightbeam.mtl rename to Assets/Engine/EngineAssets/Materials/test/lightbeam.mtl diff --git a/Engine/EngineAssets/Materials/test/lightbeam_floodlight.mtl b/Assets/Engine/EngineAssets/Materials/test/lightbeam_floodlight.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/lightbeam_floodlight.mtl rename to Assets/Engine/EngineAssets/Materials/test/lightbeam_floodlight.mtl diff --git a/Engine/EngineAssets/Materials/test/lighthouseBeam.mtl b/Assets/Engine/EngineAssets/Materials/test/lighthouseBeam.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/lighthouseBeam.mtl rename to Assets/Engine/EngineAssets/Materials/test/lighthouseBeam.mtl diff --git a/Engine/EngineAssets/Materials/test/lighthousetemplebeam.mtl b/Assets/Engine/EngineAssets/Materials/test/lighthousetemplebeam.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/lighthousetemplebeam.mtl rename to Assets/Engine/EngineAssets/Materials/test/lighthousetemplebeam.mtl diff --git a/Engine/EngineAssets/Materials/test/nodraw.mtl b/Assets/Engine/EngineAssets/Materials/test/nodraw.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/nodraw.mtl rename to Assets/Engine/EngineAssets/Materials/test/nodraw.mtl diff --git a/Engine/EngineAssets/Materials/test/sky.mtl b/Assets/Engine/EngineAssets/Materials/test/sky.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/sky.mtl rename to Assets/Engine/EngineAssets/Materials/test/sky.mtl diff --git a/Engine/EngineAssets/Materials/test/skyHDR.mtl b/Assets/Engine/EngineAssets/Materials/test/skyHDR.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/skyHDR.mtl rename to Assets/Engine/EngineAssets/Materials/test/skyHDR.mtl diff --git a/Engine/EngineAssets/Materials/test/textures/glass_wall_ddn.tif b/Assets/Engine/EngineAssets/Materials/test/textures/glass_wall_ddn.tif similarity index 100% rename from Engine/EngineAssets/Materials/test/textures/glass_wall_ddn.tif rename to Assets/Engine/EngineAssets/Materials/test/textures/glass_wall_ddn.tif diff --git a/Engine/EngineAssets/Materials/test/textures/templeBeam.tif b/Assets/Engine/EngineAssets/Materials/test/textures/templeBeam.tif similarity index 100% rename from Engine/EngineAssets/Materials/test/textures/templeBeam.tif rename to Assets/Engine/EngineAssets/Materials/test/textures/templeBeam.tif diff --git a/Engine/EngineAssets/Materials/test/textures/templeBeam.tif.exportsettings b/Assets/Engine/EngineAssets/Materials/test/textures/templeBeam.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Materials/test/textures/templeBeam.tif.exportsettings rename to Assets/Engine/EngineAssets/Materials/test/textures/templeBeam.tif.exportsettings diff --git a/Engine/EngineAssets/Materials/test/volumeObject.mtl b/Assets/Engine/EngineAssets/Materials/test/volumeObject.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/volumeObject.mtl rename to Assets/Engine/EngineAssets/Materials/test/volumeObject.mtl diff --git a/Engine/EngineAssets/Materials/test/volumeObject2.mtl b/Assets/Engine/EngineAssets/Materials/test/volumeObject2.mtl similarity index 100% rename from Engine/EngineAssets/Materials/test/volumeObject2.mtl rename to Assets/Engine/EngineAssets/Materials/test/volumeObject2.mtl diff --git a/Engine/EngineAssets/Objects/Default.cgf b/Assets/Engine/EngineAssets/Objects/Default.cgf similarity index 100% rename from Engine/EngineAssets/Objects/Default.cgf rename to Assets/Engine/EngineAssets/Objects/Default.cgf diff --git a/Engine/EngineAssets/Objects/helper.mtl b/Assets/Engine/EngineAssets/Objects/helper.mtl similarity index 100% rename from Engine/EngineAssets/Objects/helper.mtl rename to Assets/Engine/EngineAssets/Objects/helper.mtl diff --git a/Engine/EngineAssets/Production/MidGray.tif b/Assets/Engine/EngineAssets/Production/MidGray.tif similarity index 100% rename from Engine/EngineAssets/Production/MidGray.tif rename to Assets/Engine/EngineAssets/Production/MidGray.tif diff --git a/Engine/EngineAssets/Production/MidGray.tif.exportsettings b/Assets/Engine/EngineAssets/Production/MidGray.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Production/MidGray.tif.exportsettings rename to Assets/Engine/EngineAssets/Production/MidGray.tif.exportsettings diff --git a/Engine/EngineAssets/Production/TangentReference_ddn.tif b/Assets/Engine/EngineAssets/Production/TangentReference_ddn.tif similarity index 100% rename from Engine/EngineAssets/Production/TangentReference_ddn.tif rename to Assets/Engine/EngineAssets/Production/TangentReference_ddn.tif diff --git a/Engine/EngineAssets/Production/TangentReference_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Production/TangentReference_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Production/TangentReference_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Production/TangentReference_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Production/UV.tif b/Assets/Engine/EngineAssets/Production/UV.tif similarity index 100% rename from Engine/EngineAssets/Production/UV.tif rename to Assets/Engine/EngineAssets/Production/UV.tif diff --git a/Engine/EngineAssets/Production/UV.tif.exportsettings b/Assets/Engine/EngineAssets/Production/UV.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Production/UV.tif.exportsettings rename to Assets/Engine/EngineAssets/Production/UV.tif.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/AreaTex.dds b/Assets/Engine/EngineAssets/ScreenSpace/AreaTex.dds similarity index 100% rename from Engine/EngineAssets/ScreenSpace/AreaTex.dds rename to Assets/Engine/EngineAssets/ScreenSpace/AreaTex.dds diff --git a/Engine/EngineAssets/ScreenSpace/NormalsFitting.dds b/Assets/Engine/EngineAssets/ScreenSpace/NormalsFitting.dds similarity index 100% rename from Engine/EngineAssets/ScreenSpace/NormalsFitting.dds rename to Assets/Engine/EngineAssets/ScreenSpace/NormalsFitting.dds diff --git a/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif b/Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif similarity index 100% rename from Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif rename to Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif diff --git a/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif b/Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif similarity index 100% rename from Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif rename to Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif diff --git a/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/SearchTex.dds b/Assets/Engine/EngineAssets/ScreenSpace/SearchTex.dds similarity index 100% rename from Engine/EngineAssets/ScreenSpace/SearchTex.dds rename to Assets/Engine/EngineAssets/ScreenSpace/SearchTex.dds diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_love.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_love.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_love.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_music.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_music.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_music.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_pentagon.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_spherical.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_square.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_square.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_square.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_star.TIF rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF diff --git a/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/bokeh_star.TIF.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/bokeh_star.TIF.exportsettings diff --git a/Engine/EngineAssets/ScreenSpace/film_grain.dds b/Assets/Engine/EngineAssets/ScreenSpace/film_grain.dds similarity index 100% rename from Engine/EngineAssets/ScreenSpace/film_grain.dds rename to Assets/Engine/EngineAssets/ScreenSpace/film_grain.dds diff --git a/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif b/Assets/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif similarity index 100% rename from Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif rename to Assets/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif diff --git a/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif.exportsettings b/Assets/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif.exportsettings rename to Assets/Engine/EngineAssets/ScreenSpace/grain_bayer_mul.tif.exportsettings diff --git a/Engine/EngineAssets/Shading/SonarVisionGradient.TIF b/Assets/Engine/EngineAssets/Shading/SonarVisionGradient.TIF similarity index 100% rename from Engine/EngineAssets/Shading/SonarVisionGradient.TIF rename to Assets/Engine/EngineAssets/Shading/SonarVisionGradient.TIF diff --git a/Engine/EngineAssets/Shading/SonarVisionGradient.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/SonarVisionGradient.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/SonarVisionGradient.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/SonarVisionGradient.TIF.exportsettings diff --git a/Engine/EngineAssets/Shading/ThermalVisionGradient.tif b/Assets/Engine/EngineAssets/Shading/ThermalVisionGradient.tif similarity index 100% rename from Engine/EngineAssets/Shading/ThermalVisionGradient.tif rename to Assets/Engine/EngineAssets/Shading/ThermalVisionGradient.tif diff --git a/Engine/EngineAssets/Shading/ThermalVisionGradient.tif.exportsettings b/Assets/Engine/EngineAssets/Shading/ThermalVisionGradient.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/ThermalVisionGradient.tif.exportsettings rename to Assets/Engine/EngineAssets/Shading/ThermalVisionGradient.tif.exportsettings diff --git a/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF b/Assets/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF similarity index 100% rename from Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF rename to Assets/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF diff --git a/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/ThermalVisionGradient02.TIF.exportsettings diff --git a/Engine/EngineAssets/Shading/WaterFoam.TIF b/Assets/Engine/EngineAssets/Shading/WaterFoam.TIF similarity index 100% rename from Engine/EngineAssets/Shading/WaterFoam.TIF rename to Assets/Engine/EngineAssets/Shading/WaterFoam.TIF diff --git a/Engine/EngineAssets/Shading/WaterFoam.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/WaterFoam.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/WaterFoam.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/WaterFoam.TIF.exportsettings diff --git a/Engine/EngineAssets/Shading/cook_d_sampler_G16R16F.dds b/Assets/Engine/EngineAssets/Shading/cook_d_sampler_G16R16F.dds similarity index 100% rename from Engine/EngineAssets/Shading/cook_d_sampler_G16R16F.dds rename to Assets/Engine/EngineAssets/Shading/cook_d_sampler_G16R16F.dds diff --git a/Engine/EngineAssets/Shading/defaultProbe_cm.tif b/Assets/Engine/EngineAssets/Shading/defaultProbe_cm.tif similarity index 100% rename from Engine/EngineAssets/Shading/defaultProbe_cm.tif rename to Assets/Engine/EngineAssets/Shading/defaultProbe_cm.tif diff --git a/Engine/EngineAssets/Shading/environmentBRDF.tif b/Assets/Engine/EngineAssets/Shading/environmentBRDF.tif similarity index 100% rename from Engine/EngineAssets/Shading/environmentBRDF.tif rename to Assets/Engine/EngineAssets/Shading/environmentBRDF.tif diff --git a/Engine/EngineAssets/Shading/generic_reflections.tif b/Assets/Engine/EngineAssets/Shading/generic_reflections.tif similarity index 100% rename from Engine/EngineAssets/Shading/generic_reflections.tif rename to Assets/Engine/EngineAssets/Shading/generic_reflections.tif diff --git a/Engine/EngineAssets/Shading/generic_reflections.tif.exportsettings b/Assets/Engine/EngineAssets/Shading/generic_reflections.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/generic_reflections.tif.exportsettings rename to Assets/Engine/EngineAssets/Shading/generic_reflections.tif.exportsettings diff --git a/Engine/EngineAssets/Shading/layer_effect_anim_function.tif b/Assets/Engine/EngineAssets/Shading/layer_effect_anim_function.tif similarity index 100% rename from Engine/EngineAssets/Shading/layer_effect_anim_function.tif rename to Assets/Engine/EngineAssets/Shading/layer_effect_anim_function.tif diff --git a/Engine/EngineAssets/Shading/layer_effect_anim_function.tif.exportsettings b/Assets/Engine/EngineAssets/Shading/layer_effect_anim_function.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/layer_effect_anim_function.tif.exportsettings rename to Assets/Engine/EngineAssets/Shading/layer_effect_anim_function.tif.exportsettings diff --git a/Engine/EngineAssets/Shading/nanosuit_mask.TIF b/Assets/Engine/EngineAssets/Shading/nanosuit_mask.TIF similarity index 100% rename from Engine/EngineAssets/Shading/nanosuit_mask.TIF rename to Assets/Engine/EngineAssets/Shading/nanosuit_mask.TIF diff --git a/Engine/EngineAssets/Shading/nanosuit_mask.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/nanosuit_mask.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/nanosuit_mask.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/nanosuit_mask.TIF.exportsettings diff --git a/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF b/Assets/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF similarity index 100% rename from Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF rename to Assets/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF diff --git a/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/nanosuit_modes_grads.TIF.exportsettings diff --git a/Engine/EngineAssets/Shading/vignetting.TIF b/Assets/Engine/EngineAssets/Shading/vignetting.TIF similarity index 100% rename from Engine/EngineAssets/Shading/vignetting.TIF rename to Assets/Engine/EngineAssets/Shading/vignetting.TIF diff --git a/Engine/EngineAssets/Shading/vignetting.TIF.exportsettings b/Assets/Engine/EngineAssets/Shading/vignetting.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Shading/vignetting.TIF.exportsettings rename to Assets/Engine/EngineAssets/Shading/vignetting.TIF.exportsettings diff --git a/Engine/EngineAssets/Sky/optical.lut b/Assets/Engine/EngineAssets/Sky/optical.lut similarity index 100% rename from Engine/EngineAssets/Sky/optical.lut rename to Assets/Engine/EngineAssets/Sky/optical.lut diff --git a/Engine/EngineAssets/Sky/stars.dat b/Assets/Engine/EngineAssets/Sky/stars.dat similarity index 100% rename from Engine/EngineAssets/Sky/stars.dat rename to Assets/Engine/EngineAssets/Sky/stars.dat diff --git a/Engine/EngineAssets/Slices/DefaultLevelSetup.slice b/Assets/Engine/EngineAssets/Slices/DefaultLevelSetup.slice similarity index 100% rename from Engine/EngineAssets/Slices/DefaultLevelSetup.slice rename to Assets/Engine/EngineAssets/Slices/DefaultLevelSetup.slice diff --git a/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif diff --git a/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/DefaultNoUVs_ddn.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs_ddn.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultNoUVs_ddn.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs_ddn.tif diff --git a/Engine/EngineAssets/TextureMsg/DefaultNoUVs_spec.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs_spec.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultNoUVs_spec.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultNoUVs_spec.tif diff --git a/Engine/EngineAssets/TextureMsg/DefaultSolids.mtl b/Assets/Engine/EngineAssets/TextureMsg/DefaultSolids.mtl similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultSolids.mtl rename to Assets/Engine/EngineAssets/TextureMsg/DefaultSolids.mtl diff --git a/Engine/EngineAssets/TextureMsg/DefaultSolids_ddn.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_ddn.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultSolids_ddn.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_ddn.tif diff --git a/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif diff --git a/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_diff.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/DefaultSolids_spec.tif b/Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_spec.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/DefaultSolids_spec.tif rename to Assets/Engine/EngineAssets/TextureMsg/DefaultSolids_spec.tif diff --git a/Engine/EngineAssets/TextureMsg/NotFound.psd b/Assets/Engine/EngineAssets/TextureMsg/NotFound.psd similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound.psd rename to Assets/Engine/EngineAssets/TextureMsg/NotFound.psd diff --git a/Engine/EngineAssets/TextureMsg/NotFound.tif b/Assets/Engine/EngineAssets/TextureMsg/NotFound.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound.tif rename to Assets/Engine/EngineAssets/TextureMsg/NotFound.tif diff --git a/Engine/EngineAssets/TextureMsg/NotFound_a.tif b/Assets/Engine/EngineAssets/TextureMsg/NotFound_a.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound_a.tif rename to Assets/Engine/EngineAssets/TextureMsg/NotFound_a.tif diff --git a/Engine/EngineAssets/TextureMsg/NotFound_cm.tif b/Assets/Engine/EngineAssets/TextureMsg/NotFound_cm.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound_cm.tif rename to Assets/Engine/EngineAssets/TextureMsg/NotFound_cm.tif diff --git a/Engine/EngineAssets/TextureMsg/NotFound_ddn.tif b/Assets/Engine/EngineAssets/TextureMsg/NotFound_ddn.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound_ddn.tif rename to Assets/Engine/EngineAssets/TextureMsg/NotFound_ddn.tif diff --git a/Engine/EngineAssets/TextureMsg/NotFound_ddna.tif b/Assets/Engine/EngineAssets/TextureMsg/NotFound_ddna.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/NotFound_ddna.tif rename to Assets/Engine/EngineAssets/TextureMsg/NotFound_ddna.tif diff --git a/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif b/Assets/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif rename to Assets/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif diff --git a/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/PhysProxyTooBig.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/RCError.psd b/Assets/Engine/EngineAssets/TextureMsg/RCError.psd similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError.psd rename to Assets/Engine/EngineAssets/TextureMsg/RCError.psd diff --git a/Engine/EngineAssets/TextureMsg/RCError.tif b/Assets/Engine/EngineAssets/TextureMsg/RCError.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError.tif rename to Assets/Engine/EngineAssets/TextureMsg/RCError.tif diff --git a/Engine/EngineAssets/TextureMsg/RCError_a.tif b/Assets/Engine/EngineAssets/TextureMsg/RCError_a.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_a.tif rename to Assets/Engine/EngineAssets/TextureMsg/RCError_a.tif diff --git a/Engine/EngineAssets/TextureMsg/RCError_a.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/RCError_a.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_a.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/RCError_a.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/RCError_cm.tif b/Assets/Engine/EngineAssets/TextureMsg/RCError_cm.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_cm.tif rename to Assets/Engine/EngineAssets/TextureMsg/RCError_cm.tif diff --git a/Engine/EngineAssets/TextureMsg/RCError_ddn.tif b/Assets/Engine/EngineAssets/TextureMsg/RCError_ddn.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_ddn.tif rename to Assets/Engine/EngineAssets/TextureMsg/RCError_ddn.tif diff --git a/Engine/EngineAssets/TextureMsg/RCError_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/RCError_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/RCError_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/RCError_ddna.tif b/Assets/Engine/EngineAssets/TextureMsg/RCError_ddna.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_ddna.tif rename to Assets/Engine/EngineAssets/TextureMsg/RCError_ddna.tif diff --git a/Engine/EngineAssets/TextureMsg/RCError_ddna.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/RCError_ddna.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/RCError_ddna.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/RCError_ddna.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMe.tif b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMe.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMe.tif rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMe.tif diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMe.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMe.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMe.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMe.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMeCm.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif diff --git a/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/ReplaceMeRelease.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif b/Assets/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/ShaderCompiling.tif rename to Assets/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif diff --git a/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/ShaderCompiling.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/ShaderCompiling.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/ShaderError.tif b/Assets/Engine/EngineAssets/TextureMsg/ShaderError.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/ShaderError.tif rename to Assets/Engine/EngineAssets/TextureMsg/ShaderError.tif diff --git a/Engine/EngineAssets/TextureMsg/ShaderError.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/ShaderError.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/ShaderError.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/ShaderError.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling.tif b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling.tif rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling.tif diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_a.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_cm.tif b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_cm.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_cm.tif rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_cm.tif diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif diff --git a/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif.exportsettings b/Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif.exportsettings rename to Assets/Engine/EngineAssets/TextureMsg/TextureCompiling_ddna.tif.exportsettings diff --git a/Engine/EngineAssets/TextureMsg/color_Black.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Black.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Black.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Black.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Blue.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Blue.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Blue.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Blue.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Cyan.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Cyan.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Cyan.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Cyan.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Green.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Green.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Green.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Green.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Magenta.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Magenta.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Magenta.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Magenta.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Orange.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Orange.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Orange.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Orange.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Purple.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Purple.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Purple.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Purple.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Red.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Red.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Red.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Red.tif diff --git a/Engine/EngineAssets/TextureMsg/color_White.tif b/Assets/Engine/EngineAssets/TextureMsg/color_White.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_White.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_White.tif diff --git a/Engine/EngineAssets/TextureMsg/color_Yellow.tif b/Assets/Engine/EngineAssets/TextureMsg/color_Yellow.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/color_Yellow.tif rename to Assets/Engine/EngineAssets/TextureMsg/color_Yellow.tif diff --git a/Engine/EngineAssets/TextureMsg/mipmapdebug.tif b/Assets/Engine/EngineAssets/TextureMsg/mipmapdebug.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/mipmapdebug.tif rename to Assets/Engine/EngineAssets/TextureMsg/mipmapdebug.tif diff --git a/Engine/EngineAssets/TextureMsg/orange_for_designer.tif b/Assets/Engine/EngineAssets/TextureMsg/orange_for_designer.tif similarity index 100% rename from Engine/EngineAssets/TextureMsg/orange_for_designer.tif rename to Assets/Engine/EngineAssets/TextureMsg/orange_for_designer.tif diff --git a/Engine/EngineAssets/Textures/BlackAlpha.tif b/Assets/Engine/EngineAssets/Textures/BlackAlpha.tif similarity index 100% rename from Engine/EngineAssets/Textures/BlackAlpha.tif rename to Assets/Engine/EngineAssets/Textures/BlackAlpha.tif diff --git a/Engine/EngineAssets/Textures/BlackCM.tif b/Assets/Engine/EngineAssets/Textures/BlackCM.tif similarity index 100% rename from Engine/EngineAssets/Textures/BlackCM.tif rename to Assets/Engine/EngineAssets/Textures/BlackCM.tif diff --git a/Engine/EngineAssets/Textures/BlackCM.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/BlackCM.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/BlackCM.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/BlackCM.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/Cubemap/default_level_cubemap.tif b/Assets/Engine/EngineAssets/Textures/Cubemap/default_level_cubemap.tif similarity index 100% rename from Engine/EngineAssets/Textures/Cubemap/default_level_cubemap.tif rename to Assets/Engine/EngineAssets/Textures/Cubemap/default_level_cubemap.tif diff --git a/Engine/EngineAssets/Textures/Cursor_Green.tif b/Assets/Engine/EngineAssets/Textures/Cursor_Green.tif similarity index 100% rename from Engine/EngineAssets/Textures/Cursor_Green.tif rename to Assets/Engine/EngineAssets/Textures/Cursor_Green.tif diff --git a/Engine/EngineAssets/Textures/Cursor_Green.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/Cursor_Green.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/Cursor_Green.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/Cursor_Green.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/FogVolShadowJitter.tif b/Assets/Engine/EngineAssets/Textures/FogVolShadowJitter.tif similarity index 100% rename from Engine/EngineAssets/Textures/FogVolShadowJitter.tif rename to Assets/Engine/EngineAssets/Textures/FogVolShadowJitter.tif diff --git a/Engine/EngineAssets/Textures/FogVolShadowJitter.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/FogVolShadowJitter.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/FogVolShadowJitter.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/FogVolShadowJitter.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/Frozen/frost_noise3.dds b/Assets/Engine/EngineAssets/Textures/Frozen/frost_noise3.dds similarity index 100% rename from Engine/EngineAssets/Textures/Frozen/frost_noise3.dds rename to Assets/Engine/EngineAssets/Textures/Frozen/frost_noise3.dds diff --git a/Engine/EngineAssets/Textures/Frozen/frost_noise4.tif b/Assets/Engine/EngineAssets/Textures/Frozen/frost_noise4.tif similarity index 100% rename from Engine/EngineAssets/Textures/Frozen/frost_noise4.tif rename to Assets/Engine/EngineAssets/Textures/Frozen/frost_noise4.tif diff --git a/Engine/EngineAssets/Textures/Frozen/snow_spatter.tif b/Assets/Engine/EngineAssets/Textures/Frozen/snow_spatter.tif similarity index 100% rename from Engine/EngineAssets/Textures/Frozen/snow_spatter.tif rename to Assets/Engine/EngineAssets/Textures/Frozen/snow_spatter.tif diff --git a/Engine/EngineAssets/Textures/GreyAlpha.tif b/Assets/Engine/EngineAssets/Textures/GreyAlpha.tif similarity index 100% rename from Engine/EngineAssets/Textures/GreyAlpha.tif rename to Assets/Engine/EngineAssets/Textures/GreyAlpha.tif diff --git a/Engine/EngineAssets/Textures/GreyAlpha.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/GreyAlpha.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/GreyAlpha.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/GreyAlpha.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/Palette/cloak_interlation.dds b/Assets/Engine/EngineAssets/Textures/Palette/cloak_interlation.dds similarity index 100% rename from Engine/EngineAssets/Textures/Palette/cloak_interlation.dds rename to Assets/Engine/EngineAssets/Textures/Palette/cloak_interlation.dds diff --git a/Engine/EngineAssets/Textures/Palette/cloak_palette.tif b/Assets/Engine/EngineAssets/Textures/Palette/cloak_palette.tif similarity index 100% rename from Engine/EngineAssets/Textures/Palette/cloak_palette.tif rename to Assets/Engine/EngineAssets/Textures/Palette/cloak_palette.tif diff --git a/Engine/EngineAssets/Textures/Palette/cloak_palette.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/Palette/cloak_palette.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/Palette/cloak_palette.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/Palette/cloak_palette.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/Palette/cloak_sparks.dds b/Assets/Engine/EngineAssets/Textures/Palette/cloak_sparks.dds similarity index 100% rename from Engine/EngineAssets/Textures/Palette/cloak_sparks.dds rename to Assets/Engine/EngineAssets/Textures/Palette/cloak_sparks.dds diff --git a/Engine/EngineAssets/Textures/Palette/cloak_transition.dds b/Assets/Engine/EngineAssets/Textures/Palette/cloak_transition.dds similarity index 100% rename from Engine/EngineAssets/Textures/Palette/cloak_transition.dds rename to Assets/Engine/EngineAssets/Textures/Palette/cloak_transition.dds diff --git a/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif b/Assets/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif similarity index 100% rename from Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif rename to Assets/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif diff --git a/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/TexelsPerMeterGrad.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/VolumeRaster.tif b/Assets/Engine/EngineAssets/Textures/VolumeRaster.tif similarity index 100% rename from Engine/EngineAssets/Textures/VolumeRaster.tif rename to Assets/Engine/EngineAssets/Textures/VolumeRaster.tif diff --git a/Engine/EngineAssets/Textures/VolumeRaster.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/VolumeRaster.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/VolumeRaster.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/VolumeRaster.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/alienhud_distortionimage.tif b/Assets/Engine/EngineAssets/Textures/alienhud_distortionimage.tif similarity index 100% rename from Engine/EngineAssets/Textures/alienhud_distortionimage.tif rename to Assets/Engine/EngineAssets/Textures/alienhud_distortionimage.tif diff --git a/Engine/EngineAssets/Textures/alienhud_distortionimage.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/alienhud_distortionimage.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/alienhud_distortionimage.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/alienhud_distortionimage.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/alienhud_noise1.tif b/Assets/Engine/EngineAssets/Textures/alienhud_noise1.tif similarity index 100% rename from Engine/EngineAssets/Textures/alienhud_noise1.tif rename to Assets/Engine/EngineAssets/Textures/alienhud_noise1.tif diff --git a/Engine/EngineAssets/Textures/alienhud_noise1.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/alienhud_noise1.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/alienhud_noise1.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/alienhud_noise1.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/black.tif b/Assets/Engine/EngineAssets/Textures/black.tif similarity index 100% rename from Engine/EngineAssets/Textures/black.tif rename to Assets/Engine/EngineAssets/Textures/black.tif diff --git a/Engine/EngineAssets/Textures/black.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/black.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/black.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/black.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/caustics_sampler.dds b/Assets/Engine/EngineAssets/Textures/caustics_sampler.dds similarity index 100% rename from Engine/EngineAssets/Textures/caustics_sampler.dds rename to Assets/Engine/EngineAssets/Textures/caustics_sampler.dds diff --git a/Engine/EngineAssets/Textures/color.tif b/Assets/Engine/EngineAssets/Textures/color.tif similarity index 100% rename from Engine/EngineAssets/Textures/color.tif rename to Assets/Engine/EngineAssets/Textures/color.tif diff --git a/Engine/EngineAssets/Textures/default_cch.tif b/Assets/Engine/EngineAssets/Textures/default_cch.tif similarity index 100% rename from Engine/EngineAssets/Textures/default_cch.tif rename to Assets/Engine/EngineAssets/Textures/default_cch.tif diff --git a/Engine/EngineAssets/Textures/default_cch.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/default_cch.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/default_cch.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/default_cch.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/defaults/16_12.tif b/Assets/Engine/EngineAssets/Textures/defaults/16_12.tif similarity index 100% rename from Engine/EngineAssets/Textures/defaults/16_12.tif rename to Assets/Engine/EngineAssets/Textures/defaults/16_12.tif diff --git a/Engine/EngineAssets/Textures/defaults/16_34.tif b/Assets/Engine/EngineAssets/Textures/defaults/16_34.tif similarity index 100% rename from Engine/EngineAssets/Textures/defaults/16_34.tif rename to Assets/Engine/EngineAssets/Textures/defaults/16_34.tif diff --git a/Engine/EngineAssets/Textures/defaults/16_5.tif b/Assets/Engine/EngineAssets/Textures/defaults/16_5.tif similarity index 100% rename from Engine/EngineAssets/Textures/defaults/16_5.tif rename to Assets/Engine/EngineAssets/Textures/defaults/16_5.tif diff --git a/Engine/EngineAssets/Textures/defaults/16_grey.tif b/Assets/Engine/EngineAssets/Textures/defaults/16_grey.tif similarity index 100% rename from Engine/EngineAssets/Textures/defaults/16_grey.tif rename to Assets/Engine/EngineAssets/Textures/defaults/16_grey.tif diff --git a/Engine/EngineAssets/Textures/defaults/spot_default.tif b/Assets/Engine/EngineAssets/Textures/defaults/spot_default.tif similarity index 100% rename from Engine/EngineAssets/Textures/defaults/spot_default.tif rename to Assets/Engine/EngineAssets/Textures/defaults/spot_default.tif diff --git a/Engine/EngineAssets/Textures/detailDecalVariation.tif b/Assets/Engine/EngineAssets/Textures/detailDecalVariation.tif similarity index 100% rename from Engine/EngineAssets/Textures/detailDecalVariation.tif rename to Assets/Engine/EngineAssets/Textures/detailDecalVariation.tif diff --git a/Engine/EngineAssets/Textures/dither_2.dds b/Assets/Engine/EngineAssets/Textures/dither_2.dds similarity index 100% rename from Engine/EngineAssets/Textures/dither_2.dds rename to Assets/Engine/EngineAssets/Textures/dither_2.dds diff --git a/Engine/EngineAssets/Textures/dither_pattern_2d.dds b/Assets/Engine/EngineAssets/Textures/dither_pattern_2d.dds similarity index 100% rename from Engine/EngineAssets/Textures/dither_pattern_2d.dds rename to Assets/Engine/EngineAssets/Textures/dither_pattern_2d.dds diff --git a/Engine/EngineAssets/Textures/flares/Flare_Glow001.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_Glow001.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_Glow001.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_Glow001.tif diff --git a/Engine/EngineAssets/Textures/flares/Flare_Glow002.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_Glow002.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_Glow002.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_Glow002.tif diff --git a/Engine/EngineAssets/Textures/flares/Flare_Orbs001.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_Orbs001.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_Orbs001.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_Orbs001.tif diff --git a/Engine/EngineAssets/Textures/flares/Flare_SoftSpot001.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_SoftSpot001.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_SoftSpot001.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_SoftSpot001.tif diff --git a/Engine/EngineAssets/Textures/flares/Flare_SoftSpot002.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_SoftSpot002.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_SoftSpot002.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_SoftSpot002.tif diff --git a/Engine/EngineAssets/Textures/flares/Flare_Sun001.tif b/Assets/Engine/EngineAssets/Textures/flares/Flare_Sun001.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/Flare_Sun001.tif rename to Assets/Engine/EngineAssets/Textures/flares/Flare_Sun001.tif diff --git a/Engine/EngineAssets/Textures/flares/flare01.tif b/Assets/Engine/EngineAssets/Textures/flares/flare01.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/flare01.tif rename to Assets/Engine/EngineAssets/Textures/flares/flare01.tif diff --git a/Engine/EngineAssets/Textures/flares/flare02.tif b/Assets/Engine/EngineAssets/Textures/flares/flare02.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/flare02.tif rename to Assets/Engine/EngineAssets/Textures/flares/flare02.tif diff --git a/Engine/EngineAssets/Textures/flares/ghost_grey.tif b/Assets/Engine/EngineAssets/Textures/flares/ghost_grey.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/ghost_grey.tif rename to Assets/Engine/EngineAssets/Textures/flares/ghost_grey.tif diff --git a/Engine/EngineAssets/Textures/flares/ghost_multicolor.tif b/Assets/Engine/EngineAssets/Textures/flares/ghost_multicolor.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/ghost_multicolor.tif rename to Assets/Engine/EngineAssets/Textures/flares/ghost_multicolor.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/ghost.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/ghost.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/ghost.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/ghost.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/ghost.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/ghost.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/ghost.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/ghost.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/glow.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/glow.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/glow.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/glow.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/glow.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/glow.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/glow.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/glow.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/iris_shafts.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/multi_ghost.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/orbs.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/orbs.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/orbs.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/orbs.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/orbs.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/orbs.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/orbs.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/orbs.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/ring.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/ring.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/ring.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/ring.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/ring.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/ring.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/ring.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/ring.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/test_demo.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/test_demo.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/test_demo.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/test_demo.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/test_demo.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/test_demo.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/test_demo.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/test_demo.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif b/Assets/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif rename to Assets/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif diff --git a/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/flares/icons/vol_shafts.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/flares/iris_shaft.tif b/Assets/Engine/EngineAssets/Textures/flares/iris_shaft.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/iris_shaft.tif rename to Assets/Engine/EngineAssets/Textures/flares/iris_shaft.tif diff --git a/Engine/EngineAssets/Textures/flares/lens_blurshape.tif b/Assets/Engine/EngineAssets/Textures/flares/lens_blurshape.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/lens_blurshape.tif rename to Assets/Engine/EngineAssets/Textures/flares/lens_blurshape.tif diff --git a/Engine/EngineAssets/Textures/flares/lens_dirtyglass.tif b/Assets/Engine/EngineAssets/Textures/flares/lens_dirtyglass.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/lens_dirtyglass.tif rename to Assets/Engine/EngineAssets/Textures/flares/lens_dirtyglass.tif diff --git a/Engine/EngineAssets/Textures/flares/lens_noise01.tif b/Assets/Engine/EngineAssets/Textures/flares/lens_noise01.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/lens_noise01.tif rename to Assets/Engine/EngineAssets/Textures/flares/lens_noise01.tif diff --git a/Engine/EngineAssets/Textures/flares/lens_raindrops.tif b/Assets/Engine/EngineAssets/Textures/flares/lens_raindrops.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/lens_raindrops.tif rename to Assets/Engine/EngineAssets/Textures/flares/lens_raindrops.tif diff --git a/Engine/EngineAssets/Textures/flares/lens_raindrops02.tif b/Assets/Engine/EngineAssets/Textures/flares/lens_raindrops02.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/lens_raindrops02.tif rename to Assets/Engine/EngineAssets/Textures/flares/lens_raindrops02.tif diff --git a/Engine/EngineAssets/Textures/flares/orb_01.tif b/Assets/Engine/EngineAssets/Textures/flares/orb_01.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/orb_01.tif rename to Assets/Engine/EngineAssets/Textures/flares/orb_01.tif diff --git a/Engine/EngineAssets/Textures/flares/orb_cell01.tif b/Assets/Engine/EngineAssets/Textures/flares/orb_cell01.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/orb_cell01.tif rename to Assets/Engine/EngineAssets/Textures/flares/orb_cell01.tif diff --git a/Engine/EngineAssets/Textures/flares/orb_cell02.tif b/Assets/Engine/EngineAssets/Textures/flares/orb_cell02.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/orb_cell02.tif rename to Assets/Engine/EngineAssets/Textures/flares/orb_cell02.tif diff --git a/Engine/EngineAssets/Textures/flares/orb_cell03.tif b/Assets/Engine/EngineAssets/Textures/flares/orb_cell03.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/orb_cell03.tif rename to Assets/Engine/EngineAssets/Textures/flares/orb_cell03.tif diff --git a/Engine/EngineAssets/Textures/flares/orb_cell04.tif b/Assets/Engine/EngineAssets/Textures/flares/orb_cell04.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/orb_cell04.tif rename to Assets/Engine/EngineAssets/Textures/flares/orb_cell04.tif diff --git a/Engine/EngineAssets/Textures/flares/spectrum_full.tif b/Assets/Engine/EngineAssets/Textures/flares/spectrum_full.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/spectrum_full.tif rename to Assets/Engine/EngineAssets/Textures/flares/spectrum_full.tif diff --git a/Engine/EngineAssets/Textures/flares/spectrum_half.tif b/Assets/Engine/EngineAssets/Textures/flares/spectrum_half.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/spectrum_half.tif rename to Assets/Engine/EngineAssets/Textures/flares/spectrum_half.tif diff --git a/Engine/EngineAssets/Textures/flares/spectrum_quater.tif b/Assets/Engine/EngineAssets/Textures/flares/spectrum_quater.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/spectrum_quater.tif rename to Assets/Engine/EngineAssets/Textures/flares/spectrum_quater.tif diff --git a/Engine/EngineAssets/Textures/flares/spectrum_specs.tif b/Assets/Engine/EngineAssets/Textures/flares/spectrum_specs.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/spectrum_specs.tif rename to Assets/Engine/EngineAssets/Textures/flares/spectrum_specs.tif diff --git a/Engine/EngineAssets/Textures/flares/streak01.tif b/Assets/Engine/EngineAssets/Textures/flares/streak01.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/streak01.tif rename to Assets/Engine/EngineAssets/Textures/flares/streak01.tif diff --git a/Engine/EngineAssets/Textures/flares/visor_scratch.tif b/Assets/Engine/EngineAssets/Textures/flares/visor_scratch.tif similarity index 100% rename from Engine/EngineAssets/Textures/flares/visor_scratch.tif rename to Assets/Engine/EngineAssets/Textures/flares/visor_scratch.tif diff --git a/Engine/EngineAssets/Textures/fresnel_sampler.dds b/Assets/Engine/EngineAssets/Textures/fresnel_sampler.dds similarity index 100% rename from Engine/EngineAssets/Textures/fresnel_sampler.dds rename to Assets/Engine/EngineAssets/Textures/fresnel_sampler.dds diff --git a/Engine/EngineAssets/Textures/fringe_map.dds b/Assets/Engine/EngineAssets/Textures/fringe_map.dds similarity index 100% rename from Engine/EngineAssets/Textures/fringe_map.dds rename to Assets/Engine/EngineAssets/Textures/fringe_map.dds diff --git a/Engine/EngineAssets/Textures/frost_refl2.tif b/Assets/Engine/EngineAssets/Textures/frost_refl2.tif similarity index 100% rename from Engine/EngineAssets/Textures/frost_refl2.tif rename to Assets/Engine/EngineAssets/Textures/frost_refl2.tif diff --git a/Engine/EngineAssets/Textures/frost_refl2.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/frost_refl2.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/frost_refl2.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/frost_refl2.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/fuzzy_pow_sampler_merged.dds b/Assets/Engine/EngineAssets/Textures/fuzzy_pow_sampler_merged.dds similarity index 100% rename from Engine/EngineAssets/Textures/fuzzy_pow_sampler_merged.dds rename to Assets/Engine/EngineAssets/Textures/fuzzy_pow_sampler_merged.dds diff --git a/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif b/Assets/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif rename to Assets/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif diff --git a/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/glass_decalatlas_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif b/Assets/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif similarity index 100% rename from Engine/EngineAssets/Textures/glass_decalatlas_diff.tif rename to Assets/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif diff --git a/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/glass_decalatlas_diff.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/glass_decalatlas_diff.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/grey.dds b/Assets/Engine/EngineAssets/Textures/grey.dds similarity index 100% rename from Engine/EngineAssets/Textures/grey.dds rename to Assets/Engine/EngineAssets/Textures/grey.dds diff --git a/Engine/EngineAssets/Textures/hex.tif b/Assets/Engine/EngineAssets/Textures/hex.tif similarity index 100% rename from Engine/EngineAssets/Textures/hex.tif rename to Assets/Engine/EngineAssets/Textures/hex.tif diff --git a/Engine/EngineAssets/Textures/hex.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hex.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hex.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hex.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hex_ddn.tif b/Assets/Engine/EngineAssets/Textures/hex_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/hex_ddn.tif rename to Assets/Engine/EngineAssets/Textures/hex_ddn.tif diff --git a/Engine/EngineAssets/Textures/hex_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hex_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hex_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hex_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hex_grad.tif b/Assets/Engine/EngineAssets/Textures/hex_grad.tif similarity index 100% rename from Engine/EngineAssets/Textures/hex_grad.tif rename to Assets/Engine/EngineAssets/Textures/hex_grad.tif diff --git a/Engine/EngineAssets/Textures/hex_grad.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hex_grad.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hex_grad.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hex_grad.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hex_line.tif b/Assets/Engine/EngineAssets/Textures/hex_line.tif similarity index 100% rename from Engine/EngineAssets/Textures/hex_line.tif rename to Assets/Engine/EngineAssets/Textures/hex_line.tif diff --git a/Engine/EngineAssets/Textures/hex_line.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hex_line.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hex_line.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hex_line.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hex_rand.tif b/Assets/Engine/EngineAssets/Textures/hex_rand.tif similarity index 100% rename from Engine/EngineAssets/Textures/hex_rand.tif rename to Assets/Engine/EngineAssets/Textures/hex_rand.tif diff --git a/Engine/EngineAssets/Textures/hex_rand.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hex_rand.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hex_rand.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hex_rand.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_areas.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_areas.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_areas.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_areas.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_areas.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_areas.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_areas.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_areas.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_blurmask_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_healthgradient.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_healthgradient.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_healthgradient.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_lvlgradient.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_round.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_round.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_round.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_round.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_round.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_round.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_round.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_round.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif b/Assets/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_veinsblood.tif rename to Assets/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif diff --git a/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/hiteffect_veinsblood.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/hiteffect_veinsblood.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/interference.dds b/Assets/Engine/EngineAssets/Textures/interference.dds similarity index 100% rename from Engine/EngineAssets/Textures/interference.dds rename to Assets/Engine/EngineAssets/Textures/interference.dds diff --git a/Engine/EngineAssets/Textures/jumpnoisehighfrequency_x27y19.dds b/Assets/Engine/EngineAssets/Textures/jumpnoisehighfrequency_x27y19.dds similarity index 100% rename from Engine/EngineAssets/Textures/jumpnoisehighfrequency_x27y19.dds rename to Assets/Engine/EngineAssets/Textures/jumpnoisehighfrequency_x27y19.dds diff --git a/Engine/EngineAssets/Textures/moisturedroplets.tif b/Assets/Engine/EngineAssets/Textures/moisturedroplets.tif similarity index 100% rename from Engine/EngineAssets/Textures/moisturedroplets.tif rename to Assets/Engine/EngineAssets/Textures/moisturedroplets.tif diff --git a/Engine/EngineAssets/Textures/moisturedroplets.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/moisturedroplets.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/moisturedroplets.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/moisturedroplets.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/nightvis_grad.tif b/Assets/Engine/EngineAssets/Textures/nightvis_grad.tif similarity index 100% rename from Engine/EngineAssets/Textures/nightvis_grad.tif rename to Assets/Engine/EngineAssets/Textures/nightvis_grad.tif diff --git a/Engine/EngineAssets/Textures/nightvis_grad.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/nightvis_grad.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/nightvis_grad.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/nightvis_grad.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/noise.tif b/Assets/Engine/EngineAssets/Textures/noise.tif similarity index 100% rename from Engine/EngineAssets/Textures/noise.tif rename to Assets/Engine/EngineAssets/Textures/noise.tif diff --git a/Engine/EngineAssets/Textures/noise3d.dds b/Assets/Engine/EngineAssets/Textures/noise3d.dds similarity index 100% rename from Engine/EngineAssets/Textures/noise3d.dds rename to Assets/Engine/EngineAssets/Textures/noise3d.dds diff --git a/Engine/EngineAssets/Textures/oceanwaves_ddn.tif b/Assets/Engine/EngineAssets/Textures/oceanwaves_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/oceanwaves_ddn.tif rename to Assets/Engine/EngineAssets/Textures/oceanwaves_ddn.tif diff --git a/Engine/EngineAssets/Textures/oceanwaves_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/oceanwaves_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/oceanwaves_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/oceanwaves_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/palletteInst.dds b/Assets/Engine/EngineAssets/Textures/palletteInst.dds similarity index 100% rename from Engine/EngineAssets/Textures/palletteInst.dds rename to Assets/Engine/EngineAssets/Textures/palletteInst.dds diff --git a/Engine/EngineAssets/Textures/perlinNoise2d.tif b/Assets/Engine/EngineAssets/Textures/perlinNoise2d.tif similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise2d.tif rename to Assets/Engine/EngineAssets/Textures/perlinNoise2d.tif diff --git a/Engine/EngineAssets/Textures/perlinNoise2d.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/perlinNoise2d.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise2d.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/perlinNoise2d.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif b/Assets/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif rename to Assets/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif diff --git a/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/perlinNoiseDerivatives.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif b/Assets/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif rename to Assets/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif diff --git a/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/perlinNoiseNormal_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/perlinNoise_sum.tif b/Assets/Engine/EngineAssets/Textures/perlinNoise_sum.tif similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise_sum.tif rename to Assets/Engine/EngineAssets/Textures/perlinNoise_sum.tif diff --git a/Engine/EngineAssets/Textures/perlinNoise_sum.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/perlinNoise_sum.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise_sum.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/perlinNoise_sum.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif b/Assets/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise_sum_small.tif rename to Assets/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif diff --git a/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/perlinNoise_sum_small.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/perlinNoise_sum_small.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/pixeltex.dds b/Assets/Engine/EngineAssets/Textures/pixeltex.dds similarity index 100% rename from Engine/EngineAssets/Textures/pixeltex.dds rename to Assets/Engine/EngineAssets/Textures/pixeltex.dds diff --git a/Engine/EngineAssets/Textures/rotrandomcm.dds b/Assets/Engine/EngineAssets/Textures/rotrandomcm.dds similarity index 100% rename from Engine/EngineAssets/Textures/rotrandomcm.dds rename to Assets/Engine/EngineAssets/Textures/rotrandomcm.dds diff --git a/Engine/EngineAssets/Textures/scratch.tif b/Assets/Engine/EngineAssets/Textures/scratch.tif similarity index 100% rename from Engine/EngineAssets/Textures/scratch.tif rename to Assets/Engine/EngineAssets/Textures/scratch.tif diff --git a/Engine/EngineAssets/Textures/scratch.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/scratch.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/scratch.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/scratch.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/scratch_ddn.tif b/Assets/Engine/EngineAssets/Textures/scratch_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/scratch_ddn.tif rename to Assets/Engine/EngineAssets/Textures/scratch_ddn.tif diff --git a/Engine/EngineAssets/Textures/scratch_ddn.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/scratch_ddn.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/scratch_ddn.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/scratch_ddn.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/screen_noisy_bump.dds b/Assets/Engine/EngineAssets/Textures/screen_noisy_bump.dds similarity index 100% rename from Engine/EngineAssets/Textures/screen_noisy_bump.dds rename to Assets/Engine/EngineAssets/Textures/screen_noisy_bump.dds diff --git a/Engine/EngineAssets/Textures/screenfrost_alpha.TIF b/Assets/Engine/EngineAssets/Textures/screenfrost_alpha.TIF similarity index 100% rename from Engine/EngineAssets/Textures/screenfrost_alpha.TIF rename to Assets/Engine/EngineAssets/Textures/screenfrost_alpha.TIF diff --git a/Engine/EngineAssets/Textures/screenfrost_alpha.TIF.exportsettings b/Assets/Engine/EngineAssets/Textures/screenfrost_alpha.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/screenfrost_alpha.TIF.exportsettings rename to Assets/Engine/EngineAssets/Textures/screenfrost_alpha.TIF.exportsettings diff --git a/Engine/EngineAssets/Textures/screenfrost_ddn.TIF b/Assets/Engine/EngineAssets/Textures/screenfrost_ddn.TIF similarity index 100% rename from Engine/EngineAssets/Textures/screenfrost_ddn.TIF rename to Assets/Engine/EngineAssets/Textures/screenfrost_ddn.TIF diff --git a/Engine/EngineAssets/Textures/screenfrost_ddn.TIF.exportsettings b/Assets/Engine/EngineAssets/Textures/screenfrost_ddn.TIF.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/screenfrost_ddn.TIF.exportsettings rename to Assets/Engine/EngineAssets/Textures/screenfrost_ddn.TIF.exportsettings diff --git a/Engine/EngineAssets/Textures/snowflakes.tif b/Assets/Engine/EngineAssets/Textures/snowflakes.tif similarity index 100% rename from Engine/EngineAssets/Textures/snowflakes.tif rename to Assets/Engine/EngineAssets/Textures/snowflakes.tif diff --git a/Engine/EngineAssets/Textures/snowflakes.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/snowflakes.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/snowflakes.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/snowflakes.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/startscreen.tif b/Assets/Engine/EngineAssets/Textures/startscreen.tif similarity index 100% rename from Engine/EngineAssets/Textures/startscreen.tif rename to Assets/Engine/EngineAssets/Textures/startscreen.tif diff --git a/Engine/EngineAssets/Textures/startscreen.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/startscreen.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/startscreen.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/startscreen.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/user_tex1.tif b/Assets/Engine/EngineAssets/Textures/user_tex1.tif similarity index 100% rename from Engine/EngineAssets/Textures/user_tex1.tif rename to Assets/Engine/EngineAssets/Textures/user_tex1.tif diff --git a/Engine/EngineAssets/Textures/user_tex2.tif b/Assets/Engine/EngineAssets/Textures/user_tex2.tif similarity index 100% rename from Engine/EngineAssets/Textures/user_tex2.tif rename to Assets/Engine/EngineAssets/Textures/user_tex2.tif diff --git a/Engine/EngineAssets/Textures/vector_noise.dds b/Assets/Engine/EngineAssets/Textures/vector_noise.dds similarity index 100% rename from Engine/EngineAssets/Textures/vector_noise.dds rename to Assets/Engine/EngineAssets/Textures/vector_noise.dds diff --git a/Engine/EngineAssets/Textures/water_droplets.dds b/Assets/Engine/EngineAssets/Textures/water_droplets.dds similarity index 100% rename from Engine/EngineAssets/Textures/water_droplets.dds rename to Assets/Engine/EngineAssets/Textures/water_droplets.dds diff --git a/Engine/EngineAssets/Textures/water_gloss.tif b/Assets/Engine/EngineAssets/Textures/water_gloss.tif similarity index 100% rename from Engine/EngineAssets/Textures/water_gloss.tif rename to Assets/Engine/EngineAssets/Textures/water_gloss.tif diff --git a/Engine/EngineAssets/Textures/water_gloss.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/water_gloss.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/water_gloss.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/water_gloss.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/white.tif b/Assets/Engine/EngineAssets/Textures/white.tif similarity index 100% rename from Engine/EngineAssets/Textures/white.tif rename to Assets/Engine/EngineAssets/Textures/white.tif diff --git a/Engine/EngineAssets/Textures/white.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/white.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/white.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/white.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/white_cm.tif b/Assets/Engine/EngineAssets/Textures/white_cm.tif similarity index 100% rename from Engine/EngineAssets/Textures/white_cm.tif rename to Assets/Engine/EngineAssets/Textures/white_cm.tif diff --git a/Engine/EngineAssets/Textures/white_cm.tif.exportsettings b/Assets/Engine/EngineAssets/Textures/white_cm.tif.exportsettings similarity index 100% rename from Engine/EngineAssets/Textures/white_cm.tif.exportsettings rename to Assets/Engine/EngineAssets/Textures/white_cm.tif.exportsettings diff --git a/Engine/EngineAssets/Textures/white_ddn.tif b/Assets/Engine/EngineAssets/Textures/white_ddn.tif similarity index 100% rename from Engine/EngineAssets/Textures/white_ddn.tif rename to Assets/Engine/EngineAssets/Textures/white_ddn.tif diff --git a/Engine/EngineAssets/defaulttextures.xml b/Assets/Engine/EngineAssets/defaulttextures.xml similarity index 100% rename from Engine/EngineAssets/defaulttextures.xml rename to Assets/Engine/EngineAssets/defaulttextures.xml diff --git a/Engine/Engine_Dependencies.xml b/Assets/Engine/Engine_Dependencies.xml similarity index 100% rename from Engine/Engine_Dependencies.xml rename to Assets/Engine/Engine_Dependencies.xml diff --git a/Engine/Entities/AnimObject.ent b/Assets/Engine/Entities/AnimObject.ent similarity index 100% rename from Engine/Entities/AnimObject.ent rename to Assets/Engine/Entities/AnimObject.ent diff --git a/Engine/Entities/AreaBezierVolume.ent b/Assets/Engine/Entities/AreaBezierVolume.ent similarity index 100% rename from Engine/Entities/AreaBezierVolume.ent rename to Assets/Engine/Entities/AreaBezierVolume.ent diff --git a/Engine/Entities/AreaBox.ent b/Assets/Engine/Entities/AreaBox.ent similarity index 100% rename from Engine/Entities/AreaBox.ent rename to Assets/Engine/Entities/AreaBox.ent diff --git a/Engine/Entities/AreaShape.ent b/Assets/Engine/Entities/AreaShape.ent similarity index 100% rename from Engine/Entities/AreaShape.ent rename to Assets/Engine/Entities/AreaShape.ent diff --git a/Engine/Entities/AreaSolid.ent b/Assets/Engine/Entities/AreaSolid.ent similarity index 100% rename from Engine/Entities/AreaSolid.ent rename to Assets/Engine/Entities/AreaSolid.ent diff --git a/Engine/Entities/AreaSphere.ent b/Assets/Engine/Entities/AreaSphere.ent similarity index 100% rename from Engine/Entities/AreaSphere.ent rename to Assets/Engine/Entities/AreaSphere.ent diff --git a/Engine/Entities/AreaTrigger.ent b/Assets/Engine/Entities/AreaTrigger.ent similarity index 100% rename from Engine/Entities/AreaTrigger.ent rename to Assets/Engine/Entities/AreaTrigger.ent diff --git a/Engine/Entities/AudioAreaAmbience.ent b/Assets/Engine/Entities/AudioAreaAmbience.ent similarity index 100% rename from Engine/Entities/AudioAreaAmbience.ent rename to Assets/Engine/Entities/AudioAreaAmbience.ent diff --git a/Engine/Entities/AudioAreaEntity.ent b/Assets/Engine/Entities/AudioAreaEntity.ent similarity index 100% rename from Engine/Entities/AudioAreaEntity.ent rename to Assets/Engine/Entities/AudioAreaEntity.ent diff --git a/Engine/Entities/AudioAreaRandom.ent b/Assets/Engine/Entities/AudioAreaRandom.ent similarity index 100% rename from Engine/Entities/AudioAreaRandom.ent rename to Assets/Engine/Entities/AudioAreaRandom.ent diff --git a/Engine/Entities/AudioTriggerSpot.ent b/Assets/Engine/Entities/AudioTriggerSpot.ent similarity index 100% rename from Engine/Entities/AudioTriggerSpot.ent rename to Assets/Engine/Entities/AudioTriggerSpot.ent diff --git a/Engine/Entities/BasicEntity.ent b/Assets/Engine/Entities/BasicEntity.ent similarity index 100% rename from Engine/Entities/BasicEntity.ent rename to Assets/Engine/Entities/BasicEntity.ent diff --git a/Engine/Entities/CActorWrapper.ent b/Assets/Engine/Entities/CActorWrapper.ent similarity index 100% rename from Engine/Entities/CActorWrapper.ent rename to Assets/Engine/Entities/CActorWrapper.ent diff --git a/Engine/Entities/CameraSource.ent b/Assets/Engine/Entities/CameraSource.ent similarity index 100% rename from Engine/Entities/CameraSource.ent rename to Assets/Engine/Entities/CameraSource.ent diff --git a/Engine/Entities/CameraTarget.ent b/Assets/Engine/Entities/CameraTarget.ent similarity index 100% rename from Engine/Entities/CameraTarget.ent rename to Assets/Engine/Entities/CameraTarget.ent diff --git a/Engine/Entities/Comment.ent b/Assets/Engine/Entities/Comment.ent similarity index 100% rename from Engine/Entities/Comment.ent rename to Assets/Engine/Entities/Comment.ent diff --git a/Engine/Entities/EnvironmentLight.ent b/Assets/Engine/Entities/EnvironmentLight.ent similarity index 100% rename from Engine/Entities/EnvironmentLight.ent rename to Assets/Engine/Entities/EnvironmentLight.ent diff --git a/Engine/Entities/FogVolume.ent b/Assets/Engine/Entities/FogVolume.ent similarity index 100% rename from Engine/Entities/FogVolume.ent rename to Assets/Engine/Entities/FogVolume.ent diff --git a/Engine/Entities/GeomCache.ent b/Assets/Engine/Entities/GeomCache.ent similarity index 100% rename from Engine/Entities/GeomCache.ent rename to Assets/Engine/Entities/GeomCache.ent diff --git a/Engine/Entities/Light.ent b/Assets/Engine/Entities/Light.ent similarity index 100% rename from Engine/Entities/Light.ent rename to Assets/Engine/Entities/Light.ent diff --git a/Engine/Entities/LivingEntity.ent b/Assets/Engine/Entities/LivingEntity.ent similarity index 100% rename from Engine/Entities/LivingEntity.ent rename to Assets/Engine/Entities/LivingEntity.ent diff --git a/Engine/Entities/NavigationSeedPoint.ent b/Assets/Engine/Entities/NavigationSeedPoint.ent similarity index 100% rename from Engine/Entities/NavigationSeedPoint.ent rename to Assets/Engine/Entities/NavigationSeedPoint.ent diff --git a/Engine/Entities/ParticleEffect.ent b/Assets/Engine/Entities/ParticleEffect.ent similarity index 100% rename from Engine/Entities/ParticleEffect.ent rename to Assets/Engine/Entities/ParticleEffect.ent diff --git a/Engine/Entities/ProceduralObject.ent b/Assets/Engine/Entities/ProceduralObject.ent similarity index 100% rename from Engine/Entities/ProceduralObject.ent rename to Assets/Engine/Entities/ProceduralObject.ent diff --git a/Engine/Entities/ProximityTrigger.ent b/Assets/Engine/Entities/ProximityTrigger.ent similarity index 100% rename from Engine/Entities/ProximityTrigger.ent rename to Assets/Engine/Entities/ProximityTrigger.ent diff --git a/Engine/Entities/RigidBody.ent b/Assets/Engine/Entities/RigidBody.ent similarity index 100% rename from Engine/Entities/RigidBody.ent rename to Assets/Engine/Entities/RigidBody.ent diff --git a/Engine/Entities/RigidBodyEx.ent b/Assets/Engine/Entities/RigidBodyEx.ent similarity index 100% rename from Engine/Entities/RigidBodyEx.ent rename to Assets/Engine/Entities/RigidBodyEx.ent diff --git a/Engine/Entities/SmartObject.ent b/Assets/Engine/Entities/SmartObject.ent similarity index 100% rename from Engine/Entities/SmartObject.ent rename to Assets/Engine/Entities/SmartObject.ent diff --git a/Engine/Entities/TagPoint.ent b/Assets/Engine/Entities/TagPoint.ent similarity index 100% rename from Engine/Entities/TagPoint.ent rename to Assets/Engine/Entities/TagPoint.ent diff --git a/Engine/Entities/UiCanvasRef.ent b/Assets/Engine/Entities/UiCanvasRef.ent similarity index 100% rename from Engine/Entities/UiCanvasRef.ent rename to Assets/Engine/Entities/UiCanvasRef.ent diff --git a/Engine/Fonts/Vera.ttf b/Assets/Engine/Fonts/Vera.ttf similarity index 100% rename from Engine/Fonts/Vera.ttf rename to Assets/Engine/Fonts/Vera.ttf diff --git a/Engine/Fonts/VeraMono.ttf b/Assets/Engine/Fonts/VeraMono.ttf similarity index 100% rename from Engine/Fonts/VeraMono.ttf rename to Assets/Engine/Fonts/VeraMono.ttf diff --git a/Engine/Fonts/Vera_COPYRIGHT.TXT b/Assets/Engine/Fonts/Vera_COPYRIGHT.TXT similarity index 100% rename from Engine/Fonts/Vera_COPYRIGHT.TXT rename to Assets/Engine/Fonts/Vera_COPYRIGHT.TXT diff --git a/Engine/Fonts/Vera_RELEASENOTES.TXT b/Assets/Engine/Fonts/Vera_RELEASENOTES.TXT similarity index 100% rename from Engine/Fonts/Vera_RELEASENOTES.TXT rename to Assets/Engine/Fonts/Vera_RELEASENOTES.TXT diff --git a/Engine/Fonts/console.font b/Assets/Engine/Fonts/console.font similarity index 100% rename from Engine/Fonts/console.font rename to Assets/Engine/Fonts/console.font diff --git a/Engine/Fonts/console.xml b/Assets/Engine/Fonts/console.xml similarity index 100% rename from Engine/Fonts/console.xml rename to Assets/Engine/Fonts/console.xml diff --git a/Engine/Fonts/default-ui.font b/Assets/Engine/Fonts/default-ui.font similarity index 100% rename from Engine/Fonts/default-ui.font rename to Assets/Engine/Fonts/default-ui.font diff --git a/Engine/Fonts/default-ui.xml b/Assets/Engine/Fonts/default-ui.xml similarity index 100% rename from Engine/Fonts/default-ui.xml rename to Assets/Engine/Fonts/default-ui.xml diff --git a/Engine/Fonts/default.font b/Assets/Engine/Fonts/default.font similarity index 100% rename from Engine/Fonts/default.font rename to Assets/Engine/Fonts/default.font diff --git a/Engine/Fonts/default.xml b/Assets/Engine/Fonts/default.xml similarity index 100% rename from Engine/Fonts/default.xml rename to Assets/Engine/Fonts/default.xml diff --git a/Engine/Fonts/hud.font b/Assets/Engine/Fonts/hud.font similarity index 100% rename from Engine/Fonts/hud.font rename to Assets/Engine/Fonts/hud.font diff --git a/Engine/Fonts/hud.xml b/Assets/Engine/Fonts/hud.xml similarity index 100% rename from Engine/Fonts/hud.xml rename to Assets/Engine/Fonts/hud.xml diff --git a/Engine/Libs/MaterialEffects/FXLibs/collisions.xml b/Assets/Engine/Libs/MaterialEffects/FXLibs/collisions.xml similarity index 100% rename from Engine/Libs/MaterialEffects/FXLibs/collisions.xml rename to Assets/Engine/Libs/MaterialEffects/FXLibs/collisions.xml diff --git a/Engine/Libs/MaterialEffects/materialeffects.xml b/Assets/Engine/Libs/MaterialEffects/materialeffects.xml similarity index 100% rename from Engine/Libs/MaterialEffects/materialeffects.xml rename to Assets/Engine/Libs/MaterialEffects/materialeffects.xml diff --git a/Engine/Libs/MaterialEffects/surfacetypes.xml b/Assets/Engine/Libs/MaterialEffects/surfacetypes.xml similarity index 100% rename from Engine/Libs/MaterialEffects/surfacetypes.xml rename to Assets/Engine/Libs/MaterialEffects/surfacetypes.xml diff --git a/Engine/Libs/PostEffectGroups/Default.xml b/Assets/Engine/Libs/PostEffectGroups/Default.xml similarity index 100% rename from Engine/Libs/PostEffectGroups/Default.xml rename to Assets/Engine/Libs/PostEffectGroups/Default.xml diff --git a/Engine/Objects/default/editorprimitive.mtl b/Assets/Engine/Objects/default/editorprimitive.mtl similarity index 100% rename from Engine/Objects/default/editorprimitive.mtl rename to Assets/Engine/Objects/default/editorprimitive.mtl diff --git a/Engine/Objects/default/primitive_capsule.cgf b/Assets/Engine/Objects/default/primitive_capsule.cgf similarity index 100% rename from Engine/Objects/default/primitive_capsule.cgf rename to Assets/Engine/Objects/default/primitive_capsule.cgf diff --git a/Engine/Objects/default/primitive_cube.cgf b/Assets/Engine/Objects/default/primitive_cube.cgf similarity index 100% rename from Engine/Objects/default/primitive_cube.cgf rename to Assets/Engine/Objects/default/primitive_cube.cgf diff --git a/Engine/Objects/default/primitive_plane.cgf b/Assets/Engine/Objects/default/primitive_plane.cgf similarity index 100% rename from Engine/Objects/default/primitive_plane.cgf rename to Assets/Engine/Objects/default/primitive_plane.cgf diff --git a/Engine/Objects/default/primitive_sphere.cgf b/Assets/Engine/Objects/default/primitive_sphere.cgf similarity index 100% rename from Engine/Objects/default/primitive_sphere.cgf rename to Assets/Engine/Objects/default/primitive_sphere.cgf diff --git a/Engine/Schema/Environment.xmlschema b/Assets/Engine/Schema/Environment.xmlschema similarity index 100% rename from Engine/Schema/Environment.xmlschema rename to Assets/Engine/Schema/Environment.xmlschema diff --git a/Engine/Schema/FlaresLibrary.xmlschema b/Assets/Engine/Schema/FlaresLibrary.xmlschema similarity index 100% rename from Engine/Schema/FlaresLibrary.xmlschema rename to Assets/Engine/Schema/FlaresLibrary.xmlschema diff --git a/Engine/Schema/Font.xmlschema b/Assets/Engine/Schema/Font.xmlschema similarity index 100% rename from Engine/Schema/Font.xmlschema rename to Assets/Engine/Schema/Font.xmlschema diff --git a/Engine/Schema/ParticleLibrary.xmlschema b/Assets/Engine/Schema/ParticleLibrary.xmlschema similarity index 100% rename from Engine/Schema/ParticleLibrary.xmlschema rename to Assets/Engine/Schema/ParticleLibrary.xmlschema diff --git a/Engine/Schema/cloudlibrary.xmlschema b/Assets/Engine/Schema/cloudlibrary.xmlschema similarity index 100% rename from Engine/Schema/cloudlibrary.xmlschema rename to Assets/Engine/Schema/cloudlibrary.xmlschema diff --git a/Engine/Schema/editorappdescriptor.xmlschema b/Assets/Engine/Schema/editorappdescriptor.xmlschema similarity index 100% rename from Engine/Schema/editorappdescriptor.xmlschema rename to Assets/Engine/Schema/editorappdescriptor.xmlschema diff --git a/Engine/Schema/enginedependency.xmlschema b/Assets/Engine/Schema/enginedependency.xmlschema similarity index 100% rename from Engine/Schema/enginedependency.xmlschema rename to Assets/Engine/Schema/enginedependency.xmlschema diff --git a/Engine/Schema/ent.xmlschema b/Assets/Engine/Schema/ent.xmlschema similarity index 100% rename from Engine/Schema/ent.xmlschema rename to Assets/Engine/Schema/ent.xmlschema diff --git a/Engine/Schema/gameappdescriptor.xmlschema b/Assets/Engine/Schema/gameappdescriptor.xmlschema similarity index 100% rename from Engine/Schema/gameappdescriptor.xmlschema rename to Assets/Engine/Schema/gameappdescriptor.xmlschema diff --git a/Engine/Schema/materialeffectlibrary.xmlschema b/Assets/Engine/Schema/materialeffectlibrary.xmlschema similarity index 100% rename from Engine/Schema/materialeffectlibrary.xmlschema rename to Assets/Engine/Schema/materialeffectlibrary.xmlschema diff --git a/Engine/Schema/materialeffects.xmlschema b/Assets/Engine/Schema/materialeffects.xmlschema similarity index 100% rename from Engine/Schema/materialeffects.xmlschema rename to Assets/Engine/Schema/materialeffects.xmlschema diff --git a/Engine/Schema/rainandsnowtextures.xmlschema b/Assets/Engine/Schema/rainandsnowtextures.xmlschema similarity index 100% rename from Engine/Schema/rainandsnowtextures.xmlschema rename to Assets/Engine/Schema/rainandsnowtextures.xmlschema diff --git a/Engine/Schema/surfacetypes.xmlschema b/Assets/Engine/Schema/surfacetypes.xmlschema similarity index 100% rename from Engine/Schema/surfacetypes.xmlschema rename to Assets/Engine/Schema/surfacetypes.xmlschema diff --git a/Engine/Schema/vegdescriptorlist.xmlschema b/Assets/Engine/Schema/vegdescriptorlist.xmlschema similarity index 100% rename from Engine/Schema/vegdescriptorlist.xmlschema rename to Assets/Engine/Schema/vegdescriptorlist.xmlschema diff --git a/Engine/Scripts/EngineCommon.lua b/Assets/Engine/Scripts/EngineCommon.lua similarity index 100% rename from Engine/Scripts/EngineCommon.lua rename to Assets/Engine/Scripts/EngineCommon.lua diff --git a/Engine/Scripts/Entities/AI/NavigationSeedPoint.lua b/Assets/Engine/Scripts/Entities/AI/NavigationSeedPoint.lua similarity index 100% rename from Engine/Scripts/Entities/AI/NavigationSeedPoint.lua rename to Assets/Engine/Scripts/Entities/AI/NavigationSeedPoint.lua diff --git a/Engine/Scripts/Entities/AI/SmartObject.lua b/Assets/Engine/Scripts/Entities/AI/SmartObject.lua similarity index 100% rename from Engine/Scripts/Entities/AI/SmartObject.lua rename to Assets/Engine/Scripts/Entities/AI/SmartObject.lua diff --git a/Engine/Scripts/Entities/AI/TagPoint.lua b/Assets/Engine/Scripts/Entities/AI/TagPoint.lua similarity index 100% rename from Engine/Scripts/Entities/AI/TagPoint.lua rename to Assets/Engine/Scripts/Entities/AI/TagPoint.lua diff --git a/Engine/Scripts/Entities/Actor/CActorWrapper.lua b/Assets/Engine/Scripts/Entities/Actor/CActorWrapper.lua similarity index 100% rename from Engine/Scripts/Entities/Actor/CActorWrapper.lua rename to Assets/Engine/Scripts/Entities/Actor/CActorWrapper.lua diff --git a/Engine/Scripts/Entities/Anim/MannequinObject.lua b/Assets/Engine/Scripts/Entities/Anim/MannequinObject.lua similarity index 100% rename from Engine/Scripts/Entities/Anim/MannequinObject.lua rename to Assets/Engine/Scripts/Entities/Anim/MannequinObject.lua diff --git a/Engine/Scripts/Entities/Default/GeomEntity.lua b/Assets/Engine/Scripts/Entities/Default/GeomEntity.lua similarity index 100% rename from Engine/Scripts/Entities/Default/GeomEntity.lua rename to Assets/Engine/Scripts/Entities/Default/GeomEntity.lua diff --git a/Engine/Scripts/Entities/Default/RopeEntity.lua b/Assets/Engine/Scripts/Entities/Default/RopeEntity.lua similarity index 100% rename from Engine/Scripts/Entities/Default/RopeEntity.lua rename to Assets/Engine/Scripts/Entities/Default/RopeEntity.lua diff --git a/Engine/Scripts/Entities/Environment/WaterVolume.lua b/Assets/Engine/Scripts/Entities/Environment/WaterVolume.lua similarity index 100% rename from Engine/Scripts/Entities/Environment/WaterVolume.lua rename to Assets/Engine/Scripts/Entities/Environment/WaterVolume.lua diff --git a/Engine/Scripts/Entities/Lights/EnvironmentLight.lua b/Assets/Engine/Scripts/Entities/Lights/EnvironmentLight.lua similarity index 100% rename from Engine/Scripts/Entities/Lights/EnvironmentLight.lua rename to Assets/Engine/Scripts/Entities/Lights/EnvironmentLight.lua diff --git a/Engine/Scripts/Entities/Lights/Light.lua b/Assets/Engine/Scripts/Entities/Lights/Light.lua similarity index 100% rename from Engine/Scripts/Entities/Lights/Light.lua rename to Assets/Engine/Scripts/Entities/Lights/Light.lua diff --git a/Engine/Scripts/Entities/Others/CameraSource.lua b/Assets/Engine/Scripts/Entities/Others/CameraSource.lua similarity index 100% rename from Engine/Scripts/Entities/Others/CameraSource.lua rename to Assets/Engine/Scripts/Entities/Others/CameraSource.lua diff --git a/Engine/Scripts/Entities/Others/CameraTarget.lua b/Assets/Engine/Scripts/Entities/Others/CameraTarget.lua similarity index 100% rename from Engine/Scripts/Entities/Others/CameraTarget.lua rename to Assets/Engine/Scripts/Entities/Others/CameraTarget.lua diff --git a/Engine/Scripts/Entities/Others/Comment.lua b/Assets/Engine/Scripts/Entities/Others/Comment.lua similarity index 100% rename from Engine/Scripts/Entities/Others/Comment.lua rename to Assets/Engine/Scripts/Entities/Others/Comment.lua diff --git a/Engine/Scripts/Entities/Others/ProceduralObject.lua b/Assets/Engine/Scripts/Entities/Others/ProceduralObject.lua similarity index 100% rename from Engine/Scripts/Entities/Others/ProceduralObject.lua rename to Assets/Engine/Scripts/Entities/Others/ProceduralObject.lua diff --git a/Engine/Scripts/Entities/Others/RigidBody.lua b/Assets/Engine/Scripts/Entities/Others/RigidBody.lua similarity index 100% rename from Engine/Scripts/Entities/Others/RigidBody.lua rename to Assets/Engine/Scripts/Entities/Others/RigidBody.lua diff --git a/Engine/Scripts/Entities/Particle/ParticleEffect.lua b/Assets/Engine/Scripts/Entities/Particle/ParticleEffect.lua similarity index 100% rename from Engine/Scripts/Entities/Particle/ParticleEffect.lua rename to Assets/Engine/Scripts/Entities/Particle/ParticleEffect.lua diff --git a/Engine/Scripts/Entities/Physics/AnimObject.lua b/Assets/Engine/Scripts/Entities/Physics/AnimObject.lua similarity index 100% rename from Engine/Scripts/Entities/Physics/AnimObject.lua rename to Assets/Engine/Scripts/Entities/Physics/AnimObject.lua diff --git a/Engine/Scripts/Entities/Physics/AreaBezierVolume.lua b/Assets/Engine/Scripts/Entities/Physics/AreaBezierVolume.lua similarity index 100% rename from Engine/Scripts/Entities/Physics/AreaBezierVolume.lua rename to Assets/Engine/Scripts/Entities/Physics/AreaBezierVolume.lua diff --git a/Engine/Scripts/Entities/Physics/BasicEntity.lua b/Assets/Engine/Scripts/Entities/Physics/BasicEntity.lua similarity index 100% rename from Engine/Scripts/Entities/Physics/BasicEntity.lua rename to Assets/Engine/Scripts/Entities/Physics/BasicEntity.lua diff --git a/Engine/Scripts/Entities/Physics/LivingEntity.lua b/Assets/Engine/Scripts/Entities/Physics/LivingEntity.lua similarity index 100% rename from Engine/Scripts/Entities/Physics/LivingEntity.lua rename to Assets/Engine/Scripts/Entities/Physics/LivingEntity.lua diff --git a/Engine/Scripts/Entities/Physics/RigidBodyEx.lua b/Assets/Engine/Scripts/Entities/Physics/RigidBodyEx.lua similarity index 100% rename from Engine/Scripts/Entities/Physics/RigidBodyEx.lua rename to Assets/Engine/Scripts/Entities/Physics/RigidBodyEx.lua diff --git a/Engine/Scripts/Entities/Render/FogVolume.lua b/Assets/Engine/Scripts/Entities/Render/FogVolume.lua similarity index 100% rename from Engine/Scripts/Entities/Render/FogVolume.lua rename to Assets/Engine/Scripts/Entities/Render/FogVolume.lua diff --git a/Engine/Scripts/Entities/Render/GeomCache.lua b/Assets/Engine/Scripts/Entities/Render/GeomCache.lua similarity index 100% rename from Engine/Scripts/Entities/Render/GeomCache.lua rename to Assets/Engine/Scripts/Entities/Render/GeomCache.lua diff --git a/Engine/Scripts/Entities/Sound/AudioAreaAmbience.lua b/Assets/Engine/Scripts/Entities/Sound/AudioAreaAmbience.lua similarity index 100% rename from Engine/Scripts/Entities/Sound/AudioAreaAmbience.lua rename to Assets/Engine/Scripts/Entities/Sound/AudioAreaAmbience.lua diff --git a/Engine/Scripts/Entities/Sound/AudioAreaEntity.lua b/Assets/Engine/Scripts/Entities/Sound/AudioAreaEntity.lua similarity index 100% rename from Engine/Scripts/Entities/Sound/AudioAreaEntity.lua rename to Assets/Engine/Scripts/Entities/Sound/AudioAreaEntity.lua diff --git a/Engine/Scripts/Entities/Sound/AudioAreaRandom.lua b/Assets/Engine/Scripts/Entities/Sound/AudioAreaRandom.lua similarity index 100% rename from Engine/Scripts/Entities/Sound/AudioAreaRandom.lua rename to Assets/Engine/Scripts/Entities/Sound/AudioAreaRandom.lua diff --git a/Engine/Scripts/Entities/Sound/AudioTriggerSpot.lua b/Assets/Engine/Scripts/Entities/Sound/AudioTriggerSpot.lua similarity index 100% rename from Engine/Scripts/Entities/Sound/AudioTriggerSpot.lua rename to Assets/Engine/Scripts/Entities/Sound/AudioTriggerSpot.lua diff --git a/Engine/Scripts/Entities/Sound/Shared/AudioUtils.lua b/Assets/Engine/Scripts/Entities/Sound/Shared/AudioUtils.lua similarity index 100% rename from Engine/Scripts/Entities/Sound/Shared/AudioUtils.lua rename to Assets/Engine/Scripts/Entities/Sound/Shared/AudioUtils.lua diff --git a/Engine/Scripts/Entities/Triggers/AreaTrigger.lua b/Assets/Engine/Scripts/Entities/Triggers/AreaTrigger.lua similarity index 100% rename from Engine/Scripts/Entities/Triggers/AreaTrigger.lua rename to Assets/Engine/Scripts/Entities/Triggers/AreaTrigger.lua diff --git a/Engine/Scripts/Entities/Triggers/ProximityTrigger.lua b/Assets/Engine/Scripts/Entities/Triggers/ProximityTrigger.lua similarity index 100% rename from Engine/Scripts/Entities/Triggers/ProximityTrigger.lua rename to Assets/Engine/Scripts/Entities/Triggers/ProximityTrigger.lua diff --git a/Engine/Scripts/Entities/UI/UiCanvasRefEntity.lua b/Assets/Engine/Scripts/Entities/UI/UiCanvasRefEntity.lua similarity index 100% rename from Engine/Scripts/Entities/UI/UiCanvasRefEntity.lua rename to Assets/Engine/Scripts/Entities/UI/UiCanvasRefEntity.lua diff --git a/Engine/Scripts/Utils/Components/GameplayUtils.lua b/Assets/Engine/Scripts/Utils/Components/GameplayUtils.lua similarity index 100% rename from Engine/Scripts/Utils/Components/GameplayUtils.lua rename to Assets/Engine/Scripts/Utils/Components/GameplayUtils.lua diff --git a/Engine/Scripts/Utils/Components/InputUtils.lua b/Assets/Engine/Scripts/Utils/Components/InputUtils.lua similarity index 100% rename from Engine/Scripts/Utils/Components/InputUtils.lua rename to Assets/Engine/Scripts/Utils/Components/InputUtils.lua diff --git a/Engine/Scripts/Utils/Components/MultiHandlers.lua b/Assets/Engine/Scripts/Utils/Components/MultiHandlers.lua similarity index 100% rename from Engine/Scripts/Utils/Components/MultiHandlers.lua rename to Assets/Engine/Scripts/Utils/Components/MultiHandlers.lua diff --git a/Engine/Scripts/Utils/Containers.lua b/Assets/Engine/Scripts/Utils/Containers.lua similarity index 100% rename from Engine/Scripts/Utils/Containers.lua rename to Assets/Engine/Scripts/Utils/Containers.lua diff --git a/Engine/Scripts/Utils/EntityUtils.lua b/Assets/Engine/Scripts/Utils/EntityUtils.lua similarity index 100% rename from Engine/Scripts/Utils/EntityUtils.lua rename to Assets/Engine/Scripts/Utils/EntityUtils.lua diff --git a/Engine/Scripts/Utils/Math.lua b/Assets/Engine/Scripts/Utils/Math.lua similarity index 100% rename from Engine/Scripts/Utils/Math.lua rename to Assets/Engine/Scripts/Utils/Math.lua diff --git a/Engine/SeedAssetList.seed b/Assets/Engine/SeedAssetList.seed similarity index 100% rename from Engine/SeedAssetList.seed rename to Assets/Engine/SeedAssetList.seed diff --git a/Engine/Shaders/DistanceClouds.ext b/Assets/Engine/Shaders/DistanceClouds.ext similarity index 100% rename from Engine/Shaders/DistanceClouds.ext rename to Assets/Engine/Shaders/DistanceClouds.ext diff --git a/Engine/Shaders/Eye.ext b/Assets/Engine/Shaders/Eye.ext similarity index 100% rename from Engine/Shaders/Eye.ext rename to Assets/Engine/Shaders/Eye.ext diff --git a/Engine/Shaders/Fur.ext b/Assets/Engine/Shaders/Fur.ext similarity index 100% rename from Engine/Shaders/Fur.ext rename to Assets/Engine/Shaders/Fur.ext diff --git a/Engine/Shaders/GeometryBeam.ext b/Assets/Engine/Shaders/GeometryBeam.ext similarity index 100% rename from Engine/Shaders/GeometryBeam.ext rename to Assets/Engine/Shaders/GeometryBeam.ext diff --git a/Engine/Shaders/Glass.ext b/Assets/Engine/Shaders/Glass.ext similarity index 100% rename from Engine/Shaders/Glass.ext rename to Assets/Engine/Shaders/Glass.ext diff --git a/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Clouds.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Clouds.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Clouds.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Clouds.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Common.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Common.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/Common.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Common.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Common.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Common.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Debug.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Debug.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Debug.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Debug.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DebugLight.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Eye.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Eye.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Eye.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Eye.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/FallBack.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FallBack.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FallBack.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/FallBack.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FogVolume.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Fur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Fur.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Fur.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Fur.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/FurZPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Glass.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Glass.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Glass.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Glass.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Hair.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Hair.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Hair.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Hair.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Helper.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Helper.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Helper.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Helper.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Hud3D.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Illum.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Illum.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Illum.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Illum.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/IllumTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/LensOptics.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Light.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Light.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Light.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Light.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/LightBeam.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Monitor.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Monitor.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Monitor.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Monitor.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/NoDraw.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Particles.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Particles.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Particles.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Particles.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/PostAA.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostAA.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/PostAA.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/PostAA.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/PostEffects.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Scopes.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Scopes.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Scopes.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Scopes.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Sketch.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sketch.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Sketch.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Sketch.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Sky.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sky.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Sky.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Sky.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Stars.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Stars.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Stars.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Stars.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Stereo.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Stereo.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Stereo.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Stereo.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Terrain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Terrain.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Terrain.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Terrain.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/TiledShading.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/UI.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/UI.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/UI.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/UI.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Vegetation.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Video.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Video.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Video.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Video.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/Water.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Water.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Water.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Water.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/Waterfall.cfx rename to Assets/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx diff --git a/Engine/Shaders/HWScripts/CryFX/fragLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/fragLib.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/fragLib.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/fragLib.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/shadeLib.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi diff --git a/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi similarity index 100% rename from Engine/Shaders/HWScripts/CryFX/vertexLib.cfi rename to Assets/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi diff --git a/Engine/Shaders/Hair.ext b/Assets/Engine/Shaders/Hair.ext similarity index 100% rename from Engine/Shaders/Hair.ext rename to Assets/Engine/Shaders/Hair.ext diff --git a/Engine/Shaders/HumanSkin.ext b/Assets/Engine/Shaders/HumanSkin.ext similarity index 100% rename from Engine/Shaders/HumanSkin.ext rename to Assets/Engine/Shaders/HumanSkin.ext diff --git a/Engine/Shaders/Illum.ext b/Assets/Engine/Shaders/Illum.ext similarity index 100% rename from Engine/Shaders/Illum.ext rename to Assets/Engine/Shaders/Illum.ext diff --git a/Engine/Shaders/LensOptics.ext b/Assets/Engine/Shaders/LensOptics.ext similarity index 100% rename from Engine/Shaders/LensOptics.ext rename to Assets/Engine/Shaders/LensOptics.ext diff --git a/Engine/Shaders/LightBeam.ext b/Assets/Engine/Shaders/LightBeam.ext similarity index 100% rename from Engine/Shaders/LightBeam.ext rename to Assets/Engine/Shaders/LightBeam.ext diff --git a/Engine/Shaders/Monitor.ext b/Assets/Engine/Shaders/Monitor.ext similarity index 100% rename from Engine/Shaders/Monitor.ext rename to Assets/Engine/Shaders/Monitor.ext diff --git a/Engine/Shaders/ParticleImposter.ext b/Assets/Engine/Shaders/ParticleImposter.ext similarity index 100% rename from Engine/Shaders/ParticleImposter.ext rename to Assets/Engine/Shaders/ParticleImposter.ext diff --git a/Engine/Shaders/Particles.ext b/Assets/Engine/Shaders/Particles.ext similarity index 100% rename from Engine/Shaders/Particles.ext rename to Assets/Engine/Shaders/Particles.ext diff --git a/Engine/Shaders/RunTime.ext b/Assets/Engine/Shaders/RunTime.ext similarity index 100% rename from Engine/Shaders/RunTime.ext rename to Assets/Engine/Shaders/RunTime.ext diff --git a/Engine/Shaders/Scopes.ext b/Assets/Engine/Shaders/Scopes.ext similarity index 100% rename from Engine/Shaders/Scopes.ext rename to Assets/Engine/Shaders/Scopes.ext diff --git a/Engine/Shaders/ShaderProfiles.txt b/Assets/Engine/Shaders/ShaderProfiles.txt similarity index 100% rename from Engine/Shaders/ShaderProfiles.txt rename to Assets/Engine/Shaders/ShaderProfiles.txt diff --git a/Engine/Shaders/ShadowMaskGen.ext b/Assets/Engine/Shaders/ShadowMaskGen.ext similarity index 100% rename from Engine/Shaders/ShadowMaskGen.ext rename to Assets/Engine/Shaders/ShadowMaskGen.ext diff --git a/Engine/Shaders/SketchTerrain.ext b/Assets/Engine/Shaders/SketchTerrain.ext similarity index 100% rename from Engine/Shaders/SketchTerrain.ext rename to Assets/Engine/Shaders/SketchTerrain.ext diff --git a/Engine/Shaders/SkyHDR.ext b/Assets/Engine/Shaders/SkyHDR.ext similarity index 100% rename from Engine/Shaders/SkyHDR.ext rename to Assets/Engine/Shaders/SkyHDR.ext diff --git a/Engine/Shaders/StarterGame_GeometryBeamScaling.ext b/Assets/Engine/Shaders/StarterGame_GeometryBeamScaling.ext similarity index 100% rename from Engine/Shaders/StarterGame_GeometryBeamScaling.ext rename to Assets/Engine/Shaders/StarterGame_GeometryBeamScaling.ext diff --git a/Engine/Shaders/Statics.ext b/Assets/Engine/Shaders/Statics.ext similarity index 100% rename from Engine/Shaders/Statics.ext rename to Assets/Engine/Shaders/Statics.ext diff --git a/Engine/Shaders/TemplBeamProc.ext b/Assets/Engine/Shaders/TemplBeamProc.ext similarity index 100% rename from Engine/Shaders/TemplBeamProc.ext rename to Assets/Engine/Shaders/TemplBeamProc.ext diff --git a/Engine/Shaders/Terrain.ext b/Assets/Engine/Shaders/Terrain.ext similarity index 100% rename from Engine/Shaders/Terrain.ext rename to Assets/Engine/Shaders/Terrain.ext diff --git a/Engine/Shaders/Vegetation.ext b/Assets/Engine/Shaders/Vegetation.ext similarity index 100% rename from Engine/Shaders/Vegetation.ext rename to Assets/Engine/Shaders/Vegetation.ext diff --git a/Engine/Shaders/VolumeObject.ext b/Assets/Engine/Shaders/VolumeObject.ext similarity index 100% rename from Engine/Shaders/VolumeObject.ext rename to Assets/Engine/Shaders/VolumeObject.ext diff --git a/Engine/Shaders/Water.ext b/Assets/Engine/Shaders/Water.ext similarity index 100% rename from Engine/Shaders/Water.ext rename to Assets/Engine/Shaders/Water.ext diff --git a/Engine/Shaders/WaterVolume.ext b/Assets/Engine/Shaders/WaterVolume.ext similarity index 100% rename from Engine/Shaders/WaterVolume.ext rename to Assets/Engine/Shaders/WaterVolume.ext diff --git a/Engine/Shaders/Waterfall.ext b/Assets/Engine/Shaders/Waterfall.ext similarity index 100% rename from Engine/Shaders/Waterfall.ext rename to Assets/Engine/Shaders/Waterfall.ext diff --git a/Engine/exclude.filetag b/Assets/Engine/exclude.filetag similarity index 100% rename from Engine/exclude.filetag rename to Assets/Engine/exclude.filetag diff --git a/Engine/include.filetag b/Assets/Engine/include.filetag similarity index 100% rename from Engine/include.filetag rename to Assets/Engine/include.filetag diff --git a/Engine/materials/material_layers_default.mtl b/Assets/Engine/materials/material_layers_default.mtl similarity index 100% rename from Engine/materials/material_layers_default.mtl rename to Assets/Engine/materials/material_layers_default.mtl diff --git a/Engine/materials/material_terrain_default.mtl b/Assets/Engine/materials/material_terrain_default.mtl similarity index 100% rename from Engine/materials/material_terrain_default.mtl rename to Assets/Engine/materials/material_terrain_default.mtl diff --git a/Engine/textures/default_icon.png b/Assets/Engine/textures/default_icon.png similarity index 100% rename from Engine/textures/default_icon.png rename to Assets/Engine/textures/default_icon.png diff --git a/Engine/textures/default_icon.png.exportsettings b/Assets/Engine/textures/default_icon.png.exportsettings similarity index 100% rename from Engine/textures/default_icon.png.exportsettings rename to Assets/Engine/textures/default_icon.png.exportsettings diff --git a/Engine/textures/defaults/defaultnouvs.tif b/Assets/Engine/textures/defaults/defaultnouvs.tif similarity index 100% rename from Engine/textures/defaults/defaultnouvs.tif rename to Assets/Engine/textures/defaults/defaultnouvs.tif diff --git a/Engine/textures/defaults/grey.tif b/Assets/Engine/textures/defaults/grey.tif similarity index 100% rename from Engine/textures/defaults/grey.tif rename to Assets/Engine/textures/defaults/grey.tif diff --git a/Engine/textures/skys/night/half_moon.tif b/Assets/Engine/textures/skys/night/half_moon.tif similarity index 100% rename from Engine/textures/skys/night/half_moon.tif rename to Assets/Engine/textures/skys/night/half_moon.tif diff --git a/AutomatedTesting/EngineFinder.cmake b/AutomatedTesting/EngineFinder.cmake new file mode 100644 index 0000000000..1fdcef2b56 --- /dev/null +++ b/AutomatedTesting/EngineFinder.cmake @@ -0,0 +1,50 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# +# This file is copied during engine registration. Edits to this file will be lost next +# time a registration happens. + +include_guard() + +# Read the engine name from the project_json file +file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json) +string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine) +if(json_error) + message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}") +endif() + +# Read the list of paths from ~.o3de/o3de_manifest.json +file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory) # Windows +if((NOT home_directory) OR (NOT EXISTS ${home_directory})) + file(TO_CMAKE_PATH "$ENV{HOME}" home_directory)# Unix +endif() + +if (NOT home_directory) + message(FATAL_ERROR "Cannot find user home directory, the o3de manifest cannot be found") +endif() +# Set manifest path to path in the user home directory +set(manifest_path ${home_directory}/.o3de/o3de_manifest.json) + +if(EXISTS ${manifest_path}) + file(READ ${manifest_path} manifest_json) + string(JSON engines_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines) + if(json_error) + message(FATAL_ERROR "Unable to read key 'engines' from '${manifest_path}', error: ${json_error}") + endif() + + math(EXPR engines_count "${engines_count}-1") + foreach(engine_path_index RANGE ${engines_count}) + string(JSON engine_path ERROR_VARIABLE json_error GET ${manifest_json} engines ${engine_path_index}) + if(${json_error}) + message(FATAL_ERROR "Unable to read engines[${engine_path_index}] '${manifest_path}', error: ${json_error}") + endif() + list(APPEND CMAKE_MODULE_PATH "${engine_path}/cmake") + endforeach() +endif() diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake index 4d5680a30d..f9d1e60dda 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake @@ -8,3 +8,8 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # + +set(GEM_DEPENDENCIES + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Null.Private +) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake index 4d5680a30d..ee7be9ac6d 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake @@ -8,3 +8,10 @@ # remove or modify any license notices. This file is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # + +set(GEM_DEPENDENCIES + Gem::Atom_RHI_Null.Private + Gem::Atom_RHI_Null.Builders + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Metal.Builders +) \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index d31ea6334c..6d3727195e 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -25,10 +25,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Main.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -39,10 +38,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Periodic.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -56,7 +54,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TIMEOUT 3600 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -71,10 +68,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -85,10 +81,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE sandbox TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Sandbox.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets ) @@ -101,10 +96,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -120,10 +114,9 @@ endif() # TEST_SUITE main # TEST_SERIAL # PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py -# TIMEOUT 3600 +# TIMEOUT 1500 # RUNTIME_DEPENDENCIES # Legacy::Editor -# Legacy::CryRenderNULL # AZ::AssetProcessor # AutomatedTesting.Assets # ) @@ -136,10 +129,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE sandbox TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets Gem::EditorPythonBindings.Editor @@ -154,10 +146,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets Gem::EditorPythonBindings.Editor @@ -173,7 +164,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE main TEST_SERIAL TRUE PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor AZ::AssetProcessor @@ -196,7 +187,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - TIMEOUT 36000 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -212,7 +203,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE sandbox PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg PYTEST_MARKS "SUITE_sandbox" - TIMEOUT 36000 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -228,7 +219,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg PYTEST_MARKS "SUITE_periodic" - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -244,7 +235,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -259,7 +250,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas PYTEST_MARKS "SUITE_periodic" - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -274,7 +265,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SERIAL TEST_SUITE periodic PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES AZ::AssetProcessor Legacy::Editor @@ -292,10 +283,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ TEST_SUITE periodic TEST_SERIAL PATH ${CMAKE_CURRENT_LIST_DIR}/editor - TIMEOUT 3600 + TIMEOUT 1500 RUNTIME_DEPENDENCIES Legacy::Editor - Legacy::CryRenderNULL AZ::AssetProcessor AutomatedTesting.Assets COMPONENT @@ -314,7 +304,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) # AZ::AssetProcessor # AZ::AssetProcessorBatch # AutomatedTesting.GameLauncher - # Legacy::CryRenderNULL #) endif() diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py deleted file mode 100755 index 41ae0608a4..0000000000 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -its licensors. - -For complete copyright and license terms please see the LICENSE at the root of this -distribution (the "License"). All use of this software is governed by the License, -or, if provided, by the license below or the license accompanying this file. Do not -remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -""" - -# -# This is a pytest module to test the in-Editor Python API from ViewPane.h -# -import pytest -pytest.importorskip('ly_test_tools') - -import sys -import os -sys.path.append(os.path.dirname(__file__)) -from hydra_utils import launch_test_case - - -@pytest.mark.SUITE_sandbox -@pytest.mark.parametrize('launcher_platform', ['windows_editor']) -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['auto_test']) -class TestLegacyCryMaterialsCommandsAutomation(object): - - def test_Legacy_CryMaterials(self, request, editor, level, launcher_platform): - - unexpected_lines=[] - expected_lines = [ - # "Material Settings/Shader updated correctly", # Disabled, SPEC-3590 - # "Material Settings/Surface Type updated correctly", # Disabled, SPEC-3590 - "Texture Maps/Diffuse/Tiling/IsTileU updated correctly", - "Texture Maps/Diffuse/Tiling/TileU updated correctly", - "Texture Maps/Diffuse/Rotator/Type updated correctly", - "Texture Maps/Diffuse/Rotator/Amplitude updated correctly", - "Texture Maps/Diffuse/Oscillator/AmplitudeU updated correctly", - "Opacity Settings/Opacity updated correctly", - "Opacity Settings/AlphaTest updated correctly", - "Opacity Settings/Additive updated correctly", - "Lighting Settings/Diffuse Color updated correctly", - "Lighting Settings/Specular Color updated correctly", - "Lighting Settings/Emissive Intensity updated correctly", - "Lighting Settings/Emissive Color updated correctly", - "Advanced/Allow layer activation updated correctly", - "Advanced/2 Sided updated correctly", - "Advanced/No Shadow updated correctly", - "Advanced/Use Scattering updated correctly", - "Advanced/Hide After Breaking updated correctly", - "Advanced/Fog Volume Shading Quality High updated correctly", - "Advanced/Blend Terrain Color updated correctly", - "Advanced/Voxel Coverage updated correctly", - "Advanced/Propagate Opacity Settings updated correctly", - "Advanced/Propagate Lighting Settings updated correctly", - "Advanced/Propagate Advanced Settings updated correctly", - "Advanced/Propagate Texture Maps updated correctly", - "Advanced/Propagate Shader Params updated correctly", - "Advanced/Propagate Shader Generation updated correctly", - "Advanced/Propagate Vertex Deformation updated correctly", - # "Shader Params/Blend Factor updated correctly", # Disabled, SPEC-3590 - # "Shader Params/Indirect bounce color updated correctly", # Disabled, SPEC-3590 - "Vertex Deformation/Type updated correctly", - "Vertex Deformation/Wave Length X updated correctly", - "Vertex Deformation/Wave X/Level updated correctly", - "Vertex Deformation/Wave X/Amplitude updated correctly", - "Vertex Deformation/Wave X/Phase updated correctly", - "Vertex Deformation/Wave X/Frequency updated correctly" - ] - - test_case_file = os.path.join(os.path.dirname(__file__), 'CryMaterialsCommands_test_case.py') - launch_test_case(editor, test_case_file, expected_lines, unexpected_lines) - diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py deleted file mode 100755 index 913b1ace24..0000000000 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py +++ /dev/null @@ -1,116 +0,0 @@ -""" -All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -its licensors. - -For complete copyright and license terms please see the LICENSE at the root of this -distribution (the "License"). All use of this software is governed by the License, -or, if provided, by the license below or the license accompanying this file. Do not -remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -""" - -# Tests the legacy Python API for CryMaterials while the Editor is running - -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.legacy.material as material -import azlmbr.math as math - -materialName = 'materials/ter_layer_green' -print(f'Starting CryMaterial test case using material {materialName}') - - -def MaterialPropertyTest(property, value, doReset=True): - try: - # get old value and attempt to set new value - oldValue = material.get_property(materialName, property) - if oldValue == value: - print(f'>>> `{property}` already set to {oldValue}') - return - material.set_property(materialName, property, value) - - # test that the set new value worked - newValue = material.get_property(materialName, property) - if oldValue != newValue: - print(f"{property} updated correctly") - - # reset back to old value - if doReset: - material.set_property(materialName, property, oldValue) - except: - print(f'!!! hit an exception when setting `{property}` to {value}') - - -color = math.Color() -color.r = 255.0 -color.g = 128.0 -color.b = 64.0 -color.a = 0.0 - -# Material Settings -# MaterialPropertyTest("Material Settings/Shader", "Geometrybeam") # Disabled, SPEC-3590 -# MaterialPropertyTest("Material Settings/Surface Type", "grass") # Disabled, SPEC-3590 - -# Texture Maps -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileU", False) -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileV", False) -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/TileU", 0.42) -MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Type", 'Oscillated Rotation') -MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Amplitude", 42.0) -MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/TypeU", 'Fixed Moving') -MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/AmplitudeU", 42.0) - -# Vertex Deformation -MaterialPropertyTest("Vertex Deformation/Type", 'Sin Wave') -MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0) -MaterialPropertyTest("Vertex Deformation/Type", 'Perlin 3D') -MaterialPropertyTest("Vertex Deformation/Noise Scale", math.Vector3(1.1, 2.2, 3.3)) - -# Opacity Settings -MaterialPropertyTest("Opacity Settings/Opacity", 42) -MaterialPropertyTest("Opacity Settings/AlphaTest", 2) -MaterialPropertyTest("Opacity Settings/Additive", True) - -# Lighting Settings -MaterialPropertyTest("Lighting Settings/Diffuse Color", color) -MaterialPropertyTest("Lighting Settings/Specular Color", color) -MaterialPropertyTest("Lighting Settings/Emissive Intensity", 42.0) -MaterialPropertyTest("Lighting Settings/Emissive Color", color) -MaterialPropertyTest("Lighting Settings/Specular Level", 2.0) - -# Advanced -MaterialPropertyTest("Advanced/Allow layer activation", False) -MaterialPropertyTest("Advanced/2 Sided", True) -MaterialPropertyTest("Advanced/No Shadow", True) -MaterialPropertyTest("Advanced/Use Scattering", True) -MaterialPropertyTest("Advanced/Hide After Breaking", True) -MaterialPropertyTest("Advanced/Fog Volume Shading Quality High", True) -MaterialPropertyTest("Advanced/Blend Terrain Color", True) -MaterialPropertyTest("Advanced/Voxel Coverage", 0.42) -# --- MaterialPropertyTest("Advanced/Link to Material", "materials/ter_layer_blue") # Works, but clears on UI refresh -MaterialPropertyTest("Advanced/Propagate Opacity Settings", True) -MaterialPropertyTest("Advanced/Propagate Lighting Settings", True) -MaterialPropertyTest("Advanced/Propagate Advanced Settings", True) -MaterialPropertyTest("Advanced/Propagate Texture Maps", True) -MaterialPropertyTest("Advanced/Propagate Shader Params", True) -MaterialPropertyTest("Advanced/Propagate Shader Generation", True) -MaterialPropertyTest("Advanced/Propagate Vertex Deformation", True) - -# Shader parameters vary with each Shader, just testing a couple of them... -# MaterialPropertyTest("Shader Params/Blend Factor", 7.0, False) # Disabled, SPEC-3590 -# MaterialPropertyTest("Shader Params/Indirect bounce color", color, False) # Disabled, SPEC-3590 - -### These values are reset to False when set. Left them here commented for reference. -# MaterialPropertyTest("Shader Generation Params/Dust & Turbulence", True) -# MaterialPropertyTest("Shader Generation Params/Receive Shadows", True) -# MaterialPropertyTest("Shader Generation Params/UV Vignetting", True) - -# Vertex Deformation -MaterialPropertyTest("Vertex Deformation/Type", "Sin Wave") -MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Level", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Amplitude", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Phase", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Frequency", 42.0) - -editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt') diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index de3e04e67e..6a865ee690 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -100,7 +100,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL - TIMEOUT 3600 + TIMEOUT 1500 TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessor @@ -123,7 +123,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py EXCLUDE_TEST_RUN_TARGET_FROM_IDE TEST_SERIAL - TIMEOUT 3600 + TIMEOUT 1500 TEST_SUITE periodic RUNTIME_DEPENDENCIES AZ::AssetProcessorBatch diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py index cfd088adc0..e329846554 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py @@ -71,9 +71,9 @@ class TestsAssetProcessorBatch_DependenycyTests(object): env = ap_setup_fixture BATCH_LOG_PATH = env["ap_batch_log_file"] asset_processor.create_temp_asset_root() - asset_processor.add_relative_source_asset(os.path.join("Engine", "engine_dependencies.xml")) - asset_processor.add_scan_folder("Engine") - asset_processor.add_relative_source_asset(os.path.join("Engine", "Libs", "MaterialEffects", "surfacetypes.xml")) + asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "engine_dependencies.xml")) + asset_processor.add_scan_folder(os.path.join("Assets", "Engine")) + asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "Libs", "MaterialEffects", "surfacetypes.xml")) # Precondition: Assets are all processed asset_processor.batch_process() @@ -103,7 +103,7 @@ class TestsAssetProcessorBatch_DependenycyTests(object): assert surfacetypes_missing_logline, "Surfacetypes.xml not seen in the batch log as missing." # Add the schema file which allows our xml parser to understand dependencies for our engine_dependencies file - asset_processor.add_relative_source_asset(os.path.join("Engine", "Schema", "enginedependency.xmlschema")) + asset_processor.add_relative_source_asset(os.path.join("Assets", "Engine", "Schema", "enginedependency.xmlschema")) asset_processor.batch_process() _, output = asset_processor.batch_process(capture_output=True, diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py index 7c7b6b2452..b25ee081a1 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py @@ -205,10 +205,13 @@ class TestsAssetProcessorGUI_AllPlatforms(object): env = ap_setup_fixture # Copy test assets to new folder in dev folder # This new folder will be created outside the default project folder and will not be added as a scan folder - # by default, instead we'll modify the temporary AssetProcessorPlatformConfig.ini to add it test_assets_folder, cache_folder = asset_processor.prepare_test_environment(env["tests_dir"], "C4874115", relative_asset_root='', add_scan_folder=False) + # The AssetProcessor internal _cache_folder path is updated to point at the cache root in order + # to allow the comparison between the source asset path of "/C4874115" to match the cache assets + # in + asset_processor._cache_folder = os.path.dirname(cache_folder) assert os.path.exists(test_assets_folder), f"Test assets folder was not found {test_assets_folder}" # Run AP Batch @@ -226,7 +229,6 @@ class TestsAssetProcessorGUI_AllPlatforms(object): test_scan_folder_root_key = f"{ASSET_PROCESSOR_SETTINGS_ROOT_KEY}/ScanFolder C4874115" test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/watch=@ROOT@/C4874115"') - test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/output=C4874115"') test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/recursive=1"') test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/order=5000"') diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C4874115/C4874115_test_asset.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C4874115/C4874115/C4874115_test_asset.txt similarity index 100% rename from AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C4874115/C4874115_test_asset.txt rename to AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/assets/C4874115/C4874115/C4874115_test_asset.txt diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index 82a7e92c16..e701ff8d16 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -161,20 +161,6 @@ def run(): # Deletion/Undo/Redo test verify_deletion_undo_redo(self.component_name, entity_obj) - # Area Light Component - area_light = "Area Light" - ComponentTests( - area_light, lambda entity_obj: verify_required_component_addition( - entity_obj, ["Capsule Shape"], area_light)) - - # Decal Component - material_asset_path = os.path.join("Materials", "basic_grey.material") - material_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False) - ComponentTests( - "Decal", lambda entity_obj: verify_set_property( - entity_obj, "Settings|Decal Settings|Material", material_asset)) - # DepthOfField Component camera_entity = hydra.Entity("camera_entity") camera_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), ["Camera"]) @@ -185,6 +171,14 @@ def run(): lambda entity_obj: verify_set_property( entity_obj, "Controller|Configuration|Camera Entity", camera_entity.id)) + # Decal Component + material_asset_path = os.path.join("AutomatedTesting", "Materials", "basic_grey.material") + material_asset = asset.AssetCatalogRequestBus( + bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False) + ComponentTests( + "Decal (Atom)", lambda entity_obj: verify_set_property( + entity_obj, "Controller|Configuration|Material", material_asset)) + # Directional Light Component ComponentTests( "Directional Light", @@ -213,9 +207,6 @@ def run(): # Physical Sky Component ComponentTests("Physical Sky") - # Point Light Component - ComponentTests("Point Light") - # PostFX Layer Component ComponentTests("PostFX Layer") diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index 8621fcb248..aafa2ff9b7 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -7,10 +7,12 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -""" +Main suite tests for the Atom renderer. +""" import logging import os + import pytest import editor_python_test_tools.hydra_test_utils as hydra @@ -23,197 +25,8 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("level", ["auto_test"]) -class TestAtomEditorComponents(object): - - - @pytest.mark.test_case_id( - "C32078117", # Area Light - "C32078130", # Display Mapper - "C32078129", # Light - "C32078131", # Radius Weight Modifier - "C32078127", # PostFX Layer - "C32078126", # Point Light - "C32078125", # Physical Sky - "C32078115", # Global Skylight (IBL) - "C32078121", # Exposure Control - "C32078120", # Directional Light - "C32078119", # DepthOfField - "C32078118") # Decal - def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): - cfg_args = [level] - - expected_lines = [ - # Area Light Component - "Area Light Entity successfully created", - "Area Light_test: Component added to the entity: True", - "Area Light_test: Component removed after UNDO: True", - "Area Light_test: Component added after REDO: True", - "Area Light_test: Entered game mode: True", - "Area Light_test: Entity enabled after adding required components: True", - "Area Light_test: Entity is hidden: True", - "Area Light_test: Entity is shown: True", - "Area Light_test: Entity deleted: True", - "Area Light_test: UNDO entity deletion works: True", - "Area Light_test: REDO entity deletion works: True", - # Decal Component - "Decal Entity successfully created", - "Decal_test: Component added to the entity: True", - "Decal_test: Component removed after UNDO: True", - "Decal_test: Component added after REDO: True", - "Decal_test: Entered game mode: True", - "Decal_test: Exit game mode: True", - "Decal Settings|Decal Settings|Material: SUCCESS", - "Decal_test: Entity is hidden: True", - "Decal_test: Entity is shown: True", - "Decal_test: Entity deleted: True", - "Decal_test: UNDO entity deletion works: True", - "Decal_test: REDO entity deletion works: True", - # DepthOfField Component - "DepthOfField Entity successfully created", - "DepthOfField_test: Component added to the entity: True", - "DepthOfField_test: Component removed after UNDO: True", - "DepthOfField_test: Component added after REDO: True", - "DepthOfField_test: Entered game mode: True", - "DepthOfField_test: Exit game mode: True", - "DepthOfField_test: Entity disabled initially: True", - "DepthOfField_test: Entity enabled after adding required components: True", - "DepthOfField Controller|Configuration|Camera Entity: SUCCESS", - "DepthOfField_test: Entity is hidden: True", - "DepthOfField_test: Entity is shown: True", - "DepthOfField_test: Entity deleted: True", - "DepthOfField_test: UNDO entity deletion works: True", - "DepthOfField_test: REDO entity deletion works: True", - # Directional Light Component - "Directional Light Entity successfully created", - "Directional Light_test: Component added to the entity: True", - "Directional Light_test: Component removed after UNDO: True", - "Directional Light_test: Component added after REDO: True", - "Directional Light_test: Entered game mode: True", - "Directional Light_test: Exit game mode: True", - "Directional Light Controller|Configuration|Shadow|Camera: SUCCESS", - "Directional Light_test: Entity is hidden: True", - "Directional Light_test: Entity is shown: True", - "Directional Light_test: Entity deleted: True", - "Directional Light_test: UNDO entity deletion works: True", - "Directional Light_test: REDO entity deletion works: True", - # Exposure Control Component - "Exposure Control Entity successfully created", - "Exposure Control_test: Component added to the entity: True", - "Exposure Control_test: Component removed after UNDO: True", - "Exposure Control_test: Component added after REDO: True", - "Exposure Control_test: Entered game mode: True", - "Exposure Control_test: Exit game mode: True", - "Exposure Control_test: Entity disabled initially: True", - "Exposure Control_test: Entity enabled after adding required components: True", - "Exposure Control_test: Entity is hidden: True", - "Exposure Control_test: Entity is shown: True", - "Exposure Control_test: Entity deleted: True", - "Exposure Control_test: UNDO entity deletion works: True", - "Exposure Control_test: REDO entity deletion works: True", - # Global Skylight (IBL) Component - "Global Skylight (IBL) Entity successfully created", - "Global Skylight (IBL)_test: Component added to the entity: True", - "Global Skylight (IBL)_test: Component removed after UNDO: True", - "Global Skylight (IBL)_test: Component added after REDO: True", - "Global Skylight (IBL)_test: Entered game mode: True", - "Global Skylight (IBL)_test: Exit game mode: True", - "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS", - "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS", - "Global Skylight (IBL)_test: Entity is hidden: True", - "Global Skylight (IBL)_test: Entity is shown: True", - "Global Skylight (IBL)_test: Entity deleted: True", - "Global Skylight (IBL)_test: UNDO entity deletion works: True", - "Global Skylight (IBL)_test: REDO entity deletion works: True", - # Physical Sky Component - "Physical Sky Entity successfully created", - "Physical Sky component was added to entity", - "Entity has a Physical Sky component", - "Physical Sky_test: Component added to the entity: True", - "Physical Sky_test: Component removed after UNDO: True", - "Physical Sky_test: Component added after REDO: True", - "Physical Sky_test: Entered game mode: True", - "Physical Sky_test: Exit game mode: True", - "Physical Sky_test: Entity is hidden: True", - "Physical Sky_test: Entity is shown: True", - "Physical Sky_test: Entity deleted: True", - "Physical Sky_test: UNDO entity deletion works: True", - "Physical Sky_test: REDO entity deletion works: True", - # Point Light Component - "Point Light Entity successfully created", - "Point Light_test: Component added to the entity: True", - "Point Light_test: Component removed after UNDO: True", - "Point Light_test: Component added after REDO: True", - "Point Light_test: Entered game mode: True", - "Point Light_test: Exit game mode: True", - "Point Light_test: Entity is hidden: True", - "Point Light_test: Entity is shown: True", - "Point Light_test: Entity deleted: True", - "Point Light_test: UNDO entity deletion works: True", - "Point Light_test: REDO entity deletion works: True", - # PostFX Layer Component - "PostFX Layer Entity successfully created", - "PostFX Layer_test: Component added to the entity: True", - "PostFX Layer_test: Component removed after UNDO: True", - "PostFX Layer_test: Component added after REDO: True", - "PostFX Layer_test: Entered game mode: True", - "PostFX Layer_test: Exit game mode: True", - "PostFX Layer_test: Entity is hidden: True", - "PostFX Layer_test: Entity is shown: True", - "PostFX Layer_test: Entity deleted: True", - "PostFX Layer_test: UNDO entity deletion works: True", - "PostFX Layer_test: REDO entity deletion works: True", - # Radius Weight Modifier Component - "Radius Weight Modifier Entity successfully created", - "Radius Weight Modifier_test: Component added to the entity: True", - "Radius Weight Modifier_test: Component removed after UNDO: True", - "Radius Weight Modifier_test: Component added after REDO: True", - "Radius Weight Modifier_test: Entered game mode: True", - "Radius Weight Modifier_test: Exit game mode: True", - "Radius Weight Modifier_test: Entity is hidden: True", - "Radius Weight Modifier_test: Entity is shown: True", - "Radius Weight Modifier_test: Entity deleted: True", - "Radius Weight Modifier_test: UNDO entity deletion works: True", - "Radius Weight Modifier_test: REDO entity deletion works: True", - # Light Component - "Light Entity successfully created", - "Light_test: Component added to the entity: True", - "Light_test: Component removed after UNDO: True", - "Light_test: Component added after REDO: True", - "Light_test: Entered game mode: True", - "Light_test: Exit game mode: True", - "Light_test: Entity is hidden: True", - "Light_test: Entity is shown: True", - "Light_test: Entity deleted: True", - "Light_test: UNDO entity deletion works: True", - "Light_test: REDO entity deletion works: True", - # Display Mapper Component - "Display Mapper Entity successfully created", - "Display Mapper_test: Component added to the entity: True", - "Display Mapper_test: Component removed after UNDO: True", - "Display Mapper_test: Component added after REDO: True", - "Display Mapper_test: Entered game mode: True", - "Display Mapper_test: Exit game mode: True", - "Display Mapper_test: Entity is hidden: True", - "Display Mapper_test: Entity is shown: True", - "Display Mapper_test: Entity deleted: True", - "Display Mapper_test: UNDO entity deletion works: True", - "Display Mapper_test: REDO entity deletion works: True", - ] - - unexpected_lines = [ - "failed to open", - "Traceback (most recent call last):", - ] +class TestAtomEditorComponentsMain(object): - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_AddedToEntity.py", - timeout=EDITOR_TIMEOUT, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - ) + # It requires at least one test + def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): + pass diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py index 01474e6018..8ca5b5aa31 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py @@ -7,6 +7,8 @@ distribution (the "License"). All use of this software is governed by the Licens or, if provided, by the license below or the license accompanying this file. Do not remove or modify any license notices. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +Sandbox suite tests for the Atom renderer. """ import pytest @@ -15,8 +17,172 @@ import pytest @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("level", ["auto_test"]) -class TestAtomEditorComponents(object): +class TestAtomEditorComponentsSandbox(object): + + @pytest.mark.test_case_id( + "C32078117", # Area Light + "C32078130", # Display Mapper + "C32078129", # Light + "C32078131", # Radius Weight Modifier + "C32078127", # PostFX Layer + "C32078126", # Point Light + "C32078125", # Physical Sky + "C32078115", # Global Skylight (IBL) + "C32078121", # Exposure Control + "C32078120", # Directional Light + "C32078119", # DepthOfField + "C32078118") # Decal + def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): + cfg_args = [level] + + expected_lines = [ + # Decal Component + "Decal (Atom) Entity successfully created", + "Decal (Atom)_test: Component added to the entity: True", + "Decal (Atom)_test: Component removed after UNDO: True", + "Decal (Atom)_test: Component added after REDO: True", + "Decal (Atom)_test: Entered game mode: True", + "Decal (Atom)_test: Exit game mode: True", + "Decal (Atom) Controller|Configuration|Material: SUCCESS", + "Decal (Atom)_test: Entity is hidden: True", + "Decal (Atom)_test: Entity is shown: True", + "Decal (Atom)_test: Entity deleted: True", + "Decal (Atom)_test: UNDO entity deletion works: True", + "Decal (Atom)_test: REDO entity deletion works: True", + # DepthOfField Component + "DepthOfField Entity successfully created", + "DepthOfField_test: Component added to the entity: True", + "DepthOfField_test: Component removed after UNDO: True", + "DepthOfField_test: Component added after REDO: True", + "DepthOfField_test: Entered game mode: True", + "DepthOfField_test: Exit game mode: True", + "DepthOfField_test: Entity disabled initially: True", + "DepthOfField_test: Entity enabled after adding required components: True", + "DepthOfField Controller|Configuration|Camera Entity: SUCCESS", + "DepthOfField_test: Entity is hidden: True", + "DepthOfField_test: Entity is shown: True", + "DepthOfField_test: Entity deleted: True", + "DepthOfField_test: UNDO entity deletion works: True", + "DepthOfField_test: REDO entity deletion works: True", + # Directional Light Component + "Directional Light Entity successfully created", + "Directional Light_test: Component added to the entity: True", + "Directional Light_test: Component removed after UNDO: True", + "Directional Light_test: Component added after REDO: True", + "Directional Light_test: Entered game mode: True", + "Directional Light_test: Exit game mode: True", + "Directional Light Controller|Configuration|Shadow|Camera: SUCCESS", + "Directional Light_test: Entity is hidden: True", + "Directional Light_test: Entity is shown: True", + "Directional Light_test: Entity deleted: True", + "Directional Light_test: UNDO entity deletion works: True", + "Directional Light_test: REDO entity deletion works: True", + # Exposure Control Component + "Exposure Control Entity successfully created", + "Exposure Control_test: Component added to the entity: True", + "Exposure Control_test: Component removed after UNDO: True", + "Exposure Control_test: Component added after REDO: True", + "Exposure Control_test: Entered game mode: True", + "Exposure Control_test: Exit game mode: True", + "Exposure Control_test: Entity disabled initially: True", + "Exposure Control_test: Entity enabled after adding required components: True", + "Exposure Control_test: Entity is hidden: True", + "Exposure Control_test: Entity is shown: True", + "Exposure Control_test: Entity deleted: True", + "Exposure Control_test: UNDO entity deletion works: True", + "Exposure Control_test: REDO entity deletion works: True", + # Global Skylight (IBL) Component + "Global Skylight (IBL) Entity successfully created", + "Global Skylight (IBL)_test: Component added to the entity: True", + "Global Skylight (IBL)_test: Component removed after UNDO: True", + "Global Skylight (IBL)_test: Component added after REDO: True", + "Global Skylight (IBL)_test: Entered game mode: True", + "Global Skylight (IBL)_test: Exit game mode: True", + "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS", + "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS", + "Global Skylight (IBL)_test: Entity is hidden: True", + "Global Skylight (IBL)_test: Entity is shown: True", + "Global Skylight (IBL)_test: Entity deleted: True", + "Global Skylight (IBL)_test: UNDO entity deletion works: True", + "Global Skylight (IBL)_test: REDO entity deletion works: True", + # Physical Sky Component + "Physical Sky Entity successfully created", + "Physical Sky component was added to entity", + "Entity has a Physical Sky component", + "Physical Sky_test: Component added to the entity: True", + "Physical Sky_test: Component removed after UNDO: True", + "Physical Sky_test: Component added after REDO: True", + "Physical Sky_test: Entered game mode: True", + "Physical Sky_test: Exit game mode: True", + "Physical Sky_test: Entity is hidden: True", + "Physical Sky_test: Entity is shown: True", + "Physical Sky_test: Entity deleted: True", + "Physical Sky_test: UNDO entity deletion works: True", + "Physical Sky_test: REDO entity deletion works: True", + # PostFX Layer Component + "PostFX Layer Entity successfully created", + "PostFX Layer_test: Component added to the entity: True", + "PostFX Layer_test: Component removed after UNDO: True", + "PostFX Layer_test: Component added after REDO: True", + "PostFX Layer_test: Entered game mode: True", + "PostFX Layer_test: Exit game mode: True", + "PostFX Layer_test: Entity is hidden: True", + "PostFX Layer_test: Entity is shown: True", + "PostFX Layer_test: Entity deleted: True", + "PostFX Layer_test: UNDO entity deletion works: True", + "PostFX Layer_test: REDO entity deletion works: True", + # Radius Weight Modifier Component + "Radius Weight Modifier Entity successfully created", + "Radius Weight Modifier_test: Component added to the entity: True", + "Radius Weight Modifier_test: Component removed after UNDO: True", + "Radius Weight Modifier_test: Component added after REDO: True", + "Radius Weight Modifier_test: Entered game mode: True", + "Radius Weight Modifier_test: Exit game mode: True", + "Radius Weight Modifier_test: Entity is hidden: True", + "Radius Weight Modifier_test: Entity is shown: True", + "Radius Weight Modifier_test: Entity deleted: True", + "Radius Weight Modifier_test: UNDO entity deletion works: True", + "Radius Weight Modifier_test: REDO entity deletion works: True", + # Light Component + "Light Entity successfully created", + "Light_test: Component added to the entity: True", + "Light_test: Component removed after UNDO: True", + "Light_test: Component added after REDO: True", + "Light_test: Entered game mode: True", + "Light_test: Exit game mode: True", + "Light_test: Entity is hidden: True", + "Light_test: Entity is shown: True", + "Light_test: Entity deleted: True", + "Light_test: UNDO entity deletion works: True", + "Light_test: REDO entity deletion works: True", + # Display Mapper Component + "Display Mapper Entity successfully created", + "Display Mapper_test: Component added to the entity: True", + "Display Mapper_test: Component removed after UNDO: True", + "Display Mapper_test: Component added after REDO: True", + "Display Mapper_test: Entered game mode: True", + "Display Mapper_test: Exit game mode: True", + "Display Mapper_test: Entity is hidden: True", + "Display Mapper_test: Entity is shown: True", + "Display Mapper_test: Entity deleted: True", + "Display Mapper_test: UNDO entity deletion works: True", + "Display Mapper_test: REDO entity deletion works: True", + ] + + unexpected_lines = [ + "failed to open", + "Traceback (most recent call last):", + ] - # It requires at least one test - def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): - pass + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_AtomEditorComponents_AddedToEntity.py", + timeout=EDITOR_TIMEOUT, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + null_renderer=True, + cfg_args=cfg_args, + ) diff --git a/AutomatedTesting/Registry/assets_scan_folders.setreg b/AutomatedTesting/Registry/assets_scan_folders.setreg index 5394d381a3..91061f3337 100644 --- a/AutomatedTesting/Registry/assets_scan_folders.setreg +++ b/AutomatedTesting/Registry/assets_scan_folders.setreg @@ -38,6 +38,13 @@ "Gems/PrimitiveAssets" ] }, + "MaterialEditor": + { + "SourcePaths": + [ + "Gems/Atom/Tools/MaterialEditor" + ] + }, "UiBasics": { "SourcePaths": diff --git a/AutomatedTesting/sounds/wwise_project/Helios.wproj b/AutomatedTesting/sounds/wwise_project/Helios.wproj deleted file mode 100644 index 3db6efcfdf..0000000000 --- a/AutomatedTesting/sounds/wwise_project/Helios.wproj +++ /dev/null @@ -1,13159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - GeneratedSoundBanks\Windows - - - - - 256 - - - - - - ..\wwise\ - - - - - Copy Streamed Files and Generate Dependency Info - - - - - "$(WwiseExePath)\CopyStreamedFiles.exe" -info "$(InfoFilePath)" -outputpath "$(SoundBankPath)" -banks "$(SoundBankListAsTextFile)" -languages "$(LanguageList)" -"$(WwiseProjectPath)\..\..\..\Tools\Python\python3.cmd" "$(WwiseProjectPath)\..\..\..\Gems\AudioEngineWwise\Tools\WwiseAuthoringScripts\bank_info_parser.py" "$(InfoFilePath)" "$(SoundBankPath)" - - - - - - - - - - - - - - - -80 - - - - - - - - - - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 8 - - - - - 0 - - - - - -1 - - - - - -1 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - -1 - - - - - -1 - - - - - 0 - - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - 0 - - - - - False - - - - - True - - - - - False - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 2 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - False - - - - - 65535 - - - - - 127 - - - - - 0 - - - - - 1 - - - - - 60 - - - - - 0 - - - - - 127 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 50 - - - - - - - - - 1 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - 10000 - - - - - 1 - - - - - 400 - - - - - 1 - - - - - 1 - - - - - 0.5 - - - - - 0 - - - - - -96 - - - - - 0 - - - - - True - - - - - False - - - - - 0 - - - - - 0 - - - - - 16 - - - - - -96 - - - - - 0 - - - - - 48000 - - - - - 0 - - - - - - - - - 16 - - - - - False - - - - - 1 - - - - - 75 - - - - - - - - - False - - - - - 512 - - - - - -50 - - - - - -30 - - - - - -40 - - - - - 0 - - - - - 24024 - - - - - 0 - - - - - 8 - - - - - English(US) - - - - - 0 - - - - - 0 - - - - - False - - - - - - - - - - - - - - - 1 - - - - - True - - - - - False - - - - - False - - - - - True - - - - - 256 - - - - - - - - - - 50 - - - - - 100 - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - - - - - True - - - - - True - - - - - True - - - - - True - - - - - -80 - - - - - - - - - - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 64 - - - - - 1.5 - - - - - 2 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - 64 - - - - - 64 - - - - - 4 - - - - - 0 - - - - - 0.1 - - - - - 4 - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 20 - - - - - 10000 - - - - - 0.2 - - - - - True - - - - - 80 - - - - - 0.2 - - - - - False - - - - - 200 - - - - - 0.25 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - True - - - - - True - - - - - True - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 4 - - - - - 4 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - True - - - - - 0 - - - - - 100 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 10 - - - - - 1 - - - - - 200 - - - - - 0 - - - - - 0 - - - - - 10 - - - - - 1 - - - - - 200 - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 40 - - - - - 0 - - - - - 1000 - - - - - 160 - - - - - 0 - - - - - 0.5 - - - - - 0.2 - - - - - 0 - - - - - 0.5 - - - - - 0.2 - - - - - 0 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 0.2 - - - - - 0 - - - - - 0.2 - - - - - 0.2 - - - - - 3000 - - - - - 0.2 - - - - - 0 - - - - - 6 - - - - - 15000 - - - - - 0 - - - - - 1000 - - - - - 20000 - - - - - 0 - - - - - 0.5 - - - - - 0.2 - - - - - 0 - - - - - 0.5 - - - - - 0.2 - - - - - 0 - - - - - 1 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - 1 - - - - - False - - - - - - - - - 1 - - - - - 0 - - - - - True - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - False - - - - - 3 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - False - - - - - 65535 - - - - - 127 - - - - - 0 - - - - - 1 - - - - - 60 - - - - - 0 - - - - - 127 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - False - - - - - 65535 - - - - - 127 - - - - - 0 - - - - - 1 - - - - - 60 - - - - - 0 - - - - - 127 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 1 - - - - - False - - - - - 2 - - - - - True - - - - - False - - - - - 0 - - - - - 1 - - - - - 1 - - - - - 50 - - - - - False - - - - - -10 - - - - - True - - - - - 1 - - - - - 1 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 1 - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 50 - - - - - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 5 - - - - - 0.5 - - - - - 0 - - - - - True - - - - - 5000 - - - - - 10000 - - - - - False - - - - - - - - - False - - - - - 0 - - - - - 3 - - - - - 9 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - False - - - - - 65535 - - - - - 127 - - - - - 0 - - - - - 1 - - - - - 60 - - - - - 0 - - - - - 127 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - 0 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 50 - - - - - - - - - 1000 - - - - - 5000 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 96 - - - - - -100 - - - - - -100 - - - - - -100 - - - - - False - - - - - False - - - - - - - - - False - - - - - 0 - - - - - 35 - - - - - 0 - - - - - True - - - - - 0 - - - - - 1 - - - - - 1 - - - - - True - - - - - - - - - 0 - - - - - - - - - False - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 3 - - - - - 9 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - False - - - - - 0 - - - - - False - - - - - - - - - 3 - - - - - 64 - - - - - - - - - 0 - - - - - False - - - - - False - - - - - - - - - 3 - - - - - 64 - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 100 - - - - - 0 - - - - - True - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 100 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - -96 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 100 - - - - - 0 - - - - - False - - - - - 0 - - - - - 50 - - - - - 50 - - - - - 50 - - - - - - - - - False - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - 4000 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 1 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - 120 - - - - - 4 - - - - - 4 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 100 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 100 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - False - - - - - 65535 - - - - - 127 - - - - - 0 - - - - - 1 - - - - - 60 - - - - - 0 - - - - - 127 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 50 - - - - - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 1 - - - - - - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - 0 - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - True - - - - - False - - - - - False - - - - - True - - - - - True - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - - -1 - - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 1 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - 120 - - - - - 4 - - - - - 4 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - True - - - - - True - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 12 - - - - - False - - - - - 20 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 1 - - - - - 50 - - - - - False - - - - - -10 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 100 - - - - - 120 - - - - - 4 - - - - - 4 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 1 - - - - - 1 - - - - - False - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 50 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 7 - - - - - - - - - - False - - - - - 1 - - - - - - - - - - False - - - - - True - - - - - True - - - - - True - - - - - True - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - - - - - 4 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - -6 - - - - - 0 - - - - - 90 - - - - - 0 - - - - - 245 - - - - - False - - - - - False - - - - - 100 - - - - - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - False - - - - - 100 - - - - - - - - - True - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - False - - - - - - - - - - - - - - - False - - - - - False - - - - - True - - - - - False - - - - - False - - - - - True - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - True - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - True - - - - - False - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - - - - - True - - - - - - - - - 0 - - - - - False - - - - - - - - - - - - - - - - - - True - - - - - 4 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - - - - - 0 - - - - - False - - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - 1 - - - - - 8 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - 100 - - - - - 0 - - - - - True - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 100 - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 100 - - - - - 1 - - - - - 0 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - False - - - - - - - - - 0 - - - - - 50 - - - - - 0.2 - - - - - False - - - - - 0.2 - - - - - 0.5 - - - - - True - - - - - 100 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - False - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - - - - - - 1 - - - - - False - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - - - - - - 1 - - - - - False - - - - - 0 - - - - - - - - - - 0 - - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - - - - - 0 - - - - - - - - - 0 - - - - - False - - - - - - - - - 0 - - - - - - - - - 0 - - - - - True - - - - - 1 - - - - - 1 - - - - - False - - - - - 1 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - - - - - - 4 - - - - - 1 - - - - - 440 - - - - - -12 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 1 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 4 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - -12 - - - - - 1 - - - - - False - - - - - 0 - - - - - -12 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - False - - - - - 10 - - - - - 0 - - - - - - - - - 0 - - - - - 4 - - - - - 6 - - - - - 5 - - - - - 100 - - - - - 1000 - - - - - 12000 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - True - - - - - True - - - - - True - - - - - 0 - - - - - False - - - - - True - - - - - 1 - - - - - 1 - - - - - 1 - - - - - - - - - 0 - - - - - 0.5 - - - - - 15 - - - - - True - - - - - True - - - - - 0 - - - - - False - - - - - True - - - - - 25 - - - - - - - - - 0.1 - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - True - - - - - 1.5 - - - - - 0.1 - - - - - 0 - - - - - - - - - 0.1 - - - - - True - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - True - - - - - 3 - - - - - 0.01 - - - - - -40 - - - - - - - - - True - - - - - 0 - - - - - True - - - - - 0.01 - - - - - 0 - - - - - False - - - - - True - - - - - 10 - - - - - 0.1 - - - - - 0 - - - - - - - - - 100 - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - 1 - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - True - - - - - 40 - - - - - 0 - - - - - 0 - - - - - 18000 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - True - - - - - 10 - - - - - 0 - - - - - 100 - - - - - -40 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - True - - - - - 40 - - - - - 18000 - - - - - -96 - - - - - -20 - - - - - 20 - - - - - 0 - - - - - 0 - - - - - False - - - - - True - - - - - 100 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 13.62 - - - - - 26.09 - - - - - 26.55 - - - - - 26.91 - - - - - 28.04 - - - - - 29.09 - - - - - 29.9 - - - - - 30.86 - - - - - 15.66 - - - - - 17.52 - - - - - 19.02 - - - - - 20.83 - - - - - 22.6 - - - - - 24.05 - - - - - 24.78 - - - - - 25.6 - - - - - -96.3 - - - - - 2 - - - - - True - - - - - 8 - - - - - False - - - - - 0 - - - - - True - - - - - 4 - - - - - -35 - - - - - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - True - - - - - 0 - - - - - True - - - - - 100 - - - - - 0 - - - - - False - - - - - -96.3 - - - - - - - - - 0 - - - - - 0 - - - - - 40 - - - - - 1.2 - - - - - 80 - - - - - 50 - - - - - 8 - - - - - 2 - - - - - 100 - - - - - 15 - - - - - 5 - - - - - 66 - - - - - -96.3 - - - - - 0 - - - - - -20 - - - - - 23 - - - - - True - - - - - False - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 3 - - - - - 1 - - - - - 1 - - - - - 1000 - - - - - 0 - - - - - 3 - - - - - 1 - - - - - 2 - - - - - 10000 - - - - - 0 - - - - - 3 - - - - - 1 - - - - - 0 - - - - - 2.25 - - - - - True - - - - - 0 - - - - - -96.3 - - - - - -96.3 - - - - - False - - - - - 25 - - - - - 8 - - - - - 0 - - - - - -20 - - - - - 100 - - - - - 50 - - - - - 100 - - - - - 0.8 - - - - - 0.1 - - - - - 0 - - - - - 180 - - - - - - - - - 1 - - - - - 0 - - - - - False - - - - - 0 - - - - - 1 - - - - - 0 - - - - - False - - - - - 0 - - - - - 10 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0.5 - - - - - False - - - - - 0 - - - - - 10 - - - - - 5 - - - - - 1 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0.25 - - - - - False - - - - - 0 - - - - - 0.5 - - - - - - - - - 1 - - - - - 1 - - - - - True - - - - - 0.5 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - False - - - - - 0 - - - - - 10 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - False - - - - - 10 - - - - - 0.5 - - - - - 0 - - - - - 1 - - - - - - - - - 440 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 10 - - - - - - - - - False - - - - - 440 - - - - - 0 - - - - - 10 - - - - - 1 - - - - - - - - - 0 - - - - - 5 - - - - - 1 - - - - - True - - - - - 0 - - - - - 1 - - - - - True - - - - - 50 - - - - - 1 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - False - - - - - 100 - - - - - - - - - 0 - - - - - 50 - - - - - 50 - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 100 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - -96.3 - - - - - 0 - - - - - 0 - - - - - False - - - - - 4 - - - - - 0 - - - - - 100 - - - - - 0 - - - - - 0 - - - - - -75 - - - - - False - - - - - False - - - - - 6 - - - - - 0 - - - - - 0 - - - - - True - - - - - 100 - - - - - True - - - - - 0 - - - - - -96.3 - - - - - 0 - - - - - -60 - - - - - -96.3 - - - - - False - - - - - 0 - - - - - 0 - - - - - 1024 - - - - - 48000 - - - - - 48000 - - - - - 48000 - - - - - 180 - - - - - 0 - - - - - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - 0 - - - - - -48 - - - - - False - - - - - 0.1 - - - - - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - 100 - - - - - 0 - - - - - 2048 - - - - - - - - - 0 - - - - - True - - - - - 100 - - - - - 1 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - True - - - - - True - - - - - - - - - 1 - - - - - False - - - - - Recorder.wav - - - - - -3 - - - - - 0 - - - - - True - - - - - 0 - - - - - 0 - - - - - - - - - - True - - - - - -96.3 - - - - - False - - - - - -3 - - - - - -3 - - - - - - - - - 0 - - - - - 0 - - - - - False - - - - - False - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - -100 - - - - - True - - - - - -12 - - - - - 0.1 - - - - - -12 - - - - - 0 - - - - - False - - - - - -12 - - - - - 0.1 - - - - - -12 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - 50 - - - - - -96 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - 0 - - - - - False - - - - - False - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - False - - - - - True - - - - - True - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1024 - - - - - - - - - 0 - - - - - 0 - - - - - True - - - - - 0 - - - - - False - - - - - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - -96 - - - - - 0 - - - - - 0 - - - - - False - - - - - -6 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - False - - - - - -6 - - - - - 50 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - - - - - False - - - - - False - - - - - - - - - 1 - - - - - 0 - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 250 - - - - - 100 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - -96 - - - - - 3 - - - - - True - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - False - - - - - 0.5 - - - - - 0 - - - - - 2400 - - - - - 345 - - - - - 0 - - - - - 0 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 1 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - False - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 100 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 10 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 20000 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0.707 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1000 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 256 - - - - - False - - - - - 100 - - - - - 100 - - - - - 100 - - - - - 100 - - - - - 1000 - - - - - 1000 - - - - - 1000 - - - - - 1000 - - - - - 20000 - - - - - 20000 - - - - - 20000 - - - - - 20000 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 5 - - - - - 5 - - - - - 9 - - - - - 9 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 16641 - - - - - 0 - - - - - 0 - - - - - False - - - - - 10 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 60 - - - - - 1 - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - 0 - - - - - True - - - - - False - - - - - 0.01 - - - - - True - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0.1 - - - - - 0 - - - - - 0.01 - - - - - True - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0.1 - - - - - 0 - - - - - 0.01 - - - - - True - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0.1 - - - - - 0 - - - - - 0.01 - - - - - True - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0.1 - - - - - 0 - - - - - 150 - - - - - 1000 - - - - - 6000 - - - - - 0 - - - - - False - - - - - 0 - - - - - 4 - - - - - 0 - - - - - False - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - True - - - - - True - - - - - True - - - - - True - - - - - True - - - - - 5 - - - - - 100 - - - - - 0 - - - - - 1 - - - - - True - - - - - 3 - - - - - 200 - - - - - 0 - - - - - 1 - - - - - True - - - - - 3 - - - - - 500 - - - - - 0 - - - - - 1 - - - - - True - - - - - 4 - - - - - 1000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 3 - - - - - 3000 - - - - - 0 - - - - - 1 - - - - - False - - - - - 3 - - - - - 6000 - - - - - 0 - - - - - 1 - - - - - 4 - - - - - - - - - -12 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - False - - - - - - - - - 1 - - - - - 0 - - - - - - - - - 0 - - - - - 0 - - - - - 1 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - -12 - - - - - 1 - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 6 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - - - - - 1 - - - - - 1 - - - - - 1 - - - - - 0 - - - - - - - - - - 0 - - - - - 0 - - - - - - - - - 0.6 - - - - - 0.6 - - - - - 0.5 - - - - - 0.3 - - - - - 0.05 - - - - - 0.25 - - - - - 0.02 - - - - - 1.5 - - - - - 0.2 - - - - - 0.3 - - - - - True - - - - - 0.2 - - - - - 8 - - - - - 0.2 - - - - - 12 - - - - - - - - - 20 - - - - - 0.7 - - - - - 100 - - - - - 0.1 - - - - - 1 - - - - - 1 - - - - - True - - - - - 1 - - - - - 0 - - - - - 3 - - - - - 1 - - - - - - - - - 2 - - - - - 0.7 - - - - - 1 - - - - - 0 - - - - - 1 - - - - - 0.9 - - - - - 0.1 - - - - - 3 - - - - - - - - - 0 - - - - - True - - - - - False - - - - - - - - - 0 - - - - - False - - - - - False - - - - - True - - - - - 0 - - - - - 0 - - - - - - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - False - - - - - 2 - - - - - False - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - 0 - - - - - - - - - False - - - - - 0 - - - - - 0 - - - - - 1.4 - - - - - -6 - - - - - True - - - - - 0 - - - - - 0 - - - - - False - - - - - True - - - - - 0.5 - - - - - 10000 - - - - - -6 - - - - - 7 - - - - - 1 - - - - - 1 - - - - - 7.25 - - - - - 2.75 - - - - - 3.25 - - - - - 4.25 - - - - - 4.75 - - - - - 3.75 - - - - - - - - - 100 - - - - - 50 - - - - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - -200 - 37 - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - 100 - 37 - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - 100 - 37 - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - -200 - 37 - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - 100 - 37 - - - - - - - - - - - - - - 0 - 0 - 5 - - - 100 - 100 - 37 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CMakeLists.txt b/CMakeLists.txt index ad5cd9f431..ae8a7a05f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# Cmake version 3.17 is the minimum version needed for all of Open 3D Engine's supported platforms +# Cmake version 3.19 is the minimum version needed for all of Open 3D Engine's supported platforms cmake_minimum_required(VERSION 3.19) # CMP0111 introduced in 3.19 has a bug that produces the policy to warn every time there is an @@ -75,7 +75,9 @@ foreach(restricted_platform ${PAL_RESTRICTED_PLATFORMS}) endif() endforeach() -add_subdirectory(scripts) +if(NOT INSTALLED_ENGINE) + add_subdirectory(scripts) +endif() # SPEC-1417 will investigate and fix this if(NOT PAL_PLATFORM_NAME STREQUAL "Mac") @@ -125,5 +127,5 @@ if(NOT INSTALLED_ENGINE) ly_setup_o3de_install() # IMPORTANT: must be included last - include(cmake/CPack.cmake) + include(cmake/Packaging.cmake) endif() diff --git a/Code/CryEngine/CMakeLists.txt b/Code/CryEngine/CMakeLists.txt index 1735224146..96f6427268 100644 --- a/Code/CryEngine/CMakeLists.txt +++ b/Code/CryEngine/CMakeLists.txt @@ -9,8 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -add_subdirectory(Cry3DEngine) add_subdirectory(CryCommon) -add_subdirectory(CryFont) add_subdirectory(CrySystem) -add_subdirectory(RenderDll) diff --git a/Code/CryEngine/Cry3DEngine/3DEngineLight.cpp b/Code/CryEngine/Cry3DEngine/3DEngineLight.cpp deleted file mode 100644 index 054620003c..0000000000 --- a/Code/CryEngine/Cry3DEngine/3DEngineLight.cpp +++ /dev/null @@ -1,733 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Light sources manager - - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "AABBSV.h" -#include "LightEntity.h" -#include "ObjectsTree.h" -#include "ClipVolumeManager.h" - -ILightSource* C3DEngine::CreateLightSource() -{ - // construct new object - CLightEntity* pLightEntity = new CLightEntity(); - - m_lstStaticLights.Add(pLightEntity); - - return pLightEntity; -} - -void C3DEngine::DeleteLightSource(ILightSource* pLightSource) -{ - if (m_lstStaticLights.Delete((CLightEntity*)pLightSource) || pLightSource == m_pSun) - { - if (pLightSource == m_pSun) - { - m_pSun = NULL; - } - - delete pLightSource; - } - else - { - assert(!"Light object not found"); - } -} - -void CLightEntity::Release(bool) -{ - Get3DEngine()->UnRegisterEntityDirect(this); - Get3DEngine()->DeleteLightSource(this); -} - -void CLightEntity::SetLightProperties(const CDLight& light) -{ - C3DEngine* engine = Get3DEngine(); - - m_light = light; - - m_bShadowCaster = (m_light.m_Flags & DLF_CASTSHADOW_MAPS) != 0; - - m_light.m_fBaseRadius = m_light.m_fRadius; - m_light.m_fLightFrustumAngle = CLAMP(m_light.m_fLightFrustumAngle, 0.f, (LIGHT_PROJECTOR_MAX_FOV / 2.f)); - - if (!(m_light.m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT))) - { - m_light.m_fLightFrustumAngle = 90.f / 2.f; - } - - m_light.m_pOwner = this; - - if (m_light.m_Flags & DLF_ATTACH_TO_SUN) - { - m_dwRndFlags |= ERF_RENDER_ALWAYS | ERF_HUD; - } - - engine->GetLightEntities()->Delete((ILightSource*)this); - - PodArray& lightEntities = *engine->GetLightEntities(); - - //on consoles we force all lights (except sun) to be deferred - if (GetCVars()->e_DynamicLightsForceDeferred && !(m_light.m_Flags & (DLF_SUN | DLF_POST_3D_RENDERER))) - { - m_light.m_Flags |= DLF_DEFERRED_LIGHT; - } - - if (light.m_Flags & DLF_DEFERRED_LIGHT) - { - lightEntities.Add((ILightSource*)this); - } - else - { - lightEntities.InsertBefore((ILightSource*)this, 0); - } -} - -void C3DEngine::ResetCasterCombinationsCache() -{ - for (int nSunInUse = 0; nSunInUse < 2; nSunInUse++) - { - // clear user counters - for (ShadowFrustumListsCacheUsers::iterator it = m_FrustumsCacheUsers[nSunInUse].begin(); it != m_FrustumsCacheUsers[nSunInUse].end(); ++it) - { - it->second = 0; - } - } -} - -void C3DEngine::DeleteAllStaticLightSources() -{ - for (int i = 0; i < m_lstStaticLights.Count(); i++) - { - delete m_lstStaticLights[i]; - } - m_lstStaticLights.Reset(); - - m_pSun = NULL; -} - -void C3DEngine::InitShadowFrustums(const SRenderingPassInfo& passInfo) -{ - assert(passInfo.IsGeneralPass()); - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - if (m_pSun) - { - CDLight* pLight = &m_pSun->GetLightProperties(); - CLightEntity* pLightEntity = (CLightEntity*)pLight->m_pOwner; - - if (passInfo.RenderShadows() && (pLight->m_Flags & DLF_CASTSHADOW_MAPS) && pLight->m_Id >= 0) - { - pLightEntity->UpdateGSMLightSourceShadowFrustum(passInfo); - - if (pLightEntity->m_pShadowMapInfo) - { - pLight->m_pShadowMapFrustums = pLightEntity->m_pShadowMapInfo->pGSM; - } - } - - _smart_ptr pMat = pLightEntity->GetMaterial(); - if (pMat) - { - pLight->m_Shader = pMat->GetShaderItem(); - } - - // update copy of light ion the renderer - if (pLight->m_Id >= 0) - { - CDLight* pRndLight = NULL; - GetRenderer()->EF_Query(EFQ_LightSource, pLight->m_Id, pRndLight); - assert(pLight->m_Id == pRndLight->m_Id); - pRndLight->m_pShadowMapFrustums = pLight->m_pShadowMapFrustums; - pRndLight->m_Shader = pLight->m_Shader; - pRndLight->m_Flags = pLight->m_Flags; - } - - // add per object shadow frustums - m_nCustomShadowFrustumCount = 0; - if (passInfo.RenderShadows() && GetCVars()->e_ShadowsPerObject > 0) - { - const uint nFrustumCount = m_lstPerObjectShadows.size(); - if (nFrustumCount > m_lstCustomShadowFrustums.size()) - { - m_lstCustomShadowFrustums.resize(nFrustumCount); - } - - for (uint i = 0; i < nFrustumCount; ++i) - { - if (m_lstPerObjectShadows[i].pCaster) - { - ShadowMapFrustum* pFr = &m_lstCustomShadowFrustums[i]; - pFr->m_eFrustumType = ShadowMapFrustum::e_PerObject; - - CLightEntity::ProcessPerObjectFrustum(pFr, &m_lstPerObjectShadows[i], m_pSun, passInfo); - ++m_nCustomShadowFrustumCount; - } - } - } - } - - if (passInfo.RenderShadows()) - { - ResetCasterCombinationsCache(); - } -} - -void C3DEngine::AddPerObjectShadow(IShadowCaster* pCaster, float fConstBias, float fSlopeBias, float fJitter, const Vec3& vBBoxScale, uint nTexSize) -{ - SPerObjectShadow* pOS = GetPerObjectShadow(pCaster); - if (!pOS) - { - pOS = &m_lstPerObjectShadows.AddNew(); - } - - pOS->pCaster = pCaster; - pOS->fConstBias = fConstBias; - pOS->fSlopeBias = fSlopeBias; - pOS->fJitter = fJitter; - pOS->vBBoxScale = vBBoxScale; - pOS->nTexSize = nTexSize; -} - -void C3DEngine::RemovePerObjectShadow(IShadowCaster* pCaster) -{ - SPerObjectShadow* pOS = GetPerObjectShadow(pCaster); - if (pOS) - { - FRAME_PROFILER("C3DEngine::RemovePerObjectShadow", GetSystem(), PROFILE_3DENGINE); - - size_t nIndex = (size_t)(pOS - m_lstPerObjectShadows.begin()); - m_lstPerObjectShadows.Delete(nIndex); - } -} - -struct SPerObjectShadow* C3DEngine::GetPerObjectShadow(IShadowCaster* pCaster) -{ - for (int i = 0; i < m_lstPerObjectShadows.Count(); ++i) - { - if (m_lstPerObjectShadows[i].pCaster == pCaster) - { - return &m_lstPerObjectShadows[i]; - } - } - - return NULL; -} - -void C3DEngine::GetCustomShadowMapFrustums(ShadowMapFrustum*& arrFrustums, int& nFrustumCount) -{ - arrFrustums = m_lstCustomShadowFrustums.begin(); - nFrustumCount = m_nCustomShadowFrustumCount; -} - -// delete pLight->m_pProjCamera; -//pLight->m_pProjCamera=0; -//if(pLight->m_pShader) -// SAFE_RELEASE(pLight->m_pShader); -namespace -{ - static inline bool CmpCastShadowFlag(const CDLight* p1, const CDLight* p2) - { - // move sun first - if ((p1->m_Flags & DLF_SUN) > (p2->m_Flags & DLF_SUN)) - { - return true; - } - else if ((p1->m_Flags & DLF_SUN) < (p2->m_Flags & DLF_SUN)) - { - return false; - } - - // move shadow casters first - if ((p1->m_Flags & DLF_CASTSHADOW_MAPS) > (p2->m_Flags & DLF_CASTSHADOW_MAPS)) - { - return true; - } - else if ((p1->m_Flags & DLF_CASTSHADOW_MAPS) < (p2->m_Flags & DLF_CASTSHADOW_MAPS)) - { - return false; - } - - // get some sorting consistency for shadow casters - if (p1->m_pOwner > p2->m_pOwner) - { - return true; - } - else if (p1->m_pOwner < p2->m_pOwner) - { - return false; - } - - return false; - } -} - -////////////////////////////////////////////////////////////////////////// - -void C3DEngine::SubmitSun(const SRenderingPassInfo& passInfo) -{ - assert(passInfo.IsGeneralPass()); - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - if (m_pSun) - { - CDLight* light = &m_pSun->GetLightProperties(); - - GetRenderer()->EF_ADDDlight(light, passInfo); - } -} - -void C3DEngine::RemoveEntityLightSources(IRenderNode* pEntity) -{ - for (int i = 0; i < m_lstStaticLights.Count(); i++) - { - if (m_lstStaticLights[i] == pEntity) - { - m_lstStaticLights.Delete(i); - if (pEntity == m_pSun) - { - m_pSun = NULL; - } - i--; - } - } -} - -ILightSource* C3DEngine::GetSunEntity() -{ - return m_pSun; -} - -void C3DEngine::OnCasterDeleted(IShadowCaster* pCaster) -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_3DENGINE); - { // make sure pointer to object will not be used somewhere in the renderer - if (m_pSun) - { - m_pSun->OnCasterDeleted(pCaster); - } - - if (GetRenderer()->GetActiveGPUCount() > 1) - { - if (ShadowFrustumMGPUCache* pFrustumCache = GetRenderer()->GetShadowFrustumMGPUCache()) - { - pFrustumCache->DeleteFromCache(pCaster); - } - } - - // remove from per object shadows list - RemovePerObjectShadow(pCaster); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::Init() -{ - m_bUpdateLightVolumes = false; - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pLightVolumes[i].reserve(LV_MAX_COUNT); - m_pLightVolsInfo[i].reserve(LV_MAX_COUNT); - } - memset(m_nWorldCells, 0, sizeof(m_nWorldCells)); - memset(m_pWorldLightCells, 0, sizeof(m_pWorldLightCells)); -} - -void CLightVolumesMgr::Reset() -{ - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - stl::free_container(m_pLightVolumes[i]); - } - - m_bUpdateLightVolumes = false; - memset(m_nWorldCells, 0, sizeof(m_nWorldCells)); - memset(m_pWorldLightCells, 0, sizeof(m_pWorldLightCells)); -} - -////////////////////////////////////////////////////////////////////////// - -uint16 CLightVolumesMgr::RegisterVolume(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo) -{ - DynArray& lightVolsInfo = m_pLightVolsInfo[passInfo.ThreadID()]; - - IF ((m_bUpdateLightVolumes && (lightVolsInfo.size() < LV_MAX_COUNT)) && fRadius < 256.0f, 1) - { - FUNCTION_PROFILER_3DENGINE; - - int32 nPosx = (int32)(floorf(vPos.x * LV_CELL_RSIZEX)); - int32 nPosy = (int32)(floorf(vPos.y * LV_CELL_RSIZEY)); - int32 nPosz = (int32)(floorf(vPos.z * LV_CELL_RSIZEZ)); - - // Check if world cell has any light volume, else add new one - uint16 nHashIndex = GetWorldHashBucketKey(nPosx, nPosy, nPosz); - uint16* pCurrentVolumeID = &m_nWorldCells[nHashIndex]; - - while (*pCurrentVolumeID != 0) - { - SLightVolInfo& sVolInfo = *lightVolsInfo[*pCurrentVolumeID - 1]; - - int32 nVolumePosx = (int32)(floorf(sVolInfo.vVolume.x * LV_CELL_RSIZEX)); - int32 nVolumePosy = (int32)(floorf(sVolInfo.vVolume.y * LV_CELL_RSIZEY)); - int32 nVolumePosz = (int32)(floorf(sVolInfo.vVolume.z * LV_CELL_RSIZEZ)); - - if (nPosx == nVolumePosx && - nPosy == nVolumePosy && - nPosz == nVolumePosz && - nClipVolumeRef == sVolInfo.nClipVolumeID) - { - return (uint16) * pCurrentVolumeID; - } - - pCurrentVolumeID = &sVolInfo.nNextVolume; - } - - // create new volume - SLightVolInfo* pLightVolInfo = new SLightVolInfo(vPos, fRadius, nClipVolumeRef); - lightVolsInfo.push_back(pLightVolInfo); - *pCurrentVolumeID = lightVolsInfo.size(); - - return *pCurrentVolumeID; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::RegisterLight(const CDLight& pDL, uint32 nLightID, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - IF ((m_bUpdateLightVolumes && !(pDL.m_Flags & LV_DLF_LIGHTVOLUMES_MASK)), 1) - { - FUNCTION_PROFILER_3DENGINE; - - const f32 fColCheck = (f32) fsel(pDL.m_Color.r + pDL.m_Color.g + pDL.m_Color.b - 0.333f, 1.0f, 0.0f); //light color > threshold - const f32 fRadCheck = (f32) fsel(pDL.m_fRadius - 0.5f, 1.0f, 0.0f); //light radius > threshold - if (fColCheck * fRadCheck) - { - //if the radius is large than certain value, all the the world light cells will be lighted anyway. So we just add the light to all the cells - //the input radius restriction will be added too - if(floorf(pDL.m_fRadius*LV_LIGHT_CELL_R_SIZE) > LV_LIGHTS_WORLD_BUCKET_SIZE) - { - for (int32 idx = 0; idx < LV_LIGHTS_WORLD_BUCKET_SIZE; idx++) - { - SLightCell& lightCell = m_pWorldLightCells[idx]; - CryPrefetch(&lightCell); - if (lightCell.nLightCount < LV_LIGHTS_MAX_COUNT) - { - lightCell.nLightID[lightCell.nLightCount] = nLightID; - lightCell.nLightCount += 1; - } - } - } - else - { - int32 nMiny = (int32)(floorf((pDL.m_Origin.y - pDL.m_fRadius) * LV_LIGHT_CELL_R_SIZE)); - int32 nMaxy = (int32)(floorf((pDL.m_Origin.y + pDL.m_fRadius) * LV_LIGHT_CELL_R_SIZE)); - int32 nMinx = (int32)(floorf((pDL.m_Origin.x - pDL.m_fRadius) * LV_LIGHT_CELL_R_SIZE)); - int32 nMaxx = (int32)(floorf((pDL.m_Origin.x + pDL.m_fRadius) * LV_LIGHT_CELL_R_SIZE)); - - // Register light into all cells touched by light radius - for (int32 y = nMiny, ymax = nMaxy; y <= ymax; ++y) - { - for (int32 x = nMinx, xmax = nMaxx; x <= xmax; ++x) - { - SLightCell& lightCell = m_pWorldLightCells[GetWorldHashBucketKey(x, y, 1, LV_LIGHTS_WORLD_BUCKET_SIZE)]; - CryPrefetch(&lightCell); - if (lightCell.nLightCount < LV_LIGHTS_MAX_COUNT) - { - //only if the las light added to the cell wasn't the same light - if (!(lightCell.nLightCount > 0 && lightCell.nLightID[lightCell.nLightCount - 1] == nLightID)) - { - lightCell.nLightID[lightCell.nLightCount] = nLightID; - lightCell.nLightCount += 1; - } - } - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::AddLight(const SRenderLight& pLight, const SLightVolInfo* __restrict pVolInfo, SLightVolume& pVolume) -{ - // Check for clip volume - if (pLight.m_nStencilRef[0] == pVolInfo->nClipVolumeID || pLight.m_nStencilRef[1] == pVolInfo->nClipVolumeID || - pLight.m_nStencilRef[0] == CClipVolumeManager::AffectsEverythingStencilRef) - { - const Vec4* __restrict vLight = (Vec4*) &pLight.m_Origin.x; - const Vec4& vVolume = pVolInfo->vVolume; - const f32 fDimCheck = (f32) fsel(vLight->w - vVolume.w * 0.1f, 1.0f, 0.0f); //light radius not more than 10x smaller than volume radius - const f32 fOverlapCheck = (f32) fsel(sqr(vVolume.x - vLight->x) + sqr(vVolume.y - vLight->y) + sqr(vVolume.z - vLight->z) - sqr(vVolume.w + vLight->w), 0.0f, 1.0f);// touches volumes - if (fDimCheck * fOverlapCheck) - { - float fAttenuationBulbSize = pLight.m_fAttenuationBulbSize; - Vec3 lightColor = *((Vec3*)&pLight.m_Color); - - // Adjust light intensity so that the intended brightness is reached 1 meter from the light's surface - IF (!(pLight.m_Flags & (DLF_AREA_LIGHT | DLF_AMBIENT)), 1) - { - fAttenuationBulbSize = max(fAttenuationBulbSize, 0.001f); - - // Solve I * 1 / (1 + d/lightsize)^2 = 1 - float intensityMul = 1.0f + 1.0f / fAttenuationBulbSize; - intensityMul *= intensityMul; - lightColor *= intensityMul; - } - - pVolume.pData.push_back(); - SLightVolume::SLightData& lightData = pVolume.pData[pVolume.pData.size() - 1]; - lightData.vPos = *vLight; - lightData.vColor = Vec4(lightColor, fAttenuationBulbSize); - lightData.vParams = Vec4(0.f, 0.f, 0.f, 0.f); - - IF (pLight.m_Flags & DLF_PROJECT, 1) - { - lightData.vParams = Vec4(pLight.m_ObjMatrix.GetColumn0(), cos_tpl(DEG2RAD(pLight.m_fLightFrustumAngle))); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::Update(const SRenderingPassInfo& passInfo) -{ - uint32 nThreadID = passInfo.ThreadID(); - DynArray& lightVolsInfo = m_pLightVolsInfo[nThreadID]; - - if (!m_bUpdateLightVolumes || lightVolsInfo.empty()) - { - return; - } - - FUNCTION_PROFILER_3DENGINE; - TArray* pLights = GetRenderer()->EF_GetDeferredLights(passInfo); - const uint32 nLightCount = pLights->size(); - - uint32 nLightVols = lightVolsInfo.size(); - LightVolumeVector& lightVols = m_pLightVolumes[nThreadID]; - uint32 existingLightVolsCount = 0; //This is 0, that just means we will be overwriting all existing light volumes - - //If this is a recursive pass (not the first time that this is called this frame), we're just going to be adding on new light volumes to the existing collection - if (passInfo.IsRecursivePass()) - { - existingLightVolsCount = lightVols.size(); - - //If no new light volumes have been added, don't bother updating - if (nLightVols == existingLightVolsCount) - { - return; - } - } - - lightVols.resize(nLightVols); - - if (!nLightCount) - { - //Start out existingLightVolsCount to avoid clearing out existing light volumes when we don't need to - for (uint32 v = existingLightVolsCount; v < nLightVols; ++v) - { - lightVols[v].pData.resize(0); - } - - return; - } - - const int MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE = 1024; - - if (nLightCount > MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "More lights in the scene (%d) than supported by the Light Volume Update function (%d). Extra lights will be ignored.", - nLightCount, MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE); - } - - //This can be a uint8 array because nLightVols should never be greater than 256(LV_MAX_COUNT) - assert(LV_MAX_COUNT <= 256); - uint8 lightProcessedStateArray[MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE]; - - //Start at the number of light volumes that already exist so that we don't end up re-updating light volumes unnecessarily. - for (uint32 v = existingLightVolsCount; v < nLightVols; ++v) - { - const Vec4* __restrict vBVol = &lightVolsInfo[v]->vVolume; - int32 nMiny = (int32)(floorf((vBVol->y - vBVol->w) * LV_LIGHT_CELL_R_SIZE)); - int32 nMaxy = (int32)(floorf((vBVol->y + vBVol->w) * LV_LIGHT_CELL_R_SIZE)); - int32 nMinx = (int32)(floorf((vBVol->x - vBVol->w) * LV_LIGHT_CELL_R_SIZE)); - int32 nMaxx = (int32)(floorf((vBVol->x + vBVol->w) * LV_LIGHT_CELL_R_SIZE)); - - lightVols[v].pData.resize(0); - - // Loop through active light cells touching bounding volume (~avg 2 cells) - for (int32 y = nMiny, ymax = nMaxy; y <= ymax; ++y) - { - for (int32 x = nMinx, xmax = nMaxx; x <= xmax; ++x) - { - const SLightCell& lightCell = m_pWorldLightCells[GetWorldHashBucketKey(x, y, 1, LV_LIGHTS_WORLD_BUCKET_SIZE)]; - CryPrefetch(&lightCell); - - const SRenderLight& pFirstDL = (*pLights)[lightCell.nLightID[0]]; - CryPrefetch(&pFirstDL); - CryPrefetch(&pFirstDL.m_ObjMatrix); - for (uint32 l = 0; (l < lightCell.nLightCount) & (lightVols[v].pData.size() < LIGHTVOLUME_MAXLIGHTS); ++l) - { - const int32 nLightId = lightCell.nLightID[l]; - - //Only allow IDs < MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE to continue or else we'll overflow access to - //lightProcessedStateArray[MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE]. Skipping the extra lights shouldn't really matter - //since A) folks won't be using that many lights, and B) for the case of light emitting particles, they tend to be grouped - //so that the individual contributions tend to bleed together anyway. - if (nLightId >= MAX_NUM_LIGHTS_FOR_LIGHT_VOLUME_UPDATE) - { - continue; - } - - if (static_cast(nLightId) < nLightCount) - { - const SRenderLight& pDL = (*pLights)[nLightId]; - const int32 nNextLightId = lightCell.nLightID[(l + 1) & (LIGHTVOLUME_MAXLIGHTS - 1)]; - const SRenderLight& pNextDL = (*pLights)[nNextLightId]; - CryPrefetch(&pNextDL); - CryPrefetch(&pNextDL.m_ObjMatrix); - - IF(lightProcessedStateArray[nLightId] != v + 1, 1) - { - lightProcessedStateArray[nLightId] = v + 1; - AddLight(pDL, &*lightVolsInfo[v], lightVols[v]); - } - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::Clear(const SRenderingPassInfo& passInfo) -{ - DynArray& lightVolsInfo = m_pLightVolsInfo[passInfo.ThreadID()]; - - m_bUpdateLightVolumes = false; - if (GetCVars()->e_LightVolumes && passInfo.IsGeneralPass() && GetCVars()->e_DynamicLights) - { - memset(m_nWorldCells, 0, sizeof(m_nWorldCells)); - memset(m_pWorldLightCells, 0, sizeof(m_pWorldLightCells)); - - //Clean up volume info data - for (size_t i = 0; i < lightVolsInfo.size(); ++i) - { - delete lightVolsInfo[i]; - } - - m_pLightVolsInfo[passInfo.ThreadID()].clear(); - m_bUpdateLightVolumes = (GetCVars()->e_LightVolumes == 1) ? true : false; - } -} - -////////////////////////////////////////////////////////////////////////// - -void CLightVolumesMgr::GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols) -{ - pLightVols = 0; - nNumVols = 0; - if (GetCVars()->e_LightVolumes == 1 && GetCVars()->e_DynamicLights && !m_pLightVolumes[nThreadID].empty()) - { - pLightVols = &m_pLightVolumes[nThreadID][0]; - nNumVols = m_pLightVolumes[nThreadID].size(); - } -} - - -void C3DEngine::GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols) -{ - m_LightVolumesMgr.GetLightVolumes(nThreadID, pLightVols, nNumVols); -} - -uint16 C3DEngine::RegisterVolumeForLighting(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo) -{ - return m_LightVolumesMgr.RegisterVolume(vPos, fRadius, nClipVolumeRef, passInfo); -} - -////////////////////////////////////////////////////////////////////////// -#ifndef _RELEASE -void CLightVolumesMgr::DrawDebug(const SRenderingPassInfo& passInfo) -{ - DynArray& lightVolsInfo = m_pLightVolsInfo[passInfo.ThreadID()]; - - IRenderer* pRenderer = GetRenderer(); - IRenderAuxGeom* pAuxGeom = GetRenderer()->GetIRenderAuxGeom(); - if (!pAuxGeom || !passInfo.IsGeneralPass()) - { - return; - } - - ColorF cWhite = ColorF(1, 1, 1, 1); - ColorF cBad = ColorF(1.0f, 0.0, 0.0f, 1.0f); - ColorF cWarning = ColorF(1.0f, 1.0, 0.0f, 1.0f); - ColorF cGood = ColorF(0.0f, 0.5, 1.0f, 1.0f); - ColorF cSingleCell = ColorF(0.0f, 1.0, 0.0f, 1.0f); - - const uint32 nLightVols = lightVolsInfo.size(); - LightVolumeVector& lightVols = m_pLightVolumes[passInfo.ThreadID()]; - const Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - - float fYLine = 8.0f, fYStep = 20.0f; - GetRenderer()->Draw2dLabel(8.0f, fYLine += fYStep, 2.0f, (float*)&cWhite.r, false, "Light Volumes Info (count %d)", nLightVols); - - for (uint32 v = 0; v < nLightVols; ++v) // draw each light volume - { - SLightVolume& lv = lightVols[v]; - SLightVolInfo& lvInfo = *lightVolsInfo[v]; - - ColorF& cCol = (lv.pData.size() >= 10) ? cBad : ((lv.pData.size() >= 5) ? cWarning : cGood); - const Vec3 vPos = Vec3(lvInfo.vVolume.x, lvInfo.vVolume.y, lvInfo.vVolume.z); - const float fCamDistSq = (vPos - vCamPos).len2(); - cCol.a = max(0.25f, min(1.0f, 1024.0f / (fCamDistSq + 1e-6f))); - - pRenderer->DrawLabelEx(vPos, 1.3f, (float*)&cCol.r, true, true, "Id: %d\nPos: %.2f %.2f %.2f\nRadius: %.2f\nLights: %d\nOutLights: %d", - v, vPos.x, vPos.y, vPos.z, lvInfo.vVolume.w, lv.pData.size(), (*(int32*)&lvInfo.vVolume.w) & (1 << 31) ? 1 : 0); - - if (GetCVars()->e_LightVolumesDebug == 2) - { - const float fSideSize = 0.707f * sqrtf(lvInfo.vVolume.w * lvInfo.vVolume.w * 2); - pAuxGeom->DrawAABB(AABB(vPos - Vec3(fSideSize), vPos + Vec3(fSideSize)), false, cCol, eBBD_Faceted); - } - - if (GetCVars()->e_LightVolumesDebug == 3) - { - cBad.a = 1.0f; - const Vec3 vCellPos = Vec3(floorf((lvInfo.vVolume.x) * LV_CELL_RSIZEX) * LV_CELL_SIZEX, - floorf((lvInfo.vVolume.y) * LV_CELL_RSIZEY) * LV_CELL_SIZEY, - floorf((lvInfo.vVolume.z) * LV_CELL_RSIZEZ) * LV_CELL_SIZEZ); - - const Vec3 vMin = vCellPos; - const Vec3 vMax = vMin + Vec3(LV_CELL_SIZEX, LV_CELL_SIZEY, LV_CELL_SIZEZ); - pAuxGeom->DrawAABB(AABB(vMin, vMax), false, cBad, eBBD_Faceted); - } - } -} -#endif diff --git a/Code/CryEngine/Cry3DEngine/3DEngineMemory.cpp b/Code/CryEngine/Cry3DEngine/3DEngineMemory.cpp deleted file mode 100644 index 65cb53d0b1..0000000000 --- a/Code/CryEngine/Cry3DEngine/3DEngineMemory.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "3DEngineMemory.h" - -// Static CTemporaryPool instance -CTemporaryPool* CTemporaryPool::s_Instance = NULL; - -namespace util -{ - void* pool_allocate(size_t nSize) - { - return CTemporaryPool::Get()->Allocate(nSize, 8); - } - void pool_free(void* ptr) - { - return CTemporaryPool::Get()->Free(ptr); - } -} diff --git a/Code/CryEngine/Cry3DEngine/3DEngineMemory.h b/Code/CryEngine/Cry3DEngine/3DEngineMemory.h deleted file mode 100644 index 143aeccab2..0000000000 --- a/Code/CryEngine/Cry3DEngine/3DEngineMemory.h +++ /dev/null @@ -1,286 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_3DENGINEMEMORY_H -#define CRYINCLUDE_CRY3DENGINE_3DENGINEMEMORY_H -#pragma once - -// The type of pool responsible for temporary allocations within the 3dengine -// -// Note: The header is included here for reasons of devirtualization. If -// included directly from the precompiled header in 3dEngine, the gamedll will -// fail to compile! -#include -#include - -using NCryPoolAlloc::CFirstFit; // speed of allocations are crucial, so simply use the first fitting free allocation -using NCryPoolAlloc::CInPlace; // -using NCryPoolAlloc::CMemoryDynamic; // the pool itself will be dynamically allocated -using NCryPoolAlloc::CListItemInPlace; // use inplace items - -// Tempororary Pool Holder -class CTemporaryPool -{ -private: - // Access granted for 3dEngine to create, destroy and maintain the temporary - // pool for the 3d engine - friend class C3DEngine; - - // The static pool instance - one pool to rule them all (temp allocations at least) - static CTemporaryPool* s_Instance; - - // The type of the backing temporary pool - typedef CFirstFit, CListItemInPlace> TTemporaryPool; - TTemporaryPool Pool; - - // A non-recursive critical section guards the pool against concurrent access - typedef CryCriticalSectionNonRecursive TTemporaryPoolLock; - TTemporaryPoolLock Lock; - - // Initialize the pool manager. - // - // Allocates the backing storage and initializes the temporary pool - // itself. The backing storage is aligned to 16 bytes to reduce the amount of - // cachelines crossed by the temporary pool - static bool Initialize(size_t poolSize) - { - // Create the object instance - s_Instance = new CTemporaryPool(); - if (!s_Instance) - { - CryFatalError("CTemporaryPool::Init(): could not create an instance of CTemporaryPool"); - return false; - } - - // Allocate the backing storage - uint8* tempPool = reinterpret_cast(CryModuleMemalign(poolSize, 16)); - if (!tempPool) - { - CryFatalError("CTemporaryPool::Init(): could not allocate %" PRISIZE_T " bytes for temportary pool", poolSize); - return false; - } - - // Initialize the actual pool - s_Instance->Pool.InitMem(poolSize, tempPool); - return true; - } - - // Shutdown the temporary pool manager. - // - // Frees the temporary pool - static bool Shutdown() - { - if (s_Instance == NULL) - { - CryFatalError("CTemporaryPool::Shutdown(): no temporary pool instance present"); - return false; - } - - bool error = false; - CTemporaryPool& instance = *s_Instance; - if (instance.Pool.Data()) - { - CryModuleMemalignFree(instance.Pool.Data()); - } - else - { - error = true; - } - - delete s_Instance; - s_Instance = NULL; - return !error; - } - - // Templated construct helper member function using an inplace factory - // - // Called from the templated New function below. Returns a typed - // pointer to the inplace constructed object. - template - T* Construct(const InPlaceFactory& factory, void* storage) - { - return reinterpret_cast(factory.template apply(storage)); - } - - // Templated destruct helper member function. - // - // Calls the object's destructor and returns a void pointer to the storage - template - void* Destruct(T* obj) - { - obj->~T(); - return reinterpret_cast(obj); - } - - // Empty private constructor/destructors to prevent clients from creating and - // destroying instances of CTemporaryPool (there should only be one instance - // in the 3DEngine). - CTemporaryPool() {}; - ~CTemporaryPool() {}; - -public: - - // Allocate a block of memory with the given size and alignment - void* Allocate(size_t size, size_t align) - { - AUTO_LOCK_T(CryCriticalSectionNonRecursive, Lock); - void* pData = Pool.Allocate(size, align); - if (pData == NULL) - { - CryFatalError("**** could not allocate %" PRISIZE_T " bytes from temporary pool", size); - } - return Pool.Resolve(pData); - }; - - // Allocates memory and constructs object of type 'T' - // - // Note: This method is respects the alignment of 'T' via C99 alignof() - template - T* New(const Expr& expr) - { - AUTO_LOCK_T(CryCriticalSectionNonRecursive, Lock); - void* pObjStorage = Pool.Allocate(sizeof(T), alignof(T)); - if (pObjStorage == NULL) - { - CryFatalError("**** could not allocate %d bytes from temporary pool", - (int)sizeof (T)); - } - return Construct(expr, pObjStorage); - }; - - // Allocates memory and constructs object of type 'T' - // - // Note: This method is respects the alignment of 'T' via C99 alignof() - template - T* New() - { - AUTO_LOCK_T(CryCriticalSectionNonRecursive, Lock); - void* pObjStorage = Pool.Allocate(sizeof(T), alignof(T)); - if (pObjStorage == NULL) - { - CryFatalError("**** could not allocate %d bytes from temporary pool", - (int)sizeof (T)); - } - return Construct(InplaceFactory(), pObjStorage); - }; - - // Frees a block of memory from the temporary pool - // - void Free(void* ptr) - { - AUTO_LOCK_T(CryCriticalSectionNonRecursive, Lock); - Pool.Free(ptr); - } - - - // Destroys an object of type 'T' and frees the underlying block of memory - template - void Delete(T* ptr) - { - AUTO_LOCK_T(CryCriticalSectionNonRecursive, Lock); - Pool.Free(Destruct(ptr)); - } - - // Static function to retrieve the static instance of CTemporaryPool - static CTemporaryPool* Get() { return s_Instance; }; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(Pool.Data(), Pool.MemSize()); - } -}; - -// A stl compliant scratch allocator that uses the given temporary pool. -template -class scratch_allocator -{ -public: - typedef Type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - template - struct rebind - { - typedef scratch_allocator other; - }; - - scratch_allocator() {} - template - scratch_allocator(const scratch_allocator&) {} - scratch_allocator(const scratch_allocator&) {} - ~scratch_allocator() {} - - pointer address(reference x) const {return &x; } - const_pointer address(const_reference x) const { return &x; } - - // Note: size can be zero - return value will be null in that case - value_type* allocate(size_type n, const void* = 0) - { - if (n != 0) - { - size_type buf_size = n * sizeof(value_type); - - void* ret = CTemporaryPool::Get()->Allocate( - buf_size, - alignof(value_type)); - - return reinterpret_cast(ret); - } - return 0; - } - - // Note: size can be zero. - void deallocate(pointer p, [[maybe_unused]] size_type n) - { - if (p != NULL) - { - CTemporaryPool::Get()->Free(p); - } - } - - size_type max_size() const { return size_t(-1) / sizeof(value_type); } - - void construct(pointer p, const_reference val) - { new (reinterpret_cast(p))value_type(val); } - - void destroy(pointer p) { p->~value_type(); } - - void cleanup() {} - - size_t get_heap_size() { return 0; } - - size_t get_wasted_in_allocation() { return 0; } - - size_t get_wasted_in_blocks() { return 0; } -}; - - -// A scratch vector type to use the stl vector -template -class scratch_vector - : public std::vector > -{ -}; - -namespace util -{ - extern void* pool_allocate(size_t nSize); - extern void pool_free(void* ptr); -} - -#endif // CRYINCLUDE_CRY3DENGINE_3DENGINEMEMORY_H diff --git a/Code/CryEngine/Cry3DEngine/3DEngineRender.cpp b/Code/CryEngine/Cry3DEngine/3DEngineRender.cpp deleted file mode 100644 index 26c731aca4..0000000000 --- a/Code/CryEngine/Cry3DEngine/3DEngineRender.cpp +++ /dev/null @@ -1,3932 +0,0 @@ - -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : rendering - - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "Ocean.h" -#include -#include -#include "DecalManager.h" -#include "SkyLightManager.h" - -#include "CullBuffer.h" -#include "LightEntity.h" -#include "FogVolumeRenderNode.h" -#include "ObjectsTree.h" -#include "CloudsManager.h" -#include "MatMan.h" -#include "VolumeObjectRenderNode.h" -#include "CryPath.h" -#include "ILocalMemoryUsage.h" -#include "BitFiddling.h" -#include "ObjMan.h" -#include "GeomCacheManager.h" -#include "ClipVolumeManager.h" -#include "ITimeOfDay.h" -#include "Environment/OceanEnvironmentBus.h" - -#include - - - -#ifdef GetCharWidth -#undef GetCharWidth -#endif //GetCharWidth - - -#ifdef WIN32 -#include -#endif - -#include -#include -#include -#include // for AZ_MAX_PATH_LEN -#include -#include "../RenderDll/Common/Memory/VRAMDrillerBus.h" - -//////////////////////////////////////////////////////////////////////////////////////// -// RenderScene -//////////////////////////////////////////////////////////////////////////////////////// -#define FREE_MEMORY_YELLOW_LIMIT (30) -#define FREE_MEMORY_RED_LIMIT (10) -#define DISPLAY_INFO_SCALE (1.25f) -#define DISPLAY_INFO_SCALE_SMALL (1.1f) -#define STEP_SMALL_DIFF (2.f) - -#if defined(WIN32) || defined(WIN64) || defined(MAC) -// for panorama screenshots -class CStitchedImage - : public Cry3DEngineBase -{ -public: - CStitchedImage(C3DEngine& rEngine, - const uint32 dwWidth, - const uint32 dwHeight, - const uint32 dwVirtualWidth, - const uint32 dwVirtualHeight, - const uint32 dwSliceCount, - const f32 fTransitionSize, - const bool bMetaData = false) - : m_rEngine(rEngine) - , m_dwWidth(dwWidth) - , m_dwHeight(dwHeight) - , m_fInvWidth(1.f / static_cast(dwWidth)) - , m_fInvHeight(1.f / static_cast(dwHeight)) - , m_dwVirtualWidth(dwVirtualWidth) - , m_dwVirtualHeight(dwVirtualHeight) - , m_fInvVirtualWidth(1.f / static_cast(dwVirtualWidth)) - , m_fInvVirtualHeight(1.f / static_cast(dwVirtualHeight)) - , m_nFileId(0) - , m_dwSliceCount(dwSliceCount) - , m_fHorizFOV(2 * gf_PI / dwSliceCount) - , m_bFlipY(false) - , m_fTransitionSize(fTransitionSize) - , m_bMetaData(bMetaData) - { - assert(dwWidth); - assert(dwHeight); - - m_RGB.resize(m_dwWidth * 3 * m_dwHeight); - - // ratio between width and height defines angle 1 (angle from mid to cylinder edges) - float fVert1Frac = (2 * gf_PI * m_dwHeight) / m_dwWidth; - - // slice count defines angle 2 - float fHorizFrac = tanf(GetHorizFOVWithBorder() * 0.5f); - float fVert2Frac = 2.0f * fHorizFrac / rEngine.GetRenderer()->GetWidth() * rEngine.GetRenderer()->GetHeight(); - // float fVert2Frac = 2.0f * fHorizFrac / rEngine.GetRenderer()->GetWidth() * rEngine.GetRenderer()->GetHeight(); - - // the bigger one defines the needed angle - float fVertFrac = max(fVert1Frac, fVert2Frac); - - // planar image becomes a barrel after projection and we need to zoom in to only utilize the usable part (inner rect) - // this is not always needed - for quality with low slice count we could be save some quality here - fVertFrac /= cosf(GetHorizFOVWithBorder() * 0.5f); - - // compute FOV from Frac - float fVertFOV = 2 * atanf(0.5f * fVertFrac); - - m_fPanoramaShotVertFOV = fabsf(fVertFOV); - - CryLog("RenderFov = %f degrees (%f = max(%f,%f)*fix)", RAD2DEG(m_fPanoramaShotVertFOV), fVertFrac, fVert1Frac, fVert2Frac); - Clear(); - } - - void Clear() - { - memset(&m_RGB[0], 0, m_dwWidth * m_dwHeight * 3); - } - - // szDirectory + "/" + file_id + "." + extension - // logs errors in the case there are problems - bool SaveImage(const char* szDirectory) - { - assert(szDirectory); - - const char* szExtension = m_rEngine.GetCVars()->e_ScreenShotFileFormat->GetString(); - - if (azstricmp(szExtension, "dds") != 0 && - azstricmp(szExtension, "tga") != 0 && - azstricmp(szExtension, "jpg") != 0) - { - gEnv->pLog->LogError("Format e_ScreenShotFileFormat='%s' not supported", szExtension); - return false; - } - - const char* sRequestedName = m_rEngine.GetCVars()->e_ScreenShotFileName->GetString(); - - char sFileName[AZ_MAX_PATH_LEN]; - - if (azstricmp(sRequestedName, "") != 0) - { - AZStd::string folderPath; - AZStd::string fileName; - AzFramework::StringFunc::Path::Split(sRequestedName, nullptr, &folderPath, &fileName); - gEnv->pFileIO->CreatePath((AZStd::string("@user@/ScreenShots/") + folderPath).c_str()); - azsnprintf(sFileName, sizeof(sFileName), "@user@/ScreenShots/%s.%s", sRequestedName, szExtension); - } - else - { - azsnprintf(sFileName, sizeof(sFileName), "@user@/ScreenShots/%s", szDirectory); - gEnv->pFileIO->CreatePath(sFileName); - - // find free file id - for (;; ) - { - azsnprintf(sFileName, sizeof(sFileName), "@user@/ScreenShots/%s/%.5d.%s", szDirectory, m_nFileId, szExtension); - - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(sFileName, "rb"); - - if (fileHandle == AZ::IO::InvalidHandle) - { - break; // file doesn't exist - } - - gEnv->pCryPak->FClose(fileHandle); - m_nFileId++; - } - } - - bool bOk; - - if (azstricmp(szExtension, "dds") == 0) - { - bOk = gEnv->pRenderer->WriteDDS((byte*)&m_RGB[0], m_dwWidth, m_dwHeight, 3, sFileName, eTF_BC3, 1); - } - else - if (azstricmp(szExtension, "tga") == 0) - { - bOk = gEnv->pRenderer->WriteTGA((byte*)&m_RGB[0], m_dwWidth, m_dwHeight, sFileName, 24, 24); - } - else - { - bOk = gEnv->pRenderer->WriteJPG((byte*)&m_RGB[0], m_dwWidth, m_dwHeight, sFileName, 24); - } - - if (!bOk) - { - gEnv->pLog->LogError("Failed to write '%s' (not supported on this platform?)", sFileName); - } - else //write meta data - { - if (m_bMetaData) - { - const f32 fSizeX = GetCVars()->e_ScreenShotMapSizeX; - const f32 fSizeY = GetCVars()->e_ScreenShotMapSizeY; - const f32 fTLX = GetCVars()->e_ScreenShotMapCenterX - fSizeX; - const f32 fTLY = GetCVars()->e_ScreenShotMapCenterY - fSizeY; - const f32 fBRX = GetCVars()->e_ScreenShotMapCenterX + fSizeX; - const f32 fBRY = GetCVars()->e_ScreenShotMapCenterY + fSizeY; - - snprintf(sFileName, sizeof(sFileName), "@user@/ScreenShots/%s/%.5d.%s", szDirectory, m_nFileId, "xml"); - - AZ::IO::HandleType metaFileHandle = gEnv->pCryPak->FOpen(sFileName, "wt"); - if (metaFileHandle != AZ::IO::InvalidHandle) - { - char sFileData[1024]; - snprintf(sFileData, sizeof(sFileData), "", - m_nFileId, szExtension, fTLX, fTLY, fBRX, fBRY); - string data(sFileData); - gEnv->pCryPak->FWrite(data.c_str(), data.size(), metaFileHandle); - gEnv->pCryPak->FClose(metaFileHandle); - } - } - } - - // reset filename when done so user doesn't overwrite other screen shots (unless they want to) - // this is done here as there is no callback for standard screenshots to allow the user to clear - // this when done with the screen shot, so I decided to just always clear it when done - m_rEngine.GetCVars()->e_ScreenShotFileName->Set(""); - - return bOk; - } - - // rasterize rectangle - // Arguments: - // x0 - x0, excluding - // y1 - >y0, excluding - void RasterizeRect(const uint32* pRGBAImage, - const uint32 dwWidth, - const uint32 dwHeight, - const uint32 dwSliceX, - const uint32 dwSliceY, - const f32 fTransitionSize, - const bool bFadeBordersX, - const bool bFadeBordersY) - { - { - //calculate rect inside the whole image - const int32 OrgX0 = static_cast(static_cast((dwSliceX * dwWidth) * m_dwWidth) * m_fInvVirtualWidth); - const int32 OrgY0 = static_cast(static_cast((dwSliceY * dwHeight) * m_dwHeight) * m_fInvVirtualHeight); - const int32 OrgX1 = min(static_cast(static_cast(((dwSliceX + 1) * dwWidth) * m_dwWidth) * m_fInvVirtualWidth), static_cast(m_dwWidth)) - (m_rEngine.GetCVars()->e_ScreenShotDebug == 1 ? 1 : 0); - const int32 OrgY1 = min(static_cast(static_cast(((dwSliceY + 1) * dwHeight) * m_dwHeight) * m_fInvVirtualHeight), static_cast(m_dwHeight)) - (m_rEngine.GetCVars()->e_ScreenShotDebug == 1 ? 1 : 0); - //expand bounds for borderblending - const int32 CenterX = (OrgX0 + OrgX1) / 2; - const int32 CenterY = (OrgY0 + OrgY1) / 2; - const int32 X0 = static_cast(static_cast(OrgX0 - CenterX) * (1.f + fTransitionSize)) + CenterX; - const int32 Y0 = static_cast(static_cast(OrgY0 - CenterY) * (1.f + fTransitionSize)) + CenterY; - const int32 X1 = static_cast(static_cast(OrgX1 - CenterX) * (1.f + fTransitionSize)) + CenterX; - const int32 Y1 = static_cast(static_cast(OrgY1 - CenterY) * (1.f + fTransitionSize)) + CenterY; - const f32 InvBlendX = 1.f / max(static_cast(X1 - OrgX1), 0.01f);//0.5 is here because the border is two times wider then the border of the single segment in total - const f32 InvBlendY = 1.f / max(static_cast(Y1 - OrgY1), 0.01f); - const int32 DebugScale = (m_rEngine.GetCVars()->e_ScreenShotDebug == 2) ? 65536 : 0; - for (int32 y = max(Y0, 0); y < Y1 && y < (int)m_dwHeight; y++) - { - const f32 WeightY = bFadeBordersY ? min(1.f, static_cast(min(y - Y0, Y1 - y)) * InvBlendY) : 1.f; - for (int32 x = max(X0, 0); x < X1 && x < (int)m_dwWidth; x++) - { - uint8* pDst = &m_RGB[m_bFlipY ? 3 * (x + (m_dwHeight - y - 1) * m_dwWidth) : 3 * (x + y * m_dwWidth)]; - const f32 WeightX = bFadeBordersX ? min(1.f, static_cast(min(x - X0, X1 - x)) * InvBlendX) : 1.f; - GetBilinearFilteredBlend(static_cast(static_cast(x - X0) / static_cast(X1 - X0) * static_cast(dwWidth) * 16.f), - static_cast(static_cast(y - Y0) / static_cast(Y1 - Y0) * static_cast(dwHeight) * 16.f), - pRGBAImage, dwWidth, dwHeight, - max(static_cast(WeightX * WeightY * 65536.f), DebugScale), pDst); - } - } - } - } - - void RasterizeCylinder(const uint32* pRGBAImage, - const uint32 dwWidth, - const uint32 dwHeight, - const uint32 dwSlice, - const bool bFadeBorders) - { - float fSrcAngleMin = GetSliceAngle(dwSlice - 1); - float fFractionVert = tanf(m_fPanoramaShotVertFOV * 0.5f); - float fFractionHoriz = fFractionVert * gEnv->pRenderer->GetCamera().GetProjRatio(); - float fInvFractionHoriz = 1.0f / fFractionHoriz; - - // for soft transition - float fFadeOutFov = GetHorizFOVWithBorder(); - float fFadeInFov = GetHorizFOV(); - - int x0 = 0, y0 = 0, x1 = m_dwWidth, y1 = m_dwHeight; - - float fScaleX = 1.0f / m_dwWidth; - float fScaleY = 0.5f * fInvFractionHoriz / (m_dwWidth / (2 * gf_PI)) / dwHeight * dwWidth; // this value is not correctly computed yet - but using many slices reduced the problem - - if (m_bFlipY) - { - fScaleY = -fScaleY; - } - - - // it's more efficient to process colums than lines - for (int x = x0; x < x1; ++x) - { - uint8* pDst = &m_RGB[3 * (x + y0 * m_dwWidth)]; - float fSrcX = x * fScaleX - 0.5f; // -0.5 .. 0.5 - float fSrcAngleX = fSrcAngleMin + 2 * gf_PI * fSrcX; - - if (fSrcAngleX > gf_PI) - { - fSrcAngleX -= 2 * gf_PI; - } - if (fSrcAngleX < -gf_PI) - { - fSrcAngleX += 2 * gf_PI; - } - - if (fabs(fSrcAngleX) > fFadeOutFov * 0.5f) - { - continue; // clip away curved parts of the barrel - } - float fScrPosX = (tanf(fSrcAngleX) * 0.5f * fInvFractionHoriz + 0.5f) * dwWidth; - // float fInvCosSrcX = 1.0f / cos(fSrcAngleX); - float fInvCosSrcX = 1.0f / cosf(fSrcAngleX); - - if (fScrPosX >= 0 && fScrPosX <= (float)dwWidth) // this is an optimization - but it could be done even more efficient - { - if (fInvCosSrcX > 0) // don't render the viewer opposing direction - { - int iSrcPosX16 = (int)(fScrPosX * 16.0f); - - float fYOffset = 16 * 0.5f * dwHeight - 16 * 0.5f * m_dwHeight * fScaleY * fInvCosSrcX * dwHeight; - float fYMul = 16 * fScaleY * fInvCosSrcX * dwHeight; - - float fSrcY = y0 * fYMul + fYOffset; - - uint32 dwLerp64k = 256 * 256 - 1; - - if (!bFadeBorders) - { - // first pass - every second image without soft borders - for (int y = y0; y < y1; ++y, fSrcY += fYMul, pDst += m_dwWidth * 3) - { - GetBilinearFiltered(iSrcPosX16, (int)fSrcY, pRGBAImage, dwWidth, dwHeight, pDst); - } - } - else - { - // second pass - do all the inbetween with soft borders - float fOffSlice = fabs(fSrcAngleX / fFadeInFov) - 0.5f; - - if (fOffSlice < 0) - { - fOffSlice = 0; // no transition in this area - } - float fBorder = (fFadeOutFov - fFadeInFov) * 0.5f; - - if (fBorder < 0.001f) - { - fBorder = 0.001f; // we do not have border - } - float fFade = 1.0f - fOffSlice * fFadeInFov / fBorder; - - if (fFade < 0.0f) - { - fFade = 0.0f; // don't use this slice here - } - dwLerp64k = (uint32)(fFade * (256.0f * 256.0f - 1.0f)); // 0..64k - - if (dwLerp64k) // optimization - { - for (int y = y0; y < y1; ++y, fSrcY += fYMul, pDst += m_dwWidth * 3) - { - GetBilinearFilteredBlend(iSrcPosX16, (int)fSrcY, pRGBAImage, dwWidth, dwHeight, dwLerp64k, pDst); - } - } - } - } - } - } - } - - // fast, rgb only - static inline ColorB lerp(const ColorB x, const ColorB y, const uint32 a, const uint32 dwBase) - { - const int32 b = dwBase - a; - const int32 RC = dwBase / 2;//rounding correction - - - return ColorB(((int)x.r * b + (int)y.r * a + RC) / dwBase, - ((int)x.g * b + (int)y.g * a + RC) / dwBase, - ((int)x.b * b + (int)y.b * a + RC) / dwBase); - } - - static inline ColorB Mul(const ColorB x, const int32 a, const int32 dwBase) - { - return ColorB(((int)x.r * (int)a) / dwBase, - ((int)x.g * (int)a) / dwBase, - ((int)x.b * (int)a) / dwBase); - } - static inline ColorB MadSaturate(const ColorB x, const int32 a, const int32 dwBase, const ColorB y) - { - const int32 MAX_COLOR = 0xff; - const ColorB PreMuled = Mul(x, a, dwBase); - return ColorB(min((int)PreMuled.r + (int)y.r, MAX_COLOR), - min((int)PreMuled.g + (int)y.g, MAX_COLOR), - min((int)PreMuled.b + (int)y.b, MAX_COLOR)); - } - - // bilinear filtering in fixpoint, - // 4bit fractional part -> multiplier 16 - // --lookup outside of the image is not defined - // lookups outside the image are now clamped, needed due to some float inaccuracy while rasterizing a rect-screenshot - // Arguments: - // iX16 - fX mul 16 - // iY16 - fY mul 16 - // result - [0]=red, [1]=green, [2]=blue - static inline bool GetBilinearFilteredRaw(const int iX16, const int iY16, - const uint32* pRGBAImage, - const uint32 dwWidth, const uint32 dwHeight, - ColorB& result) - { - int iLocalX = min(max(iX16 / 16, 0), static_cast(dwWidth - 1)); - int iLocalY = min(max(iY16 / 16, 0), static_cast(dwHeight - 1)); - - int iLerpX = iX16 & 0xf; // 0..15 - int iLerpY = iY16 & 0xf; // 0..15 - - ColorB colS[4]; - - const uint32* pRGBA = &pRGBAImage[iLocalX + iLocalY * dwWidth]; - - colS[0] = pRGBA[0]; - colS[1] = pRGBA[1]; - colS[2] = pRGBA[iLocalY + 1uL < dwHeight ? dwWidth : 0]; - colS[3] = pRGBA[(iLocalX + 1uL < dwWidth ? 1 : 0) + (iLocalY + 1uL < dwHeight ? dwWidth : 0)]; - - ColorB colTop, colBottom; - - colTop = lerp(colS[0], colS[1], iLerpX, 16); - colBottom = lerp(colS[2], colS[3], iLerpX, 16); - - result = lerp(colTop, colBottom, iLerpY, 16); - return true; - } - - - // blend with background - static inline bool GetBilinearFiltered(const int iX16, const int iY16, - const uint32* pRGBAImage, - const uint32 dwWidth, const uint32 dwHeight, - uint8 result[3]) - { - ColorB colFiltered; - if (GetBilinearFilteredRaw(iX16, iY16, pRGBAImage, dwWidth, dwHeight, colFiltered)) - { - result[0] = colFiltered.r; - result[1] = colFiltered.g; - result[2] = colFiltered.b; - return true; - } - return false; - } - - static inline bool GetBilinearFilteredBlend(const int iX16, const int iY16, - const uint32* pRGBAImage, - const uint32 dwWidth, const uint32 dwHeight, - const uint32 dwLerp64k, - uint8 result[3]) - { - ColorB colFiltered; - if (GetBilinearFilteredRaw(iX16, iY16, pRGBAImage, dwWidth, dwHeight, colFiltered)) - { - ColorB colRet = lerp(ColorB(result[0], result[1], result[2]), colFiltered, dwLerp64k, 256 * 256); - - result[0] = colRet.r; - result[1] = colRet.g; - result[2] = colRet.b; - return true; - } - return false; - } - - static inline bool GetBilinearFilteredAdd(const int iX16, const int iY16, - const uint32* pRGBAImage, - const uint32 dwWidth, const uint32 dwHeight, - const uint32 dwLerp64k, - uint8 result[3]) - { - ColorB colFiltered; - if (GetBilinearFilteredRaw(iX16, iY16, pRGBAImage, dwWidth, dwHeight, colFiltered)) - { - ColorB colRet = MadSaturate(colFiltered, dwLerp64k, 256 * 256, ColorB(result[0], result[1], result[2])); - - result[0] = colRet.r; - result[1] = colRet.g; - result[2] = colRet.b; - return true; - } - return false; - } - - - float GetSliceAngle(const uint32 dwSlice) const - { - uint32 dwAlternatingSlice = (dwSlice * 2) % m_dwSliceCount; - - float fAngleStep = m_fHorizFOV; - - float fRet = fAngleStep * dwAlternatingSlice; - - if (dwSlice * 2 >= m_dwSliceCount) - { - fRet += fAngleStep; - } - - return fRet; - } - - float GetHorizFOV() const - { - return m_fHorizFOV; - } - - float GetHorizFOVWithBorder() const - { - return m_fHorizFOV * (1.0f + m_fTransitionSize); - } - - void* GetBuffer(){ return &m_RGB[0]; } - uint32 GetWidth() { return m_dwWidth; } - uint32 GetHeight() { return m_dwHeight; } - - - //private: // ------------------------------------------------------------------- - - uint32 m_dwWidth; // >0 - uint32 m_dwHeight; // >0 - f32 m_fInvWidth; // >0 - f32 m_fInvHeight; // >0 - uint32 m_dwVirtualWidth; // >0 - uint32 m_dwVirtualHeight; // >0 - f32 m_fInvVirtualWidth; // >0 - f32 m_fInvVirtualHeight; // >0 - std::vector m_RGB; // [channel + x*3 + m_dwWidth*3*y], channel=0..2, xe_ScreenShotWidth); - const uint32 dwPanHeight = max(1, GetCVars()->e_ScreenShotHeight); - const f32 fTransitionSize = min(1.f, abs(GetCVars()->e_ScreenShotQuality) * 0.01f); - - const uint32 widthSlices = (dwPanWidth + GetRenderer()->GetWidth() - 1) / GetRenderer()->GetWidth(); - const uint32 heightSlices = (dwPanHeight + GetRenderer()->GetHeight() - 1) / GetRenderer()->GetHeight(); - uint32 MinSlices = max(widthSlices, heightSlices); - MinSlices = max(MinSlices, (uint32)GetCVars()->e_ScreenShotMinSlices); - - const uint32 dwVirtualWidth = GetRenderer()->GetWidth() * MinSlices; - const uint32 dwVirtualHeight = GetRenderer()->GetHeight() * MinSlices; - - GetRenderer()->StartScreenShot(GetCVars()->e_ScreenShot); - - switch (abs(GetCVars()->e_ScreenShot)) - { - case ESST_HIGHRES: - GetConsole()->ShowConsole(false); - - MinSlices = max(MinSlices, 1u); - pStitchedImage = new CStitchedImage(*this, dwPanWidth, dwPanHeight, dwVirtualWidth, dwVirtualHeight, MinSlices, fTransitionSize); - - ScreenShotHighRes(pStitchedImage, nRenderFlags, passInfo, MinSlices, fTransitionSize); - pStitchedImage->SaveImage("HiRes"); - pStitchedImage->Clear(); // good for debugging - delete pStitchedImage; - if (GetCVars()->e_ScreenShot > 0) // <0 is used for multiple frames (videos) - { - GetCVars()->e_ScreenShot = 0; - } - break; - case ESST_PANORAMA: - GetConsole()->ShowConsole(false); - - // Panorama screenshots will exhibit artifacts if insufficient slices are used to render them - // 20 slices yields great quality. - MinSlices = max(MinSlices, 20u); - pStitchedImage = new CStitchedImage(*this, dwPanWidth, dwPanHeight, dwVirtualWidth, dwVirtualHeight, MinSlices, fTransitionSize); - - ScreenShotPanorama(pStitchedImage, nRenderFlags, passInfo, MinSlices, fTransitionSize); - pStitchedImage->SaveImage("Panorama"); - pStitchedImage->Clear(); // good for debugging - delete pStitchedImage; - if (GetCVars()->e_ScreenShot > 0) // <0 is used for multiple frames (videos) - { - GetCVars()->e_ScreenShot = 0; - } - break; - case ESST_MAP_DELAYED: - { - GetCVars()->e_ScreenShot = sgn(GetCVars()->e_ScreenShot) * ESST_MAP; // sgn() to keep sign bit , <0 is used for multiple frames (videos) - } - break; - case ESST_SWMAP_DELAYED: - { - GetCVars()->e_ScreenShot = sgn(GetCVars()->e_ScreenShot) * ESST_SWMAP; // sgn() to keep sign bit , <0 is used for multiple frames (videos) - } - break; - case ESST_SWMAP: - case ESST_MAP: - { - static const unsigned int nMipMapSnapshotSize = 2048; - GetRenderer()->ChangeViewport(0, 0, nMipMapSnapshotSize, nMipMapSnapshotSize); - uint32 TmpHeight, TmpWidth, TmpVirtualHeight, TmpVirtualWidth; - TmpHeight = TmpWidth = TmpVirtualHeight = TmpVirtualWidth = 1; - - while ((TmpHeight << 1) <= dwPanHeight) - { - TmpHeight <<= 1; - } - while ((TmpWidth << 1) <= dwPanWidth) - { - TmpWidth <<= 1; - } - const uint32 TmpMinSlices = max(max(1, GetCVars()->e_ScreenShotMinSlices), - max(static_cast((TmpWidth + nMipMapSnapshotSize - 1) / nMipMapSnapshotSize), - static_cast((TmpHeight + nMipMapSnapshotSize - 1) / nMipMapSnapshotSize))); - while ((TmpVirtualHeight << 1) <= TmpMinSlices * nMipMapSnapshotSize) - { - TmpVirtualHeight <<= 1; - } - while ((TmpVirtualWidth << 1) <= TmpMinSlices * nMipMapSnapshotSize) - { - TmpVirtualWidth <<= 1; - } - - GetConsole()->ShowConsole(false); - pStitchedImage = new CStitchedImage(*this, TmpWidth, TmpHeight, TmpVirtualWidth, TmpVirtualHeight, TmpMinSlices, fTransitionSize, true); - ScreenShotMap(pStitchedImage, nRenderFlags, passInfo, TmpMinSlices, fTransitionSize); - if (abs(GetCVars()->e_ScreenShot) == ESST_MAP) - { - pStitchedImage->SaveImage("Map"); - } - - if (m_pScreenshotCallback) - { - const f32 fSizeX = GetCVars()->e_ScreenShotMapSizeX; - const f32 fSizeY = GetCVars()->e_ScreenShotMapSizeY; - const f32 fTLX = GetCVars()->e_ScreenShotMapCenterX - fSizeX; - const f32 fTLY = GetCVars()->e_ScreenShotMapCenterY - fSizeY; - const f32 fBRX = GetCVars()->e_ScreenShotMapCenterX + fSizeX; - const f32 fBRY = GetCVars()->e_ScreenShotMapCenterY + fSizeY; - - m_pScreenshotCallback->SendParameters(pStitchedImage->GetBuffer(), pStitchedImage->GetWidth(), pStitchedImage->GetHeight(), fTLX, fTLY, fBRX, fBRY); - } - - pStitchedImage->Clear(); // good for debugging - delete pStitchedImage; - } - if (GetCVars()->e_ScreenShot > 0) // <0 is used for multiple frames (videos) - { - GetCVars()->e_ScreenShot = 0; - } - - break; - default: - GetCVars()->e_ScreenShot = 0; - } - - GetRenderer()->EndScreenShot(GetCVars()->e_ScreenShot); - -#endif //#if defined(WIN32) || defined(WIN64) -} - - - -struct SDebugFrustrum -{ - Vec3 m_vPos[8]; - const char* m_szName; - CTimeValue m_TimeStamp; - ColorB m_Color; - float m_fQuadDist; // < 0 if not used -}; - -static StaticInstance> g_DebugFrustrums; - -void C3DEngine::DebugDraw_Draw() -{ -#ifndef _RELEASE - if (m_DebugDrawListMgr.IsEnabled()) - { - m_DebugDrawListMgr.Update(); - } - - CTimeValue CurrentTime = gEnv->pTimer->GetFrameStartTime(); - - IRenderAuxGeom* pAux = GetRenderer()->GetIRenderAuxGeom(); - - SAuxGeomRenderFlags oldFlags = pAux->GetRenderFlags(); - SAuxGeomRenderFlags newFlags; - newFlags.SetAlphaBlendMode(e_AlphaBlended); - newFlags.SetCullMode(e_CullModeNone); - newFlags.SetDepthWriteFlag(e_DepthWriteOff); - pAux->SetRenderFlags(newFlags); - std::vector::iterator it; - - for (it = g_DebugFrustrums.begin(); it != g_DebugFrustrums.end(); ) - { - SDebugFrustrum& ref = *it; - - float fRatio = (CurrentTime - ref.m_TimeStamp).GetSeconds() * 2.0f; - - if (fRatio > 1.0f) - { - it = g_DebugFrustrums.erase(it); - continue; - } - - vtx_idx pnInd[8] = { 0, 4, 1, 5, 2, 6, 3, 7 }; - - float fRadius = ((ref.m_vPos[0] + ref.m_vPos[1] + ref.m_vPos[2] + ref.m_vPos[3]) - (ref.m_vPos[4] + ref.m_vPos[5] + ref.m_vPos[6] + ref.m_vPos[7])).GetLength() * 0.25f; - float fDistance = min(fRadius, 33.0f); // in meters - - float fRenderRatio = fRatio * fDistance / fRadius; - - if (ref.m_fQuadDist > 0) - { - fRenderRatio = ref.m_fQuadDist / fRadius; - } - - Vec3 vPos[4]; - - for (uint32 i = 0; i < 4; ++i) - { - vPos[i] = ref.m_vPos[i] * fRenderRatio + ref.m_vPos[i + 4] * (1.0f - fRenderRatio); - } - - Vec3 vMid = (vPos[0] + vPos[1] + vPos[2] + vPos[3]) * 0.25f; - - ColorB col = ref.m_Color; - - if (ref.m_fQuadDist <= 0) - { - for (uint32 i = 0; i < 4; ++i) - { - vPos[i] = vPos[i] * 0.95f + vMid * 0.05f; - } - - // quad - if (ref.m_fQuadDist != -999.f) - { - pAux->DrawTriangle(vPos[0], col, vPos[2], col, vPos[1], col); - pAux->DrawTriangle(vPos[2], col, vPos[0], col, vPos[3], col); - } - // projection lines - pAux->DrawLines(ref.m_vPos, 8, pnInd, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - pAux->DrawLines(ref.m_vPos, 8, pnInd + 2, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - pAux->DrawLines(ref.m_vPos, 8, pnInd + 4, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - pAux->DrawLines(ref.m_vPos, 8, pnInd + 6, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - } - else - { - // rectangle - pAux->DrawPolyline(vPos, 4, true, RGBA8(0xff, 0xff, 0x1f, 0xff)); - } - - ++it; - } - - pAux->SetRenderFlags(oldFlags); - - - if (GetCVars()->e_DebugDraw == 16) - { - DebugDraw_UpdateDebugNode(); - } - else - { - GetRenderer()->SetDebugRenderNode(NULL); - } - -#endif //_RELEASE -} - -void C3DEngine::DebugDraw_UpdateDebugNode() -{ -#ifndef _RELEASE - - -#endif //_RELEASE -} - -void C3DEngine::RenderWorld(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName) -{ - AZ_TRACE_METHOD(); - - if (nRenderFlags & SHDF_ALLOW_AO) - { - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::OnFrameStart, passInfo); - } - - if (m_szLevelFolder[0] != 0) - { - m_nFramesSinceLevelStart++; - } - - assert(szDebugName); - - if (!GetCVars()->e_Render) - { - return; - } - - IF (!m_bEditor && (m_bInShutDown || m_bInUnload) && !GetRenderer()->IsPost3DRendererEnabled(), 0) - { - // Do not render during shutdown/unloading (should never reach here, unless something wrong with game/editor code) - return; - } - - FUNCTION_PROFILER_3DENGINE; - - if (GetCVars()->e_ScreenShot) - { - ScreenshotDispatcher(nRenderFlags, passInfo); - // screenshots can mess up the frame ids, be safe and recreate the rendering passinfo object after a screenshot - const_cast(passInfo) = SRenderingPassInfo::CreateGeneralPassRenderingInfo(passInfo.GetCamera()); - } - - if (GetCVars()->e_DefaultMaterial) - { - _smart_ptr pMat = GetMaterialManager()->LoadMaterial("Materials/material_default"); - _smart_ptr pTerrainMat = GetMaterialManager()->LoadMaterial("Materials/material_terrain_default"); - GetRenderer()->SetDefaultMaterials(pMat, pTerrainMat); - } - else - { - GetRenderer()->SetDefaultMaterials(NULL, NULL); - } - - // skip rendering if camera is invalid - if (IsCameraAnd3DEngineInvalid(passInfo, szDebugName)) - { - return; - } - - // this will also set the camera in passInfo for the General Pass (done here to support e_camerafreeze) - UpdateRenderingCamera(szDebugName, passInfo); - - RenderInternal(nRenderFlags, passInfo, szDebugName); - -#if !defined(_RELEASE) - PrintDebugInfo(passInfo); -#endif -} - -void C3DEngine::RenderInternal(const int nRenderFlags, const SRenderingPassInfo& passInfo, [[maybe_unused]] const char* szDebugName) -{ - assert(m_pObjManager); - - - if (AZ::Interface::Get()) - { - GetRenderer()->EF_EndEf3D( - IsShadersSyncLoad() ? (nRenderFlags | SHDF_NOASYNC | SHDF_STREAM_SYNC) : nRenderFlags, - GetObjManager()->GetUpdateStreamingPrioriryRoundId(), - GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast(), - passInfo); - } - else - { - UpdatePreRender(passInfo); - RenderScene(nRenderFlags, passInfo); - UpdatePostRender(passInfo); - } -} - - -void C3DEngine::PreWorldStreamUpdate(const CCamera& cam) -{ - if (m_szLevelFolder[0] != 0) - { - m_nStreamingFramesSinceLevelStart++; - } - - // force preload terrain data if camera was teleported more than 32 meters - if (!IsAreaActivationInUse() || m_bLayersActivated) - { - float fDistance = m_vPrevMainFrameCamPos.GetDistance(cam.GetPosition()); - - if (m_vPrevMainFrameCamPos != Vec3(-1000000.f, -1000000.f, -1000000.f)) - { - m_vAverageCameraMoveDir = m_vAverageCameraMoveDir * .75f + (cam.GetPosition() - m_vPrevMainFrameCamPos) / max(0.01f, GetTimer()->GetFrameTime()) * .25f; - if (m_vAverageCameraMoveDir.GetLength() > 10.f) - { - m_vAverageCameraMoveDir.SetLength(10.f); - } - - float fNewSpeed = fDistance / max(0.001f, gEnv->pTimer->GetFrameTime()); - if (fNewSpeed > m_fAverageCameraSpeed) - { - m_fAverageCameraSpeed = fNewSpeed * .20f + m_fAverageCameraSpeed * .80f; - } - else - { - m_fAverageCameraSpeed = fNewSpeed * .02f + m_fAverageCameraSpeed * .98f; - } - m_fAverageCameraSpeed = CLAMP(m_fAverageCameraSpeed, 0, 10.f); - } - - // Adjust streaming mip bias based on camera speed and depending on installed on HDD or not - bool bStreamingFromHDD = gEnv->pSystem->GetStreamEngine()->IsStreamDataOnHDD(); - if (GetCVars()->e_StreamAutoMipFactorSpeedThreshold) - { - if (m_fAverageCameraSpeed > GetCVars()->e_StreamAutoMipFactorSpeedThreshold) - { - GetRenderer()->SetTexturesStreamingGlobalMipFactor(bStreamingFromHDD ? GetCVars()->e_StreamAutoMipFactorMax * .5f : GetCVars()->e_StreamAutoMipFactorMax); - } - else - { - GetRenderer()->SetTexturesStreamingGlobalMipFactor(bStreamingFromHDD ? GetCVars()->e_StreamAutoMipFactorMin * .5f : GetCVars()->e_StreamAutoMipFactorMin); - } - } - else - { - if (bStreamingFromHDD) - { - GetRenderer()->SetTexturesStreamingGlobalMipFactor(0); - } - else - { - GetRenderer()->SetTexturesStreamingGlobalMipFactor(GetCVars()->e_StreamAutoMipFactorMaxDVD); - } - } - - if (GetCVars()->e_AutoPrecacheCameraJumpDist && fDistance > GetCVars()->e_AutoPrecacheCameraJumpDist) - { - m_bContentPrecacheRequested = true; - - // Invalidate existing precache info - m_pObjManager->IncrementUpdateStreamingPrioriryRoundIdFast(8); - m_pObjManager->IncrementUpdateStreamingPrioriryRoundId(8); - } - - m_vPrevMainFrameCamPos = cam.GetPosition(); - } -} - -void C3DEngine::WorldStreamUpdate() -{ -#if defined(STREAMENGINE_ENABLE_STATS) - static uint32 nCurrentRequestCount = 0; - static uint64 nCurrentBytesRead = 0; - if (m_nStreamingFramesSinceLevelStart == 1) - { - // store current streaming stats - SStreamEngineStatistics& fullStats = gEnv->pSystem->GetStreamEngine()->GetStreamingStatistics(); - nCurrentBytesRead = fullStats.nTotalBytesRead; - nCurrentRequestCount = fullStats.nTotalRequestCount; - } -#endif - - static float fTestStartTime = 0; - if (m_nStreamingFramesSinceLevelStart == 1) - { - fTestStartTime = GetCurAsyncTimeSec(); - gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME, 0, 0); - } - - // Simple streaming performance test: Wait until all startup texture streaming jobs finish and print a message - if (!m_bEditor) - { - if (!m_bPreCacheEndEventSent) - { - IStreamEngine* pSE = gEnv->pSystem->GetStreamEngine(); - SStreamEngineOpenStats openStats; - pSE->GetStreamingOpenStatistics(openStats); - bool bStarted = - (openStats.nOpenRequestCountByType[eStreamTaskTypeTexture] > 0) || - (openStats.nOpenRequestCountByType[eStreamTaskTypeGeometry] > 0); - - float fTime = GetCurAsyncTimeSec() - fTestStartTime; - - switch (m_nStreamingFramesSinceLevelStart) - { - case 1: - pSE->PauseStreaming(true, (1 << eStreamTaskTypeTexture) | (1 << eStreamTaskTypeGeometry)); - break; - case 4: - pSE->PauseStreaming(false, (1 << eStreamTaskTypeGeometry)); - break; - case 8: - pSE->PauseStreaming(false, (1 << eStreamTaskTypeTexture)); - break; - } - - int nGlobalSystemState = gEnv->pSystem->GetSystemGlobalState(); - - if ((nGlobalSystemState != ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_COMPLETE && (!bStarted || fTime >= 10.0f)) && m_nStreamingFramesSinceLevelStart > 16) - { - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_COMPLETE); - - if (!bStarted) - { - PrintMessage("Textures startup streaming finished in %.1f sec", fTime); - } - else - { - PrintMessage("Textures startup streaming timed out after %.1f sec", fTime); - } - - m_fTimeStateStarted = fTime; - } - - if (nGlobalSystemState == ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_COMPLETE && (fTime - m_fTimeStateStarted) > 0.4f) - { - pSE->PauseStreaming(false, (1 << eStreamTaskTypeTexture) | (1 << eStreamTaskTypeGeometry)); - - m_bPreCacheEndEventSent = true; - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_RUNNING); - gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_END, 0, 0); - - fTestStartTime = 0.f; - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics& fullStats = pSE->GetStreamingStatistics(); - uint64 nBytesRead = fullStats.nTotalBytesRead - nCurrentBytesRead; - uint32 nRequestCount = fullStats.nTotalRequestCount - nCurrentRequestCount; - - uint32 nOverallFileReadKB = (uint32)(nBytesRead / 1024); - uint32 nOverallFileReadNum = nRequestCount; - uint32 nBlockSize = (uint32)(nBytesRead / max((uint32)1, nRequestCount)); - float fReadBandwidthMB = (float)fullStats.nTotalSessionReadBandwidth / (1024 * 1024); - - PrintMessage("Average block size: %d KB, Average throughput: %.1f MB/sec, Jobs processed: %d (%.1f MB), File IO Bandwidth: %.2fMB/s", - (nBlockSize) / 1024, (float)(nOverallFileReadKB / max(fTime, 1.f)) / 1024.f, - nOverallFileReadNum, (float)nOverallFileReadKB / 1024.f, - fReadBandwidthMB); - - if (GetCVars()->e_StreamSaveStartupResultsIntoXML) - { - const char* testResultsFile = "@usercache@/TestResults/Streaming_Level_Start_Throughput.xml"; - - AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb"); - if (resultsFile != AZ::IO::InvalidHandle) - { - AZ::IO::Print(resultsFile, - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n", - fTime, - (nOverallFileReadKB / nOverallFileReadNum), - (float)nOverallFileReadKB / max(fTime, 1.f) / 1024.f, - nOverallFileReadNum, - (float)nOverallFileReadKB / 1024.f); - gEnv->pCryPak->FClose(resultsFile); - } - } -#endif - // gEnv->pCryPak->GetFileReadSequencer()->EndSection(); // STREAMING - } - else if (m_szLevelFolder[0]) - { - ProposeContentPrecache(); - } - } - } - else - { - if (!m_bPreCacheEndEventSent && m_nStreamingFramesSinceLevelStart == 4) - { - m_bPreCacheEndEventSent = true; - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_RUNNING); - gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_END, 0, 0); - } - } -} - -void C3DEngine::PrintDebugInfo(const SRenderingPassInfo& passInfo) -{ - if (GetCVars()->e_DebugDraw) - { - f32 fColor[4] = {1, 1, 0, 1}; - - float fYLine = 8.0f, fYStep = 20.0f; - - GetRenderer()->Draw2dLabel(8.0f, fYLine += fYStep, 2.0f, fColor, false, "e_DebugDraw = %d", GetCVars()->e_DebugDraw); - - const char* szMode = ""; - - switch (static_cast(GetCVars()->e_DebugDraw)) - { - case -1: - szMode = "Showing bounding boxes"; - break; - case 1: - szMode = "bounding boxes, name of the used cgf, polycount, used LOD"; - break; - case -2: - case 2: - szMode = "color coded polygon count(red,yellow,green,turqoise, blue)"; - break; - case -3: - szMode = "show color coded LODs count, flashing color indicates LOD."; - break; - case 3: - szMode = "show color coded LODs count, flashing color indicates LOD.\nFormat: (Current LOD [Min LOD; Max LOD] (LOD Ratio / Distance to camera)"; - break; - case -4: - case 4: - szMode = "object texture memory usage in KB"; - break; - case -5: - case 5: - szMode = "number of render materials (color coded)"; - break; - case 6: - szMode = "ambient color (R,G,B,A)"; - break; - case 7: - szMode = "triangle count, number of render materials, texture memory in KB"; - break; - case 8: - szMode = "Free slot"; - break; - case 9: - szMode = "Free slot"; - break; - case 10: - szMode = "Deprecated option, use \"r_showlines 2\" instead"; - break; - case 11: - szMode = "Free slot"; - break; - case 12: - szMode = "Free slot"; - break; - case 13: - szMode = "occlusion amount (used during AO computations)"; - break; - // case 14: szMode="";break; - case 15: - szMode = "display helpers"; - break; - case 16: - szMode = "Debug Gun"; - break; - case 17: - szMode = "streaming: buffer sizes (black: geometry, blue: texture)"; - if (gEnv->pLocalMemoryUsage) - { - gEnv->pLocalMemoryUsage->OnRender(GetRenderer(), &passInfo.GetCamera()); - } - break; - case 18: - szMode = "Free slot"; - break; - case 19: - szMode = "physics proxy triangle count"; - break; - case 20: - szMode = "Character attachments texture memory usage"; - break; - case 21: - szMode = "Display animated objects distance to camera"; - break; - case -22: - case 22: - szMode = "object's current LOD vertex count"; - break; - case 23: - szMode = "Display shadow casters in red"; - break; - case 24: - szMode = "Objects without LODs.\n name - (triangle count)\n draw calls - zpass/general/transparent/shadows/misc"; - break; - case 25: - szMode = "Objects without LODs (Red). Objects that need more LODs (Blue)\n name - (triangle count)\n draw calls - zpass/general/transparent/shadows/misc"; - break; - - default: - assert(0); - } - - GetRenderer()->Draw2dLabel(8.0f, fYLine += fYStep, 2.0f, fColor, false, " %s", szMode); - - if (GetCVars()->e_DebugDraw == 17) - { - GetRenderer()->Draw2dLabel(8.0f, fYLine += fYStep, 2.0f, fColor, false, " StatObj geometry used: %.2fMb / %dMb", CObjManager::s_nLastStreamingMemoryUsage / (1024.f * 1024.f), GetCVars()->e_StreamCgfPoolSize); - - ICVar* cVar = GetConsole()->GetCVar("r_TexturesStreaming"); - if (!cVar || !cVar->GetIVal()) - { - GetRenderer()->Draw2dLabel(8.0f, fYLine += fYStep, 2.0f, fColor, false, " You have to set r_TexturesStreaming = 1 to see texture information!"); - } - } - } - - float fTextPosX = 10, fTextPosY = 10, fTextStepY = 12; - - // print list of streamed meshes - if (m_pObjManager && GetCVars()->e_StreamCgf && GetCVars()->e_StreamCgfDebug >= 3) - { - // overall status - { - static char szCGFStreaming[256] = ""; - static SObjectsStreamingStatus objectsStreamingStatus = {0}; - - { - m_pObjManager->GetObjectsStreamingStatus(objectsStreamingStatus); - sprintf_s(szCGFStreaming, 256, "CgfStrm: Loaded:%d InProg:%d All:%d Act:%d MemUsed:%2.2f MemReq:%2.2f Pool:%d", - objectsStreamingStatus.nReady, objectsStreamingStatus.nInProgress, objectsStreamingStatus.nTotal, objectsStreamingStatus.nActive, float(objectsStreamingStatus.nAllocatedBytes) / 1024 / 1024, float(objectsStreamingStatus.nMemRequired) / 1024 / 1024, GetCVars()->e_StreamCgfPoolSize); - } - - bool bOutOfMem((float(objectsStreamingStatus.nMemRequired) / 1024 / 1024) > GetCVars()->e_StreamCgfPoolSize); - bool bCloseToOutOfMem((float(objectsStreamingStatus.nMemRequired) / 1024 / 1024) > GetCVars()->e_StreamCgfPoolSize * 90 / 100); - - ColorF color = Col_White; - if (bOutOfMem) - { - color = Col_Red; - } - else if (bCloseToOutOfMem) - { - color = Col_Orange; - } - - DrawTextLeftAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, color, szCGFStreaming); - fTextPosY += fTextStepY; - } - - DrawTextLeftAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_White, "------------------- List of meshes bigger than %d KB -------------------", GetCVars()->e_StreamCgfDebugMinObjSize); - - for (int nObjId = 0; nObjId < m_pObjManager->GetArrStreamableObjects().Count(); nObjId++) - { - CStatObj* pStatObj = (CStatObj*)m_pObjManager->GetArrStreamableObjects()[nObjId].GetStreamAbleObject(); - - int nKB = pStatObj->GetStreamableContentMemoryUsage() >> 10; - int nSel = (pStatObj->m_nSelectedFrameId >= passInfo.GetMainFrameID() - 2); - - string sName; - pStatObj->GetStreamableName(sName); - - if ((nKB >= GetCVars()->e_StreamCgfDebugMinObjSize && strstr(sName.c_str(), GetCVars()->e_StreamCgfDebugFilter->GetString())) || nSel) - { - const char* pComment = 0; - - if (!pStatObj->m_bCanUnload) - { - pComment = "NO_STRM"; - } - else if (pStatObj->m_pLod0) - { - pComment = " LOD_X"; - } - else if (!pStatObj->m_bLodsAreLoadedFromSeparateFile && pStatObj->m_nLoadedLodsNum > 1) - { - pComment = " SINGLE"; - } - else if (pStatObj->m_nLoadedLodsNum > 1) - { - pComment = " LOD_0"; - } - else - { - pComment = "NO_LODS"; - } - - int nDiff = SATURATEB(int(float(nKB - GetCVars()->e_StreamCgfDebugMinObjSize) / max(1, (int)GetCVars()->e_StreamCgfDebugMinObjSize) * 255)); - ColorB col(nDiff, 255 - nDiff, 0, 255); - if (nSel && (1 & (int)(GetCurTimeSec() * 5.f))) - { - col = Col_Yellow; - } - ColorF fColor(col[0] / 255.f, col[1] / 255.f, col[2] / 255.f, col[3] / 255.f); - - const char* pStatusText = "Unload"; - if (pStatObj->m_eStreamingStatus == ecss_Ready) - { - pStatusText = "Ready "; - } - else if (pStatObj->m_eStreamingStatus == ecss_InProgress) - { - pStatusText = "InProg"; - } - - DrawTextLeftAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, fColor, "%1.2f mb, %s, %s, %s", - 1.f / 1024.f * nKB, pComment, pStatusText, sName.c_str()); - - if (fTextPosY > (float)gEnv->pRenderer->GetHeight()) - { - break; - } - } - } - } - - if (m_arrProcessStreamingLatencyTestResults.Count()) - { - float fAverTime = 0; - for (int i = 0; i < m_arrProcessStreamingLatencyTestResults.Count(); i++) - { - fAverTime += m_arrProcessStreamingLatencyTestResults[i]; - } - fAverTime /= m_arrProcessStreamingLatencyTestResults.Count(); - - int nAverTexNum = 0; - for (int i = 0; i < m_arrProcessStreamingLatencyTexNum.Count(); i++) - { - nAverTexNum += m_arrProcessStreamingLatencyTexNum[i]; - } - nAverTexNum /= m_arrProcessStreamingLatencyTexNum.Count(); - - DrawTextLeftAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Yellow, "------ SQT Average Time = %.1f, TexNum = %d ------", fAverTime, nAverTexNum); - - for (int i = 0; i < m_arrProcessStreamingLatencyTestResults.Count(); i++) - { - DrawTextLeftAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Yellow, "Run %d: Time = %.1f, TexNum = %d", - i, m_arrProcessStreamingLatencyTestResults[i], m_arrProcessStreamingLatencyTexNum[i]); - } - } - -#if defined(USE_GEOM_CACHES) -#ifndef _RELEASE - if (GetCVars()->e_GeomCacheDebug) - { - m_pGeomCacheManager->DrawDebugInfo(); - } - else - { - m_pGeomCacheManager->ResetDebugInfo(); - } -#endif -#endif -} - -void C3DEngine::UpdatePreRender(const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - FUNCTION_PROFILER(GetISystem(), PROFILE_3DENGINE); - - assert(passInfo.IsGeneralPass()); - - // Compute global shadow cascade parameters. - { - m_fGsmRange = GetCVars()->e_GsmRange; - m_fGsmRangeStep = GetCVars()->e_GsmRangeStep; - - //!!!also formulas for computing biases per gsm needs to be changed - m_fShadowsConstBias = GetCVars()->e_ShadowsConstBias; - m_fShadowsSlopeBias = GetCVars()->e_ShadowsSlopeBias; - - if (m_eShadowMode == ESM_HIGHQUALITY) - { - m_fGsmRange = min(0.15f, GetCVars()->e_GsmRange); - m_fGsmRangeStep = min(2.8f, GetCVars()->e_GsmRangeStep); - - m_fShadowsConstBias = min(GetCVars()->e_ShadowsConstBiasHQ, GetCVars()->e_ShadowsConstBias); - m_fShadowsSlopeBias = min(GetCVars()->e_ShadowsSlopeBiasHQ, GetCVars()->e_ShadowsSlopeBias); - } - - const int nCascadeCount = Get3DEngine()->GetShadowsCascadeCount(NULL); - m_pObjManager->SetGSMMaxDistance(Get3DEngine()->m_fGsmRange * powf(Get3DEngine()->m_fGsmRangeStep, (float)nCascadeCount)); - } - - // (bethelz) This has to happen before particle updates. - m_PhysicsAreaUpdates.Update(); - - if (passInfo.RenderClouds()) - { - if (m_pCloudsManager) - { - m_pCloudsManager->MoveClouds(); - } - - CVolumeObjectRenderNode::MoveVolumeObjects(); - } - - UpdateSun(passInfo); - - // Set traceable fog volume areas - CFogVolumeRenderNode::SetTraceableArea(AABB(passInfo.GetCamera().GetPosition(), 1024.0f), passInfo); -} - -void C3DEngine::UpdatePostRender(const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - FUNCTION_PROFILER(GetISystem(), PROFILE_3DENGINE); - - assert (m_pObjManager); - - m_pObjManager->CheckTextureReadyFlag(); - if (GetCVars()->e_StreamCgf) - { - static Array2d memUsage; - - int nArrayDim = 256; -#ifndef CONSOLE_CONST_CVAR_MODE - if (GetCVars()->e_StreamCgfDebugHeatMap == 1) - { - memUsage.Allocate(nArrayDim); - CCamera camOld = passInfo.GetCamera(); - - PrintMessage("Computing mesh streaming heat map"); - - //The assumption is that this is called on Main Thread, otherwise the loop - //Should be wrapped inside a EnumerateHandlers lambda. - auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler(); - const float defaultTerrainHeight = AzFramework::Terrain::TerrainDataRequests::GetDefaultTerrainHeight(); - - const AZ::Aabb terrainAabb = terrain ? terrain->GetTerrainAabb() : AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - const int nTerrainSizeX = static_cast(terrainAabb.GetXExtent()); - const int nTerrainSizeY = static_cast(terrainAabb.GetYExtent()); - const int nStepX = nTerrainSizeX / nArrayDim; - const int nStepY = nTerrainSizeY / nArrayDim; - - for (int x = 0; x < nTerrainSizeX; x += nStepX) - { - for (int y = 0; y < nTerrainSizeY; y += nStepY) - { - CCamera camTmp = camOld; - float terrainHeight = terrain ? terrain->GetHeightFromFloats((float)x, (float)y) : defaultTerrainHeight; - camTmp.SetPosition(Vec3((float)x + (float)nStepX / 2.f, (float)y + (float)nStepY / 2.f, terrainHeight)); - //SetCamera(camTmp); - m_pObjManager->ProcessObjectsStreaming(passInfo); - - SObjectsStreamingStatus objectsStreamingStatus; - m_pObjManager->GetObjectsStreamingStatus(objectsStreamingStatus); - - memUsage[x / nStepX][y / nStepY] = objectsStreamingStatus.nMemRequired; - } - - if (!((x / nStepX) & 31)) - { - PrintMessage(" working ..."); - } - } - - PrintMessage(" done"); - - GetCVars()->e_StreamCgfDebugHeatMap = 2; - //SetCamera(camOld); - } - else if (GetCVars()->e_StreamCgfDebugHeatMap == 2) - { - auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler(); - const float defaultTerrainHeight = AzFramework::Terrain::TerrainDataRequests::GetDefaultTerrainHeight(); - - const AZ::Aabb terrainAabb = terrain ? terrain->GetTerrainAabb() : AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - const float terrainSizeX = terrainAabb.GetXExtent(); - const float terrainSizeY = terrainAabb.GetYExtent(); - const float fStepX = terrainSizeX / nArrayDim; - const float fStepY = terrainSizeY / nArrayDim; - - for (int x = 0; x < memUsage.GetSize(); x++) - { - for (int y = 0; y < memUsage.GetSize(); y++) - { - float terrainHeight = terrain ? terrain->GetHeightFromFloats((float)x * fStepX, (float)y * fStepY) : defaultTerrainHeight; - Vec3 v0((float)x* fStepX, (float)y* fStepY, terrainHeight); - Vec3 v1((float)x* fStepX + fStepX, (float)y* fStepY + fStepY, v0.z + fStepX); - v0 += Vec3(.25f, .25f, .25f); - v1 -= Vec3(.25f, .25f, .25f); - AABB box(v0, v1); - if (!passInfo.GetCamera().IsAABBVisible_F(box)) - { - continue; - } - - int nMemUsageMB = memUsage[(int)(x)][(int)(y)] / 1024 / 1024; - - int nOverLoad = nMemUsageMB - GetCVars()->e_StreamCgfPoolSize; - - ColorB col = Col_Red; - - if (nOverLoad < GetCVars()->e_StreamCgfPoolSize / 2) - { - col = Col_Yellow; - } - - if (nOverLoad < 0) - { - col = Col_Green; - } - - DrawBBox(box, col); - } - } - } -#endif //CONSOLE_CONST_CVAR_MODE - m_pObjManager->ProcessObjectsStreaming(passInfo); - } - else - { - m_pObjManager->GetStreamPreCacheCameras()[0].vPosition = passInfo.GetCamera().GetPosition(); - if (Distance::Point_AABBSq(m_pObjManager->GetStreamPreCacheCameras()[0].vPosition, m_pObjManager->GetStreamPreCacheCameras()[0].bbox) > 0.0f) - { - m_pObjManager->GetStreamPreCacheCameras()[0].bbox = AABB(m_pObjManager->GetStreamPreCacheCameras()[0].vPosition, GetCVars()->e_StreamPredictionBoxRadius); - } - m_pObjManager->UpdateObjectsStreamingPriority(false, passInfo); - } - - // (bethelz) Per-frame precache request handled by streaming systems. - m_bContentPrecacheRequested = false; -} - -int __cdecl C3DEngine__Cmp_SRNInfo(const void* v1, const void* v2) -{ - SRNInfo* p1 = (SRNInfo*)v1; - SRNInfo* p2 = (SRNInfo*)v2; - - float fViewDist1 = p1->fMaxViewDist - p1->objSphere.radius; - float fViewDist2 = p2->fMaxViewDist - p2->objSphere.radius; - - // if same - give closest sectors higher priority - if (fViewDist1 > fViewDist2) - { - return 1; - } - else if (fViewDist1 < fViewDist2) - { - return -1; - } - - return 0; -} - -void C3DEngine::SetSkyMaterialPath(const string& skyMatName) -{ - m_skyMatName = skyMatName; - m_pSkyMat = nullptr; -} - -void C3DEngine::SetSkyLowSpecMaterialPath(const string& skyLowSpecMatName) -{ - m_skyLowSpecMatName = skyLowSpecMatName; - m_pSkyLowSpecMat = nullptr; -} - -void C3DEngine::LoadSkyMaterial() -{ - const int skyType = GetCVars()->e_SkyType; - if (skyType == 0) - { - if (!m_pSkyLowSpecMat) - { - m_pSkyLowSpecMat = m_skyLowSpecMatName.empty() ? nullptr : m_pMatMan->LoadMaterial(m_skyLowSpecMatName.c_str(), false, false, MTL_FLAG_IS_SKY); - AZ_Warning("3DEngine", m_pSkyLowSpecMat, "Missing low spec sky material: %s", m_skyLowSpecMatName.c_str()); - } - } - else - { - if (!m_pSkyMat) - { - m_pSkyMat = m_skyMatName.empty() ? nullptr : m_pMatMan->LoadMaterial(m_skyMatName.c_str(), false, false, MTL_FLAG_IS_SKY); - AZ_Warning("3DEngine", m_pSkyMat, "Missing sky material: %s", m_skyMatName.c_str()); - } - } - m_previousSkyType = skyType; -} - -_smart_ptr C3DEngine::GetSkyMaterial() -{ - const int skyType = GetCVars()->e_SkyType; - - // If e_SkyType has changed, then we may need to load a different sky material. - if (skyType != m_previousSkyType) - { - LoadSkyMaterial(); - } - - return (skyType == 0) ? m_pSkyLowSpecMat : m_pSkyMat; -} - -void C3DEngine::SetSkyMaterial(_smart_ptr pSkyMat) -{ - m_pSkyMat = pSkyMat; -} - -bool C3DEngine::IsHDRSkyMaterial(_smart_ptr pMat) const -{ - return pMat && !azstricmp(pMat->GetSafeSubMtl(0)->GetShaderItem().m_pShader->GetName(), "SkyHDR"); -} - -void C3DEngine::RenderScene(const int nRenderFlags, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - CRY_ASSERT(passInfo.IsGeneralPass()); - CRY_ASSERT(m_pVisAreaManager); - CRY_ASSERT(m_pClipVolumeManager); - CRY_ASSERT(m_pDecalManager); - - GetObjManager()->GetCullThread().SetActive(true); - - if (GetCVars()->e_CoverageBuffer) - { - m_pCoverageBuffer->BeginFrame(passInfo); - } - - if (m_pVisAreaManager != nullptr) - { - m_pVisAreaManager->DrawOcclusionAreasIntoCBuffer(m_pCoverageBuffer, passInfo); - m_pVisAreaManager->CheckVis(passInfo); - } - - if (m_pClipVolumeManager) - { - m_pClipVolumeManager->PrepareVolumesForRendering(passInfo); - } - - if (m_pObjManager) - { - m_pObjManager->RenderAllObjectDebugInfo(); - } - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - - // make sure all jobs from the previous frame have finished - threadID nPrevThreadID = 0; - gEnv->pRenderer->EF_Query(EFQ_RenderThreadList, nPrevThreadID); - gEnv->pRenderer->GetFinalizeRendItemJobExecutor(nPrevThreadID)->WaitForCompletion(); - gEnv->pRenderer->GetFinalizeShadowRendItemJobExecutor(nPrevThreadID)->WaitForCompletion(); - - GetRenderer()->EF_ClearSkinningDataPool(); - GetRenderer()->BeginSpawningGeneratingRendItemJobs(passInfo.ThreadID()); - - GetRenderer()->EF_StartEf(passInfo); - - m_bIsInRenderScene = true; - COctreeNode::ReleaseEmptyNodes(); - - m_LightVolumesMgr.Clear(passInfo); - - SubmitSun(passInfo); - - if (GetCVars()->e_StatObjBufferRenderTasks && m_pObjManager != nullptr) - { - m_pObjManager->BeginOcclusionCulling(passInfo); - } - - if (m_pVisAreaManager != nullptr) - { - m_pVisAreaManager->DrawVisibleSectors(passInfo, rendItemSorter); - } - m_nOceanRenderFlags &= ~OCR_OCEANVOLUME_VISIBLE; - - if (IsOutdoorVisible() || GetRenderer()->IsPost3DRendererEnabled()) - { - if (m_pVisAreaManager != nullptr && m_pVisAreaManager->m_lstOutdoorPortalCameras.Count() && - (m_pVisAreaManager->m_pCurArea || m_pVisAreaManager->m_pCurPortal)) - { // enable multi-camera culling - const_cast(passInfo.GetCamera()).m_pMultiCamera = &m_pVisAreaManager->m_lstOutdoorPortalCameras; - } - - if (IsOutdoorVisible()) - { - RenderSkyBox(GetSkyMaterial(), passInfo); - } - - rendItemSorter.IncreaseOctreeCounter(); - { - FRAME_PROFILER_LEGACYONLY("COctreeNode::Render_____", GetSystem(), PROFILE_3DENGINE); - AZ_TRACE_METHOD_NAME("COctreeNode::Render"); - if (m_pObjectsTree != nullptr) - { - m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS, passInfo, rendItemSorter); - } - } - rendItemSorter.IncreaseGroupCounter(); - } - else if (m_pVisAreaManager && m_pVisAreaManager->IsSkyVisible()) - { - RenderSkyBox(GetSkyMaterial(), passInfo); - } - - // Outdoor is not visible, that means there is no SkyBox to render. - // So we want to clear the GBuffer RT/background in order to avoid artifacts. - GetRenderer()->SetClearBackground(!IsOutdoorVisible()); - - if (nRenderFlags & SHDF_ALLOW_AO) - { - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::UpdateRenderData); - } - - { - FRAME_PROFILER_LEGACYONLY("COctreeNode::Render_Object_Nodes_NEAR", GetSystem(), PROFILE_3DENGINE); - AZ_TRACE_METHOD_NAME("COctreeNode::Render_Object_Nodes_NEAR"); - rendItemSorter.IncreaseOctreeCounter(); - if (GetCVars()->e_PortalsBigEntitiesFix) - { - if (!IsOutdoorVisible() && GetVisAreaManager() != nullptr && GetVisAreaManager()->GetCurVisArea()) - { - if (GetVisAreaManager()->GetCurVisArea()->IsConnectedToOutdoor()) - { - CCamera cam = passInfo.GetCamera(); - cam.SetFrustum(cam.GetViewSurfaceX(), cam.GetViewSurfaceZ(), cam.GetFov(), min(cam.GetNearPlane(), 1.f), 2.f, cam.GetPixelAspectRatio()); - m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS | OCTREENODE_RENDER_FLAG_OBJECTS_ONLY_ENTITIES, SRenderingPassInfo::CreateTempRenderingInfo(cam, passInfo), rendItemSorter); - } - } - } - } - rendItemSorter.IncreaseGroupCounter(); - - // render special objects like laser beams intersecting entire level - for (int i = 0; i < m_lstAlwaysVisible.Count(); i++) - { - IRenderNode* pObj = m_lstAlwaysVisible[i]; - const AABB& objBox = pObj->GetBBox(); - // don't frustum cull the HUD. When e.g. zooming the FOV for this camera is very different to the - // fixed HUD FOV, and this can cull incorrectly. - const unsigned int dwRndFlags = pObj->GetRndFlags(); - if (dwRndFlags & ERF_HUD || passInfo.GetCamera().IsAABBVisible_E(objBox)) - { - FRAME_PROFILER_LEGACYONLY("C3DEngine::RenderScene_DrawAlwaysVisible", GetSystem(), PROFILE_3DENGINE); - AZ_TRACE_METHOD_NAME("COctreeNode::RenderScene_DrawAlwaysVisible"); - - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - assert(fEntDistance >= 0 && _finite(fEntDistance)); - if (fEntDistance < pObj->m_fWSMaxViewDist && GetObjManager() != nullptr) - { - GetObjManager()->RenderObject(pObj, objBox, fEntDistance, pObj->GetRenderNodeType(), passInfo, rendItemSorter); - } - } - } - rendItemSorter.IncreaseGroupCounter(); - - if (m_pOcean) - { - ProcessOcean(passInfo); - } - - if (passInfo.RenderDecals() && m_pDecalManager != nullptr) - { - m_pDecalManager->Render(passInfo); - } - - // tell the occlusion culler that no new work will be submitted - if (GetCVars()->e_StatObjBufferRenderTasks == 1 && GetObjManager() != nullptr) - { - GetObjManager()->PushIntoCullQueue(SCheckOcclusionJobData::CreateQuitJobData()); - } - - // fill shadow list here to allow more time between starting and waiting for the occlusion buffer - InitShadowFrustums(passInfo); - - gEnv->pSystem->DoWorkDuringOcclusionChecks(); - - if (GetCVars()->e_StatObjBufferRenderTasks && m_pObjManager != nullptr) - { - m_pObjManager->RenderBufferedRenderMeshes(passInfo); - } - - // don't start shadow jobs if we aren't generating shadows - if ((nRenderFlags & SHDF_NO_SHADOWGEN) == 0) - { - GetRenderer()->EF_InvokeShadowMapRenderJobs(IsShadersSyncLoad() ? (nRenderFlags | SHDF_NOASYNC | SHDF_STREAM_SYNC) : nRenderFlags); - } - - m_LightVolumesMgr.Update(passInfo); - - SetupDistanceFog(); - - SetupClearColor(); - - { - FRAME_PROFILER("Renderer::EF_EndEf3D", GetSystem(), PROFILE_RENDERER); - // TODO: separate SHDF_NOASYNC and SHDF_STREAM_SYNC flags - GetRenderer()->EF_EndEf3D(IsShadersSyncLoad() ? (nRenderFlags | SHDF_NOASYNC | SHDF_STREAM_SYNC) : nRenderFlags, GetObjManager()->GetUpdateStreamingPrioriryRoundId(), GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast(), passInfo); - } - - GetRenderer()->EnableFog(false); - - bool bIsMultiThreadedRenderer = false; - gEnv->pRenderer->EF_Query(EFQ_RenderMultithreaded, bIsMultiThreadedRenderer); - if (bIsMultiThreadedRenderer) - { - gEnv->pRenderer->EndSpawningGeneratingRendItemJobs(); - } - - m_bIsInRenderScene = false; - -#ifndef _RELEASE - IF (GetCVars()->e_LightVolumesDebug, 0) - { - m_LightVolumesMgr.DrawDebug(passInfo); - } -#endif -} - -void C3DEngine::WaitForCullingJobsCompletion() -{ - const bool waitForOcclusionJobCompletion = true; - m_pObjManager->EndOcclusionCulling(waitForOcclusionJobCompletion); - COctreeNode::WaitForContentJobCompletion(); -} - -void C3DEngine::RenderSceneReflection(const int nRenderFlags, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - CRY_ASSERT(passInfo.IsRecursivePass()); - CRY_ASSERT(passInfo.GetRecursiveLevel() < MAX_RECURSION_LEVELS); - CRY_ASSERT(m_pVisAreaManager); - CRY_ASSERT(m_pClipVolumeManager); - CRY_ASSERT(m_pDecalManager); - - if (!GetCVars()->e_Recursion) - { - return; - } - - if (m_pVisAreaManager != nullptr) - { - m_pVisAreaManager->CheckVis(passInfo); - } - - if (m_pClipVolumeManager != nullptr) - { - m_pClipVolumeManager->PrepareVolumesForRendering(passInfo); - } - //////////////////////////////////////////////////////////////////////////////////////// - // From here we add render elements of main scene - //////////////////////////////////////////////////////////////////////////////////////// - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - - GetRenderer()->EF_StartEf(passInfo); - - if (m_pVisAreaManager != nullptr) - { - m_pVisAreaManager->DrawVisibleSectors(passInfo, rendItemSorter); - } - - if (IsOutdoorVisible() || GetRenderer()->IsPost3DRendererEnabled()) - { - if (m_pVisAreaManager != nullptr && m_pVisAreaManager->m_lstOutdoorPortalCameras.Count() && - (m_pVisAreaManager->m_pCurArea || m_pVisAreaManager->m_pCurPortal)) - { // enable multi-camera culling - const_cast(passInfo.GetCamera()).m_pMultiCamera = &m_pVisAreaManager->m_lstOutdoorPortalCameras; - } - - if (IsOutdoorVisible()) - { - RenderSkyBox(GetSkyMaterial(), passInfo); - } - - { - rendItemSorter.IncreaseOctreeCounter(); - FRAME_PROFILER("COctreeNode::Render_____", GetSystem(), PROFILE_3DENGINE); - if (m_pObjectsTree != nullptr) - { - m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS, passInfo, rendItemSorter); - } - } - rendItemSorter.IncreaseGroupCounter(); - } - else if (m_pVisAreaManager != nullptr && m_pVisAreaManager->IsSkyVisible()) - { - RenderSkyBox(GetSkyMaterial(), passInfo); - } - - { - FRAME_PROFILER("COctreeNode::Render_Object_Nodes_NEAR", GetSystem(), PROFILE_3DENGINE); - rendItemSorter.IncreaseOctreeCounter(); - if (GetCVars()->e_PortalsBigEntitiesFix) - { - if (!IsOutdoorVisible() && GetVisAreaManager() != nullptr && GetVisAreaManager()->GetCurVisArea()) - { - if (GetVisAreaManager()->GetCurVisArea()->IsConnectedToOutdoor()) - { - CCamera cam = passInfo.GetCamera(); - cam.SetFrustum(cam.GetViewSurfaceX(), cam.GetViewSurfaceZ(), cam.GetFov(), min(cam.GetNearPlane(), 1.f), 2.f, cam.GetPixelAspectRatio()); - if (m_pObjectsTree != nullptr) - { - m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS | OCTREENODE_RENDER_FLAG_OBJECTS_ONLY_ENTITIES, SRenderingPassInfo::CreateTempRenderingInfo(cam, passInfo), rendItemSorter); - } - } - } - } - } - rendItemSorter.IncreaseGroupCounter(); - - // render special objects like laser beams intersecting entire level - for (int i = 0; i < m_lstAlwaysVisible.Count(); i++) - { - IRenderNode* pObj = m_lstAlwaysVisible[i]; - const AABB& objBox = pObj->GetBBox(); - // don't frustum cull the HUD. When e.g. zooming the FOV for this camera is very different to the - // fixed HUD FOV, and this can cull incorrectly. - const unsigned int dwRndFlags = pObj->GetRndFlags(); - if (dwRndFlags & ERF_HUD || passInfo.GetCamera().IsAABBVisible_E(objBox)) - { - FRAME_PROFILER("C3DEngine::RenderScene_DrawAlwaysVisible", GetSystem(), PROFILE_3DENGINE); - - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - assert(fEntDistance >= 0 && _finite(fEntDistance)); - if (fEntDistance < pObj->m_fWSMaxViewDist) - { - GetObjManager()->RenderObject(pObj, objBox, fEntDistance, pObj->GetRenderNodeType(), passInfo, rendItemSorter); - } - } - } - rendItemSorter.IncreaseGroupCounter(); - - if (m_pOcean) - { - ProcessOcean(passInfo); - } - - //Update light volumes again. Processing particles may have resulted in an increase in the number of light volumes. - m_LightVolumesMgr.Update(passInfo); - - if (passInfo.RenderDecals() && m_pDecalManager != nullptr) - { - m_pDecalManager->Render(passInfo); - } - - { - FRAME_PROFILER("Renderer::EF_EndEf3D", GetSystem(), PROFILE_RENDERER); - GetRenderer()->EF_EndEf3D(IsShadersSyncLoad() ? (nRenderFlags | SHDF_NOASYNC | SHDF_STREAM_SYNC) : nRenderFlags, GetObjManager()->GetUpdateStreamingPrioriryRoundId(), GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast(), passInfo); - } -} - -void C3DEngine::ProcessOcean(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - AZ_Assert(m_pOcean != nullptr, "Ocean pointer must be validated before calling ProcessOcean"); - - if (GetOceanRenderFlags() & OCR_NO_DRAW || !GetVisAreaManager() || GetCVars()->e_DefaultMaterial) - { - return; - } - - bool bOceanIsForcedByVisAreaFlags = GetVisAreaManager()->IsOceanVisible(); - - if (!IsOutdoorVisible() && !bOceanIsForcedByVisAreaFlags) - { - return; - } - - bool bOceanVisible = false; - if (OceanToggle::IsActive()) - { - bOceanVisible = OceanRequest::OceanIsEnabled(); - } - else - { - bOceanVisible = true; - } - - if (bOceanVisible && passInfo.RenderWaterOcean() && m_bOcean) - { - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - float fWaterPlaneSize = passInfo.GetCamera().GetFarPlane(); - const float fOceanLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel(): m_pOcean->GetWaterLevel(); - - AABB boxOcean(Vec3(vCamPos.x - fWaterPlaneSize, vCamPos.y - fWaterPlaneSize, std::numeric_limits::lowest()), - Vec3(vCamPos.x + fWaterPlaneSize, vCamPos.y + fWaterPlaneSize, fOceanLevel + 0.5f)); - - if ((!bOceanIsForcedByVisAreaFlags && passInfo.GetCamera().IsAABBVisible_EM(boxOcean)) || - (bOceanIsForcedByVisAreaFlags && passInfo.GetCamera().IsAABBVisible_E (boxOcean))) - { - bool bOceanIsVisibleFromIndoor = true; - if (class PodArray* pMultiCamera = passInfo.GetCamera().m_pMultiCamera) - { - for (int i = 0; i < pMultiCamera->Count(); i++) - { - CVisArea* pExitPortal = (CVisArea*)(pMultiCamera->Get(i))->m_pPortal; - float fMinZ = pExitPortal->GetAABBox()->min.z; - float fMaxZ = pExitPortal->GetAABBox()->max.z; - - if (!bOceanIsForcedByVisAreaFlags) - { - if (fMinZ > fOceanLevel && vCamPos.z < fMinZ) - { - bOceanIsVisibleFromIndoor = false; - } - - if (fMaxZ < fOceanLevel && vCamPos.z > fMaxZ) - { - bOceanIsVisibleFromIndoor = false; - } - } - } - } - - if (bOceanIsVisibleFromIndoor) - { - m_pOcean->Update(passInfo); - - if ((GetOceanRenderFlags() & OCR_OCEANVOLUME_VISIBLE)) - { - if (passInfo.RenderWaterOcean()) - { - m_pOcean->Render(passInfo); - m_pOcean->SetLastFov(passInfo.GetCamera().GetFov()); - } - } - } - } - } - - if (GetCVars()->e_WaterRipplesDebug > 0) - { - GetRenderer()->EF_DrawWaterSimHits(); - } -} - -void C3DEngine::RenderSkyBox(_smart_ptr pMat, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - if (!Get3DEngine()->GetCoverageBuffer()->IsOutdooVisible()) - { - return; - } - - const float fForceDrawLastSortOffset = 100000.0f; - - // hdr sky dome - // TODO: temporary workaround to force the right sky dome for the selected shader - if (m_pREHDRSky && IsHDRSkyMaterial(pMat)) - { - if (GetCVars()->e_SkyBox) - { -#ifndef CONSOLE_CONST_CVAR_MODE - if (GetCVars()->e_SkyQuality < 1) - { - GetCVars()->e_SkyQuality = 1; - } - else if (GetCVars()->e_SkyQuality > 2) - { - GetCVars()->e_SkyQuality = 2; - } -#endif - m_pSkyLightManager->SetQuality(GetCVars()->e_SkyQuality); - - // set sky light incremental update rate and perform update - if (GetCVars()->e_SkyUpdateRate <= 0.0f) - { - GetCVars()->e_SkyUpdateRate = 0.01f; - } - m_pSkyLightManager->IncrementalUpdate(GetCVars()->e_SkyUpdateRate, passInfo); - - // prepare render object - CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObj) - { - return; - } - pObj->m_II.m_Matrix.SetTranslationMat(passInfo.GetCamera().GetPosition()); - pObj->m_pRenderNode = 0;//m_pREHDRSky; - pObj->m_fSort = fForceDrawLastSortOffset; // force sky to draw last - - /* if( 0 == m_nRenderStackLevel ) - { - // set scissor rect - pObj->m_nScissorX1 = GetCamera().m_ScissorInfo.x1; - pObj->m_nScissorY1 = GetCamera().m_ScissorInfo.y1; - pObj->m_nScissorX2 = GetCamera().m_ScissorInfo.x2; - pObj->m_nScissorY2 = GetCamera().m_ScissorInfo.y2; - }*/ - - m_pREHDRSky->m_pRenderParams = m_pSkyLightManager->GetRenderParams(); - m_pREHDRSky->m_moonTexId = m_nNightMoonTexId; - - // add sky dome to render list - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - GetRenderer()->EF_AddEf(m_pREHDRSky, pMat->GetSafeSubMtl(0)->GetShaderItem(), pObj, passInfo, EFSLIST_GENERAL, 1, rendItemSorter); - } - } - // skybox - else - { - if (pMat && m_pRESky && GetCVars()->e_SkyBox) - { - CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObj) - { - return; - } - pObj->m_II.m_Matrix.SetTranslationMat(passInfo.GetCamera().GetPosition()); - pObj->m_II.m_Matrix = pObj->m_II.m_Matrix * Matrix33::CreateRotationZ(DEG2RAD(m_fSkyBoxAngle)); - pObj->m_fSort = fForceDrawLastSortOffset; // force sky to draw last - - if (OceanToggle::IsActive()) - { - m_pRESky->m_fTerrainWaterLevel = OceanRequest::GetOceanLevelOrDefault(-100000.0f); - } - else - { - const float waterLevel = m_pOcean ? m_pOcean->GetWaterLevel() : 0.0f; - m_pRESky->m_fTerrainWaterLevel = max(0.0f, waterLevel); - } - m_pRESky->m_fSkyBoxStretching = m_fSkyBoxStretching; - - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - GetRenderer()->EF_AddEf(m_pRESky, pMat->GetSafeSubMtl(0)->GetShaderItem(), pObj, passInfo, EFSLIST_GENERAL, 1, rendItemSorter); - } - } -} - -void C3DEngine::DrawTextRightAligned(const float x, const float y, const char* format, ...) -{ - va_list args; - va_start(args, format); - - SDrawTextInfo ti; - ti.flags = eDrawText_FixedSize | eDrawText_Right | eDrawText_2D | eDrawText_Monospace; - ti.xscale = ti.yscale = DISPLAY_INFO_SCALE; - GetRenderer()->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args); - - va_end(args); -} - -void C3DEngine::DrawTextAligned(int flags, const float x, const float y, const float scale, const ColorF& color, const char* format, ...) -{ - va_list args; - va_start(args, format); - - SDrawTextInfo ti; - ti.flags = flags; - ti.color[0] = color[0]; - ti.color[1] = color[1]; - ti.color[2] = color[2]; - ti.color[3] = color[3]; - ti.xscale = ti.yscale = scale; - GetRenderer()->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args); - - va_end(args); -} - -void C3DEngine::DrawTextLeftAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) -{ - va_list args; - va_start(args, format); - - SDrawTextInfo ti; - ti.flags = eDrawText_FixedSize | eDrawText_2D | eDrawText_Monospace; - ti.color[0] = color[0]; - ti.color[1] = color[1]; - ti.color[2] = color[2]; - ti.color[3] = color[3]; - ti.xscale = ti.yscale = scale; - GetRenderer()->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args); - - va_end(args); -} - -void C3DEngine::DrawTextRightAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) -{ - va_list args; - va_start(args, format); - - SDrawTextInfo ti; - ti.flags = eDrawText_FixedSize | eDrawText_Right | eDrawText_2D | eDrawText_Monospace; - ti.color[0] = color[0]; - ti.color[1] = color[1]; - ti.color[2] = color[2]; - ti.color[3] = color[3]; - ti.xscale = ti.yscale = scale; - GetRenderer()->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args); - - va_end(args); -} - -int __cdecl C3DEngine__Cmp_FPS(const void* v1, const void* v2) -{ - float f1 = *(float*)v1; - float f2 = *(float*)v2; - - if (f1 > f2) - { - return 1; - } - else if (f1 < f2) - { - return -1; - } - - return 0; -} - -inline void Blend(float& Stat, float StatCur, float fBlendCur) -{ - Stat = Stat * (1.f - fBlendCur) + StatCur * fBlendCur; -} - -inline void Blend(float& Stat, int& StatCur, float fBlendCur) -{ - Blend(Stat, float(StatCur), fBlendCur); - StatCur = int_round(Stat); -} - -#ifdef ENABLE_LW_PROFILERS -static void AppendString(char*& szEnd, const char* szToAppend) -{ - assert(szToAppend); - - while (*szToAppend) - { - *szEnd++ = *szToAppend++; - } - - *szEnd++ = ' '; - *szEnd = 0; -} -#endif - -void C3DEngine::DisplayInfo([[maybe_unused]] float& fTextPosX, [[maybe_unused]] float& fTextPosY, [[maybe_unused]] float& fTextStepY, [[maybe_unused]] const bool bEnhanced) -{ -#ifdef ENABLE_LW_PROFILERS - // FUNCTION_PROFILER_3DENGINE; causes 0 fps in stats - static ICVar* pDisplayInfo = GetConsole()->GetCVar("r_DisplayInfo"); - assert(pDisplayInfo); - if (pDisplayInfo && pDisplayInfo->GetIVal() == 0) - { - return; - } - - if (gEnv->IsDedicated()) - { - return; - } - -#if defined(INFO_FRAME_COUNTER) - static int frameCounter = 0; -#endif - GetRenderer()->SetState(GS_NODEPTHTEST); - - fTextPosY = -10; - fTextStepY = 13; - fTextPosX = (float)GetRenderer()->GetOverlayWidth() - 5.0f; - - const char* description = GetRenderer()->GetRenderDescription(); - if (description && description[0] != 0) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.5f, ColorF(1.0f, 1.0f, 0.5f, 1.0f), - "%s", description); - } - - // If stat averaging is on, compute blend amount for current stats. - float fFPS = GetTimer()->GetFrameRate(); - - // Limit the FPS history for a single level to ~1 hour. - // This vector is cleared on each level load, but during a soak test this continues to grow every frame - const AZStd::size_t maxFPSEntries = 60 * 60 * 60; // 60ms * 60s * 60min - if (arrFPSforSaveLevelStats.size() < maxFPSEntries) - { - arrFPSforSaveLevelStats.push_back(SATURATEB((int)fFPS)); - } - - float fBlendTime = GetTimer()->GetCurrTime(); - int iBlendMode = 0; - float fBlendCur = GetTimer()->GetProfileFrameBlending(&fBlendTime, &iBlendMode); - - if (pDisplayInfo && pDisplayInfo->GetIVal() == 3) - { - static float fCurrentFPS, fCurrentFrameTime; - Blend(fCurrentFPS, fFPS, fBlendCur); - Blend(fCurrentFrameTime, GetTimer()->GetRealFrameTime() * 1000.0f, fBlendCur); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.5f, ColorF(1.0f, 1.0f, 0.5f, 1.0f), - "FPS %.1f - %.1fms", fCurrentFPS, fCurrentFrameTime); - return; - } - - // make level name - char szLevelName[128]; - - *szLevelName = 0; - { - int ii; - for (ii = strlen(m_szLevelFolder) - 2; ii > 0; ii--) - { - if (m_szLevelFolder[ii] == '\\' || m_szLevelFolder[ii] == '/') - { - break; - } - } - - if (ii >= 0) - { - cry_strcpy(szLevelName, &m_szLevelFolder[ii + 1]); - - for (int i = strlen(szLevelName) - 1; i > 0; i--) - { - if (szLevelName[i] == '\\' || szLevelName[i] == '/') - { - szLevelName[i] = 0; - } - } - } - } - - Matrix33 m = Matrix33(GetRenderingCamera().GetMatrix()); - //m.OrthonormalizeFast(); // why is that needed? is it? - Ang3 aAng = RAD2DEG(Ang3::GetAnglesXYZ(m)); - Vec3 vPos = GetRenderingCamera().GetPosition(); - - // Time of day info - int hours = 0; - int minutes = 0; - ITimeOfDay* timeOfDay = GetTimeOfDay(); - if (timeOfDay) - { - float time = timeOfDay->GetTime(); - hours = (int)time; - minutes = (int)((time - hours) * 60); - } - - // display out of memory message if an allocation failed - IF (gEnv->bIsOutOfMemory, 0) - { - ColorF fColor(1.0f, 0.0f, 0.0f, 1.0f); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 4.0f, fColor, "**** Out of Memory ****"); - fTextPosY += 40.0f; - } - // display out of memory message if an allocation failed - IF (gEnv->bIsOutOfVideoMemory, 0) - { - ColorF fColor(1.0f, 0.0f, 0.0f, 1.0f); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 4.0f, fColor, "**** Out of Video Memory ****"); - fTextPosY += 40.0f; - } - - float fogCullDist = 0.0f; - Vec2 vViewportScale = Vec2(0.0f, 0.0f); - m_pRenderer->EF_Query(EFQ_GetFogCullDistance, fogCullDist); - m_pRenderer->EF_Query(EFQ_GetViewportDownscaleFactor, vViewportScale); - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "CamPos=%.2f %.2f %.2f Angl=%3d %2d %3d ZN=%.2f ZF=%d", - vPos.x, vPos.y, vPos.z, (int)aAng.x, (int)aAng.y, (int)aAng.z, - GetRenderingCamera().GetNearPlane(), (int)GetRenderingCamera().GetFarPlane()); - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "Cam FC=%.2f VS=%.2f,%.2f Zoom=%.2f Speed=%1.2f TimeOfDay=%02d:%02d", - fogCullDist, vViewportScale.x, vViewportScale.y, - GetZoomFactor(), GetAverageCameraSpeed(), hours, minutes); - - // get version - const SFileVersion& ver = GetSystem()->GetFileVersion(); - //char sVersion[128]; - //ver.ToString(sVersion); - - // Get memory usage. - static IMemoryManager::SProcessMemInfo processMemInfo; - { - static int nGetMemInfoCount = 0; - if ((nGetMemInfoCount & 0x1F) == 0 && GetISystem()->GetIMemoryManager()) - { - // Only get mem stats every 32 frames. - GetISystem()->GetIMemoryManager()->GetProcessMemInfo(processMemInfo); - } - nGetMemInfoCount++; - } - - bool bMultiGPU; - m_pRenderer->EF_Query(EFQ_MultiGPUEnabled, bMultiGPU); - - const char* pRenderType(0); - - if (AZ::Interface::Get()) - { - pRenderType = "DX11"; - } - else - { - switch (gEnv->pRenderer->GetRenderType()) - { - case eRT_OpenGL: - pRenderType = "GL"; - break; - case eRT_DX11: - pRenderType = "DX11"; - break; - case eRT_DX12: - pRenderType = "DX12"; - break; - case eRT_Jasper: - pRenderType = "Jasper"; - break; - case eRT_Provo: - pRenderType = "Provo"; - break; - case eRT_Metal: - pRenderType = "Metal"; - break; - case eRT_Null: - pRenderType = "Null"; - break; - case eRT_Undefined: - default: - assert(0); - pRenderType = "Undefined"; - break; - } - } - assert(gEnv->pSystem); - bool bTextureStreamingEnabled = false; - m_pRenderer->EF_Query(EFQ_TextureStreamingEnabled, bTextureStreamingEnabled); - const bool bCGFStreaming = GetCVars()->e_StreamCgf && m_pObjManager; - const bool bTexStreaming = gEnv->pSystem->GetStreamEngine() && bTextureStreamingEnabled; - char szFlags[128], * szFlagsEnd = szFlags; - -#ifndef _RELEASE - ESystemConfigSpec spec = GetISystem()->GetConfigSpec(); - switch (spec) - { - case CONFIG_AUTO_SPEC: - AppendString(szFlagsEnd, "Auto"); - break; - case CONFIG_LOW_SPEC: - AppendString(szFlagsEnd, "LowSpec"); - break; - case CONFIG_MEDIUM_SPEC: - AppendString(szFlagsEnd, "MedSpec"); - break; - case CONFIG_HIGH_SPEC: - AppendString(szFlagsEnd, "HighSpec"); - break; - case CONFIG_VERYHIGH_SPEC: - AppendString(szFlagsEnd, "VeryHighSpec"); - break; - default: - assert(0); - } -#endif -#ifndef CONSOLE_CONST_CVAR_MODE - static ICVar* pMultiThreaded = GetConsole()->GetCVar("r_MultiThreaded"); - if (pMultiThreaded && pMultiThreaded->GetIVal() > 0) -#endif - AppendString(szFlagsEnd, "MT"); - - char* sAAMode = NULL; - m_pRenderer->EF_Query(EFQ_AAMode, sAAMode); - AppendString(szFlagsEnd, sAAMode); - - if (IsAreaActivationInUse()) - { - AppendString(szFlagsEnd, "LA"); - } - - if (bMultiGPU) - { - AppendString(szFlagsEnd, "MGPU"); - } - - if (gEnv->pSystem->IsDevMode()) - { - AppendString(szFlagsEnd, gEnv->IsEditor() ? "DevMode (Editor)" : "DevMode"); - } - - if (bCGFStreaming || bTexStreaming) - { - if (bCGFStreaming && !bTexStreaming) - { - AppendString(szFlagsEnd, "StG"); - } - if (bTexStreaming && !bCGFStreaming) - { - AppendString(szFlagsEnd, "StT"); - } - if (bTexStreaming && bCGFStreaming) - { - AppendString(szFlagsEnd, "StGT"); - } - } - - // remove last space - if (szFlags != szFlagsEnd) - { - *(szFlagsEnd - 1) = 0; - } -#ifdef _RELEASE - const char* mode = "Release"; -#else - const char* mode = "Profile"; -#endif - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "%s %s %dbit %s %s [%d.%d]", - pRenderType, mode, (int)sizeof(char*) * 8, szFlags, szLevelName, ver.v[1], ver.v[0]); - - // Polys in scene - int nPolygons, nShadowPolygons; - GetRenderer()->GetPolyCount(nPolygons, nShadowPolygons); - int nDrawCalls, nShadowGenDrawCalls; - GetRenderer()->GetCurrentNumberOfDrawCalls(nDrawCalls, nShadowGenDrawCalls); - - int nGeomInstances = GetRenderer()->GetNumGeomInstances(); - int nGeomInstanceDrawCalls = GetRenderer()->GetNumGeomInstanceDrawCalls(); - - if (fBlendCur != 1.f) - { - // Smooth over time. - static float fPolygons, fShadowVolPolys, fDrawCalls, fShadowGenDrawCalls, fGeomInstances, fGeomInstanceDrawCalls; - Blend(fPolygons, nPolygons, fBlendCur); - Blend(fShadowVolPolys, nShadowPolygons, fBlendCur); - Blend(fDrawCalls, nDrawCalls, fBlendCur); - Blend(fShadowGenDrawCalls, nShadowGenDrawCalls, fBlendCur); - Blend(fGeomInstances, nGeomInstances, fBlendCur); - Blend(fGeomInstanceDrawCalls, nGeomInstanceDrawCalls, fBlendCur); - } - - // - static float m_lastAverageDPTime = -FLT_MAX; - float curTime = gEnv->pTimer->GetAsyncCurTime(); - static int lastDrawCalls = 0; - static int lastShadowGenDrawCalls = 0; - static int avgPolys = 0; - static int avgShadowPolys = 0; - static int sumPolys = 0; - static int sumShadowPolys = 0; - static int nPolysFrames = 0; - if (curTime < m_lastAverageDPTime) - { - m_lastAverageDPTime = curTime; - } - if (curTime - m_lastAverageDPTime > 1.0f) - { - lastDrawCalls = nDrawCalls; - lastShadowGenDrawCalls = nShadowGenDrawCalls; - m_lastAverageDPTime = curTime; - avgPolys = nPolysFrames ? sumPolys / nPolysFrames : 0; - avgShadowPolys = nPolysFrames ? sumShadowPolys / nPolysFrames : 0; - sumPolys = nPolygons; - sumShadowPolys = nShadowPolygons; - nPolysFrames = 1; - } - else - { - nPolysFrames++; - sumPolys += nPolygons; - sumShadowPolys += nShadowPolygons; - } - // - - int nMaxDrawCalls = GetCVars()->e_MaxDrawCalls <= 0 ? 2000 : GetCVars()->e_MaxDrawCalls; - bool bInRed = (nDrawCalls + nShadowGenDrawCalls) > nMaxDrawCalls; - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, bInRed ? Col_Red : Col_White, "DP: %04d (%04d) ShadowGen:%04d (%04d) - Total: %04d Instanced: %04d", - nDrawCalls, lastDrawCalls, nShadowGenDrawCalls, lastShadowGenDrawCalls, nDrawCalls + nShadowGenDrawCalls, nDrawCalls + nShadowGenDrawCalls - nGeomInstances + nGeomInstanceDrawCalls); -#if defined(MOBILE) - bInRed = nPolygons > 500000; -#else - bInRed = nPolygons > 1500000; -#endif - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, bInRed ? Col_Red : Col_White, "Polys: %03d,%03d (%03d,%03d) Shadow:%03d,%03d (%03d,%03d)", - nPolygons / 1000, nPolygons % 1000, avgPolys / 1000, avgPolys % 1000, - nShadowPolygons / 1000, nShadowPolygons % 1000, avgShadowPolys / 1000, avgShadowPolys % 1000); - - { - SShaderCacheStatistics stats; - m_pRenderer->EF_Query(EFQ_GetShaderCacheInfo, stats); - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_White, "ShaderCache: %d GCM | %d Async Reqs | Compile: %s", - (int)stats.m_nGlobalShaderCacheMisses, (int)stats.m_nNumShaderAsyncCompiles, stats.m_bShaderCompileActive ? "On" : "Off"); - } - } - - // print stats about CGF's streaming - if (bCGFStreaming) - { - static char szCGFStreaming[256] = ""; - static SObjectsStreamingStatus objectsStreamingStatus = {0}; - - if (!(GetRenderer()->GetFrameID(false) & 15) || !szCGFStreaming[0] || GetCVars()->e_StreamCgfDebug) - { - m_pObjManager->GetObjectsStreamingStatus(objectsStreamingStatus); - sprintf_s(szCGFStreaming, 256, "CgfStrm: Loaded:%d InProg:%d All:%d Act:%d PcP:%d MemUsed:%2.2f MemReq:%2.2f Pool:%d", - objectsStreamingStatus.nReady, objectsStreamingStatus.nInProgress, objectsStreamingStatus.nTotal, objectsStreamingStatus.nActive, - (int)m_pObjManager->GetStreamPreCachePointDefs().size(), - float(objectsStreamingStatus.nAllocatedBytes) / 1024 / 1024, float(objectsStreamingStatus.nMemRequired) / 1024 / 1024, GetCVars()->e_StreamCgfPoolSize); - } - - bool bOutOfMem((float(objectsStreamingStatus.nMemRequired) / 1024 / 1024) > GetCVars()->e_StreamCgfPoolSize); - bool bCloseToOutOfMem((float(objectsStreamingStatus.nMemRequired) / 1024 / 1024) > GetCVars()->e_StreamCgfPoolSize * 90 / 100); - - ColorF color = Col_White; - if (bOutOfMem) - { - color = Col_Red; - } - else if (bCloseToOutOfMem) - { - color = Col_Orange; - } - // if(bTooManyRequests) - // color = Col_Magenta; - - if ((pDisplayInfo->GetIVal() == 2 || GetCVars()->e_StreamCgfDebug) || bOutOfMem || bCloseToOutOfMem) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, color, szCGFStreaming); - } - } - - // print stats about textures' streaming - if (bTexStreaming) - { - static char szTexStreaming[256] = ""; - static bool bCloseToOutOfMem = false; - static bool bOutOfMem = false; - static bool bTooManyRequests = false; - static bool bOverloadedPool = false; - static uint32 nTexCount = 0; - static uint32 nTexSize = 0; - - float fTexBandwidthRequired = 0.f; - m_pRenderer->GetBandwidthStats(&fTexBandwidthRequired); - - if (!(GetRenderer()->GetFrameID(false) % 30) || !szTexStreaming[0]) - { - STextureStreamingStats stats(!(GetRenderer()->GetFrameID(false) % 120)); - m_pRenderer->EF_Query(EFQ_GetTexStreamingInfo, stats); - - if (!(GetRenderer()->GetFrameID(false) % 120)) - { - bOverloadedPool = stats.bPoolOverflowTotally; - nTexCount = stats.nRequiredStreamedTexturesCount; - nTexSize = stats.nRequiredStreamedTexturesSize; - } - - int nPlatformSize = nTexSize; - - const int iPercentage = int((float)stats.nCurrentPoolSize / stats.nMaxPoolSize * 100.f); - const int iStaticPercentage = int((float)stats.nStaticTexturesSize / stats.nMaxPoolSize * 100.f); - sprintf_s(szTexStreaming, "TexStrm: TexRend: %u NumTex: %u Req:%.1fMB Mem(strm/stat/tot):%.1f/%.1f/%.1fMB(%d%%/%d%%) PoolSize:%" PRISIZE_T "MB PoolFrag:%.1f%%", - stats.nNumTexturesPerFrame, nTexCount, (float)nPlatformSize / 1024 / 1024, - (float)stats.nStreamedTexturesSize / 1024 / 1024, (float)stats.nStaticTexturesSize / 1024 / 1024, (float)stats.nCurrentPoolSize / 1024 / 1024, - iPercentage, iStaticPercentage, stats.nMaxPoolSize / 1024 / 1024, - stats.fPoolFragmentation * 100.0f - ); - bOverloadedPool |= stats.bPoolOverflowTotally; - - bCloseToOutOfMem = iPercentage >= 90; - bOutOfMem = stats.bPoolOverflow; - } - - if (pDisplayInfo->GetIVal() == 2 || bCloseToOutOfMem || bTooManyRequests || bOverloadedPool) - { - ColorF color = Col_White; - if (bOutOfMem) - { - color = Col_Red; - } - else if (bCloseToOutOfMem) - { - color = Col_Orange; - } - if (bTooManyRequests) - { - color = Col_Magenta; - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, color, "%s", szTexStreaming); - } - - if (pDisplayInfo->GetIVal() > 0 && bOverloadedPool) - { - DrawTextLeftAligned(0, 10, 2.3f, Col_Red, "Texture pool totally overloaded!"); - } - } - - - - { - static char szMeshPoolUse[256] = ""; - static unsigned nFlushFrameId = 0U; - static unsigned nFallbackFrameId = 0U; - static SMeshPoolStatistics lastStats; - static SMeshPoolStatistics stats; - - const unsigned nMainFrameId = GetRenderer()->GetFrameID(false); - m_pRenderer->EF_Query(EFQ_GetMeshPoolInfo, stats); - const int iPercentage = int((float)stats.nPoolInUse / (stats.nPoolSize ? stats.nPoolSize : 1U) * 100.f); - const int iVolatilePercentage = int((float)stats.nInstancePoolInUse / (stats.nInstancePoolSize ? stats.nInstancePoolSize : 1U) * 100.f); - nFallbackFrameId = lastStats.nFallbacks < stats.nFallbacks ? nMainFrameId : nFallbackFrameId; - nFlushFrameId = lastStats.nFlushes < stats.nFlushes ? nMainFrameId : nFlushFrameId; - const bool bOverflow = nMainFrameId - nFlushFrameId < 50; - const bool bFallback = nMainFrameId - nFallbackFrameId < 50; - - sprintf_s(szMeshPoolUse, - "Mesh Pool: MemUsed:%.2fKB(%d%%%%) Peak %.fKB PoolSize:%" PRISIZE_T "KB Flushes %" PRISIZE_T " Fallbacks %.3fKB %s", - (float)stats.nPoolInUse / 1024, - iPercentage, - (float)stats.nPoolInUsePeak / 1024, - stats.nPoolSize / 1024, - stats.nFlushes, - (float)stats.nFallbacks / 1024.0f, - (bFallback ? "FULL!" : bOverflow ? "OVERFLOW" : "")); - - if (stats.nPoolSize && (pDisplayInfo->GetIVal() == 2 || bOverflow || bFallback)) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, - bFallback ? Col_Red : bOverflow ? Col_Orange : Col_White, - szMeshPoolUse); - } - if (stats.nPoolSize && pDisplayInfo->GetIVal() == 2) - { - char szVolatilePoolsUse[256]; - sprintf_s(szVolatilePoolsUse, - "Mesh Instance Pool: MemUsed:%.2fKB(%d%%%%) Peak %.fKB PoolSize:%" PRISIZE_T "KB Fallbacks %.3fKB", - (float)stats.nInstancePoolInUse / 1024, - iVolatilePercentage, - (float)stats.nInstancePoolInUsePeak / 1024, - stats.nInstancePoolSize / 1024, - (float)stats.nInstanceFallbacks / 1024.0f); - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, - Col_White, szVolatilePoolsUse); - } - - memcpy(&lastStats, &stats, sizeof(lastStats)); - } - - // streaming info - { - IStreamEngine* pSE = gEnv->pSystem->GetStreamEngine(); - if (pSE) - { - SStreamEngineStatistics& stats = pSE->GetStreamingStatistics(); - SStreamEngineOpenStats openStats; - pSE->GetStreamingOpenStatistics(openStats); - - static char szStreaming[128] = ""; - if (!(GetRenderer()->GetFrameID(false) & 7)) - { - if (pDisplayInfo->GetIVal() == 2) - { - sprintf_s(szStreaming, "Streaming IO: ACT: %3dmsec, Jobs:%2d Total:%5d", - (uint32)stats.fAverageCompletionTime, openStats.nOpenRequestCount, stats.nTotalStreamingRequestCount); - } - else - { - sprintf_s(szStreaming, "Streaming IO: ACT: %3dmsec, Jobs:%2d", - (uint32)stats.fAverageCompletionTime, openStats.nOpenRequestCount); - } - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, szStreaming); - - if (stats.bTempMemOutOfBudget) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.3f, Col_Red, "Temporary Streaming Memory Pool Out of Budget!"); - } - } - - if (pDisplayInfo && pDisplayInfo->GetIVal() == 2) // more streaming info - { - SStreamEngineStatistics& stats = gEnv->pSystem->GetStreamEngine()->GetStreamingStatistics(); - - { // HDD stats - static char szStreaming[512] = ""; - sprintf_s(szStreaming, "HDD: BW:%1.2f|%1.2fMb/s (Eff:%2.1f|%2.1fMb/s) - Seek:%1.2fGB - Active:%2.1f%%%%", - (float)stats.hddInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.hddInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nAverageActualReadBandwidth / (1024 * 1024), - (float)stats.hddInfo.nAverageSeekOffset / (1024 * 1024), stats.hddInfo.fAverageActiveTime); - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, szStreaming); - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Display Info about dynamic lights. - ////////////////////////////////////////////////////////////////////////// - { - { -#ifndef _RELEASE - // Checkpoint loading information - if (!gEnv->bMultiplayer) - { - ISystem::ICheckpointData data; - gEnv->pSystem->GetCheckpointData(data); - - if (data.m_loadOrigin != ISystem::eLLO_Unknown) - { - static const char* loadStates[] = - { - "", - "New Level", - "Level to Level", - "Resumed Game", - "Map Command", - }; - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.3f, Col_White, "%s, Checkpoint loads: %i", loadStates[(int)data.m_loadOrigin], (int)data.m_totalLoads); - } - } -#endif - - int nPeakMemMB = (int)(processMemInfo.PeakPagefileUsage >> 20); - int nVirtMemMB = (int)(processMemInfo.PagefileUsage >> 20); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "Mem=%d Peak=%d DLights=(%d)", nVirtMemMB, nPeakMemMB, m_nRealLightsNum + m_nDeferredLightsNum); - - uint32 nShadowFrustums = 0; - uint32 nShadowAllocs = 0; - uint32 nShadowMaskChannels = 0; - m_pRenderer->EF_Query(EFQ_GetShadowPoolFrustumsNum, nShadowFrustums); - m_pRenderer->EF_Query(EFQ_GetShadowPoolAllocThisFrameNum, nShadowAllocs); - m_pRenderer->EF_Query(EFQ_GetShadowMaskChannelsNum, nShadowMaskChannels); - bool bThrash = (nShadowAllocs & 0x80000000) ? true : false; - nShadowAllocs &= ~0x80000000; - uint32 nAvailableShadowMaskChannels = nShadowMaskChannels >> 16; - uint32 nUsedShadowMaskChannels = nShadowMaskChannels & 0xFFFF; - bool bTooManyLights = nUsedShadowMaskChannels > nAvailableShadowMaskChannels ? true : false; - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, (nShadowFrustums || nShadowAllocs) ? Col_Yellow : Col_White, "%d Shadow Mask Channels, %3d Shadow Frustums, %3d Frustum Renders This Frame", - nUsedShadowMaskChannels, nShadowFrustums, nShadowAllocs); - - if (bThrash) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Red, "SHADOW POOL THRASHING!!!"); - } - - if (bTooManyLights) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Red, "TOO MANY SHADOW CASTING LIGHTS (%d/%d)!!!", nUsedShadowMaskChannels, nAvailableShadowMaskChannels); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Red, "Consider increasing 'r_ShadowCastingLightsMaxCount'"); - } - -#ifndef _RELEASE - uint32 numTiledShadingSkippedLights; - m_pRenderer->EF_Query(EFQ_GetTiledShadingSkippedLightsNum, numTiledShadingSkippedLights); - if (numTiledShadingSkippedLights > 0) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, Col_Red, "TILED SHADING: SKIPPED %d LIGHTS", numTiledShadingSkippedLights); - } - - if (GetCVars()->e_levelStartupFrameNum) - { - static float startupAvgFPS = 0.f; - static float levelStartupTime = 0; - static int levelStartupFrameEnd = GetCVars()->e_levelStartupFrameNum + GetCVars()->e_levelStartupFrameDelay; - int curFrameID = GetRenderer()->GetFrameID(false); - - if (curFrameID >= GetCVars()->e_levelStartupFrameDelay) - { - if (curFrameID == GetCVars()->e_levelStartupFrameDelay) - { - levelStartupTime = gEnv->pTimer->GetAsyncCurTime(); - } - if (curFrameID == levelStartupFrameEnd) - { - startupAvgFPS = (float)GetCVars()->e_levelStartupFrameNum / (gEnv->pTimer->GetAsyncCurTime() - levelStartupTime); - } - if (curFrameID >= levelStartupFrameEnd) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 2.f, Col_Red, "Startup AVG FPS: %.2f", startupAvgFPS); - fTextPosY += fTextStepY; - } - } - } -#endif //_RELEASE - } - - m_nDeferredLightsNum = 0; - } - - assert(pDisplayInfo); - if (bEnhanced) - { -#define CONVX(x) (((x) / (float)gUpdateTimesNum)) -#define CONVY(y) (1.f - ((y) / 720.f)) -#define TICKS_TO_MS(t) (1000.f * gEnv->pTimer->TicksToSeconds(t)) -# define MAX_PHYS_TIME 32.f -# define MAX_PLE_TIME 4.f - uint32 gUpdateTimeIdx = 0, gUpdateTimesNum = 0; - const sUpdateTimes* gUpdateTimes = gEnv->pSystem->GetUpdateTimeStats(gUpdateTimeIdx, gUpdateTimesNum); - if (pDisplayInfo->GetIVal() >= 5) - { - const SAuxGeomRenderFlags flags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags(); - SAuxGeomRenderFlags newFlags(flags); - newFlags.SetAlphaBlendMode(e_AlphaNone); - newFlags.SetMode2D3DFlag(e_Mode2D); - newFlags.SetCullMode(e_CullModeNone); - newFlags.SetDepthWriteFlag(e_DepthWriteOff); - newFlags.SetDepthTestFlag(e_DepthTestOff); - newFlags.SetFillMode(e_FillModeSolid); - gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newFlags); - const ColorF colorPhysFull = Col_Blue; - const ColorF colorSysFull = Col_Green; - const ColorF colorRenFull = Col_Red; - const ColorF colorPhysHalf = colorPhysFull * 0.15f; - const ColorF colorSysHalf = colorSysFull * 0.15f; - const ColorF colorRenHalf = colorRenFull * 0.15f; - float phys = (TICKS_TO_MS(gUpdateTimes[0].PhysStepTime) / 66.f) * 720.f; - float sys = (TICKS_TO_MS(gUpdateTimes[0].SysUpdateTime) / 66.f) * 720.f; - float ren = (TICKS_TO_MS(gUpdateTimes[0].RenderTime) / 66.f) * 720.f; - float _lerp = ((float)(max((int)gUpdateTimeIdx - (int)0, 0) / (float)gUpdateTimesNum)); - ColorB colorPhysLast; - colorPhysLast.lerpFloat(colorPhysFull, colorPhysHalf, _lerp); - ColorB colorSysLast; - colorSysLast.lerpFloat(colorSysFull, colorSysHalf, _lerp); - ColorB colorRenLast; - colorRenLast.lerpFloat(colorRenFull, colorRenHalf, _lerp); - Vec3 lastPhys(CONVX(0), CONVY(phys), 1.f); - Vec3 lastSys(CONVX(0), CONVY(sys), 1.f); - Vec3 lastRen(CONVX(0), CONVY(ren), 1.f); - for (uint32 i = 0; i < gUpdateTimesNum; ++i) - { - const float x = (float)i; - _lerp = ((float)(max((int)gUpdateTimeIdx - (int)i, 0) / (float)gUpdateTimesNum)); - const sUpdateTimes& sample = gUpdateTimes[i]; - phys = (TICKS_TO_MS(sample.PhysStepTime) / 66.f) * 720.f; - sys = (TICKS_TO_MS(sample.SysUpdateTime) / 66.f) * 720.f; - ren = (TICKS_TO_MS(sample.RenderTime) / 66.f) * 720.f; - Vec3 curPhys(CONVX(x), CONVY(phys), 1.f); - Vec3 curSys(CONVX(x), CONVY(sys), 1.f); - Vec3 curRen(CONVX(x), CONVY(ren), 1.f); - ColorB colorPhys; - colorPhys.lerpFloat(colorPhysFull, colorPhysHalf, _lerp); - ColorB colorSys; - colorSys.lerpFloat(colorSysFull, colorSysHalf, _lerp); - ColorB colorRen; - colorRen.lerpFloat(colorRenFull, colorRenHalf, _lerp); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(lastPhys, colorPhysLast, curPhys, colorPhys); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(lastSys, colorSysLast, curSys, colorSys); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(lastRen, colorRenLast, curRen, colorRen); - lastPhys = curPhys; - colorPhysLast = colorPhys; - lastSys = curSys; - colorSysLast = colorSys; - lastRen = curRen; - colorRenLast = colorRen; - } - gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(flags); - } - const float curPhysTime = TICKS_TO_MS(gUpdateTimes[gUpdateTimeIdx].PhysStepTime); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE_SMALL, curPhysTime > MAX_PHYS_TIME ? Col_Red : Col_White, "%3.1f ms Phys", curPhysTime); - const float curPhysWaitTime = TICKS_TO_MS(gUpdateTimes[gUpdateTimeIdx].physWaitTime); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE_SMALL, curPhysTime > MAX_PHYS_TIME ? Col_Red : Col_White, "%3.1f ms WaitPhys", curPhysWaitTime); - - float partTicks = 0; - - //3dengine stats from RenderWorld - { -#if defined(MOBILE) - const float maxVal = 12.f; -#else - const float maxVal = 50.f; -#endif - float fTimeMS = TICKS_TO_MS(m_nRenderWorldUSecs) - partTicks; - DrawTextRightAligned(fTextPosX, fTextPosY += (fTextStepY - STEP_SMALL_DIFF), DISPLAY_INFO_SCALE_SMALL, fTimeMS > maxVal ? Col_Red : Col_White, "%.2f ms RendWorld", fTimeMS); - } - - { - SStreamEngineStatistics stat = gEnv->pSystem->GetStreamEngine()->GetStreamingStatistics(); - - float fTimeMS = 1000.0f * gEnv->pTimer->TicksToSeconds(stat.nMainStreamingThreadWait); - DrawTextRightAligned(fTextPosX, fTextPosY += (fTextStepY - STEP_SMALL_DIFF), - DISPLAY_INFO_SCALE_SMALL, Col_White, "%3.1f ms StreamFin", fTimeMS); - } - } - -#undef MAX_PHYS_TIME -#undef TICKS_TO_MS -#undef CONVY -#undef CONVX - - ////////////////////////////////////////////////////////////////////////// - // Display Thermal information of the device (if supported) - ////////////////////////////////////////////////////////////////////////// - - if (ThermalInfoRequestsBus::GetTotalNumOfEventHandlers()) - { - const int thermalSensorCount = static_cast(ThermalSensorType::Count); - const char* sensorStrings[thermalSensorCount] = { "CPU", "GPU", "Battery" }; - for (int i = 0; i < thermalSensorCount; ++i) - { - float temperature = 0.f; - ThermalSensorType sensor = static_cast(i); - EBUS_EVENT_RESULT(temperature, ThermalInfoRequestsBus, GetSensorTemp, sensor); - AZStd::string tempText; - ColorF tempColor; - if (temperature > 0.f) - { - float overheatingTemp = 0.f; - EBUS_EVENT_RESULT(overheatingTemp, ThermalInfoRequestsBus, GetSensorOverheatingTemp, sensor); - tempText = AZStd::string::format(" %.1f C", temperature); - tempColor = temperature >= overheatingTemp ? Col_Red : Col_White; - } - else - { - tempText = "N/A"; - tempColor = Col_White; - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE, tempColor, "%s Temp %s", sensorStrings[i], tempText.c_str()); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Display Current fps - ////////////////////////////////////////////////////////////////////////// - - if (iBlendMode) - { - // Track FPS frequency, report min/max. - Blend(m_fAverageFPS, fFPS, fBlendCur); - - Blend(m_fMinFPSDecay, fFPS, fBlendCur); - if (fFPS <= m_fMinFPSDecay) - { - m_fMinFPS = m_fMinFPSDecay = fFPS; - } - - Blend(m_fMaxFPSDecay, fFPS, fBlendCur); - if (fFPS >= m_fMaxFPSDecay) - { - m_fMaxFPS = m_fMaxFPSDecay = fFPS; - } - - const char* sMode = ""; - switch (iBlendMode) - { - case 1: - sMode = "frame avg"; - break; - case 2: - sMode = "time avg"; - break; - case 3: - sMode = "peak hold"; - break; - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.5f, ColorF(1.0f, 1.0f, 0.5f, 1.0f), - "FPS %.1f [%.0f..%.0f], %s over %.1f s", - m_fAverageFPS, m_fMinFPS, m_fMaxFPS, sMode, fBlendTime); - } - else - { - const int nHistorySize = 16; - static float arrfFrameRateHistory[nHistorySize] = {0}; - - static int nFrameId = 0; - nFrameId++; - int nSlotId = nFrameId % nHistorySize; - assert(nSlotId >= 0 && nSlotId < nHistorySize); - arrfFrameRateHistory[nSlotId] = min(9999.f, GetTimer()->GetFrameRate()); - - float fMinFPS = 9999.0f; - float fMaxFPS = 0; - for (int i = 0; i < nHistorySize; i++) - { - if (arrfFrameRateHistory[i] < fMinFPS) - { - fMinFPS = arrfFrameRateHistory[i]; - } - if (arrfFrameRateHistory[i] > fMaxFPS) - { - fMaxFPS = arrfFrameRateHistory[i]; - } - } - - float fFrameRate = 0; - float fValidFrames = 0; - for (int i = 0; i < nHistorySize; i++) - { - int s = (nFrameId - i) % nHistorySize; - fFrameRate += arrfFrameRateHistory[s]; - fValidFrames++; - } - fFrameRate /= fValidFrames; - - m_fAverageFPS = fFrameRate; - m_fMinFPS = m_fMinFPSDecay = fMinFPS; - m_fMaxFPS = m_fMaxFPSDecay = fMaxFPS; - - - //only difference to r_DisplayInfo 1, need ms for GPU time - float fMax = (int(GetCurTimeSec() * 2) & 1) ? 999.f : 888.f; - if (bEnhanced) - { - /* DrawTextRightAligned( fTextPosX, fTextPosY+=fTextStepY, "%6.2f ~%6.2f ms (%6.2f..%6.2f) CPU", - GetTimer()->GetFrameTime()*1000.0f, 1000.0f/max(0.0001f,fFrameRate), - 1000.0f/max(0.0001f,fMinFPS), - 1000.0f/max(0.0001f,fMaxFPS)); - */ - const RPProfilerStats* pFrameRPPStats = GetRenderer()->GetRPPStats(eRPPSTATS_OverallFrame); - float gpuTime = pFrameRPPStats ? pFrameRPPStats->gpuTime : 0.0f; - static float sGPUTime = 0.f; - if (gpuTime < 1000.f && gpuTime > 0.01f) - { - sGPUTime = gpuTime; //catch sporadic jumps - } - if (sGPUTime > 0.01f) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, DISPLAY_INFO_SCALE_SMALL, (gpuTime >= 40.f) ? Col_Red : Col_White, "%3.1f ms GPU", sGPUTime); - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.4f, ColorF(1.0f, 1.0f, 0.2f, 1.0f), "FPS %5.1f (%3d..%3d)(%3.1f ms)", - min(fMax, fFrameRate), (int)min(fMax, fMinFPS), (int)min(fMax, fMaxFPS), GetTimer()->GetFrameTime() * 1000.0f); - } - else - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, 1.4f, ColorF(1.0f, 1.0f, 0.2f, 1.0f), "FPS %5.1f (%3d..%3d)", - min(fMax, fFrameRate), (int)min(fMax, fMinFPS), (int)min(fMax, fMaxFPS)); - } - } - -#ifndef _RELEASE - if (GetCVars()->e_GsmStats) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "--------------- GSM Stats ---------------"); - - if (m_pSun && m_pSun->m_pShadowMapInfo) - { - CLightEntity::ShadowMapInfo* pSMI = m_pSun->m_pShadowMapInfo; - int arrGSMCastersCount[MAX_GSM_LODS_NUM]; - memset(arrGSMCastersCount, 0, sizeof(arrGSMCastersCount)); - char szText[256] = "Objects count per shadow map: "; - for (int nLod = 0; nLod < Get3DEngine()->GetShadowsCascadeCount(NULL) && nLod < MAX_GSM_LODS_NUM; nLod++) - { - ShadowMapFrustum*& pLsource = pSMI->pGSM[nLod]; - if (nLod) - { - azstrcat(szText, AZ_ARRAY_SIZE(szText), ", "); - } - - char* pstr = szText + strlen(szText); - sprintf_s(pstr, sizeof(szText) - (pstr - szText), "%d", pLsource->m_castersList.Count()); - } - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, szText); - } - - for (int nSunInUse = 0; nSunInUse < 2; nSunInUse++) - { - if (nSunInUse) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "WithSun ListId FrNum UserNum"); - } - else - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "NoSun ListId FrNum UserNum"); - } - - // TODO: For Nick, check if needed anymore - //for(ShadowFrustumListsCache::iterator it = m_FrustumsCache[nSunInUse].begin(); it != m_FrustumsCache[nSunInUse].end(); ++it) - //{ - // int nListId = (int)it->first; - // PodArray * pList = it->second; - - // DrawTextRightAligned( fTextPosX, fTextPosY+=fTextStepY, - // "%8d %8d %8d", - // nListId, - // pList->Count(), m_FrustumsCacheUsers[nSunInUse][nListId]); - //} - } - } - - // objects counter - if (GetCVars()->e_ObjStats) - { -#define DRAW_OBJ_STATS(_var) DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "%s: %d", (#_var), GetInstCount(_var)) - - DRAW_OBJ_STATS(eERType_NotRenderNode); - DRAW_OBJ_STATS(eERType_Light); - DRAW_OBJ_STATS(eERType_Cloud); - DRAW_OBJ_STATS(eERType_FogVolume); - DRAW_OBJ_STATS(eERType_Decal); - DRAW_OBJ_STATS(eERType_WaterVolume); - DRAW_OBJ_STATS(eERType_DistanceCloud); - DRAW_OBJ_STATS(eERType_VolumeObject); - DRAW_OBJ_STATS(eERType_Rope); - DRAW_OBJ_STATS(eERType_PrismObject); - DRAW_OBJ_STATS(eERType_RenderComponent); - DRAW_OBJ_STATS(eERType_StaticMeshRenderComponent); - DRAW_OBJ_STATS(eERType_DynamicMeshRenderComponent); - DRAW_OBJ_STATS(eERType_SkinnedMeshRenderComponent); - DRAW_OBJ_STATS(eERType_GameEffect); - DRAW_OBJ_STATS(eERType_BreakableGlass); - - if (IsObjectTreeReady()) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "--- By list type: ---"); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, " Main: %d", m_pObjectsTree->GetObjectsCount(eMain)); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "Caster: %d", m_pObjectsTree->GetObjectsCount(eCasters)); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "LigAll: %d", m_lstStaticLights.Count()); - } - - int nFree = m_LTPRootFree.Count(); - int nUsed = m_LTPRootUsed.Count(); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "RNTmpData(Used+Free): %d + %d = %d (%d KB)", - nUsed, nFree, nUsed + nFree, (nUsed + nFree) * (int)sizeof(CRNTmpData) / 1024); - - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "COctreeNode::m_arrEmptyNodes.Count() = %d", COctreeNode::m_arrEmptyNodes.Count()); - } - - CCullBuffer* pCB = GetCoverageBuffer(); - if (pCB && GetCVars()->e_CoverageBuffer && GetCVars()->e_CoverageBufferDebug && pCB->TrisWritten()) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, - "CB: Write:%3d/%2d Test:%4d/%4d/%3d ZFarM:%.2f ZNearM:%.2f Res:%d OI:%s", - pCB->TrisWritten(), pCB->ObjectsWritten(), - pCB->TrisTested(), pCB->ObjectsTested(), pCB->ObjectsTestedAndRejected(), - pCB->GetZFarInMeters(), pCB->GetZNearInMeters(), pCB->SelRes(), - pCB->IsOutdooVisible() ? "Out" : "In"); - } - -#if defined(INFO_FRAME_COUNTER) - ++frameCounter; - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "Frame #%d", frameCounter); -#endif - - ITimeOfDay* pTimeOfDay = Get3DEngine()->GetTimeOfDay(); - if (GetCVars()->e_TimeOfDayDebug && pTimeOfDay) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "---------------------------------------"); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "------------ Time of Day -------------"); - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, " "); - - int nVarCount = pTimeOfDay->GetVariableCount(); - for (int v = 0; v < nVarCount; ++v) - { - ITimeOfDay::SVariableInfo pVar; - pTimeOfDay->GetVariableInfo(v, pVar); - - if (pVar.type == ITimeOfDay::TYPE_FLOAT) - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, " %s: %.9f", pVar.displayName, pVar.fValue[0]); - } - else - { - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, " %s: %.3f %.3f %.3f", pVar.displayName, pVar.fValue[0], pVar.fValue[1], pVar.fValue[2]); - } - } - DrawTextRightAligned(fTextPosX, fTextPosY += fTextStepY, "---------------------------------------"); - } - -#endif - // We only show memory usage in dev mode. - if (gEnv->pSystem->IsDevMode()) - { - if (GetCVars()->e_DisplayMemoryUsageIcon) - { - uint64 nAverageMemoryUsage(0); - uint64 nHighMemoryUsage(0); - uint64 nCurrentMemoryUsage(0); - const uint64 nMegabyte(1024 * 1024); - - // Copied from D3DDriver.cpp, function CD3D9Renderer::RT_EndFrame(). - int nIconSize = 16; - - nCurrentMemoryUsage = processMemInfo.TotalPhysicalMemory - processMemInfo.FreePhysicalMemory; - -#if defined(_WIN64) || defined(WIN64) || defined(MAC) || defined(LINUX64) - nAverageMemoryUsage = 3000; - nHighMemoryUsage = 6000; - // This is the same value as measured in the editor. - nCurrentMemoryUsage = processMemInfo.PagefileUsage / nMegabyte; -#elif defined(_WIN32) || defined(LINUX32) - nAverageMemoryUsage = 800; - nHighMemoryUsage = 1200; - // This is the same value as measured in the editor. - nCurrentMemoryUsage = processMemInfo.PagefileUsage / nMegabyte; -#endif //_WIN32 - - ITexture* pRenderTexture(m_ptexIconAverageMemoryUsage); - if (nCurrentMemoryUsage > nHighMemoryUsage) - { - pRenderTexture = m_ptexIconHighMemoryUsage; - } - else if (nCurrentMemoryUsage < nAverageMemoryUsage) - { - pRenderTexture = m_ptexIconLowMemoryUsage; - } - - if (pRenderTexture && gEnv->pRenderer) - { - float vpWidth = (float)gEnv->pRenderer->GetOverlayWidth(), vpHeight = (float)gEnv->pRenderer->GetOverlayHeight(); - float iconWidth = (float)nIconSize / vpWidth * 800.0f; - float iconHeight = (float)nIconSize / vpHeight * 600.0f; - gEnv->pRenderer->Push2dImage((fTextPosX / vpWidth) * 800.0f - iconWidth, ((fTextPosY += nIconSize + 3) / vpHeight) * 600.0f, - iconWidth, iconHeight, pRenderTexture->GetTextureID(), 0, 1.0f, 1.0f, 0); - } - } - } -#endif -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////// -static const float DISPLAY_MEMORY_ROW_MARGIN = 16.0f; -static const float DISPLAY_MEMORY_ROW_HEIGHT = 32.0f; -static const float DISPLAY_MEMORY_ROW_NUMBER_WIDTH = 128.0f; -static const float DISPLAY_MEMORY_ROW_FONT_SCALE = 1.5f; -static const float DISPLAY_MEMORY_COL_LABEL_FONT_SCALE = 1.0f; - -static inline void AdjustDisplayMemoryParameters(float& yPos, float& columnInset, float columnWidth, float screenHeight) -{ - int column = (int)(yPos + DISPLAY_MEMORY_ROW_HEIGHT) / (int)screenHeight; - columnInset += columnWidth * column; - yPos -= screenHeight * column; -} - -static void DisplayMemoryRow(C3DEngine& engine, float columnWidth, float screenHeight, float yPos, float valueA, float valueB, const char* valueBFormat, const ColorF& color, const char* categoryName, const char* subcategoryName = nullptr) -{ - float columnInset = columnWidth - DISPLAY_MEMORY_ROW_MARGIN; - AdjustDisplayMemoryParameters(yPos, columnInset, columnWidth, screenHeight); - if (valueA != -1.0f) - { - engine.DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, color, "%.1fMB", valueA); - } - if (valueB != -1.0f) - { - engine.DrawTextRightAligned(columnInset, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, color, valueBFormat, valueB); - } - - if (subcategoryName) - { - static const float MAIN_TEXT_SCALE = 1.5f; - static const float SUB_TEXT_SCALE = 1.0f; - static const float SUB_LINE_OFFSET_Y = 16.0f; - - engine.DrawTextLeftAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 4, yPos, MAIN_TEXT_SCALE, color, "%s", categoryName); - engine.DrawTextLeftAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 4, yPos + SUB_LINE_OFFSET_Y, SUB_TEXT_SCALE, color, "%s", subcategoryName); - } - else - { - engine.DrawTextLeftAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 4, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, color, "%s", categoryName); - } -} - -void C3DEngine::DisplayMemoryStatistics() -{ - const ColorF headerColor = ColorF(0.4f, 0.9f, 0.3f, 1.0f); - const ColorF statisticColor = ColorF(0.4f, 0.9f, 0.9f, 1.0f); - const ColorF subtotalColor = ColorF(0.4f, 0.3f, 0.9f, 1.0f); - const ColorF totalColor = ColorF(0.9f, 0.9f, 0.9f, 1.0f); - const ColorF labelColor = ColorF(0.4f, 0.3f, 0.3f, 1.0f); - - const float screenHeight = (float)m_pRenderer->GetHeight(); - - if (GetCVars()->e_MemoryProfiling == 1) - { - const float columnWidth = (float)(m_pRenderer->GetWidth() / 2); - float columnInset = columnWidth - DISPLAY_MEMORY_ROW_MARGIN; - - float memoryYPos = DISPLAY_MEMORY_ROW_HEIGHT; - float memoryYPosStepSize = DISPLAY_MEMORY_ROW_HEIGHT; - - // Add column labels and header - this->DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH, memoryYPos, DISPLAY_MEMORY_COL_LABEL_FONT_SCALE, labelColor, "Allocated"); - this->DrawTextRightAligned(columnInset, memoryYPos, DISPLAY_MEMORY_COL_LABEL_FONT_SCALE, labelColor, "No. Allocations"); - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, -1.0f, -1.0f, "%.1fMB", headerColor, "VRAM Usage"); - memoryYPos += (memoryYPosStepSize * 0.5f); - - float totalTrackedGPUAlloc = 0.0f; - - // Print the memory usage of each major VRAM category and each subcategory - for (int category = 0; category < Render::Debug::VRAM_CATEGORY_NUMBER_CATEGORIES; ++category) - { - float categorySubTotal = 0.0f; - AZStd::string categoryName; - - for (int subcategory = 0; subcategory < Render::Debug::VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES; ++subcategory) - { - AZStd::string subcategoryName; - size_t numberBytesAllocated = 0; - size_t numberAllocations = 0; - EBUS_EVENT(Render::Debug::VRAMDrillerBus, GetCurrentVRAMStats, static_cast(category), - static_cast(subcategory), categoryName, subcategoryName, numberBytesAllocated, numberAllocations); - - if (numberAllocations != 0) - { - float numMBallocated = numberBytesAllocated / (1024.0f * 1024.0f); - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, numMBallocated, (float)numberAllocations, "%.0f", statisticColor, categoryName.c_str(), subcategoryName.c_str()); - - memoryYPos += memoryYPosStepSize; - totalTrackedGPUAlloc += numMBallocated; - categorySubTotal += numMBallocated; - } - } - if (categorySubTotal > 0.0f) - { - float yPos = memoryYPos; - AdjustDisplayMemoryParameters(yPos, columnInset, columnWidth, screenHeight); - DrawTextLeftAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 4, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, subtotalColor, "%s Subtotal", categoryName.c_str()); - DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, subtotalColor, "%.1fMB", categorySubTotal); - memoryYPos += (memoryYPosStepSize * 0.5f); - } - } - - float allocatedVideoMemoryMB = -1.0f, reservedVideoMemoryMB = -1.0f; - -#if defined(AZ_PLATFORM_PROVO) - size_t allocatedVideoMemoryBytes = 0, reservedVideoMemoryBytes = 0; - VirtualAllocator::QueryVideoMemory(allocatedVideoMemoryBytes, reservedVideoMemoryBytes); - allocatedVideoMemoryMB = static_cast(allocatedVideoMemoryBytes) / (1024.0f * 1024.0f); - reservedVideoMemoryMB = static_cast(reservedVideoMemoryBytes) / (1024.0f * 1024.0f); -#else - // Non PROVO platforms just sum up the tracked allocations - allocatedVideoMemoryMB = totalTrackedGPUAlloc; -#endif - - DrawTextLeftAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 4, memoryYPos, DISPLAY_MEMORY_ROW_FONT_SCALE, totalColor, "Total"); - if (reservedVideoMemoryMB != -1.0f) - { - DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 1, memoryYPos, DISPLAY_MEMORY_ROW_FONT_SCALE, totalColor, "%.1fMB/%.1fMB", allocatedVideoMemoryMB, reservedVideoMemoryMB); - memoryYPos += (memoryYPosStepSize * 0.5f); - } - else - { - DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH * 1, memoryYPos, DISPLAY_MEMORY_ROW_FONT_SCALE, totalColor, "%.1fMB", allocatedVideoMemoryMB); - memoryYPos += (memoryYPosStepSize * 0.5f); - } - - // Spacer - memoryYPos += (memoryYPosStepSize * 0.5f); - - // Add column labels and header - this->DrawTextRightAligned(columnInset - DISPLAY_MEMORY_ROW_NUMBER_WIDTH, memoryYPos, DISPLAY_MEMORY_COL_LABEL_FONT_SCALE, labelColor, "Allocated"); - this->DrawTextRightAligned(columnInset, memoryYPos, DISPLAY_MEMORY_COL_LABEL_FONT_SCALE, labelColor, "Capacity"); - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, -1.0f, -1.0f, "%.1fMB", headerColor, "CPU Memory Usage"); - memoryYPos += (memoryYPosStepSize * 0.5f); - - float totalTrackedCPUAlloc = 0.0f; - float totalCapacityCPUAlloc = 0.0f; - - AZ::AllocatorManager& allocatorManager = AZ::AllocatorManager::Instance(); - const size_t allocatorCount = allocatorManager.GetNumAllocators(); - AZStd::map existingAllocators; - AZStd::map sourcesToAllocators; - - // Build a mapping of original allocator sources to their allocators - for (int i = 0; i < allocatorCount; ++i) - { - AZ::IAllocator* allocator = allocatorManager.GetAllocator(i); - sourcesToAllocators.emplace(allocator->GetOriginalAllocationSource(), allocator); - } - - // Group up any allocators under this size - static float smallAllocatorCapacityMaxMB = 10.0f; - float smallAllocatorsTotalCapacityMB = 0.0f; - float smallAllocatorsTotalAllocatedMB = 0.0f; - - for (int i = 0; i < allocatorCount; ++i) - { - AZ::IAllocator* allocator = allocatorManager.GetAllocator(i); - AZ::IAllocatorAllocate* source = allocator->GetAllocationSource(); - AZ::IAllocatorAllocate* originalSource = allocator->GetOriginalAllocationSource(); - AZ::IAllocatorAllocate* schema = allocator->GetSchema(); - AZ::IAllocator* alias = (source != originalSource) ? sourcesToAllocators[source] : nullptr; - - if (schema && !alias) - { - // Check to see if this allocator's source maps to another allocator - // Need to check both the schema and the allocator itself, as either one might be used as the alias depending on how it's implemented - AZStd::array checkAllocators = { { schema, allocator->GetAllocationSource() } }; - - for (AZ::IAllocatorAllocate* check : checkAllocators) - { - auto existing = existingAllocators.emplace(check, allocator); - - if (!existing.second) - { - alias = existing.first->second; - // Do not break out of the loop as we need to add to the map for all entries - } - } - } - - if (!alias) - { - static const AZ::IAllocator* OS_ALLOCATOR = &AZ::AllocatorInstance::GetAllocator(); - float allocatedMB = (float)source->NumAllocatedBytes() / (1024.0f * 1024.0f); - float capacityMB = (float)source->Capacity() / (1024.0f * 1024.0f); - - totalTrackedCPUAlloc += allocatedMB; - totalCapacityCPUAlloc += capacityMB; - - // Skip over smaller allocators so the display is readable. - if (capacityMB < smallAllocatorCapacityMaxMB) - { - smallAllocatorsTotalCapacityMB += capacityMB; - smallAllocatorsTotalAllocatedMB += allocatedMB; - continue; - } - - if (allocator == OS_ALLOCATOR) - { - // Need to special case the OS allocator because its capacity is a made-up number. Better to just use the allocated amount, it will hopefully be small anyway. - capacityMB = allocatedMB; - } - - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, allocatedMB, capacityMB, "%.1fMB", statisticColor, allocator->GetName(), allocator->GetDescription()); - - memoryYPos += memoryYPosStepSize; - } - } - - if (smallAllocatorCapacityMaxMB > 0.0f) - { - AZStd::string subText = AZStd::string::format("Allocators smaller than %.0f MB", smallAllocatorCapacityMaxMB); - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, smallAllocatorsTotalAllocatedMB, smallAllocatorsTotalCapacityMB, "%.1fMB", statisticColor, "All Small Allocators", subText.c_str()); - memoryYPos += memoryYPosStepSize; - } - - DisplayMemoryRow(*this, columnWidth, screenHeight, memoryYPos, totalTrackedCPUAlloc, totalCapacityCPUAlloc, "%.1fMB", totalColor, "Total"); - memoryYPos += (memoryYPosStepSize * 0.5f); - } - else if (GetCVars()->e_MemoryProfiling == 2) - { - const float columnWidth = (float)(m_pRenderer->GetWidth() / 2); - - float memoryYPos = DISPLAY_MEMORY_ROW_HEIGHT; - float memoryYPosStepSize = DISPLAY_MEMORY_ROW_HEIGHT; - - AZ::AllocatorManager& allocatorManager = AZ::AllocatorManager::Instance(); - const size_t allocatorCount = allocatorManager.GetNumAllocators(); - AZStd::map existingAllocators; - AZStd::map sourcesToAllocators; - - // Build a mapping of original allocator sources to their allocators - for (int i = 0; i < allocatorCount; ++i) - { - AZ::IAllocator* allocator = allocatorManager.GetAllocator(i); - sourcesToAllocators.emplace(allocator->GetOriginalAllocationSource(), allocator); - } - - for (int i = 0; i < allocatorCount; ++i) - { - AZ::IAllocator* allocator = allocatorManager.GetAllocator(i); - AZ::IAllocatorAllocate* source = allocator->GetAllocationSource(); - AZ::IAllocatorAllocate* originalSource = allocator->GetOriginalAllocationSource(); - AZ::IAllocatorAllocate* schema = allocator->GetSchema(); - AZ::IAllocator* alias = (source != originalSource) ? sourcesToAllocators[source] : nullptr; - - if (schema && !alias) - { - // Check to see if this allocator's source maps to another allocator - // Need to check both the schema and the allocator itself, as either one might be used as the alias depending on how it's implemented - AZStd::array checkAllocators = { { schema, allocator->GetAllocationSource() } }; - - for (AZ::IAllocatorAllocate* check : checkAllocators) - { - auto existing = existingAllocators.emplace(check, allocator); - - if (!existing.second) - { - alias = existing.first->second; - // Do not break out of the loop as we need to add to the map for all entries - } - } - } - - if (alias) - { - float columnInset = columnWidth - DISPLAY_MEMORY_ROW_MARGIN; - float yPos = memoryYPos; - AdjustDisplayMemoryParameters(yPos, columnInset, columnWidth, screenHeight); - DrawTextRightAligned(columnInset, yPos, DISPLAY_MEMORY_ROW_FONT_SCALE, statisticColor, "%s => %s", allocator->GetName(), alias->GetName()); - memoryYPos += (memoryYPosStepSize * 0.5f); - } - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -void C3DEngine::SetupDistanceFog() -{ - FUNCTION_PROFILER_3DENGINE; - - GetRenderer()->SetFogColor(ColorF(m_vFogColor.x, m_vFogColor.y, m_vFogColor.z, 1.0f)); - GetRenderer()->EnableFog(GetCVars()->e_Fog > 0); -} - -void C3DEngine::ScreenShotHighRes([[maybe_unused]] CStitchedImage* pStitchedImage, [[maybe_unused]] const int nRenderFlags, [[maybe_unused]] const SRenderingPassInfo& passInfo, [[maybe_unused]] uint32 SliceCount, [[maybe_unused]] f32 fTransitionSize) -{ -#if defined(WIN32) || defined(WIN64) || defined(MAC) - - //If the requested format is TGA we want the framebuffer in BGR format; otherwise we want RGB - const char* szExtension = GetCVars()->e_ScreenShotFileFormat->GetString(); - bool BGRA = (azstricmp(szExtension, "tga") == 0) ? true : false; - - // finish frame started by system - GetRenderer()->EndFrame(); - - // The occlusion system does not like being restarted mid-frame like this. Disable it for - // the screenshot system. - AZ::s32 statObjBufferRenderTasks = GetCVars()->e_StatObjBufferRenderTasks; - GetCVars()->e_StatObjBufferRenderTasks = 0; - - GetConsole()->SetScrollMax(0); - - const uint32 ScreenWidth = GetRenderer()->GetWidth(); - const uint32 ScreenHeight = GetRenderer()->GetHeight(); - uint32* pImage = new uint32[ScreenWidth * ScreenHeight]; - for (uint32 yy = 0; yy < SliceCount; yy++) - { - for (uint32 xx = 0; xx < SliceCount; xx++) - { - const int BlendX = (xx * 2) / SliceCount; - const int BlendY = (yy * 2) / SliceCount; - const int x = (((xx * 2) % SliceCount) & ~1) + BlendX; - const int y = (((yy * 2) % SliceCount) & ~1) + BlendY; - const int reverseX = SliceCount - 1 - x; - const int reverseY = SliceCount - 1 - y; - - const float halfTransitionSize = fTransitionSize * 0.5f; - const float sliceCountF = static_cast(SliceCount); - - // start new frame and define needed tile - const f32 ScreenScale = 1.0f / ((1.0f / sliceCountF) * (1.0f + fTransitionSize)); - - GetRenderer()->BeginFrame(); - - // This has to happen after BeginFrame(), because BeginFrame increments the frame counter, and SRenderingPassInfo - // pulls from that counter in the constructor. Individual render nodes track the frame they were last rendered with - // and will bail if the same frame is rendered twice. - SRenderingPassInfo screenShotPassInfo = SRenderingPassInfo::CreateGeneralPassRenderingInfo(passInfo.GetCamera()); - PrintMessage("Rendering tile %d of %d ... ", xx + yy * SliceCount + 1, SliceCount * SliceCount); - - const float normalizedX = ((static_cast(reverseX) - halfTransitionSize) / sliceCountF); - const float normalizedY = ((static_cast(reverseY) - halfTransitionSize) / sliceCountF); - - GetRenderer()->SetRenderTile( - ScreenScale * normalizedX, - ScreenScale * normalizedY, - ScreenScale, ScreenScale); - - UpdateRenderingCamera("ScreenShotHighRes", screenShotPassInfo); - - RenderInternal(nRenderFlags, screenShotPassInfo, "ScreenShotHighRes"); - - // Make sure we've composited to the final back buffer. - GetRenderer()->SwitchToNativeResolutionBackbuffer(); - - GetRenderer()->EndFrame(); - - PrintMessagePlus("reading frame buffer ... "); - - GetRenderer()->ReadFrameBufferFast(pImage, ScreenWidth, ScreenHeight, BGRA); - pStitchedImage->RasterizeRect(pImage, ScreenWidth, ScreenHeight, x, y, fTransitionSize, - fTransitionSize > 0.0001f && BlendX, - fTransitionSize > 0.0001f && BlendY); - - PrintMessagePlus("ok"); - } - } - delete[] pImage; - - GetCVars()->e_StatObjBufferRenderTasks = statObjBufferRenderTasks; - - // re-start frame so system can safely finish it - GetRenderer()->BeginFrame(); - - // restore initial state - GetRenderer()->SetViewport(0, 0, GetRenderer()->GetWidth(), GetRenderer()->GetHeight()); - GetConsole()->SetScrollMax(300); - GetRenderer()->SetRenderTile(); - - PrintMessagePlus(" ok"); -#endif // #if defined(WIN32) || defined(WIN64) -} - - - -bool C3DEngine::ScreenShotMap([[maybe_unused]] CStitchedImage* pStitchedImage, - [[maybe_unused]] const int nRenderFlags, - [[maybe_unused]] const SRenderingPassInfo& passInfo, - [[maybe_unused]] const uint32 SliceCount, - [[maybe_unused]] const f32 fTransitionSize) -{ -#if defined(WIN32) || defined(WIN64) || defined(MAC) - - const f32 fTLX = GetCVars()->e_ScreenShotMapCenterX - GetCVars()->e_ScreenShotMapSizeX + fTransitionSize * GetRenderer()->GetWidth(); - const f32 fTLY = GetCVars()->e_ScreenShotMapCenterY - GetCVars()->e_ScreenShotMapSizeY + fTransitionSize * GetRenderer()->GetHeight(); - const f32 fBRX = GetCVars()->e_ScreenShotMapCenterX + GetCVars()->e_ScreenShotMapSizeX + fTransitionSize * GetRenderer()->GetWidth(); - const f32 fBRY = GetCVars()->e_ScreenShotMapCenterY + GetCVars()->e_ScreenShotMapSizeY + fTransitionSize * GetRenderer()->GetHeight(); - const f32 Height = GetCVars()->e_ScreenShotMapCamHeight; - const int Orient = GetCVars()->e_ScreenShotMapOrientation; - - const char* SettingsFileName = GetLevelFilePath("ScreenshotMap.Settings"); - - AZ::IO::HandleType metaFileHandle = gEnv->pCryPak->FOpen(SettingsFileName, "wt"); - if (metaFileHandle != AZ::IO::InvalidHandle) - { - char Data[1024 * 8]; - snprintf(Data, sizeof(Data), "", - GetCVars()->e_ScreenShotMapCenterX, - GetCVars()->e_ScreenShotMapCenterY, - GetCVars()->e_ScreenShotMapSizeX, - GetCVars()->e_ScreenShotMapSizeY, - GetCVars()->e_ScreenShotMapCamHeight, - GetCVars()->e_ScreenShotQuality, - GetCVars()->e_ScreenShotMapOrientation); - string data(Data); - gEnv->pCryPak->FWrite(data.c_str(), data.size(), metaFileHandle); - gEnv->pCryPak->FClose(metaFileHandle); - } - - // This bit is necessary because we don't have a way to render the world using an orthographic projection. This is doing - // a hacky orthographic projection by shifting the camera up to a sufficient height to fake it. To preserve depth range - // we define a maximum range then then fit the near / far planes to extend [-HeightRangeMax, HeightRangeMax] along Z (which is the up axis). - const float HeightRangeMax = 4096; - const float HeightRangeMaxDiv2 = HeightRangeMax / 2.0f; - - const float NearClip = max(Height - HeightRangeMaxDiv2, 1.0f); - const float FarClip = max(Height + HeightRangeMaxDiv2, HeightRangeMax); - - CCamera cam = passInfo.GetCamera(); - Matrix34 tmX, tmY; - float xrot = -gf_PI * 0.5f; - float yrot = Orient == 0 ? -gf_PI * 0.5f : -0.0f; - tmX.SetRotationX(xrot); - tmY.SetRotationY(yrot); - Matrix34 tm = tmX * tmY; - tm.SetTranslation(Vec3((fTLX + fBRX) * 0.5f, (fTLY + fBRY) * 0.5f, Height)); - cam.SetMatrix(tm); - - const f32 AngleX = atanf(((fBRX - fTLX) * 0.5f) / Height); - const f32 AngleY = atanf(((fBRY - fTLY) * 0.5f) / Height); - - ICVar* r_drawnearfov = GetConsole()->GetCVar("r_DrawNearFoV"); - assert(r_drawnearfov); - const f32 drawnearfov_backup = r_drawnearfov->GetFVal(); - const f32 ViewingSize = (float)min(cam.GetViewSurfaceX(), cam.GetViewSurfaceZ()); - if (max(AngleX, AngleY) <= 0) - { - return false; - } - cam.SetFrustum((int)ViewingSize, (int)ViewingSize, max(0.001f, max(AngleX, AngleY) * 2.f), NearClip, FarClip); - r_drawnearfov->Set(-1); - ScreenShotHighRes(pStitchedImage, nRenderFlags, SRenderingPassInfo::CreateTempRenderingInfo(cam, passInfo), SliceCount, fTransitionSize); - r_drawnearfov->Set(drawnearfov_backup); - - return true; -#else // #if defined(WIN32) || defined(WIN64) - return false; -#endif // #if defined(WIN32) || defined(WIN64) -} - - -bool C3DEngine::ScreenShotPanorama([[maybe_unused]] CStitchedImage* pStitchedImage, [[maybe_unused]] const int nRenderFlags, [[maybe_unused]] const SRenderingPassInfo& passInfo, [[maybe_unused]] uint32 SliceCount, [[maybe_unused]] f32 fTransitionSize) -{ -#if defined(WIN32) || defined(WIN64) || defined(MAC) - - //If the requested format is TGA we want the framebuffer in BGR format; otherwise we want RGB - const char* szExtension = GetCVars()->e_ScreenShotFileFormat->GetString(); - bool BGRA = (azstricmp(szExtension, "tga") == 0) ? true : false; - - // finish frame started by system - GetRenderer()->EndFrame(); - - float r_drawnearfov_backup = -1; - ICVar* r_drawnearfov = GetConsole()->GetCVar("r_DrawNearFoV"); - assert(r_drawnearfov); - - r_drawnearfov_backup = r_drawnearfov->GetFVal(); - r_drawnearfov->Set(-1); // means the fov override should be switched off - - // The occlusion system does not like being restarted mid-frame like this. Disable it for - // the screenshot system. - AZ::s32 statObjBufferRenderTasks = GetCVars()->e_StatObjBufferRenderTasks; - GetCVars()->e_StatObjBufferRenderTasks = 0; - - GetTimer()->EnableTimer(false); - - uint32* pImage = new uint32[GetRenderer()->GetWidth() * GetRenderer()->GetHeight()]; - - for (int iSlice = SliceCount - 1; iSlice >= 0; --iSlice) - { - if (iSlice == 0) // the last one should do eye adaption - { - GetTimer()->EnableTimer(true); - } - - GetRenderer()->BeginFrame(); - - Matrix33 rot; - rot.SetIdentity(); - - float fAngle = pStitchedImage->GetSliceAngle(iSlice); - - rot.SetRotationZ(fAngle); - - CCamera cam = passInfo.GetCamera(); - - Matrix34 tm = cam.GetMatrix(); - tm = tm * rot; - tm.SetTranslation(passInfo.GetCamera().GetPosition()); - cam.SetMatrix(tm); - - cam.SetFrustum(cam.GetViewSurfaceX(), cam.GetViewSurfaceZ(), pStitchedImage->m_fPanoramaShotVertFOV, cam.GetNearPlane(), cam.GetFarPlane(), cam.GetPixelAspectRatio()); - - SRenderingPassInfo screenShotPassInfo = SRenderingPassInfo::CreateGeneralPassRenderingInfo(cam); - - UpdateRenderingCamera("ScreenShotPanorama", screenShotPassInfo); - - // render scene - RenderInternal(nRenderFlags, screenShotPassInfo, "ScreenShotPanorama"); - - // Make sure we've composited to the final back buffer. - GetRenderer()->SwitchToNativeResolutionBackbuffer(); - - GetRenderer()->ReadFrameBufferFast(pImage, GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), BGRA); - - GetRenderer()->EndFrame(); // show last frame (from direction) - - const bool bFadeBorders = (iSlice + 1) * 2 <= (int)SliceCount; - - PrintMessage("PanoramaScreenShot %d/%d FadeBorders:%c (id: %d/%d)", iSlice + 1, SliceCount, bFadeBorders ? 't' : 'f', GetRenderer()->GetFrameID(false), GetRenderer()->GetFrameID(true)); - - pStitchedImage->RasterizeCylinder(pImage, GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), iSlice + 1, bFadeBorders); - - if (GetCVars()->e_ScreenShotQuality < 0) // to debug FadeBorders - { - if (iSlice * 2 == SliceCount) - { - pStitchedImage->Clear(); - PrintMessage("PanoramaScreenShot clear"); - } - } - } - delete [] pImage; - - r_drawnearfov->Set(r_drawnearfov_backup); - GetCVars()->e_StatObjBufferRenderTasks = statObjBufferRenderTasks; - - // re-start frame so system can safely finish it - GetRenderer()->BeginFrame(); - - return true; -#else // #if defined(WIN32) || defined(WIN64) - return false; -#endif // #if defined(WIN32) || defined(WIN64) -} - - - -void C3DEngine::SetupClearColor() -{ - FUNCTION_PROFILER_3DENGINE; - - bool bCameraInOutdoors = m_pVisAreaManager && !m_pVisAreaManager->m_pCurArea && !(m_pVisAreaManager->m_pCurPortal && m_pVisAreaManager->m_pCurPortal->m_lstConnections.Count() > 1); - GetRenderer()->SetClearColor(bCameraInOutdoors ? m_vFogColor : Vec3(0, 0, 0)); -} - -void C3DEngine::FillDebugFPSInfo(SDebugFPSInfo& info) -{ - size_t c = 0; - float average = 0.0f, min = 0.0f, max = 0.0f; - const float clampFPS = 200.0f; - for (size_t i = 0, end = arrFPSforSaveLevelStats.size(); i < end; ++i) - { - if (arrFPSforSaveLevelStats[i] > 1.0f && arrFPSforSaveLevelStats[i] < clampFPS) - { - ++c; - average += arrFPSforSaveLevelStats[i]; - } - } - - if (c) - { - average /= (float)c; - } - - int minc = 0, maxc = 0; - for (size_t i = 0, end = arrFPSforSaveLevelStats.size(); i < end; ++i) - { - if (arrFPSforSaveLevelStats[i] > average && arrFPSforSaveLevelStats[i] < clampFPS) - { - ++maxc; - max += arrFPSforSaveLevelStats[i]; - } - - if (arrFPSforSaveLevelStats[i] < average && arrFPSforSaveLevelStats[i] < clampFPS) - { - ++minc; - min += arrFPSforSaveLevelStats[i]; - } - } - - if (minc == 0) - { - minc = 1; - } - if (maxc == 0) - { - maxc = 1; - } - - info.fAverageFPS = average; - info.fMinFPS = min / (float)minc; - info.fMaxFPS = max / (float)maxc; -} diff --git a/Code/CryEngine/Cry3DEngine/3DEngine_Jobs.cpp b/Code/CryEngine/Cry3DEngine/3DEngine_Jobs.cpp deleted file mode 100644 index a6beb77dda..0000000000 --- a/Code/CryEngine/Cry3DEngine/3DEngine_Jobs.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of I3DEngine interface methods - - -#include "Cry3DEngine_precompiled.h" -#include - -#include "3dEngine.h" - -#include - -#include "VisAreas.h" -#include "ObjMan.h" -#include "Ocean.h" - -#include "DecalManager.h" -#include "IndexedMesh.h" -#include "AABBSV.h" - -#include "MatMan.h" - -#include "CullBuffer.h" -#include "CGF/CGFLoader.h" -#include "CGF/ReadOnlyChunkFile.h" - -#include "CloudRenderNode.h" -#include "CloudsManager.h" -#include "SkyLightManager.h" -#include "FogVolumeRenderNode.h" -#include "DecalRenderNode.h" -#include "TimeOfDay.h" -#include "LightEntity.h" -#include "FogVolumeRenderNode.h" -#include "ObjectsTree.h" -#include "WaterVolumeRenderNode.h" -#include "DistanceCloudRenderNode.h" -#include "VolumeObjectRenderNode.h" -#include "RenderMeshMerger.h" -#include "DeferredCollisionEvent.h" -#include "OpticsManager.h" -#include "ClipVolumeManager.h" -#include "Environment/OceanEnvironmentBus.h" - - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) -#include "PrismRenderNode.h" -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - -//Platform specific includes -#if defined(WIN32) || defined(WIN64) -#include "CryWindows.h" -#endif - -/////////////////////////////////////////////////////////////////////////////// -void C3DEngine::CheckAddLight(CDLight* pLight, const SRenderingPassInfo& passInfo) -{ - if (pLight->m_Id < 0) - { - GetRenderer()->EF_ADDDlight(pLight, passInfo); - assert(pLight->m_Id >= 0); - } -} - -/////////////////////////////////////////////////////////////////////////////// -float C3DEngine::GetLightAmount(CDLight* pLight, const AABB& objBox) -{ - // find amount of light - float fDist = sqrt_tpl(Distance::Point_AABBSq(pLight->m_Origin, objBox)); - float fLightAttenuation = (pLight->m_Flags & DLF_DIRECTIONAL) ? 1.f : 1.f - (fDist) / (pLight->m_fRadius); - if (fLightAttenuation < 0) - { - fLightAttenuation = 0; - } - - float fLightAmount = - (pLight->m_Color.r + pLight->m_Color.g + pLight->m_Color.b) * 0.233f + - (pLight->GetSpecularMult()) * 0.1f; - - return fLightAmount * fLightAttenuation; -} - -/////////////////////////////////////////////////////////////////////////////// -float C3DEngine::GetWaterLevel() -{ - if (OceanToggle::IsActive()) - { - return OceanRequest::GetOceanLevel(); - } - return m_pOcean ? m_pOcean->GetWaterLevel() : WATER_LEVEL_UNKNOWN; -} - -/////////////////////////////////////////////////////////////////////////////// -bool C3DEngine::IsTessellationAllowed(const CRenderObject* pObj, const SRenderingPassInfo& passInfo, bool bIgnoreShadowPass) const -{ -#ifdef MESH_TESSELLATION_ENGINE - assert(pObj && GetCVars()); - bool rendererTessellation; - GetRenderer()->EF_Query(EFQ_MeshTessellation, rendererTessellation); - if (pObj->m_fDistance < GetCVars()->e_TessellationMaxDistance - && GetCVars()->e_Tessellation - && rendererTessellation - && !(pObj->m_ObjFlags & FOB_DISSOLVE)) // dissolve is not working with tessellation for now - { - bool bAllowTessellation = true; - - // Check if rendering into shadow map and enable tessellation only if allowed - if (!bIgnoreShadowPass && passInfo.IsShadowPass()) - { - if (IsTessellationAllowedForShadowMap(passInfo)) - { - // NOTE: This might be useful for game projects - // Use tessellation only for objects visible in main view - // Shadows will switch to non-tessellated when caster gets out of view - IRenderNode* pRN = (IRenderNode*)pObj->m_pRenderNode; - if (pRN) - { - bAllowTessellation = (pRN->IsRenderNode() && (pRN->GetDrawFrame() > passInfo.GetFrameID() - 10)); - } - } - else - { - bAllowTessellation = false; - } - } - - return bAllowTessellation; - } -#endif //#ifdef MESH_TESSELLATION_ENGINE - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -void C3DEngine::CreateRNTmpData(CRNTmpData** ppInfo, IRenderNode* pRNode, const SRenderingPassInfo& passInfo) -{ - // m_checkCreateRNTmpData lock scope - { - AUTO_LOCK(m_checkCreateRNTmpData); - FUNCTION_PROFILER_3DENGINE; - - if (*ppInfo) - { - return; // check if another thread already intialized ppInfo - } - // make sure element is allocated - if (m_LTPRootFree.pNext == &m_LTPRootFree) - { - CRNTmpData* pNew = new CRNTmpData; //m_RNTmpDataPools.GetNewElement(); - pNew->Link(&m_LTPRootFree); - } - - // move element from m_LTPRootFree to m_LTPRootUsed - CRNTmpData* pElem = m_LTPRootFree.pNext; - pElem->Unlink(); - pElem->Link(&m_LTPRootUsed); - - pElem->pOwnerRef = ppInfo; - pElem->nFrameInfoId = GetFrameInfoId(ppInfo, passInfo.GetMainFrameID()); - - assert(!pElem->pOwnerRef || !(*pElem->pOwnerRef)); - memset(&pElem->userData, 0, sizeof(pElem->userData)); - - - // Add a memory barrier that the write to nFrameInfoID is visible - // before *ppInfo is written, else we have a race condtition in - // CheckCreateRNTmpData as we don't use a lock there - // for performance reasons - MemoryBarrier(); - - *ppInfo = pElem; - } - - if (pRNode) - { - pRNode->OnRenderNodeBecomeVisible(passInfo); // Internally uses the just assigned RNTmpData pointer i.e IRenderNode::m_pRNTmpData ... - - if (IVisArea* pVisArea = pRNode->GetEntityVisArea()) - { - pRNode->m_pRNTmpData->userData.m_pClipVolume = pVisArea; - } - else if (GetClipVolumeManager()->IsClipVolumeRequired(pRNode)) - { - GetClipVolumeManager()->UpdateEntityClipVolume(pRNode->GetPos(), pRNode); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void C3DEngine::RenderRenderNode_ShadowPass(IShadowCaster* pShadowCaster, const SRenderingPassInfo& passInfo, [[maybe_unused]] AZ::LegacyJobExecutor* pJobExecutor) -{ - assert(passInfo.IsShadowPass()); - - SRendItemSorter rendItemSorter = SRendItemSorter::CreateShadowPassRendItemSorter(passInfo); - - if (!pShadowCaster->IsRenderNode()) - { - const Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - const AABB objBox = pShadowCaster->GetBBoxVirtual(); - - SRendParams rParams; - rParams.fDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - rParams.lodValue = pShadowCaster->ComputeLod(0, passInfo); - rParams.rendItemSorter = rendItemSorter.GetValue(); - - pShadowCaster->Render(rParams, passInfo); - return; - } - - IRenderNode* pRenderNode = static_cast(pShadowCaster); - if ((pRenderNode->m_dwRndFlags & ERF_HIDDEN) != 0) - { - return; - } - - int nStaticObjectLod = -1; - if (passInfo.GetShadowMapType() == SRenderingPassInfo::SHADOW_MAP_CACHED) - { - nStaticObjectLod = GetCVars()->e_ShadowsCacheObjectLod; - } - else if (passInfo.GetShadowMapType() == SRenderingPassInfo::SHADOW_MAP_CACHED_MGPU_COPY) - { - nStaticObjectLod = pRenderNode->m_cStaticShadowLod; - } - - Get3DEngine()->CheckCreateRNTmpData(&pRenderNode->m_pRNTmpData, pRenderNode, passInfo); - - int wantedLod = pRenderNode->m_pRNTmpData->userData.nWantedLod; - - if (GetCVars()->e_LodForceUpdate && m_pObjManager) - { - const Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - const AABB objBox = pRenderNode->GetBBoxVirtual(); - float fDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - wantedLod = m_pObjManager->GetObjectLOD(pRenderNode, fDistance); - } - - if (pRenderNode->GetShadowLodBias() != IRenderNode::SHADOW_LODBIAS_DISABLE) - { - if (passInfo.IsShadowPass() && (pRenderNode->GetDrawFrame(0) < (passInfo.GetFrameID() - 10))) - { - wantedLod += GetCVars()->e_ShadowsLodBiasInvis; - } - wantedLod += GetCVars()->e_ShadowsLodBiasFixed; - wantedLod += pRenderNode->GetShadowLodBias(); - } - - if (nStaticObjectLod >= 0) - { - wantedLod = nStaticObjectLod; - } - - { - const Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - const AABB objBox = pRenderNode->GetBBoxVirtual(); - SRendParams rParams; - rParams.fDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - rParams.lodValue = pRenderNode->ComputeLod(wantedLod, passInfo); - rParams.rendItemSorter = rendItemSorter.GetValue(); - rParams.pRenderNode = pRenderNode; - pRenderNode->Render(rParams, passInfo); - } -} - -/////////////////////////////////////////////////////////////////////////////// -ITimeOfDay* C3DEngine::GetTimeOfDay() -{ - CTimeOfDay* tod = m_pTimeOfDay; - - if (!tod) - { - tod = new CTimeOfDay; - m_pTimeOfDay = tod; - } - - return tod; -} - -/////////////////////////////////////////////////////////////////////////////// -void C3DEngine::TraceFogVolumes(const Vec3& vPos, const AABB& objBBox, SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo, bool fogVolumeShadingQuality) -{ - CFogVolumeRenderNode::TraceFogVolumes(vPos, objBBox, fogVolData, passInfo, fogVolumeShadingQuality); -} - -/////////////////////////////////////////////////////////////////////////////// -void C3DEngine::AsyncOctreeUpdate(IRenderNode* pEnt, int nSID, [[maybe_unused]] int nSIDConsideredSafe, uint32 nFrameID, bool bUnRegisterOnly) -{ - FUNCTION_PROFILER_3DENGINE; - -#ifdef _DEBUG // crash test basically - const char* szClass = pEnt->GetEntityClassName(); - const char* szName = pEnt->GetName(); - if (!szName[0] && !szClass[0]) - { - Warning("I3DEngine::RegisterEntity: Entity undefined"); // do not register undefined objects - } - // if(strstr(szName,"Dude")) - // int y=0; -#endif - - IF (bUnRegisterOnly, 0) - { - UnRegisterEntityImpl(pEnt); - return; - } - ; - - AABB aabb; - pEnt->FillBBox(aabb); - float fObjRadiusSqr = aabb.GetRadiusSqr(); - EERType eERType = pEnt->GetRenderNodeType(); - -#ifdef SUPP_HMAP_OCCL - if (pEnt->m_pRNTmpData) - { - pEnt->m_pRNTmpData->userData.m_OcclState.vLastVisPoint.Set(0, 0, 0); - } -#endif - - - const unsigned int dwRndFlags = pEnt->GetRndFlags(); - - if (!(dwRndFlags & ERF_RENDER_ALWAYS) && !(dwRndFlags & ERF_CASTSHADOWMAPS)) - { - if (GetCVars()->e_ObjFastRegister && pEnt->m_pOcNode && ((COctreeNode*)pEnt->m_pOcNode)->IsRightNode(aabb, fObjRadiusSqr, pEnt->m_fWSMaxViewDist)) - { // same octree node - Vec3 vEntCenter = GetEntityRegisterPoint(pEnt); - - IVisArea* pVisArea = pEnt->GetEntityVisArea(); - if (pVisArea && pVisArea->IsPointInsideVisArea(vEntCenter)) - { - return; // same visarea - } - IVisArea* pVisAreaFromPos = (!m_pVisAreaManager || dwRndFlags & ERF_OUTDOORONLY) ? NULL : GetVisAreaManager()->GetVisAreaFromPos(vEntCenter); - if (pVisAreaFromPos == pVisArea) - { - // NOTE: can only get here when pVisArea==NULL due to 'same visarea' check above. So check for changed clip volume - if (GetClipVolumeManager()->IsClipVolumeRequired(pEnt)) - { - GetClipVolumeManager()->UpdateEntityClipVolume(vEntCenter, pEnt); - } - - return; // same visarea or same outdoor - } - } - } - - if (pEnt->m_pOcNode) - { - UnRegisterEntityImpl(pEnt); - } - else if (GetCVars()->e_StreamCgf && (eERType == eERType_RenderComponent || eERType == eERType_DynamicMeshRenderComponent || eERType == eERType_GeomCache)) - { // Temporary solution: Force streaming priority update for objects that was not registered before - // and was not visible before since usual prediction system was not able to detect them - - if ((uint32)pEnt->GetDrawFrame(0) < nFrameID - 16) - { - // defer the render node streaming priority update still we have a correct 3D Engine camera - int nElementID = m_deferredRenderComponentStreamingPriorityUpdates.Find(pEnt); - if (nElementID == -1) // only add elements once - { - m_deferredRenderComponentStreamingPriorityUpdates.push_back(pEnt); - } - } - } - - pEnt->m_fWSMaxViewDist = pEnt->GetMaxViewDist(); - - bool useVisAreas = true; - - if (eERType != eERType_Light) - { - if (fObjRadiusSqr > sqr(MAX_VALID_OBJECT_VOLUME) || !_finite(fObjRadiusSqr)) - { - Warning("I3DEngine::RegisterEntity: Object has invalid bbox: name: %s, class name: %s, GetRadius() = %.2f", - pEnt->GetName(), pEnt->GetEntityClassName(), fObjRadiusSqr); - return; // skip invalid objects - usually only objects with invalid very big scale will reach this point - } - - if (dwRndFlags & ERF_RENDER_ALWAYS) - { - if (m_lstAlwaysVisible.Find(pEnt) < 0) - { - m_lstAlwaysVisible.Add(pEnt); - } - - if (dwRndFlags & ERF_HUD) - { - return; - } - } - - if (pEnt->m_dwRndFlags & ERF_OUTDOORONLY) - { - useVisAreas = false; - } - } - else - { - CLightEntity* pLight = (CLightEntity*)pEnt; - uint32 lightFlag = pLight->m_light.m_Flags; - if ((lightFlag & DLF_ATTACH_TO_SUN) || //If the light is attached to the sun, we need to make sure it renders even the entity is not in view port - (lightFlag & (DLF_IGNORES_VISAREAS | DLF_DEFERRED_LIGHT | DLF_THIS_AREA_ONLY)) == (DLF_IGNORES_VISAREAS | DLF_DEFERRED_LIGHT) - ) - { - if (m_lstAlwaysVisible.Find(pEnt) < 0) - { - m_lstAlwaysVisible.Add(pEnt); - } - } - - if (lightFlag & DLF_IGNORES_VISAREAS) - { - useVisAreas = false; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Check for occlusion proxy. - { - CStatObj* pStatObj = (CStatObj*)pEnt->GetEntityStatObj(); - if (pStatObj) - { - if (pStatObj->m_bHaveOcclusionProxy) - { - pEnt->m_dwRndFlags |= ERF_GOOD_OCCLUDER; - pEnt->m_nInternalFlags |= IRenderNode::HAS_OCCLUSION_PROXY; - } - } - } - ////////////////////////////////////////////////////////////////////////// - if (!useVisAreas || !(m_pVisAreaManager && m_pVisAreaManager->SetEntityArea(pEnt, aabb, fObjRadiusSqr))) - { - if (m_pObjectsTree == nullptr) - { - AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); - m_pObjectsTree = COctreeNode::Create(nSID, AABB(Vec3(0, 0, 0), Vec3(terrainAabb.GetXExtent(), terrainAabb.GetYExtent(), terrainAabb.GetZExtent())), NULL); - } - - m_pObjectsTree->InsertObject(pEnt, aabb, fObjRadiusSqr, aabb.GetCenter()); - } - - // update clip volume: use vis area if we have one, otherwise check if we're in the same volume as before. check other volumes as last resort only - if (pEnt->m_pRNTmpData) - { - Vec3 vEntCenter = GetEntityRegisterPoint(pEnt); - CRNTmpData::SRNUserData& userData = pEnt->m_pRNTmpData->userData; - - if (IVisArea* pVisArea = pEnt->GetEntityVisArea()) - { - userData.m_pClipVolume = pVisArea; - } - else if (GetClipVolumeManager()->IsClipVolumeRequired(pEnt)) - { - GetClipVolumeManager()->UpdateEntityClipVolume(vEntCenter, pEnt); - } - } - - // register decals, to clean up longer not renderes decals and their render meshes - if (eERType == eERType_Decal) - { - m_decalRenderNodes.push_back((IDecalRenderNode*)pEnt); - } -} - -/////////////////////////////////////////////////////////////////////////////// -bool C3DEngine::UnRegisterEntityImpl(IRenderNode* pEnt) -{ - // make sure we don't try to update the streaming priority if an object - // was added and removed in the same frame - int nElementID = m_deferredRenderComponentStreamingPriorityUpdates.Find(pEnt); - if (nElementID != -1) - { - m_deferredRenderComponentStreamingPriorityUpdates.DeleteFastUnsorted(nElementID); - } - - FUNCTION_PROFILER_3DENGINE; - -#ifdef _DEBUG // crash test basically - const char* szClass = pEnt->GetEntityClassName(); - const char* szName = pEnt->GetName(); - if (!szName[0] && !szClass[0]) - { - Warning("C3DEngine::RegisterEntity: Entity undefined"); - } -#endif - - EERType eRenderNodeType = pEnt->GetRenderNodeType(); - - bool bFound = false; - - if (pEnt->m_pOcNode) - { - bFound = ((COctreeNode*)pEnt->m_pOcNode)->DeleteObject(pEnt); - } - - if (pEnt->m_dwRndFlags & ERF_RENDER_ALWAYS || (eRenderNodeType == eERType_Light) || (eRenderNodeType == eERType_FogVolume)) - { - m_lstAlwaysVisible.Delete(pEnt); - } - - if (eRenderNodeType == eERType_Decal) - { - std::vector::iterator it = std::find(m_decalRenderNodes.begin(), m_decalRenderNodes.end(), (IDecalRenderNode*)pEnt); - if (it != m_decalRenderNodes.end()) - { - m_decalRenderNodes.erase(it); - } - } - - if (CClipVolumeManager* pClipVolumeManager = GetClipVolumeManager()) - { - pClipVolumeManager->UnregisterRenderNode(pEnt); - } - - return bFound; -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 C3DEngine::GetEntityRegisterPoint(IRenderNode* pEnt) -{ - AABB aabb; - pEnt->FillBBox(aabb); - - Vec3 vPoint; - - if (pEnt->m_dwRndFlags & ERF_REGISTER_BY_POSITION) - { - vPoint = pEnt->GetPos(); - - if (pEnt->GetRenderNodeType() != eERType_Light) - { - // check for valid position - if (aabb.GetDistanceSqr(vPoint) > sqr(128.f)) - { - Warning("I3DEngine::RegisterEntity: invalid entity position: Name: %s, Class: %s, Pos=(%.1f,%.1f,%.1f), BoxMin=(%.1f,%.1f,%.1f), BoxMax=(%.1f,%.1f,%.1f)", - pEnt->GetName(), pEnt->GetEntityClassName(), - pEnt->GetPos().x, pEnt->GetPos().y, pEnt->GetPos().z, - pEnt->GetBBox().min.x, pEnt->GetBBox().min.y, pEnt->GetBBox().min.z, - pEnt->GetBBox().max.x, pEnt->GetBBox().max.y, pEnt->GetBBox().max.z - ); - } - // clamp by bbox - vPoint.CheckMin(aabb.max); - vPoint.CheckMax(aabb.min + Vec3(0, 0, .5f)); - } - } - else - { - vPoint = aabb.GetCenter(); - } - - return vPoint; -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 C3DEngine::GetSunDirNormalized() const -{ - return m_vSunDirNormalized; -} - - diff --git a/Code/CryEngine/Cry3DEngine/3dEngine.cpp b/Code/CryEngine/Cry3DEngine/3dEngine.cpp deleted file mode 100644 index 1050916423..0000000000 --- a/Code/CryEngine/Cry3DEngine/3dEngine.cpp +++ /dev/null @@ -1,5536 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of I3DEngine interface methods - - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" - -#include -#include -#include -#include "VisAreas.h" -#include "ObjMan.h" -#include "Ocean.h" -#include -#include "DecalManager.h" -#include "IndexedMesh.h" - -#include "MatMan.h" - -#include "CullBuffer.h" -#include "CGF/CGFLoader.h" -#include "CGF/ChunkFileWriters.h" -#include "CGF/ReadOnlyChunkFile.h" - -#include "CloudRenderNode.h" -#include "CloudsManager.h" -#include "SkyLightManager.h" -#include "FogVolumeRenderNode.h" -#include "DecalRenderNode.h" -#include "TimeOfDay.h" -#include "LightEntity.h" -#include "FogVolumeRenderNode.h" -#include "ObjectsTree.h" -#include "WaterVolumeRenderNode.h" -#include "DistanceCloudRenderNode.h" -#include "VolumeObjectRenderNode.h" -#include "RenderMeshMerger.h" -#include "DeferredCollisionEvent.h" -#include "OpticsManager.h" -#include "GeomCacheRenderNode.h" -#include "GeomCacheManager.h" -#include "ClipVolumeManager.h" -#include -#include "PostEffectGroup.h" -#include "MainThreadRenderRequestBus.h" -#include "ObjMan.h" -#include "Environment/OceanEnvironmentBus.h" -#include -#include - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) -#include "PrismRenderNode.h" -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - -#include -#include -#include -#include -#include -#include - -#include - -// required for LARGE_INTEGER used by QueryPerformanceCounter -#ifdef WIN32 -#include -#endif - -threadID Cry3DEngineBase::m_nMainThreadId = 0; -bool Cry3DEngineBase::m_bRenderTypeEnabled[eERType_TypesNum]; -ISystem* Cry3DEngineBase::m_pSystem = 0; -IRenderer* Cry3DEngineBase::m_pRenderer = 0; -ITimer* Cry3DEngineBase::m_pTimer = 0; -ILog* Cry3DEngineBase::m_pLog = 0; - -COcean* Cry3DEngineBase::m_pOcean = nullptr; -CObjManager* Cry3DEngineBase::m_pObjManager = 0; -IConsole* Cry3DEngineBase::m_pConsole = 0; -C3DEngine* Cry3DEngineBase::m_p3DEngine = 0; -CVars* Cry3DEngineBase::m_pCVars = 0; -AZ::IO::IArchive* Cry3DEngineBase::m_pCryPak = nullptr; -IOpticsManager* Cry3DEngineBase::m_pOpticsManager = 0; -CDecalManager* Cry3DEngineBase::m_pDecalManager = 0; -CSkyLightManager* Cry3DEngineBase::m_pSkyLightManager = 0; -CCloudsManager* Cry3DEngineBase::m_pCloudsManager = 0; -CVisAreaManager* Cry3DEngineBase::m_pVisAreaManager = 0; -CClipVolumeManager* Cry3DEngineBase::m_pClipVolumeManager = 0; -CRenderMeshMerger* Cry3DEngineBase::m_pRenderMeshMerger = 0; -CMatMan* Cry3DEngineBase::m_pMatMan = 0; -IStreamedObjectListener* Cry3DEngineBase::m_pStreamListener = 0; -#if defined(USE_GEOM_CACHES) -CGeomCacheManager* Cry3DEngineBase::m_pGeomCacheManager = 0; -#endif - -bool Cry3DEngineBase::m_bLevelLoadingInProgress = false; -bool Cry3DEngineBase::m_bIsInRenderScene = false; - -int Cry3DEngineBase::m_CpuFlags = 0; -#if !defined(CONSOLE) -bool Cry3DEngineBase::m_bEditor = false; -#endif //!defined(CONSOLE) -ESystemConfigSpec Cry3DEngineBase::m_LightConfigSpec = CONFIG_VERYHIGH_SPEC; -int Cry3DEngineBase::m_arrInstancesCounter[eERType_TypesNum]; - -#define LAST_POTENTIALLY_VISIBLE_TIME 2 - -namespace -{ - class CLoadLogListener - : public ILoaderCGFListener - { - public: - virtual ~CLoadLogListener(){} - virtual void Warning(const char* format) {Cry3DEngineBase::Warning("%s", format); } - virtual void Error(const char* format) {Cry3DEngineBase::Error("%s", format); } - virtual bool IsValidationEnabled() { return Cry3DEngineBase::GetCVars()->e_StatObjValidate != 0; } - }; -} - -namespace OceanGlobals -{ - float g_oceanLevel = 0.0f; - float g_oceanStep = 1.0f; - AZStd::recursive_mutex g_oceanParamsMutex; -} - -////////////////////////////////////////////////////////////////////// -C3DEngine::C3DEngine(ISystem* pSystem) -{ - //#if defined(_DEBUG) && defined(WIN32) - // _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - //#endif - - // Level info - m_fSunSpecMult = 1.f; - m_bAreaActivationInUse = false; - - Cry3DEngineBase::m_nMainThreadId = CryGetCurrentThreadId(); - Cry3DEngineBase::m_pSystem = pSystem; - Cry3DEngineBase::m_pRenderer = gEnv->pRenderer; - Cry3DEngineBase::m_pTimer = gEnv->pTimer; - Cry3DEngineBase::m_pLog = gEnv->pLog; - Cry3DEngineBase::m_pConsole = gEnv->pConsole; - Cry3DEngineBase::m_p3DEngine = this; - Cry3DEngineBase::m_pCryPak = gEnv->pCryPak; - Cry3DEngineBase::m_pCVars = 0; - Cry3DEngineBase::m_pRenderMeshMerger = new CRenderMeshMerger; - Cry3DEngineBase::m_pMatMan = new CMatMan; - Cry3DEngineBase::m_pStreamListener = NULL; - Cry3DEngineBase::m_CpuFlags = pSystem->GetCPUFlags(); - - memset(Cry3DEngineBase::m_arrInstancesCounter, 0, sizeof(Cry3DEngineBase::m_arrInstancesCounter)); - -#if !defined(CONSOLE) - m_bEditor = gEnv->IsEditor(); -#endif - m_pObjectsTree = nullptr; - m_pCVars = new CVars(); - Cry3DEngineBase::m_pCVars = m_pCVars; - - m_pTimeOfDay = NULL; - - m_postEffectGroups = std::make_unique(); - m_postEffectBaseGroup = m_postEffectGroups->GetGroup("Base"); - if (IPostEffectGroup* pPostEffectsDefaultGroup = m_postEffectGroups->GetGroup(m_defaultPostEffectGroup)) - { - pPostEffectsDefaultGroup->SetEnable(true); - } - - m_szLevelFolder[0] = 0; - - m_pSun = 0; - m_nFlags = 0; - m_pSkyMat = 0; - m_pSkyLowSpecMat = 0; - m_pTerrainWaterMat = 0; - m_nWaterBottomTexId = 0; - m_vSunDir = Vec3(5.f, 5.f, DISTANCE_TO_THE_SUN); - m_vSunDirRealtime = Vec3(5.f, 5.f, DISTANCE_TO_THE_SUN).GetNormalized(); - - m_nBlackTexID = 0; - - // create components - m_pObjManager = CryAlignedNew(); - - m_pDecalManager = 0;//new CDecalManager (m_pSystem, this); - m_pCloudsManager = new CCloudsManager; - m_pOpticsManager = 0; - m_pVisAreaManager = 0; - m_pClipVolumeManager = new CClipVolumeManager(); - m_pSkyLightManager = CryAlignedNew(); - - // create REs - m_pRESky = 0; - m_pREHDRSky = 0; - - m_pPhysMaterialEnumerator = 0; - - m_fMaxViewDistHighSpec = 8000; - m_fMaxViewDistLowSpec = 1000; - - m_fSkyBoxAngle = 0; - m_fSkyBoxStretching = 0; - - - m_physicsAreaUpdatesHandler = AZStd::make_unique(m_PhysicsAreaUpdates); - - m_bOcean = true; - m_nOceanRenderFlags = 0; - - m_bSunShadows = true; - m_nSunAdditionalCascades = 0; - m_CachedShadowsBounds.Reset(); - m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate; - - m_fSunClipPlaneRange = 256.0f; - m_fSunClipPlaneRangeShift = 0.0f; - - m_nRealLightsNum = m_nDeferredLightsNum = 0; - - m_pCoverageBuffer = CryAlignedNew(); - - m_fLightsHDRDynamicPowerFactor = 0.0f; - - m_vHDRFilmCurveParams = Vec4(1.0f, 1.0f, 1.0f, 1.0f); - m_vHDREyeAdaptation = Vec3(0.05f, 0.8f, 0.9f); - m_fHDRBloomAmount = 0.0f; - m_vColorBalance = Vec3(1.0f, 1.0f, 1.0f); - m_fHDRSaturation = 1.0f; - - m_vSkyHightlightPos.Set(0, 0, 0); - m_vSkyHightlightCol.Set(0, 0, 0); - m_fSkyHighlightSize = 0; - - m_volFogGlobalDensity = 0.02f; - m_volFogGlobalDensityMultiplierLDR = 1.0f; - m_volFogFinalDensityClamp = 1.0f; - - m_idMatLeaves = -1; - - m_oceanFogColor = 0.2f * Vec3(29.0f, 102.0f, 141.0f) / 255.0f; - m_oceanFogColorShallow = Vec3(0, 0, 0); //0.5f * Vec3( 206.0f, 249.0f, 253.0f ) / 255.0f; - m_oceanFogDensity = 0; //0.2f; - - m_oceanCausticsDistanceAtten = 100.0f; - - m_oceanCausticDepth = 8.0f; - m_oceanCausticIntensity = 1.0f; - - m_oceanWindDirection = 1; - m_oceanWindSpeed = 4.0f; - m_oceanWavesSpeed = 1.0f; - m_oceanWavesAmount = 1.5f; - m_oceanWavesSize = 0.75f; - - m_fParticlesAmbientMultiplier = m_fParticlesLightMultiplier = 1.f; - m_fRefreshSceneDataCVarsSumm = -1; - m_nRenderTypeEnableCVarSum = -1; - - if (!m_LTPRootFree.pNext) - { - m_LTPRootFree.pNext = &m_LTPRootFree; - m_LTPRootFree.pPrev = &m_LTPRootFree; - } - - if (!m_LTPRootUsed.pNext) - { - m_LTPRootUsed.pNext = &m_LTPRootUsed; - m_LTPRootUsed.pPrev = &m_LTPRootUsed; - } - m_bResetRNTmpDataPool = false; - - m_fSunDirUpdateTime = 0; - m_vSunDirNormalized.zero(); - - m_volFogRamp = Vec3(0, 100.0f, 0); - m_volFogShadowRange = Vec3(0.1f, 0, 0); - m_volFogShadowDarkening = Vec3(0.25f, 1, 1); - m_volFogShadowEnable = Vec3(0, 0, 0); - m_volFog2CtrlParams = Vec3(64.0f, 0.0f, 1.0f); - m_volFog2ScatteringParams = Vec3(1.0f, 0.3f, 0.6f); - m_volFog2Ramp = Vec3(0.0f, 0.0f, 0.0f); - m_volFog2Color = Vec3(1.0f, 1.0f, 1.0f); - m_volFog2GlobalDensity = Vec3(0.1f, 1.0f, 0.4f); - m_volFog2HeightDensity = Vec3(0.0f, 1.0f, 0.1f); - m_volFog2HeightDensity2 = Vec3(4000.0f, 0.0001f, 0.95f); - m_volFog2Color1 = Vec3(1.0f, 1.0f, 1.0f); - m_volFog2Color2 = Vec3(1.0f, 1.0f, 1.0f); - m_nightSkyHorizonCol = Vec3(0, 0, 0); - m_nightSkyZenithCol = Vec3(0, 0, 0); - m_nightSkyZenithColShift = 0; - m_nightSkyStarIntensity = 0; - m_moonDirection = Vec3(0, 0, 0); - m_nightMoonCol = Vec3(0, 0, 0); - m_nightMoonSize = 0; - m_nightMoonInnerCoronaCol = Vec3(0, 0, 0); - m_nightMoonInnerCoronaScale = 1.0f; - m_nightMoonOuterCoronaCol = Vec3(0, 0, 0); - m_nightMoonOuterCoronaScale = 1.0f; - m_moonRotationLatitude = 0; - m_moonRotationLongitude = 0; - m_skyboxMultiplier = 1.0f; - m_dayNightIndicator = 1.0f; - m_fogColor2 = Vec3(0, 0, 0); - m_fogColorRadial = Vec3(0, 0, 0); - m_volFogHeightDensity = Vec3(0, 1, 0); - m_volFogHeightDensity2 = Vec3(4000.0f, 0, 0); - m_volFogGradientCtrl = Vec3(1, 1, 1); - - m_vFogColor = Vec3(1.0f, 1.0f, 1.0f); - m_vAmbGroundCol = Vec3(0.0f, 0.0f, 0.0f); - - m_dawnStart = 350.0f / 60.0f; - m_dawnEnd = 360.0f / 60.0f; - m_duskStart = 12.0f + 360.0f / 60.0f; - m_duskEnd = 12.0f + 370.0f / 60.0f; - - m_fCloudShadingSunLightMultiplier = 0; - m_fCloudShadingSkyLightMultiplier = 0; - m_vCloudShadingCustomSunColor = Vec3(0, 0, 0); - m_vCloudShadingCustomSkyColor = Vec3(0, 0, 0); - - m_vPrevMainFrameCamPos.Set(-1000000.f, -1000000.f, -1000000.f); - m_fAverageCameraSpeed = 0; - m_vAverageCameraMoveDir = Vec3(0); - m_bContentPrecacheRequested = false; - m_bTerrainTextureStreamingInProgress = false; - m_bLayersActivated = false; - m_eShadowMode = ESM_NORMAL; - - ClearDebugFPSInfo(); - - m_fMaxViewDistScale = 1.f; - - m_ptexIconLowMemoryUsage = NULL; - m_ptexIconAverageMemoryUsage = NULL; - m_ptexIconHighMemoryUsage = NULL; - m_ptexIconEditorConnectedToConsole = NULL; - m_pScreenshotCallback = 0; - m_bInShutDown = false; - m_bInUnload = false; - m_bInLoad = false; - - m_nCloudShadowTexId = 0; - - m_nNightMoonTexId = 0; - - m_pDeferredPhysicsEventManager = new CDeferredPhysicsEventManager(); - -#if defined(USE_GEOM_CACHES) - m_pGeomCacheManager = new CGeomCacheManager(); -#endif - - m_LightVolumesMgr.Init(); - - m_pBreakableBrushHeap = NULL; - - m_nWindSamplePositions = 0; - m_pWindSamplePositions = NULL; - - m_fZoomFactor = 0.0f; - - m_fAmbMaxHeight = 0.0f; - m_fAmbMinHeight = 0.0f; - - m_pLightQuality = NULL; - m_fSaturation = 0.0f; - - m_fGsmRange = 0.0f; - m_fGsmRangeStep = 0.0f; - m_fShadowsConstBias = 0.0f; - m_fShadowsSlopeBias = 0.0f; - m_nCustomShadowFrustumCount = 0; - m_bHeightMapAoEnabled = false; - - m_bendingPoolIdx = 0; - m_levelLoaded = false; -} - -////////////////////////////////////////////////////////////////////// -C3DEngine::~C3DEngine() -{ - m_bInShutDown = true; - m_bInUnload = true; - m_bInLoad = false; - - CheckMemoryHeap(); - - ShutDown(); - - delete m_pTimeOfDay; - delete m_pDecalManager; - delete m_pVisAreaManager; - SAFE_DELETE(m_pClipVolumeManager); - - CryAlignedDelete(m_pCoverageBuffer); - m_pCoverageBuffer = 0; - CryAlignedDelete(m_pSkyLightManager); - m_pSkyLightManager = 0; - SAFE_DELETE(m_pObjectsTree); - // delete m_pSceneTree; - delete m_pRenderMeshMerger; - delete m_pMatMan; - m_pMatMan = 0; - delete m_pCloudsManager; - - delete m_pCVars; - - delete m_pDeferredPhysicsEventManager; -} - -bool C3DEngine::CheckMinSpec(uint32 nMinSpec) -{ - return Cry3DEngineBase::CheckMinSpec(nMinSpec); -} - -bool C3DEngine::Init() -{ - m_pOpticsManager = new COpticsManager; - m_pSystem->SetIOpticsManager(m_pOpticsManager); - - for (int i = 0; i < eERType_TypesNum; i++) - { - m_bRenderTypeEnabled[i] = true; - } - - UpdateRenderTypeEnableLookup(); - - // Allocate the temporary pool used for allocations during streaming and loading - const size_t tempPoolSize = static_cast(GetCVars()->e_3dEngineTempPoolSize) << 10; - AZ_Assert(tempPoolSize != 0, "Temp pool size should not be 0."); - - { - if (!CTemporaryPool::Initialize(tempPoolSize)) - { - AZ_Assert(false, "Could not initialize initialize temporary pool for 3D Engine startup."); - return false; - } - } - - SFrameLodInfo frameLodInfo; - frameLodInfo.fLodRatio = GetCVars()->e_LodRatio; - - frameLodInfo.fTargetSize = GetCVars()->e_LodFaceAreaTargetSize; - AZ_Assert(frameLodInfo.fTargetSize > 0.f, "FrameLodInfo target size should be greater than 0."); - if (frameLodInfo.fTargetSize <= 0.f) - { - frameLodInfo.fTargetSize = 1.f; - } - - frameLodInfo.nMinLod = GetCVars()->e_LodMin; - frameLodInfo.nMaxLod = GetCVars()->e_LodMax; - if (GetCVars()->e_Lods == 0) - { - frameLodInfo.nMinLod = 0; - frameLodInfo.nMaxLod = 0; - } - SetFrameLodInfo(frameLodInfo); - - return true; -} - -bool C3DEngine::IsCameraAnd3DEngineInvalid(const SRenderingPassInfo& passInfo, const char* szCaller) -{ - const CCamera& rCamera = passInfo.GetCamera(); - const float MAX_M23_REPORTED = 3000000.f; // MAT => upped from 100,000 which spammed this message on spear and cityhall. Really should stop editor generating - // water levels that trigger this message. - - if (!_finite(rCamera.GetMatrix().m03) || !_finite(rCamera.GetMatrix().m13) || !_finite(rCamera.GetMatrix().m23) || GetMaxViewDistance() <= 0 || - rCamera.GetMatrix().m23 < -MAX_M23_REPORTED || rCamera.GetMatrix().m23 > MAX_M23_REPORTED || rCamera.GetFov() < 0.0001f || rCamera.GetFov() > gf_PI) - { - Error("Bad camera passed to 3DEngine from %s: Pos=(%.1f, %.1f, %.1f), Fov=%.1f, MaxViewDist=%.1f. Maybe the water level is too extreme.", - szCaller, - rCamera.GetMatrix().m03, rCamera.GetMatrix().m13, rCamera.GetMatrix().m23, - rCamera.GetFov(), _finite(rCamera.GetMatrix().m03) ? GetMaxViewDistance() : 0); - return true; - } - - return false; -} - -void C3DEngine::OnFrameStart() -{ - FUNCTION_PROFILER_3DENGINE; - - m_nRenderWorldUSecs = 0; - m_pDeferredPhysicsEventManager->Update(); - - m_bendingPoolIdx = (m_bendingPoolIdx + 1) % NUM_BENDING_POOLS; - m_bendingPool[m_bendingPoolIdx].resize(0); - -#if defined(USE_GEOM_CACHES) - if (!gEnv->IsDedicated()) - { - if (m_pGeomCacheManager) - { - m_pGeomCacheManager->StreamingUpdate(); - } - } -#endif - //update texture load handlers - for (TTextureLoadHandlers::iterator iter = m_textureLoadHandlers.begin(); iter != m_textureLoadHandlers.end(); iter++) - { - (*iter)->Update(); - } -} - -float GetOceanLevelCallback(int ix, int iy) -{ - using namespace OceanGlobals; - return OceanToggle::IsActive() ? OceanRequest::GetAccurateOceanHeight(Vec3(ix * g_oceanStep, iy * g_oceanStep, g_oceanLevel)) : gEnv->p3DEngine->GetAccurateOceanHeight(Vec3(ix * g_oceanStep, iy * g_oceanStep, g_oceanLevel)); -} - -unsigned char GetOceanSurfTypeCallback([[maybe_unused]] int ix, [[maybe_unused]] int iy) -{ - return 0; -} - -void C3DEngine::Update() -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - ProcessAsyncStaticObjectLoadRequests(); - - m_LightConfigSpec = (ESystemConfigSpec)GetCurrentLightSpec(); - - if (GetObjManager()) - { - GetObjManager()->ClearStatObjGarbage(); - } - - if (m_pDecalManager) - { - m_pDecalManager->Update(GetTimer()->GetFrameTime()); - } - - if (GetCVars()->e_PrecacheLevel == 3) - { - PrecacheLevel(true, 0, 0); - } - - DebugDraw_Draw(); - - ProcessCVarsChange(); - - { - using namespace OceanGlobals; - AZStd::lock_guard lock(g_oceanParamsMutex); - - g_oceanLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : GetWaterLevel(); - } - - CRenderMeshUtils::ClearHitCache(); - - CleanUpOldDecals(); - - CDecalRenderNode::ResetDecalUpdatesCounter(); - - - if (m_pBreakableBrushHeap) - { - m_pBreakableBrushHeap->Cleanup(); - } - - // make sure all jobs from the previous frame have finished - threadID nThreadID; - gEnv->pRenderer->EF_Query(EFQ_RenderThreadList, nThreadID); - gEnv->pRenderer->GetFinalizeRendItemJobExecutor(nThreadID)->WaitForCompletion(); - gEnv->pRenderer->GetFinalizeShadowRendItemJobExecutor(nThreadID)->WaitForCompletion(); - - UpdateRNTmpDataPool(m_bResetRNTmpDataPool); - m_bResetRNTmpDataPool = false; - - m_PhysicsAreaUpdates.GarbageCollect(); -} - -void C3DEngine::Tick() -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - // make sure all jobs from the previous frame have finished (also in Tick since Update is not called during loading) - threadID nThreadID = 0; - gEnv->pRenderer->EF_Query(EFQ_RenderThreadList, nThreadID); - gEnv->pRenderer->GetFinalizeRendItemJobExecutor(nThreadID)->WaitForCompletion(); - gEnv->pRenderer->GetFinalizeShadowRendItemJobExecutor(nThreadID)->WaitForCompletion(); - - AZ::MainThreadRenderRequestBus::ExecuteQueuedEvents(); - - AZ::MaterialNotificationEventBus::ExecuteQueuedEvents(); - - // clear stored cameras from last frame - m_RenderingPassCameras[nThreadID].resize(0); -} - - -void C3DEngine::ProcessCVarsChange() -{ - static int nObjectLayersActivation = -1; - - if (nObjectLayersActivation != GetCVars()->e_ObjectLayersActivation) - { - if (GetCVars()->e_ObjectLayersActivation == 2) - { - ActivateObjectsLayer(~0, true, true, true, true, "ALL_OBJECTS"); - } - if (GetCVars()->e_ObjectLayersActivation == 3) - { - ActivateObjectsLayer(~0, false, true, true, true, "ALL_OBJECTS"); - } - - nObjectLayersActivation = GetCVars()->e_ObjectLayersActivation; - } - - float fNewCVarsSumm = - GetCVars()->e_ShadowsCastViewDistRatio + - GetCVars()->e_Dissolve + - GetFloatCVar(e_DissolveDistMin) + - GetFloatCVar(e_DissolveDistMax) + - GetFloatCVar(e_DissolveDistband) + - GetCVars()->e_ViewDistRatio + - GetCVars()->e_ViewDistMin + - GetCVars()->e_ViewDistRatioDetail + - GetCVars()->e_DefaultMaterial + - GetGeomDetailScreenRes() + - GetCVars()->e_Portals + - GetCVars()->e_DebugDraw + - GetFloatCVar(e_ViewDistCompMaxSize) + - GetCVars()->e_DecalsDefferedStatic + - GetRenderer()->GetWidth(); - - if (m_fRefreshSceneDataCVarsSumm != -1 && m_fRefreshSceneDataCVarsSumm != fNewCVarsSumm) - { - UpdateStatInstGroups(); - - AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); - float terrainSize = AZ::GetMax(terrainAabb.GetXExtent(), terrainAabb.GetYExtent()); - - // re-register every instance in level - constexpr float UNREASONABLY_SMALL_TERRAIN_SIZE = 1.0f; - constexpr float VERY_LARGE_TERRAIN_SIZE = 16.0f * 1024.0f; - if (terrainSize < UNREASONABLY_SMALL_TERRAIN_SIZE) - { - //Only happens when the runtime terrain system was excluded from this build. - terrainSize = VERY_LARGE_TERRAIN_SIZE; - } - GetObjManager()->ReregisterEntitiesInArea( - Vec3(-terrainSize, -terrainSize, -terrainSize), - Vec3(terrainSize * 2.f, terrainSize * 2.f, terrainSize * 2.f)); - - // refresh vegetation properties - UpdateStatInstGroups(); - - // force refresh of temporary data associated with visible objects - MarkRNTmpDataPoolForReset(); - } - - m_fRefreshSceneDataCVarsSumm = fNewCVarsSumm; - - int nRenderTypeEnableCVarSum = - (GetCVars()->e_Entities << 2); - - if (m_nRenderTypeEnableCVarSum != nRenderTypeEnableCVarSum) - { - m_nRenderTypeEnableCVarSum = nRenderTypeEnableCVarSum; - - UpdateRenderTypeEnableLookup(); - } - - { - float fNewCVarsSumm2 = - GetCVars()->e_LodRatio; - - static float fCVarsSumm2 = fNewCVarsSumm2; - - if (fCVarsSumm2 != fNewCVarsSumm2) - { - MarkRNTmpDataPoolForReset(); - - fCVarsSumm2 = fNewCVarsSumm2; - } - } - - SFrameLodInfo frameLodInfo; - frameLodInfo.fLodRatio = GetCVars()->e_LodRatio; - - frameLodInfo.fTargetSize = GetCVars()->e_LodFaceAreaTargetSize; - CRY_ASSERT(frameLodInfo.fTargetSize > 0.f); - if (frameLodInfo.fTargetSize <= 0.f) - { - frameLodInfo.fTargetSize = 1.f; - } - - frameLodInfo.nMinLod = GetCVars()->e_LodMin; - frameLodInfo.nMaxLod = GetCVars()->e_LodMax; - if (GetCVars()->e_Lods == 0) - { - frameLodInfo.nMinLod = 0; - frameLodInfo.nMaxLod = 0; - } - SetFrameLodInfo(frameLodInfo); -} - -////////////////////////////////////////////////////////////////////// -void C3DEngine::ShutDown() -{ - if (GetRenderer() != GetSystem()->GetIRenderer()) - { - CryFatalError("Renderer was deallocated before I3DEngine::ShutDown() call"); - } - - UnlockCGFResources(); - - UnloadLevel(); - -#if defined(USE_GEOM_CACHES) - delete m_pGeomCacheManager; - m_pGeomCacheManager = 0; -#endif - - if (m_pOpticsManager) - { - delete m_pOpticsManager; - m_pOpticsManager = 0; - m_pSystem->SetIOpticsManager(m_pOpticsManager); - } - - CryAlignedDelete(m_pObjManager); - m_pObjManager = 0; - - - // Free the temporary pool's underlying storage - // and reset the pool - if (!CTemporaryPool::Shutdown()) - { - CryFatalError("C3DEngine::Shutdown() could not shutdown temporary pool"); - } - - COctreeNode::Shutdown(); -} - -#ifndef _RELEASE -void C3DEngine::ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOut, const SRenderingPassInfo& passInfo) -{ - static float fSQTestOffset = 0; - static PodArray arrTestTextures; - static ITexture* pTestTexture = 0; - static ITexture* pLastNotReadyTexture = 0; - static float fStartTime = 0; - static float fDelayStartTime = 0; - static size_t nMaxTexUsage = 0; - - static int nOpenRequestCount = 0; - SStreamEngineOpenStats stats; - gEnv->pSystem->GetStreamEngine()->GetStreamingOpenStatistics(stats); - if (stats.nOpenRequestCount > nOpenRequestCount) - { - nOpenRequestCount = stats.nOpenRequestCount; - } - else - { - nOpenRequestCount = max(0, nOpenRequestCount + stats.nOpenRequestCount) / 2; - } - - ICVar* pTSFlush = GetConsole()->GetCVar("r_TexturesStreamingDebug"); - - if (GetCVars()->e_SQTestBegin == 1) - { // Init waiting few seconds until streaming is stabilized and all required textures are loaded - PrintMessage("======== Starting streaming latency test ========"); - fDelayStartTime = GetCurTimeSec(); - nMaxTexUsage = 0; - GetCVars()->e_SQTestBegin = 2; - PrintMessage("Waiting %.1f seconds and zero requests and no camera movement", GetCVars()->e_SQTestDelay); - - if (ICVar* pPart = GetConsole()->GetCVar("e_Particles")) - { - pPart->Set(0); - } - if (ICVar* pAI = GetConsole()->GetCVar("sys_AI")) - { - pAI->Set(0); - } - } - else if (GetCVars()->e_SQTestBegin == 2) - { // Perform waiting - if (GetCurTimeSec() - fDelayStartTime > GetCVars()->e_SQTestDelay && !nOpenRequestCount && m_fAverageCameraSpeed < .01f) - { - pTSFlush->Set(0); - GetCVars()->e_SQTestBegin = 3; - } - else - { - pTSFlush->Set(3); - } - } - else if (GetCVars()->e_SQTestBegin == 3) - { // Build a list of all important loaded textures - PrintMessage("Collect information about loaded textures"); - - fSQTestOffset = (float)GetCVars()->e_SQTestDistance; - - arrTestTextures.Clear(); - SRendererQueryGetAllTexturesParam param; - - GetRenderer()->EF_Query(EFQ_GetAllTextures, param); - if (param.pTextures) - { - for (uint32 i = 0; i < param.numTextures; i++) - { - ITexture* pTexture = param.pTextures[i]; - if (pTexture->GetAccessFrameId() > (int)(passInfo.GetMainFrameID() - 4)) - { - if (pTexture->GetMinLoadedMip() <= GetCVars()->e_SQTestMip) - { - if (pTexture->IsStreamable()) - { - if (pTexture->GetWidth() * pTexture->GetHeight() >= 256 * 256) - { - arrTestTextures.Add(pTexture); - - if (strstr(pTexture->GetName(), GetCVars()->e_SQTestTextureName->GetString())) - { - pTestTexture = pTexture; - PrintMessage("Test texture name: %s", pTexture->GetName()); - } - } - } - } - } - } - } - - GetRenderer()->EF_Query(EFQ_GetAllTexturesRelease, param); - - PrintMessage("%d test textures found", arrTestTextures.Count()); - - PrintMessage("Teleporting camera to offset position"); - - GetCVars()->e_SQTestBegin = 4; - } - else if (GetCVars()->e_SQTestBegin == 4) - { // Init waiting few seconds until streaming is stabilized and all required textures are loaded - fDelayStartTime = GetCurTimeSec(); - GetCVars()->e_SQTestBegin = 5; - PrintMessage("Waiting %.1f seconds and zero requests and no camera movement", GetCVars()->e_SQTestDelay); - } - else if (GetCVars()->e_SQTestBegin == 5) - { // Move camera to offset position and perform waiting - Matrix34 mat = camIn.GetMatrix(); - Vec3 vPos = camIn.GetPosition() - camIn.GetViewdir() * fSQTestOffset; - mat.SetTranslation(vPos); - camOut.SetMatrix(mat); - - if (GetCurTimeSec() - fDelayStartTime > GetCVars()->e_SQTestDelay && !nOpenRequestCount && m_fAverageCameraSpeed < .01f) - { - PrintMessage("Begin camera movement"); - GetCVars()->e_SQTestBegin = 6; - pTSFlush->Set(0); - } - else - { - pTSFlush->Set(3); - } - } - else if (GetCVars()->e_SQTestBegin == 6) - { // Process camera movement from offset position to test point - Matrix34 mat = camIn.GetMatrix(); - Vec3 vPos = camIn.GetPosition() - camIn.GetViewdir() * fSQTestOffset; - mat.SetTranslation(vPos); - camOut.SetMatrix(mat); - - fSQTestOffset -= GetTimer()->GetFrameTime() * (float)GetCVars()->e_SQTestMoveSpeed; - - STextureStreamingStats statsTex(true); - m_pRenderer->EF_Query(EFQ_GetTexStreamingInfo, statsTex); - nMaxTexUsage = max(nMaxTexUsage, statsTex.nRequiredStreamedTexturesSize); - - if (fSQTestOffset <= 0) - { - PrintMessage("Finished camera movement"); - fStartTime = GetCurTimeSec(); - PrintMessage("Waiting for %d textures to stream in ...", arrTestTextures.Count()); - - GetCVars()->e_SQTestBegin = 7; - pLastNotReadyTexture = 0; - } - } - else if (GetCVars()->e_SQTestBegin == 7) - { // Wait until test all needed textures are loaded again - STextureStreamingStats statsTex(true); - m_pRenderer->EF_Query(EFQ_GetTexStreamingInfo, statsTex); - nMaxTexUsage = max(nMaxTexUsage, statsTex.nRequiredStreamedTexturesSize); - - if (pTestTexture) - { - if (pTestTexture->GetMinLoadedMip() <= GetCVars()->e_SQTestMip) - { - PrintMessage("BINGO: Selected test texture loaded in %.1f sec", GetCurTimeSec() - fStartTime); - pTestTexture = NULL; - if (!arrTestTextures.Count()) - { - GetCVars()->e_SQTestBegin = 0; - GetConsole()->GetCVar("e_SQTestBegin")->Set(0); - } - } - } - - if (arrTestTextures.Count()) - { - int nFinishedNum = 0; - for (int i = 0; i < arrTestTextures.Count(); i++) - { - if (arrTestTextures[i]->GetMinLoadedMip() <= GetCVars()->e_SQTestMip) - { - nFinishedNum++; - } - else - { - pLastNotReadyTexture = arrTestTextures[i]; - } - } - - if (nFinishedNum == arrTestTextures.Count()) - { - PrintMessage("BINGO: %d of %d test texture loaded in %.1f sec", nFinishedNum, arrTestTextures.Count(), GetCurTimeSec() - fStartTime); - if (pLastNotReadyTexture) - { - PrintMessage("LastNotReadyTexture: %s [%d x %d]", pLastNotReadyTexture->GetName(), pLastNotReadyTexture->GetWidth(), pLastNotReadyTexture->GetHeight()); - } - PrintMessage("MaxTexUsage: %" PRISIZE_T " MB", nMaxTexUsage / 1024 / 1024); - arrTestTextures.Clear(); - - GetCVars()->e_SQTestBegin = 0; - GetConsole()->GetCVar("e_SQTestBegin")->Set(0); - - m_arrProcessStreamingLatencyTestResults.Add(GetCurTimeSec() - fStartTime); - m_arrProcessStreamingLatencyTexNum.Add(nFinishedNum); - - if (GetCVars()->e_SQTestCount == 0) - { - const char* testResultsFile = "@usercache@/TestResults/Streaming_Latency_Test.xml"; - - AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb"); - if (resultsFile != AZ::IO::InvalidHandle) - { - float fAverTime = 0; - for (int i = 0; i < m_arrProcessStreamingLatencyTestResults.Count(); i++) - { - fAverTime += m_arrProcessStreamingLatencyTestResults[i]; - } - fAverTime /= m_arrProcessStreamingLatencyTestResults.Count(); - - int nAverTexNum = 0; - for (int i = 0; i < m_arrProcessStreamingLatencyTexNum.Count(); i++) - { - nAverTexNum += m_arrProcessStreamingLatencyTexNum[i]; - } - nAverTexNum /= m_arrProcessStreamingLatencyTexNum.Count(); - - AZ::IO::Print(resultsFile, "\n" - "\n" - "\n" - "\n" - "\n" - "\n", - fAverTime, - nAverTexNum); - gEnv->pCryPak->FClose(resultsFile); - } - - if (GetCVars()->e_SQTestExitOnFinish) - { - GetSystem()->Quit(); - } - } - } - else if ((passInfo.GetMainFrameID() & 31) == 0) - { - PrintMessage("Waiting: %d of %d test texture loaded in %.1f sec", nFinishedNum, arrTestTextures.Count(), GetCurTimeSec() - fStartTime); - } - } - } -} -#endif - -////////////////////////////////////////////////////////////////////// -void C3DEngine::UpdateRenderingCamera([[maybe_unused]] const char* szCallerName, const SRenderingPassInfo& passInfo) -{ - CCamera newCam = passInfo.GetCamera(); - - if (passInfo.IsGeneralPass()) - { - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::UpdateVoxelData); - } - - if IsCVarConstAccess(constexpr) (bool(GetFloatCVar(e_CameraRotationSpeed))) - { - Matrix34 mat = passInfo.GetCamera().GetMatrix(); - Matrix33 matRot; - matRot.SetRotationZ(-GetCurTimeSec() * GetFloatCVar(e_CameraRotationSpeed)); - newCam.SetMatrix(mat * matRot); - } - -#if !defined(_RELEASE) - - { - //this feature move the camera along with the player to a certain position and sets the angle accordingly - // (does not work via goto) - //u can switch it off again via e_CameraGoto 0 - const char* const pCamGoto = GetCVars()->e_CameraGoto->GetString(); - assert(pCamGoto); - if (strlen(pCamGoto) > 1) - { - Ang3 aAngDeg; - Vec3 vPos; - int args = azsscanf(pCamGoto, "%f %f %f %f %f %f", &vPos.x, &vPos.y, &vPos.z, &aAngDeg.x, &aAngDeg.y, &aAngDeg.z); - if (args >= 3) - { - Vec3 curPos = newCam.GetPosition(); - if (fabs(vPos.x - curPos.x) > 10.f || fabs(vPos.y - curPos.y) > 10.f || fabs(vPos.z - curPos.z) > 10.f) - { - char buf[128]; - sprintf_s(buf, "goto %f %f %f", vPos.x, vPos.y, vPos.z); - gEnv->pConsole->ExecuteString(buf); - } - if (args >= 6) - { - Matrix34 mat = passInfo.GetCamera().GetMatrix(); - mat.SetTranslation(vPos); - mat.SetRotation33(Matrix33::CreateRotationXYZ(DEG2RAD(aAngDeg))); - newCam.SetMatrix(mat); - } - } - } - } - - // Streaming latency test - if (GetCVars()->e_SQTestCount && !GetCVars()->e_SQTestBegin) - { - GetConsole()->GetCVar("e_SQTestBegin")->Set(1); - GetConsole()->GetCVar("e_SQTestCount")->Set(GetCVars()->e_SQTestCount - 1); - } - if (GetCVars()->e_SQTestBegin) - { - ProcessStreamingLatencyTest(passInfo.GetCamera(), newCam, passInfo); - } - -#endif - - // set the camera if e_cameraFreeze is not set - if (GetCVars()->e_CameraFreeze || GetCVars()->e_CoverageBufferDebugFreeze) - { - DrawSphere(GetRenderingCamera().GetPosition(), .05f); - - // always set camera to request position for the renderer, allows debugging with e_camerafreeze - GetRenderer()->SetCamera(gEnv->pSystem->GetViewCamera()); - } - else - { - m_RenderingCamera = newCam; - // always set camera to request position for the renderer, allows debugging with e_camerafreeze - GetRenderer()->SetCamera(newCam); - } - - // now we have a valid camera, we can start generation of the occlusion buffer - // only needed for editor here, in game we spawn the job more early - if (passInfo.IsGeneralPass() && GetCVars()->e_StatObjBufferRenderTasks) - { - if (gEnv->IsEditor()) - { - GetObjManager()->PrepareCullbufferAsync(passInfo.GetCamera()); - } - else - { - assert(IsEquivalent(passInfo.GetCamera().GetViewdir(), GetObjManager()->GetCullThread().GetViewDir())); // early set camera differs from current main camera - will cause occlusion errors - } - } - - ///////////////////////////////////////////////////////////////////////////// - // update streaming priority of newly seen CComponentRenders (fix for streaming system issue) - for (int i = 0, nSize = m_deferredRenderComponentStreamingPriorityUpdates.size(); i < nSize; ++i) - { - IRenderNode* pRenderNode = m_deferredRenderComponentStreamingPriorityUpdates[i]; - AABB aabb = pRenderNode->GetBBox(); - const Vec3& vCamPos = GetRenderingCamera().GetPosition(); - float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, aabb)) * passInfo.GetZoomFactor(); - - GetObjManager()->UpdateRenderNodeStreamingPriority(pRenderNode, fEntDistance, 1.0f, false, passInfo); - if (GetCVars()->e_StreamCgfDebug == 2) - { - PrintMessage("C3DEngine::RegisterEntity__GetObjManager()->UpdateRenderNodeStreamingPriority %s", pRenderNode->GetName()); - } - } - m_deferredRenderComponentStreamingPriorityUpdates.resize(0); -} - -void C3DEngine::GetSvoStaticTextures(I3DEngine::SSvoStaticTexInfo& svoInfo, PodArray* pLightsTI_S, PodArray* pLightsTI_D) -{ - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::GetSvoStaticTextures, svoInfo, pLightsTI_S, pLightsTI_D); -} - -void C3DEngine::GetSvoBricksForUpdate(PodArray& arrNodeInfo, bool getDynamic) -{ - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::GetSvoBricksForUpdate, arrNodeInfo, getDynamic); -} - -#if defined(FEATURE_SVO_GI) -void C3DEngine::LoadTISettings(XmlNodeRef pInputNode) -{ - const char* szXmlNodeName = "Total_Illumination_v2"; - if (gEnv->pConsole->GetCVar("e_svoTI_Active")) - { - gEnv->pConsole->GetCVar("e_svoTI_Active")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "Active", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "InjectionMultiplier", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "NumberOfBounces", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_Saturation")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "Saturation", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_ConeMaxLength")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "ConeMaxLength", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_DiffuseConeWidth")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "DiffuseConeWidth", "0")); - - gEnv->pConsole->GetCVar("e_svoTI_SSAOAmount")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "SSAOAmount", "0")); - gEnv->pConsole->GetCVar("e_svoTI_UseLightProbes")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "UseLightProbes", "0")); - gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetRed")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "AmbientOffsetRed", "1")); - gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetGreen")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "AmbientOffsetGreen", "1")); - gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBlue")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "AmbientOffsetBlue", "1")); - gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBias")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "AmbientOffsetBias", ".1")); - - gEnv->pConsole->GetCVar("e_svoTI_IntegrationMode")->Set(GetXMLAttribText(pInputNode, szXmlNodeName, "IntegrationMode", "0")); - - if (gEnv->pConsole->GetCVar("e_svoTI_IntegrationMode")->GetIVal() < 1) // AO - { - gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->Set("1"); - } - } -} -#endif -void C3DEngine::PrepareOcclusion(const CCamera& rCamera) -{ - if (!gEnv->IsEditor() && GetCVars()->e_StatObjBufferRenderTasks && !gEnv->IsFMVPlaying() && (!IsEquivalent(rCamera.GetPosition(), Vec3(0, 0, 0), VEC_EPSILON) || GetRenderer()->IsPost3DRendererEnabled())) - { - GetObjManager()->PrepareCullbufferAsync(rCamera); - } -} - -void C3DEngine::EndOcclusion() -{ - GetObjManager()->EndOcclusionCulling(); -} - -IStatObj* C3DEngine::LoadStatObjUnsafeManualRef(const char* fileName, const char* geomName, IStatObj::SSubObject** subObject, - bool useStreaming, unsigned long loadingFlags, const void* data, int dataSize) -{ - return LoadStatObjInternal(fileName, geomName, subObject, useStreaming, loadingFlags, &CObjManager::LoadStatObjUnsafeManualRef, data, dataSize); -} - -_smart_ptr C3DEngine::LoadStatObjAutoRef(const char* fileName, const char* geomName, IStatObj::SSubObject** subObject, - bool useStreaming, unsigned long loadingFlags, const void* data, int dataSize) -{ - return LoadStatObjInternal(fileName, geomName, subObject, useStreaming, loadingFlags, &CObjManager::LoadStatObjAutoRef, data, dataSize); -} - -template -TReturn C3DEngine::LoadStatObjInternal(const char* fileName, const char* geomName, IStatObj::SSubObject** subObject, bool useStreaming, - unsigned long loadingFlags, LoadStatObjFunc loadStatObjFunc, const void* data, int dataSize) -{ - if (!fileName || !fileName[0]) - { - m_pSystem->Warning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, 0, 0, "I3DEngine::LoadStatObj: filename is not specified"); - return nullptr; - } - - if (!m_pObjManager) - { - m_pObjManager = CryAlignedNew(); - } - - CObjManager* pObjManager = static_cast(m_pObjManager); - return (pObjManager->*loadStatObjFunc)(fileName, geomName, subObject, useStreaming, loadingFlags, data, dataSize, nullptr); -} - -void C3DEngine::LoadStatObjAsync(I3DEngine::LoadStaticObjectAsyncResult resultCallback, const char* szFileName, const char* szGeomName, bool bUseStreaming, unsigned long nLoadingFlags) -{ - CRY_ASSERT_MESSAGE(szFileName && szFileName[0], "LoadStatObjAsync: Invalid filename"); - CRY_ASSERT_MESSAGE(m_pObjManager, "Object manager is not ready."); - - StaticObjectAsyncLoadRequest request; - request.m_callback = resultCallback; - request.m_filename = szFileName; - request.m_geomName = szGeomName; - request.m_useStreaming = bUseStreaming; - request.m_loadingFlags = nLoadingFlags; - - { - AZStd::lock_guard lock(m_statObjQueueLock); - m_statObjLoadRequests.push(std::move(request)); - } -} - -void C3DEngine::ProcessAsyncStaticObjectLoadRequests() -{ - // Same scheme as skinned meshes: CharacterManager::ProcessAsyncLoadRequests. - - enum - { - kMaxLoadsPerFrame = 20 - }; - size_t loadsThisFrame = 0; - - while (loadsThisFrame < kMaxLoadsPerFrame) - { - StaticObjectAsyncLoadRequest request; - { - AZStd::lock_guard lock(m_statObjQueueLock); - if (m_statObjLoadRequests.empty()) - { - break; - } - request = std::move(m_statObjLoadRequests.front()); - m_statObjLoadRequests.pop(); - } - - _smart_ptr object = LoadStatObjAutoRef(request.m_filename.c_str(), request.m_geomName.c_str(), nullptr, request.m_useStreaming, request.m_loadingFlags); - request.m_callback(object); - - ++loadsThisFrame; - } -} - -IStatObj* C3DEngine::FindStatObjectByFilename(const char* filename) -{ - if (filename == NULL) - { - return NULL; - } - - if (filename[0] == 0) - { - return NULL; - } - - return m_pObjManager->FindStaticObjectByFilename(filename); -} - -void C3DEngine::RegisterEntity(IRenderNode* pEnt, int nSID, int nSIDConsideredSafe) -{ - FUNCTION_PROFILER_3DENGINE; - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - CryFatalError("C3DEngine::RegisterEntity should only be called on main thread."); - } - - uint32 nFrameID = GetRenderer()->GetFrameID(); - AsyncOctreeUpdate(pEnt, nSID, nSIDConsideredSafe, nFrameID, false); -} - -void C3DEngine::UnRegisterEntityDirect(IRenderNode* pEnt) -{ - UnRegisterEntityImpl(pEnt); -} - -void C3DEngine::UnRegisterEntityAsJob(IRenderNode* pEnt) -{ - AsyncOctreeUpdate(pEnt, (int)0, (int)0, (int)0, true); -} - -bool C3DEngine::CreateDecalInstance(const CryEngineDecalInfo& decal, CDecal* pCallerManagedDecal) -{ - if (!GetCVars()->e_Decals && !pCallerManagedDecal) - { - return false; - } - - return m_pDecalManager->Spawn(decal, pCallerManagedDecal); -} - -void C3DEngine::SelectEntity(IRenderNode* pEntity) -{ - static IRenderNode* pSelectedNode; - static float fLastTime; - if (pEntity && GetCVars()->e_Decals == 3) - { - float fCurTime = gEnv->pTimer->GetAsyncCurTime(); - if (fCurTime - fLastTime < 1.0f) - { - return; - } - fLastTime = fCurTime; - if (pSelectedNode) - { - pSelectedNode->SetRndFlags(ERF_SELECTED, false); - } - pEntity->SetRndFlags(ERF_SELECTED, true); - pSelectedNode = pEntity; - } -} - -void C3DEngine::CreateDecal(const struct CryEngineDecalInfo& decal) -{ - IF (!GetCVars()->e_DecalsAllowGameDecals, 0) - { - return; - } - - if (GetCVars()->e_Decals == 2) - { - IRenderNode* pRN = decal.ownerInfo.pRenderNode; - PrintMessage("Debug: C3DEngine::CreateDecal: Pos=(%.1f,%.1f,%.1f) Size=%.2f DecalMaterial=%s HitObjectName=%s(%s)", - decal.vPos.x, decal.vPos.y, decal.vPos.z, decal.fSize, decal.szMaterialName, - pRN ? pRN->GetName() : "NULL", pRN ? pRN->GetEntityClassName() : "NULL"); - } - - assert(!decal.pExplicitRightUpFront); // only game-play decals come here - - static uint32 nGroupId = 0; - nGroupId++; - - if ((GetCVars()->e_DecalsDefferedStatic == 1 && decal.pExplicitRightUpFront) || - (GetCVars()->e_DecalsDefferedDynamic == 1 && !decal.pExplicitRightUpFront && - (!decal.ownerInfo.pRenderNode || - decal.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_StaticMeshRenderComponent || - decal.fGrowTimeAlpha || decal.fSize > GetFloatCVar(e_DecalsDefferedDynamicMinSize))) - && !decal.bForceSingleOwner) - { - CryEngineDecalInfo decal_adjusted = decal; - decal_adjusted.nGroupId = nGroupId; - decal_adjusted.bDeferred = true; - m_pDecalManager->SpawnHierarchical(decal_adjusted, NULL); - return; - } - - if (decal.ownerInfo.pRenderNode && decal.fSize > 0.5f && !decal.bForceSingleOwner) - { - PodArray lstEntities; - Vec3 vRadius(decal.fSize, decal.fSize, decal.fSize); - const AABB cExplosionBox(decal.vPos - vRadius, decal.vPos + vRadius); - - if (CVisArea* pArea = (CVisArea*)decal.ownerInfo.pRenderNode->GetEntityVisArea()) - { - if (pArea->m_pObjectsTree) - { - pArea->m_pObjectsTree->MoveObjectsIntoList(&lstEntities, &cExplosionBox, false, true, true, true); - } - } - else - { - Get3DEngine()->MoveObjectsIntoListGlobal(&lstEntities, &cExplosionBox, false, true, true, true); - } - - for (int i = 0; i < lstEntities.Count(); i++) - { - // decals on statobj's of render node - CryEngineDecalInfo decalOnRenderNode = decal; - decalOnRenderNode.ownerInfo.pRenderNode = lstEntities[i].pNode; - decalOnRenderNode.nGroupId = nGroupId; - - // if(decalOnRenderNode.ownerInfo.pRenderNode->GetRenderNodeType() != decal.ownerInfo.pRenderNode->GetRenderNodeType()) - // continue; - - if (decalOnRenderNode.ownerInfo.pRenderNode->GetRndFlags() & ERF_HIDDEN) - { - continue; - } - - m_pDecalManager->SpawnHierarchical(decalOnRenderNode, NULL); - } - } - else - { - CryEngineDecalInfo decalStatic = decal; - decalStatic.nGroupId = nGroupId; - m_pDecalManager->SpawnHierarchical(decalStatic, NULL); - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::SetSunColor(Vec3 vColor) -{ - if (m_pObjManager) - { - m_pObjManager->SetSunColor(vColor); - m_pObjManager->SetSunAnimColor(vColor); - } -} - -Vec3 C3DEngine::GetSunAnimColor() -{ - if (m_pObjManager) - { - return m_pObjManager->GetSunAnimColor(); - } - - return Vec3(); -} - -void C3DEngine::SetSunAnimColor(const Vec3& sunAnimColor) -{ - if (m_pObjManager) - { - m_pObjManager->SetSunAnimColor(sunAnimColor); - } -} - -float C3DEngine::GetSunAnimSpeed() -{ - if (m_pObjManager) - { - return m_pObjManager->GetSunAnimSpeed(); - } - - return 0.0f; -} - -void C3DEngine::SetSunAnimSpeed(float sunAnimSpeed) -{ - if (m_pObjManager) - { - m_pObjManager->SetSunAnimSpeed(sunAnimSpeed); - } -} - -AZ::u8 C3DEngine::GetSunAnimPhase() -{ - if (m_pObjManager) - { - return m_pObjManager->GetSunAnimPhase(); - } - - return 0; -} - -void C3DEngine::SetSunAnimPhase(AZ::u8 sunAnimPhase) -{ - if (m_pObjManager) - { - m_pObjManager->SetSunAnimPhase(sunAnimPhase); - } -} - -AZ::u8 C3DEngine::GetSunAnimIndex() -{ - if (m_pObjManager) - { - return m_pObjManager->GetSunAnimIndex(); - } - - return 0; -} - -void C3DEngine::SetSunAnimIndex(AZ::u8 sunAnimIndex) -{ - if (m_pObjManager) - { - m_pObjManager->SetSunAnimIndex(sunAnimIndex); - } -} - -void C3DEngine::SetSSAOAmount(float fMul) -{ - if (m_pObjManager) - { - m_pObjManager->SetSSAOAmount(fMul); - } -} - -void C3DEngine::SetSSAOContrast(float fMul) -{ - if (m_pObjManager) - { - m_pObjManager->SetSSAOContrast(fMul); - } -} - -void C3DEngine::RemoveAllStaticObjects([[maybe_unused]] int nSID) -{ - if (!IsObjectTreeReady()) - { - return; - } - - PodArray lstObjects; - - // Don't remove objects from the octree, since our query will return more objects than just the ones we're looking for. - const bool removeObjectsFromOctree = false; - - // Skip gathering decals, since we're only looking for vegetation. - const bool skipDecals = true; - const bool skipERFNoDecalNodeDecals = true; - - // Skip dynamic vegetation, since we're only looking to remove static vegetation. - const bool skipDynamicObjects = true; - - GetObjectTree()->MoveObjectsIntoList(&lstObjects, nullptr, removeObjectsFromOctree, skipDecals, skipERFNoDecalNodeDecals, skipDynamicObjects); -} - -void C3DEngine::OnExplosion(Vec3 vPos, float fRadius, [[maybe_unused]] bool bDeformTerrain) -{ - if (GetCVars()->e_Decals == 2) - { - PrintMessage("Debug: C3DEngine::OnExplosion: Pos=(%.1f,%.1f,%.1f) fRadius=%.2f", vPos.x, vPos.y, vPos.z, fRadius); - } - - auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler(); - if (!terrain) - { - return; - } - - AZ::Aabb terrainAabb = terrain->GetTerrainAabb(); - if (!terrainAabb.Contains(LYVec3ToAZVec3(vPos)) || fRadius <= 0) - { - return; // out of terrain - } - - const AZ::Vector2 terrainGridResolution = terrain->GetTerrainGridResolution(); - const float unitSizeX = terrainGridResolution.GetX(); - const float unitSizeY = terrainGridResolution.GetY(); - - // do not create decals near the terrain holes - { - for (float x = vPos.x - fRadius; x <= vPos.x + fRadius + 1.0f; x += unitSizeX) - { - for (float y = vPos.y - fRadius; y <= vPos.y + fRadius + 1.0f; y += unitSizeY) - { - if (terrain->GetIsHoleFromFloats(x, y)) - { - return; - } - } - } - } - - // reduce ground decals size depending on distance to the ground - - // delete decals what can not be correctly updated - Vec3 vRadius(fRadius, fRadius, fRadius); - AABB areaBox(vPos - vRadius, vPos + vRadius); - Get3DEngine()->DeleteDecalsInRange(&areaBox, NULL); -} - -float C3DEngine::GetMaxViewDistance(bool bScaled) -{ - // lerp between specs - float fMaxViewDist; - - // camera height lerp factor - if (OceanToggle::IsActive() && !OceanRequest::OceanIsEnabled()) - { - fMaxViewDist = m_fMaxViewDistHighSpec; - } - else - { - // spec lerp factor - float lerpSpec = clamp_tpl(GetCVars()->e_MaxViewDistSpecLerp, 0.0f, 1.0f); - - // lerp between specs - fMaxViewDist = m_fMaxViewDistLowSpec * (1.f - lerpSpec) + m_fMaxViewDistHighSpec * lerpSpec; - - const float waterLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : GetWaterLevel(); - float lerpHeight = clamp_tpl(max(0.f, GetSystem()->GetViewCamera().GetPosition().z - waterLevel) / GetFloatCVar(e_MaxViewDistFullDistCamHeight), 0.0f, 1.0f); - - // lerp between prev result and high spec - fMaxViewDist = fMaxViewDist * (1.f - lerpHeight) + m_fMaxViewDistHighSpec * lerpHeight; - } - - if (bScaled) - { - fMaxViewDist *= m_fMaxViewDistScale; - } - - // for debugging - const float fMaxViewDistCVar = GetFloatCVar(e_MaxViewDistance); - fMaxViewDist = (float)fsel(fMaxViewDistCVar, fMaxViewDistCVar, fMaxViewDist); - - fMaxViewDist = (float)fsel(fabsf(fMaxViewDist) - 0.100001f, fMaxViewDist, 0.100001f); - - // eliminate some floating point inconsistency here, there's no point in nitpicking 7999.9995 view distance vs 8000 - fMaxViewDist = AZ::ClampIfCloseMag(fMaxViewDist, float(round(fMaxViewDist)), 0.01f); - - return fMaxViewDist; -} - -void C3DEngine::SetFrameLodInfo(const SFrameLodInfo& frameLodInfo) -{ - if (frameLodInfo.fLodRatio != m_frameLodInfo.fLodRatio || frameLodInfo.fTargetSize != m_frameLodInfo.fTargetSize) - { - ++m_frameLodInfo.nID; - m_frameLodInfo.fLodRatio = frameLodInfo.fLodRatio; - m_frameLodInfo.fTargetSize = frameLodInfo.fTargetSize; - } - m_frameLodInfo.nMinLod = frameLodInfo.nMinLod; - m_frameLodInfo.nMaxLod = frameLodInfo.nMaxLod; -} - -void C3DEngine::SetFogColor(const Vec3& vFogColor) -{ - m_vFogColor = vFogColor; - GetRenderer()->SetClearColor(m_vFogColor); -} - -Vec3 C3DEngine::GetFogColor() -{ - return m_vFogColor; -} - -void C3DEngine::GetSkyLightParameters(Vec3& sunDir, Vec3& sunIntensity, float& Km, float& Kr, float& g, Vec3& rgbWaveLengths) -{ - CSkyLightManager::SSkyDomeCondition skyCond; - m_pSkyLightManager->GetCurSkyDomeCondition(skyCond); - - g = skyCond.m_g; - Km = skyCond.m_Km; - Kr = skyCond.m_Kr; - sunIntensity = skyCond.m_sunIntensity; - rgbWaveLengths = skyCond.m_rgbWaveLengths; - sunDir = skyCond.m_sunDirection; -} - -void C3DEngine::SetSkyLightParameters(const Vec3& sunDir, const Vec3& sunIntensity, float Km, float Kr, float g, const Vec3& rgbWaveLengths, bool forceImmediateUpdate) -{ - CSkyLightManager::SSkyDomeCondition skyCond; - - skyCond.m_g = g; - skyCond.m_Km = Km; - skyCond.m_Kr = Kr; - skyCond.m_sunIntensity = sunIntensity; - skyCond.m_rgbWaveLengths = rgbWaveLengths; - skyCond.m_sunDirection = sunDir; - - m_pSkyLightManager->SetSkyDomeCondition(skyCond); - if (forceImmediateUpdate && IsHDRSkyMaterial(GetSkyMaterial())) - { - m_pSkyLightManager->FullUpdate(); - } -} - -void C3DEngine::SetLightsHDRDynamicPowerFactor(const float value) -{ - m_fLightsHDRDynamicPowerFactor = value; -} - -float C3DEngine::GetLightsHDRDynamicPowerFactor() const -{ - return m_fLightsHDRDynamicPowerFactor; -} - -bool C3DEngine::IsTessellationAllowedForShadowMap(const SRenderingPassInfo& passInfo) const -{ -#ifdef MESH_TESSELLATION_ENGINE - SRenderingPassInfo::EShadowMapType shadowType = passInfo.GetShadowMapType(); - switch (shadowType) - { - case SRenderingPassInfo::SHADOW_MAP_GSM: - return passInfo.ShadowFrustumLod() < GetCVars()->e_ShadowsTessellateCascades; - case SRenderingPassInfo::SHADOW_MAP_LOCAL: - return GetCVars()->e_ShadowsTessellateDLights != 0; - case SRenderingPassInfo::SHADOW_MAP_NONE: - default: - return false; - } -#else - - return false; - -#endif //#ifdef MESH_TESSELLATION_ENGINE -} - -void C3DEngine::SetPhysMaterialEnumerator(IPhysMaterialEnumerator* pPhysMaterialEnumerator) -{ - m_pPhysMaterialEnumerator = pPhysMaterialEnumerator; -} - -IPhysMaterialEnumerator* C3DEngine::GetPhysMaterialEnumerator() -{ - return m_pPhysMaterialEnumerator; -} - -float C3DEngine::GetDistanceToSectorWithWater() -{ - const Vec3 camPosition = GetRenderingCamera().GetPosition(); - const float minDistance = 0.1f; - const bool oceanActive = OceanToggle::IsActive(); - const bool oceanEnabled = OceanRequest::OceanIsEnabled(); - float distance = minDistance; - - if (oceanActive && !oceanEnabled) - { - distance = std::numeric_limits::infinity(); - } - else - { - if (oceanActive && oceanEnabled) - { - distance = camPosition.z - OceanRequest::GetOceanLevel(); - } - else - { - distance = std::numeric_limits::infinity(); - } - } - - return max(distance, minDistance); -} - -Vec3 C3DEngine::GetSunColor() const -{ - return m_pObjManager ? m_pObjManager->GetSunColor() : Vec3(0, 0, 0); -} - -float C3DEngine::GetSSAOAmount() const -{ - return m_pObjManager ? m_pObjManager->GetSSAOAmount() : 1.0f; -} - -float C3DEngine::GetSSAOContrast() const -{ - return m_pObjManager ? m_pObjManager->GetSSAOContrast() : 1.0f; -} - -void C3DEngine::SetRainParams(const SRainParams& rainParams) -{ - if (m_pObjManager) - { - m_pObjManager->GetRainParams().bIgnoreVisareas = rainParams.bIgnoreVisareas; - m_pObjManager->GetRainParams().bDisableOcclusion = rainParams.bDisableOcclusion; - m_pObjManager->GetRainParams().qRainRotation = rainParams.qRainRotation; - m_pObjManager->GetRainParams().vWorldPos = rainParams.vWorldPos; - m_pObjManager->GetRainParams().vColor = rainParams.vColor; - m_pObjManager->GetRainParams().fAmount = rainParams.fAmount; - m_pObjManager->GetRainParams().fCurrentAmount = rainParams.fCurrentAmount; - m_pObjManager->GetRainParams().fRadius = rainParams.fRadius; - m_pObjManager->GetRainParams().fFakeGlossiness = rainParams.fFakeGlossiness; - m_pObjManager->GetRainParams().fFakeReflectionAmount = rainParams.fFakeReflectionAmount; - m_pObjManager->GetRainParams().fDiffuseDarkening = rainParams.fDiffuseDarkening; - m_pObjManager->GetRainParams().fRainDropsAmount = rainParams.fRainDropsAmount; - m_pObjManager->GetRainParams().fRainDropsSpeed = rainParams.fRainDropsSpeed; - m_pObjManager->GetRainParams().fRainDropsLighting = rainParams.fRainDropsLighting; - m_pObjManager->GetRainParams().fMistAmount = rainParams.fMistAmount; - m_pObjManager->GetRainParams().fMistHeight = rainParams.fMistHeight; - m_pObjManager->GetRainParams().fPuddlesAmount = rainParams.fPuddlesAmount; - m_pObjManager->GetRainParams().fPuddlesMaskAmount = rainParams.fPuddlesMaskAmount; - m_pObjManager->GetRainParams().fPuddlesRippleAmount = rainParams.fPuddlesRippleAmount; - m_pObjManager->GetRainParams().fSplashesAmount = rainParams.fSplashesAmount; - - m_pObjManager->GetRainParams().nUpdateFrameID = GetRenderer()->GetFrameID(); - } -} - -bool C3DEngine::GetRainParams(SRainParams& rainParams) -{ - bool bRet = false; - const int nFrmID = GetRenderer()->GetFrameID(); - if (m_pObjManager) - { - // Copy shared rain data only - rainParams.bIgnoreVisareas = m_pObjManager->GetRainParams().bIgnoreVisareas; - rainParams.bDisableOcclusion = m_pObjManager->GetRainParams().bDisableOcclusion; - rainParams.qRainRotation = m_pObjManager->GetRainParams().qRainRotation; - rainParams.vWorldPos = m_pObjManager->GetRainParams().vWorldPos; - rainParams.vColor = m_pObjManager->GetRainParams().vColor; - rainParams.fAmount = m_pObjManager->GetRainParams().fAmount; - rainParams.fCurrentAmount = m_pObjManager->GetRainParams().fCurrentAmount; - rainParams.fRadius = m_pObjManager->GetRainParams().fRadius; - rainParams.fFakeGlossiness = m_pObjManager->GetRainParams().fFakeGlossiness; - rainParams.fFakeReflectionAmount = m_pObjManager->GetRainParams().fFakeReflectionAmount; - rainParams.fDiffuseDarkening = m_pObjManager->GetRainParams().fDiffuseDarkening; - rainParams.fRainDropsAmount = m_pObjManager->GetRainParams().fRainDropsAmount; - rainParams.fRainDropsSpeed = m_pObjManager->GetRainParams().fRainDropsSpeed; - rainParams.fRainDropsLighting = m_pObjManager->GetRainParams().fRainDropsLighting; - rainParams.fMistAmount = m_pObjManager->GetRainParams().fMistAmount; - rainParams.fMistHeight = m_pObjManager->GetRainParams().fMistHeight; - rainParams.fPuddlesAmount = m_pObjManager->GetRainParams().fPuddlesAmount; - rainParams.fPuddlesMaskAmount = m_pObjManager->GetRainParams().fPuddlesMaskAmount; - rainParams.fPuddlesRippleAmount = m_pObjManager->GetRainParams().fPuddlesRippleAmount; - rainParams.fSplashesAmount = m_pObjManager->GetRainParams().fSplashesAmount; - - if (!IsOutdoorVisible() && !rainParams.bIgnoreVisareas) - { - rainParams.fAmount = 0.f; - } - - bRet = m_pObjManager->GetRainParams().nUpdateFrameID == nFrmID; - } - return bRet; -} - -void C3DEngine::SetSnowSurfaceParams(const Vec3& vCenter, float fRadius, float fSnowAmount, float fFrostAmount, float fSurfaceFreezing) -{ - if (m_pObjManager) - { - m_pObjManager->GetSnowParams().m_vWorldPos = vCenter; - m_pObjManager->GetSnowParams().m_fRadius = fRadius; - m_pObjManager->GetSnowParams().m_fSnowAmount = fSnowAmount; - m_pObjManager->GetSnowParams().m_fFrostAmount = fFrostAmount; - m_pObjManager->GetSnowParams().m_fSurfaceFreezing = fSurfaceFreezing; - } -} - -bool C3DEngine::GetSnowSurfaceParams(Vec3& vCenter, float& fRadius, float& fSnowAmount, float& fFrostAmount, float& fSurfaceFreezing) -{ - bool bRet = false; - if (m_pObjManager) - { - vCenter = m_pObjManager->GetSnowParams().m_vWorldPos; - fRadius = m_pObjManager->GetSnowParams().m_fRadius; - fSnowAmount = 0.f; - fFrostAmount = 0.f; - fSurfaceFreezing = 0.f; - if (IsOutdoorVisible()) - { - fSnowAmount = m_pObjManager->GetSnowParams().m_fSnowAmount; - fFrostAmount = m_pObjManager->GetSnowParams().m_fFrostAmount; - fSurfaceFreezing = m_pObjManager->GetSnowParams().m_fSurfaceFreezing; - } - bRet = true; - } - return bRet; -} - -void C3DEngine::SetSnowFallParams(int nSnowFlakeCount, float fSnowFlakeSize, float fSnowFallBrightness, float fSnowFallGravityScale, float fSnowFallWindScale, float fSnowFallTurbulence, float fSnowFallTurbulenceFreq) -{ - if (m_pObjManager) - { - m_pObjManager->GetSnowParams().m_nSnowFlakeCount = nSnowFlakeCount; - m_pObjManager->GetSnowParams().m_fSnowFlakeSize = fSnowFlakeSize; - m_pObjManager->GetSnowParams().m_fSnowFallBrightness = fSnowFallBrightness; - m_pObjManager->GetSnowParams().m_fSnowFallGravityScale = fSnowFallGravityScale; - m_pObjManager->GetSnowParams().m_fSnowFallWindScale = fSnowFallWindScale; - m_pObjManager->GetSnowParams().m_fSnowFallTurbulence = fSnowFallTurbulence; - m_pObjManager->GetSnowParams().m_fSnowFallTurbulenceFreq = fSnowFallTurbulenceFreq; - } -} - -bool C3DEngine::GetSnowFallParams(int& nSnowFlakeCount, float& fSnowFlakeSize, float& fSnowFallBrightness, float& fSnowFallGravityScale, float& fSnowFallWindScale, float& fSnowFallTurbulence, float& fSnowFallTurbulenceFreq) -{ - bool bRet = false; - if (m_pObjManager) - { - nSnowFlakeCount = 0; - fSnowFlakeSize = 0.f; - fSnowFallBrightness = 0.f; - fSnowFallGravityScale = 0.f; - fSnowFallWindScale = 0.f; - fSnowFallTurbulence = 0.f; - fSnowFallTurbulenceFreq = 0.f; - if (IsOutdoorVisible()) - { - nSnowFlakeCount = m_pObjManager->GetSnowParams().m_nSnowFlakeCount; - fSnowFlakeSize = m_pObjManager->GetSnowParams().m_fSnowFlakeSize; - fSnowFallBrightness = m_pObjManager->GetSnowParams().m_fSnowFallBrightness; - fSnowFallGravityScale = m_pObjManager->GetSnowParams().m_fSnowFallGravityScale; - fSnowFallWindScale = m_pObjManager->GetSnowParams().m_fSnowFallWindScale; - fSnowFallTurbulence = m_pObjManager->GetSnowParams().m_fSnowFallTurbulence; - fSnowFallTurbulenceFreq = m_pObjManager->GetSnowParams().m_fSnowFallTurbulenceFreq; - } - bRet = true; - } - return bRet; -} - -void C3DEngine::SetSunDir(const Vec3& newSunDir) -{ - Vec3 vSunDirNormalized = newSunDir.normalized(); - m_vSunDirRealtime = vSunDirNormalized; - if (vSunDirNormalized.Dot(m_vSunDirNormalized) < GetFloatCVar(e_SunAngleSnapDot) || - GetCurTimeSec() - m_fSunDirUpdateTime > GetFloatCVar(e_SunAngleSnapSec)) - { - m_vSunDirNormalized = vSunDirNormalized; - m_vSunDir = m_vSunDirNormalized * DISTANCE_TO_THE_SUN; - - m_fSunDirUpdateTime = GetCurTimeSec(); - } -} - -Vec3 C3DEngine::GetSunDir() const -{ - return m_vSunDir; -} - -Vec3 C3DEngine::GetRealtimeSunDirNormalized() const -{ - return m_vSunDirRealtime; -} - -void C3DEngine::FreeRenderNodeState(IRenderNode* pEnt) -{ - // make sure we don't try to update the streaming priority if an object - // was added and removed in the same frame - int nElementID = m_deferredRenderComponentStreamingPriorityUpdates.Find(pEnt); - if (nElementID != -1) - { - m_deferredRenderComponentStreamingPriorityUpdates.DeleteFastUnsorted(nElementID); - } - - m_pObjManager->RemoveFromRenderAllObjectDebugInfo(pEnt); - - -#if !defined(_RELEASE) - if (!gEnv->IsDedicated()) - { - //As render nodes can be deleted in many places, it's possible that the map of render nodes used by stats gathering (r_stats 6, perfHUD, debug gun) could get aliased. - //Ensure that this node is removed from the map to prevent a dereference after deletion. - gEnv->pRenderer->ForceRemoveNodeFromDrawCallsMap(pEnt); - } -#endif - - m_lstAlwaysVisible.Delete(pEnt); - - if (m_pDecalManager && (pEnt->m_nInternalFlags & IRenderNode::DECAL_OWNER)) - { - m_pDecalManager->OnEntityDeleted(pEnt); - } - - if (pEnt->GetRenderNodeType() == eERType_Light) - { - GetRenderer()->OnEntityDeleted(pEnt); - } - - if (pEnt->GetRndFlags() & (ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS)) - { // make sure pointer to object will not be used somewhere in the renderer -#if !defined(_RELEASE) - if (!(pEnt->GetRndFlags() & ERF_HAS_CASTSHADOWMAPS)) - { - Warning("IRenderNode has ERF_CASTSHADOWMAPS set but not ERF_HAS_CASTSHADOWMAPS, name: '%s', class: '%s'.", pEnt->GetName(), pEnt->GetEntityClassName()); - } -#endif - Get3DEngine()->OnCasterDeleted(pEnt); - } - - UnRegisterEntityImpl(pEnt); - - if (pEnt->m_pRNTmpData) - { - Get3DEngine()->FreeRNTmpData(&pEnt->m_pRNTmpData); - assert(!pEnt->m_pRNTmpData); - } -} - -const char* C3DEngine::GetLevelFilePath(const char* szFileName) -{ - cry_strcpy(m_sGetLevelFilePathTmpBuff, m_szLevelFolder); - if (*szFileName && (*szFileName == '/' || *szFileName == '\\')) - { - cry_strcat(m_sGetLevelFilePathTmpBuff, szFileName + 1); - } - else - { - cry_strcat(m_sGetLevelFilePathTmpBuff, szFileName); - } - return m_sGetLevelFilePathTmpBuff; -} - -void C3DEngine::ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName) -{ - if (m_pVisAreaManager) - { - m_pVisAreaManager->ActivatePortal(vPos, bActivate, szEntityName); - } -} - -bool C3DEngine::SetStatInstGroup(int nGroupId, const IStatInstGroup& siGroup, int nSID) -{ - if (m_pObjManager->GetListStaticTypes().Count() == 0) - { - AZ_Warning("C3DEngine", false, "Trying to set a Stat instance without an initialized Object manager. This might be caused by using the vegetation system without terrain."); - return false; - } - if ((nSID < 0) || (nSID >= m_pObjManager->GetListStaticTypes().Count())) - { - AZ_Assert(false, "Invalid StatInst ID: %d (should be > 0 and < %d)", nSID, m_pObjManager->GetListStaticTypes().Count()); - return false; - } - - m_fRefreshSceneDataCVarsSumm = -100; - - m_pObjManager->GetListStaticTypes()[nSID].resize(max(nGroupId + 1, m_pObjManager->GetListStaticTypes()[nSID].Count())); - - if (nGroupId < 0 || nGroupId >= m_pObjManager->GetListStaticTypes()[nSID].Count()) - { - return false; - } - - StatInstGroup& rGroup = m_pObjManager->GetListStaticTypes()[nSID][nGroupId]; - - // If the object was changed in the editor, ResetActiveNodes will need to be called later - // Keep track of the previous object so we can check for this later - _smart_ptr pPreviousObject = rGroup.pStatObj; - rGroup.pStatObj = siGroup.pStatObj; - - if (rGroup.pStatObj) - { - cry_strcpy(rGroup.szFileName, siGroup.pStatObj->GetFilePath()); - } - else - { - rGroup.szFileName[0] = 0; - } - - rGroup.bHideability = siGroup.bHideability; - rGroup.bHideabilitySecondary = siGroup.bHideabilitySecondary; - rGroup.nPlayerHideable = siGroup.nPlayerHideable; - rGroup.fBending = siGroup.fBending; - rGroup.nCastShadowMinSpec = siGroup.nCastShadowMinSpec; - rGroup.bRecvShadow = siGroup.bRecvShadow; - rGroup.bDynamicDistanceShadows = siGroup.bDynamicDistanceShadows; - - rGroup.bUseAlphaBlending = siGroup.bUseAlphaBlending; - rGroup.fSpriteDistRatio = siGroup.fSpriteDistRatio; - rGroup.fLodDistRatio = siGroup.fLodDistRatio; - rGroup.fShadowDistRatio = siGroup.fShadowDistRatio; - rGroup.fMaxViewDistRatio = siGroup.fMaxViewDistRatio; - - rGroup.fBrightness = siGroup.fBrightness; - - _smart_ptr pPreviousGroupMaterial = rGroup.pMaterial; - rGroup.pMaterial = siGroup.pMaterial; - - rGroup.fDensity = siGroup.fDensity; - rGroup.fElevationMax = siGroup.fElevationMax; - rGroup.fElevationMin = siGroup.fElevationMin; - rGroup.fSize = siGroup.fSize; - rGroup.fSizeVar = siGroup.fSizeVar; - rGroup.fSlopeMax = siGroup.fSlopeMax; - rGroup.fSlopeMin = siGroup.fSlopeMin; - rGroup.fStiffness = siGroup.fStiffness; - rGroup.fDamping = siGroup.fDamping; - rGroup.fVariance = siGroup.fVariance; - rGroup.fAirResistance = siGroup.fAirResistance; - - rGroup.bRandomRotation = siGroup.bRandomRotation; - rGroup.nRotationRangeToTerrainNormal = siGroup.nRotationRangeToTerrainNormal; - rGroup.nMaterialLayers = siGroup.nMaterialLayers; - - rGroup.bAllowIndoor = siGroup.bAllowIndoor; - rGroup.fAlignToTerrainCoefficient = siGroup.fAlignToTerrainCoefficient; - - rGroup.bAutoMerged = siGroup.bAutoMerged; - rGroup.minConfigSpec = siGroup.minConfigSpec; - - rGroup.nID = siGroup.nID; - - rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes()); - - MarkRNTmpDataPoolForReset(); - - return true; -} - -bool C3DEngine::GetStatInstGroup(int nGroupId, IStatInstGroup& siGroup, int nSID) -{ - assert(nSID >= 0 && nSID < m_pObjManager->GetListStaticTypes().Count()); - - if (nGroupId < 0 || nGroupId >= m_pObjManager->GetListStaticTypes()[nSID].Count()) - { - return false; - } - - StatInstGroup& rGroup = m_pObjManager->GetListStaticTypes()[nSID][nGroupId]; - - siGroup.pStatObj = rGroup.pStatObj; - if (siGroup.pStatObj) - { - cry_strcpy(siGroup.szFileName, rGroup.pStatObj->GetFilePath()); - } - - siGroup.bHideability = rGroup.bHideability; - siGroup.bHideabilitySecondary = rGroup.bHideabilitySecondary; - siGroup.nPlayerHideable = rGroup.nPlayerHideable; - siGroup.fBending = rGroup.fBending; - siGroup.nCastShadowMinSpec = rGroup.nCastShadowMinSpec; - siGroup.bRecvShadow = rGroup.bRecvShadow; - siGroup.bDynamicDistanceShadows = rGroup.bDynamicDistanceShadows; - - siGroup.bUseAlphaBlending = rGroup.bUseAlphaBlending; - siGroup.fSpriteDistRatio = rGroup.fSpriteDistRatio; - siGroup.fLodDistRatio = rGroup.fLodDistRatio; - siGroup.fShadowDistRatio = rGroup.fShadowDistRatio; - siGroup.fMaxViewDistRatio = rGroup.fMaxViewDistRatio; - - siGroup.fBrightness = rGroup.fBrightness; - siGroup.pMaterial = rGroup.pMaterial; - - siGroup.fDensity = rGroup.fDensity; - siGroup.fElevationMax = rGroup.fElevationMax; - siGroup.fElevationMin = rGroup.fElevationMin; - siGroup.fSize = rGroup.fSize; - siGroup.fSizeVar = rGroup.fSizeVar; - siGroup.fSlopeMax = rGroup.fSlopeMax; - siGroup.fSlopeMin = rGroup.fSlopeMin; - siGroup.bAutoMerged = rGroup.bAutoMerged; - - siGroup.fStiffness = rGroup.fStiffness; - siGroup.fDamping = rGroup.fDamping; - siGroup.fVariance = rGroup.fVariance; - siGroup.fAirResistance = rGroup.fAirResistance; - - siGroup.nID = rGroup.nID; - - return true; -} - -void C3DEngine::UpdateStatInstGroups() -{ - if (!m_pObjManager) - { - return; - } - - for (uint32 nSID = 0; nSID < m_pObjManager->GetListStaticTypes().size(); nSID++) - { - PodArray& rGroupTable = m_pObjManager->GetListStaticTypes()[nSID]; - for (uint32 nGroupId = 0; nGroupId < rGroupTable.size(); nGroupId++) - { - StatInstGroup& rGroup = rGroupTable[nGroupId]; - rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes()); - } - } -} - -void C3DEngine::GetMemoryUsage(class ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this) + (GetCVars()->e_StreamCgfDebug ? 100 * 1024 * 1024 : 0)); - pSizer->AddObject(m_pCVars); - - pSizer->AddObject(m_lstStaticLights); - pSizer->AddObject(m_arrLightProjFrustums); - - pSizer->AddObject(arrFPSforSaveLevelStats); - pSizer->AddObject(m_lstAlwaysVisible); - - if (CTemporaryPool* pPool = CTemporaryPool::Get()) - { - SIZER_COMPONENT_NAME(pSizer, "Temporary Pool"); - pPool->GetMemoryUsage(pSizer); - } - - { - SIZER_COMPONENT_NAME(pSizer, "RenderMeshMerger"); - m_pRenderMeshMerger->GetMemoryUsage(pSizer); - } - - { - SIZER_COMPONENT_NAME(pSizer, "Optics"); - pSizer->AddObject(m_pOpticsManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "SkyLightManager"); - pSizer->AddObject(m_pSkyLightManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "DecalManager"); - pSizer->AddObject(m_pDecalManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "OutdoorObjectsTree"); - pSizer->AddObject(m_pObjectsTree); - } - - { - SIZER_COMPONENT_NAME(pSizer, "ObjManager"); - pSizer->AddObject(m_pObjManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "Ocean"); - pSizer->AddObject(m_pOcean); - } - - { - SIZER_COMPONENT_NAME(pSizer, "VisAreas"); - pSizer->AddObject(m_pVisAreaManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "ClipVolumes"); - pSizer->AddObject(m_pClipVolumeManager); - } - - { - SIZER_COMPONENT_NAME(pSizer, "CoverageBuffer"); - pSizer->AddObject(m_pCoverageBuffer); - } - - { - SIZER_COMPONENT_NAME(pSizer, "RNTmpDataPool"); - - CRNTmpData* pNext = NULL; - - for (CRNTmpData* pElem = m_LTPRootFree.pNext; pElem != &m_LTPRootFree; pElem = pNext) - { - pSizer->AddObject(pElem, sizeof(*pElem)); - pNext = pElem->pNext; - } - - for (CRNTmpData* pElem = m_LTPRootUsed.pNext; pElem != &m_LTPRootUsed; pElem = pNext) - { - pSizer->AddObject(pElem, sizeof(*pElem)); - pNext = pElem->pNext; - } - } -} - -void C3DEngine::GetResourceMemoryUsage(ICrySizer* pSizer, const AABB& cstAABB) -{ - ////////////////////////////////////////////////////////////////////////// - std::vector cFoundRenderNodes; - unsigned int nFoundObjects(0); - - nFoundObjects = GetObjectsInBox(cstAABB); - cFoundRenderNodes.resize(nFoundObjects, NULL); - GetObjectsInBox(cstAABB, &cFoundRenderNodes.front()); - - size_t nCurrentRenderNode(0); - size_t nTotalNumberOfRenderNodes(0); - - nTotalNumberOfRenderNodes = cFoundRenderNodes.size(); - for (nCurrentRenderNode = 0; nCurrentRenderNode < nTotalNumberOfRenderNodes; ++nCurrentRenderNode) - { - IRenderNode*& piRenderNode = cFoundRenderNodes[nCurrentRenderNode]; - - _smart_ptr piMaterial(piRenderNode->GetMaterialOverride()); - if (!piMaterial) - { - piMaterial = piRenderNode->GetMaterial(); - } - - if (piMaterial) - { - piMaterial->GetResourceMemoryUsage(pSizer); - } - - { - IRenderMesh* piMesh(NULL); - size_t nCount(0); - - piMesh = piRenderNode->GetRenderMesh(nCount); - for (; piMesh; ++nCount, piMesh = piRenderNode->GetRenderMesh(nCount)) - { - // Timur, RenderMesh may not be loaded due to streaming! - piMesh->GetMemoryUsage(pSizer, IRenderMesh::MEM_USAGE_COMBINED); - } - } - } - ////////////////////////////////////////////////////////////////////////// -} - -bool C3DEngine::IsUnderWater(const Vec3& vPos) const -{ - bool bUnderWater = false; - // Check underwater - AZ_UNUSED(vPos) - CRY_PHYSICS_REPLACEMENT_ASSERT(); - return bUnderWater; -} - -void C3DEngine::SetOceanRenderFlags(uint8 nFlags) -{ - m_nOceanRenderFlags = nFlags; -} - -uint32 C3DEngine::GetOceanVisiblePixelsCount() const -{ - return COcean::GetVisiblePixelsCount(); -} - -float C3DEngine::GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth, [[maybe_unused]] int objflags) -{ - FUNCTION_PROFILER_3DENGINE; - - float terrainWorldZ = AzFramework::Terrain::TerrainDataRequests::GetDefaultTerrainHeight(); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainWorldZ - , &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats - , referencePos.x, referencePos.y, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, nullptr); - - const float padding = 0.2f; - float rayLength; - - // NOTE: Terrain is above referencePos, so referencePos is probably inside a voxel or something. - if (terrainWorldZ <= referencePos.z) - { - rayLength = min(maxRelevantDepth, (referencePos.z - terrainWorldZ)); - } - else - { - rayLength = maxRelevantDepth; - } - - rayLength += padding * 2.0f; - - // Get bottom level - CRY_PHYSICS_REPLACEMENT_ASSERT(); - - // Terrain was above or too far below referencePos, and no solid object was close enough. - return BOTTOM_LEVEL_UNKNOWN; -} - -float C3DEngine::GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth /* = 10.0f */) -{ - return GetBottomLevel (referencePos, maxRelevantDepth, ent_terrain | ent_static | ent_sleeping_rigid | ent_rigid); -} - -float C3DEngine::GetBottomLevel(const Vec3& referencePos, int objflags) -{ - return GetBottomLevel (referencePos, 10.0f, objflags); -} - -#if defined(USE_GEOM_CACHES) -IGeomCache* C3DEngine::LoadGeomCache(const char* szFileName) -{ - if (!szFileName || !szFileName[0]) - { - m_pSystem->Warning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, 0, 0, "I3DEngine::LoadGeomCache: filename is not specified"); - return 0; - } - - return m_pGeomCacheManager->LoadGeomCache(szFileName); -} - -IGeomCache* C3DEngine::FindGeomCacheByFilename(const char* szFileName) -{ - if (!szFileName || szFileName[0] == 0) - { - return NULL; - } - - return m_pGeomCacheManager->FindGeomCacheByFilename(szFileName); -} -#endif - -namespace -{ - // The return value is the next position of the source buffer. - int ReadFromBuffer(const char* pSource, int nSourceSize, int nSourcePos, void* pDest, int nDestSize) - { - if (pDest == 0 || nDestSize == 0) - { - return 0; - } - - if (nSourcePos < 0 || nSourcePos >= nSourceSize) - { - return 0; - } - - memcpy(pDest, &pSource[nSourcePos], nDestSize); - - return nSourcePos + nDestSize; - } -} - -IStatObj* C3DEngine::LoadDesignerObject(int nVersion, const char* szBinaryStream, int size) -{ - if (nVersion < 0 || nVersion > 2) - { - return NULL; - } - - int nBufferPos = 0; - int32 nSubObjectCount = 0; - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nSubObjectCount, sizeof(int32)); - - IStatObj* pStatObj = gEnv->p3DEngine->CreateStatObj(); - if (!pStatObj) - { - return NULL; - } - - std::vector statObjList; - if (nSubObjectCount == 2) - { - pStatObj->AddSubObject(gEnv->p3DEngine->CreateStatObj()); - pStatObj->AddSubObject(gEnv->p3DEngine->CreateStatObj()); - pStatObj->GetIndexedMesh()->FreeStreams(); - statObjList.push_back(pStatObj->GetSubObject(0)->pStatObj); - statObjList.push_back(pStatObj->GetSubObject(1)->pStatObj); - } - else - { - statObjList.push_back(pStatObj); - } - - if (nVersion == 2) - { - int32 nStaticObjFlags = 0; - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nStaticObjFlags, sizeof(int32)); - pStatObj->SetFlags(nStaticObjFlags); - } - - for (int k = 0, iCount(statObjList.size()); k < iCount; ++k) - { - int32 nPositionCount = 0; - int32 nTexCoordCount = 0; - int32 nFaceCount = 0; - int32 nIndexCount = 0; - int32 nTangentCount = 0; - int32 nSubsetCount = 0; - - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nPositionCount, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nTexCoordCount, sizeof(int32)); - if (nPositionCount <= 0 || nTexCoordCount <= 0) - { - return NULL; - } - - if (nVersion == 0) - { - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFaceCount, sizeof(int32)); - if (nFaceCount <= 0) - { - return NULL; - } - } - else if (nVersion >= 1) - { - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nIndexCount, sizeof(int32)); - if (nIndexCount <= 0) - { - return NULL; - } - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nTangentCount, sizeof(int32)); - } - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nSubsetCount, sizeof(int32)); - IIndexedMesh* pMesh = statObjList[k]->GetIndexedMesh(); - if (!pMesh) - { - return NULL; - } - - pMesh->FreeStreams(); - pMesh->SetVertexCount((int)nPositionCount); - pMesh->SetFaceCount((int)nFaceCount); - pMesh->SetIndexCount((int)nIndexCount); - pMesh->SetTexCoordCount((int)nTexCoordCount); - - Vec3* const positions = pMesh->GetMesh()->GetStreamPtr(CMesh::POSITIONS); - Vec3* const normals = pMesh->GetMesh()->GetStreamPtr(CMesh::NORMALS); - SMeshTexCoord* const texcoords = pMesh->GetMesh()->GetStreamPtr(CMesh::TEXCOORDS); - - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, positions, sizeof(Vec3) * nPositionCount); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, normals, sizeof(Vec3) * nPositionCount); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, texcoords, sizeof(SMeshTexCoord) * nTexCoordCount); - if (nVersion == 0) - { - SMeshFace* const faces = pMesh->GetMesh()->GetStreamPtr(CMesh::FACES); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, faces, sizeof(SMeshFace) * nFaceCount); - } - else if (nVersion >= 1) - { - vtx_idx* const indices = pMesh->GetMesh()->GetStreamPtr(CMesh::INDICES); - if constexpr (sizeof(vtx_idx) == sizeof(uint16)) - { - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, indices, sizeof(uint16) * nIndexCount); - } - else - { - uint16* indices16 = new uint16[nIndexCount]; - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, indices16, sizeof(uint16) * nIndexCount); - for (int32 i = 0; i < nIndexCount; ++i) - { - indices[i] = (vtx_idx)indices16[i]; - } - delete [] indices16; - } - pMesh->SetTangentCount((int)nTangentCount); - if (nTangentCount > 0) - { - SMeshTangents* const tangents = pMesh->GetMesh()->GetStreamPtr(CMesh::TANGENTS); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, tangents, sizeof(SMeshTangents) * nTangentCount); - } - } - - pMesh->SetSubSetCount(nSubsetCount); - for (int i = 0; i < nSubsetCount; ++i) - { - SMeshSubset subset; - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.vCenter, sizeof(Vec3)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.fRadius, sizeof(float)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &subset.fTexelDensity, sizeof(float)); - - int32 nFirstIndexId = 0; - int32 nNumIndices = 0; - int32 nFirstVertId = 0; - int32 nNumVerts = 0; - int32 nMatID = 0; - int32 nMatFlags = 0; - int32 nPhysicalizeType = 0; - - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFirstIndexId, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nNumIndices, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nFirstVertId, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nNumVerts, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nMatID, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nMatFlags, sizeof(int32)); - nBufferPos = ReadFromBuffer(szBinaryStream, size, nBufferPos, &nPhysicalizeType, sizeof(int32)); - - pMesh->SetSubsetBounds(i, subset.vCenter, subset.fRadius); - pMesh->SetSubsetIndexVertexRanges(i, (int)nFirstIndexId, (int)nNumIndices, (int)nFirstVertId, (int)nNumVerts); - pMesh->SetSubsetMaterialId(i, nMatID == -1 ? 0 : (int)nMatID); - pMesh->SetSubsetMaterialProperties(i, (int)nMatFlags, (int)nPhysicalizeType, eVF_P3F_C4B_T2F); - } - - if (nVersion == 0) - { -#if defined(WIN32) || defined(WIN64) - pMesh->Optimize(); -#endif - } - - statObjList[k]->Invalidate(true); - } - - return pStatObj; -} - -float C3DEngine::GetWaterLevel(const Vec3* pvPos, IPhysicalEntity* pent, bool bAccurate) -{ - FUNCTION_PROFILER_3DENGINE; - if (!OceanGlobals::g_oceanParamsMutex.try_lock()) - { - return OceanGlobals::g_oceanLevel; - } - - bool bInVisarea = m_pVisAreaManager && m_pVisAreaManager->GetVisAreaFromPos(*pvPos) != 0; - - - AZ_UNUSED(pent); - - float max_level = (!bInVisarea) ? (bAccurate ? GetAccurateOceanHeight(*pvPos) : GetWaterLevel()) : WATER_LEVEL_UNKNOWN; - - - OceanGlobals::g_oceanParamsMutex.unlock(); - return max(WATER_LEVEL_UNKNOWN, max_level); -} - -void C3DEngine::SetShadowsGSMCache(bool bCache) -{ - if (bCache) - { - m_nGsmCache = m_pConsole->GetCVar("r_ShadowsCache")->GetIVal(); - } - else - { - m_nGsmCache = 0; - } -} - -float C3DEngine::GetAccurateOceanHeight(const Vec3& pCurrPos) const -{ - FUNCTION_PROFILER_3DENGINE; - - static int nFrameID = -1; - const int nEngineFrameID = GetRenderer()->GetFrameID(); - static float fWaterLevel = 0; - if (nFrameID != nEngineFrameID && m_pOcean) - { - fWaterLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : m_pOcean->GetWaterLevel(); - nFrameID = nEngineFrameID; - } - - const float waterLevel = fWaterLevel + COcean::GetWave(pCurrPos, GetRenderer()->GetFrameID()); - return waterLevel; -} - -I3DEngine::CausticsParams C3DEngine::GetCausticsParams() const -{ - I3DEngine::CausticsParams params; - if (OceanToggle::IsActive()) - { - params.tiling = OceanRequest::GetCausticsTiling(); - params.distanceAttenuation = OceanRequest::GetCausticsDistanceAttenuation(); - params.depth = OceanRequest::GetCausticsDepth(); - params.intensity = OceanRequest::GetCausticsIntensity(); - } - else - { - params.tiling = m_oceanCausticsTiling; - params.distanceAttenuation = m_oceanCausticsDistanceAtten; - params.depth = m_oceanCausticDepth; - params.intensity = m_oceanCausticIntensity; - } - params.height = 0.0f; // @TODO: (@pruiksma) Parameter not currently accessible, need to decide whether to rip out or start using. [LY-62048] - return params; -} - -void C3DEngine::GetHDRSetupParams(Vec4 pParams[5]) const -{ - float hdrBloomAmount; - GetPostEffectParam("Global_User_HDRBloom", hdrBloomAmount); - pParams[0] = m_vHDRFilmCurveParams; - pParams[1] = Vec4(hdrBloomAmount * 0.3f, hdrBloomAmount * 0.3f, hdrBloomAmount * 0.3f, m_fGrainAmount); - pParams[2] = Vec4(m_vColorBalance, m_fHDRSaturation); - pParams[3] = Vec4(m_vHDREyeAdaptation, 1.0f); - pParams[4] = Vec4(m_vHDREyeAdaptationLegacy, 1.0f); -}; - - -I3DEngine::OceanAnimationData C3DEngine::GetOceanAnimationParams() const -{ - I3DEngine::OceanAnimationData data; - if (OceanToggle::IsActive()) - { - data.fWavesAmount = OceanRequest::GetWavesAmount(); - data.fWavesSize = OceanRequest::GetWavesSize(); - data.fWavesSpeed = OceanRequest::GetWavesSpeed(); - data.fWindDirection = OceanRequest::GetWindDirection(); - data.fWindSpeed = OceanRequest::GetWindSpeed(); - } - else - { - data.fWavesAmount = m_oceanWavesAmount; - data.fWavesSize = m_oceanWavesSize; - data.fWavesSpeed = m_oceanWavesSpeed; - data.fWindDirection = m_oceanWindDirection; - data.fWindSpeed = m_oceanWindSpeed; - } - - sincos_tpl(data.fWindDirection, &data.fWindDirectionU, &data.fWindDirectionV); - return data; -} - -IVisArea* C3DEngine::CreateVisArea(uint64 visGUID) -{ - return m_pObjManager ? m_pVisAreaManager->CreateVisArea(visGUID) : 0; -} - -void C3DEngine::DeleteVisArea(IVisArea* pVisArea) -{ - if (!m_pVisAreaManager->IsValidVisAreaPointer((CVisArea*)pVisArea)) - { - Warning("I3DEngine::DeleteVisArea: Invalid VisArea pointer"); - return; - } - if (m_pObjManager) - { - CVisArea* pArea = (CVisArea*)pVisArea; - - PodArray lstEntitiesInArea; - if (pArea->m_pObjectsTree) - { - pArea->m_pObjectsTree->MoveObjectsIntoList(&lstEntitiesInArea, NULL); - } - - // unregister from indoor - for (int i = 0; i < lstEntitiesInArea.Count(); i++) - { - Get3DEngine()->UnRegisterEntityDirect(lstEntitiesInArea[i].pNode); - } - - if (pArea->m_pObjectsTree) - { - assert(pArea->m_pObjectsTree->GetObjectsCount(eMain) == 0); - } - - m_pVisAreaManager->DeleteVisArea((CVisArea*)pVisArea); - - for (int i = 0; i < lstEntitiesInArea.Count(); i++) - { - Get3DEngine()->RegisterEntity(lstEntitiesInArea[i].pNode); - } - } -} - -void C3DEngine::UpdateVisArea(IVisArea* pVisArea, const Vec3* pPoints, int nCount, const char* szName, - const SVisAreaInfo& info, bool bReregisterObjects) -{ - if (!m_pObjManager) - { - return; - } - - CVisArea* pArea = (CVisArea*)pVisArea; - - // PrintMessage("C3DEngine::UpdateVisArea: %s", szName); - - Vec3 vTotalBoxMin = pArea->m_boxArea.min; - Vec3 vTotalBoxMax = pArea->m_boxArea.max; - - m_pVisAreaManager->UpdateVisArea((CVisArea*)pVisArea, pPoints, nCount, szName, info); - - if (((CVisArea*)pVisArea)->m_pObjectsTree && ((CVisArea*)pVisArea)->m_pObjectsTree->GetObjectsCount(eMain)) - { - // merge old and new bboxes - vTotalBoxMin.CheckMin(pArea->m_boxArea.min); - vTotalBoxMax.CheckMax(pArea->m_boxArea.max); - } - else - { - vTotalBoxMin = pArea->m_boxArea.min; - vTotalBoxMax = pArea->m_boxArea.max; - } - - if (bReregisterObjects) - { - m_pObjManager->ReregisterEntitiesInArea(vTotalBoxMin - Vec3(8, 8, 8), vTotalBoxMax + Vec3(8, 8, 8)); - } -} - -IClipVolume* C3DEngine::CreateClipVolume() -{ - return m_pClipVolumeManager->CreateClipVolume(); -} - -void C3DEngine::DeleteClipVolume(IClipVolume* pClipVolume) -{ - m_pClipVolumeManager->DeleteClipVolume(pClipVolume); -} - -void C3DEngine::UpdateClipVolume(IClipVolume* pClipVolume, _smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, bool bActive, uint32 flags, const char* szName) -{ - m_pClipVolumeManager->UpdateClipVolume(pClipVolume, pRenderMesh, pBspTree, worldTM, bActive, flags, szName); -} - -void C3DEngine::ResetParticlesAndDecals() -{ - if (m_pDecalManager) - { - m_pDecalManager->Reset(); - } -} - -IRenderNode* C3DEngine::CreateRenderNode(EERType type) -{ - switch (type) - { - case eERType_Cloud: - { - CCloudRenderNode* pCloud = new CCloudRenderNode(); - return pCloud; - } - case eERType_FogVolume: - { - CFogVolumeRenderNode* pFogVolume = new CFogVolumeRenderNode(); - return pFogVolume; - } - case eERType_Decal: - { - CDecalRenderNode* pDecal = new CDecalRenderNode(); - return pDecal; - } - case eERType_WaterVolume: - { - CWaterVolumeRenderNode* pWaterVolume = new CWaterVolumeRenderNode(); - return pWaterVolume; - } - case eERType_DistanceCloud: - { - CDistanceCloudRenderNode* pRenderNode = new CDistanceCloudRenderNode(); - return pRenderNode; - } - case eERType_VolumeObject: - { - IVolumeObjectRenderNode* pRenderNode = new CVolumeObjectRenderNode(); - return pRenderNode; - } -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) - case eERType_PrismObject: - { - IPrismRenderNode* pRenderNode = new CPrismRenderNode(); - return pRenderNode; - } -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - -#if defined(USE_GEOM_CACHES) - case eERType_GeomCache: - { - IRenderNode* pRenderNode = new CGeomCacheRenderNode(); - return pRenderNode; - } -#endif - } - assert(!"C3DEngine::CreateRenderNode: Specified node type is not supported."); - return 0; -} - -void C3DEngine::DeleteRenderNode(IRenderNode* pRenderNode) -{ - UnRegisterEntityDirect(pRenderNode); - delete pRenderNode; -} - - -Vec3 C3DEngine::GetWind(const AABB& box, bool bIndoors) const -{ - FUNCTION_PROFILER_3DENGINE; - -#if defined(CONSOLE_CONST_CVAR_MODE) - if constexpr (!CVars::e_Wind) -#else - if (!m_pCVars->e_Wind) -#endif - { - return Vec3_Zero; - } - - // Start with global wind. - Vec3 vWind = GetGlobalWind(bIndoors); - -#if defined(CONSOLE_CONST_CVAR_MODE) - if constexpr (CVars::e_WindAreas) -#else - if (m_pCVars->e_WindAreas) -#endif - { - const Physics::WindRequests* windRequests = AZ::Interface::Get(); - if (windRequests) - { - const AZ::Aabb aabb = LyAABBToAZAabb(box); - const AZ::Vector3 wind = windRequests->GetWind(aabb); - vWind += AZVec3ToLYVec3(wind); - } - } - - return vWind; -} - -Vec3 C3DEngine::GetGlobalWind(bool bIndoors) const -{ - FUNCTION_PROFILER_3DENGINE; - - // We assume indoor wind is zero. - if (!m_pCVars->e_Wind || bIndoors) - { - return Vec3_Zero; - } - - const Physics::WindRequests* windRequests = AZ::Interface::Get(); - if (windRequests) - { - const AZ::Vector3 wind = windRequests->GetGlobalWind(); - return AZVec3ToLYVec3(wind); - } - return Vec3_Zero; -} - -bool C3DEngine::SampleWind(Vec3* pSamples, int nSamples, const AABB& volume, bool bIndoors) const -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pCVars->e_Wind || nSamples == 0) - { - return false; - } - - IF (m_nWindSamplePositions < (size_t)nSamples, 0) - { - if (m_pWindSamplePositions) - { - CryModuleMemalignFree(m_pWindSamplePositions); - } - m_nWindSamplePositions = nSamples; - m_pWindSamplePositions = (Vec3*)CryModuleMemalign(m_nWindSamplePositions * sizeof(Vec3), 128u); - } - - Vec3* pPositions = m_pWindSamplePositions; - memcpy(pPositions, pSamples, sizeof(Vec3) * nSamples); - - // Start with global wind. - Vec3 vWind = GetGlobalWind(bIndoors); - - for (int i = 0; i < nSamples; ++i) - { - pSamples[i] = vWind; - } - -#if defined(CONSOLE_CONST_CVAR_MODE) - if constexpr (CVars::e_WindAreas) -#else - if (m_pCVars->e_WindAreas) -#endif - { - const Physics::WindRequests* windRequests = AZ::Interface::Get(); - if (windRequests) - { - for (int i = 0; i < nSamples; ++i) - { - const AZ::Vector3 position = LYVec3ToAZVec3(pPositions[i]); - const AZ::Vector3 wind = windRequests->GetWind(position); - pSamples[i] += AZVec3ToLYVec3(wind); - } - } - } - AZ_UNUSED(volume); - return true; -} - -void C3DEngine::SetupBending(CRenderObject*& pObj, const IRenderNode* pNode, const float fRadiusVert, const SRenderingPassInfo& passInfo, bool alreadyDuplicated) -{ - FUNCTION_PROFILER_3DENGINE; - if (!GetCVars()->e_VegetationBending) - { - return; - } - - if (!pNode->m_pRNTmpData) - { - return; - } - - // Get/Update PhysAreaChanged Proxy - { - // Lock to avoid a situation where two threads simultaneously find that nProxId is ~0, - // which would result in two physics proxies for the same render node which eventually leads to a crash - AUTO_LOCK(m_PhysicsAreaUpdates.m_Mutex); - const uint32 nProxyId = pNode->m_pRNTmpData->nPhysAreaChangedProxyId; - if (nProxyId != ~0) - { - m_PhysicsAreaUpdates.UpdateProxy(pNode, nProxyId); - } - else - { - pNode->m_pRNTmpData->nPhysAreaChangedProxyId = m_PhysicsAreaUpdates.CreateProxy(pNode, Area_Air); - } - } - - CRNTmpData::SRNUserData& userData = pNode->m_pRNTmpData->userData; - const bool needsUpdate = userData.nBendingLastFrame != (passInfo.GetMainFrameID() & ~(3 << 29)); - const bool isFirstFrame = userData.nBendingLastFrame == 0; - - const Vec3& vObjPos = pObj->GetTranslation(); - const float fMaxViewDist = const_cast(pNode)->GetMaxViewDist(); - const float fBendingAttenuation = 1.f - (pObj->m_fDistance / (fMaxViewDist * GetFloatCVar(e_WindBendingDistRatio))); - uint32 bendingMaskOr = 0u; - uint32 bendingMaskAnd = ~FOB_BENDED; - - if (fBendingAttenuation > 0.f && userData.m_Bending.m_fMainBendingScale > 0.f) - { - bendingMaskOr = FOB_BENDED; - bendingMaskAnd = ~0u; - - userData.m_BendingPrev = userData.m_Bending; - - if (needsUpdate) - { - userData.nBendingLastFrame = passInfo.GetMainFrameID(); - - static const float fBEND_RESPONSE = 0.25f; - static const float fMAX_BENDING = 2.f; - static const float fWAVE_PARALLEL = 0.008f; - static const float fWAVE_TRANSVERSE = 0.002f; - - if (!userData.bWindCurrent) - { - userData.vCurrentWind = m_p3DEngine->GetWind(pNode->GetBBox(), !!pNode->GetEntityVisArea()); - userData.bWindCurrent = true; - } - - // Soft clamp bending from wind amplitude. - Vec2 vBending = Vec2(userData.vCurrentWind) * fBEND_RESPONSE; - vBending *= fMAX_BENDING / (fMAX_BENDING + vBending.GetLength()); - vBending *= fBendingAttenuation; - - SBending* pBending = &userData.m_Bending; - - float fWaveFreq = 0.4f / (fRadiusVert + 1.f) + 0.2f; - - if (!userData.bBendingSet) - { - // First time shown, set full bending. - pBending->m_vBending = vBending; - userData.bBendingSet = true; - } - else - { - // Already visible, fade toward current value. - float fInterp = min(gEnv->pTimer->GetFrameTime() * fWaveFreq * 0.5f, 1.f); - pBending->m_vBending += (vBending - pBending->m_vBending) * fInterp; - } - - pBending->m_Waves[0].m_Level = 0.000f; - pBending->m_Waves[0].m_Freq = fWaveFreq; - pBending->m_Waves[0].m_Phase = vObjPos.x * 0.125f; - pBending->m_Waves[0].m_Amp = pBending->m_vBending.x * fWAVE_PARALLEL + pBending->m_vBending.y * fWAVE_TRANSVERSE; - pBending->m_Waves[0].m_eWFType = eWF_Sin; - - pBending->m_Waves[1].m_Level = 0.000f; - pBending->m_Waves[1].m_Freq = fWaveFreq * 1.125f; - pBending->m_Waves[1].m_Phase = vObjPos.y * 0.125f; - pBending->m_Waves[1].m_Amp = pBending->m_vBending.y * fWAVE_PARALLEL - pBending->m_vBending.x * fWAVE_TRANSVERSE; - pBending->m_Waves[1].m_eWFType = eWF_Sin; - } - - // When starting fresh, we use the same bend info for previous so - // that we don't get crazy motion changes. - if (isFirstFrame) - { - userData.m_BendingPrev = userData.m_Bending; - } - } - - if (!alreadyDuplicated) - { - pObj = GetRenderer()->EF_DuplicateRO(pObj, passInfo); - } - SRenderObjData* pOD = GetRenderer()->EF_GetObjData(pObj, true, passInfo.ThreadID()); - if (!pOD) - { - return; - } - - pObj->m_ObjFlags |= bendingMaskOr | FOB_DYNAMIC_OBJECT | FOB_MOTION_BLUR; - pObj->m_ObjFlags &= bendingMaskAnd; - pOD->m_pBending = Get3DEngine()->GetBendingEntry(&userData.m_Bending, passInfo); - pOD->m_BendingPrev = Get3DEngine()->GetBendingEntry(&userData.m_BendingPrev, passInfo); -} - -IVisArea* C3DEngine::GetVisAreaFromPos(const Vec3& vPos) -{ - if (m_pObjManager && m_pVisAreaManager) - { - return m_pVisAreaManager->GetVisAreaFromPos(vPos); - } - - return 0; -} - -bool C3DEngine::IntersectsVisAreas(const AABB& box, void** pNodeCache) -{ - if (m_pObjManager && m_pVisAreaManager) - { - return m_pVisAreaManager->IntersectsVisAreas(box, pNodeCache); - } - return false; -} - -bool C3DEngine::ClipToVisAreas(IVisArea* pInside, Sphere& sphere, Vec3 const& vNormal, void* pNodeCache) -{ - if (pInside) - { - return pInside->ClipToVisArea(true, sphere, vNormal); - } - else if (m_pVisAreaManager) - { - return m_pVisAreaManager->ClipOutsideVisAreas(sphere, vNormal, pNodeCache); - } - return false; -} - -bool C3DEngine::IsVisAreasConnected(IVisArea* pArea1, IVisArea* pArea2, int nMaxRecursion, bool bSkipDisabledPortals) -{ - if (pArea1 == pArea2) - { - return (true); // includes the case when both pArea1 & pArea2 are NULL (totally outside) - } - // not considered by the other checks - if (!pArea1 || !pArea2) - { - return (false); // avoid a crash - better to put this check only - } - // here in one place than in all the places where this function is called - - nMaxRecursion *= 2; // include portals since portals are the areas - - if (m_pObjManager && m_pVisAreaManager) - { - return ((CVisArea*)pArea1)->FindVisArea((CVisArea*)pArea2, nMaxRecursion, bSkipDisabledPortals); - } - - return false; -} - -bool C3DEngine::IsOutdoorVisible() -{ - if (m_pObjManager && m_pVisAreaManager) - { - return m_pVisAreaManager->IsOutdoorAreasVisible(); - } - - return false; -} - -void C3DEngine::EnableOceanRendering(bool bOcean) -{ - m_bOcean = bOcean; -} - -IObjManager* C3DEngine::GetObjManager() -{ - return Cry3DEngineBase::GetObjManager(); -} - -////////////////////////////////////////////////////////////////////////// -IMaterialHelpers& C3DEngine::GetMaterialHelpers() -{ - return Cry3DEngineBase::GetMatMan()->s_materialHelpers; -} - -IMaterialManager* C3DEngine::GetMaterialManager() -{ - return Cry3DEngineBase::GetMatMan(); -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::AddTextureLoadHandler(ITextureLoadHandler* pHandler) -{ - stl::push_back_unique(m_textureLoadHandlers, pHandler); -} - -void C3DEngine::RemoveTextureLoadHandler(ITextureLoadHandler* pHandler) -{ - stl::find_and_erase(m_textureLoadHandlers, pHandler); -} - -ITextureLoadHandler* C3DEngine::GetTextureLoadHandlerForImage(const char* path) -{ - const char* ext = PathUtil::GetExt(path); - - for (TTextureLoadHandlers::iterator iter = m_textureLoadHandlers.begin(); iter != m_textureLoadHandlers.end(); iter++) - { - if ((*iter)->SupportsExtension(ext)) - { - return *iter; - } - } - - return nullptr; -} - -void C3DEngine::CheckMemoryHeap() -{ - assert (CryMemory::IsHeapValid()); -} - -////////////////////////////////////////////////////////////////////////// -int C3DEngine::GetLoadedObjectCount() -{ - int nObjectsLoaded = m_pObjManager ? m_pObjManager->GetLoadedObjectCount() : 0; - return nObjectsLoaded; -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount) -{ - if (m_pObjManager) - { - m_pObjManager->GetLoadedStatObjArray(pObjectsArray, nCount); - } - else - { - nCount = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::GetObjectsStreamingStatus(SObjectsStreamingStatus& outStatus) -{ - if (m_pObjManager) - { - m_pObjManager->GetObjectsStreamingStatus(outStatus); - } - else - { - memset(&outStatus, 0, sizeof(outStatus)); - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::GetStreamingSubsystemData(int subsystem, SStremaingBandwidthData& outData) -{ - switch (subsystem) - { - case eStreamTaskTypeSound: - // Audio: bandwidth stats - break; - case eStreamTaskTypeGeometry: - m_pObjManager->GetBandwidthStats(&outData.fBandwidthRequested); - break; - case eStreamTaskTypeTexture: - gEnv->pRenderer->GetBandwidthStats(&outData.fBandwidthRequested); - break; - } - -#if defined(STREAMENGINE_ENABLE_STATS) - gEnv->pSystem->GetStreamEngine()->GetBandwidthStats((EStreamTaskType)subsystem, &outData.fBandwidthActual); -#endif -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::DeleteEntityDecals(IRenderNode* pEntity) -{ - if (m_pDecalManager && pEntity && (pEntity->m_nInternalFlags & IRenderNode::DECAL_OWNER)) - { - m_pDecalManager->OnEntityDeleted(pEntity); - } -} - -void C3DEngine::DeleteDecalsInRange(AABB* pAreaBox, IRenderNode* pEntity) -{ - if (m_pDecalManager) - { - m_pDecalManager->DeleteDecalsInRange(pAreaBox, pEntity); - } -} - -void C3DEngine::LockCGFResources() -{ - if (m_pObjManager) - { - m_pObjManager->SetLockCGFResources(true); - } -} - -void C3DEngine::UnlockCGFResources() -{ - if (m_pObjManager) - { - bool bNeedToFreeCGFs = m_pObjManager->IsLockCGFResources(); - m_pObjManager->SetLockCGFResources(false); - if (bNeedToFreeCGFs) - { - m_pObjManager->FreeNotUsedCGFs(); - } - } -} - -void C3DEngine::FreeUnusedCGFResources() -{ - if (m_pObjManager) - { - m_pObjManager->FreeNotUsedCGFs(); - } -} - -void CLightEntity::ShadowMapInfo::Release([[maybe_unused]] struct IRenderer* pRenderer) -{ - delete this; -} - -////////////////////////////////////////////////////////////////////////// -IIndexedMesh* C3DEngine::CreateIndexedMesh() -{ - return new CIndexedMesh(); -} - -void C3DEngine::SerializeState(TSerialize ser) -{ - ser.Value("m_bOcean", m_bOcean); - ser.Value("m_moonRotationLatitude", m_moonRotationLatitude); - ser.Value("m_moonRotationLongitude", m_moonRotationLongitude); - ser.Value("m_eShadowMode", *(alias_cast(&m_eShadowMode))); - if (ser.IsReading()) - { - UpdateMoonDirection(); - } - - if (m_pDecalManager) - { - m_pDecalManager->Serialize(ser); - } - - m_pTimeOfDay->Serialize(ser); -} - -void C3DEngine::PostSerialize(bool /*bReading*/) -{ -} - -void C3DEngine::InitMaterialDefautMappingAxis(_smart_ptr pMat) -{ - uint8 arrProj[3] = {'X', 'Y', 'Z'}; - pMat->m_ucDefautMappingAxis = 'Z'; - pMat->m_fDefautMappingScale = 1.f; - for (int c = 0; c < 3 && c < pMat->GetSubMtlCount(); c++) - { - _smart_ptr pSubMat = (_smart_ptr)pMat->GetSubMtl(c); - pSubMat->m_ucDefautMappingAxis = arrProj[c]; - pSubMat->m_fDefautMappingScale = pMat->m_fDefautMappingScale; - } -} - -////////////////////////////////////////////////////////////////////////// -CContentCGF* C3DEngine::CreateChunkfileContent(const char* filename) -{ - return new CContentCGF(filename); -} -void C3DEngine::ReleaseChunkfileContent(CContentCGF* pCGF) -{ - delete pCGF; -} - -bool C3DEngine::LoadChunkFileContent(CContentCGF* pCGF, const char* filename, bool bNoWarningMode, bool bCopyChunkFile) -{ - CLoadLogListener listener; - - if (!pCGF) - { - FileWarning(0, filename, "CGF Loading Failed: no content instance passed"); - } - else - { - CLoaderCGF cgf; - - CReadOnlyChunkFile* pChunkFile = new CReadOnlyChunkFile(bCopyChunkFile, bNoWarningMode); - - if (cgf.LoadCGF(pCGF, filename, *pChunkFile, &listener)) - { - pCGF->SetChunkFile(pChunkFile); - return true; - } - - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "%s: Failed to load chunk file: '%s'", __FUNCTION__, cgf.GetLastError()); - delete pChunkFile; - } - - return false; -} - -bool C3DEngine::LoadChunkFileContentFromMem(CContentCGF* pCGF, const void* pData, size_t nDataLen, uint32 nLoadingFlags, bool bNoWarningMode, bool bCopyChunkFile) -{ - if (!pCGF) - { - FileWarning(0, "", "CGF Loading Failed: no content instance passed"); - } - else - { - CLoadLogListener listener; - - CLoaderCGF cgf; - CReadOnlyChunkFile* pChunkFile = new CReadOnlyChunkFile(bCopyChunkFile, bNoWarningMode); - - if (cgf.LoadCGFFromMem(pCGF, pData, nDataLen, *pChunkFile, &listener, nLoadingFlags)) - { - pCGF->SetChunkFile(pChunkFile); - return true; - } - - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "%s: Failed to load chunk file: '%s'", __FUNCTION__, cgf.GetLastError()); - delete pChunkFile; - } - - return false; -} - -IChunkFile* C3DEngine::CreateChunkFile(bool bReadOnly) -{ - if (bReadOnly) - { - return new CReadOnlyChunkFile(false); - } - else - { - return new CChunkFile; - } -} - -////////////////////////////////////////////////////////////////////////// - -ChunkFile::IChunkFileWriter* C3DEngine::CreateChunkFileWriter(EChunkFileFormat eFormat, AZ::IO::IArchive* pPak, const char* filename) const -{ - ChunkFile::CryPakFileWriter* const p = new ChunkFile::CryPakFileWriter(); - - if (!p) - { - return 0; - } - - if (!p->Create(pPak, filename)) - { - delete p; - return 0; - } - - const ChunkFile::MemorylessChunkFileWriter::EChunkFileFormat fmt = - (eFormat == I3DEngine::eChunkFileFormat_0x745) - ? ChunkFile::MemorylessChunkFileWriter::eChunkFileFormat_0x745 - : ChunkFile::MemorylessChunkFileWriter::eChunkFileFormat_0x746; - - return new ChunkFile::MemorylessChunkFileWriter(fmt, p); -} - -void C3DEngine::ReleaseChunkFileWriter(ChunkFile::IChunkFileWriter* p) const -{ - if (p) - { - delete p->GetWriter(); - delete p; - } -} - -////////////////////////////////////////////////////////////////////////// - -bool C3DEngine::CreateOcean(_smart_ptr pTerrainWaterMat, float waterLevel) -{ - // make ocean surface - SAFE_DELETE(m_pOcean); - - if (pTerrainWaterMat == nullptr) - { - if (!m_pTerrainWaterMat) - { - return false; - } - - pTerrainWaterMat = m_pTerrainWaterMat; - } - - if (OceanToggle::IsActive() ? OceanRequest::OceanIsEnabled() : (waterLevel > 0)) - { - m_pOcean = new COcean(pTerrainWaterMat, waterLevel); - } - return m_pOcean != nullptr; -} - -void C3DEngine::DeleteOcean() -{ - SAFE_DELETE(m_pOcean); -} - -void C3DEngine::ChangeOceanMaterial(_smart_ptr pMat) -{ - if (m_pOcean) - { - m_pOcean->SetMaterial(pMat); - } -} - -void C3DEngine::ChangeOceanWaterLevel(float fWaterLevel) -{ - COcean::SetWaterLevelInfo(fWaterLevel); - - if (m_pOcean) - { - m_pOcean->SetWaterLevel(fWaterLevel); - } -} - -void C3DEngine::SetStreamableListener(IStreamedObjectListener* pListener) -{ - m_pStreamListener = pListener; -} - -void C3DEngine::PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum) -{ - LOADING_TIME_PROFILE_SECTION; - - if (GetVisAreaManager()) - { - GetVisAreaManager()->PrecacheLevel(bPrecacheAllVisAreas, pPrecachePoints, nPrecachePointsNum); - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::SetGlobalParameter(E3DEngineParameter param, const Vec3& v) -{ - float fValue = v.x; - switch (param) - { - case E3DPARAM_SUN_COLOR: - SetSunColor(v); - break; - - case E3DPARAM_SUN_SPECULAR_MULTIPLIER: - m_fSunSpecMult = v.x; - break; - - case E3DPARAM_AMBIENT_GROUND_COLOR: - m_vAmbGroundCol = v; - break; - case E3DPARAM_AMBIENT_MIN_HEIGHT: - m_fAmbMaxHeight = v.x; - break; - case E3DPARAM_AMBIENT_MAX_HEIGHT: - m_fAmbMinHeight = v.x; - break; - - case E3DPARAM_SKY_HIGHLIGHT_POS: - m_vSkyHightlightPos = v; - break; - case E3DPARAM_SKY_HIGHLIGHT_COLOR: - m_vSkyHightlightCol = v; - break; - case E3DPARAM_SKY_HIGHLIGHT_SIZE: - m_fSkyHighlightSize = fValue > 0.0f ? fValue : 0.0f; - break; - case E3DPARAM_VOLFOG_RAMP: - m_volFogRamp = v; - break; - case E3DPARAM_VOLFOG_SHADOW_RANGE: - m_volFogShadowRange = v; - break; - case E3DPARAM_VOLFOG_SHADOW_DARKENING: - m_volFogShadowDarkening = v; - break; - case E3DPARAM_VOLFOG_SHADOW_ENABLE: - m_volFogShadowEnable = v; - break; - case E3DPARAM_VOLFOG2_CTRL_PARAMS: - m_volFog2CtrlParams = v; - break; - case E3DPARAM_VOLFOG2_SCATTERING_PARAMS: - m_volFog2ScatteringParams = v; - break; - case E3DPARAM_VOLFOG2_RAMP: - m_volFog2Ramp = v; - break; - case E3DPARAM_VOLFOG2_COLOR: - m_volFog2Color = v; - break; - case E3DPARAM_VOLFOG2_GLOBAL_DENSITY: - m_volFog2GlobalDensity = v; - break; - case E3DPARAM_VOLFOG2_HEIGHT_DENSITY: - m_volFog2HeightDensity = v; - break; - case E3DPARAM_VOLFOG2_HEIGHT_DENSITY2: - m_volFog2HeightDensity2 = v; - break; - case E3DPARAM_VOLFOG2_COLOR1: - m_volFog2Color1 = v; - break; - case E3DPARAM_VOLFOG2_COLOR2: - m_volFog2Color2 = v; - break; - case E3DPARAM_NIGHSKY_HORIZON_COLOR: - m_nightSkyHorizonCol = v; - break; - case E3DPARAM_NIGHSKY_ZENITH_COLOR: - m_nightSkyZenithCol = v; - break; - case E3DPARAM_NIGHSKY_ZENITH_SHIFT: - m_nightSkyZenithColShift = v.x; - break; - case E3DPARAM_NIGHSKY_STAR_INTENSITY: - m_nightSkyStarIntensity = v.x; - break; - case E3DPARAM_NIGHSKY_MOON_COLOR: - m_nightMoonCol = v; - break; - case E3DPARAM_NIGHSKY_MOON_SIZE: - m_nightMoonSize = v.x; - break; - case E3DPARAM_NIGHSKY_MOON_INNERCORONA_COLOR: - m_nightMoonInnerCoronaCol = v; - break; - case E3DPARAM_NIGHSKY_MOON_INNERCORONA_SCALE: - m_nightMoonInnerCoronaScale = v.x; - break; - case E3DPARAM_NIGHSKY_MOON_OUTERCORONA_COLOR: - m_nightMoonOuterCoronaCol = v; - break; - case E3DPARAM_NIGHSKY_MOON_OUTERCORONA_SCALE: - m_nightMoonOuterCoronaScale = v.x; - break; - case E3DPARAM_OCEANFOG_COLOR: - m_oceanFogColor = v; - break; - case E3DPARAM_OCEANFOG_DENSITY: - m_oceanFogDensity = v.x; - break; - case E3DPARAM_SKY_MOONROTATION: - m_moonRotationLatitude = v.x; - m_moonRotationLongitude = v.y; - UpdateMoonDirection(); - break; - case E3DPARAM_SKYBOX_MULTIPLIER: - m_skyboxMultiplier = v.x; - break; - case E3DPARAM_DAY_NIGHT_INDICATOR: - m_dayNightIndicator = v.x; - // Audio: Set daylight parameter - break; - case E3DPARAM_FOG_COLOR2: - m_fogColor2 = v; - break; - case E3DPARAM_FOG_RADIAL_COLOR: - m_fogColorRadial = v; - break; - case E3DPARAM_VOLFOG_HEIGHT_DENSITY: - m_volFogHeightDensity = Vec3(v.x, v.y, 0); - break; - case E3DPARAM_VOLFOG_HEIGHT_DENSITY2: - m_volFogHeightDensity2 = Vec3(v.x, v.y, 0); - break; - case E3DPARAM_VOLFOG_GRADIENT_CTRL: - m_volFogGradientCtrl = v; - break; - case E3DPARAM_VOLFOG_GLOBAL_DENSITY: - m_volFogGlobalDensity = v.x; - m_volFogFinalDensityClamp = v.z; - break; - case E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR: - m_pPhotoFilterColor = Vec4(v.x, v.y, v.z, 1); - GetPostEffectBaseGroup()->SetParam("clr_ColorGrading_PhotoFilterColor", m_pPhotoFilterColor); - break; - case E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_DENSITY: - m_fPhotoFilterColorDensity = fValue; - GetPostEffectBaseGroup()->SetParam("ColorGrading_PhotoFilterColorDensity", m_fPhotoFilterColorDensity); - break; - case E3DPARAM_COLORGRADING_FILTERS_GRAIN: - m_fGrainAmount = fValue; - GetPostEffectBaseGroup()->SetParam("ColorGrading_GrainAmount", m_fGrainAmount); - break; - case E3DPARAM_SKY_SKYBOX_ANGLE: // sky box rotation - m_fSkyBoxAngle = fValue; - break; - case E3DPARAM_SKY_SKYBOX_STRETCHING: // sky box stretching - m_fSkyBoxStretching = fValue; - break; - case E3DPARAM_HDR_FILMCURVE_SHOULDER_SCALE: - m_vHDRFilmCurveParams.x = v.x; - break; - case E3DPARAM_HDR_FILMCURVE_LINEAR_SCALE: - m_vHDRFilmCurveParams.y = v.x; - break; - case E3DPARAM_HDR_FILMCURVE_TOE_SCALE: - m_vHDRFilmCurveParams.z = v.x; - break; - case E3DPARAM_HDR_FILMCURVE_WHITEPOINT: - m_vHDRFilmCurveParams.w = v.x; - break; - case E3DPARAM_HDR_EYEADAPTATION_PARAMS: - m_vHDREyeAdaptation = v; - break; - case E3DPARAM_HDR_EYEADAPTATION_PARAMS_LEGACY: - m_vHDREyeAdaptationLegacy = v; - break; - case E3DPARAM_HDR_BLOOM_AMOUNT: - m_fHDRBloomAmount = v.x; - break; - case E3DPARAM_HDR_COLORGRADING_COLOR_SATURATION: - m_fHDRSaturation = v.x; - break; - case E3DPARAM_HDR_COLORGRADING_COLOR_BALANCE: - m_vColorBalance = v; - break; - case E3DPARAM_CLOUDSHADING_MULTIPLIERS: - m_fCloudShadingSunLightMultiplier = (v.x >= 0) ? v.x : 0; - m_fCloudShadingSkyLightMultiplier = (v.y >= 0) ? v.y : 0; - break; - case E3DPARAM_CLOUDSHADING_SUNCOLOR: - m_vCloudShadingCustomSunColor = v; - break; - case E3DPARAM_CLOUDSHADING_SKYCOLOR: - m_vCloudShadingCustomSkyColor = v; - break; - case E3DPARAM_NIGHSKY_MOON_DIRECTION: // moon direction is fixed per level or updated via FG node (E3DPARAM_SKY_MOONROTATION) - default: - assert(0); - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::GetGlobalParameter(E3DEngineParameter param, Vec3& v) -{ - switch (param) - { - case E3DPARAM_SUN_COLOR: - v = GetSunColor(); - break; - - case E3DPARAM_SUN_SPECULAR_MULTIPLIER: - v = Vec3(m_fSunSpecMult, 0, 0); - break; - - case E3DPARAM_AMBIENT_GROUND_COLOR: - v = m_vAmbGroundCol; - break; - case E3DPARAM_AMBIENT_MIN_HEIGHT: - v = Vec3(m_fAmbMaxHeight, 0, 0); - break; - case E3DPARAM_AMBIENT_MAX_HEIGHT: - v = Vec3(m_fAmbMinHeight, 0, 0); - break; - case E3DPARAM_SKY_HIGHLIGHT_POS: - v = m_vSkyHightlightPos; - break; - case E3DPARAM_SKY_HIGHLIGHT_COLOR: - v = m_vSkyHightlightCol; - break; - case E3DPARAM_SKY_HIGHLIGHT_SIZE: - v = Vec3(m_fSkyHighlightSize, 0, 0); - break; - case E3DPARAM_VOLFOG_RAMP: - v = m_volFogRamp; - break; - case E3DPARAM_VOLFOG_SHADOW_RANGE: - v = m_volFogShadowRange; - break; - case E3DPARAM_VOLFOG_SHADOW_DARKENING: - v = m_volFogShadowDarkening; - break; - case E3DPARAM_VOLFOG_SHADOW_ENABLE: - v = m_volFogShadowEnable; - break; - case E3DPARAM_VOLFOG2_CTRL_PARAMS: - v = m_volFog2CtrlParams; - break; - case E3DPARAM_VOLFOG2_SCATTERING_PARAMS: - v = m_volFog2ScatteringParams; - break; - case E3DPARAM_VOLFOG2_RAMP: - v = m_volFog2Ramp; - break; - case E3DPARAM_VOLFOG2_COLOR: - v = m_volFog2Color; - break; - case E3DPARAM_VOLFOG2_GLOBAL_DENSITY: - v = m_volFog2GlobalDensity; - break; - case E3DPARAM_VOLFOG2_HEIGHT_DENSITY: - v = m_volFog2HeightDensity; - break; - case E3DPARAM_VOLFOG2_HEIGHT_DENSITY2: - v = m_volFog2HeightDensity2; - break; - case E3DPARAM_VOLFOG2_COLOR1: - v = m_volFog2Color1; - break; - case E3DPARAM_VOLFOG2_COLOR2: - v = m_volFog2Color2; - break; - case E3DPARAM_NIGHSKY_HORIZON_COLOR: - v = m_nightSkyHorizonCol; - break; - case E3DPARAM_NIGHSKY_ZENITH_COLOR: - v = m_nightSkyZenithCol; - break; - case E3DPARAM_NIGHSKY_ZENITH_SHIFT: - v = Vec3(m_nightSkyZenithColShift, 0, 0); - break; - case E3DPARAM_NIGHSKY_STAR_INTENSITY: - v = Vec3(m_nightSkyStarIntensity, 0, 0); - break; - case E3DPARAM_NIGHSKY_MOON_DIRECTION: - v = m_moonDirection; - break; - case E3DPARAM_NIGHSKY_MOON_COLOR: - v = m_nightMoonCol; - break; - case E3DPARAM_NIGHSKY_MOON_SIZE: - v = Vec3(m_nightMoonSize, 0, 0); - break; - case E3DPARAM_NIGHSKY_MOON_INNERCORONA_COLOR: - v = m_nightMoonInnerCoronaCol; - break; - case E3DPARAM_NIGHSKY_MOON_INNERCORONA_SCALE: - v = Vec3(m_nightMoonInnerCoronaScale, 0, 0); - break; - case E3DPARAM_NIGHSKY_MOON_OUTERCORONA_COLOR: - v = m_nightMoonOuterCoronaCol; - break; - case E3DPARAM_NIGHSKY_MOON_OUTERCORONA_SCALE: - v = Vec3(m_nightMoonOuterCoronaScale, 0, 0); - break; - case E3DPARAM_SKY_MOONROTATION: - v = Vec3(m_moonRotationLatitude, m_moonRotationLongitude, 0); - break; - case E3DPARAM_OCEANFOG_COLOR: - v = m_oceanFogColor; - break; - case E3DPARAM_OCEANFOG_DENSITY: - v = Vec3(m_oceanFogDensity, 0, 0); - break; - case E3DPARAM_SKYBOX_MULTIPLIER: - v = Vec3(m_skyboxMultiplier, 0, 0); - break; - case E3DPARAM_DAY_NIGHT_INDICATOR: - v = Vec3(m_dayNightIndicator, 0, 0); - break; - case E3DPARAM_FOG_COLOR2: - v = m_fogColor2; - break; - case E3DPARAM_FOG_RADIAL_COLOR: - v = m_fogColorRadial; - break; - case E3DPARAM_VOLFOG_HEIGHT_DENSITY: - v = m_volFogHeightDensity; - break; - case E3DPARAM_VOLFOG_HEIGHT_DENSITY2: - v = m_volFogHeightDensity2; - break; - case E3DPARAM_VOLFOG_GRADIENT_CTRL: - v = m_volFogGradientCtrl; - break; - case E3DPARAM_VOLFOG_GLOBAL_DENSITY: - v = Vec3(m_volFogGlobalDensity, m_volFogGlobalDensityMultiplierLDR, m_volFogFinalDensityClamp); - break; - case E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR: - v = Vec3(m_pPhotoFilterColor.x, m_pPhotoFilterColor.y, m_pPhotoFilterColor.z); - break; - case E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_DENSITY: - v = Vec3(m_fPhotoFilterColorDensity, 0, 0); - break; - case E3DPARAM_COLORGRADING_FILTERS_GRAIN: - v = Vec3(m_fGrainAmount, 0, 0); - break; - case E3DPARAM_HDR_FILMCURVE_SHOULDER_SCALE: - v = Vec3(m_vHDRFilmCurveParams.x, 0, 0); - break; - case E3DPARAM_HDR_FILMCURVE_LINEAR_SCALE: - v = Vec3(m_vHDRFilmCurveParams.y, 0, 0); - break; - case E3DPARAM_HDR_FILMCURVE_TOE_SCALE: - v = Vec3(m_vHDRFilmCurveParams.z, 0, 0); - break; - case E3DPARAM_HDR_FILMCURVE_WHITEPOINT: - v = Vec3(m_vHDRFilmCurveParams.w, 0, 0); - break; - case E3DPARAM_HDR_EYEADAPTATION_PARAMS: - v = m_vHDREyeAdaptation; - break; - case E3DPARAM_HDR_EYEADAPTATION_PARAMS_LEGACY: - v = m_vHDREyeAdaptationLegacy; - break; - case E3DPARAM_HDR_BLOOM_AMOUNT: - v = Vec3(m_fHDRBloomAmount, 0, 0); - break; - case E3DPARAM_HDR_COLORGRADING_COLOR_SATURATION: - v = Vec3(m_fHDRSaturation, 0, 0); - break; - case E3DPARAM_HDR_COLORGRADING_COLOR_BALANCE: - v = m_vColorBalance; - break; - case E3DPARAM_CLOUDSHADING_MULTIPLIERS: - v = Vec3(m_fCloudShadingSunLightMultiplier, m_fCloudShadingSkyLightMultiplier, 0); - break; - case E3DPARAM_CLOUDSHADING_SUNCOLOR: - v = m_vCloudShadingCustomSunColor; - break; - case E3DPARAM_CLOUDSHADING_SKYCOLOR: - v = m_vCloudShadingCustomSkyColor; - break; - default: - assert(0); - break; - } -} - -////////////////////////////////////////////////////////////////////////// - -void C3DEngine::SetCachedShadowBounds(const AABB& shadowBounds, float fAdditionalCascadesScale) -{ - const Vec3 boxSize = shadowBounds.GetSize(); - const bool isValid = boxSize.x > 0 && boxSize.y > 0 && boxSize.z > 0; - - m_CachedShadowsBounds = isValid ? shadowBounds : AABB(AABB::RESET); - m_fCachedShadowsCascadeScale = fAdditionalCascadesScale; - - m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate; -} - -////////////////////////////////////////////////////////////////////////// - -void C3DEngine::SetRecomputeCachedShadows(uint nUpdateStrategy) -{ - m_nCachedShadowsUpdateStrategy = nUpdateStrategy; -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::SetShadowsCascadesBias(const float* pCascadeConstBias, const float* pCascadeSlopeBias) -{ - memcpy(m_pShadowCascadeConstBias, pCascadeConstBias, sizeof(float) * MAX_SHADOW_CASCADES_NUM); - memcpy(m_pShadowCascadeSlopeBias, pCascadeSlopeBias, sizeof(float) * MAX_SHADOW_CASCADES_NUM); -} - -int C3DEngine::GetShadowsCascadeCount([[maybe_unused]] const CDLight* pLight) const -{ - int nCascadeCount = m_eShadowMode == ESM_HIGHQUALITY ? MAX_GSM_LODS_NUM : GetCVars()->e_GsmLodsNum; - return clamp_tpl(nCascadeCount, 0, MAX_GSM_LODS_NUM); -} - -////////////////////////////////////////////////////////////////////////// -bool C3DEngine::CheckIntersectClouds(const Vec3& p1, const Vec3& p2) -{ - return m_pCloudsManager->CheckIntersectClouds(p1, p2); -} - -void C3DEngine::OnRenderMeshDeleted(IRenderMesh* pRenderMesh) -{ - if (m_pDecalManager) - { - m_pDecalManager->OnRenderMeshDeleted(pRenderMesh); - } -} - -bool C3DEngine::RayObjectsIntersection2D([[maybe_unused]] Vec3 vStart, [[maybe_unused]] Vec3 vEnd, [[maybe_unused]] Vec3& vHitPoint, [[maybe_unused]] EERType eERType) -{ -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - - float fClosestHitDistance = 1000000; - - AABB aabb; - aabb.Reset(); - aabb.Add(vStart); - aabb.Add(vEnd); - if (IsObjectTreeReady()) - { - if (Overlap::AABB_AABB2D(aabb, m_pObjectsTree->GetNodeBox())) //!!!mpeykov: 2D? - { - m_pObjectsTree->RayObjectsIntersection2D(vStart, vEnd, vHitPoint, fClosestHitDistance, eERType); - } - } - - return (fClosestHitDistance < 1000000); - -#else - - assert(!"C3DEngine::RayObjectsIntersection2D not supported on consoles"); - return 0; - -#endif -} - -bool C3DEngine::RenderMeshRayIntersection(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pCustomMtl) -{ - return CRenderMeshUtils::RayIntersection(pRenderMesh, hitInfo, pCustomMtl); -} - -static SBending sBendRemoved; - -void C3DEngine::FreeRNTmpData(CRNTmpData** ppInfo) -{ - AUTO_LOCK(m_checkCreateRNTmpData); - - CRNTmpData* pTmpRNTData = (*ppInfo); - - assert(pTmpRNTData->pNext != &m_LTPRootFree); - assert(pTmpRNTData->pPrev != &m_LTPRootFree); - assert(pTmpRNTData != &m_LTPRootUsed); - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - CryFatalError("CRNTmpData should only be allocated and free'd on main thread."); - } - - if (pTmpRNTData != &m_LTPRootUsed) - { - pTmpRNTData->Unlink(); - } - - // Mark for phys area changed proxy for deletion - if (pTmpRNTData->nPhysAreaChangedProxyId != ~0) - { - m_PhysicsAreaUpdates.ResetProxy(pTmpRNTData->nPhysAreaChangedProxyId); - pTmpRNTData->nPhysAreaChangedProxyId = ~0; - } - - if (pTmpRNTData->nFrameInfoId != ~0) - { - m_elementFrameInfo[pTmpRNTData->nFrameInfoId].Reset(); - pTmpRNTData->nFrameInfoId = ~0; - } - - { -#ifdef SUPP_HWOBJ_OCCL - if (pTmpRNTData->userData.m_OcclState.pREOcclusionQuery) - { - pTmpRNTData->userData.m_OcclState.pREOcclusionQuery->Release(false); - pTmpRNTData->userData.m_OcclState.pREOcclusionQuery = NULL; - } -#endif - } - - if (pTmpRNTData != &m_LTPRootUsed) - { - pTmpRNTData->Link(&m_LTPRootFree); - *(pTmpRNTData->pOwnerRef) = NULL; - } -} - -void C3DEngine::UpdateRNTmpDataPool(bool bFreeAll) -{ - // if we are freeing the whole pool, make sure no jobs are still running which could use the RNTmpObjects - if (bFreeAll) - { - threadID nThreadID; - gEnv->pRenderer->EF_Query(EFQ_MainThreadList, nThreadID); - gEnv->pRenderer->GetFinalizeRendItemJobExecutor(nThreadID)->WaitForCompletion(); - gEnv->pRenderer->GetFinalizeShadowRendItemJobExecutor(nThreadID)->WaitForCompletion(); - } - //CryLogAlways("UpdateRNTmpDataPool bFreeAll 0x%x nMainFrameID 0X%x", bFreeAll, nMainFrameID ); - FUNCTION_PROFILER_3DENGINE; - - // Ensure continues memory - m_elementFrameInfo.CoalesceMemory(); - - const uint32 nSize = m_elementFrameInfo.size(); - if (nSize == 0) - { - return; - } - - const uint32 nMainFrameID = GetRenderer()->GetFrameID(false); - const uint32 nTmpDataMaxFrames = (uint32)GetCVars()->e_RNTmpDataPoolMaxFrames; - - if (!bFreeAll && nMainFrameID >= nTmpDataMaxFrames) - { - const uint32 nLastValidFrame = nMainFrameID - nTmpDataMaxFrames; - - uint32 nNumItemsToDelete = 0; - - SFrameInfo* pFrontIter = &m_elementFrameInfo[0]; - SFrameInfo* pBackIter = &m_elementFrameInfo[nSize - 1]; - SFrameInfo* pHead = pFrontIter; - - // Handle single element case - IF (nSize == 1, 0) - { - if (pFrontIter->bIsValid && pFrontIter->nLastUsedFrameId >= nLastValidFrame) - { - if (pFrontIter->bIsValid) - { - FreeRNTmpData(pFrontIter->ppRNTmpData); - } - - ++nNumItemsToDelete; - } - } - - // Move invalid elements to back of array and free if timed out - while (pFrontIter < pBackIter) - { - while (pFrontIter->bIsValid && pFrontIter->nLastUsedFrameId >= nLastValidFrame && pFrontIter < pBackIter) - { - ++pFrontIter; - } // Find invalid element at front - while (!(pBackIter->bIsValid && pBackIter->nLastUsedFrameId >= nLastValidFrame) && pFrontIter < pBackIter) // Find valid element at back - { - // Element timed out - if (pBackIter->bIsValid) - { - FreeRNTmpData(pBackIter->ppRNTmpData); - pBackIter->bIsValid = false; - } - - --pBackIter; - ++nNumItemsToDelete; - } - - if (pFrontIter < pBackIter) - { - // Element timed out - if (pFrontIter->bIsValid) - { - FreeRNTmpData(pFrontIter->ppRNTmpData); - } - - // Replace invalid front element with back element - // Note: No need to swap because we cut the data from the array at the end anyway - memcpy(pFrontIter, pBackIter, sizeof(SFrameInfo)); - (*pFrontIter->ppRNTmpData)->nFrameInfoId = (uint32)(pFrontIter - pHead); - - pBackIter->bIsValid = false; // safety - pBackIter->ppRNTmpData = 0; - - --pBackIter; - ++pFrontIter; - ++nNumItemsToDelete; - } - } - - assert(nSize == m_elementFrameInfo.size()); - m_elementFrameInfo.resize(nSize - nNumItemsToDelete); - } - else if (bFreeAll) // Free all - { - SFrameInfo* pFrontIter = &m_elementFrameInfo[0]; - SFrameInfo* pBackIter = &m_elementFrameInfo[nSize - 1]; - ++pBackIter; // Point to element after last element in array - - // Free all - while (pFrontIter != pBackIter) - { - // Element timed out - if (pFrontIter->bIsValid) - { - FreeRNTmpData(pFrontIter->ppRNTmpData); - } - - ++pFrontIter; - } - m_elementFrameInfo.resize(0); - } -} - -void C3DEngine::FreeRNTmpDataPool() -{ - // move all into m_LTPRootFree - UpdateRNTmpDataPool(true); - - AUTO_LOCK(m_checkCreateRNTmpData); - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - CryFatalError("CRNTmpData should only be allocated and free'd on main thread."); - } - - // delete all elements of m_LTPRootFree - CRNTmpData* pNext = NULL; - for (CRNTmpData* pElem = m_LTPRootFree.pNext; pElem != &m_LTPRootFree; pElem = pNext) - { - pNext = pElem->pNext; - pElem->Unlink(); - delete pElem; - } -} - -void C3DEngine::CopyObjectsByType(EERType objType, const AABB* pBox, PodArray* plstObjects, ObjectTreeQueryFilterCallback filterCallback) -{ - GetObjectsByTypeGlobal(*plstObjects, objType, pBox, filterCallback); - - if (GetVisAreaManager()) - { - GetVisAreaManager()->GetObjectsByType(*plstObjects, objType, pBox, filterCallback); - } -} - -void C3DEngine::CopyObjects(const AABB* pBox, PodArray* plstObjects) -{ - if (IsObjectTreeReady()) - { - m_pObjectsTree->GetObjects(*plstObjects, pBox); - } - - if (GetVisAreaManager()) - { - GetVisAreaManager()->GetObjects(*plstObjects, pBox); - } -} - -uint32 C3DEngine::GetObjectsByType(EERType objType, IRenderNode** pObjects) -{ - PodArray lstObjects; - CopyObjectsByType(objType, NULL, &lstObjects); - if (pObjects && !lstObjects.IsEmpty()) - { - memcpy(pObjects, &lstObjects[0], lstObjects.GetDataSize()); - } - return lstObjects.Count(); -} - -uint32 C3DEngine::GetObjectsByTypeInBox(EERType objType, const AABB& bbox, IRenderNode** pObjects, ObjectTreeQueryFilterCallback filterCallback) -{ - PodArray lstObjects; - CopyObjectsByType(objType, &bbox, &lstObjects, filterCallback); - if (pObjects && !lstObjects.IsEmpty()) - { - memcpy(pObjects, &lstObjects[0], lstObjects.GetDataSize()); - } - return lstObjects.Count(); -} - -void C3DEngine::GetObjectsByTypeInBox(EERType objType, const AABB& bbox, PodArray* pLstObjects, ObjectTreeQueryFilterCallback filterCallback) -{ - CopyObjectsByType(objType, &bbox, pLstObjects, filterCallback); -} - -uint32 C3DEngine::GetObjectsInBox(const AABB& bbox, IRenderNode** pObjects) -{ - PodArray lstObjects; - CopyObjects(&bbox, &lstObjects); - if (pObjects && !lstObjects.IsEmpty()) - { - memcpy(pObjects, &lstObjects[0], lstObjects.GetDataSize()); - } - return lstObjects.Count(); -} - -uint32 C3DEngine::GetObjectsByFlags(uint dwFlags, IRenderNode** pObjects /* =0 */) -{ - PodArray lstObjects; - - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->GetObjectsByFlags(dwFlags, lstObjects); - } - - if (GetVisAreaManager()) - { - GetVisAreaManager()->GetObjectsByFlags(dwFlags, lstObjects); - } - - if (pObjects && !lstObjects.IsEmpty()) - { - memcpy(pObjects, &lstObjects[0], lstObjects.GetDataSize()); - } - return lstObjects.Count(); -} - -void C3DEngine::OnObjectModified([[maybe_unused]] IRenderNode* pRenderNode, uint dwFlags) -{ - if ((dwFlags & (ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS)) != 0) - { - SetRecomputeCachedShadows(ShadowMapFrustum::ShadowCacheData::eFullUpdate); - } -} - -int SImageInfo::GetMemoryUsage() -{ - int nSize = 0; - if (detailInfo.pImgMips[0]) - { - nSize += (int)((float)(detailInfo.nDim * detailInfo.nDim * sizeof(ColorB)) * 1.3f); - } - if (baseInfo.pImgMips[0]) - { - nSize += (int)((float)(baseInfo.nDim * baseInfo.nDim * sizeof(ColorB)) * 1.3f); - } - return nSize; -} - -byte** C3DEngine::AllocateMips(byte* pImage, int nDim, byte** pImageMips) -{ - memset(pImageMips, 0, SImageSubInfo::nMipsNum * sizeof(pImageMips[0])); - - pImageMips[0] = new byte[nDim * nDim * sizeof(ColorB)]; - memcpy(pImageMips[0], pImage, nDim * nDim * sizeof(ColorB)); - - ColorB* pMipMain = (ColorB*)pImageMips[0]; - - for (int nMip = 1; (nDim >> nMip) && nMip < SImageSubInfo::nMipsNum; nMip++) - { - int nDimMip = nDim >> nMip; - - int nSubSize = 1 << nMip; - - pImageMips[nMip] = new byte[nDimMip * nDimMip * sizeof(ColorB)]; - - ColorB* pMipThis = (ColorB*)pImageMips[nMip]; - - for (int x = 0; x < nDimMip; x++) - { - for (int y = 0; y < nDimMip; y++) - { - ColorF colSumm(0, 0, 0, 0); - float fCount = 0; - for (int _x = x * nSubSize - nSubSize / 2; _x < x * nSubSize + nSubSize + nSubSize / 2; _x++) - { - for (int _y = y * nSubSize - nSubSize / 2; _y < y * nSubSize + nSubSize + nSubSize / 2; _y++) - { - int nMask = nDim - 1; - int id = (_x & nMask) * nDim + (_y & nMask); - colSumm.r += 1.f / 255.f * pMipMain[id].r; - colSumm.g += 1.f / 255.f * pMipMain[id].g; - colSumm.b += 1.f / 255.f * pMipMain[id].b; - colSumm.a += 1.f / 255.f * pMipMain[id].a; - fCount++; - } - } - - colSumm /= fCount; - - colSumm.Clamp(0, 1); - - pMipThis[x * nDimMip + y] = colSumm; - } - } - } - - return pImageMips; -} - -void C3DEngine::RegisterForStreaming(IStreamable* pObj) -{ - if (GetObjManager()) - { - GetObjManager()->RegisterForStreaming(pObj); - } -} - -void C3DEngine::UnregisterForStreaming(IStreamable* pObj) -{ - if (GetObjManager()) - { - GetObjManager()->UnregisterForStreaming(pObj); - } -} - -SImageSubInfo* C3DEngine::GetImageInfo(const char* pName) -{ - if (m_imageInfos.find(string(pName)) != m_imageInfos.end()) - { - return m_imageInfos[string(pName)]; - } - - return NULL; -} - -SImageSubInfo* C3DEngine::RegisterImageInfo(byte** pMips, int nDim, const char* pName) -{ - if (m_imageInfos.find(string(pName)) != m_imageInfos.end()) - { - return m_imageInfos[string(pName)]; - } - - assert(pMips && pMips[0]); - - SImageSubInfo* pImgSubInfo = new SImageSubInfo; - - pImgSubInfo->nDim = nDim; - - int nMipDim = pImgSubInfo->nDim; - - for (int m = 0; m < SImageSubInfo::nMipsNum && nMipDim; m++) - { - pImgSubInfo->pImgMips[m] = new byte[nMipDim * nMipDim * 4]; - - memcpy(pImgSubInfo->pImgMips[m], pMips[m], nMipDim * nMipDim * 4); - - nMipDim /= 2; - } - - const string strFileName = pName; - - pImgSubInfo->nReady = 1; - - m_imageInfos[strFileName] = pImgSubInfo; - - return pImgSubInfo; -} - -void C3DEngine::SyncProcessStreamingUpdate() -{ - if (m_pObjManager) - { - m_pObjManager->ProcessObjectsStreaming_Finish(); - } -} - -void C3DEngine::SetScreenshotCallback(IScreenshotCallback* pCallback) -{ - m_pScreenshotCallback = pCallback; -} - -void C3DEngine::ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, bool bObjects, bool bStaticLights, const char* pLayerName, IGeneralMemoryHeap* pHeap, bool bCheckLayerActivation /*=true*/) -{ - if (bCheckLayerActivation && !IsAreaActivationInUse()) - { - return; - } - - if (bActivate) - { - m_bLayersActivated = true; - } - - if (bActivate && m_nFramesSinceLevelStart <= 1) - { - m_vPrevMainFrameCamPos.Set(-1000000.f, -1000000.f, -1000000.f); - } - - FUNCTION_PROFILER_3DENGINE; - - PrintMessage("%s object layer %s (Id = %d) (LevelFrameId = %d)", bActivate ? "Activating" : "Deactivating", pLayerName, nLayerId, m_nFramesSinceLevelStart); - INDENT_LOG_DURING_SCOPE(); - - if (bObjects) - { - if (IsObjectTreeReady()) - { - m_pObjectsTree->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap); - } - - if (m_pVisAreaManager) - { - m_pVisAreaManager->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap); - } - } - - if (bStaticLights) - { - for (size_t i = 0; i < m_lstStaticLights.size(); ++i) - { - ILightSource* pLight = m_lstStaticLights[i]; - if (pLight->GetLayerId() == nLayerId) - { - pLight->SetRndFlags(ERF_HIDDEN, !bActivate); - } - } - } -} - - -void C3DEngine::GetLayerMemoryUsage(uint16 nLayerId, ICrySizer* pSizer, int* pNumBrushes, int* pNumDecals) const -{ - if (pNumBrushes) - { - *pNumBrushes = 0; - } - if (pNumDecals) - { - *pNumDecals = 0; - } - - if (m_pObjectsTree != nullptr) - { - m_pObjectsTree->GetLayerMemoryUsage(nLayerId, pSizer, pNumBrushes, pNumDecals); - } -} - - -void C3DEngine::SkipLayerLoading(uint16 nLayerId, bool bClearList) -{ - if (bClearList) - { - m_skipedLayers.clear(); - } - m_skipedLayers.insert(nLayerId); -} - - -bool C3DEngine::IsLayerSkipped(uint16 nLayerId) -{ - return m_skipedLayers.find(nLayerId) != m_skipedLayers.end() ? true : false; -} - -void C3DEngine::PrecacheRenderNode(IRenderNode* pObj, float fEntDistanceReal) -{ - FUNCTION_PROFILER_3DENGINE; - - // PrintMessage("==== PrecacheRenderNodePrecacheRenderNode: %s ====", pObj->GetName()); - - if (m_pObjManager) - { - int dwOldRndFlags = pObj->m_dwRndFlags; - pObj->m_dwRndFlags &= ~ERF_HIDDEN; - - SRenderingPassInfo passInfo = SRenderingPassInfo::CreateGeneralPassRenderingInfo(gEnv->pSystem->GetViewCamera()); - - m_pObjManager->UpdateRenderNodeStreamingPriority(pObj, fEntDistanceReal, 1.0f, fEntDistanceReal < GetFloatCVar(e_StreamCgfFastUpdateMaxDistance), passInfo, true); - pObj->m_dwRndFlags = dwOldRndFlags; - } -} - - -void C3DEngine::CleanUpOldDecals() -{ - FUNCTION_PROFILER_3DENGINE; - static uint32 nLastIndex = 0; - const uint32 nDECALS_PER_FRAME = 50; - - if (uint32 nNumDecalRenderNodes = m_decalRenderNodes.size()) - { - for (uint32 i = 0, end = __min(nDECALS_PER_FRAME, nNumDecalRenderNodes); i < end; ++i, ++nLastIndex) - { - // wrap around at the end to restart at the beginning - if (nLastIndex >= nNumDecalRenderNodes) - { - nLastIndex = 0; - } - - m_decalRenderNodes[nLastIndex]->CleanUpOldDecals(); - } - } -} - -void C3DEngine::UpdateRenderTypeEnableLookup() -{ - SetRenderNodeTypeEnabled(eERType_RenderComponent, (GetCVars()->e_Entities != 0)); - SetRenderNodeTypeEnabled(eERType_StaticMeshRenderComponent, (GetCVars()->e_Entities != 0)); - SetRenderNodeTypeEnabled(eERType_DynamicMeshRenderComponent, (GetCVars()->e_Entities != 0)); - SetRenderNodeTypeEnabled(eERType_SkinnedMeshRenderComponent, (GetCVars()->e_Entities != 0)); -} - -void C3DEngine::SetRenderNodeMaterialAtPosition(EERType eNodeType, const Vec3& vPos, _smart_ptr pMat) -{ - PodArray lstObjects; - - AABB aabbPos(vPos - Vec3(.1f, .1f, .1f), vPos + Vec3(.1f, .1f, .1f)); - - GetObjectsByTypeGlobal(lstObjects, eNodeType, &aabbPos); - - if (GetVisAreaManager()) - { - GetVisAreaManager()->GetObjectsByType(lstObjects, eNodeType, &aabbPos); - } - - for (int i = 0; i < lstObjects.Count(); i++) - { - PrintMessage("Game changed render node material: %s EERType:%d pos: (%d,%d,%d)", - pMat ? pMat->GetName() : "NULL", - (int)eNodeType, - (int)vPos.x, (int)vPos.y, (int)vPos.z); - - lstObjects[i]->SetMaterial(pMat); - } -} - -void C3DEngine::OverrideCameraPrecachePoint(const Vec3& vPos) -{ - if (m_pObjManager) - { - m_pObjManager->GetStreamPreCacheCameras()[0].vPosition = vPos; - m_pObjManager->SetCameraPrecacheOverridden(true); - } -} - -int C3DEngine::AddPrecachePoint(const Vec3& vPos, const Vec3& vDir, float fTimeOut, float fImportanceFactor) -{ - if (m_pObjManager) - { - if (m_pObjManager->GetStreamPreCachePointDefs().size() >= CObjManager::MaxPrecachePoints) - { - size_t nOldestIdx = 0; - int nOldestId = INT_MAX; - for (size_t i = 1, c = m_pObjManager->GetStreamPreCachePointDefs().size(); i < c; ++i) - { - if (m_pObjManager->GetStreamPreCachePointDefs()[i].nId < nOldestId) - { - nOldestIdx = i; - nOldestId = m_pObjManager->GetStreamPreCachePointDefs()[i].nId; - } - } - - assert (nOldestIdx > 0); - - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Precache points full - evicting oldest (%f, %f, %f)", - m_pObjManager->GetStreamPreCacheCameras()[nOldestIdx].vPosition.x, - m_pObjManager->GetStreamPreCacheCameras()[nOldestIdx].vPosition.y, - m_pObjManager->GetStreamPreCacheCameras()[nOldestIdx].vPosition.z); - - m_pObjManager->GetStreamPreCachePointDefs().DeleteFastUnsorted((int)nOldestIdx); - m_pObjManager->GetStreamPreCacheCameras().DeleteFastUnsorted((int)nOldestIdx); - } - - SObjManPrecachePoint pp; - pp.nId = m_pObjManager->IncrementNextPrecachePointId(); - pp.expireTime = gEnv->pTimer->GetAsyncTime() + CTimeValue(fTimeOut); - SObjManPrecacheCamera pc; - pc.vPosition = vPos; - pc.bbox = AABB(vPos, GetCVars()->e_StreamPredictionBoxRadius); - pc.vDirection = vDir; - pc.fImportanceFactor = fImportanceFactor; - m_pObjManager->GetStreamPreCachePointDefs().Add(pp); - m_pObjManager->GetStreamPreCacheCameras().Add(pc); - - return pp.nId; - } - - return -1; -} - -void C3DEngine::ClearPrecachePoint(int id) -{ - if (m_pObjManager) - { - for (size_t i = 1, c = m_pObjManager->GetStreamPreCachePointDefs().size(); i < c; ++i) - { - if (m_pObjManager->GetStreamPreCachePointDefs()[i].nId == id) - { - m_pObjManager->GetStreamPreCachePointDefs().DeleteFastUnsorted((int)i); - m_pObjManager->GetStreamPreCacheCameras().DeleteFastUnsorted((int)i); - break; - } - } - } -} - -void C3DEngine::ClearAllPrecachePoints() -{ - if (m_pObjManager) - { - m_pObjManager->GetStreamPreCachePointDefs().resize(1); - m_pObjManager->GetStreamPreCacheCameras().resize(1); - } -} - -void C3DEngine::GetPrecacheRoundIds(int pRoundIds[MAX_STREAM_PREDICTION_ZONES]) -{ - if (m_pObjManager) - { - pRoundIds[0] = m_pObjManager->GetUpdateStreamingPrioriryRoundIdFast(); - pRoundIds[1] = m_pObjManager->GetUpdateStreamingPrioriryRoundId(); - } -} - -SBending* C3DEngine::GetBendingEntry(SBending* pSrc, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - assert(pSrc); - SBending* pStorage = m_bendingPool[m_bendingPoolIdx].push_back_new(); - *pStorage = *pSrc; - return pStorage; -} - -/////////////////////////////////////////////////////////////////////////////// -CCamera* C3DEngine::GetRenderingPassCamera(const CCamera& rCamera) -{ - threadID nThreadID = 0; - gEnv->pRenderer->EF_Query(EFQ_RenderThreadList, nThreadID); - CCamera* pCamera = m_RenderingPassCameras[nThreadID].push_back_new(); - *pCamera = rCamera; - return pCamera; -} - -void C3DEngine::GetCollisionClass(SCollisionClass& collclass, int tableIndex) -{ - if ((unsigned)tableIndex < m_collisionClasses.size()) - { - collclass = m_collisionClasses[tableIndex]; - } - else - { - collclass = SCollisionClass(0, 0); - } -} - -class C3DEngine::PhysicsAreaUpdatesHandler - : private Physics::WindNotificationsBus::Handler -{ -public: - explicit PhysicsAreaUpdatesHandler(C3DEngine::PhysicsAreaUpdates& physicsAreaUpdates) - : m_physicsAreaUpdates(physicsAreaUpdates) - { - Physics::WindNotificationsBus::Handler::BusConnect(); - } - - ~PhysicsAreaUpdatesHandler() - { - Physics::WindNotificationsBus::Handler::BusDisconnect(); - } - -private: - // Physics::WindNotificationsBus::Handler - void OnGlobalWindChanged() override - { - // Using same 'global wind' area size value CryPhysics code had - const AZ::Vector3 globalWindHalfBound(1e7); - AZ::Aabb globalWindAabb = AZ::Aabb::CreateFromMinMax(-globalWindHalfBound, globalWindHalfBound); - - OnWindChanged(globalWindAabb); - } - - void OnWindChanged(const AZ::Aabb& aabb) override - { - SAreaChangeRecord record; - record.boxAffected = AZAabbToLyAABB(aabb); - record.uPhysicsMask = Area_Air; - - m_physicsAreaUpdates.SetAreaDirty(record); - } - - C3DEngine::PhysicsAreaUpdates& m_physicsAreaUpdates; -}; - -void C3DEngine::PhysicsAreaUpdates::SetAreaDirty(const SAreaChangeRecord& rec) -{ - // Merge with existing bb if close enough and same medium - AUTO_LOCK(m_Mutex); - static const float fMERGE_THRESHOLD = 2.f; - float fNewVolume = rec.boxAffected.GetVolume(); - for (uint i = 0; i < m_DirtyAreas.size(); i++) - { - if (m_DirtyAreas[i].uPhysicsMask == rec.uPhysicsMask) - { - AABB bbUnion = rec.boxAffected; - bbUnion.Add(m_DirtyAreas[i].boxAffected); - if (bbUnion.GetVolume() <= (fNewVolume + m_DirtyAreas[i].boxAffected.GetVolume()) * fMERGE_THRESHOLD) - { - m_DirtyAreas[i].boxAffected = bbUnion; - return; - } - } - } - m_DirtyAreas.push_back(rec); -} - -void C3DEngine::PhysicsAreaUpdates::Update() -{ - // - // (bethelz) This whole class is only used for CParticleEffect right now. - // - - FUNCTION_PROFILER_3DENGINE; - AUTO_LOCK(m_Mutex); - if (m_DirtyAreas.empty()) - { - return; - } - - // Check area against registered proxies - int nSizeAreasChanged = (int)m_DirtyAreas.size(); - int nSizeProxies = m_Proxies.size(); - - // Access elements via [i] as the thread safe list does not always safe its element in a continues array - for (int i = 0; i < nSizeProxies; ++i) - { - const SPhysAreaNodeProxy& proxy = m_Proxies[i]; - - IF (!proxy.bIsValid, 0) - { - continue; - } - - for (int j = 0; j < nSizeAreasChanged; ++j) - { - const SAreaChangeRecord& rec = m_DirtyAreas[j]; - if ((proxy.uPhysicsMask & rec.uPhysicsMask) && Overlap::AABB_AABB(proxy.bbox, rec.boxAffected)) - { - if (rec.uPhysicsMask & Area_Air) - { - if (proxy.pRenderNode->m_pRNTmpData) - { - proxy.pRenderNode->m_pRNTmpData->userData.bWindCurrent = 0; - } - } - - proxy.pRenderNode->OnPhysAreaChange(); - break; - } - } - } - - m_DirtyAreas.resize(0); -} - -void C3DEngine::PhysicsAreaUpdates::Reset() -{ - stl::free_container(m_DirtyAreas); -} - -uint32 C3DEngine::PhysicsAreaUpdates::CreateProxy(const IRenderNode* pRenderNode, uint16 uPhysicsMask) -{ - size_t nIndex = ~0; - SPhysAreaNodeProxy* proxy = m_Proxies.push_back_new(nIndex); - - proxy->pRenderNode = (IRenderNode*)pRenderNode; - proxy->uPhysicsMask = uPhysicsMask; - proxy->bIsValid = true; - proxy->bbox = pRenderNode->GetBBox(); - return nIndex; -} - -void C3DEngine::PhysicsAreaUpdates::UpdateProxy(const IRenderNode* pRenderNode, uint32 nProxyId) -{ - m_Proxies[nProxyId].bbox = pRenderNode->GetBBox(); -} - -void C3DEngine::PhysicsAreaUpdates::ResetProxy(uint32 proxyId) -{ - m_Proxies[proxyId].Reset(); -} - -void C3DEngine::PhysicsAreaUpdates::GarbageCollect() -{ - // Ensure list is continues in memory - m_Proxies.CoalesceMemory(); - - const uint32 nSize = m_Proxies.size(); - if (nSize == 0) - { - return; - } - - SPhysAreaNodeProxy* pFrontIter = &m_Proxies[0]; - SPhysAreaNodeProxy* pBackIter = &m_Proxies[nSize - 1]; - const SPhysAreaNodeProxy* pHead = pFrontIter; - uint32 nNumItemsToDelete = 0; - - // Move invalid nodes to the back of the array - do - { - while (pFrontIter->bIsValid && pFrontIter < pBackIter) - { - ++pFrontIter; - } - while (!pBackIter->bIsValid && pFrontIter < pBackIter) - { - --pBackIter; - ++nNumItemsToDelete; - } - - if (pFrontIter < pBackIter) - { - // Replace invalid front element with back element - // Note: No need to swap because we cut the data from the array at the end anyway - memcpy(pFrontIter, pBackIter, sizeof(SPhysAreaNodeProxy)); - AZ_Assert(pFrontIter->pRenderNode && pFrontIter->pRenderNode->m_pRNTmpData, "The front iterator should have a valid m_pRNTmpData after the data from the valid back iterator has been copied to it."); - if (pFrontIter->pRenderNode && pFrontIter->pRenderNode->m_pRNTmpData) - { - pFrontIter->pRenderNode->m_pRNTmpData->nPhysAreaChangedProxyId = (uint32)(pFrontIter - pHead); - } - - pBackIter->bIsValid = false; - - --pBackIter; - ++pFrontIter; - ++nNumItemsToDelete; - } - } while (pFrontIter < pBackIter); - - // Cut off invalid elements - m_Proxies.resize(nSize - nNumItemsToDelete); -} - -void C3DEngine::UpdateShaderItems() -{ - if (GetMatMan()) - { - GetMatMan()->UpdateShaderItems(); - } -} - -void C3DEngine::OnCameraTeleport() -{ - MarkRNTmpDataPoolForReset(); -} - -IObjManager* C3DEngine::GetObjectManager() -{ - return m_pObjManager; -} - -const IObjManager* C3DEngine::GetObjectManager() const -{ - return m_pObjManager; -} - -bool C3DEngine::RemoveObjectsInArea(Vec3 vExploPos, float fExploRadius) -{ - bool bEverythingDeleted = true; - - Vec3 vRadius(fExploRadius, fExploRadius, fExploRadius); - - PodArray lstEntities; - const AABB cExplosionBox(vExploPos - vRadius, vExploPos + vRadius); - MoveObjectsIntoListGlobal(&lstEntities, &cExplosionBox, false, true, true, true); - - // remove small objects around - { - for (int i = 0; i < lstEntities.Count(); i++) - { - IRenderNode* pRenderNode = lstEntities[i].pNode; - AABB entBox = pRenderNode->GetBBox(); - float fEntRadius = entBox.GetRadius(); - Vec3 vEntCenter = pRenderNode->GetBBox().GetCenter(); - float fDist = vExploPos.GetDistance(vEntCenter); - if (fDist < fExploRadius + fEntRadius && - Overlap::Sphere_AABB(Sphere(vExploPos, fExploRadius), entBox)) - { - if (fDist >= fExploRadius) - { // - Matrix34A objMat; - CStatObj* pStatObj = (CStatObj*)pRenderNode->GetEntityStatObj(0, 0, &objMat); - if (!pStatObj) - { - continue; - } - objMat.Invert(); - //assert(0); - Vec3 vOSExploPos = objMat.TransformPoint(vExploPos); - - Vec3 vScaleTest(0, 0, 1.f); - vScaleTest = objMat.TransformVector(vScaleTest); - float fObjScaleInv = vScaleTest.len(); - - if (!pStatObj->IsSphereOverlap(Sphere(vOSExploPos, fExploRadius * fObjScaleInv))) - { - continue; - } - } - } - } - } - - return bEverythingDeleted; -} - -#ifndef _RELEASE - -////////////////////////////////////////////////////////////////////////// -// onscreen infodebug code for e_debugDraw >= 100 - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::AddObjToDebugDrawList(SObjectInfoToAddToDebugDrawList& objInfo) -{ - m_DebugDrawListMgr.AddObject(objInfo); -} - - -bool CDebugDrawListMgr::m_dumpLogRequested = false; -bool CDebugDrawListMgr::m_freezeRequested = false; -bool CDebugDrawListMgr::m_unfreezeRequested = false; -uint32 CDebugDrawListMgr::m_filter = I3DEngine::DLOT_ALL; - - -////////////////////////////////////////////////////////////////////////// -CDebugDrawListMgr::CDebugDrawListMgr() -{ - m_isFrozen = false; - ClearFrameData(); - ClearConsoleCommandRequestVars(); - m_assets.reserve(32); // just a reasonable value - m_drawBoxes.reserve(256); // just a reasonable value -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::ClearFrameData() -{ - m_counter = 0; - m_assetCounter = 0; - m_assets.clear(); - m_drawBoxes.clear(); - m_indexLeastValueAsset = 0; - CheckFilterCVar(); -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::ClearConsoleCommandRequestVars() -{ - m_dumpLogRequested = false; - m_freezeRequested = false; - m_unfreezeRequested = false; -} - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::AddObject(I3DEngine::SObjectInfoToAddToDebugDrawList& newObjInfo) -{ - if (m_isFrozen) - { - return; - } - - m_lock.Lock(); - - m_counter++; - - if (!ShouldFilterOutObject(newObjInfo)) - { - TAssetInfo newAsset(newObjInfo); - TObjectDrawBoxInfo newDrawBox(newObjInfo); - - TAssetInfo* pAssetDuplicated = FindDuplicate(newAsset); - if (pAssetDuplicated) - { - pAssetDuplicated->numInstances++; - newDrawBox.assetID = pAssetDuplicated->ID; - m_drawBoxes.push_back(newDrawBox); - pAssetDuplicated->drawCalls = max(pAssetDuplicated->drawCalls, newAsset.drawCalls); - } - else - { - newAsset.ID = m_assetCounter; - newDrawBox.assetID = newAsset.ID; - bool used = false; - - // list not full, so we add - if (m_assets.size() < uint(Cry3DEngineBase::GetCVars()->e_DebugDrawListSize)) - { - used = true; - m_assets.push_back(newAsset); - } - else // if is full, only use it if value is greater than the current minimum, and then it substitutes the lowest slot - { - const TAssetInfo& leastValueAsset = m_assets[ m_indexLeastValueAsset ]; - if (leastValueAsset < newAsset) - { - used = true; - m_assets[ m_indexLeastValueAsset ] = newAsset; - } - } - if (used) - { - m_assetCounter++; - m_drawBoxes.push_back(newDrawBox); - FindNewLeastValueAsset(); - } - } - } - - m_lock.Unlock(); -} - - -////////////////////////////////////////////////////////////////////////// -CDebugDrawListMgr::TAssetInfo* CDebugDrawListMgr::FindDuplicate(const TAssetInfo& asset) -{ - std::vector::iterator iter = m_assets.begin(); - std::vector::const_iterator endArray = m_assets.end(); - - while (iter != endArray) - { - TAssetInfo& currAsset = *iter; - if (currAsset.fileName == asset.fileName) - { - return &currAsset; - } - ++iter; - } - return NULL; -} - - - -////////////////////////////////////////////////////////////////////////// -bool CDebugDrawListMgr::ShouldFilterOutObject(const I3DEngine::SObjectInfoToAddToDebugDrawList& object) -{ - if (m_filter == I3DEngine::DLOT_ALL) - { - return false; - } - - return (m_filter & object.type) == 0; -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::FindNewLeastValueAsset() -{ - uint32 size = m_assets.size(); - for (uint32 i = 0; i < size; ++i) - { - const TAssetInfo& currAsset = m_assets[ i ]; - const TAssetInfo& leastValueAsset = m_assets[ m_indexLeastValueAsset ]; - - if (currAsset < leastValueAsset) - { - m_indexLeastValueAsset = i; - } - } -} - - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::Update() -{ - m_lock.Lock(); - if (!m_isFrozen) - { - std::sort(m_assets.begin(), m_assets.end(), CDebugDrawListMgr::SortComparison); - } - gEnv->pRenderer->CollectDrawCallsInfoPerNode(true); - // it displays values from the previous frame. This mean that if it is disabled, and then enabled again later on, it will display bogus values for 1 frame...but i dont care (yet) - float X = 10.f; - float Y = 100.f; - if (m_isFrozen) - { - PrintText(X, Y, Col_Red, "FROZEN DEBUGINFO"); - } - Y += 20.f; - PrintText(X, Y, Col_White, "total assets: %d Ordered by: Showing:", m_counter); - PrintText(X + 240, Y, Col_Yellow, GetStrCurrMode()); - TMyStandardString filterStr; - GetStrCurrFilter(filterStr); - PrintText(X + 420, Y, Col_Yellow, filterStr.c_str()); - Y += 20.f; - float XName = 270; - - const char* pHeaderStr = ""; - switch (Cry3DEngineBase::GetCVars()->e_DebugDraw) - { - case LM_TRI_COUNT: - pHeaderStr = " tris " " meshMem " "rep " " type "; - break; - case LM_VERT_COUNT: - pHeaderStr = " verts " " meshMem " "rep " " type "; - break; - case LM_DRAWCALLS: - pHeaderStr = "draw Calls " " tris " "rep " " type "; - break; - case LM_TEXTMEM: - pHeaderStr = " texMem " " meshMem " "rep " " type "; - break; - case LM_MESHMEM: - pHeaderStr = " meshMem " " texMem " "rep " " type "; - break; - } - - - PrintText(X, Y, Col_White, pHeaderStr); - const int standardNameSize = 48; - PrintText(XName, Y, Col_White, "Entity (class)"); - PrintText(XName + (standardNameSize + 2) * 7, Y, Col_White, "File name"); - - Y += 20.f; - for (uint32 i = 0; i < m_assets.size(); ++i) - { - ColorF colorLine = Col_Cyan; - if (Cry3DEngineBase::GetCVars()->e_DebugDrawListBBoxIndex - 1 == i) - { - colorLine = Col_Blue; - } - const TAssetInfo& currAsset = m_assets[ i ]; - TMyStandardString texMemoryStr; - TMyStandardString meshMemoryStr; - MemToString(currAsset.texMemory, texMemoryStr); - MemToString(currAsset.meshMemory, meshMemoryStr); - - switch (Cry3DEngineBase::GetCVars()->e_DebugDraw) - { - case LM_TRI_COUNT: - PrintText(X, Y + 20.f * i, colorLine, "%7d " "%s " "%3d " "%s", - currAsset.numTris, meshMemoryStr.c_str(), currAsset.numInstances, GetAssetTypeName(currAsset.type)); - break; - case LM_VERT_COUNT: - PrintText(X, Y + 20.f * i, colorLine, "%7d " "%s " "%3d " "%s", - currAsset.numVerts, meshMemoryStr.c_str(), currAsset.numInstances, GetAssetTypeName(currAsset.type)); - break; - case LM_DRAWCALLS: - { - PrintText(X, Y + 20.f * i, colorLine, " %5d " "%7d " "%3d " "%s", - currAsset.drawCalls, currAsset.numTris, currAsset.numInstances, GetAssetTypeName(currAsset.type)); - } - break; - case LM_TEXTMEM: - PrintText(X, Y + 20.f * i, colorLine, "%s " "%s " "%3d " "%s", - texMemoryStr.c_str(), meshMemoryStr.c_str(), currAsset.numInstances, GetAssetTypeName(currAsset.type)); - break; - case LM_MESHMEM: - PrintText(X, Y + 20.f * i, colorLine, "%s " "%s " "%3d " "%s", - meshMemoryStr.c_str(), texMemoryStr.c_str(), currAsset.numInstances, GetAssetTypeName(currAsset.type)); - break; - } - - int filenameSep = 7 * (max(standardNameSize, int(currAsset.name.length())) + 2); - float XFileName = XName + filenameSep; - - PrintText(XName, Y + 20.f * i, colorLine, currAsset.name.c_str()); - PrintText(XFileName, Y + 20.f * i, colorLine, currAsset.fileName.c_str()); - } - - if (Cry3DEngineBase::GetCVars()->e_DebugDrawListBBoxIndex > 0 && uint(Cry3DEngineBase::GetCVars()->e_DebugDrawListBBoxIndex - 1) < m_assets.size()) - { - const TAssetInfo& assetInfo = m_assets[ Cry3DEngineBase::GetCVars()->e_DebugDrawListBBoxIndex - 1 ]; - uint32 numBoxesDrawn = 0; - for (uint32 i = 0; i < m_drawBoxes.size(); ++i) - { - const TObjectDrawBoxInfo& drawBox = m_drawBoxes[ i ]; - if (drawBox.assetID == assetInfo.ID) - { - gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(drawBox.bbox, drawBox.mat, true, ColorB(0, 0, 255, 100), eBBD_Faceted); - numBoxesDrawn++; - if (numBoxesDrawn >= assetInfo.numInstances) - { - break; - } - } - } - } - - if (m_freezeRequested) - { - m_isFrozen = true; - } - if (m_unfreezeRequested) - { - m_isFrozen = false; - } - if (m_dumpLogRequested) - { - DumpLog(); - } - - ClearConsoleCommandRequestVars(); - - if (!m_isFrozen) - { - ClearFrameData(); - m_assets.reserve(Cry3DEngineBase::GetCVars()->e_DebugDrawListSize); - } - m_lock.Unlock(); -} - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::PrintText(float x, float y, const ColorF& fColor, const char* label_text, ...) -{ - va_list args; - va_start(args, label_text); - SDrawTextInfo ti; - ti.xscale = ti.yscale = 1.2f; - ti.flags = eDrawText_2D | eDrawText_FixedSize | eDrawText_Monospace; - { - ti.color[0] = fColor[0]; - ti.color[1] = fColor[1]; - ti.color[2] = fColor[2]; - ti.color[3] = fColor[3]; - } - gEnv->pRenderer->DrawTextQueued(Vec3(x, y, 0.5f), ti, label_text, args); - va_end(args); -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::MemToString(uint32 memVal, TMyStandardString& outStr) -{ - if (memVal < 1024 * 1024) - { - outStr.Format("%5.1f kb", memVal / (1024.f)); - } - else - { - outStr.Format("%5.1f MB", memVal / (1024.f * 1024.f)); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CDebugDrawListMgr::TAssetInfo::operator<(const TAssetInfo& other) const -{ - switch (Cry3DEngineBase::GetCVars()->e_DebugDraw) - { - case LM_TRI_COUNT: - return (numTris < other.numTris); - - case LM_VERT_COUNT: - return (numVerts < other.numVerts); - - case LM_DRAWCALLS: - return (drawCalls < other.drawCalls); - - case LM_TEXTMEM: - return (texMemory < other.texMemory); - - case LM_MESHMEM: - return (meshMemory < other.meshMemory); - - default: - assert(false); - return false; - } -} - - -////////////////////////////////////////////////////////////////////////// -CDebugDrawListMgr::TAssetInfo::TAssetInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo) -{ - type = objInfo.type; - if (!objInfo.pClassName) - { - // custom functions to avoid any heap allocation - MyString_Assign(name, objInfo.pName); - MyStandardString_Concatenate(name, "("); - MyStandardString_Concatenate(name, objInfo.pClassName); - MyStandardString_Concatenate(name, ")"); - } - - MyFileNameString_Assign(fileName, objInfo.pFileName); - - numTris = objInfo.numTris; - numVerts = objInfo.numVerts; - texMemory = objInfo.texMemory; - meshMemory = objInfo.meshMemory; - drawCalls = gEnv->pRenderer->GetDrawCallsPerNode(objInfo.pRenderNode); - numInstances = 1; - ID = UNDEFINED_ASSET_ID; -} - - -////////////////////////////////////////////////////////////////////////// -CDebugDrawListMgr::TObjectDrawBoxInfo::TObjectDrawBoxInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo) -{ - mat.SetIdentity(); - bbox.Reset(); - if (objInfo.pMat) - { - mat = *objInfo.pMat; - } - if (objInfo.pBox) - { - bbox = *objInfo.pBox; - } - assetID = UNDEFINED_ASSET_ID; -} - - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::MyStandardString_Concatenate(TMyStandardString& outStr, const char* pStr) -{ - if (pStr && outStr.length() < outStr.capacity()) - { - outStr._ConcatenateInPlace(pStr, min(strlen(pStr), outStr.capacity() - outStr.length())); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::MyFileNameString_Assign(TFilenameString& outStr, const char* pStr) -{ - char tempBuf[ outStr.MAX_SIZE + 1 ]; - - uint32 outInd = 0; - if (pStr) - { - while (*pStr != 0 && outInd < outStr.MAX_SIZE) - { - tempBuf[outInd] = *pStr; - outInd++; - if (*pStr == '%' && outInd < outStr.MAX_SIZE) - { - tempBuf[outInd] = '%'; - outInd++; - } - pStr++; - } - } - tempBuf[ outInd ] = 0; - outStr = tempBuf; -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::ConsoleCommand(IConsoleCmdArgs* args) -{ - if (args->GetArgCount() > 1 && args->GetArg(1)) - { - switch (toupper(args->GetArg(1)[0])) - { - case 'F': - m_freezeRequested = true; - break; - case 'C': - m_unfreezeRequested = true; - break; - case 'D': - m_dumpLogRequested = true; - break; - } - } -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::CheckFilterCVar() -{ - ICVar* pCVar = gEnv->pConsole->GetCVar("e_debugdrawlistfilter"); - - if (!pCVar) - { - return; - } - - const char* pVal = pCVar->GetString(); - - if (pVal && azstricmp(pVal, "all") == 0) - { - m_filter = I3DEngine::DLOT_ALL; - return; - } - - m_filter = 0; - while (pVal && pVal[0]) - { - switch (toupper(pVal[0])) - { - case 'C': - m_filter |= I3DEngine::DLOT_CHARACTER; - break; - case 'S': - m_filter |= I3DEngine::DLOT_STATOBJ; - break; - } - ++pVal; - } -} - - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::DumpLog() -{ - TMyStandardString filterStr; - GetStrCurrFilter(filterStr); - CryLog("--------------------------------------------------------------------------------"); - CryLog(" DebugDrawList infodebug"); - CryLog("--------------------------------------------------------------------------------"); - CryLog(" total objects: %d Ordered by: %s Showing: %s", m_counter, GetStrCurrMode(), filterStr.c_str()); - CryLog(PRINTF_EMPTY_FORMAT); - CryLog(" tris verts draw Calls texMem meshMem type"); - CryLog(" ------- -------- ---------- -------- -------- ----------"); - for (uint32 i = 0; i < m_assets.size(); ++i) - { - const TAssetInfo& currAsset = m_assets[ i ]; - TMyStandardString texMemoryStr; - TMyStandardString meshMemoryStr; - MemToString(currAsset.texMemory, texMemoryStr); - MemToString(currAsset.meshMemory, meshMemoryStr); - CryLog("%8d %8d %5d %s %s %s %s %s", currAsset.numTris, currAsset.numVerts, currAsset.drawCalls, - texMemoryStr.c_str(), meshMemoryStr.c_str(), GetAssetTypeName(currAsset.type), currAsset.name.c_str(), currAsset.fileName.c_str()); - } - CryLog("--------------------------------------------------------------------------------"); -} - - - -////////////////////////////////////////////////////////////////////////// -const char* CDebugDrawListMgr::GetStrCurrMode() -{ - const char* pModesNames[] = - { - "Tri count", - "Vert count", - "Draw calls", - "Texture memory", - "Mesh memory" - }; - - uint32 index = Cry3DEngineBase::GetCVars()->e_DebugDraw - LM_BASENUMBER; - uint32 numElems = sizeof(pModesNames) / sizeof *(pModesNames); - if (index < numElems) - { - return pModesNames[index]; - } - else - { - return ""; - } -} - -////////////////////////////////////////////////////////////////////////// -void CDebugDrawListMgr::GetStrCurrFilter(TMyStandardString& strOut) -{ - const char* pFilterNames[] = - { - "", - "Characters", - "StatObjs" - }; - - uint32 numElems = sizeof(pFilterNames) / sizeof *(pFilterNames); - for (uint32 i = 1, bitVal = 1; i < numElems; ++i) - { - if ((bitVal & m_filter) != 0) - { - if (strOut.size() > 0) - { - strOut += "+"; - } - strOut += pFilterNames[i]; - } - bitVal *= 2; - } - - if (strOut.size() == 0) - { - strOut = "ALL"; - } -} - - -////////////////////////////////////////////////////////////////////////// -const char* CDebugDrawListMgr::GetAssetTypeName(I3DEngine::EDebugDrawListAssetTypes type) -{ - const char* pNames[] = - { - "", - "Brush ", - "Vegetation", - "Character ", - "StatObj " - }; - - uint32 numElems = sizeof(pNames) / sizeof *(pNames); - for (uint32 i = 1, bitVal = 1; i < numElems; ++i) - { - if (bitVal == type) - { - return pNames[i]; - } - bitVal *= 2; - } - - return ""; -} - - - -#endif //RELEASE - -void C3DEngine::GetStatObjAndMatTables(DynArray* pStatObjTable, DynArray<_smart_ptr >* pMatTable, DynArray* pStatInstGroupTable, uint32 nObjTypeMask) -{ - SHotUpdateInfo exportInfo; - exportInfo.nObjTypeMask = nObjTypeMask; - - std::vector statObjTable; - std::vector<_smart_ptr > matTable; - std::vector statInstGroupTable; - - if (Get3DEngine() && Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->GenerateStatObjAndMatTables((pStatObjTable != NULL) ? &statObjTable : NULL, - (pMatTable != NULL) ? &matTable : NULL, - (pStatInstGroupTable != NULL) ? &statInstGroupTable : NULL, - &exportInfo); - } - - if (GetVisAreaManager()) - { - GetVisAreaManager()->GenerateStatObjAndMatTables((pStatObjTable != NULL) ? &statObjTable : NULL, - (pMatTable != NULL) ? &matTable : NULL, - (pStatInstGroupTable != NULL) ? &statInstGroupTable : NULL, - &exportInfo); - } - - if (pStatObjTable) - { - pStatObjTable->resize(statObjTable.size()); - for (size_t i = 0; i < statObjTable.size(); ++i) - { - (*pStatObjTable)[i] = statObjTable[i]; - } - - statObjTable.clear(); - } - - if (pMatTable) - { - pMatTable->resize(matTable.size()); - for (size_t i = 0; i < matTable.size(); ++i) - { - (*pMatTable)[i] = matTable[i]; - } - - matTable.clear(); - } - - if (pStatInstGroupTable) - { - pStatInstGroupTable->resize(statInstGroupTable.size()); - for (size_t i = 0; i < statInstGroupTable.size(); ++i) - { - (*pStatInstGroupTable)[i] = statInstGroupTable[i]; - } - - statInstGroupTable.clear(); - } -} - diff --git a/Code/CryEngine/Cry3DEngine/3dEngine.h b/Code/CryEngine/Cry3DEngine/3dEngine.h deleted file mode 100644 index a8e46c32ae..0000000000 --- a/Code/CryEngine/Cry3DEngine/3dEngine.h +++ /dev/null @@ -1,1514 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_3DENGINE_H -#define CRYINCLUDE_CRY3DENGINE_3DENGINE_H -#pragma once - -#include -#include -#include -#include -#include -#include - -#ifdef DrawText -#undef DrawText -#endif //DrawText - -struct IOctreeNode; -struct IDeferredPhysicsEventManager; -class COctreeNode; -class CCullBuffer; - -struct StatInstGroup; - - -namespace LegacyProceduralVegetation -{ - class VegetationPoolManager; -} - -class CMemoryBlock - : public IMemoryBlock -{ -public: - virtual void* GetData() { return m_pData; } - virtual int GetSize() { return m_nSize; } - virtual ~CMemoryBlock() { delete[] m_pData; } - - CMemoryBlock() { m_pData = 0; m_nSize = 0; } - CMemoryBlock(const void* pData, int nSize) - { - m_pData = 0; - m_nSize = 0; - SetData(pData, nSize); - } - void SetData(const void* pData, int nSize) - { - delete[] m_pData; - m_pData = new uint8[nSize]; - memcpy(m_pData, pData, nSize); - m_nSize = nSize; - } - void Free() - { - delete[] m_pData; - m_pData = NULL; - m_nSize = 0; - } - void Allocate(int nSize) - { - delete[] m_pData; - m_pData = new uint8[nSize]; - memset(m_pData, 0, nSize); - m_nSize = nSize; - } - - static CMemoryBlock* CompressToMemBlock(void* pData, int nSize, ISystem* pSystem) - { - CMemoryBlock* pMemBlock = NULL; - uint8* pTmp = new uint8[nSize + 4]; - size_t nComprSize = nSize; - *(uint32*)pTmp = nSize; - if (pSystem->CompressDataBlock(pData, nSize, pTmp + 4, nComprSize)) - { - pMemBlock = new CMemoryBlock(pTmp, nComprSize + 4); - } - - delete[] pTmp; - return pMemBlock; - } - - static CMemoryBlock* DecompressFromMemBlock(CMemoryBlock* pMemBlock, ISystem* pSystem) - { - size_t nUncompSize = *(uint32*)pMemBlock->GetData(); - SwapEndian(nUncompSize); - CMemoryBlock* pResult = new CMemoryBlock; - pResult->Allocate(nUncompSize); - if (!pSystem->DecompressDataBlock((byte*)pMemBlock->GetData() + 4, pMemBlock->GetSize() - 4, pResult->GetData(), nUncompSize)) - { - assert(!"CMemoryBlock::DecompressFromMemBlock failed"); - delete pResult; - pResult = NULL; - } - - return pResult; - } - - uint8* m_pData; - int m_nSize; -}; - -// Values to combine for phys area type selection -enum EAreaPhysics -{ - Area_Water = BIT(0), - Area_Air = BIT(1), - // Other physics media can be masked in as well - - Area_Gravity = BIT(14), - Area_Other = BIT(15), -}; - -struct SAreaChangeRecord -{ - AABB boxAffected; // Area of change - uint16 uPhysicsMask; // Types of mediums for this area -}; - -struct SPhysAreaNodeProxy -{ - void Reset() - { - pRenderNode = (IRenderNode*)(intptr_t)-1; - bIsValid = false; - bbox.Reset(); - } - - IRenderNode* pRenderNode; // RenderNode - uint16 uPhysicsMask; // Bit mask of physics interested in - bool bIsValid; // Does the proxy carry valid data - AABB bbox; // Bounding box of render node -}; - -struct SFrameInfo -{ - void Reset() - { - ppRNTmpData = (CRNTmpData**)(intptr_t)-1; - bIsValid = false; - nCreatedFrameId = nLastUsedFrameId = ~0; - } - - uint32 nLastUsedFrameId; - uint32 nCreatedFrameId; - bool bIsValid; - CRNTmpData** ppRNTmpData; -}; - -struct SNodeInfo; -class CStitchedImage; -struct DLightAmount -{ - CDLight* pLight; - float fAmount; -}; - -template -struct CPoolAllocator -{ - CPoolAllocator() { m_nCounter = 0; } - - ~CPoolAllocator() - { - Reset(); - } - - void Reset() - { - for (int i = 0; i < m_Pools.Count(); i++) - { - delete[](byte*)m_Pools[i]; - m_Pools[i] = NULL; - } - m_nCounter = 0; - } - - void ReleaseElement(T* pElem) - { - if (pElem) - { - m_FreeElements.Add(pElem); - } - } - - T* GetNewElement() - { - if (m_FreeElements.Count()) - { - T* pPtr = m_FreeElements.Last(); - m_FreeElements.DeleteLast(); - return pPtr; - } - - int nPoolId = m_nCounter / nMaxElemsInChunk; - int nElemId = m_nCounter - nPoolId * nMaxElemsInChunk; - m_Pools.PreAllocate(nPoolId + 1, nPoolId + 1); - if (!m_Pools[nPoolId]) - { - m_Pools[nPoolId] = (T*)new byte[nMaxElemsInChunk * sizeof(T)]; - } - m_nCounter++; - return &m_Pools[nPoolId][nElemId]; - } - - int GetCount() { return m_nCounter - m_FreeElements.Count(); } - int GetCapacity() { return m_Pools.Count() * nMaxElemsInChunk; } - int GetCapacityBytes() { return GetCapacity() * sizeof(T); } - -private: - - int m_nCounter; - PodArray m_Pools; - PodArray m_FreeElements; -}; - -struct SImageSubInfo -{ - SImageSubInfo() { memset(this, 0, sizeof(*this)); fTiling = fTilingIn = 1.f; } - - static const int nMipsNum = 4; - - union - { - byte* pImgMips[nMipsNum]; - int pImgMipsSizeKeeper[8]; - }; - - float fAmount; - int nReady; - int nDummy[4]; - - _smart_ptr pMat; - int nDim; - float fTilingIn; - float fTiling; - float fSpecularAmount; - int nSortOrder; - int nAlignFix; - - AUTO_STRUCT_INFO -}; - -struct SImageInfo - : public Cry3DEngineBase -{ - SImageInfo() - { - szDetMatName[0] = szBaseTexName[0] = '\0'; - nPhysSurfaceType = 0; - nLayerId = 0; - fUseRemeshing = 0; - fBr = 1.f; - layerFilterColor = Col_White; - nDetailSurfTypeId = 0; - ZeroStruct(arrTextureId); - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*nothing*/ } - - SImageSubInfo baseInfo; - SImageSubInfo detailInfo; - - char szDetMatName[128 - 20]; - - int arrTextureId[4]; - int nPhysSurfaceType; - - char szBaseTexName[128]; - - float fUseRemeshing; - ColorF layerFilterColor; - int nLayerId; - float fBr; - int nDetailSurfTypeId; - - int GetMemoryUsage(); - - AUTO_STRUCT_INFO -}; - -struct SSceneFrustum -{ - uint32* pRgbImage; - uint32 nRgbWidth, nRgbHeight; - - float* pDepthImage; - uint32 nDepthWidth, nDepthHeight; - - CCamera camera; - - IRenderMesh* pRM; - _smart_ptr pMaterial; - - float fDistance; - int nId; - - static int Compare(const void* v1, const void* v2) - { - SSceneFrustum* p[2] = { (SSceneFrustum*)v1, (SSceneFrustum*)v2 }; - - if (p[0]->fDistance > p[1]->fDistance) - { - return 1; - } - if (p[0]->fDistance < p[1]->fDistance) - { - return -1; - } - - if (p[0]->nId > p[1]->nId) - { - return 1; - } - if (p[0]->nId < p[1]->nId) - { - return -1; - } - - return 0; - } -}; - -struct SPerObjectShadow -{ - IShadowCaster* pCaster; - float fConstBias; - float fSlopeBias; - float fJitter; - Vec3 vBBoxScale; - uint nTexSize; -}; -////////////////////////////////////////////////////////////////////// -#define LV_MAX_COUNT 256 -#define LV_LIGHTS_MAX_COUNT 64 - -#define LV_WORLD_BUCKET_SIZE 512 -#define LV_LIGHTS_WORLD_BUCKET_SIZE 512 - -#define LV_WORLD_SIZEX 128 -#define LV_WORLD_SIZEY 128 -#define LV_WORLD_SIZEZ 64 - -#define LV_CELL_SIZEX 4 -#define LV_CELL_SIZEY 4 -#define LV_CELL_SIZEZ 8 - -#define LV_CELL_RSIZEX (1.0f / (float)LV_CELL_SIZEX) -#define LV_CELL_RSIZEY (1.0f / (float)LV_CELL_SIZEY) -#define LV_CELL_RSIZEZ (1.0f / (float)LV_CELL_SIZEZ) - -#define LV_LIGHT_CELL_SIZE 32 -#define LV_LIGHT_CELL_R_SIZE (1.0f / (float)LV_LIGHT_CELL_SIZE) - -#define LV_DLF_LIGHTVOLUMES_MASK (DLF_DISABLED | DLF_FAKE | DLF_AMBIENT | DLF_DEFERRED_CUBEMAPS) - -class CLightVolumesMgr - : public Cry3DEngineBase -{ -public: - CLightVolumesMgr() - { - Init(); - } - - void Init(); - void Reset(); - uint16 RegisterVolume(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo); - void RegisterLight(const CDLight& pDL, uint32 nLightID, const SRenderingPassInfo& passInfo); - void Update(const SRenderingPassInfo& passInfo); - void Clear(const SRenderingPassInfo& passInfo); - void GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols); -#ifndef _RELEASE - void DrawDebug(const SRenderingPassInfo& passInfo); -#endif - -private: - struct SLightVolInfo - { - SLightVolInfo() - : vVolume(ZERO, 0.0f) - , nNextVolume(0) - , nClipVolumeID(0) - { - }; - SLightVolInfo(const Vec3& pPos, float fRad, uint8 clipVolumeID) - : vVolume(pPos, fRad) - , nNextVolume(0) - , nClipVolumeID(clipVolumeID) - { - }; - - Vec4 vVolume; // xyz: position, w: radius - uint16 nNextVolume; // index of next light volume for this hash bucket (0 if none) - uint8 nClipVolumeID; // clip volume stencil ref - }; - - struct SLightCell - { - SLightCell() - : nLightCount(0) - { - }; - - uint16 nLightID[LV_LIGHTS_MAX_COUNT]; - uint8 nLightCount; - }; - - inline int32 GetIntHash(const int32 k, [[maybe_unused]] const int32 nBucketSize = LV_WORLD_BUCKET_SIZE) const - { - static const uint32 nHashBits = 9; - static const uint32 nGoldenRatio32bits = 2654435761u; // (2^32) / (golden ratio) - return (k * nGoldenRatio32bits) >> (32 - nHashBits); // ref: knuths integer multiplicative hash function - } - - inline uint16 GetWorldHashBucketKey(const int32 x, const int32 y, const int32 z, const int32 nBucketSize = LV_WORLD_BUCKET_SIZE) const - { - const uint32 nPrimeNum = 101;//0xd8163841; - return aznumeric_caster((((GetIntHash(x) + nPrimeNum) * nPrimeNum + GetIntHash(y)) * nPrimeNum + GetIntHash(z)) & (nBucketSize - 1)); - } - - void AddLight(const SRenderLight& pLight, const SLightVolInfo* __restrict pVolInfo, SLightVolume& pVolume); - - typedef DynArray LightVolumeVector; - -private: - LightVolumeVector m_pLightVolumes[RT_COMMAND_BUF_COUNT]; // Final light volume list. move light list creation to renderer to avoid double-buffering this - DynArray m_pLightVolsInfo[RT_COMMAND_BUF_COUNT]; // World cells data - SLightCell m_pWorldLightCells[LV_LIGHTS_WORLD_BUCKET_SIZE]; // 2D World cell buckets for light sources ids - uint16 m_nWorldCells[LV_WORLD_BUCKET_SIZE]; // World cell buckets for light volumes - bool m_bUpdateLightVolumes : 1; -}; - -// onscreen infodebug for e_debugDraw >= 100 -#ifndef _RELEASE -class CDebugDrawListMgr -{ - typedef CryFixedStringT<64> TMyStandardString; - typedef CryFixedStringT<128> TFilenameString; - -public: - - CDebugDrawListMgr(); - void Update(); - void AddObject(I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); - void DumpLog(); - bool IsEnabled() const { return Cry3DEngineBase::GetCVars()->e_DebugDraw >= LM_BASENUMBER; } - static void ConsoleCommand(IConsoleCmdArgs* args); - -private: - - enum - { - UNDEFINED_ASSET_ID = 0xffffffff - }; - - struct TAssetInfo - { - TMyStandardString name; - TFilenameString fileName; - uint32 numTris; - uint32 numVerts; - uint32 texMemory; - uint32 meshMemory; - uint32 drawCalls; - uint32 numInstances; - I3DEngine::EDebugDrawListAssetTypes type; - uint32 ID; // to identify which drawBoxes belong to this asset - - TAssetInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); - bool operator<(const TAssetInfo& other) const; - }; - - struct TObjectDrawBoxInfo - { - Matrix34 mat; - AABB bbox; - uint32 assetID; - - TObjectDrawBoxInfo(const I3DEngine::SObjectInfoToAddToDebugDrawList& objInfo); - }; - - void FindNewLeastValueAsset(); - void ClearFrameData(); - void ClearConsoleCommandRequestVars(); - static bool SortComparison(const TAssetInfo& A, const TAssetInfo& B) { return B < A; } - const char* GetStrCurrMode(); - void GetStrCurrFilter(TMyStandardString& strOut); - bool ShouldFilterOutObject(const I3DEngine::SObjectInfoToAddToDebugDrawList& newObject); - void MemToString(uint32 memVal, TMyStandardString& outStr); - static void PrintText(float x, float y, const ColorF& fColor, const char* label_text, ...); - const char* GetAssetTypeName(I3DEngine::EDebugDrawListAssetTypes type); - TAssetInfo* FindDuplicate(const TAssetInfo& object); - void CheckFilterCVar(); - - // to avoid any heap allocation - static void MyStandardString_Concatenate(TMyStandardString& outStr, const char* str); - static void MyFileNameString_Assign(TFilenameString& outStr, const char* pStr); - - template - static void MyString_Assign(T& outStr, const char* pStr) - { - if (pStr) - { - outStr._Assign(pStr, min(strlen(pStr), outStr.capacity())); - } - else - { - outStr = ""; - } - } - - - - enum EListModes - { - LM_BASENUMBER = 100, - LM_TRI_COUNT = LM_BASENUMBER, - LM_VERT_COUNT, - LM_DRAWCALLS, - LM_TEXTMEM, - LM_MESHMEM - }; - - - bool m_isFrozen; - uint32 m_counter; - uint32 m_assetCounter; - uint32 m_indexLeastValueAsset; - std::vector m_assets; - std::vector m_drawBoxes; - CryCriticalSection m_lock; - - static bool m_dumpLogRequested; - static bool m_freezeRequested; - static bool m_unfreezeRequested; - static uint32 m_filter; -}; -#endif //_RELEASE - -////////////////////////////////////////////////////////////////////// -class C3DEngine - : public I3DEngine - , public Cry3DEngineBase -{ -public: - - // I3DEngine interface implementation - virtual bool Init(); - virtual void OnFrameStart(); - virtual void Update(); - virtual void RenderWorld(int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName); - virtual void PreWorldStreamUpdate(const CCamera& cam); - virtual void WorldStreamUpdate(); - virtual void ShutDown(); - virtual void Release() { CryAlignedDelete(this); }; - virtual void SetLevelPath(const char* szFolderName); - virtual bool LoadLevel(const char* szFolderName, const char* szMissionName); - virtual void UnloadLevel(); - virtual void PostLoadLevel(); - virtual bool InitLevelForEditor(const char* szFolderName, const char* szMissionName); - virtual bool LevelLoadingInProgress(); - virtual void DisplayInfo(float& fTextPosX, float& fTextPosY, float& fTextStepY, bool bEnhanced); - virtual void DisplayMemoryStatistics(); - virtual void SetupDistanceFog(); - virtual IStatObj* LoadStatObjUnsafeManualRef(const char* fileName, const char* geomName = nullptr, /*[Out]*/ IStatObj::SSubObject** subObject = nullptr, - bool useStreaming = true, unsigned long loadingFlags = 0, const void* data = nullptr, int dataSize = 0) override; - virtual _smart_ptr LoadStatObjAutoRef(const char* fileName, const char* geomName = nullptr, /*[Out]*/ IStatObj::SSubObject** subObject = nullptr, - bool useStreaming = true, unsigned long loadingFlags = 0, const void* data = nullptr, int dataSize = 0) override; - virtual const IObjManager* GetObjectManager() const; - virtual IObjManager* GetObjectManager(); - - virtual IStatObj* FindStatObjectByFilename(const char* filename); - virtual void RegisterEntity(IRenderNode* pEnt, int nSID = -1, int nSIDConsideredSafe = -1); - virtual bool IsSunShadows(){ return m_bSunShadows; }; - virtual void SelectEntity(IRenderNode* pEnt); - virtual void LoadEmptyLevel() override; - - virtual void LoadStatObjAsync(LoadStaticObjectAsyncResult resultCallback, const char* szFileName, const char* szGeomName = nullptr, bool bUseStreaming = true, unsigned long nLoadingFlags = 0); - virtual void ProcessAsyncStaticObjectLoadRequests() override; - -#ifndef _RELEASE - virtual void AddObjToDebugDrawList(SObjectInfoToAddToDebugDrawList& objInfo); - virtual bool IsDebugDrawListEnabled() const { return m_DebugDrawListMgr.IsEnabled(); } -#endif - - virtual void UnRegisterEntityDirect(IRenderNode* pEnt); - virtual void UnRegisterEntityAsJob(IRenderNode* pEnt); - - virtual bool IsUnderWater(const Vec3& vPos) const; - virtual void SetOceanRenderFlags(uint8 nFlags); - virtual uint8 GetOceanRenderFlags() const { return m_nOceanRenderFlags; } - virtual uint32 GetOceanVisiblePixelsCount() const; - virtual float GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth, int objtypes); - virtual float GetBottomLevel(const Vec3& referencePos, float maxRelevantDepth /* = 10.0f*/); - virtual float GetBottomLevel(const Vec3& referencePos, int objflags); - -#if defined(USE_GEOM_CACHES) - virtual IGeomCache* LoadGeomCache(const char* szFileName); - virtual IGeomCache* FindGeomCacheByFilename(const char* szFileName); -#endif - - virtual IStatObj* LoadDesignerObject(int nVersion, const char* szBinaryStream, int size); - - void AsyncOctreeUpdate(IRenderNode* pEnt, int nSID, int nSIDConsideredSafe, uint32 nFrameID, bool bUnRegisterOnly); - bool UnRegisterEntityImpl(IRenderNode* pEnt); - - // Fast option - use if just ocean height required - virtual float GetWaterLevel(); - // This will return ocean height or water volume height, optional for accurate water height query - virtual float GetWaterLevel(const Vec3* pvPos, IPhysicalEntity* pent = NULL, bool bAccurate = false); - // Only use for Accurate query - this will return exact ocean height - virtual float GetAccurateOceanHeight(const Vec3& pCurrPos) const; - - virtual CausticsParams GetCausticsParams() const; - virtual OceanAnimationData GetOceanAnimationParams() const override; - virtual void GetHDRSetupParams(Vec4 pParams[5]) const; - virtual void CreateDecal(const CryEngineDecalInfo& Decal); - - virtual void SetSunDir(const Vec3& newSunOffset); - virtual Vec3 GetSunDir() const; - virtual Vec3 GetSunDirNormalized() const; - virtual Vec3 GetRealtimeSunDirNormalized() const; - virtual void SetSunColor(Vec3 vColor); - Vec3 GetSunAnimColor() override; - void SetSunAnimColor(const Vec3& sunAnimColor) override; - float GetSunAnimSpeed() override; - void SetSunAnimSpeed(float sunAnimSpeed) override; - AZ::u8 GetSunAnimPhase() override; - void SetSunAnimPhase(AZ::u8 sunAnimPhase) override; - AZ::u8 GetSunAnimIndex() override; - void SetSunAnimIndex(AZ::u8 sunAnimIndex) override; - virtual void SetSSAOAmount(float fMul); - virtual void SetSSAOContrast(float fMul); - virtual void SetRainParams(const SRainParams& rainParams); - virtual bool GetRainParams(SRainParams& rainParams); - virtual void SetSnowSurfaceParams(const Vec3& vCenter, float fRadius, float fSnowAmount, float fFrostAmount, float fSurfaceFreezing); - virtual bool GetSnowSurfaceParams(Vec3& vCenter, float& fRadius, float& fSnowAmount, float& fFrostAmount, float& fSurfaceFreezing); - virtual void SetSnowFallParams(int nSnowFlakeCount, float fSnowFlakeSize, float fSnowFallBrightness, float fSnowFallGravityScale, float fSnowFallWindScale, float fSnowFallTurbulence, float fSnowFallTurbulenceFreq); - virtual bool GetSnowFallParams(int& nSnowFlakeCount, float& fSnowFlakeSize, float& fSnowFallBrightness, float& fSnowFallGravityScale, float& fSnowFallWindScale, float& fSnowFallTurbulence, float& fSnowFallTurbulenceFreq); - virtual void OnExplosion(Vec3 vPos, float fRadius, bool bDeformTerrain = true); - //! For editor - virtual void RemoveAllStaticObjects(int nSID); - - virtual void SetPhysMaterialEnumerator(IPhysMaterialEnumerator* pPhysMaterialEnumerator); - virtual IPhysMaterialEnumerator* GetPhysMaterialEnumerator(); - virtual void LoadMissionDataFromXMLNode(const char* szMissionName); - - void AddDynamicLightSource(const class CDLight& LSource, ILightSource* pEnt, int nEntityLightId, float fFadeout, const SRenderingPassInfo& passInfo); - - inline void AddLightToRenderer(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) - { - const uint32 nLightID = GetRenderer()->EF_GetDeferredLightsNum(); - GetRenderer()->EF_AddDeferredLight(pLight, fMult, passInfo, rendItemSorter); - Get3DEngine()->m_LightVolumesMgr.RegisterLight(pLight, nLightID, passInfo); - m_nDeferredLightsNum++; - } - - virtual void SetMaxViewDistanceScale(float fScale) { m_fMaxViewDistScale = fScale; } - virtual float GetMaxViewDistance(bool bScaled = true); - virtual const SFrameLodInfo& GetFrameLodInfo() const { return m_frameLodInfo; } - virtual void SetFrameLodInfo(const SFrameLodInfo& frameLodInfo); - virtual void SetFogColor(const Vec3& vFogColor); - virtual Vec3 GetFogColor(); - virtual float GetDistanceToSectorWithWater(); - - virtual void GetSkyLightParameters(Vec3& sunDir, Vec3& sunIntensity, float& Km, float& Kr, float& g, Vec3& rgbWaveLengths); - virtual void SetSkyLightParameters(const Vec3& sunDir, const Vec3& sunIntensity, float Km, float Kr, float g, const Vec3& rgbWaveLengths, bool forceImmediateUpdate = false); - - void SetLightsHDRDynamicPowerFactor(const float value); - virtual float GetLightsHDRDynamicPowerFactor() const; - - // Return true if tessellation is allowed (by cvars) into currently set shadow map LOD - bool IsTessellationAllowedForShadowMap(const SRenderingPassInfo& passInfo) const; - // Return true if tessellation is allowed for given render object - virtual bool IsTessellationAllowed(const CRenderObject* pObj, const SRenderingPassInfo& passInfo, bool bIgnoreShadowPass = false) const; - - virtual void SetRenderNodeMaterialAtPosition(EERType eNodeType, const Vec3& vPos, _smart_ptr pMat); - virtual void OverrideCameraPrecachePoint(const Vec3& vPos); - virtual int AddPrecachePoint(const Vec3& vPos, const Vec3& vDir, float fTimeOut = 3.f, float fImportanceFactor = 1.0f); - virtual void ClearPrecachePoint(int id); - virtual void ClearAllPrecachePoints(); - virtual void GetPrecacheRoundIds(int pRoundIds[MAX_STREAM_PREDICTION_ZONES]); - - virtual void TraceFogVolumes(const Vec3& vPos, const AABB& objBBox, SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo, bool fogVolumeShadingQuality); - - virtual Vec3 GetSunColor() const; - virtual float GetSSAOAmount() const; - virtual float GetSSAOContrast() const; - - virtual void FreeRenderNodeState(IRenderNode* pEnt); - virtual const char* GetLevelFilePath(const char* szFileName); - - bool LoadCompiledOctreeForEditor() override; - virtual bool SetStatInstGroup(int nGroupId, const IStatInstGroup& siGroup, int nSID); - virtual bool GetStatInstGroup(int nGroupId, IStatInstGroup& siGroup, int nSID); - virtual void ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual void GetResourceMemoryUsage(ICrySizer* pSizer, const AABB& cstAABB); - virtual IVisArea* CreateVisArea(uint64 visGUID); - virtual void DeleteVisArea(IVisArea* pVisArea); - virtual void UpdateVisArea(IVisArea* pArea, const Vec3* pPoints, int nCount, const char* szName, - const SVisAreaInfo& info, bool bReregisterObjects); - virtual IClipVolume* CreateClipVolume(); - virtual void DeleteClipVolume(IClipVolume* pClipVolume); - virtual void UpdateClipVolume(IClipVolume* pClipVolume, _smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, bool bActive, uint32 flags, const char* szName); - virtual void ResetParticlesAndDecals(); - virtual IRenderNode* CreateRenderNode(EERType type); - virtual void DeleteRenderNode(IRenderNode* pRenderNode); - virtual Vec3 GetWind(const AABB& box, bool bIndoors) const; - virtual Vec3 GetGlobalWind(bool bIndoors) const; - virtual bool SampleWind(Vec3* pSamples, int nSamples, const AABB& volume, bool bIndoors) const; - void SetupBending(CRenderObject*& pObj, const IRenderNode* pNode, const float fRadiusVert, const SRenderingPassInfo& passInfo, bool alreadyDuplicated = false); - virtual IVisArea* GetVisAreaFromPos(const Vec3& vPos); - virtual bool IntersectsVisAreas(const AABB& box, void** pNodeCache = 0); - virtual bool ClipToVisAreas(IVisArea* pInside, Sphere& sphere, Vec3 const& vNormal, void* pNodeCache = 0); - virtual bool IsVisAreasConnected(IVisArea* pArea1, IVisArea* pArea2, int nMaxReqursion, bool bSkipDisabledPortals); - void EnableOceanRendering(bool bOcean); // todo: remove - - virtual void AddTextureLoadHandler(ITextureLoadHandler* pHandler); - virtual void RemoveTextureLoadHandler(ITextureLoadHandler* pHandler); - virtual ITextureLoadHandler* GetTextureLoadHandlerForImage(const char* ext); - virtual struct ILightSource* CreateLightSource(); - virtual void DeleteLightSource(ILightSource* pLightSource); - virtual bool RestoreTerrainFromDisk(int nSID); - virtual void CheckMemoryHeap(); - - virtual int GetLoadedObjectCount(); - virtual void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount); - virtual void GetObjectsStreamingStatus(SObjectsStreamingStatus& outStatus); - virtual void GetStreamingSubsystemData(int subsystem, SStremaingBandwidthData& outData); - virtual void DeleteEntityDecals(IRenderNode* pEntity); - virtual void DeleteDecalsInRange(AABB* pAreaBox, IRenderNode* pEntity); - virtual void LockCGFResources(); - virtual void UnlockCGFResources(); - virtual void FreeUnusedCGFResources(); - - virtual void SerializeState(TSerialize ser); - virtual void PostSerialize(bool bReading); - - virtual void SetStreamableListener(IStreamedObjectListener* pListener); - - ////////////////////////////////////////////////////////////////////////// - // Materials access. - virtual IMaterialHelpers& GetMaterialHelpers(); - virtual IMaterialManager* GetMaterialManager(); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ObjManager access. - virtual IObjManager* GetObjManager() override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // CGF Loader. - ////////////////////////////////////////////////////////////////////////// - virtual CContentCGF* CreateChunkfileContent(const char* filename); - virtual void ReleaseChunkfileContent(CContentCGF*); - virtual bool LoadChunkFileContent(CContentCGF* pCGF, const char* filename, bool bNoWarningMode = false, bool bCopyChunkFile = true); - virtual bool LoadChunkFileContentFromMem(CContentCGF* pCGF, const void* pData, size_t nDataLen, uint32 nLoadingFlags, bool bNoWarningMode = false, bool bCopyChunkFile = true); - ////////////////////////////////////////////////////////////////////////// - virtual IChunkFile* CreateChunkFile(bool bReadOnly = false); - - ////////////////////////////////////////////////////////////////////////// - // Chunk file writer. - ////////////////////////////////////////////////////////////////////////// - virtual ChunkFile::IChunkFileWriter* CreateChunkFileWriter(EChunkFileFormat eFormat, AZ::IO::IArchive* pPak, const char* filename) const; - virtual void ReleaseChunkFileWriter(ChunkFile::IChunkFileWriter* p) const; - - ////////////////////////////////////////////////////////////////////////// - // Post processing effects interfaces - - class IPostEffectGroupManager* GetPostEffectGroups() const override { return m_postEffectGroups.get(); } - class IPostEffectGroup* GetPostEffectBaseGroup() const override { return m_postEffectBaseGroup; } - - // Most code should use either GetPostEffectGroups() or GetPostEffectBaseGroup() instead of these - virtual void SetPostEffectParam(const char* pParam, float fValue, bool bForceValue = false) const; - virtual void SetPostEffectParamVec4(const char* pParam, const Vec4& pValue, bool bForceValue = false) const; - virtual void SetPostEffectParamString(const char* pParam, const char* pszArg) const; - - virtual void GetPostEffectParam(const char* pParam, float& fValue) const; - virtual void GetPostEffectParamVec4(const char* pParam, Vec4& pValue) const; - virtual void GetPostEffectParamString(const char* pParam, const char*& pszArg) const; - - virtual int32 GetPostEffectID(const char* pPostEffectName); - - virtual void ResetPostEffects(bool bOnSpecChange = false); - virtual void DisablePostEffects(); - - virtual void SetShadowsGSMCache(bool bCache); - virtual void SetCachedShadowBounds(const AABB& shadowBounds, float fAdditionalCascadesScale); - virtual void SetRecomputeCachedShadows(uint nUpdateStrategy = 0); - void SetShadowsCascadesBias(const float* pCascadeConstBias, const float* pCascadeSlopeBias); - const float* GetShadowsCascadesConstBias() const { return m_pShadowCascadeConstBias; } - const float* GetShadowsCascadesSlopeBias() const { return m_pShadowCascadeSlopeBias; } - int GetShadowsCascadeCount(const CDLight* pLight) const; - - virtual uint32 GetObjectsByType(EERType objType, IRenderNode** pObjects); - uint32 GetObjectsByTypeInBox(EERType objType, const AABB& bbox, IRenderNode** pObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; - virtual uint32 GetObjectsInBox(const AABB& bbox, IRenderNode** pObjects = 0); - void GetObjectsByTypeInBox(EERType objType, const AABB& bbox, PodArray* pLstObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; - virtual uint32 GetObjectsByFlags(uint dwFlags, IRenderNode** pObjects = 0); - virtual void OnObjectModified(IRenderNode* pRenderNode, uint dwFlags); - - virtual void ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, bool bObjects, bool bStaticLights, const char* pLayerName, IGeneralMemoryHeap* pHeap = NULL, bool bCheckLayerActivation = true); - virtual void GetLayerMemoryUsage(uint16 nLayerId, ICrySizer* pSizer, int* pNumBrushes, int* pNumDecals) const; - virtual void SkipLayerLoading(uint16 nLayerId, bool bClearList); - bool IsLayerSkipped(uint16 nLayerId); - - ////////////////////////////////////////////////////////////////////////// - - const char* GetLevelFolder() override { return m_szLevelFolder; } - - bool SaveCGF(std::vector& pObjs); - - virtual bool IsAreaActivationInUse() { return m_bAreaActivationInUse && GetCVars()->e_ObjectLayersActivation; } - - int GetCurrentLightSpec() - { - return CONFIG_VERYHIGH_SPEC; // very high spec. - } - - bool CheckMinSpec(uint32 nMinSpec) override; - - void UpdateRenderingCamera(const char* szCallerName, const SRenderingPassInfo& passInfo); - virtual void PrepareOcclusion(const CCamera& rCamera); - virtual void EndOcclusion(); -#ifndef _RELEASE - void ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOut, const SRenderingPassInfo& passInfo); -#endif - - void ScreenShotHighRes(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); - - // cylindrical mapping made by multiple slices rendered and distorted - // Returns: - // true=mode is active, stop normal rendering, false=mode is not active - bool ScreenShotPanorama(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); - // Render simple top-down screenshot for map overviews - bool ScreenShotMap(CStitchedImage* pStitchedImage, const int nRenderFlags, const SRenderingPassInfo& passInfo, uint32 SliceCount, f32 fTransitionSize); - - void ScreenshotDispatcher(const int nRenderFlags, const SRenderingPassInfo& passInfo); - - virtual void FillDebugFPSInfo(SDebugFPSInfo& info); - - void ClearDebugFPSInfo(bool bUnload = false) - { - m_fAverageFPS = 0.0f; - m_fMinFPS = m_fMinFPSDecay = 999.f; - m_fMaxFPS = m_fMaxFPSDecay = 0.0f; - ClearPrecacheInfo(); - if (bUnload) - { - stl::free_container(arrFPSforSaveLevelStats); - } - else - { - arrFPSforSaveLevelStats.clear(); - } - } - - void ClearPrecacheInfo() - { - m_nFramesSinceLevelStart = 0; - m_nStreamingFramesSinceLevelStart = 0; - m_bPreCacheEndEventSent = false; - m_fTimeStateStarted = 0.0f; - } - - virtual const CCamera& GetRenderingCamera() const { return m_RenderingCamera; } - virtual float GetZoomFactor() const { return m_fZoomFactor; } - virtual void Tick(); - - virtual void UpdateShaderItems(); - void GetCollisionClass(SCollisionClass& collclass, int tableIndex); - - C3DEngine(ISystem* pSystem); - ~C3DEngine(); - - const float GetGSMRange() override { return m_fGsmRange; } - const float GetGSMRangeStep() override { return m_fGsmRangeStep; } - - void UpdatePreRender(const SRenderingPassInfo& passInfo); - void UpdatePostRender(const SRenderingPassInfo& passInfo); - - virtual void RenderScene(const int nRenderFlags, const SRenderingPassInfo& passInfo); - virtual void RenderSceneReflection(int nRenderFlags, const SRenderingPassInfo& passInfo); - virtual void DebugDraw_UpdateDebugNode(); - - void DebugDraw_Draw(); - bool IsOutdoorVisible(); - void RenderSkyBox(_smart_ptr pMat, const SRenderingPassInfo& passInfo); - - int GetStreamingFramesSinceLevelStart() { return m_nStreamingFramesSinceLevelStart; } - int GetRenderFramesSinceLevelStart() { return m_nFramesSinceLevelStart; } - - bool CreateDecalInstance(const CryEngineDecalInfo&DecalInfo, class CDecal* pCallerManagedDecal); - Vec3 GetTerrainSurfaceNormal(Vec3 vPos); - void LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, int nSID); -#if defined(FEATURE_SVO_GI) - void LoadTISettings(XmlNodeRef pInputNode); -#endif - void LoadDefaultAssets(); - - // access to components - static CVars* GetCVars() { return m_pCVars; } - ILINE CVisAreaManager* GetVisAreaManager() { return m_pVisAreaManager; } - ILINE CClipVolumeManager* GetClipVolumeManager() { return m_pClipVolumeManager; } - ILINE PodArray* GetLightEntities() { return &m_lstStaticLights; } - - ILINE IGeneralMemoryHeap* GetBreakableBrushHeap() { return m_pBreakableBrushHeap; } - - virtual void OnCameraTeleport(); - - bool m_bAreaActivationInUse; - - // Level info - float m_fSkyBoxAngle, m_fSkyBoxStretching; - - float m_fMaxViewDistScale; - float m_fMaxViewDistHighSpec; - float m_fMaxViewDistLowSpec; - - float m_volFogGlobalDensity; - float m_volFogGlobalDensityMultiplierLDR; - float m_volFogFinalDensityClamp; - - float m_fCloudShadingSunLightMultiplier; - float m_fCloudShadingSkyLightMultiplier; - Vec3 m_vCloudShadingCustomSunColor; - Vec3 m_vCloudShadingCustomSkyColor; - - Vec3 m_vFogColor; - Vec3 m_vDefFogColor; - Vec3 m_vSunDir; - Vec3 m_vSunDirNormalized; - float m_fSunDirUpdateTime; - Vec3 m_vSunDirRealtime; - - Vec3 m_volFogRamp; - Vec3 m_volFogShadowRange; - Vec3 m_volFogShadowDarkening; - Vec3 m_volFogShadowEnable; - - Vec3 m_volFog2CtrlParams; - Vec3 m_volFog2ScatteringParams; - Vec3 m_volFog2Ramp; - Vec3 m_volFog2Color; - Vec3 m_volFog2GlobalDensity; - Vec3 m_volFog2HeightDensity; - Vec3 m_volFog2HeightDensity2; - Vec3 m_volFog2Color1; - Vec3 m_volFog2Color2; - - Vec3 m_nightSkyHorizonCol; - Vec3 m_nightSkyZenithCol; - float m_nightSkyZenithColShift; - float m_nightSkyStarIntensity; - Vec3 m_nightMoonCol; - float m_nightMoonSize; - Vec3 m_nightMoonInnerCoronaCol; - float m_nightMoonInnerCoronaScale; - Vec3 m_nightMoonOuterCoronaCol; - float m_nightMoonOuterCoronaScale; - - float m_moonRotationLatitude; - float m_moonRotationLongitude; - Vec3 m_moonDirection; - int m_nWaterBottomTexId; - int m_nNightMoonTexId; - float m_fSunClipPlaneRange; - float m_fSunClipPlaneRangeShift; - bool m_bSunShadows; - - int m_nCloudShadowTexId; - - float m_fGsmRange; - float m_fGsmRangeStep; - float m_fShadowsConstBias; - float m_fShadowsSlopeBias; - - int m_nSunAdditionalCascades; - int m_nGsmCache; - Vec3 m_oceanFogColor; - Vec3 m_oceanFogColorShallow; - float m_oceanFogDensity; - float m_skyboxMultiplier; - float m_dayNightIndicator; - bool m_bHeightMapAoEnabled; - - Vec3 m_fogColor2; - Vec3 m_fogColorRadial; - Vec3 m_volFogHeightDensity; - Vec3 m_volFogHeightDensity2; - Vec3 m_volFogGradientCtrl; - -private: - float m_oceanWindDirection; - float m_oceanWindSpeed; - float m_oceanWavesSpeed; - float m_oceanWavesAmount; - float m_oceanWavesSize; - -public: - float m_dawnStart; - float m_dawnEnd; - float m_duskStart; - float m_duskEnd; - - float m_fParticlesAmbientMultiplier; - float m_fParticlesLightMultiplier; - // film characteristic curve tweakables - Vec4 m_vHDRFilmCurveParams; - Vec3 m_vHDREyeAdaptation; - Vec3 m_vHDREyeAdaptationLegacy; - float m_fHDRBloomAmount; - - // hdr color grading - Vec3 m_vColorBalance; - float m_fHDRSaturation; - - // default post effect group path - const char* m_defaultPostEffectGroup = "Libs/PostEffectGroups/Default.xml"; - -#ifndef _RELEASE - CDebugDrawListMgr m_DebugDrawListMgr; -#endif - -#define MAX_SHADOW_CASCADES_NUM 20 - - float m_pShadowCascadeConstBias[MAX_SHADOW_CASCADES_NUM]; - float m_pShadowCascadeSlopeBias[MAX_SHADOW_CASCADES_NUM]; - - AABB m_CachedShadowsBounds; - uint m_nCachedShadowsUpdateStrategy; - float m_fCachedShadowsCascadeScale; - - // special case for combat mode adjustments - float m_fSaturation; - Vec4 m_pPhotoFilterColor; - float m_fPhotoFilterColorDensity; - float m_fGrainAmount; - float m_fSunSpecMult; - - // Level shaders - _smart_ptr m_pTerrainWaterMat; - _smart_ptr m_pSkyMat; - _smart_ptr m_pSkyLowSpecMat; - _smart_ptr m_pSunMat; - - // Fog Materials - _smart_ptr< IMaterial > m_pMatFogVolEllipsoid; - _smart_ptr< IMaterial > m_pMatFogVolBox; - - void CleanLevelShaders() - { - m_pTerrainWaterMat = 0; - m_pSkyMat = 0; - m_pSkyLowSpecMat = 0; - m_pSunMat = 0; - - m_pMatFogVolEllipsoid = 0; - m_pMatFogVolBox = 0; - } - - // Render elements - CRESky* m_pRESky; - CREHDRSky* m_pREHDRSky; - - int m_nDeferredLightsNum; - - mutable Vec3* m_pWindSamplePositions; - mutable size_t m_nWindSamplePositions; - - // functions SRenderingPass - virtual CCamera* GetRenderingPassCamera(const CCamera& rCamera); - - virtual void GetSvoStaticTextures(I3DEngine::SSvoStaticTexInfo& svoInfo, PodArray* pLightsTI_S, PodArray* pLightsTI_D); - virtual void GetSvoBricksForUpdate(PodArray& arrNodeInfo, bool getDynamic); - - bool IsShadersSyncLoad() { return m_bContentPrecacheRequested && GetCVars()->e_AutoPrecacheTexturesAndShaders; } - bool IsStatObjSyncLoad() { return m_bContentPrecacheRequested && GetCVars()->e_AutoPrecacheCgf; } - float GetAverageCameraSpeed() { return m_fAverageCameraSpeed; } - Vec3 GetAverageCameraMoveDir() { return m_vAverageCameraMoveDir; } - - typedef std::map ShadowFrustumListsCacheUsers; - ShadowFrustumListsCacheUsers m_FrustumsCacheUsers[2]; - - struct ILightSource* GetSunEntity(); - - void OnCasterDeleted(IShadowCaster* pCaster) override; - - CCullBuffer* GetCoverageBuffer() { return m_pCoverageBuffer; } - - void InitShadowFrustums(const SRenderingPassInfo& passInfo); - - /////////////////////////////////////////////////////////////////////////////// - - virtual void GetLightVolumes(threadID nThreadID, SLightVolume*& pLightVols, uint32& nNumVols); - virtual uint16 RegisterVolumeForLighting(const Vec3& vPos, f32 fRadius, uint8 nClipVolumeRef, const SRenderingPassInfo& passInfo); - - CLightVolumesMgr m_LightVolumesMgr; - - /////////////////////////////////////////////////////////////////////////////// - - void RemoveEntityLightSources(IRenderNode* pEntity); - - int GetRealLightsNum() { return m_nRealLightsNum; } - void SetupClearColor(); - void CheckAddLight(CDLight* pLight, const SRenderingPassInfo& passInfo); - - void DrawTextRightAligned(const float x, const float y, const char* format, ...) PRINTF_PARAMS(4, 5); - void DrawTextRightAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(6, 7); - void DrawTextLeftAligned(const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(6, 7); - void DrawTextAligned(int flags, const float x, const float y, const float scale, const ColorF& color, const char* format, ...) PRINTF_PARAMS(7, 8); - - void DrawBBoxHelper(const Vec3& vMin, const Vec3& vMax, ColorB col = Col_White) override { DrawBBox(vMin, vMax, col); } - void DrawBBoxHelper(const AABB& box, ColorB col = Col_White) override { DrawBBox(box, col); } - - float GetLightAmount(CDLight* pLight, const AABB& objBox); - - IStatObj* CreateStatObj(); - virtual IStatObj* CreateStatObjOptionalIndexedMesh(bool createIndexedMesh); - - // Creates a new indexed mesh. - IIndexedMesh* CreateIndexedMesh(); - - void InitMaterialDefautMappingAxis(_smart_ptr pMat) override; - _smart_ptr MakeSystemMaterialFromShaderHelper(const char* sShaderName, SInputShaderResources* Res = NULL) override - { - return MakeSystemMaterialFromShader(sShaderName, Res); - } - - bool CheckMinSpecHelper(uint32 nMinSpec) override { return CheckMinSpec(nMinSpec); } - - virtual IVisAreaManager* GetIVisAreaManager() { return (IVisAreaManager*)m_pVisAreaManager; } - bool CreateOcean(_smart_ptr pTerrainWaterMat, float waterLevel) override; - void DeleteOcean() override; - void ChangeOceanMaterial(_smart_ptr pMat) override; - void ChangeOceanWaterLevel(float fWaterLevel) override; - - bool LoadVisAreas(std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable); - bool LoadUsedShadersList(); - bool PrecreateDecals(); - void LoadFlaresData(); - - void LoadCollisionClasses(XmlNodeRef node); - - virtual void PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum); - virtual void ProposeContentPrecache() { m_bContentPrecacheRequested = true; } - bool IsContentPrecacheRequested() { return m_bContentPrecacheRequested; } - - virtual ITimeOfDay* GetTimeOfDay(); - virtual void SetSkyMaterialPath(const string& skyMaterialPath); - virtual void SetSkyLowSpecMaterialPath(const string& skyMaterialPath); - virtual void LoadSkyMaterial(); - virtual _smart_ptr GetSkyMaterial(); - void SetSkyMaterial(_smart_ptr pSkyMat) override; - bool IsHDRSkyMaterial(_smart_ptr pMat) const; - - using I3DEngine::SetGlobalParameter; - virtual void SetGlobalParameter(E3DEngineParameter param, const Vec3& v); - using I3DEngine::GetGlobalParameter; - virtual void GetGlobalParameter(E3DEngineParameter param, Vec3& v); - virtual void SetShadowMode(EShadowMode shadowMode) { m_eShadowMode = shadowMode; } - virtual EShadowMode GetShadowMode() const { return m_eShadowMode; } - virtual void AddPerObjectShadow(IShadowCaster* pCaster, float fConstBias, float fSlopeBias, float fJitter, const Vec3& vBBoxScale, uint nTexSize); - virtual void RemovePerObjectShadow(IShadowCaster* pCaster); - virtual struct SPerObjectShadow* GetPerObjectShadow(IShadowCaster* pCaster); - virtual void GetCustomShadowMapFrustums(ShadowMapFrustum*& arrFrustums, int& nFrustumCount); - virtual int SaveStatObj(IStatObj* pStatObj, TSerialize ser); - virtual IStatObj* LoadStatObj(TSerialize ser); - - virtual bool CheckIntersectClouds(const Vec3& p1, const Vec3& p2); - virtual void OnRenderMeshDeleted(IRenderMesh* pRenderMesh); - virtual bool RayObjectsIntersection2D(Vec3 vStart, Vec3 vEnd, Vec3& vHitPoint, EERType eERType); - virtual bool RenderMeshRayIntersection(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pCustomMtl = 0); - - virtual IOpticsManager* GetOpticsManager() { return m_pOpticsManager; } - - virtual void RegisterForStreaming(IStreamable* pObj); - virtual void UnregisterForStreaming(IStreamable* pObj); - - virtual void PrecacheRenderNode(IRenderNode* pObj, float fEntDistanceReal); - - void MarkRNTmpDataPoolForReset() { m_bResetRNTmpDataPool = true; } - SBending* GetBendingEntry(SBending*, const SRenderingPassInfo& passInfo); - - static void GetObjectsByTypeGlobal(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback = nullptr); - static void MoveObjectsIntoListGlobal(PodArray* plstResultEntities, const AABB* pAreaBox, bool bRemoveObjects = false, bool bSkipDecals = false, bool bSkip_ERF_NO_DECALNODE_DECALS = false, bool bSkipDynamicObjects = false, EERType eRNType = eERType_TypesNum); - - bool IsObjectTreeReady() override - { - return m_pObjectsTree != nullptr; - } - - IOctreeNode* GetIObjectTree() override - { - return (IOctreeNode*)m_pObjectsTree; - } - - inline COctreeNode* GetObjectTree() - { - return m_pObjectsTree; - } - - inline void SetObjectTree(COctreeNode* tree) - { - m_pObjectsTree = tree; - } - - int m_idMatLeaves; // for shooting foliages - bool m_bResetRNTmpDataPool; - - float m_fRefreshSceneDataCVarsSumm; - int m_nRenderTypeEnableCVarSum; - - PodArray m_lstAlwaysVisible; - PodArray m_lstPerObjectShadows; - PodArray m_lstCustomShadowFrustums; - int m_nCustomShadowFrustumCount; - - CryCriticalSection m_checkCreateRNTmpData; - CThreadSafeRendererContainer m_elementFrameInfo; - CRNTmpData m_LTPRootFree, m_LTPRootUsed; - void CreateRNTmpData(CRNTmpData** ppInfo, IRenderNode* pRNode, const SRenderingPassInfo& passInfo); - void CheckCreateRNTmpData(CRNTmpData** ppInfo, IRenderNode* pRNode, const SRenderingPassInfo& passInfo) override - { - // Lock to avoid a situation where two threads simultaneously find that *ppinfo is null, - // which would result in two CRNTmpData objects for the same owner which eventually leads to a crash - AUTO_LOCK(m_checkCreateRNTmpData); - if (CRNTmpData* tmpData = (*ppInfo)) - { - m_elementFrameInfo[tmpData->nFrameInfoId].nLastUsedFrameId = passInfo.GetMainFrameID(); - } - else - { - CreateRNTmpData(ppInfo, pRNode, passInfo); - } - } - - uint32 GetFrameInfoId(CRNTmpData** ppRNTmpData, uint32 createdFrameID) - { - size_t index = 0; - SFrameInfo* pFrameInfo = m_elementFrameInfo.push_back_new(index); - pFrameInfo->nCreatedFrameId = createdFrameID; - pFrameInfo->nLastUsedFrameId = createdFrameID; - pFrameInfo->ppRNTmpData = ppRNTmpData; - pFrameInfo->bIsValid = true; - return index; - } - - void FreeRNTmpData(CRNTmpData** ppInfo); - - void FreeRNTmpDataPool(); - void UpdateRNTmpDataPool(bool bFreeAll); - - // CPoolAllocator m_RNTmpDataPools; - - void UpdateStatInstGroups(); - void UpdateRenderTypeEnableLookup(); - void ProcessOcean(const SRenderingPassInfo& passInfo); - Vec3 GetEntityRegisterPoint(IRenderNode* pEnt); - - virtual void RenderRenderNode_ShadowPass(IShadowCaster* pRNode, const SRenderingPassInfo& passInfo, AZ::LegacyJobExecutor* pJobExecutor); - void ProcessCVarsChange(); - ILINE int GetGeomDetailScreenRes() - { - return GetCVars()->e_ForceDetailLevelForScreenRes ? GetCVars()->e_ForceDetailLevelForScreenRes : GetRenderer()->GetWidth(); - } - - int GetBlackTexID() { return m_nBlackTexID; } - int GetBlackCMTexID() { return m_nBlackCMTexID; } - - virtual void SyncProcessStreamingUpdate(); - - virtual void SetScreenshotCallback(IScreenshotCallback* pCallback); - - virtual IDeferredPhysicsEventManager* GetDeferredPhysicsEventManager() { return m_pDeferredPhysicsEventManager; } - - void PrintDebugInfo(const SRenderingPassInfo& passInfo); - - SImageSubInfo* RegisterImageInfo(byte** pMips, int nDim, const char* pName); - SImageSubInfo* GetImageInfo(const char* pName); - std::map m_imageInfos; - byte** AllocateMips(byte* pImage, int nDim, byte** pImageMips); - IScreenshotCallback* m_pScreenshotCallback; - OcclusionTestClient m_OceanOcclTestVar; - bool m_bInShutDown; - bool m_bInUnload; - bool m_bInLoad; - - IDeferredPhysicsEventManager* m_pDeferredPhysicsEventManager; - - std::set m_skipedLayers; - - IGeneralMemoryHeap* m_pBreakableBrushHeap; - - AZStd::mutex m_statObjQueueLock; - std::queue m_statObjLoadRequests; - - typedef std::list TTextureLoadHandlers; - TTextureLoadHandlers m_textureLoadHandlers; - - class PhysicsAreaUpdates - { - public: - void SetAreaDirty(const SAreaChangeRecord& rec); - - uint32 CreateProxy(const IRenderNode* pRenderNode, uint16 uPhysicsMask); - - void UpdateProxy(const IRenderNode* pRenderNode, uint32 nProxyId); - - void ResetProxy(uint32 proxyId); - - void Update(); - - void Reset(); - - void GarbageCollect(); - - CryCriticalSection m_Mutex; - private: - CThreadSafeRendererContainer m_Proxies; - PodArray m_DirtyAreas; - }; - - PhysicsAreaUpdates& GetPhysicsAreaUpdates() - { - return m_PhysicsAreaUpdates; - } - - //I3DEngine Overrides START - void GetStatObjAndMatTables(DynArray* pStatObjTable, DynArray<_smart_ptr >* pMatTable, DynArray* pStatInstGroupTable, uint32 nObjTypeMask) override; - void WaitForCullingJobsCompletion() override; - //I3DEngine Overrides END - -private: - - // IProcess Implementation - void SetFlags(int flags) { m_nFlags = flags; } - int GetFlags(void) { return m_nFlags; } - int m_nFlags; - - COctreeNode* m_pObjectsTree; - - std::vector arrFPSforSaveLevelStats; - PodArray m_arrProcessStreamingLatencyTestResults; - PodArray m_arrProcessStreamingLatencyTexNum; - - // fields which are used by SRenderingPass to store over frame information - CThreadSafeRendererContainer m_RenderingPassCameras[2]; // camera storage for SRenderingPass, the cameras cannot be stored on stack to allow job execution - - float m_fZoomFactor; // zoom factor of m_RenderingCamera - // cameras used by 3DEngine - CCamera m_RenderingCamera; // Camera used for Rendering on 3DEngine Side, normally equal to the view camera, except if frozen with e_camerafreeze - - PodArray m_deferredRenderComponentStreamingPriorityUpdates; // deferred streaming priority updates for newly seen CComponentRenders - - float m_fLightsHDRDynamicPowerFactor; // lights hdr exponent/exposure - - int m_nBlackTexID; - int m_nBlackCMTexID; - char m_sGetLevelFilePathTmpBuff[AZ_MAX_PATH_LEN]; - char m_szLevelFolder[_MAX_PATH]; - - bool m_bOcean; // todo: remove - - // Ocean Caustics - Should be removed once the Ocean Gem is done and the feature toggle for it is removed. - float m_oceanCausticsDistanceAtten; - float m_oceanCausticsTiling; - float m_oceanCausticDepth; - float m_oceanCausticIntensity; - - Vec3 m_vSkyHightlightPos; - Vec3 m_vSkyHightlightCol; - float m_fSkyHighlightSize; - Vec3 m_vAmbGroundCol; - float m_fAmbMaxHeight; - float m_fAmbMinHeight; - uint8 m_nOceanRenderFlags; - Vec3 m_vPrevMainFrameCamPos; - float m_fAverageCameraSpeed; - Vec3 m_vAverageCameraMoveDir; - EShadowMode m_eShadowMode; - bool m_bLayersActivated; - bool m_bContentPrecacheRequested; - bool m_bTerrainTextureStreamingInProgress; - bool m_bSegmentOperationInProgress; - - // interfaces - IPhysMaterialEnumerator* m_pPhysMaterialEnumerator; - - // data containers - int m_nRealLightsNum; - - PodArray m_lstStaticLights; - - PodArray m_collisionClasses; - -#define MAX_LIGHTS_NUM 32 - PodArray m_arrLightProjFrustums; - - class CTimeOfDay* m_pTimeOfDay; - - std::unique_ptr m_postEffectGroups; - class IPostEffectGroup* m_postEffectBaseGroup; - - ICVar* m_pLightQuality; - - // FPS for savelevelstats - - float m_fAverageFPS; - float m_fMinFPS, m_fMinFPSDecay; - float m_fMaxFPS, m_fMaxFPSDecay; - int m_nFramesSinceLevelStart; - int m_nStreamingFramesSinceLevelStart; - bool m_bPreCacheEndEventSent; - float m_fTimeStateStarted; - uint32 m_nRenderWorldUSecs; - SFrameLodInfo m_frameLodInfo; - - ITexture* m_ptexIconLowMemoryUsage; - ITexture* m_ptexIconAverageMemoryUsage; - ITexture* m_ptexIconHighMemoryUsage; - ITexture* m_ptexIconEditorConnectedToConsole; - - std::vector m_decalRenderNodes; // list of registered decal render nodes, used to clean up longer not drawn decals - - class PhysicsAreaUpdatesHandler; - AZStd::unique_ptr m_physicsAreaUpdatesHandler; - - PhysicsAreaUpdates m_PhysicsAreaUpdates; - - string m_skyMatName; - string m_skyLowSpecMatName; - - // Variable to keep track if the cvar e_SkyType has changed, which may cause the engine to load a different sky material - int m_previousSkyType = -1; - - //Bending Pools contain the per frame Vegetation, Decals, etc. structures. Each Engine-frame the next buffer is - // cleared and set as the current in a ring and page-allocated to fit the needs of the current frame. - static const int NUM_BENDING_POOLS = 4; - CThreadSafeRendererContainer m_bendingPool[NUM_BENDING_POOLS]; - int m_bendingPoolIdx; - - bool m_levelLoaded; - - // not sorted - - void LoadTimeOfDaySettingsFromXML(XmlNodeRef node); - char* GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szDefaultValue); - char* GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szLevel3, const char* szDefaultValue); - - // without calling high level functions like panorama screenshot - void RenderInternal(const int nRenderFlags, const SRenderingPassInfo& passInfo, const char* szDebugName); - - bool IsCameraAnd3DEngineInvalid(const SRenderingPassInfo& passInfo, const char* szCaller); - - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - - void ResetCasterCombinationsCache(); - - void DeleteAllStaticLightSources(); - - void UpdateSun(const SRenderingPassInfo& passInfo); - void SubmitSun(const SRenderingPassInfo& passInfo); - - CCullBuffer* m_pCoverageBuffer; - struct CLightEntity* m_pSun; - - void UpdateMoonDirection(); - - // Copy objects from tree - void CopyObjectsByType(EERType objType, const AABB* pBox, PodArray* plistObjects, ObjectTreeQueryFilterCallback filterCallback = nullptr); - void CopyObjects(const AABB* pBox, PodArray* plistObjects); - - void CleanUpOldDecals(); - - template - using LoadStatObjFunc = TReturn(CObjManager::*)(const char* filename, const char* _szGeomName, IStatObj::SSubObject** ppSubObject, bool bUseStreaming, unsigned long nLoadingFlags, const void* pData, int nDataSize, const char* szBlockName); - - template - TReturn LoadStatObjInternal(const char* fileName, const char* geomName, IStatObj::SSubObject** subObject, bool useStreaming, - unsigned long loadingFlags, LoadStatObjFunc loadStatObjFunc, const void* data = nullptr, int dataSize = 0); - - bool RemoveObjectsInArea(Vec3 vExploPos, float fExploRadius); - - /////////////////////////////////////////////////////////////////////////// - // Octree Loading/Saving related START - /////////////////////////////////////////////////////////////////////////// - - - //! initialWorldSize: in Meters. - bool CreateOctree(float initialWorldSize); - - void DestroyOctree(); - - /////////////////////////////////////////////////////////////////////////// - // Octree Loading/Saving related END - /////////////////////////////////////////////////////////////////////////// -}; - -#endif // CRYINCLUDE_CRY3DENGINE_3DENGINE_H diff --git a/Code/CryEngine/Cry3DEngine/3dEngineLoad.cpp b/Code/CryEngine/Cry3DEngine/3dEngineLoad.cpp deleted file mode 100644 index 215fe602c9..0000000000 --- a/Code/CryEngine/Cry3DEngine/3dEngineLoad.cpp +++ /dev/null @@ -1,1285 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Level loading - - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "Ocean.h" -#include "DecalManager.h" -#include "MatMan.h" -#include "IndexedMesh.h" -#include "SkyLightManager.h" -#include "ObjectsTree.h" -#include "LightEntity.h" -#include "TimeOfDay.h" -#include "LightEntity.h" -#include "RenderMeshMerger.h" -#include "FogVolumeRenderNode.h" -#include "IDeferredCollisionEvent.h" -#include -#include "ClipVolumeManager.h" -#include "Environment/OceanEnvironmentBus.h" - -#include -#include -#include - -#include -#include - -//------------------------------------------------------------------------------ -#define LEVEL_DATA_FILE "LevelData.xml" -#define CUSTOM_MATERIALS_FILE "Materials.xml" -#define PARTICLES_FILE "LevelParticles.xml" -#define SHADER_LIST_FILE "ShadersList.txt" -#define LEVEL_CONFIG_FILE "Level.cfg" -#define LEVEL_EDITOR_CONFIG_FILE "Editor.cfg" -//------------------------------------------------------------------------------ -const uint32 MAX_ACTIVE_BREEZE_POINTS = 99; -//------------------------------------------------------------------------------ - -inline Vec3 StringToVector(const char* str) -{ - Vec3 vTemp(0, 0, 0); - float x, y, z; - if (azsscanf(str, "%f,%f,%f", &x, &y, &z) == 3) - { - vTemp(x, y, z); - } - else - { - vTemp(0, 0, 0); - } - return vTemp; -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::LoadEmptyLevel() -{ - CreateOctree(0.0f); - LoadDefaultAssets(); -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::SetLevelPath(const char* szFolderName) -{ - // make folder path - assert(strlen(szFolderName) < 1024); - azstrcpy(m_szLevelFolder, AZ_ARRAY_SIZE(m_szLevelFolder), szFolderName); - if (strlen(m_szLevelFolder) > 0) - { - if (m_szLevelFolder[strlen(m_szLevelFolder) - 1] != '/') - { - azstrcat(m_szLevelFolder, AZ_ARRAY_SIZE (m_szLevelFolder), "/"); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::LoadDefaultAssets() -{ - GetRenderer()->InitSystemResources(FRR_SYSTEM_RESOURCES); - - //Add a call to refresh the loading screen and call the loading tick functions to ensure that no big gaps in coverage occur. - SYNCHRONOUS_LOADING_TICK(); - -#if !defined(SYS_ENV_AS_STRUCT) - PREFAST_ASSUME(gEnv); -#endif - - GetMatMan()->InitDefaults(); - - m_nBlackTexID = GetRenderer()->EF_LoadTexture("EngineAssets/Textures/black.dds", FT_DONT_STREAM)->GetTextureID(); - m_nBlackCMTexID = GetRenderer()->EF_LoadTexture("EngineAssets/Textures/BlackCM.dds", FT_DONT_RELEASE | FT_DONT_STREAM)->GetTextureID(); - - m_pMatFogVolEllipsoid = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/FogVolumeEllipsoid", false); - m_pMatFogVolBox = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/FogVolumeBox", false); - - if (!m_pRESky) - { - m_pRESky = (CRESky*)GetRenderer()->EF_CreateRE(eDATA_Sky); //m_pRESky->m_fAlpha = 1.f; - } - if (!m_pREHDRSky) - { - m_pREHDRSky = (CREHDRSky*)GetRenderer()->EF_CreateRE(eDATA_HDRSky); - } - - if (!m_ptexIconLowMemoryUsage) - { - m_ptexIconLowMemoryUsage = gEnv->pRenderer->EF_LoadDefaultTexture("LowMemoryUsage"); - } - - if (!m_ptexIconAverageMemoryUsage) - { - m_ptexIconAverageMemoryUsage = gEnv->pRenderer->EF_LoadDefaultTexture("AverageMemoryUsage"); - } - - if (!m_ptexIconHighMemoryUsage) - { - m_ptexIconHighMemoryUsage = gEnv->pRenderer->EF_LoadDefaultTexture("HighMemoryUsage"); - } - - if (!m_ptexIconEditorConnectedToConsole) - { - m_ptexIconEditorConnectedToConsole = gEnv->pRenderer->EF_LoadDefaultTexture("LivePreview"); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool C3DEngine::InitLevelForEditor([[maybe_unused]] const char* szFolderName, [[maybe_unused]] const char* szMissionName) -{ -#if defined(CONSOLE) - CRY_ASSERT_MESSAGE(0, "InitLevelForEditor not supported on consoles yet"); - return false; -#else - LOADING_TIME_PROFILE_SECTION; - - m_bEditor = true; - m_bAreaActivationInUse = false; - m_bLayersActivated = true; - - ClearDebugFPSInfo(); - - bool usePrefabSystemEnabled = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); - - if (!szFolderName || !szFolderName[0]) - { - Warning("C3DEngine::LoadLevel: Level name is not specified"); - return 0; - } - - if (!usePrefabSystemEnabled && (!szMissionName || !szMissionName[0])) - { - Warning("C3DEngine::LoadLevel: Mission name is not specified"); - } - - char szMissionNameBody[256] = "NoMission"; - if (!szMissionName) - { - szMissionName = szMissionNameBody; - } - - SetLevelPath(szFolderName); - - // Load console vars specific to this level. - if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_CONFIG_FILE))) - { - GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_CONFIG_FILE)); - } - - if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_EDITOR_CONFIG_FILE))) - { - GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_EDITOR_CONFIG_FILE)); - } - - if (!m_pObjManager) - { - m_pObjManager = CryAlignedNew(); - } - - if (!m_pVisAreaManager) - { - m_pVisAreaManager = new CVisAreaManager(); - } - - CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0); - - if (m_pSkyLightManager) - { - m_pSkyLightManager->InitSkyDomeMesh(); - } - - // recreate decals - SAFE_DELETE(m_pDecalManager); - m_pDecalManager = new CDecalManager(); - - // restore game state - EnableOceanRendering(true); - m_pObjManager->SetLockCGFResources(0); - - LoadDefaultAssets(); - - { - const char* SettingsFileName = GetLevelFilePath("ScreenshotMap.Settings"); - - AZ::IO::HandleType metaFileHandle = gEnv->pCryPak->FOpen(SettingsFileName, "r"); - if (metaFileHandle != AZ::IO::InvalidHandle) - { - char Data[1024 * 8]; - gEnv->pCryPak->FRead(Data, sizeof(Data), metaFileHandle); - azsscanf(Data, "", - &GetCVars()->e_ScreenShotMapCenterX, - &GetCVars()->e_ScreenShotMapCenterY, - &GetCVars()->e_ScreenShotMapSizeX, - &GetCVars()->e_ScreenShotMapSizeY, - &GetCVars()->e_ScreenShotMapCamHeight, - &GetCVars()->e_ScreenShotQuality, - &GetCVars()->e_ScreenShotMapOrientation); - gEnv->pCryPak->FClose(metaFileHandle); - } - } - - - GetObjManager()->LoadOcclusionMesh(szFolderName); - - // delete m_pObjectsTree[nSID]; - // m_pObjectsTree[nSID] = NULL; - return (true); -#endif -} - -bool C3DEngine::LevelLoadingInProgress() -{ - return Cry3DEngineBase::m_bLevelLoadingInProgress; -} - -bool C3DEngine::LoadCompiledOctreeForEditor() -{ - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (usePrefabSystemForLevels) - { - // Prefab levels don't use any of the legacy level data. - return true; - } - - - // Load LevelData.xml File. - XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE)); - - if (xmlLevelData == 0) - { - Error("C3DEngine::LoadLevel: xml file not found (files missing?)"); // files missing ? - return false; - } - - LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses")); - - return true; -} - -bool C3DEngine::LoadVisAreas(std::vector** ppStatObjTable, std::vector<_smart_ptr >** ppMatTable) -{ - LOADING_TIME_PROFILE_SECTION; - - PrintMessage("===== Loading %s =====", COMPILED_VISAREA_MAP_FILE_NAME); - - // open file - AZ::IO::HandleType fileHandle = GetPak()->FOpen(GetLevelFilePath(COMPILED_VISAREA_MAP_FILE_NAME), "rbx"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - // read header - SVisAreaManChunkHeader header; - if (!GetPak()->FRead(&header, 1, fileHandle, false)) - { - GetPak()->FClose(fileHandle); - return 0; - } - - SwapEndian(header, (header.nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian); - - if (header.nChunkSize) - { - assert(!m_pVisAreaManager); - m_pVisAreaManager = new CVisAreaManager(); - if (!m_pVisAreaManager->Load(fileHandle, header.nChunkSize, &header, *ppStatObjTable, *ppMatTable)) - { - delete m_pVisAreaManager; - m_pVisAreaManager = NULL; - } - } - - assert(GetPak()->FEof(fileHandle)); - - GetPak()->FClose(fileHandle); - - return m_pVisAreaManager != NULL; -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::UnloadLevel() -{ - if (!m_levelLoaded) - { - return; - } - GetRenderer()->EnableLevelUnloading(true); - - GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_UNLOAD, 0, 0); - // Run any events that were queued against the system tick bus before we start tearing down systems and deleting things - // This should prevent any stale events from running when the next level is loaded - AZ::SystemTickBus::ExecuteQueuedEvents(); - - GetRenderer()->EnableLevelUnloading(false); - - m_bInUnload = true; - m_szLevelFolder[0] = 0; - - GetRenderer()->FlushRTCommands(true, true, true); - - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::ReleaseData); - InstanceStatObjEventBus::Broadcast(&InstanceStatObjEventBus::Events::ReleaseData); - - FreeRNTmpDataPool(); - - if (m_pSkyLightManager) - { - m_pSkyLightManager->ReleaseSkyDomeMesh(); - } - - ResetPostEffects(); - - // delete decal manager - if (m_pDecalManager) - { - CryComment("Deleting Decals"); - SAFE_DELETE(m_pDecalManager); - CryComment("done"); - } - - if (m_pOcean) - { - CryComment("Deleting Ocean"); - SAFE_DELETE(m_pOcean); - CryComment("done"); - } - - // delete outdoor objects - CryComment("Deleting Octree"); - DestroyOctree(); - SAFE_DELETE(m_pObjectsTree); - m_pObjectsTree = nullptr; - - // delete indoors - if (m_pVisAreaManager) - { - CryComment("Deleting VisAreas"); - SAFE_DELETE(m_pVisAreaManager); - CryComment("done"); - } - - CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0); - - m_LightVolumesMgr.Reset(); - - m_pTerrainWaterMat = 0; - m_nWaterBottomTexId = 0; - - - ////////////////////////////////////////////////////////////////////////// - CryComment("Removing Lights ..."); - DeleteAllStaticLightSources(); - SAFE_DELETE(m_pSun); - CryComment("done"); - ////////////////////////////////////////////////////////////////////////// - - - CleanLevelShaders(); - - if (m_pRESky) - { - m_pRESky->Release(true); - } - if (m_pREHDRSky) - { - m_pREHDRSky->Release(true); - } - m_pRESky = 0; - m_pREHDRSky = 0; - stl::free_container(m_skyMatName); - stl::free_container(m_skyLowSpecMatName); - m_previousSkyType = -1; - - if (m_nCloudShadowTexId) - { - ITexture* tex = GetRenderer()->EF_GetTextureByID(m_nCloudShadowTexId); - if (tex) - { - tex->Release(); - } - - m_nCloudShadowTexId = 0; - GetRenderer()->SetCloudShadowsParams(0, Vec3(0, 0, 0), 1, false, 1); - SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_ENABLE, Vec3(0, 0, 0)); - } - - if (m_nNightMoonTexId) - { - ITexture* tex = GetRenderer()->EF_GetTextureByID(m_nNightMoonTexId); - if (tex) - { - tex->Release(); - } - - m_nNightMoonTexId = 0; - } - - ////////////////////////////////////////////////////////////////////////// - if (m_pObjManager) - { - bool bDeleteAll = !m_bEditor || m_bInShutDown; - CryComment("Deleting Static Objects"); - m_pObjManager->UnloadObjects(bDeleteAll); - m_pObjManager->GetCullThread().UnloadLevel(); - CryComment("done"); - } - - AZ_Assert(m_pObjectsTree == nullptr, "m_pObjectsTree == nullptr"); - COctreeNode::StaticReset(); - - ////////////////////////////////////////////////////////////////////////// - // Force delete all materials. - ////////////////////////////////////////////////////////////////////////// - if (GetMatMan() && !m_bEditor) - { - // Should be after deleting all meshes. - // We force delete all materials. - CryComment("Deleting Materials"); - GetMatMan()->ShutDown(); - CryComment("done"); - } - - //Set default icons to nullptr here, texture manager will take care of the memory release - m_ptexIconAverageMemoryUsage = nullptr; - m_ptexIconLowMemoryUsage = nullptr; - m_ptexIconHighMemoryUsage = nullptr; - m_ptexIconEditorConnectedToConsole = nullptr; - - if (m_pOpticsManager && !gEnv->IsEditor()) - { - m_pOpticsManager->Reset(); - } - - ////////////////////////////////////////////////////////////////////////// - - stl::free_container(m_lstAlwaysVisible); - if (m_decalRenderNodes.empty()) - { - stl::free_container(m_decalRenderNodes); - } - stl::free_container(m_lstPerObjectShadows); - m_nCustomShadowFrustumCount = 0; - - Cry3DEngineBase::m_pRenderMeshMerger->Reset(); - - SAFE_DELETE(m_pTimeOfDay); - CLightEntity::StaticReset(); - CVisArea::StaticReset(); - CFogVolumeRenderNode::StaticReset(); - - GetRenderer()->FlushRTCommands(true, true, true); - - IDeferredPhysicsEventManager* pPhysEventManager = GetDeferredPhysicsEventManager(); - if (pPhysEventManager) - { - pPhysEventManager->ClearDeferredEvents(); - } - - m_PhysicsAreaUpdates.Reset(); - for (size_t i = 0; i < NUM_BENDING_POOLS; stl::free_container(m_bendingPool[i++])) - { - ; - } - - ////////////////////////////////////////////////////////////////////////// - // clear data used for SRenderingPass - stl::free_container(m_RenderingPassCameras[0]); - stl::free_container(m_RenderingPassCameras[1]); - stl::free_container(m_deferredRenderComponentStreamingPriorityUpdates); - - stl::free_container(m_lstCustomShadowFrustums); - - m_nWindSamplePositions = 0; - if (m_pWindSamplePositions) - { - CryModuleMemalignFree(m_pWindSamplePositions); - m_pWindSamplePositions = NULL; - } - - stl::free_container(m_collisionClasses); - m_levelLoaded = false; -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::LoadFlaresData() -{ - string flareExportListPath = gEnv->p3DEngine->GetLevelFilePath(FLARE_EXPORT_FILE); - XmlNodeRef pFlareRootNode = gEnv->pSystem->LoadXmlFromFile(flareExportListPath); - - if (pFlareRootNode == NULL) - { - return; - } - - int nFlareExportFileVer = 0; - pFlareRootNode->getAttr("Version", nFlareExportFileVer); - - for (int i = 0, iCount(pFlareRootNode->getChildCount()); i < iCount; ++i) - { - XmlNodeRef pFlareNode = pFlareRootNode->getChild(i); - if (pFlareNode == NULL) - { - continue; - } - const char* flareName = NULL; - if (!pFlareNode->getAttr("name", &flareName)) - { - continue; - } - int nOutIndex(-1); - - if (nFlareExportFileVer == 0) - { - gEnv->pOpticsManager->Load(flareName, nOutIndex); - } - else if (nFlareExportFileVer == 1) - { - if (pFlareNode->getChildCount() == 0) - { - gEnv->pOpticsManager->Load(flareName, nOutIndex); - } - else if (pFlareNode->getChildCount() > 0) - { - gEnv->pOpticsManager->Load(pFlareNode, nOutIndex); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName) -{ - LOADING_TIME_PROFILE_SECTION; - - CRY_ASSERT(m_levelLoaded == false); - - PREFAST_ASSUME(gEnv); - - stl::scoped_set setInLoad(m_bInLoad, true); - - m_bInUnload = false; - m_bAreaActivationInUse = false; - m_bLayersActivated = false; - m_eShadowMode = ESM_NORMAL; - - m_vPrevMainFrameCamPos.Set(-1000000.f, -1000000.f, -1000000.f); - m_vAverageCameraMoveDir = Vec3(0); - m_fAverageCameraSpeed = 0; - - ClearDebugFPSInfo(); - -#if !defined(CONSOLE) - m_bEditor = false; -#endif - - assert(!m_bEditor); - - ////////////////////////////////////////////////////////////////////////// - - if (!szFolderName || !szFolderName[0]) - { - Warning("C3DEngine::LoadLevel: Level name is not specified"); - return 0; - } - - if (!szMissionName || !szMissionName[0]) - { - Warning("C3DEngine::LoadLevel: Mission name is not specified"); - } - - char szMissionNameBody[256] = "NoMission"; - if (!szMissionName) - { - szMissionName = szMissionNameBody; - } - - SetLevelPath(szFolderName); - - if (GetPak()->IsFileExist(GetLevelFilePath(LEVEL_CONFIG_FILE))) - { - GetISystem()->LoadConfiguration(GetLevelFilePath(LEVEL_CONFIG_FILE)); - } - - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (!usePrefabSystemForLevels) - { // check is LevelData.xml file exist - char sMapFileName[_MAX_PATH]; - cry_strcpy(sMapFileName, m_szLevelFolder); - cry_strcat(sMapFileName, LEVEL_DATA_FILE); - if (!IsValidFile(sMapFileName)) - { - PrintMessage("Error: Level not found: %s", sMapFileName); - return 0; - } - } - - if (!m_pObjManager) - { - m_pObjManager = CryAlignedNew(); - } - - CRY_ASSERT(m_pClipVolumeManager->GetClipVolumeCount() == 0); - - // Load and activate all shaders used by the level before activating any shaders - if (!m_bEditor) - { - LoadUsedShadersList(); - } - -#if AZ_LOADSCREENCOMPONENT_ENABLED - // Make sure system resources are inited before displaying a load screen - GetRenderer()->InitSystemResources(FRR_SYSTEM_RESOURCES); - // IMPORTANT: This MUST be done AFTER the LoadConfiguration() above. - EBUS_EVENT(LoadScreenBus, LevelStart); -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - LoadDefaultAssets(); - - if (m_pSkyLightManager) - { - m_pSkyLightManager->InitSkyDomeMesh(); - // set default render parameters. - // for some reason this is not done later??? - m_pSkyLightManager->UpdateRenderParams(); - } - - // Load LevelData.xml File. - XmlNodeRef xmlLevelData; - if (!usePrefabSystemForLevels) - { - xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE)); - - if (xmlLevelData == 0) - { - Error("C3DEngine::LoadLevel: xml file not found (files missing?)"); // files missing ? - return false; - } - } - - // re-create decal manager - SAFE_DELETE(m_pDecalManager); - m_pDecalManager = new CDecalManager(); - - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_MATERIALS); - if (GetCVars()->e_PreloadMaterials) - { - // Preload materials. - GetMatMan()->PreloadLevelMaterials(); - } - if (GetCVars()->e_PreloadDecals) - { - // Preload materials. - GetMatMan()->PreloadDecalMaterials(); - } - - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_OBJECTS); - // preload level cgfs - if (GetCVars()->e_StatObjPreload && !gEnv->IsEditor()) - { - m_pObjManager->PreloadLevelObjects(); - } - - if (!usePrefabSystemForLevels) - { - LoadCollisionClasses(xmlLevelData->findChild("CollisionClasses")); - } - - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_STATIC_WORLD); - - if (usePrefabSystemForLevels) - { - // When using the prefab system, just initialize a default manager instead of loading values from the indoor.dat file. - m_pVisAreaManager = new CVisAreaManager(); - } - else - { -#if defined(FEATURE_SVO_GI) - if (gEnv->pConsole->GetCVar("e_GI")->GetIVal()) - { - // Load SVOGI settings - char szFileName[256]; - azsprintf(szFileName, "mission_%s.xml", szMissionName); - XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName)); - if (xmlMission) - { - LoadTISettings(xmlMission->findChild("Environment")); - } - } -#endif - - // load indoors - std::vector* pStatObjTable = NULL; - std::vector<_smart_ptr>* pMatTable = NULL; - - if (!LoadVisAreas(&pStatObjTable, &pMatTable)) - { - Error("VisAreas file (%s) not found or file version error, please try to re-export the level", COMPILED_VISAREA_MAP_FILE_NAME); - return false; - } - - SAFE_DELETE(pStatObjTable); - SAFE_DELETE(pMatTable); - } - - - //Update loading screen and important tick functions - SYNCHRONOUS_LOADING_TICK(); - - PrintMessage("===== Loading mission settings from XML ====="); - - //Update loading screen and important tick functions - SYNCHRONOUS_LOADING_TICK(); - - // load leveldata.xml - m_pTerrainWaterMat = 0; - m_nWaterBottomTexId = 0; - - // This call is needed whether or not the prefab system is used for levels. If prefabs are used, it will initialize the - // environment and time of day managers with default values. With legacy levels, they will intialize from the saved xml files. - LoadMissionDataFromXMLNode(szMissionName); - - //Update loading screen and important tick functions - SYNCHRONOUS_LOADING_TICK(); - - if (!usePrefabSystemForLevels) - { - // init water if not initialized already (if no mission was found) - if (!GetOcean()) - { - PrintMessage("===== Creating Ocean ====="); - CreateOcean(m_pTerrainWaterMat, COcean::GetWaterLevelInfo()); - } - - PrintMessage("===== Load level physics data ====="); - LoadFlaresData(); - } - - // restore game state - EnableOceanRendering(true); - m_pObjManager->SetLockCGFResources(false); - - if (!usePrefabSystemForLevels) - { - PrintMessage("===== loading occlusion mesh ====="); - - GetObjManager()->LoadOcclusionMesh(szFolderName); - } - - PrintMessage("===== Finished loading static world ====="); - - m_skipedLayers.clear(); - - if (gEnv->pMaterialEffects) - { - gEnv->pMaterialEffects->CompleteInit(); - } - - return (true); -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::LoadCollisionClasses(XmlNodeRef node) -{ - m_collisionClasses.clear(); - if (node) - { - int count = node->getChildCount(); - m_collisionClasses.reserve(count); - for (int i = 0; i < count; i++) - { - SCollisionClass cc(0, 0); - XmlNodeRef xmlCC = node->getChild(i); - xmlCC->getAttr("type", cc.type); - xmlCC->getAttr("ignore", cc.ignore); - m_collisionClasses.push_back(cc); - } - } -} - -void C3DEngine::LoadMissionDataFromXMLNode(const char* szMissionName) -{ - LOADING_TIME_PROFILE_SECTION; - - GetRenderer()->MakeMainContextActive(); - - // set default values - m_vFogColor(1, 1, 1); - m_fMaxViewDistHighSpec = 8000; - m_fMaxViewDistLowSpec = 1000; - m_vDefFogColor = m_vFogColor; - - // mission environment - if (szMissionName && szMissionName[0]) - { - char szFileName[256]; - sprintf_s(szFileName, "mission_%s.xml", szMissionName); - XmlNodeRef xmlMission = GetSystem()->LoadXmlFromFile(Get3DEngine()->GetLevelFilePath(szFileName)); - if (xmlMission) - { - LoadEnvironmentSettingsFromXML(xmlMission->findChild("Environment"), GetDefSID()); - LoadTimeOfDaySettingsFromXML(xmlMission->findChild("TimeOfDay")); - } - else - { - // XML file couldn't be found, just use the defaults for everything. - LoadEnvironmentSettingsFromXML(nullptr, GetDefSID()); - LoadTimeOfDaySettingsFromXML(nullptr); - } - } - else - { - Error("C3DEngine::LoadMissionDataFromXMLNode: Mission name is not defined"); - } -} - -char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szDefaultValue) -{ - static char szResText[128]; - - cry_strcpy(szResText, szDefaultValue); - - if (pInputNode) - { - XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1); - if (nodeLevel && nodeLevel->haveAttr(szLevel2)) - { - cry_strcpy(szResText, nodeLevel->getAttr(szLevel2)); - } - } - - return szResText; -} - -char* C3DEngine::GetXMLAttribText(XmlNodeRef pInputNode, const char* szLevel1, const char* szLevel2, const char* szLevel3, const char* szDefaultValue) -{ - static char szResText[128]; - - cry_strcpy(szResText, szDefaultValue); - - if (pInputNode) - { - XmlNodeRef nodeLevel = pInputNode->findChild(szLevel1); - if (nodeLevel) - { - nodeLevel = nodeLevel->findChild(szLevel2); - if (nodeLevel) - { - cry_strcpy(szResText, nodeLevel->getAttr(szLevel3)); - } - } - } - - return szResText; -} - -void C3DEngine::UpdateMoonDirection() -{ - float moonLati(-gf_PI + gf_PI* m_moonRotationLatitude / 180.0f); - float moonLong(0.5f * gf_PI - gf_PI* m_moonRotationLongitude / 180.0f); - - float sinLon(sinf(moonLong)); - float cosLon(cosf(moonLong)); - float sinLat(sinf(moonLati)); - float cosLat(cosf(moonLati)); - - m_moonDirection = Vec3(sinLon * cosLat, sinLon * sinLat, cosLon); -} - -void C3DEngine::LoadEnvironmentSettingsFromXML(XmlNodeRef pInputNode, [[maybe_unused]] int nSID) -{ - PrintComment("Loading environment settings from XML ..."); - - // set start and end time for dawn/dusk (to fade moon/sun light in and out) - float dawnTime = (float)atof(GetXMLAttribText(pInputNode, "Lighting", "DawnTime", "355")); - float dawnDuration = (float)atof(GetXMLAttribText(pInputNode, "Lighting", "DawnDuration", "10")); - float duskTime = (float)atof(GetXMLAttribText(pInputNode, "Lighting", "DuskTime", "365")); - float duskDuration = (float)atof(GetXMLAttribText(pInputNode, "Lighting", "DuskDuration", "10")); - - m_dawnStart = (dawnTime - dawnDuration * 0.5f) / 60.0f; - m_dawnEnd = (dawnTime + dawnDuration * 0.5f) / 60.0f; - m_duskStart = 12.0f + (duskTime - duskDuration * 0.5f) / 60.0f; - m_duskEnd = 12.0f + (duskTime + duskDuration * 0.5f) / 60.0f; - - if (m_dawnEnd > m_duskStart) - { - m_duskEnd += m_dawnEnd - m_duskStart; - m_duskStart = m_dawnEnd; - } - - - // get moon info - m_moonRotationLatitude = (float)atof(GetXMLAttribText(pInputNode, "Moon", "Latitude", "240")); - m_moonRotationLongitude = (float)atof(GetXMLAttribText(pInputNode, "Moon", "Longitude", "45")); - UpdateMoonDirection(); - - m_nightMoonSize = (float)atof(GetXMLAttribText(pInputNode, "Moon", "Size", "0.5")); - - { - char moonTexture[256]; - cry_strcpy(moonTexture, GetXMLAttribText(pInputNode, "Moon", "Texture", "Textures/Skys/Night/half_moon.dds")); - - ITexture* pTex(0); - if (moonTexture[0] != '\0') - { - pTex = GetRenderer()->EF_LoadTexture(moonTexture, FT_DONT_STREAM); - } - - m_nNightMoonTexId = pTex ? pTex->GetTextureID() : 0; - } - - // max view distance - m_fMaxViewDistHighSpec = (float)atol(GetXMLAttribText(pInputNode, "Fog", "ViewDistance", "8000")); - m_fMaxViewDistLowSpec = (float)atol(GetXMLAttribText(pInputNode, "Fog", "ViewDistanceLowSpec", "1000")); - m_fMaxViewDistScale = 1.f; - - m_volFogGlobalDensityMultiplierLDR = (float)max(atof(GetXMLAttribText(pInputNode, "Fog", "LDRGlobalDensMult", "1.0")), 0.0); - - // SkyBox - const string skyMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "Material", "EngineAssets/Materials/Sky/Sky"); - const string skyLowSpecMaterialName = GetXMLAttribText(pInputNode, "SkyBox", "MaterialLowSpec", "EngineAssets/Materials/Sky/Sky"); - SetSkyMaterialPath(skyMaterialName); - SetSkyLowSpecMaterialPath(skyLowSpecMaterialName); - LoadSkyMaterial(); - - m_fSkyBoxAngle = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Angle", "0.0")); - m_fSkyBoxStretching = (float)atof(GetXMLAttribText(pInputNode, "SkyBox", "Stretching", "0.5")); - - // set terrain water (aka the infinite ocean), sun road and bottom shaders - if (OceanToggle::IsActive()) - { - AZStd::string szOceanMatName = OceanRequest::GetOceanMaterialName(); - m_pTerrainWaterMat = GetMatMan()->LoadMaterial(szOceanMatName.c_str(), false); - } - else - { - char szTerrainWaterMatName[256]; - cry_strcpy(szTerrainWaterMatName, GetXMLAttribText(pInputNode, "Ocean", "Material", "EngineAssets/Materials/Water/Ocean_default")); - m_pTerrainWaterMat = szTerrainWaterMatName[0] ? GetMatMan()->LoadMaterial(szTerrainWaterMatName, false) : nullptr; - } - CreateOcean(m_pTerrainWaterMat, COcean::GetWaterLevelInfo()); - - m_oceanWindDirection = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WindDirection", "1.0")); - m_oceanWindSpeed = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WindSpeed", "4.0")); - m_oceanWavesSpeed = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesSpeed", "1.0")); - m_oceanWavesAmount = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesAmount", "1.5")); - m_oceanWavesSize = (float) atof(GetXMLAttribText(pInputNode, "OceanAnimation", "WavesSize", "0.75")); - - // re-scale speed based on size - the smaller the faster waves move - m_oceanWavesSpeed /= m_oceanWavesSize; - - m_oceanCausticsDistanceAtten = (float)atof(GetXMLAttribText(pInputNode, "Ocean", "CausticsDistanceAtten", "100.0")); - m_oceanCausticsTiling = (float)atof(GetXMLAttribText(pInputNode, "Ocean", "CausticsTilling", "1.0")); - m_oceanCausticDepth = (float)atof(GetXMLAttribText(pInputNode, "Ocean", "CausticDepth", "8.0")); - m_oceanCausticIntensity = (float)atof(GetXMLAttribText(pInputNode, "Ocean", "CausticIntensity", "1.0")); - - // update relevant time of day settings - ITimeOfDay* pTimeOfDay(GetTimeOfDay()); - if (pTimeOfDay) - { - CTimeOfDay::SEnvironmentInfo envTODInfo; - { - const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunLinkedToTOD", "true"); - envTODInfo.bSunLinkedToTOD = !strcmp(pText, "true") || !strcmp(pText, "1"); - } - // get rotation of sun around z axis (needed to define an arbitrary path over zenit for day/night cycle position calculations) - envTODInfo.sunRotationLatitude = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "SunRotation", "240")); - envTODInfo.sunRotationLongitude = (float) atof(GetXMLAttribText(pInputNode, "Lighting", "Longitude", "90")); - - pTimeOfDay->SetEnvironmentSettings(envTODInfo); - pTimeOfDay->Update(true, true); - } - - { - const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunShadowsMinSpec", "1"); - int nMinSpec = atoi(pText); - if (nMinSpec > 0 && CheckMinSpec(nMinSpec)) - { - m_bSunShadows = true; - } - else - { - m_bSunShadows = false; - } - } - - { - const char* pText = GetXMLAttribText(pInputNode, "EnvState", "SunShadowsAdditionalCascadeMinSpec", "0"); - int nMinSpec = atoi(pText); - if (nMinSpec > 0 && CheckMinSpec(nMinSpec)) - { - m_nSunAdditionalCascades = 1; - } - else - { - m_nSunAdditionalCascades = 0; - } - } - - { - m_nGsmCache = m_pConsole->GetCVar("r_ShadowsCache")->GetIVal(); - } - - { - const char* pText = GetXMLAttribText(pInputNode, "Terrain", "HeightMapAO", "false"); - m_bHeightMapAoEnabled = !strcmp(pText, "true") || !strcmp(pText, "1"); - } - - { - int nMinSpec = 3;//atoi(pText); - m_fSunClipPlaneRange = 256.0; - m_fSunClipPlaneRangeShift = 0.0f; - - if (nMinSpec > 0 && CheckMinSpec(nMinSpec)) - { - m_fSunClipPlaneRange = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "SunShadowsClipPlaneRange", "256.0")); - - float fSunClipPlaneRangeShift = (float)atof(GetXMLAttribText(pInputNode, "EnvState", "SunShadowsClipPlaneRangeShift", "0.0")); - m_fSunClipPlaneRangeShift = clamp_tpl(fSunClipPlaneRangeShift / 100.0f, 0.0f, 1.0f); - } - } - - { - const char* pText = GetXMLAttribText(pInputNode, "EnvState", "UseLayersActivation", "false"); - Get3DEngine()->m_bAreaActivationInUse = !strcmp(pText, "true") || !strcmp(pText, "1"); - } - - // load cloud shadow parameters - { - char cloudShadowTexture[256]; - cry_strcpy(cloudShadowTexture, GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowTexture", "")); - - ITexture* pTex = 0; - if (cloudShadowTexture[0] != '\0') - { - pTex = GetRenderer()->EF_LoadTexture(cloudShadowTexture, FT_DONT_STREAM); - } - - m_nCloudShadowTexId = pTex ? pTex->GetTextureID() : 0; - - // Get animation parameters - const Vec3 cloudShadowSpeed = StringToVector(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowSpeed", "0,0,0")); - - const float cloudShadowTiling = (float)atof(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowTiling", "1.0")); - const float cloudShadowBrightness = (float)atof(GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowBrightness", "1.0")); - - const char* pText = GetXMLAttribText(pInputNode, "CloudShadows", "CloudShadowInvert", "false"); - const bool cloudShadowInvert = !strcmp(pText, "true") || !strcmp(pText, "1"); - - GetRenderer()->SetCloudShadowsParams(m_nCloudShadowTexId, cloudShadowSpeed, cloudShadowTiling, cloudShadowInvert, cloudShadowBrightness); - } - - // Particle lighting params. Remove for projects post C3, should be no particle lighting multipliers - have assets tweaked from start - { - m_fParticlesAmbientMultiplier = (float)atof(GetXMLAttribText(pInputNode, "ParticleLighting", "AmbientMul", "1.0")); - m_fParticlesLightMultiplier = (float)atof(GetXMLAttribText(pInputNode, "ParticleLighting", "LightsMul", "1.0")); - } - - { - const char* pText = GetXMLAttribText(pInputNode, "VolFogShadows", "Enable", "false"); - const bool enable = !strcmp(pText, "true") || !strcmp(pText, "1"); - - pText = GetXMLAttribText(pInputNode, "VolFogShadows", "EnableForClouds", "false"); - const bool enableForClouds = !strcmp(pText, "true") || !strcmp(pText, "1"); - - SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_ENABLE, Vec3(enable ? 1.0f : 0.0f, enableForClouds ? 1.0f : 0.0f, 0.0f)); - } - -#if defined(FEATURE_SVO_GI) - if (gEnv->pConsole->GetCVar("e_GI")->GetIVal()) - { - LoadTISettings(pInputNode); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -void C3DEngine::LoadTimeOfDaySettingsFromXML(XmlNodeRef node) -{ - if (node) - { - GetTimeOfDay()->Serialize(node, true); - ITimeOfDay::SAdvancedInfo info; - GetTimeOfDay()->GetAdvancedInfo(info); - GetTimeOfDay()->SetTime(info.fStartTime, true); - } -} - -//! create static object containing empty IndexedMesh -IStatObj* C3DEngine::CreateStatObj() -{ - CStatObj* pStatObj = new CStatObj(); - pStatObj->m_pIndexedMesh = new CIndexedMesh(); - return pStatObj; -} - -IStatObj* C3DEngine::CreateStatObjOptionalIndexedMesh(bool createIndexedMesh) -{ - CStatObj* pStatObj = new CStatObj(); - if (createIndexedMesh) - { - pStatObj->m_pIndexedMesh = new CIndexedMesh(); - } - return pStatObj; -} - -bool C3DEngine::RestoreTerrainFromDisk([[maybe_unused]] int nSID) -{ - ResetParticlesAndDecals(); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool C3DEngine::LoadUsedShadersList() -{ - LOADING_TIME_PROFILE_SECTION; - gEnv->pRenderer->EF_Query(EFQ_SetShaderCombinations); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool C3DEngine::PrecreateDecals() -{ - LOADING_TIME_PROFILE_SECTION; - - CObjManager::DecalsToPrecreate& decals(GetObjManager()->GetDecalsToPrecreate()); - // pre-create ... - if (GetCVars()->e_DecalsPreCreate) - { - CryLog("Pre-creating %d decals...", (int)decals.size()); - - CObjManager::DecalsToPrecreate::iterator it(decals.begin()); - CObjManager::DecalsToPrecreate::iterator itEnd(decals.end()); - for (; it != itEnd; ++it) - { - IDecalRenderNode* pDecalRenderNode(*it); - pDecalRenderNode->Precache(); - } - - CryLog(" done.\n"); - } - else - { - CryLog("Skipped pre-creation of decals.\n"); - } - - // ... and discard list (even if pre-creation was skipped!) - decals.resize(0); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -// Called by game when everything needed for level is loaded. -////////////////////////////////////////////////////////////////////////// -void C3DEngine::PostLoadLevel() -{ - LOADING_TIME_PROFILE_SECTION; - - CRY_ASSERT(m_levelLoaded == false); - - ////////////////////////////////////////////////////////////////////////// - // Submit water material to physics if the ocean exists - ////////////////////////////////////////////////////////////////////////// - - - if (GetCVars()->e_PrecacheLevel) - { - // pre-create decals - PrecreateDecals(); - } - - gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_TEXTURES); - - GetRenderer()->PostLevelLoading(); - - // refresh material constants pulled in from resources (such as textures) - GetMatMan()->RefreshShaderResourceConstants(); - - if (m_nGsmCache > 0) - { - m_CachedShadowsBounds.Reset(); - SetRecomputeCachedShadows(m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate); - } - m_levelLoaded = true; -} - - -int C3DEngine::SaveStatObj(IStatObj* pStatObj, TSerialize ser) -{ - if (!(pStatObj->GetFlags() & STATIC_OBJECT_GENERATED)) - { - bool bVal = false; - ser.Value("altered", bVal); - ser.Value("file", pStatObj->GetFilePath()); - ser.Value("geom", pStatObj->GetGeoName()); - } - else - { - bool bVal = true; - ser.Value("altered", bVal); - ser.Value("CloneSource", pStatObj->GetCloneSourceObject() ? pStatObj->GetCloneSourceObject()->GetFilePath() : "0"); - pStatObj->Serialize(ser); - } - - return 1; -} - -IStatObj* C3DEngine::LoadStatObj(TSerialize ser) -{ - bool bVal; - IStatObj* pStatObj; - ser.Value("altered", bVal); - if (!bVal) - { - string fileName, geomName; - ser.Value("file", fileName); - ser.Value("geom", geomName); - pStatObj = LoadStatObjUnsafeManualRef(fileName, geomName); - } - else - { - string srcObjName; - ser.Value("CloneSource", srcObjName); - if (*(const unsigned short*)(const char*)srcObjName != '0') - { - pStatObj = LoadStatObjUnsafeManualRef(srcObjName)->Clone(false, false, true); - } - else - { - pStatObj = CreateStatObj(); - } - pStatObj->Serialize(ser); - } - return pStatObj; -} - - - - diff --git a/Code/CryEngine/Cry3DEngine/3dEngineOctreeCompile.cpp b/Code/CryEngine/Cry3DEngine/3dEngineOctreeCompile.cpp deleted file mode 100644 index 7983dda0c9..0000000000 --- a/Code/CryEngine/Cry3DEngine/3dEngineOctreeCompile.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" -#include "Ocean.h" -#include "StatObj.h" -#include "ObjMan.h" -#include "MatMan.h" -#include "VisAreas.h" -#include "ObjectsTree.h" - -#include -#include -#include -#include -#include -#include - - -#define SIGC_HIDEABILITY BIT(3) -#define SIGC_HIDEABILITYSECONDARY BIT(4) -#define SIGC_PROCEDURALLYANIMATED BIT(6) -#define SIGC_CASTSHADOW BIT(7) // Deprecated -#define SIGC_RECVSHADOW BIT(8) -#define SIGC_DYNAMICDISTANCESHADOWS BIT(9) -#define SIGC_USEALPHABLENDING BIT(10) -#define SIGC_RANDOMROTATION BIT(12) -#define SIGC_ALLOWINDOOR BIT(13) - -// Bits 13-14 reserved for player hideability -#define SIGC_PLAYERHIDEABLE_LOWBIT (13) -#define SIGC_PLAYERHIDEABLE_MASK BIT(13) | BIT(14) - -#define SIGC_CASTSHADOW_MINSPEC_SHIFT (15) - -// Get the number of bits needed for the maximum spec level -#define SIGC_CASTSHADOW_MINSPEC_MASK_NUM_BITS_NEEDED (IntegerLog2(uint32(END_CONFIG_SPEC_ENUM - 1)) + 1) - -// Create a mask based on the number of bits needed -#define SIGC_CASTSHADOW_MINSPEC_MASK_BITS ((1 << SIGC_CASTSHADOW_MINSPEC_MASK_NUM_BITS_NEEDED) - 1) -#define SIGC_CASTSHADOW_MINSPEC_MASK (SIGC_CASTSHADOW_MINSPEC_MASK_BITS << SIGC_CASTSHADOW_MINSPEC_SHIFT) - -AZ_CVAR(float, bg_DefaultMaxOctreeWorldSize, 4096.0f, nullptr, AZ::ConsoleFunctorFlags::NeedsReload, "Default world size to use for the octree when terrain is not present."); - -bool C3DEngine::CreateOctree(float maxRootOctreeNodeSize) -{ - float rootOctreeNodeSize = (maxRootOctreeNodeSize > 0.0f) ? maxRootOctreeNodeSize : bg_DefaultMaxOctreeWorldSize; - COctreeNode* newOctreeNode = COctreeNode::Create(DEFAULT_SID, AABB(Vec3(0), Vec3(rootOctreeNodeSize)), NULL); - if (!newOctreeNode) - { - Error("Failed to create octree with initial world size=%f", rootOctreeNodeSize); - return false; - } - SetObjectTree(newOctreeNode); - Cry3DEngineBase::GetObjManager()->GetListStaticTypes().PreAllocate(1, 1); - Cry3DEngineBase::GetObjManager()->GetListStaticTypes()[DEFAULT_SID].Reset(); - return true; -} - - -void C3DEngine::DestroyOctree() -{ - COctreeNode* objectTree = GetObjectTree(); - if (objectTree) - { - delete objectTree; - SetObjectTree(nullptr); - } -} - -#define RAD2BYTE(x) ((x)*255.0f / float(g_PI2)) -#define BYTE2RAD(x) ((x)* float(g_PI2) / 255.0f) - -#include "TypeInfo_impl.h" - diff --git a/Code/CryEngine/Cry3DEngine/BasicArea.cpp b/Code/CryEngine/Cry3DEngine/BasicArea.cpp deleted file mode 100644 index 0af2e5cd7e..0000000000 --- a/Code/CryEngine/Cry3DEngine/BasicArea.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : objects container, streaming, common part for indoor and outdoor sectors - - -#include "Cry3DEngine_precompiled.h" - -CBasicArea::~CBasicArea() -{ - delete m_pObjectsTree; - m_pObjectsTree = NULL; -} diff --git a/Code/CryEngine/Cry3DEngine/BasicArea.h b/Code/CryEngine/Cry3DEngine/BasicArea.h deleted file mode 100644 index d29b605863..0000000000 --- a/Code/CryEngine/Cry3DEngine/BasicArea.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_BASICAREA_H -#define CRYINCLUDE_CRY3DENGINE_BASICAREA_H -#pragma once - -#define COPY_MEMBER_SAVE(_dst, _src, _name) { (_dst)->_name = (_src)->_name; } -#define COPY_MEMBER_LOAD(_dst, _src, _name) { (_dst)->_name = (_src)->_name; } - -enum EObjList -{ - DYNAMIC_OBJECTS = 0, - STATIC_OBJECTS, - PROC_OBJECTS, - ENTITY_LISTS_NUM -}; - -struct SRNInfo -{ - SRNInfo() - { - memset(this, 0, sizeof(*this)); - } - - SRNInfo(IRenderNode* _pNode) - { - fMaxViewDist = _pNode->m_fWSMaxViewDist; - AABB aabbBox = _pNode->GetBBox(); - objSphere.center = aabbBox.GetCenter(); - objSphere.radius = aabbBox.GetRadius(); - pNode = _pNode; - nRType = _pNode->GetRenderNodeType(); - - /*#ifdef _DEBUG - erType = _pNode->GetRenderNodeType(); - cry_strcpy(szName, _pNode->GetName()); - #endif*/ - } - - bool operator == (const IRenderNode* _pNode) const { return (pNode == _pNode); } - bool operator == (const SRNInfo& rOther) const { return (pNode == rOther.pNode); } - - float fMaxViewDist; - Sphere objSphere; - IRenderNode* pNode; - EERType nRType; - /*#ifdef _DEBUG - EERType erType; - char szName[32]; - #endif*/ -}; - -struct SCasterInfo -{ - SCasterInfo() - { - memset(this, 0, sizeof(*this)); - } - - SCasterInfo(IRenderNode* _pNode, float fMaxDist) - { - fMaxCastingDist = fMaxDist; - objBox = _pNode->GetBBox(); - objSphere.center = objBox.GetCenter(); - objSphere.radius = objBox.GetRadius(); - pNode = _pNode; - nRType = _pNode->GetRenderNodeType(); - nRenderNodeFlags = _pNode->GetRndFlags(); - bCanExecuteAsRenderJob = _pNode->CanExecuteRenderAsJob(); - } - - SCasterInfo(IRenderNode* _pNode, float fMaxDist, EERType renderNodeType) - { - fMaxCastingDist = fMaxDist; - _pNode->FillBBox(objBox); - objSphere.center = objBox.GetCenter(); - objSphere.radius = objBox.GetRadius(); - pNode = _pNode; - nRType = renderNodeType; - nRenderNodeFlags = _pNode->GetRndFlags(); - bCanExecuteAsRenderJob = _pNode->CanExecuteRenderAsJob(); - } - - bool operator == (const IRenderNode* _pNode) const { return (pNode == _pNode); } - bool operator == (const SCasterInfo& rOther) const { return (pNode == rOther.pNode); } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*nothing*/} - - float fMaxCastingDist; - Sphere objSphere; - AABB objBox; - IRenderNode* pNode; - uint32 nGSMFrameId; - EERType nRType; - bool bCanExecuteAsRenderJob; - uint32 nRenderNodeFlags; -}; - -#define UPDATE_PTR_AND_SIZE(_pData, _nDataSize, _SIZE_PLUS) \ - { \ - _pData += (_SIZE_PLUS); \ - _nDataSize -= (_SIZE_PLUS); \ - assert(_nDataSize >= 0); \ - } \ - -enum EAreaType -{ - eAreaType_Undefined, - eAreaType_OcNode, - eAreaType_VisArea -}; - -struct CBasicArea - : public Cry3DEngineBase -{ - CBasicArea() - { - m_boxArea.min = m_boxArea.max = Vec3(0, 0, 0); - m_pObjectsTree = NULL; - } - - ~CBasicArea(); - - void CompileObjects(int nListId); // optimize objects lists for rendering - - class COctreeNode* m_pObjectsTree; - - AABB m_boxArea; // bbox containing everything in sector including child sectors - AABB m_boxStatics; // bbox containing only objects in STATIC_OBJECTS list of this node and height-map -}; - -#endif // CRYINCLUDE_CRY3DENGINE_BASICAREA_H diff --git a/Code/CryEngine/Cry3DEngine/CCullRenderer.cpp b/Code/CryEngine/Cry3DEngine/CCullRenderer.cpp deleted file mode 100644 index b2de025ccb..0000000000 --- a/Code/CryEngine/Cry3DEngine/CCullRenderer.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "CCullRenderer.h" - -namespace NAsyncCull -{ -} diff --git a/Code/CryEngine/Cry3DEngine/CCullRenderer.h b/Code/CryEngine/Cry3DEngine/CCullRenderer.h deleted file mode 100644 index a1dcdbcd6e..0000000000 --- a/Code/CryEngine/Cry3DEngine/CCullRenderer.h +++ /dev/null @@ -1,1566 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "VMath.hpp" -#include - -//#define CULL_RENDERER_REPROJ_DEBUG -#define CULL_RENDERER_MINZ - -// enable this define to allow ingame debugging of the coverage buffer -#define CULLING_ENABLE_DEBUG_OVERLAY - -extern SHWOccZBuffer HWZBuffer; - - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(CCullRenderer_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(WIN64) -#define CULLINLINE inline -#define CULLNOINLINE inline -#else - #define CULLINLINE ILINE - #define CULLNOINLINE inline -#endif - -namespace NAsyncCull { - namespace Debug { - inline void Draw2DBox(float fX, float fY, float fHeight, float fWidth, const ColorB& rColor, float fScreenHeight, float fScreenWidth, IRenderAuxGeom* pAuxRenderer) - { - float fPosition[4][2] = { - { fX, fY }, - { fX, fY + fHeight }, - { fX + fWidth, fY + fHeight }, - { fX + fWidth, fY} - }; - - // compute normalized position from absolute points - Vec3 vPosition[4] = { - Vec3(fPosition[0][0] / fScreenWidth, fPosition[0][1] / fScreenHeight, 0.0f), - Vec3(fPosition[1][0] / fScreenWidth, fPosition[1][1] / fScreenHeight, 0.0f), - Vec3(fPosition[2][0] / fScreenWidth, fPosition[2][1] / fScreenHeight, 0.0f), - Vec3(fPosition[3][0] / fScreenWidth, fPosition[3][1] / fScreenHeight, 0.0f) - }; - - vtx_idx const anTriangleIndices[6] = { - 0, 1, 2, - 0, 2, 3 - }; - - pAuxRenderer->DrawTriangles(vPosition, 4, anTriangleIndices, 6, rColor); - } - } // namesapce Debug -} //namespace NasyncCull - -namespace NAsyncCull -{ - typedef float tdZexel; - typedef uint16 tdIndex; - - typedef PodArray& tdVertexCacheArg; - typedef PodArray tdVertexCache; - - enum - { - VERTEX_CACHE_COUNT = 64 * 1024 - }; - - extern const NVMath::vec4 MaskNot3; - - template - class CCullRenderer - { - public: - enum - { - RESOLUTION_X = SIZEX - }; - enum - { - RESOLUTION_Y = SIZEY - }; - private: - - NVMath::vec4 m_VMaxXY _ALIGN(16); - static float m_ZBufferMainMemory[SIZEX * SIZEY] _ALIGN(128); - uint32 m_SizeX4; - _MS_ALIGN(16) float m_Reproject[16] _ALIGN(16); - uint32 m_nNumWorker; - tdZexel* m_ZBuffer; - - tdZexel** m_ZBufferSwap; - - DEFINE_ALIGNED_DATA(tdZexel, m_ZBufferSwapMerged[SIZEX * SIZEY], 128); // 128 byte for XMemSet128 - -#ifdef CULL_RENDERER_REPROJ_DEBUG - tdZexel m_ZBufferOrig[SIZEX * SIZEY]; -#endif - - uint32 m_DrawCall; - uint32 m_PolyCount; - - template - CULLINLINE bool Triangle(const NVMath::vec4& rV0, - const NVMath::vec4& rV1, - const NVMath::vec4& rV2) - { - using namespace NVMath; - vec4 V0 = rV0; - vec4 V1 = rV1; - vec4 V2 = rV2; - - const uint32 Idx = SignMask(Shuffle(Shuffle(V0, V1), V2)) & (BitX | BitY | BitZ); - if (Idx == (BitX | BitY | BitZ)) - { - return false; - } - - bool Visible = false; - - switch (Idx) - { - case 0: - break; - case BitX: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F0, Sub(F0, F2)); - const vec4 M1 = Div(F0, Sub(F0, F1)); - const vec4 P0 = Madd(Sub(V2, V0), M0, V0); - const vec4 P1 = Madd(Sub(V1, V0), M1, V0); - Visible = Triangle2D(P0, P1, V1); - V0 = P0; - } - break; - case BitY: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F1, Sub(F1, F0)); - const vec4 M1 = Div(F1, Sub(F1, F2)); - const vec4 P0 = Madd(Sub(V0, V1), M0, V1); - const vec4 P1 = Madd(Sub(V2, V1), M1, V1); - Visible = Triangle2D(P0, P1, V2); - V1 = P0; - } - break; - case BitX | BitY: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F0, Sub(F0, F2)); - const vec4 M1 = Div(F1, Sub(F1, F2)); - V0 = Madd(Sub(V2, V0), M0, V0); - V1 = Madd(Sub(V2, V1), M1, V1); - } - break; - case BitZ: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F2, Sub(F2, F1)); - const vec4 M1 = Div(F2, Sub(F2, F0)); - const vec4 P0 = Madd(Sub(V1, V2), M0, V2); - const vec4 P1 = Madd(Sub(V0, V2), M1, V2); - Visible = Triangle2D(V0, P0, P1); - V2 = P0; - } - break; - case BitX | BitZ: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F0, Sub(F0, F1)); - const vec4 M1 = Div(F2, Sub(F2, F1)); - V0 = Madd(Sub(V1, V0), M0, V0); - V2 = Madd(Sub(V1, V2), M1, V2); - } - break; - case BitY | BitZ: - { - const vec4 F0 = Splat<2>(V0); - const vec4 F1 = Splat<2>(V1); - const vec4 F2 = Splat<2>(V2); - const vec4 M0 = Div(F1, Sub(F1, F0)); - const vec4 M1 = Div(F2, Sub(F2, F0)); - V1 = Madd(Sub(V0, V1), M0, V1); - V2 = Madd(Sub(V0, V2), M1, V2); - } - break; - case BitX | BitY | BitZ: - break; -#if AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE - default: - __assume(0); -#endif - } - return Visible | Triangle2D(V0, V1, V2); - } - - - template -#if AZ_TRAIT_COMPILER_PASS_4PLUS_VECTOR_PARAMETERS_BY_VALUE - CULLINLINE bool Triangle2D(NVMath::vec4 rV0, NVMath::vec4 rV1, NVMath::vec4 rV2, uint32 MinX = 0, uint32 MinY = 0, uint32 MaxX = 0, uint32 MaxY = 0, NVMath::vec4 VMinMax = NVMath::Vec4Zero(), NVMath::vec4 V210 = NVMath::Vec4Zero()) -#else - CULLINLINE bool Triangle2D(NVMath::vec4 rV0, NVMath::vec4 rV1, NVMath::vec4 rV2, uint32 MinX = 0, uint32 MinY = 0, uint32 MaxX = 0, uint32 MaxY = 0, NVMath::vec4& VMinMax = NVMath::Vec4Zero(), NVMath::vec4& V210 = NVMath::Vec4Zero()) -#endif - { - using namespace NVMath; - - vec4 V0, V1, V2; - if (PROJECT) - { - const vec4 WWW = Shuffle(Shuffle(rV0, rV1), rV2); - const vec4 iWWW = Rcp(WWW); - V0 = Mul(rV0, Splat<0>(iWWW)); - V1 = Mul(rV1, Splat<1>(iWWW)); - V2 = Mul(rV2, Splat<2>(iWWW)); - V210 = Sub(Shuffle(V1, V2), Swizzle(V0)); - vec4 Det = Mul(V210, Swizzle(V210)); - Det = Sub(Det, Splat<1>(Det)); - if (CULL_BACKFACES) - { - if ((SignMask(CmpLE(Det, Vec4Epsilon())) & BitX) != 0) - { - return false; - } - } - - Det = Select(Det, NVMath::Vec4(-FLT_EPSILON), CmpEq(Det, Vec4Zero())); - V210 = Div(V210, Swizzle(Det)); - - vec4 VMax = Max(Max(V0, V1), V2); - vec4 VMin = Min(Min(V0, V1), V2); - VMax = Add(VMax, Vec4One()); - VMinMax = Shuffle(VMin, VMax); - VMinMax = Max(VMinMax, Vec4Zero()); - VMinMax = Min(VMinMax, m_VMaxXY); - VMinMax = floatToint32(VMinMax); - const uint32* pMM = reinterpret_cast(&VMinMax); - MinX = pMM[0]; - MinY = pMM[1]; - MaxX = pMM[2]; - MaxY = pMM[3]; - if (MinX >= MaxX || MinY >= MaxY) - { - return false; - } - } - else - { - V0 = rV0; - V1 = rV1; - V2 = rV2; - } - - - MinX &= ~3; - - VMinMax = And(VMinMax, MaskNot3); - -#ifdef CULL_RENDERER_MINZ - const vec4 VMinZ = Splat<2>(Min(Min(rV0, rV1), rV2)); -#endif - const vec4 V0z = Splat<2>(rV0); - const vec4 Z10 = Sub(Splat<2>(rV1), V0z); - const vec4 Z20 = Sub(Splat<2>(rV2), V0z); - - const vec4 X20 = Splat<0>(V210); - const vec4 Y20 = Splat<1>(V210); - const vec4 X10 = Sub(Vec4Zero(), Splat<2>(V210)); - const vec4 Y10 = Splat<3>(V210); - - VMinMax = Sub(int32Tofloat(VMinMax), V0); - const vec4 dx4 = Add(Splat<0>(VMinMax), Vec4ZeroOneTwoThree()); - const vec4 Y1x = Mul(Y10, dx4); - const vec4 Y2x = Sub(Vec4Zero(), Mul(Y20, dx4)); - vec4 dy4 = Splat<1>(VMinMax); - const vec4 Y14 = Mul(Y10, Vec4Four()); - const vec4 Y24 = Sub(Vec4Zero(), Mul(Y20, Vec4Four())); - const vec4 Y34 = Add(Y14, Y24); - vec4 Visible = Vec4FFFFFFFF(); - uint16 y = MinY; - do - { - vec4 Px = Madd(X10, dy4, Y1x); - vec4 Py = Madd(X20, dy4, Y2x); - vec4 Pz = Sub(Sub(Vec4One(), Py), Px); - - vec4* pDstZ = reinterpret_cast(&m_ZBuffer[MinX + y * (uint16)SIZEX]); - y++; - uint16 x = MinX; - do - { - Prefetch(pDstZ); - x += 4; - vec4 Mask = Or(Or(Px, Py), Pz); - vec4 Z, rZ = *pDstZ; -#ifdef CULL_RENDERER_MINZ - if (!WRITE) //compile time - { - Mask = Or(Mask, CmpLE(rZ, VMinZ)); - } - else -#endif - { - Z = Madd(Z10, Px, Madd(Z20, Py, V0z)); - Mask = Or(Mask, CmpLE(rZ, Z)); - } - Px = Add(Px, Y14); - Py = Add(Py, Y24); - Pz = Sub(Pz, Y34); - if (CULL) //compile time - { - Visible = And(Visible, Mask); - } - if (WRITE) //compile time - { - *pDstZ = SelectSign(Z, rZ, Mask); - } - pDstZ++; - } while (x < MaxX); - if constexpr (!WRITE && CULL) - { - if ((SignMask(Visible) & (BitX | BitY | BitZ | BitW)) != (BitX | BitY | BitZ | BitW)) - { - return true; - } - } - dy4 = Add(dy4, Vec4One()); - } while (y < MaxY); - return CULL && (SignMask(Visible) & (BitX | BitY | BitZ | BitW)) != (BitX | BitY | BitZ | BitW); - } - - - CULLINLINE bool Quad2D(const NVMath::vec4& rV0, const NVMath::vec4& rV1, const NVMath::vec4& rV3, const NVMath::vec4& rV2) - { - using namespace NVMath; - const vec4 WWW = Shuffle(Shuffle(rV0, rV1), Shuffle(rV2, rV3)); - const vec4 iWWW = Rcp(WWW); - - vec4 V0 = Mul(rV0, Splat<0>(iWWW)); - vec4 V1 = Mul(rV1, Splat<1>(iWWW)); - vec4 V2 = Mul(rV2, Splat<2>(iWWW)); - vec4 V3 = Mul(rV3, Splat<3>(iWWW)); - - vec4 V210 = Sub(Shuffle(V1, V2), Swizzle(V0)); - vec4 V213 = Sub(Shuffle(V1, V2), Swizzle(V3)); - vec4 Det = Mul(V210, Swizzle(V210)); - Det = Sub(Det, Splat<1>(Det)); - - vec4 VMax = Max(Max(V0, V1), Max(V2, V3)); - vec4 VMin = Min(Min(V0, V1), Min(V2, V3)); - VMax = Add(VMax, Vec4One()); - //saturate to 0 - ScreenSize cause it's assigned to uin16 - VMin = Min(VMin, m_VMaxXY); - VMax = Min(VMax, m_VMaxXY); - - vec4 VMinMax = floatToint32(Max(Shuffle(VMin, VMax), Vec4Zero())); - uint16 MinX = Vec4int32(VMinMax, 0); - const uint16 MinY = Vec4int32(VMinMax, 1); - const uint16 MaxX = Vec4int32(VMinMax, 2); - const uint16 MaxY = Vec4int32(VMinMax, 3); - if (MinX >= MaxX || MinY >= MaxY) - { - return false; - } - MinX &= ~3; - - const vec4 VMinZ = Splat<2>(Min(Min(rV0, rV1), Min(rV2, rV3))); - Det = Rcp(Splat<0>(Det)); - V210 = Mul(V210, Det); - V213 = Mul(V213, Det); - const vec4 X20 = Splat<0>(V210); - const vec4 Y20 = Splat<1>(V210); - const vec4 X10 = Splat<2>(V210); - const vec4 Y10 = Splat<3>(V210); - const vec4 X23 = Splat<0>(V213); - const vec4 Y23 = Splat<1>(V213); - const vec4 X13 = Splat<2>(V213); - const vec4 Y13 = Splat<3>(V213); - - const vec4 dx4 = Sub(Add(NVMath::Vec4(static_cast(MinX)), Vec4ZeroOneTwoThree()), Splat<0>(V0)); - const vec4 Y10x = Mul(Y10, dx4); - const vec4 Y20x = Mul(Y20, dx4); - const vec4 Y13x = Mul(Y13, dx4); - const vec4 Y23x = Mul(Y23, dx4); - vec4 dy4 = Sub(NVMath::Vec4(static_cast(MinY)), Splat<1>(V0)); - const vec4 Y104 = Mul(Y10, Vec4Four()); - const vec4 Y204 = Mul(Y20, Vec4Four()); - const vec4 Y134 = Mul(Y13, Vec4Four()); - const vec4 Y234 = Mul(Y23, Vec4Four()); - const vec4 Y304 = Sub(Y104, Y204); - const vec4 Y334 = Sub(Y134, Y234); - vec4 Visible = Vec4FFFFFFFF(); - uint16 y = MinY; - do - { - vec4 P0x = Sub(Y10x, Mul(X10, dy4)); - vec4 P0y = Sub(Mul(X20, dy4), Y20x); - vec4 P3x = Sub(Y13x, Mul(X13, dy4)); - vec4 P3y = Sub(Mul(X23, dy4), Y23x); - uint16 x = MinX; - vec4* pDstZ = reinterpret_cast(&m_ZBuffer[MinX + y * (uint16)SIZEX]); - do - { - Prefetch(pDstZ); - vec4 Mask = Or(Or(P0x, P0y), Or(P3x, P3y)); - vec4 rZ = *pDstZ++; - Mask = Or(Mask, CmpLE(rZ, VMinZ)); - x += 4; - Visible = And(Visible, Mask); - P0x = Add(P0x, Y104); - P0y = Sub(P0y, Y204); - P3x = Add(P3x, Y134); - P3y = Sub(P3y, Y234); - } while (x < MaxX); - if (SignMask(Visible) != (BitX | BitY | BitZ | BitW)) - { - return true; - } - y++; - dy4 = Add(dy4, Vec4One()); - } while (y < MaxY); - return false; - } - - - void Show(); - public: - - CULLINLINE CCullRenderer() - { - m_ZBuffer = m_ZBufferMainMemory; - m_DebugRender = 0; - m_nNumWorker = 0; - m_ZBufferSwap = NULL; - } - - ~CCullRenderer() - { - for (uint32 i = 0; i < m_nNumWorker; ++i) - { - CryModuleMemalignFree(m_ZBufferSwap[i]); - } - delete[] m_ZBufferSwap; - } - - void Prepare() - { - if (m_nNumWorker) - { - return; - } - - m_nNumWorker = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads(); - m_ZBufferSwap = new tdZexel*[m_nNumWorker]; - for (uint32 i = 0; i < m_nNumWorker; ++i) - { - m_ZBufferSwap[i] = (tdZexel*)CryModuleMemalign(sizeof(tdZexel) * SIZEX * SIZEY, 128); - } - } - - CULLINLINE void Clear() - { - m_VMaxXY = NVMath::int32Tofloat(NVMath::Vec4(SIZEX, SIZEY, SIZEX, SIZEY)); - for (uint32 a = 0, S = SIZEX * SIZEY; a < S; a++) - { - m_ZBuffer[a] = 9999999999.f; - } - m_DrawCall = 0; - m_PolyCount = 0; - } - - bool DownLoadHWDepthBuffer([[maybe_unused]] float nearPlane, [[maybe_unused]] float farPlane, [[maybe_unused]] float nearestMax, [[maybe_unused]] float Bias) - { - Matrix44A& Reproject = *reinterpret_cast(&m_Reproject); - - m_VMaxXY = NVMath::int32Tofloat(NVMath::Vec4(SIZEX, SIZEY, SIZEX, SIZEY)); - - if (!gEnv->pRenderer->GetOcclusionBuffer((uint16*)&m_ZBuffer[0], reinterpret_cast(&Reproject))) - { - return false; - } - - for (uint32 i = 0; i < m_nNumWorker; ++i) - { - memset(m_ZBufferSwap[i], 0, SIZEX * SIZEY * sizeof(float)); - } - memset(m_ZBufferSwapMerged, 0, SIZEX * SIZEY * sizeof(float)); - - return true; - } - - void ReprojectHWDepthBuffer(const Matrix44A& rCurrent, float nearPlane, float farPlane, float nearestMax, [[maybe_unused]] float Bias, int nStartLine, int nNumLines) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - //#define USE_W_DEPTH - //#define SCALE_DEPTH - - const uint32 workerThreadID = AZ::JobContext::GetGlobalContext()->GetJobManager().GetWorkerThreadId(); - CRY_ASSERT(workerThreadID != AZ::JobManager::InvalidWorkerThreadId); - float* pZBufferSwap = m_ZBufferSwap[workerThreadID]; - - int sizeX = SIZEX; - int sizeY = SIZEY; - - float fWidth = (float) sizeX; - float fHeight = (float) sizeY; - - const float a = farPlane / (farPlane - nearPlane); - const float b = farPlane * nearPlane / (nearPlane - farPlane); - - Matrix44A fromScreen; - fromScreen.SetIdentity(); - fromScreen.SetTranslation(Vec3(-1.0f + 0.5f / fWidth, 1.0f - 0.5f / fHeight, 0.0f)); - fromScreen.m00 = 2.0f / fWidth; - fromScreen.m11 = -2.0f / fHeight; // Y flipped - fromScreen.Transpose(); - - Matrix44A Reproject = *reinterpret_cast(&m_Reproject); - Reproject.Invert(); - DEFINE_ALIGNED_DATA(Matrix44A, mToWorld, 16); - mToWorld = fromScreen * Reproject; - - { - int x, y; - float fY; - using namespace NVMath; - -#ifdef USE_W_DEPTH - Matrix44A mReproject = mToWorld * rCurrent; - const vec4 MR0 = reinterpret_cast(&mReproject)[0]; - const vec4 MR1 = reinterpret_cast(&mReproject)[1]; - const vec4 MR2 = reinterpret_cast(&mReproject)[2]; - const vec4 MR3 = reinterpret_cast(&mReproject)[3]; - - const vec4 vA = NVMath::Vec4(a); - const vec4 vB = NVMath::Vec4(b); -#else - const vec4 MW0 = reinterpret_cast(&mToWorld)[0]; - const vec4 MW1 = reinterpret_cast(&mToWorld)[1]; - const vec4 MW2 = reinterpret_cast(&mToWorld)[2]; - const vec4 MW3 = reinterpret_cast(&mToWorld)[3]; - - const vec4 MS0 = reinterpret_cast(&rCurrent)[0]; - const vec4 MS1 = reinterpret_cast(&rCurrent)[1]; - const vec4 MS2 = reinterpret_cast(&rCurrent)[2]; - const vec4 MS3 = reinterpret_cast(&rCurrent)[3]; -#endif - - const vec4 vXOffsets = NVMath::Vec4(0.0f, 1.0f, 2.0f, 3.0f); - const vec4 vXIncrement = NVMath:: Vec4(4.0f); - - const float nearestLinear = b / (nearestMax - a); - const vec4 vfEpsilon = NVMath::Vec4Epsilon(); - const vec4 vfOne = NVMath::Vec4One(); - const vec4 vZero = NVMath::Vec4Zero(); - - vec4* pSrcZ = reinterpret_cast(&m_ZBuffer[nStartLine * sizeX]); - - for (y = nStartLine, fY = static_cast(nStartLine); y < nStartLine + nNumLines; y++, fY += 1.0f) - { - const vec4 vYYYY = NVMath::Vec4(fY); - - vec4 vXCoords = vXOffsets; - - for (x = 0; x < sizeX; x += 4) - { - const vec4 vNonLinearDepth = *pSrcZ; - - vec4 vXXXX[4]; - vXXXX[0] = Splat<0>(vXCoords); - vXXXX[1] = Splat<1>(vXCoords); - vXXXX[2] = Splat<2>(vXCoords); - vXXXX[3] = Splat<3>(vXCoords); - - vec4 vZZZZ[4]; - vZZZZ[0] = Splat<0>(vNonLinearDepth); - vZZZZ[1] = Splat<1>(vNonLinearDepth); - vZZZZ[2] = Splat<2>(vNonLinearDepth); - vZZZZ[3] = Splat<3>(vNonLinearDepth); - - for (int i = 0; i < 4; i++) - { -#ifdef USE_W_DEPTH - vec4 vScreenPos = Madd(MR0, vXXXX[i], Madd(MR1, vYYYY, Madd(MR2, vZZZZ[i], MR3))); - - vec4 vScreenPosH = Div(vScreenPos, Splat<3>(vScreenPos)); - - vec4 vNewDepth = Div(vB, Sub(Splat<2>(vScreenPosH), vA)); - - float newDepth = Vec4float<2>(vNewDepth); -#else - vec4 vWorldPos = Madd(MW0, vXXXX[i], Madd(MW1, vYYYY, Madd(MW2, vZZZZ[i], MW3))); - - vec4 vWorldPosH = Div(vWorldPos, Max(Splat<3>(vWorldPos), vfEpsilon)); - - vec4 vScreenPos = Madd(MS0, Splat<0>(vWorldPosH), Madd(MS1, Splat<1>(vWorldPosH), Madd(MS2, Splat<2>(vWorldPosH), MS3))); - - vec4 vNewDepth = Splat<2>(vScreenPos); - - vec4 vScreenPosH = Div(vScreenPos, Max(Splat<3>(vScreenPos), vfEpsilon)); - - float newDepth = Vec4float<2>(vNewDepth); -#endif - // It is faster to use simple non-vectorized code to write the depth in the buffer - - if (newDepth > 0.f) - { - int X; - int Y; - if (Vec4float<0>(vZZZZ[i]) < nearestMax) - { - X = x + i; - Y = y; - newDepth = nearestLinear; - } - else - { - vec4 vFinalScreenPosU = floatToint32(vScreenPosH); - - X = Vec4int32<0>(vFinalScreenPosU); - Y = Vec4int32<1>(vFinalScreenPosU); - } - - if (X >= 0 && Y >= 0 && X < sizeX && Y < sizeY) - { - float* pDstZ = &pZBufferSwap[X + (Y * sizeX)]; - float depth = *pDstZ; - - depth = depth <= 0.f ? farPlane : depth; - *pDstZ = min(depth, newDepth); - } - } - } - vXCoords = Add(vXIncrement, vXCoords); - - pSrcZ++; - } - } - } - } - - void MergeReprojectHWDepthBuffer(int nStartLine, int nNumLines) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - const int sizeX = SIZEX; - using namespace NVMath; - - const vec4 zero = Vec4Zero(); - - for (uint32 i = 0; i < m_nNumWorker; ++i) - { - for (int y = nStartLine; y < nStartLine + nNumLines; y++) - { - for (int x = 0; x < sizeX; x += 4) - { - vec4* pDstZ = reinterpret_cast(&m_ZBufferSwapMerged[x + (y * sizeX)]); - vec4 vDstZ = *pDstZ; - - vec4* pSrcZ = reinterpret_cast(&m_ZBufferSwap[i][x + (y * sizeX)]); - vec4 vSrcZ = *pSrcZ; - - // remove zeros so Min doesn't select them - vDstZ = Select(vDstZ, vSrcZ, CmpLE(vDstZ, zero)); - vSrcZ = Select(vSrcZ, vDstZ, CmpLE(vSrcZ, zero)); - - const vec4 vNewDepth = Min(vSrcZ, vDstZ); - - *pDstZ = vNewDepth; - } - } - } - } - - void ReprojectHWDepthBufferAfterMerge([[maybe_unused]] const Matrix44A& rCurrent, [[maybe_unused]] float nearPlane, float farPlane, [[maybe_unused]] float nearestMax, float Bias, int nStartLine, int nNumLines) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - using namespace NVMath; - int sizeX = SIZEX; - int sizeY = SIZEY; - const vec4 vFarPlane = NVMath::Vec4(farPlane); - - float* pZBufferSwap = m_ZBufferSwapMerged; - vec4* pSwap = reinterpret_cast(&pZBufferSwap[0]); - vec4* pDst = reinterpret_cast(&m_ZBuffer[nStartLine * sizeX]); - - const vec4 vBiasAdd = NVMath::Vec4(Bias < 0.f ? -Bias : 0.f); - const vec4 vBiasMul = NVMath::Vec4(Bias > 0.f ? Bias : 0.f); - const int pitchX = SIZEX / 4; - - vec4 zero = Vec4Zero(); - - for (int y = nStartLine; y < nStartLine + nNumLines; y++) - { - int minY = max((int)0, (int)y - 1); - int maxY = min((int)sizeY - 1, (int)y + 1); - - int maxX = min(pitchX - 1, 0 + 1); - - vec4 src[3]; - vec4 srcMax[3]; - vec4 srcCenter; - - // left, no data available yet - srcMax[0] = zero; - - // center - src[0] = pSwap[0 + minY * pitchX]; - src[1] = pSwap[0 + y * pitchX]; - src[2] = pSwap[0 + maxY * pitchX]; - srcMax[1] = Max(Max(src[0], src[1]), src[2]); - srcCenter = src[1]; - - // right - src[0] = pSwap[maxX + minY * pitchX]; - src[1] = pSwap[maxX + y * pitchX]; - src[2] = pSwap[maxX + maxY * pitchX]; - srcMax[2] = Max(Max(src[0], src[1]), src[2]); - - int vecX = 0; - for (int x = 0; x < sizeX; x += 4) //todo, fix edge cases - { - vec4 vDst; - - vec4 vSrcIsZero = CmpLE(srcCenter, zero); - - // 0 - { - vec4 vLeft, vCenter; - vLeft = SelectStatic<0x8>(zero, srcMax[0]); - vCenter = SelectStatic<0x3>(zero, srcMax[1]); - - vec4 _vMax; - _vMax = Max(vLeft, vCenter); - _vMax = Max(_vMax, Swizzle(_vMax)); - _vMax = Max(_vMax, Swizzle(_vMax)); - - vDst = _vMax; - } - - // 1 - { - vec4 vCenter; - - vCenter = SelectStatic<0x7>(zero, srcMax[1]); - - vec4 _vMax; - _vMax = Max(vCenter, Swizzle(vCenter)); - _vMax = Max(_vMax, Swizzle(_vMax)); - - vDst = SelectStatic<0x2>(vDst, _vMax); - } - - // 2 - { - vec4 vCenter; - - vCenter = SelectStatic<0xE>(zero, srcMax[1]); - - vec4 _vMax; - _vMax = Max(vCenter, Swizzle(vCenter)); - _vMax = Max(_vMax, Swizzle(_vMax)); - - vDst = SelectStatic<0x4>(vDst, _vMax); - } - - // 3 - { - vec4 vRight, vCenter; - - vRight = SelectStatic<0x1>(zero, srcMax[2]); - vCenter = SelectStatic<0xC>(zero, srcMax[1]); - - vec4 _vMax; - _vMax = Max(vRight, vCenter); - - _vMax = Max(_vMax, Swizzle(_vMax)); - _vMax = Max(_vMax, Swizzle(_vMax)); - - vDst = SelectStatic<0x8>(vDst, _vMax); - } - - vec4 vDstIsZero = CmpLE(vDst, zero); - vDst = Select(vDst, vFarPlane, vDstIsZero); - - vDst = Select(srcCenter, vDst, vSrcIsZero); - - vDst = Add(vDst, vBiasAdd);//linear bias - vDst = Add(vDst, Madd(vBiasMul, vDst, vBiasMul));// none-linear bias -#ifdef SCALE_DEPTH - //*pDst = Mul(vDst, NVMath::Vec4(1.2f)); - *pDst = Add(vDst, NVMath::Vec4(0.5f)); -#else - *pDst = vDst; -#endif - - //next loop - ++pDst; - ++vecX; - - // shift to the left - srcMax[0] = srcMax[1]; - srcMax[1] = srcMax[2]; - srcCenter = src[1]; - - // load right data - maxX = min(pitchX - 1, vecX + 1); - src[0] = pSwap[maxX + minY * pitchX]; - src[1] = pSwap[maxX + y * pitchX]; - src[2] = pSwap[maxX + maxY * pitchX]; - srcMax[2] = Max(Max(src[0], src[1]), src[2]); - } - } - - //for(int a=0;a<128;a+=16) - // printf("%2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\n", - // m_ZBuffer[a+0],m_ZBuffer[a+1],m_ZBuffer[a+2],m_ZBuffer[a+3], - // m_ZBuffer[a+4],m_ZBuffer[a+5],m_ZBuffer[a+6],m_ZBuffer[a+7], - // m_ZBuffer[a+8],m_ZBuffer[a+9],m_ZBuffer[a+10],m_ZBuffer[a+11], - // m_ZBuffer[a+12],m_ZBuffer[a+13],m_ZBuffer[a+14],m_ZBuffer[a+15]); - -#ifdef CULL_RENDERER_REPROJ_DEBUG - memcpy(&pZBufferSwap[nStartLine * sizeX], &m_ZBuffer[nStartLine * sizeX], sizeX * nNumLines * sizeof(float)); -#endif - - -#ifdef SCALE_DEPTH -#undef SCALE_DEPTH -#endif - -#ifdef USE_W_DEPTH -#undef USE_W_DEPTH -#endif - } - - CULLNOINLINE int AABBInFrustum(const NVMath::vec4* pViewProj, Vec3 Min, Vec3 Max, Vec3 ViewPos) - { - using namespace NVMath; - const NVMath::vec4 M0 = pViewProj[0]; - const NVMath::vec4 M1 = pViewProj[1]; - const NVMath::vec4 M2 = pViewProj[2]; - const NVMath::vec4 M3 = pViewProj[3]; - const NVMath::vec4 MinX = NVMath::Vec4(Min.x); - const NVMath::vec4 MinY = NVMath::Vec4(Min.y); - const NVMath::vec4 MinZ = NVMath::Vec4(Min.z); - const NVMath::vec4 MaxX = NVMath::Vec4(Max.x); - const NVMath::vec4 MaxY = NVMath::Vec4(Max.y); - const NVMath::vec4 MaxZ = NVMath::Vec4(Max.z); - - vec4 VB0 = Madd(MinX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3))); - vec4 VB1 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3))); - vec4 VB2 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3))); - vec4 VB3 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3))); - vec4 VB4 = Madd(MinX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3))); - vec4 VB5 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3))); - vec4 VB6 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3))); - vec4 VB7 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3))); - vec4 SMask = And(And(And(VB0, VB1), And(VB2, VB3)), And(Or(VB4, VB5), And(VB6, VB7))); - if (SignMask(SMask) & BitZ) - { - return 0; - } - - int Visible = 3; - - SMask = Or(Or(Or(VB0, VB1), Or(VB2, VB3)), Or(Or(VB4, VB5), Or(VB6, VB7))); - if ((SignMask(SMask) & BitZ) == 0) - { - VB0 = Div(VB0, Splat<3>(VB0)); - VB1 = Div(VB1, Splat<3>(VB1)); - VB2 = Div(VB2, Splat<3>(VB2)); - VB3 = Div(VB3, Splat<3>(VB3)); - VB4 = Div(VB4, Splat<3>(VB4)); - VB5 = Div(VB5, Splat<3>(VB5)); - VB6 = Div(VB6, Splat<3>(VB6)); - VB7 = Div(VB7, Splat<3>(VB7)); - const vec4 VC0 = Madd(VB0, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC1 = Madd(VB1, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC2 = Madd(VB2, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC3 = Madd(VB3, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC4 = Madd(VB4, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC5 = Madd(VB5, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC6 = Madd(VB6, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 VC7 = Madd(VB7, NVMath::Vec4(-1.f), m_VMaxXY); - const vec4 SMaskB = And(And(And(VB0, VB1), And(VB2, VB3)), And(And(VB4, VB5), And(VB6, VB7))); - const vec4 SMaskC = And(And(And(VC0, VC1), And(VC2, VC3)), And(And(VC4, VC5), And(VC6, VC7))); - if ((SignMask(SMaskB) & (BitX | BitY)) || (SignMask(SMaskC) & (BitX | BitY))) - { - return 0; - } - Visible = 1; - } - //return true; - if (Max.x < ViewPos.x) - { - if (Triangle(VB3, VB2, VB7)) - { - return Visible; //MaxX - } - if (Triangle(VB7, VB2, VB6)) - { - return Visible; - } - Visible &= ~1; - } - else - if (Min.x > ViewPos.x) - { - if (Triangle(VB0, VB1, VB4)) - { - return Visible; //MinX - } - if (Triangle(VB4, VB1, VB5)) - { - return Visible; - } - Visible &= ~1; - } - if (Max.y < ViewPos.y) - { - if (Triangle(VB1, VB3, VB5)) - { - return Visible | 1; //MaxY - } - if (Triangle(VB5, VB3, VB7)) - { - return Visible | 1; - } - Visible &= ~1; - } - else - if (Min.y > ViewPos.y) - { - if (Triangle(VB2, VB0, VB6)) - { - return Visible | 1; //MinY - } - if (Triangle(VB6, VB0, VB4)) - { - return Visible | 1; - } - Visible &= ~1; - } - if (Max.z < ViewPos.z) - { - if (Triangle(VB4, VB5, VB6)) - { - return Visible | 1; //MaxZ - } - if (Triangle(VB6, VB5, VB7)) - { - return Visible | 1; - } - Visible = 0; - } - else - if (Min.z > ViewPos.z) - { - if (Triangle(VB1, VB0, VB3)) - { - return Visible | 1; //MinZ - } - if (Triangle(VB3, VB0, VB2)) - { - return Visible | 1; - } - Visible = 0; - } - return Visible & (Visible << 1); - } - - - CULLINLINE bool TestQuad(const NVMath::vec4* pViewProj, const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) - { - const NVMath::vec4 M0 = pViewProj[0]; - const NVMath::vec4 M1 = pViewProj[1]; - const NVMath::vec4 M2 = pViewProj[2]; - const NVMath::vec4 M3 = pViewProj[3]; - - const Vec3 v0 = vCenter - vAxisX - vAxisY; - const Vec3 v1 = vCenter - vAxisX + vAxisY; - const Vec3 v2 = vCenter + vAxisX + vAxisY; - const Vec3 v3 = vCenter + vAxisX - vAxisY; - - const NVMath::vec4 VB0 = NVMath::Madd(NVMath::Vec4(v0.x), M0, NVMath::Madd(NVMath::Vec4(v0.y), M1, NVMath::Madd(NVMath::Vec4(v0.z), M2, M3))); - const NVMath::vec4 VB1 = NVMath::Madd(NVMath::Vec4(v1.x), M0, NVMath::Madd(NVMath::Vec4(v1.y), M1, NVMath::Madd(NVMath::Vec4(v1.z), M2, M3))); - const NVMath::vec4 VB2 = NVMath::Madd(NVMath::Vec4(v2.x), M0, NVMath::Madd(NVMath::Vec4(v2.y), M1, NVMath::Madd(NVMath::Vec4(v2.z), M2, M3))); - const NVMath::vec4 VB3 = NVMath::Madd(NVMath::Vec4(v3.x), M0, NVMath::Madd(NVMath::Vec4(v3.y), M1, NVMath::Madd(NVMath::Vec4(v3.z), M2, M3))); - - // Note: Explicitly disabling backface culling here - if (Triangle(VB2, VB0, VB3)) - { - return true; - } - if (Triangle(VB1, VB0, VB2)) - { - return true; - } - - return false; - } - - CULLNOINLINE bool TestAABB(const NVMath::vec4* pViewProj, Vec3 Min, Vec3 Max, Vec3 ViewPos) - { - using namespace NVMath; - const NVMath::vec4 M0 = pViewProj[0]; - const NVMath::vec4 M1 = pViewProj[1]; - const NVMath::vec4 M2 = pViewProj[2]; - const NVMath::vec4 M3 = pViewProj[3]; - const NVMath::vec4 MinX = NVMath::Vec4(Min.x); - const NVMath::vec4 MinY = NVMath::Vec4(Min.y); - const NVMath::vec4 MinZ = NVMath::Vec4(Min.z); - const NVMath::vec4 MaxX = NVMath::Vec4(Max.x); - const NVMath::vec4 MaxY = NVMath::Vec4(Max.y); - const NVMath::vec4 MaxZ = NVMath::Vec4(Max.z); - - const vec4 VB0 = Madd(MinX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3))); - const vec4 VB1 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3))); - const vec4 VB2 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MinZ, M2, M3))); - const vec4 VB3 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MinZ, M2, M3))); - const vec4 VB4 = Madd(MinX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3))); - const vec4 VB5 = Madd(MinX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3))); - const vec4 VB6 = Madd(MaxX, M0, Madd(MinY, M1, Madd(MaxZ, M2, M3))); - const vec4 VB7 = Madd(MaxX, M0, Madd(MaxY, M1, Madd(MaxZ, M2, M3))); - vec4 SMask = Or(Or(Or(VB0, VB1), Or(VB2, VB3)), Or(Or(VB4, VB5), Or(VB6, VB7))); - - if (SignMask(SMask) & BitZ) - { - if (Max.x < ViewPos.x) - { - if (Triangle(VB3, VB2, VB7)) - { - return true; //MaxX - } - if (Triangle(VB7, VB2, VB6)) - { - return true; - } - } - if (Min.x > ViewPos.x) - { - if (Triangle(VB0, VB1, VB4)) - { - return true; //MinX - } - if (Triangle(VB4, VB1, VB5)) - { - return true; - } - } - if (Max.y < ViewPos.y) - { - if (Triangle(VB1, VB3, VB5)) - { - return true; //MaxY - } - if (Triangle(VB5, VB3, VB7)) - { - return true; - } - } - if (Min.y > ViewPos.y) - { - if (Triangle(VB2, VB0, VB6)) - { - return true; //MinY - } - if (Triangle(VB6, VB0, VB4)) - { - return true; - } - } - if (Max.z < ViewPos.z) - { - if (Triangle(VB4, VB5, VB6)) - { - return true; //MaxZ - } - if (Triangle(VB6, VB5, VB7)) - { - return true; - } - } - if (Min.z > ViewPos.z) - { - if (Triangle(VB1, VB0, VB3)) - { - return true; //MinZ - } - if (Triangle(VB3, VB0, VB2)) - { - return true; - } - } - } - else - { - if (Max.x < ViewPos.x) - { - //if(Quad2D(VB3,VB2,VB6,VB7))return true; - if (Triangle2D(VB3, VB2, VB7)) - { - return true; - } - if (Triangle2D(VB7, VB2, VB6)) - { - return true; - } - } - if (Min.x > ViewPos.x) - { - //if(Quad2D(VB0,VB1,VB5,VB4))return true; - if (Triangle2D(VB0, VB1, VB4)) - { - return true; - } - if (Triangle2D(VB4, VB1, VB5)) - { - return true; - } - } - if (Max.y < ViewPos.y) - { - //if(Quad2D(VB1,VB3,VB7,VB5))return true; - if (Triangle2D(VB1, VB3, VB5)) - { - return true; - } - if (Triangle2D(VB5, VB3, VB7)) - { - return true; - } - } - if (Min.y > ViewPos.y) - { - //if(Quad2D(VB2,VB0,VB4,VB6))return true; - if (Triangle2D(VB2, VB0, VB6)) - { - return true; - } - if (Triangle2D(VB6, VB0, VB4)) - { - return true; - } - } - if (Max.z < ViewPos.z) - { - //if(Quad2D(VB4,VB5,VB7,VB6))return true; - if (Triangle2D(VB4, VB5, VB6)) - { - return true; - } - if (Triangle2D(VB6, VB5, VB7)) - { - return true; - } - } - if (Min.z > ViewPos.z) - { - //if(Quad2D(VB1,VB0,VB2,VB3))return true; - if (Triangle2D(VB1, VB0, VB3)) - { - return true; - } - if (Triangle2D(VB3, VB0, VB2)) - { - return true; - } - } - } - return false; - } - - template - CULLNOINLINE void Rasterize(const NVMath::vec4* pViewProj, const NVMath::vec4* __restrict pTriangles, size_t TriCount) - { - using namespace NVMath; - Prefetch(pTriangles); - m_DrawCall++; - m_PolyCount += TriCount; - - const vec4 M0 = pViewProj[0]; - const vec4 M1 = pViewProj[1]; - const vec4 M2 = pViewProj[2]; - const vec4 M3 = pViewProj[3]; - const size_t VCacheCount = 48; //16x3 vertices - vec4 VTmp[VCacheCount]; - vec4 DetTmp[VCacheCount * 2 / 3]; - - - - if (TriCount > 65535) - { - TriCount = 65535; - } - for (size_t a = 0, S = TriCount; a < S; a += VCacheCount) - { - vec4 ZMask = Vec4Zero(); - const size_t VTmpCount = VCacheCount + a > TriCount ? TriCount - a : VCacheCount; - vec4* pVTmp = VTmp; - for (size_t b = 0; b < VTmpCount; b += 3, pVTmp += 3, pTriangles += 3) - { - Prefetch(pTriangles + 48); - const vec4 VA = reinterpret_cast(pTriangles)[0]; - const vec4 VB = reinterpret_cast(pTriangles)[1]; - const vec4 VC = reinterpret_cast(pTriangles)[2]; - - const vec4 V0 = Madd(Splat<0>(VA), M0, Madd(Splat<1>(VA), M1, Madd(Splat<2>(VA), M2, M3))); - const vec4 V1 = Madd(Splat<0>(VB), M0, Madd(Splat<1>(VB), M1, Madd(Splat<2>(VB), M2, M3))); - const vec4 V2 = Madd(Splat<0>(VC), M0, Madd(Splat<1>(VC), M1, Madd(Splat<2>(VC), M2, M3))); - if (NEEDCLIPPING) - { - ZMask = Or(Or(ZMask, V0), Or(V1, V2)); - } - pVTmp[0] = V0; - pVTmp[1] = V1; - pVTmp[2] = V2; - } - - const uint32 Idx = SignMask(ZMask) & BitZ; -AZ_PUSH_DISABLE_WARNING(4127, "-Wunknown-warning-option") - if (NEEDCLIPPING && Idx == BitZ) -AZ_POP_DISABLE_WARNING - { - for (size_t b = 0; b < VTmpCount; b += 3) - { - Triangle(VTmp[b], VTmp[b + 2], VTmp[b + 1]); - } - } - else - { - pVTmp = VTmp; - const vec4 M = NVMath::Vec4(~0u, ~0u, 0u, ~0u); - pVTmp = VTmp; - vec4* pDetTmp = DetTmp; - for (size_t b = 0; b < VTmpCount; b += 12, pVTmp += 12, pDetTmp += 8) - { - vec4 V0 = pVTmp[0]; - vec4 V1 = pVTmp[1]; - vec4 V2 = pVTmp[2]; - vec4 V3 = pVTmp[3]; - vec4 V4 = pVTmp[4]; - vec4 V5 = pVTmp[5]; - vec4 V6 = pVTmp[6]; - vec4 V7 = pVTmp[7]; - vec4 V8 = pVTmp[8]; - vec4 V9 = pVTmp[9]; - vec4 VA = pVTmp[10]; - vec4 VB = pVTmp[11]; - const vec4 W0123 = Shuffle(Shuffle(V0, V1), Shuffle(V2, V3)); - const vec4 W4567 = Shuffle(Shuffle(V4, V5), Shuffle(V6, V7)); - const vec4 W89AB = Shuffle(Shuffle(V8, V9), Shuffle(VA, VB)); - const vec4 iW0123 = Rcp(W0123); - const vec4 iW4567 = Rcp(W4567); - const vec4 iW89AB = Rcp(W89AB); - const vec4 V0T = Mul(V0, Splat<0>(iW0123)); - const vec4 V1T = Mul(V1, Splat<1>(iW0123)); - const vec4 V2T = Mul(V2, Splat<2>(iW0123)); - const vec4 V3T = Mul(V3, Splat<3>(iW0123)); - const vec4 V4T = Mul(V4, Splat<0>(iW4567)); - const vec4 V5T = Mul(V5, Splat<1>(iW4567)); - const vec4 V6T = Mul(V6, Splat<2>(iW4567)); - const vec4 V7T = Mul(V7, Splat<3>(iW4567)); - const vec4 V8T = Mul(V8, Splat<0>(iW89AB)); - const vec4 V9T = Mul(V9, Splat<1>(iW89AB)); - const vec4 VAT = Mul(VA, Splat<2>(iW89AB)); - const vec4 VBT = Mul(VB, Splat<3>(iW89AB)); - V0 = SelectBits(V0, V0T, M); - V1 = SelectBits(V1, V1T, M); - V2 = SelectBits(V2, V2T, M); - V3 = SelectBits(V3, V3T, M); - V4 = SelectBits(V4, V4T, M); - V5 = SelectBits(V5, V5T, M); - V6 = SelectBits(V6, V6T, M); - V7 = SelectBits(V7, V7T, M); - V8 = SelectBits(V8, V8T, M); - V9 = SelectBits(V9, V9T, M); - VA = SelectBits(VA, VAT, M); - VB = SelectBits(VB, VBT, M); - vec4 V012 = Sub(Shuffle(V2T, V1T), Swizzle(V0T)); - vec4 V345 = Sub(Shuffle(V5T, V4T), Swizzle(V3T)); - vec4 V678 = Sub(Shuffle(V8T, V7T), Swizzle(V6T)); - vec4 V9AB = Sub(Shuffle(VBT, VAT), Swizzle(V9T)); - vec4 Det012 = Mul(V012, Swizzle(V012)); - vec4 Det345 = Mul(V345, Swizzle(V345)); - vec4 Det678 = Mul(V678, Swizzle(V678)); - vec4 Det9AB = Mul(V9AB, Swizzle(V9AB)); - Det012 = Sub(Det012, Splat<1>(Det012)); - Det345 = Sub(Det345, Splat<1>(Det345)); - Det678 = Sub(Det678, Splat<1>(Det678)); - Det9AB = Sub(Det9AB, Splat<1>(Det9AB)); - vec4 Det = Shuffle(Shuffle(Det012, Det345), Shuffle(Det678, Det9AB)); -#if !defined(LINUX) && !defined(APPLE) //to avoid DivBy0 exception on PC - Det = Select(Det, NVMath::Vec4(-FLT_EPSILON), CmpEq(Det, Vec4Zero())); -#endif - Det = Rcp(Det); - Det012 = Splat<0>(Det); - Det345 = Splat<1>(Det); - Det678 = Splat<2>(Det); - Det9AB = Splat<3>(Det); - - vec4 VMax012 = Max(Max(V0T, V1T), V2T); - vec4 VMax345 = Max(Max(V3T, V4T), V5T); - vec4 VMax678 = Max(Max(V6T, V7T), V8T); - vec4 VMax9AB = Max(Max(V9T, VAT), VBT); - vec4 VMin012 = Min(Min(V0T, V1T), V2T); - vec4 VMin345 = Min(Min(V3T, V4T), V5T); - vec4 VMin678 = Min(Min(V6T, V7T), V8T); - vec4 VMin9AB = Min(Min(V9T, VAT), VBT); - VMax012 = Add(VMax012, Vec4One()); - VMax345 = Add(VMax345, Vec4One()); - VMax678 = Add(VMax678, Vec4One()); - VMax9AB = Add(VMax9AB, Vec4One()); - vec4 VMinMax012 = Shuffle(VMin012, VMax012); - vec4 VMinMax345 = Shuffle(VMin345, VMax345); - vec4 VMinMax678 = Shuffle(VMin678, VMax678); - vec4 VMinMax9AB = Shuffle(VMin9AB, VMax9AB); - VMinMax012 = Max(VMinMax012, Vec4Zero()); - VMinMax345 = Max(VMinMax345, Vec4Zero()); - VMinMax678 = Max(VMinMax678, Vec4Zero()); - VMinMax9AB = Max(VMinMax9AB, Vec4Zero()); - VMinMax012 = Min(VMinMax012, m_VMaxXY); - VMinMax345 = Min(VMinMax345, m_VMaxXY); - VMinMax678 = Min(VMinMax678, m_VMaxXY); - VMinMax9AB = Min(VMinMax9AB, m_VMaxXY); - VMinMax012 = floatToint32(VMinMax012); - VMinMax345 = floatToint32(VMinMax345); - VMinMax678 = floatToint32(VMinMax678); - VMinMax9AB = floatToint32(VMinMax9AB); - VMinMax012 = Or(VMinMax012, CmpLE(Det012, Vec4Zero())); //backface cull - VMinMax345 = Or(VMinMax345, CmpLE(Det345, Vec4Zero())); - VMinMax678 = Or(VMinMax678, CmpLE(Det678, Vec4Zero())); - VMinMax9AB = Or(VMinMax9AB, CmpLE(Det9AB, Vec4Zero())); - - pVTmp[0] = V0; - pVTmp[1] = V1; - pVTmp[2] = V2; - pVTmp[3] = V3; - pVTmp[4] = V4; - pVTmp[5] = V5; - pVTmp[6] = V6; - pVTmp[7] = V7; - pVTmp[8] = V8; - pVTmp[9] = V9; - pVTmp[10] = VA; - pVTmp[11] = VB; - pDetTmp[0] = VMinMax012; - pDetTmp[1] = Mul(V012, Det012); - pDetTmp[2] = VMinMax345; - pDetTmp[3] = Mul(V345, Det345); - pDetTmp[4] = VMinMax678; - pDetTmp[5] = Mul(V678, Det678); - pDetTmp[6] = VMinMax9AB; - pDetTmp[7] = Mul(V9AB, Det9AB); - } - - pDetTmp = DetTmp; - for (size_t b = 0; b < VTmpCount; b += 3, pDetTmp += 2) - { - const uint32* pMM = reinterpret_cast(pDetTmp); - const uint16 MinX = pMM[0]; - const uint16 MinY = pMM[1]; - const uint16 MaxX = pMM[2]; - const uint16 MaxY = pMM[3]; - if (MinX < MaxX && MinY < MaxY) - { - Triangle2D(VTmp[b], VTmp[b + 2], VTmp[b + 1], MinX, MinY, MaxX, MaxY, pDetTmp[0], pDetTmp[1]); - } - } - } - } - } - template - CULLNOINLINE bool Rasterize(const NVMath::vec4* pViewProj, tdVertexCacheArg vertexCache, - const tdIndex* __restrict pIndices, const uint32 ICount, - const uint8* __restrict pVertices, const uint32 VertexSize, const uint32 VCount) - { - using namespace NVMath; - if (!VCount || !ICount) - { - return false; - } - - m_DrawCall++; - m_PolyCount += VCount / 3; - - const vec4 M0 = pViewProj[0]; - const vec4 M1 = pViewProj[1]; - const vec4 M2 = pViewProj[2]; - const vec4 M3 = pViewProj[3]; - - if (VCount + 1 > vertexCache.size()) - { - vertexCache.resize(VCount + 1); - } - vec4* pVCache = &vertexCache[0]; - pVCache = reinterpret_cast(((reinterpret_cast(pVCache) + 15) & ~15)); - - vec4 SMask = Vec4Zero(); - for (uint32 a = 0, S = VCount & ~3; a < S; a += 4) - { - const float* pV0 = reinterpret_cast(pVertices + a * VertexSize); - const float* pV1 = reinterpret_cast(pVertices + (a + 1) * VertexSize); - const float* pV2 = reinterpret_cast(pVertices + (a + 2) * VertexSize); - const float* pV3 = reinterpret_cast(pVertices + (a + 3) * VertexSize); - const vec4 V0 = Madd(NVMath::Vec4(pV0[0]), M0, Madd(NVMath::Vec4(pV0[1]), M1, Madd(NVMath::Vec4(pV0[2]), M2, M3))); - const vec4 V1 = Madd(NVMath::Vec4(pV1[0]), M0, Madd(NVMath::Vec4(pV1[1]), M1, Madd(NVMath::Vec4(pV1[2]), M2, M3))); - const vec4 V2 = Madd(NVMath::Vec4(pV2[0]), M0, Madd(NVMath::Vec4(pV2[1]), M1, Madd(NVMath::Vec4(pV2[2]), M2, M3))); - const vec4 V3 = Madd(NVMath::Vec4(pV3[0]), M0, Madd(NVMath::Vec4(pV3[1]), M1, Madd(NVMath::Vec4(pV3[2]), M2, M3))); - SMask = Or(SMask, V0); - SMask = Or(SMask, V1); - SMask = Or(SMask, V2); - SMask = Or(SMask, V3); - pVCache[a ] = V0; - pVCache[a + 1] = V1; - pVCache[a + 2] = V2; - pVCache[a + 3] = V3; - } - for (uint32 a = VCount & ~3, S = VCount; a < S; a++) - { - const float* pV = reinterpret_cast(pVertices + a * VertexSize); - const vec4 V = Madd(NVMath::Vec4(pV[0]), M0, Madd(NVMath::Vec4(pV[1]), M1, Madd(NVMath::Vec4(pV[2]), M2, M3))); - SMask = Or(SMask, V); - pVCache[a] = V; - } - - bool Visible = false; - if (SignMask(SMask) & BitZ) - { - for (uint32 a = 0; a < ICount; a += 3) - { - vec4 Pos0 = pVCache[pIndices[a]]; - vec4 Pos2 = pVCache[pIndices[a + 1]]; - vec4 Pos1 = pVCache[pIndices[a + 2]]; - Visible |= Triangle(Pos0, Pos1, Pos2); - if (!WRITE && Visible) - { - return true; - } - } - } - else - { - for (uint32 a = 0; a < ICount; a += 3) - { - vec4 Pos0 = pVCache[pIndices[a]]; - vec4 Pos2 = pVCache[pIndices[a + 1]]; - vec4 Pos1 = pVCache[pIndices[a + 2]]; - Visible |= Triangle2D(Pos0, Pos1, Pos2); - if (!WRITE && Visible) - { - return true; - } - } - } - return Visible; - } - - int m_DebugRender; - - void DrawDebug(IRenderer* pRenderer, int32 nStep) - { // project buffer to the screen -#if defined(CULLING_ENABLE_DEBUG_OVERLAY) - nStep %= 32; - if (!nStep) - { - return; - } - - //if(!m_DebugRender) - // return; - - const float FarPlaneInv = 255.f / pRenderer->GetCamera().GetFarPlane(); - - SAuxGeomRenderFlags oFlags(e_Def2DPublicRenderflags); - oFlags.SetDepthTestFlag(e_DepthTestOff); - oFlags.SetDepthWriteFlag(e_DepthWriteOff); - oFlags.SetCullMode(e_CullModeNone); - oFlags.SetAlphaBlendMode(e_AlphaNone); - pRenderer->GetIRenderAuxGeom()->SetRenderFlags(oFlags); - - int nScreenHeight = gEnv->pRenderer->GetHeight(); - int nScreenWidth = gEnv->pRenderer->GetWidth(); - - float fScreenHeight = (float)nScreenHeight; - float fScreenWidth = (float)nScreenWidth; - - float fTopOffSet = 35.0f; - float fSideOffSet = 35.0f; - - // draw z-buffer after reprojection (unknown parts are red) - fTopOffSet += 200.0f; - for (uint32 y = 0; y < SIZEY; y += 1) - { - const float* __restrict pVMemZ = alias_cast(&m_ZBuffer[y * SIZEX]); - float fY = fTopOffSet + (y * 3); - for (uint32 x = 0; x < SIZEX; x += 4) - { - float fX0 = fSideOffSet + ((x + 0) * 3); - float fX1 = fSideOffSet + ((x + 1) * 3); - float fX2 = fSideOffSet + ((x + 2) * 3); - float fX3 = fSideOffSet + ((x + 3) * 3); - - //ColorB ValueColor0 = ((ColorB*)pVMemZ)[x+0]; - //ColorB ValueColor1 = ((ColorB*)pVMemZ)[x+1]; - //ColorB ValueColor2 = ((ColorB*)pVMemZ)[x+2]; - //ColorB ValueColor3 = ((ColorB*)pVMemZ)[x+3]; - ////ColorB color0=ColorB(ValueColor0,ValueColor0,ValueColor0,222); - ////ColorB color1=ColorB(ValueColor1,ValueColor1,ValueColor1,222); - ////ColorB color2=ColorB(ValueColor2,ValueColor2,ValueColor2,222); - ////ColorB color3=ColorB(ValueColor3,ValueColor3,ValueColor3,222); - // - //NAsyncCull::Debug::Draw2DBox(fX0,fY,3.0f,3.0f,ValueColor0, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom()); - //NAsyncCull::Debug::Draw2DBox(fX1,fY,3.0f,3.0f,ValueColor1, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom()); - //NAsyncCull::Debug::Draw2DBox(fX2,fY,3.0f,3.0f,ValueColor2, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom()); - //NAsyncCull::Debug::Draw2DBox(fX3,fY,3.0f,3.0f,ValueColor3, fScreenHeight,fScreenWidth,pRenderer->GetIRenderAuxGeom()); - uint32 ValueColor0 = (uint32)(pVMemZ[x + 0]); - uint32 ValueColor1 = (uint32)(pVMemZ[x + 1]); - uint32 ValueColor2 = (uint32)(pVMemZ[x + 2]); - uint32 ValueColor3 = (uint32)(pVMemZ[x + 3]); - ColorB Color0(ValueColor0, ValueColor0 * 16, ValueColor0 * 256, 222); - ColorB Color1(ValueColor1, ValueColor1 * 16, ValueColor1 * 256, 222); - ColorB Color2(ValueColor2, ValueColor2 * 16, ValueColor2 * 256, 222); - ColorB Color3(ValueColor3, ValueColor3 * 16, ValueColor3 * 256, 222); - - NAsyncCull::Debug::Draw2DBox(fX0, fY, 3.0f, 3.0f, Color0, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom()); - NAsyncCull::Debug::Draw2DBox(fX1, fY, 3.0f, 3.0f, Color1, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom()); - NAsyncCull::Debug::Draw2DBox(fX2, fY, 3.0f, 3.0f, Color2, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom()); - NAsyncCull::Debug::Draw2DBox(fX3, fY, 3.0f, 3.0f, Color3, fScreenHeight, fScreenWidth, pRenderer->GetIRenderAuxGeom()); - } - } -#endif - } - - CULLINLINE uint32 SizeX() const{return SIZEX; } - CULLINLINE uint32 SizeY() const{return SIZEY; } - }; -} - -template -_MS_ALIGN(128) float NAsyncCull::CCullRenderer::m_ZBufferMainMemory[SIZEX * SIZEY] _ALIGN(128); diff --git a/Code/CryEngine/Cry3DEngine/CCullThread.cpp b/Code/CryEngine/Cry3DEngine/CCullThread.cpp deleted file mode 100644 index dfc4caf82c..0000000000 --- a/Code/CryEngine/Cry3DEngine/CCullThread.cpp +++ /dev/null @@ -1,818 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "CCullThread.h" -#include "ObjMan.h" -#include "CCullRenderer.h" -#include -#include - -typedef NAsyncCull::CCullRenderer tdCullRasterizer; - -volatile static NAsyncCull::tdVertexCache g_VertexCache; -uint8 g_RasterizerBuffer[sizeof(tdCullRasterizer) + 16]; -tdCullRasterizer* g_Rasterizer; -#define RASTERIZER (*g_Rasterizer) - -namespace NAsyncCull -{ - const NVMath::vec4 MaskNot3 = NVMath::Vec4(~3u, ~0u, ~0u, ~0u); - - CCullThread::CCullThread() - : m_Enabled(false) - , m_Active(false) - , m_nPrepareState(IDLE) - , m_OCMMeshCount(0) - , m_OCMInstCount(0) - , m_OCMOffsetInstances(0) - { - size_t Buffer = reinterpret_cast(g_RasterizerBuffer); - Buffer += 127; - Buffer &= ~127; - g_Rasterizer = new(reinterpret_cast(Buffer))tdCullRasterizer(); - - m_NearPlane = 0; - m_FarPlane = 0; - m_NearestMax = 0; - } - - bool CCullThread::LoadLevel(const char* pFolderName) - { - m_OCMBuffer.resize(0); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen((string(pFolderName) + "/occluder.ocm").c_str(), "rbx"); - if (fileHandle == AZ::IO::InvalidHandle) - { - //__debugbreak(); - return false; - } - gEnv->pCryPak->FSeek(fileHandle, 0, SEEK_END); - const size_t Size = gEnv->pCryPak->FTell(fileHandle); - gEnv->pCryPak->FSeek(fileHandle, 0L, SEEK_SET); - m_OCMBuffer.reserve(Size + 144 * 3 + 16); //48tri*9byte padding for unrolled loop in rasterization without special case (not 144 algined poly count) - //16 for alignment - m_OCMBuffer.resize(Size); - size_t BufferOffset = reinterpret_cast(&m_OCMBuffer[0]); - BufferOffset = (BufferOffset + 15) & ~15; - m_pOCMBufferAligned = reinterpret_cast(BufferOffset); - - gEnv->pCryPak->FRead(m_pOCMBufferAligned, Size, fileHandle, false); - gEnv->pCryPak->FClose(fileHandle); - - const uint32 Version = Swap(*reinterpret_cast(&m_pOCMBufferAligned[0])); - m_OCMMeshCount = *reinterpret_cast(&m_pOCMBufferAligned[4]); - m_OCMInstCount = *reinterpret_cast(&m_pOCMBufferAligned[8]); - m_OCMOffsetInstances = *reinterpret_cast(&m_pOCMBufferAligned[12]); - - if (Version != ~3u && Version != ~4u) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Unsupported occlusion mesh format version. Please reexport the occluder mesh."); - stl::free_container(m_OCMBuffer); - return false; - } - - if (m_OCMOffsetInstances & 3) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "The occluder mesh contains invalid data. Please reexport the occluder mesh."); - stl::free_container(m_OCMBuffer); - return false; - } - - if (Version == ~3u) //bump to version ~4 - { - m_OCMMeshCount = Swap(m_OCMMeshCount); - m_OCMInstCount = Swap(m_OCMInstCount); - m_OCMOffsetInstances = Swap(m_OCMOffsetInstances); - PodArray OCMBufferOut(Size * 8, Size * 8); - uint8* pOut = &OCMBufferOut[0]; - *reinterpret_cast(&pOut[0]) = ~4u;//version - *reinterpret_cast(&pOut[4]) = m_OCMMeshCount; - *reinterpret_cast(&pOut[8]) = m_OCMInstCount; - *reinterpret_cast(&pOut[12]) = m_OCMOffsetInstances;//needs to be patched at the end - pOut += 16; - uint8* pMeshes = &m_pOCMBufferAligned[0];//actually starts at 16, but MeshOffset is zero based - uint8* pInstances = &m_pOCMBufferAligned[m_OCMOffsetInstances]; - std::map Offsets;// - for (size_t a = 0; a < m_OCMInstCount; a++) - { - Matrix44 World(IDENTITY); - uint8* pInstance = pInstances + a * (sizeof(int) + 12 * sizeof(float));//meshoffset+worldmatrix43 - uint32& MeshOffset = *reinterpret_cast(&pInstance[0]); - float* pWorldMat = reinterpret_cast(&pInstance[4]); - Swap(MeshOffset); - Swap(pWorldMat[0x0]); - Swap(pWorldMat[0x1]); - Swap(pWorldMat[0x2]); - Swap(pWorldMat[0x3]); - Swap(pWorldMat[0x4]); - Swap(pWorldMat[0x5]); - Swap(pWorldMat[0x6]); - Swap(pWorldMat[0x7]); - Swap(pWorldMat[0x8]); - Swap(pWorldMat[0x9]); - Swap(pWorldMat[0xA]); - Swap(pWorldMat[0xB]); - - if (Offsets.find(MeshOffset) != Offsets.end())//already endian swapped? - { - continue; - } - Offsets[MeshOffset] = static_cast(pOut - &OCMBufferOut[0]);//zero based offset - - uint8* pMesh = pMeshes + MeshOffset; - uint16& QuadCount = *reinterpret_cast(pMesh); - uint16& TriCount = *reinterpret_cast(pMesh + 2); - Swap(QuadCount); - Swap(TriCount); - *reinterpret_cast(pOut) = TriCount + QuadCount / 4 * 6; - pOut += 16;//to keep 16byte alignment - - const size_t Quads16 = (reinterpret_cast(pMesh + 4) + 15) & ~15; - const size_t Tris16 = (Quads16 + QuadCount * 3 + 15) & ~15; - const int8* pQuads = reinterpret_cast(Quads16); - const int8* pTris = reinterpret_cast(Tris16); - - for (size_t b = 0, S = QuadCount; b < S; b += 4) - { - const float x0 = *pQuads++; - const float y0 = *pQuads++; - const float z0 = *pQuads++; - const float x1 = *pQuads++; - const float y1 = *pQuads++; - const float z1 = *pQuads++; - const float x2 = *pQuads++; - const float y2 = *pQuads++; - const float z2 = *pQuads++; - const float x3 = *pQuads++; - const float y3 = *pQuads++; - const float z3 = *pQuads++; - reinterpret_cast(pOut)[0x00] = x0; - reinterpret_cast(pOut)[0x01] = y0; - reinterpret_cast(pOut)[0x02] = z0; - reinterpret_cast(pOut)[0x03] = 1.f; - reinterpret_cast(pOut)[0x04] = x2; - reinterpret_cast(pOut)[0x05] = y2; - reinterpret_cast(pOut)[0x06] = z2; - reinterpret_cast(pOut)[0x07] = 1.f; - reinterpret_cast(pOut)[0x08] = x3; - reinterpret_cast(pOut)[0x09] = y3; - reinterpret_cast(pOut)[0x0a] = z3; - reinterpret_cast(pOut)[0x0b] = 1.f; - - reinterpret_cast(pOut)[0x0c] = x2; - reinterpret_cast(pOut)[0x0d] = y2; - reinterpret_cast(pOut)[0x0e] = z2; - reinterpret_cast(pOut)[0x0f] = 1.f; - reinterpret_cast(pOut)[0x10] = x0; - reinterpret_cast(pOut)[0x11] = y0; - reinterpret_cast(pOut)[0x12] = z0; - reinterpret_cast(pOut)[0x13] = 1.f; - reinterpret_cast(pOut)[0x14] = x1; - reinterpret_cast(pOut)[0x15] = y1; - reinterpret_cast(pOut)[0x16] = z1; - reinterpret_cast(pOut)[0x17] = 1.f; - pOut += 0x18 * sizeof(float); - } - for (size_t c = 0, S = TriCount; c < S; c++) - { - const float x = *pTris++; - const float y = *pTris++; - const float z = *pTris++; - reinterpret_cast(pOut)[0x00] = x; - reinterpret_cast(pOut)[0x01] = y; - reinterpret_cast(pOut)[0x02] = z; - reinterpret_cast(pOut)[0x03] = 1.f; - pOut += 4 * sizeof(float); - } - } - m_OCMOffsetInstances = static_cast(pOut - &OCMBufferOut[0]); - const size_t InstanceSize = m_OCMInstCount * (sizeof(int) + 12 * sizeof(float)); - memcpy(pOut, pInstances, InstanceSize); - for (size_t a = 0; a < m_OCMInstCount; a++) - { - uint8* pInstance = pOut + a * (sizeof(int) + 12 * sizeof(float));//meshoffset+worldmatrix43 - uint32& MeshOffset = *reinterpret_cast(&pInstance[0]); - MeshOffset = Offsets[MeshOffset]; - } - pOut += InstanceSize; - - m_OCMBuffer.resize(pOut - &OCMBufferOut[0]); - size_t bufferOffset = reinterpret_cast(&m_OCMBuffer[0]); - bufferOffset = (bufferOffset + 15) & ~15; - m_pOCMBufferAligned = reinterpret_cast(bufferOffset); - memcpy(m_pOCMBufferAligned, &OCMBufferOut[0], m_OCMBuffer.size()); - } - - // Integrity check: each mesh data must be aligned to 4 bytes - uint8* pInstances = &m_pOCMBufferAligned[m_OCMOffsetInstances]; - for (size_t a = 0; a < m_OCMInstCount; a++) - { - uint8* pInstance = pInstances + a * (sizeof(int) + 12 * sizeof(float));//meshoffset+worldmatrix43 - uint32 MeshOffset = *reinterpret_cast(&pInstance[0]); - if (MeshOffset & 3) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "The occluder mesh contains invalid data. Please reexport the occluder mesh."); - stl::free_container(m_OCMBuffer); - return false; - } - } - - return true; - } - - void CCullThread::UnloadLevel() - { - stl::free_container(m_OCMBuffer); - m_pOCMBufferAligned = NULL; - - m_OCMMeshCount = 0; - m_OCMInstCount = 0; - m_OCMOffsetInstances = 0; - } - - void CCullThread::PrepareCullbufferAsync(const CCamera& rCamera) - { - Matrix44 MatProj; - Matrix44 MatView; - Matrix44 MatViewProj; - -#if !defined(_RELEASE) // debug code to catch double invocations of the prepare occlusion buffer job per frame - static int _debug = -1; - if (_debug == -1) - { - _debug = gEnv->pRenderer->GetFrameID(false); - } - else if (_debug == gEnv->pRenderer->GetFrameID(false)) - { - __debugbreak(); - } - else - { - _debug = gEnv->pRenderer->GetFrameID(false); - } -#endif - - const CCamera& rCam = rCamera; - - CCamera tmp_cam = m_pRenderer->GetCamera(); - m_pRenderer->SetCamera(rCam); - m_pRenderer->GetModelViewMatrix(reinterpret_cast(&MatView)); - m_pRenderer->GetProjectionMatrix(reinterpret_cast(&MatProj)); - m_pRenderer->SetCamera(tmp_cam); - - uint32 nReverseDepthEnabled = 0; - m_pRenderer->EF_Query(EFQ_ReverseDepthEnabled, nReverseDepthEnabled); - - if (nReverseDepthEnabled) // Convert to regular depth again. TODO: make occlusion culler work with reverse depth - { - MatProj.m22 = -MatProj.m22 + MatProj.m23; - MatProj.m32 = -MatProj.m32 + MatProj.m33; - } - - m_ViewDir = rCam.GetViewdir(); - MatViewProj = MatView * MatProj; - - MatViewProj.Transpose(); - - const float SCALEX = static_cast(CULL_SIZEX / 2); - const float SCALEY = static_cast(CULL_SIZEY / 2); - const Matrix44A MatScreen(SCALEX, 0.f, 0.f, SCALEX, - 0.f, -SCALEY, 0.f, SCALEY, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); - m_MatScreenViewProj = MatScreen * MatViewProj; - m_MatScreenViewProjTransposed = m_MatScreenViewProj.GetTransposed(); - m_NearPlane = rCam.GetNearPlane(); - m_FarPlane = rCam.GetFarPlane(); - m_NearestMax = m_pRenderer->GetNearestRangeMax(); - - m_Position = rCam.GetPosition(); - - HWZBuffer.ZBufferSizeX = CULL_SIZEX; - HWZBuffer.ZBufferSizeY = CULL_SIZEY; - - GetObjManager()->BeginCulling(); - - m_nPrepareState = PREPARE_STARTED; - m_Enabled = false; - m_bCheckOcclusionRequested = 0; - - RASTERIZER.Prepare(); - - m_PrepareBufferSync.PushCompletionFence(); - m_OcclusionJobExecutor.StartJob([this]() - { - this->PrepareOcclusion(); - }); // legacy: job.SetPriorityLevel(JobManager::eHighPriority); job.SetBlocking(); - } - - void CCullThread::CullStart(const SRenderingPassInfo& passInfo) - { - FUNCTION_PROFILER_3DENGINE; - - // signal rasterizer that it should stop - m_bCheckOcclusionRequested = 1; - - // tell the job that the PPU is ready for occlusion culling, this call will - // start the check occlusion job if the prepare step has finished, if not - // the prepare job itself will start the culling job - bool bNeedJobStart = false; - { - AUTO_LOCK(m_FollowUpLock); - if (m_nPrepareState == PREPARE_DONE) - { - m_nPrepareState = CHECK_STARTED; - bNeedJobStart = true; - } - else - { - m_nPrepareState = CHECK_REQUESTED; - *((SRenderingPassInfo*)m_passInfoForCheckOcclusion) = passInfo; - } - } - - if (bNeedJobStart) - { - m_OcclusionJobExecutor.StartJob([this, passInfo]() - { - this->CheckOcclusion(passInfo); - }); // legacy: job.SetPriorityLevel(JobManager::eHighPriority); - } - } - - void CCullThread::CullEnd(bool waitForOcclusionJobCompletion) - { - // If no frame was rendered, we need to remove the producer added in BeginCulling - m_PrepareBufferSync.WaitForCompletion(); - - bool bNeedRemoveProducer = false; - { - if (m_nPrepareState != CHECK_STARTED && m_nPrepareState != IDLE) - { - bNeedRemoveProducer = true; - } - } - - if (bNeedRemoveProducer) - { - GetObjManager()->RemoveCullJobProducer(); - m_nPrepareState = IDLE; // No producer so mark us as idle - } - - if (waitForOcclusionJobCompletion) - { - m_OcclusionJobExecutor.WaitForCompletion(); - } - - } - - void CCullThread::OutputMeshList() - { - } - - - float DistToBox(Vec3 Center, Vec3 Extends, Vec3 ViewPos) - { - Vec3 Delta = (ViewPos - Center).abs(); - Delta = (Delta - Extends); - Delta.x = max(Delta.x, 0.f); - Delta.y = max(Delta.y, 0.f); - Delta.z = max(Delta.z, 0.f); - return Delta.x * Delta.x + Delta.y * Delta.y + Delta.z * Delta.z; - } - - void CCullThread::RasterizeZBuffer(uint32 PolyLimit) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - if (m_OCMInstCount == 0) - { - float fRed[4] = {1, 0, 0, 1}; - gEnv->pRenderer->Draw2dLabel(1.0f, 5.0f, 1.6f, fRed, false, "OCM file failed to load -> no occlusion checking possible!"); - return; - } - - uint Tmp[16 * sizeof(float) * 2 + 16]; - const uint8* pMeshes = m_pOCMBufferAligned;//actually starts at 16, but MeshOffset is zero based - uint8* pInstances = &m_pOCMBufferAligned[m_OCMOffsetInstances]; - - Matrix44A& rTmp0 = *reinterpret_cast((reinterpret_cast(Tmp) + 15) & ~15); - Matrix44A& rTmp1 = *reinterpret_cast((reinterpret_cast(Tmp) + 15 + 64) & ~15); - rTmp0 = m_MatScreenViewProj.GetTransposed(); - - int Visible = 0; - int Invisible = 0; - uint32 Poly = 0; - float LastDist; - uint8* pLastInstance = 0; - - bool Swapped = true; - for (size_t c = 0; c < 20 && Swapped; c++)//incrementally (max 20 rounds) bubblesort instances front to back - { - Swapped = false; - LastDist = -1.f; - for (size_t a = 0; a < m_OCMInstCount; a++) - { - Matrix44 World(IDENTITY); - uint8* pInstance = pInstances + a * (sizeof(int) + 12 * sizeof(float));//meshoffset+worldmatrix43 - const uint32 MeshOffset = *reinterpret_cast(&pInstance[0]); - const float* pWorldMat = reinterpret_cast(&pInstance[4]); - memcpy(&World, (void*)pWorldMat, 12 * sizeof(float)); - - //simple incremental bubblesort - const float Dist = (World.GetTranslation() - m_Position).GetLength(); - if (Dist < LastDist) - { - PREFAST_ASSUME(pLastInstance); - Swapped = true; - for (size_t b = 0; b < 13; b++) - { - std::swap(reinterpret_cast(pLastInstance)[b], reinterpret_cast(pInstance)[b]); - } - } - - LastDist = Dist; - pLastInstance = pInstance; - } - } - - const bool EarlyOut = GetCVars()->e_CoverageBufferEarlyOut == 1; - const int64 MaxEarlyOutDelay = (int64)(GetCVars()->e_CoverageBufferEarlyOutDelay * 1000.0f); - LastDist = -1.f; - - ITimer* pTimer = gEnv->pTimer; - int64 StartTime = -1; - - for (size_t a = 0; a < m_OCMInstCount && (PolyLimit == 0 || Poly < PolyLimit); a++) - { - // stop if MT need to run check occlusion - if (EarlyOut && *const_cast(&m_bCheckOcclusionRequested)) - { - if (StartTime < 0) - { - StartTime = pTimer->GetAsyncTime().GetMicroSecondsAsInt64(); - } - - int64 CurTime = pTimer->GetAsyncTime().GetMicroSecondsAsInt64(); - if (CurTime - StartTime > MaxEarlyOutDelay) - { - break; - } - } - - Matrix44 World(IDENTITY); - uint8* pInstance = pInstances + a * (sizeof(int) + 12 * sizeof(float));//meshoffset+worldmatrix43 - const uint32 MeshOffset = *reinterpret_cast(&pInstance[0]); - const float* pWorldMat = reinterpret_cast(&pInstance[4]); - memcpy(&World, (void*)pWorldMat, 12 * sizeof(float)); - - Vec3 Pos = World.GetTranslation(), Extend; - Extend.x = (fabsf(World.m00) + fabsf(World.m01) + fabsf(World.m02)) * (127.f); - Extend.y = (fabsf(World.m10) + fabsf(World.m11) + fabsf(World.m12)) * (127.f); - Extend.z = (fabsf(World.m20) + fabsf(World.m21) + fabsf(World.m22)) * (127.f); - - const int InFrustum = RASTERIZER.AABBInFrustum(reinterpret_cast(&rTmp0), Pos - Extend, Pos + Extend, m_Position); - if (!InFrustum) - { - Invisible++; - continue; - } - else - { - Visible++; - } - - rTmp1 = (m_MatScreenViewProj * World).GetTransposed(); - const uint8* pMesh = pMeshes + MeshOffset; - const size_t TriCount = *reinterpret_cast(pMesh); - const size_t Tris16 = (reinterpret_cast(pMesh + 4) + 15) & ~15; - const int8* pTris = reinterpret_cast(Tris16); - if (InFrustum & 2) - { - RASTERIZER.Rasterize(reinterpret_cast(&rTmp1), reinterpret_cast(pTris), TriCount); - } - else - { - RASTERIZER.Rasterize(reinterpret_cast(&rTmp1), reinterpret_cast(pTris), TriCount); - } - Poly += TriCount; - } - } - -#if !defined(_RELEASE) - void CCullThread::CoverageBufferDebugDraw() - { - RASTERIZER.DrawDebug(m_pRenderer, 1); - } -#endif - - - void CCullThread::PrepareOcclusion() - { - if (!GetCVars()->e_CameraFreeze) - { - FUNCTION_PROFILER_3DENGINE; - using namespace NVMath; - - int bHWZBuffer = GetCVars()->e_CoverageBufferReproj; - - if (bHWZBuffer > 3 && m_OCMBuffer.empty()) - { - bHWZBuffer = 2; - } - - if ((bHWZBuffer & 3) > 0) - { - m_Enabled = RASTERIZER.DownLoadHWDepthBuffer(m_NearPlane, m_FarPlane, m_NearestMax, GetCVars()->e_CoverageBufferBias); - } - else - { - RASTERIZER.Clear(); - } - } - - m_OcclusionJobExecutor.StartJob([this]() - { - this->PrepareOcclusion_ReprojectZBuffer(); - }); // legacy: job.SetPriorityLevel(JobManager::eHighPriority); - } - - void CCullThread::PrepareOcclusion_ReprojectZBuffer() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - int bHWZBuffer = GetCVars()->e_CoverageBufferReproj; - - if (bHWZBuffer > 3 && m_OCMBuffer.empty()) - { - bHWZBuffer = 2; - } - - if (!GetCVars()->e_CameraFreeze && (bHWZBuffer & 3) > 0 && m_Enabled) - { - enum - { - nLinesPerJob = 8 - }; - m_nRunningReprojJobs = tdCullRasterizer::RESOLUTION_Y / nLinesPerJob; - m_nRunningReprojJobsAfterMerge = tdCullRasterizer::RESOLUTION_Y / nLinesPerJob; - for (int i = 0; i < tdCullRasterizer::RESOLUTION_Y; i += nLinesPerJob) - { - m_OcclusionJobExecutor.StartJob([this, i]() - { - this->PrepareOcclusion_ReprojectZBufferLine(i, nLinesPerJob); - }); // legacy: job.SetPriorityLevel(JobManager::eHighPriority); - } - } - else - { - m_OcclusionJobExecutor.StartJob([this]() - { - this->PrepareOcclusion_RasterizeZBuffer(); - }); // job.SetPriorityLevel(JobManager::eHighPriority); - } - } - - void CCullThread::PrepareOcclusion_ReprojectZBufferLine(int nStartLine, int nNumLines) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - if (!GetCVars()->e_CameraFreeze) - { - uint Tmp[80]; - Matrix44A& rTmp = *reinterpret_cast((reinterpret_cast(Tmp) + 15) & ~15); - rTmp = m_MatScreenViewProjTransposed; - RASTERIZER.ReprojectHWDepthBuffer(rTmp, m_NearPlane, m_FarPlane, m_NearestMax, GetCVars()->e_CoverageBufferBias, nStartLine, nNumLines); - } - - uint32 nRemainingJobs = CryInterlockedDecrement((volatile int*)&m_nRunningReprojJobs); - if (nRemainingJobs == 0) - { - enum - { - nLinesPerJob = 8 - }; - for (int i = 0; i < tdCullRasterizer::RESOLUTION_Y; i += nLinesPerJob) - { - m_OcclusionJobExecutor.StartJob([this, i]() - { - this->PrepareOcclusion_ReprojectZBufferLineAfterMerge(i, nLinesPerJob); - }); // job.SetPriorityLevel(JobManager::eHighPriority); - } - } - } - - void CCullThread::PrepareOcclusion_ReprojectZBufferLineAfterMerge(int nStartLine, int nNumLines) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - // merge the reprojected buffer bevore new jobs are started on it - RASTERIZER.MergeReprojectHWDepthBuffer(nStartLine, nNumLines); - - if (!GetCVars()->e_CameraFreeze) - { - uint Tmp[80]; - Matrix44A& rTmp = *reinterpret_cast((reinterpret_cast(Tmp) + 15) & ~15); - rTmp = m_MatScreenViewProjTransposed; - RASTERIZER.ReprojectHWDepthBufferAfterMerge(rTmp, m_NearPlane, m_FarPlane, m_NearestMax, GetCVars()->e_CoverageBufferBias, nStartLine, nNumLines); - } - - uint32 nRemainingJobs = CryInterlockedDecrement((volatile int*)&m_nRunningReprojJobsAfterMerge); - if (nRemainingJobs == 0) - { - m_OcclusionJobExecutor.StartJob([this]() - { - this->PrepareOcclusion_RasterizeZBuffer(); - }); //job.SetPriorityLevel(JobManager::eHighPriority); - } - } - - - void CCullThread::PrepareOcclusion_RasterizeZBuffer() - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - m_Enabled = true; - if (!GetCVars()->e_CameraFreeze) - { - int bHWZBuffer = GetCVars()->e_CoverageBufferReproj; - int PolyLimit = GetCVars()->e_CoverageBufferRastPolyLimit; - - if (bHWZBuffer > 3 && m_OCMBuffer.empty()) - { - bHWZBuffer = 2; - } - - bool rast_z_buff = (bHWZBuffer & 4) ? true : false; - if (rast_z_buff) - { - m_Enabled = true; - RasterizeZBuffer((uint32)PolyLimit); - } - } - - bool bNeedJobStart = false; - { - AUTO_LOCK(m_FollowUpLock); - if (m_nPrepareState == CHECK_REQUESTED) - { - m_nPrepareState = CHECK_STARTED; - bNeedJobStart = true; - } - else - { - m_nPrepareState = PREPARE_DONE; - } - } - - m_PrepareBufferSync.PopCompletionFence(); - if (bNeedJobStart) - { - m_OcclusionJobExecutor.StartJob([this]() - { - this->CheckOcclusion(*reinterpret_cast(m_passInfoForCheckOcclusion)); - }); // legacy: job.SetPriorityLevel(JobManager::eHighPriority) - } - } - - void CCullThread::CheckOcclusion(SRenderingPassInfo passInfo) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - uint8 AlignBuffer[2 * sizeof(Matrix44A) + 16]; - size_t pBuffer = (reinterpret_cast(AlignBuffer) + 15) & ~15; - Matrix44A& RESTRICT_REFERENCE rMatFinalT = reinterpret_cast(pBuffer)[1]; - - - Vec3 localPostion; - memcpy(&localPostion, &m_Position, sizeof(Vec3)); - - const AABB PosAABB = AABB(m_Position, 0.5f); - const float Bias = GetCVars()->e_CoverageBufferAABBExpand; - rMatFinalT = m_MatScreenViewProj.GetTransposed(); - - // Debugging stats in green to screen here with how many octree nodes pass/fail and how many terrain nodes pass/fail - unsigned int octreeNodesCulled = 0; - unsigned int octreeNodesVisible = 0; - while (1) - { - SCheckOcclusionJobData jobData; - GetObjManager()->PopFromCullQueue(&jobData); - - // stop processing when beeing told so - if (jobData.type == SCheckOcclusionJobData::QUIT) - { - break; - } - - if (jobData.type == SCheckOcclusionJobData::OCTREE_NODE) - { - AABB rAABB; - COctreeNode* pOctTreeNode = (COctreeNode*)jobData.octTreeData.pOctTreeNode; - - memcpy(&rAABB, &pOctTreeNode->GetObjectsBBox(), sizeof(AABB)); - float fDistance = sqrtf(Distance::Point_AABBSq(passInfo.GetCamera().GetPosition(), rAABB)); - - // Test OctTree BoundingBox - if (TestAABB(rAABB, fDistance)) - { - pOctTreeNode->COctreeNode::RenderContent(jobData.octTreeData.nRenderMask, passInfo, jobData.rendItemSorter, jobData.pCam); - octreeNodesVisible++; - } - else - { - octreeNodesCulled++; - } - } - else - { - __debugbreak(); // unknown culler job type - } - } - - if (GetCVars()->e_CoverageBufferDebug) - { - float fGreen[4] = {0, 1, 0, 1}; - gEnv->pRenderer->Draw2dLabel(16.0f, 32.0f, 1.6f, fGreen, false, AZStd::string::format("Octree Nodes Culled %i, Octree Nodes Visible %i",octreeNodesCulled, octreeNodesVisible).c_str()); - } - - GetObjManager()->RemoveCullJobProducer(); - } - - /////////////////////////////////////////////////////////////////////////////// - bool CCullThread::TestAABB(const AABB& rAABB, float fEntDistance, float fVerticalExpand) - { - IF (GetCVars()->e_CheckOcclusion == 0, 0) - { - return true; - } - - const AABB PosAABB = AABB(m_Position, 0.5f); - const float Bias = GetCVars()->e_CoverageBufferAABBExpand; - DEFINE_ALIGNED_DATA(Matrix44A, rMatFinalT(m_MatScreenViewProj.GetTransposed()), 16); - AABB bbox(rAABB); - - if (Bias < 0.f) - { - bbox.Expand((bbox.max - bbox.min) * -Bias - Vec3(Bias, Bias, Bias)); - } - else - { - bbox.Expand(Vec3(Bias * fEntDistance)); - } - - float fVerticalExpandScaled = fVerticalExpand * fEntDistance; - bbox.min.z -= fVerticalExpandScaled; - bbox.max.z += fVerticalExpandScaled; - - if (!m_Enabled) - { - return true; - } - - if (bbox.IsIntersectBox(PosAABB)) - { - return true; - } - - if (RASTERIZER.TestAABB(reinterpret_cast(&rMatFinalT), bbox.min, bbox.max, m_Position)) - { - return true; - } - - return false; - } - - bool CCullThread::TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) - { - IF (GetCVars()->e_CheckOcclusion == 0, 0) - { - return true; - } - - if (!m_Enabled) - { - return true; - } - - DEFINE_ALIGNED_DATA(Matrix44A, rMatFinalT(m_MatScreenViewProj.GetTransposed()), 16); - if (RASTERIZER.TestQuad(reinterpret_cast(&rMatFinalT), vCenter, vAxisX, vAxisY)) - { - return true; - } - - return false; - } -} // namespace NAsyncCull - - diff --git a/Code/CryEngine/Cry3DEngine/CCullThread.h b/Code/CryEngine/Cry3DEngine/CCullThread.h deleted file mode 100644 index a1eaee7dc9..0000000000 --- a/Code/CryEngine/Cry3DEngine/CCullThread.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CCULLTHREAD_H -#define CRYINCLUDE_CRY3DENGINE_CCULLTHREAD_H -#pragma once - -#include "CryThread.h" -#include - -namespace NAsyncCull -{ - class CCullThread - : public Cry3DEngineBase - { - bool m_Enabled; - bool m_Active; // used to verify that the cull job is running and no new jobs are added after the job has finished - - public: - enum PrepareStateT - { - IDLE, PREPARE_STARTED, PREPARE_DONE, CHECK_REQUESTED, CHECK_STARTED - }; - - PrepareStateT m_nPrepareState; - CryCriticalSection m_FollowUpLock; - char m_passInfoForCheckOcclusion[sizeof(SRenderingPassInfo)]; - uint32 m_nRunningReprojJobs; - uint32 m_nRunningReprojJobsAfterMerge; - int m_bCheckOcclusionRequested; - - private: - AZ::LegacyJobExecutor m_OcclusionJobExecutor; // All jobs pushed against this instance to gurantee a wait on all jobs before exiting ~CCullThread - AZ::LegacyJobExecutor m_PrepareBufferSync; - Matrix44A m_MatScreenViewProj _ALIGN(16); - Matrix44A m_MatScreenViewProjTransposed; - Vec3 m_ViewDir; - Vec3 m_Position; - float m_NearPlane; - float m_FarPlane; - float m_NearestMax; - - PodArray m_OCMBuffer; - uint8* m_pOCMBufferAligned; - uint32 m_OCMMeshCount; - uint32 m_OCMInstCount; - uint32 m_OCMOffsetInstances; - - template - T Swap(T& rData) - { - // #if IS_LOCAL_MACHINE_BIG_ENDIAN - PREFAST_SUPPRESS_WARNING(6326) - switch (sizeof(T)) - { - case 1: - break; - case 2: - SwapEndianBase(reinterpret_cast(&rData)); - break; - case 4: - SwapEndianBase(reinterpret_cast(&rData)); - break; - case 8: - SwapEndianBase(reinterpret_cast(&rData)); - break; - default: -#if defined(__clang__) || defined(__GNUC__) - __builtin_unreachable(); -#else - __assume(0); -#endif - } - //#endif - return rData; - } - - void RasterizeZBuffer(uint32 PolyLimit); - void OutputMeshList(); - - public: - - void CheckOcclusion(SRenderingPassInfo passInfo); - void PrepareOcclusion(); - - void PrepareOcclusion_RasterizeZBuffer(); - void PrepareOcclusion_ReprojectZBuffer(); - void PrepareOcclusion_ReprojectZBufferLine(int nStartLine, int nNumLines); - void PrepareOcclusion_ReprojectZBufferLineAfterMerge(int nStartLine, int nNumLines); - void Init(); - - bool LoadLevel(const char* pFolderName); - void UnloadLevel(); - - bool TestAABB(const AABB& rAABB, float fEntDistance, float fVerticalExpand = 0.0f); - bool TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY); - - CCullThread(); - ~CCullThread() = default; - - -#ifndef _RELEASE - void CoverageBufferDebugDraw(); -#endif - - void PrepareCullbufferAsync(const CCamera& rCamera); - void CullStart(const SRenderingPassInfo& passInfo); - void CullEnd(bool waitForOcclusionJobCompletion = false); - - bool IsActive() const { return m_Active; } - void SetActive(bool bActive) { m_Active = bActive; } - - Vec3 GetViewDir() { return m_ViewDir; }; - } _ALIGN(128); -} - -#endif // CRYINCLUDE_CRY3DENGINE_CCULLTHREAD_H - diff --git a/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.cpp b/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.cpp deleted file mode 100644 index f8f7d8df04..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.cpp +++ /dev/null @@ -1,4336 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "CGFLoader.h" - -#include -#include -#include "CryPath.h" -#include "ReadOnlyChunkFile.h" -#include "IStatObj.h" - -// #define DEBUG_DUMP_RBATCHES -#define VERTEX_SCALE (0.01f) -#define PHYSICS_PROXY_NODE "PhysicsProxy" -#define PHYSICS_PROXY_NODE2 "$collision" -#define PHYSICS_PROXY_NODE3 "$physics_proxy" -enum -{ - MAX_NUMBER_OF_BONES = 65534 -}; - -#if !defined(FUNCTION_PROFILER_3DENGINE) -#define FUNCTION_PROFILER_3DENGINE -#endif - -#if !defined(LOADING_TIME_PROFILE_SECTION) -#define LOADING_TIME_PROFILE_SECTION -#endif - -#ifndef ARRAY_LENGTH -# define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0])) -#endif - - -namespace -{ - // Templated construct helper function using an inplace factory - // - // Called from the templated New function below. Returns a typed - // pointer to the inplace constructed object. - template - T* Construct( - const InPlaceFactory& factory, - void* (*pAllocFnc)(size_t)) - { - return reinterpret_cast(factory.template apply(pAllocFnc(sizeof(T)))); - } - - // Templated construct helper function using an inplace factory - // - // Called from the templated New function below. Returns a typed - // pointer to the inplace constructed object. - template - T* Construct(void* (*pAllocFnc)(size_t)) - { - return new (pAllocFnc(sizeof(T)))T; - } - - // Templated destruct helper function - // - // Calls the object's destructor and returns a void pointer to the storage - template - void Destruct(T* obj, void(*pDestructFnc)(void*)) - { - obj->~T(); - pDestructFnc(reinterpret_cast(obj)); - } -} - -////////////////////////////////////////////////////////////////////////// -CLoaderCGF::CLoaderCGF( - AllocFncPtr pAllocFnc, - DestructFncPtr pDestructFnc, - bool bAllowStreamSharing) - : m_pAllocFnc(pAllocFnc) - , m_pDestructFnc(pDestructFnc) -{ - m_pChunkFile = NULL; - - ////////////////////////////////////////////////////////////////////////// - // To find really used materials - memset(MatIdToSubset, 0, sizeof(MatIdToSubset)); - nLastChunkId = 0; - ////////////////////////////////////////////////////////////////////////// - - m_bUseReadOnlyMesh = false; - - m_bAllowStreamSharing = bAllowStreamSharing; - - m_pCompiledCGF = 0; - - m_maxWeightsPerVertex = 4; -} - -////////////////////////////////////////////////////////////////////////// -CLoaderCGF::~CLoaderCGF() -{ -} - -////////////////////////////////////////////////////////////////////////// -CContentCGF* CLoaderCGF::LoadCGF(const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags) -{ - CContentCGF* const pContentCGF = new CContentCGF(filename); - if (!pContentCGF) - { - return NULL; - } - if (!LoadCGF(pContentCGF, filename, chunkFile, pListener, nLoadingFlags)) - { - delete pContentCGF; - return NULL; - } - return pContentCGF; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadCGF(CContentCGF* pContentCGF, const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!chunkFile.IsLoaded()) - { - if (!chunkFile.Read(filename)) - { - m_LastError = chunkFile.GetLastError(); - return false; - } - } - - if (gEnv) - { - //Update loading screen and important tick functions - SYNCHRONOUS_LOADING_TICK(); - } - - return LoadCGFWork(pContentCGF, filename, chunkFile, pListener, nLoadingFlags); -} - -bool CLoaderCGF::LoadCGFFromMem(CContentCGF* pContentCGF, const void* pData, size_t nDataLen, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!chunkFile.IsLoaded()) - { - if (!chunkFile.ReadFromMemory(pData, (int)nDataLen)) - { - m_LastError = chunkFile.GetLastError(); - return false; - } - } - - if (gEnv) - { - //Update loading screen and important tick functions - SYNCHRONOUS_LOADING_TICK(); - } - - return LoadCGFWork(pContentCGF, pContentCGF->GetFilename(), chunkFile, pListener, nLoadingFlags); -} - -bool CLoaderCGF::LoadCGFWork(CContentCGF* pContentCGF, const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags) -{ - m_pListener = pListener; - m_bUseReadOnlyMesh = chunkFile.IsReadOnly(); - - cry_strcpy(m_filename, filename); - m_pChunkFile = &chunkFile; - - // Load mesh from chunk file. - - if (!pContentCGF) - { - m_LastError.Format("no valid CContentCGF instance for cgf file: %s", m_filename); - return false; - } - m_pCGF = pContentCGF; - - { - const char* const pExt = PathUtil::GetExt(filename); - m_IsCHR = - !azstricmp(pExt, "chr") || - !azstricmp(pExt, "chrp") || - !azstricmp(pExt, "chrm") || - !azstricmp(pExt, "skin") || - !azstricmp(pExt, "skinp") || - !azstricmp(pExt, "skinm") || - !azstricmp(pExt, "skel"); - } - - const bool bJustGeometry = (nLoadingFlags& IStatObj::ELoadingFlagsJustGeometry) != 0; - - if (!LoadChunks(bJustGeometry)) - { - return false; - } - - for (int i = 0; i < m_pChunkFile->NumChunks(); i++) - { - if (m_pChunkFile->GetChunk(i)->bSwapEndian) - { - m_pCGF->m_bConsoleFormat = true; - break; - } - } - - if (!bJustGeometry) - { - if (m_pCGF->GetMaterialCount() > 0) - { - m_pCGF->SetCommonMaterial(m_pCGF->GetMaterial(0)); - } - } - - ProcessNodes(); - - if (gEnv) - { - SYNCHRONOUS_LOADING_TICK(); - } - - if (!bJustGeometry) - { - if (!ProcessSkinning()) - { - return false; - } - } - - if (pListener && pListener->IsValidationEnabled()) - { - const char* pErrorDescription = 0; - if (!m_pCGF->ValidateMeshes(&pErrorDescription)) - { - Warning( - "!Invalid meshes (%s) found in file: %s\n" - "The file is corrupt (possibly generated with old/buggy RC) -- please re-export it with newest RC", - pErrorDescription, m_filename); - } - } - - m_pListener = 0; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadChunks(bool bJustGeometry) -{ - LOADING_TIME_PROFILE_SECTION; - - m_CompiledBones = false; - m_CompiledMesh = 0; - m_CompiledBonesBoxes = false; - - m_numBonenameList = 0; - m_numBoneInitialPos = 0; - m_numMorphTargets = 0; - m_numBoneHierarchy = 0; - - // Load Nodes. - const uint32 numChunk = m_pChunkFile->NumChunks(); - m_pCGF->GetSkinningInfo()->m_arrPhyBoneMeshes.clear(); - m_pCGF->GetSkinningInfo()->m_numChunks = numChunk; - - for (uint32 i = 0; i < numChunk; i++) - { - IChunkFile::ChunkDesc* const pChunkDesc = m_pChunkFile->GetChunk(i); - - if (!bJustGeometry) - { - if (m_IsCHR) - { - switch (pChunkDesc->chunkType) - { - case ChunkType_BoneNameList: - m_numBonenameList++; - if (!ReadBoneNameList(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_BoneInitialPos: - m_numBoneInitialPos++; - if (!ReadBoneInitialPos(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_BoneAnim: - m_numBoneHierarchy++; - if (!ReadBoneHierarchy(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_BoneMesh: - if (!ReadBoneMesh(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_MeshMorphTarget: - m_numMorphTargets++; - if (!ReadMorphTargets(pChunkDesc)) - { - return false; - } - break; - - //--------------------------------------------------------- - //--- chunks for compiled characters ---- - //--------------------------------------------------------- - - case ChunkType_CompiledBones: - if (!ReadCompiledBones(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_CompiledPhysicalBones: - if (!ReadCompiledPhysicalBones(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_CompiledPhysicalProxies: - if (!ReadCompiledPhysicalProxies(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_CompiledMorphTargets: - if (!ReadCompiledMorphTargets(pChunkDesc)) - { - return false; - } - break; - - - case ChunkType_CompiledIntFaces: - if (!ReadCompiledIntFaces(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_CompiledIntSkinVertices: - if (!ReadCompiledIntSkinVertice(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_CompiledExt2IntMap: - if (!ReadCompiledExt2IntMap(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_BonesBoxes: - if (!ReadCompiledBonesBoxes(pChunkDesc)) - { - return false; - } - break; - } - } - - switch (pChunkDesc->chunkType) - { - //--------------------------------------------------------- - //--- chunks for CGA-objects ----------------------- - //--------------------------------------------------------- - - case ChunkType_ExportFlags: - if (!LoadExportFlagsChunk(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_Node: - if (!LoadNodeChunk(pChunkDesc, false)) - { - return false; - } - break; - - case ChunkType_MtlName: - if (!LoadMaterialFromChunk(pChunkDesc->chunkId)) - { - return false; - } - break; - - case ChunkType_BreakablePhysics: - if (!ReadCompiledBreakablePhysics(pChunkDesc)) - { - return false; - } - break; - - case ChunkType_FoliageInfo: - if (!LoadFoliageInfoChunk(pChunkDesc)) - { - return false; - } - break; - } - } - else - { - switch (pChunkDesc->chunkType) - { - case ChunkType_Node: - if (!LoadNodeChunk(pChunkDesc, true)) - { - return false; - } - break; - } - } - } - - return true; -} - - - -bool CLoaderCGF::ReadBoneInitialPos(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->chunkVersion != BONEINITIALPOS_CHUNK_DESC_0001::VERSION) - { - m_LastError.Format("BoneInitialPos chunk is of unknown version %d", pChunkDesc->chunkVersion); - return false; - } - - BONEINITIALPOS_CHUNK_DESC_0001* const pBIPChunk = (BONEINITIALPOS_CHUNK_DESC_0001*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pBIPChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - const uint32 numBones = pBIPChunk->numBones; - - SBoneInitPosMatrix* const pDefMatrix = (SBoneInitPosMatrix*)(pBIPChunk + 1); - SwapEndian(pDefMatrix, numBones, bSwapEndianness); - - m_arrInitPose34.resize(numBones, IDENTITY); - for (uint32 nBone = 0; nBone < numBones; ++nBone) - { - m_arrInitPose34[nBone].m00 = pDefMatrix[nBone].mx[0][0]; - m_arrInitPose34[nBone].m01 = pDefMatrix[nBone].mx[1][0]; - m_arrInitPose34[nBone].m02 = pDefMatrix[nBone].mx[2][0]; - m_arrInitPose34[nBone].m03 = pDefMatrix[nBone].mx[3][0] * VERTEX_SCALE; - m_arrInitPose34[nBone].m10 = pDefMatrix[nBone].mx[0][1]; - m_arrInitPose34[nBone].m11 = pDefMatrix[nBone].mx[1][1]; - m_arrInitPose34[nBone].m12 = pDefMatrix[nBone].mx[2][1]; - m_arrInitPose34[nBone].m13 = pDefMatrix[nBone].mx[3][1] * VERTEX_SCALE; - m_arrInitPose34[nBone].m20 = pDefMatrix[nBone].mx[0][2]; - m_arrInitPose34[nBone].m21 = pDefMatrix[nBone].mx[1][2]; - m_arrInitPose34[nBone].m22 = pDefMatrix[nBone].mx[2][2]; - m_arrInitPose34[nBone].m23 = pDefMatrix[nBone].mx[3][2] * VERTEX_SCALE; - m_arrInitPose34[nBone].OrthonormalizeFast(); // for some reason Max supplies unnormalized matrices. - } - - return true; -} - - -////////////////////////////////////////////////////////////////////////// - -bool CLoaderCGF::ReadMorphTargets(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - -#if !defined(RESOURCE_COMPILER) - m_LastError.Format("%s tried to load a noncompiled MeshMorphTarget chunk %i", __FUNCTION__, (int)pChunkDesc->chunkId); - return false; -#else - if (pChunkDesc->chunkVersion != MESHMORPHTARGET_CHUNK_DESC_0001::VERSION) - { - m_LastError.Format("MeshMorphTarget chunk %i is of unknown version %i", (int)pChunkDesc->chunkId, (int)pChunkDesc->chunkVersion); - return false; - } - - // the chunk must at least contain its header and the name (min 2 bytes) - if (pChunkDesc->size <= sizeof(MESHMORPHTARGET_CHUNK_DESC_0001)) - { - m_LastError.Format("MeshMorphTarget chunk %i: Bad size: %i", (int)pChunkDesc->chunkId, (int)pChunkDesc->size); - return false; - } - - if (m_vertexOldToNew.empty()) - { - m_LastError.Format("MeshMorphTarget chunk %i: main mesh was not loaded yet or its type is not Skin.", (int)pChunkDesc->chunkId); - return false; - } - - MESHMORPHTARGET_CHUNK_DESC_0001* const pMeshMorphTarget = (MESHMORPHTARGET_CHUNK_DESC_0001*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pMeshMorphTarget, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - const uint32 oldVertexCount = pMeshMorphTarget->numMorphVertices; - if (oldVertexCount <= 0) - { - m_LastError.Format("MeshMorphTarget chunk %i: Bad # of vertices: %i", (int)pChunkDesc->chunkId, (int)oldVertexCount); - return false; - } - - if (oldVertexCount > m_vertexOldToNew.size()) - { - m_LastError.Format("MeshMorphTarget chunk %i: bad # of morph target vertices: %i (# of entries in the remapping table is %i).", (int)pChunkDesc->chunkId, (int)oldVertexCount, (int)m_vertexOldToNew.size()); - return false; - } - - SMeshMorphTargetVertex* const pSrcVertices = (SMeshMorphTargetVertex*)(pMeshMorphTarget + 1); - SwapEndian(pSrcVertices, (size_t)oldVertexCount, bSwapEndianness); - - // Remap vertices to match main mesh's remapping - - for (uint32 i = 0; i < oldVertexCount; ++i) - { - const unsigned oldIdx = pSrcVertices[i].nVertexId; - if (oldIdx >= m_vertexOldToNew.size()) - { - m_LastError.Format("MeshMorphTarget chunk %i: bad vertex index (%u) at element %u", (int)pChunkDesc->chunkId, oldIdx, (unsigned)i); - return false; - } - - const int newIdx = m_vertexOldToNew[oldIdx]; - if (newIdx < 0) - { - m_LastError.Format("MeshMorphTarget chunk %i: bad remapping value (%i) at element %u", (int)pChunkDesc->chunkId, (int)newIdx, (unsigned)i); - return false; - } - - pSrcVertices[i].nVertexId = (unsigned)newIdx; - } - - // Get rid of duplicated entries and also sort in ascending order of vertex indices - - struct CompareByVertexIndex - { - static bool less(const SMeshMorphTargetVertex& left, const SMeshMorphTargetVertex& right) - { - return left.nVertexId < right.nVertexId; - } - }; - - std::sort(&pSrcVertices[0], &pSrcVertices[oldVertexCount], CompareByVertexIndex::less); - - uint32 newVertexCount = 0; - for (uint32 i = 0; i < oldVertexCount; ++i) - { - if (i == 0 || CompareByVertexIndex::less(pSrcVertices[i - 1], pSrcVertices[i])) - { - pSrcVertices[newVertexCount++] = pSrcVertices[i]; - } - } - - // Form results - - MorphTargets* const pMT = new MorphTargets; - - //store the mesh ID - pMT->MeshID = pMeshMorphTarget->nChunkIdMesh; - //store the name of morph-target - const char* pName = (const char*)(pSrcVertices + oldVertexCount); - pMT->m_strName = "#" + string(pName); - //store the vertices&indices of morph-target - pMT->m_arrIntMorph.resize(newVertexCount); - memcpy(&pMT->m_arrIntMorph[0], pSrcVertices, sizeof(SMeshMorphTargetVertex) * newVertexCount); - - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrMorphTargets.push_back(pMT); - - return true; -#endif -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadBoneNameList(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->chunkVersion != BONENAMELIST_CHUNK_DESC_0745::VERSION) - { - m_LastError.Format("Unknown version of bone name list chunk"); - return false; - } - - // the chunk contains variable-length packed strings following tightly each other - BONENAMELIST_CHUNK_DESC_0745* pNameChunk = (BONENAMELIST_CHUNK_DESC_0745*)(pChunkDesc->data); - SwapEndian(*pNameChunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - const uint32 nGeomBones = pNameChunk->numEntities; - - // we know how many strings there are there; note that the whole bunch - // of strings may be followed by padding zeros - m_arrBoneNameTable.resize(nGeomBones, ""); - - // scan through all the strings (strings are zero-terminated) - const char* const pNameListEnd = ((const char*)pNameChunk) + pChunkDesc->size; - const char* pName = (const char*)(pNameChunk + 1); - uint32 numNames = 0; - while (*pName && pName < pNameListEnd && numNames < nGeomBones) - { - m_arrBoneNameTable[numNames] = pName; - pName += m_arrBoneNameTable[numNames].size() + 1; - numNames++; - } - if (numNames < nGeomBones) - { - m_LastError.Format("inconsistent bone name list chunk: only %d out of %d bone names have been read.", numNames, nGeomBones); - return false; - } - - return true; -} - - - -///////////////////////////////////////////////////////////////////////////////////// -// loads the root bone (and the hierarchy) and returns true if loaded successfully -// this gets called only for LOD 0 -///////////////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadBoneHierarchy(IChunkFile::ChunkDesc* pChunkDesc) -{ - if (pChunkDesc->chunkVersion != BONEANIM_CHUNK_DESC_0290::VERSION) - { - m_LastError.Format("Unknown version of bone hierarchy chunk"); - return false; - } - - CSkinningInfo* pSkinningInfo = m_pCGF->GetSkinningInfo(); - - BONEANIM_CHUNK_DESC_0290* pChunk = (BONEANIM_CHUNK_DESC_0290*)(pChunkDesc->data); - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - m_pBoneAnimRawData = 0; - - if (pChunk->nBones <= 0) - { - m_LastError = "There must be at least one bone."; - return false; - } - - if (pChunkDesc->size < sizeof(*pChunk) || - pChunk->nBones != (pChunkDesc->size - sizeof(*pChunk)) / sizeof(BONE_ENTITY)) - { - m_LastError = "Corrupted bone hierarchy chunk data."; - } - - m_pBoneAnimRawData = pChunk + 1; - m_pBoneAnimRawDataEnd = ((const char*)pChunk) + pChunkDesc->size; - - BONE_ENTITY* const pBones = (BONE_ENTITY*)m_pBoneAnimRawData; - - for (int i = 0; i < pChunk->nBones; ++i) - { - SwapEndian(pBones[i], bSwapEndianness); - } - - if (pBones[0].ParentID != -1) - { - m_LastError = "The first bone in the hierarchy has a parent, but the first none expected to be the root bone."; - return false; - } - - /* - for (int i = 1; i < pChunk->nBones; ++i) - { - if (pBones[i].ParentID == -1) - { - m_LastError = "The skeleton has multiple roots. Only single-rooted skeletons are supported in this version."); - return false; - } - } - */ - - pSkinningInfo->m_arrBonesDesc.resize(pChunk->nBones); - CryBoneDescData zeroBone; - memset(&zeroBone, 0, sizeof(zeroBone)); - std::fill(pSkinningInfo->m_arrBonesDesc.begin(), pSkinningInfo->m_arrBonesDesc.end(), zeroBone); - m_arrIndexToId.resize(pChunk->nBones, ~0); - m_arrIdToIndex.resize(pChunk->nBones, ~0); - - m_nNextBone = 1; - assert(m_nNextBone <= pChunk->nBones); - - m_numBones = 0; - - for (int i = 0; i < pChunk->nBones; ++i) - { - if (pBones[i].ParentID == -1) - { - const int nRootBoneIndex = i; - m_nNextBone = nRootBoneIndex + 1; - RecursiveBoneLoader(nRootBoneIndex, nRootBoneIndex); - } - } - assert(pChunk->nBones == m_numBones); - - //----------------------------------------------------------------------------- - //--- read physical information --- - //----------------------------------------------------------------------------- - pSkinningInfo->m_arrBoneEntities.resize(pChunk->nBones); - - int32 test = 0; - for (int i = 0; i < pChunk->nBones; ++i) - { - pSkinningInfo->m_arrBoneEntities[i] = pBones[i]; - test |= pBones[i].phys.nPhysGeom; - } - return true; -} - - - - -// loads the whole hierarchy of bones, using the state machine -// when this function is called, the bone is already allocated -uint32 CLoaderCGF::RecursiveBoneLoader(int nBoneParentIndex, int nBoneIndex) -{ - m_numBones++; - CSkinningInfo* pSkinningInfo = m_pCGF->GetSkinningInfo(); - - BONE_ENTITY* pEntity = (BONE_ENTITY*)m_pBoneAnimRawData; - SwapEndian(*pEntity); - m_pBoneAnimRawData = ((uint8*)m_pBoneAnimRawData) + sizeof(BONE_ENTITY); - - // initialize the next bone - CryBoneDescData& rBoneDesc = pSkinningInfo->m_arrBonesDesc[nBoneIndex]; - //read bone info - - CopyPhysInfo(rBoneDesc.m_PhysInfo[0], pEntity->phys); - int nFlags = 0; - if (pEntity->prop[0]) - { - nFlags = joint_no_gravity | joint_isolated_accelerations; - } - else - { - if (!CryStringUtils::strnstr(pEntity->prop, "gravity", sizeof(pEntity->prop))) - { - nFlags |= joint_no_gravity; - } - if (!CryStringUtils::strnstr(pEntity->prop, "active_phys", sizeof(pEntity->prop))) - { - nFlags |= joint_isolated_accelerations; - } - } - (rBoneDesc.m_PhysInfo[0].flags &= ~(joint_no_gravity | joint_isolated_accelerations)) |= nFlags; - - //get bone info - rBoneDesc.m_nControllerID = pEntity->ControllerID; - - // set the mapping entries - m_arrIndexToId[nBoneIndex] = pEntity->BoneID; - m_arrIdToIndex[pEntity->BoneID] = nBoneIndex; - - rBoneDesc.m_nOffsetParent = nBoneParentIndex - nBoneIndex; - - // load children - if (pEntity->nChildren) - { - int nChildrenIndexBase = m_nNextBone; - m_nNextBone += pEntity->nChildren; - if (nChildrenIndexBase < 0) - { - return 0; - } - // load the children - rBoneDesc.m_numChildren = pEntity->nChildren; - rBoneDesc.m_nOffsetChildren = nChildrenIndexBase - nBoneIndex; - for (int nChild = 0; nChild < pEntity->nChildren; ++nChild) - { - if (!RecursiveBoneLoader(nBoneIndex, nChildrenIndexBase + nChild)) - { - return 0; - } - } - } - else - { - rBoneDesc.m_numChildren = 0; - rBoneDesc.m_nOffsetChildren = 0; - } - return m_numBones; -} - - -namespace -{ - struct BoneVertex - { - Vec3 pos; - int matId; - int faceIndex; - int cornerIndex; - }; - - struct BoneVertexComparator - { - bool operator()(const BoneVertex& v0, const BoneVertex& v1) const - { - int res = memcmp(&v0.pos, &v1.pos, sizeof(v0.pos)); - // The 'if' block below prevents sharing vertices between faces with different materials. - // Note: you can comment the block out to enable sharing and decreases # of resulting - // vertices in case of multi-material geometry. - if (res == 0) - { - res = v0.matId - v1.matId; - } - return res < 0; - } - }; -} - - -static bool CompactBoneVertices( - DynArray& outArrPositions, - DynArray& outArrMaterials, - DynArray& outArrIndices, - const int inVertexCount, - const CryVertex* const inVertices, - const int inFaceCount, - const CryFace* const inFaces) -{ - outArrPositions.clear(); - outArrMaterials.clear(); - outArrIndices.clear(); - - DynArray verts; - verts.reserve(inFaceCount * 3); - - outArrMaterials.reserve(inFaceCount); - - for (int i = 0; i < inFaceCount; ++i) - { - outArrMaterials.push_back(inFaces[i].MatID); - - for (int j = 0; j < 3; ++j) - { - const int vIdx = inFaces[i][j]; - if (vIdx < 0 || vIdx >= inVertexCount) - { - return false; - } - BoneVertex v; - v.pos = inVertices[vIdx].p; - v.matId = inFaces[i].MatID; - v.faceIndex = i; - v.cornerIndex = j; - verts.push_back(v); - } - } - - std::sort(verts.begin(), verts.end(), BoneVertexComparator()); - - outArrPositions.reserve(inVertexCount); // preallocating by using a good enough guess - outArrIndices.resize(3 * inFaceCount, -1); - - int outVertexCount = 0; - for (int i = 0; i < verts.size(); ++i) - { - if (i == 0 || BoneVertexComparator()(verts[i - 1], verts[i])) - { - outArrPositions.push_back(verts[i].pos); - ++outVertexCount; - if (outVertexCount > (1 << 16)) - { - return false; - } - } - outArrIndices[verts[i].faceIndex * 3 + verts[i].cornerIndex] = outVertexCount - 1; - } - - // Making sure that the code above has no bugs - for (int i = 0; i < outArrIndices.size(); ++i) - { - if (outArrIndices[i] < 0) - { - return false; - } - } - - return true; -} - - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadBoneMesh(IChunkFile::ChunkDesc* pChunkDesc) -{ - if (pChunkDesc->chunkVersion != MESH_CHUNK_DESC_0745::VERSION && - pChunkDesc->chunkVersion != MESH_CHUNK_DESC_0745::COMPATIBLE_OLD_VERSION) - { - m_LastError.Format( - "Unknown version (0x%x) of BoneMesh chunk. The only supported versions are 0x%x and 0x%x.", - (uint)pChunkDesc->chunkVersion, - (uint)MESH_CHUNK_DESC_0745::VERSION, - (uint)MESH_CHUNK_DESC_0745::COMPATIBLE_OLD_VERSION); - return false; - } - - if (pChunkDesc->size < sizeof(MESH_CHUNK_DESC_0745)) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Bad chunk size"); - return false; - } - - MESH_CHUNK_DESC_0745* const pMeshChunk = (MESH_CHUNK_DESC_0745*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pMeshChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - if (pMeshChunk->nVerts <= 0) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Bad vertex count (%d)", pMeshChunk->nVerts); - return false; - } - if (pMeshChunk->nFaces <= 0) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Bad face count (%d)", pMeshChunk->nFaces); - return false; - } - if (pMeshChunk->nTVerts != 0) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Texture coordinates found (%d)", pMeshChunk->nTVerts); - return false; - } - if (pMeshChunk->flags1 != 0 || pMeshChunk->flags2 != 0) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Flags are not 0 (0x%x, 0x%x)", (int)pMeshChunk->flags1, (int)pMeshChunk->flags2); - return false; - } - - // prepare vertices - void* pRawData = pMeshChunk + 1; - CryVertex* const pSrcVertices = (CryVertex*)pRawData; - SwapEndian(pSrcVertices, pMeshChunk->nVerts, bSwapEndianness); - if ((const char*)(pSrcVertices + pMeshChunk->nVerts) > (const char*)pRawData + (pChunkDesc->size - sizeof(*pMeshChunk))) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Vertex data are truncated"); - return false; - } - pRawData = pSrcVertices + pMeshChunk->nVerts; - - // prepare indices and MatIDs - CryFace* const pSrcFaces = (CryFace*)pRawData; - SwapEndian(pSrcFaces, pMeshChunk->nFaces, bSwapEndianness); - if ((const char*)(pSrcFaces + pMeshChunk->nFaces) > (const char*)pRawData + (pChunkDesc->size - sizeof(*pMeshChunk))) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Vertex data are truncated"); - return false; - } - - PhysicalProxy pbm; - - pbm.ChunkID = pChunkDesc->chunkId; - - // Bone meshes may contain many vertices sharing positions, so we - // call CompactBoneVertices() to get vertices with unique positions only - if (!CompactBoneVertices( - pbm.m_arrPoints, - pbm.m_arrMaterials, - pbm.m_arrIndices, - pMeshChunk->nVerts, - pSrcVertices, - pMeshChunk->nFaces, - pSrcFaces)) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Bad geometry (indices are out range or too many vertices in mesh)"); - return false; - } - - // SS: I have no idea why we used this magic number of vertices (60000). I just keep it as is. - if (pbm.m_arrPoints.size() > 60000) - { - m_LastError.Format("CLoaderCGF::ReadBoneMesh: Bad vertex count (%d)", pbm.m_arrPoints.size()); - return false; - } - - for (int i = 0, n = pbm.m_arrPoints.size(); i < n; ++i) - { - pbm.m_arrPoints[i] *= VERTEX_SCALE; - } - - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrPhyBoneMeshes.push_back(pbm); - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledBones(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - COMPILED_BONE_CHUNK_DESC_0800* const pBIPChunk = (COMPILED_BONE_CHUNK_DESC_0800*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pBIPChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == pBIPChunk->VERSION) - { - CryBoneDescData_Comp* const pSrcVertices = (CryBoneDescData_Comp*)(pBIPChunk + 1); - const uint32 nDataSize = pChunkDesc->size - sizeof(COMPILED_BONE_CHUNK_DESC_0800); - const uint32 numBones = nDataSize / sizeof(CryBoneDescData_Comp); - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrBonesDesc.resize(numBones); - SwapEndian(pSrcVertices, (size_t)numBones, bSwapEndianness); - - for (uint32 i = 0; i < numBones; i++) - { - pSkinningInfo->m_arrBonesDesc[i].m_nControllerID = pSrcVertices[i].m_nControllerID; - memcpy( - &pSkinningInfo->m_arrBonesDesc[i].m_fMass, - &pSrcVertices[i].m_fMass, - (INT_PTR)&pSrcVertices[i + 1] - (INT_PTR)&pSrcVertices[i].m_fMass); - for (uint32 j = 0; j < 2; j++) - { - pSkinningInfo->m_arrBonesDesc[i].m_PhysInfo[j].pPhysGeom = (phys_geometry*)(INT_PTR)pSrcVertices[i].m_PhysInfo[j].nPhysGeom; - memcpy( - &pSkinningInfo->m_arrBonesDesc[i].m_PhysInfo[j].flags, - &pSrcVertices[i].m_PhysInfo[j].flags, - (INT_PTR)&pSrcVertices[i].m_PhysInfo[j + 1] - (INT_PTR)&pSrcVertices[i].m_PhysInfo[j].flags); - } - } - - m_CompiledBones = true; - return true; - } - - m_LastError.Format("Unknown version of compiled bone chunk"); - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledPhysicalBones(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - COMPILED_PHYSICALBONE_CHUNK_DESC_0800* const pChunk = (COMPILED_PHYSICALBONE_CHUNK_DESC_0800*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == pChunk->VERSION) - { - BONE_ENTITY* pSrcVertices = (BONE_ENTITY*)(pChunk + 1); - const uint32 nDataSize = pChunkDesc->size - sizeof(COMPILED_PHYSICALBONE_CHUNK_DESC_0800); - const uint32 numBones = nDataSize / sizeof(BONE_ENTITY); - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrBoneEntities.resize(numBones); - SwapEndian(pSrcVertices, (size_t)numBones, bSwapEndianness); - for (uint32 i = 0; i < numBones; i++) - { - pSkinningInfo->m_arrBoneEntities[i] = pSrcVertices[i]; - } - - m_CompiledBones = true; - return true; - } - - m_LastError.Format("Unknown version of compiled physical bone chunk"); - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledPhysicalProxies(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - CSkinningInfo* pSkinningInfo = m_pCGF->GetSkinningInfo(); - COMPILED_PHYSICALPROXY_CHUNK_DESC_0800* const pIMTChunk = (COMPILED_PHYSICALPROXY_CHUNK_DESC_0800*)pChunkDesc->data; - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pIMTChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - if (pIMTChunk->numPhysicalProxies > 0xffff) - { - // Fixing bug of old format: numPhysicalProxies was stored in little-endian - // format when chunk header had 'big-endian' flag set. - SwapEndianBase(&pIMTChunk->numPhysicalProxies, 1); - } - - if (pChunkDesc->chunkVersion == pIMTChunk->VERSION) - { - PhysicalProxy sm; - const uint8* rawdata = (const uint8*)(pIMTChunk + 1); - const uint32 numPhysicalProxies = pIMTChunk->numPhysicalProxies; - - for (uint32 i = 0; i < numPhysicalProxies; i++) - { - SMeshPhysicalProxyHeader* header = (SMeshPhysicalProxyHeader*)rawdata; - rawdata += sizeof(SMeshPhysicalProxyHeader); - - SwapEndian(*header, bSwapEndianness); - - sm.ChunkID = header->ChunkID; - if (sm.ChunkID > 0xFFFF) - { - SwapEndian(sm.ChunkID, true); - } - - //store the vertices - COMPILE_TIME_ASSERT(sizeof(sm.m_arrPoints[0]) == sizeof(Vec3)); - SwapEndian((Vec3*)rawdata, (size_t)header->numPoints, bSwapEndianness); - sm.m_arrPoints.resize(header->numPoints); - memcpy(sm.m_arrPoints.begin(), rawdata, sizeof(sm.m_arrPoints[0]) * header->numPoints); - rawdata += sizeof(sm.m_arrPoints[0]) * header->numPoints; - - //store the indices - COMPILE_TIME_ASSERT(sizeof(sm.m_arrIndices[0]) == sizeof(uint16)); - SwapEndian((uint16*)rawdata, (size_t)header->numIndices, bSwapEndianness); - sm.m_arrIndices.resize(header->numIndices); - memcpy(sm.m_arrIndices.begin(), rawdata, sizeof(sm.m_arrIndices[0]) * header->numIndices); - rawdata += sizeof(sm.m_arrIndices[0]) * header->numIndices; - - //store the materials - COMPILE_TIME_ASSERT(sizeof(sm.m_arrMaterials[0]) == sizeof(uint8)); - SwapEndian((uint8*)rawdata, (size_t)header->numMaterials, bSwapEndianness); - sm.m_arrMaterials.resize(header->numMaterials); - memcpy(sm.m_arrMaterials.begin(), rawdata, sizeof(sm.m_arrMaterials[0]) * header->numMaterials); - rawdata += sizeof(sm.m_arrMaterials[0]) * header->numMaterials; - - pSkinningInfo->m_arrPhyBoneMeshes.push_back(sm); - } - return true; - } - - m_LastError.Format("Unknown version of compiled physical proxies chunk"); - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledMorphTargets(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - // Note that this chunk type often contains non-aligned data. Because of that - // we use chunk's data only after memcpy()'ing them. - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - - COMPILED_MORPHTARGETS_CHUNK_DESC_0800 chunk; - memcpy(&chunk, pChunkDesc->data, sizeof(chunk)); - SwapEndian(chunk, bSwapEndianness); - - const uint8* rawdata = ((const uint8*)pChunkDesc->data) + sizeof(chunk); - - if (pChunkDesc->chunkVersion == chunk.VERSION || pChunkDesc->chunkVersion == chunk.VERSION1) - { - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - if (pChunkDesc->chunkVersion == chunk.VERSION1) - { - pSkinningInfo->m_bRotatedMorphTargets = true; - } - - - for (uint32 i = 0; i < chunk.numMorphTargets; ++i) - { - MorphTargetsPtr pSm = new MorphTargets; - - SMeshMorphTargetHeader header; - - memcpy(&header, rawdata, sizeof(header)); - SwapEndian(header, bSwapEndianness); - rawdata += sizeof(header); - - pSm->MeshID = header.MeshID; - - pSm->m_strName = string((const char*)rawdata); - rawdata += header.NameLength; - - // store the internal vertices&indices of morph-target - COMPILE_TIME_ASSERT(sizeof(pSm->m_arrIntMorph[0]) == sizeof(SMeshMorphTargetVertex)); - pSm->m_arrIntMorph.resize(header.numIntVertices); - size_t size = sizeof(pSm->m_arrIntMorph[0]) * header.numIntVertices; - if (size > 0) - { - memcpy(pSm->m_arrIntMorph.begin(), rawdata, size); - SwapEndian(pSm->m_arrIntMorph.begin(), (size_t)header.numIntVertices, bSwapEndianness); - rawdata += size; - } - - // store the external vertices&indices of morph-target - COMPILE_TIME_ASSERT(sizeof(pSm->m_arrExtMorph[0]) == sizeof(SMeshMorphTargetVertex)); - pSm->m_arrExtMorph.resize(header.numExtVertices); - size = sizeof(pSm->m_arrExtMorph[0]) * header.numExtVertices; - if (size > 0) - { - memcpy(pSm->m_arrExtMorph.begin(), rawdata, size); - SwapEndian(pSm->m_arrExtMorph.begin(), (size_t)header.numExtVertices, bSwapEndianness); - rawdata += size; - } - - pSkinningInfo->m_arrMorphTargets.push_back(pSm); - } - return true; - } - - m_LastError.Format("Unknown version of compiled morph targets chunk"); - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledIntFaces(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == COMPILED_INTFACES_CHUNK_DESC_0800::VERSION) - { - TFace* const pSrc = (TFace*)pChunkDesc->data; - const uint32 numIntFaces = pChunkDesc->size / sizeof(pSrc[0]); - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrIntFaces.resize(numIntFaces); - SwapEndian(pSrc, (size_t)numIntFaces, bSwapEndianness); - for (uint32 i = 0; i < numIntFaces; ++i) - { - pSkinningInfo->m_arrIntFaces[i] = pSrc[i]; - } - m_CompiledMesh |= 2; - return true; - } - - m_LastError.Format("Unknown version of compiled int faces chunk"); - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledIntSkinVertice(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - COMPILED_INTSKINVERTICES_CHUNK_DESC_0800* const pBIPChunk = (COMPILED_INTSKINVERTICES_CHUNK_DESC_0800*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pBIPChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == pBIPChunk->VERSION) - { - IntSkinVertex* const pSrcVertices = (IntSkinVertex*)(pBIPChunk + 1); - const uint32 nDataSize = pChunkDesc->size - sizeof(COMPILED_INTSKINVERTICES_CHUNK_DESC_0800); - const uint32 numIntVertices = nDataSize / sizeof(pSrcVertices[0]); - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrIntVertices.resize(numIntVertices); - SwapEndian(pSrcVertices, (size_t)numIntVertices, bSwapEndianness); - for (uint32 i = 0; i < numIntVertices; ++i) - { - pSkinningInfo->m_arrIntVertices[i] = pSrcVertices[i]; - } - m_CompiledMesh |= 1; - return true; - } - - m_LastError.Format("Unknown version of compiled skin vertices chunk"); - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledBonesBoxes(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == COMPILED_BONEBOXES_CHUNK_DESC_0800::VERSION || - pChunkDesc->chunkVersion == COMPILED_BONEBOXES_CHUNK_DESC_0800::VERSION1) - { - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - - if (pChunkDesc->chunkVersion == COMPILED_BONEBOXES_CHUNK_DESC_0800::VERSION1) - { - pSkinningInfo->m_bProperBBoxes = false; - if (pSkinningInfo->m_arrCollisions.empty()) - { - pSkinningInfo->m_bProperBBoxes = true; - } - else - { - // CHECK FOR AT LEAST 1 EMPTY - for (int n = 0; n < pSkinningInfo->m_arrCollisions.size(); ++n) - { - const bool bValid = !pSkinningInfo->m_arrCollisions[n].m_aABB.IsReset(); - if (bValid) - { - pSkinningInfo->m_bProperBBoxes = true; - break; - } - } - } - - /* Ivo: this warning is not needed. It happens always if a character has no physics-proxy, and many simple characters don't have one - if (!pSkinningInfo->m_bProperBBoxes) - { - CryWarning(VALIDATOR_MODULE_3DENGINE,VALIDATOR_WARNING,"%s: Invalid bones bounds", m_filename); - }*/ - - pSkinningInfo->m_bProperBBoxes = false; - } - - char* pSrc = (char*)pChunkDesc->data; - - pSkinningInfo->m_arrCollisions.push_back(MeshCollisionInfo()); - MeshCollisionInfo& info = pSkinningInfo->m_arrCollisions[pSkinningInfo->m_arrCollisions.size() - 1]; - - COMPILE_TIME_ASSERT(sizeof(info.m_iBoneId) == sizeof(int32)); - SwapEndian((int32*)pSrc, 1, bSwapEndianness); - memcpy(&info.m_iBoneId, pSrc, sizeof(info.m_iBoneId)); - pSrc += sizeof(info.m_iBoneId); - - COMPILE_TIME_ASSERT(sizeof(info.m_aABB) == sizeof(AABB)); - SwapEndian((AABB*)pSrc, 1, bSwapEndianness); - memcpy(&info.m_aABB, pSrc, sizeof(info.m_aABB)); - pSrc += sizeof(info.m_aABB); - - int32 size; - COMPILE_TIME_ASSERT(sizeof(size) == sizeof(int32)); - SwapEndian((int32*)pSrc, 1, bSwapEndianness); - memcpy(&size, pSrc, sizeof(size)); - pSrc += sizeof(size); - - if (size > 0) - { - COMPILE_TIME_ASSERT(sizeof(info.m_arrIndexes[0]) == sizeof(int16)); - SwapEndian((int16*)pSrc, size, bSwapEndianness); - info.m_arrIndexes.resize(size); - memcpy(info.m_arrIndexes.begin(), pSrc, size * sizeof(info.m_arrIndexes[0])); - } - - m_CompiledBonesBoxes = true; - return true; - } - - m_LastError.Format("Unknown version of compiled bone boxes chunk"); - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledExt2IntMap(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - pChunkDesc->bSwapEndian = false; - - if (pChunkDesc->chunkVersion == COMPILED_EXT2INTMAP_CHUNK_DESC_0800::VERSION) - { - uint16* const pSrc = (uint16*)pChunkDesc->data; - const uint32 numExtVertices = pChunkDesc->size / sizeof(pSrc[0]); - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - pSkinningInfo->m_arrExt2IntMap.resize(numExtVertices); - SwapEndian(pSrc, (size_t)numExtVertices, bSwapEndianness); - for (uint32 i = 0; i < numExtVertices; ++i) - { - assert(pSrc[i] != 0xffff); - pSkinningInfo->m_arrExt2IntMap[i] = pSrc[i]; - } - m_CompiledMesh |= 4; - return true; - } - m_LastError.Format("Unknown version of compiled Ext2Int map chunk"); - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::ReadCompiledBreakablePhysics(IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->chunkVersion != BREAKABLE_PHYSICS_CHUNK_DESC::VERSION) - { - m_LastError.Format("Unknown version of breakable physics chunk"); - return false; - } - - BREAKABLE_PHYSICS_CHUNK_DESC* const pChunk = (BREAKABLE_PHYSICS_CHUNK_DESC*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(*pChunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - CPhysicalizeInfoCGF* const pPi = m_pCGF->GetPhysicalizeInfo(); - - pPi->nGranularity = pChunk->granularity; - pPi->nMode = pChunk->nMode; - pPi->nRetVtx = pChunk->nRetVtx; - pPi->nRetTets = pChunk->nRetTets; - if (pPi->nRetVtx > 0) - { - char* pData = ((char*)pChunk) + sizeof(BREAKABLE_PHYSICS_CHUNK_DESC); - SwapEndian((Vec3*)pData, pPi->nRetVtx, bSwapEndianness); - memcpy(pPi->pRetVtx, pData, pPi->nRetVtx * sizeof(Vec3)); - } - if (pPi->nRetTets > 0) - { - char* pData = ((char*)pChunk) + sizeof(BREAKABLE_PHYSICS_CHUNK_DESC) + pPi->nRetVtx * sizeof(Vec3); - SwapEndian((int*)pData, pPi->nRetTets * 4, bSwapEndianness); - memcpy(pPi->pRetTets, pData, pPi->nRetTets * sizeof(int) * 4); - } - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// - -#if defined(RESOURCE_COMPILER) - -namespace ProcessSkinningHelpers -{ - struct RBatch - { - uint32 startFace; - uint32 numFaces; - uint32 MaterialID; - }; - - bool SplitIntoRBatches( - std::vector& arrSubsets, - std::vector& arrExtFaces, - string& lastError, - const CMesh* const pMesh) - { - arrSubsets.clear(); - arrExtFaces.clear(); - - const int numSubsets = pMesh->m_subsets.size(); - - //-------------------------------------------------------------------------- - //--- sort render-batches for hardware skinning --- - //-------------------------------------------------------------------------- - - std::vector arrBatches; - for (uint32 m = 0; m < numSubsets; m++) - { - const int numFacesTotal = pMesh->GetIndexCount() / 3; - const int firstFace = pMesh->m_subsets[m].nFirstIndexId / 3; - const int numFaces = pMesh->m_subsets[m].nNumIndices / 3; - if (firstFace >= numFacesTotal) - { - lastError.Format("Wrong first face id index (%i out of %i)", (int)firstFace, (int)numFacesTotal); - return false; - } - if (numFaces <= 0 || firstFace + numFaces > numFacesTotal) - { - lastError.Format("Bad # of faces (%i)", (int)numFaces); - return false; - } - - { - RBatch rbatch; - rbatch.MaterialID = pMesh->m_subsets[m].nMatID; - rbatch.startFace = arrExtFaces.size(); - rbatch.numFaces = numFaces; - - arrBatches.push_back(rbatch); - } - - vtx_idx* const pIndices = &pMesh->m_pIndices[firstFace * 3]; - - for (int i = 0; i < numFaces * 3; i += 3) - { - arrExtFaces.push_back(TFace(pIndices[i + 0], pIndices[i + 1], pIndices[i + 2])); - } - } - - //------------------------------------------------------------------------- - //--- check if material batches overlap --- - //------------------------------------------------------------------------- - { - for (uint32 m = 0; m < numSubsets; m++) - { - uint32 vmin = 0xffffffff; - uint32 vmax = 0x00000000; - - uint32 nFirstFaceId = pMesh->m_subsets[m].nFirstIndexId / 3; - uint32 numFaces = pMesh->m_subsets[m].nNumIndices / 3; - for (uint32 f = 0; f < numFaces; f++) - { - uint32 i0 = arrExtFaces[nFirstFaceId + f].i0; - uint32 i1 = arrExtFaces[nFirstFaceId + f].i1; - uint32 i2 = arrExtFaces[nFirstFaceId + f].i2; - if (vmin > i0) - { - vmin = i0; - } - if (vmin > i1) - { - vmin = i1; - } - if (vmin > i2) - { - vmin = i2; - } - if (vmax < i0) - { - vmax = i0; - } - if (vmax < i1) - { - vmax = i1; - } - if (vmax < i2) - { - vmax = i2; - } - } - if (pMesh->m_subsets[m].nFirstVertId != vmin || - pMesh->m_subsets[m].nNumVerts != vmax - vmin + 1) - { - lastError = "Overlapping material batches"; - return false; - } - } - - for (uint32 a = 0; a < numSubsets; a++) - { - for (uint32 b = 0; b < numSubsets; b++) - { - if (a == b) - { - continue; - } - uint32 amin = pMesh->m_subsets[a].nFirstVertId; - uint32 amax = pMesh->m_subsets[a].nNumVerts + amin - 1; - uint32 bmin = pMesh->m_subsets[b].nFirstVertId; - uint32 bmax = pMesh->m_subsets[b].nNumVerts + bmin - 1; - if (amax >= bmin && amin <= bmax) - { - lastError = "Overlapping material batches"; - return false; - } - } - } - } - - arrSubsets.resize(arrBatches.size()); //subsets of the mesh as they appear in video-mem - for (uint32 m = 0; m < arrBatches.size(); m++) - { - uint32 mat = arrBatches[m].MaterialID; - // assert(matm_subsets.size(); - for (r = 0; r < numSubsets2; r++) - { - if (mat == pMesh->m_subsets[r].nMatID) - { - found = true; - break; - } - } - - if (!found) - { - lastError.Format("Mesh subset for material %i was not found.", (int)mat); - return false; - } - - arrSubsets[m] = pMesh->m_subsets[r]; - arrSubsets[m].nMatID = arrBatches[m].MaterialID; - arrSubsets[m].nFirstIndexId = arrBatches[m].startFace * 3; - arrSubsets[m].nNumIndices = arrBatches[m].numFaces * 3; - - //Make sure the all vertices are in range if indices. This is important for ATI-kards - uint32 sml_index = 0xffffffff; - uint32 big_index = 0x00000000; - uint32 sface = arrBatches[m].startFace; - uint32 eface = arrBatches[m].numFaces + sface; - for (uint32 i = sface; i < eface; i++) - { - uint32 i0 = arrExtFaces[i].i0; - uint32 i1 = arrExtFaces[i].i1; - uint32 i2 = arrExtFaces[i].i2; - if (sml_index > i0) - { - sml_index = i0; - } - if (sml_index > i1) - { - sml_index = i1; - } - if (sml_index > i2) - { - sml_index = i2; - } - if (big_index < i0) - { - big_index = i0; - } - if (big_index < i1) - { - big_index = i1; - } - if (big_index < i2) - { - big_index = i2; - } - } - arrSubsets[m].nFirstVertId = sml_index; - arrSubsets[m].nNumVerts = big_index - sml_index + 1; - } - - return true; - } -} -#endif - - -bool CLoaderCGF::ProcessSkinning() -{ - LOADING_TIME_PROFILE_SECTION; - - CSkinningInfo* const pSkinningInfo = m_pCGF->GetSkinningInfo(); - - const uint32 numBones = pSkinningInfo->m_arrBonesDesc.size(); - - //do we have an initialized skeleton? - if (numBones == 0) - { - return true; - } - - if (numBones > MAX_NUMBER_OF_BONES) - { - m_LastError.Format("Too many bones: %i. Reached limit of %i bones.", int(numBones), int(MAX_NUMBER_OF_BONES)); - return false; - } - -#if !defined(RESOURCE_COMPILER) - - if (m_CompiledMesh != 7 && m_CompiledBones != 1) - { - CryFatalError("%s tried to load a noncompiled mesh: %s", __FUNCTION__, m_filename); - m_LastError.Format("noncompiled mesh"); - return false; - } - return true; - -#else - using namespace ProcessSkinningHelpers; - - if (m_CompiledBones == 0) - { - //process raw bone-data - assert(m_numBonenameList < 2); - assert(m_numBoneInitialPos < 2); - assert(m_numBoneHierarchy < 2); - - const uint32 numIPos = m_arrInitPose34.size(); - if (numBones != numIPos) - { - m_LastError.Format("Skeleton-Initial-Positions are missing."); - return false; - } - - const uint32 numBonenames = m_arrBoneNameTable.size(); - if (numBones != numBonenames) - { - m_LastError.Format("Number of bones does not match in the bone hierarchy chunk (%d) and the bone name chunk (%d)", numBones, numBonenames); - return false; - } - - //------------------------------------------------------------------------------------------ - //---- use the old chunks to initialize the bone structure ---------------------------- - //------------------------------------------------------------------------------------------ - static const char* const arrLimbNames[] = - { - "L UpperArm", - "R UpperArm", - "L Thigh", - "R Thigh" - }; - static const int limbNamesCount = sizeof(arrLimbNames) / sizeof(arrLimbNames[0]); - const uint32 numBonesDesc = pSkinningInfo->m_arrBonesDesc.size(); - for (uint32 nBone = 0; nBone < numBonesDesc; ++nBone) - { - uint32 nBoneID = m_arrIndexToId[nBone]; - if (nBoneID == ~0) - { - continue; - } - - pSkinningInfo->m_arrBonesDesc[nBone].m_DefaultW2B = m_arrInitPose34[nBoneID].GetInvertedFast(); - pSkinningInfo->m_arrBonesDesc[nBone].m_DefaultB2W = m_arrInitPose34[nBoneID]; - - memset(pSkinningInfo->m_arrBonesDesc[nBone].m_arrBoneName, 0, sizeof(pSkinningInfo->m_arrBonesDesc[nBone].m_arrBoneName)); - azstrcpy(pSkinningInfo->m_arrBonesDesc[nBone].m_arrBoneName, sizeof(pSkinningInfo->m_arrBonesDesc[nBone].m_arrBoneName), m_arrBoneNameTable[nBoneID].c_str()); - - //fill in names of the bones and the limb IDs --- - uint32 nBoneId = m_arrIndexToId[nBone]; - pSkinningInfo->m_arrBonesDesc[nBone].m_nLimbId = -1; - for (int j = 0; j < limbNamesCount; ++j) - { - if (strstr(m_arrBoneNameTable[nBoneId], arrLimbNames[j])) - { - pSkinningInfo->m_arrBonesDesc[nBone].m_nLimbId = j; - break; - } - } - } - } - - if (m_CompiledMesh != 0 && m_CompiledMesh != 7) - { - m_LastError.Format("Found mix of new and old chunks"); - return false; - } - - if (m_CompiledMesh) - { - return true; - } - - //------------------------------------------------------------------------------------------ - //---- get the mesh ----------------------------------------------------------------- - //------------------------------------------------------------------------------------------ - - CNodeCGF* pNode = 0; - for (int i = 0; i < m_pCGF->GetNodeCount(); ++i) - { - if (m_pCGF->GetNode(i)->type == CNodeCGF::NODE_MESH && m_pCGF->GetNode(i)->pMesh) - { - pNode = m_pCGF->GetNode(i); - break; - } - } - if (!pNode) - { - return true; - } - - CMesh* const pMesh = pNode->pMesh; - - if (!pMesh) - { - m_LastError = "No mesh found"; - return false; - } - - if (pMesh->m_pPositionsF16) - { - m_LastError.Format("Unexpected format of vertex positions: f16"); - return false; - } - - const uint32 numIntVertices = pMesh->GetVertexCount(); - - /* ----------------------------------------------------------------------------- - // NOTE: Related to commented out code below! - // Color0 is copied into two distinct streams in the Engine: - // as Color in the Base stream and as indices in the Shape - // Deformation stream. The latter needs for the values to be - // snapped while the former doesn't. - // Snapping used to happen here at compiling/loading time, however - // this will destroy the Color information that might be needed in - // the Base stream. - // We are now snapping the values when copying this data into the - // Shape Deformation stream, while leaving the data copied in the - // Base stream untouched. A properer solution would be to create an - // additional chunk in the file and completely decouple the two - // datasets. - - if (pMesh->m_pColor0) - { - //----------------------------------------------------------------- - //--- do a color-snap on all vcolors and calculate index --- - //----------------------------------------------------------------- - for (uint32 i=0; im_pColor0[i].r = (pMesh->m_pColor0[i].r>0x80) ? 0xff : 0x00; - pMesh->m_pColor0[i].g = (pMesh->m_pColor0[i].g>0x80) ? 0xff : 0x00; - pMesh->m_pColor0[i].b = (pMesh->m_pColor0[i].b>0x80) ? 0xff : 0x00; - pMesh->m_pColor0[i].a = 0; - //calculate the index (this is the only value we need in the vertex-shader) - if (pMesh->m_pColor0[i].r) pMesh->m_pColor0[i].a|=1; - if (pMesh->m_pColor0[i].g) pMesh->m_pColor0[i].a|=2; - if (pMesh->m_pColor0[i].b) pMesh->m_pColor0[i].a|=4; - } - } - ----------------------------------------------------------------------------- */ - - //-------------------------------------------------------------- - //--- copy the links into geometry info --- - //-------------------------------------------------------------- - { - const uint32 numLinks = m_arrLinksTmp.size(); - if (numIntVertices != numLinks) - { - m_LastError.Format("Different number of vertices (%i) and vertex links (%i)", (int)numIntVertices, (int)numLinks); - return false; - } - assert(!m_arrIdToIndex.empty()); - - for (uint32 i = 0; i < numIntVertices; ++i) - { - MeshUtils::VertexLinks& links = m_arrLinksTmp[i]; - - for (int j = 0; j < (int)links.links.size(); ++j) - { - MeshUtils::VertexLinks::Link& cl = links.links[j]; - if (cl.boneId >= 0 && cl.boneId < (int)m_arrIdToIndex.size()) - { - cl.boneId = m_arrIdToIndex[cl.boneId]; - } - else - { - // bone index is out of range - // if you get this assert, most probably there is desynchronization between different LODs of the same model - // - all of them must be exported with exactly the same skeletons. - assert(0); - cl.boneId = 0; - } - } - - const char* const err = links.Normalize(MeshUtils::VertexLinks::eSort_ByWeight, 0.0f, (int)links.links.size()); - if (err) - { - m_LastError.Format("Internal error in skin compiler: %s", err); - return false; - } - - // Paranoid checks - { - float w = 0; - for (int j = 0; j < (int)links.links.size(); ++j) - { - w += links.links[j].weight; - } - if (fabsf(w - 1.0f) > 0.005f) - { - m_LastError.Format("Internal error in skin compiler: %s", "sum of weights is not 1.0"); - return false; - } - - for (int j = 1; j < (int)links.links.size(); ++j) - { - if (links.links[j - 1].weight < links.links[j].weight) - { - m_LastError.Format("Internal error in skin compiler: %s", "links are not sorted by weight"); - return false; - } - } - } - } - } - - //--------------------------------------------------------------------- - // create internal SkinBuffer - //--------------------------------------------------------------------- - bool bHasExtraBoneMappings = false; - pSkinningInfo->m_arrIntVertices.resize(numIntVertices); - for (uint32 nVert = 0; nVert < numIntVertices; ++nVert) - { - const MeshUtils::VertexLinks& rLinks_base = m_arrLinksTmp[nVert]; - - const int numVertexLinks = (int)rLinks_base.links.size(); - assert(numVertexLinks > 0 && numVertexLinks <= 8); - - bHasExtraBoneMappings = bHasExtraBoneMappings || numVertexLinks > 4; - - IntSkinVertex v; - - if (pMesh->m_pColor0) - { - v.color = pMesh->m_pColor0[nVert].GetRGBA(); - } - else - { - v.color = ColorB(0xff, 0xff, 0xff, 1 | 2 | 4); - } - - v.__obsolete0 = Vec3(ZERO); - v.__obsolete2 = Vec3(ZERO); - - const int n = std::min(numVertexLinks, (int)ARRAY_LENGTH(v.weights)); - for (int j = 0; j < n; ++j) - { - v.boneIDs[j] = rLinks_base.links[j].boneId; - v.weights[j] = rLinks_base.links[j].weight; - } - for (int j = n; j < ARRAY_LENGTH(v.weights); ++j) - { - v.boneIDs[j] = 0; - v.weights[j] = 0; - } - - // transform position from bone-space to world-space - v.pos = Vec3(ZERO); - for (int j = 0; j < numVertexLinks; ++j) - { - v.pos += - pSkinningInfo->m_arrBonesDesc[rLinks_base.links[j].boneId].m_DefaultB2W * - rLinks_base.links[j].offset * - rLinks_base.links[j].weight; - } - - pSkinningInfo->m_arrIntVertices[nVert] = v; - } - - //-------------------------------------------------------------------------- - // sort faces by subsets - //-------------------------------------------------------------------------- - // for each subset, construct an array of faces and keep the faces (in the original order) in there - typedef std::map > SubsetFacesMap; - SubsetFacesMap mapSubsetFaces; - - if (numIntVertices > (1 << 16)) - { - m_LastError.Format("Too many vertices in skin geometry: %i (max possible is %i)", numIntVertices, (1 << 16)); - return false; - } - - // put each face into its subset group; - // the corresponding groups will be created by the map automatically - // upon the first request of that group - const uint32 numIntFaces = pMesh->GetFaceCount(); - - for (uint32 i = 0; i < numIntFaces; ++i) - { - const int subsetIdx = pMesh->m_pFaces[i].nSubset; - if (subsetIdx < 0 || subsetIdx > pMesh->m_subsets.size()) - { - m_LastError.Format("Invalid subset index detected: %i (# of subsets: %i)", subsetIdx, (int)pMesh->m_subsets.size()); - return false; - } - if (pMesh->m_subsets[subsetIdx].nMatID >= MAX_SUB_MATERIALS) - { - m_LastError.Format("Maximum number of submaterials reached (%i)", (int)MAX_SUB_MATERIALS); - return false; - } - - int vIdx[3]; - for (int j = 0; j < 3; ++j) - { - vIdx[j] = pMesh->m_pFaces[i].v[j]; - if (vIdx[j] < 0) - { - m_LastError.Format("Internal vertex index %i is negative (# of vertices is %i)", vIdx[j], numIntVertices); - return false; - } - if (vIdx[j] >= numIntVertices) - { - m_LastError.Format("Internal vertex index %i is out of range (# of vertices is %i)", vIdx[j], numIntVertices); - return false; - } - } - mapSubsetFaces[subsetIdx].push_back(TFace(vIdx[0], vIdx[1], vIdx[2])); - } - - if (pMesh->GetSubSetCount() != mapSubsetFaces.size()) - { - m_LastError.Format("Number of referenced subsets (%d) is not equal to number of stored subsets (%i)", (int)mapSubsetFaces.size(), pMesh->GetSubSetCount()); - return false; - } - - //-------------------------------------------------------------------------- - // create array with internal faces (sorted by subsets) - //-------------------------------------------------------------------------- - { - pSkinningInfo->m_arrIntFaces.resize(numIntFaces); - - int newFaceCount = 0; - for (SubsetFacesMap::iterator itMtl = mapSubsetFaces.begin(); itMtl != mapSubsetFaces.end(); ++itMtl) - { - const size_t faceCount = itMtl->second.size(); - for (size_t f = 0; f < faceCount; ++f, ++newFaceCount) - { - pSkinningInfo->m_arrIntFaces[newFaceCount] = itMtl->second[f]; - } - } - assert(newFaceCount == numIntFaces); - } - - // Compile contents. - // These map from internal (original) to external (optimized) indices/vertices - std::vector arrVRemapping; - std::vector arrIRemapping; - - m_pCompiledCGF = MakeCompiledSkinCGF(m_pCGF, &arrVRemapping, &arrIRemapping); - if (!m_pCompiledCGF) - { - return false; - } - const uint32 numVRemapping = arrVRemapping.size(); - if (numVRemapping == 0) - { - m_LastError = "Empty vertex remapping"; - return false; - } - if (arrIRemapping.size() != numIntFaces * 3) - { - m_LastError.Format("Wrong # of indices for remapping"); - return false; - } - - //allocates the external to internal map entries - // (m_arrExt2IntMap[]: for each final vertex contains its index in initial vertex buffer) - // TODO: in theory arrVRemapping.size() is not necessarily equals to the number of final vertices. - // It could be bigger if a face is not referenced from any of the subsets. - pSkinningInfo->m_arrExt2IntMap.resize(numVRemapping, ~0); - for (uint32 i = 0; i < numIntFaces; ++i) - { - const uint32 idx0 = arrVRemapping[arrIRemapping[i * 3 + 0]]; - const uint32 idx1 = arrVRemapping[arrIRemapping[i * 3 + 1]]; - const uint32 idx2 = arrVRemapping[arrIRemapping[i * 3 + 2]]; - if (idx0 >= numVRemapping || idx1 >= numVRemapping || idx2 >= numVRemapping) - { - m_LastError.Format("Indices out of range"); - return false; - } - pSkinningInfo->m_arrExt2IntMap[idx0] = pSkinningInfo->m_arrIntFaces[i].i0; - pSkinningInfo->m_arrExt2IntMap[idx1] = pSkinningInfo->m_arrIntFaces[i].i1; - pSkinningInfo->m_arrExt2IntMap[idx2] = pSkinningInfo->m_arrIntFaces[i].i2; - } - - { - int brokenCount = 0; - for (uint32 i = 0; i < numVRemapping; i++) - { - if (pSkinningInfo->m_arrExt2IntMap[i] >= numIntVertices) - { - ++brokenCount; - // "Fixing" mapping allows us to comment out "return false" below (in case of an urgent need) - pSkinningInfo->m_arrExt2IntMap[i] = 0; - } - } - if (brokenCount > 0) - { - m_LastError.Format("Remapping-table is broken. %i of %i vertices are not remapped", brokenCount, numVRemapping); - return false; - } - } - - //------------------------------------------------------------------------- - - std::vector arrSubsets; - std::vector arrExtFaces; - - if (!SplitIntoRBatches(arrSubsets, arrExtFaces, m_LastError, pMesh)) - { - return false; - } - - //-------------------------------------------------------------------------- - //--- copy compiled-data back into CMesh --- - //-------------------------------------------------------------------------- - for (size_t f = 0, n = arrExtFaces.size(); f < n; ++f) - { - pMesh->m_pIndices[f * 3 + 0] = arrExtFaces[f].i0; - pMesh->m_pIndices[f * 3 + 1] = arrExtFaces[f].i1; - pMesh->m_pIndices[f * 3 + 2] = arrExtFaces[f].i2; - } - - pMesh->m_subsets.clear(); - pMesh->m_subsets.reserve(arrSubsets.size()); - for (size_t i = 0; i < arrSubsets.size(); ++i) - { - pMesh->m_subsets.push_back(arrSubsets[i]); - } - - ////////////////////////////////////////////////////////////////////////// - // Create and fill bone-mapping streams. - ////////////////////////////////////////////////////////////////////////// - { - pMesh->ReallocStream(CMesh::BONEMAPPING, 0, numVRemapping); - if (bHasExtraBoneMappings) - { - pMesh->ReallocStream(CMesh::EXTRABONEMAPPING, 0, numVRemapping); - } - - for (uint32 i = 0; i < numVRemapping; ++i) - { - const uint32 index = pSkinningInfo->m_arrExt2IntMap[i]; - const MeshUtils::VertexLinks& links = m_arrLinksTmp[index]; - const int linkCount = (int)links.links.size(); - - // Convert floating point weights to integer [0;255] weights - int w[8]; - { - assert(linkCount <= 8); - - int wSum = 0; - for (int j = 0; j < linkCount; ++j) - { - w[j] = (int)(links.links[j].weight * 255.0f + 0.5f); - wSum += w[j]; - } - - // Ensure that the sum of weights is exactly 255. - // Note that the code below preserves sorting by - // weight in descending order. - if (wSum < 255) - { - w[0] += 255 - wSum; - } - else if (wSum > 255) - { - for (int j = 0;; ++j) - { - if (j >= linkCount - 1 || w[j] > w[j + 1]) - { - --w[j]; - if (--wSum == 255) - { - break; - } - j = std::max(j - 1, 0) - 1; - } - } - } - - // TODO: quantization to integer values might produce zero weight links, so - // it might be a good idea to delete such links. Warning: m_arrIntVertices[] - // also stores (up to) four links, so we should delete matching zero-weight - // links in m_arrIntVertices[] as well. - } - - // Fill CMesh::BONEMAPPING stream - { - const int n = std::min(linkCount, 4); - for (int j = 0; j < n; ++j) - { - pMesh->m_pBoneMapping[i].boneIds[j] = links.links[j].boneId; - pMesh->m_pBoneMapping[i].weights[j] = (uint8)w[j]; - } - for (int j = n; j < 4; ++j) - { - pMesh->m_pBoneMapping[i].boneIds[j] = 0; - pMesh->m_pBoneMapping[i].weights[j] = 0; - } - } - - // Fill CMesh::EXTRABONEMAPPING stream - if (bHasExtraBoneMappings) - { - const int n = std::max(linkCount - 4, 0); - for (int j = 0; j < n; ++j) - { - pMesh->m_pExtraBoneMapping[i].boneIds[j] = links.links[4 + j].boneId; - pMesh->m_pExtraBoneMapping[i].weights[j] = (uint8)w[4 + j]; - } - for (int j = n; j < 4; ++j) - { - pMesh->m_pExtraBoneMapping[i].boneIds[j] = 0; - pMesh->m_pExtraBoneMapping[i].weights[j] = 0; - } - } - } - } - - // Keep original transform for morph targets - Matrix34 mat34 = pNode->localTM * Diag33(VERTEX_SCALE, VERTEX_SCALE, VERTEX_SCALE); - - ////////////////////////////////////////////////////////////////////////// - // Copy shape-deformation and positions. - ////////////////////////////////////////////////////////////////////////// - { - // Modify orientation, but keep translation. - // We need to keep translation to be able to use pivot of the node. - // It allows us to control coordinate origin for FP16 meshes. - // The translation is applied later before skinning. - const Matrix34 oldWorldTM = pNode->worldTM; - const Vec3 translation = oldWorldTM.GetTranslation(); - pNode->worldTM = Matrix34(Matrix33(IDENTITY), translation); - // Reconstruct localTM out of new worldTM - if (pNode->pParent) - { - Matrix34 parentWorldInverted = pNode->pParent->worldTM; - parentWorldInverted.Invert(); - pNode->localTM = parentWorldInverted * pNode->worldTM; - } - else - { - pNode->localTM = pNode->worldTM; - } - - for (uint32 e = 0; e < numVRemapping; ++e) - { - const uint32 i = pSkinningInfo->m_arrExt2IntMap[e]; - const IntSkinVertex& intVertex = pSkinningInfo->m_arrIntVertices[i]; - pMesh->m_pPositions[e] = intVertex.pos - translation; - } - - // The exporting pipeline is expected to produce pNode->worldTM - // with identity orientation only, but let's be paranoid and handle - // non-identity orientations properly as well. - - const float eps = 0.001f; - const bool bIdentity = - oldWorldTM.GetColumn0().IsEquivalent(Vec3(1, 0, 0), eps) && - oldWorldTM.GetColumn1().IsEquivalent(Vec3(0, 1, 0), eps) && - oldWorldTM.GetColumn2().IsEquivalent(Vec3(0, 0, 1), eps); - - if (!bIdentity) - { - for (uint32 e = 0; e < numVRemapping; ++e) - { - const uint32 i = pSkinningInfo->m_arrExt2IntMap[e]; - - pMesh->m_pNorms[e].RotateSafelyBy(oldWorldTM); - pMesh->m_pTangents[i].RotateSafelyBy(oldWorldTM); - } - } - } - - //-------------------------------------------------------------------------- - //--- prepare morph-targets --- - //-------------------------------------------------------------------------- - uint32 numMorphTargets = pSkinningInfo->m_arrMorphTargets.size(); - for (uint32 it = 0; it < numMorphTargets; ++it) - { - //init internal morph-targets - MorphTargets* pMorphtarget = pSkinningInfo->m_arrMorphTargets[it]; - uint32 numMorphVerts = pMorphtarget->m_arrIntMorph.size(); -#if !defined(NDEBUG) - uint32 intVertexCount = pSkinningInfo->m_arrIntVertices.size(); -#endif - for (uint32 i = 0; i < numMorphVerts; i++) - { - uint32 idx = pMorphtarget->m_arrIntMorph[i].nVertexId; - assert(idx < intVertexCount); - Vec3 mvertex = (mat34 * pMorphtarget->m_arrIntMorph[i].ptVertex) - pSkinningInfo->m_arrIntVertices[idx].pos; - pMorphtarget->m_arrIntMorph[i].ptVertex = mvertex; - } - - //init external morph-targets - for (uint32 v = 0; v < numMorphVerts; v++) - { - uint32 idx = pMorphtarget->m_arrIntMorph[v].nVertexId; - Vec3 mvertex = pMorphtarget->m_arrIntMorph[v].ptVertex; - - const uint16* pExtToIntMap = &pSkinningInfo->m_arrExt2IntMap[0]; - uint32 numExtVertices = numVRemapping; - assert(numExtVertices); - for (uint32 i = 0; i < numExtVertices; ++i) - { - uint32 index = pExtToIntMap[i]; - if (index == idx) - { - SMeshMorphTargetVertex mp; - mp.nVertexId = i; - mp.ptVertex = mvertex; - pMorphtarget->m_arrExtMorph.push_back(mp); - } - } - } - } - - pMesh->m_bbox.Reset(); - for (size_t v = 0; v < numVRemapping; ++v) - { - pMesh->m_bbox.Add(pMesh->m_pPositions[v]); - } - - return true; -#endif -} - - - - -//------------------------------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------------------------------ - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) - -CContentCGF* CLoaderCGF::MakeCompiledSkinCGF( - CContentCGF* pCGF, std::vector* pVertexRemapping, std::vector* pIndexRemapping) PREFAST_SUPPRESS_WARNING(6262) //function uses > 32k stack space -{ - CContentCGF* const pCompiledCGF = new CContentCGF(pCGF->GetFilename()); - *pCompiledCGF->GetExportInfo() = *pCGF->GetExportInfo(); // Copy export info. - - // Compile mesh. - // Note that this function cannot fill/return mapping arrays properly in case of - // multiple meshes (because mapping is per-mesh), so we will treat multiple - // meshes as error. - bool bMeshFound = false; - for (int i = 0; i < pCGF->GetNodeCount(); ++i) - { - CNodeCGF* const pNodeCGF = pCGF->GetNode(i); - if (!pNodeCGF->pMesh || pNodeCGF->type != CNodeCGF::NODE_MESH || pNodeCGF->bPhysicsProxy) - { - continue; - } - - if (bMeshFound) - { - m_LastError.Format("Failed to compile skinned geometry file %s - %s", pCGF->GetFilename(), "*multiple* mesh nodes aren't supported"); - delete pCompiledCGF; - return 0; - } - - bMeshFound = true; - - mesh_compiler::CMeshCompiler meshCompiler; - - meshCompiler.SetIndexRemapping(pIndexRemapping); - meshCompiler.SetVertexRemapping(pVertexRemapping); - - int flags = mesh_compiler::MESH_COMPILE_TANGENTS | mesh_compiler::MESH_COMPILE_OPTIMIZE; - if (pCompiledCGF->GetExportInfo()->bUseCustomNormals) - { - flags |= mesh_compiler::MESH_COMPILE_USECUSTOMNORMALS; - } - - if (!meshCompiler.Compile(*pNodeCGF->pMesh, flags)) - { - m_LastError.Format("Failed to compile skinned geometry file %s - %s", pCGF->GetFilename(), meshCompiler.GetLastError()); - delete pCompiledCGF; - return 0; - } - - pCompiledCGF->AddNode(pNodeCGF); - - // We continue scanning just to detect if we have multiple mesh nodes (to throw an error) - } - - // Compile physics proxy nodes. - if (pCGF->GetExportInfo()->bHavePhysicsProxy) - { - for (int i = 0; i < pCGF->GetNodeCount(); ++i) - { - CNodeCGF* pNodeCGF = pCGF->GetNode(i); - if (pNodeCGF->pMesh && pNodeCGF->bPhysicsProxy) - { - // Compile physics proxy mesh. - mesh_compiler::CMeshCompiler meshCompiler; - if (!meshCompiler.Compile(*pNodeCGF->pMesh, mesh_compiler::MESH_COMPILE_OPTIMIZE)) - { - m_LastError.Format("Failed to compile skinned geometry in node %s in file %s - %s", pNodeCGF->name, pCGF->GetFilename(), meshCompiler.GetLastError()); - delete pCompiledCGF; - return 0; - } - } - pCompiledCGF->AddNode(pNodeCGF); - } - } - - return pCompiledCGF; -} - -#endif - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadExportFlagsChunk(IChunkFile::ChunkDesc* pChunkDesc) -{ - if (pChunkDesc->chunkVersion != EXPORT_FLAGS_CHUNK_DESC::VERSION) - { - m_LastError.Format("Unknown version of export flags chunk"); - return false; - } - - EXPORT_FLAGS_CHUNK_DESC& chunk = *(EXPORT_FLAGS_CHUNK_DESC*)pChunkDesc->data; - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - CExportInfoCGF* pExportInfo = m_pCGF->GetExportInfo(); - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::MERGE_ALL_NODES) - { - pExportInfo->bMergeAllNodes = true; - } - else - { - pExportInfo->bMergeAllNodes = false; - } - - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::HAVE_AUTO_LODS) - { - pExportInfo->bHaveAutoLods = true; - } - else - { - pExportInfo->bHaveAutoLods = false; - } - - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::USE_CUSTOM_NORMALS) - { - pExportInfo->bUseCustomNormals = true; - } - else - { - pExportInfo->bUseCustomNormals = false; - } - - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::WANT_F32_VERTICES) - { - pExportInfo->bWantF32Vertices = true; - } - else - { - pExportInfo->bWantF32Vertices = false; - } - - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::EIGHT_WEIGHTS_PER_VERTEX) - { - pExportInfo->b8WeightsPerVertex = true; - } - else - { - pExportInfo->b8WeightsPerVertex = false; - } - if (chunk.flags & EXPORT_FLAGS_CHUNK_DESC::SKINNED_CGF) - { - pExportInfo->bSkinnedCGF = true; - } - else - { - pExportInfo->bSkinnedCGF = false; - } - - return true; -} - -inline const char* stristr2(const char* szString, const char* szSubstring) -{ - int nSuperstringLength = (int)strlen(szString); - int nSubstringLength = (int)strlen(szSubstring); - - for (int nSubstringPos = 0; nSubstringPos <= nSuperstringLength - nSubstringLength; ++nSubstringPos) - { - if (_strnicmp(szString + nSubstringPos, szSubstring, nSubstringLength) == 0) - { - return szString + nSubstringPos; - } - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadNodeChunk(IChunkFile::ChunkDesc* pChunkDesc, bool bJustGeometry) -{ - if (pChunkDesc->chunkVersion != NODE_CHUNK_DESC_0824::VERSION && - pChunkDesc->chunkVersion != NODE_CHUNK_DESC_0824::COMPATIBLE_OLD_VERSION) - { - m_LastError.Format( - "Unknown version (0x%x) of Node chunk. The only supported versions are 0x%x and 0x%x.", - (uint)pChunkDesc->chunkVersion, - (uint)NODE_CHUNK_DESC_0824::VERSION, - (uint)NODE_CHUNK_DESC_0824::COMPATIBLE_OLD_VERSION); - return false; - } - - NODE_CHUNK_DESC_0824* nodeChunk = (NODE_CHUNK_DESC_0824*)pChunkDesc->data; - assert(nodeChunk); - SwapEndian(*nodeChunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - CNodeCGF* pNodeCGF = Construct(InplaceFactory(m_pDestructFnc), m_pAllocFnc); - m_pCGF->AddNode(pNodeCGF); - - cry_strcpy(pNodeCGF->name, nodeChunk->name); - - // Fill node object. - pNodeCGF->nChunkId = pChunkDesc->chunkId; - pNodeCGF->nParentChunkId = nodeChunk->ParentID; - pNodeCGF->nObjectChunkId = nodeChunk->ObjectID; - pNodeCGF->pParent = 0; - pNodeCGF->pMesh = 0; - - pNodeCGF->pos_cont_id = nodeChunk->pos_cont_id; - pNodeCGF->rot_cont_id = nodeChunk->rot_cont_id; - pNodeCGF->scl_cont_id = nodeChunk->scl_cont_id; - - pNodeCGF->pMaterial = 0; - if (nodeChunk->MatID > 0) - { - pNodeCGF->pMaterial = LoadMaterialFromChunk(nodeChunk->MatID); - if (!pNodeCGF->pMaterial) - { - return false; - } - } - - { - const float* const pMat = &nodeChunk->tm[0][0]; - - pNodeCGF->localTM.SetFromVectors( - Vec3(pMat[0], pMat[1], pMat[2]), - Vec3(pMat[4], pMat[5], pMat[6]), - Vec3(pMat[8], pMat[9], pMat[10]), - Vec3(pMat[12] * VERTEX_SCALE, pMat[13] * VERTEX_SCALE, pMat[14] * VERTEX_SCALE)); - } - - if (pNodeCGF->nParentChunkId > 1) - { - pNodeCGF->bIdentityMatrix = false; - } - else - { - // FIXME: 1) Other code in CryEngine sets bIdentityMatrix by analyzing worldTM instead of localTM. What is the right choice? - // FIXME: 2) bIdentityMatrix is re-computed in CLoaderCGF::ProcessNodes(). What is the point of computing it here as well? - pNodeCGF->bIdentityMatrix = pNodeCGF->localTM.IsIdentity(); - } - - if (nodeChunk->PropStrLen > 0) - { - pNodeCGF->properties.Format("%.*s", nodeChunk->PropStrLen, ((const char*)nodeChunk) + sizeof(*nodeChunk)); - } - - // By default node type is mesh. - pNodeCGF->type = CNodeCGF::NODE_MESH; - - pNodeCGF->bPhysicsProxy = false; - if (stristr2(nodeChunk->name, PHYSICS_PROXY_NODE) || stristr2(nodeChunk->name, PHYSICS_PROXY_NODE2) || stristr2(nodeChunk->name, PHYSICS_PROXY_NODE3)) - { - pNodeCGF->type = CNodeCGF::NODE_HELPER; - pNodeCGF->bPhysicsProxy = true; - m_pCGF->GetExportInfo()->bHavePhysicsProxy = true; - } - else if (nodeChunk->name[0] == '$') - { - pNodeCGF->type = CNodeCGF::NODE_HELPER; - } - - // Check if valid object node. - if (nodeChunk->ObjectID > 0) - { - IChunkFile::ChunkDesc* const pObjChunkDesc = m_pChunkFile->FindChunkById(nodeChunk->ObjectID); - if (!pObjChunkDesc) - { - assert(pObjChunkDesc); - m_LastError.Format("Failed to find chunk with id %d", nodeChunk->ObjectID); - return false; - } - if (pObjChunkDesc->chunkType == ChunkType_Mesh) - { - if (pNodeCGF->type == CNodeCGF::NODE_HELPER) - { - pNodeCGF->helperType = HP_GEOMETRY; - } - if (!LoadGeomChunk(pNodeCGF, pObjChunkDesc)) - { - return false; - } - } - else if (!bJustGeometry) - { - if (pObjChunkDesc->chunkType == ChunkType_Helper) - { - pNodeCGF->type = CNodeCGF::NODE_HELPER; - if (!LoadHelperChunk(pNodeCGF, pObjChunkDesc)) - { - return false; - } - } - } - } - else - { - // pNodeCGF->type = CNodeCGF::NODE_HELPER; - // pNodeCGF->helperType = HP_POINT; - // pNodeCGF->helperSize = Vec3(0.01f,0.01f,0.01f); - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadHelperChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->chunkVersion != HELPER_CHUNK_DESC::VERSION) - { - m_LastError.Format("Unknown version of Helper chunk"); - return false; - } - - HELPER_CHUNK_DESC& chunk = *(HELPER_CHUNK_DESC*)pChunkDesc->data; - assert(&chunk); - - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - // Fill node object. - pNode->helperType = chunk.type; - pNode->helperSize = chunk.size; - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CLoaderCGF::ProcessNodes() -{ - LOADING_TIME_PROFILE_SECTION; - - ////////////////////////////////////////////////////////////////////////// - // Bind Nodes parents. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < m_pCGF->GetNodeCount(); i++) - { - if (m_pCGF->GetNode(i)->nParentChunkId > 0) - { - for (int j = 0; j < m_pCGF->GetNodeCount(); j++) - { - if (m_pCGF->GetNode(i)->nParentChunkId == m_pCGF->GetNode(j)->nChunkId) - { - m_pCGF->GetNode(i)->pParent = m_pCGF->GetNode(j); - break; - } - } - } - } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Calculate Node world matrices. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < m_pCGF->GetNodeCount(); i++) - { - CNodeCGF* pNode = m_pCGF->GetNode(i); - Matrix34 tm = pNode->localTM; - for (CNodeCGF* pCurNode = pNode->pParent; pCurNode; pCurNode = pCurNode->pParent) - { - tm = pCurNode->localTM * tm; - } - pNode->worldTM = tm; - pNode->bIdentityMatrix = pNode->worldTM.IsIdentity(); - - if (pNode->pMesh) - { - SetupMeshSubsets(*pNode->pMesh, pNode->pMaterial); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CLoaderCGF::SetupMeshSubsets(CMesh& mesh, CMaterialCGF* pMaterialCGF) -{ - if (!m_pCGF->GetExportInfo()->bCompiledCGF) - { - const DynArray& usedMaterialIds = m_pCGF->GetUsedMaterialIDs(); - - if (mesh.m_subsets.empty()) - { - ////////////////////////////////////////////////////////////////////////// - // Setup mesh subsets. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < usedMaterialIds.size(); i++) - { - SMeshSubset meshSubset; - int nMatID = usedMaterialIds[i]; - meshSubset.nMatID = nMatID; - meshSubset.nPhysicalizeType = PHYS_GEOM_TYPE_NONE; - mesh.m_subsets.push_back(meshSubset); - } - } - } - - if (pMaterialCGF) - { - for (int i = 0; i < mesh.m_subsets.size(); i++) - { - SMeshSubset& meshSubset = mesh.m_subsets[i]; - if (pMaterialCGF->subMaterials.size() > 0) - { - int id = meshSubset.nMatID; - if (id >= (int)pMaterialCGF->subMaterials.size()) - { - // Let's use 3dsMax's approach of handling material ids out of range - id %= (int)pMaterialCGF->subMaterials.size(); - } - - if (id >= 0 && pMaterialCGF->subMaterials[id] != NULL) - { - meshSubset.nPhysicalizeType = pMaterialCGF->subMaterials[id]->nPhysicalizeType; - } - else - { - Warning("Submaterial %d is not available for subset %d in %s", meshSubset.nMatID, i, m_filename); - } - } - else - { - meshSubset.nPhysicalizeType = pMaterialCGF->nPhysicalizeType; - } - } - } -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadGeomChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc) -{ - LOADING_TIME_PROFILE_SECTION; - - // First check if this geometry chunk was already loaded by some node. - int nNumNodes = m_pCGF->GetNodeCount(); - for (int i = 0; i < nNumNodes; i++) - { - CNodeCGF* pOldNode = m_pCGF->GetNode(i); - if (pOldNode != pNode && pOldNode->nObjectChunkId == pChunkDesc->chunkId) - { - pNode->pMesh = pOldNode->pMesh; - pNode->pSharedMesh = pOldNode; - return true; - } - } - - assert(pChunkDesc && pChunkDesc->chunkType == ChunkType_Mesh); - - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::VERSION || - pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::COMPATIBLE_OLD_VERSION || - pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0802::VERSION) - { - m_pCGF->GetExportInfo()->bCompiledCGF = true; - return LoadCompiledMeshChunk(pNode, pChunkDesc); - } - - // Uncompiled format - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0745::VERSION || - pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0745::COMPATIBLE_OLD_VERSION) - { -#if !defined(RESOURCE_COMPILER) && !defined(ENABLE_NON_COMPILED_CGF) - m_LastError.Format("%s: non-compiled geometry chunk in %s", __FUNCTION__, m_filename); - return false; -#else - m_pCGF->GetExportInfo()->bCompiledCGF = false; - - const int maxLinkCount = - m_pCGF->GetExportInfo()->b8WeightsPerVertex - ? 8 - : ((m_maxWeightsPerVertex <= 8) ? m_maxWeightsPerVertex : 8); // CMesh doesn't support more than 8 weights - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - pChunkDesc->bSwapEndian = false; - - uint8* pMeshChunkData = (uint8*)pChunkDesc->data; - - MESH_CHUNK_DESC_0745* chunk; - StepData(chunk, pMeshChunkData, 1, bSwapEndianness); - - if (!(chunk->flags2 & MESH_CHUNK_DESC_0745::FLAG2_HAS_TOPOLOGY_IDS)) - { - m_LastError.Format("%s: obsolete non-compiled geometry chunk format in %s", __FUNCTION__, m_filename); - return false; - } - - ////////////////////////////////////////////////////////////////////////// - // Preparing source mesh data (may contain duplicate vertices) - ////////////////////////////////////////////////////////////////////////// - - MeshUtils::Mesh mesh; - const char* err = 0; - - if (chunk->nVerts <= 0) - { - m_LastError.Format("%s: missing vertices in %s", __FUNCTION__, m_filename); - return false; - } - if (chunk->nFaces <= 0) - { - m_LastError.Format("%s: missing faces in %s", __FUNCTION__, m_filename); - return false; - } - if (chunk->nTVerts != 0 && chunk->nTVerts != chunk->nVerts) - { - m_LastError.Format("%s: Number of texture coordinates doesn't match number of vertices", __FUNCTION__); - return false; - } - - // Preparing positions and normals - { - CryVertex* p; - StepData(p, pMeshChunkData, chunk->nVerts, bSwapEndianness); - - err = mesh.SetPositions(&p->p.x, chunk->nVerts, sizeof(*p), VERTEX_SCALE); // VERTEX_SCALE - to convert from centimeters to meters - if (!err) - { - err = mesh.SetNormals(&p->n.x, chunk->nVerts, sizeof(*p)); - } - - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - // Preparing faces and face material IDs - { - CryFace* p; - StepData(p, pMeshChunkData, chunk->nFaces, bSwapEndianness); - err = mesh.SetFaces(&p->v0, chunk->nFaces, sizeof(*p)); - if (!err) - { - err = mesh.SetFaceMatIds(&p->MatID, chunk->nFaces, sizeof(*p), MAX_SUB_MATERIALS - 1); - } - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - mesh.RemoveDegradedFaces(); - } - - // Preparing topology IDs - { - int* p; - StepData(p, pMeshChunkData, chunk->nVerts, bSwapEndianness); - err = mesh.SetTopologyIds(p, chunk->nVerts, sizeof(*p)); - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - // Preparing texture coordinates - if (chunk->nTVerts > 0) - { - CryUV* p; - StepData(p, pMeshChunkData, chunk->nVerts, bSwapEndianness); - err = mesh.SetTexCoords(&p->u, chunk->nVerts, sizeof(*p), true, 0); - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - // Preparing vertex-bone links - if (chunk->flags1 & MESH_CHUNK_DESC_0745::FLAG1_BONE_INFO) - { - mesh.m_links.resize(chunk->nVerts); - - for (int i = 0; i < chunk->nVerts; ++i) - { - MeshUtils::VertexLinks& linksDst = mesh.m_links[i]; - - int32* pNumLinks; - StepData(pNumLinks, pMeshChunkData, 1, bSwapEndianness); - - if (pNumLinks == nullptr) - { - return false; - } - - if (*pNumLinks <= 0) - { - m_LastError.Format("%s: Number of links for vertex is invalid: %i", __FUNCTION__, *pNumLinks); - return false; - } - - linksDst.links.resize(*pNumLinks); - - CryLink* pLinksSrc; - StepData(pLinksSrc, pMeshChunkData, *pNumLinks, bSwapEndianness); - for (int j = 0; j < *pNumLinks; ++j) - { - linksDst.links[j].boneId = pLinksSrc[j].BoneID; - linksDst.links[j].weight = pLinksSrc[j].Blending; - linksDst.links[j].offset = pLinksSrc[j].offset * VERTEX_SCALE; - } - - err = linksDst.Normalize(MeshUtils::VertexLinks::eSort_ByWeight, 0.0f, maxLinkCount); - - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - } - - // Preparing colors - if (chunk->flags2 & MESH_CHUNK_DESC_0745::FLAG2_HAS_VERTEX_COLOR) - { - CryIRGB* p; - StepData(p, pMeshChunkData, chunk->nVerts, bSwapEndianness); - assert(&p->r < &p->b); - err = mesh.SetColors(&p->r, chunk->nVerts, sizeof(*p)); - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - // Preparing alphas - if (chunk->flags2 & MESH_CHUNK_DESC_0745::FLAG2_HAS_VERTEX_ALPHA) - { - uint8* p; - StepData(p, pMeshChunkData, chunk->nVerts, bSwapEndianness); - err = mesh.SetAlphas(p, chunk->nVerts, sizeof(*p)); - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - // Prevent sharing materials by vertices (this call might create new vertices) - mesh.SetVertexMaterialIdsFromFaceMaterialIds(); - - // Validation - { - err = mesh.Validate(); - if (err) - { - m_LastError.Format("%s: Failed: %s", __FUNCTION__, err); - return false; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Compute vertex remapping - ////////////////////////////////////////////////////////////////////////// - - mesh.ComputeVertexRemapping(); - - ////////////////////////////////////////////////////////////////////////// - // Creating resulting mesh - ////////////////////////////////////////////////////////////////////////// - - CMesh* const pMesh = new CMesh(); - - const int nVerts = mesh.m_vertexOldToNew.size(); - const int nVertsNew = mesh.m_vertexNewToOld.size(); - - // Filling positions, normals, topology IDs, texture coordinates, colors - { - pMesh->SetVertexCount(nVertsNew); - pMesh->ReallocStream(CMesh::TOPOLOGY_IDS, 0, nVertsNew); - pMesh->ReallocStream(CMesh::TEXCOORDS, 0, nVertsNew); - if (!mesh.m_colors.empty() || !mesh.m_alphas.empty()) - { - pMesh->ReallocStream(CMesh::COLORS, 0, nVertsNew); - } - - for (uint32 uvSet = 0; uvSet < mesh.m_texCoords.size(); ++uvSet) - { - if (!mesh.m_texCoords[uvSet].empty()) - { - SMeshTexCoord* texCoords = pMesh->GetStreamPtr(CMesh::TEXCOORDS, uvSet); - for (int i = 0; i < nVertsNew; ++i) - { - const int origVertex = mesh.m_vertexNewToOld[i]; - texCoords[i] = SMeshTexCoord(mesh.m_texCoords[uvSet][origVertex].x, mesh.m_texCoords[uvSet][origVertex].y); - } - } - } - - for (int i = 0; i < nVertsNew; ++i) - { - const int origVertex = mesh.m_vertexNewToOld[i]; - - pMesh->m_pPositions[i] = mesh.m_positions[origVertex]; - - pMesh->m_pNorms[i] = SMeshNormal(mesh.m_normals[origVertex]); - - pMesh->m_pTopologyIds[i] = mesh.m_topologyIds[origVertex]; - - if (pMesh->m_pColor0) - { - uint8 r = 0xFF; - uint8 g = 0xFF; - uint8 b = 0xFF; - uint8 a = 0xFF; - if (!mesh.m_colors.empty()) - { - r = mesh.m_colors[origVertex].r; - g = mesh.m_colors[origVertex].g; - b = mesh.m_colors[origVertex].b; - } - if (!mesh.m_alphas.empty()) - { - a = mesh.m_alphas[origVertex]; - } - - pMesh->m_pColor0[i] = SMeshColor(r, g, b, a); - } - } - } - - // Filling vertex-bone links - { - m_arrLinksTmp.clear(); - if (!mesh.m_links.empty()) - { - m_arrLinksTmp.reserve(nVertsNew); - for (int i = 0; i < nVertsNew; ++i) - { - const int origVertex = mesh.m_vertexNewToOld[i]; - m_arrLinksTmp.push_back(mesh.m_links[origVertex]); - } - - // Remember the mapping table for future re-mapping of uncompiled Morph Target vertices (if any) - m_vertexOldToNew = mesh.m_vertexOldToNew; - } - } - - // Filling faces - { - const int nFaces = mesh.GetFaceCount(); - pMesh->SetFaceCount(nFaces); - - DynArray& usedMaterialIds = m_pCGF->GetUsedMaterialIDs(); - - for (int i = 0; i < nFaces; ++i) - { - const MeshUtils::Face& cf = mesh.m_faces[i]; - const int matId = mesh.m_faceMatIds[i]; - - SMeshFace& face = pMesh->m_pFaces[i]; - - face.v[0] = mesh.m_vertexOldToNew[cf.vertexIndex[0]]; - face.v[1] = mesh.m_vertexOldToNew[cf.vertexIndex[1]]; - face.v[2] = mesh.m_vertexOldToNew[cf.vertexIndex[2]]; - - // Map material ID to index of subset - if (!MatIdToSubset[matId]) - { - MatIdToSubset[matId] = 1 + nLastChunkId++; - // Order of material ids in usedMaterialIds correspond to the indices of chunks. - usedMaterialIds.push_back(matId); - } - face.nSubset = MatIdToSubset[matId] - 1; - } - } - - // Computing AABB - pMesh->m_bbox.Reset(); - for (int i = 0; i < nVertsNew; ++i) - { - pMesh->m_bbox.Add(pMesh->m_pPositions[i]); - } - - // Saving results - pNode->pMesh = pMesh; - - return true; -#endif - } - - m_LastError.Format("%s: unknown geometry chunk version in %s", __FUNCTION__, m_filename); - return false; -} - -template -bool CLoaderCGF::LoadStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, ECgfStreamType Type, int streamIndex, CMesh::EStream MStream) -{ - if (chunk.GetStreamChunkID(Type, streamIndex) <= 0) - { - return true; - } - - void* pStreamData; - int nStreamType; - int nStreamIndex; - int nElemCount; - int nElemSize; - bool bSwapEndianness; - if (!LoadStreamDataChunk(chunk.GetStreamChunkID(Type, streamIndex), pStreamData, nStreamType, nStreamIndex, nElemCount, nElemSize, bSwapEndianness)) - { - return false; - } - if (nStreamType != Type) - { - m_LastError.Format("Mesh stream type %d stream number %d has unknown type (%d instead of %d)", (int)MStream, streamIndex, (int)nStreamType, (int)Type); - return false; - } - if (nStreamIndex != streamIndex) - { - m_LastError.Format("Mesh stream index for type %d did not match what was expected (%d instead of %d)", (int)Type, nStreamIndex, streamIndex); - return false; - } - if (nElemSize != sizeof(T)) - { - m_LastError.Format("Mesh stream type %d stream number %d has damaged data (elemSize:%u)", (int)MStream, streamIndex, (uint)nElemSize); - return false; - } - - SwapEndian((T*)pStreamData, nElemCount, bSwapEndianness); - - void* pMeshElements = 0; - { - const bool bSourceAligned = (((UINT_PTR)pStreamData & 0x3) == 0); - const bool bShare = (m_bUseReadOnlyMesh && bSourceAligned && m_bAllowStreamSharing); - - if (bShare) - { - mesh.SetSharedStream(MStream, streamIndex, pStreamData, nElemCount); - } - else - { - mesh.ReallocStream(MStream, streamIndex, nElemCount); - } - - int nMeshElemSize = 0; - mesh.GetStreamInfo(MStream, streamIndex, pMeshElements, nMeshElemSize); - if (nMeshElemSize != nElemSize || nMeshElemSize != sizeof(T)) - { - m_LastError.Format("Mesh stream type %d stream number %d has damaged data (elemCount:%u, elemSize:%u)", - (int)MStream, streamIndex, (uint)nElemCount, (uint)nMeshElemSize); - - return false; - } - - if (!bShare) - { - memcpy(pMeshElements, pStreamData, nElemCount * nElemSize); - } - } - - return true; -} - -template -bool CLoaderCGF::LoadStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, ECgfStreamType Type, int streamIndex, CMesh::EStream MStreamA, CMesh::EStream MStreamB) -{ - if (chunk.GetStreamChunkID(Type, streamIndex) <= 0) - { - return true; - } - - void* pStreamData; - int nStreamType; - int nStreamIndex; - int nElemCount; - int nElemSize; - bool bSwapEndianness; - if (!LoadStreamDataChunk(chunk.GetStreamChunkID(Type, streamIndex), pStreamData, nStreamType, nStreamIndex, nElemCount, nElemSize, bSwapEndianness)) - { - return false; - } - if (nStreamType != Type) - { - m_LastError.Format("Mesh stream type %d/%d stream number %d/%d has unknown type (%d instead of %d)", (int)MStreamA, (int)MStreamB, streamIndex, streamIndex, (int)nStreamType, (int)Type); - return false; - } - if (nStreamIndex != streamIndex) - { - m_LastError.Format("Mesh stream index for type %d did not match what was expected (%d instead of %d)", (int)Type, nStreamIndex, streamIndex); - return false; - } - if ((nElemSize != sizeof(TA) && nElemSize != sizeof(TB))) - { - m_LastError.Format("Mesh stream type %d/%d stream number %d/%d has unsupported element size (%u instead of %u or %u)", (int)MStreamA, (int)MStreamB, streamIndex, streamIndex, (uint)nElemSize, (uint)sizeof(TA), (uint)sizeof(TB)); - return false; - } - - const bool bUseA = (nElemSize == sizeof(TA)); - - if (bUseA) - { - SwapEndian((TA*)pStreamData, nElemCount, bSwapEndianness); - } - else - { - SwapEndian((TB*)pStreamData, nElemCount, bSwapEndianness); - } - - void* pMeshElements = 0; - { - const bool bSourceAligned = (((UINT_PTR)pStreamData & 0x3) == 0); - const bool bShare = (m_bUseReadOnlyMesh && bSourceAligned && m_bAllowStreamSharing); - - if (bShare) - { - mesh.SetSharedStream((bUseA ? MStreamA : MStreamB), streamIndex, pStreamData, nElemCount); - } - else - { - mesh.ReallocStream((bUseA ? MStreamA : MStreamB), streamIndex, nElemCount); - } - - int nMeshElemSize = 0; - mesh.GetStreamInfo((bUseA ? MStreamA : MStreamB), streamIndex, pMeshElements, nMeshElemSize); - if (nMeshElemSize != nElemSize || nMeshElemSize != (bUseA ? sizeof(TA) : sizeof(TB))) - { - m_LastError.Format("Mesh stream type %d stream number %d has damaged data (elemCount:%u, elemSize:%u)", - (int)(bUseA ? MStreamA : MStreamB), streamIndex, (uint)nElemCount, (uint)nMeshElemSize); - return false; - } - - if (!bShare) - { - memcpy(pMeshElements, pStreamData, nElemCount * nElemSize); - } - } - - return true; -} - -template -bool CLoaderCGF::LoadBoneMappingStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, const std::vector >& globalBonesPerSubset) -{ - const ECgfStreamType Type = CGF_STREAM_BONEMAPPING; - CMesh::EStream MStream = CMesh::BONEMAPPING; - // There is only one index stream per mesh, so get index stream 0 - int streamIndex = 0; - if (chunk.GetStreamChunkID(Type, streamIndex) <= 0) - { - return true; - } - - void* pStreamData; - int nStreamType; - int nStreamIndex; - int nElemCount; - int nStreamElemSize; - bool bSwapEndianness; - if (!LoadStreamDataChunk(chunk.GetStreamChunkID(Type, streamIndex), pStreamData, nStreamType, nStreamIndex, nElemCount, nStreamElemSize, bSwapEndianness)) - { - return false; - } - if (nStreamType != Type) - { - m_LastError.Format("Bone mapping stream %d has unknown type (%d instead of %d)", (int)MStream, (int)nStreamType, (int)Type); - return false; - } - - if (nElemCount != mesh.GetVertexCount() && nElemCount != 2 * mesh.GetVertexCount()) - { - m_LastError.Format("Bone mapping stream %d has wrong # vertices %d (expected %d or %d)", (int)MStream, nElemCount, mesh.GetVertexCount(), 2 * mesh.GetVertexCount()); - return false; - } - - COMPILE_TIME_ASSERT(sizeof(mesh.m_pBoneMapping[0]) == sizeof(SMeshBoneMapping_uint16)); - - if (nStreamElemSize == sizeof(SMeshBoneMapping_uint8)) - { - // Obsolete format. We support it just because many existing asset files use it. - - if (globalBonesPerSubset.size() != mesh.m_subsets.size()) - { - m_LastError.Format("Bad or missing bone remapping tables. Contact an RC programmer."); - return false; - } - - SwapEndian((SMeshBoneMapping_uint8*)pStreamData, nElemCount, bSwapEndianness); - - // Converting local (per-preset) uint8 bone indices to global bone uint16 indices - - mesh.ReallocStream(MStream, nStreamIndex, nElemCount); - - SMeshBoneMapping_uint16* const pMeshElements = mesh.GetStreamPtr(MStream, nStreamIndex); - if (!pMeshElements) - { - // Should never happen because we did check it by COMPILE_TIME_ASSERT() above. - m_LastError.Format("Bone mapping has invalid size. Contact an RC programmer."); - return false; - } - - // Filling bone indices with 0xFFFF allows us to perform input data - // validation (see code with '== 0xFFFF' below) - memset(pMeshElements, 0xFF, nElemCount * sizeof(pMeshElements[0])); - - const SMeshBoneMapping_uint8* const pSrcBoneMapping = (const SMeshBoneMapping_uint8*)pStreamData; - - const int vertexCount = mesh.GetVertexCount(); - const int indexCount = mesh.GetIndexCount(); - - for (int subset = 0; subset < mesh.m_subsets.size(); ++subset) - { - SMeshSubset& meshSubset = mesh.m_subsets[subset]; - - const std::vector& globalBones = globalBonesPerSubset[subset]; - - if (meshSubset.nNumIndices == 0) - { - continue; - } - - for (int extra = 0; extra < nElemCount; extra += vertexCount) - { - for (int j = meshSubset.nFirstIndexId; j < meshSubset.nFirstIndexId + meshSubset.nNumIndices; ++j) - { - const int vIdx = mesh.m_pIndices[j]; - - if (vIdx < meshSubset.nFirstVertId || vIdx >= meshSubset.nFirstVertId + meshSubset.nNumVerts) - { - m_LastError.Format("Index stream contains invalid vertex index."); - return false; - } - - for (int k = 0; k < 4; ++k) - { - const uint8 weight = pSrcBoneMapping[vIdx + extra].weights[k]; - if (weight <= 0) - { - if (pMeshElements[vIdx + extra].boneIds[k] == 0xFFFF) - { - pMeshElements[vIdx + extra].weights[k] = 0; - pMeshElements[vIdx + extra].boneIds[k] = 0; - } - else if (pMeshElements[vIdx + extra].weights[k] != 0 || - pMeshElements[vIdx + extra].boneIds[k] != 0) - { - m_LastError.Format("Conflicting vertex-bone references."); - return false; - } - continue; - } - - const uint8 boneIdx = pSrcBoneMapping[vIdx + extra].boneIds[k]; - if (boneIdx < 0 || (size_t)boneIdx >= globalBones.size()) - { - m_LastError.Format( - "Bad bone mapping found in subset %d, vertex %d: boneIdx %d, # bones in subset %d.", - subset, vIdx, boneIdx, (int)globalBones.size()); - return false; - } - - const uint16 globalBoneIdx = globalBones[boneIdx]; - - if (pMeshElements[vIdx + extra].boneIds[k] == 0xFFFF) - { - pMeshElements[vIdx + extra].weights[k] = weight; - pMeshElements[vIdx + extra].boneIds[k] = globalBoneIdx; - } - else if (pMeshElements[vIdx + extra].weights[k] != weight || - pMeshElements[vIdx + extra].boneIds[k] != globalBoneIdx) - { - m_LastError.Format("Conflicting vertex-bone references."); - return false; - } - } - } - } - } - - int orphanVertexCount = 0; - for (int i = 0; i < nElemCount; ++i) - { - for (int k = 0; k < 4; ++k) - { - const uint boneIdx = pMeshElements[i].boneIds[k]; - if (boneIdx >= 0xFFFF) - { - ++orphanVertexCount; - pMeshElements[i].weights[k] = 0; - pMeshElements[i].boneIds[k] = 0; - } - } - } - - if (orphanVertexCount) - { - orphanVertexCount /= 4 * (nElemCount / vertexCount); - CryWarning( - VALIDATOR_MODULE_ASSETS, VALIDATOR_WARNING, - "Found %d orphan vertices", orphanVertexCount); - } - } - else if (nStreamElemSize == sizeof(SMeshBoneMapping_uint16)) - { - SwapEndian((SMeshBoneMapping_uint16*)pStreamData, nElemCount, bSwapEndianness); - - const bool bSourceAligned = (((UINT_PTR)pStreamData & 0x3) == 0); - const bool bShare = (m_bUseReadOnlyMesh && bSourceAligned && m_bAllowStreamSharing); - - if (bShare) - { - mesh.SetSharedStream(MStream, nStreamIndex, pStreamData, nElemCount); - } - else - { - mesh.ReallocStream(MStream, nStreamIndex, nElemCount); - } - - SMeshBoneMapping_uint16* const pMeshElements = mesh.GetStreamPtr(MStream, nStreamIndex); - if (!pMeshElements) - { - // Should never happen because we did check it by COMPILE_TIME_ASSERT() above. - m_LastError.Format("Bone mapping has invalid size. Contact an RC programmer."); - return false; - } - - if (!bShare) - { - memcpy(pMeshElements, pStreamData, nElemCount * sizeof(pMeshElements[0])); - } - } - else - { - m_LastError.Format("Bone mapping stream %d has damaged data (elemSize:%u)", (int)MStream, (uint)nStreamElemSize); - return false; - } - - // Validation - { - SMeshBoneMapping_uint16* const pMeshElements = mesh.GetStreamPtr(MStream, nStreamIndex); - - for (int i = 0; i < nElemCount; ++i) - { - for (int k = 0; k < 4; ++k) - { - const uint boneIdx = pMeshElements[i].boneIds[k]; - if (boneIdx >= MAX_NUMBER_OF_BONES) - { - m_LastError.Format("Bad bone index detected: %u.", (uint)boneIdx); - return false; - } - } - } - } - - return true; -} - -template -bool CLoaderCGF::LoadIndexStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk) -{ - const ECgfStreamType Type = CGF_STREAM_INDICES; - CMesh::EStream MStream = CMesh::INDICES; - // There is only one index stream per mesh - int streamIndex = 0; - - if (chunk.GetStreamChunkID(Type, streamIndex) <= 0) - { - return true; - } - - void* pStreamData; - int nStreamType; - int nStreamIndex; - int nElemCount; - int nStreamElemSize; - bool bSwapEndianness; - if (!LoadStreamDataChunk(chunk.GetStreamChunkID(Type, streamIndex), pStreamData, nStreamType, nStreamIndex, nElemCount, nStreamElemSize, bSwapEndianness)) - { - return false; - } - if (nStreamType != Type) - { - m_LastError.Format("Index stream %d has unknown type (%d instead of %d)", (int)MStream, (int)nStreamType, (int)Type); - return false; - } - - if (nStreamElemSize == sizeof(uint16)) - { - SwapEndian((uint16*)pStreamData, nElemCount, bSwapEndianness); - } - else if (nStreamElemSize == sizeof(uint32)) - { - SwapEndian((uint32*)pStreamData, nElemCount, bSwapEndianness); - } - else - { - m_LastError.Format("Index stream %d has damaged data (elemSize:%u)", (int)MStream, (uint)nStreamElemSize); - return false; - } - - const bool bSourceAligned = (((UINT_PTR)pStreamData & 0x3) == 0); - const bool bShare = (m_bUseReadOnlyMesh && bSourceAligned && m_bAllowStreamSharing); - - COMPILE_TIME_ASSERT(sizeof(mesh.m_pIndices[0]) == sizeof(vtx_idx)); - COMPILE_TIME_ASSERT(sizeof(vtx_idx) == 2 || sizeof(vtx_idx) == 4); - - if (nStreamElemSize == sizeof(vtx_idx)) - { - if (bShare) - { - mesh.SetSharedStream(MStream, nStreamIndex, pStreamData, nElemCount); - } - else - { - mesh.ReallocStream(MStream, nStreamIndex, nElemCount); - } - - void* pMeshIndices = 0; - int nMeshIndexSize = 0; - mesh.GetStreamInfo(MStream, nStreamIndex, pMeshIndices, nMeshIndexSize); - if (nMeshIndexSize != sizeof(vtx_idx)) - { - // Should never happen - we already did COMPILE_TIME_ASSERT(sizeof(mesh.m_pIndices[0]) == sizeof(vtx_idx)) - m_LastError.Format("Vertex index has invalid size. Contact an RC programmer."); - return false; - } - - if (!bShare) - { - memcpy(pMeshIndices, pStreamData, nElemCount * nStreamElemSize); - } - } - else - { - // Converting index format uint16 <--> uint32 - -#if !defined(RESOURCE_COMPILER) -#if 0 // Sokov: commented out the warning because it was confusing users. We will uncomment it after implementing converting files to proper index format during asset exporting. - CryWarning( - VALIDATOR_MODULE_ASSETS, VALIDATOR_WARNING, - "%s: This asset contains vertex indices in incorrect format (%u-bit instead of %u-bit). " - "Probably it didn't go through build process yet. " - "Disregard this message if this asset was just exported.", - m_filename, (uint)nStreamElemSize * 8, (uint)sizeof(vtx_idx) * 8); -#endif -#endif - - mesh.ReallocStream(MStream, nStreamIndex, nElemCount); - - void* pMeshIndices = 0; - int nMeshIndexSizeCheck = 0; - mesh.GetStreamInfo(MStream, nStreamIndex, pMeshIndices, nMeshIndexSizeCheck); - if (nMeshIndexSizeCheck != sizeof(vtx_idx)) - { - // Should never happen - we already did COMPILE_TIME_ASSERT(sizeof(mesh.m_pIndices[0]) == sizeof(vtx_idx)) - m_LastError.Format("Vertex index has invalid size. Contact an RC programmer."); - return false; - } - - if (nStreamElemSize == sizeof(uint16)) - { - const uint16* const pSrc = (const uint16*)pStreamData; - for (int i = 0; i < nElemCount; ++i) - { - ((uint32*)pMeshIndices)[i] = (uint32)pSrc[i]; - } - } - else - { - const uint32* const pSrc = (const uint32*)pStreamData; - for (int i = 0; i < nElemCount; ++i) - { - const uint32 idx = pSrc[i]; - if (idx >= 0xffff) // ">=": index 0xffff is reserved (the engine uses it to mark invalid indices etc) - { - m_LastError.Format("Cannot convert index stream %d from %u-bit to %u-bit format because it contains index %u", (int)MStream, (uint)nStreamElemSize * 8, (uint)sizeof(vtx_idx) * 8, (uint)pSrc[i]); - return false; - } - ((uint16*)pMeshIndices)[i] = (uint16)idx; - } - } - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadCompiledMeshChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc) -{ - if (!pChunkDesc || pChunkDesc->chunkType != ChunkType_Mesh) - { - m_LastError.Format("Corrupted compiled mesh chunk"); - return false; - } - - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0802::VERSION) - { - MESH_CHUNK_DESC_0802& chunk = *(MESH_CHUNK_DESC_0802*)pChunkDesc->data; - return LoadCompiledMeshChunk(pNode, pChunkDesc, chunk); - } - - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::VERSION || pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::COMPATIBLE_OLD_VERSION) - { - MESH_CHUNK_DESC_0801& chunk = *(MESH_CHUNK_DESC_0801*)pChunkDesc->data; - return LoadCompiledMeshChunk(pNode, pChunkDesc, chunk); - } - - m_LastError.Format("Unknown version of compiled mesh chunk"); - return false; -} - -template -bool CLoaderCGF::LoadCompiledMeshChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc, MESH_CHUNK_DESC chunk) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->bSwapEndian) - { - SwapEndian(chunk, true); - pChunkDesc->bSwapEndian = false; - } - - Vec3 bboxMin, bboxMax; - memcpy(&bboxMin, &chunk.bboxMin, sizeof(bboxMin)); - memcpy(&bboxMax, &chunk.bboxMax, sizeof(bboxMax)); - - pNode->meshInfo.nVerts = chunk.nVerts; - pNode->meshInfo.nIndices = chunk.nIndices; - pNode->meshInfo.nSubsets = chunk.nSubsets; - pNode->meshInfo.bboxMin = bboxMin; - pNode->meshInfo.bboxMax = bboxMax; - pNode->meshInfo.fGeometricMean = chunk.geometricMeanFaceArea; - pNode->nPhysicalizeFlags = chunk.nFlags2; - - for (int nPhysGeomType = 0; nPhysGeomType < 4; nPhysGeomType++) - { - if (chunk.nPhysicsDataChunkId[nPhysGeomType] > 0) - { - LoadPhysicsDataChunk(pNode, nPhysGeomType, chunk.nPhysicsDataChunkId[nPhysGeomType]); - } - } - - if (chunk.nFlags & MESH_CHUNK_DESC::MESH_IS_EMPTY) - { - // This is an empty mesh. - if (pNode->type == CNodeCGF::NODE_MESH) - { - // Do not create CMesh for it. - m_pCGF->GetExportInfo()->bNoMesh = true; - } - return true; - } - - std::unique_ptr pMesh(new CMesh()); - CMesh& mesh = *(pMesh.get()); - - if (!m_bUseReadOnlyMesh) - { - mesh.SetVertexCount(chunk.nVerts); - mesh.SetIndexCount(chunk.nIndices); - - if (chunk.GetStreamChunkID(CGF_STREAM_TEXCOORDS, 0) > 0) - { - mesh.ReallocStream(CMesh::TEXCOORDS, 0, chunk.nVerts); - } - } - - mesh.m_bbox = AABB(bboxMin, bboxMax); - - std::vector > globalBonesPerSubset; - - if (chunk.nSubsets > 0 && chunk.nSubsetsChunkId > 0) - { - IChunkFile::ChunkDesc* pSubsetChunkDesc = m_pChunkFile->FindChunkById(chunk.nSubsetsChunkId); - if (!pSubsetChunkDesc || pSubsetChunkDesc->chunkType != ChunkType_MeshSubsets) - { - m_LastError.Format("MeshSubsets Chunk not found in CGF file %s", m_filename); - return false; - } - if (!LoadMeshSubsetsChunk(mesh, pSubsetChunkDesc, globalBonesPerSubset)) - { - return false; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Read streams - ////////////////////////////////////////////////////////////////////////// - - COMPILE_TIME_ASSERT(sizeof(Vec3f16) == 8); - - bool ok = true; - - // Read position stream. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_POSITIONS, 0, CMesh::POSITIONS, CMesh::POSITIONSF16); - if (mesh.m_streamSize[CMesh::POSITIONSF16][0] > 0 && !m_bUseReadOnlyMesh) - { - const int count = mesh.m_streamSize[CMesh::POSITIONSF16][0]; - mesh.ReallocStream(CMesh::POSITIONS, 0, count); - - void* pSrc = 0; - int nSrcElementSize = 0; - mesh.GetStreamInfo(CMesh::POSITIONSF16, 0, pSrc, nSrcElementSize); - assert(pSrc); - - void* pDst = 0; - int nDstElementSize = 0; - mesh.GetStreamInfo(CMesh::POSITIONS, 0, pDst, nDstElementSize); - - if (pDst) - { - const Vec3f16* const pS = (const Vec3f16*)pSrc; - Vec3* const pD = (Vec3*)pDst; - for (int i = 0; i < count; ++i) - { - pD[i] = pS[i].ToVec3(); - } - mesh.ReallocStream(CMesh::POSITIONSF16, 0, 0); - } - } - - // Read normals stream. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_NORMALS, 0, CMesh::NORMALS); - - // Read Texture coordinates stream. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_TEXCOORDS, 0, CMesh::TEXCOORDS); - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0802::VERSION) - { - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_TEXCOORDS, 1, CMesh::TEXCOORDS); - } - // Read indices stream. - ok = ok && LoadIndexStreamChunk(mesh, chunk); - - // Read colors stream. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_COLORS, 0, CMesh::COLORS); - - // Read 2nd colors stream - // For 0801 and prior compatable versions, a second color stream would have a stream type of CGF_STREAM_COLORS2, since only one stream per type was allowed - if (pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::VERSION || pChunkDesc->chunkVersion == MESH_CHUNK_DESC_0801::COMPATIBLE_OLD_VERSION) - { - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_COLORS2, 0, CMesh::COLORS); - } - // For 0802 (which coincides with multiple-uv sets implementation) and beyond, a 2nd color stream would have a type of CGF_STREAM_COLORS with an index of 1 - else - { - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_COLORS, 1, CMesh::COLORS); - } - - // Read Vertex Mapping. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_VERT_MATS, 0, CMesh::VERT_MATS); - - // Read Tangent Streams. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_TANGENTS, 0, CMesh::TANGENTS); - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_QTANGENTS, 0, CMesh::QTANGENTS); - - // Read interleaved stream. - ok = ok && LoadStreamChunk(mesh, chunk, CGF_STREAM_P3S_C4B_T2S, 0, CMesh::P3S_C4B_T2S); - - ok = ok && LoadBoneMappingStreamChunk(mesh, chunk, globalBonesPerSubset); - - if (!ok) - { - return false; - } - - if (chunk.nFlags & MESH_CHUNK_DESC::HAS_EXTRA_WEIGHTS) - { - // The memory being used by the extraWeight array has been allocated in the LoadBoneMappingStreamChunk. - mesh.m_pExtraBoneMapping = &mesh.m_pBoneMapping[mesh.GetVertexCount()]; - } - - if (chunk.nFlags & MESH_CHUNK_DESC::HAS_TEX_MAPPING_DENSITY) - { - mesh.m_texMappingDensity = chunk.texMappingDensity; - } - else - { - mesh.RecomputeTexMappingDensity(); - } - - - if (chunk.nFlags & MESH_CHUNK_DESC::HAS_FACE_AREA) - { - mesh.m_geometricMeanFaceArea = chunk.geometricMeanFaceArea; - } - else - { - //if the chunk does not have face area than try computing it - mesh.RecomputeGeometricMeanFaceArea(); - } - - if (mesh.m_geometricMeanFaceArea <= 0.0f) - { - Warning("Invalid geometric mean face area for node %s on file %s", pNode->name, this->m_filename); - } - - pNode->pMesh = pMesh.release(); - - if (chunk.GetStreamChunkID(CGF_STREAM_SKINDATA, 0) > 0) - { - int nStreamType, nStreamIndex, nStreamCount, nElemSize; - void* pStreamData; - bool bSwapEndianness; - if (!LoadStreamDataChunk(chunk.GetStreamChunkID(CGF_STREAM_SKINDATA, 0), pStreamData, nStreamType, nStreamIndex, nStreamCount, nElemSize, bSwapEndianness)) - { - return false; - } - SwapEndian((CrySkinVtx*)pStreamData, nStreamCount, bSwapEndianness); - memcpy(pNode->pSkinInfo = new CrySkinVtx[nStreamCount], pStreamData, nStreamCount * nElemSize); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadMeshSubsetsChunk(CMesh& mesh, IChunkFile::ChunkDesc* pChunkDesc, std::vector >& globalBonesPerSubset) -{ - LOADING_TIME_PROFILE_SECTION; - - globalBonesPerSubset.clear(); - - if (pChunkDesc->chunkType != ChunkType_MeshSubsets) - { - m_LastError.Format("Unknown type in mesh subset chunk"); - return false; - } - - if (pChunkDesc->chunkVersion != MESH_SUBSETS_CHUNK_DESC_0800::VERSION) - { - m_LastError.Format("Unknown version of mesh subset chunk"); - return false; - } - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - pChunkDesc->bSwapEndian = false; - - uint8* pCurDataLoc = (uint8*)pChunkDesc->data; - - MESH_SUBSETS_CHUNK_DESC_0800& chunk = *StepData(pCurDataLoc, bSwapEndianness); - - const bool cbBoneIDs = (chunk.nFlags & MESH_SUBSETS_CHUNK_DESC_0800::BONEINDICES) != 0; - const bool cbSubsetTexelDensities = (chunk.nFlags & MESH_SUBSETS_CHUNK_DESC_0800::HAS_SUBSET_TEXEL_DENSITY) != 0; - - for (int i = 0; i < chunk.nCount; i++) - { - MESH_SUBSETS_CHUNK_DESC_0800::MeshSubset& meshSubset = *StepData(pCurDataLoc, bSwapEndianness); - - SMeshSubset subset; - - subset.nFirstIndexId = meshSubset.nFirstIndexId; - subset.nNumIndices = meshSubset.nNumIndices; - subset.nFirstVertId = meshSubset.nFirstVertId; - subset.nNumVerts = meshSubset.nNumVerts; - subset.nMatID = meshSubset.nMatID; - subset.fRadius = meshSubset.fRadius; - subset.vCenter = meshSubset.vCenter; - mesh.m_subsets.push_back(subset); - } - - //------------------------------------------------------------------ - if (cbBoneIDs) - { - globalBonesPerSubset.resize(chunk.nCount); - - for (int i = 0; i < chunk.nCount; i++) - { - MESH_SUBSETS_CHUNK_DESC_0800::MeshBoneIDs& meshSubset = *StepData(pCurDataLoc, bSwapEndianness); - - globalBonesPerSubset[i].resize(meshSubset.numBoneIDs); - - for (uint32 b = 0; b < meshSubset.numBoneIDs; ++b) - { - globalBonesPerSubset[i][b] = meshSubset.arrBoneIDs[b]; - } - } - } - - if (cbSubsetTexelDensities) - { - for (int i = 0; i < chunk.nCount; i++) - { - MESH_SUBSETS_CHUNK_DESC_0800::MeshSubsetTexelDensity& meshSubset = *StepData(pCurDataLoc, bSwapEndianness); - mesh.m_subsets[i].fTexelDensity = meshSubset.texelDensity; - } - } - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadStreamDataChunk(int nChunkId, void*& pStreamData, int& nStreamType, int& nStreamIndex, int& nCount, int& nElemSize, bool& bSwapEndianness) -{ - IChunkFile::ChunkDesc* pChunkDesc = m_pChunkFile->FindChunkById(nChunkId); - if (!pChunkDesc) - { - m_LastError.Format("Failed to find chunk with id %d", nChunkId); - return false; - } - - if (pChunkDesc->chunkType != ChunkType_DataStream) - { - m_LastError.Format("Unknown type of stream data chunk"); - return false; - } - - if (pChunkDesc->chunkVersion != STREAM_DATA_CHUNK_DESC_0800::VERSION && pChunkDesc->chunkVersion != STREAM_DATA_CHUNK_DESC_0801::VERSION) - { - m_LastError.Format("Unknown version of stream data chunk"); - return false; - } - - LOADING_TIME_PROFILE_SECTION; - if (pChunkDesc->chunkVersion == STREAM_DATA_CHUNK_DESC_0800::VERSION) - { - // Convert legacy .cgf file to the new version - STREAM_DATA_CHUNK_DESC_0800& chunk = *(STREAM_DATA_CHUNK_DESC_0800*)pChunkDesc->data; - bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - nStreamType = chunk.nStreamType; - nStreamIndex = 0; // Since version 0800 didn't have a streamIndex, set the streamIndex to 0 - nCount = chunk.nCount; - nElemSize = chunk.nElementSize; - pStreamData = (char*)pChunkDesc->data + sizeof(chunk); - - return true; - } - else - { - STREAM_DATA_CHUNK_DESC_0801& chunk = *(STREAM_DATA_CHUNK_DESC_0801*)pChunkDesc->data; - bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - nStreamType = chunk.nStreamType; - nStreamIndex = chunk.nStreamIndex; - nCount = chunk.nCount; - nElemSize = chunk.nElementSize; - pStreamData = (char*)pChunkDesc->data + sizeof(chunk); - - return true; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadPhysicsDataChunk(CNodeCGF* pNode, int nPhysGeomType, int nChunkId) -{ - IChunkFile::ChunkDesc* const pChunkDesc = m_pChunkFile->FindChunkById(nChunkId); - if (!pChunkDesc) - { - return false; - } - - if (pChunkDesc->chunkType != ChunkType_MeshPhysicsData) - { - return false; - } - - if (pChunkDesc->chunkVersion != MESH_PHYSICS_DATA_CHUNK_DESC_0800::VERSION) - { - return false; - } - - LOADING_TIME_PROFILE_SECTION; - - MESH_PHYSICS_DATA_CHUNK_DESC_0800& chunk = *(MESH_PHYSICS_DATA_CHUNK_DESC_0800*)pChunkDesc->data; - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - assert(nPhysGeomType >= 0 && nPhysGeomType < 4); - - pNode->physicalGeomData[nPhysGeomType].resize(chunk.nDataSize); - void* const pDst = &(pNode->physicalGeomData[nPhysGeomType][0]); - const void* const pSrc = (char*)pChunkDesc->data + sizeof(chunk); - memcpy(pDst, pSrc, chunk.nDataSize); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CLoaderCGF::LoadFoliageInfoChunk(IChunkFile::ChunkDesc* pChunkDesc) -{ - if (pChunkDesc->chunkVersion != FOLIAGE_INFO_CHUNK_DESC::VERSION && - pChunkDesc->chunkVersion != FOLIAGE_INFO_CHUNK_DESC::VERSION2) - { - m_LastError.Format("Unknown version of FoliageInfo chunk"); - return false; - } - - FOLIAGE_INFO_CHUNK_DESC& chunk = *(FOLIAGE_INFO_CHUNK_DESC*)pChunkDesc->data; - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - SwapEndian(chunk, bSwapEndianness); - pChunkDesc->bSwapEndian = false; - - SFoliageInfoCGF& fi = *m_pCGF->GetFoliageInfo(); - bool isSkinned = m_pCGF->GetExportInfo()->bSkinnedCGF; - fi.nSpines = chunk.nSpines; - if (fi.nSpines) - { - fi.nSkinnedVtx = chunk.nSkinnedVtx; - - FOLIAGE_SPINE_SUB_CHUNK* const pSpineSrc = (FOLIAGE_SPINE_SUB_CHUNK*)(&chunk + 1); - Vec3* const pSpineVtxSrc = (Vec3*)(&pSpineSrc[chunk.nSpines]); - Vec4* const pSpineSegDimSrc = (Vec4*)(&pSpineVtxSrc[chunk.nSpineVtx]); - //START: Per bone UDP for stiffness, damping and thickness for touch bending vegetation - float* pStiffness = new float[chunk.nSpineVtx]; - float* pDamping = new float[chunk.nSpineVtx]; - float* pThickness = new float[chunk.nSpineVtx]; - SMeshBoneMapping_uint8* pBoneMappingSrc = nullptr; - - if (pChunkDesc->chunkVersion == FOLIAGE_INFO_CHUNK_DESC::VERSION) - { - for (int i = 0; i < chunk.nSpineVtx; i++) - { - pStiffness[i] = SSpineRC::GetDefaultStiffness(); - pDamping[i] = SSpineRC::GetDefaultDamping(); - pThickness[i] = SSpineRC::GetDefaultThickness(); - } - pBoneMappingSrc = (SMeshBoneMapping_uint8*)&pSpineSegDimSrc[chunk.nSpineVtx]; - } - else - { - float* pStiffnessSrc = (float*)(&pSpineSegDimSrc[chunk.nSpineVtx]); - float* pDampingSrc = (float*)(&pStiffnessSrc[chunk.nSpineVtx]); - float* pThicknessSrc = (float*)(&pDampingSrc[chunk.nSpineVtx]); - - if (bSwapEndianness) - { - SwapEndian(pStiffnessSrc, chunk.nSpineVtx, true); - SwapEndian(pDampingSrc, chunk.nSpineVtx, true); - SwapEndian(pThicknessSrc, chunk.nSpineVtx, true); - } - - memcpy(pStiffness, pStiffnessSrc, sizeof(pStiffness[0]) * chunk.nSpineVtx); - memcpy(pDamping, pDampingSrc, sizeof(pStiffness[0]) * chunk.nSpineVtx); - memcpy(pThickness, pThicknessSrc, sizeof(pStiffness[0]) * chunk.nSpineVtx); - - pBoneMappingSrc = (SMeshBoneMapping_uint8*)&pThicknessSrc[chunk.nSpineVtx]; - } - - //Add LOD support for touch bending vegetation - //Load bone mapping. Skinned CGF doesn't have chunkBoneIds because it doesn't need bone index remapping to mesh bone id. - if (isSkinned && chunk.nBoneIds == 0) - { - const char* pStart = (const char*)pBoneMappingSrc; - { - int numBoneMapping = *pStart; - pStart += sizeof(int); - int vertexCount = 0; - - for (int i = 0; i < numBoneMapping; i++) - { - const char* pCGFNodeName = pStart; - pStart += CGF_NODE_NAME_LENGTH; - memcpy(&vertexCount, pStart, sizeof(int)); - SMeshBoneMappingInfo_uint8* pBoneMappingEntry = new SMeshBoneMappingInfo_uint8(vertexCount); - pStart += sizeof(int); - memcpy(pBoneMappingEntry->pBoneMapping, pStart, sizeof(SMeshBoneMapping_uint8)*vertexCount); - pStart += sizeof(SMeshBoneMapping_uint8)*vertexCount; - - if (bSwapEndianness) - { - SwapEndian(&pBoneMappingEntry->nVertexCount, 1, true); - SwapEndian(pBoneMappingEntry->pBoneMapping, pBoneMappingEntry->nVertexCount, true); - } - fi.boneMappings[pCGFNodeName] = pBoneMappingEntry; - } - } - } - else - { - uint16* const pBoneIdsSrc = (uint16*)(&pBoneMappingSrc[chunk.nSkinnedVtx]); - if (bSwapEndianness) - { - SwapEndian(pBoneMappingSrc, chunk.nSkinnedVtx, true); - SwapEndian(pBoneIdsSrc, chunk.nBoneIds, true); - } - fi.pBoneMapping = new SMeshBoneMapping_uint8[chunk.nSkinnedVtx]; - memcpy(fi.pBoneMapping, pBoneMappingSrc, sizeof(pBoneMappingSrc[0]) * chunk.nSkinnedVtx); - fi.chunkBoneIds.resize(chunk.nBoneIds); - memcpy(&fi.chunkBoneIds[0], pBoneIdsSrc, sizeof(fi.chunkBoneIds[0]) * chunk.nBoneIds); - COMPILE_TIME_ASSERT(sizeof(fi.chunkBoneIds[0]) == sizeof(pBoneIdsSrc[0])); - } - - if (bSwapEndianness) - { - SwapEndian(pSpineSrc, chunk.nSpines, true); - SwapEndian(pSpineVtxSrc, chunk.nSpineVtx, true); - SwapEndian(pSpineSegDimSrc, chunk.nSpineVtx, true); - } - - Vec3* const pSpineVtx = new Vec3[chunk.nSpineVtx]; - Vec4* const pSpineSegDim = new Vec4[chunk.nSpineVtx]; - memcpy(pSpineVtx, pSpineVtxSrc, sizeof(pSpineVtx[0]) * chunk.nSpineVtx); - memcpy(pSpineSegDim, pSpineSegDimSrc, sizeof(pSpineSegDim[0]) * chunk.nSpineVtx); - - fi.pSpines = new SSpineRC[chunk.nSpines]; - int i, j; - for (i = j = 0; i < chunk.nSpines; j += fi.pSpines[i++].nVtx) - { - fi.pSpines[i].nVtx = pSpineSrc[i].nVtx; - fi.pSpines[i].len = pSpineSrc[i].len; - fi.pSpines[i].navg = pSpineSrc[i].navg; - fi.pSpines[i].iAttachSpine = pSpineSrc[i].iAttachSpine - 1; - fi.pSpines[i].iAttachSeg = pSpineSrc[i].iAttachSeg - 1; - fi.pSpines[i].pVtx = pSpineVtx + j; - fi.pSpines[i].pSegDim = pSpineSegDim + j; - - // Per bone data for stiffness, damping and thickness for touch bending vegetation - fi.pSpines[i].pStiffness = pStiffness + j; - fi.pSpines[i].pDamping = pDamping + j; - fi.pSpines[i].pThickness = pThickness + j; - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -CMaterialCGF* CLoaderCGF::LoadMaterialFromChunk(int nChunkId) -{ - for (int i = 0; i < m_pCGF->GetMaterialCount(); i++) - { - if (m_pCGF->GetMaterial(i)->nChunkId == nChunkId) - { - return m_pCGF->GetMaterial(i); - } - } - - IChunkFile::ChunkDesc* const pChunkDesc = m_pChunkFile->FindChunkById(nChunkId); - if (!pChunkDesc) - { - m_LastError.Format("Can't find material chunk with id %d in file %s", nChunkId, m_filename); - return 0; - } - - LOADING_TIME_PROFILE_SECTION; - - if (pChunkDesc->chunkType != ChunkType_MtlName) - { - m_LastError.Format( - "Invalid chunk type (0x%08x instead of expected material chunk type 0x%08x) in chunk %d in file %s", - (int)pChunkDesc->chunkType, (int)ChunkType_MtlName, nChunkId, m_filename); - return 0; - } - - return LoadMaterialNameChunk(pChunkDesc); -} - - -////////////////////////////////////////////////////////////////////////// -static const char* GetNextAsciizString(const char*& pCurrent, const char* const pEnd) -{ - const char* const result = pCurrent; - - while (pCurrent < pEnd && *pCurrent >= ' ') - { - ++pCurrent; - } - - if (pCurrent >= pEnd || *pCurrent != 0) - { - // If we found that the data are damaged (*pCurrent != 0) then it's - // better to stop using the data. We move pCurrent to the end - // for that - it guarantees that all future calls return "". - pCurrent = pEnd; - return ""; - } - - ++pCurrent; - - return result; -} - - -////////////////////////////////////////////////////////////////////////// -CMaterialCGF* CLoaderCGF::LoadMaterialNameChunk(IChunkFile::ChunkDesc* pChunkDesc) -{ - FUNCTION_PROFILER_3DENGINE; - - if (pChunkDesc->chunkVersion == MTL_NAME_CHUNK_DESC_0802::VERSION) - { - MTL_NAME_CHUNK_DESC_0802 chunk; - - const bool bSwapEndianness = pChunkDesc->bSwapEndian; - - memcpy(&chunk, pChunkDesc->data, sizeof(chunk)); - SwapEndian(chunk, bSwapEndianness); - - CMaterialCGF* pMtlCGF = Construct(InplaceFactory(m_pDestructFnc), m_pAllocFnc); - pMtlCGF->nChunkId = pChunkDesc->chunkId; - m_pCGF->AddMaterial(pMtlCGF); - - for (size_t i = 0; i < sizeof(chunk.name); ++i) - { - if (chunk.name[i] == '\\') - { - chunk.name[i] = '/'; - } - } - cry_strcpy(pMtlCGF->name, chunk.name); - - const int32 slotCount = (chunk.nSubMaterials <= 0) ? 1 : chunk.nSubMaterials; - const int nPhysicalizeTypeMaxCount = (pChunkDesc->size - sizeof(MTL_NAME_CHUNK_DESC_0802)) / sizeof(int32); - - if (slotCount > nPhysicalizeTypeMaxCount) - { - m_LastError.Format("Corrupted MTL_NAME_CHUNK_DESC_0802 chunk"); - return NULL; - } - - const int32* const pPhysicalizeTypes = (const int32*)((const char*)pChunkDesc->data + sizeof(MTL_NAME_CHUNK_DESC_0802)); - - if (chunk.nSubMaterials <= 0) - { - int nPhysicalizeType = pPhysicalizeTypes[0]; - SwapEndian(nPhysicalizeType, bSwapEndianness); - pMtlCGF->nPhysicalizeType = nPhysicalizeType; - } - else if (chunk.nSubMaterials <= MAX_SUB_MATERIALS) - { - const char* pNames = (const char*)&pPhysicalizeTypes[slotCount]; - const char* const pNamesEnd = (const char*)pChunkDesc->data + pChunkDesc->size; - - for (int i = 0; i < chunk.nSubMaterials; ++i) - { - CMaterialCGF* const pSubMaterial = new CMaterialCGF; - - cry_strcpy(pSubMaterial->name, GetNextAsciizString(pNames, pNamesEnd)); - - int nPhysicalizeType = pPhysicalizeTypes[i]; - SwapEndian(nPhysicalizeType, bSwapEndianness); - - if (nPhysicalizeType != PHYS_GEOM_TYPE_NONE && - (nPhysicalizeType < PHYS_GEOM_TYPE_DEFAULT || nPhysicalizeType > PHYS_GEOM_TYPE_DEFAULT_PROXY)) - { - m_LastError.Format("Invalid physicalize type in material name chunk (0x%08x) in %s, %s", nPhysicalizeType, pMtlCGF->name, m_filename); - return NULL; - } - - pSubMaterial->nPhysicalizeType = nPhysicalizeType; - pMtlCGF->subMaterials.push_back(pSubMaterial); - m_pCGF->AddMaterial(pSubMaterial); - } - } - else - { - m_LastError.Format("Material name chunk: too many submaterials (0x%08x) in %s, %s", chunk.nSubMaterials, pMtlCGF->name, m_filename); - return NULL; - } - - return pMtlCGF; - } - - if (pChunkDesc->chunkVersion == MTL_NAME_CHUNK_DESC_0800::VERSION) - { - if (pChunkDesc->size > sizeof(MTL_NAME_CHUNK_DESC_0800)) - { - m_LastError.Format("Illegal material name chunk size %s (%d should be %d)", m_filename, (int)pChunkDesc->size, (int)sizeof(MTL_NAME_CHUNK_DESC_0800)); - return NULL; - } - - MTL_NAME_CHUNK_DESC_0800& chunk = *(MTL_NAME_CHUNK_DESC_0800*)pChunkDesc->data; - SwapEndian(chunk, pChunkDesc->bSwapEndian); - pChunkDesc->bSwapEndian = false; - - for (size_t i = 0; i < sizeof(chunk.name); ++i) - { - if (chunk.name[i] == '\\') - { - chunk.name[i] = '/'; - } - } - - CMaterialCGF* pMtlCGF = Construct(InplaceFactory(m_pDestructFnc), m_pAllocFnc); - pMtlCGF->nChunkId = pChunkDesc->chunkId; - m_pCGF->AddMaterial(pMtlCGF); - cry_strcpy(pMtlCGF->name, chunk.name); - - // hack for old broken assets - if (size_t(chunk.nSubMaterials) > 0xffff || chunk.nPhysicalizeType > 0xffff) - { - Warning("Fixing material name chunk with wrong endianness: %s, %s", pMtlCGF->name, m_filename); - Warning(" nSubMaterials=0x%08x, nPhysicalizeType=0x%08x, nFlags=0x%08x", - int(chunk.nSubMaterials), int(chunk.nPhysicalizeType), int(chunk.nFlags)); - SwapEndian(chunk, true); - } - - pMtlCGF->nPhysicalizeType = chunk.nPhysicalizeType; - if ((unsigned int)pMtlCGF->nPhysicalizeType <= (PHYS_GEOM_TYPE_DEFAULT_PROXY - PHYS_GEOM_TYPE_DEFAULT)) - { - pMtlCGF->nPhysicalizeType += PHYS_GEOM_TYPE_DEFAULT; // fixup if was exported with PHYS_GEOM_TYPE_DEFAULT==0 - } - - if (pMtlCGF->nPhysicalizeType != PHYS_GEOM_TYPE_NONE && - (pMtlCGF->nPhysicalizeType < PHYS_GEOM_TYPE_DEFAULT || - pMtlCGF->nPhysicalizeType > PHYS_GEOM_TYPE_DEFAULT_PROXY)) - { - m_LastError.Format("Invalid physicalize type in material name chunk (0x%08x) in %s, %s", pMtlCGF->nPhysicalizeType, pMtlCGF->name, m_filename); - return NULL; - } - - if (size_t(chunk.nSubMaterials) <= MTL_NAME_CHUNK_DESC_0800_MAX_SUB_MATERIALS) - { - pMtlCGF->subMaterials.resize(chunk.nSubMaterials, NULL); - for (int i = 0; i < chunk.nSubMaterials; i++) - { - if (chunk.nSubMatChunkId[i] > 0) - { - CMaterialCGF* const pMtl = LoadMaterialFromChunk(chunk.nSubMatChunkId[i]); - if (!pMtl) - { - return NULL; - } - if (!pMtl->subMaterials.empty()) - { - m_LastError.Format("Multi-material used as sub-material from file %s", m_filename); - return NULL; - } - pMtlCGF->subMaterials[i] = pMtl; - } - } - } - else - { - m_LastError.Format("Material name chunk: too many submaterials (0x%08x) in %s, %s", chunk.nSubMaterials, pMtlCGF->name, m_filename); - return NULL; - } - return pMtlCGF; - } - - m_LastError.Format("Illegal material name chunk %s", m_filename); - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CLoaderCGF::Warning(const char* szFormat, ...) -{ - if (m_pListener) - { - char szBuffer[1024]; - va_list args; - va_start(args, szFormat); - azvsprintf(szBuffer, szFormat, args); - m_pListener->Warning(szBuffer); - va_end(args); - } -} diff --git a/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.h b/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.h deleted file mode 100644 index 6377f71d84..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/CGFLoader.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CGFLOADER_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CGFLOADER_H -#pragma once - -#include "../MeshCompiler/MeshCompiler.h" -#include "ChunkFile.h" -#include "CGFContent.h" - -#if defined(RESOURCE_COMPILER) || defined(ENABLE_NON_COMPILED_CGF) -#include "../../../Tools/CryCommonTools/Export/MeshUtils.h" -#endif - -////////////////////////////////////////////////////////////////////////// -class ILoaderCGFListener -{ -public: - virtual ~ILoaderCGFListener(){} - virtual void Warning(const char* format) = 0; - virtual void Error(const char* format) = 0; - virtual bool IsValidationEnabled() { return true; } -}; - -class CLoaderCGF -{ -public: - typedef void* (* AllocFncPtr)(size_t); - typedef void (* DestructFncPtr)(void*); - - CLoaderCGF(AllocFncPtr pAlloc = operator new, DestructFncPtr pDestruct = operator delete, bool bAllowStreamSharing = true); - ~CLoaderCGF(); - - CContentCGF* LoadCGF(const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags = 0); - bool LoadCGF(CContentCGF* pContentCGF, const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags = 0); - bool LoadCGFFromMem(CContentCGF* pContentCGF, const void* pData, size_t nDataLen, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags = 0); - bool LoadCGFWork(CContentCGF* pContentCGF, const char* filename, IChunkFile& chunkFile, ILoaderCGFListener* pListener, unsigned long nLoadingFlags); - - const char* GetLastError() { return m_LastError; } - CContentCGF* GetCContentCGF() { return m_pCompiledCGF; } - - void SetMaxWeightsPerVertex(int maxWeightsPerVertex) { m_maxWeightsPerVertex = maxWeightsPerVertex; } - -private: - bool LoadChunks(bool bJustGeometry); - bool LoadExportFlagsChunk(IChunkFile::ChunkDesc* pChunkDesc); - bool LoadNodeChunk(IChunkFile::ChunkDesc* pChunkDesc, bool bJustGeometry); - - bool LoadHelperChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc); - bool LoadGeomChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc); - bool LoadCompiledMeshChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc); - template - bool LoadCompiledMeshChunk(CNodeCGF* pNode, IChunkFile::ChunkDesc* pChunkDesc, MESH_CHUNK_DESC chunk); - bool LoadMeshSubsetsChunk(CMesh& mesh, IChunkFile::ChunkDesc* pChunkDesc, std::vector >& globalBonesPerSubset); - bool LoadStreamDataChunk(int nChunkId, void*& pStreamData, int& nStreamType, int& nStreamIndex, int& nCount, int& nElemSize, bool& bSwapEndianness); - template - bool LoadStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, ECgfStreamType Type, int streamIndex, CMesh::EStream MStream); - //! Used to load data into one of two potential destination streams in CMesh determined by the element size of the data stored in the .cgf. e.g. load into either CMesh::POSITIONS or CMesh::POSITIONS16 - template - bool LoadStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, ECgfStreamType Type, int streamIndex, CMesh::EStream MStreamA, CMesh::EStream MStreamB); - template - bool LoadBoneMappingStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk, const std::vector >& globalBonesPerSubset); - template - bool LoadIndexStreamChunk(CMesh& mesh, const MESH_CHUNK_DESC& chunk); - - bool LoadPhysicsDataChunk(CNodeCGF* pNode, int nPhysGeomType, int nChunkId); - - bool LoadFoliageInfoChunk(IChunkFile::ChunkDesc* pChunkDesc); - - CMaterialCGF* LoadMaterialFromChunk(int nChunkId); - - CMaterialCGF* LoadMaterialNameChunk(IChunkFile::ChunkDesc* pChunkDesc); - - void ProcessNodes(); - void SetupMeshSubsets(CMesh& mesh, CMaterialCGF* pMaterialCGF); - - ////////////////////////////////////////////////////////////////////////// - // loading of skinned meshes - ////////////////////////////////////////////////////////////////////////// - bool ProcessSkinning(); - CContentCGF* MakeCompiledSkinCGF(CContentCGF* pCGF, std::vector* pVertexRemapping, std::vector* pIndexRemapping); - - //old chunks - bool ReadBoneNameList(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadMorphTargets(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadBoneInitialPos(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadBoneHierarchy(IChunkFile::ChunkDesc* pChunkDesc); - uint32 RecursiveBoneLoader(int nBoneParentIndex, int nBoneIndex); - bool ReadBoneMesh(IChunkFile::ChunkDesc* pChunkDesc); - - //new chunks - bool ReadCompiledBones(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledPhysicalBones(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledPhysicalProxies(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledMorphTargets(IChunkFile::ChunkDesc* pChunkDesc); - - bool ReadCompiledIntFaces(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledIntSkinVertice(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledExt2IntMap(IChunkFile::ChunkDesc* pChunkDesc); - bool ReadCompiledBonesBoxes(IChunkFile::ChunkDesc* pChunkDesc); - - bool ReadCompiledBreakablePhysics(IChunkFile::ChunkDesc* pChunkDesc); - - void Warning(const char* szFormat, ...) PRINTF_PARAMS(2, 3); - -private: - uint32 m_IsCHR; - uint32 m_CompiledBones; - uint32 m_CompiledBonesBoxes; - uint32 m_CompiledMesh; - - uint32 m_numBonenameList; - uint32 m_numBoneInitialPos; - uint32 m_numMorphTargets; - uint32 m_numBoneHierarchy; - - std::vector m_arrIndexToId; // the mapping BoneIndex -> BoneID - std::vector m_arrIdToIndex; // the mapping BoneID -> BineIndex - std::vector m_arrBoneNameTable; // names of bones - std::vector m_arrInitPose34; -#if defined(RESOURCE_COMPILER) || defined(ENABLE_NON_COMPILED_CGF) - std::vector m_arrLinksTmp; - std::vector m_vertexOldToNew; // used to re-map uncompiled Morph Target vertices right after reading them -#endif - - CContentCGF* m_pCompiledCGF; - const void* m_pBoneAnimRawData, * m_pBoneAnimRawDataEnd; - uint32 m_numBones; - int m_nNextBone; - - ////////////////////////////////////////////////////////////////////////// - - string m_LastError; - - char m_filename[260]; - - IChunkFile* m_pChunkFile; - CContentCGF* m_pCGF; - - // To find really used materials - uint16 MatIdToSubset[MAX_SUB_MATERIALS]; - int nLastChunkId; - - ILoaderCGFListener* m_pListener; - - bool m_bUseReadOnlyMesh; - bool m_bAllowStreamSharing; - - int m_maxWeightsPerVertex; - - AllocFncPtr m_pAllocFnc; - DestructFncPtr m_pDestructFnc; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CGFLOADER_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.cpp b/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.cpp deleted file mode 100644 index f3dfc60696..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.cpp +++ /dev/null @@ -1,1603 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#if !defined(CONSOLE) -# define INCLUDE_SAVECGF -#endif - -#if defined(RESOURCE_COMPILER) || defined(INCLUDE_SAVECGF) - -#include "CGFSaver.h" -#include "ChunkData.h" -#include "ChunkFile.h" -#include "QTangent.h" - -#if defined(RESOURCE_COMPILER) - -#include "SwapEndianness.h" -#include "CompileTimeAssert.h" - -// If RESOURCE_COMPILER is defined, then this library must be linked to a target that has the following RCLog methods implemented -extern void RCLog(const char* szFormat, ...); -extern void RCLogWarning(const char* szFormat, ...); -extern void RCLogError(const char* szFormat, ...); - - -#endif - -#include "QTangent.h" - -#define SCALE_TO_CGF 100.0f - -////////////////////////////////////////////////////////////////////////// -CSaverCGF::CSaverCGF(CChunkFile& chunkFile) -{ - assert(&chunkFile); - m_pChunkFile = &chunkFile; - m_bDoNotSaveMeshData = false; - m_bDoNotSaveNonMeshData = false; - m_bSavePhysicsMeshes = true; - m_bCompactVertexStreams = false; - m_bComputeSubsetTexelDensity = false; - m_pCGF = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSaverCGF::SetMeshDataSaving(bool bEnable) -{ - m_bDoNotSaveMeshData = !bEnable; -} - -void CSaverCGF::SetNonMeshDataSaving(bool bEnable) -{ - m_bDoNotSaveNonMeshData = !bEnable; -} - -void CSaverCGF::SetSavePhysicsMeshes(bool bEnable) -{ - m_bSavePhysicsMeshes = bEnable; -} - -void CSaverCGF::SetVertexStreamCompacting(bool bEnable) -{ - m_bCompactVertexStreams = bEnable; -} - -void CSaverCGF::SetSubsetTexelDensityComputing(bool bEnable) -{ - m_bComputeSubsetTexelDensity = bEnable; -} - -////////////////////////////////////////////////////////////////////////// -void CSaverCGF::SaveContent( - CContentCGF* pCGF, - bool bSwapEndian, - bool bStorePositionsAsF16, - bool bUseQtangents, - bool bStoreIndicesAsU16) -{ - SetContent(pCGF); - - SaveExportFlags(bSwapEndian); - SaveMaterials(bSwapEndian); - SaveNodes(bSwapEndian, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16); - SaveBreakablePhysics(bSwapEndian); - SaveFoliage(); -} - -////////////////////////////////////////////////////////////////////////// -void CSaverCGF::SetContent(CContentCGF* pCGF) -{ - m_pCGF = pCGF; -} - - -const CContentCGF* CSaverCGF::GetContent() const -{ - return m_pCGF; -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledBones(bool bSwapEndian, void* pData, int nSize, int version) -{ - COMPILED_BONE_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledBones, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledPhysicalBones(bool bSwapEndian, void* pData, int nSize, int version) -{ - COMPILED_PHYSICALBONE_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledPhysicalBones, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledPhysicalProxis(bool bSwapEndian, void* pData, int nSize, uint32 numPhysicalProxies, int version) -{ - COMPILED_PHYSICALPROXY_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - chunk.numPhysicalProxies = numPhysicalProxies; - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledPhysicalProxies, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledMorphTargets(bool bSwapEndian, void* pData, int nSize, uint32 numMorphTargets, int version) -{ - COMPILED_MORPHTARGETS_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - chunk.numMorphTargets = numMorphTargets; - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledMorphTargets, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledIntSkinVertices(bool bSwapEndian, void* pData, int nSize, int version) -{ - COMPILED_INTSKINVERTICES_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledIntSkinVertices, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledIntFaces(bool bSwapEndian, void* pData, int nSize, int version) -{ - CChunkData chunkData; - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledIntFaces, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledBoneBox(bool bSwapEndian, void* pData, int nSize, int version) -{ - CChunkData chunkData; - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_BonesBoxes, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveCompiledExt2IntMap(bool bSwapEndian, void* pData, int nSize, int version) -{ - CChunkData chunkData; - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_CompiledExt2IntMap, - version, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveBones(bool bSwapEndian, void* pData, int numBones, int nSize) -{ - BONEANIM_CHUNK_DESC_0290 chunk; - ZeroStruct(chunk); - chunk.nBones = numBones; - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_BoneAnim, - BONEANIM_CHUNK_DESC_0290::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveBoneNames(bool bSwapEndian, char* boneList, int numBones, int listSize) -{ - BONENAMELIST_CHUNK_DESC_0745 chunk; - ZeroStruct(chunk); - chunk.numEntities = numBones; - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(boneList, listSize); - - return m_pChunkFile->AddChunk( - ChunkType_BoneNameList, - BONENAMELIST_CHUNK_DESC_0745::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveBoneInitialMatrices(bool bSwapEndian, SBoneInitPosMatrix* matrices, int numBones, int nSize) -{ - BONEINITIALPOS_CHUNK_DESC_0001 chunk; - ZeroStruct(chunk); - chunk.numBones = numBones; - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(matrices, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_BoneInitialPos, - BONEINITIALPOS_CHUNK_DESC_0001::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveBoneMesh([[maybe_unused]] bool bSwapEndian, PhysicalProxy& proxy) -{ - // uncompiled mesh chunk - MESH_CHUNK_DESC_0745 chunk; - ZeroStruct(chunk); - - int numVertices = proxy.m_arrPoints.size(); - int numFaces = proxy.m_arrMaterials.size(); - - chunk.nFaces = numFaces; - chunk.nTVerts = 0; - chunk.nVerts = numVertices; - chunk.VertAnimID = -1; - - // add chunk members - CChunkData chunkData; - chunkData.Add(chunk); - - // copy positions and vertices to a CryVertex array ----------------------------------- - CryVertex* vertices = new CryVertex[numVertices]; - for (int i = 0; i < numVertices; i++) - { - vertices[i].p = proxy.m_arrPoints[i] * 100.0f; - vertices[i].n = Vec3(ZERO); - } - chunkData.AddData(vertices, numVertices * sizeof(CryVertex)); - SAFE_DELETE_ARRAY(vertices); - - // copy faces to a CryFace array ------------------------------------------------------ - CryFace* faces = new CryFace[numFaces]; - for (int i = 0; i < numFaces; i++) - { - faces[i].v0 = proxy.m_arrIndices[i * 3 + 0]; - faces[i].v1 = proxy.m_arrIndices[i * 3 + 1]; - faces[i].v2 = proxy.m_arrIndices[i * 3 + 2]; - faces[i].MatID = proxy.m_arrMaterials[i]; - } - chunkData.AddData(faces, numFaces * sizeof(CryFace)); - SAFE_DELETE_ARRAY(faces); - - int nMeshChunkId = m_pChunkFile->AddChunk( - ChunkType_BoneMesh, - MESH_CHUNK_DESC_0745::VERSION, - eEndianness_Native, - chunkData.data, chunkData.size); - - return nMeshChunkId; -} - -////////////////////////////////////////////////////////////////////////// -void CSaverCGF::SaveNodes( - bool bSwapEndian, - bool bStorePositionsAsF16, - bool bUseQtangents, - bool bStoreIndicesAsU16 - ) -{ - m_savedNodes.clear(); - uint32 numNodes = m_pCGF->GetNodeCount(); - for (uint i = 0; i < numNodes; i++) - { - CNodeCGF* pNode = m_pCGF->GetNode(i); - SaveNode(pNode, bSwapEndian, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16); - } -} - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) -void CSaverCGF::SaveUncompiledNodes() -{ - m_savedNodes.clear(); - uint32 numNodes = m_pCGF->GetNodeCount(); - for (int i = 0; i < numNodes; i++) - { - CNodeCGF* pNode = m_pCGF->GetNode(i); - SaveUncompiledNode(pNode); - } -} -#endif - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveNode( - CNodeCGF* const pNode, - const bool bSwapEndian, - const bool bStorePositionsAsF16, - const bool bUseQtangents, - const bool bStoreIndicesAsU16 - ) -{ - if (m_savedNodes.find(pNode) != m_savedNodes.end()) - { - return pNode->nChunkId; - } - - if (m_bDoNotSaveNonMeshData && (pNode->bPhysicsProxy || !pNode->pMesh)) - { - return -1; - } - - m_savedNodes.insert(pNode); - - NODE_CHUNK_DESC_0824 chunk; - ZeroStruct(chunk); - - for (int i = 0; i < m_pCGF->GetNodeCount(); ++i) - { - CNodeCGF* const pOtherNode = m_pCGF->GetNode(i); - if (pOtherNode->pParent == pNode) - { - chunk.nChildren++; - } - } - - cry_strcpy(chunk.name, pNode->name); - azstrncpy(chunk.name, sizeof(chunk.name), pNode->name, sizeof(pNode->name)); - chunk.name[sizeof(chunk.name) - 1] = 0; - - // Set matrix to node chunk. - float* pMat = (float*)&chunk.tm; - pMat[0] = pNode->localTM(0, 0); - pMat[1] = pNode->localTM(1, 0); - pMat[2] = pNode->localTM(2, 0); - pMat[4] = pNode->localTM(0, 1); - pMat[5] = pNode->localTM(1, 1); - pMat[6] = pNode->localTM(2, 1); - pMat[8] = pNode->localTM(0, 2); - pMat[9] = pNode->localTM(1, 2); - pMat[10] = pNode->localTM(2, 2); - pMat[12] = pNode->localTM.GetTranslation().x * SCALE_TO_CGF; - pMat[13] = pNode->localTM.GetTranslation().y * SCALE_TO_CGF; - pMat[14] = pNode->localTM.GetTranslation().z * SCALE_TO_CGF; - - if (pNode->pMaterial) - { - chunk.MatID = pNode->pMaterial->nChunkId; - } - - chunk.ObjectID = -1; - chunk.ParentID = -1; - - if (pNode->pParent) - { - pNode->nParentChunkId = SaveNode(pNode->pParent, bSwapEndian, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16); - chunk.ParentID = pNode->nParentChunkId; - } - - if (pNode->type == CNodeCGF::NODE_MESH || - (pNode->type == CNodeCGF::NODE_HELPER && pNode->helperType == HP_GEOMETRY)) - { - pNode->nObjectChunkId = SaveNodeMesh(pNode, bSwapEndian, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16); - } - else if (pNode->type == CNodeCGF::NODE_HELPER) - { - pNode->nObjectChunkId = (pNode->helperType == HP_GEOMETRY) - ? SaveNodeMesh(pNode, bSwapEndian, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16) - : SaveHelperChunk(pNode, bSwapEndian); - } - - int positionIndex = pNode->pos_cont_id; - int rotationIndex = pNode->rot_cont_id; - int scaleIndex = pNode->scl_cont_id; - - chunk.pos_cont_id = positionIndex; - chunk.rot_cont_id = rotationIndex; - chunk.scl_cont_id = scaleIndex; - - chunk.ObjectID = pNode->nObjectChunkId; - chunk.PropStrLen = pNode->properties.length(); - - const int PropLen = chunk.PropStrLen; - - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - // Copy property string - chunkData.AddData(pNode->properties.c_str(), PropLen); - - pNode->nChunkId = m_pChunkFile->AddChunk( - ChunkType_Node, - NODE_CHUNK_DESC_0824::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); - - return pNode->nChunkId; -} - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) -int CSaverCGF::SaveUncompiledNode(CNodeCGF* pNode) -{ - if (m_savedNodes.find(pNode) != m_savedNodes.end()) - { - return pNode->nChunkId; - } - - m_savedNodes.insert(pNode); - - NODE_CHUNK_DESC_0824 chunk; - ZeroStruct(chunk); - - for (int i = 0; i < m_pCGF->GetNodeCount(); i++) - { - CNodeCGF* pOtherNode = m_pCGF->GetNode(i); - if (pOtherNode->pParent == pNode) - { - chunk.nChildren++; - } - } - - azstrncpy(chunk.name, sizeof(chunk.name), pNode->name, sizeof(pNode->name)); - chunk.name[sizeof(chunk.name) - 1] = 0; - - chunk.pos_cont_id = pNode->pos_cont_id; - chunk.rot_cont_id = pNode->rot_cont_id; - chunk.scl_cont_id = pNode->scl_cont_id; - - // Set matrix to node chunk. - float* pMat = (float*)&chunk.tm; - pMat[0] = pNode->localTM(0, 0); - pMat[1] = pNode->localTM(1, 0); - pMat[2] = pNode->localTM(2, 0); - pMat[4] = pNode->localTM(0, 1); - pMat[5] = pNode->localTM(1, 1); - pMat[6] = pNode->localTM(2, 1); - pMat[8] = pNode->localTM(0, 2); - pMat[9] = pNode->localTM(1, 2); - pMat[10] = pNode->localTM(2, 2); - pMat[12] = pNode->localTM.GetTranslation().x * SCALE_TO_CGF; - pMat[13] = pNode->localTM.GetTranslation().y * SCALE_TO_CGF; - pMat[14] = pNode->localTM.GetTranslation().z * SCALE_TO_CGF; - - if (pNode->pMaterial) - { - chunk.MatID = pNode->pMaterial->nChunkId; - } - - chunk.ObjectID = -1; - chunk.ParentID = -1; - if (pNode->pParent) - { - pNode->nParentChunkId = SaveUncompiledNode(pNode->pParent); - chunk.ParentID = pNode->nParentChunkId; - } - if (pNode->type == CNodeCGF::NODE_MESH && pNode->pMesh && pNode->pMesh->GetFaceCount() > 0) - { - pNode->nObjectChunkId = SaveUncompiledNodeMesh(pNode); - } - if (pNode->type == CNodeCGF::NODE_HELPER && pNode->helperType == HP_GEOMETRY && pNode->pMesh) - { - pNode->nObjectChunkId = SaveUncompiledNodeMesh(pNode); - } - else if (pNode->type == CNodeCGF::NODE_HELPER) - { - pNode->nObjectChunkId = SaveUncompiledHelperChunk(pNode); - } - else if (pNode->type == CNodeCGF::NODE_LIGHT) - { - // Save Light chunk - } - - chunk.ObjectID = pNode->nObjectChunkId; - chunk.PropStrLen = pNode->properties.length(); - - CChunkData chunkData; - chunkData.Add(chunk); - // Copy property string - chunkData.AddData(pNode->properties.c_str(), chunk.PropStrLen); - - pNode->nChunkId = m_pChunkFile->AddChunk( - ChunkType_Node, - NODE_CHUNK_DESC_0824::VERSION, - eEndianness_Native, - chunkData.data, chunkData.size); - - return pNode->nChunkId; -} -#endif - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) -void CSaverCGF::SaveUncompiledMorphTargets() -{ - CSkinningInfo* skinningInfo = (m_pCGF ? m_pCGF->GetSkinningInfo() : 0); - for (int morphIndex = 0, morphCount = int(skinningInfo ? skinningInfo->m_arrMorphTargets.size() : 0); morphIndex < morphCount; ++morphIndex) - { - MorphTargets* morph = skinningInfo->m_arrMorphTargets[morphIndex]; - - MESHMORPHTARGET_CHUNK_DESC_0001 chunk; - ZeroStruct(chunk); - chunk.nChunkIdMesh = -1; // TODO: Save this properly! - chunk.numMorphVertices = (skinningInfo ? int(morph->m_arrIntMorph.size()) : 0); - - CChunkData chunkData; - chunkData.Add(chunk); - if (morph->m_arrIntMorph.size()) - { - chunkData.AddData(&morph->m_arrIntMorph[0], int(morph->m_arrIntMorph.size() * sizeof(SMeshMorphTargetVertex))); - } - chunkData.AddData(morph->m_strName.c_str(), int(morph->m_strName.size() + 1)); - - m_pChunkFile->AddChunk( - ChunkType_MeshMorphTarget, - MESHMORPHTARGET_CHUNK_DESC_0001::VERSION, - eEndianness_Native, - chunkData.data, chunkData.size); - } -} -#endif - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveNodeMesh( - CNodeCGF* pNode, - bool bSwapEndian, - bool bStorePositionsAsF16, - bool bUseQTangents, - bool bStoreIndicesAsU16) -{ - if (pNode->pMesh) - { - if (m_mapMeshToChunk.find(pNode->pMesh) != m_mapMeshToChunk.end()) - { - // This mesh already saved. - return m_mapMeshToChunk.find(pNode->pMesh)->second; - } - } - - MESH_CHUNK_DESC_0802 chunk; - ZeroStruct(chunk); - - if (pNode->pMesh) - { - const CMesh& mesh = *pNode->pMesh; - - const int nVerts = mesh.GetVertexCount(); - const int nIndices = mesh.GetIndexCount(); - - chunk.nVerts = nVerts; - chunk.nIndices = nIndices; - chunk.nSubsets = mesh.GetSubSetCount(); - chunk.bboxMin = mesh.m_bbox.min; - chunk.bboxMax = mesh.m_bbox.max; - } - else - { - chunk.nVerts = pNode->meshInfo.nVerts; - chunk.nIndices = pNode->meshInfo.nIndices; - chunk.nSubsets = pNode->meshInfo.nSubsets; - chunk.bboxMax = pNode->meshInfo.bboxMin; - chunk.bboxMax = pNode->meshInfo.bboxMax; - } - - const bool bEmptyMesh = m_bDoNotSaveMeshData || pNode->bPhysicsProxy || !pNode->pMesh; - - if (bEmptyMesh) - { - chunk.nFlags |= MESH_CHUNK_DESC_0802::MESH_IS_EMPTY; - } - chunk.nFlags2 = pNode->nPhysicalizeFlags; - - if (m_bSavePhysicsMeshes) - { - for (int i = 0; i < 4; ++i) - { - if (!pNode->physicalGeomData[i].empty()) - { - chunk.nPhysicsDataChunkId[i] = SavePhysicalDataChunk(&pNode->physicalGeomData[i][0], pNode->physicalGeomData[i].size(), bSwapEndian); - } - } - } - - if (!bEmptyMesh) - { - CMesh& mesh = *pNode->pMesh; - - mesh.RecomputeTexMappingDensity(); - chunk.texMappingDensity = mesh.m_texMappingDensity; - chunk.nFlags |= MESH_CHUNK_DESC_0802::HAS_TEX_MAPPING_DENSITY; - - chunk.nSubsetsChunkId = SaveMeshSubsetsChunk(mesh, bSwapEndian); - - const int vertexCount = mesh.GetVertexCount(); - bool bInterleaved = false; - - if (m_bCompactVertexStreams && mesh.m_pPositions && mesh.m_pColor0 && mesh.m_pTexCoord) - { - std::vector interleavedVertices(vertexCount); - memset(&interleavedVertices[0], 0, sizeof(interleavedVertices[0]) * interleavedVertices.size()); - - const Vec3* const pPositions = mesh.m_pPositions; - const SMeshColor* const pColors = mesh.m_pColor0; - const SMeshTexCoord* const pTexCoords = mesh.m_pTexCoord; - - for (int vi = 0; vi < vertexCount; ++vi) - { - SVF_P3S_C4B_T2S& vert = interleavedVertices[vi]; - const ColorB clr = pColors[vi].GetRGBA(); - const Vec2 uv = pTexCoords[vi].GetUV(); - - vert.xyz = Vec3f16(pPositions[vi].x, pPositions[vi].y, pPositions[vi].z); - vert.color.dcolor = clr.pack_abgr8888(); - vert.st = Vec2f16(uv.x, uv.y); - - SwapEndian(vert.xyz, bSwapEndian); - SwapEndian(vert.color.dcolor, bSwapEndian); - SwapEndian(vert.st, bSwapEndian); - } - - chunk.nStreamChunkID[CGF_STREAM_P3S_C4B_T2S][0] = SaveStreamDataChunk(&interleavedVertices[0], CGF_STREAM_P3S_C4B_T2S, 0, vertexCount, sizeof(interleavedVertices[0]), bSwapEndian); - - bInterleaved = true; - } - - // We don't support writing m_pPositionsF16 (although we can) - if (mesh.m_pPositionsF16) - { - assert(0); - } - - if (mesh.m_pPositions && !bInterleaved) - { - COMPILE_TIME_ASSERT(sizeof(mesh.m_pPositions[0]) == sizeof(Vec3)); - if (bStorePositionsAsF16) - { - const Vec3* pRealData = mesh.m_pPositions; - std::vector tmpVec(vertexCount); - for (int i = 0; i < vertexCount; ++i, ++pRealData) - { - tmpVec[i] = Vec3f16(pRealData->x, pRealData->y, pRealData->z); - SwapEndian(tmpVec[i], bSwapEndian); - } - chunk.nStreamChunkID[CGF_STREAM_POSITIONS][0] = SaveStreamDataChunk(&tmpVec[0], CGF_STREAM_POSITIONS, 0, vertexCount, sizeof(tmpVec[0]), bSwapEndian); - } - else - { - SwapEndian(mesh.m_pPositions, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_POSITIONS][0] = SaveStreamDataChunk(mesh.m_pPositions, CGF_STREAM_POSITIONS, 0, vertexCount, sizeof(mesh.m_pPositions[0]), bSwapEndian); - SwapEndian(mesh.m_pPositions, vertexCount, bSwapEndian); - } - } - - if (mesh.m_pNorms && !m_bCompactVertexStreams) - { - SwapEndian(mesh.m_pNorms, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_NORMALS][0] = SaveStreamDataChunk(mesh.m_pNorms, CGF_STREAM_NORMALS, 0, vertexCount, sizeof(Vec3), bSwapEndian); - SwapEndian(mesh.m_pNorms, vertexCount, bSwapEndian); - } - - for (int i = 0; i < mesh.GetNumberOfStreamsByType(CMesh::TEXCOORDS); ++i) - { - SMeshTexCoord* textureCoordinates = mesh.GetStreamPtr(CMesh::TEXCOORDS, i); - if (textureCoordinates && !bInterleaved) - { - SwapEndian(textureCoordinates, mesh.GetTexCoordCount(), bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_TEXCOORDS][i] = SaveStreamDataChunk(textureCoordinates, CGF_STREAM_TEXCOORDS, i, mesh.GetTexCoordCount(), sizeof(CryUV), bSwapEndian); - SwapEndian(textureCoordinates, mesh.GetTexCoordCount(), bSwapEndian); - } - } - - if (mesh.m_pColor0 && !bInterleaved) - { - SwapEndian(mesh.m_pColor0, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_COLORS][0] = SaveStreamDataChunk(mesh.m_pColor0, CGF_STREAM_COLORS, 0, vertexCount, sizeof(SMeshColor), bSwapEndian); - SwapEndian(mesh.m_pColor0, vertexCount, bSwapEndian); - } - - if (mesh.m_pColor1) - { - SwapEndian(mesh.m_pColor1, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_COLORS][1] = SaveStreamDataChunk(mesh.m_pColor1, CGF_STREAM_COLORS, 1, vertexCount, sizeof(SMeshColor), bSwapEndian); - SwapEndian(mesh.m_pColor1, vertexCount, bSwapEndian); - } - - if (mesh.m_pVertMats) - { - SwapEndian(mesh.m_pVertMats, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_VERT_MATS][0] = SaveStreamDataChunk(mesh.m_pVertMats, CGF_STREAM_VERT_MATS, 0, vertexCount, sizeof(mesh.m_pVertMats[0]), bSwapEndian); - SwapEndian(mesh.m_pVertMats, vertexCount, bSwapEndian); - } - - if (mesh.m_pIndices) - { - const int indexCount = mesh.GetIndexCount(); - - COMPILE_TIME_ASSERT(sizeof(mesh.m_pIndices[0]) == sizeof(vtx_idx)); - COMPILE_TIME_ASSERT(sizeof(vtx_idx) == 2 || sizeof(vtx_idx) == 4); - - if (sizeof(mesh.m_pIndices[0]) == (bStoreIndicesAsU16 ? 2 : 4)) - { - SwapEndian(mesh.m_pIndices, indexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_INDICES][0] = SaveStreamDataChunk(mesh.m_pIndices, CGF_STREAM_INDICES, 0, indexCount, sizeof(mesh.m_pIndices[0]), bSwapEndian); - SwapEndian(mesh.m_pIndices, indexCount, bSwapEndian); - } - else if (bStoreIndicesAsU16) - { - if (vertexCount > 0xffff) // 0xffff is used instead of 0x10000 to reserve index 0xffff for special cases - { -#if defined(RESOURCE_COMPILER) - RCLogError("Saving mesh with 16-bit vertex indices is impossible - 16-bit indices cannot address %i vertices", vertexCount); -#endif - return -1; - } - std::vector tmp(indexCount); - for (int i = 0; i < indexCount; ++i) - { - tmp[i] = (uint16)mesh.m_pIndices[i]; - SwapEndian(tmp[i], bSwapEndian); - } - chunk.nStreamChunkID[CGF_STREAM_INDICES][0] = SaveStreamDataChunk(&tmp[0], CGF_STREAM_INDICES, 0, indexCount, sizeof(uint16), bSwapEndian); - } - else - { - std::vector tmp(indexCount); - for (int i = 0; i < indexCount; ++i) - { - tmp[i] = mesh.m_pIndices[i]; - SwapEndian(tmp[i], bSwapEndian); - } - chunk.nStreamChunkID[CGF_STREAM_INDICES][0] = SaveStreamDataChunk(&tmp[0], CGF_STREAM_INDICES, 0, indexCount, sizeof(uint32), bSwapEndian); - } - } - - if (mesh.m_pTangents) - { - if (bUseQTangents) - { - std::vector qTangents(vertexCount); - MeshTangentsFrameToQTangents( - &mesh.m_pTangents[0], sizeof(mesh.m_pTangents[0]), vertexCount, - &qTangents[0], sizeof(qTangents[0])); - SwapEndian(&qTangents[0], vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_QTANGENTS][0] = SaveStreamDataChunk(&qTangents[0], CGF_STREAM_QTANGENTS, 0, vertexCount, sizeof(SMeshQTangents), bSwapEndian); - } - else - { - SwapEndian(mesh.m_pTangents, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_TANGENTS][0] = SaveStreamDataChunk(mesh.m_pTangents, CGF_STREAM_TANGENTS, 0, vertexCount, sizeof(SMeshTangents), bSwapEndian); - SwapEndian(mesh.m_pTangents, vertexCount, bSwapEndian); - } - } - - if (mesh.m_pBoneMapping) - { - if (mesh.m_pExtraBoneMapping) - { - chunk.nFlags |= MESH_CHUNK_DESC_0802::HAS_EXTRA_WEIGHTS; - - std::vector tempBoneMapping; - COMPILE_TIME_ASSERT(sizeof(tempBoneMapping[0]) == sizeof(mesh.m_pBoneMapping[0])); - tempBoneMapping.resize(vertexCount * 2); - memcpy(&tempBoneMapping[0], mesh.m_pBoneMapping, sizeof(tempBoneMapping[0]) * vertexCount); - memcpy(&tempBoneMapping[vertexCount], mesh.m_pExtraBoneMapping, sizeof(tempBoneMapping[0]) * vertexCount); - SwapEndian(&tempBoneMapping[0], vertexCount * 2, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_BONEMAPPING][0] = SaveStreamDataChunk(&tempBoneMapping[0], CGF_STREAM_BONEMAPPING, 0, vertexCount * 2, sizeof(tempBoneMapping[0]), bSwapEndian); - } - else - { - SwapEndian(mesh.m_pBoneMapping, vertexCount, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_BONEMAPPING][0] = SaveStreamDataChunk(mesh.m_pBoneMapping, CGF_STREAM_BONEMAPPING, 0, vertexCount, sizeof(mesh.m_pBoneMapping[0]), bSwapEndian); - SwapEndian(mesh.m_pBoneMapping, vertexCount, bSwapEndian); - } - } - - if (pNode->pSkinInfo) - { - SwapEndian(pNode->pSkinInfo, vertexCount + 1, bSwapEndian); - chunk.nStreamChunkID[CGF_STREAM_SKINDATA][0] = SaveStreamDataChunk(pNode->pSkinInfo, CGF_STREAM_SKINDATA, 0, vertexCount + 1, sizeof(pNode->pSkinInfo[0]), bSwapEndian); - SwapEndian(pNode->pSkinInfo, vertexCount + 1, bSwapEndian); - } - } - - SwapEndian(chunk, bSwapEndian); - - const int nMeshChunkId = m_pChunkFile->AddChunk( - ChunkType_Mesh, - MESH_CHUNK_DESC_0802::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - &chunk, sizeof(chunk)); - - m_mapMeshToChunk[pNode->pMesh] = nMeshChunkId; - - return nMeshChunkId; -} - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) -int CSaverCGF::SaveUncompiledNodeMesh(CNodeCGF* pNode) -{ - if (m_mapMeshToChunk.find(pNode->pMesh) != m_mapMeshToChunk.end()) - { - // This mesh already saved. - return m_mapMeshToChunk.find(pNode->pMesh)->second; - } - - const CMesh* const mesh = pNode->pMesh; - - const bool HasBoneInfo = (mesh->m_pBoneMapping != 0); - const bool HasVertexColors = (mesh->m_pColor0 != 0); - const bool HasVertexAlphas = HasVertexColors; - const bool WriteVCol = true; - - // uncompiled mesh chunk - MESH_CHUNK_DESC_0745 chunk; - ZeroStruct(chunk); - - const int numVertices = mesh->GetVertexCount(); - const int numFaces = mesh->GetFaceCount(); - const int numUVs = mesh->GetTexCoordCount(); - - if (numUVs != 0 && numUVs != numVertices) - { - RCLogError("Mesh for node \"%s\" has mismatching number of vertices and texture coordinates", pNode->name); - return -1; - } - - if (!mesh->m_pTopologyIds) - { - RCLogError("Mesh for node \"%s\" has no topology info. Contact an RC programmer.", pNode->name); - return -1; - } - - assert(mesh->m_pPositions); - assert(mesh->m_pNorms); - assert(mesh->m_pFaces); - - chunk.flags1 = 0; - chunk.flags2 = MESH_CHUNK_DESC_0745::FLAG2_HAS_TOPOLOGY_IDS; - chunk.flags1 |= HasBoneInfo ? MESH_CHUNK_DESC_0745::FLAG1_BONE_INFO : 0; - chunk.flags2 |= (WriteVCol && HasVertexColors) ? MESH_CHUNK_DESC_0745::FLAG2_HAS_VERTEX_COLOR : 0; - chunk.flags2 |= (WriteVCol && HasVertexAlphas) ? MESH_CHUNK_DESC_0745::FLAG2_HAS_VERTEX_ALPHA : 0; - chunk.nFaces = numFaces; - chunk.nTVerts = numUVs; - chunk.nVerts = numVertices; - chunk.VertAnimID = -1; // nVertexAnimChunkID; - - // add chunk members - CChunkData chunkData; - chunkData.Add(chunk); - - // copy positions and vertices to a CryVertex array ----------------------------------- - { - CryVertex* vertices = new CryVertex[numVertices]; - for (int i = 0; i < numVertices; i++) - { - vertices[i].p = mesh->m_pPositions[i]; - vertices[i].n = mesh->m_pNorms[i].GetN(); - } - chunkData.AddData(vertices, numVertices * sizeof(CryVertex)); - SAFE_DELETE_ARRAY(vertices); - } - - // copy faces to a CryFace array ------------------------------------------------------ - { - CryFace* faces = new CryFace[numFaces]; - for (int i = 0; i < numFaces; i++) - { - faces[i].v0 = mesh->m_pFaces[i].v[0]; - faces[i].v1 = mesh->m_pFaces[i].v[1]; - faces[i].v2 = mesh->m_pFaces[i].v[2]; - faces[i].MatID = mesh->m_subsets[mesh->m_pFaces[i].nSubset].nMatID; - } - chunkData.AddData(faces, numFaces * sizeof(CryFace)); - SAFE_DELETE_ARRAY(faces); - } - - // topology info ---------------------------------------------------------------------- - { - chunkData.AddData(mesh->m_pTopologyIds, numVertices * sizeof(mesh->m_pTopologyIds[0])); - } - - // copy texture coordinates to a CryUV array ------------------------------------------ - if (numUVs) - { - assert(numUVs == numVertices); - - CryUV* uvs = new CryUV[numUVs]; - for (int i = 0; i < numUVs; i++) - { - mesh->m_pTexCoord[i].ExportTo(uvs[i].u, uvs[i].v); - } - chunkData.AddData(uvs, numUVs * sizeof(CryUV)); - SAFE_DELETE_ARRAY(uvs); - } - - if (HasBoneInfo) - { - CSkinningInfo* skinningInfo = m_pCGF->GetSkinningInfo(); - Matrix34 objectTransform = pNode->worldTM; - - typedef std::map > BadBoneIDs; - BadBoneIDs badBoneIDs; - - std::vector arrLinks; - - for (int k = 0; k < numVertices; k++) - { - Vec3 point = mesh->m_pPositions[k]; - Vec3 worldVertex = objectTransform.TransformPoint(point); - - arrLinks.clear(); - - float totalweight = 0.0f; - - for (int j = 0; j < 8; j++) - { - int boneID = -1; - float blending = 0.0f; - - if (j < 4) - { - boneID = mesh->m_pBoneMapping[k].boneIds[j]; - blending = (float)(mesh->m_pBoneMapping[k].weights[j]) / 255.0f; - } - else if (mesh->m_pExtraBoneMapping) - { - boneID = mesh->m_pExtraBoneMapping[k].boneIds[j - 4]; - blending = (float)(mesh->m_pExtraBoneMapping[k].weights[j - 4]) / 255.0f; - } - - if (blending < 0.01f) - { - continue; - } - - if (boneID >= skinningInfo->m_arrBonesDesc.size()) - { - badBoneIDs[boneID].insert(k); - continue; - } - - totalweight += blending; - - const Matrix34& boneTransform = skinningInfo->m_arrBonesDesc[boneID].m_DefaultW2B; - const Vec3 offset = boneTransform.TransformPoint(worldVertex); - - static float const metersToCentimeters = 100.0f; - - CryLink link; - link.BoneID = boneID; - link.Blending = blending; - link.offset = offset * metersToCentimeters; - - arrLinks.push_back(link); - } - - const int nLinks = arrLinks.size(); - - for (int j = 0; j < nLinks; j++) - { - arrLinks[j].Blending /= totalweight; - } - - chunkData.AddData(&nLinks, sizeof(int)); - if (!arrLinks.empty()) - { - chunkData.AddData(&arrLinks[0], nLinks * sizeof(CryLink)); - } - else - { - RCLogError("Mesh indicated it has bones, but no valid bones were found."); - } - } - - if (!badBoneIDs.empty()) - { - RCLogError("Skinned mesh for node \"%s\" contains references to missing bones:", pNode->name); - BadBoneIDs::iterator it; - string message; - string vertexStr; - for (it = badBoneIDs.begin(); it != badBoneIDs.end(); ++it) - { - const std::set& vertexIndices = it->second; - message.Format(" Bone %i, vertices:", it->first); - for (std::set::const_iterator vit = vertexIndices.begin(); vit != vertexIndices.end(); ++vit) - { - vertexStr.Format(" %i", *vit); - message += vertexStr; - } - RCLogError("%s", message.c_str()); - } - } - } - - if (WriteVCol) - { - if (HasVertexColors) - { - CryIRGB* vertexcolors = new CryIRGB[numVertices]; - for (int i = 0; i < numVertices; i++) - { - const ColorB clr = mesh->m_pColor0[i].GetRGBA(); - - vertexcolors[i].r = clr.r; - vertexcolors[i].g = clr.g; - vertexcolors[i].b = clr.b; - } - chunkData.AddData(vertexcolors, numVertices * sizeof(CryIRGB)); - SAFE_DELETE_ARRAY(vertexcolors); - } - - if (HasVertexAlphas) - { - unsigned char* vertexalphas = new unsigned char[numVertices]; - for (int i = 0; i < numVertices; i++) - { - const ColorB clr = mesh->m_pColor0[i].GetRGBA(); - - vertexalphas[i] = clr.a; - } - chunkData.AddData(vertexalphas, numVertices * sizeof(unsigned char)); - SAFE_DELETE_ARRAY(vertexalphas); - } - } - - if (0) // save morph targets - the loader load this? - { - } - - if (0) // save bone initial pose - the loader load this? - { - } - - int nMeshChunkId = m_pChunkFile->AddChunk( - ChunkType_Mesh, - MESH_CHUNK_DESC_0745::VERSION, - eEndianness_Native, - chunkData.data, chunkData.size); - - m_mapMeshToChunk[pNode->pMesh] = nMeshChunkId; - - return nMeshChunkId; -} -#endif - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveHelperChunk(CNodeCGF* pNode, bool bSwapEndian) -{ - HELPER_CHUNK_DESC chunk; - ZeroStruct(chunk); - - chunk.type = pNode->helperType; - chunk.size = pNode->helperSize; - - SwapEndian(chunk, bSwapEndian); - - return m_pChunkFile->AddChunk( - ChunkType_Helper, - HELPER_CHUNK_DESC::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - &chunk, sizeof(chunk)); -} - -////////////////////////////////////////////////////////////////////////// -#if defined(RESOURCE_COMPILER) -int CSaverCGF::SaveUncompiledHelperChunk(CNodeCGF* pNode) -{ - HELPER_CHUNK_DESC chunk; - ZeroStruct(chunk); - - chunk.type = pNode->helperType; - chunk.size = pNode->helperSize; - - return m_pChunkFile->AddChunk( - ChunkType_Helper, - HELPER_CHUNK_DESC::VERSION, - eEndianness_Native, - &chunk, sizeof(chunk)); -} -#endif - -////////////////////////////////////////////////////////////////////////// -// TODO:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -int CSaverCGF::SaveBreakablePhysics(bool bSwapEndian) -{ - const CPhysicalizeInfoCGF* const pPi = m_pCGF->GetPhysicalizeInfo(); - - if (!pPi || pPi->nGranularity == -1) - { - return 0; - } - - BREAKABLE_PHYSICS_CHUNK_DESC chunk; - ZeroStruct(chunk); - - chunk.granularity = pPi->nGranularity; - chunk.nMode = pPi->nMode; - chunk.nRetVtx = pPi->nRetVtx; - chunk.nRetTets = pPi->nRetTets; - - CChunkData chunkData; - chunkData.Add(chunk); - if (pPi->pRetVtx) - { - chunkData.AddData(pPi->pRetVtx, pPi->nRetVtx * sizeof(Vec3)); - } - if (pPi->pRetTets) - { - chunkData.AddData(pPi->pRetTets, pPi->nRetTets * sizeof(int) * 4); - } - - SwapEndian(chunk, bSwapEndian); - - return m_pChunkFile->AddChunk( - ChunkType_BreakablePhysics, - BREAKABLE_PHYSICS_CHUNK_DESC::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveMeshSubsetsChunk(CMesh& mesh, bool bSwapEndian) -{ - MESH_SUBSETS_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - - chunk.nCount = mesh.GetSubSetCount(); - - if (m_bComputeSubsetTexelDensity) - { - chunk.nFlags |= MESH_SUBSETS_CHUNK_DESC_0800::HAS_SUBSET_TEXEL_DENSITY; - } - - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - - for (int i = 0; i < mesh.GetSubSetCount(); i++) - { - const SMeshSubset& srcSubset = mesh.m_subsets[i]; - - MESH_SUBSETS_CHUNK_DESC_0800::MeshSubset subset; - memset(&subset, 0, sizeof(subset)); - subset.nFirstIndexId = srcSubset.nFirstIndexId; - subset.nNumIndices = srcSubset.nNumIndices; - subset.nFirstVertId = srcSubset.nFirstVertId; - subset.nNumVerts = srcSubset.nNumVerts; - subset.nMatID = srcSubset.nMatID; - subset.fRadius = srcSubset.fRadius; - subset.vCenter = srcSubset.vCenter; - SwapEndian(subset, bSwapEndian); - chunkData.Add(subset); - } - - // add subset texel densities - if (m_bComputeSubsetTexelDensity) - { - for (int i = 0; i < mesh.GetSubSetCount(); ++i) - { - MESH_SUBSETS_CHUNK_DESC_0800::MeshSubsetTexelDensity subset; - - const char* err; - float posArea, texArea; - if (!mesh.ComputeSubsetTexMappingAreas((size_t)i, posArea, texArea, err)) - { -#if defined(RESOURCE_COMPILER) - RCLog("ComputeSubsetTexMappingAreas: %s", err); -#endif - subset.texelDensity = 0.0f; - } - else - { - subset.texelDensity = texArea / posArea; - } - - SwapEndian(subset, bSwapEndian); - chunkData.AddData(&subset, sizeof(subset)); - } - } - - return m_pChunkFile->AddChunk( - ChunkType_MeshSubsets, - MESH_SUBSETS_CHUNK_DESC_0800::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveStreamDataChunk(const void* pStreamData, int nStreamType, int nIndex, int nCount, int nElemSize, bool bSwapEndian) -{ - STREAM_DATA_CHUNK_DESC_0801 chunk; - ZeroStruct(chunk); - - chunk.nStreamType = nStreamType; - chunk.nStreamIndex = nIndex; - chunk.nCount = nCount; - chunk.nElementSize = nElemSize; - - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pStreamData, nCount * nElemSize); - - return m_pChunkFile->AddChunk( - ChunkType_DataStream, - STREAM_DATA_CHUNK_DESC_0801::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SavePhysicalDataChunk(const void* pData, int nSize, bool bSwapEndian) -{ - MESH_PHYSICS_DATA_CHUNK_DESC_0800 chunk; - ZeroStruct(chunk); - - chunk.nDataSize = nSize; - - SwapEndian(chunk, bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_MeshPhysicsData, - MESH_PHYSICS_DATA_CHUNK_DESC_0800::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveExportFlags(bool bSwapEndian) -{ - if (m_bDoNotSaveNonMeshData) - { - return -1; - } - - EXPORT_FLAGS_CHUNK_DESC chunk; - ZeroStruct(chunk); - - CExportInfoCGF* pExpInfo = m_pCGF->GetExportInfo(); - if (pExpInfo->bMergeAllNodes) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::MERGE_ALL_NODES; - } - if (pExpInfo->bUseCustomNormals) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::USE_CUSTOM_NORMALS; - } - if (pExpInfo->bHaveAutoLods) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::HAVE_AUTO_LODS; - } - if (pExpInfo->bWantF32Vertices) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::WANT_F32_VERTICES; - } - if (pExpInfo->b8WeightsPerVertex) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::EIGHT_WEIGHTS_PER_VERTEX; - } - if (pExpInfo->bSkinnedCGF) - { - chunk.flags |= EXPORT_FLAGS_CHUNK_DESC::SKINNED_CGF; - } - - if (pExpInfo->bFromColladaXSI) - { - chunk.assetAuthorTool |= EXPORT_FLAGS_CHUNK_DESC::FROM_COLLADA_XSI; - } - if (pExpInfo->bFromColladaMAX) - { - chunk.assetAuthorTool |= EXPORT_FLAGS_CHUNK_DESC::FROM_COLLADA_MAX; - } - if (pExpInfo->bFromColladaMAYA) - { - chunk.assetAuthorTool |= EXPORT_FLAGS_CHUNK_DESC::FROM_COLLADA_MAYA; - } - - chunk.authorToolVersion = pExpInfo->authorToolVersion; - - static const size_t rcVersionElementCount = sizeof(pExpInfo->rc_version) / sizeof(pExpInfo->rc_version[0]); - std::copy(pExpInfo->rc_version, pExpInfo->rc_version + rcVersionElementCount, chunk.rc_version); - cry_strcpy(chunk.rc_version_string, sizeof(chunk.rc_version_string), pExpInfo->rc_version_string); - - SwapEndian(chunk, bSwapEndian); - - return m_pChunkFile->AddChunk( - ChunkType_ExportFlags, - EXPORT_FLAGS_CHUNK_DESC::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - &chunk, sizeof(chunk)); -} - -////////////////////////////////////////////////////////////////////////// -void CSaverCGF::SaveMaterials(bool bSwapEndian) -{ - for (int i = 0; i < m_pCGF->GetNodeCount(); ++i) - { - CMaterialCGF* const pMaterialCGF = m_pCGF->GetNode(i)->pMaterial; - if (pMaterialCGF) - { - SaveMaterial(pMaterialCGF, bSwapEndian); - } - } -} - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveMaterial(CMaterialCGF* pMtl, bool bSwapEndian) -{ - // Check whether the material has already been saved. - if (m_savedMaterials.find(pMtl) != m_savedMaterials.end()) - { - return pMtl->nChunkId; - } - - m_savedMaterials.insert(pMtl); - - MTL_NAME_CHUNK_DESC_0802 chunk; - ZeroStruct(chunk); - - cry_strcpy(chunk.name, sizeof(chunk.name), pMtl->name); - - DynArray nPhysicalizeTypeArray; - DynArray names; - - int nSubMaterials = int(pMtl->subMaterials.size()); - - if (nSubMaterials == 0) - { - nPhysicalizeTypeArray.push_back(pMtl->nPhysicalizeType); - } - else - { - if (nSubMaterials > MAX_SUB_MATERIALS) - { -#if defined(RESOURCE_COMPILER) - RCLogError("Material %s uses %d sub-materials but maximum allowed is %d.", pMtl->name, nSubMaterials, MAX_SUB_MATERIALS); -#else - CryWarning( - VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, - "Material %s uses %d sub-materials but maximum allowed is %d.", pMtl->name, nSubMaterials, MAX_SUB_MATERIALS); -#endif - nSubMaterials = MAX_SUB_MATERIALS; - } - nPhysicalizeTypeArray.resize(nSubMaterials, PHYS_GEOM_TYPE_DEFAULT); - - for (int childIndex = 0; childIndex < nSubMaterials; ++childIndex) - { - CMaterialCGF* childMaterial = pMtl->subMaterials[childIndex]; - if (childMaterial) - { - nPhysicalizeTypeArray[childIndex] = childMaterial->nPhysicalizeType; - for (int i = 0; childMaterial->name[i] != 0; ++i) - { - names.push_back(childMaterial->name[i]); - } - } - names.push_back(0); - } - } - - chunk.nSubMaterials = nSubMaterials; - - SwapEndian(chunk, bSwapEndian); - SwapEndian(&nPhysicalizeTypeArray[0], nPhysicalizeTypeArray.size(), bSwapEndian); - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(&nPhysicalizeTypeArray[0], nPhysicalizeTypeArray.size() * sizeof(nPhysicalizeTypeArray[0])); - if (!names.empty()) - { - chunkData.AddData(&names[0], names.size() * sizeof(names[0])); - } - - pMtl->nChunkId = m_pChunkFile->AddChunk( - ChunkType_MtlName, - MTL_NAME_CHUNK_DESC_0802::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); - - return pMtl->nChunkId; -} - -int CSaverCGF::SaveController831(bool bSwapEndian, const CONTROLLER_CHUNK_DESC_0831& ctrlChunk, void* pData, int nSize) -{ - CChunkData chunkData; - chunkData.Add(ctrlChunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_Controller, - CONTROLLER_CHUNK_DESC_0831::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - -int CSaverCGF::SaveControllerDB905(bool bSwapEndian, const CONTROLLER_CHUNK_DESC_0905& ctrlChunk, void* pData, int nSize) -{ - CChunkData chunkData; - chunkData.Add(ctrlChunk); - chunkData.AddData(pData, nSize); - - return m_pChunkFile->AddChunk( - ChunkType_Controller, - CONTROLLER_CHUNK_DESC_0905::VERSION, - (bSwapEndian ? eEndianness_NonNative : eEndianness_Native), - chunkData.data, chunkData.size); -} - - -////////////////////////////////////////////////////////////////////////// -int CSaverCGF::SaveFoliage() -{ - FOLIAGE_INFO_CHUNK_DESC chunk; - ZeroStruct(chunk); - - bool isSkinned = m_pCGF->GetExportInfo()->bSkinnedCGF; - - SFoliageInfoCGF& fi = *m_pCGF->GetFoliageInfo(); - - if (fi.nSpines > 0) - { - int i, j; - chunk.nSpines = fi.nSpines; - chunk.nSkinnedVtx = fi.nSkinnedVtx; - chunk.nBoneIds = fi.chunkBoneIds.size(); - chunk.nSpineVtx = 0; - - for (i = 0; i < fi.nSpines; chunk.nSpineVtx += fi.pSpines[i++].nVtx) - { - ; - } - - FOLIAGE_SPINE_SUB_CHUNK* const pSpineBuf = new FOLIAGE_SPINE_SUB_CHUNK[fi.nSpines]; - Vec3* const pSpineVtx = new Vec3[chunk.nSpineVtx]; - Vec4* const pSpineSegDim = new Vec4[chunk.nSpineVtx]; - float* const pStiffness = new float[chunk.nSpineVtx]; - float* const pDamping = new float[chunk.nSpineVtx]; - float* const pThickness = new float[chunk.nSpineVtx]; - - memset(pSpineBuf, 0, sizeof(pSpineBuf[0]) * fi.nSpines); - - for (i = j = 0; i < fi.nSpines; j += fi.pSpines[i++].nVtx) - { - pSpineBuf[i].nVtx = fi.pSpines[i].nVtx; - pSpineBuf[i].len = fi.pSpines[i].len; - pSpineBuf[i].navg = fi.pSpines[i].navg; - pSpineBuf[i].iAttachSpine = fi.pSpines[i].iAttachSpine + 1; - pSpineBuf[i].iAttachSeg = fi.pSpines[i].iAttachSeg + 1; - memcpy(pSpineVtx + j, fi.pSpines[i].pVtx, fi.pSpines[i].nVtx * sizeof(Vec3)); - memcpy(pSpineSegDim + j, fi.pSpines[i].pSegDim, fi.pSpines[i].nVtx * sizeof(Vec4)); - memcpy(pStiffness + j, fi.pSpines[i].pStiffness, fi.pSpines[i].nVtx * sizeof(float)); - memcpy(pDamping + j, fi.pSpines[i].pDamping, fi.pSpines[i].nVtx * sizeof(float)); - memcpy(pThickness + j, fi.pSpines[i].pThickness, fi.pSpines[i].nVtx * sizeof(float)); - } - - CChunkData chunkData; - chunkData.Add(chunk); - chunkData.AddData(pSpineBuf, sizeof(pSpineBuf[0]) * fi.nSpines); - chunkData.AddData(pSpineVtx, sizeof(pSpineVtx[0]) * chunk.nSpineVtx); - chunkData.AddData(pSpineSegDim, sizeof(pSpineSegDim[0]) * chunk.nSpineVtx); - chunkData.AddData(pStiffness, sizeof(pStiffness[0]) * chunk.nSpineVtx); - chunkData.AddData(pDamping, sizeof(pDamping[0]) * chunk.nSpineVtx); - chunkData.AddData(pThickness, sizeof(pThickness[0]) * chunk.nSpineVtx); - //Add bone mapping(s) - if (isSkinned && chunk.nBoneIds == 0) - { - int numBoneMapping = fi.boneMappings.size(); - chunkData.AddData(&numBoneMapping, sizeof(numBoneMapping)); - - AZStd::unordered_map::iterator iter = fi.boneMappings.begin(); - while (iter != fi.boneMappings.end()) - { - const SMeshBoneMappingInfo_uint8* pBoneMappingEntry = iter->second; - chunkData.AddData(iter->first.c_str(), CGF_NODE_NAME_LENGTH); - chunkData.AddData(&pBoneMappingEntry->nVertexCount, sizeof(int)); - chunkData.AddData(pBoneMappingEntry->pBoneMapping, sizeof(pBoneMappingEntry->pBoneMapping[0]) * pBoneMappingEntry->nVertexCount); - iter++; - } - } - else - { - chunkData.AddData(fi.pBoneMapping, sizeof(fi.pBoneMapping[0]) * fi.nSkinnedVtx); - chunkData.AddData(&fi.chunkBoneIds[0], sizeof(fi.chunkBoneIds[0]) * fi.chunkBoneIds.size()); - } - delete[] pSpineSegDim; - delete[] pSpineVtx; - delete[] pSpineBuf; - delete[] pStiffness; - delete[] pDamping; - delete[] pThickness; - - return m_pChunkFile->AddChunk( - ChunkType_FoliageInfo, - FOLIAGE_INFO_CHUNK_DESC::VERSION2, - eEndianness_Native, - chunkData.data, chunkData.size); - } - else - { - return 0; - } -} - -#endif diff --git a/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.h b/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.h deleted file mode 100644 index 0084e40680..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/CGFSaver.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CGFSAVER_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CGFSAVER_H -#pragma once - -#if defined(RESOURCE_COMPILER) || defined(INCLUDE_SAVECGF) - -#include "CGFContent.h" - -class CChunkFile; - -////////////////////////////////////////////////////////////////////////// -class CSaverCGF -{ -public: - CSaverCGF(CChunkFile& chunkFile); - - void SaveContent(CContentCGF* pCGF, bool bSwapEndian, bool bStorePositionsAsF16, bool bUseQtangents, bool bStoreIndicesAsU16); - - void SetContent(CContentCGF* pCGF); - - const CContentCGF* GetContent() const; - - // Enable/Disable saving of the node mesh. - void SetMeshDataSaving(bool bEnable); - - // Enable/Disable saving of non-mesh related data. - void SetNonMeshDataSaving(bool bEnable); - - // Enable/disable saving of physics meshes. - void SetSavePhysicsMeshes(bool bEnable); - - // Enable compaction of vertex streams (for optimised streaming) - void SetVertexStreamCompacting(bool bEnable); - - // Enable computation of subset texel density - void SetSubsetTexelDensityComputing(bool bEnable); - - void SaveNodes(bool bSwapEndian, bool bStorePositionsAsF16, bool bUseQtangents, bool bStoreIndicesAsU16); - int SaveNode(CNodeCGF* pNode, bool bSwapEndian, bool bStorePositionsAsF16, bool bUseQtangents, bool bStoreIndicesAsU16); - - void SaveMaterials(bool bSwapEndian); - int SaveMaterial(CMaterialCGF* pMtl, bool bNeedSwap); - int SaveExportFlags(bool bSwapEndian); - - // Compiled chunks for characters - int SaveCompiledBones(bool bSwapEndian, void* pData, int nSize, int version); - int SaveCompiledPhysicalBones(bool bSwapEndian, void* pData, int nSize, int version); - int SaveCompiledPhysicalProxis(bool bSwapEndian, void* pData, int nSize, uint32 numIntMorphTargets, int version); - int SaveCompiledMorphTargets(bool bSwapEndian, void* pData, int nSize, uint32 numIntMorphTargets, int version); - int SaveCompiledIntFaces(bool bSwapEndian, void* pData, int nSize, int version); - int SaveCompiledIntSkinVertices(bool bSwapEndian, void* pData, int nSize, int version); - int SaveCompiledExt2IntMap(bool bSwapEndian, void* pData, int nSize, int version); - int SaveCompiledBoneBox(bool bSwapEndian, void* pData, int nSize, int version); - - // Chunks for characters (for Collada->cgf export) - int SaveBones(bool bSwapEndian, void* pData, int numBones, int nSize); - int SaveBoneNames(bool bSwapEndian, char* boneList, int numBones, int listSize); - int SaveBoneInitialMatrices(bool bSwapEndian, SBoneInitPosMatrix* matrices, int numBones, int nSize); - int SaveBoneMesh(bool bSwapEndian, PhysicalProxy& proxy); -#if defined(RESOURCE_COMPILER) - void SaveUncompiledNodes(); - int SaveUncompiledNode(CNodeCGF* pNode); - void SaveUncompiledMorphTargets(); - int SaveUncompiledNodeMesh(CNodeCGF* pNode); - int SaveUncompiledHelperChunk(CNodeCGF* pNode); -#endif - - int SaveBreakablePhysics(bool bNeedEndianSwap); - - int SaveController831(bool bSwapEndian, const CONTROLLER_CHUNK_DESC_0831& ctrlChunk, void* pData, int nSize); - int SaveControllerDB905(bool bSwapEndian, const CONTROLLER_CHUNK_DESC_0905& ctrlChunk, void* pData, int nSize); - - int SaveFoliage(); - -private: - // Return mesh chunk id - int SaveNodeMesh(CNodeCGF* pNode, bool bSwapEndian, bool bStorePositionsAsF16, bool bUseQTangents, bool bStoreIndicesAsU16); - int SaveHelperChunk(CNodeCGF* pNode, bool bSwapEndian); - int SaveMeshSubsetsChunk(CMesh& mesh, bool bSwapEndian); - int SaveStreamDataChunk(const void* pStreamData, int nStreamType, int nStreamIndex, int nCount, int nElemSize, bool bSwapEndian); - int SavePhysicalDataChunk(const void* pData, int nSize, bool bSwapEndian); - -private: - CChunkFile* m_pChunkFile; - CContentCGF* m_pCGF; - std::set m_savedNodes; - std::set m_savedMaterials; - std::map m_mapMeshToChunk; - bool m_bDoNotSaveMeshData; - bool m_bDoNotSaveNonMeshData; - bool m_bSavePhysicsMeshes; - bool m_bCompactVertexStreams; - bool m_bComputeSubsetTexelDensity; -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CGFSAVER_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/CMakeLists.txt b/Code/CryEngine/Cry3DEngine/CGF/CMakeLists.txt deleted file mode 100644 index 9fb55c6c5c..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -ly_add_target( - NAME Cry3DEngine.CGF.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - cry3dengine_cgf_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - Legacy::CryCommon -) - -ly_add_target( - NAME Cry3DEngine.CGF.RC.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - cry3dengine_cgf_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - COMPILE_DEFINITIONS - PRIVATE - RESOURCE_COMPILER - BUILD_DEPENDENCIES - PRIVATE - Legacy::CryCommon -) diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkData.h b/Code/CryEngine/Cry3DEngine/CGF/ChunkData.h deleted file mode 100644 index beacfa1ed7..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkData.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CHUNKDATA_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CHUNKDATA_H -#pragma once - -struct CChunkData -{ - char* data; - int size; - - CChunkData() { data = 0; size = 0; } - ~CChunkData() { free(data); } - - template - void Add(const T& object) - { - AddData(&object, sizeof(object)); - } - void AddData(const void* pSrcData, int nSrcDataSize) - { - data = (char*)realloc(data, size + nSrcDataSize); - memcpy(data + size, pSrcData, nSrcDataSize); - size += nSrcDataSize; - } -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CHUNKDATA_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.cpp b/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.cpp deleted file mode 100644 index beca3fd6f5..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "ChunkFile.h" -#include "ChunkFileReaders.h" -#include "ChunkFileWriters.h" - -#if !defined(FUNCTION_PROFILER_3DENGINE) - #define FUNCTION_PROFILER_3DENGINE -#endif - -#if !defined(LOADING_TIME_PROFILE_SECTION) - #define LOADING_TIME_PROFILE_SECTION -#endif - -namespace -{ - inline bool ChunkLessOffset(const IChunkFile::ChunkDesc* const p0, const IChunkFile::ChunkDesc* const p1) - { - return IChunkFile::ChunkDesc::LessOffset(*p0, *p1); - } -} - - -CChunkFile::CChunkFile() - : m_pInternalData(NULL) -{ - Clear(); -} - -CChunkFile::~CChunkFile() -{ - Clear(); -} - -void CChunkFile::Clear() -{ - ReleaseMemoryBuffer(); - ReleaseChunks(); - - m_nLastChunkId = 0; - m_pInternalData = NULL; - m_bLoaded = false; -} - -////////////////////////////////////////////////////////////////////////// -CChunkFile::ChunkDesc* CChunkFile::GetChunk(int nChunkIdx) -{ - assert(nChunkIdx >= 0 && nChunkIdx < (int)m_chunks.size()); - return m_chunks[nChunkIdx]; -} - -const CChunkFile::ChunkDesc* CChunkFile::GetChunk(int nChunkIdx) const -{ - assert(nChunkIdx >= 0 && nChunkIdx < (int)m_chunks.size()); - return m_chunks[nChunkIdx]; -} - -// number of chunks -int CChunkFile::NumChunks() const -{ - return (int)m_chunks.size(); -} - -////////////////////////////////////////////////////////////////////////// -int CChunkFile::AddChunk(ChunkTypes chunkType, int chunkVersion, EEndianness eEndianness, const void* chunkData, int chunkSize) -{ - ChunkDesc* const pChunk = new ChunkDesc; - - pChunk->bSwapEndian = (eEndianness == eEndianness_NonNative); - - // This block of code is used for debugging only - if (false) - { - for (size_t i = 0, n = m_chunks.size(); i < n; ++i) - { - if (m_chunks[i]->bSwapEndian != pChunk->bSwapEndian) - { - break; - } - } - } - - pChunk->chunkType = chunkType; - pChunk->chunkVersion = chunkVersion; - - const int chunkId = ++m_nLastChunkId; - pChunk->chunkId = chunkId; - - pChunk->data = new char[chunkSize]; - pChunk->size = chunkSize; - memcpy(pChunk->data, chunkData, chunkSize); - - m_chunks.push_back(pChunk); - m_chunkIdMap[chunkId] = pChunk; - - return chunkId; -} - -////////////////////////////////////////////////////////////////////////// -void CChunkFile::DeleteChunkById(int nChunkId) -{ - for (size_t i = 0, n = m_chunks.size(); i < n; ++i) - { - if (m_chunks[i]->chunkId == nChunkId) - { - m_chunkIdMap.erase(nChunkId); - if (m_chunks[i]->data) - { - delete [] (char*)m_chunks[i]->data; - m_chunks[i]->data = 0; - } - delete m_chunks[i]; - m_chunks.erase(m_chunks.begin() + i); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CChunkFile::DeleteChunksByType(ChunkTypes nChunkType) -{ - size_t j = 0; - for (size_t i = 0, n = m_chunks.size(); i < n; ++i) - { - if (m_chunks[i]->chunkType == nChunkType) - { - m_chunkIdMap.erase(m_chunks[i]->chunkId); - if (m_chunks[i]->data) - { - delete [] (char*)m_chunks[i]->data; - m_chunks[i]->data = 0; - } - delete m_chunks[i]; - } - else - { - m_chunks[j] = m_chunks[i]; - ++j; - } - } - m_chunks.resize(j); -} - -////////////////////////////////////////////////////////////////////////// -void CChunkFile::ReleaseChunks() -{ - m_bLoaded = false; - for (size_t i = 0; i < m_chunks.size(); ++i) - { - if (m_chunks[i]->data) - { - delete [] (char*) m_chunks[i]->data; - } - delete m_chunks[i]; - } - m_chunks.clear(); - m_chunkIdMap.clear(); -} - -////////////////////////////////////////////////////////////////////////// -CChunkFile::ChunkDesc* CChunkFile::FindChunkByType(ChunkTypes nChunkType) -{ - for (size_t i = 0; i < m_chunks.size(); ++i) - { - if (m_chunks[i]->chunkType == nChunkType) - { - return m_chunks[i]; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CChunkFile::ChunkDesc* CChunkFile::FindChunkById(int nChunkId) -{ - ChunkIdMap::iterator it = m_chunkIdMap.find(nChunkId); - if (it != m_chunkIdMap.end()) - { - return it->second; - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CChunkFile::Write(const char* filename) -{ - if (m_chunks.empty()) - { - m_LastError.Format("Writing *empty* chunk files is not supported (file '%s')", filename); - return false; - } - - // Validate requested endianness. Kept here for debug. - if (false) - { - bool bHasSwapEndianTrue = false; - bool bHasSwapEndianFalse = false; - for (size_t i = 0; i < m_chunks.size(); ++i) - { - const ChunkDesc& cd = *m_chunks[i]; - if (cd.bSwapEndian) - { - bHasSwapEndianTrue = true; - } - else - { - bHasSwapEndianFalse = true; - } - } - if (bHasSwapEndianTrue && bHasSwapEndianFalse) - { - //Warning("Writing chunk files with *mixed* endianness is not supported (file '%s')", filename); - } - } - - ChunkFile::OsFileWriter writer; - - if (!writer.Create(filename)) - { - m_LastError.Format("Failed to open '%s' for writing", filename); - return false; - } - - ChunkFile::MemorylessChunkFileWriter wr(ChunkFile::MemorylessChunkFileWriter::eChunkFileFormat_0x746, &writer); - wr.SetAlignment(4); - - while (wr.StartPass()) - { - for (size_t i = 0; i < m_chunks.size(); ++i) - { - const ChunkDesc& cd = *m_chunks[i]; - wr.StartChunk((cd.bSwapEndian ? eEndianness_NonNative : eEndianness_Native), cd.chunkType, cd.chunkVersion, cd.chunkId); - wr.AddChunkData(cd.data, cd.size); - } - } - - if (!wr.HasWrittenSuccessfully()) - { - m_LastError.Format("Failed to write '%s'", filename); - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CChunkFile::WriteToMemoryBuffer(void** pData, int* nSize) -{ - ReleaseMemoryBuffer(); - *pData = 0; - - if (m_chunks.empty()) - { - m_LastError.Format("Writing *empty* chunk files is not supported"); - return false; - } - - // Do writing in *two* stages: - // 1) computing required size (see sizeWriter below) - // 2) allocating and writing data (see memoryWriter below) - - ChunkFile::SizeWriter sizeWriter; - ChunkFile::MemoryWriter memoryWriter; - - for (int stage = 0; stage < 2; ++stage) - { - ChunkFile::IWriter* pWriter; - if (stage == 0) - { - sizeWriter.Start(); - pWriter = &sizeWriter; - } - else - { - assert(m_pInternalData == 0); - *nSize = sizeWriter.GetPos(); - assert(*nSize > 0); - - m_pInternalData = (char*)malloc(*nSize); - if (m_pInternalData == 0) - { - m_LastError.Format("Failed to allocate %u bytes", uint(*nSize)); - return false; - } - - if (!memoryWriter.Start(m_pInternalData, *nSize)) - { - assert(0); - m_LastError.Format("Internal error"); - ReleaseMemoryBuffer(); - return false; - } - pWriter = &memoryWriter; - } - - ChunkFile::MemorylessChunkFileWriter wr(ChunkFile::MemorylessChunkFileWriter::eChunkFileFormat_0x746, pWriter); - wr.SetAlignment(4); - - while (wr.StartPass()) - { - for (size_t i = 0; i < m_chunks.size(); ++i) - { - const ChunkDesc& cd = *m_chunks[i]; - wr.StartChunk((cd.bSwapEndian ? eEndianness_NonNative : eEndianness_Native), cd.chunkType, cd.chunkVersion, cd.chunkId); - wr.AddChunkData(cd.data, cd.size); - } - } - - if (!wr.HasWrittenSuccessfully()) - { - m_LastError.Format("Failed to write"); - ReleaseMemoryBuffer(); - return false; - } - - assert(stage != 2 || memoryWriter.GetPos() == *nSize); - } - - *pData = m_pInternalData; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CChunkFile::ReleaseMemoryBuffer() -{ - if (m_pInternalData) - { - free(m_pInternalData); - m_pInternalData = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CChunkFile::Read(const char* filename) -{ - LOADING_TIME_PROFILE_SECTION; - - ReleaseChunks(); - - // Loading chunks - { - ChunkFile::CryFileReader f; - - if (!f.Open(filename)) - { - m_LastError.Format("File %s failed to open for reading", filename); - return false; - } - - { - const char* err = 0; - - err = ChunkFile::GetChunkTableEntries_0x746(&f, m_chunks); - if (err) - { - err = ChunkFile::GetChunkTableEntries_0x744_0x745(&f, m_chunks); - if (!err) - { - err = ChunkFile::StripChunkHeaders_0x744_0x745(&f, m_chunks); - } - } - - if (err) - { - m_LastError = err; - return false; - } - } - - for (size_t i = 0; i < m_chunks.size(); ++i) - { - ChunkDesc& cd = *m_chunks[i]; - - assert(cd.data == 0); - - cd.data = new char[cd.size]; - - if (!f.SetPos(cd.fileOffset) || - !f.Read(cd.data, cd.size)) - { - m_LastError.Format( - "Failed to read chunk data (offset:%u, size:%u) from file %s", - cd.fileOffset, cd.size, filename); - return false; - } - } - } - - m_nLastChunkId = 0; - - for (size_t i = 0; i < m_chunks.size(); ++i) - { - // Add chunk to chunk map. - m_chunkIdMap[m_chunks[i]->chunkId] = m_chunks[i]; - - // Update last chunk ID. - if (m_chunks[i]->chunkId > m_nLastChunkId) - { - m_nLastChunkId = m_chunks[i]->chunkId; - } - } - - if (m_chunks.size() != m_chunkIdMap.size()) - { - const int duplicateCount = (int)(m_chunks.size() - m_chunkIdMap.size()); - m_LastError.Format( - "%d duplicate chunk ID%s found in file %s", - duplicateCount, ((duplicateCount > 1) ? "s" : ""), filename); - return false; - } - - m_bLoaded = true; - - return true; -} diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.h b/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.h deleted file mode 100644 index bfe1d36a0c..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFile.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILE_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILE_H -#pragma once - -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////// -// Chunk file reader. -// Accesses a chunked file structure through file mapping object. -// Opens a chunk file and checks for its validity. -// If it's invalid, closes it as if there was no open operation. -// Error handling is performed through the return value of Read(): -// it must be true for successfully open files -//////////////////////////////////////////////////////////////////////// - -class CChunkFile - : public IChunkFile -{ -public: - ////////////////////////////////////////////////////////////////////////// - CChunkFile(); - virtual ~CChunkFile(); - - // interface IChunkFile -------------------------------------------------- - - virtual void Release() { delete this; } - - void Clear(); - - virtual bool IsReadOnly() const { return false; } - virtual bool IsLoaded() const { return m_bLoaded; } - - virtual bool Read(const char* filename); - virtual bool ReadFromMemory([[maybe_unused]] const void* pData, [[maybe_unused]] int nDataSize) { return false; } - - virtual bool Write(const char* filename); - virtual bool WriteToMemoryBuffer(void** pData, int* nSize); - virtual void ReleaseMemoryBuffer(); - - virtual int AddChunk(ChunkTypes chunkType, int chunkVersion, EEndianness eEndianness, const void* chunkData, int chunkSize); - virtual void DeleteChunkById(int nChunkId); - virtual void DeleteChunksByType(ChunkTypes nChunkType); - - virtual ChunkDesc* FindChunkByType(ChunkTypes nChunkType); - virtual ChunkDesc* FindChunkById(int nChunkId); - - virtual int NumChunks() const; - - virtual ChunkDesc* GetChunk(int nIndex); - virtual const ChunkDesc* GetChunk(int nIndex) const; - - virtual const char* GetLastError() const { return m_LastError; } - - // ----------------------------------------------------------------------- - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_LastError); - pSizer->AddObject(m_chunks); - pSizer->AddObject(m_chunkIdMap); - } - -private: - void ReleaseChunks(); - -private: - // this variable contains the last error occurred in this class - string m_LastError; - - int m_nLastChunkId; - std::vector m_chunks; - typedef std::map ChunkIdMap; - ChunkIdMap m_chunkIdMap; - char* m_pInternalData; - bool m_bLoaded; -}; - -TYPEDEF_AUTOPTR(CChunkFile); - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILE_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileComponents.h b/Code/CryEngine/Cry3DEngine/CGF/ChunkFileComponents.h deleted file mode 100644 index 88ebfd44ea..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileComponents.h +++ /dev/null @@ -1,265 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILECOMPONENTS_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILECOMPONENTS_H -#pragma once - -#include "CryHeaders.h" - -namespace ChunkFile -{ - // All chunk files use *little-endian* format to store file header and chunk. - // Chunk data are stored in either little-endian or big-endian format, - // see kBigEndianVersionFlag. - - struct FileHeader_0x744_0x745 - { - char signature[7]; - char _pad_[1]; - uint32 fileType; - uint32 version; - uint32 chunkTableOffset; - - enum EFileType - { - eFileType_Geom = 0xFFFF0000U, - eFileType_Anim, - }; - - static const char* GetExpectedSignature() - { - return "CryTek"; - } - - bool HasValidSignature() const - { - return memcmp(GetExpectedSignature(), signature, sizeof(signature)) == 0; - } - - void Set(uint32 a_chunkTableOffset) - { - memcpy(signature, GetExpectedSignature(), sizeof(signature)); - _pad_[0] = 0; - // We need to set eFileType_Geom or eFileType_Anim, but asking - // the caller to provide us the type will complicate the code, so we - // set eFileType_Geom only. It's ok because all our readers - // don't differentiate between eFileType_Geom and eFileType_Anim. - fileType = eFileType_Geom; - version = 0x745; - chunkTableOffset = a_chunkTableOffset; - } - - void SwapEndianness() - { - SwapEndianBase(&fileType, 1); - SwapEndianBase(&version, 1); - SwapEndianBase(&chunkTableOffset, 1); - } - }; - - - struct FileHeader_0x746 - { - char signature[4]; - uint32 version; - uint32 chunkCount; - uint32 chunkTableOffset; - - static const char* GetExpectedSignature() - { - return "CrCh"; - } - - static const char* GetExpectedSpeedTreeSignature() - { - return "STCh"; - } - - bool HasValidSignature() const - { - return (memcmp(GetExpectedSignature(), signature, sizeof(signature)) == 0) || - (memcmp(GetExpectedSpeedTreeSignature(), signature, sizeof(signature)) == 0); - } - - void Set(int32 a_chunkCount, uint32 a_chunkTableOffset) - { - memcpy(signature, GetExpectedSignature(), sizeof(signature)); - version = 0x746; - chunkCount = a_chunkCount; - chunkTableOffset = a_chunkTableOffset; - } - - void SwapEndianness() - { - SwapEndianBase(&version, 1); - SwapEndianBase(&chunkCount, 1); - SwapEndianBase(&chunkTableOffset, 1); - } - }; - - - struct ChunkHeader_0x744_0x745 - { - uint32 type; - uint32 version; - uint32 offsetInFile; - uint32 id; - - enum - { - kBigEndianVersionFlag = 0x80000000U - }; - - void SwapEndianness() - { - SwapEndianBase(&type, 1); - SwapEndianBase(&version, 1); - SwapEndianBase(&offsetInFile, 1); - SwapEndianBase(&id, 1); - } - }; - - - struct ChunkTableEntry_0x744 - : public ChunkHeader_0x744_0x745 - { - void SwapEndianness() - { - ChunkHeader_0x744_0x745::SwapEndianness(); - } - }; - - - struct ChunkTableEntry_0x745 - : public ChunkHeader_0x744_0x745 - { - uint32 size; - - void SwapEndianness() - { - ChunkHeader_0x744_0x745::SwapEndianness(); - SwapEndianBase(&size, 1); - } - }; - - - struct ChunkTableEntry_0x746 - { - uint16 type; - uint16 version; - uint32 id; - uint32 size; - uint32 offsetInFile; - - enum - { - kBigEndianVersionFlag = 0x8000U - }; - - void SwapEndianness() - { - SwapEndianBase(&type, 1); - SwapEndianBase(&version, 1); - SwapEndianBase(&id, 1); - SwapEndianBase(&size, 1); - SwapEndianBase(&offsetInFile, 1); - } - }; - - - // We need this function to strip 0x744 & 0x745 chunk headers - // from chunk data properly: some chunks in 0x744 and 0x745 formats - // don't have chunk headers in their data. - // 'chunkType' is expected to be provided in the 0x746 format. - inline bool ChunkContainsHeader_0x744_0x745(const uint16 chunkType, const uint16 chunkVersion) - { - switch (chunkType) - { - case ChunkType_SourceInfo: - return false; - case ChunkType_Controller: - return (chunkVersion != CONTROLLER_CHUNK_DESC_0827::VERSION && chunkVersion != CONTROLLER_CHUNK_DESC_0830::VERSION); - case ChunkType_BoneNameList: - return (chunkVersion != BONENAMELIST_CHUNK_DESC_0745::VERSION); - case ChunkType_MeshMorphTarget: - return (chunkVersion != MESHMORPHTARGET_CHUNK_DESC_0001::VERSION); - case ChunkType_BoneInitialPos: - return (chunkVersion != BONEINITIALPOS_CHUNK_DESC_0001::VERSION); - default: - return true; - } - } - - - static inline uint16 ConvertChunkTypeTo0x746(uint32 type) - { - if (type <= 0xFFFF) - { - // Input type seems to be already in 0x746 format (or it's 0) - return type; - } - - // Input type seems to be in 0x745 format - - if ((type & 0xFFFF) >= 0xF000) - { - // Cannot fit into resulting 0x746 type (uint16) - return 0; - } - if ((type & 0xFFFF0000U) == 0xCCCC0000U) - { - return 0x1000 + (type & 0x0FFF); - } - if ((type & 0xFFFF0000U) == 0xACDC0000U) - { - return 0x2000 + (type & 0x0FFF); - } - if ((type & 0xFFFF0000U) == 0xAAFC0000U) - { - return 0x3000 + (type & 0x0FFF); - } - - // Unknown 0x745 chunk type - return 0; - } - - static inline uint32 ConvertChunkTypeTo0x745(uint32 type) - { - if (type > 0xFFFF) - { - // Input type seems to be already in 0x745 format - return type; - } - - // Input type seems to be in 0x746 format - - if ((type & 0xF000) == 0x1000) - { - return 0xCCCC0000U + (type & 0x0FFF); - } - if ((type & 0xF000) == 0x2000) - { - return 0xACDC0000U + (type & 0x0FFF); - } - if ((type & 0xF000) == 0x3000) - { - return 0xAAFC0000U + (type & 0x0FFF); - } - - // Unknown 0x746 chunk type (or it's 0) - return 0; - } -} // namespace ChunkFile - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILECOMPONENTS_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.cpp b/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.cpp deleted file mode 100644 index afdd4cbec2..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include -#include -#include "ChunkFileReaders.h" -#include "CryPath.h" - -namespace ChunkFile -{ - ////////////////////////////////////////////////////////////////////////// - - CryFileReader::CryFileReader() - { - } - - CryFileReader::~CryFileReader() - { - Close(); - } - - bool CryFileReader::Open(const char* filename) - { - Close(); - - if (filename == 0 || filename[0] == 0) - { - return false; - } - - if (!m_f.Open(filename, "rb")) - { - return false; - } - - m_offset = 0; - - return true; - } - - void CryFileReader::Close() - { - m_f.Close(); - } - - int32 CryFileReader::GetSize() - { - return m_f.GetLength(); - } - - bool CryFileReader::SetPos(int32 pos) - { - if (pos < 0) - { - return false; - } - m_offset = pos; - return m_f.Seek(m_offset, SEEK_SET) == 0; - } - - bool CryFileReader::Read(void* buffer, size_t size) - { - return m_f.ReadRaw(buffer, size) == size; - } - - ////////////////////////////////////////////////////////////////////////// - - MemoryReader::MemoryReader() - : m_ptr(0) - , m_size(0) - { - } - - MemoryReader::~MemoryReader() - { - } - - bool MemoryReader::Start(void* ptr, int32 size) - { - if (ptr == 0 || size <= 0) - { - return false; - } - - m_ptr = (char*)ptr; - m_size = size; - m_offset = 0; - - return true; - } - - void MemoryReader::Close() - { - } - - int32 MemoryReader::GetSize() - { - return m_size; - } - - bool MemoryReader::SetPos(int32 pos) - { - if (pos < 0 || pos > m_size) - { - return false; - } - m_offset = pos; - return true; - } - - bool MemoryReader::Read(void* buffer, size_t size) - { - if (!m_ptr) - { - return false; - } - - if (size <= 0) - { - return true; - } - - if ((size_t)m_offset + size > (size_t)m_size) - { - return false; - } - - memcpy(buffer, &m_ptr[m_offset], size); - m_offset += size; - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - - namespace - { - class ChunkListRef - { - std::vector& m_chunks; - - public: - ChunkListRef(std::vector& chunks) - : m_chunks(chunks) - { - } - - void Clear() - { - for (size_t i = 0; i < m_chunks.size(); ++i) - { - if (m_chunks[i].data) - { - delete [] (char*)m_chunks[i].data; - m_chunks[i].data = 0; - } - } - m_chunks.clear(); - } - - void Create(size_t count) - { - Clear(); - m_chunks.resize(count); - for (size_t i = 0; i < count; ++i) - { - m_chunks[i].data = 0; - m_chunks[i].size = 0; - } - } - - void Sort() - { - std::sort(m_chunks.begin(), m_chunks.end(), IChunkFile::ChunkDesc::LessOffset); - } - - size_t GetCount() const - { - return m_chunks.size(); - } - - IChunkFile::ChunkDesc& Get(size_t index) - { - return m_chunks[index]; - } - }; - - class ChunkPtrListRef - { - std::vector& m_chunks; - - public: - ChunkPtrListRef(std::vector& chunks) - : m_chunks(chunks) - { - } - - void Clear() - { - for (size_t i = 0; i < m_chunks.size(); ++i) - { - if (m_chunks[i]) - { - if (m_chunks[i]->data) - { - delete [] (char*)(m_chunks[i]->data); - m_chunks[i]->data = 0; - } - delete m_chunks[i]; - } - } - m_chunks.clear(); - } - - void Create(size_t count) - { - Clear(); - m_chunks.resize(count, 0); - for (size_t i = 0; i < count; ++i) - { - m_chunks[i] = new IChunkFile::ChunkDesc; - m_chunks[i]->data = 0; - m_chunks[i]->size = 0; - } - } - - void Sort() - { - std::sort(m_chunks.begin(), m_chunks.end(), IChunkFile::ChunkDesc::LessOffsetByPtr); - } - - size_t GetCount() const - { - return m_chunks.size(); - } - - IChunkFile::ChunkDesc& Get(size_t index) - { - return *m_chunks[index]; - } - }; - } // namespace - - - ////////////////////////////////////////////////////////////////////////// - - template - static const char* GetChunkTableEntries_0x744_0x745_Tpl(IReader* pReader, TListRef& chunks) - { - chunks.Clear(); - - ChunkFile::FileHeader_0x744_0x745 header; - - if (!pReader->SetPos(0) || - !pReader->Read(&header, sizeof(header))) - { - return "Cannot read header of chunk file"; - } - - if (!header.HasValidSignature()) - { - return "Unknown signature in chunk file"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - header.SwapEndianness(); - } - - if (header.version != 0x744 && header.version != 0x745) - { - return "Version of chunk file is neither 0x744 nor 0x745"; - } - - if (header.fileType != header.eFileType_Geom && header.fileType != header.eFileType_Anim) - { - return "Type of chunk file is neither FileType_Geom nor FileType_Anim"; - } - - uint32 chunkCount = 0; - { - if (!pReader->SetPos(header.chunkTableOffset) || - !pReader->Read(&chunkCount, sizeof(chunkCount))) - { - return "Failed to read # of chunks"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - SwapEndianBase(&chunkCount, 1); - } - - if (chunkCount < 0 || chunkCount > 1000000) - { - return "Invalid # of chunks in file"; - } - } - - if (chunkCount <= 0) - { - return 0; - } - - chunks.Create(chunkCount); - - if (header.version == 0x744) - { - std::vector srcChunks; - srcChunks.resize(chunkCount); - - if (!pReader->Read(&srcChunks[0], sizeof(srcChunks[0]) * srcChunks.size())) - { - return "Failed to read chunk entries from file"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - for (uint32 i = 0; i < chunkCount; ++i) - { - srcChunks[i].SwapEndianness(); - } - } - - for (uint32 i = 0; i < chunkCount; ++i) - { - IChunkFile::ChunkDesc& cd = chunks.Get(i); - - cd.chunkType = (ChunkTypes)ConvertChunkTypeTo0x746(srcChunks[i].type); - cd.chunkVersion = srcChunks[i].version & ~ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag; - cd.chunkId = srcChunks[i].id; - cd.fileOffset = srcChunks[i].offsetInFile; - cd.bSwapEndian = (srcChunks[i].version & ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag) ? SYSTEM_IS_LITTLE_ENDIAN : SYSTEM_IS_BIG_ENDIAN; - } - - chunks.Sort(); - - const uint32 endOfChunkData = (header.chunkTableOffset < chunks.Get(0).fileOffset) - ? (uint32)pReader->GetSize() - : header.chunkTableOffset; - - for (uint32 i = 0; i < chunkCount; ++i) - { - // calculate chunk size based on the next (by offset in file) chunk or - // on the end of the chunk data portion of the file - - const size_t nextOffsetInFile = (i + 1 < chunkCount) - ? chunks.Get(i + 1).fileOffset - : endOfChunkData; - - chunks.Get(i).size = nextOffsetInFile - chunks.Get(i).fileOffset; - } - } - else // header.version == 0x745 - { - std::vector srcChunks; - srcChunks.resize(chunkCount); - - if (!pReader->Read(&srcChunks[0], sizeof(srcChunks[0]) * srcChunks.size())) - { - return "Failed to read chunk entries from file."; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - for (uint32 i = 0; i < chunkCount; ++i) - { - srcChunks[i].SwapEndianness(); - } - } - - for (uint32 i = 0; i < chunkCount; ++i) - { - IChunkFile::ChunkDesc& cd = chunks.Get(i); - - cd.chunkType = (ChunkTypes)ConvertChunkTypeTo0x746(srcChunks[i].type); - cd.chunkVersion = srcChunks[i].version & ~ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag; - cd.chunkId = srcChunks[i].id; - cd.fileOffset = srcChunks[i].offsetInFile; - cd.size = srcChunks[i].size; - cd.bSwapEndian = (srcChunks[i].version & ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag) ? SYSTEM_IS_LITTLE_ENDIAN : SYSTEM_IS_BIG_ENDIAN; - } - } - - const uint32 fileSize = (uint32)pReader->GetSize(); - - for (uint32 i = 0; i < chunkCount; ++i) - { - const IChunkFile::ChunkDesc& cd = chunks.Get(i); - - if (cd.size + cd.fileOffset > fileSize) - { - return "Data in chunk file are corrupted"; - } - } - - return 0; - } - - - template - static const char* GetChunkTableEntries_0x746_Tpl(IReader* pReader, TListRef& chunks) - { - chunks.Clear(); - - ChunkFile::FileHeader_0x746 header; - - if (!pReader->SetPos(0) || - !pReader->Read(&header, sizeof(header))) - { - return "Cannot read header from file."; - } - - if (!header.HasValidSignature()) - { - return "Unknown signature in chunk file"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - header.SwapEndianness(); - } - - if (header.version != 0x746) - { - return "Version of chunk file is not 0x746"; - } - - if (header.chunkCount < 0 || header.chunkCount > 10000000) - { - return "Invalid # of chunks in file."; - } - - if (header.chunkCount <= 0) - { - return 0; - } - - chunks.Create(header.chunkCount); - - std::vector srcChunks; - srcChunks.resize(header.chunkCount); - - if (!pReader->SetPos(header.chunkTableOffset) || - !pReader->Read(&srcChunks[0], sizeof(srcChunks[0]) * srcChunks.size())) - { - return "Failed to read chunk entries from file"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - for (uint32 i = 0; i < header.chunkCount; ++i) - { - srcChunks[i].SwapEndianness(); - } - } - - for (size_t i = 0, n = chunks.GetCount(); i < n; ++i) - { - IChunkFile::ChunkDesc& cd = chunks.Get(i); - - cd.chunkType = (ChunkTypes)srcChunks[i].type; - cd.chunkVersion = srcChunks[i].version & ~ChunkFile::ChunkTableEntry_0x746::kBigEndianVersionFlag; - cd.chunkId = srcChunks[i].id; - cd.size = srcChunks[i].size; - cd.fileOffset = srcChunks[i].offsetInFile; - cd.bSwapEndian = (srcChunks[i].version & ChunkFile::ChunkTableEntry_0x746::kBigEndianVersionFlag) ? SYSTEM_IS_LITTLE_ENDIAN : SYSTEM_IS_BIG_ENDIAN; - } - - return 0; - } - - - template - static const char* StripChunkHeaders_0x744_0x745_Tpl(IReader* pReader, TListRef& chunks) - { - for (size_t i = 0, n = chunks.GetCount(); i < n; ++i) - { - IChunkFile::ChunkDesc& ct = chunks.Get(i); - - if (ChunkFile::ChunkContainsHeader_0x744_0x745(ct.chunkType, ct.chunkVersion)) - { - ChunkFile::ChunkHeader_0x744_0x745 ch; - if (ct.size < sizeof(ch)) - { - return "Damaged data: reported size of chunk data is less that size of the chunk header"; - } - - // Validation - { - if (!pReader->SetPos(ct.fileOffset) || - !pReader->Read(&ch, sizeof(ch))) - { - return "Failed to read chunk header from file"; - } - - if (SYSTEM_IS_BIG_ENDIAN) - { - ch.SwapEndianness(); - } - - ch.version &= ~ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag; - - if (ConvertChunkTypeTo0x746(ch.type) != ct.chunkType || - ch.version != ct.chunkVersion || - ch.id != ct.chunkId) - { - return "Data in a chunk header don't match data in the chunk table"; - } - - // The following check is commented out because we have (on 2013/11/25) - // big number of .cgf files in Crysis 3 that fail to pass the check. - //if (ch.offsetInFile != ct.fileOffset) - //{ - // return "File offset data in a chunk header don't match data in the chunk table"; - //} - } - - ct.fileOffset += sizeof(ch); - ct.size -= sizeof(ch); - - if (ct.data) - { - ct.data = ((char*)ct.data) + sizeof(ch); - } - } - - if (ct.size < 0) - { - return "A negative-length chunk found in file"; - } - } - - return 0; - } - - - const char* GetChunkTableEntries_0x744_0x745(IReader* pReader, std::vector& chunks) - { - ChunkListRef c(chunks); - return GetChunkTableEntries_0x744_0x745_Tpl(pReader, c); - } - - const char* GetChunkTableEntries_0x744_0x745(IReader* pReader, std::vector& chunks) - { - ChunkPtrListRef c(chunks); - return GetChunkTableEntries_0x744_0x745_Tpl(pReader, c); - } - - - const char* GetChunkTableEntries_0x746(IReader* pReader, std::vector& chunks) - { - ChunkListRef c(chunks); - return GetChunkTableEntries_0x746_Tpl(pReader, c); - } - - const char* GetChunkTableEntries_0x746(IReader* pReader, std::vector& chunks) - { - ChunkPtrListRef c(chunks); - return GetChunkTableEntries_0x746_Tpl(pReader, c); - } - - - const char* StripChunkHeaders_0x744_0x745(IReader* pReader, std::vector& chunks) - { - ChunkListRef c(chunks); - return StripChunkHeaders_0x744_0x745_Tpl(pReader, c); - } - - const char* StripChunkHeaders_0x744_0x745(IReader* pReader, std::vector& chunks) - { - ChunkPtrListRef c(chunks); - return StripChunkHeaders_0x744_0x745_Tpl(pReader, c); - } -} // namespace ChunkFile diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.h b/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.h deleted file mode 100644 index fa916f8cce..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileReaders.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEREADERS_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEREADERS_H -#pragma once - -#include // for CCryFile -#include "ChunkFileComponents.h" -#include -#include "IChunkFile.h" - -namespace ChunkFile -{ - struct IReader - { - virtual ~IReader() - { - } - - virtual void Close() = 0; - virtual int32 GetSize() = 0; - virtual bool SetPos(int32 pos) = 0; - virtual bool Read(void* buffer, size_t size) = 0; - }; - - - class CryFileReader - : public IReader - { - public: - CryFileReader(); - virtual ~CryFileReader(); - - bool Open(const char* filename); - - //------------------------------------------------------- - // IReader interface - virtual void Close(); - virtual int32 GetSize(); - virtual bool SetPos(int32 pos); - virtual bool Read(void* buffer, size_t size); - //------------------------------------------------------- - - private: - CCryFile m_f; - int32 m_offset; - }; - - - class MemoryReader - : public IReader - { - public: - MemoryReader(); - virtual ~MemoryReader(); - - bool Start(void* ptr, int32 size); - - //------------------------------------------------------- - // IReader interface - virtual void Close(); - virtual int32 GetSize(); - virtual bool SetPos(int32 pos); - virtual bool Read(void* buffer, size_t size); - //------------------------------------------------------- - - private: - char* m_ptr; - int32 m_size; - int32 m_offset; - }; - - - const char* GetChunkTableEntries_0x744_0x745(IReader* pReader, std::vector& chunks); - const char* GetChunkTableEntries_0x744_0x745(IReader* pReader, std::vector& chunks); - - const char* GetChunkTableEntries_0x746(IReader* pReader, std::vector& chunks); - const char* GetChunkTableEntries_0x746(IReader* pReader, std::vector& chunks); - - const char* StripChunkHeaders_0x744_0x745(IReader* pReader, std::vector& chunks); - const char* StripChunkHeaders_0x744_0x745(IReader* pReader, std::vector& chunks); -} // namespace ChunkFile - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEREADERS_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.cpp b/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.cpp deleted file mode 100644 index 006854366d..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "ChunkFileWriters.h" -#include - -static inline size_t ComputeSizeOfAlignment(size_t pos, size_t alignment) -{ - if (alignment <= 1 || (alignment & (alignment - 1))) - { - return 0; - } - const size_t mask = alignment - 1; - return (alignment - (pos & mask)) & mask; -} - - -namespace ChunkFile -{ - ////////////////////////////////////////////////////////////////////////// - - bool IWriter::WriteZeros(size_t size) - { - if (size <= 0) - { - return true; - } - - char bf[1024]; - memset(bf, 0, (sizeof(bf) < size ? sizeof(bf) : size)); - - while (size > 0) - { - const uint32 sz = (sizeof(bf) < size ? sizeof(bf) : size); - size -= sz; - if (!Write(bf, sz)) - { - return false; - } - } - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - - OsFileWriter::OsFileWriter() - : m_f(0) - { - } - - OsFileWriter::~OsFileWriter() - { - Erase(); - } - - bool OsFileWriter::Create(const char* filename) - { - Erase(); - - if (filename == 0 || filename[0] == 0) - { - // RCLogError("Filename is empty"); - return false; - } - - m_filename = filename; - - m_f = nullptr; - azfopen(&m_f, filename, "wb"); - if (!m_f) - { - // RCLogError("Failed to create file %s.", m_filename.c_str()); - return false; - } - - m_offset = 0; - - return true; - } - - void OsFileWriter::Erase() - { - if (m_f) - { - Close(); - ::remove(m_filename.c_str()); - } - } - - void OsFileWriter::Close() - { - if (m_f) - { - fclose(m_f); - m_f = 0; - } - } - - int32 OsFileWriter::GetPos() const - { - return m_offset; - } - - bool OsFileWriter::Write(const void* buffer, size_t size) - { - if (!m_f) - { - return false; - } - - if (size <= 0) - { - return true; - } - - if (fwrite(buffer, size, 1, m_f) != 1) - { - // RCLogError("Failed to write %u byte(s) to file %s.", (uint)size, m_filename.c_str()); - Erase(); - return false; - } - - m_offset += size; - - return true; - } - - ////////////////////////////////////////////////////////////////////////// -#if !defined(RESOURCE_COMPILER) - - CryPakFileWriter::CryPakFileWriter() - : m_pPak(0) - , m_fileHandle(AZ::IO::InvalidHandle) - { - } - - CryPakFileWriter::~CryPakFileWriter() - { - Erase(); - } - - bool CryPakFileWriter::Create(AZ::IO::IArchive* pPak, const char* filename) - { - Erase(); - - if (pPak == 0 || filename == 0 || filename[0] == 0) - { - return false; - } - - m_pPak = pPak; - m_filename = filename; - - m_fileHandle = m_pPak->FOpen(m_filename.c_str(), "w+b"); - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - m_offset = 0; - - return true; - } - - void CryPakFileWriter::Erase() - { - if (m_fileHandle != AZ::IO::InvalidHandle) - { - Close(); - m_pPak->RemoveFile(m_filename.c_str()); - } - } - - void CryPakFileWriter::Close() - { - if (m_fileHandle != AZ::IO::InvalidHandle) - { - m_pPak->FClose(m_fileHandle); - m_fileHandle = AZ::IO::InvalidHandle; - } - } - - int32 CryPakFileWriter::GetPos() const - { - return m_offset; - } - - bool CryPakFileWriter::Write(const void* buffer, size_t size) - { - if (m_fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - if (size <= 0) - { - return true; - } - - if (m_pPak->FWrite(buffer, 1, size, m_fileHandle) != size) - { - Erase(); - return false; - } - - m_offset += size; - - return true; - } - -#endif - ////////////////////////////////////////////////////////////////////////// - - MemoryWriter::MemoryWriter() - : m_ptr(0) - , m_size(0) - { - } - - MemoryWriter::~MemoryWriter() - { - } - - bool MemoryWriter::Start(void* ptr, int32 size) - { - Erase(); - - if (ptr == 0 || size <= 0) - { - return false; - } - - m_ptr = (char*)ptr; - m_size = size; - m_offset = 0; - - return true; - } - - void MemoryWriter::Erase() - { - m_ptr = 0; - m_size = 0; - } - - void MemoryWriter::Close() - { - m_ptr = 0; - m_size = 0; - } - - int32 MemoryWriter::GetPos() const - { - return m_offset; - } - - bool MemoryWriter::Write(const void* buffer, size_t size) - { - if (!m_ptr) - { - return false; - } - - if (size <= 0) - { - return true; - } - - if ((size_t)m_offset + size > (size_t)m_size) - { - Erase(); - return false; - } - - memcpy(&m_ptr[m_offset], buffer, size); - m_offset += size; - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - - MemorylessChunkFileWriter::MemorylessChunkFileWriter( - EChunkFileFormat eFormat, - IWriter* pWriter) - : m_eChunkFileFormat(eFormat) - , m_pWriter(pWriter) - , m_alignment(4) - , m_chunkCount(0) - , m_eState(eState_Init) - { - if (!m_pWriter) - { - m_eState = eState_Fail; - } - } - - MemorylessChunkFileWriter::~MemorylessChunkFileWriter() - { - if (m_eState != eState_Success) - { - Fail(); - } - } - - void MemorylessChunkFileWriter::SetAlignment(size_t alignment) - { - m_alignment = (alignment < 1) ? 1 : alignment; - } - - bool MemorylessChunkFileWriter::StartPass() - { - switch (m_eState) - { - case eState_Init: - m_eState = eState_CountingChunks; - m_chunkIndex = -1; - break; - case eState_CountingChunks: - WriteFileHeader(m_chunkIndex + 1, GetSizeOfHeader()); - m_eState = eState_WritingChunkTable; - WriteChunkTableHeader(m_chunkIndex + 1); - m_dataOffsetInFile = GetSizeOfHeader() + GetSizeOfChunkTable(m_chunkIndex + 1); - m_chunkIndex = -1; - break; - case eState_WritingChunkTable: - if (m_chunkIndex >= 0) - { - WriteChunkEntry(); - } - m_eState = eState_WritingData; - m_dataOffsetInFile = GetSizeOfHeader() + GetSizeOfChunkTable(m_chunkIndex + 1); - m_chunkIndex = -1; - break; - case eState_WritingData: - m_eState = eState_Success; - m_pWriter->Close(); - return false; - case eState_Fail: - return false; - default: - assert(0); - Fail(); - return false; - } - return true; - } - - void MemorylessChunkFileWriter::StartChunk(EEndianness eEndianness, uint32 type, uint32 version, uint32 id) - { - if (type != 0) - { - type = ConvertChunkTypeTo0x746(type); - if (type == 0) - { - Fail(); - return; - } - } - - if (version >= ChunkFile::ChunkTableEntry_0x746::kBigEndianVersionFlag) - { - Fail(); - return; - } - - switch (m_eState) - { - case eState_CountingChunks: - ++m_chunkIndex; - break; - case eState_WritingChunkTable: - if (m_chunkIndex >= 0) - { - WriteChunkEntry(); - } - /* fall through */ - case eState_WritingData: - { - size_t size = ComputeSizeOfAlignment(m_dataOffsetInFile, m_alignment); - - // Make sure that zero-length chunks have distinct positions in file - if (size == 0 && m_chunkIndex > 0 && m_chunkSize == 0) - { - size = m_alignment; - } - - m_dataOffsetInFile += size; - m_chunkOffsetInFile = m_dataOffsetInFile; - if (m_eState == eState_WritingData && !m_pWriter->WriteZeros(size)) - { - Fail(); - return; - } - } - - ++m_chunkIndex; - m_chunkEndianness = eEndianness; - m_chunkType = type; - m_chunkVersion = version; - m_chunkId = id; - m_chunkSize = 0; - - if (m_eChunkFileFormat == eChunkFileFormat_0x745 && - ChunkContainsHeader_0x744_0x745(m_chunkType, m_chunkVersion)) - { - ChunkHeader_0x744_0x745 c; - - c.type = ConvertChunkTypeTo0x745(m_chunkType); - c.version = m_chunkVersion | (m_chunkEndianness == eEndianness_Big ? ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag : 0); - c.id = m_chunkId; - c.offsetInFile = m_chunkOffsetInFile; - - if (SYSTEM_IS_BIG_ENDIAN) - { - c.SwapEndianness(); - } - - AddChunkData(&c, sizeof(c)); - } - break; - default: - Fail(); - break; - } - } - - void MemorylessChunkFileWriter::AddChunkData(void* ptr, size_t size) - { - if (m_chunkIndex < 0) - { - Fail(); - return; - } - - switch (m_eState) - { - case eState_CountingChunks: - break; - case eState_WritingChunkTable: - case eState_WritingData: - m_chunkSize += size; - m_dataOffsetInFile += size; - if (m_eState == eState_WritingData && !m_pWriter->Write(ptr, size)) - { - Fail(); - } - break; - default: - Fail(); - break; - } - } - - void MemorylessChunkFileWriter::AddChunkDataZeros(size_t size) - { - if (m_chunkIndex < 0) - { - Fail(); - return; - } - - switch (m_eState) - { - case eState_CountingChunks: - break; - case eState_WritingChunkTable: - case eState_WritingData: - m_chunkSize += size; - m_dataOffsetInFile += size; - if (m_eState == eState_WritingData && !m_pWriter->WriteZeros(size)) - { - Fail(); - } - break; - default: - Fail(); - break; - } - } - - void MemorylessChunkFileWriter::AddChunkDataAlignment(size_t alignment) - { - const size_t size = ComputeSizeOfAlignment(m_chunkSize, alignment); - return AddChunkDataZeros(size); - } - - bool MemorylessChunkFileWriter::HasWrittenSuccessfully() const - { - return m_eState == eState_Success; - } - - IWriter* MemorylessChunkFileWriter::GetWriter() const - { - return m_pWriter; - } - - ////////////////////////////////////////////////////////////////////////// - - void MemorylessChunkFileWriter::Fail() - { - m_eState = eState_Fail; - if (m_pWriter) - { - m_pWriter->Erase(); - } - } - - size_t MemorylessChunkFileWriter::GetSizeOfHeader() const - { - return (m_eChunkFileFormat == eChunkFileFormat_0x745) - ? sizeof(FileHeader_0x744_0x745) - : sizeof(FileHeader_0x746); - } - - void MemorylessChunkFileWriter::WriteFileHeader(int32 chunkCount, uint32 chunkTableOffsetInFile) - { - if (m_eChunkFileFormat == eChunkFileFormat_0x745) - { - FileHeader_0x744_0x745 h; - h.Set(chunkTableOffsetInFile); - - if (SYSTEM_IS_BIG_ENDIAN) - { - h.SwapEndianness(); - } - - if (!m_pWriter->Write(&h, sizeof(h))) - { - Fail(); - } - } - else - { - FileHeader_0x746 h; - h.Set(chunkCount, chunkTableOffsetInFile); - - if (SYSTEM_IS_BIG_ENDIAN) - { - h.SwapEndianness(); - } - - if (!m_pWriter->Write(&h, sizeof(h))) - { - Fail(); - } - } - } - - size_t MemorylessChunkFileWriter::GetSizeOfChunkTable(int32 chunkCount) const - { - if (m_eChunkFileFormat == eChunkFileFormat_0x745) - { - return sizeof(uint32) + chunkCount * sizeof(ChunkTableEntry_0x745); - } - else - { - return chunkCount * sizeof(ChunkTableEntry_0x746); - } - } - - void MemorylessChunkFileWriter::WriteChunkTableHeader(int32 chunkCount) - { - if (m_eChunkFileFormat == eChunkFileFormat_0x745) - { - if (SYSTEM_IS_BIG_ENDIAN) - { - SwapEndianBase(&chunkCount, 1); - } - - if (!m_pWriter->Write(&chunkCount, sizeof(chunkCount))) - { - Fail(); - } - } - } - - void MemorylessChunkFileWriter::WriteChunkEntry() - { - if (m_chunkIndex < 0) - { - assert(0); - Fail(); - return; - } - - if (m_eChunkFileFormat == eChunkFileFormat_0x745) - { - ChunkTableEntry_0x745 c; - - c.type = ConvertChunkTypeTo0x745(m_chunkType); - c.version = m_chunkVersion | (m_chunkEndianness == eEndianness_Big ? ChunkFile::ChunkHeader_0x744_0x745::kBigEndianVersionFlag : 0); - c.id = m_chunkId; - c.size = m_chunkSize; - c.offsetInFile = m_chunkOffsetInFile; - - if (SYSTEM_IS_BIG_ENDIAN) - { - c.SwapEndianness(); - } - - if (!m_pWriter->Write(&c, sizeof(c))) - { - Fail(); - } - } - else - { - ChunkTableEntry_0x746 c; - - c.type = m_chunkType; - c.version = m_chunkVersion | (m_chunkEndianness == eEndianness_Big ? ChunkFile::ChunkTableEntry_0x746::kBigEndianVersionFlag : 0); - c.id = m_chunkId; - c.size = m_chunkSize; - c.offsetInFile = m_chunkOffsetInFile; - - if (SYSTEM_IS_BIG_ENDIAN) - { - c.SwapEndianness(); - } - - if (!m_pWriter->Write(&c, sizeof(c))) - { - Fail(); - } - } - } - - ////////////////////////////////////////////////////////////////////////// -} // namespace ChunkFile diff --git a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.h b/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.h deleted file mode 100644 index 4bf632efeb..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ChunkFileWriters.h +++ /dev/null @@ -1,341 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEWRITERS_H -#define CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEWRITERS_H -#pragma once - -#include "ChunkFileComponents.h" - -// RESOURCE_COMPIELR is defined by max plugin, too, and the max plugin MAY NOT include any of azcore -// or anything else which uses modern C++ -#if !defined(RESOURCE_COMPILER) -#include -#endif - -namespace AZ::IO -{ - struct IArchive; -} -namespace ChunkFile -{ - struct IWriter - { - virtual ~IWriter() - { - } - - virtual void Erase() = 0; - virtual void Close() = 0; // if Close() is not called then the file should be deleted in destructor - - virtual int32 GetPos() const = 0; - - virtual bool Write(const void* buffer, size_t size) = 0; - - // non-virtual helper function - bool WriteZeros(size_t size); - }; - - - class OsFileWriter - : public IWriter - { - public: - OsFileWriter(); - virtual ~OsFileWriter(); - - bool Create(const char* filename); - - //------------------------------------------------------- - // IWriter interface - virtual void Erase(); - virtual void Close(); - - virtual int32 GetPos() const; - - virtual bool Write(const void* buffer, size_t size); - //------------------------------------------------------- - - private: - string m_filename; - FILE* m_f; - int32 m_offset; - }; - - -#if !defined(RESOURCE_COMPILER) - class CryPakFileWriter - : public IWriter - { - public: - CryPakFileWriter(); - virtual ~CryPakFileWriter(); - - bool Create(AZ::IO::IArchive* pPak, const char* filename); - - //------------------------------------------------------- - // IWriter interface - virtual void Erase(); - virtual void Close(); - - virtual int32 GetPos() const; - - virtual bool Write(const void* buffer, size_t size); - //------------------------------------------------------- - - private: - string m_filename; - AZ::IO::IArchive* m_pPak; - AZ::IO::HandleType m_fileHandle; - int32 m_offset; - }; -#endif - - - // Doesn't write any data, just computes the size - class SizeWriter - : public IWriter - { - public: - SizeWriter() - { - } - virtual ~SizeWriter() - { - } - - void Start() - { - m_offset = 0; - } - - //------------------------------------------------------- - // IWriter interface - virtual void Erase() - { - } - - virtual void Close() - { - } - - virtual int32 GetPos() const - { - return m_offset; - } - - virtual bool Write([[maybe_unused]] const void* buffer, size_t size) - { - m_offset += size; - return true; - } - //------------------------------------------------------- - - private: - int32 m_offset; - }; - - - class MemoryWriter - : public IWriter - { - public: - MemoryWriter(); - virtual ~MemoryWriter(); - - bool Start(void* ptr, int32 size); - - //------------------------------------------------------- - // IWriter interface - virtual void Erase(); - virtual void Close(); - - virtual int32 GetPos() const; - - virtual bool Write(const void* buffer, size_t size); - //------------------------------------------------------- - - private: - char* m_ptr; - int32 m_size; - int32 m_offset; - }; - - - // Memoryless chunk file writer - // - // Usage example: - // - // OsFileWriter writer; - // if (!writer.Create(filename)) - // { - // showAnErrorMessage(); - // } - // else - // { - // MemorylessChunkFileWriter wr(eChunFileFormat, writer); - // while (wr.StartPass()) - // { - // // default alignment of chunk data in file is 4, but you may change it by calling wr.SetAlignment(xxx) - // - // wr.StartChunk(eEndianness_Native, chunkA_type, chunkA_version, chunkA_id); - // wr.AddChunkData(data_ptr0, data_size0); // make sure that data have endianness specified by bLittleEdndian - // wr.AddChunkData(data_ptr1, data_size1); - // ... - // wr.StartChunk(eEndianness_Native, chunkB_type, chunkB_version, chunkB_id); - // wr.AddChunkData(data_ptrN, data_sizeN); - // ... - // } - // if (!wr.HasWrittenSuccessfully()) - // { - // showAnErrorMessage(); - // } - // } - // - // Usage example (interface way): see - // - // OsFileWriter writer; - // if (!writer.Create(filename)) - // { - // showAnErrorMessage(); - // } - // else - // { - // MemorylessChunkFileWriter wr(eChunFileFormat, writer); - // while (wr.StartPass()) - // { - // // default alignment of chunk data in file is 4, but you may change it by calling wr.SetAlignment(xxx) - // - // wr.StartChunk(eEndianness_Native, chunkA_type, chunkA_version, chunkA_id); - // wr.AddChunkData(data_ptr0, data_size0); // make sure that data have endianness specified by bLittleEdndian - // wr.AddChunkData(data_ptr1, data_size1); - // ... - // wr.StartChunk(eEndianness_Native, chunkB_type, chunkB_version, chunkB_id); - // wr.AddChunkData(data_ptrN, data_sizeN); - // ... - // } - // if (!wr.HasWrittenSuccessfully()) - // { - // showAnErrorMessage(); - // } - // } - // - - - struct IChunkFileWriter - { - virtual ~IChunkFileWriter() - { - } - - - // Sets alignment for *beginning* of chunk data. - // Allowed to be called at any time, influences all future - // StartChunk() calls (until a new SetAlignment() call). - virtual void SetAlignment(size_t alignment) = 0; - - // Returns false when there is no more passes left. - virtual bool StartPass() = 0; - - // eEndianness specifies endianness of the data user is - // going to provide via AddChunkData*(). The data will be - // sent to the low-level writer as is, without any re-coding. - virtual void StartChunk(EEndianness eEndianness, uint32 type, uint32 version, uint32 id) = 0; - virtual void AddChunkData(void* ptr, size_t size) = 0; - virtual void AddChunkDataZeros(size_t size) = 0; - virtual void AddChunkDataAlignment(size_t alignment) = 0; - - virtual bool HasWrittenSuccessfully() const = 0; - - virtual IWriter* GetWriter() const = 0; - }; - - - - class MemorylessChunkFileWriter - : public IChunkFileWriter - { - public: - enum EChunkFileFormat - { - eChunkFileFormat_0x745, - eChunkFileFormat_0x746, - }; - - MemorylessChunkFileWriter(EChunkFileFormat eFormat, IWriter* pWriter); - - //------------------------------------------------------- - // IChunkFileWriter interface - virtual ~MemorylessChunkFileWriter(); - - virtual void SetAlignment(size_t alignment); - - virtual bool StartPass(); - - virtual void StartChunk(EEndianness eEndianness, uint32 type, uint32 version, uint32 id); - virtual void AddChunkData(void* ptr, size_t size); - virtual void AddChunkDataZeros(size_t size); - virtual void AddChunkDataAlignment(size_t alignment); - - virtual bool HasWrittenSuccessfully() const; - - virtual IWriter* GetWriter() const; - //------------------------------------------------------- - - private: - void Fail(); - - static size_t ComputeSizeOfAlignmentArea(size_t pos, size_t alignment); - - size_t GetSizeOfHeader() const; - void WriteFileHeader(int32 chunkCount, uint32 chunkTableOffsetInFile); - - size_t GetSizeOfChunkTable(int32 chunkCount) const; - void WriteChunkTableHeader(int32 chunkCount); - void WriteChunkEntry(); - - private: - IWriter* const m_pWriter; - - EChunkFileFormat m_eChunkFileFormat; - - size_t m_alignment; - - int32 m_chunkCount; - - int32 m_chunkIndex; - uint16 m_chunkType; - uint16 m_chunkVersion; - uint32 m_chunkId; - uint32 m_chunkSize; - uint32 m_chunkOffsetInFile; - EEndianness m_chunkEndianness; - - uint32 m_dataOffsetInFile; - - enum EState - { - eState_Init, - - eState_CountingChunks, - eState_WritingChunkTable, - eState_WritingData, - - eState_Success, - eState_Fail, - }; - EState m_eState; - }; -} // namespace ChunkFile - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_CHUNKFILEWRITERS_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.cpp b/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.cpp deleted file mode 100644 index 1aa1f3101b..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include "ReadOnlyChunkFile.h" -#include "ChunkFileComponents.h" -#include "ChunkFileReaders.h" -#include -#include - -#define MAX_CHUNKS_NUM 10000000 - -#if !defined(FUNCTION_PROFILER_3DENGINE) -# define FUNCTION_PROFILER_3DENGINE -#endif - -#if !defined(LOADING_TIME_PROFILE_SECTION) -# define LOADING_TIME_PROFILE_SECTION -#endif - -////////////////////////////////////////////////////////////////////////// -CReadOnlyChunkFile::CReadOnlyChunkFile(bool bCopyFileData, bool bNoWarningMode) -{ - m_pFileBuffer = 0; - m_nBufferSize = 0; - - m_bNoWarningMode = bNoWarningMode; - - m_bOwnFileBuffer = false; - m_bLoaded = false; - m_bCopyFileData = bCopyFileData; -} - -CReadOnlyChunkFile::~CReadOnlyChunkFile() -{ - FreeBuffer(); -} - -////////////////////////////////////////////////////////////////////////// -void CReadOnlyChunkFile::FreeBuffer() -{ - if (m_pFileBuffer && m_bOwnFileBuffer) - { - delete [] m_pFileBuffer; - } - m_pFileBuffer = 0; - m_nBufferSize = 0; - m_bOwnFileBuffer = false; - m_bLoaded = false; -} - -////////////////////////////////////////////////////////////////////////// -CReadOnlyChunkFile::ChunkDesc* CReadOnlyChunkFile::GetChunk(int nIndex) -{ - assert(size_t(nIndex) < m_chunks.size()); - return &m_chunks[nIndex]; -} - -////////////////////////////////////////////////////////////////////////// -const CReadOnlyChunkFile::ChunkDesc* CReadOnlyChunkFile::GetChunk(int nIndex) const -{ - assert(size_t(nIndex) < m_chunks.size()); - return &m_chunks[nIndex]; -} - -// number of chunks -int CReadOnlyChunkFile::NumChunks() const -{ - return (int)m_chunks.size(); -} - -////////////////////////////////////////////////////////////////////////// -CReadOnlyChunkFile::ChunkDesc* CReadOnlyChunkFile::FindChunkByType(ChunkTypes nChunkType) -{ - for (size_t i = 0, count = m_chunks.size(); i < count; ++i) - { - if (m_chunks[i].chunkType == nChunkType) - { - return &m_chunks[i]; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CReadOnlyChunkFile::ChunkDesc* CReadOnlyChunkFile::FindChunkById(int id) -{ - ChunkDesc chunkToFind; - chunkToFind.chunkId = id; - - std::vector::iterator it = std::lower_bound(m_chunks.begin(), m_chunks.end(), chunkToFind, IChunkFile::ChunkDesc::LessId); - if (it != m_chunks.end() && id == (*it).chunkId) - { - return &(*it); - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadOnlyChunkFile::ReadChunkTableFromBuffer() -{ - LOADING_TIME_PROFILE_SECTION; - - if (m_pFileBuffer == 0) - { - m_LastError.Format("Unexpected empty buffer"); - return false; - } - - { - ChunkFile::MemoryReader f; - - if (!f.Start(m_pFileBuffer, m_nBufferSize)) - { - m_LastError.Format("Empty memory chunk file"); - return false; - } - - bool bStripHeaders = false; - const char* err = 0; - - err = ChunkFile::GetChunkTableEntries_0x746(&f, m_chunks); - if (err) - { - err = ChunkFile::GetChunkTableEntries_0x744_0x745(&f, m_chunks); - bStripHeaders = true; - } - - if (!err) - { - for (size_t i = 0; i < m_chunks.size(); ++i) - { - ChunkDesc& cd = m_chunks[i]; - cd.data = m_pFileBuffer + cd.fileOffset; - } - if (bStripHeaders) - { - err = ChunkFile::StripChunkHeaders_0x744_0x745(&f, m_chunks); - } - } - - if (err) - { - m_LastError = err; - return false; - } - } - - // Sort chunks by Id, for faster queries later (see FindChunkById()). - std::sort(m_chunks.begin(), m_chunks.end(), IChunkFile::ChunkDesc::LessId); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadOnlyChunkFile::Read(const char* filename) -{ - LOADING_TIME_PROFILE_SECTION; - - FreeBuffer(); - - if (!AZ::IO::FileIOBase::GetInstance()) - { - m_LastError = "File system not ready yet."; - return false; - } - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(filename)) - { - m_LastError.Format("File '%s' not found", filename); - return false; - } - - AZ::u64 fileSize; - if (!AZ::IO::FileIOBase::GetInstance()->Size(filename, fileSize)) - { - m_LastError.Format("Failed to retrieve file size for '%s'", filename); - return false; - } - - m_pFileBuffer = new char[fileSize]; - m_bOwnFileBuffer = true; - - AZ::IO::FileIOStream stream(filename, AZ::IO::OpenMode::ModeRead); - if (stream.Read(fileSize, m_pFileBuffer) != fileSize) - { - m_LastError.Format("Failed to read %u bytes from file '%s'", fileSize, filename); - return false; - } - - m_nBufferSize = aznumeric_caster(fileSize); - - if (!ReadChunkTableFromBuffer()) - { - return false; - } - - m_bLoaded = true; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadOnlyChunkFile::ReadFromMemory(const void* pData, int nDataSize) -{ - LOADING_TIME_PROFILE_SECTION; - - FreeBuffer(); - - m_pFileBuffer = (char*)pData; - m_bOwnFileBuffer = false; - m_nBufferSize = nDataSize; - - if (!ReadChunkTableFromBuffer()) - { - return false; - } - m_bLoaded = true; - return true; -} diff --git a/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.h b/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.h deleted file mode 100644 index 9f0be6481a..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/ReadOnlyChunkFile.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CGF_READONLYCHUNKFILE_H -#define CRYINCLUDE_CRY3DENGINE_CGF_READONLYCHUNKFILE_H -#pragma once - -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////// -// Chunk file reader. -// Accesses a chunked file structure through file mapping object. -// Opens a chunk file and checks for its validity. -// If it's invalid, closes it as if there was no open operation. -// Error handling is performed through the return value of Read: it must -// be true for successfully open files -//////////////////////////////////////////////////////////////////////// - -class CReadOnlyChunkFile - : public IChunkFile -{ -public: - ////////////////////////////////////////////////////////////////////////// - CReadOnlyChunkFile(bool bCopyFileData, bool bNoWarningMode = false); - virtual ~CReadOnlyChunkFile(); - - // interface IChunkFile -------------------------------------------------- - - virtual void Release() { delete this; } - - virtual bool IsReadOnly() const { return true; } - virtual bool IsLoaded() const { return m_bLoaded; } - - virtual bool Read(const char* filename); - virtual bool ReadFromMemory(const void* pData, int nDataSize); - - virtual bool Write([[maybe_unused]] const char* filename) { return false; } - virtual bool WriteToMemoryBuffer([[maybe_unused]] void** pData, [[maybe_unused]] int* nSize) { return false; } - virtual void ReleaseMemoryBuffer() {} - - virtual int AddChunk([[maybe_unused]] ChunkTypes chunkType, [[maybe_unused]] int chunkVersion, [[maybe_unused]] EEndianness eEndianness, [[maybe_unused]] const void* chunkData, [[maybe_unused]] int chunkSize) { return -1; } - virtual void DeleteChunkById([[maybe_unused]] int nChunkId) {} - virtual void DeleteChunksByType([[maybe_unused]] ChunkTypes nChunkType) {} - - virtual ChunkDesc* FindChunkByType(ChunkTypes nChunkType); - virtual ChunkDesc* FindChunkById(int nChunkId); - - virtual int NumChunks() const; - - virtual ChunkDesc* GetChunk(int nIndex); - virtual const ChunkDesc* GetChunk(int nIndex) const; - - virtual const char* GetLastError() const { return m_LastError; } - - // ----------------------------------------------------------------------- - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_LastError); - pSizer->AddObject(m_chunks); - } -private: - bool ReadChunkTableFromBuffer(); - void FreeBuffer(); - -private: - // this variable contains the last error occurred in this class - string m_LastError; - - std::vector m_chunks; - - char* m_pFileBuffer; - int m_nBufferSize; - bool m_bOwnFileBuffer; - bool m_bNoWarningMode; - bool m_bLoaded; - bool m_bCopyFileData; -}; - -TYPEDEF_AUTOPTR(CReadOnlyChunkFile); - -#endif // CRYINCLUDE_CRY3DENGINE_CGF_READONLYCHUNKFILE_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/SwapEndianness.h b/Code/CryEngine/Cry3DEngine/CGF/SwapEndianness.h deleted file mode 100644 index d61c611d59..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/SwapEndianness.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_TOOLS_RC_RESOURCECOMPILER_SWAPENDIANNESS_H -#define CRYINCLUDE_TOOLS_RC_RESOURCECOMPILER_SWAPENDIANNESS_H -#pragma once - - - -inline void SwapEndians_(void* pData, size_t nCount, size_t nSizeCheck) -{ - // Primitive type. - switch (nSizeCheck) - { - case 1: - break; - case 2: - { - while (nCount--) - { - uint16& i = *((uint16*&)pData)++; - i = ((i >> 8) + (i << 8)) & 0xFFFF; - } - break; - } - case 4: - { - while (nCount--) - { - uint32& i = *((uint32*&)pData)++; - i = (i >> 24) + ((i >> 8) & 0xFF00) + ((i & 0xFF00) << 8) + (i << 24); - } - break; - } - case 8: - { - while (nCount--) - { - uint64& i = *((uint64*&)pData)++; - i = (i >> 56) + ((i >> 40) & 0xFF00) + ((i >> 24) & 0xFF0000) + ((i >> 8) & 0xFF000000) - + ((i & 0xFF000000) << 8) + ((i & 0xFF0000) << 24) + ((i & 0xFF00) << 40) + (i << 56); - } - break; - } - default: - assert(0); - } -} - - -template -void SwapEndianness(T* t, std::size_t count) -{ - SwapEndians_(t, count, sizeof(T)); -} - - -template -void SwapEndianness(T& t) -{ - SwapEndianness(&t, 1); -} - - -#endif // CRYINCLUDE_TOOLS_RC_RESOURCECOMPILER_SWAPENDIANNESS_H diff --git a/Code/CryEngine/Cry3DEngine/CGF/cry3dengine_cgf_files.cmake b/Code/CryEngine/Cry3DEngine/CGF/cry3dengine_cgf_files.cmake deleted file mode 100644 index 754cc58b3e..0000000000 --- a/Code/CryEngine/Cry3DEngine/CGF/cry3dengine_cgf_files.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - CGFLoader.cpp - CGFSaver.cpp - ChunkFile.cpp - ReadOnlyChunkFile.cpp - CGFLoader.h - CGFSaver.h - ChunkData.h - ChunkFile.h - ReadOnlyChunkFile.h - ChunkFileReaders.cpp - ChunkFileReaders.h - ChunkFileWriters.cpp - ChunkFileWriters.h - SwapEndianness.h -) diff --git a/Code/CryEngine/Cry3DEngine/CMakeLists.txt b/Code/CryEngine/Cry3DEngine/CMakeLists.txt deleted file mode 100644 index 89d7e09e30..0000000000 --- a/Code/CryEngine/Cry3DEngine/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -add_subdirectory(CGF) -add_subdirectory(MeshCompiler) - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform) - -ly_add_target( - NAME Cry3DEngine.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - cry3dengine_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - PRIVATE - ${pal_tool_dirs} - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::mikkelsen - Legacy::CryCommon - Legacy::CryRender.Headers -) - -ly_add_target( - NAME Cry3DEngine ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} - NAMESPACE Legacy - FILES_CMAKE - cry3dengine_shared_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - .. - BUILD_DEPENDENCIES - PRIVATE - Legacy::Cry3DEngine.Static - Legacy::Cry3DEngine.MeshCompiler.Static - Legacy::Cry3DEngine.CGF.Static - Legacy::CryCommon -) - -################################################################################ -# Tests -################################################################################ -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_add_target( - NAME Cry3DEngine.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - cry3dengine_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Legacy::CryCommon - Legacy::Cry3DEngine.Static - Legacy::Cry3DEngine.MeshCompiler.Static - Legacy::Cry3DEngine.CGF.Static - ) - ly_add_googletest( - NAME Legacy::Cry3DEngine.Tests - ) -endif() diff --git a/Code/CryEngine/Cry3DEngine/CZBufferCuller.cpp b/Code/CryEngine/Cry3DEngine/CZBufferCuller.cpp deleted file mode 100644 index 381c6b8058..0000000000 --- a/Code/CryEngine/Cry3DEngine/CZBufferCuller.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Occlusion buffer - - -#include "Cry3DEngine_precompiled.h" -#include "CZBufferCuller.h" - -SHWOccZBuffer HWZBuffer; - -void CZBufferCuller::BeginFrame(const SRenderingPassInfo& passInfo) -{ - if (!GetCVars()->e_CoverageBuffer) - { - return; - } - const CCamera& rCam = passInfo.GetCamera(); - m_AccurateTest = GetCVars()->e_CoverageBufferAccurateOBBTest; - - m_Treshold = GetCVars()->e_CoverageBufferTolerance; - - - FUNCTION_PROFILER_3DENGINE; - if (GetCVars()->e_CoverageBufferDebugFreeze || GetCVars()->e_CameraFreeze) - { - return; - } - - m_ObjectsTested = - m_ObjectsTestedAndRejected = 0; - //to enable statistics - m_Camera = rCam; - m_Position = rCam.GetPosition(); - uint32 oldSizeX = m_SizeX; - - const uint32 sizeX = min(max(1, GetCVars()->e_CoverageBufferResolution), 1024); - const uint32 sizeY = sizeX; - - m_SizeX = sizeX; - m_SizeY = sizeY; - m_fSizeX = static_cast(sizeX); - m_fSizeY = static_cast(sizeY); - m_fSizeZ = static_cast(TZB_MAXDEPTH); - - - if (oldSizeX != sizeX) - { - CryModuleMemalignFree(m_ZBuffer); - //64-byte buffer to avoid memory page issues when vector loading - m_ZBuffer = (TZBZexel*)CryModuleMemalign((sizeof(TZBZexel) * sizeX * sizeY) + 64, 128); - } - - m_MatViewProj.Transpose(); - - m_RotationSafe = GetCVars()->e_CoverageBufferRotationSafeCheck; - - m_DebugFreez = GetCVars()->e_CoverageBufferDebugFreeze != 0; -} - -void CZBufferCuller::ReloadBuffer(const uint32 BufferID) -{ - if (m_DebugFreez) - { - return; - } - m_Bias = BufferID == 0 ? static_cast(GetCVars()->e_CoverageBufferBias) : 0; -} - - -CZBufferCuller::CZBufferCuller() - : m_OutdoorVisible(1) - , m_MatViewProj(IDENTITY) -{ - m_SizeX = - m_SizeY = min(max(1, GetCVars()->e_CoverageBufferResolution), 1024); - m_ZBuffer = (TZBZexel*)CryModuleMemalign((sizeof(TZBZexel) * m_SizeX * m_SizeY) + 64, 128); - - m_ObjectsTested = - m_ObjectsTestedAndRejected = 0; -} - -bool CZBufferCuller::IsBoxVisible(const AABB& objBox, [[maybe_unused]] uint32* const __restrict pResDest) -{ - FUNCTION_PROFILER_3DENGINE; - m_ObjectsTested++; - Vec4 Verts[8] = - { - m_MatViewProj* Vec4(objBox.min.x, objBox.min.y, objBox.min.z, 1.f),//0 - m_MatViewProj * Vec4(objBox.min.x, objBox.max.y, objBox.min.z, 1.f),//1 - m_MatViewProj * Vec4(objBox.max.x, objBox.min.y, objBox.min.z, 1.f),//2 - m_MatViewProj * Vec4(objBox.max.x, objBox.max.y, objBox.min.z, 1.f),//3 - m_MatViewProj * Vec4(objBox.min.x, objBox.min.y, objBox.max.z, 1.f),//4 - m_MatViewProj * Vec4(objBox.min.x, objBox.max.y, objBox.max.z, 1.f),//5 - m_MatViewProj * Vec4(objBox.max.x, objBox.min.y, objBox.max.z, 1.f),//6 - m_MatViewProj * Vec4(objBox.max.x, objBox.max.y, objBox.max.z, 1.f)//7 - }; - bool CutNearPlane = Verts[0].w <= 0.f; - CutNearPlane |= Verts[1].w <= 0.f; - CutNearPlane |= Verts[2].w <= 0.f; - CutNearPlane |= Verts[3].w <= 0.f; - CutNearPlane |= Verts[4].w <= 0.f; - CutNearPlane |= Verts[5].w <= 0.f; - CutNearPlane |= Verts[6].w <= 0.f; - CutNearPlane |= Verts[7].w <= 0.f; - if (CutNearPlane) - { - return true; - } - - IF (m_RotationSafe == 1, 0) - { - return Rasterize<1>(Verts, 8); - } - IF (m_RotationSafe == 2, 1) - { - return Rasterize<2>(Verts, 8); - } - return Rasterize<0>(Verts, 8); -} - -static int sh = 8; -void CZBufferCuller::DrawDebug(int32 nStep) -{ // project buffer to the screen - nStep %= 32; - if (!nStep) - { - return; - } - - const CCamera& rCam = GetCamera(); - float farPlane = rCam.GetFarPlane(); - float nearPlane = rCam.GetNearPlane(); - - float a = farPlane / (farPlane - nearPlane); - float b = farPlane * nearPlane / (nearPlane - farPlane); - - const float scale = 10.0f; - - TransformationMatrices backupSceneMatrices; - - m_pRenderer->Set2DMode(m_SizeX, m_SizeY, backupSceneMatrices); - SAuxGeomRenderFlags Flags = e_Def3DPublicRenderflags; - Flags.SetDepthWriteFlag(e_DepthWriteOff); - Flags.SetAlphaBlendMode(e_AlphaBlended); - m_pRenderer->GetIRenderAuxGeom()->SetRenderFlags(Flags); - Vec3 vSize(.4f, .4f, .4f); - if (nStep == 1) - { - vSize = Vec3(.5f, .5f, .5f); - } - for (uint32 y = 0; y < m_SizeY; y += nStep) - { - for (uint32 x = 0; x < m_SizeX; x += nStep) - { - Vec3 vPos((float)x, (float)(m_SizeY - y - 1), 0); - vPos += Vec3(0.5f, -0.5f, 0); - const uint32 Value = m_ZBuffer[x + y * m_SizeX]; - //Value>>=sh; - - float w = Value / (65535.0f); - - float z = b / (w - a); - - uint32 ValueC = 255u - min(255u, (uint32)(z * scale)); - ColorB col; - - col = ColorB(ValueC, ValueC, ValueC, 200); - - - if (Value != 0xffff) - { - //ColorB col((Value&31)<<3,((Value>>5)&31)<<3,((Value>>10)&63)<<2,200); - GetRenderer()->GetIRenderAuxGeom()->DrawAABB(AABB(vPos - vSize, vPos + vSize), nStep <= 2, col, eBBD_Faceted); - } - } - } - //m_pRenderer->GetIRenderAuxGeom()->Flush(); - m_pRenderer->Unset2DMode(backupSceneMatrices); -} - -void CZBufferCuller::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "CoverageBuffer"); - pSizer->AddObject(m_ZBuffer, sizeof(TZBZexel) * m_SizeX * m_SizeY); -} diff --git a/Code/CryEngine/Cry3DEngine/CZBufferCuller.h b/Code/CryEngine/Cry3DEngine/CZBufferCuller.h deleted file mode 100644 index f5e01abc68..0000000000 --- a/Code/CryEngine/Cry3DEngine/CZBufferCuller.h +++ /dev/null @@ -1,273 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Occlusion Culler using hardware generated ZBuffer - - -#ifndef CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H -#define CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H -#pragma once - -#include -struct IRenderMesh; - -typedef uint16 TZBZexel; -const uint64 TZB_MAXDEPTH = (1 << (sizeof(TZBZexel) * 8)) - 1; - -class CZBufferCuller - : public Cry3DEngineBase -{ -protected: - bool m_DebugFreez; - uint32 m_SizeX; - uint32 m_SizeY; - f32 m_fSizeX; - f32 m_fSizeY; - f32 m_fSizeZ; - TZBZexel* m_ZBuffer; - - Matrix44 m_MatProj; - Matrix44 m_MatView; - Matrix44 m_MatViewProj; - Matrix44A m_MatViewProjT; - Vec3 m_Position; - - int32 m_Bias; - uint32 m_RotationSafe; - uint32 m_AccurateTest; - uint32 m_Treshold; - - f32 m_FixedZFar; - uint32 m_ObjectsTested; - uint32 m_ObjectsTestedAndRejected; - CCamera m_Camera; - int m_OutdoorVisible; - - template - bool Rasterize(const T rVertices, const uint32 VCount) - { - int64 MinX = m_SizeX; - int64 MaxX = 0; - int64 MinY = m_SizeY; - int64 MaxY = 0; - int64 MinZ = TZB_MAXDEPTH; - for (uint32 a = 0; a < VCount; a++) - { - Vec4 V = rVertices[a]; - const f32 InvW = 1.f / V.w; - int64 X = static_cast((V.x * InvW * 0.5f + 0.5f) * m_fSizeX + 0.5f); - int64 Y = static_cast((V.y * InvW * 0.5f + 0.5f) * m_fSizeY + 0.5f); - int64 Z = static_cast(V.z * InvW * m_fSizeZ); - if (X < MinX) - { - MinX = X; - } - else - if (X > MaxX) - { - MaxX = X; - } - if (Y < MinY) - { - MinY = Y; - } - else - if (Y > MaxY) - { - MaxY = Y; - } - if (Z < MinZ) - { - MinZ = Z; - } - } - if (MinX < 0) - { - if constexpr (ROTATE == 1) - { - return true; - } - else - { - MinX = 0; - } - } - if (MaxX > m_SizeX) - { - if constexpr (ROTATE == 1) - { - return true; - } - else - { - MaxX = m_SizeX; - } - } - if (MinY < 0) - { - if constexpr (ROTATE == 1) - { - return true; - } - else - { - MinY = 0; - } - } - if (MaxY > m_SizeY) - { - if constexpr (ROTATE == 1) - { - return true; - } - else - { - MaxY = m_SizeY; - } - } - if constexpr (ROTATE == 2) - { - if (MinX >= m_SizeX || MinY >= m_SizeY || MaxX < 0 || MaxX < 0) - { - return true; - } - } - for (int64 y = MinY; y < MaxY; y++) - { - for (int64 x = MinX; x < MaxX; x++) - { - if (static_cast(m_ZBuffer[static_cast(x) + static_cast(y) * m_SizeX]) > MinZ) - { - return true; - } - } - } - return false; - } - - - - bool IsBoxVisible_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_OCEAN(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_OCCELL(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_OCCELL_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_OBJECT(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_OBJECT_TO_LIGHT(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_TERRAIN_NODE(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible_PORTAL(const AABB& objBox, uint32* const __restrict pResDest = NULL); - bool IsBoxVisible(const AABB& objBox, uint32* const __restrict pResDest = NULL); - - -public: - CZBufferCuller(); - ~CZBufferCuller(){CryModuleMemalignFree(m_ZBuffer); } - - // start new frame - void BeginFrame(const SRenderingPassInfo& passInfo); - void ReloadBuffer(const uint32 BufferID); - - // render into buffer - ILINE void AddRenderMesh([[maybe_unused]] IRenderMesh* pRM, [[maybe_unused]] Matrix34A* pTranRotMatrix, _smart_ptr pMaterial, [[maybe_unused]] bool bOutdoorOnly, [[maybe_unused]] bool bCompletelyInFrustum, [[maybe_unused]] bool bNoCull){} - - - ILINE bool IsObjectVisible(const AABB& objBox, EOcclusionObjectType eOcclusionObjectType, [[maybe_unused]] float fDistance, uint32* pRetVal = NULL) - { - switch (eOcclusionObjectType) - { - case eoot_OCCLUDER: - return IsBoxVisible_OCCLUDER(objBox, pRetVal); - case eoot_OCEAN: - return IsBoxVisible_OCEAN(objBox, pRetVal); - case eoot_OCCELL: - return IsBoxVisible_OCCELL(objBox, pRetVal); - case eoot_OCCELL_OCCLUDER: - return IsBoxVisible_OCCELL_OCCLUDER(objBox, pRetVal); - case eoot_OBJECT: - return IsBoxVisible_OBJECT(objBox, pRetVal); - case eoot_OBJECT_TO_LIGHT: - return IsBoxVisible_OBJECT_TO_LIGHT(objBox, pRetVal); - case eoot_TERRAIN_NODE: - return IsBoxVisible_TERRAIN_NODE(objBox, pRetVal); - case eoot_PORTAL: - return IsBoxVisible_PORTAL(objBox, pRetVal); - } - assert(!"Undefined occluder type"); - - return true; - } - - // draw content to the screen for debug - void DrawDebug(int32 nStep); - - // return current camera - const CCamera& GetCamera() const {return m_Camera; } - - void GetMemoryUsage(ICrySizer* pSizer) const; - - bool IsOutdooVisible(){return m_OutdoorVisible == 1; } - int32 TrisWritten() const{return 0; } - int32 ObjectsWritten() const{return 0; } - int32 TrisTested() const{return 0; } - int32 ObjectsTested() const{return m_ObjectsTested; } - int32 ObjectsTestedAndRejected() const{return m_ObjectsTestedAndRejected; } - int32 SelRes() const{return m_SizeX; } - float FixedZFar() const{return m_FixedZFar; } - float GetZNearInMeters() const{return 0.f; } - float GetZFarInMeters() const{return 1024; } -} _ALIGN(128); - -ILINE bool CZBufferCuller::IsBoxVisible_TERRAIN_NODE(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OCCELL_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OCCLUDER(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OCEAN(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OCCELL(const AABB& objBox, uint32* const __restrict pResDest) -{ - if (GetCVars()->e_CoverageBufferDebugFreeze) - { - return true; - } - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OBJECT(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_OBJECT_TO_LIGHT(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -ILINE bool CZBufferCuller::IsBoxVisible_PORTAL(const AABB& objBox, uint32* const __restrict pResDest) -{ - return IsBoxVisible(objBox, pResDest); -} - -#endif // CRYINCLUDE_CRY3DENGINE_CZBUFFERCULLER_H diff --git a/Code/CryEngine/Cry3DEngine/ClipVolume.cpp b/Code/CryEngine/Cry3DEngine/ClipVolume.cpp deleted file mode 100644 index 841e8c983b..0000000000 --- a/Code/CryEngine/Cry3DEngine/ClipVolume.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "ClipVolume.h" - -CClipVolume::CClipVolume() - : m_nStencilRef(0) - , m_WorldTM(IDENTITY) - , m_InverseWorldTM(IDENTITY) - , m_BBoxWS(AABB::RESET) - , m_BBoxLS(AABB::RESET) - , m_pBspTree(NULL) -{ - memset(m_sName, 0x0, sizeof(m_sName)); -} - -CClipVolume::~CClipVolume() -{ - m_pRenderMesh = NULL; - - for (size_t i = 0; i < m_lstRenderNodes.size(); ++i) - { - if (m_lstRenderNodes[i]->m_pRNTmpData) - { - m_lstRenderNodes[i]->m_pRNTmpData->userData.m_pClipVolume = NULL; - } - } -} - -void CClipVolume::SetName(const char* szName) -{ - cry_strcpy(m_sName, szName); -} - -void CClipVolume::GetClipVolumeMesh(_smart_ptr& renderMesh, Matrix34& worldTM) const -{ - renderMesh = m_pRenderMesh; - worldTM = m_WorldTM; -} - -AABB CClipVolume::GetClipVolumeBBox() const -{ - return m_BBoxWS; -} - -void CClipVolume::Update(_smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, uint32 flags) -{ - const bool bMeshUpdated = m_pRenderMesh != pRenderMesh; - - m_pRenderMesh = pRenderMesh; - m_pBspTree = pBspTree; - m_WorldTM = worldTM; - m_InverseWorldTM = worldTM.GetInverted(); - m_BBoxWS.Reset(); - m_BBoxLS.Reset(); - m_nFlags = flags; - - if (m_pRenderMesh) - { - pRenderMesh->GetBBox(m_BBoxLS.min, m_BBoxLS.max); - m_BBoxWS.SetTransformedAABB(worldTM, m_BBoxLS); - } -} - -bool CClipVolume::IsPointInsideClipVolume(const Vec3& point) const -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pRenderMesh || !m_pBspTree || !m_BBoxWS.IsContainPoint(point)) - { - return false; - } - - Vec3 pt = m_InverseWorldTM.TransformPoint(point); - return m_BBoxLS.IsContainPoint(pt) && m_pBspTree->IsInside(pt); -} - -void CClipVolume::RegisterRenderNode(IRenderNode* pRenderNode) -{ - if (m_lstRenderNodes.Find(pRenderNode) < 0) - { - m_lstRenderNodes.Add(pRenderNode); - - if (pRenderNode->m_pRNTmpData) - { - pRenderNode->m_pRNTmpData->userData.m_pClipVolume = this; - } - } -} -void CClipVolume::UnregisterRenderNode(IRenderNode* pRenderNode) -{ - if (m_lstRenderNodes.Delete(pRenderNode) && pRenderNode->m_pRNTmpData) - { - pRenderNode->m_pRNTmpData->userData.m_pClipVolume = NULL; - } -} - -void CClipVolume::GetMemoryUsage(class ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); -} diff --git a/Code/CryEngine/Cry3DEngine/ClipVolume.h b/Code/CryEngine/Cry3DEngine/ClipVolume.h deleted file mode 100644 index 8f3d4d1d44..0000000000 --- a/Code/CryEngine/Cry3DEngine/ClipVolume.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __INCLUDE_CRY3DENGINE_CLIPVOLUME_H -#define __INCLUDE_CRY3DENGINE_CLIPVOLUME_H - -struct IBSPTree3D; - -class CClipVolume - : public IClipVolume -{ -public: - CClipVolume(); - virtual ~CClipVolume(); - - ////////////// IClipVolume implementation ////////////// - virtual void GetClipVolumeMesh(_smart_ptr& renderMesh, Matrix34& worldTM) const; - virtual AABB GetClipVolumeBBox() const; - - virtual uint8 GetStencilRef() const { return m_nStencilRef; } - virtual uint GetClipVolumeFlags() const { return m_nFlags; } - virtual bool IsPointInsideClipVolume(const Vec3& vPos) const; - //////////////////////////// - - void SetName(const char* szName); - void SetStencilRef(int nStencilRef) { m_nStencilRef = nStencilRef; } - - void Update(_smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, uint32 flags); - - void RegisterRenderNode(IRenderNode* pRenderNode); - void UnregisterRenderNode(IRenderNode* pRenderNode); - - void GetMemoryUsage(class ICrySizer* pSizer) const; - -private: - uint8 m_nStencilRef; - uint32 m_nFlags; - Matrix34 m_WorldTM; - Matrix34 m_InverseWorldTM; - AABB m_BBoxWS; - AABB m_BBoxLS; - - _smart_ptr m_pRenderMesh; - IBSPTree3D* m_pBspTree; - - PodArray m_lstRenderNodes; - char m_sName[64]; -}; - -#endif //__INCLUDE_CRY3DENGINE_CLIPVOLUME_H diff --git a/Code/CryEngine/Cry3DEngine/ClipVolumeManager.cpp b/Code/CryEngine/Cry3DEngine/ClipVolumeManager.cpp deleted file mode 100644 index 26e0b5c238..0000000000 --- a/Code/CryEngine/Cry3DEngine/ClipVolumeManager.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "ClipVolume.h" -#include "ClipVolumeManager.h" -#include "LightEntity.h" -#include "FogVolumeRenderNode.h" -#include "ObjMan.h" - -CClipVolumeManager::~CClipVolumeManager() -{ - assert(m_ClipVolumes.empty()); -} - -IClipVolume* CClipVolumeManager::CreateClipVolume() -{ - SClipVolumeInfo volumeInfo(new CClipVolume()); - m_ClipVolumes.push_back(volumeInfo); - - return m_ClipVolumes.back().m_pVolume; -} - -bool CClipVolumeManager::DeleteClipVolume(IClipVolume* pClipVolume) -{ - if (m_ClipVolumes.Delete(static_cast(pClipVolume))) - { - delete pClipVolume; - return true; - } - return false; -} - -bool CClipVolumeManager::UpdateClipVolume(IClipVolume* pClipVolume, _smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, bool bActive, uint32 flags, const char* szName) -{ - int nVolumeIndex = m_ClipVolumes.Find((CClipVolume*)pClipVolume); - if (nVolumeIndex >= 0) - { - SClipVolumeInfo& volumeInfo = m_ClipVolumes[nVolumeIndex]; - volumeInfo.m_pVolume->Update(pRenderMesh, pBspTree, worldTM, flags); - volumeInfo.m_pVolume->SetName(szName); - volumeInfo.m_bActive = bActive; - - AABB volumeBBox = pClipVolume->GetClipVolumeBBox(); - Get3DEngine()->GetObjManager()->ReregisterEntitiesInArea(volumeBBox.min, volumeBBox.max); - return true; - } - - return false; -} - -void CClipVolumeManager::PrepareVolumesForRendering(const SRenderingPassInfo& passInfo) -{ - for (size_t i = 0; i < m_ClipVolumes.size(); ++i) - { - SClipVolumeInfo& volInfo = m_ClipVolumes[i]; - volInfo.m_pVolume->SetStencilRef(InactiveVolumeStencilRef); - - if (volInfo.m_bActive && passInfo.GetCamera().IsAABBVisible_F(volInfo.m_pVolume->GetClipVolumeBBox())) - { - uint8 nStencilRef = GetRenderer()->EF_AddDeferredClipVolume(volInfo.m_pVolume); - volInfo.m_pVolume->SetStencilRef(nStencilRef); - } - } -} - -void CClipVolumeManager::UpdateEntityClipVolume(const Vec3& pos, IRenderNode* pRenderNode) -{ - FRAME_PROFILER("CClipVolumeManager::UpdateEntityClipVolume", GetSystem(), PROFILE_3DENGINE); - - if (!pRenderNode || !pRenderNode->m_pRNTmpData) - { - return; - } - - IClipVolume* pPreviousVolume = pRenderNode->m_pRNTmpData->userData.m_pClipVolume; - UnregisterRenderNode(pRenderNode); - - // user assigned clip volume - CLightEntity* pLight = static_cast(pRenderNode); - if (pRenderNode->GetRenderNodeType() == eERType_Light && (pLight->m_light.m_Flags & DLF_HAS_CLIP_VOLUME) != 0) - { - for (int i = 1; i >= 0; --i) - { - if (CClipVolume* pVolume = static_cast(pLight->m_light.m_pClipVolumes[i])) - { - pVolume->RegisterRenderNode(pRenderNode); - } - } - } - else // assign by position - { - // Check if entity is in same clip volume as before - if (pPreviousVolume && (pPreviousVolume->GetClipVolumeFlags() & IClipVolume::eClipVolumeIsVisArea) == 0) - { - CClipVolume* pVolume = static_cast(pPreviousVolume); - if (pVolume->IsPointInsideClipVolume(pos)) - { - pVolume->RegisterRenderNode(pRenderNode); - return; - } - } - - if (CClipVolume* pVolume = GetClipVolumeByPos(pos, pPreviousVolume)) - { - pVolume->RegisterRenderNode(pRenderNode); - } - } -} - -void CClipVolumeManager::UnregisterRenderNode(IRenderNode* pRenderNode) -{ - if (!pRenderNode) - { - return; - } - - for (size_t i = 0; i < m_ClipVolumes.size(); ++i) - { - m_ClipVolumes[i].m_pVolume->UnregisterRenderNode(pRenderNode); - } - - if (pRenderNode->m_pRNTmpData) - { - pRenderNode->m_pRNTmpData->userData.m_pClipVolume = NULL; - } -} - -bool CClipVolumeManager::IsClipVolumeRequired(IRenderNode* pRenderNode) const -{ - const uint32 NoClipVolumeLights = DLF_SUN | DLF_ATTACH_TO_SUN; - - const bool bForwardObject = (pRenderNode->m_nInternalFlags & IRenderNode::REQUIRES_FORWARD_RENDERING) != 0; - const EERType ertype = pRenderNode->GetRenderNodeType(); - const bool bIsValidLight = ertype == eERType_Light && - (static_cast(pRenderNode)->m_light.m_Flags & NoClipVolumeLights) == 0; - const bool bIsValidFogVolume = (ertype == eERType_FogVolume) && - static_cast(pRenderNode)->IsAffectsThisAreaOnly(); - - return bIsValidLight || bForwardObject || bIsValidFogVolume; -} - -CClipVolume* CClipVolumeManager::GetClipVolumeByPos(const Vec3& pos, const IClipVolume* pIgnoreVolume) const -{ - for (size_t i = 0; i < m_ClipVolumes.size(); ++i) - { - const SClipVolumeInfo& volInfo = m_ClipVolumes[i]; - - if (volInfo.m_bActive && volInfo.m_pVolume != pIgnoreVolume && volInfo.m_pVolume->IsPointInsideClipVolume(pos)) - { - return m_ClipVolumes[i].m_pVolume; - } - } - - return NULL; -} - -void CClipVolumeManager::GetMemoryUsage(class ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(this)); - for (size_t i = 0; i < m_ClipVolumes.size(); ++i) - { - pSizer->AddObject(m_ClipVolumes[i].m_pVolume); - } -} diff --git a/Code/CryEngine/Cry3DEngine/ClipVolumeManager.h b/Code/CryEngine/Cry3DEngine/ClipVolumeManager.h deleted file mode 100644 index 46a4bf27fe..0000000000 --- a/Code/CryEngine/Cry3DEngine/ClipVolumeManager.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __INCLUDE_CRY3DENGINE_CLIPVOLUMEMANAGER_H -#define __INCLUDE_CRY3DENGINE_CLIPVOLUMEMANAGER_H - -class CClipVolume; - -class CClipVolumeManager - : public Cry3DEngineBase -{ - struct SClipVolumeInfo - { - CClipVolume* m_pVolume; - bool m_bActive; - - SClipVolumeInfo() - : m_bActive(false) {} - SClipVolumeInfo(CClipVolume* pVolume) - : m_pVolume(pVolume) - , m_bActive(false) - {} - - bool operator==(const SClipVolumeInfo& other) const { return m_pVolume == other.m_pVolume; } - }; - -public: - static const uint8 InactiveVolumeStencilRef = 0xFD; - static const uint8 AffectsEverythingStencilRef = 0xFE; - - virtual ~CClipVolumeManager(); - - virtual IClipVolume* CreateClipVolume(); - virtual bool DeleteClipVolume(IClipVolume* pClipVolume); - virtual bool UpdateClipVolume(IClipVolume* pClipVolume, _smart_ptr pRenderMesh, IBSPTree3D* pBspTree, const Matrix34& worldTM, bool bActive, uint32 flags, const char* szName); - - void PrepareVolumesForRendering(const SRenderingPassInfo& passInfo); - - void UpdateEntityClipVolume(const Vec3& pos, IRenderNode* pRenderNode); - void UnregisterRenderNode(IRenderNode* pRenderNode); - - bool IsClipVolumeRequired(IRenderNode* pRenderNode) const; - CClipVolume* GetClipVolumeByPos(const Vec3& pos, const IClipVolume* pIgnoreVolume = NULL) const; - - void GetMemoryUsage(class ICrySizer* pSizer) const; - size_t GetClipVolumeCount() const { return m_ClipVolumes.size(); } - -private: - PodArray m_ClipVolumes; -}; - - -#endif //__INCLUDE_CRY3DENGINE_CLIPVOLUMEMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/CloudRenderNode.cpp b/Code/CryEngine/Cry3DEngine/CloudRenderNode.cpp deleted file mode 100644 index 344617622e..0000000000 --- a/Code/CryEngine/Cry3DEngine/CloudRenderNode.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "CloudRenderNode.h" -#include "CloudsManager.h" -#include "VisAreas.h" -#include "ObjMan.h" -#include "Environment/OceanEnvironmentBus.h" - -////////////////////////////////////////////////////////////////////////// -CCloudRenderNode::CCloudRenderNode() -{ - m_bounds.min = Vec3(-1, -1, -1); - m_bounds.max = Vec3(1, 1, 1); - m_fScale = 1.0f; - m_offsetedMatrix.SetIdentity(); - m_matrix.SetIdentity(); - m_vOffset.Set(0, 0, 0); - m_alpha = 1.f; - - m_pCloudRenderElement = (CREBaseCloud*)GetRenderer()->EF_CreateRE(eDATA_Cloud); - m_pREImposter = (CREImposter*) GetRenderer()->EF_CreateRE(eDATA_Imposter); - - GetCloudsManager()->AddCloudRenderNode(this); - - m_origin = Vec3(0, 0, 0); - m_moveProps.m_autoMove = false; - m_moveProps.m_speed = Vec3(0, 0, 0); - m_moveProps.m_spaceLoopBox = Vec3(2000.0f, 2000.0f, 2000.0f); - m_moveProps.m_fadeDistance = 0; -} - -////////////////////////////////////////////////////////////////////////// -CCloudRenderNode::~CCloudRenderNode() -{ - GetCloudsManager()->RemoveCloudRenderNode(this); - m_pCloudRenderElement->Release(false); - m_pREImposter->Release(false); - - Get3DEngine()->FreeRenderNodeState(this); -} - - -////////////////////////////////////////////////////////////////////////// -bool CCloudRenderNode::LoadCloudFromXml(XmlNodeRef root) -{ - m_pCloudDesc = new SCloudDescription; - GetCloudsManager()->ParseCloudFromXml(root, m_pCloudDesc); - - SetCloudDesc(m_pCloudDesc); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CCloudRenderNode::LoadCloud(const char* sCloudFilename) -{ - m_bounds.min = Vec3(-1, -1, -1); - m_bounds.max = Vec3(1, 1, 1); - - SetCloudDesc(GetCloudsManager()->LoadCloud(sCloudFilename)); - - return m_pCloudDesc != 0; -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::SetMovementProperties(const SCloudMovementProperties& properties) -{ - m_moveProps = properties; -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::SetCloudDesc(SCloudDescription* pCloud) -{ - m_pCloudDesc = pCloud; - if (m_pCloudDesc != NULL && m_pCloudDesc->m_particles.size() > 0) - { - m_vOffset = m_pCloudDesc->m_offset; - m_bounds.min = m_pCloudDesc->m_bounds.min - m_pCloudDesc->m_offset; - m_bounds.max = m_pCloudDesc->m_bounds.max - m_pCloudDesc->m_offset; - if (m_pCloudDesc->m_pMaterial) - { - m_pMaterial = m_pCloudDesc->m_pMaterial; - } - m_pCloudRenderElement->SetParticles(&m_pCloudDesc->m_particles[0], m_pCloudDesc->m_particles.size()); - - m_WSBBox.SetTransformedAABB(m_matrix, m_bounds); - m_fScale = m_matrix.GetColumn(0).GetLength(); - // Offset matrix by the cloud bounds offset. - m_offsetedMatrix = m_matrix * Matrix34::CreateTranslationMat(-m_vOffset); - } -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::SetMatrix(const Matrix34& mat) -{ - SetMatrixInternal(mat, true); -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::SetMatrixInternal(const Matrix34& mat, bool updateOrigin) -{ - m_dwRndFlags |= ERF_OUTDOORONLY; - - if (updateOrigin) - { - m_origin = mat.GetTranslation(); - } - - m_matrix = mat; - m_pos = mat.GetTranslation(); - // m_WSBBox.SetTransformedAABB( m_matrix,m_bounds ); - m_fScale = mat.GetColumn(0).GetLength(); - m_WSBBox.SetTransformedAABB(Matrix34::CreateTranslationMat(m_pos), AABB(m_bounds.min * m_fScale, m_bounds.max * m_fScale)); - - // Offset matrix by the cloud bounds offset. - // m_offsetedMatrix = m_matrix * Matrix34::CreateTranslationMat(-m_vOffset); - m_offsetedMatrix = Matrix34::CreateTranslationMat(m_pos - m_vOffset * m_fScale); - m_offsetedMatrix.ScaleColumn(Vec3(m_fScale, m_fScale, m_fScale)); - Get3DEngine()->RegisterEntity(this); -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::MoveCloud() -{ - FUNCTION_PROFILER_3DENGINE; - - Vec3 pos(m_matrix.GetTranslation()); - - ITimer* pTimer(gEnv->pTimer); - if (m_moveProps.m_autoMove) - { - // update position - float deltaTime = pTimer->GetFrameTime(); - - assert(deltaTime >= 0); - - pos += deltaTime * m_moveProps.m_speed; - - // constrain movement to specified loop box - Vec3 loopBoxMin(m_origin - m_moveProps.m_spaceLoopBox); - Vec3 loopBoxMax(m_origin + m_moveProps.m_spaceLoopBox); - - if (pos.x < loopBoxMin.x) - { - pos.x = loopBoxMax.x; - } - if (pos.y < loopBoxMin.y) - { - pos.y = loopBoxMax.y; - } - if (pos.z < loopBoxMin.z) - { - pos.z = loopBoxMax.z; - } - - if (pos.x > loopBoxMax.x) - { - pos.x = loopBoxMin.x; - } - if (pos.y > loopBoxMax.y) - { - pos.y = loopBoxMin.y; - } - if (pos.z > loopBoxMax.z) - { - pos.z = loopBoxMin.z; - } - - // set new position - Matrix34 mat(m_matrix); - mat.SetTranslation(pos); - SetMatrixInternal(mat, false); - - // fade out clouds at the borders of the loop box - if (m_moveProps.m_fadeDistance > 0) - { - Vec3 fade(max(m_moveProps.m_spaceLoopBox.x, m_moveProps.m_fadeDistance), - max(m_moveProps.m_spaceLoopBox.y, m_moveProps.m_fadeDistance), - max(m_moveProps.m_spaceLoopBox.z, m_moveProps.m_fadeDistance)); - - fade -= Vec3(fabs(pos.x - m_origin.x), fabs(pos.y - m_origin.y), fabs(pos.z - m_origin.z)); - - m_alpha = clamp_tpl(min(min(fade.x, fade.y), fade.z) / m_moveProps.m_fadeDistance, 0.0f, 1.0f); - } - } - else - { - if ((m_origin - pos).GetLengthSquared() > 1e-4f) - { - Matrix34 mat(m_matrix); - mat.SetTranslation(m_origin); - SetMatrixInternal(mat, false); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pMaterial || !passInfo.RenderClouds()) - { - return; - } - - IRenderer* pRenderer(GetRenderer()); - - // get render objects - CRenderObject* pRO = pRenderer->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pRO) - { - return; - } - - SShaderItem& shaderItem = (rParams.pMaterial) ? rParams.pMaterial->GetShaderItem(0) : m_pMaterial->GetShaderItem(0); - - pRO->m_II.m_Matrix = m_offsetedMatrix; - SRenderObjData* pOD = pRenderer->EF_GetObjData(pRO, true, passInfo.ThreadID()); - pOD->m_fTempVars[0] = m_fScale; - pRO->m_fSort = 0; - pRO->m_fDistance = rParams.fDistance; - int nAfterWater = GetObjManager()->IsAfterWater(m_offsetedMatrix.GetTranslation(), passInfo) ? 1 : 0; - pRO->m_II.m_AmbColor = rParams.AmbientColor; - pRO->m_fAlpha = rParams.fAlpha * m_alpha; - - float mvd(GetMaxViewDist()); - float d((passInfo.GetCamera().GetPosition() - m_offsetedMatrix.GetTranslation()).GetLength()); - if (d > 0.9f * mvd) - { - float s(clamp_tpl(1.0f - (d - 0.9f * mvd) / (0.1f * mvd), 0.0f, 1.0f)); - pRO->m_fAlpha *= s; - } - - pRenderer->EF_AddEf(m_pCloudRenderElement, shaderItem, pRO, passInfo, EFSLIST_TRANSP, nAfterWater, SRendItemSorter(rParams.rendItemSorter)); -} - -////////////////////////////////////////////////////////////////////////// -bool CCloudRenderNode::CheckIntersection(const Vec3& p1, const Vec3& p2) -{ - if (p1 == p2) - { - return false; - } - if (m_pCloudDesc && m_pCloudDesc->m_pCloudTree) - { - Vec3 outp; - if (Intersect::Lineseg_AABB(Lineseg(p1, p2), m_WSBBox, outp)) - { - Matrix34 pInv = m_offsetedMatrix.GetInverted(); - return m_pCloudDesc->m_pCloudTree->CheckIntersection(pInv * p1, pInv * p2); - } - } - return false; -} - -void CCloudRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_pos += delta; - m_origin += delta; - m_matrix.SetTranslation(m_matrix.GetTranslation() + delta); - m_offsetedMatrix.SetTranslation(m_offsetedMatrix.GetTranslation() + delta); - m_WSBBox.Move(delta); -} diff --git a/Code/CryEngine/Cry3DEngine/CloudRenderNode.h b/Code/CryEngine/Cry3DEngine/CloudRenderNode.h deleted file mode 100644 index c82dc1ebcc..0000000000 --- a/Code/CryEngine/Cry3DEngine/CloudRenderNode.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CLOUDRENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_CLOUDRENDERNODE_H -#pragma once - -struct SCloudDescription; - -////////////////////////////////////////////////////////////////////////// -// RenderNode for rendering single cloud object. -////////////////////////////////////////////////////////////////////////// -class CCloudRenderNode - : public ICloudRenderNode - , public Cry3DEngineBase -{ -public: - - CCloudRenderNode(); - - ////////////////////////////////////////////////////////////////////////// - // Implements ICloudRenderNode - ////////////////////////////////////////////////////////////////////////// - virtual bool LoadCloud(const char* sCloudFilename); - virtual bool LoadCloudFromXml(XmlNodeRef cloudNode); - virtual void SetMovementProperties(const SCloudMovementProperties& properties); - - ////////////////////////////////////////////////////////////////////////// - // Implements IRenderNode - ////////////////////////////////////////////////////////////////////////// - virtual void GetLocalBounds(AABB& bbox) { bbox = m_bounds; }; - virtual void SetMatrix(const Matrix34& mat); - - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const { return "Cloud"; } - virtual const char* GetName() const { return "Cloud"; } - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - void SetMaterial(_smart_ptr pMat) override { m_pMaterial = pMat; } - virtual _smart_ptr GetMaterial(Vec3* pHitPos = NULL); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - ////////////////////////////////////////////////////////////////////////// - - bool CheckIntersection(const Vec3& p1, const Vec3& p2); - void MoveCloud(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -private: - void SetCloudDesc(SCloudDescription* pCloud); - ~CCloudRenderNode(); - virtual void SetMatrixInternal(const Matrix34& mat, bool updateOrigin); - -private: - Vec3 m_pos; - float m_fScale; - _smart_ptr m_pMaterial; - _smart_ptr m_pCloudDesc; - Matrix34 m_matrix; - Matrix34 m_offsetedMatrix; - Vec3 m_vOffset; - AABB m_bounds; - - CREBaseCloud* m_pCloudRenderElement; - CREImposter* m_pREImposter; - float m_alpha; - - Vec3 m_origin; - SCloudMovementProperties m_moveProps; - - AABB m_WSBBox; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_CLOUDRENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/CloudsManager.cpp b/Code/CryEngine/Cry3DEngine/CloudsManager.cpp deleted file mode 100644 index 9c1a52b921..0000000000 --- a/Code/CryEngine/Cry3DEngine/CloudsManager.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "CloudRenderNode.h" -#include "CloudsManager.h" -#include -#include "MatMan.h" - -////////////////////////////////////////////////////////////////////////// -SCloudDescription::~SCloudDescription() -{ - delete m_pCloudTree; - m_pCloudTree = 0; - // Unregister itself from clouds manager. - if (!filename.empty()) - { - Get3DEngine()->GetCloudsManager()->Unregister(this); - } -} - -////////////////////////////////////////////////////////////////////////// -SCloudDescription* CCloudsManager::LoadCloud(const char* sFilename) -{ - string filename = PathUtil::ToUnixPath(sFilename); - - SCloudDescription* pCloud = stl::find_in_map(m_cloudsMap, filename, NULL); - if (!pCloud) - { - XmlNodeRef root = GetISystem()->LoadXmlFromFile(filename); - if (root) - { - pCloud = new SCloudDescription; - pCloud->filename = filename; - ParseCloudFromXml(root, pCloud); - - CloudParticles particles; - particles.resize(pCloud->m_particles.size()); - for (uint32 i = 0; i < particles.size(); i++) - { - particles[i] = &pCloud->m_particles[i]; - } - pCloud->m_pCloudTree = new SCloudQuadTree(); - pCloud->m_pCloudTree->Init(pCloud->m_bounds, particles); - - Register(pCloud); - } - } - - return pCloud; -} - - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::ParseCloudFromXml(XmlNodeRef root, SCloudDescription* pCloud) -{ - assert(pCloud); - - pCloud->m_bounds.min = Vec3(0, 0, 0); - pCloud->m_bounds.max = Vec3(0, 0, 0); - pCloud->m_pMaterial = 0; - const char* sMtlName = root->getAttr("Material"); - if (sMtlName && sMtlName[0] != '\0') - { - pCloud->m_pMaterial = GetMatMan()->LoadMaterial(sMtlName); - - if (!pCloud->m_pMaterial) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Error: Failed to load cloud material" /*,sMtlName*/); - } - } - - int numRows = 1; - int numCols = 1; - root->getAttr("TextureNumRows", numRows); - root->getAttr("TextureNumCols", numCols); - if (numRows < 1) - { - numRows = 1; - } - if (numCols < 1) - { - numCols = 1; - } - - pCloud->m_textureRows = numRows; - pCloud->m_textureCols = numCols; - - pCloud->m_numSprites = root->getChildCount(); - pCloud->m_particles.reserve(pCloud->m_numSprites); - pCloud->m_particles.clear(); - - float xTextureStep = 1.0f / numCols; - float yTextureStep = 1.0f / numRows; - - Vec3 pos(0, 0, 0); - int texID = 0; - float angle = 0; - float radius = 0; - Vec2 uv[2]; - if (pCloud->m_numSprites > 0) - { - pCloud->m_bounds.Reset(); - } - for (int i = 0; i < root->getChildCount(); i++) - { - XmlNodeRef child = root->getChild(i); - child->getAttr("Pos", pos); - child->getAttr("texID", texID); - child->getAttr("Radius", radius); - if (!child->getAttr("Angle", angle)) - { - angle = 0; - } - - int x = texID % numCols; - int y = texID / numCols; - - uv[0].x = x * xTextureStep; - uv[0].y = y * yTextureStep; - uv[1].x = (x + 1) * xTextureStep; - uv[1].y = (y + 1) * yTextureStep; - - SCloudParticle sprite(pos, radius, radius, 0, 0, uv); - pCloud->m_particles.push_back(sprite); - - pCloud->m_bounds.Add(pos - Vec3(radius, radius, radius)); - pCloud->m_bounds.Add(pos + Vec3(radius, radius, radius)); - } - - // Offset particles so that bounding box is centered at origin. - pCloud->m_offset = -pCloud->m_bounds.GetCenter(); - pCloud->m_bounds.min += pCloud->m_offset; - pCloud->m_bounds.max += pCloud->m_offset; - - for (uint32 i = 0; i < pCloud->m_particles.size(); i++) - { - pCloud->m_particles[i].SetPosition(pCloud->m_particles[i].GetPosition() + pCloud->m_offset); - } -} - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::Register(SCloudDescription* desc) -{ - assert(desc); - m_cloudsMap[desc->filename] = desc; -} - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::Unregister(SCloudDescription* desc) -{ - assert(desc); - m_cloudsMap.erase(desc->filename); -} - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::AddCloudRenderNode(CCloudRenderNode* pNode) -{ - m_cloudNodes.push_back(pNode); -} - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::RemoveCloudRenderNode(CCloudRenderNode* pNode) -{ - int size = m_cloudNodes.size(); - for (int i = 0; i < size; i++) - { - if (m_cloudNodes[i] == pNode) - { - if (i < size - 1) - { - m_cloudNodes[i] = m_cloudNodes[size - 1]; - } - m_cloudNodes.resize(size - 1); - break; - } - } -} - -//!!! WARNING -//bool Sp_IsDraw = false; -//Matrix34 Sp_Mat; -//Vec3 Sp_Pos; -//float Sp_Rad; - - -////////////////////////////////////////////////////////////////////////// -bool CCloudsManager::CheckIntersectClouds(const Vec3& p1, const Vec3& p2) -{ - for (std::vector::iterator it = m_cloudNodes.begin(); it != m_cloudNodes.end(); ++it) - { - //Sp_IsDraw = false; - if ((*it)->CheckIntersection(p1, p2)) - { - //Sp_Mat = (*it)->m_offsetedMatrix; - //Sp_IsDraw = true; - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CCloudsManager::MoveClouds() -{ - FUNCTION_PROFILER_3DENGINE; - - std::vector::iterator it(m_cloudNodes.begin()); - std::vector::iterator itEnd(m_cloudNodes.end()); - for (; it != itEnd; ++it) - { - (*it)->MoveCloud(); - } -} - -////////////////////////////////////////////////////////////////////////// -void SCloudQuadTree::Init(const AABB& bounds, const CloudParticles& particles, int maxlevel) -{ - m_bounds = bounds; - - if (m_level >= maxlevel) - { - m_particles.resize(particles.size()); - memcpy(&m_particles[0], &particles[0], particles.size() * sizeof(SCloudParticle*)); - return; - } - - CloudParticles parts; - for (int k = 0; k < 4; k++) - { - AABB bnds; - parts.resize(0); - - Vec3 centr = (bounds.min + bounds.max) / 2; - - if (k == 0) - { - bnds = AABB(bounds.min, Vec3(centr.x, centr.y, bounds.max.z)); - } - else if (k == 1) - { - bnds = AABB(Vec3(bounds.min.x, centr.y, bounds.min.z), Vec3(centr.x, bounds.max.y, bounds.max.z)); - } - else if (k == 2) - { - bnds = AABB(Vec3(centr.x, bounds.min.y, bounds.min.z), Vec3(bounds.max.x, centr.y, bounds.max.z)); - } - else if (k == 3) - { - bnds = AABB(Vec3(centr.x, centr.y, bounds.min.z), bounds.max); - } - for (uint32 i = 0; i < particles.size(); i++) - { - SCloudParticle* pPtcl = particles[i]; - if (bnds.IsOverlapSphereBounds(pPtcl->GetPosition(), pPtcl->GetRadiusX()) || - bnds.IsContainSphere(pPtcl->GetPosition(), pPtcl->GetRadiusX())) - { - parts.push_back(pPtcl); - } - } - if (!parts.empty()) - { - m_pQuads[k] = new SCloudQuadTree(m_level + 1); - m_pQuads[k]->Init(bnds, parts, maxlevel); - } - } -} - - -////////////////////////////////////////////////////////////////////////// -bool SCloudQuadTree::CheckIntersection(const Vec3& p1, const Vec3& p2) -{ - Vec3 outp, outp2; - if (Intersect::Lineseg_AABB(Lineseg(p1, p2), m_bounds, outp)) - { - if (m_pQuads[0] && m_pQuads[0]->CheckIntersection(p1, p2)) - { - return true; - } - if (m_pQuads[1] && m_pQuads[1]->CheckIntersection(p1, p2)) - { - return true; - } - if (m_pQuads[2] && m_pQuads[2]->CheckIntersection(p1, p2)) - { - return true; - } - if (m_pQuads[3] && m_pQuads[3]->CheckIntersection(p1, p2)) - { - return true; - } - if (!m_particles.empty()) - { - for (uint32 i = 0; i < m_particles.size(); i++) - { - //if(Intersect::Lineseg_Sphere(Lineseg(p1, p2), Sphere (m_particles[i]->GetPosition(), m_particles[i]->GetRadiusX()*(2.0f/3)), outp, outp2)) - if (Intersect::Lineseg_Sphere(Lineseg(p1, p2), Sphere (m_particles[i]->GetPosition(), m_particles[i]->GetRadiusX()), outp, outp2)) - { - //Sp_Pos = m_particles[i]->GetPosition(); - //Sp_Rad = m_particles[i]->GetRadiusX()/2; - return true; - } - } - } - } - return false; -} - -/* -//!!! WARNING -extern bool Sp_IsDraw; -extern Matrix34 Sp_Mat; -extern Vec3 Sp_Pos; -extern float Sp_Rad; - - -void C3DEngine::Hack_GetSprite(bool & IsDraw, Matrix34 & Mat, Vec3 & Pos, float & Rad) -{ - IsDraw = Sp_IsDraw; - Mat = Sp_Mat; - Pos = Sp_Pos; - Rad = Sp_Rad; -} -*/ diff --git a/Code/CryEngine/Cry3DEngine/CloudsManager.h b/Code/CryEngine/Cry3DEngine/CloudsManager.h deleted file mode 100644 index 38c5aac911..0000000000 --- a/Code/CryEngine/Cry3DEngine/CloudsManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CLOUDSMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_CLOUDSMANAGER_H -#pragma once - -class CCloudRenderNode; - -typedef std::vector CloudParticles; - -struct SCloudQuadTree -{ - CloudParticles m_particles; - AABB m_bounds; - SCloudQuadTree* m_pQuads[4]; - int m_level; - SCloudQuadTree(int level = 0) - { - m_pQuads[0] = 0; - m_pQuads[1] = 0; - m_pQuads[2] = 0; - m_pQuads[3] = 0; - m_level = level; - } - ~SCloudQuadTree() - { - delete m_pQuads[0]; - delete m_pQuads[1]; - delete m_pQuads[2]; - delete m_pQuads[3]; - m_pQuads[0] = m_pQuads[1] = m_pQuads[2] = m_pQuads[3] = 0; - } - void Init(const AABB& bounds, const CloudParticles& particles, int maxlevel = 2); - bool CheckIntersection(const Vec3& p1, const Vec3& p2); -}; - - -////////////////////////////////////////////////////////////////////////// -// SCloudDescription contains cached representation of the cloud description file. -////////////////////////////////////////////////////////////////////////// -struct SCloudDescription - : public _reference_target_t - , public Cry3DEngineBase -{ - string filename; - int m_textureRows; - int m_textureCols; - int m_numSprites; - - AABB m_bounds; - Vec3 m_offset; - - _smart_ptr m_pMaterial; - std::vector m_particles; - SCloudQuadTree* m_pCloudTree; - - SCloudDescription() - { - m_textureRows = 0; - m_textureCols = 0; - m_numSprites = 0; - m_pCloudTree = 0; - }; - ~SCloudDescription(); -}; - - -////////////////////////////////////////////////////////////////////////// -// CloudsManager is used to manage cloud descriptions loaded from the files. -// When cloud file is once loaded it caches its content and next time the same -// cloud file is request, Clients will get the cached content. -////////////////////////////////////////////////////////////////////////// -class CCloudsManager - : public Cry3DEngineBase -{ -public: - CCloudsManager() {}; - ~CCloudsManager() {}; - - // Loads cloud file and returns cloud description. - // If cloud was already loaded cached instance is returned. - // Reference count of the cloud description is incremented,Client must call Release on returned pointer to free cloud description. - SCloudDescription* LoadCloud(const char* sFilename); - - // Used to parse xml node and create a cloud description from it. - void ParseCloudFromXml(XmlNodeRef node, SCloudDescription* pCloud); - - void AddCloudRenderNode(CCloudRenderNode* pNode); - void RemoveCloudRenderNode(CCloudRenderNode* pNode); - bool CheckIntersectClouds(const Vec3& p1, const Vec3& p2); - void MoveClouds(); - -private: - friend struct SCloudDescription; - void Register(SCloudDescription* desc); - void Unregister(SCloudDescription* desc); - -private: - typedef std::map > CloudsMaps; - - CloudsMaps m_cloudsMap; - std::vector m_cloudNodes; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_CLOUDSMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngine.cpp b/Code/CryEngine/Cry3DEngine/Cry3DEngine.cpp deleted file mode 100644 index 01b5b053c3..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngine.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines the DLL entry point, implements access to other modules - - -#include "Cry3DEngine_precompiled.h" - -#include "MatMan.h" - -#include -#include - -#include "I3DEngine_info.h" - -////////////////////////////////////////////////////////////////////// - -struct CSystemEventListner_3DEngine - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - if (Cry3DEngineBase::Get3DEngine()) - { - Cry3DEngineBase::Get3DEngine()->ClearPrecacheInfo(); - } - break; - case ESYSTEM_EVENT_RANDOM_SEED: - cry_random_seed(gEnv->bNoRandomSeed ? 0 : (uint32)wparam); - break; - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - if (Cry3DEngineBase::Get3DEngine()) - { - Cry3DEngineBase::Get3DEngine()->ClearDebugFPSInfo(true); - } - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - if (Cry3DEngineBase::Get3DEngine()) - { - Cry3DEngineBase::Get3DEngine()->ClearDebugFPSInfo(); - } - if (Cry3DEngineBase::GetObjManager()) - { - Cry3DEngineBase::GetObjManager()->FreeNotUsedCGFs(); - } - Cry3DEngineBase::m_bLevelLoadingInProgress = false; - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_START: - { - Cry3DEngineBase::m_bLevelLoadingInProgress = true; - break; - } - case ESYSTEM_EVENT_LEVEL_UNLOAD: - { - Cry3DEngineBase::m_bLevelLoadingInProgress = true; - break; - } - case ESYSTEM_EVENT_3D_POST_RENDERING_START: - { - Cry3DEngineBase::GetMatMan()->DoLoadSurfaceTypesInInit(false); - break; - } - case ESYSTEM_EVENT_3D_POST_RENDERING_END: - { - if (Cry3DEngineBase::Get3DEngine()->GetObjectTree()) - { - delete Cry3DEngineBase::Get3DEngine()->GetObjectTree(); - Cry3DEngineBase::Get3DEngine()->SetObjectTree(nullptr); - } - - if (IObjManager* pObjManager = Cry3DEngineBase::GetObjManager()) - { - pObjManager->UnloadObjects(true); - } - - - if (Cry3DEngineBase::GetMatMan()) - { - Cry3DEngineBase::GetMatMan()->ShutDown(); - Cry3DEngineBase::GetMatMan()->DoLoadSurfaceTypesInInit(true); - } - - break; - } - } - } -}; -static CSystemEventListner_3DEngine g_system_event_listener_engine; - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -class CEngineModule_Cry3DEngine - : public IEngineModule -{ - CRYINTERFACE_SIMPLE(IEngineModule) - CRYGENERATE_SINGLETONCLASS(CEngineModule_Cry3DEngine, "EngineModule_Cry3DEngine", 0x2d38f12a521d43cf, 0xba18fd1fa7ea5020) - - ////////////////////////////////////////////////////////////////////////// - virtual const char* GetName() const { - return "Cry3DEngine"; - }; - virtual const char* GetCategory() const { return "CryEngine"; }; - - ////////////////////////////////////////////////////////////////////////// - virtual bool Initialize(SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams) - { - ISystem* pSystem = env.pSystem; - - ModuleInitISystem(pSystem, "Cry3DEngine"); - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_engine); - - C3DEngine* p3DEngine = CryAlignedNew(pSystem); - env.p3DEngine = p3DEngine; - return true; - } -}; - -CRYREGISTER_SINGLETON_CLASS(CEngineModule_Cry3DEngine) - -CEngineModule_Cry3DEngine::CEngineModule_Cry3DEngine() -{ -}; - -CEngineModule_Cry3DEngine::~CEngineModule_Cry3DEngine() -{ -}; - -#if !defined(AZ_MONOLITHIC_BUILD) - #include -#endif - -#include "TypeInfo_impl.h" - -// 3DEngine types -#include "SkyLightNishita_info.h" - -STRUCT_INFO_BEGIN(SImageSubInfo) -VAR_INFO(nDummy) -VAR_INFO(nDim) -VAR_INFO(fTilingIn) -VAR_INFO(fTiling) -VAR_INFO(fSpecularAmount) -VAR_INFO(nSortOrder) -STRUCT_INFO_END(SImageSubInfo) - -STRUCT_INFO_BEGIN(SImageInfo) -VAR_INFO(baseInfo) -VAR_INFO(detailInfo) -VAR_INFO(szDetMatName) -VAR_INFO(arrTextureId) -VAR_INFO(nPhysSurfaceType) -VAR_INFO(szBaseTexName) -VAR_INFO(fUseRemeshing) -VAR_INFO(layerFilterColor) -VAR_INFO(nLayerId) -VAR_INFO(fBr) -STRUCT_INFO_END(SImageInfo) diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngine.rc b/Code/CryEngine/Cry3DEngine/Cry3DEngine.rc deleted file mode 100644 index 5730d0a537..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngine.rc +++ /dev/null @@ -1,111 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Russian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.cpp b/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.cpp deleted file mode 100644 index 9ff585b716..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.cpp +++ /dev/null @@ -1,237 +0,0 @@ - -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "Cry3DEngine_precompiled.h" -#include - -#define MAX_ERROR_STRING MAX_WARNING_LENGTH - -////////////////////////////////////////////////////////////////////////// -void Cry3DEngineBase::PrintComment(const char* szText, ...) -{ - if (!szText) - { - return; - } - - va_list args; - va_start(args, szText); - GetLog()->LogV(IMiniLog::eComment, szText, args); - va_end(args); -} - -void Cry3DEngineBase::PrintMessage(const char* szText, ...) -{ - if (!szText) - { - return; - } - - va_list args; - va_start(args, szText); - GetLog()->LogV(GetCVars()->e_3dEngineLogAlways ? IMiniLog::eAlways : IMiniLog::eMessage, szText, args); - va_end(args); - - GetLog()->UpdateLoadingScreen(0); -} - -void Cry3DEngineBase::PrintMessagePlus(const char* szText, ...) -{ - if (!szText) - { - return; - } - - va_list arglist; - char buf[MAX_ERROR_STRING]; - va_start(arglist, szText); - int count = azvsnprintf(buf, sizeof(buf), szText, arglist); - if (count == -1 || count >= sizeof(buf)) - { - buf[sizeof(buf) - 1] = '\0'; - } - va_end(arglist); - GetLog()->LogPlus(buf); - - GetLog()->UpdateLoadingScreen(0); -} - -float Cry3DEngineBase::GetCurTimeSec() -{ - return (gEnv->pTimer->GetCurrTime()); -} - -float Cry3DEngineBase::GetCurAsyncTimeSec() -{ - return (gEnv->pTimer->GetAsyncTime().GetSeconds()); -} - -////////////////////////////////////////////////////////////////////////// -void Cry3DEngineBase::Warning(const char* format, ...) -{ - if (!format) - { - return; - } - - va_list args; - va_start(args, format); - // Call to validating warning of system. - m_pSystem->WarningV(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, 0, 0, format, args); - va_end(args); - - GetLog()->UpdateLoadingScreen(0); -} - -////////////////////////////////////////////////////////////////////////// -void Cry3DEngineBase::Error(const char* format, ...) -{ - // assert(!"Cry3DEngineBase::Error"); - if (format) - { - va_list args; - va_start(args, format); - // Call to validating warning of system. - m_pSystem->WarningV(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, 0, 0, format, args); - va_end(args); - } - - GetLog()->UpdateLoadingScreen(0); -} - -////////////////////////////////////////////////////////////////////////// -void Cry3DEngineBase::FileWarning(int flags, const char* file, const char* format, ...) -{ - if (format) - { - va_list args; - va_start(args, format); - // Call to validating warning of system. - m_pSystem->WarningV(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, flags | VALIDATOR_FLAG_FILE, file, format, args); - va_end(args); - } - - GetLog()->UpdateLoadingScreen(0); -} - -_smart_ptr Cry3DEngineBase::MakeSystemMaterialFromShader(const char* sShaderName, SInputShaderResources* Res) -{ - _smart_ptr pMat = Get3DEngine()->GetMaterialManager()->CreateMaterial(sShaderName); - //pMat->AddRef(); - SShaderItem si; - - si = GetRenderer()->EF_LoadShaderItem(sShaderName, true, 0, Res); - - pMat->AssignShaderItem(si); - return pMat; -} - -////////////////////////////////////////////////////////////////////////// -bool Cry3DEngineBase::IsValidFile(const char* sFilename) -{ - LOADING_TIME_PROFILE_SECTION; - - return gEnv->pCryPak->IsFileExist(sFilename); -} - -////////////////////////////////////////////////////////////////////////// -bool Cry3DEngineBase::IsResourceLocked(const char* sFilename) -{ - auto pResList = GetPak()->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel); - if (pResList) - { - return pResList->IsExist(sFilename); - } - return false; -} - -void Cry3DEngineBase::DrawBBoxLabeled(const AABB& aabb, const Matrix34& m34, const ColorB& col, const char* format, ...) -{ - va_list args; - va_start(args, format); - char szText[256]; - vsnprintf_s(szText, sizeof(szText), sizeof(szText) - 1, format, args); - float fColor[4] = { col[0] / 255.f, col[1] / 255.f, col[2] / 255.f, col[3] / 255.f }; - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->DrawLabelEx(m34.TransformPoint(aabb.GetCenter()), 1.3f, fColor, true, true, szText); - GetRenderer()->GetIRenderAuxGeom()->DrawAABB(aabb, m34, false, col, eBBD_Faceted); - va_end(args); -} - -////////////////////////////////////////////////////////////////////////// -void Cry3DEngineBase::DrawBBox(const Vec3& vMin, const Vec3& vMax, ColorB col) -{ - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->GetIRenderAuxGeom()->DrawAABB(AABB(vMin, vMax), false, col, eBBD_Faceted); -} - -void Cry3DEngineBase::DrawBBox(const AABB& box, ColorB col) -{ - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->GetIRenderAuxGeom()->DrawAABB(box, false, col, eBBD_Faceted); -} - -void Cry3DEngineBase::DrawLine(const Vec3& vMin, const Vec3& vMax, ColorB col) -{ - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vMin, col, vMax, col); -} - -void Cry3DEngineBase::DrawSphere(const Vec3& vPos, float fRadius, ColorB color) -{ - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->GetIRenderAuxGeom()->DrawSphere(vPos, fRadius, color); -} - -void Cry3DEngineBase::DrawQuad(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, ColorB color) -{ - GetRenderer()->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - GetRenderer()->GetIRenderAuxGeom()->DrawTriangle(v0, color, v2, color, v3, color); - GetRenderer()->GetIRenderAuxGeom()->DrawTriangle(v0, color, v1, color, v2, color); -} - -// Check if preloading is enabled. -bool Cry3DEngineBase::IsPreloadEnabled() -{ - bool bPreload = false; - ICVar* pSysPreload = GetConsole()->GetCVar("sys_preload"); - if (pSysPreload && pSysPreload->GetIVal() != 0) - { - bPreload = true; - } - - return bPreload; -} - -////////////////////////////////////////////////////////////////////////// -bool Cry3DEngineBase::CheckMinSpec(uint32 nMinSpec) -{ - if ((int)nMinSpec != 0 && GetCVars()->e_ObjQuality != 0 && (int)nMinSpec > GetCVars()->e_ObjQuality) - { - return false; - } - - return true; -} - -bool Cry3DEngineBase::IsEscapePressed() -{ -#ifdef WIN32 - if (Cry3DEngineBase::m_bEditor && (CryGetAsyncKeyState(0x03) & 1)) // Ctrl+Break - { - Get3DEngine()->PrintMessage("*** Ctrl-Break was pressed - operation aborted ***"); - return true; - } -#endif - return false; -} diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.h b/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.h deleted file mode 100644 index 9ce248f642..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngineBase.h +++ /dev/null @@ -1,202 +0,0 @@ - -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Access to external stuff used by 3d engine. Most 3d engine classes -// are derived from this base class to access other interfaces - - -#ifndef CRYINCLUDE_CRY3DENGINE_CRY3DENGINEBASE_H -#define CRYINCLUDE_CRY3DENGINE_CRY3DENGINEBASE_H -#pragma once - -#include "3DEngineMemory.h" - -struct ISystem; -struct IRenderer; -struct ILog; -struct ITimer; -struct IConsole; -struct I3DEngine; -struct IObjManager; -struct CVars; -struct CVisAreaManager; - -class COcean; -class C3DEngine; -class CParticleManager; -class CDecalManager; -class CRainManager; -class CCloudsManager; -class CSkyLightManager; -class CRenderMeshMerger; -class CMergedMeshesManager; -class CGeomCacheManager; -class CBreezeGenerator; -class CMatMan; -class CClipVolumeManager; - -namespace AZ::IO -{ - struct IArchive; -} - -#define DISTANCE_TO_THE_SUN 1000000 - -#if !defined(_RELEASE) -#define OBJMAN_STREAM_STATS -#endif - -struct Cry3DEngineBase -{ - static ISystem* m_pSystem; - static IRenderer* m_pRenderer; - static ITimer* m_pTimer; - static ILog* m_pLog; - static ::IConsole* m_pConsole; - static C3DEngine* m_p3DEngine; - static CVars* m_pCVars; - static AZ::IO::IArchive* m_pCryPak; - static CObjManager* m_pObjManager; - static COcean* m_pOcean; - static IOpticsManager* m_pOpticsManager; - static CDecalManager* m_pDecalManager; - static CCloudsManager* m_pCloudsManager; - static CVisAreaManager* m_pVisAreaManager; - static CClipVolumeManager* m_pClipVolumeManager; - static CMatMan* m_pMatMan; - static CSkyLightManager* m_pSkyLightManager; - static CRenderMeshMerger* m_pRenderMeshMerger; - static IStreamedObjectListener* m_pStreamListener; -#if defined(USE_GEOM_CACHES) - static CGeomCacheManager* m_pGeomCacheManager; -#endif - - static float m_fInvDissolveDistBand; - static threadID m_nMainThreadId; - static bool m_bLevelLoadingInProgress; - static bool m_bIsInRenderScene; - static bool m_bAsyncOctreeUpdates; - static bool m_bRenderTypeEnabled[eERType_TypesNum]; - - static int m_CpuFlags; - static ESystemConfigSpec m_LightConfigSpec; -#if defined(CONSOLE) - static const bool m_bEditor = false; -#else - static bool m_bEditor; -#endif - static int m_arrInstancesCounter[eERType_TypesNum]; - - // components access - ILINE static ISystem* GetSystem() { return m_pSystem; } - ILINE static IRenderer* GetRenderer() { return m_pRenderer; } - ILINE static ITimer* GetTimer() { return m_pTimer; } - ILINE static ILog* GetLog() { return m_pLog; } - - inline static ::IConsole* GetConsole() { return m_pConsole; } - inline static C3DEngine* Get3DEngine() { return m_p3DEngine; } - inline static CObjManager* GetObjManager() { return m_pObjManager; }; - - inline static COcean* GetOcean() { return m_pOcean; }; - inline static CVars* GetCVars() { return m_pCVars; } - inline static CVisAreaManager* GetVisAreaManager() { return m_pVisAreaManager; } - inline static AZ::IO::IArchive* GetPak() { return m_pCryPak; } - inline static CMatMan* GetMatMan() { return m_pMatMan; } - inline static CCloudsManager* GetCloudsManager() { return m_pCloudsManager; } - inline static CRenderMeshMerger* GetSharedRenderMeshMerger() { return m_pRenderMeshMerger; }; - inline static CTemporaryPool* GetTemporaryPool() { return CTemporaryPool::Get(); }; - -#if defined(USE_GEOM_CACHES) - inline static CGeomCacheManager* GetGeomCacheManager() { return m_pGeomCacheManager; }; -#endif - - ILINE static bool IsRenderNodeTypeEnabled(EERType rnType) { return m_bRenderTypeEnabled[(int)rnType]; } - ILINE static void SetRenderNodeTypeEnabled(EERType rnType, bool bEnabled) {m_bRenderTypeEnabled[(int)rnType] = bEnabled; } - - inline static int GetDefSID() { return DEFAULT_SID; }; - - float GetCurTimeSec(); - float GetCurAsyncTimeSec(); - - static void PrintMessage(const char* szText, ...) PRINTF_PARAMS(1, 2); - static void PrintMessagePlus(const char* szText, ...) PRINTF_PARAMS(1, 2); - static void PrintComment(const char* szText, ...) PRINTF_PARAMS(1, 2); - - // Validator warning. - static void Warning(const char* format, ...) PRINTF_PARAMS(1, 2); - static void Error(const char* format, ...) PRINTF_PARAMS(1, 2); - static void FileWarning(int flags, const char* file, const char* format, ...) - PRINTF_PARAMS(3, 4); - - CRenderObject* GetIdentityCRenderObject(int nThreadID) - { - CRenderObject* pCRenderObject = GetRenderer()->EF_GetObject_Temp(nThreadID); - if (!pCRenderObject) - { - return NULL; - } - pCRenderObject->m_II.m_Matrix.SetIdentity(); - return pCRenderObject; - } - - static bool IsValidFile(const char* sFilename); - static bool IsResourceLocked(const char* sFilename); - - static bool IsPreloadEnabled(); - - _smart_ptr MakeSystemMaterialFromShader(const char* sShaderName, SInputShaderResources* Res = NULL); - void DrawBBoxLabeled(const AABB& aabb, const Matrix34& m34, const ColorB& col, const char* format, ...) PRINTF_PARAMS(5, 6); - void DrawBBox(const Vec3& vMin, const Vec3& vMax, ColorB col = Col_White); - void DrawBBox(const AABB& box, ColorB col = Col_White); - void DrawLine(const Vec3& vMin, const Vec3& vMax, ColorB col = Col_White); - void DrawSphere(const Vec3& vPos, float fRadius, ColorB color = ColorB(255, 255, 255, 255)); - void DrawQuad(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, ColorB color); - - int& GetInstCount(EERType eType) { return m_arrInstancesCounter[eType]; } - - uint32 GetMinSpecFromRenderNodeFlags(uint32 dwRndFlags) const { return (dwRndFlags & ERF_SPEC_BITS_MASK) >> ERF_SPEC_BITS_SHIFT; } - static bool CheckMinSpec(uint32 nMinSpec); - - static bool IsEscapePressed(); - - size_t fread( - void* buffer, - size_t elementSize, - size_t count, - FILE* stream) - { - size_t res = ::fread(buffer, elementSize, count, stream); - if (res != count) - { - Error("fread() failed"); - } - return res; - } - - int fseek ( - FILE* stream, - long offset, - int whence - ) - { - int res = ::fseek(stream, offset, whence); - if (res != 0) - { - Error("fseek() failed"); - } - return res; - } -}; - -#endif // CRYINCLUDE_CRY3DENGINE_CRY3DENGINEBASE_H diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngineTraits.h b/Code/CryEngine/Cry3DEngine/Cry3DEngineTraits.h deleted file mode 100644 index ed7563b572..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngineTraits.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include "ProjectDefines.h" - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(Cry3DEngineTraits_h) -#else -#if defined(WIN32) || defined(WIN64) -#define AZ_LEGACY_3DENGINE_TRAIT_DEFINE_MM_MULLO_EPI32_EMU 1 -#endif -#if defined(WIN32) || defined(WIN64) -#define AZ_LEGACY_3DENGINE_TRAIT_DO_EXTRA_GEOMCACHE_PROCESSING 1 // probably needs a better name -#endif -#define AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_CVTEPI16_EPI32 0 -#define AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_MULLO_EPI32 0 -#define AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_PACKUS_EPI32 0 -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(MAC) -#define AZ_LEGACY_3DENGINE_TRAIT_HAS_SSE 1 -#endif -#define AZ_LEGACY_3DENGINE_TRAIT_UNROLL_GEOMETRY_BACKING_LOOPS 1 -#if defined(APPLE) || defined(LINUX) -#define AZ_LEGACY_3DENGINE_TRAIT_DISABLE_MMRM_SSE_INSTRUCTIONS 1 -#endif -#endif diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.cpp b/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.cpp deleted file mode 100644 index f238d8963e..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" diff --git a/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.h b/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.h deleted file mode 100644 index 42226bb513..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry3DEngine_precompiled.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -const int nThreadsNum = 3; - -#include - -#include -//#define DEFINE_MODULE_NAME "Cry3DEngine" -//#define FORCE_STANDARD_ASSERT // fix edit and continue - -#if defined(WIN64) -#define CRY_INTEGRATE_DX12 -#endif - -////////////////////////////////////////////////////////////////////////////////////////////// -// Highlevel defines - -// deferred cull queue handling - currently disabled -// #define USE_CULL_QUEUE - -// Compilation (Export to Engine) not needed on consoles -#if defined(CONSOLE) -# define ENGINE_ENABLE_COMPILATION 0 -#else -# define ENGINE_ENABLE_COMPILATION 1 -#endif - -#include -#include -#include - -#define MAX_PATH_LENGTH 512 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Cry3DEngineBase.h" -#include -#include "CryArray.h" -#include "cvars.h" -#include -#include -#include -#include "Material.h" -#include "3dEngine.h" -#include "ObjMan.h" - -#include -#include "BasicArea.h" -#include "Environment/OceanEnvironmentBus.h" - -#include "ObjectsTree.h" - -inline int snprintf(char* buf, int size, const char* format, ...) -{ - va_list arglist; - va_start(arglist, format); - int res = azvsnprintf(buf, size, format, arglist); - va_end(arglist); - return res; -} - -template -void AddToPtr(byte*& pPtr, T& rObj, EEndian eEndian) -{ - PREFAST_SUPPRESS_WARNING(6326) COMPILE_TIME_ASSERT(((sizeof(T) % 4) == 0)); - assert(!((INT_PTR)pPtr & 3)); - memcpy(pPtr, &rObj, sizeof(rObj)); - SwapEndian(*(T*)pPtr, eEndian); - pPtr += sizeof(rObj); - assert(!((INT_PTR)pPtr & 3)); -} - -template -void AddToPtr(byte*& pPtr, int& nDataSize, T& rObj, EEndian eEndian) -{ - PREFAST_SUPPRESS_WARNING(6326) COMPILE_TIME_ASSERT(((sizeof(T) % 4) == 0)); - assert(!((INT_PTR)pPtr & 3)); - memcpy(pPtr, &rObj, sizeof(rObj)); - SwapEndian(*(T*)pPtr, eEndian); - pPtr += sizeof(rObj); - nDataSize -= sizeof(rObj); - assert(nDataSize >= 0); - assert(!((INT_PTR)pPtr & 3)); -} - - -inline void FixAlignment(byte*& pPtr, int& nDataSize) -{ - while ((UINT_PTR)pPtr & 3) - { - *pPtr = 222; - pPtr++; - nDataSize--; - } -} - -inline void FixAlignment(byte*& pPtr) -{ - while ((UINT_PTR)pPtr & 3) - { - *pPtr = 222; - pPtr++; - } -} - -template -void AddToPtr(byte*& pPtr, int& nDataSize, const T* pArray, int nElemNum, EEndian eEndian, bool bFixAlignment = false) -{ - assert(!((INT_PTR)pPtr & 3)); - memcpy(pPtr, pArray, nElemNum * sizeof(T)); - SwapEndian((T*)pPtr, nElemNum, eEndian); - pPtr += nElemNum * sizeof(T); - nDataSize -= nElemNum * sizeof(T); - assert(nDataSize >= 0); - - if (bFixAlignment) - { - FixAlignment(pPtr, nDataSize); - } - else - { - assert(!((INT_PTR)pPtr & 3)); - } -} - -template -void AddToPtr(byte*& pPtr, const T* pArray, int nElemNum, EEndian eEndian, bool bFixAlignment = false) -{ - assert(!((INT_PTR)pPtr & 3)); - memcpy(pPtr, pArray, nElemNum * sizeof(T)); - SwapEndian((T*)pPtr, nElemNum, eEndian); - pPtr += nElemNum * sizeof(T); - - if (bFixAlignment) - { - FixAlignment(pPtr); - } - else - { - assert(!((INT_PTR)pPtr & 3)); - } -} - -struct TriangleIndex -{ - TriangleIndex() { ZeroStruct(*this); } - uint16& operator [] (const int& n) { assert(n >= 0 && n < 3); return idx[n]; } - const uint16& operator [] (const int& n) const { assert(n >= 0 && n < 3); return idx[n]; } - uint16 idx[3]; - uint16 nCull; -}; - - #define FUNCTION_PROFILER_3DENGINE FUNCTION_PROFILER(gEnv->pSystem, PROFILE_3DENGINE) - #define FUNCTION_PROFILER_3DENGINE_LEGACYONLY FUNCTION_PROFILER_LEGACYONLY(gEnv->pSystem, PROFILE_3DENGINE) - - diff --git a/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.cpp b/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.cpp deleted file mode 100644 index 7a85244397..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.cpp +++ /dev/null @@ -1,990 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -namespace LegacyCryPhysicsUtils -{ - namespace qhull_IMPL - { - static int __qhullcalled = 0; - - int qhull(strided_pointer _pts, int npts, index_t*& pTris, qhullmalloc qmalloc) - { -#if defined(PLATFORM_64BIT) - static ptitem ptbuf[4096]; - static qhtritem trbuf[4096]; - static qhtritem* tmparr_ptr_buf[2048]; - static int tmparr_idx_buf[2048]; -#else - static ptitem ptbuf[1024]; - static qhtritem trbuf[1024]; - static qhtritem* tmparr_ptr_buf[512]; - static int tmparr_idx_buf[512]; -#endif - static volatile int g_lockQhull; - int iter = 0, maxiter = 0; - __qhullcalled++; - strided_pointer pts = strided_pointer((Vec3mem*)_pts.data, _pts.iStride); - - ptitem* pt, * ptmax, * ptdeleted, * ptlist = npts > sizeof(ptbuf) / sizeof(ptbuf[0]) ? new ptitem[npts] : ptbuf; - qhtritem* tr, * trnext, * trend, * trnew, * trdata = trbuf, * trstart = 0, * trlast, * trbest = nullptr; - int i, j, k, ti, trdatasz = sizeof(trbuf) / sizeof(trbuf[0]), bidx[6], n, next_iter, delbuds; - qhtritem** tmparr_ptr = tmparr_ptr_buf; - int* tmparr_idx = tmparr_idx_buf, tmparr_sz = 512; - float dist, maxdist /*,e*/; - Vec3 pmin(VMAX), pmax(VMIN); - WriteLock lock(g_lockQhull); - - // select points for initial tetrahedron - // first, find 6 points corresponding to min and max coordinates - for (i = 1; i < npts; i++) - { - if (pts[i].x > pmax.x) - { - pmax.x = pts[i].x; - bidx[0] = i; - } - if (pts[i].x < pmin.x) - { - pmin.x = pts[i].x; - bidx[1] = i; - } - if (pts[i].y > pmax.y) - { - pmax.y = pts[i].y; - bidx[2] = i; - } - if (pts[i].y < pmin.y) - { - pmin.y = pts[i].y; - bidx[3] = i; - } - if (pts[i].z > pmax.z) - { - pmax.z = pts[i].z; - bidx[4] = i; - } - if (pts[i].z < pmin.z) - { - pmin.z = pts[i].z; - bidx[5] = i; - } - } - // e = max(max(pmax.x-pmin.x,pmax.y-pmin.y),pmax.z-pmin.z)*0.01f; - - for (bidx[0] = 0, i = 1; i < npts; i++) - { - bidx[0] += i - bidx[0] & -isneg(pts[i].x - pts[bidx[0]].x); - } - for (bidx[1] = 0, i = 1; i < npts; i++) - { - bidx[1] += i - bidx[1] & -isneg((pts[bidx[1]] - pts[bidx[0]]).len2() - (pts[i] - pts[bidx[0]]).len2()); - } - Vec3 norm = pts[bidx[1]] - pts[bidx[0]]; - for (bidx[2] = 0, i = 1; i < npts; i++) - { - bidx[2] += i - bidx[2] & -isneg((norm ^ pts[bidx[2]] - pts[bidx[0]]).len2() - (norm ^ pts[i] - pts[bidx[0]]).len2()); - } - norm = pts[bidx[1]] - pts[bidx[0]] ^ pts[bidx[2]] - pts[bidx[0]]; - for (bidx[3] = 0, i = 1; i < npts; i++) - { - bidx[3] += i - bidx[3] & -isneg(fabs_tpl((pts[bidx[3]] - pts[bidx[0]]) * norm) - fabs_tpl((pts[i] - pts[bidx[0]]) * norm)); - } - if ((pts[bidx[3]] - pts[bidx[0]]) * norm > 0) - { - i = bidx[1]; - bidx[1] = bidx[2]; - bidx[2] = i; - } - - // build a double linked list from all points - for (i = 0; i < npts; i++) - { - ptlist[i].prev = ptlist + i - 1; - ptlist[i].next = ptlist + i + 1; - } - ptlist[0].prev = ptlist + npts - 1; - ptlist[npts - 1].next = ptlist; - // remove selected points from the list - for (i = 0; i < 4; i++) - { - delete_item_from_list(ptlist + bidx[i]); - } - // assign 3 points to each of 4 initial triangles - for (i = 0; i < 4; i++) - { - for (j = k = 0; j < 4; j++) - { - if (j != i) - { - trbuf[i].idx[k++] = bidx[j]; // skip i.th point in i.th triangle - } - } - trbuf[i].n = pts[trbuf[i].idx[1]] - pts[trbuf[i].idx[0]] ^ pts[trbuf[i].idx[2]] - pts[trbuf[i].idx[0]]; - trbuf[i].pt0 = pts[trbuf[i].idx[0]]; - if (e_cansee(pts[bidx[i]] - trbuf[i].pt0, trbuf[i].n, 0)) // flip the orientation so that ccw normal points outwards - { - ti = trbuf[i].idx[0]; - trbuf[i].idx[0] = trbuf[i].idx[2]; - trbuf[i].idx[2] = ti; - trbuf[i].n = -trbuf[i].n; - } - trbuf[i].ptassoc = 0; - trbuf[i].deleted = 0; - add_item_to_list(trstart, trbuf + i); - } - // fill buddy links for each triangle - for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) - { - if (j != i) - { - for (k = 0; k < 3; k++) - { - for (ti = 0; ti < 3; ti++) - { - if (trbuf[i].idx[k] == trbuf[j].idx[ti] && trbuf[i].idx[k == 2 ? 0 : k + 1] == trbuf[j].idx[ti == 0 ? 2 : ti - 1]) - { - trbuf[i].buddy[k] = trbuf + j; - break; - } - } - } - } - } - } - trend = trstart + 4; - for (i = 0; i < 4; i++) - { - if (trbuf[i].n.len2() < 1E-6f) - { -#ifdef _DEBUG - //OutputDebugString("WARNING: convex hull not computed because of degenerate initial triangles\n"); -#endif - n = 0; - goto endqhull; // some degenerate case, don't party with it - } - } - // associate points with one of the initial triangles - for (i = 0; i < npts; i++) - { - if (ptlist[i].next) - { - break; - } - } - associate_ptlist_with_trilist(ptlist + i, trstart, ptlist, pts); - -#define DELETE_TRI(ptri) { \ - merge_lists(ptdeleted, (ptri)->ptassoc); \ - if ((ptri) == trstart) {trstart = (ptri)->next; } \ - if ((ptri) == trnext) {trnext = (ptri)->next; } \ - delete_item_from_list(ptri); (ptri)->deleted = 1; } - - - // main loop - iter = 0; - maxiter = npts * npts * 2; - ptmax = trstart->ptassoc; - tr = trstart; - do - { - trnext = tr->next; - pt = tr->ptassoc; - if (pt) - { - // find the fartherst of the associated with the triangle points - maxdist = -1E37f; - do - { - if ((dist = pts[(int)(pt - ptlist)] * tr->n) > maxdist) - { - maxdist = dist; - ptmax = pt; - } - pt = pt->next; - } while (pt != tr->ptassoc); - ptdeleted = 0; - if (tr->ptassoc == ptmax) - { - tr->ptassoc = ptmax->next; - } - delete_item_from_list(ptmax); - if (tr->ptassoc == ptmax) - { - tr->ptassoc = 0; - } - - // find the triangle that the point can see "most confidently" - tr = trstart; - trlast = tr->prev; - ti = static_cast(ptmax - ptlist); - maxdist = -1E37f; - do - { - trnext = tr->next; - if ((pts[ti] - tr->pt0) * tr->n > maxdist) - { - maxdist = (pts[ti] - tr->pt0) * tr->n; - trbest = tr; - } - if (tr == trlast) - { - break; - } - tr = trnext; - } while (true); - - // "flood fill" triangles that the point can see around that one - DELETE_TRI(trbest) - tr = trbest->next = trbest->prev = trbest; - do - { - if (tr->buddy[0] && !tr->buddy[0]->deleted && e_cansee(pts[ti] - tr->buddy[0]->pt0, tr->buddy[0]->n, 0)) - { - DELETE_TRI(tr->buddy[0]) - add_item_to_list(tr, tr->buddy[0]); - } - if (tr->buddy[1] && !tr->buddy[1]->deleted && e_cansee(pts[ti] - tr->buddy[1]->pt0, tr->buddy[1]->n, 0)) - { - DELETE_TRI(tr->buddy[1]) - add_item_to_list(tr, tr->buddy[1]); - } - if (tr->buddy[2] && !tr->buddy[2]->deleted && e_cansee(pts[ti] - tr->buddy[2]->pt0, tr->buddy[2]->n, 0)) - { - DELETE_TRI(tr->buddy[2]) - add_item_to_list(tr, tr->buddy[2]); - } - tr = tr->next; - } while (tr != trbest); - - // delete near-visible triangles around deleted area edges to preserve hole convexity - // do as many iterations as needed - do - { - tr = trstart; - trlast = tr->prev; - next_iter = 0; - do - { - trnext = tr->next; - if (e_cansee(pts[ti] - tr->pt0, tr->n, -0.001f)) - { - delbuds = tr->buddy[0]->deleted + tr->buddy[1]->deleted + tr->buddy[2]->deleted; - if (delbuds >= 2) // delete triangles that have 2+ buddies deleted - { - if (tr == trlast) - { - trlast = tr->next; - } - DELETE_TRI(tr); - next_iter = 1; - } - else if (delbuds == 1) // follow triangle fan around both shared edge ends - { - int bi, bi0, bi1, nfantris, fandir; - qhtritem* fantris[64], * tr1; - - for (bi0 = 0; bi0 < 3 && !tr->buddy[bi0]->deleted; bi0++) - { - ; // bi0 - deleted buddy index - } - for (fandir = -1; fandir <= 1; fandir += 2) // follow fans in 2 possible directions - { - tr1 = tr; - bi1 = bi0; - nfantris = 0; - do - { - if (nfantris == 64) - { - break; - } - bi = bi1 + fandir; - if (bi > 2) - { - bi -= 3; - } - if (bi < 0) - { - bi += 3; - } - for (bi1 = 0; bi1 < 3 && tr1->buddy[bi]->buddy[bi1] != tr1; bi1++) - { - ; - } - fantris[nfantris++] = tr1; // store this triangle in a temporary fan list - tr1 = tr1->buddy[bi]; - bi = bi1; // go to the next fan triangle - if (!e_cansee(pts[ti] - tr1->pt0, tr1->n, -0.002f)) - { - break; // discard this fan - } - if (tr1->deleted) - { - if (tr1 != tr->buddy[bi0]) - { - // delete fan only if it ended on _another_ deleted triangle - for (--nfantris; nfantris >= 0; nfantris--) - { - if (fantris[nfantris] == trlast) - { - trlast = fantris[nfantris]->next; - } - DELETE_TRI(fantris[nfantris]) - } - next_iter = 1; - } - break; // fan end - } - } while (true); - } - } - } - if (tr == trlast) - { - break; - } - tr = trnext; - } while (tr); - } while (next_iter && trstart); - - if (!trstart || trstart->deleted) - { - n = 0; - goto endqhull; - } - - // find triangles that shared an edge with deleted triangles - trnew = 0; - tr = trstart; - do - { - for (i = 0; i < 3; i++) - { - if (tr->buddy[i]->deleted) - { - // create a new triangle - if (trend >= trdata + trdatasz) - { - qhtritem* trdata_new = new qhtritem[trdatasz += 256]; - memcpy(trdata_new, trdata, (trend - trdata) * sizeof(qhtritem)); - intptr_t diff = (intptr_t)trdata_new - (intptr_t)trdata; - for (n = 0; n < trdatasz - 256; n++) - { - relocate_tritem(trdata_new + n, diff); - } - relocate_ptritem(trend, diff); - relocate_ptritem(trstart, diff); - relocate_ptritem(trnext, diff); - relocate_ptritem(tr, diff); - relocate_ptritem(trbest, diff); - relocate_ptritem(trnew, diff); - if (trdata != trbuf) - { - delete[] trdata; - } - trdata = trdata_new; - } - trend->idx[0] = static_cast(ptmax - ptlist); - trend->idx[1] = tr->idx[i == 2 ? 0 : i + 1]; - trend->idx[2] = tr->idx[i]; - trend->ptassoc = 0; - trend->deleted = 0; - trend->n = pts[trend->idx[1]] - pts[trend->idx[0]] ^ pts[trend->idx[2]] - pts[trend->idx[0]]; - trend->pt0 = pts[trend->idx[0]]; - trend->buddy[1] = tr; - tr->buddy[i] = trend; - trend->buddy[0] = trend->buddy[2] = 0; - add_item_to_list(trnew, trend++); - } - } - tr = tr->next; - } while (tr != trstart); - - // sort pointers to the new triangles by their 2nd vertex index - n = static_cast(trend - trnew); - if (tmparr_sz < n) - { - if (tmparr_idx != tmparr_idx_buf) - { - delete[] tmparr_idx; - } - if (tmparr_ptr != tmparr_ptr_buf) - { - delete[] tmparr_ptr; - } - tmparr_idx = new int[n]; - tmparr_ptr = new qhtritem * [n]; - } - for (tr = trnew, i = 0; tr < trend; tr++, i++) - { - tmparr_idx[i] = tr->idx[2]; - tmparr_ptr[i] = tr; - } - qsort(tmparr_idx, (void**)tmparr_ptr, 0, static_cast(trend - trnew - 1)); - - // find 0th buddy for each new triangle (i.e. the triangle, which has its idx[2]==tr->idx[1] - for (tr = trnew; tr < trend; tr++) - { - i = bin_search(tmparr_idx, n, tr->idx[1]); - tr->buddy[0] = tmparr_ptr[i]; - tmparr_ptr[i]->buddy[2] = tr; - } - for (tr = trnew; tr < trend; tr++) - { - if (!tr->buddy[0] || !tr->buddy[2]) - { - goto endqh; - } - } - - // assign all points from the deleted triangles to the new triangles - associate_ptlist_with_trilist(ptdeleted, trnew, ptlist, pts); - // add new triangles to the list - merge_lists(trnext, trnew); - } - else if (trnext == trstart) - { - break; // all triangles in queue have no associated vertices - } - tr = trnext; - } while (++iter < maxiter); - - endqh: - - // build the final triangle list - for (tr = trstart, n = 1; tr->next != trstart; tr = tr->next, n++) - { - ; - } - if (!pTris) - { - pTris = !qmalloc ? new index_t[n * 3] : (index_t*)qmalloc(sizeof(index_t) * n * 3); - } - i = 0; - tr = trstart; - do - { - pTris[i] = tr->idx[0]; - pTris[i + 1] = tr->idx[1]; - pTris[i + 2] = tr->idx[2]; - tr = tr->next; - i += 3; - } while (tr != trstart); - - endqhull: - if (ptlist != ptbuf) - { - delete[] ptlist; - } - if (tmparr_idx != tmparr_idx_buf) - { - delete[] tmparr_idx; - } - if (tmparr_ptr != tmparr_ptr_buf) - { - delete[] tmparr_ptr; - } - if (trdata != trbuf) - { - delete[] trdata; - } - - return n; - } -#undef DELETE_TRI - - void associate_ptlist_with_trilist(ptitem* ptlist, qhtritem* trilist, ptitem* pt0, strided_pointer pvtx) - { - if (!ptlist) - { - return; - } - ptitem* pt = ptlist, * ptnext, * ptlast = ptlist->prev; - qhtritem* tr; - int i; - do - { - ptnext = pt->next; - delete_item_from_list(pt); - tr = trilist; - i = static_cast(pt - pt0); - do - { - if (e_cansee(pvtx[i] - tr->pt0, tr->n)) - { - add_item_to_list(tr->ptassoc, pt); - break; - } - tr = tr->next; - } while (tr != trilist); - if (pt == ptlast) - { - break; - } - pt = ptnext; - } while (true); - } - - void qsort(int* v, void** p, int left, int right) - { - if (left >= right) - { - return; - } - int i, last; - swap(v, p, left, (left + right) >> 1); - for (last = left, i = left + 1; i <= right; i++) - { - if (v[i] < v[left]) - { - swap(v, p, ++last, i); - } - } - swap(v, p, left, last); - - qsort(v, p, left, last - 1); - qsort(v, p, last + 1, right); - } - - int bin_search(int* v, int n, int idx) - { - int left = 0, right = n, m; - do - { - m = (left + right) >> 1; - if (v[m] == idx) - { - return m; - } - if (v[m] < idx) - { - left = m; - } - else - { - right = m; - } - } while (left < right - 1); - return left; - } - } - - int qhull(strided_pointer _pts, int npts, index_t*& pTris, qhullmalloc qmalloc) - { - return qhull_IMPL::qhull(_pts, npts, pTris, qmalloc); - } - - int TriangulatePoly(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf) - { - return TriangulatePoly_IMPL::TriangulatePoly(pVtx, nVtx, pTris, szTriBuf); - } - - namespace TriangulatePoly_IMPL - { - int TriangulatePolyBruteforce(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf) - { - int i, nThunks, nNonEars, nTris = 0; - vtxthunk* ptr, * ptr0, bufThunks[32], * pThunks = nVtx <= 31 ? bufThunks : new vtxthunk[nVtx + 1]; - - ptr = ptr0 = pThunks; - for (i = nThunks = 0; i < nVtx; i++) - { - if (!is_unused(pVtx[i].x)) - { - pThunks[nThunks].next[0] = pThunks + nThunks - 1; - pThunks[nThunks].next[1] = pThunks + nThunks + 1; - pThunks[nThunks].pt = pVtx + i; - ptr = pThunks + nThunks++; - } - } - if (nThunks < 3) - { - return 0; - } - ptr->next[1] = ptr0; - ptr0->next[0] = ptr; - for (i = 0; i < nThunks; i++) - { - pThunks[i].bProcessed = (*pThunks[i].next[1]->pt - *pThunks[i].pt ^ *pThunks[i].next[0]->pt - *pThunks[i].pt) > 0; - } - - for (nNonEars = 0; nNonEars < nThunks && nTris < szTriBuf; ptr0 = ptr0->next[1]) - { - if (nThunks == 3) - { - pTris[nTris * 3] = static_cast(ptr0->pt - pVtx); - pTris[nTris * 3 + 1] = static_cast(ptr0->next[1]->pt - pVtx); - pTris[nTris * 3 + 2] = static_cast(ptr0->next[0]->pt - pVtx); - nTris++; - break; - } - for (i = 0; (*ptr0->next[1]->pt - *ptr0->pt ^ *ptr0->next[0]->pt - *ptr0->pt) < 0 && i < nThunks; ptr0 = ptr0->next[1], i++) - { - ; - } - if (i == nThunks) - { - break; - } - for (ptr = ptr0->next[1]->next[1]; ptr != ptr0->next[0] && ptr->bProcessed; ptr = ptr->next[1]) - { - ; // find the 1st non-convex vertex after ptr0 - } - for (; ptr != ptr0->next[0] && min(min(*ptr0->pt - *ptr0->next[0]->pt ^ *ptr->pt - *ptr0->next[0]->pt, - *ptr0->next[1]->pt - *ptr0->pt ^ *ptr->pt - *ptr0->pt), - *ptr0->next[0]->pt - *ptr0->next[1]->pt ^ *ptr->pt - *ptr0->next[1]->pt) < 0; ptr = ptr->next[1]) - { - ; - } - if (ptr == ptr0->next[0]) // vertex is an ear, output the corresponding triangle - { - pTris[nTris * 3] = static_cast(ptr0->pt - pVtx); - pTris[nTris * 3 + 1] = static_cast(ptr0->next[1]->pt - pVtx); - pTris[nTris * 3 + 2] = static_cast(ptr0->next[0]->pt - pVtx); - nTris++; - ptr0->next[1]->next[0] = ptr0->next[0]; - ptr0->next[0]->next[1] = ptr0->next[1]; - nThunks--; - nNonEars = 0; - } - else - { - nNonEars++; - } - } - - if (pThunks != bufThunks) - { - delete[] pThunks; - } - return nTris; - } - - int TriangulatePoly(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf) - { - if (nVtx < 3) - { - return 0; - } - vtxthunk* pThunks, * pPrevThunk, * pContStart, ** pSags, ** pBottoms, * pPinnacle = nullptr, * pBounds[2], * pPrevBounds[2], * ptr, * ptr_next; - vtxthunk bufThunks[32], * bufSags[16], * bufBottoms[16]; - int i, nThunks, nBottoms = 0, nSags = 0, iBottom = 0, nConts = 0, j, isag, nThunks0, nTris = 0, nPrevSags, nTrisCnt, iter, nDegenTris = 0; - float ymax, ymin, e, area0 = 0, area1 = 0, cntarea, minCntArea; - - isag = is_unused(pVtx[0].x); - ymin = ymax = pVtx[isag].y; - for (i = isag; i < nVtx; i++) - { - if (!is_unused(pVtx[i].x)) - { - ymin = min(ymin, pVtx[i].y); - ymax = max(ymax, pVtx[i].y); - } - } - e = (ymax - ymin) * 0.0005f; - for (i = 1 + isag; i < nVtx; i++) - { - if (!is_unused(pVtx[i].x)) - { - j = i < nVtx - 1 && !is_unused(pVtx[i + 1].x) ? i + 1 : isag; - if ((ymin = min(pVtx[j].y, pVtx[i - 1].y)) > pVtx[i].y - e) - { - if ((pVtx[j] - pVtx[i] ^ pVtx[i - 1] - pVtx[i]) > 0) - { - nBottoms++; // we have a bottom - } - else if (ymin > pVtx[i].y + 1E-8f) - { - nSags++; // we have a sag - } - } - } - else - { - nConts++; - isag = ++i; - } - } - nSags += nConts; - if ((nConts - 2) >> 31 & g_bBruteforceTriangulation) - { - return TriangulatePolyBruteforce(pVtx, nVtx, pTris, szTriBuf); - } - pThunks = nVtx + nSags * 2 <= sizeof(bufThunks) / sizeof(bufThunks[0]) ? bufThunks : new vtxthunk[nVtx + nSags * 2]; - - for (i = nThunks = 0, pContStart = pPrevThunk = pThunks; i < nVtx; i++) - { - if (!is_unused(pVtx[i].x)) - { - pThunks[nThunks].next[1] = pThunks + nThunks; - pThunks[nThunks].next[1] = pPrevThunk->next[1]; - pPrevThunk->next[1] = pThunks + nThunks; - pThunks[nThunks].next[0] = pPrevThunk; - pThunks[nThunks].jump = 0; - pPrevThunk = pThunks + nThunks; - pThunks[nThunks].bProcessed = 0; - pThunks[nThunks++].pt = &pVtx[i]; - } - else - { - pPrevThunk->next[1] = pContStart; - pContStart->next[0] = pThunks + nThunks - 1; - pContStart = pPrevThunk = pThunks + nThunks; - } - } - - for (i = j = 0, cntarea = 0, minCntArea = 1; i < nThunks; i++) - { - cntarea += *pThunks[i].pt ^ *pThunks[i].next[1]->pt; - j++; - if (pThunks[i].next[1] != pThunks + i + 1) - { - if (j >= 3) - { - area0 += cntarea; - minCntArea = min(cntarea, minCntArea); - } - cntarea = 0; - j = 0; - } - } - if (minCntArea > 0 && nConts > 1) - { - // if all contours are positive, triangulate them as separate (it's more safe) - for (i = 0; i < nThunks; i++) - { - if (pThunks[i].next[0] != pThunks + i - 1) - { - nTrisCnt = TriangulatePoly(pThunks[i].pt, static_cast((pThunks[i].next[0]->pt - pThunks[i].pt) + 2), pTris + nTris * 3, szTriBuf - nTris * 3); - for (j = 0, isag = static_cast(pThunks[i].pt - pVtx); j < nTrisCnt * 3; j++) - { - pTris[nTris * 3 + j] += isag; - } - i = static_cast(pThunks[i].next[0] - pThunks); - nTris += nTrisCnt; - } - } - if (pThunks != bufThunks) - { - delete[] pThunks; - } - return nTris; - } - - pSags = nSags <= sizeof(bufSags) / sizeof(bufSags[0]) ? bufSags : new vtxthunk * [nSags]; - pBottoms = nSags + nBottoms <= sizeof(bufBottoms) / sizeof(bufBottoms[0]) ? bufBottoms : new vtxthunk * [nSags + nBottoms]; - - for (i = nSags = nBottoms = 0; i < nThunks; i++) - { - if ((ymin = min(pThunks[i].next[1]->pt->y, pThunks[i].next[0]->pt->y)) > pThunks[i].pt->y - e) - { - if ((*pThunks[i].next[1]->pt - *pThunks[i].pt ^ *pThunks[i].next[0]->pt - *pThunks[i].pt) >= 0) - { - pBottoms[nBottoms++] = pThunks + i; // we have a bottom - } - else if (ymin > pThunks[i].pt->y + e) - { - pSags[nSags++] = pThunks + i; // we have a sag - } - } - } - iBottom = -1; - pBounds[0] = pBounds[1] = pPrevBounds[0] = pPrevBounds[1] = 0; - nThunks0 = nThunks; - nPrevSags = nSags; - iter = nThunks * 4; - - do - { - nextiter: - if (!pBounds[0]) // if bounds are empty, get the next available bottom - { - for (++iBottom; iBottom < nBottoms && !pBottoms[iBottom]->next[0]; iBottom++) - { - ; - } - if (iBottom >= nBottoms) - { - break; - } - pBounds[0] = pBounds[1] = pPinnacle = pBottoms[iBottom]; - } - pBounds[0]->bProcessed = pBounds[1]->bProcessed = 1; - if (pBounds[0] == pPrevBounds[0] && pBounds[1] == pPrevBounds[1] && nSags == nPrevSags || !pBounds[0]->next[0] || !pBounds[1]->next[0]) - { - pBounds[0] = pBounds[1] = 0; - continue; - } - pPrevBounds[0] = pBounds[0]; - pPrevBounds[1] = pBounds[1]; - nPrevSags = nSags; - - // check if left or right is a top - for (i = 0; i < 2; i++) - { - if (pBounds[i]->next[0]->pt->y < pBounds[i]->pt->y && pBounds[i]->next[1]->pt->y <= pBounds[i]->pt->y && - (*pBounds[i]->next[0]->pt - *pBounds[i]->pt ^ *pBounds[i]->next[1]->pt - *pBounds[i]->pt) > 0) - { - if (pBounds[i]->jump) - { - do - { - ptr = pBounds[i]->jump; - pBounds[i]->jump = 0; - pBounds[i] = ptr; - } while (pBounds[i]->jump); - } - else - { - pBounds[i]->jump = pBounds[i ^ 1]; - pBounds[0] = pBounds[1] = 0; - goto nextiter; - } - if (!pBounds[0]->next[0] || !pBounds[1]->next[0]) - { - pBounds[0] = pBounds[1] = 0; - goto nextiter; - } - } - } - i = isneg(pBounds[1]->next[1]->pt->y - pBounds[0]->next[0]->pt->y); - ymax = pBounds[i ^ 1]->next[i ^ 1]->pt->y; - ymin = min(pBounds[0]->pt->y, pBounds[1]->pt->y); - - for (j = 0, isag = -1; j < nSags; j++) - { - if (inrange(pSags[j]->pt->y, ymin, ymax) && // find a sag in next left-left-right-next right quad - pSags[j] != pBounds[0]->next[0] && pSags[j] != pBounds[1]->next[1] && - (*pBounds[0]->pt - *pBounds[0]->next[0]->pt ^ *pSags[j]->pt - *pBounds[0]->next[0]->pt) >= 0 && - (*pBounds[1]->pt - *pBounds[0]->pt ^ *pSags[j]->pt - *pBounds[0]->pt) >= 0 && - (*pBounds[1]->next[1]->pt - *pBounds[1]->pt ^ *pSags[j]->pt - *pBounds[1]->pt) >= 0 && - (*pBounds[0]->next[0]->pt - *pBounds[1]->next[1]->pt ^ *pSags[j]->pt - *pBounds[1]->next[1]->pt) >= 0) - { - ymax = pSags[j]->pt->y; - isag = j; - } - } - - if (isag >= 0) // build a bridge between the sag and the highest active point - { - if (pSags[isag]->next[0]) - { - pPinnacle->next[1]->next[0] = pThunks + nThunks; - pSags[isag]->next[0]->next[1] = pThunks + nThunks + 1; - pThunks[nThunks].next[0] = pThunks + nThunks + 1; - pThunks[nThunks].next[1] = pPinnacle->next[1]; - pThunks[nThunks + 1].next[1] = pThunks + nThunks; - pThunks[nThunks + 1].next[0] = pSags[isag]->next[0]; - pPinnacle->next[1] = pSags[isag]; - pSags[isag]->next[0] = pPinnacle; - pThunks[nThunks].pt = pPinnacle->pt; - pThunks[nThunks + 1].pt = pSags[isag]->pt; - pThunks[nThunks].jump = pThunks[nThunks + 1].jump = 0; - pThunks[nThunks].bProcessed = pThunks[nThunks + 1].bProcessed = 0; - if (pBounds[1] == pPinnacle) - { - pBounds[1] = pThunks + nThunks; - } - for (ptr = pThunks + nThunks, j = 0; ptr != pBounds[1]->next[1] && j < nThunks; ptr = ptr->next[1], j++) - { - if (min(ptr->next[0]->pt->y, ptr->next[1]->pt->y) > ptr->pt->y) // ptr is a bottom - { - pBottoms[nBottoms++] = ptr; - break; - } - } - pBounds[1] = pPinnacle; - pPinnacle = pSags[isag]; - nThunks += 2; - } - for (j = isag; j < nSags - 1; j++) - { - pSags[j] = pSags[j + 1]; - } - --nSags; - continue; - } - - // create triangles featuring the new vertex - for (ptr = pBounds[i]; ptr != pBounds[i ^ 1] && nTris < szTriBuf; ptr = ptr_next) - { - if ((*ptr->next[i ^ 1]->pt - *ptr->pt ^ *ptr->next[i]->pt - *ptr->pt) * (1 - i * 2) > 0 || pBounds[0]->next[0] == pBounds[1]->next[1]) - { - // output the triangle - pTris[nTris * 3] = static_cast(pBounds[i]->next[i]->pt - pVtx); - pTris[nTris * 3 + 1 + i] = static_cast(ptr->pt - pVtx); - pTris[nTris * 3 + 2 - i] = static_cast(ptr->next[i ^ 1]->pt - pVtx); - vector2df edge0 = pVtx[pTris[nTris * 3 + 1]] - pVtx[pTris[nTris * 3]], edge1 = pVtx[pTris[nTris * 3 + 2]] - pVtx[pTris[nTris * 3]]; - float darea = edge0 ^ edge1; - area1 += darea; - nDegenTris += isneg(sqr(darea) - sqr(0.02f) * (edge0 * edge0) * (edge1 * edge1)); - nTris++; - ptr->next[i ^ 1]->next[i] = ptr->next[i]; - ptr->next[i]->next[i ^ 1] = ptr->next[i ^ 1]; - pBounds[i] = ptr_next = ptr->next[i ^ 1]; - if (pPinnacle == ptr) - { - pPinnacle = ptr->next[i]; - } - ptr->next[0] = ptr->next[1] = 0; - ptr->bProcessed = 1; - } - else - { - break; - } - } - - if ((pBounds[i] = pBounds[i]->next[i]) == pBounds[i ^ 1]->next[i ^ 1]) - { - pBounds[0] = pBounds[1] = 0; - } - else if (pBounds[i]->pt->y > pPinnacle->pt->y) - { - pPinnacle = pBounds[i]; - } - } while (nTris < szTriBuf && --iter); - - if (pThunks != bufThunks) - { - delete[] pThunks; - } - if (pBottoms != bufBottoms) - { - delete[] pBottoms; - } - if (pSags != bufSags) - { - delete[] pSags; - } - - int bProblem = nTrisarea0 * 0.003f || nTris >= szTriBuf; - if (bProblem || nDegenTris) - { - if (nConts == 1) - { - return TriangulatePolyBruteforce(pVtx, nVtx, pTris, szTriBuf); - } - else - { - g_nTriangulationErrors += bProblem; - } - } - - return nTris; - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.h b/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.h deleted file mode 100644 index 208f21d288..0000000000 --- a/Code/CryEngine/Cry3DEngine/Cry_LegacyPhysUtils.h +++ /dev/null @@ -1,909 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Copied utils functions from CryPhysics that are used by non-physics systems -// This functions will be eventually removed, DO *NOT* use these functions -// TO-DO: Re-implement users using new code -// LY-109806 - -#pragma once - -#include "stridedptr.h" -#include "Cry_Math.h" -#include "Cry_Vector3.h" - -namespace LegacyCryPhysicsUtils -{ - typedef int index_t; - - // Workaround for bug in GCC 4.8. The kind of access patterns here leads to an internal - // compiler error in GCC 4.8 when optimizing with debug symbols. Two possible solutions - // are available, compile in Profile mode without debug symbols or remove optimizations - // in the code where the bug occurs - // see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59776 -#if defined(_PROFILE) && !defined(__clang__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) - // Cannot use #pragma GCC optimize("O0") because it causes a system crash when using - // the gcc compiler for another platform -#define CRY_GCC48_AVOID_OPTIMIZE __attribute__((optimize("-O0"))) -#else -#define CRY_GCC48_AVOID_OPTIMIZE -#endif - // unused_marker deliberately fills a variable with invalid data, - // so that later is_unused() can check whether it was initialized - // (this is used in all physics params/status/action structures) - class unused_marker - { - public: - union f2i - { - float f; - uint32 i; - }; - union d2i - { - double d; - uint32 i[2]; - }; - unused_marker() {} - unused_marker& operator,(float& x) CRY_GCC48_AVOID_OPTIMIZE; - unused_marker& operator,(double& x) CRY_GCC48_AVOID_OPTIMIZE; - unused_marker& operator,(int& x) CRY_GCC48_AVOID_OPTIMIZE; - unused_marker& operator,(unsigned int& x) CRY_GCC48_AVOID_OPTIMIZE; - template - unused_marker& operator,(ref*& x) { x = (ref*)-1; return *this; } - template - unused_marker& operator,(Vec3_tpl& x) { return *this, x.x; } - template - unused_marker& operator,(Quat_tpl& x) { return *this, x.w; } - template - unused_marker& operator,(strided_pointer& x) { return *this, x.data; } - }; - inline unused_marker& unused_marker::operator,(float& x) { *alias_cast(&x) = 0xFFBFFFFF; return *this; } - inline unused_marker& unused_marker::operator,(double& x) { (alias_cast(&x))[false ? 1 : 0] = 0xFFF7FFFF; return *this; } - inline unused_marker& unused_marker::operator,(int& x) { x = 1 << 31; return *this; } - inline unused_marker& unused_marker::operator,(unsigned int& x) { x = 1u << 31; return *this; } - -#undef CRY_GCC48_AVOID_OPTIMIZE - - inline bool is_unused(const float& x) { unused_marker::f2i u; u.f = x; return (u.i & 0xFFA00000) == 0xFFA00000; } - - inline bool is_unused(int x) { return x == 1 << 31; } - inline bool is_unused(unsigned int x) { return x == 1u << 31; } - template - bool is_unused(ref* x) { return x == (ref*)-1; } - template - bool is_unused(strided_pointer x) { return is_unused(x.data); } - template - bool is_unused(const Ang3_tpl& x) { return is_unused(x.x); } - template - bool is_unused(const Vec3_tpl& x) { return is_unused(x.x); } - template - bool is_unused(const Quat_tpl& x) { return is_unused(x.w); } - inline bool is_unused(const double& x) { unused_marker::d2i u; u.d = x; return (u.i[eLittleEndian ? 1 : 0] & 0xFFF40000) == 0xFFF40000; } -#ifndef MARK_UNUSED -#define MARK_UNUSED LegacyCryPhysicsUtils::unused_marker(), -#endif - typedef void* (*qhullmalloc)(size_t); - namespace qhull_IMPL - { - struct ptitem - { - ptitem* next, * prev; - }; - - struct qhtritem - { - qhtritem* next, * prev; - ptitem* ptassoc; - Vec3 n, pt0; - int idx[3]; - qhtritem* buddy[3]; - int deleted; - }; - - inline bool e_cansee(const Vec3& dp, const Vec3& n, float e = 0.002f) { return sqr_signed(dp * n) > sqr_signed(e)* dp.len2()* n.len2(); } - - inline void relocate_ptritem(qhtritem*& ptr, intptr_t diff) - { - ptr = (qhtritem*)((intptr_t)ptr + diff & ~- iszero((intptr_t)ptr)); // offset the pointer, but leave out 0s - } - - inline void relocate_tritem(qhtritem* ptr, intptr_t diff) - { - relocate_ptritem(ptr->next, diff); - relocate_ptritem(ptr->prev, diff); - relocate_ptritem(ptr->buddy[0], diff); - relocate_ptritem(ptr->buddy[1], diff); - relocate_ptritem(ptr->buddy[2], diff); - } - - template - void delete_item_from_list(item* p) - { - if (p->prev) - { - p->prev->next = p->next; - } - if (p->next) - { - p->next->prev = p->prev; - } - p->prev = p->next = 0; - } - template - void add_item_to_list(item*& pin, item* pnew) - { - if (!pin) - { - pin = pnew->next = pnew->prev = pnew; - } - else - { - pnew->next = pin->next; - pnew->prev = pin; - pin->next->prev = pnew; - pin->next = pnew; - } - } - template - void merge_lists(item*& plist, item* pnew) - { - if (!pnew) - { - return; - } - if (!plist) - { - plist = pnew; - } - else - { - plist->next->prev = pnew->prev; - pnew->prev->next = plist->next; - plist->next = pnew; - pnew->prev = plist; - } - } - - struct Vec3mem - : Vec3 - { - Vec3 operator-(const Vec3& op) const { return sub(op); } - float operator*(const Vec3& op) const { return dot(op); } - Vec3 operator^(const Vec3& op) const { return cross(op); } - }; - - void associate_ptlist_with_trilist(ptitem* ptlist, qhtritem* trilist, ptitem* pt0, strided_pointer pvtx); - - inline void swap(int* v, void** p, int i1, int i2) - { - int ti = v[i1]; - v[i1] = v[i2]; - v[i2] = ti; - void* tp = p[i1]; - p[i1] = p[i2]; - p[i2] = tp; - } - - void qsort(int* v, void** p, int left, int right); - - int bin_search(int* v, int n, int idx); - - int qhull(strided_pointer _pts, int npts, index_t*& pTris, qhullmalloc qmalloc); - - } // namespace qhull_IMPL - - int qhull(strided_pointer _pts, int npts, index_t*& pTris, qhullmalloc qmalloc); - - namespace TriangulatePoly_IMPL - { - static int g_bSaferBooleans = 1; - static int g_nTriangulationErrors; - static int g_bBruteforceTriangulation = 0; - - struct vtxthunk - { - vtxthunk* next[2]; - vtxthunk* jump; - vector2df* pt; - int bProcessed; - }; - - int TriangulatePolyBruteforce(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf); - - int TriangulatePoly(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf); - - } // namespace TriangulatePoly_IMPL - - int TriangulatePoly(vector2df* pVtx, int nVtx, int* pTris, int szTriBuf); - - namespace polynomial_tpl_IMPL - { - template - class polynomial_tpl - { - public: - explicit polynomial_tpl() { denom = (ftype)1; }; - explicit polynomial_tpl(ftype op) { zero(); data[degree] = op; } - AZ_FORCE_INLINE polynomial_tpl& zero() - { - for (int i = 0; i <= degree; i++) - { - data[i] = 0; - } - denom = (ftype)1; - return *this; - } - polynomial_tpl(const polynomial_tpl& src) { *this = src; } - polynomial_tpl& operator=(const polynomial_tpl& src) - { - denom = src.denom; - for (int i = 0; i <= degree; i++) - { - data[i] = src.data[i]; - } - return *this; - } - template - AZ_FORCE_INLINE polynomial_tpl& operator=(const polynomial_tpl& src) - { - int i; - denom = src.denom; - for (i = 0; i <= min(degree, degree1); i++) - { - data[i] = src.data[i]; - } - for (; i < degree; i++) - { - data[i] = 0; - } - return *this; - } - AZ_FORCE_INLINE polynomial_tpl& set(ftype* pdata) - { - for (int i = 0; i <= degree; i++) - { - data[degree - i] = pdata[i]; - } - return *this; - } - - AZ_FORCE_INLINE ftype& operator[](int idx) { return data[idx]; } - - void calc_deriviative(polynomial_tpl& deriv, int curdegree = degree) const; - - AZ_FORCE_INLINE polynomial_tpl& fixsign() - { - ftype sg = sgnnz(denom); - denom *= sg; - for (int i = 0; i <= degree; i++) - { - data[i] *= sg; - } - return *this; - } - - int findroots(ftype start, ftype end, ftype* proots, int nIters = 20, int curdegree = degree, bool noDegreeCheck = false) const; - int nroots(ftype start, ftype end) const; - - AZ_FORCE_INLINE ftype eval(ftype x) const - { - ftype res = 0; - for (int i = degree; i >= 0; i--) - { - res = res * x + data[i]; - } - return res; - } - AZ_FORCE_INLINE ftype eval(ftype x, int subdegree) const - { - ftype res = data[subdegree]; - for (int i = subdegree - 1; i >= 0; i--) - { - res = res * x + data[i]; - } - return res; - } - - AZ_FORCE_INLINE polynomial_tpl& operator+=(ftype op) { data[0] += op * denom; return *this; } - AZ_FORCE_INLINE polynomial_tpl& operator-=(ftype op) { data[0] -= op * denom; return *this; } - AZ_FORCE_INLINE polynomial_tpl operator*(ftype op) const - { - polynomial_tpl res; - res.denom = denom; - for (int i = 0; i <= degree; i++) - { - res.data[i] = data[i] * op; - } - return res; - } - AZ_FORCE_INLINE polynomial_tpl& operator*=(ftype op) - { - for (int i = 0; i <= degree; i++) - { - data[i] *= op; - } - return *this; - } - AZ_FORCE_INLINE polynomial_tpl operator/(ftype op) const - { - polynomial_tpl res = *this; - res.denom = denom * op; - return res; - } - AZ_FORCE_INLINE polynomial_tpl& operator/=(ftype op) { denom *= op; return *this; } - - AZ_FORCE_INLINE polynomial_tpl sqr() const { return *this * *this; } - - ftype denom; - ftype data[degree + 1]; - }; - - template - struct tagPolyE - { - inline static ftype polye() { return (ftype)1E-10; } - }; - - template<> - inline float tagPolyE::polye() { return 1e-6f; } - - template - inline ftype polye() { return tagPolyE::polye(); } - - // Don't use this macro; use AZStd::max instead. This is only here to make the template const arguments below readable - // and because Visual Studio 2013 doesn't have a const_expr version of std::max - #define deprecated_degmax(degree1, degree2) (((degree1) > (degree2)) ? (degree1) : (degree2)) - - template - AZ_FORCE_INLINE polynomial_tpl operator+(const polynomial_tpl& pn, ftype op) - { - polynomial_tpl res = pn; - res.data[0] += op * res.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(const polynomial_tpl& pn, ftype op) - { - polynomial_tpl res = pn; - res.data[0] -= op * res.denom; - return res; - } - - template - AZ_FORCE_INLINE polynomial_tpl operator+(ftype op, const polynomial_tpl& pn) - { - polynomial_tpl res = pn; - res.data[0] += op * res.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(ftype op, const polynomial_tpl& pn) - { - polynomial_tpl res = pn; - res.data[0] -= op * res.denom; - for (int i = 0; i <= degree; i++) - { - res.data[i] = -res.data[i]; - } - return res; - } - template - polynomial_tpl AZ_FORCE_INLINE psqr(const polynomial_tpl& op) { return op * op; } - - template - AZ_FORCE_INLINE polynomial_tpl operator+(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - int i; - for (i = 0; i <= min(degree1, degree2); i++) - { - res.data[i] = op1.data[i] * op2.denom + op2.data[i] * op1.denom; - } - for (; i <= degree1; i++) - { - res.data[i] = op1.data[i] * op2.denom; - } - for (; i <= degree2; i++) - { - res.data[i] = op2.data[i] * op1.denom; - } - res.denom = op1.denom * op2.denom; - return res; - } - template - AZ_FORCE_INLINE polynomial_tpl operator-(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - int i; - for (i = 0; i <= min(degree1, degree2); i++) - { - res.data[i] = op1.data[i] * op2.denom - op2.data[i] * op1.denom; - } - for (; i <= degree1; i++) - { - res.data[i] = op1.data[i] * op2.denom; - } - for (; i <= degree2; i++) - { - res.data[i] = op2.data[i] * op1.denom; - } - res.denom = op1.denom * op2.denom; - return res; - } - - template - AZ_FORCE_INLINE polynomial_tpl& operator+=(polynomial_tpl& op1, const polynomial_tpl& op2) - { - for (int i = 0; i < min(degree1, degree2); i++) - { - op1.data[i] = op1.data[i] * op2.denom + op2.data[i] * op1.denom; - } - op1.denom *= op2.denom; - return op1; - } - template - AZ_FORCE_INLINE polynomial_tpl& operator-=(polynomial_tpl& op1, const polynomial_tpl& op2) - { - for (int i = 0; i < min(degree1, degree2); i++) - { - op1.data[i] = op1.data[i] * op2.denom - op2.data[i] * op1.denom; - } - op1.denom *= op2.denom; - return op1; - } - - template - AZ_FORCE_INLINE polynomial_tpl operator*(const polynomial_tpl& op1, const polynomial_tpl& op2) - { - polynomial_tpl res; - res.zero(); - int j; - switch (degree1) - { - case 8: - for (j = 0; j <= degree2; j++) - { - res.data[8 + j] += op1.data[8] * op2.data[j]; - } - case 7: - for (j = 0; j <= degree2; j++) - { - res.data[7 + j] += op1.data[7] * op2.data[j]; - } - case 6: - for (j = 0; j <= degree2; j++) - { - res.data[6 + j] += op1.data[6] * op2.data[j]; - } - case 5: - for (j = 0; j <= degree2; j++) - { - res.data[5 + j] += op1.data[5] * op2.data[j]; - } - case 4: - for (j = 0; j <= degree2; j++) - { - res.data[4 + j] += op1.data[4] * op2.data[j]; - } - case 3: - for (j = 0; j <= degree2; j++) - { - res.data[3 + j] += op1.data[3] * op2.data[j]; - } - case 2: - for (j = 0; j <= degree2; j++) - { - res.data[2 + j] += op1.data[2] * op2.data[j]; - } - case 1: - for (j = 0; j <= degree2; j++) - { - res.data[1 + j] += op1.data[1] * op2.data[j]; - } - case 0: - for (j = 0; j <= degree2; j++) - { - res.data[0 + j] += op1.data[0] * op2.data[j]; - } - } - res.denom = op1.denom * op2.denom; - return res; - } - - - template - AZ_FORCE_INLINE void polynomial_divide(const polynomial_tpl& num, const polynomial_tpl& den, polynomial_tpl& quot, - polynomial_tpl& rem, int degree1, int degree2) - { - int i, j, k, l; - ftype maxel; - for (i = 0; i <= degree1; i++) - { - rem.data[i] = num.data[i]; - } - for (i = 0; i <= degree1 - degree2; i++) - { - quot.data[i] = 0; - } - for (i = 1, maxel = fabs_tpl(num.data[0]); i <= degree1; i++) - { - maxel = max(maxel, num.data[i]); - } - for (maxel *= polye(); degree1 >= 0 && fabs_tpl(num.data[degree1]) < maxel; degree1--) - { - ; - } - for (i = 1, maxel = fabs_tpl(den.data[0]); i <= degree2; i++) - { - maxel = max(maxel, den.data[i]); - } - for (maxel *= polye(); degree2 >= 0 && fabs_tpl(den.data[degree2]) < maxel; degree2--) - { - ; - } - rem.denom = num.denom; - quot.denom = (ftype)1; - if (degree1 < 0 || degree2 < 0) - { - return; - } - - for (k = degree1 - degree2, l = degree1; l >= degree2; l--, k--) - { - quot.data[k] = rem.data[l] * den.denom; - quot.denom *= den.data[degree2]; - for (i = degree1 - degree2; i > k; i--) - { - quot.data[i] *= den.data[degree2]; - } - for (i = degree2 - 1, j = l - 1; i >= 0; i--, j--) - { - rem.data[j] = rem.data[j] * den.data[degree2] - den.data[i] * rem.data[l]; - } - for (; j >= 0; j--) - { - rem.data[j] *= den.data[degree2]; - } - rem.denom *= den.data[degree2]; - } - } - - template - AZ_FORCE_INLINE polynomial_tpl operator/(const polynomial_tpl& num, const polynomial_tpl& den) - { - polynomial_tpl quot; - polynomial_tpl rem; - polynomial_divide((polynomial_tpl&)num, (polynomial_tpl&)den, (polynomial_tpl&)quot, - (polynomial_tpl&)rem, degree1, degree2); - return quot; - } - template - AZ_FORCE_INLINE polynomial_tpl operator%(const polynomial_tpl& num, const polynomial_tpl& den) - { - polynomial_tpl quot; - polynomial_tpl rem; - polynomial_divide((polynomial_tpl&)num, (polynomial_tpl&)den, (polynomial_tpl&)quot, - (polynomial_tpl&)rem, degree1, degree2); - return (polynomial_tpl&)rem; - } - - template - AZ_FORCE_INLINE void polynomial_tpl::calc_deriviative(polynomial_tpl& deriv, int curdegree) const - { - for (int i = 0; i < curdegree; i++) - { - deriv.data[i] = data[i + 1] * (i + 1); - } - deriv.denom = denom; - } - - template - to_t* convert_type(from_t* input) - { - typedef union - { - to_t* to; - from_t* from; - } convert_union; - convert_union u; - u.from = input; - return u.to; - } - - template - AZ_FORCE_INLINE int polynomial_tpl::nroots(ftype start, ftype end) const - { - polynomial_tpl f[degree + 1]; - int i, j, sg_a, sg_b; - ftype val, prevval; - - calc_deriviative(f[0]); - polynomial_divide(*convert_type >(this), *convert_type< polynomial_tpl >(&f[0]), *convert_type >(&f[degree]), - *convert_type >(&f[1]), degree, degree - 1); - f[1].denom = -f[1].denom; - for (i = 2; i < degree; i++) - { - polynomial_divide(*convert_type >(&f[i - 2]), *convert_type >(&f[i - 1]), *convert_type >(&f[degree]), - *convert_type >(&f[i]), degree + 1 - i, degree - i); - f[i].denom = -f[i].denom; - if (fabs_tpl(f[i].denom) > (ftype)1E10) - { - for (j = 0; j <= degree - 1 - i; j++) - { - f[i].data[j] *= (ftype)1E-10; - } - f[i].denom *= (ftype)1E-10; - } - } - - prevval = eval(start) * denom; - for (i = sg_a = 0; i < degree; i++, prevval = val) - { - val = f[i].eval(start, degree - 1 - i) * f[i].denom; - sg_a += isneg(val * prevval); - } - - prevval = eval(end) * denom; - for (i = sg_b = 0; i < degree; i++, prevval = val) - { - val = f[i].eval(end, degree - 1 - i) * f[i].denom; - sg_b += isneg(val * prevval); - } - - return fabs_tpl(sg_a - sg_b); - } - - template - AZ_FORCE_INLINE ftype cubert_tpl(ftype x) { return fabs_tpl(x) > (ftype)1E-20 ? exp_tpl(log_tpl(fabs_tpl(x)) * (ftype)(1.0 / 3)) * sgnnz(x) : x; } - template - AZ_FORCE_INLINE ftype pow_tpl(ftype x, ftype pow) { return fabs_tpl(x) > (ftype)1E-20 ? exp_tpl(log_tpl(fabs_tpl(x)) * pow) * sgnnz(x) : x; } - template - AZ_FORCE_INLINE void swap(ftype* ptr, int i, int j) { ftype t = ptr[i]; ptr[i] = ptr[j]; ptr[j] = t; } - - template - int polynomial_tpl::findroots(ftype start, ftype end, ftype* proots, [[maybe_unused]] int nIters, int degree, bool noDegreeCheck) const - { - AZ_UNUSED(nIters); - int i, j, nRoots = 0; - ftype maxel; - if (!noDegreeCheck) - { - for (i = 1, maxel = fabs_tpl(data[0]); i <= degree; i++) - { - maxel = max(maxel, data[i]); - } - for (maxel *= polye(); degree > 0 && fabs_tpl(data[degree]) <= maxel; degree--) - { - ; - } - } - - if constexpr (maxdegree >= 1) - { - if (degree == 1) - { - proots[0] = data[0] / data[1]; - nRoots = 1; - } - } - - if constexpr (maxdegree >= 2) - { - if (degree == 2) - { - ftype a, b, c, d, bound[2], sg; - - a = data[2]; - b = data[1]; - c = data[0]; - d = aznumeric_cast(sgnnz(a)); - a *= d; - b *= d; - c *= d; - d = b * b - a * c * 4; - bound[0] = start * a * 2 + b; - bound[1] = end * a * 2 + b; - sg = aznumeric_cast((sgnnz(bound[0] * bound[1]) + 1) >> 1); - bound[0] *= bound[0]; - bound[1] *= bound[1]; - bound[isneg(fabs_tpl(bound[1]) - fabs_tpl(bound[0]))] *= sg; - - if (isnonneg(d) & inrange(d, bound[0], bound[1])) - { - d = sqrt_tpl(d); - a = (ftype)0.5 / a; - proots[nRoots] = (-b - d) * a; - nRoots += inrange(proots[nRoots], start, end); - proots[nRoots] = (-b + d) * a; - nRoots += inrange(proots[nRoots], start, end); - } - } - } - - if constexpr (maxdegree >= 3) - { - if (degree == 3) - { - ftype t, a, b, c, a3, p, q, Q, Qr, Ar, Ai, phi; - - t = (ftype)1.0 / data[3]; - a = data[2] * t; - b = data[1] * t; - c = data[0] * t; - a3 = a * (ftype)(1.0 / 3); - p = b - a * a3; - q = (a3 * b - c) * (ftype)0.5 - cube(a3); - Q = cube(p * (ftype)(1.0 / 3)) + q * q; - Qr = sqrt_tpl(fabs_tpl(Q)); - - if (Q > 0) - { - proots[0] = cubert_tpl(q + Qr) + cubert_tpl(q - Qr) - a3; - nRoots = 1; - } - else - { - phi = atan2_tpl(Qr, q) * (ftype)(1.0 / 3); - t = pow_tpl(Qr * Qr + q * q, (ftype)(1.0 / 6)); - Ar = t * cos_tpl(phi); - Ai = t * sin_tpl(phi); - proots[0] = 2 * Ar - a3; - proots[1] = aznumeric_cast(-Ar + Ai * sqrt3 - a3); - proots[2] = aznumeric_cast(-Ar - Ai * sqrt3 - a3); - i = idxmax3(proots); - swap(proots, i, 2); - i = isneg(proots[0] - proots[1]); - swap(proots, i, 1); - nRoots = 3; - } - } - } - - if constexpr (maxdegree >= 4) - { - if (degree == 4) - { - ftype t, a3, a2, a1, a0, y, R, D, E, subroots[3]; - const ftype e = (ftype)1E-9; - - t = (ftype)1.0 / data[4]; - a3 = data[3] * t; - a2 = data[2] * t; - a1 = data[1] * t; - a0 = data[0] * t; - polynomial_tpl p3aux; - ftype kp3aux[] = { 1, -a2, a1 * a3 - 4 * a0, 4 * a2 * a0 - a1 * a1 - a3 * a3 * a0 }; - p3aux.set(kp3aux); - if (!p3aux.findroots((ftype)-1E20, (ftype)1E20, subroots)) - { - return 0; - } - R = a3 * a3 * (ftype)0.25 - a2 + (y = subroots[0]); - - if (R > -e) - { - if (R < e) - { - D = E = a3 * a3 * (ftype)(3.0 / 4) - 2 * a2; - t = y * y - 4 * a0; - if (t < -e) - { - return 0; - } - t = 2 * sqrt_tpl(max((ftype)0, t)); - } - else - { - R = sqrt_tpl(max((ftype)0, R)); - D = E = a3 * a3 * (ftype)(3.0 / 4) - R * R - 2 * a2; - t = (4 * a3 * a2 - 8 * a1 - a3 * a3 * a3) / R * (ftype)0.25; - } - if (D + t > -e) - { - D = sqrt_tpl(max((ftype)0, D + t)); - proots[nRoots++] = a3 * (ftype)-0.25 + (R - D) * (ftype)0.5; - proots[nRoots++] = a3 * (ftype)-0.25 + (R + D) * (ftype)0.5; - } - if (E - t > -e) - { - E = sqrt_tpl(max((ftype)0, E - t)); - proots[nRoots++] = a3 * (ftype)-0.25 - (R + E) * (ftype)0.5; - proots[nRoots++] = a3 * (ftype)-0.25 - (R - E) * (ftype)0.5; - } - if (nRoots == 4) - { - i = idxmax3(proots); - if (proots[3] < proots[i]) - { - swap(proots, i, 3); - } - i = idxmax3(proots); - swap(proots, i, 2); - i = isneg(proots[0] - proots[1]); - swap(proots, i, 1); - } - } - } - } - - if constexpr (maxdegree > 4) - { - if (degree > 4) - { - ftype roots[maxdegree + 1], prevroot, val, prevval[2], curval, bound[2], middle; - polynomial_tpl deriv; - int nExtremes, iter, iBound; - calc_deriviative(deriv); - - // find a subset of deriviative extremes between start and end - for (nExtremes = deriv.findroots(start, end, roots + 1, nIters, degree - 1) + 1; nExtremes > 1 && roots[nExtremes - 1] > end; nExtremes--) - { - ; - } - for (i = 1; i < nExtremes && roots[i] < start; i++) - { - ; - } - roots[i - 1] = start; - PREFAST_ASSUME(nExtremes < maxdegree + 1); - roots[nExtremes++] = end; - - for (prevroot = start, prevval[0] = eval(start, degree), nRoots = 0; i < nExtremes; prevval[0] = val, prevroot = roots[i++]) - { - val = eval(roots[i], degree); - if (val * prevval[0] < 0) - { - // we have exactly one root between prevroot and roots[i] - bound[0] = prevroot; - bound[1] = roots[i]; - iter = 0; - do - { - middle = (bound[0] + bound[1]) * (ftype)0.5; - curval = eval(middle, degree); - iBound = isneg(prevval[0] * curval); - bound[iBound] = middle; - prevval[iBound] = curval; - } while (++iter < nIters); - proots[nRoots++] = middle; - } - } - } - } - - for (i = 0; i < nRoots && proots[i] < start; i++) - { - ; - } - for (; nRoots > i&& proots[nRoots - 1] > end; nRoots--) - { - ; - } - for (j = i; j < nRoots; j++) - { - proots[j - i] = proots[j]; - } - - return nRoots - i; - } - } // namespace polynomial_tpl_IMPL - template - using polynomial_tpl = polynomial_tpl_IMPL::polynomial_tpl; - - typedef polynomial_tpl P3; - typedef polynomial_tpl P2; - typedef polynomial_tpl P1; - typedef polynomial_tpl P3f; - typedef polynomial_tpl P2f; - typedef polynomial_tpl P1f; -} // namespace LegacyCryPhysicsUtils diff --git a/Code/CryEngine/Cry3DEngine/CullBuffer.cpp b/Code/CryEngine/Cry3DEngine/CullBuffer.cpp deleted file mode 100644 index ce640ce343..0000000000 --- a/Code/CryEngine/Cry3DEngine/CullBuffer.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - diff --git a/Code/CryEngine/Cry3DEngine/CullBuffer.h b/Code/CryEngine/Cry3DEngine/CullBuffer.h deleted file mode 100644 index 246ee6457c..0000000000 --- a/Code/CryEngine/Cry3DEngine/CullBuffer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Occlusion buffer main include - - -#ifndef CRYINCLUDE_CRY3DENGINE_CULLBUFFER_H -#define CRYINCLUDE_CRY3DENGINE_CULLBUFFER_H -#pragma once - -#include "ProjectDefines.h" -#include "ObjMan.h" // EOcclusionObjectType -#include "CZBufferCuller.h" - -class CCullBuffer - : public CZBufferCuller -{ -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_CULLBUFFER_H diff --git a/Code/CryEngine/Cry3DEngine/Decal.cpp b/Code/CryEngine/Cry3DEngine/Decal.cpp deleted file mode 100644 index c9179459a4..0000000000 --- a/Code/CryEngine/Cry3DEngine/Decal.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : draw, create decals on the world - - -#include "Cry3DEngine_precompiled.h" - -#include "DecalManager.h" -#include "3dEngine.h" -#include "ObjMan.h" - -#include - -IGeometry* CDecal::s_pSphere = 0; - -void CDecal::ResetStaticData() -{ - SAFE_RELEASE(s_pSphere); -} - -int CDecal::Update(bool& active, const float fFrameTime) -{ - // process life time and disable decal when needed - m_fLifeTime -= fFrameTime; - - if (m_fLifeTime < 0) - { - active = 0; - FreeRenderData(); - } - else if (m_ownerInfo.pRenderNode && m_ownerInfo.pRenderNode->m_nInternalFlags & IRenderNode::UPDATE_DECALS) - { - active = false; - return 1; - } - return 0; -} - -Vec3 CDecal::GetWorldPosition() -{ - Vec3 vPos = m_vPos; - - if (m_ownerInfo.pRenderNode) - { - if (m_eDecalType == eDecalType_OS_SimpleQuad || m_eDecalType == eDecalType_OS_OwnersVerticesUsed) - { - assert(m_ownerInfo.pRenderNode); - if (m_ownerInfo.pRenderNode) - { - Matrix34A objMat; - if (IStatObj* pEntObject = m_ownerInfo.GetOwner(objMat)) - { - vPos = objMat.TransformPoint(vPos); - } - } - } - } - - return vPos; -} - -void CDecal::Render(const float fCurTime, int nAfterWater, float fDistanceFading, float fDistance, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pMaterial || !m_pMaterial->GetShaderItem().m_pShader || m_pMaterial->GetShaderItem().m_pShader->GetShaderType() != eST_General) - { - return; // shader not supported for decals - } - // Get decal alpha from life time - float fAlpha = m_fLifeTime * 2; - - if (fAlpha > 1.f) - { - fAlpha = 1.f; - } - else if (fAlpha < 0) - { - return; - } - - fAlpha *= fDistanceFading; - - float fSizeK; - if (m_fGrowTime) - { - fSizeK = min(1.f, sqrt_tpl((fCurTime - m_fLifeBeginTime) / m_fGrowTime)); - } - else - { - fSizeK = 1.f; - } - - float fSizeAlphaK; - if (m_fGrowTimeAlpha) - { - fSizeAlphaK = min(1.f, sqrt_tpl((fCurTime - m_fLifeBeginTime) / m_fGrowTimeAlpha)); - } - else - { - fSizeAlphaK = 1.f; - } - - if (m_bDeferred) - { - SDeferredDecal newItem; - newItem.fAlpha = fAlpha; - newItem.pMaterial = m_pMaterial; - newItem.nSortOrder = m_sortPrio; - newItem.nFlags = 0; - - Vec3 vRight, vUp, vNorm; - Matrix34A objMat; - - if (IStatObj* pEntObject = m_ownerInfo.GetOwner(objMat)) - { - vRight = objMat.TransformVector(m_vRight * m_fSize); - vUp = objMat.TransformVector(m_vUp * m_fSize); - vNorm = objMat.TransformVector((Vec3(m_vRight).Cross(m_vUp)) * m_fSize); - } - else - { - vRight = (m_vRight * m_fSize); - vUp = (m_vUp * m_fSize); - vNorm = ((Vec3(m_vRight).Cross(m_vUp)) * m_fSize); - } - - Matrix33 matRotation; - matRotation.SetColumn(0, vRight); - matRotation.SetColumn(1, vUp); - matRotation.SetColumn(2, vNorm * GetFloatCVar(e_DecalsDefferedDynamicDepthScale)); - newItem.projMatrix.SetRotation33(matRotation); - newItem.projMatrix.SetTranslation(m_vWSPos + vNorm * .1f * m_fWSSize); - - if (m_fGrowTimeAlpha) - { - newItem.fGrowAlphaRef = max(.02f, 1.f - fSizeAlphaK); - } - else - { - newItem.fGrowAlphaRef = 0; - } - - GetRenderer()->EF_AddDeferredDecal(newItem); - return; - } - - switch (m_eDecalType) - { - case eDecalType_WS_Merged: - case eDecalType_OS_OwnersVerticesUsed: - { - // check if owner mesh was deleted - if (m_pRenderMesh && (m_pRenderMesh->GetVertexContainer() == m_pRenderMesh) && m_pRenderMesh->GetVerticesCount() < 3) - { - FreeRenderData(); - } - - if (!m_pRenderMesh) - { - break; - } - - // setup transformation - CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObj) - { - return; - } - pObj->m_fSort = 0; - pObj->m_RState = 0; - - Matrix34A objMat; - if (m_ownerInfo.pRenderNode && !m_ownerInfo.GetOwner(objMat)) - { - assert(0); - return; - } - else - if (!m_ownerInfo.pRenderNode) - { - objMat.SetIdentity(); - if (m_eDecalType == eDecalType_WS_Merged) - { - objMat.SetTranslation(m_vPos); - } - } - - pObj->m_II.m_Matrix = objMat; - - pObj->m_nSort = m_sortPrio; - - // somehow it's need's to be twice bigger to be same as simple decals - float fSize2 = m_fSize * fSizeK * 2.f; ///m_ownerInfo.pRenderNode->GetScale(); - if (fSize2 < 0.0001f) - { - return; - } - - // setup texgen - // S component - float correctScale(-1); - m_arrBigDecalRMCustomData[0] = correctScale * m_vUp.x / fSize2; - m_arrBigDecalRMCustomData[1] = correctScale * m_vUp.y / fSize2; - m_arrBigDecalRMCustomData[2] = correctScale * m_vUp.z / fSize2; - - Vec3 vPosDecS = m_vPos; - if (m_eDecalType == eDecalType_WS_Merged) - { - vPosDecS.zero(); - } - - float D0 = - m_arrBigDecalRMCustomData[0] * vPosDecS.x + - m_arrBigDecalRMCustomData[1] * vPosDecS.y + - m_arrBigDecalRMCustomData[2] * vPosDecS.z; - - m_arrBigDecalRMCustomData[3] = -D0 + 0.5f; - - // T component - m_arrBigDecalRMCustomData[4] = m_vRight.x / fSize2; - m_arrBigDecalRMCustomData[5] = m_vRight.y / fSize2; - m_arrBigDecalRMCustomData[6] = m_vRight.z / fSize2; - - float D1 = - m_arrBigDecalRMCustomData[4] * vPosDecS.x + - m_arrBigDecalRMCustomData[5] * vPosDecS.y + - m_arrBigDecalRMCustomData[6] * vPosDecS.z; - - m_arrBigDecalRMCustomData[7] = -D1 + 0.5f; - - // pass attenuation info - m_arrBigDecalRMCustomData[8] = vPosDecS.x; - m_arrBigDecalRMCustomData[9] = vPosDecS.y; - m_arrBigDecalRMCustomData[10] = vPosDecS.z; - m_arrBigDecalRMCustomData[11] = m_fSize; - - // N component - Vec3 vNormal(Vec3(correctScale* m_vUp).Cross(m_vRight).GetNormalized()); - m_arrBigDecalRMCustomData[12] = vNormal.x * (m_fSize / m_fWSSize); - m_arrBigDecalRMCustomData[13] = vNormal.y * (m_fSize / m_fWSSize); - m_arrBigDecalRMCustomData[14] = vNormal.z * (m_fSize / m_fWSSize); - m_arrBigDecalRMCustomData[15] = 0; - - - // draw complex decal using new indices and original object vertices - pObj->m_fAlpha = fAlpha; - pObj->m_ObjFlags |= FOB_DECAL | FOB_DECAL_TEXGEN_2D; - pObj->m_nTextureID = -1; - //pObj->m_nTextureID1 = -1; - pObj->m_II.m_AmbColor = m_vAmbient; - m_pRenderMesh->SetREUserData(m_arrBigDecalRMCustomData, 0, fAlpha); - m_pRenderMesh->AddRenderElements(m_pMaterial, pObj, passInfo, EFSLIST_GENERAL, nAfterWater); - } - break; - - case eDecalType_OS_SimpleQuad: - { - assert(m_ownerInfo.pRenderNode); - if (!m_ownerInfo.pRenderNode) - { - break; - } - - // transform decal in software from owner space into world space and render as quad - Matrix34A objMat; - IStatObj* pEntObject = m_ownerInfo.GetOwner(objMat); - if (!pEntObject) - { - break; - } - - Vec3 vPos = objMat.TransformPoint(m_vPos); - Vec3 vRight = objMat.TransformVector(m_vRight * m_fSize); - Vec3 vUp = objMat.TransformVector(m_vUp * m_fSize); - UCol uCol; - - uCol.dcolor = 0xffffffff; - uCol.bcolor[3] = fastround_positive(fAlpha * 255); - - GetObjManager()->AddDecalToRenderer(fDistance, m_pMaterial, m_sortPrio, vRight * fSizeK, vUp * fSizeK, uCol, - OS_ALPHA_BLEND, m_vAmbient, vPos, nAfterWater, passInfo, rendItemSorter); - } - break; - - case eDecalType_WS_SimpleQuad: - { // draw small world space decal untransformed - UCol uCol; - uCol.dcolor = 0; - uCol.bcolor[3] = fastround_positive(fAlpha * 255); - - GetObjManager()->AddDecalToRenderer(fDistance, m_pMaterial, m_sortPrio, m_vRight * m_fSize * fSizeK, - m_vUp * m_fSize * fSizeK, uCol, OS_ALPHA_BLEND, m_vAmbient, m_vPos, nAfterWater, passInfo, - rendItemSorter); - } - break; - - case eDecalType_WS_OnTheGround: - { - RenderBigDecalOnTerrain(fAlpha, fSizeK, passInfo); - } - break; - } -} - -void CDecal::FreeRenderData() -{ - // delete render mesh - m_pRenderMesh = NULL; - - m_ownerInfo.pRenderNode = 0; -} - -void CDecal::RenderBigDecalOnTerrain(float fAlpha, float fScale, const SRenderingPassInfo& passInfo) -{ - float fRadius = m_fSize * fScale; - - // check terrain bounds - if (m_vPos.x < -fRadius || m_vPos.y < -fRadius) - { - return; - } - auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler(); - if (!terrain) - { - return; - } - - const AZ::Aabb terrainAabb = terrain->GetTerrainAabb(); - const float terrainSizeX = terrainAabb.GetXExtent(); - const float terrainSizeY = terrainAabb.GetYExtent(); - - if (m_vPos.x >= terrainSizeX + fRadius || m_vPos.y >= terrainSizeY + fRadius) - { - return; - } - - const AZ::Vector2 terrainGridResolution = terrain->GetTerrainGridResolution(); - const int nUsintSize = static_cast(AZ::GetMax(terrainGridResolution.GetX(), terrainGridResolution.GetY())); - fRadius += nUsintSize; - - const float terrainHeight = terrain->GetHeightFromFloats(m_vPos.x, m_vPos.y, AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP); - if (fabs(m_vPos.z - terrainHeight) > fRadius) - { - return; // too far from ground surface - } - // setup texgen - float fSize = m_fSize * fScale; - if (fSize < 0.05f) - { - return; - } - - // m_vUp and m_vRight are the scaled binormal and tangent - // The shader projects the vertex pass position onto these to calculate UVs - // However binormal and tangent are only half the height and width of the decal - // So we need to double them - Vec3 uvUp = m_vUp * 2.0f; - Vec3 uvRight = m_vRight * 2.0f; - - // Let T denote the tangent, B the binormal and P the vertex position in decal space - // The shader calculates UVs by projecting vertex position onto the tangent and binormal: - // U = dot( T, P ) - // V = dot( B, P ) - // UVs should range 0...1, so normalize by the length of the tangent and binormal: - // U = dot( normalize(T), P / length(T) ) - // V = dot( normalize(B), P / length(B) ) - // This is equivalent to: - // U = dot( T, P ) / ( length(T) * length(T) ) - // V = dot( B, P ) / ( length(B) * length(B) ) - // The length squared can be folded into the tangent and binormal: - // U = dot( T / lengthSq(T), P ) - // V = dot( B / lengthSq(B), P ) - // Hence: - uvUp /= uvUp.GetLengthSquared(); - uvRight /= uvRight.GetLengthSquared(); - - // S component - float correctScale(-1); - m_arrBigDecalRMCustomData[0] = correctScale * uvUp.x / fSize; - m_arrBigDecalRMCustomData[1] = correctScale * uvUp.y / fSize; - m_arrBigDecalRMCustomData[2] = correctScale * uvUp.z / fSize; - - // T component - m_arrBigDecalRMCustomData[4] = uvRight.x / fSize; - m_arrBigDecalRMCustomData[5] = uvRight.y / fSize; - m_arrBigDecalRMCustomData[6] = uvRight.z / fSize; - - // UV centering happens in the shader - // See shader function _TCModifyDecal - m_arrBigDecalRMCustomData[3] = 0.0f; - m_arrBigDecalRMCustomData[7] = 0.0f; - - // pass attenuation info - m_arrBigDecalRMCustomData[8] = 0; - m_arrBigDecalRMCustomData[9] = 0; - m_arrBigDecalRMCustomData[10] = 0; - m_arrBigDecalRMCustomData[11] = fSize * 2.0f; - - Vec3 vNormal(Vec3(correctScale* m_vUp).Cross(m_vRight).GetNormalized()); - m_arrBigDecalRMCustomData[12] = vNormal.x; - m_arrBigDecalRMCustomData[13] = vNormal.y; - m_arrBigDecalRMCustomData[14] = vNormal.z; - m_arrBigDecalRMCustomData[15] = 0; - - CRenderObject* pObj = GetIdentityCRenderObject(passInfo.ThreadID()); - if (!pObj) - { - return; - } - - pObj->m_II.m_Matrix.SetTranslation(m_vPos); - - pObj->m_fAlpha = fAlpha; - pObj->m_ObjFlags |= FOB_DECAL | FOB_DECAL_TEXGEN_2D; - pObj->m_nTextureID = -1; - //pObj->m_nTextureID1 = -1; - pObj->m_II.m_AmbColor = m_vAmbient; - - pObj->m_nSort = m_sortPrio; - - Plane planes[4]; - planes[0].SetPlane(m_vRight, m_vRight * m_fSize + m_vPos); - planes[1].SetPlane(-m_vRight, -m_vRight * m_fSize + m_vPos); - planes[2].SetPlane(m_vUp, m_vUp * m_fSize + m_vPos); - planes[3].SetPlane(-m_vUp, -m_vUp * m_fSize + m_vPos); -} diff --git a/Code/CryEngine/Cry3DEngine/DecalManager.cpp b/Code/CryEngine/Cry3DEngine/DecalManager.cpp deleted file mode 100644 index 930403a2fd..0000000000 --- a/Code/CryEngine/Cry3DEngine/DecalManager.cpp +++ /dev/null @@ -1,1791 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : draw, create decals on the world - - -#include "Cry3DEngine_precompiled.h" - -#include "DecalManager.h" -#include "3dEngine.h" -#include -#include "ObjMan.h" -#include "MatMan.h" - -#include - -#include "RenderMeshMerger.h" -#include "RenderMeshUtils.h" -#include "VisAreas.h" -#include "DecalRenderNode.h" -#include "Environment/OceanEnvironmentBus.h" - -#ifndef RENDER_MESH_TEST_DISTANCE - #define RENDER_MESH_TEST_DISTANCE (0.2f) -#endif - -static const int MAX_ASSEMBLE_SIZE = 5; - -CDecalManager::CDecalManager() -{ - m_nCurDecal = 0; - memset(m_arrbActiveDecals, 0, sizeof(m_arrbActiveDecals)); -} - -CDecalManager::~CDecalManager() -{ - CDecal::ResetStaticData(); -} - -bool CDecalManager::AdjustDecalPosition(CryEngineDecalInfo& DecalInfo, bool bMakeFatTest) -{ - Matrix34A objMat, objMatInv; - Matrix33 objRot, objRotInv; - - CStatObj* pEntObject = (CStatObj*)DecalInfo.ownerInfo.GetOwner(objMat); - if (!pEntObject || !pEntObject->GetRenderMesh() || !pEntObject->GetRenderTrisCount()) - { - return false; - } - - objRot = Matrix33(objMat); - objRot.NoScale(); // No scale. - objRotInv = objRot; - objRotInv.Invert(); - - float fWorldScale = objMat.GetColumn(0).GetLength(); // GetScale - float fWorldScaleInv = 1.0f / fWorldScale; - - // transform decal into object space - objMatInv = objMat; - objMatInv.Invert(); - - // put into normal object space hit direction of projection - Vec3 vOS_HitDir = objRotInv.TransformVector(DecalInfo.vHitDirection).GetNormalized(); - - // put into position object space hit position - Vec3 vOS_HitPos = objMatInv.TransformPoint(DecalInfo.vPos); - vOS_HitPos -= vOS_HitDir * RENDER_MESH_TEST_DISTANCE * fWorldScaleInv; - - _smart_ptr pMat = DecalInfo.ownerInfo.pRenderNode ? DecalInfo.ownerInfo.pRenderNode->GetMaterial() : NULL; - - Vec3 vOS_OutPos(0, 0, 0), vOS_OutNormal(0, 0, 0), vTmp; - IRenderMesh* pRM = pEntObject->GetRenderMesh(); - - AABB aabbRNode; - pRM->GetBBox(aabbRNode.min, aabbRNode.max); - Vec3 vOut(0, 0, 0); - if (!Intersect::Ray_AABB(Ray(vOS_HitPos, vOS_HitDir), aabbRNode, vOut)) - { - return false; - } - - if (!pRM || !pRM->GetVerticesCount()) - { - return false; - } - - if (RayRenderMeshIntersection(pRM, vOS_HitPos, vOS_HitDir, vOS_OutPos, vOS_OutNormal, false, 0, pMat)) - { - // now check that none of decal sides run across edges - Vec3 srcp = vOS_OutPos + 0.01f * fWorldScaleInv * vOS_OutNormal; /// Rise hit point a little bit above hit plane. - Vec3 vDecalNormal = vOS_OutNormal; - float fMaxHitDistance = 0.02f * fWorldScaleInv; - - // get decal directions - Vec3 vRi(0, 0, 0), vUp(0, 0, 0); - if (fabs(vOS_OutNormal.Dot(Vec3(0, 0, 1))) > 0.999f) - { // horiz surface - vRi = Vec3(0, 1, 0); - vUp = Vec3(1, 0, 0); - } - else - { - vRi = vOS_OutNormal.Cross(Vec3(0, 0, 1)); - vRi.Normalize(); - vUp = vOS_OutNormal.Cross(vRi); - vUp.Normalize(); - } - - vRi *= DecalInfo.fSize * 0.65f; - vUp *= DecalInfo.fSize * 0.65f; - - if (!bMakeFatTest || ( - RayRenderMeshIntersection(pRM, srcp + vUp, -vDecalNormal, vTmp, vTmp, true, fMaxHitDistance, pMat) && - RayRenderMeshIntersection(pRM, srcp - vUp, -vDecalNormal, vTmp, vTmp, true, fMaxHitDistance, pMat) && - RayRenderMeshIntersection(pRM, srcp + vRi, -vDecalNormal, vTmp, vTmp, true, fMaxHitDistance, pMat) && - RayRenderMeshIntersection(pRM, srcp - vRi, -vDecalNormal, vTmp, vTmp, true, fMaxHitDistance, pMat))) - { - DecalInfo.vPos = objMat.TransformPoint(vOS_OutPos + vOS_OutNormal * 0.001f * fWorldScaleInv); - DecalInfo.vNormal = objRot.TransformVector(vOS_OutNormal); - return true; - } - } - return false; -} - -struct HitPosInfo -{ - HitPosInfo() { memset(this, 0, sizeof(HitPosInfo)); } - Vec3 vPos, vNormal; - float fDistance; -}; - -int __cdecl CDecalManager__CmpHitPos(const void* v1, const void* v2) -{ - HitPosInfo* p1 = (HitPosInfo*)v1; - HitPosInfo* p2 = (HitPosInfo*)v2; - - if (p1->fDistance > p2->fDistance) - { - return 1; - } - else if (p1->fDistance < p2->fDistance) - { - return -1; - } - - return 0; -} - -bool CDecalManager::RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, - Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, float fMaxHitDistance, _smart_ptr pMat) -{ - SRayHitInfo hitInfo; - hitInfo.bUseCache = GetCVars()->e_DecalsHitCache != 0; - hitInfo.bInFirstHit = bFastTest; - hitInfo.inRay.origin = vInPos; - hitInfo.inRay.direction = vInDir.GetNormalized(); - hitInfo.inReferencePoint = vInPos; - hitInfo.fMaxHitDistance = fMaxHitDistance; - bool bRes = CRenderMeshUtils::RayIntersection(pRenderMesh, hitInfo, pMat); - vOutPos = hitInfo.vHitPos; - vOutNormal = hitInfo.vHitNormal; - return bRes; -} - -bool CDecalManager::SpawnHierarchical(const CryEngineDecalInfo& rootDecalInfo, CDecal* pCallerManagedDecal) -{ - // decal on terrain or simple decal on always static object - if (!rootDecalInfo.ownerInfo.pRenderNode) - { - return Spawn(rootDecalInfo, pCallerManagedDecal); - } - - bool bSuccess = false; - - AABB decalBoxWS; - float fSize = rootDecalInfo.fSize; - decalBoxWS.max = rootDecalInfo.vPos + Vec3(fSize, fSize, fSize); - decalBoxWS.min = rootDecalInfo.vPos - Vec3(fSize, fSize, fSize); - - for (int nEntitySlotId = 0; nEntitySlotId < 16; nEntitySlotId++) - { - Matrix34A entSlotMatrix; - entSlotMatrix.SetIdentity(); - CStatObj* _pStatObj = (CStatObj*)rootDecalInfo.ownerInfo.pRenderNode->GetEntityStatObj(nEntitySlotId, ~0, &entSlotMatrix, true); - if (_pStatObj) - { - if (_pStatObj->m_nFlags & STATIC_OBJECT_COMPOUND) - { - if (int nSubCount = _pStatObj->GetSubObjectCount()) - { // spawn decals on stat obj sub objects - CryEngineDecalInfo decalInfo = rootDecalInfo; - decalInfo.ownerInfo.nRenderNodeSlotId = nEntitySlotId; - if (rootDecalInfo.ownerInfo.nRenderNodeSlotSubObjectId >= 0) - { - decalInfo.ownerInfo.nRenderNodeSlotSubObjectId = rootDecalInfo.ownerInfo.nRenderNodeSlotSubObjectId; - bSuccess |= Spawn(decalInfo, pCallerManagedDecal); - } - else - { - for (int nSubId = 0; nSubId < nSubCount; nSubId++) - { - IStatObj::SSubObject& subObj = _pStatObj->SubObject(nSubId); - if (subObj.pStatObj && !subObj.bHidden && subObj.nType == STATIC_SUB_OBJECT_MESH) - { - Matrix34 subObjMatrix = entSlotMatrix * subObj.tm; - AABB subObjAABB = AABB::CreateTransformedAABB(subObjMatrix, subObj.pStatObj->GetAABB()); - if (Overlap::AABB_AABB(subObjAABB, decalBoxWS)) - { - decalInfo.ownerInfo.nRenderNodeSlotSubObjectId = nSubId; - bSuccess |= Spawn(decalInfo, pCallerManagedDecal); - } - } - } - } - } - } - else - { - AABB subObjAABB = AABB::CreateTransformedAABB(entSlotMatrix, _pStatObj->GetAABB()); - if (Overlap::AABB_AABB(subObjAABB, decalBoxWS)) - { - CryEngineDecalInfo decalInfo = rootDecalInfo; - decalInfo.ownerInfo.nRenderNodeSlotId = nEntitySlotId; - decalInfo.ownerInfo.nRenderNodeSlotSubObjectId = -1; // no childs - bSuccess |= Spawn(decalInfo, pCallerManagedDecal); - } - } - } - } - - return bSuccess; -} - -bool CDecalManager::Spawn(CryEngineDecalInfo DecalInfo, CDecal* pCallerManagedDecal) -{ - FUNCTION_PROFILER_3DENGINE; - - Vec3 vCamPos = GetSystem()->GetViewCamera().GetPosition(); - - // do not spawn if too far - float fZoom = GetObjManager() ? Get3DEngine()->GetZoomFactor() : 1.f; - float fDecalDistance = DecalInfo.vPos.GetDistance(vCamPos); - if (!pCallerManagedDecal && (fDecalDistance > Get3DEngine()->GetMaxViewDistance() || fDecalDistance * fZoom > DecalInfo.fSize * ENTITY_DECAL_DIST_FACTOR * 3.f)) - { - return false; - } - - int overlapCount(0); - int targetSize(0); - int overlapIds[MAX_ASSEMBLE_SIZE]; - - // do not spawn new decals if they could overlap the existing and similar ones - if (!pCallerManagedDecal && !GetCVars()->e_DecalsOverlapping && DecalInfo.fSize && !DecalInfo.bSkipOverlappingTest) - { - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i]) - { - // skip overlapping check if decals are very different in size - if ((m_arrDecals[i].m_iAssembleSize > 0) == DecalInfo.bAssemble) - { - float fSizeRatio = m_arrDecals[i].m_fWSSize / DecalInfo.fSize; - if (((m_arrDecals[i].m_iAssembleSize > 0) || (fSizeRatio > 0.5f && fSizeRatio < 2.f)) && m_arrDecals[i].m_nGroupId != DecalInfo.nGroupId) - { - float fDist = m_arrDecals[i].m_vWSPos.GetSquaredDistance(DecalInfo.vPos); - if (fDist < sqr(m_arrDecals[i].m_fWSSize * 0.5f + DecalInfo.fSize * 0.5f) && (DecalInfo.vNormal.Dot(m_arrDecals[i].m_vFront) > 0.f)) - { - if (DecalInfo.bAssemble && m_arrDecals[i].m_iAssembleSize < MAX_ASSEMBLE_SIZE) - { - if (overlapCount < MAX_ASSEMBLE_SIZE) - { - overlapIds[overlapCount] = i; - overlapCount++; - } - else - { - m_arrbActiveDecals[i] = false; - } - } - else - { - return true; - } - } - } - } - } - } - } - - float fAssembleSizeModifier(1.0f); - if (DecalInfo.bAssemble) - { - Vec3 avgPos(0.0f, 0.0f, 0.0f); - int validAssembles(0); - for (int i = 0; i < overlapCount; i++) - { - int id = overlapIds[i]; - - float fDist = m_arrDecals[id].m_vWSPos.GetSquaredDistance(DecalInfo.vPos); - float minDist = sqr(m_arrDecals[id].m_fWSSize * 0.4f); - if (fDist > minDist) - { - avgPos += m_arrDecals[id].m_vWSPos; - targetSize += m_arrDecals[id].m_iAssembleSize; - validAssembles++; - } - } - - if (overlapCount && !validAssembles) - { - return true; - } - - for (int i = 0; i < overlapCount; i++) - { - int id = overlapIds[i]; - m_arrbActiveDecals[id] = false; - } - - ++validAssembles; - ++targetSize; - avgPos += DecalInfo.vPos; - - if (targetSize > 1) - { - avgPos /= float(validAssembles); - DecalInfo.vPos = avgPos; - targetSize = min(targetSize, MAX_ASSEMBLE_SIZE); - - const float sizetable[MAX_ASSEMBLE_SIZE] = {1.0f, 1.5f, 2.3f, 3.5f, 3.5f}; - const char sValue[2] = { aznumeric_caster('0' + targetSize), 0 }; - cry_strcat(DecalInfo.szMaterialName, sValue); - fAssembleSizeModifier = sizetable[targetSize - 1]; - } - } - - - if (GetCVars()->e_Decals > 1) - { - DrawSphere(DecalInfo.vPos, DecalInfo.fSize); - } - - // update lifetime for near decals under control by the decal manager - if (!pCallerManagedDecal) - { - if (DecalInfo.fSize > 1 && GetCVars()->e_DecalsNeighborMaxLifeTime) - { // force near decals to fade faster - float fCurrTime = GetTimer()->GetCurrTime(); - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i] && m_arrDecals[i].m_nGroupId != DecalInfo.nGroupId) - { - if (m_arrDecals[i].m_vWSPos.GetSquaredDistance(DecalInfo.vPos) < sqr(m_arrDecals[i].m_fWSSize / 1.5f + DecalInfo.fSize / 2.0f)) - { - if ((m_arrDecals[i]).m_fLifeBeginTime < fCurrTime - 0.1f) - { - if (m_arrDecals[i].m_fLifeTime > GetCVars()->e_DecalsNeighborMaxLifeTime) - { - if (m_arrDecals[i].m_fLifeTime < 10000) // decals spawn by cut scenes need to stay - { - m_arrDecals[i].m_fLifeTime = GetCVars()->e_DecalsNeighborMaxLifeTime; - } - } - } - } - } - } - } - - // loop position in array - m_nCurDecal = (m_nCurDecal + 1) & (DECAL_COUNT - 1); - //if(m_nCurDecal>=DECAL_COUNT) - // m_nCurDecal=0; - } - - // create reference to decal which is to be filled - CDecal& newDecal(pCallerManagedDecal ? *pCallerManagedDecal : m_arrDecals[ m_nCurDecal ]); - - newDecal.m_bDeferred = DecalInfo.bDeferred; - - newDecal.m_iAssembleSize = targetSize; - // free old pRM - newDecal.FreeRenderData(); - - newDecal.m_nGroupId = DecalInfo.nGroupId; - - // get material if specified - newDecal.m_pMaterial = 0; - - if (DecalInfo.szMaterialName[0] != '\0') - { - newDecal.m_pMaterial = GetMatMan()->LoadMaterial(DecalInfo.szMaterialName, false, true); - if (!newDecal.m_pMaterial) - { - newDecal.m_pMaterial = GetMatMan()->LoadMaterial("EngineAssets/Materials/Decals/Default", true, true); - newDecal.m_pMaterial->AddRef(); - Warning("CDecalManager::Spawn: Specified decal material \"%s\" not found!\n", DecalInfo.szMaterialName); - } - } - - newDecal.m_sortPrio = DecalInfo.sortPrio; - - // set up user defined decal basis if provided - bool useDefinedUpRight(false); - Vec3 userDefinedUp; - Vec3 userDefinedRight; - if (DecalInfo.pExplicitRightUpFront) - { - userDefinedRight = DecalInfo.pExplicitRightUpFront->GetColumn(0); - userDefinedUp = DecalInfo.pExplicitRightUpFront->GetColumn(1); - DecalInfo.vNormal = DecalInfo.pExplicitRightUpFront->GetColumn(2); - useDefinedUpRight = true; - } - - // just in case - DecalInfo.vNormal.NormalizeSafe(); - - // remember object we need to follow - newDecal.m_ownerInfo.nRenderNodeSlotId = DecalInfo.ownerInfo.nRenderNodeSlotId; - newDecal.m_ownerInfo.nRenderNodeSlotSubObjectId = DecalInfo.ownerInfo.nRenderNodeSlotSubObjectId; - - newDecal.m_vWSPos = DecalInfo.vPos; - newDecal.m_fWSSize = DecalInfo.fSize * fAssembleSizeModifier; - - // If owner entity and object is specified - make decal use entity geometry - float _fObjScale = 1.f; - - Matrix34A _objMat; - Matrix33 worldRot; - IStatObj* pStatObj = DecalInfo.ownerInfo.GetOwner(_objMat); - if (pStatObj) - { - worldRot = Matrix33(_objMat); - _objMat.Invert(); - } - - float fWrapMinSize = GetFloatCVar(e_DecalsDefferedDynamicMinSize); - - if (DecalInfo.ownerInfo.pRenderNode && DecalInfo.ownerInfo.nRenderNodeSlotId >= 0 && (DecalInfo.fSize > fWrapMinSize || pCallerManagedDecal) && !DecalInfo.bDeferred) - { - newDecal.m_eDecalType = eDecalType_OS_OwnersVerticesUsed; - - IRenderMesh* pSourceRenderMesh = NULL; - - if (pStatObj) - { - pSourceRenderMesh = pStatObj->GetRenderMesh(); - } - - if (!pSourceRenderMesh) - { - return false; - } - - // transform decal into object space - Matrix33 objRotInv = Matrix33(_objMat); - objRotInv.NoScale(); - - if (useDefinedUpRight) - { - userDefinedRight = objRotInv.TransformVector(userDefinedRight).GetNormalized(); - userDefinedUp = objRotInv.TransformVector(userDefinedUp).GetNormalized(); - assert(fabsf(DecalInfo.vNormal.Dot(-DecalInfo.vHitDirection.GetNormalized()) - 1.0f) < 1e-4f); - } - - // make decals smaller but longer if hit direction is near perpendicular to surface normal - float fSizeModificator = 0.25f + 0.75f * fabs(DecalInfo.vHitDirection.GetNormalized().Dot(DecalInfo.vNormal)); - - // put into normal object space hit direction of projection - DecalInfo.vNormal = -objRotInv.TransformVector((DecalInfo.vHitDirection - DecalInfo.vNormal * 0.25f).GetNormalized()); - - if (!DecalInfo.vNormal.IsZero()) - { - DecalInfo.vNormal.Normalize(); - } - - // put into position object space hit position - DecalInfo.vPos = _objMat.TransformPoint(DecalInfo.vPos); - - // find object scale - float fObjScale = 1.f; - Vec3 vTest(0, 0, 1.f); - vTest = _objMat.TransformVector(vTest); - fObjScale = 1.f / vTest.len(); - - if (fObjScale < 0.01f) - { - return false; - } - - // transform size into object space - DecalInfo.fSize /= fObjScale; - - DecalInfo.fSize *= (DecalInfo.bAssemble ? fAssembleSizeModifier : fSizeModificator); - - if (DecalInfo.bForceEdge) - { - SRayHitInfo hitInfo; - hitInfo.bUseCache = GetCVars()->e_DecalsHitCache != 0; - hitInfo.bInFirstHit = false; - hitInfo.inRay.origin = DecalInfo.vPos + DecalInfo.vNormal; - hitInfo.inRay.direction = -DecalInfo.vNormal; - hitInfo.inReferencePoint = DecalInfo.vPos + DecalInfo.vNormal; - hitInfo.inRetTriangle = true; - CRenderMeshUtils::RayIntersection(pSourceRenderMesh, hitInfo, pStatObj ? pStatObj->GetMaterial() : NULL); - - MoveToEdge(pSourceRenderMesh, DecalInfo.fSize, hitInfo.vHitPos, hitInfo.vHitNormal, hitInfo.vTri0, hitInfo.vTri1, hitInfo.vTri2); - DecalInfo.vPos = hitInfo.vHitPos; - DecalInfo.vNormal = hitInfo.vHitNormal; - } - - // make decal geometry - if (!newDecal.m_pMaterial) - { - // I'm not sure what consequences will be if m_pMaterial is null, so we warn about it just in case. Feel free to remove this if you hit it and all is well. - Warning("CDecalManager::Spawn: Decal material is null while creating BigDecalRenderMesh"); - } - newDecal.m_pRenderMesh = MakeBigDecalRenderMesh(pSourceRenderMesh, DecalInfo.vPos, DecalInfo.fSize, DecalInfo.vNormal, newDecal.m_pMaterial, pStatObj ? pStatObj->GetMaterial() : NULL); - - if (!newDecal.m_pRenderMesh) - { - return false; // no geometry found - } - } - else if (!DecalInfo.ownerInfo.pRenderNode && DecalInfo.ownerInfo.pDecalReceivers && (DecalInfo.fSize > fWrapMinSize || pCallerManagedDecal) && !DecalInfo.bDeferred) - { - newDecal.m_eDecalType = eDecalType_WS_Merged; - - assert(!newDecal.m_pRenderMesh); - - // put into normal hit direction of projection - DecalInfo.vNormal = -DecalInfo.vHitDirection; - if (!DecalInfo.vNormal.IsZero()) - { - DecalInfo.vNormal.Normalize(); - } - - Vec3 vSize(DecalInfo.fSize * 1.333f, DecalInfo.fSize * 1.333f, DecalInfo.fSize * 1.333f); - AABB decalAABB(DecalInfo.vPos - vSize, DecalInfo.vPos + vSize); - - // build list of objects - PodArray lstRMI; - for (int nObj = 0; nObj < DecalInfo.ownerInfo.pDecalReceivers->Count(); nObj++) - { - IRenderNode* pDecalOwner = DecalInfo.ownerInfo.pDecalReceivers->Get(nObj)->pNode; - Matrix34A objMat; - if (IStatObj* pEntObject = pDecalOwner->GetEntityStatObj(DecalInfo.ownerInfo.nRenderNodeSlotId, 0, &objMat)) - { - SRenderMeshInfoInput rmi; - rmi.pMesh = pEntObject->GetRenderMesh(); - rmi.pMat = pEntObject->GetMaterial(); - rmi.mat = objMat; - - if (rmi.pMesh) - { - AABB transAABB = AABB::CreateTransformedAABB(rmi.mat, pEntObject->GetAABB()); - if (Overlap::AABB_AABB(decalAABB, transAABB)) - { - lstRMI.Add(rmi); - } - } - else - if (int nSubObjCount = pEntObject->GetSubObjectCount()) - { // multi sub objects - for (int nSubObj = 0; nSubObj < nSubObjCount; nSubObj++) - { - IStatObj::SSubObject* pSubObj = pEntObject->GetSubObject(nSubObj); - if (pSubObj->pStatObj) - { - rmi.pMesh = pSubObj->pStatObj->GetRenderMesh(); - rmi.pMat = pSubObj->pStatObj->GetMaterial(); - rmi.mat = objMat * pSubObj->tm; - if (rmi.pMesh) - { - AABB transAABB = AABB::CreateTransformedAABB(rmi.mat, pSubObj->pStatObj->GetAABB()); - if (Overlap::AABB_AABB(decalAABB, transAABB)) - { - lstRMI.Add(rmi); - } - } - } - } - } - } - } - - if (!lstRMI.Count()) - { - return false; - } - - SDecalClipInfo DecalClipInfo; - DecalClipInfo.vPos = DecalInfo.vPos; - DecalClipInfo.fRadius = DecalInfo.fSize; - DecalClipInfo.vProjDir = DecalInfo.vNormal; - - PodArray outRenderMeshes; - CRenderMeshMerger Merger; - SMergeInfo info; - info.sMeshName = "MergedDecal"; - info.sMeshType = "MergedDecal"; - info.pDecalClipInfo = &DecalClipInfo; - info.vResultOffset = DecalInfo.vPos; - newDecal.m_pRenderMesh = Merger.MergeRenderMeshes(lstRMI.GetElements(), lstRMI.Count(), outRenderMeshes, info); - - if (!newDecal.m_pRenderMesh) - { - return false; // no geometry found - } - assert(newDecal.m_pRenderMesh->GetChunks().size() == 1); - } - else - if (DecalInfo.ownerInfo.pRenderNode && - (DecalInfo.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_RenderComponent || - DecalInfo.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_StaticMeshRenderComponent || - DecalInfo.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_DynamicMeshRenderComponent || - DecalInfo.ownerInfo.pRenderNode->GetRenderNodeType() == eERType_SkinnedMeshRenderComponent) && - DecalInfo.ownerInfo.nRenderNodeSlotId >= 0) - { - newDecal.m_eDecalType = eDecalType_OS_SimpleQuad; - - Matrix34A objMat; - - // transform decal from world space into entity space - IStatObj* pEntObject = DecalInfo.ownerInfo.GetOwner(objMat); - if (!pEntObject) - { - return false; - } - assert(pEntObject); - objMat.Invert(); - - if (useDefinedUpRight) - { - userDefinedRight = objMat.TransformVector(userDefinedRight).GetNormalized(); - userDefinedUp = objMat.TransformVector(userDefinedUp).GetNormalized(); - assert(fabsf(DecalInfo.vNormal.Dot(-DecalInfo.vHitDirection.GetNormalized()) - 1.0f) < 1e-4f); - } - - DecalInfo.vNormal = objMat.TransformVector(DecalInfo.vNormal).GetNormalized(); - DecalInfo.vPos = objMat.TransformPoint(DecalInfo.vPos); - - // find object scale - Vec3 vTest(0, 0, 1.f); - vTest = objMat.TransformVector(vTest); - _fObjScale = 1.f / vTest.len(); - - DecalInfo.fSize /= _fObjScale; - } - else - { - bool isHole = true; - auto enumerationCallback = [&](AzFramework::Terrain::TerrainDataRequests* terrain) -> bool - { - isHole = false; - if (!DecalInfo.preventDecalOnGround && DecalInfo.fSize > (fWrapMinSize * 2.f) && !DecalInfo.ownerInfo.pRenderNode && - (DecalInfo.vPos.z - terrain->GetHeightFromFloats(DecalInfo.vPos.x, DecalInfo.vPos.y)) < DecalInfo.fSize && !DecalInfo.bDeferred) - { - newDecal.m_eDecalType = eDecalType_WS_OnTheGround; - - const AZ::Vector2 terrainGridResolution = terrain->GetTerrainGridResolution(); - const float unitSizeX = terrainGridResolution.GetX(); - const float unitSizeY = terrainGridResolution.GetY(); - - const float x1 = (DecalInfo.vPos.x - DecalInfo.fSize) / unitSizeX * unitSizeX - unitSizeX; - const float x2 = (DecalInfo.vPos.x + DecalInfo.fSize) / unitSizeX * unitSizeX + unitSizeX; - const float y1 = (DecalInfo.vPos.y - DecalInfo.fSize) / unitSizeY * unitSizeY - unitSizeY; - const float y2 = (DecalInfo.vPos.y + DecalInfo.fSize) / unitSizeY * unitSizeY + unitSizeY; - - for (float x = x1; x <= x2; x += unitSizeX) - { - for (float y = y1; y <= y2; y += unitSizeY) - { - if (terrain->GetIsHoleFromFloats(x, y)) - { - isHole = true; - return false; - } - } - } - } - // Only one handler should exist. - return false; - }; - AzFramework::Terrain::TerrainDataRequestBus::EnumerateHandlers(enumerationCallback); - if (isHole) - { - return false; - } - else - { - newDecal.m_eDecalType = eDecalType_WS_SimpleQuad; - } - - DecalInfo.ownerInfo.pRenderNode = NULL; - } - - // spawn - if (!useDefinedUpRight) - { - if (DecalInfo.vNormal.Dot(Vec3(0, 0, 1)) > 0.999f) - { // floor - newDecal.m_vRight = Vec3(0, 1, 0); - newDecal.m_vUp = Vec3(-1, 0, 0); - } - else if (DecalInfo.vNormal.Dot(Vec3(0, 0, -1)) > 0.999f) - { // ceil - newDecal.m_vRight = Vec3(1, 0, 0); - newDecal.m_vUp = Vec3(0, -1, 0); - } - else if (!DecalInfo.vNormal.IsZero()) - { - newDecal.m_vRight = DecalInfo.vNormal.Cross(Vec3(0, 0, 1)); - newDecal.m_vRight.Normalize(); - newDecal.m_vUp = DecalInfo.vNormal.Cross(newDecal.m_vRight); - newDecal.m_vUp.Normalize(); - } - - // rotate vectors - if (!DecalInfo.vNormal.IsZero()) - { - AngleAxis rotation(DecalInfo.fAngle, DecalInfo.vNormal); - newDecal.m_vRight = rotation * newDecal.m_vRight; - newDecal.m_vUp = rotation * newDecal.m_vUp; - } - } - else - { - newDecal.m_vRight = userDefinedRight; - newDecal.m_vUp = userDefinedUp; - } - - newDecal.m_vFront = DecalInfo.vNormal; - - newDecal.m_vPos = DecalInfo.vPos; - newDecal.m_vPos += DecalInfo.vNormal * 0.001f / _fObjScale; - - newDecal.m_fSize = DecalInfo.fSize; - newDecal.m_fLifeTime = DecalInfo.fLifeTime * GetCVars()->e_DecalsLifeTimeScale; - assert(!DecalInfo.pIStatObj); // not used -> not supported - - newDecal.m_ownerInfo.pRenderNode = DecalInfo.ownerInfo.pRenderNode; - if (DecalInfo.ownerInfo.pRenderNode) - { - DecalInfo.ownerInfo.pRenderNode->m_nInternalFlags |= IRenderNode::DECAL_OWNER; - } - - newDecal.m_fGrowTime = DecalInfo.fGrowTime; - newDecal.m_fGrowTimeAlpha = DecalInfo.fGrowTimeAlpha; - newDecal.m_fLifeBeginTime = GetTimer()->GetCurrTime(); - - if (DecalInfo.pIStatObj && !pCallerManagedDecal) - { - //assert(!"Geometry decals neede to be re-debugged"); - DecalInfo.pIStatObj->AddRef(); - } - - if (!pCallerManagedDecal) - { - m_arrbActiveDecals[ m_nCurDecal ] = true; - ++m_nCurDecal; - } - -#ifdef _DEBUG - if (newDecal.m_ownerInfo.pRenderNode) - { - cry_strcpy(newDecal.m_decalOwnerEntityClassName, newDecal.m_ownerInfo.pRenderNode->GetEntityClassName()); - cry_strcpy(newDecal.m_decalOwnerName, newDecal.m_ownerInfo.pRenderNode->GetName()); - newDecal.m_decalOwnerType = newDecal.m_ownerInfo.pRenderNode->GetRenderNodeType(); - } - else - { - newDecal.m_decalOwnerEntityClassName[0] = '\0'; - newDecal.m_decalOwnerName[0] = '\0'; - newDecal.m_decalOwnerType = eERType_NotRenderNode; - } -#endif - - return true; -} - -void CDecalManager::Update(const float fFrameTime) -{ - CryPrefetch(&m_arrbActiveDecals[0]); - CryPrefetch(&m_arrbActiveDecals[128]); - CryPrefetch(&m_arrbActiveDecals[256]); - CryPrefetch(&m_arrbActiveDecals[384]); - - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i]) - { - IRenderNode* pRenderNode = m_arrDecals[i].m_ownerInfo.pRenderNode; - if (m_arrDecals[i].Update(m_arrbActiveDecals[i], fFrameTime)) - { - if (pRenderNode && m_arrTempUpdatedOwners.Find(pRenderNode) < 0) - { - m_arrTempUpdatedOwners.Add(pRenderNode); - } - } - } - } - - for (int i = 0; i < m_arrTempUpdatedOwners.Count(); i++) - { - m_arrTempUpdatedOwners[i]->m_nInternalFlags &= ~IRenderNode::UPDATE_DECALS; - } - - m_arrTempUpdatedOwners.Clear(); -} - - -void CDecalManager::Render(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!passInfo.RenderDecals() || !GetObjManager()) - { - return; - } - - float fCurrTime = GetTimer()->GetCurrTime(); - float fZoom = passInfo.GetZoomFactor(); - - static int nLastUpdateStreamingPrioriryRoundId = 0; - bool bPrecacheMaterial = nLastUpdateStreamingPrioriryRoundId != GetObjManager()->GetUpdateStreamingPrioriryRoundId(); - nLastUpdateStreamingPrioriryRoundId = GetObjManager()->GetUpdateStreamingPrioriryRoundId(); - - static int nLastUpdateStreamingPrioriryRoundIdFast = 0; - bool bPrecacheMaterialFast = nLastUpdateStreamingPrioriryRoundIdFast != GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast(); - nLastUpdateStreamingPrioriryRoundIdFast = GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast(); - - const CCamera& rCamera = passInfo.GetCamera(); - - // draw - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i]) - { - CDecal* pDecal = &m_arrDecals[i]; - pDecal->m_vWSPos = pDecal->GetWorldPosition(); - float fDist = rCamera.GetPosition().GetDistance(pDecal->m_vWSPos) * fZoom; - float fMaxViewDist = pDecal->m_fWSSize * ENTITY_DECAL_DIST_FACTOR * 3.0f; - if (fDist < fMaxViewDist) - { - if (rCamera.IsSphereVisible_F(Sphere(pDecal->m_vWSPos, pDecal->m_fWSSize))) - { - bool bAfterWater = GetObjManager()->IsAfterWater(pDecal->m_vWSPos, passInfo); - if (pDecal->m_pMaterial) - { - if (passInfo.IsGeneralPass()) - { - if (bPrecacheMaterialFast && (fDist < GetFloatCVar(e_StreamPredictionMinFarZoneDistance))) - { - if (CMatInfo* pMatInfo = (CMatInfo*)pDecal->m_pMaterial.get()) - { - pMatInfo->PrecacheMaterial(fDist, NULL, true); - } - } - - if (bPrecacheMaterial) - { - if (CMatInfo* pMatInfo = (CMatInfo*)pDecal->m_pMaterial.get()) - { - pMatInfo->PrecacheMaterial(fDist, NULL, false); - } - } - } - - // TODO: take entity orientation into account - Vec3 vSize(pDecal->m_fWSSize, pDecal->m_fWSSize, pDecal->m_fWSSize); - AABB aabb(pDecal->m_vWSPos - vSize, pDecal->m_vWSPos + vSize); - - - float fDistFading = SATURATE((1.f - fDist / fMaxViewDist) * DIST_FADING_FACTOR); - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - pDecal->Render(fCurrTime, bAfterWater, fDistFading, fDist, passInfo, rendItemSorter); - - if (GetCVars()->e_Decals > 1) - { - Vec3 vCenter = pDecal->m_vWSPos; - AABB aabbCenter(vCenter - vSize * 0.05f, vCenter + vSize * 0.05f); - - DrawBBox(aabb); - DrawBBox(aabbCenter, Col_Yellow); - - Vec3 vNormal(Vec3(pDecal->m_vUp).Cross(-pDecal->m_vRight).GetNormalized()); - - Matrix34A objMat; - IStatObj* pEntObject = pDecal->m_ownerInfo.GetOwner(objMat); - if (pEntObject) - { - vNormal = objMat.TransformVector(vNormal).GetNormalized(); - } - - DrawLine(vCenter, vCenter + vNormal * pDecal->m_fWSSize); - - if (pDecal->m_pRenderMesh) - { - pDecal->m_pRenderMesh->GetBBox(aabb.min, aabb.max); - DrawBBox(aabb, Col_Red); - } - } - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CDecalManager::OnEntityDeleted(IRenderNode* pRenderNode) -{ - FUNCTION_PROFILER_3DENGINE; - - // remove decals of this entity - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i]) - { - if (m_arrDecals[i].m_ownerInfo.pRenderNode == pRenderNode) - { - if (GetCVars()->e_Decals == 2) - { - CDecal& decal = m_arrDecals[i]; - Vec3 vPos = decal.GetWorldPosition(); - const char* szOwnerName = "none"; -#ifdef _DEBUG - szOwnerName = decal.m_decalOwnerName; -#endif - PrintMessage("Debug: C3DEngine::OnDecalDeleted: Pos=(%.1f,%.1f,%.1f) Size=%.2f DecalMaterial=%s OwnerName=%s", - vPos.x, vPos.y, vPos.z, decal.m_fSize, decal.m_pMaterial ? decal.m_pMaterial->GetName() : "none", szOwnerName); - } - - m_arrbActiveDecals[i] = false; - m_arrDecals[i].FreeRenderData(); - } - } - } - - // update decal render nodes - PodArray lstObjects; - Get3DEngine()->GetObjectsByTypeGlobal(lstObjects, eERType_Decal, NULL); - - if (Get3DEngine()->GetVisAreaManager()) - { - Get3DEngine()->GetVisAreaManager()->GetObjectsByType(lstObjects, eERType_Decal, NULL); - } - - for (int i = 0; i < lstObjects.Count(); i++) - { - ((CDecalRenderNode*)lstObjects[i])->RequestUpdate(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CDecalManager::OnRenderMeshDeleted(IRenderMesh* pRenderMesh) -{ - // remove decals of this entity - for (int i = 0; i < DECAL_COUNT; i++) - { - if (m_arrbActiveDecals[i]) - { - if ( - (m_arrDecals[i].m_ownerInfo.pRenderNode && ( - m_arrDecals[i].m_ownerInfo.pRenderNode->GetRenderMesh(0) == pRenderMesh || - m_arrDecals[i].m_ownerInfo.pRenderNode->GetRenderMesh(1) == pRenderMesh || - m_arrDecals[i].m_ownerInfo.pRenderNode->GetRenderMesh(2) == pRenderMesh)) - || - (m_arrDecals[i].m_pRenderMesh && m_arrDecals[i].m_pRenderMesh->GetVertexContainer() == pRenderMesh) - ) - { - m_arrbActiveDecals[i] = false; - m_arrDecals[i].FreeRenderData(); - // PrintMessage("CDecalManager::OnRenderMeshDeleted succseed"); - } - } - } -} - -void CDecalManager::MoveToEdge(IRenderMesh* pRM, const float fRadius, Vec3& vOutPos, Vec3& vOutNormal, const Vec3& vTri0, const Vec3& vTri1, const Vec3& vTri2) -{ - FUNCTION_PROFILER_3DENGINE; - - AABB boxRM; - pRM->GetBBox(boxRM.min, boxRM.max); - Sphere sp(vOutPos, fRadius); - if (!Overlap::Sphere_AABB(sp, boxRM)) - { - return; - } - - // get position offset and stride - int nPosStride = 0; - byte* pPos = pRM->GetPosPtr(nPosStride, FSL_READ); - - vtx_idx* pInds = pRM->GetIndexPtr(FSL_READ); - - if (!pPos || !pInds) - { - return; - } - -#if !defined(NDEBUG) - int nInds = pRM->GetIndicesCount(); -#endif - - // if(nInds>6000) - // return; // skip insane objects - - assert(nInds % 3 == 0); - - if (!vOutNormal.IsZero()) - { - vOutNormal.Normalize(); - } - else - { - return; - } - - float bestDot = 2.0f; - Vec3 bestNormal(ZERO); - Vec3 bestPoint(ZERO); - - // render tris - TRenderChunkArray& Chunks = pRM->GetChunks(); - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - - for (int i = pChunk->nFirstIndexId; i < nLastIndexId; i += 3) - { - assert(pInds[i + 0] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 1] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 2] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 0] >= pChunk->nFirstVertId); - assert(pInds[i + 1] >= pChunk->nFirstVertId); - assert(pInds[i + 2] >= pChunk->nFirstVertId); - - // get tri vertices - Vec3 v0 = (*(Vec3*)&pPos[nPosStride * pInds[i + 0]]); - Vec3 v1 = (*(Vec3*)&pPos[nPosStride * pInds[i + 1]]); - Vec3 v2 = (*(Vec3*)&pPos[nPosStride * pInds[i + 2]]); - - bool first = false; - bool second = false; - bool third = false; - - if (v0 == vTri0 || v0 == vTri1 || v0 == vTri2) - { - first = true; - } - else if (v1 == vTri0 || v1 == vTri1 || v1 == vTri2) - { - second = true; - } - else if (v2 == vTri0 || v2 == vTri1 || v2 == vTri2) - { - third = true; - } - - if (first || second || third) - { - // get triangle normal - Vec3 vNormal = (v1 - v0).Cross(v2 - v0).GetNormalized(); - - float testDot = vNormal.Dot(vOutNormal); - if (testDot < bestDot) - { - bestDot = testDot; - bestNormal = vNormal; - if (first) - { - bestPoint = v0; - } - else if (second) - { - bestPoint = v1; - } - else if (third) - { - bestPoint = v2; - } - } - } - } - } - - if (bestDot < 1.0f) - { - vOutNormal = (bestNormal + vOutNormal).GetNormalized(); - vOutPos.x = bestPoint.x; - vOutPos.y = bestPoint.y; - } -} - -void CDecalManager::FillBigDecalIndices(IRenderMesh* pRM, Vec3 vPos, float fRadius, Vec3 vProjDirIn, PodArray* plstIndices, _smart_ptr pMat, AABB& meshBBox, float& texelAreaDensity) -{ - FUNCTION_PROFILER_3DENGINE; - - AABB boxRM; - pRM->GetBBox(boxRM.min, boxRM.max); - - Sphere sp(vPos, fRadius); - if (!Overlap::Sphere_AABB(sp, boxRM)) - { - return; - } - - IRenderMesh::ThreadAccessLock lockrm(pRM); - HWVSphere hwSphere(sp); - - // get position offset and stride - int nInds = pRM->GetIndicesCount(); - - if (nInds > GetCVars()->e_DecalsMaxTrisInObject * 3) - { - return; // skip insane objects - } - CDecalRenderNode::m_nFillBigDecalIndicesCounter++; - - int nPosStride = 0; - byte* pPos = pRM->GetPosPtr(nPosStride, FSL_READ); - if (!pPos) - { - return; - } - vtx_idx* pInds = pRM->GetIndexPtr(FSL_READ); - if (!pInds) - { - return; - } - - assert(nInds % 3 == 0); - - plstIndices->Clear(); - - bool bPointProj(vProjDirIn.IsZeroFast()); - - if (!bPointProj) - { - vProjDirIn.Normalize(); - } - - if (!pMat) - { - return; - } - - plstIndices->PreAllocate(16); - - hwvec3 vProjDir = HWVLoadVecUnaligned(&vProjDirIn); - - int usedTrianglesTotal = 0; - - TRenderChunkArray& Chunks = pRM->GetChunks(); - - { - hwvec3 meshBBoxMin = HWVLoadVecUnaligned(&meshBBox.min); - hwvec3 meshBBoxMax = HWVLoadVecUnaligned(&meshBBox.max); - - SIMDFConstant(fEpsilon, 0.001f); - - const int kNumChunks = Chunks.size(); - - if (bPointProj) - { - hwvec3 hwvPos = HWVLoadVecUnaligned(&vPos); - - for (int nChunkId = 0; nChunkId < kNumChunks; nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - - PrefetchLine(&Chunks[nChunkId + 1], 0); - PrefetchLine(&pInds[pChunk->nFirstIndexId], 0); - - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - const SShaderItem& shaderItem = pMat->GetShaderItem(pChunk->m_nMatID); - - if (!shaderItem.m_pShader || !shaderItem.m_pShaderResources) - { - continue; - } - - if (shaderItem.m_pShader->GetFlags() & (EF_NODRAW | EF_DECAL)) - { - continue; - } - - PrefetchLine(plstIndices->GetElements(), 0); - - int usedTriangles = 0; - int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - - int i = pChunk->nFirstIndexId; - - int iPosIndex0 = nPosStride * pInds[i + 0]; - int iPosIndex1 = nPosStride * pInds[i + 1]; - int iPosIndex2 = nPosStride * pInds[i + 2]; - - for (; i < nLastIndexId; i += 3) - { - assert(pInds[i + 0] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 1] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 2] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 0] >= pChunk->nFirstVertId); - assert(pInds[i + 1] >= pChunk->nFirstVertId); - assert(pInds[i + 2] >= pChunk->nFirstVertId); - - PrefetchLine(&pInds[i], 128); - - int iNextPosIndex0 = 0; - int iNextPosIndex1 = 0; - int iNextPosIndex2 = 0; - - if (i + 5 < nLastIndexId) - { - iNextPosIndex0 = nPosStride * pInds[i + 3]; - iNextPosIndex1 = nPosStride * pInds[i + 4]; - iNextPosIndex2 = nPosStride * pInds[i + 5]; - - PrefetchLine(&pPos[iNextPosIndex0], 0); - PrefetchLine(&pPos[iNextPosIndex1], 0); - PrefetchLine(&pPos[iNextPosIndex2], 0); - } - - - // get tri vertices - const hwvec3 v0 = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iPosIndex0])); - const hwvec3 v1 = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iPosIndex1])); - const hwvec3 v2 = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iPosIndex2])); - - // test the face - hwvec3 v0v1Diff = HWVSub(v0, v1); - hwvec3 v2v1Diff = HWVSub(v2, v1); - hwvec3 vPosv0Diff = HWVSub(hwvPos, v0); - - hwvec3 vCrossResult = HWVCross(v0v1Diff, v2v1Diff); - - simdf fDot = HWV3Dot(vPosv0Diff, vCrossResult); - - if (SIMDFGreaterThan(fDot, fEpsilon)) - { - if (Overlap::HWVSphere_TriangleFromPoints(hwSphere, v0, v1, v2)) - { - plstIndices->AddList(&pInds[i], 3); - - hwvec3 triBBoxMax1 = HWVMax(v1, v0); - hwvec3 triBBoxMax2 = HWVMax(meshBBoxMax, v2); - - hwvec3 triBBoxMin1 = HWVMin(v1, v0); - hwvec3 triBBoxMin2 = HWVMin(meshBBoxMin, v2); - - meshBBoxMax = HWVMax(triBBoxMax1, triBBoxMax2); - meshBBoxMin = HWVMin(triBBoxMin1, triBBoxMin2); - - usedTriangles++; - } - } - - iPosIndex0 = iNextPosIndex0; - iPosIndex1 = iNextPosIndex1; - iPosIndex2 = iNextPosIndex2; - } - - if (pChunk->m_texelAreaDensity > 0.0f && pChunk->m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += usedTriangles * pChunk->m_texelAreaDensity; - usedTrianglesTotal += usedTriangles; - } - } - } - else - { - for (int nChunkId = 0; nChunkId < kNumChunks; nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - - if (nChunkId + 1 < kNumChunks) - { - PrefetchLine(&Chunks[nChunkId + 1], 0); - } - PrefetchLine(&pInds[pChunk->nFirstIndexId], 0); - - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - const SShaderItem& shaderItem = pMat->GetShaderItem(pChunk->m_nMatID); - - if (!shaderItem.m_pShader || !shaderItem.m_pShaderResources) - { - continue; - } - - if (shaderItem.m_pShader->GetFlags() & (EF_NODRAW | EF_DECAL)) - { - continue; - } - - PrefetchLine(plstIndices->GetElements(), 0); - - int usedTriangles = 0; - const int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - const int nLastValidIndexId = nLastIndexId - 1; - - int i = pChunk->nFirstIndexId; - - int iNextPosIndex0 = 0; - int iNextPosIndex1 = 0; - int iNextPosIndex2 = 0; - - if (i + 5 < nLastIndexId) - { - iNextPosIndex0 = nPosStride * pInds[i + 3]; - iNextPosIndex1 = nPosStride * pInds[i + 4]; - iNextPosIndex2 = nPosStride * pInds[i + 5]; - - PrefetchLine(&pPos[iNextPosIndex0], 0); - PrefetchLine(&pPos[iNextPosIndex1], 0); - PrefetchLine(&pPos[iNextPosIndex2], 0); - } - - hwvec3 v0Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[nPosStride * pInds[i + 0]])); - hwvec3 v1Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[nPosStride * pInds[i + 1]])); - hwvec3 v2Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[nPosStride * pInds[i + 2]])); - - const int nLastIndexToUse = nLastIndexId - 3; - - for (; i < nLastIndexToUse; i += 3) - { - assert(pInds[i + 0] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 1] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 2] < pChunk->nFirstVertId + pChunk->nNumVerts); - assert(pInds[i + 0] >= pChunk->nFirstVertId); - assert(pInds[i + 1] >= pChunk->nFirstVertId); - assert(pInds[i + 2] >= pChunk->nFirstVertId); - - const int iLookaheadIdx = min_branchless(i + 8, nLastValidIndexId); - const int iPrefetchIndex2 = nPosStride * pInds[iLookaheadIdx]; - - // get tri vertices - const hwvec3 v0 = v0Next; - const hwvec3 v1 = v1Next; - const hwvec3 v2 = v2Next; - - //Need to prefetch further ahead - byte* pPrefetch = &pPos[iPrefetchIndex2]; - PrefetchLine(pPrefetch, 0); - - v0Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iNextPosIndex0])); - - // get triangle normal - hwvec3 v1v0Diff = HWVSub(v1, v0); - hwvec3 v2v0Diff = HWVSub(v2, v0); - - v1Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iNextPosIndex1])); - - hwvec3 vNormal = HWVCross(v1v0Diff, v2v0Diff); - simdf fDot = HWV3Dot(vNormal, vProjDir); - - v2Next = HWVLoadVecUnaligned(reinterpret_cast(&pPos[iNextPosIndex2])); - - // test the face - if (SIMDFGreaterThan(fDot, fEpsilon)) - { - if (Overlap::HWVSphere_TriangleFromPoints(hwSphere, v0, v1, v2)) - { - plstIndices->AddList(&pInds[i], 3); - - hwvec3 triBBoxMax1 = HWVMax(v1, v0); - hwvec3 triBBoxMax2 = HWVMax(meshBBoxMax, v2); - - hwvec3 triBBoxMin1 = HWVMin(v1, v0); - hwvec3 triBBoxMin2 = HWVMin(meshBBoxMin, v2); - - meshBBoxMax = HWVMax(triBBoxMax1, triBBoxMax2); - meshBBoxMin = HWVMin(triBBoxMin1, triBBoxMin2); - - usedTriangles++; - } - } - - iNextPosIndex0 = nPosStride * pInds[iLookaheadIdx - 2]; - iNextPosIndex1 = nPosStride * pInds[iLookaheadIdx - 1]; - iNextPosIndex2 = iPrefetchIndex2; - } - - const hwvec3 v0 = v0Next; - const hwvec3 v1 = v1Next; - const hwvec3 v2 = v2Next; - - // get triangle normal - hwvec3 v1v0Diff = HWVSub(v1, v0); - hwvec3 v2v0Diff = HWVSub(v2, v0); - hwvec3 vNormal = HWVCross(v1v0Diff, v2v0Diff); - simdf fDot = HWV3Dot(vNormal, vProjDir); - - // test the face - if (SIMDFGreaterThan(fDot, fEpsilon)) - { - if (Overlap::HWVSphere_TriangleFromPoints(hwSphere, v0, v1, v2)) - { - plstIndices->AddList(&pInds[i], 3); - - hwvec3 triBBoxMax1 = HWVMax(v1, v0); - hwvec3 triBBoxMax2 = HWVMax(meshBBoxMax, v2); - - hwvec3 triBBoxMin1 = HWVMin(v1, v0); - hwvec3 triBBoxMin2 = HWVMin(meshBBoxMin, v2); - - meshBBoxMax = HWVMax(triBBoxMax1, triBBoxMax2); - meshBBoxMin = HWVMin(triBBoxMin1, triBBoxMin2); - - // triBBoxMax = HWVMax(triBBoxMax, v2); - // triBBoxMin = HWVMin(triBBoxMin, v2); - // - // meshBBoxMax = HWVMax(triBBoxMax, meshBBoxMax); - // meshBBoxMin = HWVMin(triBBoxMin, meshBBoxMin); - - usedTriangles++; - } - } - - - if (pChunk->m_texelAreaDensity > 0.0f && pChunk->m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += usedTriangles * pChunk->m_texelAreaDensity; - usedTrianglesTotal += usedTriangles; - } - } - } - - HWVSaveVecUnaligned(&meshBBox.max, meshBBoxMax); - HWVSaveVecUnaligned(&meshBBox.min, meshBBoxMin); - } - - if (usedTrianglesTotal != 0) - { - texelAreaDensity = texelAreaDensity / usedTrianglesTotal; - } -} - - -_smart_ptr CDecalManager::MakeBigDecalRenderMesh(IRenderMesh* pSourceRenderMesh, Vec3 vPos, float fRadius, Vec3 vProjDir, _smart_ptr pDecalMat, _smart_ptr pSrcMat) -{ - if (!pSourceRenderMesh || pSourceRenderMesh->GetVerticesCount() == 0) - { - return 0; - } - - // make indices of this decal - PodArray lstIndices; - - AABB meshBBox(vPos, vPos); - float texelAreaDensity = 0.0f; - - if (pSourceRenderMesh && pSourceRenderMesh->GetVerticesCount()) - { - FillBigDecalIndices(pSourceRenderMesh, vPos, fRadius, vProjDir, &lstIndices, pSrcMat, meshBBox, texelAreaDensity); - } - - if (!lstIndices.Count()) - { - return 0; - } - - // make fake vert buffer with one vertex // todo: remove this - PodArray EmptyVertBuffer; - EmptyVertBuffer.Add(SVF_P3S_C4B_T2S()); - - _smart_ptr pRenderMesh = 0; - pRenderMesh = GetRenderer()->CreateRenderMeshInitialized(EmptyVertBuffer.GetElements(), EmptyVertBuffer.Count(), eVF_P3S_C4B_T2S, - lstIndices.GetElements(), lstIndices.Count(), prtTriangleList, "BigDecalOnStatObj", "BigDecal", eRMT_Static, 1, 0, 0, 0, false, false, 0); - pRenderMesh->SetVertexContainer(pSourceRenderMesh); - pRenderMesh->SetChunk(pDecalMat, 0, pSourceRenderMesh->GetVerticesCount(), 0, lstIndices.Count(), texelAreaDensity, eVF_P3S_C4B_T2S); - pRenderMesh->SetBBox(meshBBox.min, meshBBox.max); - - return pRenderMesh; -} - -void CDecalManager::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->Add (*this); -} - -void CDecalManager::DeleteDecalsInRange(AABB* pAreaBox, IRenderNode* pEntity) -{ - if (GetCVars()->e_Decals > 1 && pAreaBox) - { - DrawBBox(*pAreaBox); - } - - for (int i = 0; i < DECAL_COUNT; i++) - { - if (!m_arrbActiveDecals[i]) - { - continue; - } - - if (pEntity && (pEntity != m_arrDecals[i].m_ownerInfo.pRenderNode)) - { - continue; - } - - if (pAreaBox) - { - Vec3 vPos = m_arrDecals[i].GetWorldPosition(); - Vec3 vSize(m_arrDecals[i].m_fWSSize, m_arrDecals[i].m_fWSSize, m_arrDecals[i].m_fWSSize); - AABB decalBox(vPos - vSize, vPos + vSize); - if (!Overlap::AABB_AABB(*pAreaBox, decalBox)) - { - continue; - } - } - - if (m_arrDecals[i].m_eDecalType != eDecalType_WS_OnTheGround) - { - m_arrbActiveDecals[i] = false; - } - - m_arrDecals[i].FreeRenderData(); - - if (GetCVars()->e_Decals == 2) - { - CDecal& decal = m_arrDecals[i]; - PrintMessage("Debug: CDecalManager::DeleteDecalsInRange: Pos=(%.1f,%.1f,%.1f) Size=%.2f DecalMaterial=%s", - decal.m_vPos.x, decal.m_vPos.y, decal.m_vPos.z, decal.m_fSize, decal.m_pMaterial ? decal.m_pMaterial->GetName() : "none"); - } - } -} - -void CDecalManager::Serialize(TSerialize ser) -{ - ser.BeginGroup("StaticDecals"); - - if (ser.IsReading()) - { - Reset(); - } - - uint32 dwDecalCount = 0; - - for (uint32 dwI = 0; dwI < DECAL_COUNT; dwI++) - { - if (m_arrbActiveDecals[dwI]) - { - dwDecalCount++; - } - } - - ser.Value("DecalCount", dwDecalCount); - - if (ser.IsWriting()) - { - for (uint32 _dwI = 0; _dwI < DECAL_COUNT; _dwI++) - { - if (m_arrbActiveDecals[_dwI]) - { - CDecal& ref = m_arrDecals[_dwI]; - - ser.BeginGroup("Decal"); - ser.Value("Pos", ref.m_vPos); - ser.Value("Right", ref.m_vRight); - ser.Value("Up", ref.m_vUp); - ser.Value("Front", ref.m_vFront); - ser.Value("Size", ref.m_fSize); - ser.Value("WSPos", ref.m_vWSPos); - ser.Value("WSSize", ref.m_fWSSize); - ser.Value("fLifeTime", ref.m_fLifeTime); - - // serialize material, handle legacy decals with textureID converted to material created at runtime - string matName(""); - if (ref.m_pMaterial && ref.m_pMaterial->GetName()) - { - matName = ref.m_pMaterial->GetName(); - } - ser.Value("MatName", matName); - - // TODO: IStatObj * m_pStatObj; // only if real 3d object is used as decal () - // TODO: IRenderNode * m_pDecalOwner; // transformation parent object (0 means parent is the world) - ser.Value("nRenderNodeSlotId", ref.m_ownerInfo.nRenderNodeSlotId); - ser.Value("nRenderNodeSlotSubObjectId", ref.m_ownerInfo.nRenderNodeSlotSubObjectId); - - int nDecalType = (int)ref.m_eDecalType; - ser.Value("eDecalType", nDecalType); - - ser.Value("fGrowTime", ref.m_fGrowTime); - ser.Value("fGrowTimeAlpha", ref.m_fGrowTimeAlpha); - ser.Value("fLifeBeginTime", ref.m_fLifeBeginTime); - - bool bBigDecalUsed = ref.IsBigDecalUsed(); - - ser.Value("bBigDecal", bBigDecalUsed); - - // m_arrBigDecalRMs[] will be created on the fly so no need load/save it - - if (bBigDecalUsed) - { - for (uint32 dwI = 0; dwI < sizeof(ref.m_arrBigDecalRMCustomData) / sizeof(ref.m_arrBigDecalRMCustomData[0]); ++dwI) - { - char szName[16]; - - sprintf_s(szName, "BDCD%d", dwI); - ser.Value(szName, ref.m_arrBigDecalRMCustomData[dwI]); - } - } - ser.EndGroup(); - } - } - } - else - if (ser.IsReading()) - { - m_nCurDecal = 0; - - for (uint32 _dwI = 0; _dwI < dwDecalCount; _dwI++) - { - if (m_nCurDecal < DECAL_COUNT) - { - CDecal& ref = m_arrDecals[m_nCurDecal]; - - ref.FreeRenderData(); - - ser.BeginGroup("Decal"); - ser.Value("Pos", ref.m_vPos); - ser.Value("Right", ref.m_vRight); - ser.Value("Up", ref.m_vUp); - ser.Value("Front", ref.m_vFront); - ser.Value("Size", ref.m_fSize); - ser.Value("WSPos", ref.m_vWSPos); - ser.Value("WSSize", ref.m_fWSSize); - ser.Value("fLifeTime", ref.m_fLifeTime); - - // serialize material, handle legacy decals with textureID converted to material created at runtime - string matName(""); - ser.Value("MatName", matName); - bool isTempMat(false); - ser.Value("IsTempMat", isTempMat); - - ref.m_pMaterial = 0; - if (!matName.empty()) - { - ref.m_pMaterial = GetMatMan()->LoadMaterial(matName.c_str(), false, true); - if (!ref.m_pMaterial) - { - Warning("Decal material \"%s\" not found!\n", matName.c_str()); - } - } - - // TODO: IStatObj * m_pStatObj; // only if real 3d object is used as decal () - // TODO: IRenderNode * m_pDecalOwner; // transformation parent object (0 means parent is the world) - ser.Value("nRenderNodeSlotId", ref.m_ownerInfo.nRenderNodeSlotId); - ser.Value("nRenderNodeSlotSubObjectId", ref.m_ownerInfo.nRenderNodeSlotSubObjectId); - - int nDecalType = eDecalType_Undefined; - ser.Value("eDecalType", nDecalType); - ref.m_eDecalType = (EDecal_Type)nDecalType; - - ser.Value("fGrowTime", ref.m_fGrowTime); - ser.Value("fGrowTimeAlpha", ref.m_fGrowTimeAlpha); - ser.Value("fLifeBeginTime", ref.m_fLifeBeginTime); - - // no need to to store m_arrBigDecalRMs[] as it becomes recreated - - bool bBigDecalsAreaUsed = false; - - ser.Value("bBigDecals", bBigDecalsAreaUsed); - - if (bBigDecalsAreaUsed) - { - for (uint32 dwI = 0; dwI < sizeof(ref.m_arrBigDecalRMCustomData) / sizeof(ref.m_arrBigDecalRMCustomData[0]); ++dwI) - { - char szName[16]; - - sprintf_s(szName, "BDCD%d", dwI); - ser.Value(szName, ref.m_arrBigDecalRMCustomData[dwI]); - } - } - - // m_arrBigDecalRMs[] will be created on the fly so no need load/save it - - m_arrbActiveDecals[m_nCurDecal] = bool(nDecalType != eDecalType_Undefined); - - ++m_nCurDecal; - ser.EndGroup(); - } - } - } - - ser.EndGroup(); -} - -_smart_ptr CDecalManager::GetMaterialForDecalTexture(const char* pTextureName) -{ - if (!pTextureName || *pTextureName == 0) - { - return 0; - } - - IMaterialManager* pMatMan = GetMatMan(); - _smart_ptr pMat = pMatMan->FindMaterial(pTextureName); - if (pMat) - { - return pMat; - } - - _smart_ptr pMatSrc = pMatMan->LoadMaterial("EngineAssets/Materials/Decals/Default", false, true); - if (pMatSrc) - { - _smart_ptr pMatDst = pMatMan->CreateMaterial(pTextureName, pMatSrc->GetFlags() | MTL_FLAG_NON_REMOVABLE); - if (pMatDst) - { - SShaderItem& si = pMatSrc->GetShaderItem(); - SInputShaderResources isr = si.m_pShaderResources; - - // This will create texture data insertion to the table for the diffuse slot - isr.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name = pTextureName; - - SShaderItem siDst = GetRenderer()->EF_LoadShaderItem(si.m_pShader->GetName(), true, 0, &isr, si.m_pShader->GetGenerationMask()); - - pMatDst->AssignShaderItem(siDst); - - return pMatDst; - } - } - - return 0; -} - -IStatObj* SDecalOwnerInfo::GetOwner(Matrix34A& objMat) -{ - if (!pRenderNode) - { - return NULL; - } - - IStatObj* pStatObj = pRenderNode->GetEntityStatObj(nRenderNodeSlotId, nRenderNodeSlotSubObjectId, &objMat, true); - if (pStatObj) - { - if (nRenderNodeSlotSubObjectId >= 0 && nRenderNodeSlotSubObjectId < pStatObj->GetSubObjectCount()) - { - IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(nRenderNodeSlotSubObjectId); - pStatObj = pSubObj->pStatObj; - objMat = objMat * pSubObj->tm; - } - } - - if (pStatObj && (pStatObj->GetFlags() & STATIC_OBJECT_HIDDEN)) - { - return NULL; - } - - if (pStatObj) - { - if (int nMinLod = ((CStatObj*)pStatObj)->GetMinUsableLod()) - { - if (IStatObj* pLodObj = pStatObj->GetLodObject(nMinLod)) - { - pStatObj = pLodObj; - } - } - } - - return pStatObj; -} diff --git a/Code/CryEngine/Cry3DEngine/DecalManager.h b/Code/CryEngine/Cry3DEngine/DecalManager.h deleted file mode 100644 index 304ad345cd..0000000000 --- a/Code/CryEngine/Cry3DEngine/DecalManager.h +++ /dev/null @@ -1,159 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_DECALMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_DECALMANAGER_H -#pragma once - -#define DECAL_COUNT (512) // must be pow2 -#define ENTITY_DECAL_DIST_FACTOR (200) -#define DIST_FADING_FACTOR (6.f) - -class C3DEngine; - -enum EDecal_Type -{ - eDecalType_Undefined, - eDecalType_OS_OwnersVerticesUsed, - eDecalType_WS_Merged, - eDecalType_WS_OnTheGround, - eDecalType_WS_SimpleQuad, - eDecalType_OS_SimpleQuad -}; - -class CDecal - : public Cry3DEngineBase -{ -public: - - // cur state - Vec3 m_vPos; - Vec3 m_vRight, m_vUp, m_vFront; - float m_fSize; - Vec3 m_vWSPos; // Decal position (world coordinates) from DecalInfo.vPos - float m_fWSSize; // Decal size (world coordinates) from DecalInfo.fSize - - // life style - float m_fLifeTime; // relative time left till decal should die - Vec3 m_vAmbient; // ambient color - SDecalOwnerInfo m_ownerInfo; - EDecal_Type m_eDecalType; - float m_fGrowTime, m_fGrowTimeAlpha; // e.g. growing blood pools - float m_fLifeBeginTime; // - - uint8 m_iAssembleSize; // of how many decals has this decal be assembled, 0 if not to assemble - uint8 m_sortPrio; - uint8 m_bDeferred; - - // render data - _smart_ptr m_pRenderMesh; // only needed for terrain decals, 4 of them because they might cross borders - float m_arrBigDecalRMCustomData[16]; // only needed if one of m_arrBigDecalRMs[]!=0, most likely we can reduce to [12] - - _smart_ptr< IMaterial > m_pMaterial; - uint32 m_nGroupId; // used for multi-component decals - -#ifdef _DEBUG - char m_decalOwnerEntityClassName[256]; - char m_decalOwnerName[256]; - EERType m_decalOwnerType; -#endif - - CDecal() - : m_vPos(0, 0, 0) - , m_vRight(0, 0, 0) - , m_vUp(0, 0, 0) - , m_vFront(0, 0, 0) - , m_fSize(0) - , m_vWSPos(0, 0, 0) - , m_fWSSize(0) - , m_fLifeTime(0) - , m_vAmbient(0, 0, 0) - , m_fGrowTime(0) - , m_fGrowTimeAlpha(0) - , m_fLifeBeginTime(0) - , m_sortPrio(0) - , m_pMaterial(0) - , m_nGroupId(0) - , m_iAssembleSize(0) - , m_bDeferred(0) - { - m_eDecalType = eDecalType_Undefined; - m_pRenderMesh = NULL; - memset(&m_arrBigDecalRMCustomData[0], 0, sizeof(m_arrBigDecalRMCustomData)); - -#ifdef _DEBUG - m_decalOwnerEntityClassName[0] = '\0'; - m_decalOwnerName[0] = '\0'; - m_decalOwnerType = eERType_NotRenderNode; -#endif - } - - ~CDecal() - { - FreeRenderData(); - } - - void Render(const float fFrameTime, int nAfterWater, float fDistanceFading, float fDiatance, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - int Update(bool& active, const float fFrameTime); - void RenderBigDecalOnTerrain(float fAlpha, float fScale, const SRenderingPassInfo& passInfo); - void FreeRenderData(); - static void ResetStaticData(); - bool IsBigDecalUsed() const { return m_pRenderMesh != 0; } - Vec3 GetWorldPosition(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - -private: - static IGeometry* s_pSphere; -}; - -class CDecalManager - : public Cry3DEngineBase -{ - CDecal m_arrDecals[DECAL_COUNT]; - bool m_arrbActiveDecals[DECAL_COUNT]; - int m_nCurDecal; - PodArray m_arrTempUpdatedOwners; - -public: // --------------------------------------------------------------- - - CDecalManager(); - ~CDecalManager(); - bool Spawn(CryEngineDecalInfo Decal, CDecal* pCallerManagedDecal = 0); - // once per frame - void Update(const float fFrameTime); - // maybe multiple times per frame - void Render(const SRenderingPassInfo& passInfo); - void OnEntityDeleted(IRenderNode* pEnt); - void OnRenderMeshDeleted(IRenderMesh* pRenderMesh); - - // complex decals - void FillBigDecalIndices(IRenderMesh* pRenderMesh, Vec3 vPos, float fRadius, Vec3 vProjDir, PodArray* plstIndices, _smart_ptr pMat, AABB& meshBBox, float& texelAreaDensity); - _smart_ptr MakeBigDecalRenderMesh(IRenderMesh* pSourceRenderMesh, Vec3 vPos, float fRadius, Vec3 vProjDir, _smart_ptr pDecalMat, _smart_ptr pSrcMat); - void MoveToEdge(IRenderMesh* pRM, const float fRadius, Vec3& vPos, Vec3& vOutNorm, const Vec3& vTri0, const Vec3& vTri1, const Vec3& vTri2); - void GetMemoryUsage(ICrySizer* pSizer) const; - void Reset() { memset(m_arrbActiveDecals, 0, sizeof(m_arrbActiveDecals)); m_nCurDecal = 0; } - void DeleteDecalsInRange(AABB* pAreaBox, IRenderNode* pEntity); - bool AdjustDecalPosition(CryEngineDecalInfo& DecalInfo, bool bMakeFatTest); - static bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, float fMaxHitDistance, _smart_ptr pMat); - void Serialize(TSerialize ser); - bool SpawnHierarchical(const CryEngineDecalInfo& rootDecalInfo, CDecal* pCallerManagedDecal); - -private: - _smart_ptr GetMaterialForDecalTexture(const char* pTextureName); -}; - -#endif // CRYINCLUDE_CRY3DENGINE_DECALMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/DecalRenderNode.cpp b/Code/CryEngine/Cry3DEngine/DecalRenderNode.cpp deleted file mode 100644 index 63e2912f27..0000000000 --- a/Code/CryEngine/Cry3DEngine/DecalRenderNode.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "DecalRenderNode.h" -#include "VisAreas.h" -#include "ObjMan.h" -#include "MatMan.h" - -#include - -#include "Environment/OceanEnvironmentBus.h" - -int CDecalRenderNode::m_nFillBigDecalIndicesCounter = 0; - -CDecalRenderNode::CDecalRenderNode() - : m_pos(0, 0, 0) - , m_localBounds(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_pMaterial(NULL) - , m_updateRequested(false) - , m_decalProperties() - , m_decal(nullptr) - , m_nLastRenderedFrameId(0) - , m_nLayerId(0) -{ - m_Matrix.SetIdentity(); -} - - -CDecalRenderNode::~CDecalRenderNode() -{ - DeleteDecal(); - GetISystem()->GetI3DEngine()->FreeRenderNodeState(this); -} - - -const SDecalProperties* CDecalRenderNode::GetDecalProperties() const -{ - return &m_decalProperties; -} - -void CDecalRenderNode::DeleteDecal() -{ - if (m_decal) - { - delete m_decal; - m_decal = nullptr; - } -} - -void CDecalRenderNode::SetCommonProperties(CryEngineDecalInfo& decalInfo) -{ - decalInfo.fSize = m_decalProperties.m_radius; - decalInfo.pExplicitRightUpFront = &m_decalProperties.m_explicitRightUpFront; - decalInfo.sortPrio = m_decalProperties.m_sortPrio; - - decalInfo.pIStatObj = nullptr; - decalInfo.ownerInfo.pRenderNode = nullptr; - decalInfo.fLifeTime = 1.0f; // default life time for rendering, decal won't grow older as we don't update it - decalInfo.fGrowTime = 0.0f; - decalInfo.fAngle = 0.0f; - - // We don't set decalInfo.szMaterialName here because that is handled in CDecalRenderNode::CreateDecal() -} - -void CDecalRenderNode::CreatePlanarDecal() -{ - CryEngineDecalInfo decalInfo; - - SetCommonProperties(decalInfo); - - // necessary params - decalInfo.vPos = m_decalProperties.m_pos; - decalInfo.vNormal = m_decalProperties.m_normal; - - // default for all other - decalInfo.vHitDirection = Vec3(0, 0, 0); - decalInfo.preventDecalOnGround = true; - - CreateDecal(decalInfo); -} - -void CDecalRenderNode::CreateDecalOnTerrain() -{ - bool terrainExists = false; - float terrainHeight = AZ::Constants::FloatMax; - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainHeight - , &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats - , m_decalProperties.m_pos.x, m_decalProperties.m_pos.y, AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR, &terrainExists); - if (!terrainExists) - { - //No terrain system available, or there's a hole at the given location. - return; - } - float terrainDelta(m_decalProperties.m_pos.z - terrainHeight); - if (terrainDelta < m_decalProperties.m_radius && terrainDelta > -0.5f) - { - CryEngineDecalInfo decalInfo; - - SetCommonProperties(decalInfo); - - // necessary params - decalInfo.vPos = Vec3(m_decalProperties.m_pos.x, m_decalProperties.m_pos.y, terrainHeight); - decalInfo.vNormal = Vec3(0, 0, 1); - decalInfo.vHitDirection = Vec3(0, 0, -1); - decalInfo.preventDecalOnGround = false; - - CreateDecal(decalInfo); - } -} - -void CDecalRenderNode::CreateDecal(const CryEngineDecalInfo& decalInfo) -{ - m_decal = new CDecal(); - if (m_p3DEngine->CreateDecalInstance(decalInfo, m_decal)) - { - // Rather than setting decalInfo.szMaterialName in SetCommonProperties(), it's better to set IMaterial directly since we already have the desired material. - // This is more reliable than using the material name. For example, if the material was cloned from another one it would have the same name - // as the original, and CreateDecalInstance() would load the original from disk rather than the clone. - m_decal->m_pMaterial = m_pMaterial; - } - else - { - DeleteDecal(); - } -} - -void CDecalRenderNode::CreateDecals() -{ - DeleteDecal(); - - if (m_decalProperties.m_deferred) - { - return; - } - - _smart_ptr pMaterial(GetMaterial()); - - assert(0 != pMaterial && "CDecalRenderNode::CreateDecals() -- Invalid Material!"); - if (!pMaterial) - { - return; - } - - switch (m_decalProperties.m_projectionType) - { - case SDecalProperties::ePlanar: - { - CreatePlanarDecal(); - break; - } - case SDecalProperties::eProjectOnTerrain: - { - CreateDecalOnTerrain(); - break; - } - default: - { - assert(!"CDecalRenderNode::CreateDecals() : Unsupported decal projection type!"); - break; - } - } -} - - -void CDecalRenderNode::ProcessUpdateRequest() -{ - if (!m_updateRequested || m_nFillBigDecalIndicesCounter >= GetCVars()->e_DecalsMaxUpdatesPerFrame) - { - return; - } - - CreateDecals(); - m_updateRequested = false; -} - -void CDecalRenderNode::UpdateAABBFromRenderMeshes() -{ - if (m_decalProperties.m_projectionType == SDecalProperties::eProjectOnTerrain) - { - AABB WSBBox; - WSBBox.Reset(); - - if (m_decal && m_decal->m_pRenderMesh && m_decal->m_eDecalType != eDecalType_OS_OwnersVerticesUsed) - { - AABB aabb; - m_decal->m_pRenderMesh->GetBBox(aabb.min, aabb.max); - if (m_decal->m_eDecalType == eDecalType_WS_Merged || m_decal->m_eDecalType == eDecalType_WS_OnTheGround) - { - aabb.min += m_decal->m_vPos; - aabb.max += m_decal->m_vPos; - } - WSBBox.Add(aabb); - } - - if (!WSBBox.IsReset()) - { - m_WSBBox = WSBBox; - } - } -} - -//special check for def decals forcing -bool CDecalRenderNode::CheckForceDeferred() -{ - if (m_pMaterial != NULL) - { - SShaderItem& sItem = m_pMaterial->GetShaderItem(0); - if (sItem.m_pShaderResources != NULL) - { - float fCosA = m_decalProperties.m_normal.GetNormalized().Dot(Vec3(0, 0, 1)); - if (fCosA > 0.5f) - { - return false; - } - - if (SEfResTexture* pEnvRes0 = sItem.m_pShaderResources->GetTextureResource(EFTT_ENV)) - { - if (pEnvRes0->m_Sampler.m_pITex == NULL) - { - m_decalProperties.m_projectionType = SDecalProperties::ePlanar; - m_decalProperties.m_deferred = true; - return true; - } - } - else - { - m_decalProperties.m_projectionType = SDecalProperties::ePlanar; - m_decalProperties.m_deferred = true; - return true; - } - } - } - return false; -} - -void CDecalRenderNode::SetDecalProperties(const SDecalProperties& properties) -{ - // update bounds - m_localBounds = AABB(-properties.m_radius * Vec3(1, 1, 1), properties.m_radius * Vec3(1, 1, 1)); - - // register material - m_pMaterial = GetMatMan()->LoadMaterial(properties.m_pMaterialName, false); - - // copy decal properties - m_decalProperties = properties; - m_decalProperties.m_pMaterialName = 0; // reset this as it's assumed to be a temporary pointer only, refer to m_materialID to get material - - // request update - m_updateRequested = true; - - bool bForced = 0; - - if (properties.m_deferred || (GetCVars()->e_DecalsDefferedStatic && (m_decalProperties.m_projectionType != SDecalProperties::ePlanar && m_decalProperties.m_projectionType != SDecalProperties::eProjectOnTerrain))) - { - m_decalProperties.m_deferred = true; - } - - if (GetCVars()->e_DecalsForceDeferred) - { - if (CheckForceDeferred()) - { - bForced = true; - } - } - - // set normal just in case; normal direction will be determined by m_explicitRightUpFront - m_decalProperties.m_normal = properties.m_normal; - - m_fWSMaxViewDist = properties.m_maxViewDist; - - // set matrix - m_Matrix.SetRotation33(m_decalProperties.m_explicitRightUpFront); - Matrix33 matScale; - if (bForced && !properties.m_deferred) - { - matScale.SetScale(Vec3(properties.m_radius, properties.m_radius, properties.m_radius * 0.05f)); - } - else - { - matScale.SetScale(Vec3(properties.m_radius, properties.m_radius, properties.m_radius * properties.m_depth)); - } - - m_Matrix = m_Matrix * matScale; - m_Matrix.SetTranslation(properties.m_pos); -} - -IRenderNode* CDecalRenderNode::Clone() const -{ - CDecalRenderNode* pDestDecal = new CDecalRenderNode(); - - // CDecalRenderNode member vars - pDestDecal->m_pos = m_pos; - pDestDecal->m_localBounds = m_localBounds; - pDestDecal->m_pMaterial = m_pMaterial; - pDestDecal->m_updateRequested = true; - pDestDecal->m_decalProperties = m_decalProperties; - pDestDecal->m_WSBBox = m_WSBBox; - pDestDecal->m_Matrix = m_Matrix; - pDestDecal->m_nLayerId = m_nLayerId; - - //IRenderNode member vars - // We cannot just copy over due to issues with the linked list of IRenderNode objects - CopyIRenderNodeData(pDestDecal); - - return pDestDecal; -} - -void CDecalRenderNode::SetMatrix(const Matrix34& mat) -{ - m_pos = mat.GetTranslation(); - - if (m_decalProperties.m_projectionType == SDecalProperties::ePlanar) - { - m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 0.5f), Vec3(1, 1, 0.5f))); - } - else - { - m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 1), Vec3(1, 1, 1))); - } - - Get3DEngine()->RegisterEntity(this); -} - -void CDecalRenderNode::SetMatrixFull(const Matrix34& mat) -{ - m_Matrix = mat; - m_pos = mat.GetTranslation(); - - if (m_decalProperties.m_projectionType == SDecalProperties::ePlanar) - { - m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 0.5f), Vec3(1, 1, 0.5f))); - } - else - { - m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 1), Vec3(1, 1, 1))); - } -} - -const char* CDecalRenderNode::GetEntityClassName() const -{ - return "Decal"; -} - - -const char* CDecalRenderNode::GetName() const -{ - return "Decal"; -} - - -void CDecalRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!passInfo.RenderDecals()) - { - return; // false; - } - - float distFading = SATURATE((1.f - rParam.fDistance / m_fWSMaxViewDist) * DIST_FADING_FACTOR); - - if (m_decalProperties.m_deferred) - { - if (passInfo.IsShadowPass()) - { - return; // otherwise causing flickering with GI - } - SDeferredDecal newItem; - newItem.fAlpha = m_decalProperties.m_opacity; - newItem.angleAttenuation = m_decalProperties.m_angleAttenuation; - newItem.pMaterial = m_pMaterial; - newItem.projMatrix = m_Matrix; - newItem.nSortOrder = m_decalProperties.m_sortPrio; - newItem.nFlags = DECAL_STATIC; - GetRenderer()->EF_AddDeferredDecal(newItem); - return; - } - - // update last rendered frame id - m_nLastRenderedFrameId = passInfo.GetMainFrameID(); - - bool bUpdateAABB = m_updateRequested; - - if (passInfo.IsGeneralPass()) - { - ProcessUpdateRequest(); - } - - if (m_decal && 0 != m_decal->m_pMaterial) - { - m_decal->m_vAmbient.x = rParam.AmbientColor.r; - m_decal->m_vAmbient.y = rParam.AmbientColor.g; - m_decal->m_vAmbient.z = rParam.AmbientColor.b; - bool bAfterWater = GetObjManager()->IsAfterWater(m_decal->m_vWSPos, passInfo); - - m_decal->Render(0, bAfterWater, distFading, rParam.fDistance, passInfo, SRendItemSorter(rParam.rendItemSorter)); - } - - // terrain decal meshes are created only during rendering so only after that bbox can be computed - if (bUpdateAABB) - { - UpdateAABBFromRenderMeshes(); - } -} - - -void CDecalRenderNode::SetMaterial(_smart_ptr pMat) -{ - if (m_decal) - { - m_decal->m_pMaterial = pMat; - } - - m_pMaterial = pMat; - - //special check for def decals forcing - if (GetCVars()->e_DecalsForceDeferred) - { - CheckForceDeferred(); - } -} - - - -void CDecalRenderNode::Precache() -{ - ProcessUpdateRequest(); -} - - -void CDecalRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "DecalNode"); - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_decal); -} - -void CDecalRenderNode::CleanUpOldDecals() -{ - if (m_nLastRenderedFrameId != 0 && // was rendered at least once - (int)GetRenderer()->GetFrameID(false) > (int)m_nLastRenderedFrameId + GetCVars()->e_DecalsMaxValidFrames) - { - DeleteDecal(); - m_nLastRenderedFrameId = 0; - m_updateRequested = true; // make sure if rendered again, that the decal is recreated - } -} - -void CDecalRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_pos += delta; - m_WSBBox.Move(delta); - m_Matrix.SetTranslation(m_Matrix.GetTranslation() + delta); -} diff --git a/Code/CryEngine/Cry3DEngine/DecalRenderNode.h b/Code/CryEngine/Cry3DEngine/DecalRenderNode.h deleted file mode 100644 index 87ca1fd9e1..0000000000 --- a/Code/CryEngine/Cry3DEngine/DecalRenderNode.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_DECALRENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_DECALRENDERNODE_H -#pragma once - - -#include "DecalManager.h" - - -class CDecalRenderNode - : public IDecalRenderNode - , public Cry3DEngineBase -{ -public: - // implements IDecalRenderNode - virtual void SetDecalProperties(const SDecalProperties& properties); - virtual const SDecalProperties* GetDecalProperties() const; - virtual void CleanUpOldDecals(); - - // implements IRenderNode - virtual IRenderNode* Clone() const; - virtual void SetMatrix(const Matrix34& mat); - virtual const Matrix34& GetMatrix() { return m_Matrix; } - - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const; - virtual const char* GetName() const; - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - void SetMaterial(_smart_ptr pMat) override; - virtual _smart_ptr GetMaterial(Vec3* pHitPos = 0); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void Precache(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - - virtual uint8 GetSortPriority() { return m_decalProperties.m_sortPrio; } - - virtual void SetLayerId(uint16 nLayerId) { m_nLayerId = nLayerId; } - virtual uint16 GetLayerId() { return m_nLayerId; } - static void ResetDecalUpdatesCounter() { CDecalRenderNode::m_nFillBigDecalIndicesCounter = 0; } - - // SetMatrix only supports changing position, this will do the full transform - void SetMatrixFull(const Matrix34& mat); -public: - CDecalRenderNode(); - void RequestUpdate() { m_updateRequested = true; DeleteDecal(); } - void DeleteDecal(); - -private: - ~CDecalRenderNode(); - void CreateDecals(); - void ProcessUpdateRequest(); - void UpdateAABBFromRenderMeshes(); - bool CheckForceDeferred(); - - void SetCommonProperties(CryEngineDecalInfo& decalInfo); - void CreatePlanarDecal(); - void CreateDecalOnTerrain(); - void CreateDecal(const CryEngineDecalInfo& decalInfo); - -private: - Vec3 m_pos; - AABB m_localBounds; - _smart_ptr m_pMaterial; - bool m_updateRequested; - SDecalProperties m_decalProperties; - CDecal* m_decal; - AABB m_WSBBox; - Matrix34 m_Matrix; - uint32 m_nLastRenderedFrameId; - uint16 m_nLayerId; - -public: - static int m_nFillBigDecalIndicesCounter; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_DECALRENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.cpp b/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.cpp deleted file mode 100644 index dd053fa2b2..0000000000 --- a/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "DeferredCollisionEvent.h" - -CDeferredPhysicsEventManager::CDeferredPhysicsEventManager() - : m_hThreadPool(-1) - , m_bEntitySystemReset(false) -{ - if (gEnv->IsDedicated()) - { - return; - } - - // Disable MT if Editor. - if (gEnv->IsEditor()) - { - return; - } - - ThreadPoolDesc threadPoolDesc; - threadPoolDesc.sPoolName = "DeferredPhysicsEvents"; - threadPoolDesc.nThreadStackSizeKB = 24; - - // let the DeferredPhysicsEvents run on Core3 - if (!threadPoolDesc.CreateThread(BIT(3))) - { - return; - } - - IThreadTaskManager* pThreadTaskManager = gEnv->pSystem->GetIThreadTaskManager(); - assert(pThreadTaskManager); - - m_hThreadPool = pThreadTaskManager->CreateThreadsPool(threadPoolDesc); -} - - -CDeferredPhysicsEventManager::~CDeferredPhysicsEventManager() -{ -} - - -void CDeferredPhysicsEventManager::DispatchDeferredEvent(IDeferredPhysicsEvent* pEvent) -{ - assert(pEvent); - // execute immediately if we don't use deferred physcis events - if (GetCVars()->e_DeferredPhysicsEvents == 0 || m_hThreadPool < 0) - { - pEvent->OnUpdate(); - return; - } - - // Register the task with the ThreadTask manager - IThreadTaskManager* pThreadTaskManager = gEnv->pSystem->GetIThreadTaskManager(); - assert(pThreadTaskManager); - - pEvent->GetTaskInfo()->m_params.name = "DeferredPhysicsEvents"; - pEvent->GetTaskInfo()->m_params.nFlags = THREAD_TASK_ASSIGN_TO_POOL; - pEvent->GetTaskInfo()->m_params.nThreadsGroupId = m_hThreadPool; - pEvent->GetTaskInfo()->m_pThread = NULL; - pThreadTaskManager->RegisterTask(pEvent, pEvent->GetTaskInfo()->m_params); -} - - -void ApplyCollisionImpulse(EventPhysCollision* pCollision) -{ - if (pCollision->normImpulse && pCollision->pEntity[1] && - pCollision->pEntity[0] && pCollision->pEntity[0]->GetType() == PE_PARTICLE && - pCollision->pEntity[0]->GetForeignData(pCollision->pEntity[0]->GetiForeignData())) // no foreign data mean it's likely scheduled for deletion - { - pe_action_impulse ai; - ai.point = pCollision->pt; - ai.partid = pCollision->partid[1]; - ai.impulse = (pCollision->vloc[0] - pCollision->vloc[1]) * pCollision->normImpulse; - pCollision->pEntity[1]->Action(&ai); - } -} - - -int CDeferredPhysicsEventManager::HandleEvent(const EventPhys* pEvent, IDeferredPhysicsEventManager::CreateEventFunc pCreateFunc, [[maybe_unused]] IDeferredPhysicsEvent::DeferredEventType type) -{ - EventPhysCollision* pCollision = (EventPhysCollision*)pEvent; - assert(pCollision); - - if (pCollision->deferredState == EPC_DEFERRED_FINISHED) - { - ApplyCollisionImpulse(pCollision); - return pCollision->deferredResult; - } - - // == create new deferred event object, and do some housekeeping(ensuring entities not deleted, remebering event for cleanup) == // - IDeferredPhysicsEvent* pDeferredEvent = pCreateFunc(pEvent); - - // == start executing == // - pDeferredEvent->Start(); - - - // == check if we really needed to deferred this event(early outs, not deferred code paths) == // - if (GetCVars()->e_DeferredPhysicsEvents == 0 || pDeferredEvent->HasFinished()) - { - int nResult = pDeferredEvent->Result((EventPhys*)pEvent); - SAFE_DELETE(pDeferredEvent); - ApplyCollisionImpulse(pCollision); - return nResult; - } - - if (pCollision->pEntity[0]) - { - pCollision->pEntity[0]->AddRef(); - } - if (pCollision->pEntity[1]) - { - pCollision->pEntity[1]->AddRef(); - } - - // == re-queue event for the next frame, to keep the physical entity alive == // - RegisterDeferredEvent(pDeferredEvent); - - return 0; -} - - -void CDeferredPhysicsEventManager::RegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent) -{ - assert(pDeferredEvent); - m_activeDeferredEvents.push_back(pDeferredEvent); -} - - -void CDeferredPhysicsEventManager::UnRegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent) -{ - std::vector::iterator it = std::find(m_activeDeferredEvents.begin(), m_activeDeferredEvents.end(), pDeferredEvent); - if (it == m_activeDeferredEvents.end()) - { - return; - } - - // == remove from active list == // - m_activeDeferredEvents.erase(it); - - if (m_bEntitySystemReset) - { - return; - } - - // == decrement keep alive counter on entity == // - EventPhysCollision* pCollision = (EventPhysCollision*)pDeferredEvent->PhysicsEvent(); - if (pCollision->pEntity[0]) - { - pCollision->pEntity[0]->Release(); - } - if (pCollision->pEntity[1]) - { - pCollision->pEntity[1]->Release(); - } -} - - -void CDeferredPhysicsEventManager::ClearDeferredEvents() -{ - // move content of the active deferred events array to a tmp one to prevent provlems with UnRegisterDeferredEvent called by destructors - std::vector tmp = m_activeDeferredEvents; - m_bEntitySystemReset = true; - - for (std::vector::iterator it = tmp.begin(); it != tmp.end(); ++it) - { - (*it)->Sync(); - delete *it; - } - stl::free_container(m_activeDeferredEvents); - m_bEntitySystemReset = false; -} - -void CDeferredPhysicsEventManager::Update() -{ - std::vector tmp = m_activeDeferredEvents; - - for (std::vector::iterator it = tmp.begin(), end = tmp.end(); it != end; ++it) - { - IDeferredPhysicsEvent* collisionEvent = *it; - assert(collisionEvent); - PREFAST_ASSUME(collisionEvent); - EventPhysCollision* epc = (EventPhysCollision*) collisionEvent->PhysicsEvent(); - - if (collisionEvent->HasFinished() == false) - { - continue; - } - - epc->deferredResult = collisionEvent->Result(); - - if (epc->deferredState != EPC_DEFERRED_FINISHED) - { - epc->deferredState = EPC_DEFERRED_FINISHED; - } - else - { - SAFE_DELETE(collisionEvent); - } - } -} - -IDeferredPhysicsEvent* CDeferredPhysicsEventManager::GetLastCollisionEventForEntity(IPhysicalEntity* pPhysEnt) -{ - EventPhysCollision* pLastPhysEvent; - for (int i = m_activeDeferredEvents.size() - 1; i >= 0; i--) - { - pLastPhysEvent = (EventPhysCollision*)m_activeDeferredEvents[i]->PhysicsEvent(); - if (pLastPhysEvent && pLastPhysEvent->idval == EventPhysCollision::id && pLastPhysEvent->pEntity[0] == pPhysEnt) - { - return m_activeDeferredEvents[i]; - } - } - return 0; -} diff --git a/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.h b/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.h deleted file mode 100644 index 9ffcbe9f2c..0000000000 --- a/Code/CryEngine/Cry3DEngine/DeferredCollisionEvent.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_DEFERREDCOLLISIONEVENT_H -#define CRYINCLUDE_CRY3DENGINE_DEFERREDCOLLISIONEVENT_H -#pragma once - -#include - -// Implementation class for the DeferredPhysicsEvent Manager -class CDeferredPhysicsEventManager - : public IDeferredPhysicsEventManager - , public Cry3DEngineBase -{ -public: - CDeferredPhysicsEventManager(); - virtual ~CDeferredPhysicsEventManager(); - - virtual void DispatchDeferredEvent(IDeferredPhysicsEvent* pEvent); - virtual int HandleEvent(const EventPhys* pEvent, IDeferredPhysicsEventManager::CreateEventFunc, IDeferredPhysicsEvent::DeferredEventType); - - virtual void RegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent); - virtual void UnRegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent); - - virtual void ClearDeferredEvents(); - - virtual void Update(); - - virtual IDeferredPhysicsEvent* GetLastCollisionEventForEntity(IPhysicalEntity* pPhysEnt); - -private: - ThreadPoolHandle m_hThreadPool; // thread pool to use for deferred event tasks - std::vector m_activeDeferredEvents; // list of all active deferred events, used for cleanup and statistics - bool m_bEntitySystemReset; // means all entity ptrs in events are stale -}; - -#endif // CRYINCLUDE_CRY3DENGINE_DEFERREDCOLLISIONEVENT_H diff --git a/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.cpp b/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.cpp deleted file mode 100644 index b18f8ccb76..0000000000 --- a/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "DistanceCloudRenderNode.h" -#include "VisAreas.h" -#include "ObjMan.h" -#include "MatMan.h" -#include "Environment/OceanEnvironmentBus.h" - -CDistanceCloudRenderNode::CDistanceCloudRenderNode() - : m_pos(0, 0, 0) - , m_sizeX(1) - , m_sizeY(1) - , m_rotationZ(0) - , m_pMaterial(NULL) -{ -} - - -CDistanceCloudRenderNode::~CDistanceCloudRenderNode() -{ - Get3DEngine()->FreeRenderNodeState(this); -} - - -SDistanceCloudProperties CDistanceCloudRenderNode::GetProperties() const -{ - SDistanceCloudProperties properties; - - properties.m_sizeX = m_sizeX; - properties.m_sizeY = m_sizeY; - properties.m_rotationZ = m_rotationZ; - properties.m_pos = m_pos; - properties.m_pMaterialName = 0; // query materialID instead! - - return properties; -} - - -void CDistanceCloudRenderNode::SetProperties(const SDistanceCloudProperties& properties) -{ - // register material - m_pMaterial = GetMatMan()->LoadMaterial(properties.m_pMaterialName, false); - - // copy distance cloud properties - m_sizeX = properties.m_sizeX; - m_sizeY = properties.m_sizeY; - m_rotationZ = properties.m_rotationZ; - m_pos = properties.m_pos; -} - - -void CDistanceCloudRenderNode::SetMatrix(const Matrix34& mat) -{ - Get3DEngine()->UnRegisterEntityAsJob(this); - - m_pos = mat.GetTranslation(); - - m_WSBBox.SetTransformedAABB(mat, AABB(-Vec3(1, 1, 1e-4f), Vec3(1, 1, 1e-4f))); - - Get3DEngine()->RegisterEntity(this); -} - - -const char* CDistanceCloudRenderNode::GetEntityClassName() const -{ - return "DistanceCloud"; -} - - -const char* CDistanceCloudRenderNode::GetName() const -{ - return "DistanceCloud"; -} - -static inline uint16 HalfFlip(uint16 h) -{ - uint16 mask = -int16(h >> 15) | 0x8000; - return h ^ mask; -} - - -void CDistanceCloudRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - _smart_ptr pMaterial(GetMaterial()); - - if (!passInfo.RenderClouds() || !pMaterial) - { - return; // false; - } - CRenderObject* pOb(gEnv->pRenderer->EF_GetObject_Temp(passInfo.ThreadID())); - if (!pOb) - { - return; // false; - } - const CCamera& cam(passInfo.GetCamera()); - float zDist = cam.GetPosition().z - m_pos.z; - if (cam.GetViewdir().z < 0) - { - zDist = -zDist; - } - pOb->m_nSort = HalfFlip(CryConvertFloatToHalf(zDist)); - //pOb->m_II.m_Matrix.SetIdentity(); - - // fill general vertex data - f32 sinZ(0), cosZ(1); - sincos_tpl(DEG2RAD(m_rotationZ), &sinZ, &cosZ); - Vec3 right(m_sizeX * cosZ, m_sizeY * sinZ, 0); - Vec3 up(-m_sizeX * sinZ, m_sizeY * cosZ, 0); - - SVF_P3F_C4B_T2F pVerts[4]; - pVerts[0].xyz = (-right - up) + m_pos; - pVerts[0].st = Vec2(0, 1); - pVerts[0].color.dcolor = ~0; - - pVerts[1].xyz = (right - up) + m_pos; - pVerts[1].st = Vec2(1, 1); - pVerts[1].color.dcolor = ~0; - - pVerts[2].xyz = (right + up) + m_pos; - pVerts[2].st = Vec2(1, 0); - pVerts[2].color.dcolor = ~0; - - pVerts[3].xyz = (-right + up) + m_pos; - pVerts[3].st = Vec2(0, 0); - pVerts[3].color.dcolor = ~0; - - // prepare tangent space (tangent, bitangent) and fill it in - Vec3 rightUnit(cosZ, sinZ, 0); - Vec3 upUnit(-sinZ, cosZ, 0); - - SPipTangents pTangents[4]; - - pTangents[0] = SPipTangents(rightUnit, -upUnit, 1); - pTangents[1] = pTangents[0]; - pTangents[2] = pTangents[0]; - pTangents[3] = pTangents[0]; - - // prepare indices - uint16 pIndices[6]; - pIndices[0] = 0; - pIndices[1] = 1; - pIndices[2] = 2; - - pIndices[3] = 0; - pIndices[4] = 2; - pIndices[5] = 3; - - int afterWater(GetObjManager()->IsAfterWater(m_pos, passInfo)); - GetRenderer()->EF_AddPolygonToScene(pMaterial->GetShaderItem(), 4, pVerts, pTangents, pOb, passInfo, pIndices, 6, afterWater, SRendItemSorter(rParam.rendItemSorter)); - - // return true; -} - - -void CDistanceCloudRenderNode::SetMaterial(_smart_ptr pMat) -{ - m_pMaterial = pMat; -} - - -void CDistanceCloudRenderNode::Precache() -{ -} - - -void CDistanceCloudRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "DistanceCloudNode"); - pSizer->AddObject(this, sizeof(*this)); -} - -void CDistanceCloudRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_pos += delta; - m_WSBBox.Move(delta); -} diff --git a/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.h b/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.h deleted file mode 100644 index b9974f3c45..0000000000 --- a/Code/CryEngine/Cry3DEngine/DistanceCloudRenderNode.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_DISTANCECLOUDRENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_DISTANCECLOUDRENDERNODE_H -#pragma once - - -class CDistanceCloudRenderNode - : public IDistanceCloudRenderNode - , public Cry3DEngineBase -{ -public: - // implements IDistanceCloudRenderNode - virtual void SetProperties(const SDistanceCloudProperties& properties); - - // implements IRenderNode - virtual void SetMatrix(const Matrix34& mat); - - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const; - virtual const char* GetName() const; - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - void SetMaterial(_smart_ptr pMat) override; - virtual _smart_ptr GetMaterial(Vec3* pHitPos = 0); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void Precache(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - virtual void SetLayerId(uint16 nLayerId) { m_nLayerId = nLayerId; } - virtual uint16 GetLayerId() { return m_nLayerId; } - -public: - CDistanceCloudRenderNode(); - SDistanceCloudProperties GetProperties() const; - -private: - ~CDistanceCloudRenderNode(); - -private: - Vec3 m_pos; - float m_sizeX; - float m_sizeY; - float m_rotationZ; - _smart_ptr< IMaterial > m_pMaterial; - AABB m_WSBBox; - uint16 m_nLayerId; -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_DISTANCECLOUDRENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/Environment/OceanEnvironmentBus.h b/Code/CryEngine/Cry3DEngine/Environment/OceanEnvironmentBus.h deleted file mode 100644 index 088a34077d..0000000000 --- a/Code/CryEngine/Cry3DEngine/Environment/OceanEnvironmentBus.h +++ /dev/null @@ -1,329 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include -#include - -#include -#include -#include - -namespace AZ -{ - /** - * Feature toggle for the ocean feature(s) - */ - class OceanFeatureToggle - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - virtual ~OceanFeatureToggle() = default; - - virtual bool OceanComponentEnabled() const { return false; } - - }; - using OceanFeatureToggleBus = AZ::EBus; - - /*! - * Messages services for environment data points - * Note: The Gem for Water is meant to override this when enabled in a project - */ - class OceanEnvironmentRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - using MutexType = AZStd::recursive_mutex; - - ////////////////////////////////////////////////////////////////////////// - - // flags for toggling ocean reflections - enum class ReflectionFlags - { - Entities = SRenderingPassInfo::ENTITIES, - StaticObjects = SRenderingPassInfo::STATIC_OBJECTS - }; - - // Ocean requests - - virtual bool OceanIsEnabled() const = 0; - - // Fast option - use if just ocean height required - virtual float GetOceanLevel() const = 0; - virtual void SetOceanLevel(float oceanLevel) = 0; - virtual float GetOceanLevelOrDefault(const float defaultValue) const = 0; - - // This will return ocean height or water volume height, optional for accurate water height query - virtual float GetWaterLevel(const Vec3& position) const = 0; - - // Only use for Accurate query - this will return exact ocean height - virtual float GetAccurateOceanHeight(const Vec3& position) const = 0; - - // gets the amount of water tessellation - virtual int GetWaterTessellationAmount() const = 0; - virtual void SetWaterTessellationAmount(int amount) = 0; - - // the ocean material asset - virtual const AZStd::string& GetOceanMaterialName() const = 0; - virtual void SetOceanMaterialName(const AZStd::string& matName) = 0; - - // Animation data - virtual float GetAnimationWindDirection() const = 0; - virtual float GetAnimationWindSpeed() const = 0; - virtual float GetAnimationWavesSpeed() const = 0; - virtual float GetAnimationWavesSize() const = 0; - virtual float GetAnimationWavesAmount() const = 0; - virtual void SetAnimationWindDirection(float dir) = 0; - virtual void SetAnimationWindSpeed(float speed) = 0; - virtual void SetAnimationWavesSpeed(float speed) = 0; - virtual void SetAnimationWavesSize(float size) = 0; - virtual void SetAnimationWavesAmount(float amount) = 0; - - // Ocean reflection - virtual void ApplyReflectRenderFlags(int& flags) const = 0; - virtual bool GetReflectRenderFlag(ReflectionFlags flag) const = 0; - virtual float GetReflectResolutionScale() const = 0; - virtual bool GetReflectionAnisotropic() const = 0; - virtual void SetReflectRenderFlag(ReflectionFlags flag, bool value) = 0; - virtual void SetReflectResolutionScale(float scale) = 0; - virtual void SetReflectionAnisotropic(bool enabled) = 0; - - // Ocean bottom - virtual bool GetUseOceanBottom() const = 0; - virtual void SetUseOceanBottom(bool use) = 0; - - // Underwater Effects - virtual bool GetGodRaysEnabled() const = 0; - virtual void SetGodRaysEnabled(bool enabled) = 0; - virtual float GetUnderwaterDistortion() const = 0; - virtual void SetUnderwaterDistortion(float) = 0; - - // Caustics - virtual bool GetCausticsEnabled() const = 0; - virtual float GetCausticsDepth() const = 0; - virtual float GetCausticsIntensity() const = 0; - virtual float GetCausticsTiling() const = 0; - virtual float GetCausticsDistanceAttenuation() const = 0; - virtual void SetCausticsEnabled(bool enable) = 0; - virtual void SetCausticsDepth(float depth) = 0; - virtual void SetCausticsIntensity(float intensity) = 0; - virtual void SetCausticsTiling(float tiling) = 0; - virtual void SetCausticsDistanceAttenuation(float dist) = 0; - - // Ocean fog data - virtual AZ::Color GetFogColorPremultiplied() const = 0; - virtual AZ::Color GetFogColor() const = 0; - virtual void SetFogColor(const AZ::Color& fogColor) = 0; - virtual float GetFogColorMultiplier() const = 0; - virtual void SetFogColorMultiplier(float fogMultiplier) = 0; - virtual AZ::Color GetNearFogColor() const = 0; - virtual void SetNearFogColor(const AZ::Color& nearColor) = 0; - virtual float GetFogDensity() const = 0; - virtual void SetFogDensity(float density) = 0; - }; - - using OceanEnvironmentBus = AZ::EBus; - -} // namespace AZ - -namespace OceanToggle -{ - /** - * As long as the Water gem is in a preview state, the legacy code and data will be protected by this feature toggle check. - */ - AZ_INLINE bool IsActive() - { - bool bHasOceanFeature = false; - AZ::OceanFeatureToggleBus::BroadcastResult(bHasOceanFeature, &AZ::OceanFeatureToggleBus::Events::OceanComponentEnabled); - return bHasOceanFeature; - } -} // namespace OceanToggle - -namespace OceanRequest -{ - - AZ_INLINE bool OceanIsEnabled() - { - bool enabled = false; - AZ::OceanEnvironmentBus::BroadcastResult(enabled, &AZ::OceanEnvironmentBus::Events::OceanIsEnabled); - return enabled; - } - - // Ocean level - - AZ_INLINE float GetOceanLevel() - { - float fWaterLevel = AZ::OceanConstants::s_HeightUnknown; - AZ::OceanEnvironmentBus::BroadcastResult(fWaterLevel, &AZ::OceanEnvironmentBus::Events::GetOceanLevel); - return fWaterLevel; - } - - AZ_INLINE float GetOceanLevelOrDefault(const float defaultValue) - { - return OceanIsEnabled() ? GetOceanLevel() : defaultValue; - } - - AZ_INLINE float GetWaterLevel(const Vec3& position) - { - float fWaterLevel = AZ::OceanConstants::s_HeightUnknown; - AZ::OceanEnvironmentBus::BroadcastResult(fWaterLevel, &AZ::OceanEnvironmentBus::Events::GetWaterLevel, position); - return fWaterLevel; - } - - AZ_INLINE float GetAccurateOceanHeight(const Vec3& position) - { - float fWaterLevel = AZ::OceanConstants::s_HeightUnknown; - AZ::OceanEnvironmentBus::BroadcastResult(fWaterLevel, &AZ::OceanEnvironmentBus::Events::GetAccurateOceanHeight, position); - return fWaterLevel; - } - - // the ocean material - - AZ_INLINE AZStd::string GetOceanMaterialName() - { - AZStd::string value = "EngineAssets/Materials/Water/Ocean_default.mtl"; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetOceanMaterialName); - return value; - } - - // Wave animation data - - AZ_INLINE float GetWavesAmount() - { - float value = AZ::OceanConstants::s_animationWavesAmountDefault; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetAnimationWavesAmount); - return value; - } - - AZ_INLINE float GetWavesSpeed() - { - float value = AZ::OceanConstants::s_animationWavesSpeedDefault; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetAnimationWavesSpeed); - return value; - } - - AZ_INLINE float GetWavesSize() - { - float value = AZ::OceanConstants::s_animationWavesSizeDefault; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetAnimationWavesSize); - return value; - } - - AZ_INLINE float GetWindDirection() - { - float value = AZ::OceanConstants::s_animationWindDirectionDefault; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetAnimationWindDirection); - return value; - } - - AZ_INLINE float GetWindSpeed() - { - float value = AZ::OceanConstants::s_animationWindSpeedDefault; - AZ::OceanEnvironmentBus::BroadcastResult(value, &AZ::OceanEnvironmentBus::Events::GetAnimationWindSpeed); - return value; - } - - // Ocean bottom - - AZ_INLINE bool GetUseOceanBottom() - { - bool useOceanBottom = AZ::OceanConstants::s_UseOceanBottom; - AZ::OceanEnvironmentBus::BroadcastResult(useOceanBottom, &AZ::OceanEnvironmentBus::Events::GetUseOceanBottom); - return useOceanBottom; - } - - - AZ_INLINE bool GetGodRaysEnabled() - { - bool godRaysEnabled = AZ::OceanConstants::s_GodRaysEnabled; - AZ::OceanEnvironmentBus::BroadcastResult(godRaysEnabled, &AZ::OceanEnvironmentBus::Events::GetGodRaysEnabled); - return godRaysEnabled; - } - - AZ_INLINE float GetUnderwaterDistortion() - { - float underwaterDistortion = AZ::OceanConstants::s_UnderwaterDistortion; - AZ::OceanEnvironmentBus::BroadcastResult(underwaterDistortion, &AZ::OceanEnvironmentBus::Events::GetUnderwaterDistortion); - return underwaterDistortion; - } - - // Cuastics - - AZ_INLINE bool GetCausticsEnabled() - { - bool causticsEnabled = false; - AZ::OceanEnvironmentBus::BroadcastResult(causticsEnabled, &AZ::OceanEnvironmentBus::Events::GetCausticsEnabled); - return causticsEnabled; - } - - AZ_INLINE float GetCausticsDepth() - { - float causticsDepth = AZ::OceanConstants::s_CausticsDepthDefault; - AZ::OceanEnvironmentBus::BroadcastResult(causticsDepth, &AZ::OceanEnvironmentBus::Events::GetCausticsDepth); - return causticsDepth; - } - - AZ_INLINE float GetCausticsIntensity() - { - float causticsIntensity = AZ::OceanConstants::s_CausticsIntensityDefault; - AZ::OceanEnvironmentBus::BroadcastResult(causticsIntensity, &AZ::OceanEnvironmentBus::Events::GetCausticsIntensity); - return causticsIntensity; - } - - AZ_INLINE float GetCausticsTiling() - { - float causticsTiling = AZ::OceanConstants::s_CausticsTilingDefault; - AZ::OceanEnvironmentBus::BroadcastResult(causticsTiling, &AZ::OceanEnvironmentBus::Events::GetCausticsTiling); - return causticsTiling; - } - - AZ_INLINE float GetCausticsDistanceAttenuation() - { - float causticsDistanceAtten = AZ::OceanConstants::s_CausticsDistanceAttenDefault; - AZ::OceanEnvironmentBus::BroadcastResult(causticsDistanceAtten, &AZ::OceanEnvironmentBus::Events::GetCausticsDistanceAttenuation); - return causticsDistanceAtten; - } - - // Ocean fog - AZ_INLINE AZ::Vector3 GetFogColorPremultiplied() - { - AZ::Color fogColor = AZ::OceanConstants::s_oceanFogColorDefault; - AZ::OceanEnvironmentBus::BroadcastResult(fogColor, &AZ::OceanEnvironmentBus::Events::GetFogColorPremultiplied); - return fogColor.GetAsVector3(); - } - - AZ_INLINE AZ::Vector3 GetNearFogColor() - { - AZ::Color nearFogColor = AZ::OceanConstants::s_oceanNearFogColorDefault; - AZ::OceanEnvironmentBus::BroadcastResult(nearFogColor, &AZ::OceanEnvironmentBus::Events::GetNearFogColor); - return nearFogColor.GetAsVector3(); - } - - AZ_INLINE float GetFogDensity() - { - float fogDensity = AZ::OceanConstants::s_oceanFogDensityDefault; - AZ::OceanEnvironmentBus::BroadcastResult(fogDensity, &AZ::OceanEnvironmentBus::Events::GetFogDensity); - return fogDensity; - } - -} // namespace OceanRequest diff --git a/Code/CryEngine/Cry3DEngine/EnvironmentPreset.cpp b/Code/CryEngine/Cry3DEngine/EnvironmentPreset.cpp deleted file mode 100644 index 5dd2ea1811..0000000000 --- a/Code/CryEngine/Cry3DEngine/EnvironmentPreset.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "ITimeOfDay.h" -#include "EnvironmentPreset.h" - -#include -#include -#include -#include - -#include -#include - -SERIALIZATION_ENUM_BEGIN_NESTED(SBezierControlPoint, ETangentType, "TangentType") -SERIALIZATION_ENUM_VALUE_NESTED(SBezierControlPoint, eTangentType_Custom, "Custom") -SERIALIZATION_ENUM_VALUE_NESTED(SBezierControlPoint, eTangentType_Auto, "Smooth") -SERIALIZATION_ENUM_VALUE_NESTED(SBezierControlPoint, eTangentType_Zero, "Zero") -SERIALIZATION_ENUM_VALUE_NESTED(SBezierControlPoint, eTangentType_Step, "Step") -SERIALIZATION_ENUM_VALUE_NESTED(SBezierControlPoint, eTangentType_Linear, "Linear") -SERIALIZATION_ENUM_END() - -namespace EnvironmentPresetDetails -{ - static const float sBezierSplineKeyValueEpsilon = 0.001f; - - ////////////////////////////////////////////////////////////////////////// - SBezierKey ApplyInTangent(const SBezierKey& key, const SBezierKey& leftKey, const SBezierKey* pRightKey) - { - SBezierKey newKey = key; - - if (leftKey.m_controlPoint.m_outTangentType == SBezierControlPoint::eTangentType_Step) - { - newKey.m_controlPoint.m_inTangent = Vec2(0.0f, 0.0f); - return newKey; - } - else if (key.m_controlPoint.m_inTangentType != SBezierControlPoint::eTangentType_Step) - { - const SAnimTime leftTime = leftKey.m_time; - const SAnimTime rightTime = pRightKey ? pRightKey->m_time : key.m_time; - - // Rebase to [0, rightTime - leftTime] to increase float precision - const float floatTime = (key.m_time - leftTime).ToFloat(); - const float floatLeftTime = 0.0f; - const float floatRightTime = (rightTime - leftTime).ToFloat(); - - newKey.m_controlPoint = Bezier::CalculateInTangent(floatTime, key.m_controlPoint, - floatLeftTime, &leftKey.m_controlPoint, - floatRightTime, pRightKey ? &pRightKey->m_controlPoint : NULL); - } - else - { - newKey.m_controlPoint.m_inTangent = Vec2(0.0f, 0.0f); - newKey.m_controlPoint.m_value = leftKey.m_controlPoint.m_value; - } - - return newKey; - } - - SBezierKey ApplyOutTangent(const SBezierKey& key, const SBezierKey* pLeftKey, const SBezierKey& rightKey) - { - SBezierKey newKey = key; - - if (rightKey.m_controlPoint.m_inTangentType == SBezierControlPoint::eTangentType_Step - && key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step) - { - newKey.m_controlPoint.m_outTangent = Vec2(0.0f, 0.0f); - } - else if (key.m_controlPoint.m_outTangentType != SBezierControlPoint::eTangentType_Step) - { - const SAnimTime leftTime = pLeftKey ? pLeftKey->m_time : key.m_time; - const SAnimTime rightTime = rightKey.m_time; - - // Rebase to [0, rightTime - leftTime] to increase float precision - const float floatTime = (key.m_time - leftTime).ToFloat(); - const float floatLeftTime = 0.0f; - const float floatRightTime = (rightTime - leftTime).ToFloat(); - - newKey.m_controlPoint = Bezier::CalculateOutTangent(floatTime, key.m_controlPoint, - floatLeftTime, pLeftKey ? &pLeftKey->m_controlPoint : NULL, - floatRightTime, &rightKey.m_controlPoint); - } - else - { - newKey.m_controlPoint.m_outTangent = Vec2(0.0f, 0.0f); - newKey.m_controlPoint.m_value = rightKey.m_controlPoint.m_value; - } - - return newKey; - } -} - -CBezierSpline::CBezierSpline() -{ - m_keys.reserve(2); -} - -CBezierSpline::~CBezierSpline() -{ -} - -void CBezierSpline::Init(float fDefaultValue) -{ - m_keys.clear(); - InsertKey(SAnimTime(0.0f), fDefaultValue); - InsertKey(SAnimTime(1.0f), fDefaultValue); -} - -float CBezierSpline::Evaluate(float t) const -{ - if (m_keys.size() == 0) - { - return 0.0f; - } - - if (m_keys.size() == 1) - { - return m_keys.front().m_controlPoint.m_value; - } - - const SAnimTime time(t); - - if (time <= m_keys.front().m_time) - { - return m_keys.front().m_controlPoint.m_value; - } - else if (time >= m_keys.back().m_time) - { - return m_keys.back().m_controlPoint.m_value; - } - - const TKeyContainer::const_iterator it = std::upper_bound(m_keys.begin(), m_keys.end(), time, SCompKeyTime()); - const TKeyContainer::const_iterator startIt = it - 1; - - if (startIt->m_controlPoint.m_outTangentType == SBezierControlPoint::eTangentType_Step) - { - return it->m_controlPoint.m_value; - } - - if (it->m_controlPoint.m_inTangentType == SBezierControlPoint::eTangentType_Step) - { - return startIt->m_controlPoint.m_value; - } - - const SAnimTime deltaTime = it->m_time - startIt->m_time; - - if (deltaTime == SAnimTime(0)) - { - return startIt->m_controlPoint.m_value; - } - - const float timeInSegment = (time - startIt->m_time).ToFloat(); - - const SBezierKey* pKeyLeftOfSegment = (startIt != m_keys.begin()) ? &*(startIt - 1) : NULL; - const SBezierKey* pKeyRightOfSegment = (startIt != (m_keys.end() - 2)) ? &*(startIt + 2) : NULL; - const SBezierKey segmentStart = EnvironmentPresetDetails::ApplyOutTangent(*startIt, pKeyLeftOfSegment, *(startIt + 1)); - const SBezierKey segmentEnd = EnvironmentPresetDetails::ApplyInTangent(*(startIt + 1), *startIt, pKeyRightOfSegment); - - const float factor = Bezier::InterpolationFactorFromX(timeInSegment, deltaTime.ToFloat(), segmentStart.m_controlPoint, segmentEnd.m_controlPoint); - const float fResult = Bezier::EvaluateY(factor, segmentStart.m_controlPoint, segmentEnd.m_controlPoint); - - return fResult; -} - -void CBezierSpline::InsertKey(SAnimTime time, float value) -{ - SBezierKey key; - key.m_time = time; - key.m_controlPoint.m_value = value; - - const size_t nKeyNum = m_keys.size(); - for (size_t i = 0; i < nKeyNum; ++i) - { - if (m_keys[i].m_time > time) - { - m_keys.insert(m_keys.begin() + i, key); - return; - } - } - - m_keys.push_back(key); -} - -void CBezierSpline::UpdateKeyForTime(float fTime, float value) -{ - const SAnimTime time(fTime); - - const size_t nKeyNum = m_keys.size(); - for (size_t i = 0; i < nKeyNum; ++i) - { - if (fabs(m_keys[i].m_time.ToFloat() - fTime) < EnvironmentPresetDetails::sBezierSplineKeyValueEpsilon) - { - m_keys[i].m_controlPoint.m_value = value; - return; - } - } - - InsertKey(time, value); -} - -void CBezierSpline::Serialize(Serialization::IArchive& ar) -{ - ar(m_keys, "keys"); -} - -////////////////////////////////////////////////////////////////////////// - -CTimeOfDayVariable::CTimeOfDayVariable() - : m_id(ITimeOfDay::PARAM_TOTAL) - , m_type(ITimeOfDay::TYPE_FLOAT) - , m_name(NULL) - , m_displayName(NULL) - , m_group(NULL) - , m_minValue(0.0f) - , m_maxValue(0.0f) - , m_value(ZERO) -{ -} - -CTimeOfDayVariable::~CTimeOfDayVariable() -{ -} - -void CTimeOfDayVariable::Init(const char* group, const char* displayName, const char* name, ITimeOfDay::ETimeOfDayParamID nParamId, ITimeOfDay::EVariableType type, float defVal0, float defVal1, float defVal2) -{ - m_id = nParamId; - m_type = type; - m_name = name; - m_displayName = (displayName && *displayName) ? displayName : name; - m_group = (group && *group) ? group : "Default"; - - if (ITimeOfDay::TYPE_FLOAT == type) - { - m_value.x = defVal0; - m_minValue = defVal1; - m_maxValue = defVal2; - m_spline[0].Init(defVal0); - } - else if (ITimeOfDay::TYPE_COLOR == type) - { - m_value.x = defVal0; - m_value.y = defVal1; - m_value.z = defVal2; - - m_minValue = 0.0f; - m_maxValue = 1.0f; - - m_spline[0].Init(defVal0); - m_spline[1].Init(defVal1); - m_spline[2].Init(defVal2); - } -} - -void CTimeOfDayVariable::Update(float time) -{ - m_value = GetInterpolatedAt(time); -} - -Vec3 CTimeOfDayVariable::GetInterpolatedAt(float t) const -{ - Vec3 result; - result.x = clamp_tpl(m_spline[0].Evaluate(t), m_minValue, m_maxValue); - result.y = clamp_tpl(m_spline[1].Evaluate(t), m_minValue, m_maxValue); - result.z = clamp_tpl(m_spline[2].Evaluate(t), m_minValue, m_maxValue); - return result; -} - -size_t CTimeOfDayVariable::GetSplineKeyCount(int nSpline) const -{ - if (const CBezierSpline* pSpline = GetSpline(nSpline)) - { - return pSpline->GetKeyCount(); - } - - return 0; -} - -bool CTimeOfDayVariable::GetSplineKeys(int nSpline, SBezierKey* keysArray, unsigned int keysArraySize) const -{ - if (const CBezierSpline* pSpline = GetSpline(nSpline)) - { - if (keysArraySize < pSpline->GetKeyCount()) - { - return false; - } - - pSpline->GetKeys(keysArray); - return true; - } - - return false; -} - -bool CTimeOfDayVariable::SetSplineKeys(int nSpline, const SBezierKey* keysArray, unsigned int keysArraySize) -{ - if (CBezierSpline* pSpline = GetSpline(nSpline)) - { - pSpline->SetKeys(keysArray, keysArraySize); - return true; - } - return false; -} - -bool CTimeOfDayVariable::UpdateSplineKeyForTime(int nSpline, float fTime, float newKey) -{ - if (CBezierSpline* pSpline = GetSpline(nSpline)) - { - pSpline->UpdateKeyForTime(fTime, newKey); - return true; - } - return false; -} - -void CTimeOfDayVariable::Serialize(Serialization::IArchive& ar) -{ - ITimeOfDay::ETimeOfDayParamID defID = m_id; - ITimeOfDay::EVariableType defType = m_type; - - ar(defID, "id"); - ar(defType, "type"); - if (!ar.IsInput() || (defID == m_id && defType == m_type)) - { // Write always, Read only when ID and Type are correct/Schema hasn't changed - ar(m_minValue, "minValue"); - ar(m_maxValue, "maxValue"); - - ar(m_spline[0], "spline0"); - ar(m_spline[1], "spline1"); - ar(m_spline[2], "spline2"); - } -} - -////////////////////////////////////////////////////////////////////////// - -CEnvironmentPreset::CEnvironmentPreset() -{ - ResetVariables(); -} - -CEnvironmentPreset::~CEnvironmentPreset() -{ -} - -void CEnvironmentPreset::ResetVariables() -{ - const float fRecip255 = 1.0f / 255.0f; - - AddVar("Sun", "", "Sun color", ITimeOfDay::PARAM_SUN_COLOR, ITimeOfDay::TYPE_COLOR, 255.0f * fRecip255, 248.0f * fRecip255, 248.0f * fRecip255); - AddVar("Sun", "Sun intensity (lux)", "Sun intensity", ITimeOfDay::PARAM_SUN_INTENSITY, ITimeOfDay::TYPE_FLOAT, 119000.0f, 0.0f, 550000.0f); - AddVar("Sun", "", "Sun specular multiplier", ITimeOfDay::PARAM_SUN_SPECULAR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 4.0f); - - AddVar("Fog", "Color (bottom)", "Fog color", ITimeOfDay::PARAM_FOG_COLOR, ITimeOfDay::TYPE_COLOR, 0.0f, 0.0f, 0.0f); - AddVar("Fog", "Color (bottom) multiplier", "Fog color multiplier", ITimeOfDay::PARAM_FOG_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 16.0f); - AddVar("Fog", "Height (bottom)", "Fog height (bottom)", ITimeOfDay::PARAM_VOLFOG_HEIGHT, ITimeOfDay::TYPE_FLOAT, 0.0f, -5000.0f, 30000.0f); - AddVar("Fog", "Density (bottom)", "Fog layer density (bottom)", ITimeOfDay::PARAM_VOLFOG_DENSITY, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Fog", "Color (top)", "Fog color (top)", ITimeOfDay::PARAM_FOG_COLOR2, ITimeOfDay::TYPE_COLOR, 0.0f, 0.0f, 0.0f); - AddVar("Fog", "Color (top) multiplier", "Fog color (top) multiplier", ITimeOfDay::PARAM_FOG_COLOR2_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 16.0f); - AddVar("Fog", "Height (top)", "Fog height (top)", ITimeOfDay::PARAM_VOLFOG_HEIGHT2, ITimeOfDay::TYPE_FLOAT, 4000.0f, -5000.0f, 30000.0f); - AddVar("Fog", "Density (top)", "Fog layer density (top)", ITimeOfDay::PARAM_VOLFOG_DENSITY2, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); - AddVar("Fog", "Color height offset", "Fog color height offset", ITimeOfDay::PARAM_VOLFOG_HEIGHT_OFFSET, ITimeOfDay::TYPE_FLOAT, 0.0f, -1.0f, 1.0f); - - AddVar("Fog", "Color (radial)", "Fog color (radial)", ITimeOfDay::PARAM_FOG_RADIAL_COLOR, ITimeOfDay::TYPE_COLOR, 0.0f, 0.0f, 0.0f); - AddVar("Fog", "Color (radial) multiplier", "Fog color (radial) multiplier", ITimeOfDay::PARAM_FOG_RADIAL_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 16.0f); - AddVar("Fog", "Radial size", "Fog radial size", ITimeOfDay::PARAM_VOLFOG_RADIAL_SIZE, ITimeOfDay::TYPE_FLOAT, 0.75f, 0.0f, 1.0f); - AddVar("Fog", "Radial lobe", "Fog radial lobe", ITimeOfDay::PARAM_VOLFOG_RADIAL_LOBE, ITimeOfDay::TYPE_FLOAT, 0.5f, 0.0f, 1.0f); - - AddVar("Fog", "Global density", "Volumetric fog: Global density", ITimeOfDay::PARAM_VOLFOG_GLOBAL_DENSITY, ITimeOfDay::TYPE_FLOAT, 0.02f, 0.0f, 100.0f); - AddVar("Fog", "Final density clamp", "Volumetric fog: Final density clamp", ITimeOfDay::PARAM_VOLFOG_FINAL_DENSITY_CLAMP, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - - AddVar("Fog", "Ramp start", "Volumetric fog: Ramp start", ITimeOfDay::PARAM_VOLFOG_RAMP_START, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 30000.0f); - AddVar("Fog", "Ramp end", "Volumetric fog: Ramp end", ITimeOfDay::PARAM_VOLFOG_RAMP_END, ITimeOfDay::TYPE_FLOAT, 100.0f, 0.0f, 30000.0f); - AddVar("Fog", "Ramp influence", "Volumetric fog: Ramp influence", ITimeOfDay::PARAM_VOLFOG_RAMP_INFLUENCE, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); - - AddVar("Fog", "Shadow darkening", "Volumetric fog: Shadow darkening", ITimeOfDay::PARAM_VOLFOG_SHADOW_DARKENING, ITimeOfDay::TYPE_FLOAT, 0.25f, 0.0f, 1.0f); - AddVar("Fog", "Shadow darkening sun", "Volumetric fog: Shadow darkening sun", ITimeOfDay::PARAM_VOLFOG_SHADOW_DARKENING_SUN, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Fog", "Shadow darkening ambient", "Volumetric fog: Shadow darkening ambient", ITimeOfDay::PARAM_VOLFOG_SHADOW_DARKENING_AMBIENT, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Fog", "Shadow range", "Volumetric fog: Shadow range", ITimeOfDay::PARAM_VOLFOG_SHADOW_RANGE, ITimeOfDay::TYPE_FLOAT, 0.1f, 0.0f, 1.0f); - - AddVar("Volumetric fog", "Height (bottom)", "Volumetric fog 2: Fog height (bottom)", ITimeOfDay::PARAM_VOLFOG2_HEIGHT, ITimeOfDay::TYPE_FLOAT, 0.0f, -5000.0f, 30000.0f); - AddVar("Volumetric fog", "Density (bottom)", "Volumetric fog 2: Fog layer density (bottom)", ITimeOfDay::PARAM_VOLFOG2_DENSITY, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Volumetric fog", "Height (top)", "Volumetric fog 2: Fog height (top)", ITimeOfDay::PARAM_VOLFOG2_HEIGHT2, ITimeOfDay::TYPE_FLOAT, 4000.0f, -5000.0f, 30000.0f); - AddVar("Volumetric fog", "Density (top)", "Volumetric fog 2: Fog layer density (top)", ITimeOfDay::PARAM_VOLFOG2_DENSITY2, ITimeOfDay::TYPE_FLOAT, 0.0001f, 0.0f, 1.0f); - AddVar("Volumetric fog", "Global density", "Volumetric fog 2: Global fog density", ITimeOfDay::PARAM_VOLFOG2_GLOBAL_DENSITY, ITimeOfDay::TYPE_FLOAT, 0.1f, 0.0f, 100.0f); - AddVar("Volumetric fog", "Ramp start", "Volumetric fog 2: Ramp start", ITimeOfDay::PARAM_VOLFOG2_RAMP_START, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 30000.0f); - AddVar("Volumetric fog", "Ramp end", "Volumetric fog 2: Ramp end", ITimeOfDay::PARAM_VOLFOG2_RAMP_END, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 30000.0f); - AddVar("Volumetric fog", "Color (atmosphere)", "Volumetric fog 2: Fog albedo color (atmosphere)", ITimeOfDay::PARAM_VOLFOG2_COLOR1, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - AddVar("Volumetric fog", "Anisotropy (atmosphere)", "Volumetric fog 2: Anisotropy factor (atmosphere)", ITimeOfDay::PARAM_VOLFOG2_ANISOTROPIC1, ITimeOfDay::TYPE_FLOAT, 0.2f, -1.0f, 1.0f); - AddVar("Volumetric fog", "Color (sun radial)", "Volumetric fog 2: Fog albedo color (sun radial)", ITimeOfDay::PARAM_VOLFOG2_COLOR2, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - AddVar("Volumetric fog", "Anisotropy (sun radial)", "Volumetric fog 2: Anisotropy factor (sun radial)", ITimeOfDay::PARAM_VOLFOG2_ANISOTROPIC2, ITimeOfDay::TYPE_FLOAT, 0.95f, -1.0f, 1.0f); - AddVar("Volumetric fog", "Radial blend factor", "Volumetric fog 2: Blend factor for sun scattering", ITimeOfDay::PARAM_VOLFOG2_BLEND_FACTOR, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Volumetric fog", "Radial blend mode", "Volumetric fog 2: Blend mode for sun scattering", ITimeOfDay::PARAM_VOLFOG2_BLEND_MODE, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); - AddVar("Volumetric fog", "Range", "Volumetric fog 2: Maximum range of ray-marching", ITimeOfDay::PARAM_VOLFOG2_RANGE, ITimeOfDay::TYPE_FLOAT, 64.0f, 0.0f, 8192.0f); - AddVar("Volumetric fog", "In-scattering", "Volumetric fog 2: In-scattering factor", ITimeOfDay::PARAM_VOLFOG2_INSCATTER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 100.0f); - AddVar("Volumetric fog", "Extinction", "Volumetric fog 2: Extinction factor", ITimeOfDay::PARAM_VOLFOG2_EXTINCTION, ITimeOfDay::TYPE_FLOAT, 0.3f, 0.0f, 100.0f); - AddVar("Volumetric fog", "Color (entities)", "Volumetric fog 2: Fog albedo color (entities)", ITimeOfDay::PARAM_VOLFOG2_COLOR, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - AddVar("Volumetric fog", "Anisotropy (entities)", "Volumetric fog 2: Anisotropy factor (entities)", ITimeOfDay::PARAM_VOLFOG2_ANISOTROPIC, ITimeOfDay::TYPE_FLOAT, 0.6f, -1.0f, 1.0f); - AddVar("Volumetric fog", "Analytical fog visibility", "Volumetric fog 2: Analytical volumetric fog visibility", ITimeOfDay::PARAM_VOLFOG2_GLOBAL_FOG_VISIBILITY, ITimeOfDay::TYPE_FLOAT, 0.5f, 0.0f, 1.0f); - AddVar("Volumetric fog", "Final density clamp", "Volumetric fog 2: Final density clamp", ITimeOfDay::PARAM_VOLFOG2_FINAL_DENSITY_CLAMP, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - - AddVar("Sky Light", "Sun intensity", "Sky light: Sun intensity", ITimeOfDay::PARAM_SKYLIGHT_SUN_INTENSITY, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - AddVar("Sky Light", "Sun intensity multiplier", "Sky light: Sun intensity multiplier", ITimeOfDay::PARAM_SKYLIGHT_SUN_INTENSITY_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 50.0f, 0.0f, 1000.0f); - AddVar("Sky Light", "Mie scattering", "Sky light: Mie scattering", ITimeOfDay::PARAM_SKYLIGHT_KM, ITimeOfDay::TYPE_FLOAT, 4.8f, 0.0f, 1000.0f); - AddVar("Sky Light", "Rayleigh scattering", "Sky light: Rayleigh scattering", ITimeOfDay::PARAM_SKYLIGHT_KR, ITimeOfDay::TYPE_FLOAT, 2.0f, 0.0f, 1000.0f); - AddVar("Sky Light", "Sun anisotropy factor", "Sky light: Sun anisotropy factor", ITimeOfDay::PARAM_SKYLIGHT_G, ITimeOfDay::TYPE_FLOAT, -0.997f, -0.9999f, 0.9999f); - AddVar("Sky Light", "Wavelength (R)", "Sky light: Wavelength (R)", ITimeOfDay::PARAM_SKYLIGHT_WAVELENGTH_R, ITimeOfDay::TYPE_FLOAT, 694.0f, 380.0f, 780.0f); - AddVar("Sky Light", "Wavelength (G)", "Sky light: Wavelength (G)", ITimeOfDay::PARAM_SKYLIGHT_WAVELENGTH_G, ITimeOfDay::TYPE_FLOAT, 597.0f, 380.0f, 780.0f); - AddVar("Sky Light", "Wavelength (B)", "Sky light: Wavelength (B)", ITimeOfDay::PARAM_SKYLIGHT_WAVELENGTH_B, ITimeOfDay::TYPE_FLOAT, 488.0f, 380.0f, 780.0f); - - AddVar("Night Sky", "Horizon color", "Night sky: Horizon color", ITimeOfDay::PARAM_NIGHSKY_HORIZON_COLOR, ITimeOfDay::TYPE_COLOR, 222.0f * fRecip255, 148.0f * fRecip255, 47.0f * fRecip255); - AddVar("Night Sky", "Zenith color", "Night sky: Zenith color", ITimeOfDay::PARAM_NIGHSKY_ZENITH_COLOR, ITimeOfDay::TYPE_COLOR, 17.0f * fRecip255, 38.0f * fRecip255, 78.0f * fRecip255); - AddVar("Night Sky", "Zenith shift", "Night sky: Zenith shift", ITimeOfDay::PARAM_NIGHSKY_ZENITH_SHIFT, ITimeOfDay::TYPE_FLOAT, 0.25f, 0.0f, 16.0f); - AddVar("Night Sky", "Star intensity", "Night sky: Star intensity", ITimeOfDay::PARAM_NIGHSKY_START_INTENSITY, ITimeOfDay::TYPE_FLOAT, 0.01f, 0.0f, 16.0f); - AddVar("Night Sky", "Moon color", "Night sky: Moon color", ITimeOfDay::PARAM_NIGHSKY_MOON_COLOR, ITimeOfDay::TYPE_COLOR, 255.0f * fRecip255, 255.0f * fRecip255, 255.0f * fRecip255); - AddVar("Night Sky", "Moon inner corona color", "Night sky: Moon inner corona color", ITimeOfDay::PARAM_NIGHSKY_MOON_INNERCORONA_COLOR, ITimeOfDay::TYPE_COLOR, 230.0f * fRecip255, 255.0f * fRecip255, 255.0f * fRecip255); - AddVar("Night Sky", "Moon inner corona scale", "Night sky: Moon inner corona scale", ITimeOfDay::PARAM_NIGHSKY_MOON_INNERCORONA_SCALE, ITimeOfDay::TYPE_FLOAT, 0.499f, 0.0f, 2.0f); - AddVar("Night Sky", "Moon outer corona color", "Night sky: Moon outer corona color", ITimeOfDay::PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR, ITimeOfDay::TYPE_COLOR, 128.0f * fRecip255, 200.0f * fRecip255, 255.0f * fRecip255); - AddVar("Night Sky", "Moon outer corona scale", "Night sky: Moon outer corona scale", ITimeOfDay::PARAM_NIGHSKY_MOON_OUTERCORONA_SCALE, ITimeOfDay::TYPE_FLOAT, 0.006f, 0.0f, 2.0f); - - AddVar("Night Sky Multiplier", "Horizon color", "Night sky: Horizon color multiplier", ITimeOfDay::PARAM_NIGHSKY_HORIZON_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.0001f, 0.0f, 1.0f); - AddVar("Night Sky Multiplier", "Zenith color", "Night sky: Zenith color multiplier", ITimeOfDay::PARAM_NIGHSKY_ZENITH_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.00002f, 0.0f, 1.0f); - AddVar("Night Sky Multiplier", "Moon color", "Night sky: Moon color multiplier", ITimeOfDay::PARAM_NIGHSKY_MOON_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.01f, 0.0f, 1.0f); - AddVar("Night Sky Multiplier", "Moon inner corona color", "Night sky: Moon inner corona color multiplier", ITimeOfDay::PARAM_NIGHSKY_MOON_INNERCORONA_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.0001f, 0.0f, 1.0f); - AddVar("Night Sky Multiplier", "Moon outer corona color", "Night sky: Moon outer corona color multiplier", ITimeOfDay::PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.00005f, 0.0f, 1.0f); - - AddVar("Cloud Shading", "Sun contribution", "Cloud shading: Sun light multiplier", ITimeOfDay::PARAM_CLOUDSHADING_SUNLIGHT_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.96f, 0.0f, 16.0f); - AddVar("Cloud Shading", "Sun custom color", "Cloud shading: Sun custom color", ITimeOfDay::PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR, ITimeOfDay::TYPE_COLOR, 215.0f * fRecip255, 200.0f * fRecip255, 170.0f * fRecip255); - AddVar("Cloud Shading", "Sun custom color multiplier", "Cloud shading: Sun custom color multiplier", ITimeOfDay::PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 16.0f); - AddVar("Cloud Shading", "Sun custom color influence", "Cloud shading: Sun custom color influence", ITimeOfDay::PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR_INFLUENCE, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); - - AddVar("Sun Rays Effect", "", "Sun shafts visibility", ITimeOfDay::PARAM_SUN_SHAFTS_VISIBILITY, ITimeOfDay::TYPE_FLOAT, 0.25f, 0.0f, 1.0f); - AddVar("Sun Rays Effect", "", "Sun rays visibility", ITimeOfDay::PARAM_SUN_RAYS_VISIBILITY, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 10.0f); - AddVar("Sun Rays Effect", "", "Sun rays attenuation", ITimeOfDay::PARAM_SUN_RAYS_ATTENUATION, ITimeOfDay::TYPE_FLOAT, 5.0f, 0.0f, 10.0f); - AddVar("Sun Rays Effect", "", "Sun rays suncolor influence", ITimeOfDay::PARAM_SUN_RAYS_SUNCOLORINFLUENCE, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Sun Rays Effect", "", "Sun rays custom color", ITimeOfDay::PARAM_SUN_RAYS_CUSTOMCOLOR, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - - AddVar("HDR", "", "Film curve shoulder scale", ITimeOfDay::PARAM_HDR_FILMCURVE_SHOULDER_SCALE, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 10.0f); - AddVar("HDR", "", "Film curve midtones scale", ITimeOfDay::PARAM_HDR_FILMCURVE_LINEAR_SCALE, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 10.0f); - AddVar("HDR", "", "Film curve toe scale", ITimeOfDay::PARAM_HDR_FILMCURVE_TOE_SCALE, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 10.0f); - AddVar("HDR", "", "Film curve whitepoint", ITimeOfDay::PARAM_HDR_FILMCURVE_WHITEPOINT, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 10.0f); - AddVar("HDR", "", "Saturation", ITimeOfDay::PARAM_HDR_COLORGRADING_COLOR_SATURATION, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 2.0f); - AddVar("HDR", "", "Color balance", ITimeOfDay::PARAM_HDR_COLORGRADING_COLOR_BALANCE, ITimeOfDay::TYPE_COLOR, 1.0f, 1.0f, 1.0f); - AddVar("HDR", "(Dep) Scene key", "Scene key", ITimeOfDay::PARAM_HDR_EYEADAPTATION_SCENEKEY, ITimeOfDay::TYPE_FLOAT, 0.18f, 0.0f, 1.0f); - AddVar("HDR", "(Dep) Min exposure", "Min exposure", ITimeOfDay::PARAM_HDR_EYEADAPTATION_MIN_EXPOSURE, ITimeOfDay::TYPE_FLOAT, 0.36f, 0.0f, 10.0f); - AddVar("HDR", "(Dep) Max exposure", "Max exposure", ITimeOfDay::PARAM_HDR_EYEADAPTATION_MAX_EXPOSURE, ITimeOfDay::TYPE_FLOAT, 2.8f, 0.0f, 10.0f); - AddVar("HDR", "", "EV Min", ITimeOfDay::PARAM_HDR_EYEADAPTATION_EV_MIN, ITimeOfDay::TYPE_FLOAT, 4.5f, -10.0f, 20.0f); - AddVar("HDR", "", "EV Max", ITimeOfDay::PARAM_HDR_EYEADAPTATION_EV_MAX, ITimeOfDay::TYPE_FLOAT, 17.0f, -10.0f, 20.0f); - AddVar("HDR", "", "EV Auto compensation", ITimeOfDay::PARAM_HDR_EYEADAPTATION_EV_AUTO_COMPENSATION, ITimeOfDay::TYPE_FLOAT, 1.5f, -5.0f, 5.0f); - AddVar("HDR", "", "Bloom amount", ITimeOfDay::PARAM_HDR_BLOOM_AMOUNT, ITimeOfDay::TYPE_FLOAT, 0.1f, 0.0f, 10.0f); - - AddVar("Filters", "Grain", "Filters: grain", ITimeOfDay::PARAM_COLORGRADING_FILTERS_GRAIN, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 8.0f); // deprecated - AddVar("Filters", "Photofilter color", "Filters: photofilter color", ITimeOfDay::PARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR, ITimeOfDay::TYPE_COLOR, 0.952f, 0.517f, 0.09f); // deprecated - AddVar("Filters", "Photofilter density", "Filters: photofilter density", ITimeOfDay::PARAM_COLORGRADING_FILTERS_PHOTOFILTER_DENSITY, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); // deprecated - - AddVar("Depth Of Field", "Focus range", "Dof: focus range", ITimeOfDay::PARAM_COLORGRADING_DOF_FOCUSRANGE, ITimeOfDay::TYPE_FLOAT, 1000.0f, 0.0f, 10000.0f); - AddVar("Depth Of Field", "Blur amount", "Dof: blur amount", ITimeOfDay::PARAM_COLORGRADING_DOF_BLURAMOUNT, ITimeOfDay::TYPE_FLOAT, 0.0f, 0.0f, 1.0f); - - AddVar("Advanced", "", "Ocean fog color", ITimeOfDay::PARAM_OCEANFOG_COLOR, ITimeOfDay::TYPE_COLOR, 29.0f * fRecip255, 102.0f * fRecip255, 141.0f * fRecip255); - AddVar("Advanced", "", "Ocean fog color multiplier", ITimeOfDay::PARAM_OCEANFOG_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - AddVar("Advanced", "", "Ocean fog density", ITimeOfDay::PARAM_OCEANFOG_DENSITY, ITimeOfDay::TYPE_FLOAT, 0.2f, 0.0f, 1.0f); - - AddVar("Advanced", "", "Static skybox multiplier", ITimeOfDay::PARAM_SKYBOX_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 1.0f); - - const float arrDepthConstBias[] = {1.0f, 1.0f, 1.9f, 3.0f, 2.0f, 2.0f, 2.0f, 2.0f}; - const float arrDepthSlopeBias[] = {4.0f, 2.0f, 0.24f, 0.24f, 0.5f, 0.5f, 0.5f, 0.5f}; - AddVar("Shadows", "", "Cascade 0: Bias", ITimeOfDay::PARAM_SHADOWSC0_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[0], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 0: Slope Bias", ITimeOfDay::PARAM_SHADOWSC0_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[0], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 1: Bias", ITimeOfDay::PARAM_SHADOWSC1_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[1], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 1: Slope Bias", ITimeOfDay::PARAM_SHADOWSC1_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[1], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 2: Bias", ITimeOfDay::PARAM_SHADOWSC2_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[2], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 2: Slope Bias", ITimeOfDay::PARAM_SHADOWSC2_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[2], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 3: Bias", ITimeOfDay::PARAM_SHADOWSC3_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[3], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 3: Slope Bias", ITimeOfDay::PARAM_SHADOWSC3_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[3], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 4: Bias", ITimeOfDay::PARAM_SHADOWSC4_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[4], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 4: Slope Bias", ITimeOfDay::PARAM_SHADOWSC4_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[4], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 5: Bias", ITimeOfDay::PARAM_SHADOWSC5_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[5], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 5: Slope Bias", ITimeOfDay::PARAM_SHADOWSC5_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[5], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 6: Bias", ITimeOfDay::PARAM_SHADOWSC6_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[6], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 6: Slope Bias", ITimeOfDay::PARAM_SHADOWSC6_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[6], 0.0f, 500.0f); - AddVar("Shadows", "", "Cascade 7: Bias", ITimeOfDay::PARAM_SHADOWSC7_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthConstBias[7], 0.0f, 10.0f); - AddVar("Shadows", "", "Cascade 7: Slope Bias", ITimeOfDay::PARAM_SHADOWSC7_SLOPE_BIAS, ITimeOfDay::TYPE_FLOAT, arrDepthSlopeBias[7], 0.0f, 500.0f); - - AddVar("Shadows", "", "Shadow jittering", ITimeOfDay::PARAM_SHADOW_JITTERING, ITimeOfDay::TYPE_FLOAT, 2.5f, 0.f, 10.f); - - AddVar("Obsolete", "", "HDR dynamic power factor", ITimeOfDay::PARAM_HDR_DYNAMIC_POWER_FACTOR, ITimeOfDay::TYPE_FLOAT, 0.0f, -4.0f, 4.0f); - AddVar("Obsolete", "", "Sky brightening (terrain occlusion)", ITimeOfDay::PARAM_TERRAIN_OCCL_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 0.3f, 0.f, 1.f); - AddVar("Obsolete", "", "Sun color multiplier", ITimeOfDay::PARAM_SUN_COLOR_MULTIPLIER, ITimeOfDay::TYPE_FLOAT, 1.0f, 0.0f, 16.0f); -} - -void CEnvironmentPreset::Serialize(Serialization::IArchive& ar) -{ - for (size_t i = 0; i < ITimeOfDay::PARAM_TOTAL; ++i) - { - ar(m_vars[i], "var"); - } -} - -void CEnvironmentPreset::Update(float t) -{ - for (size_t i = 0; i < ITimeOfDay::PARAM_TOTAL; ++i) - { - m_vars[i].Update(t); - } -} - -CTimeOfDayVariable* CEnvironmentPreset::GetVar(const char* varName) -{ - for (size_t i = 0; i < ITimeOfDay::PARAM_TOTAL; ++i) - { - if (strcmp(m_vars[i].GetName(), varName) == 0) - { - return &m_vars[i]; - } - } - return NULL; -} - -bool CEnvironmentPreset::InterpolateVarInRange(ITimeOfDay::ETimeOfDayParamID id, float fMin, float fMax, unsigned int nCount, Vec3* resultArray) const -{ - const float fdx = 1.0f / float(nCount); - float normX = 0.0f; - for (unsigned int i = 0; i < nCount; ++i) - { - const float time = Lerp(fMin, fMax, normX); - resultArray[i] = m_vars[id].GetInterpolatedAt(time); - normX += fdx; - } - - return true; -} - -void CEnvironmentPreset::AddVar(const char* group, const char* displayName, const char* name, ITimeOfDay::ETimeOfDayParamID nParamId, ITimeOfDay::EVariableType type, float defVal0, float defVal1, float defVal2) -{ - CTimeOfDayVariable& var = m_vars[nParamId]; - var.Init(group, displayName, name, nParamId, type, defVal0, defVal1, defVal2); -} diff --git a/Code/CryEngine/Cry3DEngine/EnvironmentPreset.h b/Code/CryEngine/Cry3DEngine/EnvironmentPreset.h deleted file mode 100644 index 0fd4242f2e..0000000000 --- a/Code/CryEngine/Cry3DEngine/EnvironmentPreset.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _environment_preset_h_ -#define _environment_preset_h_ -#pragma once - -#include - -class CBezierSpline -{ -public: - CBezierSpline(); - ~CBezierSpline(); - - void Init(float fDefaultValue); - float Evaluate(float t) const; - - void SetKeys(const SBezierKey* keysArray, unsigned int keysArraySize) { m_keys.resize(keysArraySize); memcpy(&m_keys[0], keysArray, keysArraySize * sizeof(SBezierKey)); } - void GetKeys(SBezierKey* keys) const { memcpy(keys, &m_keys[0], m_keys.size() * sizeof(SBezierKey)); } - - void InsertKey(SAnimTime time, float value); - void UpdateKeyForTime(float fTime, float value); - - void Resize(size_t nSize) { m_keys.resize(nSize); } - - size_t GetKeyCount() const { return m_keys.size(); } - const SBezierKey& GetKey(size_t nIndex) const { return m_keys[nIndex]; } - SBezierKey& GetKey(size_t nIndex) { return m_keys[nIndex]; } - - void Serialize(Serialization::IArchive& ar); -private: - typedef std::vector TKeyContainer; - TKeyContainer m_keys; - - struct SCompKeyTime - { - bool operator()(const TKeyContainer::value_type& l, const TKeyContainer::value_type& r) const { return l.m_time < r.m_time; } - bool operator()(SAnimTime l, const TKeyContainer::value_type& r) const { return l < r.m_time; } - bool operator()(const TKeyContainer::value_type& l, SAnimTime r) const { return l.m_time < r; } - }; -}; - -////////////////////////////////////////////////////////////////////////// -class CTimeOfDayVariable -{ -public: - CTimeOfDayVariable(); - ~CTimeOfDayVariable(); - - void Init(const char* group, const char* displayName, const char* name, ITimeOfDay::ETimeOfDayParamID nParamId, ITimeOfDay::EVariableType type, float defVal0, float defVal1, float defVal2); - void Update(float time); - - Vec3 GetInterpolatedAt(float t) const; - - ITimeOfDay::EVariableType GetType() const {return m_type; } - const char* GetName() const { return m_name; } - const char* GetDisplayName() const { return m_displayName; } - const char* GetGroupName() const { return m_group; } - const Vec3 GetValue() const { return m_value; } - - float GetMinValue() const { return m_minValue; } - float GetMaxValue() const { return m_maxValue; } - - const CBezierSpline* GetSpline(int nIndex) const - { - if (nIndex >= 0 && nIndex < Vec3::component_count) - { - return &m_spline[nIndex]; - } - else - { - return NULL; - } - } - - CBezierSpline* GetSpline(int nIndex) - { - if (nIndex >= 0 && nIndex < Vec3::component_count) - { - return &m_spline[nIndex]; - } - else - { - return NULL; - } - } - - size_t GetSplineKeyCount(int nSpline) const; - bool GetSplineKeys(int nSpline, SBezierKey* keysArray, unsigned int keysArraySize) const; - bool SetSplineKeys(int nSpline, const SBezierKey* keysArray, unsigned int keysArraySize); - bool UpdateSplineKeyForTime(int nSpline, float fTime, float newKey); - - void Serialize(Serialization::IArchive& ar); -private: - ITimeOfDay::ETimeOfDayParamID m_id; - ITimeOfDay::EVariableType m_type; - - const char* m_name; // Variable name. - const char* m_displayName; // Variable user readable name. - const char* m_group; // Group name. - - float m_minValue; - float m_maxValue; - - Vec3 m_value; - CBezierSpline m_spline[Vec3::component_count]; //spline for each component in m_value -}; - -////////////////////////////////////////////////////////////////////////// -class CEnvironmentPreset -{ -public: - CEnvironmentPreset(); - ~CEnvironmentPreset(); - - void ResetVariables(); - void Update(float t); - - const CTimeOfDayVariable* GetVar(ITimeOfDay::ETimeOfDayParamID id) const { return &m_vars[id]; } - CTimeOfDayVariable* GetVar(ITimeOfDay::ETimeOfDayParamID id) { return &m_vars[id]; } - CTimeOfDayVariable* GetVar(const char* varName); - bool InterpolateVarInRange(ITimeOfDay::ETimeOfDayParamID id, float fMin, float fMax, unsigned int nCount, Vec3* resultArray) const; - - void Serialize(Serialization::IArchive& ar); - -private: - void AddVar(const char* group, const char* displayName, const char* name, ITimeOfDay::ETimeOfDayParamID nParamId, ITimeOfDay::EVariableType type, float defVal0, float defVal1, float defVal2); - - CTimeOfDayVariable m_vars[ITimeOfDay::PARAM_TOTAL]; -}; - -#endif //_environment_preset_h_ diff --git a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.cpp b/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.cpp deleted file mode 100644 index a3de520b1f..0000000000 --- a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "FogVolumeRenderNode.h" -#include "VisAreas.h" -#include "CREFogVolume.h" -#include "Cry_Geo.h" -#include "ObjMan.h" -#include "ClipVolumeManager.h" -#include "Environment/OceanEnvironmentBus.h" - -#include - - -AABB CFogVolumeRenderNode::s_tracableFogVolumeArea(Vec3(0, 0, 0), Vec3(0, 0, 0)); -StaticInstance CFogVolumeRenderNode::s_cachedFogVolumes; -StaticInstance CFogVolumeRenderNode::s_globalFogVolumeMap; -bool CFogVolumeRenderNode::s_forceTraceableAreaUpdate(false); - -void CFogVolumeRenderNode::StaticReset() -{ - stl::free_container(s_cachedFogVolumes); -} - -void CFogVolumeRenderNode::ForceTraceableAreaUpdate() -{ - s_forceTraceableAreaUpdate = true; -} - - -void CFogVolumeRenderNode::SetTraceableArea(const AABB& traceableArea, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - // do we bother? - if (!GetCVars()->e_Fog || !GetCVars()->e_FogVolumes) - { - return; - } - - if (GetCVars()->e_VolumetricFog != 0) - { - return; - } - - // is update of traceable areas necessary - if (!s_forceTraceableAreaUpdate) - { - if ((s_tracableFogVolumeArea.GetCenter() - traceableArea.GetCenter()).GetLengthSquared() < 1e-4f && (s_tracableFogVolumeArea.GetSize() - traceableArea.GetSize()).GetLengthSquared() < 1e-4f) - { - return; - } - } - - // set new area and reset list of traceable fog volumes - s_tracableFogVolumeArea = traceableArea; - s_cachedFogVolumes.resize(0); - - // collect all candidates - Vec3 traceableAreaCenter(s_tracableFogVolumeArea.GetCenter()); - IVisArea* pVisAreaOfCenter(GetVisAreaManager() ? GetVisAreaManager()->GetVisAreaFromPos(traceableAreaCenter) : NULL); - - GlobalFogVolumeMap::const_iterator itEnd(s_globalFogVolumeMap.end()); - for (GlobalFogVolumeMap::const_iterator it(s_globalFogVolumeMap.begin()); it != itEnd; ++it) - { - const CFogVolumeRenderNode* pFogVolume(*it); - if (pVisAreaOfCenter || (!pVisAreaOfCenter && !pFogVolume->GetEntityVisArea())) // if outside only add fog volumes which are outside as well - { - if (Overlap::AABB_AABB(s_tracableFogVolumeArea, pFogVolume->m_WSBBox)) // bb of fog volume overlaps with traceable area - { - s_cachedFogVolumes.push_back(SCachedFogVolume(pFogVolume, Vec3(pFogVolume->m_pos - traceableAreaCenter).GetLengthSquared())); - } - } - } - - // sort by distance - std::sort(s_cachedFogVolumes.begin(), s_cachedFogVolumes.end()); - - // reset force-update flags - s_forceTraceableAreaUpdate = false; -} - -void CFogVolumeRenderNode::RegisterFogVolume(const CFogVolumeRenderNode* pFogVolume) -{ - GlobalFogVolumeMap::const_iterator it(s_globalFogVolumeMap.find(pFogVolume)); - assert(it == s_globalFogVolumeMap.end() && - "CFogVolumeRenderNode::RegisterFogVolume() -- Fog volume already registered!"); - if (it == s_globalFogVolumeMap.end()) - { - s_globalFogVolumeMap.insert(pFogVolume); - ForceTraceableAreaUpdate(); - } -} - - -void CFogVolumeRenderNode::UnregisterFogVolume(const CFogVolumeRenderNode* pFogVolume) -{ - GlobalFogVolumeMap::iterator it(s_globalFogVolumeMap.find(pFogVolume)); - assert(it != s_globalFogVolumeMap.end() && - "CFogVolumeRenderNode::UnRegisterFogVolume() -- Fog volume previously not registered!"); - if (it != s_globalFogVolumeMap.end()) - { - s_globalFogVolumeMap.erase(it); - ForceTraceableAreaUpdate(); - } -} - - -CFogVolumeRenderNode::CFogVolumeRenderNode() - : m_matNodeWS() - , m_matWS() - , m_matWSInv() - , m_volumeType(0) - , m_pos(0, 0, 0) - , m_x(1, 0, 0) - , m_y(0, 1, 0) - , m_z(0, 0, 1) - , m_size(1, 1, 1) - , m_scale(1, 1, 1) - , m_globalDensity(1) - , m_densityOffset(0) - , m_nearCutoff(0) - , m_fHDRDynamic(0) - , m_softEdges(1) - , m_color(1, 1, 1, 1) - , m_useGlobalFogColor(false) - , m_affectsThisAreaOnly(false) - , m_rampParams(0, 1, 0) - , m_updateFrameID(0) - , m_windInfluence(1) - , m_noiseElapsedTime(-5000.0f) - , m_densityNoiseScale(0) - , m_densityNoiseOffset(0) - , m_densityNoiseTimeFrequency(0) - , m_densityNoiseFrequency(1, 1, 1) - , m_heightFallOffDir(0, 0, 1) - , m_heightFallOffDirScaled(0, 0, 1) - , m_heightFallOffShift(0, 0, 0) - , m_heightFallOffBasePoint(0, 0, 0) - , m_localBounds(Vec3(-0.5f, -0.5f, -0.5f), Vec3(0.5f, 0.5f, 0.5f)) - , m_globalDensityFader() - , m_pMatFogVolEllipsoid(0) - , m_pMatFogVolBox(0) - , m_WSBBox() - , m_cachedSoftEdgesLerp(1, 0) - , m_cachedFogColor(1, 1, 1, 1) -{ - m_matNodeWS.SetIdentity(); - - m_matWS.SetIdentity(); - m_matWSInv.SetIdentity(); - - m_windOffset.x = cry_random(0.0f, 1000.0f); - m_windOffset.y = cry_random(0.0f, 1000.0f); - m_windOffset.z = cry_random(0.0f, 1000.0f); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pFogVolumeRenderElement[i] = (CREFogVolume*) GetRenderer()->EF_CreateRE(eDATA_FogVolume); - } - - m_pMatFogVolEllipsoid = Get3DEngine()->m_pMatFogVolEllipsoid; - m_pMatFogVolBox = Get3DEngine()->m_pMatFogVolBox; - - //Get3DEngine()->RegisterEntity( this ); - RegisterFogVolume(this); -} - - -CFogVolumeRenderNode::~CFogVolumeRenderNode() -{ - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - if (m_pFogVolumeRenderElement[i]) - { - m_pFogVolumeRenderElement[i]->Release(false); - m_pFogVolumeRenderElement[i] = 0; - } - } - - UnregisterFogVolume(this); - Get3DEngine()->FreeRenderNodeState(this); -} - - -void CFogVolumeRenderNode::UpdateFogVolumeMatrices() -{ - // update matrices used for ray tracing, distance sorting, etc. - Matrix34 mtx = Matrix34::CreateFromVectors(m_size.x * m_x * 0.5f, m_size.y * m_y * 0.5f, m_size.z * m_z * 0.5f, m_pos); - m_matWS = mtx; - m_matWSInv = mtx.GetInverted(); -} - - -void CFogVolumeRenderNode::UpdateWorldSpaceBBox() -{ - // update bounding box in world space used for culling - m_WSBBox.SetTransformedAABB(m_matNodeWS, m_localBounds); -} - - -void CFogVolumeRenderNode::UpdateHeightFallOffBasePoint() -{ - m_heightFallOffBasePoint = m_pos + m_heightFallOffShift; -} - - -void CFogVolumeRenderNode::SetFogVolumeProperties(const SFogVolumeProperties& properties) -{ - m_globalDensityFader.SetInvalid(); - - assert(properties.m_size.x > 0 && properties.m_size.y > 0 && properties.m_size.z > 0); - if ((m_size - properties.m_size).GetLengthSquared() > 1e-4) - { - m_size = properties.m_size; - m_localBounds.min = Vec3(-0.5f, -0.5f, -0.5f).CompMul(m_size); - m_localBounds.max = -m_localBounds.min; - UpdateWorldSpaceBBox(); - } - - m_volumeType = properties.m_volumeType; - assert(m_volumeType >= 0 && m_volumeType <= 1); - m_color = properties.m_color; - assert(properties.m_globalDensity >= 0); - m_useGlobalFogColor = properties.m_useGlobalFogColor; - m_globalDensity = properties.m_globalDensity; - m_densityOffset = properties.m_densityOffset; - m_nearCutoff = properties.m_nearCutoff; - m_fHDRDynamic = properties.m_fHDRDynamic; - assert(properties.m_softEdges >= 0 && properties.m_softEdges <= 1); - m_softEdges = properties.m_softEdges; - - // IgnoreVisArea and AffectsThisAreaOnly don't work concurrently. - SetRndFlags(ERF_RENDER_ALWAYS, properties.m_ignoresVisAreas && !properties.m_affectsThisAreaOnly); - - m_affectsThisAreaOnly = properties.m_affectsThisAreaOnly; - - float latiArc(DEG2RAD(90.0f - properties.m_heightFallOffDirLati)); - float longArc(DEG2RAD(properties.m_heightFallOffDirLong)); - float sinLati(sinf(latiArc)); - float cosLati(cosf(latiArc)); - float sinLong(sinf(longArc)); - float cosLong(cosf(longArc)); - m_heightFallOffDir = Vec3(sinLati * cosLong, sinLati * sinLong, cosLati); - m_heightFallOffShift = m_heightFallOffDir * properties.m_heightFallOffShift; - m_heightFallOffDirScaled = m_heightFallOffDir * properties.m_heightFallOffScale; - UpdateHeightFallOffBasePoint(); - - m_rampParams = Vec3(properties.m_rampStart, properties.m_rampEnd, properties.m_rampInfluence); - - m_windInfluence = properties.m_windInfluence; - m_densityNoiseScale = properties.m_densityNoiseScale; - m_densityNoiseOffset = properties.m_densityNoiseOffset + 1.0f; - m_densityNoiseTimeFrequency = properties.m_densityNoiseTimeFrequency; - m_densityNoiseFrequency = properties.m_densityNoiseFrequency * 0.01f;// scale the value to useful range -} - - -const Matrix34& CFogVolumeRenderNode::GetMatrix() const -{ - return m_matNodeWS; -} - - -void CFogVolumeRenderNode::GetLocalBounds(AABB& bbox) -{ - bbox = m_localBounds; -}; - - -void CFogVolumeRenderNode::SetMatrix(const Matrix34& mat) -{ - m_matNodeWS = mat; - - // get translation and rotational part of fog volume from entity matrix - // scale is specified explicitly as fog volumes can be non-uniformly scaled - m_pos = m_matNodeWS.GetTranslation(); - m_x = m_matNodeWS.GetColumn(0); - m_y = m_matNodeWS.GetColumn(1); - m_z = m_matNodeWS.GetColumn(2); - - UpdateFogVolumeMatrices(); - UpdateWorldSpaceBBox(); - UpdateHeightFallOffBasePoint(); - - Get3DEngine()->RegisterEntity(this); - ForceTraceableAreaUpdate(); -} - -void CFogVolumeRenderNode::SetScale(const Vec3& scale) -{ - m_scale = scale; -} - -void CFogVolumeRenderNode::FadeGlobalDensity(float fadeTime, float newGlobalDensity) -{ - if (newGlobalDensity >= 0) - { - if (fadeTime == 0) - { - m_globalDensity = newGlobalDensity; - m_globalDensityFader.SetInvalid(); - } - else if (fadeTime > 0) - { - float curFrameTime(gEnv->pTimer->GetCurrTime()); - m_globalDensityFader.Set(curFrameTime, curFrameTime + fadeTime, m_globalDensity, newGlobalDensity); - } - } -} - -const char* CFogVolumeRenderNode::GetEntityClassName() const -{ - return "FogVolume"; -} - - -const char* CFogVolumeRenderNode::GetName() const -{ - return "FogVolume"; -} - - -ColorF CFogVolumeRenderNode::GetFogColor() const -{ - //FUNCTION_PROFILER_3DENGINE - Vec3 fogColor(m_color.r, m_color.g, m_color.b); - - bool bVolFogEnabled = (GetCVars()->e_VolumetricFog != 0); - if (bVolFogEnabled) - { - if (m_useGlobalFogColor) - { - Get3DEngine()->GetGlobalParameter(E3DPARAM_VOLFOG2_COLOR, fogColor); - } - } - else - { - if (m_useGlobalFogColor) - { - fogColor = Get3DEngine()->GetFogColor(); - } - - bool bHDRModeEnabled = false; - GetRenderer()->EF_Query(EFQ_HDRModeEnabled, bHDRModeEnabled); - if (bHDRModeEnabled) - { - const float HDRDynamicMultiplier = 2.0f; - fogColor *= powf(HDRDynamicMultiplier, m_fHDRDynamic); - } - } - - return fogColor; -} - - -Vec2 CFogVolumeRenderNode::GetSoftEdgeLerp(const Vec3& viewerPosOS) const -{ - // Volumetric fog doesn't need special treatment when camera is in the ellipsoid. - if (GetCVars()->e_VolumetricFog != 0) - { - return Vec2(m_softEdges, 1.0f - m_softEdges); - } - - //FUNCTION_PROFILER_3DENGINE - // ramp down soft edge factor as soon as camera enters the ellipsoid - float softEdge(m_softEdges * clamp_tpl((viewerPosOS.GetLength() - 0.95f) * 20.0f, 0.0f, 1.0f)); - return Vec2(softEdge, 1.0f - softEdge); -} - - -bool CFogVolumeRenderNode::IsViewerInsideVolume(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - - // check if fog volumes bounding box intersects the near clipping plane - const Plane* pNearPlane(cam.GetFrustumPlane(FR_PLANE_NEAR)); - Vec3 pntOnNearPlane(cam.GetPosition() - pNearPlane->DistFromPlane(cam.GetPosition()) * pNearPlane->n); - Vec3 pntOnNearPlaneOS(m_matWSInv.TransformPoint(pntOnNearPlane)); - - Vec3 nearPlaneOS_n(m_matWSInv.TransformVector(pNearPlane->n) /*.GetNormalized()*/); - f32 nearPlaneOS_d(-nearPlaneOS_n.Dot(pntOnNearPlaneOS)); - - // get extreme lengths - float t(fabsf(nearPlaneOS_n.x) + fabsf(nearPlaneOS_n.y) + fabsf(nearPlaneOS_n.z)); - //float t( 0.0f ); - //if( nearPlaneOS_n.x >= 0 ) t += -nearPlaneOS_n.x; else t += nearPlaneOS_n.x; - //if( nearPlaneOS_n.y >= 0 ) t += -nearPlaneOS_n.y; else t += nearPlaneOS_n.y; - //if( nearPlaneOS_n.z >= 0 ) t += -nearPlaneOS_n.z; else t += nearPlaneOS_n.z; - - float t0 = t + nearPlaneOS_d; - float t1 = -t + nearPlaneOS_d; - - return t0 * t1 < 0.0f; -} - - -void CFogVolumeRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // anything to render? - if (passInfo.IsRecursivePass()) - { - return; - } - - if (!m_pMatFogVolBox || !m_pMatFogVolEllipsoid || GetCVars()->e_Fog == 0 || GetCVars()->e_FogVolumes == 0) - { - return; - } - - const int32 fillThreadID = passInfo.ThreadID(); - - if (!m_pFogVolumeRenderElement[fillThreadID]) - { - return; - } - - if (m_globalDensityFader.IsValid()) - { - float curFrameTime(gEnv->pTimer->GetCurrTime()); - m_globalDensity = m_globalDensityFader.GetValue(curFrameTime); - if (!m_globalDensityFader.IsTimeInRange(curFrameTime)) - { - m_globalDensityFader.SetInvalid(); - } - } - - // transform camera into fog volumes object space (where fog volume is a unit-sphere at (0,0,0)) - const CCamera& cam(passInfo.GetCamera()); - Vec3 viewerPosWS(cam.GetPosition()); - Vec3 viewerPosOS(m_matWSInv * viewerPosWS); - - m_cachedFogColor = GetFogColor(); - m_cachedSoftEdgesLerp = GetSoftEdgeLerp(viewerPosOS); - - bool bVolFog = (GetCVars()->e_VolumetricFog != 0); - - // reset elapsed time for noise when FogVolume stayed out of viewport for 30 frames. - // this prevents the time from being too large number. - if ((m_updateFrameID + 30) < passInfo.GetMainFrameID() && m_noiseElapsedTime > 5000.0f) - { - m_noiseElapsedTime = -5000.0f; - } - - if (bVolFog && m_densityNoiseScale > 0.0f && m_updateFrameID != passInfo.GetMainFrameID()) - { - Vec3 wind = Get3DEngine()->GetGlobalWind(false); - const float elapsedTime = gEnv->pTimer->GetFrameTime(); - - m_windOffset = ((-m_windInfluence * elapsedTime) * wind) + m_windOffset; - - const float windOffsetSpan = 1000.0f;// it should match the constant value in FogVolume.cfx - m_windOffset.x = m_windOffset.x - floor(m_windOffset.x / windOffsetSpan) * windOffsetSpan; - m_windOffset.y = m_windOffset.y - floor(m_windOffset.y / windOffsetSpan) * windOffsetSpan; - m_windOffset.z = m_windOffset.z - floor(m_windOffset.z / windOffsetSpan) * windOffsetSpan; - - m_noiseElapsedTime += m_densityNoiseTimeFrequency * elapsedTime; - - m_updateFrameID = passInfo.GetMainFrameID(); - } - - float densityOffset = bVolFog ? (m_densityOffset * 0.001f) : m_densityOffset;// scale the value to useful range - // set render element attributes - m_pFogVolumeRenderElement[fillThreadID]->m_center = m_pos; - m_pFogVolumeRenderElement[fillThreadID]->m_viewerInsideVolume = IsViewerInsideVolume(passInfo) ? 1 : 0; - m_pFogVolumeRenderElement[fillThreadID]->m_affectsThisAreaOnly = m_affectsThisAreaOnly ? 1 : 0; - m_pFogVolumeRenderElement[fillThreadID]->m_stencilRef = rParam.nClipVolumeStencilRef; - m_pFogVolumeRenderElement[fillThreadID]->m_volumeType = (m_volumeType != 0) ? 1 : 0; - m_pFogVolumeRenderElement[fillThreadID]->m_localAABB = m_localBounds; - m_pFogVolumeRenderElement[fillThreadID]->m_matWSInv = m_matWSInv; - m_pFogVolumeRenderElement[fillThreadID]->m_fogColor = m_cachedFogColor; - m_pFogVolumeRenderElement[fillThreadID]->m_globalDensity = m_globalDensity; - m_pFogVolumeRenderElement[fillThreadID]->m_densityOffset = densityOffset; - m_pFogVolumeRenderElement[fillThreadID]->m_nearCutoff = m_nearCutoff; - m_pFogVolumeRenderElement[fillThreadID]->m_softEdgesLerp = m_cachedSoftEdgesLerp; - m_pFogVolumeRenderElement[fillThreadID]->m_heightFallOffDirScaled = m_heightFallOffDirScaled; - m_pFogVolumeRenderElement[fillThreadID]->m_heightFallOffBasePoint = m_heightFallOffBasePoint; - m_pFogVolumeRenderElement[fillThreadID]->m_eyePosInWS = viewerPosWS; - m_pFogVolumeRenderElement[fillThreadID]->m_eyePosInOS = viewerPosOS; - m_pFogVolumeRenderElement[fillThreadID]->m_rampParams = m_rampParams; - m_pFogVolumeRenderElement[fillThreadID]->m_windOffset = m_windOffset; - m_pFogVolumeRenderElement[fillThreadID]->m_noiseScale = m_densityNoiseScale; - m_pFogVolumeRenderElement[fillThreadID]->m_noiseFreq = m_densityNoiseFrequency; - m_pFogVolumeRenderElement[fillThreadID]->m_noiseOffset = m_densityNoiseOffset; - m_pFogVolumeRenderElement[fillThreadID]->m_noiseElapsedTime = m_noiseElapsedTime; - m_pFogVolumeRenderElement[fillThreadID]->m_scale = m_scale; - - if (bVolFog && GetCVars()->e_FogVolumesTiledInjection) - { - // add FogVolume to volumetric fog renderer - GetRenderer()->PushFogVolume(m_pFogVolumeRenderElement[fillThreadID], passInfo); - } - else - { - IRenderer* pRenderer = GetRenderer(); - CRenderObject* pRenderObject = pRenderer->EF_GetObject_Temp(fillThreadID); - - if (!pRenderObject) - { - return; - } - - // set basic render object properties - pRenderObject->m_II.m_Matrix = m_matNodeWS; - pRenderObject->m_fSort = 0; - - int nAfterWater = GetObjManager()->IsAfterWater(m_pos, passInfo) ? 1 : 0; - - // TODO: add constant factor to sortID to make fog volumes render before all other alpha transparent geometry (or have separate render list?) - pRenderObject->m_fSort = WATER_LEVEL_SORTID_OFFSET * 0.5f; - - // get shader item - SShaderItem& shaderItem(0 != rParam.pMaterial ? rParam.pMaterial->GetShaderItem(0) : - 1 == m_volumeType ? m_pMatFogVolBox->GetShaderItem(0) : m_pMatFogVolEllipsoid->GetShaderItem(0)); - - // get target render list - int nList = bVolFog ? EFSLIST_FOG_VOLUME : EFSLIST_TRANSP; - - // add to renderer - GetRenderer()->EF_AddEf(m_pFogVolumeRenderElement[fillThreadID], shaderItem, pRenderObject, passInfo, nList, nAfterWater, SRendItemSorter(rParam.rendItemSorter)); - } -} - - -void CFogVolumeRenderNode::SetMaterial(_smart_ptr pMat) -{ -} - - -void CFogVolumeRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "FogVolumeNode"); - pSizer->AddObject(this, sizeof(*this)); -} - -void CFogVolumeRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_pos += delta; - m_matNodeWS.SetTranslation(m_matNodeWS.GetTranslation() + delta); - m_matWS.SetTranslation(m_matWS.GetTranslation() + delta); - m_matWSInv = m_matWS.GetInverted(); - m_heightFallOffBasePoint += delta; - m_WSBBox.Move(delta); -} diff --git a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.h b/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.h deleted file mode 100644 index ef647c5368..0000000000 --- a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_FOGVOLUMERENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_FOGVOLUMERENDERNODE_H -#pragma once - - -class CREFogVolume; - - -class CFogVolumeRenderNode - : public IFogVolumeRenderNode - , public Cry3DEngineBase -{ -public: - static void StaticReset(); - - static void SetTraceableArea(const AABB& traceableArea, const SRenderingPassInfo& passInfo); - static void TraceFogVolumes(const Vec3& vPos, const AABB& objBBox, SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo, bool fogVolumeShadingQuality); - static bool OverlapProjectedAABB(const AABB& objBBox0, const AABB& objBBox1, const CCamera& camera); -public: - CFogVolumeRenderNode(); - - // implements IFogVolumeRenderNode - virtual void SetFogVolumeProperties(const SFogVolumeProperties& properties); - virtual const Matrix34& GetMatrix() const; - - virtual void FadeGlobalDensity(float fadeTime, float newGlobalDensity); - - // implements IRenderNode - virtual void GetLocalBounds(AABB& bbox); - virtual void SetMatrix(const Matrix34& mat); - virtual void SetScale(const Vec3& scale); - - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const; - virtual const char* GetName() const; - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - void SetMaterial(_smart_ptr pMat) override; - virtual _smart_ptr GetMaterial(Vec3* pHitPos); - virtual _smart_ptr GetMaterialOverride() { return NULL; } - virtual float GetMaxViewDist(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - float GetGlobalDensity() const { return m_globalDensity; } - float GetDensityoffset() const { return m_densityOffset; } - Vec3 GetHeightFallOffBasePoint() const { return m_heightFallOffBasePoint; } - Vec3 GetHeightFallOffDirScaled() const { return m_heightFallOffDirScaled; } - - - ILINE bool IsAffectsThisAreaOnly() const { return m_affectsThisAreaOnly; } - int GetVolumeType() const { return m_volumeType; } -private: - static void RegisterFogVolume(const CFogVolumeRenderNode* pFogVolume); - static void UnregisterFogVolume(const CFogVolumeRenderNode* pFogVolume); - -private: - ~CFogVolumeRenderNode(); - - void UpdateFogVolumeMatrices(); - void UpdateWorldSpaceBBox(); - void UpdateHeightFallOffBasePoint(); - ColorF GetFogColor() const; - Vec2 GetSoftEdgeLerp(const Vec3& viewerPosOS) const; - bool IsViewerInsideVolume(const SRenderingPassInfo& passInfo) const; - - void GetVolumetricFogColorEllipsoid(const Vec3& worldPos, const SRenderingPassInfo& passInfo, ColorF& resultColor) const; - void GetVolumetricFogColorBox(const Vec3& worldPos, const SRenderingPassInfo& passInfo, ColorF& resultColor) const; - - static void ForceTraceableAreaUpdate(); - -private: - struct SCachedFogVolume - { - SCachedFogVolume() - : m_pFogVol(0) - , m_distToCenterSq(0) {} - - SCachedFogVolume(const CFogVolumeRenderNode* pFogVol, float distToCenterSq) - : m_pFogVol(pFogVol) - , m_distToCenterSq(distToCenterSq) - { - } - - bool operator < (const SCachedFogVolume& rhs) const - { - return m_distToCenterSq > rhs.m_distToCenterSq; - } - - const CFogVolumeRenderNode* m_pFogVol; - float m_distToCenterSq; - }; - - typedef std::vector< SCachedFogVolume > CachedFogVolumes; - typedef std::set< const CFogVolumeRenderNode* > GlobalFogVolumeMap; - - static AABB s_tracableFogVolumeArea; - static StaticInstance s_cachedFogVolumes; - static StaticInstance s_globalFogVolumeMap; - static bool s_forceTraceableAreaUpdate; - - struct SFader - { - SFader() - : m_startTime(0) - , m_endTime(0) - , m_startValue(0) - , m_endValue(0) - { - } - - void Set(float startTime, float endTime, float startValue, float endValue) - { - m_startTime = startTime; - m_endTime = endTime; - m_startValue = startValue; - m_endValue = endValue; - } - - void SetInvalid() - { - Set(0, 0, 0, 0); - } - - bool IsValid() - { - return m_startTime >= 0 && m_endTime > m_startTime && m_startValue != m_endValue; - } - - bool IsTimeInRange(float time) - { - return time >= m_startTime && time <= m_endTime; - } - - float GetValue(float time) - { - float t = clamp_tpl((time - m_startTime) / (m_endTime - m_startTime), 0.0f, 1.0f); - return m_startValue + t * (m_endValue - m_startValue); - } - - private: - float m_startTime; - float m_endTime; - float m_startValue; - float m_endValue; - }; - -private: - Matrix34 m_matNodeWS; - - Matrix34 m_matWS; - Matrix34 m_matWSInv; - - int m_volumeType; - Vec3 m_pos; - Vec3 m_x; - Vec3 m_y; - Vec3 m_z; - // size of fog set by SFogVolumeProperties - Vec3 m_size; - // scale on entity - Vec3 m_scale; - - float m_globalDensity; - float m_densityOffset; - float m_nearCutoff; - float m_fHDRDynamic; - float m_softEdges; - ColorF m_color; - bool m_useGlobalFogColor; - bool m_affectsThisAreaOnly; - Vec3 m_rampParams; - uint32 m_updateFrameID; - float m_windInfluence; - Vec3 m_windOffset; - float m_noiseElapsedTime; - float m_densityNoiseScale; - float m_densityNoiseOffset; - float m_densityNoiseTimeFrequency; - Vec3 m_densityNoiseFrequency; - - Vec3 m_heightFallOffDir; - Vec3 m_heightFallOffDirScaled; - Vec3 m_heightFallOffShift; - Vec3 m_heightFallOffBasePoint; - - AABB m_localBounds; - - SFader m_globalDensityFader; - - _smart_ptr< IMaterial > m_pMatFogVolEllipsoid; - _smart_ptr< IMaterial > m_pMatFogVolBox; - - CREFogVolume* m_pFogVolumeRenderElement[RT_COMMAND_BUF_COUNT]; - AABB m_WSBBox; - - Vec2 m_cachedSoftEdgesLerp; - ColorF m_cachedFogColor; -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_FOGVOLUMERENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode_Jobs.cpp b/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode_Jobs.cpp deleted file mode 100644 index 7f6b359d78..0000000000 --- a/Code/CryEngine/Cry3DEngine/FogVolumeRenderNode_Jobs.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "FogVolumeRenderNode.h" -#include "VisAreas.h" -#include "CREFogVolume.h" -#include "Cry_Geo.h" -#include "ObjMan.h" - - -/////////////////////////////////////////////////////////////////////////////// -inline static float expf_s(float arg) -{ - return expf(clamp_tpl(arg, -80.0f, 80.0f)); -} - -AABB UnprojectAABB2D(const AABB& aabb, const CCamera& camera) -{ - Vec3 results[4]; - camera.Unproject(Vec3(aabb.min.x, aabb.min.y, 1), results[0]); - camera.Unproject(Vec3(aabb.max.x, aabb.min.y, 1), results[1]); - camera.Unproject(Vec3(aabb.max.x, aabb.max.y, 1), results[2]); - camera.Unproject(Vec3(aabb.min.x, aabb.max.y, 1), results[3]); - - AABB newAABB(AABB::RESET); - newAABB.Add(results[0]); - newAABB.Add(results[1]); - newAABB.Add(results[2]); - newAABB.Add(results[3]); - return newAABB; -} - -AABB GetProjectedQuadFromAABB(const AABB& aabb, const CCamera& camera) -{ - // Get all 8 points of the AABB - - Vec3 aabbPoints[] = - { - Vec3(aabb.max.x, aabb.max.y, aabb.max.z), - Vec3(aabb.max.x, aabb.min.y, aabb.max.z), - Vec3(aabb.min.x, aabb.min.y, aabb.max.z), - Vec3(aabb.min.x, aabb.max.y, aabb.max.z), - Vec3(aabb.max.x, aabb.max.y, aabb.min.z), - Vec3(aabb.max.x, aabb.min.y, aabb.min.z), - Vec3(aabb.min.x, aabb.min.y, aabb.min.z), - Vec3(aabb.min.x, aabb.max.y, aabb.min.z), - }; - const int numAABBPoints = AZ_ARRAY_SIZE(aabbPoints); - - AZ_Assert(numAABBPoints==8,"you should have 8 points in the aabb"); - - // Project each AABB point and construct another AABB. - AABB quadResult(AABB::RESET); - for (int i = 0; i < numAABBPoints; ++i) - { - Vec3 projectedPoint; - camera.Project(aabbPoints[i], projectedPoint); - quadResult.Add(projectedPoint); - } - return quadResult; -} - - -// To know if aabb are aligned with camera, we test if projected quads overlap. -bool CFogVolumeRenderNode::OverlapProjectedAABB(const AABB& aabb0, const AABB& aabb1, const CCamera& camera) -{ - // quads are AABB2D. - AABB quad0 = GetProjectedQuadFromAABB(aabb0, camera); - AABB quad1 = GetProjectedQuadFromAABB(aabb1, camera); - bool bOverlap = Overlap::AABB_AABB2D(quad0, quad1); - return bOverlap; -} - -void AverageFogVolume(SFogVolumeData& fogVolData, const CFogVolumeRenderNode* pFogVol) -{ - AABB& avgAABBoxOut = fogVolData.avgAABBox; - avgAABBoxOut.Add(pFogVol->GetBBox()); - - // ratio is used to approximate fog volumes contribution depending of the importance of their size. - float ratio = pFogVol->GetBBox().GetRadius() / avgAABBoxOut.GetRadius(); - fogVolData.m_heightFallOffBasePoint = Lerp(fogVolData.m_heightFallOffBasePoint,pFogVol->GetHeightFallOffBasePoint(), ratio); - fogVolData.m_heightFallOffDirScaled = Lerp(fogVolData.m_heightFallOffDirScaled,pFogVol->GetHeightFallOffDirScaled(), ratio); - fogVolData.m_densityOffset = Lerp(fogVolData.m_densityOffset, pFogVol->GetDensityoffset(), ratio); - fogVolData.m_globalDensity = Lerp(fogVolData.m_globalDensity, pFogVol->GetGlobalDensity(), ratio); - fogVolData.m_volumeType |= pFogVol->GetVolumeType(); -} - -/////////////////////////////////////////////////////////////////////////////// -// TraceFogVolumes : -// if object intersects/is aligned with fog volumes then register these fog volumes, -// check if object is in front of the fog volume and compute average color. -// if highVertexShadingQuality average fog volume box. -/////////////////////////////////////////////////////////////////////////////// -void CFogVolumeRenderNode::TraceFogVolumes(const Vec3& objPosition, const AABB& objAABB, SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo, bool fogVolumeShadingQuality) -{ - FUNCTION_PROFILER_3DENGINE; - PrefetchLine(&s_tracableFogVolumeArea, 0); - - // init default result - ColorF localFogColor = ColorF(0.0f, 0.0f, 0.0f, 0.0f); - - // We will "accumulate" fog volumes contribution the same way that fog color. - - // trace is needed when volumetric fog is off. - if (GetCVars()->e_Fog && GetCVars()->e_FogVolumes && (GetCVars()->e_VolumetricFog == 0)) - { - const Vec3 worldPos = objPosition; - - // init view ray - Vec3 camPos(s_tracableFogVolumeArea.GetCenter()); - Lineseg lineseg(camPos, objPosition); - -#ifdef _DEBUG - const SCachedFogVolume* prev(0); -#endif - - // loop over all traceable fog volumes - CachedFogVolumes::const_iterator itEnd(s_cachedFogVolumes.end()); - for (CachedFogVolumes::const_iterator it(s_cachedFogVolumes.begin()); it != itEnd; ++it) - { - // get current fog volume - const CFogVolumeRenderNode* pFogVol((*it).m_pFogVol); - - bool isAligned = false; - bool isFrontOfBoxCenter = false; - // only trace visible fog volumes - if (!(pFogVol->GetRndFlags() & ERF_HIDDEN)) - { - bool projectedAABBIntersect = false; - bool isInside = Overlap::Point_AABB(objPosition, pFogVol->m_WSBBox); - - if (fogVolumeShadingQuality) - { - projectedAABBIntersect = OverlapProjectedAABB(pFogVol->m_WSBBox, objAABB, passInfo.GetCamera()); - isInside = isInside || Overlap::AABB_AABB(objAABB, pFogVol->m_WSBBox); - } - - // check if view ray intersects with bounding box of current fog volume - isAligned = Overlap::Lineseg_AABB(lineseg, pFogVol->m_WSBBox); - if (projectedAABBIntersect || isAligned) - { - // compute contribution of current fog volume - ColorF color(0,0,0); - - // Get distance camera to fog volume. - const CCamera& cam(passInfo.GetCamera()); - Vec3 cameraToObject(objPosition - cam.GetPosition()); - Vec3 cameraToFogVolume(pFogVol->m_WSBBox.GetCenter() - cam.GetPosition()); - isFrontOfBoxCenter = (cameraToFogVolume.GetLengthSquared() > cameraToObject.GetLengthSquared()); - // if particle is in front of the box center and not inside the box, then do not accumulate fog color. - if (isFrontOfBoxCenter && !isInside) - { - continue; - } - - if (fogVolumeShadingQuality) - { - // Accumulate this fogVolData - AverageFogVolume(fogVolData, pFogVol); - color = pFogVol->GetFogColor(); - } - else - { - if (0 == pFogVol->m_volumeType) - { - pFogVol->GetVolumetricFogColorEllipsoid(worldPos, passInfo, color); - } - else - { - pFogVol->GetVolumetricFogColorBox(worldPos, passInfo, color); - } - - color.a = 1.0f - color.a; // 0 = transparent, 1 = opaque - } - - - - // blend fog colors - localFogColor.r = Lerp(localFogColor.r, color.r, color.a); - localFogColor.g = Lerp(localFogColor.g, color.g, color.a); - localFogColor.b = Lerp(localFogColor.b, color.b, color.a); - localFogColor.a = Lerp(localFogColor.a, 1.0f, color.a); - - } - - } - -#ifdef _DEBUG - if (prev) - { - assert(prev->m_distToCenterSq >= (*it).m_distToCenterSq); - prev = &(*it); - } -#endif - } - - const float fDivisor = (float)fsel(-localFogColor.a, 1.0f, localFogColor.a); - const float fMultiplier = (float)fsel(-localFogColor.a, 0.0f, 1.0f / fDivisor); - - localFogColor.r *= fMultiplier; - localFogColor.g *= fMultiplier; - localFogColor.b *= fMultiplier; - } - - localFogColor.a = 1.0f - localFogColor.a; - fogVolData.fogColor = localFogColor; -} - -/////////////////////////////////////////////////////////////////////////////// -void CFogVolumeRenderNode::GetVolumetricFogColorEllipsoid(const Vec3& worldPos, const SRenderingPassInfo& passInfo, ColorF& resultColor) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPos(cam.GetPosition()); - Vec3 camDir(cam.GetViewdir()); - Vec3 cameraLookDir(worldPos - camPos); - - resultColor = ColorF(1.0f, 1.0f, 1.0f, 1.0f); - - if (cameraLookDir.GetLengthSquared() > 1e-4f) - { - // setup ray tracing in OS - Vec3 cameraPosInOSx2(m_matWSInv.TransformPoint(camPos) * 2.0f); - Vec3 cameraLookDirInOS(m_matWSInv.TransformVector(cameraLookDir)); - - float tI(sqrtf(cameraLookDirInOS.Dot(cameraLookDirInOS))); - float invOfScaledCamDirLength(1.0f / tI); - cameraLookDirInOS *= invOfScaledCamDirLength; - - // calc coefficients for ellipsoid parametrization (just a simple unit-sphere in its own space) - float B(cameraPosInOSx2.Dot(cameraLookDirInOS)); - float Bsq(B * B); - float C(cameraPosInOSx2.Dot(cameraPosInOSx2) - 4.0f); - - // solve quadratic equation - float discr(Bsq - C); - if (discr >= 0.0) - { - float discrSqrt = sqrtf(discr); - - // ray hit - Vec3 cameraPosInWS(camPos); - Vec3 cameraLookDirInWS((worldPos - camPos) * invOfScaledCamDirLength); - - ////////////////////////////////////////////////////////////////////////// - - float tS(max(0.5f * (-B - discrSqrt), 0.0f)); // clamp to zero so front ray-ellipsoid intersection is NOT behind camera - float tE(max(0.5f * (-B + discrSqrt), 0.0f)); // clamp to zero so back ray-ellipsoid intersection is NOT behind camera - //float tI( ( worldPos - camPos ).Dot( camDir ) / cameraLookDirInWS.Dot( camDir ) ); - tI = max(tS, min(tI, tE)); // clamp to range [tS, tE] - - Vec3 front(tS * cameraLookDirInWS + cameraPosInWS); - Vec3 dist((tI - tS) * cameraLookDirInWS); - float distLength(dist.GetLength()); - float fogInt(distLength * expf_s(-(front - m_heightFallOffBasePoint).Dot(m_heightFallOffDirScaled))); - - ////////////////////////////////////////////////////////////////////////// - - float heightDiff(dist.Dot(m_heightFallOffDirScaled)); - if (fabsf(heightDiff) > 0.001f) - { - fogInt *= (1.0f - expf_s(-heightDiff)) / heightDiff; - } - - float softArg(clamp_tpl(discr * m_cachedSoftEdgesLerp.x + m_cachedSoftEdgesLerp.y, 0.0f, 1.0f)); - fogInt *= softArg * (2.0f - softArg); - - float fog(expf_s(-m_globalDensity * fogInt)); - - resultColor = ColorF(m_cachedFogColor.r, m_cachedFogColor.g, m_cachedFogColor.b, min(fog, 1.0f)); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CFogVolumeRenderNode::GetVolumetricFogColorBox(const Vec3& worldPos, const SRenderingPassInfo& passInfo, ColorF& resultColor) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPos(cam.GetPosition()); - Vec3 cameraLookDir(worldPos - camPos); - - resultColor = ColorF(1.0f, 1.0f, 1.0f, 1.0f); - - if (cameraLookDir.GetLengthSquared() > 1e-4f) - { - // setup ray tracing in OS - Vec3 cameraPosInOS(m_matWSInv.TransformPoint(camPos)); - Vec3 cameraLookDirInOS(m_matWSInv.TransformVector(cameraLookDir)); - - float tI(sqrtf(cameraLookDirInOS.Dot(cameraLookDirInOS))); - float invOfScaledCamDirLength(1.0f / tI); - cameraLookDirInOS *= invOfScaledCamDirLength; - - const float fMax = std::numeric_limits::max(); - float tS(0), tE(fMax); - - //TODO: - // May be worth profiling use of a loop here, iterating over elements of vector; - // might save on i-cache, but suspect we'll lose instruction interleaving and hit - // more register dependency issues. - - //These fsels mean that the result is ignored if cameraLookDirInOS.x is 0.0f, - // avoiding a floating point compare. Avoiding the fcmp is ~15% faster - const float fXSelect = -fabsf(cameraLookDirInOS.x); - const float fXDivisor = (float)fsel(fXSelect, 1.0f, cameraLookDirInOS.x); - const float fXMultiplier = (float)fsel(fXSelect, 0.0f, 1.0f); - const float fXInvMultiplier = 1.0f - fXMultiplier; - - //Accurate to 255/256ths on console - float invCameraDirInOSx = fres(fXDivisor); //(1.0f / fXDivisor); - - float tPosPlane((1 - cameraPosInOS.x) * invCameraDirInOSx); - float tNegPlane((-1 - cameraPosInOS.x) * invCameraDirInOSx); - - float tFrontFace = (float)fsel(-cameraLookDirInOS.x, tPosPlane, tNegPlane); - float tBackFace = (float)fsel(-cameraLookDirInOS.x, tNegPlane, tPosPlane); - - tS = max(tS, tFrontFace * fXMultiplier); - tE = min(tE, (tBackFace * fXMultiplier) + (fXInvMultiplier * fMax)); - - - - const float fYSelect = -fabsf(cameraLookDirInOS.y); - const float fYDivisor = (float)fsel(fYSelect, 1.0f, cameraLookDirInOS.y); - const float fYMultiplier = (float)fsel(fYSelect, 0.0f, 1.0f); - const float fYInvMultiplier = 1.0f - fYMultiplier; - - //Accurate to 255/256ths on console - float invCameraDirInOSy = fres(fYDivisor); //(1.0f / fYDivisor); - - tPosPlane = ((1 - cameraPosInOS.y) * invCameraDirInOSy); - tNegPlane = ((-1 - cameraPosInOS.y) * invCameraDirInOSy); - - tFrontFace = (float)fsel(-cameraLookDirInOS.y, tPosPlane, tNegPlane); - tBackFace = (float)fsel(-cameraLookDirInOS.y, tNegPlane, tPosPlane); - - tS = max(tS, tFrontFace * fYMultiplier); - tE = min(tE, (tBackFace * fYMultiplier) + (fYInvMultiplier * fMax)); - - - - const float fZSelect = -fabsf(cameraLookDirInOS.z); - const float fZDivisor = (float)fsel(fZSelect, 1.0f, cameraLookDirInOS.z); - const float fZMultiplier = (float)fsel(fZSelect, 0.0f, 1.0f); - const float fZInvMultiplier = 1.0f - fZMultiplier; - - //Accurate to 255/256ths on console - float invCameraDirInOSz = fres(fZDivisor); //(1.0f / fZDivisor); - - tPosPlane = ((1 - cameraPosInOS.z) * invCameraDirInOSz); - tNegPlane = ((-1 - cameraPosInOS.z) * invCameraDirInOSz); - - tFrontFace = (float)fsel(-cameraLookDirInOS.z, tPosPlane, tNegPlane); - tBackFace = (float)fsel(-cameraLookDirInOS.z, tNegPlane, tPosPlane); - - tS = max(tS, tFrontFace * fZMultiplier); - tE = min(tE, (tBackFace * fZMultiplier) + (fZInvMultiplier * fMax)); - - tE = max(tE, 0.0f); - - if (tS <= tE) - { - Vec3 cameraPosInWS(camPos); - Vec3 cameraLookDirInWS((worldPos - camPos) * invOfScaledCamDirLength); - - ////////////////////////////////////////////////////////////////////////// - - tI = max(tS, min(tI, tE)); // clamp to range [tS, tE] - - Vec3 front(tS * cameraLookDirInWS + cameraPosInWS); - Vec3 dist((tI - tS) * cameraLookDirInWS); - float distLength(dist.GetLength()); - float fogInt(distLength * expf_s(-(front - m_heightFallOffBasePoint).Dot(m_heightFallOffDirScaled))); - - ////////////////////////////////////////////////////////////////////////// - - float heightDiff(dist.Dot(m_heightFallOffDirScaled)); - - //heightDiff = fabsf( heightDiff ) > 0.001f ? heightDiff : 0.001f - heightDiff = (float)fsel((-fabsf(heightDiff) + 0.001f), 0.001f, heightDiff); - - fogInt *= (1.0f - expf_s(-heightDiff)) * fres(heightDiff); - - float fog(expf_s(-m_globalDensity * fogInt)); - - resultColor = ColorF(m_cachedFogColor.r, m_cachedFogColor.g, m_cachedFogColor.b, min(fog, 1.0f)); - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/GeomCache.cpp b/Code/CryEngine/Cry3DEngine/GeomCache.cpp deleted file mode 100644 index a2726c8a86..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCache.cpp +++ /dev/null @@ -1,1098 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages geometry cache data - -#include "Cry3DEngine_precompiled.h" - -#if defined(USE_GEOM_CACHES) - -#include -#include "GeomCache.h" -#include "GeomCacheManager.h" -#include "GeomCacheDecoder.h" -#include "StringUtils.h" -#include "MatMan.h" - -#include - -CGeomCache::CGeomCache(const char* pFileName) - : m_bValid(false) - , m_bLoaded(false) - , m_refCount(0) - , m_fileName(pFileName) - , m_lastDrawMainFrameId(0) - , m_bPlaybackFromMemory(false) - , m_numFrames(0) - , m_compressedAnimationDataSize(0) - , m_totalUncompressedAnimationSize(0) - , m_numStreams(0) - , m_staticMeshDataOffset(0) - , m_aabb(0.0f) -{ - m_bUseStreaming = GetCVars()->e_StreamCgf > 0; - m_staticDataHeader.m_compressedSize = 0; - m_staticDataHeader.m_uncompressedSize = 0; - - string materialPath = PathUtil::ReplaceExtension(m_fileName, "mtl"); - m_pMaterial = GetMatMan()->LoadMaterial(materialPath); - - if (!LoadGeomCache()) - { - FileWarning(0, m_fileName.c_str(), "Failed to load geometry cache: %s", m_lastError.c_str()); - stl::free_container(m_lastError); - } -} - -CGeomCache::~CGeomCache() -{ - Shutdown(); -} - -int CGeomCache::AddRef() -{ - ++m_refCount; - return m_refCount; -} - -int CGeomCache::Release() -{ - assert(m_refCount >= 0); - - --m_refCount; - int refCount = m_refCount; - if (m_refCount <= 0) - { - GetGeomCacheManager()->DeleteGeomCache(this); - } - - return refCount; -} - -void CGeomCache::SetMaterial(_smart_ptr pMaterial) -{ - m_pMaterial = pMaterial; -} - -_smart_ptr CGeomCache::GetMaterial() -{ - return m_pMaterial; -} - -const _smart_ptr CGeomCache::GetMaterial() const -{ - return m_pMaterial; -} - -const char* CGeomCache::GetFilePath() const -{ - return m_fileName; -} - -bool CGeomCache::LoadGeomCache() -{ - using namespace GeomCacheFile; - - LOADING_TIME_PROFILE_SECTION; - - CRY_DEFINE_ASSET_SCOPE("GeomCache", m_fileName); - - AZ::IO::ScopedFileHandle geomCacheFileHandle(*gEnv->pCryPak, m_fileName.c_str(), "rb"); - if (!geomCacheFileHandle.IsValid()) - { - return false; - } - - size_t bytesRead = 0; - - // Read header and check signature - SHeader header; - bytesRead = gEnv->pCryPak->FReadRaw((void*)&header, 1, sizeof(SHeader), geomCacheFileHandle); - if (bytesRead != sizeof(SHeader)) - { - m_lastError = "Could not read header"; - return false; - } - - if (header.m_signature != kFileSignature) - { - m_lastError = "Bad file signature"; - return false; - } - - if (header.m_version != kCurrentVersion) - { - m_lastError = "Bad file version"; - return false; - } - - const bool bFileHas32BitIndexFormat = (header.m_flags & eFileHeaderFlags_32BitIndices) != 0; - if (((sizeof(vtx_idx) == sizeof(uint16)) && bFileHas32BitIndexFormat) || ((sizeof(vtx_idx) == sizeof(uint32)) && !bFileHas32BitIndexFormat)) - { - m_lastError = "Index format mismatch"; - return false; - } - - if (header.m_blockCompressionFormat != eBlockCompressionFormat_None && - header.m_blockCompressionFormat != eBlockCompressionFormat_Deflate && - header.m_blockCompressionFormat != eBlockCompressionFormat_LZ4HC && - header.m_blockCompressionFormat != eBlockCompressionFormat_ZSTD) - { - m_lastError = "Bad block compression format"; - return false; - } - - m_bPlaybackFromMemory = (header.m_flags & GeomCacheFile::eFileHeaderFlags_PlaybackFromMemory) != 0; - m_blockCompressionFormat = static_cast(header.m_blockCompressionFormat); - m_totalUncompressedAnimationSize = header.m_totalUncompressedAnimationSize; - m_numFrames = header.m_numFrames; - m_aabb.min = Vec3(header.m_aabbMin[0], header.m_aabbMin[1], header.m_aabbMin[2]); - m_aabb.max = Vec3(header.m_aabbMax[0], header.m_aabbMax[1], header.m_aabbMax[2]); - - // Read frame times and frame offsets. - if (!ReadFrameInfos(geomCacheFileHandle, header.m_numFrames)) - { - return false; - } - - const int maxPlaybackFromMemorySize = std::max(0, GetCVars()->e_GeomCacheMaxPlaybackFromMemorySize); - if (m_bPlaybackFromMemory && m_compressedAnimationDataSize > uint(maxPlaybackFromMemorySize * 1024 * 1024)) - { - GetLog()->LogWarning("Animated data size of geometry cache '%s' is over memory playback limit " - "of %d MiB. Reverting to stream playback.", m_fileName.c_str(), maxPlaybackFromMemorySize); - m_bPlaybackFromMemory = false; - } - - // Load static node data and physics geometries - { - std::vector compressedData; - std::vector decompressedData; - - if (!ReadStaticBlock(geomCacheFileHandle, (EBlockCompressionFormat)(header.m_blockCompressionFormat), compressedData) - || !DecompressStaticBlock((EBlockCompressionFormat)(header.m_blockCompressionFormat), &compressedData[0], decompressedData)) - { - if (m_lastError.empty()) - { - m_lastError = "Could not read or decompress static block"; - } - - return false; - } - - CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size()); - if (!ReadNodesStaticDataRec(reader)) - { - if (m_lastError.empty()) - { - m_lastError = "Could not read node static data"; - } - - return false; - } - } - - m_staticMeshDataOffset = gEnv->pCryPak->FTell(geomCacheFileHandle); - - if (!m_bUseStreaming) - { - std::vector compressedData; - std::vector decompressedData; - - if (!ReadStaticBlock(geomCacheFileHandle, (EBlockCompressionFormat)(header.m_blockCompressionFormat), compressedData) - || !DecompressStaticBlock((EBlockCompressionFormat)(header.m_blockCompressionFormat), &compressedData[0], decompressedData)) - { - if (m_lastError.empty()) - { - m_lastError = "Could not read or decompress static block"; - } - - return false; - } - - CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size()); - if (!ReadMeshesStaticData(reader, m_fileName.c_str())) - { - if (m_lastError.empty()) - { - m_lastError = "Could not read mesh static data"; - } - - return false; - } - - if (m_bPlaybackFromMemory && m_frameInfos.size() > 0) - { - std::vector animationData; - animationData.resize(static_cast(m_compressedAnimationDataSize)); - bytesRead = gEnv->pCryPak->FReadRaw((void*)&animationData[0], 1, static_cast(m_compressedAnimationDataSize), geomCacheFileHandle); - - if (!LoadAnimatedData(&animationData[0], 0)) - { - return false; - } - } - - m_bLoaded = true; - } - else - { - bytesRead = gEnv->pCryPak->FReadRaw((void*)&m_staticDataHeader, 1, sizeof(GeomCacheFile::SCompressedBlockHeader), geomCacheFileHandle); - if (bytesRead != sizeof(GeomCacheFile::SCompressedBlockHeader)) - { - m_lastError = "Bad data"; - return false; - } - } - - m_bValid = true; - return true; -} - -bool CGeomCache::ReadStaticBlock(AZ::IO::HandleType fileHandle, [[maybe_unused]] GeomCacheFile::EBlockCompressionFormat compressionFormat, std::vector& compressedData) -{ - compressedData.resize(sizeof(GeomCacheFile::SCompressedBlockHeader)); - - size_t bytesRead = 0; - bytesRead = gEnv->pCryPak->FReadRaw((void*)&compressedData[0], 1, sizeof(GeomCacheFile::SCompressedBlockHeader), fileHandle); - if (bytesRead != sizeof(GeomCacheFile::SCompressedBlockHeader)) - { - return false; - } - - m_staticDataHeader = *reinterpret_cast(&compressedData[0]); - compressedData.resize(sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize); - - bytesRead = gEnv->pCryPak->FReadRaw(&compressedData[sizeof(GeomCacheFile::SCompressedBlockHeader)], 1, m_staticDataHeader.m_compressedSize, fileHandle); - if (bytesRead != m_staticDataHeader.m_compressedSize) - { - return false; - } - - return true; -} - -bool CGeomCache::DecompressStaticBlock(GeomCacheFile::EBlockCompressionFormat compressionFormat, const char* pCompressedData, std::vector& decompressedData) -{ - const GeomCacheFile::SCompressedBlockHeader staticBlockHeader = *reinterpret_cast(pCompressedData); - decompressedData.resize(staticBlockHeader.m_uncompressedSize); - - if (!GeomCacheDecoder::DecompressBlock(compressionFormat, &decompressedData[0], pCompressedData)) - { - m_lastError = "Could not decompress static data"; - return false; - } - - return true; -} - -bool CGeomCache::ReadFrameInfos(AZ::IO::HandleType fileHandle, const uint32 numFrames) -{ - LOADING_TIME_PROFILE_SECTION; - - size_t bytesRead; - - std::vector fileFrameInfos; - - fileFrameInfos.resize(numFrames); - bytesRead = gEnv->pCryPak->FReadRaw((void*)&fileFrameInfos[0], 1, numFrames * sizeof(GeomCacheFile::SFrameInfo), fileHandle); - if (bytesRead != (numFrames * sizeof(GeomCacheFile::SFrameInfo))) - { - return false; - } - - m_frameInfos.resize(numFrames); - for (uint i = 0; i < numFrames; ++i) - { - m_frameInfos[i].m_frameTime = fileFrameInfos[i].m_frameTime; - m_frameInfos[i].m_frameType = fileFrameInfos[i].m_frameType; - m_frameInfos[i].m_frameSize = fileFrameInfos[i].m_frameSize; - m_frameInfos[i].m_frameOffset = fileFrameInfos[i].m_frameOffset; - m_compressedAnimationDataSize += m_frameInfos[i].m_frameSize; - } - - if (m_frameInfos.front().m_frameType != GeomCacheFile::eFrameType_IFrame - || m_frameInfos.back().m_frameType != GeomCacheFile::eFrameType_IFrame) - { - return false; - } - - // Assign prev/next index frames and count total data size - uint prevIFrame = 0; - for (uint i = 0; i < numFrames; ++i) - { - m_frameInfos[i].m_prevIFrame = prevIFrame; - - if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame) - { - prevIFrame = i; - } - } - - uint nextIFrame = numFrames - 1; - for (int i = numFrames - 1; i >= 0; --i) - { - m_frameInfos[i].m_nextIFrame = nextIFrame; - - if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame) - { - nextIFrame = i; - } - } - - return true; -} - -bool CGeomCache::ReadMeshesStaticData(CGeomCacheStreamReader& reader, const char* pFileName) -{ - LOADING_TIME_PROFILE_SECTION; - - uint32 numMeshes; - if (!reader.Read(&numMeshes)) - { - return false; - } - - std::vector meshInfos; - meshInfos.reserve(numMeshes); - - for (uint32 i = 0; i < numMeshes; ++i) - { - GeomCacheFile::SMeshInfo meshInfo; - m_staticMeshData.push_back(SGeomCacheStaticMeshData()); - SGeomCacheStaticMeshData& staticMeshData = m_staticMeshData.back(); - - if (!reader.Read(&meshInfo)) - { - return false; - } - - staticMeshData.m_bUsePredictor = (meshInfo.m_flags & GeomCacheFile::eMeshIFrameFlags_UsePredictor) != 0; - staticMeshData.m_positionPrecision[0] = meshInfo.m_positionPrecision[0]; - staticMeshData.m_positionPrecision[1] = meshInfo.m_positionPrecision[1]; - staticMeshData.m_positionPrecision[2] = meshInfo.m_positionPrecision[2]; - staticMeshData.m_uvMax = meshInfo.m_uvMax; - staticMeshData.m_constantStreams = static_cast(meshInfo.m_constantStreams); - staticMeshData.m_animatedStreams = static_cast(meshInfo.m_animatedStreams); - staticMeshData.m_numVertices = meshInfo.m_numVertices; - staticMeshData.m_aabb.min = Vec3(meshInfo.m_aabbMin[0], meshInfo.m_aabbMin[1], meshInfo.m_aabbMin[2]); - staticMeshData.m_aabb.max = Vec3(meshInfo.m_aabbMax[0], meshInfo.m_aabbMax[1], meshInfo.m_aabbMax[2]); - staticMeshData.m_hash = meshInfo.m_hash; - - std::vector tempName(meshInfo.m_nameLength); - if (!reader.Read(&tempName[0], meshInfo.m_nameLength)) - { - return false; - } - - if (gEnv->IsEditor()) - { - staticMeshData.m_name = &tempName[0]; - } - - // Read material IDs - staticMeshData.m_materialIds.resize(meshInfo.m_numMaterials); - - if (!reader.Read(&staticMeshData.m_materialIds[0], meshInfo.m_numMaterials)) - { - return false; - } - - meshInfos.push_back(meshInfo); - } - - m_staticMeshData.reserve(numMeshes); - for (uint32 i = 0; i < numMeshes; ++i) - { - if (!ReadMeshStaticData(reader, meshInfos[i], m_staticMeshData[i], pFileName)) - { - return false; - } - } - - return true; -} - -bool CGeomCache::ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, - SGeomCacheStaticMeshData& staticMeshData, const char* pFileName) -{ - CGeomCacheMeshManager& meshManager = GetGeomCacheManager()->GetMeshManager(); - - if (meshInfo.m_animatedStreams == 0) - { - // If we don't need the static data to fill dynamic meshes, just construct a static mesh - _smart_ptr pRenderMesh = meshManager.ConstructStaticRenderMesh(reader, meshInfo, staticMeshData, pFileName); - - if (!pRenderMesh) - { - return false; - } - - m_staticRenderMeshes.push_back(pRenderMesh); - } - else - { - // Otherwise we need the static data for filling the dynamic mesh later and read it to the vertex array in staticMeshData - if (!meshManager.ReadMeshStaticData(reader, meshInfo, staticMeshData)) - { - return false; - } - } - - return true; -} - -bool CGeomCache::ReadNodesStaticDataRec(CGeomCacheStreamReader& reader) -{ - LOADING_TIME_PROFILE_SECTION; - - GeomCacheFile::SNodeInfo nodeInfo; - if (!reader.Read(&nodeInfo)) - { - return false; - } - - SGeomCacheStaticNodeData staticNodeData; - staticNodeData.m_meshOrGeometryIndex = nodeInfo.m_meshIndex; - staticNodeData.m_numChildren = nodeInfo.m_numChildren; - staticNodeData.m_type = static_cast(nodeInfo.m_type); - staticNodeData.m_transformType = static_cast(nodeInfo.m_transformType); - - std::vector tempName(nodeInfo.m_nameLength); - if (!reader.Read(&tempName[0], nodeInfo.m_nameLength)) - { - return false; - } - - if (gEnv->IsEditor()) - { - staticNodeData.m_name = &tempName[0]; - } - - staticNodeData.m_nameHash = CryStringUtils::HashString(&tempName[0]); - - if (!reader.Read(&staticNodeData.m_localTransform)) - { - return false; - } - - if (staticNodeData.m_type == GeomCacheFile::eNodeType_PhysicsGeometry) - { - uint32 geometrySize; - if (!reader.Read(&geometrySize)) - { - return false; - } - - std::vector geometryData(geometrySize); - if (!reader.Read(&geometryData[0], geometrySize)) - { - return false; - } - - CMemStream memStream(&geometryData[0], geometrySize, false); - // Geometry - CRY_PHYSICS_REPLACEMENT_ASSERT(); - - staticNodeData.m_meshOrGeometryIndex = (uint32)(m_physicsGeometries.size() - 1); - } - - m_staticNodeData.push_back(staticNodeData); - - for (uint32 i = 0; i < nodeInfo.m_numChildren; ++i) - { - if (!ReadNodesStaticDataRec(reader)) - { - return false; - } - } - - return true; -} - -float CGeomCache::GetDuration() const -{ - if (m_frameInfos.empty()) - { - return 0.0f; - } - else - { - return m_frameInfos.back().m_frameTime - m_frameInfos.front().m_frameTime; - } -} - -IGeomCache::SStatistics CGeomCache::GetStatistics() const -{ - IGeomCache::SStatistics stats; - memset(&stats, 0, sizeof(stats)); - - std::set materialIds; - - - const uint numMeshes = m_staticMeshData.size(); - for (uint i = 0; i < numMeshes; ++i) - { - const SGeomCacheStaticMeshData& meshData = m_staticMeshData[i]; - materialIds.insert(meshData.m_materialIds.begin(), meshData.m_materialIds.end()); - - stats.m_staticDataSize += static_cast(sizeof(SGeomCacheStaticMeshData)); - stats.m_staticDataSize += static_cast(sizeof(vtx_idx) * meshData.m_indices.size()); - stats.m_staticDataSize += static_cast(sizeof(uint32) * meshData.m_numIndices.size()); - stats.m_staticDataSize += static_cast(sizeof(Vec3) * meshData.m_positions.size()); - stats.m_staticDataSize += static_cast(sizeof(UCol) * meshData.m_colors.size()); - stats.m_staticDataSize += static_cast(sizeof(Vec2) * meshData.m_texcoords.size()); - stats.m_staticDataSize += static_cast(sizeof(SPipTangents) * meshData.m_tangents.size()); - stats.m_staticDataSize += static_cast(sizeof(uint16) * meshData.m_materialIds.size()); - stats.m_staticDataSize += static_cast(sizeof(uint16) * meshData.m_predictorData.size()); - - uint numIndices = 0; - const uint numMaterials = meshData.m_numIndices.size(); - for (uint j = 0; j < numMaterials; ++j) - { - numIndices += meshData.m_numIndices[j]; - } - - if (meshData.m_animatedStreams == 0) - { - ++stats.m_numStaticMeshes; - stats.m_numStaticVertices += meshData.m_numVertices; - stats.m_numStaticTriangles += numIndices / 3; - } - else - { - ++stats.m_numAnimatedMeshes; - stats.m_numAnimatedVertices += meshData.m_numVertices; - stats.m_numAnimatedTriangles += numIndices / 3; - } - } - - stats.m_staticDataSize += static_cast(m_staticNodeData.size() * sizeof(SGeomCacheStaticNodeData)); - stats.m_staticDataSize += static_cast(m_frameInfos.size() * sizeof(SFrameInfo)); - - stats.m_bPlaybackFromMemory = m_bPlaybackFromMemory; - stats.m_averageAnimationDataRate = (float(m_compressedAnimationDataSize) / 1024.0f / 1024.0f) / float(GetDuration()); - stats.m_numMaterials = static_cast(materialIds.size()); - stats.m_diskAnimationDataSize = static_cast(m_compressedAnimationDataSize); - stats.m_memoryAnimationDataSize = static_cast(m_animationData.size()); - - return stats; -} - -void CGeomCache::Shutdown() -{ - if (m_pStaticDataReadStream) - { - m_pStaticDataReadStream->Abort(); - m_pStaticDataReadStream = NULL; - } - - GetObjManager()->UnregisterForStreaming(this); - GetGeomCacheManager()->StopCacheStreamsAndWait(this); - - const uint numListeners = m_listeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_listeners[i]->OnGeomCacheStaticDataUnloaded(); - } - - m_eStreamingStatus = ecss_NotLoaded; - - stl::free_container(m_frameInfos); - stl::free_container(m_staticMeshData); - stl::free_container(m_staticNodeData); - stl::free_container(m_physicsGeometries); - stl::free_container(m_animationData); -} - -void CGeomCache::Reload() -{ - Shutdown(); - - const bool bUseStreaming = m_bUseStreaming; - m_bUseStreaming = false; - m_bValid = false; - m_bLoaded = false; - LoadGeomCache(); - m_bUseStreaming = bUseStreaming; - - if (m_bLoaded) - { - const uint numListeners = m_listeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_listeners[i]->OnGeomCacheStaticDataLoaded(); - } - } - else - { - FileWarning(0, m_fileName.c_str(), "Failed to load geometry cache: %s", m_lastError.c_str()); - stl::free_container(m_lastError); - } -} - -uint CGeomCache::GetNumFrames() const -{ - return m_frameInfos.size(); -} - -bool CGeomCache::PlaybackFromMemory() const -{ - return m_bPlaybackFromMemory; -} - -uint64 CGeomCache::GetCompressedAnimationDataSize() const -{ - return m_compressedAnimationDataSize; -} - -char* CGeomCache::GetFrameData(const uint frameIndex) -{ - assert(m_bPlaybackFromMemory); - - char* pAnimationData = &m_animationData[0]; - - SGeomCacheFrameHeader* pFrameHeader = reinterpret_cast( - pAnimationData + (frameIndex * sizeof(SGeomCacheFrameHeader))); - - return pAnimationData + pFrameHeader->m_offset; -} - -const char* CGeomCache::GetFrameData(const uint frameIndex) const -{ - assert(m_bPlaybackFromMemory); - - const char* pAnimationData = &m_animationData[0]; - - const SGeomCacheFrameHeader* pFrameHeader = reinterpret_cast( - pAnimationData + (frameIndex * sizeof(SGeomCacheFrameHeader))); - - return pAnimationData + pFrameHeader->m_offset; -} - -const AABB& CGeomCache::GetAABB() const -{ - return m_aabb; -} - -uint CGeomCache::GetFloorFrameIndex(const float time) const -{ - if (m_frameInfos.empty()) - { - return 0; - } - - const float duration = GetDuration(); - float timeInCycle = fmod(time, duration); - uint numLoops = static_cast(floor(time / duration)); - - // Make sure that exactly at wrap around we still refer to last frame - if (timeInCycle == 0.0f && time > 0.0f) - { - timeInCycle = duration; - numLoops -= 1; - } - - const uint numFrames = m_frameInfos.size(); - const uint numPreviousCycleFrames = numLoops * numFrames; - uint frameInCycle; - - // upper_bound = first value greater than time - SFrameInfo value = { timeInCycle }; - std::vector::const_iterator findIter = - std::upper_bound(m_frameInfos.begin(), m_frameInfos.end(), value, CompareFrameTimes); - if (findIter == m_frameInfos.begin()) - { - frameInCycle = 0; - } - else if (findIter == m_frameInfos.end()) - { - frameInCycle = static_cast(m_frameInfos.size() - 1); - } - else - { - frameInCycle = static_cast(findIter - m_frameInfos.begin() - 1); - } - - return frameInCycle + numPreviousCycleFrames; -} - -uint CGeomCache::GetCeilFrameIndex(const float time) const -{ - if (m_frameInfos.empty()) - { - return 0; - } - - const float duration = GetDuration(); - float timeInCycle = fmod(time, duration); - uint numLoops = static_cast(floor(time / duration)); - - // Make sure that exactly at wrap around we still refer to last frame - if (timeInCycle == 0.0f && time > 0.0f) - { - timeInCycle = duration; - numLoops -= 1; - } - - const uint numFrames = m_frameInfos.size(); - const uint numPreviousCycleFrames = numLoops * numFrames; - uint frameInCycle; - - // lower_bound = first value greater than or equal to time - SFrameInfo value = { timeInCycle }; - std::vector::const_iterator findIter = - std::lower_bound(m_frameInfos.begin(), m_frameInfos.end(), value, CompareFrameTimes); - if (findIter == m_frameInfos.end()) - { - frameInCycle = static_cast(m_frameInfos.size() - 1); - } - else - { - frameInCycle = static_cast(findIter - m_frameInfos.begin()); - } - - return frameInCycle + numPreviousCycleFrames; -} - -GeomCacheFile::EFrameType CGeomCache::GetFrameType(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - return (GeomCacheFile::EFrameType)m_frameInfos[frameIndex % numFrames].m_frameType; -} - -uint64 CGeomCache::GetFrameOffset(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - return m_frameInfos[frameIndex % numFrames].m_frameOffset; -} - -uint32 CGeomCache::GetFrameSize(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - return m_frameInfos[frameIndex % numFrames].m_frameSize; -} - -float CGeomCache::GetFrameTime(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - const uint numLoops = frameIndex / numFrames; - const float duration = GetDuration(); - return (duration * numLoops) + m_frameInfos[frameIndex % numFrames].m_frameTime; -} - -uint CGeomCache::GetPrevIFrame(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - const uint numLoops = frameIndex / numFrames; - return (numFrames * numLoops) + m_frameInfos[frameIndex % numFrames].m_prevIFrame; -} - -uint CGeomCache::GetNextIFrame(const uint frameIndex) const -{ - const uint numFrames = m_frameInfos.size(); - const uint numLoops = frameIndex / numFrames; - return (numFrames * numLoops) + m_frameInfos[frameIndex % numFrames].m_nextIFrame; -} - -bool CGeomCache::NeedsPrevFrames(const uint frameIndex) const -{ - if (GetFrameType(frameIndex) == GeomCacheFile::eFrameType_IFrame - || GetFrameType(frameIndex - 1) == GeomCacheFile::eFrameType_IFrame) - { - return false; - } - - return true; -} - -void CGeomCache::ValidateReadRange(const uint start, uint& end) const -{ - const uint numFrames = m_frameInfos.size(); - uint startMod = start % numFrames; - uint endMod = end % numFrames; - - if (endMod < startMod) - { - end = start + (numFrames - 1 - startMod); - } -} - -GeomCacheFile::EBlockCompressionFormat CGeomCache::GetBlockCompressionFormat() const -{ - return m_blockCompressionFormat; -} - -void CGeomCache::UpdateStreamableComponents(float importance, [[maybe_unused]] const Matrix34A& objMatrix, [[maybe_unused]] IRenderNode* pRenderNode, bool bFullUpdate) -{ - if (!m_bUseStreaming) - { - return; - } - - const int nRoundId = GetObjManager()->GetUpdateStreamingPrioriryRoundId(); - - if (UpdateStreamingPrioriryLowLevel(importance, nRoundId, bFullUpdate)) - { - GetObjManager()->RegisterForStreaming(this); - } -} - -void CGeomCache::StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream) -{ - m_bValid = false; - - assert(m_eStreamingStatus == ecss_NotLoaded); - if (m_eStreamingStatus != ecss_NotLoaded) - { - return; - } - - if (m_bLoaded) - { - const uint numListeners = m_listeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_listeners[i]->OnGeomCacheStaticDataLoaded(); - } - - m_eStreamingStatus = ecss_Ready; - return; - } - - // start streaming - StreamReadParams params; - params.dwUserData = 0; - params.nOffset = static_cast(m_staticMeshDataOffset); - params.nSize = sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize; - params.pBuffer = NULL; - params.nLoadTime = 10000; - params.nMaxLoadTime = 10000; - - if (m_bPlaybackFromMemory) - { - params.nSize += static_cast(m_compressedAnimationDataSize); - } - - if (bFinishNow) - { - params.ePriority = estpUrgent; - } - - if (m_fileName.empty()) - { - m_eStreamingStatus = ecss_Ready; - if (ppStream) - { - *ppStream = NULL; - } - return; - } - - m_pStaticDataReadStream = GetSystem()->GetStreamEngine()->StartRead(eStreamTaskTypeGeometry, m_fileName, this, ¶ms); - - if (ppStream) - { - (*ppStream) = m_pStaticDataReadStream; - } - - if (!bFinishNow) - { - m_eStreamingStatus = ecss_InProgress; - } - else if (!ppStream) - { - m_pStaticDataReadStream->Wait(); - } -} - -void CGeomCache::StreamOnComplete([[maybe_unused]] IReadStream* pStream, unsigned nError) -{ - if (nError != 0 || !m_bValid) - { - return; - } - - const uint numListeners = m_listeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_listeners[i]->OnGeomCacheStaticDataLoaded(); - } - - m_eStreamingStatus = ecss_Ready; - - m_pStaticDataReadStream = NULL; -} - -void CGeomCache::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) -{ - if (nError != 0) - { - return; - } - - const char* pData = (char*)pStream->GetBuffer(); - - std::vector decompressedData; - if (!DecompressStaticBlock((GeomCacheFile::EBlockCompressionFormat)(m_blockCompressionFormat), pData, decompressedData)) - { - if (m_lastError.empty()) - { - m_lastError = "Could not decompress static block"; - return; - } - } - - CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size()); - if (!ReadMeshesStaticData(reader, m_fileName.c_str())) - { - if (m_lastError.empty()) - { - m_lastError = "Could not read mesh static data"; - return; - } - } - - if (m_bPlaybackFromMemory && m_frameInfos.size() > 0) - { - if (!LoadAnimatedData(pData, sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize)) - { - return; - } - } - - m_bValid = true; - m_bLoaded = true; - - pStream->FreeTemporaryMemory(); -} - -bool CGeomCache::LoadAnimatedData(const char* pData, const size_t bufferOffset) -{ - const uint numFrames = m_frameInfos.size(); - - // First get size necessary for decompressing animation data - uint32 totalDecompressedAnimatedDataSize = GeomCacheDecoder::GetDecompressBufferSize(pData + bufferOffset, numFrames); - - // Allocate memory and decompress blocks into it - m_animationData.resize(totalDecompressedAnimatedDataSize); - if (!GeomCacheDecoder::DecompressBlocks(m_blockCompressionFormat, &m_animationData[0], pData + bufferOffset, 0, numFrames, numFrames)) - { - m_lastError = "Could not decompress animation data"; - return false; - } - - // Decode index frames - for (uint i = 0; i < numFrames; ++i) - { - if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame) - { - GeomCacheDecoder::DecodeIFrame(this, GetFrameData(i)); - } - } - - // Decode b-frames - for (uint i = 0; i < numFrames; ++i) - { - if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_BFrame) - { - char* pFrameData = GetFrameData(i); - char* pPrevFrameData[2] = { pFrameData, pFrameData }; - - if (NeedsPrevFrames(i)) - { - pPrevFrameData[0] = GetFrameData(i - 2); - pPrevFrameData[1] = GetFrameData(i - 1); - } - - char* pFloorIndexFrameData = GetFrameData(GetPrevIFrame(i)); - char* pCeilIndexFrameData = GetFrameData(GetNextIFrame(i)); - - GeomCacheDecoder::DecodeBFrame(this, pFrameData, pPrevFrameData, pFloorIndexFrameData, pCeilIndexFrameData); - } - } - - return true; -} - -int CGeomCache::GetStreamableContentMemoryUsage([[maybe_unused]] bool bJustForDebug) -{ - return 0; -} - -void CGeomCache::ReleaseStreamableContent() -{ - const uint numListeners = m_listeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_listeners[i]->OnGeomCacheStaticDataUnloaded(); - } - - // Data cannot be unloaded right away, because stream could still be active, - // so we need to wait for a UnloadData callback from the geom cache managers - m_eStreamingStatus = ecss_NotLoaded; -} - -void CGeomCache::GetStreamableName(string& sName) -{ - sName = m_fileName; -} - -uint32 CGeomCache::GetLastDrawMainFrameId() -{ - return m_lastDrawMainFrameId; -} - -bool CGeomCache::IsUnloadable() const -{ - return m_bUseStreaming; -} - -void CGeomCache::AddListener(IGeomCacheListener* pListener) -{ - stl::push_back_unique(m_listeners, pListener); -} - -void CGeomCache::RemoveListener(IGeomCacheListener* pListener) -{ - stl::find_and_erase(m_listeners, pListener); -} - -void CGeomCache::UnloadData() -{ - //When not streaming, only allow data release if the geom cache has been processed by its render node - if (!m_bUseStreaming && !m_processedByRenderNode) - { - return; - } - - if (m_eStreamingStatus == ecss_NotLoaded) - { - CGeomCacheMeshManager& meshManager = GetGeomCacheManager()->GetMeshManager(); - - uint numStaticMesh = m_staticMeshData.size(); - for (uint i = 0; i < numStaticMesh; ++i) - { - if (m_staticMeshData[i].m_animatedStreams == 0) - { - meshManager.RemoveReference(m_staticMeshData[i]); - } - } - - stl::free_container(m_staticRenderMeshes); - stl::free_container(m_staticMeshData); - stl::free_container(m_animationData); - m_bLoaded = false; - } -} - -#endif diff --git a/Code/CryEngine/Cry3DEngine/GeomCache.h b/Code/CryEngine/Cry3DEngine/GeomCache.h deleted file mode 100644 index f40dec46cf..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCache.h +++ /dev/null @@ -1,309 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages geometry cache data - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHE_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHE_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include -#include "GeomCacheFileFormat.h" - -struct SGeomCacheStaticMeshData -{ - bool m_bUsePredictor; - uint8 m_positionPrecision[3]; - float m_uvMax; - uint32 m_numVertices; - GeomCacheFile::EStreams m_constantStreams; - GeomCacheFile::EStreams m_animatedStreams; - uint64 m_hash; - AABB m_aabb; - string m_name; - - std::vector m_indices; - std::vector m_numIndices; - stl::aligned_vector m_positions; - stl::aligned_vector m_colors; - stl::aligned_vector m_texcoords; - stl::aligned_vector m_tangents; - std::vector m_materialIds; - std::vector m_predictorData; -}; - -struct SGeomCacheStaticNodeData -{ - uint32 m_meshOrGeometryIndex; - uint32 m_numChildren; - GeomCacheFile::ENodeType m_type; - GeomCacheFile::ETransformType m_transformType; - QuatTNS m_localTransform; - uint32 m_nameHash; - string m_name; -}; - -class CGeomCacheStreamReader -{ -public: - CGeomCacheStreamReader(const char* pData, const size_t length) - : m_pData(pData) - , m_length(length) - , m_position(0) {} - - template - bool Read(T* pDest, size_t numElements) - { - const size_t numBytes = sizeof(T) * numElements; - - if (m_position + numBytes > m_length) - { - return false; - } - - memcpy(pDest, &m_pData[m_position], numBytes); - m_position += numBytes; - - return true; - } - - template - bool Read(T* pDest) - { - const size_t numBytes = sizeof(T); - - if (m_position + numBytes > m_length) - { - return false; - } - - memcpy(pDest, &m_pData[m_position], numBytes); - m_position += numBytes; - - return true; - } - -private: - const char* m_pData; - const size_t m_length; - size_t m_position; -}; - -struct IGeomCacheListener -{ -public: - virtual ~IGeomCacheListener() {} - - virtual void OnGeomCacheStaticDataLoaded() = 0; - virtual void OnGeomCacheStaticDataUnloaded() = 0; -}; - -class CGeomCache - : public IGeomCache - , public IStreamCallback - , public Cry3DEngineBase -{ - friend class CGeomCacheManager; - -public: - CGeomCache(const char* pFileName); - ~CGeomCache(); - - // Gets number of frames - uint GetNumFrames() const; - - // Returns true if cache plays back from memory - bool PlaybackFromMemory() const; - - const char* GetFrameData(const uint frameIndex) const; - uint64 GetCompressedAnimationDataSize() const; - - // Gets the max extend of the geom cache through the entire animation - const AABB& GetAABB() const override; - - void SetProcessedByRenderNode(bool processedByRenderNode) override { m_processedByRenderNode = processedByRenderNode; } - - // Returns frame for specific time. Rounds to ceil or floor - uint GetFloorFrameIndex(const float time) const; - uint GetCeilFrameIndex(const float time) const; - - // Frame infos - GeomCacheFile::EFrameType GetFrameType(const uint frameIndex) const; - uint64 GetFrameOffset(const uint frameIndex) const; - uint32 GetFrameSize(const uint frameIndex) const; - float GetFrameTime(const uint frameIndex) const; - uint GetPrevIFrame(const uint frameIndex) const; - uint GetNextIFrame(const uint frameIndex) const; - - // Returns true if this frame uses motion prediction and needs the last two frames - bool NeedsPrevFrames(const uint frameIndex) const; - - // Validates a frame range for reading from disk - void ValidateReadRange(const uint start, uint& end) const; - - // Get block compression format - GeomCacheFile::EBlockCompressionFormat GetBlockCompressionFormat() const; - - // Access to the mesh and node lists - const std::vector& GetStaticMeshData() const { return m_staticMeshData; } - const std::vector& GetStaticNodeData() const { return m_staticNodeData; } - const std::vector& GetPhysicsGeometries() const { return m_physicsGeometries; } - - // Listener interface for async loading - void AddListener(IGeomCacheListener* pListener); - void RemoveListener(IGeomCacheListener* pListener); - - bool IsLoaded() const { return m_bLoaded; } - void UnloadData(); - - // Ref count for streams - uint GetNumStreams() const { return m_numStreams; } - void IncreaseNumStreams() { ++m_numStreams; } - void DecreaseNumStreams() { --m_numStreams; } - - // IGeomCache - virtual int AddRef(); - virtual int Release(); - - virtual bool IsValid() const { return m_bValid; } - - virtual void SetMaterial(_smart_ptr pMaterial); - virtual _smart_ptr GetMaterial(); - virtual const _smart_ptr GetMaterial() const; - - virtual const char* GetFilePath() const; - - virtual float GetDuration() const; - - virtual IGeomCache::SStatistics GetStatistics() const; - - virtual void Reload(); - - // Static data streaming - void UpdateStreamableComponents(float importance, const Matrix34A& objMatrix, IRenderNode* pRenderNode, bool bFullUpdate); - void SetLastDrawMainFrameId(const uint32 id) { m_lastDrawMainFrameId = id; } - - // IStreamable - virtual void StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream); - virtual int GetStreamableContentMemoryUsage(bool bJustForDebug); - virtual void ReleaseStreamableContent(); - virtual void GetStreamableName(string& sName); - virtual uint32 GetLastDrawMainFrameId(); - virtual bool IsUnloadable() const; - - // IStreamCallback - virtual void StreamOnComplete(IReadStream* pStream, unsigned nError); - virtual void StreamAsyncOnComplete(IReadStream* pStream, unsigned nError); - -private: - struct SFrameInfo - { - float m_frameTime; - uint32 m_frameType; - uint32 m_frameSize; - uint32 m_prevIFrame; - uint32 m_nextIFrame; - uint64 m_frameOffset; - }; - - void Shutdown(); - - bool LoadGeomCache(); - - bool ReadFrameInfos(AZ::IO::HandleType fileHandle, const uint32 numFrames); - - bool ReadStaticBlock(AZ::IO::HandleType fileHandle, GeomCacheFile::EBlockCompressionFormat compressionFormat, std::vector& compressedData); - bool DecompressStaticBlock(GeomCacheFile::EBlockCompressionFormat compressionFormat, const char* pCompressedData, std::vector& decompressedData); - - bool ReadMeshesStaticData(CGeomCacheStreamReader& reader, const char* pFileName); - bool ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, - SGeomCacheStaticMeshData& mesh, const char* pFileName); - - bool LoadAnimatedData(const char* pData, const size_t bufferOffset); - - bool ReadNodesStaticDataRec(CGeomCacheStreamReader& reader); - - static bool CompareFrameTimes(const SFrameInfo& a, const SFrameInfo& b) - { - return a.m_frameTime < b.m_frameTime; - } - - char* GetFrameData(const uint frameIndex); - - bool m_bValid; - bool m_bLoaded; - - int m_refCount; - _smart_ptr m_pMaterial; - string m_fileName; - string m_lastError; - - // Static data streaming state - bool m_bUseStreaming; - uint32 m_lastDrawMainFrameId; - IReadStreamPtr m_pStaticDataReadStream; - - // Cache block compression format - GeomCacheFile::EBlockCompressionFormat m_blockCompressionFormat; - - // Playback from memory flag - bool m_bPlaybackFromMemory; - - // Number of frames - uint m_numFrames; - - // Number of streams reading from this cache - uint m_numStreams; - - // Offset of static mesh data - uint64 m_staticMeshDataOffset; - - // Total size of animated data - uint64 m_compressedAnimationDataSize; - - // Total size of uncompressed animation data - uint64 m_totalUncompressedAnimationSize; - - // AABB of entire animation - AABB m_aabb; - - // Static data size; - GeomCacheFile::SCompressedBlockHeader m_staticDataHeader; - - // Frame infos - std::vector m_frameInfos; - - std::vector m_staticMeshData; - std::vector m_staticNodeData; - - // Physics - std::vector m_physicsGeometries; - - // Holds references of static render meshes until cache object dies - std::vector<_smart_ptr > m_staticRenderMeshes; - - // Listeners - std::vector m_listeners; - - // Animation data (memory playback) - std::vector m_animationData; - - // Only matters when e_streamCGF is 0 - bool m_processedByRenderNode = true; -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHE_H diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.cpp b/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.cpp deleted file mode 100644 index 6d8d1683b8..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.cpp +++ /dev/null @@ -1,973 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Decodes geom cache data - - -#include "Cry3DEngine_precompiled.h" - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheDecoder.h" -#include "GeomCache.h" -#include "GeomCacheRenderNode.h" -#include "GeomCachePredictors.h" -#include "IZlibDecompressor.h" -#include "ILZ4Decompressor.h" -#include "IZStdDecompressor.h" -#include "Cry3DEngineTraits.h" - -namespace GeomCacheDecoder -{ - // This namespace will provide the different vertex decode function permutations to avoid dynamic branching - const uint kNumPermutations = 2 * 2 * 2 * 3; - - GeomCacheFile::Color FixedPointColorLerp(int32 a, int32 b, const int32 lerpFactor) - { - return a + (((b - a) * lerpFactor) >> 16); - } - - inline uint GetDecodeVerticesPerm(const bool bMotionBlur, const GeomCacheFile::EStreams constantStreamMask, const GeomCacheFile::EStreams animatedStreamMask) - { - uint permutation = 0; - - permutation += bMotionBlur ? (2 * 2 * 3) : 0; - permutation += (constantStreamMask& GeomCacheFile::eStream_Positions) ? (2 * 3) : 0; - permutation += (constantStreamMask& GeomCacheFile::eStream_Texcoords) ? 3 : 0; - permutation += (constantStreamMask& GeomCacheFile::eStream_Colors) ? 1 : 0; - permutation += (animatedStreamMask& GeomCacheFile::eStream_Colors) ? 2 : 0; - - return permutation; - } - -#if AZ_LEGACY_3DENGINE_TRAIT_DO_EXTRA_GEOMCACHE_PROCESSING - #define vec4f_swizzle(v, p, q, r, s) (_mm_shuffle_ps((v), (v), ((s) << 6 | (r) << 4 | (q) << 2 | (p)))) - - void ConvertToTangentAndBitangentVec4f(const __m128 interpolated, const __m128 floor, __m128& tangent, __m128& bitangent) - { - const __m128 comparedAgainstW = _mm_setr_ps(FLT_MIN, FLT_MIN, FLT_MIN, 0.0f); - const __m128 flipSignMask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); - const __m128 twos = _mm_setr_ps(2.0f, 2.0f, 2.0f, 0.0f); - - // (interpolated.w < 0.0f) != (floor.w < 0.0f) => flip sign of quaternions in registers - const __m128 cmp = _mm_xor_ps(_mm_cmplt_ps(interpolated, comparedAgainstW), _mm_cmplt_ps(floor, comparedAgainstW)); - const __m128 signCmp = vec4f_swizzle(cmp, 3, 3, 3, 3); - const __m128 xyzw = _mm_xor_ps(interpolated, _mm_and_ps(signCmp, flipSignMask)); - const __m128 wSignBit = _mm_and_ps(_mm_castsi128_ps(_mm_setr_epi32(0, 0, 0, 0x80000000)), xyzw); - - // Calculate tangent & bitangent - const __m128 xxxx = vec4f_swizzle(xyzw, 0, 0, 0, 0); - const __m128 yyyy = vec4f_swizzle(xyzw, 1, 1, 1, 1); - const __m128 wwww = vec4f_swizzle(xyzw, 3, 3, 3, 3); - const __m128 wzyx = vec4f_swizzle(xyzw, 3, 2, 1, 0); - const __m128 zwxy = vec4f_swizzle(xyzw, 2, 3, 0, 1); - - // tangent = (2 * (x * x + w * w) - 1, 2 * (y * x + z * w), 2 * (z * x - y * w), sign(w)) - __m128 wwnw = _mm_xor_ps(wwww, _mm_castsi128_ps(_mm_setr_epi32(0, 0, 0x80000000, 0))); // -> (w, w, -w, w) - tangent = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(xyzw, xxxx), _mm_mul_ps(wzyx, wwnw)), twos), _mm_setr_ps(-1.0f, 0.0f, 0.0f, 1.0f)); - tangent = _mm_or_ps(wSignBit, tangent); - - // bitangent = (2 * (x * y - z * w), 2 * (y * y + w * w) - 1, 2 * (z * y + x * w), sign(w)) - __m128 nwww = _mm_xor_ps(wwww, _mm_castsi128_ps(_mm_setr_epi32(0x80000000, 0, 0, 0))); // -> (-w, w, w, w) - bitangent = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(xyzw, yyyy), _mm_mul_ps(zwxy, nwww)), twos), _mm_setr_ps(0.0f, -1.0f, 0.0f, 1.0f)); - bitangent = _mm_or_ps(wSignBit, bitangent); - } - - // Don't use _mm_dp_ps because it's slower than the _mm_hadd_ps way (_mm_dp_ps is a microcoded instruction). - ILINE __m128 _mm_dp_ps_emu(const __m128& a, const __m128& b) - { - __m128 tmp1 = _mm_mul_ps(a, b); - __m128 tmp2 = _mm_hadd_ps(tmp1, tmp1); - return _mm_hadd_ps(tmp2, tmp2); - } - - __m128i _mm_cvtepi16_epi32_emu(const __m128i& a) - { -#if AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_CVTEPI16_EPI32 - return _mm_cvtepi16_epi32(a); -#else - // 5 instructions (unpack, and, cmp, and, or). Idea is to fill 0xFFFF in the hi-word if the sign bit of the lo-word 1. - const __m128i signBitsMask = _mm_set1_epi32(0x00008000); - const __m128i hiWordBitMask = _mm_set1_epi32(0xFFFF0000); - - // Unsigned conversion, upper word will be 0x0000 even if sign bit is set - const __m128i unpacked = _mm_unpacklo_epi16(a, _mm_set1_epi16(0)); - - // Mask out sign bits - const __m128i signBitsMasked = _mm_castps_si128(_mm_and_ps(_mm_castsi128_ps(unpacked), _mm_castsi128_ps(signBitsMask))); - - // Sets dwords to 0xFFFFFFFF if sign bit is 1 - const __m128i cmpBits = _mm_cmpeq_epi32(signBitsMasked, signBitsMask); - - // Mask dwords to 0xFFFF0000 if sign bit was set - const __m128i signExtendBits = _mm_and_si128(hiWordBitMask, cmpBits); - - // Finally sign extend with 0xFFFF0000 if sign bit was set - return _mm_or_si128(unpacked, signExtendBits); -#endif - } -#endif - - void DecodeAndInterpolateTangents(const uint numVertices, const float lerpFactor, const GeomCacheFile::QTangent* __restrict pFloorQTangents, - const GeomCacheFile::QTangent* __restrict pCeilQTangents, strided_pointer pTangents) - { -#if AZ_LEGACY_3DENGINE_TRAIT_DO_EXTRA_GEOMCACHE_PROCESSING - const uint numVerticesPerIteration = 2; - const uint numSIMDIterations = numVertices / numVerticesPerIteration; - - const float kMultiplier = float((2 << (GeomCacheFile::kTangentQuatPrecision - 1)) - 1); - const __m128 convertFromUint16FactorPacked = _mm_set1_ps(1.0f / kMultiplier); - const __m128 lerpFactorPacked = _mm_set1_ps(lerpFactor); - const __m128i zero = _mm_setzero_si128(); - const __m128 flipSignMask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); - const __m128 scaleToInt16Factor = _mm_setr_ps(32767.0f, 32767.0f, 32767.0f, 32767.0f); - - __m128i* pFloorQTangents128 = (__m128i*)&pFloorQTangents[0]; - __m128i* pCeilQTangents128 = (__m128i*)&pCeilQTangents[0]; - __m128i* pTangents128 = (__m128i*)pTangents.data; - - for (unsigned int i = 0, j = 0; i < numSIMDIterations; ++i, j += 2) - { - const __m128i floorQTangents = _mm_load_si128(pFloorQTangents128 + i); - const __m128i ceilQTangents = _mm_load_si128(pCeilQTangents128 + i); - - // Unpack to lo/hi qTangents and convert to float [-1, 1] - __m128 floorLo = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepi16_epi32_emu(floorQTangents)), convertFromUint16FactorPacked); - __m128 floorHi = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepi16_epi32_emu(_mm_shuffle_epi32(floorQTangents, _MM_SHUFFLE(1, 0, 3, 2)))), convertFromUint16FactorPacked); - __m128 ceilLo = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepi16_epi32_emu(ceilQTangents)), convertFromUint16FactorPacked); - __m128 ceilHi = _mm_mul_ps(_mm_cvtepi32_ps(_mm_cvtepi16_epi32_emu(_mm_shuffle_epi32(ceilQTangents, _MM_SHUFFLE(1, 0, 3, 2)))), convertFromUint16FactorPacked); - - // Need to flip sign of the ceil quaternion if the dot product of floor and ceil < 0 - __m128 dotLo = _mm_dp_ps_emu(floorLo, ceilLo); - __m128 dotCmpLo = _mm_cmplt_ps(dotLo, _mm_castsi128_ps(zero)); - __m128 flipSignLo = _mm_and_ps(dotCmpLo, flipSignMask); - ceilLo = _mm_xor_ps(ceilLo, flipSignLo); - - __m128 dotHi = _mm_dp_ps_emu(floorHi, ceilHi); - __m128 dotCmpHi = _mm_cmplt_ps(dotHi, _mm_castsi128_ps(zero)); - __m128 flipSignHi = _mm_and_ps(dotCmpHi, flipSignMask); - ceilHi = _mm_xor_ps(ceilHi, flipSignHi); - - // Interpolate the quaternions - __m128 interpolatedLo = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ceilLo, floorLo), lerpFactorPacked), floorLo); - __m128 interpolatedHi = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ceilHi, floorHi), lerpFactorPacked), floorHi); - - // Normalize - interpolatedLo = _mm_mul_ps(_mm_rsqrt_ps(_mm_dp_ps_emu(interpolatedLo, interpolatedLo)), interpolatedLo); - interpolatedHi = _mm_mul_ps(_mm_rsqrt_ps(_mm_dp_ps_emu(interpolatedHi, interpolatedHi)), interpolatedHi); - - // Convert to tangent/bitangent pairs - __m128 tangentLo, bitangentLo, tangentHi, bitangentHi; - ConvertToTangentAndBitangentVec4f(interpolatedLo, floorLo, tangentLo, bitangentLo); - ConvertToTangentAndBitangentVec4f(interpolatedHi, floorHi, tangentHi, bitangentHi); - - // Scale and convert to int - __m128i tangentIntLo = _mm_cvtps_epi32(_mm_mul_ps(tangentLo, scaleToInt16Factor)); - __m128i bitangentIntLo = _mm_cvtps_epi32(_mm_mul_ps(bitangentLo, scaleToInt16Factor)); - __m128i tangentIntHi = _mm_cvtps_epi32(_mm_mul_ps(tangentHi, scaleToInt16Factor)); - __m128i bitangentIntHi = _mm_cvtps_epi32(_mm_mul_ps(bitangentHi, scaleToInt16Factor)); - - // Pack - __m128i tangentBitangentLo = _mm_packs_epi32(tangentIntLo, bitangentIntLo); - __m128i tangentBitangentHi = _mm_packs_epi32(tangentIntHi, bitangentIntHi); - - // And finally store - _mm_store_si128(pTangents128 + j, tangentBitangentLo); - _mm_store_si128(pTangents128 + j + 1, tangentBitangentHi); - } - - const uint scalarStart = numSIMDIterations * numVerticesPerIteration; -#else - const uint scalarStart = 0; -#endif - for (unsigned int i = scalarStart; i < numVertices; ++i) - { - const Quat decodedFloorQTangent = DecodeQTangent(pFloorQTangents[i]); - const Quat decodedCeilQTangent = DecodeQTangent(pCeilQTangents[i]); - - Quat interpolatedQTangent = Quat::CreateNlerp(decodedFloorQTangent, decodedCeilQTangent, lerpFactor); - - if ((interpolatedQTangent.w < 0.0f) != (decodedFloorQTangent.w < 0.0f)) - { - interpolatedQTangent = -interpolatedQTangent; - } - - ConvertToTangentAndBitangent(interpolatedQTangent, pTangents[i]); - } - } - - template - void DecodeAndInterpolateColorAndTexcoords([[maybe_unused]] SGeomCacheRenderMeshUpdateContext& updateContext, [[maybe_unused]] const uint index, - const SGeomCacheStaticMeshData& staticMeshData, [[maybe_unused]] uint32 fpLerpFactor, const float lerpFactor, - [[maybe_unused]] const GeomCacheFile::Color* __restrict pFloorReds, [[maybe_unused]] const GeomCacheFile::Color* __restrict pCeilReds, - [[maybe_unused]] const GeomCacheFile::Color* __restrict pFloorGreens, [[maybe_unused]] const GeomCacheFile::Color* __restrict pCeilGreens, - [[maybe_unused]] const GeomCacheFile::Color* __restrict pFloorBlues, [[maybe_unused]] const GeomCacheFile::Color* __restrict pCeilBlues, - [[maybe_unused]] const GeomCacheFile::Color* __restrict pFloorAlphas, [[maybe_unused]] const GeomCacheFile::Color* __restrict pCeilAlphas, - [[maybe_unused]] const GeomCacheFile::Texcoords* __restrict pFloorTexcoords, [[maybe_unused]] const GeomCacheFile::Texcoords* __restrict pCeilTexcoords) - { - if constexpr (!bConstantColors && !bAnimatedColors) - { - updateContext.m_pColors[index].dcolor = 0xFFFFFFFF; - } - else if (bConstantColors) - { - updateContext.m_pColors[index].bcolor[0] = staticMeshData.m_colors[index].bcolor[0]; - updateContext.m_pColors[index].bcolor[1] = staticMeshData.m_colors[index].bcolor[1]; - updateContext.m_pColors[index].bcolor[2] = staticMeshData.m_colors[index].bcolor[2]; - updateContext.m_pColors[index].bcolor[3] = staticMeshData.m_colors[index].bcolor[3]; - } - else if (bAnimatedColors) - { - updateContext.m_pColors[index].bcolor[0] = FixedPointColorLerp(pFloorBlues[index], pCeilBlues[index], fpLerpFactor); - updateContext.m_pColors[index].bcolor[1] = FixedPointColorLerp(pFloorGreens[index], pCeilGreens[index], fpLerpFactor); - updateContext.m_pColors[index].bcolor[2] = FixedPointColorLerp(pFloorReds[index], pCeilReds[index], fpLerpFactor); - updateContext.m_pColors[index].bcolor[3] = FixedPointColorLerp(pFloorAlphas[index], pCeilAlphas[index], fpLerpFactor); - } - - if (bConstantTexcoords) - { - updateContext.m_pTexcoords[index] = staticMeshData.m_texcoords[index]; - } - else - { - updateContext.m_pTexcoords[index] = Vec2::CreateLerp(DecodeTexcoord(pFloorTexcoords[index], staticMeshData.m_uvMax), DecodeTexcoord(pCeilTexcoords[index], staticMeshData.m_uvMax), lerpFactor); - } - } - - template - void DecodeMeshVerticesBranchless(SGeomCacheRenderMeshUpdateContext& updateContext, - const SGeomCacheStaticMeshData& staticMeshData, const char* pFloorFrameDataPtr, - const char* pCeilFrameDataPtr, const float lerpFactor) - { - const unsigned int numVertices = staticMeshData.m_numVertices; - const int32 fpLerpFactor = int32(lerpFactor * 65535.0f); - - const bool bMotionBlur = Permutation % (2 * 2 * 2 * 3) >= (2 * 2 * 3); - const bool bConstantPositions = Permutation % (2 * 2 * 3) >= (2 * 3); - const bool bConstantTexcoords = (Permutation % (2 * 3)) >= 3; - const bool bConstantColors = (Permutation % 3) == 1; - const bool bAnimatedColors = (Permutation % 3) == 2; - - const Vec3& aabbMin = staticMeshData.m_aabb.min; - const Vec3 aabbSize = staticMeshData.m_aabb.GetSize(); - - const GeomCacheFile::Position* __restrict pFloorPositions = bConstantPositions ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Position* __restrict pCeilPositions = bConstantPositions ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += bConstantPositions ? 0 : ((numVertices * sizeof(GeomCacheFile::Position) + 15) & ~15); - pCeilFrameDataPtr += bConstantPositions ? 0 : ((numVertices * sizeof(GeomCacheFile::Position) + 15) & ~15); - - const GeomCacheFile::Texcoords* __restrict pFloorTexcoords = bConstantTexcoords ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Texcoords* __restrict pCeilTexcoords = bConstantTexcoords ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += bConstantTexcoords ? 0 : ((numVertices * sizeof(GeomCacheFile::Texcoords) + 15) & ~15); - pCeilFrameDataPtr += bConstantTexcoords ? 0 : ((numVertices * sizeof(GeomCacheFile::Texcoords) + 15) & ~15); - - const GeomCacheFile::QTangent* __restrict pFloorQTangents = (bConstantPositions && bConstantTexcoords) ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::QTangent* __restrict pCeilQTangents = (bConstantPositions && bConstantTexcoords) ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += (bConstantPositions && bConstantTexcoords) ? 0 : ((numVertices * sizeof(GeomCacheFile::QTangent) + 15) & ~15); - pCeilFrameDataPtr += (bConstantPositions && bConstantTexcoords) ? 0 : ((numVertices * sizeof(GeomCacheFile::QTangent) + 15) & ~15); - - const GeomCacheFile::Color* __restrict pFloorReds = !bAnimatedColors ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Color* __restrict pCeilReds = !bAnimatedColors ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - pCeilFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - - const GeomCacheFile::Color* __restrict pFloorGreens = !bAnimatedColors ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Color* __restrict pCeilGreens = !bAnimatedColors ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - pCeilFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - - const GeomCacheFile::Color* __restrict pFloorBlues = !bAnimatedColors ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Color* __restrict pCeilBlues = !bAnimatedColors ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - pCeilFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - - const GeomCacheFile::Color* __restrict pFloorAlphas = !bAnimatedColors ? NULL : - reinterpret_cast(pFloorFrameDataPtr); - const GeomCacheFile::Color* __restrict pCeilAlphas = !bAnimatedColors ? NULL : - reinterpret_cast(pCeilFrameDataPtr); - pFloorFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - pCeilFrameDataPtr += !bAnimatedColors ? 0 : ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15); - - const Vec3 posConvertFactor = Vec3(1.0f / float((2 << (staticMeshData.m_positionPrecision[0] - 1)) - 1), - 1.0f / float((2 << (staticMeshData.m_positionPrecision[1] - 1)) - 1), - 1.0f / float((2 << (staticMeshData.m_positionPrecision[2] - 1)) - 1)); - -#if AZ_LEGACY_3DENGINE_TRAIT_DO_EXTRA_GEOMCACHE_PROCESSING - const uint numVerticesPerIteration = 8; - const uint numPackedFloatsPerIteration = (numVerticesPerIteration * sizeof(Vec3)) / 16; - const uint numPackedUInt16PerIteration = (numVerticesPerIteration * sizeof(Vec3_tpl)) / 16; - const uint numFloatsPerIteration = numVerticesPerIteration * (sizeof(Vec3) / sizeof(float)); - const uint numFloatsPerPack = 4; - const uint numSIMDIterations = numVertices / numVerticesPerIteration; - - float* pPrevPositionsF = updateContext.m_prevPositions.size() > 0 ? (float*)&updateContext.m_prevPositions[0] : NULL; - float* pVelocitiesF = (float*)&updateContext.m_pVelocities[0]; - __m128i* pFloorPositions128 = (__m128i*)&pFloorPositions[0]; - __m128i* pCeilPositions128 = (__m128i*)&pCeilPositions[0]; - - const __m128 lerpFactorPacked = _mm_set1_ps(lerpFactor); - - __m128 convertFromUint16FactorPacked[numPackedFloatsPerIteration]; - convertFromUint16FactorPacked[0] = _mm_setr_ps(posConvertFactor.x, posConvertFactor.y, posConvertFactor.z, posConvertFactor.x); - convertFromUint16FactorPacked[1] = _mm_setr_ps(posConvertFactor.y, posConvertFactor.z, posConvertFactor.x, posConvertFactor.y); - convertFromUint16FactorPacked[2] = _mm_setr_ps(posConvertFactor.z, posConvertFactor.x, posConvertFactor.y, posConvertFactor.z); - convertFromUint16FactorPacked[3] = _mm_setr_ps(posConvertFactor.x, posConvertFactor.y, posConvertFactor.z, posConvertFactor.x); - convertFromUint16FactorPacked[4] = _mm_setr_ps(posConvertFactor.y, posConvertFactor.z, posConvertFactor.x, posConvertFactor.y); - convertFromUint16FactorPacked[5] = _mm_setr_ps(posConvertFactor.z, posConvertFactor.x, posConvertFactor.y, posConvertFactor.z); - - __m128 aabbMinPacked[numPackedFloatsPerIteration]; - aabbMinPacked[0] = _mm_setr_ps(aabbMin.x, aabbMin.y, aabbMin.z, aabbMin.x); - aabbMinPacked[1] = _mm_setr_ps(aabbMin.y, aabbMin.z, aabbMin.x, aabbMin.y); - aabbMinPacked[2] = _mm_setr_ps(aabbMin.z, aabbMin.x, aabbMin.y, aabbMin.z); - aabbMinPacked[3] = _mm_setr_ps(aabbMin.x, aabbMin.y, aabbMin.z, aabbMin.x); - aabbMinPacked[4] = _mm_setr_ps(aabbMin.y, aabbMin.z, aabbMin.x, aabbMin.y); - aabbMinPacked[5] = _mm_setr_ps(aabbMin.z, aabbMin.x, aabbMin.y, aabbMin.z); - - __m128 aabbSizePacked[numPackedFloatsPerIteration]; - aabbSizePacked[0] = _mm_setr_ps(aabbSize.x, aabbSize.y, aabbSize.z, aabbSize.x); - aabbSizePacked[1] = _mm_setr_ps(aabbSize.y, aabbSize.z, aabbSize.x, aabbSize.y); - aabbSizePacked[2] = _mm_setr_ps(aabbSize.z, aabbSize.x, aabbSize.y, aabbSize.z); - aabbSizePacked[3] = _mm_setr_ps(aabbSize.x, aabbSize.y, aabbSize.z, aabbSize.x); - aabbSizePacked[4] = _mm_setr_ps(aabbSize.y, aabbSize.z, aabbSize.x, aabbSize.y); - aabbSizePacked[5] = _mm_setr_ps(aabbSize.z, aabbSize.x, aabbSize.y, aabbSize.z); - - __m128 newPositions[numPackedFloatsPerIteration]; - __m128 oldPositions[numPackedFloatsPerIteration]; - - for (unsigned int i = 0; i < numSIMDIterations; ++i) - { - const uint floatOffset = i * numFloatsPerIteration; - - if constexpr (bMotionBlur && !bConstantPositions) - { - for (uint j = 0; j < numPackedFloatsPerIteration; ++j) - { - oldPositions[j] = _mm_load_ps(&pPrevPositionsF[floatOffset + j * numFloatsPerPack]); - } - } - - if (bConstantPositions) - { - for (uint j = 0; j < numVerticesPerIteration; ++j) - { - const uint index = (i * numVerticesPerIteration) + j; - updateContext.m_pPositions[index] = staticMeshData.m_positions[index]; - } - } - else if (!bConstantPositions) - { - const __m128i zero = _mm_setzero_si128(); - - for (uint j = 0, k = 0; j < numPackedUInt16PerIteration; ++j, k += 2) - { - const uint indexLo = k; - const uint indexHi = k + 1; - - __m128i floorPositions = _mm_load_si128(pFloorPositions128 + (i * numPackedUInt16PerIteration) + j); - __m128i ceilPositions = _mm_load_si128(pCeilPositions128 + (i * numPackedUInt16PerIteration) + j); - - // Unpack and convert to float [0, 1] - __m128 floorLo = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(floorPositions, zero)), convertFromUint16FactorPacked[indexLo]); - __m128 floorHi = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(floorPositions, zero)), convertFromUint16FactorPacked[indexHi]); - __m128 ceilLo = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi16(ceilPositions, zero)), convertFromUint16FactorPacked[indexLo]); - __m128 ceilHi = _mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi16(ceilPositions, zero)), convertFromUint16FactorPacked[indexHi]); - - // Convert to [aabbMin, aabbMax] range - floorLo = _mm_add_ps(_mm_mul_ps(floorLo, aabbSizePacked[indexLo]), aabbMinPacked[indexLo]); - floorHi = _mm_add_ps(_mm_mul_ps(floorHi, aabbSizePacked[indexHi]), aabbMinPacked[indexHi]); - ceilLo = _mm_add_ps(_mm_mul_ps(ceilLo, aabbSizePacked[indexLo]), aabbMinPacked[indexLo]); - ceilHi = _mm_add_ps(_mm_mul_ps(ceilHi, aabbSizePacked[indexHi]), aabbMinPacked[indexHi]); - - // Interpolate - newPositions[indexLo] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ceilLo, floorLo), lerpFactorPacked), floorLo); - newPositions[indexHi] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ceilHi, floorHi), lerpFactorPacked), floorHi); - } - - // Store to scratch & prev position array - _MS_ALIGN(16) Vec3 positionScratch[numVerticesPerIteration]; - float* __restrict pPositionScratch128 = (float*)&positionScratch[0]; - for (uint j = 0; j < numPackedFloatsPerIteration; ++j) - { - _mm_store_ps(pPositionScratch128 + j * numFloatsPerPack, newPositions[j]); - _mm_store_ps(&pPrevPositionsF[floatOffset + j * numFloatsPerPack], newPositions[j]); - } - - // Scatter to position vertex stream - for (uint j = 0; j < numVerticesPerIteration; ++j) - { - const uint index = (i * numVerticesPerIteration) + j; - updateContext.m_pPositions[index] = positionScratch[j]; - } - } - - for (uint j = 0; j < numVerticesPerIteration; ++j) - { - const uint index = (i * numVerticesPerIteration) + j; - DecodeAndInterpolateColorAndTexcoords(updateContext, index, staticMeshData, fpLerpFactor, lerpFactor, - pFloorReds, pCeilReds, pFloorGreens, pCeilGreens, pFloorBlues, pCeilBlues, pFloorAlphas, pCeilAlphas, pFloorTexcoords, pCeilTexcoords); - } - - if (!bMotionBlur) - { - __m128 zero = _mm_setzero_ps(); - for (uint j = 0; j < numPackedFloatsPerIteration; ++j) - { - _mm_store_ps(&pVelocitiesF[floatOffset + j * numFloatsPerPack], zero); - } - } - else if (!bConstantPositions) - { - for (uint j = 0; j < numPackedFloatsPerIteration; ++j) - { - __m128 motionVectors = _mm_sub_ps(oldPositions[j], newPositions[j]); - _mm_store_ps(&pVelocitiesF[floatOffset + j * numFloatsPerPack], motionVectors); - } - } - } - - const uint scalarStart = numSIMDIterations * numVerticesPerIteration; -#else - const uint scalarStart = 0; -#endif - - for (unsigned int i = scalarStart; i < numVertices; ++i) - { - Vec3 newPosition; - Vec3 oldPosition; - - if constexpr (bMotionBlur && !bConstantPositions) - { - oldPosition = updateContext.m_prevPositions[i]; - } - - if (bConstantPositions) - { - newPosition = staticMeshData.m_positions[i]; - } - else if (!bConstantPositions) - { - newPosition = Vec3::CreateLerp(DecodePosition(aabbMin, aabbSize, pFloorPositions[i], posConvertFactor), - DecodePosition(aabbMin, aabbSize, pCeilPositions[i], posConvertFactor), lerpFactor); - } - - Vec3 oldPos = updateContext.m_pPositions[i]; - updateContext.m_pPositions[i] = newPosition; - updateContext.m_prevPositions[i] = newPosition; - - DecodeAndInterpolateColorAndTexcoords(updateContext, i, staticMeshData, fpLerpFactor, lerpFactor, - pFloorReds, pCeilReds, pFloorGreens, pCeilGreens, pFloorBlues, pCeilBlues, pFloorAlphas, pCeilAlphas, pFloorTexcoords, pCeilTexcoords); - - if (!bMotionBlur) - { - updateContext.m_pVelocities[i] = Vec3(0.0f, 0.0f, 0.0f); - } - else if (!bConstantPositions) - { - updateContext.m_pVelocities[i] = oldPosition - newPosition; - } - } - - if constexpr (bConstantPositions && bConstantTexcoords) - { - for (unsigned int i = 0; i < numVertices; ++i) - { - updateContext.m_pTangents[i] = staticMeshData.m_tangents[i]; - } - } - else - { - DecodeAndInterpolateTangents(numVertices, lerpFactor, pFloorQTangents, pCeilQTangents, updateContext.m_pTangents); - } - } - - uint32 GetMeshDataSize(const SGeomCacheStaticMeshData& staticMeshData) - { - const unsigned int numVertices = staticMeshData.m_numVertices; - - const GeomCacheFile::EStreams constantStreamMask = staticMeshData.m_constantStreams; - const GeomCacheFile::EStreams animatedStreamMask = staticMeshData.m_animatedStreams; - - const bool bConstantPositions = (constantStreamMask& GeomCacheFile::eStream_Positions) != 0; - const bool bConstantTexcoords = (constantStreamMask& GeomCacheFile::eStream_Texcoords) != 0; - const bool bAnimatedColors = (animatedStreamMask& GeomCacheFile::eStream_Colors) != 0; - - uint32 offset = 0; - offset += bConstantPositions ? 0 : ((numVertices * sizeof(GeomCacheFile::Position) + 15) & ~15); - offset += bConstantTexcoords ? 0 : ((numVertices * sizeof(GeomCacheFile::Texcoords) + 15) & ~15); - offset += (bConstantPositions && bConstantTexcoords) ? 0 : ((numVertices * sizeof(GeomCacheFile::QTangent) + 15) & ~15); - offset += !bAnimatedColors ? 0 : (4 * ((numVertices * sizeof(GeomCacheFile::Color) + 15) & ~15)); - - return offset; - } - - typedef void (* TDecodeVerticesBranchlessPtr)(SGeomCacheRenderMeshUpdateContext& updateContext, - const SGeomCacheStaticMeshData& staticMeshData, const char* pFloorFrameDataPtr, - const char* pCeilFrameDataPtr, const float lerpFactor); - - TDecodeVerticesBranchlessPtr pDecodeFunctions[kNumPermutations]; - - template - struct PermutationInit - { - // Need two variables, because GCC otherwise complains about too many recursions - static TDecodeVerticesBranchlessPtr m_pFunction1; - static TDecodeVerticesBranchlessPtr m_pFunction2; - }; - - template - TDecodeVerticesBranchlessPtr PermutationInit::m_pFunction1 = pDecodeFunctions[Permutation - 1] - = PermutationInit::m_pFunction1 = &DecodeMeshVerticesBranchless; - template<> - TDecodeVerticesBranchlessPtr PermutationInit<0>::m_pFunction1 = &DecodeMeshVerticesBranchless<0>; - - template - TDecodeVerticesBranchlessPtr PermutationInit::m_pFunction2 = pDecodeFunctions[Permutation - 1 + (kNumPermutations / 2)] - = PermutationInit::m_pFunction2 = &DecodeMeshVerticesBranchless; - template<> - TDecodeVerticesBranchlessPtr PermutationInit<0>::m_pFunction2 = &DecodeMeshVerticesBranchless<(kNumPermutations / 2)>; - - // This forces the instantiation of PermutationInit::m_pFunction - // and therefore recursively initializes pDecodeFunctions with the DecodeVertices permutations - template struct PermutationInit; - - void DecodeIFrame(const CGeomCache* pGeomCache, char* pData) - { - // Skip header - pData += sizeof(GeomCacheFile::SFrameHeader); - const std::vector& staticMeshData = pGeomCache->GetStaticMeshData(); - - const uint numMeshes = staticMeshData.size(); - for (uint i = 0; i < numMeshes; ++i) - { - const SGeomCacheStaticMeshData& currentStaticMeshData = staticMeshData[i]; - - if (currentStaticMeshData.m_animatedStreams == 0) - { - continue; - } - - pData += sizeof(GeomCacheFile::SMeshFrameHeader); - - const GeomCacheFile::EStreams streamMask = currentStaticMeshData.m_animatedStreams; - const bool bUsePrediction = currentStaticMeshData.m_bUsePredictor; - const uint numVertices = currentStaticMeshData.m_numVertices; - - if (streamMask & GeomCacheFile::eStream_Positions) - { - if (bUsePrediction) - { - GeomCacheFile::Position* pPositions = reinterpret_cast(pData); - GeomCachePredictors::ParallelogramPredictor(numVertices, pPositions, pPositions, currentStaticMeshData.m_predictorData); - } - - pData += ((sizeof(GeomCacheFile::Position) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_Texcoords) - { - if (bUsePrediction) - { - GeomCacheFile::Texcoords* pTexcoords = reinterpret_cast(pData); - GeomCachePredictors::ParallelogramPredictor(numVertices, pTexcoords, pTexcoords, currentStaticMeshData.m_predictorData); - } - - pData += ((sizeof(GeomCacheFile::Texcoords) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_QTangents) - { - if (bUsePrediction) - { - GeomCacheFile::QTangent* pQTangents = reinterpret_cast(pData); - GeomCachePredictors::QTangentPredictor(numVertices, pQTangents, pQTangents, currentStaticMeshData.m_predictorData); - } - - pData += ((sizeof(GeomCacheFile::QTangent) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_Colors) - { - if (bUsePrediction) - { - GeomCacheFile::Color* pReds = reinterpret_cast(pData); - pData += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - GeomCacheFile::Color* pGreens = reinterpret_cast(pData); - pData += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - GeomCacheFile::Color* pBlues = reinterpret_cast(pData); - pData += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - GeomCacheFile::Color* pAlphas = reinterpret_cast(pData); - pData += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - - GeomCachePredictors::ColorPredictor(numVertices, pReds, pReds, currentStaticMeshData.m_predictorData); - GeomCachePredictors::ColorPredictor(numVertices, pGreens, pGreens, currentStaticMeshData.m_predictorData); - GeomCachePredictors::ColorPredictor(numVertices, pBlues, pBlues, currentStaticMeshData.m_predictorData); - GeomCachePredictors::ColorPredictor(numVertices, pAlphas, pAlphas, currentStaticMeshData.m_predictorData); - } - else - { - pData += 4 * ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - } - } - } - } - - void DecodeBFrame(const CGeomCache* pGeomCache, char* pData, char* pPrevFramesData[2], char* pFloorIndexFrameData, char* pCeilIndexFrameData) - { - // Skip header - size_t offset = sizeof(GeomCacheFile::SFrameHeader); - const std::vector& staticMeshData = pGeomCache->GetStaticMeshData(); - - const uint numMeshes = staticMeshData.size(); - for (uint i = 0; i < numMeshes; ++i) - { - const SGeomCacheStaticMeshData& currentStaticMeshData = staticMeshData[i]; - - if (currentStaticMeshData.m_animatedStreams == 0) - { - continue; - } - - const GeomCacheFile::SMeshFrameHeader* pFrameHeader = reinterpret_cast(pData + offset); - offset += sizeof(GeomCacheFile::SMeshFrameHeader); - - if ((pFrameHeader->m_flags & GeomCacheFile::eFrameFlags_Hidden) != 0) - { - offset += GetMeshDataSize(currentStaticMeshData); - continue; - } - - const GeomCacheFile::EStreams streamMask = currentStaticMeshData.m_animatedStreams; - const uint numVertices = currentStaticMeshData.m_numVertices; - - if (streamMask & GeomCacheFile::eStream_Positions) - { - GeomCacheFile::Position* pPositions = reinterpret_cast(pData + offset); - GeomCachePredictors::STemporalPredictorData predictorData; - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - typedef Vec3_tpl I; - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_positionStreamPredictorControl, predictorData, pPositions, pPositions); - - offset += ((sizeof(GeomCacheFile::Position) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_Texcoords) - { - GeomCacheFile::Texcoords* pTexcoords = reinterpret_cast(pData + offset); - GeomCachePredictors::STemporalPredictorData predictorData; - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - typedef Vec2_tpl I; - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_texcoordStreamPredictorControl, predictorData, pTexcoords, pTexcoords); - - offset += ((sizeof(GeomCacheFile::Texcoords) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_QTangents) - { - GeomCacheFile::QTangent* pQTangents = reinterpret_cast(pData + offset); - GeomCachePredictors::STemporalPredictorData predictorData; - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - typedef Vec4_tpl I; - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_qTangentStreamPredictorControl, predictorData, pQTangents, pQTangents); - - offset += ((sizeof(GeomCacheFile::QTangent) * numVertices) + 15) & ~15; - } - - if (streamMask & GeomCacheFile::eStream_Colors) - { - GeomCachePredictors::STemporalPredictorData predictorData; - typedef uint16 I; - - GeomCacheFile::Color* pReds = reinterpret_cast(pData + offset); - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_colorStreamPredictorControl[0], predictorData, pReds, pReds); - - offset += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - - GeomCacheFile::Color* pGreens = reinterpret_cast(pData + offset); - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_colorStreamPredictorControl[1], predictorData, pGreens, pGreens); - - offset += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - - GeomCacheFile::Color* pBlues = reinterpret_cast(pData + offset); - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_colorStreamPredictorControl[2], predictorData, pBlues, pBlues); - - offset += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - - GeomCacheFile::Color* pAlphas = reinterpret_cast(pData + offset); - predictorData.m_numElements = numVertices; - predictorData.m_pPrevFrames[0] = reinterpret_cast(pPrevFramesData[0] + offset); - predictorData.m_pPrevFrames[1] = reinterpret_cast(pPrevFramesData[1] + offset); - predictorData.m_pFloorFrame = reinterpret_cast(pFloorIndexFrameData + offset); - predictorData.m_pCeilFrame = reinterpret_cast(pCeilIndexFrameData + offset); - - GeomCachePredictors::InterpolateMotionDeltaPredictor - (pFrameHeader->m_colorStreamPredictorControl[3], predictorData, pAlphas, pAlphas); - - offset += ((sizeof(GeomCacheFile::Color) * numVertices) + 15) & ~15; - } - } - } - - bool PrepareFillMeshData([[maybe_unused]] SGeomCacheRenderMeshUpdateContext& updateContext, const SGeomCacheStaticMeshData& staticMeshData, - const char*& pFloorFrameMeshData, const char*& pCeilFrameMeshData, size_t& offsetToNextMesh, float& lerpFactor) - { - const GeomCacheFile::SMeshFrameHeader* pFloorHeader = reinterpret_cast(pFloorFrameMeshData); - const GeomCacheFile::SMeshFrameHeader* pCeilHeader = reinterpret_cast(pCeilFrameMeshData); - - pFloorFrameMeshData += sizeof(GeomCacheFile::SMeshFrameHeader); - pCeilFrameMeshData += sizeof(GeomCacheFile::SMeshFrameHeader); - - const bool bFloorFrameHidden = (pFloorHeader->m_flags & GeomCacheFile::eFrameFlags_Hidden) != 0; - const bool bCeilFrameHidden = (pCeilHeader->m_flags & GeomCacheFile::eFrameFlags_Hidden) != 0; - - offsetToNextMesh = GetMeshDataSize(staticMeshData); - - if (bFloorFrameHidden && bCeilFrameHidden) - { - return false; - } - else if (bFloorFrameHidden) - { - lerpFactor = 1.0f; - } - else if (bCeilFrameHidden) - { - lerpFactor = 0.0f; - } - -#if defined(CONSOLE_CONST_CVAR_MODE) - if constexpr (CVars::e_GeomCacheLerpBetweenFrames == 0) -#else - if (Cry3DEngineBase::m_pCVars->e_GeomCacheLerpBetweenFrames == 0) -#endif - { - pCeilFrameMeshData = pFloorFrameMeshData; - lerpFactor = 0.0f; - } - - return true; - } - - void FillMeshDataFromDecodedFrame(const bool bMotionBlur, SGeomCacheRenderMeshUpdateContext& updateContext, - const SGeomCacheStaticMeshData& staticMeshData, const char* pFloorFrameMeshData, const char* pCeilFrameMeshData, float lerpFactor) - { - // Fetch indices from static data - const uint numIndices = staticMeshData.m_indices.size(); - for (uint i = 0; i < numIndices; ++i) - { - updateContext.m_pIndices[i] = staticMeshData.m_indices[i]; - } - - const uint permutation = GetDecodeVerticesPerm(bMotionBlur, staticMeshData.m_constantStreams, staticMeshData.m_animatedStreams); - TDecodeVerticesBranchlessPtr pDecodeFunction = pDecodeFunctions[permutation]; - (*pDecodeFunction)(updateContext, staticMeshData, pFloorFrameMeshData, pCeilFrameMeshData, lerpFactor); - } - - Vec3 DecodePosition(const Vec3& aabbMin, const Vec3& aabbSize, const GeomCacheFile::Position& inPosition, const Vec3& convertFactor) - { - return Vec3(aabbMin.x + ((float)inPosition.x * convertFactor.x) * aabbSize.x, - aabbMin.y + ((float)inPosition.y * convertFactor.y) * aabbSize.y, - aabbMin.z + ((float)inPosition.z * convertFactor.z) * aabbSize.z); - } - - Vec2 DecodeTexcoord(const GeomCacheFile::Texcoords& inTexcoords, float uvMax) - { - const float convertFromInt16Factor = 1.0f / 32767.0f; - - return Vec2((float)inTexcoords.x * convertFromInt16Factor * uvMax, - (float)inTexcoords.y * convertFromInt16Factor * uvMax); - } - - Quat DecodeQTangent(const GeomCacheFile::QTangent& inQTangent) - { - const float kMultiplier = float((2 << (GeomCacheFile::kTangentQuatPrecision - 1)) - 1); - const float convertFromInt16Factor = 1.0f / kMultiplier; - - return Quat((float)inQTangent.w * convertFromInt16Factor, (float)inQTangent.x * convertFromInt16Factor, - (float)inQTangent.y * convertFromInt16Factor, (float)inQTangent.z * convertFromInt16Factor); - } - - void TransformAndConvertToTangentAndBitangent(const Quat& rotation, const Quat& inQTangent, SPipTangents& outTangents) - { - int16 reflection = alias_cast(inQTangent.w) & 0x80000000 ? -1 : +1; - Quat transformedQTangent = rotation * inQTangent; - - outTangents = SPipTangents(transformedQTangent, reflection); - } - - void ConvertToTangentAndBitangent(const Quat& inQTangent, SPipTangents& outTangents) - { - int16 reflection = alias_cast(inQTangent.w) & 0x80000000 ? -1 : +1; - - outTangents = SPipTangents(inQTangent, reflection); - } - - uint32 GetDecompressBufferSize(const char* const pStartBlock, const unsigned int numFrames) - { - FUNCTION_PROFILER_3DENGINE; - - uint32 totalUncompressedSize = 0; - const char* pCurrentBlock = pStartBlock; - - const uint32 headersSize = ((sizeof(SGeomCacheFrameHeader) * numFrames) + 15) & ~15; - - for (unsigned int i = 0; i < numFrames; ++i) - { - const GeomCacheFile::SCompressedBlockHeader* pBlockHeader = reinterpret_cast(pCurrentBlock); - pCurrentBlock += sizeof(GeomCacheFile::SCompressedBlockHeader) + pBlockHeader->m_compressedSize; - totalUncompressedSize += pBlockHeader->m_uncompressedSize; - } - - uint32 totalSize = headersSize + totalUncompressedSize; - if (totalSize % 16 != 0) - { - CryFatalError("GetDecompressBufferSize mod 16 != 0"); - } - - return totalSize; - } - - bool DecompressBlock(const GeomCacheFile::EBlockCompressionFormat compressionFormat, char* const pDest, const char* const pSource) - { - FUNCTION_PROFILER_3DENGINE; - - const GeomCacheFile::SCompressedBlockHeader* const pBlockHeader = reinterpret_cast(pSource); - const char* const pBlockData = reinterpret_cast(pSource + sizeof(GeomCacheFile::SCompressedBlockHeader)); - - if (compressionFormat == GeomCacheFile::eBlockCompressionFormat_None) - { - assert(pBlockHeader->m_compressedSize == pBlockHeader->m_uncompressedSize); - memcpy(const_cast(pDest), pSource + sizeof(GeomCacheFile::SCompressedBlockHeader), pBlockHeader->m_uncompressedSize); - } - else if (compressionFormat == GeomCacheFile::eBlockCompressionFormat_Deflate) - { - IZLibInflateStream* pInflateStream = GetISystem()->GetIZLibDecompressor()->CreateInflateStream(); - - pInflateStream->SetOutputBuffer(const_cast(pDest), pBlockHeader->m_uncompressedSize); - pInflateStream->Input(pBlockData, pBlockHeader->m_compressedSize); - pInflateStream->EndInput(); - EZInflateState state = pInflateStream->GetState(); - assert(state == eZInfState_Finished); - pInflateStream->Release(); - - if (state == eZInfState_Error) - { - return false; - } - } - else if (compressionFormat == GeomCacheFile::eBlockCompressionFormat_LZ4HC) - { - ILZ4Decompressor* pDecompressor = GetISystem()->GetLZ4Decompressor(); - return pDecompressor->DecompressData(pBlockData, const_cast(pDest), pBlockHeader->m_uncompressedSize); - } - else if (compressionFormat == GeomCacheFile::eBlockCompressionFormat_ZSTD) - { - IZStdDecompressor* pDecompressor = GetISystem()->GetZStdDecompressor(); - return pDecompressor->DecompressData(pBlockData, pBlockHeader->m_compressedSize, const_cast(pDest), pBlockHeader->m_uncompressedSize); - } - else - { - return false; - } - - return true; - } - - bool DecompressBlocks(const GeomCacheFile::EBlockCompressionFormat compressionFormat, char* const pDest, - const char* const pSource, const uint blockOffset, const uint numBlocks, const uint numHandleFrames) - { - FUNCTION_PROFILER_3DENGINE; - - const char* pCurrentSource = pSource; - const uint32 headersSize = ((sizeof(SGeomCacheFrameHeader) * numHandleFrames) + 15) & ~15; - char* pCurrentDest = pDest + headersSize; - - for (uint i = 0; i < blockOffset; ++i) - { - const GeomCacheFile::SCompressedBlockHeader* const pBlockHeader = reinterpret_cast(pCurrentSource); - pCurrentSource += sizeof(GeomCacheFile::SCompressedBlockHeader) + pBlockHeader->m_compressedSize; - pCurrentDest += pBlockHeader->m_uncompressedSize; - } - - for (uint i = blockOffset; i < blockOffset + numBlocks; ++i) - { - const GeomCacheFile::SCompressedBlockHeader* const pBlockHeader = reinterpret_cast(pCurrentSource); - - if (!DecompressBlock(compressionFormat, pCurrentDest, pCurrentSource)) - { - return false; - } - - SGeomCacheFrameHeader* pHeader = reinterpret_cast(pDest + i * sizeof(SGeomCacheFrameHeader)); - pHeader->m_offset = static_cast(pCurrentDest - pDest); - pHeader->m_state = SGeomCacheFrameHeader::eFHS_Undecoded; - - pCurrentSource += sizeof(GeomCacheFile::SCompressedBlockHeader) + pBlockHeader->m_compressedSize; - pCurrentDest += pBlockHeader->m_uncompressedSize; - } - - return true; - } -} - -#endif diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.h b/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.h deleted file mode 100644 index cdbb2cb9f9..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheDecoder.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Decodes geom cache data - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHEDECODER_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHEDECODER_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheFileFormat.h" - -class CGeomCache; -struct SGeomCacheRenderMeshUpdateContext; -struct SGeomCacheStaticMeshData; - -struct SGeomCacheFrameHeader -{ - enum EFrameHeaderState - { - eFHS_Uninitialized = 0, - eFHS_Undecoded = 1, - eFHS_Decoded = 2 - }; - - EFrameHeaderState m_state; - uint32 m_offset; -}; - -namespace GeomCacheDecoder -{ - // Decodes an index frame - void DecodeIFrame(const CGeomCache* pGeomCache, char* pData); - - // Decodes a bi-directional predicted frame - void DecodeBFrame(const CGeomCache * pGeomCache, char* pData, char* pPrevFramesData[2], - char* pFloorIndexFrameData, char* pCeilIndexFrameData); - - bool PrepareFillMeshData(SGeomCacheRenderMeshUpdateContext& updateContext, const SGeomCacheStaticMeshData& staticMeshData, - const char*& pFloorFrameMeshData, const char*& pCeilFrameMeshData, size_t& offsetToNextMesh, float& lerpFactor); - - void FillMeshDataFromDecodedFrame(const bool bMotionBlur, SGeomCacheRenderMeshUpdateContext& updateContext, - const SGeomCacheStaticMeshData& staticMeshData, const char* pFloorFrameMeshData, - const char* pCeilFrameMeshData, float lerpFactor); - - // Gets total needed space for uncompressing successive blocks - uint32 GetDecompressBufferSize(const char* const pStartBlock, const uint numFrames); - - // Decompresses one block of compressed data with header for input - bool DecompressBlock(const GeomCacheFile::EBlockCompressionFormat compressionFormat, char* const pDest, const char* const pSource); - - // Decompresses blocks of compressed data with headers for input and output - bool DecompressBlocks(const GeomCacheFile::EBlockCompressionFormat compressionFormat, char* const pDest, - const char* const pSource, const uint blockOffset, const uint numBlocks, const uint numHandleFrames); - - Vec3 DecodePosition(const Vec3& aabbMin, const Vec3& aabbSize, const GeomCacheFile::Position& inPosition, const Vec3& convertFactor); - Vec2 DecodeTexcoord(const GeomCacheFile::Texcoords& inTexcoords, float uvMax); - Quat DecodeQTangent(const GeomCacheFile::QTangent& inQTangent); - - void TransformAndConvertToTangentAndBitangent(const Quat& rotation, const Quat& inQTangent, SPipTangents& outTangents); - void ConvertToTangentAndBitangent(const Quat& inQTangent, SPipTangents& outTangents); -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHEDECODER_H diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheManager.cpp b/Code/CryEngine/Cry3DEngine/GeomCacheManager.cpp deleted file mode 100644 index 6547e786fe..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheManager.cpp +++ /dev/null @@ -1,1793 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages geometry cache instances and streaming - - -#include "Cry3DEngine_precompiled.h" - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheManager.h" -#include "GeomCache.h" -#include "GeomCacheRenderNode.h" -#include "Cry_Color.h" - -namespace -{ - const uint kMinBufferSizeInMiB = 8; - const uint kMaxBufferSizeInMiB = 2048; -} - -CGeomCacheManager::CGeomCacheManager() - : m_pPoolBaseAddress(NULL) - , m_pPool(NULL) - , m_poolSize(0) - , m_lastRequestStream(0) - , m_numMissedFrames(0) - , m_numStreamAborts(0) - , m_numErrorAborts(0) - , m_numDecompressStreamAborts(0) - , m_numReadStreamAborts(0) - , m_numFailedAllocs(0) -{ - ChangeBufferSize(GetCVars()->e_GeomCacheBufferSize); - - ICVar* pGeomCacheBufferSizeCVar = gEnv->pConsole->GetCVar("e_GeomCacheBufferSize"); - if (pGeomCacheBufferSizeCVar) - { - pGeomCacheBufferSizeCVar->SetOnChangeCallback(&CGeomCacheManager::OnChangeBufferSize); - } - - // Connect for LegacyAssetEventBus::Handler - BusConnect(AZ_CRC("cax", 0x97e80f83)); -} - -CGeomCacheManager::~CGeomCacheManager() -{ - Reset(); - UnloadGeomCaches(); - - if (!gEnv->IsDedicated()) - { - m_pPool->Release(); - m_pPool = NULL; - - CryMemory::FreePages(m_pPoolBaseAddress, m_poolSize); - } - // Disconnect for LegacyAssetEventBus::Handler - BusDisconnect(); -} - -void CGeomCacheManager::Reset() -{ - const uint numStreams = m_streamInfos.size(); - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo* pStreamInfo = m_streamInfos[i]; - AbortStreamAndWait(*pStreamInfo); - delete pStreamInfo; - } - - stl::free_container(m_streamInfos); - - GetMeshManager().Reset(); -} - -void CGeomCacheManager::StopCacheStreamsAndWait(CGeomCache* pGeomCache) -{ - const uint numStreams = m_streamInfos.size(); - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo* pStreamInfo = m_streamInfos[i]; - if (pStreamInfo->m_pGeomCache == pGeomCache) - { - AbortStreamAndWait(*pStreamInfo); - } - } -} - -CGeomCache* CGeomCacheManager::FindGeomCacheByFilename(const char* filename) -{ - return stl::find_in_map(m_nameToGeomCacheMap, CONST_TEMP_STRING(filename), NULL); -} - -CGeomCache* CGeomCacheManager::LoadGeomCache(const char* szFileName) -{ - LOADING_TIME_PROFILE_SECTION; - - // Normalize file name - char sFilename[_MAX_PATH]; - - // Remap %level% alias if needed an unify filename - int nAliasNameLen = sizeof("%level%") - 1; - if (strncmp(szFileName, "%level%", nAliasNameLen) == 0) - { - cry_strcpy(sFilename, Get3DEngine()->GetLevelFilePath(szFileName + nAliasNameLen)); - } - else - { - cry_strcpy(sFilename, szFileName); - } - std::replace(sFilename, sFilename + strlen(sFilename), '\\', '/'); // To Unix Path - - // Try to find existing object for that file - CGeomCache* pGeomCache = stl::find_in_map(m_nameToGeomCacheMap, CONST_TEMP_STRING(sFilename), NULL); - if (pGeomCache) - { - return pGeomCache; - } - - // Load geom cache - pGeomCache = new CGeomCache(sFilename); - m_nameToGeomCacheMap[sFilename] = pGeomCache; - return pGeomCache; -} - -void CGeomCacheManager::UnloadGeomCaches() -{ - for (TGeomCacheMap::iterator iter = m_nameToGeomCacheMap.begin(); iter != m_nameToGeomCacheMap.end(); ++iter) - { - delete iter->second; - } - - stl::free_container(m_nameToGeomCacheMap); -} - -void CGeomCacheManager::DeleteGeomCache(CGeomCache* pGeomCache) -{ - const char* pFilename = pGeomCache->GetFilePath(); - m_nameToGeomCacheMap.erase(pFilename); - delete pGeomCache; -} - -void CGeomCacheManager::RegisterForStreaming(CGeomCacheRenderNode* pRenderNode) -{ - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - if (!pRenderNode) - { - return; - } - - for (uint i = 0; i < m_streamInfos.size(); ++i) - { - const SGeomCacheStreamInfo* pStreamInfo = m_streamInfos[i]; - if (pStreamInfo->m_pRenderNode == pRenderNode) - { - return; - } - } - - CGeomCache* pGeomCache = static_cast(pRenderNode->GetGeomCache()); - pGeomCache->IncreaseNumStreams(); - - const uint numFrames = pGeomCache->GetNumFrames(); - - SGeomCacheStreamInfo* pStreamInfo = new SGeomCacheStreamInfo(pRenderNode, pGeomCache, numFrames); - m_streamInfos.push_back(pStreamInfo); - - // If cache is too short we need to allocate double the amount of frame data. Otherwise we can't loop without aborts, - // because IssueDiskReadRequest prevents the same frame info from being used twice. - const uint preferredDiskRequestSize = (size_t)std::max(0, GetCVars()->e_GeomCachePreferredDiskRequestSize * 1024); - const uint64 compressedAnimationDataSize = pGeomCache->GetCompressedAnimationDataSize(); - - const float maxBufferAheadTime = std::max(1.0f, GetCVars()->e_GeomCacheMaxBufferAheadTime); - const float duration = pGeomCache->GetDuration(); - - const bool bNeedDoubleFrameData = (compressedAnimationDataSize < (preferredDiskRequestSize * 2)) || (duration < (maxBufferAheadTime * 2)); - - const uint numFrameData = bNeedDoubleFrameData ? (numFrames * 2) : numFrames; - pStreamInfo->m_frameData.resize(numFrameData); - ReinitializeStreamFrameData(*pStreamInfo, 0, numFrameData - 1); -} - -void CGeomCacheManager::OnFileChanged(AZStd::string assetPath) -{ - CGeomCache* geomCache = FindGeomCacheByFilename(assetPath.c_str()); - if (geomCache) - { - geomCache->Reload(); - } -} - -void CGeomCacheManager::OnChangeBufferSize(ICVar* pCVar) -{ - GetGeomCacheManager()->ChangeBufferSize(pCVar->GetIVal()); -} - -void CGeomCacheManager::ChangeBufferSize(const uint newSizeInMiB) -{ - const uint numStreams = m_streamInfos.size(); - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo* pStreamInfo = m_streamInfos[i]; - AbortStreamAndWait(*pStreamInfo); - } - - if (!gEnv->IsDedicated()) - { - SAFE_RELEASE(m_pPool); - if (m_pPoolBaseAddress) - { - CryMemory::FreePages(m_pPoolBaseAddress, m_poolSize); - } - - const int geomCacheBufferSize = clamp_tpl(newSizeInMiB, kMinBufferSizeInMiB, kMaxBufferSizeInMiB); - GetCVars()->e_GeomCacheBufferSize = geomCacheBufferSize; - - const uint kMiBtoBytesFactor = 1024 * 1024; - m_poolSize = geomCacheBufferSize * kMiBtoBytesFactor; - - m_pPoolBaseAddress = CryMemory::AllocPages(m_poolSize); - m_pPool = gEnv->pSystem->GetIMemoryManager()->CreateGeneralMemoryHeap(m_pPoolBaseAddress, m_poolSize, "GEOMCACHE_POOL"); - } -} - -void CGeomCacheManager::ReinitializeStreamFrameData(SGeomCacheStreamInfo& streamInfo, uint startFrame, uint endFrame) -{ - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - - const uint frameDataSize = streamInfo.m_frameData.size(); - startFrame = std::min(frameDataSize - 1, startFrame); - endFrame = std::min(frameDataSize - 1, endFrame); - - for (uint i = startFrame; i <= endFrame; ++i) - { - SGeomCacheStreamInfo::SFrameData& frameData = streamInfo.m_frameData[i]; - - frameData.m_bDecompressJobLaunched = false; - frameData.m_pDecompressHandle = NULL; - - const GeomCacheFile::EFrameType frameType = pGeomCache->GetFrameType(i); - - if (frameType == GeomCacheFile::eFrameType_IFrame) - { - frameData.m_decodeDependencyCounter = 1; - } - else if (frameType == GeomCacheFile::eFrameType_BFrame) - { - assert(i > 0); - - if (pGeomCache->GetFrameType(i - 1) == GeomCacheFile::eFrameType_IFrame) - { - frameData.m_decodeDependencyCounter = 3; - } - else - { - frameData.m_decodeDependencyCounter = 2; - } - } - } -} - -void CGeomCacheManager::UnRegisterForStreaming(CGeomCacheRenderNode* pRenderNode, bool bWaitForJobs) -{ - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - TStreamInfosIter iter = m_streamInfos.begin(); - while (iter != m_streamInfos.end()) - { - SGeomCacheStreamInfo* pStreamInfo = *iter; - if (pStreamInfo->m_pRenderNode == pRenderNode) - { - if (pStreamInfo->m_pNewestReadRequestHandle || pStreamInfo->m_pOldestDecompressHandle) - { - gEnv->pLog->LogWarning("Unregistering stream %s while still active", pStreamInfo->m_pRenderNode->GetName()); - } - - if (!bWaitForJobs) - { - AbortStream(*pStreamInfo); - } - else - { - AbortStreamAndWait(*pStreamInfo); - } - - m_streamInfosAbortList.push_back(pStreamInfo); - iter = m_streamInfos.erase(iter); - } - else - { - ++iter; - } - } - - RetireRemovedStreams(); -} - -void CGeomCacheManager::StreamingUpdate() -{ - FUNCTION_PROFILER_3DENGINE; - - const bool bCachesActive = GetCVars()->e_GeomCaches != 0; - - RetireRemovedStreams(); - - const uint numStreams = m_streamInfos.size(); - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo& streamInfo = *m_streamInfos[i]; - - { - FRAME_PROFILER("CGeomCacheManager::StreamingUpdate_WaitForLastFillJob", GetSystem(), PROFILE_3DENGINE); - streamInfo.m_fillRenderNodeJobExecutor.WaitForCompletion(); - } - - // Update wanted playback frame - CGeomCacheRenderNode* pRenderNode = streamInfo.m_pRenderNode; - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - streamInfo.m_wantedPlaybackTime = pRenderNode->GetPlaybackTime(); - streamInfo.m_wantedFloorFrame = pGeomCache->GetFloorFrameIndex(streamInfo.m_wantedPlaybackTime); - streamInfo.m_wantedCeilFrame = pGeomCache->GetCeilFrameIndex(streamInfo.m_wantedPlaybackTime); - streamInfo.m_bLooping = streamInfo.m_pRenderNode->IsLooping(); - - if (!streamInfo.m_bLooping) - { - const uint numFrames = streamInfo.m_numFrames; - streamInfo.m_wantedFloorFrame = std::min((uint)streamInfo.m_wantedFloorFrame, numFrames - 1); - streamInfo.m_wantedCeilFrame = std::min((uint)streamInfo.m_wantedCeilFrame, numFrames - 1); - } - - assert(streamInfo.m_wantedFloorFrame + 1 == streamInfo.m_wantedCeilFrame - || streamInfo.m_wantedFloorFrame == streamInfo.m_wantedCeilFrame); - - // Update bbox for this frame - pRenderNode->UpdateBBox(); - - // Abort stream and trash it if it's not valid anymore - ValidateStream(streamInfo); - - // Try to trash as many aborted handles as possible - RetireAbortedHandles(streamInfo); - - // Retire handles that are not needed anymore - RetireHandles(streamInfo); - } - - if (bCachesActive) - { - const CTimeValue currentFrameTime = GetTimer()->GetFrameStartTime(); - LaunchStreamingJobs(numStreams, currentFrameTime); - } - - // Start disk read requests alternating between geom cache render nodes until no more - // can be issued (buffers full, max read ahead time reached, no free request object) - bool bMoreRequests = true; - while (bMoreRequests && bCachesActive) - { - bMoreRequests = false; - uint nextRequestStream = m_lastRequestStream + 1; - - for (uint i = 0; i < numStreams; ++i) - { - const uint requestStream = (nextRequestStream + i) % numStreams; - - SGeomCacheStreamInfo& streamInfo = *m_streamInfos[i]; - const CGeomCacheRenderNode* pRenderNode = streamInfo.m_pRenderNode; - const bool bIsStreaming = pRenderNode->IsStreaming(); - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - const bool bPlaybackFromMemory = pGeomCache->PlaybackFromMemory(); - const float playbackFrame = streamInfo.m_wantedPlaybackTime; - const float displayedFrame = streamInfo.m_displayedFrameTime; - - if (!bPlaybackFromMemory && (bIsStreaming || (displayedFrame != playbackFrame))) - { - const bool bRequestIssued = IssueDiskReadRequest(streamInfo); - - if (bRequestIssued) - { - m_lastRequestStream = requestStream; - } - - bMoreRequests |= bRequestIssued; - } - } - } - -#ifndef _RELEASE - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo& streamInfo = *m_streamInfos[i]; - streamInfo.m_pRenderNode->DebugRender(); - } -#endif -} - -void CGeomCacheManager::LaunchStreamingJobs(const uint numStreams, const CTimeValue currentFrameTime) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - // Launch streaming jobs - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo* pStreamInfo = m_streamInfos[i]; - CGeomCacheRenderNode* pRenderNode = pStreamInfo->m_pRenderNode; - const CGeomCache* pGeomCache = pStreamInfo->m_pGeomCache; - - if (!pGeomCache) - { - continue; - } - - const bool bIsStreaming = pRenderNode->IsStreaming(); - const float playbackFrameTime = pStreamInfo->m_wantedPlaybackTime; - const float displayedFrameTime = pStreamInfo->m_displayedFrameTime; - - LaunchDecompressJobs(pStreamInfo, currentFrameTime); - - const bool bSameFrame = playbackFrameTime == displayedFrameTime; - if (!bSameFrame || pStreamInfo->m_sameFrameFillCount < 2) - { - pRenderNode->StartAsyncUpdate(); - // Legacy priority - High - pStreamInfo->m_fillRenderNodeJobExecutor.StartJob([this, pStreamInfo]() { this->FillRenderNodeAsync_JobEntry(pStreamInfo); }); - - } - } -} - -void CGeomCacheManager::RetireRemovedStreams() -{ - FUNCTION_PROFILER_3DENGINE; - - TStreamInfosIter iter = m_streamInfosAbortList.begin(); - - while (iter != m_streamInfosAbortList.end()) - { - SGeomCacheStreamInfo* pStreamInfo = *iter; - - pStreamInfo->m_fillRenderNodeJobExecutor.WaitForCompletion(); - RetireAbortedHandles(*pStreamInfo); - - if (pStreamInfo->m_fillRenderNodeJobExecutor.IsRunning() - || pStreamInfo->m_pReadAbortListHead || pStreamInfo->m_pDecompressAbortListHead) - { - ++iter; - } - else - { - // Nothing left running, we can finally delete the stream - CGeomCache* pGeomCache = pStreamInfo->m_pGeomCache; - pGeomCache->DecreaseNumStreams(); - - pStreamInfo->m_pRenderNode->ClearFillData(); - - delete pStreamInfo; - iter = m_streamInfosAbortList.erase(iter); - } - } - - for (TGeomCacheMap::iterator it = m_nameToGeomCacheMap.begin(); it != m_nameToGeomCacheMap.end(); ++it) - { - CGeomCache* pGeomCache = it->second; - if (pGeomCache->GetNumStreams() == 0) - { - pGeomCache->UnloadData(); - } - } -} - -void CGeomCacheManager::ValidateStream(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - const CGeomCacheRenderNode* pRenderNode = streamInfo.m_pRenderNode; - const bool bIsStreaming = pRenderNode->IsStreaming(); - const float wantedPlaybackTime = streamInfo.m_wantedPlaybackTime; - const float displayedFrameTime = streamInfo.m_displayedFrameTime; - - if (!pRenderNode->IsStreaming() && (displayedFrameTime == wantedPlaybackTime) && streamInfo.m_sameFrameFillCount >= 2) - { - AbortStream(streamInfo); - return; - } - - // Abort if there was an error in the stream. Also set the render node to not play back in this case. - if (streamInfo.m_pOldestReadRequestHandle && streamInfo.m_pOldestReadRequestHandle->m_error != 0) - { - ++m_numStreamAborts; - ++m_numErrorAborts; - gEnv->pLog->LogError("Error in cache stream %s", streamInfo.m_pRenderNode->GetName()); - AbortStream(streamInfo); - streamInfo.m_pRenderNode->StopStreaming(); - return; - } - - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - const float currentCacheStreamingTime = streamInfo.m_pRenderNode->GetStreamingTime(); - const uint wantedFloorFrame = pGeomCache->GetFloorFrameIndex(currentCacheStreamingTime); - - // Check if stream is invalid - bool bAbort = false; - - if (streamInfo.m_pOldestDecompressHandle) - { - if ((streamInfo.m_pOldestDecompressHandle->m_startFrame > wantedFloorFrame) - || (streamInfo.m_pNewestDecompressHandle->m_endFrame < wantedFloorFrame)) - { - gEnv->pLog->LogWarning("Aborting cache stream %s (decompress stream: [%u, %u], wanted frame: %u)", streamInfo.m_pRenderNode->GetName(), - streamInfo.m_pOldestDecompressHandle->m_startFrame, streamInfo.m_pNewestDecompressHandle->m_endFrame, wantedFloorFrame); - ++m_numDecompressStreamAborts; - bAbort = true; - } - } - else if (streamInfo.m_pOldestReadRequestHandle) - { - if (streamInfo.m_pOldestReadRequestHandle->m_startFrame > wantedFloorFrame) - { - gEnv->pLog->LogWarning("Aborting cache stream %s (read stream start: %u, wanted frame: %u)", streamInfo.m_pRenderNode->GetName(), - streamInfo.m_pOldestReadRequestHandle->m_startFrame, wantedFloorFrame); - ++m_numReadStreamAborts; - bAbort = true; - } - } - - if (bAbort) - { - ++m_numStreamAborts; - AbortStream(streamInfo); - } -} - -void CGeomCacheManager::AbortStream(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - streamInfo.m_bAbort = true; - - { - FRAME_PROFILER("CGeomCacheManager::AbortStream_LockFillRenderNode", GetSystem(), PROFILE_3DENGINE); - streamInfo.m_abortCS.Lock(); - } - - if (streamInfo.m_pNewestReadRequestHandle) - { - FRAME_PROFILER("CGeomCacheManager::AbortStream_AbortReads", GetSystem(), PROFILE_3DENGINE); - - assert(streamInfo.m_pOldestReadRequestHandle != NULL); - - // Abort read requests if possible - for (SGeomCacheReadRequestHandle* pCurrentReadRequestHandle = streamInfo.m_pOldestReadRequestHandle; - pCurrentReadRequestHandle; pCurrentReadRequestHandle = static_cast(pCurrentReadRequestHandle->m_pNext)) - { - if (pCurrentReadRequestHandle->m_pReadStream) - { - pCurrentReadRequestHandle->m_pReadStream->TryAbort(); - } - } - - // Put all handles in the read request list on the abort list - assert(streamInfo.m_pNewestReadRequestHandle->m_pNext == NULL); - streamInfo.m_pNewestReadRequestHandle->m_pNext = streamInfo.m_pReadAbortListHead; - streamInfo.m_pReadAbortListHead = streamInfo.m_pOldestReadRequestHandle; - - // Mark read request list as empty - streamInfo.m_pOldestReadRequestHandle = NULL; - streamInfo.m_pNewestReadRequestHandle = NULL; - } - - if (streamInfo.m_pOldestDecompressHandle) - { - FRAME_PROFILER("CGeomCacheManager::AbortStream_AbortDecompress", GetSystem(), PROFILE_3DENGINE); - - assert(streamInfo.m_pOldestDecompressHandle != NULL); - - // Put all handles in the decompress list on the abort list - assert(streamInfo.m_pNewestDecompressHandle->m_pNext == NULL); - streamInfo.m_pNewestDecompressHandle->m_pNext = streamInfo.m_pDecompressAbortListHead; - streamInfo.m_pDecompressAbortListHead = streamInfo.m_pOldestDecompressHandle; - - // Mark read decompress list as empty - streamInfo.m_pNewestDecompressHandle = NULL; - streamInfo.m_pOldestDecompressHandle = NULL; - } - - assert(streamInfo.m_pOldestDecompressHandle == NULL - && streamInfo.m_pNewestDecompressHandle == NULL); - - streamInfo.m_numFramesMissed = 0; - streamInfo.m_bAbort = false; - streamInfo.m_bLooping = false; - streamInfo.m_abortCS.Unlock(); -} - -void CGeomCacheManager::AbortStreamAndWait(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - AbortStream(streamInfo); - - streamInfo.m_fillRenderNodeJobExecutor.WaitForCompletion(); - - CryMutex dummyCS; - - // Wait for all read requests to finish - for (SGeomCacheReadRequestHandle* pCurrentAbortedHandle = streamInfo.m_pReadAbortListHead; - pCurrentAbortedHandle; pCurrentAbortedHandle = static_cast(pCurrentAbortedHandle->m_pNext)) - { - CryAutoLock lock(dummyCS); - while (pCurrentAbortedHandle->m_numJobReferences > 0) - { - pCurrentAbortedHandle->m_jobReferencesCV.Wait(dummyCS); - } - - if (pCurrentAbortedHandle->m_pReadStream) - { - pCurrentAbortedHandle->m_pReadStream->Wait(); - } - } - - for (SGeomCacheBufferHandle* pCurrentAbortedHandle = streamInfo.m_pDecompressAbortListHead; - pCurrentAbortedHandle; pCurrentAbortedHandle = pCurrentAbortedHandle->m_pNext) - { - CryAutoLock lock(dummyCS); - while (pCurrentAbortedHandle->m_numJobReferences > 0) - { - pCurrentAbortedHandle->m_jobReferencesCV.Wait(dummyCS); - } - } - - // And finally retire their handles - RetireAbortedHandles(streamInfo); - - assert(streamInfo.m_pReadAbortListHead == NULL); -} - -void CGeomCacheManager::RetireAbortedHandles(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - SGeomCacheReadRequestHandle* pNextReadRequestAbortHandle = NULL; - for (SGeomCacheReadRequestHandle* pCurrentAbortedHandle = streamInfo.m_pReadAbortListHead; - pCurrentAbortedHandle; pCurrentAbortedHandle = pNextReadRequestAbortHandle) - { - // If jobs are still running, wait till next frame - if (pCurrentAbortedHandle->m_numJobReferences > 0 || (pCurrentAbortedHandle->m_pReadStream && !pCurrentAbortedHandle->m_pReadStream->IsFinished())) - { - break; - } - - // Remove from abort list - pNextReadRequestAbortHandle = static_cast(pCurrentAbortedHandle->m_pNext); - streamInfo.m_pReadAbortListHead = pNextReadRequestAbortHandle; - - // And finally retire handle - RetireBufferHandle(pCurrentAbortedHandle); - } - - SGeomCacheBufferHandle* pNextDecompressAbortHandle = NULL; - for (SGeomCacheBufferHandle* pCurrentAbortedHandle = streamInfo.m_pDecompressAbortListHead; - pCurrentAbortedHandle; pCurrentAbortedHandle = pNextDecompressAbortHandle) - { - // If jobs are still running, wait till next frame - if (pCurrentAbortedHandle->m_numJobReferences > 0) - { - break; - } - - // Remove from abort list - pNextDecompressAbortHandle = pCurrentAbortedHandle->m_pNext; - streamInfo.m_pDecompressAbortListHead = pNextDecompressAbortHandle; - - // And finally retire handle - RetireDecompressHandle(streamInfo, pCurrentAbortedHandle); - } -} - -bool CGeomCacheManager::IssueDiskReadRequest(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - // Constants - const CGeomCacheRenderNode* pRenderNode = streamInfo.m_pRenderNode; - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - const bool bIsStreaming = pRenderNode->IsStreaming(); - - const float currentCacheStreamingTime = streamInfo.m_pRenderNode->GetStreamingTime(); - const uint wantedFloorFrame = pGeomCache->GetFloorFrameIndex(currentCacheStreamingTime); - const uint wantedCeilFrame = pGeomCache->GetCeilFrameIndex(currentCacheStreamingTime); - const float minBufferAheadTime = std::max(0.1f, GetCVars()->e_GeomCacheMinBufferAheadTime); - const float maxBufferAheadTime = std::max(1.0f, GetCVars()->e_GeomCacheMaxBufferAheadTime); - const float cacheMinBufferAhead = currentCacheStreamingTime + minBufferAheadTime; - const float cacheMaxBufferAhead = currentCacheStreamingTime + maxBufferAheadTime; - - const bool bLooping = streamInfo.m_bLooping; - const uint numFrames = streamInfo.m_numFrames; - - const uint preferredDiskRequestSize = (size_t)std::max(0, GetCVars()->e_GeomCachePreferredDiskRequestSize * 1024); - - // Compute frame range that we want to read from disk - uint frameRangeBegin = pGeomCache->GetPrevIFrame(wantedFloorFrame); - uint frameRangeEnd = pGeomCache->GetNextIFrame(bIsStreaming ? pGeomCache->GetCeilFrameIndex(cacheMaxBufferAhead) : wantedFloorFrame); - - // Avoid reading an entire block if we are not streaming and time is precisely at an index frame. - // This primarily helps when streaming in the first frame after a render node is created. - if (!bIsStreaming && (wantedFloorFrame == wantedCeilFrame) && - pGeomCache->GetFrameType(wantedFloorFrame) == GeomCacheFile::eFrameType_IFrame) - { - frameRangeBegin = wantedFloorFrame; - frameRangeEnd = frameRangeBegin; - } - - // Make sure not to re-request frames that are already in the decode buffer - if (streamInfo.m_pNewestDecompressHandle) - { - uint decodedFramesEnd = streamInfo.m_pNewestDecompressHandle->m_endFrame; - frameRangeBegin = std::max(decodedFramesEnd + 1, frameRangeBegin); - } - - // Read request params and handle to be filled - StreamReadParams params; - SGeomCacheReadRequestHandle* pRequestHandle; - - { - assert(!streamInfo.m_pOldestReadRequestHandle || streamInfo.m_pNewestReadRequestHandle); - if (streamInfo.m_pNewestReadRequestHandle) - { - uint streamEndFrame = streamInfo.m_pNewestReadRequestHandle->m_endFrame; - - // Check if we already requested up to frameRangeEnd - if (streamInfo.m_pNewestReadRequestHandle->m_endFrame >= frameRangeEnd) - { - return false; - } - - frameRangeBegin = streamEndFrame + 1; - } - - const float frameRangeBeginTime = pGeomCache->GetFrameTime(frameRangeBegin); - if (frameRangeBeginTime > cacheMinBufferAhead) - { - return false; - } - - if (!bLooping && frameRangeEnd >= (numFrames - 1)) - { - frameRangeEnd = numFrames - 1; - } - - if (frameRangeBegin > frameRangeEnd) - { - return false; - } - - if ((frameRangeEnd - frameRangeBegin + 1) > numFrames) - { - frameRangeEnd = frameRangeBegin + numFrames - 1; - } - - pGeomCache->ValidateReadRange(frameRangeBegin, frameRangeEnd); - - // Now that we have a final range of unread frames, make a read request - uint requestSize = 0; - for (uint currentFrame = frameRangeBegin; currentFrame <= frameRangeEnd; ++currentFrame) - { - requestSize += pGeomCache->GetFrameSize(currentFrame); - - // Stop if size has reached preferred request size and current frame is an index frame - if (requestSize >= preferredDiskRequestSize && pGeomCache->GetFrameType(currentFrame) == GeomCacheFile::eFrameType_IFrame && frameRangeBegin != currentFrame) - { - frameRangeEnd = currentFrame; - break; - } - } - - assert(requestSize > 0); - - // Allocate new request handle & buffer space - pRequestHandle = NewReadRequestHandle(requestSize, streamInfo); - if (!pRequestHandle) - { - return false; - } - - // Init handle - pRequestHandle->m_startFrame = frameRangeBegin; - pRequestHandle->m_endFrame = frameRangeEnd; - - // Add request handle to stream linked list - if (streamInfo.m_pNewestReadRequestHandle) - { - streamInfo.m_pNewestReadRequestHandle->m_pNext = pRequestHandle; - streamInfo.m_pNewestReadRequestHandle = pRequestHandle; - } - else - { - streamInfo.m_pOldestReadRequestHandle = pRequestHandle; - streamInfo.m_pNewestReadRequestHandle = pRequestHandle; - } - - const float timeLeft = std::max(pGeomCache->GetFrameTime(frameRangeBegin) - currentCacheStreamingTime - - static_cast(GetCVars()->e_GeomCacheDecodeAheadTime), 0.0f); - - // Fill read request params - params.nOffset = static_cast(pGeomCache->GetFrameOffset(frameRangeBegin)); - params.nSize = requestSize; - params.pBuffer = pRequestHandle->m_pBuffer; - params.ePriority = estpAboveNormal; - params.nLoadTime = static_cast(timeLeft * 1000); - params.nPerceptualImportance = 255; - params.nFlags = IStreamEngine::FLAGS_NO_SYNC_CALLBACK; - } - - // Issue request - CryInterlockedIncrement(&pRequestHandle->m_numJobReferences); - pRequestHandle->m_pReadStream = GetSystem()->GetStreamEngine()->StartRead( - eStreamTaskTypeGeomCache, pGeomCache->GetFilePath(), pRequestHandle, ¶ms); - - // This can happen if streaming system is already shutting down. There will be no callback in this case, so decrement m_numJobReferences. - if (pRequestHandle->m_pReadStream == NULL) - { - if (CryInterlockedDecrement(&pRequestHandle->m_numJobReferences) == 0) - { - pRequestHandle->m_jobReferencesCV.Notify(); - } - } - - return true; -} - -void CGeomCacheManager::LaunchDecompressJobs(SGeomCacheStreamInfo* pStreamInfo, const CTimeValue currentFrameTime) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - const CGeomCache* pGeomCache = pStreamInfo->m_pGeomCache; - const GeomCacheFile::EBlockCompressionFormat blockCompressionFormat = pGeomCache->GetBlockCompressionFormat(); - const float currentCacheStreamingTime = pStreamInfo->m_pRenderNode->GetStreamingTime(); - const uint wantedFloorFrame = pGeomCache->GetFloorFrameIndex(currentCacheStreamingTime); - const uint numStreamFrames = pStreamInfo->m_numFrames; - const uint frameDataSize = pStreamInfo->m_frameData.size(); - - // Need to check if there are still jobs running for the same render node on the stream abort list - for (TStreamInfosIter iter = m_streamInfosAbortList.begin(); iter != m_streamInfosAbortList.end(); ++iter) - { - SGeomCacheStreamInfo* pCurrentStreamInfo = *iter; - if (pStreamInfo->m_pRenderNode == pCurrentStreamInfo->m_pRenderNode) - { - return; - } - } - - // Wait until abort list has been processed before spawning new jobs - if (pStreamInfo->m_pDecompressAbortListHead || pStreamInfo->m_pReadAbortListHead) - { - return; - } - - for (SGeomCacheReadRequestHandle* pReadRequestHandle = pStreamInfo->m_pOldestReadRequestHandle; pReadRequestHandle; - pReadRequestHandle = static_cast(pReadRequestHandle->m_pNext)) - { - if (pReadRequestHandle->m_frameTime == currentFrameTime) - { - // Don't decode frames that were read in the same render frame - return; - } - - if (pStreamInfo->m_bAbort) - { - return; - } - - if (pReadRequestHandle->m_error) - { - return; - } - - if (pReadRequestHandle->m_state != SGeomCacheReadRequestHandle::eRRHS_FinishedRead) - { - return; - } - - // Stop decoding after e_GeomCacheDecodeAheadTime - const float blockDeltaFromPlaybackTime = (pGeomCache->GetFrameTime(pReadRequestHandle->m_startFrame) - currentCacheStreamingTime); - const float decodeAheadTime = GetCVars()->e_GeomCacheDecodeAheadTime; - if (blockDeltaFromPlaybackTime > decodeAheadTime) - { - return; - } - - const uint startFrame = pReadRequestHandle->m_startFrame; - const uint endFrame = pReadRequestHandle->m_endFrame; - - // Need to check if stream is already referencing same frames when looping - if (pStreamInfo->m_pOldestDecompressHandle && pStreamInfo->m_bLooping) - { - const uint checkRangeStart = pStreamInfo->m_pOldestDecompressHandle->m_startFrame; - const uint checkRangeEnd = pStreamInfo->m_pNewestDecompressHandle->m_endFrame; - - const uint startRangeMod = checkRangeStart % frameDataSize; - const uint endRangeMod = checkRangeEnd % frameDataSize; - const uint startFrameMod = startFrame % frameDataSize; - // Check range must be extended to next index frame because retiring of stream begin could otherwise overwrite frame data - const uint endFrameMod = pGeomCache->GetNextIFrame(endFrame) % frameDataSize; - - const bool bRangeWraps = endRangeMod < startRangeMod; - const bool bFramesWrap = endFrameMod < startFrameMod; - - // check all four different cases for range overlapping - if ((bRangeWraps && bFramesWrap) - || (bRangeWraps && !bFramesWrap && (startFrameMod <= endRangeMod || endFrameMod >= startRangeMod)) - || (!bRangeWraps && bFramesWrap && (startRangeMod <= endFrameMod || endRangeMod >= startFrameMod)) - || (!bRangeWraps && !bFramesWrap && (startFrameMod <= endRangeMod && startRangeMod <= endFrameMod))) - { - return; - } - } - - // Determine size for decompression buffer - const uint numFrames = (endFrame - startFrame) + 1; - const uint32 decompressBlockSize = GeomCacheDecoder::GetDecompressBufferSize(pReadRequestHandle->m_pBuffer, numFrames); - - SGeomCacheBufferHandle* pNewDecompressBufferHandle = NewBufferHandle(decompressBlockSize, *pStreamInfo); - if (!pNewDecompressBufferHandle) - { - // Could not allocate space for decompression - return; - } - - // Zero frame headers - memset(pNewDecompressBufferHandle->m_pBuffer, 0, sizeof(SGeomCacheFrameHeader) * numFrames); - - pReadRequestHandle->m_state = SGeomCacheReadRequestHandle::eRRHS_Decompressing; - pNewDecompressBufferHandle->m_startFrame = startFrame; - pNewDecompressBufferHandle->m_endFrame = endFrame; - - for (uint i = startFrame; i <= endFrame; ++i) - { - const uint frameIndex = i % frameDataSize; - assert(!pStreamInfo->m_frameData[frameIndex].m_pDecompressHandle); - pStreamInfo->m_frameData[frameIndex].m_pDecompressHandle = pNewDecompressBufferHandle; - } - - // Add to decompress request handle linked list - { - assert(!pStreamInfo->m_pOldestDecompressHandle || pStreamInfo->m_pNewestDecompressHandle); - - // Add request handle to stream linked list - if (pStreamInfo->m_pNewestDecompressHandle) - { - pStreamInfo->m_pNewestDecompressHandle->m_pNext = pNewDecompressBufferHandle; - pStreamInfo->m_pNewestDecompressHandle = pNewDecompressBufferHandle; - } - else - { - pStreamInfo->m_pOldestDecompressHandle = pNewDecompressBufferHandle; - pStreamInfo->m_pNewestDecompressHandle = pNewDecompressBufferHandle; - } - } - - for (uint i = 0; i < numFrames; ++i) - { - const uint frameIndex = startFrame + i; - - // For b frames we need to make sure that jobs for previous frames were launched. Otherwise m_numJobReferences will - // never reach zero, because the frame decode job has a dependency job that was never launched. - if (pGeomCache->GetFrameType(frameIndex) == GeomCacheFile::eFrameType_IFrame - || pStreamInfo->m_frameData[(frameIndex - 1) % frameDataSize].m_bDecompressJobLaunched) - { - CryInterlockedIncrement(&pReadRequestHandle->m_numJobReferences); - CryInterlockedIncrement(&pNewDecompressBufferHandle->m_numJobReferences); - CryInterlockedIncrement(&pNewDecompressBufferHandle->m_numJobReferences); - - pStreamInfo->m_frameData[frameIndex % frameDataSize].m_bDecompressJobLaunched = true; - // Legacy priority - stream - AZ::Job* job = AZ::CreateJobFunction([this, pStreamInfo, i, pNewDecompressBufferHandle, pReadRequestHandle]() { this->DecompressFrame_JobEntry(pStreamInfo, i, pNewDecompressBufferHandle, pReadRequestHandle); }, true, nullptr); - job->Start(); - - } - } - } -} - -void CGeomCacheManager::DecompressFrame_JobEntry(SGeomCacheStreamInfo* pStreamInfo, const uint blockIndex, - SGeomCacheBufferHandle* pDecompressHandle, SGeomCacheReadRequestHandle* pReadRequestHandle) -{ - FUNCTION_PROFILER_3DENGINE; - - const CGeomCache* pGeomCache = pStreamInfo->m_pGeomCache; - const uint frameIndex = pDecompressHandle->m_startFrame + blockIndex; - - if (!pStreamInfo->m_bAbort && !pStreamInfo->m_pDecompressAbortListHead) - { - const GeomCacheFile::EBlockCompressionFormat blockCompressionFormat = pGeomCache->GetBlockCompressionFormat(); - const uint numFrames = pReadRequestHandle->m_endFrame - pReadRequestHandle->m_startFrame + 1; - - SGeomCacheFrameHeader* pHeader = GetFrameDecompressHeader(pStreamInfo, frameIndex); - if (!pHeader || pHeader->m_state != SGeomCacheFrameHeader::eFHS_Uninitialized) - { - CryFatalError("Trying to access uninitialized data while decoding an index frame"); - } - - if (!GeomCacheDecoder::DecompressBlocks(blockCompressionFormat, pDecompressHandle->m_pBuffer, - pReadRequestHandle->m_pBuffer, blockIndex, 1, numFrames)) - { - // Decompress block size failed: Flag error - pReadRequestHandle->m_error = 1; - } - } - - if (CryInterlockedDecrement(&pReadRequestHandle->m_numJobReferences) == 0) - { - pReadRequestHandle->m_state = SGeomCacheReadRequestHandle::eRRHS_Done; - pReadRequestHandle->m_jobReferencesCV.Notify(); - } - - if (CryInterlockedDecrement(&pDecompressHandle->m_numJobReferences) == 0) - { - pDecompressHandle->m_jobReferencesCV.Notify(); - } - - const int newDependencyCounter = CryInterlockedDecrement(GetDependencyCounter(pStreamInfo, frameIndex)); - - if (newDependencyCounter < 0 || newDependencyCounter > 2) - { - CryFatalError("Invalid dependency counter"); - } - else if (newDependencyCounter == 0) - { - SDecodeFrameJobData jobData; - jobData.m_frameIndex = frameIndex; - jobData.m_pGeomCache = pGeomCache; - jobData.m_pStreamInfo = pStreamInfo; - LaunchDecodeJob(jobData); - } -} - -void CGeomCacheManager::LaunchDecodeJob(SDecodeFrameJobData jobData) -{ - const GeomCacheFile::EFrameType frameType = jobData.m_pGeomCache->GetFrameType(jobData.m_frameIndex); - - switch (frameType) - { - case GeomCacheFile::eFrameType_IFrame: - { - // Legacy priority - stream - AZ::Job* job = AZ::CreateJobFunction([this, jobData]() { this->DecodeIFrame_JobEntry(jobData); }, true); - job->Start(); - break; - } - case GeomCacheFile::eFrameType_BFrame: - { - // Legacy priority - stream - AZ::Job* job = AZ::CreateJobFunction([this, jobData]() { this->DecodeBFrame_JobEntry(jobData); }, true); - job->Start(); - break; - } - } -} - -void CGeomCacheManager::DecodeIFrame_JobEntry(SDecodeFrameJobData jobData) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!jobData.m_pStreamInfo->m_bAbort && !jobData.m_pStreamInfo->m_pDecompressAbortListHead) - { - char* pFrameData = GetFrameDecompressData(jobData.m_pStreamInfo, jobData.m_frameIndex); - GeomCacheDecoder::DecodeIFrame(jobData.m_pGeomCache, pFrameData); - - SGeomCacheFrameHeader* pHeader = GetFrameDecompressHeader(jobData.m_pStreamInfo, jobData.m_frameIndex); - - if (pHeader->m_state != SGeomCacheFrameHeader::eFHS_Undecoded) - { - CryFatalError("Trying to access uninitialized data while decoding an index frame"); - } - - pHeader->m_state = SGeomCacheFrameHeader::eFHS_Decoded; - } - - SGeomCacheBufferHandle* pHandle = GetFrameDecompressHandle(jobData.m_pStreamInfo, jobData.m_frameIndex); - if (CryInterlockedDecrement(&pHandle->m_numJobReferences) == 0) - { - pHandle->m_jobReferencesCV.Notify(); - } - - // Decrement dependency counter of first b frame after previous index frame and launch job if ready - const uint prevIFrame = jobData.m_pGeomCache->GetPrevIFrame(jobData.m_frameIndex); - if (prevIFrame < jobData.m_frameIndex) - { - const uint bFrameIndex = prevIFrame + 1; - if (jobData.m_pGeomCache->GetFrameType(bFrameIndex) == GeomCacheFile::eFrameType_BFrame) - { - const int newDependencyCounter = CryInterlockedDecrement(GetDependencyCounter(jobData.m_pStreamInfo, bFrameIndex)); - - if (newDependencyCounter < 0 || newDependencyCounter > 2) - { - CryFatalError("Invalid dependency counter"); - } - else if (newDependencyCounter == 0) - { - SDecodeFrameJobData bFrameJobState = jobData; - bFrameJobState.m_frameIndex = bFrameIndex; - LaunchDecodeJob(bFrameJobState); - } - } - } - - // Decrement dependency counter of b frame right after index frame and launch job if ready - const uint numFrames = jobData.m_pStreamInfo->m_numFrames; - if ((jobData.m_frameIndex % numFrames) + 1 < numFrames) - { - const uint bFrameIndex = jobData.m_frameIndex + 1; - if (jobData.m_pGeomCache->GetFrameType(bFrameIndex) == GeomCacheFile::eFrameType_BFrame) - { - const int newDependencyCounter = CryInterlockedDecrement(GetDependencyCounter(jobData.m_pStreamInfo, bFrameIndex)); - - if (newDependencyCounter < 0 || newDependencyCounter > 2) - { - CryFatalError("Invalid dependency counter"); - } - else if (newDependencyCounter == 0) - { - SDecodeFrameJobData bFrameJobState = jobData; - bFrameJobState.m_frameIndex = bFrameIndex; - LaunchDecodeJob(bFrameJobState); - } - } - } -} - -void CGeomCacheManager::DecodeBFrame_JobEntry(SDecodeFrameJobData jobData) -{ - FUNCTION_PROFILER_3DENGINE; - - const uint prevIFrame = jobData.m_pGeomCache->GetPrevIFrame(jobData.m_frameIndex); - const uint nextIFrame = jobData.m_pGeomCache->GetNextIFrame(jobData.m_frameIndex); - - if (!jobData.m_pStreamInfo->m_bAbort && !jobData.m_pStreamInfo->m_pDecompressAbortListHead) - { - char* pFrameData = GetFrameDecompressData(jobData.m_pStreamInfo, jobData.m_frameIndex); - - // For frames that have 0 influence for motion the predictor will still read data - // from the prev frame pointers, so just set it to the current frame's data. - char* pPrevFramesData[2] = { pFrameData, pFrameData }; - if (jobData.m_pGeomCache->NeedsPrevFrames(jobData.m_frameIndex)) - { - pPrevFramesData[0] = GetFrameDecompressData(jobData.m_pStreamInfo, jobData.m_frameIndex - 2); - pPrevFramesData[1] = GetFrameDecompressData(jobData.m_pStreamInfo, jobData.m_frameIndex - 1); - } - - SGeomCacheFrameHeader* pPrevIFrameHeader = GetFrameDecompressHeader(jobData.m_pStreamInfo, prevIFrame); - SGeomCacheFrameHeader* pNextIFrameHeader = GetFrameDecompressHeader(jobData.m_pStreamInfo, nextIFrame); - - if (pPrevIFrameHeader->m_state != SGeomCacheFrameHeader::eFHS_Decoded - || pNextIFrameHeader->m_state != SGeomCacheFrameHeader::eFHS_Decoded) - { - CryFatalError("Trying to access invalid data while decoding a b frame"); - } - - char* pFloorIndexFrameData = GetFrameDecompressData(jobData.m_pStreamInfo, prevIFrame); - char* pCeilIndexFrameData = GetFrameDecompressData(jobData.m_pStreamInfo, nextIFrame); - - GeomCacheDecoder::DecodeBFrame(jobData.m_pGeomCache, pFrameData, pPrevFramesData, pFloorIndexFrameData, pCeilIndexFrameData); - - SGeomCacheFrameHeader* pHeader = GetFrameDecompressHeader(jobData.m_pStreamInfo, jobData.m_frameIndex); - - if (pHeader->m_state != SGeomCacheFrameHeader::eFHS_Undecoded) - { - CryFatalError("Trying to access invalid data while decoding a b frame"); - } - - pHeader->m_state = SGeomCacheFrameHeader::eFHS_Decoded; - } - - SGeomCacheBufferHandle* pHandle = GetFrameDecompressHandle(jobData.m_pStreamInfo, jobData.m_frameIndex); - if (CryInterlockedDecrement(&pHandle->m_numJobReferences) == 0) - { - pHandle->m_jobReferencesCV.Notify(); - } - - // Decrement dependency counter of b frame right after frame and launch job if ready - const uint numFrames = jobData.m_pStreamInfo->m_numFrames; - if ((jobData.m_frameIndex % numFrames) + 1 < numFrames) - { - const uint bFrameIndex = jobData.m_frameIndex + 1; - if (jobData.m_pGeomCache->GetFrameType(bFrameIndex) == GeomCacheFile::eFrameType_BFrame) - { - const int newDependencyCounter = CryInterlockedDecrement(GetDependencyCounter(jobData.m_pStreamInfo, bFrameIndex)); - - if (newDependencyCounter < 0 || newDependencyCounter > 2) - { - CryFatalError("Invalid dependency counter"); - } - else if (newDependencyCounter == 0) - { - SDecodeFrameJobData bFrameJobState = jobData; - bFrameJobState.m_frameIndex = bFrameIndex; - LaunchDecodeJob(bFrameJobState); - } - } - } -} - -void CGeomCacheManager::FillRenderNodeAsync_JobEntry(SGeomCacheStreamInfo* pStreamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // Prevent the stream from aborting while filling the render buffer - CryAutoLock abortLock(pStreamInfo->m_abortCS); - - CGeomCacheRenderNode* pRenderNode = pStreamInfo->m_pRenderNode; - const CGeomCache* pGeomCache = pStreamInfo->m_pGeomCache; - - if (pStreamInfo->m_bAbort || pStreamInfo->m_pDecompressAbortListHead) - { - // End job if abort flag was raised - pRenderNode->SkipFrameFill(); - return; - } - - const uint floorPlaybackFrame = pStreamInfo->m_wantedFloorFrame; - const uint ceilPlaybackFrame = pStreamInfo->m_wantedCeilFrame; - bool bFrameFilled = false; - - const char* pFloorFrameData = NULL; - const char* pCeilFrameData = NULL; - - if (!pGeomCache->PlaybackFromMemory()) - { - SGeomCacheFrameHeader* pFloorHeader = GetFrameDecompressHeader(pStreamInfo, floorPlaybackFrame); - SGeomCacheFrameHeader* pCeilHeader = GetFrameDecompressHeader(pStreamInfo, ceilPlaybackFrame); - - if (pFloorHeader && pFloorHeader->m_state == SGeomCacheFrameHeader::eFHS_Decoded && pCeilHeader && pCeilHeader->m_state == SGeomCacheFrameHeader::eFHS_Decoded) - { - pFloorFrameData = GetFrameDecompressData(pStreamInfo, floorPlaybackFrame); - pCeilFrameData = GetFrameDecompressData(pStreamInfo, ceilPlaybackFrame); - } - } - else - { - pFloorFrameData = pGeomCache->GetFrameData(floorPlaybackFrame % pGeomCache->GetNumFrames()); - pCeilFrameData = pGeomCache->GetFrameData(ceilPlaybackFrame % pGeomCache->GetNumFrames()); - } - - if (pFloorFrameData && pCeilFrameData) - { - const float floorFrameTime = pGeomCache->GetFrameTime(floorPlaybackFrame); - const float ceilFrameTime = pGeomCache->GetFrameTime(ceilPlaybackFrame); - const float wantedPlaybackTime = pStreamInfo->m_wantedPlaybackTime; - - assert(wantedPlaybackTime >= floorFrameTime && wantedPlaybackTime <= ceilFrameTime); - - float lerpFactor = 0.0f; - if (ceilFrameTime != floorFrameTime) - { - lerpFactor = (wantedPlaybackTime - floorFrameTime) / (ceilFrameTime - floorFrameTime); - } - - assert(lerpFactor >= 0.0f && lerpFactor <= 1.0f); - - // m_displayedFrameTime == -1.0f means uninitialized cache. Treat as same frame, because we only want to fill twice on load. - const bool bSameFrame = (pStreamInfo->m_displayedFrameTime == pStreamInfo->m_wantedPlaybackTime) || (pStreamInfo->m_displayedFrameTime == -1.0f); - - if (bSameFrame) - { - CryInterlockedIncrement(&pStreamInfo->m_sameFrameFillCount); - } - else - { - pStreamInfo->m_sameFrameFillCount = 0; - } - - if (!pRenderNode->FillFrameAsync(pFloorFrameData, pCeilFrameData, lerpFactor)) - { - pRenderNode->SkipFrameFill(); - } - - pStreamInfo->m_displayedFrameTime = pStreamInfo->m_wantedPlaybackTime; - bFrameFilled = true; - } - else - { - pRenderNode->SkipFrameFill(); - } - - if (!bFrameFilled && pRenderNode->IsStreaming()) - { - // If this happens, then we don't have the necessary data in the decompression - // buffer and the geom cache render node wasn't updated - ++pStreamInfo->m_numFramesMissed; - ++m_numMissedFrames; - } -} - -template -TBufferHandleType* CGeomCacheManager::NewBufferHandle(const uint32 size, SGeomCacheStreamInfo& streamInfo) -{ - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - CryFatalError("CGeomCacheManager::NewBufferHandle must be called from main thread"); - } - - char* pBlock = NULL; - - size_t pointerSize = (sizeof(SGeomCacheBufferHandle*) + 15) & ~15; - - if (!gEnv->IsDedicated()) - { - // Try to allocate requested size in the buffer, otherwise return NULL - { - FRAME_PROFILER("CGeomCacheManager::NewBufferHandle_Malloc", GetSystem(), PROFILE_3DENGINE); - pBlock = reinterpret_cast(m_pPool->Memalign(16, pointerSize + size, "geom cache block")); - } - } - - if (!pBlock) - { - ++m_numFailedAllocs; - return NULL; - } - - // Remove from free list - TBufferHandleType* pNewRequest = new TBufferHandleType(); - - // Initialize and return request handle - *alias_cast(pBlock) = pNewRequest; - pNewRequest->m_pBuffer = pBlock + pointerSize; - pNewRequest->m_bufferSize = size; - pNewRequest->m_frameTime = GetTimer()->GetFrameStartTime(); - pNewRequest->m_pStream = &streamInfo; - - return pNewRequest; -} - -SGeomCacheReadRequestHandle* CGeomCacheManager::NewReadRequestHandle(const uint32 size, SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - SGeomCacheBufferHandle* pNewHandle = NewBufferHandle(size, streamInfo); - SGeomCacheReadRequestHandle* pReadRequestHandle = static_cast(pNewHandle); - - if (pReadRequestHandle) - { - pReadRequestHandle->m_state = SGeomCacheReadRequestHandle::eRRHS_Reading; - pReadRequestHandle->m_error = 0L; - pReadRequestHandle->m_pReadStream = NULL; - } - - return pReadRequestHandle; -} - -void CGeomCacheManager::RetireHandles(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - const CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - const float currentCacheStreamingTime = streamInfo.m_pRenderNode->GetStreamingTime(); - const uint wantedFloorFrame = pGeomCache->GetFloorFrameIndex(currentCacheStreamingTime); - - SGeomCacheBufferHandle* pNextReadRequestHandle = streamInfo.m_pOldestReadRequestHandle; - while (pNextReadRequestHandle) - { - SGeomCacheReadRequestHandle* pCurrentReadRequestHandle = static_cast(pNextReadRequestHandle); - pNextReadRequestHandle = pCurrentReadRequestHandle->m_pNext; - - const uint handleEndFrame = pCurrentReadRequestHandle->m_endFrame; - - if (pCurrentReadRequestHandle->m_numJobReferences == 0 && - ((handleEndFrame + 2) < wantedFloorFrame || pCurrentReadRequestHandle->m_state == SGeomCacheReadRequestHandle::eRRHS_Done)) - { - RetireOldestReadRequestHandle(streamInfo); - } - else - { - break; - } - } - - SGeomCacheBufferHandle* pNextDecompressHandle = streamInfo.m_pOldestDecompressHandle; - while (pNextDecompressHandle) - { - SGeomCacheBufferHandle* pCurrentDecompressHandle = pNextDecompressHandle; - pNextDecompressHandle = pCurrentDecompressHandle->m_pNext; - - const uint handleEndFrame = pCurrentDecompressHandle->m_endFrame; - - // We also wait for the jobs of the next frame because of b frame -> index frame back references - if (((handleEndFrame + 2) < wantedFloorFrame) && (pCurrentDecompressHandle->m_numJobReferences == 0) - && !(pCurrentDecompressHandle->m_pNext && pCurrentDecompressHandle->m_pNext->m_numJobReferences > 0)) - { - RetireOldestDecompressHandle(streamInfo); - } - else - { - break; - } - } -} - -void CGeomCacheManager::RetireOldestReadRequestHandle(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - SGeomCacheReadRequestHandle* pOldestHandle; - - pOldestHandle = streamInfo.m_pOldestReadRequestHandle; - - if (pOldestHandle == streamInfo.m_pNewestReadRequestHandle) - { - assert(pOldestHandle->m_pNext == NULL); - streamInfo.m_pOldestReadRequestHandle = NULL; - streamInfo.m_pNewestReadRequestHandle = NULL; - } - else - { - streamInfo.m_pOldestReadRequestHandle = static_cast(pOldestHandle->m_pNext); - } - - assert(pOldestHandle); - if (pOldestHandle) - { - if (pOldestHandle->m_numJobReferences > 0) - { - CryFatalError("Trying to retire handle with non zero job count"); - } - - RetireBufferHandle(pOldestHandle); - } -} - -void CGeomCacheManager::RetireOldestDecompressHandle(SGeomCacheStreamInfo& streamInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - SGeomCacheBufferHandle* pOldestHandle = NULL; - - // Unlink from stream linked list - { - pOldestHandle = streamInfo.m_pOldestDecompressHandle; - - assert(pOldestHandle); - if (!pOldestHandle) - { - return; - } - - if (pOldestHandle == streamInfo.m_pNewestDecompressHandle) - { - assert(pOldestHandle->m_pNext == NULL); - streamInfo.m_pOldestDecompressHandle = NULL; - streamInfo.m_pNewestDecompressHandle = NULL; - } - else - { - streamInfo.m_pOldestDecompressHandle = pOldestHandle->m_pNext; - } - } - - if (pOldestHandle) - { - RetireDecompressHandle(streamInfo, pOldestHandle); - } -} - -void CGeomCacheManager::RetireDecompressHandle(SGeomCacheStreamInfo& streamInfo, SGeomCacheBufferHandle* pHandle) -{ - CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - - const uint frameDataSize = streamInfo.m_frameData.size(); - uint reinitializeStart = pGeomCache->GetPrevIFrame(pHandle->m_startFrame) % frameDataSize; - uint reinitializeEnd = pHandle->m_endFrame % frameDataSize; - - if (!pHandle->m_pNext && (reinitializeEnd != (frameDataSize - 1))) - { - // If this was the last handle in stream or the next handle start frame is not right after the current handles end frame - // we need to reinitialize until the next index frame because index frame jobs will decrement dependency - // counters from b frames ahead of time. - - reinitializeEnd = pGeomCache->GetNextIFrame(reinitializeEnd) + 1; - } - - ReinitializeStreamFrameData(streamInfo, reinitializeStart, reinitializeEnd); - RetireBufferHandle(pHandle); -} - -template -void CGeomCacheManager::RetireBufferHandle(TBufferHandleType* pHandle) -{ - FUNCTION_PROFILER_3DENGINE; - - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - CryFatalError("CGeomCacheManager::RetireBufferHandle must be called from main thread"); - } - - if (pHandle->m_numJobReferences) - { - CryFatalError("Trying to retire handle with jobs still running"); - } - - { - FRAME_PROFILER("CGeomCacheManager::RetireBufferHandle_Free", GetSystem(), PROFILE_3DENGINE); - size_t pointerSize = (sizeof(SGeomCacheBufferHandle*) + 15) & ~15; - m_pPool->Free(pHandle->m_pBuffer - pointerSize); - } - - delete pHandle; -} - -float CGeomCacheManager::GetPrecachedTime(const IGeomCacheRenderNode* pRenderNode) -{ - assert(gEnv->mMainThreadId == CryGetCurrentThreadId()); - - for (uint i = 0; i < m_streamInfos.size(); ++i) - { - SGeomCacheStreamInfo& streamInfo = *m_streamInfos[i]; - if (streamInfo.m_pRenderNode == pRenderNode) - { - const float playbackTime = pRenderNode->GetPlaybackTime(); - - if (streamInfo.m_pNewestDecompressHandle) - { - CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - - const uint frame = streamInfo.m_pNewestDecompressHandle->m_startFrame; - const float frameTime = pGeomCache->GetFrameTime(frame); - - if (playbackTime <= frameTime) - { - return frameTime - playbackTime; - } - } - - break; - } - } - - return 0.0f; -} - -SGeomCacheBufferHandle* CGeomCacheManager::GetFrameDecompressHandle(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex) -{ - const uint frameDataSize = pStreamInfo->m_frameData.size(); - return pStreamInfo->m_frameData[frameIndex % frameDataSize].m_pDecompressHandle; -} - -SGeomCacheFrameHeader* CGeomCacheManager::GetFrameDecompressHeader(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex) -{ - SGeomCacheBufferHandle* pHandle = GetFrameDecompressHandle(pStreamInfo, frameIndex); - - if (!pHandle) - { - return nullptr; - } - - //If the start frame is greater than the frame index - //we're going to crash because frameOffset will overflow and - //access pHandle->pBuffer beyond its limits - //This can happen if the user sets the start frame too high - if (pHandle->m_startFrame > frameIndex) - { - return nullptr; - } - - const uint frameOffset = frameIndex - pHandle->m_startFrame; - - SGeomCacheFrameHeader* pHeader = reinterpret_cast( - pHandle->m_pBuffer + (frameOffset * sizeof(SGeomCacheFrameHeader))); - return pHeader; -} - -char* CGeomCacheManager::GetFrameDecompressData(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex) -{ - SGeomCacheFrameHeader* pHeader = GetFrameDecompressHeader(pStreamInfo, frameIndex); - SGeomCacheBufferHandle* pHandle = GetFrameDecompressHandle(pStreamInfo, frameIndex); - - if (!pHandle || !pHeader) - { - return NULL; - } - - return pHandle->m_pBuffer + pHeader->m_offset; -} - -int* CGeomCacheManager::GetDependencyCounter(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex) -{ - const uint frameDataSize = pStreamInfo->m_frameData.size(); - return &pStreamInfo->m_frameData[frameIndex % frameDataSize].m_decodeDependencyCounter; -} - -#ifndef _RELEASE -namespace -{ - void Draw2DBox(float x, float y, float width, float height, const ColorB& color, float screenHeight, float screenWidth, IRenderAuxGeom* pAuxRenderer) - { - float position[4][2] = { - { x - 1.0f, y - 1.0f}, - { x - 1.0f, y + height + 1.0f}, - { x + width + 1.0f, y + height + 1.0f}, - { x + width + 1.0f, y - 1.0f} - }; - - Vec3 positions[4] = { - Vec3(position[0][0] / screenWidth, position[0][1] / screenHeight, 0.0f), - Vec3(position[1][0] / screenWidth, position[1][1] / screenHeight, 0.0f), - Vec3(position[2][0] / screenWidth, position[2][1] / screenHeight, 0.0f), - Vec3(position[3][0] / screenWidth, position[3][1] / screenHeight, 0.0f) - }; - - vtx_idx const indices[6] = { 0, 1, 2, 0, 2, 3 }; - - pAuxRenderer->DrawTriangles(positions, 4, indices, 6, color); - } - - void Draw2DBoxOutLine(float x, float y, float width, float height, const ColorB& color, float screenHeight, float screenWidth, IRenderAuxGeom* pAuxRenderer) - { - float position[4][2] = { - { x - 1.0f, y - 1.0f}, - { x - 1.0f, y + height + 1.0f}, - { x + width + 1.0f, y + height + 1.0f}, - { x + width + 1.0f, y - 1.0f} - }; - - Vec3 positions[4] = { - Vec3(position[0][0] / screenWidth, position[0][1] / screenHeight, 0.0f), - Vec3(position[1][0] / screenWidth, position[1][1] / screenHeight, 0.0f), - Vec3(position[2][0] / screenWidth, position[2][1] / screenHeight, 0.0f), - Vec3(position[3][0] / screenWidth, position[3][1] / screenHeight, 0.0f) - }; - - - pAuxRenderer->DrawLine(positions[0], color, positions[1], color); - pAuxRenderer->DrawLine(positions[1], color, positions[2], color); - pAuxRenderer->DrawLine(positions[2], color, positions[3], color); - pAuxRenderer->DrawLine(positions[3], color, positions[0], color); - } - - void DrawStream(const char* pBase, const size_t poolSize, const SGeomCacheBufferHandle* pFirstHandle, const ColorF& color, const float boxLeft, const float boxTop, - const float boxWidth, const float boxHeight, const float screenWidth, const float screenHeight, IRenderAuxGeom* pRenderAuxGeom) - { - const float bufferSize = (float)poolSize; - for (const SGeomCacheBufferHandle* pCurrentHandle = pFirstHandle; pCurrentHandle; pCurrentHandle = pCurrentHandle->m_pNext) - { - ColorF blockColor = color; - - const float offset = (float)(pCurrentHandle->m_pBuffer - pBase); - const float size = (float)pCurrentHandle->m_bufferSize; - - const float left = boxWidth * (offset / bufferSize); - const float width = boxWidth * (size / bufferSize); - - Draw2DBox(boxLeft + left + 1, boxTop + 1, width - 3, boxHeight - 2, blockColor, screenHeight, screenWidth, pRenderAuxGeom); - } - } -} - -void CGeomCacheManager::DrawDebugInfo() -{ - IRenderAuxGeom* const pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); - - const SAuxGeomRenderFlags oldFlags = pRenderAuxGeom->GetRenderFlags(); - - SAuxGeomRenderFlags flags(e_Def2DPublicRenderflags); - flags.SetDepthTestFlag(e_DepthTestOff); - flags.SetDepthWriteFlag(e_DepthWriteOff); - flags.SetCullMode(e_CullModeNone); - flags.SetAlphaBlendMode(e_AlphaNone); - pRenderAuxGeom->SetRenderFlags(flags); - - const float screenHeight = (float)gEnv->pRenderer->GetHeight(); - const float screenWidth = (float)gEnv->pRenderer->GetWidth(); - - const float topOffset = screenHeight * 0.01f; - const float sideOffset = screenWidth * 0.01f; - - const float bufferBoxTop = 2.0f + 8.0f * topOffset; - const float bufferBoxHeight = screenHeight * 0.05f; - const float bufferBoxLeft = sideOffset; - const float bufferBoxWidth = screenWidth * 0.5f; - - float streamInfosTop = bufferBoxTop + bufferBoxHeight + 2.0f * topOffset; - const float streamInfoSpacing = 20.0f; - const float streamInfoBoxSize = 10.0f; - - uint numActiveStreams = 0; - - const uint kNumColors = 8; - ColorF colors[kNumColors] = { Col_Red, Col_Green, Col_Yellow, Col_Blue, Col_Aquamarine, Col_Thistle, Col_Tan, Col_Salmon }; - - uint colorIndex = 0; - const uint numStreams = m_streamInfos.size(); - for (uint i = 0; i < numStreams; ++i) - { - SGeomCacheStreamInfo& streamInfo = *m_streamInfos[i]; - CGeomCacheRenderNode* pRenderNode = streamInfo.m_pRenderNode; - CGeomCache* pGeomCache = streamInfo.m_pGeomCache; - const char* pName = streamInfo.m_pRenderNode->GetName(); - - const bool bDisplay = ((GetCVars()->e_GeomCacheDebug != 2) || (pRenderNode->IsStreaming() || streamInfo.m_pOldestDecompressHandle || streamInfo.m_pNewestReadRequestHandle)) - && strstr(pName, GetCVars()->e_GeomCacheDebugFilter->GetString()) != NULL; - - if (bDisplay) - { - ColorF& color = colors[colorIndex % kNumColors]; - - DrawStream(reinterpret_cast(m_pPoolBaseAddress), m_poolSize, streamInfo.m_pOldestDecompressHandle, color, bufferBoxLeft, bufferBoxTop, - bufferBoxWidth, bufferBoxHeight, screenWidth, screenHeight, pRenderAuxGeom); - DrawStream(reinterpret_cast(m_pPoolBaseAddress), m_poolSize, streamInfo.m_pDecompressAbortListHead, color, bufferBoxLeft, bufferBoxTop, - bufferBoxWidth, bufferBoxHeight, screenWidth, screenHeight, pRenderAuxGeom); - DrawStream(reinterpret_cast(m_pPoolBaseAddress), m_poolSize, streamInfo.m_pOldestReadRequestHandle, color, bufferBoxLeft, bufferBoxTop, - bufferBoxWidth, bufferBoxHeight, screenWidth, screenHeight, pRenderAuxGeom); - DrawStream(reinterpret_cast(m_pPoolBaseAddress), m_poolSize, streamInfo.m_pReadAbortListHead, color, bufferBoxLeft, bufferBoxTop, - bufferBoxWidth, bufferBoxHeight, screenWidth, screenHeight, pRenderAuxGeom); - - const float currentTop = streamInfosTop + streamInfoSpacing * 2.5f * numActiveStreams; - Draw2DBox(sideOffset, currentTop, streamInfoBoxSize, streamInfoBoxSize, color, screenHeight, screenWidth, pRenderAuxGeom); - - const float wantedPlaybackTime = streamInfo.m_wantedPlaybackTime; - const uint wantedFloorFrame = streamInfo.m_wantedFloorFrame; - const uint wantedCeilFrame = streamInfo.m_wantedCeilFrame; - const int oldestDiskFrame = streamInfo.m_pOldestReadRequestHandle ? streamInfo.m_pOldestReadRequestHandle->m_startFrame : -1; - const int newestDiskFrame = streamInfo.m_pNewestReadRequestHandle ? streamInfo.m_pNewestReadRequestHandle->m_endFrame : -1; - const int oldestDecompressFrame = streamInfo.m_pOldestDecompressHandle ? streamInfo.m_pOldestDecompressHandle->m_startFrame : -1; - const int newestDecompressFrame = streamInfo.m_pNewestDecompressHandle ? streamInfo.m_pNewestDecompressHandle->m_endFrame : -1; - - IGeomCache::SStatistics stats = pGeomCache->GetStatistics(); - - const char* pCompressionMethod = "Store"; - if (pGeomCache->GetBlockCompressionFormat() == GeomCacheFile::eBlockCompressionFormat_Deflate) - { - pCompressionMethod = "Deflate"; - } - else if (pGeomCache->GetBlockCompressionFormat() == GeomCacheFile::eBlockCompressionFormat_LZ4HC) - { - pCompressionMethod = "LZ4 HC"; - } - else if (pGeomCache->GetBlockCompressionFormat() == GeomCacheFile::eBlockCompressionFormat_ZSTD) - { - pCompressionMethod = "ZSTD"; - } - gEnv->pRenderer->Draw2dLabel(sideOffset + streamInfoSpacing, currentTop - 5.0f, 1.5f, Col_White, false, "%s - %.3gs %s- %.3g MiB/s - %s - %d frames missed", - streamInfo.m_pRenderNode->GetName(), pGeomCache->GetDuration(), streamInfo.m_bLooping ? "looping " : "", stats.m_averageAnimationDataRate, pCompressionMethod, streamInfo.m_numFramesMissed); - gEnv->pRenderer->Draw2dLabel(sideOffset + streamInfoSpacing, streamInfoSpacing + currentTop - 5.0f, 1.5f, Col_White, false, - "Frame: [%04u, %04u], Disk Frames: [%04u, %04u], Decompress Frames: [%04u, %04u], Playback time: %g", wantedFloorFrame, wantedCeilFrame, - oldestDiskFrame, newestDiskFrame, oldestDecompressFrame, newestDecompressFrame, wantedPlaybackTime); - - ++numActiveStreams; - ++colorIndex; - } - } - - const uint numAbortedStreams = m_streamInfosAbortList.size(); - gEnv->pRenderer->Draw2dLabel(sideOffset, topOffset, 1.5f, Col_Yellow, false, "%u Geometry Cache(s) active", numActiveStreams); - gEnv->pRenderer->Draw2dLabel(sideOffset, 3.5f * topOffset, 1.5f, (m_numMissedFrames > 0) ? Col_Red : Col_Green, false, "%u Frames missed", m_numMissedFrames); - gEnv->pRenderer->Draw2dLabel(sideOffset + 160.0f, 3.5f * topOffset, 1.5f, (m_numStreamAborts > 0) ? Col_Red : Col_Green, false, "%u Stream aborts (err: %u, decomp: %u, read: %u)", - m_numStreamAborts, m_numErrorAborts, m_numDecompressStreamAborts, m_numReadStreamAborts); - gEnv->pRenderer->Draw2dLabel(sideOffset + 520.0f, 3.5f * topOffset, 1.5f, (m_numFailedAllocs > 0) ? Col_Yellow : Col_Green, false, "%u Failed alloc(s)", m_numFailedAllocs); - gEnv->pRenderer->Draw2dLabel(sideOffset + 670.0f, 3.5f * topOffset, 1.5f, (numAbortedStreams > 0) ? Col_Yellow : Col_Green, false, "%u Aborted stream(s)", numAbortedStreams); - - gEnv->pRenderer->Draw2dLabel(sideOffset, 6.0f * topOffset, 1.25f, Col_White, false, "Geom Cache Buffer:"); - Draw2DBoxOutLine(bufferBoxLeft, bufferBoxTop, bufferBoxWidth, bufferBoxHeight, Col_White, screenHeight, screenWidth, pRenderAuxGeom); - - pRenderAuxGeom->SetRenderFlags(oldFlags); -} -#endif - -#endif diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheManager.h b/Code/CryEngine/Cry3DEngine/GeomCacheManager.h deleted file mode 100644 index 43e90c21ca..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheManager.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages geometry cache instances and streaming - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHEMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHEMANAGER_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheDecoder.h" -#include "GeomCacheMeshManager.h" -#include - -#include - -class CGeomCache; -class CGeomCacheRenderNode; - -struct SGeomCacheStreamInfo; - -struct SGeomCacheBufferHandle -{ - SGeomCacheBufferHandle() - { - m_pNext = NULL; - m_startFrame = 0; - m_endFrame = 0; - m_bufferSize = 0; - m_pBuffer = NULL; - m_pStream = NULL; - m_numJobReferences = 0; - } - - volatile int m_numJobReferences; - uint32 m_bufferSize; - uint32 m_startFrame; - uint32 m_endFrame; - char* m_pBuffer; - - SGeomCacheStreamInfo* m_pStream; - CTimeValue m_frameTime; - - // Next buffer handle for this stream or in the free list - SGeomCacheBufferHandle* m_pNext; - - CryConditionVariable m_jobReferencesCV; -}; - -// This handle represents a block in the read buffer -struct SGeomCacheReadRequestHandle - : public SGeomCacheBufferHandle - , public IStreamCallback -{ - // IStreamCallback - virtual void StreamOnComplete([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - virtual void StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) - { - if (nError != 0 && nError != ERROR_USER_ABORT) - { - string error = "Geom cache read request failed with error: " + string(pStream->GetErrorName()); - gEnv->pLog->LogError("%s", error.c_str()); - } - - m_state = eRRHS_FinishedRead; - m_error = nError; - - if (CryInterlockedDecrement(&m_numJobReferences) == 0) - { - m_jobReferencesCV.Notify(); - } - } - - enum EReadRequestHandleState - { - eRRHS_Reading = 0, - eRRHS_FinishedRead = 1, - eRRHS_Decompressing = 2, - eRRHS_Done = 3 - }; - - volatile EReadRequestHandleState m_state; - volatile long m_error; - IReadStreamPtr m_pReadStream; -}; - -struct SGeomCacheStreamInfo -{ - SGeomCacheStreamInfo(CGeomCacheRenderNode* pRenderNode, CGeomCache* pGeomCache, const uint numFrames) - : m_pRenderNode(pRenderNode) - , m_pGeomCache(pGeomCache) - , m_numFrames(numFrames) - , m_displayedFrameTime(-1.0f) - , m_wantedPlaybackTime(0.0f) - , m_wantedFloorFrame(0) - , m_wantedCeilFrame(0) - , m_sameFrameFillCount(0) - , m_numFramesMissed(0) - , m_pOldestReadRequestHandle(NULL) - , m_pNewestReadRequestHandle(NULL) - , m_pReadAbortListHead(NULL) - , m_pOldestDecompressHandle(NULL) - , m_pNewestDecompressHandle(NULL) - , m_pDecompressAbortListHead(NULL) - , m_bAbort(0L) - , m_bLooping(false) - {} - - CGeomCacheRenderNode* m_pRenderNode; - CGeomCache* m_pGeomCache; - - uint m_numFrames; - - volatile float m_displayedFrameTime; - volatile float m_wantedPlaybackTime; - volatile uint m_wantedFloorFrame; - volatile uint m_wantedCeilFrame; - volatile int m_sameFrameFillCount; - - uint m_numFramesMissed; - - SGeomCacheReadRequestHandle* m_pOldestReadRequestHandle; - SGeomCacheReadRequestHandle* m_pNewestReadRequestHandle; - SGeomCacheReadRequestHandle* m_pReadAbortListHead; - - SGeomCacheBufferHandle* m_pOldestDecompressHandle; - SGeomCacheBufferHandle* m_pNewestDecompressHandle; - SGeomCacheBufferHandle* m_pDecompressAbortListHead; - - volatile bool m_bAbort; - CryCriticalSection m_abortCS; - - bool m_bLooping; - - AZ::LegacyJobExecutor m_fillRenderNodeJobExecutor; - - struct SFrameData - { - bool m_bDecompressJobLaunched; - - // For each frame we initialize a counter to the number of jobs - // that need to complete before the frame can be decoded. - // - // Each index frame has exactly one dependent job (inflate) - // The first B frame after an index frame has three dependencies (inflate + previous and last index frame) - // All other B frames have only two dependencies (inflate + previous B frame) - int m_decodeDependencyCounter; - - // Pointer to decompress handle for this frame. - SGeomCacheBufferHandle* m_pDecompressHandle; - }; - - // Array with data for each frame - std::vector m_frameData; -}; - -struct SDecodeFrameJobData -{ - uint m_frameIndex; - const CGeomCache* m_pGeomCache; - SGeomCacheStreamInfo* m_pStreamInfo; -}; - -class CGeomCacheManager - : public Cry3DEngineBase - , public AzFramework::LegacyAssetEventBus::Handler -{ -public: - CGeomCacheManager(); - ~CGeomCacheManager(); - - // Called during level unload to free all resource references - void Reset(); - - CGeomCache* LoadGeomCache(const char* szFileName); - void DeleteGeomCache(CGeomCache* pGeomCache); - - void StreamingUpdate(); - - void RegisterForStreaming(CGeomCacheRenderNode* pRenderNode); - void UnRegisterForStreaming(CGeomCacheRenderNode* pRenderNode, bool bWaitForJobs); - - float GetPrecachedTime(const IGeomCacheRenderNode* pRenderNode); - -#ifndef _RELEASE - void DrawDebugInfo(); - void ResetDebugInfo() { m_numMissedFrames = 0; m_numStreamAborts = 0; m_numFailedAllocs = 0; } -#endif - - void DecompressFrame_JobEntry(SGeomCacheStreamInfo* pStreamInfo, const uint blockIndex, - SGeomCacheBufferHandle* pDecompressHandle, SGeomCacheReadRequestHandle* pReadRequestHandle); - - void FillRenderNodeAsync_JobEntry(SGeomCacheStreamInfo* pStreamInfo); - - void DecodeIFrame_JobEntry(SDecodeFrameJobData jobState); - void DecodeBFrame_JobEntry(SDecodeFrameJobData jobState); - - CGeomCacheMeshManager& GetMeshManager() { return m_meshManager; } - - void StopCacheStreamsAndWait(CGeomCache* pGeomCache); - - CGeomCache* FindGeomCacheByFilename(const char* filename); - - // For changing the buffer size on runtime. This will do a blocking wait on all active streams, - // so it should only be called when we are sure that no caches are playing (e.g. on level load) - void ChangeBufferSize(const uint newSizeInMiB); - -private: - - // override from LegacyAssetEventBus::Handler - void OnFileChanged(AZStd::string assetPath) override; - - static void OnChangeBufferSize(ICVar* pCVar); - - void ReinitializeStreamFrameData(SGeomCacheStreamInfo& streamInfo, uint startFrame, uint endFrame); - - void UnloadGeomCaches(); - - bool IssueDiskReadRequest(SGeomCacheStreamInfo& pStreamInfo); - - void LaunchStreamingJobs(const uint numStreams, const CTimeValue currentFrameTime); - void LaunchDecompressJobs(SGeomCacheStreamInfo* pStreamInfo, const CTimeValue currentFrameTime); - void LaunchDecodeJob(SDecodeFrameJobData jobState); - - template - TBufferHandleType* NewBufferHandle(const uint32 size, SGeomCacheStreamInfo& streamInfo); - SGeomCacheReadRequestHandle* NewReadRequestHandle(const uint32 size, SGeomCacheStreamInfo& streamInfo); - - void RetireHandles(SGeomCacheStreamInfo& streamInfo); - void RetireOldestReadRequestHandle(SGeomCacheStreamInfo& streamInfo); - void RetireOldestDecompressHandle(SGeomCacheStreamInfo& streamInfo); - void RetireDecompressHandle(SGeomCacheStreamInfo& streamInfo, SGeomCacheBufferHandle* pHandle); - template - void RetireBufferHandle(TBufferHandleType* pHandle); - - void RetireRemovedStreams(); - void ValidateStream(SGeomCacheStreamInfo& streamInfo); - void AbortStream(SGeomCacheStreamInfo& streamInfo); - void AbortStreamAndWait(SGeomCacheStreamInfo& streamInfo); - void RetireAbortedHandles(SGeomCacheStreamInfo& streamInfo); - - SGeomCacheBufferHandle* GetFrameDecompressHandle(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex); - SGeomCacheFrameHeader* GetFrameDecompressHeader(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex); - char* GetFrameDecompressData(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex); - int* GetDependencyCounter(SGeomCacheStreamInfo* pStreamInfo, const uint frameIndex); - - void* m_pPoolBaseAddress; - IGeneralMemoryHeap* m_pPool; - size_t m_poolSize; - - uint m_lastRequestStream; - - uint m_numMissedFrames; - uint m_numStreamAborts; - uint m_numErrorAborts; - uint m_numDecompressStreamAborts; - uint m_numReadStreamAborts; - uint m_numFailedAllocs; - - typedef std::vector::iterator TStreamInfosIter; - std::vector m_streamInfos; - std::vector m_streamInfosAbortList; - - typedef std::map > TGeomCacheMap; - TGeomCacheMap m_nameToGeomCacheMap; - - CGeomCacheMeshManager m_meshManager; -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHEMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.cpp b/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.cpp deleted file mode 100644 index 8c12c38ed8..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages static meshes for geometry caches - - -#include "Cry3DEngine_precompiled.h" - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheMeshManager.h" -#include "GeomCacheDecoder.h" - -void CGeomCacheMeshManager::Reset() -{ - stl::free_container(m_meshMap); -} - -bool CGeomCacheMeshManager::ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, SGeomCacheStaticMeshData& staticMeshData) const -{ - LOADING_TIME_PROFILE_SECTION; - - if (staticMeshData.m_constantStreams & GeomCacheFile::eStream_Indices) - { - if (!ReadMeshIndices(reader, meshInfo, staticMeshData, staticMeshData.m_indices)) - { - return false; - } - } - - if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Positions) != 0) - { - staticMeshData.m_positions.resize(staticMeshData.m_numVertices); - - strided_pointer positions(&staticMeshData.m_positions[0], sizeof(Vec3)); - if (!ReadMeshPositions(reader, meshInfo, positions)) - { - return false; - } - } - - if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Texcoords) != 0) - { - staticMeshData.m_texcoords.resize(staticMeshData.m_numVertices); - - strided_pointer texcoords(&staticMeshData.m_texcoords[0], sizeof(Vec2)); - if (!ReadMeshTexcoords(reader, meshInfo, texcoords)) - { - return false; - } - } - - if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_QTangents) != 0) - { - staticMeshData.m_tangents.resize(staticMeshData.m_numVertices); - - strided_pointer tangents(&staticMeshData.m_tangents[0], sizeof(SPipTangents)); - if (!ReadMeshQTangents(reader, meshInfo, tangents)) - { - return false; - } - } - - if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Colors) != 0) - { - UCol defaultColor; - defaultColor.dcolor = 0xFFFFFFFF; - staticMeshData.m_colors.resize(staticMeshData.m_numVertices, defaultColor); - - strided_pointer colors(&staticMeshData.m_colors[0], sizeof(UCol)); - if (!ReadMeshColors(reader, meshInfo, colors)) - { - return false; - } - } - - if (staticMeshData.m_bUsePredictor) - { - uint32 predictorDataSize; - if (!reader.Read(&predictorDataSize)) - { - return false; - } - - staticMeshData.m_predictorData.resize(predictorDataSize); - if (!reader.Read(&staticMeshData.m_predictorData[0], predictorDataSize)) - { - return false; - } - } - - return true; -} - -_smart_ptr CGeomCacheMeshManager::ConstructStaticRenderMesh(CGeomCacheStreamReader& reader, - const GeomCacheFile::SMeshInfo& meshInfo, SGeomCacheStaticMeshData& staticMeshData, const char* pFileName) -{ - LOADING_TIME_PROFILE_SECTION; - - std::vector vertexData(staticMeshData.m_numVertices * sizeof(SVF_P3F_C4B_T2F), 0); - std::vector tangentData(staticMeshData.m_numVertices); - - std::vector indices; - strided_pointer positions((Vec3*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, xyz)), sizeof(SVF_P3F_C4B_T2F)); - strided_pointer colors((UCol*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, color)), sizeof(SVF_P3F_C4B_T2F)); - strided_pointer texcoords((Vec2*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, st)), sizeof(SVF_P3F_C4B_T2F)); - strided_pointer tangents((SPipTangents*)((char*)(&tangentData[0])), sizeof(SPipTangents)); - - if (!ReadMeshIndices(reader, meshInfo, staticMeshData, indices) - || !ReadMeshPositions(reader, meshInfo, positions) - || !ReadMeshTexcoords(reader, meshInfo, texcoords) - || !ReadMeshQTangents(reader, meshInfo, tangents)) - { - return NULL; - } - - if (meshInfo.m_constantStreams & GeomCacheFile::eStream_Colors) - { - if (!ReadMeshColors(reader, meshInfo, colors)) - { - return NULL; - } - } - else - { - UCol defaultColor; - defaultColor.dcolor = 0xFFFFFFFF; - - const uint numVertices = meshInfo.m_numVertices; - for (uint i = 0; i < numVertices; ++i) - { - colors[i] = defaultColor; - } - } - - TMeshMap::iterator findIter = m_meshMap.find(staticMeshData.m_hash); - if (findIter != m_meshMap.end()) - { - ++findIter->second.m_refCount; - return findIter->second.m_pRenderMesh; - } - - _smart_ptr pRenderMesh = gEnv->pRenderer->CreateRenderMeshInitialized(&vertexData[0], meshInfo.m_numVertices, - eVF_P3F_C4B_T2F, &indices[0], indices.size(), prtTriangleList, "GeomCacheConstantMesh", pFileName, eRMT_Static, 1, 0, - NULL, NULL, false, false, &tangentData[0]); - - CRenderChunk chunk; - chunk.nNumVerts = meshInfo.m_numVertices; - uint32 currentIndexOffset = 0; - - for (unsigned int i = 0; i < meshInfo.m_numMaterials; ++i) - { - chunk.nFirstIndexId = currentIndexOffset; - chunk.nNumIndices = staticMeshData.m_numIndices[i]; - chunk.m_nMatID = staticMeshData.m_materialIds[i]; - chunk.m_vertexFormat = eVF_P3F_C4B_T2F; - pRenderMesh->SetChunk(i, chunk); - currentIndexOffset += chunk.nNumIndices; - } - - SMeshMapInfo meshMapInfo; - meshMapInfo.m_refCount = 1; - meshMapInfo.m_pRenderMesh = pRenderMesh; - - m_meshMap[staticMeshData.m_hash] = meshMapInfo; - return pRenderMesh; -} - -_smart_ptr CGeomCacheMeshManager::GetStaticRenderMesh(const uint64 hash) const -{ - TMeshMap::const_iterator findIter = m_meshMap.find(hash); - if (findIter != m_meshMap.end()) - { - return findIter->second.m_pRenderMesh; - } - - return NULL; -} - -void CGeomCacheMeshManager::RemoveReference(SGeomCacheStaticMeshData& staticMeshData) -{ - TMeshMap::iterator findIter = m_meshMap.find(staticMeshData.m_hash); - if (findIter != m_meshMap.end()) - { - uint& refCount = findIter->second.m_refCount; - --refCount; - - if (refCount == 0) - { - m_meshMap.erase(findIter); - } - } -} - -bool CGeomCacheMeshManager::ReadMeshIndices(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, - SGeomCacheStaticMeshData& staticMeshData, std::vector& indices) const -{ - const uint16 numMaterials = meshInfo.m_numMaterials; - staticMeshData.m_numIndices.reserve(numMaterials); - - for (unsigned int i = 0; i < numMaterials; ++i) - { - uint32 numIndices; - if (!reader.Read(&numIndices)) - { - return false; - } - - staticMeshData.m_numIndices.push_back(numIndices); - - const uint indicesStart = indices.size(); - indices.resize(indicesStart + numIndices); - if (!reader.Read(&indices[indicesStart], numIndices)) - { - return false; - } - } - - return true; -} - -bool CGeomCacheMeshManager::ReadMeshPositions(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer positions) const -{ - const Vec3 aabbMin = Vec3(meshInfo.m_aabbMin[0], meshInfo.m_aabbMin[1], meshInfo.m_aabbMin[2]); - const Vec3 aabbMax = Vec3(meshInfo.m_aabbMax[0], meshInfo.m_aabbMax[1], meshInfo.m_aabbMax[2]); - const AABB meshAABB(aabbMin, aabbMax); - const Vec3 aabbSize = meshAABB.GetSize(); - const Vec3 posConvertFactor = Vec3(1.0f / float((2 << (meshInfo.m_positionPrecision[0] - 1)) - 1), - 1.0f / float((2 << (meshInfo.m_positionPrecision[1] - 1)) - 1), - 1.0f / float((2 << (meshInfo.m_positionPrecision[2] - 1)) - 1)); - - const uint numVertices = meshInfo.m_numVertices; - for (uint i = 0; i < numVertices; ++i) - { - GeomCacheFile::Position position; - - if (!reader.Read(&position)) - { - return false; - } - - positions[i] = GeomCacheDecoder::DecodePosition(aabbMin, aabbSize, position, posConvertFactor); - } - - return true; -} - -bool CGeomCacheMeshManager::ReadMeshTexcoords(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer texcoords) const -{ - const uint numVertices = meshInfo.m_numVertices; - for (uint i = 0; i < numVertices; ++i) - { - GeomCacheFile::Texcoords texcoord; - - if (!reader.Read(&texcoord)) - { - return false; - } - - texcoords[i] = GeomCacheDecoder::DecodeTexcoord(texcoord, meshInfo.m_uvMax); - } - - return true; -} - -bool CGeomCacheMeshManager::ReadMeshQTangents(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer tangents) const -{ - const uint numVertices = meshInfo.m_numVertices; - for (uint i = 0; i < numVertices; ++i) - { - GeomCacheFile::QTangent qTangent; - - if (!reader.Read(&qTangent)) - { - return false; - } - - Quat qDecodedTangent = GeomCacheDecoder::DecodeQTangent(qTangent); - GeomCacheDecoder::ConvertToTangentAndBitangent(qDecodedTangent, tangents[i]); - } - - return true; -} - -bool CGeomCacheMeshManager::ReadMeshColors(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer colors) const -{ - const uint numVertices = meshInfo.m_numVertices; - for (int colorIndex = 2; colorIndex >= 0; --colorIndex) - { - for (uint i = 0; i < numVertices; ++i) - { - GeomCacheFile::Color color; - - if (!reader.Read(&color)) - { - return false; - } - - colors[i].bcolor[colorIndex] = color; - } - } - - for (uint i = 0; i < numVertices; ++i) - { - GeomCacheFile::Color color; - - if (!reader.Read(&color)) - { - return false; - } - - colors[i].bcolor[3] = color; - } - - return true; -} - -#endif diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.h b/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.h deleted file mode 100644 index 3c2f62d8b7..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheMeshManager.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages static meshes for geometry caches - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHEMESHMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHEMESHMANAGER_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include "IRenderMesh.h" -#include "GeomCacheFileFormat.h" -#include "GeomCache.h" -#include - -class CGeomCacheMeshManager -{ -public: - void Reset(); - - bool ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, SGeomCacheStaticMeshData& staticMeshData) const; - _smart_ptr ConstructStaticRenderMesh(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, - SGeomCacheStaticMeshData& staticMeshData, const char* pFileName); - _smart_ptr GetStaticRenderMesh(const uint64 hash) const; - void RemoveReference(SGeomCacheStaticMeshData& staticMeshData); -private: - bool ReadMeshIndices(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, - SGeomCacheStaticMeshData& staticMeshData, std::vector& indices) const; - bool ReadMeshPositions(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer positions) const; - bool ReadMeshTexcoords(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer texcoords) const; - bool ReadMeshQTangents(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer tangents) const; - bool ReadMeshColors(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer colors) const; - - struct SMeshMapInfo - { - _smart_ptr m_pRenderMesh; - uint m_refCount; - }; - - // Map from mesh hash to render mesh - typedef AZStd::unordered_map TMeshMap; - TMeshMap m_meshMap; -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHEMESHMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/GeomCachePredictors.h b/Code/CryEngine/Cry3DEngine/GeomCachePredictors.h deleted file mode 100644 index c6a3c44f6e..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCachePredictors.h +++ /dev/null @@ -1,449 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Predictors for index frame compression - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHEPREDICTORS_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHEPREDICTORS_H -#pragma once - -#include "GeomCacheFileFormat.h" -#include "Cry3DEngineTraits.h" - -namespace GeomCachePredictors -{ - ////////////////////////////////////////////////////////////////////////// - // Index frame prediction - ////////////////////////////////////////////////////////////////////////// - - template - void ParallelogramPredictor(const uint numValues, T* pIn, T* pOut, const std::vector& predictorData) - { - T* pAbsoluteValues = kbEncode ? pIn : pOut; - uint outPosition = 0; - - for (uint i = 0, predictorDataPos = 0; i < numValues; ++i) - { - const uint16 uDist = predictorData[predictorDataPos++]; - T predictedValue; - - if (uDist == 0xFFFF) - { - if (i == 0) - { - // There is no previous value, so we just pass through - pOut[outPosition++] = pIn[i]; - continue; - } - - // No neighbour triangle, just use previous value for prediction - predictedValue = pAbsoluteValues[i - 1]; - } - else - { - // Parallelogram prediction - const uint16 vDist = predictorData[predictorDataPos++]; - const uint16 wDist = predictorData[predictorDataPos++]; - - const T& u = pAbsoluteValues[i - uDist]; - const T& v = pAbsoluteValues[i - vDist]; - const T& w = pAbsoluteValues[i - wDist]; - - predictedValue = u + v - w; - } - - if (kbEncode) - { - const T realValue = pIn[i]; - const T delta = realValue - predictedValue; - pOut[outPosition++] = delta; - } - else - { - const T delta = pIn[i]; - const T realValue = delta + predictedValue; - pOut[outPosition++] = realValue; - } - } - } - - template - void QTangentPredictor(const uint numValues, const GeomCacheFile::QTangent* pIn, GeomCacheFile::QTangent* pOut, const std::vector& predictorData) - { - const GeomCacheFile::QTangent* pAbsoluteValues = kbEncode ? pIn : pOut; - uint outPosition = 0; - - for (uint i = 0, predictorDataPos = 0; i < numValues; ++i) - { - const uint16 uDist = predictorData[predictorDataPos++]; - Vec4_tpl predictedValue; - - if (uDist == 0xFFFF) - { - if (i == 0) - { - // There is no previous value, so we just pass through - pOut[outPosition++] = pIn[i]; - continue; - } - - // No neighbour triangle, just use previous value for prediction - predictedValue = pAbsoluteValues[i - 1]; - } - else - { - // Average value of two nearest vertices of adjancent triangle - const uint16 vDist = predictorData[predictorDataPos++]; - ++predictorDataPos; - - const GeomCacheFile::QTangent& u = pAbsoluteValues[i - uDist]; - const GeomCacheFile::QTangent& v = pAbsoluteValues[i - vDist]; - predictedValue = Vec4_tpl(u) + Vec4_tpl(v); - - // Vec4_tpl defines division in a way that only works for floats - predictedValue.x /= 2; - predictedValue.y /= 2; - predictedValue.z /= 2; - predictedValue.w /= 2; - } - - if (kbEncode) - { - const GeomCacheFile::QTangent& realValue = pIn[i]; - const GeomCacheFile::QTangent delta = realValue - predictedValue; - pOut[outPosition++] = delta; - } - else - { - const GeomCacheFile::QTangent delta = pIn[i]; - const GeomCacheFile::QTangent realValue = delta + predictedValue; - pOut[outPosition++] = realValue; - } - } - } - - template - inline void ColorPredictor(const uint numValues, const GeomCacheFile::Color* pIn, GeomCacheFile::Color* pOut, const std::vector& predictorData) - { - const GeomCacheFile::Color* pAbsoluteValues = kbEncode ? pIn : pOut; - uint outPosition = 0; - - for (uint i = 0, predictorDataPos = 0; i < numValues; ++i) - { - const uint16 uDist = predictorData[predictorDataPos++]; - int32 predictedValue; - - if (uDist == 0xFFFF) - { - if (i == 0) - { - // There is no previous value, so we just pass through - pOut[outPosition++] = pIn[i]; - continue; - } - - // No neighbour triangle, just use previous value for prediction - predictedValue = pAbsoluteValues[i - 1]; - } - else - { - // Average value of two nearest vertices of adjancent triangle - const uint16 vDist = predictorData[predictorDataPos++]; - ++predictorDataPos; - - const GeomCacheFile::Color& u = pAbsoluteValues[i - uDist]; - const GeomCacheFile::Color& v = pAbsoluteValues[i - vDist]; - predictedValue = (int32(u) + int32(v)) / 2; - } - - if (kbEncode) - { - const GeomCacheFile::Color& realValue = pIn[i]; - const GeomCacheFile::Color delta = realValue - predictedValue; - pOut[outPosition++] = delta; - } - else - { - const GeomCacheFile::Color delta = pIn[i]; - const GeomCacheFile::Color realValue = delta + predictedValue; - pOut[outPosition++] = realValue; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Temporal prediction - ////////////////////////////////////////////////////////////////////////// - - // Motion predictor input data - template - struct STemporalPredictorData - { - uint m_numElements; - const T* m_pPrevFrames[2]; - const T* m_pFloorFrame; - const T* m_pCeilFrame; - }; - - template - Vec2_tpl operator>>(const Vec2_tpl& v, uint shift) - { - Vec2_tpl result = v; - result.x >>= shift; - result.y >>= shift; - return result; - } - - template - Vec3_tpl operator>>(const Vec3_tpl& v, uint shift) - { - Vec3_tpl result = v; - result.x >>= shift; - result.y >>= shift; - result.z >>= shift; - return result; - } - - template - Vec4_tpl operator>>(const Vec4_tpl& v, uint shift) - { - Vec4_tpl result = v; - result.x >>= shift; - result.y >>= shift; - result.z >>= shift; - result.w >>= shift; - return result; - } - - template - void InterpolateDeltaEncode(const uint numValues, const uint8 lerpFactor, const T* pFloorFrame, const T* pCeilFrame, const T* pIn, T* pOut) - { - for (uint i = 0; i < numValues; ++i) - { - const I floorValue = I(pFloorFrame[i]); - const I ceilValue = I(pCeilFrame[i]); - const T predictedValue = T(floorValue + (((ceilValue - floorValue) * lerpFactor) >> 8)); - - const T& realValue = pIn[i]; - const T delta = realValue - predictedValue; - pOut[i] = delta; - } - } - - template - void MotionDeltaEncode(const uint numValues, const uint8 acceleration, const T* const pPrevFrames[2], const T* pIn, T* pOut) - { - for (uint i = 0; i < numValues; ++i) - { - const I prevPrevFrameValue = I(pPrevFrames[0][i]); - const I prevFrameValue = I(pPrevFrames[1][i]); - const T predictedValue = T(prevFrameValue + (((prevFrameValue - prevPrevFrameValue) * acceleration) >> 7)); - - const T& realValue = pIn[i]; - const T delta = realValue - predictedValue; - pOut[i] = delta; - } - } - - template - void InterpolateMotionDeltaPredictor(const GeomCacheFile::STemporalPredictorControl& controlIn, const STemporalPredictorData& data, const T* pIn, T* pOut) - { - const T* pFloorFrame = data.m_pFloorFrame; - const T* const pCeilFrame = data.m_pCeilFrame; - const T* const* pPrevFrames = data.m_pPrevFrames; - - const uint8& lerpFactor = controlIn.m_indexFrameLerpFactor; - const uint8& acceleration = controlIn.m_acceleration; - const uint8 combineFactor = controlIn.m_combineFactor; - - const uint numElements = data.m_numElements; - for (uint i = 0; i < numElements; ++i) - { - const I prevPrevFrameValue = I(pPrevFrames[0][i]); - const I prevFrameValue = I(pPrevFrames[1][i]); - const I floorValue = I(pFloorFrame[i]); - const I ceilValue = I(pCeilFrame[i]); - - const I interpolatePredictedValue = T(floorValue + (((ceilValue - floorValue) * lerpFactor) >> 8)); - const I motionPredictedValue = T(prevFrameValue + (((prevFrameValue - prevPrevFrameValue) * acceleration) >> 7)); - const T predictedValue = (interpolatePredictedValue + (((motionPredictedValue - interpolatePredictedValue) * combineFactor) >> 7)); - - if (kbEncode) - { - const T realValue = pIn[i]; - const T delta = realValue - predictedValue; - pOut[i] = delta; - } - else - { - const T delta = pIn[i]; - const T realValue = delta + predictedValue; - pOut[i] = realValue; - } - } - } - -#if AZ_LEGACY_3DENGINE_TRAIT_DEFINE_MM_MULLO_EPI32_EMU - ILINE __m128i _mm_mullo_epi32_emu(const __m128i& a, const __m128i& b) - { - #if AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_MULLO_EPI32 - return _mm_mullo_epi32(a, b); - #else - __m128i tmp1 = _mm_mul_epu32(a, b); - __m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a, 4), _mm_srli_si128(b, 4)); - return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0))); - #endif - } - - ILINE __m128i _mm_packus_epi32_emu(__m128i& a, __m128i& b) - { -#if AZ_LEGACY_3DENGINE_TRAIT_HAS_MM_PACKUS_EPI32 - return _mm_packus_epi32(a, b); -#else - a = _mm_slli_epi32(a, 16); - b = _mm_slli_epi32(b, 16); - a = _mm_srai_epi32(a, 16); - b = _mm_srai_epi32(b, 16); - return _mm_packs_epi32(a, b); -#endif - } - - ILINE __m128i Interpolate(__m128i a, __m128i b, __m128i c, const uint32 factor, const int shiftFactor) - { - const __m128i zero = _mm_setzero_si128(); - const __m128i truncate = _mm_set_epi16(0, -1, 0, -1, 0, -1, 0, -1); - - // Unpack to 2x4 32 bit integers - __m128i factors = _mm_set1_epi32(factor); - - __m128i aLo = _mm_unpacklo_epi16(a, zero); - __m128i aHi = _mm_unpackhi_epi16(a, zero); - __m128i bLo = _mm_unpacklo_epi16(b, zero); - __m128i bHi = _mm_unpackhi_epi16(b, zero); - - // Interpolate and pack again - __m128i lerpLo = _mm_sub_epi32(bLo, aLo); - lerpLo = _mm_mullo_epi32_emu(lerpLo, factors); - lerpLo = _mm_srli_epi32(lerpLo, shiftFactor); - lerpLo = _mm_and_si128(lerpLo, truncate); - - __m128i lerpHi = _mm_sub_epi32(bHi, aHi); - lerpHi = _mm_mullo_epi32_emu(lerpHi, factors); - lerpHi = _mm_srli_epi32(lerpHi, shiftFactor); - lerpHi = _mm_and_si128(lerpHi, truncate); - - __m128i lerp = _mm_packus_epi32_emu(lerpLo, lerpHi); - __m128i result = _mm_add_epi16(lerp, c); - - return result; - } - - template<> - void InterpolateMotionDeltaPredictor - (const GeomCacheFile::STemporalPredictorControl& controlIn, const STemporalPredictorData& data, const uint16* pIn, uint16* pOut) - { - __m128i* pRawIn = (__m128i*)pIn; - __m128i* pRawOut = (__m128i*)pOut; - __m128i* pFloorFrame = (__m128i*)data.m_pFloorFrame; - __m128i* pCeilFrame = (__m128i*)data.m_pCeilFrame; - __m128i* pPrevFrames[2] = { (__m128i*)data.m_pPrevFrames[0], (__m128i*)data.m_pPrevFrames[1] }; - - const uint8 lerpFactor = controlIn.m_indexFrameLerpFactor; - const uint8 acceleration = controlIn.m_acceleration; - const uint8 combineFactor = controlIn.m_combineFactor; - - // vector store as much as possible, but account for cases where the output buffer - // size doesn't divide evenly by 8 - const uint remainingElements = data.m_numElements % 8; - const uint numElementsPadded = data.m_numElements / 8 + (remainingElements != 0); - const uint lastElement = numElementsPadded - 1; - for (uint i = 0; i < numElementsPadded; ++i) - { - // Load 8 floor & ceil values - __m128i floorValues = _mm_load_si128(pFloorFrame + i); - __m128i ceilValues = _mm_load_si128(pCeilFrame + i); - - // Load 8 prep prev & prev frame values - __m128i prevPrevFrameValues = _mm_load_si128(pPrevFrames[0] + i); - __m128i prevFrameValues = _mm_load_si128(pPrevFrames[1] + i); - - // Calculate prediction - __m128i lerp = Interpolate(floorValues, ceilValues, floorValues, lerpFactor, 8); - __m128i motion = Interpolate(prevPrevFrameValues, prevFrameValues, prevFrameValues, acceleration, 7); - __m128i predictedValues = Interpolate(lerp, motion, lerp, combineFactor, 7); - - __m128i delta = _mm_load_si128(pRawIn + i); - __m128i realValues = _mm_add_epi16(delta, predictedValues); - if (i == lastElement) - { - memcpy(pOut + (i * 8), &realValues, remainingElements * sizeof(uint16)); - } - else - { - _mm_store_si128(pRawOut + i, realValues); - } - } - } - - template<> - void InterpolateMotionDeltaPredictor, Vec2_tpl, false> - (const GeomCacheFile::STemporalPredictorControl& controlIn, const STemporalPredictorData >& data, - const Vec2_tpl* pIn, Vec2_tpl* pOut) - { - STemporalPredictorData uInt16Data; - - uInt16Data.m_pFloorFrame = (uint16*)data.m_pFloorFrame; - uInt16Data.m_pCeilFrame = (uint16*)data.m_pCeilFrame; - uInt16Data.m_pPrevFrames[0] = (uint16*)data.m_pPrevFrames[0]; - uInt16Data.m_pPrevFrames[1] = (uint16*)data.m_pPrevFrames[1]; - uInt16Data.m_numElements = data.m_numElements * 2; - - InterpolateMotionDeltaPredictor(controlIn, uInt16Data, (uint16*)pIn, (uint16*)pOut); - } - - template<> - void InterpolateMotionDeltaPredictor, Vec3_tpl, false> - (const GeomCacheFile::STemporalPredictorControl& controlIn, const STemporalPredictorData >& data, - const Vec3_tpl* pIn, Vec3_tpl* pOut) - { - STemporalPredictorData uInt16Data; - - uInt16Data.m_pFloorFrame = (uint16*)data.m_pFloorFrame; - uInt16Data.m_pCeilFrame = (uint16*)data.m_pCeilFrame; - uInt16Data.m_pPrevFrames[0] = (uint16*)data.m_pPrevFrames[0]; - uInt16Data.m_pPrevFrames[1] = (uint16*)data.m_pPrevFrames[1]; - uInt16Data.m_numElements = data.m_numElements * 3; - - InterpolateMotionDeltaPredictor(controlIn, uInt16Data, (uint16*)pIn, (uint16*)pOut); - } - - template<> - void InterpolateMotionDeltaPredictor, Vec4_tpl, false> - (const GeomCacheFile::STemporalPredictorControl& controlIn, const STemporalPredictorData >& data, - const Vec4_tpl* pIn, Vec4_tpl* pOut) - { - STemporalPredictorData uInt16Data; - - uInt16Data.m_pFloorFrame = (uint16*)data.m_pFloorFrame; - uInt16Data.m_pCeilFrame = (uint16*)data.m_pCeilFrame; - uInt16Data.m_pPrevFrames[0] = (uint16*)data.m_pPrevFrames[0]; - uInt16Data.m_pPrevFrames[1] = (uint16*)data.m_pPrevFrames[1]; - uInt16Data.m_numElements = data.m_numElements * 4; - - InterpolateMotionDeltaPredictor(controlIn, uInt16Data, (uint16*)pIn, (uint16*)pOut); - } -#endif -} - -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHEPREDICTORS_H diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.cpp b/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.cpp deleted file mode 100644 index 8f190aa594..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.cpp +++ /dev/null @@ -1,1491 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Draws geometry caches - - -#include "Cry3DEngine_precompiled.h" - -#if defined(USE_GEOM_CACHES) - -#include "GeomCacheRenderNode.h" -#include "GeomCacheManager.h" -#include "MatMan.h" - -#include - -namespace -{ - // Constants - const float kDefaultMaxViewDist = 1000.0f; -} - -CGeomCacheRenderNode::CGeomCacheRenderNode() - : m_pGeomCache(NULL) - , m_playbackTime(0.0f) - , m_pPhysicalEntity(NULL) - , m_maxViewDist(kDefaultMaxViewDist) - , m_bBox(0.0f) - , m_currentAABB(0.0f) - , m_currentDisplayAABB(0.0f) - , m_standInVisible(eStandInType_None) - , m_pStandIn(NULL) - , m_pFirstFrameStandIn(NULL) - , m_pLastFrameStandIn(NULL) - , m_standInDistance(0.0f) - , m_streamInDistance(0.0f) - , m_bInitialized(false) - , m_bLooping(false) - , m_bIsStreaming(false) - , m_bFilledFrameOnce(false) - , m_bBoundsChanged(true) - , m_bDrawing(true) - , m_bTransformReady(true) -{ - m_matrix.SetIdentity(); - m_pMaterial = GetMatMan()->GetDefaultMaterial(); - - SetRndFlags(ERF_HAS_CASTSHADOWMAPS, true); - SetRndFlags(ERF_CASTSHADOWMAPS, true); -} - -CGeomCacheRenderNode::~CGeomCacheRenderNode() -{ - Clear(true); - - if (m_pGeomCache) - { - m_pGeomCache->RemoveListener(this); - m_pGeomCache = nullptr; - } - - m_pMaterial = nullptr; - - Get3DEngine()->FreeRenderNodeState(this); -} - -const char* CGeomCacheRenderNode::GetEntityClassName() const -{ - return "GeomCache"; -} - -const char* CGeomCacheRenderNode::GetName() const -{ - if (m_pGeomCache) - { - return m_pGeomCache->GetFilePath(); - } - - return "GeomCacheNotSet"; -} - -Vec3 CGeomCacheRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - assert(bWorldOnly); - return m_matrix.GetTranslation(); -} - -void CGeomCacheRenderNode::SetBBox(const AABB& bBox) -{ - m_bBox = bBox; -} - -const AABB CGeomCacheRenderNode::GetBBox() const -{ - return m_bBox; -} - -void CGeomCacheRenderNode::UpdateBBox() -{ - AABB newAABB; - - const Vec3 vCamPos = Get3DEngine()->GetRenderingCamera().GetPosition(); - float distance = Distance::Point_Point(vCamPos, m_matrix.GetTranslation()); - - const bool bGeomCacheLoaded = m_pGeomCache ? m_pGeomCache->IsLoaded() : false; - - const bool bAllowStandIn = GetCVars()->e_Lods != 0; - const bool bInStandInDistance = distance > m_standInDistance && bAllowStandIn; - - EStandInType selectedStandIn = SelectStandIn(); - IStatObj* pStandIn = GetStandIn(selectedStandIn); - - if (pStandIn && (bInStandInDistance || !bGeomCacheLoaded)) - { - m_standInVisible = selectedStandIn; - newAABB = pStandIn->GetAABB(); - } - else - { - m_standInVisible = eStandInType_None; - newAABB = m_currentDisplayAABB; - } - - if (newAABB.min != m_currentAABB.min || newAABB.max != m_currentAABB.max) - { - m_bBoundsChanged = true; - m_currentAABB = newAABB; - } - - if (m_streamInDistance > 0.0f) - { - m_bIsStreaming = distance <= m_streamInDistance; - } -} - -void CGeomCacheRenderNode::GetLocalBounds(AABB& bbox) -{ - bbox = m_currentAABB; -} - -bool CGeomCacheRenderNode::DidBoundsChange() -{ - bool bBoundsChanged = m_bBoundsChanged; - - if (bBoundsChanged) - { - CalcBBox(); - } - - m_bBoundsChanged = false; - return bBoundsChanged; -} - -/* Geom caches are rendered using a custom render element for performance reasons (CREGeomCache). - * We only call mfAdd once per material, so a lot of meshes can be rendered with just one CRenderObject in the render pipeline. - * Mesh and transform updates run asynchronously started from FillFrameAsync and are synchronized in the render thread (CREGeomCache::Update) - * Visible meshes are added to a SMeshRenderData vector in UpdateTransformsRec. The lists are rendered in CREGeomCache::mfDraw - * Downside is that meshes in the cache are not sorted by depth for transparency passes -*/ -void CGeomCacheRenderNode::Render(const struct SRendParams& rendParams, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_bInitialized || !m_bDrawing || (m_renderMeshes.empty() && m_renderMeshUpdateContexts.empty()) - || !m_pGeomCache || m_dwRndFlags & ERF_HIDDEN || !passInfo.RenderGeomCaches()) - { - return; - } - - m_pGeomCache->SetLastDrawMainFrameId(passInfo.GetMainFrameID()); - - SRendParams drawParams = rendParams; - - drawParams.pMatrix = &m_matrix; - drawParams.nClipVolumeStencilRef = 0; - drawParams.ppRNTmpData = &m_pRNTmpData; - - switch (m_standInVisible) - { - case eStandInType_None: - { -#ifndef _RELEASE - if (GetCVars()->e_GeomCacheDebugDrawMode == 3) - { - break; - } -#endif - - drawParams.pMaterial = m_pMaterial; - - IRenderer* const pRenderer = GetRenderer(); - CRenderObject* pRenderObject = pRenderer->EF_GetObject_Temp(passInfo.ThreadID()); - - if (pRenderObject) - { - FillRenderObject(drawParams, passInfo, m_pMaterial, pRenderObject); - - if (m_pRenderElements.size() > 0 && passInfo.IsGeneralPass()) - { - // Only need to call this once because SRenderObjData::m_pInstance is the same for all of them - m_pRenderElements.begin()->second.m_pRenderElement->SetupMotionBlur(pRenderObject, passInfo); - } - - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - const uint materialId = iter->first; - CREGeomCache* pCREGeomCache = iter->second.m_pRenderElement; - - SShaderItem& shaderItem = m_pMaterial->GetShaderItem(materialId); - const int renderList = rendParams.nRenderList; - const int afterWater = rendParams.nAfterWater; - SRendItemSorter rendItemSorter(rendParams.rendItemSorter); - - pRenderer->EF_AddEf(pCREGeomCache, shaderItem, pRenderObject, passInfo, renderList, afterWater, rendItemSorter); - } - } - break; - } - case eStandInType_Default: - { - // Override material if there stand in has a material that is not default - _smart_ptr pStandInMaterial = m_pStandIn->GetMaterial(); - drawParams.pMaterial = (pStandInMaterial && !pStandInMaterial->IsDefault()) ? pStandInMaterial : drawParams.pMaterial; - - m_pStandIn->Render(drawParams, passInfo); - break; - } - case eStandInType_FirstFrame: - { - // Override material if there stand in has a material that is not default - _smart_ptr pStandInMaterial = m_pFirstFrameStandIn->GetMaterial(); - drawParams.pMaterial = (pStandInMaterial && !pStandInMaterial->IsDefault()) ? pStandInMaterial : drawParams.pMaterial; - - m_pFirstFrameStandIn->Render(drawParams, passInfo); - break; - } - case eStandInType_LastFrame: - { - // Override material if there stand in has a material that is not default - _smart_ptr pStandInMaterial = m_pLastFrameStandIn->GetMaterial(); - drawParams.pMaterial = (pStandInMaterial && !pStandInMaterial->IsDefault()) ? pStandInMaterial : drawParams.pMaterial; - - m_pLastFrameStandIn->Render(drawParams, passInfo); - break; - } - } -} - -void CGeomCacheRenderNode::SetMaterial(_smart_ptr pMat) -{ - if (pMat) - { - m_pMaterial = pMat; - } - else if (m_pGeomCache) - { - _smart_ptr pMaterial = m_pGeomCache->GetMaterial(); - m_pMaterial = pMaterial; - } - else - { - m_pMaterial = GetMatMan()->GetDefaultMaterial(); - } - - UpdatePhysicalMaterials(); -} - -_smart_ptr CGeomCacheRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - if (m_pMaterial) - { - return m_pMaterial; - } - else if (m_pGeomCache) - { - return m_pGeomCache->GetMaterial(); - } - - return NULL; -} - -float CGeomCacheRenderNode::GetMaxViewDist() -{ - return m_maxViewDist * m_fViewDistanceMultiplier; -} - -void CGeomCacheRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "GeomCache"); - pSizer->AddObject(this, sizeof(*this)); -} - -void CGeomCacheRenderNode::SetMatrix(const Matrix34& matrix) -{ - m_matrix = matrix; - CalcBBox(); -} - -void CGeomCacheRenderNode::CalcBBox() -{ - m_bBox = AABB(0.0f); - - if (!m_pGeomCache || !m_pGeomCache->IsValid()) - { - return; - } - - m_bBox.SetTransformedAABB(m_matrix, m_currentAABB); -} - -bool CGeomCacheRenderNode::LoadGeomCache(const char* sGeomCacheFileName) -{ - Clear(false); - - m_pGeomCache = static_cast(Get3DEngine()->LoadGeomCache(sGeomCacheFileName)); - - if (m_pGeomCache && !m_pGeomCache->IsValid()) - { - m_pGeomCache = NULL; - } - - if (m_pGeomCache) - { - m_currentAABB = m_pGeomCache->GetAABB(); - m_bBoundsChanged = true; - m_pMaterial = m_pGeomCache->GetMaterial(); - - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - m_nodeMatrices.resize(staticNodeData.size()); - uint currentNodeIndex = 0; - InitTransformsRec(currentNodeIndex, staticNodeData, QuatTNS(IDENTITY)); - - m_pGeomCache->AddListener(this); - - if (m_pGeomCache->IsLoaded()) - { - return Initialize(); - } - } - - return true; -} - -void CGeomCacheRenderNode::SetGeomCache(_smart_ptr geomCache) -{ - Clear(false); - - if (geomCache == nullptr || !geomCache->IsValid()) - { - return; - } - - m_pGeomCache = static_cast(geomCache.get()); - - m_currentAABB = m_pGeomCache->GetAABB(); - m_bBoundsChanged = true; - m_pMaterial = m_pGeomCache->GetMaterial(); - - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - m_nodeMatrices.resize(staticNodeData.size()); - uint currentNodeIndex = 0; - InitTransformsRec(currentNodeIndex, staticNodeData, QuatTNS(IDENTITY)); - - m_pGeomCache->AddListener(this); - - if (m_pGeomCache->IsLoaded()) - { - Initialize(); - } -} - -bool CGeomCacheRenderNode::Initialize() -{ - assert(!m_bInitialized); - if (m_bInitialized) - { - return true; - } - - if (m_pGeomCache) - { - if (!InitializeRenderMeshes()) - { - return false; - } - - const std::vector& staticMeshData = m_pGeomCache->GetStaticMeshData(); - - const uint numMeshes = staticMeshData.size(); - for (uint i = 0; i < numMeshes; ++i) - { - const SGeomCacheStaticMeshData& meshData = staticMeshData[i]; - uint numMaterials = meshData.m_materialIds.size(); - - for (uint j = 0; j < numMaterials; ++j) - { - const uint16 materialId = meshData.m_materialIds[j]; - if (m_pRenderElements.find(materialId) == m_pRenderElements.end()) - { - CREGeomCache* pRenderElement = static_cast(GetRenderer()->EF_CreateRE(eDATA_GeomCache)); - - SGeomCacheRenderElementData renderElementData; - renderElementData.m_pRenderElement = pRenderElement; - renderElementData.m_pUpdateState = (volatile int*)NULL; - renderElementData.m_pCurrentFillData = NULL; - - m_pRenderElements[materialId] = renderElementData; - pRenderElement->InitializeRenderElement(numMeshes, &m_renderMeshes[0], materialId); - } - } - } - - GetGeomCacheManager()->RegisterForStreaming(this); - - m_bInitialized = true; - - return true; - } - - return false; -} - -void CGeomCacheRenderNode::Clear(bool bWaitForStreamingJobs) -{ - m_bInitialized = false; - - GetGeomCacheManager()->UnRegisterForStreaming(this, bWaitForStreamingJobs); - - m_renderMeshes.clear(); - m_renderMeshUpdateContexts.clear(); - - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - CREGeomCache* pCREGeomCache = iter->second.m_pRenderElement; - pCREGeomCache->Release(); - } - - m_currentAABB = AABB(0.0f); - m_currentDisplayAABB = AABB(0.0f); - m_pRenderElements.clear(); -} - -void CGeomCacheRenderNode::SetPlaybackTime(const float time) -{ - if (m_pGeomCache) - { - const float duration = m_pGeomCache->GetDuration(); - const bool bInsideTimeRange = (time >= 0.0f && (m_bLooping || time <= duration)); - - float clampedTime = time < 0.0f ? 0.0f : time; - if (!m_bLooping) - { - clampedTime = time > duration ? duration : time; - } - - m_playbackTime = clampedTime; - m_streamingTime = clampedTime; - - if (m_pGeomCache && bInsideTimeRange) - { - StartStreaming(clampedTime); - return; - } - } - - StopStreaming(); -} - -void CGeomCacheRenderNode::StartStreaming(const float time) -{ - if (m_pGeomCache && time >= 0.0f && (m_bLooping || time <= m_pGeomCache->GetDuration())) - { - m_streamingTime = time; - m_bIsStreaming = true; - } -} - -void CGeomCacheRenderNode::StopStreaming() -{ - m_bIsStreaming = false; -} - -bool CGeomCacheRenderNode::IsLooping() const -{ - return m_bLooping; -} - -void CGeomCacheRenderNode::SetLooping(const bool bEnable) -{ - if (m_pGeomCache && m_pGeomCache->GetNumFrames() <= 1) - { - // looping a 1 frame cache is the same as not looping it. However the underlying logic on how we stream and read the GeomCache - // from disk breaks for a 1 frame loop. So we explicitly don't allow looping of a single frame cache, which doesn't make a - // visible difference to the user, since a 1 frame loop looks the same as playing back once. - m_bLooping = false; - } - else - { - m_bLooping = bEnable; - } -} - -bool CGeomCacheRenderNode::IsStreaming() const -{ - return m_bIsStreaming && m_pGeomCache && !m_pGeomCache->PlaybackFromMemory(); -} - -float CGeomCacheRenderNode::GetPrecachedTime() const -{ - return GetGeomCacheManager()->GetPrecachedTime(this); -} - -void CGeomCacheRenderNode::StartAsyncUpdate() -{ - FUNCTION_PROFILER_3DENGINE; - - m_bTransformReady = false; - - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - SGeomCacheRenderElementData& data = iter->second; - CREGeomCache* pCREGeomCache = data.m_pRenderElement; - data.m_pUpdateState = pCREGeomCache->SetAsyncUpdateState(data.m_threadId); - data.m_pCurrentFillData = pCREGeomCache->GetMeshFillDataPtr(); - } - - const std::vector& staticMeshData = m_pGeomCache->GetStaticMeshData(); - - const uint numDynamicRenderMeshes = m_renderMeshUpdateContexts.size(); - for (uint i = 0; i < numDynamicRenderMeshes; ++i) - { - SGeomCacheRenderMeshUpdateContext& updateContext = m_renderMeshUpdateContexts[i]; - - _smart_ptr pRenderMesh = SetupDynamicRenderMesh(updateContext); - m_renderMeshUpdateContexts[i].m_pRenderMesh = pRenderMesh; - - const SGeomCacheStaticMeshData& currentMeshData = staticMeshData[updateContext.m_meshId]; - const uint numMaterials = currentMeshData.m_materialIds.size(); - for (uint j = 0; j < numMaterials; ++j) - { - const uint16 materialId = currentMeshData.m_materialIds[j]; - SGeomCacheRenderElementData& data = m_pRenderElements[materialId]; - CREGeomCache::SMeshRenderData& meshData = (*data.m_pCurrentFillData)[updateContext.m_meshId]; - meshData.m_pRenderMesh = pRenderMesh; - } - } -} - -void CGeomCacheRenderNode::SkipFrameFill() -{ - const uint numDynamicRenderMeshes = m_renderMeshUpdateContexts.size(); - for (uint i = 0; i < numDynamicRenderMeshes; ++i) - { - SGeomCacheRenderMeshUpdateContext& updateContext = m_renderMeshUpdateContexts[i]; - if (updateContext.m_pUpdateState) - { - CryInterlockedDecrement(updateContext.m_pUpdateState); - } - } - - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - CryInterlockedDecrement(iter->second.m_pUpdateState); - } - - m_bTransformReady = true; - m_bTransformReadyCV.Notify(); -} - -bool CGeomCacheRenderNode::FillFrameAsync(const char* const pFloorFrameData, const char* const pCeilFrameData, const float lerpFactor) -{ - FUNCTION_PROFILER_3DENGINE; - - CryAutoLock fillLock(m_fillCS); - - if ((m_renderMeshes.empty() && m_renderMeshUpdateContexts.empty()) - || (!m_renderMeshUpdateContexts.empty() && m_renderMeshUpdateContexts[0].m_pUpdateState == NULL) - || (m_standInVisible != eStandInType_None && m_bFilledFrameOnce)) - { - return false; - } - - const CGeomCache* const pGeomCache = m_pGeomCache; - assert(pGeomCache); - - if (!pGeomCache) - { - return false; - } - - const std::vector& staticMeshData = pGeomCache->GetStaticMeshData(); - const std::vector& staticNodeData = pGeomCache->GetStaticNodeData(); - - const uint numMeshes = staticMeshData.size(); - const uint numNodes = staticNodeData.size(); - - if (numMeshes == 0 || numNodes == 0) - { - return false; - } - - // Computer pointers to mesh & node data in frames - const GeomCacheFile::SFrameHeader* const floorFrameHeader = reinterpret_cast(pFloorFrameData); - const char* pFloorMeshData = pFloorFrameData + sizeof(GeomCacheFile::SFrameHeader); - const char* const pFloorNodeData = pFloorFrameData + sizeof(GeomCacheFile::SFrameHeader) + floorFrameHeader->m_nodeDataOffset; - - const GeomCacheFile::SFrameHeader* const ceilFrameHeader = reinterpret_cast(pCeilFrameData); - const char* pCeilMeshData = pCeilFrameData + sizeof(GeomCacheFile::SFrameHeader); - const char* const pCeilNodeData = pCeilFrameData + sizeof(GeomCacheFile::SFrameHeader) + ceilFrameHeader->m_nodeDataOffset; - - // Update geom cache AABB - AABB floorAABB(Vec3(floorFrameHeader->m_frameAABBMin[0], floorFrameHeader->m_frameAABBMin[1], floorFrameHeader->m_frameAABBMin[2]), - Vec3(floorFrameHeader->m_frameAABBMax[0], floorFrameHeader->m_frameAABBMax[1], floorFrameHeader->m_frameAABBMax[2])); - AABB ceilAABB(Vec3(ceilFrameHeader->m_frameAABBMin[0], ceilFrameHeader->m_frameAABBMin[1], ceilFrameHeader->m_frameAABBMin[2]), - Vec3(ceilFrameHeader->m_frameAABBMax[0], ceilFrameHeader->m_frameAABBMax[1], ceilFrameHeader->m_frameAABBMax[2])); - - m_currentDisplayAABB = floorAABB; - m_currentDisplayAABB.Add(ceilAABB); - - // Update meshes & clear instances - for (uint meshId = 0; meshId < numMeshes; ++meshId) - { - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - SGeomCacheRenderElementData& data = iter->second; - (*data.m_pCurrentFillData)[meshId].m_instances.clear(); - } - } - - // Add instance for current frame - uint currentMeshIndex = 0; - uint currentNodeIndex = 0; - uint currentNodeDataOffset = 0; - - UpdateTransformsRec(currentMeshIndex, currentNodeIndex, staticNodeData, staticMeshData, - currentNodeDataOffset, pFloorNodeData, pCeilNodeData, QuatTNS(IDENTITY), lerpFactor); - - m_bTransformReady = true; - m_bTransformReadyCV.Notify(); - - UpdatePhysicalEntity(NULL); - - uint currentRenderMesh = 0; - for (uint meshId = 0; meshId < numMeshes; ++meshId) - { - const SGeomCacheStaticMeshData* pStaticMeshData = &staticMeshData[meshId]; - if (pStaticMeshData->m_animatedStreams != 0) - { - size_t offsetToNextMesh = 0; - float meshLerpFactor = lerpFactor; - SGeomCacheRenderMeshUpdateContext* pUpdateContext = &m_renderMeshUpdateContexts[currentRenderMesh++]; - - if (GeomCacheDecoder::PrepareFillMeshData(*pUpdateContext, *pStaticMeshData, pFloorMeshData, pCeilMeshData, offsetToNextMesh, meshLerpFactor)) - { - AZ::Job* job = AZ::CreateJobFunction([this, pUpdateContext, pStaticMeshData, pFloorMeshData, pCeilMeshData, meshLerpFactor]() { this->UpdateMesh_JobEntry(pUpdateContext, pStaticMeshData, pFloorMeshData, pCeilMeshData, meshLerpFactor); }, true, nullptr); - job->Start(); - } - else - { - CryInterlockedDecrement(pUpdateContext->m_pUpdateState); - } - - pFloorMeshData += offsetToNextMesh; - pCeilMeshData += offsetToNextMesh; - } - } - - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - SGeomCacheRenderElementData& data = iter->second; - data.m_pRenderElement->DisplayFilledBuffer(data.m_threadId); - CryInterlockedDecrement(iter->second.m_pUpdateState); - } - - m_bFilledFrameOnce = true; - return true; -} - -void CGeomCacheRenderNode::UpdateMesh_JobEntry(SGeomCacheRenderMeshUpdateContext *pUpdateContext, const SGeomCacheStaticMeshData *pStaticMeshData, - const char* pFloorMeshData, const char* pCeilMeshData, float lerpFactor) -{ - GeomCacheDecoder::FillMeshDataFromDecodedFrame(m_bFilledFrameOnce, *pUpdateContext, *pStaticMeshData, pFloorMeshData, pCeilMeshData, lerpFactor); - CryInterlockedDecrement(pUpdateContext->m_pUpdateState); -} - -void CGeomCacheRenderNode::ClearFillData() -{ - FUNCTION_PROFILER_3DENGINE; - - const std::vector& staticMeshData = m_pGeomCache->GetStaticMeshData(); - const uint numMeshes = staticMeshData.size(); - - // Clear dynamic render meshes in fill buffer to release their unused memory - for (uint meshId = 0; meshId < numMeshes; ++meshId) - { - const SGeomCacheStaticMeshData& meshData = staticMeshData[meshId]; - - if (meshData.m_animatedStreams != 0) - { - for (TRenderElementMap::iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - SGeomCacheRenderElementData& data = iter->second; - DynArray* pFillData = data.m_pRenderElement->GetMeshFillDataPtr(); - (*pFillData)[meshId].m_pRenderMesh = NULL; - } - } - } -} - -void CGeomCacheRenderNode::InitTransformsRec(uint& currentNodeIndex, const std::vector& staticNodeData, const QuatTNS& currentTransform) -{ - const SGeomCacheStaticNodeData& currentNodeData = staticNodeData[currentNodeIndex]; - const QuatTNS newTransformQuat = currentTransform * currentNodeData.m_localTransform; - const Matrix34 newTransformMatrix(newTransformQuat); - m_nodeMatrices[currentNodeIndex] = newTransformMatrix; - - currentNodeIndex += 1; - - const uint32 numChildren = currentNodeData.m_numChildren; - for (uint32 i = 0; i < numChildren; ++i) - { - InitTransformsRec(currentNodeIndex, staticNodeData, newTransformQuat); - } -} - -void CGeomCacheRenderNode::UpdateTransformsRec(uint& currentNodeIndex, uint& currentMeshIndex, const std::vector& staticNodeData, - const std::vector& staticMeshData, uint& currentNodeDataOffset, const char* const pFloorNodeData, - const char* const pCeilNodeData, const QuatTNS& currentTransform, const float lerpFactor) -{ - const SGeomCacheStaticNodeData& currentNodeData = staticNodeData[currentNodeIndex]; - - const uint32 floorNodeFlags = *reinterpret_cast(pFloorNodeData + currentNodeDataOffset); - const uint32 ceilNodeFlags = *reinterpret_cast(pCeilNodeData + currentNodeDataOffset); - currentNodeDataOffset += sizeof(uint32); - - QuatTNS newTransformQuat; - - // Update transform - if (currentNodeData.m_transformType == GeomCacheFile::eTransformType_Constant) - { - // Matrix from static data - newTransformQuat = currentTransform * currentNodeData.m_localTransform; - } - else - { - // Matrix from frame data - const QuatTNS* const pFloorTransform = reinterpret_cast(pFloorNodeData + currentNodeDataOffset); - const QuatTNS* const pCeilTransform = reinterpret_cast(pCeilNodeData + currentNodeDataOffset); - - QuatTNS interpolatedTransform; - if (!(floorNodeFlags& GeomCacheFile::eFrameFlags_Hidden) && !(ceilNodeFlags & GeomCacheFile::eFrameFlags_Hidden)) - { - interpolatedTransform.q = Quat::CreateSlerp(pFloorTransform->q, pCeilTransform->q, lerpFactor); - interpolatedTransform.t = Vec3::CreateLerp(pFloorTransform->t, pCeilTransform->t, lerpFactor); - interpolatedTransform.s = Vec3::CreateLerp(pFloorTransform->s, pCeilTransform->s, lerpFactor); - } - else if (!(floorNodeFlags & GeomCacheFile::eFrameFlags_Hidden)) - { - interpolatedTransform = *pFloorTransform; - } - else - { - interpolatedTransform = *pCeilTransform; - } - - newTransformQuat = currentTransform * interpolatedTransform; - currentNodeDataOffset += sizeof(QuatTNS); - } - - Matrix34 newTransformMatrix(newTransformQuat); - - if (currentNodeData.m_type == GeomCacheFile::eNodeType_Mesh) - { - const SGeomCacheStaticMeshData& currentMeshData = staticMeshData[currentNodeData.m_meshOrGeometryIndex]; - - const bool bVisible = ((floorNodeFlags& GeomCacheFile::eFrameFlags_Hidden) == 0); - - if (bVisible) - { - CREGeomCache::SMeshInstance meshInstance; - meshInstance.m_aabb = currentMeshData.m_aabb; - meshInstance.m_matrix = newTransformMatrix; - meshInstance.m_prevMatrix = m_bFilledFrameOnce ? m_nodeMatrices[currentNodeIndex] : newTransformMatrix; - -#ifndef _RELEASE - const int debugDrawMode = GetCVars()->e_GeomCacheDebugDrawMode; - if (debugDrawMode == 0 || debugDrawMode > 2 - || (debugDrawMode == 1 && currentMeshData.m_animatedStreams != 0) - || (debugDrawMode == 2 && currentMeshData.m_animatedStreams == 0)) -#endif - { - const uint numMaterials = currentMeshData.m_materialIds.size(); - for (uint i = 0; i < numMaterials; ++i) - { - const uint16 materialId = currentMeshData.m_materialIds[i]; - SGeomCacheRenderElementData& data = m_pRenderElements[materialId]; - (*data.m_pCurrentFillData)[currentNodeData.m_meshOrGeometryIndex].m_instances.push_back(meshInstance); - } - } - } - } - - m_nodeMatrices[currentNodeIndex] = newTransformMatrix; - - currentNodeIndex += 1; - - const uint32 numChildren = currentNodeData.m_numChildren; - for (uint32 i = 0; i < numChildren; ++i) - { - UpdateTransformsRec(currentNodeIndex, currentMeshIndex, staticNodeData, staticMeshData, currentNodeDataOffset, - pFloorNodeData, pCeilNodeData, newTransformQuat, lerpFactor); - } -} - -void CGeomCacheRenderNode::FillRenderObject(const SRendParams& rendParams, [[maybe_unused]] const SRenderingPassInfo& passInfo, _smart_ptr pMaterial, CRenderObject* pRenderObject) -{ - FUNCTION_PROFILER_3DENGINE; - - - pRenderObject->m_pRenderNode = rendParams.pRenderNode; - pRenderObject->m_fSort = rendParams.fCustomSortOffset; - pRenderObject->m_fDistance = rendParams.fDistance; - - pRenderObject->m_ObjFlags |= FOB_DYNAMIC_OBJECT; - pRenderObject->m_ObjFlags |= rendParams.dwFObjFlags; - - pRenderObject->m_II.m_AmbColor = rendParams.AmbientColor; - - if (rendParams.nTextureID >= 0) - { - pRenderObject->m_nTextureID = rendParams.nTextureID; - } - - pRenderObject->m_II.m_Matrix = *rendParams.pMatrix; - pRenderObject->m_nClipVolumeStencilRef = rendParams.nClipVolumeStencilRef; - pRenderObject->m_fAlpha = rendParams.fAlpha; - pRenderObject->m_DissolveRef = rendParams.nDissolveRef; - - if (rendParams.nAfterWater) - { - pRenderObject->m_ObjFlags |= FOB_AFTER_WATER; - } - else - { - pRenderObject->m_ObjFlags &= ~FOB_AFTER_WATER; - } - - pRenderObject->m_pCurrMaterial = pMaterial; -} - -bool CGeomCacheRenderNode::InitializeRenderMeshes() -{ - const std::vector& staticMeshData = m_pGeomCache->GetStaticMeshData(); - - const uint numMeshes = staticMeshData.size(); - for (uint i = 0; i < numMeshes; ++i) - { - const SGeomCacheStaticMeshData& meshData = staticMeshData[i]; - - IRenderMesh* pRenderMesh = NULL; - - // Only meshes with constant topology for now. TODO: Add support for heterogeneous meshes. - if (meshData.m_animatedStreams == 0) - { - pRenderMesh = GetGeomCacheManager()->GetMeshManager().GetStaticRenderMesh(meshData.m_hash); - - assert(pRenderMesh != NULL); - if (!pRenderMesh) - { - return false; - } - } - else if (meshData.m_animatedStreams != 0) - { - SGeomCacheRenderMeshUpdateContext updateContext; - updateContext.m_prevPositions.resize(meshData.m_numVertices, Vec3(0.0f, 0.0f, 0.0f)); - updateContext.m_meshId = i; - m_renderMeshUpdateContexts.push_back(updateContext); - pRenderMesh = NULL; - } - - m_renderMeshes.push_back(pRenderMesh); - } - - return true; -} - -_smart_ptr CGeomCacheRenderNode::SetupDynamicRenderMesh(SGeomCacheRenderMeshUpdateContext& updateContext) -{ - FUNCTION_PROFILER_3DENGINE; - - const std::vector& staticMeshData = m_pGeomCache->GetStaticMeshData(); - const SGeomCacheStaticMeshData& meshData = staticMeshData[updateContext.m_meshId]; - - // Create zero cleared render mesh - const uint numMaterials = meshData.m_numIndices.size(); - uint numIndices = 0; - for (uint i = 0; i < numMaterials; ++i) - { - numIndices += meshData.m_numIndices[i]; - } - - _smart_ptr pRenderMesh = gEnv->pRenderer->CreateRenderMeshInitialized(NULL, meshData.m_numVertices, - eVF_P3F_C4B_T2F, NULL, numIndices, prtTriangleList, - "GeomCacheDynamicMesh", m_pGeomCache->GetFilePath(), eRMT_Dynamic); - - pRenderMesh->LockForThreadAccess(); - - updateContext.m_pIndices = pRenderMesh->GetIndexPtr(FSL_VIDEO_CREATE); - updateContext.m_pPositions.data = (Vec3*)pRenderMesh->GetPosPtrNoCache(updateContext.m_pPositions.iStride, FSL_VIDEO_CREATE); - updateContext.m_pColors.data = (UCol*)pRenderMesh->GetColorPtr(updateContext.m_pColors.iStride, FSL_VIDEO_CREATE); - updateContext.m_pTexcoords.data = (Vec2*)pRenderMesh->GetUVPtrNoCache(updateContext.m_pTexcoords.iStride, FSL_VIDEO_CREATE); - updateContext.m_pTangents.data = (SPipTangents*)pRenderMesh->GetTangentPtr(updateContext.m_pTangents.iStride, FSL_VIDEO_CREATE); - updateContext.m_pVelocities.data = (Vec3*)pRenderMesh->GetVelocityPtr(updateContext.m_pVelocities.iStride, FSL_VIDEO_CREATE); - - CRenderChunk chunk; - chunk.nNumVerts = meshData.m_numVertices; - uint32 currentIndexOffset = 0; - - std::vector chunks; - chunks.reserve(numMaterials); - - for (uint i = 0; i < numMaterials; ++i) - { - chunk.nFirstIndexId = currentIndexOffset; - chunk.nNumIndices = meshData.m_numIndices[i]; - chunk.m_nMatID = meshData.m_materialIds[i]; - chunks.push_back(chunk); - currentIndexOffset += chunk.nNumIndices; - } - - pRenderMesh->SetRenderChunks(&chunks[0], numMaterials, false); - - updateContext.m_pUpdateState = pRenderMesh->SetAsyncUpdateState(); - pRenderMesh->UnLockForThreadAccess(); - - return pRenderMesh; -} - -void CGeomCacheRenderNode::SetStandIn(const char* pFilePath, const char* pMaterial) -{ - m_pStandIn = Get3DEngine()->LoadStatObjAutoRef(pFilePath); - - if (m_pStandIn) - { - m_pStandIn->SetMaterial(GetMatMan()->LoadMaterial(pMaterial)); - } -} - -void CGeomCacheRenderNode::SetFirstFrameStandIn(const char* pFilePath, const char* pMaterial) -{ - m_pFirstFrameStandIn = Get3DEngine()->LoadStatObjAutoRef(pFilePath); - - if (m_pFirstFrameStandIn) - { - m_pFirstFrameStandIn->SetMaterial(GetMatMan()->LoadMaterial(pMaterial)); - } -} - -void CGeomCacheRenderNode::SetLastFrameStandIn(const char* pFilePath, const char* pMaterial) -{ - m_pLastFrameStandIn = Get3DEngine()->LoadStatObjAutoRef(pFilePath); - - if (m_pLastFrameStandIn) - { - m_pLastFrameStandIn->SetMaterial(GetMatMan()->LoadMaterial(pMaterial)); - } -} - -void CGeomCacheRenderNode::SetStandInDistance(const float distance) -{ - m_standInDistance = distance; -} - -void CGeomCacheRenderNode::SetStreamInDistance(const float distance) -{ - m_streamInDistance = distance; -} - -CGeomCacheRenderNode::EStandInType CGeomCacheRenderNode::SelectStandIn() const -{ - const bool bFirstFrame = m_playbackTime == 0.0f; - const bool bLastFrame = !m_bLooping && (m_pGeomCache ? (m_playbackTime >= m_pGeomCache->GetDuration()) : false); - - if (bFirstFrame && m_pFirstFrameStandIn && m_pFirstFrameStandIn->GetRenderMesh()) - { - return eStandInType_FirstFrame; - } - else if (bLastFrame && m_pLastFrameStandIn && m_pLastFrameStandIn->GetRenderMesh()) - { - return eStandInType_LastFrame; - } - else if (m_pStandIn && m_pStandIn->GetRenderMesh()) - { - return eStandInType_Default; - } - - return eStandInType_None; -} - -IStatObj* CGeomCacheRenderNode::GetStandIn(const EStandInType type) const -{ - switch (type) - { - case eStandInType_Default: - return m_pStandIn; - case eStandInType_FirstFrame: - return m_pFirstFrameStandIn; - case eStandInType_LastFrame: - return m_pLastFrameStandIn; - } - - return NULL; -} - -void CGeomCacheRenderNode::DebugDraw(const SGeometryDebugDrawInfo& info, float fExtrudeScale, uint nodeIndex) const -{ - CryAutoLock fillLock(m_fillCS); - - if (!m_bDrawing) - { - return; - } - - switch (m_standInVisible) - { - case eStandInType_None: - { - if (m_pGeomCache && m_nodeMatrices.size() > 0) - { - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - nodeIndex = std::min(nodeIndex, (uint)(staticNodeData.size() - 1)); - DebugDrawRec(info, fExtrudeScale, nodeIndex, staticNodeData); - } - break; - } - case eStandInType_Default: - { - m_pStandIn->DebugDraw(info, fExtrudeScale); - break; - } - case eStandInType_FirstFrame: - { - m_pFirstFrameStandIn->DebugDraw(info, fExtrudeScale); - break; - } - case eStandInType_LastFrame: - { - m_pLastFrameStandIn->DebugDraw(info, fExtrudeScale); - break; - } - } -} - -void CGeomCacheRenderNode::DebugDrawRec(const SGeometryDebugDrawInfo& info, float fExtrudeScale, - uint& currentNodeIndex, const std::vector& staticNodeData) const -{ - const SGeomCacheStaticNodeData& currentNodeData = staticNodeData[currentNodeIndex]; - - if (currentNodeData.m_type == GeomCacheFile::eNodeType_Mesh) - { - for (TRenderElementMap::const_iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - CREGeomCache* pCREGeomCache = iter->second.m_pRenderElement; - DynArray* pFillData = pCREGeomCache->GetRenderDataPtr(); - - if (pFillData) - { - CREGeomCache::SMeshRenderData& renderData = (*pFillData)[currentNodeData.m_meshOrGeometryIndex]; - IRenderMesh* pRenderMesh = renderData.m_pRenderMesh.get(); - - if (renderData.m_instances.size() > 0 && pRenderMesh) - { - Matrix34 pieceMatrix = m_matrix * m_nodeMatrices[currentNodeIndex]; - - SGeometryDebugDrawInfo subInfo = info; - subInfo.tm = pieceMatrix; - - pRenderMesh->DebugDraw(subInfo, ~0, fExtrudeScale); - break; - } - } - } - } - - currentNodeIndex += 1; - - const uint32 numChildren = currentNodeData.m_numChildren; - for (uint32 i = 0; i < numChildren; ++i) - { - DebugDrawRec(info, fExtrudeScale, currentNodeIndex, staticNodeData); - } -} - -bool CGeomCacheRenderNode::RayIntersectionRec(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl, uint* pHitNodeIndex, - uint& currentNodeIndex, const std::vector& staticNodeData, SRayHitInfo& hitOut, float& fMinDistance) const -{ - const SGeomCacheStaticNodeData& currentNodeData = staticNodeData[currentNodeIndex]; - - bool bHit = false; - - if (currentNodeData.m_type == GeomCacheFile::eNodeType_Mesh) - { - for (TRenderElementMap::const_iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - CREGeomCache* pCREGeomCache = iter->second.m_pRenderElement; - DynArray* pFillData = pCREGeomCache->GetRenderDataPtr(); - - if (pFillData) - { - CREGeomCache::SMeshRenderData& renderData = (*pFillData)[currentNodeData.m_meshOrGeometryIndex]; - IRenderMesh* pRenderMesh = renderData.m_pRenderMesh.get(); - - if (renderData.m_instances.size() > 0 && pRenderMesh) - { - Matrix34 pieceMatrix = m_matrix * m_nodeMatrices[currentNodeIndex]; - - AABB meshAABB = m_pGeomCache->GetStaticMeshData()[currentNodeData.m_meshOrGeometryIndex].m_aabb; - - AABB pieceWorldAABB; - pieceWorldAABB.SetTransformedAABB(pieceMatrix, meshAABB); - - Vec3 vOut; - if (!Intersect::Ray_AABB(hitInfo.inRay, pieceWorldAABB, vOut)) - { - continue; - } - - Matrix34 invPieceMatrix = pieceMatrix.GetInverted(); - - // Transform ray into sub-object local space. - SRayHitInfo subHitInfo = hitInfo; - ZeroStruct(subHitInfo); - subHitInfo.inReferencePoint = invPieceMatrix.TransformPoint(hitInfo.inReferencePoint); - subHitInfo.inRay.origin = invPieceMatrix.TransformPoint(hitInfo.inRay.origin); - subHitInfo.inRay.direction = invPieceMatrix.TransformVector(hitInfo.inRay.direction); - - if (CRenderMeshUtils::RayIntersection(pRenderMesh, subHitInfo, NULL)) - { - const uint materialId = iter->first; - _smart_ptr pMaterial = const_cast(this)->GetMaterial(NULL); - _smart_ptr pSubMaterial = pMaterial->GetSafeSubMtl(materialId); - - if (subHitInfo.nHitMatID == materialId) - { - subHitInfo.vHitPos = pieceMatrix.TransformPoint(subHitInfo.vHitPos); - subHitInfo.fDistance = hitInfo.inReferencePoint.GetDistance(subHitInfo.vHitPos); - - if (subHitInfo.fDistance < fMinDistance) - { - bHit = true; - fMinDistance = subHitInfo.fDistance; - hitOut = subHitInfo; - - hitOut.nHitMatID = materialId; - if (pSubMaterial) - { - hitInfo.nHitSurfaceID = pSubMaterial->GetSurfaceTypeId(); - } - - if (pHitNodeIndex) - { - *pHitNodeIndex = currentNodeIndex; - } - } - } - } - } - } - } - } - - currentNodeIndex += 1; - - const uint32 numChildren = currentNodeData.m_numChildren; - for (uint32 i = 0; i < numChildren; ++i) - { - bHit = RayIntersectionRec(hitInfo, pCustomMtl, pHitNodeIndex, currentNodeIndex, staticNodeData, hitOut, fMinDistance) || bHit; - } - - return bHit; -} - -#ifndef _RELEASE -void CGeomCacheRenderNode::DebugRender() -{ - if (m_pGeomCache && GetCVars()->e_GeomCacheDebugDrawMode == 3) - { - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - uint currentNodeIndex = 0; - InstancingDebugDrawRec(currentNodeIndex, staticNodeData); - } -} - -void CGeomCacheRenderNode::InstancingDebugDrawRec(uint& currentNodeIndex, const std::vector& staticNodeData) -{ - CryAutoLock fillLock(m_fillCS); - - const SGeomCacheStaticNodeData& currentNodeData = staticNodeData[currentNodeIndex]; - - ColorF colors[] = { - Col_Aquamarine, Col_Blue, Col_BlueViolet, Col_Brown, Col_CadetBlue, Col_Coral, Col_CornflowerBlue, Col_Cyan, - Col_DimGrey, Col_FireBrick, Col_ForestGreen, Col_Gold, Col_Goldenrod, Col_Gray, Col_Green, Col_GreenYellow, Col_IndianRed, Col_Khaki, - Col_LightBlue, Col_LightGray, Col_LightSteelBlue, Col_LightWood, Col_LimeGreen, Col_Magenta, Col_Maroon, Col_MedianWood, Col_MediumAquamarine, - Col_MediumBlue, Col_MediumForestGreen, Col_MediumGoldenrod, Col_MediumOrchid, Col_MediumSeaGreen, Col_MediumSlateBlue, Col_MediumSpringGreen, - Col_MediumTurquoise, Col_MediumVioletRed, Col_MidnightBlue, Col_Navy, Col_NavyBlue, Col_Orange, Col_OrangeRed, Col_Orchid, Col_PaleGreen, - Col_Pink, Col_Plum, Col_Red, Col_Salmon, Col_SeaGreen, Col_Sienna, Col_SkyBlue, Col_SlateBlue, Col_SpringGreen, Col_SteelBlue, Col_Tan, - Col_Thistle, Col_Transparent, Col_Turquoise, Col_Violet, Col_VioletRed, Col_Wheat, Col_Yellow - }; - - const uint kNumColors = sizeof(colors) / sizeof(ColorF); - - if (currentNodeData.m_type == GeomCacheFile::eNodeType_Mesh) - { - for (TRenderElementMap::const_iterator iter = m_pRenderElements.begin(); iter != m_pRenderElements.end(); ++iter) - { - CREGeomCache* pCREGeomCache = iter->second.m_pRenderElement; - DynArray* pFillData = pCREGeomCache->GetRenderDataPtr(); - - if (pFillData) - { - CREGeomCache::SMeshRenderData& renderData = (*pFillData)[currentNodeData.m_meshOrGeometryIndex]; - IRenderMesh* pRenderMesh = renderData.m_pRenderMesh.get(); - - if (renderData.m_instances.size() > 0 && pRenderMesh) - { - Matrix34 pieceMatrix = m_matrix * m_nodeMatrices[currentNodeIndex]; - - SGeometryDebugDrawInfo info; - info.bNoLines = true; - info.bExtrude = false; - info.tm = pieceMatrix; - - const uint64 kMul = 0x9ddfea08eb382d69ULL; - uint64 hash = (uint64)alias_cast(pRenderMesh); - hash ^= (hash >> 47); - hash *= kMul; - - info.color = colors[hash % kNumColors]; - - pRenderMesh->DebugDraw(info); - break; - } - } - } - } - - currentNodeIndex += 1; - - const uint32 numChildren = currentNodeData.m_numChildren; - for (uint32 i = 0; i < numChildren; ++i) - { - InstancingDebugDrawRec(currentNodeIndex, staticNodeData); - } -} -#endif - -bool CGeomCacheRenderNode::RayIntersection(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl, uint* pNodeIndex) const -{ - CryAutoLock fillLock(m_fillCS); - - switch (m_standInVisible) - { - case eStandInType_None: - { - if (m_pGeomCache && m_nodeMatrices.size() > 0) - { - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - - SRayHitInfo hitOut; - float fMinDistance = std::numeric_limits::max(); - uint currentNodeIndex = 0; - - if (RayIntersectionRec(hitInfo, pCustomMtl, pNodeIndex, currentNodeIndex, staticNodeData, hitOut, fMinDistance)) - { - // Restore input ray/reference point. - hitOut.inReferencePoint = hitInfo.inReferencePoint; - hitOut.inRay = hitInfo.inRay; - hitOut.fDistance = fMinDistance; - - hitInfo = hitOut; - return true; - } - } - break; - } - case eStandInType_Default: - { - return m_pStandIn->RayIntersection(hitInfo, pCustomMtl); - } - case eStandInType_FirstFrame: - { - return m_pFirstFrameStandIn->RayIntersection(hitInfo, pCustomMtl); - } - case eStandInType_LastFrame: - { - return m_pLastFrameStandIn->RayIntersection(hitInfo, pCustomMtl); - } - } - - return false; -} - -uint CGeomCacheRenderNode::GetNodeCount() const -{ - if (!m_pGeomCache) - { - return 0; - } - - const uint numNodes = m_pGeomCache->GetStaticNodeData().size(); - return numNodes; -} - -Matrix34 CGeomCacheRenderNode::GetNodeTransform(const uint nodeIndex) const -{ - FUNCTION_PROFILER_3DENGINE; - - { - CryAutoLock lock(m_bTransformsReadyCS); - while (!m_bTransformReady) - { - m_bTransformReadyCV.Wait(m_bTransformsReadyCS); - } - } - - if (nodeIndex >= m_nodeMatrices.size() || !m_pGeomCache) - { - return Matrix34(IDENTITY); - } - - return m_nodeMatrices[nodeIndex]; -} - -const char* CGeomCacheRenderNode::GetNodeName(const uint nodeIndex) const -{ - if (!m_pGeomCache) - { - return ""; - } - - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - return staticNodeData[nodeIndex].m_name.c_str(); -} - -uint32 CGeomCacheRenderNode::GetNodeNameHash(const uint nodeIndex) const -{ - if (!m_pGeomCache) - { - return 0; - } - - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - return staticNodeData[nodeIndex].m_nameHash; -} - -bool CGeomCacheRenderNode::IsNodeDataValid(const uint nodeIndex) const -{ - FUNCTION_PROFILER_3DENGINE; - - { - CryAutoLock lock(m_bTransformsReadyCS); - while (!m_bTransformReady) - { - m_bTransformReadyCV.Wait(m_bTransformsReadyCS); - } - } - - if (nodeIndex >= m_nodeMatrices.size() || !m_pGeomCache) - { - return false; - } - - return true; -} - -void CGeomCacheRenderNode::InitPhysicalEntity(IPhysicalEntity* pPhysicalEntity, const pe_articgeomparams& params) -{ - m_pPhysicalEntity = pPhysicalEntity; - UpdatePhysicalEntity(¶ms); -} - -void CGeomCacheRenderNode::UpdatePhysicalEntity(const pe_articgeomparams* pParams) -{ - if (!m_pPhysicalEntity) - { - return; - } - - const std::vector& staticNodeData = m_pGeomCache->GetStaticNodeData(); - const std::vector& physicsGeometries = m_pGeomCache->GetPhysicsGeometries(); - - Matrix34 scaleMatrix = GetMatrix(); - const Vec3 scale = Vec3(scaleMatrix.GetColumn0().GetLength(), scaleMatrix.GetColumn1().GetLength(), scaleMatrix.GetColumn2().GetLength()); - scaleMatrix.SetScale(scale); - - const uint numNodes = staticNodeData.size(); - for (uint i = 0; i < numNodes; ++i) - { - const SGeomCacheStaticNodeData& nodeData = staticNodeData[i]; - if (nodeData.m_type == GeomCacheFile::eNodeType_PhysicsGeometry) - { - const Matrix34 nodeTransform = GetNodeTransform(i); - phys_geometry* pGeometry = physicsGeometries[nodeData.m_meshOrGeometryIndex]; - if (pGeometry) - { - Matrix34 nodeMatrix = scaleMatrix * nodeTransform; - - if (pParams) - { - pe_articgeomparams params = *pParams; - m_pPhysicalEntity->AddGeometry(pGeometry, ¶ms, i); - } - - pe_params_part params; - params.pMtx3x4 = &nodeMatrix; - params.partid = i; - m_pPhysicalEntity->SetParams(¶ms); - } - } - } -} - -void CGeomCacheRenderNode::UpdatePhysicalMaterials() -{ - if (m_pPhysicalEntity && m_pMaterial) - { - int surfaceTypesId[MAX_SUB_MATERIALS] = { 0 }; - const int numIds = m_pMaterial->FillSurfaceTypeIds(surfaceTypesId); - - pe_params_part params; - params.nMats = numIds; - params.pMatMapping = surfaceTypesId; - m_pPhysicalEntity->SetParams(¶ms); - } -} - -void CGeomCacheRenderNode::UpdateStreamableComponents(float fImportance, float fDistance, bool bFullUpdate, int nLod, const float fInvScale, bool bDrawNear) -{ - Matrix34A matrix = GetMatrix(); - - const bool bAllowStandIn = GetCVars()->e_Lods != 0; - const bool bStreamInGeomCache = !m_pStandIn || (fDistance <= std::max(m_standInDistance, m_streamInDistance)) || !bAllowStandIn; - if (m_pGeomCache && bStreamInGeomCache) - { - m_pGeomCache->UpdateStreamableComponents(fImportance, matrix, this, bFullUpdate); - } - - static_cast(m_pMaterial.get())->PrecacheMaterial(fDistance * fInvScale, NULL, bFullUpdate, bDrawNear); - - PrecacheStandIn(m_pStandIn, fImportance, fDistance, bFullUpdate, nLod, fInvScale, bDrawNear); - PrecacheStandIn(m_pFirstFrameStandIn, fImportance, fDistance, bFullUpdate, nLod, fInvScale, bDrawNear); - PrecacheStandIn(m_pLastFrameStandIn, fImportance, fDistance, bFullUpdate, nLod, fInvScale, bDrawNear); -} - -void CGeomCacheRenderNode::PrecacheStandIn(IStatObj* pStandIn, float fImportance, float fDistance, bool bFullUpdate, int nLod, const float fInvScale, bool bDrawNear) -{ - if (pStandIn) - { - IStatObj* pLod = pStandIn->GetLodObject(nLod, true); - if (pLod) - { - IObjManager* pObjManager = GetObjManager(); - Matrix34A matrix = GetMatrix(); - static_cast(pLod)->UpdateStreamableComponents(fImportance, matrix, bFullUpdate, nLod); - pObjManager->PrecacheStatObjMaterial(pLod->GetMaterial(), fDistance * fInvScale, pLod, bFullUpdate, bDrawNear); - } - } -} - -void CGeomCacheRenderNode::OnGeomCacheStaticDataLoaded() -{ - Initialize(); -} - -void CGeomCacheRenderNode::OnGeomCacheStaticDataUnloaded() -{ - Clear(false); -} - -#endif diff --git a/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.h b/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.h deleted file mode 100644 index 4181cb8224..0000000000 --- a/Code/CryEngine/Cry3DEngine/GeomCacheRenderNode.h +++ /dev/null @@ -1,287 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Draws geometry caches - - -#ifndef CRYINCLUDE_CRY3DENGINE_GEOMCACHERENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_GEOMCACHERENDERNODE_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include "GeomCache.h" -#include "GeomCacheDecoder.h" - -struct SGeomCacheRenderMeshUpdateContext -{ - SGeomCacheRenderMeshUpdateContext() - : m_meshId(0) - , m_pRenderMesh(NULL) - , m_pUpdateState(NULL) - , m_pIndices(NULL) {} - - // Information needed to create the render mesh each frame - uint m_meshId; - - // The render mesh - _smart_ptr m_pRenderMesh; - - // Locks the render mesh from rendering until it was filled - volatile int* m_pUpdateState; - - // Previous positions for motion blur - stl::aligned_vector m_prevPositions; - - // Data pointers for updating - vtx_idx* m_pIndices; - strided_pointer m_pPositions; - strided_pointer m_pColors; - strided_pointer m_pTexcoords; - strided_pointer m_pTangents; - strided_pointer m_pVelocities; -}; - -struct SGeomCacheRenderElementData -{ - CREGeomCache* m_pRenderElement; - volatile int* m_pUpdateState; - int m_threadId; - DynArray* m_pCurrentFillData; -}; - -class CGeomCacheRenderNode - : public IGeomCacheRenderNode - , public IGeomCacheListener - , public Cry3DEngineBase -{ -public: - CGeomCacheRenderNode(); - virtual ~CGeomCacheRenderNode(); - - virtual const char* GetName() const; - virtual const char* GetEntityClassName() const; - virtual EERType GetRenderNodeType() { return eERType_GeomCache; } - - virtual Vec3 GetPos(bool bWorldOnly) const; - virtual void SetBBox(const AABB& WSBBox); - virtual const AABB GetBBox() const; - virtual void GetLocalBounds(AABB& bbox); - - // Called before rendering to update to current frame bbox - void UpdateBBox(); - - virtual void Render(const struct SRendParams& entDrawParams, const SRenderingPassInfo& passInfo); - - void SetMatrix(const Matrix34& matrix); - const Matrix34& GetMatrix() const { return m_matrix; } - - virtual void SetMaterial(_smart_ptr pMat); - virtual _smart_ptr GetMaterial(Vec3* pHitPos); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - - void SetBaseMaxViewDistance(float maxViewDistance) override { m_maxViewDist = maxViewDistance; } - virtual float GetMaxViewDist(); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - - // Streaming - float GetStreamingTime() const { return std::max(m_streamingTime, m_playbackTime); } - - // Called for starting the update job in CGeomCacheManager - void StartAsyncUpdate(); - - // Called by fill job if it didn't call FillFrameAsync because data wasn't available - void SkipFrameFill(); - - // Called from the update job in CGeomCacheManager - bool FillFrameAsync(const char* const pFloorFrameData, const char* const pCeilFrameData, const float lerpFactor); - - // Called from FillFrameAsync - void UpdateMesh_JobEntry(SGeomCacheRenderMeshUpdateContext *pUpdateContext, const SGeomCacheStaticMeshData *pStaticMeshData, - const char* pFloorMeshData, const char* pCeilMeshData, float lerpFactor); - - // Called from CGeomCacheManager when playback stops - void ClearFillData(); - - // Called from CObjManager to update streaming - void UpdateStreamableComponents(float fImportance, float fDistance, bool bFullUpdate, int nLod, const float fInvScale, bool bDrawNear); - - // IGeomCacheRenderNode - virtual bool LoadGeomCache(const char* sGeomCacheFileName); - void SetGeomCache(_smart_ptr geomCache) override; - - virtual void SetPlaybackTime(const float time); - virtual float GetPlaybackTime() const { return m_playbackTime; } - - virtual bool IsStreaming() const; - virtual void StartStreaming(const float time); - virtual void StopStreaming(); - virtual bool IsLooping() const; - virtual void SetLooping(const bool bEnable); - virtual float GetPrecachedTime() const; - - virtual IGeomCache* GetGeomCache() const { return m_pGeomCache; } - - virtual bool DidBoundsChange(); - - virtual void SetDrawing(bool bDrawing) { m_bDrawing = bDrawing; } - - // Set stand in CGFs and distance - virtual void SetStandIn(const char* pFilePath, const char* pMaterial); - IStatObj* GetStandIn() override { return m_pStandIn; } - virtual void SetFirstFrameStandIn(const char* pFilePath, const char* pMaterial); - IStatObj* GetFirstFrameStandIn() override { return m_pFirstFrameStandIn; } - virtual void SetLastFrameStandIn(const char* pFilePath, const char* pMaterial); - IStatObj* GetLastFrameStandIn() override { return m_pLastFrameStandIn; } - virtual void SetStandInDistance(const float distance); - float GetStandInDistance() override { return m_standInDistance; } - - // Set distance at which cache will start streaming automatically (0 means no auto streaming) - virtual void SetStreamInDistance(const float distance); - float GetStreamInDistance() override { return m_streamInDistance; } - - virtual void DebugDraw(const SGeometryDebugDrawInfo& info, float fExtrudeScale, uint nodeIndex) const; - virtual bool RayIntersection(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl, uint* pHitNodeIndex) const; - - // Get node information - virtual uint GetNodeCount() const; - virtual Matrix34 GetNodeTransform(const uint nodeIndex) const; - virtual const char* GetNodeName(const uint nodeIndex) const; - virtual uint32 GetNodeNameHash(const uint nodeIndex) const; - virtual bool IsNodeDataValid(const uint nodeIndex) const; - - // Physics - virtual void InitPhysicalEntity(IPhysicalEntity* pPhysicalEntity, const pe_articgeomparams& params); - - void OffsetPosition([[maybe_unused]] const Vec3& delta) {} - -#ifndef _RELEASE - void DebugRender(); -#endif - -private: - void CalcBBox(); - - void FillRenderObject(const SRendParams& rendParams, const SRenderingPassInfo& passInfo, _smart_ptr pMaterial, CRenderObject* pRenderObject); - - bool Initialize(); - bool InitializeRenderMeshes(); - _smart_ptr SetupDynamicRenderMesh(SGeomCacheRenderMeshUpdateContext& updateContext); - - void Clear(bool bWaitForStreamingJobs); - - void InitTransformsRec(uint& currentNodeIndex, const std::vector& staticNodeData, const QuatTNS& currentTransform); - - void UpdateTransformsRec(uint& currentNodeIndex, uint& currentMeshIndex, const std::vector& staticNodeData, - const std::vector& staticMeshData, uint& currentNodeDataOffset, const char* const pFloorNodeData, - const char* const pCeilNodeData, const QuatTNS& currentTransform, const float lerpFactor); - - // IGeomCacheListener - virtual void OnGeomCacheStaticDataLoaded(); - virtual void OnGeomCacheStaticDataUnloaded(); - - void DebugDrawRec(const SGeometryDebugDrawInfo& info, float fExtrudeScale, - uint& currentNodeIndex, const std::vector& staticNodeData) const; - bool RayIntersectionRec(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl, uint* pHitNodeIndex, - uint& currentNodeIndex, const std::vector& staticNodeData, - SRayHitInfo& hitOut, float& fMinDistance) const; - -#ifndef _RELEASE - void InstancingDebugDrawRec(uint& currentNodeIndex, const std::vector& staticNodeData); -#endif - - enum EStandInType - { - eStandInType_None, - eStandInType_Default, - eStandInType_FirstFrame, - eStandInType_LastFrame - }; - - EStandInType SelectStandIn() const; - IStatObj* GetStandIn(const EStandInType type) const; - - void PrecacheStandIn(IStatObj* pStandIn, float fImportance, float fDistance, bool bFullUpdate, int nLod, const float fInvScale, bool bDrawNear); - - void UpdatePhysicalEntity(const pe_articgeomparams* pParams); - void UpdatePhysicalMaterials(); - - // Material ID -> render element data + update state pointer - typedef AZStd::unordered_map TRenderElementMap; - TRenderElementMap m_pRenderElements; - - // Saved node transforms for motion blur and attachments - std::vector m_nodeMatrices; - - // All render meshes - std::vector<_smart_ptr > m_renderMeshes; - - // Update contexts for render meshes - std::vector m_renderMeshUpdateContexts; - - // Override material - _smart_ptr m_pMaterial; - - // The rendered cache - _smart_ptr m_pGeomCache; - - // World space matrix - Matrix34 m_matrix; - - // Playback - volatile float m_playbackTime; - - // Streaming flag - volatile float m_streamingTime; - - // Misc - IPhysicalEntity* m_pPhysicalEntity; - float m_maxViewDist; - - // World space bounding box - AABB m_bBox; - - // AABB of current displayed frame and render buffer - AABB m_currentAABB; - AABB m_currentDisplayAABB; - - // Used for editor debug rendering & ray intersection - mutable CryCriticalSection m_fillCS; - - // Transform ready sync - mutable CryMutex m_bTransformsReadyCS; - mutable CryConditionVariable m_bTransformReadyCV; - - // Stand in stat objects - EStandInType m_standInVisible; - _smart_ptr m_pStandIn; - _smart_ptr m_pFirstFrameStandIn; - _smart_ptr m_pLastFrameStandIn; - float m_standInDistance; - - // Distance at which render node will automatically start streaming - float m_streamInDistance; - - // Flags - volatile bool m_bInitialized; - bool m_bLooping; - volatile bool m_bIsStreaming; - bool m_bFilledFrameOnce; - bool m_bBoundsChanged; - bool m_bDrawing; - bool m_bTransformReady; -}; - -#endif -#endif // CRYINCLUDE_CRY3DENGINE_GEOMCACHERENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/IndexedMesh.cpp b/Code/CryEngine/Cry3DEngine/IndexedMesh.cpp deleted file mode 100644 index 3768c73433..0000000000 --- a/Code/CryEngine/Cry3DEngine/IndexedMesh.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "IndexedMesh.h" -#include "MeshCompiler/MeshCompiler.h" - -DEFINE_INTRUSIVE_LINKED_LIST(CIndexedMesh) - -CIndexedMesh::CIndexedMesh() -{ -} - -CIndexedMesh::~CIndexedMesh() -{ -} - -void CIndexedMesh::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - CMesh::GetMemoryUsage(pSizer); -} - -void CIndexedMesh::RestoreFacesFromIndices() -{ - const int indexCount = GetIndexCount(); - SetFaceCount(indexCount / 3); - memset(m_pFaces, 0, GetFaceCount() * sizeof(m_pFaces[0])); - - int nFaceId = 0; - for (int i = 0; i < indexCount; i += 3) - { - if (m_pIndices[i] != (vtx_idx) - 1) // deleted faces have -1 here - { - for (int v = 0; v < 3; ++v) - { - assert((int)m_pIndices[i + v] < GetVertexCount()); - m_pFaces[nFaceId].v[v] = m_pIndices[i + v]; - } - ++nFaceId; - } - } - - SetFaceCount(nFaceId); -} - -void CIndexedMesh::Optimize(const char* szComment) -{ - mesh_compiler::CMeshCompiler meshCompiler; - - if (szComment) - { - // mesh_compiler::MESH_COMPILE_OPTIMIZE is a bit expensive so we show a warning if it's used at run time - Warning("CIndexedMesh::Optimize is called at run time by %s", szComment); - } - - if (!meshCompiler.Compile(*this, (mesh_compiler::MESH_COMPILE_TANGENTS | mesh_compiler::MESH_COMPILE_OPTIMIZE))) - { - Warning("CIndexedMesh::Optimize failed: %s", meshCompiler.GetLastError()); - } -} - -void CIndexedMesh::CalcBBox() -{ - const int vertexCount = GetVertexCount(); - - if (vertexCount == 0 || !m_pPositions) - { - m_bbox = AABB(Vec3(0, 0, 0), Vec3(0, 0, 0)); - return; - } - - assert(m_pPositionsF16 == 0); - - m_bbox.Reset(); - - const int faceCount = GetFaceCount(); - - if (faceCount > 0) - { - for (int i = 0; i < faceCount; ++i) - { - for (int v = 0; v < 3; ++v) - { - const int nIndex = m_pFaces[i].v[v]; - assert(nIndex >= 0 && nIndex < vertexCount); - m_bbox.Add(m_pPositions[nIndex]); - } - } - } - else - { - const int indexCount = GetIndexCount(); - - for (int i = 0; i < indexCount; ++i) - { - m_bbox.Add(m_pPositions[m_pIndices[i]]); - } - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/IndexedMesh.h b/Code/CryEngine/Cry3DEngine/IndexedMesh.h deleted file mode 100644 index 7f50843728..0000000000 --- a/Code/CryEngine/Cry3DEngine/IndexedMesh.h +++ /dev/null @@ -1,202 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_INDEXEDMESH_H -#define CRYINCLUDE_CRY3DENGINE_INDEXEDMESH_H -#pragma once - -#include "CryArray.h" -#include "CryHeaders.h" -#include "IIndexedMesh.h" - -class CIndexedMesh - : public IIndexedMesh - , public CMesh - , public stl::intrusive_linked_list_node - , public Cry3DEngineBase -{ -public: - CIndexedMesh(); - virtual ~CIndexedMesh(); - - ////////////////////////////////////////////////////////////////////////// - // IIndexedMesh - ////////////////////////////////////////////////////////////////////////// - - virtual void Release() - { - delete this; - } - - // gives read-only access to mesh data - virtual void GetMeshDescription(SMeshDescription& meshDesc) const - { - meshDesc.m_pFaces = m_pFaces; - meshDesc.m_pVerts = m_pPositions; - meshDesc.m_pVertsF16 = m_pPositionsF16; - meshDesc.m_pNorms = m_pNorms; - meshDesc.m_pColor = m_pColor0; - meshDesc.m_pTexCoord = m_pTexCoord; - meshDesc.m_pIndices = m_pIndices; - meshDesc.m_nFaceCount = GetFaceCount(); - meshDesc.m_nVertCount = GetVertexCount(); - meshDesc.m_nCoorCount = GetTexCoordCount(); - meshDesc.m_nIndexCount = GetIndexCount(); - } - - virtual CMesh* GetMesh() - { - return this; - } - - virtual void SetMesh(CMesh& mesh) - { - Copy(mesh); - } - - virtual void FreeStreams() - { - return CMesh::FreeStreams(); - } - - virtual int GetFaceCount() const - { - return CMesh::GetFaceCount(); - } - - virtual void SetFaceCount(int nNewCount) - { - CMesh::SetFaceCount(nNewCount); - } - - virtual int GetVertexCount() const - { - return CMesh::GetVertexCount(); - } - - virtual void SetVertexCount(int nNewCount) - { - CMesh::SetVertexCount(nNewCount); - } - - virtual void SetColorCount(int nNewCount) - { - CMesh::ReallocStream(COLORS, 0, nNewCount); - } - - virtual int GetTexCoordCount() const - { - return CMesh::GetTexCoordCount(); - } - - virtual void SetTexCoordCount(int nNewCount, int numStreams = 1) - { - for (int i = 0; i < numStreams; ++i) - { - CMesh::ReallocStream(TEXCOORDS, i, nNewCount); - } - } - - virtual int GetTangentCount() const - { - return CMesh::GetTangentCount(); - } - - virtual void SetTangentCount(int nNewCount) - { - CMesh::ReallocStream(TANGENTS, 0, nNewCount); - } - - virtual void SetTexCoordsAndTangentsCount(int nNewCount) - { - CMesh::SetTexCoordsAndTangentsCount(nNewCount); - } - - virtual int GetIndexCount() const - { - return CMesh::GetIndexCount(); - } - - virtual void SetIndexCount(int nNewCount) - { - CMesh::SetIndexCount(nNewCount); - } - - virtual void AllocateBoneMapping() - { - ReallocStream(BONEMAPPING, 0, GetVertexCount()); - } - - virtual int GetSubSetCount() const - { - return m_subsets.size(); - } - - virtual void SetSubSetCount(int nSubsets) - { - m_subsets.resize(nSubsets); - } - - virtual const SMeshSubset& GetSubSet(int nIndex) const - { - return m_subsets[nIndex]; - } - - virtual void SetSubsetBounds(int nIndex, const Vec3& vCenter, float fRadius) - { - m_subsets[nIndex].vCenter = vCenter; - m_subsets[nIndex].fRadius = fRadius; - } - - virtual void SetSubsetIndexVertexRanges(int nIndex, int nFirstIndexId, int nNumIndices, int nFirstVertId, int nNumVerts) - { - m_subsets[nIndex].nFirstIndexId = nFirstIndexId; - m_subsets[nIndex].nNumIndices = nNumIndices; - m_subsets[nIndex].nFirstVertId = nFirstVertId; - m_subsets[nIndex].nNumVerts = nNumVerts; - } - - virtual void SetSubsetMaterialId(int nIndex, int nMatID) - { - m_subsets[nIndex].nMatID = nMatID; - } - - virtual void SetSubsetMaterialProperties(int nIndex, int nMatFlags, int nPhysicalizeType, const AZ::Vertex::Format& vertexFormat) - { - m_subsets[nIndex].nMatFlags = nMatFlags; - m_subsets[nIndex].nPhysicalizeType = nPhysicalizeType; - m_subsets[nIndex].vertexFormat = vertexFormat; - } - - virtual AABB GetBBox() const - { - return m_bbox; - } - - virtual void SetBBox(const AABB& box) - { - m_bbox = box; - } - - virtual void CalcBBox(); - - virtual void Optimize(const char* szComment = NULL); - - virtual void RestoreFacesFromIndices(); - - ////////////////////////////////////////////////////////////////////////// - - void GetMemoryUsage(class ICrySizer* pSizer) const; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_INDEXEDMESH_H diff --git a/Code/CryEngine/Cry3DEngine/LightEntity.cpp b/Code/CryEngine/Cry3DEngine/LightEntity.cpp deleted file mode 100644 index 2bd410b918..0000000000 --- a/Code/CryEngine/Cry3DEngine/LightEntity.cpp +++ /dev/null @@ -1,1926 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "3dEngine.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "LightEntity.h" -#include "CullBuffer.h" -#include "IShader.h" -#include "ClipVolume.h" -#include "ClipVolumeManager.h" -#include "ShadowCache.h" - -#include -#include - -PodArray CLightEntity::s_lstTmpCastersHull; - -#define MIN_SHADOW_RES_OMNI_LIGHT 64 -#define MIN_SHADOW_RES_PROJ_LIGHT 128 - -void CLightEntity::StaticReset() -{ - stl::free_container(s_lstTmpCastersHull); -} - -void CLightEntity::InitEntityShadowMapInfoStructure() -{ - // Init ShadowMapInfo structure - if (!m_pShadowMapInfo) - { - m_pShadowMapInfo = new ShadowMapInfo(); // leak - } -} - -CLightEntity::CLightEntity() - : m_VoxelGIMode{VM_None} -{ - m_layerId = ~0; - - m_bShadowCaster = false; - m_pShadowMapInfo = NULL; - m_pNotCaster = NULL; - - memset(&m_Matrix, 0, sizeof(m_Matrix)); - - m_pStatObj = NULL; - GetInstCount(GetRenderNodeType())++; -} - -CLightEntity::~CLightEntity() -{ - SAFE_RELEASE(m_light.m_Shader.m_pShader); - - Get3DEngine()->FreeRenderNodeState(this); - - ((C3DEngine*)Get3DEngine())->RemoveEntityLightSources(this); - - // delete shadow frustums - if (m_pShadowMapInfo) - { - for (int nLod = 0; nLod < MAX_GSM_LODS_NUM; nLod++) - { - //TODO: after porting the sorting to jobs, add a sync point here to prevent deleting a ShadowFrustum which could still be used by a job - SAFE_DELETE(m_pShadowMapInfo->pGSM[nLod]); - } - } - SAFE_DELETE(m_pShadowMapInfo); - - GetInstCount(GetRenderNodeType())--; - - SAFE_RELEASE(m_pStatObj); -} - -const char* CLightEntity::GetName(void) const -{ - return m_Name.size() ? m_Name.c_str() : (m_light.m_sName ? m_light.m_sName : "LightEntity"); -} - -bool CLightEntity::IsLightAreasVisible() -{ - IVisArea* pArea = GetEntityVisArea(); - - // test area vis - if (!pArea || pArea->GetVisFrameId() == GetRenderer()->GetFrameID()) - { - return true; // visible - } - if (m_light.m_Flags & DLF_THIS_AREA_ONLY) - { - return false; - } - - // test neighbors - IVisArea* Areas[64]; - int nCount = pArea->GetVisAreaConnections(Areas, 64); - for (int i = 0; i < nCount; i++) - { - if (Areas[i]->GetVisFrameId() == GetRenderer()->GetFrameID()) - { - return true; // visible - } - } - return false; // not visible -} - - -////////////////////////////////////////////////////////////////////////// -int CLightEntity::GetSlotCount() const -{ - if (m_pStatObj) - { - return 1; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CLightEntity::SetMatrix(const Matrix34& mat) -{ - m_Matrix = mat; - Vec3 wp = mat.GetTranslation(); - if (!(m_light.m_Flags & DLF_DEFERRED_CUBEMAPS)) - { - float fRadius = m_light.m_fRadius; - if (m_light.m_Flags & DLF_AREA_LIGHT) // Use max for area lights. - { - fRadius += max(m_light.m_fAreaWidth, m_light.m_fAreaHeight); - } - SetBBox(AABB(wp - Vec3(fRadius), wp + Vec3(fRadius))); - } - else - { - OBB obb(OBB::CreateOBBfromAABB(Matrix33(m_Matrix), AABB(-m_light.m_ProbeExtents, m_light.m_ProbeExtents))); - SetBBox(AABB::CreateAABBfromOBB(wp, obb)); - } - m_light.SetPosition(wp); - - // Updating light properties here can permanently set our m_bShadowCaster to false if e_shadows is 0 so preserve it. - // really updating the matrix shouldn't change our shadow casting property and we should probably make a new function - // to update matrix related properties instead of calling SetLightProperties - bool isShadowCaster = m_bShadowCaster; - SetLightProperties(m_light); - m_bShadowCaster = isShadowCaster; - - Get3DEngine()->RegisterEntity(this); - - if (!memcmp(&m_Matrix, &mat, sizeof(Matrix34))) - { - return; - } - - //update shadow frustums - if (m_pShadowMapInfo != NULL) - { - for (int i = 0; i < MAX_GSM_LODS_NUM && m_pShadowMapInfo->pGSM[i] != NULL; i++) - { - m_pShadowMapInfo->pGSM[i]->RequestUpdate(); - } - } -} - - -void C3DEngine::UpdateSun(const SRenderingPassInfo& passInfo) -{ - if (GetCVars()->e_Sun) - { - if (!m_pSun) - { - m_pSun = (CLightEntity*)CreateLightSource(); - } - - CDLight DynLight; - DynLight.SetPosition(passInfo.GetCamera().GetPosition() + GetSunDir()); - DynLight.m_fRadius = 100000000; - DynLight.SetLightColor(GetSunColor()); - DynLight.SetSpecularMult(GetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER)); - DynLight.m_Flags |= DLF_DIRECTIONAL | DLF_SUN | DLF_THIS_AREA_ONLY | DLF_LM | DLF_SPECULAROCCLUSION | - ((m_bSunShadows && passInfo.RenderShadows()) ? DLF_CASTSHADOW_MAPS : 0); - DynLight.m_sName = "Sun"; - - DynLight.m_nLightStyle = gEnv->p3DEngine->GetSunAnimIndex(); - DynLight.SetAnimSpeed(gEnv->p3DEngine->GetSunAnimSpeed()); - DynLight.m_nLightPhase = gEnv->p3DEngine->GetSunAnimPhase(); - - m_pSun->SetLightProperties(DynLight); - - m_pSun->SetBBox(AABB( - DynLight.m_Origin - Vec3(DynLight.m_fRadius, DynLight.m_fRadius, DynLight.m_fRadius), - DynLight.m_Origin + Vec3(DynLight.m_fRadius, DynLight.m_fRadius, DynLight.m_fRadius))); - - m_pSun->SetRndFlags(ERF_OUTDOORONLY, true); - - CDLight* lightProps = &m_pSun->GetLightProperties(); //We want the address of the CDLight stored in the sun, not the address of DynLight - GetRenderer()->EF_UpdateDLight(lightProps); - - //Update the sun's animated color with the color calculated in EF_UpdateDLight - gEnv->p3DEngine->SetSunAnimColor(Vec3(lightProps->m_Color.r, lightProps->m_Color.g, lightProps->m_Color.b)); - - RegisterEntity(m_pSun); - } - else if (m_pSun) - { - UnRegisterEntityAsJob(m_pSun); - DeleteLightSource(m_pSun); - m_pSun = nullptr; - } -} - -Vec3 CLightEntity::GSM_GetNextScreenEdge(float fPrevRadius, float fPrevDistanceFromView, const SRenderingPassInfo& passInfo) -{ - Vec3 vEdgeN = passInfo.GetCamera().GetEdgeN(); - Vec3 vEdgeF = passInfo.GetCamera().GetEdgeF(); - Vec3 vPrevSphereCenter(0.0f, fPrevDistanceFromView, 0.0f); - - float fDistToFrustEdge = (((vPrevSphereCenter - vEdgeN).Cross(vEdgeF - vEdgeN)).GetLength()) / ((vEdgeF - vEdgeN).GetLength()); - float fDistToPlaneOnEdgeSquared = fPrevRadius * fPrevRadius - fDistToFrustEdge * fDistToFrustEdge; - float fDistToPlaneOnEdge = fDistToPlaneOnEdgeSquared > 0.0f ? sqrt_tpl(fDistToPlaneOnEdgeSquared) : 0.0f; - - Vec3 vEdgeDir = (vEdgeF - vEdgeN); - vEdgeDir.SetLength(2.0f * fDistToPlaneOnEdge); - return vEdgeN + vEdgeDir; -}; - -float CLightEntity::GSM_GetLODProjectionCenter(const Vec3& vEdgeScreen, float fRadius) -{ - float fScreenEdgeSq = vEdgeScreen.z * vEdgeScreen.z + vEdgeScreen.x * vEdgeScreen.x; - float fRadiusSq = max(fRadius * fRadius, 2.0f * fScreenEdgeSq); - float fDistanceFromNear = sqrt_tpl(fRadiusSq - fScreenEdgeSq); - float fDistanceFromView = fDistanceFromNear + vEdgeScreen.y; - return fDistanceFromView; -} - - -void CLightEntity::UpdateGSMLightSourceShadowFrustum(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - const int nMaxLodCount = min(GetCVars()->e_GsmLodsNum, MAX_GSM_LODS_NUM); - int nDynamicLodCount = nMaxLodCount; - int nCachedLodCount = 0; - - // check for shadow cache - if (m_light.m_Flags & DLF_SUN) - { - int nFirstCachedLod = GetCVars()->e_ShadowsCache ? Get3DEngine()->m_nGsmCache - 1 : -1; - if (nFirstCachedLod >= 0) - { - nDynamicLodCount = clamp_tpl(nFirstCachedLod, 0, nMaxLodCount); - nCachedLodCount = nMaxLodCount - nDynamicLodCount; - } - } - else - { - // If a light is not the SUN, then we don't take e_GsmLodsNum - // into account and decide we will have one lod. - nDynamicLodCount = 1; - } - - // update dynamic and static frustums - float fDistFromView = 0; - float fRadiusLastLod = 0; - - int nNextLod = 0; - nNextLod = UpdateGSMLightSourceDynamicShadowFrustum(nDynamicLodCount, nCachedLodCount, fDistFromView, fRadiusLastLod, nCachedLodCount == 0, passInfo); - nNextLod += UpdateGSMLightSourceCachedShadowFrustum(nDynamicLodCount, nCachedLodCount, fDistFromView, fRadiusLastLod, passInfo); - - // free not used frustums - for (int nLod = nNextLod; nLod < MAX_GSM_LODS_NUM; nLod++) - { - if (ShadowMapFrustum* pFr = m_pShadowMapInfo->pGSM[nLod]) - { - pFr->ResetCasterLists(); - pFr->m_eFrustumType = ShadowMapFrustum::e_GsmDynamic; - SAFE_DELETE(pFr->pShadowCacheData); - } - } -} - -int CLightEntity::UpdateGSMLightSourceDynamicShadowFrustum(int nDynamicLodCount, int nDistanceLodCount, float& fDistanceFromViewNextDynamicLod, float& fGSMBoxSizeNextDynamicLod, bool bFadeLastCascade, const SRenderingPassInfo& passInfo) -{ - InitEntityShadowMapInfoStructure(); - - float fGSMBoxSize = fGSMBoxSizeNextDynamicLod = (float)Get3DEngine()->m_fGsmRange; - Vec3 vCameraDir = passInfo.GetCamera().GetMatrix().GetColumn(1).GetNormalized(); - float fDistToLight = passInfo.GetCamera().GetPosition().GetDistance(GetPos(true)); - - PodArray& lstCastersHull = s_lstTmpCastersHull; - lstCastersHull.Clear(); - - // prepare shadow frustums - int nLod; - - //compute distance for first LOD - Vec3 vEdgeScreen = passInfo.GetCamera().GetEdgeN(); - //clamp first frustum to DRAW_NEAREST_MIN near plane because weapon can be placed beyond camera near plane in world space - vEdgeScreen.y = min(vEdgeScreen.y, DRAW_NEAREST_MIN); - float fDistanceFromView = fDistanceFromViewNextDynamicLod = GSM_GetLODProjectionCenter(vEdgeScreen, Get3DEngine()->m_fGsmRange); - - for (nLod = 0; nLod < nDynamicLodCount + nDistanceLodCount; nLod++) - { - float fFOV = (m_light).m_fLightFrustumAngle * 2; - bool bDoGSM = (fGSMBoxSize < m_light.m_fRadius * 0.01f && fGSMBoxSize < fDistToLight * 0.5f * (fFOV / 90.f) && fDistToLight < m_light.m_fRadius) - && ((m_light.m_Flags & DLF_SUN) || Get3DEngine()->GetShadowsCascadeCount(&m_light) > 1); - - if (bDoGSM) - { - //Vec3 vSunDir = Get3DEngine()->GetSunDir().GetNormalized(); // todo: remove GetNormalized() once GetSunDir() returns the normalized value - Vec3 vSunDir = Vec3(1.0f, 0.0f, 0.0f); - Vec3 vCameraDirWithoutDepth = vCameraDir - vCameraDir.Dot(vSunDir) * vSunDir; - - Vec3 vFocusPos = passInfo.GetCamera().GetPosition() + vCameraDirWithoutDepth * fGSMBoxSize; - SetBBox(AABB(vFocusPos - Vec3(fGSMBoxSize, fGSMBoxSize, fGSMBoxSize), vFocusPos + Vec3(fGSMBoxSize, fGSMBoxSize, fGSMBoxSize))); - } - else - { - float fRadius = m_light.m_fRadius; - if (m_light.m_Flags & DLF_AREA_LIGHT) // Use max for area lights. - { - fRadius += max(m_light.m_fAreaWidth, m_light.m_fAreaHeight); - } - SetBBox(AABB(m_light.m_Origin - Vec3(fRadius), m_light.m_Origin + Vec3(fRadius))); - } - - if (!m_pShadowMapInfo->pGSM[nLod]) - { - m_pShadowMapInfo->pGSM[nLod] = new ShadowMapFrustum; - } - - m_pShadowMapInfo->pGSM[nLod]->m_eFrustumType = nLod < nDynamicLodCount ? ShadowMapFrustum::e_GsmDynamic : ShadowMapFrustum::e_GsmDynamicDistance; - m_pShadowMapInfo->pGSM[nLod]->bUseAdditiveBlending = false; - m_pShadowMapInfo->pGSM[nLod]->fShadowFadingDist = (bFadeLastCascade && nLod == nDynamicLodCount - 1) ? 1.0f : 0.0f; - - if (!ProcessFrustum(nLod, bDoGSM ? fGSMBoxSize : 0, fDistanceFromView, lstCastersHull, passInfo)) - { - nLod++; - break; - } - - //compute plane for next GSM slice - vEdgeScreen = GSM_GetNextScreenEdge(fGSMBoxSize, fDistanceFromView, passInfo); - fGSMBoxSize *= Get3DEngine()->m_fGsmRangeStep; - - //compute distance from camera for next LOD - fDistanceFromView = GSM_GetLODProjectionCenter(vEdgeScreen, fGSMBoxSize); - - if (nLod < nDynamicLodCount) - { - fDistanceFromViewNextDynamicLod = fDistanceFromView; - fGSMBoxSizeNextDynamicLod = fGSMBoxSize; - } - } - - return nLod; -} - -int CLightEntity::UpdateGSMLightSourceCachedShadowFrustum(int nFirstLod, int nLodCount, float& fDistFromViewDynamicLod, float fRadiusDynamicLod, const SRenderingPassInfo& passInfo) -{ - ShadowFrustumMGPUCache* pFrustumCache = GetRenderer()->GetShadowFrustumMGPUCache(); - assert(pFrustumCache); - - static ICVar* pHeightMapAOVar = GetConsole()->GetCVar("r_HeightMapAO"); - const int firstCachedFrustumIndex = nFirstLod + nLodCount; - const bool bRestoreFromCache = GetRenderer()->GetActiveGPUCount() > 1 && pFrustumCache->nUpdateMaskMT != 0 && m_pShadowMapInfo->pGSM[firstCachedFrustumIndex]; - const bool bHeightMapAO = Get3DEngine()->m_bHeightMapAoEnabled && pHeightMapAOVar && pHeightMapAOVar->GetIVal() > 0 && (m_light.m_Flags & DLF_SUN); - - int nLod = 0; - - if (bRestoreFromCache) - { - for (nLod = 0; nLod < nLodCount; ++nLod) - { - assert(pFrustumCache->m_pStaticShadowMapFrustums[nLod] && m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]); - - ShadowMapFrustum* pFr = m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]; - *pFr = *pFrustumCache->m_pStaticShadowMapFrustums[nLod]; - pFr->bIsMGPUCopy = true; - } - - if (bHeightMapAO) - { - assert(pFrustumCache->m_pHeightMapAOFrustum && m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]); - - ShadowMapFrustum* pFr = m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]; - *pFr = *pFrustumCache->m_pHeightMapAOFrustum; - pFr->bIsMGPUCopy = true; - - ++nLod; - } - } - else - { - ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy = - static_cast(Get3DEngine()->m_nCachedShadowsUpdateStrategy); - - if (GetCVars()->e_ShadowsCacheUpdate) - { - nUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate; - } - - ShadowCache shadowCache(this, nUpdateStrategy); - - for (nLod = 0; nLod < nLodCount; ++nLod) - { - ShadowMapFrustum*& pFr = m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]; - shadowCache.InitShadowFrustum(pFr, nFirstLod + nLod, nFirstLod, fDistFromViewDynamicLod, fRadiusDynamicLod, passInfo); - if (!pFr) - { - continue; - } - - CalculateShadowBias(pFr, nFirstLod + nLod, fRadiusDynamicLod); - pFr->bIsMGPUCopy = false; - - // update MGPU frustum cache - if (GetRenderer()->GetActiveGPUCount() > 1 && pFrustumCache->m_pStaticShadowMapFrustums[nLod]) - { - *pFrustumCache->m_pStaticShadowMapFrustums[nLod] = *pFr; - } - - // update distance from view - Vec3 vEdgeScreen = GSM_GetNextScreenEdge(fRadiusDynamicLod, fDistFromViewDynamicLod, passInfo); - fRadiusDynamicLod *= Get3DEngine()->m_fGsmRangeStep; - fDistFromViewDynamicLod = GSM_GetLODProjectionCenter(vEdgeScreen, fRadiusDynamicLod); - } - - if (bHeightMapAO) - { - ShadowMapFrustum*& pFr = m_pShadowMapInfo->pGSM[firstCachedFrustumIndex + nLod]; - - shadowCache.InitHeightMapAOFrustum(pFr, nFirstLod + nLod, passInfo); - pFr->bIsMGPUCopy = false; - if (GetRenderer()->GetActiveGPUCount() > 1 && pFrustumCache->m_pHeightMapAOFrustum) - { - *pFrustumCache->m_pHeightMapAOFrustum = *pFr; - } - - ++nLod; - } - - if (GetCVars()->e_ShadowsCacheUpdate == 1) - { - GetCVars()->e_ShadowsCacheUpdate = 0; - } - - if (GetCVars()->e_ShadowsCacheRequireManualUpdate == 1) - { - Get3DEngine()->m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eManualUpdate; - } - else if (GetCVars()->e_ShadowsCacheRequireManualUpdate == 2) - { - Get3DEngine()->m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eManualOrDistanceUpdate; - } - else - { - Get3DEngine()->m_nCachedShadowsUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate; - } - - int nActiveGPUCount = GetRenderer()->GetActiveGPUCount(); - pFrustumCache->nUpdateMaskMT = (1 << nActiveGPUCount) - 1; - } - - return nLod; -} - -bool CLightEntity::ProcessFrustum(int nLod, float fGSMBoxSize, float fDistanceFromView, PodArray& lstCastersHull, const SRenderingPassInfo& passInfo) -{ - ShadowMapFrustum* pFr = m_pShadowMapInfo->pGSM[nLod]; - - // make shadow map frustum for receiving (include all objects into frustum) - assert(pFr); - - bool bDoGSM = fGSMBoxSize != 0; - - if (bDoGSM)// && (m_light.m_Flags & DLF_SUN || m_light.m_Flags & DLF_PROJECT)) - { - InitShadowFrustum_SUN_Conserv(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, fGSMBoxSize, fDistanceFromView, nLod, passInfo); - - const uint32 renderNodeFlags = pFr->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance ? ERF_DYNAMIC_DISTANCESHADOWS : 0xFFFFFFFF; - FillFrustumCastersList_SUN(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, renderNodeFlags, lstCastersHull, nLod, passInfo); - } - else if (m_light.m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT)) - { - InitShadowFrustum_PROJECTOR(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, passInfo); - FillFrustumCastersList_PROJECTOR(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, passInfo); - } - else - { - pFr->bOmniDirectionalShadow = true; - InitShadowFrustum_OMNI(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, passInfo); - FillFrustumCastersList_OMNI(pFr, SMC_EXTEND_FRUSTUM | SMC_SHADOW_FRUSTUM_TEST, passInfo); - } - - CalculateShadowBias(pFr, nLod, fGSMBoxSize); - - if (GetCVars()->e_ShadowsFrustums && pFr && !pFr->m_castersList.IsEmpty()) - { - pFr->DrawFrustum(GetRenderer(), (GetCVars()->e_ShadowsFrustums == 1) ? 1000 : 1); - } - - - return bDoGSM; -} - -void CLightEntity::InitShadowFrustum_SUN_Conserv(ShadowMapFrustum* pFr, [[maybe_unused]] int dwAllowedTypes, float fGSMBoxSize, float fDistance, int nLod, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(nLod >= 0 && nLod < MAX_GSM_LODS_NUM); - - //TOFIX: replace fGSMBoxSize by fRadius - float fRadius = fGSMBoxSize; -#ifdef FEATURE_SVO_GI - if (gEnv->pConsole->GetCVar("e_svoTI_Active") && - gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal() && - nLod == 2) - { - fRadius += gEnv->pConsole->GetCVar("e_svoTI_ConeMaxLength")->GetFVal() * 0.5f; - } -#endif - - Vec3 vViewDir = passInfo.GetCamera().GetViewdir(); - pFr->RequestUpdate(); - pFr->nShadowMapLod = nLod; - pFr->vLightSrcRelPos = m_light.m_Origin - passInfo.GetCamera().GetPosition(); - pFr->fRadius = m_light.m_fRadius; - assert(m_light.m_pOwner); - pFr->pLightOwner = m_light.m_pOwner; - pFr->m_Flags = m_light.m_Flags; - pFr->bIncrementalUpdate = false; - - const AABB& box = GetBBox(); - const float fBoxRadius = max(0.00001f, box.GetRadius()); - - // float fDistToLightSrc = pFr->vLightSrcRelPos.GetLength(); - pFr->fFOV = (float)RAD2DEG(atan_tpl(fRadius / DISTANCE_TO_THE_SUN)) * 2.0f; - if (pFr->fFOV > LIGHT_PROJECTOR_MAX_FOV) - { - pFr->fFOV = LIGHT_PROJECTOR_MAX_FOV; - } - pFr->fProjRatio = 1.0f; - - //Sampling parameters - //Calculate proper projection of frustum to the terrain receiving area but not based on fBoxRadius - - float arrWidthS[] = {1.94f, 1.0f, 0.8f, 0.5f, 0.3f, 0.3f, 0.3f, 0.3f}; - - pFr->fWidthS = arrWidthS[nLod];//fBoxRadiusMax/arrRangeS[nLod]; //fBoxRadius //*GetCVars()->e_ShadowsMaxTexRes * - pFr->fWidthT = pFr->fWidthS; - pFr->fBlurS = 0.0f;//arrBlurS[nLod]; - pFr->fBlurT = pFr->fBlurS; - - Vec3 vLightDir = pFr->vLightSrcRelPos.normalized(); - - float fDist = pFr->vLightSrcRelPos.GetLength(); - - //float fMaxFrustEdge = GSM_GetNextScreenEdge(fGSMBoxSize, fDistance).GetLength(); - Vec3 vEdgeN = passInfo.GetCamera().GetEdgeN(); - Vec3 vCamSpView(0.0f, fDistance, 0.0f); - float fEdgeScale = (fDistance + fGSMBoxSize) / vEdgeN.y * vEdgeN.GetLength(); - float fMaxFrustEdge = ((vEdgeN.GetNormalized() * fEdgeScale) - vCamSpView).GetLength(); - fMaxFrustEdge *= 1.37f; - - { - const float fDepthRange = 2.0f * max(Get3DEngine()->m_fSunClipPlaneRange, fMaxFrustEdge); - const float fNearAdjust = Lerp(fDepthRange - fMaxFrustEdge, fMaxFrustEdge, Get3DEngine()->m_fSunClipPlaneRangeShift); - - pFr->fNearDist = fDist - fNearAdjust; - pFr->fFarDist = fDist + fDepthRange - fNearAdjust; - } - - if (pFr->fFarDist > m_light.m_fRadius) - { - pFr->fFarDist = m_light.m_fRadius; - } - - if (pFr->fNearDist < pFr->fFarDist * 0.005f) - { - pFr->fNearDist = pFr->fFarDist * 0.005f; - } - - assert(pFr->fNearDist < pFr->fFarDist); - - pFr->nTexSize = GetCVars()->e_ShadowsMaxTexRes; - - pFr->vProjTranslation = passInfo.GetCamera().GetPosition() + fDistance * vViewDir; - - // local jitter amount depends on frustum size - pFr->fFrustrumSize = 1.0f / (fGSMBoxSize * (float)Get3DEngine()->m_fGsmRange); - pFr->nUpdateFrameId = passInfo.GetFrameID(); - pFr->bIncrementalUpdate = false; - - // setup the frustum main frustum plane before calculating frustum bounds and blending - CCamera& FrustCam = pFr->FrustumPlanes[0] = CCamera(); - Matrix34A mat = Matrix33::CreateRotationVDir(-vLightDir); - mat.SetTranslation(pFr->vLightSrcRelPos + pFr->vProjTranslation); - FrustCam.SetMatrixNoUpdate(mat); - FrustCam.SetFrustum(256, 256, pFr->fFOV * (gf_PI / 180.0f), pFr->fNearDist, pFr->fFarDist); - - GetGsmFrustumBounds(passInfo.GetCamera(), pFr); - - if (GetCVars()->e_ShadowsBlendCascades) - { - pFr->bBlendFrustum = true; - pFr->fBlendVal = GetCVars()->e_ShadowsBlendCascadesVal; - - CCamera& BlendCam = pFr->FrustumPlanes[1] = pFr->FrustumPlanes[0]; - BlendCam.SetFrustum(256, 256, pFr->fBlendVal * pFr->fFOV * (gf_PI / 180.0f), pFr->fNearDist, pFr->fFarDist); - } - else - { - pFr->bBlendFrustum = false; - pFr->fBlendVal = 1.0f; - } -} - -void CLightEntity::CalculateShadowBias(ShadowMapFrustum* pFr, int nLod, float fGSMBoxSize) const -{ - const float* arrDepthConstBias = Get3DEngine()->GetShadowsCascadesConstBias(); - const float* arrDepthSlopeBias = Get3DEngine()->GetShadowsCascadesSlopeBias(); - - assert(nLod >= 0 && nLod < 8); - - if (m_light.m_Flags & DLF_SUN) - { - float fVladRatio = min(fGSMBoxSize / 2.f, 1.f); - float fConstBiasRatio = arrDepthConstBias[nLod] * Get3DEngine()->m_fShadowsConstBias * fVladRatio; - float fSlopeBiasRatio = arrDepthSlopeBias[nLod] * Get3DEngine()->m_fShadowsSlopeBias * fVladRatio; - - pFr->fDepthConstBias = fConstBiasRatio * (pFr->fFarDist - pFr->fNearDist) / (872727.27f * 2.0f) /** 0.000000001f;*/; - pFr->fDepthTestBias = fVladRatio * (pFr->fFarDist - pFr->fNearDist) * (fGSMBoxSize * 0.5f * 0.5f + 0.5f) * 0.0000005f; - pFr->fDepthSlopeBias = fSlopeBiasRatio * (fGSMBoxSize / max(0.00001f, Get3DEngine()->m_fGsmRange)) * 0.1f; - } - else - { - pFr->fDepthConstBias = m_light.m_fShadowBias * 0.000003f * pFr->fFarDist; //should be reverted to 0.0000001 after fixinf +X-frustum - pFr->fDepthTestBias = 0.00028f * pFr->fFarDist; - pFr->fDepthSlopeBias = m_light.m_fShadowSlopeBias * Get3DEngine()->m_fShadowsSlopeBias; - } - - if (pFr->fDepthTestBias > 0.005f) - { - pFr->fDepthTestBias = 0.005f; - } - - if (pFr->fNearDist < 1000.f) // if not sun - { - if (pFr->fDepthTestBias < 0.0005f) - { - pFr->fDepthTestBias = 0.0005f; - } - } -} - -bool SegmentFrustumIntersection(const Vec3& P0, const Vec3& P1, const CCamera& frustum, Vec3* pvIntesectP0 = NULL, Vec3* pvIntesectP1 = NULL) -{ - if (P0.IsEquivalent(P1)) - { - return frustum.IsPointVisible(P0); - } - - //Actual Segment-Frustum intersection test - float tE = 0.0f; - float tL = 1.0f; - Vec3 dS = P1 - P0; - - for (int i = 0; i < 6; i++) - { - const Plane* currPlane = frustum.GetFrustumPlane(i); - - Vec3 ni = currPlane->n; - Vec3 Vi = ni * (-currPlane->d); - - float N = -(ni | Vec3(P0 - Vi)); - float D = ni | dS; - - if (D == 0) //segment is parallel to face - { - if (N < 0) - { - return false; //outside face - } - else - { - continue; //inside face - } - } - - float t = N / D; - if (D < 0) //segment is entering face - { - tE = max(tE, t); - if (tE > tL) - { - return false; - } - } - else //segment is leaving face - { - tL = min(tL, t); - if (tL < tE) - { - return false; - } - } - } - //calc intersection point if needed - if (pvIntesectP0) - { - *pvIntesectP0 = P0 + tE * dS; // = P(tE) = point where S enters polygon - } - if (pvIntesectP1) - { - *pvIntesectP1 = P0 + tL * dS; // = P(tL) = point where S leaves polygon - } - //it's intersecting frustum - return true; -} - - -bool CLightEntity::FrustumIntersection(const CCamera& viewFrustum, const CCamera& shadowFrustum) -{ - int i; - - Vec3 pvViewFrust[8]; - Vec3 pvShadowFrust[8]; - - viewFrustum.GetFrustumVertices(pvViewFrust); - shadowFrustum.GetFrustumVertices(pvShadowFrust); - - for (i = 0; i < 8; i++) - { - if (viewFrustum.IsPointVisible(pvShadowFrust[i])) - { - return true; - } - - if (shadowFrustum.IsPointVisible(pvViewFrust[i])) - { - return true; - } - } - - for (i = 0; i < 4; i++) - { - //far face - if (SegmentFrustumIntersection(pvShadowFrust[i], pvShadowFrust[(i + 1) % 4], viewFrustum)) - { - return true; - } - //near face - if (SegmentFrustumIntersection(pvShadowFrust[i + 4], pvShadowFrust[(i + 1) % 4 + 4], viewFrustum)) - { - return true; - } - //other edges - if (SegmentFrustumIntersection(pvShadowFrust[i], pvShadowFrust[i + 4], viewFrustum)) - { - return true; - } - - //vice-versa test - //far face - if (SegmentFrustumIntersection(pvViewFrust[i], pvViewFrust[(i + 1) % 4], shadowFrustum)) - { - return true; - } - //near face - if (SegmentFrustumIntersection(pvViewFrust[i + 4], pvViewFrust[(i + 1) % 4 + 4], shadowFrustum)) - { - return true; - } - //other edges - if (SegmentFrustumIntersection(pvViewFrust[i], pvViewFrust[i + 4], shadowFrustum)) - { - return true; - } - } - - return false; -} - -bool CLightEntity::GetGsmFrustumBounds(const CCamera& viewFrustum, ShadowMapFrustum* pShadowFrustum) -{ - int i; - - Vec3 pvViewFrust[8]; - Vec3 pvShadowFrust[8]; - - CCamera& camShadowFrustum = pShadowFrustum->FrustumPlanes[0]; - - Matrix34A mShadowView, mShadowProj; - Matrix34A mShadowComposite = viewFrustum.GetMatrix().GetInverted(); - Matrix44A mCameraView = Matrix44A(viewFrustum.GetMatrix().GetInverted()); - viewFrustum.GetFrustumVertices(pvViewFrust); - camShadowFrustum.GetFrustumVertices(pvShadowFrust); - - Vec3 vCamPosition = viewFrustum.GetPosition(); - Vec3 vIntersectP0(0, 0, 0), vIntersectP1(0, 0, 0); - - AABB viewAABB; - viewAABB.Reset(); - - bool bIntersected = false; - f32 fDisatanceToMaxBound = 0; - Vec3 vMaxBoundPoint(ZERO); - - for (i = 0; i < 4; i++) - { - //far face - if (SegmentFrustumIntersection(pvShadowFrust[i], pvShadowFrust[(i + 1) % 4], viewFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - - //near face - if (SegmentFrustumIntersection(pvShadowFrust[i + 4], pvShadowFrust[(i + 1) % 4 + 4], viewFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - - if (SegmentFrustumIntersection(pvShadowFrust[i], pvShadowFrust[i + 4], viewFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - - if (SegmentFrustumIntersection(pvViewFrust[i], pvViewFrust[(i + 1) % 4], camShadowFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - - if (SegmentFrustumIntersection(pvViewFrust[i + 4], pvViewFrust[(i + 1) % 4 + 4], camShadowFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - - if (SegmentFrustumIntersection(pvViewFrust[i], pvViewFrust[i + 4], camShadowFrustum, &vIntersectP0, &vIntersectP1)) - { - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawLine(vIntersectP0, RGBA8(0xff, 0xff, 0x1f, 0xff), vIntersectP1, RGBA8(0xff, 0xff, 0x1f, 0xff), 2.0f); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP0, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vIntersectP1, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - } - - float fCurDistance = (vCamPosition - vIntersectP0).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP0; - fDisatanceToMaxBound = fCurDistance; - } - - fCurDistance = (vCamPosition - vIntersectP1).GetLength(); - if (fCurDistance > fDisatanceToMaxBound) - { - vMaxBoundPoint = vIntersectP1; - fDisatanceToMaxBound = fCurDistance; - } - - bIntersected = true; - } - } - - if (GetCVars()->e_GsmDepthBoundsDebug) - { - GetRenderer()->GetIRenderAuxGeom()->DrawPoint(vMaxBoundPoint, RGBA8(0xff, 0x00, 0x00, 0xff), 10); - } - - return bIntersected; -} - -void GetCubemapFrustum(ShadowMapFrustum* pFr, int nS, CCamera& shadowFrust) -{ - float sCubeVector[6][7] = - { - {1, 0, 0, 0, 0, 1, -90},//posx - {-1, 0, 0, 0, 0, 1, 90},//negx - {0, 1, 0, 0, 0, -1, 0},//posy - {0, -1, 0, 0, 0, 1, 0},//negy - {0, 0, 1, 0, 1, 0, 0},//posz - {0, 0, -1, 0, 1, 0, 0},//negz - }; - - int nShadowTexSize = pFr->nTexSize; - Vec3 vPos = pFr->vLightSrcRelPos + pFr->vProjTranslation; - - Vec3 vForward = Vec3(sCubeVector[nS][0], sCubeVector[nS][1], sCubeVector[nS][2]); - Vec3 vUp = Vec3(sCubeVector[nS][3], sCubeVector[nS][4], sCubeVector[nS][5]); - Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[nS][6])); - - float fMinDist = pFr->fNearDist; - float fMaxDist = pFr->fFarDist; - shadowFrust.SetMatrix(Matrix34(matRot, vPos)); - shadowFrust.SetFrustum(nShadowTexSize, nShadowTexSize, 90.0f * gf_PI / 180.0f, fMinDist, fMaxDist); -} - -void CLightEntity::CheckValidFrustums_OMNI(ShadowMapFrustum* pFr, const SRenderingPassInfo& passInfo) -{ - pFr->nOmniFrustumMask = 0; - - const CCamera& cameraFrust = passInfo.GetCamera(); - - for (int nS = 0; nS < 6; nS++) - { - CCamera shadowFrust; - GetCubemapFrustum(pFr, nS, shadowFrust); - - if (FrustumIntersection(cameraFrust, shadowFrust)) - { - pFr->nOmniFrustumMask |= (1 << nS); - } - } -} - -bool CLightEntity::CheckFrustumsIntersect(CLightEntity* lightEnt) -{ - Vec3 pvShadowFrust[8]; - bool bRes = false; - - ShadowMapFrustum* pFr1; - ShadowMapFrustum* pFr2; - - pFr1 = this->GetShadowFrustum(0); - pFr2 = lightEnt->GetShadowFrustum(0); - - if (!pFr1 || !pFr2) - { - return false; - } - - int nFaces1, nFaces2; - nFaces1 = (pFr1->bOmniDirectionalShadow ? 6 : 1); - nFaces2 = (pFr2->bOmniDirectionalShadow ? 6 : 1); - - for (int nS1 = 0; nS1 < nFaces1; nS1++) - { - for (int nS2 = 0; nS2 < nFaces2; nS2++) - { - CCamera shadowFrust1 = pFr1->FrustumPlanes[nS1]; - CCamera shadowFrust2 = pFr2->FrustumPlanes[nS2]; - ; - - if (FrustumIntersection(shadowFrust1, shadowFrust2)) - { - bRes = true; - - //debug frustums - vtx_idx pnInd[8] = { - 0, 4, 1, 5, 2, 6, 3, 7 - }; - //first frustum - shadowFrust1.GetFrustumVertices(pvShadowFrust); - GetRenderer()->GetIRenderAuxGeom()->DrawPolyline(pvShadowFrust, 4, true, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawPolyline(pvShadowFrust + 4, 4, true, RGBA8(0xff, 0xff, 0x1f, 0xff)); - - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 2, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 4, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 6, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - - //second frustum - shadowFrust2.GetFrustumVertices(pvShadowFrust); - GetRenderer()->GetIRenderAuxGeom()->DrawPolyline(pvShadowFrust, 4, true, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawPolyline(pvShadowFrust + 4, 4, true, RGBA8(0xff, 0xff, 0x1f, 0xff)); - - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 2, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 4, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - GetRenderer()->GetIRenderAuxGeom()->DrawLines(pvShadowFrust, 8, pnInd + 6, 2, RGBA8(0xff, 0xff, 0x1f, 0xff)); - } - } - } - return bRes; -} - -void CLightEntity::InitShadowFrustum_PROJECTOR(ShadowMapFrustum* pFr, [[maybe_unused]] int dwAllowedTypes, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - const int nFrameId = passInfo.GetMainFrameID(); - - float fShadowUpdate = (float)(m_light.m_nShadowUpdateRatio * GetCVars()->e_ShadowsUpdateViewDistRatio); - const float fShadowUpdateScale = (1 << DL_SHADOW_UPDATE_SHIFT) * (1 << DL_SHADOW_UPDATE_SHIFT);// e_ShadowsUpdateViewDistRatio is also fixed point, 256 == 1.0f - - // construct camera from projector - Matrix34 entMat = ((ILightSource*)m_light.m_pOwner)->GetMatrix(); - - Vec3 vProjDir = entMat.GetColumn(0).GetNormalizedSafe(); - - pFr->nShadowMapLod = -1; // not used - - // place center into middle of projector far plane - pFr->vLightSrcRelPos = -vProjDir * m_light.m_fRadius; - pFr->vProjTranslation = m_light.m_Origin - pFr->vLightSrcRelPos; - if (pFr->fRadius != m_light.m_fRadius) - { - pFr->RequestUpdate(); - } - pFr->bIncrementalUpdate = false; - pFr->fRadius = m_light.m_fRadius; - assert(m_light.m_pOwner && m_light.m_pOwner == this); - pFr->pLightOwner = this; - pFr->m_Flags = m_light.m_Flags; - pFr->bBlendFrustum = false; - - // float fDistToLightSrc = pFr->vLightSrcRelPos.GetLength(); - pFr->fFOV = CLAMP(m_light.m_fLightFrustumAngle * 2.f, 0.0001f, LIGHT_PROJECTOR_MAX_FOV); - - pFr->fNearDist = 0.01f; - pFr->fFarDist = m_light.m_fRadius; - - // set texture size - uint32 nTexSize = GetCVars()->e_ShadowsMaxTexRes; - - if (pFr->bOmniDirectionalShadow) - { - nTexSize = GetCVars()->e_ShadowsMaxTexRes / 2; - } - - const CCamera& cCam = passInfo.GetCamera(); - - float fLightToCameraDist = cCam.GetPosition().GetDistance(m_light.m_Origin); - - float fLightToCameraDistAdjusted = max(5.f, fLightToCameraDist - m_light.m_fRadius); - while (nTexSize > (800.f / fLightToCameraDistAdjusted) * pFr->fRadius * m_light.m_Color.Luminance() * (pFr->fFOV / 90.f) && nTexSize > 256) - { - nTexSize /= 2; - } - - float shadowUpdateDist = max(0.0f, fLightToCameraDist - m_light.m_fShadowUpdateMinRadius); - - float shadowUpdateRate = 255.0f; - - if (GetCVars()->e_ShadowsUpdateViewDistRatio) - { - shadowUpdateRate = min(255.f, fShadowUpdateScale * shadowUpdateDist * passInfo.GetZoomFactor() / (fShadowUpdate)); - } - - pFr->nShadowPoolUpdateRate = (uint8) shadowUpdateRate; - - - if (m_light.m_Flags & DLF_DEFERRED_LIGHT) - { - float fScaledRadius = m_light.m_fRadius * m_light.m_fShadowResolutionScale; - //TD smooth distribution curve - float fAreaZ0, fAreaZ1; - if (fLightToCameraDist <= m_light.m_fRadius) - { - fAreaZ0 = cCam.GetNearPlane(); - fAreaZ1 = 2.0f * fScaledRadius; - } - else - { - fAreaZ0 = max(cCam.GetNearPlane(), fLightToCameraDist - fScaledRadius); - fAreaZ1 = fLightToCameraDist + fScaledRadius; - } - - - float fCamFactor = log(cCam.GetFarPlane() / cCam.GetNearPlane()); - - float fFadingBase = GetCVars()->e_ShadowsAdaptScale; - float fSMZ0 = log(fAreaZ0 / cCam.GetNearPlane()) / log(fFadingBase); - float fSMZ1 = log(fAreaZ1 / cCam.GetNearPlane()) / log(fFadingBase); - fSMZ0 /= fCamFactor; - fSMZ1 /= fCamFactor; - - float fCoverageScaleFactor = GetCVars()->e_ShadowsResScale; - if (!(m_light.m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT))) - { - fCoverageScaleFactor /= 3.5f; - } - - - nTexSize = int((fSMZ1 - fSMZ0) * ((float)GetCVars()->e_ShadowsMaxTexRes * fCoverageScaleFactor /*/(7*cCam.GetFarPlane())*/)); - - uint32 nPoolSize = GetCVars()->e_ShadowsPoolSize; - uint32 nMaxTexRes = GetCVars()->e_ShadowsMaxTexRes; - - uint32 nMinRes, nMaxRes, nPhysicalMaxRes; - - if (m_light.m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT)) - { - nMinRes = MIN_SHADOW_RES_PROJ_LIGHT; - nMaxRes = nMaxTexRes; - nPhysicalMaxRes = nPoolSize; - } - else - { - nMinRes = MIN_SHADOW_RES_OMNI_LIGHT; - nMaxRes = nMaxTexRes >> 1; - nPhysicalMaxRes = nPoolSize >> 2; - } - - if (m_light.m_nShadowMinResolution) - { - nMinRes = nPoolSize >> (4 - m_light.m_nShadowMinResolution); // 4 possible percentages of pool size exposed in editor 100%, 50%, 25%, 12.5% (IEditorImpl.cpp) - - if (nMinRes > nMaxRes) // if a very large min res is requested, go beyond normal limits, up to physical pool size. CINEMATICS ONLY PLEASE! - { - nMaxRes = min(nPhysicalMaxRes, nMinRes); - } - } - - nTexSize = max(nMinRes, nTexSize); - nTexSize = min(min(nMaxRes, nTexSize), nPhysicalMaxRes); // make sure we never go above pool size - - // force power of two - nTexSize = 1 << IntegerLog2((uint32)nTexSize); - } - - if (pFr->nTexSize != nTexSize) - { - pFr->nTexSize = nTexSize; - pFr->RequestUpdate(); - } - pFr->fFrustrumSize = 20.0f * nTexSize / 64.0f; - pFr->nUpdateFrameId = nFrameId; -} - -void CLightEntity::InitShadowFrustum_OMNI(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo) -{ - InitShadowFrustum_PROJECTOR(pFr, dwAllowedTypes, passInfo); - CheckValidFrustums_OMNI(pFr, passInfo); -} - -bool IsABBBVisibleInFrontOfPlane_FAST(const AABB& objBox, const SPlaneObject& clipPlane); - -bool IsAABBInsideHull(const SPlaneObject* pHullPlanes, int nPlanesNum, const AABB& aabbBox) -{ - for (int i = 0; i < nPlanesNum; i++) - { - if (!IsABBBVisibleInFrontOfPlane_FAST(aabbBox, pHullPlanes[i])) - { - return false; - } - } - - return true; -} - -bool IsSphereInsideHull(const SPlaneObject* pHullPlanes, int nPlanesNum, const Sphere& objSphere) -{ - for (int i = 0; i < nPlanesNum; i++) - { - if (-pHullPlanes[i].plane.DistFromPlane(objSphere.center) > objSphere.radius) - { - return false; - } - } - return true; -} - -int CLightEntity::MakeShadowCastersHullSun(PodArray& lstCastersHull, const SRenderingPassInfo& passInfo) -{ - // Construct hull from camera vertices and light source position - FUNCTION_PROFILER_3DENGINE; - - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - - Vec3 arrFrustVerts[10]; - passInfo.GetCamera().GetFrustumVertices(arrFrustVerts); - - // 0 to 5 are the camera frustum vertices - for (int v = 0; v < 4; v++) - { - arrFrustVerts[v] = vCamPos + (arrFrustVerts[v] - vCamPos).normalized() * GetObjManager()->GetGSMMaxDistance() * 1.3f; //0.2f; - } - arrFrustVerts[4] = passInfo.GetCamera().GetPosition(); - - // 5 to 9 are the translated frustum vertices - Vec3 vSunDir = (m_light.m_Origin - vCamPos).normalized() * Get3DEngine()->m_fSunClipPlaneRange; - for (int v = 0; v < 5; v++) - { - arrFrustVerts[v + 5] = arrFrustVerts[v] + vSunDir; - } - - // The method outputs at most 10 planes - lstCastersHull.reserve(10); - - // Indices to create the planes of the camera frustum, can be offset by 5 to create planes for the translated frustum - uint vertexIndex[5][3] = { - {4, 1, 0}, {4, 0, 3}, {4, 3, 2}, {4, 2, 1}, {0, 1, 2} - }; - - Plane planeArray[5]; - planeArray[0] = Plane::CreatePlane(arrFrustVerts[vertexIndex[0][0]], arrFrustVerts[vertexIndex[0][1]], arrFrustVerts[vertexIndex[0][2]]); - planeArray[1] = Plane::CreatePlane(arrFrustVerts[vertexIndex[1][0]], arrFrustVerts[vertexIndex[1][1]], arrFrustVerts[vertexIndex[1][2]]); - planeArray[2] = Plane::CreatePlane(arrFrustVerts[vertexIndex[2][0]], arrFrustVerts[vertexIndex[2][1]], arrFrustVerts[vertexIndex[2][2]]); - planeArray[3] = Plane::CreatePlane(arrFrustVerts[vertexIndex[3][0]], arrFrustVerts[vertexIndex[3][1]], arrFrustVerts[vertexIndex[3][2]]); - planeArray[4] = Plane::CreatePlane(arrFrustVerts[vertexIndex[4][0]], arrFrustVerts[vertexIndex[4][1]], arrFrustVerts[vertexIndex[4][2]]); - - // Test each plane against the sun vector to know if all the translated vertices are on the correct side of the plane. - bool bUsePlane[5]; - for (uint i = 0; i < 5; ++i) - { - bUsePlane[i] = planeArray[i].n.Dot(vSunDir) > 0; - } - - // Select the far plane - if (bUsePlane[4]) - { - SPlaneObject po; - po.plane = planeArray[4]; - po.Update(); - lstCastersHull.Add(po); - } - else - { - SPlaneObject po; - po.plane = Plane::CreatePlane(arrFrustVerts[vertexIndex[4][0] + 5], arrFrustVerts[vertexIndex[4][1] + 5], arrFrustVerts[vertexIndex[4][2] + 5]); - po.Update(); - lstCastersHull.Add(po); - } - - // Select side planes - for (uint i = 0; i < 4; ++i) - { - uint iPlaneOffset = bUsePlane[i] ? 0 : 5; - uint iOtherOffset = bUsePlane[i] ? 5 : 0; - uint iNextPlane = i < 3 ? i + 1 : 0; - - // Either add this plane or the equivalent plane in the translated frustum - if (bUsePlane[i]) - { - SPlaneObject po; - po.plane = planeArray[i]; - po.Update(); - lstCastersHull.Add(po); - } - else - { - SPlaneObject po; - po.plane = Plane::CreatePlane(arrFrustVerts[vertexIndex[i][0] + 5], arrFrustVerts[vertexIndex[i][1] + 5], arrFrustVerts[vertexIndex[i][2] + 5]); - po.Update(); - lstCastersHull.Add(po); - } - - // If this plane belong to a different frustum than the far plane, add a junction plane - if (bUsePlane[4] != bUsePlane[i]) - { - SPlaneObject po; - po.plane = Plane::CreatePlane(arrFrustVerts[vertexIndex[i][1] + iPlaneOffset], arrFrustVerts[vertexIndex[i][1] + iOtherOffset], arrFrustVerts[vertexIndex[i][2] + iPlaneOffset]); - //plane won't be valid in the case that the sun vector aligned with this edge of the camera frustrum. When this happens the new planes are pulled straight along that vector - //and the 3 vertices used will form 2 colinear vectors. Which will create an invalid plane. - //This means we don't need the junction plane however, so just don't create it. - if (po.plane.IsValid()) - { - po.Update(); - lstCastersHull.Add(po); - } - } - - // If this plane belong to a different frustum than the next plane, add a junction plane - if (bUsePlane[iNextPlane] != bUsePlane[i]) - { - SPlaneObject po; - po.plane = Plane::CreatePlane(arrFrustVerts[vertexIndex[i][0] + iPlaneOffset], arrFrustVerts[vertexIndex[i][2] + iPlaneOffset], arrFrustVerts[vertexIndex[i][2] + iOtherOffset]); - po.Update(); - lstCastersHull.Add(po); - } - } - - return lstCastersHull.Count(); -} - -void CLightEntity::FillFrustumCastersList_SUN(ShadowMapFrustum* pFr, int dwAllowedTypes, int nRenderNodeFlags, PodArray& lstCastersHull, int nLod, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - pFr->bOmniDirectionalShadow = false; - - if (pFr->bBlendFrustum) - { - float fBlendVal = GetCVars()->e_ShadowsBlendCascadesVal; - - float fRange = Get3DEngine()->m_fGsmRange; - float fRangeStep = Get3DEngine()->m_fGsmRangeStep; - float fRadius = fRange * powf(fRangeStep, aznumeric_caster(nLod)); - - float fBlendRadius = fRadius - (fBlendVal * (nLod + 1)); - - pFr->fBlendVal = fBlendRadius / fRadius; - pFr->bBlendFrustum = true; - } - - AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); - const AZ::Vector3 terrainCenter = terrainAabb.GetCenter(); - const float terrainSize = AZ::GetMax(terrainAabb.GetXExtent(), terrainAabb.GetYExtent()); - Vec3 vMapCenter = AZVec3ToLYVec3(terrainCenter); - - // prevent crash in qhull - if (!dwAllowedTypes || !((passInfo.GetCamera().GetPosition() - vMapCenter).GetLength() < terrainSize * 4)) - { - return; - } - - if (!lstCastersHull.Count()) // make hull first time it is needed - { - MakeShadowCastersHullSun(lstCastersHull, passInfo); - } - - if (pFr->isUpdateRequested(0)) - { - pFr->ResetCasterLists(); - if (pFr->m_eFrustumType != ShadowMapFrustum::e_GsmDynamicDistance || GetCVars()->e_DynamicDistanceShadows > 0) - { - PodArray* pShadowHull = (pFr->nShadowMapLod && !passInfo.IsRenderingCubemap()) ? &lstCastersHull : NULL; -#ifdef FEATURE_SVO_GI - if (gEnv->pConsole->GetCVar("e_svoTI_Active") && - gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal()) - { - pShadowHull = NULL; // TODO: enable hull usage for GI (use extended hull check) - } -#endif - m_pObjManager->MakeShadowCastersList((CVisArea*)GetEntityVisArea(), GetBBox(), - dwAllowedTypes, nRenderNodeFlags, pFr->vLightSrcRelPos + pFr->vLightSrcRelPos, &m_light, pFr, pShadowHull, passInfo); - } - } -} - -void CLightEntity::FillFrustumCastersList_PROJECTOR(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // fill casters list - pFr->ResetCasterLists(); - pFr->bOmniDirectionalShadow = false; - - if (dwAllowedTypes) - { - // setup camera - CCamera& FrustCam = pFr->FrustumPlanes[0] = CCamera(); - Vec3 vLightDir = -pFr->vLightSrcRelPos.normalized(); - Matrix34 mat = Matrix33::CreateRotationVDir(vLightDir); - mat.SetTranslation(GetBBox().GetCenter()); - - FrustCam.SetMatrix(mat); - FrustCam.SetFrustum(pFr->nTexSize, pFr->nTexSize, pFr->fFOV * (gf_PI / 180.0f), pFr->fNearDist, pFr->fFarDist); - - m_pObjManager->MakeShadowCastersList((CVisArea*)GetEntityVisArea(), GetBBox(), - dwAllowedTypes, 0xFFFFFFFF, pFr->vLightSrcRelPos + GetBBox().GetCenter(), &m_light, pFr, NULL, passInfo); - - DetectCastersListChanges(pFr, passInfo); - - pFr->aabbCasters.Reset(); // fix: should i .Reset() pFr->aabbCasters ? - } -} - -void CLightEntity::FillFrustumCastersList_OMNI(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // fill casters list - pFr->ResetCasterLists(); - - if (dwAllowedTypes) - { - // setup camera - CCamera& FrustCam = pFr->FrustumPlanes[0] = CCamera(); - Vec3 vLightDir = -pFr->vLightSrcRelPos.normalized(); - Matrix34 mat = Matrix33::CreateRotationVDir(vLightDir); - mat.SetTranslation(GetBBox().GetCenter()); - - FrustCam.SetMatrix(mat); - FrustCam.SetFrustum(256, 256, pFr->fFOV * (gf_PI / 180.0f) * 0.9f, pFr->fNearDist, pFr->fFarDist); - - m_pObjManager->MakeShadowCastersList((CVisArea*)GetEntityVisArea(), GetBBox(), - dwAllowedTypes, 0xFFFFFFFF, pFr->vLightSrcRelPos + GetBBox().GetCenter(), &m_light, pFr, NULL, passInfo); - - DetectCastersListChanges(pFr, passInfo); - - pFr->aabbCasters.Reset(); // fix: should i .Reset() pFr->aabbCasters ? - - // Update all omni frustums - pFr->UpdateOmniFrustums(); - } -} - -void CLightEntity::DetectCastersListChanges(ShadowMapFrustum* pFr, const SRenderingPassInfo& passInfo) -{ - uint32 uCastersListCheckSum = 0; - for (int i = 0; i < pFr->m_castersList.Count(); ++i) - { - IShadowCaster* pNode = pFr->m_castersList.GetAt(i); - const AABB entBox = pNode->GetBBoxVirtual(); - uCastersListCheckSum += uint32((entBox.min.x + entBox.min.y + entBox.min.z) * 10000.f); - uCastersListCheckSum += uint32((entBox.max.x + entBox.max.y + entBox.max.z) * 10000.f); - } - - if (pFr->fRadius < DISTANCE_TO_THE_SUN) - { - uCastersListCheckSum += uint32((m_WSBBox.min.x + m_WSBBox.min.y + m_WSBBox.min.z) * 10000.f); - uCastersListCheckSum += uint32((m_WSBBox.max.x + m_WSBBox.max.y + m_WSBBox.max.z) * 10000.f); - } - - if (pFr->uCastersListCheckSum != uCastersListCheckSum) - { - pFr->RequestUpdate(); - pFr->uCastersListCheckSum = uCastersListCheckSum; - - if (GetCVars()->e_ShadowsDebug == 3) - { - const char* szName = ((CLightEntity*)(pFr->pLightOwner))->m_light.m_sName; - PrintMessage("Requesting %s shadow update for %s, frame id = %d", - pFr->bOmniDirectionalShadow ? "Cube" : "2D", szName, passInfo.GetFrameID()); - } - } -} - -ShadowMapFrustum* CLightEntity::GetShadowFrustum(int nId) -{ - if (m_pShadowMapInfo && nId < MAX_GSM_LODS_NUM) - { - return m_pShadowMapInfo->pGSM[nId]; - } - - return NULL; -}; - - -void CLightEntity::OnCasterDeleted(IShadowCaster* pCaster) -{ - if (!m_pShadowMapInfo) - { - return; - } - - for (int nGsmId = 0; nGsmId < MAX_GSM_LODS_NUM; nGsmId++) - { - ShadowMapFrustum* pFr = m_pShadowMapInfo->pGSM[nGsmId]; - if (pFr) - { - pFr->m_castersList.Delete(pCaster); - pFr->m_jobExecutedCastersList.Delete(pCaster); - - if (pFr->pShadowCacheData) - { - pFr->pShadowCacheData->mProcessedCasters.erase(pCaster); - } - } - } -} - -void CLightEntity::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "LightEntity"); - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pShadowMapInfo); -} - -void CLightEntity::UpdateCastShadowFlag(float fDistance, const SRenderingPassInfo& passInfo) -{ - if (!(m_light.m_Flags & DLF_SUN)) - { - if (fDistance > m_fWSMaxViewDist * GetFloatCVar(e_ShadowsCastViewDistRatioLights) || !passInfo.RenderShadows()) - { - m_light.m_Flags &= ~DLF_CASTSHADOW_MAPS; - } - else if (m_bShadowCaster) - { - m_light.m_Flags |= DLF_CASTSHADOW_MAPS; - } - } - -#if defined(FEATURE_SVO_GI) - if (GetVoxelGIMode() == VM_Dynamic) - { - m_light.m_Flags |= DLF_USE_FOR_SVOGI; - } - else - { - m_light.m_Flags &= ~DLF_USE_FOR_SVOGI; - } -#endif -} - -void CLightEntity::Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo) -{ -#if defined(FEATURE_SVO_GI) - if (gEnv->pConsole->GetCVar("e_svoTI_Active") && - gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal() && - gEnv->pConsole->GetCVar("e_GI")->GetIVal() && - !GetVoxelGIMode()) - { - return; - } -#endif - if (m_layerId != uint16(~0) && m_dwRndFlags & ERF_HIDDEN) - { - return; - } - - if (!(m_light.m_Flags & DLF_DEFERRED_LIGHT) || passInfo.IsRecursivePass()) - { - return; - } - - if (m_light.m_fRadius < 0.01f) - { - return; - } - - UpdateCastShadowFlag(rParams.fDistance, passInfo); - - FUNCTION_PROFILER_3DENGINE; - - int nRenderNodeMinSpec = (m_dwRndFlags & ERF_SPEC_BITS_MASK) >> ERF_SPEC_BITS_SHIFT; - if (!CheckMinSpec(nRenderNodeMinSpec)) - { - return; - } - - Sphere sp(m_light.m_BaseOrigin, m_light.m_fBaseRadius); - - bool bIsVisible = false; - if (m_light.m_Flags & DLF_DEFERRED_CUBEMAPS) - { - OBB obb(OBB::CreateOBBfromAABB(Matrix33(m_light.m_ObjMatrix), AABB(-m_light.m_ProbeExtents, m_light.m_ProbeExtents))); - bIsVisible = passInfo.GetCamera().IsOBBVisible_F(m_light.m_Origin, obb); - } - else if (m_light.m_Flags & DLF_AREA_LIGHT) - { - // OBB test for area lights. - Vec3 vBoxMax(m_light.m_fBaseRadius, m_light.m_fBaseRadius + m_light.m_fAreaWidth, m_light.m_fBaseRadius + m_light.m_fAreaHeight); - Vec3 vBoxMin(-0.1f, -(m_light.m_fBaseRadius + m_light.m_fAreaWidth), -(m_light.m_fBaseRadius + m_light.m_fAreaHeight)); - - OBB obb(OBB::CreateOBBfromAABB(Matrix33(m_light.m_ObjMatrix), AABB(vBoxMin, vBoxMax))); - bIsVisible = passInfo.GetCamera().IsOBBVisible_F(m_light.m_BaseOrigin, obb); - } - else - { - bIsVisible = passInfo.GetCamera().IsSphereVisible_F(sp); - } - - if (!bIsVisible && !(m_light.m_Flags & DLF_ATTACH_TO_SUN)) - { - return; - } - - //assert(m_light.IsOk()); - - if ((m_light.m_Flags & DLF_DISABLED) || (!GetCVars()->e_DynamicLights)) - { - return; - } - - if ((m_light.m_Flags & DLF_PROJECT) && (m_light.m_fLightFrustumAngle < 90.f) && (m_light.m_pLightImage)) - { - if (!gEnv->pConsole->GetCVar("e_GI")->GetIVal() || - (gEnv->pConsole->GetCVar("e_svoTI_Active") && !gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal()) || - GetVoxelGIMode() != VM_Dynamic) - { - CCamera lightCam = passInfo.GetCamera(); - lightCam.SetPositionNoUpdate(m_light.m_Origin); - Matrix34 entMat = ((ILightSource*)(m_light.m_pOwner))->GetMatrix(); - entMat.OrthonormalizeFast(); - Matrix33 matRot = Matrix33::CreateRotationVDir(entMat.GetColumn(0)); - lightCam.SetMatrixNoUpdate(Matrix34(matRot, m_light.m_Origin)); - lightCam.SetFrustum(1, 1, (m_light.m_fLightFrustumAngle * 2) / 180.0f * gf_PI, 0.1f, m_light.m_fRadius); - if (!FrustumIntersection(passInfo.GetCamera(), lightCam)) - { - return; - } - } - } - - const int nEngineFrameID = passInfo.GetFrameID(); - - int nMaxReqursion = (m_light.m_Flags & DLF_THIS_AREA_ONLY) ? 2 : 3; - if (!m_pObjManager || !m_pVisAreaManager || !m_pVisAreaManager->IsEntityVisAreaVisible(this, nMaxReqursion, &m_light, passInfo)) - { - if (m_light.m_Flags & (DLF_SUN) && m_pVisAreaManager && m_pVisAreaManager->m_bSunIsNeeded) - { // sun may be used in indoor even if outdoor is not visible - } - else if (!GetEntityVisArea() && !(m_light.m_Flags & DLF_THIS_AREA_ONLY) && m_pVisAreaManager && m_pVisAreaManager->m_bSunIsNeeded) - { // not "this area only" outdoor light affects everything - } - else if ((m_light.m_Flags & (DLF_IGNORES_VISAREAS | DLF_THIS_AREA_ONLY)) == DLF_IGNORES_VISAREAS) - { - } - else - { - return; - } - } - - if (CVisArea* pArea = (CVisArea*)GetEntityVisArea()) - { // vis area lsource - IVisArea* pCameraVisArea = Get3DEngine()->GetVisAreaFromPos(passInfo.GetCamera().GetPosition()); - - // check if light is visible thru light area portal cameras - if (pArea->m_nRndFrameId == nEngineFrameID && pArea != (CVisArea*)pCameraVisArea) - { - int nCam = 0; - for (; nCam < pArea->m_lstCurCamerasLen; nCam++) - { - if (CVisArea::s_tmpCameras[pArea->m_lstCurCamerasIdx + nCam].IsSphereVisible_F(sp)) - { - break; - } - } - - if (nCam == pArea->m_lstCurCamerasLen) - { - return; // invisible - } - } - - // check if lsource is in visible area - if (!IsLightAreasVisible() && pCameraVisArea != pArea) - { - if (m_light.m_Flags & DLF_THIS_AREA_ONLY) - { - if (pArea) - { - int nRndFrameId = pArea->GetVisFrameId(); - if (nEngineFrameID - nRndFrameId > MAX_FRAME_ID_STEP_PER_FRAME) - { - return; // area invisible - } - } - else - { - return; // area invisible - } - } - } - } - else - { // outdoor lsource - if (!(m_light.m_Flags & DLF_DIRECTIONAL) && !IsLightAreasVisible()) - { - return; // outdoor invisible - } - } - - m_light.m_nStencilRef[0] = CClipVolumeManager::AffectsEverythingStencilRef; - m_light.m_nStencilRef[1] = CClipVolumeManager::InactiveVolumeStencilRef; - - if (m_light.m_Flags & DLF_THIS_AREA_ONLY) - { - // User assigned clip volumes. Note: ClipVolume 0 has already been assigned in AsyncOctreeUpdate - if ((m_light.m_Flags & DLF_HAS_CLIP_VOLUME) != 0 && m_light.m_pClipVolumes[1] != NULL) - { - m_light.m_nStencilRef[1] = m_light.m_pClipVolumes[1]->GetStencilRef(); - } - - m_light.m_nStencilRef[0] = (m_pRNTmpData && m_pRNTmpData->userData.m_pClipVolume) ? m_pRNTmpData->userData.m_pClipVolume->GetStencilRef() : 0; - } - - // associated clip volume invisible - if (m_light.m_nStencilRef[0] == CClipVolumeManager::InactiveVolumeStencilRef && m_light.m_nStencilRef[1] == CClipVolumeManager::InactiveVolumeStencilRef) - { - return; - } - - _smart_ptr pMat = GetMaterial(); - if (pMat) - { - SAFE_RELEASE(m_light.m_Shader.m_pShader); - m_light.m_Shader = pMat->GetShaderItem(); - if (m_light.m_Shader.m_pShader) - { - m_light.m_Shader.m_pShader->AddRef(); - } - } - - GetRenderer()->EF_UpdateDLight(&m_light); - - int16 forwardLightCount = Get3DEngine()->GetSunEntity() ? 1 : 0; - m_light.m_Id = int16(forwardLightCount + GetRenderer()->EF_GetDeferredLightsNum()); - - bool castShadows = false; - if (passInfo.RenderShadows() && (m_light.m_Flags & DLF_CASTSHADOW_MAPS) && m_light.m_Id >= 0) - { - UpdateGSMLightSourceShadowFrustum(passInfo); - - if (m_pShadowMapInfo) - { - m_light.m_pShadowMapFrustums = m_pShadowMapInfo->pGSM; - } - - castShadows = true; - } - - if (GetCVars()->e_DynamicLights && m_fWSMaxViewDist) - { - if (GetCVars()->e_DynamicLights == 2) - { - CDLight* pL = &m_light; - float fSize = 0.05f * (sinf(GetCurTimeSec() * 10.f) + 2.0f); - DrawSphere(pL->m_Origin, fSize, pL->m_Color); - GetRenderer()->DrawLabel(pL->m_Origin, 1.3f, "id=%d, rad=%.1f, vdm=%.1f, mvd=%.1f, shadows=%i", pL->m_Id, pL->m_fRadius, m_fViewDistanceMultiplier, m_fWSMaxViewDist, castShadows); - } - - const float mult = SATURATE(6.f * (1.f - (rParams.fDistance / m_fWSMaxViewDist))); - IF (m_light.m_Color.Luminance() * mult > 0, 1) - { - Get3DEngine()->AddLightToRenderer(m_light, mult, passInfo, SRendItemSorter(rParams.rendItemSorter)); - } - } -} - -IRenderNode::EVoxelGIMode CLightEntity::GetVoxelGIMode() -{ - if (m_light.m_BaseColor.Luminance() > .01f && m_light.m_fBaseRadius > 0.5f) - { - if (m_light.m_Flags & DLF_SUN) - { - if (GetCVars()->e_Sun) - { - return VM_Static; - } - else - { - return VM_None; - } - } - return m_VoxelGIMode; - } - return VM_None; -} - -void CLightEntity::SetDesiredVoxelGIMode(EVoxelGIMode mode) -{ - m_VoxelGIMode = mode; -} - -void CLightEntity::SetName(const char* name) -{ - m_Name = name; - -#if defined(FEATURE_SVO_GI) - if (strstr(m_Name.c_str(), "_TI")) - { - if (strstr(m_Name.c_str(), "_TI_DYN")) - { - m_VoxelGIMode = VM_Dynamic; - } - else - { - m_VoxelGIMode = VM_Static; - } - } -#endif -} - -void CLightEntity::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_light.m_Origin += delta; - m_light.m_BaseOrigin += delta; - m_Matrix.SetTranslation(m_Matrix.GetTranslation() + delta); - m_WSBBox.Move(delta); -} - -void CLightEntity::ProcessPerObjectFrustum(ShadowMapFrustum* pFr, struct SPerObjectShadow* pPerObjectShadow, ILightSource* pLightSource, const SRenderingPassInfo& passInfo) -{ - assert(pFr); - CDLight& light = pLightSource->GetLightProperties(); - - pFr->RequestUpdate(); - pFr->ResetCasterLists(); - pFr->m_castersList.Add(pPerObjectShadow->pCaster); - - // get caster's bounding box and scale - AABB objectBBox; - pPerObjectShadow->pCaster->FillBBox(objectBBox); - Vec3 vExtents = 0.5f * objectBBox.GetSize().CompMul(pPerObjectShadow->vBBoxScale); - pFr->aabbCasters = AABB(objectBBox.GetCenter() - vExtents, objectBBox.GetCenter() + vExtents); - - pFr->m_Flags = light.m_Flags; - pFr->bUseAdditiveBlending = true; - uint nTexSize = aznumeric_caster(pPerObjectShadow->nTexSize * GetCVars()->e_ShadowsPerObjectResolutionScale); - nTexSize = clamp_tpl(nTexSize, 64, GetRenderer()->GetMaxTextureSize()); - pFr->nTexSize = 1 << IntegerLog2(nTexSize); - pFr->nTextureWidth = pFr->nTexSize; - pFr->nTextureHeight = pFr->nTexSize; - pFr->bBlendFrustum = false; - - // now update frustum params based on object box - AABB objectsBox = pFr->aabbCasters; - const Vec3 lightPos = light.m_Origin - passInfo.GetCamera().GetPosition() + objectsBox.GetCenter(); - const Vec3 lookAt = objectsBox.GetCenter(); - - pFr->vProjTranslation = objectsBox.GetCenter(); - pFr->vLightSrcRelPos = light.m_Origin - passInfo.GetCamera().GetPosition(); - pFr->fFOV = (float)RAD2DEG(atan_tpl(objectsBox.GetRadius() / (lookAt - lightPos).GetLength())) * 2.0f; - pFr->fProjRatio = 1.0f; - pFr->fNearDist = pFr->vLightSrcRelPos.GetLength() - objectsBox.GetRadius(); - pFr->fFarDist = pFr->vLightSrcRelPos.GetLength() + objectsBox.GetRadius(); - - pFr->fDepthConstBias = pPerObjectShadow->fConstBias; - pFr->fDepthSlopeBias = pPerObjectShadow->fSlopeBias; - pFr->fWidthS = pPerObjectShadow->fJitter; - pFr->fWidthT = pPerObjectShadow->fJitter; - pFr->fBlurS = 0.0f; - pFr->fBlurT = 0.0f; - - if (GetCVars()->e_ShadowsFrustums) - { - pFr->DrawFrustum(GetRenderer(), (GetCVars()->e_ShadowsFrustums == 1) ? 1000 : 1); - Get3DEngine()->DrawBBox(pFr->aabbCasters, Col_Green); - } -} diff --git a/Code/CryEngine/Cry3DEngine/LightEntity.h b/Code/CryEngine/Cry3DEngine/LightEntity.h deleted file mode 100644 index cc0e094561..0000000000 --- a/Code/CryEngine/Cry3DEngine/LightEntity.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_LIGHTENTITY_H -#define CRYINCLUDE_CRY3DENGINE_LIGHTENTITY_H -#pragma once - -const float LIGHT_PROJECTOR_MAX_FOV = 180.f; - -struct CLightEntity - : public ILightSource - , public Cry3DEngineBase -{ - static void StaticReset(); - -public: - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName(void) const { return "LightEntityClass"; } - virtual const char* GetName(void) const; - virtual Vec3 GetPos(bool) const; - virtual void Render(const SRendParams&, const SRenderingPassInfo& passInfo); - virtual void SetMaterial(_smart_ptr pMat) { m_pMaterial = pMat; } - virtual _smart_ptr GetMaterial([[maybe_unused]] Vec3* pHitPos = NULL) { return m_pMaterial; } - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void SetLightProperties(const CDLight& light); - virtual CDLight& GetLightProperties() { return m_light; }; - virtual void Release(bool); - virtual void SetMatrix(const Matrix34& mat); - virtual const Matrix34& GetMatrix() { return m_Matrix; } - virtual struct ShadowMapFrustum* GetShadowFrustum(int nId = 0); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - virtual void SetCastingException(IRenderNode* pNotCaster) { m_pNotCaster = pNotCaster; } - virtual bool IsLightAreasVisible(); - - virtual struct IStatObj* GetEntityStatObj([[maybe_unused]] unsigned int nPartId = 0, [[maybe_unused]] unsigned int nSubPartId = 0, [[maybe_unused]] Matrix34A* pMatrix = NULL, [[maybe_unused]] bool bReturnOnlyVisible = false) { return NULL; } - virtual int GetSlotCount() const; - virtual EVoxelGIMode GetVoxelGIMode() override; - virtual void SetDesiredVoxelGIMode(EVoxelGIMode mode) override; - virtual void SetName(const char* name); - void InitEntityShadowMapInfoStructure(); - void UpdateGSMLightSourceShadowFrustum(const SRenderingPassInfo& passInfo); - int UpdateGSMLightSourceDynamicShadowFrustum(int nDynamicLodCount, int nDistanceLodCount, float& fDistanceFromViewLastDynamicLod, float& fGSMBoxSizeLastDynamicLod, bool bFadeLastCascade, const SRenderingPassInfo& passInfo); - int UpdateGSMLightSourceCachedShadowFrustum(int nFirstLod, int nLodCount, float& fDistFromViewDynamicLod, float fRadiusDynamicLod, const SRenderingPassInfo& passInfo); - bool ProcessFrustum(int nLod, float fCamBoxSize, float fDistanceFromView, PodArray& lstCastersHull, const SRenderingPassInfo& passInfo); - static void ProcessPerObjectFrustum(ShadowMapFrustum* pFr, struct SPerObjectShadow* pPerObjectShadow, ILightSource* pLightSource, const SRenderingPassInfo& passInfo); - void InitShadowFrustum_SUN_Conserv(ShadowMapFrustum* pFr, int dwAllowedTypes, float fGSMBoxSize, float fDistance, int nLod, const SRenderingPassInfo& passInfo); - void InitShadowFrustum_PROJECTOR(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo); - void InitShadowFrustum_OMNI(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo); - void FillFrustumCastersList_SUN(ShadowMapFrustum* pFr, int dwAllowedTypes, int nRenderNodeFlags, PodArray& lstCastersHull, int nLod, const SRenderingPassInfo& passInfo); - void FillFrustumCastersList_PROJECTOR(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo); - void FillFrustumCastersList_OMNI(ShadowMapFrustum* pFr, int dwAllowedTypes, const SRenderingPassInfo& passInfo); - void CheckValidFrustums_OMNI(ShadowMapFrustum* pFr, const SRenderingPassInfo& passInfo); - bool CheckFrustumsIntersect(CLightEntity* lightEnt); - bool GetGsmFrustumBounds(const CCamera& viewFrustum, ShadowMapFrustum* pShadowFrustum); - void DetectCastersListChanges(ShadowMapFrustum* pFr, const SRenderingPassInfo& passInfo); - void OnCasterDeleted(IShadowCaster* pCaster); - int MakeShadowCastersHullSun(PodArray& lstCastersHull, const SRenderingPassInfo& passInfo); - static Vec3 GSM_GetNextScreenEdge(float fPrevRadius, float fPrevDistanceFromView, const SRenderingPassInfo& passInfo); - static float GSM_GetLODProjectionCenter(const Vec3& vEdgeScreen, float fRadius); - static bool FrustumIntersection(const CCamera& viewFrustum, const CCamera& shadowFrustum); - void UpdateCastShadowFlag(float fDistance, const SRenderingPassInfo& passInfo); - void CalculateShadowBias(ShadowMapFrustum* pFr, int nLod, float fGSMBoxSize) const; - - CLightEntity(); - ~CLightEntity(); - - CDLight m_light; - bool m_bShadowCaster : 1; - - _smart_ptr m_pMaterial; - Matrix34 m_Matrix; - IRenderNode* m_pNotCaster; - - // used for shadow maps - struct ShadowMapInfo - { - ShadowMapInfo() { memset(this, 0, sizeof(ShadowMapInfo)); } - void Release(struct IRenderer* pRenderer); - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - struct ShadowMapFrustum* pGSM[MAX_GSM_LODS_NUM]; - }* m_pShadowMapInfo; - - AABB m_WSBBox; - - void SetLayerId(uint16 nLayerId) { m_layerId = nLayerId; } - uint16 GetLayerId() { return m_layerId; } - -private: - static PodArray s_lstTmpCastersHull; - -private: - IStatObj* m_pStatObj; - - uint16 m_layerId; - EVoxelGIMode m_VoxelGIMode; - AZStd::string m_Name; -}; -#endif diff --git a/Code/CryEngine/Cry3DEngine/MatMan.cpp b/Code/CryEngine/Cry3DEngine/MatMan.cpp deleted file mode 100644 index 29c8ec1be5..0000000000 --- a/Code/CryEngine/Cry3DEngine/MatMan.cpp +++ /dev/null @@ -1,1577 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Material Manager Implementation - - -#include "Cry3DEngine_precompiled.h" -#include "MatMan.h" -#include "3dEngine.h" -#include "ObjMan.h" -#include "IRenderer.h" -#include "SurfaceTypeManager.h" -#include "CGFContent.h" -#include -#include -#include "MaterialUtils.h" // from crycommon -#include -#include - -#define MATERIAL_EXT ".mtl" -#define MATERIAL_NODRAW "nodraw" - -#define MATERIAL_DECALS_FOLDER "Materials/Decals" -#define MATERIAL_DECALS_SEARCH_WILDCARD "*.mtl" -#define MTL_LEVEL_CACHE_PAK "mtl.pak" - - -////////////////////////////////////////////////////////////////////////// -struct MaterialHelpers CMatMan::s_materialHelpers; - -int CMatMan::e_sketch_mode = 0; -int CMatMan::e_pre_sketch_spec = 0; -int CMatMan::e_texeldensity = 0; - -//------------------------------------------------------------------------------ -// Default textures declarations -//------------------------------------------------------------------------------ -#if !defined(_RELEASE) - // Texture names to be used for error / process loading indications - static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMe.tif"; - static const char* szTextureCompiling = "EngineAssets/TextureMsg/TextureCompiling.tif"; - static const char* szShaderCompiling = "EngineAssets/TextureMsg/ShaderCompiling.tif"; - static const char* szGeomNotBreakable = "EngineAssets/TextureMsg/GeomNotBreakable.tif"; -#else - // Some of the textures here will direct to the regular DefaultSolids_diff to prevent eye catching - // bug textures in release mode - static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMeRelease.tif"; - static const char* szTextureCompiling = "EngineAssets/TextureMsg/DefaultSolids_diff.tif"; - static const char* szShaderCompiling = "EngineAssets/TextureMsg/DefaultSolids_diff.tif"; - static const char* szGeomNotBreakable = "EngineAssets/TextureMsg/ReplaceMeRelease.tif"; -#endif - -static const char* szDefaultSolid = "EngineAssets/TextureMsg/DefaultSolids_diff.tif"; -static const char* szNormalDefault = "EngineAssets/Textures/white_ddn.dds"; -//------------------------------------------------------------------------------ - - -static void OnSketchModeChange(ICVar* pVar) -{ - int mode = pVar->GetIVal(); - ((CMatMan*)gEnv->p3DEngine->GetMaterialManager())->SetSketchMode(mode); -} - -static void OnDebugTexelDensityChange(ICVar* pVar) -{ - int mode = pVar->GetIVal(); - ((CMatMan*)gEnv->p3DEngine->GetMaterialManager())->SetTexelDensityDebug(mode); -} - -////////////////////////////////////////////////////////////////////////// -CMatMan::CMatMan() -{ - m_bInitialized = false; - m_bLoadSurfaceTypesInInit = true; - m_pListener = NULL; - m_pDefaultMtl = NULL; - m_pDefaultTerrainLayersMtl = NULL; - m_pDefaultLayersMtl = NULL; - m_pDefaultHelperMtl = NULL; - m_pNoDrawMtl = NULL; - - m_pSurfaceTypeManager = new CSurfaceTypeManager(GetSystem()); - - REGISTER_CVAR_CB(e_sketch_mode, 0, VF_CHEAT, "Enables Sketch mode drawing", OnSketchModeChange); - REGISTER_CVAR_CB(e_texeldensity, 0, VF_CHEAT, - "Enables texel density debug\n" - " 1: Objects texel density\n" - " 2: Objects texel density with colored mipmaps\n" - " 3: Terrain texel density\n" - " 4: Terrain texel density with colored mipmaps\n", - OnDebugTexelDensityChange); - - m_pXmlParser = GetISystem()->GetXmlUtils()->CreateXmlParser(); - - // Connect for LegacyAssetEventBus::Handler - BusConnect(AZ_CRC("mtl", 0xb01910e0)); -} - -////////////////////////////////////////////////////////////////////////// -CMatMan::~CMatMan() -{ - delete m_pSurfaceTypeManager; - int nNotUsed = 0, nNotUsedParents = 0; - - m_pDefaultMtl = nullptr; - m_pDefaultTerrainLayersMtl = nullptr; - m_pDefaultLayersMtl = nullptr; - m_pDefaultHelperMtl = nullptr; - m_pNoDrawMtl = nullptr; - - if (nNotUsed) - { - PrintMessage("Warning: CMatMan::~CMatMan: %d(%d) of %" PRISIZE_T " materials was not used in level", - nNotUsedParents, nNotUsed, m_mtlNameMap.size()); - } - - - // Disconnect for LegacyAssetEventBus::Handler - BusDisconnect(); -} - -////////////////////////////////////////////////////////////////////////// -AZStd::string CMatMan::UnifyName(const char* sMtlName) const -{ - if (strlen(sMtlName) > AZ_MAX_PATH_LEN) - { - AZ_Error("Rendering", false, "Error attempting to generate material identifier from the input '%s'. The length of the string exceeds the maximum path length. If you are using script canvas or lua to find or load a material, ensure you are using a valid path to a material as input.", sMtlName); - return AZStd::string(); - } - - char name[AZ_MAX_PATH_LEN]; - - azstrcpy(name, AZ_MAX_PATH_LEN, sMtlName); - MaterialUtils::UnifyMaterialName(name); - - return name; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::CreateMaterial(const char* sMtlName, int nMtlFlags) -{ - CMatInfo* pMat = new CMatInfo; - - //m_mtlSet.insert( pMat ); - pMat->SetName(sMtlName); - pMat->SetFlags(nMtlFlags | pMat->GetFlags()); - - if (!(nMtlFlags & MTL_FLAG_PURE_CHILD)) - { - AZStd::lock_guard lock(m_materialMapMutex); - m_mtlNameMap[ UnifyName(sMtlName) ] = pMat; - } - - if (nMtlFlags & MTL_FLAG_NON_REMOVABLE) - { - // Add reference to this material to prevent its deletion. - AZStd::lock_guard lock(m_nonRemovablesMutex); - m_nonRemovables.push_back(pMat); - } - return pMat; -} - -////////////////////////////////////////////////////////////////////////// -// A placeholder material while the original is loading. -// Add more edge case handling for various material types if required -_smart_ptr CMatMan::CreateMaterialPlaceholder(const char* materialName, int nMtlFlags, const char* textureName, _smart_ptr existingMtl) -{ - SInputShaderResources sr; - SShaderItem si; - - sr.m_LMaterial.m_Opacity = 1; - sr.m_LMaterial.m_Diffuse.set(1, 1, 1, 1); - sr.m_LMaterial.m_Specular.set(0, 0, 0, 0); - - // This will create texture data insertion to the table for the diffuse slot - sr.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name = textureName; - - if (nMtlFlags & MTL_FLAG_IS_TERRAIN) - si = GetRenderer()->EF_LoadShaderItem("Terrain.Layer", true, 0, &sr); - else if (nMtlFlags & MTL_FLAG_IS_SKY) - si = GetRenderer()->EF_LoadShaderItem("SkyHDR", true, 0, &sr); - else - si = GetRenderer()->EF_LoadShaderItem("Illum", true, 0, &sr); - - if (si.m_pShaderResources) - si.m_pShaderResources->SetMaterialName(materialName); - - if (existingMtl) - { - //For existing material we need to clear sub-materials, set flags and assign the new shader item. - existingMtl->SetSubMtlCount(0); - existingMtl->SetFlags(nMtlFlags); - existingMtl->AssignShaderItem(si); - - //Note: All PURE_CHILD materials are sub-materials, but not all sub-materials are PURE_CHILD. - //You can have one sub-material that shares some properties with another sub-material in the same parent, and overrides other properties. A sub-material that does this is not a pure child. - //But since it is seldom used, this should cover most cases when we want to know whether the material is a root. - if (!(nMtlFlags & MTL_FLAG_PURE_CHILD)) - { - AZStd::lock_guard lock(m_materialMapMutex); - m_mtlNameMap[UnifyName(materialName)] = existingMtl; - } - - return existingMtl; - } - else - { - _smart_ptr pMtl = CreateMaterial(materialName); - pMtl->AssignShaderItem(si); - return pMtl; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::NotifyCreateMaterial(_smart_ptr pMtl) -{ - if (m_pListener) - { - m_pListener->OnCreateMaterial(pMtl); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool CMatMan::Unregister(_smart_ptr pMat, bool deleteEditorMaterial) -{ - assert(pMat); - if (m_pListener && deleteEditorMaterial) - { - m_pListener->OnDeleteMaterial(pMat); - } - - if (!(pMat->GetFlags() & MTL_FLAG_PURE_CHILD)) - { - AZStd::lock_guard lock(m_materialMapMutex); - - AZStd::string unifiedName = UnifyName(pMat->GetName()); - m_pendingMaterialLoads.erase(unifiedName); - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::RenameMaterial(_smart_ptr pMtl, const char* sNewName) -{ - assert(pMtl); - - AZStd::lock_guard lock(m_materialMapMutex); - const char* sName = pMtl->GetName(); - AZStd::unique_ptr resetEvent = nullptr; - - if (*sName != '\0') - { - AZStd::string unifiedName = UnifyName(pMtl->GetName()); - - if (m_pendingMaterialLoads.find(unifiedName) != m_pendingMaterialLoads.end()) - { - resetEvent = std::move(m_pendingMaterialLoads[unifiedName]); - m_pendingMaterialLoads.erase(unifiedName); - } - - m_mtlNameMap.erase(unifiedName); - } - - pMtl->SetName(sNewName); - AZStd::string newUnifiedName = UnifyName(sNewName); - - m_mtlNameMap[newUnifiedName] = pMtl; - if (resetEvent != nullptr) - { - m_pendingMaterialLoads[newUnifiedName] = std::move(resetEvent); - } - -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::FindMaterial(const char* sMtlName) const -{ - AZStd::string name = UnifyName(sMtlName); - AZStd::lock_guard lock(m_materialMapMutex); - - MtlNameMap::const_iterator it = m_mtlNameMap.find(name); - - if (it == m_mtlNameMap.end()) - { - return 0; - } - - return it->second; -} - -//////////////////////////////////////////////////////////////////////////////// -//------------------------------------------------------------------------------ -_smart_ptr CMatMan::LoadMaterial(const char* sMtlName, bool bMakeIfNotFound, bool bNonremovable, unsigned long nLoadingFlags) -{ - return LoadMaterialInternal(sMtlName, bMakeIfNotFound, bNonremovable, nLoadingFlags); -} - - - -//////////////////////////////////////////////////////////////////////////////// -//------------------------------------------------------------------------------ -_smart_ptr CMatMan::LoadMaterialInternal(const char* sMtlName, bool bMakeIfNotFound, bool bNonremovable, unsigned long nLoadingFlags) -{ - if (!m_bInitialized) - { - InitDefaults(); - } - - if (m_pDefaultMtl && GetCVars()->e_StatObjPreload == 2) - { - return m_pDefaultMtl; - } - - AZStd::string name = UnifyName(sMtlName); - _smart_ptr pMtl = nullptr; - - UniqueManualEvent uniqueManualEvent = CheckMaterialCache(name, pMtl); - - if (pMtl != nullptr) - { - return pMtl; - } - - // Failed to retrieve from cache and failed to get 'permission' to safely load, abort load - if (!uniqueManualEvent.HasControl()) - { - if (bMakeIfNotFound) - { - pMtl = CreateMaterialPlaceholder(name.c_str(), nLoadingFlags, szDefaultSolid); - return pMtl; - } - return nullptr; - } - - LOADING_TIME_PROFILE_SECTION; // Only profile actually loading of the material. - - CRY_DEFINE_ASSET_SCOPE("Material", sMtlName); - - _smart_ptr materialRawPointer = pMtl; - - AZStd::string filename = name; - auto extPos = filename.find('.'); - - if (extPos == AZStd::string::npos) - { - filename += MATERIAL_EXT; - } - - - bool fileExists = AZ::IO::FileIOBase::GetInstance()->Exists(filename.c_str()); - if (!fileExists) - { - // If the material doesn't exist check if it's queued or being compiled. If so it means the file will become available shortly (as - // GetAssetStatus will push it to the top of the queue) and hot loading will take care of the file. If it's in a broken state, - // remove it as if loading failed. - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult(status, &AzFramework::AssetSystemRequestBus::Events::GetAssetStatus, filename); - - switch (status) - { - case AzFramework::AssetSystem::AssetStatus_Queued: - // Fall through - case AzFramework::AssetSystem::AssetStatus_Compiling: - { - AZStd::string unifiedName = UnifyName(filename.c_str()); - pMtl = CreateMaterialPlaceholder(unifiedName.c_str(), nLoadingFlags, szDefaultSolid ); - break; - } - - case AzFramework::AssetSystem::AssetStatus_Compiled: - // If the materials compiled it could be that between the check if it exists and getting the status it completed compilation. - // In this case, check the status again and load as normal if found, otherwise consider it an error. - if (AZ::IO::FileIOBase::GetInstance()->Exists(filename.c_str())) - { - fileExists = true; - break; - } - // else fall through - - case AzFramework::AssetSystem::AssetStatus_Unknown: - // Fall through - case AzFramework::AssetSystem::AssetStatus_Missing: - // Fall through - case AzFramework::AssetSystem::AssetStatus_Failed: - // Fall through - default: - { - AZStd::lock_guard lock(m_materialMapMutex); - uniqueManualEvent.Set(); - m_pendingMaterialLoads.erase(name); - break; - } - } - } - - if (fileExists) - { - // If the material already exists load it from the cache. If there's a build in flight the material will get reloaded - // when building finishes and if it's not in flight anymore the latest material will be loaded. - XmlNodeRef mtlNode = GetSystem()->LoadXmlFromFile(filename.c_str()); - - if (mtlNode) - { - pMtl = MakeMaterialFromXml(name, mtlNode, false, 0, nullptr, nLoadingFlags); - - if (pMtl && e_sketch_mode != 0) - { - ((CMatInfo*)pMtl.get())->SetSketchMode(e_sketch_mode); - } - } - else - { - //Loading has failed so evict from pending list. - AZStd::lock_guard lock(m_materialMapMutex); - uniqueManualEvent.Set(); - m_pendingMaterialLoads.erase(name); - } - } - - if (bNonremovable && pMtl) - { // mark as non-removable material on specific cases (probes..) - AZStd::lock_guard lock(m_nonRemovablesMutex); - m_nonRemovables.push_back((CMatInfo*)pMtl.get()); - } - - if (!pMtl && bMakeIfNotFound) - { - pMtl = CreateMaterialPlaceholder(name.c_str(), nLoadingFlags, szDefaultSolid); - } - - return pMtl; -} - -//! Let the first thread load the material, block the rest until its done so they can just use the cached version -template -UniqueManualEvent CMatMan::CheckMaterialCache(const AZStd::string& name, T& cachedMaterial) -{ - bool hasControl = false; - ManualResetEvent* manualResetEvent; - - AZStd::unique_lock lock(m_materialMapMutex); - - auto iterator = m_pendingMaterialLoads.find(name); - - if (iterator != m_pendingMaterialLoads.end()) - { - manualResetEvent = iterator->second.get(); - } - else - { - // Event not found, create one - hasControl = true; - manualResetEvent = new ManualResetEvent(); - m_pendingMaterialLoads.emplace(name, AZStd::unique_ptr(manualResetEvent)); - } - - if (!hasControl) - { - manualResetEvent->Wait(); - - MtlNameMap::const_iterator it = m_mtlNameMap.find(name); - - if (it != m_mtlNameMap.end()) - { - cachedMaterial = it->second; - } - else - { - cachedMaterial = nullptr; - } - } - - return UniqueManualEvent(manualResetEvent, hasControl); -} - - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::MakeMaterialFromXml(const AZStd::string& sMtlName, XmlNodeRef node, bool bForcePureChild, uint16 sortPrio /*= 0*/, _smart_ptr pExistingMtl /*= 0*/, unsigned long nLoadingFlags /*= 0*/, _smart_ptr pParentMtl /*= 0*/) -{ - int mtlFlags = 0; - CryFixedStringT<128> shaderName; - uint64 nShaderGenMask = 0; - SInputShaderResources sr; - - assert(node != 0); - - sr.m_SortPrio = sortPrio; - - // Loading - node->getAttr("MtlFlags", mtlFlags); - mtlFlags &= (MTL_FLAGS_SAVE_MASK); // Clean flags that are not supposed to be save/loaded. - if (bForcePureChild) - { - mtlFlags |= MTL_FLAG_PURE_CHILD; - } - - _smart_ptr pMtl = pExistingMtl; - if (!pMtl) - { - pMtl = CreateMaterial(sMtlName.c_str(), mtlFlags); - } - else - { - pMtl->SetFlags(mtlFlags | pMtl->GetFlags()); - pMtl->SetDirty(false); - } - - uint32 dccMaterialHash = 0; - node->getAttr("DccMaterialHash", dccMaterialHash); - pMtl->SetDccMaterialHash(dccMaterialHash); - - if (!(mtlFlags & MTL_FLAG_MULTI_SUBMTL)) - { - shaderName = node->getAttr("Shader"); - - if (!(mtlFlags & MTL_64BIT_SHADERGENMASK)) - { - uint32 nShaderGenMask32 = 0; - node->getAttr("GenMask", nShaderGenMask32); - nShaderGenMask = nShaderGenMask32; - - // Remap 32bit flags to 64 bit version - nShaderGenMask = GetRenderer()->EF_GetRemapedShaderMaskGen((const char*) shaderName, nShaderGenMask); - mtlFlags |= MTL_64BIT_SHADERGENMASK; - } - else - { - node->getAttr("GenMask", nShaderGenMask); - } - - if (node->haveAttr("StringGenMask")) - { - const char* pszShaderGenMask = node->getAttr("StringGenMask"); - nShaderGenMask = GetRenderer()->EF_GetShaderGlobalMaskGenFromString((const char*) shaderName, pszShaderGenMask, nShaderGenMask); // get common mask gen - } - else - { - // version doesn't have string gen mask yet ? Remap flags if needed - nShaderGenMask = GetRenderer()->EF_GetRemapedShaderMaskGen((const char*) shaderName, nShaderGenMask, ((mtlFlags & MTL_64BIT_SHADERGENMASK) != 0)); - } - mtlFlags |= MTL_64BIT_SHADERGENMASK; - - const char* surfaceType = node->getAttr("SurfaceType"); - pMtl->SetSurfaceType(surfaceType); - - if (azstricmp(shaderName, "nodraw") == 0) - { - mtlFlags |= MTL_FLAG_NODRAW; - } - - pMtl->SetFlags(mtlFlags | pMtl->GetFlags()); - - s_materialHelpers.SetLightingFromXml(sr, node); - s_materialHelpers.SetTexturesFromXml(sr, node); - s_materialHelpers.MigrateXmlLegacyData(sr, node); - - // Next warn about textures with drive letter in them - for (auto &iter : sr.m_TexturesResourcesMap ) - { - SEfResTexture* pTexture = &(iter.second); - const char* name = pTexture->m_Name; - if (name && (strchr(name, ':') != nullptr)) - { - CryLog("Invalid texture '%s' found in material '%s'", name, sMtlName.c_str()); - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have a link name - ////////////////////////////////////////////////////////////////////////// - XmlNodeRef pLinkName = node->findChild("MaterialLinkName"); - if (pLinkName) - { - const char* szLinkName = pLinkName->getAttr("name"); - pMtl->SetMaterialLinkName(szLinkName); - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have vertex deform. - ////////////////////////////////////////////////////////////////////////// - s_materialHelpers.SetVertexDeformFromXml(sr, node); - - ////////////////////////////////////////////////////////////////////////// - // Load public parameters. - XmlNodeRef publicVarsNode = node->findChild("PublicParams"); - - ////////////////////////////////////////////////////////////////////////// - // Reload shader item with new resources and shader. - if (!(mtlFlags & MTL_FLAG_MULTI_SUBMTL)) - { - sr.m_szMaterialName = sMtlName.c_str(); - - LoadMaterialShader(pMtl, pParentMtl, shaderName.c_str(), nShaderGenMask, sr, publicVarsNode); - pMtl->SetShaderName(shaderName); - } - else - { - //Release any shader item if assigned for material group - pMtl->ReleaseCurrentShaderItem(); - } - - ////////////////////////////////////////////////////////////////////////// - // Load material layers data - ////////////////////////////////////////////////////////////////////////// - - if (pMtl && pMtl->GetShaderItem().m_pShader && pMtl->GetShaderItem().m_pShaderResources) - { - XmlNodeRef pMtlLayersNode = node->findChild("MaterialLayers"); - if (pMtlLayersNode) - { - int nLayerCount = min((int) MTL_LAYER_MAX_SLOTS, (int) pMtlLayersNode->getChildCount()); - if (nLayerCount) - { - uint8 nMaterialLayerFlags = 0; - - pMtl->SetLayerCount(nLayerCount); - for (int l(0); l < nLayerCount; ++l) - { - XmlNodeRef pLayerNode = pMtlLayersNode->getChild(l); - if (pLayerNode) - { - if (const char* pszShaderName = pLayerNode->getAttr("Name")) - { - bool bNoDraw = false; - pLayerNode->getAttr("NoDraw", bNoDraw); - - uint8 nLayerFlags = 0; - if (bNoDraw) - { - nLayerFlags |= MTL_LAYER_USAGE_NODRAW; - - if (!azstricmp(pszShaderName, "frozenlayerwip")) - { - nMaterialLayerFlags |= MTL_LAYER_FROZEN; - } - } - else - { - nLayerFlags &= ~MTL_LAYER_USAGE_NODRAW; - } - - bool bFadeOut = false; - pLayerNode->getAttr("FadeOut", bFadeOut); - if (bFadeOut) - { - nLayerFlags |= MTL_LAYER_USAGE_FADEOUT; - } - else - { - nLayerFlags &= ~MTL_LAYER_USAGE_FADEOUT; - } - - XmlNodeRef pPublicsParamsNode = pLayerNode->findChild("PublicParams"); - sr.m_szMaterialName = sMtlName.c_str(); - LoadMaterialLayerSlot(l, pMtl, pszShaderName, sr, pPublicsParamsNode, nLayerFlags); - } - } - } - - SShaderItem& pShaderItemBase = pMtl->GetShaderItem(); - if (pShaderItemBase.m_pShaderResources) - { - pShaderItemBase.m_pShaderResources->SetMtlLayerNoDrawFlags(nMaterialLayerFlags); - } - } - } - } - - // Serialize sub materials. - XmlNodeRef childsNode = node->findChild("SubMaterials"); - if (childsNode) - { - int nSubMtls = childsNode->getChildCount(); - pMtl->SetSubMtlCount(nSubMtls); - for (int i = 0; i < nSubMtls; i++) - { - XmlNodeRef mtlNode = childsNode->getChild(i); - if (mtlNode->isTag("Material")) - { - const char* name = mtlNode->getAttr("Name"); - _smart_ptr pChildMtl = MakeMaterialFromXml(name, mtlNode, true, uint16(nSubMtls - i - 1), 0, nLoadingFlags, pMtl); - if (pChildMtl) - { - pMtl->SetSubMtl(i, pChildMtl); - } - else - { - pMtl->SetSubMtl(i, m_pDefaultMtl); - } - } - else - { - const char* name = mtlNode->getAttr("Name"); - if (name[0]) - { - _smart_ptr pChildMtl = LoadMaterial(name, true, false, nLoadingFlags); - if (pChildMtl) - { - pMtl->SetSubMtl(i, pChildMtl); - } - } - } - } - } - NotifyCreateMaterial(pMtl); - return pMtl; -} - -////////////////////////////////////////////////////////////////////////// -bool CMatMan::LoadMaterialShader(_smart_ptr pMtl, _smart_ptr pParentMtl, const char* sShader, uint64 nShaderGenMask, SInputShaderResources& sr, XmlNodeRef& publicsNode) -{ - // Mark material invalid by default. - sr.m_ResFlags = pMtl->GetFlags(); - - // Set public params. - if (publicsNode) - { - // Copy public params from the shader. - //sr.m_ShaderParams = shaderItem.m_pShader->GetPublicParams(); - // Parse public parameters, and assign them to source shader resources. - ParsePublicParams(sr, publicsNode); - //shaderItem.m_pShaderResources->SetShaderParams(&sr, shaderItem.m_pShader); - } - - SShaderItem shaderItem = gEnv->pRenderer->EF_LoadShaderItem(sShader, false, 0, &sr, nShaderGenMask); - if (!shaderItem.m_pShader || (shaderItem.m_pShader->GetFlags() & EF_NOTFOUND) != 0) - { - Warning("Failed to load shader \"%s\" in material \"%s\"", sShader, pMtl->GetName()); - if (!shaderItem.m_pShader) - { - return false; - } - } - pMtl->AssignShaderItem(shaderItem); - - return true; -} - -bool CMatMan::LoadMaterialLayerSlot(uint32 nSlot, _smart_ptr pMtl, const char* szShaderName, SInputShaderResources& pBaseResources, XmlNodeRef& pPublicsNode, uint8 nLayerFlags) -{ - if (!pMtl || pMtl->GetLayer(nSlot) || !pPublicsNode) - { - return false; - } - - // need to handle no draw case - if (azstricmp(szShaderName, "nodraw") == 0) - { - // no shader = skip layer - return false; - } - - // Get base material/shaderItem info - SInputShaderResources pInputResources; - SShaderItem& pShaderItemBase = pMtl->GetShaderItem(); - - uint32 nMaskGenBase = (uint32)pShaderItemBase.m_pShader->GetGenerationMask(); - SShaderGen* pShaderGenBase = pShaderItemBase.m_pShader->GetGenerationParams(); - - // copy diffuse and bump textures names - pInputResources.m_szMaterialName = pBaseResources.m_szMaterialName; - - // The following copies the entire texture data for this slot as it did not exist in the map - if (pBaseResources.GetTextureResource(EFTT_DIFFUSE)) - { - pInputResources.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name = pBaseResources.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name; - } - - if (pBaseResources.GetTextureResource(EFTT_NORMALS)) - { - pInputResources.m_TexturesResourcesMap[EFTT_NORMALS].m_Name = pBaseResources.m_TexturesResourcesMap[EFTT_NORMALS].m_Name; - } - - // Names validity - if the texture slot doesn't exist or no name replace with default textures - if (pInputResources.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name.empty()) - { - pInputResources.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name = szReplaceMe; - } - - if (pInputResources.m_TexturesResourcesMap[EFTT_NORMALS].m_Name.empty()) - { - pInputResources.m_TexturesResourcesMap[EFTT_NORMALS].m_Name = szNormalDefault; - } - // Load layer shader item - IShader* pNewShader = gEnv->pRenderer->EF_LoadShader(szShaderName, 0); - if (!pNewShader) - { - Warning("Failed to load material layer shader %s in Material %s", szShaderName, pMtl->GetName()); - return false; - } - - // mask generation for base material shader - uint32 nMaskGenLayer = 0; - SShaderGen* pShaderGenLayer = pNewShader->GetGenerationParams(); - if (pShaderGenBase && pShaderGenLayer) - { - for (unsigned nLayerBit(0); nLayerBit < pShaderGenLayer->m_BitMask.size(); ++nLayerBit) - { - SShaderGenBit* pLayerBit = pShaderGenLayer->m_BitMask[nLayerBit]; - - for (unsigned nBaseBit(0); nBaseBit < pShaderGenBase->m_BitMask.size(); ++nBaseBit) - { - SShaderGenBit* pBaseBit = pShaderGenBase->m_BitMask[nBaseBit]; - - // Need to check if flag name is common to both shaders (since flags values can be different), if so activate it on this layer - if (nMaskGenBase & pBaseBit->m_Mask) - { - if (!pLayerBit->m_ParamName.empty() && !pBaseBit->m_ParamName.empty()) - { - if (pLayerBit->m_ParamName == pBaseBit->m_ParamName) - { - nMaskGenLayer |= pLayerBit->m_Mask; - break; - } - } - } - } - } - } - - // Reload with proper flags - IShader* pShader = gEnv->pRenderer->EF_LoadShader(szShaderName, 0, nMaskGenLayer); - if (!pShader) - { - Warning("Failed to load material layer shader %s in Material %s", szShaderName, pMtl->GetName()); - SAFE_RELEASE(pNewShader); - return false; - } - SAFE_RELEASE(pNewShader); - - // Copy public params from the shader. - //pInputResources.m_ShaderParams = pShaderItem.m_pShader->GetPublicParams(); - - // Copy resources from base material - SShaderItem ShaderItem(pShader, pShaderItemBase.m_pShaderResources->Clone()); - - ParsePublicParams(pInputResources, pPublicsNode); - - // Parse public parameters, and assign them to source shader resources. - ShaderItem.m_pShaderResources->SetShaderParams(&pInputResources, ShaderItem.m_pShader); - - IMaterialLayer* pCurrMtlLayer = pMtl->CreateLayer(); - - pCurrMtlLayer->SetFlags(nLayerFlags); - pCurrMtlLayer->SetShaderItem(pMtl, ShaderItem); - - // Clone returns an instance with a refcount of 1, and SetShaderItem increments it, so - // we need to release the cloned ref. - SAFE_RELEASE(ShaderItem.m_pShaderResources); - SAFE_RELEASE(ShaderItem.m_pShader); - - pMtl->SetLayer(nSlot, pCurrMtlLayer); - - return true; -} - -////////////////////////////////////////////////////////////////////////// - -static void shGetVector4(const char* buf, float v[4]) -{ - if (!buf) - { - return; - } -#if !defined(NDEBUG) - int res = -#endif - azsscanf(buf, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]); - assert(res); -} - -void CMatMan::ParsePublicParams(SInputShaderResources& sr, XmlNodeRef paramsNode) -{ - sr.m_ShaderParams.clear(); - - int nA = paramsNode->getNumAttributes(); - if (!nA) - { - return; - } - - for (int i = 0; i < nA; i++) - { - const char* key = NULL, * val = NULL; - paramsNode->getAttributeByIndex(i, &key, &val); - SShaderParam Param; - assert(val && key); - Param.m_Name = key; - Param.m_Value.m_Color[0] = Param.m_Value.m_Color[1] = Param.m_Value.m_Color[2] = Param.m_Value.m_Color[3] = 0; - shGetVector4(val, Param.m_Value.m_Color); - Param.m_Type = eType_FCOLOR; - sr.m_ShaderParams.push_back(Param); - } -} - -////////////////////////////////////////////////////////////////////////// -ISurfaceType* CMatMan::GetSurfaceTypeByName(const char* sSurfaceTypeName, const char* sWhy) -{ - return m_pSurfaceTypeManager->GetSurfaceTypeByName(sSurfaceTypeName, sWhy); -}; - -////////////////////////////////////////////////////////////////////////// -int CMatMan::GetSurfaceTypeIdByName(const char* sSurfaceTypeName, const char* sWhy) -{ - ISurfaceType* pSurfaceType = m_pSurfaceTypeManager->GetSurfaceTypeByName(sSurfaceTypeName, sWhy); - if (pSurfaceType) - { - return pSurfaceType->GetId(); - } - return 0; -}; - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::GetDefaultLayersMaterial() -{ - if (!m_bInitialized) - { - InitDefaults(); - } - - return m_pDefaultLayersMtl; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::GetDefaultHelperMaterial() -{ - if (!m_bInitialized) - { - InitDefaults(); - } - - return m_pDefaultHelperMtl; -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::GetLoadedMaterials(AZStd::vector<_smart_ptr>* pData, uint32& nObjCount) const -{ - AZStd::lock_guard lock(m_materialMapMutex); - nObjCount = m_mtlNameMap.size(); - - if (!pData) - { - return; - } - - MtlNameMap::const_iterator it, end = m_mtlNameMap.end(); - - for (it = m_mtlNameMap.begin(); it != end; ++it) - { - _smart_ptr pMat = it->second; - - pData->push_back(pMat); - } -} - - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::CloneMaterial(_smart_ptr pSrcMtl, int nSubMtl) -{ - if (pSrcMtl->GetFlags() & MTL_FLAG_MULTI_SUBMTL) - { - _smart_ptr pMultiMat = new CMatInfo; - - //m_mtlSet.insert( pMat ); - pMultiMat->SetName(pSrcMtl->GetName()); - pMultiMat->SetFlags(pMultiMat->GetFlags() | MTL_FLAG_MULTI_SUBMTL); - - bool bCloneAllSubMtls = nSubMtl < 0; - - int nSubMtls = pSrcMtl->GetSubMtlCount(); - pMultiMat->SetSubMtlCount(nSubMtls); - for (int i = 0; i < nSubMtls; i++) - { - CMatInfo* pChildSrcMtl = (CMatInfo*)pSrcMtl->GetSubMtl(i).get(); - if (!pChildSrcMtl) - { - continue; - } - if (bCloneAllSubMtls) - { - pMultiMat->SetSubMtl(i, pChildSrcMtl->Clone()); - } - else - { - pMultiMat->SetSubMtl(i, pChildSrcMtl); - if (i == nSubMtls) - { - // Clone this slot. - pMultiMat->SetSubMtl(i, pChildSrcMtl->Clone()); - } - } - } - return pMultiMat; - } - else - { - _smart_ptr pMat = reinterpret_cast(pSrcMtl.get())->Clone(); - return pMat; - } -} - -void CMatMan::CopyMaterial(_smart_ptr pMtlSrc, _smart_ptr pMtlDest, EMaterialCopyFlags flags) -{ - ((CMatInfo*)pMtlSrc.get())->Copy(pMtlDest, flags); -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::CloneMultiMaterial(_smart_ptr pSrcMtl, const char* sSubMtlName) -{ - if (pSrcMtl->GetFlags() & MTL_FLAG_MULTI_SUBMTL) - { - _smart_ptr pMultiMat = new CMatInfo; - - //m_mtlSet.insert( pMat ); - pMultiMat->SetName(pSrcMtl->GetName()); - pMultiMat->SetFlags(pMultiMat->GetFlags() | MTL_FLAG_MULTI_SUBMTL); - - bool bCloneAllSubMtls = sSubMtlName == 0; - - int nSubMtls = pSrcMtl->GetSubMtlCount(); - pMultiMat->SetSubMtlCount(nSubMtls); - for (int i = 0; i < nSubMtls; i++) - { - CMatInfo* pChildSrcMtl = (CMatInfo*)pSrcMtl->GetSubMtl(i).get(); - if (!pChildSrcMtl) - { - continue; - } - if (bCloneAllSubMtls) - { - pMultiMat->SetSubMtl(i, pChildSrcMtl->Clone()); - } - else - { - pMultiMat->SetSubMtl(i, pChildSrcMtl); - if (azstricmp(pChildSrcMtl->GetName(), sSubMtlName) == 0) - { - // Clone this slot. - pMultiMat->SetSubMtl(i, pChildSrcMtl->Clone()); - } - } - } - return pMultiMat; - } - else - { - return ((CMatInfo*)pSrcMtl.get())->Clone(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::DoLoadSurfaceTypesInInit(bool doLoadSurfaceTypesInInit) -{ - m_bLoadSurfaceTypesInInit = doLoadSurfaceTypesInInit; -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::InitDefaults() -{ - if (m_bInitialized) - { - return; - } - m_bInitialized = true; - - LOADING_TIME_PROFILE_SECTION; - - SYNCHRONOUS_LOADING_TICK(); - - if (m_bLoadSurfaceTypesInInit) - { - m_pSurfaceTypeManager->LoadSurfaceTypes(); - } - - if (!m_pDefaultMtl) - { - // This line is REQUIRED by the buildbot testing framework to determine when tests have formally started. Please inform WillW or Morgan before changing this. - CryLogAlways("Initializing default materials..."); - m_pDefaultMtl = CreateMaterialPlaceholder("Default", 0, szReplaceMe); - } - - if (!m_pDefaultTerrainLayersMtl) - { - m_pDefaultTerrainLayersMtl = CreateMaterialPlaceholder("DefaultTerrainLayer", MTL_FLAG_IS_TERRAIN, szReplaceMe); - } - - if (!m_pDefaultLayersMtl) - { - m_pDefaultLayersMtl = LoadMaterial("Materials/material_layers_default", false); - } - - if (!m_pNoDrawMtl) - { - m_pNoDrawMtl = new CMatInfo; - m_pNoDrawMtl->SetFlags(MTL_FLAG_NODRAW); - m_pNoDrawMtl->SetName(MATERIAL_NODRAW); - SShaderItem si; - si.m_pShader = GetRenderer()->EF_LoadShader(MATERIAL_NODRAW, 0); - m_pNoDrawMtl->AssignShaderItem(si); - - AZStd::string unifiedName = UnifyName(m_pNoDrawMtl->GetName()); - auto* resetEvent = new ManualResetEvent(); - resetEvent->Set(); - - m_mtlNameMap[unifiedName] = m_pNoDrawMtl; - m_pendingMaterialLoads.emplace(unifiedName, AZStd::unique_ptr(resetEvent)); - } - - if (!m_pDefaultHelperMtl) - { - m_pDefaultHelperMtl = new CMatInfo; - m_pDefaultHelperMtl->SetName("DefaultHelper"); - SInputShaderResources sr; - sr.m_LMaterial.m_Opacity = 1; - sr.m_LMaterial.m_Diffuse.set(1, 1, 1, 1); - // Notice that the following line creates a texture data slot, inserts it and set the texture name - sr.m_TexturesResourcesMap[EFTT_DIFFUSE].m_Name = szReplaceMe; - SShaderItem si = GetRenderer()->EF_LoadShaderItem("Helper", true, 0, &sr); - if (si.m_pShaderResources) - { - si.m_pShaderResources->SetMaterialName("DefaultHelper"); - } - m_pDefaultHelperMtl->AssignShaderItem(si); - } - - SLICE_AND_SLEEP(); -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::LoadCGFMaterial(CMaterialCGF* pMaterialCGF, const char* sCgfFilename, unsigned long nLoadingFlags) -{ - FUNCTION_PROFILER_3DENGINE; - LOADING_TIME_PROFILE_SECTION; - - CryPathString sMtlName = pMaterialCGF->name; - if (sMtlName.find('/') == stack_string::npos) - { - // If no slashes in the name assume it is in same folder as a cgf. - sMtlName = PathUtil::AddSlash(PathUtil::GetPath(stack_string(sCgfFilename))) + sMtlName; - } - else - { - sMtlName = PathUtil::MakeGamePath(sMtlName); - } - return LoadMaterial(sMtlName.c_str(), true, false, nLoadingFlags); -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::SetSketchMode(int mode) -{ - if (mode != 0) - { - gEnv->pConsole->ExecuteString("exec sketch_on"); - } - else - { - gEnv->pConsole->ExecuteString("exec sketch_off"); - } - - AZStd::lock_guard lock(m_materialMapMutex); - - for (MtlNameMap::iterator it = m_mtlNameMap.begin(); it != m_mtlNameMap.end(); ++it) - { - CMatInfo* pMtl = (CMatInfo*)it->second.get(); - pMtl->SetSketchMode(mode); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::SetTexelDensityDebug(int mode) -{ - AZStd::lock_guard lock(m_materialMapMutex); - - for (MtlNameMap::iterator it = m_mtlNameMap.begin(); it != m_mtlNameMap.end(); ++it) - { - CMatInfo* pMtl = (CMatInfo*)it->second.get(); - pMtl->SetTexelDensityDebug(mode); - } -} - - -namespace -{ - static bool IsPureChild(_smart_ptr pMtl) - { - return (pMtl->GetFlags() & MTL_FLAG_PURE_CHILD) ? true : false; - } - static bool IsMultiSubMaterial(_smart_ptr pMtl) - { - return (pMtl->GetFlags() & MTL_FLAG_MULTI_SUBMTL) ? true : false; - }; -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::ReloadMaterial(_smart_ptr pMtl) -{ - AZStd::string name = UnifyName(pMtl->GetName()); - - AZStd::string filename = name; - auto extPos = filename.find('.'); - if (extPos == AZStd::string::npos) - { - filename += MATERIAL_EXT; - } - - XmlNodeRef mtlNode = GetSystem()->LoadXmlFromFile(filename.c_str()); - - if (mtlNode) - { - // This should reload the Material's data in-place without modifying any - // material management registration. Otherwise we would have to send some - // kind of messages about the material being replaced to every object - // with a pointer to it. - MakeMaterialFromXml(name, mtlNode, false, 0, pMtl); - } - else - { - AZ_Warning("Material System", false, "Failed to re-load %s", filename.c_str()); - } -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::LoadMaterialFromXml(const char* sMtlName, XmlNodeRef mtlNode) -{ - AZStd::string name = UnifyName(sMtlName); - - AZStd::unique_lock lock(m_materialMapMutex); - MtlNameMap::const_iterator it = m_mtlNameMap.find(name); - - _smart_ptr pMtl = 0; - - if (it != m_mtlNameMap.end()) - { - pMtl = it->second; - pMtl = MakeMaterialFromXml(name, mtlNode, false, 0, pMtl); - return pMtl; - } - - if (!pMtl) - { - pMtl = MakeMaterialFromXml(name, mtlNode, false); - } - - return pMtl; -} - -////////////////////////////////////////////////////////////////////////// -bool CMatMan::SaveMaterial(XmlNodeRef node, _smart_ptr pMtl) -{ - // Saving. - node->setAttr("MtlFlags", pMtl->GetFlags()); - node->setAttr("DccMaterialHash", pMtl->GetDccMaterialHash()); - - SShaderItem& si = pMtl->GetShaderItem(0); - SInputShaderResources m_shaderResources = SInputShaderResources(si.m_pShaderResources); - - if (!IsMultiSubMaterial(pMtl)) - { - node->setAttr("Shader", si.m_pShader->GetName()); - node->setAttr("GenMask", si.m_pShader->GetGenerationMask()); - node->setAttr("SurfaceType", pMtl->GetSurfaceType() ? pMtl->GetSurfaceType()->GetName() : NULL); - - SInputShaderResources& sr = m_shaderResources; - //if (!m_shaderName.IsEmpty() && (azstricmp(m_shaderName,"nodraw") != 0)) - { - s_materialHelpers.SetXmlFromLighting(sr, node); - s_materialHelpers.SetXmlFromTextures(sr, node); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Save out the link name if present - ////////////////////////////////////////////////////////////////////////// - const char* szLinkName = pMtl->GetMaterialLinkName(); - if (szLinkName != 0 && strlen(szLinkName)) - { - XmlNodeRef pLinkName = node->newChild("MaterialLinkName"); - pLinkName->setAttr("name", szLinkName); - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have vertex deform. - ////////////////////////////////////////////////////////////////////////// - s_materialHelpers.SetXmlFromVertexDeform(m_shaderResources, node); - - if (pMtl->GetSubMtlCount() > 0) - { - // Serialize sub materials. - XmlNodeRef childsNode = node->newChild("SubMaterials"); - for (int i = 0; i < pMtl->GetSubMtlCount(); i++) - { - _smart_ptr pSubMtl = pMtl->GetSubMtl(i); - if (pSubMtl && IsPureChild(pSubMtl)) - { - XmlNodeRef mtlNode = childsNode->newChild("Material"); - mtlNode->setAttr("Name", pSubMtl->GetName()); - SaveMaterial(mtlNode, pSubMtl); - } - else - { - XmlNodeRef mtlNode = childsNode->newChild("MaterialRef"); - if (pSubMtl) - { - mtlNode->setAttr("Name", pSubMtl->GetName()); - } - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Save public parameters. - ////////////////////////////////////////////////////////////////////////// - /* - if (m_publicVarsCache) - { - node->addChild( m_publicVarsCache ); - } - else */ - - if (!m_shaderResources.m_ShaderParams.empty()) - { - XmlNodeRef publicsNode = node->newChild("PublicParams"); - s_materialHelpers.SetXmlFromShaderParams(m_shaderResources, publicsNode); - } - - ////////////////////////////////////////////////////////////////////////// - // Save material layers data - ////////////////////////////////////////////////////////////////////////// - - bool bMaterialLayers = false; - for (int l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - const IMaterialLayer* pLayer = pMtl->GetLayer(l); - if (pLayer && pLayer->GetShaderItem().m_pShader && strlen(pLayer->GetShaderItem().m_pShader->GetName()) != 0) - { - bMaterialLayers = true; - break; - } - } - - if (bMaterialLayers) - { - XmlNodeRef mtlLayersNode = node->newChild("MaterialLayers"); - for (int l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - XmlNodeRef layerNode = mtlLayersNode->newChild("Layer"); - const IMaterialLayer* pLayer = pMtl->GetLayer(l); - if (pLayer && pLayer->GetShaderItem().m_pShader && strlen(pLayer->GetShaderItem().m_pShader->GetName()) != 0) - { - SInputShaderResources shaderRes(pLayer->GetShaderItem().m_pShaderResources); - - layerNode->setAttr("Name", pLayer->GetShaderItem().m_pShader->GetName()); - layerNode->setAttr("NoDraw", pLayer->GetShaderItem().m_pShader->GetFlags() & MTL_LAYER_USAGE_NODRAW); - layerNode->setAttr("FadeOut", pLayer->GetShaderItem().m_pShader->GetFlags() & MTL_LAYER_USAGE_FADEOUT); - - if (!shaderRes.m_ShaderParams.empty()) - { - XmlNodeRef publicsNode = layerNode->newChild("PublicParams"); - s_materialHelpers.SetXmlFromShaderParams(shaderRes, publicsNode); - } - } - } - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::PreloadLevelMaterials() -{ - LOADING_TIME_PROFILE_SECTION; - - //bool bMtlfCacheExist = GetISystem()->GetIResourceManager()->LoadLevelCachePak( MTL_LEVEL_CACHE_PAK,"" ); - //if (!bMtlfCacheExist) - //return; - - PrintMessage("==== Starting Loading Level Materials ===="); - float fStartTime = GetCurAsyncTimeSec(); - - auto pResList = GetISystem()->GetIResourceManager()->GetLevelResourceList(); - - if (!pResList) - { - Error("Error loading level Materials: resource list is NULL"); - return; - } - - int nCounter = 0; - int nInLevelCacheCount = 0; - - _smart_ptr pXmlParser = GetISystem()->GetXmlUtils()->CreateXmlParser(); - - // Request objects loading from Streaming System. - CryPathString mtlName; - CryPathString mtlFilename; - CryPathString mtlCacheFilename; - for (const char* sName = pResList->GetFirst(); sName != NULL; sName = pResList->GetNext()) - { - if (strstr(sName, ".mtl") == 0 && strstr(sName, ".binmtl") == 0) - { - continue; - } - - mtlFilename = sName; - - mtlName = sName; - PathUtil::RemoveExtension(mtlName); - - if (FindMaterial(mtlName)) - { - continue; - } - - // Load this material as un-removable. - _smart_ptr pMtl = LoadMaterial(mtlName, false, true); - if (pMtl) - { - nCounter++; - } - - //This loop can take a few seconds, so we should refresh the loading screen and call the loading tick functions to ensure that no big gaps in coverage occur. - SYNCHRONOUS_LOADING_TICK(); - } - - //GetISystem()->GetIResourceManager()->UnloadLevelCachePak( MTL_LEVEL_CACHE_PAK ); - PrintMessage("==== Finished loading level Materials: %d mtls loaded (%d from LevelCache) in %.1f sec ====", nCounter, nInLevelCacheCount, GetCurAsyncTimeSec() - fStartTime); -} - - -////////////////////////////////////////////////////////////////////////// -void CMatMan::PreloadDecalMaterials() -{ - LOADING_TIME_PROFILE_SECTION; - - float fStartTime = GetCurAsyncTimeSec(); - - bool bVerboseLogging = GetCVars()->e_StatObjPreload > 1; - int nCounter = 0; - - // Wildcards load. - CryPathString sPath = PathUtil::Make(CryPathString(MATERIAL_DECALS_FOLDER), CryPathString(MATERIAL_DECALS_SEARCH_WILDCARD)); - PrintMessage("===== Loading all Decal materials from a folder: %s =====", sPath.c_str()); - - AZStd::vector mtlFiles; - SDirectoryEnumeratorHelper dirHelper; - dirHelper.ScanDirectoryRecursive(gEnv->pCryPak, "", MATERIAL_DECALS_FOLDER, MATERIAL_DECALS_SEARCH_WILDCARD, mtlFiles); - - for (int i = 0, num = (int)mtlFiles.size(); i < num; i++) - { - CryPathString sMtlName{ mtlFiles[i].data(), mtlFiles[i].size() }; - PathUtil::RemoveExtension(sMtlName); - - if (bVerboseLogging) - { - CryLog("Preloading Decal Material: %s", sMtlName.c_str()); - } - - _smart_ptr pMtl = LoadMaterial(sMtlName.c_str(), false, true); // Load material as non-removable - if (pMtl) - { - nCounter++; - } - } - PrintMessage("==== Finished Loading Decal Materials: %d mtls loaded in %.1f sec ====", nCounter, GetCurAsyncTimeSec() - fStartTime); -} - -////////////////////////////////////////////////////////////////////////// -void CMatMan::ShutDown() -{ - CryLogAlways("shutting down mat man\n"); - { - AZStd::unique_lock lock(m_materialMapMutex); - - m_pXmlParser = 0; - - m_mtlNameMap.clear(); - m_pendingMaterialLoads.clear(); - } - - { - AZStd::lock_guard lock(m_nonRemovablesMutex); - stl::free_container(m_nonRemovables); - } - - // Free default materials - m_pDefaultMtl = nullptr; - m_pDefaultTerrainLayersMtl = nullptr; - m_pNoDrawMtl = nullptr; - m_pDefaultHelperMtl = nullptr; - m_pDefaultLayersMtl = nullptr; - - - - m_pSurfaceTypeManager->RemoveAll(); - m_bInitialized = false; -} - - -void CMatMan::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pDefaultMtl); - pSizer->AddObject(m_pDefaultLayersMtl); - pSizer->AddObject(m_pDefaultTerrainLayersMtl); - pSizer->AddObject(m_pNoDrawMtl); - pSizer->AddObject(m_pDefaultHelperMtl); - pSizer->AddObject(m_pSurfaceTypeManager); - pSizer->AddObject(m_pXmlParser); - - pSizer->AddObject(m_mtlNameMap); - pSizer->AddObject(m_pendingMaterialLoads); - pSizer->AddObject(m_nonRemovables); -} - -void CMatMan::UpdateShaderItems() -{ - AZStd::lock_guard lock(m_materialMapMutex); - - for (MtlNameMap::iterator iter = m_mtlNameMap.begin(); iter != m_mtlNameMap.end(); ++iter) - { - CMatInfo* pMaterial = static_cast(iter->second.get()); - pMaterial->UpdateShaderItems(); - } -} - -void CMatMan::RefreshMaterialRuntime() -{ - RefreshShaderResourceConstants(); -} - -void CMatMan::RefreshShaderResourceConstants() -{ - AZStd::lock_guard lock(m_materialMapMutex); - - for (MtlNameMap::iterator iter = m_mtlNameMap.begin(); iter != m_mtlNameMap.end(); ++iter) - { - CMatInfo* pMaterial = static_cast(iter->second.get()); - pMaterial->RefreshShaderResourceConstants(); - } -} - -// override from LegacyAssetEventBus::Handler -// Notifies listeners that a file changed -void CMatMan::OnFileChanged(AZStd::string assetPath) -{ - _smart_ptr mat = FindMaterial(assetPath.c_str()); - - //Reload material pointer in place if the material is found - if (mat) - { - ReloadMaterial(mat); - } -} - -void CMatMan::OnFileRemoved(AZStd::string assetPath) -{ - _smart_ptr mat = FindMaterial(assetPath.c_str()); - - //Reload the material in place to a place holder - if (mat) - { - Unregister(mat); - CreateMaterialPlaceholder(mat->GetName(), mat->GetFlags(), szDefaultSolid, mat); - } -} - diff --git a/Code/CryEngine/Cry3DEngine/MatMan.h b/Code/CryEngine/Cry3DEngine/MatMan.h deleted file mode 100644 index 6706471f70..0000000000 --- a/Code/CryEngine/Cry3DEngine/MatMan.h +++ /dev/null @@ -1,256 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_MATMAN_H -#define CRYINCLUDE_CRY3DENGINE_MATMAN_H -#pragma once - -#include "Cry3DEngineBase.h" -#include "SurfaceTypeManager.h" -#include -#include "MaterialHelpers.h" -#include -#include -#include - -// forward declarations. -struct IMaterial; -struct ISurfaceType; -struct ISurfaceTypeManager; -class CMatInfo; - -class ManualResetEvent -{ -public: - ManualResetEvent() - : m_flag(false), - m_mutex(), - m_conditionVariable() - { - } - - void Wait() - { - AZStd::unique_lock lock(m_mutex); - m_conditionVariable.wait(lock, [this] - { - return m_flag == true; - }); - } - - void Set() - { - { - AZStd::unique_lock lock(m_mutex); - m_flag = true; - } - - m_conditionVariable.notify_all(); - } - - void Unset() - { - AZStd::unique_lock lock(m_mutex); - m_flag = false; - } - - bool IsSet() const - { - AZStd::unique_lock lock(m_mutex); - return m_flag; - } - -private: - bool m_flag; - mutable AZStd::mutex m_mutex; - AZStd::condition_variable m_conditionVariable; -}; - -class UniqueManualEvent -{ -public: - UniqueManualEvent(ManualResetEvent* manualResetEvent, bool hasControl) - : m_manualResetEvent(manualResetEvent), - m_hasControl(hasControl) - { - - } - - //! Indicates if the current thread has control of the event and is blocking other threads from proceeding - bool HasControl() const - { - return m_hasControl; - } - - void Set() - { - if (m_hasControl) - { - m_manualResetEvent->Set(); - m_hasControl = false; - } - } - - ~UniqueManualEvent() - { - Set(); - } - -private: - bool m_hasControl; - ManualResetEvent* m_manualResetEvent; -}; - -////////////////////////////////////////////////////////////////////////// -// -// CMatMan is a material manager class. -// -////////////////////////////////////////////////////////////////////////// -class CMatMan - : public IMaterialManager - , public Cry3DEngineBase - , public AzFramework::LegacyAssetEventBus::Handler -{ -public: - CMatMan(); - virtual ~CMatMan(); - - void ShutDown(); - - // interface IMaterialManager -------------------------------------------------------- - - virtual _smart_ptr CreateMaterial(const char* sMtlName, int nMtlFlags = 0); - virtual _smart_ptr FindMaterial(const char* sMtlName) const; - virtual _smart_ptr LoadMaterial(const char* sMtlName, bool bMakeIfNotFound = true, bool bNonremovable = false, unsigned long nLoadingFlags = 0); - virtual _smart_ptr LoadMaterialFromXml(const char* sMtlName, XmlNodeRef mtlNode); - virtual void ReloadMaterial(_smart_ptr pMtl); - virtual void SetListener(IMaterialManagerListener* pListener) { m_pListener = pListener; }; - virtual _smart_ptr GetDefaultMaterial(); - virtual _smart_ptr GetDefaultTerrainLayerMaterial() - { - if (!m_bInitialized) - { - InitDefaults(); - } - return m_pDefaultTerrainLayersMtl; - } - virtual _smart_ptr GetDefaultLayersMaterial(); - virtual _smart_ptr GetDefaultHelperMaterial(); - virtual ISurfaceType* GetSurfaceTypeByName(const char* sSurfaceTypeName, const char* sWhy = NULL); - virtual int GetSurfaceTypeIdByName(const char* sSurfaceTypeName, const char* sWhy = NULL); - virtual ISurfaceType* GetSurfaceType(int nSurfaceTypeId, const char* sWhy = NULL) - { - return m_pSurfaceTypeManager->GetSurfaceTypeFast(nSurfaceTypeId, sWhy); - } - virtual ISurfaceTypeManager* GetSurfaceTypeManager() { return m_pSurfaceTypeManager; } - - _smart_ptr LoadCGFMaterial(CMaterialCGF* pMaterialCGF, const char* sCgfFilename, unsigned long nLoadingFlags = 0) override; - virtual _smart_ptr CloneMaterial(_smart_ptr pMtl, int nSubMtl = -1); - virtual _smart_ptr CloneMultiMaterial(_smart_ptr pMtl, const char* sSubMtlName = 0); - virtual void GetLoadedMaterials(AZStd::vector<_smart_ptr>* pData, uint32& nObjCount) const; - - virtual bool SaveMaterial(XmlNodeRef mtlNode, _smart_ptr pMtl); - virtual void CopyMaterial(_smart_ptr pMtlSrc, _smart_ptr pMtlDest, EMaterialCopyFlags flags); - - virtual void RenameMaterial(_smart_ptr pMtl, const char* sNewName); - virtual void RefreshMaterialRuntime(); - // ------------------------------------------------------------------------------------ - - void InitDefaults(); - - void PreloadLevelMaterials(); - void DoLoadSurfaceTypesInInit(bool doLoadSurfaceTypesInInit); - - void UpdateShaderItems(); - void RefreshShaderResourceConstants(); - - // Load all known game decal materials. - void PreloadDecalMaterials(); - - void SetSketchMode(int mode); - int GetSketchMode() { return e_sketch_mode; } - void SetTexelDensityDebug(int mode); - int GetTexelDensityDebug() { return e_texeldensity; } - - ////////////////////////////////////////////////////////////////////////// - ISurfaceType* GetSurfaceTypeFast(int nSurfaceTypeId, const char* sWhy = NULL) { return m_pSurfaceTypeManager->GetSurfaceTypeFast(nSurfaceTypeId, sWhy); } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - -private: // ----------------------------------------------------------------------------- - friend class CMatInfo; - bool Unregister(_smart_ptr pMat, bool deleteEditorMaterial = true); - - _smart_ptr CreateMaterialPlaceholder(const char* materialName, int nMtlFlags, const char* textureName, _smart_ptr existingMtl = nullptr); - - bool LoadMaterialShader(_smart_ptr pMtl, _smart_ptr pParentMtl, const char* sShader, uint64 nShaderGenMask, SInputShaderResources& sr, XmlNodeRef& publicsNode); - bool LoadMaterialLayerSlot(uint32 nSlot, _smart_ptr pMtl, const char* szShaderName, SInputShaderResources& pBaseResources, XmlNodeRef& pPublicsNode, uint8 nLayerFlags); - - void ParsePublicParams(SInputShaderResources& sr, XmlNodeRef paramsNode); - AZStd::string UnifyName(const char* sMtlName) const; - // Can be called after material creation and initialization, to inform editor that new material in engine exist. - // Only used internally. - void NotifyCreateMaterial(_smart_ptr pMtl); - // Make a valid material from the XML node. - _smart_ptr MakeMaterialFromXml(const AZStd::string& sMtlName, XmlNodeRef node, bool bForcePureChild, uint16 sortPrio = 0, _smart_ptr pExistingMtl = 0, unsigned long nLoadingFlags = 0, _smart_ptr pParentMtl = 0); - - template - UniqueManualEvent CheckMaterialCache(const AZStd::string& name, T& cachedMaterial); - - _smart_ptr LoadMaterialInternal(const char* sMtlName, bool bMakeIfNotFound, bool bNonremovable, unsigned long nLoadingFlags); - - // override from LegacyAssetEventBus::Handler - // Notifies listeners that a file changed - void OnFileChanged(AZStd::string assetPath) override; - void OnFileRemoved(AZStd::string assetPath) override; -private: - typedef AZStd::unordered_map > MtlNameMap; - - MtlNameMap m_mtlNameMap; // - - IMaterialManagerListener* m_pListener; // - _smart_ptr m_pDefaultMtl; // - _smart_ptr m_pDefaultLayersMtl; // - _smart_ptr m_pDefaultTerrainLayersMtl; // - _smart_ptr m_pNoDrawMtl; // - _smart_ptr m_pDefaultHelperMtl; - - std::vector<_smart_ptr > m_nonRemovables; // - - CSurfaceTypeManager* m_pSurfaceTypeManager; // - - ////////////////////////////////////////////////////////////////////////// - // Cached XML parser. - _smart_ptr m_pXmlParser; - - bool m_bInitialized; - bool m_bLoadSurfaceTypesInInit; - - mutable AZStd::mutex m_nonRemovablesMutex; - - mutable AZStd::recursive_mutex m_materialMapMutex; - AZStd::unordered_map> m_pendingMaterialLoads; - -public: - // Global namespace "instance", not a class "instance", no member-variables, only const functions; - // Used to encapsulate the material-definition/io into Cry3DEngine (and make it plugable that way). - static MaterialHelpers s_materialHelpers; - - static int e_sketch_mode; - static int e_lowspec_mode; - static int e_pre_sketch_spec; - static int e_texeldensity; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_MATMAN_H - diff --git a/Code/CryEngine/Cry3DEngine/Material.cpp b/Code/CryEngine/Cry3DEngine/Material.cpp deleted file mode 100644 index b0853db518..0000000000 --- a/Code/CryEngine/Cry3DEngine/Material.cpp +++ /dev/null @@ -1,1455 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "MatMan.h" -#include -#include "VisAreas.h" - -DEFINE_INTRUSIVE_LINKED_LIST(CMatInfo) - -////////////////////////////////////////////////////////////////////////// -void CMaterialLayer::SetShaderItem(const _smart_ptr pParentMtl, const SShaderItem& pShaderItem) -{ - assert(pParentMtl && "CMaterialLayer::SetShaderItem invalid material"); - - if (pShaderItem.m_pShader) - { - pShaderItem.m_pShader->AddRef(); - } - - if (pShaderItem.m_pShaderResources) - { - pShaderItem.m_pShaderResources->AddRef(); - CMatInfo* pParentMatInfo = (CMatInfo*)(pParentMtl.get()); - pShaderItem.m_pShaderResources->SetMaterialName(pParentMatInfo->m_sUniqueMaterialName); - } - - gEnv->pRenderer->ClearShaderItem(&m_pShaderItem); - SAFE_RELEASE(m_pShaderItem.m_pShader); - SAFE_RELEASE(m_pShaderItem.m_pShaderResources); - - m_pShaderItem = pShaderItem; - gEnv->pRenderer->UpdateShaderItem(&m_pShaderItem, nullptr); -} -////////////////////////////////////////////////////////////////////////// -void CMaterialLayer::GetMemoryUsage(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "MaterialLayer"); - pSizer->AddObject(this, sizeof(*this)); -} - -////////////////////////////////////////////////////////////////////////// -size_t CMaterialLayer::GetResourceMemoryUsage(ICrySizer* pSizer) -{ - size_t nResourceMemory(0); - // Pushing some context to use the Macro. - { - SIZER_COMPONENT_NAME(pSizer, "Textures"); - - IRenderShaderResources* piResources(m_pShaderItem.m_pShaderResources); - if (piResources) - { - ////////////////////////////////////////////////////////////////////////// - // Texture - for (size_t nCount = 0; nCount < EFTT_MAX; ++nCount) - { - SEfResTexture* piTextureResource(piResources->GetTextureResource(nCount)); - if (piTextureResource) - { - ITexture* piTexture = piTextureResource->m_Sampler.m_pITex; - if (piTexture) - { - SIZER_COMPONENT_NAME(pSizer, "MemoryTexture"); - size_t nCurrentResourceMemoryUsage = piTexture->GetDataSize(); - nResourceMemory += nCurrentResourceMemoryUsage; - pSizer->AddObject(piTexture, nCurrentResourceMemoryUsage); - - IResourceCollector* pColl = pSizer->GetResourceCollector(); - if (pColl) - { - pColl->AddResource(piTexture->GetName(), nCurrentResourceMemoryUsage); - } - } - } - } - ////////////////////////////////////////////////////////////////////////// - } - } - return nResourceMemory; -} - -////////////////////////////////////////////////////////////////////////// -CMatInfo::CMatInfo() -{ - m_nRefCount = 0; - m_Flags = 0; - - m_nSurfaceTypeId = 0; - - m_pMaterialLayers = 0; - - m_ucDefautMappingAxis = 0; - m_fDefautMappingScale = 1.f; - -#ifdef SUPPORT_MATERIAL_SKETCH - m_pPreSketchShader = 0; - m_nPreSketchTechnique = 0; -#endif - -#ifdef SUPPORT_MATERIAL_EDITING - m_pUserData = NULL; -#endif - - m_pActiveLayer = NULL; - - m_shaderName = "Non-Initialized Shader name"; - - ZeroStruct(m_streamZoneInfo); - - // Used to know when a .dccmtl file has been changed, - // requiring the source material to be updated - m_dccMaterialHash = 0; - - m_isDirty = false; -} - -////////////////////////////////////////////////////////////////////////// -CMatInfo::~CMatInfo() -{ - ShutDown(); -} - -void CMatInfo::AddRef() -{ - CryInterlockedIncrement(&m_nRefCount); -} -////////////////////////////////////////////////////////////////////////// -void CMatInfo::Release() -{ - if (CryInterlockedDecrement(&m_nRefCount) <= 0) - { - delete this; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::ShutDown() -{ - SAFE_DELETE(m_pMaterialLayers); - - ReleaseCurrentShaderItem(); - m_subMtls.clear(); -} - -////////////////////////////////////////////////////////////////////////// -IMaterialHelpers& CMatInfo::GetMaterialHelpers() -{ - return GetMatMan()->s_materialHelpers; -} - -IMaterialManager* CMatInfo::GetMaterialManager() -{ - return GetMatMan(); -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetName(const char* sName) -{ - m_sMaterialName = sName; - m_sUniqueMaterialName = m_sMaterialName; - if (m_shaderItem.m_pShaderResources) - { - m_shaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName); // Only for correct warning message purposes. - } - if (m_Flags & MTL_FLAG_MULTI_SUBMTL) - { - for (int i = 0, num = m_subMtls.size(); i < num; i++) - { - if (m_subMtls[i] && (m_subMtls[i]->m_Flags & MTL_FLAG_PURE_CHILD)) - { - m_subMtls[i]->m_sUniqueMaterialName = m_sMaterialName; - if (m_subMtls[i]->m_shaderItem.m_pShaderResources) - { - m_subMtls[i]->m_shaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName); - } - } - - if (m_subMtls[i] && strstr(m_subMtls[i]->m_sUniqueMaterialName, MTL_SPECIAL_NAME_RAYCAST_PROXY) != 0) - { - m_subMtls[i]->m_Flags |= MTL_FLAG_RAYCAST_PROXY; - m_subMtls[i]->m_Flags |= MTL_FLAG_NODRAW; - } - } - } - - if (strstr(sName, MTL_SPECIAL_NAME_COLLISION_PROXY) != 0 || strstr(sName, MTL_SPECIAL_NAME_COLLISION_PROXY_VEHICLE) != 0) - { - m_Flags |= MTL_FLAG_COLLISION_PROXY; - } - else if (strstr(sName, MTL_SPECIAL_NAME_RAYCAST_PROXY) != 0) - { - m_Flags |= MTL_FLAG_RAYCAST_PROXY; - m_Flags |= MTL_FLAG_NODRAW; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsDefault() -{ - return this == GetMatMan()->GetDefaultMaterial(); -} - -////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsMaterialGroup() const -{ - return (m_Flags & MTL_FLAG_MULTI_SUBMTL) != 0 || m_subMtls.size() > 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsSubMaterial() const -{ - return (m_Flags & MTL_FLAG_PURE_CHILD) != 0; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::UpdateFlags() -{ - m_Flags &= ~(MTL_FLAG_REQUIRE_FORWARD_RENDERING | MTL_FLAG_REQUIRE_NEAREST_CUBEMAP); - - if (m_shaderItem.m_pShader) - { - IRenderShaderResources* pRendShaderResources = m_shaderItem.m_pShaderResources; - - const bool bAlphaBlended = (m_shaderItem.m_pShader->GetFlags() & (EF_NODRAW | EF_DECAL)) || (pRendShaderResources && pRendShaderResources->IsTransparent()); - const bool bIsHair = (m_shaderItem.m_pShader->GetFlags2() & EF2_HAIR) != 0; - const bool bIsGlass = m_shaderItem.m_pShader->GetShaderType() == eST_Glass; - const bool bIsWater = m_shaderItem.m_pShader->GetShaderType() == eST_Water; - const bool bIsEye = strcmp(m_shaderItem.m_pShader->GetName(), "Eye") == 0; - const bool bIsFur = m_shaderItem.m_pShader->GetShaderDrawType() == eSHDT_Fur; - - if (bAlphaBlended && !(m_shaderItem.m_pShader->GetFlags2() & EF2_NODRAW) && !(m_shaderItem.m_pShader->GetFlags() & EF_DECAL)) - { - m_Flags |= MTL_FLAG_REQUIRE_FORWARD_RENDERING; - } - else if (bIsHair || bIsGlass || bIsFur) - { - m_Flags |= MTL_FLAG_REQUIRE_FORWARD_RENDERING; - } - - if ((bAlphaBlended || bIsHair || bIsGlass || bIsWater || bIsEye) && - (pRendShaderResources) && - (pRendShaderResources->GetTextureResource(EFTT_ENV)) && - (pRendShaderResources->GetTextureResource(EFTT_ENV)->m_Sampler.m_eTexType == eTT_NearestCube)) - { - m_Flags |= MTL_FLAG_REQUIRE_NEAREST_CUBEMAP; - } - - // Make sure to refresh sectors - static int nLastUpdateFrameId = 0; - if (gEnv->IsEditing() && GetVisAreaManager() && nLastUpdateFrameId != GetRenderer()->GetFrameID()) - { - nLastUpdateFrameId = GetRenderer()->GetFrameID(); - } - } -} - -void CMatInfo::ReleaseCurrentShaderItem() -{ - // Clear the renderer's shader resources to nullptr before releasing the shader item so there are no dangling pointers - gEnv->pRenderer->ClearShaderItem(&m_shaderItem); - SAFE_RELEASE(m_shaderItem.m_pShader); - SAFE_RELEASE(m_shaderItem.m_pShaderResources); -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetShaderItem(const SShaderItem& _ShaderItem) -{ - if (_ShaderItem.m_pShader) - { - _ShaderItem.m_pShader->AddRef(); - } - if (_ShaderItem.m_pShaderResources) - { - _ShaderItem.m_pShaderResources->AddRef(); - _ShaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName); - } - - ReleaseCurrentShaderItem(); - - m_shaderItem = _ShaderItem; - gEnv->pRenderer->UpdateShaderItem(&m_shaderItem, this); - - UpdateFlags(); - - int sketchMode = m_pMatMan->GetSketchMode(); - if (sketchMode) - { - SetSketchMode(sketchMode); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::AssignShaderItem(const SShaderItem& _ShaderItem) -{ - //if (_ShaderItem.m_pShader) - // _ShaderItem.m_pShader->AddRef(); - if (_ShaderItem.m_pShaderResources) - { - _ShaderItem.m_pShaderResources->SetMaterialName(m_sUniqueMaterialName); - } - - ReleaseCurrentShaderItem(); - - m_shaderItem = _ShaderItem; - gEnv->pRenderer->UpdateShaderItem(&m_shaderItem, this); - - UpdateFlags(); -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetSurfaceType(const char* sSurfaceTypeName) -{ - m_nSurfaceTypeId = 0; - - ISurfaceType* pSurfaceType = GetMatMan()->GetSurfaceTypeByName(sSurfaceTypeName, m_sMaterialName); - if (pSurfaceType) - { - m_nSurfaceTypeId = pSurfaceType->GetId(); - } -} - -ISurfaceType* CMatInfo::GetSurfaceType() -{ - return GetMatMan()->GetSurfaceType(m_nSurfaceTypeId, m_sMaterialName); -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetSubMtlCount(int numSubMtl) -{ - AUTO_LOCK(GetSubMaterialResizeLock()); - if (numSubMtl > 0) - { - m_Flags |= MTL_FLAG_MULTI_SUBMTL; - } - else if(numSubMtl == 0) - { - m_Flags &= ~MTL_FLAG_MULTI_SUBMTL; - } - else - { - AZ_Assert(false, "SetSubMtlCount called with negative value for material %s.", m_sMaterialName.c_str()); - return; - } - - m_subMtls.resize(numSubMtl); -} - -////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES], IRenderMesh* pRenderMesh) const -{ - if (pRenderMesh) - { - TRenderChunkArray* pChunks = &pRenderMesh->GetChunks(); - - if (pChunks != NULL) - { - for (uint32 i = 0, size = pChunks->size(); i < size; i++) - { - if (!AreChunkTexturesStreamedIn(&(*pChunks)[i], nMinPrecacheRoundIds)) - { - return false; - } - } - } - - pChunks = &pRenderMesh->GetChunksSkinned(); - for (uint32 i = 0, size = pChunks->size(); i < size; i++) - { - if (!AreChunkTexturesStreamedIn(&(*pChunks)[i], nMinPrecacheRoundIds)) - { - return false; - } - } - } - else - { - if (!AreChunkTexturesStreamedIn(NULL, nMinPrecacheRoundIds)) - { - return false; - } - } - - return true; -} - -bool CMatInfo::AreChunkTexturesStreamedIn(CRenderChunk* pRenderChunk, const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const -{ - const CMatInfo* pMaterial = this; - - if (pRenderChunk && pRenderChunk->pRE && pRenderChunk->nNumIndices && pRenderChunk->nNumVerts) - { // chunk is defined and have valid geometry - if (pRenderChunk->m_nMatID < (uint16)m_subMtls.size()) - { - pMaterial = (CMatInfo*)m_subMtls[pRenderChunk->m_nMatID]; - } - - if (pMaterial != NULL) - { - return pMaterial->AreTexturesStreamedIn(nMinPrecacheRoundIds); - } - } - else if (!pRenderChunk) - { - if (!AreTexturesStreamedIn(nMinPrecacheRoundIds)) - { - return false; - } - - for (int nSubMtl = 0; nSubMtl < (int)m_subMtls.size(); ++nSubMtl) - { - pMaterial = m_subMtls[nSubMtl]; - - if (pMaterial != NULL) - { - if (!pMaterial->AreTexturesStreamedIn(nMinPrecacheRoundIds)) - { - return false; - } - } - } - } - - return true; -} - -bool CMatInfo::AreTexturesStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const -{ - // Check this material - if (IRenderShaderResources* pShaderResources = GetShaderItem().m_pShaderResources) - { - for (auto iter = pShaderResources->GetTexturesResourceMap()->begin(); iter != pShaderResources->GetTexturesResourceMap()->end(); ++iter) - { - SEfResTexture* pTextureResource = &(iter->second); - if (ITexture* pTexture = pTextureResource->m_Sampler.m_pITex) - { - if (!pTexture->IsStreamedIn(nMinPrecacheRoundIds)) - { - return false; - } - } - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetSubMtl(int nSlot, _smart_ptr pMtl) -{ - if (nSlot < 0 || nSlot >= static_cast(m_subMtls.size())) - { - AZ_Error("Rendering", false, "SetSubMtl inserting material '%s' outside the range of m_subMtls in '%s'. Call SetSubMtlCount first to increase the size of m_subMtls.", pMtl->GetName(), m_sMaterialName.c_str()); - return; - } - if (pMtl && pMtl->IsMaterialGroup()) - { - AZ_Error("Rendering", false, "SetSubMtl attempting to insert a material group '%s' as a sub-material of '%s'. Only individual materials can be sub-materials.", pMtl->GetName(), m_sMaterialName.c_str()); - return; - } - m_subMtls[nSlot] = (CMatInfo*)pMtl.get(); -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetLayerCount(uint32 nCount) -{ - if (!m_pMaterialLayers) - { - m_pMaterialLayers = new MatLayers; - } - - m_pMaterialLayers->resize(nCount); -} - -////////////////////////////////////////////////////////////////////////// -uint32 CMatInfo::GetLayerCount() const -{ - if (m_pMaterialLayers) - { - return (uint32) m_pMaterialLayers->size(); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetLayer(uint32 nSlot, IMaterialLayer* pLayer) -{ - assert(m_pMaterialLayers); - assert(nSlot < (uint32) m_pMaterialLayers->size()); - - if (m_pMaterialLayers && pLayer && nSlot < (uint32) m_pMaterialLayers->size()) - { - (*m_pMaterialLayers)[nSlot] = static_cast< CMaterialLayer*>(pLayer); - } -} - -////////////////////////////////////////////////////////////////////////// - -const IMaterialLayer* CMatInfo::GetLayer(uint8 nLayersMask, [[maybe_unused]] uint8 nLayersUsageMask) const -{ - if (m_pMaterialLayers && nLayersMask) - { - int nSlotCount = m_pMaterialLayers->size(); - for (int nSlot = 0; nSlot < nSlotCount; ++nSlot) - { - CMaterialLayer* pLayer = static_cast< CMaterialLayer*>((*m_pMaterialLayers)[nSlot]); - - if (nLayersMask & (1 << nSlot)) - { - if (pLayer) - { - m_pActiveLayer = pLayer; - return m_pActiveLayer; - } - - m_pActiveLayer = 0; - - return 0; - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -const IMaterialLayer* CMatInfo::GetLayer(uint32 nSlot) const -{ - if (m_pMaterialLayers && nSlot < (uint32) m_pMaterialLayers->size()) - { - return static_cast< CMaterialLayer*>((*m_pMaterialLayers)[nSlot]); - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -IMaterialLayer* CMatInfo::CreateLayer() -{ - return new CMaterialLayer; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetUserData([[maybe_unused]] void* pUserData) -{ -#ifdef SUPPORT_MATERIAL_EDITING - m_pUserData = pUserData; -#endif -} - -////////////////////////////////////////////////////////////////////////// -void* CMatInfo::GetUserData() const -{ -#ifdef SUPPORT_MATERIAL_EDITING - return m_pUserData; -#else - CryFatalError("CMatInfo::GetUserData not supported on this platform"); - return NULL; -#endif -} - -////////////////////////////////////////////////////////////////////////// -int CMatInfo::FillSurfaceTypeIds(int pSurfaceIdsTable[]) -{ - if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - pSurfaceIdsTable[0] = m_nSurfaceTypeId; - return 1; // Not Multi material. - } - for (int i = 0; i < (int)m_subMtls.size(); i++) - { - if (m_subMtls[i] != 0) - { - pSurfaceIdsTable[i] = m_subMtls[i]->m_nSurfaceTypeId; - } - else - { - pSurfaceIdsTable[i] = 0; - } - } - return m_subMtls.size(); -} - - -void CMatInfo::Copy(_smart_ptr pMtlDest, EMaterialCopyFlags flags) -{ - CMatInfo* pMatInfo = static_cast(pMtlDest.get()); - if (flags & MTL_COPY_NAME) - { - pMatInfo->m_sMaterialName = m_sMaterialName; - pMatInfo->m_sUniqueMaterialName = m_sUniqueMaterialName; - } - pMatInfo->m_nSurfaceTypeId = m_nSurfaceTypeId; - pMatInfo->m_Flags = m_Flags; - - if (GetShaderItem().m_pShaderResources) - { - // - SShaderItem& siSrc(GetShaderItem()); - SInputShaderResources isr(siSrc.m_pShaderResources); - // - SShaderItem& siDstTex(pMatInfo->GetShaderItem()); - SInputShaderResources idsTex(siDstTex.m_pShaderResources); - if (!(flags & MTL_COPY_TEXTURES)) - { - isr.m_TexturesResourcesMap = idsTex.m_TexturesResourcesMap; - } - SShaderItem siDst(GetRenderer()->EF_LoadShaderItem(siSrc.m_pShader->GetName(), false, 0, &isr, siSrc.m_pShader->GetGenerationMask())); - pMatInfo->AssignShaderItem(siDst); - siDst.m_pShaderResources->CloneConstants(siSrc.m_pShaderResources); - } -} - - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatInfo::Clone() -{ - _smart_ptr pMatInfo = new CMatInfo; - - pMatInfo->m_sMaterialName = m_sMaterialName; - pMatInfo->m_sUniqueMaterialName = m_sUniqueMaterialName; - pMatInfo->m_nSurfaceTypeId = m_nSurfaceTypeId; - pMatInfo->m_Flags = m_Flags; - - SShaderItem& siSrc(GetShaderItem()); - SInputShaderResources isr(siSrc.m_pShaderResources); - - SShaderItem siDst(GetRenderer()->EF_LoadShaderItem(siSrc.m_pShader->GetName(), false, 0, &isr, siSrc.m_pShader->GetGenerationMask())); - pMatInfo->AssignShaderItem(siDst); - siDst.m_pShaderResources->CloneConstants(siSrc.m_pShaderResources); - - // Necessary to delete all the data allocated in the renderer - GetRenderer()->EF_ReleaseInputShaderResource(&isr); - - return pMatInfo; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "Material"); - pSizer->AddObject(this, sizeof(*this)); - - if (m_pMaterialLayers) - { - int n = m_pMaterialLayers->size(); - for (int i = 0; i < n; i++) - { - CMaterialLayer* pMaterialLayer = (*m_pMaterialLayers)[i]; - if (pMaterialLayer) - { - pMaterialLayer->GetMemoryUsage(pSizer); - } - } - } - - // all sub material - { - pSizer->AddObject(m_subMtls); - } -} -////////////////////////////////////////////////////////////////////////// -size_t CMatInfo::GetResourceMemoryUsage(ICrySizer* pSizer) -{ - size_t nTotalResourceMemoryUsage(0); - - if (m_pMaterialLayers) - { - int n = m_pMaterialLayers->size(); - for (int i = 0; i < n; i++) - { - CMaterialLayer* pMaterialLayer = (*m_pMaterialLayers)[i]; - if (pMaterialLayer) - { - nTotalResourceMemoryUsage += pMaterialLayer->GetResourceMemoryUsage(pSizer); - } - } - } - - if (m_shaderItem.m_pShaderResources) - { - nTotalResourceMemoryUsage += m_shaderItem.m_pShaderResources->GetResourceMemoryUsage(pSizer); - } - - // all sub material - { - int iCnt = GetSubMtlCount(); - for (int i = 0; i < iCnt; ++i) - { - _smart_ptr piMaterial(GetSubMtl(i)); - if (piMaterial) - { - nTotalResourceMemoryUsage += piMaterial->GetResourceMemoryUsage(pSizer); - } - } - } - return nTotalResourceMemoryUsage; -} - -////////////////////////////////////////////////////////////////////////// -bool CMatInfo::SetGetMaterialParamFloat(const char* sParamName, float& v, bool bGet, bool allowShaderParam /*= false*/, int materialIndex /*= 0*/) -{ - //For a material group, we need to set the param to a sub-material specified by materialIndex - if (IsMaterialGroup()) - { - int subMtlCount = GetSubMtlCount(); - if (materialIndex >= 0 && materialIndex < subMtlCount) - { - IMaterial* subMtl = GetSubMtl(materialIndex); - if (subMtl) - { - return subMtl->SetGetMaterialParamFloat(sParamName, v, bGet, allowShaderParam); - } - else - { - AZ_Error("Rendering", false, "Attempted to access an invalid Sub-Material at index %d.", materialIndex); - return false; - } - } - else - { - AZ_Error("Rendering", false, "Attempted to access an invalid Sub-Material at index %d. %d Materials are available.", materialIndex, subMtlCount); - return false; - } - } - else if (materialIndex > 0) - { - AZ_Warning("Rendering", false, "Setting a parameter on a single Material does not require a Material Index."); - } - - //For a single material, we need to make sure it has all the shader resources we need - IRenderShaderResources* pRendShaderRes = m_shaderItem.m_pShaderResources; - if (!pRendShaderRes) - { - AZ_Warning("Rendering", false, "Attempted to access params on a Material that has no Shader Resources."); - return false; - } - - const bool bEmissive = pRendShaderRes->IsEmissive(); - const bool bTransparent = pRendShaderRes->IsTransparent(); - bool bOk = GetMaterialHelpers().SetGetMaterialParamFloat(*pRendShaderRes, sParamName, v, bGet); - - if (!bOk && allowShaderParam) - { - auto& shaderParams = pRendShaderRes->GetParameters(); - - if (bGet) - { - for (int i = 0; i < shaderParams.size(); ++i) - { - SShaderParam& param = shaderParams[i]; - if (azstricmp(param.m_Name.c_str(), sParamName) == 0) - { - v = 0.0f; - - switch (param.m_Type) - { - case eType_BOOL: - v = param.m_Value.m_Bool; - bOk = true; - break; - case eType_BYTE: - v = param.m_Value.m_Byte; - bOk = true; - break; - case eType_SHORT: - v = param.m_Value.m_Short; - bOk = true; - break; - case eType_INT: - v = (float)param.m_Value.m_Int; - bOk = true; - break; - case eType_HALF: - case eType_FLOAT: - v = param.m_Value.m_Float; - bOk = true; - break; - default: - AZ_Warning(nullptr, false, "Unsupported param type %d in %s", param.m_Type, AZ_FUNCTION_SIGNATURE); - } - - break; - } - } - } - else - { - UParamVal val; - val.m_Float = v; - bOk = SShaderParam::SetParam(sParamName, &shaderParams, val); - } - } - - if (bOk && m_shaderItem.m_pShader && !bGet) - { - // since "glow" is a post effect it needs to be updated here - // If unit opacity changed, the transparency preprocess flag must be updated. (This causes SShaderItem::Update() -> SShaderItem::PostLoad(), - // updating the transparency preprocess flag (SShaderItem::m_nPreprocessFlags, FB_TRANSPARENT) based on CShaderResources::IsTransparent()) - if (bEmissive != pRendShaderRes->IsEmissive() || - bTransparent != pRendShaderRes->IsTransparent()) - { - GetRenderer()->ForceUpdateShaderItem(&m_shaderItem, this); - } - - pRendShaderRes->UpdateConstants(m_shaderItem.m_pShader); - } - - m_isDirty |= (bOk && !bGet); - - return bOk; -} - -bool CMatInfo::SetGetMaterialParamVec3(const char* sParamName, Vec3& v, bool bGet, bool allowShaderParam /*= false*/, int materialIndex /*= 0*/) -{ - static const float defaultAlpha = 1.0f; - - Vec4 vec4(v, defaultAlpha); - const bool bOk = SetGetMaterialParamVec4(sParamName, vec4, bGet, allowShaderParam, materialIndex); - - if(bOk && bGet) - { - v = Vec3(vec4); - } - - m_isDirty |= (bOk && !bGet); - - return bOk; -} - -bool CMatInfo::SetGetMaterialParamVec4(const char* sParamName, Vec4& v, bool bGet, bool allowShaderParam /*= false*/, int materialIndex /*= 0*/) -{ - //For a material group, we need to set the param to a sub-material specified by materialIndex - if (IsMaterialGroup()) - { - int subMtlCount = GetSubMtlCount(); - if (materialIndex >= 0 && materialIndex < subMtlCount) - { - IMaterial* subMtl = GetSubMtl(materialIndex); - if (subMtl) - { - return subMtl->SetGetMaterialParamVec4(sParamName, v, bGet, allowShaderParam); - } - else - { - AZ_Error("Rendering", false, "Attempted to access an invalid Sub-Material at index %d.", materialIndex); - return false; - } - } - else - { - AZ_Error("Rendering", false, "Attempted to access an invalid Sub-Material at index %d. %d Materials are available.", materialIndex, subMtlCount); - return false; - } - } - else if (materialIndex > 0) - { - AZ_Warning("Rendering", false, "Setting a parameter on a single Material does not require a Material Index."); - } - - //For a single material, we need to make sure it has all the shader resources we need - IRenderShaderResources* pRendShaderRes = m_shaderItem.m_pShaderResources; - if (!pRendShaderRes) - { - AZ_Warning("Rendering", false, "Attempted to access params on a Material that has no Shader Resources."); - return false; - } - - static const float defaultAlpha = 1.0f; - - // Note we are only passing XYZ to the IMaterialHelpers here because it only deals with with "diffuse", "specular", and "emissive_color", which don't use the W/alpha channel. - Vec3 vec3(v); - bool bOk = GetMaterialHelpers().SetGetMaterialParamVec3(*pRendShaderRes, sParamName, vec3, bGet); - if (bOk && bGet) - { - v = Vec4(vec3, defaultAlpha); - } - - if (!bOk && allowShaderParam) - { - auto& shaderParams = pRendShaderRes->GetParameters(); - - if (bGet) - { - for (int i = 0; i < shaderParams.size(); ++i) - { - SShaderParam& param = shaderParams[i]; - if (azstricmp(param.m_Name.c_str(), sParamName) == 0) - { - if (param.m_Type == eType_VECTOR) - { - v = Vec4(param.m_Value.m_Vector[0], param.m_Value.m_Vector[1], param.m_Value.m_Vector[2], defaultAlpha); - bOk = true; - } - else if (param.m_Type == eType_FCOLOR) - { - v = Vec4(param.m_Value.m_Color[0], param.m_Value.m_Color[1], param.m_Value.m_Color[2], param.m_Value.m_Color[3]); - bOk = true; - } - else - { - AZ_Warning(nullptr, false, "Unsupported param type %d in %s", param.m_Type, AZ_FUNCTION_SIGNATURE); - } - } - } - } - else - { - UParamVal val; - val.m_Color[0] = v.x; - val.m_Color[1] = v.y; - val.m_Color[2] = v.z; - val.m_Color[3] = v.w; - - bOk = SShaderParam::SetParam(sParamName, &shaderParams, val); - } - } - - if (bOk && m_shaderItem.m_pShader && !bGet) - { - pRendShaderRes->UpdateConstants(m_shaderItem.m_pShader); - } - - m_isDirty |= (bOk && !bGet); - - return bOk; -} - -void CMatInfo::SetDirty(bool dirty /*= true*/) -{ - m_isDirty = dirty; -} - -bool CMatInfo::IsDirty() const -{ - bool isChildrenDirty = false; - if (IsMaterialGroup()) - { - for (int i = 0 ; i < m_subMtls.size(); i ++) - { - if (m_subMtls[i]) - { - if (m_subMtls[i]->IsMaterialGroup()) - { - AZ_Assert(!m_subMtls[i]->IsMaterialGroup(), "Sub-material '%s' in material '%s' is a material group. Material groups cannot be sub-materials. This could lead to a cycle and infinite recursion in CMatInfo::IsDirty().", m_subMtls[i]->GetName(), m_sMaterialName.c_str()); - // Exit early to prevent a possible infinite recursion. - // Return true to conservatively indicate that this material should be re-loaded - return true; - } - isChildrenDirty |= m_subMtls[i]->IsDirty(); - } - } - } - return m_isDirty | isChildrenDirty; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetSketchMode([[maybe_unused]] int mode) -{ -#ifdef SUPPORT_MATERIAL_SKETCH - if (mode == 0) - { - if (m_pPreSketchShader) - { - m_shaderItem.m_pShader = m_pPreSketchShader; - m_shaderItem.m_nTechnique = m_nPreSketchTechnique; - m_pPreSketchShader = 0; - m_nPreSketchTechnique = 0; - } - } - else - { - if (m_shaderItem.m_pShader && m_shaderItem.m_pShader != m_pPreSketchShader) - { - EShaderType shaderType = m_shaderItem.m_pShader->GetShaderType(); - - // nGenerationMask = (uint32)m_shaderItem.m_pShader->GetGenerationMask(); - - // Do not replace this shader types. - switch (shaderType) - { - case eST_Shadow: - case eST_Water: - case eST_FX: - case eST_PostProcess: - case eST_HDR: - case eST_Sky: - // For this shaders do not replace them. - return; - } - } - - if (!m_pPreSketchShader) - { - m_pPreSketchShader = m_shaderItem.m_pShader; - m_nPreSketchTechnique = m_shaderItem.m_nTechnique; - } - - //m_shaderItem.m_pShader = ((CMatMan*)GetMatMan())->GetDefaultHelperMaterial()->GetShaderItem().m_pShader; - if (mode == 1) - { - m_shaderItem.m_pShader = gEnv->pRenderer->EF_LoadShader("Sketch"); - m_shaderItem.m_nTechnique = 0; - } - else if (mode == 2) - { - m_shaderItem.m_pShader = gEnv->pRenderer->EF_LoadShader("Sketch.Fast"); - m_shaderItem.m_nTechnique = 0; - } - else if (mode == 4) - { - SShaderItem tmp = gEnv->pRenderer->EF_LoadShaderItem("Sketch.TexelsPerMeter", false); - m_shaderItem.m_pShader = tmp.m_pShader; - m_shaderItem.m_nTechnique = tmp.m_nTechnique; - } - - if (m_shaderItem.m_pShader) - { - m_shaderItem.m_pShader->AddRef(); - } - } - for (int i = 0; i < (int)m_subMtls.size(); i++) - { - if (m_subMtls[i]) - { - m_subMtls[i]->SetSketchMode(mode); - } - } -#endif -} - -void CMatInfo::SetTexelDensityDebug([[maybe_unused]] int mode) -{ -#ifdef SUPPORT_MATERIAL_SKETCH - if (m_shaderItem.m_pShader) - { - EShaderType shaderType = m_pPreSketchShader ? m_pPreSketchShader->GetShaderType() : m_shaderItem.m_pShader->GetShaderType(); - - switch (shaderType) - { - case eST_Shadow: - case eST_Water: - case eST_FX: - case eST_PostProcess: - case eST_HDR: - case eST_Sky: - // For this shaders do not replace them. - mode = 0; - break; - default: - if (mode == 1 || mode == 2) - { - break; - } - mode = 0; - break; - } - - if (mode == 0) - { - if (m_pPreSketchShader) - { - m_shaderItem.m_pShader = m_pPreSketchShader; - m_shaderItem.m_nTechnique = m_nPreSketchTechnique; - m_pPreSketchShader = 0; - m_nPreSketchTechnique = 0; - } - } - else - { - if (!m_pPreSketchShader) - { - m_pPreSketchShader = m_shaderItem.m_pShader; - m_nPreSketchTechnique = m_shaderItem.m_nTechnique; - } - - SShaderItem tmp; - if (mode == 3 || mode == 4) - { - tmp = gEnv->pRenderer->EF_LoadShaderItem("SketchTerrain.TexelDensityTerrainLayer", false); - } - else - { - tmp = gEnv->pRenderer->EF_LoadShaderItem("Sketch.TexelDensity", false); - } - m_shaderItem.m_pShader = tmp.m_pShader; - m_shaderItem.m_nTechnique = tmp.m_nTechnique; - } - } - - for (int i = 0; i < (int)m_subMtls.size(); i++) - { - if (m_subMtls[i]) - { - m_subMtls[i]->SetTexelDensityDebug(mode); - } - } -#endif -} - -void CMatInfo::PrecacheMaterial(const float _fEntDistance, IRenderMesh* pRenderMesh, bool bFullUpdate, bool bDrawNear) -{ - // FUNCTION_PROFILER_3DENGINE; - LOADING_TIME_PROFILE_SECTION; - - int nFlags = 0; - float fEntDistance; - if (bDrawNear) - { - fEntDistance = _fEntDistance; - nFlags |= FPR_HIGHPRIORITY; - } - else - { - fEntDistance = max(GetFloatCVar(e_StreamPredictionMinReportDistance), _fEntDistance); - } - - float fMipFactor = fEntDistance * fEntDistance; - - // updating texture streaming distances - if (pRenderMesh) - { - TRenderChunkArray* pChunks = &pRenderMesh->GetChunks(); - - if (pChunks != NULL) - { - for (uint32 i = 0, size = pChunks->size(); i < size; i++) - { - PrecacheChunkTextures(fMipFactor, nFlags, &(*pChunks)[i], bFullUpdate); - } - } - - pChunks = &pRenderMesh->GetChunksSkinned(); - for (uint32 i = 0, size = pChunks->size(); i < size; i++) - { - PrecacheChunkTextures(fMipFactor, nFlags, &(*pChunks)[i], bFullUpdate); - } - } - else - { - PrecacheChunkTextures(fMipFactor, nFlags, NULL, bFullUpdate); - } -} - -void CMatInfo::DisableTextureStreaming() -{ - const int numSubMaterials = max(GetSubMtlCount(), 1); - for (int subMaterialId = 0; subMaterialId < numSubMaterials; ++subMaterialId) - { - _smart_ptr subMaterial = GetSafeSubMtl(subMaterialId); - if (subMaterial) - { - const SShaderItem& shaderItem = subMaterial->GetShaderItem(); - IRenderShaderResources* pSHRes = shaderItem.m_pShaderResources; - - if (pSHRes) - { - // Iterate through each texture in the material - for ( auto& iter : *(pSHRes->GetTexturesResourceMap()) ) - { - SEfResTexture* pTextureRes = &(iter.second); - uint16 textureSlot = iter.first; - uint32 textureFlags = FT_DONT_STREAM; - - if (textureSlot == EFTT_SMOOTHNESS || textureSlot == EFTT_SECOND_SMOOTHNESS) - { - textureFlags |= FT_ALPHA; - } - - // Calling load texture here will not actually re-create/re-load an existing texture. It will simply toggle streaming off - ITexture* texture = gEnv->pRenderer->EF_LoadTexture(pTextureRes->m_Name.c_str(), textureFlags); - // Call release to decrement the ref count, otherwise the texture will leak when switching between maps - if (texture) - { - texture->Release(); - } - } - } - } - } -} - -void CMatInfo::RequestTexturesLoading(const float fMipFactor) -{ - PrecacheTextures(fMipFactor, FPR_STARTLOADING, false); -} - -void CMatInfo::PrecacheTextures(const float fMipFactor, const int nFlags, bool bFullUpdate) -{ - SStreamingPredictionZone& rZone = m_streamZoneInfo[bFullUpdate ? 1 : 0]; - int bHighPriority = (nFlags & FPR_HIGHPRIORITY) != 0; - - rZone.fMinMipFactor = min(rZone.fMinMipFactor, fMipFactor); - rZone.bHighPriority |= bHighPriority; - - int nRoundId = bFullUpdate ? GetObjManager()->GetUpdateStreamingPrioriryRoundIdFast() : GetObjManager()->GetUpdateStreamingPrioriryRoundId(); - - // TODO: fix fast update - if (rZone.nRoundId != nRoundId) - { - int nCurrentFlags = Get3DEngine()->IsShadersSyncLoad() ? FPR_SYNCRONOUS : 0; - nCurrentFlags |= bFullUpdate ? FPR_SINGLE_FRAME_PRIORITY_UPDATE : 0; - - SShaderItem& rSI = m_shaderItem; - if (rSI.m_pShader && rSI.m_pShaderResources && !(rSI.m_pShader->GetFlags() & EF_NODRAW)) - { - if (rZone.nRoundId == (nRoundId - 1)) - { - nCurrentFlags |= rZone.bHighPriority ? FPR_HIGHPRIORITY : 0; - GetRenderer()->EF_PrecacheResource(&rSI, rZone.fMinMipFactor, 0, nCurrentFlags, nRoundId, 1); // accumulated value is valid - } - else - { - nCurrentFlags |= (nFlags & FPR_HIGHPRIORITY); - GetRenderer()->EF_PrecacheResource(&rSI, fMipFactor, 0, nCurrentFlags, nRoundId, 1); // accumulated value is not valid, pass current value - } - } - - rZone.nRoundId = nRoundId; - rZone.fMinMipFactor = fMipFactor; - rZone.bHighPriority = bHighPriority; - } -} - -void CMatInfo::PrecacheChunkTextures(const float fMipFactorDef, const int nFlags, CRenderChunk* pRenderChunk, bool bFullUpdate) -{ - // FUNCTION_PROFILER_3DENGINE; - - CMatInfo* pMaterial = this; - - if (pRenderChunk && pRenderChunk->pRE && pRenderChunk->nNumIndices && pRenderChunk->nNumVerts) - { // chunk is defined and have valid geometry - if (pRenderChunk->m_nMatID < (uint16)m_subMtls.size()) - { - pMaterial = (CMatInfo*)m_subMtls[pRenderChunk->m_nMatID]; - } - - if (pMaterial != NULL) - { - float fMipFactor = GetCVars()->e_StreamPredictionTexelDensity ? (fMipFactorDef * pRenderChunk->m_texelAreaDensity) : fMipFactorDef; - pMaterial->PrecacheTextures(fMipFactor, nFlags, bFullUpdate); - } - } - else if (!pRenderChunk) - { // chunk is not set - load all sub-materials - float fMipFactor = fMipFactorDef; - - PrecacheTextures(fMipFactor, nFlags, bFullUpdate); - - for (int nSubMtl = 0; nSubMtl < (int)m_subMtls.size(); ++nSubMtl) - { - pMaterial = m_subMtls[nSubMtl]; - - if (pMaterial != NULL) - { - pMaterial->PrecacheTextures(fMipFactor, nFlags, bFullUpdate); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -int CMatInfo::GetTextureMemoryUsage(ICrySizer* pSizer, int nSubMtlSlot) -{ - int textureSize = 0; - std::set used; - - int nSlotStart = 0; - int nSlotEnd = (int)m_subMtls.size(); - - if (nSubMtlSlot >= 0) - { - nSlotStart = nSubMtlSlot; - nSlotEnd = nSubMtlSlot + 1; - } - if (nSlotEnd >= (int)m_subMtls.size()) - { - nSlotEnd = (int)m_subMtls.size(); - } - - if (nSlotEnd == 0) - { - nSlotEnd = 1; - } - - for (int i = nSlotStart; i < nSlotEnd; i++) - { - IRenderShaderResources* pRes = m_shaderItem.m_pShaderResources; - if (i < (int)m_subMtls.size() && m_subMtls[i] != NULL && (m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - SShaderItem shaderItem = m_subMtls[i]->m_shaderItem; - if (!shaderItem.m_pShaderResources) - { - continue; - } - pRes = shaderItem.m_pShaderResources; - } - if (!pRes) - { - continue; - } - - for ( auto& iter : *(pRes->GetTexturesResourceMap()) ) - { - SEfResTexture* pResTexure = &(iter.second); - if (!pResTexure->m_Sampler.m_pITex) - { - continue; - } - - ITexture* pTexture = pResTexure->m_Sampler.m_pITex; - if (!pTexture) - { - continue; - } - - if (used.find(pTexture) != used.end()) // Already used in size calculation. - { - continue; - } - used.insert(pTexture); - - int nTexSize = pTexture->GetDataSize(); - textureSize += nTexSize; - - if (pSizer) - { - pSizer->AddObject(pTexture, nTexSize); - } - } - } - - return textureSize; -} - -void CMatInfo::SetKeepLowResSysCopyForDiffTex() -{ - int nSlotStart = 0; - int nSlotEnd = (int)m_subMtls.size(); - - if (nSlotEnd == 0) - { - nSlotEnd = 1; - } - - for (int i = nSlotStart; i < nSlotEnd; i++) - { - IRenderShaderResources* pRes = m_shaderItem.m_pShaderResources; - - if (i < (int)m_subMtls.size() && m_subMtls[i] != NULL && (m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - SShaderItem shaderItem = m_subMtls[i]->m_shaderItem; - if (!shaderItem.m_pShaderResources) - { - continue; - } - pRes = shaderItem.m_pShaderResources; - } - - if (!pRes) - { - continue; - } - - { - SEfResTexture* pResTexure = pRes->GetTextureResource(EFTT_DIFFUSE); - if (!pResTexure || !pResTexure->m_Sampler.m_pITex) - { - continue; - } - ITexture* pTexture = pResTexure->m_Sampler.m_pITex; - if (!pTexture) - { - continue; - } - - pTexture->SetKeepSystemCopy(true); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::SetMaterialLinkName([[maybe_unused]] const char* name) -{ -#ifdef SUPPORT_MATERIAL_EDITING - if (name) - { - m_sMaterialLinkName = name; - } - else - { - m_sMaterialLinkName.clear(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -const char* CMatInfo::GetMaterialLinkName() const -{ -#ifdef SUPPORT_MATERIAL_EDITING - return m_sMaterialLinkName.c_str(); -#else - CryFatalError("CMatInfo::GetMaterialLinkName not supported on this platform"); - return ""; -#endif -} - -////////////////////////////////////////////////////////////////////////// -CryCriticalSection& CMatInfo::GetSubMaterialResizeLock() -{ - static CryCriticalSection s_sSubMaterialResizeLock; - return s_sSubMaterialResizeLock; -} - -////////////////////////////////////////////////////////////////////////// -void CMatInfo::UpdateShaderItems() -{ - IRenderer* pRenderer = gEnv->pRenderer; - pRenderer->UpdateShaderItem(&m_shaderItem, this); - - for (int i = 0; i < (int)m_subMtls.size(); ++i) - { - CMatInfo* pSubMaterial = m_subMtls[i]; - if (pSubMaterial) - { - pRenderer->UpdateShaderItem(&pSubMaterial->m_shaderItem, this); - } - } -} - -void CMatInfo::RefreshShaderResourceConstants() -{ - IRenderer* pRenderer = gEnv->pRenderer; - pRenderer->RefreshShaderResourceConstants(&m_shaderItem, this); - - for (int i = 0; i < (int)m_subMtls.size(); ++i) - { - CMatInfo* pSubMaterial = m_subMtls[i]; - if (pSubMaterial) - { - pRenderer->RefreshShaderResourceConstants(&pSubMaterial->m_shaderItem, this); - } - } -} - diff --git a/Code/CryEngine/Cry3DEngine/Material.h b/Code/CryEngine/Cry3DEngine/Material.h deleted file mode 100644 index bc0546a4e1..0000000000 --- a/Code/CryEngine/Cry3DEngine/Material.h +++ /dev/null @@ -1,342 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_MATERIAL_H -#define CRYINCLUDE_CRY3DENGINE_MATERIAL_H -#pragma once - -#include - -#if !defined(CONSOLE) -# define SUPPORT_MATERIAL_EDITING -#endif - -#ifndef _RELEASE -#define SUPPORT_MATERIAL_SKETCH -#endif - -class CMaterialLayer - : public IMaterialLayer -{ -public: - CMaterialLayer() - : m_nRefCount(0) - , m_nFlags(0) - { - } - - virtual ~CMaterialLayer() - { - SAFE_RELEASE(m_pShaderItem.m_pShader); - SAFE_RELEASE(m_pShaderItem.m_pShaderResources); - } - - virtual void AddRef() - { - m_nRefCount++; - }; - - virtual void Release() - { - if (--m_nRefCount <= 0) - { - delete this; - } - } - - virtual void Enable(bool bEnable = true) - { - m_nFlags |= (bEnable == false) ? MTL_LAYER_USAGE_NODRAW : 0; - } - - virtual bool IsEnabled() const - { - return (m_nFlags & MTL_LAYER_USAGE_NODRAW) ? false : true; - } - - virtual void FadeOut(bool bFadeOut = true) - { - m_nFlags |= (bFadeOut == false) ? MTL_LAYER_USAGE_FADEOUT : 0; - } - - virtual bool DoesFadeOut() const - { - return (m_nFlags & MTL_LAYER_USAGE_FADEOUT) ? true : false; - } - - virtual void SetShaderItem(const _smart_ptr pParentMtl, const SShaderItem& pShaderItem); - - virtual const SShaderItem& GetShaderItem() const - { - return m_pShaderItem; - } - - virtual SShaderItem& GetShaderItem() - { - return m_pShaderItem; - } - - virtual void SetFlags(uint8 nFlags) - { - m_nFlags = nFlags; - } - - virtual uint8 GetFlags() const - { - return m_nFlags; - } - - void GetMemoryUsage(ICrySizer* pSizer); - size_t GetResourceMemoryUsage(ICrySizer* pSizer); - -private: - uint8 m_nFlags; - int m_nRefCount; - SShaderItem m_pShaderItem; -}; - -////////////////////////////////////////////////////////////////////// -class CMatInfo - : public IMaterial - , public Cry3DEngineBase -{ -public: - CMatInfo(); - ~CMatInfo(); - - void ShutDown(); - - virtual void AddRef(); - virtual void Release(); - - virtual int GetNumRefs() { return m_nRefCount; }; - - ////////////////////////////////////////////////////////////////////////// - // IMaterial implementation - ////////////////////////////////////////////////////////////////////////// - int Size(); - - virtual IMaterialHelpers& GetMaterialHelpers(); - virtual IMaterialManager* GetMaterialManager(); - - virtual void SetName(const char* pName); - virtual const char* GetName() const { return m_sMaterialName; }; - - virtual void SetFlags(int flags) { m_Flags = flags; }; - virtual int GetFlags() const { return m_Flags; }; - virtual void UpdateFlags(); - - bool IsMaterialGroup() const override; - bool IsSubMaterial() const override; - - // Returns true if this is the default material. - virtual bool IsDefault(); - - virtual int GetSurfaceTypeId() { return m_nSurfaceTypeId; }; - - virtual void SetSurfaceType(const char* sSurfaceTypeName); - virtual ISurfaceType* GetSurfaceType(); - - void SetShaderName(const char* pName) override - { - m_shaderName = pName; - }; - const char* GetShaderName() const override - { - return m_shaderName.c_str(); - }; - - // shader item - virtual void ReleaseCurrentShaderItem(); - virtual void SetShaderItem(const SShaderItem& _ShaderItem); - // [Alexey] EF_LoadShaderItem return value with RefCount = 1, so if you'll use SetShaderItem after EF_LoadShaderItem use Assign function - virtual void AssignShaderItem(const SShaderItem& _ShaderItem); - - virtual SShaderItem& GetShaderItem(); - virtual const SShaderItem& GetShaderItem() const; - - /** - * Retrieves the shader item of the sub-material of the given index - * - * If the material has no sub-materials or is not flagged as having any sub-materials - * this will return its own shader item. If no shader item is found for the given - * sub-material the default material's shader item will be returned instead. - * - * @param nSubMtlSlot The index to the requested sub-material - * - * @return A reference to the sub-material's shader item - */ - virtual SShaderItem& GetShaderItem(int nSubMtlSlot); - - /** - * Retrieves the shader item of the sub-material of the given index - * - * If the material has no sub-materials or is not flagged as having any sub-materials - * this will return its own shader item. If no shader item is found for the given - * sub-material the default material's shader item will be returned instead. - * - * @param nSubMtlSlot The index to the requested sub-material - * - * @return A reference to the sub-material's shader item - */ - virtual const SShaderItem& GetShaderItem(int nSubMtlSlot) const; - - virtual bool IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES], IRenderMesh* pRenderMesh) const; - bool AreChunkTexturesStreamedIn(CRenderChunk* pChunk, const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const; - bool AreTexturesStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const; - - ////////////////////////////////////////////////////////////////////////// - // Functions to set param into the material/material group - // If this is a material group, materialIndex specifies the index of the sub-material to be modified - ////////////////////////////////////////////////////////////////////////// - bool SetGetMaterialParamFloat(const char* sParamName, float& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override; - bool SetGetMaterialParamVec3(const char* sParamName, Vec3& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override; - bool SetGetMaterialParamVec4(const char* sParamName, Vec4& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override; - - void SetDirty(bool dirty = true) override; - bool IsDirty() const override; - - ////////////////////////////////////////////////////////////////////////// - // Sub materials. - ////////////////////////////////////////////////////////////////////////// - virtual void SetSubMtlCount(int numSubMtl); - virtual int GetSubMtlCount(){return m_subMtls.size(); } - virtual _smart_ptr GetSubMtl(int nSlot) - { - if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - return 0; // Not Multi material. - } - if (nSlot >= 0 && nSlot < (int)m_subMtls.size()) - { - return m_subMtls[nSlot]; - } - else - { - return 0; - } - } - virtual void SetSubMtl(int nSlot, _smart_ptr pMtl); - virtual void SetUserData(void* pUserData); - virtual void* GetUserData() const; - - virtual _smart_ptr GetSafeSubMtl(int nSlot); - virtual _smart_ptr Clone(); - virtual void Copy(_smart_ptr pMtlDest, EMaterialCopyFlags flags); - - ////////////////////////////////////////////////////////////////////////// - // Layers - ////////////////////////////////////////////////////////////////////////// - virtual void SetLayerCount(uint32 nCount); - virtual uint32 GetLayerCount() const; - virtual void SetLayer(uint32 nSlot, IMaterialLayer* pLayer); - virtual const IMaterialLayer* GetLayer(uint8 nLayersMask, uint8 nLayersUsageMask) const; - virtual const IMaterialLayer* GetLayer(uint32 nSlot) const; - virtual IMaterialLayer* CreateLayer(); - - // Fill int table with surface ids of sub materials. - // Return number of filled items. - int FillSurfaceTypeIds(int pSurfaceIdsTable[]); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - - virtual size_t GetResourceMemoryUsage(ICrySizer* pSizer); - - void UpdateShaderItems() override; - void RefreshShaderResourceConstants(); - - ////////////////////////////////////////////////////////////////////////// - void SetSketchMode(int mode); - void SetTexelDensityDebug(int mode); - - // Check for specific rendering conditions (forward rendering/nearest cubemap requirement) - bool IsForwardRenderingRequired(); - bool IsNearestCubemapRequired(); - - void DisableTextureStreaming() override; - virtual void RequestTexturesLoading(const float fMipFactor); - - virtual void PrecacheMaterial(const float fEntDistance, struct IRenderMesh* pRenderMesh, bool bFullUpdate, bool bDrawNear = false); - void PrecacheTextures(const float fMipFactor, const int nFlags, bool bFullUpdate); - void PrecacheChunkTextures(const float fInstanceDistance, const int nFlags, CRenderChunk* pRenderChunk, bool bFullUpdate); - - virtual int GetTextureMemoryUsage(ICrySizer* pSizer, int nSubMtlSlot = -1); - virtual void SetKeepLowResSysCopyForDiffTex(); - - virtual void SetMaterialLinkName(const char* name); - virtual const char* GetMaterialLinkName() const; - - uint32 GetDccMaterialHash() const override { return m_dccMaterialHash; } - void SetDccMaterialHash(uint32 hash) override { m_dccMaterialHash = hash; } - - virtual CryCriticalSection& GetSubMaterialResizeLock(); - -private: - friend class CMatMan; - friend class CMaterialLayer; - - ////////////////////////////////////////////////////////////////////////// - string m_sMaterialName; - string m_sUniqueMaterialName; - - // Id of surface type assigned to this material. - int m_nSurfaceTypeId; - - //! Number of references to this material. - int m_nRefCount; - //! Material flags. - //! @see EMatInfoFlags - int m_Flags; - - uint32 m_dccMaterialHash; - - SShaderItem m_shaderItem; - - //! shader full name - AZStd::string m_shaderName; - -#ifdef SUPPORT_MATERIAL_SKETCH - _smart_ptr m_pPreSketchShader; - int m_nPreSketchTechnique; -#endif - - //! Array of Sub materials. - typedef DynArray<_smart_ptr > SubMtls; - SubMtls m_subMtls; - -#ifdef SUPPORT_MATERIAL_EDITING - // User data used by Editor. - void* m_pUserData; - - string m_sMaterialLinkName; -#endif - - //! Material layers - typedef std::vector< _smart_ptr< CMaterialLayer > > MatLayers; - MatLayers* m_pMaterialLayers; - - //! Used for material layers - mutable CMaterialLayer* m_pActiveLayer; - - struct SStreamingPredictionZone - { - int nRoundId : 31; - int bHighPriority : 1; - float fMinMipFactor; - } m_streamZoneInfo[2]; - - bool m_isDirty; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_MATERIAL_H - diff --git a/Code/CryEngine/Cry3DEngine/MaterialHelpers.cpp b/Code/CryEngine/Cry3DEngine/MaterialHelpers.cpp deleted file mode 100644 index a9a2c90cb2..0000000000 --- a/Code/CryEngine/Cry3DEngine/MaterialHelpers.cpp +++ /dev/null @@ -1,861 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "IShader.h" -#include "MaterialHelpers.h" - -/* ----------------------------------------------------------------------- - * These functions are used in Cry3DEngine, CrySystem, CryRenderD3D11, - * Editor, ResourceCompilerMaterial and more - */ - -////////////////////////////////////////////////////////////////////////// -namespace -{ - static struct - { - EEfResTextures slot; - const char* ename; - bool adjustable; - const char* name; - const char* description; - const char* suffix; - } - s_TexSlotSemantics[] = - { - // NOTE: must be in order with filled holes to allow direct lookup - { EFTT_DIFFUSE, "EFTT_DIFFUSE", true, "Diffuse" , "Base surface color. Alpha mask is contained in alpha channel." , "_diff" }, - { EFTT_NORMALS, "EFTT_NORMALS", true, "Bumpmap" , "Normal direction for each pixel simulating bumps on the surface. Smoothness map contained in alpha channel." , "_ddn" }, // Ideally "Normal" but need to keep backwards-compatibility - { EFTT_SPECULAR, "EFTT_SPECULAR", true, "Specular" , "Reflective and shininess intensity and color of reflective highlights" , "_spec" }, - { EFTT_ENV, "EFTT_ENV", true, "Environment" , "Deprecated" , "_cm" }, - { EFTT_DETAIL_OVERLAY, "EFTT_DETAIL_OVERLAY", true, "Detail" , "Increases micro and macro surface bump, diffuse and gloss detail. To use, enable the 'Detail Mapping' shader gen param. " , "_detail" }, - { EFTT_SECOND_SMOOTHNESS, "EFTT_SECOND_SMOOTHNESS", false, "SecondSmoothness" , "" , "" }, - { EFTT_HEIGHT, "EFTT_HEIGHT", true, "Heightmap" , "Height for offset bump, POM, silhouette POM, and displacement mapping defined by a Grayscale texture" , "_displ" }, - { EFTT_DECAL_OVERLAY, "EFTT_DECAL_OVERLAY", true, "Decal" , "" , "" }, // called "DecalOverlay" in the shaders - { EFTT_SUBSURFACE, "EFTT_SUBSURFACE", true, "SubSurface" , "" , "_sss" }, // called "Subsurface" in the shaders - { EFTT_CUSTOM, "EFTT_CUSTOM", true, "Custom" , "" , "" }, // called "CustomMap" in the shaders - { EFTT_CUSTOM_SECONDARY, "EFTT_CUSTOM_SECONDARY", true, "[1] Custom" , "" , "" }, - { EFTT_OPACITY, "EFTT_OPACITY", true, "Opacity" , "SubSurfaceScattering map to simulate thin areas for light to penetrate" , "" }, - { EFTT_SMOOTHNESS, "EFTT_SMOOTHNESS", false, "Smoothness" , "" , "_ddna" }, - { EFTT_EMITTANCE, "EFTT_EMITTANCE", true, "Emittance" , "Multiplies the emissive color with RGB texture. Emissive alpha mask is contained in alpha channel." , "_em" }, - { EFTT_OCCLUSION, "EFTT_OCCLUSION", true, "Occlusion" , "Grayscale texture to mask diffuse lighting response and simulate darker areas" , "" }, - { EFTT_SPECULAR_2, "EFTT_SPECULAR_2", true, "Specular2" , "" , "_spec" }, - - // Backwards compatible names are found here and mapped to the updated enum - { EFTT_NORMALS, "EFTT_BUMP", false, "Normal" , "" , "" }, // called "Bump" in the shaders - { EFTT_SMOOTHNESS, "EFTT_GLOSS_NORMAL_A", false, "GlossNormalA" , "" , "" }, - { EFTT_HEIGHT, "EFTT_BUMPHEIGHT", false, "Height" , "" , "" }, // called "BumpHeight" in the shaders - - // This is the terminator for the name-search - { EFTT_UNKNOWN, "EFTT_UNKNOWN", false, NULL , "" }, - }; - -#if 0 - static class Verify - { - public: - Verify() - { - for (int i = 0; s_TexSlotSemantics[i].name; i++) - { - if (s_TexSlotSemantics[i].slot != i) - { - throw std::runtime_error("Invalid texture slot lookup array."); - } - } - } - } - s_VerifyTexSlotSemantics; -#endif -} - -// This should be done per shader (hence, semantics lookup map should be constructed per shader type) -EEfResTextures MaterialHelpers::FindTexSlot(const char* texName) const -{ - for (int i = 0; s_TexSlotSemantics[i].name; i++) - { - if (azstricmp(s_TexSlotSemantics[i].name, texName) == 0) - { - return s_TexSlotSemantics[i].slot; - } - } - - return EFTT_UNKNOWN; -} - -const char* MaterialHelpers::FindTexName(EEfResTextures texSlot) const -{ - for (int i = 0; s_TexSlotSemantics[i].name; i++) - { - if (s_TexSlotSemantics[i].slot == texSlot) - { - return s_TexSlotSemantics[i].name; - } - } - - return NULL; -} - -const char* MaterialHelpers::LookupTexName(EEfResTextures texSlot) const -{ - assert((texSlot >= 0) && (texSlot < EFTT_MAX)); - return s_TexSlotSemantics[texSlot].name; -} - -const char* MaterialHelpers::LookupTexDesc(EEfResTextures texSlot) const -{ - assert((texSlot >= 0) && (texSlot < EFTT_MAX)); - return s_TexSlotSemantics[texSlot].description; -} - -const char* MaterialHelpers::LookupTexEnum(EEfResTextures texSlot) const -{ - assert((texSlot >= 0) && (texSlot < EFTT_MAX)); - return s_TexSlotSemantics[texSlot].ename; -} - -const char* MaterialHelpers::LookupTexSuffix(EEfResTextures texSlot) const -{ - assert((texSlot >= 0) && (texSlot < EFTT_MAX)); - return s_TexSlotSemantics[texSlot].suffix; -} - -bool MaterialHelpers::IsAdjustableTexSlot(EEfResTextures texSlot) const -{ - assert((texSlot >= 0) && (texSlot < EFTT_MAX)); - return s_TexSlotSemantics[texSlot].adjustable; -} - -////////////////////////////////////////////////////////////////////////// -// [Shader System TO DO] - automate these lookups to be data driven! -bool MaterialHelpers::SetGetMaterialParamFloat(IRenderShaderResources& pShaderResources, const char* sParamName, float& v, bool bGet) const -{ - EEfResTextures texSlot = EFTT_UNKNOWN; - - if (!azstricmp("emissive_intensity", sParamName)) - { - texSlot = EFTT_EMITTANCE; - } - else if (!azstricmp("shininess", sParamName)) - { - texSlot = EFTT_SMOOTHNESS; - } - else if (!azstricmp("opacity", sParamName)) - { - texSlot = EFTT_OPACITY; - } - - if (!azstricmp("alpha", sParamName)) - { - if (bGet) - { - v = pShaderResources.GetAlphaRef(); - } - else - { - pShaderResources.SetAlphaRef(v); - } - - return true; - } - else if (texSlot != EFTT_UNKNOWN) - { - if (bGet) - { - v = pShaderResources.GetStrengthValue(texSlot); - } - else - { - pShaderResources.SetStrengthValue(texSlot, v); - } - - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool MaterialHelpers::SetGetMaterialParamVec3(IRenderShaderResources& pShaderResources, const char* sParamName, Vec3& v, bool bGet) const -{ - EEfResTextures texSlot = EFTT_UNKNOWN; - - if (!azstricmp("diffuse", sParamName)) - { - texSlot = EFTT_DIFFUSE; - } - else if (!azstricmp("specular", sParamName)) - { - texSlot = EFTT_SPECULAR; - } - else if (!azstricmp("emissive_color", sParamName)) - { - texSlot = EFTT_EMITTANCE; - } - - if (texSlot != EFTT_UNKNOWN) - { - if (bGet) - { - v = pShaderResources.GetColorValue(texSlot).toVec3(); - } - else - { - pShaderResources.SetColorValue(texSlot, ColorF(v, 1.0f)); - } - - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetTexModFromXml(SEfTexModificator& pTextureModifier, const XmlNodeRef& modNode) const -{ - // Modificators - float f; - uint8 c; - - modNode->getAttr("TexMod_RotateType", pTextureModifier.m_eRotType); - modNode->getAttr("TexMod_TexGenType", pTextureModifier.m_eTGType); - modNode->getAttr("TexMod_bTexGenProjected", pTextureModifier.m_bTexGenProjected); - - for (int baseu = 'U', u = baseu; u <= 'W'; u++) - { - char RT[] = "Rotate?"; - RT[6] = u; - - if (modNode->getAttr(RT, f)) - { - pTextureModifier.m_Rot [u - baseu] = Degr2Word(f); - } - - char RR[] = "TexMod_?RotateRate"; - RR[7] = u; - char RP[] = "TexMod_?RotatePhase"; - RP[7] = u; - char RA[] = "TexMod_?RotateAmplitude"; - RA[7] = u; - char RC[] = "TexMod_?RotateCenter"; - RC[7] = u; - - if (modNode->getAttr(RR, f)) - { - pTextureModifier.m_RotOscRate [u - baseu] = Degr2Word(f); - } - if (modNode->getAttr(RP, f)) - { - pTextureModifier.m_RotOscPhase [u - baseu] = Degr2Word(f); - } - if (modNode->getAttr(RA, f)) - { - pTextureModifier.m_RotOscAmplitude[u - baseu] = Degr2Word(f); - } - if (modNode->getAttr(RC, f)) - { - pTextureModifier.m_RotOscCenter [u - baseu] = f; - } - - if (u > 'V') - { - continue; - } - - char TL[] = "Tile?"; - TL[4] = u; - char OF[] = "Offset?"; - OF[6] = u; - - if (modNode->getAttr(TL, f)) - { - pTextureModifier.m_Tiling [u - baseu] = f; - } - if (modNode->getAttr(OF, f)) - { - pTextureModifier.m_Offs [u - baseu] = f; - } - - char OT[] = "TexMod_?OscillatorType"; - OT[7] = u; - char OR[] = "TexMod_?OscillatorRate"; - OR[7] = u; - char OP[] = "TexMod_?OscillatorPhase"; - OP[7] = u; - char OA[] = "TexMod_?OscillatorAmplitude"; - OA[7] = u; - - if (modNode->getAttr(OT, c)) - { - pTextureModifier.m_eMoveType [u - baseu] = c; - } - if (modNode->getAttr(OR, f)) - { - pTextureModifier.m_OscRate [u - baseu] = f; - } - if (modNode->getAttr(OP, f)) - { - pTextureModifier.m_OscPhase [u - baseu] = f; - } - if (modNode->getAttr(OA, f)) - { - pTextureModifier.m_OscAmplitude [u - baseu] = f; - } - } -} - -////////////////////////////////////////////////////////////////////////// -static SEfTexModificator defaultTexMod; -static bool defaultTexMod_Initialized = false; - -void MaterialHelpers::SetXmlFromTexMod(const SEfTexModificator& pTextureModifier, XmlNodeRef& node) const -{ - if (!defaultTexMod_Initialized) - { - ZeroStruct(defaultTexMod); - defaultTexMod.m_Tiling[0] = 1; - defaultTexMod.m_Tiling[1] = 1; - defaultTexMod_Initialized = true; - } - - if (memcmp(&pTextureModifier, &defaultTexMod, sizeof(pTextureModifier)) == 0) - { - return; - } - - XmlNodeRef modNode = node->newChild("TexMod"); - if (modNode) - { - // Modificators - float f; - uint16 s; - uint8 c; - - modNode->setAttr("TexMod_RotateType", pTextureModifier.m_eRotType); - modNode->setAttr("TexMod_TexGenType", pTextureModifier.m_eTGType); - modNode->setAttr("TexMod_bTexGenProjected", pTextureModifier.m_bTexGenProjected); - - for (int baseu = 'U', u = baseu; u <= 'W'; u++) - { - char RT[] = "Rotate?"; - RT[6] = u; - - if ((s = pTextureModifier.m_Rot [u - baseu]) != defaultTexMod.m_Rot [u - baseu]) - { - modNode->setAttr(RT, Word2Degr(s)); - } - - char RR[] = "TexMod_?RotateRate"; - RR[7] = u; - char RP[] = "TexMod_?RotatePhase"; - RP[7] = u; - char RA[] = "TexMod_?RotateAmplitude"; - RA[7] = u; - char RC[] = "TexMod_?RotateCenter"; - RC[7] = u; - - if ((s = pTextureModifier.m_RotOscRate [u - baseu]) != defaultTexMod.m_RotOscRate [u - baseu]) - { - modNode->setAttr(RR, Word2Degr(s)); - } - if ((s = pTextureModifier.m_RotOscPhase [u - baseu]) != defaultTexMod.m_RotOscPhase [u - baseu]) - { - modNode->setAttr(RP, Word2Degr(s)); - } - if ((s = pTextureModifier.m_RotOscAmplitude[u - baseu]) != defaultTexMod.m_RotOscAmplitude[u - baseu]) - { - modNode->setAttr(RA, Word2Degr(s)); - } - if ((f = pTextureModifier.m_RotOscCenter [u - baseu]) != defaultTexMod.m_RotOscCenter [u - baseu]) - { - modNode->setAttr(RC, f); - } - - if (u > 'V') - { - continue; - } - - char TL[] = "Tile?"; - TL[4] = u; - char OF[] = "Offset?"; - OF[6] = u; - - if ((f = pTextureModifier.m_Tiling [u - baseu]) != defaultTexMod.m_Tiling [u - baseu]) - { - modNode->setAttr(TL, f); - } - if ((f = pTextureModifier.m_Offs [u - baseu]) != defaultTexMod.m_Offs [u - baseu]) - { - modNode->setAttr(OF, f); - } - - char OT[] = "TexMod_?OscillatorType"; - OT[7] = u; - char OR[] = "TexMod_?OscillatorRate"; - OR[7] = u; - char OP[] = "TexMod_?OscillatorPhase"; - OP[7] = u; - char OA[] = "TexMod_?OscillatorAmplitude"; - OA[7] = u; - - if ((c = pTextureModifier.m_eMoveType [u - baseu]) != defaultTexMod.m_eMoveType [u - baseu]) - { - modNode->setAttr(OT, c); - } - if ((f = pTextureModifier.m_OscRate [u - baseu]) != defaultTexMod.m_OscRate [u - baseu]) - { - modNode->setAttr(OR, f); - } - if ((f = pTextureModifier.m_OscPhase [u - baseu]) != defaultTexMod.m_OscPhase [u - baseu]) - { - modNode->setAttr(OP, f); - } - if ((f = pTextureModifier.m_OscAmplitude [u - baseu]) != defaultTexMod.m_OscAmplitude [u - baseu]) - { - modNode->setAttr(OA, f); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetTexturesFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const -{ - const char* texmap = ""; - const char* fileName = ""; - - XmlNodeRef texturesNode = node->findChild("Textures"); - if (texturesNode) - { - for (int c = 0; c < texturesNode->getChildCount(); c++) - { - XmlNodeRef texNode = texturesNode->getChild(c); - texmap = texNode->getAttr("Map"); - - // [Shader System TO DO] - this must become per shader (and not global) according to the parser - uint8 texSlot = MaterialHelpers::FindTexSlot(texmap); - - // [Shader System TO DO] - in the new system simply gather texture slot names, then identify name usage - // and accordingly match the slot (dynamically associated per shader by the parser). - if (texSlot == EFTT_UNKNOWN) - { - continue; - } - - fileName = texNode->getAttr("File"); - - // legacy. Some textures used to be referenced using "engine\\" or "engine/" - this is no longer valid - if ( - (strlen(fileName) > 7) && - (azstrnicmp(fileName, "engine", 6) == 0) && - ((fileName[6] == '\\') || (fileName[6] == '/')) - ) - { - fileName = fileName + 7; - } - - // legacy: Files were saved into a mtl with many leading forward or back slashes, we eat them all here. We want it to start with a rel path. - const char* actualFileName = fileName; - while ((actualFileName[0]) && ((actualFileName[0] == '\\') || (actualFileName[0] == '/'))) - { - ++actualFileName; - } - fileName = actualFileName; - - // Next insert the texture resource if did not exist - TexturesResourcesMap* pTextureReourcesMap = pShaderResources.GetTexturesResourceMap(); - SEfResTexture* pTextureRes = &(*pTextureReourcesMap)[texSlot]; - - pTextureRes->m_Name = fileName; - texNode->getAttr("IsTileU", pTextureRes->m_bUTile); - texNode->getAttr("IsTileV", pTextureRes->m_bVTile); - texNode->getAttr("TexType", pTextureRes->m_Sampler.m_eTexType); - - int filter = pTextureRes->m_Filter; - if (texNode->getAttr("Filter", filter)) - { - pTextureRes->m_Filter = filter; - } - - // Next look for modulation node - add it only if exist - XmlNodeRef modNode = texNode->findChild("TexMod"); - if (modNode) - SetTexModFromXml( *(pTextureRes->AddModificator()), modNode); - } - } -} - -////////////////////////////////////////////////////////////////////////// -static SInputShaderResources defaultShaderResource; // for comparison with the default values -static SEfResTexture defaultTextureResource; // for comparison with the default values - -void MaterialHelpers::SetXmlFromTextures( SInputShaderResources& pShaderResources, XmlNodeRef& node) const -{ - // Save texturing data. - XmlNodeRef texturesNode = node->newChild("Textures"); - - for (auto& iter : *(pShaderResources.GetTexturesResourceMap()) ) - { - EEfResTextures texId = static_cast(iter.first); - const SEfResTexture* pTextureRes = &(iter.second); - if (pTextureRes && !pTextureRes->m_Name.empty() && IsAdjustableTexSlot(texId)) - { - XmlNodeRef texNode = texturesNode->newChild("Texture"); - - texNode->setAttr("Map", MaterialHelpers::LookupTexName(texId)); - texNode->setAttr("File", pTextureRes->m_Name.c_str()); - - if (pTextureRes->m_Filter != defaultTextureResource.m_Filter) - { - texNode->setAttr("Filter", pTextureRes->m_Filter); - } - if (pTextureRes->m_bUTile != defaultTextureResource.m_bUTile) - { - texNode->setAttr("IsTileU", pTextureRes->m_bUTile); - } - if (pTextureRes->m_bVTile != defaultTextureResource.m_bVTile) - { - texNode->setAttr("IsTileV", pTextureRes->m_bVTile); - } - if (pTextureRes->m_Sampler.m_eTexType != defaultTextureResource.m_Sampler.m_eTexType) - { - texNode->setAttr("TexType", pTextureRes->m_Sampler.m_eTexType); - } - - ////////////////////////////////////////////////////////////////////////// - // Save texture modificators Modificators - ////////////////////////////////////////////////////////////////////////// - SetXmlFromTexMod( *pTextureRes->GetModificator(), texNode); - } - /* [Shader System] - TO DO: test to see if slots can be removed - else - { - AZ_Assert(!pTextureRes->m_Name.empty(), "Shader resource texture error - Texture exists without a name"); - } - */ - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetVertexDeformFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const -{ - if (defaultShaderResource.m_DeformInfo.m_eType != pShaderResources.m_DeformInfo.m_eType) - { - node->setAttr("vertModifType", pShaderResources.m_DeformInfo.m_eType); - } - - XmlNodeRef deformNode = node->findChild("VertexDeform"); - if (deformNode) - { - int deform_type = eDT_Unknown; - deformNode->getAttr("Type", deform_type); - pShaderResources.m_DeformInfo.m_eType = (EDeformType)deform_type; - deformNode->getAttr("DividerX", pShaderResources.m_DeformInfo.m_fDividerX); - deformNode->getAttr("NoiseScale", pShaderResources.m_DeformInfo.m_vNoiseScale); - - XmlNodeRef waveX = deformNode->findChild("WaveX"); - if (waveX) - { - int type = eWF_None; - waveX->getAttr("Type", type); - pShaderResources.m_DeformInfo.m_WaveX.m_eWFType = (EWaveForm)type; - waveX->getAttr("Amp", pShaderResources.m_DeformInfo.m_WaveX.m_Amp); - waveX->getAttr("Level", pShaderResources.m_DeformInfo.m_WaveX.m_Level); - waveX->getAttr("Phase", pShaderResources.m_DeformInfo.m_WaveX.m_Phase); - waveX->getAttr("Freq", pShaderResources.m_DeformInfo.m_WaveX.m_Freq); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetXmlFromVertexDeform(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const -{ - int vertModif = pShaderResources.m_DeformInfo.m_eType; - node->setAttr("vertModifType", vertModif); - - if (pShaderResources.m_DeformInfo.m_eType != eDT_Unknown) - { - XmlNodeRef deformNode = node->newChild("VertexDeform"); - - deformNode->setAttr("Type", pShaderResources.m_DeformInfo.m_eType); - deformNode->setAttr("DividerX", pShaderResources.m_DeformInfo.m_fDividerX); - deformNode->setAttr("NoiseScale", pShaderResources.m_DeformInfo.m_vNoiseScale); - - XmlNodeRef waveX = deformNode->newChild("WaveX"); - waveX->setAttr("Type", pShaderResources.m_DeformInfo.m_WaveX.m_eWFType); - waveX->setAttr("Amp", pShaderResources.m_DeformInfo.m_WaveX.m_Amp); - waveX->setAttr("Level", pShaderResources.m_DeformInfo.m_WaveX.m_Level); - waveX->setAttr("Phase", pShaderResources.m_DeformInfo.m_WaveX.m_Phase); - waveX->setAttr("Freq", pShaderResources.m_DeformInfo.m_WaveX.m_Freq); - - } -} - -////////////////////////////////////////////////////////////////////////// -static inline ColorF ToCFColor(const Vec3& col) -{ - return ColorF(col); -} - -void MaterialHelpers::SetLightingFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const -{ - // Load lighting data. - Vec3 vColor; - Vec4 vColor4; - if (node->getAttr("Diffuse", vColor4)) - { - pShaderResources.m_LMaterial.m_Diffuse = ColorF(vColor4.x, vColor4.y, vColor4.z, vColor4.w); - } - else if (node->getAttr("Diffuse", vColor)) - { - pShaderResources.m_LMaterial.m_Diffuse = ToCFColor(vColor); - } - if (node->getAttr("Specular", vColor4)) - { - pShaderResources.m_LMaterial.m_Specular = ColorF(vColor4.x, vColor4.y, vColor4.z, vColor4.w); - } - else if (node->getAttr("Specular", vColor)) - { - pShaderResources.m_LMaterial.m_Specular = ToCFColor(vColor); - } - if (node->getAttr("Emittance", vColor4)) - { - pShaderResources.m_LMaterial.m_Emittance = ColorF(vColor4.x, vColor4.y, vColor4.z, vColor4.w); - } - - node->getAttr("Shininess", pShaderResources.m_LMaterial.m_Smoothness); - node->getAttr("Opacity", pShaderResources.m_LMaterial.m_Opacity); - node->getAttr("AlphaTest", pShaderResources.m_AlphaRef); - node->getAttr("VoxelCoverage", pShaderResources.m_VoxelCoverage); -} - -////////////////////////////////////////////////////////////////////////// -static inline Vec3 ToVec3(const ColorF& col) -{ - return Vec3(col.r, col.g, col.b); -} - -static inline Vec4 ToVec4(const ColorF& col) -{ - return Vec4(col.r, col.g, col.b, col.a); -} - -void MaterialHelpers::SetXmlFromLighting(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const -{ - // Save ligthing data. - if (defaultShaderResource.m_LMaterial.m_Diffuse != pShaderResources.m_LMaterial.m_Diffuse) - { - node->setAttr("Diffuse", ToVec4(pShaderResources.m_LMaterial.m_Diffuse)); - } - if (defaultShaderResource.m_LMaterial.m_Specular != pShaderResources.m_LMaterial.m_Specular) - { - node->setAttr("Specular", ToVec4(pShaderResources.m_LMaterial.m_Specular)); - } - if (defaultShaderResource.m_LMaterial.m_Emittance != pShaderResources.m_LMaterial.m_Emittance) - { - node->setAttr("Emittance", ToVec4(pShaderResources.m_LMaterial.m_Emittance)); - } - - if (defaultShaderResource.m_LMaterial.m_Opacity != pShaderResources.m_LMaterial.m_Opacity) - { - node->setAttr("Opacity", pShaderResources.m_LMaterial.m_Opacity); - } - if (defaultShaderResource.m_LMaterial.m_Smoothness != pShaderResources.m_LMaterial.m_Smoothness) - { - node->setAttr("Shininess", pShaderResources.m_LMaterial.m_Smoothness); - } - - if (defaultShaderResource.m_AlphaRef != pShaderResources.m_AlphaRef) - { - node->setAttr("AlphaTest", pShaderResources.m_AlphaRef); - } - if (defaultShaderResource.m_VoxelCoverage != pShaderResources.m_VoxelCoverage) - { - node->setAttr("VoxelCoverage", pShaderResources.m_VoxelCoverage); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetShaderParamsFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const -{ - int nA = node->getNumAttributes(); - if (!nA) - { - return; - } - - for (int i = 0; i < nA; i++) - { - const char* key = NULL, * val = NULL; - node->getAttributeByIndex(i, &key, &val); - - // try to set existing param first - bool bFound = false; - - for (int j = 0; j < pShaderResources.m_ShaderParams.size(); j++) - { - SShaderParam* pParam = &pShaderResources.m_ShaderParams[j]; - - if (pParam->m_Name == key) - { - bFound = true; - - switch (pParam->m_Type) - { - case eType_BYTE: - node->getAttr(key, pParam->m_Value.m_Byte); - break; - case eType_SHORT: - node->getAttr(key, pParam->m_Value.m_Short); - break; - case eType_INT: - node->getAttr(key, pParam->m_Value.m_Int); - break; - case eType_FLOAT: - node->getAttr(key, pParam->m_Value.m_Float); - break; - case eType_FCOLOR: - case eType_FCOLORA: - { - Vec3 vValue; - node->getAttr(key, vValue); - - pParam->m_Value.m_Color[0] = vValue.x; - pParam->m_Value.m_Color[1] = vValue.y; - pParam->m_Value.m_Color[2] = vValue.z; - } - break; - case eType_VECTOR: - { - Vec4 vValue; - if (node->getAttr(key, vValue)) - { - pParam->m_Value.m_Color[0] = vValue.x; - pParam->m_Value.m_Color[1] = vValue.y; - pParam->m_Value.m_Color[2] = vValue.z; - pParam->m_Value.m_Color[3] = vValue.w; - } - else - { - Vec3 vValue3; - if (node->getAttr(key, vValue3)) - { - pParam->m_Value.m_Color[0] = vValue3.x; - pParam->m_Value.m_Color[1] = vValue3.y; - pParam->m_Value.m_Color[2] = vValue3.z; - pParam->m_Value.m_Color[3] = 1.0f; - } - } - } - break; - default: - break; - } - } - } - - if (!bFound) - { - assert(val && key); - - SShaderParam Param; - Param.m_Name = key; - Param.m_Value.m_Color[0] = Param.m_Value.m_Color[1] = Param.m_Value.m_Color[2] = Param.m_Value.m_Color[3] = 0; -#if !defined(NDEBUG) - int res = -#endif - azsscanf(val, "%f,%f,%f,%f", &Param.m_Value.m_Color[0], &Param.m_Value.m_Color[1], &Param.m_Value.m_Color[2], &Param.m_Value.m_Color[3]); - assert(res); - - pShaderResources.m_ShaderParams.push_back(Param); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialHelpers::SetXmlFromShaderParams(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const -{ - for (int i = 0; i < pShaderResources.m_ShaderParams.size(); i++) - { - const SShaderParam* pParam = &pShaderResources.m_ShaderParams[i]; - switch (pParam->m_Type) - { - case eType_BYTE: - node->setAttr(pParam->m_Name.c_str(), (int)pParam->m_Value.m_Byte); - break; - case eType_SHORT: - node->setAttr(pParam->m_Name.c_str(), (int)pParam->m_Value.m_Short); - break; - case eType_INT: - node->setAttr(pParam->m_Name.c_str(), (int)pParam->m_Value.m_Int); - break; - case eType_FLOAT: - node->setAttr(pParam->m_Name.c_str(), (float)pParam->m_Value.m_Float); - break; - case eType_FCOLOR: - node->setAttr(pParam->m_Name.c_str(), Vec3(pParam->m_Value.m_Color[0], pParam->m_Value.m_Color[1], pParam->m_Value.m_Color[2])); - break; - case eType_VECTOR: - node->setAttr(pParam->m_Name.c_str(), Vec3(pParam->m_Value.m_Vector[0], pParam->m_Value.m_Vector[1], pParam->m_Value.m_Vector[2])); - break; - default: - break; - } - } -} - -//------------------------------------------------------------------------------ -// [Shader System TO DO] - the following function supports older version of data -// and converts them. -// This needs to go away soon! -//------------------------------------------------------------------------------ -void MaterialHelpers::MigrateXmlLegacyData(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const -{ - float glowAmount; - - // Migrate glow from 3.8.3 to emittance - if (node->getAttr("GlowAmount", glowAmount) && glowAmount > 0) - { - SEfResTexture* pTextureRes = pShaderResources.GetTextureResource(EFTT_DIFFUSE); - if (pTextureRes && (pTextureRes->m_Sampler.m_eTexType == eTT_2D)) - { - // The following line will create and insert a new texture data slot if did not exist. - pShaderResources.m_TexturesResourcesMap[EFTT_EMITTANCE].m_Name = pTextureRes->m_Name; - } - const float legacyHDRDynMult = 2.0f; - const float legacyIntensityScale = 10.0f; // Legacy scale factor 10000 divided by 1000 for kilonits - - // Clamp this at EMISSIVE_INTENSITY_SOFT_MAX because some previous glow parameters become extremely bright. - pShaderResources.m_LMaterial.m_Emittance.a = min(powf(glowAmount * legacyHDRDynMult, legacyHDRDynMult) * legacyIntensityScale, EMISSIVE_INTENSITY_SOFT_MAX); - - std::string materialName = node->getAttr("Name"); - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Material %s has had legacy GlowAmount automatically converted to Emissive Intensity. The material parameters related to Emittance should be manually adjusted for this material.", materialName.c_str()); - } - - XmlNodeRef publicParamsNode = node->findChild("PublicParams"); - if (publicParamsNode && publicParamsNode->haveAttr("BlendLayer2Specular")) - { - // Check to see if the BlendLayer2Specular is a float - AZStd::string blendLayer2SpecularString(publicParamsNode->getAttr("BlendLayer2Specular")); - - // If there are no commas in the string representation, it must be a single float instead of a color - if (blendLayer2SpecularString.find(',') == AZStd::string::npos) - { - float blendLayer2SpecularFloat = 0.0f; - publicParamsNode->getAttr("BlendLayer2Specular", blendLayer2SpecularFloat); - publicParamsNode->setAttr("BlendLayer2Specular", Vec4(blendLayer2SpecularFloat, blendLayer2SpecularFloat, blendLayer2SpecularFloat, 0.0)); - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/MaterialHelpers.h b/Code/CryEngine/Cry3DEngine/MaterialHelpers.h deleted file mode 100644 index efc1139ec6..0000000000 --- a/Code/CryEngine/Cry3DEngine/MaterialHelpers.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __MaterialHelpers_h__ -#define __MaterialHelpers_h__ -#pragma once - -#include - -// Description: -// Namespace "implementation", not a class "implementation", no member-variables, only const functions; -// Used to encapsulate the material-definition/io into Cry3DEngine (and make it plugable that way). -struct MaterialHelpers - : public IMaterialHelpers -{ - ////////////////////////////////////////////////////////////////////////// - virtual EEfResTextures FindTexSlot(const char* texName) const final; - virtual const char* FindTexName(EEfResTextures texSlot) const final; - virtual const char* LookupTexName(EEfResTextures texSlot) const final; - virtual const char* LookupTexDesc(EEfResTextures texSlot) const final; - virtual const char* LookupTexEnum(EEfResTextures texSlot) const final; - virtual const char* LookupTexSuffix(EEfResTextures texSlot) const final; - virtual bool IsAdjustableTexSlot(EEfResTextures texSlot) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual bool SetGetMaterialParamFloat(IRenderShaderResources& pShaderResources, const char* sParamName, float& v, bool bGet) const final; - virtual bool SetGetMaterialParamVec3(IRenderShaderResources& pShaderResources, const char* sParamName, Vec3& v, bool bGet) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void SetTexModFromXml(SEfTexModificator& pShaderResources, const XmlNodeRef& modNode) const final; - virtual void SetXmlFromTexMod(const SEfTexModificator& pShaderResources, XmlNodeRef& node) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void SetTexturesFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const final; - virtual void SetXmlFromTextures( SInputShaderResources& pShaderResources, XmlNodeRef& node) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void SetVertexDeformFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const final; - virtual void SetXmlFromVertexDeform(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void SetLightingFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const final; - virtual void SetXmlFromLighting(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void SetShaderParamsFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const final; - virtual void SetXmlFromShaderParams(const SInputShaderResources& pShaderResources, XmlNodeRef& node) const final; - - ////////////////////////////////////////////////////////////////////////// - virtual void MigrateXmlLegacyData(SInputShaderResources& pShaderResources, const XmlNodeRef& node) const final; -}; - -#endif - diff --git a/Code/CryEngine/Cry3DEngine/Material_Jobs.cpp b/Code/CryEngine/Cry3DEngine/Material_Jobs.cpp deleted file mode 100644 index 157c20a6e2..0000000000 --- a/Code/CryEngine/Cry3DEngine/Material_Jobs.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Material Manager Implementation - - -#include "Cry3DEngine_precompiled.h" -#include "MatMan.h" -#include "3dEngine.h" -#include "ObjMan.h" -#include "IRenderer.h" -#include "SurfaceTypeManager.h" -#include "CGFContent.h" -#include - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatMan::GetDefaultMaterial() -{ - return m_pDefaultMtl; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CMatInfo::GetSafeSubMtl(int nSubMtlSlot) -{ - if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - return this; // Not Multi material. - } - if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL) - { - return m_subMtls[nSubMtlSlot]; - } - else - { - return GetMatMan()->GetDefaultMaterial(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -SShaderItem& CMatInfo::GetShaderItem() -{ - return m_shaderItem; -} - - -/////////////////////////////////////////////////////////////////////////////// -const SShaderItem& CMatInfo::GetShaderItem() const -{ - return m_shaderItem; -} - -////////////////////////////////////////////////////////////////////////// -SShaderItem& CMatInfo::GetShaderItem(int nSubMtlSlot) -{ - SShaderItem* pShaderItem = NULL; - if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - pShaderItem = &m_shaderItem; // Not Multi material. - } - else if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL) - { - pShaderItem = &(m_subMtls[nSubMtlSlot]->m_shaderItem); - } - else - { - _smart_ptr pDefaultMaterial = GetMatMan()->GetDefaultMaterial(); - pShaderItem = &(static_cast(pDefaultMaterial.get())->m_shaderItem); - } - - return *pShaderItem; -} - -/////////////////////////////////////////////////////////////////////////////// -const SShaderItem& CMatInfo::GetShaderItem(int nSubMtlSlot) const -{ - const SShaderItem* pShaderItem = NULL; - if (m_subMtls.empty() || !(m_Flags & MTL_FLAG_MULTI_SUBMTL)) - { - pShaderItem = &m_shaderItem; // Not Multi material. - } - else if (nSubMtlSlot >= 0 && nSubMtlSlot < (int)m_subMtls.size() && m_subMtls[nSubMtlSlot] != NULL) - { - pShaderItem = &(m_subMtls[nSubMtlSlot]->m_shaderItem); - } - else - { - _smart_ptr pDefaultMaterial = GetMatMan()->GetDefaultMaterial(); - pShaderItem = &(static_cast(pDefaultMaterial.get())->m_shaderItem); - } - - return *pShaderItem; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsForwardRenderingRequired() -{ - bool bRequireForwardRendering = (m_Flags & MTL_FLAG_REQUIRE_FORWARD_RENDERING) != 0; - - if (!bRequireForwardRendering) - { - for (int i = 0; i < (int)m_subMtls.size(); ++i) - { - if (m_subMtls[i] != 0 && m_subMtls[i]->m_Flags & MTL_FLAG_REQUIRE_FORWARD_RENDERING) - { - bRequireForwardRendering = true; - break; - } - } - } - - return bRequireForwardRendering; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CMatInfo::IsNearestCubemapRequired() -{ - bool bRequireNearestCubemap = (m_Flags & MTL_FLAG_REQUIRE_NEAREST_CUBEMAP) != 0; - - if (!bRequireNearestCubemap) - { - for (int i = 0; i < (int)m_subMtls.size(); ++i) - { - if (m_subMtls[i] != 0 && m_subMtls[i]->m_Flags & MTL_FLAG_REQUIRE_NEAREST_CUBEMAP) - { - bRequireNearestCubemap = true; - break; - } - } - } - - return bRequireNearestCubemap; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/CMakeLists.txt b/Code/CryEngine/Cry3DEngine/MeshCompiler/CMakeLists.txt deleted file mode 100644 index e50cf1c972..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - -ly_add_target( - NAME Cry3DEngine.MeshCompiler.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - meshcompiler_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::mikkelsen - Legacy::CryCommon -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.cpp b/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.cpp deleted file mode 100644 index 264c08905f..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include // for assert - -#include "ForsythFaceReorderer.h" - -#include // powf() - - -ForsythFaceReorderer::ForsythFaceReorderer() -{ - computeValencyScoreTable(); -} - - -bool ForsythFaceReorderer::reorderFaces( - const size_t cacheSize, - const uint verticesPerFace, - const size_t indexCount, - const uint32* const inVertexIndices, - uint32* const outVertexIndices, - uint32* const outFaceToOldFace) -{ - clear(); - - if (verticesPerFace < sk_minVerticesPerFace || verticesPerFace > sk_maxVerticesPerFace) - { - return false; - } - if (indexCount <= 0) - { - return true; - } - if (indexCount % verticesPerFace != 0) - { - return false; - } - if (inVertexIndices == 0) - { - return false; - } - if (outVertexIndices == 0) - { - return false; - } - - if ((cacheSize < verticesPerFace) || (cacheSize > sk_maxCacheSize)) - { - return false; - } - - m_cacheSize = (int)cacheSize; - m_cacheUsedSize = 0; - computeCacheScoreTable(verticesPerFace); - - const size_t faceCount = indexCount / verticesPerFace; - if (indexCount / verticesPerFace >= (uint32) - 1) - { - // Face count is too high - return false; - } - - size_t writtenFaceCount = 0; - - uint32 vertexCount; - { - // TODO: use minVertexIndex also. It will allow to use less memory for ranged indices. - // For example indices in ranges [800;899] will use memory size 100, not 900. - uint32 maxVertexIndex = 0; - for (size_t i = 0; i < indexCount; ++i) - { - if (inVertexIndices[i] > maxVertexIndex) - { - maxVertexIndex = inVertexIndices[i]; - } - } - if (((size_t)maxVertexIndex) + 1 >= (uint32) - 1) - { - // Vertex count is too high - return false; - } - vertexCount = maxVertexIndex + 1; - } - - // Allocate and initialize arrays - { - { - Vertex initVertex; - initVertex.m_pFaceList = 0; - initVertex.m_aliveFaceCount = 0; - initVertex.m_posInCache = -1; - initVertex.m_score = 0; - m_vertices.resize(vertexCount, initVertex); - } - - m_deadFacesBitArray.resize((faceCount + 7) / 8, 0); - - m_faceScores.resize(faceCount, 0); - - m_vertexFaceLists.resize(faceCount * verticesPerFace); - } - - // Fill per-vertex face lists - { - for (size_t i = 0; i < indexCount; ++i) - { - const uint32 vertexIndex = inVertexIndices[i]; - if (m_vertices[vertexIndex].m_aliveFaceCount >= sk_maxValency) - { - // Vertex valency is too high - return false; - } - ++m_vertices[vertexIndex].m_aliveFaceCount; - } - - uint32 pos = 0; - for (uint32 vi = 0; vi < vertexCount; ++vi) - { - Vertex& v = m_vertices[vi]; - v.m_pFaceList = &m_vertexFaceLists[pos]; - pos += v.m_aliveFaceCount; - v.m_aliveFaceCount = 0; - } - assert(pos == faceCount * verticesPerFace); - - const uint32* pVertexIndex = &inVertexIndices[0]; - for (uint32 fi = 0; fi < faceCount; ++fi, pVertexIndex += verticesPerFace) - { - for (uint j = 0; j < verticesPerFace; ++j) - { - Vertex& v = m_vertices[pVertexIndex[j]]; - v.m_pFaceList[v.m_aliveFaceCount++] = fi; - } - } - } - - // Compute vertex and face scores - { - for (uint32 vi = 0; vi < vertexCount; ++vi) - { - computeVertexScore(m_vertices[vi]); - } - - const uint32* pVertexIndex = &inVertexIndices[0]; - for (uint32 fi = 0; fi < faceCount; ++fi, pVertexIndex += verticesPerFace) - { - m_faceScores[fi] = 0; - for (uint j = 0; j < verticesPerFace; ++j) - { - const Vertex& v = m_vertices[pVertexIndex[j]]; - m_faceScores[fi] += v.m_score; - } - } - } - - // Add faces with highest scores to the output buffer, one by one. - uint32 faceSearchCursor = 0; - uint32 bestFaceToAdd; - for (;; ) - { - // Find face with highest score - { - bestFaceToAdd = (uint32) - 1; - float highestScore = -1; - for (int i = 0; i < m_cacheUsedSize; ++i) - { - const Vertex& v = m_vertices[m_cache[i]]; - const uint32* const pFaces = v.m_pFaceList; - for (valency_type j = 0; j < v.m_aliveFaceCount; ++j) - { - const uint32 faceIndex = pFaces[j]; - if (highestScore < m_faceScores[faceIndex]) - { - highestScore = m_faceScores[faceIndex]; - bestFaceToAdd = faceIndex; - } - } - } - - if (bestFaceToAdd == (uint32) - 1) - { - bestFaceToAdd = findBestFaceToAdd(faceSearchCursor); - assert(bestFaceToAdd != (uint32) - 1); - } - } - - // Add the best face to the output buffer - { - size_t writtenIndexCount = writtenFaceCount * verticesPerFace; - for (uint j = 0; j < verticesPerFace; ++j) - { - outVertexIndices[writtenIndexCount + j] = inVertexIndices[(size_t)bestFaceToAdd * verticesPerFace + j]; - } - if (outFaceToOldFace) - { - outFaceToOldFace[writtenFaceCount] = bestFaceToAdd; - } - if (++writtenFaceCount == faceCount) - { - // We're done. - return true; - } - } - - // Make changes to the cache, vertex & cache scores, vertex face lists - { - m_deadFacesBitArray[bestFaceToAdd >> 3] |= 1 << (bestFaceToAdd & 7); - - for (int j = verticesPerFace - 1; j >= 0; --j) - { - const uint32 vertexIndex = inVertexIndices[(size_t)bestFaceToAdd * verticesPerFace + j]; - moveVertexToCacheTop(vertexIndex); - removeFaceFromVertex(vertexIndex, bestFaceToAdd); - } - - for (int i = 0; i < m_cacheUsedSize; ++i) - { - Vertex& v = m_vertices[m_cache[i]]; - if (i >= m_cacheSize) - { - v.m_posInCache = -1; - } - const float oldScore = v.m_score; - computeVertexScore(v); - const float differenceScore = v.m_score - oldScore; - const uint32* const pFaces = v.m_pFaceList; - for (valency_type j = 0; j < v.m_aliveFaceCount; ++j) - { - m_faceScores[pFaces[j]] += differenceScore; - } - } - if (m_cacheUsedSize > m_cacheSize) - { - m_cacheUsedSize = m_cacheSize; - } - } - } -} - - -void ForsythFaceReorderer::clear() -{ - m_vertices.clear(); - m_deadFacesBitArray.clear(); - m_faceScores.clear(); - m_vertexFaceLists.clear(); -} - -void ForsythFaceReorderer::computeCacheScoreTable(const int verticesPerFace) -{ - static const float lastFaceScore = 0.75f; - static const float cacheDecayPower = 1.5f; - - // Vertices of last added face should have *same* fixed score, - // because otherwise results will depend on the order of vertices - // in face (5,6,7 and 7,5,6 will produce different results). - for (int j = 0; j < verticesPerFace; ++j) - { - m_scoreTable_cachePosition[j] = lastFaceScore; - } - - for (int i = verticesPerFace; i < m_cacheSize; ++i) - { - const float x = 1.0f - ((i - verticesPerFace) / (m_cacheSize - verticesPerFace)); - m_scoreTable_cachePosition[i] = powf(x, cacheDecayPower); - } -} - -void ForsythFaceReorderer::computeValencyScoreTable() -{ - // Lower number of alive faces in the vertex produces higher score. - // It allows to get rid of lone vertices quickly. - - static const float valencyPower = -0.5f; - static const float valencyScale = 2.0f; - - m_scoreTable_valency[0] = 0; - for (valency_type i = 1; i < sk_valencyTableSize; ++i) - { - m_scoreTable_valency[i] = valencyScale * powf(i, valencyPower); - } -} - -void ForsythFaceReorderer::computeVertexScore(ForsythFaceReorderer::Vertex& v) -{ - if (v.m_aliveFaceCount > 0) - { - assert(v.m_posInCache < m_cacheSize); - const float valencyScore = (v.m_aliveFaceCount < sk_valencyTableSize) ? m_scoreTable_valency[v.m_aliveFaceCount] : 0; - // Preventing "SCA: warning C6385: Invalid data: accessing 'm_scoreTable_cachePosition', the readable size is '200' bytes, but '484' bytes might be read" - PREFAST_SUPPRESS_WARNING(6385) const float cacheScore = (v.m_posInCache >= 0) ? m_scoreTable_cachePosition[v.m_posInCache] : 0; - v.m_score = valencyScore + cacheScore; - } -} - -void ForsythFaceReorderer::moveVertexToCacheTop(const uint32 vertexIndex) -{ - const int oldPosInCache = m_vertices[vertexIndex].m_posInCache; - for (int dst = (oldPosInCache >= 0) ? oldPosInCache : m_cacheUsedSize; dst > 0; --dst) - { - const uint32 v = m_cache[dst - 1]; - m_cache[dst] = v; - ++m_vertices[v].m_posInCache; - } - m_cache[0] = vertexIndex; - m_vertices[vertexIndex].m_posInCache = 0; - if (oldPosInCache < 0) - { - ++m_cacheUsedSize; - } -} - -void ForsythFaceReorderer::removeFaceFromVertex(const uint32 vertexIndex, const uint32 faceIndex) -{ - Vertex& v = m_vertices[vertexIndex]; - assert(v.m_aliveFaceCount > 0); - uint32* const pFaces = v.m_pFaceList; - for (int j = 0;; ++j) - { - if (pFaces[j] == faceIndex) - { - pFaces[j] = pFaces[--v.m_aliveFaceCount]; - return; - } - } -} - -uint32 ForsythFaceReorderer::findBestFaceToAdd(uint32& faceSearchCursor) const -{ - assert(!m_faceScores.empty()); - assert(faceSearchCursor < m_faceScores.size()); - while (m_deadFacesBitArray[faceSearchCursor >> 3] & (1 << (faceSearchCursor & 7))) - { - ++faceSearchCursor; - } - return faceSearchCursor++; -} - - diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.h b/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.h deleted file mode 100644 index 6bc9df5f91..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/ForsythFaceReorderer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#include - -#include "CompileTimeAssert.h" - - -// -// Note: This implementation, in contrast to many other implementations -// of the Forsyth's algorithm, does not crash when the input faces contain -// duplicate indices, for example (8,3,8) or (1,1,9). -// -class ForsythFaceReorderer -{ -public: - static const size_t sk_maxCacheSize = 50; // you can change it. note: making it higher will increase sizeof(*this) - static const size_t sk_minVerticesPerFace = 3; - static const size_t sk_maxVerticesPerFace = 4; - - COMPILE_TIME_ASSERT(sk_minVerticesPerFace >= 3); // Bad min # of vertices per face - COMPILE_TIME_ASSERT(sk_minVerticesPerFace <= sk_maxVerticesPerFace); // Bad # of vertices per face - COMPILE_TIME_ASSERT(sk_maxVerticesPerFace <= sk_maxCacheSize); // Bad max cache size - -private: - typedef uint16 valency_type; - static const valency_type sk_maxValency = 0xFFFF; - - typedef int8 cachepos_type; - static const cachepos_type sk_maxCachePos = 127; - - struct Vertex - { - uint32* m_pFaceList; - valency_type m_aliveFaceCount; - cachepos_type m_posInCache; - float m_score; - }; - - static const size_t sk_valencyTableSize = 32; // note: size_t is used instead of valency_type because valency_type overflows if sk_valencyTableSize == 1 + sk_maxValency - COMPILE_TIME_ASSERT(sk_valencyTableSize - 1 <= sk_maxValency); // Bad valency table size - - COMPILE_TIME_ASSERT(sk_maxCacheSize <= 1 + (size_t)sk_maxCachePos); // Max cache size is too big - - std::vector m_vertices; - std::vector m_deadFacesBitArray; - std::vector m_faceScores; // score of every face - std::vector m_vertexFaceLists; // lists with indices of faces (each vertex has own list) - - int m_cacheSize; - int m_cacheUsedSize; - uint32 m_cache[sk_maxCacheSize + sk_maxVerticesPerFace]; // +sk_maxVerticesPerFace is temporary storage for vertices of the incoming face - - float m_scoreTable_valency[sk_valencyTableSize]; - float m_scoreTable_cachePosition[sk_maxCacheSize]; - -public: - ForsythFaceReorderer(); - - // notes: - // 1) it's not allowed to pass same array for inVertexIndices and outVertexIndices - // 2) outFaceToOldFace is optional (pass 0 if you don't need this array filled) - bool reorderFaces( - const size_t cacheSize, - const uint verticesPerFace, - const size_t indexCount, - const uint32* const inVertexIndices, - uint32* const outVertexIndices, - uint32* const outFaceToOldFace); - -private: - void clear(); - void computeCacheScoreTable(const int verticesPerFace); - void computeValencyScoreTable(); - void computeVertexScore(Vertex& v); - void moveVertexToCacheTop(const uint32 vertexIndex); - void removeFaceFromVertex(const uint32 vertexIndex, const uint32 faceIndex); - uint32 findBestFaceToAdd(uint32& faceSearchCursor) const; -}; - - diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.cpp b/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.cpp deleted file mode 100644 index 23b8c99be0..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.cpp +++ /dev/null @@ -1,1547 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include - -#include "MeshCompiler.h" -#include "TangentSpaceCalculation.h" -#include "ForsythFaceReorderer.h" -#include "PVRTTriStrip/PVRTTriStrip.h" - -#include // memset() - - -namespace mesh_compiler -{ - ////////////////////////////////////////////////////////////////////////// - CMeshCompiler::CMeshCompiler() - : m_pVertexMap(0) - , m_pIndexMap(0) - { - } - - ////////////////////////////////////////////////////////////////////////// - CMeshCompiler::~CMeshCompiler() - { - } - - namespace - { - struct VertexLess - { - const CMesh& mesh; - - VertexLess(const CMesh& a_mesh) - : mesh(a_mesh) - { - assert(mesh.m_pPositionsF16 == 0); - } - - bool operator()(int a, int b) const - { - if (mesh.m_pTopologyIds && mesh.m_pTopologyIds[a] != mesh.m_pTopologyIds[b]) - { - return mesh.m_pTopologyIds[a] < mesh.m_pTopologyIds[b]; - } - - int res = memcmp(&mesh.m_pPositions[a], &mesh.m_pPositions[b], sizeof(mesh.m_pPositions[a])); - if (res) - { - return res < 0; - } - for (uint streamIndex = 0; streamIndex < CMesh::maxStreamsPerType; ++streamIndex) - { - SMeshTexCoord* texCoords = mesh.GetStreamPtr(CMesh::TEXCOORDS, streamIndex); - if (texCoords) - { - res = memcmp(&texCoords[a], &texCoords[b], sizeof(texCoords[a])); - if (res) - { - return res < 0; - } - } - } - if (mesh.m_pNorms) - { - res = memcmp(&mesh.m_pNorms[a], &mesh.m_pNorms[b], sizeof(mesh.m_pNorms[a])); - if (res) - { - return res < 0; - } - } - if (mesh.m_pColor0) - { - res = memcmp(&mesh.m_pColor0[a], &mesh.m_pColor0[b], sizeof(mesh.m_pColor0[a])); - if (res) - { - return res < 0; - } - } - if (mesh.m_pColor1) - { - res = memcmp(&mesh.m_pColor1[a], &mesh.m_pColor1[b], sizeof(mesh.m_pColor1[a])); - if (res) - { - return res < 0; - } - } - if (mesh.m_pVertMats) - { - res = memcmp(&mesh.m_pVertMats[a], &mesh.m_pVertMats[b], sizeof(mesh.m_pVertMats[a])); - if (res) - { - return res < 0; - } - } - if (mesh.m_pTangents) - { - res = memcmp(&mesh.m_pTangents[a], &mesh.m_pTangents[b], sizeof(mesh.m_pTangents[a])); - if (res) - { - return res < 0; - } - } - - return false; - } - }; - - // Copies a vertex from old to new mesh - inline void CopyMeshVertex(CMesh& newMesh, int newVertex, const CMesh& oldMesh, int oldVertex) - { - assert(newVertex < newMesh.GetVertexCount()); - assert(newMesh.m_pPositionsF16 == 0); - assert(oldMesh.m_pPositionsF16 == 0); - - newMesh.m_pPositions[newVertex] = oldMesh.m_pPositions[oldVertex]; - if (oldMesh.m_pNorms) - { - newMesh.m_pNorms[newVertex] = oldMesh.m_pNorms[oldVertex]; - } - if (oldMesh.m_pTopologyIds) - { - newMesh.m_pTopologyIds[newVertex] = oldMesh.m_pTopologyIds[oldVertex]; - } - for (uint streamIndex = 0; streamIndex < CMesh::maxStreamsPerType; ++streamIndex) - { - SMeshTexCoord* oldMeshTexCoords = oldMesh.GetStreamPtr(CMesh::TEXCOORDS, streamIndex); - if (oldMeshTexCoords) - { - SMeshTexCoord* newMeshTexCoords = newMesh.GetStreamPtr(CMesh::TEXCOORDS, streamIndex); - newMeshTexCoords[newVertex] = oldMeshTexCoords[oldVertex]; - } - } - if (oldMesh.m_pColor0) - { - newMesh.m_pColor0[newVertex] = oldMesh.m_pColor0[oldVertex]; - } - if (oldMesh.m_pColor1) - { - newMesh.m_pColor1[newVertex] = oldMesh.m_pColor1[oldVertex]; - } - if (oldMesh.m_pVertMats) - { - newMesh.m_pVertMats[newVertex] = oldMesh.m_pVertMats[oldVertex]; - } - if (oldMesh.m_pTangents) - { - newMesh.m_pTangents[newVertex] = oldMesh.m_pTangents[oldVertex]; - } - //New since Touch Bending Gem. A Mesh can have boneMappings. - if (oldMesh.m_pBoneMapping) - { - newMesh.m_pBoneMapping[newVertex] = oldMesh.m_pBoneMapping[oldVertex]; - } - } - - // Modified version of MeshUtils::Mesh::ComputeVertexRemapping() - // Computes vertexOldToNew and vertexNewToOld by detecting duplicate vertices - void ComputeVertexRemapping(const CMesh& mesh, std::vector& vertexOldToNew, std::vector& vertexNewToOld) - { - const size_t nVerts = mesh.GetVertexCount(); - - vertexNewToOld.resize(nVerts); - for (size_t i = 0; i < nVerts; ++i) - { - vertexNewToOld[i] = i; - } - - VertexLess less(mesh); - std::sort(vertexNewToOld.begin(), vertexNewToOld.end(), less); - - vertexOldToNew.resize(nVerts); - - int nVertsNew = 0; - for (size_t i = 0; i < nVerts; ++i) - { - if (i == 0 || less(vertexNewToOld[i - 1], vertexNewToOld[i])) - { - vertexNewToOld[nVertsNew++] = vertexNewToOld[i]; - } - vertexOldToNew[vertexNewToOld[i]] = nVertsNew - 1; - } - vertexNewToOld.resize(nVertsNew); - } - } // namespace - - ////////////////////////////////////////////////////////////////////////// - - namespace - { - class CMeshInputProxy - : public ITriangleInputProxy - { - struct Index - { - int index; - int origPos; - }; - - template - void prepareUniqueIndices(std::vector& outIndices, std::vector& tmp, const TComparator& comparator) - { - const int faceCount = m_mesh.GetFaceCount(); - - tmp.resize(faceCount * 3); - outIndices.resize(faceCount * 3, -1); - - for (int i = 0; i < faceCount; ++i) - { - for (int j = 0; j < 3; ++j) - { - tmp[i * 3 + j].index = m_mesh.m_pFaces[i].v[j]; - tmp[i * 3 + j].origPos = i * 3 + j; - } - } - - std::sort(tmp.begin(), tmp.end(), comparator); - - int curIndex = -1; - for (int i = 0, n = faceCount * 3; i < n; ++i) - { - if (curIndex < 0 || comparator(tmp[i - 1], tmp[i])) - { - curIndex = tmp[i].index; - } - outIndices[tmp[i].origPos] = curIndex; - } - } - - const char* ValidateMesh() const - { - if (m_mesh.m_pPositionsF16) - { - return "the mesh has 16-bit positions"; - } - if (!m_mesh.m_pFaces) - { - return "the mesh has no stream with faces"; - } - if (!m_mesh.m_pPositions) - { - return "the mesh has no stream with positions"; - } - if (!m_mesh.m_pNorms) - { - return "the mesh has no stream with normals"; - } - if (!m_mesh.m_pTexCoord) - { - return "the mesh has no stream with texture coordinates"; - } - - const int faceCount = m_mesh.GetFaceCount(); - const int vertexCount = m_mesh.GetVertexCount(); - const int texCoordCount = m_mesh.GetTexCoordCount(); - if (faceCount <= 0) - { - return "face count in the mesh is 0"; - } - if (vertexCount <= 0) - { - return "vertex count in the mesh is 0"; - } - if (texCoordCount <= 0) - { - return "texture coordinate count in the mesh is 0"; - } - if (vertexCount != texCoordCount) - { - return "mismatch in number of positions and texture coordinates in the mesh"; - } - - for (int i = 0; i < faceCount; ++i) - { - for (int j = 0; j < 3; ++j) - { - const int vIdx = m_mesh.m_pFaces[i].v[j]; - if (vIdx < 0 || vIdx >= vertexCount) - { - return "a face in the mesh has vertex index that is out of range"; - } - } - } - - // Trying to trigger a crash if a stream size is not correct - { - Vec3 v(0.0f, 0.0f, 0.0f); - SMeshNormal n(v); - SMeshTexCoord uv(0, 0); - - v = m_mesh.m_pPositions[0]; - v = m_mesh.m_pPositions[vertexCount - 1]; - n = m_mesh.m_pNorms[0]; - n = m_mesh.m_pNorms[vertexCount - 1]; - uv = m_mesh.m_pTexCoord[0]; - uv = m_mesh.m_pTexCoord[vertexCount - 1]; - } - - return 0; - } - - public: - CMeshInputProxy(const CMesh& inMesh) - : m_mesh(inMesh) - { - m_pErrorText = ValidateMesh(); - if (m_pErrorText) - { - return; - } - - assert(m_mesh.m_pPositionsF16 == 0); - - struct PositionComparator - { - const Vec3* const pPositions; - const int* const pTopologyIds; - - PositionComparator(const Vec3* const a_pPositions, const int* const a_pTopologyIds) - : pPositions(a_pPositions) - , pTopologyIds(a_pTopologyIds) - { - } - - bool operator()(const Index& v0, const Index& v1) const - { - if (pTopologyIds) - { - const int a = pTopologyIds[v0.index]; - const int b = pTopologyIds[v1.index]; - if (a != b) - { - return a < b; - } - } - const Vec3& a = pPositions[v0.index]; - const Vec3& b = pPositions[v1.index]; - if (a.x != b.x) - { - return a.x < b.x; - } - if (a.y != b.y) - { - return a.y < b.y; - } - return a.z < b.z; - } - }; - - struct NormalComparator - { - const SMeshNormal* const pNormals; - - NormalComparator(const SMeshNormal* const a_pNormals) - : pNormals(a_pNormals) - { - } - - bool operator()(const Index& v0, const Index& v1) const - { - const SMeshNormal& a = pNormals[v0.index]; - const SMeshNormal& b = pNormals[v1.index]; - - return a < b; - } - }; - - struct TexCoordComparator - { - const SMeshTexCoord* const pTexCoords; - - TexCoordComparator(const SMeshTexCoord* const a_pTexCoords) - : pTexCoords(a_pTexCoords) - { - } - - bool operator()(const Index& v0, const Index& v1) const - { - const SMeshTexCoord& a = pTexCoords[v0.index]; - const SMeshTexCoord& b = pTexCoords[v1.index]; - - return a < b; - } - }; - - std::vector tmp; - prepareUniqueIndices(m_posIndx, tmp, PositionComparator(m_mesh.m_pPositions, m_mesh.m_pTopologyIds)); - prepareUniqueIndices(m_normIndx, tmp, NormalComparator(m_mesh.m_pNorms)); - prepareUniqueIndices(m_texCoordIndx, tmp, TexCoordComparator(m_mesh.m_pTexCoord)); - SMeshTexCoord* texCoords = m_mesh.GetStreamPtr(CMesh::TEXCOORDS, 1); - if (texCoords) - { - prepareUniqueIndices(m_texCoord2Indx, tmp, TexCoordComparator(texCoords)); - } - } - - const char* GetErrorText() const - { - return m_pErrorText; - } - - // interface ITriangleInputProxy ---------------------------------------------- - - //! /return 0.. - uint32 GetTriangleCount() const - { - return m_mesh.GetFaceCount(); - } - - //! /param indwTriNo 0.. - //! /param outdwPos - //! /param outdwNorm - //! /param outdwUV - void GetTriangleIndices(const uint32 indwTriNo, uint32 outdwPos[3], uint32 outdwNorm[3], uint32 outdwUV[3]) const - { - const int* const pPosInds = &m_posIndx[indwTriNo * 3]; - const int* const pNormInds = &m_normIndx[indwTriNo * 3]; - const int* const pTexCoordInds = &m_texCoordIndx[indwTriNo * 3]; - - for (int j = 0; j < 3; ++j) - { - outdwPos[j] = pPosInds[j]; - outdwUV[j] = pTexCoordInds[j]; - outdwNorm[j] = pNormInds[j]; - } - } - - //! /param indwPos 0.. - //! /param outfPos - void GetPos(const uint32 indwPos, Vec3& outfPos) const - { - assert(!m_pErrorText); - assert((int)indwPos < m_mesh.GetVertexCount()); - outfPos = m_mesh.m_pPositions[indwPos]; - } - - //! /param indwPos 0.. - //! /param outfUV - void GetUV(const uint32 indwPos, Vec2& outfUV) const - { - assert(!m_pErrorText); - assert((int)indwPos < m_mesh.GetTexCoordCount()); - outfUV = m_mesh.m_pTexCoord[indwPos].GetUV(); - } - - //! /param indwTriNo 0.. - //! /param indwVertNo 0.. - //! /param outfNorm - void GetNorm(const uint32 indwTriNo, const uint32 indwVertNo, Vec3& outfNorm) const - { - assert(!m_pErrorText); - assert((int)indwTriNo < m_mesh.GetFaceCount()); - assert((int)indwVertNo < 3); - const int vIdx = m_mesh.m_pFaces[indwTriNo].v[indwVertNo]; - assert(vIdx < m_mesh.GetVertexCount()); - outfNorm = m_mesh.m_pNorms[vIdx].GetN(); - } - //----------------------------------------------------------------------------- - - private: - const CMesh& m_mesh; - const char* m_pErrorText; - std::vector m_posIndx; // indices of unique positions (in mesh.m_pPositions) for each corner of each triangle - std::vector m_normIndx; // indices of unique normals (in mesh.m_pNorms) for each corner of each triangle - std::vector m_texCoordIndx; // indices of unique texture coordinates normals (in mesh.m_pTexCoord) for each corner of each triangle - std::vector m_texCoord2Indx; // indices of unique texture coordinates normals (in mesh.m_pTexCoord[1]) for each corner of each triangle for the 2nd uv set - }; - } - - - //do not use vec3 lib to keep it the fallback as it was - inline static Vec3 CrossProd(const Vec3& a, const Vec3& b) - { - Vec3 ret; - ret.x = a.y * b.z - a.z * b.y; - ret.y = a.z * b.x - a.x * b.z; - ret.z = a.x * b.y - a.y * b.x; - return ret; - } - - inline static void GetOtherBaseVec(const Vec3& s, Vec3& a, Vec3& b) - { - if (fabsf(s.z) > 0.5f) - { - a.x = s.z; - a.y = s.y; - a.z = -s.x; - } - else - { - a.x = s.y; - a.y = -s.x; - a.z = s.z; - } - - b = CrossProd(s, a).normalize(); - a = CrossProd(b, s).normalize(); - } - - //check packed tangent space and ensure some useful values, fix always according to normal - static void VerifyTangentSpace(SMeshTangents& rTangents, const SMeshNormal& rNormal) - { - Vec3 normal = rNormal.GetN(); - - if (normal.GetLengthSquared() < 0.1f) - { - normal = Vec3(0, 0, 1); - } - else if (normal.GetLengthSquared() < 0.9f) - { - normal.Normalize(); - } - - //unpack first(necessary since the quantization can introduce errors whereas the original float data were different) - Vec3 tangent, bitangent; - rTangents.GetTB(tangent, bitangent); - - //check if they are equal - const bool cIsEqual = (tangent == bitangent); - //check if they are zero - const bool cTangentIsZero = (tangent.GetLengthSquared() < 0.01f); - const bool cBitangentIsZero = (bitangent.GetLengthSquared() < 0.01f); - const bool cbHasBeenChanged = (cIsEqual || cTangentIsZero || cBitangentIsZero); - - if (cIsEqual) - { - //fix case where both vec's are equal - GetOtherBaseVec(normal, tangent, bitangent); - } - else - if (cTangentIsZero) - { - //fix case where tangent is zero - bitangent.Normalize();//just to make sure - if (abs(bitangent * normal) > 0.9f)//if angle between both vecs is to low, calc new one for both - { - GetOtherBaseVec(normal, tangent, bitangent); - } - else - { - tangent = CrossProd(normal, bitangent); - } - } - else - if (cBitangentIsZero) - { - //fix case where bitangent is zero - tangent.Normalize();//just to make sure - if (abs(tangent * normal) > 0.9f)//if angle between both vecs is to low, calc new one for both - { - GetOtherBaseVec(normal, tangent, bitangent); - } - else - { - bitangent = CrossProd(tangent, normal); - } - } - - //pack altered tangent vecs - if (cbHasBeenChanged) - { - rTangents = SMeshTangents(tangent, bitangent, normal); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Optimizes CMesh. - // IMPLEMENTATION: - // . Sort|Group faces by materials - // . Create vertex buffer with sequence of (possibly non-unique) vertices, 3 verts per face - // . For each (non-unique) vertex calculate the tangent base - // . Index the mesh (Compact Vertices): detect and delete duplicate vertices - // . Remove degenerated triangles in the generated mesh (GetIndices()) - // . Sort vertices and indices for GPU cache - bool CMeshCompiler::Compile(CMesh& mesh, int flags) - { - assert(mesh.m_pPositionsF16 == 0); - - if (mesh.GetFaceCount() == 0) - { - // the mesh is either empty or already compiled - - const int cVertexCount = mesh.GetVertexCount(); - if (cVertexCount == 0) - { - // the mesh is empty, nothing to do - return true; - } - - // the mesh is already compiled, likely to have a refresh here: just verify and correct tangent space - if (mesh.m_pTangents && mesh.m_pNorms) - { - for (int i = 0; i < cVertexCount; ++i) - { - VerifyTangentSpace(mesh.m_pTangents[i], mesh.m_pNorms[i]); - } - } - - - // Confetti begin: David Srour - // A CGF is already compiled as soon as a mesh is imported in the editor. - // Thus, the following code path branch will only get hit if: - // - RC job is being done outside the editor (eg. when compiling mobile resources via XML file) - // - Job input is an already compiled CGF file - // - "Refresh" was specific to force recompile - // - "OptimizedPrimitiveType = 1" to specify PowerVR stripify algorithm - if (flags & MESH_COMPILE_PVR_STRIPIFY) - { - const bool bOk = StripifyMesh_PVRTriStripList(mesh); - if (!bOk) - { - m_LastError.Format("Mesh compilation failed - stripifier failed. Contact an RC programmer."); - return false; - } - FindVertexRanges(mesh); - } - - return true; - } - - // the mesh has faces - it means that it's a non-compiled mesh. let's compile it. - - // Check input data - { - if (mesh.GetIndexCount() > 0) - { - m_LastError.Format( - "Mesh compilation failed - input mesh has both indices and faces. Contact an RC programmer."); - return false; - } - - const int vertexCount = mesh.GetVertexCount(); - const int faceCount = mesh.GetFaceCount(); - const int subSetCount = mesh.GetSubSetCount(); - - if (subSetCount >= MAX_SUB_MATERIALS) - { - m_LastError.Format( - "Mesh compilation failed - Number of subsets (%d) exceeds the maximum amount of sub-materials (%d).", - subSetCount, MAX_SUB_MATERIALS); - return false; - } - - for (int i = 0; i < faceCount; ++i) - { - const SMeshFace& face = mesh.m_pFaces[i]; - if (face.nSubset < 0 || face.nSubset >= subSetCount) - { - m_LastError.Format( - "Mesh compilation failed - face %d has bad subset index %d (allowed range is [0;%d]). Contact an RC programmer.", - i, (int)face.nSubset, subSetCount - 1); - return false; - } - for (int j = 0; j < 3; ++j) - { - const int vIdx = mesh.m_pFaces[i].v[j]; - if (vIdx < 0 || vIdx >= vertexCount) - { - m_LastError.Format( - "Mesh compilation failed - face %d has bad vertex index %d (allowed range is [0;%d]). Contact an RC programmer.", - i, vIdx, vertexCount - 1); - return false; - } - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Calculate Tangent Space. - // Results will be stored in bases[] and m_thash_table[] - ////////////////////////////////////////////////////////////////////////// - - std::vector bases; - - // m_thash_table[] contains a std::vector per subset. - // Vector contains faces belonging to the subset. - // Face contains three indices of elements in bases[]. - COMPILE_TIME_ASSERT(sizeof(m_thash_table) / sizeof(m_thash_table[0]) == MAX_SUB_MATERIALS); - for (int i = 0; i < MAX_SUB_MATERIALS; ++i) - { - m_thash_table[i].clear(); - } - - if (flags & MESH_COMPILE_TANGENTS) - { - // Generate tangent basis vectors before indexing per-material - - CMeshInputProxy Input(mesh); - if (Input.GetErrorText()) - { - m_LastError.Format("Mesh compilation failed - %s. Contact an RC or Editor programmer.", Input.GetErrorText()); - return false; - } - - CTangentSpaceCalculation tangents; - string errorMessage; - - // calculate the base matrices - const bool bUseCustomNormals = (flags & MESH_COMPILE_USECUSTOMNORMALS) ? true : false; - const eCalculateTangentSpaceErrorCode nErrorCode = tangents.CalculateTangentSpace(Input, bUseCustomNormals, errorMessage); - - if (nErrorCode != CALCULATE_TANGENT_SPACE_NO_ERRORS) - { - const char* errorCodeMessage; - - switch (nErrorCode) - { - case VERTICES_SHARING_COORDINATES: - errorCodeMessage = "Asset contains non-manifold geometry.\nPlease fix the model in your DCC tool to solve this issue.\n"; - break; - case ALL_VERTICES_ON_THE_SAME_VECTOR: - errorCodeMessage = "Asset contains non-manifold geometry.\nPlease fix the model in your DCC tool to solve this issue.\n"; - break; - case BROKEN_TEXTURE_COORDINATES: - errorCodeMessage = "Texture UV coordinates are not valid.\nCheck that the UV's have space on the UV map in your DCC tool to solve this issue.\n"; - break; - case MEMORY_ALLOCATION_FAILED: - errorCodeMessage = "Mesh compiler failed to allocate memory for compilation.\nYou can reduce the size of your mesh to attempt to solve this issue.\n"; - break; - default: - AZ_Assert(false, "Unknown error code. Please implement a failure message."); - errorCodeMessage = "Unknown error code encountered.\nThis happens when a programmer has not implemented a message for an error code.\n"; - break; - } - - m_LastError.Format("\n%s%sCalculateTangentSpace() failed - error code: %d", errorCodeMessage, errorMessage.c_str(), nErrorCode); - return false; - } - - const uint32 dwCnt = tangents.GetBaseCount(); - const uint32 dwTris = Input.GetTriangleCount(); - - bases.resize(dwCnt); - - std::vector basisIndices; - basisIndices.resize(dwTris * 3); - - for (uint32 dwTri = 0; dwTri < dwTris; dwTri++) - { - uint32 dwBaseIndx[3]; - - tangents.GetTriangleBaseIndices(dwTri, dwBaseIndx); - - // for every corner of the triangle - for (uint32 i = 0; i < 3; i++) - { - assert(dwBaseIndx[i] < dwCnt); - basisIndices[dwTri * 3 + i] = dwBaseIndx[i]; // set the base vector - } - } - - for (uint32 i = 0; i < dwCnt; i++) - { - Vec3 Tangent, Bitangent, Normal; - - tangents.GetBase(i, (float*)&Tangent, (float*)&Bitangent, (float*)&Normal); - - bases[i] = SMeshTangents(Tangent, Bitangent, Normal); - - VerifyTangentSpace(bases[i], SMeshNormal(Normal)); - } - - const int faceCount = mesh.GetFaceCount(); - for (int i = 0; i < faceCount; i++) - { - SBasisFace fc; - - fc.v[0] = basisIndices[i * 3 + 0]; - fc.v[1] = basisIndices[i * 3 + 1]; - fc.v[2] = basisIndices[i * 3 + 2]; - - const SMeshFace& face = mesh.m_pFaces[i]; - m_thash_table[face.nSubset].push_back(fc); - } - } - ////////////////////////////////////////////////////////////////////////// - - // Create new mesh that will store non-unique vertices, 3 vertices per face - - const int max_vert_num = mesh.GetFaceCount() * 3; - - CMesh outMesh; - outMesh.Copy(mesh); - outMesh.SetVertexCount(max_vert_num); - outMesh.ReallocStream(CMesh::VERT_MATS, 0, max_vert_num); - if (mesh.m_pTopologyIds) - { - outMesh.ReallocStream(CMesh::TOPOLOGY_IDS, 0, max_vert_num); - } - if (mesh.m_pTexCoord) - { - outMesh.ReallocStream(CMesh::TEXCOORDS, 0, max_vert_num); - } - if (mesh.GetStreamPtr(CMesh::TEXCOORDS, 1)) - { - outMesh.ReallocStream(CMesh::TEXCOORDS, 1, max_vert_num); - } - if (flags & MESH_COMPILE_TANGENTS) - { - outMesh.ReallocStream(CMesh::TANGENTS, 0, max_vert_num); - } - if (mesh.m_pColor0) - { - outMesh.ReallocStream(CMesh::COLORS, 0, max_vert_num); - } - if (mesh.m_pColor1) - { - outMesh.ReallocStream(CMesh::COLORS, 1, max_vert_num); - } - //New Since Touch Bending Gem. A Touch Bendable Mesh has bone mappings. - if (mesh.m_pBoneMapping) - { - outMesh.ReallocStream(CMesh::BONEMAPPING, 0, max_vert_num); - } - - // temporarily store original subset index in subset's nNumVerts - { - const uint32 nSubsets = outMesh.GetSubSetCount(); - for (uint32 i = 0; i < nSubsets; i++) - { - outMesh.m_subsets[i].nNumVerts = i; - } - } - - // Sort subsets depending on their physicalization type (don't do it for character meshes (with mapping)). - if (!m_pVertexMap) - { - // move normal physicalize subsets to the beginning (needed for breakable objects) - for (uint32 i = 0; i < (uint32)outMesh.m_subsets.size(); i++) - { - const SMeshSubset& outSubset = outMesh.m_subsets[i]; - if (outSubset.nPhysicalizeType == PHYS_GEOM_TYPE_DEFAULT) - { - const SMeshSubset tmp = outSubset; - outMesh.m_subsets.erase(outMesh.m_subsets.begin() + i); - outMesh.m_subsets.insert(outMesh.m_subsets.begin(), tmp); - } - } - // move physicalize proxy subsets to the end - for (int nSubset = (int)outMesh.m_subsets.size() - 1; nSubset >= 0; --nSubset) - { - const SMeshSubset& outSubset = outMesh.m_subsets[nSubset]; - if (outSubset.nPhysicalizeType != PHYS_GEOM_TYPE_NONE && outSubset.nPhysicalizeType != PHYS_GEOM_TYPE_DEFAULT) - { - const SMeshSubset tmp = outSubset; - outMesh.m_subsets.erase(outMesh.m_subsets.begin() + nSubset); - outMesh.m_subsets.push_back(tmp); - } - } - } - - // m_vhash_table[] contains a std::vector per subset. - // Vector contains faces belonging to the subset. - // Face contains three indices of elements in mesh.m_pVertices[]. - COMPILE_TIME_ASSERT(sizeof(m_vhash_table) / sizeof(m_vhash_table[0]) == MAX_SUB_MATERIALS); - for (int i = 0; i < MAX_SUB_MATERIALS; ++i) - { - m_vhash_table[i].clear(); - } - for (int i = 0, n = mesh.GetFaceCount(); i < n; ++i) - { - const SMeshFace& face = mesh.m_pFaces[i]; - m_vhash_table[face.nSubset].push_back(&face); - } - - // Fill the new mesh with vertices - { - int buff_vert_count = 0; - - for (int t = 0; t < outMesh.GetSubSetCount(); t++) - { - SMeshSubset& subset = outMesh.m_subsets[t]; - // memorize the starting index of this material's face range - subset.nFirstIndexId = buff_vert_count; - - // scan through all the faces using the shader #t. - // note: subset's nNumVerts contains original subset index - const size_t nNumFacesInSubset = m_vhash_table[subset.nNumVerts].size(); - for (size_t i = 0; i < nNumFacesInSubset; ++i) - { - const SMeshFace* const pFace = m_vhash_table[subset.nNumVerts][i]; - - for (int v = 0; v < 3; ++v) - { - CopyMeshVertex(outMesh, buff_vert_count, mesh, pFace->v[v]); - - if (!bases.empty()) - { - const SBasisFace& tFace = m_thash_table[subset.nNumVerts][i]; - outMesh.m_pTangents[buff_vert_count] = bases[tFace.v[v]]; - } - - // store subset id to prevent vertex sharing between materials during re-compacting - outMesh.m_pVertMats[buff_vert_count] = pFace->nSubset; - - ++buff_vert_count; - } - } - - subset.nNumIndices = buff_vert_count - subset.nFirstIndexId; - } - - if (buff_vert_count != max_vert_num) - { - m_LastError.Format("Mesh compilation failed - internal error inf handling vertices. Contact an RC programmer."); - return false; - } - } - - if (!CreateIndicesAndDeleteDuplicateVertices(outMesh)) - { - return false; - } - - if (flags & MESH_COMPILE_VALIDATE_FAIL_ON_DEGENERATE_FACES) - { - if(CheckForDegenerateFaces(outMesh)) - { - m_LastError.Format("Mesh contains degenerate faces."); - return false; - } - } - - if (flags & MESH_COMPILE_OPTIMIZE) - { - const bool bOk = StripifyMesh_Forsyth(outMesh); - if (!bOk) - { - m_LastError.Format("Mesh compilation failed - stripifier failed. Contact an RC programmer."); - return false; - } - } - else - { - if (m_pIndexMap || m_pVertexMap) - { - m_LastError.Format("Mesh compilation failed - face and/or index maps cannot be requested without OPTIMIZE. Contact an RC programmer."); - return false; - } - } - - FindVertexRanges(outMesh); - - // Copy modified mesh back to original one. - mesh.Copy(outMesh); - - // Calculate bounding box. - mesh.m_bbox.Reset(); - for (int i = 0, n = mesh.GetVertexCount(); i < n; ++i) - { - mesh.m_bbox.Add(mesh.m_pPositions[i]); - } - - if (flags & MESH_COMPILE_VALIDATE) - { - const char* pErrorDescription = 0; - if (!mesh.Validate(&pErrorDescription)) - { - m_LastError.Format("Internal error in mesh compiling (%s). Contact an RC programmer.", pErrorDescription); - return false; - } - } - - return true; - } - - - bool CMeshCompiler::StripifyMesh_Forsyth(CMesh& mesh) - { - if (mesh.GetFaceCount() > 0) - { - // We don't support stripifying of meshes with explicit faces, we support meshes with index array only - return false; - } - - enum - { - kCACHESIZE_GEFORCE3 = 24 - }; - const size_t cacheSize = kCACHESIZE_GEFORCE3; - enum - { - kVerticesPerFace = 3 - }; - - // Prepare mapping buffers - if (m_pIndexMap) - { - const int n = mesh.GetIndexCount(); - m_pIndexMap->resize(n); - for (int i = 0; i < n; ++i) - { - (*m_pIndexMap)[i] = mesh.m_pIndices[i]; - } - } - if (m_pVertexMap) - { - const int n = mesh.GetVertexCount(); - m_pVertexMap->resize(n, -1); - } - - - CMesh newMesh; - newMesh.Copy(mesh); - - // TODO: make those variables members of CMeshCompiler so we don't need to allocate memory every time - ForsythFaceReorderer ffr; - std::vector buffer0; - std::vector buffer1; - - // Reserve space - // - // We will use buffer0 for both subset's indices and for mapping from old vertex indices - // to new vertex indices (number of vertices decreases in case some vertices are not - // referenced from indices). In the latter case having size of buffer0 equal to number of - // indices is not enough if indices refer vertices in a spare fashion. Unfortunately, - // to compute range of referenced vertices we need to scan all indices in all subsets - // which is not fast. - { - int maxIndexCountInSubset = 0; - int maxVertexCountInSubset = 0; - - for (int i = 0; i < newMesh.GetSubSetCount(); i++) - { - const SMeshSubset& subset = mesh.m_subsets[i]; - - if (subset.nNumIndices == 0) - { - continue; - } - if (subset.nNumIndices < 0) - { - assert(0); - return false; - } - if (subset.nNumIndices % kVerticesPerFace != 0) - { - assert(0); - return false; - } - if (subset.nFirstIndexId % kVerticesPerFace != 0) - { - assert(0); - return false; - } - - if (maxIndexCountInSubset < subset.nNumIndices) - { - maxIndexCountInSubset = subset.nNumIndices; - } - - int subsetMinIndex = mesh.m_pIndices[subset.nFirstIndexId]; - int subsetMaxIndex = subsetMinIndex; - for (int j = 1; j < subset.nNumIndices; ++j) - { - const int idx = mesh.m_pIndices[subset.nFirstIndexId + j]; - if (idx < subsetMinIndex) - { - subsetMinIndex = idx; - } - else if (idx > subsetMaxIndex) - { - subsetMaxIndex = idx; - } - } - - if (maxVertexCountInSubset < subsetMaxIndex - subsetMinIndex + 1) - { - maxVertexCountInSubset = subsetMaxIndex - subsetMinIndex + 1; - } - } - - buffer0.resize(max(maxIndexCountInSubset, maxVertexCountInSubset)); - buffer1.resize(maxIndexCountInSubset); - } - - int newVertexCount = 0; - - for (int i = 0; i < newMesh.GetSubSetCount(); i++) - { - const SMeshSubset& subset = mesh.m_subsets[i]; - - if (subset.nNumIndices == 0) - { - continue; - } - - int subsetMinIndex = mesh.m_pIndices[subset.nFirstIndexId]; - int subsetMaxIndex = subsetMinIndex; - for (int j = 1; j < subset.nNumIndices; ++j) - { - const int idx = mesh.m_pIndices[subset.nFirstIndexId + j]; - if (idx < subsetMinIndex) - { - subsetMinIndex = idx; - } - else if (idx > subsetMaxIndex) - { - subsetMaxIndex = idx; - } - } - - for (int j = 0; j < subset.nNumIndices; ++j) - { - buffer0[j] = mesh.m_pIndices[subset.nFirstIndexId + j] - subsetMinIndex; - } - - const bool bOk = ffr.reorderFaces( - cacheSize, - kVerticesPerFace, - subset.nNumIndices, - &buffer0[0], // inVertexIndices - &buffer1[0], // outVertexIndices - 0); // faceToOldFace[] - we don't need it - - if (!bOk) - { - return false; - } - - // Reorder vertices - - SMeshSubset& newSubset = newMesh.m_subsets[i]; - newSubset.nFirstVertId = newVertexCount; - newSubset.nNumVerts = 0; - newSubset.nFirstIndexId = subset.nFirstIndexId; - newSubset.nNumIndices = subset.nNumIndices; - - const int oldSubsetVertexCount = (int)subsetMaxIndex - (int)subsetMinIndex + 1; - - assert(buffer0.size() >= (size_t)oldSubsetVertexCount); - memset(&buffer0[0], -1, sizeof(buffer0[0]) * oldSubsetVertexCount); - - for (int j = 0; j < subset.nNumIndices; ++j) - { - const uint32 idx = buffer1[j]; - const int oldVertexIndex = subsetMinIndex + idx; - if (buffer0[idx] == -1) - { - if (m_pVertexMap) - { - (*m_pVertexMap)[oldVertexIndex] = newVertexCount; - } - buffer0[idx] = newVertexCount; - //copy from old -> new vertex buffer - CopyMeshVertex(newMesh, newVertexCount, mesh, oldVertexIndex); - ++newVertexCount; - ++newSubset.nNumVerts; - } - newMesh.m_pIndices[subset.nFirstIndexId + j] = buffer0[idx]; - } - } - - newMesh.SetVertexCount(newVertexCount); - - mesh.Copy(newMesh); - - return true; - } - - // Confetti Begin: Nicholas Baldwin - bool CMeshCompiler::StripifyMesh_PVRTriStripList(CMesh& mesh) - { - if (mesh.GetFaceCount() > 0) - { - // We don't support stripifying of meshes with explicit faces, we support meshes with index array only - return false; - } - - enum - { - kCACHESIZE_GEFORCE3 = 24 - }; - const size_t cacheSize = kCACHESIZE_GEFORCE3; - enum - { - kVerticesPerFace = 3 - }; - - // Prepare mapping buffers - if (m_pIndexMap) - { - const int n = mesh.GetIndexCount(); - m_pIndexMap->resize(n); - for (int i = 0; i < n; ++i) - { - (*m_pIndexMap)[i] = mesh.m_pIndices[i]; - } - } - if (m_pVertexMap) - { - const int n = mesh.GetVertexCount(); - m_pVertexMap->resize(n, -1); - } - - - CMesh newMesh; - newMesh.Copy(mesh); - - // TODO: make those variables members of CMeshCompiler so we don't need to allocate memory every time - std::vector buffer0; - std::vector buffer1; - - // Reserve space - // - // We will use buffer0 for both subset's indices and for mapping from old vertex indices - // to new vertex indices (number of vertices decreases in case some vertices are not - // referenced from indices). In the latter case having size of buffer0 equal to number of - // indices is not enough if indices refer vertices in a spare fashion. Unfortunately, - // to compute range of referenced vertices we need to scan all indices in all subsets - // which is not fast. - { - int maxIndexCountInSubset = 0; - int maxVertexCountInSubset = 0; - - for (int i = 0; i < newMesh.GetSubSetCount(); i++) - { - const SMeshSubset& subset = mesh.m_subsets[i]; - - if (subset.nNumIndices == 0) - { - continue; - } - if (subset.nNumIndices < 0) - { - assert(0); - return false; - } - if (subset.nNumIndices % kVerticesPerFace != 0) - { - assert(0); - return false; - } - if (subset.nFirstIndexId % kVerticesPerFace != 0) - { - assert(0); - return false; - } - - if (maxIndexCountInSubset < subset.nNumIndices) - { - maxIndexCountInSubset = subset.nNumIndices; - } - - int subsetMinIndex = mesh.m_pIndices[subset.nFirstIndexId]; - int subsetMaxIndex = subsetMinIndex; - for (int j = 1; j < subset.nNumIndices; ++j) - { - const int idx = mesh.m_pIndices[subset.nFirstIndexId + j]; - if (idx < subsetMinIndex) - { - subsetMinIndex = idx; - } - else if (idx > subsetMaxIndex) - { - subsetMaxIndex = idx; - } - } - - if (maxVertexCountInSubset < subsetMaxIndex - subsetMinIndex + 1) - { - maxVertexCountInSubset = subsetMaxIndex - subsetMinIndex + 1; - } - } - - buffer0.resize(max(maxIndexCountInSubset, maxVertexCountInSubset)); - } - - int newVertexCount = 0; - - for (int i = 0; i < newMesh.GetSubSetCount(); i++) - { - const SMeshSubset& subset = mesh.m_subsets[i]; - - if (subset.nNumIndices == 0) - { - continue; - } - - int subsetMinIndex = mesh.m_pIndices[subset.nFirstIndexId]; - int subsetMaxIndex = subsetMinIndex; - for (int j = 1; j < subset.nNumIndices; ++j) - { - const int idx = mesh.m_pIndices[subset.nFirstIndexId + j]; - if (idx < subsetMinIndex) - { - subsetMinIndex = idx; - } - else if (idx > subsetMaxIndex) - { - subsetMaxIndex = idx; - } - } - - buffer1.clear(); - buffer1.resize(subset.nNumIndices); - for (int j = 0; j < subset.nNumIndices; ++j) - { - buffer0[j] = mesh.m_pIndices[subset.nFirstIndexId + j] - subsetMinIndex; - buffer1[j] = mesh.m_pIndices[subset.nFirstIndexId + j] - subsetMinIndex; - } - - PVRTTriStripList(&buffer1[0], buffer1.size() / kVerticesPerFace); - - // Reorder vertices - - SMeshSubset& newSubset = newMesh.m_subsets[i]; - newSubset.nFirstVertId = newVertexCount; - newSubset.nNumVerts = 0; - newSubset.nFirstIndexId = subset.nFirstIndexId; - newSubset.nNumIndices = subset.nNumIndices; - - const int oldSubsetVertexCount = (int)subsetMaxIndex - (int)subsetMinIndex + 1; - - assert(buffer0.size() >= (size_t)oldSubsetVertexCount); - memset(&buffer0[0], -1, sizeof(buffer0[0]) * oldSubsetVertexCount); - - for (int j = 0; j < subset.nNumIndices; ++j) - { - const uint32 idx = buffer1[j]; - const int oldVertexIndex = subsetMinIndex + idx; - if (buffer0[idx] == -1) - { - if (m_pVertexMap) - { - (*m_pVertexMap)[oldVertexIndex] = newVertexCount; - } - buffer0[idx] = newVertexCount; - //copy from old -> new vertex buffer - CopyMeshVertex(newMesh, newVertexCount, mesh, oldVertexIndex); - ++newVertexCount; - ++newSubset.nNumVerts; - } - newMesh.m_pIndices[subset.nFirstIndexId + j] = buffer0[idx]; - } - } - - newMesh.SetVertexCount(newVertexCount); - - mesh.Copy(newMesh); - - return true; - } - - - ////////////////////////////////////////////////////////////////////////// - // - // Input: - // mesh contains mesh.GetVertexCount() vertices (vertex data are stored in - // m_pPositions[] m_pNorms[] and in other data streams). - // Face and index streams are ignored. - // Output: - // 1) mesh contains unique vertices only. - // 2) data stream mesh.m_pIndices has "inputMesh.GetVertexCount()" - // indices (one output index per each input vertex). - // note that an output index points to an *unique* vertex in the - // output mesh. - // 3) data stream mesh.m_pFaces is empty. - // - // For example vertices [A, B, B, C, A, D] will be transformed to - // [A, B, C, D], and index array created will be [0, 1, 1, 2, 0, 3]. - // - // Note that mesh.subsets[] is neither used nor changed. - // - bool CMeshCompiler::CreateIndicesAndDeleteDuplicateVertices(CMesh& mesh) - { - assert(mesh.m_pPositionsF16 == 0); - - const int oldVertexCount = mesh.GetVertexCount(); - if (oldVertexCount <= 0) - { - return true; - } - - CMesh oldMesh; - oldMesh.Copy(mesh); - - std::vector vertexOldToNew; - std::vector vertexNewToOld; - ComputeVertexRemapping(oldMesh, vertexOldToNew, vertexNewToOld); - - const int newVertexCount = (int)vertexNewToOld.size(); - - assert(vertexOldToNew.size() == oldVertexCount); - const uint maxVertexCount = (sizeof(vtx_idx) == 2 ? 0xffff : 0x7fffffff); - if (newVertexCount > maxVertexCount) - { - m_LastError.Format("Too many vertices in mesh after compilation: %u (limit is %u).", (uint)newVertexCount, (uint)maxVertexCount); - return false; - } - - for (int i = 0; i < newVertexCount; ++i) - { - CopyMeshVertex(mesh, i, oldMesh, vertexNewToOld[i]); - } - - mesh.SetVertexCount(newVertexCount); - if (mesh.m_pNorms) - { - mesh.ReallocStream(CMesh::NORMALS, 0, newVertexCount); - } - if (mesh.m_pTexCoord) - { - mesh.ReallocStream(CMesh::TEXCOORDS, 0, newVertexCount); - } - if (mesh.GetStreamPtr(CMesh::TEXCOORDS, 1)) - { - mesh.ReallocStream(CMesh::TEXCOORDS, 1, newVertexCount); - } - if (mesh.m_pColor0) - { - mesh.ReallocStream(CMesh::COLORS, 0, newVertexCount); - } - if (mesh.m_pColor1) - { - mesh.ReallocStream(CMesh::COLORS, 1, newVertexCount); - } - if (mesh.m_pTangents) - { - mesh.ReallocStream(CMesh::TANGENTS, 0, newVertexCount); - } - //New since Touch Bending Gem. a Tocuh Bendable Mesh has bone mappings. - if (mesh.m_pBoneMapping) - { - mesh.ReallocStream(CMesh::BONEMAPPING, 0, newVertexCount); - } - mesh.ReallocStream(CMesh::TOPOLOGY_IDS, 0, 0); - mesh.ReallocStream(CMesh::VERT_MATS, 0, 0); - mesh.SetFaceCount(0); - mesh.SetIndexCount(oldVertexCount); - for (int i = 0; i < oldVertexCount; ++i) - { - mesh.m_pIndices[i] = vertexOldToNew[i]; - } - - return true; - } - - ////////////////////////////////////////////////////////////////////////// - bool CMeshCompiler::CheckForDegenerateFaces(const CMesh& mesh) - { - for (int i = 0; i < mesh.GetSubSetCount(); i++) - { - const SMeshSubset& subset = mesh.m_subsets[i]; - for (int j = subset.nFirstIndexId; j < subset.nFirstIndexId + subset.nNumIndices; j += 3) - { - if (mesh.m_pIndices[j + 0] == mesh.m_pIndices[j + 1] || - mesh.m_pIndices[j + 1] == mesh.m_pIndices[j + 2] || - mesh.m_pIndices[j + 2] == mesh.m_pIndices[j + 0]) - { - return true; - } - } - } - return false; - } - - ////////////////////////////////////////////////////////////////////////// - void CMeshCompiler::FindVertexRanges(CMesh& mesh) - { - assert(mesh.m_pPositionsF16 == 0); - - const int nNumIndices = mesh.GetIndexCount(); - - // Find vertex range (both index and spacial ranges) for each material (needed for rendering) - for (int i = 0; i < mesh.GetSubSetCount(); i++) - { - SMeshSubset& subset = mesh.m_subsets[i]; - - if (subset.nNumIndices == 0) - { - subset.nNumVerts = 0; - continue; - } - - if (subset.nNumIndices + subset.nFirstIndexId > nNumIndices) - { - assert(0); - continue; - } - - int nMin = INT_MAX; - int nMax = INT_MIN; - Vec3 vMin = SetMaxBB(); - Vec3 vMax = SetMinBB(); - - for (int j = subset.nFirstIndexId; j < subset.nNumIndices + subset.nFirstIndexId; j++) - { - int index = mesh.m_pIndices[j]; - Vec3 v = mesh.m_pPositions[index]; - vMin.CheckMin(v); - vMax.CheckMax(v); - nMin = min(nMin, index); - nMax = max(nMax, index); - } - subset.vCenter = (vMin + vMax) * 0.5f; - subset.fRadius = (vMin - subset.vCenter).GetLength(); - subset.nFirstVertId = nMin; - subset.nNumVerts = nMax - nMin + 1; - } - } - - - ////////////////////////////////////////////////////////////////////////// - bool CMeshCompiler::CompareMeshes(const CMesh& mesh1, const CMesh& mesh2) - { - if (mesh1.m_subsets.size() != mesh2.m_subsets.size()) - { - return false; - } - - if (mesh1.GetFaceCount() != mesh2.GetFaceCount()) - { - return false; - } - if (mesh1.GetVertexCount() != mesh2.GetVertexCount()) - { - return false; - } - if (mesh1.GetTexCoordCount() != mesh2.GetTexCoordCount()) - { - return false; - } - if (mesh1.GetIndexCount() != mesh2.GetIndexCount()) - { - return false; - } - - if (!mesh1.CompareStreams(mesh2)) - { - return false; - } - - return true; - } -} // namespace mesh_compiler diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.h b/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.h deleted file mode 100644 index 36735d5c1c..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/MeshCompiler.h +++ /dev/null @@ -1,235 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_MESHCOMPILER_H -#define CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_MESHCOMPILER_H -#pragma once - -#include "IIndexedMesh.h" - -namespace mesh_compiler -{ - enum EMeshCompileFlags - { - MESH_COMPILE_OPTIMIZE = BIT(0), - MESH_COMPILE_TANGENTS = BIT(1), - MESH_COMPILE_USECUSTOMNORMALS = BIT(3), - MESH_COMPILE_VALIDATE = BIT(4), - - // Optimizes a mesh using PowerVR SDK's optimizer. - // This should only be set with "OptimizedPrimitiveType=1" when compiling mobile assets outside the editor. - MESH_COMPILE_PVR_STRIPIFY = BIT(5), - - MESH_COMPILE_VALIDATE_FAIL_ON_DEGENERATE_FACES = BIT(6), - }; - - ////////////////////////////////////////////////////////////////////////// - class CMeshCompiler - { - public: - CMeshCompiler(); - ~CMeshCompiler(); - - // for flags see EMeshCompilerFlags - bool Compile(CMesh& mesh, int flags); - - void SetVertexRemapping(std::vector* pVertexMap) - { - m_pVertexMap = pVertexMap; - } - - void SetIndexRemapping(std::vector* pIndexMap) - { - m_pIndexMap = pIndexMap; - } - - inline bool IsEquivalentVec3dCheckYFirst(const Vec3& v0, const Vec3& v1, float fEpsilon) - { - if (fabsf(v0.y - v1.y) < fEpsilon) - { - if (fabsf(v0.x - v1.x) < fEpsilon) - { - if (fabsf(v0.z - v1.z) < fEpsilon) - { - return true; - } - } - } - return false; - } - - _inline const Vec3& ToVec3(const Vec3& vec) { return vec; } - _inline const Vec3 ToVec3(const Vec3f16& vec) { return vec.ToVec3(); } - - template - inline int FindInPosBuffer_VF_P3X(const Vec3& vPosToFind, const T* pVertBuff, std::vector* pHash, float fEpsilon) - { - for (uint32 i = 0; i < pHash->size(); i++) - { - if (IsEquivalentVec3dCheckYFirst(ToVec3(pVertBuff[(*pHash)[i]].xyz), vPosToFind, fEpsilon)) - { - return (*pHash)[i]; - } - } - - return -1; - } - - template - void WeldPos_VF_P3X( - PodArray& vertices, - PodArray& tangents, - PodArray& normals, - PodArray& indices, - float fEpsilon, - const AABB& boxBoundary) - { - const int numVertices = vertices.Count(); - V* pTmpVerts = new V[numVertices]; - SPipTangents* pTmpTangents = new SPipTangents[tangents.Count()]; - -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal* pTmpNormals = NULL; - if (normals.Count() > 0) - { - pTmpNormals = new SPipNormal[normals.Count()]; - } - - SPipNormal emptyNormal; -#endif - - int nCurVertex = 0; - PodArray newIndices; - std::vector arrHashTable[256]; - newIndices.reserve(indices.size()); - std::vector* pHash = 0; - - float fHashElemSize = 256.0f / max(boxBoundary.max.x - boxBoundary.min.x, 0.01f); - - for (uint32 i = 0; i < indices.size(); i++) - { - int v = indices[i]; - - assert(v < vertices.Count()); - - V& vPos = vertices[v]; - SPipTangents& vTang = tangents[v]; -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal& vNorm = pTmpNormals ? normals[v] : emptyNormal; -#endif - - bool bInRange( - vPos.xyz.x > boxBoundary.min.x && vPos.xyz.y > boxBoundary.min.y && vPos.xyz.z > boxBoundary.min.z && - vPos.xyz.x < boxBoundary.max.x && vPos.xyz.y < boxBoundary.max.y && vPos.xyz.z < boxBoundary.max.z); - - int nHashValue = int((vPos.xyz.x - boxBoundary.min.x) * fHashElemSize); - - pHash = &arrHashTable[(unsigned char)(nHashValue)]; - int nFind = FindInPosBuffer_VF_P3X(ToVec3(vPos.xyz), pTmpVerts, pHash, bInRange ? fEpsilon : 0.01f); - if (nFind < 0) - { - pHash->push_back(nCurVertex); - - // make sure neighbor hashes also have this vertex - if (bInRange && fEpsilon > 0.01f) - { - pHash = &arrHashTable[(unsigned char)(nHashValue + 1)]; - if (FindInPosBuffer_VF_P3X(ToVec3(vPos.xyz), pTmpVerts, pHash, fEpsilon) < 0) - { - pHash->push_back(nCurVertex); - } - - pHash = &arrHashTable[(unsigned char)(nHashValue - 1)]; - if (FindInPosBuffer_VF_P3X(ToVec3(vPos.xyz), pTmpVerts, pHash, fEpsilon) < 0) - { - pHash->push_back(nCurVertex); - } - } - - PREFAST_ASSUME(nCurVertex < numVertices); - - // add new vertex - pTmpVerts[nCurVertex] = vPos; - pTmpTangents[nCurVertex] = vTang; -#if ENABLE_NORMALSTREAM_SUPPORT - if (pTmpNormals) - { - pTmpNormals[nCurVertex] = vNorm; - } -#endif - newIndices.push_back(nCurVertex); - nCurVertex++; - } - else - { - newIndices.push_back(nFind); - } - } - - indices.Clear(); - indices.AddList(newIndices); - - vertices.Clear(); - vertices.AddList(pTmpVerts, nCurVertex); - - tangents.Clear(); - tangents.AddList(pTmpTangents, nCurVertex); - -#if ENABLE_NORMALSTREAM_SUPPORT - if (pTmpNormals) - { - normals.Clear(); - normals.AddList(pTmpNormals, nCurVertex); - - delete[] pTmpNormals; - } -#endif - - delete [] pTmpVerts; - delete [] pTmpTangents; - } - - static bool CompareMeshes(const CMesh& mesh1, const CMesh& mesh2); - - const char* GetLastError() const - { - return m_LastError; - } - - private: - bool CreateIndicesAndDeleteDuplicateVertices(CMesh& mesh); - bool StripifyMesh_Forsyth(CMesh& mesh); - bool StripifyMesh_PVRTriStripList(CMesh& mesh); - - public: - static bool CheckForDegenerateFaces(const CMesh& mesh); - - private: - static void FindVertexRanges(CMesh& mesh); - - private: - struct SBasisFace - { - int v[3]; - }; - std::vector m_vhash_table[MAX_SUB_MATERIALS]; - std::vector m_thash_table[MAX_SUB_MATERIALS]; - - std::vector* m_pVertexMap; - std::vector* m_pIndexMap; - - string m_LastError; - }; -} // namespace mesh_compiler - -#endif // CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_MESHCOMPILER_H diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.cpp b/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.cpp deleted file mode 100644 index f0ff8f15c4..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.cpp +++ /dev/null @@ -1,947 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -/****************************************************************************** - - @File PVRTTriStrip.cpp - - @Title PVRTTriStrip - - @Version @Version - - @Copyright Copyright (c) Imagination Technologies Limited. - - @Platform Independent - - @Description Strips a triangle list. - -******************************************************************************/ - -/**************************************************************************** -** Includes -****************************************************************************/ -#include -#include - -#include "PVRTTriStrip.h" - -/**************************************************************************** -** Defines -****************************************************************************/ -#define RND_TRIS_ORDER -#define FREE(X) { if(X) { free(X); (X) = 0; } } - -/**************************************************************************** -** Structures -****************************************************************************/ - -/**************************************************************************** -** Class: CTri -****************************************************************************/ -class CTri; - -/*!*************************************************************************** - @Class CTriState - @Description Stores a pointer to the triangles either side of itself, - as well as it's winding. -*****************************************************************************/ -class CTriState -{ -public: - CTri *pRev, *pFwd; - bool bWindFwd; - - CTriState() - { - bWindFwd = true; // Initial value irrelevent - pRev = NULL; - pFwd = NULL; - } -}; -/*!*************************************************************************** - @Class CTri - @Description Object used to store information about the triangle, such as - the vertex indices it is made from, which triangles are - adjacent to it, etc. -*****************************************************************************/ -class CTri -{ -public: - CTriState sNew, sOld; - - CTri *pAdj[3]; - bool bInStrip; - - const unsigned int *pIdx; // three indices for the tri - bool bOutput; - -public: - CTri(); - int FindEdge(const unsigned int pw0, const unsigned int pw1) const; - void Cement(); - void Undo(); - int EdgeFromAdjTri(const CTri &tri) const; // Find the index of the adjacent tri -}; - -/*!*************************************************************************** - @Class CStrip - @Description Object used to store the triangles that a given strip is - composed from. -*****************************************************************************/ -class CStrip -{ -protected: - unsigned int m_nTriCnt; - CTri *m_pTri; - unsigned int m_nStrips; - - CTri **m_psStrip; // Working space for finding strips - -public: - CStrip( - const unsigned int * const pui32TriList, - const unsigned int nTriCnt); - ~CStrip(); - -protected: - bool StripGrow( - CTri &triFrom, - const unsigned int nEdgeFrom, - const int nMaxChange); - -public: - void StripFromEdges(); - void StripImprove(); - - void Output( - unsigned int **ppui32Strips, - unsigned int **ppnStripLen, - unsigned int *pnStripCnt); -}; - -/**************************************************************************** -** Constants -****************************************************************************/ - -/**************************************************************************** -** Code: Class: CTri -****************************************************************************/ -CTri::CTri() -{ - pAdj[0] = NULL; - pAdj[1] = NULL; - pAdj[2] = NULL; - bInStrip = false; - bOutput = false; -} - -/*!*************************************************************************** - @Function FindEdge - @Input pw0 The first index - @Input pw1 The second index - @Return The index of the edge - @Description Finds the index of the edge that the current object shares - with the two vertex index values that have been passed in - (or returns -1 if they dont share an edge). -*****************************************************************************/ -int CTri::FindEdge(const unsigned int pw0, const unsigned int pw1) const -{ - if((pIdx[0] == pw0 && pIdx[1] == pw1)) - return 0; - if((pIdx[1] == pw0 && pIdx[2] == pw1)) - return 1; - if((pIdx[2] == pw0 && pIdx[0] == pw1)) - return 2; - return -1; -} -/*!*************************************************************************** - @Function Cement - @Description Assigns the new state as the old state. -*****************************************************************************/ -void CTri::Cement() -{ - sOld = sNew; -} -/*!*************************************************************************** - @Function Undo - @Description Reverts the new state to the old state. -*****************************************************************************/ -void CTri::Undo() -{ - sNew = sOld; -} -/*!*************************************************************************** - @Function EdgeFromAdjTri - @Input tri The triangle to compare - @Return int Index of adjacent triangle (-1 if not adjacent) - @Description If the input triangle is adjacent to the current triangle, - it's index is returned. -*****************************************************************************/ -int CTri::EdgeFromAdjTri(const CTri &tri) const -{ - for(int i = 0; i < 3; ++i) - { - if(pAdj[i] == &tri) - { - return i; - } - } - assert(false); - return -1; -} - -/**************************************************************************** -** Local code -****************************************************************************/ -/*!*************************************************************************** - @Function OrphanTri - @Input tri The triangle test - @Return int Returns 1 if change was made - @Description If the input triangle is not wound forward and is not the last - triangle in the strip, the connection with the next triangle - in the strip is removed. -*****************************************************************************/ -static int OrphanTri( - CTri * const pTri) -{ - assert(!pTri->bInStrip); - if(pTri->sNew.bWindFwd || !pTri->sNew.pFwd) - return 0; - - pTri->sNew.pFwd->sNew.pRev = NULL; - pTri->sNew.pFwd = NULL; - return 1; -} -/*!*************************************************************************** - @Function TakeTri - @Input pTri The triangle to take - @Input pRevNew The triangle that is before pTri in the new strip - @Return int Returns 1 if a new strip has been created - @Description Removes the triangle from it's current strip - and places it in a new one (following pRevNew in the new strip). -*****************************************************************************/ -static int TakeTri( - CTri * const pTri, - CTri * const pRevNew, - const bool bFwd) -{ - int nRet; - - assert(!pTri->bInStrip); - - if(pTri->sNew.pFwd && pTri->sNew.pRev) - { - assert(pTri->sNew.pFwd->sNew.pRev == pTri); - pTri->sNew.pFwd->sNew.pRev = NULL; - assert(pTri->sNew.pRev->sNew.pFwd == pTri); - pTri->sNew.pRev->sNew.pFwd = NULL; - - // If in the middle of a Strip, this will generate a new Strip - nRet = 1; - - // The second tri in the strip may need to be orphaned, or it will have wrong winding order - nRet += OrphanTri(pTri->sNew.pFwd); - } - else if(pTri->sNew.pFwd) - { - assert(pTri->sNew.pFwd->sNew.pRev == pTri); - pTri->sNew.pFwd->sNew.pRev = NULL; - - // If at the beginning of a Strip, no change - nRet = 0; - - // The second tri in the strip may need to be orphaned, or it will have wrong winding order - nRet += OrphanTri(pTri->sNew.pFwd); - } - else if(pTri->sNew.pRev) - { - assert(pTri->sNew.pRev->sNew.pFwd == pTri); - pTri->sNew.pRev->sNew.pFwd = NULL; - - // If at the end of a Strip, no change - nRet = 0; - } - else - { - // Otherwise it's a lonesome triangle; one Strip removed! - nRet = -1; - } - - pTri->sNew.pFwd = NULL; - pTri->sNew.pRev = pRevNew; - pTri->bInStrip = true; - pTri->sNew.bWindFwd = bFwd; - - if(pRevNew) - { - assert(!pRevNew->sNew.pFwd); - pRevNew->sNew.pFwd = pTri; - } - - return nRet; -} -/*!*************************************************************************** - @Function TryLinkEdge - @Input src The source triangle - @Input cmp The triangle to compare with - @Input nSrcEdge The edge of souce triangle to compare - @Input idx0 Vertex index 0 of the compare triangle - @Input idx1 Vertex index 1 of the compare triangle - @Description If the triangle to compare currently has no adjacent - triangle along the specified edge, link the source triangle - (along it's specified edge) with the compare triangle. -*****************************************************************************/ -static bool TryLinkEdge( - CTri &src, - CTri &cmp, - const int nSrcEdge, - const unsigned int idx0, - const unsigned int idx1) -{ - int nCmpEdge; - - nCmpEdge = cmp.FindEdge(idx0, idx1); - if(nCmpEdge != -1 && !cmp.pAdj[nCmpEdge]) - { - cmp.pAdj[nCmpEdge] = &src; - src.pAdj[nSrcEdge] = &cmp; - return true; - } - return false; -} - -/**************************************************************************** -** Code: Class: CStrip -****************************************************************************/ -CStrip::CStrip( - const unsigned int * const pui32TriList, - const unsigned int nTriCnt) -{ - unsigned int i, j; - bool b0, b1, b2; - - m_nTriCnt = nTriCnt; - - /* - Generate adjacency info - */ - m_pTri = new CTri[nTriCnt]; - for(i = 0; i < nTriCnt; ++i) - { - // Set pointer to indices - m_pTri[i].pIdx = &pui32TriList[3 * i]; - - b0 = false; - b1 = false; - b2 = false; - for(j = 0; j < i && !(b0 & b1 & b2); ++j) - { - if(!b0) - b0 = TryLinkEdge(m_pTri[i], m_pTri[j], 0, m_pTri[i].pIdx[1], m_pTri[i].pIdx[0]); - - if(!b1) - b1 = TryLinkEdge(m_pTri[i], m_pTri[j], 1, m_pTri[i].pIdx[2], m_pTri[i].pIdx[1]); - - if(!b2) - b2 = TryLinkEdge(m_pTri[i], m_pTri[j], 2, m_pTri[i].pIdx[0], m_pTri[i].pIdx[2]); - } - } - - // Initially, every triangle is a strip. - m_nStrips = m_nTriCnt; - - // Allocate working space for the strippers - m_psStrip = new CTri*[m_nTriCnt]; -} - -CStrip::~CStrip() -{ - delete [] m_pTri; - delete [] m_psStrip; -} -/*!*************************************************************************** - @Function StripGrow - @Input triFrom The triangle to begin from - @Input nEdgeFrom The edge of the triangle to begin from - @Input maxChange The maximum number of changes to be made - @Description Takes triFrom as a starting point of triangles to add to - the list and adds triangles sequentially by finding the next - triangle that is adjacent to the current triangle. - This is repeated until the maximum number of changes - have been made. -*****************************************************************************/ -bool CStrip::StripGrow( - CTri &triFrom, - const unsigned int nEdgeFrom, - const int nMaxChange) -{ - unsigned int i; - bool bFwd; - int nDiff, nDiffTot, nEdge; - CTri *pTri, *pTriPrev, *pTmp; - unsigned int nStripLen; - - // Start strip from this tri - pTri = &triFrom; - pTriPrev = NULL; - - nDiffTot = 0; - nStripLen = 0; - - // Start strip from this edge - nEdge = nEdgeFrom; - bFwd = true; - - // Extend the strip until we run out, or we find an improvement - nDiff = 1; - while(nDiff > nMaxChange) - { - // Add pTri to the strip - assert(pTri); - nDiff += TakeTri(pTri, pTriPrev, bFwd); - assert(nStripLen < m_nTriCnt); - m_psStrip[nStripLen++] = pTri; - - // Jump to next tri - pTriPrev = pTri; - pTri = pTri->pAdj[nEdge]; - if(!pTri) - break; // No more tris, gotta stop - - if(pTri->bInStrip) - break; // No more tris, gotta stop - - // Find which edge we came over - nEdge = pTri->EdgeFromAdjTri(*pTriPrev); - - // Find the edge to leave over - if(bFwd) - { - if(--nEdge < 0) - nEdge = 2; - } - else - { - if(++nEdge > 2) - nEdge = 0; - } - - // Swap the winding order for the next tri - bFwd = !bFwd; - } - assert(!pTriPrev->sNew.pFwd); - - /* - Accept or reject this strip. - - Accepting changes which don't change the number of strips - adds variety, which can help better strips to develop. - */ - if(nDiff <= nMaxChange) - { - nDiffTot += nDiff; - - // Great, take the Strip - for(i = 0; i < nStripLen; ++i) - { - pTri = m_psStrip[i]; - assert(pTri->bInStrip); - - // Cement affected tris - pTmp = pTri->sOld.pFwd; - if(pTmp && !pTmp->bInStrip) - { - if(pTmp->sOld.pFwd && !pTmp->sOld.pFwd->bInStrip) - pTmp->sOld.pFwd->Cement(); - pTmp->Cement(); - } - - pTmp = pTri->sOld.pRev; - if(pTmp && !pTmp->bInStrip) - { - pTmp->Cement(); - } - - // Cement this tris - pTri->bInStrip = false; - pTri->Cement(); - } - } - else - { - // Shame, undo the strip - for(i = 0; i < nStripLen; ++i) - { - pTri = m_psStrip[i]; - assert(pTri->bInStrip); - - // Undo affected tris - pTmp = pTri->sOld.pFwd; - if(pTmp && !pTmp->bInStrip) - { - if(pTmp->sOld.pFwd && !pTmp->sOld.pFwd->bInStrip) - pTmp->sOld.pFwd->Undo(); - pTmp->Undo(); - } - - pTmp = pTri->sOld.pRev; - if(pTmp && !pTmp->bInStrip) - { - pTmp->Undo(); - } - - // Undo this tris - pTri->bInStrip = false; - pTri->Undo(); - } - } - -#ifdef _DEBUG - for(int nDbg = 0; nDbg < (int)m_nTriCnt; ++nDbg) - { - assert(m_pTri[nDbg].bInStrip == false); - assert(m_pTri[nDbg].bOutput == false); - assert(m_pTri[nDbg].sOld.pRev == m_pTri[nDbg].sNew.pRev); - assert(m_pTri[nDbg].sOld.pFwd == m_pTri[nDbg].sNew.pFwd); - - if(m_pTri[nDbg].sNew.pRev) - { - assert(m_pTri[nDbg].sNew.pRev->sNew.pFwd == &m_pTri[nDbg]); - } - - if(m_pTri[nDbg].sNew.pFwd) - { - assert(m_pTri[nDbg].sNew.pFwd->sNew.pRev == &m_pTri[nDbg]); - } - } -#endif - - if(nDiffTot) - { - m_nStrips += nDiffTot; - return true; - } - return false; -} - -/*!*************************************************************************** - @Function StripFromEdges - @Description Creates a strip from the object's edge information. -*****************************************************************************/ -void CStrip::StripFromEdges() -{ - unsigned int i, j, nTest; - CTri *pTri, *pTriPrev; - int nEdge = 0; - - /* - Attempt to create grid-oriented strips. - */ - for(i = 0; i < m_nTriCnt; ++i) - { - pTri = &m_pTri[i]; - - // Count the number of empty edges - nTest = 0; - for(j = 0; j < 3; ++j) - { - if(!pTri->pAdj[j]) - { - ++nTest; - } - else - { - nEdge = j; - } - } - - if(nTest != 2) - continue; - - for(;;) - { - // A tri with two empty edges is a corner (there are other corners too, but this works so...) - while(StripGrow(*pTri, nEdge, -1)) {}; - - pTriPrev = pTri; - pTri = pTri->pAdj[nEdge]; - if(!pTri) - break; - - // Find the edge we came over - nEdge = pTri->EdgeFromAdjTri(*pTriPrev); - - // Step around to the next edge - if(++nEdge > 2) - nEdge = 0; - - pTriPrev = pTri; - pTri = pTri->pAdj[nEdge]; - if(!pTri) - break; - - // Find the edge we came over - nEdge = pTri->EdgeFromAdjTri(*pTriPrev); - - // Step around to the next edge - if(--nEdge < 0) - nEdge = 2; - -#if 0 - // If we're not tracking the edge, give up - nTest = nEdge - 1; - if(nTest < 0) - nTest = 2; - if(pTri->pAdj[nTest]) - break; - else - continue; -#endif - } - } -} - -#ifdef RND_TRIS_ORDER -struct pair -{ - unsigned int i, o; -}; - -static int compare(const void *arg1, const void *arg2) -{ - return ((pair*)arg1)->i - ((pair*)arg2)->i; -} -#endif -/*!*************************************************************************** - @Function StripImprove - @Description Optimises the strip -*****************************************************************************/ -void CStrip::StripImprove() -{ - unsigned int i, j; - bool bChanged; - int nRepCnt, nChecks; - int nMaxChange; -#ifdef RND_TRIS_ORDER - pair *pnOrder; - - /* - Create a random order to process the tris - */ - pnOrder = new pair[m_nTriCnt]; -#endif - - nRepCnt = 0; - nChecks = 2; - nMaxChange = 0; - - /* - Reduce strip count by growing each of the three strips each tri can start. - */ - while(nChecks) - { - --nChecks; - - bChanged = false; - -#ifdef RND_TRIS_ORDER - /* - Create a random order to process the tris - */ - for(i = 0; i < m_nTriCnt; ++i) - { - pnOrder[i].i = rand() * rand(); - pnOrder[i].o = i; - } - qsort(pnOrder, m_nTriCnt, sizeof(*pnOrder), compare); -#endif - - /* - Process the tris - */ - for(i = 0; i < m_nTriCnt; ++i) - { - for(j = 0; j < 3; ++j) - { -#ifdef RND_TRIS_ORDER - bChanged |= StripGrow(m_pTri[pnOrder[i].o], j, nMaxChange); -#else - bChanged |= StripGrow(m_pTri[i], j, nMaxChange); -#endif - } - } - ++nRepCnt; - - // Check the results once or twice - if(bChanged) - nChecks = 2; - - nMaxChange = (nMaxChange == 0 ? -1 : 0); - } - -#ifdef RND_TRIS_ORDER - delete [] pnOrder; -#endif - //_RPT1(_CRT_WARN, "Reps: %d\n", nRepCnt); -} -/*!*************************************************************************** - @Function Output - @Output ppui32Strips - @Output ppnStripLen The length of the strip - @Output pnStripCnt - @Description Outputs key information about the strip to the output - parameters. -*****************************************************************************/ -void CStrip::Output( - unsigned int **ppui32Strips, - unsigned int **ppnStripLen, - unsigned int *pnStripCnt) -{ - unsigned int *pui32Strips; - unsigned int *pnStripLen; - unsigned int i, j, nIdx, nStrip; - CTri *pTri; - - /* - Output Strips - */ - pnStripLen = (unsigned int*)malloc(m_nStrips * sizeof(*pnStripLen)); - pui32Strips = (unsigned int*)malloc((m_nTriCnt + m_nStrips * 2) * sizeof(*pui32Strips)); - nStrip = 0; - nIdx = 0; - for(i = 0; i < m_nTriCnt; ++i) - { - pTri = &m_pTri[i]; - - if(pTri->sNew.pRev) - continue; - assert(!pTri->sNew.pFwd || pTri->sNew.bWindFwd); - assert(pTri->bOutput == false); - - if(!pTri->sNew.pFwd) - { - pui32Strips[nIdx++] = pTri->pIdx[0]; - pui32Strips[nIdx++] = pTri->pIdx[1]; - pui32Strips[nIdx++] = pTri->pIdx[2]; - pnStripLen[nStrip] = 1; - pTri->bOutput = true; - } - else - { - if(pTri->sNew.pFwd == pTri->pAdj[0]) - { - pui32Strips[nIdx++] = pTri->pIdx[2]; - pui32Strips[nIdx++] = pTri->pIdx[0]; - } - else if(pTri->sNew.pFwd == pTri->pAdj[1]) - { - pui32Strips[nIdx++] = pTri->pIdx[0]; - pui32Strips[nIdx++] = pTri->pIdx[1]; - } - else - { - assert(pTri->sNew.pFwd == pTri->pAdj[2]); - pui32Strips[nIdx++] = pTri->pIdx[1]; - pui32Strips[nIdx++] = pTri->pIdx[2]; - } - - pnStripLen[nStrip] = 0; - do - { - assert(pTri->bOutput == false); - - // Increment tris-in-this-strip counter - ++pnStripLen[nStrip]; - - // Output the new vertex index - for(j = 0; j < 3; ++j) - { - if( - (pui32Strips[nIdx-2] != pTri->pIdx[j]) && - (pui32Strips[nIdx-1] != pTri->pIdx[j])) - { - break; - } - } - assert(j != 3); - pui32Strips[nIdx++] = pTri->pIdx[j]; - - // Double-check that the previous three indices are the indices of this tris (in some order) - assert( - ((pui32Strips[nIdx-3] == pTri->pIdx[0]) && (pui32Strips[nIdx-2] == pTri->pIdx[1]) && (pui32Strips[nIdx-1] == pTri->pIdx[2])) || - ((pui32Strips[nIdx-3] == pTri->pIdx[1]) && (pui32Strips[nIdx-2] == pTri->pIdx[2]) && (pui32Strips[nIdx-1] == pTri->pIdx[0])) || - ((pui32Strips[nIdx-3] == pTri->pIdx[2]) && (pui32Strips[nIdx-2] == pTri->pIdx[0]) && (pui32Strips[nIdx-1] == pTri->pIdx[1])) || - ((pui32Strips[nIdx-3] == pTri->pIdx[2]) && (pui32Strips[nIdx-2] == pTri->pIdx[1]) && (pui32Strips[nIdx-1] == pTri->pIdx[0])) || - ((pui32Strips[nIdx-3] == pTri->pIdx[1]) && (pui32Strips[nIdx-2] == pTri->pIdx[0]) && (pui32Strips[nIdx-1] == pTri->pIdx[2])) || - ((pui32Strips[nIdx-3] == pTri->pIdx[0]) && (pui32Strips[nIdx-2] == pTri->pIdx[2]) && (pui32Strips[nIdx-1] == pTri->pIdx[1]))); - - // Check that the latest three indices are not degenerate - assert(pui32Strips[nIdx-1] != pui32Strips[nIdx-2]); - assert(pui32Strips[nIdx-1] != pui32Strips[nIdx-3]); - assert(pui32Strips[nIdx-2] != pui32Strips[nIdx-3]); - - pTri->bOutput = true; - - // Check that the next triangle is adjacent to this triangle - assert( - (pTri->sNew.pFwd == pTri->pAdj[0]) || - (pTri->sNew.pFwd == pTri->pAdj[1]) || - (pTri->sNew.pFwd == pTri->pAdj[2]) || - (!pTri->sNew.pFwd)); - // Check that this triangle is adjacent to the next triangle - assert( - (!pTri->sNew.pFwd) || - (pTri == pTri->sNew.pFwd->pAdj[0]) || - (pTri == pTri->sNew.pFwd->pAdj[1]) || - (pTri == pTri->sNew.pFwd->pAdj[2])); - - pTri = pTri->sNew.pFwd; - } while(pTri); - } - - ++nStrip; - } - assert(nIdx == m_nTriCnt + m_nStrips * 2); - assert(nStrip == m_nStrips); - - // Check all triangles have been output - for(i = 0; i < m_nTriCnt; ++i) - { - assert(m_pTri[i].bOutput == true); - } - - // Check all triangles are present - j = 0; - for(i = 0; i < m_nStrips; ++i) - { - j += pnStripLen[i]; - } - assert(j == m_nTriCnt); - - // Output data - *pnStripCnt = m_nStrips; - *ppui32Strips = pui32Strips; - *ppnStripLen = pnStripLen; -} - -/**************************************************************************** -** Code -****************************************************************************/ - -/*!*************************************************************************** - @Function PVRTTriStrip - @Output ppui32Strips - @Output ppnStripLen - @Output pnStripCnt - @Input pui32TriList - @Input nTriCnt - @Description Reads a triangle list and generates an optimised triangle strip. -*****************************************************************************/ -void PVRTTriStrip( - unsigned int **ppui32Strips, - unsigned int **ppnStripLen, - unsigned int *pnStripCnt, - const unsigned int * const pui32TriList, - const unsigned int nTriCnt) -{ - unsigned int *pui32Strips; - unsigned int *pnStripLen; - unsigned int nStripCnt; - - /* - If the order in which triangles are tested as strip roots is - randomised, then several attempts can be made. Use the best result. - */ - for(int i = 0; i < -#ifdef RND_TRIS_ORDER - 5 -#else - 1 -#endif - ; ++i) - { - CStrip stripper(pui32TriList, nTriCnt); - -#ifdef RND_TRIS_ORDER - srand(i); -#endif - - stripper.StripFromEdges(); - stripper.StripImprove(); - stripper.Output(&pui32Strips, &pnStripLen, &nStripCnt); - - if(!i || nStripCnt < *pnStripCnt) - { - if(i) - { - FREE(*ppui32Strips); - FREE(*ppnStripLen); - } - - *ppui32Strips = pui32Strips; - *ppnStripLen = pnStripLen; - *pnStripCnt = nStripCnt; - } - else - { - FREE(pui32Strips); - FREE(pnStripLen); - } - } -} - -/*!*************************************************************************** - @Function PVRTTriStripList - @Modified pui32TriList - @Input nTriCnt - @Description Reads a triangle list and generates an optimised triangle strip. - Result is converted back to a triangle list. -*****************************************************************************/ -void PVRTTriStripList(unsigned int * const pui32TriList, const unsigned int nTriCnt) -{ - unsigned int *pui32Strips; - unsigned int *pnStripLength; - unsigned int nNumStrips; - unsigned int *pui32TriPtr, *pui32StripPtr; - - /* - Strip the geometry - */ - PVRTTriStrip(&pui32Strips, &pnStripLength, &nNumStrips, pui32TriList, nTriCnt); - - /* - Convert back to a triangle list - */ - pui32StripPtr = pui32Strips; - pui32TriPtr = pui32TriList; - for(unsigned int i = 0; i < nNumStrips; ++i) - { - *pui32TriPtr++ = *pui32StripPtr++; - *pui32TriPtr++ = *pui32StripPtr++; - *pui32TriPtr++ = *pui32StripPtr++; - - for(unsigned int j = 1; j < pnStripLength[i]; ++j) - { - // Use two indices from previous triangle, flipping tri order alternately. - if(j & 0x01) - { - *pui32TriPtr++ = pui32StripPtr[-1]; - *pui32TriPtr++ = pui32StripPtr[-2]; - } - else - { - *pui32TriPtr++ = pui32StripPtr[-2]; - *pui32TriPtr++ = pui32StripPtr[-1]; - } - - *pui32TriPtr++ = *pui32StripPtr++; - } - } - - free(pui32Strips); - free(pnStripLength); -} - -/***************************************************************************** - End of file (PVRTTriStrip.cpp) -*****************************************************************************/ - diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.h b/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.h deleted file mode 100644 index 7632eae191..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/PVRTTriStrip/PVRTTriStrip.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -/*!**************************************************************************** - - @file PVRTTriStrip.h - @copyright Copyright (c) Imagination Technologies Limited. - @brief Strips a triangle list. - -******************************************************************************/ -#ifndef _PVRTTRISTRIP_H_ -#define _PVRTTRISTRIP_H_ - - -/**************************************************************************** -** Declarations -****************************************************************************/ - -/*!*************************************************************************** - @brief Reads a triangle list and generates an optimised triangle strip. - @param[out] ppui32Strips - @param[out] ppnStripLen - @param[out] pnStripCnt - @param[in] pui32TriList - @param[in] nTriCnt -*****************************************************************************/ -void PVRTTriStrip( - unsigned int** ppui32Strips, - unsigned int** ppnStripLen, - unsigned int* pnStripCnt, - const unsigned int* const pui32TriList, - const unsigned int nTriCnt); - - -/*!*************************************************************************** - @brief Reads a triangle list and generates an optimised triangle strip. Result is - converted back to a triangle list. - @param[in,out] pui32TriList - @param[in] nTriCnt -*****************************************************************************/ -void PVRTTriStripList(unsigned int* const pui32TriList, const unsigned int nTriCnt); - - -#endif /* _PVRTTRISTRIP_H_ */ - -/***************************************************************************** - End of file (PVRTTriStrip.h) -*****************************************************************************/ - diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Android/platform_android_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Android/platform_android_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Linux/platform_linux_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Mac/platform_mac_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Windows/platform_windows_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/iOS/platform_ios_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.cpp b/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.cpp deleted file mode 100644 index 9d2e513302..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include -#include -#include - - -#include "TangentSpaceCalculation.h" -#include - -struct SMikkVertex -{ - Vec3 pos, norm, tang, bitang; - Vec2 magST; - Vec2 texc; -}; - -struct SMikkFace -{ - int vertexOffset; - int nrOriginalFace; -}; - -struct SMikkMesh -{ - std::vector mikkVerts; - std::vector mikkFaces; - int mikkNumFaces; -}; - -CTangentSpaceCalculation::CBase33::CBase33() -{ -} - -CTangentSpaceCalculation::CBase33::CBase33(const Vec3& Uval, const Vec3& Vval, const Vec3& Nval) -{ - u = Uval; - v = Vval; - n = Nval; -} - -bool CTangentSpaceCalculation::CVec3PredicateLess::operator() (const Vec3& first, const Vec3& second) const -{ - if (first.x < second.x) - { - return true; - } - - if (first.x > second.x) - { - return false; - } - - if (first.y < second.y) - { - return true; - } - - if (first.y > second.y) - { - return false; - } - - return (first.z < second.z); -} - -bool CTangentSpaceCalculation::CBase33PredicateLess::operator() (const CBase33& first, const CBase33& second) const -{ - if (first.n.x < second.n.x) - { - return true; - } - - if (first.n.x > second.n.x) - { - return false; - } - - if (first.n.y < second.n.y) - { - return true; - } - - if (first.n.y > second.n.y) - { - return false; - } - - if (first.n.z < second.n.z) - { - return true; - } - - if (first.n.z > second.n.z) - { - return false; - } - - if (first.u.x < second.u.x) - { - return true; - } - - if (first.u.x > second.u.x) - { - return false; - } - - if (first.u.y < second.u.y) - { - return true; - } - - if (first.u.y > second.u.y) - { - return false; - } - - if (first.u.z < second.u.z) - { - return true; - } - - if (first.u.z > second.u.z) - { - return false; - } - - if (first.v.x < second.v.x) - { - return true; - } - - if (first.v.x > second.v.x) - { - return false; - } - - if (first.v.y < second.v.y) - { - return true; - } - - if (first.v.y > second.v.y) - { - return false; - } - - return first.v.z < second.v.z; -} - -bool CTangentSpaceCalculation::CBaseIndexOrder::operator() (const CBaseIndex& a, const CBaseIndex& b) const -{ - // first sort by position - if (a.m_posIndex < b.m_posIndex) - { - return true; - } - if (a.m_posIndex > b.m_posIndex) - { - return false; - } - - // then by normal - if (a.m_normIndex < b.m_normIndex) - { - return true; - } - if (a.m_normIndex > b.m_normIndex) - { - return false; - } - - return false; -} - -float CTangentSpaceCalculation::CalcAngleBetween(const Vec3& invA, const Vec3& invB) -{ - double LengthQ = sqrt(invA.len2() * invB.len2()); - - // to prevent division by zero - if (LengthQ < 0.00000001) - { - LengthQ = 0.00000001; - } - - double f = invA.Dot(invB) / LengthQ; - - // acos_tpl need input in the range [-1..1] - if (f > 1.0f) - { - f = 1.0f; - } - else if (f < -1.0f) - { - f = -1.0f; - } - - // cosf is not available on every platform - float fRet = (float)acos_tpl(f); - - return fRet; -} - -void CTangentSpaceCalculation::DebugMesh(const ITriangleInputProxy& proxy) const -{ - uint32 dwTriCount = proxy.GetTriangleCount(); - - // search for polygons that use the same indices (input data problems) - for (uint32 a = 0; a < dwTriCount; a++) - { - uint32 dwAPos[3], dwANorm[3], dwAUV[3]; - - proxy.GetTriangleIndices(a, dwAPos, dwANorm, dwAUV); - - for (uint32 b = a + 1; b < dwTriCount; b++) - { - uint32 dwBPos[3], dwBNorm[3], dwBUV[3]; - - proxy.GetTriangleIndices(b, dwBPos, dwBNorm, dwBUV); - - assert(!(dwAPos[0] == dwBPos[0] && dwAPos[1] == dwBPos[1] && dwAPos[2] == dwBPos[2])); - assert(!(dwAPos[1] == dwBPos[0] && dwAPos[2] == dwBPos[1] && dwAPos[0] == dwBPos[2])); - assert(!(dwAPos[2] == dwBPos[0] && dwAPos[0] == dwBPos[1] && dwAPos[1] == dwBPos[2])); - - assert(!(dwAPos[1] == dwBPos[0] && dwAPos[0] == dwBPos[1] && dwAPos[2] == dwBPos[2])); - assert(!(dwAPos[2] == dwBPos[0] && dwAPos[1] == dwBPos[1] && dwAPos[0] == dwBPos[2])); - assert(!(dwAPos[0] == dwBPos[0] && dwAPos[2] == dwBPos[1] && dwAPos[1] == dwBPos[2])); - } - } -} - -Vec3 CTangentSpaceCalculation::Rotate(const Vec3& vFrom, const Vec3& vTo, const Vec3& vInput) -{ - // no mesh is perfect - // assert(IsNormalized(vFrom)); - // no mesh is perfect - // assert(IsNormalized(vTo)); - - // rotation axis - Vec3 vRotAxis = vFrom.cross(vTo); - - float fSin = vRotAxis.len(); - float fCos = vFrom.Dot(vTo); - - // no rotation - if (fSin < 0.00001f) - { - return vInput; - } - - // normalize - vRotAxis = vRotAxis * (1.0f / fSin); - - // perpendicular to vRotAxis and vFrom90deg - Vec3 vFrom90deg = (vRotAxis.cross(vFrom)).normalize(); - - // Base is vFrom,vFrom90deg,vRotAxis - float fXInPlane = vFrom.Dot(vInput); - float fYInPlane = vFrom90deg.Dot(vInput); - - Vec3 a = vFrom * (fXInPlane * fCos - fYInPlane * fSin); - Vec3 b = vFrom90deg * (fXInPlane * fSin + fYInPlane * fCos); - Vec3 c = vRotAxis * (vRotAxis.Dot(vInput)); - - return a + b + c; -} - -eCalculateTangentSpaceErrorCode CTangentSpaceCalculation::CalculateTangentSpace(const ITriangleInputProxy& inInput, const bool bUseCustomNormals, string& errorMessage) -{ - if (bUseCustomNormals) - { - return CalculateTangentSpaceMikk(inInput, errorMessage); - } - - uint32 dwTriCount = inInput.GetTriangleCount(); - - // not a number in texture coordinates - bool bTextureCoordinatesBroken = false; - - // clear result - m_baseVectors.clear(); - m_trianglesBaseAssigment.clear(); - m_trianglesBaseAssigment.reserve(dwTriCount); - assert(m_baseVectors.empty()); - assert(m_trianglesBaseAssigment.empty()); - - // second=index into m_BaseVectors, generated output data - std::multimap mBaseMap; - // base vectors per triangle - std::vector vTriangleBase; - - // calculate the base vectors per triangle ------------------------------------------- - { - eCalculateTangentSpaceErrorCode errorCode = CALCULATE_TANGENT_SPACE_NO_ERRORS; - for (uint32 i = 0; i < dwTriCount; i++) - { - // get data from caller --------------------------- - uint32 dwPos[3], dwNorm[3], dwUV[3]; - - inInput.GetTriangleIndices(i, dwPos, dwNorm, dwUV); - - Vec3 vPos[3]; - Vec2 vUV[3]; - - for (int e = 0; e < 3; e++) - { - inInput.GetPos(dwPos[e], vPos[e]); - inInput.GetUV(dwUV[e], vUV[e]); - } - - // calculate tangent vectors --------------------------- - - Vec3 vA = vPos[1] - vPos[0]; - Vec3 vB = vPos[2] - vPos[0]; - Vec3 vC = vPos[2] - vPos[1]; - - if (vA.IsZero()) - { - //vert 0 and 1 have the same coordinates - errorMessage.Format("Vertices 0 and 1 have the same coordinate: (%f : %f : %f)\n", vPos[0].x, vPos[0].y, vPos[0].z); - errorCode = VERTICES_SHARING_COORDINATES; - continue; - } - - if (vB.IsZero()) - { - //vert 2 and 0 have the same coordinates - errorMessage.Format("Vertices 2 and 0 have the same coordinate: (%f : %f : %f)\n", vPos[0].x, vPos[0].y, vPos[0].z); - errorCode = VERTICES_SHARING_COORDINATES; - continue; - } - - if (vC.IsZero()) - { - //vert 2 and 1 have the same coordinates - errorMessage.Format("Vertices 2 and 1 have the same coordinate: (%f : %f : %f)\n", vPos[1].x, vPos[1].y, vPos[1].z); - errorCode = VERTICES_SHARING_COORDINATES; - continue; - } - - float fDeltaU1 = vUV[1].x - vUV[0].x; - float fDeltaU2 = vUV[2].x - vUV[0].x; - float fDeltaV1 = vUV[1].y - vUV[0].y; - float fDeltaV2 = vUV[2].y - vUV[0].y; - - float div = (fDeltaU1 * fDeltaV2 - fDeltaU2 * fDeltaV1); - - if (_isnan(div)) - { - errorMessage.Format("Vertices 0,1,2 have broken texture coordinates v0:(%f : %f : %f) v1:(%f : %f : %f) v2:(%f : %f : %f)\n", vPos[0].x, vPos[0].y, vPos[0].z, vPos[1].x, vPos[1].y, vPos[1].z, vPos[2].x, vPos[2].y, vPos[2].z); - bTextureCoordinatesBroken = true; - div = 0.0f; - } - - Vec3 vU, vV, vN = (vA.cross(vB)).normalize(); - - if (div != 0.0) - { - // 2D triangle area = (u1*v2-u2*v1)/2 - float a = fDeltaV2; // /div was removed - no required because of normalize() - float b = -fDeltaV1; - float c = -fDeltaU2; - float d = fDeltaU1; - - // /fAreaMul2*fAreaMul2 was optimized away -> small triangles in UV should contribute less and - // less artifacts (no divide and multiply) - vU = (vA * a + vB * b) * fsgnf(div); - vV = (vA * c + vB * d) * fsgnf(div); - } - else - { - vU = Vec3(1, 0, 0); - vV = Vec3(0, 1, 0); - } - - vTriangleBase.push_back(CBase33(vU, vV, vN)); - } - if (errorCode != CALCULATE_TANGENT_SPACE_NO_ERRORS) - { - return errorCode; - } - } - - // distribute the normals to the vertices - { - // we create a new tangent base for every vertex index that has a different normal (later we split further for mirrored use) - // and sum the base vectors (weighted by angle and mirrored if necessary) - for (uint32 i = 0; i < dwTriCount; i++) - { - uint32 e; - - // get data from caller --------------------------- - uint32 dwPos[3], dwNorm[3], dwUV[3]; - - inInput.GetTriangleIndices(i, dwPos, dwNorm, dwUV); - CBase33 TriBase = vTriangleBase[i]; - Vec3 vPos[3]; - - for (e = 0; e < 3; e++) - { - inInput.GetPos(dwPos[e], vPos[e]); - } - - // for each triangle vertex - for (e = 0; e < 3; e++) - { - // weight by angle to fix the L-Shape problem - float fWeight = CalcAngleBetween(vPos[(e + 2) % 3] - vPos[e], vPos[(e + 1) % 3] - vPos[e]); - - if (fWeight <= 0.0f) - { - fWeight = 0.0001f; - } - - AddNormal2Base(mBaseMap, dwPos[e], dwNorm[e], TriBase.n * fWeight); - } - } - } - - // distribute the uv vectors to the vertices - { - // we create a new tangent base for every vertex index that has a different normal - // if the base vectors does'nt fit we split as well - for (uint32 i = 0; i < dwTriCount; i++) - { - uint32 e; - - // get data from caller --------------------------- - uint32 dwPos[3], dwNorm[3], dwUV[3]; - - CTriBaseIndex Indx; - inInput.GetTriangleIndices(i, dwPos, dwNorm, dwUV); - CBase33 TriBase = vTriangleBase[i]; - Vec3 vPos[3]; - - for (e = 0; e < 3; e++) - { - inInput.GetPos(dwPos[e], vPos[e]); - } - - // for each triangle vertex - for (e = 0; e < 3; e++) - { - // weight by angle to fix the L-Shape problem - float fWeight = CalcAngleBetween(vPos[(e + 2) % 3] - vPos[e], vPos[(e + 1) % 3] - vPos[e]); - - Indx.p[e] = AddUV2Base(mBaseMap, dwPos[e], dwNorm[e], TriBase.u * fWeight, TriBase.v * fWeight, TriBase.n.normalize()); - } - - m_trianglesBaseAssigment.push_back(Indx); - } - } - - - // adjust the base vectors per vertex ------------------------------------------- - { - std::vector::iterator it; - - for (it = m_baseVectors.begin(); it != m_baseVectors.end(); ++it) - { - CBase33& ref = (*it); - - // rotate u and v in n plane - { - Vec3 vUout, vVout, vNout; - - vNout = ref.n; - vNout.normalize(); - - // project u in n plane - // project v in n plane - vUout = ref.u - vNout * (vNout.Dot(ref.u)); - vVout = ref.v - vNout * (vNout.Dot(ref.v)); - - ref.u = vUout; - ref.u.normalize(); - - ref.v = vVout; - ref.v.normalize(); - - ref.n = vNout; - - //assert(ref.u.x>=-1 && ref.u.x<=1); - //assert(ref.u.y>=-1 && ref.u.y<=1); - //assert(ref.u.z>=-1 && ref.u.z<=1); - //assert(ref.v.x>=-1 && ref.v.x<=1); - //assert(ref.v.y>=-1 && ref.v.y<=1); - //assert(ref.v.z>=-1 && ref.v.z<=1); - //assert(ref.n.x>=-1 && ref.n.x<=1); - //assert(ref.n.y>=-1 && ref.n.y<=1); - //assert(ref.n.z>=-1 && ref.n.z<=1); - } - } - } - - return bTextureCoordinatesBroken ? BROKEN_TEXTURE_COORDINATES : CALCULATE_TANGENT_SPACE_NO_ERRORS; -} - -uint32 CTangentSpaceCalculation::AddUV2Base(std::multimap& inMap, - const uint32 indwPosNo, const uint32 indwNormNo, const Vec3& inU, const Vec3& inV, const Vec3& inNormN) -{ - CBaseIndex Indx; - - Indx.m_posIndex = indwPosNo; - Indx.m_normIndex = indwNormNo; - - std::multimap::iterator iFind, iFindEnd; - - iFind = inMap.lower_bound(Indx); - - assert(iFind != inMap.end()); - - Vec3 vNormal = m_baseVectors[(*iFind).second].n; - - iFindEnd = inMap.upper_bound(Indx); - - uint32 dwBaseUVIndex = 0xffffffff; // init with not found - - bool bParity = inU.cross(inV).Dot(inNormN) > 0.0f; - - for (; iFind != iFindEnd; ++iFind) - { - CBase33& refFound = m_baseVectors[(*iFind).second]; - - if (!refFound.u.IsZero()) - { - bool bParityRef = refFound.u.cross(refFound.v).Dot(refFound.n) > 0.0f; - bool bParityCheck = (bParityRef == bParity); - - if (!bParityCheck) - { - continue; - } - - // bool bHalfAngleCheck=normalize(inU+inV) * normalize(refFound.u+refFound.v) > 0.0f; - Vec3 normRefFound = refFound.n; - normRefFound.normalize(); - - Vec3 uvRefSum = refFound.u + refFound.v; - uvRefSum.normalize(); - - Vec3 vRotHalf = Rotate(normRefFound, inNormN, uvRefSum); - - Vec3 uvInSum = inU + inV; - uvInSum.normalize(); - bool bHalfAngleCheck = uvInSum.Dot(vRotHalf) > 0.0f; - // bool bHalfAngleCheck=normalize(normalize(inU)+normalize(inV)) * normalize(normalize(refFound.u)+normalize(refFound.v)) > 0.0f; - - if (!bHalfAngleCheck) - { - continue; - } - } - - dwBaseUVIndex = (*iFind).second; - break; - } - - // not found - if (dwBaseUVIndex == 0xffffffff) - { - // otherwise create a new base - CBase33 Base(Vec3(0, 0, 0), Vec3(0, 0, 0), vNormal); - - dwBaseUVIndex = m_baseVectors.size(); - - inMap.insert(std::pair(Indx, dwBaseUVIndex)); - m_baseVectors.push_back(Base); - } - - CBase33& refBaseUV = m_baseVectors[dwBaseUVIndex]; - - refBaseUV.u = refBaseUV.u + inU; - refBaseUV.v = refBaseUV.v + inV; - - //no mesh is perfect - if (inU.x != 0.0f || inU.y != 0.0f || inU.z != 0.0f) - { - assert(refBaseUV.u.x != 0.0f || refBaseUV.u.y != 0.0f || refBaseUV.u.z != 0.0f); - } - // no mesh is perfect - if (inV.x != 0.0f || inV.y != 0.0f || inV.z != 0.0f) - { - assert(refBaseUV.v.x != 0.0f || refBaseUV.v.y != 0.0f || refBaseUV.v.z != 0.0f); - } - - return dwBaseUVIndex; -} - -void CTangentSpaceCalculation::AddNormal2Base(std::multimap& inMap, const uint32 indwPosNo, const uint32 indwNormNo, const Vec3& inNormal) -{ - CBaseIndex Indx; - - Indx.m_posIndex = indwPosNo; - Indx.m_normIndex = indwNormNo; - - std::multimap::iterator iFind = inMap.find(Indx); - - uint32 dwBaseNIndex; - - if (iFind != inMap.end()) - { - dwBaseNIndex = (*iFind).second; - } - else - { - CBase33 Base(Vec3(0, 0, 0), Vec3(0, 0, 0), Vec3(0, 0, 0)); - - dwBaseNIndex = m_baseVectors.size(); - inMap.insert(std::pair(Indx, dwBaseNIndex)); - m_baseVectors.push_back(Base); - } - - CBase33& refBaseN = m_baseVectors[dwBaseNIndex]; - - refBaseN.n = refBaseN.n + inNormal; -} - -void CTangentSpaceCalculation::GetBase(const uint32 indwPos, float* outU, float* outV, float* outN) -{ - CBase33& base = m_baseVectors[indwPos]; - - outU[0] = base.u.x; - outV[0] = base.v.x; - outN[0] = base.n.x; - outU[1] = base.u.y; - outV[1] = base.v.y; - outN[1] = base.n.y; - outU[2] = base.u.z; - outV[2] = base.v.z; - outN[2] = base.n.z; -} - -void CTangentSpaceCalculation::GetTriangleBaseIndices(const uint32 indwTriNo, uint32 outdwBase[3]) -{ - assert(indwTriNo < m_trianglesBaseAssigment.size()); - CTriBaseIndex& indx = m_trianglesBaseAssigment[indwTriNo]; - - for (uint32 i = 0; i < 3; i++) - { - outdwBase[i] = indx.p[i]; - } -} - -size_t CTangentSpaceCalculation::GetBaseCount() -{ - return m_baseVectors.size(); -} - -static int MikkGetNumFaces(const SMikkTSpaceContext* pContext) -{ - SMikkMesh* mikkMesh = (SMikkMesh*)pContext->m_pUserData; - return mikkMesh->mikkNumFaces; -} - -static int MikkGetNumVerticesOfFace([[maybe_unused]] const SMikkTSpaceContext* pContext, [[maybe_unused]] const int iFace) -{ - return 3; -} - -static void MikkGetPosition(const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) -{ - SMikkMesh* mikkMesh = (SMikkMesh*)pContext->m_pUserData; - const SMikkFace& face = mikkMesh->mikkFaces[iFace]; - - const Vec3& pos = mikkMesh->mikkVerts[face.vertexOffset + iVert].pos; - fvPosOut[0] = pos.x; - fvPosOut[1] = pos.y; - fvPosOut[2] = pos.z; -} - -static void MikkGetNormal(const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) -{ - SMikkMesh* mikkMesh = (SMikkMesh*)pContext->m_pUserData; - const SMikkFace& face = mikkMesh->mikkFaces[iFace]; - - const Vec3& normal = mikkMesh->mikkVerts[face.vertexOffset + iVert].norm; - fvNormOut[0] = normal.x; - fvNormOut[1] = normal.y; - fvNormOut[2] = normal.z; -} - -static void MikkGetTexCoord(const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) -{ - SMikkMesh* mikkMesh = (SMikkMesh*)pContext->m_pUserData; - const SMikkFace& face = mikkMesh->mikkFaces[iFace]; - - const Vec2& tan = mikkMesh->mikkVerts[face.vertexOffset + iVert].texc; - fvTexcOut[0] = tan.x; - fvTexcOut[1] = tan.y; -} - -static void MikkSetTSpace(const SMikkTSpaceContext* pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, [[maybe_unused]] const tbool bIsOrientationPreserving, const int iFace, const int iVert) -{ - SMikkMesh* mikkMesh = (SMikkMesh*)pContext->m_pUserData; - const SMikkFace& face = mikkMesh->mikkFaces[iFace]; - const int index = face.vertexOffset + iVert; - - mikkMesh->mikkVerts[index].tang = Vec3(fvTangent[0], fvTangent[1], fvTangent[2]); - mikkMesh->mikkVerts[index].bitang = Vec3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]); - mikkMesh->mikkVerts[index].magST.x = fMagS; - mikkMesh->mikkVerts[index].magST.y = fMagT; -} - -eCalculateTangentSpaceErrorCode CTangentSpaceCalculation::CalculateTangentSpaceMikk(const ITriangleInputProxy& proxy, string& errorMessage) -{ - const uint32 numFaces = proxy.GetTriangleCount(); - - // prepare the working mesh for mikkelsen algorithm - // when custom normals are specified, we'll use them - SMikkMesh mikkMesh; - mikkMesh.mikkNumFaces = numFaces; - mikkMesh.mikkVerts.resize(numFaces * 3); - mikkMesh.mikkFaces.resize(numFaces); - - for (uint32 f = 0; f < numFaces; ++f) - { - uint32 outdwPos[3]; - uint32 outdwNorm[3]; - uint32 outdwUV[3]; - proxy.GetTriangleIndices(f, outdwPos, outdwNorm, outdwUV); - - mikkMesh.mikkFaces[f].vertexOffset = f * 3; - mikkMesh.mikkFaces[f].nrOriginalFace = f; - - for (uint32 vId = 0; vId < 3; ++vId) - { - SMikkVertex& vert(mikkMesh.mikkVerts[mikkMesh.mikkFaces[f].vertexOffset + vId]); - - proxy.GetPos(outdwPos[vId], vert.pos); - proxy.GetNorm(f, vId, vert.norm); - proxy.GetUV(outdwUV[vId], vert.texc); - - vert.tang = Vec3(1.0f, 0.0f, 0.0f); - vert.bitang = Vec3(0.0f, 1.0f, 0.0f); - } - } - - // prepare mikkelsen interface - SMikkTSpaceInterface mikkInterface; - memset(&mikkInterface, 0, sizeof(SMikkTSpaceInterface)); - - mikkInterface.m_getNumFaces = MikkGetNumFaces; - mikkInterface.m_getNumVerticesOfFace = MikkGetNumVerticesOfFace; - mikkInterface.m_getPosition = MikkGetPosition; - mikkInterface.m_getNormal = MikkGetNormal; - mikkInterface.m_getTexCoord = MikkGetTexCoord; - mikkInterface.m_setTSpace = MikkSetTSpace; - - SMikkTSpaceContext mikkContext; - memset(&mikkContext, 0, sizeof(SMikkTSpaceContext)); - mikkContext.m_pUserData = &mikkMesh; - mikkContext.m_pInterface = &mikkInterface; - - // generate tangent basis - bool res = genTangSpaceDefault(&mikkContext) != 0; - if (!res) - { - errorMessage = "Failed to allocate memory for Mikkelsen Tangent Basis algorithm."; - return MEMORY_ALLOCATION_FAILED; - } - - m_baseVectors.clear(); - m_trianglesBaseAssigment.clear(); - m_trianglesBaseAssigment.resize(proxy.GetTriangleCount()); - - std::map uniqueBaseVectors; - std::map::const_iterator it; - - // remove tangent basis duplicates and add them to the mesh - for (int f = 0; f < mikkMesh.mikkNumFaces; ++f) - { - const SMikkFace& face = mikkMesh.mikkFaces[f]; - - CTriBaseIndex tbi; - for (int ii = 0; ii < 3; ++ii) - { - const int index = face.vertexOffset + ii; - const SMikkVertex& vert = mikkMesh.mikkVerts[index]; - - CBase33 base; - base.u = vert.tang; - base.v = vert.bitang; - - float fNorm[3]; - MikkGetNormal(&mikkContext, &fNorm[0], face.nrOriginalFace, ii); - - base.n.x = fNorm[0]; - base.n.y = fNorm[1]; - base.n.z = fNorm[2]; - - int val; - it = uniqueBaseVectors.find(base); - if (it != uniqueBaseVectors.end()) - { - val = it->second; - } - else - { - val = m_baseVectors.size(); - m_baseVectors.push_back(base); - uniqueBaseVectors[base] = val; - } - tbi.p[ii] = val; - } - m_trianglesBaseAssigment[face.nrOriginalFace] = tbi; - } - - return CALCULATE_TANGENT_SPACE_NO_ERRORS; -} diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.h b/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.h deleted file mode 100644 index a5abea7335..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/TangentSpaceCalculation.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : calculated the tangent space base vector for a given mesh -// Dependencies : none -// Documentation : "How to calculate tangent base vectors.doc" - - -#ifndef CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_TANGENTSPACECALCULATION_H -#define CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_TANGENTSPACECALCULATION_H -#pragma once - - -enum eCalculateTangentSpaceErrorCode -{ - CALCULATE_TANGENT_SPACE_NO_ERRORS, - BROKEN_TEXTURE_COORDINATES, - VERTICES_SHARING_COORDINATES, - ALL_VERTICES_ON_THE_SAME_VECTOR, - MEMORY_ALLOCATION_FAILED -}; - -class ITriangleInputProxy -{ -public: - virtual ~ITriangleInputProxy(){} - - virtual uint32 GetTriangleCount() const = 0; - virtual void GetTriangleIndices(const uint32 indwTriNo, uint32 outdwPos[3], uint32 outdwNorm[3], uint32 outdwUV[3]) const = 0; - virtual void GetPos(const uint32 indwPos, Vec3& outfPos) const = 0; - virtual void GetUV(const uint32 indwPos, Vec2& outfUV) const = 0; - virtual void GetNorm(const uint32 indwTriNo, const uint32 indwVertNo, Vec3& outfNorm) const = 0; -}; - -class CTangentSpaceCalculation -{ -public: - //! /param inInput - the normals are only used as smoothing input - we calculate the normals ourself - eCalculateTangentSpaceErrorCode CalculateTangentSpace(const ITriangleInputProxy& inInput, const bool bUseCustomNormals, string& errorMessage); - - size_t GetBaseCount(); - void GetTriangleBaseIndices(const uint32 indwTriNo, uint32 outdwBase[3]); - - //! returns a orthogonal base (perpendicular and normalized) - void GetBase(const uint32 indwPos, float* outU, float* outV, float* outN); - -private: - - struct CBase33 - { - CBase33(); - CBase33(const Vec3& Uval, const Vec3& Vval, const Vec3& Nval); - - Vec3 u; - Vec3 v; - Vec3 n; // part of the tangent base but can be used also as vertex normal - }; - - struct CVec3PredicateLess - { - bool operator() (const Vec3& first, const Vec3& second) const; - }; - - struct CBase33PredicateLess - { - bool operator() (const CBase33& first, const CBase33& second) const; - }; - - struct CBaseIndex - { - // position index in the positions stream - uint32 m_posIndex; - // normal index in the vertex normals stream - uint32 m_normIndex; - }; - - struct CBaseIndexOrder - { - bool operator() (const CBaseIndex& a, const CBaseIndex& b) const; - }; - - struct CTriBaseIndex - { - uint32 p[3]; //!< index in m_BaseVectors - }; - - // [dwTriangleCount] - std::vector m_trianglesBaseAssigment; - // [0..] generated output data - std::vector m_baseVectors; - - eCalculateTangentSpaceErrorCode CalculateTangentSpaceMikk(const ITriangleInputProxy& inInput, string& errorMessage); - - CBase33& GetBase(std::multimap& inMap, const uint32 indwPosNo, const uint32 indwNormNo); - uint32 AddUV2Base(std::multimap& inMap, const uint32 indwPosNo, const uint32 indwNormNo, const Vec3& inU, const Vec3& inV, const Vec3& inNormN); - void AddNormal2Base(std::multimap& inMap, const uint32 indwPosNo, const uint32 indwNormNo, const Vec3& inNormal); - Vec3 Rotate(const Vec3& vFrom, const Vec3& vTo, const Vec3& vInput); - void DebugMesh(const ITriangleInputProxy& inInput) const; - float CalcAngleBetween(const Vec3& invA, const Vec3& invB); -}; - -#endif // CRYINCLUDE_CRY3DENGINE_MESHCOMPILER_TANGENTSPACECALCULATION_H diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.cpp b/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.cpp deleted file mode 100644 index d03d9c7c23..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - - -#include - -#include "VertexCacheOptimizer.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define VERTEXCACHEOPTIMIZER_CPP_SECTION_1 1 -#define VERTEXCACHEOPTIMIZER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION VERTEXCACHEOPTIMIZER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(VertexCacheOptimizer_cpp) -#endif - -namespace vcache -{ - bool VertexCacheOptimizer::ReorderIndicesInPlace([[maybe_unused]] void* pIndices, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] int indexSize) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION VERTEXCACHEOPTIMIZER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(VertexCacheOptimizer_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED - #else - return true; - #endif - } -} diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.h b/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.h deleted file mode 100644 index 70a35f96eb..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/VertexCacheOptimizer.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace vcache -{ - class VertexCacheOptimizer - { - public: - static bool ReorderIndicesInPlace(void* pIndices, uint32 numIndices, int indexSize); - - VertexCacheOptimizer(const VertexCacheOptimizer& rhs) = delete; - const VertexCacheOptimizer& operator=(VertexCacheOptimizer& rhs) = delete; - }; -} diff --git a/Code/CryEngine/Cry3DEngine/MeshCompiler/meshcompiler_files.cmake b/Code/CryEngine/Cry3DEngine/MeshCompiler/meshcompiler_files.cmake deleted file mode 100644 index 31f7369c88..0000000000 --- a/Code/CryEngine/Cry3DEngine/MeshCompiler/meshcompiler_files.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ForsythFaceReorderer.cpp - MeshCompiler.cpp - TangentSpaceCalculation.cpp - ForsythFaceReorderer.h - MeshCompiler.h - TangentSpaceCalculation.h - PVRTTriStrip/PVRTTriStrip.h - PVRTTriStrip/PVRTTriStrip.cpp - VertexCacheOptimizer.cpp - VertexCacheOptimizer.h -) diff --git a/Code/CryEngine/Cry3DEngine/ObjMan.cpp b/Code/CryEngine/Cry3DEngine/ObjMan.cpp deleted file mode 100644 index a073f00859..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjMan.cpp +++ /dev/null @@ -1,1377 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Loading trees, buildings, register/unregister entities for rendering - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "CullBuffer.h" -#include "3dEngine.h" -#include "IndexedMesh.h" -#include "ObjectsTree.h" -#include -#include "DecalRenderNode.h" -#include -#include - -#include - -#include - -#define BRUSH_LIST_FILE "brushlist.txt" -#define CGF_LEVEL_CACHE_PAK "cgf.pak" - -namespace BoneNames -{ - const char* Cloth = "cloth"; -} - -////////////////////////////////////////////////////////////////////////// -IStatObj* CObjManager::GetStaticObjectByTypeID(int nTypeID, int nSID) -{ - assert(nSID >= 0 && nSID < m_lstStaticTypes.Count()); - - if (nTypeID >= 0 && nTypeID < m_lstStaticTypes[nSID].Count()) - { - return m_lstStaticTypes[nSID][nTypeID].pStatObj; - } - - return 0; -} - -IStatObj* CObjManager::FindStaticObjectByFilename(const char* filename) -{ - string lowerFileName(filename); - return stl::find_in_map(m_nameToObjectMap, CONST_TEMP_STRING(lowerFileName.MakeLower()), NULL); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::UnloadObjects(bool bDeleteAll) -{ - - CleanStreamingData(); - - m_pRMBox = 0; - - m_decalsToPrecreate.resize(0); - - // Clear all objects that are in the garbage collector. - ClearStatObjGarbage(); - - stl::free_container(m_checkForGarbage); - m_bGarbageCollectionEnabled = false; - - if (bDeleteAll) - { - { - AZStd::unique_lock loadLock(m_loadMutex); - - m_lockedObjects.clear(); // Lock/Unlock resources will not work with this. - - // Release default stat obj. - m_pDefaultCGF = 0; - - m_nameToObjectMap.clear(); - m_lstLoadedObjects.clear(); - } - -#if !defined(_RELEASE) - int nNumLeaks = 0; -#endif - std::vector garbage; - for (CStatObj* pStatObj = CStatObj::get_intrusive_list_root(); pStatObj; pStatObj = pStatObj->m_next_intrusive) - { - garbage.push_back(pStatObj); - -#if !defined(_RELEASE) - if (!pStatObj->IsDefaultObject()) - { - nNumLeaks++; - Warning("StatObj not deleted: %s (%s) RefCount: %d", pStatObj->m_szFileName.c_str(), pStatObj->m_szGeomName.c_str(), pStatObj->m_nUsers); - } -#endif //_RELEASE - } - -#ifndef _RELEASE - // deleting leaked objects - if (nNumLeaks > 0) - { - Warning("CObjManager::CheckObjectLeaks: %d object(s) found in memory", nNumLeaks); - } -#endif //_RELEASE - - for (int i = 0, num = (int)garbage.size(); i < num; i++) - { - CStatObj* pStatObj = garbage[i]; - pStatObj->ShutDown(); - } - for (int i = 0, num = (int)garbage.size(); i < num; i++) - { - CStatObj* pStatObj = garbage[i]; - delete pStatObj; - } - -#ifdef POOL_STATOBJ_ALLOCS - assert(m_statObjPool->GetTotalMemory().nUsed == 0); -#endif - } - m_bGarbageCollectionEnabled = true; - -#ifdef POOL_STATOBJ_ALLOCS - m_statObjPool->FreeMemoryIfEmpty(); -#endif - - //If this collection is not cleared on unload then character materials will - //leak and most likely crash the engine across level loads. - stl::free_container(m_collectedMaterials); - stl::free_container(m_decalsToPrecreate); - stl::free_container(m_tmpAreas0); - stl::free_container(m_tmpAreas1); - for (int nSID = 0; nSID < m_lstStaticTypes.Count(); nSID++) - { - m_lstStaticTypes[nSID].Free(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::CleanStreamingData() -{ - stl::free_container(m_arrStreamingNodeStack); - - stl::free_container(m_arrStreamableToRelease); - stl::free_container(m_arrStreamableToLoad); - stl::free_container(m_arrStreamableToDelete); -} - -////////////////////////////////////////////////////////////////////////// -// class for asyncronous preloading of level CGF's -////////////////////////////////////////////////////////////////////////// -struct CLevelStatObjLoader - : public IStreamCallback - , public Cry3DEngineBase -{ - int m_nTasksNum; - - CLevelStatObjLoader() - { - m_nTasksNum = 0; - } - - void StartStreaming(const char* pFileName) - { - m_nTasksNum++; - - // request the file - StreamReadParams params; - params.dwUserData = 0; - params.nSize = 0; - params.pBuffer = NULL; - params.nLoadTime = 0; - params.nMaxLoadTime = 0; - params.ePriority = estpUrgent; - GetSystem()->GetStreamEngine()->StartRead(eStreamTaskTypeGeometry, pFileName, this, ¶ms); - } - - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError) - { - if (!nError) - { - string szName = pStream->GetName(); - // remove game folder from path - const char* szInGameName = strstr(szName, "\\"); - // load CGF from memory - GetObjManager()->LoadStatObjUnsafeManualRef(szInGameName + 1, NULL, NULL, true, 0, pStream->GetBuffer(), pStream->GetBytesRead()); - } - - m_nTasksNum--; - } -}; - -////////////////////////////////////////////////////////////////////////// -// Preload in efficient way all CGF's used in level -////////////////////////////////////////////////////////////////////////// -void CObjManager::PreloadLevelObjects() -{ - LOADING_TIME_PROFILE_SECTION; - - // Starting a new level, so make sure the round ids are ahead of what they were in the last level - m_nUpdateStreamingPrioriryRoundId += 8; - m_nUpdateStreamingPrioriryRoundIdFast += 8; - - PrintMessage("Starting loading level CGF's ..."); - INDENT_LOG_DURING_SCOPE(); - - float fStartTime = GetCurAsyncTimeSec(); - - bool bCgfCacheExist = false; - if (GetCVars()->e_StreamCgf != 0) - { - // Only when streaming enable use no-mesh cgf pak. - //bCgfCacheExist = GetISystem()->GetIResourceManager()->LoadLevelCachePak( CGF_LEVEL_CACHE_PAK,"" ); - } - auto pResList = GetISystem()->GetIResourceManager()->GetLevelResourceList(); - - // Construct streamer object - CLevelStatObjLoader cgfStreamer; - - CryPathString cgfFilename; - int nCgfCounter = 0; - int nInLevelCacheCount = 0; - - bool bVerboseLogging = GetCVars()->e_StatObjPreload > 1; - - - ////////////////////////////////////////////////////////////////////////// - // Enumerate all .CGF inside level from the "brushlist.txt" file. - { - string brushListFilename = Get3DEngine()->GetLevelFilePath(BRUSH_LIST_FILE); - CCryFile file; - if (file.Open(brushListFilename.c_str(), "rb") && file.GetLength() > 0) - { - int nFileLength = file.GetLength(); - char* buf = new char[nFileLength + 1]; - buf[nFileLength] = 0; // Null terminate - file.ReadRaw(buf, nFileLength); - - // Parse file, every line in a file represents a resource filename. - char seps[] = "\r\n"; - char *next_token = nullptr; - char* token = azstrtok(buf, 0, seps, &next_token); - while (token != NULL) - { - int nAliasLen = sizeof("%level%") - 1; - if (strncmp(token, "%level%", nAliasLen) == 0) - { - cgfFilename = Get3DEngine()->GetLevelFilePath(token + nAliasLen); - } - else - { - cgfFilename = token; - } - - if (bVerboseLogging) - { - CryLog("%s", cgfFilename.c_str()); - } - // Do not use streaming for the Brushes from level.pak. - GetObjManager()->LoadStatObjUnsafeManualRef(cgfFilename.c_str(), NULL, 0, false, 0); - //cgfStreamer.StartStreaming(cgfFilename.c_str()); - nCgfCounter++; - - token = azstrtok(NULL, 0, seps, &next_token); - - //This loop can take a few seconds, so we should refresh the loading screen and call the loading tick functions to ensure that no big gaps in coverage occur. - SYNCHRONOUS_LOADING_TICK(); - } - delete []buf; - } - } - ////////////////////////////////////////////////////////////////////////// - - // Request objects loading from Streaming System. - if (pResList) - { - if (const char* pCgfName = pResList->GetFirst()) - { - while (pCgfName) - { - if (strstr(pCgfName, ".cgf")) - { - const char* sLodName = strstr(pCgfName, "_lod"); - if (sLodName && (sLodName[4] >= '0' && sLodName[4] <= '9')) - { - // Ignore Lod files. - pCgfName = pResList->GetNext(); - continue; - } - - cgfFilename = pCgfName; - - if (bVerboseLogging) - { - CryLog("%s", cgfFilename.c_str()); - } - IStatObj* pStatObj = GetObjManager()->LoadStatObjUnsafeManualRef(cgfFilename.c_str(), NULL, 0, true, 0); - if (pStatObj) - { - if (pStatObj->IsMeshStrippedCGF()) - { - nInLevelCacheCount++; - } - } - // cgfStreamer.StartStreaming(cgfFilename.c_str()); - nCgfCounter++; - - // This loop can take a few seconds, so we should refresh the loading screen and call the loading tick functions to - // ensure that no big gaps in coverage occur. - SYNCHRONOUS_LOADING_TICK(); - } - - pCgfName = pResList->GetNext(); - } - } - } - - // PrintMessage("Finished requesting level CGF's: %d objects in %.1f sec", nCgfCounter, GetCurAsyncTimeSec()-fStartTime); - - // Continue updating streaming system until all CGF's are loaded - if (cgfStreamer.m_nTasksNum > 0) - { - LOADING_TIME_PROFILE_SECTION_NAMED("CObjManager::PreloadLevelObjects_StreamEngine_Update"); - GetSystem()->GetStreamEngine()->UpdateAndWait(); - } - - if (bCgfCacheExist) - { - //GetISystem()->GetIResourceManager()->UnloadLevelCachePak( CGF_LEVEL_CACHE_PAK ); - } - - float dt = GetCurAsyncTimeSec() - fStartTime; - PrintMessage("Finished loading level CGF's: %d objects loaded (%d from LevelCache) in %.1f sec", nCgfCounter, nInLevelCacheCount, dt); -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Create / delete object -////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template -T CObjManager::LoadStatObjInternal(const char* filename, - const char* _szGeomName, - IStatObj::SSubObject** ppSubObject, - bool bUseStreaming, - unsigned long nLoadingFlags, - const void* pData, - int nDataSize, - [[maybe_unused]] const char* szBlockName) -{ - LoadDefaultCGF(filename, nLoadingFlags); - - LOADING_TIME_PROFILE_SECTION; - - if (ppSubObject) - { - *ppSubObject = NULL; - } - - AZStd::unique_lock loadLock(m_loadMutex); - - if (!strcmp(filename, "NOFILE")) - { // make empty object to be filled from outside - CStatObj* pObject = new CStatObj(); - m_lstLoadedObjects.insert(pObject); - - return pObject; - } - - // Normalize file name - // Remap %level% alias if needed and unify filename - char normalizedFilename[_MAX_PATH]; - NormalizeLevelName(filename, normalizedFilename); - - bool bForceBreakable = strstr(normalizedFilename, "break") != 0; - if (_szGeomName && !strcmp(_szGeomName, "#ForceBreakable")) - { - bForceBreakable = true; - _szGeomName = 0; - } - - // Try to find already loaded object - IStatObj* pObject = 0; - - int flagCloth = 0; - if (_szGeomName && !strcmp(_szGeomName, BoneNames::Cloth)) - { - _szGeomName = 0; - flagCloth = STATIC_OBJECT_DYNAMIC | STATIC_OBJECT_CLONE; - } - else - { - // This branch needs to be handled carefully to avoid returning an object that is in the process of being deleted by ClearStatObjGarbage on another thread - // It is important that ClearStatObjGarbage is not run during this time (done via m_loadMutex) - - AZStd::string lowerFileName(normalizedFilename); - int(* toLowerFunc)(int) = std::tolower; //Needed to help the compiler figure out the right tolower to use on android - AZStd::transform(lowerFileName.begin(), lowerFileName.end(), lowerFileName.begin(), toLowerFunc); - - pObject = stl::find_in_map(m_nameToObjectMap, CONST_TEMP_STRING(lowerFileName.c_str()), NULL); - if (pObject) - { - assert(!pData); - - return (T)LoadFromCacheNoRef(pObject, bUseStreaming, nLoadingFlags, _szGeomName, ppSubObject); - } - } - - // Load new CGF - return LoadNewCGF(pObject, flagCloth, bUseStreaming, bForceBreakable, nLoadingFlags, normalizedFilename, pData, nDataSize, filename, _szGeomName, ppSubObject); -} - -IStatObj* CObjManager::LoadStatObjUnsafeManualRef(const char* filename, - const char* _szGeomName, - IStatObj::SSubObject** ppSubObject, - bool bUseStreaming, - unsigned long nLoadingFlags, - const void* pData, - int nDataSize, - const char* szBlockName) -{ - return LoadStatObjInternal(filename, _szGeomName, ppSubObject, bUseStreaming, nLoadingFlags, pData, nDataSize, szBlockName); -} - -_smart_ptr CObjManager::LoadStatObjAutoRef(const char* filename, - const char* _szGeomName, - IStatObj::SSubObject** ppSubObject, - bool bUseStreaming, - unsigned long nLoadingFlags, - const void* pData, - int nDataSize, - const char* szBlockName) -{ - return LoadStatObjInternal<_smart_ptr >(filename, _szGeomName, ppSubObject, bUseStreaming, nLoadingFlags, pData, nDataSize, szBlockName); -} - -template -void CObjManager::NormalizeLevelName(const char* filename, char(&normalizedFilename)[SIZE_IN_CHARS]) -{ - const int nAliasNameLen = sizeof("%level%") - 1; - - if (strncmp(filename, "%level%", nAliasNameLen) == 0) - { - cry_strcpy(normalizedFilename, Get3DEngine()->GetLevelFilePath(filename + nAliasNameLen)); - } - else - { - cry_strcpy(normalizedFilename, filename); - } - - PREFAST_SUPPRESS_WARNING(6054) // normalizedFilename is null terminated - std::replace(normalizedFilename, normalizedFilename + strlen(normalizedFilename), '\\', '/'); // To Unix Path -} - -void CObjManager::LoadDefaultCGF(const char* filename, unsigned long nLoadingFlags) -{ - string fixedFileName(filename); - fixedFileName = PathUtil::ToUnixPath(fixedFileName); - - if (!m_pDefaultCGF && azstricmp(fixedFileName.c_str(), DEFAULT_CGF_NAME) != 0) - { - // Load default object if not yet loaded. - const char* sDefaulObjFilename = DEFAULT_CGF_NAME; - // prepare default object - m_pDefaultCGF = LoadStatObjUnsafeManualRef(sDefaulObjFilename, NULL, NULL, false, nLoadingFlags); - if (!m_pDefaultCGF) - { - Error("CObjManager::LoadStatObj: Default object not found (%s)", sDefaulObjFilename); - m_pDefaultCGF = new CStatObj(); - } - m_pDefaultCGF->SetDefaultObject(true); - } -} - -IStatObj* CObjManager::LoadNewCGF(IStatObj* pObject, int flagCloth, bool bUseStreaming, bool bForceBreakable, unsigned long nLoadingFlags, const char* normalizedFilename, const void* pData, int nDataSize, const char* originalFilename, const char* geomName, IStatObj::SSubObject** ppSubObject) -{ - pObject = new CStatObj(); - pObject->SetFlags(pObject->GetFlags() | flagCloth); - - bUseStreaming &= (GetCVars()->e_StreamCgf != 0); - - if (bUseStreaming) - { - pObject->SetCanUnload(true); - } - if (bForceBreakable) - { - nLoadingFlags |= IStatObj::ELoadingFlagsForceBreakable; - } - - if (!pObject->LoadCGF(normalizedFilename, strstr(normalizedFilename, "_lod") != NULL, nLoadingFlags, pData, nDataSize)) - { - Error("Failed to load cgf: %s", originalFilename); - // object not found - // if geom name is specified - just return 0 - if (geomName && geomName[0]) - { - delete pObject; - return nullptr; - } - - // make unique default CGF for every case of missing CGF, this will make export process more reliable and help finding missing CGF's in pure game - /* pObject->m_bCanUnload = false; - if (m_bEditor && pObject->LoadCGF( DEFAULT_CGF_NAME, false, nLoadingFlags, pData, nDataSize )) - { - pObject->m_szFileName = sFilename; - pObject->m_bDefaultObject = true; - } - else*/ - { - delete pObject; - return m_pDefaultCGF; - } - } - - // now try to load lods - if (!pObject->AreLodsLoaded()) - { - pObject->LoadLowLODs(bUseStreaming, nLoadingFlags); - } - - if (!pObject->IsUnloadable()) - { // even if streaming is disabled we register object for potential streaming (streaming system will never unload it) - pObject->DisableStreaming(); - } - - // sub meshes merging - pObject->TryMergeSubObjects(false); - - m_lstLoadedObjects.insert(pObject); - m_nameToObjectMap[pObject->GetFileName().MakeLower()] = pObject; - - if (geomName && geomName[0]) - { - // Return SubObject. - CStatObj::SSubObject* pSubObject = pObject->FindSubObject(geomName); - if (!pSubObject || !pSubObject->pStatObj) - { - return 0; - } - if (pSubObject->pStatObj) - { - if (ppSubObject) - { - *ppSubObject = pSubObject; - } - return (CStatObj*)pSubObject->pStatObj; - } - } - -#if AZ_LOADSCREENCOMPONENT_ENABLED - if (GetISystem() && GetISystem()->GetGlobalEnvironment() && GetISystem()->GetGlobalEnvironment()->mMainThreadId == CryGetCurrentThreadId()) - { - EBUS_EVENT(LoadScreenBus, UpdateAndRender); - } -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - return pObject; -} - -IStatObj* CObjManager::LoadFromCacheNoRef(IStatObj* pObject, bool bUseStreaming, unsigned long nLoadingFlags, const char* geomName, IStatObj::SSubObject** ppSubObject) -{ - if (!bUseStreaming && pObject->IsUnloadable()) - { - pObject->DisableStreaming(); - } - - if (!pObject->AreLodsLoaded()) - { - pObject->LoadLowLODs(bUseStreaming, nLoadingFlags); - } - - if (geomName && geomName[0]) - { - // Return SubObject. - IStatObj::SSubObject* pSubObject = pObject->FindSubObject(geomName); - if (!pSubObject || !pSubObject->pStatObj) - { - return nullptr; - } - - if (ppSubObject) - { - *ppSubObject = pSubObject; - } - - // UnregisterForGarbage needs to be called on pObject before returning - UnregisterForGarbage(pObject); - - return (CStatObj*)pSubObject->pStatObj; - } - - UnregisterForGarbage(pObject); - - return pObject; -} - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::InternalDeleteObject(IStatObj* pObject) -{ - assert(pObject); - - AZStd::lock_guard loadLock(m_loadMutex); - - if (!m_bLockCGFResources && !IsResourceLocked(pObject->GetFileName())) - { - LoadedObjects::iterator it = m_lstLoadedObjects.find(pObject); - if (it != m_lstLoadedObjects.end()) - { - m_lstLoadedObjects.erase(it); - m_nameToObjectMap.erase(pObject->GetFileName().MakeLower()); - } - else - { - //Warning( "CObjManager::ReleaseObject called on object not loaded in ObjectManager %s",pObject->m_szFileName.c_str() ); - //return false; - } - - delete pObject; - return true; - } - else if (m_bLockCGFResources) - { - // Put them to locked stat obj list. - stl::push_back_unique(m_lockedObjects, pObject); - } - - return false; -} - -IStatObj* CObjManager::AllocateStatObj() -{ -#ifdef POOL_STATOBJ_ALLOCS - return (IStatObj*)m_statObjPool->Allocate(); -#else - return (IStatObj*)malloc(sizeof(CStatObj)); -#endif -} - -void CObjManager::FreeStatObj(IStatObj* pObj) -{ -#ifdef POOL_STATOBJ_ALLOCS - m_statObjPool->Deallocate(pObj); -#else - free(pObj); -#endif -} - -CObjManager::CObjManager() - : m_pDefaultCGF (NULL) - , m_decalsToPrecreate() - , m_bNeedProcessObjectsStreaming_Finish(false) - , m_CullThread() - , m_fGSMMaxDistance(0) - , m_bLockCGFResources(false) - , m_sunAnimIndex(0) - , m_sunAnimSpeed(0) - , m_sunAnimPhase(0) - , m_nNextPrecachePointId(0) - , m_bCameraPrecacheOverridden(false) - , m_fILMul(1.f) - , m_fSSAOAmount(1.f) - , m_fSSAOContrast(1.f) - , m_pRMBox(nullptr) - , m_bGarbageCollectionEnabled(true) -{ -#ifdef POOL_STATOBJ_ALLOCS - m_statObjPool = new stl::PoolAllocator(stl::FHeap().PageSize(64)); // 20Kb per page -#endif - - m_vStreamPreCachePointDefs.Add(SObjManPrecachePoint()); - m_vStreamPreCacheCameras.Add(SObjManPrecacheCamera()); - - m_pObjManager = this; - - m_vSunColor.Set(0, 0, 0); - m_rainParams.nUpdateFrameID = -1; - m_rainParams.fAmount = 0.f; - m_rainParams.fRadius = 1.f; - m_rainParams.vWorldPos.Set(0, 0, 0); - m_rainParams.vColor.Set(1, 1, 1); - m_rainParams.fFakeGlossiness = 0.5f; - m_rainParams.fFakeReflectionAmount = 1.5f; - m_rainParams.fDiffuseDarkening = 0.5f; - m_rainParams.fRainDropsAmount = 0.5f; - m_rainParams.fRainDropsSpeed = 1.f; - m_rainParams.fRainDropsLighting = 1.f; - m_rainParams.fMistAmount = 3.f; - m_rainParams.fMistHeight = 8.f; - m_rainParams.fPuddlesAmount = 1.5f; - m_rainParams.fPuddlesMaskAmount = 1.0f; - m_rainParams.fPuddlesRippleAmount = 2.0f; - m_rainParams.fSplashesAmount = 1.3f; - m_rainParams.bIgnoreVisareas = false; - m_rainParams.bDisableOcclusion = false; - - -#ifdef SUPP_HWOBJ_OCCL - if (GetRenderer()->GetFeatures() & RFT_OCCLUSIONTEST) - { - m_pShaderOcclusionQuery = GetRenderer()->EF_LoadShader("OcclusionTest"); - } - else - { - m_pShaderOcclusionQuery = 0; - } -#endif - - m_decalsToPrecreate.reserve(128); - - // init queue for check occlusion - m_CheckOcclusionQueue.Init(GetCVars()->e_CheckOcclusionQueueSize); - m_CheckOcclusionOutputQueue.Init(GetCVars()->e_CheckOcclusionOutputQueueSize); - - StatInstGroupEventBus::Handler::BusConnect(); -} - -// make unit box for occlusion test -void CObjManager::MakeUnitCube() -{ - if (m_pRMBox) - { - return; - } - - SVF_P3F_C4B_T2F arrVerts[8]; - arrVerts[0].xyz = Vec3(0, 0, 0); - arrVerts[1].xyz = Vec3(1, 0, 0); - arrVerts[2].xyz = Vec3(0, 0, 1); - arrVerts[3].xyz = Vec3(1, 0, 1); - arrVerts[4].xyz = Vec3(0, 1, 0); - arrVerts[5].xyz = Vec3(1, 1, 0); - arrVerts[6].xyz = Vec3(0, 1, 1); - arrVerts[7].xyz = Vec3(1, 1, 1); - - // 6-------7 - // / /| - // 2-------3 | - // | | | - // | 4 | 5 - // | |/ - // 0-------1 - - static const vtx_idx arrIndices[] = - { - // front + back - 1, 0, 2, - 2, 3, 1, - 5, 6, 4, - 5, 7, 6, - // left + right - 0, 6, 2, - 0, 4, 6, - 1, 3, 7, - 1, 7, 5, - // top + bottom - 3, 2, 6, - 6, 7, 3, - 1, 4, 0, - 1, 5, 4 - }; - - m_pRMBox = GetRenderer()->CreateRenderMeshInitialized( - arrVerts, - sizeof(arrVerts) / sizeof(arrVerts[0]), - eVF_P3F_C4B_T2F, - arrIndices, - sizeof(arrIndices) / sizeof(arrIndices[0]), - prtTriangleList, - "OcclusionQueryCube", "OcclusionQueryCube", - eRMT_Static); - - m_pRMBox->SetChunk(NULL, 0, sizeof(arrVerts) / sizeof(arrVerts[0]), 0, sizeof(arrIndices) / sizeof(arrIndices[0]), 1.0f, eVF_P3F_C4B_T2F, 0); - - m_bGarbageCollectionEnabled = true; -} - -CObjManager::~CObjManager() -{ - StatInstGroupEventBus::Handler::BusDisconnect(); - - // free default object - m_pDefaultCGF = 0; - - // free brushes - /* assert(!m_lstBrushContainer.Count()); - for(int i=0; iGetEntityStatObj()) - ReleaseObject((CStatObj*)m_lstBrushContainer[i]->GetEntityStatObj()); - delete m_lstBrushContainer[i]; - } - m_lstBrushContainer.Reset(); - */ - UnloadObjects(true); -#ifdef POOL_STATOBJ_ALLOCS - delete m_statObjPool; -#endif -} - - -// mostly xy size -float CObjManager::GetXYRadius(int type, int nSID) -{ - assert(nSID >= 0 && nSID < m_lstStaticTypes.Count()); - - if ((m_lstStaticTypes[nSID].Count() <= type || !m_lstStaticTypes[nSID][type].pStatObj)) - { - return 0.0f; - } - - Vec3 vSize = m_lstStaticTypes[nSID][type].pStatObj->GetBoxMax() - m_lstStaticTypes[nSID][type].pStatObj->GetBoxMin(); - vSize.z *= 0.5f; - - float fXYRadius = vSize.GetLength() * 0.5f; - - return fXYRadius; -} - -bool CObjManager::GetStaticObjectBBox(int nType, Vec3& vBoxMin, Vec3& vBoxMax, int nSID) -{ - assert(nSID >= 0 && nSID < m_lstStaticTypes.Count()); - - if ((m_lstStaticTypes[nSID].Count() <= nType || !m_lstStaticTypes[nSID][nType].pStatObj)) - { - return false; - } - - vBoxMin = m_lstStaticTypes[nSID][nType].pStatObj->GetBoxMin(); - vBoxMax = m_lstStaticTypes[nSID][nType].pStatObj->GetBoxMax(); - - return true; -} - - -void CObjManager::AddDecalToRenderer(float fDistance, - _smart_ptr pMat, - const uint8 sortPrio, - Vec3 right, - Vec3 up, - const UCol& ucResCol, - [[maybe_unused]] const uint8 uBlendType, - const Vec3& vAmbientColor, - Vec3 vPos, - const int nAfterWater, - const SRenderingPassInfo& passInfo, - const SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - // repeated objects are free imedeately in renderer - CRenderObject* pOb(GetIdentityCRenderObject(passInfo.ThreadID())); - if (!pOb) - { - return; - } - - // prepare render object - pOb->m_fDistance = fDistance; - pOb->m_nTextureID = -1; - pOb->m_fAlpha = (float)ucResCol.bcolor[3] / 255.f; - pOb->m_II.m_AmbColor = vAmbientColor; - pOb->m_fSort = 0; - pOb->m_ObjFlags |= FOB_DECAL; - pOb->m_nSort = sortPrio; - - SVF_P3F_C4B_T2F pVerts[4]; - uint16 pIndices[6]; - - // TODO: determine whether this is a decal on opaque or transparent geometry - // (put it in the respective renderlist for correct shadowing) - // fill general vertex data - pVerts[0].xyz = (-right - up) + vPos; - pVerts[0].st = Vec2(0, 1); - pVerts[0].color.dcolor = ~0; - - pVerts[1].xyz = (right - up) + vPos; - pVerts[1].st = Vec2(1, 1); - pVerts[1].color.dcolor = ~0; - - pVerts[2].xyz = (right + up) + vPos; - pVerts[2].st = Vec2(1, 0); - pVerts[2].color.dcolor = ~0; - - pVerts[3].xyz = (-right + up) + vPos; - pVerts[3].st = Vec2(0, 0); - pVerts[3].color.dcolor = ~0; - - // prepare tangent space (tangent, bitangent) and fill it in - Vec3 rightUnit(right.GetNormalized()); - Vec3 upUnit(up.GetNormalized()); - - SPipTangents pTangents[4]; - - pTangents[0] = SPipTangents(rightUnit, -upUnit, -1); - pTangents[1] = pTangents[0]; - pTangents[2] = pTangents[0]; - pTangents[3] = pTangents[0]; - - // fill decals topology (two triangles) - pIndices[0] = 0; - pIndices[1] = 1; - pIndices[2] = 2; - - pIndices[3] = 0; - pIndices[4] = 2; - pIndices[5] = 3; - - GetRenderer()->EF_AddPolygonToScene(pMat->GetShaderItem(), 4, pVerts, pTangents, pOb, passInfo, pIndices, 6, nAfterWater, rendItemSorter); -} - - -void CObjManager::GetMemoryUsage(class ICrySizer* pSizer) const -{ - { - SIZER_COMPONENT_NAME(pSizer, "Self"); - pSizer->AddObject(this, sizeof(*this)); - } - - { - SIZER_COMPONENT_NAME(pSizer, "StaticTypes"); - pSizer->AddObject(m_lstStaticTypes); - } - - { - SIZER_COMPONENT_NAME(pSizer, "CMesh"); - CIndexedMesh* pMesh = CIndexedMesh::get_intrusive_list_root(); - while (pMesh) - { - pSizer->AddObject(pMesh); - pMesh = pMesh->m_next_intrusive; - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "StatObj"); - for (CStatObj* pStatObj = CStatObj::get_intrusive_list_root(); pStatObj; pStatObj = pStatObj->m_next_intrusive) - { - pStatObj->GetMemoryUsage(pSizer); - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "EmptyNodes"); - pSizer->AddObject(COctreeNode::m_arrEmptyNodes); - } -} - -// retrieves the bandwidth calculations for the audio streaming -void CObjManager::GetBandwidthStats([[maybe_unused]] float* fBandwidthRequested) -{ -#if !defined (_RELEASE) - if (fBandwidthRequested && CStatObj::s_fStreamingTime != 0.0f) - { - *fBandwidthRequested = (CStatObj::s_nBandwidth / CStatObj::s_fStreamingTime) / 1024.0f; - } -#endif -} - -void CObjManager::ReregisterEntitiesInArea(Vec3 vBoxMin, Vec3 vBoxMax) -{ - PodArray lstEntitiesInArea; - - AABB vBoxAABB(vBoxMin, vBoxMax); - - Get3DEngine()->MoveObjectsIntoListGlobal(&lstEntitiesInArea, &vBoxAABB, true); - - if (GetVisAreaManager()) - { - GetVisAreaManager()->MoveObjectsIntoList(&lstEntitiesInArea, vBoxAABB, true); - } - - int nChanged = 0; - for (int i = 0; i < lstEntitiesInArea.Count(); i++) - { - IVisArea* pPrevArea = lstEntitiesInArea[i].pNode->GetEntityVisArea(); - Get3DEngine()->UnRegisterEntityDirect(lstEntitiesInArea[i].pNode); - - if (lstEntitiesInArea[i].pNode->GetRenderNodeType() == eERType_Decal) - { - ((CDecalRenderNode*)lstEntitiesInArea[i].pNode)->RequestUpdate(); - } - - Get3DEngine()->RegisterEntity(lstEntitiesInArea[i].pNode); - if (pPrevArea != lstEntitiesInArea[i].pNode->GetEntityVisArea()) - { - nChanged++; - } - } -} - - -void CObjManager::FreeNotUsedCGFs() -{ - AZStd::vector garbageList; - - { - AZStd::lock_guard loadLock(m_loadMutex); - - m_lockedObjects.clear(); - - if (!m_bLockCGFResources) - { - //Timur, You MUST use next here, or with erase you invalidating - LoadedObjects::iterator next; - for (LoadedObjects::iterator it = m_lstLoadedObjects.begin(); it != m_lstLoadedObjects.end(); it = next) - { - next = it; - ++next; - CStatObj* p = (CStatObj*)(*it); - if (p->m_nUsers <= 0) - { - // Add to the list and run CheckForGarbage afterwards so we don't have to hold two locks at once - garbageList.push_back(p); - } - } - } - } - - { - AZStd::lock_guard lock(m_garbageMutex); - for (auto* object : garbageList) - { - CheckForGarbage(object); - } - } - - ClearStatObjGarbage(); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount) -{ - AZStd::lock_guard loadLock(m_loadMutex); - - if (!pObjectsArray) - { - nCount = m_lstLoadedObjects.size(); - return; - } - - CObjManager::LoadedObjects::iterator it = m_lstLoadedObjects.begin(); - for (int i = 0; i < nCount && it != m_lstLoadedObjects.end(); i++, it++) - { - pObjectsArray[i] = *it; - } -} - -void StatInstGroup::Update([[maybe_unused]] CVars* pCVars, [[maybe_unused]] int nGeomDetailScreenRes) -{ - m_dwRndFlags = 0; - - static ICVar* pObjShadowCastSpec = gEnv->pConsole->GetCVar("e_ObjShadowCastSpec"); - if (nCastShadowMinSpec <= pObjShadowCastSpec->GetIVal()) - { - m_dwRndFlags |= ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS; - } - - if (bDynamicDistanceShadows) - { - m_dwRndFlags |= ERF_DYNAMIC_DISTANCESHADOWS; - } - if (bHideability) - { - m_dwRndFlags |= ERF_HIDABLE; - } - if (bHideabilitySecondary) - { - m_dwRndFlags |= ERF_HIDABLE_SECONDARY; - } - if (!bAllowIndoor) - { - m_dwRndFlags |= ERF_OUTDOORONLY; - } - - uint32 nSpec = (uint32)minConfigSpec; - if (nSpec != 0) - { - m_dwRndFlags &= ~ERF_SPEC_BITS_MASK; - m_dwRndFlags |= (nSpec << ERF_SPEC_BITS_SHIFT) & ERF_SPEC_BITS_MASK; - } - - if (GetStatObj()) - { - fVegRadiusVert = GetStatObj()->GetRadiusVert(); - fVegRadiusHor = GetStatObj()->GetRadiusHors(); - fVegRadius = max(fVegRadiusVert, fVegRadiusHor); - } - else - { - fVegRadiusHor = fVegRadius = fVegRadiusVert = 0; - } - -#if defined(FEATURE_SVO_GI) - _smart_ptr pMat = pMaterial ? pMaterial : (pStatObj ? pStatObj->GetMaterial() : 0); - if (pMat && (gEnv->pConsole->GetCVar("e_svoTI_Active") && - gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal() && - gEnv->pConsole->GetCVar("e_GI")->GetIVal())) - { - pMat->SetKeepLowResSysCopyForDiffTex(); - } -#endif -} - -bool CObjManager::SphereRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const float fRadius, _smart_ptr pMat) -{ - FUNCTION_PROFILER_3DENGINE; - - // get position offset and stride - int nPosStride = 0; - byte* pPos = pRenderMesh->GetPosPtr(nPosStride, FSL_READ); - - // get indices - vtx_idx* pInds = pRenderMesh->GetIndexPtr(FSL_READ); - assert(pRenderMesh->GetIndicesCount() % 3 == 0); - - // test tris - TRenderChunkArray& Chunks = pRenderMesh->GetChunks(); - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - // skip transparent and alpha test - if (pMat) - { - const SShaderItem& shaderItem = pMat->GetShaderItem(pChunk->m_nMatID); - if (!shaderItem.m_pShader || shaderItem.m_pShader->GetFlags() & EF_NODRAW) - { - continue; - } - } - - int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - for (int i = pChunk->nFirstIndexId; i < nLastIndexId; i += 3) - { - assert((int)pInds[i + 0] < pRenderMesh->GetVerticesCount()); - assert((int)pInds[i + 1] < pRenderMesh->GetVerticesCount()); - assert((int)pInds[i + 2] < pRenderMesh->GetVerticesCount()); - - // get triangle vertices - Vec3 v0 = (*(Vec3*)&pPos[nPosStride * pInds[i + 0]]); - Vec3 v1 = (*(Vec3*)&pPos[nPosStride * pInds[i + 1]]); - Vec3 v2 = (*(Vec3*)&pPos[nPosStride * pInds[i + 2]]); - - AABB triBox; - triBox.min = v0; - triBox.max = v0; - triBox.Add(v1); - triBox.Add(v2); - - if (Overlap::Sphere_AABB(Sphere(vInPos, fRadius), triBox)) - { - return true; - } - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::ClearStatObjGarbage() -{ - FUNCTION_PROFILER_3DENGINE; - - // No work? Exit early before attempting to take any locks - if (m_checkForGarbage.empty()) - { - return; - } - - // We have to take the load lock here because InternalDeleteObject needs this lock and loadMutex has to be locked before garbageMutex - // Additionally, we need to hold one of these locks for the entire duration of this function to prevent the loading thread from using an object that is about to be deleted - // To avoid stalls due to the threads loading files, try to get the lock and if it fails simply try again next frame unless there are too many garbage objects. - AZStd::unique_lock loadLock(m_loadMutex, AZStd::try_to_lock_t()); - if (!loadLock.owns_lock()) - { - if (m_checkForGarbage.size() > s_maxPendingGarbageObjects) - { - AZ_PROFILE_SCOPE_STALL(AZ::Debug::ProfileCategory::ThreeDEngine, "StatObjGarbage overflow"); - // There are too many objects pending garbage collection so force a clear this frame even if loading is happening. - loadLock.lock(); - } - else - { - return; - } - } - - AZStd::vector garbage; - - // We might need to perform the entire garbage collection logic more than once because the call to - // pStatObj->Shutdown() has the potential to add separate LOD models back onto the m_checkForGarbage list. - // If we only run the logic once, we might exit the ClearStatObjGarbage() function with garbage that hasn't been - // fully cleared. - while (!m_checkForGarbage.empty()) - { - { - AZStd::unique_lock garbageLock(m_garbageMutex); - - // Make sure all stat objects inside this array are unique. - // Only check explicitly added objects. - IStatObj* pStatObj; - - while (!m_checkForGarbage.empty()) - { - pStatObj = m_checkForGarbage.back(); - m_checkForGarbage.pop_back(); - - if (pStatObj->CheckGarbage()) - { - // Check if it must be released. - int nChildRefs = pStatObj->CountChildReferences(); - - if (pStatObj->GetUserCount() <= 0 && nChildRefs <= 0) - { - garbage.push_back(pStatObj); - } - else - { - pStatObj->SetCheckGarbage(false); - } - } - } - } - - // First ShutDown object clearing all pointers. - for (int i = 0, num = (int)garbage.size(); i < num; i++) - { - IStatObj* pStatObj = garbage[i]; - - if (!m_bLockCGFResources && !IsResourceLocked(pStatObj->GetFileName())) - { - // only shutdown object if it can be deleted by InternalDeleteObject() - pStatObj->ShutDown(); - } - } - - // Then delete all garbage objects. - for (int i = 0, num = (int)garbage.size(); i < num; i++) - { - IStatObj* pStatObj = garbage[i]; - InternalDeleteObject(pStatObj); - } - - garbage.clear(); - } -} - -////////////////////////////////////////////////////////////////////////// -IRenderMesh* CObjManager::GetRenderMeshBox() -{ - if (!m_pRMBox) - { - MakeUnitCube(); - } - return m_pRMBox; -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::CheckForGarbage(IStatObj* pObject) -{ - if (m_bGarbageCollectionEnabled && - !pObject->CheckGarbage()) - { - AZStd::lock_guard lock(m_garbageMutex); - - pObject->SetCheckGarbage(true); - m_checkForGarbage.push_back(pObject); - } -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::UnregisterForGarbage(IStatObj* pObject) -{ - CRY_ASSERT(pObject); - - if (m_bGarbageCollectionEnabled && - pObject->CheckGarbage()) - { - AZStd::lock_guard lock(m_garbageMutex); - - if (!m_checkForGarbage.empty()) - { - auto iterator = std::find(m_checkForGarbage.begin(), m_checkForGarbage.end(), pObject); - - if (iterator != m_checkForGarbage.end()) - { - m_checkForGarbage.erase(iterator); - } - } - - pObject->SetCheckGarbage(false); - } -} - -void CObjManager::MakeDepthCubemapRenderItemList(CVisArea* pReceiverArea, const AABB& cubemapAABB, [[maybe_unused]] int renderNodeFlags, PodArray* objectsList, const SRenderingPassInfo& passInfo) -{ - if (pReceiverArea) - { - if (pReceiverArea->m_pObjectsTree) - { - pReceiverArea->m_pObjectsTree->FillDepthCubemapRenderList(cubemapAABB, passInfo, objectsList); - } - } - else - { - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->FillDepthCubemapRenderList(cubemapAABB, passInfo, objectsList); - } - } -} - -////////////////////////////////////////////////////////////////////////// -// StatInstGroupEventBus -////////////////////////////////////////////////////////////////////////// -StatInstGroupId CObjManager::GenerateStatInstGroupId() -{ - // generate new id - StatInstGroupId id = StatInstGroupEvents::s_InvalidStatInstGroupId; - for (StatInstGroupId i = 0; i < std::numeric_limits::max(); ++i) - { - if (m_usedIds.find(i) == m_usedIds.end()) - { - id = i; - break; - } - } - - if (id == StatInstGroupEvents::s_InvalidStatInstGroupId) - { - return id; - } - - // Mark id as used - m_usedIds.insert(id); - return id; -} - -void CObjManager::ReleaseStatInstGroupId(StatInstGroupId statInstGroupId) -{ - // Free id for this object - m_usedIds.erase(statInstGroupId); -} - -void CObjManager::ReleaseStatInstGroupIdSet(const AZStd::unordered_set& statInstGroupIdSet) -{ - for (auto groupId : statInstGroupIdSet) - { - m_usedIds.erase(groupId); - } -} - -void CObjManager::ReserveStatInstGroupIdRange(StatInstGroupId from, StatInstGroupId to) -{ - for (StatInstGroupId id = from; id < to; ++id) - { - m_usedIds.insert(id); - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/ObjMan.h b/Code/CryEngine/Cry3DEngine/ObjMan.h deleted file mode 100644 index cd888b9932..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjMan.h +++ /dev/null @@ -1,534 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_OBJMAN_H -#define CRYINCLUDE_CRY3DENGINE_OBJMAN_H -#pragma once - - -#include -#include - -#include "StatObj.h" -#include "../RenderDll/Common/Shadow_Renderer.h" - -#include "StlUtils.h" -#include "cbuffer.h" -#include "CZBufferCuller.h" -#include "PoolAllocator.h" -#include "CCullThread.h" -#include -#include - -#include -#include - -#define ENTITY_MAX_DIST_FACTOR 100 -#define MAX_VALID_OBJECT_VOLUME (10000000000.f) -#define DEFAULT_CGF_NAME ("engineassets/objects/default.cgf") - -struct IStatObj; -struct IIndoorBase; -struct IRenderNode; -struct ISystem; -struct IDecalRenderNode; -struct SCheckOcclusionJobData; -struct SCheckOcclusionOutput; -struct CVisArea; - -class CVegetation; - -class C3DEngine; -struct IMaterial; - -#define SMC_EXTEND_FRUSTUM 8 -#define SMC_SHADOW_FRUSTUM_TEST 16 - -#define OCCL_TEST_HEIGHT_MAP 1 -#define OCCL_TEST_CBUFFER 2 -#define OCCL_TEST_INDOOR_OCCLUDERS_ONLY 4 -#define POOL_STATOBJ_ALLOCS - -//! contains stat obj instance group properties (vegetation object properties) -struct StatInstGroup - : public IStatInstGroup -{ - StatInstGroup() - { - pStatObj = nullptr; - } - - void Update(struct CVars* pCVars, int nGeomDetailScreenRes); - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct SExportedBrushMaterial -{ - int size; - char material[64]; -}; - -struct SRenderMeshInfoOutput -{ - SRenderMeshInfoOutput() { memset(this, 0, sizeof(*this)); } - _smart_ptr pMesh; - _smart_ptr pMat; -}; - -struct SObjManRenderDebugInfo -{ - SObjManRenderDebugInfo(IRenderNode* _pEnt, float _fEntDistance) - : pEnt(_pEnt) - , fEntDistance(_fEntDistance) {} - - IRenderNode* pEnt; - float fEntDistance; -}; - -////////////////////////////////////////////////////////////////////////// -class CObjManager - : public Cry3DEngineBase - , public IObjManager - , private StatInstGroupEventBus::Handler -{ -public: - enum - { - MaxPrecachePoints = 4, - }; - //! The maximum number of objects pending garbage collection before cleanup is forced - //! in the current frame instead of delayed until loading has completed. - //! This helps reduce spikes when cleaning up render objects. - static const size_t s_maxPendingGarbageObjects = 250; - -public: - CObjManager(); - virtual ~CObjManager(); - - void PreloadLevelObjects(); - void UnloadObjects(bool bDeleteAll); - - void CheckTextureReadyFlag(); - - IStatObj* AllocateStatObj(); - void FreeStatObj(IStatObj* pObj); - virtual _smart_ptr GetDefaultCGF() { return m_pDefaultCGF; } - - virtual SRainParams& GetRainParams() override { return m_rainParams; } - virtual SSnowParams& GetSnowParams() override { return m_snowParams; } - - template - static int GetItemId(std::vector* pArray, T* pItem, [[maybe_unused]] bool bAssertIfNotFound = true) - { - for (uint32 i = 0, end = pArray->size(); i < end; ++i) - { - if ((*pArray)[i] == pItem) - { - return i; - } - } - return -1; - } - - template - static T* GetItemPtr(std::vector* pArray, int nId) - { - if (nId < 0) - { - return NULL; - } - - assert(nId < (int)pArray->size()); - - if (nId < (int)pArray->size()) - { - return (*pArray)[nId]; - } - else - { - return NULL; - } - } - - - template - static int GetItemId(std::vector<_smart_ptr >* pArray, _smart_ptr pItem, [[maybe_unused]] bool bAssertIfNotFound = true) - { - for (uint32 i = 0, end = pArray->size(); i < end; ++i) - { - if ((*pArray)[i] == pItem) - { - return i; - } - } - return -1; - } - - template - static _smart_ptr GetItemPtr(std::vector<_smart_ptr >* pArray, int nId) - { - if (nId < 0) - { - return NULL; - } - - assert(nId < (int)pArray->size()); - - if (nId < (int)pArray->size()) - { - return (*pArray)[nId]; - } - else - { - return NULL; - } - } - - //! Loads a static object from a CGF file. Does not increment the static object's reference counter. The reference returned is not guaranteed to be valid unless run on the same thread running the garbage collection. Best used for priming the cache - virtual IStatObj* LoadStatObjUnsafeManualRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) override; - - //! Loads a static object from a CGF file. Increments the static object's reference counter. This method is threadsafe. Not suitable for preloading - _smart_ptr LoadStatObjAutoRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL); - -private: - - template - T LoadStatObjInternal(const char* filename, const char* _szGeomName, IStatObj::SSubObject** ppSubObject, bool bUseStreaming, unsigned long nLoadingFlags, const void* pData, int nDataSize, const char* szBlockName); - - template - void NormalizeLevelName(const char* filename, char(&normalizedFilename)[SIZE_IN_CHARS]); - - void LoadDefaultCGF(const char* filename, unsigned long nLoadingFlags); - virtual IStatObj* LoadNewCGF(IStatObj* pObject, int flagCloth, bool bUseStreaming, bool bForceBreakable, unsigned long nLoadingFlags, const char* normalizedFilename, const void* pData, int nDataSize, const char* originalFilename, const char* geomName, IStatObj::SSubObject** ppSubObject) override; - - virtual IStatObj* LoadFromCacheNoRef(IStatObj* pObject, bool bUseStreaming, unsigned long nLoadingFlags, const char* geomName, IStatObj::SSubObject** ppSubObject) override; - - PodArray > m_lstStaticTypes; - -public: - - void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount); - - // Deletes object. - // Only should be called by Release function of IStatObj. - virtual bool InternalDeleteObject(IStatObj* pObject) override; - - PodArray >& GetListStaticTypes() { return m_lstStaticTypes; } - int GetListStaticTypesCount() override { return m_lstStaticTypes.Count(); } - int GetListStaticTypesGroupCount(int typeId) override { return m_lstStaticTypes[typeId].Count(); } - IStatInstGroup* GetIStatInstGroup(int typeId, int groupId) override { return &m_lstStaticTypes[typeId][groupId]; } - - void MakeShadowCastersList(CVisArea* pReceiverArea, const AABB& aabbReceiver, - int dwAllowedTypes, int32 nRenderNodeFlags, Vec3 vLightPos, CDLight* pLight, ShadowMapFrustum* pFr, PodArray* pShadowHull, const SRenderingPassInfo& passInfo); - - int MakeStaticShadowCastersList(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int nMaxNodes, const SRenderingPassInfo& passInfo); - - void MakeDepthCubemapRenderItemList(CVisArea* pReceiverArea, const AABB& cubemapAABB, int renderNodeFlags, PodArray* objectsList, const SRenderingPassInfo& passInfo); - - // decal pre-caching - DecalsToPrecreate m_decalsToPrecreate; - - void PrecacheStatObjMaterial(_smart_ptr pMaterial, const float fEntDistance, IStatObj* pStatObj, bool bFullUpdate, bool bDrawNear); - virtual DecalsToPrecreate& GetDecalsToPrecreate() override { return m_decalsToPrecreate; } - - void PrecacheStatObj(IStatObj* pStatObj, int nLod, const Matrix34A& statObjMatrix, _smart_ptr pMaterial, float fImportance, float fEntDistance, bool bFullUpdate, bool bHighPriority); - - virtual PodArray& GetArrStreamableObjects() override { return m_arrStreamableObjects; } - virtual PodArray& GetStreamPreCacheCameras() override { return m_vStreamPreCacheCameras; } - - virtual Vec3 GetSunColor() override { return m_vSunColor; } - virtual void SetSunColor(const Vec3& color) override { m_vSunColor = color; } - - Vec3 GetSunAnimColor() override { return m_sunAnimColor; } - void SetSunAnimColor(const Vec3& color) override { m_sunAnimColor = color; } - - float GetSunAnimSpeed() override { return m_sunAnimSpeed; } - void SetSunAnimSpeed(float sunAnimSpeed) override { m_sunAnimSpeed = sunAnimSpeed; } - - AZ::u8 GetSunAnimPhase() override { return m_sunAnimPhase; } - void SetSunAnimPhase(AZ::u8 sunAnimPhase) override { m_sunAnimPhase = sunAnimPhase; } - - AZ::u8 GetSunAnimIndex() override { return m_sunAnimIndex; } - void SetSunAnimIndex(AZ::u8 sunAnimIndex) override { m_sunAnimIndex = sunAnimIndex; } - - virtual float GetSSAOAmount() override { return m_fSSAOAmount; } - virtual void SetSSAOAmount(float amount) override { m_fSSAOAmount = amount; } - - virtual float GetSSAOContrast() override { return m_fSSAOContrast; } - virtual void SetSSAOContrast(float amount) override { m_fSSAOContrast = amount; } - - virtual bool IsCameraPrecacheOverridden() override { return m_bCameraPrecacheOverridden; } - virtual void SetCameraPrecacheOverridden(bool state) override { m_bCameraPrecacheOverridden = state; } - - virtual ObjectsMap& GetNameToObjectMap() override { return m_nameToObjectMap; } - virtual LoadedObjects& GetLoadedObjects() override { return m_lstLoadedObjects; } - - ////////////////////////////////////////////////////////////////////////// - - ObjectsMap m_nameToObjectMap; - LoadedObjects m_lstLoadedObjects; - - /// Thread-safety for async requests to CreateInstance. - // Always take this lock before m_garbageMutex if taking both - AZStd::recursive_mutex m_loadMutex; - -public: - int GetLoadedObjectCount() { return m_lstLoadedObjects.size(); } - - uint16 CheckCachedNearestCubeProbe(IRenderNode* pEnt) - { - if (pEnt->m_pRNTmpData) - { - CRNTmpData::SRNUserData& pUserDataRN = pEnt->m_pRNTmpData->userData; - - const uint16 nCacheClearThreshold = 32; - ++pUserDataRN.nCubeMapIdCacheClearCounter; - pUserDataRN.nCubeMapIdCacheClearCounter &= (nCacheClearThreshold - 1); - - if (pUserDataRN.nCubeMapId && pUserDataRN.nCubeMapIdCacheClearCounter) - { - return pUserDataRN.nCubeMapId; - } - } - - // cache miss - return 0; - } - - int16 GetNearestCubeProbe(IVisArea* pVisArea, const AABB& objBox, bool bSpecular = true); - - void RenderObject(IRenderNode* o, - const AABB& objBox, - float fEntDistance, - EERType eERType, - const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - - void RenderDecalAndRoad(IRenderNode* pEnt, - const AABB& objBox, float fEntDistance, - bool nCheckOcclusion, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - - void RenderObjectDebugInfo(IRenderNode* pEnt, float fEntDistance, const SRenderingPassInfo& passInfo); - void RenderAllObjectDebugInfo(); - void RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance); - void RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt); - - float GetXYRadius(int nType, int nSID = GetDefSID()); - bool GetStaticObjectBBox(int nType, Vec3& vBoxMin, Vec3& vBoxMax, int nSID = GetDefSID()); - - IStatObj* GetStaticObjectByTypeID(int nTypeID, int nSID = GetDefSID()); - IStatObj* FindStaticObjectByFilename(const char* filename); - - //float GetBendingRandomFactor() override; - int GetUpdateStreamingPrioriryRoundIdFast() override { return m_nUpdateStreamingPrioriryRoundIdFast; } - int GetUpdateStreamingPrioriryRoundId() override { return m_nUpdateStreamingPrioriryRoundId; }; - virtual void IncrementUpdateStreamingPrioriryRoundIdFast(int amount) override { m_nUpdateStreamingPrioriryRoundIdFast += amount; } - virtual void IncrementUpdateStreamingPrioriryRoundId(int amount) override { m_nUpdateStreamingPrioriryRoundId += amount; } - - virtual void SetLockCGFResources(bool value) override { m_bLockCGFResources = value; } - virtual bool IsLockCGFResources() override { return m_bLockCGFResources != 0; } - - - bool IsBoxOccluded(const AABB& objBox, - float fDistance, - OcclusionTestClient* const __restrict pOcclTestVars, - bool bIndoorOccludersOnly, - EOcclusionObjectType eOcclusionObjectType, - const SRenderingPassInfo& passInfo); - - void AddDecalToRenderer(float fDistance, - _smart_ptr pMat, - const uint8 sortPrio, - Vec3 right, - Vec3 up, - const UCol& ucResCol, - const uint8 uBlendType, - const Vec3& vAmbientColor, - Vec3 vPos, - const int nAfterWater, - const SRenderingPassInfo& passInfo, - const SRendItemSorter& rendItemSorter); - - ////////////////////////////////////////////////////////////////////////// - - void RegisterForStreaming(IStreamable* pObj); - void UnregisterForStreaming(IStreamable* pObj); - void UpdateRenderNodeStreamingPriority(IRenderNode* pObj, float fEntDistance, float fImportanceFactor, bool bFullUpdate, const SRenderingPassInfo& passInfo, bool bHighPriority = false); - - void GetMemoryUsage(class ICrySizer* pSizer) const; - void GetBandwidthStats(float* fBandwidthRequested); - - void ReregisterEntitiesInArea(Vec3 vBoxMin, Vec3 vBoxMax); - void UpdateObjectsStreamingPriority(bool bSyncLoad, const SRenderingPassInfo& passInfo); - void ProcessObjectsStreaming(const SRenderingPassInfo& passInfo); - - // implementation parts of ProcessObjectsStreaming - void ProcessObjectsStreaming_Impl(bool bSyncLoad, const SRenderingPassInfo& passInfo); - void ProcessObjectsStreaming_Sort(bool bSyncLoad, const SRenderingPassInfo& passInfo); - void ProcessObjectsStreaming_Release(); - void ProcessObjectsStreaming_InitLoad(bool bSyncLoad); - void ProcessObjectsStreaming_Finish(); - -#ifdef OBJMAN_STREAM_STATS - void ProcessObjectsStreaming_Stats(const SRenderingPassInfo& passInfo); -#endif - - // time counters - - virtual bool IsAfterWater(const Vec3& vPos, const SRenderingPassInfo& passInfo) override; - - void GetObjectsStreamingStatus(I3DEngine::SObjectsStreamingStatus& outStatus); - - void FreeNotUsedCGFs(); - - void MakeUnitCube(); - - ////////////////////////////////////////////////////////////////////////// - // CheckOcclusion functionality - bool CheckOcclusion_TestAABB(const AABB& rAABB, float fEntDistance) override; - bool CheckOcclusion_TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) override; - - void PushIntoCullQueue(const SCheckOcclusionJobData& rCheckOcclusionData) override; - void PopFromCullQueue(SCheckOcclusionJobData* pCheckOcclusionData); - - void PushIntoCullOutputQueue(const SCheckOcclusionOutput& rCheckOcclusionOutput) override; - bool PopFromCullOutputQueue(SCheckOcclusionOutput* pCheckOcclusionOutput) override; - - void BeginCulling() override; - void RemoveCullJobProducer() override; - void AddCullJobProducer() override; - virtual NAsyncCull::CCullThread& GetCullThread() override { return m_CullThread; }; - -#ifndef _RELEASE - void CoverageBufferDebugDraw() override; -#endif - - bool LoadOcclusionMesh(const char* pFileName) override; - - ////////////////////////////////////////////////////////////////////////// - // Garbage collection for parent stat objects. - // Returns number of deleted objects - void ClearStatObjGarbage(); - void CheckForGarbage(IStatObj* pObject); - void UnregisterForGarbage(IStatObj* pObject); - - int GetObjectLOD(const IRenderNode* pObj, float fDistance); - bool RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMat, _smart_ptr pMat, - Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest); - bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, _smart_ptr pMat); - bool SphereRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const float fRadius, _smart_ptr pMat); - PodArray m_tmpAreas0, m_tmpAreas1; - - uint8 GetDissolveRef(float fDist, float fMaxViewDist); - float GetLodDistDissolveRef(SLodDistDissolveTransitionState* pState, float curDist, int nNewLod, const SRenderingPassInfo& passInfo); - - virtual PodArray& GetArrStreamingNodeStack() override { return m_arrStreamingNodeStack; } - virtual PodArray& GetStreamPreCachePointDefs() override { return m_vStreamPreCachePointDefs; } - - void CleanStreamingData(); - IRenderMesh* GetRenderMeshBox(); - - void PrepareCullbufferAsync(const CCamera& rCamera); - void BeginOcclusionCulling(const SRenderingPassInfo& passInfo); - void EndOcclusionCulling(bool waitForOcclusionJobCompletion = false); - void RenderBufferedRenderMeshes(const SRenderingPassInfo& passInfo); - - virtual float GetGSMMaxDistance() const override { return m_fGSMMaxDistance; } - virtual void SetGSMMaxDistance(float value) override { m_fGSMMaxDistance = value; } - - virtual int IncrementNextPrecachePointId() override { return m_nNextPrecachePointId++; } -private: - std::vector, float> > m_collectedMaterials; - -public: - ////////////////////////////////////////////////////////////////////////// - // Public Member variables (need to be cleaned). - ////////////////////////////////////////////////////////////////////////// - - static int m_nUpdateStreamingPrioriryRoundId; - static int m_nUpdateStreamingPrioriryRoundIdFast; - static int s_nLastStreamingMemoryUsage; //For streaming tools in editor - - Vec3 m_vSunColor; //Similar to CDLight's m_BaseColor - Vec3 m_sunAnimColor; //Similar to CDLight's m_Color - float m_sunAnimSpeed; - AZ::u8 m_sunAnimPhase; - AZ::u8 m_sunAnimIndex; - - float m_fILMul; - float m_fSSAOAmount; - float m_fSSAOContrast; - SRainParams m_rainParams; - SSnowParams m_snowParams; - - int m_bLockCGFResources; - - float m_fGSMMaxDistance; - -public: - ////////////////////////////////////////////////////////////////////////// - // Private Member variables. - ////////////////////////////////////////////////////////////////////////// - PodArray m_arrStreamableToRelease; - PodArray m_arrStreamableToLoad; - PodArray m_arrStreamableToDelete; - bool m_bNeedProcessObjectsStreaming_Finish; - -#ifdef SUPP_HWOBJ_OCCL - IShader* m_pShaderOcclusionQuery; -#endif - - // bool LoadStaticObjectsFromXML(XmlNodeRef xmlVegetation); - _smart_ptr m_pDefaultCGF; - _smart_ptr m_pRMBox; - - ////////////////////////////////////////////////////////////////////////// - std::vector<_smart_ptr > m_lockedObjects; - - ////////////////////////////////////////////////////////////////////////// - - bool m_bGarbageCollectionEnabled; - - PodArray m_arrStreamableObjects; - PodArray m_arrStreamingNodeStack; - PodArray m_vStreamPreCachePointDefs; - PodArray m_vStreamPreCacheCameras; - int m_nNextPrecachePointId; - bool m_bCameraPrecacheOverridden; - -#ifdef POOL_STATOBJ_ALLOCS - stl::PoolAllocator* m_statObjPool; -#endif - - CThreadSafeRendererContainer m_arrRenderDebugInfo; - - NAsyncCull::CCullThread m_CullThread; - CryMT::SingleProducerSingleConsumerQueue m_CheckOcclusionQueue; - CryMT::N_ProducerSingleConsumerQueue m_CheckOcclusionOutputQueue; - -private: - - // Always take this lock after m_loadLock if taking both - AZStd::recursive_mutex m_garbageMutex; - AZStd::vector m_checkForGarbage; - -private: - // StatInstGroupEventBus - AZStd::unordered_set m_usedIds; - StatInstGroupId GenerateStatInstGroupId() override; - void ReleaseStatInstGroupId(StatInstGroupId statInstGroupId) override; - void ReleaseStatInstGroupIdSet(const AZStd::unordered_set& statInstGroupIdSet) override; - void ReserveStatInstGroupIdRange(StatInstGroupId from, StatInstGroupId to) override; -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_OBJMAN_H diff --git a/Code/CryEngine/Cry3DEngine/ObjManDraw.cpp b/Code/CryEngine/Cry3DEngine/ObjManDraw.cpp deleted file mode 100644 index ad2d4c8545..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjManDraw.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Draw static objects (vegetations) - - -#include "Cry3DEngine_precompiled.h" diff --git a/Code/CryEngine/Cry3DEngine/ObjManDrawEntity.cpp b/Code/CryEngine/Cry3DEngine/ObjManDrawEntity.cpp deleted file mode 100644 index 350c566263..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjManDrawEntity.cpp +++ /dev/null @@ -1,595 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Render all entities in the sector together with shadows - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "3dEngine.h" -#include "CullBuffer.h" -#include "3dEngine.h" -#include "LightEntity.h" -#include "DecalManager.h" -#include "ObjectsTree.h" - -void CObjManager::RenderDecalAndRoad(IRenderNode* pEnt, - const AABB& objBox, - float fEntDistance, - bool nCheckOcclusion, - const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - // do not draw if marked to be not drawn or already drawn in this frame - unsigned int nRndFlags = pEnt->GetRndFlags(); - - if (nRndFlags & ERF_HIDDEN) - { - return; - } - - EERType eERType = pEnt->GetRenderNodeType(); - - // detect bad objects - float fEntLengthSquared = objBox.GetSize().GetLengthSquared(); - if (eERType != eERType_Light || !_finite(fEntLengthSquared)) - { - if (fEntLengthSquared > MAX_VALID_OBJECT_VOLUME || !_finite(fEntLengthSquared) || fEntLengthSquared <= 0) - { - Warning("CObjManager::RenderObject: Object has invalid bbox: %s,%s, Radius = %.2f, Center = (%.1f,%.1f,%.1f)", - pEnt->GetName(), pEnt->GetEntityClassName(), sqrt_tpl(fEntLengthSquared) * 0.5f, - pEnt->GetBBox().GetCenter().x, pEnt->GetBBox().GetCenter().y, pEnt->GetBBox().GetCenter().z); - return; // skip invalid objects - usually only objects with invalid very big scale will reach this point - } - } - - // allocate RNTmpData for potentially visible objects - Get3DEngine()->CheckCreateRNTmpData(&pEnt->m_pRNTmpData, pEnt, passInfo); - - if (nCheckOcclusion && pEnt->m_pOcNode) - { - if (GetObjManager()->IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pRNTmpData->userData.m_OcclState, - pEnt->m_pOcNode->m_pVisArea != NULL, eoot_OBJECT, passInfo)) - { - return; - } - } - - // skip "outdoor only" objects if outdoor is not visible - if (GetCVars()->e_CoverageBuffer == 2 && nRndFlags & ERF_OUTDOORONLY && !Get3DEngine()->GetCoverageBuffer()->IsOutdooVisible()) - { - return; - } - - if (pEnt->GetDrawFrame(passInfo.GetRecursiveLevel()) == passInfo.GetFrameID()) - { - return; - } - pEnt->SetDrawFrame(passInfo.GetFrameID(), passInfo.GetRecursiveLevel()); - - CVisArea* pVisArea = (CVisArea*)pEnt->GetEntityVisArea(); - - const Vec3& vCamPos = passInfo.GetCamera().GetPosition(); - - // test only near/big occluders - others will be tested on tree nodes level - if (!objBox.IsContainPoint(vCamPos)) - { - if (eERType == eERType_Light || fEntDistance < pEnt->m_fWSMaxViewDist * GetCVars()->e_OcclusionCullingViewDistRatio) - { - if (IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pRNTmpData->userData.m_OcclState, pVisArea != NULL, eoot_OBJECT, passInfo)) - { - return; - } - } - } - - SRendParams DrawParams; - DrawParams.pTerrainTexInfo = NULL; - DrawParams.dwFObjFlags = 0; - DrawParams.fDistance = fEntDistance; - DrawParams.AmbientColor = Vec3(0, 0, 0); - DrawParams.pRenderNode = pEnt; - - // set lights bit mask - DrawParams.nAfterWater = IsAfterWater(objBox.GetCenter(), passInfo) ? 1 : 0; - - // draw bbox - if (GetCVars()->e_BBoxes)// && eERType != eERType_Light) - { - RenderObjectDebugInfo(pEnt, fEntDistance, passInfo); - } - - DrawParams.m_pVisArea = pVisArea; - - DrawParams.nMaterialLayers = pEnt->GetMaterialLayers(); - DrawParams.rendItemSorter = rendItemSorter.GetValue(); - - pEnt->Render(DrawParams, passInfo); -} - -void CObjManager::RenderObject(IRenderNode* pEnt, - const AABB& objBox, - float fEntDistance, - EERType eERType, - const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - const CVars* pCVars = GetCVars(); - - // do not draw if marked to be not drawn or already drawn in this frame - unsigned int nRndFlags = pEnt->GetRndFlags(); - - if (nRndFlags & ERF_HIDDEN) - { - return; - } - -#ifndef _RELEASE - // check cvars - switch (eERType) - { - case eERType_Decal: - if (!passInfo.RenderDecals()) - { - return; - } - break; - case eERType_WaterVolume: - if (!passInfo.RenderWaterVolumes()) - { - return; - } - break; - case eERType_Light: - if (!GetCVars()->e_DynamicLights || !passInfo.RenderEntities()) - { - return; - } - break; - case eERType_Cloud: - case eERType_DistanceCloud: - if (!passInfo.RenderClouds()) - { - return; - } - break; - default: - if (!passInfo.RenderEntities()) - { - return; - } - break; - } - - // detect bad objects - float fEntLengthSquared = objBox.GetSize().GetLengthSquared(); - if (eERType != eERType_Light || !_finite(fEntLengthSquared)) - { - if (fEntLengthSquared > MAX_VALID_OBJECT_VOLUME || !_finite(fEntLengthSquared) || fEntLengthSquared <= 0) - { - Warning("CObjManager::RenderObject: Object has invalid bbox: %s, %s, Radius = %.2f, Center = (%.1f,%.1f,%.1f)", - pEnt->GetName(), pEnt->GetEntityClassName(), sqrt_tpl(fEntLengthSquared) * 0.5f, - pEnt->GetBBox().GetCenter().x, pEnt->GetBBox().GetCenter().y, pEnt->GetBBox().GetCenter().z); - return; // skip invalid objects - usually only objects with invalid very big scale will reach this point - } - } -#endif - - if (pEnt->m_dwRndFlags & ERF_COLLISION_PROXY || pEnt->m_dwRndFlags & ERF_RAYCAST_PROXY) - { - // Collision proxy is visible in Editor while in editing mode. - if (!gEnv->IsEditor() || !gEnv->IsEditing()) - { - if (GetCVars()->e_DebugDraw == 0) - { - return; //true; - } - } - } - - // allocate RNTmpData for potentially visible objects - Get3DEngine()->CheckCreateRNTmpData(&pEnt->m_pRNTmpData, pEnt, passInfo); - PrefetchLine(pEnt->m_pRNTmpData, 0); //m_pRNTmpData is >128 bytes, prefetching data used in dissolveref here - -#if !defined(CONSOLE) - // detect already culled occluder - if ((nRndFlags & ERF_GOOD_OCCLUDER)) - { - if (pEnt->m_pRNTmpData->userData.m_OcclState.nLastOccludedMainFrameID == passInfo.GetMainFrameID()) - { - return; - } - - if (pCVars->e_CoverageBufferDrawOccluders) - { - return; - } - } -#endif // !defined(CONSOLE) - - // skip "outdoor only" objects if outdoor is not visible - if (pCVars->e_CoverageBuffer == 2 && nRndFlags & ERF_OUTDOORONLY && !Get3DEngine()->GetCoverageBuffer()->IsOutdooVisible()) - { - return; - } - - const int nRenderStackLevel = passInfo.GetRecursiveLevel(); - - const int nDrawFrame = pEnt->GetDrawFrame(nRenderStackLevel); - - if (eERType != eERType_Light) - { - if (nDrawFrame == passInfo.GetFrameID()) - { - return; - } - pEnt->SetDrawFrame(passInfo.GetFrameID(), nRenderStackLevel); - } - - CVisArea* pVisArea = (CVisArea*)pEnt->GetEntityVisArea(); - - const Vec3& vCamPos = passInfo.GetCamera().GetPosition(); - - // test only near/big occluders - others will be tested on tree nodes level - // Note: Not worth prefetch on rCam or objBox as both have been recently used by calling functions & will be in cache - Rich S - if (!(nRndFlags & ERF_RENDER_ALWAYS) && !objBox.IsContainPoint(vCamPos)) - { - if (eERType == eERType_Light || fEntDistance < pEnt->m_fWSMaxViewDist * pCVars->e_OcclusionCullingViewDistRatio) - { - if (IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pRNTmpData->userData.m_OcclState, pVisArea != NULL, eoot_OBJECT, passInfo)) - { - return; - } - } - } - - if (eERType == eERType_Light) - { - if (nDrawFrame == passInfo.GetFrameID()) - { - return; - } - pEnt->SetDrawFrame(passInfo.GetFrameID(), nRenderStackLevel); - } - - SRendParams DrawParams; - DrawParams.pTerrainTexInfo = NULL; - DrawParams.dwFObjFlags = 0; - DrawParams.fDistance = fEntDistance; - DrawParams.AmbientColor = Vec3(0, 0, 0); - DrawParams.pRenderNode = pEnt; - //DrawParams.pInstance = pEnt; - - if (eERType != eERType_Light && (pEnt->m_nInternalFlags & IRenderNode::REQUIRES_NEAREST_CUBEMAP)) - { - uint16 nCubemapTexId = CheckCachedNearestCubeProbe(pEnt); - if (!nCubemapTexId || !pCVars->e_CacheNearestCubePicking) - { - nCubemapTexId = GetNearestCubeProbe(pVisArea, objBox); - } - - CRNTmpData::SRNUserData* pUserDataRN = (pEnt->m_pRNTmpData) ? &pEnt->m_pRNTmpData->userData : 0; - if (pUserDataRN) - { - pUserDataRN->nCubeMapId = nCubemapTexId; - } - - DrawParams.nTextureID = nCubemapTexId; - } - - if (pCVars->e_Dissolve && eERType != eERType_Light && passInfo.IsGeneralPass()) - { - DrawParams.nDissolveRef = GetDissolveRef(fEntDistance, pEnt->m_fWSMaxViewDist); - if (DrawParams.nDissolveRef) - { - DrawParams.dwFObjFlags |= FOB_DISSOLVE | FOB_DISSOLVE_OUT; - if (DrawParams.nDissolveRef == 255) - { - return; - } - } - } - - DrawParams.nAfterWater = IsAfterWater(objBox.GetCenter(), passInfo) ? 1 : 0; - - if (nRndFlags & ERF_SELECTED) - { - DrawParams.dwFObjFlags |= FOB_SELECTED; - } - - if (pCVars->e_LodForceUpdate) - { - pEnt->m_pRNTmpData->userData.nWantedLod = CObjManager::GetObjectLOD(pEnt, fEntDistance); - } - - // draw bbox -#if !defined(_RELEASE) - if (pCVars->e_BBoxes)// && eERType != eERType_Light) - { - RenderObjectDebugInfo(pEnt, fEntDistance, passInfo); - } -#endif - - if (pEnt->m_dwRndFlags & ERF_NO_DECALNODE_DECALS) - { - DrawParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT; - DrawParams.NoDecalReceiver = true; - } - - DrawParams.m_pVisArea = pVisArea; - -#if !defined(_RELEASE) - if (nRenderStackLevel < 0 || nRenderStackLevel >= MAX_RECURSION_LEVELS) - { - CRY_ASSERT_MESSAGE(nRenderStackLevel >= 0 && nRenderStackLevel < MAX_RECURSION_LEVELS, "nRenderStackLevel is outside max recursions level"); - } -#endif - - DrawParams.nClipVolumeStencilRef = 0; - if (pEnt->m_pRNTmpData && pEnt->m_pRNTmpData->userData.m_pClipVolume) - { - DrawParams.nClipVolumeStencilRef = pEnt->m_pRNTmpData->userData.m_pClipVolume->GetStencilRef(); - } - - DrawParams.nMaterialLayers = pEnt->GetMaterialLayers(); - DrawParams.lodValue = pEnt->ComputeLod(pEnt->m_pRNTmpData->userData.nWantedLod, passInfo); - DrawParams.rendItemSorter = rendItemSorter.GetValue(); - - pEnt->Render(DrawParams, passInfo); -} - -void CObjManager::RenderAllObjectDebugInfo() -{ - AZ_TRACE_METHOD(); - m_arrRenderDebugInfo.CoalesceMemory(); - for (size_t i = 0; i < m_arrRenderDebugInfo.size(); ++i) - { - SObjManRenderDebugInfo& rRenderDebugInfo = m_arrRenderDebugInfo[i]; - if (rRenderDebugInfo.pEnt) - { - RenderObjectDebugInfo_Impl(rRenderDebugInfo.pEnt, rRenderDebugInfo.fEntDistance); - } - } - m_arrRenderDebugInfo.resize(0); -} - -void CObjManager::RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt) -{ - for (size_t i = 0; i < m_arrRenderDebugInfo.size(); ++i) - { - SObjManRenderDebugInfo& rRenderDebugInfo = m_arrRenderDebugInfo[i]; - if (rRenderDebugInfo.pEnt == pEnt) - { - rRenderDebugInfo.pEnt = NULL; - break; - } - } -} - -void CObjManager::RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance) -{ - if (GetCVars()->e_BBoxes > 0) - { - ColorF color(1, 1, 1, 1); - - if (GetCVars()->e_BBoxes == 2 && pEnt->GetRndFlags() & ERF_SELECTED) - { - color.a *= clamp_tpl(pEnt->GetImportance(), 0.5f, 1.f); - float fFontSize = max(2.f - fEntDistance * 0.01f, 1.f); - - string sLabel = pEnt->GetDebugString(); - if (sLabel.empty()) - { - sLabel.Format("%s/%s", - pEnt->GetName(), pEnt->GetEntityClassName()); - } - GetRenderer()->DrawLabelEx(pEnt->GetBBox().GetCenter(), fFontSize, (float*)&color, true, true, "%s", sLabel.c_str()); - } - - IRenderAuxGeom* pRenAux = GetRenderer()->GetIRenderAuxGeom(); - pRenAux->SetRenderFlags(SAuxGeomRenderFlags()); - AABB rAABB = pEnt->GetBBox(); - const float Bias = GetCVars()->e_CoverageBufferAABBExpand; - if (Bias < 0.f) - { - rAABB.Expand((rAABB.max - rAABB.min) * Bias - Vec3(Bias, Bias, Bias)); - } - else - { - rAABB.Expand(Vec3(Bias, Bias, Bias)); - } - - pRenAux->DrawAABB(rAABB, false, color, eBBD_Faceted); - } -} - -bool CObjManager::RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, _smart_ptr pMat) -{ - FUNCTION_PROFILER_3DENGINE; - - struct MeshLock - { - MeshLock(IRenderMesh* m = 0) - : mesh(m) - { - if (m) - { - m->LockForThreadAccess(); - } - } - ~MeshLock() - { - if (mesh) - { - mesh->UnlockStream(VSF_GENERAL); - mesh->UnlockIndexStream(); - mesh->UnLockForThreadAccess(); - } - } - private: - IRenderMesh* mesh; - }; - - MeshLock rmLock(pRenderMesh); - - // get position offset and stride - int nPosStride = 0; - byte* pPos = pRenderMesh->GetPosPtr(nPosStride, FSL_READ); - - // get indices - vtx_idx* pInds = pRenderMesh->GetIndexPtr(FSL_READ); - assert(pRenderMesh->GetIndicesCount() % 3 == 0); - - float fClosestHitDistance = -1; - - Lineseg l0(vInPos + vInDir, vInPos - vInDir); - Lineseg l1(vInPos - vInDir, vInPos + vInDir); - - Vec3 vHitPoint(0, 0, 0); - - // bool b2DTest = fabs(vInDir.x)<0.001f && fabs(vInDir.y)<0.001f; - - // test tris - TRenderChunkArray& Chunks = pRenderMesh->GetChunks(); - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - if (pMat) - { - const SShaderItem& shaderItem = pMat->GetShaderItem(pChunk->m_nMatID); - if (!shaderItem.m_pShader || shaderItem.m_pShader->GetFlags() & EF_NODRAW) - { - continue; - } - } - - AABB triBox; - - int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - for (int i = pChunk->nFirstIndexId; i < nLastIndexId; i += 3) - { - assert((int)pInds[i + 0] < pRenderMesh->GetVerticesCount()); - assert((int)pInds[i + 1] < pRenderMesh->GetVerticesCount()); - assert((int)pInds[i + 2] < pRenderMesh->GetVerticesCount()); - - // get vertices - const Vec3 v0 = (*(Vec3*)&pPos[nPosStride * pInds[i + 0]]); - const Vec3 v1 = (*(Vec3*)&pPos[nPosStride * pInds[i + 1]]); - const Vec3 v2 = (*(Vec3*)&pPos[nPosStride * pInds[i + 2]]); - /* - if(b2DTest) - { - triBox.min = triBox.max = v0; - triBox.Add(v1); - triBox.Add(v2); - if( vInPos.x < triBox.min.x || vInPos.x > triBox.max.x || vInPos.y < triBox.min.y || vInPos.y > triBox.max.y ) - continue; - } - */ - // make line triangle intersection - if (Intersect::Lineseg_Triangle(l0, v0, v1, v2, vHitPoint) || - Intersect::Lineseg_Triangle(l1, v0, v1, v2, vHitPoint)) - { - if (bFastTest) - { - return (true); - } - - float fDist = vHitPoint.GetDistance(vInPos); - if (fDist < fClosestHitDistance || fClosestHitDistance < 0) - { - fClosestHitDistance = fDist; - vOutPos = vHitPoint; - vOutNormal = (v1 - v0).Cross(v2 - v0); - } - } - } - } - - if (fClosestHitDistance >= 0) - { - vOutNormal.Normalize(); - return true; - } - - return false; -} - -bool CObjManager::RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMatrix, _smart_ptr pMat, - Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest) -{ - assert(pStatObj); - - CStatObj* pCStatObj = (CStatObj*)pStatObj; - - if (!pCStatObj || pCStatObj->m_nFlags & STATIC_OBJECT_HIDDEN) - { - return false; - } - - Matrix34 matInv = objMatrix.GetInverted(); - Vec3 vOSStart = matInv.TransformPoint(vStart); - Vec3 vOSEnd = matInv.TransformPoint(vEnd); - Vec3 vOSHitPoint(0, 0, 0), vOSHitNorm(0, 0, 0); - - Vec3 vBoxHitPoint; - if (!Intersect::Ray_AABB(Ray(vOSStart, vOSEnd - vOSStart), pCStatObj->GetAABB(), vBoxHitPoint)) - { - return false; - } - - bool bHitDetected = false; - - if (IRenderMesh* pRenderMesh = pStatObj->GetRenderMesh()) - { - if (CObjManager::RayRenderMeshIntersection(pRenderMesh, vOSStart, vOSEnd - vOSStart, vOSHitPoint, vOSHitNorm, bFastTest, pMat)) - { - bHitDetected = true; - Vec3 vHitPoint = objMatrix.TransformPoint(vOSHitPoint); - float fDist = vHitPoint.GetDistance(vStart); - if (fDist < fClosestHitDistance) - { - fClosestHitDistance = fDist; - vClosestHitPoint = vHitPoint; - } - } - } - else - { - // multi-sub-objects - for (int s = 0, num = pCStatObj->SubObjectCount(); s < num; s++) - { - IStatObj::SSubObject& subObj = pCStatObj->SubObject(s); - if (subObj.pStatObj && !subObj.bHidden && subObj.nType == STATIC_SUB_OBJECT_MESH) - { - Matrix34 subObjMatrix = objMatrix * subObj.tm; - if (RayStatObjIntersection(subObj.pStatObj, subObjMatrix, pMat, vStart, vEnd, vClosestHitPoint, fClosestHitDistance, bFastTest)) - { - bHitDetected = true; - } - } - } - } - - return bHitDetected; -} diff --git a/Code/CryEngine/Cry3DEngine/ObjManFar.cpp b/Code/CryEngine/Cry3DEngine/ObjManFar.cpp deleted file mode 100644 index 1d7f6aea92..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjManFar.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : draw far objects as sprites - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "3dEngine.h" - -static PodArray arrVegetationSprites[RT_COMMAND_BUF_COUNT][MAX_RECURSION_LEVELS]; - -void CObjManager::UnloadFarObjects() -{ - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int j = 0; j < MAX_RECURSION_LEVELS; ++j) - { - stl::free_container(arrVegetationSprites[i][j]); - } - } -} - -void CObjManager::RenderFarObjects(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - int nCount = 0; - for (int t = 0; t < nThreadsNum; t++) - { - nCount += m_arrVegetationSprites[passInfo.GetRecursiveLevel()][t].size(); - } - - if (!m_REFarTreeSprites) - { - m_REFarTreeSprites = (CREFarTreeSprites*)GetRenderer()->EF_CreateRE(eDATA_FarTreeSprites); - } - if (m_REFarTreeSprites && GetCVars()->e_VegetationSprites && nCount && !GetCVars()->e_DefaultMaterial) - { - arrVegetationSprites[passInfo.ThreadID()][passInfo.GetRecursiveLevel()].Clear(); - - for (int t = 0; t < nThreadsNum; t++) - { - CThreadSafeRendererContainer& rList = m_arrVegetationSprites[passInfo.GetRecursiveLevel()][t]; - if (rList.size()) - { - rList.CoalesceMemory(); - for (size_t i = 0; i < rList.size(); ++i) - { - arrVegetationSprites[passInfo.ThreadID()][passInfo.GetRecursiveLevel()].Add(rList[i]); - } - } - } - m_REFarTreeSprites->m_arrVegetationSprites[passInfo.ThreadID()][passInfo.GetRecursiveLevel()] = &arrVegetationSprites[passInfo.ThreadID()][passInfo.GetRecursiveLevel()]; - CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObj) - { - return; - } - pObj->m_II.m_Matrix.SetIdentity(); - SShaderItem shItem(m_p3DEngine->m_pFarTreeSprites); - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - GetRenderer()->EF_AddEf(m_REFarTreeSprites, shItem, pObj, passInfo, EFSLIST_GENERAL, 1, rendItemSorter); - } -} - -void CObjManager::DrawFarObjects(float fMaxViewDist, const SRenderingPassInfo& passInfo) -{ - if (!GetCVars()->e_VegetationSprites) - { - return; - } - - FUNCTION_PROFILER_3DENGINE; - - if (passInfo.GetRecursiveLevel() >= MAX_RECURSION_LEVELS) - { - assert(!"Recursion depther than MAX_RECURSION_LEVELS is not supported"); - return; - } - - ////////////////////////////////////////////////////////////////////////////////////// - // Draw all far - ////////////////////////////////////////////////////////////////////////////////////// -} - -void CObjManager::GenerateFarObjects(float fMaxViewDist, const SRenderingPassInfo& passInfo) -{ - if (!GetCVars()->e_VegetationSprites) - { - return; - } - - FUNCTION_PROFILER_3DENGINE; - - if (passInfo.GetRecursiveLevel() >= MAX_RECURSION_LEVELS) - { - assert(!"Recursion depther than MAX_RECURSION_LEVELS is not supported"); - return; - } -} diff --git a/Code/CryEngine/Cry3DEngine/ObjManShadows.cpp b/Code/CryEngine/Cry3DEngine/ObjManShadows.cpp deleted file mode 100644 index 66ceb3fef6..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjManShadows.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Shadow casters/receivers relations - - -#include "Cry3DEngine_precompiled.h" - -#include "ObjMan.h" -#include "VisAreas.h" -#include "3dEngine.h" -#include -#include "LightEntity.h" -#include "ObjectsTree.h" - -bool IsAABBInsideHull(const SPlaneObject* pHullPlanes, int nPlanesNum, const AABB& aabbBox); - -void CObjManager::MakeShadowCastersList(CVisArea* pArea, [[maybe_unused]] const AABB& aabbReceiver, [[maybe_unused]] int dwAllowedTypes, int32 nRenderNodeFlags, [[maybe_unused]] Vec3 vLightPos, CDLight* pLight, ShadowMapFrustum* pFr, PodArray* pShadowHull, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - assert(pLight && vLightPos.len() > 1); // world space pos required - - pFr->m_castersList.Clear(); - pFr->m_jobExecutedCastersList.Clear(); - - CVisArea* pLightArea = pLight->m_pOwner ? (CVisArea*)pLight->m_pOwner->GetEntityVisArea() : NULL; - - if (pArea) - { - if (pArea->m_pObjectsTree) - { - pArea->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - - if (pLightArea) - { - // check neighbor sectors and portals if light and object are not in same area - if (!(pLight->m_Flags & DLF_THIS_AREA_ONLY)) - { - for (int pp = 0; pp < pArea->m_lstConnections.Count(); pp++) - { - CVisArea* pN = pArea->m_lstConnections[pp]; - if (pN->m_pObjectsTree) - { - pN->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - - for (int p = 0; p < pN->m_lstConnections.Count(); p++) - { - CVisArea* pNN = pN->m_lstConnections[p]; - if (pNN != pLightArea && pNN->m_pObjectsTree) - { - pNN->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - } - } - } - else if (!pLightArea->IsPortal()) - { // visit also portals - for (int p = 0; p < pArea->m_lstConnections.Count(); p++) - { - CVisArea* pN = pArea->m_lstConnections[p]; - if (pN->m_pObjectsTree) - { - pN->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - } - } - } - } - else - { - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - - // check also visareas effected by sun - CVisAreaManager* pVisAreaManager = GetVisAreaManager(); - if (pVisAreaManager) - { - { - PodArray& lstAreas = pVisAreaManager->m_lstVisAreas; - for (int i = 0; i < lstAreas.Count(); i++) - { - if (lstAreas[i]->IsAffectedByOutLights() && lstAreas[i]->m_pObjectsTree) - { - bool bUnused = false; - if (pFr->IntersectAABB(*lstAreas[i]->GetAABBox(), &bUnused)) - { - if (!pShadowHull || IsAABBInsideHull(pShadowHull->GetElements(), pShadowHull->Count(), *lstAreas[i]->GetAABBox())) - { - lstAreas[i]->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - } - } - } - } - { - PodArray& lstAreas = pVisAreaManager->m_lstPortals; - for (int i = 0; i < lstAreas.Count(); i++) - { - if (lstAreas[i]->IsAffectedByOutLights() && lstAreas[i]->m_pObjectsTree) - { - bool bUnused = false; - if (pFr->IntersectAABB(*lstAreas[i]->GetAABBox(), &bUnused)) - { - if (!pShadowHull || IsAABBInsideHull(pShadowHull->GetElements(), pShadowHull->Count(), *lstAreas[i]->GetAABBox())) - { - lstAreas[i]->m_pObjectsTree->FillShadowCastersList(false, pLight, pFr, pShadowHull, nRenderNodeFlags, passInfo); - } - } - } - } - } - } - } - - // add casters with per object shadow map for point lights - if ((pLight->m_Flags & DLF_SUN) == 0) - { - for (uint i = 0; i < Get3DEngine()->m_lstPerObjectShadows.size(); ++i) - { - IShadowCaster* pCaster = Get3DEngine()->m_lstPerObjectShadows[i].pCaster; - assert(pCaster); - - AABB casterBox = pCaster->GetBBoxVirtual(); - - if (!IsRenderNodeTypeEnabled(pCaster->GetRenderNodeType())) - { - continue; - } - - bool bObjCompletellyInFrustum = false; - if (!pFr->IntersectAABB(casterBox, &bObjCompletellyInFrustum)) - { - continue; - } - - pFr->m_castersList.Add(pCaster); - } - } -} - -int CObjManager::MakeStaticShadowCastersList(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int nMaxNodes, const SRenderingPassInfo& passInfo) -{ - int nRemainingNodes = nMaxNodes; - - int nNumTrees = 1; - if (CVisAreaManager* pVisAreaManager = GetVisAreaManager()) - { - nNumTrees += pVisAreaManager->m_lstVisAreas.size() + pVisAreaManager->m_lstPortals.size(); - } - - // objects tree first - int nStartSID = pFrustum->pShadowCacheData->mOctreePath[0]; - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->GetShadowCastersTimeSliced(pIgnoreNode, pFrustum, renderNodeExcludeFlags, nRemainingNodes, 1, passInfo); - } - - if (nRemainingNodes <= 0) - { - return nRemainingNodes; - } - - pFrustum->pShadowCacheData->mOctreePath[0]++; - - // Vis Areas - CVisAreaManager* pVisAreaManager = GetVisAreaManager(); - if (pVisAreaManager) - { - PodArray* lstAreaTypes[] = - { - &pVisAreaManager->m_lstVisAreas, - &pVisAreaManager->m_lstPortals - }; - - //The minus one is a legacy counting issue. Essentially skipping the octree in the engine. - nStartSID = max(0, nStartSID - 1); - - const int nNumAreaTypes = sizeof(lstAreaTypes) / sizeof(lstAreaTypes[0]); - for (int nAreaType = 0; nAreaType < nNumAreaTypes; ++nAreaType) - { - PodArray& lstAreas = *lstAreaTypes[nAreaType]; - - for (int i = nStartSID; i < lstAreas.Count(); i++) - { - if (lstAreas[i]->IsAffectedByOutLights() && lstAreas[i]->m_pObjectsTree) - { - if (pFrustum->aabbCasters.IsReset() || Overlap::AABB_AABB(pFrustum->aabbCasters, *lstAreas[i]->GetAABBox())) - { - lstAreas[i]->m_pObjectsTree->GetShadowCastersTimeSliced(pIgnoreNode, pFrustum, renderNodeExcludeFlags, nRemainingNodes, 0, passInfo); - } - } - - if (nRemainingNodes <= 0) - { - return nRemainingNodes; - } - - pFrustum->pShadowCacheData->mOctreePath[0]++; - } - - nStartSID = max(0, nStartSID - lstAreas.Count()); - } - } - - - // if we got here we processed every tree, so reset tree index - pFrustum->pShadowCacheData->mOctreePath[0] = 0; - return nRemainingNodes; -} diff --git a/Code/CryEngine/Cry3DEngine/ObjManStreaming.cpp b/Code/CryEngine/Cry3DEngine/ObjManStreaming.cpp deleted file mode 100644 index 8a71bdfea7..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjManStreaming.cpp +++ /dev/null @@ -1,1202 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Loading trees, buildings, ragister/unregister entities for rendering - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" - -#include "CullBuffer.h" -#include "3dEngine.h" -#include "IndexedMesh.h" -#include "DecalRenderNode.h" -#include "FogVolumeRenderNode.h" -#include "GeomCacheRenderNode.h" -#include "CryPhysicsDeprecation.h" - -int CObjManager::m_nUpdateStreamingPrioriryRoundId = 1; -int CObjManager::m_nUpdateStreamingPrioriryRoundIdFast = 1; -int CObjManager::s_nLastStreamingMemoryUsage = 0; - -struct CObjManager_Cmp_Streamable_Priority -{ - // returns true if v1 < v2 - ILINE bool operator()(const SStreamAbleObject& v1, const SStreamAbleObject& v2) const - { - IStreamable* arrObj[2] = { v1.GetStreamAbleObject(), v2.GetStreamAbleObject() }; - - // compare priorities - if (v1.fCurImportance > v2.fCurImportance) - { - return true; - } - if (v1.fCurImportance < v2.fCurImportance) - { - return false; - } - - // give low lod's and small meshes higher priority - int MemUsage0 = v1.GetStreamableContentMemoryUsage(); - int MemUsage1 = v2.GetStreamableContentMemoryUsage(); - if (MemUsage0 < MemUsage1) - { - return true; - } - if (MemUsage0 > MemUsage1) - { - return false; - } - - // fix sorting consistency - if (arrObj[0] > arrObj[1]) - { - return true; - } - if (arrObj[0] < arrObj[1]) - { - return false; - } - - return false; - } -}; - -void CObjManager::RegisterForStreaming(IStreamable* pObj) -{ - SStreamAbleObject streamAbleObject(pObj); - if (m_arrStreamableObjects.Find(streamAbleObject) < 0) - { - m_arrStreamableObjects.Add(streamAbleObject); - -#ifdef OBJMAN_STREAM_STATS - if (m_pStreamListener) - { - string name; - pObj->GetStreamableName(name); - m_pStreamListener->OnCreatedStreamedObject(name.c_str(), pObj); - } -#endif - } -} - -void CObjManager::UnregisterForStreaming(IStreamable* pObj) -{ - if (m_arrStreamableObjects.size() > 0) - { - SStreamAbleObject streamAbleObject(pObj, false); - [[maybe_unused]] bool deleted = m_arrStreamableObjects.Delete(streamAbleObject); - -#ifdef OBJMAN_STREAM_STATS - if (deleted && m_pStreamListener) - { - m_pStreamListener->OnDestroyedStreamedObject(pObj); - } -#endif - - if (m_arrStreamableObjects.empty()) - { - stl::free_container(m_arrStreamableObjects); - } - } -} - -void CObjManager::UpdateObjectsStreamingPriority(bool bSyncLoad, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - const size_t nPrecachePoints = m_vStreamPreCachePointDefs.size(); - const bool bNeedsUnique = nPrecachePoints > 1; - - if (bSyncLoad) - { - PrintMessage("Updating level streaming priorities for %" PRISIZE_T " cameras (LevelFrameId = %d)", nPrecachePoints, Get3DEngine()->GetStreamingFramesSinceLevelStart()); - for (size_t pci = 0; pci < nPrecachePoints; ++pci) - { - PrintMessage("-- %f %f %f", - m_vStreamPreCacheCameras[m_vStreamPreCachePointDefs[pci].nId].vPosition.x, - m_vStreamPreCacheCameras[m_vStreamPreCachePointDefs[pci].nId].vPosition.y, - m_vStreamPreCacheCameras[m_vStreamPreCachePointDefs[pci].nId].vPosition.z); - } - } - - CVisAreaManager* pVisAreaMgr = GetVisAreaManager(); - - if (bSyncLoad) - { - m_arrStreamingNodeStack.clear(); - } - - bool bPrecacheNear = true; - - if (bSyncLoad || (passInfo.GetFrameID() & 3) || GetFloatCVar(e_StreamCgfFastUpdateMaxDistance) == 0) - { - bPrecacheNear = false; - - if (!m_arrStreamingNodeStack.Count()) - { - FRAME_PROFILER("UpdateObjectsStreamingPriority_Init", GetSystem(), PROFILE_3DENGINE); - - if (GetCVars()->e_StreamCgf == 2) - { - PrintMessage("UpdateObjectsStreamingPriority_Restart %d", passInfo.GetFrameID()); - } - - for (size_t ppIdx = 0, ppCount = nPrecachePoints; ppIdx != ppCount; ++ppIdx) - { - const Vec3& vPrecachePoint = m_vStreamPreCacheCameras[ppIdx].vPosition; - - CVisArea* pCurArea = pVisAreaMgr ? (CVisArea*)pVisAreaMgr->GetVisAreaFromPos(vPrecachePoint) : NULL; - if (CVisArea* pRoot0 = pCurArea) - { - m_tmpAreas0.Clear(); - pRoot0->AddConnectedAreas(m_tmpAreas0, GetCVars()->e_StreamPredictionMaxVisAreaRecursion); - - bool bFoundOutside = false; - - if (!GetCVars()->e_StreamPredictionAlwaysIncludeOutside) - { - for (int v = 0; v < m_tmpAreas0.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas0[v]; - if (pN1->IsPortal() && pN1->m_lstConnections.Count() == 1) - { - bFoundOutside = true; - break; - } - } - } - else - { - bFoundOutside = true; - } - - if (bFoundOutside) - { - if (Get3DEngine()->IsObjectTreeReady()) - { - m_arrStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - } - - for (int v = 0; v < m_tmpAreas0.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas0[v]; - assert(bNeedsUnique || m_arrStreamingNodeStack.Find(pN1->m_pObjectsTree) < 0); - if (pN1->m_pObjectsTree) - { - m_arrStreamingNodeStack.Add(pN1->m_pObjectsTree); - } - } - } - else if (GetVisAreaManager()) - { - if (Get3DEngine()->IsObjectTreeReady()) - { - m_arrStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - - // find portals around - m_tmpAreas0.Clear(); - GetVisAreaManager()->MakeActiveEntransePortalsList(NULL, m_tmpAreas0, NULL, passInfo); - - // make list of areas for streaming - m_tmpAreas1.Clear(); - for (int p = 0; p < m_tmpAreas0.Count(); p++) - { - if (CVisArea* pRoot = m_tmpAreas0[p]) - { - pRoot->AddConnectedAreas(m_tmpAreas1, GetCVars()->e_StreamPredictionMaxVisAreaRecursion); - } - } - - // fill list of object trees - for (int v = 0; v < m_tmpAreas1.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas1[v]; - assert(bNeedsUnique || m_arrStreamingNodeStack.Find(pN1->m_pObjectsTree) < 0); - if (pN1->m_pObjectsTree) - { - m_arrStreamingNodeStack.Add(pN1->m_pObjectsTree); - } - } - } - else - { - if (Get3DEngine()->IsObjectTreeReady()) - { - m_arrStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - } - } - - IF_UNLIKELY (bNeedsUnique) - { - std::sort(m_arrStreamingNodeStack.begin(), m_arrStreamingNodeStack.end()); - m_arrStreamingNodeStack.resize(std::distance(m_arrStreamingNodeStack.begin(), std::unique(m_arrStreamingNodeStack.begin(), m_arrStreamingNodeStack.end()))); - } - } - - { - // Time-sliced scene streaming priority update - // Update scene faster if in zoom and if camera moving fast - float fMaxTimeToSpendMS = GetCVars()->e_StreamPredictionUpdateTimeSlice * max(Get3DEngine()->GetAverageCameraSpeed() * .5f, 1.f) / max(passInfo.GetZoomFactor(), 0.1f); - fMaxTimeToSpendMS = min(fMaxTimeToSpendMS, GetCVars()->e_StreamPredictionUpdateTimeSlice * 2.f); - - CTimeValue maxTimeToSpend; - maxTimeToSpend.SetSeconds(fMaxTimeToSpendMS * 0.001f); - - const CTimeValue startTime = GetTimer()->GetAsyncTime(); - - const float fMinDist = GetFloatCVar(e_StreamPredictionMinFarZoneDistance); - const float fMaxViewDistance = Get3DEngine()->GetMaxViewDistance(); - - { - FRAME_PROFILER("UpdateObjectsStreamingPriority_MarkNodes", GetSystem(), PROFILE_3DENGINE); - - while (m_arrStreamingNodeStack.Count()) - { - COctreeNode* pLast = m_arrStreamingNodeStack.Last(); - m_arrStreamingNodeStack.DeleteLast(); - - pLast->UpdateStreamingPriority(m_arrStreamingNodeStack, fMinDist, fMaxViewDistance, false, &m_vStreamPreCacheCameras[0], nPrecachePoints, passInfo); - - if (!bSyncLoad && (GetTimer()->GetAsyncTime() - startTime) > maxTimeToSpend) - { - break; - } - } - } - } - - if (!m_arrStreamingNodeStack.Count()) - { - // Round has done. - ++m_nUpdateStreamingPrioriryRoundId; - } - } - - if (bPrecacheNear || bSyncLoad) - { - FRAME_PROFILER("UpdateObjectsStreamingPriority_Mark_NEAR_Nodes", GetSystem(), PROFILE_3DENGINE); - - PodArray fastStreamingNodeStack; - const int nVisAreaRecursion = min(GetCVars()->e_StreamPredictionMaxVisAreaRecursion, 2); - - for (size_t ppIdx = 0, ppCount = nPrecachePoints; ppIdx != ppCount; ++ppIdx) - { - const Vec3& vPrecachePoint = m_vStreamPreCacheCameras[ppIdx].vPosition; - - CVisArea* pCurArea = pVisAreaMgr ? (CVisArea*)pVisAreaMgr->GetVisAreaFromPos(vPrecachePoint) : NULL; - if (CVisArea* pRoot0 = pCurArea) - { - m_tmpAreas0.Clear(); - pRoot0->AddConnectedAreas(m_tmpAreas0, nVisAreaRecursion); - - bool bFoundOutside = false; - - if (!GetCVars()->e_StreamPredictionAlwaysIncludeOutside) - { - for (int v = 0; v < m_tmpAreas0.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas0[v]; - if (pN1->IsPortal() && pN1->m_lstConnections.Count() == 1) - { - bFoundOutside = true; - break; - } - } - } - else - { - bFoundOutside = true; - } - - if (bFoundOutside) - { - if (Get3DEngine()->IsObjectTreeReady()) - { - fastStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - } - - for (int v = 0; v < m_tmpAreas0.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas0[v]; - assert(bNeedsUnique || fastStreamingNodeStack.Find(pN1->m_pObjectsTree) < 0); - if (pN1->m_pObjectsTree) - { - fastStreamingNodeStack.Add(pN1->m_pObjectsTree); - } - } - } - else if (GetVisAreaManager()) - { - if (Get3DEngine()->IsObjectTreeReady()) - { - fastStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - - // find portals around - m_tmpAreas0.Clear(); - GetVisAreaManager()->MakeActiveEntransePortalsList(NULL, m_tmpAreas0, NULL, passInfo); - - // make list of areas for streaming - m_tmpAreas1.Clear(); - for (int p = 0; p < m_tmpAreas0.Count(); p++) - { - if (CVisArea* pRoot = m_tmpAreas0[p]) - { - pRoot->AddConnectedAreas(m_tmpAreas1, nVisAreaRecursion); - } - } - - // fill list of object trees - for (int v = 0; v < m_tmpAreas1.Count(); v++) - { - CVisArea* pN1 = m_tmpAreas1[v]; - assert(bNeedsUnique || fastStreamingNodeStack.Find(pN1->m_pObjectsTree) < 0); - if (pN1->m_pObjectsTree) - { - fastStreamingNodeStack.Add(pN1->m_pObjectsTree); - } - } - } - else - { - if (Get3DEngine()->IsObjectTreeReady()) - { - fastStreamingNodeStack.Add(Get3DEngine()->GetObjectTree()); - } - } - } - - IF_UNLIKELY (bNeedsUnique) - { - std::sort(fastStreamingNodeStack.begin(), fastStreamingNodeStack.end()); - fastStreamingNodeStack.resize(std::distance(fastStreamingNodeStack.begin(), std::unique(fastStreamingNodeStack.begin(), fastStreamingNodeStack.end()))); - } - - const float fMaxDist = max(0.f, GetFloatCVar(e_StreamCgfFastUpdateMaxDistance) - GetFloatCVar(e_StreamPredictionDistanceFar)); - - while (fastStreamingNodeStack.Count()) - { - COctreeNode* pLast = fastStreamingNodeStack.Last(); - fastStreamingNodeStack.DeleteLast(); - - pLast->UpdateStreamingPriority(fastStreamingNodeStack, 0.f, fMaxDist, true, &m_vStreamPreCacheCameras[0], nPrecachePoints, passInfo); - } - - m_nUpdateStreamingPrioriryRoundIdFast++; - } -} - -void CObjManager::CheckTextureReadyFlag() -{ - FUNCTION_PROFILER_3DENGINE; - - if (m_lstStaticTypes.empty()) - { - return; - } - - static uint32 nSID = 0; - static uint32 nGroupId = 0; - - if (nSID >= m_lstStaticTypes.size()) - { - nSID = 0; - } - - PodArray& rGroupTable = m_lstStaticTypes[nSID]; - - if (nGroupId >= rGroupTable.size()) - { - nGroupId = 0; - nSID++; - } - - nGroupId++; -} - -void CObjManager::ProcessObjectsStreaming(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - IF (!GetCVars()->e_StreamCgf, 0) - { - return; - } - - // this assert is most likely triggered by forgetting to call - // 3dEngine::SyncProcessStreamingUpdate at the end of the frame, leading to multiple - // updates, but not starting and/or stopping streaming tasks - assert(m_bNeedProcessObjectsStreaming_Finish == false); - if (m_bNeedProcessObjectsStreaming_Finish == true) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "ProcessObjectsStreaming invoked without a following ProcessObjectsStreaming_Finish, please check your update logic"); - } - - const CCamera& rCamera = passInfo.GetCamera(); - - float fTimeStart = GetTimer()->GetAsyncCurTime(); - - bool bSyncLoad = Get3DEngine()->IsStatObjSyncLoad(); - - if (!m_bCameraPrecacheOverridden) - { - SObjManPrecacheCamera& precachePoint = m_vStreamPreCacheCameras[0]; - - if (rCamera.GetPosition().GetDistance(precachePoint.vPosition) >= GetFloatCVar(e_StreamCgfGridUpdateDistance)) - { - Vec3 vOffset = Get3DEngine()->GetAverageCameraMoveDir() * GetFloatCVar(e_StreamPredictionAhead); - vOffset.z *= .5f; - precachePoint.vPosition = rCamera.GetPosition() + vOffset; - - // Raycast for precache points - CRY_PHYSICS_REPLACEMENT_ASSERT(); - - if IsCVarConstAccess(constexpr) (bool(GetFloatCVar(e_StreamPredictionAheadDebug))) - { - DrawSphere(precachePoint.vPosition, 0.5f); - } - } - - if (Distance::Point_AABBSq(precachePoint.vPosition, precachePoint.bbox) > 0.0f) - { - precachePoint.bbox = AABB(precachePoint.vPosition, GetCVars()->e_StreamPredictionBoxRadius); - } - } - - if (bSyncLoad && Get3DEngine()->IsShadersSyncLoad()) - { - PrintMessage("Pre-caching render meshes, shaders and textures"); - } - else if (bSyncLoad) - { - PrintMessage("Pre-caching render meshes for camera position"); - } - - CTimeValue currentTime = gEnv->pTimer->GetAsyncTime(); - - bool bSyncLoadPoints = m_bCameraPrecacheOverridden || Get3DEngine()->IsContentPrecacheRequested() || bSyncLoad || (GetCVars()->e_StreamCgf == 3) || (GetCVars()->e_StreamCgfDebugHeatMap != 0); - UpdateObjectsStreamingPriority(bSyncLoadPoints, passInfo); - - // Remove stale precache points - - size_t ppWriteIdx = 0; - for (size_t ppIdx = 0, ppCount = m_vStreamPreCachePointDefs.size(); ppIdx != ppCount; ++ppIdx) - { - SObjManPrecachePoint& pp = m_vStreamPreCachePointDefs[ppIdx]; - - if (ppIdx == 0 || currentTime < pp.expireTime) - { - m_vStreamPreCachePointDefs[ppWriteIdx] = pp; - m_vStreamPreCacheCameras[ppWriteIdx] = m_vStreamPreCacheCameras[ppIdx]; - ++ppWriteIdx; - } - } - m_vStreamPreCachePointDefs.resize(ppWriteIdx); - m_vStreamPreCacheCameras.resize(ppWriteIdx); - - m_bCameraPrecacheOverridden = false; - - m_bNeedProcessObjectsStreaming_Finish = true; - ProcessObjectsStreaming_Impl(bSyncLoad, passInfo); - - // during precache don't run asynchrony and sync directly to ensure the ESYSTEM_EVENT_LEVEL_PRECACHED - // event is send to activate the renderthread - // this also applies to the editor, since it calls the render function multiple times and thus invoking the - // function multiple times without syncing - if (bSyncLoad || gEnv->IsEditor()) - { - ProcessObjectsStreaming_Finish(); - } - - if (bSyncLoad) - { - float t = GetTimer()->GetAsyncCurTime() - fTimeStart; - if (t > (1.0f / 15.0f)) - { - PrintMessage("Finished pre-caching in %.1f sec", t); - } - } -} - -void CObjManager::ProcessObjectsStreaming_Impl(bool bSyncLoad, const SRenderingPassInfo& passInfo) -{ - ProcessObjectsStreaming_Sort(bSyncLoad, passInfo); - ProcessObjectsStreaming_Release(); -#ifdef OBJMAN_STREAM_STATS - ProcessObjectsStreaming_Stats(passInfo); -#endif - ProcessObjectsStreaming_InitLoad(bSyncLoad); -} - -void CObjManager::ProcessObjectsStreaming_Sort(bool bSyncLoad, const SRenderingPassInfo& passInfo) -{ - int nNumStreamableObjects = m_arrStreamableObjects.Count(); - - static float fLastTime = 0; - const float fTime = GetTimer()->GetAsyncCurTime(); - - // call sort only every 100 ms - if (nNumStreamableObjects && ((fTime > fLastTime + 0.1f) || bSyncLoad)) - { - FRAME_PROFILER("ProcessObjectsStreaming_Sort", GetSystem(), PROFILE_3DENGINE); - - SStreamAbleObject* arrStreamableObjects = &m_arrStreamableObjects[0]; - assert(arrStreamableObjects); - - const float fMeshStreamingMaxIImportance = 10.f; - - if (bSyncLoad) - { - // just put file offset into importance - for (int i = 0; i < nNumStreamableObjects; i++) - { - SStreamAbleObject& rObj = arrStreamableObjects[i]; - - if (!rObj.GetStreamAbleObject()->IsUnloadable()) - { - rObj.fCurImportance = fMeshStreamingMaxIImportance; - continue; - } - - string fileName; - rObj.GetStreamAbleObject()->GetStreamableName(fileName); - int nOffset = (int)(GetPak()->GetFileOffsetOnMedia(fileName.c_str()) / 1024); - rObj.fCurImportance = -(float)nOffset; - } - } - else - { - // use data of previous prediction round since current round is not finished yet - int nRoundId = CObjManager::m_nUpdateStreamingPrioriryRoundId - 1; - - for (int i = 0; i < nNumStreamableObjects; i++) - { - SStreamAbleObject& rObj = arrStreamableObjects[i]; - - if (!rObj.GetStreamAbleObject()->IsUnloadable()) - { - rObj.fCurImportance = fMeshStreamingMaxIImportance; - continue; - } - - // compute importance of objects for selected nRoundId - rObj.fCurImportance = -1000.f; - - IStreamable::SInstancePriorityInfo* pInfo = &(rObj.GetStreamAbleObject()->m_arrUpdateStreamingPrioriryRoundInfo[0]); - - for (int nRoundIdx = 0; nRoundIdx < 2; nRoundIdx++) - { - if (pInfo[nRoundIdx].nRoundId == nRoundId) - { - rObj.fCurImportance = pInfo[nRoundIdx].fMaxImportance; - if (rObj.GetLastDrawMainFrameId() > (passInfo.GetMainFrameID() - GetCVars()->e_RNTmpDataPoolMaxFrames)) - { - rObj.fCurImportance += GetFloatCVar(e_StreamCgfVisObjPriority); - } - break; - } - } - } - } - - std::sort(&arrStreamableObjects[0], &arrStreamableObjects[nNumStreamableObjects], CObjManager_Cmp_Streamable_Priority()); - - fLastTime = fTime; - } -} - -void CObjManager::ProcessObjectsStreaming_Release() -{ - FRAME_PROFILER("ProcessObjectsStreaming_Release", GetSystem(), PROFILE_3DENGINE); - int nMemoryUsage = 0; - - int nNumStreamableObjects = m_arrStreamableObjects.Count(); - SStreamAbleObject* arrStreamableObjects = nNumStreamableObjects ? &m_arrStreamableObjects[0] : NULL; - - for (int nObjId = 0; nObjId < nNumStreamableObjects; nObjId++) - { - const SStreamAbleObject& rObj = arrStreamableObjects[nObjId]; - - nMemoryUsage += rObj.GetStreamableContentMemoryUsage(); - - bool bUnload = nMemoryUsage >= GetCVars()->e_StreamCgfPoolSize * 1024 * 1024; - - if (!bUnload && GetCVars()->e_StreamCgfDebug == 4) - { - if (rObj.GetStreamAbleObject()->m_arrUpdateStreamingPrioriryRoundInfo[0].nRoundId < (CObjManager::m_nUpdateStreamingPrioriryRoundId - 8)) - { - bUnload = true; - } - } - - if (bUnload && rObj.GetStreamAbleObject()->IsUnloadable()) - { - if (rObj.GetStreamAbleObject()->m_eStreamingStatus == ecss_Ready) - { - m_arrStreamableToRelease.push_back(rObj.GetStreamAbleObject()); - } - - // remove from list if not active for long time - if (rObj.GetStreamAbleObject()->m_eStreamingStatus == ecss_NotLoaded) - { - if (rObj.GetStreamAbleObject()->m_arrUpdateStreamingPrioriryRoundInfo[0].nRoundId < (CObjManager::m_nUpdateStreamingPrioriryRoundId - 8)) - { - rObj.GetStreamAbleObject()->m_arrUpdateStreamingPrioriryRoundInfo[0].nRoundId = 0; - m_arrStreamableToDelete.push_back(rObj.GetStreamAbleObject()); - } - } - } - } - s_nLastStreamingMemoryUsage = nMemoryUsage; -} - -void CObjManager::ProcessObjectsStreaming_InitLoad(bool bSyncLoad) -{ - FRAME_PROFILER("ProcessObjectsStreaming_InitLoad", GetSystem(), PROFILE_3DENGINE); - - int nMaxInProgress = GetCVars()->e_StreamCgfMaxTasksInProgress; - int nMaxToStart = GetCVars()->e_StreamCgfMaxNewTasksPerUpdate; - int nMaxMemUsage = GetCVars()->e_StreamCgfPoolSize * 1024 * 1024; - int nNumStreamableObjects = m_arrStreamableObjects.Count(); - SStreamAbleObject* arrStreamableObjects = nNumStreamableObjects ? &m_arrStreamableObjects[0] : NULL; - - int nMemoryUsage = 0; - int nInProgress = 0; - int nInProgressMem = 0; - int nStarted = 0; - - SMeshPoolStatistics stats; - GetRenderer()->EF_Query(EFQ_GetMeshPoolInfo, stats); - size_t poolLimit = stats.nPoolSize << 2; // 4 times the pool limit because the rendermesh pool has been reduced - - for (int nObjId = 0; nObjId < nNumStreamableObjects; nObjId++) - { - const SStreamAbleObject& rObj = m_arrStreamableObjects[nObjId]; - if (rObj.GetStreamAbleObject()->m_eStreamingStatus == ecss_InProgress) - { - nInProgress++; - nInProgressMem += rObj.GetStreamableContentMemoryUsage(); - } - } - - for (int nObjId = 0; (nObjId < nNumStreamableObjects) && ((nInProgress < nMaxInProgress && (nInProgressMem < static_cast(poolLimit) || !poolLimit) && nStarted < nMaxToStart) || bSyncLoad); nObjId++) - { - const SStreamAbleObject& rObj = arrStreamableObjects[nObjId]; - IStreamable* pStatObj = rObj.GetStreamAbleObject(); - - int size = rObj.GetStreamableContentMemoryUsage(); - if (poolLimit && poolLimit <= (size_t)(nInProgressMem + size)) - { - // Actually the above check is an implicit size limit on CGFs - which is awful because it can lead to meshes never - // streamed in. This has to change after crysis2 - for now, this will include a white list of meshes that need to be - // loaded for crysis2 in the prism2 level. - if ((size_t)poolLimit <= (size_t)size) - { - string name; - pStatObj->GetStreamableName(name); - CryLogAlways("[WARNING] object '%s' skipped because too large (%d kb (>= %" PRISIZE_T " kb limit))", name.c_str(), size / 1024, poolLimit / 1024); - continue; - } - - if (!bSyncLoad) - { - continue; - } - } - - nMemoryUsage += size; - if (nMemoryUsage >= nMaxMemUsage) - { - break; - } - - if (rObj.GetStreamAbleObject()->m_eStreamingStatus == ecss_NotLoaded) - { - m_arrStreamableToLoad.push_back(rObj.GetStreamAbleObject()); - nInProgressMem += size; - ++nInProgress; - ++nStarted; - - if ((GetCVars()->e_AutoPrecacheCgf == 2) && (nObjId > nNumStreamableObjects / 2)) - { - break; - } - } - } -} - -void CObjManager::ProcessObjectsStreaming_Finish() -{ - if (m_bNeedProcessObjectsStreaming_Finish == false) - { - return; - } - - LOADING_TIME_PROFILE_SECTION; - - m_bNeedProcessObjectsStreaming_Finish = false; - - FRAME_PROFILER("ProcessObjectsStreaming_Finish", GetSystem(), PROFILE_3DENGINE); - bool bSyncLoad = Get3DEngine()->IsStatObjSyncLoad(); - - { - LOADING_TIME_PROFILE_SECTION; - - // now unload the stat object - while (!m_arrStreamableToRelease.empty()) - { - IStreamable* pStatObj = m_arrStreamableToRelease.back(); - m_arrStreamableToRelease.DeleteLast(); - if (pStatObj) - { - pStatObj->ReleaseStreamableContent(); - -#ifdef OBJMAN_STREAM_STATS - if (m_pStreamListener) - { - m_pStreamListener->OnUnloadedStreamedObject(pStatObj); - } -#endif - - if (GetCVars()->e_StreamCgfDebug == 2) - { - string sName; - pStatObj->GetStreamableName(sName); - PrintMessage("Unloaded: %s", sName.c_str()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "ProcessObjectsStreaming_Finish is trying to release streamable content of a deleted pStatObj"); - } - } - - int nSyncObjCounter = 0; - - // start streaming of stat objects - if (bSyncLoad) - { - gEnv->pRenderer->EnableBatchMode(true); - } - - //const uint nMaxNumberOfSyncStreamingRequests = GetCVars()->e_AutoPrecacheCgfMaxTasks; - - std::vector streamsToFinish; - - GetISystem()->GetStreamEngine()->BeginReadGroup(); // Make sure new streaming requests are accumulated - - for (size_t nId = 0; nId < m_arrStreamableToLoad.size(); nId++) - { - IStreamable* pStatObj = m_arrStreamableToLoad[nId]; - - // If there is a rendermesh pool present, only submit streaming job if - // the pool size in the renderer is sufficient. NOTE: This is a weak - // test. Better test would be to actually preallocate the memory here and - // only submit the streaming job if the memory could be obtained. - - if (GetCVars()->e_StreamCgfDebug == 2) - { - string sName; - pStatObj->GetStreamableName(sName); - PrintMessage("Loading: %s", sName.c_str()); - } - - pStatObj->StartStreaming(false, NULL); - -#ifdef OBJMAN_STREAM_STATS - if (m_pStreamListener) - { - m_pStreamListener->OnRequestedStreamedObject(pStatObj); - } -#endif - } - - GetISystem()->GetStreamEngine()->EndReadGroup(); // Make sure new streaming requests are accumulated - - if (bSyncLoad) - { - gEnv->pRenderer->EnableBatchMode(false); - } - - if (bSyncLoad && nSyncObjCounter) - { - PrintMessage("Finished synchronous pre-cache of render meshes for %d CGF's", nSyncObjCounter); - } - - m_arrStreamableToLoad.clear(); - - // remove no longer needed objects from list - while (!m_arrStreamableToDelete.empty()) - { - IStreamable* pStatObj = m_arrStreamableToDelete.back(); - m_arrStreamableToDelete.DeleteLast(); - SStreamAbleObject stramAbleObject(pStatObj); - m_arrStreamableObjects.Delete(stramAbleObject); - -#ifdef OBJMAN_STREAM_STATS - if (m_pStreamListener) - { - m_pStreamListener->OnDestroyedStreamedObject(pStatObj); - } -#endif - } - } -} - -#ifdef OBJMAN_STREAM_STATS -void CObjManager::ProcessObjectsStreaming_Stats(const SRenderingPassInfo& passInfo) -{ - IStreamedObjectListener* pListener = m_pStreamListener; - if (!pListener) - { - return; - } - - int nNumStreamableObjects = m_arrStreamableObjects.Count(); - SStreamAbleObject* arrStreamableObjects = nNumStreamableObjects ? &m_arrStreamableObjects[0] : NULL; - - int nCurrentFrameId = passInfo.GetMainFrameID(); - - void* pBegunUse[512]; - void* pEndUse[512]; - - int nBegunUse = 0; - int nEndUse = 0; - - for (int nObjId = 0; nObjId < nNumStreamableObjects; nObjId++) - { - const SStreamAbleObject& rObj = arrStreamableObjects[nObjId]; - IStreamable* pObj = rObj.GetStreamAbleObject(); - - if (pObj->m_eStreamingStatus == ecss_Ready) - { - int framesSinceLastUse = nCurrentFrameId - pObj->GetLastDrawMainFrameId(); - - if (framesSinceLastUse < 2) - { - if (!pObj->m_nStatsInUse) - { - pObj->m_nStatsInUse = 1; - pBegunUse[nBegunUse++] = pObj; - - IF_UNLIKELY (nBegunUse == sizeof(pBegunUse) / sizeof(pBegunUse[0])) - { - pListener->OnBegunUsingStreamedObjects(pBegunUse, nBegunUse); - nBegunUse = 0; - } - } - } - else - { - if (pObj->m_nStatsInUse) - { - pObj->m_nStatsInUse = 0; - pEndUse[nEndUse++] = pObj; - - IF_UNLIKELY (nEndUse == sizeof(pEndUse) / sizeof(pEndUse[0])) - { - pListener->OnEndedUsingStreamedObjects(pEndUse, nEndUse); - nEndUse = 0; - } - } - } - } - } - - if (nBegunUse) - { - pListener->OnBegunUsingStreamedObjects(pBegunUse, nBegunUse); - } - - if (nEndUse) - { - pListener->OnEndedUsingStreamedObjects(pEndUse, nEndUse); - } -} -#endif - -void CObjManager::GetObjectsStreamingStatus(I3DEngine::SObjectsStreamingStatus& outStatus) -{ - outStatus.nReady = outStatus.nInProgress = outStatus.nTotal = outStatus.nAllocatedBytes = outStatus.nMemRequired = 0; - outStatus.nMeshPoolSize = GetCVars()->e_StreamCgfPoolSize; - - for (LoadedObjects::iterator it = m_lstLoadedObjects.begin(); it != m_lstLoadedObjects.end(); ++it) - { - IStatObj* pStatObj = *it; - if (pStatObj->IsSubObject()) - { - continue; - } - - if (pStatObj->GetLodLevel0()) - { - continue; - } - - for (int l = 0; l < MAX_STATOBJ_LODS_NUM; l++) - { - if (CStatObj* pLod = (CStatObj*)pStatObj->GetLodObject(l)) - { - outStatus.nTotal++; - } - } - } - - outStatus.nActive = m_arrStreamableObjects.Count(); - - for (int nObjId = 0; nObjId < m_arrStreamableObjects.Count(); nObjId++) - { - const SStreamAbleObject& rStreamAbleObject = m_arrStreamableObjects[nObjId]; - - if (rStreamAbleObject.GetStreamAbleObject()->m_eStreamingStatus == ecss_Ready) - { - outStatus.nReady++; - } - - if (rStreamAbleObject.GetStreamAbleObject()->m_eStreamingStatus == ecss_InProgress) - { - outStatus.nInProgress++; - } - - if (rStreamAbleObject.GetStreamAbleObject()->m_eStreamingStatus == ecss_Ready) - { - outStatus.nAllocatedBytes += rStreamAbleObject.GetStreamableContentMemoryUsage(); - } - - if (rStreamAbleObject.GetStreamAbleObject()->m_arrUpdateStreamingPrioriryRoundInfo[0].nRoundId >= (CObjManager::m_nUpdateStreamingPrioriryRoundId - 4)) - { - outStatus.nMemRequired += rStreamAbleObject.GetStreamableContentMemoryUsage(); - } - } -} - -void CObjManager::PrecacheStatObjMaterial(_smart_ptr pMaterial, const float fEntDistance, IStatObj* pStatObj, bool bFullUpdate, bool bDrawNear) -{ - // FUNCTION_PROFILER_3DENGINE; - - if (!pMaterial && pStatObj) - { - pMaterial = pStatObj->GetMaterial(); - } - - if (!pMaterial) - { - return; - } - - if (pStatObj) - { - for (int i = 0; i < pStatObj->GetSubObjectCount(); i++) - { - PrecacheStatObjMaterial(pMaterial, fEntDistance, pStatObj->GetSubObject(i)->pStatObj, bFullUpdate, bDrawNear); - } - } - - if (CMatInfo* pMatInfo = static_cast(pMaterial.get())) - { - pMatInfo->PrecacheMaterial(fEntDistance, (pStatObj ? pStatObj->GetRenderMesh() : NULL), bFullUpdate, bDrawNear); - } -} - -namespace -{ - void CollectRenderMeshMaterials(_smart_ptr pMaterial, IRenderMesh* pRenderMesh, std::vector, float> >& collectedMaterials) - { - if (!pMaterial || !pRenderMesh) - { - return; - } - - stl::push_back_unique(collectedMaterials, std::pair<_smart_ptr, float>(pMaterial, 1.0f)); - - TRenderChunkArray& chunks = pRenderMesh->GetChunks(); - const uint subMtlCount = pMaterial->GetSubMtlCount(); - - const uint numChunks = chunks.size(); - for (uint i = 0; i < numChunks; ++i) - { - CRenderChunk& chunk = chunks[i]; - if (chunk.nNumIndices > 0 && chunk.nNumVerts > 0 && chunk.m_nMatID < subMtlCount) - { - stl::push_back_unique(collectedMaterials, std::pair<_smart_ptr, float>(pMaterial->GetSubMtl(chunk.m_nMatID), chunk.m_texelAreaDensity)); - } - } - } -} - -void CObjManager::PrecacheStatObj(IStatObj* pStatObj, int nLod, const Matrix34A& statObjMatrix, _smart_ptr pMaterial, float fImportance, float fEntDistance, bool bFullUpdate, bool bHighPriority) -{ - if (!pStatObj) - { - return; - } - - const int minLod = pStatObj->GetMinUsableLod(); - const int maxLod = (int)pStatObj->GetMaxUsableLod(); - const int minPrecacheLod = clamp_tpl(nLod - 1, minLod, maxLod); - const int maxPrecacheLod = clamp_tpl(nLod + 1, minLod, maxLod); - - for (int currentLod = minPrecacheLod; currentLod <= maxPrecacheLod; ++currentLod) - { - IStatObj* pLodStatObj = pStatObj->GetLodObject(currentLod, true); - _smart_ptr pLodMaterial = pLodStatObj->GetMaterial(); - PrecacheStatObjMaterial(pMaterial ? pMaterial : pLodMaterial, fEntDistance, pLodStatObj, bFullUpdate, bHighPriority); - pStatObj->UpdateStreamableComponents(fImportance, statObjMatrix, bFullUpdate, nLod); - } -} - -void CObjManager::UpdateRenderNodeStreamingPriority(IRenderNode* pObj, float fEntDistanceReal, float fImportanceFactor, bool bFullUpdate, const SRenderingPassInfo& passInfo, bool bHighPriority) -{ - // FUNCTION_PROFILER_3DENGINE; - - if (pObj->m_dwRndFlags & ERF_HIDDEN) - { - return; - } - - if (pObj->m_fWSMaxViewDist < 0.01f) - { - return; - } - - // check cvars - const EERType nodeType = pObj->GetRenderNodeType(); - - const float fEntDistance = max(0.f, fEntDistanceReal - GetFloatCVar(e_StreamPredictionDistanceNear)); - - float fImportance = (1.f - (fEntDistance / ((pObj->m_fWSMaxViewDist + GetFloatCVar(e_StreamPredictionDistanceFar))))) * fImportanceFactor; - - if (fImportance < 0) - { - return; - } - - float fObjScale = 1.f; - AABB objBox(pObj->GetBBox()); - - switch (nodeType) - { - case eERType_Decal: - if (!passInfo.RenderDecals()) - { - return; - } - fObjScale = max(0.001f, ((CDecalRenderNode*)pObj)->CDecalRenderNode::GetMatrix().GetColumn0().GetLength()); - break; - case eERType_WaterVolume: - if (!passInfo.RenderWaterVolumes()) - { - return; - } - break; - case eERType_Light: - if (!GetCVars()->e_DynamicLights) - { - return; - } - break; - case eERType_FogVolume: - fObjScale = max(0.001f, ((CFogVolumeRenderNode*)pObj)->CFogVolumeRenderNode::GetMatrix().GetColumn0().GetLength()); - break; - case eERType_Cloud: - case eERType_DistanceCloud: - fObjScale = max(0.001f, pObj->GetBBox().GetRadius()); - break; -#if defined(USE_GEOM_CACHES) - case eERType_GeomCache: - if (!passInfo.RenderGeomCaches()) - { - return; - } - fObjScale = max(0.001f, ((CGeomCacheRenderNode*)pObj)->CGeomCacheRenderNode::GetMatrix().GetColumn0().GetLength()); -#endif - default: - if (!passInfo.RenderEntities()) - { - return; - } - break; - } - - float fInvObjScale = 1.0f / fObjScale; - int nLod = CObjManager::GetObjectLOD(pObj, fEntDistanceReal); - _smart_ptr pRenderNodeMat = pObj->GetMaterialOverride(); - - if (pObj->m_pRNTmpData) - { - if IsCVarConstAccess(constexpr) (GetFloatCVar(e_StreamCgfGridUpdateDistance) != 0.0f || GetFloatCVar(e_StreamPredictionAhead) != 0.0f || GetFloatCVar(e_StreamPredictionMinFarZoneDistance) != 0.0f) - { - float fDistanceToCam = sqrt_tpl(Distance::Point_AABBSq(passInfo.GetCamera().GetPosition(), objBox)) * passInfo.GetZoomFactor(); - pObj->m_pRNTmpData->userData.nWantedLod = CObjManager::GetObjectLOD(pObj, fDistanceToCam); - } - else - { - pObj->m_pRNTmpData->userData.nWantedLod = nLod; - } - } - - const int nSlotCount = pObj->GetSlotCount(); - for (int nEntSlot = 0; nEntSlot < nSlotCount; ++nEntSlot) - { - bool bDrawNear = false; - - _smart_ptr pSlotMat = pObj->GetEntitySlotMaterial(nEntSlot, false, &bDrawNear); - if (!pSlotMat) - { - pSlotMat = pRenderNodeMat; - } - - // If the object is in camera space, don't use the prediction position. - const float fEntPrecacheDistance = (bDrawNear) - ? sqrt_tpl(Distance::Point_AABBSq(passInfo.GetCamera().GetPosition(), objBox)) - : fEntDistance; - - bDrawNear |= bHighPriority; - - Matrix34A matParent; - CStatObj* pStatObj = (CStatObj*)pObj->GetEntityStatObj(nEntSlot, 0, &matParent, false); - if (pStatObj) - { - _smart_ptr pStatObjMat = pStatObj->GetMaterial(); - PrecacheStatObj(pStatObj, nLod, matParent, pSlotMat ? pSlotMat : pStatObjMat, fImportance, fEntDistanceReal * fInvObjScale, bFullUpdate, bHighPriority); - } - -#if defined(USE_GEOM_CACHES) - //This is the legacy case where the CGeomCacheRenderNode is a slot in a CComponentRenderer - else if (CGeomCacheRenderNode* pGeomCacheRenderNode = static_cast(pObj->GetGeomCacheRenderNode(nEntSlot, &matParent, false))) - { - pGeomCacheRenderNode->UpdateStreamableComponents(fImportance, fEntDistance, bFullUpdate, nLod, fInvObjScale, bFullUpdate); - } - //For the newer AZ systems CGeomCacheRenderNodes are not tied to the CComponentRenderer - else if (nodeType == eERType_GeomCache) - { - CGeomCacheRenderNode* geomCacheRenderNode = static_cast(pObj); - geomCacheRenderNode->UpdateStreamableComponents(fImportance, fEntDistance, bFullUpdate, nLod, fInvObjScale, bFullUpdate); - } -#endif - else if (pSlotMat) - { - pSlotMat->PrecacheMaterial(fEntDistance * fInvObjScale, pObj->GetRenderMesh(nLod), bFullUpdate, bHighPriority); - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree.cpp b/Code/CryEngine/Cry3DEngine/ObjectsTree.cpp deleted file mode 100644 index 1c4427f3a0..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree.cpp +++ /dev/null @@ -1,1824 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "CullBuffer.h" -#include "DecalRenderNode.h" -#include "RenderMeshMerger.h" -#include "DecalManager.h" -#include "VisAreas.h" -#include "LightEntity.h" -#include "WaterVolumeRenderNode.h" -#include "DistanceCloudRenderNode.h" -#include "ShadowCache.h" -#include "Ocean.h" -#include "IShader.h" -#include - -#include - -#define MAX_NODE_NUM 7 - -const float fNodeMinSize = 8.f; -const float fObjectToNodeSizeRatio = 1.f / 8.f; -const float fMinShadowCasterViewDist = 8.f; - -PodArray COctreeNode::m_arrEmptyNodes; -bool COctreeNode::m_removeVegetationCastersOneByOne = true; - -COctreeNode::~COctreeNode() -{ - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode, * pNext; pObj; pObj = pNext) - { - pNext = pObj->m_pNext; - - if (pObj->IsAllocatedOutsideOf3DEngineDLL()) - { - Get3DEngine()->UnRegisterEntityDirect(pObj); - } - else - { - pObj->ReleaseNode(true); - } - } - - assert(!m_arrObjects[l].m_pFirstNode); - } - - for (int i = 0; i < 8; i++) - { - delete m_arrChilds[i]; - m_arrChilds[i] = NULL; - } - - m_arrEmptyNodes.Delete(this); - - if (GetObjManager()) - { - GetObjManager()->GetArrStreamingNodeStack().Delete(this); - } - - if (m_pRNTmpData) - { - Get3DEngine()->FreeRNTmpData(&m_pRNTmpData); - } -} - -void COctreeNode::SetVisArea(CVisArea* pVisArea) -{ - m_pVisArea = pVisArea; - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->SetVisArea(pVisArea); - } - } -} - - -extern float arrVegetation_fSpriteSwitchState[nThreadsNum]; - - -void COctreeNode::Render_Object_Nodes(bool bNodeCompletelyInFrustum, int nRenderMask, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter) -{ - assert(nRenderMask & OCTREENODE_RENDER_FLAG_OBJECTS); - - const CCamera& rCam = passInfo.GetCamera(); - - if (m_nOccludedFrameId == passInfo.GetFrameID()) - { - return; - } - - if (!bNodeCompletelyInFrustum && !rCam.IsAABBVisible_EH(m_objectsBox, &bNodeCompletelyInFrustum)) - { - return; - } - - const Vec3& vCamPos = rCam.GetPosition(); - - float fNodeDistanceSq = Distance::Point_AABBSq(vCamPos, m_objectsBox) * sqr(passInfo.GetZoomFactor()); - - if (fNodeDistanceSq > sqr(m_fObjectsMaxViewDist)) - { - return; - } - - float fNodeDistance = sqrt_tpl(fNodeDistanceSq); - - Get3DEngine()->CheckCreateRNTmpData(&m_pRNTmpData, NULL, passInfo); - - if (m_nLastVisFrameId != passInfo.GetFrameID() && m_pParent) - { - if (GetObjManager()->IsBoxOccluded(m_objectsBox, fNodeDistance, &m_pRNTmpData->userData.m_OcclState, m_pVisArea != NULL, eoot_OCCELL, passInfo)) - { - m_nOccludedFrameId = passInfo.GetFrameID(); - return; - } - } - - m_nLastVisFrameId = passInfo.GetFrameID(); - - if (GetCVars()->e_ObjectsTreeBBoxes) - { - if (GetCVars()->e_ObjectsTreeBBoxes == 1) - { - const AABB& nodeBox = GetNodeBox(); - DrawBBox(nodeBox, Col_Blue); - } - if (GetCVars()->e_ObjectsTreeBBoxes == 2) - { - DrawBBox(m_objectsBox, Col_Red); - } - } - - m_fNodeDistance = fNodeDistance; - m_bNodeCompletelyInFrustum = bNodeCompletelyInFrustum; - - if (HasAnyRenderableCandidates(passInfo)) - { - // when using the occlusion culler, push the work to the jobs doing the occlusion checks, else just compute in main thread - if (GetCVars()->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass()) - { - GetObjManager()->PushIntoCullQueue(SCheckOcclusionJobData::CreateOctreeJobData(this, nRenderMask, rendItemSorter, &passInfo.GetCamera())); - } - else - { - RenderContentJobEntry(nRenderMask, passInfo, rendItemSorter, &passInfo.GetCamera()); - } - - rendItemSorter.IncreaseOctreeCounter(); - } - - int nFirst = - ((vCamPos.x > m_vNodeCenter.x) ? 4 : 0) | - ((vCamPos.y > m_vNodeCenter.y) ? 2 : 0) | - ((vCamPos.z > m_vNodeCenter.z) ? 1 : 0); - - if (m_arrChilds[nFirst ]) - { - m_arrChilds[nFirst ]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 1]) - { - m_arrChilds[nFirst ^ 1]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 2]) - { - m_arrChilds[nFirst ^ 2]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 4]) - { - m_arrChilds[nFirst ^ 4]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 3]) - { - m_arrChilds[nFirst ^ 3]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 5]) - { - m_arrChilds[nFirst ^ 5]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 6]) - { - m_arrChilds[nFirst ^ 6]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } - - if (m_arrChilds[nFirst ^ 7]) - { - m_arrChilds[nFirst ^ 7]->Render_Object_Nodes(bNodeCompletelyInFrustum, nRenderMask, passInfo, rendItemSorter); - } -} - -void COctreeNode::CompileObjects() -{ - FUNCTION_PROFILER_3DENGINE; - - m_lstCasters.Clear(); - - m_bStaticInstancingIsDirty = true; - - float fObjMaxViewDistance = 0; - - size_t numCasters = 0; - const unsigned int nSkipShadowCastersRndFlags = ERF_HIDDEN | ERF_COLLISION_PROXY | ERF_RAYCAST_PROXY | ERF_STATIC_INSTANCING; // shadow casters with these render flags are ignored - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - int nFlags = pObj->GetRndFlags(); - - IF (nFlags & nSkipShadowCastersRndFlags, 0) - { - continue; - } - - IF (GetCVars()->e_ShadowsPerObject && gEnv->p3DEngine->GetPerObjectShadow(pObj), 0) - { - continue; - } - - EERType eRType = pObj->GetRenderNodeType(); - float WSMaxViewDist = pObj->GetMaxViewDist(); - - if (nFlags & ERF_CASTSHADOWMAPS && WSMaxViewDist > fMinShadowCasterViewDist && eRType != eERType_Light) - { - ++numCasters; - } - } - } - - m_lstCasters.reserve(numCasters); - - - // update node - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode, * pNext; pObj; pObj = pNext) - { - pNext = pObj->m_pNext; - - IF (pObj->m_dwRndFlags & ERF_HIDDEN, 0) - { - continue; - } - - EERType eRType = pObj->GetRenderNodeType(); - - // update max view distances - const float fNewMaxViewDist = pObj->GetMaxViewDist(); - pObj->m_fWSMaxViewDist = fNewMaxViewDist; - - // update REQUIRES_FORWARD_RENDERING flag - //IF(GetCVars()->e_ShadowsOnAlphaBlend,0) - { - pObj->m_nInternalFlags &= ~(IRenderNode::REQUIRES_FORWARD_RENDERING | IRenderNode::REQUIRES_NEAREST_CUBEMAP); - if (eRType != eERType_Light && - eRType != eERType_Cloud && - eRType != eERType_FogVolume && - eRType != eERType_Decal && - eRType != eERType_DistanceCloud) - { - if (CMatInfo* pMatInfo = (CMatInfo*)pObj->GetMaterial().get()) - { - if (pMatInfo->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - - if (pMatInfo->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - - if (eRType == eERType_RenderComponent ||eRType == eERType_StaticMeshRenderComponent || eRType == eERType_DynamicMeshRenderComponent || eRType == eERType_SkinnedMeshRenderComponent) - { - int nSlotCount = pObj->GetSlotCount(); - - for (int s = 0; s < nSlotCount; s++) - { - if (CMatInfo* pMat = (CMatInfo*)pObj->GetEntitySlotMaterial(s).get()) - { - if (pMat->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - if (pMat->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - - if (IStatObj* pStatObj = pObj->GetEntityStatObj(s)) - { - if (CMatInfo* pMat = (CMatInfo*)pStatObj->GetMaterial().get()) - { - if (pMat->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - if (pMat->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - } - } - } - } - } - - int nFlags = pObj->GetRndFlags(); - - // fill shadow casters list - const bool bHasPerObjectShadow = GetCVars()->e_ShadowsPerObject && gEnv->p3DEngine->GetPerObjectShadow(pObj); - if (!(nFlags & nSkipShadowCastersRndFlags) && nFlags & ERF_CASTSHADOWMAPS && fNewMaxViewDist > fMinShadowCasterViewDist && - eRType != eERType_Light && !bHasPerObjectShadow) - { - COctreeNode* pNode = this; - while (pNode && !(pNode->m_renderFlags & ERF_CASTSHADOWMAPS)) - { - pNode->m_renderFlags |= ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS; - pNode = pNode->m_pParent; - } - - float fMaxCastDist = fNewMaxViewDist * GetCVars()->e_ShadowsCastViewDistRatio; - m_lstCasters.Add(SCasterInfo(pObj, fMaxCastDist, eRType)); - } - - fObjMaxViewDistance = max(fObjMaxViewDistance, fNewMaxViewDist); - } - } - - if (fObjMaxViewDistance > m_fObjectsMaxViewDist) - { - COctreeNode* pNode = this; - while (pNode) - { - pNode->m_fObjectsMaxViewDist = max(pNode->m_fObjectsMaxViewDist, fObjMaxViewDistance); - pNode = pNode->m_pParent; - } - } - - const Vec3& sunDir = Get3DEngine()->GetSunDirNormalized(); - m_fpSunDirX = (uint32) (sunDir.x * 63.5f + 63.5f); - m_fpSunDirZ = (uint32) (sunDir.z * 63.5f + 63.5f); - m_fpSunDirYs = sunDir.y < 0.0f ? 1 : 0; -} - - -bool IsAABBInsideHull(const SPlaneObject* pHullPlanes, int nPlanesNum, const AABB& aabbBox); -bool IsSphereInsideHull(const SPlaneObject* pHullPlanes, int nPlanesNum, const Sphere& objSphere); - -void COctreeNode::FillShadowCastersList(bool bNodeCompletellyInFrustum, CDLight* pLight, ShadowMapFrustum* pFr, PodArray* pShadowHull, uint32 nRenderNodeFlags, const SRenderingPassInfo& passInfo) -{ - if (GetCVars()->e_Objects) - { - if (m_renderFlags & ERF_CASTSHADOWMAPS) - { - FRAME_PROFILER("COctreeNode::FillShadowMapCastersList", GetSystem(), PROFILE_3DENGINE); - - _MS_ALIGN(64) ShadowMapFrustumParams params; - params.pLight = pLight; - params.pFr = pFr; - params.pShadowHull = pShadowHull; - params.passInfo = &passInfo; - params.vCamPos = passInfo.GetCamera().GetPosition(); - params.bSun = (pLight->m_Flags & DLF_SUN) != 0; - params.nRenderNodeFlags = nRenderNodeFlags; - - FillShadowMapCastersList(params, bNodeCompletellyInFrustum); - } - } -} - -void COctreeNode::FillDepthCubemapRenderList(const AABB& cubemapAABB, const SRenderingPassInfo& passInfo, PodArray* objectsList) -{ - if (GetCVars()->e_Objects) - { - //get objects from this node - for (IRenderNode* obj = m_arrObjects[eRNListType_Unknown].m_pFirstNode; obj; obj = obj->m_pNext) - { - if (cubemapAABB.IsIntersectBox(obj->GetBBox())) - { - objectsList->Add(obj); - } - } - - //check child nodes - for (int i = 0; i <= MAX_NODE_NUM; i++) - { - const bool bPrefetch = i < MAX_NODE_NUM && !!m_arrChilds[i + 1]; - - if (m_arrChilds[i]) - { - m_arrChilds[i]->FillDepthCubemapRenderList(cubemapAABB, passInfo, objectsList); - } - } - } -} - -void COctreeNode::FillShadowMapCastersList(const ShadowMapFrustumParams& params, bool bNodeCompletellyInFrustum) -{ - if (!bNodeCompletellyInFrustum && !params.pFr->IntersectAABB(m_objectsBox, &bNodeCompletellyInFrustum)) - { - return; - } - - const int frameID = params.passInfo->GetFrameID(); - if (params.bSun && bNodeCompletellyInFrustum) - { - nFillShadowCastersSkipFrameId = frameID; - } - - if (params.pShadowHull && !IsAABBInsideHull(params.pShadowHull->GetElements(), params.pShadowHull->Count(), m_objectsBox)) - { - nFillShadowCastersSkipFrameId = frameID; - return; - } - - PrefetchLine(&m_lstCasters, 0); - - const float fShadowsCastViewDistRatio = GetCVars()->e_ShadowsCastViewDistRatio; - if (fShadowsCastViewDistRatio != 0.0f) - { - float fNodeDistanceSqr = Distance::Point_AABBSq(params.vCamPos, m_objectsBox); - if (fNodeDistanceSqr > sqr(m_fObjectsMaxViewDist * fShadowsCastViewDistRatio)) - { - nFillShadowCastersSkipFrameId = frameID; - return; - } - } - - PrefetchLine(m_lstCasters.begin(), 0); - PrefetchLine(m_lstCasters.begin(), 128); - - IRenderNode* pNotCaster = ((CLightEntity*)params.pLight->m_pOwner)->m_pNotCaster; - - SCasterInfo* pCastersEnd = m_lstCasters.end(); - for (SCasterInfo* pCaster = m_lstCasters.begin(); pCaster < pCastersEnd; pCaster++) - { - if (params.bSun && pCaster->nGSMFrameId == frameID && params.pShadowHull) - { - continue; - } - if (!IsRenderNodeTypeEnabled(pCaster->nRType)) - { - continue; - } - if (pCaster->pNode == NULL || pCaster->pNode == pNotCaster) - { - continue; - } - if ((pCaster->nRenderNodeFlags & params.nRenderNodeFlags) == 0) - { - continue; - } - - float fDistanceSq = Distance::Point_PointSq(params.vCamPos, pCaster->objSphere.center); - if (fDistanceSq > sqr(pCaster->fMaxCastingDist + pCaster->objSphere.radius)) - { - pCaster->nGSMFrameId = frameID; - continue; - } - - bool bObjCompletellyInFrustum = bNodeCompletellyInFrustum; - if (!bObjCompletellyInFrustum && !params.pFr->IntersectAABB(pCaster->objBox, &bObjCompletellyInFrustum)) - { - continue; - } - if (params.bSun && bObjCompletellyInFrustum) - { - pCaster->nGSMFrameId = frameID; - } - - if (params.bSun && bObjCompletellyInFrustum) - { - pCaster->nGSMFrameId = frameID; - } - if (params.pShadowHull && !IsSphereInsideHull(params.pShadowHull->GetElements(), params.pShadowHull->Count(), pCaster->objSphere)) - { - pCaster->nGSMFrameId = frameID; - continue; - } - - if (pCaster->bCanExecuteAsRenderJob) - { - Get3DEngine()->CheckCreateRNTmpData(&pCaster->pNode->m_pRNTmpData, pCaster->pNode, *params.passInfo); - params.pFr->m_jobExecutedCastersList.Add(pCaster->pNode); - } - else - { - params.pFr->m_castersList.Add(pCaster->pNode); - } - } - - for (int i = 0; i <= MAX_NODE_NUM; i++) - { - const bool bPrefetch = i < MAX_NODE_NUM && !!m_arrChilds[i + 1]; - - if (m_arrChilds[i] && (m_arrChilds[i]->m_renderFlags & ERF_CASTSHADOWMAPS) && (!params.bSun || !params.pShadowHull || m_arrChilds[i]->nFillShadowCastersSkipFrameId != frameID)) - { - m_arrChilds[i]->FillShadowMapCastersList(params, bNodeCompletellyInFrustum); - } - } -} - -AABB COctreeNode::GetShadowCastersBox(const AABB* pBBox, const Matrix34* pShadowSpaceTransform) -{ - AABB result(AABB::RESET); - if (!pBBox || Overlap::AABB_AABB(*pBBox, GetObjectsBBox())) - { - for (size_t i = 0; i < m_lstCasters.size(); ++i) - { - AABB casterBox = m_lstCasters[i].objBox; - if (!pBBox || Overlap::AABB_AABB(*pBBox, casterBox)) - { - if (pShadowSpaceTransform) - { - casterBox = AABB::CreateTransformedAABB(*pShadowSpaceTransform, casterBox); - } - - result.Add(casterBox); - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - result.Add(m_arrChilds[i]->GetShadowCastersBox(pBBox, pShadowSpaceTransform)); - } - } - } - - return result; -} - -COctreeNode* COctreeNode::FindNodeContainingBox(const AABB& objBox) -{ - { - const AABB& nodeBox = GetNodeBox(); - if (!nodeBox.IsContainSphere(objBox.min, -0.01f) || !nodeBox.IsContainSphere(objBox.max, -0.01f)) - { - return NULL; - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - if (COctreeNode* pFoundNode = m_arrChilds[i]->FindNodeContainingBox(objBox)) - { - return pFoundNode; - } - } - } - - return this; -} - -void COctreeNode::MoveObjectsIntoList(PodArray* plstResultEntities, const AABB* pAreaBox, - bool bRemoveObjects, bool bSkipDecals, bool bSkip_ERF_NO_DECALNODE_DECALS, bool bSkipDynamicObjects, - EERType eRNType) -{ - FUNCTION_PROFILER_3DENGINE; - - if (pAreaBox && !Overlap::AABB_AABB(m_objectsBox, *pAreaBox)) - { - return; - } - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode, * pNext; pObj; pObj = pNext) - { - pNext = pObj->m_pNext; - - if (eRNType < eERType_TypesNum && pObj->GetRenderNodeType() != eRNType) - { - continue; - } - - if (bSkipDecals && pObj->GetRenderNodeType() == eERType_Decal) - { - continue; - } - - if (bSkip_ERF_NO_DECALNODE_DECALS && pObj->GetRndFlags() & ERF_NO_DECALNODE_DECALS) - { - continue; - } - - if (bSkipDynamicObjects) - { - EERType eRType = pObj->GetRenderNodeType(); - - if (eRType == eERType_RenderComponent || eRType == eERType_DynamicMeshRenderComponent || eRType == eERType_SkinnedMeshRenderComponent) - { - if (pObj->IsMovableByGame()) - { - continue; - } - } - else if ( - eRType != eERType_StaticMeshRenderComponent) - { - continue; - } - } - - if (pAreaBox && !Overlap::AABB_AABB(pObj->GetBBox(), *pAreaBox)) - { - continue; - } - - if (bRemoveObjects) - { - UnlinkObject(pObj); - - CompileObjects(); - } - - plstResultEntities->Add(pObj); - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->MoveObjectsIntoList(plstResultEntities, pAreaBox, bRemoveObjects, bSkipDecals, bSkip_ERF_NO_DECALNODE_DECALS, bSkipDynamicObjects, eRNType); - } - } -} - -void COctreeNode::DeleteObjectsByFlag(int nRndFlag) -{ - FUNCTION_PROFILER_3DENGINE; - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode, * pNext; pObj; pObj = pNext) - { - pNext = pObj->m_pNext; - - if (pObj->GetRndFlags() & nRndFlag) - { - DeleteObject(pObj); - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->DeleteObjectsByFlag(nRndFlag); - } - } -} - -void COctreeNode::UnregisterEngineObjectsInArea(const SHotUpdateInfo* pExportInfo, PodArray& arrUnregisteredObjects, bool bOnlyEngineObjects) -{ - FUNCTION_PROFILER_3DENGINE; - - const AABB* pAreaBox = (pExportInfo && !pExportInfo->areaBox.IsReset()) ? &pExportInfo->areaBox : NULL; - - { - const AABB& nodeBox = GetNodeBox(); - if (pAreaBox && !Overlap::AABB_AABB(nodeBox, *pAreaBox)) - { - return; - } - } - - uint32 nObjTypeMask = pExportInfo ? pExportInfo->nObjTypeMask : (uint32) ~0; - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode, * pNext; pObj; pObj = pNext) - { - pNext = pObj->m_pNext; - - EERType eType = pObj->GetRenderNodeType(); - - if (bOnlyEngineObjects) - { - if (!(nObjTypeMask & (1 << eType))) - { - continue; - } - - if (eType == eERType_Decal || - eType == eERType_WaterVolume || - eType == eERType_DistanceCloud ) - { - Get3DEngine()->UnRegisterEntityAsJob(pObj); - arrUnregisteredObjects.Add(pObj); - CompileObjects(); - } - } - else - { - Get3DEngine()->UnRegisterEntityAsJob(pObj); - arrUnregisteredObjects.Add(pObj); - CompileObjects(); - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, bOnlyEngineObjects); - } - } -} - -int COctreeNode::GetObjectsCount(EOcTeeNodeListType eListType) -{ - int nCount = 0; - - switch (eListType) - { - case eMain: - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - nCount++; - } - } - break; - case eCasters: - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->GetRndFlags() & ERF_CASTSHADOWMAPS) - { - nCount++; - } - } - } - break; - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - nCount += m_arrChilds[i]->GetObjectsCount(eListType); - } - } - - return nCount; -} - - -void COctreeNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - pObj->GetMemoryUsage(pSizer); - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "ObjLists"); - - pSizer->AddObject(m_lstCasters); - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetMemoryUsage(pSizer); - } - } - - if (pSizer) - { - pSizer->AddObject(this, sizeof(*this)); - } -} - -void C3DEngine::GetObjectsByTypeGlobal(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback) -{ - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->GetObjectsByType(lstObjects, objType, pBBox, filterCallback); - } -} - -void C3DEngine::MoveObjectsIntoListGlobal(PodArray* plstResultEntities, const AABB* pAreaBox, - bool bRemoveObjects, bool bSkipDecals, bool bSkip_ERF_NO_DECALNODE_DECALS, bool bSkipDynamicObjects, - EERType eRNType) -{ - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->MoveObjectsIntoList(plstResultEntities, pAreaBox, bRemoveObjects, bSkipDecals, bSkip_ERF_NO_DECALNODE_DECALS, bSkipDynamicObjects, eRNType); - } -} - -void COctreeNode::ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, IGeneralMemoryHeap* pHeap) -{ - for (IRenderNode* pObj = m_arrObjects[eRNListType_DecalsAndRoads].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - EERType eType = pObj->GetRenderNodeType(); - - if (eType == eERType_Decal) - { - CDecalRenderNode* pDecal = (CDecalRenderNode*)pObj; - if (pDecal->GetLayerId() == nLayerId || nLayerId == uint16(~0)) - { - pDecal->SetRndFlags(ERF_HIDDEN, !bActivate); - - if (bActivate) - { - pDecal->RequestUpdate(); - } - else - { - pDecal->DeleteDecal(); - } - } - } - } - - for (IRenderNode* pObj = m_arrObjects[eRNListType_Unknown].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->GetRenderNodeType() == eERType_WaterVolume) - { - CWaterVolumeRenderNode* pWatVol = (CWaterVolumeRenderNode*)pObj; - if (pWatVol->GetLayerId() == nLayerId || nLayerId == uint16(~0)) - { - pWatVol->SetRndFlags(ERF_HIDDEN, !bActivate); - - if (GetCVars()->e_ObjectLayersActivationPhysics) - { - if (bActivate && bPhys) - { - pWatVol->Physicalize(); - } - else - { - pWatVol->Dephysicalize(); - } - } - else if (!bPhys) - { - pWatVol->Dephysicalize(); - } - } - } - - if (pObj->GetRenderNodeType() == eERType_DistanceCloud) - { - CDistanceCloudRenderNode* pCloud = (CDistanceCloudRenderNode*)pObj; - if (pCloud->GetLayerId() == nLayerId || nLayerId == uint16(~0)) - { - pCloud->SetRndFlags(ERF_HIDDEN, !bActivate); - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap); - } - } -} - -void COctreeNode::GetLayerMemoryUsage(uint16 nLayerId, ICrySizer* pSizer, int* pNumBrushes, int* pNumDecals) -{ - for (IRenderNode* pObj = m_arrObjects[eRNListType_DecalsAndRoads].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - EERType eType = pObj->GetRenderNodeType(); - - if (eType == eERType_Decal) - { - CDecalRenderNode* pDecal = (CDecalRenderNode*)pObj; - if (pDecal->GetLayerId() == nLayerId || nLayerId == uint16(~0)) - { - pDecal->GetMemoryUsage(pSizer); - if (pNumDecals) - { - (*pNumDecals)++; - } - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetLayerMemoryUsage(nLayerId, pSizer, pNumBrushes, pNumDecals); - } - } -} - - -void COctreeNode::GetObjects(PodArray& lstObjects, const AABB* pBBox) -{ - if (pBBox && !Overlap::AABB_AABB(*pBBox, GetObjectsBBox())) - { - return; - } - - unsigned int nCurrentObject(eRNListType_First); - for (nCurrentObject = eRNListType_First; nCurrentObject < eRNListType_ListsNum; ++nCurrentObject) - { - for (IRenderNode* pObj = m_arrObjects[nCurrentObject].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (!pBBox || Overlap::AABB_AABB(*pBBox, pObj->GetBBox())) - { - lstObjects.Add(pObj); - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetObjects(lstObjects, pBBox); - } - } -} - -bool COctreeNode::GetShadowCastersTimeSliced(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int& totalRemainingNodes, int nCurLevel, const SRenderingPassInfo& passInfo) -{ - assert(pFrustum->pShadowCacheData); - - if (totalRemainingNodes <= 0) - { - return false; - } - - if (!pFrustum->pShadowCacheData->mOctreePathNodeProcessed[nCurLevel]) - { - if (pFrustum->aabbCasters.IsReset() || Overlap::AABB_AABB(pFrustum->aabbCasters, GetObjectsBBox())) - { - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pNode = m_arrObjects[l].m_pFirstNode; pNode; pNode = pNode->m_pNext) - { - if (!IsRenderNodeTypeEnabled(pNode->GetRenderNodeType())) - { - continue; - } - - if (pNode == pIgnoreNode) - { - continue; - } - - const int nFlags = pNode->GetRndFlags(); - if (nFlags & (ERF_HIDDEN | ERF_COLLISION_PROXY | ERF_RAYCAST_PROXY | renderNodeExcludeFlags)) - { - continue; - } - - // Ignore ERF_CASTSHADOWMAPS for ambient occlusion casters - if (pFrustum->m_eFrustumType != ShadowMapFrustum::e_HeightMapAO && (pNode->GetRndFlags() & ERF_CASTSHADOWMAPS) == 0) - { - continue; - } - - if (pFrustum->pShadowCacheData->mProcessedCasters.find(pNode) != pFrustum->pShadowCacheData->mProcessedCasters.end()) - { - continue; - } - - AABB objBox = pNode->GetBBox(); - const float fDistanceSq = Distance::Point_PointSq(passInfo.GetCamera().GetPosition(), objBox.GetCenter()); - const float fMaxDist = pNode->GetMaxViewDist() * GetCVars()->e_ShadowsCastViewDistRatio + objBox.GetRadius(); - - if (fDistanceSq > sqr(fMaxDist)) - { - continue; - } - - // find closest loaded lod - for (int nSlot = 0; nSlot < pNode->GetSlotCount(); ++nSlot) - { - bool bCanRender = false; - - if (IStatObj* pStatObj = pNode->GetEntityStatObj(nSlot)) - { - for (int i = 0; i < MAX_STATOBJ_LODS_NUM; ++i) - { - IStatObj* pLod = pStatObj->GetLodObject(i); - - if (pLod && pLod->m_eStreamingStatus == ecss_Ready) - { - bCanRender = true; - break; - } - } - } - - if (bCanRender) - { - if (pNode->CanExecuteRenderAsJob()) - { - Get3DEngine()->CheckCreateRNTmpData(&pNode->m_pRNTmpData, pNode, passInfo); - pFrustum->m_jobExecutedCastersList.Add(pNode); - } - else - { - pFrustum->m_castersList.Add(pNode); - } - } - } - } - } - } - - pFrustum->pShadowCacheData->mOctreePathNodeProcessed[nCurLevel] = true; - if (!pFrustum->m_castersList.IsEmpty() || !pFrustum->m_jobExecutedCastersList.IsEmpty()) - { - --totalRemainingNodes; - } - } - - - for (int i = pFrustum->pShadowCacheData->mOctreePath[nCurLevel]; i < 8; ++i) - { - if (m_arrChilds[i] && (m_arrChilds[i]->m_renderFlags & ERF_CASTSHADOWMAPS)) - { - bool bDone = m_arrChilds[i]->GetShadowCastersTimeSliced(pIgnoreNode, pFrustum, renderNodeExcludeFlags, totalRemainingNodes, nCurLevel + 1, passInfo); - - if (!bDone) - { - return false; - } - } - - pFrustum->pShadowCacheData->mOctreePath[nCurLevel] = i; - } - - // this subtree is fully processed: reset traversal state - pFrustum->pShadowCacheData->mOctreePath[nCurLevel] = 0; - pFrustum->pShadowCacheData->mOctreePathNodeProcessed[nCurLevel] = 0; - return true; -} - -bool COctreeNode::IsObjectTypeInTheBox(EERType objType, const AABB& WSBBox) -{ - if (!Overlap::AABB_AABB(WSBBox, GetObjectsBBox())) - { - return false; - } - - ERNListType eListType = IRenderNode::GetRenderNodeListId(objType); - - for (IRenderNode* pObj = m_arrObjects[eListType].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->GetRenderNodeType() == objType) - { - if (Overlap::AABB_AABB(WSBBox, pObj->GetBBox())) - { - return true; - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - if (m_arrChilds[i]->IsObjectTypeInTheBox(objType, WSBBox)) - { - return true; - } - } - } - - return false; -} - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - -bool COctreeNode::RayObjectsIntersection2D(Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, EERType eERType) -{ - FUNCTION_PROFILER_3DENGINE; - - // Vec3 vBoxHitPoint; - // if(!Intersect::Ray_AABB(Ray(vStart, vEnd-vStart), m_objectsBox, vBoxHitPoint)) - // return false; - - if (vStart.x > m_objectsBox.max.x || vStart.y > m_objectsBox.max.y || - vStart.x < m_objectsBox.min.x || vStart.y < m_objectsBox.min.y) - { - return false; - } - - const bool oceanEnabled = OceanToggle::IsActive() ? OceanRequest::OceanIsEnabled() : true; - float fOceanLevel = WATER_LEVEL_UNKNOWN; - if (OceanToggle::IsActive()) - { - fOceanLevel = OceanRequest::GetOceanLevel(); - } - else - { - fOceanLevel = m_pOcean ? m_pOcean->GetWaterLevel() : WATER_LEVEL_UNKNOWN; - } - - ERNListType eListType = IRenderNode::GetRenderNodeListId(eERType); - - for (IRenderNode* pObj = m_arrObjects[eListType].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - uint32 dwFlags = pObj->GetRndFlags(); - - if (dwFlags & ERF_HIDDEN || !(dwFlags & ERF_CASTSHADOWMAPS) || dwFlags & ERF_COLLISION_PROXY) - { - continue; - } - - if (pObj->GetRenderNodeType() != eERType) - { - continue; - } - - // if(!Intersect::Ray_AABB(Ray(vStart, vEnd-vStart), pObj->GetBBox(), vBoxHitPoint)) - // continue; - - const AABB& objBox = pObj->GetBBox(); - - if ((objBox.max.z - objBox.min.z) < 2.f) - { - continue; - } - - if (oceanEnabled && objBox.max.z < fOceanLevel) - { - continue; - } - - if (vStart.x > objBox.max.x || vStart.y > objBox.max.y || vStart.x < objBox.min.x || vStart.y < objBox.min.y) - { - continue; - } - - Matrix34A objMatrix; - CStatObj* pStatObj = (CStatObj*)pObj->GetEntityStatObj(0, 0, &objMatrix); - - if (pStatObj->GetOcclusionAmount() < 0.32f) - { - continue; - } - - { - if (pStatObj->m_nFlags & STATIC_OBJECT_HIDDEN) - { - continue; - } - - Matrix34 matInv = objMatrix.GetInverted(); - Vec3 vOSStart = matInv.TransformPoint(vStart); - Vec3 vOSEnd = matInv.TransformPoint(vEnd); - Vec3 vOSHitPoint(0, 0, 0), vOSHitNorm(0, 0, 0); - - Vec3 vBoxHitPoint; - if (!Intersect::Ray_AABB(Ray(vOSStart, vOSEnd - vOSStart), pStatObj->GetAABB(), vBoxHitPoint)) - { - continue; - } - - vOSHitPoint = vOSStart; - vOSHitPoint.z = pStatObj->GetObjectHeight(vOSStart.x, vOSStart.y); - - if (vOSHitPoint.z != 0) - { - Vec3 vHitPoint = objMatrix.TransformPoint(vOSHitPoint); - float fDist = vHitPoint.GetDistance(vStart); - if (fDist < fClosestHitDistance) - { - fClosestHitDistance = fDist; - vClosestHitPoint = vHitPoint; - } - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->RayObjectsIntersection2D(vStart, vEnd, vClosestHitPoint, fClosestHitDistance, eERType); - } - } - - return false; -} - -#endif - -void COctreeNode::GenerateStatObjAndMatTables(std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, std::vector* pStatInstGroupTable, SHotUpdateInfo* pExportInfo) -{ - //if eERType number is changed, have to check this code. - COMPILE_TIME_ASSERT(eERType_TypesNum == 28); - - AABB* pBox = (pExportInfo && !pExportInfo->areaBox.IsReset()) ? &pExportInfo->areaBox : NULL; - - if (pBox && !Overlap::AABB_AABB(GetNodeBox(), *pBox)) - { - return; - } - - uint32 nObjTypeMask = pExportInfo ? pExportInfo->nObjTypeMask : (uint32) ~0; - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - EERType eType = pObj->GetRenderNodeType(); - - if (!(nObjTypeMask & (1 << eType))) - { - continue; - } - - //Add static meshes that have static transforms to the - //static object table. - if (eType == eERType_StaticMeshRenderComponent) - { - if (CObjManager::GetItemId(pStatObjTable, pObj->GetEntityStatObj(), false) < 0) - { - pStatObjTable->push_back(pObj->GetEntityStatObj()); - } - } - - if (eType == eERType_Decal || - eType == eERType_WaterVolume || - eType == eERType_DistanceCloud || - eType == eERType_StaticMeshRenderComponent) - { - if (CObjManager::GetItemId(pMatTable, pObj->GetMaterial(), false) < 0) - { - pMatTable->push_back(pObj->GetMaterial()); - } - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo); - } - } -} - -int COctreeNode::Cmp_OctreeNodeSize(const void* v1, const void* v2) -{ - COctreeNode* pNode1 = *((COctreeNode**)v1); - COctreeNode* pNode2 = *((COctreeNode**)v2); - - if (pNode1->GetNodeRadius2() > pNode2->GetNodeRadius2()) - { - return +1; - } - if (pNode1->GetNodeRadius2() < pNode2->GetNodeRadius2()) - { - return -1; - } - - return 0; -} - -COctreeNode* COctreeNode::FindChildFor([[maybe_unused]] IRenderNode* pObj, [[maybe_unused]] const AABB& objBox, [[maybe_unused]] const float fObjRadius, const Vec3& vObjCenter) -{ - int nChildId = - ((vObjCenter.x > m_vNodeCenter.x) ? 4 : 0) | - ((vObjCenter.y > m_vNodeCenter.y) ? 2 : 0) | - ((vObjCenter.z > m_vNodeCenter.z) ? 1 : 0); - - if (!m_arrChilds[nChildId]) - { - m_arrChilds[nChildId] = COctreeNode::Create(m_nSID, GetChildBBox(nChildId), m_pVisArea, this); - } - - return m_arrChilds[nChildId]; -} - - -bool COctreeNode::HasChildNodes() -{ - if (!m_arrChilds[0] && !m_arrChilds[1] && !m_arrChilds[2] && !m_arrChilds[3]) - { - if (!m_arrChilds[4] && !m_arrChilds[5] && !m_arrChilds[6] && !m_arrChilds[7]) - { - return false; - } - } - - return true; -} - -int COctreeNode::CountChildNodes() -{ - return - (m_arrChilds[0] != 0) + - (m_arrChilds[1] != 0) + - (m_arrChilds[2] != 0) + - (m_arrChilds[3] != 0) + - (m_arrChilds[4] != 0) + - (m_arrChilds[5] != 0) + - (m_arrChilds[6] != 0) + - (m_arrChilds[7] != 0); -} - -void COctreeNode::ReleaseEmptyNodes() -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_arrEmptyNodes.Count()) - { - return; - } - - // sort childs first - qsort(m_arrEmptyNodes.GetElements(), m_arrEmptyNodes.Count(), sizeof(m_arrEmptyNodes[0]), Cmp_OctreeNodeSize); - - int nInitCount = m_arrEmptyNodes.Count(); - - for (int i = 0; i < nInitCount && m_arrEmptyNodes.Count(); i++) - { - COctreeNode* pNode = m_arrEmptyNodes[0]; - - if (pNode && pNode->IsEmpty()) - { - COctreeNode* pParent = pNode->m_pParent; - - // unregister in parent - for (int n = 0; n < 8; n++) - { - if (pParent->m_arrChilds[n] == pNode) - { - pParent->m_arrChilds[n] = NULL; - } - } - - delete pNode; - - // request parent validation - if (pParent && pParent->IsEmpty() && m_arrEmptyNodes.Find(pParent) < 0) - { - m_arrEmptyNodes.Add(pParent); - } - } - - // remove from list - m_arrEmptyNodes.Delete(pNode); - } -} - -void COctreeNode::StaticReset() -{ - ReleaseEmptyNodes(); - stl::free_container(m_arrEmptyNodes); -} - -static float Distance_PrecacheCam_AABBSq(const SObjManPrecacheCamera& a, const AABB& b) -{ - float d2 = 0.0f; - - if (a.bbox.max.x < b.min.x) - { - d2 += sqr(b.min.x - a.bbox.max.x); - } - if (b.max.x < a.bbox.min.x) - { - d2 += sqr(a.bbox.min.x - b.max.x); - } - if (a.bbox.max.y < b.min.y) - { - d2 += sqr(b.min.y - a.bbox.max.y); - } - if (b.max.y < a.bbox.min.y) - { - d2 += sqr(a.bbox.min.y - b.max.y); - } - if (a.bbox.max.z < b.min.z) - { - d2 += sqr(b.min.z - a.bbox.max.z); - } - if (b.max.z < a.bbox.min.z) - { - d2 += sqr(a.bbox.min.z - b.max.z); - } - - return d2; -} - -bool COctreeNode::UpdateStreamingPriority(PodArray& arrRecursion, float fMinDist, float fMaxDist, bool bFullUpdate, const SObjManPrecacheCamera* pPrecacheCams, size_t nPrecacheCams, const SRenderingPassInfo& passInfo) -{ - // FUNCTION_PROFILER_3DENGINE; - - // Select the minimum distance to the node - float fNodeDistanceSq = Distance_PrecacheCam_AABBSq(pPrecacheCams[0], m_objectsBox); - for (size_t iPrecacheCam = 1; iPrecacheCam < nPrecacheCams; ++iPrecacheCam) - { - float fPcNodeDistanceSq = Distance_PrecacheCam_AABBSq(pPrecacheCams[iPrecacheCam], m_objectsBox); - fNodeDistanceSq = min(fNodeDistanceSq, fPcNodeDistanceSq); - } - float fNodeDistance = sqrt_tpl(fNodeDistanceSq); - - if (passInfo.GetCamera().IsAABBVisible_E(GetNodeBox())) - { - fNodeDistance *= passInfo.GetZoomFactor(); - } - - const float fPredictionDistanceFar = GetFloatCVar(e_StreamPredictionDistanceFar); - - if (fNodeDistance > min(m_fObjectsMaxViewDist, fMaxDist) + fPredictionDistanceFar) - { - return true; - } - - AABB objBox; - - const bool bEnablePerNodeDistance = GetCVars()->e_StreamCgfUpdatePerNodeDistance > 0; - CVisArea* pRoot0 = GetVisAreaManager() ? GetVisAreaManager()->GetCurVisArea() : NULL; - - float fMinDistSq = fMinDist * fMinDist; - - PREFAST_SUPPRESS_WARNING(6255) - float* pfMinVisAreaDistSq = (float*)alloca(sizeof(float) * nPrecacheCams); - - for (size_t iPrecacheCam = 0; iPrecacheCam < nPrecacheCams; ++iPrecacheCam) - { - float fMinVisAreaDist = 0.0f; - - if (pRoot0) - { - // search from camera to entity visarea or outdoor - AABB aabbCam = pPrecacheCams[iPrecacheCam].bbox; - float fResDist = 10000.0f; - if (pRoot0->GetDistanceThruVisAreas(aabbCam, m_pVisArea, m_objectsBox, bFullUpdate ? 2 : GetCVars()->e_StreamPredictionMaxVisAreaRecursion, fResDist)) - { - fMinVisAreaDist = fResDist; - } - } - else if (m_pVisArea) - { - // search from entity to outdoor - AABB aabbCam = pPrecacheCams[iPrecacheCam].bbox; - float fResDist = 10000.0f; - if (m_pVisArea->GetDistanceThruVisAreas(m_objectsBox, NULL, aabbCam, bFullUpdate ? 2 : GetCVars()->e_StreamPredictionMaxVisAreaRecursion, fResDist)) - { - fMinVisAreaDist = fResDist; - } - } - - pfMinVisAreaDistSq[iPrecacheCam] = fMinVisAreaDist * fMinVisAreaDist; - } - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->m_pNext) - { - cryPrefetchT0SSE(pObj->m_pNext); - } - - - IF (pObj->m_dwRndFlags & ERF_HIDDEN, 0) - { - continue; - } - - pObj->FillBBox(objBox); - - // stream more in zoom mode if in frustum - float fZoomFactorSq = passInfo.GetCamera().IsAABBVisible_E(objBox) - ? passInfo.GetZoomFactor() * passInfo.GetZoomFactor() - : 1.0f; - - for (size_t iPrecacheCam = 0; iPrecacheCam < nPrecacheCams; ++iPrecacheCam) - { - const Vec3& pcPosition = pPrecacheCams[iPrecacheCam].vPosition; - - float fEntDistanceSq = Distance_PrecacheCam_AABBSq(pPrecacheCams[iPrecacheCam], objBox); - fEntDistanceSq = max(fEntDistanceSq, fMinDistSq); - fEntDistanceSq *= fZoomFactorSq; - fEntDistanceSq = max(fEntDistanceSq, pfMinVisAreaDistSq[iPrecacheCam]); - - float fMaxDistComb = min(pObj->m_fWSMaxViewDist, fMaxDist) + fPredictionDistanceFar; - float fMaxDistCombSq = fMaxDistComb * fMaxDistComb; - - if (/*fMinDistSq <= fEntDistanceSq &&*/ fEntDistanceSq < fMaxDistCombSq) - { - float fEntDistance = sqrt_tpl(fEntDistanceSq); - assert(fEntDistance >= 0 && _finite(fEntDistance)); - - float fDist = fEntDistance; - if (!bFullUpdate && fEntDistance < fNodeDistance && bEnablePerNodeDistance) - { - fDist = fNodeDistance; - } - - // If we're inside the object, very close, or facing the object, set importance scale to 1.0f. Otherwise, 0.8f. - float fImportanceScale = (float)fsel( - 4.0f - fEntDistance, - 1.0f, - (float)fsel( - (objBox.GetCenter() - pcPosition).Dot(pPrecacheCams[iPrecacheCam].vDirection), - 1.0f, - 0.8f)); - - // I replaced fEntDistance with fNoideDistance here because of Timur request! It's suppose to be unified to-node-distance - GetObjManager()->UpdateRenderNodeStreamingPriority(pObj, fDist, fImportanceScale, bFullUpdate, passInfo); - } - } - } - } - - // Prioritise the first camera (probably the real camera) - int nFirst = - ((pPrecacheCams[0].vPosition.x > m_vNodeCenter.x) ? 4 : 0) | - ((pPrecacheCams[0].vPosition.y > m_vNodeCenter.y) ? 2 : 0) | - ((pPrecacheCams[0].vPosition.z > m_vNodeCenter.z) ? 1 : 0); - - if (m_arrChilds[nFirst ]) - { - arrRecursion.Add(m_arrChilds[nFirst ]); - } - - if (m_arrChilds[nFirst ^ 1]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 1]); - } - - if (m_arrChilds[nFirst ^ 2]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 2]); - } - - if (m_arrChilds[nFirst ^ 4]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 4]); - } - - if (m_arrChilds[nFirst ^ 3]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 3]); - } - - if (m_arrChilds[nFirst ^ 5]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 5]); - } - - if (m_arrChilds[nFirst ^ 6]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 6]); - } - - if (m_arrChilds[nFirst ^ 7]) - { - arrRecursion.Add(m_arrChilds[nFirst ^ 7]); - } - - return true; -} - -int COctreeNode::Load(AZ::IO::HandleType& fileHandle, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibilityMask) -{ - return Load_T(fileHandle, nDataSize, pStatObjTable, pMatTable, eEndian, pBox, pLayerVisibilityMask); -} -int COctreeNode::Load(uint8*& f, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibilityMask) -{ - return Load_T(f, nDataSize, pStatObjTable, pMatTable, eEndian, pBox, pLayerVisibilityMask); -} - -template -int COctreeNode::Load_T(T& f, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibilityMask) -{ - if (pBox && !Overlap::AABB_AABB(GetNodeBox(), *pBox)) - { - return 0; - } - - SOcTreeNodeChunk chunk; - if (!PakLoadDataUtils::LoadDataFromFile(&chunk, 1, f, nDataSize, eEndian)) - { - return 0; - } - - assert(chunk.nChunkVersion == OCTREENODE_CHUNK_VERSION || chunk.nChunkVersion == OCTREENODE_CHUNK_VERSION_OLD); - if (chunk.nChunkVersion != OCTREENODE_CHUNK_VERSION && chunk.nChunkVersion != OCTREENODE_CHUNK_VERSION_OLD) - { - return 0; - } - - if (chunk.nObjectsBlockSize) - { - // load objects data into memory buffer, make sure buffer is aligned - - auto pMemBlock = gEnv->pCryPak->PoolAllocMemoryBlock(chunk.nObjectsBlockSize + 8, "LoadObjectInstances"); - byte* pPtr = (byte*)pMemBlock->m_address.get(); - - while (UINT_PTR(pPtr) & 3) - { - pPtr++; - } - - if (!PakLoadDataUtils::LoadDataFromFile(pPtr, chunk.nObjectsBlockSize, f, nDataSize, eEndian)) - { - return 0; - } - - if (!m_bEditor) - { - LoadObjects(pPtr, pPtr + chunk.nObjectsBlockSize, pStatObjTable, pMatTable, eEndian, chunk.nChunkVersion, pLayerVisibilityMask); - } - } - - // count number of nodes loaded - int nNodesNum = 1; - - // process childs - for (int nChildId = 0; nChildId < 8; nChildId++) - { - if (chunk.ucChildsMask & (1 << nChildId)) - { - if (!m_arrChilds[nChildId]) - { - m_arrChilds[nChildId] = COctreeNode::Create(m_nSID, GetChildBBox(nChildId), m_pVisArea, this); - } - - int nNewNodesNum = m_arrChilds[nChildId]->Load_T(f, nDataSize, pStatObjTable, pMatTable, eEndian, pBox, pLayerVisibilityMask); - - if (!nNewNodesNum && !pBox) - { - return 0; // data error - } - nNodesNum += nNewNodesNum; - } - } - - return nNodesNum; -} - - - - - -#if ENGINE_ENABLE_COMPILATION -int COctreeNode::GetData(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) -{ - AABB* pBox = (pExportInfo && !pExportInfo->areaBox.IsReset()) ? &pExportInfo->areaBox : NULL; - - const AABB& nodeBox = GetNodeBox(); - if (pBox && !Overlap::AABB_AABB(nodeBox, *pBox)) - { - return 0; - } - - if (pData) - { - // get node data - SOcTreeNodeChunk chunk; - chunk.nChunkVersion = OCTREENODE_CHUNK_VERSION; - chunk.nodeBox = nodeBox; - - // fill ChildsMask - chunk.ucChildsMask = 0; - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - chunk.ucChildsMask |= (1 << i); - } - } - - CMemoryBlock memblock; - SaveObjects(&memblock, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo); - - chunk.nObjectsBlockSize = memblock.GetSize(); - - AddToPtr(pData, nDataSize, chunk, eEndian); - - AddToPtr(pData, nDataSize, (byte*)memblock.GetData(), memblock.GetSize(), eEndian); - } - else // just count size - { - nDataSize += sizeof(SOcTreeNodeChunk); - nDataSize += SaveObjects(NULL, NULL, NULL, NULL, eEndian, pExportInfo); - } - - // count number of nodes loaded - int nNodesNum = 1; - - // process childs - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - nNodesNum += m_arrChilds[i]->GetData(pData, nDataSize, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo); - } - } - - return nNodesNum; -} -#endif - -bool COctreeNode::CleanUpTree() -{ - bool bChildObjectsFound = false; - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - if (!m_arrChilds[i]->CleanUpTree()) - { - delete m_arrChilds[i]; - m_arrChilds[i] = NULL; - } - else - { - bChildObjectsFound = true; - } - } - } - - // update max view distances - - m_fObjectsMaxViewDist = 0.f; - m_objectsBox = GetNodeBox(); - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - pObj->m_fWSMaxViewDist = pObj->GetMaxViewDist(); - m_fObjectsMaxViewDist = max(m_fObjectsMaxViewDist, pObj->m_fWSMaxViewDist); - m_objectsBox.Add(pObj->GetBBox()); - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_fObjectsMaxViewDist = max(m_fObjectsMaxViewDist, m_arrChilds[i]->m_fObjectsMaxViewDist); - m_objectsBox.Add(m_arrChilds[i]->m_objectsBox); - } - } - - return (bChildObjectsFound || HasObjects()); -} - -////////////////////////////////////////////////////////////////////////// -bool COctreeNode::CheckRenderFlagsMinSpec(uint32 dwRndFlags) -{ - int nRenderNodeMinSpec = (dwRndFlags & ERF_SPEC_BITS_MASK) >> ERF_SPEC_BITS_SHIFT; - return CheckMinSpec(nRenderNodeMinSpec); -} - -void COctreeNode::OffsetObjects(const Vec3& offset) -{ - CompileObjects(); - m_objectsBox.Move(offset); - m_vNodeCenter += offset; - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - pObj->OffsetPosition(offset); - } - } - for (int i = 0; i < 8; ++i) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->OffsetObjects(offset); - } - } -} - -bool COctreeNode::HasAnyRenderableCandidates(const SRenderingPassInfo& passInfo) const -{ - // This checks if anything will be rendered, assuming we pass occlusion checks - // This is based on COctreeNode::RenderContentJobEntry's implementation, - // if that would do nothing, we can skip the running of occlusion and rendering jobs for this node - const bool bDecalsAndRoads = passInfo.RenderDecals() && m_arrObjects[eRNListType_DecalsAndRoads].m_pFirstNode != NULL; - const bool bUnknown = m_arrObjects[eRNListType_Unknown].m_pFirstNode != NULL; - return bDecalsAndRoads || bUnknown; -} diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree.h b/Code/CryEngine/Cry3DEngine/ObjectsTree.h deleted file mode 100644 index 2a2260c010..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree.h +++ /dev/null @@ -1,451 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_H -#define CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_H -#pragma once - -#define OCTREENODE_RENDER_FLAG_OBJECTS 1 -#define OCTREENODE_RENDER_FLAG_OCCLUDERS 2 -#define OCTREENODE_RENDER_FLAG_CASTERS 4 -#define OCTREENODE_RENDER_FLAG_OBJECTS_ONLY_ENTITIES 8 - -#define OCTREENODE_CHUNK_VERSION_OLD 3 -#define OCTREENODE_CHUNK_VERSION 5 - -#include -#include - -class COctreeNode; -template -class PodArray; -struct CLightEntity; -struct ILightSource; -/////////////////////////////////////////////////////////////////////////////// -// data to be pushed to occlusion culler -_MS_ALIGN(16) struct SCheckOcclusionJobData -{ - enum JobTypeT - { - QUIT, - OCTREE_NODE, - }; - - SCheckOcclusionJobData() {} - - static SCheckOcclusionJobData CreateQuitJobData(); - static SCheckOcclusionJobData CreateOctreeJobData(COctreeNode* pOctTreeNode, int nRenderMask, const SRendItemSorter& rendItemSorter, const CCamera* pCam); - - JobTypeT type; // type to indicate with which data the union is filled - union - { - // data for octree nodes - struct - { - COctreeNode* pOctTreeNode; - int nRenderMask; - } octTreeData; - - // data for terrain nodes - struct - { - float vAABBMin[3]; - float vAABBMax[3]; - float fDistance; - } terrainData; - }; - // common data - SRendItemSorter rendItemSorter; // ensure order octree traversal oder even with parallel execution - const CCamera* pCam; // store camera to handle vis areas correctly -} _ALIGN(16); - -/////////////////////////////////////////////////////////////////////////////// -inline SCheckOcclusionJobData SCheckOcclusionJobData::CreateQuitJobData() -{ - SCheckOcclusionJobData jobData; - jobData.type = QUIT; - return jobData; -} - -/////////////////////////////////////////////////////////////////////////////// -inline SCheckOcclusionJobData SCheckOcclusionJobData::CreateOctreeJobData(COctreeNode* pOctTreeNode, int nRenderMask, const SRendItemSorter& rendItemSorter, const CCamera* pCam) -{ - SCheckOcclusionJobData jobData; - jobData.type = OCTREE_NODE; - jobData.octTreeData.pOctTreeNode = pOctTreeNode; - jobData.octTreeData.nRenderMask = nRenderMask; - jobData.rendItemSorter = rendItemSorter; - jobData.pCam = pCam; - return jobData; -} - -/////////////////////////////////////////////////////////////////////////////// -// data written by occlusion culler jobs, to control main thread 3dengine side rendering -_MS_ALIGN(16) struct SCheckOcclusionOutput -{ - enum JobTypeT - { - ROAD_DECALS, - COMMON, - }; - - static SCheckOcclusionOutput CreateDecalsAndRoadsOutput(IRenderNode* pObj, const AABB& rObjBox, float fEntDistance, bool bCheckPerObjectOcclusion, const SRendItemSorter& rendItemSorter); - static SCheckOcclusionOutput CreateCommonObjectOutput(IRenderNode* pObj, const AABB& rObjBox, float fEntDistance, SSectorTextureSet* pTerrainTexInfo, const SRendItemSorter& rendItemSorter); - - JobTypeT type; - union - { - //ROAD_DECALS,COMMON Data - struct - { - IRenderNode* pObj; - SSectorTextureSet* pTerrainTexInfo; - float fEntDistance; - bool bCheckPerObjectOcclusion; - } common; - }; - - AABB objBox; - SRendItemSorter rendItemSorter; -} _ALIGN(16); - -/////////////////////////////////////////////////////////////////////////////// -inline SCheckOcclusionOutput SCheckOcclusionOutput::CreateDecalsAndRoadsOutput(IRenderNode* pObj, const AABB& rObjBox, float fEntDistance, bool bCheckPerObjectOcclusion, const SRendItemSorter& rendItemSorter) -{ - SCheckOcclusionOutput outputData; - outputData.type = ROAD_DECALS; - outputData.rendItemSorter = rendItemSorter; - outputData.objBox = rObjBox; - - outputData.common.pObj = pObj; - outputData.common.pTerrainTexInfo = NULL; - outputData.common.fEntDistance = fEntDistance; - outputData.common.bCheckPerObjectOcclusion = bCheckPerObjectOcclusion; - - return outputData; -} - -/////////////////////////////////////////////////////////////////////////////// -inline SCheckOcclusionOutput SCheckOcclusionOutput::CreateCommonObjectOutput(IRenderNode* pObj, const AABB& rObjBox, float fEntDistance, SSectorTextureSet* pTerrainTexInfo, const SRendItemSorter& rendItemSorter) -{ - SCheckOcclusionOutput outputData; - outputData.type = COMMON; - outputData.rendItemSorter = rendItemSorter; - outputData.objBox = rObjBox; - - outputData.common.pObj = pObj; - outputData.common.fEntDistance = fEntDistance; - outputData.common.pTerrainTexInfo = pTerrainTexInfo; - - return outputData; -} - -/////////////////////////////////////////////////////////////////////////////// -enum EOcTeeNodeListType -{ - eMain, - eCasters, - eSprites_deprecated, - eLights, -}; - -template -struct TDoublyLinkedList -{ - T* m_pFirstNode, * m_pLastNode; - - TDoublyLinkedList() - { - m_pFirstNode = m_pLastNode = NULL; - } - - ~TDoublyLinkedList() - { - assert(!m_pFirstNode && !m_pLastNode); - } - - void insertAfter(T* pAfter, T* pObj) - { - pObj->m_pPrev = pAfter; - pObj->m_pNext = pAfter->m_pNext; - if (pAfter->m_pNext == NULL) - { - m_pLastNode = pObj; - } - else - { - pAfter->m_pNext->m_pPrev = pObj; - } - pAfter->m_pNext = pObj; - } - - void insertBefore(T* pBefore, T* pObj) - { - pObj->m_pPrev = pBefore->m_pPrev; - pObj->m_pNext = pBefore; - if (pBefore->m_pPrev == NULL) - { - m_pFirstNode = pObj; - } - else - { - pBefore->m_pPrev->m_pNext = pObj; - } - pBefore->m_pPrev = pObj; - } - - void insertBeginning(T* pObj) - { - if (m_pFirstNode == NULL) - { - m_pFirstNode = pObj; - m_pLastNode = pObj; - pObj->m_pPrev = NULL; - pObj->m_pNext = NULL; - } - else - { - insertBefore(m_pFirstNode, pObj); - } - } - - void insertEnd(T* pObj) - { - if (m_pLastNode == NULL) - { - insertBeginning(pObj); - } - else - { - insertAfter(m_pLastNode, pObj); - } - } - - void remove(T* pObj) - { - if (pObj->m_pPrev == NULL) - { - m_pFirstNode = pObj->m_pNext; - } - else - { - pObj->m_pPrev->m_pNext = pObj->m_pNext; - } - - if (pObj->m_pNext == NULL) - { - m_pLastNode = pObj->m_pPrev; - } - else - { - pObj->m_pNext->m_pPrev = pObj->m_pPrev; - } - - pObj->m_pPrev = pObj->m_pNext = NULL; - } - - bool empty() const { return m_pFirstNode == NULL; } -}; - -struct SInstancingInfo -{ - SInstancingInfo() { pStatInstGroup = 0; aabb.Reset(); fMinSpriteDistance = 10000.f; bInstancingInUse = 0; } - StatInstGroup* pStatInstGroup; - DynArray arrInstances; - stl::aligned_vector arrMats; - AABB aabb; - float fMinSpriteDistance; - bool bInstancingInUse; -}; - -struct SLayerVisibility -{ - const uint8* pLayerVisibilityMask; - const uint16* pLayerIdTranslation; -}; - -struct SOctreeLoadObjectsData -{ - COctreeNode* pNode; - ptrdiff_t offset; - size_t size; - _smart_ptr pMemBlock; - byte* pObjPtr; - byte* pEndObjPtr; -}; - -class COctreeNode - : Cry3DEngineBase - , public IOctreeNode -{ -public: - - struct ShadowMapFrustumParams - { - CDLight* pLight; - struct ShadowMapFrustum* pFr; - PodArray* pShadowHull; - const SRenderingPassInfo* passInfo; - Vec3 vCamPos; - uint32 nRenderNodeFlags; - bool bSun; - }; - - ~COctreeNode(); - - bool HasChildNodes(); - int CountChildNodes(); - void InsertObject(IRenderNode* pObj, const AABB& objBox, const float fObjRadiusSqr, const Vec3& vObjCenter); - bool DeleteObject(IRenderNode* pObj); - void Render_Object_Nodes(bool bNodeCompletelyInFrustum, int nRenderMask, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter); - - static void Shutdown(); - static void WaitForContentJobCompletion(); - void RenderContent(int nRenderMask, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, const CCamera* pCam); - void RenderContentJobEntry(int nRenderMask, const SRenderingPassInfo& passInfo, SRendItemSorter rendItemSorter, const CCamera* pCam); - void RenderCommonObjects(TDoublyLinkedList* lstObjects, const CCamera& rCam, int nRenderMask, bool bNodeCompletelyInFrustum, SSectorTextureSet* pTerrainTexInfo, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter); - void RenderDecalsAndRoads(TDoublyLinkedList* lstObjects, const CCamera& rCam, int nRenderMask, bool bNodeCompletelyInFrustum, SSectorTextureSet* pTerrainTexInfo, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter); - - void FillShadowCastersList(bool bNodeCompletellyInFrustum, CDLight* pLight, struct ShadowMapFrustum* pFr, PodArray* pShadowHull, uint32 nRenderNodeFlags, const SRenderingPassInfo& passInfo); - void FillShadowMapCastersList(const ShadowMapFrustumParams& params, bool bNodeCompletellyInFrustum); - void FillDepthCubemapRenderList(const AABB& cubemapAABB, const SRenderingPassInfo& passInfo, PodArray* objectsList); - void ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, IGeneralMemoryHeap* pHeap); - void GetLayerMemoryUsage(uint16 nLayerId, ICrySizer* pSizer, int* pNumBrushes, int* pNumDecals); - - COctreeNode* FindNodeContainingBox(const AABB& objBox); - void MoveObjectsIntoList(PodArray* plstResultEntities, const AABB* pAreaBox, bool bRemoveObjects = false, bool bSkipDecals = false, bool bSkip_ERF_NO_DECALNODE_DECALS = false, bool bSkipDynamicObjects = false, EERType eRNType = eERType_TypesNum); - -# if ENGINE_ENABLE_COMPILATION - int GetData(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); -# endif - - const AABB& GetObjectsBBox() { return m_objectsBox; } - AABB GetShadowCastersBox(const AABB* pBBox, const Matrix34* pShadowSpaceTransform); - void DeleteObjectsByFlag(int nRndFlag); - void UnregisterEngineObjectsInArea(const SHotUpdateInfo* pExportInfo, PodArray& arrUnregisteredObjects, bool bOnlyEngineObjects); - uint32 GetLastVisFrameId() { return m_nLastVisFrameId; } - void GetObjectsByType(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; - void GetObjectsByFlags(uint dwFlags, PodArray& lstObjects); - - void GetNearestCubeProbe(float& fMinDistance, int& nMaxPriority, CLightEntity*& pNearestLight, const AABB* pBBox); - void GetObjects(PodArray& lstObjects, const AABB* pBBox); - bool GetShadowCastersTimeSliced(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int& totalRemainingNodes, int nCurLevel, const SRenderingPassInfo& passInfo); - bool IsObjectTypeInTheBox(EERType objType, const AABB& WSBBox); - bool CleanUpTree(); - int GetObjectsCount(EOcTeeNodeListType eListType); - int SaveObjects(class CMemoryBlock* pMemBlock, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, const SHotUpdateInfo * pExportInfo); - int LoadObjects(byte* pPtr, byte* pEndPtr, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, int nChunkVersion, const SLayerVisibility* pLayerVisibility); - static int GetSingleObjectSize (IRenderNode* pObj, const SHotUpdateInfo* pExportInfo); - static void SaveSingleObject (byte*& pPtr, int& nDatanSize, IRenderNode* pObj, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, const SHotUpdateInfo* pExportInfo); - static void LoadSingleObject(byte*& pPtr, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, int nChunkVersion, const SLayerVisibility* pLayerVisibility, int nSID); - bool IsRightNode(const AABB& objBox, const float fObjRadius, float fObjMaxViewDist); - void GetMemoryUsage(ICrySizer* pSizer) const; - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - bool RayObjectsIntersection2D(Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, EERType eERType); -#endif - - template - int Load_T(T& f, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibility); - int Load(AZ::IO::HandleType& fileHandle, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibility); - int Load(uint8*& f, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, AABB* pBox, const SLayerVisibility* pLayerVisibility); - - void GenerateStatObjAndMatTables(std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, SHotUpdateInfo* pExportInfo); - static void ReleaseEmptyNodes(); - static void StaticReset(); - bool IsEmpty(); - bool HasObjects(); - - bool UpdateStreamingPriority(PodArray& arrRecursion, float fMinDist, float fMaxDist, bool bFullUpdate, const SObjManPrecacheCamera* pPrecacheCams, size_t nPrecacheCams, const SRenderingPassInfo& passInfo); - AABB GetNodeBox() const - { - return AABB( - m_vNodeCenter - m_vNodeAxisRadius, - m_vNodeCenter + m_vNodeAxisRadius); - } - - void OffsetObjects(const Vec3& offset); - void SetVisArea(CVisArea* pVisArea); - void UpdateVisAreaSID([[maybe_unused]] CVisArea* pVisArea, int nSID) - { - assert(pVisArea); - m_nSID = nSID; - } - - static COctreeNode* Create(int nSID, const AABB& box, struct CVisArea* pVisArea, COctreeNode* pParent = NULL); - -protected: - AABB GetChildBBox(int nChildId); - void CompileObjects(); - void UpdateObjects(IRenderNode* pObj); - void CompileObjectsBrightness(); - float GetNodeObjectsMaxViewDistance(); - - // Check if min spec specified in render node passes current server config spec. - static bool CheckRenderFlagsMinSpec(uint32 dwRndFlags); - - void LinkObject(IRenderNode* pObj, EERType eERType, bool bPushFront = true); - void UnlinkObject(IRenderNode* pObj); - - static int Cmp_OctreeNodeSize(const void* v1, const void* v2); - -private: - COctreeNode(int nSID, const AABB& box, struct CVisArea* pVisArea, COctreeNode* pParent); - - float GetNodeRadius2() const { return m_vNodeAxisRadius.Dot(m_vNodeAxisRadius); } - COctreeNode* FindChildFor(IRenderNode* pObj, const AABB& objBox, const float fObjRadius, const Vec3& vObjCenter); - bool HasAnyRenderableCandidates(const SRenderingPassInfo& passInfo) const; - - uint32 m_nOccludedFrameId; - uint32 m_renderFlags; - uint32 m_errTypesBitField; - AABB m_objectsBox; - float m_fObjectsMaxViewDist; - uint32 m_nLastVisFrameId; - - COctreeNode* m_arrChilds[8]; - TDoublyLinkedList m_arrObjects[eRNListType_ListsNum]; - PodArray m_lstCasters; - Vec3 m_vNodeCenter; - Vec3 m_vNodeAxisRadius; - COctreeNode* m_pParent; - uint32 nFillShadowCastersSkipFrameId; - float m_fNodeDistance; - int m_nManageVegetationsFrameId; - int m_nSID; - struct CRNTmpData* m_pRNTmpData; - - uint32 m_bHasLights : 1; - uint32 m_bNodeCompletelyInFrustum : 1; - uint32 m_fpSunDirX : 7; - uint32 m_fpSunDirZ : 7; - uint32 m_fpSunDirYs : 1; - uint32 m_bStaticInstancingIsDirty : 1; - - struct SNodeInstancingInfo - { - SNodeInstancingInfo() { pRNode = 0; nodeMatrix.IsIdentity(); } - Matrix34 nodeMatrix; - class CVegetation * pRNode; - }; - std::map>, PodArray*> * m_pStaticInstancingInfo; - - static void* m_pRenderContentJobQueue; - static bool m_removeVegetationCastersOneByOne; - -public: - static PodArray m_arrEmptyNodes; -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_H diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree_Jobs.cpp b/Code/CryEngine/Cry3DEngine/ObjectsTree_Jobs.cpp deleted file mode 100644 index 8c10083afd..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree_Jobs.cpp +++ /dev/null @@ -1,1433 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Octree parts used on Jobs to prevent scanning too many files for micro functions - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "CullBuffer.h" -#include "3dEngine.h" -#include "IndexedMesh.h" -#include "ObjectsTree.h" - -#include "DecalRenderNode.h" -#include "FogVolumeRenderNode.h" -#include "Ocean.h" -#include "LightEntity.h" -#include "WaterVolumeRenderNode.h" -#include "DistanceCloudRenderNode.h" -#include "Environment/OceanEnvironmentBus.h" - -#define CHECK_OBJECTS_BOX_WARNING_SIZE (1.0e+10f) -#define fNodeMinSize (8.f) -#define fObjectToNodeSizeRatio (1.f / 8.f) -#define fMinShadowCasterViewDist (8.f) - -namespace LegacyInternal -{ - // File scoped LegacyJobExecutor instance used to run all RenderContent jobs - static AZ::LegacyJobExecutor* s_renderContentJobExecutor; -}; - -////////////////////////////////////////////////////////////////////////// -COctreeNode::COctreeNode(int nSID, const AABB& box, CVisArea* pVisArea, COctreeNode* pParent) - : m_nOccludedFrameId(0), m_renderFlags(0), m_errTypesBitField(0), m_fObjectsMaxViewDist(0.0f), m_nLastVisFrameId(0) - , nFillShadowCastersSkipFrameId(0), m_fNodeDistance(0.0f), m_nManageVegetationsFrameId(0) - , m_bHasLights(0), m_bNodeCompletelyInFrustum(0) -{ - memset(m_arrChilds, 0, sizeof(m_arrChilds)); - memset(m_arrObjects, 0, sizeof(m_arrObjects)); - memset(&m_lstCasters, 0, sizeof(m_lstCasters)); - - m_pRNTmpData = NULL; - m_nSID = nSID; - m_vNodeCenter = box.GetCenter(); - m_vNodeAxisRadius = box.GetSize() * 0.5f; - m_objectsBox.min = box.max; - m_objectsBox.max = box.min; - -#if !defined(_RELEASE) - // Check if bounding box is crazy -#define CHECK_OBJECTS_BOX_WARNING_SIZE (1.0e+10f) - if (GetCVars()->e_CheckOctreeObjectsBoxSize != 0) // pParent is checked as silly sized things are added to the root (e.g. the sun) - { - if (pParent && !m_objectsBox.IsReset() && (m_objectsBox.min.len() > CHECK_OBJECTS_BOX_WARNING_SIZE || m_objectsBox.max.len() > CHECK_OBJECTS_BOX_WARNING_SIZE)) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR_DBGBRK, "COctreeNode being created with a huge m_objectsBox: [%f %f %f] -> [%f %f %f]\n", m_objectsBox.min.x, m_objectsBox.min.y, m_objectsBox.min.z, m_objectsBox.max.x, m_objectsBox.max.y, m_objectsBox.max.z); - } - } -#endif - - m_pVisArea = pVisArea; - m_pParent = pParent; - - m_fpSunDirX = 63; - m_fpSunDirZ = 0; - m_fpSunDirYs = 0; - - m_pStaticInstancingInfo = nullptr; - m_bStaticInstancingIsDirty = false; -} - -////////////////////////////////////////////////////////////////////////// -COctreeNode* COctreeNode::Create(int nSID, const AABB& box, struct CVisArea* pVisArea, COctreeNode* pParent) -{ - return new COctreeNode(nSID, box, pVisArea, pParent); -} - -////////////////////////////////////////////////////////////////////////// -bool COctreeNode::HasObjects() -{ - for (int l = 0; l < eRNListType_ListsNum; l++) - { - if (m_arrObjects[l].m_pFirstNode) - { - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::RenderContent(int nRenderMask, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, const CCamera* pCam) -{ - if (GetCVars()->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass()) - { - GetObjManager()->AddCullJobProducer(); - } - - if (!LegacyInternal::s_renderContentJobExecutor) - { - LegacyInternal::s_renderContentJobExecutor = new AZ::LegacyJobExecutor; - } - - LegacyInternal::s_renderContentJobExecutor->StartJob( - [this, nRenderMask, passInfo, rendItemSorter, pCam] - { - this->RenderContentJobEntry(nRenderMask, passInfo, rendItemSorter, pCam); - } - ); -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::Shutdown() -{ - WaitForContentJobCompletion(); -} - -void COctreeNode::WaitForContentJobCompletion() -{ - //Deleting it calls WaitForCompletion(), and the next call to RenderContent() will create a new instance - delete LegacyInternal::s_renderContentJobExecutor; - LegacyInternal::s_renderContentJobExecutor = nullptr; -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::RenderContentJobEntry(int nRenderMask, const SRenderingPassInfo& passInfo, SRendItemSorter rendItemSorter, const CCamera* pCam) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ThreeDEngine); - - SSectorTextureSet* pTerrainTexInfo = NULL; - - if (m_arrObjects[eRNListType_DecalsAndRoads].m_pFirstNode && (passInfo.RenderDecals())) - { - RenderDecalsAndRoads(&m_arrObjects[eRNListType_DecalsAndRoads], *pCam, nRenderMask, m_bNodeCompletelyInFrustum != 0, pTerrainTexInfo, passInfo, rendItemSorter); - } - - if (m_arrObjects[eRNListType_Unknown].m_pFirstNode) - { - RenderCommonObjects(&m_arrObjects[eRNListType_Unknown], *pCam, nRenderMask, m_bNodeCompletelyInFrustum != 0, pTerrainTexInfo, passInfo, rendItemSorter); - } - - if (GetCVars()->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass()) - { - GetObjManager()->RemoveCullJobProducer(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -void COctreeNode::RenderDecalsAndRoads(TDoublyLinkedList* lstObjects, const CCamera& rCam, [[maybe_unused]] int nRenderMask, bool bNodeCompletelyInFrustum, [[maybe_unused]] SSectorTextureSet* pTerrainTexInfo, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - CVars* pCVars = GetCVars(); - AABB objBox; - const Vec3 vCamPos = rCam.GetPosition(); - - bool bCheckPerObjectOcclusion = true; - - for (IRenderNode* pObj = lstObjects->m_pFirstNode, * pNext; pObj; pObj = pNext) - { - rendItemSorter.IncreaseObjectCounter(); - pNext = pObj->m_pNext; - - if (pObj->m_pNext) - { - cryPrefetchT0SSE(pObj->m_pNext); - } - - IF (pObj->m_dwRndFlags & ERF_HIDDEN, 0) - { - continue; - } - - pObj->FillBBox(objBox); - - if (bNodeCompletelyInFrustum || rCam.IsAABBVisible_FM(objBox)) - { - float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - assert(fEntDistance >= 0 && _finite(fEntDistance)); - if (fEntDistance < pObj->m_fWSMaxViewDist) - { -#if !defined(_RELEASE) - EERType rnType = pObj->GetRenderNodeType(); - if (!passInfo.RenderDecals() && rnType == eERType_Decal) - { - continue; - } -#endif // _RELEASE - - if (pCVars->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass()) - { - // if object is visible, write to output queue for main thread processing - if (GetObjManager()->CheckOcclusion_TestAABB(objBox, fEntDistance)) - { - GetObjManager()->PushIntoCullOutputQueue(SCheckOcclusionOutput::CreateDecalsAndRoadsOutput(pObj, objBox, fEntDistance, bCheckPerObjectOcclusion, rendItemSorter)); - } - } - else - { - GetObjManager()->RenderDecalAndRoad(pObj, objBox, fEntDistance, bCheckPerObjectOcclusion, passInfo, rendItemSorter); - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void COctreeNode::RenderCommonObjects(TDoublyLinkedList* lstObjects, const CCamera& rCam, int nRenderMask, bool bNodeCompletelyInFrustum, SSectorTextureSet* pTerrainTexInfo, const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - CVars* pCVars = GetCVars(); - AABB objBox; - const Vec3 vCamPos = rCam.GetPosition(); - - for (IRenderNode* pObj = lstObjects->m_pFirstNode, * pNext; pObj; pObj = pNext) - { - rendItemSorter.IncreaseObjectCounter(); - pNext = pObj->m_pNext; - - if (pObj->m_pNext) - { - cryPrefetchT0SSE(pObj->m_pNext); - } - - IF (pObj->m_dwRndFlags & ERF_HIDDEN, 0) - { - continue; - } - - pObj->FillBBox(objBox); - EERType rnType = pObj->GetRenderNodeType(); - - if (bNodeCompletelyInFrustum || rCam.IsAABBVisible_FM(objBox)) - { - float fEntDistance = sqrt_tpl(Distance::Point_AABBSq(vCamPos, objBox)) * passInfo.GetZoomFactor(); - assert(fEntDistance >= 0 && _finite(fEntDistance)); - if (fEntDistance < pObj->m_fWSMaxViewDist) - { - if (nRenderMask & OCTREENODE_RENDER_FLAG_OBJECTS_ONLY_ENTITIES) - { - if (rnType != eERType_RenderComponent && rnType != eERType_DynamicMeshRenderComponent && rnType != eERType_SkinnedMeshRenderComponent) - { - if (rnType == eERType_Light) - { - CLightEntity* pEnt = (CLightEntity*)pObj; - if (!pEnt->GetEntityVisArea() && !(pEnt->m_light.m_Flags & DLF_THIS_AREA_ONLY)) - { // not "this area only" outdoor light affects everything - } - else - { - continue; - } - } - else - { - continue; - } - } - } - - if (rnType == eERType_Light) - { - bool bLightVisible = true; - CLightEntity* pLightEnt = (CLightEntity*)pObj; - - // first check against camera view frustum - CDLight* pLight = &pLightEnt->m_light; - if (pLight->m_Flags & DLF_DEFERRED_CUBEMAPS) - { - OBB obb(OBB::CreateOBBfromAABB(Matrix33(pLight->m_ObjMatrix), AABB(-pLight->m_ProbeExtents, pLight->m_ProbeExtents))); - bLightVisible = passInfo.GetCamera().IsOBBVisible_F(pLight->m_Origin, obb); - } - else if (pLightEnt->m_light.m_Flags & DLF_AREA_LIGHT) - { - // OBB test for area lights. - Vec3 vBoxMax(pLight->m_fBaseRadius, pLight->m_fBaseRadius + pLight->m_fAreaWidth, pLight->m_fBaseRadius + pLight->m_fAreaHeight); - Vec3 vBoxMin(-0.1f, -(pLight->m_fBaseRadius + pLight->m_fAreaWidth), -(pLight->m_fBaseRadius + pLight->m_fAreaHeight)); - - OBB obb(OBB::CreateOBBfromAABB(Matrix33(pLight->m_ObjMatrix), AABB(vBoxMin, vBoxMax))); - bLightVisible = rCam.IsOBBVisible_F(pLight->m_Origin, obb); - } - else - { - bLightVisible = rCam.IsSphereVisible_F(Sphere(pLight->m_BaseOrigin, pLight->m_fBaseRadius)); - } - - if (!bLightVisible) - { - continue; - } - } - - if (pCVars->e_StatObjBufferRenderTasks == 1 && passInfo.IsGeneralPass()) - { - // If object is visible - if (rnType == eERType_DistanceCloud || GetObjManager()->CheckOcclusion_TestAABB(objBox, fEntDistance)) - { - if (pObj->CanExecuteRenderAsJob()) - { - // If object can be executed as a job, call RenderObject directly from this job - GetObjManager()->RenderObject(pObj, objBox, fEntDistance, eERType_RenderComponent, passInfo, rendItemSorter); - } - else - { - // Otherwise, write to output queue for main thread processing - GetObjManager()->PushIntoCullOutputQueue(SCheckOcclusionOutput::CreateCommonObjectOutput(pObj, objBox, fEntDistance, pTerrainTexInfo, rendItemSorter)); - } - } - } - else - { - GetObjManager()->RenderObject(pObj, objBox, fEntDistance, rnType, passInfo, rendItemSorter); - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::UnlinkObject(IRenderNode* pObj) -{ - ERNListType eListType = pObj->GetRenderNodeListId(pObj->GetRenderNodeType()); - - assert(eListType >= 0 && eListType < eRNListType_ListsNum); - TDoublyLinkedList& rList = m_arrObjects[eListType]; - - assert(pObj != pObj->m_pPrev && pObj != pObj->m_pNext); - assert(!rList.m_pFirstNode || !rList.m_pFirstNode->m_pPrev); - assert(!rList.m_pLastNode || !rList.m_pLastNode->m_pNext); - - if (pObj->m_pNext || pObj->m_pPrev || pObj == rList.m_pLastNode || pObj == rList.m_pFirstNode) - { - rList.remove(pObj); - } - - assert(!rList.m_pFirstNode || !rList.m_pFirstNode->m_pPrev); - assert(!rList.m_pLastNode || !rList.m_pLastNode->m_pNext); - assert(pObj != pObj->m_pPrev && pObj != pObj->m_pNext); - assert(!pObj->m_pNext && !pObj->m_pPrev); -} - -bool COctreeNode::DeleteObject(IRenderNode* pObj) -{ - FUNCTION_PROFILER_3DENGINE; - - if (pObj->m_pOcNode && pObj->m_pOcNode != this) - { - return ((COctreeNode*)(pObj->m_pOcNode))->DeleteObject(pObj); - } - - UnlinkObject(pObj); - - if (m_removeVegetationCastersOneByOne) - { - for (int i = 0; i < m_lstCasters.Count(); i++) - { - if (m_lstCasters[i].pNode == pObj) - { - m_lstCasters.Delete(i); - break; - } - } - } - - C3DEngine* p3DEngine = Get3DEngine(); - bool bSafeToUse = p3DEngine ? p3DEngine->IsObjectTreeReady() : false; - - pObj->m_pOcNode = NULL; - pObj->m_nSID = -1; - - if (bSafeToUse && IsEmpty() && m_arrEmptyNodes.Find(this) < 0) - { - m_arrEmptyNodes.Add(this); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::InsertObject(IRenderNode* pObj, const AABB& objBox, const float fObjRadiusSqr, const Vec3& vObjCenter) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ThreeDEngineDetailed); - - COctreeNode* pCurrentNode = this; - - const EERType eType = pObj->GetRenderNodeType(); - const uint32 renderFlags = (pObj->GetRndFlags() & (ERF_GOOD_OCCLUDER | ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS)); - - const bool bTypeLight = (eType == eERType_Light); - const float fWSMaxViewDist = pObj->m_fWSMaxViewDist; - - Vec3 vObjectCentre = vObjCenter; - - while (true) - { - PrefetchLine(&pCurrentNode->m_arrChilds[0], 0); - -#if !defined(_RELEASE) - if (GetCVars()->e_CheckOctreeObjectsBoxSize != 0) // pCurrentNode->m_pParent is checked as silly sized things are added to the root (e.g. the sun) - { - if (pCurrentNode->m_pParent && !objBox.IsReset() && (objBox.min.len() > CHECK_OBJECTS_BOX_WARNING_SIZE || objBox.max.len() > CHECK_OBJECTS_BOX_WARNING_SIZE)) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR_DBGBRK, "Huge object being added to a COctreeNode, name: '%s', objBox: [%f %f %f] -> [%f %f %f]\n", pObj->GetName(), objBox.min.x, objBox.min.y, objBox.min.z, objBox.max.x, objBox.max.y, objBox.max.z); - } - } -#endif - - // parent bbox includes all children - pCurrentNode->m_objectsBox.Add(objBox); - - pCurrentNode->m_fObjectsMaxViewDist = max(pCurrentNode->m_fObjectsMaxViewDist, fWSMaxViewDist); - - pCurrentNode->m_renderFlags |= renderFlags; - - pCurrentNode->m_bHasLights |= (bTypeLight); - - if (pCurrentNode->m_vNodeAxisRadius.x * 2.0f > fNodeMinSize) // store voxels and roads in root - { - float nodeRadius = sqrt(pCurrentNode->GetNodeRadius2()); - - if (fObjRadiusSqr < sqr(nodeRadius * fObjectToNodeSizeRatio)) - { - int nChildId = - ((vObjCenter.x > pCurrentNode->m_vNodeCenter.x) ? 4 : 0) | - ((vObjCenter.y > pCurrentNode->m_vNodeCenter.y) ? 2 : 0) | - ((vObjCenter.z > pCurrentNode->m_vNodeCenter.z) ? 1 : 0); - - if (!pCurrentNode->m_arrChilds[nChildId]) - { - pCurrentNode->m_arrChilds[nChildId] = COctreeNode::Create(pCurrentNode->m_nSID, pCurrentNode->GetChildBBox(nChildId), pCurrentNode->m_pVisArea, pCurrentNode); - } - - pCurrentNode = pCurrentNode->m_arrChilds[nChildId]; - - continue; - } - } - - break; - } - - //disable as it leads to some corruption on 360 - // PrefetchLine(&pObj->m_pOcNode, 0); //Writing to m_pOcNode was a common L2 cache miss - - pCurrentNode->LinkObject(pObj, eType); - - pObj->m_pOcNode = pCurrentNode; - pObj->m_nSID = pCurrentNode->m_nSID; - - // only mark octree nodes as not compiled during loading and in the editor - // otherwise update node (and parent node) flags on per added object basis - if (m_bLevelLoadingInProgress || gEnv->IsEditor()) - { - // Do nothing - } - else - { - pCurrentNode->UpdateObjects(pObj); - } - - pCurrentNode->m_nManageVegetationsFrameId = 0; -} - -////////////////////////////////////////////////////////////////////////// -AABB COctreeNode::GetChildBBox(int nChildId) -{ - int x = (nChildId / 4); - int y = (nChildId - x * 4) / 2; - int z = (nChildId - x * 4 - y * 2); - const Vec3& vSize = m_vNodeAxisRadius; - Vec3 vOffset = vSize; - vOffset.x *= x; - vOffset.y *= y; - vOffset.z *= z; - AABB childBox; - childBox.min = m_vNodeCenter - vSize + vOffset; - childBox.max = childBox.min + vSize; - return childBox; -} - -////////////////////////////////////////////////////////////////////////// -bool COctreeNode::IsEmpty() -{ - if (m_pParent) - { - if (!m_arrChilds[0] && !m_arrChilds[1] && !m_arrChilds[2] && !m_arrChilds[3]) - { - if (!m_arrChilds[4] && !m_arrChilds[5] && !m_arrChilds[6] && !m_arrChilds[7]) - { - if (!HasObjects()) - { - return true; - } - } - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool COctreeNode::IsRightNode(const AABB& objBox, const float fObjRadiusSqr, [[maybe_unused]] float fObjMaxViewDist) -{ - const AABB& nodeBox = GetNodeBox(); - if (!Overlap::Point_AABB(objBox.GetCenter(), nodeBox)) - { - if (m_pParent) - { - return false; // fail if center is not inside or node bbox - } - } - if (2 != Overlap::AABB_AABB_Inside(objBox, m_objectsBox)) - { - return false; // fail if not completely inside of objects bbox - } - float fNodeRadiusRated = GetNodeRadius2() * sqr(fObjectToNodeSizeRatio); - - if (fObjRadiusSqr > fNodeRadiusRated * 4.f) - { - if (m_pParent) - { - return false; // fail if object is too big and we need to register it some of parents - } - } - if (m_vNodeAxisRadius.x * 2.0f > fNodeMinSize) - { - if (fObjRadiusSqr < fNodeRadiusRated) - { - // if(fObjMaxViewDist < m_fNodeRadius*GetCVars()->e_ViewDistRatioVegetation*fObjectToNodeSizeRatio) - return false; // fail if object is too small and we need to register it some of childs - } - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::LinkObject(IRenderNode* pObj, EERType eERType, bool bPushFront) -{ - ERNListType eListType = pObj->GetRenderNodeListId(eERType); - - TDoublyLinkedList& rList = m_arrObjects[eListType]; - - assert(pObj != pObj->m_pPrev && pObj != pObj->m_pNext); - assert(!pObj->m_pNext && !pObj->m_pPrev); - assert(!rList.m_pFirstNode || !rList.m_pFirstNode->m_pPrev); - assert(!rList.m_pLastNode || !rList.m_pLastNode->m_pNext); - - if (bPushFront) - { - rList.insertBeginning(pObj); - } - else - { - rList.insertEnd(pObj); - } - - assert(!rList.m_pFirstNode || !rList.m_pFirstNode->m_pPrev); - assert(!rList.m_pLastNode || !rList.m_pLastNode->m_pNext); - assert(pObj != pObj->m_pPrev && pObj != pObj->m_pNext); -} - -////////////////////////////////////////////////////////////////////////// -void COctreeNode::UpdateObjects(IRenderNode* pObj) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ThreeDEngineDetailed); - - float fObjMaxViewDistance = 0; - - bool bVegetHasAlphaTrans = false; - int nFlags = pObj->GetRndFlags(); - EERType eRType = pObj->GetRenderNodeType(); - - IF (nFlags & ERF_HIDDEN, 0) - { - return; - } - - I3DEngine* p3DEngine = GetISystem()->GetI3DEngine(); - const Vec3& sunDir = p3DEngine->GetSunDirNormalized(); - uint32 sunDirX = (uint32)(sunDir.x * 63.5f + 63.5f); - uint32 sunDirZ = (uint32)(sunDir.z * 63.5f + 63.5f); - uint32 sunDirYs = (uint32)(sunDir.y < 0.0f ? 1 : 0); - - pObj->m_nInternalFlags &= ~(IRenderNode::REQUIRES_FORWARD_RENDERING | IRenderNode::REQUIRES_NEAREST_CUBEMAP); - - // update max view distances - const float fNewMaxViewDist = pObj->GetMaxViewDist(); - pObj->m_fWSMaxViewDist = fNewMaxViewDist; - - if (eRType != eERType_Light && eRType != eERType_Cloud && eRType != eERType_FogVolume && eRType != eERType_Decal && eRType != eERType_DistanceCloud) - { - { - CMatInfo* pMatInfo = (CMatInfo*)pObj->GetMaterial().get(); - if (pMatInfo) - { - if (bVegetHasAlphaTrans || pMatInfo->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - - if (pMatInfo->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - - if (eRType == eERType_RenderComponent || eRType == eERType_DynamicMeshRenderComponent || eRType == eERType_SkinnedMeshRenderComponent) - { - int nSlotCount = pObj->GetSlotCount(); - - for (int s = 0; s < nSlotCount; s++) - { - if (CMatInfo* pMat = (CMatInfo*)pObj->GetEntitySlotMaterial(s).get()) - { - if (pMat->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - if (pMat->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - - if (IStatObj* pStatObj = pObj->GetEntityStatObj(s)) - { - if (CMatInfo* pMat = (CMatInfo*)pStatObj->GetMaterial().get()) - { - if (pMat->IsForwardRenderingRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_FORWARD_RENDERING; - } - if (pMat->IsNearestCubemapRequired()) - { - pObj->m_nInternalFlags |= IRenderNode::REQUIRES_NEAREST_CUBEMAP; - } - } - } - } - } - } - } - - bool bUpdateParentShadowFlags = false; - - // fill shadow casters list - const bool bHasPerObjectShadow = GetCVars()->e_ShadowsPerObject && p3DEngine->GetPerObjectShadow(pObj); - if (nFlags & ERF_CASTSHADOWMAPS && fNewMaxViewDist > fMinShadowCasterViewDist && eRType != eERType_Light && !bHasPerObjectShadow) - { - bUpdateParentShadowFlags = true; - - float fMaxCastDist = fNewMaxViewDist * GetCVars()->e_ShadowsCastViewDistRatio; - m_lstCasters.Add(SCasterInfo(pObj, fMaxCastDist, eRType)); - } - - fObjMaxViewDistance = max(fObjMaxViewDistance, fNewMaxViewDist); - - // traverse the octree upwards and fill in new flags - COctreeNode* pNode = this; - bool bContinue = false; - do - { - // update max view dist - if (pNode->m_fObjectsMaxViewDist < fObjMaxViewDistance) - { - pNode->m_fObjectsMaxViewDist = fObjMaxViewDistance; - bContinue = true; - } - - // update shadow flags - if (bUpdateParentShadowFlags && (pNode->m_renderFlags & ERF_CASTSHADOWMAPS) == 0) - { - pNode->m_renderFlags |= ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS; - bContinue = true; - } - - pNode = pNode->m_pParent; - } while (pNode != NULL && bContinue); - - m_fpSunDirX = sunDirX; - m_fpSunDirZ = sunDirZ; - m_fpSunDirYs = sunDirYs; -} - -////////////////////////////////////////////////////////////////////////// -int16 CObjManager::GetNearestCubeProbe(IVisArea* pVisArea, const AABB& objBox, bool bSpecular) -{ - // Only used for alpha blended geometry - but still should be optimized further - float fMinDistance = FLT_MAX; - int nMaxPriority = -1; - CLightEntity* pNearestLight = NULL; - int16 nDefaultId = Get3DEngine()->GetBlackCMTexID(); - - if (!pVisArea) - { - if (Get3DEngine()->IsObjectTreeReady()) - { - Get3DEngine()->GetObjectTree()->GetNearestCubeProbe(fMinDistance, nMaxPriority, pNearestLight, &objBox); - } - } - else - { - Get3DEngine()->GetVisAreaManager()->GetNearestCubeProbe(fMinDistance, nMaxPriority, pNearestLight, &objBox); - } - - if (pNearestLight) - { - ITexture* pTexCM = bSpecular ? pNearestLight->m_light.GetSpecularCubemap() : pNearestLight->m_light.GetDiffuseCubemap(); - // Return cubemap ID or -1 if invalid - return (pTexCM && pTexCM->GetTextureType() >= eTT_Cube) ? pTexCM->GetTextureID() : nDefaultId; - } - - // No cubemap found - return nDefaultId; -} - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::IsAfterWater(const Vec3& vPos, const SRenderingPassInfo& passInfo) -{ - // considered "after water" if any of the following is true: - // - Position & camera are on the same side of the water surface on recursive level 0 - // - Position & camera are on opposite sides of the water surface on recursive level 1 - - float fWaterLevel; - if (OceanToggle::IsActive()) - { - if (!OceanRequest::OceanIsEnabled()) - { - return true; - } - fWaterLevel = OceanRequest::GetOceanLevel(); - } - else - { - fWaterLevel = GetOcean() ? GetOcean()->GetWaterLevel() : WATER_LEVEL_UNKNOWN; - } - - return (0.5f - passInfo.GetRecursiveLevel()) * (0.5f - passInfo.IsCameraUnderWater()) * (vPos.z - fWaterLevel) > 0; -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::RenderObjectDebugInfo(IRenderNode* pEnt, float fEntDistance, const SRenderingPassInfo& passInfo) -{ - if (!passInfo.IsGeneralPass()) - { - return; - } - - m_arrRenderDebugInfo.push_back(SObjManRenderDebugInfo(pEnt, fEntDistance)); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::RemoveCullJobProducer() -{ - m_CheckOcclusionOutputQueue.RemoveProducer(); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::AddCullJobProducer() -{ - m_CheckOcclusionOutputQueue.AddProducer(); -} - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::CheckOcclusion_TestAABB(const AABB& rAABB, float fEntDistance) -{ - return m_CullThread.TestAABB(rAABB, fEntDistance); -} - - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::CheckOcclusion_TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) -{ - return m_CullThread.TestQuad(vCenter, vAxisX, vAxisY); -} - -#ifndef _RELEASE -////////////////////////////////////////////////////////////////////////// -void CObjManager::CoverageBufferDebugDraw() -{ - m_CullThread.CoverageBufferDebugDraw(); -} -#endif - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::LoadOcclusionMesh(const char* pFileName) -{ - return m_CullThread.LoadLevel(pFileName); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::PushIntoCullQueue(const SCheckOcclusionJobData& rCheckOcclusionData) -{ -#if !defined(_RELEASE) - IF (!m_CullThread.IsActive(), 0) - { - __debugbreak(); - } - IF (rCheckOcclusionData.type == SCheckOcclusionJobData::QUIT, 0) - { - m_CullThread.SetActive(false); - } -#endif - // Prevent our queue from filling up, and make sure to always leave room for the "QUIT" message. - // If we try to add nodes to a full queue, it's possible for deadlocks to occur. The CheckOcclusionQueue - // is filled from the main thread, and will block if the queue is full. The queue is emptied from a culling - // thread, but the CheckOcclusionOutputQueue is filled from the culling thread and will block if *its* queue is - // full. The main thread is the one that empties the output queue thread, so queues that are full on both sides, - // mixed with bad timing, can cause a deadlock. Such are the perils of lockless fixed size queues. :( - // Rather than locking up, we will instead emit a warning and over-cull by not even submitting our geometry for - // potential rendering. - if ((m_CheckOcclusionQueue.FreeCount() > 1) || - (rCheckOcclusionData.type == SCheckOcclusionJobData::QUIT)) - { - m_CheckOcclusionQueue.Push(rCheckOcclusionData); - } - else - { - // If this warning is hit in the editor, it's likely because of editing terrain. Edited terrain draws at the highest - // LOD, which means you'll need to set this to (heightmap height * width) / (32 * 32) at a bare minimum to have a - // large enough buffer. It will need to be even larger if you have significant amounts of static geometry in the level too. - // If this warning is hit in-game, you'll just need to use trial and error to determine a large enough size. - AZ_Warning("Cull", false, - "Occlusion Queue is full - need to set the e_CheckOcclusionQueueSize CVar value larger (current value = %u).", - m_CheckOcclusionQueue.BufferSize()); - } - -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::PopFromCullQueue(SCheckOcclusionJobData* pCheckOcclusionData) -{ - m_CheckOcclusionQueue.Pop(pCheckOcclusionData); -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::PushIntoCullOutputQueue(const SCheckOcclusionOutput& rCheckOcclusionOutput) -{ - // Prevent our output queue from filling up. If we try to add nodes to a full queue, it's possible for deadlocks - // to occur. (See explanation in PushIntoCullQueue() above) - // Rather than locking up, we will instead emit a warning and over-cull by not even submitting our geometry for - // potential rendering. - if (m_CheckOcclusionOutputQueue.FreeCount() > 0) - { - m_CheckOcclusionOutputQueue.Push(rCheckOcclusionOutput); - } - else - { - // If this warning is hit in the editor, it's likely because of editing terrain. This should likely be set to 2x to 4x the - // size of e_CheckOcclusionQueueSize. - // If this warning is hit in-game, you'll just need to use trial and error to determine a large enough size. - AZ_Warning("Cull", false, - "Occlusion Output Queue is full - need to set the e_CheckOcclusionOutputQueueSize CVar value larger (current value = %u).", - m_CheckOcclusionOutputQueue.BufferSize()); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CObjManager::PopFromCullOutputQueue(SCheckOcclusionOutput* pCheckOcclusionOutput) -{ - return m_CheckOcclusionOutputQueue.Pop(pCheckOcclusionOutput); -} - -/////////////////////////////////////////////////////////////////////////////// -uint8 CObjManager::GetDissolveRef(float fDist, float fMVD) -{ - float fDissolveDist = 1.0f / CLAMP(0.1f * fMVD, GetFloatCVar(e_DissolveDistMin), GetFloatCVar(e_DissolveDistMax)); - - return (uint8)SATURATEB((1.0f + (fDist - fMVD) * fDissolveDist) * 255.f); -} - -/////////////////////////////////////////////////////////////////////////////// -float CObjManager::GetLodDistDissolveRef(SLodDistDissolveTransitionState* pState, float curDist, int nNewLod, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - float fDissolveDistbandClamped = min(GetFloatCVar(e_DissolveDistband), curDist * .4f) + 0.001f; - - if (!pState->fStartDist) - { - pState->fStartDist = curDist; - pState->nOldLod = nNewLod; - pState->nNewLod = nNewLod; - - pState->bFarside = (pState->nNewLod < pState->nOldLod && pState->nNewLod != -1) || pState->nOldLod == -1; - } - else if (pState->nNewLod != nNewLod) - { - pState->nNewLod = nNewLod; - pState->fStartDist = curDist; - - pState->bFarside = (pState->nNewLod < pState->nOldLod && pState->nNewLod != -1) || pState->nOldLod == -1; - } - else if ((pState->nOldLod != pState->nNewLod)) - { - // transition complete - if ( - (!pState->bFarside && curDist - pState->fStartDist > fDissolveDistbandClamped) || - (pState->bFarside && pState->fStartDist - curDist > fDissolveDistbandClamped) - ) - { - pState->nOldLod = pState->nNewLod; - } - // with distance based transitions we can always 'fail' back to the previous LOD. - else if ( - (!pState->bFarside && curDist < pState->fStartDist) || - (pState->bFarside && curDist > pState->fStartDist) - ) - { - pState->nNewLod = pState->nOldLod; - } - } - - if (pState->nOldLod == pState->nNewLod) - { - return 0.f; - } - else - { - if (pState->bFarside) - { - return SATURATE(((pState->fStartDist - curDist) * (1.f / fDissolveDistbandClamped))); - } - else - { - return SATURATE(((curDist - pState->fStartDist) * (1.f / fDissolveDistbandClamped))); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -int CObjManager::GetObjectLOD(const IRenderNode* pObj, float fDistance) -{ - SFrameLodInfo frameLodInfo = Get3DEngine()->GetFrameLodInfo(); - int resultLod = MAX_STATOBJ_LODS_NUM - 1; - bool boundingBBoxBased = ((pObj->GetRndFlags() & ERF_LOD_BBOX_BASED) != 0); - // If it is bounding box based, it does not use face area data. - bool useLodFaceArea = (GetCVars()->e_LodFaceArea != 0) && !boundingBBoxBased; - - if (useLodFaceArea) - { - float distances[SMeshLodInfo::s_nMaxLodCount]; - useLodFaceArea = pObj->GetLodDistances(frameLodInfo, distances); - if (useLodFaceArea) - { - for (uint i = 0; i < MAX_STATOBJ_LODS_NUM - 1; ++i) - { - if (fDistance < distances[i]) - { - resultLod = i; - break; - } - } - } - } - - if (!useLodFaceArea) - { - const float fLodRatioNorm = pObj->GetLodRatioNormalized(); - const float fRadius = pObj->GetBBox().GetRadius(); - resultLod = (int)(fDistance * (fLodRatioNorm * fLodRatioNorm) / (max(frameLodInfo.fLodRatio * min(fRadius, GetFloatCVar(e_LodCompMaxSize)), 0.001f))); - } - - return resultLod; -} - -/////////////////////////////////////////////////////////////////////////////// -void COctreeNode::GetObjectsByFlags(uint dwFlags, PodArray& lstObjects) -{ - unsigned int nCurrentObject(eRNListType_First); - for (nCurrentObject = eRNListType_First; nCurrentObject < eRNListType_ListsNum; ++nCurrentObject) - { - for (IRenderNode* pObj = m_arrObjects[nCurrentObject].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if ((pObj->GetRndFlags() & dwFlags) == dwFlags) - { - lstObjects.Add(pObj); - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetObjectsByFlags(dwFlags, lstObjects); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void COctreeNode::GetObjectsByType(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback) -{ - if (objType == eERType_Light && !m_bHasLights) - { - return; - } - - if (pBBox && !Overlap::AABB_AABB(*pBBox, GetObjectsBBox())) - { - return; - } - - ERNListType eListType = IRenderNode::GetRenderNodeListId(objType); - - for (IRenderNode* pObj = m_arrObjects[eListType].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->GetRenderNodeType() == objType) - { - AABB box; - pObj->FillBBox(box); - if (!pBBox || Overlap::AABB_AABB(*pBBox, box)) - { - // Check the filterCallback to perform a final validation that we want this object - // to appear in our results list. If there's no filterCallback, then always add - // the object. - if (!filterCallback || filterCallback(pObj, objType)) - { - lstObjects.Add(pObj); - } - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetObjectsByType(lstObjects, objType, pBBox, filterCallback); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void COctreeNode::GetNearestCubeProbe(float& fMinDistance, int& nMaxPriority, CLightEntity*& pNearestLight, const AABB* pBBox) -{ - if (!m_bHasLights) - { - return; - } - - if (!pBBox || pBBox && !Overlap::AABB_AABB(*pBBox, GetObjectsBBox())) - { - return; - } - - Vec3 vCenter = pBBox->GetCenter(); - - ERNListType eListType = IRenderNode::GetRenderNodeListId(eERType_Light); - - for (IRenderNode* pObj = m_arrObjects[eListType].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - if (pObj->GetRenderNodeType() == eERType_Light) - { - AABB box; - pObj->FillBBox(box); - if (Overlap::AABB_AABB(*pBBox, box)) - { - CLightEntity* pLightEnt = (CLightEntity*)pObj; - CDLight* pLight = &pLightEnt->m_light; - - if (pLight->m_Flags & DLF_DEFERRED_CUBEMAPS) - { - Vec3 vCenterRel = vCenter - pLight->GetPosition(); - Vec3 vCenterOBBSpace; - vCenterOBBSpace.x = pLightEnt->m_Matrix.GetColumn0().GetNormalized().dot(vCenterRel); - vCenterOBBSpace.y = pLightEnt->m_Matrix.GetColumn1().GetNormalized().dot(vCenterRel); - vCenterOBBSpace.z = pLightEnt->m_Matrix.GetColumn2().GetNormalized().dot(vCenterRel); - - // Check if object center is within probe OBB - Vec3 vProbeExtents = pLight->m_ProbeExtents; - if (fabs(vCenterOBBSpace.x) < vProbeExtents.x && fabs(vCenterOBBSpace.y) < vProbeExtents.y && fabs(vCenterOBBSpace.z) < vProbeExtents.z) - { - if (pLight->m_nSortPriority > nMaxPriority - && pLight->m_fProbeAttenuation > 0) // Don't return a probe that is disabled/invisible. In particular this provides better results when lighting particles. - { - pNearestLight = (CLightEntity*)pObj; - nMaxPriority = pLight->m_nSortPriority; - fMinDistance = 0; - } - } - } - } - } - } - - for (int i = 0; i < 8; i++) - { - if (m_arrChilds[i]) - { - m_arrChilds[i]->GetNearestCubeProbe(fMinDistance, nMaxPriority, pNearestLight, pBBox); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -bool CObjManager::IsBoxOccluded(const AABB& objBox, - [[maybe_unused]] float fDistance, - OcclusionTestClient* const __restrict pOcclTestVars, - bool/* bIndoorOccludersOnly*/, - [[maybe_unused]] EOcclusionObjectType eOcclusionObjectType, - const SRenderingPassInfo& passInfo) -{ - // if object was visible during last frames - const uint32 mainFrameID = passInfo.GetMainFrameID(); - - if (GetCVars()->e_OcclusionLazyHideFrames) - { - //This causes massive spikes in draw calls when rotating - if (pOcclTestVars->nLastVisibleMainFrameID > mainFrameID - GetCVars()->e_OcclusionLazyHideFrames) - { - // prevent checking all objects in same frame - int nId = (int)(UINT_PTR(pOcclTestVars) / 256); - if ((nId & 7) != (mainFrameID & 7)) - { - return false; - } - } - } - - // use fast and reliable test right here - CVisAreaManager* pVisAreaManager = GetVisAreaManager(); - if (GetCVars()->e_OcclusionVolumes && pVisAreaManager && pVisAreaManager->IsOccludedByOcclVolumes(objBox, passInfo)) - { - pOcclTestVars->nLastOccludedMainFrameID = mainFrameID; - return true; - } - - if (GetCVars()->e_CoverageBuffer) - { - return pOcclTestVars->nLastOccludedMainFrameID == mainFrameID - 1; - } - - pOcclTestVars->nLastVisibleMainFrameID = mainFrameID; - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CLightEntity::FillBBox(AABB& aabb) -{ - aabb = CLightEntity::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CLightEntity::GetRenderNodeType() -{ - return eERType_Light; -} - -/////////////////////////////////////////////////////////////////////////////// -float CLightEntity::GetMaxViewDist() -{ - if (m_light.m_Flags & DLF_SUN) - { - return 10.f * DISTANCE_TO_THE_SUN; - } - return max(GetCVars()->e_ViewDistMin, CLightEntity::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatioLights * GetViewDistanceMultiplier()); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CLightEntity::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - assert(bWorldOnly); - return m_light.m_Origin; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void COcean::FillBBox(AABB& aabb) -{ - aabb = COcean::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType COcean::GetRenderNodeType() -{ - return eERType_WaterVolume; -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 COcean::GetPos(bool) const -{ - return Vec3(0, 0, 0); -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr COcean::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CFogVolumeRenderNode::FillBBox(AABB& aabb) -{ - aabb = CFogVolumeRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CFogVolumeRenderNode::GetRenderNodeType() -{ - return eERType_FogVolume; -} - -/////////////////////////////////////////////////////////////////////////////// -float CFogVolumeRenderNode::GetMaxViewDist() -{ - return max(GetCVars()->e_ViewDistMin, CFogVolumeRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistanceMultiplier()); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CFogVolumeRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_pos; -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CFogVolumeRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return 0; -} -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CDecalRenderNode::FillBBox(AABB& aabb) -{ - aabb = CDecalRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CDecalRenderNode::GetRenderNodeType() -{ - return eERType_Decal; -} - -/////////////////////////////////////////////////////////////////////////////// -float CDecalRenderNode::GetMaxViewDist() -{ - return m_decalProperties.m_maxViewDist * GetViewDistanceMultiplier(); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CDecalRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_pos; -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CDecalRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CWaterVolumeRenderNode::FillBBox(AABB& aabb) -{ - aabb = CWaterVolumeRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CWaterVolumeRenderNode::GetRenderNodeType() -{ - return eERType_WaterVolume; -} - -/////////////////////////////////////////////////////////////////////////////// -float CWaterVolumeRenderNode::GetMaxViewDist() -{ - return max(GetCVars()->e_ViewDistMin, CWaterVolumeRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistanceMultiplier()); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CWaterVolumeRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_center; -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CWaterVolumeRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CDistanceCloudRenderNode::FillBBox(AABB& aabb) -{ - aabb = CDistanceCloudRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CDistanceCloudRenderNode::GetRenderNodeType() -{ - return eERType_DistanceCloud; -} - -/////////////////////////////////////////////////////////////////////////////// -float CDistanceCloudRenderNode::GetMaxViewDist() -{ - return max(GetCVars()->e_ViewDistMin, CDistanceCloudRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistanceMultiplier()); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CDistanceCloudRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_pos; -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CDistanceCloudRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) -#include "PrismRenderNode.h" - -/////////////////////////////////////////////////////////////////////////////// -void CPrismRenderNode::FillBBox(AABB& aabb) -{ - aabb = CPrismRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CPrismRenderNode::GetRenderNodeType() -{ - return eERType_PrismObject; -} - -/////////////////////////////////////////////////////////////////////////////// -float CPrismRenderNode::GetMaxViewDist() -{ - return 1000.0f; -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CPrismRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_mat.GetTranslation(); -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CPrismRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - -#endif - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -#include "VolumeObjectRenderNode.h" -#include "CloudRenderNode.h" - -/////////////////////////////////////////////////////////////////////////////// -void CVolumeObjectRenderNode::FillBBox(AABB& aabb) -{ - aabb = CVolumeObjectRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CVolumeObjectRenderNode::GetRenderNodeType() -{ - return eERType_VolumeObject; -} - -/////////////////////////////////////////////////////////////////////////////// -float CVolumeObjectRenderNode::GetMaxViewDist() -{ - return max(GetCVars()->e_ViewDistMin, CVolumeObjectRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistanceMultiplier()); -} - -/////////////////////////////////////////////////////////////////////////////// -Vec3 CVolumeObjectRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_pos; -} - -/////////////////////////////////////////////////////////////////////////////// -_smart_ptr CVolumeObjectRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CCloudRenderNode::FillBBox(AABB& aabb) -{ - aabb = CCloudRenderNode::GetBBox(); -} - -/////////////////////////////////////////////////////////////////////////////// -EERType CCloudRenderNode::GetRenderNodeType() -{ - return eERType_Cloud; -} - -////////////////////////////////////////////////////////////////////////// -float CCloudRenderNode::GetMaxViewDist() -{ - return max(GetCVars()->e_ViewDistMin, CCloudRenderNode::GetBBox().GetRadius() * GetCVars()->e_ViewDistRatio * GetViewDistanceMultiplier()); -} - -////////////////////////////////////////////////////////////////////////// -Vec3 CCloudRenderNode::GetPos([[maybe_unused]] bool bWorldOnly) const -{ - return m_pos; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CCloudRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos) -{ - return m_pMaterial; -} diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree_MT.cpp b/Code/CryEngine/Cry3DEngine/ObjectsTree_MT.cpp deleted file mode 100644 index 654fa26848..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree_MT.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "CullBuffer.h" -#include "RenderMeshMerger.h" -#include "DecalManager.h" -#include "VisAreas.h" -#include "LightEntity.h" - -#ifdef WIN32 -#include -#endif //WIN32 - -#ifndef PI -#define PI 3.14159f -#endif - -////////////////////////////////////////////////////////////////////////// -void CObjManager::PrepareCullbufferAsync(const CCamera& rCamera) -{ - AZ_TRACE_METHOD(); - if (!(gEnv->IsDedicated())) - { - m_CullThread.PrepareCullbufferAsync(rCamera); - } -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::BeginOcclusionCulling(const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - if (!gEnv->IsDedicated()) - { - m_CullThread.CullStart(passInfo); - } -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::EndOcclusionCulling(bool waitForOcclusionJobCompletion) -{ - AZ_TRACE_METHOD(); - if (!gEnv->IsDedicated()) - { - m_CullThread.CullEnd(waitForOcclusionJobCompletion); - } -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::RenderBufferedRenderMeshes(const SRenderingPassInfo& passInfo) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - SCheckOcclusionOutput outputData; - while (1) - { - { - AZ_PROFILE_SCOPE_STALL(AZ::Debug::ProfileCategory::Renderer, "PopFromCullOutputQueue"); - // process till we know that no more procers are working - if (!GetObjManager()->PopFromCullOutputQueue(&outputData)) - { - break; - } - } - - switch (outputData.type) - { - case SCheckOcclusionOutput::ROAD_DECALS: - GetObjManager()->RenderDecalAndRoad(outputData.common.pObj, - outputData.objBox, - outputData.common.fEntDistance, - outputData.common.bCheckPerObjectOcclusion, - passInfo, - outputData.rendItemSorter); - break; - case SCheckOcclusionOutput::COMMON: - GetObjManager()->RenderObject(outputData.common.pObj, - outputData.objBox, - outputData.common.fEntDistance, - outputData.common.pObj->GetRenderNodeType(), - passInfo, - outputData.rendItemSorter); - break; - default: - CryFatalError("Got Unknown Output type from CheckOcclusion"); - break; - } - } -#if !defined(_RELEASE) - if (GetCVars()->e_CoverageBufferDebug) - { - GetObjManager()->CoverageBufferDebugDraw(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -void CObjManager::BeginCulling() -{ - m_CheckOcclusionOutputQueue.SetRunningState(); -} - diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize.cpp b/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize.cpp deleted file mode 100644 index dddf7567b9..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "DecalRenderNode.h" -#include "WaterVolumeRenderNode.h" -#include "DistanceCloudRenderNode.h" -#include "VisAreas.h" -#include - -#pragma pack(push,4) - -// common node data -struct SRenderNodeChunk -{ - AABB m_WSBBox = AABB(); - uint16 m_nLayerId = 0; - int8 m_cShadowLodBias = 0; - uint8 m_ucDummy = 0; - uint32 m_dwRndFlags = 0; - uint16 m_nObjectTypeIndex = 0; - uint16 m_pad16 = 0; - float m_fViewDistanceMultiplier = 0.0f; - uint8 m_ucLodRatio = 0; - // Can't guarantee alignment for derived structs across different compilers - // http://stackoverflow.com/questions/22404423/c-pod-struct-inheritance-are-there-any-guarantees-about-the-memory-layout-of - uint8 m_pad8 = 0; - uint16 m_pad16B = 0; - - AUTO_STRUCT_INFO_LOCAL -}; - -#define ROADCHUNKFLAG_IGNORE_TERRAIN_HOLES 1 -#define ROADCHUNKFLAG_PHYSICALIZE 2 - -struct SDecalChunk - : public SRenderNodeChunk -{ - int16 m_projectionType = 0; - uint8 m_deferred = 0; - uint8 m_pad8 = 0; - f32 m_depth = 0.0f; - Vec3 m_pos = Vec3(0.0f); - Vec3 m_normal = Vec3(0.0f); - Matrix33 m_explicitRightUpFront = Matrix33(); - f32 m_radius = 0.0f; - int32 m_nMaterialId = 0; - int32 m_nSortPriority = 0; - - AUTO_STRUCT_INFO_LOCAL -}; - -struct SWaterVolumeChunk - : public SRenderNodeChunk -{ - // volume type and id - int32 m_volumeTypeAndMiscBits = 0; - uint64 m_volumeID = 0; - - // material - int32 m_materialID = 0; - - // fog properties - f32 m_fogDensity = 0.0f; - Vec3 m_fogColor = Vec3(0.0f); - Plane m_fogPlane = Plane(); - f32 m_fogShadowing = 0.0f; - - // caustic propeties - uint8 m_caustics = 0; - uint8 m_pad8 = 0; - uint16 m_pad16 = 0; - f32 m_causticIntensity = 0.0f; - f32 m_causticTiling = 0.0f; - f32 m_causticHeight = 0.0f; - - // render geometry - f32 m_uTexCoordBegin = 0.0f; - f32 m_uTexCoordEnd = 0.0f; - f32 m_surfUScale = 0.0f; - f32 m_surfVScale = 0.0f; - uint32 m_numVertices = 0; - - // physics properties - f32 m_volumeDepth = 0.0f; - f32 m_streamSpeed = 0.0f; - uint32 m_numVerticesPhysAreaContour = 0; - - AUTO_STRUCT_INFO_LOCAL -}; - -struct SWaterVolumeVertex -{ - Vec3 m_xyz; - - AUTO_STRUCT_INFO_LOCAL -}; - -struct SDistanceCloudChunk - : public SRenderNodeChunk -{ - Vec3 m_pos = Vec3(0.0f); - f32 m_sizeX = 0.0f; - f32 m_sizeY = 0.0f; - f32 m_rotationZ = 0.0f; - int32 m_materialID = 0; - - AUTO_STRUCT_INFO_LOCAL -}; - -#pragma pack(pop) - -AUTO_TYPE_INFO(EERType) - -#include "TypeInfo_impl.h" -#include "ObjectsTree_Serialize_info.h" - -inline void CopyCommonData(SRenderNodeChunk* pChunk, IRenderNode* pObj) -{ - pChunk->m_WSBBox = pObj->GetBBox(); - //COPY_MEMBER_SAVE(pChunk,pObj,m_fWSMaxViewDist); - COPY_MEMBER_SAVE(pChunk, pObj, m_dwRndFlags); - COPY_MEMBER_SAVE(pChunk, pObj, m_fViewDistanceMultiplier); - COPY_MEMBER_SAVE(pChunk, pObj, m_ucLodRatio); - COPY_MEMBER_SAVE(pChunk, pObj, m_cShadowLodBias); - pChunk->m_nLayerId = pObj->GetLayerId(); -} - -inline void LoadCommonData(SRenderNodeChunk* pChunk, IRenderNode* pObj, const SLayerVisibility* pLayerVisibility) -{ - //COPY_MEMBER_LOAD(pObj,pChunk,m_fWSMaxViewDist); - COPY_MEMBER_LOAD(pObj, pChunk, m_dwRndFlags); - COPY_MEMBER_LOAD(pObj, pChunk, m_fViewDistanceMultiplier); - COPY_MEMBER_LOAD(pObj, pChunk, m_ucLodRatio); - COPY_MEMBER_LOAD(pObj, pChunk, m_cShadowLodBias); - pObj->m_dwRndFlags &= ~(ERF_HIDDEN | ERF_SELECTED); - if (pObj->m_dwRndFlags & ERF_CASTSHADOWMAPS) - { - pObj->m_dwRndFlags |= ERF_HAS_CASTSHADOWMAPS; - } - - if (NULL != pLayerVisibility) - { - const uint16 newLayerId = pLayerVisibility->pLayerIdTranslation[pChunk->m_nLayerId]; - pObj->SetLayerId(newLayerId); - } - else - { - pObj->SetLayerId(pChunk->m_nLayerId); - } -} - -////////////////////////////////////////////////////////////////////////// -inline static uint8 CheckLayerVisibility(const uint16 layerId, const SLayerVisibility* pLayerVisibility) -{ - return pLayerVisibility->pLayerVisibilityMask[layerId >> 3] & (1 << (layerId & 7)); -} - -////////////////////////////////////////////////////////////////////////// -int COctreeNode::SaveObjects([[maybe_unused]] CMemoryBlock* pMemBlock, [[maybe_unused]] std::vector* pStatObjTable, [[maybe_unused]] std::vector<_smart_ptr >* pMatTable, [[maybe_unused]] std::vector* pStatInstGroupTable, [[maybe_unused]] EEndian eEndian, [[maybe_unused]] const SHotUpdateInfo* pExportInfo) -{ -# if !ENGINE_ENABLE_COMPILATION - CryFatalError("serialization code removed, please enable ENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h"); - return 0; -# else - uint32 nObjTypeMask = pExportInfo ? pExportInfo->nObjTypeMask : (uint32) ~0; - - int nBlockSize = 0; - - // FreeAreaBrushes(); - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pObj = m_arrObjects[l].m_pFirstNode; pObj; pObj = pObj->m_pNext) - { - IRenderNode* pRenderNode = pObj; - EERType eType = pRenderNode->GetRenderNodeType(); - - if (!(nObjTypeMask & (1 << eType))) - { - continue; - } - - if ((pRenderNode->GetRndFlags() & ERF_COMPONENT_ENTITY) != 0) - { - continue; - } - - nBlockSize += GetSingleObjectSize(pObj, pExportInfo); - } - } - - if (!pMemBlock || !nBlockSize) - { - return nBlockSize; - } - - pMemBlock->Allocate(nBlockSize); - byte* pPtr = (byte*)pMemBlock->GetData(); - - int nDatanSize = nBlockSize; - - for (int l = 0; l < eRNListType_ListsNum; l++) - { - for (IRenderNode* pRenderNode = m_arrObjects[l].m_pFirstNode; pRenderNode; pRenderNode = pRenderNode->m_pNext) - { - EERType eType = pRenderNode->GetRenderNodeType(); - - if (!(nObjTypeMask & (1 << eType))) - { - continue; - } - - if ((pRenderNode->GetRndFlags() & ERF_COMPONENT_ENTITY) != 0) - { - continue; - } - - SaveSingleObject(pPtr, nDatanSize, pRenderNode, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo); - } - } - - assert(pPtr == (byte*)pMemBlock->GetData() + nBlockSize); - assert(nDatanSize == 0); - - return nBlockSize; -# endif -} - -////////////////////////////////////////////////////////////////////////// -int COctreeNode::LoadObjects(byte* pPtr, byte* pEndPtr, std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, EEndian eEndian, int nChunkVersion, const SLayerVisibility* pLayerVisibility) -{ - while (pPtr < pEndPtr) - { - LoadSingleObject(pPtr, pStatObjTable, pMatTable, eEndian, nChunkVersion, pLayerVisibility, m_nSID); - } - - return 0; -} - -int COctreeNode::GetSingleObjectSize(IRenderNode* pObj, [[maybe_unused]] const SHotUpdateInfo* pExportInfo) -{ - IRenderNode* pRenderNode = pObj; - EERType eType = pRenderNode->GetRenderNodeType(); - - int nBlockSize = 0; - - if (eType == eERType_Decal && !(pRenderNode->GetRndFlags() & ERF_PROCEDURAL)) - { - nBlockSize += sizeof(eType); - nBlockSize += sizeof(SDecalChunk); - } - else if (eType == eERType_WaterVolume) - { - CWaterVolumeRenderNode* pWVRN(static_cast< CWaterVolumeRenderNode* >(pRenderNode)); - const SWaterVolumeSerialize* pSerParams(pWVRN->GetSerializationParams()); - if (pSerParams && pWVRN->m_hasToBeSerialised) - { - nBlockSize += sizeof(eType); - nBlockSize += sizeof(SWaterVolumeChunk); - nBlockSize += (pSerParams->m_vertices.size() + pSerParams->m_physicsAreaContour.size()) * sizeof(SWaterVolumeVertex); - int cntAux; - pWVRN->GetAuxSerializationDataPtr(cntAux); - nBlockSize += cntAux * sizeof(float); - } - } - else if (eType == eERType_DistanceCloud) - { - nBlockSize += sizeof(eType); - nBlockSize += sizeof(SDistanceCloudChunk); - } - // align to 4 - while (UINT_PTR(nBlockSize) & 3) - { - nBlockSize++; - } - - return nBlockSize; -} - -void COctreeNode::SaveSingleObject(byte*& pPtr, int& nDatanSize, IRenderNode* pEnt, [[maybe_unused]] std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, [[maybe_unused]] std::vector* pStatInstGroupTable, EEndian eEndian, [[maybe_unused]] const SHotUpdateInfo* pExportInfo) -{ - EERType eType = pEnt->GetRenderNodeType(); - - if (eERType_Decal == eType && !(pEnt->GetRndFlags() & ERF_PROCEDURAL)) - { - AddToPtr(pPtr, nDatanSize, eType, eEndian); - - CDecalRenderNode* pObj((CDecalRenderNode*)pEnt); - - SDecalChunk chunk; - - CopyCommonData(&chunk, pObj); - - // decal properties - const SDecalProperties* pDecalProperties(pObj->GetDecalProperties()); - assert(pDecalProperties); - chunk.m_projectionType = pDecalProperties->m_projectionType; - chunk.m_deferred = pDecalProperties->m_deferred; - chunk.m_pos = pDecalProperties->m_pos; - chunk.m_normal = pDecalProperties->m_normal; - chunk.m_explicitRightUpFront = pDecalProperties->m_explicitRightUpFront; - chunk.m_radius = pDecalProperties->m_radius; - chunk.m_depth = pDecalProperties->m_depth; - - chunk.m_nMaterialId = CObjManager::GetItemId(pMatTable, pObj->GetMaterial()); - chunk.m_nSortPriority = pDecalProperties->m_sortPrio; - - AddToPtr(pPtr, nDatanSize, chunk, eEndian); - } - else if (eERType_WaterVolume == eType) - { - CWaterVolumeRenderNode* pObj((CWaterVolumeRenderNode*)pEnt); - - if (pObj->m_hasToBeSerialised) - { - // get access to serialization parameters - const SWaterVolumeSerialize* pSerData(pObj->GetSerializationParams()); - if (pSerData) - { - //assert( pSerData ); // trying to save level outside the editor? - - // save type - AddToPtr(pPtr, nDatanSize, eType, eEndian); - - // save node data - SWaterVolumeChunk chunk; - int cntAux; - float* pAuxData = pObj->GetAuxSerializationDataPtr(cntAux); - - CopyCommonData(&chunk, pObj); - - chunk.m_volumeTypeAndMiscBits = (pSerData->m_volumeType & 0xFFFF) | ((pSerData->m_capFogAtVolumeDepth ? 1 : 0) << 16) | ((pSerData->m_fogColorAffectedBySun ? 0 : 1) << 17) | (cntAux << 24); - chunk.m_volumeID = pSerData->m_volumeID; - - chunk.m_materialID = CObjManager::GetItemId(pMatTable, pSerData->m_pMaterial); - - chunk.m_fogDensity = pSerData->m_fogDensity; - chunk.m_fogColor = pSerData->m_fogColor; - chunk.m_fogPlane = pSerData->m_fogPlane; - chunk.m_fogShadowing = pSerData->m_fogShadowing; - - chunk.m_caustics = pSerData->m_caustics; - chunk.m_causticIntensity = pSerData->m_causticIntensity; - chunk.m_causticTiling = pSerData->m_causticTiling; - chunk.m_causticHeight = pSerData->m_causticHeight; - - chunk.m_uTexCoordBegin = pSerData->m_uTexCoordBegin; - chunk.m_uTexCoordEnd = pSerData->m_uTexCoordEnd; - chunk.m_surfUScale = pSerData->m_surfUScale; - chunk.m_surfVScale = pSerData->m_surfVScale; - chunk.m_numVertices = pSerData->m_vertices.size(); - - chunk.m_volumeDepth = pSerData->m_volumeDepth; - chunk.m_streamSpeed = pSerData->m_streamSpeed; - chunk.m_numVerticesPhysAreaContour = pSerData->m_physicsAreaContour.size(); - - AddToPtr(pPtr, nDatanSize, chunk, eEndian); - AddToPtr(pPtr, pAuxData, cntAux, eEndian); - nDatanSize -= cntAux * sizeof(pAuxData[0]); - - // save vertices - for (size_t i(0); i < pSerData->m_vertices.size(); ++i) - { - SWaterVolumeVertex v; - v.m_xyz = pSerData->m_vertices[i]; - - AddToPtr(pPtr, nDatanSize, v, eEndian); - } - - // save physics area contour vertices - for (size_t i(0); i < pSerData->m_physicsAreaContour.size(); ++i) - { - SWaterVolumeVertex v; - v.m_xyz = pSerData->m_physicsAreaContour[i]; - - AddToPtr(pPtr, nDatanSize, v, eEndian); - } - } - } - } - else if (eERType_DistanceCloud == eType) - { - AddToPtr(pPtr, nDatanSize, eType, eEndian); - - CDistanceCloudRenderNode* pObj((CDistanceCloudRenderNode*)pEnt); - - SDistanceCloudChunk chunk; - - CopyCommonData(&chunk, pObj); - - // distance cloud properties - SDistanceCloudProperties properties(pObj->GetProperties()); - chunk.m_pos = properties.m_pos; - chunk.m_sizeX = properties.m_sizeX; - chunk.m_sizeY = properties.m_sizeY; - chunk.m_rotationZ = properties.m_rotationZ; - chunk.m_materialID = CObjManager::GetItemId(pMatTable, pObj->GetMaterial()); - - AddToPtr(pPtr, nDatanSize, chunk, eEndian); - } - - // align to 4 - while (UINT_PTR(pPtr) & 3) - { - byte emptyByte = 222; - memcpy(pPtr, &emptyByte, sizeof(emptyByte)); - pPtr += sizeof(emptyByte); - nDatanSize -= sizeof(emptyByte); - } -} - -void COctreeNode::LoadSingleObject(byte*& pPtr, [[maybe_unused]] std::vector* pStatObjTable, std::vector<_smart_ptr >* pMatTable, EEndian eEndian, [[maybe_unused]] int nChunkVersion, const SLayerVisibility* pLayerVisibility, int nSID) -{ - EERType eType = *StepData(pPtr, eEndian); - - // For these structures, our Endian swapping is built in to the member copy. - if (eERType_Decal == eType) - { - SDecalChunk* pChunk(StepData(pPtr, eEndian)); - if (!CheckRenderFlagsMinSpec(pChunk->m_dwRndFlags)) - { - return; - } - - if (Get3DEngine()->IsLayerSkipped(pChunk->m_nLayerId)) - { - return; - } - - CDecalRenderNode* pObj(new CDecalRenderNode()); - - // common node data - pObj->SetBBox(pChunk->m_WSBBox); - LoadCommonData(pChunk, pObj, pLayerVisibility); - - // decal properties - SDecalProperties properties; - - switch (pChunk->m_projectionType) - { - case SDecalProperties::eProjectOnTerrainAndStaticObjects: - { - properties.m_projectionType = SDecalProperties::eProjectOnTerrainAndStaticObjects; - break; - } - case SDecalProperties::eProjectOnTerrain: - { - properties.m_projectionType = SDecalProperties::eProjectOnTerrain; - break; - } - case SDecalProperties::ePlanar: - default: - { - properties.m_projectionType = SDecalProperties::ePlanar; - break; - } - } - memcpy(&properties.m_pos, &pChunk->m_pos, sizeof (pChunk->m_pos)); - memcpy(&properties.m_normal, &pChunk->m_normal, sizeof (pChunk->m_normal)); - memcpy(&properties.m_explicitRightUpFront, &pChunk->m_explicitRightUpFront, sizeof (pChunk->m_explicitRightUpFront)); - memcpy(&properties.m_radius, &pChunk->m_radius, sizeof(pChunk->m_radius)); - memcpy(&properties.m_depth, &pChunk->m_depth, sizeof(pChunk->m_depth)); - - _smart_ptr pMaterial(CObjManager::GetItemPtr(pMatTable, pChunk->m_nMaterialId)); - assert(pMaterial); - properties.m_pMaterialName = pMaterial ? pMaterial->GetName() : ""; - properties.m_sortPrio = pChunk->m_nSortPriority; - properties.m_deferred = pChunk->m_deferred; - - pObj->SetDecalProperties(properties); - - // set object visibility - if (NULL != pLayerVisibility) - { - CRY_ASSERT(pChunk->m_nLayerId != 0); - if (!CheckLayerVisibility(pObj->GetLayerId(), pLayerVisibility)) - { - pObj->SetRndFlags(ERF_HIDDEN, true); - } - } - else if (Get3DEngine()->IsAreaActivationInUse()) - { - // keep everything deactivated, game will activate it later - pObj->SetRndFlags(ERF_HIDDEN, true); - } - - //if( pObj->GetMaterialID() != pChunk->m_materialID ) - if (pObj->GetMaterial() != pMaterial) - { - const char* pMatName("_can't_resolve_material_name_"); - int32 matID(pChunk->m_nMaterialId); - if (matID >= 0 && matID < (int)pMatTable->size()) - { - pMatName = pMaterial ? pMaterial->GetName() : ""; - } - Warning("Warning: Removed placement decal at (%4.2f, %4.2f, %4.2f) with invalid material \"%s\"!\n", pChunk->m_pos.x, pChunk->m_pos.y, pChunk->m_pos.z, pMatName); - pObj->ReleaseNode(); - } - else - { - Get3DEngine()->RegisterEntity(pObj, nSID, nSID); - GetObjManager()->GetDecalsToPrecreate().push_back(pObj); - } - } - else if (eERType_WaterVolume == eType) - { - // read common info - SWaterVolumeChunk* pChunk(StepData(pPtr, eEndian)); - if (!CheckRenderFlagsMinSpec(pChunk->m_dwRndFlags) || Get3DEngine()->IsLayerSkipped(pChunk->m_nLayerId)) - { - for (uint32 j(0); j < pChunk->m_numVertices; ++j) - { - StepData(pPtr, eEndian); - } - - for (uint32 j(0); j < pChunk->m_numVerticesPhysAreaContour; ++j) - { - StepData(pPtr, eEndian); - } - - return; - } - - CWaterVolumeRenderNode* pObj(new CWaterVolumeRenderNode()); - - int auxCntSrc = pChunk->m_volumeTypeAndMiscBits >> 24, auxCntDst; - float* pAuxDataDst = pObj->GetAuxSerializationDataPtr(auxCntDst); - StepData(pPtr, auxCntSrc, eEndian); - memcpy(pAuxDataDst, pAuxDataDst, min(auxCntSrc, auxCntDst) * sizeof(float)); - - // read common node data - pObj->SetBBox(pChunk->m_WSBBox); - LoadCommonData(pChunk, pObj, pLayerVisibility); - - // read vertices - std::vector vertices; - vertices.reserve(pChunk->m_numVertices); - for (uint32 j(0); j < pChunk->m_numVertices; ++j) - { - SWaterVolumeVertex* pVertex(StepData(pPtr, eEndian)); - vertices.push_back(pVertex->m_xyz); - } - - // read physics area contour vertices - std::vector physicsAreaContour; - physicsAreaContour.reserve(pChunk->m_numVerticesPhysAreaContour); - for (uint32 j(0); j < pChunk->m_numVerticesPhysAreaContour; ++j) - { - SWaterVolumeVertex* pVertex(StepData(pPtr, eEndian)); - physicsAreaContour.push_back(pVertex->m_xyz); - } - - const int volumeType = pChunk->m_volumeTypeAndMiscBits & 0xFFFF; - const bool capFogAtVolumeDepth = ((pChunk->m_volumeTypeAndMiscBits & 0x10000) != 0) ? true : false; - const bool fogColorAffectedBySun = ((pChunk->m_volumeTypeAndMiscBits & 0x20000) == 0) ? true : false; - const bool enableCaustics = (pChunk->m_caustics != 0) ? true : false; - - // create volume - switch (volumeType) - { - case IWaterVolumeRenderNode::eWVT_River: - { - pObj->CreateRiver(pChunk->m_volumeID, &vertices[0], pChunk->m_numVertices, pChunk->m_uTexCoordBegin, pChunk->m_uTexCoordEnd, Vec2(pChunk->m_surfUScale, pChunk->m_surfVScale), pChunk->m_fogPlane, false, nSID); - break; - } - case IWaterVolumeRenderNode::eWVT_Area: - { - pObj->CreateArea(pChunk->m_volumeID, &vertices[0], pChunk->m_numVertices, Vec2(pChunk->m_surfUScale, pChunk->m_surfVScale), pChunk->m_fogPlane, false, nSID); - break; - } - case IWaterVolumeRenderNode::eWVT_Ocean: - { - assert(!"COctreeNode::SerializeObjects( ... ) -- Water volume of type \"Ocean\" not supported yet!"); - break; - } - default: - { - assert(!"COctreeNode::SerializeObjects( ... ) -- Invalid water volume type!"); - break; - } - } - - // set material - _smart_ptr pMaterial(CObjManager::GetItemPtr(pMatTable, pChunk->m_materialID)); - - - // set properties - pObj->SetFogDensity(pChunk->m_fogDensity); - pObj->SetFogColor(pChunk->m_fogColor); - pObj->SetFogColorAffectedBySun(fogColorAffectedBySun); - pObj->SetFogShadowing(pChunk->m_fogShadowing); - - pObj->SetVolumeDepth(pChunk->m_volumeDepth); - pObj->SetStreamSpeed(pChunk->m_streamSpeed); - pObj->SetCapFogAtVolumeDepth(capFogAtVolumeDepth); - - pObj->SetCaustics(enableCaustics); - pObj->SetCausticIntensity(pChunk->m_causticIntensity); - pObj->SetCausticTiling(pChunk->m_causticTiling); - pObj->SetCausticHeight(pChunk->m_causticHeight); - - // set object visibility - if (NULL != pLayerVisibility) - { - CRY_ASSERT(pChunk->m_nLayerId != 0); - if (!CheckLayerVisibility(pObj->GetLayerId(), pLayerVisibility)) - { - pObj->SetRndFlags(ERF_HIDDEN, true); - } - } - else if (Get3DEngine()->IsAreaActivationInUse()) - { - // keep everything deactivated, game will activate it later - pObj->SetRndFlags(ERF_HIDDEN, true); - } - - // set physics - if (!physicsAreaContour.empty()) - { - switch (volumeType) - { - case IWaterVolumeRenderNode::eWVT_River: - { - pObj->SetRiverPhysicsArea(&physicsAreaContour[0], physicsAreaContour.size()); - break; - } - case IWaterVolumeRenderNode::eWVT_Area: - { - pObj->SetAreaPhysicsArea(&physicsAreaContour[0], physicsAreaContour.size()); - break; - } - case IWaterVolumeRenderNode::eWVT_Ocean: - { - assert(!"COctreeNode::SerializeObjects( ... ) -- Water volume of type \"Ocean\" not supported yet!"); - break; - } - default: - { - assert(!"COctreeNode::SerializeObjects( ... ) -- Invalid water volume type!"); - break; - } - } - - if (!(Get3DEngine()->IsAreaActivationInUse() && GetCVars()->e_ObjectLayersActivationPhysics) && !(pChunk->m_dwRndFlags & ERF_NO_PHYSICS)) - { - pObj->Physicalize(); - } - } - - // set material - pObj->SetMaterial(pMaterial); - - Get3DEngine()->RegisterEntity(pObj, nSID, nSID); - } - else if (eERType_DistanceCloud == eType) - { - SDistanceCloudChunk* pChunk(StepData(pPtr, eEndian)); - if (!CheckRenderFlagsMinSpec(pChunk->m_dwRndFlags)) - { - return; - } - - if (Get3DEngine()->IsLayerSkipped(pChunk->m_nLayerId)) - { - return; - } - - CDistanceCloudRenderNode* pObj(new CDistanceCloudRenderNode()); - - // common node data - AABB box; - memcpy(&box, &pChunk->m_WSBBox, sizeof(AABB)); - pObj->SetBBox(box); - LoadCommonData(pChunk, pObj, pLayerVisibility); - - // distance cloud properties - SDistanceCloudProperties properties; - - properties.m_pos = pChunk->m_pos; - properties.m_sizeX = pChunk->m_sizeX; - properties.m_sizeY = pChunk->m_sizeY; - properties.m_rotationZ = pChunk->m_rotationZ; - - _smart_ptr pMaterial(CObjManager::GetItemPtr(pMatTable, pChunk->m_materialID)); - assert(pMaterial); - properties.m_pMaterialName = pMaterial ? pMaterial->GetName() : ""; - - pObj->SetProperties(properties); - - // set object visibility - if (NULL != pLayerVisibility) - { - CRY_ASSERT(pChunk->m_nLayerId != 0); - if (!CheckLayerVisibility(pObj->GetLayerId(), pLayerVisibility)) - { - pObj->SetRndFlags(ERF_HIDDEN, true); - } - } - else if (Get3DEngine()->IsAreaActivationInUse()) - { - // keep everything deactivated, game will activate it later - pObj->SetRndFlags(ERF_HIDDEN, true); - } - - if (pObj->GetMaterial() != pMaterial) - { - const char* pMatName("_can't_resolve_material_name_"); - int32 matID(pChunk->m_materialID); - if (matID >= 0 && matID < (int32)(*pMatTable).size()) - { - pMatName = pMaterial ? pMaterial->GetName() : ""; - } - Warning("Warning: Removed distance cloud at (%4.2f, %4.2f, %4.2f) with invalid material \"%s\"!\n", pChunk->m_pos.x, pChunk->m_pos.y, pChunk->m_pos.z, pMatName); - pObj->ReleaseNode(); - } - else - { - Get3DEngine()->RegisterEntity(pObj, nSID, nSID); - } - } - else - { - assert(!"Unsupported object type"); - } - - // align to 4 - while (UINT_PTR(pPtr) & 3) - { - assert(*pPtr == 222); - pPtr++; - } -} - diff --git a/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize_info.h b/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize_info.h deleted file mode 100644 index b5194a233b..0000000000 --- a/Code/CryEngine/Cry3DEngine/ObjectsTree_Serialize_info.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_SERIALIZE_INFO_H -#define CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_SERIALIZE_INFO_H -#pragma once - -STRUCT_INFO_BEGIN(SRenderNodeChunk) -STRUCT_VAR_INFO(m_WSBBox, TYPE_INFO(AABB)) -STRUCT_VAR_INFO(m_nLayerId, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_cShadowLodBias, TYPE_INFO(int8)) -STRUCT_VAR_INFO(m_ucDummy, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_dwRndFlags, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nObjectTypeIndex, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_pad16, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_fViewDistanceMultiplier, TYPE_INFO(float)) -STRUCT_VAR_INFO(m_ucLodRatio, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_pad8, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_pad16B, TYPE_INFO(uint16)) -STRUCT_INFO_END(SRenderNodeChunk) - -STRUCT_INFO_BEGIN(SDecalChunk) -STRUCT_BASE_INFO(SRenderNodeChunk) -STRUCT_VAR_INFO(m_projectionType, TYPE_INFO(int16)) -STRUCT_VAR_INFO(m_deferred, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_pad8, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_depth, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_pos, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(m_normal, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(m_explicitRightUpFront, TYPE_INFO(Matrix33)) -STRUCT_VAR_INFO(m_radius, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_nMaterialId, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_nSortPriority, TYPE_INFO(int32)) -STRUCT_INFO_END(SDecalChunk) - -STRUCT_INFO_BEGIN(SWaterVolumeChunk) -STRUCT_BASE_INFO(SRenderNodeChunk) -STRUCT_VAR_INFO(m_volumeTypeAndMiscBits, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_volumeID, TYPE_INFO(uint64)) -STRUCT_VAR_INFO(m_materialID, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_fogDensity, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_fogColor, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(m_fogPlane, TYPE_INFO(Plane)) -STRUCT_VAR_INFO(m_fogShadowing, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_caustics, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_pad8, TYPE_INFO(uint8)) -STRUCT_VAR_INFO(m_pad16, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_causticIntensity, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_causticTiling, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_causticHeight, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_uTexCoordBegin, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_uTexCoordEnd, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_surfUScale, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_surfVScale, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_numVertices, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_volumeDepth, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_streamSpeed, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_numVerticesPhysAreaContour, TYPE_INFO(uint32)) -STRUCT_INFO_END(SWaterVolumeChunk) - -STRUCT_INFO_BEGIN(SWaterVolumeVertex) -STRUCT_VAR_INFO(m_xyz, TYPE_INFO(Vec3)) -STRUCT_INFO_END(SWaterVolumeVertex) - -STRUCT_INFO_BEGIN(SDistanceCloudChunk) -STRUCT_BASE_INFO(SRenderNodeChunk) -STRUCT_VAR_INFO(m_pos, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(m_sizeX, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_sizeY, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_rotationZ, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_materialID, TYPE_INFO(int32)) -STRUCT_INFO_END(SDistanceCloudChunk) - -#endif // CRYINCLUDE_CRY3DENGINE_OBJECTSTREE_SERIALIZE_INFO_H diff --git a/Code/CryEngine/Cry3DEngine/Ocean.cpp b/Code/CryEngine/Cry3DEngine/Ocean.cpp deleted file mode 100644 index 98e45f6386..0000000000 --- a/Code/CryEngine/Cry3DEngine/Ocean.cpp +++ /dev/null @@ -1,1002 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Create and draw ocean water geometry (screen space grid, cycle buffers) - - -#include "Cry3DEngine_precompiled.h" - -#include "Ocean.h" -#include "CullBuffer.h" -#include "3dEngine.h" -#include "ObjMan.h" -#include "MatMan.h" -#include "VisAreas.h" - -#include "Environment/OceanEnvironmentBus.h" - -ITimer* COcean::m_pTimer = 0; -CREWaterOcean* COcean::m_pOceanRE = 0; -uint32 COcean::m_nVisiblePixelsCount = ~0; -float COcean::m_fWaterLevelInfo = WATER_LEVEL_UNKNOWN; - -// defined in CryEngine\Cry3DEngine\3dEngine.cpp -namespace OceanGlobals -{ - extern float g_oceanStep; -} - -COcean::COcean(_smart_ptr pMat, float fWaterLevel) -{ - m_pRenderMesh = 0; - m_pBottomCapRenderMesh = 0; - m_swathWidth = 0; - m_bUsingFFT = false; - m_bUseTessHW = false; - m_fWaterLevel = fWaterLevel; - - memset(m_fRECustomData, 0, sizeof(m_fRECustomData)); - memset(m_fREOceanBottomCustomData, 0, sizeof(m_fREOceanBottomCustomData)); - m_windUvTransform = AZ::Vector2(0.0f, 0.0f); - - SetMaterial(pMat); - m_fLastFov = 0; - m_fLastVisibleFrameTime = 0.0f; - - m_pShaderOcclusionQuery = GetRenderer()->EF_LoadShader("OcclusionTest", 0); - - memset(m_pREOcclusionQueries, 0, sizeof(m_pREOcclusionQueries)); - - m_nLastVisibleFrameId = 0; - - m_pBottomCapMaterial = GetMatMan()->LoadMaterial("EngineAssets/Materials/Water/WaterOceanBottom", false); - m_pFogIntoMat = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/OceanInto", false); - m_pFogOutofMat = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/OceanOutof", false); - m_pFogIntoMatLowSpec = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/OceanIntoLowSpec", false); - m_pFogOutofMatLowSpec = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/OceanOutofLowSpec", false); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_pWVRE[i] = static_cast(GetRenderer()->EF_CreateRE(eDATA_WaterVolume)); - if (m_pWVRE[i]) - { - m_pWVRE[i]->m_drawWaterSurface = false; - m_pWVRE[i]->m_pParams = &m_wvParams[i]; - m_pWVRE[i]->m_pOceanParams = &m_wvoParams[i]; - } - } - - m_pOceanRE = static_cast(GetRenderer()->EF_CreateRE(eDATA_WaterOcean)); - - m_nVertsCount = 0; - m_nIndicesCount = 0; - - m_bOceanFFT = false; -} - - -COcean::~COcean() -{ - for (int32 x = 0; x < CYCLE_BUFFERS_NUM; ++x) - { - if (m_pREOcclusionQueries[x]) - { - m_pREOcclusionQueries[x]->Release(true); - } - } - - m_pRenderMesh = NULL; - m_pBottomCapRenderMesh = NULL; - - SAFE_RELEASE(m_pOceanRE); - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - SAFE_RELEASE(m_pWVRE[i]); - } -} - -int32 COcean::GetMemoryUsage() -{ - int32 nSize = 0; - - nSize += sizeofVector(m_pMeshIndices); - nSize += sizeofVector(m_pMeshVerts); - nSize += sizeofVector(m_pBottomCapVerts); - nSize += sizeofVector(m_pBottomCapIndices); - - return nSize; -} - -void COcean::Update(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - C3DEngine* p3DEngine = (C3DEngine*)Get3DEngine(); - IRenderer* pRenderer = GetRenderer(); - if (passInfo.IsRecursivePass() || !passInfo.RenderWaterOcean() || !m_pMaterial) - { - return; - } - - const CCamera& rCamera = passInfo.GetCamera(); - uint32 nBufID = passInfo.GetFrameID() % CYCLE_BUFFERS_NUM; - - Vec3 vCamPos = rCamera.GetPosition(); - float fWaterLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : p3DEngine->GetWaterLevel(); - - // No hardware FFT support - m_bOceanFFT = false; - if ((pRenderer->GetFeatures() & (RFT_HW_VERTEXTEXTURES) && GetCVars()->e_WaterOceanFFT) && pRenderer->EF_GetShaderQuality(eST_Water) >= eSQ_High) - { - m_bOceanFFT = true; - } - - if (vCamPos.z < fWaterLevel) - { - // if camera is in indoors and lower than ocean level - // and exit portals are higher than ocean level - skip ocean rendering - CVisArea* pVisArea = (CVisArea*)p3DEngine->GetVisAreaFromPos(vCamPos); - if (pVisArea && !pVisArea->IsPortal()) - { - for (int32 i = 0; i < pVisArea->m_lstConnections.Count(); i++) - { - if (pVisArea->m_lstConnections[i]->IsConnectedToOutdoor() && pVisArea->m_lstConnections[i]->m_boxArea.min.z < fWaterLevel) - { - break; // there is portal making ocean visible - } - if (i == pVisArea->m_lstConnections.Count()) - { - return; // ocean surface is not visible - } - } - } - } - - bool bWaterVisible = IsVisible(passInfo); - float _fWaterPlaneSize = rCamera.GetFarPlane(); - - // Check if water surface occluded - if (fabs(m_fLastFov - rCamera.GetFov()) < 0.01f && GetCVars()->e_HwOcclusionCullingWater && passInfo.IsGeneralPass()) - { - AABB boxOcean(Vec3(vCamPos.x - _fWaterPlaneSize, vCamPos.y - _fWaterPlaneSize, fWaterLevel), - Vec3(vCamPos.x + _fWaterPlaneSize, vCamPos.y + _fWaterPlaneSize, fWaterLevel)); - - if ((!GetVisAreaManager()->IsOceanVisible() && rCamera.IsAABBVisible_EM(boxOcean)) || - (GetVisAreaManager()->IsOceanVisible() && rCamera.IsAABBVisible_E(boxOcean))) - { - // make element if not ready - if (!m_pREOcclusionQueries[nBufID]) - { - m_pREOcclusionQueries[nBufID] = (CREOcclusionQuery*)GetRenderer()->EF_CreateRE(eDATA_OcclusionQuery); - m_pREOcclusionQueries[nBufID]->m_pRMBox = (CRenderMesh*)GetObjManager()->GetRenderMeshBox(); - } - - // get last test result - // if((m_pREOcclusionQueries[nFillThreadID][nBufID]->m_nCheckFrame - passInfo.GetFrameID())<2) - { - COcean::m_nVisiblePixelsCount = m_pREOcclusionQueries[nBufID]->m_nVisSamples; - if (COcean::IsWaterVisibleOcclusionCheck()) - { - m_nLastVisibleFrameId = passInfo.GetFrameID(); - bWaterVisible = true; - } - } - - // request new test - m_pREOcclusionQueries[nBufID]->m_vBoxMin(boxOcean.min.x, boxOcean.min.y, boxOcean.min.z - 1.0f); - m_pREOcclusionQueries[nBufID]->m_vBoxMax(boxOcean.max.x, boxOcean.max.y, boxOcean.max.z); - - m_pREOcclusionQueries[nBufID]->mfReadResult_Try(COcean::m_nVisiblePixelsCount); - if (!m_pREOcclusionQueries[nBufID]->m_nDrawFrame || m_pREOcclusionQueries[nBufID]->HasSucceeded()) - { - SShaderItem shItem(m_pShaderOcclusionQuery); - CRenderObject* pObj = GetIdentityCRenderObject(passInfo.ThreadID()); - if (!pObj) - { - return; - } - GetRenderer()->EF_AddEf(m_pREOcclusionQueries[nBufID], shItem, pObj, passInfo, EFSLIST_WATER_VOLUMES, 0, SRendItemSorter::CreateDefaultRendItemSorter()); - } - } - } - else - { - m_nLastVisibleFrameId = passInfo.GetFrameID(); - bWaterVisible = true; - } - - if (bWaterVisible || vCamPos.z < fWaterLevel) - { - m_p3DEngine->SetOceanRenderFlags(OCR_OCEANVOLUME_VISIBLE); - - // lazy mesh creation - if (bWaterVisible) - { - Create(); - } - } -} - -void COcean::Create() -{ - // Calculate water geometry and update vertex buffers - int32 nScrGridSizeX; - int32 nScrGridSizeY; - - GetOceanGridSize(nScrGridSizeX, nScrGridSizeY); - - bool bUseWaterTessHW; - GetRenderer()->EF_Query(EFQ_WaterTessellation, bUseWaterTessHW); - - // Generate screen space grid - if ((m_bOceanFFT && m_bUsingFFT != m_bOceanFFT) || m_bUseTessHW != bUseWaterTessHW || m_swathWidth != GetCVars()->e_WaterTessellationSwathWidth || !m_nVertsCount || !m_nIndicesCount || nScrGridSizeX * nScrGridSizeY != m_nPrevGridDim) - { - m_nPrevGridDim = nScrGridSizeX * nScrGridSizeY; - m_pMeshVerts.Clear(); - m_pMeshIndices.Clear(); - m_nVertsCount = 0; - m_nIndicesCount = 0; - - m_bUsingFFT = m_bOceanFFT; - m_bUseTessHW = bUseWaterTessHW; - // Update the swath width - m_swathWidth = GetCVars()->e_WaterTessellationSwathWidth; - - // Render ocean with screen space tessellation - - int32 nScreenY = GetRenderer()->GetHeight(); - int32 nScreenX = GetRenderer()->GetWidth(); - - if (!nScreenY || !nScreenX) - { - return; - } - - float fRcpScrGridSizeX = 1.0f / ((float) nScrGridSizeX - 1); - float fRcpScrGridSizeY = 1.0f / ((float) nScrGridSizeY - 1); - - SVF_P3F_C4B_T2F tmp; - Vec3 vv; - vv.z = 0; - - m_pMeshVerts.reserve(nScrGridSizeX * nScrGridSizeY); - m_pMeshIndices.reserve(nScrGridSizeX * nScrGridSizeY); - - // Grid vertex generation - for (int32 y(0); y < nScrGridSizeY; ++y) - { - vv.y = (float) y * fRcpScrGridSizeY;// + fRcpScrGridSize; - - for (int32 x(0); x < nScrGridSizeX; ++x) - { - // vert 1 - vv.x = (float) x * fRcpScrGridSizeX;// + fRcpScrGridSize; - - // store in z edges information - float fx = fabs((vv.x) * 2.0f - 1.0f); - float fy = fabs((vv.y) * 2.0f - 1.0f); - //float fEdgeDisplace = sqrt_tpl(fx*fx + fy * fy);//max(fx, fy); - float fEdgeDisplace = max(fx, fy); - //sqrt_tpl(fx*fx + fy * fy); - vv.z = fEdgeDisplace; //!((y==0 ||y == nScrGridSize-1) || (x==0 || x == nScrGridSize-1)); - - tmp.xyz = vv; - m_pMeshVerts.Add(tmp); - } - } - - if (m_bUseTessHW) - { - // Normal approach - int32 nIndex = 0; - for (int32 y(0); y < nScrGridSizeY - 1; ++y) - { - for (int32 x(0); x < nScrGridSizeX - 1; ++x, ++nIndex) - { - m_pMeshIndices.Add(nScrGridSizeX * y + x); - m_pMeshIndices.Add(nScrGridSizeX * y + x + 1); - m_pMeshIndices.Add(nScrGridSizeX * (y + 1) + x); - - m_pMeshIndices.Add(nScrGridSizeX * (y + 1) + x); - m_pMeshIndices.Add(nScrGridSizeX * y + x + 1); - m_pMeshIndices.Add(nScrGridSizeX * (y + 1) + x + 1); - - //m_pMeshIndices.Add( nIndex ); - //m_pMeshIndices.Add( nIndex + 1); - //m_pMeshIndices.Add( nIndex + nScrGridSizeX); - - //m_pMeshIndices.Add( nIndex + nScrGridSizeX); - //m_pMeshIndices.Add( nIndex + 1); - //m_pMeshIndices.Add( nIndex + nScrGridSizeX + 1); - } - } - } - else - { - // Grid index generation - - if (m_swathWidth < 0) - { - // Normal approach - int32 nIndex = 0; - for (int32 y(0); y < nScrGridSizeY - 1; ++y) - { - for (int32 x(0); x < nScrGridSizeX; ++x, ++nIndex) - { - m_pMeshIndices.Add(nIndex); - m_pMeshIndices.Add(nIndex + nScrGridSizeX); - } - - if (nScrGridSizeY - 2 > y) - { - m_pMeshIndices.Add(nIndex + nScrGridSizeY - 1); - m_pMeshIndices.Add(nIndex); - } - } - } - else if(m_swathWidth > 1) - { - // Boustrophedonic walk - // - // 0 1 2 3 4 - // 5 6 7 8 9 - // 10 11 12 13 14 - // 15 16 17 18 19 - // - // Should generate the following indices - // 0 5 1 6 2 7 3 8 4 9 9 14 14 9 13 8 12 7 11 6 10 5 5 10 10 15 11 16 12 17 13 18 14 19 - // - - int32 startX = 0, endX = m_swathWidth - 1; - - do - { - for (int32 y(0); y < nScrGridSizeY - 1; y += 2) - { - // Forward - for (int32 x(startX); x <= endX; ++x) - { - m_pMeshIndices.Add(y * nScrGridSizeX + x); - m_pMeshIndices.Add((y + 1) * nScrGridSizeX + x); - } - - // Can we go backwards? - if (y + 2 < nScrGridSizeY) - { - // Restart strip by duplicating last and first of next strip - m_pMeshIndices.Add((y + 1) * nScrGridSizeX + endX); - m_pMeshIndices.Add((y + 2) * nScrGridSizeX + endX); - - //Backward - for (int32 x(endX); x >= startX; --x) - { - m_pMeshIndices.Add((y + 2) * nScrGridSizeX + x); - m_pMeshIndices.Add((y + 1) * nScrGridSizeX + x); - } - - // Restart strip - if (y + 2 == nScrGridSizeY - 1 && endX < nScrGridSizeX - 1) - { - if (endX < nScrGridSizeX - 1) - { - // Need to restart at the top of the next column - m_pMeshIndices.Add((nScrGridSizeY - 1) * nScrGridSizeX + startX); - m_pMeshIndices.Add(endX); - } - } - else - { - m_pMeshIndices.Add((y + 1) * nScrGridSizeX + startX); - m_pMeshIndices.Add((y + 2) * nScrGridSizeX + startX); - } - } - else - { - // We can restart to next column - if (endX < nScrGridSizeX - 1) - { - // Restart strip for next swath - m_pMeshIndices.Add((nScrGridSizeY - 1) * nScrGridSizeX + endX); - m_pMeshIndices.Add(endX); - } - } - } - - startX = endX; - endX = startX + m_swathWidth - 1; - - if (endX >= nScrGridSizeX) - { - endX = nScrGridSizeX - 1; - } - } while (startX < nScrGridSizeX - 1); - } - else - { - AZ_TracePrintf("Ocean", "e_WaterTessellationSwathWidth cannot be 0.") - } - } - - m_nVertsCount = m_pMeshVerts.Count(); - m_nIndicesCount = m_pMeshIndices.Count(); - - m_pRenderMesh = GetRenderer()->CreateRenderMeshInitialized( - m_pMeshVerts.GetElements(), - m_pMeshVerts.Count(), - eVF_P3F_C4B_T2F, - m_pMeshIndices.GetElements(), - m_pMeshIndices.Count(), - m_bUseTessHW ? prtTriangleList : prtTriangleStrip, - "OutdoorWaterGrid", "OutdoorWaterGrid", - eRMT_Static); - - m_pRenderMesh->SetChunk(m_pMaterial, 0, m_pMeshVerts.Count(), 0, m_pMeshIndices.Count(), 1.0f, eVF_P3F_C4B_T2F); - - if (m_bOceanFFT) - { - m_pOceanRE->Create(m_pMeshVerts.Count(), m_pMeshVerts.GetElements(), m_pMeshIndices.Count(), m_pMeshIndices.GetElements(), sizeof(m_pMeshIndices[0])); - } - - m_pMeshVerts.Free(); - m_pMeshIndices.Free(); - } -} - -void COcean::Render(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // if reaches render stage - means ocean is visible - - C3DEngine* p3DEngine = (C3DEngine*)Get3DEngine(); - IRenderer* pRenderer(GetRenderer()); - - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - float fWaterLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : p3DEngine->GetWaterLevel(); - - CRenderObject* pObject = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObject) - { - return; - } - pObject->m_II.m_Matrix.SetIdentity(); - pObject->m_pRenderNode = this; - - m_fLastFov = passInfo.GetCamera().GetFov(); - - // make distance to water level near to zero - m_pRenderMesh->SetBBox(vCamPos, vCamPos); - - // test for multiple lights and shadows support - - m_Camera = passInfo.GetCamera(); - pObject->m_fAlpha = 1.f; - - int32 gridSizeX; - int32 gridSizeY; - GetOceanGridSize(gridSizeX, gridSizeY); - const float tessellationScaleFactor = 1000.0f; // physical size of grid is how many grid tiles per thousand meters. - m_fRECustomData[0] = tessellationScaleFactor / (gridSizeX - 1); - - const auto oceanAnimationData = p3DEngine->GetOceanAnimationParams(); - - m_fRECustomData[1] = oceanAnimationData.fWindSpeed; - m_fRECustomData[2] = oceanAnimationData.fWavesSpeed; - m_fRECustomData[3] = oceanAnimationData.fWavesAmount; - m_fRECustomData[4] = oceanAnimationData.fWavesSize; - - const float timeDiff = p3DEngine->GetTimer()->GetFrameTime(); - - // calculate the wind direction - AZ::Vector2 windDirectionVector = AZ::Vector2::CreateFromAngle(oceanAnimationData.fWindDirection); - - // calculate wind offset based on speed and time delta - float windFrameOffset = 0.0025f * timeDiff * oceanAnimationData.fWindSpeed; - m_windUvTransform += windDirectionVector * windFrameOffset; - - // update constant buffer with the values; - m_fRECustomData[6] = m_windUvTransform.GetX(); - m_fRECustomData[5] = m_windUvTransform.GetY(); - - m_fRECustomData[7] = fWaterLevel; - - m_fRECustomData[8] = m_fRECustomData[9] = m_fRECustomData[10] = m_fRECustomData[11] = 0.0f; - - bool isFastpath = GetCVars()->e_WaterOcean == 2; - bool bUsingMergedFog = false; - - { - Vec3 camPos(passInfo.GetCamera().GetPosition()); - - // Check if we outside water volume - we can enable fast path with merged fog version - if (camPos.z - fWaterLevel >= oceanAnimationData.fWavesSize) - { - Vec3 fogColor; - if (OceanToggle::IsActive()) - { - AZ::Vector3 oceanFogColor = OceanRequest::GetFogColorPremultiplied(); - fogColor = Vec3(oceanFogColor.GetX(), oceanFogColor.GetY(), oceanFogColor.GetZ()); - } - else - { - fogColor = m_p3DEngine->m_oceanFogColor; - } - Vec3 cFinalFogColor = gEnv->p3DEngine->GetSunColor().CompMul(fogColor); - float fogDensity = OceanToggle::IsActive() ? OceanRequest::GetFogDensity() : m_p3DEngine->m_oceanFogDensity; - Vec4 vFogParams = Vec4(cFinalFogColor, fogDensity * 1.44269502f);// log2(e) = 1.44269502 - - m_fRECustomData[8] = vFogParams.x; - m_fRECustomData[9] = vFogParams.y; - m_fRECustomData[10] = vFogParams.z; - m_fRECustomData[11] = vFogParams.w; - if (isFastpath) - { - bUsingMergedFog = true; - } - } - } - - { - CMatInfo* pMatInfo = (CMatInfo*)m_pMaterial.get(); - float fInstanceDistance = AZ::OceanConstants::s_oceanIsVeryFarAway; - pMatInfo->PrecacheMaterial(fInstanceDistance, 0, false); - } - - if (!GetCVars()->e_WaterOceanFFT || !m_bOceanFFT) - { - m_pRenderMesh->SetREUserData(&m_fRECustomData[0]); - m_pRenderMesh->AddRenderElements(m_pMaterial, pObject, passInfo, EFSLIST_WATER, 0); - } - else - { - SShaderItem& shaderItem(m_pMaterial->GetShaderItem(0)); - m_pOceanRE->m_CustomData = &m_fRECustomData[0]; - pRenderer->EF_AddEf(m_pOceanRE, shaderItem, pObject, passInfo, EFSLIST_WATER, 0, SRendItemSorter::CreateDefaultRendItemSorter()); - } - - bool useOceanBottom = OceanToggle::IsActive() ? OceanRequest::GetUseOceanBottom() : (GetCVars()->e_WaterOceanBottom == 1); - if (useOceanBottom) - { - RenderBottomCap(passInfo); - } - - if (!bUsingMergedFog) - { - RenderFog(passInfo); - } -} - -void COcean::SetMaterial(_smart_ptr pMat) -{ - m_pMaterial = pMat; -} - -void COcean::RenderBottomCap(const SRenderingPassInfo& passInfo) -{ - - Vec3 vCamPos = passInfo.GetCamera().GetPosition(); - - // Render ocean with screen space tessellation - - int32 nScreenY = GetRenderer()->GetHeight(); - int32 nScreenX = GetRenderer()->GetWidth(); - - if (!nScreenY || !nScreenX) - { - return; - } - - // Calculate water geometry and update vertex buffers - static const int32 nScrGridSize = 5; - // distance between grid points for -1.0 to 1.0 space. - static const float fRcpScrGridSize = 2.0f / static_cast(nScrGridSize - 1); - - if (!m_pBottomCapVerts.Count() || !m_pBottomCapIndices.Count() || nScrGridSize * nScrGridSize != m_pBottomCapVerts.Count()) - { - m_pBottomCapVerts.Clear(); - m_pBottomCapIndices.Clear(); - - SVF_P3F_C4B_T2F tmp; - tmp.xyz.z = 1.0f; - - // Grid vertex generation - for (int32 y = 0; y < nScrGridSize; ++y) - { - tmp.xyz.y = -1.0f + y * fRcpScrGridSize; - for (int32 x(0); x < nScrGridSize; ++x) - { - tmp.xyz.x = -1.0f + x * fRcpScrGridSize; - m_pBottomCapVerts.Add(tmp); - } - } - - // Normal approach - int32 nIndex = 0; - for (int32 y(0); y < nScrGridSize - 1; ++y) - { - for (int32 x(0); x < nScrGridSize; ++x, ++nIndex) - { - m_pBottomCapIndices.Add(nIndex); - m_pBottomCapIndices.Add(nIndex + nScrGridSize); - } - - if (nScrGridSize - 2 > y) - { - m_pBottomCapIndices.Add(nIndex + nScrGridSize - 1); - m_pBottomCapIndices.Add(nIndex); - } - } - - m_pBottomCapRenderMesh = GetRenderer()->CreateRenderMeshInitialized( - m_pBottomCapVerts.GetElements(), - m_pBottomCapVerts.Count(), - eVF_P3F_C4B_T2F, - m_pBottomCapIndices.GetElements(), - m_pBottomCapIndices.Count(), - prtTriangleStrip, - "OceanBottomGrid", "OceanBottomGrid", - eRMT_Static); - - m_pBottomCapRenderMesh->SetChunk(m_pBottomCapMaterial, 0, m_pBottomCapVerts.Count(), 0, m_pBottomCapIndices.Count(), 1.0f, eVF_P3F_C4B_T2F); - } - - CRenderObject* pObject = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - if (!pObject) - { - return; - } - pObject->m_II.m_Matrix.SetIdentity(); - pObject->m_pRenderNode = this; - - // make distance to water level near to zero - m_pBottomCapRenderMesh->SetBBox(vCamPos, vCamPos); - - m_Camera = passInfo.GetCamera(); - pObject->m_fAlpha = 1.f; - - m_pBottomCapRenderMesh->AddRenderElements(m_pBottomCapMaterial, pObject, passInfo, EFSLIST_GENERAL, 0); -} - -void COcean::RenderFog(const SRenderingPassInfo& passInfo) -{ - if (!GetCVars()->e_Fog || !GetCVars()->e_FogVolumes) - { - return; - } - - IRenderer* pRenderer(GetRenderer()); - C3DEngine* p3DEngine(Get3DEngine()); - - const int fillThreadID = passInfo.ThreadID(); - - CRenderObject* pROVol(pRenderer->EF_GetObject_Temp(fillThreadID)); - if (!pROVol) - { - return; - } - - bool isFastpath = GetCVars()->e_WaterOcean == 2; - bool isLowSpec(GetCVars()->e_ObjQuality == CONFIG_LOW_SPEC || isFastpath); - if (pROVol && m_pWVRE[fillThreadID] && ((!isLowSpec && m_pFogIntoMat && m_pFogOutofMat) || - (isLowSpec && m_pFogIntoMatLowSpec && m_pFogOutofMatLowSpec))) - { - Vec3 camPos(passInfo.GetCamera().GetPosition()); - float waterLevel(OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : p3DEngine->GetWaterLevel()); - Vec3 planeOrigin(camPos.x, camPos.y, waterLevel); - - // fill water volume param structure - m_wvParams[fillThreadID].m_center = planeOrigin; - m_wvParams[fillThreadID].m_fogPlane.Set(Vec3(0, 0, 1), -waterLevel); - - float distCamToFogPlane(camPos.z + m_wvParams[fillThreadID].m_fogPlane.d); - m_wvParams[fillThreadID].m_viewerCloseToWaterPlane = (distCamToFogPlane) < 0.5f; - m_wvParams[fillThreadID].m_viewerInsideVolume = distCamToFogPlane < 0.00f; - m_wvParams[fillThreadID].m_viewerCloseToWaterVolume = true; - - const auto oceanAnimationData = p3DEngine->GetOceanAnimationParams(); - - if (!isFastpath || (distCamToFogPlane < oceanAnimationData.fWavesSize)) - { - Vec3 fogColor; - Vec3 fogColorShallow; - bool oceanToggleIsActive = OceanToggle::IsActive(); - if (oceanToggleIsActive) - { - AZ::Vector3 oceanFogColor = OceanRequest::GetFogColorPremultiplied(); - fogColor = Vec3(oceanFogColor.GetX(), oceanFogColor.GetY(), oceanFogColor.GetZ()); - - AZ::Vector3 nearFogColor = OceanRequest::GetNearFogColor(); - fogColorShallow = Vec3(nearFogColor.GetX(), nearFogColor.GetY(), nearFogColor.GetZ()); - } - else - { - fogColor = m_p3DEngine->m_oceanFogColor; - fogColorShallow = m_p3DEngine->m_oceanFogColorShallow; - } - float fogDensity = oceanToggleIsActive ? OceanRequest::GetFogDensity() : m_p3DEngine->m_oceanFogDensity; - - if (isLowSpec) - { - m_wvParams[fillThreadID].m_fogColor = fogColor; - m_wvParams[fillThreadID].m_fogDensity = fogDensity; - - m_wvoParams[fillThreadID].m_fogColor = Vec3(0, 0, 0); // not needed for low spec - m_wvoParams[fillThreadID].m_fogColorShallow = Vec3(0, 0, 0); // not needed for low spec - m_wvoParams[fillThreadID].m_fogDensity = 0; // not needed for low spec - - m_pWVRE[fillThreadID]->m_pOceanParams = 0; - } - else - { - m_wvParams[fillThreadID].m_fogColor = Vec3(0, 0, 0); // not needed, we set ocean specific params below - m_wvParams[fillThreadID].m_fogDensity = 0; // not needed, we set ocean specific params below - - m_wvoParams[fillThreadID].m_fogColor = fogColor; - m_wvoParams[fillThreadID].m_fogColorShallow = fogColorShallow; - m_wvoParams[fillThreadID].m_fogDensity = fogDensity; - - m_pWVRE[fillThreadID]->m_pOceanParams = &m_wvoParams[fillThreadID]; - } - - // tessellate plane - float planeSize(2.0f * passInfo.GetCamera().GetFarPlane()); - size_t subDivSize(min(64, 1 + (int32) (planeSize / 512.0f))); - if (isFastpath) - { - subDivSize = 4; - } - - size_t numSubDivVerts((subDivSize + 1) * (subDivSize + 1)); - - if (m_wvVertices[fillThreadID].size() != numSubDivVerts) - { - m_wvVertices[fillThreadID].resize(numSubDivVerts); - m_wvParams[fillThreadID].m_pVertices = &m_wvVertices[fillThreadID][0]; - m_wvParams[fillThreadID].m_numVertices = m_wvVertices[fillThreadID].size(); - - m_wvIndices[fillThreadID].resize(subDivSize * subDivSize * 6); - m_wvParams[fillThreadID].m_pIndices = &m_wvIndices[fillThreadID][0]; - m_wvParams[fillThreadID].m_numIndices = m_wvIndices[fillThreadID].size(); - - size_t ind(0); - for (uint32 y(0); y < subDivSize; ++y) - { - for (uint32 x(0); x < subDivSize; ++x, ind += 6) - { - m_wvIndices[fillThreadID][ind + 0] = (y) * (subDivSize + 1) + (x); - m_wvIndices[fillThreadID][ind + 1] = (y) * (subDivSize + 1) + (x + 1); - m_wvIndices[fillThreadID][ind + 2] = (y + 1) * (subDivSize + 1) + (x + 1); - - m_wvIndices[fillThreadID][ind + 3] = (y) * (subDivSize + 1) + (x); - m_wvIndices[fillThreadID][ind + 4] = (y + 1) * (subDivSize + 1) + (x + 1); - m_wvIndices[fillThreadID][ind + 5] = (y + 1) * (subDivSize + 1) + (x); - } - } - } - { - float xyDelta(2.0f * planeSize / (float) subDivSize); - float zDelta(waterLevel - camPos.z); - - size_t ind(0); - float yd(-planeSize); - for (uint32 y(0); y <= subDivSize; ++y, yd += xyDelta) - { - float xd(-planeSize); - for (uint32 x(0); x <= subDivSize; ++x, xd += xyDelta, ++ind) - { - m_wvVertices[fillThreadID][ind].xyz = Vec3(xd, yd, zDelta); - m_wvVertices[fillThreadID][ind].st = Vec2(0, 0); - } - } - } - - // fill in data for render object - pROVol->m_II.m_Matrix.SetIdentity(); - pROVol->m_fSort = 0; - - // get shader item - SShaderItem& shaderItem(m_wvParams[fillThreadID].m_viewerInsideVolume ? - (isLowSpec ? m_pFogOutofMatLowSpec->GetShaderItem(0) : m_pFogOutofMat->GetShaderItem(0)) : - (isLowSpec ? m_pFogIntoMatLowSpec->GetShaderItem(0) : m_pFogIntoMat->GetShaderItem(0))); - - // add to renderer - pRenderer->EF_AddEf(m_pWVRE[fillThreadID], shaderItem, pROVol, passInfo, EFSLIST_WATER_VOLUMES, distCamToFogPlane < -0.1f, SRendItemSorter::CreateDefaultRendItemSorter()); - } - } -} - -bool COcean::IsVisible(const SRenderingPassInfo& passInfo) -{ - if (abs(m_nLastVisibleFrameId - passInfo.GetFrameID()) <= 2) - { - m_fLastVisibleFrameTime = 0.0f; - } - - m_fLastVisibleFrameTime += gEnv->pTimer->GetFrameTime(); - - if (m_fLastVisibleFrameTime > 2.0f) // at least 2 seconds - { - return (abs(m_nLastVisibleFrameId - passInfo.GetFrameID()) < 64); // and at least 64 frames - } - return true; // keep water visible for a couple frames - or at least 1 second - minimizes popping during fast camera movement -} - -void COcean::SetTimer(ITimer* pTimer) -{ - assert(pTimer); - m_pTimer = pTimer; -} - -float COcean::GetWave(const Vec3& pPos, int32 nFrameID) -{ - // todo: optimize... - - IRenderer* pRenderer(GetRenderer()); - if (!pRenderer) - { - return 0.0f; - } - - EShaderQuality nShaderQuality = pRenderer->EF_GetShaderQuality(eST_Water); - - if (!m_pTimer || nShaderQuality < eSQ_High) - { - return 0.0f; - } - - // Return height - matching computation on GPU - - C3DEngine* p3DEngine(Get3DEngine()); - - bool bOceanFFT = false; - if ((pRenderer->GetFeatures() & (RFT_HW_VERTEXTEXTURES) && GetCVars()->e_WaterOceanFFT) && nShaderQuality >= eSQ_High) - { - bOceanFFT = true; - } - - const auto oceanAnimationData = p3DEngine->GetOceanAnimationParams(); - - if (bOceanFFT) - { - Vec4 pDispPos = Vec4(0, 0, 0, 0); - - if (m_pOceanRE) - { - // Get height from FFT grid - - Vec4* pGridFFT = m_pOceanRE->GetDisplaceGrid(); - if (!pGridFFT) - { - return 0.0f; - } - - // match scales used in shader - float fScaleX = pPos.x * 0.0125f * oceanAnimationData.fWavesAmount * 1.25f; - float fScaleY = pPos.y * 0.0125f * oceanAnimationData.fWavesAmount * 1.25f; - - float fu = fScaleX * 64.0f; - float fv = fScaleY * 64.0f; - int32 u1 = ((int32)fu) & 63; - int32 v1 = ((int32)fv) & 63; - int32 u2 = (u1 + 1) & 63; - int32 v2 = (v1 + 1) & 63; - - // Fractional parts - float fracu = fu - floorf(fu); - float fracv = fv - floorf(fv); - - // Get weights - float w1 = (1 - fracu) * (1 - fracv); - float w2 = fracu * (1 - fracv); - float w3 = (1 - fracu) * fracv; - float w4 = fracu * fracv; - - Vec4 h1 = pGridFFT[u1 + v1 * 64]; - Vec4 h2 = pGridFFT[u2 + v1 * 64]; - Vec4 h3 = pGridFFT[u1 + v2 * 64]; - Vec4 h4 = pGridFFT[u2 + v2 * 64]; - - // scale and sum the four heights - pDispPos = h1 * w1 + h2 * w2 + h3 * w3 + h4 * w4; - } - - // match scales used in shader - return pDispPos.z * 0.06f * oceanAnimationData.fWavesSize; - } - - // constant to scale down values a bit - const float fAnimAmplitudeScale = 1.0f / 5.0f; - - static int32 s_nFrameID = 0; - static Vec3 s_vFlowDir = Vec3(0, 0, 0); - static Vec4 s_vFrequencies = Vec4(0, 0, 0, 0); - static Vec4 s_vPhases = Vec4(0, 0, 0, 0); - static Vec4 s_vAmplitudes = Vec4(0, 0, 0, 0); - - // Update per-frame data - if (s_nFrameID != nFrameID) - { - sincos_tpl(oceanAnimationData.fWindDirection, &s_vFlowDir.y, &s_vFlowDir.x); - s_vFrequencies = Vec4(0.233f, 0.455f, 0.6135f, -0.1467f) * oceanAnimationData.fWavesSpeed * 5.0f; - s_vPhases = Vec4(0.1f, 0.159f, 0.557f, 0.2199f) * oceanAnimationData.fWavesAmount; - s_vAmplitudes = Vec4(1.0f, 0.5f, 0.25f, 0.5f) * oceanAnimationData.fWavesSize; - - s_nFrameID = nFrameID; - } - - const float fPhase = sqrt_tpl(pPos.x * pPos.x + pPos.y * pPos.y); - Vec4 vCosPhase = s_vPhases * (fPhase + pPos.x); - - Vec4 vWaveFreq = s_vFrequencies * m_pTimer->GetCurrTime(); - - Vec4 vCosWave = Vec4(cos_tpl(vWaveFreq.x * s_vFlowDir.x + vCosPhase.x), - cos_tpl(vWaveFreq.y * s_vFlowDir.x + vCosPhase.y), - cos_tpl(vWaveFreq.z * s_vFlowDir.x + vCosPhase.z), - cos_tpl(vWaveFreq.w * s_vFlowDir.x + vCosPhase.w)); - - - Vec4 vSinPhase = s_vPhases * (fPhase + pPos.y); - Vec4 vSinWave = Vec4(sin_tpl(vWaveFreq.x * s_vFlowDir.y + vSinPhase.x), - sin_tpl(vWaveFreq.y * s_vFlowDir.y + vSinPhase.y), - sin_tpl(vWaveFreq.z * s_vFlowDir.y + vSinPhase.z), - sin_tpl(vWaveFreq.w * s_vFlowDir.y + vSinPhase.w)); - - return (vCosWave.Dot(s_vAmplitudes) + vSinWave.Dot(s_vAmplitudes)) * fAnimAmplitudeScale; -} - -uint32 COcean::GetVisiblePixelsCount() -{ - return m_nVisiblePixelsCount; -} - -bool COcean::IsWaterVisibleOcclusionCheck() -{ - //Metal only supports yes(1 or more pixels)/no occlusion querys. m_nVisiblePixelsCount will always be 1 for yes, 0 for no. -#if defined(IOS) || defined(ANDROID) - return m_nVisiblePixelsCount >= 1; -#else - return m_nVisiblePixelsCount > 16; -#endif -} - -// Gets the X & Y Grid sizes based on cVars. Individual X & Y CVars should probably go away in -// favor of a single value that exists on an ocean component instead of using CVars at all. -void COcean::GetOceanGridSize(int& outX, int& outY) const -{ - // Calculate water geometry and update vertex buffers - if (OceanToggle::IsActive()) - { - outX = AZ::OceanConstants::s_waterTessellationDefault; - AZ::OceanEnvironmentBus::BroadcastResult(outX, &AZ::OceanEnvironmentBus::Events::GetWaterTessellationAmount); - outY = outX; - } - else - { - // Calculate water geometry and update vertex buffers - outX = outY = GetCVars()->e_WaterTessellationAmount; - - bool bUseWaterTessHW; - GetRenderer()->EF_Query(EFQ_WaterTessellation, bUseWaterTessHW); - - if (!bUseWaterTessHW && m_bOceanFFT) - { - outX = outY = 20 * 10; // for hi/very specs - use maximum tessellation - } - } -} - -void COcean::SetWaterLevel(float fWaterLevel) -{ - m_fWaterLevel = fWaterLevel; - OceanGlobals::g_oceanStep = -1; // if e_PhysOceanCell is used, make it re-apply the params on Update -} diff --git a/Code/CryEngine/Cry3DEngine/Ocean.h b/Code/CryEngine/Cry3DEngine/Ocean.h deleted file mode 100644 index 4212292bed..0000000000 --- a/Code/CryEngine/Cry3DEngine/Ocean.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_TERRAIN_WATER_H -#define CRYINCLUDE_CRY3DENGINE_TERRAIN_WATER_H -#pragma once - -#include - -#define CYCLE_BUFFERS_NUM 4 - -class COcean: public IRenderNode - , public Cry3DEngineBase -{ -public: - COcean(_smart_ptr pMat, float fWaterLevel); - ~COcean(); - - - void SetWaterLevel(float fWaterLevel); - static void SetWaterLevelInfo(float fWaterLevelInfo) { m_fWaterLevelInfo = fWaterLevelInfo; } - static float GetWaterLevelInfo() { return m_fWaterLevelInfo; } - - void Create(); - void Update(const SRenderingPassInfo& passInfo); - void Render(const SRenderingPassInfo& passInfo); - - bool IsVisible(const SRenderingPassInfo& passInfo); - - void SetLastFov(float fLastFov) {m_fLastFov = fLastFov; } - static void SetTimer(ITimer* pTimer); - - float GetWaterLevel() { return m_fWaterLevel; } - static float GetWave(const Vec3& pPosition, int32 nFrameID); - static uint32 GetVisiblePixelsCount(); - int32 GetMemoryUsage(); - - // fake IRenderNode implementation - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName(void) const { return "Ocean"; } - virtual const char* GetName(void) const { return "Ocean"; } - virtual Vec3 GetPos(bool) const; - virtual void Render(const SRendParams&, [[maybe_unused]] const SRenderingPassInfo& passInfo) {} - virtual void SetMaterial(_smart_ptr pMat) override; - virtual _smart_ptr GetMaterial(Vec3* pHitPos = NULL); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist() { return 1000000.f; } - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - virtual const AABB GetBBox() const { return AABB(Vec3(-1000000.f, -1000000.f, -1000000.f), Vec3(1000000.f, 1000000.f, 1000000.f)); } - virtual void SetBBox([[maybe_unused]] const AABB& WSBBox) { } - virtual void FillBBox(AABB& aabb); - - virtual void OffsetPosition([[maybe_unused]] const Vec3& delta) {} - -private: - - void RenderFog(const SRenderingPassInfo& passInfo); - void RenderBottomCap(const SRenderingPassInfo& passInfo); - void GetOceanGridSize(int& outX, int& outY) const; - -private: - static bool IsWaterVisibleOcclusionCheck(); - - // Ocean data - _smart_ptr m_pMaterial; - _smart_ptr m_pRenderMesh; - - PodArray m_pMeshVerts; - PodArray m_pMeshIndices; - - int32 m_nPrevGridDim; - int32 m_nVertsCount; - int32 m_nIndicesCount; - - int32 m_nTessellationType; - int32 m_nTessellationTiles; - - // Ocean bottom cap data - _smart_ptr< IMaterial > m_pBottomCapMaterial; - _smart_ptr m_pBottomCapRenderMesh; - - PodArray m_pBottomCapVerts; - PodArray m_pBottomCapIndices; - - // Visibility data - CCamera m_Camera; - class CREOcclusionQuery* m_pREOcclusionQueries[CYCLE_BUFFERS_NUM]; - IShader* m_pShaderOcclusionQuery; - float m_fLastFov; - float m_fLastVisibleFrameTime; - int32 m_nLastVisibleFrameId; - static uint32 m_nVisiblePixelsCount; - float m_fWaterLevel; - - float m_fRECustomData[12]; // used for passing data to renderer - float m_fREOceanBottomCustomData[8]; // used for passing data to renderer - AZ::Vector2 m_windUvTransform; // used for texture offset due to wind - bool m_bOceanFFT; - - // Ocean fog related members - CREWaterVolume::SParams m_wvParams[RT_COMMAND_BUF_COUNT]; - CREWaterVolume::SOceanParams m_wvoParams[RT_COMMAND_BUF_COUNT]; - - _smart_ptr< IMaterial > m_pFogIntoMat; - _smart_ptr< IMaterial > m_pFogOutofMat; - _smart_ptr< IMaterial > m_pFogIntoMatLowSpec; - _smart_ptr< IMaterial > m_pFogOutofMatLowSpec; - - CREWaterVolume* m_pWVRE[RT_COMMAND_BUF_COUNT]; - std::vector m_wvVertices[RT_COMMAND_BUF_COUNT]; - std::vector m_wvIndices[RT_COMMAND_BUF_COUNT]; - - int32 m_swathWidth; - bool m_bUsingFFT; - bool m_bUseTessHW; - - static ITimer* m_pTimer; - static CREWaterOcean* m_pOceanRE; - static float m_fWaterLevelInfo; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_TERRAIN_WATER_H diff --git a/Code/CryEngine/Cry3DEngine/OpticsManager.cpp b/Code/CryEngine/Cry3DEngine/OpticsManager.cpp deleted file mode 100644 index 01efd4a84f..0000000000 --- a/Code/CryEngine/Cry3DEngine/OpticsManager.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "OpticsManager.h" - -void COpticsManager::Reset() -{ - m_OpticsMap.clear(); - m_SearchedOpticsSet.clear(); - stl::free_container(m_OpticsList); -} - -IOpticsElementBase* COpticsManager::Create(EFlareType type) const -{ - return gEnv->pRenderer->CreateOptics(type); -} - -IOpticsElementBase* COpticsManager::ParseOpticsRecursively(IOpticsElementBase* pParentOptics, XmlNodeRef& node) const -{ - const char* type; - if (!node->getAttr("Type", &type)) - { - return NULL; - } - - IOpticsElementBase* pOptics = Create(GetFlareType(type)); - if (pOptics == NULL) - { - return NULL; - } - - bool bEnable(false); - node->getAttr("Enable", bEnable); - pOptics->SetEnabled(bEnable); - - const char* name; - if (node->getAttr("Name", &name)) - { - pOptics->SetName(name); - } - - if (pParentOptics) - { - pParentOptics->AddElement(pOptics); - } - - for (int i = 0, iChildCount(node->getChildCount()); i < iChildCount; ++i) - { - XmlNodeRef pChild = node->getChild(i); - if (pChild == (IXmlNode*)NULL) - { - continue; - } - - if (!_stricmp(pChild->getTag(), "Params")) - { - pOptics->Load(pChild); - } - else if (!_stricmp(pChild->getTag(), "FlareItem")) - { - ParseOpticsRecursively(pOptics, pChild); - } - } - - return pOptics; -} - - -bool COpticsManager::Load(const char* fullFlareName, int& nOutIndex, bool forceReload /*= false*/) -{ - if (!forceReload) - { - int nOpticsIndex = FindOpticsIndex(fullFlareName); - if (nOpticsIndex >= 0) - { - nOutIndex = nOpticsIndex; - return true; - } - } - - string strFullFlareName(fullFlareName); - int nPos = strFullFlareName.find("."); - if (nPos == -1) - { - return false; - } - - string xmlFileName = strFullFlareName.substr(0, nPos); - - int restLength = strFullFlareName.length() - nPos - 1; - if (restLength <= 0) - { - return false; - } - - if (!forceReload && m_SearchedOpticsSet.find(fullFlareName) != m_SearchedOpticsSet.end()) - { - return false; - } - - string fullPath = string(FLARE_LIBS_PATH) + xmlFileName + ".xml"; - XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(fullPath.c_str()); - - if (rootNode == (IXmlNode*)NULL) - { - return false; - } - - string opticsLibName = strFullFlareName.substr(nPos + 1, restLength); - m_SearchedOpticsSet.insert(fullFlareName); - - for (int i = 0, iChildCount(rootNode->getChildCount()); i < iChildCount; ++i) - { - XmlNodeRef childNode = rootNode->getChild(i); - if (childNode == (IXmlNode*)NULL) - { - continue; - } - const char* name; - if (!childNode->getAttr("Name", &name)) - { - continue; - } - if (_stricmp(name, opticsLibName.c_str())) - { - continue; - } - IOpticsElementBase* pOptics = ParseOpticsRecursively(NULL, childNode); - if (pOptics == NULL) - { - return false; - } - return AddOptics(pOptics, fullFlareName, nOutIndex, forceReload); - } - - return false; -} - -bool COpticsManager::Load(XmlNodeRef& rootNode, int& nOutIndex) -{ - const char* name = NULL; - if ((rootNode == (IXmlNode*)NULL) || (!rootNode->getAttr("Name", &name))) - { - return false; - } - - const char* libName = NULL; - if (!rootNode->getAttr("Library", &libName)) - { - return false; - } - - IOpticsElementBase* pOptics = ParseOpticsRecursively(NULL, rootNode); - if (pOptics == NULL) - { - return false; - } - - string fullFlareName = libName + string(".") + name; - return AddOptics(pOptics, fullFlareName, nOutIndex); -} - -EFlareType COpticsManager::GetFlareType(const char* typeStr) const -{ - if (typeStr == NULL) - { - return eFT__Base__; - } - - const FlareInfoArray::Props array = FlareInfoArray::Get(); - for (size_t i = 0; i < array.size; ++i) - { - if (!_stricmp(array.p[i].name, typeStr)) - { - return array.p[i].type; - } - } - - return eFT__Base__; -} - -int COpticsManager::FindOpticsIndex(const char* fullFlareName) const -{ - std::map::const_iterator iOptics = m_OpticsMap.find(CONST_TEMP_STRING(fullFlareName)); - if (iOptics != m_OpticsMap.end()) - { - return iOptics->second; - } - return -1; -} - -IOpticsElementBase* COpticsManager::GetOptics(int nIndex) -{ - if ((size_t)nIndex >= m_OpticsList.size()) - { - return NULL; - } - return m_OpticsList[nIndex]; -} - -bool COpticsManager::AddOptics(IOpticsElementBase* pOptics, const char* name, int& nOutNewIndex, bool allowReplace /*= false*/) -{ - if (name == NULL) - { - return false; - } - - auto opticsIter = m_OpticsMap.find(name); - if (opticsIter != m_OpticsMap.end()) - { - if (allowReplace) - { - nOutNewIndex = opticsIter->second; - m_OpticsList[nOutNewIndex] = pOptics; - return true; - } - else - { - return false; - } - } - else - { - nOutNewIndex = (int)m_OpticsList.size(); - m_OpticsList.push_back(pOptics); - m_OpticsMap[name] = nOutNewIndex; - return true; - } -} - -bool COpticsManager::Rename(const char* fullFlareName, const char* newFullFlareName) -{ - if (m_OpticsMap.find(newFullFlareName) != m_OpticsMap.end()) - { - return true; - } - - std::map::iterator iOptics = m_OpticsMap.find(fullFlareName); - if (iOptics == m_OpticsMap.end()) - { - return false; - } - - int nOpticsIndex = iOptics->second; - if (nOpticsIndex < 0 || nOpticsIndex >= (int)m_OpticsList.size()) - { - return false; - } - - m_OpticsMap.erase(iOptics); - - IOpticsElementBasePtr pOptics = m_OpticsList[nOpticsIndex]; - pOptics->SetName(newFullFlareName); - m_OpticsMap[newFullFlareName] = nOpticsIndex; - - return true; -} - -void COpticsManager::GetMemoryUsage(ICrySizer* pSizer) const -{ - for (int i = 0, iSize(m_OpticsList.size()); i < iSize; ++i) - { - m_OpticsList[i]->GetMemoryUsage(pSizer); - } -} - -void COpticsManager::Invalidate() -{ - for (int i = 0, iSize(m_OpticsList.size()); i < iSize; ++i) - { - m_OpticsList[i]->Invalidate(); - } -} diff --git a/Code/CryEngine/Cry3DEngine/OpticsManager.h b/Code/CryEngine/Cry3DEngine/OpticsManager.h deleted file mode 100644 index 1bb8d4d8d6..0000000000 --- a/Code/CryEngine/Cry3DEngine/OpticsManager.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_OPTICSMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_OPTICSMANAGER_H -#pragma once - -#include "IFlares.h" - -class COpticsManager - : public Cry3DEngineBase - , public IOpticsManager -{ -public: - - ~COpticsManager(){} - - void Reset(); - - IOpticsElementBase* Create(EFlareType type) const; - IOpticsElementBase* GetOptics(int nIndex); - - bool Load(const char* fullFlareName, int& nOutIndex, bool forceReload = false); - bool Load(XmlNodeRef& rootNode, int& nOutIndex); - bool AddOptics(IOpticsElementBase* pOptics, const char* name, int& nOutNewIndex, bool allowReplace = false); - bool Rename(const char* fullFlareName, const char* newFullFlareName); - - void GetMemoryUsage(ICrySizer* pSizer) const; - void Invalidate(); - -private: - IOpticsElementBase* ParseOpticsRecursively(IOpticsElementBase* pParentOptics, XmlNodeRef& node) const; - EFlareType GetFlareType(const char* typeStr) const; - int FindOpticsIndex(const char* fullFlareName) const; - -private: - std::vector m_OpticsList; - std::map m_OpticsMap; - // All flare list which has already been searched for. - std::set m_SearchedOpticsSet; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_OPTICSMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/Platform/Android/platform_android_files.cmake b/Code/CryEngine/Cry3DEngine/Platform/Android/platform_android_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/Platform/Linux/platform_linux_files.cmake b/Code/CryEngine/Cry3DEngine/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac.cmake b/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac_files.cmake b/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows.cmake b/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - diff --git a/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows_files.cmake b/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/Platform/iOS/platform_ios_files.cmake b/Code/CryEngine/Cry3DEngine/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/Cry3DEngine/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/Cry3DEngine/PostEffectGroup.cpp b/Code/CryEngine/Cry3DEngine/PostEffectGroup.cpp deleted file mode 100644 index 58e2ab4c88..0000000000 --- a/Code/CryEngine/Cry3DEngine/PostEffectGroup.cpp +++ /dev/null @@ -1,457 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include "PostEffectGroup.h" -#include - -class BlendVisitor -{ -private: - bool m_enable; - float m_blendAmount; - -public: - void Init(bool enable, float blendAmount) - { - m_enable = enable; - m_blendAmount = blendAmount; - } - - PostEffectGroupParam operator()(float base, float blend) - { - return base * (1.f - m_blendAmount) + blend * m_blendAmount; - } - - PostEffectGroupParam operator()(const Vec4& base, const Vec4& blend) - { - return base * (1.f - m_blendAmount) + blend * m_blendAmount; - } - - PostEffectGroupParam operator()(const AZStd::string& base, const AZStd::string& blend) - { - return m_enable ? blend : base; - } - - template - PostEffectGroupParam operator()(const T&, const U&) - { - CRY_ASSERT(false); - return 0.f; - } -}; - -class SyncVisitor -{ -private: - const AZStd::string* m_name; - -public: - void SetName(const AZStd::string& name) - { - m_name = &name; - } - - void operator()(float param) - { - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->SetPostEffectParam(m_name->c_str(), param); - } - } - - void operator()(const Vec4& param) - { - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->SetPostEffectParamVec4(m_name->c_str(), param); - } - } - - void operator()(const AZStd::string& param) - { - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->SetPostEffectParamString(m_name->c_str(), param.c_str()); - } - } -}; - -PostEffectGroup::PostEffectGroup(class PostEffectGroupManager* manager, const char* name, GroupPriority priority, bool hold, float fadeDistance) - : m_manager(manager) - , m_name(name) - , m_enable(false) - , m_priority(priority) - , m_hold(hold) - , m_fadeDistance(fadeDistance) - , m_lastUpdateFrame(gEnv->nMainFrameID) - , m_enableDuration(0.f) - , m_disableDuration(1000.f) - , m_strength(0.f) -{ - EBUS_EVENT_RESULT(m_id, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, m_name.c_str(), AZ::AzTypeInfo::Uuid(), true); -} - -void PostEffectGroup::SetEnable(bool enable) -{ - if (m_enable == enable) - { - return; - } - m_enable = enable; - if (m_enable) - { - m_lastUpdateFrame = gEnv->nMainFrameID; - m_enableDuration = 0.f; - m_manager->Sort(); - } - else - { - m_disableDuration = 0.f; - } - - // Our m_enable state has changed. Alert the PostEffectGroupManager of this. - m_manager->SetGroupToggledThisFrame(this); -} - -void PostEffectGroup::StopEffect() -{ - m_enable = false; - m_enableDuration = 0.f; - m_disableDuration = m_blendOut.GetKeyRangeEnd(); -} - -void PostEffectGroup::SetParam(const char* name, const PostEffectGroupParam& value) -{ - m_params[name] = value; - if (m_enable) - { - m_lastUpdateFrame = gEnv->nMainFrameID; - m_manager->Sort(); - } -} - -void PostEffectGroup::ClearParams() -{ - m_params.clear(); - if (m_enable) - { - m_lastUpdateFrame = gEnv->nMainFrameID; - m_manager->Sort(); - } -} - -void PostEffectGroup::ApplyAtPosition(const Vec3& position) -{ - float distance = (position - gEnv->pSystem->GetViewCamera().GetPosition()).len(); - if (distance < m_fadeDistance) - { - m_strength += 1.f - distance / m_fadeDistance; - } -} - -void PostEffectGroup::BlendWith(AZStd::unordered_map& paramMap) -{ - if (!m_enable && m_disableDuration >= m_blendOut.GetKeyRangeEnd()) - { - return; - } - m_enableDuration += gEnv->pTimer->GetFrameTime(); - if (!m_enable) - { - m_disableDuration += gEnv->pTimer->GetFrameTime(); - } - if (m_enable && !m_hold && m_enableDuration >= m_blendIn.GetKeyRangeEnd()) - { - m_enable = false; - m_disableDuration = m_enableDuration - m_blendIn.GetKeyRangeEnd(); - } - for (auto& param : m_params) - { - if (paramMap.find(param.first) == paramMap.end()) - { - paramMap[param.first] = param.second; - } - else - { - BlendVisitor blendVisitor; - float blendInAmount = 1.f, blendOutAmount = 1.f; - if (!m_blendIn.empty() && m_enableDuration < m_blendIn.GetKeyRangeEnd()) - { - m_blendIn.InterpolateFloat(m_enableDuration, blendInAmount); - } - if (!m_enable) // m_blendOut.empty() is already checked above - { - m_blendOut.InterpolateFloat(m_disableDuration, blendOutAmount); - } - blendVisitor.Init(m_enable, blendInAmount * blendOutAmount * (m_fadeDistance ? m_strength : 1.f)); - paramMap[param.first] = AZStd::visit(blendVisitor, paramMap[param.first], param.second); - } - } -} - -void PostEffectGroup::ClearSplines() -{ - m_blendIn.Clear(); - m_blendOut.Clear(); -} - -PostEffectGroupManager::PostEffectGroupManager() -{ - // Note that the priority of the Base group is 1, this is to prevent invalid ordering with the "Default" group. - PostEffectGroup* base = new PostEffectGroup(this, "Base", PostEffectGroup::kPriorityBase, true, 0.f); - base->SetEnable(true); - m_groups.push_back(std::unique_ptr(base)); - gEnv->pRenderer->RegisterSyncWithMainListener(this); - if (gEnv->IsEditor()) - { - // Only monitor assets in the editor. - AzFramework::AssetCatalogEventBus::Handler::BusConnect(); - } -} - -PostEffectGroupManager::~PostEffectGroupManager() -{ - gEnv->pRenderer->RemoveSyncWithMainListener(this); - if (gEnv->IsEditor()) - { - AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); - } -} - -IPostEffectGroup* PostEffectGroupManager::GetGroup(const char* name) -{ - for (auto& group : m_groups) - { - if (strcmp(group->GetName(), name) == 0) - { - return group.get(); - } - } - - // Group not loaded, so try to load it from XML - // Load on demand instead of at startup so that users can place the XML file in any CryPak path - return LoadGroup(name); -} - -IPostEffectGroup* PostEffectGroupManager::GetGroup(const unsigned int index) -{ - if (index < m_groups.size()) - { - return m_groups[index].get(); - } - - return nullptr; -} - -const unsigned int PostEffectGroupManager::GetGroupCount() -{ - return m_groups.size(); -} - -IPostEffectGroup* PostEffectGroupManager::LoadGroup(const char* name, PostEffectGroup* groupToLoadInto) -{ - XmlNodeRef root = GetISystem()->LoadXmlFromFile(name); - unsigned int priority; - bool hold = false; - float fadeDistance = 0.f; - if (!root) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Can't open post effect group '%s'.", name); - return nullptr; - } - if (!root->isTag("PostEffectGroup")) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Post effect group '%s' is missing 'PostEffectGroup' root tag", name); - return nullptr; - } - if (!root->getAttr("priority", priority)) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Post effect group '%s' is missing 'priority' attribute", name); - return nullptr; - } - root->getAttr("hold", hold); - root->getAttr("fadeDistance", fadeDistance); - PostEffectGroup* group = groupToLoadInto; - if (!group) - { - // No pointer was sent in, so create a new PostEffectGroup and add it to the list. - group = new PostEffectGroup(this, name, static_cast(priority), hold, fadeDistance); - m_groups.push_back(std::unique_ptr(group)); - } - else - { - // Existing PostEffectGroup was sent in, reset its properties so that we can load onto it again. - // This is only called from OnCatalogAssetChanged, so should only happen in the editor. - group->StopEffect(); - group->SetPriority(static_cast(priority)); - group->SetHold(hold); - group->SetFadeDistance(fadeDistance); - group->ClearSplines(); - } - - for (int i = 0; i < root->getChildCount(); i++) - { - XmlNodeRef node = root->getChild(i); - const char* effectName; - if (node->isTag("Effect") && node->getAttr("name", &effectName)) - { - // Set effect params - for (int j = 0; j < node->getChildCount(); j++) - { - XmlNodeRef paramNode = node->getChild(j); - const char* paramName; - if (paramNode->isTag("Param") && paramNode->getAttr("name", ¶mName)) - { - std::string paramFullName = std::string(effectName) + "_" + paramName; - float floatValue; - Vec4 vec4Value; - const char* stringValue; - if (paramNode->getAttr("floatValue", floatValue)) - { - group->SetParam(paramFullName.c_str(), floatValue); - } - else if (paramNode->getAttr("vec4Value", vec4Value)) - { - group->SetParam(paramFullName.c_str(), vec4Value); - } - else if (paramNode->getAttr("colorValue", vec4Value)) - { - group->SetParam(("clr_" + paramFullName).c_str(), vec4Value); - } - else if (paramNode->getAttr("stringValue", &stringValue)) - { - group->SetParam(paramFullName.c_str(), stringValue); - } - else if (paramNode->getAttr("textureValue", &stringValue)) - { - group->SetParam(("tex_" + paramFullName).c_str(), stringValue); - } - else - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Post effect group '%s' effect '%s' param '%s' needs either a floatValue, vec4Value, colorValue, stringValue, or textureValue attribute", - name, effectName, paramName); - } - } - else - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Post effect group '%s' effect '%s' must contain Param tags with a name attribute", name, effectName); - } - } - continue; - } - ISplineInterpolator* spline = - node->isTag("BlendIn") ? group->GetBlendIn() : - node->isTag("BlendOut") ? group->GetBlendOut() : - nullptr; - if (spline) - { - // Add blend spline keys - for (int j = 0; j < node->getChildCount(); j++) - { - XmlNodeRef keyNode = node->getChild(j); - float time, value; - if (keyNode->isTag("Key") && keyNode->getAttr("time", time) && keyNode->getAttr("value", value)) - { - spline->InsertKeyFloat(time, value); - } - else - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Post effect group '%s' blend spline key must be of form ", name); - } - } - // Set blend curve type - const char* curveAttr = node->getAttr("curve"); - ESplineKeyTangentType curveType = SPLINE_KEY_TANGENT_NONE; - if (strcmp(curveAttr, "linear") == 0) - { - curveType = SPLINE_KEY_TANGENT_LINEAR; - } - else if (strcmp(curveAttr, "step") == 0) - { - curveType = SPLINE_KEY_TANGENT_STEP; - } - else if (strcmp(curveAttr, "") != 0 && strcmp(curveAttr, "smooth") != 0) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Post effect group '%s' %s spline has unrecognized curve '%s'. Expecting 'smooth', 'linear', or 'step'.", - name, node->getTag(), curveAttr); - } - for (int j = 0; j < spline->GetKeyCount(); j++) - { - spline->SetKeyFlags(j, (curveType << SPLINE_KEY_TANGENT_IN_SHIFT) | (curveType << SPLINE_KEY_TANGENT_OUT_SHIFT)); - } - continue; - } - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "Unrecognized XML tag in post effect group '%s'", name); - } - return group; -} - -void PostEffectGroupManager::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) -{ - for (auto& group : m_groups) - { - if (group->GetAssetId() == assetId) - { - // Reload this asset. Sending in the pointer will cause LoadGroup to load in place. - LoadGroup(group->GetName(), group.get()); - return; - } - } -} - -void PostEffectGroupManager::SyncMainWithRender() -{ - // Blend postprocessing params - m_paramCache.clear(); - - // Flip our buffers and clear - m_fillThreadIndex = (m_fillThreadIndex + 1) & 1; - m_groupsToggledThisFrame[m_fillThreadIndex].clear(); - - for (auto& group : m_groups) - { - group->BlendWith(m_paramCache); - group->ResetStrength(); - } - SyncVisitor syncVisitor; - for (auto& param : m_paramCache) - { - syncVisitor.SetName(param.first); - AZStd::visit(syncVisitor, param.second); - } - // Swap buffers in lower level system - gEnv->pRenderer->SyncPostEffects(); -} - -void PostEffectGroupManager::Sort() -{ - // Sort effect groups by priority then time updated, so that they'll be blended in that order - std::sort(m_groups.begin(), m_groups.end(), [](const std::unique_ptr& a, const std::unique_ptr& b) - { - if (a->GetPriority() == b->GetPriority()) - { - return a->GetLastUpdateFrame() < b->GetLastUpdateFrame(); - } - return a->GetPriority() < b->GetPriority(); - }); -} - -const PostEffectGroupList& PostEffectGroupManager::GetGroupsToggledThisFrame() -{ - unsigned int processThreadIndex = (m_fillThreadIndex + 1) & 1; - return m_groupsToggledThisFrame[processThreadIndex]; -} - -void PostEffectGroupManager::SetGroupToggledThisFrame( IPostEffectGroup* group ) -{ - m_groupsToggledThisFrame[m_fillThreadIndex].push_back(group); -} diff --git a/Code/CryEngine/Cry3DEngine/PostEffectGroup.h b/Code/CryEngine/Cry3DEngine/PostEffectGroup.h deleted file mode 100644 index cfc830ec44..0000000000 --- a/Code/CryEngine/Cry3DEngine/PostEffectGroup.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include "IPostEffectGroup.h" -#include "ISplines.h" -#include -#include -#include - -class PostEffectGroup : public IPostEffectGroup -{ -public: - // PostEffectGroups are assets, but have no handler yet. For now, we will use this UUID to refer to them. - AZ_TYPE_INFO(PostEffectGroup, "{BDDCFCE8-6E4E-4816-AE1C-ED98B02DA75D}"); - - // Priority to assign to any group. Note that a higher value relates to a higher priority. - enum GroupPriority - { - kPriorityDefault = 0, // Used for the default effect settings. - kPriorityBase = 1, // Base group edited by user/code. Should always be higher priority than kDefalt. - // Add any future priorities here. - }; - - PostEffectGroup(class PostEffectGroupManager* manager, const char* name, GroupPriority priority, bool hold, float fadeDistance); - - const char* GetName() const override { return m_name.c_str(); } - void SetEnable(bool enable) override; - bool GetEnable() const override { return m_enable; } - unsigned int GetPriority() const override { return m_priority; } - bool GetHold() const override { return m_hold; } - float GetFadeDistance() const override { return m_fadeDistance; } - void SetParam(const char* name, const PostEffectGroupParam& value) override; - PostEffectGroupParam* GetParam(const char* name) override { return &m_params[name]; } - void ClearParams() override; - void ApplyAtPosition(const Vec3& position) override; - ISplineInterpolator* GetBlendIn() { return &m_blendIn; } - ISplineInterpolator* GetBlendOut() { return &m_blendOut; } - uint32 GetLastUpdateFrame() const { return m_lastUpdateFrame; } - void BlendWith(AZStd::unordered_map& paramMap); - void ResetStrength() { m_strength = 0.f; } - AZ::Data::AssetId GetAssetId() const { return m_id; } - // Functions for changing an effect that has already been loaded. Not in the interface because they are intended to be used internally during hot reloads in the editor. - void StopEffect(); - void ClearSplines(); - void SetPriority(GroupPriority priority) { m_priority = priority; } - void SetHold(bool hold) { m_hold = hold; } - void SetFadeDistance(float fadeDistance) { m_fadeDistance = fadeDistance; } - -private: - class BlendSpline : public spline::CBaseSplineInterpolator < float, spline::BezierSpline > - { - public: - float GetKeyRangeEnd() - { - return empty() ? 0.f : GetKeyTime(num_keys() - 1); - } - - void Clear() - { - RemoveKeysInRange(0.0f, GetKeyRangeEnd()); - } - - void SerializeSpline([[maybe_unused]] XmlNodeRef &node, [[maybe_unused]] bool bLoading){} - }; - - class PostEffectGroupManager* m_manager; - AZStd::string m_name; - bool m_enable; - GroupPriority m_priority; - bool m_hold; - float m_fadeDistance; - AZStd::unordered_map m_params; - BlendSpline m_blendIn; - BlendSpline m_blendOut; - uint32 m_lastUpdateFrame; - float m_enableDuration; - float m_disableDuration; - float m_strength; - AZ::Data::AssetId m_id; -}; - -class PostEffectGroupManager - : public IPostEffectGroupManager - , public ISyncMainWithRenderListener - , private AzFramework::AssetCatalogEventBus::Handler -{ -public: - PostEffectGroupManager(); - ~PostEffectGroupManager() override; - - IPostEffectGroup* GetGroup(const char* name) override; - IPostEffectGroup* GetGroup(const unsigned int index) override; - const unsigned int GetGroupCount() override; - void SyncMainWithRender() override; - void Sort(); - - // Returns a list of PostEFfectGroups that had their enabled state changed this frame - const PostEffectGroupList& GetGroupsToggledThisFrame() override; - void SetGroupToggledThisFrame( IPostEffectGroup* group ); -private: - // Sending in a PostEffectGroup* to LoadGroup will cause a load in place. - // Sending in a nullptr to LoadGroup will construct a new PostEffectGroup. - IPostEffectGroup* LoadGroup(const char* name, PostEffectGroup* groupToLoadInto = nullptr); - // =============== AssetCatalogEventBus Functions ============== - void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override; - - std::vector> m_groups; - AZStd::unordered_map m_paramCache; - - // A list of PostEffectGroups that had their Enabled state changed this frame - // Double buffered for render thread/main thread. - PostEffectGroupList m_groupsToggledThisFrame[2]; - - // The renderer version of the fill/process thread IDs is not available to us here. - unsigned int m_fillThreadIndex = 0; -}; diff --git a/Code/CryEngine/Cry3DEngine/PostProcessEffects.cpp b/Code/CryEngine/Cry3DEngine/PostProcessEffects.cpp deleted file mode 100644 index 52a771aa30..0000000000 --- a/Code/CryEngine/Cry3DEngine/PostProcessEffects.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Notes : Check PostEffects.h for list of available effects - - -#include "Cry3DEngine_precompiled.h" -#include "IPostEffectGroup.h" -#include "ITimeOfDay.h" - -void C3DEngine::SetPostEffectParam(const char* pParam, float fValue, bool bForceValue) const -{ - if (pParam) - { - GetRenderer()->EF_SetPostEffectParam(pParam, fValue, bForceValue); - } -} - -void C3DEngine::GetPostEffectParam(const char* pParam, float& fValue) const -{ - if (pParam) - { - GetRenderer()->EF_GetPostEffectParam(pParam, fValue); - } -} - -void C3DEngine::SetPostEffectParamVec4(const char* pParam, const Vec4& pValue, bool bForceValue) const -{ - if (pParam) - { - GetRenderer()->EF_SetPostEffectParamVec4(pParam, pValue, bForceValue); - } -} - -void C3DEngine::GetPostEffectParamVec4(const char* pParam, Vec4& pValue) const -{ - if (pParam) - { - GetRenderer()->EF_GetPostEffectParamVec4(pParam, pValue); - } -} - -void C3DEngine::SetPostEffectParamString(const char* pParam, const char* pszArg) const -{ - if (pParam && pszArg) - { - GetRenderer()->EF_SetPostEffectParamString(pParam, pszArg); - } -} - -void C3DEngine::GetPostEffectParamString(const char* pParam, const char*& pszArg) const -{ - if (pParam) - { - GetRenderer()->EF_GetPostEffectParamString(pParam, pszArg); - } -} - -int32 C3DEngine::GetPostEffectID(const char* pPostEffectName) -{ - return GetRenderer()->EF_GetPostEffectID(pPostEffectName); -} - -void C3DEngine::ResetPostEffects(bool bOnSpecChange) -{ - GetPostEffectBaseGroup()->ClearParams(); - - GetRenderer()->EF_ResetPostEffects(bOnSpecChange); - - GetTimeOfDay()->Update(false, true); -} - -void C3DEngine::DisablePostEffects() -{ - IPostEffectGroupManager* groupManager = gEnv->p3DEngine->GetPostEffectGroups(); - if (groupManager) - { - for (unsigned int i = 0; i < groupManager->GetGroupCount(); i++) - { - IPostEffectGroup* group = groupManager->GetGroup(i); - if (strcmp(group->GetName(), m_defaultPostEffectGroup) != 0 && strcmp(group->GetName(), "Base") != 0) - { - group->SetEnable(false); - } - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/PrismRenderNode.cpp b/Code/CryEngine/Cry3DEngine/PrismRenderNode.cpp deleted file mode 100644 index f904e67bd1..0000000000 --- a/Code/CryEngine/Cry3DEngine/PrismRenderNode.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) - -#include "PrismRenderNode.h" - -CPrismRenderNode::CPrismRenderNode() - : m_pMaterial(0) -{ - m_mat.SetIdentity(); - m_WSBBox = AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)); - m_pRE = (CREPrismObject*) GetRenderer()->EF_CreateRE(eDATA_PrismObject); - // m_pMaterial = GetMatMan()->LoadMaterial("Materials/VolumeData/Default", false); - m_dwRndFlags |= ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS; -} - -CPrismRenderNode::~CPrismRenderNode() -{ - if (m_pRE) - { - m_pRE->Release(false); - } - - Get3DEngine()->FreeRenderNodeState(this); -} - -void CPrismRenderNode::SetMatrix(const Matrix34& mat) -{ - m_mat = mat; - m_WSBBox.SetTransformedAABB(mat, AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1))); - Get3DEngine()->RegisterEntity(this); -} - - -const char* CPrismRenderNode::GetName() const -{ - return "PrismObject"; -} - -void CPrismRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pMaterial) - { - return; - } - - CRenderObject* pRO = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); // pointer could be cached - - if (pRO) - { - // set basic render object properties - pRO->m_II.m_Matrix = m_mat; - pRO->m_fSort = 0; - pRO->m_fDistance = rParam.fDistance; - - // transform camera into object space - const CCamera& cam(passInfo.GetCamera()); - Vec3 viewerPosWS(cam.GetPosition()); - - m_pRE->m_center = m_mat.GetTranslation(); - - SShaderItem& shaderItem(m_pMaterial->GetShaderItem(0)); - - GetRenderer()->EF_AddEf(m_pRE, shaderItem, pRO, passInfo, EFSLIST_GENERAL, 0, SRendItemSorter(rParam.rendItemSorter)); - } -} - -void CPrismRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "PrismRenderNode"); - pSizer->AddObject(this, sizeof(*this)); -} - -void CPrismRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_WSBBox.Move(delta); - m_mat.SetTranslation(m_mat.GetTranslation() + delta); - if (m_pRE) - { - m_pRE->m_center += delta; - } -} - -#endif // EXCLUDE_DOCUMENTATION_PURPOSE diff --git a/Code/CryEngine/Cry3DEngine/PrismRenderNode.h b/Code/CryEngine/Cry3DEngine/PrismRenderNode.h deleted file mode 100644 index 94b3165579..0000000000 --- a/Code/CryEngine/Cry3DEngine/PrismRenderNode.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_PRISMRENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_PRISMRENDERNODE_H -#pragma once - -class CPrismRenderNode - : public IPrismRenderNode - , public Cry3DEngineBase -{ -public: - CPrismRenderNode(); - - // interface IPrismRenderNode -------------------------------------------- - - // interface IRenderNode ------------------------------------------------- - virtual void SetMatrix(const Matrix34& mat); - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const { return "PrismObject"; } - virtual const char* GetName() const; - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - virtual void SetMaterial(_smart_ptr pMat) { m_pMaterial = pMat; } - virtual _smart_ptr GetMaterial(Vec3* pHitPos = 0); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - -private: - ~CPrismRenderNode(); - - AABB m_WSBBox; - Matrix34 m_mat; - _smart_ptr< IMaterial > m_pMaterial; - CREPrismObject* m_pRE; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_PRISMRENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/RenderMeshMerger.cpp b/Code/CryEngine/Cry3DEngine/RenderMeshMerger.cpp deleted file mode 100644 index 6366b8d69d..0000000000 --- a/Code/CryEngine/Cry3DEngine/RenderMeshMerger.cpp +++ /dev/null @@ -1,1895 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "MatMan.h" -#include "VisAreas.h" -#include "CullBuffer.h" -#include "3dEngine.h" -#include "IndexedMesh.h" -#include "RenderMeshMerger.h" -#include "MeshCompiler/MeshCompiler.h" -#include "../RenderDll/Common/Shaders/Vertex.h" - -CRenderMeshMerger::CRenderMeshMerger() -{ - m_nTotalVertexCount = 0; - m_nTotalIndexCount = 0; -} - -CRenderMeshMerger::~CRenderMeshMerger() -{ -} - -int CRenderMeshMerger::Cmp_Materials(_smart_ptr pMat1, _smart_ptr pMat2) -{ - if (!pMat1 || !pMat2) - { - return 0; - } - - SShaderItem& shaderItem1 = pMat1->GetShaderItem(); - SShaderItem& shaderItem2 = pMat2->GetShaderItem(); - - // vert format - AZ::Vertex::Format vertexFormat1 = shaderItem1.m_pShader->GetVertexFormat(); - AZ::Vertex::Format vertexFormat2 = shaderItem2.m_pShader->GetVertexFormat(); - - if (vertexFormat1 > vertexFormat2) - { - return 1; - } - if (vertexFormat1 < vertexFormat2) - { - return -1; - } - - bool bDecal1 = (shaderItem1.m_pShader->GetFlags() & EF_DECAL) != 0; - bool bDecal2 = (shaderItem2.m_pShader->GetFlags() & EF_DECAL) != 0; - - // shader - if (bDecal1 > bDecal2) - { - return 1; - } - if (bDecal1 < bDecal2) - { - return -1; - } - - // shader resources - if (shaderItem1.m_pShaderResources > shaderItem2.m_pShaderResources) - { - return 1; - } - if (shaderItem1.m_pShaderResources < shaderItem2.m_pShaderResources) - { - return -1; - } - - // shader - if (shaderItem1.m_pShader > shaderItem2.m_pShader) - { - return 1; - } - if (shaderItem1.m_pShader < shaderItem2.m_pShader) - { - return -1; - } - - // compare mats ptr - if (pMat1 > pMat2) - { - return 1; - } - if (pMat1 < pMat2) - { - return -1; - } - - return 0; -} - -int CRenderMeshMerger::Cmp_RenderChunksInfo(const void* v1, const void* v2) -{ - SRenderMeshInfoInput* in1 = (SRenderMeshInfoInput*)v1; - SRenderMeshInfoInput* in2 = (SRenderMeshInfoInput*)v2; - - //assert(pChunk1->LMInfo.iRAETex == pChunk2->LMInfo.iRAETex); - - _smart_ptr pMat1 = in1->pMat; - _smart_ptr pMat2 = in2->pMat; - - return Cmp_Materials(pMat1, pMat2); -} - -int CRenderMeshMerger::Cmp_RenderChunks_(const void* v1, const void* v2) -{ - SMergedChunk* pChunk1 = (SMergedChunk*)v1; - SMergedChunk* pChunk2 = (SMergedChunk*)v2; - - if (pChunk1->rChunk.nSubObjectIndex < pChunk2->rChunk.nSubObjectIndex) - { - return -1; - } - if (pChunk1->rChunk.nSubObjectIndex > pChunk2->rChunk.nSubObjectIndex) - { - return 1; - } - - _smart_ptr pMat1 = pChunk1->pMaterial; - _smart_ptr pMat2 = pChunk2->pMaterial; - - return Cmp_Materials(pMat1, pMat2); -} - -void CRenderMeshMerger::IsChunkValid([[maybe_unused]] const CRenderChunk& Ch, [[maybe_unused]] PodArray& lstVerts, [[maybe_unused]] PodArray& lstIndices) -{ -#ifdef _DEBUG - assert(Ch.nFirstIndexId + Ch.nNumIndices <= (uint32)lstIndices.Count()); - assert(Ch.nFirstVertId + Ch.nNumVerts <= (uint16)lstVerts.Count()); - - for (uint32 i = Ch.nFirstIndexId; i < Ch.nFirstIndexId + Ch.nNumIndices; i++) - { - assert(lstIndices[i] >= Ch.nFirstVertId && lstIndices[i] < (uint32)(Ch.nFirstVertId + Ch.nNumVerts)); - assert(lstIndices[i] >= 0 && lstIndices[i] < (uint32)lstVerts.Count()); - } -#endif -} - -void CRenderMeshMerger::MakeRenderMeshInfoListOfAllChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info) -{ - for (int nRmi = 0; nRmi < nRMICount; nRmi++) - { - SRenderMeshInfoInput* pRMI = &pRMIArray[nRmi]; - IRenderMesh* pRM = pRMI->pMesh; - - const TRenderChunkArray& chunks = pRM->GetChunks(); - int nChunkCount = chunks.size(); - for (int nChunk = 0; nChunk < nChunkCount; nChunk++) - { - const CRenderChunk& renderChunk = chunks[nChunk]; - - if (renderChunk.m_nMatFlags & MTL_FLAG_NODRAW || !renderChunk.pRE) - { - continue; - } - - _smart_ptr pCustMat; - if (pRMI->pMat && renderChunk.m_nMatID < pRMI->pMat->GetSubMtlCount()) - { - pCustMat = pRMI->pMat->GetSubMtl(renderChunk.m_nMatID); - } - else - { - pCustMat = pRMI->pMat; - } - - if (!pCustMat) - { - continue; - } - if (!pCustMat->GetShaderItem().m_pShader) - { - pCustMat = GetMatMan()->GetDefaultMaterial(); - } - - IShader* pShader = pCustMat->GetShaderItem().m_pShader; - - if (!pShader) - { - continue; - } - if (pShader->GetFlags() & EF_NODRAW) - { - continue; - } - - if (info.pDecalClipInfo) - { - if (pShader->GetFlags() & EF_DECAL) - { - continue; - } - } - - SRenderMeshInfoInput RMIChunk = *pRMI; - RMIChunk.pMat = info.pDecalClipInfo ? NULL : pCustMat; - RMIChunk.nChunkId = nChunk; - - m_lstRMIChunks.Add(RMIChunk); - } - } -} - -// Note: This code used to be inline in CRenderMeshMerger::MakeListOfAllCRenderChunks, but it was for some reason seg faulting the Android GCC 4.9 compiler in Profile. -void CalculateNormalAndTangent(SPipTangents& basis, SPipNormal& normal, byte* pNorm, byte* pTangs, int nNormStride, int nTangsStride, bool bMatrixHasRotation, int v, SRenderMeshInfoInput* pRMI) -{ - assert((pTangs) || (!pNorm)); - if (pTangs) - { - basis = *(SPipTangents*)&pTangs[nTangsStride * v]; -#if ENABLE_NORMALSTREAM_SUPPORT - if (pNorm) - { - normal = *(SPipNormal*)&pNorm[nNormStride * v]; - } -#endif - - if (bMatrixHasRotation) - { - basis.TransformSafelyBy(pRMI->mat); -#if ENABLE_NORMALSTREAM_SUPPORT - if (pNorm) - { - normal.TransformSafelyBy(pRMI->mat); - } -#endif - } - } -} - - -void CRenderMeshMerger::MakeListOfAllCRenderChunks(SMergeInfo& info) -{ - FUNCTION_PROFILER_3DENGINE; - - m_nTotalVertexCount = 0; - m_nTotalIndexCount = 0; - - for (int nEntityId = 0; nEntityId < m_lstRMIChunks.Count(); nEntityId++) - { - SRenderMeshInfoInput* pRMI = &m_lstRMIChunks[nEntityId]; - - bool bMatrixHasRotation; - if (!pRMI->mat.m01 && !pRMI->mat.m02 && !pRMI->mat.m10 && !pRMI->mat.m12 && !pRMI->mat.m20 && !pRMI->mat.m21) - { - bMatrixHasRotation = false; - } - else - { - bMatrixHasRotation = true; - } - - Matrix34 matInv = pRMI->mat.GetInverted(); - - IRenderMesh* pRM = pRMI->pMesh; - if (!pRM->GetVerticesCount()) - { - continue; - } - - int nInitVertCout = m_lstVerts.Count(); - - - int nPosStride = 0; - int nTexStride = 0; - int nColorStride = 0; - Vec3* pPos = 0; - Vec2* pTex = 0; - UCol* pColor = 0; - - // get vertices's - { - FRAME_PROFILER("CRenderMeshMerger::MakeListOfAllCRenderChunks_GetPosPtr", GetSystem(), PROFILE_3DENGINE); - - pPos = reinterpret_cast(pRM->GetPosPtr(nPosStride, FSL_READ)); - pTex = reinterpret_cast(pRM->GetUVPtr(nTexStride, FSL_READ)); - pColor = reinterpret_cast(pRM->GetColorPtr(nColorStride, FSL_READ)); - } - - if (!pPos || !pTex || !pColor) - { - continue; - } - - // get tangent basis - int nNormStride = 0; - int nTangsStride = 0; - byte* pNorm = 0; - byte* pTangs = 0; - - if (pRM->GetVertexFormat() != eVF_P3S_N4B_C4B_T2S) - { - pTangs = pRM->GetTangentPtr(nTangsStride, FSL_READ); - } - -#if ENABLE_NORMALSTREAM_SUPPORT - // get normal stream - { - pNorm = pRM->GetNormPtr(nNormStride, FSL_READ); - } -#endif - - Vec3 vMin, vMax; - pRM->GetBBox(vMin, vMax); - - // get indices - vtx_idx* pSrcInds = pRM->GetIndexPtr(FSL_READ); - - Vec3 vOSPos(0, 0, 0); - Vec3 vOSProjDir(0, 0, 0); - float fMatrixScale = 1.f; - float fOSRadius = 0.f; - - if (info.pDecalClipInfo && info.pDecalClipInfo->fRadius) - { - vOSPos = matInv.TransformPoint(info.pDecalClipInfo->vPos); - vOSProjDir = matInv.TransformVector(info.pDecalClipInfo->vProjDir); - fMatrixScale = vOSProjDir.GetLength(); - fOSRadius = info.pDecalClipInfo->fRadius * fMatrixScale; - if (vOSProjDir.GetLength() > 0.01f) - { - vOSProjDir.Normalize(); - } - } - - CRenderChunk newMatInfo = pRM->GetChunks()[pRMI->nChunkId]; - -#ifdef _DEBUG - uint32 nIndCount = pRM->GetIndicesCount(); - CRenderChunk Ch = newMatInfo; - for (uint32 i = Ch.nFirstIndexId; i < Ch.nFirstIndexId + Ch.nNumIndices; i++) - { - assert(i >= 0 && i < nIndCount); - assert(pSrcInds[i] >= Ch.nFirstVertId && pSrcInds[i] < Ch.nFirstVertId + Ch.nNumVerts); - assert((int)pSrcInds[i] < pRM->GetVerticesCount()); - } -#endif - - int nFirstIndexId = m_lstIndices.Count(); - - // add indices - for (uint32 i = newMatInfo.nFirstIndexId; i < newMatInfo.nFirstIndexId + newMatInfo.nNumIndices; i += 3) - { - assert((int)pSrcInds[i + 0] < pRM->GetVerticesCount()); - assert((int)pSrcInds[i + 1] < pRM->GetVerticesCount()); - assert((int)pSrcInds[i + 2] < pRM->GetVerticesCount()); - - assert((int)pSrcInds[i + 0] >= newMatInfo.nFirstVertId && pSrcInds[i + 0] < newMatInfo.nFirstVertId + newMatInfo.nNumVerts); - assert((int)pSrcInds[i + 1] >= newMatInfo.nFirstVertId && pSrcInds[i + 1] < newMatInfo.nFirstVertId + newMatInfo.nNumVerts); - assert((int)pSrcInds[i + 2] >= newMatInfo.nFirstVertId && pSrcInds[i + 2] < newMatInfo.nFirstVertId + newMatInfo.nNumVerts); - - // skip not needed triangles for decals - if (fOSRadius) - { - // get verts - Vec3 v0 = pPos[nPosStride * pSrcInds[i + 0]]; - Vec3 v1 = pPos[nPosStride * pSrcInds[i + 1]]; - Vec3 v2 = pPos[nPosStride * pSrcInds[i + 2]]; - - if (vOSProjDir.IsZero()) - { // explosion mode - // test the face - float fDot0 = (vOSPos - v0).Dot((v1 - v0).Cross(v2 - v0)); - float fTest = -0.15f; - if (fDot0 < fTest) - { - continue; - } - } - else - { - // get triangle normal - Vec3 vNormal = (v1 - v0).Cross(v2 - v0); - - // test the face - if (vNormal.Dot(vOSProjDir) <= 0) - { - continue; - } - } - - // get bbox - AABB triBox; - triBox.min = v0; - triBox.min.CheckMin(v1); - triBox.min.CheckMin(v2); - triBox.max = v0; - triBox.max.CheckMax(v1); - triBox.max.CheckMax(v2); - - if (!Overlap::Sphere_AABB(Sphere(vOSPos, fOSRadius), triBox)) - { - continue; - } - } - else if (info.pClipCellBox) - { - // get verts - Vec3 v0 = pRMI->mat.TransformPoint(pPos[nPosStride * pSrcInds[i + 0]]); - Vec3 v1 = pRMI->mat.TransformPoint(pPos[nPosStride * pSrcInds[i + 1]]); - Vec3 v2 = pRMI->mat.TransformPoint(pPos[nPosStride * pSrcInds[i + 2]]); - - if (!Overlap::AABB_Triangle(*info.pClipCellBox, v0, v1, v2)) - { - continue; - } - } - - m_lstIndices.Add((int)(pSrcInds[i + 0]) - newMatInfo.nFirstVertId + nInitVertCout); - m_lstIndices.Add((int)(pSrcInds[i + 1]) - newMatInfo.nFirstVertId + nInitVertCout); - m_lstIndices.Add((int)(pSrcInds[i + 2]) - newMatInfo.nFirstVertId + nInitVertCout); - } - - newMatInfo.nFirstIndexId = nFirstIndexId; - newMatInfo.nNumIndices = m_lstIndices.Count() - nFirstIndexId; - - if (!newMatInfo.nNumIndices) - { - continue; - } - - // add vertices - for (int v = newMatInfo.nFirstVertId; v < (int)newMatInfo.nFirstVertId + (int)newMatInfo.nNumVerts; v++) - { - assert(v >= 0 && v < pRM->GetVerticesCount()); - - SVF_P3S_C4B_T2S vert; - - // set pos - Vec3 vPos = pPos[nPosStride * v]; - vPos = pRMI->mat.TransformPoint(vPos); - vert.xyz = vPos - info.vResultOffset; - - // set uv - if (pTex) - { - vert.st = pTex[nTexStride * v]; - } - else - { - vert.st = Vec2f16(0, 0); - } - - vert.color = pColor[nColorStride * v + 0]; - - m_lstVerts.Add(vert); - - // get tangent basis + normal - SPipTangents basis = SPipTangents(Vec4sf(0, 0, 0, 0), Vec4sf(0, 0, 0, 0)); - SPipNormal normal = SPipNormal(Vec3(0, 0, 0)); - - CalculateNormalAndTangent(basis, normal, pNorm, pTangs, nNormStride, nTangsStride, bMatrixHasRotation, v, pRMI); - - m_lstTangBasises.Add(basis); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Add(normal); -#endif - } - - // set vert range - newMatInfo.nFirstVertId = m_lstVerts.Count() - newMatInfo.nNumVerts; - newMatInfo.pRE = NULL; - - // assert(IsHeapValid()); - // IsChunkValid(newMatInfo, m_lstVerts, m_lstIndices); - - if (m_lstChunks.Count()) - { - assert(m_lstChunks.Last().rChunk.nFirstVertId + m_lstChunks.Last().rChunk.nNumVerts == newMatInfo.nFirstVertId); - } - - if (newMatInfo.nNumIndices) - { - SMergedChunk mrgChunk; - mrgChunk.rChunk = newMatInfo; - mrgChunk.rChunk.nSubObjectIndex = pRMI->nSubObjectIndex; - mrgChunk.pMaterial = info.pDecalClipInfo ? NULL : pRMI->pMat.get(); - if (pRMI->pMat) - { - mrgChunk.rChunk.m_nMatFlags = pRMI->pMat->GetFlags(); - } - m_lstChunks.Add(mrgChunk); - } - - m_nTotalVertexCount += newMatInfo.nNumVerts; - m_nTotalIndexCount += newMatInfo.nNumIndices; - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::CompactVertices(SMergeInfo& info) -{ - if (info.bPrintDebugMessages) - { - PrintMessage("Removing unused vertices"); - } - - PodArray lstVertUsage; - lstVertUsage.PreAllocate(m_lstVerts.Count(), m_lstVerts.Count()); - for (int i = 0; i < m_lstIndices.Count(); i++) - { - lstVertUsage[m_lstIndices[i]] = 1; - } - - PodArray lstVertsOptimized; - lstVertsOptimized.PreAllocate(m_lstVerts.Count()); - PodArray lstTangBasisesOptimized; - lstTangBasisesOptimized.PreAllocate(m_lstVerts.Count()); -#if ENABLE_NORMALSTREAM_SUPPORT - PodArray lstNormalsOptimized; - lstNormalsOptimized.PreAllocate(m_lstVerts.Count()); -#endif - - int nCurChunkId = 0; - CRenderChunk* pChBack = &m_lstChunks[0].rChunk; - int nVertsRemoved = 0; - PodArray lstChunksBk; - lstChunksBk.AddList(m_lstChunks); - for (int i = 0; i < m_lstVerts.Count(); ) - { - if (lstVertUsage[i]) - { - lstVertsOptimized.Add(m_lstVerts[i]); - lstTangBasisesOptimized.Add(m_lstTangBasises[i]); -#if ENABLE_NORMALSTREAM_SUPPORT - lstNormalsOptimized.Add(m_lstNormals[i]); -#endif - } - else - { - nVertsRemoved++; - } - - lstVertUsage[i] = lstVertsOptimized.Count() - 1; - - i++; - - if (i >= (int)lstChunksBk[nCurChunkId].rChunk.nFirstVertId + (int)lstChunksBk[nCurChunkId].rChunk.nNumVerts) - { - if (nVertsRemoved) - { - pChBack->nNumVerts -= nVertsRemoved; - - for (int nId = nCurChunkId + 1; nId < m_lstChunks.Count(); nId++) - { - CRenderChunk& ChBack = m_lstChunks[nId].rChunk; - ChBack.nFirstVertId -= nVertsRemoved; - } - - nVertsRemoved = 0; - } - - nCurChunkId++; - if (nCurChunkId < m_lstChunks.Count()) - { - pChBack = &m_lstChunks[nCurChunkId].rChunk; - } - else - { - break; - } - } - } - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - m_lstIndices[i] = lstVertUsage[m_lstIndices[i]]; - } - - int nOldVertsNum = m_lstVerts.Count(); - - m_lstVerts = lstVertsOptimized; - m_lstTangBasises = lstTangBasisesOptimized; -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals = lstNormalsOptimized; -#endif - - if (info.bPrintDebugMessages) - { - PrintMessage("old->new = %d->%d vertices", nOldVertsNum, m_lstVerts.Count()); - } - - int nBadTrisCount = 0; - for (int i = 0; i < m_lstIndices.Count(); i += 3) - { - if (m_lstIndices[i + 0] == m_lstIndices[i + 1] || - m_lstIndices[i + 1] == m_lstIndices[i + 2] || - m_lstIndices[i + 2] == m_lstIndices[i + 0]) - { - nBadTrisCount++; - } - } - - if (nBadTrisCount) - { - PrintMessage("CRenderMeshMerger::CompactVertices: Warning: %d bad tris found", nBadTrisCount); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::ClipByAABB(SMergeInfo& info) -{ - if (info.bPrintDebugMessages) - { - PrintMessage(" Do clipping . . ." /*, m_lstChunks.Count()*/); - } - - { // minimize range - uint32 nMin = ~0; - uint32 nMax = 0; - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - if (nMin > m_lstIndices[i]) - { - nMin = m_lstIndices[i]; - } - if (nMax < m_lstIndices[i]) - { - nMax = m_lstIndices[i]; - } - } - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - m_lstIndices[i] -= nMin; - } - - if (m_lstVerts.Count() - nMax - 1 > 0) - { - m_lstVerts.Delete(nMax + 1, m_lstVerts.Count() - (nMax + 1)); - m_lstTangBasises.Delete(nMax + 1, m_lstTangBasises.Count() - (nMax + 1)); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(nMax + 1, m_lstNormals.Count() - (nMax + 1)); -#endif - } - - m_lstVerts.Delete(0, nMin); - m_lstTangBasises.Delete(0, nMin); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(0, nMin); -#endif - } - - // define clip planes - Plane planes[6]; - float fClipRadius = info.pDecalClipInfo->fRadius * 1.3f; - planes[0].SetPlane(Vec3(0, 0, 1), info.pDecalClipInfo->vPos + Vec3(0, 0, fClipRadius)); - planes[1].SetPlane(Vec3(0, 0, -1), info.pDecalClipInfo->vPos + Vec3(0, 0, -fClipRadius)); - planes[2].SetPlane(Vec3(0, 1, 0), info.pDecalClipInfo->vPos + Vec3(0, fClipRadius, 0)); - planes[3].SetPlane(Vec3(0, -1, 0), info.pDecalClipInfo->vPos + Vec3(0, -fClipRadius, 0)); - planes[4].SetPlane(Vec3(1, 0, 0), info.pDecalClipInfo->vPos + Vec3(fClipRadius, 0, 0)); - planes[5].SetPlane(Vec3(-1, 0, 0), info.pDecalClipInfo->vPos + Vec3(-fClipRadius, 0, 0)); - - // clip triangles - int nOrigCount = m_lstIndices.Count(); - for (int i = 0; i < nOrigCount; i += 3) - { - if (ClipTriangle(i, planes, 6)) - { - i -= 3; - nOrigCount -= 3; - } - } - - if (m_lstIndices.Count() < 3 || m_lstVerts.Count() < 3) - { - return; - } - - assert(m_lstTangBasises.Count() == m_lstVerts.Count()); -#if ENABLE_NORMALSTREAM_SUPPORT - assert(m_lstNormals.Count() == m_lstVerts.Count()); -#endif - - { // minimize range - uint32 nMin = ~0; - uint32 nMax = 0; - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - if (nMin > m_lstIndices[i]) - { - nMin = m_lstIndices[i]; - } - if (nMax < m_lstIndices[i]) - { - nMax = m_lstIndices[i]; - } - } - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - m_lstIndices[i] -= nMin; - } - - if (m_lstVerts.Count() - nMax - 1 > 0) - { - m_lstVerts.Delete(nMax + 1, m_lstVerts.Count() - (nMax + 1)); - m_lstTangBasises.Delete(nMax + 1, m_lstTangBasises.Count() - (nMax + 1)); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(nMax + 1, m_lstNormals.Count() - (nMax + 1)); -#endif - } - - m_lstVerts.Delete(0, nMin); - m_lstTangBasises.Delete(0, nMin); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(0, nMin); -#endif - } - -#ifdef _DEBUG - assert(m_lstTangBasises.Count() == m_lstVerts.Count()); -#if ENABLE_NORMALSTREAM_SUPPORT - assert(m_lstNormals.Count() == m_lstVerts.Count()); -#endif - for (int i = 0; i < m_lstIndices.Count(); i++) - { - assert(m_lstIndices[i] >= 0 && m_lstIndices[i] < (uint32)m_lstVerts.Count()); - } -#endif - - if (m_lstIndices.Count() < 3 || m_lstVerts.Count() < 3) - { - return; - } - - m_lstChunks[0].rChunk.nNumIndices = m_lstIndices.Count(); - m_lstChunks[0].rChunk.nNumVerts = m_lstVerts.Count(); -} - -////////////////////////////////////////////////////////////////////////// -bool CRenderMeshMerger::ClipTriangle(int nStartIdxId, Plane* pPlanes, int nPlanesNum) -{ - const PodArray& clipped = m_tmpClipContext.Clip( - m_lstVerts[m_lstIndices[nStartIdxId + 0]].xyz.ToVec3(), - m_lstVerts[m_lstIndices[nStartIdxId + 1]].xyz.ToVec3(), - m_lstVerts[m_lstIndices[nStartIdxId + 2]].xyz.ToVec3(), - pPlanes, nPlanesNum); - - if (clipped.Count() < 3) - { - m_lstIndices.Delete(nStartIdxId, 3); - return true; // entire triangle is clipped away - } - - if (clipped.Count() == 3) - { - if (clipped[0].IsEquivalent(m_lstVerts[m_lstIndices[nStartIdxId + 0]].xyz.ToVec3())) - { - if (clipped[1].IsEquivalent(m_lstVerts[m_lstIndices[nStartIdxId + 1]].xyz.ToVec3())) - { - if (clipped[2].IsEquivalent(m_lstVerts[m_lstIndices[nStartIdxId + 2]].xyz.ToVec3())) - { - return false; // entire triangle is in - } - } - } - } - // replace old triangle with several new triangles - int nStartId = m_lstVerts.Count(); - int nStartIndex = m_lstIndices[nStartIdxId + 0]; - SVF_P3S_C4B_T2S fullVert = m_lstVerts[nStartIndex]; - SPipTangents fullTang = m_lstTangBasises[nStartIndex]; -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal fullNorm = m_lstNormals[nStartIndex]; -#endif - - for (int i = 0; i < clipped.Count(); i++) - { - fullVert.xyz = clipped[i]; - m_lstVerts.Add(fullVert); - m_lstTangBasises.Add(fullTang); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Add(fullNorm); -#endif - } - - // put first new triangle into position of original one - m_lstIndices[nStartIdxId + 0] = nStartId + 0; - m_lstIndices[nStartIdxId + 1] = nStartId + 1; - m_lstIndices[nStartIdxId + 2] = nStartId + 2; - - // put others in the end - for (int i = 1; i < clipped.Count() - 2; i++) - { - m_lstIndices.Add(nStartId + 0); - m_lstIndices.Add(nStartId + i + 1); - m_lstIndices.Add(nStartId + i + 2); - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::ClipDecals(SMergeInfo& info) -{ - if (info.bPrintDebugMessages) - { - PrintMessage(" Do clipping . . ." /*, m_lstChunks.Count()*/); - } - - { // minimize range - uint32 nMin = ~0; - uint32 nMax = 0; - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - if (nMin > m_lstIndices[i]) - { - nMin = m_lstIndices[i]; - } - if (nMax < m_lstIndices[i]) - { - nMax = m_lstIndices[i]; - } - } - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - m_lstIndices[i] -= nMin; - } - - if (m_lstVerts.Count() - nMax - 1 > 0) - { - m_lstVerts.Delete(nMax + 1, m_lstVerts.Count() - (nMax + 1)); - m_lstTangBasises.Delete(nMax + 1, m_lstTangBasises.Count() - (nMax + 1)); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(nMax + 1, m_lstNormals.Count() - (nMax + 1)); -#endif - } - - m_lstVerts.Delete(0, nMin); - m_lstTangBasises.Delete(0, nMin); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(0, nMin); -#endif - } - - // define clip planes - Plane planes[6]; - float fClipRadius = info.pDecalClipInfo->fRadius * 1.3f; - planes[0].SetPlane(Vec3(0, 0, 1), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(0, 0, fClipRadius)); - planes[1].SetPlane(Vec3(0, 0, -1), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(0, 0, -fClipRadius)); - planes[2].SetPlane(Vec3(0, 1, 0), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(0, fClipRadius, 0)); - planes[3].SetPlane(Vec3(0, -1, 0), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(0, -fClipRadius, 0)); - planes[4].SetPlane(Vec3(1, 0, 0), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(fClipRadius, 0, 0)); - planes[5].SetPlane(Vec3(-1, 0, 0), info.pDecalClipInfo->vPos - info.vResultOffset + Vec3(-fClipRadius, 0, 0)); - - // clip triangles - int nOrigCount = m_lstIndices.Count(); - for (int i = 0; i < nOrigCount; i += 3) - { - if (ClipTriangle(i, planes, 6)) - { - i -= 3; - nOrigCount -= 3; - } - } - - if (m_lstIndices.Count() < 3 || m_lstVerts.Count() < 3) - { - return; - } - - assert(m_lstTangBasises.Count() == m_lstVerts.Count()); -#if ENABLE_NORMALSTREAM_SUPPORT - assert(m_lstNormals.Count() == m_lstVerts.Count()); -#endif - - { // minimize range - uint32 nMin = ~0; - uint32 nMax = 0; - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - if (nMin > m_lstIndices[i]) - { - nMin = m_lstIndices[i]; - } - if (nMax < m_lstIndices[i]) - { - nMax = m_lstIndices[i]; - } - } - - for (int i = 0; i < m_lstIndices.Count(); i++) - { - m_lstIndices[i] -= nMin; - } - - if (m_lstVerts.Count() - nMax - 1 > 0) - { - m_lstVerts.Delete(nMax + 1, m_lstVerts.Count() - (nMax + 1)); - m_lstTangBasises.Delete(nMax + 1, m_lstTangBasises.Count() - (nMax + 1)); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(nMax + 1, m_lstNormals.Count() - (nMax + 1)); -#endif - } - - m_lstVerts.Delete(0, nMin); - m_lstTangBasises.Delete(0, nMin); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.Delete(0, nMin); -#endif - } - -#ifdef _DEBUG - assert(m_lstTangBasises.Count() == m_lstVerts.Count()); -#if ENABLE_NORMALSTREAM_SUPPORT - assert(m_lstNormals.Count() == m_lstVerts.Count()); -#endif - for (int i = 0; i < m_lstIndices.Count(); i++) - { - assert(m_lstIndices[i] >= 0 && m_lstIndices[i] < (uint32)m_lstVerts.Count()); - } -#endif - - if (m_lstIndices.Count() < 3 || m_lstVerts.Count() < 3) - { - return; - } - - m_lstChunks[0].rChunk.nNumIndices = m_lstIndices.Count(); - m_lstChunks[0].rChunk.nNumVerts = m_lstVerts.Count(); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::TryMergingChunks(SMergeInfo& info) -{ - PodArray& lstChunksMerged = m_lstChunksMergedTemp; - lstChunksMerged.clear(); - lstChunksMerged.reserve(m_lstChunks.size()); - - AZ::Vertex::Format currentVertexFormat; - for (int nChunkId = 0; nChunkId < m_lstChunks.Count(); nChunkId++) - { - SMergedChunk& mergChunk = m_lstChunks[nChunkId]; - - // IsChunkValid(mergChunk, m_lstVerts, m_lstIndices); - - AZ::Vertex::Format chunkVertexFormat; - if (info.pDecalClipInfo) - { - chunkVertexFormat = AZ::Vertex::Format(); - } - else if (info.bMergeToOneRenderMesh) - { - chunkVertexFormat = currentVertexFormat; - } - else - { - _smart_ptr pMat = mergChunk.pMaterial; - chunkVertexFormat = mergChunk.rChunk.m_vertexFormat; - } - - if (!nChunkId || - (chunkVertexFormat != currentVertexFormat || Cmp_RenderChunks_(&mergChunk, &m_lstChunks[nChunkId - 1]) || - (lstChunksMerged.Last().rChunk.nNumVerts + mergChunk.rChunk.nNumVerts) > 0xFFFF)) - { // not equal materials - add new chunk - lstChunksMerged.Add(mergChunk); - } - else - { - float texelAreaDensity = 0.0f; - int totalIndices = 0; - - if (lstChunksMerged.Last().rChunk.m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += lstChunksMerged.Last().rChunk.nNumIndices * lstChunksMerged.Last().rChunk.m_texelAreaDensity; - totalIndices += lstChunksMerged.Last().rChunk.nNumIndices; - } - - if (mergChunk.rChunk.m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += mergChunk.rChunk.nNumIndices * mergChunk.rChunk.m_texelAreaDensity; - totalIndices += mergChunk.rChunk.nNumIndices; - } - - if (totalIndices != 0) - { - lstChunksMerged.Last().rChunk.m_texelAreaDensity = texelAreaDensity / totalIndices; - } - - lstChunksMerged.Last().rChunk.nNumIndices += mergChunk.rChunk.nNumIndices; - lstChunksMerged.Last().rChunk.nNumVerts += mergChunk.rChunk.nNumVerts; - } - - IsChunkValid(lstChunksMerged.Last().rChunk, m_lstVerts, m_lstIndices); - - currentVertexFormat = chunkVertexFormat; - } - - m_lstChunks = lstChunksMerged; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CRenderMeshMerger::MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, - PodArray& outRenderMeshes, - SMergeInfo& info) PREFAST_SUPPRESS_WARNING(6262) //function uses > 32k stack space -{ - FUNCTION_PROFILER_3DENGINE; - - if (info.bPrintDebugMessages) - { - PrintMessage("MergeRenderMeshs: name: %s, input brushes num: %d", info.sMeshName, nRMICount); - } - - m_nTotalVertexCount = 0; - m_nTotalIndexCount = 0; - - m_lstRMIChunks.clear(); - m_lstVerts.clear(); - m_lstTangBasises.clear(); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.clear(); -#endif - m_lstIndices.clear(); - m_lstChunks.clear(); - - // make list of all chunks - MakeRenderMeshInfoListOfAllChunks(pRMIArray, nRMICount, info); - - if (info.bPrintDebugMessages) - { - PrintMessage("%d render chunks found", m_lstRMIChunks.Count()); - } - - if (!m_lstRMIChunks.Count()) - { - return NULL; - } - - // sort by materials - if (!info.pDecalClipInfo) - { - qsort(m_lstRMIChunks.GetElements(), m_lstRMIChunks.Count(), sizeof(m_lstRMIChunks[0]), Cmp_RenderChunksInfo); - } - - // make list of all CRenderChunks - MakeListOfAllCRenderChunks(info); - - // assert(IsHeapValid()); - - if (!m_lstVerts.Count() || !m_lstChunks.Count() || !m_lstIndices.Count()) - { - return NULL; - } - - if (info.bPrintDebugMessages) - { - PrintMessage("%d chunks left after culling (%d verts, %d indices)", m_lstChunks.Count(), m_lstVerts.Count(), m_lstIndices.Count()); - } - - // Split chunks that does not fit together. - TryMergingChunks(info); - - if (info.bPrintDebugMessages) - { - PrintMessage("%d chunks left after merging", m_lstChunks.Count()); - } - - if (!m_lstChunks.Count()) - { - return NULL; - } - - // now we have list of merged/sorted chunks, indices and vertices's - // overall amount of vertices's may be more than 0xFFFF - if (m_lstChunks.Count() == 1 && info.pDecalClipInfo && GetCVars()->e_DecalsClip) - { - // clip decals if needed - ClipDecals(info); - if (m_lstIndices.Count() < 3 || m_lstVerts.Count() < 3) - { - return NULL; - } - - // find AABB - AABB aabb = AABB(m_lstVerts[0].xyz.ToVec3(), m_lstVerts[0].xyz.ToVec3()); - for (int i = 0; i < m_lstVerts.Count(); i++) - { - aabb.Add(m_lstVerts[i].xyz.ToVec3()); - } - - // weld positions - mesh_compiler::CMeshCompiler meshCompiler; -#if ENABLE_NORMALSTREAM_SUPPORT - PREFAST_SUPPRESS_WARNING(6385); - meshCompiler.WeldPos_VF_P3X(m_lstVerts, m_lstTangBasises, m_lstNormals, m_lstIndices, VEC_EPSILON, aabb); -#else - PodArray lstNormalsDummy; - meshCompiler.WeldPos_VF_P3X(m_lstVerts, m_lstTangBasises, lstNormalsDummy, m_lstIndices, VEC_EPSILON, aabb); -#endif - - // update chunk - CRenderChunk& Ch0 = m_lstChunks[0].rChunk; - Ch0.nFirstIndexId = 0; - Ch0.nNumIndices = m_lstIndices.Count(); - Ch0.nFirstVertId = 0; - Ch0.nNumVerts = m_lstVerts.Count(); - } - - if (/*GetCVars()->e_scene_merging_compact_vertices && */ info.bCompactVertBuffer) - { // remove gaps in vertex buffers - CompactVertices(info); - } - -#ifdef _DEBUG - for (int nChunkId = 0; nChunkId < m_lstChunks.Count(); nChunkId++) - { - CRenderChunk& Ch0 = m_lstChunks[nChunkId].rChunk; - IsChunkValid(Ch0, m_lstVerts, m_lstIndices); - } -#endif // _DEBUG - - if (info.bPrintDebugMessages) - { - PrintMessage("Making new RenderMeshes"); - } - - outRenderMeshes.clear(); - - m_lstNewChunks.reserve(m_lstChunks.Count()); - m_lstNewVerts.reserve(m_nTotalVertexCount); - m_lstNewTangBasises.reserve(m_nTotalVertexCount); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.reserve(m_nTotalVertexCount); -#endif - m_lstNewIndices.reserve(m_nTotalIndexCount); - - for (int nChunkId = 0; nChunkId < m_lstChunks.Count(); ) - { - AABB finalBox; - finalBox.Reset(); - - m_lstNewVerts.clear(); - m_lstNewTangBasises.clear(); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.clear(); -#endif - m_lstNewIndices.clear(); - m_lstNewChunks.clear(); - - int nVertsNum = 0; - for (; nChunkId < m_lstChunks.Count(); ) - { - CRenderChunk Ch = m_lstChunks[nChunkId].rChunk; - SMergedChunk& mrgChunk = m_lstChunks[nChunkId]; - - assert(m_lstNewVerts.Count() + Ch.nNumVerts <= 0xFFFF); - - IsChunkValid(Ch, m_lstVerts, m_lstIndices); - - int nCurrIdxPos = m_lstNewIndices.Count(); - int nCurrVertPos = m_lstNewVerts.Count(); - - m_lstNewVerts.AddList(&m_lstVerts[Ch.nFirstVertId], Ch.nNumVerts); - m_lstNewTangBasises.AddList(&m_lstTangBasises[Ch.nFirstVertId], Ch.nNumVerts); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.AddList(&m_lstNormals[Ch.nFirstVertId], Ch.nNumVerts); -#endif - - for (uint32 i = Ch.nFirstIndexId; i < Ch.nFirstIndexId + Ch.nNumIndices; i++) - { - uint32 nIndex = m_lstIndices[i] - Ch.nFirstVertId + nCurrVertPos; - assert(nIndex >= 0 && nIndex <= 0xFFFF && nIndex < (uint32)m_lstNewVerts.Count()); - nIndex = nIndex & 0xFFFF; - m_lstNewIndices.Add(nIndex); - finalBox.Add(m_lstNewVerts[nIndex].xyz.ToVec3()); - } - - Ch.nFirstIndexId = nCurrIdxPos; - Ch.nFirstVertId = nCurrVertPos; - - nVertsNum += Ch.nNumVerts; - - { - assert(Ch.nFirstIndexId + Ch.nNumIndices <= (uint32)m_lstNewIndices.Count()); - assert(Ch.nFirstVertId + Ch.nNumVerts <= (uint16)m_lstNewVerts.Count()); - -#ifdef _DEBUG - for (uint32 i = Ch.nFirstIndexId; i < Ch.nFirstIndexId + Ch.nNumIndices; i++) - { - assert(m_lstNewIndices[i] >= Ch.nFirstVertId && m_lstNewIndices[i] < Ch.nFirstVertId + Ch.nNumVerts); - assert((int)m_lstNewIndices[i] < m_lstNewVerts.Count()); - } -#endif - } - - SMergedChunk newMergedChunk; - newMergedChunk.rChunk = Ch; - newMergedChunk.pMaterial = mrgChunk.pMaterial; - m_lstNewChunks.Add(newMergedChunk); - - nChunkId++; - - if (nChunkId < m_lstChunks.Count()) - { - if (nVertsNum + m_lstChunks[nChunkId].rChunk.nNumVerts > 0xFFFF) - { - break; - } - - if (info.bMergeToOneRenderMesh) - { - continue; - } - - // detect vert format change - SShaderItem& shaderItemCur = mrgChunk.pMaterial->GetShaderItem(); - AZ::Vertex::Format nextChunkVertexFormatCurrent = shaderItemCur.m_pShader->GetVertexFormat(); - nextChunkVertexFormatCurrent = mrgChunk.rChunk.m_vertexFormat; - - SShaderItem& shaderItemNext = m_lstChunks[nChunkId].pMaterial->GetShaderItem(); - AZ::Vertex::Format nextChunkVertFormatNext = shaderItemNext.m_pShader->GetVertexFormat(); - nextChunkVertFormatNext = m_lstChunks[nChunkId].rChunk.m_vertexFormat; - - if (nextChunkVertFormatNext != nextChunkVertexFormatCurrent) - { - break; - } - } - } - - IRenderMesh::SInitParamerers params; - params.pVertBuffer = m_lstNewVerts.GetElements(); - params.nVertexCount = m_lstNewVerts.Count(); - params.vertexFormat = eVF_P3S_C4B_T2S; - params.pIndices = m_lstNewIndices.GetElements(); - params.nIndexCount = m_lstNewIndices.Count(); - params.pTangents = m_lstNewTangBasises.GetElements(); -#if ENABLE_NORMALSTREAM_SUPPORT - params.pNormals = m_lstNewNormals.GetElements(); -#endif - params.nPrimetiveType = prtTriangleList; - params.eType = eRMT_Static; - params.nRenderChunkCount = 0; - params.bOnlyVideoBuffer = false; - params.bPrecache = false; - - // make new RenderMesh - _smart_ptr pNewLB = GetRenderer()->CreateRenderMesh(info.sMeshName, info.sMeshType, ¶ms); - - _smart_ptr pParentMaterial = NULL; - - pNewLB->SetBBox(finalBox.min, finalBox.max); - - if (!info.pUseMaterial) - { - // make new parent material - if (!info.pDecalClipInfo) - { - char szMatName[256] = ""; - sprintf_s(szMatName, "%s_Material", info.sMeshName); - pParentMaterial = GetMatMan()->CreateMaterial(szMatName, MTL_FLAG_MULTI_SUBMTL); - pParentMaterial->AddRef(); - pParentMaterial->SetSubMtlCount(m_lstChunks.Count()); - } - - // define chunks - for (int i = 0; i < m_lstNewChunks.Count(); i++) - { - CRenderChunk* pChunk = &m_lstNewChunks[i].rChunk; - - _smart_ptr pMat = m_lstNewChunks[i].pMaterial; - - if (pParentMaterial) - { - assert(pMat); - pParentMaterial->SetSubMtl(i, pMat); - } - - assert(pChunk->nFirstIndexId + pChunk->nNumIndices <= (uint32)m_lstNewIndices.Count()); - - pChunk->m_nMatID = i; - if (pMat) - { - pChunk->m_nMatFlags = pMat->GetFlags(); - } - pNewLB->SetChunk(i, *pChunk); - } - } - else - { - pParentMaterial = info.pUseMaterial; - - // define chunks - for (int i = 0; i < m_lstNewChunks.Count(); i++) - { - CRenderChunk* pChunk = &m_lstNewChunks[i].rChunk; - assert(pChunk->nFirstIndexId + pChunk->nNumIndices <= (uint32)m_lstNewIndices.Count()); - - _smart_ptr pSubMtl = info.pUseMaterial->GetSafeSubMtl(pChunk->m_nMatID); - pChunk->m_nMatFlags = pSubMtl->GetFlags(); - - pNewLB->SetChunk(i, *pChunk); - } - } - - SRenderMeshInfoOutput rmi; - rmi.pMesh = pNewLB; - rmi.pMat = pParentMaterial; - if (pParentMaterial) - { - pParentMaterial->AddRef(); - } - - outRenderMeshes.push_back(rmi); - } - - if (info.bPrintDebugMessages) - { - PrintMessage("%" PRISIZE_T " RenderMeshes created", outRenderMeshes.size()); - } - - return outRenderMeshes.Count() ? outRenderMeshes[0].pMesh : _smart_ptr(NULL); -} - -struct sort_render_chunks_by_material -{ - bool operator ()(const SMergedChunk& c1, const SMergedChunk& c2) const - { - return c1.pMaterial < c2.pMaterial; - } -}; - -////////////////////////////////////////////////////////////////////////// -bool CRenderMeshMerger::GenerateRenderChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount) -{ - bool bCanMerge = true; - PodArray& allChunks = m_lstChunksAll; - - allChunks.clear(); - allChunks.reserve(nRMICount); - - for (int nRmi = 0; nRmi < nRMICount; nRmi++) - { - SRenderMeshInfoInput* pRMI = &pRMIArray[nRmi]; - IRenderMesh* pRM = pRMI->pMesh; - - // Ignore bad meshes. - if (pRM->GetVerticesCount() == 0 || pRM->GetIndicesCount() == 0) - { - continue; - } - - const TRenderChunkArray& chunks = pRM->GetChunks(); - int nChunkCount = chunks.size(); - for (int nChunk = 0; nChunk < nChunkCount; nChunk++) - { - const CRenderChunk& renderChunk = chunks[nChunk]; - - if (renderChunk.m_nMatFlags & MTL_FLAG_NODRAW || !renderChunk.pRE) - { - continue; - } - - if (renderChunk.nNumVerts == 0 || renderChunk.nNumIndices == 0) - { - continue; - } - - if (!pRMI->pMat) - { - continue; - } - - _smart_ptr pCustMat = (pRMI->pMat) ? pRMI->pMat->GetSafeSubMtl(renderChunk.m_nMatID) : 0; - if (!pCustMat) - { - continue; - } - - if (!pCustMat->GetShaderItem().m_pShader) - { - pCustMat = GetMatMan()->GetDefaultMaterial(); - } - - IShader* pShader = pCustMat->GetShaderItem().m_pShader; - - if (!pShader) - { - continue; - } - - if (pShader->GetFlags() & EF_NODRAW) - { - continue; - } - - SMergedChunk newChunk; - newChunk.pFromMesh = pRMI; - newChunk.pMaterial = pCustMat; - newChunk.rChunk = renderChunk; - newChunk.rChunk.nSubObjectIndex = pRMI->nSubObjectIndex; - newChunk.rChunk.pRE = 0; - - allChunks.push_back(newChunk); - } - } - - // sort by materials - std::sort(allChunks.begin(), allChunks.end(), sort_render_chunks_by_material()); - - return bCanMerge; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::MergeRenderChunks() -{ - PodArray& allChunks = m_lstChunksAll; - - ////////////////////////////////////////////////////////////////////////// - // Create array of merged chunks. - ////////////////////////////////////////////////////////////////////////// - PodArray& mergedChunks = m_lstChunks; - mergedChunks.clear(); - mergedChunks.reserve(allChunks.size()); - - if (allChunks.size() > 0) - { - // Add first chunk. - mergedChunks.push_back(allChunks[0]); - } - - for (size_t nChunkId = 1; nChunkId < allChunks.size(); nChunkId++) - { - SMergedChunk& currChunk = allChunks[nChunkId]; - - SMergedChunk& prevChunk = mergedChunks.back(); - - if ((currChunk.pMaterial != prevChunk.pMaterial) || - ((prevChunk.rChunk.nNumVerts + currChunk.rChunk.nNumVerts) > 0xFFFF) || - ((prevChunk.rChunk.nNumIndices + currChunk.rChunk.nNumIndices) > 0xFFFF)) - { // not equal materials - add new chunk - mergedChunks.Add(currChunk); - } - else - { - float texelAreaDensity = 0.0f; - int totalIndices = 0; - - if (prevChunk.rChunk.m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += prevChunk.rChunk.nNumIndices * prevChunk.rChunk.m_texelAreaDensity; - totalIndices += prevChunk.rChunk.nNumIndices; - } - - if (currChunk.rChunk.m_texelAreaDensity != (float)UINT_MAX) - { - texelAreaDensity += currChunk.rChunk.nNumIndices * currChunk.rChunk.m_texelAreaDensity; - totalIndices += currChunk.rChunk.nNumIndices; - } - - if (totalIndices != 0) - { - prevChunk.rChunk.m_texelAreaDensity = texelAreaDensity / totalIndices; - } - else - { - prevChunk.rChunk.m_texelAreaDensity = 1.f; - } - - prevChunk.rChunk.nNumIndices += currChunk.rChunk.nNumIndices; - prevChunk.rChunk.nNumVerts += currChunk.rChunk.nNumVerts; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMeshMerger::MergeBuffers(AABB& bounds) -{ - FUNCTION_PROFILER_3DENGINE; - - m_nTotalVertexCount = 0; - m_nTotalIndexCount = 0; - - int nNeedVertices = 0; - int nNeedIndices = 0; - - PodArray& allChunks = m_lstChunksAll; - - // Calculate total required sizes. - for (size_t nChunk = 0; nChunk < allChunks.size(); nChunk++) - { - SMergedChunk& renderChunk = allChunks[nChunk]; - nNeedIndices += renderChunk.rChunk.nNumIndices; - nNeedVertices += renderChunk.rChunk.nNumVerts; - } - - PodArray& arrIndices = m_lstNewIndices; - arrIndices.clear(); - arrIndices.reserve(nNeedIndices); - - PodArray& arrVertices = m_lstVerts; - arrVertices.clear(); - arrVertices.reserve(nNeedVertices); - - PodArray& arrTangents = m_lstTangBasises; - arrTangents.clear(); - arrTangents.reserve(nNeedVertices); - -#if ENABLE_NORMALSTREAM_SUPPORT - PodArray& arrNormals = m_lstNormals; - arrNormals.clear(); - arrNormals.reserve(nNeedVertices); -#endif - - m_lstMergeBuffersData.clear(); - m_lstMergeBuffersData.resize(allChunks.size()); - - m_tmpAABB = bounds; - - // do all GetPos etc calls before in the t thread - for (size_t nChunk = 0; nChunk < allChunks.size(); nChunk++) - { - SMergeBuffersData& rMergeBufferData = m_lstMergeBuffersData[nChunk]; - IRenderMesh* pRM = allChunks[nChunk].pFromMesh->pMesh; - pRM->LockForThreadAccess(); - rMergeBufferData.pPos = pRM->GetPosPtr(rMergeBufferData.nPosStride, FSL_READ); - rMergeBufferData.pTex = pRM->GetUVPtr(rMergeBufferData.nTexStride, FSL_READ); - rMergeBufferData.pColor = pRM->GetColorPtr(rMergeBufferData.nColorStride, FSL_READ); - rMergeBufferData.pTangs = pRM->GetTangentPtr(rMergeBufferData.nTangsStride, FSL_READ); - rMergeBufferData.nIndCount = pRM->GetIndicesCount(); - rMergeBufferData.pSrcInds = pRM->GetIndexPtr(FSL_READ); - -#if ENABLE_NORMALSTREAM_SUPPORT - rMergeBufferData.pNorm = pRM->GetNormPtr(rMergeBufferData.nNormStride, FSL_READ); -#endif - } - - MergeBuffersImpl(&m_tmpAABB, m_lstMergeBuffersData.GetElements()); - - // operation on buffers has finished, unlock them again for rendermesh garbage collection - for (size_t nChunk = 0; nChunk < allChunks.size(); nChunk++) - { - IRenderMesh* pRM = allChunks[nChunk].pFromMesh->pMesh; - pRM->UnLockForThreadAccess(); - } - - bounds = m_tmpAABB; -} - -void CRenderMeshMerger::MergeBuffersImpl(AABB* pBounds, SMergeBuffersData* _arrMergeBuffersData) -{ - // size for SPU buffers, currently we have 16 buffers, means we need 128 kb - uint32 nNumMergeChunks = m_lstChunksAll.size(); - - PodArray& allChunks = m_lstChunksAll; - SMergeBuffersData* arrMergeBuffersData = _arrMergeBuffersData; - - PodArray& arrIndices = m_lstNewIndices; - PodArray& arrVertices = m_lstVerts; - PodArray& arrTangents = m_lstTangBasises; - -#if ENABLE_NORMALSTREAM_SUPPORT - PodArray& arrNormals = m_lstNormals; -#endif - - for (size_t nChunk = 0; nChunk < nNumMergeChunks; nChunk++) - { - SMergedChunk& renderChunk = allChunks[nChunk]; - SMergeBuffersData& rMergeBufferData = arrMergeBuffersData[nChunk]; - SRenderMeshInfoInput* pRMI = renderChunk.pFromMesh; - Matrix34& rMatrix = pRMI->mat; - - bool bMatrixHasRotation; - if (!rMatrix.m01 && !rMatrix.m02 && !rMatrix.m10 && !rMatrix.m12 && !rMatrix.m20 && !rMatrix.m21) - { - bMatrixHasRotation = false; - } - else - { - bMatrixHasRotation = true; - } - - Vec3 vOffset = rMatrix.GetTranslation(); - - IRenderMesh* pRM = pRMI->pMesh; - - // get streams. - int nPosStride = rMergeBufferData.nPosStride; - int nTexStride = rMergeBufferData.nTexStride; - int nColorStride = rMergeBufferData.nColorStride; - int nTangsStride = rMergeBufferData.nTangsStride; - - uint8* pPos = rMergeBufferData.pPos; - uint8* pTex = rMergeBufferData.pTex; - uint8* pColor = rMergeBufferData.pColor; - uint8* pTangs = rMergeBufferData.pTangs; - -#if ENABLE_NORMALSTREAM_SUPPORT - int nNormStride = rMergeBufferData.nNormStride; - uint8* pNorm = rMergeBufferData.pNorm; -#endif - - if (!pPos || !pTex || !pColor || !pTangs) - { - assert(0); // Should not happen. - continue; - } - - Vec3 vMin, vMax; - pRM->GetBBox(vMin, vMax); - pBounds->Add(vMin); - pBounds->Add(vMax); - - // get indices - vtx_idx* pInds = rMergeBufferData.pSrcInds; - - Vec3 vOSPos(0, 0, 0); - Vec3 vOSProjDir(0, 0, 0); - - int nLastVertex = arrVertices.size(); - int nLastIndex = arrIndices.size(); - - ////////////////////////////////////////////////////////////////////////// - // add indices - ////////////////////////////////////////////////////////////////////////// - int nCurrIndex = nLastIndex; - arrIndices.resize(nLastIndex + renderChunk.rChunk.nNumIndices); - int nAdjustedVertexOffset = nLastVertex - renderChunk.rChunk.nFirstVertId; - int i = renderChunk.rChunk.nFirstIndexId; - int numInd = renderChunk.rChunk.nFirstIndexId + renderChunk.rChunk.nNumIndices; - - vtx_idx* __restrict pSrcInds = pInds; - vtx_idx* __restrict pDstInds = &arrIndices[0]; - - for (; i < numInd; i += 3, nCurrIndex += 3) - { - pDstInds[nCurrIndex + 0] = pSrcInds[i + 0] + nAdjustedVertexOffset; - pDstInds[nCurrIndex + 1] = pSrcInds[i + 1] + nAdjustedVertexOffset; - pDstInds[nCurrIndex + 2] = pSrcInds[i + 2] + nAdjustedVertexOffset; - } - - ////////////////////////////////////////////////////////////////////////// - renderChunk.rChunk.nFirstIndexId = nLastIndex; - - ////////////////////////////////////////////////////////////////////////// - // add vertices - ////////////////////////////////////////////////////////////////////////// - int nCurrVertex = nLastVertex; - arrVertices.resize(nLastVertex + renderChunk.rChunk.nNumVerts); - arrTangents.resize(nLastVertex + renderChunk.rChunk.nNumVerts); - -#if ENABLE_NORMALSTREAM_SUPPORT - arrNormals.resize(nLastVertex + renderChunk.rChunk.nNumVerts); -#endif - - int v = renderChunk.rChunk.nFirstVertId; - int numVert = renderChunk.rChunk.nFirstVertId + renderChunk.rChunk.nNumVerts; - if (bMatrixHasRotation) - { - SVF_P3S_C4B_T2S* __restrict pDstVerts = &arrVertices[0]; - SPipTangents* __restrict pDstTangs = &arrTangents[0]; -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal* __restrict pDstNorms = &arrNormals[0]; -#endif - - uint8* pSrcPos = pPos; - uint8* pSrcTex = pTex; - uint8* pSrcColor = pColor; - uint8* pSrcTangs = pTangs; -#if ENABLE_NORMALSTREAM_SUPPORT - uint8* pSrcNorm = pNorm; -#endif - for (; v < numVert; v++, nCurrVertex++) - { - SVF_P3S_C4B_T2S& vert = pDstVerts[nCurrVertex]; - SPipTangents& basis = pDstTangs[nCurrVertex]; -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal& normal = pDstNorms[nCurrVertex]; -#endif - // set pos/uv - Vec3& vPos = (*(Vec3*)&pSrcPos[nPosStride * v]); - Vec2* pUV = (Vec2*)&pSrcTex[nTexStride * v]; - - vert.xyz = rMatrix.TransformPoint(vPos); - vert.st = *pUV; - vert.color.dcolor = *(uint32*)&pSrcColor[nColorStride * v + 0]; - - // get tangent basis - basis = *(SPipTangents*)&pSrcTangs[nTangsStride * v]; - -#if ENABLE_NORMALSTREAM_SUPPORT - normal = SPipNormal(Vec3(0, 0, 0)); - if (pSrcNorm) - { - normal = *(SPipNormal*)&pSrcNorm[nNormStride * v]; - } -#endif - - if (bMatrixHasRotation) - { - basis.TransformSafelyBy(rMatrix); -#if ENABLE_NORMALSTREAM_SUPPORT - if (pSrcNorm) - { - normal.TransformSafelyBy(rMatrix); - } -#endif - } - } - } - else - { - SVF_P3S_C4B_T2S* __restrict pDstVerts = &arrVertices[0]; - SPipTangents* __restrict pDstTangs = &arrTangents[0]; -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal* __restrict pDstNorms = &arrNormals[0]; -#endif - - uint8* pSrcPos = pPos; - uint8* pSrcTex = pTex; - uint8* pSrcColor = pColor; - uint8* pSrcTangs = pTangs; -#if ENABLE_NORMALSTREAM_SUPPORT - uint8* pSrcNorm = pNorm; -#endif - for (; v < numVert; v++, nCurrVertex++) - { - SVF_P3S_C4B_T2S& vert = pDstVerts[nCurrVertex]; - SPipTangents& basis = pDstTangs[nCurrVertex]; - -#if ENABLE_NORMALSTREAM_SUPPORT - SPipNormal& normal = pDstNorms[nCurrVertex]; -#endif - - // set pos/uv - Vec3& vPos = (*(Vec3*)&pSrcPos[nPosStride * v]); - Vec2* pUV = (Vec2*)&pSrcTex[nTexStride * v]; - - vert.xyz = rMatrix.TransformPoint(vPos); - vert.st = *pUV; - vert.color.dcolor = *(uint32*)&pSrcColor[nColorStride * v]; - - // get tangent basis - basis = *(SPipTangents*)&pSrcTangs[nTangsStride * v]; - -#if ENABLE_NORMALSTREAM_SUPPORT - normal = SPipNormal(Vec3(0, 0, 0)); - if (pSrcNorm) - { - normal = *(SPipNormal*)(&pSrcNorm[nNormStride * v]); - } -#endif - } - } - - // set vert range - renderChunk.rChunk.nFirstVertId = nLastVertex; - - m_nTotalVertexCount += renderChunk.rChunk.nNumVerts; - m_nTotalIndexCount += renderChunk.rChunk.nNumIndices; - - renderChunk.rChunk.m_vertexFormat = eVF_P3S_C4B_T2S; - } -} - -void CRenderMeshMerger::Reset() -{ - stl::free_container(m_lstRMIChunks); - stl::free_container(m_lstVerts); - stl::free_container(m_lstTangBasises); - stl::free_container(m_lstIndices); - stl::free_container(m_lstChunks); - stl::free_container(m_lstChunksAll); - stl::free_container(m_lstNewVerts); - stl::free_container(m_lstNewTangBasises); - stl::free_container(m_lstNewIndices); - stl::free_container(m_lstNewChunks); - stl::free_container(m_lstChunksMergedTemp); - stl::free_container(m_tmpRenderChunkArray); - stl::free_container(m_lstMergeBuffersData); - -#if ENABLE_NORMALSTREAM_SUPPORT - stl::free_container(m_lstNormals); - stl::free_container(m_lstNewNormals); -#endif - - m_tmpClipContext.Reset(); -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CRenderMeshMerger::MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info) -{ - m_nTotalVertexCount = 0; - m_nTotalIndexCount = 0; - - m_lstRMIChunks.clear(); - m_lstVerts.clear(); - m_lstTangBasises.clear(); -#if ENABLE_NORMALSTREAM_SUPPORT - m_lstNormals.clear(); -#endif - m_lstIndices.clear(); - m_lstNewIndices.clear(); - m_lstChunks.clear(); - - // make list of all chunks - if (!GenerateRenderChunks(pRMIArray, nRMICount)) - { - return 0; - } - - MergeRenderChunks(); - - if (m_lstChunksAll.empty()) - { - return NULL; - } - - // Often even single mesh must be merged, when non identity matrix is provided - /* - if (m_lstChunks.size() == m_lstChunksAll.size()) - { - // No reduction of render chunks. - return 0; - } - */ - - AABB finalBounds; - finalBounds.Reset(); - MergeBuffers(finalBounds); - - if (m_lstNewIndices.empty() || m_lstVerts.empty() || m_lstTangBasises.empty()) - { - return 0; - } - - // Repeat merging to properly update vertex ranges. - MergeRenderChunks(); - - IRenderMesh::SInitParamerers params; - params.pVertBuffer = &m_lstVerts.front(); - params.nVertexCount = m_lstVerts.size(); - params.vertexFormat = eVF_P3S_C4B_T2S; - params.pIndices = &m_lstNewIndices.front(); - params.nIndexCount = m_lstNewIndices.size(); - params.pTangents = &m_lstTangBasises.front(); -#if ENABLE_NORMALSTREAM_SUPPORT - params.pNormals = &m_lstNormals.front(); -#endif - params.nPrimetiveType = prtTriangleList; - params.eType = eRMT_Static; - params.nRenderChunkCount = 0; - params.bOnlyVideoBuffer = false; - params.bPrecache = false; - params.bLockForThreadAccess = true;//calls LockForThreadAccess in the Rendermesh ctor - - _smart_ptr pRenderMesh = GetRenderer()->CreateRenderMesh(info.sMeshType, info.sMeshName, ¶ms); - pRenderMesh->SetBBox(finalBounds.min, finalBounds.max); - - ////////////////////////////////////////////////////////////////////////// - // Setup merged chunks - ////////////////////////////////////////////////////////////////////////// - m_tmpRenderChunkArray.resize(m_lstChunks.size()); - for (size_t i = 0, num = m_lstChunks.size(); i < num; i++) - { - m_tmpRenderChunkArray[i] = m_lstChunks[i].rChunk; - } - pRenderMesh->SetRenderChunks(&m_tmpRenderChunkArray.front(), m_tmpRenderChunkArray.size(), false); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Setup un-merged chunks - ////////////////////////////////////////////////////////////////////////// - m_tmpRenderChunkArray.resize(m_lstChunksAll.size()); - for (size_t i = 0, num = m_lstChunksAll.size(); i < num; i++) - { - m_tmpRenderChunkArray[i] = m_lstChunksAll[i].rChunk; - } - pRenderMesh->SetRenderChunks(&m_tmpRenderChunkArray.front(), m_tmpRenderChunkArray.size(), true); - ////////////////////////////////////////////////////////////////////////// - - pRenderMesh->UnLockForThreadAccess(); - - return pRenderMesh; -} diff --git a/Code/CryEngine/Cry3DEngine/RenderMeshMerger.h b/Code/CryEngine/Cry3DEngine/RenderMeshMerger.h deleted file mode 100644 index 23df1750ad..0000000000 --- a/Code/CryEngine/Cry3DEngine/RenderMeshMerger.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H -#define CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H -#pragma once - -////////////////////////////////////////////////////////////////////////// -// Input structure for RenderMesh merger -////////////////////////////////////////////////////////////////////////// -struct SRenderMeshInfoInput -{ - _smart_ptr pMesh; - _smart_ptr pMat; - IRenderNode* pSrcRndNode; - Matrix34 mat; - int nSubObjectIndex; - int nChunkId; - bool bIdentityMatrix; - - SRenderMeshInfoInput() - : pMesh(0) - , pMat(0) - , nChunkId(-1) - , nSubObjectIndex(0) - , pSrcRndNode(0) - , bIdentityMatrix(false) { mat.SetIdentity(); } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - -struct SDecalClipInfo -{ - Vec3 vPos; - float fRadius; - Vec3 vProjDir; -}; - -struct SMergeInfo -{ - const char* sMeshType; - const char* sMeshName; - bool bCompactVertBuffer; - bool bPrintDebugMessages; - bool bMakeNewMaterial; - bool bMergeToOneRenderMesh; - bool bPlaceInstancePositionIntoVertexNormal; - _smart_ptr pUseMaterial; // Force to use this material - - SDecalClipInfo* pDecalClipInfo; - AABB* pClipCellBox; - Vec3 vResultOffset; // this offset will be subtracted from output vertex positions - - SMergeInfo() - : sMeshType("") - , sMeshName("") - , bCompactVertBuffer(false) - , bPrintDebugMessages(false) - , bMakeNewMaterial(true) - , bMergeToOneRenderMesh(false) - , bPlaceInstancePositionIntoVertexNormal(0) - , pUseMaterial(0) - , pDecalClipInfo(0) - , pClipCellBox(0) - , vResultOffset(0, 0, 0) {} -}; - -struct SMergedChunk -{ - CRenderChunk rChunk; - _smart_ptr pMaterial; - SRenderMeshInfoInput* pFromMesh; - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - -struct SMergeBuffersData -{ - int nPosStride; - int nTexStride; - int nColorStride; - int nTangsStride; - int nIndCount; - uint8* pPos; - uint8* pTex; - uint8* pColor; - uint8* pTangs; - vtx_idx* pSrcInds; -#if ENABLE_NORMALSTREAM_SUPPORT - int nNormStride; - uint8* pNorm; -#endif -}; - -class CRenderMeshMerger - : public Cry3DEngineBase -{ -public: - CRenderMeshMerger(void); - ~CRenderMeshMerger(void); - - void Reset(); - - _smart_ptr MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, PodArray& outRenderMeshes, SMergeInfo& info); - - _smart_ptr MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info); -public: - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - - pSizer->AddObject(m_lstRMIChunks); - pSizer->AddObject(m_lstVerts); - pSizer->AddObject(m_lstTangBasises); - pSizer->AddObject(m_lstIndices); - - pSizer->AddObject(m_lstChunks); - pSizer->AddObject(m_lstChunksAll); - - pSizer->AddObject(m_lstNewVerts); - pSizer->AddObject(m_lstNewTangBasises); - pSizer->AddObject(m_lstNewIndices); - pSizer->AddObject(m_lstNewChunks); - - pSizer->AddObject(m_lstChunksMergedTemp); - - pSizer->AddObject(m_tmpRenderChunkArray); - pSizer->AddObject(m_tmpClipContext); - } - - void MergeBuffersImpl(AABB* pBounds, SMergeBuffersData* arrMergeBuffersData); - -protected: - PodArray m_lstRMIChunks; - PodArray m_lstVerts; - PodArray m_lstTangBasises; - PodArray m_lstIndices; - - PodArray m_lstChunks; - PodArray m_lstChunksAll; - - PodArray m_lstNewVerts; - PodArray m_lstNewTangBasises; - PodArray m_lstNewIndices; - PodArray m_lstNewChunks; - -#if ENABLE_NORMALSTREAM_SUPPORT - PodArray m_lstNormals; - PodArray m_lstNewNormals; -#endif - - PodArray m_lstChunksMergedTemp; - - TRenderChunkArray m_tmpRenderChunkArray; - - PodArray m_lstMergeBuffersData; - AABB m_tmpAABB; - - CPolygonClipContext m_tmpClipContext; - - int m_nTotalVertexCount; - int m_nTotalIndexCount; - -private: - bool GenerateRenderChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount); - void MergeRenderChunks(); - void MergeBuffers(AABB& bounds); - - void MakeRenderMeshInfoListOfAllChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info); - void MakeListOfAllCRenderChunks(SMergeInfo& info); - void IsChunkValid(const CRenderChunk& Ch, PodArray& lstVerts, PodArray& lstIndices); - - void ClipByAABB(SMergeInfo& info); - void ClipDecals(SMergeInfo& info); - void CompactVertices(SMergeInfo& info); - void TryMergingChunks(SMergeInfo& info); - - bool ClipTriangle(int nStartIdxId, Plane* pPlanes, int nPlanesNum); - - static int Cmp_Materials(_smart_ptr pMat1, _smart_ptr pMat2); - static int Cmp_RenderChunks_(const void* v1, const void* v2); - static int Cmp_RenderChunksInfo(const void* v1, const void* v2); -}; - -#endif // CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H diff --git a/Code/CryEngine/Cry3DEngine/RenderMeshUtils.cpp b/Code/CryEngine/Cry3DEngine/RenderMeshUtils.cpp deleted file mode 100644 index 18acd0b7bd..0000000000 --- a/Code/CryEngine/Cry3DEngine/RenderMeshUtils.cpp +++ /dev/null @@ -1,904 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "RenderMeshUtils.h" - -namespace -{ - enum - { - MAX_CACHED_HITS = 8 - }; - struct SCachedHit - { - IRenderMesh* pRenderMesh; - SRayHitInfo hitInfo; - Vec3 tri[3]; - }; - static SCachedHit last_hits[MAX_CACHED_HITS]; -} - - -bool SIntersectionData::Init(IRenderMesh* param_pRenderMesh, SRayHitInfo* param_pHitInfo, _smart_ptr param_pMtl, bool param_bRequestDecalPlacementTest) -{ - pRenderMesh = param_pRenderMesh; - pHitInfo = param_pHitInfo; - pMtl = param_pMtl; - bDecalPlacementTestRequested = param_bRequestDecalPlacementTest; - - bool bAllDMeshData = pHitInfo->bGetVertColorAndTC; - - nVerts = pRenderMesh->GetVerticesCount(); - nInds = pRenderMesh->GetIndicesCount(); - - if (nInds == 0 || nVerts == 0) - { - return false; - } - pPos = (uint8*)pRenderMesh->GetPosPtr(nPosStride, FSL_READ); - pInds = pRenderMesh->GetIndexPtr(FSL_READ); - -#if defined (_DEBUG) - // Perform a quick validation of the vectors from this render mesh - for (int index = 0;index < nVerts; index++) - { - Vec3& check = *((Vec3*)&pPos[nPosStride * index]); - if (isnan(check.x) || isnan(check.y) || isnan(check.z)) - { - CryLog("Warning: Invalid vector at index (%d) detected in render mesh for %s.", nPosStride * index, pRenderMesh->GetSourceName()); - break; - } - } -#endif - - if (!pPos || !pInds) - { - return false; - } - - if (bAllDMeshData) - { - pUV = (uint8*)pRenderMesh->GetUVPtr(nUVStride, FSL_READ); - pCol = (uint8*)pRenderMesh->GetColorPtr(nColStride, FSL_READ); - - pTangs = pRenderMesh->GetTangentPtr(nTangsStride, FSL_READ); - } - - return true; -} - -template -bool GetBarycentricCoordinates(const T& a, const T& b, const T& c, const T& p, float& u, float& v, float& w, float fBorder /* = 0.f */) -{ - // Compute vectors - T v0 = b - a; - T v1 = c - a; - T v2 = p - a; - - // Compute dot products - float dot00 = v0.Dot(v0); - float dot01 = v0.Dot(v1); - float dot02 = v0.Dot(v2); - float dot11 = v1.Dot(v1); - float dot12 = v1.Dot(v2); - - // Compute barycentric coordinates - float invDenom = 1.f / (dot00 * dot11 - dot01 * dot01); - v = (dot11 * dot02 - dot01 * dot12) * invDenom; - w = (dot00 * dot12 - dot01 * dot02) * invDenom; - u = 1.f - v - w; - - // Check if point is in triangle - return (u >= -fBorder) && (v >= -fBorder) && (w >= -fBorder); -} - -void CRenderMeshUtils::ClearHitCache() -{ - // do not allow items to stay too long in the cache, it allows to minimize wrong hit detections - memmove(&last_hits[1], &last_hits[0], sizeof(last_hits) - sizeof(last_hits[0])); // Move hits to the end of array, throwing out the last one. - memset(&last_hits[0], 0, sizeof(last_hits[0])); -} -////////////////////////////////////////////////////////////////////////// -bool CRenderMeshUtils::RayIntersection(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pMtl) -{ - SIntersectionData data; - - pRenderMesh->LockForThreadAccess(); - if (!data.Init(pRenderMesh, &hitInfo, pMtl)) - { - return false; - } - - // forward call to implementation - bool result = CRenderMeshUtils::RayIntersectionImpl(&data, &hitInfo, pMtl, false); - - pRenderMesh->UnlockStream(VSF_GENERAL); - pRenderMesh->UnlockIndexStream(); - pRenderMesh->UnLockForThreadAccess(); - return result; -} - -void CRenderMeshUtils::RayIntersectionAsync(SIntersectionData* pIntersectionRMData) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ThreeDEngine); - - // forward call to implementation - SRayHitInfo& rHitInfo = *pIntersectionRMData->pHitInfo; - SIntersectionData& rIntersectionData = *pIntersectionRMData; - - if (CRenderMeshUtils::RayIntersectionImpl(&rIntersectionData, &rHitInfo, rIntersectionData.pMtl, true)) - { - const float testAreaSize = GetFloatCVar(e_DecalsPlacementTestAreaSize); - const float minTestDepth = GetFloatCVar(e_DecalsPlacementTestMinDepth); - - if (rIntersectionData.bDecalPlacementTestRequested && testAreaSize) - { - rIntersectionData.fDecalPlacementTestMaxSize = 0.f; - float fRange = testAreaSize * 0.5f; - - for (uint32 i = 0; i < 2; ++i, fRange *= 2.f) - { - Vec3 vDir = -rHitInfo.vHitNormal; - vDir.Normalize(); - - Vec3 vRight; - Vec3 vUp; - - if (fabs(vDir.Dot(Vec3(0, 0, 1))) > 0.995f) - { - vRight = Vec3(1, 0, 0); - vUp = Vec3(0, 1, 0); - } - else - { - vRight = vDir.Cross(Vec3(0, 0, 1)); - vUp = vRight.Cross(vDir); - } - - Vec3 arrOffset[4] = { vRight* fRange, -vRight * fRange, vUp * fRange, -vUp * fRange }; - - SRayHitInfo hInfo; - SIntersectionData intersectionData; - - float fDepth = max(minTestDepth, fRange * 0.2f); - - int nPoint; - for (nPoint = 0; nPoint < 4; nPoint++) - { - intersectionData = rIntersectionData; - - hInfo = rHitInfo; - hInfo.inReferencePoint = hInfo.vHitPos + arrOffset[nPoint];//*fRange; - hInfo.inRay.origin = hInfo.inReferencePoint + hInfo.vHitNormal * fDepth; - hInfo.inRay.direction = -hInfo.vHitNormal * fDepth * 2.f; - hInfo.fMaxHitDistance = fDepth; - if (!CRenderMeshUtils::RayIntersectionImpl(&intersectionData, &hInfo, rIntersectionData.pMtl, true)) - { - break; - } - } - - if (nPoint == 4) - { - rIntersectionData.fDecalPlacementTestMaxSize = fRange; - } - else - { - break; - } - } - } - } -} - -bool GetVertColorAndTC(SIntersectionData& rIntersectionRMData, SRayHitInfo& hitInfo) -{ - int nPosStride = rIntersectionRMData.nPosStride; - uint8* pPos = rIntersectionRMData.pPos; - - int nUVStride = rIntersectionRMData.nUVStride; - uint8* pUV = rIntersectionRMData.pUV; - - int nColStride = rIntersectionRMData.nColStride; - uint8* pCol = rIntersectionRMData.pCol; - - vtx_idx* pInds = rIntersectionRMData.pInds; - - int I0 = pInds[hitInfo.nHitTriID + 0]; - int I1 = pInds[hitInfo.nHitTriID + 1]; - int I2 = pInds[hitInfo.nHitTriID + 2]; - - // get tri vertices - Vec3& tv0 = *((Vec3*)&pPos[nPosStride * I0]); - Vec3& tv1 = *((Vec3*)&pPos[nPosStride * I1]); - Vec3& tv2 = *((Vec3*)&pPos[nPosStride * I2]); - - float u = 0.f, v = 0.f, w = 0.f; - if (GetBarycentricCoordinates(tv0, tv1, tv2, hitInfo.vHitPos, u, v, w, 16.0f)) - { - float arrVertWeight[3] = { max(0.f, u), max(0.f, v), max(0.f, w) }; - float fDiv = 1.f / (arrVertWeight[0] + arrVertWeight[1] + arrVertWeight[2]); - arrVertWeight[0] *= fDiv; - arrVertWeight[1] *= fDiv; - arrVertWeight[2] *= fDiv; - - Vec2 tc0 = *((Vec2*)&pUV[nUVStride * I0]); - Vec2 tc1 = *((Vec2*)&pUV[nUVStride * I1]); - Vec2 tc2 = *((Vec2*)&pUV[nUVStride * I2]); - - hitInfo.vHitTC = tc0 * arrVertWeight[0] + tc1 * arrVertWeight[1] + tc2 * arrVertWeight[2]; - - Vec4 c0 = (*(ColorB*)&pCol[nColStride * I0]).toVec4(); - Vec4 c1 = (*(ColorB*)&pCol[nColStride * I1]).toVec4(); - Vec4 c2 = (*(ColorB*)&pCol[nColStride * I2]).toVec4(); - - // get tangent basis - int nTangsStride = rIntersectionRMData.nTangsStride; - byte* pTangs = rIntersectionRMData.pTangs; - - Vec4 tangent[3]; - Vec4 bitangent[3]; - int arrId[3] = { I0, I1, I2 }; - for (int ii = 0; ii < 3; ii++) - { - SPipTangents tb = *(SPipTangents*)&pTangs[nTangsStride * arrId[ii]]; - - tb.GetTB(tangent[ii], bitangent[ii]); - } - - hitInfo.vHitTangent = (tangent[0] * arrVertWeight[0] + tangent[1] * arrVertWeight[1] + tangent[2] * arrVertWeight[2]); - hitInfo.vHitBitangent = (bitangent[0] * arrVertWeight[0] + bitangent[1] * arrVertWeight[1] + bitangent[2] * arrVertWeight[2]); - hitInfo.vHitColor = (c0 * arrVertWeight[0] + c1 * arrVertWeight[1] + c2 * arrVertWeight[2]) / 255.f; - return true; - } - return false; -} - -bool CRenderMeshUtils::RayIntersectionImpl(SIntersectionData* pIntersectionRMData, SRayHitInfo* phitInfo, _smart_ptr pMtl, bool bAsync) -{ -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - IF (phitInfo->bGetVertColorAndTC, 0) -#else - IF (phitInfo->bGetVertColorAndTC && phitInfo->inRay.direction.IsZero(), 0) -#endif - { - return RayIntersectionFastImpl(*pIntersectionRMData, *phitInfo, pMtl, bAsync); - } - - SIntersectionData& rIntersectionRMData = *pIntersectionRMData; - SRayHitInfo& hitInfo = *phitInfo; - - FUNCTION_PROFILER_3DENGINE; - - //CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); - - float fMaxDist2 = hitInfo.fMaxHitDistance * hitInfo.fMaxHitDistance; - - Vec3 vHitPos(0, 0, 0); - Vec3 vHitNormal(0, 0, 0); - - static bool bClearHitCache = true; - if (bClearHitCache && !bAsync) - { - memset(last_hits, 0, sizeof(last_hits)); - bClearHitCache = false; - } - - if (hitInfo.bUseCache && !bAsync) - { - Vec3 vOut; - // Check for cached hits. - for (int i = 0; i < MAX_CACHED_HITS; i++) - { - if (last_hits[i].pRenderMesh == rIntersectionRMData.pRenderMesh) - { - // If testing same render mesh, check if we hit the same triangle again. - if (Intersect::Ray_Triangle(hitInfo.inRay, last_hits[i].tri[0], last_hits[i].tri[2], last_hits[i].tri[1], vOut)) - { - if (fMaxDist2) - { - float fDistance2 = hitInfo.inReferencePoint.GetSquaredDistance(vOut); - if (fDistance2 > fMaxDist2) - { - continue; // Ignore hits that are too far. - } - } - - // Cached hit. - hitInfo.vHitPos = vOut; - hitInfo.vHitNormal = last_hits[i].hitInfo.vHitNormal; - hitInfo.nHitMatID = last_hits[i].hitInfo.nHitMatID; - hitInfo.nHitSurfaceID = last_hits[i].hitInfo.nHitSurfaceID; - - if (hitInfo.inRetTriangle) - { - hitInfo.vTri0 = last_hits[i].tri[0]; - hitInfo.vTri1 = last_hits[i].tri[1]; - hitInfo.vTri2 = last_hits[i].tri[2]; - } - //CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - //CryLogAlways( "TestTime :%.2f", (t1-t0).GetMilliSeconds() ); - //static int nCount = 0; CryLogAlways( "Cached Hit %d",++nCount ); - hitInfo.pRenderMesh = rIntersectionRMData.pRenderMesh; - rIntersectionRMData.bResult = true; - return true; - } - } - } - } - - uint nVerts = rIntersectionRMData.nVerts; - int nInds = rIntersectionRMData.nInds; - - assert(nInds != 0 && nVerts != 0); - - // get position offset and stride - const int nPosStride = rIntersectionRMData.nPosStride; - uint8* const pPos = rIntersectionRMData.pPos; - - // get indices - vtx_idx* const pInds = rIntersectionRMData.pInds; - - assert(pInds != NULL && pPos != NULL); - assert(nInds % 3 == 0); - - float fMinDistance2 = FLT_MAX; - - Ray inRay = hitInfo.inRay; - - bool bAnyHit = false; - - Vec3 vOut; - Vec3 tri[3]; - - // test tris - TRenderChunkArray& RESTRICT_REFERENCE Chunks = rIntersectionRMData.pRenderMesh->GetChunks(); - int nChunkCount = Chunks.size(); - - for (int nChunkId = 0; nChunkId < nChunkCount; nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - - IF (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE, 0) - { - continue; - } - const int16 nChunkMatID = pChunk->m_nMatID; - - bool b2Sided = false; - - if (pMtl) - { - const SShaderItem& shaderItem = pMtl->GetShaderItem(nChunkMatID); - if (hitInfo.bOnlyZWrite && !shaderItem.IsZWrite()) - { - continue; - } - if (!shaderItem.m_pShader || shaderItem.m_pShader->GetFlags() & EF_NODRAW || shaderItem.m_pShader->GetFlags() & EF_DECAL) - { - continue; - } - if (shaderItem.m_pShader->GetCull() & eCULL_None) - { - b2Sided = true; - } - if (shaderItem.m_pShaderResources && shaderItem.m_pShaderResources->GetResFlags() & MTL_FLAG_2SIDED) - { - b2Sided = true; - } - } - - int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices; - const vtx_idx* __restrict pIndices = rIntersectionRMData.pInds; - - IF (nLastIndexId - 1 >= nInds, 0) - { - Error("%s (%s): invalid mesh chunk", __FUNCTION__, rIntersectionRMData.pRenderMesh->GetSourceName()); - rIntersectionRMData.bResult = false; - return 0; - } - - // make line triangle intersection - int i = pChunk->nFirstIndexId; - - while (i < nLastIndexId) - { - int p = nLastIndexId; - - for (; i < p; i += 3)//process all prefetched vertices - { - IF (pInds[i + 2] >= nVerts, 0) - { - Error("%s (%s): invalid mesh indices", __FUNCTION__, rIntersectionRMData.pRenderMesh->GetSourceName()); - rIntersectionRMData.bResult = false; - return 0; - } - - // get tri vertices - const Vec3& tv0 = *(const Vec3*)&pPos[ nPosStride * pIndices[i + 0] ]; - const Vec3& tv1 = *(const Vec3*)&pPos[ nPosStride * pIndices[i + 1] ]; - const Vec3& tv2 = *(const Vec3*)&pPos[ nPosStride * pIndices[i + 2] ]; - - if (Intersect::Ray_Triangle(inRay, tv0, tv2, tv1, vOut)) - { - float fDistance2 = hitInfo.inReferencePoint.GetSquaredDistance(vOut); - if (fMaxDist2) - { - if (fDistance2 > fMaxDist2) - { - continue; // Ignore hits that are too far. - } - } - bAnyHit = true; - // Test front. - if (hitInfo.bInFirstHit) - { - vHitPos = vOut; - hitInfo.nHitMatID = nChunkMatID; - hitInfo.nHitTriID = i; - tri[0] = tv0; - tri[1] = tv1; - tri[2] = tv2; - goto AnyHit;//need to break chunk loops, vertex loop and prefetched loop - } - if (fDistance2 < fMinDistance2) - { - fMinDistance2 = fDistance2; - vHitPos = vOut; - hitInfo.nHitMatID = nChunkMatID; - hitInfo.nHitTriID = i; - tri[0] = tv0; - tri[1] = tv1; - tri[2] = tv2; - } - } - else - if (b2Sided) - { - if (Intersect::Ray_Triangle(inRay, tv0, tv1, tv2, vOut)) - { - float fDistance2 = hitInfo.inReferencePoint.GetSquaredDistance(vOut); - if (fMaxDist2) - { - if (fDistance2 > fMaxDist2) - { - continue; // Ignore hits that are too far. - } - } - - bAnyHit = true; - // Test back. - if (hitInfo.bInFirstHit) - { - vHitPos = vOut; - hitInfo.nHitMatID = nChunkMatID; - hitInfo.nHitTriID = i; - tri[0] = tv0; - tri[1] = tv2; - tri[2] = tv1; - goto AnyHit;//need to break chunk loops, vertex loop and prefetched loop - } - if (fDistance2 < fMinDistance2) - { - fMinDistance2 = fDistance2; - vHitPos = vOut; - hitInfo.nHitMatID = nChunkMatID; - hitInfo.nHitTriID = i; - tri[0] = tv0; - tri[1] = tv2; - tri[2] = tv1; - } - } - } - } - } - } -AnyHit: - if (bAnyHit) - { - hitInfo.pRenderMesh = rIntersectionRMData.pRenderMesh; - - // return closest to the shooter - hitInfo.fDistance = (float)sqrt_tpl(fMinDistance2); - hitInfo.vHitNormal = (tri[1] - tri[0]).Cross(tri[2] - tri[0]).GetNormalized(); - hitInfo.vHitPos = vHitPos; - hitInfo.nHitSurfaceID = 0; - - if (hitInfo.inRetTriangle) - { - hitInfo.vTri0 = tri[0]; - hitInfo.vTri1 = tri[1]; - hitInfo.vTri2 = tri[2]; - } - -#ifndef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - if (hitInfo.bGetVertColorAndTC && hitInfo.nHitTriID >= 0 && !inRay.direction.IsZero()) - { - GetVertColorAndTC(rIntersectionRMData, hitInfo); - } -#endif - - if (pMtl) - { - pMtl = pMtl->GetSafeSubMtl(hitInfo.nHitMatID); - if (pMtl) - { - hitInfo.nHitSurfaceID = pMtl->GetSurfaceTypeId(); - } - } - - if (!bAsync) - { - ////////////////////////////////////////////////////////////////////////// - // Add to cached results. - memmove(&last_hits[1], &last_hits[0], sizeof(last_hits) - sizeof(last_hits[0])); // Move hits to the end of array, throwing out the last one. - last_hits[0].pRenderMesh = rIntersectionRMData.pRenderMesh; - last_hits[0].hitInfo = hitInfo; - memcpy(last_hits[0].tri, tri, sizeof(tri)); - ////////////////////////////////////////////////////////////////////////// - } - } - //CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - //CryLogAlways( "TestTime :%.2f", (t1-t0).GetMilliSeconds() ); - - rIntersectionRMData.bResult = bAnyHit; - return bAnyHit; -} - -bool CRenderMeshUtils::RayIntersectionFast(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pMtl) -{ - SIntersectionData data; - - if (!data.Init(pRenderMesh, &hitInfo, pMtl)) - { - return false; - } - - // forward call to implementation - return CRenderMeshUtils::RayIntersectionFastImpl(data, hitInfo, pMtl, false); -} - -////////////////////////////////////////////////////////////////////////// -bool CRenderMeshUtils::RayIntersectionFastImpl(SIntersectionData& rIntersectionRMData, SRayHitInfo& hitInfo, _smart_ptr pMtl, [[maybe_unused]] bool bAsync) -{ - float fBestDist = hitInfo.fMaxHitDistance; // squared distance works different for values less and more than 1.f - - Vec3 vHitPos(0, 0, 0); - Vec3 vHitNormal(0, 0, 0); - - int nVerts = rIntersectionRMData.nVerts; - int nInds = rIntersectionRMData.nInds; - - assert(nInds != 0 && nVerts != 0); - - // get position offset and stride - int nPosStride = rIntersectionRMData.nPosStride; - uint8* pPos = rIntersectionRMData.pPos; - - int nUVStride = rIntersectionRMData.nUVStride; - uint8* pUV = rIntersectionRMData.pUV; - - int nColStride = rIntersectionRMData.nColStride; - uint8* pCol = rIntersectionRMData.pCol; - - // get indices - vtx_idx* pInds = rIntersectionRMData.pInds; - - assert(pInds != NULL && pPos != NULL); - - assert(nInds % 3 == 0); - - Ray inRay = hitInfo.inRay; - - bool bAnyHit = false; - - Vec3 vOut; - Vec3 tri[3]; - - // test tris - - Line inLine(inRay.origin, inRay.direction); - - if (!inRay.direction.IsZero() && hitInfo.nHitTriID >= 0) - { - if (hitInfo.nHitTriID + 2 >= nInds) - { - return false; - } - - int I0 = pInds[hitInfo.nHitTriID + 0]; - int I1 = pInds[hitInfo.nHitTriID + 1]; - int I2 = pInds[hitInfo.nHitTriID + 2]; - - if (I0 < nVerts && I1 < nVerts && I2 < nVerts) - { - // get tri vertices - Vec3& tv0 = *((Vec3*)&pPos[nPosStride * I0]); - Vec3& tv1 = *((Vec3*)&pPos[nPosStride * I1]); - Vec3& tv2 = *((Vec3*)&pPos[nPosStride * I2]); - - if (Intersect::Line_Triangle(inLine, tv0, tv2, tv1, vOut))// || Intersect::Line_Triangle( inLine, tv0, tv1, tv2, vOut )) - { - float fDistance = (hitInfo.inReferencePoint - vOut).GetLengthFast(); - - if (fBestDist == 0.f || fDistance < fBestDist) - { - bAnyHit = true; - fBestDist = fDistance; - vHitPos = vOut; - tri[0] = tv0; - tri[1] = tv1; - tri[2] = tv2; - } - } - } - } - - if (hitInfo.nHitTriID == HIT_UNKNOWN) - { - if (inRay.direction.IsZero()) - { - ProcessBoxIntersection(inRay, hitInfo, rIntersectionRMData, pMtl, pInds, nVerts, pPos, nPosStride, pUV, nUVStride, pCol, nColStride, nInds, bAnyHit, fBestDist, vHitPos, tri); - } - else - { - if (const PodArray >* pTris = rIntersectionRMData.pRenderMesh->GetTrisForPosition(inRay.origin + inRay.direction * 0.5f, pMtl)) - { - for (int nId = 0; nId < pTris->Count(); ++nId) - { - const std::pair& t = pTris->GetAt(nId); - - if (t.first + 2 >= nInds) - { - return false; - } - - int I0 = pInds[t.first + 0]; - int I1 = pInds[t.first + 1]; - int I2 = pInds[t.first + 2]; - - if (I0 >= nVerts || I1 >= nVerts || I2 >= nVerts) - { - return false; - } - - // get tri vertices - Vec3& tv0 = *((Vec3*)&pPos[nPosStride * I0]); - Vec3& tv1 = *((Vec3*)&pPos[nPosStride * I1]); - Vec3& tv2 = *((Vec3*)&pPos[nPosStride * I2]); - - if (Intersect::Line_Triangle(inLine, tv0, tv2, tv1, vOut)) // || Intersect::Line_Triangle( inLine, tv0, tv1, tv2, vOut )) - { - float fDistance = (hitInfo.inReferencePoint - vOut).GetLengthFast(); - - if (fDistance < fBestDist) - { - bAnyHit = true; - fBestDist = fDistance; - vHitPos = vOut; - tri[0] = tv0; - tri[1] = tv1; - tri[2] = tv2; - hitInfo.nHitMatID = t.second; - hitInfo.nHitTriID = t.first; - } - } - } - } - } - } - - if (bAnyHit) - { - hitInfo.pRenderMesh = rIntersectionRMData.pRenderMesh; - - // return closest to the shooter - hitInfo.fDistance = fBestDist; - hitInfo.vHitNormal = (tri[1] - tri[0]).Cross(tri[2] - tri[0]).GetNormalized(); - hitInfo.vHitPos = vHitPos; - hitInfo.nHitSurfaceID = 0; - - if (pMtl) - { - pMtl = pMtl->GetSafeSubMtl(hitInfo.nHitMatID); - if (pMtl) - { - hitInfo.nHitSurfaceID = pMtl->GetSurfaceTypeId(); - } - } - - if (hitInfo.bGetVertColorAndTC && hitInfo.nHitTriID >= 0 && !inRay.direction.IsZero()) - { - GetVertColorAndTC(rIntersectionRMData, hitInfo); - } - } - - //CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - //CryLogAlways( "TestTime :%.2f", (t1-t0).GetMilliSeconds() ); - - return bAnyHit; -} - -// used for CPU voxelization -bool CRenderMeshUtils::ProcessBoxIntersection(Ray& inRay, SRayHitInfo& hitInfo, SIntersectionData& rIntersectionRMData, _smart_ptr pMtl, vtx_idx* pInds, int nVerts, uint8* pPos, int nPosStride, uint8* pUV, int nUVStride, uint8* pCol, int nColStride, int nInds, bool& bAnyHit, float& fBestDist, Vec3& vHitPos, Vec3* tri) -{ - AABB voxBox; - voxBox.min = inRay.origin - Vec3(hitInfo.fMaxHitDistance); - voxBox.max = inRay.origin + Vec3(hitInfo.fMaxHitDistance); - - if (hitInfo.pHitTris) - { // just collect tris - TRenderChunkArray& Chunks = rIntersectionRMData.pRenderMesh->GetChunks(); - int nChunkCount = Chunks.size(); - - for (int nChunkId = 0; nChunkId < nChunkCount; nChunkId++) - { - CRenderChunk* pChunk(&Chunks[nChunkId]); - - IF (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE, 0) - { - continue; - } - - const int16 nChunkMatID = pChunk->m_nMatID; - - bool b2Sided = false; - - const SShaderItem& shaderItem = pMtl->GetShaderItem(nChunkMatID); - // if (!shaderItem.IsZWrite()) - // continue; - IShader* pShader = shaderItem.m_pShader; - if (!pShader || pShader->GetFlags() & EF_NODRAW || pShader->GetFlags() & EF_DECAL || (pShader->GetShaderType() != eST_General)) - { - continue; - } - if (pShader->GetCull() & eCULL_None) - { - b2Sided = true; - } - if (shaderItem.m_pShaderResources && shaderItem.m_pShaderResources->GetResFlags() & MTL_FLAG_2SIDED) - { - b2Sided = true; - } - - float fOpacity = shaderItem.m_pShaderResources->GetStrengthValue(EFTT_OPACITY) * shaderItem.m_pShaderResources->GetVoxelCoverage(); - if (fOpacity < hitInfo.fMinHitOpacity) - { - continue; - } - - // ColorB colEm = shaderItem.m_pShaderResources->GetEmissiveColor(); - // if(!colEm.r && !colEm.g && !colEm.b) - // colEm = Col_DarkGray; - - // make line triangle intersection - for (uint ii = pChunk->nFirstIndexId; ii < pChunk->nFirstIndexId + pChunk->nNumIndices; ii += 3) - { - int I0 = pInds[ii + 0]; - int I1 = pInds[ii + 1]; - int I2 = pInds[ii + 2]; - - if (I0 >= nVerts || I1 >= nVerts || I2 >= nVerts) - { - return false; - } - - // get tri vertices - Vec3& tv0 = *((Vec3*)&pPos[nPosStride * I0]); - Vec3& tv1 = *((Vec3*)&pPos[nPosStride * I1]); - Vec3& tv2 = *((Vec3*)&pPos[nPosStride * I2]); - -#if defined(_DEBUG) - // Additional validation checks against the vectors that will be used in the triangle overlap - // validation - if (isnan(tv0.x) || isnan(tv0.y) || isnan(tv0.z) || - isnan(tv1.x) || isnan(tv1.y) || isnan(tv1.z) || - isnan(tv2.x) || isnan(tv2.y) || isnan(tv2.z)) - { - return false; - } -#endif // defined(_DEBUG) - - if (Overlap::AABB_Triangle(voxBox, tv0, tv2, tv1)) - { - AABB triBox(tv0, tv0); - triBox.Add(tv2); - triBox.Add(tv1); - - if (triBox.GetRadiusSqr() > 0.00001f) - { - SRayHitTriangle ht; - ht.v[0] = tv0; - ht.v[1] = tv1; - ht.v[2] = tv2; - - ht.t[0] = *((Vec2*)&pUV[nUVStride * I0]); - ht.t[1] = *((Vec2*)&pUV[nUVStride * I1]); - ht.t[2] = *((Vec2*)&pUV[nUVStride * I2]); - - ht.pMat = pMtl->GetSafeSubMtl(nChunkMatID); - - ht.c[0] = (*(ColorB*)&pCol[nColStride * I0]); - ht.c[1] = (*(ColorB*)&pCol[nColStride * I1]); - ht.c[2] = (*(ColorB*)&pCol[nColStride * I2]); - - ht.nOpacity = SATURATEB(int(fOpacity * 255.f)); - hitInfo.pHitTris->Add(ht); - } - } - } - } - } - else if (const PodArray >* pTris = rIntersectionRMData.pRenderMesh->GetTrisForPosition(inRay.origin, pMtl)) - { - for (int nId = 0; nId < pTris->Count(); ++nId) - { - const std::pair& t = pTris->GetAt(nId); - - if (t.first + 2 >= nInds) - { - return false; - } - - int I0 = pInds[t.first + 0]; - int I1 = pInds[t.first + 1]; - int I2 = pInds[t.first + 2]; - - if (I0 >= nVerts || I1 >= nVerts || I2 >= nVerts) - { - return false; - } - - // get tri vertices - Vec3& tv0 = *((Vec3*)&pPos[nPosStride * I0]); - Vec3& tv1 = *((Vec3*)&pPos[nPosStride * I1]); - Vec3& tv2 = *((Vec3*)&pPos[nPosStride * I2]); - - if (Overlap::AABB_Triangle(voxBox, tv0, tv2, tv1)) - { - { - _smart_ptr pSubMtl = pMtl->GetSafeSubMtl(t.second); - if (pSubMtl) - { - if (!pSubMtl->GetShaderItem().IsZWrite()) - { - continue; - } - if (!pSubMtl->GetShaderItem().m_pShader) - { - continue; - } - if (pSubMtl->GetShaderItem().m_pShader->GetShaderType() != eST_Metal && pSubMtl->GetShaderItem().m_pShader->GetShaderType() != eST_General) - { - continue; - } - } - } - - bAnyHit = true; - fBestDist = 0; - vHitPos = voxBox.GetCenter(); - tri[0] = tv0; - tri[1] = tv1; - tri[2] = tv2; - hitInfo.nHitMatID = t.second; - hitInfo.nHitTriID = t.first; - - break; - } - } - } - - return bAnyHit; -} diff --git a/Code/CryEngine/Cry3DEngine/RenderMeshUtils.h b/Code/CryEngine/Cry3DEngine/RenderMeshUtils.h deleted file mode 100644 index da2f277773..0000000000 --- a/Code/CryEngine/Cry3DEngine/RenderMeshUtils.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_RENDERMESHUTILS_H -#define CRYINCLUDE_CRY3DENGINE_RENDERMESHUTILS_H -#pragma once - -struct SIntersectionData; - -////////////////////////////////////////////////////////////////////////// -// RenderMesh utilities. -////////////////////////////////////////////////////////////////////////// -class CRenderMeshUtils - : public Cry3DEngineBase -{ -public: - // Do a render-mesh vs Ray intersection, return true for intersection. - static bool RayIntersection(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pMtl = 0); - static bool RayIntersectionFast(IRenderMesh* pRenderMesh, SRayHitInfo& hitInfo, _smart_ptr pCustomMtl = 0); - - // async versions, aren't using the cache, and are used by the deferredrayintersection class - static void RayIntersectionAsync(SIntersectionData* pIntersectionRMData); - - static void ClearHitCache(); - - - ////////////////////////////////////////////////////////////////////////// - //void FindCollisionWithRenderMesh( IRenderMesh *pRenderMesh, SRayHitInfo &hitInfo ); - // void FindCollisionWithRenderMesh( IPhysiIRenderMesh2 *pRenderMesh, SRayHitInfo &hitInfo ); -private: - // functions implementing the logic for RayIntersection - static bool RayIntersectionImpl(SIntersectionData* pIntersectionRMData, SRayHitInfo* phitInfo, _smart_ptr pCustomMtl, bool bAsync); - static bool RayIntersectionFastImpl(SIntersectionData& rIntersectionRMData, SRayHitInfo& hitInfo, _smart_ptr pCustomMtl, bool bAsync); - static bool ProcessBoxIntersection(Ray& inRay, SRayHitInfo& hitInfo, SIntersectionData& rIntersectionRMData, _smart_ptr pMtl, vtx_idx* pInds, int nVerts, uint8* pPos, int nPosStride, uint8* pUV, int nUVStride, uint8* pCol, int nColStride, int nInds, bool& bAnyHit, float& fBestDist, Vec3& vHitPos, Vec3* tri); -}; - -// struct to collect parameters for the wrapped RayInterseciton functions -struct SIntersectionData -{ - SIntersectionData() - : pRenderMesh(NULL) - , nVerts(0) - , nInds(0) - , nPosStride(0) - , pPos(NULL) - , pInds(NULL) - , nUVStride(0) - , pUV(NULL) - , nColStride(0) - , pCol(NULL) - , nTangsStride(0) - , pTangs(NULL) - , bResult(false) - , bNeedFallback(false) - , fDecalPlacementTestMaxSize(1000.f) - , bDecalPlacementTestRequested(false) - , pHitInfo(0) - , pMtl(0) - { - } - - bool Init(IRenderMesh* pRenderMesh, SRayHitInfo* _pHitInfo, _smart_ptr _pMtl, bool _bRequestDecalPlacementTest = false); - - IRenderMesh* pRenderMesh; - SRayHitInfo* pHitInfo; - _smart_ptr pMtl; - bool bDecalPlacementTestRequested; - - int nVerts; - int nInds; - - int nPosStride; - uint8* pPos; - vtx_idx* pInds; - - int nUVStride; - uint8* pUV; - - int nColStride; - uint8* pCol; - - int nTangsStride; - byte* pTangs; - - bool bResult; - float fDecalPlacementTestMaxSize; // decal will look acceptable in this place - bool bNeedFallback; -}; - -template -bool GetBarycentricCoordinates(const T& a, const T& b, const T& c, const T& p, float& u, float& v, float& w, float fBorder = 0.f); - -#endif // CRYINCLUDE_CRY3DENGINE_RENDERMESHUTILS_H diff --git a/Code/CryEngine/Cry3DEngine/RenderMeshUtils/Tests/Test_RenderMeshUtils.cpp b/Code/CryEngine/Cry3DEngine/RenderMeshUtils/Tests/Test_RenderMeshUtils.cpp deleted file mode 100644 index b482d0c03e..0000000000 --- a/Code/CryEngine/Cry3DEngine/RenderMeshUtils/Tests/Test_RenderMeshUtils.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include - -#include "RenderMeshUtils.h" - -namespace TestRenderMeshUtils -{ - void TestBarycentricCoordinates(Vec3 t0, Vec3 t1, Vec3 t2, const std::vector& hitPoints, const std::vector& expectedBarycentricCoordinates, bool expectedIsHit) - { - assert(hitPoints.size() == expectedBarycentricCoordinates.size()); - - float u = 0.f; - float v = 0.f; - float w = 0.f; - for (uint i = 0; i < hitPoints.size(); ++i) - { - EXPECT_TRUE(GetBarycentricCoordinates(t0, t1, t2, hitPoints[i], u, v, w) == expectedIsHit); - - EXPECT_FLOAT_EQ(expectedBarycentricCoordinates[i].x, u); - EXPECT_FLOAT_EQ(expectedBarycentricCoordinates[i].y, v); - EXPECT_FLOAT_EQ(expectedBarycentricCoordinates[i].z, w); - } - } - - GTEST_TEST(GetBarycentricCoordinatesTest, Call_CoordinatesOnVertexOfUnitTriangle_ReturnsTrue) - { - // Test triangle - Vec3 t0(1.f, 0.f, 0.f); - Vec3 t1(0.f, 1.f, 0.f); - Vec3 t2(0.f, 0.f, 1.f); - - // Test data - std::vector vertexHitPoints = { - { 1.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, { 0.f, 0.f, 1.f } - }; - std::vector vertexExpectedBarycentricCoordinates = { - { 1.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, { 0.f, 0.f, 1.f } - }; - - TestBarycentricCoordinates(t0, t1, t2, vertexHitPoints, vertexExpectedBarycentricCoordinates, true); - } - - GTEST_TEST(GetBarycentricCoordinatesTest, Call_CoordinatesOnEdgeOfUnitTriangle_ReturnsTrue) - { - // Test triangle - Vec3 t0(1.f, 0.f, 0.f); - Vec3 t1(0.f, 1.f, 0.f); - Vec3 t2(0.f, 0.f, 1.f); - - // Test data - std::vector edgeHitPoints = { - { 0.5f, 0.5f, 0.0f }, { 0.5f, 0.0f, 0.5f }, { 0.0f, 0.5f, 0.5f } - }; - std::vector edgeExpectedBarycentricCoordinates = { - { 0.5f, 0.5f, 0.0f }, { 0.5f, 0.0f, 0.5f }, { 0.0f, 0.5f, 0.5f } - }; - - TestBarycentricCoordinates(t0, t1, t2, edgeHitPoints, edgeExpectedBarycentricCoordinates, true); - } - - GTEST_TEST(GetBarycentricCoordinatesTest, Call_CoordinatesOnCenterOfUnitTriangle_ReturnsTrue) - { - // Test triangle - Vec3 t0(1.f, 0.f, 0.f); - Vec3 t1(0.f, 1.f, 0.f); - Vec3 t2(0.f, 0.f, 1.f); - - // Test data - std::vector centerHitPoints = { - { 0.5f, 0.5f, 0.5f }, { 1.f, 1.f, 1.f }, { -1.f, -1.f, -1.f } - }; - std::vector centerExpectedBarycentricCoordinates = { - { 1.f / 3.f, 1.f / 3.f, 1.f / 3.f }, { 1.f / 3.f, 1.f / 3.f, 1.f / 3.f }, { 1.f / 3.f, 1.f / 3.f, 1.f / 3.f } - }; - - TestBarycentricCoordinates(t0, t1, t2, centerHitPoints, centerExpectedBarycentricCoordinates, true); - } - - GTEST_TEST(GetBarycentricCoordinatesTest, Call_CoordinatesOffCenterOfUnitTriangle_ReturnsTrue) - { - // Test triangle - Vec3 t0(1.f, 0.f, 0.f); - Vec3 t1(0.f, 1.f, 0.f); - Vec3 t2(0.f, 0.f, 1.f); - - // Test data - std::vector offCenterHitPoints = { - { 1.f, 1.f, .75f }, { -1.f, -1.f, -.75f } - }; - std::vector offCenterExpectedBarycentricCoordinates = { - { 5.f / 12.f, 5.f / 12.f, 1.f / 6.f }, { 0.25f, 0.25f, 0.5f } - }; - - TestBarycentricCoordinates(t0, t1, t2, offCenterHitPoints, offCenterExpectedBarycentricCoordinates, true); - } - - GTEST_TEST(GetBarycentricCoordinatesTest, Call_CoordinatesOutsideOfUnitTriangle_ReturnsFalse) - { - // Test triangle - Vec3 t0(1.f, 0.f, 0.f); - Vec3 t1(0.f, 1.f, 0.f); - Vec3 t2(0.f, 0.f, 1.f); - - // Test data - std::vector nonHitPoints = { - { 1.f, 1.f, 0.f }, { 1.f, 0.f, 1.f }, { 0.f, 1.f, 1.f } - }; - std::vector nonHitExpectedBarycentricCoordinates = { - { 2.f / 3.f, 2.f / 3.f, -1.f / 3.f }, { 2.f / 3.f, -1.f / 3.f, 2.f / 3.f }, { -1.f / 3.f, 2.f / 3.f, 2.f / 3.f } - }; - - TestBarycentricCoordinates(t0, t1, t2, nonHitPoints, nonHitExpectedBarycentricCoordinates, false); - } -} diff --git a/Code/CryEngine/Cry3DEngine/ShadowCache.cpp b/Code/CryEngine/Cry3DEngine/ShadowCache.cpp deleted file mode 100644 index c93b014cd2..0000000000 --- a/Code/CryEngine/Cry3DEngine/ShadowCache.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "ShadowCache.h" -#include "LightEntity.h" -#include "VisAreas.h" - -const float ShadowCache::AO_FRUSTUM_SLOPE_BIAS = 0.5f; - -void ShadowCache::InitShadowFrustum(ShadowMapFrustum*& pFr, int nLod, int nFirstStaticLod, float fDistFromViewDynamicLod, float fRadiusDynamicLod, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - assert(nLod >= 0); - - // If we only allow updates via script, then early out here. - // When script triggers an update, m_nUpdateStrategy will be set to ShadowMapFrustum::ShadowCacheData::eFullUpdate for a single frame to process a full cached shadow update - if ( m_nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eManualUpdate ) - { - return; - } - - if (!pFr) - { - pFr = new ShadowMapFrustum; - } - - if (!pFr->pShadowCacheData) - { - pFr->pShadowCacheData = new ShadowMapFrustum::ShadowCacheData; - } - - // Check if we both allow updates if the user moves too close to the border of the shadow map and if we have come too close to said border - ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy = m_nUpdateStrategy; - bool allowDistanceBasedUpdates = nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eManualOrDistanceUpdate || nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate; - if (allowDistanceBasedUpdates && Get3DEngine()->m_CachedShadowsBounds.IsReset()) - { - // Distance from the camera to the center of the last time this cached static shadow map was updated - const float distanceBetweenCenters = (passInfo.GetCamera().GetPosition() - pFr->aabbCasters.GetCenter()).GetLength(); - - // Note: These values are calculated based on e_gsmRange, e_gsmRangeStep and your camera properties. They will not change unless those change. - const float dynamicCascadeMeasurements = fDistFromViewDynamicLod + fRadiusDynamicLod; - - // Check if our dynamic shadow frustum lies outside of the cached shadow frustum. If so, force an update. - if ((distanceBetweenCenters + dynamicCascadeMeasurements) > pFr->aabbCasters.GetSize().x / 2.0f) - { - nUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate; - - if (!gEnv->IsEditing()) - { - // If our dynamic cascade always registers as larger than the update threshold for the cached frustum, regardless of how far the camera has moved, this is a serious error. - // This needs fixed either via CVars or a flow graph node. - if (dynamicCascadeMeasurements > (pFr->aabbCasters.GetSize().x / 2.0f)) - { - // To prevent per-frame spam, but still output often enough that this message will get noticed and hopefully fixed. - // Not fixing this issue means users are potentially rendering thousands of extra objects into shadow maps per frame. - static unsigned int s_lastOutput = 1000; - if ((++s_lastOutput) > 1000) - { - s_lastOutput = 0; - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Cached shadowmap %d is forced to update even though the camera has not moved or only slightly moved." \ - "\tIf you see this output very often, and you are not using their default values, you may need to either increase the shadow cache resolution (r_ShadowsCacheResolutions) or decrease the global shadow map resolution (e_ShadowsMaxTexRes)." \ - "\tOtherwise, add a flow graph node (Environment:RecomputeStaticShadows) that updates the cached shadowmaps for this region.", nLod - nFirstStaticLod); - } - } - else - { - // The camera most likely moved a far distance away from where the last cached shadowmap was rendered; - // however, the user did not add a flowgraph node to recompute the cached shadowmaps in this region - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Update required for cached shadow map %d." \ - "\tConsider setting up manual bounds for cached shadows in this region via flow graph (Environment:RecomputeStaticShadows) if this happens too often", nLod - nFirstStaticLod); - } - } - } - } - - // If we allow only manual or distance-based updates, then early out here if nUpdateStrategy was not set to ShadowMapFrustum::ShadowCacheData::eFullUpdate after the distance checks above. - if ( nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eManualOrDistanceUpdate ) - { - return; - } - - AABB projectionBoundsLS(AABB::RESET); - const int nTexRes = GetRenderer()->GetCachedShadowsResolution()[nLod - nFirstStaticLod]; - - // non incremental update: set new bounding box and estimate near/far planes - if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate) - { - Matrix34 matView = Matrix34(GetViewMatrix(passInfo).GetTransposed()); - - if (!Get3DEngine()->m_CachedShadowsBounds.IsReset()) - { - float fBoxScale = powf(Get3DEngine()->m_fCachedShadowsCascadeScale, (float)nLod - nFirstStaticLod); - Vec3 fBoxScaleXY(max(1.f, fBoxScale)); - fBoxScaleXY.z = 1.f; - - Vec3 vExt = Get3DEngine()->m_CachedShadowsBounds.GetSize().CompMul(fBoxScaleXY * 0.5f); - Vec3 vCenter = Get3DEngine()->m_CachedShadowsBounds.GetCenter(); - - pFr->aabbCasters = AABB(vCenter - vExt, vCenter + vExt); - projectionBoundsLS = AABB::CreateTransformedAABB(matView, pFr->aabbCasters); - } - else - { - const float fDesiredPixelDensity = fRadiusDynamicLod / GetCVars()->e_ShadowsMaxTexRes; - GetCasterBox(pFr->aabbCasters, projectionBoundsLS, fDesiredPixelDensity * nTexRes, matView, passInfo); - } - } - - // finally init frustum - InitCachedFrustum(pFr, nUpdateStrategy, nLod, nTexRes, m_pLightEntity->m_light.m_Origin, projectionBoundsLS, passInfo); - pFr->m_eFrustumType = ShadowMapFrustum::e_GsmCached; - pFr->bBlendFrustum = GetCVars()->e_ShadowsBlendCascades > 0; - pFr->fBlendVal = pFr->bBlendFrustum ? GetCVars()->e_ShadowsBlendCascadesVal : 1.0f; - - // frustum debug - { - const ColorF cascadeColors[] = { Col_Red, Col_Green, Col_Blue, Col_Yellow, Col_Magenta, Col_Cyan }; - const uint colorCount = sizeof(cascadeColors) / sizeof(cascadeColors[0]); - - if (GetCVars()->e_ShadowsCacheUpdate > 2) - { - Get3DEngine()->DrawBBox(pFr->aabbCasters, cascadeColors[pFr->nShadowMapLod % colorCount]); - } - - if (GetCVars()->e_ShadowsFrustums > 0) - { - pFr->DrawFrustum(GetRenderer(), std::numeric_limits::max()); - } - } -} - -void ShadowCache::InitCachedFrustum(ShadowMapFrustum*& pFr, ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy, int nLod, int nTexSize, const Vec3& vLightPos, const AABB& projectionBoundsLS, const SRenderingPassInfo& passInfo) -{ - pFr->ResetCasterLists(); - pFr->nTexSize = nTexSize; - - if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate) - { - pFr->pShadowCacheData->Reset(); - pFr->nShadowGenMask = 1; - - assert(m_pLightEntity->m_light.m_pOwner); - pFr->pLightOwner = m_pLightEntity->m_light.m_pOwner; - pFr->m_Flags = m_pLightEntity->m_light.m_Flags; - pFr->nUpdateFrameId = passInfo.GetFrameID(); - pFr->nShadowMapLod = nLod; - pFr->vProjTranslation = pFr->aabbCasters.GetCenter(); - pFr->vLightSrcRelPos = vLightPos - pFr->aabbCasters.GetCenter(); - pFr->fNearDist = -projectionBoundsLS.max.z; - pFr->fFarDist = -projectionBoundsLS.min.z; - pFr->fFOV = (float)RAD2DEG(atan_tpl(0.5 * projectionBoundsLS.GetSize().y / pFr->fNearDist)) * 2.f; - pFr->fProjRatio = projectionBoundsLS.GetSize().x / projectionBoundsLS.GetSize().y; - pFr->fRadius = m_pLightEntity->m_light.m_fRadius; - pFr->fFrustrumSize = 1.0f / (Get3DEngine()->m_fGsmRange * pFr->aabbCasters.GetRadius() * 2.0f); - - const float arrWidthS[] = {1.94f, 1.0f, 0.8f, 0.5f, 0.3f, 0.3f, 0.3f, 0.3f}; - pFr->fWidthS = pFr->fWidthT = arrWidthS[nLod]; - pFr->fBlurS = pFr->fBlurT = 0.0f; - } - - const int maxNodesPerFrame = (nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eFullUpdate) - ? std::numeric_limits::max() - : MAX_RENDERNODES_PER_FRAME* GetRenderer()->GetActiveGPUCount(); - - const bool bExcludeDynamicDistanceShadows = GetCVars()->e_DynamicDistanceShadows != 0; - m_pObjManager->MakeStaticShadowCastersList(((CLightEntity*)m_pLightEntity->m_light.m_pOwner)->m_pNotCaster, pFr, - bExcludeDynamicDistanceShadows ? ERF_DYNAMIC_DISTANCESHADOWS : 0, maxNodesPerFrame, passInfo); - - pFr->pShadowCacheData->mProcessedCasters.insert(pFr->m_castersList.begin(), pFr->m_castersList.end()); - pFr->pShadowCacheData->mProcessedCasters.insert(pFr->m_jobExecutedCastersList.begin(), pFr->m_jobExecutedCastersList.end()); - pFr->RequestUpdate(); - pFr->bIncrementalUpdate = nUpdateStrategy == ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate && !pFr->pShadowCacheData->mProcessedCasters.empty(); -} - -void ShadowCache::InitHeightMapAOFrustum(ShadowMapFrustum*& pFr, int nLod, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - assert(nLod >= 0); - - if (!pFr) - { - pFr = new ShadowMapFrustum; - } - - if (!pFr->pShadowCacheData) - { - pFr->pShadowCacheData = new ShadowMapFrustum::ShadowCacheData; - } - - static ICVar* pHeightMapAORes = gEnv->pConsole->GetCVar("r_HeightMapAOResolution"); - static ICVar* pHeightMapAORange = gEnv->pConsole->GetCVar("r_HeightMapAORange"); - - ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy = m_nUpdateStrategy; - - // check if we have come too close to the border of the map - const float fDistFromCenter = (passInfo.GetCamera().GetPosition() - pFr->aabbCasters.GetCenter()).GetLength() + pHeightMapAORange->GetFVal() * 0.25f; - if (fDistFromCenter > pFr->aabbCasters.GetSize().x / 2.0f) - { - nUpdateStrategy = ShadowMapFrustum::ShadowCacheData::eFullUpdate; - - if (!gEnv->IsEditing()) - { - CryLog("Update required for height map AO."); - CryLog("\tConsider increasing height map AO range (r_HeightMapAORange) if this happens too often"); - } - } - - AABB projectionBoundsLS(AABB::RESET); - - // non incremental update: set new bounding box and estimate near/far planes - if (nUpdateStrategy != ShadowMapFrustum::ShadowCacheData::eIncrementalUpdate) - { - // Top down view - Matrix34 topDownView(IDENTITY); - topDownView.m03 = -passInfo.GetCamera().GetPosition().x; - topDownView.m13 = -passInfo.GetCamera().GetPosition().y; - topDownView.m23 = -passInfo.GetCamera().GetPosition().z - m_pLightEntity->m_light.m_Origin.GetLength(); - - GetCasterBox(pFr->aabbCasters, projectionBoundsLS, pHeightMapAORange->GetFVal() / 2.0f, topDownView, passInfo); - - // snap to texels - const float fSnap = pHeightMapAORange->GetFVal() / pHeightMapAORes->GetFVal(); - pFr->aabbCasters.min.x = fSnap * int(pFr->aabbCasters.min.x / fSnap); - pFr->aabbCasters.min.y = fSnap * int(pFr->aabbCasters.min.y / fSnap); - pFr->aabbCasters.min.z = fSnap * int(pFr->aabbCasters.min.z / fSnap); - - pFr->aabbCasters.max.x = pFr->aabbCasters.min.x + pHeightMapAORange->GetFVal(); - pFr->aabbCasters.max.y = pFr->aabbCasters.min.y + pHeightMapAORange->GetFVal(); - pFr->aabbCasters.max.z = fSnap * int(pFr->aabbCasters.max.z / fSnap); - - pFr->fDepthSlopeBias = AO_FRUSTUM_SLOPE_BIAS; - pFr->fDepthConstBias = 0; - - pFr->mLightViewMatrix.SetIdentity(); - pFr->mLightViewMatrix.m30 = -pFr->aabbCasters.GetCenter().x; - pFr->mLightViewMatrix.m31 = -pFr->aabbCasters.GetCenter().y; - pFr->mLightViewMatrix.m32 = -pFr->aabbCasters.GetCenter().z - m_pLightEntity->m_light.m_Origin.GetLength(); - - mathMatrixOrtho(&pFr->mLightProjMatrix, projectionBoundsLS.GetSize().x, projectionBoundsLS.GetSize().y, -projectionBoundsLS.max.z, -projectionBoundsLS.min.z); - } - - const Vec3 lightPos = pFr->aabbCasters.GetCenter() + Vec3(0, 0, 1) * m_pLightEntity->m_light.m_Origin.GetLength(); - - // finally init frustum - const int nTexRes = (int)clamp_tpl(pHeightMapAORes->GetFVal(), 0.f, 16384.f); - InitCachedFrustum(pFr, nUpdateStrategy, nLod, nTexRes, lightPos, projectionBoundsLS, passInfo); - pFr->m_eFrustumType = ShadowMapFrustum::e_HeightMapAO; -} - -void ShadowCache::GetCasterBox(AABB& BBoxWS, AABB& BBoxLS, float fRadius, const Matrix34& matView, const SRenderingPassInfo& passInfo) -{ - AABB projectionBoundsLS; - - BBoxWS = AABB(passInfo.GetCamera().GetPosition(), fRadius); - BBoxLS = AABB(matView.TransformPoint(passInfo.GetCamera().GetPosition()), fRadius); - - // try to get tighter near/far plane from casters - AABB casterBoxLS(AABB::RESET); - if (Get3DEngine()->IsObjectTreeReady()) - { - casterBoxLS.Add(Get3DEngine()->GetObjectTree()->GetShadowCastersBox(&BBoxWS, &matView)); - } - - if (CVisAreaManager* pVisAreaManager = GetVisAreaManager()) - { - for (int i = 0; i < pVisAreaManager->m_lstVisAreas.Count(); ++i) - { - if (pVisAreaManager->m_lstVisAreas[i] && pVisAreaManager->m_lstVisAreas[i]->m_pObjectsTree) - { - casterBoxLS.Add(pVisAreaManager->m_lstVisAreas[i]->m_pObjectsTree->GetShadowCastersBox(&BBoxWS, &matView)); - } - } - - for (int i = 0; i < pVisAreaManager->m_lstPortals.Count(); ++i) - { - if (pVisAreaManager->m_lstPortals[i] && pVisAreaManager->m_lstPortals[i]->m_pObjectsTree) - { - casterBoxLS.Add(pVisAreaManager->m_lstPortals[i]->m_pObjectsTree->GetShadowCastersBox(&BBoxWS, &matView)); - } - } - } - - if (!casterBoxLS.IsReset() && casterBoxLS.GetSize().z < 2 * fRadius) - { - float fDepthRange = 2.0f * max(Get3DEngine()->m_fSunClipPlaneRange, casterBoxLS.GetSize().z); - BBoxLS.max.z = casterBoxLS.max.z + 0.5f; // slight offset here to counter edge case where polygons are projection plane aligned and would come to lie directly on the near plane - BBoxLS.min.z = casterBoxLS.max.z - fDepthRange; - } -} - -Matrix44 ShadowCache::GetViewMatrix(const SRenderingPassInfo& passInfo) -{ - const Vec3 zAxis(0.f, 0.f, 1.f); - const Vec3 yAxis(0.f, 1.f, 0.f); - - Vec3 At = passInfo.GetCamera().GetPosition(); - Vec3 Eye = m_pLightEntity->m_light.m_Origin; - Vec3 Up = fabsf((Eye - At).GetNormalized().Dot(zAxis)) > 0.9995f ? yAxis : zAxis; - - Matrix44 result; - mathMatrixLookAt(&result, Eye, At, Up); - - return result; -} - -ILINE uint64 ShadowCache::HashValue(uint64 value) -{ - uint64 hash = value * kHashMul; - hash ^= (hash >> 47); - hash *= kHashMul; - return hash; -} diff --git a/Code/CryEngine/Cry3DEngine/ShadowCache.h b/Code/CryEngine/Cry3DEngine/ShadowCache.h deleted file mode 100644 index 1d141c5a85..0000000000 --- a/Code/CryEngine/Cry3DEngine/ShadowCache.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef STATIC_SHADOWS_H -#define STATIC_SHADOWS_H - -#include -#include "../RenderDll/Common/Shadow_Renderer.h" - -class ShadowCache - : public Cry3DEngineBase -{ -public: - ShadowCache(CLightEntity* pLightEntity, ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy) - : m_pLightEntity(pLightEntity) - , m_nUpdateStrategy(nUpdateStrategy) - {} - - void InitShadowFrustum(ShadowMapFrustum*& pFr, int nLod, int nFirstStaticLod, float fDistFromViewDynamicLod, float fRadiusDynamicLod, const SRenderingPassInfo& passInfo); - void InitHeightMapAOFrustum(ShadowMapFrustum*& pFr, int nLod, const SRenderingPassInfo& passInfo); - -private: - static const int MAX_RENDERNODES_PER_FRAME = 50; - static const float AO_FRUSTUM_SLOPE_BIAS; - static const uint64 kHashMul = 0x9ddfea08eb382d69ULL; - - - void InitCachedFrustum(ShadowMapFrustum*& pFr, ShadowMapFrustum::ShadowCacheData::eUpdateStrategy nUpdateStrategy, int nLod, int nTexSize, const Vec3& vLightPos, const AABB& projectionBoundsLS, const SRenderingPassInfo& passInfo); - - void GetCasterBox(AABB& BBoxWS, AABB& BBoxLS, float fRadius, const Matrix34& matView, const SRenderingPassInfo& passInfo); - Matrix44 GetViewMatrix(const SRenderingPassInfo& passInfo); - - ILINE uint64 HashValue(uint64 value); - - CLightEntity* m_pLightEntity; - ShadowMapFrustum::ShadowCacheData::eUpdateStrategy m_nUpdateStrategy; -}; -#endif diff --git a/Code/CryEngine/Cry3DEngine/SkyLightManager.cpp b/Code/CryEngine/Cry3DEngine/SkyLightManager.cpp deleted file mode 100644 index e692c63f7d..0000000000 --- a/Code/CryEngine/Cry3DEngine/SkyLightManager.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "SkyLightManager.h" -#include "SkyLightNishita.h" -#include - -#include - -static AZ::LegacyJobExecutor s_jobExecutor; - -CSkyLightManager::CSkyLightManager() - : m_pSkyLightNishita(CryAlignedNew()) - , m_pSkyDomeMesh(0) - , m_curSkyDomeCondition() - , m_updatingSkyDomeCondition() - , m_numSkyDomeColorsComputed(SSkyLightRenderParams::skyDomeTextureSize) - , m_curBackBuffer(0) - , m_lastFrameID(0) - , m_curSkyHemiColor() - , m_curHazeColor(0.0f, 0.0f, 0.0f) - , m_curHazeColorMieNoPremul(0.0f, 0.0f, 0.0f) - , m_curHazeColorRayleighNoPremul(0.0f, 0.0f, 0.0f) - , m_skyHemiColorAccum() - , m_hazeColorAccum(0.0f, 0.0f, 0.0f) - , m_hazeColorMieNoPremulAccum(0.0f, 0.0f, 0.0f) - , m_hazeColorRayleighNoPremulAccum(0.0f, 0.0f, 0.0f) - , m_bFlushFullUpdate(false) - , m_renderParams() -{ - InitSkyDomeMesh(); - - m_updateRequested[0] = m_updateRequested[1] = 0; - - // init textures with default data - m_skyDomeTextureDataMie[ 0 ].resize(SSkyLightRenderParams::skyDomeTextureSize); - m_skyDomeTextureDataMie[ 1 ].resize(SSkyLightRenderParams::skyDomeTextureSize); - m_skyDomeTextureDataRayleigh[ 0 ].resize(SSkyLightRenderParams::skyDomeTextureSize); - m_skyDomeTextureDataRayleigh[ 1 ].resize(SSkyLightRenderParams::skyDomeTextureSize); - - // init time stamps - m_skyDomeTextureTimeStamp[ 0 ] = GetRenderer()->GetFrameID(false); - m_skyDomeTextureTimeStamp[ 1 ] = GetRenderer()->GetFrameID(false); - - // init sky hemisphere colors and accumulators - memset(m_curSkyHemiColor, 0, sizeof(m_curSkyHemiColor)); - memset(m_skyHemiColorAccum, 0, sizeof(m_skyHemiColorAccum)); - - // set default render parameters - UpdateRenderParams(); -} - - -CSkyLightManager::~CSkyLightManager() -{ - CryAlignedDelete(m_pSkyLightNishita); -} - -inline static void Sync() -{ - s_jobExecutor.WaitForCompletion(); -} - -void CSkyLightManager::PushUpdateParams() -{ - //pushes the update parameters, explicite call since engine requests asynchronously - memcpy(&m_reqSkyDomeCondition[0], &m_reqSkyDomeCondition[1], sizeof(SSkyDomeCondition)); - m_updateRequested[0] = m_updateRequested[1]; - m_updateRequested[1] = 0; -} - -void CSkyLightManager::SetSkyDomeCondition(const SSkyDomeCondition& skyDomeCondition) -{ - m_reqSkyDomeCondition[1] = skyDomeCondition; - m_updateRequested[1] = 1; -} - - -void CSkyLightManager::FullUpdate() -{ - Sync(); - PushUpdateParams(); - - s_jobExecutor.Reset(); - s_jobExecutor.StartJob([this]() { this->UpdateInternal(GetRenderer()->GetFrameID(false), SSkyLightRenderParams::skyDomeTextureSize, (int)1); }); - - m_needRenderParamUpdate = true; - m_bFlushFullUpdate = true; -} - -void CSkyLightManager::IncrementalUpdate(f32 updateRatioPerFrame, const SRenderingPassInfo& passInfo) -{ - Sync(); - - FUNCTION_PROFILER_3DENGINE; - - // get current ID of "main" frame (no recursive rendering), - // incremental update should only be processed once per frame - if (m_lastFrameID != passInfo.GetMainFrameID()) - { - int32 numUpdate((int32) ((f32) SSkyLightRenderParams::skyDomeTextureSize * updateRatioPerFrame / 100.0f + 0.5f)); - numUpdate = clamp_tpl(numUpdate, 1, SSkyLightRenderParams::skyDomeTextureSize); - if (m_needRenderParamUpdate) - { - UpdateRenderParams(); // update render params - } - PushUpdateParams(); - - s_jobExecutor.Reset(); - s_jobExecutor.StartJob([this, passInfo, numUpdate]() { this->UpdateInternal(passInfo.GetMainFrameID(), numUpdate, (int)0); }); - } -} - - -void CSkyLightManager::UpdateInternal(int32 newFrameID, int32 numUpdates, int callerIsFullUpdate) -{ - FUNCTION_PROFILER_3DENGINE; - - // update sky dome if requested -- requires last update request to be fully processed! - int procUpdate = callerIsFullUpdate; - procUpdate |= (int)IsSkyDomeUpdateFinished(); - procUpdate &= m_updateRequested[0]; - if (procUpdate) - { - // set sky dome settings - memcpy(&m_updatingSkyDomeCondition, &m_reqSkyDomeCondition[0], sizeof(SSkyDomeCondition)); - m_pSkyLightNishita->SetSunDirection(m_updatingSkyDomeCondition.m_sunDirection); - m_pSkyLightNishita->SetRGBWaveLengths(m_updatingSkyDomeCondition.m_rgbWaveLengths); - m_pSkyLightNishita->SetAtmosphericConditions(m_updatingSkyDomeCondition.m_sunIntensity, - 1e-4f * m_updatingSkyDomeCondition.m_Km, 1e-4f * m_updatingSkyDomeCondition.m_Kr, m_updatingSkyDomeCondition.m_g); // scale mie and rayleigh scattering for more convenient editing in time of day dialog - - // update request has been accepted - m_updateRequested[0] = 0; - m_numSkyDomeColorsComputed = 0; - - // reset sky & haze color accumulator - m_hazeColorAccum = Vec3(0.0f, 0.0f, 0.0f); - m_hazeColorMieNoPremulAccum = Vec3(0.0f, 0.0f, 0.0f); - m_hazeColorRayleighNoPremulAccum = Vec3(0.0f, 0.0f, 0.0f); - memset(m_skyHemiColorAccum, 0, sizeof(m_skyHemiColorAccum)); - } - - // any work to do? - if (false == IsSkyDomeUpdateFinished()) - { - if (numUpdates <= 0) - { - // do a full update - numUpdates = SSkyLightRenderParams::skyDomeTextureSize; - } - - // find minimally required work load for this incremental update - numUpdates = min(SSkyLightRenderParams::skyDomeTextureSize - m_numSkyDomeColorsComputed, numUpdates); - - // perform color computations - SkyDomeTextureData& skyDomeTextureDataMie(m_skyDomeTextureDataMie[ GetBackBuffer() ]); - SkyDomeTextureData& skyDomeTextureDataRayleigh(m_skyDomeTextureDataRayleigh[ GetBackBuffer() ]); - - int32 numSkyDomeColorsComputed(m_numSkyDomeColorsComputed); - for (; numUpdates > 0; --numUpdates, ++numSkyDomeColorsComputed) - { - // calc latitude/longitude - int lon(numSkyDomeColorsComputed / SSkyLightRenderParams::skyDomeTextureWidth); - int lat(numSkyDomeColorsComputed % SSkyLightRenderParams::skyDomeTextureWidth); - - float lonArc(DEG2RAD((float) lon * 90.0f / (float) SSkyLightRenderParams::skyDomeTextureHeight)); - float latArc(DEG2RAD((float) lat * 360.0f / (float) SSkyLightRenderParams::skyDomeTextureWidth)); - - float sinLon(0); - float cosLon(0); - sincos_tpl(lonArc, &sinLon, &cosLon); - float sinLat(0); - float cosLat(0); - sincos_tpl(latArc, &sinLat, &cosLat); - - // calc sky direction for given update latitude/longitude (hemisphere) - Vec3 skyDir(sinLon * cosLat, sinLon * sinLat, cosLon); - - // compute color - //Vec3 skyColAtDir( 0.0, 0.0, 0.0 ); - Vec3 skyColAtDirMieNoPremul(0.0, 0.0, 0.0); - Vec3 skyColAtDirRayleighNoPremul(0.0, 0.0, 0.0); - Vec3 skyColAtDirRayleigh(0.0, 0.0, 0.0); - - m_pSkyLightNishita->ComputeSkyColor(skyDir, 0, &skyColAtDirMieNoPremul, &skyColAtDirRayleighNoPremul, &skyColAtDirRayleigh); - - // store color in texture - skyDomeTextureDataMie[ numSkyDomeColorsComputed ] = CryHalf4(skyColAtDirMieNoPremul.x, skyColAtDirMieNoPremul.y, skyColAtDirMieNoPremul.z, 1.0f); - skyDomeTextureDataRayleigh[ numSkyDomeColorsComputed ] = CryHalf4(skyColAtDirRayleighNoPremul.x, skyColAtDirRayleighNoPremul.y, skyColAtDirRayleighNoPremul.z, 1.0f); - - // update haze color accum (accumulate second last sample row) - if (lon == SSkyLightRenderParams::skyDomeTextureHeight - 2) - { - m_hazeColorAccum += skyColAtDirRayleigh; - m_hazeColorMieNoPremulAccum += skyColAtDirMieNoPremul; - m_hazeColorRayleighNoPremulAccum += skyColAtDirRayleighNoPremul; - } - - // update sky hemisphere color accumulator - int y(lon >> SSkyLightRenderParams::skyDomeTextureHeightBy2Log); - int x(((lat + SSkyLightRenderParams::skyDomeTextureWidthBy8) & (SSkyLightRenderParams::skyDomeTextureWidth - 1)) >> SSkyLightRenderParams::skyDomeTextureWidthBy4Log); - int skyHemiColAccumIdx(x * y + y); - assert(((unsigned int)skyHemiColAccumIdx) < 5); - m_skyHemiColorAccum[skyHemiColAccumIdx] += skyColAtDirRayleigh; - } - - m_numSkyDomeColorsComputed = numSkyDomeColorsComputed; - - // sky dome update finished? - if (false != IsSkyDomeUpdateFinished()) - { - // update time stamp - m_skyDomeTextureTimeStamp[ GetBackBuffer() ] = newFrameID; - - // get new haze color - const float c_invNumHazeSamples(1.0f / (float) SSkyLightRenderParams::skyDomeTextureWidth); - m_curHazeColor = m_hazeColorAccum * c_invNumHazeSamples; - m_curHazeColorMieNoPremul = m_hazeColorMieNoPremulAccum * c_invNumHazeSamples; - m_curHazeColorRayleighNoPremul = m_hazeColorRayleighNoPremulAccum * c_invNumHazeSamples; - - // get new sky hemisphere colors - const float c_scaleHemiTop(2.0f / (SSkyLightRenderParams::skyDomeTextureWidth * SSkyLightRenderParams::skyDomeTextureHeight)); - const float c_scaleHemiSide(8.0f / (SSkyLightRenderParams::skyDomeTextureWidth * SSkyLightRenderParams::skyDomeTextureHeight)); - m_curSkyHemiColor[0] = m_skyHemiColorAccum[0] * c_scaleHemiTop; - m_curSkyHemiColor[1] = m_skyHemiColorAccum[1] * c_scaleHemiSide; - m_curSkyHemiColor[2] = m_skyHemiColorAccum[2] * c_scaleHemiSide; - m_curSkyHemiColor[3] = m_skyHemiColorAccum[3] * c_scaleHemiSide; - m_curSkyHemiColor[4] = m_skyHemiColorAccum[4] * c_scaleHemiSide; - - // toggle sky light buffers - ToggleBuffer(); - } - } - - // update frame ID - m_lastFrameID = newFrameID; -} - -void CSkyLightManager::SetQuality(int32 quality) -{ - if (quality != m_pSkyLightNishita->GetInScatteringIntegralStepSize()) - { - Sync(); - // when setting new quality we need to start sky dome update from scratch... - // ... to avoid "artifacts" in the resulting texture - m_numSkyDomeColorsComputed = 0; - m_pSkyLightNishita->SetInScatteringIntegralStepSize(quality); - } -} - -const SSkyLightRenderParams* CSkyLightManager::GetRenderParams() const -{ - return &m_renderParams; -} - -void CSkyLightManager::UpdateRenderParams() -{ - // sky dome mesh data - m_renderParams.m_pSkyDomeMesh = m_pSkyDomeMesh; - - // sky dome texture access - m_renderParams.m_skyDomeTextureTimeStamp = m_skyDomeTextureTimeStamp[ GetFrontBuffer() ]; - m_renderParams.m_pSkyDomeTextureDataMie = (const void*) &m_skyDomeTextureDataMie[ GetFrontBuffer() ][ 0 ]; - m_renderParams.m_pSkyDomeTextureDataRayleigh = (const void*) &m_skyDomeTextureDataRayleigh[ GetFrontBuffer() ][ 0 ]; - m_renderParams.m_skyDomeTexturePitch = SSkyLightRenderParams::skyDomeTextureWidth * sizeof(CryHalf4); - - // shader constants for final per-pixel phase computation - m_renderParams.m_partialMieInScatteringConst = m_pSkyLightNishita->GetPartialMieInScatteringConst(); - m_renderParams.m_partialRayleighInScatteringConst = m_pSkyLightNishita->GetPartialRayleighInScatteringConst(); - Vec3 sunDir(m_pSkyLightNishita->GetSunDirection()); - m_renderParams.m_sunDirection = Vec4(sunDir.x, sunDir.y, sunDir.z, 0.0f); - m_renderParams.m_phaseFunctionConsts = m_pSkyLightNishita->GetPhaseFunctionConsts(); - m_renderParams.m_hazeColor = Vec4(m_curHazeColor.x, m_curHazeColor.y, m_curHazeColor.z, 0); - m_renderParams.m_hazeColorMieNoPremul = Vec4(m_curHazeColorMieNoPremul.x, m_curHazeColorMieNoPremul.y, m_curHazeColorMieNoPremul.z, 0); - m_renderParams.m_hazeColorRayleighNoPremul = Vec4(m_curHazeColorRayleighNoPremul.x, m_curHazeColorRayleighNoPremul.y, m_curHazeColorRayleighNoPremul.z, 0); - - // set sky hemisphere colors - m_renderParams.m_skyColorTop = m_curSkyHemiColor[0]; - m_renderParams.m_skyColorNorth = m_curSkyHemiColor[3]; - m_renderParams.m_skyColorWest = m_curSkyHemiColor[4]; - m_renderParams.m_skyColorSouth = m_curSkyHemiColor[1]; - m_renderParams.m_skyColorEast = m_curSkyHemiColor[2]; - - // copy sky dome condition params - m_curSkyDomeCondition = m_updatingSkyDomeCondition; - - m_needRenderParamUpdate = 0; -} - -void CSkyLightManager::GetCurSkyDomeCondition(SSkyDomeCondition& skyCond) const -{ - skyCond = m_curSkyDomeCondition; -} - -bool CSkyLightManager::IsSkyDomeUpdateFinished() const -{ - return(SSkyLightRenderParams::skyDomeTextureSize == m_numSkyDomeColorsComputed); -} - - -void CSkyLightManager::InitSkyDomeMesh() -{ - ReleaseSkyDomeMesh(); - -#if defined(MOBILE) - const uint32 c_numRings(10); - const uint32 c_numSections(10); -#else - const uint32 c_numRings(20); - const uint32 c_numSections(20); -#endif - const uint32 c_numSkyDomeVertices((c_numRings + 1) * (c_numSections + 1)); - const uint32 c_numSkyDomeTriangles(2 * c_numRings * c_numSections); - const uint32 c_numSkyDomeIndices(c_numSkyDomeTriangles * 3); - - std::vector< vtx_idx > skyDomeIndices; - std::vector< SVF_P3F_C4B_T2F > skyDomeVertices; - - // setup buffers with source data - skyDomeVertices.reserve(c_numSkyDomeVertices); - skyDomeIndices.reserve(c_numSkyDomeIndices); - - // calculate vertices - float sectionSlice(DEG2RAD(360.0f / (float) c_numSections)); - float ringSlice(DEG2RAD(180.0f / (float) c_numRings)); - for (uint32 a(0); a <= c_numRings; ++a) - { - float w(sinf(a * ringSlice)); - float z(cosf(a * ringSlice)); - - for (uint32 i(0); i <= c_numSections; ++i) - { - SVF_P3F_C4B_T2F v; - - float ii(i - a * 0.5f); // Gives better tessellation, requires texture address mode to be "wrap" - // for u when rendering (see v.st[ 0 ] below). Otherwise set ii = i; - v.xyz = Vec3(cosf(ii * sectionSlice) * w, sinf(ii * sectionSlice) * w, z); - assert(fabs(v.xyz.GetLengthSquared() - 1.0) < 1e-2 /*1e-4*/); // because of FP-16 precision - v.st = Vec2(ii / (float) c_numSections, 2.0f * (float) a / (float) c_numRings); - skyDomeVertices.push_back(v); - } - } - - // build faces - for (uint32 a(0); a < c_numRings; ++a) - { - for (uint32 i(0); i < c_numSections; ++i) - { - skyDomeIndices.push_back((vtx_idx) (a * (c_numSections + 1) + i + 1)); - skyDomeIndices.push_back((vtx_idx) (a * (c_numSections + 1) + i)); - skyDomeIndices.push_back((vtx_idx) ((a + 1) * (c_numSections + 1) + i + 1)); - - skyDomeIndices.push_back((vtx_idx) ((a + 1) * (c_numSections + 1) + i)); - skyDomeIndices.push_back((vtx_idx) ((a + 1) * (c_numSections + 1) + i + 1)); - skyDomeIndices.push_back((vtx_idx) (a * (c_numSections + 1) + i)); - } - } - - // sanity checks - assert(skyDomeVertices.size() == c_numSkyDomeVertices); - assert(skyDomeIndices.size() == c_numSkyDomeIndices); - - // create static buffers in renderer - m_pSkyDomeMesh = gEnv->pRenderer->CreateRenderMeshInitialized(&skyDomeVertices[0], c_numSkyDomeVertices, eVF_P3F_C4B_T2F, - &skyDomeIndices[0], c_numSkyDomeIndices, prtTriangleList, "SkyHDR", "SkyHDR"); -} - -void CSkyLightManager::ReleaseSkyDomeMesh() -{ - m_renderParams.m_pSkyDomeMesh = NULL; - m_pSkyDomeMesh = NULL; -} - -int CSkyLightManager::GetFrontBuffer() const -{ - assert(m_curBackBuffer >= 0 && m_curBackBuffer <= 1); - return((m_curBackBuffer + 1) & 1); -} - - -int CSkyLightManager::GetBackBuffer() const -{ - assert(m_curBackBuffer >= 0 && m_curBackBuffer <= 1); - return(m_curBackBuffer); -} - - -void CSkyLightManager::ToggleBuffer() -{ - assert(m_curBackBuffer >= 0 && m_curBackBuffer <= 1); - //better enforce cache flushing then making PPU wait til job has been finished - m_curBackBuffer = (m_curBackBuffer + 1) & 1; - m_needRenderParamUpdate = 1; -} - -void CSkyLightManager::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pSkyLightNishita); - pSizer->AddObject(m_skyDomeTextureDataMie[0]); - pSizer->AddObject(m_skyDomeTextureDataMie[1]); - pSizer->AddObject(m_skyDomeTextureDataRayleigh[0]); - pSizer->AddObject(m_skyDomeTextureDataRayleigh[1]); -} diff --git a/Code/CryEngine/Cry3DEngine/SkyLightManager.h b/Code/CryEngine/Cry3DEngine/SkyLightManager.h deleted file mode 100644 index 9b8e545cd6..0000000000 --- a/Code/CryEngine/Cry3DEngine/SkyLightManager.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_SKYLIGHTMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_SKYLIGHTMANAGER_H -#pragma once - - -#include -#include - - -class CSkyLightNishita; -struct ITimer; - - -class CSkyLightManager - : public Cry3DEngineBase -{ -public: - struct SSkyDomeCondition - { - SSkyDomeCondition() - : m_sunIntensity(20.0f, 20.0f, 20.0f) - , m_Km(0.001f) - , m_Kr(0.00025f) - , m_g(-0.99f) - , m_rgbWaveLengths(650.0f, 570.0f, 475.0f) - , m_sunDirection(0.0f, 0.707106f, 0.707106f) - { - } - - Vec3 m_sunIntensity; - float m_Km; - float m_Kr; - float m_g; - Vec3 m_rgbWaveLengths; - Vec3 m_sunDirection; - } _ALIGN(16); - -public: - CSkyLightManager(); - ~CSkyLightManager(); - - // sky dome condition - void SetSkyDomeCondition(const SSkyDomeCondition& skyDomeCondition); - void GetCurSkyDomeCondition(SSkyDomeCondition& skyCond) const; - - // controls updates - void FullUpdate(); - void IncrementalUpdate(f32 updateRatioPerFrame, const SRenderingPassInfo& passInfo); - void SetQuality(int32 quality); - - // rendering params - const SSkyLightRenderParams* GetRenderParams() const; - - void GetMemoryUsage(ICrySizer* pSizer) const; - - void InitSkyDomeMesh(); - void ReleaseSkyDomeMesh(); - - - void UpdateInternal(int32 newFrameID, int32 numUpdates, int callerIsFullUpdate = 0); -private: - typedef std::vector SkyDomeTextureData; - -private: - bool IsSkyDomeUpdateFinished() const; - - int GetFrontBuffer() const; - int GetBackBuffer() const; - void ToggleBuffer(); -public: - void UpdateRenderParams(); -private: - void PushUpdateParams(); - -private: - SSkyDomeCondition m_curSkyDomeCondition; //current sky dome conditions - SSkyDomeCondition m_reqSkyDomeCondition[2]; //requested sky dome conditions, double buffered(engine writes async) - SSkyDomeCondition m_updatingSkyDomeCondition; //sky dome conditions the update is currently processed with - int m_updateRequested[2]; //true if an update is requested, double buffered(engine writes async) - CSkyLightNishita* m_pSkyLightNishita; - - SkyDomeTextureData m_skyDomeTextureDataMie[ 2 ]; - SkyDomeTextureData m_skyDomeTextureDataRayleigh[ 2 ]; - int32 m_skyDomeTextureTimeStamp[ 2 ]; - - bool m_bFlushFullUpdate; - - _smart_ptr m_pSkyDomeMesh; - - int32 m_numSkyDomeColorsComputed; - int32 m_curBackBuffer; - - int32 m_lastFrameID; - int32 m_needRenderParamUpdate; - - Vec3 m_curSkyHemiColor[5]; - Vec3 m_curHazeColor; - Vec3 m_curHazeColorMieNoPremul; - Vec3 m_curHazeColorRayleighNoPremul; - - Vec3 m_skyHemiColorAccum[5]; - Vec3 m_hazeColorAccum; - Vec3 m_hazeColorMieNoPremulAccum; - Vec3 m_hazeColorRayleighNoPremulAccum; - - SSkyLightRenderParams m_renderParams _ALIGN(16); -} _ALIGN(128); - - -#endif // CRYINCLUDE_CRY3DENGINE_SKYLIGHTMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/SkyLightNishita.cpp b/Code/CryEngine/Cry3DEngine/SkyLightNishita.cpp deleted file mode 100644 index 260130556e..0000000000 --- a/Code/CryEngine/Cry3DEngine/SkyLightNishita.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#define IGNORE_ASSERTS -#if defined(_DEBUG) && defined(IGNORE_ASSERTS) -# undef assert -# define assert(cond) ((void)0) -#endif - -#include "SkyLightNishita.h" - -#include - -// constant definitions (all heights & radii given in km or km^-1 ) -const f64 c_maxAtmosphereHeight(100.0); -const f64 c_earthRadius(6368.0); -const f32 c_earthRadiusf(6368.0f); -const f64 c_avgDensityHeightMieInv(1.0 / 1.2); -const f64 c_avgDensityHeightRayleighInv(1.0 / 7.994); - -const f64 c_opticalDepthWhenHittingEarth(1e10); - -const f64 c_pi(3.1415926535897932384626433832795); -const f32 c_pif(3.1415926535897932384626433832795f); - -// Machine epsilon is too small to catch rounding error asserts here. We use a large enough number to prevent rounding errors, but small -// enough to still catch invalid conditions (10^-6). -static const float floatDiffFactor = 0.000001f; - -// constants for optical LUT serialization -const uint32 c_lutFileTag(0x4C594B53); // "SKYL" -const uint32 c_lutFileVersion(0x00010002); -const char c_lutFileName[] = "engineassets/sky/optical.lut"; - -static inline f64 MapSaveExpArg(f64 arg) -{ - const f64 c_saveExpArgRange((f64)650.0); // -650.0 to 650 range is safe not to introduce fp over-/underflows - return((arg < -c_saveExpArgRange) ? -c_saveExpArgRange : (arg > c_saveExpArgRange) ? c_saveExpArgRange : arg); -} - - -static inline f64 exp_precise(f64 arg) -{ - return(exp(MapSaveExpArg((f64) arg))); -} - -namespace -{ - union eco - { - f64 d; - struct - { - int32 i, j; - } n; - }; -} - -static inline f64 exp_fast(f64 arg) -{ - const f64 eco_m(1048576L / 0.693147180559945309417232121458177); - const f64 eco_a(1072693248L - 60801L); - -#if defined(_CPU_X86) || defined(_CPU_AMD64) || defined(_CPU_ARM)// for little endian (tested on Win32 / Win64) - eco e; -# ifdef _DEBUG - e.d = 1.0; - assert(e.n.j - 1072693248L || e.n.i == 0); // check IEEE-754 conformance -# endif - e.n.j = (int32) (eco_m * MapSaveExpArg(arg) + eco_a); - return((f64)e.d); -#elif defined(_CPU_G5) - eco e; -# ifdef _DEBUG - e.d = 1.0; - assert(e.n.i == 1072693248L || e.n.j == 0); // check IEEE-754 conformance -# endif - e.n.i = (int32) (eco_m * MapSaveExpArg(arg) + eco_a); - return((f64)e.d); -#else // fall back to default exp_sky() implementation for untested/unsupported target platforms -# pragma message( "Optimized exp_fast() not available for this platform!" ) -# pragma message( "If your target CPU is IEEE-754 conformant then please specify it in either the little or big endian branch (see SkyLightNishita.cpp::exp_fast())." ) - return(exp(arg)); -#endif -} - -static inline f64 OpticalScaleFunction(const f64& height, const f64& avgDensityHeightInv) -{ - assert(height >= 0.0); - assert(avgDensityHeightInv > 0.0 && avgDensityHeightInv <= 1.0); - return(exp_precise(-height * avgDensityHeightInv)); -} - - -static inline f64 IntegrateOpticalDepthInternal(const Vec3d& start, const f64& startScale, - const Vec3d& end, const f64& endScale, const f64& avgDensityHeightInv, const f64& error) -{ - assert(_finite(startScale) && _finite(endScale)); - - Vec3d mid(0.5 * (start + end)); - f64 midScale(OpticalScaleFunction(mid.GetLength() - c_earthRadius, avgDensityHeightInv)); - - if (fabs(startScale - midScale) <= error && fabs(midScale - endScale) <= error) - { - // integrate section this via simpson rule and stop recursing - const f64 c_oneSixth(1.0 / 6.0); - return((startScale + 4.0 * midScale + endScale) * c_oneSixth * (end - start).GetLength()); - } - else - { - // refine section via recursing down left and right branch - return(IntegrateOpticalDepthInternal(start, startScale, mid, midScale, avgDensityHeightInv, error) + - IntegrateOpticalDepthInternal(mid, midScale, end, endScale, avgDensityHeightInv, error)); - } -} - - -CSkyLightNishita::CSkyLightNishita() - : m_opticalDepthLUT() - , m_opticalScaleLUT() - , m_phaseLUT() - , m_Km(0.0f) - , m_Kr(0.0f) - , m_sunIntensity(20.0f, 20.0f, 20.0f) - , m_g(0.0f) - , m_invRGBWaveLength4(1.0f, 1.0f, 1.0f) - , m_sunDir(0.0f, 0.707106f, 0.707106f) - , m_inScatteringStepSize(1) -{ - SetRGBWaveLengths(Vec3(650.0f, 570.0f, 475.0f)); - SetSunDirection(Vec3(0.0f, 0.707106f, 0.707106f)); - SetAtmosphericConditions(Vec3(20.0f, 20.0f, 20.0f), 0.001f, 0.00025f, -0.99f); - ILog* pLog(C3DEngine::GetLog()); - if (false == LoadOpticalLUTs()) - { - if (0 != pLog) - { - PrintMessage("Sky light: Optical lookup tables couldn't be loaded off disc. Recomputation needed!"); - } - ComputeOpticalLUTs(); - } - else - { - if (0 != pLog) - { - PrintMessage("Sky light: Optical lookup tables loaded off disc."); - } - } -} - - -CSkyLightNishita::~CSkyLightNishita() -{ -} - - -CSkyLightNishita::SOpticalDepthLUTEntry CSkyLightNishita::LookupBilerpedOpticalDepthLUTEntry( - const SOpticalDepthLUTEntry* const __restrict cpOptDepthLUT, - uint32 heightIndex, const f32 cosVertAngle) const -{ - uint32 vertAngleIndex; - f32 vertAngleIndexFrc; - f32 saveCosVertAngle(clamp_tpl(cosVertAngle, -1.0f, 1.0f)); - f32 _index((f32) (cOLUT_AngularSteps - 1) * (-saveCosVertAngle * 0.5f + 0.5f)); - vertAngleIndex = (uint32) _index; - vertAngleIndexFrc = _index - floorf(_index); - - if (vertAngleIndex >= cOLUT_AngularSteps - 1) - { - return(cpOptDepthLUT[ OpticalLUTIndex(heightIndex, vertAngleIndex) ]); - } - else - { - uint32 index(OpticalLUTIndex(heightIndex, vertAngleIndex)); - const SOpticalDepthLUTEntry& a(cpOptDepthLUT[ index ]); - const SOpticalDepthLUTEntry& b(cpOptDepthLUT[ index + 1 ]); - - SOpticalDepthLUTEntry res; - res.mie = a.mie + vertAngleIndexFrc * (b.mie - a.mie); - res.rayleigh = a.rayleigh + vertAngleIndexFrc * (b.rayleigh - a.rayleigh); - return(res); - } -} - -CSkyLightNishita::SPhaseLUTEntry CSkyLightNishita::LookupBilerpedPhaseLUTEntry(const f32 cosPhaseAngle) const -{ - uint32 index; - f32 indexFrc; - MapCosPhaseAngleToIndex(cosPhaseAngle, index, indexFrc); - - if (index >= cPLUT_AngularSteps - 1) - { - return(m_phaseLUT[ cPLUT_AngularSteps - 1 ]); - } - else - { - const SPhaseLUTEntry& a(m_phaseLUT[ index + 0 ]); - const SPhaseLUTEntry& b(m_phaseLUT[ index + 1 ]); - - SPhaseLUTEntry res; - res.mie = a.mie + indexFrc * (b.mie - a.mie); - res.rayleigh = a.rayleigh + indexFrc * (b.rayleigh - a.rayleigh); - return(res); - } -} - -void CSkyLightNishita::SamplePartialInScatteringAtHeight(const SOpticalScaleLUTEntry& osAtHeight, - const f32 outScatteringConstMie, const Vec3& outScatteringConstRayleigh, const SOpticalDepthLUTEntry& odAtHeightSky, - const SOpticalDepthLUTEntry& odAtViewerSky, const SOpticalDepthLUTEntry& odAtHeightSun, - Vec3& partialInScatteringMie, Vec3& partialInScatteringRayleigh) const -{ - assert(odAtHeightSky.mie >= 0.0 && (odAtHeightSky.mie - floatDiffFactor) <= odAtViewerSky.mie); - assert(odAtHeightSun.mie >= 0.0); - assert(odAtHeightSky.rayleigh >= 0.0 && (odAtHeightSky.rayleigh - floatDiffFactor) <= odAtViewerSky.rayleigh); - assert(odAtHeightSun.rayleigh >= 0.0); - - // mie out-scattering - f32 sampleExpArgMie(outScatteringConstMie * (-odAtHeightSun.mie - (odAtViewerSky.mie - odAtHeightSky.mie))); - - // rayleigh out-scattering - Vec3 sampleExpArgRayleigh(outScatteringConstRayleigh * (-odAtHeightSun.rayleigh - (odAtViewerSky.rayleigh - odAtHeightSky.rayleigh))); - - // partial in-scattering sampling result - Vec3 sampleExpArg(Vec3(sampleExpArgMie, sampleExpArgMie, sampleExpArgMie) + sampleExpArgRayleigh); - Vec3 sampleRes((float)exp_fast(sampleExpArg.x), (float)exp_fast(sampleExpArg.y), (float)exp_fast(sampleExpArg.z)); - - partialInScatteringMie = osAtHeight.mie * sampleRes; - partialInScatteringRayleigh = osAtHeight.rayleigh * sampleRes; -} - -void CSkyLightNishita::ComputeInScatteringNoPremul(const f32 outScatteringConstMie, const Vec3& outScatteringConstRayleigh, const Vec3& skyDir, - Vec3& inScatteringMieNoPremul, Vec3& inScatteringRayleighNoPremul) const -{ - // start integration along the "skyDir" from the viewer's point of view - const Vec3 c_up(0.0f, 0.0f, 1.0f); - const Vec3 viewer(c_up * c_earthRadiusf); - Vec3 curRayPos(viewer); - - // to be reused by ray-sphere intersection code in loop below - f32 B(2.0f * viewer.Dot(skyDir)); - f32 Bsq(B * B); - f32 Cpart(viewer.Dot(viewer)); - - // calculate optical depth at viewer - const SOpticalDepthLUTEntry* const __restrict cpOptDepthLUT = &m_opticalDepthLUT[0]; - - const Vec3& cSunDir(m_sunDir); - - SOpticalDepthLUTEntry odAtViewerSky(LookupBilerpedOpticalDepthLUTEntry(cpOptDepthLUT, 0, skyDir.Dot(c_up))); - SOpticalDepthLUTEntry odAtViewerSun(LookupBilerpedOpticalDepthLUTEntry(cpOptDepthLUT, 0, cSunDir.Dot(c_up))); - - // sample partial in-scattering term at viewer - Vec3 curSampleMie, curSampleRayleigh; - - const SOpticalScaleLUTEntry* const __restrict cpOptScaleLUT = &m_opticalScaleLUT[0]; - - SamplePartialInScatteringAtHeight(cpOptScaleLUT[0], outScatteringConstMie, outScatteringConstRayleigh, - odAtViewerSky, odAtViewerSky, odAtViewerSun, curSampleMie, curSampleRayleigh); - - // integrate along "skyDir" over all height segments we've precalculated in the optical lookup table - inScatteringMieNoPremul = Vec3(0.0f, 0.0f, 0.0f); - inScatteringRayleighNoPremul = Vec3(0.0f, 0.0f, 0.0f); - const int32 cInScatteringStepSize(m_inScatteringStepSize); - for (int a(1); a < cOLUT_HeightSteps; a += cInScatteringStepSize) - { - // calculate intersection with current "atmosphere shell" - const SOpticalScaleLUTEntry& crOpticalScaleLUTEntry = cpOptScaleLUT[a]; - SOpticalScaleLUTEntry osAtHeight(crOpticalScaleLUTEntry); - - f32 C(Cpart - (c_earthRadiusf + osAtHeight.atmosphereLayerHeight) * (c_earthRadiusf + osAtHeight.atmosphereLayerHeight)); - f32 det(Bsq - 4.0f * C); - assert(det >= 0.0f && (0.5f * (-B - sqrtf(det)) <= 0.0f) && (((int)(0.5f * (-B + sqrtf(det)))*100.0) / 100.0f >= 0.0f)); - - f32 t(0.5f * (-B + sqrtf(det))); - - Vec3 newRayPos(viewer + t * skyDir); - - // calculate optical depth at new position - // since atmosphere bends we need to determine a new up vector to properly index the optical LUT - Vec3 newUp(newRayPos.GetNormalized()); - SOpticalDepthLUTEntry odAtHeightSky(LookupBilerpedOpticalDepthLUTEntry(cpOptDepthLUT, a, skyDir.Dot(newUp))); - SOpticalDepthLUTEntry odAtHeightSun(LookupBilerpedOpticalDepthLUTEntry(cpOptDepthLUT, a, cSunDir.Dot(newUp))); - - // when optimized in clang, values seem to drift a bit and under certain edge conditions - // raise asserts in SamplePartialInScatteringAtHeight function - if (odAtHeightSky.mie > odAtViewerSky.mie) - { - odAtHeightSky.mie = odAtViewerSky.mie; - } - if (odAtHeightSky.rayleigh > odAtViewerSky.rayleigh) - { - odAtHeightSky.rayleigh = odAtViewerSky.rayleigh; - } - - // sample partial in-scattering term at new position - Vec3 newSampleMie, newSampleRayleigh; - SamplePartialInScatteringAtHeight(osAtHeight, outScatteringConstMie, outScatteringConstRayleigh, - odAtHeightSky, odAtViewerSky, odAtHeightSun, newSampleMie, newSampleRayleigh); - - // integrate via trapezoid rule - f32 weight((newRayPos - curRayPos).GetLength() * 0.5f); - inScatteringMieNoPremul += (curSampleMie + newSampleMie) * weight; - inScatteringRayleighNoPremul += (curSampleRayleigh + newSampleRayleigh) * weight; - - // update sampling data - curRayPos = newRayPos; - curSampleMie = newSampleMie; - curSampleRayleigh = newSampleRayleigh; - } -} - -void CSkyLightNishita::ComputeSkyColor(const Vec3& skyDir, Vec3* pInScattering, Vec3* pInScatteringMieNoPremul, - Vec3* pInScatteringRayleighNoPremul, Vec3* pInScatteringRayleigh) const -{ - //// get high precision normalized sky direction - //Vec3 _skyDir( skyDir ); - //assert( _skyDir.GetLengthSquared() > 0.0 ); - //_skyDir.Normalize(); - - assert(fabsf(skyDir.GetLengthSquared() - 1.0f) < 1e-4f); - - SPhaseLUTEntry phaseLUTEntry(LookupBilerpedPhaseLUTEntry(-skyDir.Dot(m_sunDir))); - - // initialize constants for mie scattering - f32 phaseForPhiGMie(phaseLUTEntry.mie); - f32 outScatteringConstMie(4.0f * c_pif * m_Km); - Vec3 inScatteringConstMie(m_sunIntensity * m_Km * phaseForPhiGMie); - - // initialize constants for rayleigh scattering - f32 phaseForPhiGRayleigh(phaseLUTEntry.rayleigh); - Vec3 outScatteringConstRayleigh(4.0f * (float)c_pi * m_Kr * m_invRGBWaveLength4); - Vec3 inScatteringConstRayleigh((m_sunIntensity * m_Kr * phaseForPhiGRayleigh).CompMul(m_invRGBWaveLength4)); - - // compute in-scattering - Vec3 inScatteringMieNoPremul, inScatteringRayleighNoPremul; - - ComputeInScatteringNoPremul(outScatteringConstMie, outScatteringConstRayleigh, skyDir, inScatteringMieNoPremul, inScatteringRayleighNoPremul); - - assert(inScatteringMieNoPremul.x >= 0.0f && inScatteringMieNoPremul.y >= 0.0f && inScatteringMieNoPremul.z >= 0.0f); - assert(inScatteringRayleighNoPremul.x >= 0.0f && inScatteringRayleighNoPremul.y >= 0.0f && inScatteringRayleighNoPremul.z >= 0.0f); - - // return color - if (pInScattering) - { - *pInScattering = Vec3(inScatteringMieNoPremul.CompMul(inScatteringConstMie) + inScatteringRayleighNoPremul.CompMul(inScatteringConstRayleigh)); - } - - if (pInScatteringMieNoPremul) - { - *pInScatteringMieNoPremul = Vec3(inScatteringMieNoPremul); - } - - if (pInScatteringRayleighNoPremul) - { - *pInScatteringRayleighNoPremul = Vec3(inScatteringRayleighNoPremul); - } - - if (pInScatteringRayleigh) - { - *pInScatteringRayleigh = Vec3(inScatteringRayleighNoPremul.CompMul(inScatteringConstRayleigh)); - } -} - -void CSkyLightNishita::SetInScatteringIntegralStepSize(int32 stepSize) -{ - stepSize = stepSize < 1 ? 1 : stepSize > 2 ? 2 : stepSize; - m_inScatteringStepSize = stepSize; -} - -int32 CSkyLightNishita::GetInScatteringIntegralStepSize() const -{ - return(m_inScatteringStepSize); -} - -Vec4 CSkyLightNishita::GetPartialMieInScatteringConst() const -{ - Vec3 res(m_sunIntensity * m_Km); - return(Vec4(res.x, res.y, res.z, 0.0f)); -} - - -Vec4 CSkyLightNishita::GetPartialRayleighInScatteringConst() const -{ - Vec3 res((m_sunIntensity * m_Kr).CompMul(m_invRGBWaveLength4)); - return(Vec4(res.x, res.y, res.z, 0.0f)); -} - - -Vec3 CSkyLightNishita::GetSunDirection() const -{ - return(Vec3(m_sunDir.x, m_sunDir.y, m_sunDir.z)); -} - - -Vec4 CSkyLightNishita::GetPhaseFunctionConsts() const -{ - //f32 g2( m_g * m_g ); - //f32 miePart( 1.5f * ( 1.0f - g2 ) / ( 2.0f + g2 ) ); - //return( Vec4( m_g, m_g * m_g, miePart, 0.0f ) ); - - f32 g2(m_g * m_g); - f32 miePart(1.5f * (1.0f - g2) / (2.0f + g2)); - f32 miePartPow(powf(miePart, -2.0f / 3.0f)); - return(Vec4(miePartPow * -2.0f * m_g, miePartPow * (1.0f + g2), 0.0f, 0.0f)); -} - - -f64 CSkyLightNishita::IntegrateOpticalDepth(const Vec3d& start, const Vec3d& end, const f64& avgDensityHeightInv, const f64& error) const -{ - f64 startScale(OpticalScaleFunction(start.GetLength() - c_earthRadius, avgDensityHeightInv)); - f64 endScale(OpticalScaleFunction(end.GetLength() - c_earthRadius, avgDensityHeightInv)); - return(IntegrateOpticalDepthInternal(start, startScale, end, endScale, avgDensityHeightInv, error)); -} - - -bool CSkyLightNishita::ComputeOpticalDepth(const Vec3d& cameraLookDir, const f64& cameraHeight, const f64& avgDensityHeightInv, float& depth) const -{ - // init camera position - Vec3d cameraPos(0.0, cameraHeight + c_earthRadius, 0.0); - - // check if ray hits earth - // compute B, and C of quadratic function (A=1, as looking direction is normalized) - f64 B(2.0 * cameraPos.Dot(cameraLookDir)); - f64 Bsq(B * B); - f64 Cpart(cameraPos.Dot(cameraPos)); - f64 C(Cpart - c_earthRadius * c_earthRadius); - f64 det(Bsq - 4.0 * C); - - bool hitsEarth(det >= 0.0 && ((0.5 * (-B - sqrt(det)) > 1e-4) || (0.5 * (-B + sqrt(det)) > 1e-4))); - if (false != hitsEarth) - { - depth = (float)c_opticalDepthWhenHittingEarth; - return(false); - } - - // find intersection with atmosphere top - C = Cpart - (c_maxAtmosphereHeight + c_earthRadius) * (c_maxAtmosphereHeight + c_earthRadius); - det = Bsq - 4.0 * C; - assert(det >= 0.0); // ray defined outside the atmosphere - f64 t(0.5 * (-B + sqrt(det))); - assert(t >= -1e-4); - if (t < 0.0) - { - t = 0.0; - } - - // integrate depth along ray from camera to atmosphere top - f64 _depth(0.0); - - int numInitialSamples((int) t); - numInitialSamples = (numInitialSamples < 2) ? 2 : numInitialSamples; - - Vec3d lastCameraPos(cameraPos); - for (int i(1); i < numInitialSamples; ++i) - { - Vec3d curCameraPos(cameraPos + cameraLookDir * (t * ((float) i / (float) numInitialSamples))); - _depth += IntegrateOpticalDepth(lastCameraPos, curCameraPos, avgDensityHeightInv, 1e-1); - lastCameraPos = curCameraPos; - } - - assert(_depth >= 0.0 && _depth < 1e25); - assert(0 != _finite(_depth)); - - depth = (float) _depth; - return(true); -} - - -void CSkyLightNishita::ComputeOpticalLUTs() -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - ILog* pLog(C3DEngine::GetLog()); - if (0 != pLog) - { - PrintMessage("Sky light: Computing optical lookup tables (this might take a while)... "); - } - - // reset tables - m_opticalDepthLUT.resize(0); - m_opticalDepthLUT.reserve(cOLUT_HeightSteps * cOLUT_AngularSteps); - - m_opticalScaleLUT.resize(0); - m_opticalScaleLUT.reserve(cOLUT_HeightSteps); - - // compute LUTs - for (int a(0); a < cOLUT_HeightSteps; ++a) - { - f64 height(MapIndexToHeight(a)); - - // compute optical depth - for (int i(0); i < cOLUT_AngularSteps; ++i) - { - // init looking direction of camera - f64 cosVertAngle(MapIndexToCosVertAngle(i)); - Vec3d cameraLookDir(sqrt(1.0 - cosVertAngle * cosVertAngle), cosVertAngle, 0.0); - - // compute optical depth - SOpticalDepthLUTEntry e; - bool b0(ComputeOpticalDepth(cameraLookDir, height, c_avgDensityHeightMieInv, e.mie)); - bool b1(ComputeOpticalDepth(cameraLookDir, height, c_avgDensityHeightRayleighInv, e.rayleigh)); - assert(b0 == b1); - - // blend out previous values once camera ray hits earth - if (false == b0 && false == b1 && i > 0) - { - e = m_opticalDepthLUT.back(); - e.mie = (f32) ((f32)0.5 * (e.mie + c_opticalDepthWhenHittingEarth)); - e.rayleigh = (f32) ((f32)0.5 * (e.rayleigh + c_opticalDepthWhenHittingEarth)); - } - - // store result - m_opticalDepthLUT.push_back(e); - } - - { - // compute optical scale - SOpticalScaleLUTEntry e; - e.atmosphereLayerHeight = (f32) height; - e.mie = (f32) OpticalScaleFunction(height, c_avgDensityHeightMieInv); - e.rayleigh = (f32) OpticalScaleFunction(height, c_avgDensityHeightRayleighInv); - m_opticalScaleLUT.push_back(e); - } - } - - // save LUTs for next time - SaveOpticalLUTs(); - if (0 != pLog) - { - PrintMessage(" ... done.\n"); - } -} - - -void CSkyLightNishita::ComputePhaseLUT() -{ - //ILog* pLog( C3DEngine::GetLog() ); - //if( 0 != pLog ) - // PrintMessage( "Sky light: Computing phase lookup table... " ); - - // reset tables - m_phaseLUT.resize(0); - m_phaseLUT.reserve(cPLUT_AngularSteps); - - // compute coefficients - f32 g(m_g); - f32 g2(g * g); - f32 miePart(1.5f * (1.0f - g2) / (2.0f + g2)); - - // calculate entries - for (int i(0); i < cPLUT_AngularSteps; ++i) - { - f32 cosine(MapIndexToCosPhaseAngle(i)); - f32 cosine2(cosine * cosine); - - //f32 t = 1.0f + g2 - 2.0f * g * cosine; - //if (fabsf(t) < 1e-5f) - //{ - // PrintMessage( "Sky light: g = %.10f", g ); - // PrintMessage( "Sky light: g2 = %.10f", g2 ); - // PrintMessage( "Sky light: cosine = %.10f", cosine ); - // PrintMessage( "Sky light: cosine2 = %.10f", cosine2 ); - // PrintMessage( "Sky light: t = %.10f", t ); - //} - - f32 miePhase(miePart * (1.0f + cosine2) / powf(1.0f + g2 - 2.0f * g * cosine, 1.5f)); - f32 rayleighPhase(0.75f * (1.0f + cosine2)); - - SPhaseLUTEntry e; - e.mie = (float) miePhase; - e.rayleigh = (float) rayleighPhase; - m_phaseLUT.push_back(e); - } - //if( 0 != pLog ) - // PrintMessage( " ... done.\n" ); -} - - -f64 CSkyLightNishita::MapIndexToHeight(uint32 index) const -{ - // a function that maps well to mie and rayleigh at the same time - // that is, a lot of indices will map below the average density height for mie & rayleigh scattering - assert(index < cOLUT_HeightSteps); - f64 x((f64)index / (cOLUT_HeightSteps - 1)); - return(c_maxAtmosphereHeight * exp_precise(10.0 * (x - 1.0)) * x); -} - - -f64 CSkyLightNishita::MapIndexToCosVertAngle(uint32 index) const -{ - assert(index < cOLUT_AngularSteps); - return(1.0 - 2.0 * ((f64)index / (cOLUT_AngularSteps - 1))); -} - - -f32 CSkyLightNishita::MapIndexToCosPhaseAngle(uint32 index) const -{ - assert(index < cPLUT_AngularSteps); - return(1.0f - 2.0f * ((f32)index / ((f32)cPLUT_AngularSteps - 1))); -} - - -void CSkyLightNishita::MapCosPhaseAngleToIndex(const f32 cosPhaseAngle, uint32& index, f32& indexFrc) const -{ - //assert( -1 <= cosPhaseAngle && 1 >= cosPhaseAngle ); - f32 saveCosPhaseAngle(clamp_tpl(cosPhaseAngle, -1.0f, 1.0f)); - f32 _index((f32) (cPLUT_AngularSteps - 1) * (-saveCosPhaseAngle * 0.5f + 0.5f)); - index = (uint32) _index; - indexFrc = _index - floorf(_index); -} - - -uint32 CSkyLightNishita::OpticalLUTIndex(uint32 heightIndex, uint32 cosVertAngleIndex) const -{ - assert(heightIndex < cOLUT_HeightSteps && cosVertAngleIndex < cOLUT_AngularSteps); - return(heightIndex * cOLUT_AngularSteps + cosVertAngleIndex); -} - - -bool CSkyLightNishita::LoadOpticalLUTs() -{ - auto pPak(C3DEngine::GetPak()); - if (0 != pPak) - { - AZ::IO::HandleType fileHandle = pPak->FOpen(c_lutFileName, "rb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - size_t itemsRead(0); - - // read in file tag - uint32 fileTag(0); - itemsRead = pPak->FRead(&fileTag, 1, fileHandle); - if (itemsRead != 1 || fileTag != c_lutFileTag) - { - // file tag mismatch - pPak->FClose(fileHandle); - return(false); - } - - // read in file format version - uint32 fileVersion(0); - itemsRead = pPak->FRead(&fileVersion, 1, fileHandle); - if (itemsRead != 1 || fileVersion != c_lutFileVersion) - { - // file version mismatch - pPak->FClose(fileHandle); - return(false); - } - - // read in optical depth LUT - m_opticalDepthLUT.resize(cOLUT_HeightSteps * cOLUT_AngularSteps); - itemsRead = pPak->FRead(&m_opticalDepthLUT[0], m_opticalDepthLUT.size(), fileHandle); - if (itemsRead != m_opticalDepthLUT.size()) - { - pPak->FClose(fileHandle); - return(false); - } - - // read in optical scale LUT - m_opticalScaleLUT.resize(cOLUT_HeightSteps); - itemsRead = pPak->FRead(&m_opticalScaleLUT[0], m_opticalScaleLUT.size(), fileHandle); - if (itemsRead != m_opticalScaleLUT.size()) - { - pPak->FClose(fileHandle); - return(false); - } - - // check if we read entire file - uint64_t curPos(pPak->FTell(fileHandle)); - pPak->FSeek(fileHandle, 0, SEEK_END); - uint64_t endPos(pPak->FTell(fileHandle)); - if (curPos != endPos) - { - pPak->FClose(fileHandle); - return(false); - } - - // LUT successfully read - pPak->FClose(fileHandle); - return(true); - } - } - - return(false); -} - - -void CSkyLightNishita::SaveOpticalLUTs() const -{ - // only save on little endian PCs so the load function can do proper endian swapping -#if defined(_CPU_X86) || defined(_CPU_AMD64) - auto pPak(C3DEngine::GetPak()); - if (0 != pPak) - { - AZ::IO::HandleType fileHandle = pPak->FOpen(c_lutFileName, "wb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - // write out file tag - pPak->FWrite(&c_lutFileTag, 1, sizeof(c_lutFileTag), fileHandle); - - // write out file format version - pPak->FWrite(&c_lutFileVersion, 1, sizeof(c_lutFileVersion), fileHandle); - - // write out optical depth LUT - assert(m_opticalDepthLUT.size() == cOLUT_HeightSteps * cOLUT_AngularSteps); - pPak->FWrite(&m_opticalDepthLUT[0], 1, sizeof(SOpticalDepthLUTEntry) * m_opticalDepthLUT.size(), fileHandle); - - // write out optical scale LUT - assert(m_opticalScaleLUT.size() == cOLUT_HeightSteps); - pPak->FWrite(&m_opticalScaleLUT[0], 1, sizeof(SOpticalScaleLUTEntry) * m_opticalScaleLUT.size(), fileHandle); - - // close file - pPak->FClose(fileHandle); - } - } -#endif -} diff --git a/Code/CryEngine/Cry3DEngine/SkyLightNishita.h b/Code/CryEngine/Cry3DEngine/SkyLightNishita.h deleted file mode 100644 index 74c638f063..0000000000 --- a/Code/CryEngine/Cry3DEngine/SkyLightNishita.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_H -#define CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_H -#pragma once - -#include - -class CSkyLightManager; - -class CSkyLightNishita - : public Cry3DEngineBase -{ -private: - - // size of lookup tables - static const uint32 cOLUT_HeightSteps = 32; - static const uint32 cOLUT_AngularSteps = 256; - - // definition of optical depth LUT for mie/rayleigh scattering - struct SOpticalDepthLUTEntry - { - f32 mie; - f32 rayleigh; - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - AUTO_STRUCT_INFO - } _ALIGN(8); - - // definition of optical scale LUT for mie/rayleigh scattering - struct SOpticalScaleLUTEntry - { - f32 atmosphereLayerHeight; - f32 mie; - f32 rayleigh; - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - AUTO_STRUCT_INFO - }; - - // definition lookup table entry for phase function - struct SPhaseLUTEntry - { - f32 mie; - f32 rayleigh; - } _ALIGN(8); - - // definition of lookup tables - typedef std::vector< SOpticalDepthLUTEntry > OpticalDepthLUT; - typedef std::vector< SOpticalScaleLUTEntry > OpticalScaleLUT; - - static const uint32 cPLUT_AngularSteps = 256; - //replace std::vector by a custom class with static storage - class PhaseLUT - { - SPhaseLUTEntry m_LUT[cPLUT_AngularSteps] _ALIGN(128); - size_t m_Size; - public: - PhaseLUT() - : m_Size(0) { } - SPhaseLUTEntry& operator[] (size_t index) { return m_LUT[index]; } - const SPhaseLUTEntry& operator[] (size_t index) const { return m_LUT[index]; } - void resize(size_t size) { m_Size = size; }; - void reserve(size_t) { } - void push_back(SPhaseLUTEntry& entry) { m_LUT[m_Size++] = entry; } - size_t size() const { return m_Size; } - }; - -public: - CSkyLightNishita(); - ~CSkyLightNishita(); - - // set sky dome conditions - void SetAtmosphericConditions(const Vec3& sunIntensity, const f32 Km, const f32 Kr, const f32 g); - void SetRGBWaveLengths(const Vec3& rgbWaveLengths); - void SetSunDirection(const Vec3& sunDir); - - // compute sky colors - void ComputeSkyColor(const Vec3& skyDir, Vec3* pInScattering, Vec3* pInScatteringMieNoPremul, Vec3* pInScatteringRayleighNoPremul, Vec3* pInScatteringRayleigh) const; - - void SetInScatteringIntegralStepSize(int32 stepSize); - int32 GetInScatteringIntegralStepSize() const; - - // constants for final pixel shader processing, if "no pre-multiplied in-scattering " colors are to be processed in a pixel shader - Vec4 GetPartialMieInScatteringConst() const; - Vec4 GetPartialRayleighInScatteringConst() const; - Vec3 GetSunDirection() const; - Vec4 GetPhaseFunctionConsts() const; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_opticalDepthLUT); - pSizer->AddObject(m_opticalScaleLUT); - } -private: - // mapping helpers - f64 MapIndexToHeight(uint32 index) const; - f64 MapIndexToCosVertAngle(uint32 index) const; - f32 MapIndexToCosPhaseAngle(uint32 index) const; - - void MapCosPhaseAngleToIndex(const f32 cosPhaseAngle, uint32& index, f32& indexFrc) const; - - // optical lookup table access helpers - uint32 OpticalLUTIndex(uint32 heightIndex, uint32 cosVertAngleIndex) const; - - // computes lookup tables for optical depth, etc. - void ComputeOpticalLUTs(); - - // computes lookup table for phase function - void ComputePhaseLUT(); - - // computes optical depth (helpers for ComputeOpticalLUTs()) - f64 IntegrateOpticalDepth(const Vec3d& start, const Vec3d& end, - const f64& avgDensityHeightInv, const f64& error) const; - - bool ComputeOpticalDepth(const Vec3d& cameraLookDir, const f64& cameraHeight, const f64& avgDensityHeightInv, float& depth) const; - - // does a bilinearily filtered lookup into the optical depth LUT - // SOpticalDepthLUTEntry* is passed to save address resolve operations - ILINE SOpticalDepthLUTEntry LookupBilerpedOpticalDepthLUTEntry(const SOpticalDepthLUTEntry* const __restrict cpOptDepthLUT, - uint32 heightIndex, const f32 cosVertAngle) const; - - // does a bilinearily filtered lookup into the phase LUT - SPhaseLUTEntry LookupBilerpedPhaseLUTEntry(const f32 cosPhaseAngle) const; - - // computes in-scattering - void SamplePartialInScatteringAtHeight(const SOpticalScaleLUTEntry& osAtHeight, - const f32 outScatteringConstMie, const Vec3& outScatteringConstRayleigh, const SOpticalDepthLUTEntry& odAtHeightSky, - const SOpticalDepthLUTEntry& odAtViewerSky, const SOpticalDepthLUTEntry& odAtHeightSun, - Vec3& partialInScatteringMie, Vec3& partialInScatteringRayleigh) const; - - void ComputeInScatteringNoPremul(const f32 outScatteringConstMie, const Vec3& outScatteringConstRayleigh, const Vec3& skyDir, - Vec3& inScatteringMieNoPremul, Vec3& inScatteringRayleighNoPremul) const; - - // serialization of optical LUTs - bool LoadOpticalLUTs(); - void SaveOpticalLUTs() const; - - const OpticalScaleLUT& GetOpticalScaleLUT() const; - -private: - // lookup tables - OpticalDepthLUT m_opticalDepthLUT; - OpticalScaleLUT m_opticalScaleLUT; - PhaseLUT m_phaseLUT; - - // mie scattering constant - f32 m_Km; - - // rayleigh scattering constant - f32 m_Kr; - - // sun intensity - Vec3 m_sunIntensity; - - // mie scattering asymmetry factor (g is always 0.0 for rayleigh scattering) - f32 m_g; - - // wavelengths for r, g, and b to the -4th used for mie rayleigh scattering - Vec3 m_invRGBWaveLength4; - - // direction towards the sun - Vec3 m_sunDir; - - // step size for solving in-scattering integral - int32 m_inScatteringStepSize; - - friend class CSkyLightManager; -}; - -ILINE void CSkyLightNishita::SetRGBWaveLengths(const Vec3& rgbWaveLengths) -{ - assert(380.0f <= rgbWaveLengths.x && 780.0f >= rgbWaveLengths.x); - assert(380.0f <= rgbWaveLengths.y && 780.0f >= rgbWaveLengths.y); - assert(380.0f <= rgbWaveLengths.z && 780.0f >= rgbWaveLengths.z); - - m_invRGBWaveLength4.x = powf(rgbWaveLengths.x * 1e-3f, -4.0f); - m_invRGBWaveLength4.y = powf(rgbWaveLengths.y * 1e-3f, -4.0f); - m_invRGBWaveLength4.z = powf(rgbWaveLengths.z * 1e-3f, -4.0f); -} - -ILINE void CSkyLightNishita::SetSunDirection(const Vec3& sunDir) -{ - assert(sunDir.GetLengthSquared() > 0.0f); - m_sunDir = sunDir; - m_sunDir.Normalize(); -} - -ILINE void CSkyLightNishita::SetAtmosphericConditions(const Vec3& sunIntensity, - const f32 Km, const f32 Kr, const f32 g) -{ - m_sunIntensity = sunIntensity; - m_Km = Km; - m_Kr = Kr; - - // update g only if it changed as phase lut needs to be rebuilt - float newg(clamp_tpl(g, -0.9995f, 0.9995f)); - if (fabsf(m_g - newg) > 1e-6f) - { - m_g = newg; - ComputePhaseLUT(); - } -} - -ILINE const CSkyLightNishita::OpticalScaleLUT& CSkyLightNishita::GetOpticalScaleLUT() const -{ - return m_opticalScaleLUT; -} - -#endif // CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_H diff --git a/Code/CryEngine/Cry3DEngine/SkyLightNishita_info.h b/Code/CryEngine/Cry3DEngine/SkyLightNishita_info.h deleted file mode 100644 index d22816717e..0000000000 --- a/Code/CryEngine/Cry3DEngine/SkyLightNishita_info.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_INFO_H -#define CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_INFO_H -#pragma once - -#include "SkyLightNishita.h" - -STRUCT_INFO_BEGIN(CSkyLightNishita::SOpticalDepthLUTEntry) -STRUCT_VAR_INFO(mie, TYPE_INFO(f32)) -STRUCT_VAR_INFO(rayleigh, TYPE_INFO(f32)) -STRUCT_INFO_END(CSkyLightNishita::SOpticalDepthLUTEntry) - -STRUCT_INFO_BEGIN(CSkyLightNishita::SOpticalScaleLUTEntry) -STRUCT_VAR_INFO(atmosphereLayerHeight, TYPE_INFO(f32)) -STRUCT_VAR_INFO(mie, TYPE_INFO(f32)) -STRUCT_VAR_INFO(rayleigh, TYPE_INFO(f32)) -STRUCT_INFO_END(CSkyLightNishita::SOpticalScaleLUTEntry) - - -#endif // CRYINCLUDE_CRY3DENGINE_SKYLIGHTNISHITA_INFO_H diff --git a/Code/CryEngine/Cry3DEngine/StatObj.h b/Code/CryEngine/Cry3DEngine/StatObj.h deleted file mode 100644 index 771d7354a5..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObj.h +++ /dev/null @@ -1,742 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_STATOBJ_H -#define CRYINCLUDE_CRY3DENGINE_STATOBJ_H -#pragma once - -#if !defined(CONSOLE) -# define SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS -#endif - -class CIndexedMesh; -class CRenderObject; -class CContentCGF; -struct CNodeCGF; -struct CMaterialCGF; -struct phys_geometry; -struct IIndexedMesh; - -#include "../Cry3DEngine/Cry3DEngineBase.h" -#include "CryArray.h" - -#include -#include -#include "RenderMeshUtils.h" -#include "GeomQuery.h" -#include - -#define MAX_PHYS_GEOMS_TYPES 4 - -struct SDeformableMeshData -{ - IGeometry* pInternalGeom; - int* pVtxMap; - unsigned int* pUsedVtx; - int* pVtxTri; - int* pVtxTriBuf; - float* prVtxValency; - Vec3* pPrevVtx; - float kViscosity; -}; - -struct SSpine -{ - ~SSpine() { delete[] pVtx; delete[] pVtxCur; delete[] pSegDim; delete[] pStiffness; delete[] pDamping; delete[] pThickness; } - SSpine() : bActive(false), pVtx(nullptr), pVtxCur(nullptr), pSegDim(nullptr), - pStiffness(nullptr), pDamping(nullptr), pThickness(nullptr), - nVtx(0), len(0.0f), navg(0.0f, 0.0f, 0.0f), idmat(0), iAttachSpine(0), iAttachSeg(0) {} - - bool bActive; - Vec3* pVtx; - Vec3* pVtxCur; - Vec4* pSegDim; - - /// Per bone UDP for stiffness, damping and thickness for touch bending vegetation - float* pStiffness; - float* pDamping; - float* pThickness; - - int nVtx; - float len; - Vec3 navg; - int idmat; - int iAttachSpine; - int iAttachSeg; -}; - -struct SClothTangentVtx -{ - int ivtxT; // for each vertex, specifies the iThisVtx->ivtxT edge, which is the closest to the vertex's tangent vector - Vec3 edge; // that edge's projection on the vertex's normal basis - int sgnNorm; // sign of phys normal * normal from the basis -}; - -struct SSkinVtx -{ - int bVolumetric; - int idx[4]; - float w[4]; - Matrix33 M; -}; - -struct SDelayedSkinParams -{ - Matrix34 mtxSkelToMesh; - IGeometry* pPhysSkel; - float r; -}; - -struct SPhysGeomThunk -{ - phys_geometry* pgeom; - int type; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const - { - // pSizer->AddObject(pgeom); - } -}; - -struct SPhysGeomArray -{ - phys_geometry* operator[](int idx) const - { - if (idx < PHYS_GEOM_TYPE_DEFAULT) - { - return idx < (int)m_array.size() ? m_array[idx].pgeom : 0; - } - else - { - int i; - for (i = m_array.size() - 1; i >= 0 && m_array[i].type != idx; i--) - { - ; - } - return i >= 0 ? m_array[i].pgeom : 0; - } - } - void SetPhysGeom(phys_geometry* pgeom, int idx = PHYS_GEOM_TYPE_DEFAULT, int type = PHYS_GEOM_TYPE_DEFAULT) - { - int i; - if (idx < PHYS_GEOM_TYPE_DEFAULT) - { - i = idx, idx = type; - } - else - { - for (i = 0; i < (int)m_array.size() && m_array[i].type != idx; i++) - { - ; - } - } - if (pgeom) - { - if (i >= (int)m_array.size()) - { - m_array.resize(i + 1); - } - m_array[i].pgeom = pgeom; - m_array[i].type = idx; - } - else if (i < (int)m_array.size()) - { - m_array.erase(m_array.begin() + i); - } - } - int GetGeomCount() { return m_array.size(); } - int GetGeomType(int idx) { return idx >= PHYS_GEOM_TYPE_DEFAULT ? idx : m_array[idx].type; } - std::vector m_array; - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_array); - } -}; - - -struct SSyncToRenderMeshContext -{ - Vec3* vmin, *vmax; - int iVtx0; - int nVtx; - strided_pointer pVtx; - int* pVtxMap; - int mask; - float rscale; - SClothTangentVtx* ctd; - strided_pointer pMeshVtx; - strided_pointer pTangents; - strided_pointer pNormals; // TODO: change Vec3 to SPipNormal - CStatObj* pObj; - AZ::LegacyJobExecutor jobExecutor; - - void Set(Vec3* _vmin, Vec3* _vmax, int _iVtx0, int _nVtx, strided_pointer _pVtx, int* _pVtxMap - , int _mask, float _rscale, SClothTangentVtx* _ctd, strided_pointer _pMeshVtx - , strided_pointer _pTangents, strided_pointer _pNormals, CStatObj* _pObj) - { - vmin = _vmin; - vmax = _vmax; - iVtx0 = _iVtx0; - nVtx = _nVtx; - pVtx = _pVtx; - pVtxMap = _pVtxMap; - mask = _mask; - rscale = _rscale; - ctd = _ctd; - pMeshVtx = _pMeshVtx; - pTangents = _pTangents; - pNormals = _pNormals; - pObj = _pObj; - } -}; - -struct CStatObj - : public IStatObj - , public IStreamCallback - , public stl::intrusive_linked_list_node - , public Cry3DEngineBase -{ - CStatObj(); - ~CStatObj(); - -public: - ////////////////////////////////////////////////////////////////////////// - // Variables. - ////////////////////////////////////////////////////////////////////////// - volatile int m_nUsers; // reference counter - - uint32 m_nLastDrawMainFrameId; - - _smart_ptr m_pRenderMesh; -#ifdef SERVER_CHECKS - CMesh* m_pMesh; // Used by the dedicated server where the render mesh doesn't exist -#endif - - CryCriticalSection m_streamingMeshLock; - _smart_ptr m_pStreamedRenderMesh; - _smart_ptr m_pMergedRenderMesh; - - // Used by hierarchical breaking to hide sub-objects that initially must be hidden. - uint64 m_nInitialSubObjHideMask; - - CIndexedMesh* m_pIndexedMesh; - volatile int m_lockIdxMesh; - - string m_szFileName; - string m_szGeomName; - string m_szProperties; - string m_szStreamingDependencyFilePath; - - int m_nLoadedTrisCount; - int m_nLoadedVertexCount; - int m_nRenderTrisCount; - int m_nRenderMatIds; - float m_fGeometricMeanFaceArea; - float m_fLodDistance; - - // Default material. - _smart_ptr m_pMaterial; - - float m_fObjectRadius; - float m_fRadiusHors; - float m_fRadiusVert; - - Vec3 m_vBoxMin, m_vBoxMax, m_vVegCenter; - - SPhysGeomArray m_arrPhysGeomInfo; - ITetrLattice* m_pLattice; - IStatObj* m_pLastBooleanOp; - float m_lastBooleanOpScale; - - _smart_ptr* m_pLODs; - IStatObj* m_pLod0; // Level 0 stat object. (Pointer to the original object of the LOD) - unsigned int m_nMinUsableLod0 : 8; // What is the minimal LOD that can be used as LOD0. - unsigned int m_nMaxUsableLod0 : 8; // What is the maximal LOD that can be used as LOD0. - unsigned int m_nMaxUsableLod : 8; // What is the maximal LOD that can be used. - unsigned int m_nLoadedLodsNum : 8; // How many lods loaded. - - - string m_cgfNodeName; - - ////////////////////////////////////////////////////////////////////////// - // Externally set flags from enum EStaticObjectFlags. - ////////////////////////////////////////////////////////////////////////// - int m_nFlags; - - ////////////////////////////////////////////////////////////////////////// - // Internal Flags. - ////////////////////////////////////////////////////////////////////////// - unsigned int m_bCheckGarbage : 1; - unsigned int m_bCanUnload : 1; - unsigned int m_bLodsLoaded : 1; - unsigned int m_bDefaultObject : 1; - unsigned int m_bOpenEdgesTested : 1; - unsigned int m_bSubObject : 1; // This is sub object. - unsigned int m_bVehicleOnlyPhysics : 1; // Object can be used for collisions with vehicles only - unsigned int m_bBreakableByGame : 1; // material is marked as breakable by game - unsigned int m_bSharesChildren : 1; // means its subobjects belong to another parent statobj - unsigned int m_bHasDeformationMorphs : 1; - unsigned int m_bTmpIndexedMesh : 1; // indexed mesh is temporary and can be deleted after MakeRenderMesh - unsigned int m_bUnmergable : 1; // Set if sub objects cannot be merged together to the single render merge. - unsigned int m_bMerged : 1; // Set if sub objects merged together to the single render merge. - unsigned int m_bMergedLODs : 1; // Set if m_pLODs were created while merging LODs - unsigned int m_bLowSpecLod0Set : 1; - unsigned int m_bHaveOcclusionProxy : 1; // If this stat object or its childs have occlusion proxy. - unsigned int m_bLodsAreLoadedFromSeparateFile : 1; - unsigned int m_bNoHitRefinement : 1; // doesn't refine bullet hits against rendermesh - unsigned int m_bDontOccludeExplosions : 1; // don't act as an explosion occluder in physics - unsigned int m_hasClothTangentsData : 1; - unsigned int m_hasSkinInfo : 1; - unsigned int m_bMeshStrippedCGF : 1; // This CGF was loaded from the Mesh Stripped CGF, (in Level Cache) - unsigned int m_isDeformable : 1; // This cgf is deformable in the sense that it has a special renderpath - unsigned int m_isProxyTooBig : 1; - unsigned int m_bHasStreamOnlyCGF : 1; - - int m_idmatBreakable; // breakable id for the physics - ////////////////////////////////////////////////////////////////////////// - - // streaming - int m_nRenderMeshMemoryUsage; - int m_nMergedMemoryUsage; - int m_arrRenderMeshesPotentialMemoryUsage[2]; - IReadStreamPtr m_pReadStream; - -#if !defined (_RELEASE) - static float s_fStreamingTime; - static int s_nBandwidth; - float m_fStreamingStart; -#endif - - ////////////////////////////////////////////////////////////////////////// - - uint16* m_pMapFaceToFace0; - union - { - SClothTangentVtx* m_pClothTangentsData; - SSkinVtx* m_pSkinInfo; - }; - SDelayedSkinParams* m_pDelayedSkinParams; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Bendable Foliage. - ////////////////////////////////////////////////////////////////////////// - SSpine* m_pSpines; - int m_nSpines; - struct SMeshBoneMapping_uint8* m_pBoneMapping; - std::vector m_chunkBoneIds; - ////////////////////////////////////////////////////////////////////////// - -private: - ////////////////////////////////////////////////////////////////////////// - // Sub objects. - ////////////////////////////////////////////////////////////////////////// - std::vector m_subObjects; - CStatObj* m_pParentObject; // Parent object (Must not be smart pointer). - CStatObj* m_pClonedSourceObject; // If this is cloned object, pointer to original source object (Must not be smart pointer). - int m_nSubObjectMeshCount; - int m_nNodeCount; - - CGeomExtents m_Extents; // Cached extents for random pos generation. - - ////////////////////////////////////////////////////////////////////////// - // Special AI/Physics parameters. - ////////////////////////////////////////////////////////////////////////// - float m_aiVegetationRadius; - float m_phys_mass; - float m_phys_density; - - ////////////////////////////////////////////////////////////////////////// - // used only in the editor - ////////////////////////////////////////////////////////////////////////// -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - float* m_pHeightmap; - int m_nHeightmapSize; - float m_fOcclusionAmount; -#endif - - SSyncToRenderMeshContext* m_pAsyncUpdateContext; - - ////////////////////////////////////////////////////////////////////////// - // Cloth data - ////////////////////////////////////////////////////////////////////////// - AZStd::vector m_clothData; - - ////////////////////////////////////////////////////////////////////////// - // METHODS. - ////////////////////////////////////////////////////////////////////////// -public: - virtual void SetDefaultObject(bool state) override { m_bDefaultObject = state; } - - ////////////////////////////////////////////////////////////////////////// - // Fast non virtual access functions. - ILINE IStatObj::SSubObject& SubObject(int nIndex) { return m_subObjects[nIndex]; }; - ILINE int SubObjectCount() const { return m_subObjects.size(); }; - ////////////////////////////////////////////////////////////////////////// - - virtual void SetCanUnload(bool value) override { m_bCanUnload = value; } - virtual bool IsUnloadable() const { return m_bCanUnload; } - virtual bool IsUnmergable() const { return m_bUnmergable; } - virtual void SetUnmergable(bool state) { m_bUnmergable = state; } - - void DisableStreaming(); - - virtual bool AreLodsLoaded() const override { return m_bLodsLoaded; } - virtual SPhysGeomArray& GetArrPhysGeomInfo() override { return m_arrPhysGeomInfo; } - - IIndexedMesh* GetIndexedMesh(bool bCreatefNone = false); - IIndexedMesh* CreateIndexedMesh(); - void ReleaseIndexedMesh(bool bRenderMeshUpdated = false); - ILINE const Vec3 GetVegCenter() { return m_vVegCenter; } - ILINE float GetRadius() { return m_fObjectRadius; } - - virtual void SetFlags(int nFlags) override { m_nFlags = nFlags; }; - virtual int GetFlags() const override { return m_nFlags; }; - virtual bool IsLodsAreLoadedFromSeparateFile() override { return m_bLodsAreLoadedFromSeparateFile; } - - virtual int GetSubObjectMeshCount() const override { return m_nSubObjectMeshCount; } - virtual void SetSubObjectMeshCount(int count) { m_nSubObjectMeshCount = count; } - - virtual unsigned int GetVehicleOnlyPhysics() { return m_bVehicleOnlyPhysics; }; - virtual int GetIDMatBreakable() { return m_idmatBreakable; }; - virtual unsigned int GetBreakableByGame() { return m_bBreakableByGame; }; - - //Note: This function checks both the children and root data - //It should really be 'has any deformable objects' - //Should eventually be refactored as part of an eventual statobj refactor. - virtual bool IsDeformable() override; - - // Loader - bool LoadCGF(const char* filename, bool bLod, unsigned long nLoadingFlags, const void* pData, const int nDataSize); - bool LoadCGF_Int(const char* filename, bool bLod, unsigned long nLoadingFlags, const void* pData, const int nDataSize); - - ////////////////////////////////////////////////////////////////////////// - void SetMaterial(_smart_ptr pMaterial); - _smart_ptr GetMaterial() { return m_pMaterial; } - const _smart_ptr GetMaterial() const { return m_pMaterial; } - ////////////////////////////////////////////////////////////////////////// - - void RenderInternal(CRenderObject* pRenderObject, uint64 nSubObjectHideMask, const CLodValue& lodValue, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw); - void RenderObjectInternal(CRenderObject* pRenderObject, int nLod, uint8 uLodDissolveRef, bool dissolveOut, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw); - void RenderSubObject(CRenderObject* pRenderObject, int nLod, - int nSubObjId, const Matrix34A& renderTM, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw); - void RenderSubObjectInternal(CRenderObject* pRenderObject, int nLod, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw); - virtual void Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo); - void RenderRenderMesh(CRenderObject* pObj, struct SInstancingInfo* pInstInfo, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - phys_geometry* GetPhysGeom(int nGeomType = PHYS_GEOM_TYPE_DEFAULT) { return m_arrPhysGeomInfo[nGeomType]; } - void SetPhysGeom(phys_geometry* pPhysGeom, int nGeomType = PHYS_GEOM_TYPE_DEFAULT) - { - m_arrPhysGeomInfo.SetPhysGeom(pPhysGeom, nGeomType); - } - ITetrLattice* GetTetrLattice() { return m_pLattice; } - - float GetAIVegetationRadius() const { return m_aiVegetationRadius; } - void SetAIVegetationRadius(float radius) { m_aiVegetationRadius = radius; } - - //! Refresh object ( reload shaders or/and object geometry ) - virtual void Refresh(int nFlags); - - IRenderMesh* GetRenderMesh() { return m_pRenderMesh; }; - void SetRenderMesh(IRenderMesh* pRM); - - const char* GetFilePath() const { return (m_szFileName); } - void SetFilePath(const char* szFileName) { m_szFileName = szFileName; } - const char* GetGeoName() { return (m_szGeomName); } - void SetGeoName(const char* szGeoName) { m_szGeomName = szGeoName; } - bool IsSameObject(const char* szFileName, const char* szGeomName); - - //set object's min/max bbox - void SetBBoxMin(const Vec3& vBBoxMin) { m_vBoxMin = vBBoxMin; } - void SetBBoxMax(const Vec3& vBBoxMax) { m_vBoxMax = vBBoxMax; } - Vec3 GetBoxMin() { return m_vBoxMin; } - Vec3 GetBoxMax() { return m_vBoxMax; } - AABB GetAABB() { return AABB(m_vBoxMin, m_vBoxMax); } - AABB GetAABB() const { return AABB(m_vBoxMin, m_vBoxMax); } - - virtual float GetExtent(EGeomForm eForm); - virtual void GetRandomPos(PosNorm& ran, EGeomForm eForm) const; - - virtual Vec3 GetHelperPos(const char* szHelperName); - virtual const Matrix34& GetHelperTM(const char* szHelperName); - - virtual float& GetRadiusVert() override { return m_fRadiusVert; } - virtual float& GetRadiusHors() override { return m_fRadiusHors; } - - virtual int AddRef(); - - virtual int Release(); - int GetNumRefs() const { return m_nUsers; } - - virtual bool IsDefaultObject() { return (m_bDefaultObject); } - - int GetLoadedTrisCount() const override { return m_nLoadedTrisCount; } - int GetRenderTrisCount() const override { return m_nRenderTrisCount; } - int GetRenderMatIds() const override { return m_nRenderMatIds; } - - // Load LODs - void SetLodObject(int nLod, IStatObj* pLod) override; - bool LoadLowLODS_Prep(bool bUseStreaming, unsigned long nLoadingFlags); - IStatObj* LoadLowLODS_Load(int nLodLevel, bool bUseStreaming, unsigned long nLoadingFlags, const void* pData, int nDataLen); - void LoadLowLODS_Finalize(int nLoadedLods, IStatObj* loadedLods[MAX_STATOBJ_LODS_NUM]); - void LoadLowLODs(bool bUseStreaming, unsigned long nLoadingFlags); - - // Free render resources for unused upper LODs. - virtual void CleanUnusedLods() override; - - virtual void FreeIndexedMesh(); - bool RenderDebugInfo(CRenderObject* pObj, const SRenderingPassInfo& passInfo); - - //! Release method. - void GetMemoryUsage(class ICrySizer* pSizer) const; - - void ShutDown(); - void Init(); - - // void CheckLoaded(); - IStatObj* GetLodObject(int nLodLevel, bool bReturnNearest = false) override; - IStatObj* GetLowestLod() override; - _smart_ptr* GetLods() override { return m_pLODs; } - int GetLoadedLodsNum() override { return m_nLoadedLodsNum; } - void SetMerged(bool state) override { m_bMerged = state; } - int GetRenderMeshMemoryUsage() const override { return m_nRenderMeshMemoryUsage; } - int FindNearesLoadedLOD(int nLodIn, bool bSearchUp = false) override; - int FindHighestLOD(int nBias) override; - - // interface IStreamCallback ----------------------------------------------------- - - void StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) override; - void StreamOnComplete(IReadStream* pStream, unsigned nError) override; - - // ------------------------------------------------------------------------------- - - void StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream) override; - void UpdateStreamingPrioriryInternal(const Matrix34A& objMatrix, float fDistance, bool bFullUpdate); - - void MakeCompiledFileName(char* szCompiledFileName, int nMaxLen); - - bool IsPhysicsExist(); - bool IsSphereOverlap(const Sphere& sSphere); - void Invalidate(bool bPhysics = false, float tolerance = 0.05f); - - IStatObj* UpdateVertices(strided_pointer pVtx, strided_pointer pNormals, int iVtx0, int nVtx, int* pVtxMap = 0, float rscale = 1.f); - bool HasSkinInfo(float skinRadius = -1.0f) { return m_hasSkinInfo && m_pSkinInfo && (skinRadius < 0.0f || m_pSkinInfo[m_nLoadedVertexCount].w[0] == skinRadius); } - void PrepareSkinData(const Matrix34& mtxSkelToMesh, IGeometry* pPhysSkel, float r = 0.0f); - IStatObj* SkinVertices(strided_pointer pSkelVtx, const Matrix34& mtxSkelToMesh); - - ////////////////////////////////////////////////////////////////////////// - // Sub objects. - ////////////////////////////////////////////////////////////////////////// - virtual int GetSubObjectCount() const { return m_subObjects.size(); } - virtual void SetSubObjectCount(int nCount); - virtual IStatObj::SSubObject* FindSubObject(const char* sNodeName); - virtual IStatObj::SSubObject* FindSubObject_StrStr(const char* sNodeName); - virtual IStatObj::SSubObject* FindSubObject_CGA(const char* sNodeName); - virtual IStatObj::SSubObject* GetSubObject(int nIndex) - { - if (nIndex >= 0 && nIndex < (int)m_subObjects.size()) - { - return &m_subObjects[nIndex]; - } - else - { - return 0; - } - } - virtual bool RemoveSubObject(int nIndex); - virtual IStatObj* GetParentObject() const { return m_pParentObject; } - virtual IStatObj* GetCloneSourceObject() const { return m_pClonedSourceObject; } - virtual bool IsSubObject() const { return m_bSubObject; }; - virtual bool CopySubObject(int nToIndex, IStatObj* pFromObj, int nFromIndex); - virtual int PhysicalizeSubobjects(IPhysicalEntity* pent, const Matrix34* pMtx, float mass, float density = 0.0f, int id0 = 0, - strided_pointer pJointsIdMap = 0, const char* szPropsOverride = 0); - virtual IStatObj::SSubObject& AddSubObject(IStatObj* pStatObj); - virtual int Physicalize(IPhysicalEntity* pent, pe_geomparams* pgp, int id = -1, const char* szPropsOverride = 0); - ////////////////////////////////////////////////////////////////////////// - - virtual bool SaveToCGF(const char* sFilename, IChunkFile** pOutChunkFile = NULL, bool bHavePhiscalProxy = false); - - //virtual IStatObj* Clone(bool bCloneChildren=true, bool nDynamic=false); - virtual IStatObj* Clone(bool bCloneGeometry, bool bCloneChildren, bool bMeshesOnly); - - virtual int SetDeformationMorphTarget(IStatObj* pDeformed); - virtual int SubobjHasDeformMorph(int iSubObj); - virtual IStatObj* DeformMorph(const Vec3& pt, float r, float strength, IRenderMesh* pWeights = 0); - - virtual IStatObj* HideFoliage(); - - virtual int Serialize(TSerialize ser); - - // Get object properties as loaded from CGF. - virtual const char* GetProperties() { return m_szProperties.c_str(); }; - virtual void SetProperties(const char* props) { m_szProperties = props; ParseProperties(); } - - virtual bool GetPhysicalProperties(float& mass, float& density); - - virtual IStatObj* GetLastBooleanOp(float& scale) { scale = m_lastBooleanOpScale; return m_pLastBooleanOp; } - - // Intersect ray with static object. - // Ray must be in object local space. - virtual bool RayIntersection(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl = 0); - virtual bool LineSegIntersection(const Lineseg& lineSeg, Vec3& hitPos, int& surfaceTypeId); - - virtual void DebugDraw(const SGeometryDebugDrawInfo& info, float fExtrdueScale = 0.01f); - virtual void GetStatistics(SStatistics& stats); - ////////////////////////////////////////////////////////////////////////// - - virtual uint64 GetInitialHideMask() { return m_nInitialSubObjHideMask; } - virtual uint64 UpdateInitialHideMask(uint64 maskAND = 0ul - 1ul, uint64 maskOR = 0) { return m_nInitialSubObjHideMask &= maskAND |= maskOR; } - - virtual void SetStreamingDependencyFilePath(const char* szFileName) - { - const bool streamingDependencyLoop = CheckForStreamingDependencyLoop(szFileName); - if (streamingDependencyLoop) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, "StatObj '%s' cannot set '%s' as a streaming dependency as it would result in a looping dependency.", GetFilePath(), szFileName); - return; - } - - m_szStreamingDependencyFilePath = szFileName; - } - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - float GetOcclusionAmount(); - void CheckUpdateObjectHeightmap(); - float GetObjectHeight(float x, float y); -#endif - - virtual int GetMaxUsableLod() const override; - virtual int GetMinUsableLod() const override; - virtual SMeshBoneMapping_uint8* GetBoneMapping() const override { return m_pBoneMapping; } - virtual int GetSpineCount() const override { return m_nSpines; } - virtual SSpine* GetSpines() const override { return m_pSpines; } - - void RenderStreamingDebugInfo(CRenderObject* pRenderObject); - void RenderCoverInfo(CRenderObject* pRenderObject); - - virtual int CountChildReferences() const override; - void ReleaseStreamableContent(); - int GetStreamableContentMemoryUsage(bool bJustForDebug = false); - virtual void ComputeGeometricMean(SMeshLodInfo& lodInfo); - virtual float GetLodDistance() const override { return m_fLodDistance; } - virtual bool UpdateStreamableComponents(float fImportance, const Matrix34A& objMatrix, bool bFullUpdate, int nNewLod) override; - void GetStreamableName(string& sName) - { - sName = m_szFileName; - if (m_szGeomName.length()) - { - sName += " - "; - sName += m_szGeomName; - } - }; - void GetStreamFilePath(stack_string& strOut); - void FillRenderObject(const SRendParams& rParams, IRenderNode* pRenderNode, _smart_ptr pMaterial, - SInstancingInfo* pInstInfo, CRenderObject*& pObj, const SRenderingPassInfo& passInfo); - virtual uint32 GetLastDrawMainFrameId() { return m_nLastDrawMainFrameId; } - - // Allow pooled allocs - static void* operator new (size_t size); - static void operator delete (void* pToFree); - - // Used in ObjMan. - void TryMergeSubObjects(bool bFromStreaming) override; - bool IsMeshStrippedCGF() const { return m_bMeshStrippedCGF; } - string& GetFileName() override { return m_szFileName; } - const string& GetFileName() const override { return m_szFileName; } - - const string& GetCGFNodeName() const override { return m_cgfNodeName; } - - int GetUserCount() const override { return m_nUsers; } - bool CheckGarbage() const override { return m_bCheckGarbage; } - void SetCheckGarbage(bool val) override { m_bCheckGarbage = val; } - IStatObj* GetLodLevel0() override { return m_pLod0; } - void SetLodLevel0(IStatObj* lod) override { m_pLod0 = lod; } - - AZStd::vector& GetClothData() override { return m_clothData; } - -protected: - // Called by async stream callback. - bool LoadStreamRenderMeshes(const char* filename, const void* pData, const int nDataSize, bool bLod); - // Called by sync stream complete callback. - void CommitStreamRenderMeshes(); - - - void MergeSubObjectsRenderMeshes(bool bFromStreaming, CStatObj* pLod0, int nLod); - void UnMergeSubObjectsRenderMeshes(); - bool CanMergeSubObjects(); - bool IsMatIDReferencedByObj(uint16 matID); - - // bool LoadCGF_Info( const char *filename ); - CStatObj* MakeStatObjFromCgfNode(CContentCGF* pCGF, CNodeCGF* pNode, bool bLod, int nLoadingFlags, AABB& commonBBox); - void ParseProperties(); - - void CalcRadiuses(); - void GetStatisticsNonRecursive(SStatistics& stats); - - - // Creates static object contents from mesh. - // Return true if successful. - _smart_ptr MakeRenderMesh(CMesh* pMesh, bool bDoRenderMesh); - void MakeRenderMesh(); - - - const char* stristr(const char* szString, const char* szSubstring) - { - int nSuperstringLength = (int)strlen(szString); - int nSubstringLength = (int)strlen(szSubstring); - - for (int nSubstringPos = 0; nSubstringPos <= nSuperstringLength - nSubstringLength; ++nSubstringPos) - { - if (_strnicmp(szString + nSubstringPos, szSubstring, nSubstringLength) == 0) - { - return szString + nSubstringPos; - } - } - return NULL; - } - - bool CheckForStreamingDependencyLoop(const char* szFilenameDependancy) const; - - void FillClothData(CMesh& mesh); - -} _ALIGN(8); - - -////////////////////////////////////////////////////////////////////////// -// Wrapper around CStatObj that allow rendering of static object with specified parameters. -////////////////////////////////////////////////////////////////////////// -class CStatObjWrapper - : public CStatObj -{ - virtual void Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo); -private: - // Reference Static Object this wrapper was created for. - CStatObj* m_pReference; -}; - -////////////////////////////////////////////////////////////////////////// -inline void InitializeSubObject(IStatObj::SSubObject& so) -{ - so.localTM.SetIdentity(); - so.name = ""; - so.properties = ""; - so.nType = STATIC_SUB_OBJECT_MESH; - so.pWeights = 0; - so.nParent = -1; - so.tm.SetIdentity(); - so.bIdentityMatrix = true; - so.bHidden = false; - so.helperSize = Vec3(0, 0, 0); - so.pStatObj = 0; - so.bShadowProxy = 0; -} - -#endif // CRYINCLUDE_CRY3DENGINE_STATOBJ_H diff --git a/Code/CryEngine/Cry3DEngine/StatObjConstr.cpp b/Code/CryEngine/Cry3DEngine/StatObjConstr.cpp deleted file mode 100644 index 4e9d41d809..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObjConstr.cpp +++ /dev/null @@ -1,2148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" - -#include "IndexedMesh.h" -#include "../RenderDll/Common/Shadow_Renderer.h" -#include -#include -#include "ObjMan.h" -#include "MatMan.h" -#include "RenderMeshMerger.h" - -#include - -#define MAX_VERTICES_MERGABLE 15000 -#define MAX_TRIS_IN_LOD_0 512 -#define TRIS_IN_LOD_WARNING_RAIO (1.5f) -// Minimal ratio of Lod(n-1)/Lod(n) polygons to consider LOD for sub-object merging. -#define MIN_TRIS_IN_MERGED_LOD_RAIO (1.5f) - -DEFINE_INTRUSIVE_LINKED_LIST(CStatObj) - -////////////////////////////////////////////////////////////////////////// -CStatObj::CStatObj() -{ - m_pAsyncUpdateContext = 0; - m_nNodeCount = 0; - m_nMergedMemoryUsage = 0; - m_nUsers = 0; // reference counter - m_nLastDrawMainFrameId = 0; -#ifdef SERVER_CHECKS - m_pMesh = NULL; -#endif - m_nFlags = 0; -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - m_fOcclusionAmount = -1; - m_pHeightmap = NULL; - m_nHeightmapSize = 0; -#endif - m_pLODs = 0; - m_lastBooleanOpScale = 1.f; - m_fGeometricMeanFaceArea = 0.f; - m_fLodDistance = 0.0f; - - Init(); -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::Init() -{ - m_pAsyncUpdateContext = 0; - m_pIndexedMesh = 0; - m_lockIdxMesh = 0; - m_nRenderTrisCount = m_nLoadedTrisCount = m_nLoadedVertexCount = 0; - m_nRenderMatIds = 0; - m_fObjectRadius = 0; - m_fRadiusHors = 0; - m_fRadiusVert = 0; - m_pParentObject = 0; - m_pClonedSourceObject = 0; - m_bVehicleOnlyPhysics = 0; - m_bBreakableByGame = 0; - m_idmatBreakable = -1; - - m_nLoadedLodsNum = 1; - m_nMinUsableLod0 = 0; - m_nMaxUsableLod0 = 0; - m_nMaxUsableLod = 0; - m_pLod0 = 0; - - m_aiVegetationRadius = -1.0f; - m_phys_mass = -1.0f; - m_phys_density = -1.0f; - - m_vBoxMin.Set(0, 0, 0); - m_vBoxMax.Set(0, 0, 0); - m_vVegCenter.Set(0, 0, 0); - - m_fGeometricMeanFaceArea = 0.f; - m_fLodDistance = 0.0f; - - m_pRenderMesh = 0; - - - m_bDefaultObject = false; - - if (m_pLODs) - { - for (int i = 0; i < MAX_STATOBJ_LODS_NUM; i++) - { - if (m_pLODs[i]) - { - m_pLODs[i]->Init(); - } - } - } - - m_pReadStream = 0; - m_nSubObjectMeshCount = 0; - - m_nRenderMeshMemoryUsage = 0; - m_arrRenderMeshesPotentialMemoryUsage[0] = m_arrRenderMeshesPotentialMemoryUsage[1] = -1; - - m_bCanUnload = false; - m_bLodsLoaded = false; - m_bDefaultObject = false; - m_bOpenEdgesTested = false; - m_bSubObject = false; - m_bSharesChildren = false; - m_bHasDeformationMorphs = false; - m_bTmpIndexedMesh = false; - m_bMerged = false; - m_bMergedLODs = false; - m_bUnmergable = false; - m_bLowSpecLod0Set = false; - m_bHaveOcclusionProxy = false; - m_bCheckGarbage = false; - m_bLodsAreLoadedFromSeparateFile = false; - m_bNoHitRefinement = false; - m_bDontOccludeExplosions = false; - m_isDeformable = false; - m_isProxyTooBig = false; - m_bHasStreamOnlyCGF = true; - - // Assign default material originally. - m_pMaterial = GetMatMan()->GetDefaultMaterial(); - - m_pLattice = 0; - m_pSpines = 0; - m_nSpines = 0; - m_pBoneMapping = 0; - m_pLastBooleanOp = 0; - m_pMapFaceToFace0 = 0; - m_pClothTangentsData = 0; - m_pSkinInfo = 0; - m_hasClothTangentsData = m_hasSkinInfo = 0; - m_pDelayedSkinParams = 0; - m_arrPhysGeomInfo.m_array.clear(); - - m_nInitialSubObjHideMask = 0; - -#if !defined (_RELEASE) - m_fStreamingStart = 0.0f; -#endif -} - -////////////////////////////////////////////////////////////////////////// -CStatObj::~CStatObj() -{ - ShutDown(); -} - -void CStatObj::ShutDown() -{ - if (m_pReadStream) - { - // We don't need this stream anymore. - m_pReadStream->Abort(); - m_pReadStream = NULL; - } - - SAFE_DELETE(m_pAsyncUpdateContext); - - // assert (IsHeapValid()); - - SAFE_DELETE(m_pIndexedMesh); - // assert (IsHeapValid()); - - for (int n = 0; n < m_arrPhysGeomInfo.GetGeomCount(); n++) - { - if (m_arrPhysGeomInfo[n]) - { - if (m_arrPhysGeomInfo[n]->pGeom->GetForeignData() == (void*)this) - { - m_arrPhysGeomInfo[n]->pGeom->SetForeignData(0, 0); - } - // Unregister geometry - CRY_PHYSICS_REPLACEMENT_ASSERT(); - } - } - m_arrPhysGeomInfo.m_array.clear(); - - m_pStreamedRenderMesh = 0; - m_pMergedRenderMesh = 0; - SetRenderMesh(0); -#ifdef SERVER_CHECKS - SAFE_DELETE(m_pMesh); -#endif - - // assert (IsHeapValid()); - - /* // SDynTexture is not accessible for 3dengine - - for(int i=0; iReleaseDynamicRT(true); - - for(int i=0; iReleaseDynamicRT(true); - */ - - SAFE_RELEASE(m_pLattice); - - if (m_pLODs) - { - for (int i = 0; i < MAX_STATOBJ_LODS_NUM; i++) - { - if (m_pLODs[i]) - { - if (m_pLODs[i]->m_pParentObject) - { - GetObjManager()->UnregisterForStreaming(m_pLODs[i]->m_pParentObject); - } - else - { - GetObjManager()->UnregisterForStreaming(m_pLODs[i]); - } - - // Sub objects do not own the LODs, so they should not delete them. - m_pLODs[i] = 0; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Handle sub-objects and parents. - ////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < m_subObjects.size(); i++) - { - CStatObj* pChildObj = (CStatObj*)m_subObjects[i].pStatObj; - if (pChildObj) - { - if (!m_bSharesChildren) - { - pChildObj->m_pParentObject = NULL; - } - GetObjManager()->UnregisterForStreaming(pChildObj); - pChildObj->Release(); - } - } - m_subObjects.clear(); - - if (m_pParentObject && !m_pParentObject->m_subObjects.empty()) - { - // Remove this StatObject from sub-objects of the parent. - SSubObject* pSubObjects = &m_pParentObject->m_subObjects[0]; - for (int i = 0, num = m_pParentObject->m_subObjects.size(); i < num; i++) - { - if (pSubObjects[i].pStatObj == this) - { - m_pParentObject->m_subObjects.erase(m_pParentObject->m_subObjects.begin() + i); - break; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - - if (m_pMapFaceToFace0) - { - delete[] m_pMapFaceToFace0; - } - m_pMapFaceToFace0 = 0; - if (m_hasClothTangentsData && !m_pClonedSourceObject) - { - delete[] m_pClothTangentsData; - } - if (m_hasSkinInfo && !m_pClonedSourceObject) - { - delete[] m_pSkinInfo; - } - m_pClothTangentsData = 0; - m_hasClothTangentsData = 0; - m_pSkinInfo = 0; - m_hasSkinInfo = 0; - - SAFE_DELETE(m_pDelayedSkinParams); - - SAFE_RELEASE(m_pClonedSourceObject); - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - m_fOcclusionAmount = -1; - SAFE_DELETE_ARRAY(m_pHeightmap); - m_pHeightmap = 0; -#endif - - GetObjManager()->UnregisterForStreaming(this); - - SAFE_DELETE_ARRAY(m_pLODs); -} - -////////////////////////////////////////////////////////////////////////// -int CStatObj::Release() -{ - // Has to be thread safe, as it can be called by a worker thread for deferred plane breaks - int newRef = CryInterlockedDecrement(&m_nUsers); - if (newRef <= 1) - { - if (m_pParentObject && m_pParentObject->m_nUsers <= 0) - { - GetObjManager()->CheckForGarbage(m_pParentObject); - } - if (newRef <= 0) - { - GetObjManager()->CheckForGarbage(this); - } - } - return newRef; -} - -////////////////////////////////////////////////////////////////////////// -void* CStatObj::operator new ([[maybe_unused]] size_t size) -{ - IObjManager* pObjManager = GetObjManager(); - assert(size == sizeof(CStatObj)); - return pObjManager->AllocateStatObj(); -} - -void CStatObj::operator delete (void* pToFree) -{ - IObjManager* pObjManager = GetObjManager(); - pObjManager->FreeStatObj((CStatObj*)pToFree); -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::FreeIndexedMesh() -{ - if (!m_lockIdxMesh) - { - WriteLock lock(m_lockIdxMesh); - delete m_pIndexedMesh; - m_pIndexedMesh = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::CalcRadiuses() -{ - if (!m_vBoxMin.IsValid() || !m_vBoxMax.IsValid()) - { - Error("CStatObj::CalcRadiuses: Invalid bbox, File name: %s", m_szFileName.c_str()); - m_vBoxMin.zero(); - m_vBoxMax.zero(); - } - - m_fObjectRadius = m_vBoxMin.GetDistance(m_vBoxMax) * 0.5f; - float dxh = (float)max(fabs(GetBoxMax().x), fabs(GetBoxMin().x)); - float dyh = (float)max(fabs(GetBoxMax().y), fabs(GetBoxMin().y)); - m_fRadiusHors = (float)sqrt_tpl(dxh * dxh + dyh * dyh); - m_fRadiusVert = (GetBoxMax().z - 0) * 0.5f;// never change this - m_vVegCenter = (m_vBoxMax + m_vBoxMin) * 0.5f; - m_vVegCenter.z = m_fRadiusVert; -} - -void CStatObj::MakeRenderMesh() -{ - if (gEnv->IsDedicated()) - { - return; - } - - FUNCTION_PROFILER_3DENGINE; - - SetRenderMesh(0); - - if (!m_pIndexedMesh || m_pIndexedMesh->GetSubSetCount() == 0) - { - return; - } - - CMesh* pMesh = m_pIndexedMesh->GetMesh(); - - m_nRenderTrisCount = 0; - ////////////////////////////////////////////////////////////////////////// - // Initialize Mesh subset material flags. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < pMesh->GetSubSetCount(); i++) - { - SMeshSubset& subset = pMesh->m_subsets[i]; - if (!(subset.nMatFlags & MTL_FLAG_NODRAW)) - { - m_nRenderTrisCount += subset.nNumIndices / 3; - } - } - ////////////////////////////////////////////////////////////////////////// - if (!m_nRenderTrisCount) - { - return; - } - - if (!(GetFlags() & STATIC_OBJECT_DYNAMIC)) - { - m_pRenderMesh = GetRenderer()->CreateRenderMesh("StatObj_Static", GetFilePath(), NULL, eRMT_Static); - } - else - { - m_pRenderMesh = GetRenderer()->CreateRenderMesh("StatObj_Dynamic", GetFilePath(), NULL, eRMT_Dynamic); - m_pRenderMesh->KeepSysMesh(true); - } - - SMeshBoneMapping_uint16* const pBoneMap = pMesh->m_pBoneMapping; - pMesh->m_pBoneMapping = 0; - uint32 nFlags = 0; - nFlags |= (!GetCVars()->e_StreamCgf && Get3DEngine()->m_bInLoad) ? FSM_SETMESH_ASYNC : 0; - m_pRenderMesh->SetMesh(*pMesh, 0, nFlags, false); - pMesh->m_pBoneMapping = pBoneMap; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::SetMaterial(_smart_ptr pMaterial) -{ - m_pMaterial = pMaterial; -} - -/////////////////////////////////////////////////////////////////////////////////////// -Vec3 CStatObj::GetHelperPos(const char* szHelperName) -{ - SSubObject* pSubObj = FindSubObject(szHelperName); - if (!pSubObj) - { - return Vec3(0, 0, 0); - } - - return Vec3(pSubObj->tm.m03, pSubObj->tm.m13, pSubObj->tm.m23); -} - -/////////////////////////////////////////////////////////////////////////////////////// -const Matrix34& CStatObj::GetHelperTM(const char* szHelperName) -{ - SSubObject* pSubObj = FindSubObject(szHelperName); - - if (!pSubObj) - { - static Matrix34 identity(IDENTITY); - return identity; - } - - return pSubObj->tm; -} - -bool CStatObj::IsSameObject(const char* szFileName, const char* szGeomName) -{ - // cmp object names - if (szGeomName) - { - if (azstricmp(szGeomName, m_szGeomName) != 0) - { - return false; - } - } - - // Normalize file name - char szFileNameNorm[MAX_PATH_LENGTH] = ""; - char* pszDest = szFileNameNorm; - const char* pszSource = szFileName; - while (*pszSource) - { - if (*pszSource == '\\') - { - *pszDest++ = '/'; - } - else - { - *pszDest++ = *pszSource; - } - pszSource++; - } - *pszDest = 0; - - // cmp file names - if (azstricmp(szFileNameNorm, m_szFileName) != 0) - { - return false; - } - - return true; -} - -void CStatObj::GetMemoryUsage(ICrySizer* pSizer) const -{ - { - SIZER_COMPONENT_NAME(pSizer, "Self"); - pSizer->AddObject(this, sizeof(*this)); - } - - { - SIZER_COMPONENT_NAME(pSizer, "subObjects"); - pSizer->AddObject(m_subObjects); - } - - { - SIZER_COMPONENT_NAME(pSizer, "Strings"); - pSizer->AddObject(m_szFileName); - pSizer->AddObject(m_szGeomName); - pSizer->AddObject(m_szProperties); - } - - { - SIZER_COMPONENT_NAME(pSizer, "Material"); - pSizer->AddObject(m_pMaterial); - } - - { - SIZER_COMPONENT_NAME(pSizer, "PhysGeomInfo"); - pSizer->AddObject(m_arrPhysGeomInfo); - } - - if (m_pLODs) - { - for (int i = 1; i < MAX_STATOBJ_LODS_NUM; i++) - { - SIZER_COMPONENT_NAME(pSizer, "StatObjLods"); - pSizer->AddObject(m_pLODs[i]); - } - } - - if (m_pIndexedMesh) - { - SIZER_COMPONENT_NAME(pSizer, "Mesh"); - pSizer->AddObject(m_pIndexedMesh); - } - - - int nVtx = 0; - if (m_pIndexedMesh) - { - nVtx = m_pIndexedMesh->GetVertexCount(); - } - else if (m_pRenderMesh) - { - nVtx = m_pRenderMesh->GetVerticesCount(); - } - - if (m_pSpines) - { - SIZER_COMPONENT_NAME(pSizer, "StatObj Foliage Data"); - pSizer->AddObject(m_pSpines, sizeof(m_pSpines[0]), m_nSpines); - if (m_pBoneMapping) - { - pSizer->AddObject(m_pBoneMapping, sizeof(m_pBoneMapping[0]), nVtx); - } - for (int i = 0; i < m_nSpines; i++) - { - pSizer->AddObject(m_pSpines[i].pVtx, sizeof(Vec3) * 2 + sizeof(Vec4), m_pSpines[i].nVtx); - } - } - - if (m_hasClothTangentsData && (!m_pClonedSourceObject || m_pClonedSourceObject == this)) - { - SIZER_COMPONENT_NAME(pSizer, "Deformable StatObj ClothTangents"); - pSizer->AddObject(m_pClothTangentsData, nVtx * sizeof(m_pClothTangentsData[0])); - } - - if (m_hasSkinInfo && (!m_pClonedSourceObject || m_pClonedSourceObject == this)) - { - SIZER_COMPONENT_NAME(pSizer, "Deformable StatObj SkinData"); - pSizer->AddObject(m_pSkinInfo, (nVtx + 1) * sizeof(m_pSkinInfo[0])); - } - - if (m_pMapFaceToFace0) - { - SIZER_COMPONENT_NAME(pSizer, "Deformable StatObj Mesh"); - pSizer->AddObject(m_pMapFaceToFace0, sizeof(m_pMapFaceToFace0[0]) * max(m_nLoadedTrisCount, m_nRenderTrisCount)); - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::SetLodObject(int nLod, IStatObj* pLod) -{ - assert(nLod > 0 && nLod < MAX_STATOBJ_LODS_NUM); - if (nLod <= 0 || nLod >= MAX_STATOBJ_LODS_NUM) - { - return; - } - - if (strstr(m_szProperties, "lowspeclod0")) - { - m_bLowSpecLod0Set = true; - } - - bool bLodCompound = pLod && (pLod->GetFlags() & STATIC_OBJECT_COMPOUND) != 0; - - if (pLod && !bLodCompound) - { - // Check if low lod decrease amount of used materials. - int nPrevLodMatIds = m_nRenderMatIds; - int nPrevLodTris = m_nLoadedTrisCount; - if (nLod > 1 && m_pLODs && m_pLODs[nLod - 1]) - { - nPrevLodMatIds = m_pLODs[nLod - 1]->m_nRenderMatIds; - nPrevLodTris = m_pLODs[nLod - 1]->m_nLoadedTrisCount; - } - - if (GetCVars()->e_LodsForceUse) - { - if ((int)m_nMaxUsableLod < nLod) - { - m_nMaxUsableLod = nLod; - } - } - else - { - int min_tris = GetCVars()->e_LodMinTtris; - if (((pLod->GetLoadedTrisCount() >= min_tris || nPrevLodTris >= (3 * min_tris) / 2) - || pLod->GetRenderMatIds() < nPrevLodMatIds) && nLod > (int)m_nMaxUsableLod) - { - m_nMaxUsableLod = nLod; - } - } - - if (m_pParentObject && (m_pParentObject->m_nMaxUsableLod < m_nMaxUsableLod)) - { - m_pParentObject->m_nMaxUsableLod = m_nMaxUsableLod; - } - - pLod->SetLodLevel0(this); - pLod->SetMaterial(m_pMaterial); // Lod must use same material as parent. - - if (pLod->GetLoadedTrisCount() > MAX_TRIS_IN_LOD_0) - { - if ((strstr(pLod->GetProperties(), "lowspeclod0") != 0) && !m_bLowSpecLod0Set) - { - m_bLowSpecLod0Set = true; - m_nMaxUsableLod0 = nLod; - } - if (!m_bLowSpecLod0Set) - { - m_nMaxUsableLod0 = nLod; - } - } - if (nLod + 1 > (int)m_nLoadedLodsNum) - { - m_nLoadedLodsNum = nLod + 1; - } - - // When assigning lod to child object. - if (m_pParentObject) - { - if (nLod + 1 > (int)m_pParentObject->m_nLoadedLodsNum) - { - m_pParentObject->m_nLoadedLodsNum = nLod + 1; - } - } - } - - if (pLod && bLodCompound) - { - m_nMaxUsableLod = nLod; - pLod->SetUnmergable(m_bUnmergable); - } - - if (!m_pLODs && pLod) - { - m_pLODs = new _smart_ptr[MAX_STATOBJ_LODS_NUM]; - } - - if (m_pLODs) - { - m_pLODs[nLod] = (CStatObj*)pLod; - } -} - -////////////////////////////////////////////////////////////////////////// -IStatObj* CStatObj::GetLodObject(int nLodLevel, bool bReturnNearest) -{ - if (nLodLevel < 1) - { - return this; - } - - if (!m_pLODs) - { - if (bReturnNearest || nLodLevel == 0) - { - return this; - } - else - { - return NULL; - } - } - - if (bReturnNearest) - { - nLodLevel = CLAMP(nLodLevel, 0, MAX_STATOBJ_LODS_NUM - 1); - } - - CStatObj* pLod = 0; - if (nLodLevel < MAX_STATOBJ_LODS_NUM) - { - pLod = m_pLODs[nLodLevel]; - - // Look up - if (bReturnNearest && !pLod) - { - // Find highest existing lod looking up. - int lod = nLodLevel; - while (lod > 0 && m_pLODs[lod] == 0) - { - lod--; - } - if (lod > 0) - { - pLod = m_pLODs[lod]; - } - else - { - pLod = this; - } - } - // Look down - if (bReturnNearest && !pLod) - { - // Find highest existing lod looking down. - for (int lod = nLodLevel + 1; lod < MAX_STATOBJ_LODS_NUM; lod++) - { - if (m_pLODs[lod]) - { - pLod = m_pLODs[lod]; - break; - } - } - } - } - - return pLod; -} - -bool CStatObj::IsPhysicsExist() -{ - return m_arrPhysGeomInfo.GetGeomCount() > 0; -} - -bool CStatObj::IsSphereOverlap(const Sphere& sSphere) -{ - if (m_pRenderMesh && Overlap::Sphere_AABB(sSphere, AABB(m_vBoxMin, m_vBoxMax))) - { // if inside bbox - int nPosStride = 0; - int nInds = m_pRenderMesh->GetIndicesCount(); - const byte* pPos = m_pRenderMesh->GetPosPtr(nPosStride, FSL_READ); - vtx_idx* pInds = m_pRenderMesh->GetIndexPtr(FSL_READ); - - if (pInds && pPos) - { - for (int i = 0; (i + 2) < nInds; i += 3) - { // test all triangles of water surface strip - Vec3 v0 = (*(Vec3*)&pPos[nPosStride * pInds[i + 0]]); - Vec3 v1 = (*(Vec3*)&pPos[nPosStride * pInds[i + 1]]); - Vec3 v2 = (*(Vec3*)&pPos[nPosStride * pInds[i + 2]]); - Vec3 vBoxMin = v0; - vBoxMin.CheckMin(v1); - vBoxMin.CheckMin(v2); - Vec3 vBoxMax = v0; - vBoxMax.CheckMax(v1); - vBoxMax.CheckMax(v2); - - if (Overlap::Sphere_AABB(sSphere, AABB(vBoxMin, vBoxMax))) - { - return true; - } - } - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::Invalidate(bool bPhysics, float tolerance) -{ - AZ_UNUSED(bPhysics); - AZ_UNUSED(tolerance); - - if (m_pIndexedMesh) - { - if (m_pIndexedMesh->GetIndexCount() > 0) - { - m_pIndexedMesh->CalcBBox(); - - m_vBoxMin = m_pIndexedMesh->m_bbox.min; - m_vBoxMax = m_pIndexedMesh->m_bbox.max; - - MakeRenderMesh(); - m_nLoadedVertexCount = m_pIndexedMesh->GetVertexCount(); - m_nLoadedTrisCount = m_pIndexedMesh->GetFaceCount(); - if (!m_nLoadedTrisCount) - { - m_nLoadedTrisCount = m_pIndexedMesh->GetIndexCount() / 3; - } - CalcRadiuses(); - } - - ReleaseIndexedMesh(true); - } - - ////////////////////////////////////////////////////////////////////////// - // Iterate through sub objects and update hide mask and sub obj mesh count. - ////////////////////////////////////////////////////////////////////////// - m_nSubObjectMeshCount = 0; - for (size_t i = 0, numsub = m_subObjects.size(); i < numsub; i++) - { - SSubObject& subObj = m_subObjects[i]; - if (subObj.pStatObj && subObj.nType == STATIC_SUB_OBJECT_MESH) - { - m_nSubObjectMeshCount++; - } - } - - UnMergeSubObjectsRenderMeshes(); -} - -////////////////////////////////////////////////////////////////////////// -IStatObj* CStatObj::Clone(bool bCloneGeometry, bool bCloneChildren, bool bMeshesOnly) -{ - if (m_bDefaultObject) - { - return this; - } - - - - CStatObj* pNewObj = new CStatObj; - - pNewObj->m_pClonedSourceObject = m_pClonedSourceObject ? m_pClonedSourceObject : this; - pNewObj->m_pClonedSourceObject->AddRef(); // Cloned object will keep a reference to this. - - pNewObj->m_nLoadedTrisCount = m_nLoadedTrisCount; - pNewObj->m_nLoadedVertexCount = m_nLoadedVertexCount; - pNewObj->m_nRenderTrisCount = m_nRenderTrisCount; - - if (bCloneGeometry) - { - if (m_bMerged) - { - UnMergeSubObjectsRenderMeshes(); - } - if (m_pIndexedMesh && !m_bMerged) - { - pNewObj->m_pIndexedMesh = new CIndexedMesh; - pNewObj->m_pIndexedMesh->Copy(*m_pIndexedMesh->GetMesh()); - } - if (m_pRenderMesh && !m_bMerged) - { - _smart_ptr pRenderMesh = GetRenderer()->CreateRenderMesh( - "StatObj_Cloned", - pNewObj->GetFilePath(), - NULL, - ((GetFlags() & STATIC_OBJECT_DYNAMIC) ? eRMT_Dynamic : eRMT_Static)); - - m_pRenderMesh->CopyTo(pRenderMesh); - pNewObj->SetRenderMesh(pRenderMesh); - } - } - else - { - if (m_pRenderMesh) - { - if (m_pMergedRenderMesh != m_pRenderMesh) - { - pNewObj->SetRenderMesh(m_pRenderMesh); - } - else - { - pNewObj->m_pRenderMesh = m_pRenderMesh; - } - } - pNewObj->m_pMergedRenderMesh = m_pMergedRenderMesh; - pNewObj->m_bMerged = m_pMergedRenderMesh != NULL; - } - - pNewObj->m_szFileName = m_szFileName; - pNewObj->m_szGeomName = m_szGeomName; - - pNewObj->m_cgfNodeName = m_cgfNodeName; - - // Default material. - pNewObj->m_pMaterial = m_pMaterial; - - //*pNewObj->m_arrSpriteTexID = *m_arrSpriteTexID; - - pNewObj->m_fObjectRadius = m_fObjectRadius; - - for (int i = 0; i < m_arrPhysGeomInfo.GetGeomCount(); i++) - { - pNewObj->m_arrPhysGeomInfo.SetPhysGeom(m_arrPhysGeomInfo[i], i, m_arrPhysGeomInfo.GetGeomType(i)); - if (pNewObj->m_arrPhysGeomInfo[i]) - { - // Remove geometry - CRY_PHYSICS_REPLACEMENT_ASSERT(); - } - } - pNewObj->m_vBoxMin = m_vBoxMin; - pNewObj->m_vBoxMax = m_vBoxMax; - pNewObj->m_vVegCenter = m_vVegCenter; - - pNewObj->m_fGeometricMeanFaceArea = m_fGeometricMeanFaceArea; - - pNewObj->m_fRadiusHors = m_fRadiusHors; - pNewObj->m_fRadiusVert = m_fRadiusVert; - - pNewObj->m_nFlags = m_nFlags | STATIC_OBJECT_CLONE; - - pNewObj->m_fLodDistance = m_fLodDistance; - - ////////////////////////////////////////////////////////////////////////// - // Internal Flags. - ////////////////////////////////////////////////////////////////////////// - pNewObj->m_bCanUnload = false; - pNewObj->m_bDefaultObject = m_bDefaultObject; - pNewObj->m_bOpenEdgesTested = m_bOpenEdgesTested; - pNewObj->m_bSubObject = false; // [anton] since parent is not copied anyway - pNewObj->m_bVehicleOnlyPhysics = m_bVehicleOnlyPhysics; - pNewObj->m_idmatBreakable = m_idmatBreakable; - pNewObj->m_bBreakableByGame = m_bBreakableByGame; - pNewObj->m_bHasDeformationMorphs = m_bHasDeformationMorphs; - pNewObj->m_bTmpIndexedMesh = m_bTmpIndexedMesh; - pNewObj->m_bHaveOcclusionProxy = m_bHaveOcclusionProxy; - pNewObj->m_bHasStreamOnlyCGF = m_bHasStreamOnlyCGF; - pNewObj->m_eStreamingStatus = m_eStreamingStatus; - ////////////////////////////////////////////////////////////////////////// - - int numSubObj = (int)m_subObjects.size(); - if (bMeshesOnly) - { - numSubObj = 0; - for (size_t i = 0; i < m_subObjects.size(); i++) - { - if (m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH) - { - numSubObj++; - } - else - { - break; - } - } - } - pNewObj->m_subObjects.reserve(numSubObj); - for (int i = 0; i < numSubObj; i++) - { - pNewObj->m_subObjects.push_back(m_subObjects[i]); - if (m_subObjects[i].pStatObj) - { - if (bCloneChildren) - { - pNewObj->m_subObjects[i].pStatObj = m_subObjects[i].pStatObj->Clone(bCloneGeometry, bCloneChildren, bMeshesOnly); - pNewObj->m_subObjects[i].pStatObj->AddRef(); - ((CStatObj*)(pNewObj->m_subObjects[i].pStatObj))->m_pParentObject = pNewObj; - } - else - { - m_subObjects[i].pStatObj->AddRef(); - ((CStatObj*)(m_subObjects[i].pStatObj))->m_nFlags |= STATIC_OBJECT_MULTIPLE_PARENTS; - } - } - } - pNewObj->m_nSubObjectMeshCount = m_nSubObjectMeshCount; - if (!bCloneChildren) - { - pNewObj->m_bSharesChildren = true; - } - - pNewObj->m_hasClothTangentsData = m_hasClothTangentsData; - if (pNewObj->m_hasClothTangentsData) - { - pNewObj->m_pClothTangentsData = m_pClothTangentsData; - } - - pNewObj->m_hasSkinInfo = m_hasSkinInfo; - if (pNewObj->m_hasSkinInfo) - { - pNewObj->m_pSkinInfo = m_pSkinInfo; - } - - return pNewObj; -} -////////////////////////////////////////////////////////////////////////// - -IIndexedMesh* CStatObj::GetIndexedMesh(bool bCreateIfNone) -{ - WriteLock lock(m_lockIdxMesh); - if (m_pIndexedMesh) - { - return m_pIndexedMesh; - } - else if (m_pRenderMesh && bCreateIfNone) - { - if (m_pRenderMesh->GetIndexedMesh(m_pIndexedMesh = new CIndexedMesh) == NULL) - { - // GetIndexMesh will free the IndexedMesh object if an allocation failed - m_pIndexedMesh = NULL; - return NULL; - } - - CMesh* pMesh = m_pIndexedMesh->GetMesh(); - if (!pMesh || pMesh->m_subsets.size() <= 0) - { - m_pIndexedMesh->Release(); - m_pIndexedMesh = 0; - return 0; - } - m_bTmpIndexedMesh = true; - - int i, j, i0 = pMesh->m_subsets[0].nFirstVertId + pMesh->m_subsets[0].nNumVerts; - for (i = j = 1; i < pMesh->m_subsets.size(); i++) - { - if (pMesh->m_subsets[i].nFirstVertId - i0 < pMesh->m_subsets[j].nFirstVertId - i0) - { - j = i; - } - } - if (j < pMesh->m_subsets.size() && pMesh->m_subsets[0].nPhysicalizeType == PHYS_GEOM_TYPE_DEFAULT && - pMesh->m_subsets[j].nPhysicalizeType != PHYS_GEOM_TYPE_DEFAULT && pMesh->m_subsets[j].nFirstVertId > i0) - { - pMesh->m_subsets[j].nNumVerts += pMesh->m_subsets[j].nFirstVertId - i0; - pMesh->m_subsets[j].nFirstVertId = i0; - } - return m_pIndexedMesh; - } - return 0; -} - -IIndexedMesh* CStatObj::CreateIndexedMesh() -{ - if (!m_pIndexedMesh) - { - m_pIndexedMesh = new CIndexedMesh(); - } - - return m_pIndexedMesh; -} - -void CStatObj::ReleaseIndexedMesh(bool bRenderMeshUpdated) -{ - WriteLock lock(m_lockIdxMesh); - if (m_bTmpIndexedMesh && m_pIndexedMesh) - { - int istart, iend; - CMesh* pMesh = m_pIndexedMesh->GetMesh(); - if (m_pRenderMesh && !bRenderMeshUpdated) - { - TRenderChunkArray& Chunks = m_pRenderMesh->GetChunks(); - for (int i = 0; i < pMesh->m_subsets.size(); i++) - { - Chunks[i].m_nMatFlags |= pMesh->m_subsets[i].nMatFlags & 1 << 30; - } - } - if (bRenderMeshUpdated && m_pBoneMapping) - { - for (int i = iend = 0; i < (int)pMesh->m_subsets.size(); i++) - { - if ((pMesh->m_subsets[i].nMatFlags & (MTL_FLAG_NOPHYSICALIZE | MTL_FLAG_NODRAW)) == MTL_FLAG_NOPHYSICALIZE) - { - for (istart = iend++; iend < (int)m_chunkBoneIds.size() && m_chunkBoneIds[iend]; iend++) - { - ; - } - if (!pMesh->m_subsets[i].nNumIndices) - { - m_chunkBoneIds.erase(m_chunkBoneIds.begin() + istart, m_chunkBoneIds.begin() + iend); - iend = istart; - } - } - } - } - m_pIndexedMesh->Release(); - m_pIndexedMesh = 0; - m_bTmpIndexedMesh = false; - } -} - -////////////////////////////////////////////////////////////////////////// -static bool SubObjectsOfCompoundHaveLOD(const CStatObj* pStatObj, int nLod) -{ - int numSubObjects = pStatObj->GetSubObjectCount(); - for (int i = 0; i < numSubObjects; ++i) - { - const IStatObj::SSubObject* pSubObject = const_cast(pStatObj)->GetSubObject(i); - if (!pSubObject) - { - continue; - } - const CStatObj* pChildObj = (const CStatObj*)pSubObject->pStatObj; - if (!pChildObj) - { - continue; - } - if (!pChildObj->m_pLODs) - { - continue; - } - const CStatObj* pLod = pChildObj->m_pLODs[nLod]; - if (pLod) - { - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::TryMergeSubObjects(bool bFromStreaming) -{ - // sub meshes merging - if (GetCVars()->e_StatObjMerge) - { - if (!m_bUnmergable && !IsDeformable()) - { - MergeSubObjectsRenderMeshes(bFromStreaming, this, 0); - - if (!bFromStreaming && !m_pLODs && m_nFlags & STATIC_OBJECT_COMPOUND) - { - // Check if LODs were not split (production mode) - for (int i = 1; i < MAX_STATOBJ_LODS_NUM; ++i) - { - if (!SubObjectsOfCompoundHaveLOD(this, i)) - { - continue; - } - - CStatObj* pStatObj = new CStatObj(); - pStatObj->m_szFileName = m_szFileName; - char lodName[32]; - azstrcpy(lodName, 32, "-mlod"); - azltoa(i, lodName + 5, AZ_ARRAY_SIZE(lodName) - 5, 10); - pStatObj->m_szFileName.append(lodName); - pStatObj->m_szGeomName = m_szGeomName; - pStatObj->m_bSubObject = true; - - SetLodObject(i, pStatObj); - m_bMergedLODs = true; - } - } - - if (m_pLODs) - { - for (int i = 1; i < MAX_STATOBJ_LODS_NUM; i++) - { - if (m_pLODs[i]) - { - m_pLODs[i]->MergeSubObjectsRenderMeshes(bFromStreaming, this, i); - } - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::MergeSubObjectsRenderMeshes(bool bFromStreaming, CStatObj* pLod0, int nLod) -{ - if (m_bUnmergable) - { - return; - } - - FUNCTION_PROFILER_3DENGINE; - LOADING_TIME_PROFILE_SECTION; - - m_bMerged = false; - m_pMergedRenderMesh = 0; - - int nSubObjCount = (int)pLod0->m_subObjects.size(); - - std::vector lstRMI; - - SRenderMeshInfoInput rmi; - - rmi.pMat = m_pMaterial; - rmi.mat.SetIdentity(); - rmi.pMesh = 0; - rmi.pSrcRndNode = 0; - - for (int s = 0; s < nSubObjCount; s++) - { - CStatObj::SSubObject* pSubObj = &pLod0->m_subObjects[s]; - if (pSubObj->pStatObj && pSubObj->nType == STATIC_SUB_OBJECT_MESH) - { - CStatObj* pStatObj = (CStatObj*)pSubObj->pStatObj->GetLodObject(nLod, true); // Get lod, if not exist get lowest existing. - if (pStatObj) - { - CryAutoCriticalSection lock(pStatObj->m_streamingMeshLock); - if (pStatObj->m_pRenderMesh || pStatObj->m_pStreamedRenderMesh) - { - rmi.pMesh = pStatObj->m_pRenderMesh ? pStatObj->m_pRenderMesh : pStatObj->m_pStreamedRenderMesh; - rmi.mat = pSubObj->tm; - rmi.bIdentityMatrix = pSubObj->bIdentityMatrix; - rmi.nSubObjectIndex = s; - lstRMI.push_back(rmi); - } - } - } - } - - _smart_ptr pMergedMesh = 0; - if (lstRMI.size() == 1 && lstRMI[0].bIdentityMatrix) - { - // If identity matrix and only mesh-subobject use it as a merged render mesh. - pMergedMesh = rmi.pMesh; - } - else if (!lstRMI.empty()) - { - SMergeInfo info; - info.sMeshName = GetFilePath(); - info.sMeshType = "StatObj_Merged"; - info.bMergeToOneRenderMesh = true; - info.pUseMaterial = m_pMaterial; - pMergedMesh = GetSharedRenderMeshMerger()->MergeRenderMeshes(&lstRMI[0], lstRMI.size(), info); - } - - if (pMergedMesh) - { - if (bFromStreaming) - { - CryAutoCriticalSection lock(m_streamingMeshLock); - m_pMergedRenderMesh = pMergedMesh; - m_pStreamedRenderMesh = pMergedMesh; - } - else - { - m_pMergedRenderMesh = pMergedMesh; - SetRenderMesh(pMergedMesh); - } - - m_bMerged = true; - if (m_pLod0) - { - // Make sure upmost lod is also marked to be merged. - m_pLod0->SetMerged(true); - } - } -} - -bool CStatObj::IsMatIDReferencedByObj(uint16 matID) -{ - //Check root obj - if (IRenderMesh* pRenderMesh = GetRenderMesh()) - { - TRenderChunkArray& Chunks = pRenderMesh->GetChunks(); - - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - if (Chunks[nChunkId].m_nMatID == matID) - { - return true; - } - } - } - - //check children - int nSubObjCount = (int)m_subObjects.size(); - for (int s = 0; s < nSubObjCount; s++) - { - CStatObj::SSubObject* pSubObj = &m_subObjects[s]; - - if (pSubObj->pStatObj) - { - CStatObj* pSubStatObj = (CStatObj*)pSubObj->pStatObj; - - if (IRenderMesh* pSubRenderMesh = pSubStatObj->GetRenderMesh()) - { - TRenderChunkArray& Chunks = pSubRenderMesh->GetChunks(); - - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - if (Chunks[nChunkId].m_nMatID == matID) - { - return true; - } - } - } - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::CanMergeSubObjects() -{ - if (gEnv->IsDedicated()) - { - return false; - } - - if (!m_clothData.empty()) - { - return false; - } - - int nSubMeshes = 0; - int nTotalVertexCount = 0; - int nTotalTriCount = 0; - int nTotalRenderChunksCount = 0; - - int nSubObjCount = (int)m_subObjects.size(); - for (int s = 0; s < nSubObjCount; s++) - { - CStatObj::SSubObject* pSubObj = &m_subObjects[s]; - if (pSubObj->pStatObj && pSubObj->nType == STATIC_SUB_OBJECT_MESH && !pSubObj->bHidden) - { - CStatObj* pStatObj = (CStatObj*)pSubObj->pStatObj; - - // Conditions to not merge subobjects - if (pStatObj->m_pMaterial != m_pMaterial || // Different materials - pStatObj->m_nSpines || // It's bendable foliage - !pStatObj->m_clothData.empty()) // It's cloth - { - return false; - } - nSubMeshes++; - nTotalVertexCount += pStatObj->m_nLoadedVertexCount; - nTotalTriCount += pStatObj->m_nLoadedTrisCount; - nTotalRenderChunksCount += pStatObj->m_nRenderMatIds; - } - } - - // Check for mat_breakable surface type in material - if (m_pMaterial) - { - int nSubMtls = m_pMaterial->GetSubMtlCount(); - if (nSubMtls > 0) - { - for (int i = 0; i < nSubMtls; ++i) - { - _smart_ptr pSubMtl = m_pMaterial->GetSafeSubMtl(i); - if (pSubMtl) - { - ISurfaceType* pSFType = pSubMtl->GetSurfaceType(); - - // This is breakable glass. - // Do not merge meshes that have procedural physics breakability in them. - if (pSFType && pSFType->GetBreakability() != 0) - { - //if mesh is streamed, we must assume the material is referenced - if (m_bMeshStrippedCGF) - { - return false; - } - else if (IsMatIDReferencedByObj((uint16)i)) - { - return false; - } - } - } - } - } - else // nSubMtls==0 - { - ISurfaceType* pSFType = m_pMaterial->GetSurfaceType(); - - // This is breakable glass. - // Do not merge meshes that have procedural physics breakability in them. - if (pSFType && pSFType->GetBreakability() != 0) - { - return false; - } - } - } - - if (nTotalVertexCount > MAX_VERTICES_MERGABLE || nSubMeshes <= 1 || nTotalRenderChunksCount <= 1) - { - return false; - } - if ((nTotalTriCount / nTotalRenderChunksCount) > GetCVars()->e_StatObjMergeMaxTrisPerDrawCall) - { - return false; // tris to draw calls ratio is already not so bad - } - return true; -} - - -////////////////////////////////////////////////////////////////////////// -void CStatObj::UnMergeSubObjectsRenderMeshes() -{ - if (m_bMerged) - { - m_bMerged = false; - m_pMergedRenderMesh = 0; - SetRenderMesh(0); - } - if (m_bMergedLODs) - { - delete[] m_pLODs; - m_pLODs = 0; - } -} - -//------------------------------------------------------------------------------ -// This function is recovered from previous FindSubObject function which was then -// changed and creating many CGA model issues (some joints never move). -CStatObj::SSubObject* CStatObj::FindSubObject_CGA(const char* sNodeName) -{ - uint32 numSubObjects = m_subObjects.size(); - for (uint32 i = 0; i < numSubObjects; i++) - { - if (azstricmp(m_subObjects[i].name.c_str(), sNodeName) == 0) - { - return &m_subObjects[i]; - } - } - return 0; -} - - -////////////////////////////////////////////////////////////////////////// -CStatObj::SSubObject* CStatObj::FindSubObject(const char* sNodeName) -{ - uint32 numSubObjects = m_subObjects.size(); - int len = 1; // some objects has ' ' in the beginning - for (; sNodeName[len] > ' ' && sNodeName[len] != ',' && sNodeName[len] != ';'; len++) - { - ; - } - for (uint32 i = 0; i < numSubObjects; i++) - { - if (_strnicmp(m_subObjects[i].name.c_str(), sNodeName, len) == 0 && m_subObjects[i].name[len] == 0) - { - return &m_subObjects[i]; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CStatObj::SSubObject* CStatObj::FindSubObject_StrStr(const char* sNodeName) -{ - uint32 numSubObjects = m_subObjects.size(); - for (uint32 i = 0; i < numSubObjects; i++) - { - if (stristr(m_subObjects[i].name.c_str(), sNodeName)) - { - return &m_subObjects[i]; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -IStatObj::SSubObject& CStatObj::AddSubObject(IStatObj* pSubObj) -{ - assert(pSubObj); - SetSubObjectCount(m_subObjects.size() + 1); - InitializeSubObject(m_subObjects[m_subObjects.size() - 1]); - m_subObjects[m_subObjects.size() - 1].pStatObj = pSubObj; - pSubObj->AddRef(); - return m_subObjects[m_subObjects.size() - 1]; -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::RemoveSubObject(int nIndex) -{ - if (nIndex >= 0 && nIndex < (int)m_subObjects.size()) - { - SSubObject* pSubObj = &m_subObjects[nIndex]; - CStatObj* pChildObj = (CStatObj*)pSubObj->pStatObj; - if (pChildObj) - { - if (!m_bSharesChildren) - { - pChildObj->m_pParentObject = NULL; - } - pChildObj->Release(); - } - m_subObjects.erase(m_subObjects.begin() + nIndex); - Invalidate(true); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::SetSubObjectCount(int nCount) -{ - // remove sub objects. - while ((int)m_subObjects.size() > nCount) - { - RemoveSubObject(m_subObjects.size() - 1); - } - - SSubObject subobj; - InitializeSubObject(subobj); - m_subObjects.resize(nCount, subobj); - - if (nCount > 0) - { - m_nFlags |= STATIC_OBJECT_COMPOUND; - } - else - { - m_nFlags &= ~STATIC_OBJECT_COMPOUND; - } - Invalidate(true); - UnMergeSubObjectsRenderMeshes(); -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::CopySubObject(int nToIndex, IStatObj* pFromObj, int nFromIndex) -{ - SSubObject* pSrcSubObj = pFromObj->GetSubObject(nFromIndex); - if (!pSrcSubObj) - { - return false; - } - - if (nToIndex >= (int)m_subObjects.size()) - { - SetSubObjectCount(nToIndex + 1); - if (pFromObj == this) - { - pSrcSubObj = pFromObj->GetSubObject(nFromIndex); - } - } - - m_subObjects[nToIndex] = *pSrcSubObj; - if (pSrcSubObj->pStatObj) - { - pSrcSubObj->pStatObj->AddRef(); - } - - Invalidate(true); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::GetPhysicalProperties(float& mass, float& density) -{ - mass = m_phys_mass; - density = m_phys_density; - if (mass < 0 && density < 0) - { - return false; - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::RayIntersection(SRayHitInfo& hitInfo, _smart_ptr pCustomMtl) -{ - Vec3 vOut; - - bool bNonDirectionalTest = hitInfo.inRay.direction.IsZero(); - - // First check if ray intersect objects bounding box. - if (!bNonDirectionalTest && !Intersect::Ray_AABB(hitInfo.inRay, AABB(m_vBoxMin, m_vBoxMax), vOut)) - { - return false; - } - - if (bNonDirectionalTest && !Overlap::AABB_AABB( - AABB(hitInfo.inRay.origin - Vec3(hitInfo.fMaxHitDistance), hitInfo.inRay.origin + Vec3(hitInfo.fMaxHitDistance)), - AABB(m_vBoxMin, m_vBoxMax))) - { - return false; - } - - if ((m_nFlags & STATIC_OBJECT_COMPOUND) && !m_bMerged) - { - SRayHitInfo hitOut; - bool bAnyHit = false; - float fMinDistance = FLT_MAX; - for (int i = 0, num = m_subObjects.size(); i < num; i++) - { - if (m_subObjects[i].pStatObj && m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH && !m_subObjects[i].bHidden) - { - if (((CStatObj*)(m_subObjects[i].pStatObj))->m_nFlags & STATIC_OBJECT_HIDDEN) - { - continue; - } - - Matrix34 invertedTM = m_subObjects[i].tm.GetInverted(); - - SRayHitInfo hit = hitInfo; - - // Transform ray into sub-object local space. - hit.inReferencePoint = invertedTM.TransformPoint(hit.inReferencePoint); - hit.inRay.origin = invertedTM.TransformPoint(hit.inRay.origin); - hit.inRay.direction = invertedTM.TransformVector(hit.inRay.direction); - - int nFirstTriangleId = hit.pHitTris ? hit.pHitTris->Count() : 0; - - if (((CStatObj*)m_subObjects[i].pStatObj)->RayIntersection(hit, pCustomMtl)) - { - if (hit.fDistance < fMinDistance) - { - hitInfo.pStatObj = m_subObjects[i].pStatObj; - bAnyHit = true; - hitOut = hit; - } - } - - // transform collected triangles from sub-object space into object space - if (hit.pHitTris) - { - for (int t = nFirstTriangleId; t < hit.pHitTris->Count(); t++) - { - SRayHitTriangle& ht = hit.pHitTris->GetAt(t); - for (int c = 0; c < 3; c++) - { - ht.v[c] = m_subObjects[i].tm.TransformPoint(ht.v[c]); - } - } - } - } - } - if (bAnyHit) - { - // Restore input ray/reference point. - hitOut.inReferencePoint = hitInfo.inReferencePoint; - hitOut.inRay = hitInfo.inRay; - - hitInfo = hitOut; - return true; - } - } - else - { - bool result = false; - IRenderMesh* pRenderMesh = m_pRenderMesh; - - // Sometimes, object has no base lod mesh. So need to hit test with low level mesh. - // If the distance from camera is larger then a base lod distance, then base lod mesh is not loaded yet. - if (!pRenderMesh && m_nMaxUsableLod > 0 && m_pLODs && m_pLODs[m_nMaxUsableLod]) - { - pRenderMesh = m_pLODs[m_nMaxUsableLod]->GetRenderMesh(); - } - - AZ_Warning("StatObj Ray Intersection", - pRenderMesh, - "No render mesh available for hit testing for statobj %s", m_szFileName.c_str()); - - if (pRenderMesh) - { - result = CRenderMeshUtils::RayIntersection(pRenderMesh, hitInfo, pCustomMtl); - if (result) - { - hitInfo.pStatObj = this; - hitInfo.pRenderMesh = pRenderMesh; - } - } - - return result; - } - - return false; -} - -bool CStatObj::LineSegIntersection(const Lineseg& lineSeg, Vec3& hitPos, int& surfaceTypeId) -{ - bool intersects = false; -#ifdef SERVER_CHECKS - if (m_pMesh) - { - int numVertices, numVerticesf16, numIndices; - Vec3* pPositions = m_pMesh->GetStreamPtrAndElementCount(CMesh::POSITIONS, 0, &numVertices); - Vec3f16* pPositionsf16 = m_pMesh->GetStreamPtrAndElementCount(CMesh::POSITIONSF16, 0, &numVerticesf16); - uint16* pIndices = m_pMesh->GetStreamPtrAndElementCount(CMesh::INDICES, 0, &numIndices); - if (numIndices && numVerticesf16) - { - DynArray::iterator itSubset; - for (itSubset = m_pMesh->m_subsets.begin(); itSubset != m_pMesh->m_subsets.end(); ++itSubset) - { - if (!(itSubset->nMatFlags & MTL_FLAG_NODRAW)) - { - int lastIndex = itSubset->nFirstIndexId + itSubset->nNumIndices; - for (int i = itSubset->nFirstIndexId; i < lastIndex; ) - { - const Vec3 v0 = pPositionsf16[pIndices[i++]].ToVec3(); - const Vec3 v1 = pPositionsf16[pIndices[i++]].ToVec3(); - const Vec3 v2 = pPositionsf16[pIndices[i++]].ToVec3(); - - if (Intersect::Lineseg_Triangle(lineSeg, v0, v2, v1, hitPos) || // Front face - Intersect::Lineseg_Triangle(lineSeg, v0, v1, v2, hitPos)) // Back face - { - _smart_ptr pMtl = m_pMaterial->GetSafeSubMtl(itSubset->nMatID); - surfaceTypeId = pMtl->GetSurfaceTypeId(); - intersects = true; - break; - } - } - } - } - } - else if (numIndices && numVertices) - { - DynArray::iterator itSubset; - for (itSubset = m_pMesh->m_subsets.begin(); itSubset != m_pMesh->m_subsets.end(); ++itSubset) - { - if (!(itSubset->nMatFlags & MTL_FLAG_NODRAW)) - { - int lastIndex = itSubset->nFirstIndexId + itSubset->nNumIndices; - for (int i = itSubset->nFirstIndexId; i < lastIndex; ) - { - const Vec3& v0 = pPositions[pIndices[i++]]; - const Vec3& v1 = pPositions[pIndices[i++]]; - const Vec3& v2 = pPositions[pIndices[i++]]; - - if (Intersect::Lineseg_Triangle(lineSeg, v0, v2, v1, hitPos) || // Front face - Intersect::Lineseg_Triangle(lineSeg, v0, v1, v2, hitPos)) // Back face - { - _smart_ptr pMtl = m_pMaterial->GetSafeSubMtl(itSubset->nMatID); - surfaceTypeId = pMtl->GetSurfaceTypeId(); - intersects = true; - break; - } - } - } - } - } - } - else -#endif - if (m_pRenderMesh) - { - m_pRenderMesh->LockForThreadAccess(); - int numIndices = m_pRenderMesh->GetIndicesCount(); - int numVertices = m_pRenderMesh->GetVerticesCount(); - if (numIndices && numVertices) - { - int posStride; - uint8* pPositions = (uint8*)m_pRenderMesh->GetPosPtr(posStride, FSL_READ); - vtx_idx* pIndices = m_pRenderMesh->GetIndexPtr(FSL_READ); - - TRenderChunkArray& Chunks = m_pRenderMesh->GetChunks(); - int nChunkCount = Chunks.size(); - for (int nChunkId = 0; nChunkId < nChunkCount; nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - if (!(pChunk->m_nMatFlags & MTL_FLAG_NODRAW)) - { - int lastIndex = pChunk->nFirstIndexId + pChunk->nNumIndices; - for (int i = pChunk->nFirstIndexId; i < lastIndex; ) - { - const Vec3& v0 = *(Vec3*)(pPositions + pIndices[i++] * posStride); - const Vec3& v1 = *(Vec3*)(pPositions + pIndices[i++] * posStride); - const Vec3& v2 = *(Vec3*)(pPositions + pIndices[i++] * posStride); - - if (Intersect::Lineseg_Triangle(lineSeg, v0, v2, v1, hitPos) || // Front face - Intersect::Lineseg_Triangle(lineSeg, v0, v1, v2, hitPos)) // Back face - { - _smart_ptr pMtl = m_pMaterial->GetSafeSubMtl(pChunk->m_nMatID); - surfaceTypeId = pMtl->GetSurfaceTypeId(); - intersects = true; - break; - } - } - } - } - } - m_pRenderMesh->UnlockStream(VSF_GENERAL); - m_pRenderMesh->UnlockIndexStream(); - m_pRenderMesh->UnLockForThreadAccess(); - } - return intersects; -} - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - -float CStatObj::GetOcclusionAmount() -{ - if (m_fOcclusionAmount < 0) - { - PrintMessage("Computing occlusion value for: %s ... ", GetFilePath()); - - float fHits = 0; - float fTests = 0; - - Matrix34 objMatrix; - objMatrix.SetIdentity(); - - Vec3 vStep = Vec3(0.5f, 0.5f, 0.5f); - - Vec3 vClosestHitPoint; - float fClosestHitDistance = 1000; - - // y-rays - for (float x = m_vBoxMin.x; x <= m_vBoxMax.x; x += vStep.x) - { - for (float z = m_vBoxMin.z; z <= m_vBoxMax.z; z += vStep.z) - { - Vec3 vStart (x, m_vBoxMin.y, z); - Vec3 vEnd (x, m_vBoxMax.y, z); - if (GetObjManager()->RayStatObjIntersection(this, objMatrix, GetMaterial(), vStart, vEnd, vClosestHitPoint, fClosestHitDistance, true)) - { - fHits++; - } - fTests++; - } - } - - // x-rays - for (float y = m_vBoxMin.y; y <= m_vBoxMax.y; y += vStep.y) - { - for (float z = m_vBoxMin.z; z <= m_vBoxMax.z; z += vStep.z) - { - Vec3 vStart (m_vBoxMin.x, y, z); - Vec3 vEnd (m_vBoxMax.x, y, z); - if (GetObjManager()->RayStatObjIntersection(this, objMatrix, GetMaterial(), vStart, vEnd, vClosestHitPoint, fClosestHitDistance, true)) - { - fHits++; - } - fTests++; - } - } - - // z-rays - for (float y = m_vBoxMin.y; y <= m_vBoxMax.y; y += vStep.y) - { - for (float x = m_vBoxMin.x; x <= m_vBoxMax.x; x += vStep.x) - { - Vec3 vStart (x, y, m_vBoxMax.z); - Vec3 vEnd (x, y, m_vBoxMin.z); - if (GetObjManager()->RayStatObjIntersection(this, objMatrix, GetMaterial(), vStart, vEnd, vClosestHitPoint, fClosestHitDistance, true)) - { - fHits++; - } - fTests++; - } - } - - m_fOcclusionAmount = fTests ? (fHits / fTests) : 0; - - PrintMessagePlus("[%.2f]", m_fOcclusionAmount); - } - - return m_fOcclusionAmount; -} - -#endif - -void CStatObj::SetRenderMesh(IRenderMesh* pRM) -{ - LOADING_TIME_PROFILE_SECTION; - - if (pRM == m_pRenderMesh) - { - return; - } - - { - CryAutoCriticalSection lock(m_streamingMeshLock); - m_pRenderMesh = pRM; - } - - - if (m_pRenderMesh) - { - m_nRenderTrisCount = 0; - m_nRenderMatIds = 0; - - TRenderChunkArray& Chunks = m_pRenderMesh->GetChunks(); - for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++) - { - CRenderChunk* pChunk = &Chunks[nChunkId]; - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - if (pChunk->nNumIndices > 0) - { - m_nRenderMatIds++; - m_nRenderTrisCount += pChunk->nNumIndices / 3; - } - } - m_nLoadedTrisCount = pRM->GetIndicesCount() / 3; - m_nLoadedVertexCount = pRM->GetVerticesCount(); - } - - // this will prepare all deformable object during loading instead when needed. - // Thus is will prevent runtime stalls (300ms when shooting a taxi with 6000 vertices) - // but will incrase memory since every deformable information needs to be loaded(500kb for the taxi) - // So this is more a workaround, the real solution would precompute the data in the RC and load - // the data only when needed into memory - if (GetCVars()->e_PrepareDeformableObjectsAtLoadTime && m_pRenderMesh && m_pDelayedSkinParams) - { - PrepareSkinData(m_pDelayedSkinParams->mtxSkelToMesh, m_pDelayedSkinParams->pPhysSkel, m_pDelayedSkinParams->r); - } -} - -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - -void CStatObj::CheckUpdateObjectHeightmap() -{ - if (m_pHeightmap) - { - return; - } - - PrintMessage("Computing object heightmap for: %s ... ", GetFilePath()); - - m_nHeightmapSize = (int)(CLAMP(max(m_vBoxMax.x - m_vBoxMin.x, m_vBoxMax.y - m_vBoxMin.y) * 16, 8, 256)); - m_pHeightmap = new float[m_nHeightmapSize * m_nHeightmapSize]; - memset(m_pHeightmap, 0, sizeof(float) * m_nHeightmapSize * m_nHeightmapSize); - - float dx = max(0.001f, (m_vBoxMax.x - m_vBoxMin.x) / m_nHeightmapSize); - float dy = max(0.001f, (m_vBoxMax.y - m_vBoxMin.y) / m_nHeightmapSize); - - Matrix34 objMatrix; - objMatrix.SetIdentity(); - - for (float x = m_vBoxMin.x + dx; x < m_vBoxMax.x - dx; x += dx) - { - for (float y = m_vBoxMin.y + dy; y < m_vBoxMax.y - dy; y += dy) - { - Vec3 vStart (x, y, m_vBoxMax.z); - Vec3 vEnd (x, y, m_vBoxMin.z); - - Vec3 vClosestHitPoint(0, 0, 0); - float fClosestHitDistance = 1000000; - - if (GetObjManager()->RayStatObjIntersection(this, objMatrix, GetMaterial(), - vStart, vEnd, vClosestHitPoint, fClosestHitDistance, false)) - { - int nX = CLAMP(int((x - m_vBoxMin.x) / dx), 0, m_nHeightmapSize - 1); - int nY = CLAMP(int((y - m_vBoxMin.y) / dy), 0, m_nHeightmapSize - 1); - m_pHeightmap[nX * m_nHeightmapSize + nY] = vClosestHitPoint.z; - } - } - } - - PrintMessagePlus("[%dx%d] done", m_nHeightmapSize, m_nHeightmapSize); -} - -float CStatObj::GetObjectHeight(float x, float y) -{ - CheckUpdateObjectHeightmap(); - - float dx = max(0.001f, (m_vBoxMax.x - m_vBoxMin.x) / m_nHeightmapSize); - float dy = max(0.001f, (m_vBoxMax.y - m_vBoxMin.y) / m_nHeightmapSize); - - int nX = CLAMP(int((x - m_vBoxMin.x) / dx), 0, m_nHeightmapSize - 1); - int nY = CLAMP(int((y - m_vBoxMin.y) / dy), 0, m_nHeightmapSize - 1); - - return m_pHeightmap[nX * m_nHeightmapSize + nY]; -} - -#endif - -////////////////////////////////////////////////////////////////////////// -int CStatObj::CountChildReferences() const -{ - // Check if it must be released. - int nChildRefs = 0; - int numChilds = (int)m_subObjects.size(); - for (int i = 0; i < numChilds; i++) - { - const IStatObj::SSubObject& so = m_subObjects[i]; - CStatObj* pChildStatObj = (CStatObj*)so.pStatObj; - if (!pChildStatObj) // All stat objects must be at the begining of the array// - { - break; - } - - // if I'm the real parent of this child, check that no-one else is referencing it, otherwise it doesn't matter if I get deleted - if (pChildStatObj->m_pParentObject == this) - { - bool bIgnoreSharedStatObj = false; - for (int k = 0; k < i; k++) - { - if (pChildStatObj == m_subObjects[k].pStatObj) - { - // If we share pointer to this stat obj then do not count it again. - bIgnoreSharedStatObj = true; - nChildRefs -= 1; // 1 reference from current object should be ignored. - break; - } - } - if (!bIgnoreSharedStatObj) - { - nChildRefs += pChildStatObj->m_nUsers - 1; // 1 reference from parent should be ignored. - } - } - } - assert(nChildRefs >= 0); - return nChildRefs; -} - -IStatObj* CStatObj::GetLowestLod() -{ - if (int nLowestLod = CStatObj::GetMinUsableLod()) - { - return m_pLODs ? (CStatObj*)m_pLODs[CStatObj::GetMinUsableLod()] : (CStatObj*)NULL; - } - return this; -} - -////////////////////////////////////////////////////////////////////////// -int CStatObj::FindHighestLOD(int nBias) -{ - int nLowestLod = CStatObj::GetMinUsableLod(); - - // if requested lod is not ready - find nearest ready one - int nLod = CLAMP((int)m_nMaxUsableLod + nBias, nLowestLod, (int)m_nMaxUsableLod); - - while (nLod && nLod >= nLowestLod && (!m_pLODs || !m_pLODs[nLod] || !m_pLODs[nLod]->GetRenderMesh())) - { - nLod--; - } - - if (nLod == 0 && !GetRenderMesh()) - { - nLod = -1; - } - - return nLod; -} - - -////////////////////////////////////////////////////////////////////////// -void CStatObj::GetStatisticsNonRecursive(SStatistics& si) -{ - CStatObj* pStatObj = this; - - for (int lod = 0; lod < MAX_STATOBJ_LODS_NUM; lod++) - { - CStatObj* pLod = (CStatObj*)pStatObj->GetLodObject(lod); - if (pLod) - { - //if (!pLod0 && pLod->GetRenderMesh()) - //pLod0 = pLod; - - if (lod > 0 && lod + 1 > si.nLods) // Assign last existing lod. - { - si.nLods = lod + 1; - } - - si.nVerticesPerLod[lod] += pLod->m_nLoadedVertexCount; - si.nIndicesPerLod[lod] += pLod->m_nLoadedTrisCount * 3; - si.nMeshSize += pLod->m_nRenderMeshMemoryUsage; - - IRenderMesh* pRenderMesh = pLod->GetRenderMesh(); - if (pRenderMesh) - { - si.nMeshSizeLoaded += pRenderMesh->GetMemoryUsage(0, IRenderMesh::MEM_USAGE_ONLY_STREAMS); - //if (si.pTextureSizer) - //pRenderMesh->GetTextureMemoryUsage(0,si.pTextureSizer); - //if (si.pTextureSizer2) - //pRenderMesh->GetTextureMemoryUsage(0,si.pTextureSizer2); - } - } - } - - si.nIndices += m_nLoadedTrisCount * 3; - si.nVertices += m_nLoadedVertexCount; - - for (int j = 0; j < pStatObj->m_arrPhysGeomInfo.GetGeomCount(); j++) - { - if (pStatObj->GetPhysGeom(j)) - { - ICrySizer* pPhysSizer = GetISystem()->CreateSizer(); - pStatObj->GetPhysGeom(j)->pGeom->GetMemoryStatistics(pPhysSizer); - int sz = pPhysSizer->GetTotalSize(); - si.nPhysProxySize += sz; - si.nPhysProxySizeMax = max(si.nPhysProxySizeMax, sz); - si.nPhysPrimitives += pStatObj->GetPhysGeom(j)->pGeom->GetPrimitiveCount(); - pPhysSizer->Release(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::GetStatistics(SStatistics& si) -{ - si.bSplitLods = m_bLodsAreLoadedFromSeparateFile; - - bool bMultiSubObj = (GetFlags() & STATIC_OBJECT_COMPOUND) != 0; - if (!bMultiSubObj) - { - GetStatisticsNonRecursive(si); - si.nSubMeshCount = 0; - si.nNumRefs = GetNumRefs(); - si.nDrawCalls = m_nRenderMatIds; - } - else - { - si.nNumRefs = GetNumRefs(); - - std::vector addedObjects; - for (int k = 0; k < GetSubObjectCount(); k++) - { - if (!GetSubObject(k)) - { - continue; - } - CStatObj* pSubObj = (CStatObj*)GetSubObject(k)->pStatObj; - - int nSubObjectType = GetSubObject(k)->nType; - if (nSubObjectType != STATIC_SUB_OBJECT_MESH && nSubObjectType != STATIC_SUB_OBJECT_HELPER_MESH) - { - continue; - } - - if (stl::find(addedObjects, pSubObj)) - { - continue; - } - addedObjects.push_back(pSubObj); - - if (pSubObj) - { - pSubObj->GetStatisticsNonRecursive(si); - si.nSubMeshCount++; - - if (nSubObjectType == STATIC_SUB_OBJECT_MESH) - { - si.nDrawCalls += pSubObj->m_nRenderMatIds; - } - - if (pSubObj->GetNumRefs() > si.nNumRefs) - { - si.nNumRefs = pSubObj->GetNumRefs(); - } - } - } - } - - // Only do rough estimation based on the material - // This is more consistent when streaming is enabled and render mesh may no exist - if (m_pMaterial) - { - if (si.pTextureSizer) - { - m_pMaterial->GetTextureMemoryUsage(si.pTextureSizer); - } - if (si.pTextureSizer2) - { - m_pMaterial->GetTextureMemoryUsage(si.pTextureSizer2); - } - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/StatObjLoad.cpp b/Code/CryEngine/Cry3DEngine/StatObjLoad.cpp deleted file mode 100644 index d9a2919855..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObjLoad.cpp +++ /dev/null @@ -1,1724 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : loading - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "IndexedMesh.h" -#include "MatMan.h" -#include "ObjMan.h" -#include "CGF/CGFLoader.h" -#include "CGF/CGFSaver.h" -#include "CGF/ReadOnlyChunkFile.h" - -#include "CryMemoryManager.h" -#include -#include -#include -#include -#include - -#define GEOM_INFO_FILE_EXT "ginfo" -#define MESH_NAME_FOR_MAIN "main" -#define PHYSICS_BREAKABLE_JOINT "$joint" - -void CStatObj::Refresh(int nFlags) -{ - if (nFlags & FRO_GEOMETRY) - { - if (m_bCheckGarbage) - { - GetObjManager()->UnregisterForGarbage(this); - } - - ShutDown(); - Init(); - bool bRes = LoadCGF(m_szFileName, false, 0, 0, 0); - - LoadLowLODs(false, 0); - TryMergeSubObjects(false); - - if (!bRes) - { // load default in case of error - ShutDown(); - Init(); - LoadCGF("objects/default.cgf", 0, 0, 0, 0); - m_bDefaultObject = true; - } - - return; - } -} - -void CStatObj::LoadLowLODs(bool bUseStreaming, unsigned long nLoadingFlags) -{ - if (!LoadLowLODS_Prep(bUseStreaming, nLoadingFlags)) - { - return; - } - - int nLoadedLods = 1; - IStatObj* loadedLods[MAX_STATOBJ_LODS_NUM]; - for (int nLodLevel = 0; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++) - { - loadedLods[nLodLevel] = 0; - } - - for (int nLodLevel = 1; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++) - { - IStatObj* pLodStatObj = LoadLowLODS_Load(nLodLevel, bUseStreaming, nLoadingFlags, NULL, 0); - if (!pLodStatObj) - { - break; - } - nLoadedLods++; - - loadedLods[nLodLevel] = pLodStatObj; - } - - LoadLowLODS_Finalize(nLoadedLods, loadedLods); -} - -bool CStatObj::LoadLowLODS_Prep([[maybe_unused]] bool bUseStreaming, unsigned long nLoadingFlags) -{ - m_bLodsLoaded = true; - - if (nLoadingFlags & ELoadingFlagsIgnoreLoDs) - { - return false; - } - - const char* sFileExt = PathUtil::GetExt(m_szFileName); - - if (m_nLoadedLodsNum > 1 && GetFlags() & STATIC_OBJECT_COMPOUND) - { - for (int nLodLevel = 1; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++) - { - // make lod file name - char sLodFileName[512]; - char sLodNum[8]; - cry_strcpy(sLodFileName, m_szFileName); - char* sPointSeparator = strchr(sLodFileName, '.'); - if (sPointSeparator) - { - *sPointSeparator = '\0'; // Terminate at the dot - } - cry_strcat(sLodFileName, "_lod"); - azltoa(nLodLevel, sLodNum, AZ_ARRAY_SIZE(sLodNum), 10); - cry_strcat(sLodFileName, sLodNum); - cry_strcat(sLodFileName, "."); - cry_strcat(sLodFileName, sFileExt); - - if (IsValidFile(sLodFileName)) - { - m_nLoadedLodsNum = 1; - break; - } - } - } - - if (m_nLoadedLodsNum > 1) - { - return false; - } - - m_nLoadedLodsNum = 1; - - if (!GetCVars()->e_Lods) - { - return false; - } - - if (m_bSubObject) // Never do this for sub objects. - { - return false; - } - - return true; -} - -IStatObj* CStatObj::LoadLowLODS_Load(int nLodLevel, bool bUseStreaming, unsigned long nLoadingFlags, const void* pData, int nDataLen) -{ - const char* sFileExt = PathUtil::GetExt(m_szFileName); - - // make lod file name - char sLodFileName[512]; - char sLodNum[8]; - cry_strcpy(sLodFileName, m_szFileName); - char* sPointSeparator = strchr(sLodFileName, '.'); - if (sPointSeparator) - { - *sPointSeparator = '\0'; // Terminate at the dot - } - cry_strcat(sLodFileName, "_lod"); - azltoa(nLodLevel, sLodNum, AZ_ARRAY_SIZE(sLodNum), 10); - cry_strcat(sLodFileName, sLodNum); - cry_strcat(sLodFileName, "."); - cry_strcat(sLodFileName, sFileExt); - - IStatObj* pLodStatObj = m_pLODs ? (IStatObj*)m_pLODs[nLodLevel] : nullptr; - - // try to load - bool bRes = false; - - string lowerFileName(sLodFileName); - pLodStatObj = stl::find_in_map(m_pObjManager->GetNameToObjectMap(), CONST_TEMP_STRING(lowerFileName.MakeLower()), NULL); - - if (pLodStatObj) - { - pLodStatObj->SetLodLevel0(this); - bRes = true; - - typedef std::set LoadedObjects; - LoadedObjects::iterator it = m_pObjManager->GetLoadedObjects().find(pLodStatObj); - if (it != m_pObjManager->GetLoadedObjects().end()) - { - m_pObjManager->GetLoadedObjects().erase(it); - m_pObjManager->GetNameToObjectMap().erase(CONST_TEMP_STRING(sLodFileName)); - } - } - else if (pData || IsValidFile(sLodFileName)) - { - if (!pLodStatObj) - { - pLodStatObj = new CStatObj(); - pLodStatObj->SetLodLevel0(this); - } - - if (bUseStreaming && GetCVars()->e_StreamCgf) - { - pLodStatObj->SetCanUnload(true); - } - - bRes = pLodStatObj->LoadCGF(sLodFileName, true, nLoadingFlags, pData, nDataLen); - } - - if (!bRes) - { - if ((m_pLODs ? (CStatObj*)m_pLODs[nLodLevel] : (CStatObj*)NULL) != pLodStatObj) - { - SAFE_RELEASE(pLodStatObj); - } - SetLodObject(nLodLevel, 0); - return NULL; - } - - bool bLodCompound = (pLodStatObj->GetFlags() & STATIC_OBJECT_COMPOUND) != 0; - bool bLod0Compund = (GetFlags() & STATIC_OBJECT_COMPOUND) != 0; - - SetLodObject(nLodLevel, pLodStatObj); - - if (bLodCompound != bLod0Compund) - { - // LOD0 and LOD differ. - FileWarning(0, sLodFileName, "Invalid LOD%d, LOD%d have different merging property from LOD0", nLodLevel, nLodLevel); - } - - return pLodStatObj; -} - -void CStatObj::LoadLowLODS_Finalize(int nLoadedLods, IStatObj* loadedLods[MAX_STATOBJ_LODS_NUM]) -{ - ////////////////////////////////////////////////////////////////////////// - // Put LODs into the sub objects. - ////////////////////////////////////////////////////////////////////////// - if (nLoadedLods > 1) - { - m_bLodsAreLoadedFromSeparateFile = true; - - for (int i = 0; i < (int)m_subObjects.size(); i++) - { - SSubObject* pSubObject = &m_subObjects[i]; - if (!pSubObject->pStatObj || pSubObject->nType != STATIC_SUB_OBJECT_MESH) - { - continue; - } - - IStatObj* pSubStatObj = (CStatObj*)pSubObject->pStatObj; - - // int nLoadedTrisCount = ((CStatObj*)pSubObject->pStatObj)->m_nLoadedTrisCount; - - for (int nLodLevel = 1; nLodLevel < nLoadedLods; nLodLevel++) - { - if (loadedLods[nLodLevel] != 0 && loadedLods[nLodLevel]->GetSubObjectMeshCount() > 0) - { - SSubObject* pLodSubObject = loadedLods[nLodLevel]->FindSubObject(pSubObject->name); - if (pLodSubObject && pLodSubObject->pStatObj && pLodSubObject->nType == STATIC_SUB_OBJECT_MESH) - { - pSubStatObj->SetLodObject(nLodLevel, (CStatObj*)pLodSubObject->pStatObj); - } - } - } - if (pSubStatObj) - { - pSubStatObj->CleanUnusedLods(); - } - } - } - - CleanUnusedLods(); - - for (int nLodLevel = 0; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++) - { - if (loadedLods[nLodLevel]) - { - GetObjManager()->CheckForGarbage(loadedLods[nLodLevel]); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::CleanUnusedLods() -{ - ////////////////////////////////////////////////////////////////////////// - // Free render resources for unused upper LODs. - ////////////////////////////////////////////////////////////////////////// - if (m_nLoadedLodsNum > 1) - { - int nMinLod = GetMinUsableLod(); - nMinLod = clamp_tpl(nMinLod, 0, (int)m_nLoadedLodsNum - 1); - for (int i = 0; i < nMinLod; i++) - { - CStatObj* pStatObj = (CStatObj*)GetLodObject(i); - if (!pStatObj) - { - continue; - } - - if (pStatObj->m_pRenderMesh) - { - pStatObj->SetRenderMesh(0); - } - } - } - ////////////////////////////////////////////////////////////////////////// -} - -void TransformMesh(CMesh& mesh, Matrix34 tm) -{ - const int nVerts = mesh.GetVertexCount(); - if (mesh.m_pPositions) - { - for (int i = 0; i < nVerts; i++) - { - mesh.m_pPositions[i] = tm.TransformPoint(mesh.m_pPositions[i]); - } - } - else if (mesh.m_pPositionsF16) - { - for (int i = 0; i < nVerts; i++) - { - mesh.m_pPositionsF16[i] = tm.TransformPoint(mesh.m_pPositionsF16[i].ToVec3()); - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::LoadStreamRenderMeshes(const char* filename, const void* pData, const int nDataSize, bool bLod) -{ - LOADING_TIME_PROFILE_SECTION; - - CLoaderCGF cgfLoader(util::pool_allocate, util::pool_free, GetCVars()->e_StatObjTessellationMode != 2 || bLod); - CStackContainer contentContainer(InplaceFactory(m_szFileName)); - CContentCGF* pCGF = contentContainer.get(); - - bool bMeshAssigned = false; - - ////////////////////////////////////////////////////////////////////////// - // Load CGF. - ////////////////////////////////////////////////////////////////////////// - class Listener - : public ILoaderCGFListener - { - public: - virtual void Warning([[maybe_unused]] const char* format) {} - virtual void Error([[maybe_unused]] const char* format) {} - virtual bool IsValidationEnabled() { return false; } - }; - - bool bLoaded = false; - bool bLoadedChunks = false; - - Listener listener; - CReadOnlyChunkFile chunkFile(false, true); // Chunk file must exist until CGF is completely loaded, and if loading from file do not make a copy of it. - - if (filename && filename[0]) - { - bLoadedChunks = chunkFile.Read(filename); - } - else - { - bLoadedChunks = chunkFile.ReadFromMemory(pData, nDataSize); - } - - if (bLoadedChunks) - { - bLoaded = cgfLoader.LoadCGF(contentContainer.get(), m_szFileName, chunkFile, &listener, 0); - } - - if (!bLoaded) - { - FileWarning(0, m_szFileName, "CGF Streaming Failed: %s", cgfLoader.GetLastError()); - return false; - } - - ////////////////////////////////////////////////////////////////////////// - - int nSubObjCount = (int)m_subObjects.size(); - - bool bBreakNodeLoop = false; - - for (int i = 0; i < pCGF->GetNodeCount() && !bBreakNodeLoop; i++) - { - CNodeCGF* pNode = pCGF->GetNode(i); - if (!pNode->pMesh) - { - continue; - } - - bool bNodeIsValidMesh = (pNode->type == CNodeCGF::NODE_MESH || (pNode->type == CNodeCGF::NODE_HELPER && pNode->helperType == HP_GEOMETRY)); - if (!bNodeIsValidMesh) - { - continue; - } - - CStatObj* pStatObj = 0; - for (int s = 0; s < nSubObjCount && !pStatObj; s++) - { - CStatObj* pSubStatObj = (CStatObj*)m_subObjects[s].pStatObj; - if (!pSubStatObj) - { - continue; - } - for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pSubLod = (CStatObj*)pSubStatObj->GetLodObject(nLod); - if (!pSubLod) - { - continue; - } - if (0 == strcmp(pSubLod->m_cgfNodeName.c_str(), pNode->name)) - { - pStatObj = pSubLod; - break; - } - } - } - - if (!pStatObj && m_nSubObjectMeshCount <= 1) - { - // If we do not have sub objects, assign the root StatObj to be used, and then not check anymore other nodes. - for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM && !pStatObj; nLod++) - { - CStatObj* pLod = (CStatObj*)GetLodObject(nLod); - if (!pLod) - { - continue; - } - if (0 == strcmp(pLod->m_cgfNodeName.c_str(), pNode->name)) - { - pStatObj = pLod; - break; - } - } - } - if (pStatObj) - { - // add mesh to sync setup queue - pStatObj->m_pStreamedRenderMesh = pStatObj->MakeRenderMesh(pNode->pMesh, true); - if (pStatObj->m_pStreamedRenderMesh) - { - bMeshAssigned = true; - - ////////////////////////////////////////////////////////////////////////// - // FIXME: Qtangents not generated for foliage in RC, we must do that here. - ////////////////////////////////////////////////////////////////////////// - if (pStatObj->m_nSpines && pStatObj->m_pSpines) // foliage - { - pStatObj->m_pStreamedRenderMesh->GenerateQTangents(); - } - } - } - } - if (!bMeshAssigned) - { - Warning("RenderMesh not assigned %s", m_szFileName.c_str()); - } - - - ////////////////////////////////////////////////////////////////////////// - // Merge sub-objects for the new lod. - if (GetCVars()->e_StatObjMerge) - { - IStatObj* pLod0 = (m_pLod0) ? m_pLod0 : this; - pLod0->TryMergeSubObjects(true); - } - ////////////////////////////////////////////////////////////////////////// - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::CommitStreamRenderMeshes() -{ - if (m_pStreamedRenderMesh) - { - CryAutoCriticalSection lock(m_streamingMeshLock); - SetRenderMesh(m_pStreamedRenderMesh); - m_pStreamedRenderMesh = 0; - } - if (m_pLODs) - { - for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pLodObj = m_pLODs[nLod]; - if (pLodObj && pLodObj->m_pStreamedRenderMesh) - { - CryAutoCriticalSection lock(pLodObj->m_streamingMeshLock); - - pLodObj->SetRenderMesh(pLodObj->m_pStreamedRenderMesh); - pLodObj->m_pStreamedRenderMesh = 0; - } - } - } - - for (size_t i = 0, num = m_subObjects.size(); i < num; ++i) - { - CStatObj* pSubObj = (CStatObj*)m_subObjects[i].pStatObj; - if (pSubObj) - { - pSubObj->CommitStreamRenderMeshes(); - } - } -} - -bool CStatObj::IsDeformable() -{ - // Create deformable subobject is present - if (m_isDeformable) - { - return true; - } - else - { - for (int i = 0, n = GetSubObjectCount(); i < n; ++i) - { - IStatObj::SSubObject* subObject = GetSubObject(i); - if (!subObject) - { - continue; - } - if (CStatObj* pChild = static_cast(subObject->pStatObj)) - { - if (pChild->m_isDeformable) - { - return true; - } - } - } - } - - return false; -} - - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::LoadCGF(const char* filename, bool bLod, unsigned long nLoadingFlags, const void* pData, const int nDataSize) -{ - FUNCTION_PROFILER_3DENGINE; - LOADING_TIME_PROFILE_SECTION; - - CRY_DEFINE_ASSET_SCOPE("CGF", filename); - - if (m_bSubObject) // Never execute this on the sub objects. - { - return true; - } - - PrintComment("Loading %s", filename); - if (!bLod) - { - GetConsole()->TickProgressBar(); - } - - m_nRenderTrisCount = m_nLoadedTrisCount = 0; - m_nLoadedVertexCount = 0; - m_szFileName = filename; - m_szFileName.replace('\\', '/'); - - // Determine if stream only cgf is available - stack_string streamPath; - GetStreamFilePath(streamPath); - m_bHasStreamOnlyCGF = gEnv->pCryPak->IsFileExist(streamPath.c_str()); - - if (!m_bCanUnload) - { - if (m_bHasStreamOnlyCGF) - { - if (!LoadCGF_Int(filename, bLod, nLoadingFlags, pData, nDataSize)) - { - return false; - } - return LoadStreamRenderMeshes(streamPath.c_str(), 0, 0, bLod); - } - } - - return LoadCGF_Int(filename, bLod, nLoadingFlags, pData, nDataSize); -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::LoadCGF_Int(const char* filename, bool bLod, unsigned long nLoadingFlags, const void* pData, const int nDataSize) -{ - using namespace AzFramework::AssetSystem; - CLoaderCGF cgfLoader(util::pool_allocate, util::pool_free, GetCVars()->e_StatObjTessellationMode != 2 || bLod); - CStackContainer contentContainer(InplaceFactory(filename)); - CContentCGF* pCGF = contentContainer.get(); - - ////////////////////////////////////////////////////////////////////////// - // Load CGF. - ////////////////////////////////////////////////////////////////////////// - class Listener - : public ILoaderCGFListener - { - public: - virtual void Warning(const char* format) {Cry3DEngineBase::Warning("%s", format); } - virtual void Error(const char* format) {Cry3DEngineBase::Error("%s", format); } - virtual bool IsValidationEnabled() { return Cry3DEngineBase::GetCVars()->e_StatObjValidate != 0; } - }; - - AZStd::string cleanedFileName = PathUtil::ToUnixPath(filename).c_str(); - AZStd::to_lower(cleanedFileName.begin(), cleanedFileName.end()); - -# if !defined(_RELEASE) - - if (GetCVars()->e_CGFMaxFileSize >= 0 && (cleanedFileName.compare(DEFAULT_CGF_NAME) != 0)) - { - size_t fileSize = gEnv->pCryPak->FGetSize(filename, true); - if (fileSize > (size_t)GetCVars()->e_CGFMaxFileSize << 10) - { - FileWarning(0, filename, "CGF Loading Failed: file '%s' (size %3.3f kb) exceeds size limit (max %3.3f kb)", - filename, fileSize / 1024.f, (GetCVars()->e_CGFMaxFileSize << 10) / 1024.f); - return false; - } - } -# endif - - Listener listener; - CReadOnlyChunkFile chunkFile(false, bLod); // Chunk file must exist until CGF is completely loaded, and if loading from file do not make a copy of it. - - bool bLoaded = false; - bool isFileMissing = false; - if (gEnv->pCryPak) - { - if (!gEnv->pCryPak->IsFileExist(filename)) - { - isFileMissing = true; - } - } - else - { - if (!gEnv->pFileIO->Exists(filename)) - { - isFileMissing = true; - } - } - - bool isDefaultCGF = false; - if (isFileMissing) - { - //input filename is already converted to unixpath, - //we will convert the default cgf name to also unix path for comparision - AssetStatus status = AssetStatus_Unknown; - if (cleanedFileName.compare(DEFAULT_CGF_NAME) == 0) - { - isDefaultCGF = true; - } - if (isDefaultCGF) - { - //we are here if the default cgf is missing ,sync compile - EBUS_EVENT_RESULT(status, AzFramework::AssetSystemRequestBus, CompileAssetSync, cleanedFileName); - } - else - { - //we are here if a non default cgf file is missing - EBUS_EVENT_RESULT(status, AzFramework::AssetSystemRequestBus, GetAssetStatus, cleanedFileName); - } - - if ((status == AssetStatus_Missing)) - { - //if status is missing ,show the warning - FileWarning(0, cleanedFileName.c_str(), "CGF Loading Failed: %s", cgfLoader.GetLastError()); - cleanedFileName = DEFAULT_CGF_NAME; - } - else if (!isDefaultCGF && status != AssetStatus_Compiled) - { - //if we are here it means that a non default cgf file is either in the AP queue or is compiling - //we than change the name to default cgf and let it load. - cleanedFileName = DEFAULT_CGF_NAME; - } - } - - if (nDataSize) - { - if (chunkFile.ReadFromMemory(pData, nDataSize)) - { - bLoaded = cgfLoader.LoadCGF(contentContainer.get(), cleanedFileName.c_str(), chunkFile, &listener, nLoadingFlags); - } - } - else - { - bLoaded = cgfLoader.LoadCGF(contentContainer.get(), cleanedFileName.c_str(), chunkFile, &listener, nLoadingFlags); - } - if (!bLoaded) - { - FileWarning(0, cleanedFileName.c_str(), "CGF Loading Failed: %s", cgfLoader.GetLastError()); - return false; - } - ////////////////////////////////////////////////////////////////////////// - - INDENT_LOG_DURING_SCOPE(true, "While loading static object geometry '%s'", filename); - - CExportInfoCGF* pExportInfo = pCGF->GetExportInfo(); - CNodeCGF* pFirstMeshNode = NULL; - CMesh* pFirstMesh = NULL; - m_nSubObjectMeshCount = 0; - - if (!pExportInfo->bCompiledCGF) - { - FileWarning(0, cleanedFileName.c_str(), "CGF is not compiled, use RC"); - return false; - } - - m_bMeshStrippedCGF = pExportInfo->bNoMesh; - - bool bHasJoints = false; - if (nLoadingFlags & ELoadingFlagsForceBreakable) - { - m_nFlags |= STATIC_OBJECT_DYNAMIC; - } - - m_nNodeCount = pCGF->GetNodeCount(); - - m_clothData.clear(); - - ////////////////////////////////////////////////////////////////////////// - // Find out number of meshes, and get pointer to the first found mesh. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < pCGF->GetNodeCount(); i++) - { - CNodeCGF* pNode = pCGF->GetNode(i); - if (pNode->type == CNodeCGF::NODE_MESH) - { - if (m_szProperties.empty()) - { - m_szProperties = pNode->properties; // Take properties from the first mesh node. - m_szProperties.MakeLower(); - } - m_nSubObjectMeshCount++; - if (!pFirstMeshNode) - { - pFirstMeshNode = pNode; - pFirstMesh = pNode->pMesh; - } - } - else if (strncmp(pNode->name, "$joint", 6) == 0) - { - bHasJoints = true; - } - } - - bool bIsLod0Merged = false; - if (bLod && m_pLod0) - { - // This is a log object, check if parent was merged or not. - bIsLod0Merged = m_pLod0->GetSubObjectMeshCount() == 0; - } - - if (pExportInfo->bMergeAllNodes || (m_nSubObjectMeshCount <= 1 && !bHasJoints && (!bLod || bIsLod0Merged))) - { - // If we merging all nodes, ignore sub object meshes. - m_nSubObjectMeshCount = 0; - - if (pCGF->GetCommonMaterial()) - { - if (nLoadingFlags & ELoadingFlagsPreviewMode) - { - m_pMaterial = GetMatMan()->GetDefaultMaterial(); - m_pMaterial->AddRef(); - } - else - { - m_pMaterial = GetMatMan()->LoadCGFMaterial(pCGF->GetCommonMaterial(), cleanedFileName.c_str(), nLoadingFlags); - if (m_pMaterial->IsDefault()) - { - FileWarning(0, cleanedFileName.c_str(), "CGF is unable to load its default material, see XML reader error above for material info."); - } - } - } - } - - // Fail if mesh was not complied by RC - if (pFirstMesh && pFirstMesh->GetFaceCount() > 0) - { - FileWarning(0, cleanedFileName.c_str(), "CGF is not compiled"); - return false; - } - - if (GetCVars()->e_StatObjValidate) - { - const char* pErrorDescription = 0; - if (pFirstMesh && (!pFirstMesh->Validate(&pErrorDescription))) - { - FileWarning(0, cleanedFileName.c_str(), "CGF has invalid merged mesh (%s)", pErrorDescription); - assert(!"CGF has invalid merged mesh"); - return false; - } - if (!pCGF->ValidateMeshes(&pErrorDescription)) - { - FileWarning(0, cleanedFileName.c_str(), "CGF has invalid meshes (%s)", pErrorDescription); - assert(!"CGF has invalid meshes"); - return false; - } - } - - // Common of all sub nodes bbox. - AABB commonBBox; - commonBBox.Reset(); - - bool bHaveMeshNamedMain = false; - bool bHasBreakableJoints = false; - bool bRenderMeshLoaded = false; // even if streaming is disabled we may load now from stripped cgf so meshes will fail to load - in this case we will stream it later - - ////////////////////////////////////////////////////////////////////////// - // Create StatObj from Mesh. - ////////////////////////////////////////////////////////////////////////// - - _smart_ptr pMainMesh; - - if (pExportInfo->bMergeAllNodes || m_nSubObjectMeshCount == 0) - { - if (pFirstMeshNode) - { - m_vBoxMin = pFirstMeshNode->meshInfo.bboxMin; - m_vBoxMax = pFirstMeshNode->meshInfo.bboxMax; - m_fGeometricMeanFaceArea = pFirstMeshNode->meshInfo.fGeometricMean; - commonBBox.min = m_vBoxMin; - commonBBox.max = m_vBoxMax; - m_nRenderTrisCount = m_nLoadedTrisCount = pFirstMeshNode->meshInfo.nIndices / 3; - m_nLoadedVertexCount = pFirstMeshNode->meshInfo.nVerts; - m_cgfNodeName = pFirstMeshNode->name; - CalcRadiuses(); - - if (pFirstMesh) - { - // Assign mesh to this static object. - _smart_ptr pRenderMesh = MakeRenderMesh(pFirstMesh, !m_bCanUnload); - SetRenderMesh(pRenderMesh); - pMainMesh = m_pRenderMesh; - bRenderMeshLoaded |= (m_pRenderMesh != 0); -#ifdef SERVER_CHECKS - if (gEnv->IsDedicated() || GetCVars()->e_StatObjStoreMesh) - { - m_pMesh = new CMesh(); - m_pMesh->Copy(*pFirstMesh); - } -#endif - FillClothData(*pFirstMesh); - } - else - { - // If mesh not known now try to estimate its memory usage. - m_nRenderMeshMemoryUsage = CMesh::ApproximateRenderMeshMemoryUsage(pFirstMeshNode->meshInfo.nVerts, pFirstMeshNode->meshInfo.nIndices); - CalcRadiuses(); - } - } - } - ////////////////////////////////////////////////////////////////////////// - - scratch_vector nodes; - static const size_t lodNamePrefixLength = strlen(CGF_NODE_NAME_LOD_PREFIX); - - ////////////////////////////////////////////////////////////////////////// - // Create SubObjects. - ////////////////////////////////////////////////////////////////////////// - if (pCGF->GetNodeCount() > 1 || m_nSubObjectMeshCount > 0) - { - nodes.reserve(pCGF->GetNodeCount()); - - scratch_vector< std::pair > meshToObject; - meshToObject.reserve(pCGF->GetNodeCount()); - - ////////////////////////////////////////////// - // Count required subobjects and reserve space - ////////////////////////////////////////////// - size_t nSubObjects = 0; - for (int ii = 0; ii < pCGF->GetNodeCount(); ii++) - { - CNodeCGF* pNode = pCGF->GetNode(ii); - - if (pNode->bPhysicsProxy) - { - continue; - } - - if (pNode->type == CNodeCGF::NODE_MESH) - { - if (pExportInfo->bMergeAllNodes || m_nSubObjectMeshCount == 0) // Only add helpers, ignore meshes. - { - continue; - } - } - else if (pNode->type == CNodeCGF::NODE_HELPER) - { - switch (pNode->helperType) - { - case HP_GEOMETRY: - { - if (_strnicmp(pNode->name, CGF_NODE_NAME_LOD_PREFIX, lodNamePrefixLength) == 0) - { - continue; - } - } - break; - } - } - - ++nSubObjects; - } - m_subObjects.reserve(nSubObjects); - ////////////////////////////////////////////// - - int nNumMeshes = 0; - for (int ii = 0; ii < pCGF->GetNodeCount(); ii++) - { - CNodeCGF* pNode = pCGF->GetNode(ii); - - if (pNode->bPhysicsProxy) - { - continue; - } - - SSubObject subObject; - subObject.pStatObj = 0; - subObject.bIdentityMatrix = pNode->bIdentityMatrix; - subObject.bHidden = false; - subObject.tm = pNode->worldTM; - subObject.localTM = pNode->localTM; - subObject.name = pNode->name; - subObject.properties = pNode->properties; - subObject.nParent = -1; - subObject.pWeights = 0; - subObject.helperSize.Set(0, 0, 0); - - if (pNode->type == CNodeCGF::NODE_MESH) - { - if (pExportInfo->bMergeAllNodes || m_nSubObjectMeshCount == 0) // Only add helpers, ignore meshes. - { - continue; - } - - nNumMeshes++; - subObject.nType = STATIC_SUB_OBJECT_MESH; - - if (stristr(pNode->name, "shadowproxy") != 0) - { - subObject.bShadowProxy = true; - } - - if (_stricmp(pNode->name, MESH_NAME_FOR_MAIN) == 0) - { - bHaveMeshNamedMain = true; - } - } - else if (pNode->type == CNodeCGF::NODE_LIGHT) - { - subObject.nType = STATIC_SUB_OBJECT_LIGHT; - } - else if (pNode->type == CNodeCGF::NODE_HELPER) - { - if (!bHasBreakableJoints) - { - if (strstr(pNode->name, PHYSICS_BREAKABLE_JOINT) == 0) - { - bHasBreakableJoints = true; - } - } - - switch (pNode->helperType) - { - case HP_POINT: - subObject.nType = STATIC_SUB_OBJECT_POINT; - break; - case HP_DUMMY: - subObject.nType = STATIC_SUB_OBJECT_DUMMY; - subObject.helperSize = (pNode->helperSize * 0.01f); - break; - case HP_XREF: - subObject.nType = STATIC_SUB_OBJECT_XREF; - break; - case HP_CAMERA: - subObject.nType = STATIC_SUB_OBJECT_CAMERA; - break; - case HP_GEOMETRY: - { - subObject.nType = STATIC_SUB_OBJECT_HELPER_MESH; - subObject.bHidden = true; // Helpers are not rendered. - } - break; - default: - assert(0); // unknown type. - } - } - - // Only when multiple meshes inside. - // If only 1 mesh inside, Do not create a separate CStatObj for it. - if ((m_nSubObjectMeshCount > 0 && pNode->type == CNodeCGF::NODE_MESH) || - (subObject.nType == STATIC_SUB_OBJECT_HELPER_MESH)) - { - if (pNode->pSharedMesh) - { - // Try to find already create StatObj for a shred mesh node - for (int k = 0, num = (int)meshToObject.size(); k < num; k++) - { - if (pNode->pSharedMesh == meshToObject[k].first) - { - subObject.pStatObj = meshToObject[k].second; - break; - } - } - } - - if (!subObject.pStatObj) - { - // Create a StatObj from the CGF node. - subObject.pStatObj = MakeStatObjFromCgfNode(pCGF, pNode, bLod, nLoadingFlags, commonBBox); - if (pNode->pSharedMesh) - { - meshToObject.push_back(std::make_pair(pNode->pSharedMesh, static_cast(subObject.pStatObj))); - } - else - { - meshToObject.push_back(std::make_pair(pNode, static_cast(subObject.pStatObj))); - } - bRenderMeshLoaded |= (((CStatObj*)subObject.pStatObj)->m_pRenderMesh != 0); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Check if helper object is a LOD - ////////////////////////////////////////////////////////////////////////// - if ((subObject.nType == STATIC_SUB_OBJECT_HELPER_MESH) && - (_strnicmp(pNode->name, CGF_NODE_NAME_LOD_PREFIX, lodNamePrefixLength) == 0)) - { - // Check if helper object is a LOD - - if (!subObject.pStatObj) - { - continue; - } - - CStatObj* pLodStatObj = (CStatObj*)subObject.pStatObj; - CStatObj* pStatObjParent = this; - if (!pExportInfo->bMergeAllNodes && m_nSubObjectMeshCount > 0 && pNode->pParent) - { - // We are attached to some object, find it. - for (int i = 0, num = nodes.size(); i < num; i++) - { - if (nodes[i] == pNode->pParent) - { - pStatObjParent = (CStatObj*)m_subObjects[i].pStatObj; - break; - } - } - } - if (!pStatObjParent) - { - continue; - } - - const int nLodLevel = atoi(pNode->name + lodNamePrefixLength); - if ((nLodLevel >= 1) && (nLodLevel < MAX_STATOBJ_LODS_NUM)) - { - if (!pStatObjParent->m_pLODs || !pStatObjParent->m_pLODs[nLodLevel]) - { - pStatObjParent->SetLodObject(nLodLevel, pLodStatObj); - } - else - { - const char* existingGeoName = pStatObjParent->m_pLODs[nLodLevel]->GetGeoName(); - FileWarning(0, cleanedFileName.c_str(), "Duplicated LOD helper %s (%s). Existing geometry name: %s", pNode->name, cleanedFileName.c_str(), existingGeoName); - } - } - - continue; - } - ////////////////////////////////////////////////////////////////////////// - - if (subObject.pStatObj) - { - subObject.pStatObj->AddRef(); - } - - m_subObjects.push_back(subObject); - nodes.push_back(pNode); - } - - // Delete not assigned stat objects. - for (int k = 0, num = (int)meshToObject.size(); k < num; k++) - { - if (meshToObject[k].second->m_nUsers == 0) - { - delete meshToObject[k].second; - } - } - - // Assign SubObject parent pointers. - int nNumCgfNodes = (int)nodes.size(); - if (nNumCgfNodes > 0) - { - CNodeCGF** pNodes = &nodes[0]; - - ////////////////////////////////////////////////////////////////////////// - // Move meshes to beginning, Sort sub-objects so that meshes are first. - for (int i = 0; i < nNumCgfNodes; i++) - { - if (pNodes[i]->type != CNodeCGF::NODE_MESH) - { - // check if any more meshes exist. - if (i < nNumMeshes) - { - // Try to find next mesh and place it here. - for (int j = i + 1; j < nNumCgfNodes; j++) - { - if (pNodes[j]->type == CNodeCGF::NODE_MESH) - { - // Swap objects at j to i. - std::swap(pNodes[i], pNodes[j]); - std::swap(m_subObjects[i], m_subObjects[j]); - break; - } - } - } - } - } - ////////////////////////////////////////////////////////////////////////// - - // Assign Parent nodes. - for (int i = 0; i < nNumCgfNodes; i++) - { - CNodeCGF* pParentNode = pNodes[i]->pParent; - if (pParentNode) - { - for (int j = 0; j < nNumCgfNodes; j++) - { - if (pNodes[j] == pParentNode) - { - m_subObjects[i].nParent = j; - break; - } - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Handle Main/Remain meshes used for Destroyable Objects. - ////////////////////////////////////////////////////////////////////////// - if (bHaveMeshNamedMain) - { - // If have mesh named main, then mark all sub object hidden except the one called "Main". - for (int i = 0, n = m_subObjects.size(); i < n; i++) - { - if (m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH) - { - if (azstricmp(m_subObjects[i].name, MESH_NAME_FOR_MAIN) == 0) - { - m_subObjects[i].bHidden = false; - } - else - { - m_subObjects[i].bHidden = true; - } - } - } - } - ////////////////////////////////////////////////////////////////////////// - } - } - - if (m_nSubObjectMeshCount > 0) - { - m_vBoxMin = commonBBox.min; - m_vBoxMax = commonBBox.max; - CalcRadiuses(); - } - - for (int i = 0; i < pCGF->GetNodeCount(); i++) - { - if (strstr(pCGF->GetNode(i)->properties, "deformable")) - { - m_nFlags |= STATIC_OBJECT_DEFORMABLE; - } - } - - if (m_nSubObjectMeshCount > 0) - { - m_nFlags |= STATIC_OBJECT_COMPOUND; - } - else - { - m_nFlags &= ~STATIC_OBJECT_COMPOUND; - } - - if (!bLod && !m_szProperties.empty()) - { - ParseProperties(); - } - - if (!bLod) - { - CPhysicalizeInfoCGF* pPi = pCGF->GetPhysicalizeInfo(); - if (pPi->nRetTets) - { - // Lattice support? - CRY_PHYSICS_REPLACEMENT_ASSERT(); - } - } - - if (m_bHasDeformationMorphs) - { - int i, j; - for (i = GetSubObjectCount() - 1; i >= 0; i--) - { - if ((j = SubobjHasDeformMorph(i)) >= 0) - { - GetSubObject(i)->pStatObj->SetDeformationMorphTarget(GetSubObject(j)->pStatObj); - } - } - m_bUnmergable = 1; - } - - // Only objects with breakable physics joints can be merged. - if (!bHasBreakableJoints) - { - m_bUnmergable = true; - } - - // sub meshes merging - if (GetCVars()->e_StatObjMerge) - { - if (!m_bUnmergable) - { - if (!CanMergeSubObjects()) - { - m_bUnmergable = true; - } - } - } - - // Merging always produces 16 bit meshes, so disable for 32 bit meshes for now - if (pFirstMesh && pFirstMesh->m_pPositions) - { - m_bUnmergable = true; - } - - if (!m_bCanUnload && bRenderMeshLoaded) - { - m_eStreamingStatus = ecss_Ready; - } - - // Determine if the cgf is deformable - if (stristr(m_szGeomName.c_str(), "bendable") && stristr(m_szProperties.c_str(), "mergedmesh_deform")) - { - m_isDeformable = 1; - DisableStreaming(); - } - for (int i = 0; i < GetSubObjectCount(); ++i) - { - IStatObj::SSubObject* subObject = GetSubObject(i); - if (!subObject) - { - continue; - } - if (CStatObj* pChild = static_cast(GetSubObject(i)->pStatObj)) - { - if (stristr(pChild->m_szGeomName.c_str(), "bendable") && stristr(pChild->m_szProperties.c_str(), "mergedmesh_deform")) - { - pChild->m_isDeformable = 1; - pChild->DisableStreaming(); - } - } - } - - SMeshLodInfo lodInfo; - ComputeGeometricMean(lodInfo); - m_fLodDistance = sqrt(lodInfo.fGeometricMean); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -CStatObj* CStatObj::MakeStatObjFromCgfNode([[maybe_unused]] CContentCGF* pCGF, CNodeCGF* pNode, bool bLod, int nLoadingFlags, AABB& commonBBox) -{ - CNodeCGF* pTMNode = pNode; - if (pNode->pSharedMesh) - { - pNode = pNode->pSharedMesh; - } - - // Calc bbox. - if (pNode->type == CNodeCGF::NODE_MESH) - { - AABB box(pNode->meshInfo.bboxMin, pNode->meshInfo.bboxMax); - box.SetTransformedAABB(pTMNode->worldTM, box); - commonBBox.Add(box.min); - commonBBox.Add(box.max); - } - - CStatObj* pStatObj = new CStatObj; - - pStatObj->m_szFileName = m_szFileName; - pStatObj->m_szGeomName = pNode->name; - pStatObj->m_bSubObject = true; - - if (pNode->type == CNodeCGF::NODE_MESH) - { - pStatObj->m_pParentObject = this; - } - - pStatObj->m_szProperties = pNode->properties; - pStatObj->m_szProperties.MakeLower(); - if (!bLod && !pStatObj->m_szProperties.empty()) - { - pStatObj->ParseProperties(); - } - - if (pNode->pMaterial) - { - if (nLoadingFlags & ELoadingFlagsPreviewMode) - { - pStatObj->m_pMaterial = GetMatMan()->GetDefaultMaterial(); - pStatObj->m_pMaterial->AddRef(); - } - else - { - pStatObj->m_pMaterial = GetMatMan()->LoadCGFMaterial(pNode->pMaterial, m_szFileName, nLoadingFlags); - } - if (!m_pMaterial || m_pMaterial->IsDefault()) - { - m_pMaterial = pStatObj->m_pMaterial; // take it as a general stat obj material. - } - } - if (!pStatObj->m_pMaterial) - { - pStatObj->m_pMaterial = m_pMaterial; - } - - pStatObj->m_vBoxMin = pNode->meshInfo.bboxMin; - pStatObj->m_vBoxMax = pNode->meshInfo.bboxMax; - pStatObj->m_nRenderMatIds = pNode->meshInfo.nSubsets; - pStatObj->m_nRenderTrisCount = pStatObj->m_nLoadedTrisCount = pNode->meshInfo.nIndices / 3; - pStatObj->m_nLoadedVertexCount = pNode->meshInfo.nVerts; - pStatObj->m_fGeometricMeanFaceArea = pNode->meshInfo.fGeometricMean; - pStatObj->CalcRadiuses(); - - if (nLoadingFlags & ELoadingFlagsForceBreakable) - { - pStatObj->m_nFlags |= STATIC_OBJECT_DYNAMIC; - } - - if (pNode->pMesh) - { - _smart_ptr pRenderMesh = pStatObj->MakeRenderMesh(pNode->pMesh, !m_bCanUnload); - pStatObj->SetRenderMesh(pRenderMesh); - pStatObj->FillClothData(*pNode->pMesh); - } - else - { - // If mesh not known now try to estimate its memory usage. - pStatObj->m_nRenderMeshMemoryUsage = CMesh::ApproximateRenderMeshMemoryUsage(pNode->meshInfo.nVerts, pNode->meshInfo.nIndices); - } - pStatObj->m_cgfNodeName = pNode->name; - - if (pNode->pSkinInfo) - { - pStatObj->m_pSkinInfo = (SSkinVtx*)pNode->pSkinInfo; - pStatObj->m_hasSkinInfo = 1; - pNode->pSkinInfo = 0; - } - - return pStatObj; -} - -void CStatObj::FillClothData(CMesh& mesh) -{ - m_clothData.clear(); - - // NOTE: Using CMesh Colors stream with index 1 for cloth data - const int ClothVertexBufferStreamIndex = 1; - int numElements = 0; - const auto meshColorStream = mesh.GetStreamPtrAndElementCount(CMesh::COLORS, ClothVertexBufferStreamIndex, &numElements); - if (meshColorStream && numElements > 0) - { - m_clothData.resize(numElements); - for (int i = 0; i < numElements; ++i) - { - m_clothData[i] = meshColorStream[i]; - } - } -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CStatObj::MakeRenderMesh(CMesh* pMesh, bool bDoRenderMesh) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!pMesh) - { - return 0; - } - - m_vBoxMin = pMesh->m_bbox.min; - m_vBoxMax = pMesh->m_bbox.max; - m_fGeometricMeanFaceArea = pMesh->m_geometricMeanFaceArea; - - CalcRadiuses(); - - m_nLoadedTrisCount = pMesh->GetIndexCount() / 3; - m_nLoadedVertexCount = pMesh->GetVertexCount(); - if (!m_nLoadedTrisCount) - { - return 0; - } - - m_nRenderTrisCount = 0; - m_nRenderMatIds = 0; - ////////////////////////////////////////////////////////////////////////// - // Initialize Mesh subset material flags. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < pMesh->GetSubSetCount(); i++) - { - SMeshSubset& subset = pMesh->m_subsets[i]; - _smart_ptr pMtl = m_pMaterial->GetSafeSubMtl(subset.nMatID); - subset.nMatFlags = pMtl->GetFlags(); - if (subset.nPhysicalizeType == PHYS_GEOM_TYPE_NONE && pMtl->GetSurfaceType()->GetPhyscalParams().pierceability >= 10) - { - subset.nMatFlags |= MTL_FLAG_NOPHYSICALIZE; - } - if (!(subset.nMatFlags & MTL_FLAG_NODRAW) && (subset.nNumIndices > 0)) - { - m_nRenderMatIds++; - m_nRenderTrisCount += subset.nNumIndices / 3; - } - } - ////////////////////////////////////////////////////////////////////////// - - if (!m_nRenderTrisCount) - { - return 0; - } - - _smart_ptr pOutRenderMesh; - - // Create renderable mesh. - if (!gEnv->IsDedicated()) - { - if (!pMesh) - { - return 0; - } - if (pMesh->GetSubSetCount() == 0) - { - return 0; - } - - size_t nRenderMeshSize = ~0U; - if (bDoRenderMesh) - { - pOutRenderMesh = GetRenderer()->CreateRenderMesh("StatObj", m_szFileName.c_str()); - - if (m_idmatBreakable >= 0 || m_bBreakableByGame) - { - // need to keep mesh data in system memory for breakable meshes - pOutRenderMesh->KeepSysMesh(true); - } - - // we cannot use FSM_CREATE_DEVICE_MESH flag since we can have an async call to the renderer! - { - uint32 nFlags = 0; - const threadID currentThread = CryGetCurrentThreadId(); - threadID renderThread, mainThread; - - gEnv->pRenderer->GetThreadIDs(mainThread, renderThread); - - nFlags |= (GetCVars()->e_StreamCgf || currentThread != renderThread) ? 0 : FSM_CREATE_DEVICE_MESH; - nFlags |= (!GetCVars()->e_StreamCgf && Get3DEngine()->m_bInLoad) ? FSM_SETMESH_ASYNC : 0; -#ifdef MESH_TESSELLATION_ENGINE - nFlags |= FSM_ENABLE_NORMALSTREAM; -#endif - nRenderMeshSize = pOutRenderMesh->SetMesh(*pMesh, 0, nFlags, true); - if (nRenderMeshSize == ~0U) - { - return 0; - } - } - - bool arrMaterialSupportsTeselation[32]; - ZeroStruct(arrMaterialSupportsTeselation); - } - - m_nRenderMeshMemoryUsage = (nRenderMeshSize == ~0U) ? pMesh->EstimateRenderMeshMemoryUsage() : nRenderMeshSize; - //m_nRenderMeshMemoryUsage = pMesh->EstimateRenderMeshMemoryUsage(); - } - - return pOutRenderMesh; -} - -static bool CreateNodeCGF(CContentCGF* pCGF, CStatObj* pStatObj, const char* name, CNodeCGF* pParent, CMaterialCGF* pMaterial) -{ - bool bRet = true; - CNodeCGF* pNode = NULL; - if (pStatObj->GetIndexedMesh()) - { - // Add single node for merged mesh. - pNode = new CNodeCGF; - - if (!pNode) - { - CryLog("SaveToCgf: failed to allocate CNodeCGF aborting"); - return false; - } - - pNode->type = CNodeCGF::NODE_MESH; - azsnprintf(pNode->name, sizeof(pNode->name), "%s", name); - pNode->localTM.SetIdentity(); - pNode->worldTM.SetIdentity(); - pNode->bIdentityMatrix = true; - pNode->pMesh = new CMesh; - pNode->pMesh->Copy(*(pStatObj->GetIndexedMesh()->GetMesh())); - if (pNode->pMesh) - { - pNode->pMesh->m_bbox = pStatObj->GetAABB(); - } - pNode->pParent = pParent; - pNode->pMaterial = pMaterial; - pNode->nPhysicalizeFlags = 0; - pCGF->AddNode(pNode); - } - - const int subobjCount = pStatObj->GetSubObjectCount(); - for (int subidx = 0; subidx < subobjCount; ++subidx) - { - IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(subidx); - if (!pSubObj || !pSubObj->pStatObj) - { - CryLog("SaveToCgf: A sub-object in '%s' is broken.", name ? name : ""); - continue; - } - const char* subGeoName = pSubObj->pStatObj->GetGeoName() ? pSubObj->pStatObj->GetGeoName() : "Merged"; - if (!CreateNodeCGF(pCGF, (CStatObj*)pSubObj->pStatObj, subGeoName, pNode, pMaterial)) - { - bRet = false; - } - } - return bRet; -} - -////////////////////////////////////////////////////////////////////////// -// Save statobj to the CGF file. -bool CStatObj::SaveToCGF([[maybe_unused]] const char* sFilename, [[maybe_unused]] IChunkFile** pOutChunkFile, [[maybe_unused]] bool bHavePhiscalProxy) -{ -#if defined(INCLUDE_SAVECGF) - CContentCGF* pCGF = new CContentCGF(sFilename); - - pCGF->GetExportInfo()->bCompiledCGF = true; - pCGF->GetExportInfo()->bMergeAllNodes = (GetSubObjectCount() <= 0); - pCGF->GetExportInfo()->bHavePhysicsProxy = bHavePhiscalProxy; - cry_strcpy(pCGF->GetExportInfo()->rc_version_string, "From Sandbox"); - - CChunkFile* pChunkFile = new CChunkFile(); - if (pOutChunkFile) - { - *pOutChunkFile = pChunkFile; - } - - CMaterialCGF* pMaterialCGF = new CMaterialCGF; - if (m_pMaterial) - { - cry_strcpy(pMaterialCGF->name, m_pMaterial->GetName()); - } - else - { - pMaterialCGF->name[0] = 0; - } - pMaterialCGF->nPhysicalizeType = PHYS_GEOM_TYPE_DEFAULT; - pMaterialCGF->bOldMaterial = false; - pMaterialCGF->nChunkId = 0; - - // Array of sub materials. - //std::vector subMaterials; - - bool bResult = false; - if (CreateNodeCGF(pCGF, this, GetGeoName() ? GetGeoName() : "Merged", NULL, pMaterialCGF)) - { - CSaverCGF cgfSaver(*pChunkFile); - - const bool bNeedEndianSwap = false; - const bool bUseQtangents = false; - const bool bStorePositionsAsF16 = false; - const bool bStoreIndicesAsU16 = (sizeof(vtx_idx) == sizeof(uint16)); - - cgfSaver.SaveContent(pCGF, bNeedEndianSwap, bStorePositionsAsF16, bUseQtangents, bStoreIndicesAsU16); - - bResult = true; - } - - if (!pOutChunkFile && bResult) - { - bResult = pChunkFile->Write(sFilename); - pChunkFile->Release(); - } - - delete pCGF; - - return bResult; -#else // #if defined(INCLUDE_SAVECGF) -# if !defined(_RELEASE) - __debugbreak(); -# endif - return false; -#endif -} - -////////////////////////////////////////////////////////////////////////// -inline char* trim_whitespaces(char* str, char* strEnd) -{ - char* first = str; - while (first < strEnd && (*first == ' ' || *first == '\t')) - { - first++; - } - char* s = strEnd - 1; - while (s >= first && (*s == ' ' || *s == '\t')) - { - *s-- = 0; - } - return first; -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::ParseProperties() -{ - FUNCTION_PROFILER_3DENGINE; - - int nLen = m_szProperties.size(); - if (nLen >= 4090) - { - Warning("CGF '%s' have longer then 4K geometry info file", m_szFileName.c_str()); - nLen = 4090; - } - - char properties[4096]; - memcpy(properties, m_szProperties.c_str(), nLen); - properties[nLen] = 0; - - char* str = properties; - char* strEnd = str + nLen; - while (str < strEnd) - { - char* line = str; - while (str < strEnd && *str != '\n' && *str != '\r') - { - str++; - } - char* lineEnd = str; - *lineEnd = 0; - str++; - while (str < strEnd && (*str == '\n' || *str == '\r')) // Skip all \r\n at end. - { - str++; - } - - if (*line == '/' || *line == '#') // skip comments - { - continue; - } - - if (line < lineEnd) - { - // Parse line. - char* l = line; - while (l < lineEnd && *l != '=') - { - l++; - } - if (l < lineEnd) - { - *l = 0; - char* left = line; - char* right = l + 1; - - // remove white spaces from left and right. - left = trim_whitespaces(left, l); - right = trim_whitespaces(right, lineEnd); - - ////////////////////////////////////////////////////////////////////////// - if (0 == strcmp(left, "mass")) - { - m_phys_mass = (float)atof(right); - } - else if (0 == strcmp(left, "density")) - { - m_phys_density = (float)atof(right); - } - ////////////////////////////////////////////////////////////////////////// - } - else - { - // There`s no = on the line, must be a flag. - ////////////////////////////////////////////////////////////////////////// - if (0 == strcmp(line, "entity")) - { - m_nFlags |= STATIC_OBJECT_SPAWN_ENTITY; - } - else if (0 == strcmp(line, "no_player_collide")) - { - m_nFlags |= STATIC_OBJECT_NO_PLAYER_COLLIDE; - } - else if (0 == strcmp(line, "no_auto_hidepoints")) - { - m_nFlags |= STATIC_OBJECT_NO_AUTO_HIDEPOINTS; - } - else if (0 == strcmp(line, "dynamic")) - { - m_nFlags |= STATIC_OBJECT_DYNAMIC; - } - else if (0 == strcmp(line, "no_hit_refinement")) - { - m_bNoHitRefinement = true; - for (int i = m_arrPhysGeomInfo.GetGeomCount() - 1; i >= 0; i--) - { - m_arrPhysGeomInfo[i]->pGeom->SetForeignData(0, 0); - } - } - else if (0 == strcmp(line, "no_explosion_occlusion")) - { - m_bDontOccludeExplosions = true; - } - ////////////////////////////////////////////////////////////////////////// - } - } - } -} diff --git a/Code/CryEngine/Cry3DEngine/StatObjPhys.cpp b/Code/CryEngine/Cry3DEngine/StatObjPhys.cpp deleted file mode 100644 index 2163983781..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObjPhys.cpp +++ /dev/null @@ -1,2133 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : make physical representation - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "IndexedMesh.h" -#include "3dEngine.h" -#include "CGFContent.h" -#include "ObjMan.h" -#define SMALL_MESH_NUM_INDEX 30 - -#include - - -////////////////////////////////////////////////////////////////////////// -///////////////////////// Breakable Geometry ///////////////////////////// -////////////////////////////////////////////////////////////////////////// - -namespace -{ - template - struct SplitArray - { - T* ptr[2]; - T& operator[](int idx) { return ptr[idx >> 15][idx & ~(1 << 15)]; } - T* operator+(int idx) { return ptr[idx >> 15] + (idx & ~(1 << 15)); } - T* operator-(int idx) { return ptr[idx >> 15] - (idx & ~(1 << 15)); } - }; -} - -static inline int mapiTri(int itri, int* pIdx2iTri) -{ - int mask = (itri - BOP_NEWIDX0) >> 31; - return itri & mask | pIdx2iTri[itri - BOP_NEWIDX0 | mask]; -} - -static inline void swap(int* pSubsets, vtx_idx* pidx, int* pmap, int i1, int i2) -{ - int i = pSubsets[i1]; - pSubsets[i1] = pSubsets[i2]; - pSubsets[i2] = i; - i = pmap[i1]; - pmap[i1] = pmap[i2]; - pmap[i2] = i; - for (i = 0; i < 3; i++) - { - vtx_idx u = pidx[i1 * 3 + i]; - pidx[i1 * 3 + i] = pidx[i2 * 3 + i]; - pidx[i2 * 3 + i] = u; - } -} -static void qsort(int* pSubsets, vtx_idx* pidx, int* pmap, int ileft, int iright, int iter = 0) -{ - if (ileft >= iright) - { - return; - } - int i, ilast, diff = 0; - swap(pSubsets, pidx, pmap, ileft, (ileft + iright) >> 1); - for (ilast = ileft, i = ileft + 1; i <= iright; i++) - { - diff |= pSubsets[i] - pSubsets[ileft]; - if (pSubsets[i] < pSubsets[ileft] + iter) // < when iter==0 and <= when iter==1 - { - swap(pSubsets, pidx, pmap, ++ilast, i); - } - } - swap(pSubsets, pidx, pmap, ileft, ilast); - - if (diff) - { - qsort(pSubsets, pidx, pmap, ileft, ilast - 1, iter ^ 1); - qsort(pSubsets, pidx, pmap, ilast + 1, iright, iter ^ 1); - } -} - -static inline int check_mask(unsigned int* pMask, int i) -{ - return pMask[i >> 5] >> (i & 31) & 1; -} -static inline void set_mask(unsigned int* pMask, int i) -{ - pMask[i >> 5] |= 1u << (i & 31); -} -static inline void clear_mask(unsigned int* pMask, int i) -{ - pMask[i >> 5] &= ~(1u << (i & 31)); -} - -////////////////////////////////////////////////////////////////////////// -///////////////////////// Deformable Geometry //////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - -int CStatObj::SubobjHasDeformMorph(int iSubObj) -{ - int i; - char nameDeformed[256]; - cry_strcpy(nameDeformed, m_subObjects[iSubObj].name); - cry_strcat(nameDeformed, "_Destroyed"); - - for (i = m_subObjects.size() - 1; i >= 0 && strcmp(m_subObjects[i].name, nameDeformed); i--) - { - ; - } - return i; -} - -#define getBidx(islot) _getBidx(islot, pIdxABuf, pFaceToFace0A, pFace0ToFaceB, pIdxB) -static inline int _getBidx(int islot, int* pIdxABuf, uint16* pFaceToFace0A, int* pFace0ToFaceB, vtx_idx* pIdxB) -{ - int idx, mask; - idx = pFace0ToFaceB[pFaceToFace0A[pIdxABuf[islot] >> 2]] * 3 + (pIdxABuf[islot] & 3); - mask = idx >> 31; - return (pIdxB[idx & ~mask] & ~mask) + mask; -} - - -int CStatObj::SetDeformationMorphTarget(IStatObj* pDeformed) -{ - int i, j, k, j0, it, ivtx, nVtxA, nVtxAnew, nVtxA0, nIdxA, nFacesA, nFacesB; - vtx_idx* pIdxA, * pIdxB; - int* pVtx2IdxA, * pIdxABuf, * pFace0ToFaceB; - uint16* pFaceToFace0A, * pFaceToFace0B, maxFace0; - _smart_ptr pMeshA, pMeshB, pMeshBnew; - strided_pointer pVtxA, pVtxB, pVtxBnew; - strided_pointer pTexA, pTexB, pTexBnew; - strided_pointer pTangentsA, pTangentsB, pTangentsBnew; - if (!GetRenderMesh()) - { - MakeRenderMesh(); - } - if (!pDeformed->GetRenderMesh()) - { - ((CStatObj*)pDeformed)->MakeRenderMesh(); - } - if (!(pMeshA = GetRenderMesh()) || !(pMeshB = pDeformed->GetRenderMesh())) - { - return 0; - } - pFaceToFace0A = m_pMapFaceToFace0; - if (!pFaceToFace0A) - { - return 0; - } - pFaceToFace0B = ((CStatObj*)pDeformed)->m_pMapFaceToFace0; - if (!pFaceToFace0B) - { - return 0; - } - if (pMeshA->GetMorphBuddy()) - { - return 1; - } - - if (pMeshA->GetVerticesCount() > 0xffff || pMeshB->GetVerticesCount() > 0xffff) - { - return 0; - } - - nVtxA0 = nVtxA = pMeshA->GetVerticesCount(); - pVtxA.data = (Vec3*)pMeshA->GetPosPtr(pVtxA.iStride, FSL_READ); - pTexA.data = (Vec2*)pMeshA->GetUVPtr(pTexA.iStride, FSL_READ); - pTangentsA.data = (SPipTangents*)pMeshA->GetTangentPtr(pTangentsA.iStride, FSL_READ); - - pVtxB.data = (Vec3*)pMeshB->GetPosPtr(pVtxB.iStride, FSL_READ); - pTexB.data = (Vec2*)pMeshB->GetUVPtr(pTexB.iStride, FSL_READ); - pTangentsB.data = (SPipTangents*)pMeshB->GetTangentPtr(pTangentsB.iStride, FSL_READ); - - nFacesB = pMeshB->GetIndicesCount(); - nFacesB /= 3; - pIdxB = pMeshB->GetIndexPtr(FSL_READ); - nIdxA = pMeshA->GetIndicesCount(); - nFacesA = nIdxA /= 3; - pIdxA = pMeshA->GetIndexPtr(FSL_READ); - - memset(pVtx2IdxA = new int[nVtxA + 1], 0, (nVtxA + 1) * sizeof(int)); - for (i = 0; i < nIdxA; i++) - { - pVtx2IdxA[pIdxA[i]]++; - } - for (i = maxFace0 = 0; i < nFacesA; i++) - { - maxFace0 = max(maxFace0, pFaceToFace0A[i]); - } - for (i = 0; i < nVtxA; i++) - { - pVtx2IdxA[i + 1] += pVtx2IdxA[i]; - } - pIdxABuf = new int[nIdxA]; - for (i = nFacesA - 1; i >= 0; i--) - { - for (j = 2; j >= 0; j--) - { - pIdxABuf[--pVtx2IdxA[pIdxA[i * 3 + j]]] = i * 4 + j; - } - } - - for (i = nFacesB - 1; i >= 0; i--) - { - maxFace0 = max(maxFace0, pFaceToFace0B[i]); - } - memset(pFace0ToFaceB = new int[maxFace0 + 1], -1, (maxFace0 + 1) * sizeof(int)); - for (i = nFacesB - 1; i >= 0; i--) - { - pFace0ToFaceB[pFaceToFace0B[i]] = i; - } - - for (i = nVtxAnew = k = 0; i < nVtxA; i++) - { - for (j = pVtx2IdxA[i]; j < pVtx2IdxA[i + 1] - 1; j++) - { - for (k = pVtx2IdxA[i + 1] - 1; k > j; k--) - { - if (getBidx(k - 1) > getBidx(k)) - { - it = pIdxABuf[k - 1], pIdxABuf[k - 1] = pIdxABuf[k], pIdxABuf[k] = it; - } - } - } - for (j = pVtx2IdxA[i] + 1; j < pVtx2IdxA[i + 1]; j++) - { - nVtxAnew += iszero(getBidx(j) - getBidx(j - 1)) ^ 1; -#ifdef _DEBUG - if ((pVtxB[getBidx(j)] - pVtxB[getBidx(j - 1)]).len2() > sqr(0.01f)) - { - k++; - } -#endif - } - } - - pMeshBnew = GetRenderer()->CreateRenderMesh("StatObj_Deformed", GetFilePath()); - pMeshBnew->UpdateVertices(0, nVtxA0 + nVtxAnew, 0, VSF_GENERAL, 0u); - if (nVtxAnew) - { - pMeshA = GetRenderer()->CreateRenderMesh("StatObj_MorphTarget", GetFilePath()); - m_pRenderMesh->CopyTo(pMeshA, nVtxAnew); - pVtxA.data = (Vec3*)pMeshA->GetPosPtr(pVtxA.iStride, FSL_SYSTEM_UPDATE); - pTexA.data = (Vec2*)pMeshA->GetUVPtr(pTexA.iStride, FSL_SYSTEM_UPDATE); - pTangentsA.data = (SPipTangents*)pMeshA->GetTangentPtr(pTangentsA.iStride, FSL_SYSTEM_UPDATE); - nIdxA = pMeshA->GetIndicesCount(); - pIdxA = pMeshA->GetIndexPtr(FSL_READ); - m_pRenderMesh = pMeshA; - } - - pVtxBnew.data = (Vec3*)pMeshBnew->GetPosPtr(pVtxBnew.iStride, FSL_SYSTEM_UPDATE); - pTexBnew.data = (Vec2*)pMeshBnew->GetUVPtr(pTexBnew.iStride, FSL_SYSTEM_UPDATE); - pTangentsBnew.data = (SPipTangents*)pMeshBnew->GetTangentPtr(pTangentsBnew.iStride, FSL_SYSTEM_UPDATE); - - for (i = 0; i < nVtxA0; i++) - { - for (j = j0 = pVtx2IdxA[i]; j < pVtx2IdxA[i + 1]; j++) - { - if (j == pVtx2IdxA[i + 1] - 1 || getBidx(j) != getBidx(j + 1)) - { - if (j0 > pVtx2IdxA[i]) - { - ivtx = nVtxA++; - pVtxA[ivtx] = pVtxA[i]; - pTangentsA[ivtx] = pTangentsA[i]; - pTexA[ivtx] = pTexA[i]; - for (k = j0; k <= j; k++) - { - pIdxA[(pIdxABuf[k] >> 2) * 3 + (pIdxABuf[k] & 3)] = ivtx; - } - } - else - { - ivtx = i; - } - if ((it = getBidx(j)) >= 0) - { -#ifdef _DEBUG - static float maxdist = 0.1f; - float dist = (pVtxB[it] - pVtxA[i]).len(); - if (dist > maxdist) - { - k++; - } -#endif - pVtxBnew[ivtx] = pVtxB[it]; - pTangentsBnew[ivtx] = pTangentsB[it]; - pTexBnew[ivtx] = pTexB[it]; - } - else - { - pVtxBnew[ivtx] = pVtxA[i]; - pTangentsBnew[ivtx] = pTangentsA[i]; - pTexBnew[ivtx] = pTexA[i]; - } - j0 = j + 1; - } - } - } - - pMeshA->SetMorphBuddy(pMeshBnew); - pDeformed->SetFlags(pDeformed->GetFlags() | STATIC_OBJECT_HIDDEN); - - pMeshBnew->UnlockStream(VSF_GENERAL); - pMeshBnew->UnlockStream(VSF_TANGENTS); - pMeshA->UnlockStream(VSF_GENERAL); - pMeshA->UnlockStream(VSF_TANGENTS); - - delete [] pVtx2IdxA; - delete [] pIdxABuf; - delete [] pFace0ToFaceB; - - return 1; -} - - -static inline float max_fast(float op1, float op2) { return (op1 + op2 + fabsf(op1 - op2)) * 0.5f; } -static inline float min_fast(float op1, float op2) { return (op1 + op2 - fabsf(op1 - op2)) * 0.5f; } - -static void UpdateWeights(const Vec3& pt, float r, float strength, IRenderMesh* pMesh, IRenderMesh* pWeights) -{ - int i, nVtx = pMesh->GetVerticesCount(); - float r2 = r * r, rr = 1 / r; - strided_pointer pVtx; - strided_pointer pWeight; - pVtx.data = (Vec3*)pMesh->GetPosPtr(pVtx.iStride, FSL_SYSTEM_UPDATE); - pWeight.data = (Vec2*)pWeights->GetPosPtr(pWeight.iStride, FSL_SYSTEM_UPDATE); - - if (r > 0) - { - for (i = 0; i < nVtx; i++) - { - if ((pVtx[i] - pt).len2() < r2) - { - pWeight[i].x = max_fast(0.0f, min_fast(1.0f, pWeight[i].x + strength * (1 - (pVtx[i] - pt).len() * rr))); - } - } - } - else - { - for (i = 0; i < nVtx; i++) - { - pWeight[i].x = max_fast(0.0f, min_fast(1.0f, pWeight[i].x + strength)); - } - } -} - - -IStatObj* CStatObj::DeformMorph(const Vec3& pt, float r, float strength, IRenderMesh* pWeights) -{ - int i, j; - CStatObj* pObj = this; - - if (!GetCVars()->e_DeformableObjects) - { - return pObj; - } - - if (m_bHasDeformationMorphs) - { - if (!(GetFlags() & STATIC_OBJECT_CLONE)) - { - pObj = (CStatObj*)Clone(true, false, false); - pObj->m_bUnmergable = 1; - for (i = pObj->GetSubObjectCount() - 1; i >= 0; i--) - { - if ((j = pObj->SubobjHasDeformMorph(i)) >= 0) - { - pObj->GetSubObject(i)->pWeights = pObj->GetSubObject(i)->pStatObj->GetRenderMesh()->GenerateMorphWeights(); - pObj->GetSubObject(j)->pStatObj->SetFlags(pObj->GetSubObject(j)->pStatObj->GetFlags() | STATIC_OBJECT_HIDDEN); - } - } - return pObj->DeformMorph(pt, r, strength, pWeights); - } - for (i = m_subObjects.size() - 1; i >= 0; i--) - { - if (m_subObjects[i].pWeights) - { - UpdateWeights(m_subObjects[i].tm.GetInverted() * pt, - r * (fabs_tpl(m_subObjects[i].tm.GetColumn(0).len2() - 1.0f) < 0.01f ? 1.0f : 1.0f / m_subObjects[i].tm.GetColumn(0).len()), - strength, m_subObjects[i].pStatObj->GetRenderMesh(), m_subObjects[i].pWeights); - } - } - } - else if (m_nSubObjectMeshCount == 0 && m_pRenderMesh && m_pRenderMesh->GetMorphBuddy()) - { - if (!pWeights) - { - pObj = new CStatObj; - pObj->m_pMaterial = m_pMaterial; - pObj->m_fObjectRadius = m_fObjectRadius; - pObj->m_vBoxMin = m_vBoxMin; - pObj->m_vBoxMax = m_vBoxMax; - pObj->m_vVegCenter = m_vVegCenter; - pObj->m_fRadiusHors = m_fRadiusHors; - pObj->m_fRadiusVert = m_fRadiusVert; - pObj->m_nFlags = m_nFlags | STATIC_OBJECT_CLONE; - pObj->m_bHasDeformationMorphs = true; - pObj->m_nSubObjectMeshCount = 1; - pObj->m_bSharesChildren = true; - pObj->m_subObjects.resize(1); - pObj->m_subObjects[0].nType = STATIC_SUB_OBJECT_MESH; - pObj->m_subObjects[0].name = ""; - pObj->m_subObjects[0].properties = ""; - pObj->m_subObjects[0].bIdentityMatrix = true; - pObj->m_subObjects[0].tm.SetIdentity(); - pObj->m_subObjects[0].localTM.SetIdentity(); - pObj->m_subObjects[0].pStatObj = this; - pObj->m_subObjects[0].nParent = -1; - pObj->m_subObjects[0].helperSize = Vec3(0, 0, 0); - pObj->m_subObjects[0].pWeights = GetRenderMesh()->GenerateMorphWeights(); - return pObj->DeformMorph(pt, r, strength, pWeights); - } - UpdateWeights(pt, r, strength, m_pRenderMesh, pWeights); - } - - return this; -} - - -IStatObj* CStatObj::HideFoliage() -{ - int i;//,j,idx0; - CMesh* pMesh; - if (!GetIndexedMesh()) - { - return this; - } - - pMesh = GetIndexedMesh()->GetMesh(); - for (i = pMesh->m_subsets.size() - 1; i >= 0; i--) - { - if (pMesh->m_subsets[i].nPhysicalizeType == PHYS_GEOM_TYPE_NONE) - { - //pMesh->m_subsets[i].nMatFlags |= MTL_FLAG_NODRAW; - //idx0 = i>0 ? pMesh->m_subsets[i-1].nFirstIndexId+pMesh->m_subsets[i-1].nNumIndices : 0; - pMesh->m_subsets.erase(pMesh->m_subsets.begin() + i); - /*for(j=i;jm_subsets.size();j++) - { - memmove(pMesh->m_pIndices+idx0, pMesh->m_pIndices+pMesh->m_subsets[j].nFirstIndexId, - pMesh->m_subsets[j].nNumIndices*sizeof(pMesh->m_pIndices[0])); - pMesh->m_subsets[j].nFirstIndexId = idx0; - idx0 += pMesh->m_subsets[j].nNumIndices; - } - pMesh->m_nIndexCount = idx0;*/ - } - } - Invalidate(); - - return this; -} - - -////////////////////////////////////////////////////////////////////////// -//////////////////////// SubObjects ///////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -static inline int GetEdgeByBuddy(mesh_data* pmd, int itri, int itri_buddy) -{ - int iedge = 0, imask; - imask = pmd->pTopology[itri].ibuddy[1] - itri_buddy; - imask = (imask - 1) >> 31 ^ imask >> 31; - iedge = 1 & imask; - imask = pmd->pTopology[itri].ibuddy[2] - itri_buddy; - imask = (imask - 1) >> 31 ^ imask >> 31; - iedge = iedge & ~imask | 2 & imask; - return iedge; -} -static inline float qmin(float op1, float op2) { return (op1 + op2 - fabsf(op1 - op2)) * 0.5f; } -static inline float qmax(float op1, float op2) { return (op1 + op2 + fabsf(op1 - op2)) * 0.5f; } - -static int __s_pvtx_map_dummy = 0; - -static void SyncToRenderMesh(SSyncToRenderMeshContext* ctx, volatile int* updateState) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ThreeDEngine); - - IGeometry* pPhysGeom = ctx->pObj->GetPhysGeom() ? ctx->pObj->GetPhysGeom()->pGeom : 0; - if (pPhysGeom) - { - pPhysGeom->Lock(0); - IStatObj* pObjSrc = (IStatObj*)pPhysGeom->GetForeignData(0); - if (pPhysGeom->GetForeignData(DATA_MESHUPDATE) || !ctx->pObj->m_hasClothTangentsData || pObjSrc != ctx->pObj && pObjSrc != ctx->pObj->GetCloneSourceObject()) - { // skip all updates if the mesh was altered - if (updateState) - { - CryInterlockedDecrement(updateState); - } - pPhysGeom->Unlock(0); - return; - } - } - Vec3 n, edge, t; - int i, j; - Vec3* vmin = ctx->vmin, * vmax = ctx->vmax; - int iVtx0 = ctx->iVtx0, nVtx = ctx->nVtx, mask = ctx->mask; - strided_pointer pVtx = ctx->pVtx; - int* pVtxMap = (mask == ~0) ? &__s_pvtx_map_dummy : ctx->pVtxMap; - float rscale = ctx->rscale; - SClothTangentVtx* ctd = ctx->ctd; - strided_pointer pMeshVtx = ctx->pMeshVtx; - strided_pointer pTangents = ctx->pTangents; - strided_pointer pNormals = ctx->pNormals; - - AABB bbox; - bbox.Reset(); - - if (pMeshVtx) - { - for (i = iVtx0; i < nVtx; i++) - { - Vec3 v = pVtx[j = pVtxMap[i & ~mask] | i & mask] * rscale; - bbox.Add(v); - pMeshVtx[i] = v; - } - *vmin = bbox.min; - *vmax = bbox.max; - } - - if (pTangents) - { - for (i = iVtx0; i < nVtx; i++) - { - SMeshTangents tb(pTangents[i]); - int16 nsg; - tb.GetR(nsg); - - j = pVtxMap[i & ~mask] | i & mask; - n = pNormals[j] * aznumeric_cast(ctd[i].sgnNorm); - edge = (pVtx[ctd[i].ivtxT] - pVtx[j]).normalized(); - Matrix33 M; - crossproduct_matrix(pNormals[j] * ctd[i].edge.y, M) *= nsg; - M += Matrix33(IDENTITY) * ctd[i].edge.x; - t = M.GetInverted() * (edge - n * ctd[i].edge.z); - (t -= n * (n * t)).Normalize(); - t.x = qmin(qmax(t.x, -0.9999f), 0.9999f); - t.y = qmin(qmax(t.y, -0.9999f), 0.9999f); - t.z = qmin(qmax(t.z, -0.9999f), 0.9999f); - Vec3 b = n.Cross(t) * nsg; - - tb = SMeshTangents(t, b, nsg); - tb.ExportTo(pTangents[i]); - } - } - - if (updateState) - { - CryInterlockedDecrement(updateState); - } - if (pPhysGeom) - { - pPhysGeom->Unlock(0); - } -} - -IStatObj* CStatObj::UpdateVertices(strided_pointer pVtx, strided_pointer pNormals, int iVtx0, int nVtx, int* pVtxMap, float rscale) -{ - CStatObj* pObj = this; - if (m_pRenderMesh) - { - strided_pointer pMeshVtx; - strided_pointer pTangents; - int i, j, mask = 0, dummy = 0, nVtxFull; - if (!pVtxMap) - { - pVtxMap = &dummy, mask = ~0; - } - AABB bbox; - bbox.Reset(); - SClothTangentVtx* ctd; - - if (!m_hasClothTangentsData && GetPhysGeom() && GetPhysGeom()->pGeom->GetType() == GEOM_TRIMESH && m_pRenderMesh) - { - if (GetPhysGeom()->pGeom->GetForeignData(DATA_MESHUPDATE)) - { - return this; - } - ctd = m_pClothTangentsData = new SClothTangentVtx[nVtxFull = m_pRenderMesh->GetVerticesCount()]; - m_hasClothTangentsData = 1; - memset(m_pClothTangentsData, 0, sizeof(SClothTangentVtx) * nVtxFull); - mesh_data* pmd = (mesh_data*)GetPhysGeom()->pGeom->GetData(); - m_pRenderMesh->LockForThreadAccess(); - pTangents.data = (SPipTangents*)m_pRenderMesh->GetTangentPtr(pTangents.iStride, FSL_READ); - for (i = 0; i < pmd->nTris; i++) - { - for (j = 0; j < 3; j++) - { - ctd[pmd->pIndices[i * 3 + j]].ivtxT = i, ctd[pmd->pIndices[i * 3 + j]].sgnNorm = j; - } - } - if (pmd->pVtxMap) - { - for (i = 0; i < pmd->nVertices; i++) - { - ctd[i].ivtxT = ctd[pmd->pVtxMap[i]].ivtxT, ctd[i].sgnNorm = ctd[pmd->pVtxMap[i]].sgnNorm; - } - } - - for (i = 0; i < nVtxFull && pTangents; i++) - { - j = pmd->pVtxMap ? pmd->pVtxMap[i] : i; - - SMeshTangents tb = SMeshTangents(pTangents[i]); - Vec3 t, b, s; - tb.GetTBN(t, b, s); - - float tedge = -1, tedgeDenom = 0; - int itri = ctd[i].ivtxT, iedge = ctd[i].sgnNorm, itriT = 0, iedgeT = 0, itri1, loop; - Vec3 n, edge, edge0; - n.zero(); - - for (int iter = 0; iter < 2; iter++) - { - for (edge0.zero(), loop = 20;; ) // iter==0 - trace cw, 1 - ccw - { - edge = (pmd->pVertices[pmd->pIndices[itri * 3 + inc_mod3[iedge]]] - pmd->pVertices[pmd->pIndices[itri * 3 + iedge]]) * (1.f - iter * 2.f); - n += (edge0 ^ edge) * (iter * 2.f - 1.f); - edge0 = edge; - if (sqr(t * edge) * tedgeDenom > tedge * edge.len2()) - { - tedge = sqr(t * edge), tedgeDenom = edge.len2(), itriT = itri, iedgeT = iedge; - } - itri1 = pmd->pTopology[itri].ibuddy[iedge]; - if (itri1 == ctd[i].ivtxT || itri1 < 0 || --loop < 0) - { - break; - } - iedge = GetEdgeByBuddy(pmd, itri1, itri) + 1 + iter; - itri = itri1; - iedge -= 3 & (2 - iedge) >> 31; - } - if (itri1 >= 0 && iter == 0) - { - n.zero(); - } - itri = ctd[i].ivtxT; - iedge = dec_mod3[ctd[i].sgnNorm]; - } - n += pmd->pVertices[pmd->pIndices[ctd[i].ivtxT * 3 + 1]] - pmd->pVertices[pmd->pIndices[ctd[i].ivtxT * 3]] ^ - pmd->pVertices[pmd->pIndices[ctd[i].ivtxT * 3 + 2]] - pmd->pVertices[pmd->pIndices[ctd[i].ivtxT * 3]]; - - if ((ctd[i].ivtxT = pmd->pIndices[itriT * 3 + iedgeT]) == j) - { - ctd[i].ivtxT = pmd->pIndices[itriT * 3 + inc_mod3[iedgeT]]; - } - edge = (pmd->pVertices[ctd[i].ivtxT] - pmd->pVertices[j]).normalized(); - - ctd[i].edge.Set(edge * t, edge * b, edge * s); - ctd[i].sgnNorm = sgnnz(n * s); - } - if (pObj != this) - { - memcpy(pObj->m_pClothTangentsData = new SClothTangentVtx[nVtxFull], ctd, nVtxFull * sizeof(SClothTangentVtx)); - pObj->m_hasClothTangentsData = 1; - } - pObj->SetFlags(pObj->GetFlags() & ~STATIC_OBJECT_CANT_BREAK); - m_pRenderMesh->UnLockForThreadAccess(); - } - - if (GetTetrLattice() || m_hasSkinInfo) - { - Vec3 sz = GetAABB().GetSize(); - float szmin = min(min(sz.x, sz.y), sz.z), szmax = max(max(sz.x, sz.y), sz.z), szmed = sz.x + sz.y + sz.y - szmin - szmax; - if (!m_hasSkinInfo) - { - PrepareSkinData(Matrix34(IDENTITY), 0, min(szmin * 0.5f, szmed * 0.15f)); - } - if (pVtx) - { - return SkinVertices(pVtx, Matrix34(IDENTITY)); - } - return pObj; - } - - if (!pVtx) - { - return pObj; - } - - if (!(GetFlags() & STATIC_OBJECT_CLONE)) - { - pObj = (CStatObj*)Clone(true, true, false); - pObj->m_pRenderMesh->KeepSysMesh(true); - } - - IRenderMesh* mesh = pObj->m_pRenderMesh; - mesh->LockForThreadAccess(); - pMeshVtx.data = (Vec3*)((mesh = pObj->m_pRenderMesh)->GetPosPtr(pMeshVtx.iStride, FSL_SYSTEM_UPDATE)); - if (m_hasClothTangentsData && m_pClothTangentsData) - { - pTangents.data = (SPipTangents*)mesh->GetTangentPtr(pTangents.iStride, FSL_SYSTEM_UPDATE); - } - - if (!m_pAsyncUpdateContext) - { - m_pAsyncUpdateContext = new SSyncToRenderMeshContext; - } - else - { - m_pAsyncUpdateContext->jobExecutor.WaitForCompletion(); - } - m_pAsyncUpdateContext->Set(&pObj->m_vBoxMin, &pObj->m_vBoxMax, iVtx0, nVtx, pVtx, pVtxMap, mask, rscale - , m_pClothTangentsData, pMeshVtx, pTangents, pNormals, pObj); - - if (GetCVars()->e_RenderMeshUpdateAsync) - { - SSyncToRenderMeshContext* pAsyncUpdateContext = m_pAsyncUpdateContext; - volatile int* updateState = mesh->SetAsyncUpdateState(); - m_pAsyncUpdateContext->jobExecutor.StartJob([pAsyncUpdateContext, updateState]() - { - SyncToRenderMesh(pAsyncUpdateContext, updateState); - }); - } - else - { - SyncToRenderMesh(m_pAsyncUpdateContext, NULL); - if (m_hasClothTangentsData && m_pClothTangentsData) - { - mesh->UnlockStream(VSF_TANGENTS); - } - mesh->UnlockStream(VSF_GENERAL); - } - mesh->UnLockForThreadAccess(); - } - return pObj; -} - - -////////////////////////////////////////////////////////////////////////// -namespace -{ - CryCriticalSection g_cPrepareSkinData; -} - -void CStatObj::PrepareSkinData(const Matrix34& mtxSkelToMesh, IGeometry* pPhysSkel, float r) -{ - if (m_hasSkinInfo || pPhysSkel && pPhysSkel->GetType() != GEOM_TRIMESH) - { - return; - } - - // protect again possible paralle calls, if streaming is here, but mainthread also reaches this function - // before streaming thread has finished and wants to prepare data also - AUTO_LOCK(g_cPrepareSkinData); - - // recheck again to guard again creating the object two times - if (m_hasSkinInfo) - { - return; - } - - m_nFlags |= STATIC_OBJECT_DYNAMIC; - if (!m_pRenderMesh) - { - if (!m_pDelayedSkinParams) - { - m_pDelayedSkinParams = new SDelayedSkinParams; - m_pDelayedSkinParams->mtxSkelToMesh = mtxSkelToMesh; - m_pDelayedSkinParams->pPhysSkel = pPhysSkel; - m_pDelayedSkinParams->r = r; - } - return; - } - m_pRenderMesh->KeepSysMesh(true); - - int i, j, nVtx; - Vec3 vtx[4]; - geom_world_data gwd[2]; - geom_contact* pcontact; - mesh_data* md; - // two spheres for checking intersections against skeleton - CRY_PHYSICS_REPLACEMENT_ASSERT(); - AZ_UNUSED(pcontact); - AZ_UNUSED(j); - strided_pointer pVtx; - Matrix34 mtxMeshToSkel = mtxSkelToMesh.GetInverted(); - ITetrLattice* pLattice = GetTetrLattice(); - if (pLattice) - { - pPhysSkel = pLattice->CreateSkinMesh(); - } - - gwd[1].scale = mtxSkelToMesh.GetColumn0().len(); - gwd[1].offset = mtxSkelToMesh.GetTranslation(); - gwd[1].R = Matrix33(mtxSkelToMesh) * (1.0f / gwd[1].scale); - m_pRenderMesh->GetBBox(vtx[0], vtx[1]); - vtx[1] -= vtx[0]; - primitives::sphere sph; - sph.center.zero(); - sph.r = r > 0.0f ? r : min(min(vtx[1].x, vtx[1].y), vtx[1].z); - sph.r *= 3.0f; - assert(pPhysSkel); - PREFAST_ASSUME(pPhysSkel); - md = (mesh_data*)pPhysSkel->GetData(); - IRenderMesh::ThreadAccessLock lockrm(m_pRenderMesh); - pVtx.data = (Vec3*)m_pRenderMesh->GetPosPtr(pVtx.iStride, FSL_READ); - SSkinVtx* pSkinInfo = m_pSkinInfo = new SSkinVtx[nVtx = m_pRenderMesh->GetVerticesCount()]; - m_hasSkinInfo = 1; - - for (i = 0; i < nVtx; i++) - { - Vec3 v = pVtx[i]; - if (pSkinInfo[i].bVolumetric = (pLattice && pLattice->CheckPoint(mtxMeshToSkel * v, pSkinInfo[i].idx, pSkinInfo[i].w))) - { - pSkinInfo[i].M = Matrix33(md->pVertices[pSkinInfo[i].idx[1]] - md->pVertices[pSkinInfo[i].idx[0]], - md->pVertices[pSkinInfo[i].idx[2]] - md->pVertices[pSkinInfo[i].idx[0]], - md->pVertices[pSkinInfo[i].idx[3]] - md->pVertices[pSkinInfo[i].idx[0]]).GetInverted(); - } - else - { - gwd[0].offset = v; - } - } - if (pLattice) - { - pPhysSkel->Release(); - } -} - -IStatObj* CStatObj::SkinVertices(strided_pointer pSkelVtx, const Matrix34& mtxSkelToMesh) -{ - if (!m_hasSkinInfo && m_pDelayedSkinParams) - { - PrepareSkinData(m_pDelayedSkinParams->mtxSkelToMesh, m_pDelayedSkinParams->pPhysSkel, m_pDelayedSkinParams->r); - if (m_hasSkinInfo) - { - delete m_pDelayedSkinParams, m_pDelayedSkinParams = 0; - } - } - if (!m_pRenderMesh || !m_hasSkinInfo) - { - return this; - } - CStatObj* pObj = this; - if (!(GetFlags() & STATIC_OBJECT_CLONE)) - { - pObj = (CStatObj*)Clone(true, true, false); - } - if (!pObj->m_pClonedSourceObject || !pObj->m_pClonedSourceObject->m_pRenderMesh) - { - return pObj; - } - - strided_pointer pVtx; - strided_pointer pTangents, pTangents0; - Vec3 vtx[4], t, b; - Matrix33 M; - AABB bbox; - bbox.Reset(); - int i, j, nVtx; - SSkinVtx* pSkinInfo = m_pSkinInfo; - pObj->m_pRenderMesh->LockForThreadAccess(); - pObj->m_pClonedSourceObject->m_pRenderMesh->LockForThreadAccess(); - - pVtx.data = (Vec3*)pObj->m_pRenderMesh->GetPosPtr(pVtx.iStride, FSL_SYSTEM_UPDATE); - pTangents.data = (SPipTangents*)pObj->m_pRenderMesh->GetTangentPtr(pTangents.iStride, FSL_SYSTEM_UPDATE); - pTangents0.data = (SPipTangents*)pObj->m_pClonedSourceObject->m_pRenderMesh->GetTangentPtr(pTangents0.iStride, FSL_READ); - nVtx = pObj->m_pRenderMesh->GetVerticesCount(); - if (!pVtx.data) - { - nVtx = 0; - } - const bool canUseTangents = pTangents.data && pTangents0.data; - for (i = 0; i < nVtx; i++) - { - Vec3 v3 = pVtx[i]; - if (pSkinInfo[i].idx[0] >= 0) - { - for (j = 0, v3.zero(); j < 3 + pSkinInfo[i].bVolumetric; j++) - { - v3 += pSkinInfo[i].w[j] * (vtx[j] = mtxSkelToMesh * pSkelVtx[pSkinInfo[i].idx[j]]); - } - if (!pSkinInfo[i].bVolumetric) - { - Vec3 n = (vtx[1] - vtx[0] ^ vtx[2] - vtx[0]).normalized(); - v3 += n * pSkinInfo[i].w[3]; - Vec3 edge = (vtx[1] + vtx[2] - vtx[0] * 2).normalized(); - M = Matrix33(edge, n ^ edge, n); - } - else - { - M = Matrix33(vtx[1] - vtx[0], vtx[2] - vtx[0], vtx[3] - vtx[0]); - } - M *= pSkinInfo[i].M; - if (canUseTangents) - { - SMeshTangents tb(pTangents0[i]); - - tb.RotateBy(M); - tb.ExportTo(pTangents0[i]); - } - pVtx[i] = v3; - } - bbox.Add(v3); - } - pObj->m_pRenderMesh->UnlockStream(VSF_GENERAL); - pObj->m_pRenderMesh->UnlockStream(VSF_TANGENTS); - pObj->m_pClonedSourceObject->m_pRenderMesh->UnlockStream(VSF_TANGENTS); - pObj->m_pClonedSourceObject->m_pRenderMesh->UnLockForThreadAccess(); - pObj->m_pRenderMesh->UnLockForThreadAccess(); - pObj->m_vBoxMin = bbox.min; - pObj->m_vBoxMax = bbox.max; - return pObj; -} - -////////////////////////////////////////////////////////////////////////// - -int CStatObj::Physicalize(IPhysicalEntity* pent, pe_geomparams* pgp, int id, const char* szPropsOverride) -{ - int res = -1; - if (GetFlags() & STATIC_OBJECT_COMPOUND) - { - Matrix34 mtxId(IDENTITY); - res = PhysicalizeSubobjects(pent, pgp->pMtx3x4 ? pgp->pMtx3x4 : &mtxId, pgp->mass, pgp->density, id, 0, szPropsOverride); - } - - { - int i, nNoColl, iNoColl = 0; - float V; - if (pgp->mass < 0 && pgp->density < 0) - { - GetPhysicalProperties(pgp->mass, pgp->density); - } - for (i = m_arrPhysGeomInfo.GetGeomCount() - 1, nNoColl = 0, V = 0.0f; i >= 0; i--) - { - if (m_arrPhysGeomInfo.GetGeomType(i) == PHYS_GEOM_TYPE_DEFAULT) - { - V += m_arrPhysGeomInfo[i]->V; - } - else - { - iNoColl = i, ++nNoColl; - } - } - int flags0 = pgp->flags; - ISurfaceTypeManager* pSurfaceMan = Get3DEngine()->GetMaterialManager()->GetSurfaceTypeManager(); - if (phys_geometry* pSolid = m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT]) - { - if (pSolid->surface_idx < pSolid->nMats) - { - if (ISurfaceType* pMat = pSurfaceMan->GetSurfaceType(pSolid->pMatMapping[pSolid->surface_idx])) - { - if (pMat->GetPhyscalParams().collType >= 0) - { - (pgp->flags &= ~(geom_collides | geom_floats)) |= pMat->GetPhyscalParams().collType; - } - } - } - } - if (pgp->mass > pgp->density && V > 0.0f) // mass is set instead of density and V is valid - { - pgp->density = pgp->mass / V, pgp->mass = -1.0f; - } - (pgp->flags &= ~geom_colltype_explosion) |= geom_colltype_explosion & ~-(int)m_bDontOccludeExplosions; - (pgp->flags &= ~geom_manually_breakable) |= geom_manually_breakable & - (int)m_bBreakableByGame; - if (m_nFlags & STATIC_OBJECT_NO_PLAYER_COLLIDE) - { - pgp->flags &= ~geom_colltype_player; - } - if (m_nSpines && m_arrPhysGeomInfo.GetGeomCount() - nNoColl <= 1 && - (nNoColl == 1 || nNoColl == 2 && m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE] && m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT])) - { - pe_params_structural_joint psj; - bool bHasJoints = false; - if (m_arrPhysGeomInfo.GetGeomCount() > nNoColl) - { - if (nNoColl && m_pParentObject && m_pParentObject != this) - { - CStatObj* pParent; - for (pParent = m_pParentObject; pParent->m_pParentObject; pParent = pParent->m_pParentObject) - { - ; - } - bHasJoints = pParent->FindSubObject_StrStr("$joint") != 0; - psj.partid[0] = id; - psj.pt = m_arrPhysGeomInfo[iNoColl]->origin; - psj.bBreakable = 0; - } - res = pent->AddGeometry(m_arrPhysGeomInfo[PHYS_GEOM_TYPE_DEFAULT], pgp, id); - id += 1024; - } - pgp->minContactDist = 1.0f; - pgp->density = 5.0f; - if (nNoColl == 1) - { - pgp->flags = geom_log_interactions | geom_squashy; - pgp->flags |= geom_colltype_foliage_proxy; - res = pent->AddGeometry(m_arrPhysGeomInfo[iNoColl], pgp, psj.partid[1] = id); - if (bHasJoints) - { - pent->SetParams(&psj); - } - } - else - { - pgp->flags = geom_squashy | geom_colltype_obstruct; - pent->AddGeometry(m_arrPhysGeomInfo[PHYS_GEOM_TYPE_OBSTRUCT], pgp, psj.partid[1] = id); - id += 1024; - if (bHasJoints) - { - pent->SetParams(&psj); - } - pgp->flags = geom_log_interactions | geom_colltype_foliage_proxy; - int flagsCollider = pgp->flagsCollider; - pgp->flagsCollider = 0; - pent->AddGeometry(m_arrPhysGeomInfo[PHYS_GEOM_TYPE_NO_COLLIDE], pgp, psj.partid[1] = id); - pgp->flagsCollider = flagsCollider; - if (bHasJoints) - { - pent->SetParams(&psj); - } - } - } - else if (nNoColl == 1 && m_arrPhysGeomInfo.GetGeomCount() == 2) - { // one solid, one obstruct or nocoll proxy -> use single part with ray proxy - res = pent->AddGeometry(m_arrPhysGeomInfo[iNoColl], pgp, id); - pgp->flags |= geom_proxy; - pent->AddGeometry(m_arrPhysGeomInfo[iNoColl ^ 1], pgp, res); - pgp->flags &= ~geom_proxy; - } - else - { // add all solid and non-colliding geoms as individual parts - for (i = 0; i < m_arrPhysGeomInfo.GetGeomCount(); i++) - { - if (m_arrPhysGeomInfo.GetGeomType(i) == PHYS_GEOM_TYPE_DEFAULT) - { - res = pent->AddGeometry(m_arrPhysGeomInfo[i], pgp, id), id += 1024; - } - } - pgp->idmatBreakable = -1; - for (i = 0; i < m_arrPhysGeomInfo.GetGeomCount(); i++) - { - if (m_arrPhysGeomInfo.GetGeomType(i) == PHYS_GEOM_TYPE_NO_COLLIDE) - { - pgp->flags = geom_colltype_ray, res = pent->AddGeometry(m_arrPhysGeomInfo[i], pgp, id), id += 1024; - } - else if (m_arrPhysGeomInfo.GetGeomType(i) == PHYS_GEOM_TYPE_OBSTRUCT) - { - pgp->flags = geom_colltype_obstruct, res = pent->AddGeometry(m_arrPhysGeomInfo[i], pgp, id), id += 1024; - } - } - } - pgp->flags = flags0; - - if (m_arrPhysGeomInfo.GetGeomCount() >= 10 && pent->GetType() == PE_STATIC) - { - pe_params_flags pf; - pf.flagsOR = pef_parts_traceable; - pf.flagsAND = ~pef_traceable; - pent->SetParams(&pf); - } - } - return res; -} - -#define isalpha(c) isalpha((unsigned char)c) -#define isdigit(c) isdigit((unsigned char)c) - -int CStatObj::PhysicalizeSubobjects(IPhysicalEntity* pent, const Matrix34* pMtx, float mass, float density, int id0, strided_pointer pJointsIdMap, const char* szPropsOverride) -{ - int i, j, i0, i1, len = 0, len1, nObj = GetSubObjectCount(), ipart[2], nparts, bHasPlayerOnlyGeoms = 0, nGeoms = 0, id, idNext = 0; - float V[2], M, scale, jointsz; - const char* pval, * properties; - bool bHasSkeletons = false, bAutoJoints = false; - Matrix34 mtxLoc; - Vec3 dist; - primitives::box joint_bbox; - IGeometry* pJointBox = 0; - - primitives::box bbox; - IStatObj::SSubObject* pSubObj, * pSubObj1; - pe_articgeomparams partpos; - pe_params_structural_joint psj; - pe_params_flags pf; - geom_world_data gwd; - intersection_params ip; - geom_contact* pcontacts; - scale = pMtx ? pMtx->GetColumn(0).len() : 1.0f; - ip.bStopAtFirstTri = ip.bNoBorder = true; - - bbox.Basis.SetIdentity(); - bbox.size.Set(0.5f, 0.5f, 0.5f); - bbox.center.zero(); - joint_bbox = bbox; - pf.flagsOR = 0; - - for (i = 0; i < nObj; i++) - { - if ((pSubObj = GetSubObject(i))->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && pSubObj->pStatObj->GetPhysGeom() && - pSubObj->bHidden && (!strncmp(pSubObj->name, "childof_", 8))) - { - pSubObj1 = FindSubObject((const char*)pSubObj->name + 8); - if (pSubObj1) - { - pSubObj1 = GetSubObject(pSubObj->nParent); - if (pSubObj1) - { - if (strstr(pSubObj1->properties, "group")) - { - pSubObj->bHidden = pSubObj1->bHidden; - } - } - } - } - } - - for (i = 0, V[0] = V[1] = M = 0; i < nObj; i++) - { - if ((pSubObj = GetSubObject(i))->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && pSubObj->pStatObj->GetPhysGeom() && !pSubObj->bHidden && strncmp(pSubObj->name, "skeleton_", 9)) - { - float mi = -1.0f, dens = -1.0f, Vsubobj; - for (j = 0, Vsubobj = 0.0f; pSubObj->pStatObj->GetPhysGeom(j); j++) - { - if (((CStatObj*)pSubObj->pStatObj)->m_arrPhysGeomInfo.GetGeomType(j) == PHYS_GEOM_TYPE_DEFAULT) - { - Vsubobj += pSubObj->pStatObj->GetPhysGeom(j)->V; - } - } - pSubObj->pStatObj->GetPhysicalProperties(mi, dens); - if (dens > 0) - { - mi = Vsubobj * cube(scale) * dens; // Calc mass. - } - if (mi != 0.0f) - { - V[isneg(mi)] += Vsubobj * cube(scale); - } - M += max(0.0f, mi); - - if (((CStatObj*)pSubObj->pStatObj)->m_nRenderTrisCount <= 0 && - pSubObj->pStatObj->GetPhysGeom()->pGeom->GetForeignData() == pSubObj->pStatObj && - strstr(pSubObj->properties, "other_rendermesh")) - { - Vec3 center = pSubObj->localTM * (((CStatObj*)pSubObj->pStatObj)->m_vBoxMin + ((CStatObj*)pSubObj->pStatObj)->m_vBoxMax) * 0.5f; - float mindist = 1e10f, curdist; - for (j = 0, i0 = i; j < nObj; j++) - { - if (j != i) - { - pSubObj1 = GetSubObject(j); - if (pSubObj1 && pSubObj1->pStatObj && ((CStatObj*)pSubObj1->pStatObj)->m_nRenderTrisCount > 0) - { - curdist = (pSubObj1->localTM * (((CStatObj*)pSubObj1->pStatObj)->m_vBoxMin + - ((CStatObj*)pSubObj1->pStatObj)->m_vBoxMax) * 0.5f - center).len2(); - if (curdist < mindist) - { - mindist = curdist; - i0 = j; - } - } - } - } - pSubObj->pStatObj->GetPhysGeom()->pGeom->SetForeignData(GetSubObject(i0)->pStatObj, 0); - } - } - } - for (i = 0; i < nObj; i++) - { - GetSubObject(i)->nBreakerJoints = 0; - } - if (mass <= 0) - { - mass = M * density; - } - if (density <= 0) - { - if ((V[0] + V[1]) != 0) - { - density = mass / (V[0] + V[1]); - } - else - { - density = 1000.0f; // Some default. - } - } - partpos.flags = geom_collides | geom_floats; - - for (i = 0; i < nObj; i++) - { - if ((pSubObj = GetSubObject(i))->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && pSubObj->pStatObj->GetPhysGeom() && - !pSubObj->bHidden && strcmp(pSubObj->name, "colltype_player") == 0) - { - bHasPlayerOnlyGeoms = 1; - } - } - - for (i = 0; i < nObj; i++) - { - if ((pSubObj = GetSubObject(i))->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && ((CStatObj*)pSubObj->pStatObj)->m_arrPhysGeomInfo.GetGeomCount() && !pSubObj->bHidden) - { - if (pJointsIdMap) - { - continue; - } - partpos.idbody = i + id0; - partpos.pMtx3x4 = pMtx ? &(mtxLoc = *pMtx * pSubObj->tm) : &pSubObj->tm; - - float mi = 0, di = 0; - if (pSubObj->pStatObj->GetPhysicalProperties(mi, di)) - { - if (mi >= 0) - { - partpos.mass = mi, partpos.density = 0; - } - else - { - partpos.mass = 0, partpos.density = di; - } - } - else - { - partpos.density = density; - } - if (GetCVars()->e_ObjQuality != CONFIG_LOW_SPEC) - { - partpos.idmatBreakable = ((CStatObj*)pSubObj->pStatObj)->m_idmatBreakable; - if (((CStatObj*)pSubObj->pStatObj)->m_bVehicleOnlyPhysics) - { - partpos.flags = geom_colltype6; - } - else - { - partpos.flags = (geom_colltype_solid & ~(geom_colltype_player & - bHasPlayerOnlyGeoms)) | geom_colltype_ray | geom_floats | geom_colltype_explosion; - if (bHasPlayerOnlyGeoms && strcmp(pSubObj->name, "colltype_player") == 0) - { - partpos.flags = geom_colltype_player; - } - } - } - else - { - partpos.idmatBreakable = -1; - if (((CStatObj*)pSubObj->pStatObj)->m_bVehicleOnlyPhysics) - { - partpos.flags = geom_colltype6; - } - } - if (!strncmp(pSubObj->name, "skeleton_", 9)) - { - if (!GetCVars()->e_DeformableObjects) - { - continue; - } - bHasSkeletons = true; - if (mi <= 0.0f) - { - partpos.mass = 1.0f, partpos.density = 0.0f; - } - } - partpos.flagsCollider &= ~geom_destroyed_on_break; - if (strstr(pSubObj->properties, "pieces")) - { - partpos.flagsCollider |= geom_destroyed_on_break; - } - if (strstr(pSubObj->properties, "noselfcoll")) - { - partpos.flags &= ~(partpos.flagsCollider = geom_colltype_debris); - } - if ((id = pSubObj->pStatObj->Physicalize(pent, &partpos, i + id0)) >= 0) - { - nGeoms++, idNext = id + 1; - } - if (strstr(pSubObj->properties, "force_joint")) - { - pe_params_structural_joint psj1; - psj1.id = 1024 + i; - psj1.partid[0] = i + id0; - psj1.partid[1] = pSubObj->nParent + id0; - psj1.bBreakable = 0; - psj1.pt = *partpos.pMtx3x4 * (pSubObj->pStatObj->GetBoxMin() + pSubObj->pStatObj->GetBoxMax()) * 0.5f; - pent->SetParams(&psj1); - } - } - else - if (pSubObj->nType == STATIC_SUB_OBJECT_DUMMY && !strncmp(pSubObj->name, "$joint", 6)) - { - properties = szPropsOverride ? szPropsOverride : (const char*)pSubObj->properties; - psj.pt = pSubObj->tm.GetTranslation(); - psj.n = pSubObj->tm.GetColumn(2).normalized(); - psj.axisx = pSubObj->tm.GetColumn(0).normalized(); - float maxdim = max(pSubObj->helperSize.x, pSubObj->helperSize.y); - maxdim = max(maxdim, pSubObj->helperSize.z); - psj.szSensor = jointsz = maxdim * pSubObj->tm.GetColumn(0).len(); - psj.partidEpicenter = -1; - psj.bBroken = 0; - psj.id = i; - psj.bReplaceExisting = 1; - if (pSubObj->name[6] != ' ') - { - gwd.offset = psj.pt; - ipart[1] = nObj; - for (i0 = nparts = 0; i0 < nObj && nparts < 2; i0++) - { - if ((pSubObj1 = GetSubObject(i0))->nType == STATIC_SUB_OBJECT_MESH && pSubObj1->pStatObj && pSubObj1->pStatObj->GetPhysGeom() && - strncmp(pSubObj1->name, "skeleton_", 9) && !strstr(pSubObj1->properties, "group")) - { - gwd.offset = pSubObj1->tm.GetInverted() * psj.pt; - pSubObj1->pStatObj->GetPhysGeom()->pGeom->GetBBox(&bbox); - dist = bbox.Basis * (gwd.offset - bbox.center); - for (j = 0; j < 3; j++) - { - dist[j] = max(0.0f, fabs_tpl(dist[j]) - bbox.size[j]); - } - gwd.scale = jointsz; - if (fabs_tpl(pSubObj1->tm.GetColumn(0).len2() - 1.0f) > 0.01f) - { - gwd.scale /= pSubObj1->tm.GetColumn(0).len(); - } - - // Make a geometry box for intersection. - if (!pJointBox) - { - // Create box for joint - CRY_PHYSICS_REPLACEMENT_ASSERT(); - } - { - WriteLockCond lockColl; - if (dist.len2() < sqr(gwd.scale * 0.5f) && pSubObj1->pStatObj->GetPhysGeom()->pGeom->IntersectLocked(pJointBox, 0, &gwd, &ip, pcontacts, lockColl)) - { - ipart[nparts++] = i0; - } - } // lock - } - } - if (nparts == 0) - { - continue; - } - GetSubObject(ipart[0])->pStatObj->GetPhysGeom()->pGeom->GetBBox(&bbox); - gwd.offset = GetSubObject(ipart[0])->tm * bbox.center; - j = isneg((gwd.offset - psj.pt) * psj.n); - i0 = ipart[j]; - i1 = ipart[1 ^ j]; - - if (strlen((const char*)pSubObj->name) >= 7 && !strncmp((const char*)pSubObj->name + 7, "sample", 6)) - { - psj.bBroken = 2; - } - else if (strlen((const char*)pSubObj->name) >= 7 && !strncmp((const char*)pSubObj->name + 7, "impulse", 7)) - { - psj.bBroken = 2, psj.id = joint_impulse, psj.bReplaceExisting = 0, bAutoJoints = true; - } - } - else - { - for (i0 = 0; i0 < nObj && ((pSubObj1 = GetSubObject(i0))->nType != STATIC_SUB_OBJECT_MESH || - (strlen((const char*)pSubObj->name) >= 7 && (strncmp((const char*)pSubObj->name + 7, pSubObj1->name, len = strlen(pSubObj1->name)) || isalpha(pSubObj->name[7 + len])))); i0++) - { - ; - } - for (i1 = 0; i1 < nObj && ((pSubObj1 = GetSubObject(i1))->nType != STATIC_SUB_OBJECT_MESH || - (strlen((const char*)pSubObj->name) >= 8 && (strncmp((const char*)pSubObj->name + 8 + len, pSubObj1->name, len1 = strlen(pSubObj1->name)) || isalpha(pSubObj->name[8 + len + len1])))); i1++) - { - ; - } - if (i0 >= nObj && i1 >= nObj) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Error: cannot resolve part names in %s (%s)", (const char*)pSubObj->name, (const char*)m_szFileName); - } - } - if (pJointsIdMap) - { - i0 = pJointsIdMap[i0], i1 = pJointsIdMap[i1]; - } - psj.partid[0] = i0 + id0; - psj.partid[1] = i1 + id0; - psj.maxForcePush = psj.maxForcePull = psj.maxForceShift = psj.maxTorqueBend = psj.maxTorqueTwist = 1E20f; - if (pMtx) - { - psj.pt = *pMtx * psj.pt; - psj.n = pMtx->TransformVector(psj.n).normalized(); - psj.axisx = pMtx->TransformVector(psj.axisx).normalized(); - } - - pval = strstr(properties, "limit"); - if (pval && (pval - 11 < properties - 11 || strncmp(pval - 11, "constraint_", 11))) - { - for (pval += 5; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxTorqueBend = aznumeric_caster(atof(pval)); - } - //psj.maxTorqueTwist = psj.maxTorqueBend*5; - psj.maxForcePull = psj.maxTorqueBend; - psj.maxForceShift = psj.maxTorqueBend; - // psj.maxForcePush = psj.maxForcePull*2.5f; - psj.bBreakable = 1; - } - pval = strstr(properties, "twist"); - if (pval) - { - for (pval += 5; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxTorqueTwist = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "bend"); - if (pval) - { - for (pval += 4; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxTorqueBend = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "push"); - if (pval) - { - for (pval += 4; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxForcePush = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "pull"); - if (pval) - { - for (pval += 4; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxForcePull = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "shift"); - if (pval) - { - for (pval += 5; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.maxForceShift = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "damage_accum"); - if (pval) - { - for (pval += 5; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.damageAccum = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "damage_accum_threshold"); - if (pval) - { - for (pval += 5; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - psj.damageAccumThresh = aznumeric_caster(atof(pval)); - } - } - if (psj.maxForcePush + psj.maxForcePull + psj.maxForceShift + psj.maxTorqueBend + psj.maxTorqueTwist > 4.9E20f) - { - if (azsscanf(properties, "%f %f %f %f %f", - &psj.maxForcePush, &psj.maxForcePull, &psj.maxForceShift, &psj.maxTorqueBend, &psj.maxTorqueTwist) == 5) - { - psj.maxForcePush *= density; - psj.maxForcePull *= density; - psj.maxForceShift *= density; - psj.maxTorqueBend *= density; - psj.maxTorqueTwist *= density; - psj.bBreakable = 1; - } - else - { - psj.bBreakable = 0; - } - } - psj.bDirectBreaksOnly = strstr(properties, "hits_only") != 0; - psj.limitConstraint.zero(); - psj.bConstraintWillIgnoreCollisions = 1; - - len = 16; - pval = strstr(properties, "constraint_limit"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval); pval++); - if (pval) - { - psj.limitConstraint.z = aznumeric_caster(atof(pval)); - } - } - else - { - len = 5; - pval = strstr(properties, "C_lmt"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval); pval++) - ; - if (pval) - { - psj.limitConstraint.z = aznumeric_caster(atof(pval)); - } - } - } - len = 17; - pval = strstr(properties, "constraint_minang"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval) && *pval != '-'; pval++); - if (pval) - { - psj.limitConstraint.x = aznumeric_caster(DEG2RAD(atof(pval))); - } - } - else - { - len = 5; - pval = strstr(properties, "C_min"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval) && *pval != '-'; pval++) - ; - if (pval) - { - psj.limitConstraint.x = aznumeric_caster(DEG2RAD(atof(pval))); - } - } - } - len = 17; - pval = strstr(properties, "constraint_maxang"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval) && *pval != '-'; pval++); - if (pval) - { - psj.limitConstraint.y = aznumeric_caster(DEG2RAD(atof(pval))); - } - } - else - { - len = 5; - pval = strstr(properties, "C_max"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval) && *pval != '-'; pval++); - if (pval) - { - psj.limitConstraint.y = aznumeric_caster(DEG2RAD(atof(pval))); - } - } - } - len = 18; - pval = strstr(properties, "constraint_damping"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval); pval++); - if (pval) - { - psj.dampingConstraint = aznumeric_caster(atof(pval)); - } - } - else - { - len = 5; - pval = strstr(properties, "C_dmp"); - if (pval) - { - for (pval += len; *pval && !isdigit(*pval); pval++); - if (pval) - { - psj.dampingConstraint = aznumeric_caster(atof(pval)); - } - } - } - if (strstr(properties, "constraint_collides") || strstr(properties, "C_coll")) - { - psj.bConstraintWillIgnoreCollisions = 0; - } - scale = GetFloatCVar(e_JointStrengthScale); - psj.maxForcePush *= scale; - psj.maxForcePull *= scale; - psj.maxForceShift *= scale; - psj.maxTorqueBend *= scale; - psj.maxTorqueTwist *= scale; - psj.limitConstraint.z *= scale; - pent->SetParams(&psj); - if (!gEnv->bMultiplayer && strstr(properties, "gameplay_critical")) - { - pf.flagsOR |= pef_override_impulse_scale; - } - if (gEnv->bMultiplayer && strstr(properties, "mp_break_always")) - { - pf.flagsOR |= pef_override_impulse_scale; - } - if (strstr(properties, "player_can_break")) - { - pf.flagsOR |= pef_players_can_break; - } - - if (strstr(pSubObj->properties, "breaker")) - { - if (GetSubObject(i0)) - { - GetSubObject(i0)->nBreakerJoints++; - } - if (GetSubObject(i1)) - { - GetSubObject(i1)->nBreakerJoints++; - } - } - } - } - - if (bAutoJoints) - { - psj.idx = -2; // tels the physics to try and generate joints - pent->SetParams(&psj); - } - - pe_params_part pp; - if (bHasSkeletons) - { - for (i = 0; i < nObj; i++) - { - if ((pSubObj = GetSubObject(i))->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && pSubObj->pStatObj->GetPhysGeom() && !pSubObj->bHidden && - !strncmp(pSubObj->name, "skeleton_", 9)) - { - pSubObj1 = FindSubObject((const char*)pSubObj->name + 9); - if (pSubObj1) - { - pe_params_skeleton ps; - properties = szPropsOverride ? szPropsOverride : (const char*)pSubObj->properties; - pval = strstr(properties, "stiffness"); - if (pval) - { - for (pval += 9; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.stiffness = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "thickness"); - if (pval) - { - for (pval += 9; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.thickness = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "max_stretch"); - if (pval) - { - for (pval += 11; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.maxStretch = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "max_impulse"); - if (pval) - { - for (pval += 11; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.maxImpulse = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "skin_dist"); - if (pval) - { - for (pval += 9; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - pp.minContactDist = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "hardness"); - if (pval) - { - for (pval += 8; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.hardness = aznumeric_caster(atof(pval)); - } - } - pval = strstr(properties, "explosion_scale"); - if (pval) - { - for (pval += 15; *pval && !isdigit(*pval); pval++) - { - ; - } - if (pval) - { - ps.explosionScale = aznumeric_caster(atof(pval)); - } - } - - pp.partid = ps.partid = aznumeric_cast((pSubObj1 - &m_subObjects[0])) + id0; - pp.idSkeleton = i + id0; - pent->SetParams(&pp); - pent->SetParams(&ps); - ((CStatObj*)pSubObj1->pStatObj) - ->PrepareSkinData( - pSubObj1->localTM.GetInverted() * pSubObj->localTM, pSubObj->pStatObj->GetPhysGeom()->pGeom, - is_unused(pp.minContactDist) ? 0.0f : pp.minContactDist); - } - } - } - } - - new(&pp)pe_params_part; - for (i = 0; i < nObj; i++) - { - pSubObj = GetSubObject(i); - if (pSubObj->nType == STATIC_SUB_OBJECT_MESH && pSubObj->pStatObj && pSubObj->pStatObj->GetPhysGeom() && !pSubObj->bHidden && - !strncmp(pSubObj->name, "childof_", 8)) - { - pSubObj1 = FindSubObject((const char*)pSubObj->name + 8); - if (pSubObj1) - { - pSubObj1 = GetSubObject(pSubObj->nParent); - if (pSubObj1 && strstr(pSubObj1->properties, "group")) - { - pp.partid = i + id0; - pp.idParent = aznumeric_caster(pSubObj1 - &m_subObjects[0]); - pent->SetParams(&pp); - pSubObj->bHidden = true; - } - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Iterate through sub objects and update hide mask. - ////////////////////////////////////////////////////////////////////////// - m_nInitialSubObjHideMask = 0; - for (size_t a = 0, numsub = m_subObjects.size(); a < numsub; a++) - { - SSubObject& subObj = m_subObjects[a]; - if (subObj.pStatObj && subObj.nType == STATIC_SUB_OBJECT_MESH && subObj.bHidden) - { - m_nInitialSubObjHideMask |= ((uint64)1 << a); - } - } - - if (nGeoms >= 10 && pent->GetType() == PE_STATIC) - { - pf.flagsOR |= pef_parts_traceable, pf.flagsAND = ~pef_traceable; - } - - if (pf.flagsOR) - { - pent->SetParams(&pf); - } - if (pJointBox) - { - pJointBox->Release(); - } - return idNext - 1; -} - -//static const int g_nRanges = 5; -static int g_rngb2a[] = { 0, 'A', 26, 'a', 52, '0', 62, '+', 63, '/' }; -static int g_rnga2b[] = { '+', 62, '/', 63, '0', 52, 'A', 0, 'a', 26 }; -static inline int mapsymb(int symb, int* pmap, int n) -{ - int i, j; - for (i = j = 0; j < n; j++) - { - i += isneg(symb - pmap[j * 2]); - } - i = n - 1 - i; - return symb - pmap[i * 2] + pmap[i * 2 + 1]; -} - -static int Bin2ascii(const unsigned char* pin, int sz, unsigned char* pout) -{ - int a0, a1, a2, i, j, nout, chr[4]; - for (i = nout = 0; i < sz; i += 3, nout += 4) - { - a0 = pin[i]; - j = isneg(i + 1 - sz); - a1 = pin[i + j] & - j; - j = isneg(i + 2 - sz); - a2 = pin[i + j * 2] & - j; - chr[0] = a0 >> 2; - chr[1] = a0 << 4 & 0x30 | (a1 >> 4) & 0x0F; - chr[2] = a1 << 2 & 0x3C | a2 >> 6 & 0x03; - chr[3] = a2 & 0x03F; - for (j = 0; j < 4; j++) - { - *pout++ = mapsymb(chr[j], g_rngb2a, 5); - } - } - return nout; -} -static int Ascii2bin(const unsigned char* pin, int sz, unsigned char* pout, int szout) -{ - int a0, a1, a2, a3, i, nout; - for (i = nout = 0; i < sz - 4; i += 4, nout += 3) - { - a0 = mapsymb(pin[i + 0], g_rnga2b, 5); - a1 = mapsymb(pin[i + 1], g_rnga2b, 5); - a2 = mapsymb(pin[i + 2], g_rnga2b, 5); - a3 = mapsymb(pin[i + 3], g_rnga2b, 5); - *pout++ = a0 << 2 | a1 >> 4; - *pout++ = a1 << 4 & 0xF0 | a2 >> 2 & 0x0F; - *pout++ = a2 << 6 & 0xC0 | a3; - } - a0 = mapsymb(pin[i + 0], g_rnga2b, 5); - a1 = mapsymb(pin[i + 1], g_rnga2b, 5); - a2 = mapsymb(pin[i + 2], g_rnga2b, 5); - a3 = mapsymb(pin[i + 3], g_rnga2b, 5); - if (nout < szout) - { - *pout++ = a0 << 2 | a1 >> 4, nout++; - } - if (nout < szout) - { - *pout++ = a1 << 4 & 0xF0 | a2 >> 2 & 0x0F, nout++; - } - if (nout < szout) - { - *pout++ = a2 << 6 & 0xC0 | a3, nout++; - } - return nout; -} - - -static void SerializeData(TSerialize ser, const char* name, void* pdata, int size) -{ - /*static std::vector arr; - if (ser.IsReading()) - { - ser.Value(name, arr); - memcpy(pdata, &arr[0], size); - } else - { - arr.resize(((size-1)>>2)+1); - memcpy(&arr[0], pdata, size); - ser.Value(name, arr); - }*/ - static string str; - if (!size) - { - return; - } - if (ser.IsReading()) - { - ser.Value(name, str); - int n = Ascii2bin((const unsigned char*)(const char*)str, str.length(), (unsigned char*)pdata, size); - assert(n == size); - (void)n; - } - else - { - str.resize(((size - 1) / 3 + 1) * 4); - int n = Bin2ascii((const unsigned char*)pdata, size, (unsigned char*)(const char*)str); - assert(n == str.length()); - (void)n; - ser.Value(name, str); - } -} - - -int CStatObj::Serialize(TSerialize ser) -{ - ser.BeginGroup("StatObj"); - ser.Value("Flags", m_nFlags); - if (GetFlags() & STATIC_OBJECT_COMPOUND) - { - int i, nParts = m_subObjects.size(); - bool bVal; - string srcObjName; - ser.Value("nParts", nParts); - if (m_pClonedSourceObject) - { - SetSubObjectCount(nParts); - for (i = 0; i < nParts; i++) - { - ser.BeginGroup("part"); - ser.Value("bGenerated", bVal = !ser.IsReading() && m_subObjects[i].pStatObj && - m_subObjects[i].pStatObj->GetFlags() & STATIC_OBJECT_GENERATED && !m_subObjects[i].bHidden); - if (bVal) - { - if (ser.IsReading()) - { - (m_subObjects[i].pStatObj = gEnv->p3DEngine->CreateStatObj())->AddRef(); - } - m_subObjects[i].pStatObj->Serialize(ser); - } - else - { - ser.Value("subobj", m_subObjects[i].name); - if (ser.IsReading()) - { - IStatObj::SSubObject* pSrcSubObj = m_pClonedSourceObject->FindSubObject(m_subObjects[i].name); - if (pSrcSubObj) - { - m_subObjects[i] = *pSrcSubObj; - if (pSrcSubObj->pStatObj) - { - pSrcSubObj->pStatObj->AddRef(); - } - } - } - } - bVal = m_subObjects[i].bHidden; - ser.Value("hidden", bVal); - m_subObjects[i].bHidden = bVal; - ser.EndGroup(); - } - } - } - else - { -#if defined(CONSOLE) - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_ERROR, "Error: full geometry serialization should never happen on consoles. file: '%s' Geom: '%s'", m_szFileName.c_str(), m_szGeomName.c_str()); -#else - CMesh* pMesh; - int i, nVtx, nTris, nSubsets; - string matName; - _smart_ptr pMat; - - if (ser.IsReading()) - { - ser.Value("nvtx", nVtx = 0); - if (nVtx) - { - m_pIndexedMesh = new CIndexedMesh(); - pMesh = m_pIndexedMesh->GetMesh(); - assert(pMesh->m_pPositionsF16 == 0); - ser.Value("ntris", nTris); - ser.Value("nsubsets", nSubsets); - pMesh->SetVertexCount(nVtx); - pMesh->ReallocStream(CMesh::TEXCOORDS, 0, nVtx); - pMesh->ReallocStream(CMesh::TANGENTS, 0, nVtx); - pMesh->SetIndexCount(nTris * 3); - - for (i = 0; i < nSubsets; i++) - { - SMeshSubset mss; - ser.BeginGroup("subset"); - ser.Value("matid", mss.nMatID); - ser.Value("matflg", mss.nMatFlags); - ser.Value("vtx0", mss.nFirstVertId); - ser.Value("nvtx", mss.nNumVerts); - ser.Value("idx0", mss.nFirstIndexId); - ser.Value("nidx", mss.nNumIndices); - ser.Value("center", mss.vCenter); - ser.Value("radius", mss.fRadius); - pMesh->m_subsets.push_back(mss); - ser.EndGroup(); - } - - SerializeData(ser, "Positions", pMesh->m_pPositions, nVtx * sizeof(pMesh->m_pPositions[0])); - SerializeData(ser, "Normals", pMesh->m_pNorms, nVtx * sizeof(pMesh->m_pNorms[0])); - SerializeData(ser, "TexCoord", pMesh->m_pTexCoord, nVtx * sizeof(pMesh->m_pTexCoord[0])); - SerializeData(ser, "Tangents", pMesh->m_pTangents, nVtx * sizeof(pMesh->m_pTangents[0])); - SerializeData(ser, "Indices", pMesh->m_pIndices, nTris * 3 * sizeof(pMesh->m_pIndices[0])); - - ser.Value("Material", matName); - SetMaterial(gEnv->p3DEngine->GetMaterialManager()->FindMaterial(matName)); - ser.Value("MaterialAux", matName); - if (m_pMaterial && (pMat = gEnv->p3DEngine->GetMaterialManager()->FindMaterial(matName))) - { - if (pMat->GetSubMtlCount() > 0) - { - pMat = pMat->GetSubMtl(0); - } - for (i = m_pMaterial->GetSubMtlCount() - 1; i >= 0 && strcmp(m_pMaterial->GetSubMtl(i)->GetName(), matName); i--) - { - ; - } - if (i < 0) - { - i = m_pMaterial->GetSubMtlCount(); - m_pMaterial->SetSubMtlCount(i + 1); - m_pMaterial->SetSubMtl(i, pMat); - } - } - - int surfaceTypesId[MAX_SUB_MATERIALS]; - memset(surfaceTypesId, 0, sizeof(surfaceTypesId)); - int numIds = 0; - if (m_pMaterial) - { - numIds = m_pMaterial->FillSurfaceTypeIds(surfaceTypesId); - } - - - char* pIds = new char[nTris]; - memset(pIds, 0, nTris); - int j, itri; - for (i = 0; i < pMesh->m_subsets.size(); i++) - { - for (itri = (j = pMesh->m_subsets[i].nFirstIndexId) / 3; j < pMesh->m_subsets[i].nFirstIndexId + pMesh->m_subsets[i].nNumIndices; j += 3, itri++) - { - pIds[itri] = pMesh->m_subsets[i].nMatID; - } - } - - ser.Value("PhysSz", i); - if (i) - { - char* pbuf = new char[i]; - CMemStream stm(pbuf, i, false); - SerializeData(ser, "PhysMeshData", pbuf, i); - CRY_PHYSICS_REPLACEMENT_ASSERT(); - delete[] pbuf; - } - delete[] pIds; - - Invalidate(); - SetFlags(STATIC_OBJECT_GENERATED); - } - } - else - { - if (GetIndexedMesh(true)) - { - pMesh = GetIndexedMesh(true)->GetMesh(); - assert(pMesh->m_pPositionsF16 == 0); - ser.Value("nvtx", nVtx = pMesh->GetVertexCount()); - ser.Value("ntris", nTris = pMesh->GetIndexCount() / 3); - ser.Value("nsubsets", nSubsets = pMesh->m_subsets.size()); - - for (i = 0; i < nSubsets; i++) - { - ser.BeginGroup("subset"); - ser.Value("matid", pMesh->m_subsets[i].nMatID); - ser.Value("matflg", pMesh->m_subsets[i].nMatFlags); - ser.Value("vtx0", pMesh->m_subsets[i].nFirstVertId); - ser.Value("nvtx", pMesh->m_subsets[i].nNumVerts); - ser.Value("idx0", pMesh->m_subsets[i].nFirstIndexId); - ser.Value("nidx", pMesh->m_subsets[i].nNumIndices); - ser.Value("center", pMesh->m_subsets[i].vCenter); - ser.Value("radius", pMesh->m_subsets[i].fRadius); - ser.EndGroup(); - } - - if (m_pMaterial && m_pMaterial->GetSubMtlCount() > 0) - { - ser.Value("auxmatname", m_pMaterial->GetSubMtl(m_pMaterial->GetSubMtlCount() - 1)->GetName()); - } - - SerializeData(ser, "Positions", pMesh->m_pPositions, nVtx * sizeof(pMesh->m_pPositions[0])); - SerializeData(ser, "Normals", pMesh->m_pNorms, nVtx * sizeof(pMesh->m_pNorms[0])); - SerializeData(ser, "TexCoord", pMesh->m_pTexCoord, nVtx * sizeof(pMesh->m_pTexCoord[0])); - SerializeData(ser, "Tangents", pMesh->m_pTangents, nVtx * sizeof(pMesh->m_pTangents[0])); - SerializeData(ser, "Indices", pMesh->m_pIndices, nTris * 3 * sizeof(pMesh->m_pIndices[0])); - - ser.Value("Material", GetMaterial()->GetName()); - if (m_pMaterial && m_pMaterial->GetSubMtlCount() > 0) - { - ser.Value("MaterialAux", m_pMaterial->GetSubMtl(m_pMaterial->GetSubMtlCount() - 1)->GetName()); - } - else - { - ser.Value("MaterialAux", matName = ""); - } - - if (GetPhysGeom()) - { - CMemStream stm(false); - ser.Value("PhysSz", i = stm.GetUsedSize()); - SerializeData(ser, "PhysMeshData", stm.GetBuf(), i); - } - else - { - ser.Value("PhysSz", i = 0); - } - } - else - { - ser.Value("nvtx", nVtx = 0); - } - } -#endif // !defined(CONSOLE) - } - - ser.EndGroup(); //StatObj - - return 1; -} - - diff --git a/Code/CryEngine/Cry3DEngine/StatObjRend.cpp b/Code/CryEngine/Cry3DEngine/StatObjRend.cpp deleted file mode 100644 index 0cd0298241..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObjRend.cpp +++ /dev/null @@ -1,1068 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : prepare and add render element into renderer - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "../RenderDll/Common/Shadow_Renderer.h" -#include "IndexedMesh.h" -#include "VisAreas.h" -#include "GeomQuery.h" -#include "MatMan.h" -#include - -void CStatObj::Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - if (m_nFlags & STATIC_OBJECT_HIDDEN) - { - return; - } - -#ifndef _RELEASE - int nMaxDrawCalls = GetCVars()->e_MaxDrawCalls; - if (nMaxDrawCalls > 0) - { - // Don't calculate the number of drawcalls every single time a statobj is rendered. - // This creates a flickering effect with objects appearing and disappearing indicating that the limit has been reached. - static int nCurrObjCounter = 0; - if (((nCurrObjCounter++) & 31) == 1) - { - if (GetRenderer()->GetCurrentNumberOfDrawCalls() > nMaxDrawCalls) - { - return; - } - } - } -#endif // _RELEASE - - CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID()); - FillRenderObject(rParams, rParams.pRenderNode, m_pMaterial, NULL, pObj, passInfo); - - RenderInternal(pObj, rParams.nSubObjHideMask, rParams.lodValue, passInfo, SRendItemSorter(rParams.rendItemSorter), rParams.bForceDrawStatic); -} - -void CStatObj::RenderStreamingDebugInfo([[maybe_unused]] CRenderObject* pRenderObject) -{ -#ifndef _RELEASE - // CStatObj * pStreamable = m_pParentObject ? m_pParentObject : this; - - IStatObj* pStreamable = m_pLod0 ? m_pLod0 : this; - - int nKB = 0; - - if (pStreamable->GetRenderMesh()) - { - nKB += pStreamable->GetRenderMeshMemoryUsage(); - } - - for (int nLod = 1; pStreamable->GetLods() && nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - IStatObj* pLod = (CStatObj*)pStreamable->GetLods()[nLod]; - - if (!pLod) - { - continue; - } - - if (pLod->GetRenderMesh()) - { - nKB += pLod->GetRenderMeshMemoryUsage(); - } - } - - nKB >>= 10; - - if (nKB > GetCVars()->e_StreamCgfDebugMinObjSize) - { - // nKB = GetStreamableContentMemoryUsage(true) >> 10; - - const char* pComment = 0; - - pStreamable = pStreamable->GetParentObject() ? pStreamable->GetParentObject() : pStreamable; - - if (!pStreamable->IsUnloadable()) - { - pComment = "No stream"; - } - else if (!pStreamable->IsLodsAreLoadedFromSeparateFile() && pStreamable->GetLoadedLodsNum()) - { - pComment = "Single"; - } - else if (pStreamable->GetLoadedLodsNum() > 1) - { - pComment = "Split"; - } - else - { - pComment = "No LODs"; - } - - int nDiff = SATURATEB(int(float(nKB - GetCVars()->e_StreamCgfDebugMinObjSize) / max((int)1, GetCVars()->e_StreamCgfDebugMinObjSize) * 255)); - DrawBBoxLabeled(AABB(m_vBoxMin, m_vBoxMax), pRenderObject->m_II.m_Matrix, ColorB(nDiff, 255 - nDiff, 0, 255), - "%.2f mb, %s", 1.f / 1024.f * (float)nKB, pComment); - } -#endif //_RELEASE -} - -////////////////////////////////////////////////////////////////////// -void CStatObj::RenderCoverInfo(CRenderObject* pRenderObject) -{ - for (int i = 0; i < GetSubObjectCount(); ++i) - { - const IStatObj::SSubObject* subObject = GetSubObject(i); - if (subObject->nType != STATIC_SUB_OBJECT_DUMMY) - { - continue; - } - if (strstr(subObject->name, "$cover") == 0) - { - continue; - } - - Vec3 localBoxMin = -subObject->helperSize * 0.5f; - Vec3 localBoxMax = subObject->helperSize * 0.5f; - - GetRenderer()->GetIRenderAuxGeom()->DrawAABB( - AABB(localBoxMin, localBoxMax), - pRenderObject->m_II.m_Matrix * subObject->localTM, - true, ColorB(192, 0, 255, 255), - eBBD_Faceted); - } -} - -////////////////////////////////////////////////////////////////////// -void CStatObj::FillRenderObject(const SRendParams& rParams, IRenderNode* pRenderNode, _smart_ptr pMaterial, - SInstancingInfo* pInstInfo, CRenderObject*& pObj, const SRenderingPassInfo& passInfo) -{ - // FUNCTION_PROFILER_3DENGINE; - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Specify transformation - //////////////////////////////////////////////////////////////////////////////////////////////////// - - - assert(pObj); - if (!pObj) - { - return; - } - - pObj->m_pRenderNode = pRenderNode; - pObj->m_fSort = rParams.fCustomSortOffset; - SRenderObjData* pOD = NULL; - if (rParams.pInstance || rParams.m_pVisArea || pInstInfo || rParams.nVisionParams || rParams.nHUDSilhouettesParams || rParams.nSubObjHideMask) - { - pOD = pObj->GetObjData(); - - pOD->m_uniqueObjectId = reinterpret_cast(rParams.pInstance); - pOD->m_nHUDSilhouetteParams = rParams.nHUDSilhouettesParams; - - if (rParams.nSubObjHideMask && (m_pMergedRenderMesh != NULL)) - { - // Only pass SubObject hide mask for merged objects, because they have a correct correlation between Hide Mask and Render Chunks. - pOD->m_nSubObjHideMask = rParams.nSubObjHideMask; - pObj->m_ObjFlags |= FOB_MESH_SUBSET_INDICES; - } - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Set flags - //////////////////////////////////////////////////////////////////////////////////////////////////// - - pObj->m_ObjFlags |= rParams.dwFObjFlags; - - if (rParams.nTextureID >= 0) - { - pObj->m_nTextureID = rParams.nTextureID; - } - - assert(rParams.pMatrix); - { - pObj->m_II.m_Matrix = *rParams.pMatrix; - } - - pObj->m_II.m_AmbColor = rParams.AmbientColor; - pObj->m_nClipVolumeStencilRef = rParams.nClipVolumeStencilRef; - pObj->m_ObjFlags |= FOB_PARTICLE_SHADOWS; - pObj->m_fAlpha = rParams.fAlpha; - pObj->m_DissolveRef = rParams.nDissolveRef; - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Process bending - //////////////////////////////////////////////////////////////////////////////////////////////////// - if (pRenderNode && pRenderNode->GetRndFlags() & ERF_RECVWIND) - { - Get3DEngine()->SetupBending(pObj, pRenderNode, m_fRadiusVert, passInfo, false); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Set render quality - //////////////////////////////////////////////////////////////////////////////////////////////////// - - pObj->m_nRenderQuality = (uint16)(rParams.fRenderQuality * 65535.0f); - pObj->m_fDistance = rParams.fDistance; - - { - //clear, when exchange the state of pLightMapInfo to NULL, the pObj parameters must be update... - pObj->m_nSort = fastround_positive(rParams.fDistance * 2.0f); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Add render elements - //////////////////////////////////////////////////////////////////////////////////////////////////// - if (rParams.pMaterial) - { - pMaterial = rParams.pMaterial; - } - - // prepare multi-layer stuff to render object - if (!rParams.nMaterialLayersBlend && rParams.nMaterialLayers) - { - uint8 nFrozenLayer = (rParams.nMaterialLayers & MTL_LAYER_FROZEN) ? MTL_LAYER_FROZEN_MASK : 0; - uint8 nWetLayer = (rParams.nMaterialLayers & MTL_LAYER_WET) ? MTL_LAYER_WET_MASK : 0; - pObj->m_nMaterialLayers = (uint32)(nFrozenLayer << 24) | (nWetLayer << 16); - } - else - { - pObj->m_nMaterialLayers = rParams.nMaterialLayersBlend; - } - - if (rParams.nCustomData || rParams.nCustomFlags) - { - if (!pOD) - { - pOD = pObj->GetObjData(); - } - - pOD->m_nCustomData = rParams.nCustomData; - pOD->m_nCustomFlags = rParams.nCustomFlags; - } - - if (rParams.nAfterWater) - { - pObj->m_ObjFlags |= FOB_AFTER_WATER; - } - else - { - pObj->m_ObjFlags &= ~FOB_AFTER_WATER; - } - - pObj->m_pRenderNode = rParams.pRenderNode; - pObj->m_pCurrMaterial = pMaterial; - pObj->m_NoDecalReceiver = rParams.NoDecalReceiver; - if (Get3DEngine()->IsTessellationAllowed(pObj, passInfo)) - { - // Allow this RO to be tessellated, however actual tessellation will be applied if enabled in material - pObj->m_ObjFlags |= FOB_ALLOW_TESSELLATION; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CStatObj::RenderDebugInfo([[maybe_unused]] CRenderObject* pObj, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ -#ifndef _RELEASE - - if (!passInfo.IsGeneralPass()) - { - return false; - } - - IRenderer* pRend = GetRenderer(); - _smart_ptr pMaterial = pObj->m_pCurrMaterial; - - IRenderAuxGeom* pAuxGeom = GetRenderer()->GetIRenderAuxGeom(); - if (!pAuxGeom) - { - return false; - } - - Matrix34 tm = pObj->m_II.m_Matrix; - - // Convert "camera space" to "world space" - if (pObj->m_ObjFlags & FOB_NEAREST) - { - tm.AddTranslation(gEnv->pRenderer->GetCamera().GetPosition()); - } - - AABB bbox(m_vBoxMin, m_vBoxMax); - - bool bOnlyBoxes = GetCVars()->e_DebugDraw == -1; - - int e_DebugDraw = GetCVars()->e_DebugDraw; - string e_DebugDrawFilter = GetCVars()->e_DebugDrawFilter->GetString(); - bool bHasHelperFilter = e_DebugDrawFilter != ""; - bool bFiltered = false; - - if (e_DebugDraw == 1) - { - string name; - if (!m_szGeomName.empty()) - { - name = m_szGeomName.c_str(); - } - else - { - name = PathUtil::GetFile(m_szFileName.c_str()); - } - - bFiltered = name.find(e_DebugDrawFilter) == string::npos; - } - - if ((GetCVars()->e_DebugDraw == 1 || bOnlyBoxes) && !bFiltered) - { - if (!m_bMerged) - { - pAuxGeom->DrawAABB(bbox, tm, false, ColorB(0, 255, 255, 128), eBBD_Faceted); - } - else - { - pAuxGeom->DrawAABB(bbox, tm, false, ColorB(255, 200, 0, 128), eBBD_Faceted); - } - } - - - bool bNoText = e_DebugDraw < 0; - if (e_DebugDraw < 0) - { - e_DebugDraw = -e_DebugDraw; - } - - - - if (m_nRenderTrisCount > 0 && !bOnlyBoxes && !bFiltered) - { // cgf's name and tris num - int nThisLod = 0; - if (m_pLod0 && m_pLod0->GetLods()) - { - for (int i = 0; i < MAX_STATOBJ_LODS_NUM; i++) - { - if (m_pLod0->GetLods()[i] == this) - { - nThisLod = i; - break; - } - } - } - - const int nMaxUsableLod = (m_pLod0) ? m_pLod0->GetMaxUsableLod() : m_nMaxUsableLod; - const int nRealNumLods = (m_pLod0) ? m_pLod0->GetLoadedLodsNum() : m_nLoadedLodsNum; - - int nNumLods = nRealNumLods; - if (nNumLods > nMaxUsableLod + 1) - { - nNumLods = nMaxUsableLod + 1; - } - - int nLod = nThisLod; - if (nLod > nNumLods - 1) - { - nLod = nNumLods - 1; - } - - Vec3 pos = tm.TransformPoint((m_vBoxMin + m_vBoxMax) * 0.5f); - float color[4] = {1, 1, 1, 1}; - int nMats = m_pRenderMesh ? m_pRenderMesh->GetChunks().size() : 0; - int nRenderMats = 0; - - if (nMats) - { - for (int i = 0; i < nMats; ++i) - { - CRenderChunk& rc = m_pRenderMesh->GetChunks()[i]; - if (rc.pRE && rc.nNumIndices && rc.nNumVerts && ((rc.m_nMatFlags & MTL_FLAG_NODRAW) == 0)) - { - ++nRenderMats; - } - } - } - - switch (e_DebugDraw) - { - case 1: - { - const char* shortName = ""; - if (!m_szGeomName.empty()) - { - shortName = m_szGeomName.c_str(); - } - else - { - shortName = PathUtil::GetFile(m_szFileName.c_str()); - } - if (nNumLods > 1) - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s\n%d (LOD %d/%d)", shortName, m_nRenderTrisCount, nLod, nNumLods); - } - else - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s\n%d", shortName, m_nRenderTrisCount); - } - } - break; - - case 2: - { - ////////////////////////////////////////////////////////////////////////// - // Show colored poly count. - ////////////////////////////////////////////////////////////////////////// - int fMult = 1; - int nTris = m_nRenderTrisCount; - ColorB clr = ColorB(0, 0, 0, 255); - if (nTris >= 20000 * fMult) - { - clr = ColorB(255, 0, 0, 255); - } - else if (nTris >= 10000 * fMult) - { - clr = ColorB(255, 255, 0, 255); - } - else if (nTris >= 5000 * fMult) - { - clr = ColorB(0, 255, 0, 255); - } - else if (nTris >= 2500 * fMult) - { - clr = ColorB(0, 255, 255, 255); - } - else if (nTris > 1250 * fMult) - { - clr = ColorB(0, 0, 255, 255); - } - - if (pMaterial) - { - pMaterial = GetMatMan()->GetDefaultHelperMaterial(); - } - if (pObj) - { - pObj->m_II.m_AmbColor = ColorF(clr.r / 155.0f, clr.g / 155.0f, clr.b / 155.0f, 1); - pObj->m_nMaterialLayers = 0; - pObj->m_ObjFlags |= FOB_SELECTED; - } - - if (!bNoText) - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d", m_nRenderTrisCount); - } - - return false; - ////////////////////////////////////////////////////////////////////////// - } - case 3: - { - ////////////////////////////////////////////////////////////////////////// - // Show Lods - ////////////////////////////////////////////////////////////////////////// - ColorB clr; - if (nNumLods < 2) - { - if (m_nRenderTrisCount <= GetCVars()->e_LodMinTtris || nRealNumLods > 1) - { - clr = ColorB(50, 50, 50, 255); - } - else - { - clr = ColorB(255, 0, 0, 255); - float fAngle = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f) * gf_PI2; - clr.g = 127 + (int)(sinf(fAngle) * 120); // flashing color - } - } - else - { - if (nLod == 0) - { - clr = ColorB(255, 0, 0, 255); - } - else if (nLod == 1) - { - clr = ColorB(0, 255, 0, 255); - } - else if (nLod == 2) - { - clr = ColorB(0, 0, 255, 255); - } - else if (nLod == 3) - { - clr = ColorB(0, 255, 255, 255); - } - else if (nLod == 4) - { - clr = ColorB(255, 255, 0, 255); - } - else if (nLod == 5) - { - clr = ColorB(255, 0, 255, 255); - } - else - { - clr = ColorB(255, 255, 255, 255); - } - } - - if (pMaterial) - { - pMaterial = GetMatMan()->GetDefaultHelperMaterial(); - } - if (pObj) - { - pObj->m_II.m_AmbColor = ColorF(clr.r / 180.0f, clr.g / 180.0f, clr.b / 180.0f, 1); - pObj->m_nMaterialLayers = 0; - pObj->m_ObjFlags |= FOB_SELECTED; - } - - // Don't skip objects with single lod (as they should flash) - if (pObj && !bNoText) - { - const int nLod0 = nNumLods > 1 ? GetMinUsableLod() : 0; // Always 0 if one lod - const int maxLod = nNumLods > 1 ? GetMaxUsableLod() : 0; // Always 0 if one lod - - clr.toFloat4(color); // Actually use the colours calculated already to indicate lod - - const bool bRenderNodeValid(pObj && pObj->m_pRenderNode && ((UINT_PTR)(void*)(pObj->m_pRenderNode) > 0)); - IRenderNode* pRN = (IRenderNode*)pObj->m_pRenderNode; - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d [%d;%d] (%d/%.1f)", - nLod, nLod0, maxLod, - bRenderNodeValid ? pRN->GetLodRatio() : -1, pObj->m_fDistance); - } - - return false; - ////////////////////////////////////////////////////////////////////////// - } - case 4: - { - // Show texture usage. - if (m_pRenderMesh) - { - int nTexMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial); - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d", nTexMemUsage / 1024); // in KByte - } - } - break; - - case 5: - { - ////////////////////////////////////////////////////////////////////////// - // Show Num Render materials. - ////////////////////////////////////////////////////////////////////////// - ColorB clr(0, 0, 0, 0); - if (nRenderMats == 1) - { - clr = ColorB(0, 0, 255, 255); - } - else if (nRenderMats == 2) - { - clr = ColorB(0, 255, 255, 255); - } - else if (nRenderMats == 3) - { - clr = ColorB(0, 255, 0, 255); - } - else if (nRenderMats == 4) - { - clr = ColorB(255, 0, 255, 255); - } - else if (nRenderMats == 5) - { - clr = ColorB(255, 255, 0, 255); - } - else if (nRenderMats >= 6) - { - clr = ColorB(255, 0, 0, 255); - } - else if (nRenderMats >= 11) - { - clr = ColorB(255, 255, 255, 255); - } - - if (pMaterial) - { - pMaterial = GetMatMan()->GetDefaultHelperMaterial(); - } - if (pObj) - { - pObj->m_II.m_AmbColor = ColorF(clr.r / 155.0f, clr.g / 155.0f, clr.b / 155.0f, 1); - pObj->m_nMaterialLayers = 0; - pObj->m_ObjFlags |= FOB_SELECTED; - } - - if (!bNoText) - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d", nRenderMats); - } - } - break; - - case 6: - { - if (pMaterial) - { - pMaterial = GetMatMan()->GetDefaultHelperMaterial(); - } - - ColorF col(1, 1, 1, 1); - if (pObj) - { - pObj->m_nMaterialLayers = 0; - col = pObj->m_II.m_AmbColor; - } - - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d,%d,%d,%d", (int)(col.r * 255.0f), (int)(col.g * 255.0f), (int)(col.b * 255.0f), (int)(col.a * 255.0f)); - } - break; - - case 7: - if (m_pRenderMesh) - { - int nTexMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial); - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d,%d,%d", m_nRenderTrisCount, nRenderMats, nTexMemUsage / 1024); - } - break; - case 13: - { -#ifdef SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS - float fOcclusion = GetOcclusionAmount(); - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%.2f", fOcclusion); -#endif - } - break; - - case 16: - { - // Draw stats for object selected by debug gun - if (GetRenderer()->IsDebugRenderNode((IRenderNode*)pObj->m_pRenderNode)) - { - const char* shortName = PathUtil::GetFile(m_szFileName.c_str()); - - int texMemUsage = 0; - - if (m_pRenderMesh) - { - texMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial); - } - - pAuxGeom->DrawAABB(bbox, tm, false, ColorB(0, 255, 255, 128), eBBD_Faceted); - - float yellow[4] = {1.f, 1.f, 0.f, 1.f}; - - const float yOffset = 165.f; - const float xOffset = 970.f; - - if (m_pParentObject == NULL) - { - pRend->Draw2dLabel(xOffset, 40.f, 1.5f, yellow, false, "%s", shortName); - - pRend->Draw2dLabel(xOffset, yOffset, 1.5f, color, false, - //"Mesh: %s\n" - "LOD: %d/%d\n" - "Num Instances: %d\n" - "Num Tris: %d\n" - "Tex Mem usage: %.2f kb\n" - "Mesh Mem usage: %.2f kb\n" - "Num Materials: %d\n" - "Mesh Type: %s\n", - //shortName, - nLod, nNumLods, - m_nUsers, - m_nRenderTrisCount, - texMemUsage / 1024.f, - m_nRenderMeshMemoryUsage / 1024.f, - nRenderMats, - m_pRenderMesh->GetTypeName()); - } - else - { - for (int i = 0; i < m_pParentObject->SubObjectCount(); i++) - { - //find subobject position - if (m_pParentObject->SubObject(i).pStatObj == this) - { - //only render the header once - if (i == 0) - { - pRend->Draw2dLabel(600.f, 40.f, 2.f, yellow, false, "Debug Gun: %s", shortName); - } - float y = yOffset + ((i % 4) * 150.f); - float x = xOffset - (floor(i / 4.f) * 200.f); - - pRend->Draw2dLabel(x, y, 1.5f, color, false, - "Sub Mesh: %s\n" - "LOD: %d/%d\n" - "Num Instances: %d\n" - "Num Tris: %d\n" - "Tex Mem usage: %.2f kb\n" - "Mesh Mem usage: %.2f kb\n" - "Num Materials: %d\n" - "Mesh Type: %s\n", - m_szGeomName.c_str() ? m_szGeomName.c_str() : "UNKNOWN", - nLod, nNumLods, - m_nUsers, - m_nRenderTrisCount, - texMemUsage / 1024.f, - m_nRenderMeshMemoryUsage / 1024.f, - nRenderMats, - m_pRenderMesh->GetTypeName()); - - break; - } - } - } - } - } - break; - - case 19: // Displays the triangle count of physic proxies. - if (!bNoText) - { - int nPhysTrisCount = 0; - for (int j = 0; j < MAX_PHYS_GEOMS_TYPES; ++j) - { - if (GetPhysGeom(j)) - { - nPhysTrisCount += GetPhysGeom(j)->pGeom->GetPrimitiveCount(); - } - } - - if (nPhysTrisCount == 0) - { - color[3] = 0.1f; - } - - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%d", nPhysTrisCount); - } - return false; - - case 22: - { - // Show texture usage. - if (m_pRenderMesh) - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "[LOD %d: %d]", nLod, m_pRenderMesh->GetVerticesCount()); - } - } - break; - case 23: - { - if (pObj && pObj->m_pRenderNode) - { - IRenderNode* pRenderNode = (IRenderNode*)pObj->m_pRenderNode; - const bool bCastsShadow = (pRenderNode->GetRndFlags() & ERF_CASTSHADOWMAPS) != 0; - ColorF clr = bCastsShadow ? ColorF(1.f, 0.f, 0.f, 1.0f) : ColorF(0.f, 1.f, 0.f, 1.f); - - int nIndices = 0; - int nIndicesNoShadow = 0; - - // figure out how many primitives actually cast shadows - if (pMaterial && bCastsShadow) - { - for (int i = 0; i < nMats; ++i) - { - CRenderChunk& rc = m_pRenderMesh->GetChunks()[i]; - if (rc.pRE && rc.nNumIndices && rc.nNumVerts && ((rc.m_nMatFlags & MTL_FLAG_NODRAW) == 0)) - { - SShaderItem& ShaderItem = pMaterial->GetShaderItem(rc.m_nMatID); - IRenderShaderResources* pR = ShaderItem.m_pShaderResources; - - if (pR && (pR->GetResFlags() & MTL_FLAG_NOSHADOW)) - { - nIndicesNoShadow += rc.nNumIndices; - } - - nIndices += rc.nNumIndices; - } - } - - Vec3 red, green; - ColorF(1.f, 0.f, 0.f, 1.0f).toHSV(red.x, red.y, red.z); - ColorF(0.f, 1.f, 0.f, 1.0f).toHSV(green.x, green.y, green.z); - - Vec3 c = Vec3::CreateLerp(red, green, (float)nIndicesNoShadow / max(nIndices, 1)); - clr.fromHSV(c.x, c.y, c.z); - - pMaterial = GetMatMan()->GetDefaultHelperMaterial(); - } - - pObj->m_II.m_AmbColor = clr; - pObj->m_nMaterialLayers = 0; - pObj->m_ObjFlags |= FOB_SELECTED; - } - return false; - } - case 24: - case 25: - { - // display a label for this render node if the triangle count equals or exceeds - // e_DebugDrawLodMinTriangles and the object has no lods, or has too few lods - int minTriangleCount = GetCVars()->e_DebugDrawLodMinTriangles; - if (m_nLoadedTrisCount >= minTriangleCount) - { - IRenderNode* pRN = (IRenderNode*)pObj->m_pRenderNode; - const char* shortName = ""; - - if (!m_szGeomName.empty()) - { - shortName = m_szGeomName.c_str(); - } - else - { - shortName = PathUtil::GetFile(m_szFileName.c_str()); - } - - if (nNumLods == 1) - { - color[1] = color[2] = 0.0f; - - IRenderer::RNDrawcallsMapNode& drawCallsPerNode = pRend->GetDrawCallsInfoPerNodePreviousFrame(); - auto iter = drawCallsPerNode.find(pRN); - if (iter != drawCallsPerNode.end()) - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s (%d)\n%d/%d/%d/%d/%d", shortName, m_nLoadedTrisCount, iter->second.nZpass, iter->second.nGeneral, iter->second.nTransparent, iter->second.nShadows, iter->second.nMisc); - } - else - { - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s (%d)", shortName, m_nLoadedTrisCount); - } - } - else if (e_DebugDraw == 25 && nNumLods < MAX_STATOBJ_LODS_NUM) // 25 adds in drawing of objects that should be at a lower lod than exists - { - float lodDistance = sqrt(m_fGeometricMeanFaceArea); - float nextLodDistance = lodDistance * (nNumLods) / (pRN->GetLodRatioNormalized() * gEnv->p3DEngine->GetFrameLodInfo().fTargetSize); - if (pObj->m_fDistance > nextLodDistance) - { - color[0] = color[1] = 0.0f; - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s (%d)", shortName, m_nLoadedTrisCount); - } - } - } - } - break; - } - } - - if (GetCVars()->e_DebugDraw == 15 && !bOnlyBoxes) - { - // helpers - for (int i = 0; i < (int)m_subObjects.size(); i++) - { - SSubObject* pSubObject = &(m_subObjects[i]); - if (pSubObject->nType == STATIC_SUB_OBJECT_MESH && pSubObject->pStatObj) - { - continue; - } - - if (bHasHelperFilter) - { - if (pSubObject->name.find(e_DebugDrawFilter) == string::npos) - { - continue; - } - } - - // make object matrix - Matrix34 tMat = tm * pSubObject->tm; - Vec3 pos = tMat.GetTranslation(); - - // draw axes - float s = 0.02f; - ColorB col(0, 255, 255, 255); - pAuxGeom->DrawAABB(AABB(Vec3(-s, -s, -s), Vec3(s, s, s)), tMat, false, col, eBBD_Faceted); - pAuxGeom->DrawLine(pos + s * tMat.GetColumn1(), col, pos + 3.f * s * tMat.GetColumn1(), col); - - // text - float color[4] = {0, 1, 1, 1}; - pRend->DrawLabelEx(pos, 1.3f, color, true, true, "%s", pSubObject->name.c_str()); - } - } - - - if (Get3DEngine()->IsDebugDrawListEnabled()) - { - I3DEngine::SObjectInfoToAddToDebugDrawList objectInfo; - if (pObj->m_pRenderNode) - { - objectInfo.pName = ((IRenderNode*)pObj->m_pRenderNode)->GetName(); - objectInfo.pClassName = ((IRenderNode*)pObj->m_pRenderNode)->GetEntityClassName(); - } - else - { - objectInfo.pName = ""; - objectInfo.pClassName = ""; - } - objectInfo.pFileName = m_szFileName.c_str(); - if (m_pRenderMesh && pObj->m_pCurrMaterial) - { - objectInfo.texMemory = m_pRenderMesh->GetTextureMemoryUsage(pObj->m_pCurrMaterial); - } - else - { - objectInfo.texMemory = 0; - } - objectInfo.numTris = m_nRenderTrisCount; - objectInfo.numVerts = m_nLoadedVertexCount; - objectInfo.meshMemory = m_nRenderMeshMemoryUsage; - objectInfo.pMat = &tm; - objectInfo.pBox = &bbox; - objectInfo.type = I3DEngine::DLOT_STATOBJ; - objectInfo.pRenderNode = (IRenderNode*)(pObj->m_pRenderNode); - Get3DEngine()->AddObjToDebugDrawList(objectInfo); - } - - - -#endif //_RELEASE - return false; -} - -// -// StatObj functions. -// - -float CStatObj::GetExtent(EGeomForm eForm) -{ - int nSubCount = m_subObjects.size(); - if (!nSubCount) - { - return m_pRenderMesh ? m_pRenderMesh->GetExtent(eForm) : 0.f; - } - - CGeomExtent& ext = m_Extents.Make(eForm); - if (!ext) - { - // Create parts for main and sub-objects. - ext.ReserveParts(1 + nSubCount); - - ext.AddPart(m_pRenderMesh ? m_pRenderMesh->GetExtent(eForm) : 0.f); - - // Evaluate sub-objects. - for (int i = 0; i < nSubCount; i++) - { - IStatObj::SSubObject* pSub = &m_subObjects[i]; - if (pSub->nType == STATIC_SUB_OBJECT_MESH && pSub->pStatObj) - { - float fExt = pSub->pStatObj->GetExtent(eForm); - - if (eForm == GeomForm_Edges) - { - fExt *= powf(pSub->tm.Determinant(), 0.333f); - } - else if (eForm == GeomForm_Surface) - { - fExt *= powf(pSub->tm.Determinant(), 0.667f); - } - else if (eForm == GeomForm_Volume) - { - fExt *= pSub->tm.Determinant(); - } - - ext.AddPart(fExt); - } - else - { - ext.AddPart(0.f); - } - } - } - return ext.TotalExtent(); -} - -void CStatObj::GetRandomPos(PosNorm& ran, EGeomForm eForm) const -{ - if (!m_subObjects.empty()) - { - CGeomExtent const& ext = m_Extents[eForm]; - int iSubObj = ext.RandomPart(); - if (iSubObj-- > 0) - { - IStatObj::SSubObject const* pSub = &m_subObjects[iSubObj]; - assert(pSub && pSub->pStatObj); - pSub->pStatObj->GetRandomPos(ran, eForm); - ran <<= pSub->tm; - return; - } - } - if (m_pRenderMesh) - { - m_pRenderMesh->GetRandomPos(ran, eForm); - } - else - { - ran.zero(); - } -} - -void CStatObj::ComputeGeometricMean(SMeshLodInfo& lodInfo) -{ - lodInfo.Clear(); - - lodInfo.fGeometricMean = m_fGeometricMeanFaceArea; - lodInfo.nFaceCount = m_nRenderTrisCount; - - if (GetFlags() & STATIC_OBJECT_COMPOUND) - { - for (uint i = 0; i < m_subObjects.size(); ++i) - { - if (m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH && m_subObjects[i].bShadowProxy == false && m_subObjects[i].pStatObj != NULL) - { - SMeshLodInfo subLodInfo; - static_cast(m_subObjects[i].pStatObj)->ComputeGeometricMean(subLodInfo); - - lodInfo.Merge(subLodInfo); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::DebugDraw(const SGeometryDebugDrawInfo& info, float fExtrdueScale) -{ - if (m_nFlags & STATIC_OBJECT_COMPOUND && !m_bMerged) - { - // Draw sub objects. - for (int i = 0; i < (int)m_subObjects.size(); i++) - { - if (!m_subObjects[i].pStatObj || m_subObjects[i].bHidden || m_subObjects[i].nType != STATIC_SUB_OBJECT_MESH) - { - continue; - } - - SGeometryDebugDrawInfo subInfo = info; - subInfo.tm = info.tm * m_subObjects[i].localTM; - m_subObjects[i].pStatObj->DebugDraw(subInfo, fExtrdueScale); - } - } - else if (m_pRenderMesh) - { - m_pRenderMesh->DebugDraw(info, ~0, fExtrdueScale); - } - else - { - // No RenderMesh in here, so probably no geometry in highest LOD, find it in lower LODs - if (m_pLODs) - { - assert(m_nMaxUsableLod < MAX_STATOBJ_LODS_NUM); - for (int nLod = 0; nLod <= (int)m_nMaxUsableLod; nLod++) - { - if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh) - { - m_pLODs[nLod]->m_pRenderMesh->DebugDraw(info, ~0, fExtrdueScale); - break; - } - } - } - } -} - diff --git a/Code/CryEngine/Cry3DEngine/StatObjStream.cpp b/Code/CryEngine/Cry3DEngine/StatObjStream.cpp deleted file mode 100644 index 6d9b1f98b1..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObjStream.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : loading - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "IndexedMesh.h" -#include "../RenderDll/Common/Shadow_Renderer.h" -#include -#include - -#include "CGF/CGFLoader.h" -#include "CGF/CGFSaver.h" -#include "CGF/ReadOnlyChunkFile.h" - -#define GEOM_INFO_FILE_EXT "ginfo" -#define MESH_NAME_FOR_MAIN "main" - -extern const char* stristr(const char* szString, const char* szSubstring); - -extern void TransformMesh(CMesh& mesh, Matrix34 tm); - -#if !defined (_RELEASE) -float CStatObj::s_fStreamingTime = 0.0f; -int CStatObj::s_nBandwidth = 0; -#endif - -void CStatObj::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) -{ - FUNCTION_PROFILER_3DENGINE; - - if (nError == ERROR_CANT_OPEN_FILE && m_bHasStreamOnlyCGF) - { - // Deliberately ignore - } - else if (pStream->IsError()) - { // file was not loaded successfully - m_eStreamingStatus = ecss_Ready; - if (pStream->GetError() != ERROR_USER_ABORT && pStream->GetError() != ERROR_ABORTED_ON_SHUTDOWN) - { - Error("CStatObj::StreamAsyncOnComplete: Error loading CGF: %s Error: %s", m_szFileName.c_str(), pStream->GetErrorName()); - } - } - else - { -#if !defined (_RELEASE) - float timeinseconds = (gEnv->pTimer->GetCurrTime() - m_fStreamingStart); - s_nBandwidth += pStream->GetBytesRead(); - s_fStreamingTime += timeinseconds; - m_fStreamingStart = 0.0f; -#endif - - if (!LoadStreamRenderMeshes(0, pStream->GetBuffer(), pStream->GetBytesRead(), strstr(m_szFileName.c_str(), "_lod") != NULL)) - { - Error("CStatObj::StreamOnComplete_LoadCGF_FromMemBlock, filename=%s", m_szFileName.c_str()); - } - } - - pStream->FreeTemporaryMemory(); // We dont need internal stream loaded buffer anymore. -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::StreamOnComplete(IReadStream* pStream, unsigned nError) -{ - FUNCTION_PROFILER_3DENGINE; - - // Synchronous callback. - - if (nError == ERROR_CANT_OPEN_FILE && m_bHasStreamOnlyCGF) - { - m_bHasStreamOnlyCGF = 0; - m_eStreamingStatus = ecss_NotLoaded; - } - else if (pStream->IsError()) - { - // file was not loaded successfully - if (pStream->GetError() != ERROR_USER_ABORT && pStream->GetError() != ERROR_ABORTED_ON_SHUTDOWN) - { - Error("CStatObj::StreamOnComplete: Error loading CGF: %s Error: %s", m_szFileName.c_str(), pStream->GetErrorName()); - } - - m_eStreamingStatus = ecss_Ready; - } - else - { - CommitStreamRenderMeshes(); - - ////////////////////////////////////////////////////////////////////////// - // Forces vegetation sprites to be marked for regeneration from new mesh. - ////////////////////////////////////////////////////////////////////////// - for (int nSID = 0; nSID < m_pObjManager->GetListStaticTypes().Count(); nSID++) - { - PodArray& rGroupTable = m_pObjManager->GetListStaticTypes()[nSID]; - for (int nGroupId = 0, nGroups = rGroupTable.Count(); nGroupId < nGroups; nGroupId++) - { - StatInstGroup& rGroup = rGroupTable[nGroupId]; - if (rGroup.pStatObj == this) - { - rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes()); - } - } - } - ////////////////////////////////////////////////////////////////////////// - -#ifdef OBJMAN_STREAM_STATS - if (m_pStreamListener) - { - m_pStreamListener->OnReceivedStreamedObject(static_cast(this)); - } -#endif - - m_eStreamingStatus = ecss_Ready; - } - - m_pReadStream = 0; -} - -void CStatObj::GetStreamFilePath(stack_string& strOut) -{ - strOut = m_szFileName.c_str(); - strOut.append("m"); -} - -////////////////////////////////////////////////////////////////////////// -void CStatObj::StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream) -{ - assert(!m_pParentObject); - - assert(m_eStreamingStatus == ecss_NotLoaded); - - if (m_eStreamingStatus != ecss_NotLoaded) - { - return; - } - - // start streaming - StreamReadParams params; - params.dwUserData = 0; - params.nSize = 0; - params.pBuffer = NULL; - params.nLoadTime = 10000; - params.nMaxLoadTime = 10000; - if (bFinishNow) - { - params.ePriority = estpUrgent; - } - - if (m_szFileName.empty()) - { - assert(!"CStatObj::StartStreaming: CGF name is empty"); - m_eStreamingStatus = ecss_Ready; - if (ppStream) - { - *ppStream = NULL; - } - return; - } - -#if !defined (_RELEASE) - m_fStreamingStart = gEnv->pTimer->GetCurrTime(); -#endif //!defined (_RELEASE) - const char* path = m_szFileName.c_str(); - - stack_string streamPath; - if (m_bHasStreamOnlyCGF) - { - GetStreamFilePath(streamPath); - path = streamPath.c_str(); - } - - m_pReadStream = GetSystem()->GetStreamEngine()->StartRead(eStreamTaskTypeGeometry, path, this, ¶ms); - - if (ppStream) - { - (*ppStream) = m_pReadStream; - } - if (!bFinishNow) - { - m_eStreamingStatus = ecss_InProgress; - } - else if (!ppStream) - { - m_pReadStream->Wait(); - } -} - -void CStatObj::ReleaseStreamableContent() -{ - assert(!m_pParentObject); - assert(!m_pClonedSourceObject); - assert(!m_bSharesChildren); - - bool bLodsAreLoadedFromSeparateFile = m_pLod0 ? m_pLod0->IsLodsAreLoadedFromSeparateFile() : m_bLodsAreLoadedFromSeparateFile; - - if (!bLodsAreLoadedFromSeparateFile) - { - for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pLod = (CStatObj*)GetLodObject(nLod); - - if (!pLod) - { - continue; - } - - pLod->SetRenderMesh(0); - pLod->m_eStreamingStatus = ecss_NotLoaded; - - if (pLod->m_pParentObject) - { - pLod->m_pParentObject->SetRenderMesh(0); - pLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded; - } - } - } - - for (int s = 0; s < GetSubObjectCount(); s++) - { - SSubObject& sub = *GetSubObject(s); - if (!sub.pStatObj) - { - continue; - } - - if (bLodsAreLoadedFromSeparateFile) - { - CStatObj* pSubLod = (CStatObj*)sub.pStatObj; - - if (!pSubLod) - { - continue; - } - - pSubLod->SetRenderMesh(0); - pSubLod->m_eStreamingStatus = ecss_NotLoaded; - - if (pSubLod->m_pParentObject) - { - pSubLod->m_pParentObject->SetRenderMesh(0); - pSubLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded; - } - } - else - { - for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pSubLod = (CStatObj*)sub.pStatObj->GetLodObject(nLod); - - if (!pSubLod) - { - continue; - } - - pSubLod->SetRenderMesh(0); - pSubLod->m_eStreamingStatus = ecss_NotLoaded; - - if (pSubLod->m_pParentObject) - { - pSubLod->m_pParentObject->SetRenderMesh(0); - pSubLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded; - } - } - } - } - - SetRenderMesh(0); - - m_pMergedRenderMesh = 0; - - m_eStreamingStatus = ecss_NotLoaded; -} - -int CStatObj::GetStreamableContentMemoryUsage([[maybe_unused]] bool bJustForDebug) -{ - assert(!m_pParentObject || bJustForDebug); // only parents allowed to be registered for streaming - - bool bLodsAreLoadedFromSeparateFile = m_pLod0 ? m_pLod0->IsLodsAreLoadedFromSeparateFile() : m_bLodsAreLoadedFromSeparateFile; - bool bCountLods = !bLodsAreLoadedFromSeparateFile; - - if (m_arrRenderMeshesPotentialMemoryUsage[bCountLods] < 0) - { - int nCount = 0; - - if (bCountLods) - { - if (m_pLODs) - { - for (int nLod = 1; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pLod = (CStatObj*)m_pLODs[nLod]; - - if (!pLod) - { - continue; - } - - nCount += pLod->m_nRenderMeshMemoryUsage; - } - } - } - - nCount += m_nRenderMeshMemoryUsage; - - for (int s = 0; s < GetSubObjectCount(); s++) - { - SSubObject& sub = *GetSubObject(s); - - if (!sub.pStatObj) - { - continue; - } - - if (bCountLods) - { - CStatObj* pSubStatObj = (CStatObj*)sub.pStatObj; - if (pSubStatObj->m_pLODs) - { - for (int nLod = 1; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - CStatObj* pSubLod = pSubStatObj->m_pLODs[nLod]; - - if (!pSubLod) - { - continue; - } - - nCount += pSubLod->m_nRenderMeshMemoryUsage; - } - } - } - - nCount += ((CStatObj*)sub.pStatObj)->m_nRenderMeshMemoryUsage; - } - - m_arrRenderMeshesPotentialMemoryUsage[bCountLods] = nCount; - } - - if (m_pMergedRenderMesh) - { - //TODO: Need to have a function to calculate memory usage. - //m_nMergedMemoryUsage = m_pMergedRenderMesh->GetAllocatedBytes(true); - m_nMergedMemoryUsage = m_pMergedRenderMesh->GetVerticesCount() * (sizeof(SPipTangents) + sizeof(SVF_P3S_C4B_T2S)) + m_pMergedRenderMesh->GetIndicesCount() * sizeof(uint16); - } - else - if (!GetCVars()->e_StatObjMerge) - { - m_nMergedMemoryUsage = 0; - } - - return m_nMergedMemoryUsage + m_arrRenderMeshesPotentialMemoryUsage[bCountLods]; -} - -void CStatObj::UpdateStreamingPrioriryInternal(const Matrix34A& objMatrix, float fImportance, bool bFullUpdate) -{ - int nRoundId = GetObjManager()->GetUpdateStreamingPrioriryRoundId(); - - if (m_pParentObject && m_bSubObject) - { // stream parent for sub-objects - m_pParentObject->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate); - } - else if (!m_bSubObject) - { // stream object itself - if (m_bCanUnload) - { - if (UpdateStreamingPrioriryLowLevel(fImportance, nRoundId, bFullUpdate)) - { - GetObjManager()->RegisterForStreaming(this); - } - } - } - else if (m_pLod0) - { // sub-object lod without parent - m_pLod0->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate); - assert(!m_pLod0->IsLodsAreLoadedFromSeparateFile()); - } - else if (m_bCanUnload) - { - assert(!"Invalid CGF hierarchy"); - } -} - -bool CStatObj::UpdateStreamableComponents(float fImportance, const Matrix34A& objMatrix, bool bFullUpdate, int nNewLod) -{ - if (m_pLod0) // redirect to lod0, otherwise we fail to pre-cache neighbor LODs - { - return m_pLod0->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod); - } - -#ifndef _RELEASE - if (GetCVars()->e_StreamCgfDebug && strlen(GetCVars()->e_StreamCgfDebugFilter->GetString()) && strstr(m_szFileName, GetCVars()->e_StreamCgfDebugFilter->GetString())) - { - PrintMessage(__FUNCTION__); - } -#endif - - // FUNCTION_PROFILER_3DENGINE; - - if (m_nFlags & STATIC_OBJECT_HIDDEN) - { - return false; - } - - nNewLod = min(nNewLod, MAX_STATOBJ_LODS_NUM - 1); - - if ((m_nFlags & STATIC_OBJECT_COMPOUND) && SubObjectCount()) - { - for (int s = 0, num = SubObjectCount(); s < num; s++) - { - IStatObj::SSubObject& subObj = SubObject(s); - - if (subObj.pStatObj && subObj.nType == STATIC_SUB_OBJECT_MESH && !subObj.bShadowProxy) - { - Matrix34 subObjMatrix = objMatrix * subObj.tm; - - CStatObj* pSubStatObj = ((CStatObj*)subObj.pStatObj); - - if (pSubStatObj->m_nLoadedTrisCount < 1) - { - continue; - } - - for (int l = nNewLod; l <= (nNewLod + 1) && l < MAX_STATOBJ_LODS_NUM; l++) - { - if (CStatObj* pLod = (CStatObj*)pSubStatObj->GetLodObject(l, true)) - { - pLod->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate); - - if (!(CStatObj*)pSubStatObj->m_pLODs) - { - break; - } - } - } - } - } - } - else if (m_nLoadedTrisCount >= 1) - { - for (int l = nNewLod; l <= (nNewLod + 1) && l < MAX_STATOBJ_LODS_NUM; l++) - { - if (CStatObj* pLod = (CStatObj*)GetLodObject(l, true)) - { - pLod->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate); - - if (!m_pLODs) - { - break; - } - } - } - } - - // update also next state CGF - if (!m_szStreamingDependencyFilePath.empty()) - { - if (CStatObj* pNextState = (CStatObj*)GetObjManager()->FindStaticObjectByFilename(m_szStreamingDependencyFilePath)) - { - pNextState->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod); - } - } - - if (m_pParentObject && !m_pParentObject->m_szStreamingDependencyFilePath.empty()) - { - if (CStatObj* pNextState = (CStatObj*)GetObjManager()->FindStaticObjectByFilename(m_pParentObject->m_szStreamingDependencyFilePath)) - { - pNextState->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod); - } - } - - return true; -} - -void CStatObj::DisableStreaming() -{ - for (int nLodLevel = 0; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++) - { - if (CStatObj* pLodObj = (CStatObj*)GetLodObject(nLodLevel)) - { - pLodObj->m_nLastDrawMainFrameId = GetRenderer()->GetFrameID(false) + 1000; - pLodObj->UpdateStreamingPrioriryLowLevel(1.f, GetObjManager()->GetUpdateStreamingPrioriryRoundId(), true); - pLodObj->m_bCanUnload = false; - - // only register the parent object for streaming, it will stream in all subobject + lods - if (pLodObj->m_pParentObject) - { - GetObjManager()->RegisterForStreaming(pLodObj->m_pParentObject); - } - else - { - GetObjManager()->RegisterForStreaming(pLodObj); - } - } - } -} - - -bool CStatObj::CheckForStreamingDependencyLoop(const char* szFilenameDependancy) const -{ - IObjManager* pObjManager = GetObjManager(); - while (szFilenameDependancy) - { - const CStatObj* pStatObjDependency = static_cast(pObjManager->FindStaticObjectByFilename(szFilenameDependancy)); - if (!pStatObjDependency) - { - return false; - } - - if (this == pStatObjDependency) - { - return true; - } - - szFilenameDependancy = pStatObjDependency->m_szStreamingDependencyFilePath.c_str(); - } - - return false; -} diff --git a/Code/CryEngine/Cry3DEngine/StatObj_Jobs.cpp b/Code/CryEngine/Cry3DEngine/StatObj_Jobs.cpp deleted file mode 100644 index cfb8528dae..0000000000 --- a/Code/CryEngine/Cry3DEngine/StatObj_Jobs.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : prepare and add render element into renderer - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "../RenderDll/Common/Shadow_Renderer.h" - -#include "IndexedMesh.h" -#include "VisAreas.h" -#include "GeomQuery.h" - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CStatObj::RenderInternal(CRenderObject* pRenderObject, uint64 nSubObjectHideMask, const CLodValue& lodValue, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw) -{ - FUNCTION_PROFILER_3DENGINE; - - if (m_nFlags & STATIC_OBJECT_HIDDEN) - { - return; - } - - m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pParentObject) - { - m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - - if (m_nInitialSubObjHideMask != 0 && nSubObjectHideMask == 0) - { - nSubObjectHideMask = m_nInitialSubObjHideMask; - if ((m_pMergedRenderMesh != NULL) && !(pRenderObject->m_ObjFlags & FOB_MESH_SUBSET_INDICES)) // If not already set by per-instance hide mask. - { - SRenderObjData* pOD = GetRenderer()->EF_GetObjData(pRenderObject, true, passInfo.ThreadID()); - - // Only pass SubObject hide mask for merged objects, because they have a correct correlation between Hide Mask and Render Chunks. - pOD->m_nSubObjHideMask = m_nInitialSubObjHideMask; - pRenderObject->m_ObjFlags |= FOB_MESH_SUBSET_INDICES; - } - } - - if (pRenderObject->m_pRenderNode) - { - IRenderNode* pRN = (IRenderNode*)pRenderObject->m_pRenderNode; - if (m_bEditor) - { - if (pRN->m_dwRndFlags & ERF_SELECTED) - { - m_nSelectedFrameId = passInfo.GetMainFrameID(); - if (m_pParentObject) - { - m_pParentObject->m_nSelectedFrameId = passInfo.GetMainFrameID(); - } - pRenderObject->m_ObjFlags |= FOB_SELECTED; - } - else - { - pRenderObject->m_ObjFlags &= ~FOB_SELECTED; - } - - if (!gEnv->IsEditing() && pRN->m_dwRndFlags & ERF_RAYCAST_PROXY) - { - return; - } - } - else - { - if (pRN->m_dwRndFlags & ERF_RAYCAST_PROXY) - { - return; - } - } - } - - if ((m_nFlags & STATIC_OBJECT_COMPOUND) && !m_bMerged) - { - ////////////////////////////////////////////////////////////////////////// - // Render SubMeshes if present. - ////////////////////////////////////////////////////////////////////////// - if (m_nSubObjectMeshCount > 0) - { - CRenderObject* pRenderObjectB = NULL; - - if (lodValue.DissolveRefB() != 255) - { - pRenderObject->m_DissolveRef = lodValue.DissolveRefA(); - - if (pRenderObject->m_DissolveRef) - { - if (!(pRenderObject->m_ObjFlags & FOB_DISSOLVE)) - { - pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK; - } - pRenderObject->m_ObjFlags |= FOB_DISSOLVE; - - pRenderObject->m_ObjFlags |= FOB_DISSOLVE_OUT; - } - else - { - if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE)) - { - pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK; - } - pRenderObject->m_ObjFlags &= ~FOB_DISSOLVE; - } - - if (lodValue.LodB() != -1) - { - pRenderObjectB = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo); - pRenderObjectB->m_ObjFlags &= ~FOB_DISSOLVE_OUT; - } - } - else - { - pRenderObject->m_DissolveRef = 0; - if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE)) - { - pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK; - } - pRenderObject->m_ObjFlags &= ~(FOB_DISSOLVE | FOB_DISSOLVE_OUT); - } - - uint64 nBitIndex = 1; - Matrix34A renderTM = pRenderObject->m_II.m_Matrix; - for (int32 i = 0, subObjectsSize = m_subObjects.size(); i < subObjectsSize; ++i, nBitIndex <<= 1) - { - const SSubObject& subObj = m_subObjects[i]; - if (subObj.nType == STATIC_SUB_OBJECT_MESH) // all the meshes are at the beginning of the array. - { - CStatObj* const __restrict pStatObj = (CStatObj*)subObj.pStatObj; - - if (pStatObj && - (pStatObj->m_nRenderTrisCount >= 2) && - !(pStatObj->m_nFlags & STATIC_OBJECT_HIDDEN) && - (nBitIndex & nSubObjectHideMask) == 0 - ) - { - PrefetchLine(pRenderObject, 0); - RenderSubObject(pRenderObject, lodValue.LodA(), i, renderTM, passInfo, rendItemSorter, forceStaticDraw); - if (pRenderObjectB) - { - PrefetchLine(pRenderObjectB, 0); - RenderSubObject(pRenderObjectB, lodValue.LodB(), i, renderTM, passInfo, rendItemSorter, forceStaticDraw); - } - } - } - else - { - break; - } - } - - if (GetCVars()->e_DebugDraw) - { - RenderDebugInfo(pRenderObject, passInfo); - } - } - - ////////////////////////////////////////////////////////////////////////// - } - else - { // draw mesh, don't even try to render childs - RenderObjectInternal(pRenderObject, lodValue.LodA(), lodValue.DissolveRefA(), true, passInfo, rendItemSorter, forceStaticDraw); - if (lodValue.DissolveRefB() != 255) // check here since we're passing in A's ref. - { - RenderObjectInternal(pRenderObject, lodValue.LodB(), lodValue.DissolveRefA(), false, passInfo, rendItemSorter, forceStaticDraw); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CStatObj::RenderSubObject(CRenderObject* pRenderObject, int nLod, - int nSubObjId, const Matrix34A& renderTM, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, bool forceStaticDraw) -{ - const SSubObject& subObj = m_subObjects[nSubObjId]; - - CStatObj* const __restrict pStatObj = (CStatObj*)subObj.pStatObj; - - if (pStatObj == NULL) - { - return; - } - - if (subObj.bIdentityMatrix) - { - pStatObj->RenderSubObjectInternal(pRenderObject, nLod, passInfo, rendItemSorter, forceStaticDraw); - } - else - { - pRenderObject = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo); - pRenderObject->m_II.m_Matrix = renderTM * subObj.tm; - SRenderObjData* pRenderObjectData = pRenderObject->GetObjData(); - pRenderObjectData->m_uniqueObjectId = pRenderObjectData->m_uniqueObjectId + nSubObjId; - - pStatObj->RenderSubObjectInternal(pRenderObject, nLod, passInfo, rendItemSorter, forceStaticDraw); - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CStatObj::RenderSubObjectInternal(CRenderObject* pRenderObject, int nLod, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, [[maybe_unused]] bool forceStaticDraw) -{ - assert(!(m_nFlags & STATIC_OBJECT_HIDDEN)); - assert(m_nRenderTrisCount); - - m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pParentObject && (m_nFlags & STATIC_OBJECT_MULTIPLE_PARENTS)) - { - m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - - assert(!m_pParentObject || m_pParentObject->m_nLastDrawMainFrameId == passInfo.GetMainFrameID()); - - assert(!(m_nFlags & STATIC_OBJECT_COMPOUND)); - nLod = CLAMP(nLod, GetMinUsableLod(), (int)m_nMaxUsableLod); - assert(nLod < MAX_STATOBJ_LODS_NUM); - - // try next lod's if selected one is not ready - if ((!nLod && m_pRenderMesh && m_pRenderMesh->CanRender()) || !GetCVars()->e_Lods) - { - PrefetchLine(pRenderObject, 0); - RenderRenderMesh(pRenderObject, NULL, passInfo, rendItemSorter); - } - else - { - if (m_pLODs && m_pLODs[nLod]) - { - m_pLODs[nLod]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pLODs[nLod]->m_pParentObject) - { - m_pLODs[nLod]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - - if ((nLod + 1) < MAX_STATOBJ_LODS_NUM && m_pLODs[nLod + 1]) - { - m_pLODs[nLod + 1]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pLODs[nLod + 1]->m_pParentObject) - { - m_pLODs[nLod + 1]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - } - } - - if (m_pLODs) - { - for (; nLod <= (int)m_nMaxUsableLod; nLod++) - { - if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh && m_pLODs[nLod]->m_pRenderMesh->CanRender()) - { - PrefetchLine(pRenderObject, 0); - m_pLODs[nLod]->RenderRenderMesh(pRenderObject, NULL, passInfo, rendItemSorter); - break; - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CStatObj::RenderObjectInternal(CRenderObject* pRenderObject, int nTargetLod, uint8 uLodDissolveRef, bool dissolveOut, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter, [[maybe_unused]] bool forceStaticDraw) -{ - if (nTargetLod == -1 || uLodDissolveRef == 255) - { - return; - } - - int nLod = CLAMP(nTargetLod, GetMinUsableLod(), (int)m_nMaxUsableLod); - assert(nLod < MAX_STATOBJ_LODS_NUM); - - pRenderObject = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo); - - if (passInfo.IsShadowPass() && passInfo.GetShadowMapType() == SRenderingPassInfo::SHADOW_MAP_CACHED && pRenderObject->m_pRenderNode) - { - IShadowCaster* pCaster = static_cast(pRenderObject->m_pRenderNode); - pCaster->m_cStaticShadowLod = nLod; - } - - pRenderObject->m_DissolveRef = uLodDissolveRef; - - if (pRenderObject->m_DissolveRef) - { - if (!(pRenderObject->m_ObjFlags & FOB_DISSOLVE)) - { - pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK; - } - pRenderObject->m_ObjFlags |= FOB_DISSOLVE; - - if (dissolveOut) - { - pRenderObject->m_ObjFlags |= FOB_DISSOLVE_OUT; - } - } - else - { - if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE)) - { - pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK; - } - pRenderObject->m_ObjFlags &= ~FOB_DISSOLVE; - } - - // try next lod's if selected one is not ready - if ((!nLod && m_pRenderMesh && m_pRenderMesh->CanRender()) || !GetCVars()->e_Lods) - { - PrefetchLine(pRenderObject, 0); - RenderRenderMesh(pRenderObject, NULL, passInfo, rendItemSorter); - } - else - { - if (m_pLODs && m_pLODs[nLod]) - { - m_pLODs[nLod]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pLODs[nLod]->m_pParentObject) - { - m_pLODs[nLod]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - - if ((nLod + 1) < MAX_STATOBJ_LODS_NUM && m_pLODs[nLod + 1]) - { - m_pLODs[nLod + 1]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - if (m_pLODs[nLod + 1]->m_pParentObject) - { - m_pLODs[nLod + 1]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID(); - } - } - } - - if (m_pLODs) - { - for (; nLod <= (int)m_nMaxUsableLod; nLod++) - { - if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh && m_pLODs[nLod]->m_pRenderMesh->CanRender()) - { - PrefetchLine(pRenderObject, 0); - m_pLODs[nLod]->RenderRenderMesh(pRenderObject, NULL, passInfo, rendItemSorter); - break; - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CStatObj::RenderRenderMesh(CRenderObject* pRenderObject, [[maybe_unused]] SInstancingInfo* pInstInfo, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ -#if !defined(_RELEASE) - //DEBUG - filter which stat objs are rendered - if (GetCVars()->e_statObjRenderFilterMode && GetCVars()->e_pStatObjRenderFilterStr && GetCVars()->e_pStatObjRenderFilterStr[0]) - { - if (GetCVars()->e_statObjRenderFilterMode == 1) - { - //only render elems containing str - if (!strstr(m_szFileName.c_str(), GetCVars()->e_pStatObjRenderFilterStr)) - { - return; - } - } - else if (GetCVars()->e_statObjRenderFilterMode == 2) - { - //exclude elems containing str - if (strstr(m_szFileName.c_str(), GetCVars()->e_pStatObjRenderFilterStr)) - { - return; - } - } - } - - if (GetCVars()->e_DebugDraw && (!GetCVars()->e_DebugDrawShowOnlyCompound || (m_bSubObject || m_pParentObject))) - { - int nLod = 0; - if (m_pLod0 && m_pLod0->GetLods()) - { - for (; nLod < MAX_STATOBJ_LODS_NUM; nLod++) - { - if (m_pLod0->GetLods()[nLod] == this) - { - m_pRenderMesh->SetMeshLod(nLod); - break; - } - } - } - - if (GetCVars()->e_DebugDrawShowOnlyLod >= 0) - { - if (GetCVars()->e_DebugDrawShowOnlyLod != nLod) - { - return; - } - } - - if (RenderDebugInfo(pRenderObject, passInfo)) - { - return; - } - - if (m_bSubObject) - { - pRenderObject = gEnv->pRenderer->EF_DuplicateRO(pRenderObject, passInfo); - } - } - - if (!passInfo.IsShadowPass()) - { - if (GetCVars()->e_StreamCgfDebug == 1) - { - RenderStreamingDebugInfo(pRenderObject); - } - - if (GetCVars()->e_CoverCgfDebug == 1) - { - RenderCoverInfo(pRenderObject); - } - } -#endif - - if (GetCVars()->e_StatObjTestOBB && !passInfo.IsShadowPass()) - { - Matrix34 worldTM = pRenderObject->GetMatrix(); - - OBB obb = OBB::CreateOBBfromAABB(Matrix33(worldTM), AABB(m_vBoxMin, m_vBoxMax)); - - if (!passInfo.GetCamera().IsOBBVisible_E(worldTM.GetTranslation(), obb)) - { - return; - } - } - if (m_pRenderMesh) - { - CRenderObject* pObj = pRenderObject; -#if !defined(_RELEASE) - if (m_isProxyTooBig) - { - pObj = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo); - pObj->m_pCurrMaterial = m_pMaterial; - } -#endif - m_pRenderMesh->Render(pObj, passInfo, rendItemSorter); - } -} - -/////////////////////////////////////////////////////////////////////////////// -int CStatObj::GetMaxUsableLod() const -{ - int maxUsable = m_pLod0 ? max((int)m_nMaxUsableLod, (int)m_pLod0->GetMaxUsableLod()) : (int)m_nMaxUsableLod; - return min(maxUsable, GetCVars()->e_LodMax); -} - -/////////////////////////////////////////////////////////////////////////////// -int CStatObj::GetMinUsableLod() const -{ - int minUsable = m_pLod0 ? max((int)m_nMinUsableLod0, (int)m_pLod0->GetMinUsableLod()) : (int)m_nMinUsableLod0; - return max(minUsable, GetCVars()->e_LodMin); -} - -/////////////////////////////////////////////////////////////////////////////// -int CStatObj::FindNearesLoadedLOD(int nLodIn, bool bSearchUp) -{ - // make sure requested lod is loaded - /* if(CStatObj * pObjForStreamIn = nLodIn ? m_pLODs[nLodIn] : this) - { - bool bRenderNodeValid(rParams.pRenderNode && ((int)(void*)(rParams.pRenderNode)>0) && rParams.pRenderNode->m_fWSMaxViewDist); - float fImportance = bRenderNodeValid ? (1.f - (rParams.fDistance / rParams.pRenderNode->m_fWSMaxViewDist)) : 0.5f; - pObjForStreamIn->UpdateStreamingPrioriryInternal(fImportance); - }*/ - - // if requested lod is not ready - find nearest ready one - int nLod = nLodIn; - - if (nLod == 0 && !GetRenderMesh()) - { - nLod++; - } - - while (nLod && nLod < MAX_STATOBJ_LODS_NUM && (!m_pLODs || !m_pLODs[nLod] || !m_pLODs[nLod]->GetRenderMesh())) - { - nLod++; - } - - if (nLod > (int)m_nMaxUsableLod) - { - if (bSearchUp) - { - nLod = min((int)m_nMaxUsableLod, nLodIn); - - while (nLod && (!m_pLODs || !m_pLODs[nLod] || !m_pLODs[nLod]->GetRenderMesh())) - { - nLod--; - } - - if (nLod == 0 && !GetRenderMesh()) - { - nLod--; - } - } - else - { - nLod = -1; - } - } - - return nLod; -} - -////////////////////////////////////////////////////////////////////////// -int CStatObj::AddRef() -{ - return CryInterlockedIncrement(&m_nUsers); -} diff --git a/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.cpp b/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.cpp deleted file mode 100644 index 0d305d782c..0000000000 --- a/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.cpp +++ /dev/null @@ -1,617 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "SurfaceTypeManager.h" -#include - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -#define BASE_DYNAMIC_SURFACE_ID 100 -#define DEFAULT_MATERIAL_NAME "mat_default" - -////////////////////////////////////////////////////////////////////////// -template -class CSurfaceTypeEnumerator - : public ISurfaceTypeEnumerator -{ - std::vector m_items; - typename std::vector::iterator m_iterator; - -public: - CSurfaceTypeEnumerator(TMap* pMap) - { - assert(pMap); - m_items.reserve(pMap->size()); - for (typename TMap::iterator it = pMap->begin(); it != pMap->end(); ++it) - { - m_items.push_back(it->second->pSurfaceType); - } - m_iterator = m_items.begin(); - } - virtual void Release() { delete this; }; - virtual ISurfaceType* GetFirst() - { - m_iterator = m_items.begin(); - if (m_iterator == m_items.end()) - { - return 0; - } - return *m_iterator; - } - virtual ISurfaceType* GetNext() - { - if (m_iterator != m_items.end()) - { - m_iterator++; - } - if (m_iterator == m_items.end()) - { - return 0; - } - return *m_iterator; - } -}; - -////////////////////////////////////////////////////////////////////////// -// -////////////////////////////////////////////////////////////////////////// -class CMaterialSurfaceType - : public ISurfaceType -{ -public: - string m_name; - string m_typename; - int m_nId; - int m_nFlags; - SSurfaceTypeAIParams* m_aiParams; - SPhysicalParams m_physParams; - SBreakable2DParams* m_pBreakable2DParams; - std::vector m_breakageParticles; - - CMaterialSurfaceType(const char* name) - { - m_name = name; - m_nId = -1; - m_nFlags = 0; - m_aiParams = 0; - m_pBreakable2DParams = 0; - memset(&m_physParams, 0, sizeof(m_physParams)); - } - ~CMaterialSurfaceType() - { - delete m_pBreakable2DParams; - delete m_aiParams; - } - - void Reset() - { - SAFE_DELETE(m_aiParams); - SAFE_DELETE(m_pBreakable2DParams); - stl::free_container(m_breakageParticles); - stl::free_container(m_typename); - } - - ////////////////////////////////////////////////////////////////////////// - // ISurfaceType interface - ////////////////////////////////////////////////////////////////////////// - virtual void Release() { delete this; } - virtual uint16 GetId() const { return m_nId; } - virtual const char* GetName() const { return m_name; } - virtual const char* GetType() const { return m_typename; }; - virtual int GetFlags() const { return m_nFlags; }; - virtual void Execute([[maybe_unused]] SSurfaceTypeExecuteParams& params) {}; - virtual bool Load(int nId) { m_nId = nId; return true; }; - virtual int GetBreakability() const { return m_physParams.iBreakability; } - virtual int GetHitpoints() const { return (int)m_physParams.hit_points; } - virtual float GetBreakEnergy() const { return (float)m_physParams.break_energy; } - virtual const SSurfaceTypeAIParams* GetAIParams() { return m_aiParams; }; - virtual const SPhysicalParams& GetPhyscalParams() { return m_physParams; }; - virtual SBreakable2DParams* GetBreakable2DParams() { return m_pBreakable2DParams; }; - virtual SBreakageParticles* GetBreakageParticles(const char* sType, bool bLookInDefault = true); - ////////////////////////////////////////////////////////////////////////// -}; - -CMaterialSurfaceType* g_pDefaultSurfaceType = NULL; - -////////////////////////////////////////////////////////////////////////// -CMaterialSurfaceType::SBreakageParticles* CMaterialSurfaceType::GetBreakageParticles(const char* sType, bool bLookInDefault) -{ - for (int i = 0, num = m_breakageParticles.size(); i < num; i++) - { - if (strcmp(sType, m_breakageParticles[i].type) == 0) - { - return &m_breakageParticles[i]; - } - } - if (bLookInDefault && g_pDefaultSurfaceType) - { - for (int i = 0, num = g_pDefaultSurfaceType->m_breakageParticles.size(); i < num; i++) - { - if (strcmp(sType, g_pDefaultSurfaceType->m_breakageParticles[i].type) == 0) - { - return &g_pDefaultSurfaceType->m_breakageParticles[i]; - } - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -static void ReloadSurfaceTypes([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - CSurfaceTypeManager* pMgr = (CSurfaceTypeManager*)(gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager()); - pMgr->LoadSurfaceTypes(); -} - -////////////////////////////////////////////////////////////////////////// -// SurfaceManager implementation. -////////////////////////////////////////////////////////////////////////// -CSurfaceTypeManager::CSurfaceTypeManager(ISystem* pSystem) -{ - m_pSystem = pSystem; - m_lastSurfaceId = BASE_DYNAMIC_SURFACE_ID; - memset(m_idToSurface, 0, sizeof(m_idToSurface)); - - m_pDefaultSurfaceType = new CMaterialSurfaceType(DEFAULT_MATERIAL_NAME); - m_pDefaultSurfaceType->m_nId = 0; - RegisterSurfaceType(m_pDefaultSurfaceType, true); - g_pDefaultSurfaceType = m_pDefaultSurfaceType; - - REGISTER_COMMAND("e_ReloadSurfaces", &ReloadSurfaceTypes, VF_NULL, "Reload physical properties of all materials"); -} - -////////////////////////////////////////////////////////////////////////// -CSurfaceTypeManager::~CSurfaceTypeManager() -{ - g_pDefaultSurfaceType = NULL; - RemoveAll(); - m_pDefaultSurfaceType->Release(); -} - -////////////////////////////////////////////////////////////////////////// -void CSurfaceTypeManager::RemoveAll() -{ - AZStd::unique_lock lock(m_nameToSurfaceMutex); - - // Release all materials. - for (NameToSurfaceMap::iterator it = m_nameToSurface.begin(); it != m_nameToSurface.end(); ++it) - { - SSurfaceRecord* pRec = it->second; - if (pRec->pSurfaceType && pRec->pSurfaceType != m_pDefaultSurfaceType) - { - pRec->pSurfaceType->Release(); - } - delete pRec; - } - - if (m_pDefaultSurfaceType) - { - m_pDefaultSurfaceType->Reset(); - } - - stl::free_container(m_nameToSurface); - memset(m_idToSurface, 0, sizeof(m_idToSurface)); -} - -////////////////////////////////////////////////////////////////////////// -ISurfaceType* CSurfaceTypeManager::GetSurfaceTypeByName(const char* sName, const char* sWhy, bool warn) -{ - if (!sName || *sName == 0 || m_nameToSurface.size() == 1) - { - // Empty surface type. - return m_pDefaultSurfaceType; - } - - AZStd::unique_lock lock(m_nameToSurfaceMutex); - - NameToSurfaceMap::iterator it = m_nameToSurface.find(CONST_TEMP_STRING(sName)); - - SSurfaceRecord* pRec = 0; - - if (it != m_nameToSurface.end()) - { - pRec = it->second; - } - - if (!pRec || !pRec->pSurfaceType) - { - if (!sWhy) - { - sWhy = ""; - } - if (warn) - { - Warning("'%s' undefined surface type, using mat_default (%s)", sName, sWhy); - } - return m_pDefaultSurfaceType; - } - - if (!pRec->bLoaded) - { - pRec->pSurfaceType->Load(pRec->pSurfaceType->GetId()); - pRec->bLoaded = true; - } - return pRec->pSurfaceType; -} - -////////////////////////////////////////////////////////////////////////// -ISurfaceType* CSurfaceTypeManager::GetSurfaceTypeFast(int nSurfaceId, [[maybe_unused]] const char* sWhy) -{ - if (nSurfaceId <= 0 || nSurfaceId >= MAX_SURFACE_ID) - { - return m_pDefaultSurfaceType; - } - SSurfaceRecord* pRec = m_idToSurface[nSurfaceId]; - if (!pRec || !pRec->pSurfaceType) - { - //Warning( "'%d' undefined surface type id, using mat_default (%s)",nSurfaceId,sWhy ); - return m_pDefaultSurfaceType; - } - - if (!pRec->bLoaded) - { - pRec->pSurfaceType->Load(pRec->pSurfaceType->GetId()); - pRec->bLoaded = true; - } - - return pRec->pSurfaceType; -} - -////////////////////////////////////////////////////////////////////////// -ISurfaceType* CSurfaceTypeManager::GetSurfaceType(int nSurfaceId, const char* sWhy) -{ - return GetSurfaceTypeFast(nSurfaceId, sWhy); -} - -////////////////////////////////////////////////////////////////////////// -ISurfaceTypeEnumerator* CSurfaceTypeManager::GetEnumerator() -{ - return new CSurfaceTypeEnumerator(&m_nameToSurface); -} - -////////////////////////////////////////////////////////////////////////// -bool CSurfaceTypeManager::RegisterSurfaceType(ISurfaceType* pSurfaceType, bool bDefault) -{ - AZStd::unique_lock lock(m_nameToSurfaceMutex); - - assert(pSurfaceType); - - int nSurfTypeId = pSurfaceType->GetId(); - - SSurfaceRecord* pRecord = NULL; - - if (nSurfTypeId >= 0 && nSurfTypeId <= MAX_SURFACE_ID) - { - pRecord = m_idToSurface[nSurfTypeId]; - if (pRecord) - { - return true; // Already registered. - } - } - - int nId = m_lastSurfaceId; - if (nId > MAX_SURFACE_ID) - { - return false; - } - - if (bDefault) - { - nId = 0; - //m_pDefaultSurfaceType = pSurfaceType; - } - if (!pSurfaceType->Load(nId)) - { - return false; - } - - if (!bDefault) - { - m_lastSurfaceId++; - } - - pRecord = new SSurfaceRecord; - pRecord->bLoaded = true; - pRecord->pSurfaceType = pSurfaceType; - - m_idToSurface[nId] = pRecord; - m_nameToSurface[pSurfaceType->GetName()] = pRecord; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CSurfaceTypeManager::UnregisterSurfaceType(ISurfaceType* pSurfaceType) -{ - AZStd::unique_lock lock(m_nameToSurfaceMutex); - - assert(pSurfaceType); - - assert(pSurfaceType->GetId() <= MAX_SURFACE_ID); - - SSurfaceRecord* pRecord = m_idToSurface[pSurfaceType->GetId()]; - if (pRecord) - { - m_idToSurface[pSurfaceType->GetId()] = 0; - m_nameToSurface.erase(pSurfaceType->GetName()); - delete pRecord; - } -} - -////////////////////////////////////////////////////////////////////////// -void CSurfaceTypeManager::LoadSurfaceTypes() -{ - XmlNodeRef root = GetISystem()->LoadXmlFromFile("Libs/MaterialEffects/SurfaceTypes.xml"); - if (!root) - { - return; - } - - RemoveAll(); - - m_lastSurfaceId = BASE_DYNAMIC_SURFACE_ID; - RegisterSurfaceType(m_pDefaultSurfaceType, true); - - for (int i = 0, nChilds = root->getChildCount(); i < nChilds; i++) - { - SLICE_AND_SLEEP(); - - XmlNodeRef matNode = root->getChild(i); - if (!matNode->isTag("SurfaceType")) - { - continue; - } - - const char* sName = matNode->getAttr("name"); - NameToSurfaceMap::iterator it = m_nameToSurface.find(CONST_TEMP_STRING(sName)); - CMaterialSurfaceType* pSurfaceType = 0; - if (it != m_nameToSurface.end()) - { - pSurfaceType = (CMaterialSurfaceType*)it->second->pSurfaceType; - } - if (strcmp(sName, DEFAULT_MATERIAL_NAME) == 0) - { - pSurfaceType = m_pDefaultSurfaceType; - } - - if (!pSurfaceType) - { - pSurfaceType = new CMaterialSurfaceType(sName); - bool bDefault = false; - if (!RegisterSurfaceType(pSurfaceType, bDefault)) - { - continue; - } - } - - int bManuallyBreakable = 0; - bool bNoCollide = false; - bool vehicle_only_collisions = false; - bool nBreakable2d = 0; - bool can_shatter = false; - - ISurfaceType::SPhysicalParams& physParams = pSurfaceType->m_physParams; - - pSurfaceType->m_typename = matNode->getAttr("type"); - if (pSurfaceType->m_typename.empty()) - { - // typename will be name with mat_ prefix. - pSurfaceType->m_typename = pSurfaceType->m_name; - if (pSurfaceType->m_typename.find("mat_") == 0) - { - pSurfaceType->m_typename = pSurfaceType->m_typename.substr(4); - } - } - - XmlNodeRef physNode = matNode->findChild("Physics"); - physParams.friction = 0.7f; - physParams.breakable_id = -1; - physParams.collType = 1 << 31; // means "use default" - physParams.sound_obstruction = 0.0f; - - if (physNode) - { - physNode->getAttr("friction", physParams.friction); - physNode->getAttr("elasticity", physParams.bouncyness); - physNode->getAttr("breakable_id", physParams.breakable_id); - physNode->getAttr("pierceability", physParams.pierceability = 0); - physNode->getAttr("damage_reduction", physParams.damage_reduction = 0); - physNode->getAttr("ricochet_angle", physParams.ric_angle = 0); - physNode->getAttr("ric_dam_reduction", physParams.ric_dam_reduction = 0); - physNode->getAttr("ric_vel_reduction", physParams.ric_vel_reduction = 0); - physNode->getAttr("no_collide", bNoCollide = 0); - physNode->getAttr("break_energy", physParams.break_energy = 0); - physNode->getAttr("hit_points", physParams.hit_points = 0); - physNode->getAttr("hit_radius", physParams.hit_radius = 10000.0f); - physNode->getAttr("hit_maxdmg", physParams.hit_maxdmg = 1000); - physNode->getAttr("hit_lifetime", physParams.hit_lifetime = 10.0f); - physNode->getAttr("hole_size", physParams.hole_size); - physNode->getAttr("hole_size_explosion", physParams.hole_size_explosion = 0.0f); - physNode->getAttr("breakable_2d", nBreakable2d); - physNode->getAttr("hit_points_secondary", physParams.hit_points_secondary = nBreakable2d ? 1.0f : physParams.hit_points); - physNode->getAttr("vehicle_only_collisions", vehicle_only_collisions); - physNode->getAttr("can_shatter", can_shatter); - physNode->getAttr("sound_obstruction", physParams.sound_obstruction); - - string collTypeStr = physNode->getAttr("coll_types"); - if (collTypeStr.length()) - { - physParams.collType = geom_floats; - for (const char* ptr = collTypeStr.c_str(); *ptr; ) - { - for (; *ptr && (unsigned char)(*ptr - '0') > 9u; ptr++) - { - ; - } - const char* ptr0 = ptr; - int num = 0; - for (; (unsigned char)(*ptr - '0') <= 9u; (num *= 10) += *ptr++ - '0') - { - ; - } - if (ptr > ptr0) - { - if (ptr0 > collTypeStr.c_str() && (ptr0[-1] == '-' || ptr0[-1] == '~')) - { - physParams.collType &= ~(1 << num); - } - else - { - physParams.collType |= 1 << num; - } - } - } - const char* collNames[] = { "default", "all", "player", "vehicle", "explosion", "ray", "float", "water" }; - const int collVals[] = { geom_colltype0, geom_collides, geom_colltype_player, geom_colltype_vehicle, geom_colltype_explosion, geom_colltype_ray, geom_floats, geom_floats }; - for (int j = 0; j < sizeof(collVals) / sizeof(collVals[0]); j++) - { - if (const char* name = strstr(collTypeStr.c_str(), collNames[j])) - { - if (name > collTypeStr.c_str() && (name[-1] == '-' || name[-1] == '~')) - { - physParams.collType &= ~collVals[j]; - } - else - { - physParams.collType |= collVals[j]; - } - } - } - } - else - { - physParams.collType = 1 << 31; - } - - //Clamp pierceability - physParams.pierceability = max(0, min(15, physParams.pierceability)); - - // only assign if the object is not the same, otherwise the compiler - // will invoke a memcpy with the same source and destination - if (&pSurfaceType->m_physParams != &physParams) - { - pSurfaceType->m_physParams = physParams; - } - - if (physParams.break_energy != 0) - { - physParams.iBreakability = nBreakable2d ? 1 : 2; - bManuallyBreakable = sf_manually_breakable; - } - - if (bNoCollide) - { - pSurfaceType->m_nFlags |= SURFACE_TYPE_NO_COLLIDE; - } - if (vehicle_only_collisions) - { - pSurfaceType->m_nFlags |= SURFACE_TYPE_VEHICLE_ONLY_COLLISION; - } - if (can_shatter) - { - pSurfaceType->m_nFlags |= SURFACE_TYPE_CAN_SHATTER; - } - - } - - XmlNodeRef break2dNode = matNode->findChild("breakable_2d"); - if (break2dNode) - { - ISurfaceType::SBreakable2DParams break2dParams; - break2dNode->getAttr("blast_radius", break2dParams.blast_radius = 0.2f); - if (!break2dNode->getAttr("blast_radius_first", break2dParams.blast_radius_first = 0.2f)) - { - break2dParams.blast_radius_first = break2dParams.blast_radius; - } - break2dNode->getAttr("vert_size_spread", break2dParams.vert_size_spread = 0.0f); - break2dNode->getAttr("rigid_body", break2dParams.rigid_body = 0); - break2dNode->getAttr("lifetime", break2dParams.life_time = 4.0f); - break2dParams.particle_effect = break2dNode->getAttr("particle_effect"); - - break2dNode->getAttr("cell_size", break2dParams.cell_size = 0.1f); - break2dNode->getAttr("max_patch_tris", break2dParams.max_patch_tris = 6); - break2dNode->getAttr("filter_angle", break2dParams.filter_angle = 0.0f); - break2dNode->getAttr("shard_density", break2dParams.shard_density = 1200.0f); - - break2dNode->getAttr("crack_decal_scale", break2dParams.crack_decal_scale = 0.0f); - break2dParams.crack_decal_mtl = break2dNode->getAttr("crack_decal_mtl"); - break2dNode->getAttr("max_fracture", break2dParams.max_fracture = 1.0f); - break2dParams.full_fracture_fx = break2dNode->getAttr("full_fracture_fx"); - break2dNode->getAttr("use_edge_alpha", break2dParams.use_edge_alpha = 0); - break2dParams.fracture_fx = break2dNode->getAttr("fracture_fx"); - break2dNode->getAttr("no_procedural_full_fracture", break2dParams.no_procedural_full_fracture = 0); - break2dParams.broken_mtl = break2dNode->getAttr("broken_mtl"); - if (break2dParams.broken_mtl.length()) - { - gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(break2dParams.broken_mtl, false); - } - break2dNode->getAttr("destroy_timeout", break2dParams.destroy_timeout = 0); - break2dNode->getAttr("destroy_timeout_spread", break2dParams.destroy_timeout_spread = 0); - - SAFE_DELETE(pSurfaceType->m_pBreakable2DParams); - pSurfaceType->m_pBreakable2DParams = new ISurfaceType::SBreakable2DParams; - *pSurfaceType->m_pBreakable2DParams = break2dParams; - } - - { - size_t nBreakageParticles = 0; - for (int n = 0; n < matNode->getChildCount(); n++) - { - XmlNodeRef breakageNode = matNode->getChild(n); - if (breakageNode->isTag("BreakageParticles")) - { - ++nBreakageParticles; - } - } - pSurfaceType->m_breakageParticles.reserve(nBreakageParticles); - - // Load Breakage particles. - for (int n = 0; n < matNode->getChildCount(); n++) - { - XmlNodeRef breakageNode = matNode->getChild(n); - if (breakageNode->isTag("BreakageParticles")) - { - ISurfaceType::SBreakageParticles params; - breakageNode->getAttr("scale", params.scale); - breakageNode->getAttr("count_scale", params.count_scale); - breakageNode->getAttr("count_per_unit", params.count_per_unit); - params.type = breakageNode->getAttr("type"); - params.particle_effect = breakageNode->getAttr("effect"); - - pSurfaceType->m_breakageParticles.push_back(params); - } - } - } - - XmlNodeRef aiNode = matNode->findChild("AI"); - if (aiNode) - { - ISurfaceType::SSurfaceTypeAIParams aiParams; - aiNode->getAttr("fImpactRadius", aiParams.fImpactRadius); - aiNode->getAttr("fImpactSoundRadius", aiParams.fImpactSoundRadius); - aiNode->getAttr("fFootStepRadius", aiParams.fFootStepRadius); - aiNode->getAttr("proneMult", aiParams.proneMult); - aiNode->getAttr("crouchMult", aiParams.crouchMult); - aiNode->getAttr("movingMult", aiParams.movingMult); - - SAFE_DELETE(pSurfaceType->m_aiParams); - pSurfaceType->m_aiParams = new ISurfaceType::SSurfaceTypeAIParams; - *pSurfaceType->m_aiParams = aiParams; - } - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.h b/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.h deleted file mode 100644 index 6981f5e7a6..0000000000 --- a/Code/CryEngine/Cry3DEngine/SurfaceTypeManager.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_SURFACETYPEMANAGER_H -#define CRYINCLUDE_CRY3DENGINE_SURFACETYPEMANAGER_H -#pragma once - -#include - -#define MAX_SURFACE_ID 255 - -////////////////////////////////////////////////////////////////////////// -// SurfaceManager is implementing ISurfaceManager interface. -// Register and manages all known to game surface typs. -////////////////////////////////////////////////////////////////////////// -class CSurfaceTypeManager - : public ISurfaceTypeManager - , public Cry3DEngineBase -{ -public: - CSurfaceTypeManager(ISystem* pSystem); - virtual ~CSurfaceTypeManager(); - - virtual void LoadSurfaceTypes(); - - virtual ISurfaceType* GetSurfaceTypeByName(const char* sName, const char* sWhy = NULL, bool warn = true); - virtual ISurfaceType* GetSurfaceType(int nSurfaceId, const char* sWhy = NULL); - virtual ISurfaceTypeEnumerator* GetEnumerator(); - - bool RegisterSurfaceType(ISurfaceType* pSurfaceType, bool bDefault = false); - void UnregisterSurfaceType(ISurfaceType* pSurfaceType); - - ISurfaceType* GetSurfaceTypeFast(int nSurfaceId, const char* sWhy = NULL); - - void RemoveAll(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_nameToSurface); - for (int i = 0; i < MAX_SURFACE_ID + 1; ++i) - { - pSizer->AddObject(m_idToSurface[i]); - } - } -private: - ISystem* m_pSystem; - int m_lastSurfaceId; - - class CMaterialSurfaceType* m_pDefaultSurfaceType; - - struct SSurfaceRecord - { - bool bLoaded; - ISurfaceType* pSurfaceType; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - }; - - SSurfaceRecord* m_idToSurface[MAX_SURFACE_ID + 1]; - - AZStd::mutex m_nameToSurfaceMutex; - typedef std::map NameToSurfaceMap; - NameToSurfaceMap m_nameToSurface; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_SURFACETYPEMANAGER_H diff --git a/Code/CryEngine/Cry3DEngine/Tests/MaterialTests.cpp b/Code/CryEngine/Cry3DEngine/Tests/MaterialTests.cpp deleted file mode 100644 index 913b52f531..0000000000 --- a/Code/CryEngine/Cry3DEngine/Tests/MaterialTests.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include -#include -#include -#include - -#include "Material.h" - -class MaterialTest - : public UnitTest::AllocatorsTestFixture -{ -public: - void SetUp() override - { - // capture prior state. - m_priorEnv = gEnv; - m_priorSystem = Cry3DEngineBase::m_pSystem; - m_priorRenderer = Cry3DEngineBase::m_pRenderer; - - UnitTest::AllocatorsTestFixture::SetUp(); - - // LegacyAllocator is a lazily-created allocator, so it will always exist, but we still manually shut it down and - // start it up again between tests so we can have consistent behavior. - if (!AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Create(); - } - - m_data = AZStd::make_unique(); - - m_data->m_stubEnv.pSystem = &m_data->m_system; - m_data->m_stubEnv.pRenderer = &m_data->m_renderer; - - // override state - gEnv = &m_data->m_stubEnv; - Cry3DEngineBase::m_pSystem = gEnv->pSystem; - Cry3DEngineBase::m_pRenderer = &m_data->m_renderer; - } - - void TearDown() override - { - m_data.reset(); - - AZ::AllocatorInstance::Destroy(); - UnitTest::AllocatorsTestFixture::TearDown(); - - // restore state. - gEnv = m_priorEnv; - Cry3DEngineBase::m_pSystem = m_priorSystem; - Cry3DEngineBase::m_pRenderer = m_priorRenderer; - } - - struct DataMembers - { - SSystemGlobalEnvironment m_stubEnv; - ::testing::NiceMock m_system; - ::testing::NiceMock m_renderer; - }; - - AZStd::unique_ptr m_data; - SSystemGlobalEnvironment* m_priorEnv = nullptr; - ISystem* m_priorSystem = nullptr; - IRenderer* m_priorRenderer = nullptr; -}; - -TEST_F(MaterialTest, CMatInfo_SetSubMtl_OutOfRange) -{ - _smart_ptr materialGroup = new CMatInfo(); - _smart_ptr validSubMaterial = new CMatInfo(); - _smart_ptr outOfRangeSubMaterial = new CMatInfo(); - - // Make materialGroup into an actual material group - materialGroup->SetSubMtlCount(1); - materialGroup->SetSubMtl(0, validSubMaterial); - - AZ_TEST_START_TRACE_SUPPRESSION; - // SetSubMtl should fail because the index is beyond the range of material's vector of sub-materials - materialGroup->SetSubMtl(2, outOfRangeSubMaterial); - materialGroup->SetSubMtl(-1, outOfRangeSubMaterial); - AZ_TEST_STOP_TRACE_SUPPRESSION(2); - - // Material should still have a 1-size vector of sub-materials, with 'subMaterial' as its only sub-material - EXPECT_TRUE(materialGroup->IsMaterialGroup()); - EXPECT_EQ(materialGroup->GetSubMtlCount(), 1); - EXPECT_EQ(materialGroup->GetSubMtl(0), validSubMaterial); - EXPECT_EQ(materialGroup->GetSubMtl(1), nullptr); -} - -TEST_F(MaterialTest, CMatInfo_SetSubMtl_InvalidSubMaterial) -{ - _smart_ptr materialGroup = new CMatInfo(); - _smart_ptr inValidSubMaterial = new CMatInfo(); - _smart_ptr validSubMaterial0 = new CMatInfo(); - _smart_ptr validSubMaterial1 = new CMatInfo(); - - // Make the two materials into material groups by inserting sub-materials - materialGroup->SetSubMtlCount(2); - materialGroup->SetSubMtl(0, validSubMaterial0); - materialGroup->SetSubMtl(1, validSubMaterial1); - - inValidSubMaterial->SetSubMtlCount(2); - inValidSubMaterial->SetSubMtl(0, validSubMaterial0); - inValidSubMaterial->SetSubMtl(1, validSubMaterial1); - - // SetSubMtl should fail because subMaterial is a material group, and material groups cannot be sub-materials - AZ_TEST_START_TRACE_SUPPRESSION; - materialGroup->SetSubMtl(1, inValidSubMaterial); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - - // Check that subMaterial is not the material at index 1, since SetSubMtl should have failed - EXPECT_EQ(materialGroup->GetSubMtl(1), validSubMaterial1); - EXPECT_NE(materialGroup->GetSubMtl(1), inValidSubMaterial); -} - -TEST_F(MaterialTest, CMatInfo_SetSubMtlCount_SetsMaterialGroupFlag) -{ - _smart_ptr material = new CMatInfo(); - - // Check to ensure the material group flag is being set - material->SetSubMtlCount(1); - EXPECT_TRUE(material->IsMaterialGroup()); - - // Check to ensure the material group flag is being un-set - material->SetSubMtlCount(0); - EXPECT_FALSE(material->IsMaterialGroup()); -} - -TEST_F(MaterialTest, CMatInfo_IsDirty_DoesNotCrash) -{ - // Create a material group with two sub-materials - _smart_ptr materialGroup = new CMatInfo(); - materialGroup->SetSubMtlCount(2); - - // Set one sub-material to be null, and the other valid - _smart_ptr subMaterial = new CMatInfo(); - materialGroup->SetSubMtl(0, nullptr); - materialGroup->SetSubMtl(1, subMaterial); - - // Call IsDirty to validate that it does not crash - EXPECT_FALSE(materialGroup->IsDirty()); -} diff --git a/Code/CryEngine/Cry3DEngine/Tests/MockValidationTest.cpp b/Code/CryEngine/Cry3DEngine/Tests/MockValidationTest.cpp deleted file mode 100644 index 5ba771bc69..0000000000 --- a/Code/CryEngine/Cry3DEngine/Tests/MockValidationTest.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include -#include -#include - -TEST(MockValidationTests, SystemMock_Compiles) -{ - SystemMock mockSystem; -} - -TEST(MockValidationTests, LogMock_Compiles) -{ - LogMock mockLog; -} diff --git a/Code/CryEngine/Cry3DEngine/Tests/OctreeTest.cpp b/Code/CryEngine/Cry3DEngine/Tests/OctreeTest.cpp deleted file mode 100644 index 914605a40d..0000000000 --- a/Code/CryEngine/Cry3DEngine/Tests/OctreeTest.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include - -#include -#include -#include -#include "DecalRenderNode.h" - -class OctreeTest - : public UnitTest::AllocatorsTestFixture -{ -public: - void SetUp() override - { - // capture prior state. - m_savedState.m_Env = gEnv; - m_savedState.m_3DEngine = Cry3DEngineBase::m_p3DEngine; - m_savedState.m_system = Cry3DEngineBase::m_pSystem; - m_savedState.m_cvars = Cry3DEngineBase::m_pCVars; - - UnitTest::AllocatorsTestFixture::SetUp(); - - // LegacyAllocator is a lazily-created allocator, so it will always exist, but we still manually shut it down and - // start it up again between tests so we can have consistent behavior. - if (!AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Create(); - } - - m_data = AZStd::make_unique(); - - // override state with our needed test mocks - gEnv = &(m_data->m_mockGEnv); - m_data->m_mockGEnv.p3DEngine = &(m_data->m_mock3DEngine); - m_data->m_mockGEnv.pSystem = &(m_data->m_system); - Cry3DEngineBase::m_pSystem = gEnv->pSystem; - - // NOTE: We've mocked out I3DEngine, but we don't currently have a mock of C3DEngine. - // For these unit tests, we need all code paths that we're testing to go through I3DEngine. - // We set the engine's C3DEngine pointer to null to guarantee we aren't using it. - Cry3DEngineBase::m_p3DEngine = nullptr; - - // Set GetISystem()->GetI3DEngine() to return our mocked I3DEngine. - EXPECT_CALL(m_data->m_system, GetI3DEngine()).WillRepeatedly(Return(&(m_data->m_mock3DEngine))); - - // Create a default set of CVars for the Octree to read from. - // This needs to happen *after* we've set gEnv, since CVars() - // is dependent on it. - m_mockCVars = new CVars(); - Cry3DEngineBase::m_pCVars = m_mockCVars; - - // Create the test Octree - const int nSID = 0; - m_octree = COctreeNode::Create(nSID, AABB(Vec3(0.0f), Vec3(1024.0f)), nullptr); - } - - void TearDown() override - { - // Remove our test octree and mock cvars - delete m_octree; - delete m_mockCVars; - - // Remove the other mocked systems - m_data.reset(); - - AZ::AllocatorInstance::Destroy(); - UnitTest::AllocatorsTestFixture::TearDown(); - - // restore the global state that we modified during the test. - gEnv = m_savedState.m_Env; - Cry3DEngineBase::m_p3DEngine = m_savedState.m_3DEngine; - Cry3DEngineBase::m_pSystem = m_savedState.m_system; - Cry3DEngineBase::m_pCVars = m_savedState.m_cvars; - } - - // Helper functions - IRenderNode* CreateAndAddDecalNode(float radius) - { - AABB nodeBox(radius); - IRenderNode* decalEntity = new CDecalRenderNode(); - decalEntity->SetBBox(nodeBox); - m_octree->InsertObject(decalEntity, nodeBox, (radius * radius), nodeBox.GetCenter()); - return decalEntity; - } - - void RemoveNode(IRenderNode* node) - { - m_octree->DeleteObject(node); - delete node; - } - -protected: - struct DataMembers - { - SSystemGlobalEnvironment m_mockGEnv; - ::testing::NiceMock m_mock3DEngine; - ::testing::NiceMock m_system; - }; - - AZStd::unique_ptr m_data; - - CVars* m_mockCVars = nullptr; - COctreeNode* m_octree = nullptr; - -private: - struct SavedState - { - SSystemGlobalEnvironment* m_Env = nullptr; - C3DEngine* m_3DEngine = nullptr; - ISystem* m_system = nullptr; - CVars* m_cvars = nullptr; - }; - - SavedState m_savedState; -}; diff --git a/Code/CryEngine/Cry3DEngine/Tests/Test_Cry3DEngine.cpp b/Code/CryEngine/Cry3DEngine/Tests/Test_Cry3DEngine.cpp deleted file mode 100644 index 5b8dfbaac7..0000000000 --- a/Code/CryEngine/Cry3DEngine/Tests/Test_Cry3DEngine.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "Cry3DEngine_precompiled.h" -#include - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); - -TEST(Cry3DEngineCVarTest, DeclareConstIntCVar_CheckDefault_ReturnsValue_FT) -{ - // Set the default value in the initialization - struct Foo { - DeclareConstIntCVar(test_cvar, 15); - } foo; - EXPECT_EQ(foo.test_cvar, 15); - - DeclareConstIntCVar(test_cvar2, 15); - EXPECT_EQ(test_cvar2, 15); -} diff --git a/Code/CryEngine/Cry3DEngine/TimeOfDay.cpp b/Code/CryEngine/Cry3DEngine/TimeOfDay.cpp deleted file mode 100644 index 067616899a..0000000000 --- a/Code/CryEngine/Cry3DEngine/TimeOfDay.cpp +++ /dev/null @@ -1,1251 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include -#include "TimeOfDay.h" -#include "Ocean.h" -#include "IPostEffectGroup.h" -#include -#include -#include "EnvironmentPreset.h" -#include - -// Maximum number of minutes in a day converted to a float value -static const float s_maxTime = ((24 * 60) - 1) / 60.0f; - -class CBezierSplineFloat - : public spline::CBaseSplineInterpolator > -{ -public: - float m_fMinValue; - float m_fMaxValue; - - virtual int GetNumDimensions() { return 1; }; - - virtual void Interpolate(float time, ValueType& value) - { - value_type v; - if (interpolate(time, v)) - { - ToValueType(v, value); - } - // Clamp values - //value[0] = clamp_tpl(value[0],m_fMinValue,m_fMaxValue); - } - - ////////////////////////////////////////////////////////////////////////// - void SerializeSpline(XmlNodeRef& node, bool bLoading) - { - if (bLoading) - { - string keystr = node->getAttr("Keys"); - - resize(0); - int curPos = 0; - uint32 nKeys = 0; - string key = keystr.Tokenize(",", curPos); - while (!key.empty()) - { - ++nKeys; - key = keystr.Tokenize(",", curPos); - } - reserve_keys(nKeys); - - curPos = 0; - key = keystr.Tokenize(",", curPos); - while (!key.empty()) - { - float time, v; - int flags = 0; - - int res = azsscanf(key, "%g:%g:%d", &time, &v, &flags); - if (res != 3) - { - res = azsscanf(key, "%g:%g", &time, &v); - if (res != 2) - { - continue; - } - } - ValueType val; - val[0] = v; - int keyIndex = InsertKey(time, val); - SetKeyFlags(keyIndex, flags); - key = keystr.Tokenize(",", curPos); - } - } - else - { - string keystr; - string skey; - for (int i = 0; i < num_keys(); i++) - { - skey.Format("%g:%g:%d,", key(i).time, key(i).value, key(i).flags); - keystr += skey; - } - node->setAttr("Keys", keystr); - } - } -}; - -////////////////////////////////////////////////////////////////////////// -class CBezierSplineVec3 - : public spline::CBaseSplineInterpolator > -{ -public: - virtual int GetNumDimensions() { return 3; }; - - virtual void Interpolate(float time, ValueType& value) - { - value_type v; - if (interpolate(time, v)) - { - ToValueType(v, value); - } - // Clamp for colors. - //value[0] = clamp_tpl(value[0],0.0f,1.0f); - //value[1] = clamp_tpl(value[1],0.0f,1.0f); - //value[2] = clamp_tpl(value[2],0.0f,1.0f); - } - - ////////////////////////////////////////////////////////////////////////// - void SerializeSpline(XmlNodeRef& node, bool bLoading) - { - if (bLoading) - { - string keystr = node->getAttr("Keys"); - - resize(0); - int curPos = 0; - uint32 nKeys = 0; - string key = keystr.Tokenize(",", curPos); - while (!key.empty()) - { - ++nKeys; - key = keystr.Tokenize(",", curPos); - } - reserve_keys(nKeys); - - curPos = 0; - key = keystr.Tokenize(",", curPos); - while (!key.empty()) - { - float time, val0, val1, val2; - int flags = 0; - int res = azsscanf(key, "%g:(%g:%g:%g):%d,", &time, &val0, &val1, &val2, &flags); - if (res != 5) - { - res = azsscanf(key, "%g:(%g:%g:%g),", &time, &val0, &val1, &val2); - if (res != 4) - { - continue; - } - } - ValueType val; - val[0] = val0; - val[1] = val1; - val[2] = val2; - int keyIndex = InsertKey(time, val); - SetKeyFlags(keyIndex, flags); - key = keystr.Tokenize(",", curPos); - } - } - else - { - string keystr; - string skey; - for (int i = 0; i < num_keys(); i++) - { - skey.Format("%g:(%g:%g:%g):%d,", key(i).time, key(i).value.x, key(i).value.y, key(i).value.z, key(i).flags); - keystr += skey; - } - node->setAttr("Keys", keystr); - } - } - - void ClampValues([[maybe_unused]] float fMinValue, [[maybe_unused]] float fMaxValue) - { - for (int i = 0, nkeys = num_keys(); i < nkeys; i++) - { - ValueType val; - if (GetKeyValue(i, val)) - { - //val[0] = clamp_tpl(val[0],fMinValue,fMaxValue); - //val[1] = clamp_tpl(val[1],fMinValue,fMaxValue); - //val[2] = clamp_tpl(val[2],fMinValue,fMaxValue); - SetKeyValue(i, val); - } - } - } -}; - -////////////////////////////////////////////////////////////////////////// -CTimeOfDay::CTimeOfDay() -{ - m_pTimer = 0; - SetTimer(gEnv->pTimer); - m_fTime = 12; - m_fEditorTime = 12; - m_bEditMode = false; - - m_advancedInfo.fAnimSpeed = 0; - m_advancedInfo.fStartTime = 0; - m_advancedInfo.fEndTime = 24; - m_fHDRMultiplier = 1.f; - m_pTimeOfDaySpeedCVar = gEnv->pConsole->GetCVar("e_TimeOfDaySpeed"); - m_pUpdateCallback = 0; - m_sunRotationLatitude = 0; - m_sunRotationLongitude = 0; - m_bPaused = false; - m_bSunLinkedToTOD = true; - memset(m_vars, 0, sizeof(SVariableInfo) * ITimeOfDay::PARAM_TOTAL); - - // fill local var list so, sandbox can access var list without level being loaded - - // Cryengine supports the notion of environment presets which are set in code that is currently not - // in Open 3D Engine. Therefore, create a default preset here that is used as the only one. - m_defaultPreset = new CEnvironmentPreset; - for (int i = 0; i < PARAM_TOTAL; ++i) - { - const CTimeOfDayVariable* presetVar = m_defaultPreset->GetVar((ETimeOfDayParamID)i); - SVariableInfo& var = m_vars[i]; - - var.name = presetVar->GetName(); - var.displayName = presetVar->GetDisplayName(); - var.group = presetVar->GetGroupName(); - - var.nParamId = i; - var.type = presetVar->GetType(); - var.pInterpolator = NULL; - - Vec3 presetVal = presetVar->GetValue(); - var.fValue[0] = presetVal.x; - const EVariableType varType = presetVar->GetType(); - if (varType == TYPE_FLOAT) - { - var.fValue[1] = presetVar->GetMinValue(); - var.fValue[2] = presetVar->GetMaxValue(); - } - else if (varType == TYPE_COLOR) - { - var.fValue[1] = presetVal.y; - var.fValue[2] = presetVal.z; - } - } - - m_pCurrentPreset = m_defaultPreset; - - ResetVariables(); -} - -////////////////////////////////////////////////////////////////////////// -CTimeOfDay::~CTimeOfDay() -{ - for (int i = 0; i < GetVariableCount(); i++) - { - switch (m_vars[i].type) - { - case TYPE_FLOAT: - delete (CBezierSplineFloat*)(m_vars[i].pInterpolator); - break; - case TYPE_COLOR: - delete (CBezierSplineVec3*)(m_vars[i].pInterpolator); - break; - } - } - - SAFE_DELETE(m_defaultPreset); -} - -void CTimeOfDay::SetTimer(ITimer* pTimer) -{ - AZ_Assert(pTimer, "Null pointer access in CTimeOfDay::SetTimer!"); - m_pTimer = pTimer; - - // Update timer for ocean also - Craig - COcean::SetTimer(pTimer); -} - -ITimeOfDay::SVariableInfo& CTimeOfDay::GetVar(ETimeOfDayParamID id) -{ - AZ_Assert(id == m_vars[id].nParamId, "Wrong ID in CTimeOfDay::GetVar!"); - return(m_vars[ id ]); -} - -////////////////////////////////////////////////////////////////////////// -bool CTimeOfDay::GetVariableInfo(int nIndex, SVariableInfo& varInfo) const -{ - if (nIndex < 0 || nIndex >= GetVariableCount()) - { - return false; - } - - varInfo = m_vars[nIndex]; - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::SetVariableValue(int nIndex, float fValue[3]) -{ - if (nIndex < 0 || nIndex >= GetVariableCount()) - { - return; - } - - m_vars[nIndex].fValue[0] = fValue[0]; - m_vars[nIndex].fValue[1] = fValue[1]; - m_vars[nIndex].fValue[2] = fValue[2]; -} -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::ResetVariables() -{ - if (!m_pCurrentPreset) - { - return; - } - - m_pCurrentPreset->ResetVariables(); - - m_varsMap.clear(); - for (int i = 0; i < PARAM_TOTAL; ++i) - { - const CTimeOfDayVariable* presetVar = m_pCurrentPreset->GetVar((ETimeOfDayParamID)i); - SVariableInfo& var = m_vars[i]; - - var.name = presetVar->GetName(); - var.displayName = presetVar->GetDisplayName(); - var.group = presetVar->GetGroupName(); - - var.nParamId = i; - var.type = presetVar->GetType(); - SAFE_DELETE(var.pInterpolator); - - Vec3 presetVal = presetVar->GetValue(); - var.fValue[0] = presetVal.x; - const EVariableType varType = presetVar->GetType(); - if (varType == TYPE_FLOAT) - { - var.fValue[1] = presetVar->GetMinValue(); - var.fValue[2] = presetVar->GetMaxValue(); - - CBezierSplineFloat* pSpline = new CBezierSplineFloat; - pSpline->m_fMinValue = var.fValue[1]; - pSpline->m_fMaxValue = var.fValue[2]; - pSpline->reserve_keys(2); - pSpline->InsertKeyFloat(0, var.fValue[0]); - pSpline->InsertKeyFloat(1, var.fValue[0]); - var.pInterpolator = pSpline; - } - else if (varType == TYPE_COLOR) - { - var.fValue[1] = presetVal.y; - var.fValue[2] = presetVal.z; - - CBezierSplineVec3* pSpline = new CBezierSplineVec3; - pSpline->reserve_keys(2); - pSpline->InsertKeyFloat3(0, var.fValue); - pSpline->InsertKeyFloat3(1, var.fValue); - var.pInterpolator = pSpline; - } - - m_varsMap[var.name] = var.nParamId; - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::SetEnvironmentSettings(const SEnvironmentInfo& envInfo) -{ - m_sunRotationLongitude = envInfo.sunRotationLongitude; - m_sunRotationLatitude = envInfo.sunRotationLatitude; - m_bSunLinkedToTOD = envInfo.bSunLinkedToTOD; -} - - -////////////////////////////////////////////////////////////////////////// -// Time of day is specified in hours. -void CTimeOfDay::SetTime(float fHour, bool bForceUpdate, bool bEnvUpdate) -{ - // set new time - m_fTime = fHour; - - // Change time variable. - Cry3DEngineBase::GetCVars()->e_TimeOfDay = m_fTime; - - Update(true, bForceUpdate, bEnvUpdate); - - gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_TIME_OF_DAY_SET, 0, 0); -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::SetSunPos(float longitude, float latitude) -{ - m_sunRotationLongitude = longitude; - m_sunRotationLatitude = latitude; -} - - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::Update(bool bInterpolate, bool bForceUpdate, bool bEnvUpdate) -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_3DENGINE); - - if (bInterpolate) - { - if (m_pUpdateCallback) - { - m_pUpdateCallback->BeginUpdate(); - } - - // normalized time for interpolation - float t = m_fTime / s_maxTime; - - // interpolate all values - for (uint32 i = 0; i < static_cast(GetVariableCount()); i++) - { - SVariableInfo& var = m_vars[i]; - if (var.pInterpolator) - { - if (var.pInterpolator->GetNumDimensions() == 1) - { - var.pInterpolator->InterpolateFloat(t, var.fValue[0]); - } - else if (var.pInterpolator->GetNumDimensions() == 3) - { - var.pInterpolator->InterpolateFloat3(t, var.fValue); - } - - if (m_pUpdateCallback) - { - const int dim = var.pInterpolator->GetNumDimensions(); - float customValues[3] = {0, 0, 0}; - float blendWeight = 0; - if (m_pUpdateCallback->GetCustomValue((ETimeOfDayParamID) var.nParamId, dim, customValues, blendWeight)) - { - AZ_Assert(blendWeight >= 0 && blendWeight <= 1, "blendweight outside 0 and 1 in CTimeOfDay::Update!"); - blendWeight = clamp_tpl(blendWeight, 0.0f, 1.0f); - for (int j = 0; j < dim; ++j) - { - var.fValue[j] = var.fValue[j] + blendWeight * (customValues[j] - var.fValue[j]); - } - } - } - - switch (var.type) - { - case TYPE_FLOAT: - { - var.fValue[0] = clamp_tpl(var.fValue[0], var.fValue[1], var.fValue[2]); - if (fabs(var.fValue[0]) < 1e-10f) - { - var.fValue[0] = 0.0f; - } - break; - } - case TYPE_COLOR: - { - var.fValue[0] = clamp_tpl(var.fValue[0], 0.0f, 1.0f); - var.fValue[1] = clamp_tpl(var.fValue[1], 0.0f, 1.0f); - var.fValue[2] = clamp_tpl(var.fValue[2], 0.0f, 1.0f); - break; - } - default: - { - AZ_Error("TimeOfDay", false, "Invalid TimeOfDay object during CTimeOfDay::Update!"); - } - } - } - } - - if (m_pUpdateCallback) - { - m_pUpdateCallback->EndUpdate(); - } - } - - // update environment lighting according to new interpolated values - if (bEnvUpdate) - { - UpdateEnvLighting(bForceUpdate); - } -} - - -Vec3 ConvertIlluminanceToLightColor(float illuminance, Vec3 colorRGB) -{ - illuminance /= RENDERER_LIGHT_UNIT_SCALE; - - ColorF color(colorRGB); - color.adjust_luminance(illuminance); - - // Divide by PI as this is not done in the BRDF at the moment - Vec3 finalColor = color.toVec3() / gf_PI; - - return finalColor; -} -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::UpdateEnvLighting(bool forceUpdate) -{ - C3DEngine* p3DEngine((C3DEngine*)gEnv->p3DEngine); - IRenderer* pRenderer(gEnv->pRenderer); - IPostEffectGroup* postEffectGroup = p3DEngine->GetPostEffectBaseGroup(); - const float fRecip255 = 1.0f / 255.0f; - - bool bHDRModeEnabled = false; - pRenderer->EF_Query(EFQ_HDRModeEnabled, bHDRModeEnabled); - if (bHDRModeEnabled) - { - const Vec3 vEyeAdaptationParams(GetVar(PARAM_HDR_EYEADAPTATION_EV_MIN).fValue[ 0 ], - GetVar(PARAM_HDR_EYEADAPTATION_EV_MAX).fValue[ 0 ], - GetVar(PARAM_HDR_EYEADAPTATION_EV_AUTO_COMPENSATION).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_EYEADAPTATION_PARAMS, vEyeAdaptationParams); - - const Vec3 vEyeAdaptationParamsLegacy(GetVar(PARAM_HDR_EYEADAPTATION_SCENEKEY).fValue[ 0 ], - GetVar(PARAM_HDR_EYEADAPTATION_MIN_EXPOSURE).fValue[ 0 ], - GetVar(PARAM_HDR_EYEADAPTATION_MAX_EXPOSURE).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_EYEADAPTATION_PARAMS_LEGACY, vEyeAdaptationParamsLegacy); - - float fHDRShoulderScale(GetVar(PARAM_HDR_FILMCURVE_SHOULDER_SCALE).fValue[ 0 ]); - float fHDRMidtonesScale(GetVar(PARAM_HDR_FILMCURVE_LINEAR_SCALE).fValue[ 0 ]); - float fHDRToeScale(GetVar(PARAM_HDR_FILMCURVE_TOE_SCALE).fValue[ 0 ]); - float fHDRWhitePoint(GetVar(PARAM_HDR_FILMCURVE_WHITEPOINT).fValue[ 0 ]); - - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_FILMCURVE_SHOULDER_SCALE, Vec3(fHDRShoulderScale, 0, 0)); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_FILMCURVE_LINEAR_SCALE, Vec3(fHDRMidtonesScale, 0, 0)); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_FILMCURVE_TOE_SCALE, Vec3(fHDRToeScale, 0, 0)); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_FILMCURVE_WHITEPOINT, Vec3(fHDRWhitePoint, 0, 0)); - - float fHDRBloomAmount(GetVar(PARAM_HDR_BLOOM_AMOUNT).fValue[ 0 ]); - postEffectGroup->SetParam("Global_User_HDRBloom", fHDRBloomAmount); - - float fHDRSaturation(GetVar(PARAM_HDR_COLORGRADING_COLOR_SATURATION).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_COLORGRADING_COLOR_SATURATION, Vec3(fHDRSaturation, 0, 0)); - - Vec3 vColorBalance(GetVar(PARAM_HDR_COLORGRADING_COLOR_BALANCE).fValue[ 0 ], - GetVar(PARAM_HDR_COLORGRADING_COLOR_BALANCE).fValue[ 1 ], - GetVar(PARAM_HDR_COLORGRADING_COLOR_BALANCE).fValue[ 2 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_HDR_COLORGRADING_COLOR_BALANCE, vColorBalance); - } - - pRenderer->SetShadowJittering(GetVar(PARAM_SHADOW_JITTERING).fValue[ 0 ]); - - float sunMultiplier(1.0f); - float sunSpecMultiplier(GetVar(PARAM_SUN_SPECULAR_MULTIPLIER).fValue[ 0 ]); - float fogMultiplier(GetVar(PARAM_FOG_COLOR_MULTIPLIER).fValue[ 0 ]); - float fogMultiplier2(GetVar(PARAM_FOG_COLOR2_MULTIPLIER).fValue[ 0 ]); - float fogMultiplierRadial(GetVar(PARAM_FOG_RADIAL_COLOR_MULTIPLIER).fValue[ 0 ]); - float nightSkyHorizonMultiplier(GetVar(PARAM_NIGHSKY_HORIZON_COLOR_MULTIPLIER).fValue[ 0 ]); - float nightSkyZenithMultiplier(GetVar(PARAM_NIGHSKY_ZENITH_COLOR_MULTIPLIER).fValue[ 0 ]); - float nightSkyMoonMultiplier(GetVar(PARAM_NIGHSKY_MOON_COLOR_MULTIPLIER).fValue[ 0 ]); - float nightSkyMoonInnerCoronaMultiplier(GetVar(PARAM_NIGHSKY_MOON_INNERCORONA_COLOR_MULTIPLIER).fValue[ 0 ]); - float nightSkyMoonOuterCoronaMultiplier(GetVar(PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR_MULTIPLIER).fValue[ 0 ]); - - // set sun position - Vec3 sunPos; - - - if (m_bSunLinkedToTOD) - { - float timeAng(((m_fTime + 12.0f) / s_maxTime) * gf_PI * 2.0f); - float sunRot = gf_PI * (-m_sunRotationLatitude) / 180.0f; - float longitude = 0.5f * gf_PI - gf_PI * m_sunRotationLongitude / 180.0f; - - Matrix33 a, b, c, m; - - a.SetRotationZ(timeAng); - b.SetRotationX(longitude); - c.SetRotationY(sunRot); - - m = a * b * c; - sunPos = Vec3(0, 1, 0) * m; - - float h = sunPos.z; - sunPos.z = sunPos.y; - sunPos.y = -h; - } - else // when not linked, it behaves like the moon - { - float sunLati(-gf_PI + gf_PI* m_sunRotationLatitude / 180.0f); - float sunLong(0.5f * gf_PI - gf_PI* m_sunRotationLongitude / 180.0f); - - float sinLon(sinf(sunLong)); - float cosLon(cosf(sunLong)); - float sinLat(sinf(sunLati)); - float cosLat(cosf(sunLati)); - - sunPos = Vec3(sinLon * cosLat, sinLon * sinLat, cosLon); - } - - - Vec3 sunPosOrig = sunPos; - - // transition phase for sun/moon lighting - AZ_Assert(p3DEngine->m_dawnStart <= p3DEngine->m_dawnEnd, "Invalid sun/moon transition parameters in CTimeOfDay::UpdateEnvLighting!"); - AZ_Assert(p3DEngine->m_duskStart <= p3DEngine->m_duskEnd, "Invalid sun/moon transition parameters in CTimeOfDay::UpdateEnvLighting!"); - AZ_Assert(p3DEngine->m_dawnEnd <= p3DEngine->m_duskStart, "Invalid sun/moon transition parameters in CTimeOfDay::UpdateEnvLighting!"); - float sunIntensityMultiplier(1.0f); - - // The ratio between night and day for adjusting luminance. Day = 1, Night = 0, transitions = [0..1] - float dayNightIndicator(1.0); - // The ratio [0..1] relative to high noon which represents maximum luminance. - float midDayIndicator(1.0); - - if (m_fTime < p3DEngine->m_dawnStart || m_fTime >= p3DEngine->m_duskEnd) - { // Night time - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_DIRECTION, sunPos); - sunIntensityMultiplier = 0.0f; - midDayIndicator = 0.0f; - dayNightIndicator = 0.0f; - } - else - { // Dawn, day and dusk time - - // Calculating the energy multiplier where mid-day sun is 1.0 and night is 0 - const float noonTime = 12.0f; - - if (m_fTime <= noonTime) - { - float dawnToNoon = noonTime - p3DEngine->m_dawnStart; - midDayIndicator = (m_fTime - p3DEngine->m_dawnStart) / dawnToNoon; - } - else - { - float noonToDusk = p3DEngine->m_duskEnd - noonTime; - midDayIndicator = (m_fTime - noonTime) / noonToDusk; - } - midDayIndicator = cos( 0.5f * midDayIndicator * 3.14159265f ); // Converting to the cosine to represent energy distribution - - // Calculation of sun intensity and day-to-night indicator - if (m_fTime < p3DEngine->m_dawnEnd) - { - // dawn - AZ_Assert(p3DEngine->m_dawnStart < p3DEngine->m_dawnEnd, "Invalid sun/moon transition parameters in CTimeOfDay::UpdateEnvLighting!"); - float b(0.5f * (p3DEngine->m_dawnStart + p3DEngine->m_dawnEnd)); - if (m_fTime < b) - { - // fade out moon - sunMultiplier *= (b - m_fTime) / (b - p3DEngine->m_dawnStart); - sunIntensityMultiplier = 0.0f; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_DIRECTION, sunPos); - } - else - { - // fade in sun - float t((m_fTime - b) / (p3DEngine->m_dawnEnd - b)); - sunMultiplier *= t; - sunIntensityMultiplier = t; - } - dayNightIndicator = (m_fTime - p3DEngine->m_dawnStart) / (p3DEngine->m_dawnEnd - p3DEngine->m_dawnStart); - } - else if (m_fTime < p3DEngine->m_duskStart) - { - // day - dayNightIndicator = 1.0; - } - else if (m_fTime < p3DEngine->m_duskEnd) - { - // dusk - AZ_Assert(p3DEngine->m_duskStart < p3DEngine->m_duskEnd, "Invalid sun/moon transition parameters in CTimeOfDay::UpdateEnvLighting!"); - float b(0.5f * (p3DEngine->m_duskStart + p3DEngine->m_duskEnd)); - if (m_fTime < b) - { - // fade out sun - float t((b - m_fTime) / (b - p3DEngine->m_duskStart)); - sunMultiplier *= t; - sunIntensityMultiplier = t; - } - else - { - // fade in moon - sunMultiplier *= (m_fTime - b) / (p3DEngine->m_duskEnd - b); - sunIntensityMultiplier = 0.0; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_DIRECTION, sunPos); - } - - dayNightIndicator = (p3DEngine->m_duskEnd - m_fTime) / (p3DEngine->m_duskEnd - p3DEngine->m_duskStart); - } - } - - sunIntensityMultiplier = max(GetVar(PARAM_SKYLIGHT_SUN_INTENSITY_MULTIPLIER).fValue[0], 0.0f); - p3DEngine->SetGlobalParameter(E3DPARAM_DAY_NIGHT_INDICATOR, Vec3(dayNightIndicator, midDayIndicator, 0)); - - p3DEngine->SetSunDir(sunPos); - - // set sun, sky, and fog color - Vec3 sunColor(Vec3(GetVar(PARAM_SUN_COLOR).fValue[ 0 ], - GetVar(PARAM_SUN_COLOR).fValue[ 1 ], GetVar(PARAM_SUN_COLOR).fValue[ 2 ])); - float sunIntensityLux(GetVar(PARAM_SUN_INTENSITY).fValue[ 0 ] * sunMultiplier); - p3DEngine->SetSunColor(ConvertIlluminanceToLightColor(sunIntensityLux, sunColor)); - - p3DEngine->SetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER, Vec3(sunSpecMultiplier, 0, 0)); - - Vec3 fogColor(fogMultiplier* Vec3(GetVar(PARAM_FOG_COLOR).fValue[ 0 ], - GetVar(PARAM_FOG_COLOR).fValue[ 1 ], GetVar(PARAM_FOG_COLOR).fValue[ 2 ])); - p3DEngine->SetFogColor(fogColor); - - const Vec3 fogColor2 = fogMultiplier2 * Vec3(GetVar(PARAM_FOG_COLOR2).fValue[0], GetVar(PARAM_FOG_COLOR2).fValue[1], GetVar(PARAM_FOG_COLOR2).fValue[2]); - p3DEngine->SetGlobalParameter(E3DPARAM_FOG_COLOR2, fogColor2); - - const Vec3 fogColorRadial = fogMultiplierRadial * Vec3(GetVar(PARAM_FOG_RADIAL_COLOR).fValue[0], GetVar(PARAM_FOG_RADIAL_COLOR).fValue[1], GetVar(PARAM_FOG_RADIAL_COLOR).fValue[2]); - p3DEngine->SetGlobalParameter(E3DPARAM_FOG_RADIAL_COLOR, fogColorRadial); - - const Vec3 volFogHeightDensity = Vec3(GetVar(PARAM_VOLFOG_HEIGHT).fValue[0], GetVar(PARAM_VOLFOG_DENSITY).fValue[0], 0); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY, volFogHeightDensity); - - const Vec3 volFogHeightDensity2 = Vec3(GetVar(PARAM_VOLFOG_HEIGHT2).fValue[0], GetVar(PARAM_VOLFOG_DENSITY2).fValue[0], 0); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY2, volFogHeightDensity2); - - const Vec3 volFogGradientCtrl = Vec3(GetVar(PARAM_VOLFOG_HEIGHT_OFFSET).fValue[0], GetVar(PARAM_VOLFOG_RADIAL_SIZE).fValue[0], GetVar(PARAM_VOLFOG_RADIAL_LOBE).fValue[0]); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_GRADIENT_CTRL, volFogGradientCtrl); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_GLOBAL_DENSITY, Vec3(GetVar(PARAM_VOLFOG_GLOBAL_DENSITY).fValue[0], 0, GetVar(PARAM_VOLFOG_FINAL_DENSITY_CLAMP).fValue[0])); - - // set volumetric fog ramp - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_RAMP, Vec3(GetVar(PARAM_VOLFOG_RAMP_START).fValue[0], GetVar(PARAM_VOLFOG_RAMP_END).fValue[0], GetVar(PARAM_VOLFOG_RAMP_INFLUENCE).fValue[0])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_RANGE, Vec3(GetVar(PARAM_VOLFOG_SHADOW_RANGE).fValue[0], 0, 0)); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_DARKENING, Vec3(GetVar(PARAM_VOLFOG_SHADOW_DARKENING).fValue[0], GetVar(PARAM_VOLFOG_SHADOW_DARKENING_SUN).fValue[0], GetVar(PARAM_VOLFOG_SHADOW_DARKENING_AMBIENT).fValue[0])); - - // set HDR sky lighting properties - Vec3 sunIntensity(sunIntensityMultiplier* Vec3(GetVar(PARAM_SKYLIGHT_SUN_INTENSITY).fValue[ 0 ], - GetVar(PARAM_SKYLIGHT_SUN_INTENSITY).fValue[ 1 ], GetVar(PARAM_SKYLIGHT_SUN_INTENSITY).fValue[ 2 ])); - - Vec3 rgbWaveLengths(GetVar(PARAM_SKYLIGHT_WAVELENGTH_R).fValue[ 0 ], - GetVar(PARAM_SKYLIGHT_WAVELENGTH_G).fValue[ 0 ], GetVar(PARAM_SKYLIGHT_WAVELENGTH_B).fValue[ 0 ]); - - p3DEngine->SetSkyLightParameters(sunPosOrig, sunIntensity, GetVar(PARAM_SKYLIGHT_KM).fValue[ 0 ], - GetVar(PARAM_SKYLIGHT_KR).fValue[ 0 ], GetVar(PARAM_SKYLIGHT_G).fValue[ 0 ], rgbWaveLengths, forceUpdate); - - // set night sky color properties - Vec3 nightSkyHorizonColor(nightSkyHorizonMultiplier* Vec3(GetVar(PARAM_NIGHSKY_HORIZON_COLOR).fValue[ 0 ], - GetVar(PARAM_NIGHSKY_HORIZON_COLOR).fValue[ 1 ], GetVar(PARAM_NIGHSKY_HORIZON_COLOR).fValue[ 2 ])); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_HORIZON_COLOR, nightSkyHorizonColor); - - Vec3 nightSkyZenithColor(nightSkyZenithMultiplier* Vec3(GetVar(PARAM_NIGHSKY_ZENITH_COLOR).fValue[ 0 ], - GetVar(PARAM_NIGHSKY_ZENITH_COLOR).fValue[ 1 ], GetVar(PARAM_NIGHSKY_ZENITH_COLOR).fValue[ 2 ])); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_ZENITH_COLOR, nightSkyZenithColor); - - float nightSkyZenithColorShift(GetVar(PARAM_NIGHSKY_ZENITH_SHIFT).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_ZENITH_SHIFT, Vec3(nightSkyZenithColorShift, 0, 0)); - - float nightSkyStarIntensity(GetVar(PARAM_NIGHSKY_START_INTENSITY).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_STAR_INTENSITY, Vec3(nightSkyStarIntensity, 0, 0)); - - Vec3 nightSkyMoonColor(nightSkyMoonMultiplier* Vec3(GetVar(PARAM_NIGHSKY_MOON_COLOR).fValue[ 0 ], - GetVar(PARAM_NIGHSKY_MOON_COLOR).fValue[ 1 ], GetVar(PARAM_NIGHSKY_MOON_COLOR).fValue[ 2 ])); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_MOON_COLOR, nightSkyMoonColor); - - Vec3 nightSkyMoonInnerCoronaColor(nightSkyMoonInnerCoronaMultiplier* Vec3(GetVar(PARAM_NIGHSKY_MOON_INNERCORONA_COLOR).fValue[ 0 ], - GetVar(PARAM_NIGHSKY_MOON_INNERCORONA_COLOR).fValue[ 1 ], GetVar(PARAM_NIGHSKY_MOON_INNERCORONA_COLOR).fValue[ 2 ])); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_MOON_INNERCORONA_COLOR, nightSkyMoonInnerCoronaColor); - - float nightSkyMoonInnerCoronaScale(GetVar(PARAM_NIGHSKY_MOON_INNERCORONA_SCALE).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_MOON_INNERCORONA_SCALE, Vec3(nightSkyMoonInnerCoronaScale, 0, 0)); - - Vec3 nightSkyMoonOuterCoronaColor(nightSkyMoonOuterCoronaMultiplier* Vec3(GetVar(PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR).fValue[ 0 ], - GetVar(PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR).fValue[ 1 ], GetVar(PARAM_NIGHSKY_MOON_OUTERCORONA_COLOR).fValue[ 2 ])); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_MOON_OUTERCORONA_COLOR, nightSkyMoonOuterCoronaColor); - - float nightSkyMoonOuterCoronaScale(GetVar(PARAM_NIGHSKY_MOON_OUTERCORONA_SCALE).fValue[ 0 ]); - p3DEngine->SetGlobalParameter(E3DPARAM_NIGHSKY_MOON_OUTERCORONA_SCALE, Vec3(nightSkyMoonOuterCoronaScale, 0, 0)); - - // set sun shafts visibility and activate if required - - float fSunShaftsVis = GetVar(PARAM_SUN_SHAFTS_VISIBILITY).fValue[ 0 ]; - fSunShaftsVis = clamp_tpl(fSunShaftsVis, 0.0f, 0.3f); - float fSunRaysVis = GetVar(PARAM_SUN_RAYS_VISIBILITY).fValue[ 0 ]; - float fSunRaysAtten = GetVar(PARAM_SUN_RAYS_ATTENUATION).fValue[ 0 ]; - float fSunRaySunColInfluence = GetVar(PARAM_SUN_RAYS_SUNCOLORINFLUENCE).fValue[ 0 ]; - - float* pSunRaysCustomColorVar = GetVar(PARAM_SUN_RAYS_CUSTOMCOLOR).fValue; - Vec4 pSunRaysCustomColor = Vec4(pSunRaysCustomColorVar[0], pSunRaysCustomColorVar[1], pSunRaysCustomColorVar[2], 1.0f); - - postEffectGroup->SetParam("SunShafts_Active", (fSunShaftsVis > 0.05f || fSunRaysVis > 0.05f) ? 1.f : 0.f); - postEffectGroup->SetParam("SunShafts_Amount", fSunShaftsVis); - postEffectGroup->SetParam("SunShafts_RaysAmount", fSunRaysVis); - postEffectGroup->SetParam("SunShafts_RaysAttenuation", fSunRaysAtten); - postEffectGroup->SetParam("SunShafts_RaysSunColInfluence", fSunRaySunColInfluence); - postEffectGroup->SetParam("SunShafts_RaysCustomColor", pSunRaysCustomColor); - - { - const Vec3 cloudShadingMultipliers = Vec3(GetVar(PARAM_CLOUDSHADING_SUNLIGHT_MULTIPLIER).fValue[0], 0, 0); - p3DEngine->SetGlobalParameter(E3DPARAM_CLOUDSHADING_MULTIPLIERS, cloudShadingMultipliers); - - const float cloudShadingCustomSunColorMult = GetVar(PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR_MULTIPLIER).fValue[0]; - const Vec3 cloudShadingCustomSunColor = cloudShadingCustomSunColorMult * Vec3(GetVar(PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR).fValue[0], GetVar(PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR).fValue[1], GetVar(PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR).fValue[2]); - const float cloudShadingCustomSunColorInfluence = GetVar(PARAM_CLOUDSHADING_SUNLIGHT_CUSTOM_COLOR_INFLUENCE).fValue[0]; - - IObjManager* pObjMan = p3DEngine->GetObjectManager(); - const Vec3 cloudShadingSunColor = pObjMan ? cloudShadingMultipliers.x* pObjMan->GetSunColor() : Vec3(0, 0, 0); - - p3DEngine->SetGlobalParameter(E3DPARAM_CLOUDSHADING_SUNCOLOR, cloudShadingSunColor + (cloudShadingCustomSunColor - cloudShadingSunColor) * cloudShadingCustomSunColorInfluence); - } - - bool bHasOceanFeature = false; - AZ::OceanFeatureToggleBus::BroadcastResult(bHasOceanFeature, &AZ::OceanFeatureToggleBus::Events::OceanComponentEnabled); - if (!bHasOceanFeature) - { - // set ocean fog color multiplier - const float oceanFogColorMultiplier = GetVar(PARAM_OCEANFOG_COLOR_MULTIPLIER).fValue[0]; - const Vec3 oceanFogColor = Vec3(GetVar(PARAM_OCEANFOG_COLOR).fValue[0], GetVar(PARAM_OCEANFOG_COLOR).fValue[1], GetVar(PARAM_OCEANFOG_COLOR).fValue[2]); - p3DEngine->SetGlobalParameter(E3DPARAM_OCEANFOG_COLOR, oceanFogColor * oceanFogColorMultiplier); - - // legacy style: set ocean color density - const float oceanFogColorDensity = GetVar(PARAM_OCEANFOG_DENSITY).fValue[0]; - p3DEngine->SetGlobalParameter(E3DPARAM_OCEANFOG_DENSITY, Vec3(oceanFogColorDensity, 0, 0)); - } - - // set skybox multiplier - float skyBoxMultiplier(GetVar(PARAM_SKYBOX_MULTIPLIER).fValue[ 0 ] * m_fHDRMultiplier); - p3DEngine->SetGlobalParameter(E3DPARAM_SKYBOX_MULTIPLIER, Vec3(skyBoxMultiplier, 0, 0)); - - // Set color grading stuff - float fValue = GetVar(PARAM_COLORGRADING_FILTERS_GRAIN).fValue[ 0 ]; - p3DEngine->SetGlobalParameter(E3DPARAM_COLORGRADING_FILTERS_GRAIN, Vec3(fValue, 0, 0)); - - Vec4 pColor = Vec4(GetVar(PARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR).fValue[ 0 ], - GetVar(PARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR).fValue[ 1 ], - GetVar(PARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR).fValue[ 2 ], 1.0f); - p3DEngine->SetGlobalParameter(E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_COLOR, Vec3(pColor.x, pColor.y, pColor.z)); - fValue = GetVar(PARAM_COLORGRADING_FILTERS_PHOTOFILTER_DENSITY).fValue[ 0 ]; - p3DEngine->SetGlobalParameter(E3DPARAM_COLORGRADING_FILTERS_PHOTOFILTER_DENSITY, Vec3(fValue, 0, 0)); - - fValue = GetVar(PARAM_COLORGRADING_DOF_FOCUSRANGE).fValue[ 0 ]; - postEffectGroup->SetParam("Dof_Tod_FocusRange", fValue); - - fValue = GetVar(PARAM_COLORGRADING_DOF_BLURAMOUNT).fValue[ 0 ]; - postEffectGroup->SetParam("Dof_Tod_BlurAmount", fValue); - - const float arrDepthConstBias[MAX_SHADOW_CASCADES_NUM] = - { - GetVar(PARAM_SHADOWSC0_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC1_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC2_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC3_BIAS).fValue[ 0 ], - GetVar(PARAM_SHADOWSC4_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC5_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC6_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC7_BIAS).fValue[ 0 ], - 2.0f, 2.0f, 2.0f, 2.0f, - 2.0f, 2.0f, 2.0f, 2.0f, - 2.0f, 2.0f, 2.0f, 2.0f - }; - - const float arrDepthSlopeBias[MAX_SHADOW_CASCADES_NUM] = - { - GetVar(PARAM_SHADOWSC0_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC1_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC2_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC3_SLOPE_BIAS).fValue[ 0 ], - GetVar(PARAM_SHADOWSC4_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC5_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC6_SLOPE_BIAS).fValue[ 0 ], GetVar(PARAM_SHADOWSC7_SLOPE_BIAS).fValue[ 0 ], - 0.5f, 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, 0.5f - }; - - p3DEngine->SetShadowsCascadesBias(arrDepthConstBias, arrDepthSlopeBias); - - if (gEnv->IsEditing()) - { - p3DEngine->SetRecomputeCachedShadows(); - } - - // set volumetric fog 2 params - const Vec3 volFogCtrlParams = Vec3(GetVar(PARAM_VOLFOG2_RANGE).fValue[0], GetVar(PARAM_VOLFOG2_BLEND_FACTOR).fValue[0], GetVar(PARAM_VOLFOG2_BLEND_MODE).fValue[0]); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - - const Vec3 volFogScatteringParams = Vec3(GetVar(PARAM_VOLFOG2_INSCATTER).fValue[0], GetVar(PARAM_VOLFOG2_EXTINCTION).fValue[0], GetVar(PARAM_VOLFOG2_ANISOTROPIC).fValue[0]); - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_SCATTERING_PARAMS, volFogScatteringParams); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_RAMP, Vec3(GetVar(PARAM_VOLFOG2_RAMP_START).fValue[0], GetVar(PARAM_VOLFOG2_RAMP_END).fValue[0], 0.0f)); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_COLOR, Vec3(GetVar(PARAM_VOLFOG2_COLOR).fValue[0], GetVar(PARAM_VOLFOG2_COLOR).fValue[1], GetVar(PARAM_VOLFOG2_COLOR).fValue[2])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_GLOBAL_DENSITY, Vec3(GetVar(PARAM_VOLFOG2_GLOBAL_DENSITY).fValue[0], GetVar(PARAM_VOLFOG2_FINAL_DENSITY_CLAMP).fValue[0], GetVar(PARAM_VOLFOG2_GLOBAL_FOG_VISIBILITY).fValue[0])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY, Vec3(GetVar(PARAM_VOLFOG2_HEIGHT).fValue[0], GetVar(PARAM_VOLFOG2_DENSITY).fValue[0], GetVar(PARAM_VOLFOG2_ANISOTROPIC1).fValue[0])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY2, Vec3(GetVar(PARAM_VOLFOG2_HEIGHT2).fValue[0], GetVar(PARAM_VOLFOG2_DENSITY2).fValue[0], GetVar(PARAM_VOLFOG2_ANISOTROPIC2).fValue[0])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_COLOR1, Vec3(GetVar(PARAM_VOLFOG2_COLOR1).fValue[0], GetVar(PARAM_VOLFOG2_COLOR1).fValue[1], GetVar(PARAM_VOLFOG2_COLOR1).fValue[2])); - - p3DEngine->SetGlobalParameter(E3DPARAM_VOLFOG2_COLOR2, Vec3(GetVar(PARAM_VOLFOG2_COLOR2).fValue[0], GetVar(PARAM_VOLFOG2_COLOR2).fValue[1], GetVar(PARAM_VOLFOG2_COLOR2).fValue[2])); -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::SetAdvancedInfo(const SAdvancedInfo& advInfo) -{ - m_advancedInfo = advInfo; - if (m_pTimeOfDaySpeedCVar->GetFVal() != m_advancedInfo.fAnimSpeed) - { - m_pTimeOfDaySpeedCVar->Set(m_advancedInfo.fAnimSpeed); - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::GetAdvancedInfo(SAdvancedInfo& advInfo) -{ - advInfo = m_advancedInfo; -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::MigrateLegacyData(bool bSunIntensity, const XmlNodeRef& node) -{ - if (bSunIntensity) // Convert sun intensity as specified up to CE 3.8.2 to illuminance - { - SVariableInfo& varSunIntensity = GetVar(PARAM_SUN_INTENSITY); - SVariableInfo& varSunMult = GetVar(PARAM_SUN_COLOR_MULTIPLIER); - SVariableInfo& varSunColor = GetVar(PARAM_SUN_COLOR); - SVariableInfo& varHDRPower = GetVar(PARAM_HDR_DYNAMIC_POWER_FACTOR); - - int numKeys = varSunMult.pInterpolator->GetKeyCount(); - for (int key = 0; key < numKeys; ++key) - { - float time = varSunMult.pInterpolator->GetKeyTime(key); - - float sunMult, sunColor[3], hdrPower; - varSunMult.pInterpolator->GetKeyValueFloat(key, sunMult); - varSunColor.pInterpolator->InterpolateFloat3(time, sunColor); - varHDRPower.pInterpolator->InterpolateFloat(time, hdrPower); - - const float HDRDynamicMultiplier = 2.0f; - float sunColorLum = sunColor[0] * 0.2126f + sunColor[1] * 0.7152f + sunColor[2] * 0.0722f; - float sunIntensity = sunMult * sunColorLum * 10000.0f * gf_PI; - - varSunIntensity.pInterpolator->InsertKeyFloat(time, sunIntensity); - } - } - - // copy data from old node to new node if old nodes exist. - // this needs to maintain compatibility from CE 3.8.2 to above. - // this should be removed in the future. - string paramOldNameFogAlbedoColor = "Volumetric fog 2: Fog albedo color"; - string paramOldNameAnisotropic = "Volumetric fog 2: Anisotropic factor"; - for (int i = 0; i < node->getChildCount(); i++) - { - XmlNodeRef varNode = node->getChild(i); - const char* name = varNode->getAttr("Name"); - if (paramOldNameFogAlbedoColor.compare(name) == 0) - { - LoadValueFromXmlNode(PARAM_VOLFOG2_COLOR1, varNode); - LoadValueFromXmlNode(PARAM_VOLFOG2_COLOR2, varNode); - LoadValueFromXmlNode(PARAM_VOLFOG2_COLOR, varNode); - } - else if (paramOldNameAnisotropic.compare(name) == 0) - { - LoadValueFromXmlNode(PARAM_VOLFOG2_ANISOTROPIC1, varNode); - LoadValueFromXmlNode(PARAM_VOLFOG2_ANISOTROPIC, varNode); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::LoadValueFromXmlNode(ETimeOfDayParamID destId, const XmlNodeRef& varNode) -{ - if (destId < 0 || destId >= PARAM_TOTAL) - { - return; - } - - XmlNodeRef splineNode = varNode->findChild("Spline"); - SVariableInfo& var = GetVar(destId); - switch (var.type) - { - case TYPE_FLOAT: - varNode->getAttr("Value", var.fValue[0]); - if (var.pInterpolator && splineNode != 0) - { - ((CBezierSplineFloat*)var.pInterpolator)->SerializeSpline(splineNode, true); - } - break; - case TYPE_COLOR: - { - Vec3 v(var.fValue[0], var.fValue[1], var.fValue[2]); - varNode->getAttr("Color", v); - var.fValue[0] = v.x; - var.fValue[1] = v.y; - var.fValue[2] = v.z; - - if (var.pInterpolator && splineNode != 0) - { - CBezierSplineVec3* pBezierSpline = ((CBezierSplineVec3*)var.pInterpolator); - pBezierSpline->SerializeSpline(splineNode, true); - // Clamp colors in case too big colors are provided. - pBezierSpline->ClampValues(-100, 100); - } - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::Serialize(XmlNodeRef& node, bool bLoading) -{ - if (bLoading) - { - node->getAttr("Time", m_fTime); - - node->getAttr("TimeStart", m_advancedInfo.fStartTime); - node->getAttr("TimeEnd", m_advancedInfo.fEndTime); - node->getAttr("TimeAnimSpeed", m_advancedInfo.fAnimSpeed); - - if (m_pTimeOfDaySpeedCVar->GetFVal() != m_advancedInfo.fAnimSpeed) - { - m_pTimeOfDaySpeedCVar->Set(m_advancedInfo.fAnimSpeed); - } - - bool bSunIntensityFound = false; - - // Load. - for (int i = 0; i < node->getChildCount(); i++) - { - XmlNodeRef varNode = node->getChild(i); - int nParamId = stl::find_in_map(m_varsMap, varNode->getAttr("Name"), -1); - if (nParamId < 0 || nParamId >= PARAM_TOTAL) - { - continue; - } - - if (nParamId == PARAM_SUN_INTENSITY) - { - bSunIntensityFound = true; - } - - LoadValueFromXmlNode((ETimeOfDayParamID)nParamId, varNode); - } - MigrateLegacyData(!bSunIntensityFound, node); - SetTime(m_fTime, false); - } - else - { - node->setAttr("Time", m_fTime); - node->setAttr("TimeStart", m_advancedInfo.fStartTime); - node->setAttr("TimeEnd", m_advancedInfo.fEndTime); - node->setAttr("TimeAnimSpeed", m_advancedInfo.fAnimSpeed); - // Save. - for (uint32 i = 0; i < static_cast(GetVariableCount()); i++) - { - SVariableInfo& var = m_vars[i]; - XmlNodeRef varNode = node->newChild("Variable"); - varNode->setAttr("Name", var.name); - switch (var.type) - { - case TYPE_FLOAT: - varNode->setAttr("Value", var.fValue[0]); - if (var.pInterpolator) - { - XmlNodeRef splineNode = varNode->newChild("Spline"); - ((CBezierSplineFloat*)var.pInterpolator)->SerializeSpline(splineNode, bLoading); - } - break; - case TYPE_COLOR: - varNode->setAttr("Color", Vec3(var.fValue[0], var.fValue[1], var.fValue[2])); - if (var.pInterpolator) - { - XmlNodeRef splineNode = varNode->newChild("Spline"); - ((CBezierSplineVec3*)var.pInterpolator)->SerializeSpline(splineNode, bLoading); - } - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::Serialize(TSerialize ser) -{ - AZ_Assert(ser.GetSerializationTarget() != eST_Network, "Cannot serialize to network error in CTimeOfDay::Serialize"); - - string tempName; - - ser.Value("time", m_fTime); - ser.Value("mode", m_bEditMode); - ser.Value("m_sunRotationLatitude", m_sunRotationLatitude); - ser.Value("m_sunRotationLongitude", m_sunRotationLongitude); - int size = GetVariableCount(); - ser.BeginGroup("VariableValues"); - for (int v = 0; v < size; v++) - { - tempName = m_vars[v].name; - tempName.replace(' ', '_'); - tempName.replace('(', '_'); - tempName.replace(')', '_'); - tempName.replace(':', '_'); - ser.BeginGroup(tempName); - ser.Value("Val0", m_vars[v].fValue[0]); - ser.Value("Val1", m_vars[v].fValue[1]); - ser.Value("Val2", m_vars[v].fValue[2]); - ser.EndGroup(); - } - ser.EndGroup(); - - ser.Value("AdvInfoSpeed", m_advancedInfo.fAnimSpeed); - ser.Value("AdvInfoStart", m_advancedInfo.fStartTime); - ser.Value("AdvInfoEnd", m_advancedInfo.fEndTime); - - if (ser.IsReading()) - { - SetTime(m_fTime, true); - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::NetSerialize(TSerialize ser, float lag, uint32 flags) -{ - if (0 == (flags & NETSER_STATICPROPS)) - { - if (ser.IsWriting()) - { - ser.Value("time", m_fTime, 'tod'); - } - else - { - float serializedTime; - ser.Value("time", serializedTime, 'tod'); - float remoteTime = serializedTime + ((flags & NETSER_COMPENSATELAG) != 0) * m_advancedInfo.fAnimSpeed * lag; - float setTime = remoteTime; - if (0 == (flags & NETSER_FORCESET)) - { - const float adjustmentFactor = 0.05f; - const float wraparoundGuardHours = 2.0f; - - float localTime = m_fTime; - // handle wraparound - if (localTime < wraparoundGuardHours && remoteTime > (s_maxTime - wraparoundGuardHours)) - { - localTime += s_maxTime; - } - else if (remoteTime < wraparoundGuardHours && localTime > (s_maxTime - wraparoundGuardHours)) - { - remoteTime += s_maxTime; - } - // don't blend times if they're very different - if (fabsf(remoteTime - localTime) < 1.0f) - { - setTime = adjustmentFactor * remoteTime + (1.0f - adjustmentFactor) * m_fTime; - if (setTime > s_maxTime) - { - setTime -= s_maxTime; - } - } - } - SetTime(setTime, (flags & NETSER_FORCESET) != 0); - } - } - else - { - // no static serialization (yet) - } -} - -////////////////////////////////////////////////////////////////////////// -void CTimeOfDay::Tick() -{ - AZ_TRACE_METHOD(); - // if(!gEnv->bServer) - // return; - if (!m_bEditMode && !m_bPaused) - { - if (fabs(m_advancedInfo.fAnimSpeed) > 0.0001f) - { - // advance (forward or backward) - float fTime = m_fTime + m_advancedInfo.fAnimSpeed * m_pTimer->GetFrameTime(); - - // full cycle mode - if (m_advancedInfo.fStartTime <= 0.05f && m_advancedInfo.fEndTime >= 23.5f) - { - if (fTime > m_advancedInfo.fEndTime) - { - fTime = m_advancedInfo.fStartTime; - } - if (fTime < m_advancedInfo.fStartTime) - { - fTime = m_advancedInfo.fEndTime; - } - } - else if (fabs(m_advancedInfo.fStartTime - m_advancedInfo.fEndTime) <= 0.05f)//full cycle mode - { - if (fTime > s_maxTime) - { - fTime -= s_maxTime; - } - else if (fTime < 0.0f) - { - fTime += s_maxTime; - } - } - else - { - // clamp advancing time - if (fTime > m_advancedInfo.fEndTime) - { - fTime = m_advancedInfo.fEndTime; - } - if (fTime < m_advancedInfo.fStartTime) - { - fTime = m_advancedInfo.fStartTime; - } - } - - SetTime(fTime); - } - } -} - -void CTimeOfDay::SetUpdateCallback(ITimeOfDayUpdateCallback* pCallback) -{ - m_pUpdateCallback = pCallback; -} - -void CTimeOfDay::LerpWith(const ITimeOfDay& other, float lerpValue, ITimeOfDay& output) const -{ - AZ_Assert(GetVariableCount() == other.GetVariableCount() && GetVariableCount() == output.GetVariableCount(), "Attempting to lerp mismatching TimeOfDay objects!"); - CTimeOfDay& todOutput = static_cast(output); - const CTimeOfDay& todOther = static_cast(other); - - for (uint32 i = 0; i < static_cast(GetVariableCount()); i++) - { - SVariableInfo& outvar = todOutput.m_vars[i]; - const SVariableInfo& var0 = m_vars[i]; - const SVariableInfo& var1 = todOther.m_vars[i]; - if (outvar.nParamId == var0.nParamId && outvar.nParamId == var1.nParamId) - { - switch (outvar.type) - { - case TYPE_FLOAT: - { - outvar.fValue[0] = Lerp(var0.fValue[0], var1.fValue[0], lerpValue); - break; - } - case TYPE_COLOR: - { - outvar.fValue[0] = Lerp(var0.fValue[0], var1.fValue[0], lerpValue); - outvar.fValue[1] = Lerp(var0.fValue[1], var1.fValue[1], lerpValue); - outvar.fValue[2] = Lerp(var0.fValue[2], var1.fValue[2], lerpValue); - break; - } - default: - { - AZ_Error("TimeOfDay", false, "Attempting to lerp mismatching TimeOfDay objects!"); - } - } - } - else - { - CryWarning(EValidatorModule::VALIDATOR_MODULE_3DENGINE, EValidatorSeverity::VALIDATOR_WARNING, "Lerping mismatched time of day settings!"); - } - } -} - -void CTimeOfDay::BeginEditMode() -{ - m_bEditMode = true; - SetTime(m_fEditorTime); -} - -void CTimeOfDay::EndEditMode() -{ - m_bEditMode = false; - m_fEditorTime = m_fTime; -} diff --git a/Code/CryEngine/Cry3DEngine/TimeOfDay.h b/Code/CryEngine/Cry3DEngine/TimeOfDay.h deleted file mode 100644 index 09609592b8..0000000000 --- a/Code/CryEngine/Cry3DEngine/TimeOfDay.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_TIMEOFDAY_H -#define CRYINCLUDE_CRY3DENGINE_TIMEOFDAY_H -#pragma once - -#include - -class CEnvironmentPreset; -////////////////////////////////////////////////////////////////////////// -// ITimeOfDay interface implementation. -////////////////////////////////////////////////////////////////////////// -class CTimeOfDay - : public ITimeOfDay -{ -public: - CTimeOfDay(); - ~CTimeOfDay(); - - ////////////////////////////////////////////////////////////////////////// - // ITimeOfDay - ////////////////////////////////////////////////////////////////////////// - - int GetPresetCount() const override { return m_presets.size(); } - bool GetPresetsInfos([[maybe_unused]] SPresetInfo* resultArray, [[maybe_unused]] unsigned int arraySize) const override { return false; } - bool SetCurrentPreset([[maybe_unused]] const char* szPresetName) override { return false; }; - bool AddNewPreset([[maybe_unused]] const char* szPresetName) override { return false; }; - bool RemovePreset([[maybe_unused]] const char* szPresetName) override { return false; }; - bool SavePreset([[maybe_unused]] const char* szPresetName) const override { return false; }; - bool LoadPreset([[maybe_unused]] const char* szFilePath) override { return false; }; - void ResetPreset([[maybe_unused]] const char* szPresetName) override { }; - - bool ImportPreset([[maybe_unused]] const char* szPresetName, [[maybe_unused]] const char* szFilePath) override { return false; }; - bool ExportPreset([[maybe_unused]] const char* szPresetName, [[maybe_unused]] const char* szFilePath) const override { return false; }; - - int GetVariableCount() const override { return ITimeOfDay::PARAM_TOTAL; }; - bool GetVariableInfo(int nIndex, SVariableInfo &varInfo) const override; - void SetVariableValue(int nIndex, float fValue[3]) override; - - bool InterpolateVarInRange([[maybe_unused]] int nIndex, [[maybe_unused]] float fMin, [[maybe_unused]] float fMax, [[maybe_unused]] unsigned int nCount, [[maybe_unused]] Vec3* resultArray) const override { return false; }; - uint GetSplineKeysCount([[maybe_unused]] int nIndex, [[maybe_unused]] int nSpline) const override { return 0; }; - bool GetSplineKeysForVar([[maybe_unused]] int nIndex, [[maybe_unused]] int nSpline, [[maybe_unused]] SBezierKey* keysArray, [[maybe_unused]] unsigned int keysArraySize) const override { return false; }; - bool SetSplineKeysForVar([[maybe_unused]] int nIndex, [[maybe_unused]] int nSpline, [[maybe_unused]] const SBezierKey* keysArray, [[maybe_unused]] unsigned int keysArraySize) override { return false; }; - bool UpdateSplineKeyForVar([[maybe_unused]] int nIndex, [[maybe_unused]] int nSpline, [[maybe_unused]] float fTime, [[maybe_unused]] float newValue) override { return false; }; - - void ResetVariables() override; - - // Time of day is specified in hours. - void SetTime(float fHour, bool bForceUpdate = false, bool bEnvUpdate = true) override; - void SetSunPos(float longitude, float latitude) override; - float GetSunLatitude() override { return m_sunRotationLatitude; } - float GetSunLongitude() override { return m_sunRotationLongitude; } - float GetTime() override { return m_fTime; }; - - void SetPaused(bool paused) override { m_bPaused = paused; } - - void SetAdvancedInfo(const SAdvancedInfo &advInfo) override; - void GetAdvancedInfo(SAdvancedInfo &advInfo) override; - - float GetHDRMultiplier() const { return m_fHDRMultiplier; } - - void Update(bool bInterpolate = true, bool bForceUpdate = false, bool bForceEnvUpdate = true) override; - void SetUpdateCallback(ITimeOfDayUpdateCallback* pCallback) override; - - void Serialize(XmlNodeRef& node, bool bLoading) override; - void Serialize(TSerialize ser) override; - - void SetTimer(ITimer * pTimer) override; - - void NetSerialize(TSerialize ser, float lag, uint32 flags) override; - - void Tick() override; - - void SetEnvironmentSettings(const SEnvironmentInfo& envInfo) override; - void LerpWith(const ITimeOfDay& other, float lerpValue, ITimeOfDay& output) const override; - - - ////////////////////////////////////////////////////////////////////////// - - void BeginEditMode(); - void EndEditMode(); - -private: - CTimeOfDay(const CTimeOfDay&); - CTimeOfDay(const CTimeOfDay&&); - CTimeOfDay& operator=(const CTimeOfDay&); - CTimeOfDay& operator=(const CTimeOfDay&&); - - SVariableInfo& GetVar(ETimeOfDayParamID id); - void UpdateEnvLighting(bool forceUpdate); - void MigrateLegacyData(bool bSunIntensity, const XmlNodeRef& node); - void LoadValueFromXmlNode(ETimeOfDayParamID destId, const XmlNodeRef& varNode); - -private: - typedef std::map TPresetsSet; - TPresetsSet m_presets; - CEnvironmentPreset* m_pCurrentPreset; - CEnvironmentPreset* m_defaultPreset; - - SVariableInfo m_vars[ITimeOfDay::PARAM_TOTAL]; - std::map > m_varsMap; - float m_fTime; - float m_fEditorTime; - float m_sunRotationLatitude; - float m_sunRotationLongitude; - - bool m_bEditMode; - bool m_bPaused; - bool m_bSunLinkedToTOD; - - SAdvancedInfo m_advancedInfo; - ITimer* m_pTimer; - float m_fHDRMultiplier; - ICVar* m_pTimeOfDaySpeedCVar; - ITimeOfDayUpdateCallback* m_pUpdateCallback; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_TIMEOFDAY_H diff --git a/Code/CryEngine/Cry3DEngine/VMath.hpp b/Code/CryEngine/Cry3DEngine/VMath.hpp deleted file mode 100644 index 513c80f85c..0000000000 --- a/Code/CryEngine/Cry3DEngine/VMath.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : unified vector math lib - -#pragma once - -#define VEC4_SSE -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(VMath_hpp) -#endif - -//#include -#include -#include - -namespace NVMath -{ -#if defined(_CPU_NEON) - #include "VMath_NEON.hpp" -#elif (AZ_LEGACY_3DENGINE_TRAIT_HAS_SSE || defined(IOS_SIMULATOR)) && (defined(VEC4_SSE) || defined(VEC4_SSE4)) - #include "VMath_SSE.hpp" -#else - #include "VMath_C.hpp" -#endif -} diff --git a/Code/CryEngine/Cry3DEngine/VMath_C.hpp b/Code/CryEngine/Cry3DEngine/VMath_C.hpp deleted file mode 100644 index e88c984073..0000000000 --- a/Code/CryEngine/Cry3DEngine/VMath_C.hpp +++ /dev/null @@ -1,379 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : unified vector math lib - - -#ifndef __D_VMATH_C__ -#define __D_VMATH_C__ - -//#include - - -union vec4 -{ - struct - { - float m_Xf; - float m_Yf; - float m_Zf; - float m_Wf; - }; - struct - { - uint32 m_Xu; - uint32 m_Yu; - uint32 m_Zu; - uint32 m_Wu; - }; - struct - { - int32 m_Xs; - int32 m_Ys; - int32 m_Zs; - int32 m_Ws; - }; - float m_f[4]; - int32 m_s[4]; - uint32 m_u[4]; -}; - -#include "VMath_Prototypes.hpp" - -#define SWIZZLEMASK5(X, Y, Z, W) ((X) | (Y << 2) | (Z << 4) | (W << 6)) -#define SWIZZLEMASK4(N, X, Y, Z) N##x = SWIZZLEMASK5(X, Y, Z, 0), \ - N##y = SWIZZLEMASK5(X, Y, Z, 1), \ - N##z = SWIZZLEMASK5(X, Y, Z, 2), \ - N##w = SWIZZLEMASK5(X, Y, Z, 3), -#define SWIZZLEMASK3(N, X, Y) SWIZZLEMASK4(N##x, X, Y, 0) \ - SWIZZLEMASK4(N##y, X, Y, 1) \ - SWIZZLEMASK4(N##z, X, Y, 2) \ - SWIZZLEMASK4(N##w, X, Y, 3) -#define SWIZZLEMASK2(N, X) SWIZZLEMASK3(N##x, X, 0) \ - SWIZZLEMASK3(N##y, X, 1) \ - SWIZZLEMASK3(N##z, X, 2) \ - SWIZZLEMASK3(N##w, X, 3) -#define SWIZZLEMASK1 SWIZZLEMASK2(x, 0) \ - SWIZZLEMASK2(y, 1) \ - SWIZZLEMASK2(z, 2) \ - SWIZZLEMASK2(w, 3) - -enum ESwizzleMask -{ - SWIZZLEMASK1 -}; -enum ECacheLvl -{ - ECL_LVL1, - ECL_LVL2, - ECL_LVL3, -}; -#define BitX 1 -#define BitY 2 -#define BitZ 4 -#define BitW 8 - -ILINE vec4 Vec4(float x, float y, float z, float w) -{ - vec4 Ret; - Ret.m_Xf = x; - Ret.m_Yf = y; - Ret.m_Zf = z; - Ret.m_Wf = w; - return Ret; -} -ILINE vec4 Vec4(uint32 x, uint32 y, uint32 z, uint32 w) -{ - vec4 Ret; - Ret.m_Xu = x; - Ret.m_Yu = y; - Ret.m_Zu = z; - Ret.m_Wu = w; - return Ret; -} -ILINE vec4 Vec4(float x) -{ - return Vec4(x, x, x, x); -} -ILINE float Vec4float(vec4 V, uint32 Idx) -{ - return V.m_f[Idx]; -} -template -ILINE float Vec4float(vec4 V) -{ - return Vec4float(V, Idx); -} -ILINE int32 Vec4int32(vec4 V, uint32 Idx) -{ - return V.m_s[Idx]; -} -template -ILINE int32 Vec4int32(vec4 V) -{ - return Vec4int32(V, Idx); -} -ILINE vec4 Vec4Zero() -{ - return Vec4(0.f); -} - -ILINE vec4 Vec4One() -{ - return Vec4(1.f, 1.f, 1.f, 1.f); -} -ILINE vec4 Vec4Four() -{ - return Vec4(4.f, 4.f, 4.f, 4.f); -} -ILINE vec4 Vec4ZeroOneTwoThree() -{ - return Vec4(0.f, 1.f, 2.f, 3.f); -} -ILINE vec4 Vec4FFFFFFFF() -{ - return Vec4(~0u, ~0u, ~0u, ~0u); -} -ILINE vec4 Vec4Epsilon() -{ - return Vec4(FLT_EPSILON); -} -template -ILINE void Prefetch(const void* pData) -{ -} -template -ILINE vec4 Shuffle(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_u[M & 3], V0.m_u[(M >> 2) & 3], V1.m_u[(M >> 4) & 3], V1.m_u[(M >> 6) & 3]); -} -template -ILINE vec4 Swizzle(vec4 V) -{ - return Shuffle(V, V); -} -template -ILINE vec4 Splat(vec4 V) -{ - CRY_ASSERT_MESSAGE(0, "Should not be reached!"); - return Vec4FFFFFFFF(); -} -template<> -ILINE vec4 Splat<0>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<1>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<2>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<3>(vec4 V) -{ - return Shuffle(V, V); -} -ILINE vec4 Add(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf + V1.m_Xf, - V0.m_Yf + V1.m_Yf, - V0.m_Zf + V1.m_Zf, - V0.m_Wf + V1.m_Wf); -} -ILINE vec4 Sub(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf - V1.m_Xf, - V0.m_Yf - V1.m_Yf, - V0.m_Zf - V1.m_Zf, - V0.m_Wf - V1.m_Wf); -} -ILINE vec4 Mul(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf * V1.m_Xf, - V0.m_Yf * V1.m_Yf, - V0.m_Zf * V1.m_Zf, - V0.m_Wf * V1.m_Wf); -} -ILINE vec4 Div(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf / V1.m_Xf, - V0.m_Yf / V1.m_Yf, - V0.m_Zf / V1.m_Zf, - V0.m_Wf / V1.m_Wf); -} -ILINE vec4 RcpFAST(vec4 V) -{ - return Div(Vec4One(), V); -} -ILINE vec4 DivFAST(vec4 V0, vec4 V1) -{ - return Div(V0, V1); -} -ILINE vec4 Rcp(vec4 V) -{ - return Div(Vec4One(), V); -} -ILINE vec4 Madd(vec4 V0, vec4 V1, vec4 V2) -{ - return Add(V2, Mul(V0, V1)); -} -ILINE vec4 Msub(vec4 V0, vec4 V1, vec4 V2) -{ - return Sub(Mul(V0, V1), V2); -} -ILINE vec4 Min(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf < V1.m_Xf ? V0.m_Xf : V1.m_Xf, - V0.m_Yf < V1.m_Yf ? V0.m_Yf : V1.m_Yf, - V0.m_Zf < V1.m_Zf ? V0.m_Zf : V1.m_Zf, - V0.m_Wf < V1.m_Wf ? V0.m_Wf : V1.m_Wf); -} -ILINE vec4 Max(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf > V1.m_Xf ? V0.m_Xf : V1.m_Xf, - V0.m_Yf > V1.m_Yf ? V0.m_Yf : V1.m_Yf, - V0.m_Zf > V1.m_Zf ? V0.m_Zf : V1.m_Zf, - V0.m_Wf > V1.m_Wf ? V0.m_Wf : V1.m_Wf); -} -ILINE vec4 floatToint32(vec4 V) -{ - return Vec4(static_cast(static_cast(V.m_Xf)), - static_cast(static_cast(V.m_Yf)), - static_cast(static_cast(V.m_Zf)), - static_cast(static_cast(V.m_Wf))); -} -ILINE vec4 int32Tofloat(vec4 V) -{ - return Vec4(static_cast(V.m_Xs), - static_cast(V.m_Ys), - static_cast(V.m_Zs), - static_cast(V.m_Ws)); -} -ILINE vec4 CmpLE(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xf <= V1.m_Xf ? ~0u : 0u, - V0.m_Yf <= V1.m_Yf ? ~0u : 0u, - V0.m_Zf <= V1.m_Zf ? ~0u : 0u, - V0.m_Wf <= V1.m_Wf ? ~0u : 0u); -} -ILINE uint32 SignMask(vec4 V) -{ - return (V.m_Xu >> 31) | ((V.m_Yu >> 31) << 1) | ((V.m_Zu >> 31) << 2) | ((V.m_Wu >> 31) << 3); -} -ILINE vec4 And(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xu & V1.m_Xu, - V0.m_Yu & V1.m_Yu, - V0.m_Zu & V1.m_Zu, - V0.m_Wu & V1.m_Wu); -} -ILINE vec4 AndNot(vec4 V0, vec4 V1) -{ - return Vec4((~V0.m_Xu) & V1.m_Xu, - (~V0.m_Yu) & V1.m_Yu, - (~V0.m_Zu) & V1.m_Zu, - (~V0.m_Wu) & V1.m_Wu); -} -ILINE vec4 Or(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xu | V1.m_Xu, - V0.m_Yu | V1.m_Yu, - V0.m_Zu | V1.m_Zu, - V0.m_Wu | V1.m_Wu); -} -ILINE vec4 Xor(vec4 V0, vec4 V1) -{ - return Vec4(V0.m_Xu ^ V1.m_Xu, - V0.m_Yu ^ V1.m_Yu, - V0.m_Zu ^ V1.m_Zu, - V0.m_Wu ^ V1.m_Wu); -} -ILINE vec4 Select(vec4 V0, vec4 V1, vec4 M) -{ - return SelectSign(V0, V1, M); -} -ILINE vec4 ShiftAR(vec4 V, uint32 Count) -{ - return Vec4(static_cast(V.m_Xs >> Count), - static_cast(V.m_Ys >> Count), - static_cast(V.m_Zs >> Count), - static_cast(V.m_Ws >> Count)); -} -ILINE vec4 SelectSign(vec4 V0, vec4 V1, vec4 M) -{ - M = ShiftAR(M, 31); - return Or(AndNot(M, V0), And(M, V1)); -} -template -ILINE vec4 SelectStatic(vec4 V0, vec4 V1) -{ - const vec4 mask = NVMath::Vec4(M & 0x1 ? ~0x0u : 0x0u, M & 0x2 ? ~0x0u : 0x0u, M & 0x4 ? ~0x0u : 0x0u, M & 0x8 ? ~0x0u : 0x0u); - return Select(V0, V1, mask); -} - -ILINE vec4 SelectBits(vec4 V0, vec4 V1, vec4 M) -{ - return Or(AndNot(M, V0), And(M, V1)); -} - -ILINE vec4 CmpEq(vec4 V0, vec4 V1) -{ - return Vec4( - V0.m_Xs == V1.m_Xs ? 0xffffffff : 0x0, - V0.m_Ys == V1.m_Ys ? 0xffffffff : 0x0, - V0.m_Zs == V1.m_Zs ? 0xffffffff : 0x0, - V0.m_Ws == V1.m_Ws ? 0xffffffff : 0x0); -} - -ILINE void ExtractByteToFloat(vec4& rVOut0, vec4& rVOut1, vec4& rVOut2, vec4& rVOut3, vec4 VIn) -{ - const char* const VInBytes = (const char*)&VIn; - vec4 VOutVecs[4]; - int* VOutInts[4] = - { - reinterpret_cast(&VOutVecs[0]), - reinterpret_cast(&VOutVecs[1]), - reinterpret_cast(&VOutVecs[2]), - reinterpret_cast(&VOutVecs[3]) - }; - - VOutInts[0][0] = VInBytes[ 0]; - VOutInts[0][1] = VInBytes[ 1]; - VOutInts[0][2] = VInBytes[ 2]; - VOutInts[0][3] = VInBytes[ 3]; - VOutInts[1][0] = VInBytes[ 4]; - VOutInts[1][1] = VInBytes[ 5]; - VOutInts[1][2] = VInBytes[ 6]; - VOutInts[1][3] = VInBytes[ 7]; - VOutInts[2][0] = VInBytes[ 8]; - VOutInts[2][1] = VInBytes[ 9]; - VOutInts[2][2] = VInBytes[10]; - VOutInts[2][3] = VInBytes[11]; - VOutInts[3][0] = VInBytes[12]; - VOutInts[3][1] = VInBytes[13]; - VOutInts[3][2] = VInBytes[14]; - VOutInts[3][3] = VInBytes[15]; - - rVOut0 = int32Tofloat(VOutVecs[0]); - rVOut1 = int32Tofloat(VOutVecs[1]); - rVOut2 = int32Tofloat(VOutVecs[2]); - rVOut3 = int32Tofloat(VOutVecs[3]); -} - -#endif - diff --git a/Code/CryEngine/Cry3DEngine/VMath_NEON.hpp b/Code/CryEngine/Cry3DEngine/VMath_NEON.hpp deleted file mode 100644 index d032aa0ef7..0000000000 --- a/Code/CryEngine/Cry3DEngine/VMath_NEON.hpp +++ /dev/null @@ -1,552 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : unified vector math lib - - -#ifndef __D_VMATH_NEON__ -#define __D_VMATH_NEON__ - -#include - -typedef float32x4_t vec4; - -#include "VMath_Prototypes.hpp" - -#define AVOID_COMPILER_BUG - -#ifdef AVOID_COMPILER_BUG - -#define SWIZZLEMASK5(X, Y, Z, W) ((X) | (Y << 2) | (Z << 4) | (W << 6)) -#define SWIZZLEMASK4(N, X, Y, Z) N##x = SWIZZLEMASK5(X, Y, Z, 0), \ - N##y = SWIZZLEMASK5(X, Y, Z, 1), \ - N##z = SWIZZLEMASK5(X, Y, Z, 2), \ - N##w = SWIZZLEMASK5(X, Y, Z, 3), -#define SWIZZLEMASK3(N, X, Y) SWIZZLEMASK4(N##x, X, Y, 0) \ - SWIZZLEMASK4(N##y, X, Y, 1) \ - SWIZZLEMASK4(N##z, X, Y, 2) \ - SWIZZLEMASK4(N##w, X, Y, 3) -#define SWIZZLEMASK2(N, X) SWIZZLEMASK3(N##x, X, 0) \ - SWIZZLEMASK3(N##y, X, 1) \ - SWIZZLEMASK3(N##z, X, 2) \ - SWIZZLEMASK3(N##w, X, 3) -#define SWIZZLEMASK1 SWIZZLEMASK2(x, 0) \ - SWIZZLEMASK2(y, 1) \ - SWIZZLEMASK2(z, 2) \ - SWIZZLEMASK2(w, 3) - -enum ESwizzleMask -{ - SWIZZLEMASK1 -}; - -#else - -#define SWIZZLEMASK5(X, Y, Z, W) {(X + 0), (X + 1), (X + 2), (X + 3), (Y + 0), (Y + 1), (Y + 2), (Y + 3), (Z + 16), (Z + 17), (Z + 18), (Z + 19), (W + 16), (W + 17), (W + 18), (W + 19) } -#define SWIZZLEMASK4(N, X, Y, Z) SWIZZLEMASK5(X, Y, Z, 0), \ - SWIZZLEMASK5(X, Y, Z, 4), \ - SWIZZLEMASK5(X, Y, Z, 8), \ - SWIZZLEMASK5(X, Y, Z, 12), -#define SWIZZLEMASK3(N, X, Y) SWIZZLEMASK4(N##x, X, Y, 0) \ - SWIZZLEMASK4(N##y, X, Y, 4) \ - SWIZZLEMASK4(N##z, X, Y, 8) \ - SWIZZLEMASK4(N##w, X, Y, 12) -#define SWIZZLEMASK2(N, X) SWIZZLEMASK3(N##x, X, 0) \ - SWIZZLEMASK3(N##y, X, 4) \ - SWIZZLEMASK3(N##z, X, 8) \ - SWIZZLEMASK3(N##w, X, 12) -#define SWIZZLEMASK1 SWIZZLEMASK2(x, 0) \ - SWIZZLEMASK2(y, 4) \ - SWIZZLEMASK2(z, 8) \ - SWIZZLEMASK2(w, 12) - -#define SWIZZLEINDEX5(X, Y, Z, W) (X + Y + Z + W) -#define SWIZZLEINDEX4(N, X, Y, Z) N##x = SWIZZLEINDEX5(X, Y, Z, 0), \ - N##y = SWIZZLEINDEX5(X, Y, Z, 1), \ - N##z = SWIZZLEINDEX5(X, Y, Z, 2), \ - N##w = SWIZZLEINDEX5(X, Y, Z, 3), -#define SWIZZLEINDEX3(N, X, Y) SWIZZLEINDEX4(N##x, X, Y, 0) \ - SWIZZLEINDEX4(N##y, X, Y, 1) \ - SWIZZLEINDEX4(N##z, X, Y, 2) \ - SWIZZLEINDEX4(N##w, X, Y, 3) -#define SWIZZLEINDEX2(N, X) SWIZZLEINDEX3(N##x, X, 0) \ - SWIZZLEINDEX3(N##y, X, 1) \ - SWIZZLEINDEX3(N##z, X, 2) \ - SWIZZLEINDEX3(N##w, X, 3) -#define SWIZZLEINDEX1 SWIZZLEINDEX2(x, 0) \ - SWIZZLEINDEX2(y, 1) \ - SWIZZLEINDEX2(z, 2) \ - SWIZZLEINDEX2(w, 3) - -enum ESwizzleMask -{ - SWIZZLEINDEX1 -}; - -namespace cryengine_vmath_neon_internal -{ - // Contains pre-calculated lookup indices for Shuffle(). Indexed by ESwizzleMask - static const uint8x16_t g_SwizzleMasks[] = { - SWIZZLEMASK1 - }; -} // namespace cryengine_vmath_neon_internal - -#endif // AVOID_COMPILER_BUG - - -enum ECacheLvl -{ - ECL_LVL1, - ECL_LVL2, - ECL_LVL3, -}; - -/** - * Bit masks for use with result from SignMask() - */ -static const uint32 BitX = 0x00000080; -static const uint32 BitY = 0x00008000; -static const uint32 BitZ = 0x00800000; -static const uint32 BitW = 0x80000000; - -ILINE vec4 Vec4(float x, float y, float z, float w) -{ - const vec4 Ret = {x, y, z, w}; - return Ret; -} - -ILINE vec4 Vec4(uint32 x, uint32 y, uint32 z, uint32 w) -{ - const uint32x4_t Ret = {x, y, z, w}; - return (float32x4_t)Ret; -} - -ILINE vec4 Vec4(float x) -{ - return Vec4(x, x, x, x); -} - -template -ILINE int32 Vec4int32(vec4 V) -{ - return vgetq_lane_s32((int32x4_t)V, Idx); -} - -template -ILINE float Vec4float(vec4 V) -{ - return vgetq_lane_f32(V, Idx); -} - -ILINE int32 Vec4int32(vec4 V, uint32 Idx) -{ - switch (Idx) - { - case 0: - return vgetq_lane_s32((int32x4_t)V, 0); - case 1: - return vgetq_lane_s32((int32x4_t)V, 1); - case 2: - return vgetq_lane_s32((int32x4_t)V, 2); - case 3: - return vgetq_lane_s32((int32x4_t)V, 3); - default: - assert(0); - return 0; - } - //return V.m_s[Idx]; -} - -ILINE float Vec4float(vec4 V, uint32 Idx) -{ - switch (Idx) - { - case 0: - return vgetq_lane_f32(V, 0); - case 1: - return vgetq_lane_f32(V, 1); - case 2: - return vgetq_lane_f32(V, 2); - case 3: - return vgetq_lane_f32(V, 3); - default: - assert(0); - return 0; - } -} - -ILINE vec4 Vec4Zero() -{ - static const float32x4_t V = {0.f, 0.f, 0.f, 0.f}; - return V; -} - -ILINE vec4 Vec4One() -{ - static const float32x4_t V = {1.f, 1.f, 1.f, 1.f}; - return V; -} -ILINE vec4 Vec4Four() -{ - static const float32x4_t V = {4.f, 4.f, 4.f, 4.f}; - return V; -} -ILINE vec4 Vec4ZeroOneTwoThree() -{ - static const float32x4_t V = {0.f, 1.f, 2.f, 3.f}; - return V; -} -ILINE vec4 Vec4FFFFFFFF() -{ - return Vec4(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff); -} -ILINE vec4 Vec4Epsilon() -{ - static const float32x4_t V = {FLT_EPSILON, FLT_EPSILON, FLT_EPSILON, FLT_EPSILON}; - return V; -} - -/** - * Creates vector where each word element is set to value of specified element. - * INDEX 0 is x, 1 is y, etc. - * @returns {V[INDEX], V[INDEX], V[INDEX], V[INDEX]} - */ -template -ILINE vec4 Splat(vec4 V) -{ - switch (INDEX) - { - case 0: - return vdupq_lane_f32(vget_low_f32(V), 0); - case 1: - return vdupq_lane_f32(vget_low_f32(V), 1); - case 2: - // expanded to fix a clang compiler error with the preprocessor - return vdupq_lane_f32(vget_high_f32(V), 0); - case 3: - // expanded to fix a clang compiler error with the preprocessor - return vdupq_lane_f32(vget_high_f32(V), 1); - default: - assert(0); - return Vec4FFFFFFFF(); - } -} - -template -ILINE void Prefetch(const void* pData) -{ - __builtin_prefetch(pData); -} - -/** - * Return vector containing words from V0 and V1 based on mask M. - * First two elements of M specify word index in V0 and last two elements - * specify word index in V1. - * - * e.g. - * Shuffle( M={0,1,2,3} ) => {V0[0], V0[1], V1[2], V1[3]} - */ -template -ILINE vec4 Shuffle(vec4 V0, vec4 V1) -{ -#ifdef AVOID_COMPILER_BUG - return Vec4(Vec4float(V0, M & 3), Vec4float(V0, (M >> 2) & 3), Vec4float(V1, (M >> 4) & 3), Vec4float(V1, (M >> 6) & 3)); -#else - //return Vec4(V0.m_u[M&3],V0.m_u[(M>>2)&3],V1.m_u[(M>>4)&3],V1.m_u[(M>>6)&3]); - assert(M >= 0 && M < sizeof(cryengine_vmath_neon_internal::g_SwizzleMasks) / sizeof(cryengine_vmath_neon_internal::g_SwizzleMasks[0])); - // Get precomputed vector containing lookup indices for swizzle - const uint8x16_t mask = cryengine_vmath_neon_internal::g_SwizzleMasks[ M ]; - // Split the lookup indexes into xy and zw pair - const uint8x8_t low_index = vget_low_u8(mask); - const uint8x8_t high_index = vget_high_u8(mask); - // Combine inputs into table; VO=xyzw, V1=XYZW => xyzwXYZW - const uint8x8x4_t tbl = { - { - (uint8x8_t)vget_low_f32(V0), - (uint8x8_t)vget_high_f32(V0), - (uint8x8_t)vget_low_f32(V1), - (uint8x8_t)vget_high_f32(V1), - } - }; - // Look up the xy values, then zw values, then combine them - const uint8x8_t low = vtbl4_u8(tbl, low_index); - const uint8x8_t high = vtbl4_u8(tbl, high_index); - const uint8x16_t ret = vcombine_u8(low, high); - return (float32x4_t)ret; -#endif // AVOID_COMPILER_BUG -} - -template -ILINE vec4 Swizzle(vec4 V) -{ - return Shuffle(V, V); -} - -/** - * @returns V0 + V1 - */ -ILINE vec4 Add(vec4 V0, vec4 V1) -{ - return vaddq_f32(V0, V1); -} - -/** - * @returns V0 - V1 - */ -ILINE vec4 Sub(vec4 V0, vec4 V1) -{ - return vsubq_f32(V0, V1); -} - -/** - * @returns V0 * V1 - */ -ILINE vec4 Mul(vec4 V0, vec4 V1) -{ - return vmulq_f32(V0, V1); -} - -/** - * @returns V0 / V1 - */ -ILINE vec4 Div(vec4 V0, vec4 V1) -{ - return Mul(V0, Rcp(V1)); -} - -/** - * @returns 1 / V - */ -ILINE vec4 RcpFAST(vec4 V) -{ - return vrecpeq_f32(V); -} - -/** - * @returns V0 / V1 - */ -ILINE vec4 DivFAST(vec4 V0, vec4 V1) -{ - return Mul(V0, RcpFAST(V1)); -} - -/** - * @returns 1 / V - */ -ILINE vec4 Rcp(vec4 V) -{ - // Improve estimate precision with a single Newton-Raphson iteration - vec4 vEstimate = RcpFAST(V); - return vmulq_f32(vrecpsq_f32(V, vEstimate), vEstimate); -} - -/** - * @returns V0 * V1 + V2 - */ -ILINE vec4 Madd(vec4 V0, vec4 V1, vec4 V2) -{ - // Madd return V0*V1+V2 but vmla(a,b,c) does b*c+a - return vmlaq_f32(V2, V0, V1); -} - -/** - * @returns V0 * V1 - V2 - */ -ILINE vec4 Msub(vec4 V0, vec4 V1, vec4 V2) -{ - // Msub returns V0*V1-V2 but vmls(a,b,c) does a-b*c - return Sub(Mul(V0, V1), V2); -} - -ILINE vec4 Min(vec4 V0, vec4 V1) -{ - return vminq_f32(V0, V1); -} - -ILINE vec4 Max(vec4 V0, vec4 V1) -{ - return vmaxq_f32(V0, V1); -} - -ILINE vec4 floatToint32(vec4 V) -{ - return (float32x4_t)vcvtq_s32_f32(V); -} - -ILINE vec4 int32Tofloat(vec4 V) -{ - return vcvtq_f32_s32((int32x4_t)V); -} - -ILINE vec4 CmpLE(vec4 V0, vec4 V1) -{ - return (float32x4_t)vcleq_f32(V0, V1); -} - -/** - * Return sign bit of each word as a single word. Each is accessible via - * Bit[X|Y|Z|W] mask. - */ -ILINE uint32 SignMask(vec4 V) -{ - // Xcode 6.3 removed support for the non-standard 'vtbl1q_p8' in favour - // of the standard 'vtbl2_u8' which is not available in Xcode 6.2 -#if defined(__AARCH64_SIMD__) && defined(__apple_build_version__) && (__apple_build_version__ < 6020037) - const uint8x16_t tbl = vcombine_u8((uint8x8_t)vget_low_f32(V), (uint8x8_t)vget_high_f32(V)); - const uint8x8_t idx_sign = {3, 7, 11, 15}; // MSB -> LSB = W -> X (0xWWZZYYXX) - const uint8x8_t sign_bytes = vtbl1q_p8(tbl, idx_sign); -#elif 1 - // Create table from which be select bytes with msb (sign) and combine into - // single word - const uint8x8x2_t tbl = { - { - (uint8x8_t)vget_low_f32(V), - (uint8x8_t)vget_high_f32(V), - } - }; - const uint8x8_t idx_sign = {3, 7, 11, 15}; // MSB -> LSB = W -> X (0xWWZZYYXX) - const uint8x8_t sign_bytes = vtbl2_u8(tbl, idx_sign); -#else - const int32x4_t rev = vshrq_n_s32((int32x4_t)V, 24); - const int16x4_t shorts = vmovn_s32(rev); - const uint8x8_t tbl = (uint8x8_t)shorts; - const uint8x8_t index = {1, 3, 5, 7}; - const uint8x8_t sign_bytes = vtbl1_u8(tbl, index); -#endif - return vget_lane_u32((uint32x2_t)sign_bytes, 0); - //return (V.m_Xu>>31)|((V.m_Yu>>31)<<1)|((V.m_Zu>>31)<<2)|((V.m_Wu>>31)<<3); -} - -/** - * @returns V0 & V1 - */ -ILINE vec4 And(vec4 V0, vec4 V1) -{ - return (float32x4_t)vandq_u32((uint32x4_t)V0, (uint32x4_t)V1); -} - -/** - * @returns ~V0 & V1 - */ -ILINE vec4 AndNot(vec4 V0, vec4 V1) -{ - return (float32x4_t)vandq_u32(vmvnq_u32((uint32x4_t)V0), (uint32x4_t)V1); -} - -/** - * @returns V0 | V1 - */ -ILINE vec4 Or(vec4 V0, vec4 V1) -{ - return (float32x4_t)vorrq_u32((uint32x4_t)V0, (uint32x4_t)V1); -} - -/** - * @returns V0 ^ V1 - */ -ILINE vec4 Xor(vec4 V0, vec4 V1) -{ - return (float32x4_t)veorq_u32((uint32x4_t)V0, (uint32x4_t)V1); -} - -ILINE vec4 Select(vec4 V0, vec4 V1, vec4 M) -{ - return SelectSign(V0, V1, M); -} - -/** - * Returns new vector where each word element comes from V0 if the sign of - * the corresponding word in M is 0 (+), otherwise the word element comes from - * V1. - * - * e.g. - * SelectSign( {0.f,1.f,2.f,3.f}, {a.f,b.f,c.f,d.f}, {0.f,0.f,-1.f,-1.f} ) - * => {0.f, 1.f, c.f, d.f} - */ -ILINE vec4 SelectSign(vec4 V0, vec4 V1, vec4 M) -{ - const int32x4_t mask = vshrq_n_s32((int32x4_t)M, 31); - return vbslq_f32((uint32x4_t)mask, V1, V0); - //M = ShiftAR(M,31); - //return Or(AndNot(M,V0),And(M,V1)); -} - -/** - * Expands each byte of VIn as a float. - * - * e.g. - * ExtractByteToFloat( {0x00010203, 0x04...} ) => {3.f, 2.f, 1.f, 0.f} ... - */ -static ILINE void ExtractByteToFloat(vec4& rVout0, vec4& rVout1, vec4& rVout2, vec4& rVout3, vec4 VIn) -{ - // 16 bytes => 2x 8 shorts - const int8x8_t XY8 = vget_low_s8((int8x16_t)VIn); - const int8x8_t ZW8 = vget_high_s8((int8x16_t)VIn); - const int16x8_t XY16 = vmovl_s8(XY8); - const int16x8_t ZW16 = vmovl_s8(ZW8); - - // 2x 8 shorts => 4x 4 int - const int16x4_t X16 = vget_low_s16(XY16); - const int16x4_t Y16 = vget_high_s16(XY16); - const int16x4_t Z16 = vget_low_s16(ZW16); - const int16x4_t W16 = vget_high_s16(ZW16); - const int32x4_t X32 = vmovl_s16(X16); - const int32x4_t Y32 = vmovl_s16(Y16); - const int32x4_t Z32 = vmovl_s16(Z16); - const int32x4_t W32 = vmovl_s16(W16); - - // 4x 4 int => 4x 4 float - rVout0 = vcvtq_f32_s32(X32); - rVout1 = vcvtq_f32_s32(Y32); - rVout2 = vcvtq_f32_s32(Z32); - rVout3 = vcvtq_f32_s32(W32); -} - -/** - * Returns vector where each bit is from V0 if the corresponding bit in - * M is 0, otherwise the bit is from V1 (i.e. vsel instruction from PowerPC, or selb from SPU). - * - * e.g. - * SelectBits(b0001, b1110, b0011) => b0010 - */ -ILINE vec4 SelectBits(vec4 V0, vec4 V1, vec4 M) -{ - // Order of args to vbsl is exact opposite of SelectBits() - return vbslq_f32((uint32x4_t)M, V1, V0); - //return Or(AndNot(M,V0),And(M,V1)); -} - -/** - * Returns vector where, for each word, all bits are set to 1 if the - * corresponding words in V0 and V1 are equal. - * - * e.g. - * CmpEq( {0.f...}, {0.f, 1.f, 2.f...} ) => {0xffffffff, 0x0, 0x0, 0x0} - */ -ILINE vec4 CmpEq(vec4 V0, vec4 V1) -{ - return (float32x4_t)vceqq_f32(V0, V1); -} - -template -ILINE vec4 SelectStatic(vec4 V0, vec4 V1) -{ - const vec4 mask = Vec4(M & 0x1 ? ~0x0u : 0x0u, M & 0x2 ? ~0x0u : 0x0u, M & 0x4 ? ~0x0u : 0x0u, M & 0x8 ? ~0x0u : 0x0u); - return Select(V0, V1, mask); -} - - -#endif // __D_VMATH_NEON__ - -#undef AVOID_COMPILER_BUG - diff --git a/Code/CryEngine/Cry3DEngine/VMath_Prototypes.hpp b/Code/CryEngine/Cry3DEngine/VMath_Prototypes.hpp deleted file mode 100644 index e4ff98caeb..0000000000 --- a/Code/CryEngine/Cry3DEngine/VMath_Prototypes.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : unified vector math lib - - -#ifndef CRYINCLUDE_D_VMATH_H -#define CRYINCLUDE_D_VMATH_H - -ILINE vec4 Vec4(float x); -ILINE vec4 Vec4(float x, float y, float z, float w); -ILINE vec4 Vec4(uint32 x, uint32 y, uint32 z, uint32 w); -ILINE int32 Vec4int32(vec4 V, uint32 Idx); -ILINE vec4 Vec4Zero(); -ILINE vec4 Vec4One(); -ILINE vec4 Vec4Four(); -ILINE vec4 Vec4ZeroOneTwoThree(); -ILINE vec4 Vec4FFFFFFFF(); -ILINE vec4 Vec4Epsilon(); -ILINE vec4 Add(vec4 V0, vec4 V1); -ILINE vec4 Sub(vec4 V0, vec4 V1); -ILINE vec4 Mul(vec4 V0, vec4 V1); -ILINE vec4 Div(vec4 V0, vec4 V1); -ILINE vec4 RcpFAST(vec4 V); -ILINE vec4 DivFAST(vec4 V0, vec4 V1); -ILINE vec4 Rcp(vec4 V); -ILINE vec4 Madd(vec4 V0, vec4 V1, vec4 V2); -ILINE vec4 Msub(vec4 V0, vec4 V1, vec4 V2); -ILINE vec4 Min(vec4 V0, vec4 V1); -ILINE vec4 Max(vec4 V0, vec4 V1); -ILINE vec4 floatToint32(vec4 V); -ILINE vec4 int32Tofloat(vec4 V); -ILINE vec4 CmpLE(vec4 V0, vec4 V1); -ILINE uint32 SignMask(vec4 V); -ILINE vec4 And(vec4 V0, vec4 V1); -ILINE vec4 AndNot(vec4 V0, vec4 V1); -ILINE vec4 Or(vec4 V0, vec4 V1); -ILINE vec4 Xor(vec4 V0, vec4 V1); -ILINE vec4 Select(vec4 V0, vec4 V1, vec4 M); -ILINE vec4 SelectSign(vec4 V0, vec4 V1, vec4 M); - -#endif - diff --git a/Code/CryEngine/Cry3DEngine/VMath_SSE.hpp b/Code/CryEngine/Cry3DEngine/VMath_SSE.hpp deleted file mode 100644 index 3ef945f498..0000000000 --- a/Code/CryEngine/Cry3DEngine/VMath_SSE.hpp +++ /dev/null @@ -1,330 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : unified vector math lib - - -#ifndef __D_VMATH_SSE__ -#define __D_VMATH_SSE__ - -#define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY -//#include - -typedef __m128 vec4; - -#include "VMath_Prototypes.hpp" - -#define SWIZZLEMASK4(N, X, Y, Z) N##x = _MM_SHUFFLE(0, Z, Y, X), \ - N##y = _MM_SHUFFLE(1, Z, Y, X), \ - N##z = _MM_SHUFFLE(2, Z, Y, X), \ - N##w = _MM_SHUFFLE(3, Z, Y, X), -#define SWIZZLEMASK3(N, X, Y) SWIZZLEMASK4(N##x, X, Y, 0) \ - SWIZZLEMASK4(N##y, X, Y, 1) \ - SWIZZLEMASK4(N##z, X, Y, 2) \ - SWIZZLEMASK4(N##w, X, Y, 3) -#define SWIZZLEMASK2(N, X) SWIZZLEMASK3(N##x, X, 0) \ - SWIZZLEMASK3(N##y, X, 1) \ - SWIZZLEMASK3(N##z, X, 2) \ - SWIZZLEMASK3(N##w, X, 3) -#define SWIZZLEMASK1 SWIZZLEMASK2(x, 0) \ - SWIZZLEMASK2(y, 1) \ - SWIZZLEMASK2(z, 2) \ - SWIZZLEMASK2(w, 3) - -enum ESwizzleMask -{ - SWIZZLEMASK1 -}; -enum ECacheLvl -{ - ECL_LVL1 = _MM_HINT_T0, - ECL_LVL2 = _MM_HINT_T1, - ECL_LVL3 = _MM_HINT_T2, -}; -#define BitX 1 -#define BitY 2 -#define BitZ 4 -#define BitW 8 - - -ILINE vec4 Vec4(float x) -{ - return _mm_set1_ps(x); -} -ILINE vec4 Vec4(float x, float y, float z, float w) -{ - return _mm_set_ps(w, z, y, x); -} -ILINE vec4 Vec4(uint32 x, uint32 y, uint32 z, uint32 w) -{ - return _mm_set_ps(*reinterpret_cast(&w), - *reinterpret_cast(&z), - *reinterpret_cast(&y), - *reinterpret_cast(&x)); -} -ILINE float Vec4float(vec4 V, uint32 Idx) -{ - union - { - vec4 Tmp; - float V4[4]; - } T; - T.Tmp = V; - return T.V4[Idx]; -} -template -ILINE float Vec4float(vec4 V) -{ -#if defined(VEC4_SSE4) - float f; - _MM_EXTRACT_FLOAT(f, V, Idx); - return f; -#else - return Vec4float(V, Idx); -#endif -} -template -ILINE int32 Vec4int32(vec4 V) -{ -#if defined(VEC4_SSE4) - return _mm_extract_ps(V, Idx); -#else - return Vec4int32(V, Idx); -#endif -} -ILINE int32 Vec4int32(vec4 V, uint32 Idx) -{ - union - { - vec4 Tmp; - int32 V4[4]; - } T; - T.Tmp = V; - return T.V4[Idx]; -} -ILINE vec4 Vec4Zero() -{ - return _mm_setzero_ps(); -} - -ILINE vec4 Vec4One() -{ - return _mm_set_ps(1.f, 1.f, 1.f, 1.f); -} -ILINE vec4 Vec4Four() -{ - return _mm_set_ps(4.f, 4.f, 4.f, 4.f); -} -ILINE vec4 Vec4ZeroOneTwoThree() -{ - return _mm_set_ps(3.f, 2.f, 1.f, 0.f); -} -ILINE vec4 Vec4FFFFFFFF() -{ - __m128 a = _mm_setzero_ps(); - return _mm_cmpeq_ps(a, a); -} -ILINE vec4 Vec4Epsilon() -{ - return _mm_set_ps(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON, FLT_EPSILON); -} -template -ILINE void Prefetch(const void* pData) -{ -#if defined(LINUX) && !defined(__clang__) - _mm_prefetch(reinterpret_cast(pData), (_mm_hint)L); -#else - _mm_prefetch(reinterpret_cast(pData), (int)L); -#endif -} -template -ILINE vec4 Shuffle(vec4 V0, vec4 V1) -{ - return _mm_shuffle_ps(V0, V1, M); -} -template -ILINE vec4 Swizzle(vec4 V) -{ - return Shuffle(V, V); -} -ILINE void ExtractByteToFloat(vec4& rVOut0, vec4& rVOut1, vec4& rVOut2, vec4& rVOut3, vec4 VIn) -{ - const vec4 Zf = Vec4Zero(); - const __m128i Z = *reinterpret_cast(&Zf); - __m128i V0 = _mm_unpacklo_epi8(*reinterpret_cast(&VIn), Z); - __m128i V1 = _mm_unpackhi_epi8(*reinterpret_cast(&VIn), Z); - __m128i V00 = _mm_unpacklo_epi8(V0, Z); - __m128i V01 = _mm_unpackhi_epi8(V0, Z); - __m128i V10 = _mm_unpacklo_epi8(V1, Z); - __m128i V11 = _mm_unpackhi_epi8(V1, Z); - V00 = _mm_srai_epi32(_mm_slli_epi32(V00, 24), 24); - V01 = _mm_srai_epi32(_mm_slli_epi32(V01, 24), 24); - V10 = _mm_srai_epi32(_mm_slli_epi32(V10, 24), 24); - V11 = _mm_srai_epi32(_mm_slli_epi32(V11, 24), 24); - rVOut0 = int32Tofloat(*reinterpret_cast(&V00)); - rVOut1 = int32Tofloat(*reinterpret_cast(&V01)); - rVOut2 = int32Tofloat(*reinterpret_cast(&V10)); - rVOut3 = int32Tofloat(*reinterpret_cast(&V11)); -} -ILINE vec4 Add(vec4 V0, vec4 V1) -{ - return _mm_add_ps(V0, V1); -} -ILINE vec4 Sub(vec4 V0, vec4 V1) -{ - return _mm_sub_ps(V0, V1); -} -ILINE vec4 Mul(vec4 V0, vec4 V1) -{ - return _mm_mul_ps(V0, V1); -} -ILINE vec4 Div(vec4 V0, vec4 V1) -{ - return _mm_div_ps(V0, V1); -} -ILINE vec4 RcpFAST(vec4 V) -{ - return _mm_rcp_ps(V); -} -ILINE vec4 DivFAST(vec4 V0, vec4 V1) -{ - return Mul(V0, RcpFAST(V1)); -} -ILINE vec4 Rcp(vec4 V) -{ - return Div(Vec4One(), V); -} -ILINE vec4 Madd(vec4 V0, vec4 V1, vec4 V2) -{ - return Add(V2, Mul(V0, V1)); -} -ILINE vec4 Msub(vec4 V0, vec4 V1, vec4 V2) -{ - return Sub(Mul(V0, V1), V2); -} -ILINE vec4 Min(vec4 V0, vec4 V1) -{ - return _mm_min_ps(V0, V1); -} -ILINE vec4 Max(vec4 V0, vec4 V1) -{ - return _mm_max_ps(V0, V1); -} -ILINE vec4 floatToint32(vec4 V) -{ - const __m128i Tmp = _mm_cvttps_epi32(V); - return *reinterpret_cast(&Tmp); -} -ILINE vec4 int32Tofloat(vec4 V) -{ - return _mm_cvtepi32_ps(*reinterpret_cast<__m128i*>(&V)); -} -ILINE vec4 CmpLE(vec4 V0, vec4 V1) -{ - return _mm_cmple_ps(V0, V1); -} -ILINE vec4 CmpEq(vec4 V0, vec4 V1) -{ - return _mm_cmpeq_ps(V0, V1); -} -ILINE uint32 SignMask(vec4 V) -{ - return _mm_movemask_ps(V); -} -ILINE vec4 And(vec4 V0, vec4 V1) -{ - const __m128i Tmp = _mm_and_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1)); - return *reinterpret_cast(&Tmp); -} -ILINE vec4 AndNot(vec4 V0, vec4 V1) -{ - const __m128i Tmp = _mm_andnot_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1)); - return *reinterpret_cast(&Tmp); -} -ILINE vec4 Or(vec4 V0, vec4 V1) -{ - const __m128i Tmp = _mm_or_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1)); - return *reinterpret_cast(&Tmp); -} -ILINE vec4 Xor(vec4 V0, vec4 V1) -{ - const __m128i Tmp = _mm_xor_si128(*reinterpret_cast<__m128i*>(&V0), *reinterpret_cast<__m128i*>(&V1)); - return *reinterpret_cast(&Tmp); -} -ILINE vec4 ShiftAR(vec4 V, uint32 Count) -{ - const __m128i Tmp = _mm_srai_epi32(*reinterpret_cast<__m128i*>(&V), Count); - return *reinterpret_cast(&Tmp); -} -template -ILINE vec4 Splat(vec4 V) -{ - CRY_ASSERT_MESSAGE(0, "Should not be reached!"); - return Vec4FFFFFFFF(); -} -template<> -ILINE vec4 Splat<0>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<1>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<2>(vec4 V) -{ - return Shuffle(V, V); -} -template<> -ILINE vec4 Splat<3>(vec4 V) -{ - return Shuffle(V, V); -} -ILINE vec4 SelectBits(vec4 V0, vec4 V1, vec4 M) -{ -#if defined(VEC4_SSE4) - return _mm_blendv_ps(V0, V1, M); -#else - return Or(AndNot(M, V0), And(M, V1)); -#endif -} -ILINE vec4 Select(vec4 V0, vec4 V1, vec4 M) -{ -#if !defined(VEC4_SSE4) - M = ShiftAR(M, 31); -#endif - return SelectBits(V0, V1, M); -} -ILINE vec4 SelectSign(vec4 V0, vec4 V1, vec4 M) -{ -#if defined(VEC4_SSE4) - return Select(V0, V1, M); -#else - return Select(V0, V1, ShiftAR(M, 31)); -#endif -} -template -ILINE vec4 SelectStatic(vec4 V0, vec4 V1) -{ -#if defined(VEC4_SSE4) - return _mm_blend_ps(V0, V1, M); -#else - const vec4 mask = Vec4(M & 0x1 ? ~0x0u : 0x0u, M & 0x2 ? ~0x0u : 0x0u, M & 0x4 ? ~0x0u : 0x0u, M & 0x8 ? ~0x0u : 0x0u); - return Select(V0, V1, mask); -#endif -} - -#endif - diff --git a/Code/CryEngine/Cry3DEngine/VisAreaCompile.cpp b/Code/CryEngine/Cry3DEngine/VisAreaCompile.cpp deleted file mode 100644 index 34126d180c..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreaCompile.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : visarea node loading/saving - - -#include "Cry3DEngine_precompiled.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include - -#define VISAREA_NODE_CHUNK_VERSION 2 - -#define VISAREA_FLAG_OCEAN_VISIBLE BIT(0) -#define VISAREA_FLAG_IGNORE_SKY_COLOR BIT(1) -#define VISAREA_FLAG_AFFECTEDBYOUTLIGHTS BIT(2) -#define VISAREA_FLAG_SKYONLY BIT(3) -#define VISAREA_FLAG_DOUBLESIDE BIT(4) -#define VISAREA_FLAG_USEININDOORS BIT(5) -#define VISAREA_FLAG_IGNORE_GI BIT(6) -#define VISAREA_FLAG_IGNORE_OUTDOOR_AO BIT(7) - -#define MAX_VIS_AREA_CONNECTIONS_NUM 30 - -struct SVisAreaChunk -{ - int nChunkVersion; - AABB boxArea, boxStatics; - char sName[32]; - int nObjectsBlockSize; - int arrConnectionsId[MAX_VIS_AREA_CONNECTIONS_NUM]; - uint32 dwFlags; - float fPortalBlending; - Vec3 vConnNormals[2]; - float fHeight; - Vec3 vAmbColor; - float fViewDistRatio; - - AUTO_STRUCT_INFO_LOCAL -}; - -#if ENGINE_ENABLE_COMPILATION -int CVisArea::GetData(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) -{ - if (m_pObjectsTree) - { - m_pObjectsTree->CleanUpTree(); - } - - if (pData) - { - byte* pHead = pData; - SaveHeader(pData, nDataSize); - - // save shape points num - int nPointsCount = m_lstShapePoints.Count(); - SwapEndian(nPointsCount, eEndian); - memcpy(pData, &nPointsCount, sizeof(nPointsCount)); - UPDATE_PTR_AND_SIZE(pData, nDataSize, sizeof(nPointsCount)); - - // save shape points - memcpy(pData, m_lstShapePoints.GetElements(), m_lstShapePoints.GetDataSize()); - SwapEndian((Vec3*)pData, m_lstShapePoints.Count(), eEndian); - UPDATE_PTR_AND_SIZE(pData, nDataSize, m_lstShapePoints.GetDataSize()); - - SaveObjectsTree(pData, nDataSize, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo, pHead); - } - else // just count size - { - nDataSize += sizeof(SVisAreaChunk); - - nDataSize += sizeof(int); - nDataSize += m_lstShapePoints.GetDataSize(); - - if (m_pObjectsTree) - { - m_pObjectsTree->GetData(pData, nDataSize, NULL, NULL, NULL, eEndian, pExportInfo); - } - } - return true; -} -#endif - -int CVisArea::Load(byte*& f, int& nDataSizeLeft, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) -{ - return Load_T(f, nDataSizeLeft, pStatObjTable, pMatTable, eEndian, pExportInfo); -} - -int CVisArea::Load(AZ::IO::HandleType& fileHandle, int& nDataSizeLeft, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) -{ - return Load_T(fileHandle, nDataSizeLeft, pStatObjTable, pMatTable, eEndian, pExportInfo); -} - -template -int CVisArea::Load_T(T& f, int& nDataSizeLeft, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo) -{ - int objBlockSize = 0; - if (!LoadHeader_T(f, nDataSizeLeft, eEndian, objBlockSize)) - { - return 0; - } - - { // get shape points - int nPointsCount = 0; - if (!PakLoadDataUtils::LoadDataFromFile(&nPointsCount, 1, f, nDataSizeLeft, eEndian)) - { - return 0; - } - - // get shape points - m_lstShapePoints.PreAllocate(nPointsCount, nPointsCount); - if (!PakLoadDataUtils::LoadDataFromFile(m_lstShapePoints.GetElements(), nPointsCount, f, nDataSizeLeft, eEndian)) - { - return 0; - } - - UpdateClipVolume(); - } - - if (!LoadObjectsTree_T(f, nDataSizeLeft, 0, pStatObjTable, pMatTable, eEndian, pExportInfo, objBlockSize)) - { - return 0; - } - - return true; -} - - -const AABB* CVisArea::GetStaticObjectAABBox() const -{ - return &m_boxStatics; -} -#if ENGINE_ENABLE_COMPILATION -int CVisArea::SaveHeader(byte*& pData, int& nDataSize) -{ - // save node info - SVisAreaChunk* pCunk = (SVisAreaChunk*)pData; - pCunk->nChunkVersion = VISAREA_NODE_CHUNK_VERSION; - pCunk->boxArea = m_boxArea; - UpdateGeometryBBox(); - pCunk->boxStatics = m_boxStatics; - memset(pCunk->sName, 0, sizeof(pCunk->sName)); - cry_strcpy(pCunk->sName, m_pVisAreaColdData->m_sName); - memcpy(pCunk->vConnNormals, m_vConnNormals, sizeof(pCunk->vConnNormals)); - pCunk->fHeight = m_fHeight; - pCunk->vAmbColor = m_vAmbientColor; - pCunk->fViewDistRatio = m_fViewDistRatio; - pCunk->fPortalBlending = m_fPortalBlending; - - pCunk->dwFlags = 0; - if (m_bOceanVisible) - { - pCunk->dwFlags |= VISAREA_FLAG_OCEAN_VISIBLE; - } - if (m_bIgnoreSky) - { - pCunk->dwFlags |= VISAREA_FLAG_IGNORE_SKY_COLOR; - } - if (m_bAffectedByOutLights) - { - pCunk->dwFlags |= VISAREA_FLAG_AFFECTEDBYOUTLIGHTS; - } - if (m_bSkyOnly) - { - pCunk->dwFlags |= VISAREA_FLAG_SKYONLY; - } - if (m_bDoubleSide) - { - pCunk->dwFlags |= VISAREA_FLAG_DOUBLESIDE; - } - if (m_bUseInIndoors) - { - pCunk->dwFlags |= VISAREA_FLAG_USEININDOORS; - } - if (m_bIgnoreGI) - { - pCunk->dwFlags |= VISAREA_FLAG_IGNORE_GI; - } - if (m_bIgnoreOutdoorAO) - { - pCunk->dwFlags |= VISAREA_FLAG_IGNORE_OUTDOOR_AO; - } - - // transform connections id into pointers - PodArray& rAreas = IsPortal() ? GetVisAreaManager()->m_lstVisAreas : GetVisAreaManager()->m_lstPortals; - for (int i = 0; i < MAX_VIS_AREA_CONNECTIONS_NUM; i++) - { - pCunk->arrConnectionsId[i] = -1; - } - for (int i = 0; i < m_lstConnections.Count() && i < MAX_VIS_AREA_CONNECTIONS_NUM; i++) - { - IVisArea* pArea = m_lstConnections[i]; - int nId; - for (nId = 0; nId < rAreas.Count(); nId++) - { - if (pArea == rAreas[nId]) - { - break; - } - } - - if (nId < rAreas.Count()) - { - pCunk->arrConnectionsId[i] = nId; - } - else - { - pCunk->arrConnectionsId[i] = -1; - assert(!"Undefined connction"); - } - } - - UPDATE_PTR_AND_SIZE(pData, nDataSize, sizeof(SVisAreaChunk)); - - return true; -} - -int CVisArea::SaveObjectsTree(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, byte* pHead) -{ - SVisAreaChunk* pCunk = (SVisAreaChunk*)pHead; - - // save objects - pCunk->nObjectsBlockSize = 0; - - // get data from objects tree - if (m_pObjectsTree) - { - byte* pTmp = NULL; - m_pObjectsTree->GetData(pTmp, pCunk->nObjectsBlockSize, NULL, NULL, NULL, eEndian, pExportInfo); - m_pObjectsTree->GetData(pData, nDataSize, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo); // UPDATE_PTR_AND_SIZE is inside - } - - SwapEndian(*pCunk, eEndian); - - return true; -} -#endif -template -int CVisArea::LoadHeader_T(T& f, int& nDataSizeLeft, EEndian eEndian, int& objBlockSize) -{ - SVisAreaChunk chunk; - if (!PakLoadDataUtils::LoadDataFromFile(&chunk, 1, f, nDataSizeLeft, eEndian)) - { - return 0; - } - - assert(chunk.nChunkVersion == VISAREA_NODE_CHUNK_VERSION); - if (chunk.nChunkVersion != VISAREA_NODE_CHUNK_VERSION) - { - return 0; - } - - // get area info - m_boxArea = chunk.boxArea; - m_boxStatics = chunk.boxStatics; - chunk.sName[sizeof(chunk.sName) - 1] = 0; - cry_strcpy(m_pVisAreaColdData->m_sName, chunk.sName); - m_bThisIsPortal = strstr(m_pVisAreaColdData->m_sName, "portal") != 0; - m_bIgnoreSky = (strstr(m_pVisAreaColdData->m_sName, "ignoresky") != 0) || ((chunk.dwFlags & VISAREA_FLAG_IGNORE_SKY_COLOR) != 0); - memcpy(m_vConnNormals, chunk.vConnNormals, sizeof(m_vConnNormals)); - m_fHeight = chunk.fHeight; - m_vAmbientColor = chunk.vAmbColor; - m_fViewDistRatio = chunk.fViewDistRatio; - m_fPortalBlending = chunk.fPortalBlending; - - if (chunk.dwFlags == uint32(-1)) - { - chunk.dwFlags = 0; - } - m_bOceanVisible = (chunk.dwFlags & VISAREA_FLAG_OCEAN_VISIBLE) != 0; - - m_bAffectedByOutLights = (chunk.dwFlags & VISAREA_FLAG_AFFECTEDBYOUTLIGHTS) != 0; - m_bSkyOnly = (chunk.dwFlags & VISAREA_FLAG_SKYONLY) != 0; - m_bDoubleSide = (chunk.dwFlags & VISAREA_FLAG_DOUBLESIDE) != 0; - m_bUseInIndoors = (chunk.dwFlags & VISAREA_FLAG_USEININDOORS) != 0; - m_bIgnoreGI = (chunk.dwFlags & VISAREA_FLAG_IGNORE_GI) != 0; - m_bIgnoreOutdoorAO = (chunk.dwFlags & VISAREA_FLAG_IGNORE_OUTDOOR_AO) != 0; - - objBlockSize = chunk.nObjectsBlockSize; - - // convert connections id into pointers - PodArray& rAreas = IsPortal() ? GetVisAreaManager()->m_lstVisAreas : GetVisAreaManager()->m_lstPortals; - for (int i = 0; i < MAX_VIS_AREA_CONNECTIONS_NUM && rAreas.Count(); i++) - { - assert(chunk.arrConnectionsId[i] < rAreas.Count()); - if (chunk.arrConnectionsId[i] >= 0) - { - m_lstConnections.Add(rAreas[chunk.arrConnectionsId[i]]); - } - } - - return true; -} - -template -int CVisArea::LoadObjectsTree_T(T& f, int& nDataSizeLeft, int nSID, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, const int objBlockSize) -{ - // mark tree as invalid since new visarea was just added - SAFE_DELETE(GetVisAreaManager()->m_pAABBTree); - - AABB* pBox = (pExportInfo && !pExportInfo->areaBox.IsReset()) ? &pExportInfo->areaBox : NULL; - - // load content of objects tree - if (!m_bEditor && objBlockSize > 4) - { - int nCurDataSize = nDataSizeLeft; - if (nCurDataSize > 0) - { - if (!m_pObjectsTree) - { - m_pObjectsTree = COctreeNode::Create(DEFAULT_SID, m_boxArea, this); - } - m_pObjectsTree->UpdateVisAreaSID(this, nSID); - - if (pExportInfo != NULL && pExportInfo->pVisibleLayerMask != NULL && pExportInfo->pLayerIdTranslation) - { - SLayerVisibility visInfo; - visInfo.pLayerVisibilityMask = pExportInfo->pVisibleLayerMask; - visInfo.pLayerIdTranslation = pExportInfo->pLayerIdTranslation; - m_pObjectsTree->Load(f, nDataSizeLeft, pStatObjTable, pMatTable, eEndian, pBox, &visInfo); - } - else - { - m_pObjectsTree->Load(f, nDataSizeLeft, pStatObjTable, pMatTable, eEndian, pBox, NULL); - } - - assert(nDataSizeLeft == (nCurDataSize - objBlockSize)); - } - } - else if (objBlockSize > 0) - { - PakLoadDataUtils::LoadDataFromFile_Seek(objBlockSize, f, nDataSizeLeft, eEndian); - } - - return true; -} - -VisAreaGUID CVisArea::GetGUIDFromFile(byte* f, EEndian eEndian) -{ - SVisAreaChunk* pChunk = (SVisAreaChunk*)f; - SwapEndian(pChunk, sizeof(SVisAreaChunk), eEndian); - - assert(pChunk->nChunkVersion == VISAREA_NODE_CHUNK_VERSION); - if (pChunk->nChunkVersion != VISAREA_NODE_CHUNK_VERSION) - { - return 0; - } - - VisAreaGUID guid = *(VisAreaGUID*)(f + sizeof(SVisAreaChunk)); - SwapEndian(&guid, sizeof(VisAreaGUID), eEndian); - return guid; -} - -////////////////////////////////////////////////////////////////////// -// Segmented World -#if ENGINE_ENABLE_COMPILATION -int CVisArea::GetSegmentData([[maybe_unused]] byte*& pData, [[maybe_unused]] int& nDataSize, [[maybe_unused]] std::vector* pStatObjTable, [[maybe_unused]] std::vector<_smart_ptr>* pMatTable, [[maybe_unused]] std::vector* pStatInstGroupTable, [[maybe_unused]] EEndian eEndian, [[maybe_unused]] SHotUpdateInfo* pExportInfo) -{ - CRY_ASSERT(false); // SegmentedWorld has been removed - return false; -} -#endif -int CSWVisArea::Load(byte*& f, int& nDataSizeLeft, [[maybe_unused]] int nSID, [[maybe_unused]] std::vector* pStatObjTable, [[maybe_unused]] std::vector<_smart_ptr>* pMatTable, EEndian eEndian, [[maybe_unused]] SHotUpdateInfo* pExportInfo, [[maybe_unused]] const Vec2& indexOffset) -{ - int objBlockSize = 0; - if (!LoadHeader_T(f, nDataSizeLeft, eEndian, objBlockSize)) - { - return 0; - } - - CRY_ASSERT(false); // SegmentedWorld has been removed - return false; -} - -#include "TypeInfo_impl.h" -#include "VisAreaCompile_info.h" - - diff --git a/Code/CryEngine/Cry3DEngine/VisAreaCompile_info.h b/Code/CryEngine/Cry3DEngine/VisAreaCompile_info.h deleted file mode 100644 index 9435357dbc..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreaCompile_info.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_VISAREACOMPILE_INFO_H -#define CRYINCLUDE_CRY3DENGINE_VISAREACOMPILE_INFO_H -#pragma once - -STRUCT_INFO_BEGIN(SVisAreaChunk) -STRUCT_VAR_INFO(nChunkVersion, TYPE_INFO(int)) -STRUCT_VAR_INFO(boxArea, TYPE_INFO(AABB)) -STRUCT_VAR_INFO(boxStatics, TYPE_INFO(AABB)) -STRUCT_VAR_INFO(sName, TYPE_ARRAY(32, TYPE_INFO(char))) -STRUCT_VAR_INFO(nObjectsBlockSize, TYPE_INFO(int)) -STRUCT_VAR_INFO(arrConnectionsId, TYPE_ARRAY(30, TYPE_INFO(int))) -STRUCT_VAR_INFO(dwFlags, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(fPortalBlending, TYPE_INFO(float)) -STRUCT_VAR_INFO(vConnNormals, TYPE_ARRAY(2, TYPE_INFO(Vec3))) -STRUCT_VAR_INFO(fHeight, TYPE_INFO(float)) -STRUCT_VAR_INFO(vAmbColor, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(fViewDistRatio, TYPE_INFO(float)) -STRUCT_INFO_END(SVisAreaChunk) - - -#endif // CRYINCLUDE_CRY3DENGINE_VISAREACOMPILE_INFO_H diff --git a/Code/CryEngine/Cry3DEngine/VisAreaMan.cpp b/Code/CryEngine/Cry3DEngine/VisAreaMan.cpp deleted file mode 100644 index bf1fd5ff52..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreaMan.cpp +++ /dev/null @@ -1,2171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "3dEngine.h" -#include "TimeOfDay.h" -#include "AABBSV.h" - -#define DEFAULT_INITIAL_PORTALS 1 -#define DEFAULT_INITIAL_VISAREAS 1 -#define DEFAULT_INITIAL_OCCLAREAS 1 - - -CVisAreaManager::CVisAreaManager() -{ - m_pCurPortal = m_pCurArea = 0; - m_bOutdoorVisible = false; - m_bSkyVisible = false; - m_bSunIsNeeded = false; - m_bOceanVisible = false; - m_pAABBTree = NULL; - - m_visAreas.PreAllocate(DEFAULT_INITIAL_VISAREAS); - m_visAreaColdData.PreAllocate(DEFAULT_INITIAL_VISAREAS); - - m_portals.PreAllocate(DEFAULT_INITIAL_PORTALS); - m_portalColdData.PreAllocate(DEFAULT_INITIAL_PORTALS); - - m_occlAreas.PreAllocate(DEFAULT_INITIAL_OCCLAREAS); - m_occlAreaColdData.PreAllocate(DEFAULT_INITIAL_OCCLAREAS); - - m_segVisAreas.Clear(); - m_segPortals.Clear(); - m_segOcclAreas.Clear(); -} - -void CVisAreaManager::DeleteAllVisAreas() -{ - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - if (m_visAreas.Find(m_lstVisAreas[i]) >= 0) - { - delete m_lstVisAreas[i]; - } - else - { - delete m_lstVisAreas[i]->GetColdData(); - delete m_lstVisAreas[i]; - } - } - - m_visAreas.Clear(); - m_visAreaColdData.Clear(); - m_lstVisAreas.Clear(); - - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - if (m_portals.Find(m_lstPortals[i]) >= 0) - { - delete m_lstPortals[i]; - } - else - { - delete m_lstPortals[i]->GetColdData(); - delete m_lstPortals[i]; - } - } - - m_portals.Clear(); - m_portalColdData.Clear(); - m_lstPortals.Clear(); - - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - if (m_occlAreas.Find(m_lstOcclAreas[i]) >= 0) - { - delete m_lstOcclAreas[i]; - } - else - { - delete m_lstOcclAreas[i]->GetColdData(); - delete m_lstOcclAreas[i]; - } - } - - m_occlAreas.Clear(); - m_occlAreaColdData.Clear(); - m_lstOcclAreas.Clear(); - - stl::free_container(CVisArea::m_lUnavailableAreas); -} - -void SAABBTreeNode::OffsetPosition(const Vec3& delta) -{ - nodeBox.Move(delta); - if (!nodeAreas.Count()) - { - for (int i = 0; i < 2; i++) - { - if (arrChilds[i]) - { - arrChilds[i]->OffsetPosition(delta); - } - } - } -} - -CVisAreaManager::~CVisAreaManager() -{ - if (GetRenderer()) - { - GetRenderer()->EF_ClearDeferredClipVolumesList(); - } - - DeleteAllVisAreas(); - - delete m_pAABBTree; - m_pAABBTree = NULL; -} - -SAABBTreeNode::SAABBTreeNode(PodArray& lstAreas, AABB box, int nRecursion) -{ - memset(this, 0, sizeof(*this)); - - nodeBox = box; - - nRecursion++; - if (nRecursion > 8 || lstAreas.Count() < 8) - { - nodeAreas.AddList(lstAreas); - return; - } - - PodArray lstAreas0, lstAreas1; - Vec3 vSize = nodeBox.GetSize(); - Vec3 vCenter = nodeBox.GetCenter(); - - AABB nodeBox0 = nodeBox; - AABB nodeBox1 = nodeBox; - - if (vSize.x >= vSize.y && vSize.x >= vSize.z) - { - nodeBox0.min.x = vCenter.x; - nodeBox1.max.x = vCenter.x; - } - else if (vSize.y >= vSize.x && vSize.y >= vSize.z) - { - nodeBox0.min.y = vCenter.y; - nodeBox1.max.y = vCenter.y; - } - else - { - nodeBox0.min.z = vCenter.z; - nodeBox1.max.z = vCenter.z; - } - - for (int i = 0; i < lstAreas.Count(); i++) - { - if (Overlap::AABB_AABB(nodeBox0, *lstAreas[i]->GetAABBox())) - { - lstAreas0.Add(lstAreas[i]); - } - - if (Overlap::AABB_AABB(nodeBox1, *lstAreas[i]->GetAABBox())) - { - lstAreas1.Add(lstAreas[i]); - } - } - - if (lstAreas0.Count()) - { - arrChilds[0] = new SAABBTreeNode(lstAreas0, nodeBox0, nRecursion); - } - - if (lstAreas1.Count()) - { - arrChilds[1] = new SAABBTreeNode(lstAreas1, nodeBox1, nRecursion); - } -} - -SAABBTreeNode::~SAABBTreeNode() -{ - delete arrChilds[0]; - delete arrChilds[1]; -} - -SAABBTreeNode* SAABBTreeNode::GetTopNode(const AABB& box, void** pNodeCache) -{ - AABB boxClip = box; - boxClip.ClipToBox(nodeBox); - - SAABBTreeNode* pNode = this; - if (pNodeCache) - { - pNode = (SAABBTreeNode*)*pNodeCache; - if (!pNode || !pNode->nodeBox.ContainsBox(boxClip)) - { - pNode = this; - } - } - - // Find top node containing box. - for (;; ) - { - int i; - for (i = 0; i < 2; i++) - { - if (pNode->arrChilds[i] && pNode->arrChilds[i]->nodeBox.ContainsBox(boxClip)) - { - pNode = pNode->arrChilds[i]; - break; - } - } - if (i == 2) - { - break; - } - } - - if (pNodeCache) - { - *(SAABBTreeNode**)pNodeCache = pNode; - } - return pNode; -} - -bool SAABBTreeNode::IntersectsVisAreas(const AABB& box) -{ - if (nodeBox.IsIntersectBox(box)) - { - if (nodeAreas.Count()) - { // leaf - for (int i = 0; i < nodeAreas.Count(); i++) - { - if (nodeAreas[i]->m_bActive && nodeAreas[i]->m_boxArea.IsIntersectBox(box)) - { - return true; - } - } - } - else - { // node - for (int i = 0; i < 2; i++) - { - if (arrChilds[i]) - { - if (arrChilds[i]->IntersectsVisAreas(box)) - { - return true; - } - } - } - } - } - return false; -} - -int SAABBTreeNode::ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal) -{ - int nClipped = 0; - - if (sphere.radius > FLT_MAX * 0.01f || Overlap::Sphere_AABB(sphere, nodeBox)) - { - if (nodeAreas.Count()) - { // leaf - for (int i = 0; i < nodeAreas.Count(); i++) - { - if (nodeAreas[i]->m_bActive && Overlap::Sphere_AABB(sphere, nodeAreas[i]->m_boxArea)) - { - nClipped += nodeAreas[i]->ClipToVisArea(false, sphere, vNormal); - } - } - } - else - { // node - for (int i = 0; i < 2; i++) - { - if (arrChilds[i]) - { - nClipped += arrChilds[i]->ClipOutsideVisAreas(sphere, vNormal); - } - } - } - } - - return nClipped; -} - -void CVisAreaManager::UpdateAABBTree() -{ - delete m_pAABBTree; - PodArray lstAreas; - lstAreas.AddList(m_lstPortals); - lstAreas.AddList(m_lstVisAreas); - - AABB nodeBox; - nodeBox.min = Vec3(1000000, 1000000, 1000000); - nodeBox.max = -nodeBox.min; - for (int i = 0; i < lstAreas.Count(); i++) - { - nodeBox.Add(*lstAreas[i]->GetAABBox()); - } - - m_pAABBTree = new SAABBTreeNode(lstAreas, nodeBox); -} - -bool CVisAreaManager::IsEntityVisible(IRenderNode* pEnt) -{ - if (GetCVars()->e_Portals == 3) - { - return true; - } - - if (!pEnt->GetEntityVisArea()) - { - return IsOutdoorAreasVisible(); - } - - return true; -} - -void CVisAreaManager::SetCurAreas(const SRenderingPassInfo& passInfo) -{ - m_pCurArea = 0; - m_pCurPortal = 0; - - if (!GetCVars()->e_Portals) - { - return; - } - - if (!m_pAABBTree) - { - UpdateAABBTree(); - } - - CVisArea* pFound = m_pAABBTree->FindVisarea(passInfo.GetCamera().GetOccPos()); - -#ifdef _DEBUG - - // find camera portal id - for (int v = 0; v < m_lstPortals.Count(); v++) - { - if (m_lstPortals[v]->m_bActive && m_lstPortals[v]->IsPointInsideVisArea(passInfo.GetCamera().GetOccPos())) - { - m_pCurPortal = m_lstPortals[v]; - break; - } - } - - // if not inside any portal - try to find area - if (!m_pCurPortal) - { - // int nFoundAreasNum = 0; - - // find camera area - for (int nVolumeId = 0; nVolumeId < m_lstVisAreas.Count(); nVolumeId++) - { - if (m_lstVisAreas[nVolumeId]->IsPointInsideVisArea(passInfo.GetCamera().GetOccPos())) - { - // nFoundAreasNum++; - m_pCurArea = m_lstVisAreas[nVolumeId]; - break; - } - } - - // if(nFoundAreasNum>1) // if more than one area found - set cur area to undefined - { // todo: try to set joining portal as current - // m_pCurArea = 0; - } - } - - assert(pFound == m_pCurArea || pFound == m_pCurPortal); - -#endif // _DEBUG - - if (pFound) - { - if (pFound->IsPortal()) - { - m_pCurPortal = pFound; - } - else - { - m_pCurArea = pFound; - } - } - - // camera is in outdoors - m_lstActiveEntransePortals.Clear(); - if (!m_pCurArea && !m_pCurPortal) - { - MakeActiveEntransePortalsList(&passInfo.GetCamera(), m_lstActiveEntransePortals, 0, passInfo); - } - - /* - if(m_pCurArea) - { - IVisArea * arrAreas[8]; - int nres = m_pCurArea->GetVisAreaConnections(arrAreas, 8); - nres=nres; - } - DefineTrees();*/ - - /* if(GetCVars()->e_Portals == 4) - { - if(m_pCurPortal) - { - IVisArea * arrAreas[64]; - int nConnections = m_pCurPortal->GetVisAreaConnections(arrAreas,64); - PrintMessage("CurPortal = %s, nConnections = %d", m_pCurPortal->m_sName, nConnections); - } - - if(m_pCurArea) - { - IVisArea * arrAreas[64]; - int nConnections = m_pCurArea->GetVisAreaConnections(arrAreas,64); - PrintMessage("CurArea = %s, nRes = %d", m_pCurArea->m_sName, nConnections); - } - }*/ -} - -bool CVisAreaManager::IsSkyVisible() -{ - return m_bSkyVisible; -} - -bool CVisAreaManager::IsOceanVisible() -{ - return m_bOceanVisible; -} - -bool CVisAreaManager::IsOutdoorAreasVisible() -{ - if (!m_pCurArea && !m_pCurPortal) - { - m_bOutdoorVisible = true; - return m_bOutdoorVisible; // camera not in the areas - } - - if (m_pCurPortal && m_pCurPortal->m_lstConnections.Count() == 1) - { - m_bOutdoorVisible = true; - return m_bOutdoorVisible; // camera is in exit portal - } - - if (m_bOutdoorVisible) - { - return true; // exit is visible - } - // note: outdoor camera is no modified in this case - return false; -} - -/*void CVisAreaManager::SetAreaFogVolume(CTerrain * pTerrain, CVisArea * pVisArea) -{ - pVisArea->m_pFogVolume=0; - for(int f=0; fGetFogVolumes().Count(); f++) - { - const Vec3 & v1Min = Get3DEngine()->GetFogVolumes()[f].box.min; - const Vec3 & v1Max = Get3DEngine()->GetFogVolumes()[f].box.max; - const Vec3 & v2Min = pVisArea->m_boxArea.min; - const Vec3 & v2Max = pVisArea->m_boxArea.max; - - if(v1Max.x>v2Min.x && v2Max.x>v1Min.x) - if(v1Max.y>v2Min.y && v2Max.y>v1Min.y) - if(v1Max.z>v2Min.z && v2Max.z>v1Min.z) - if(!Get3DEngine()->GetFogVolumes()[f].bOcean) - { - Vec3 arrVerts3d[8] = - { - Vec3(v1Min.x,v1Min.y,v1Min.z), - Vec3(v1Min.x,v1Max.y,v1Min.z), - Vec3(v1Max.x,v1Min.y,v1Min.z), - Vec3(v1Max.x,v1Max.y,v1Min.z), - Vec3(v1Min.x,v1Min.y,v1Max.z), - Vec3(v1Min.x,v1Max.y,v1Max.z), - Vec3(v1Max.x,v1Min.y,v1Max.z), - Vec3(v1Max.x,v1Max.y,v1Max.z) - }; - - bool bIntersect = false; - for(int i=0; i<8; i++) - if(pVisArea->IsPointInsideVisArea(arrVerts3d[i])) - { - bIntersect = true; - break; - } - - if(!bIntersect) - if(pVisArea->IsPointInsideVisArea((v1Min+v1Max)*0.5f)) - bIntersect = true; - - if(!bIntersect) - { - for(int i=0; im_lstShapePoints.Count(); i++) - if(Get3DEngine()->GetFogVolumes()[f].IsInsideBBox(pVisArea->m_lstShapePoints[i])) - { - bIntersect = true; - break; - } - } - - if(!bIntersect) - { - Vec3 vCenter = (pVisArea->m_boxArea.min+pVisArea->m_boxArea.max)*0.5f; - if(Get3DEngine()->GetFogVolumes()[f].IsInsideBBox(vCenter)) - bIntersect = true; - } - - if(bIntersect) - { - pVisArea->m_pFogVolume = &Get3DEngine()->GetFogVolumes()[f]; - Get3DEngine()->GetFogVolumes()[f].bIndoorOnly = true; - pTerrain->UnregisterFogVolumeFromOutdoor(&Get3DEngine()->GetFogVolumes()[f]); - break; - } - } - } -}*/ - -void CVisAreaManager::PortalsDrawDebug() -{ - UpdateConnections(); - /* - if(m_pCurArea) - { - for(int p=0; pm_lstConnections.Count(); p++) - { - CVisArea * pPortal = m_pCurArea->m_lstConnections[p]; - float fBlink = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f)>0.5f ? 1.0f : 0.0f; - float fError = pPortal->IsPortalValid() ? 1.0f : fBlink; - GetRenderer()->SetMaterialColor(fError,fError*(pPortal->m_lstConnections.Count()<2),0,0.25f); - DrawBBox(pPortal->m_boxArea.min, pPortal->m_boxArea.max, DPRIM_SOLID_BOX); - GetRenderer()->DrawLabel((pPortal->m_boxArea.min+ pPortal->m_boxArea.max)*0.5f, - 2,pPortal->m_sName); - } - } - else*/ - { - // debug draw areas - GetRenderer()->SetMaterialColor(0, 1, 0, 0.25f); - Vec3 oneVec(1, 1, 1); - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - DrawBBox(m_lstVisAreas[v]->m_boxArea.min, m_lstVisAreas[v]->m_boxArea.max);//, DPRIM_SOLID_BOX); - GetRenderer()->DrawLabelEx((m_lstVisAreas[v]->m_boxArea.min + m_lstVisAreas[v]->m_boxArea.max) * 0.5f, - 1, (float*)&oneVec, 0, 1, m_lstVisAreas[v]->GetName()); - - GetRenderer()->SetMaterialColor(0, 1, 0, 0.25f); - DrawBBox(m_lstVisAreas[v]->m_boxStatics, Col_LightGray); - } - - // debug draw portals - for (int v = 0; v < m_lstPortals.Count(); v++) - { - CVisArea* pPortal = m_lstPortals[v]; - - float fBlink = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f) > 0.5f ? 1.0f : 0.0f; - float fError = pPortal->IsPortalValid() ? 1.f : fBlink; - - ColorB col( - (int)clamp_tpl(fError * 255.0f, 0.0f, 255.0f), - (int)clamp_tpl(fError * (pPortal->m_lstConnections.Count() < 2) * 255.0f, 0.0f, 255.0f), - 0, - 64); - DrawBBox(pPortal->m_boxArea.min, pPortal->m_boxArea.max, col); - - GetRenderer()->DrawLabelEx((pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f, - 1, (float*)&oneVec, 0, 1, pPortal->GetName()); - - Vec3 vCenter = (pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f; - DrawBBox(vCenter - Vec3(0.1f, 0.1f, 0.1f), vCenter + Vec3(0.1f, 0.1f, 0.1f)); - - int nConnections = pPortal->m_lstConnections.Count(); - if (nConnections == 1) - { - col = ColorB(0, 255, 0, 64); - } - else - { - col = ColorB(0, 0, 255, 64); - } - - for (int i = 0; i < nConnections && i < 2; i++) - { - DrawLine(vCenter, vCenter + pPortal->m_vConnNormals[i], col); - } - - DrawBBox(pPortal->m_boxStatics.min, pPortal->m_boxStatics.max, col); - } - - /* - // debug draw area shape - GetRenderer()->SetMaterialColor(0,0,1,0.25f); - for(int v=0; vm_lstShapePoints.Count(); p++) - GetRenderer()->DrawLabel(m_lstVisAreas[v]->m_lstShapePoints[p], 2,"%d", p); - for(int v=0; vm_lstShapePoints.Count(); p++) - GetRenderer()->DrawLabel(m_lstPortals[v]->m_lstShapePoints[p], 2,"%d", p);*/ - } -} - - -void CVisAreaManager::DrawVisibleSectors(const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - for (int i = 0; i < m_lstVisibleAreas.Count(); i++) - { - CVisArea* pArea = m_lstVisibleAreas[i]; - if (pArea->m_pObjectsTree) - { - for (int c = 0; c < pArea->m_lstCurCamerasLen; c++) - { - rendItemSorter.IncreaseOctreeCounter(); - // create a new RenderingPassInfo object, which a camera matching the visarea - pArea->m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS, SRenderingPassInfo::CreateTempRenderingInfo(CVisArea::s_tmpCameras[pArea->m_lstCurCamerasIdx + c], passInfo), rendItemSorter); - } - } - } - - rendItemSorter.IncreaseGroupCounter(); -} - - -void CVisAreaManager::CheckVis(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE_LEGACYONLY; - AZ_TRACE_METHOD(); - - if (passInfo.IsGeneralPass()) - { - m_bOutdoorVisible = false; - m_bSkyVisible = false; - m_bOceanVisible = false; - CVisArea::s_tmpCameras.Clear(); - } - - m_lstOutdoorPortalCameras.Clear(); - m_lstVisibleAreas.Clear(); - m_bSunIsNeeded = false; - GetRenderer()->EF_ClearDeferredClipVolumesList(); - - SetCurAreas(passInfo); - - CCamera camRoot = passInfo.GetCamera(); - camRoot.m_ScissorInfo.x1 = 0; - camRoot.m_ScissorInfo.y1 = 0; - camRoot.m_ScissorInfo.x2 = GetRenderer()->GetWidth(); // todo: use values from camera - camRoot.m_ScissorInfo.y2 = GetRenderer()->GetHeight(); - - if (GetCVars()->e_Portals == 3) - { // draw everything for debug - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - if (camRoot.IsAABBVisible_F(AABB(m_lstVisAreas[i]->m_boxArea.min, m_lstVisAreas[i]->m_boxArea.max))) - { - m_lstVisAreas[i]->PreRender(0, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - } - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - if (camRoot.IsAABBVisible_F(AABB(m_lstPortals[i]->m_boxArea.min, m_lstPortals[i]->m_boxArea.max))) - { - m_lstPortals[i]->PreRender(0, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - } - } - } - else - { - if (passInfo.IsRecursivePass()) - { // use another starting point for reflections - CVisArea* pVisArea = (CVisArea*)GetVisAreaFromPos(camRoot.GetOccPos()); - if (pVisArea) - { - pVisArea->PreRender(3, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - } - } - else if (m_pCurArea) - { // camera inside some sector - m_pCurArea->PreRender(GetCVars()->e_PortalsMaxRecursion, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - - for (int ii = 0; ii < m_lstOutdoorPortalCameras.Count(); ii++) // process all exit portals - { // for each portal build list of potentially visible entrances into other areas - MakeActiveEntransePortalsList(&m_lstOutdoorPortalCameras[ii], m_lstActiveEntransePortals, (CVisArea*)m_lstOutdoorPortalCameras[ii].m_pPortal, passInfo); - for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++) // entrance into another building is visible - { - m_lstActiveEntransePortals[i]->PreRender(i == 0 ? 5 : 1, - m_lstOutdoorPortalCameras[ii], 0, m_pCurPortal, 0, 0, 0, 0, m_lstVisibleAreas, passInfo); - } - } - - // reset scissor if skybox is visible also thru skyboxonly portal - if (m_bSkyVisible && m_lstOutdoorPortalCameras.Count() == 1) - { - m_lstOutdoorPortalCameras[0].m_ScissorInfo.x1 = - m_lstOutdoorPortalCameras[0].m_ScissorInfo.x2 = - m_lstOutdoorPortalCameras[0].m_ScissorInfo.y1 = - m_lstOutdoorPortalCameras[0].m_ScissorInfo.y2 = 0; - } - } - else if (m_pCurPortal) - { // camera inside some portal - m_pCurPortal->PreRender(GetCVars()->e_PortalsMaxRecursion - 1, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - - if (m_pCurPortal->m_lstConnections.Count() == 1) - { - m_lstOutdoorPortalCameras.Clear(); // camera in outdoor - } - if (m_pCurPortal->m_lstConnections.Count() == 1 || m_lstOutdoorPortalCameras.Count()) - { // if camera is in exit portal or exit is visible - MakeActiveEntransePortalsList(m_lstOutdoorPortalCameras.Count() ? &m_lstOutdoorPortalCameras[0] : &camRoot, - m_lstActiveEntransePortals, - m_lstOutdoorPortalCameras.Count() ? (CVisArea*)m_lstOutdoorPortalCameras[0].m_pPortal : m_pCurPortal, passInfo); - for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++) // entrance into another building is visible - { - m_lstActiveEntransePortals[i]->PreRender(i == 0 ? 5 : 1, - m_lstOutdoorPortalCameras.Count() ? m_lstOutdoorPortalCameras[0] : camRoot, 0, m_pCurPortal, 0, 0, 0, 0, m_lstVisibleAreas, passInfo); - } - // m_lstOutdoorPortalCameras.Clear(); // otherwise ocean in fleet was not scissored - } - } - else if (m_lstActiveEntransePortals.Count()) - { // camera in outdoors - process visible entrance portals - for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++) - { - m_lstActiveEntransePortals[i]->PreRender(5, camRoot, 0, m_lstActiveEntransePortals[i], &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo); - } - m_lstActiveEntransePortals.Clear(); - - // do not recurse to another building since we already processed all potential entrances - m_lstOutdoorPortalCameras.Clear(); // use default camera - m_bOutdoorVisible = true; - } - } - - if (GetCVars()->e_Portals == 2) - { - PortalsDrawDebug(); - } -} - -void CVisAreaManager::ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName) -{ - // bool bFound = false; - - for (int v = 0; v < m_lstPortals.Count(); v++) - { - AABB aabb; - aabb.min = m_lstPortals[v]->m_boxArea.min - Vec3(0.5f, 0.5f, 0.1f); - aabb.max = m_lstPortals[v]->m_boxArea.max + Vec3(0.5f, 0.5f, 0.0f); - - if (Overlap::Point_AABB(vPos, aabb)) - { - m_lstPortals[v]->m_bActive = bActivate; - - // switch to PrintComment once portals activation is working stable - PrintMessage("I3DEngine::ActivatePortal(): Portal %s is %s by entity %s at position(%.1f,%.1f,%.1f)", - m_lstPortals[v]->GetName(), bActivate ? "Enabled" : "Disabled", szEntityName, vPos.x, vPos.y, vPos.z); - - // bFound = true; - } - } - - /* - if(!bFound) - { - PrintComment("I3DEngine::ActivatePortal(): Portal not found for entity %s at position(%.1f,%.1f,%.1f)", - szEntityName, vPos.x, vPos.y, vPos.z); - } - */ -} -/* -bool CVisAreaManager::IsEntityInVisibleArea(IRenderNodeState * pRS) -{ - if( pRS && pRS->plstVisAreaId && pRS->plstVisAreaId->Count() ) - { - PodArray * pVisAreas = pRS->plstVisAreaId; - for(int n=0; nCount(); n++) - if( m_lstVisAreas[pVisAreas->GetAt(n)].m_nVisFrameId==passInfo.GetFrameID() ) - break; - - if(n==pVisAreas->Count()) - return false; // no visible areas - } - else - return false; // entity is not inside - - return true; -} */ - -bool CVisAreaManager::IsValidVisAreaPointer(CVisArea* pVisArea) -{ - if (m_lstVisAreas.Find(pVisArea) < 0 && - m_lstPortals.Find(pVisArea) < 0 && - m_lstOcclAreas.Find(pVisArea) < 0) - { - return false; - } - - return true; -} - -//This is only called from the editor, so pVisArea will not be pool allocated by type -bool CVisAreaManager::DeleteVisArea(CVisArea* pVisArea) -{ - bool bFound = false; - if (m_lstVisAreas.Delete(pVisArea) || m_lstPortals.Delete(pVisArea) || m_lstOcclAreas.Delete(pVisArea)) - { - delete pVisArea; - bFound = true; - } - - m_lstActiveOcclVolumes.Delete(pVisArea); - m_lstIndoorActiveOcclVolumes.Delete(pVisArea); - m_lstActiveEntransePortals.Delete(pVisArea); - - m_pCurArea = 0; - m_pCurPortal = 0; - UpdateConnections(); - - delete m_pAABBTree; - m_pAABBTree = NULL; - - return bFound; -} - -/*void CVisAreaManager::LoadVisAreaShapeFromXML(XmlNodeRef pDoc) -{ - for(int i=0; ifindChild("Objects"); - if (pObjectsNode) - { - for (int i = 0; i < pObjectsNode->getChildCount(); i++) - { - XmlNodeRef pNode = pObjectsNode->getChild(i); - if (pNode->isTag("Object")) - { - const char * pType = pNode->getAttr("Type"); - if (strstr(pType,"OccluderArea") || strstr(pType,"VisArea") || strstr(pType,"Portal")) - { - CVisArea * pArea = new CVisArea(); - - pArea->m_boxArea.max=SetMinBB(); - pArea->m_boxArea.min=SetMaxBB(); - - // set name - strcpy(pArea->m_sName, pNode->getAttr("Name")); - strlwr(pArea->m_sName); - - // set height - pNode->getAttr("Height",pArea->m_fHeight); - - // set ambient color - pNode->getAttr("AmbientColor", pArea->m_vAmbColor); - - // set dynamic ambient color -// pNode->getAttr("DynAmbientColor", pArea->m_vDynAmbColor); - - // set SkyOnly flag - pNode->getAttr("SkyOnly", pArea->m_bSkyOnly); - - // set AfectedByOutLights flag - pNode->getAttr("AffectedBySun", pArea->m_bAfectedByOutLights); - - // set ViewDistRatio - pNode->getAttr("ViewDistRatio", pArea->m_fViewDistRatio); - - // set DoubleSide flag - pNode->getAttr("DoubleSide", pArea->m_bDoubleSide); - - // set UseInIndoors flag - pNode->getAttr("UseInIndoors", pArea->m_bUseInIndoors); - - if(strstr(pType, "OccluderArea")) - m_lstOcclAreas.Add(pArea); - else if(strstr(pArea->m_sName,"portal") || strstr(pType,"Portal")) - m_lstPortals.Add(pArea); - else - m_lstVisAreas.Add(pArea); - - // load vertices - XmlNodeRef pPointsNode = pNode->findChild("Points"); - if (pPointsNode) - for (int i = 0; i < pPointsNode->getChildCount(); i++) - { - XmlNodeRef pPointNode = pPointsNode->getChild(i); - - Vec3 vPos; - if (pPointNode->isTag("Point") && pPointNode->getAttr("Pos", vPos)) - { - pArea->m_lstShapePoints.Add(vPos); - pArea->m_boxArea.max.CheckMax(vPos); - pArea->m_boxArea.min.CheckMin(vPos); - pArea->m_boxArea.max.CheckMax(vPos+Vec3(0,0,pArea->m_fHeight)); - pArea->m_boxArea.min.CheckMin(vPos+Vec3(0,0,pArea->m_fHeight)); - } - } - pArea->UpdateGeometryBBox(); - } - } - } - } - - // load area boxes to support old way -// LoadVisAreaBoxFromXML(pDoc); -}*/ - - -//THIS SHOULD ONLY BE CALLED BY THE EDITOR -void CVisAreaManager::UpdateVisArea(CVisArea* pArea, const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info) -{ // on first update there will be nothing to delete, area will be added into list only in this function - - // If pArea is in these lists, then remove it. - const VisAreaGUID& areaGUID = pArea->GetGUID(); - for (int i = 0; i < m_lstVisAreas.Count(); ++i) - { - CVisArea* pAreaInList = m_lstVisAreas[i]; - if (areaGUID == pAreaInList->GetGUID()) - { - m_lstVisAreas.Delete(i); - --i; - } - } - for (int i = 0; i < m_lstPortals.Count(); ++i) - { - CVisArea* pPortalInList = m_lstPortals[i]; - if (areaGUID == pPortalInList->GetGUID()) - { - m_lstPortals.Delete(i); - --i; - } - } - for (int i = 0; i < m_lstOcclAreas.Count(); ++i) - { - CVisArea* pOccAreaInList = m_lstOcclAreas[i]; - if (areaGUID == pOccAreaInList->GetGUID()) - { - m_lstOcclAreas.Delete(i); - --i; - } - } - - SGenericColdData* pColdData = pArea->GetColdData(); - if (pColdData != NULL) - { - if (pColdData->m_dataType == eCDT_Portal) - { - SPortalColdData* pPortalColdData = static_cast(pColdData); - if (pPortalColdData->m_pRNTmpData) - { - Get3DEngine()->FreeRNTmpData(&pPortalColdData->m_pRNTmpData); - pPortalColdData->m_pRNTmpData = NULL; - } - } - delete pArea->GetColdData(); - pArea->SetColdDataPtr(NULL); - } - - - SGenericColdData* pColdDataPtr = NULL; - - char sTemp[64]; - cry_strcpy(sTemp, szName); - _strlwr_s(sTemp, sizeof(sTemp)); - - bool bPortal = false; - bool bVisArea = false; - bool bOcclArea = false; - - //TODO: Refactor with code below so it's not horrible - if (strstr(sTemp, "portal")) - { - pColdDataPtr = new SPortalColdData(); - bPortal = true; - } - else if (strstr(sTemp, "visarea")) - { - pColdDataPtr = new SGenericColdData(); - bVisArea = true; - } - else if (strstr(sTemp, "occlarea")) - { - pColdDataPtr = new SGenericColdData(); - bOcclArea = true; - } - else - { - pColdDataPtr = new SGenericColdData(); - } - - assert(pColdDataPtr); - pArea->SetColdDataPtr(pColdDataPtr); - - pArea->Update(pPoints, nCount, sTemp, info); - - if (bPortal) - { - if (pArea->m_lstConnections.Count() == 1) - { - pArea->UpdateGeometryBBox(); - } - - m_lstPortals.Add(pArea); - } - else if (bVisArea) - { - m_lstVisAreas.Add(pArea); - } - else if (bOcclArea) - { - m_lstOcclAreas.Add(pArea); - } - - UpdateConnections(); - - delete m_pAABBTree; - m_pAABBTree = NULL; -} - -void CVisAreaManager::UpdateConnections() -{ - // Reset connectivity - for (int p = 0; p < m_lstPortals.Count(); p++) - { - m_lstPortals[p]->m_lstConnections.Clear(); - } - - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - m_lstVisAreas[v]->m_lstConnections.Clear(); - } - - // Init connectivity - check intersection of all areas and portals - for (int p = 0; p < m_lstPortals.Count(); p++) - { - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - if (m_lstVisAreas[v]->IsPortalIntersectAreaInValidWay(m_lstPortals[p])) - { // if bboxes intersect - m_lstVisAreas[v]->m_lstConnections.Add(m_lstPortals[p]); - m_lstPortals[p]->m_lstConnections.Add(m_lstVisAreas[v]); - - // set portal direction - Vec3 vNormal = m_lstVisAreas[v]->GetConnectionNormal(m_lstPortals[p]); - if (m_lstPortals[p]->m_lstConnections.Count() <= 2) - { - m_lstPortals[p]->m_vConnNormals[m_lstPortals[p]->m_lstConnections.Count() - 1] = vNormal; - } - } - } - } -} - -void CVisAreaManager::MoveObjectsIntoList(PodArray* plstVisAreasEntities, const AABB& boxArea, bool bRemoveObjects) -{ - for (int p = 0; p < m_lstPortals.Count(); p++) - { - if (m_lstPortals[p]->m_pObjectsTree && Overlap::AABB_AABB(m_lstPortals[p]->m_boxArea, boxArea)) - { - m_lstPortals[p]->m_pObjectsTree->MoveObjectsIntoList(plstVisAreasEntities, bRemoveObjects ? NULL : &boxArea, bRemoveObjects); - } - } - - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - if (m_lstVisAreas[v]->m_pObjectsTree && Overlap::AABB_AABB(m_lstVisAreas[v]->m_boxArea, boxArea)) - { - m_lstVisAreas[v]->m_pObjectsTree->MoveObjectsIntoList(plstVisAreasEntities, bRemoveObjects ? NULL : &boxArea, bRemoveObjects); - } - } -} - -bool CVisAreaManager::IntersectsVisAreas(const AABB& box, void** pNodeCache) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pAABBTree) - { - UpdateAABBTree(); - } - SAABBTreeNode* pTopNode = m_pAABBTree->GetTopNode(box, pNodeCache); - return pTopNode->IntersectsVisAreas(box); -} - -bool CVisAreaManager::ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal, void* pNodeCache) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pAABBTree) - { - UpdateAABBTree(); - } - AABB box(sphere.center - Vec3(sphere.radius), sphere.center + Vec3(sphere.radius)); - SAABBTreeNode* pTopNode = m_pAABBTree->GetTopNode(box, &pNodeCache); - return pTopNode->ClipOutsideVisAreas(sphere, vNormal) > 0; -} - -//This is used by the editor. Use the visareas pool for all areas, so prefetching -// is still safe. -CVisArea* CVisAreaManager::CreateVisArea(VisAreaGUID visGUID) -{ - return new CVisArea(visGUID); -} - -bool CVisAreaManager::IsEntityVisAreaVisibleReqursive(CVisArea* pVisArea, int nMaxReqursion, PodArray* pUnavailableAreas, const CDLight* pLight, const SRenderingPassInfo& passInfo) -{ - int nAreaId = pUnavailableAreas->Count(); - pUnavailableAreas->Add(pVisArea); - - bool bFound = false; - if (pVisArea) - { // check is lsource area was rendered in prev frame - if (abs(pVisArea->m_nRndFrameId - passInfo.GetFrameID()) > 2) - { - if (nMaxReqursion > 1) - { - for (int n = 0; n < pVisArea->m_lstConnections.Count(); n++) - { // loop other sectors - CVisArea* pNeibArea = (CVisArea*)pVisArea->m_lstConnections[n]; - if (-1 == pUnavailableAreas->Find(pNeibArea) && - (!pLight || Overlap::Sphere_AABB(Sphere(pLight->m_Origin, pLight->m_fRadius), *pNeibArea->GetAABBox()))) - { - if (IsEntityVisAreaVisibleReqursive(pNeibArea, nMaxReqursion - 1, pUnavailableAreas, pLight, passInfo)) - { - bFound = true; - break; - }//if visible - } - }// for - } - } - else - { - bFound = true; - } - } - else if (IsOutdoorAreasVisible()) //Indirect - outdoor can be a problem! - { - bFound = true; - } - - pUnavailableAreas->Delete(nAreaId); - return bFound; -} - -bool CVisAreaManager::IsEntityVisAreaVisible(IRenderNode* pEnt, int nMaxReqursion, const CDLight* pLight, const SRenderingPassInfo& passInfo) -{ - if (!pEnt) - { - return false; - } - - PodArray& lUnavailableAreas = m_tmpLstUnavailableAreas; - lUnavailableAreas.Clear(); - - lUnavailableAreas.PreAllocate(nMaxReqursion, 0); - - return IsEntityVisAreaVisibleReqursive((CVisArea*)pEnt->GetEntityVisArea(), nMaxReqursion, &lUnavailableAreas, pLight, passInfo); - /* - if(pEnt->GetEntityVisArea()) - { - if(pEnt->GetEntityVisArea())//->IsPortal()) - { // check is lsource area was rendered in prev frame - CVisArea * pVisArea = pEnt->GetEntityVisArea(); - int nRndFrameId = passInfo.GetFrameID(); - if(abs(pVisArea->m_nRndFrameId - nRndFrameId)>2) - { - if(!nCheckNeighbors) - return false; // this area is not visible - - // try neibhour areas - bool bFound = false; - if(pEnt->GetEntityVisArea()->IsPortal()) - { - CVisArea * pPort = pEnt->GetEntityVisArea(); - for(int n=0; nm_lstConnections.Count(); n++) - { // loop other sectors - CVisArea * pNeibArea = (CVisArea*)pPort->m_lstConnections[n]; - if(abs(pNeibArea->m_nRndFrameId - passInfo.GetFrameID())<=2) - { - bFound=true; - break; - } - } - } - else - { - for(int t=0; !bFound && tm_lstConnections.Count(); t++) - { // loop portals - CVisArea * pPort = (CVisArea*)pVisArea->m_lstConnections[t]; - if(abs(pPort->m_nRndFrameId - passInfo.GetFrameID())<=2) - { - bFound=true; - break; - } - - for(int n=0; nm_lstConnections.Count(); n++) - { // loop other sectors - CVisArea * pNeibArea = (CVisArea*)pPort->m_lstConnections[n]; - if(abs(pNeibArea->m_nRndFrameId - passInfo.GetFrameID())<=2) - { - bFound=true; - break; - } - } - } - } - - if(!bFound) - return false; - - return true; - } - } - else - return false; // not visible - } - else if(!IsOutdoorAreasVisible()) - return false; - - return true; - */ -} - -int __cdecl CVisAreaManager__CmpDistToPortal(const void* v1, const void* v2) -{ - CVisArea* p1 = *((CVisArea**)v1); - CVisArea* p2 = *((CVisArea**)v2); - - if (!p1 || !p2) - { - return 0; - } - - if (p1->m_fDistance > p2->m_fDistance) - { - return 1; - } - else if (p1->m_fDistance < p2->m_fDistance) - { - return -1; - } - - return 0; -} - -void CVisAreaManager::MakeActiveEntransePortalsList(const CCamera* pCamera, PodArray& lstActiveEntransePortals, CVisArea* pThisPortal, const SRenderingPassInfo& passInfo) -{ - lstActiveEntransePortals.Clear(); - float fZoomFactor = pCamera ? (0.2f + 0.8f * (RAD2DEG(pCamera->GetFov()) / 90.f)) : 1.f; - - for (int nPortalId = 0; nPortalId < m_lstPortals.Count(); nPortalId++) - { - CVisArea* pPortal = m_lstPortals[nPortalId]; - - if (pPortal->m_lstConnections.Count() == 1 && pPortal != pThisPortal && pPortal->IsActive() && !pPortal->m_bSkyOnly) - { - if (!pCamera || pCamera->IsAABBVisible_F(pPortal->m_boxStatics)) - { - Vec3 vNormal = pPortal->m_lstConnections[0]->GetConnectionNormal(pPortal); - Vec3 vCenter = (pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f; - if (vNormal.Dot(vCenter - (pCamera ? pCamera->GetPosition() : passInfo.GetCamera().GetPosition())) < 0) - { - continue; - } - /* - if(pCurPortal) - { - vNormal = pCurPortal->m_vConnNormals[0]; - if(vNormal.Dot(vCenter - curCamera.GetPosition())<0) - continue; - } - */ - pPortal->m_fDistance = pPortal->m_boxArea.GetDistance(pCamera ? pCamera->GetPosition() : passInfo.GetCamera().GetPosition()); - - float fRadius = (pPortal->m_boxArea.max - pPortal->m_boxArea.min).GetLength() * 0.5f; - if (pPortal->m_fDistance * fZoomFactor > fRadius * pPortal->m_fViewDistRatio * GetFloatCVar(e_ViewDistRatioPortals) / 60.f) - { - continue; - } - - SPortalColdData* pColdData = static_cast(pPortal->GetColdData()); - - Get3DEngine()->CheckCreateRNTmpData(&pColdData->m_pRNTmpData, NULL, passInfo); - - // test occlusion - if (GetObjManager()->IsBoxOccluded(pPortal->m_boxStatics, pPortal->m_fDistance, &pColdData->m_pRNTmpData->userData.m_OcclState, false, eoot_PORTAL, passInfo)) - { - continue; - } - - lstActiveEntransePortals.Add(pPortal); - - // if(GetCVars()->e_Portals==3) - // DrawBBox(pPortal->m_boxStatics.min, pPortal->m_boxStatics.max); - } - } - } - - // sort by distance - if (lstActiveEntransePortals.Count()) - { - qsort(&lstActiveEntransePortals[0], lstActiveEntransePortals.Count(), - sizeof(lstActiveEntransePortals[0]), CVisAreaManager__CmpDistToPortal); - // m_pCurPortal = lstActiveEntransePortals[0]; - } -} - -void CVisAreaManager::DrawOcclusionAreasIntoCBuffer([[maybe_unused]] CCullBuffer* pCBuffer, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - m_lstActiveOcclVolumes.Clear(); - m_lstIndoorActiveOcclVolumes.Clear(); - -#if defined(OCCLUSIONCULLER_W) - m_allActiveVerts.resize(0); - m_allActiveVerts.reserve(m_lstOcclAreas.Count()); -#endif - - float fZoomFactor = 0.2f + 0.8f * (RAD2DEG(passInfo.GetCamera().GetFov()) / 90.f); - float fDistRatio = GetFloatCVar(e_OcclusionVolumesViewDistRatio) / fZoomFactor; - - if (GetCVars()->e_OcclusionVolumes) - { - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - CVisArea* pArea = m_lstOcclAreas[i]; - if (passInfo.GetCamera().IsAABBVisible_E(pArea->m_boxArea)) - { - float fRadius = (pArea->m_boxArea.min - pArea->m_boxArea.max).GetLength(); - Vec3 vPos = (pArea->m_boxArea.min + pArea->m_boxArea.max) * 0.5f; - float fDist = passInfo.GetCamera().GetPosition().GetDistance(vPos); - if (fDist < fRadius * pArea->m_fViewDistRatio * fDistRatio && pArea->m_lstShapePoints.Count() >= 2) - { - int nRecursiveLevel = passInfo.GetRecursiveLevel(); - if (!pArea->m_arrOcclCamera[nRecursiveLevel]) - { - pArea->m_arrOcclCamera[nRecursiveLevel] = new CCamera; - } - *pArea->m_arrOcclCamera[nRecursiveLevel] = passInfo.GetCamera(); - - SActiveVerts activeVerts; - - if (pArea->m_lstShapePoints.Count() == 4) - { - activeVerts.arrvActiveVerts[0] = pArea->m_lstShapePoints[0]; - activeVerts.arrvActiveVerts[1] = pArea->m_lstShapePoints[1]; - activeVerts.arrvActiveVerts[2] = pArea->m_lstShapePoints[2]; - activeVerts.arrvActiveVerts[3] = pArea->m_lstShapePoints[3]; - } - else - { - activeVerts.arrvActiveVerts[0] = pArea->m_lstShapePoints[0]; - activeVerts.arrvActiveVerts[1] = pArea->m_lstShapePoints[0] + Vec3(0, 0, pArea->m_fHeight); - activeVerts.arrvActiveVerts[2] = pArea->m_lstShapePoints[1] + Vec3(0, 0, pArea->m_fHeight); - activeVerts.arrvActiveVerts[3] = pArea->m_lstShapePoints[1]; - } - - Plane plane; - plane.SetPlane(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[2], activeVerts.arrvActiveVerts[1]); - - if (plane.DistFromPlane(passInfo.GetCamera().GetPosition()) < 0) - { - std::swap(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[3]); - std::swap(activeVerts.arrvActiveVerts[1], activeVerts.arrvActiveVerts[2]); - } - else if (!pArea->m_bDoubleSide) - { - continue; - } - - // GetRenderer()->SetMaterialColor(1,0,0,1); - pArea->UpdatePortalCameraPlanes(*pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()], activeVerts.arrvActiveVerts, false, passInfo); - - // make far plane never clip anything - -#if defined(OCCLUSIONCULLER_W) - m_allActiveVerts.push_back(activeVerts); -#endif - - Plane newNearPlane; - newNearPlane.SetPlane(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[2], activeVerts.arrvActiveVerts[1]); - pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()]->SetFrustumPlane(FR_PLANE_NEAR, newNearPlane); - - Plane newFarPlane; - newFarPlane.SetPlane(Vec3(0, 1, -1024), Vec3(1, 0, -1024), Vec3(0, 0, -1024)); - pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()]->SetFrustumPlane(FR_PLANE_FAR, newFarPlane); - //pArea->m_arrOcclCamera[m_nRenderStackLevel]->UpdateFrustum(); - - m_lstActiveOcclVolumes.Add(pArea); - pArea->m_fDistance = fDist; - } - } - } - } - - if (m_lstActiveOcclVolumes.Count()) - { // sort occluders by distance to the camera - qsort(&m_lstActiveOcclVolumes[0], m_lstActiveOcclVolumes.Count(), - sizeof(m_lstActiveOcclVolumes[0]), CVisAreaManager__CmpDistToPortal); - - // remove occluded occluders - for (int i = m_lstActiveOcclVolumes.Count() - 1; i >= 0; i--) - { - CVisArea* pArea = m_lstActiveOcclVolumes[i]; - AABB extrudedBox = pArea->m_boxStatics; - extrudedBox.min -= Vec3(VEC_EPSILON, VEC_EPSILON, VEC_EPSILON); - extrudedBox.max += Vec3(VEC_EPSILON, VEC_EPSILON, VEC_EPSILON); - if (IsOccludedByOcclVolumes(extrudedBox, passInfo)) - { - m_lstActiveOcclVolumes.Delete(i); - } - } - -#ifdef OCCLUSIONCULLER_W - // draw them into the CBuffer - for (size_t i = 0, size = m_allActiveVerts.size(); i < size; i++) - { - pCBuffer->AddOccluderPlane(m_allActiveVerts[i].arrvActiveVerts); - } -#endif - - // put indoor occluders into separate list - for (int i = m_lstActiveOcclVolumes.Count() - 1; i >= 0; i--) - { - CVisArea* pArea = m_lstActiveOcclVolumes[i]; - if (pArea->m_bUseInIndoors) - { - m_lstIndoorActiveOcclVolumes.Add(pArea); - } - } - - if (GetCVars()->e_Portals == 4) - { // show really active occluders - for (int i = 0; i < m_lstActiveOcclVolumes.Count(); i++) - { - CVisArea* pArea = m_lstActiveOcclVolumes[i]; - GetRenderer()->SetMaterialColor(0, 1, 0, 1); - DrawBBox(pArea->m_boxStatics.min, pArea->m_boxStatics.max); - } - } - } -} - -void CVisAreaManager::GetStreamingStatus(int& nLoadedSectors, int& nTotalSectors) -{ - nLoadedSectors = 0; - nTotalSectors = m_lstPortals.Count() + m_lstVisAreas.Count(); -} - -void CVisAreaManager::GetMemoryUsage(ICrySizer* pSizer) const -{ - // areas - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - m_lstVisAreas[v]->GetMemoryUsage(pSizer); - } - - // portals - for (int v = 0; v < m_lstPortals.Count(); v++) - { - m_lstPortals[v]->GetMemoryUsage(pSizer); - } - - // occl areas - for (int v = 0; v < m_lstOcclAreas.Count(); v++) - { - m_lstOcclAreas[v]->GetMemoryUsage(pSizer); - } - - pSizer->AddObject(this, sizeof(*this)); -} - - -void CVisAreaManager::PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum) -{ - CryLog("Precaching the level ..."); - // gEnv->pLog->UpdateLoadingScreen(0); - - float fPrecacheTimeStart = GetTimer()->GetAsyncCurTime(); - - GetRenderer()->EnableSwapBuffers((GetCVars()->e_PrecacheLevel >= 2) ? true : false); - - uint32 dwPrecacheLocations = 0; - - Vec3 arrCamDir[6] = - { - Vec3(1, 0, 0), - Vec3(-1, 0, 0), - Vec3(0, 1, 0), - Vec3(0, -1, 0), - Vec3(0, 0, 1), - Vec3(0, 0, -1) - }; - - //loop over all sectors and place a light in the middle of the sector - for (int v = 0; v < m_lstVisAreas.Count() && bPrecacheAllVisAreas; v++) - { - GetRenderer()->EF_Query(EFQ_IncrementFrameID); - - ++dwPrecacheLocations; - - // find real geometry bbox - /* bool bGeomFound = false; - Vec3 vBoxMin(100000.f,100000.f,100000.f); - Vec3 vBoxMax(-100000.f,-100000.f,-100000.f); - for(int s=0; sm_lstEntities[s].Count(); e++) - { - AABB aabbBox = m_lstVisAreas[v]->m_lstEntities[s][e].aabbBox; - vBoxMin.CheckMin(aabbBox.min); - vBoxMax.CheckMax(aabbBox.max); - bGeomFound = true; - }*/ - - Vec3 vAreaCenter = m_lstVisAreas[v]->m_boxArea.GetCenter(); - CryLog(" Precaching VisArea %s", m_lstVisAreas[v]->GetName()); - - //place camera in the middle of a sector and render sector from different directions - for (int i = 0; i < 6 /*&& bGeomFound*/; i++) - { - GetRenderer()->BeginFrame(); - - // setup camera - CCamera cam = gEnv->pSystem->GetViewCamera(); - Matrix33 mat = Matrix33::CreateRotationVDir(arrCamDir[i], 0); - cam.SetMatrix(mat); - cam.SetPosition(vAreaCenter); - cam.SetFrustum(GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), gf_PI / 2, cam.GetNearPlane(), cam.GetFarPlane()); - // Get3DEngine()->SetupCamera(cam); - - - Get3DEngine()->RenderWorld(SHDF_ZPASS | SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS | SHDF_ALLOW_WATER | SHDF_ALLOW_AO, SRenderingPassInfo::CreateGeneralPassRenderingInfo(cam), "PrecacheVisAreas"); - - GetRenderer()->RenderDebug(); - GetRenderer()->EndFrame(); - - if (GetCVars()->e_PrecacheLevel >= 2) - { - CrySleep(200); - } - } - } - - CryLog("Precached %d visarea sectors", dwPrecacheLocations); - - - //-------------------------------------------------------------------------------------- - //---- PRE-FETCHING OF RENDER-DATA IN OUTDOORS ---- - //-------------------------------------------------------------------------------------- - - // loop over all cam-position in the level and render this part of the level from 6 different directions - for (int p = 0; pPrecachePoints && p < nPrecachePointsNum; p++) //loop over outdoor-camera position - { - CryLog(" Precaching PrecacheCamera point %d of %d", p, nPrecachePointsNum); - for (int i = 0; i < 6; i++) //loop over 6 camera orientations - { - GetRenderer()->BeginFrame(); - - // setup camera - CCamera cam = gEnv->pSystem->GetViewCamera(); - Matrix33 mat = Matrix33::CreateRotationVDir(arrCamDir[i], 0); - cam.SetMatrix(mat); - cam.SetPosition(pPrecachePoints[p]); - cam.SetFrustum(GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), gf_PI / 2, cam.GetNearPlane(), cam.GetFarPlane()); - - Get3DEngine()->RenderWorld(SHDF_ZPASS | SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS | SHDF_ALLOW_WATER | SHDF_ALLOW_AO, SRenderingPassInfo::CreateGeneralPassRenderingInfo(cam), "PrecacheOutdoor"); - - GetRenderer()->RenderDebug(); - GetRenderer()->EndFrame(); - - if (GetCVars()->e_PrecacheLevel >= 2) - { - CrySleep(1000); - } - } - } - - CryLog("Precached %d PrecacheCameraXX points", nPrecachePointsNum); - - GetRenderer()->EnableSwapBuffers(true); - - float fPrecacheTime = GetTimer()->GetAsyncCurTime() - fPrecacheTimeStart; - CryLog("Level Precache finished in %.2f seconds", fPrecacheTime); -} - -void CVisAreaManager::GetObjectsAround(Vec3 vExploPos, float fExploRadius, PodArray* pEntList, bool bSkip_ERF_NO_DECALNODE_DECALS, bool bSkipDynamicObjects) -{ - AABB aabbBox(vExploPos - Vec3(fExploRadius, fExploRadius, fExploRadius), vExploPos + Vec3(fExploRadius, fExploRadius, fExploRadius)); - - CVisArea* pVisArea = (CVisArea*)GetVisAreaFromPos(vExploPos); - - if (pVisArea && pVisArea->m_pObjectsTree) - { - pVisArea->m_pObjectsTree->MoveObjectsIntoList(pEntList, &aabbBox, false, true, bSkip_ERF_NO_DECALNODE_DECALS, bSkipDynamicObjects); - } - /* - // find static objects around - for(int i=0; pVisArea && im_lstEntities[STATIC_OBJECTS].Count(); i++) - { - IRenderNode * pRenderNode = pVisArea->m_lstEntities[STATIC_OBJECTS][i].pNode; - if(bSkip_ERF_NO_DECALNODE_DECALS && pRenderNode->GetRndFlags()&ERF_NO_DECALNODE_DECALS) - continue; - if(pRenderNode->GetRenderNodeType() == eERType_Decal) - continue; - if(Overlap::Sphere_AABB(Sphere(vExploPos,fExploRadius), pRenderNode->GetBBox())) - if(pEntList->Find(pRenderNode)<0) - pEntList->Add(pRenderNode); - } - }*/ -} - -void CVisAreaManager::IntersectWithBox(const AABB& aabbBox, PodArray* plstResult, [[maybe_unused]] bool bOnlyIfVisible) -{ - for (int p = 0; p < m_lstPortals.Count(); p++) - { - if (m_lstPortals[p]->m_boxArea.min.x < aabbBox.max.x&& m_lstPortals[p]->m_boxArea.max.x > aabbBox.min.x && - m_lstPortals[p]->m_boxArea.min.y < aabbBox.max.y&& m_lstPortals[p]->m_boxArea.max.y > aabbBox.min.y) - { - plstResult->Add(m_lstPortals[p]); - } - } - - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - if (m_lstVisAreas[v]->m_boxArea.min.x < aabbBox.max.x&& m_lstVisAreas[v]->m_boxArea.max.x > aabbBox.min.x && - m_lstVisAreas[v]->m_boxArea.min.y < aabbBox.max.y&& m_lstVisAreas[v]->m_boxArea.max.y > aabbBox.min.y) - { - plstResult->Add(m_lstVisAreas[v]); - } - } -} - -int CVisAreaManager::GetNumberOfVisArea() const -{ - return m_lstPortals.size() + m_lstVisAreas.size(); -} - -IVisArea* CVisAreaManager::GetVisAreaById(int nID) const -{ - if (nID < 0) - { - return NULL; - } - - if (nID < (int)m_lstPortals.size()) - { - return m_lstPortals[ nID ]; - } - nID -= m_lstPortals.size(); - if (nID < (int)m_lstVisAreas.size()) - { - return m_lstVisAreas[ nID ]; - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CVisAreaManager::AddListener(IVisAreaCallback* pListener) -{ - if (m_lstCallbacks.Find(pListener) < 0) - { - m_lstCallbacks.Add(pListener); - } -} - -////////////////////////////////////////////////////////////////////////// -void CVisAreaManager::RemoveListener(IVisAreaCallback* pListener) -{ - m_lstCallbacks.Delete(pListener); -} - -void CVisAreaManager::CloneRegion(const AABB& region, const Vec3& offset, float zRotation) -{ - PodArray points; - - PodArray visAreas; - IntersectWithBox(region, &visAreas, false); - - Vec3 localOrigin = region.GetCenter(); - Matrix34 l2w(Matrix33::CreateRotationZ(zRotation)); - l2w.SetTranslation(offset); - - int numAreas = visAreas.size(); - for (int i = 0; i < numAreas; ++i) - { - CVisArea* pSrcArea = visAreas[i]; - CVisArea* pCloneArea = CreateVisArea(0); - - SVisAreaInfo info; - info.fHeight = pSrcArea->m_fHeight; - info.vAmbientColor = pSrcArea->m_vAmbientColor; - info.bAffectedByOutLights = pSrcArea->m_bAffectedByOutLights; - info.bIgnoreSkyColor = pSrcArea->m_bIgnoreSky; - info.bSkyOnly = pSrcArea->m_bSkyOnly; - info.fViewDistRatio = pSrcArea->m_fViewDistRatio; - info.bDoubleSide = pSrcArea->m_bDoubleSide; - info.bUseDeepness = pSrcArea->m_bUseDeepness; - info.bUseInIndoors = pSrcArea->m_bUseInIndoors; - info.bOceanIsVisible = pSrcArea->m_bOceanVisible; - info.bIgnoreGI = pSrcArea->m_bIgnoreGI; - info.bIgnoreOutdoorAO = pSrcArea->m_bIgnoreOutdoorAO; - - points = pSrcArea->m_lstShapePoints; - int numPoints = points.size(); - for (int p = 0; p < numPoints; ++p) - { - Vec3& point = points[p]; - - point -= localOrigin; - point = l2w * point; - } - - const char* pName = pSrcArea->m_pVisAreaColdData->m_sName; - - UpdateVisArea(pCloneArea, &points[0], numPoints, pName, info); - } -} - -void CVisAreaManager::ClearRegion(const AABB& region) -{ - PodArray visAreas; - IntersectWithBox(region, &visAreas, false); - - bool updated = false; - - // What we're doing here is basically just what's done in DeleteVisArea, but this - // should be a pooled vis area, so we don't want to actually delete it. Instead we - // just unregister them and let the pool cleanup actually destruct them. - int numAreas = visAreas.size(); - for (int i = 0; i < numAreas; ++i) - { - CVisArea* pVisArea = visAreas[i]; - - // IntersectWithBox only checks x and y, but we want to also make sure it's in the z - if (pVisArea->m_boxArea.min.z < region.max.z && pVisArea->m_boxArea.max.z > region.min.z) - { - bool deletedVis = m_lstVisAreas.Delete(pVisArea); - bool deletedPortal = m_lstPortals.Delete(pVisArea); - bool deletedOccluder = m_lstOcclAreas.Delete(pVisArea); - - CRY_ASSERT_MESSAGE(!deletedVis || (m_visAreas.Find(pVisArea) >= 0), "Should only clear pooled vis areas, going to leak"); - CRY_ASSERT_MESSAGE(!deletedPortal || (m_portals.Find(pVisArea) >= 0), "Should only clear pooled portals, going to leak"); - CRY_ASSERT_MESSAGE(!deletedOccluder || (m_occlAreas.Find(pVisArea) >= 0), "Should only clear pooled occluders, going to leak"); - - if (deletedVis || deletedPortal || deletedOccluder) - { - updated = true; - } - - m_lstActiveOcclVolumes.Delete(pVisArea); - m_lstIndoorActiveOcclVolumes.Delete(pVisArea); - m_lstActiveEntransePortals.Delete(pVisArea); - } - } - - if (updated) - { - m_pCurArea = NULL; - m_pCurPortal = NULL; - UpdateConnections(); - - delete m_pAABBTree; - m_pAABBTree = NULL; - } -} - -void CVisAreaManager::ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, IGeneralMemoryHeap* pHeap) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - m_lstVisAreas[dwI]->m_pObjectsTree->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap); - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - m_lstPortals[dwI]->m_pObjectsTree->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap); - } - } - } -} - - -void CVisAreaManager::GetObjects(PodArray& lstObjects, const AABB* pBBox) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - m_lstVisAreas[dwI]->m_pObjectsTree->GetObjects(lstObjects, pBBox); - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - m_lstPortals[dwI]->m_pObjectsTree->GetObjects(lstObjects, pBBox); - } - } - } -} - -void CVisAreaManager::GetObjectsByFlags(uint dwFlags, PodArray& lstObjects) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - m_lstVisAreas[dwI]->m_pObjectsTree->GetObjectsByFlags(dwFlags, lstObjects); - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - m_lstPortals[dwI]->m_pObjectsTree->GetObjectsByFlags(dwFlags, lstObjects); - } - } - } -} - -void CVisAreaManager::GenerateStatObjAndMatTables(std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, SHotUpdateInfo* pExportInfo) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - m_lstVisAreas[dwI]->m_pObjectsTree->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo); - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - m_lstPortals[dwI]->m_pObjectsTree->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo); - } - } - } -} - -bool CVisAreaManager::IsAABBVisibleFromPoint(AABB& box, Vec3 pos) -{ - CVisArea* pAreaBox = (CVisArea*)GetVisAreaFromPos(box.GetCenter()); - CVisArea* pAreaPos = (CVisArea*)GetVisAreaFromPos(pos); - - if (!pAreaBox && !pAreaPos) - { - return true; // no indoors involved - } - PodArray arrPortals; - int nRecursion = 0; - Shadowvolume sv; - NAABB_SV::AABB_ReceiverShadowVolume(pos, box, sv); - - bool bRes = false; - - bRes = FindShortestPathToVisArea(pAreaPos, pAreaBox, arrPortals, nRecursion, sv); - - GetRenderer()->DrawLabel(box.GetCenter(), 2, "-%s-", bRes ? "Y" : "N"); - GetRenderer()->DrawLabel(pos, 2, "-X-"); - DrawLine(pos, box.GetCenter()); - DrawBBox(box, bRes ? Col_White : Col_NavyBlue); - - return bRes; -} - -bool CVisAreaManager::FindShortestPathToVisArea(CVisArea* pThisArea, CVisArea* pTargetArea, PodArray& arrVisitedAreas, int& nRecursion, const Shadowvolume& sv) -{ - // skip double processing - if (arrVisitedAreas.Find(pThisArea) >= 0) - { - return false; - } - - // check if point to box frustum intersects pThisArea visarea - if (pThisArea && !NAABB_SV::Is_AABB_In_ShadowVolume(sv, *pThisArea->GetAABBox())) - { - return false; - } - - // check if box visarea reached - if (pThisArea == pTargetArea) - { - return true; - } - - // register as already processed - arrVisitedAreas.Add(pThisArea); - - // recurse to connections - if (pThisArea) - { - for (int p = 0; p < pThisArea->m_lstConnections.Count(); p++) - { - if (FindShortestPathToVisArea(pThisArea->m_lstConnections[p], pTargetArea, arrVisitedAreas, nRecursion, sv)) - { - return true; - } - } - - if (pThisArea->IsPortal() && pThisArea->m_lstConnections.Count() == 1 && !pThisArea->m_bSkyOnly) - { - if (FindShortestPathToVisArea(NULL, pTargetArea, arrVisitedAreas, nRecursion, sv)) - { - return true; - } - } - } - else - { - for (int p = 0; p < m_lstPortals.Count(); p++) - { - if (m_lstPortals[p]->IsPortal() && m_lstPortals[p]->m_lstConnections.Count() == 1 && !m_lstPortals[p]->m_bSkyOnly) - { - if (FindShortestPathToVisArea(m_lstPortals[p], pTargetArea, arrVisitedAreas, nRecursion, sv)) - { - return true; - } - } - } - } - - return false; -} - -CVisArea* CVisAreaManager::CreateTypeVisArea() -{ - CVisArea* pNewVisArea = new CVisArea(); - SGenericColdData* pColdData = &m_visAreaColdData.AddNew(); - - m_visAreas.Add(pNewVisArea); - pColdData->ResetGenericData(); - pNewVisArea->SetColdDataPtr(pColdData); - - return pNewVisArea; -} - -CVisArea* CVisAreaManager::CreateTypePortal() -{ - CVisArea* pNewPortal = new CVisArea(); - SPortalColdData* pColdData = &m_portalColdData.AddNew(); - - m_portals.Add(pNewPortal); - pColdData->ResetPortalData(); - pNewPortal->SetColdDataPtr(pColdData); - - return pNewPortal; -} - -CVisArea* CVisAreaManager::CreateTypeOcclArea() -{ - CVisArea* pNewOcclArea = new CVisArea(); - SGenericColdData* pColdData = &m_occlAreaColdData.AddNew(); - - m_occlAreas.Add(pNewOcclArea); - pColdData->ResetGenericData(); - pNewOcclArea->SetColdDataPtr(pColdData); - - return pNewOcclArea; -} - -void CVisAreaManager::InitAABBTree() -{ - IF (!m_pAABBTree, 0) - { - UpdateAABBTree(); - } -} - -////////////////////////////////////////////////////////////////////// -// Segmented World -void CVisAreaManager::ReleaseInactiveSegments() -{ - for (int i = 0; i < m_arrDeletedVisArea.Count(); i++) - { - int nSlotID = m_arrDeletedVisArea[i]; - SAFE_DELETE(m_visAreas[nSlotID]->m_pObjectsTree); - } - m_arrDeletedVisArea.Clear(); - for (int i = 0; i < m_arrDeletedPortal.Count(); i++) - { - int nSlotID = m_arrDeletedPortal[i]; - SAFE_DELETE(m_portals[nSlotID]->m_pObjectsTree); - } - m_arrDeletedPortal.Clear(); - for (int i = 0; i < m_arrDeletedOcclArea.Count(); i++) - { - int nSlotID = m_arrDeletedOcclArea[i]; - SAFE_DELETE(m_occlAreas[nSlotID]->m_pObjectsTree); - } - m_arrDeletedOcclArea.Clear(); -} - -bool CVisAreaManager::CreateSegment(int nSID) -{ - if (nSID >= m_visAreaSegmentData.Count()) - { - m_visAreaSegmentData.PreAllocate(nSID + 1, nSID + 1); - m_portalSegmentData.PreAllocate(nSID + 1, nSID + 1); - if (GetCVars()->e_OcclusionVolumes) - { - m_occlAreaSegmentData.PreAllocate(nSID + 1, nSID + 1); - } - } - - return true; -} - -bool CVisAreaManager::DeleteSegment(int nSID, bool bDeleteNow) -{ - if (nSID < 0 || (size_t)nSID >= m_visAreaSegmentData.size()) - { - return false; - } - - DeleteVisAreaSegment(nSID, m_visAreaSegmentData, m_lstVisAreas, m_visAreas, m_arrDeletedVisArea); - DeleteVisAreaSegment(nSID, m_portalSegmentData, m_lstPortals, m_portals, m_arrDeletedPortal); - if (GetCVars()->e_OcclusionVolumes) - { - DeleteVisAreaSegment(nSID, m_occlAreaSegmentData, m_lstOcclAreas, m_occlAreas, m_arrDeletedOcclArea); - } - - if (bDeleteNow) - { - ReleaseInactiveSegments(); - } - - return true; -} - -void CVisAreaManager::DeleteVisAreaSegment(int nSID, - PodArray& visAreaSegmentData, - PodArray& lstVisAreas, - PodArray& visAreas, - PodArray& deletedVisAreas) -{ - std::vector& visAreasInSegment = visAreaSegmentData[nSID].m_visAreaIndices; - for (size_t i = 0; i < visAreasInSegment.size(); i++) - { - int index = visAreasInSegment[i]; - assert(index >= 0 && index < visAreas.Count()); - CSWVisArea* pVisArea = (CSWVisArea*)visAreas[index]; - pVisArea->Release(); - - // delete the visarea if it's ref count reaches zero - if (!pVisArea->NumRefs()) - { - deletedVisAreas.push_back(index); - } - } - visAreasInSegment.clear(); - - for (int i = 0; i < lstVisAreas.Count(); i++) - { - CSWVisArea* pVisArea = (CSWVisArea*)lstVisAreas[i]; - if (!pVisArea->NumRefs()) - { - lstVisAreas.Delete(i); - } - } -} - -CVisArea* CVisAreaManager::FindVisAreaByGuid(VisAreaGUID guid, PodArray& lstVisAreas) -{ - if (!guid) - { - for (int i = 0; i < lstVisAreas.Count(); i++) - { - if (lstVisAreas[i] && guid == lstVisAreas[i]->m_nVisGUID) - { - return lstVisAreas[i]; - } - } - } - - return NULL; -} - -void CVisAreaManager::OffsetPosition(const Vec3& delta) -{ - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - m_lstVisAreas[i]->OffsetPosition(delta); - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - m_lstPortals[i]->OffsetPosition(delta); - } - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - m_lstOcclAreas[i]->OffsetPosition(delta); - } - - if (m_pAABBTree) - { - m_pAABBTree->OffsetPosition(delta); - } -} diff --git a/Code/CryEngine/Cry3DEngine/VisAreaManCompile.cpp b/Code/CryEngine/Cry3DEngine/VisAreaManCompile.cpp deleted file mode 100644 index 3398c09c36..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreaManCompile.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : check vis - - -#include "Cry3DEngine_precompiled.h" - -#include "ObjMan.h" -#include "VisAreas.h" - -bool CVisAreaManager::GetCompiledData([[maybe_unused]] byte* pData, [[maybe_unused]] int nDataSize, [[maybe_unused]] std::vector** ppStatObjTable, [[maybe_unused]] std::vector<_smart_ptr>** ppMatTable, [[maybe_unused]] std::vector** ppStatInstGroupTable, [[maybe_unused]] EEndian eEndian, [[maybe_unused]] SHotUpdateInfo* pExportInfo) -{ -# if !ENGINE_ENABLE_COMPILATION - CryFatalError("serialization code removed, please enable 3DENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h"); - return false; -# else - float fStartTime = GetCurAsyncTimeSec(); - - - // PrintMessage("Exporting indoor data (%s, %.2f MB) ...", - - // write header - SVisAreaManChunkHeader* pVisAreaManagerChunkHeader = (SVisAreaManChunkHeader*)pData; - pVisAreaManagerChunkHeader->nVersion = VISAREAMANAGER_CHUNK_VERSION; - pVisAreaManagerChunkHeader->nDummy = 0; - pVisAreaManagerChunkHeader->nFlags = (eEndian == eBigEndian) ? SERIALIZATION_FLAG_BIG_ENDIAN : 0; - pVisAreaManagerChunkHeader->nFlags2 = 0; - pVisAreaManagerChunkHeader->nChunkSize = nDataSize; - - SwapEndian(*pVisAreaManagerChunkHeader, eEndian); - - UPDATE_PTR_AND_SIZE(pData, nDataSize, sizeof(SVisAreaManChunkHeader)); - - pVisAreaManagerChunkHeader->nVisAreasNum = m_lstVisAreas.Count(); - pVisAreaManagerChunkHeader->nPortalsNum = m_lstPortals.Count(); - pVisAreaManagerChunkHeader->nOcclAreasNum = m_lstOcclAreas.Count(); - - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - m_lstVisAreas[i]->GetData(pData, nDataSize, *ppStatObjTable, *ppMatTable, *ppStatInstGroupTable, eEndian, pExportInfo); - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - m_lstPortals[i]->GetData(pData, nDataSize, *ppStatObjTable, *ppMatTable, *ppStatInstGroupTable, eEndian, pExportInfo); - } - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - m_lstOcclAreas[i]->GetData(pData, nDataSize, *ppStatObjTable, *ppMatTable, *ppStatInstGroupTable, eEndian, pExportInfo); - } - - SAFE_DELETE(*ppStatObjTable); - SAFE_DELETE(*ppMatTable); - SAFE_DELETE(*ppStatInstGroupTable); - - if (!pExportInfo) - { - PrintMessagePlus(" done in %.2f sec", GetCurAsyncTimeSec() - fStartTime); - } - - assert(nDataSize == 0); - return nDataSize == 0; -# endif -} - -int CVisAreaManager::GetCompiledDataSize([[maybe_unused]] SHotUpdateInfo* pExportInfo) -{ -# if !ENGINE_ENABLE_COMPILATION - CryFatalError("serialization code removed, please enable 3DENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h"); - return 0; -# else - - int nDataSize = 0; - byte* pData = NULL; - - // get header size - nDataSize += sizeof(SVisAreaManChunkHeader); - - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - m_lstVisAreas[i]->GetData(pData, nDataSize, NULL, NULL, NULL, eLittleEndian, pExportInfo); - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - m_lstPortals[i]->GetData(pData, nDataSize, NULL, NULL, NULL, eLittleEndian, pExportInfo); - } - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - m_lstOcclAreas[i]->GetData(pData, nDataSize, NULL, NULL, NULL, eLittleEndian, pExportInfo); - } - - return nDataSize; -# endif -} - -bool CVisAreaManager::Load(AZ::IO::HandleType& fileHandle, int& nDataSize, struct SVisAreaManChunkHeader* pVisAreaManagerChunkHeader, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable) -{ - bool bRes; - - // in case of small data amount (console game) load entire file into memory in single operation - if (nDataSize < 4 * 1024 * 1024) - { - auto pMemBlock = gEnv->pCryPak->PoolAllocMemoryBlock(nDataSize + 8, "LoadIndoors"); - byte* pPtr = (byte*)pMemBlock->m_address.get(); - while (UINT_PTR(pPtr) & 3) - { - pPtr++; - } - - if (GetPak()->FReadRaw(pPtr, 1, nDataSize - sizeof(SVisAreaManChunkHeader), fileHandle) != nDataSize - sizeof(SVisAreaManChunkHeader)) - { - return false; - } - - bRes = Load_T(pPtr, nDataSize, pVisAreaManagerChunkHeader, pStatObjTable, pMatTable, false, NULL); - } - else - { - bRes = Load_T(fileHandle, nDataSize, pVisAreaManagerChunkHeader, pStatObjTable, pMatTable, false, NULL); - } - - return bRes; -} - -bool CVisAreaManager::SetCompiledData(byte* pData, int nDataSize, std::vector** ppStatObjTable, std::vector<_smart_ptr>** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo) -{ - SVisAreaManChunkHeader* pChunkHeader = (SVisAreaManChunkHeader*)pData; - pData += sizeof(SVisAreaManChunkHeader); - - SwapEndian(*pChunkHeader, eLittleEndian); - - bool bRes = Load_T(pData, nDataSize, pChunkHeader, *ppStatObjTable, *ppMatTable, bHotUpdate, pExportInfo); - - SAFE_DELETE(*ppStatObjTable); - SAFE_DELETE(*ppMatTable); - - return bRes; -} - -void CVisAreaManager::UnregisterEngineObjectsInArea(const SHotUpdateInfo* pExportInfo, PodArray& arrUnregisteredObjects, bool bOnlyEngineObjects) -{ - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - if (m_lstVisAreas[i]->m_pObjectsTree) - { - m_lstVisAreas[i]->m_pObjectsTree->UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, bOnlyEngineObjects); - } - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - if (m_lstPortals[i]->m_pObjectsTree) - { - m_lstPortals[i]->m_pObjectsTree->UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, bOnlyEngineObjects); - } - } - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - if (m_lstOcclAreas[i]->m_pObjectsTree) - { - m_lstOcclAreas[i]->m_pObjectsTree->UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, bOnlyEngineObjects); - } - } -} - -void CVisAreaManager::OnVisAreaDeleted(IVisArea* pArea) -{ - for (int i = 0, num = m_lstCallbacks.size(); i < num; i++) - { - m_lstCallbacks[i]->OnVisAreaDeleted(pArea); - } - - m_lstActiveOcclVolumes.Delete((CVisArea*)pArea); - m_lstIndoorActiveOcclVolumes.Delete((CVisArea*)pArea); - m_lstActiveEntransePortals.Delete((CVisArea*)pArea); -} - -template -bool CVisAreaManager::Load_T(T& f, int& nDataSize, SVisAreaManChunkHeader* pVisAreaManagerChunkHeader, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, [[maybe_unused]] bool bHotUpdate, SHotUpdateInfo* pExportInfo) -{ - if (pVisAreaManagerChunkHeader->nVersion != VISAREAMANAGER_CHUNK_VERSION) - { - Error("CVisAreaManager::SetCompiledData: version of file is %d, expected version is %d", pVisAreaManagerChunkHeader->nVersion, (int)VISAREAMANAGER_CHUNK_VERSION); - return 0; - } - - if (pVisAreaManagerChunkHeader->nChunkSize != nDataSize) - { - Error("CVisAreaManager::SetCompiledData: data size mismatch (%d != %d)", pVisAreaManagerChunkHeader->nChunkSize, nDataSize); - return 0; - } - - - EEndian eEndian = (pVisAreaManagerChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian; - - PodArray arrUnregisteredObjects; - UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, true); - - PodArray arrUnregisteredEntities; - UnregisterEngineObjectsInArea(NULL, arrUnregisteredEntities, false); - - DeleteAllVisAreas(); - - SAFE_DELETE(m_pAABBTree); - m_pCurArea = m_pCurPortal = 0; - - { // construct areas - m_lstVisAreas.PreAllocate(pVisAreaManagerChunkHeader->nVisAreasNum, pVisAreaManagerChunkHeader->nVisAreasNum); - m_lstPortals.PreAllocate(pVisAreaManagerChunkHeader->nPortalsNum, pVisAreaManagerChunkHeader->nPortalsNum); - m_lstOcclAreas.PreAllocate(pVisAreaManagerChunkHeader->nOcclAreasNum, pVisAreaManagerChunkHeader->nOcclAreasNum); - - nDataSize -= sizeof(SVisAreaManChunkHeader); - - // if(bHotUpdate) - // PrintMessage("Importing indoor data (%s, %.2f MB) ...", - m_visAreas.PreAllocate(pVisAreaManagerChunkHeader->nVisAreasNum); - m_visAreaColdData.PreAllocate(pVisAreaManagerChunkHeader->nVisAreasNum); - - m_portals.PreAllocate(pVisAreaManagerChunkHeader->nPortalsNum); - m_portalColdData.PreAllocate(pVisAreaManagerChunkHeader->nPortalsNum); - - m_occlAreas.PreAllocate(pVisAreaManagerChunkHeader->nOcclAreasNum); - m_occlAreaColdData.PreAllocate(pVisAreaManagerChunkHeader->nOcclAreasNum); - - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - m_lstVisAreas[i] = CreateTypeVisArea(); - } - for (int i = 0; i < m_lstPortals.Count(); i++) - { - m_lstPortals[i] = CreateTypePortal(); - } - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - m_lstOcclAreas[i] = CreateTypeOcclArea(); - } - } - - { // load areas content - for (int i = 0; i < m_lstVisAreas.Count(); i++) - { - m_lstVisAreas[i]->Load(f, nDataSize, pStatObjTable, pMatTable, eEndian, pExportInfo); - } - - for (int i = 0; i < m_lstPortals.Count(); i++) - { - m_lstPortals[i]->Load(f, nDataSize, pStatObjTable, pMatTable, eEndian, pExportInfo); - } - - for (int i = 0; i < m_lstOcclAreas.Count(); i++) - { - m_lstOcclAreas[i]->Load(f, nDataSize, pStatObjTable, pMatTable, eEndian, pExportInfo); - } - } - - for (int i = 0; i < arrUnregisteredObjects.Count(); i++) - { - arrUnregisteredObjects[i]->ReleaseNode(); - } - arrUnregisteredObjects.Reset(); - - for (int i = 0; i < arrUnregisteredEntities.Count(); i++) - { - Get3DEngine()->RegisterEntity(arrUnregisteredEntities[i]); - } - arrUnregisteredEntities.Reset(); - - SAFE_DELETE(m_pAABBTree); - m_pCurArea = m_pCurPortal = 0; - UpdateConnections(); - - return nDataSize == 0; -} - -////////////////////////////////////////////////////////////////////// -// Segmented World -inline bool IsContainBox2D(const AABB& base, const AABB& test) -{ - if (base.min.x < test.max.x && base.max.x > test.min.x && - base.min.y < test.max.y && base.max.y > test.min.y) - { - return true; - } - - return false; -} - -void CVisAreaManager::PrepareSegmentData(const AABB& box) -{ - m_segVisAreas.Clear(); - for (int v = 0; v < m_lstVisAreas.Count(); v++) - { - if (IsContainBox2D(m_lstVisAreas[v]->m_boxArea, box)) - { - m_segVisAreas.Add(m_lstVisAreas[v]); - } - } - - m_segPortals.Clear(); - for (int p = 0; p < m_lstPortals.Count(); p++) - { - if (IsContainBox2D(m_lstPortals[p]->m_boxArea, box)) - { - m_segPortals.Add(m_lstPortals[p]); - } - } - - m_segOcclAreas.Clear(); - for (int o = 0; o < m_lstOcclAreas.Count(); o++) - { - if (IsContainBox2D(m_lstOcclAreas[o]->m_boxArea, box)) - { - m_segOcclAreas.Add(m_lstOcclAreas[o]); - } - } -} - -bool CVisAreaManager::StreamCompiledData(uint8* pData, int nDataSize, int nSID, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, const Vec2& vIndexOffset) -{ - SVisAreaManChunkHeader* pVisAreaManagerChunkHeader = (SVisAreaManChunkHeader*)pData; - - pData += sizeof(SVisAreaManChunkHeader); - nDataSize -= sizeof(SVisAreaManChunkHeader); - - assert(pVisAreaManagerChunkHeader->nVersion == VISAREAMANAGER_CHUNK_VERSION); - - EEndian eEndian = (pVisAreaManagerChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian; - - SAFE_DELETE(m_pAABBTree); - m_pCurArea = m_pCurPortal = 0; - - for (int i = 0; i < pVisAreaManagerChunkHeader->nVisAreasNum; i++) - { - VisAreaGUID guid = CVisArea::GetGUIDFromFile(pData, eEndian); - CSWVisArea* pVisArea = (CSWVisArea*)FindVisAreaByGuid(guid, m_lstVisAreas); - if (!pVisArea) - { - pVisArea = CreateVisAreaFromPool(m_lstVisAreas, m_visAreas, m_visAreaColdData, false); - m_lstVisAreas.Add(pVisArea); - } - pVisArea->AddRef(); - m_visAreaSegmentData[nSID].m_visAreaIndices.push_back(pVisArea->m_nSlotID); - pVisArea->Load(pData, nDataSize, nSID, pStatObjTable, pMatTable, eEndian, 0, vIndexOffset); - } - - for (int i = 0; i < pVisAreaManagerChunkHeader->nPortalsNum; i++) - { - VisAreaGUID guid = CVisArea::GetGUIDFromFile(pData, eEndian); - CSWVisArea* pVisArea = (CSWVisArea*)FindVisAreaByGuid(guid, m_lstPortals); - if (!pVisArea) - { - pVisArea = CreateVisAreaFromPool(m_lstPortals, m_portals, m_portalColdData, true); - m_lstPortals.Add(pVisArea); - } - pVisArea->AddRef(); - m_portalSegmentData[nSID].m_visAreaIndices.push_back(pVisArea->m_nSlotID); - pVisArea->Load(pData, nDataSize, nSID, pStatObjTable, pMatTable, eEndian, 0, vIndexOffset); - } - - for (int i = 0; i < pVisAreaManagerChunkHeader->nOcclAreasNum; i++) - { - VisAreaGUID guid = CVisArea::GetGUIDFromFile(pData, eEndian); - CSWVisArea* pVisArea = (CSWVisArea*)FindVisAreaByGuid(guid, m_lstOcclAreas); - if (!pVisArea) - { - pVisArea = CreateVisAreaFromPool(m_lstOcclAreas, m_occlAreas, m_occlAreaColdData, false); - m_lstOcclAreas.Add(pVisArea); - } - pVisArea->AddRef(); - m_occlAreaSegmentData[nSID].m_visAreaIndices.push_back(pVisArea->m_nSlotID); - pVisArea->Load(pData, nDataSize, nSID, pStatObjTable, pMatTable, eEndian, 0, vIndexOffset); - } - - SAFE_DELETE(m_pAABBTree); - m_pCurArea = m_pCurPortal = 0; - - SAFE_DELETE(pStatObjTable); - SAFE_DELETE(pMatTable); - SAFE_DELETE(pStatInstGroupTable); - - return !(nDataSize == 0); -} - -CSWVisArea* CVisAreaManager::FindFreeVisAreaFromPool(PodArray& visAreas) -{ - for (int i = 0; i < visAreas.Count(); i++) - { - CSWVisArea* pVisArea = (CSWVisArea*)visAreas[i]; - - if (!pVisArea->NumRefs()) - { - pVisArea->m_nSlotID = i; - return pVisArea; - } - } - - return NULL; -} - -template -CSWVisArea* CVisAreaManager::CreateVisAreaFromPool(PodArray& lstVisAreas, PodArray& visAreas, PodArray& visAreaColdData, bool bIsPortal) -{ - CSWVisArea* pVisArea = FindFreeVisAreaFromPool(visAreas); - if (!pVisArea) - { - int nVisArea = visAreas.Count(); - visAreas.PreAllocate(nVisArea * 2); - visAreaColdData.PreAllocate(nVisArea * 2); - - ResetVisAreaList(lstVisAreas, visAreas, visAreaColdData); - - pVisArea = CreateTypeArea(visAreas, visAreaColdData, bIsPortal); - - // assign the slot id once the pool is enlarged - pVisArea->m_nSlotID = nVisArea; - } - - return pVisArea; -} - -template -void CVisAreaManager::ResetVisAreaList(PodArray& lstVisAreas, PodArray& visAreas, PodArray& visAreaColdData) -{ - for (int i = 0; i < visAreas.Count(); i++) - { - CVisArea* pVisArea = visAreas[i]; - if (pVisArea->m_pObjectsTree) - { - pVisArea->m_pObjectsTree->SetVisArea(pVisArea); - } - pVisArea->SetColdDataPtr(&visAreaColdData[i]); - lstVisAreas[i] = pVisArea; - } -} - -template -CSWVisArea* CVisAreaManager::CreateTypeArea(PodArray& visAreas, PodArray& visAreaColdData, bool bIsPortal) -{ - CSWVisArea* pNewVisArea = new CSWVisArea(); - SGenericColdData* pColdData = &visAreaColdData.AddNew(); - - visAreas.Add(pNewVisArea); - pColdData->m_dataType = bIsPortal ? eCDT_Portal : eCDT_Generic; - pNewVisArea->SetColdDataPtr(pColdData); - - return pNewVisArea; -} - diff --git a/Code/CryEngine/Cry3DEngine/VisArea_Jobs.cpp b/Code/CryEngine/Cry3DEngine/VisArea_Jobs.cpp deleted file mode 100644 index e95f203b5f..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisArea_Jobs.cpp +++ /dev/null @@ -1,809 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Visibility areas - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "3dEngine.h" -#include "TimeOfDay.h" -#include "AABBSV.h" -#include "Cry_LegacyPhysUtils.h" - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -bool InsidePolygon(const Vec3* __restrict polygon, int N, const Vec3& p) -{ - int counter = 0; - int i; - float xinters; - const Vec3* p1 = &polygon[0]; - - for (i = 1; i <= N; i++) - { - const Vec3* p2 = &polygon[i % N]; - if (p.y > min(p1->y, p2->y)) - { - if (p.y <= max(p1->y, p2->y)) - { - if (p.x <= max(p1->x, p2->x)) - { - if (p1->y != p2->y) - { - xinters = (p.y - p1->y) * (p2->x - p1->x) / (p2->y - p1->y) + p1->x; - if (p1->x == p2->x || p.x <= xinters) - { - counter++; - } - } - } - } - } - p1 = p2; - } - - if (counter % 2 == 0) - { - return(false); - } - else - { - return(true); - } -} - -/////////////////////////////////////////////////////////////////////////////// -bool InsideSpherePolygon(Vec3* polygon, int N, Sphere& S) -{ - int i; - Vec3 p1, p2; - - p1 = polygon[0]; - for (i = 1; i <= N; i++) - { - p2 = polygon[i % N]; - Vec3 vA(p1 - S.center); - Vec3 vD(p2 - p1); - vA.z = vD.z = 0; - vD.NormalizeSafe(); - float fB = vD.Dot(vA); - float fC = vA.Dot(vA) - S.radius * S.radius; - if (fB * fB >= fC) //at least 1 root - { - return(true); - } - p1 = p2; - } - - return(false); -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void CVisAreaManager::GetNearestCubeProbe(float& fMinDistance, int& nMaxPriority, CLightEntity*& pNearestLight, const AABB* pBBox) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - if (!pBBox || Overlap::AABB_AABB(*m_lstVisAreas[dwI]->GetAABBox(), *pBBox)) - { - m_lstVisAreas[dwI]->m_pObjectsTree->GetNearestCubeProbe(fMinDistance, nMaxPriority, pNearestLight, pBBox); - } - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - if (!pBBox || Overlap::AABB_AABB(*m_lstPortals[dwI]->GetAABBox(), *pBBox)) - { - m_lstPortals[dwI]->m_pObjectsTree->GetNearestCubeProbe(fMinDistance, nMaxPriority, pNearestLight, pBBox); - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CVisAreaManager::GetObjectsByType(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback) -{ - { - uint32 dwSize = m_lstVisAreas.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstVisAreas[dwI]->m_pObjectsTree) - { - if (!pBBox || Overlap::AABB_AABB(*m_lstVisAreas[dwI]->GetAABBox(), *pBBox)) - { - m_lstVisAreas[dwI]->m_pObjectsTree->GetObjectsByType(lstObjects, objType, pBBox, filterCallback); - } - } - } - } - - { - uint32 dwSize = m_lstPortals.Count(); - - for (uint32 dwI = 0; dwI < dwSize; ++dwI) - { - if (m_lstPortals[dwI]->m_pObjectsTree) - { - if (!pBBox || Overlap::AABB_AABB(*m_lstPortals[dwI]->GetAABBox(), *pBBox)) - { - m_lstPortals[dwI]->m_pObjectsTree->GetObjectsByType(lstObjects, objType, pBBox, filterCallback); - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisAreaManager::IsOccludedByOcclVolumes(const AABB& objBox, const SRenderingPassInfo& passInfo, bool bCheckOnlyIndoorVolumes) -{ - PodArray& rList = bCheckOnlyIndoorVolumes ? m_lstIndoorActiveOcclVolumes : m_lstActiveOcclVolumes; - - for (int i = 0; i < rList.Count(); i++) - { - CCamera* pCamera = rList[i]->m_arrOcclCamera[passInfo.GetRecursiveLevel()]; - bool bAllIn = 0; - if (pCamera) - { - // reduce code size by skipping many cache lookups in the camera functions as well as the camera constructor - char bufCamera[sizeof(CCamera)] _ALIGN(128); - memcpy(bufCamera, pCamera, sizeof(CCamera)); - if (alias_cast(bufCamera)->IsAABBVisible_EH(objBox, &bAllIn)) - { - if (bAllIn) - { - return true; - } - } - } - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -IVisArea* CVisAreaManager::GetVisAreaFromPos(const Vec3& vPos) -{ - FUNCTION_PROFILER_3DENGINE; - - if (!m_pAABBTree) - { - UpdateAABBTree(); - } - - return m_pAABBTree->FindVisarea(vPos); -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::IsBoxOverlapVisArea(const AABB& objBox) -{ - if (!Overlap::AABB_AABB(objBox, m_boxArea)) - { - return false; - } - - PodArray& polygonA = s_tmpPolygonA; - polygonA.Clear(); - polygonA.Add(Vec3(objBox.min.x, objBox.min.y, objBox.min.z)); - polygonA.Add(Vec3(objBox.min.x, objBox.max.y, objBox.min.z)); - polygonA.Add(Vec3(objBox.max.x, objBox.max.y, objBox.min.z)); - polygonA.Add(Vec3(objBox.max.x, objBox.min.y, objBox.min.z)); - return Overlap::Polygon_Polygon2D< PodArray >(polygonA, m_lstShapePoints); -} - -#define PORTAL_GEOM_BBOX_EXTENT 1.5f - -/////////////////////////////////////////////////////////////////////////////// -void CVisArea::UpdateGeometryBBox() -{ - m_boxStatics.max = m_boxArea.max; - m_boxStatics.min = m_boxArea.min; - - if (IsPortal()) - { // fix for big objects passing portal - m_boxStatics.max += Vec3(PORTAL_GEOM_BBOX_EXTENT, PORTAL_GEOM_BBOX_EXTENT, PORTAL_GEOM_BBOX_EXTENT); - m_boxStatics.min -= Vec3(PORTAL_GEOM_BBOX_EXTENT, PORTAL_GEOM_BBOX_EXTENT, PORTAL_GEOM_BBOX_EXTENT); - } - - if (m_pObjectsTree) - { - PodArray lstObjects; - m_pObjectsTree->GetObjectsByType(lstObjects, eERType_StaticMeshRenderComponent, NULL); - - for (int i = 0; i < lstObjects.Count(); i++) - { - AABB aabb; - lstObjects[i]->FillBBox(aabb); - m_boxStatics.Add(aabb); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CVisArea::UpdateClipVolume() -{ - if (m_lstShapePoints.Count() < 3) - { - return; - } - - const int nPoints = m_lstShapePoints.size(); - const int nVertexCount = nPoints * 2; - const int nIndexCount = (2 * nPoints + 2 * (nPoints - 2)) * 3; // 2*nPoints for sides, nPoints-2 for top and nPoints-2 for bottom - - m_pClipVolumeMesh = NULL; - - if (nPoints < 3) - { - return; - } - - std::vector vertices; - std::vector indices; - - vertices.resize(nVertexCount); - indices.resize(nIndexCount); - - std::vector triangulationPoints; - triangulationPoints.resize(nPoints + 1); - MARK_UNUSED triangulationPoints[nPoints].x; - - for (int i = 0; i < nPoints; ++i) - { - int nPointIdx = IsShapeClockwise() ? nPoints - 1 - i : i; - - vertices[i].xyz = m_lstShapePoints[nPointIdx]; - vertices[i].color.dcolor = 0xFFFFFFFF; - vertices[i].st = Vec2(ZERO); - - vertices[i + nPoints].xyz = m_lstShapePoints[nPointIdx] + Vec3(0, 0, m_fHeight); - vertices[i + nPoints].color.dcolor = 0xFFFFFFFF; - vertices[i + nPoints].st = Vec2(ZERO); - - triangulationPoints[i] = Vec2(m_lstShapePoints[nPointIdx]); - } - - // triangulate shape first - std::vector triangleIndices; - triangleIndices.resize((nPoints - 2) * 3); - MARK_UNUSED triangleIndices[triangleIndices.size() - 1]; - - int nTris = LegacyCryPhysicsUtils::TriangulatePoly(&triangulationPoints[0], triangulationPoints.size(), &triangleIndices[0], triangleIndices.size()); - - if (nTris == nPoints - 2) // triangulation success? - { - // top and bottom faces - size_t nCurIndex = 0; - for (; nCurIndex < triangleIndices.size(); nCurIndex += 3) - { - indices[nCurIndex + 2] = triangleIndices[nCurIndex + 0]; - indices[nCurIndex + 1] = triangleIndices[nCurIndex + 1]; - indices[nCurIndex + 0] = triangleIndices[nCurIndex + 2]; - - indices[triangleIndices.size() + nCurIndex + 0] = triangleIndices[nCurIndex + 0] + nPoints; - indices[triangleIndices.size() + nCurIndex + 1] = triangleIndices[nCurIndex + 1] + nPoints; - indices[triangleIndices.size() + nCurIndex + 2] = triangleIndices[nCurIndex + 2] + nPoints; - } - - nCurIndex = 2 * triangleIndices.size(); - - // side faces - for (int i = 0; i < nPoints; i++) - { - vtx_idx bl = i; - vtx_idx br = (i + 1) % nPoints; - - indices[nCurIndex++] = bl; - indices[nCurIndex++] = br + nPoints; - indices[nCurIndex++] = bl + nPoints; - - indices[nCurIndex++] = bl; - indices[nCurIndex++] = br; - indices[nCurIndex++] = br + nPoints; - } - - m_pClipVolumeMesh = gEnv->pRenderer->CreateRenderMeshInitialized(&vertices[0], vertices.size(), - eVF_P3F_C4B_T2F, &indices[0], indices.size(), prtTriangleList, - "ClipVolume", GetName(), eRMT_Dynamic); - } -} - - -void CVisArea::GetClipVolumeMesh(_smart_ptr& renderMesh, Matrix34& worldTM) const -{ - renderMesh = m_pClipVolumeMesh; - worldTM = Matrix34(IDENTITY); -} - -uint CVisArea::GetClipVolumeFlags() const -{ - int nFlags = IClipVolume::eClipVolumeIsVisArea; - nFlags |= IsConnectedToOutdoor() ? IClipVolume::eClipVolumeConnectedToOutdoor : 0; - nFlags |= IsAffectedByOutLights() ? IClipVolume::eClipVolumeAffectedBySun : 0; - nFlags |= IsIgnoringGI() ? IClipVolume::eClipVolumeIgnoreGI : 0; - nFlags |= IsIgnoringOutdoorAO() ? IClipVolume::eClipVolumeIgnoreOutdoorAO : 0; - - return nFlags; -} - - -/////////////////////////////////////////////////////////////////////////////// -void CVisArea::UpdatePortalBlendInfo() -{ - if (m_bThisIsPortal && m_lstConnections.Count() > 0 && GetCVars()->e_PortalsBlend > 0 && m_fPortalBlending > 0) - { - SClipVolumeBlendInfo blendInfo; - Vec3 vPlanePoints[2][3]; - uint nPointCount[2] = {0, 0}; - - for (int p = 0; p < m_lstShapePoints.Count(); ++p) - { - Vec3 vTestPoint = m_lstShapePoints[p] + Vec3(0, 0, m_fHeight * 0.5f); - int nVisAreaIndex = (m_lstConnections[0] && m_lstConnections[0]->IsPointInsideVisArea(vTestPoint)) ? 0 : 1; - - if (nPointCount[nVisAreaIndex] < 2) - { - vPlanePoints[nVisAreaIndex][nPointCount[nVisAreaIndex]] = m_lstShapePoints[p]; - nPointCount[nVisAreaIndex]++; - } - } - - for (int i = 0; i < 2; ++i) - { - if (nPointCount[i] == 2) - { - if (IsShapeClockwise()) - { - std::swap(vPlanePoints[i][0], vPlanePoints[i][1]); - } - - blendInfo.blendPlanes[i] = Plane::CreatePlane(vPlanePoints[i][0], vPlanePoints[i][0] + Vec3(0, 0, m_fHeight), vPlanePoints[i][1]); - blendInfo.blendVolumes[i] = i < m_lstConnections.Count() ? m_lstConnections[i] : NULL; - - // make sure plane normal points inside portal - if (nPointCount[(i + 1) % 2] > 0) - { - Vec3 c(ZERO); - for (uint j = 0; j < nPointCount[(i + 1) % 2]; ++j) - { - c += vPlanePoints[(i + 1) % 2][j]; - } - c /= (float)nPointCount[(i + 1) % 2]; - - if (blendInfo.blendPlanes[i].DistFromPlane(c) < 0) - { - blendInfo.blendPlanes[i].n = -blendInfo.blendPlanes[i].n; - blendInfo.blendPlanes[i].d = -blendInfo.blendPlanes[i].d; - } - } - } - else - { - blendInfo.blendPlanes[i] = Plane(Vec3(ZERO), 0); - blendInfo.blendVolumes[i] = NULL; - } - } - - // weight planes by user specified importance. works because we renormalize in the shader - float planeWeight = clamp_tpl(m_fPortalBlending, 1e-5f, 1.f - 1e-5f); - - blendInfo.blendPlanes[0].n *= planeWeight; - blendInfo.blendPlanes[0].d *= planeWeight; - blendInfo.blendPlanes[1].n *= 1 - planeWeight; - blendInfo.blendPlanes[1].d *= 1 - planeWeight; - - GetRenderer()->EF_SetDeferredClipVolumeBlendData(this, blendInfo); - } -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisAreaManager::SetEntityArea(IRenderNode* pEnt, const AABB& objBox, const float fObjRadiusSqr) -{ - assert(pEnt); - - Vec3 vEntCenter = Get3DEngine()->GetEntityRegisterPoint(pEnt); - - // find portal containing object center - CVisArea* pVisArea = NULL; - - const int kNumPortals = m_lstPortals.Count(); - for (int v = 0; v < kNumPortals; v++) - { - CVisArea* pCurrentPortal = m_lstPortals[v]; - PrefetchLine(pCurrentPortal, 256); - PrefetchLine(pCurrentPortal, 384); - if (pCurrentPortal->IsPointInsideVisArea(vEntCenter)) - { - pVisArea = pCurrentPortal; - if (!pVisArea->m_pObjectsTree) - { - pVisArea->m_pObjectsTree = COctreeNode::Create(DEFAULT_SID, pVisArea->m_boxArea, pVisArea); - } - pVisArea->m_pObjectsTree->InsertObject(pEnt, objBox, fObjRadiusSqr, vEntCenter); - break; - } - } - - if (!pVisArea && pEnt->m_dwRndFlags & ERF_REGISTER_BY_BBOX) - { - AABB aabb; - pEnt->FillBBox(aabb); - - for (int v = 0; v < kNumPortals; v++) - { - CVisArea* pCurrentPortal = m_lstPortals[v]; - PrefetchLine(pCurrentPortal, 256); - PrefetchLine(pCurrentPortal, 384); - if (pCurrentPortal->IsBoxOverlapVisArea(aabb)) - { - pVisArea = pCurrentPortal; - if (!pVisArea->m_pObjectsTree) - { - pVisArea->m_pObjectsTree = COctreeNode::Create(DEFAULT_SID, pVisArea->m_boxArea, pVisArea); - } - - pVisArea->m_pObjectsTree->InsertObject(pEnt, objBox, fObjRadiusSqr, vEntCenter); - break; - } - } - } - - if (!pVisArea) // if portal not found - find volume - { - const int kNumVisAreas = m_lstVisAreas.Count(); - for (int v = 0; v < kNumVisAreas; v++) - { - CVisArea* pCurrentVisArea = m_lstVisAreas[v]; - PrefetchLine(pCurrentVisArea, 256); - PrefetchLine(pCurrentVisArea, 384); - if (pCurrentVisArea->IsPointInsideVisArea(vEntCenter)) - { - pVisArea = pCurrentVisArea; - if (!pVisArea->m_pObjectsTree) - { - pVisArea->m_pObjectsTree = COctreeNode::Create(DEFAULT_SID, pVisArea->m_boxArea, pVisArea); - } - pVisArea->m_pObjectsTree->InsertObject(pEnt, objBox, fObjRadiusSqr, vEntCenter); - break; - } - } - } - - if (pVisArea && - (pEnt->GetRenderNodeType() == eERType_StaticMeshRenderComponent) - ) // update bbox of exit portal - { - if (pVisArea->IsPortal()) - { - pVisArea->UpdateGeometryBBox(); - } - } - - return pVisArea != 0; -} - -/////////////////////////////////////////////////////////////////////////////// -CVisArea* SAABBTreeNode::FindVisarea(const Vec3& vPos) -{ - if (nodeBox.IsContainPoint(vPos)) - { - if (nodeAreas.Count()) - { // leaf - for (int i = 0; i < nodeAreas.Count(); i++) - { - if (nodeAreas[i]->m_bActive && nodeAreas[i]->IsPointInsideVisArea(vPos)) - { - return nodeAreas[i]; - } - } - } - else - { // node - for (int i = 0; i < 2; i++) - { - if (arrChilds[i]) - { - if (CVisArea* pArea = arrChilds[i]->FindVisarea(vPos)) - { - return pArea; - } - } - } - } - } - - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Current scheme: Will never move sphere center, just clip radius, even to 0. -bool CVisArea::ClipToVisArea(bool bInside, Sphere& sphere, Vec3 const& vNormal) -{ - FUNCTION_PROFILER_3DENGINE; - - /* - Clip PointZ PointXY - - In In In inside, clip Z and XY - In In Out outside, return 0 - In Out In outside, return 0 - In Out Out outside, return 0 - - Out In In inside, return 0 - Out In Out outside, clip XY - Out Out In outside, clip Z - Out Out Out outside, clip XY - */ - - bool bClipXY = false, bClipZ = false; - if (bInside) - { - // Clip to 0 if center outside. - if (!IsPointInsideVisArea(sphere.center)) - { - sphere.radius = 0.f; - return true; - } - bClipXY = bClipZ = true; - } - else - { - if (Overlap::Point_AABB(sphere.center, m_boxArea)) - { - if (InsidePolygon(m_lstShapePoints.begin(), m_lstShapePoints.size(), sphere.center)) - { - sphere.radius = 0.f; - return true; - } - else - { - bClipXY = true; - } - } - else if (InsidePolygon(m_lstShapePoints.begin(), m_lstShapePoints.size(), sphere.center)) - { - bClipZ = true; - } - else - { - bClipXY = true; - } - } - - float fOrigRadius = sphere.radius; - if (bClipZ) - { - // Check against vertical planes. - float fDist = min(abs(m_boxArea.max.z - sphere.center.z), abs(sphere.center.z - m_boxArea.min.z)); - float fRadiusScale = sqrt_tpl(max(1.f - sqr(vNormal.z), 0.f)); - if (fDist < sphere.radius * fRadiusScale) - { - sphere.radius = fDist / fRadiusScale; - if (sphere.radius <= 0.f) - { - return true; - } - } - } - - if (bClipXY) - { - Vec3 vP1 = m_lstShapePoints[0]; - vP1.z = clamp_tpl(sphere.center.z, m_boxArea.min.z, m_boxArea.max.z); - for (int n = m_lstShapePoints.Count() - 1; n >= 0; n--) - { - Vec3 vP0 = m_lstShapePoints[n]; - vP0.z = vP1.z; - - // Compute nearest vector from center to plane. - Vec3 vP = vP0 - sphere.center; - Vec3 vD = vP1 - vP0; - float fN = -(vP * vD); - if (fN > 0.f) - { - float fD = vD.GetLengthSquared(); - if (fN >= fD) - { - vP += vD; - } - else - { - vP += vD * (fN / fD); - } - } - - // Check distance only in planar direction. - float fDist = vP.GetLength() * 0.99f; - float fRadiusScale = fDist > 0.f ? sqrt_tpl(max(1.f - sqr(vNormal * vP) / sqr(fDist), 0.f)) : 1.f; - if (fDist < sphere.radius * fRadiusScale) - { - sphere.radius = fDist / fRadiusScale; - if (sphere.radius <= 0.f) - { - return true; - } - } - - vP1 = vP0; - } - } - - return sphere.radius < fOrigRadius; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::IsPointInsideVisArea(const Vec3& vPos) const -{ - const int kNumPoints = m_lstShapePoints.Count(); - if (kNumPoints) - { - const Vec3* pLstShapePoints = &m_lstShapePoints[0]; - PrefetchLine(pLstShapePoints, 0); - if (Overlap::Point_AABB(vPos, m_boxArea)) - { - if (InsidePolygon(pLstShapePoints, kNumPoints, vPos)) - { - return true; - } - } - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::IsSphereInsideVisArea(const Vec3& vPos, const f32 fRadius) -{ - Sphere S(vPos, fRadius); - if (Overlap::Sphere_AABB(S, m_boxArea)) - { - if (InsidePolygon(&m_lstShapePoints[0], m_lstShapePoints.Count(), vPos) || InsideSpherePolygon(&m_lstShapePoints[0], m_lstShapePoints.Count(), S)) - { - return true; - } - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -const AABB* CVisArea::GetAABBox() const -{ - return &m_boxArea; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::IsPortal() const -{ - return m_bThisIsPortal; -} - -float CVisArea::CalcSignedArea() -{ - float fArea = 0; - for (int i = 0; i < m_lstShapePoints.Count(); i++) - { - const Vec3& v0 = m_lstShapePoints[i]; - const Vec3& v1 = m_lstShapePoints[(i + 1) % m_lstShapePoints.Count()]; - fArea += v0.x * v1.y - v1.x * v0.y; - } - return fArea / 2; -} - -void CVisArea::GetShapePoints(const Vec3*& pPoints, size_t& nPoints) -{ - if (m_lstShapePoints.empty()) - { - pPoints = 0; - nPoints = 0; - } - else - { - pPoints = &m_lstShapePoints[0]; - nPoints = m_lstShapePoints.size(); - } -} - -float CVisArea::GetHeight() -{ - return m_fHeight; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::FindVisArea(IVisArea* pAnotherArea, int nMaxRecursion, bool bSkipDisabledPortals) -{ - // collect visited areas in order to prevent visiting it again - StaticDynArray lVisitedParents; - - return FindVisAreaReqursive(pAnotherArea, nMaxRecursion, bSkipDisabledPortals, lVisitedParents); -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::FindVisAreaReqursive(IVisArea* pAnotherArea, int nMaxReqursion, bool bSkipDisabledPortals, StaticDynArray& arrVisitedParents) -{ - arrVisitedParents.push_back(this); - - if (pAnotherArea == this) - { - return true; - } - - if (pAnotherArea == NULL && IsConnectedToOutdoor()) - { - return true; - } - - bool bFound = false; - - if (nMaxReqursion > 1) - { - for (int p = 0; p < m_lstConnections.Count(); p++) - { - if (!bSkipDisabledPortals || m_lstConnections[p]->IsActive()) - { - if (std::find(arrVisitedParents.begin(), arrVisitedParents.end(), m_lstConnections[p]) == arrVisitedParents.end()) - { - if (m_lstConnections[p]->FindVisAreaReqursive(pAnotherArea, nMaxReqursion - 1, bSkipDisabledPortals, arrVisitedParents)) - { - bFound = true; - break; - } - } - } - } - } - - return bFound; -} - -/////////////////////////////////////////////////////////////////////////////// -bool CVisArea::IsConnectedToOutdoor() const -{ - if (IsPortal()) // check if this portal has just one conection - { - return m_lstConnections.Count() == 1; - } - - // find portals with just one conection - for (int p = 0; p < m_lstConnections.Count(); p++) - { - CVisArea* pPortal = m_lstConnections[p]; - if (pPortal->m_lstConnections.Count() == 1) - { - return true; - } - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - diff --git a/Code/CryEngine/Cry3DEngine/VisAreas.cpp b/Code/CryEngine/Cry3DEngine/VisAreas.cpp deleted file mode 100644 index d1247f7fc1..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreas.cpp +++ /dev/null @@ -1,1148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Visibility areas - - -#include "Cry3DEngine_precompiled.h" - -#include "StatObj.h" -#include "ObjMan.h" -#include "VisAreas.h" -#include "3dEngine.h" -#include "TimeOfDay.h" - -PodArray CVisArea::m_lUnavailableAreas; -PodArray CVisArea::s_tmpLstPortVertsClipped; -PodArray CVisArea::s_tmpLstPortVertsSS; -PodArray CVisArea::s_tmpPolygonA; -PodArray CVisArea::s_tmpLstLights; - -CPolygonClipContext CVisArea::s_tmpClipContext; -PodArray CVisArea::s_tmpCameras; -int CVisArea::s_nGetDistanceThruVisAreasCallCounter = 0; - -void CVisArea::Update(const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info) -{ - assert(m_pVisAreaColdData); - - - cry_strcpy(m_pVisAreaColdData->m_sName, szName); - _strlwr_s(m_pVisAreaColdData->m_sName, sizeof(m_pVisAreaColdData->m_sName)); - - m_bThisIsPortal = strstr(m_pVisAreaColdData->m_sName, "portal") != 0; - m_bIgnoreSky = (strstr(m_pVisAreaColdData->m_sName, "ignoresky") != 0) || info.bIgnoreSkyColor; - - m_fHeight = info.fHeight; - m_vAmbientColor = info.vAmbientColor; - m_bAffectedByOutLights = info.bAffectedByOutLights; - m_bSkyOnly = info.bSkyOnly; - m_fViewDistRatio = info.fViewDistRatio; - m_bDoubleSide = info.bDoubleSide; - m_bUseDeepness = info.bUseDeepness; - m_bUseInIndoors = info.bUseInIndoors; - m_bOceanVisible = info.bOceanIsVisible; - m_bIgnoreGI = info.bIgnoreGI; - m_bIgnoreOutdoorAO = info.bIgnoreOutdoorAO; - m_fPortalBlending = info.fPortalBlending; - - m_lstShapePoints.PreAllocate(nCount, nCount); - - if (nCount) - { - memcpy(&m_lstShapePoints[0], pPoints, sizeof(Vec3) * nCount); - } - - // update bbox - m_boxArea.max = SetMinBB(); - m_boxArea.min = SetMaxBB(); - - for (int i = 0; i < nCount; i++) - { - m_boxArea.max.CheckMax(pPoints[i]); - m_boxArea.min.CheckMin(pPoints[i]); - - m_boxArea.max.CheckMax(pPoints[i] + Vec3(0, 0, m_fHeight)); - m_boxArea.min.CheckMin(pPoints[i] + Vec3(0, 0, m_fHeight)); - } - - UpdateGeometryBBox(); - UpdateClipVolume(); -} - - -void CVisArea::StaticReset() -{ - stl::free_container(m_lUnavailableAreas); - stl::free_container(s_tmpLstPortVertsClipped); - stl::free_container(s_tmpLstPortVertsSS); - stl::free_container(s_tmpPolygonA); - stl::free_container(s_tmpLstLights); - stl::free_container(s_tmpCameras); - s_tmpClipContext.Reset(); -} - -void CVisArea::Init() -{ - m_fGetDistanceThruVisAreasMinDistance = 10000.f; - m_nGetDistanceThruVisAreasLastCallID = -1; - m_pVisAreaColdData = NULL; - m_boxStatics.min = m_boxStatics.max = m_boxArea.min = m_boxArea.max = Vec3(0, 0, 0); - m_nRndFrameId = -1; - m_bActive = true; - m_fHeight = 0; - m_vAmbientColor(0, 0, 0); - m_vConnNormals[0] = m_vConnNormals[1] = Vec3(0, 0, 0); - m_bAffectedByOutLights = false; - m_fDistance = 0; - m_bOceanVisible = m_bSkyOnly = false; - memset(m_arrOcclCamera, 0, sizeof(m_arrOcclCamera)); - m_fViewDistRatio = 100.f; - m_bDoubleSide = true; - m_bUseDeepness = false; - m_bUseInIndoors = false; - m_bIgnoreSky = m_bThisIsPortal = false; - m_bIgnoreGI = false; - m_bIgnoreOutdoorAO = false; - m_lstCurCamerasCap = 0; - m_lstCurCamerasLen = 0; - m_lstCurCamerasIdx = 0; - m_nVisGUID = 0; - m_fPortalBlending = 0.5f; - m_nStencilRef = 0; -} - -CVisArea::CVisArea() -{ - Init(); -} - -CVisArea::CVisArea(VisAreaGUID visGUID) -{ - Init(); - m_nVisGUID = visGUID; -} - -CVisArea::~CVisArea() -{ - for (int i = 0; i < MAX_RECURSION_LEVELS; i++) - { - SAFE_DELETE(m_arrOcclCamera[i]); - } - - GetVisAreaManager()->OnVisAreaDeleted(this); - - if (m_pVisAreaColdData->m_dataType == eCDT_Portal) - { - SPortalColdData* pPortalColdData = static_cast(m_pVisAreaColdData); - if (pPortalColdData->m_pRNTmpData) - { - Get3DEngine()->FreeRNTmpData(&pPortalColdData->m_pRNTmpData); - } - } -} - -float LineSegDistanceSqr(const Vec3& vPos, const Vec3& vP0, const Vec3& vP1) -{ - // Dist of line seg A(+D) from origin: - // P = A + D t[0..1] - // d^2(t) = (A + D t)^2 = A^2 + 2 A*D t + D^2 t^2 - // d^2\t = 2 A*D + 2 D^2 t = 0 - // tmin = -A*D / D^2 clamp_tpl(0,1) - // Pmin = A + D tmin - Vec3 vP = vP0 - vPos; - Vec3 vD = vP1 - vP0; - float fN = -(vP * vD); - if (fN > 0.f) - { - float fD = vD.GetLengthSquared(); - if (fN >= fD) - { - vP += vD; - } - else - { - vP += vD * (fN / fD); - } - } - return vP.GetLengthSquared(); -} - -void CVisArea::FindSurroundingVisAreaReqursive(int nMaxReqursion, bool bSkipDisabledPortals, PodArray* pVisitedAreas, int nMaxVisitedAreas, int nDeepness, PodArray* pUnavailableAreas) -{ - pUnavailableAreas->Add(this); - - if (pVisitedAreas && pVisitedAreas->Count() < nMaxVisitedAreas) - { - pVisitedAreas->Add(this); - } - - if (nMaxReqursion > (nDeepness + 1)) - { - for (int p = 0; p < m_lstConnections.Count(); p++) - { - if (!bSkipDisabledPortals || m_lstConnections[p]->IsActive()) - { - if (-1 == pUnavailableAreas->Find(m_lstConnections[p])) - { - m_lstConnections[p]->FindSurroundingVisAreaReqursive(nMaxReqursion, bSkipDisabledPortals, pVisitedAreas, nMaxVisitedAreas, nDeepness + 1, pUnavailableAreas); - } - } - } - } -} - -void CVisArea::FindSurroundingVisArea(int nMaxReqursion, bool bSkipDisabledPortals, PodArray* pVisitedAreas, int nMaxVisitedAreas, int nDeepness) -{ - if (pVisitedAreas) - { - if (pVisitedAreas->capacity() < (uint32)nMaxVisitedAreas) - { - pVisitedAreas->PreAllocate(nMaxVisitedAreas); - } - } - - m_lUnavailableAreas.Clear(); - m_lUnavailableAreas.PreAllocate(nMaxVisitedAreas, 0); - - FindSurroundingVisAreaReqursive(nMaxReqursion, bSkipDisabledPortals, pVisitedAreas, nMaxVisitedAreas, nDeepness, &m_lUnavailableAreas); -} - -int CVisArea::GetVisFrameId() -{ - return m_nRndFrameId; -} - -bool Is2dLinesIntersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) -{ - float fDiv = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - - if (fabs(fDiv) < 0.00001f) - { - return false; - } - - float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / fDiv; - float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / fDiv; - - return ua > 0 && ua < 1 && ub > 0 && ub < 1; -} - - -Vec3 CVisArea::GetConnectionNormal(CVisArea* pPortal) -{ - assert(m_lstShapePoints.Count() >= 3); - // find side of shape intersecting with portal - int nIntersNum = 0; - Vec3 arrNormals[2] = {Vec3(0, 0, 0), Vec3(0, 0, 0)}; - for (int v = 0; v < m_lstShapePoints.Count(); v++) - { - nIntersNum = 0; - arrNormals[0] = Vec3(0, 0, 0); - arrNormals[1] = Vec3(0, 0, 0); - const Vec3& v0 = m_lstShapePoints[v]; - const Vec3& v1 = m_lstShapePoints[(v + 1) % m_lstShapePoints.Count()]; - for (int p = 0; p < pPortal->m_lstShapePoints.Count(); p++) - { - const Vec3& p0 = pPortal->m_lstShapePoints[p]; - const Vec3& p1 = pPortal->m_lstShapePoints[(p + 1) % pPortal->m_lstShapePoints.Count()]; - - if (Is2dLinesIntersect(v0.x, v0.y, v1.x, v1.y, p0.x, p0.y, p1.x, p1.y)) - { - Vec3 vNormal = (v0 - v1).GetNormalized().Cross(Vec3(0, 0, 1.f)); - if (nIntersNum < 2) - { - arrNormals[nIntersNum++] = (IsShapeClockwise()) ? -vNormal : vNormal; - } - } - } - - if (nIntersNum == 2) - { - break; - } - } - - if (nIntersNum == 2 && - //IsEquivalent(arrNormals[0] == arrNormals[1]) - arrNormals[0].IsEquivalent(arrNormals[1], VEC_EPSILON) - ) - { - return arrNormals[0]; - } - - { - int nBottomPoints = 0; - for (int p = 0; p < pPortal->m_lstShapePoints.Count() && p < 4; p++) - { - if (IsPointInsideVisArea(pPortal->m_lstShapePoints[p])) - { - nBottomPoints++; - } - } - - int nUpPoints = 0; - for (int p = 0; p < pPortal->m_lstShapePoints.Count() && p < 4; p++) - { - if (IsPointInsideVisArea(pPortal->m_lstShapePoints[p] + Vec3(0, 0, pPortal->m_fHeight))) - { - nUpPoints++; - } - } - - if (nBottomPoints == 0 && nUpPoints == 4) - { - return Vec3(0, 0, 1); - } - - if (nBottomPoints == 4 && nUpPoints == 0) - { - return Vec3(0, 0, -1); - } - } - - return Vec3(0, 0, 0); -} - -void CVisArea::UpdatePortalCameraPlanes(CCamera& cam, Vec3* pVerts, bool NotForcePlaneSet, const SRenderingPassInfo& passInfo) -{ - const Vec3& vCamPos = passInfo.GetCamera().GetPosition(); - Plane plane, farPlane; - - farPlane = *passInfo.GetCamera().GetFrustumPlane(FR_PLANE_FAR); - cam.SetFrustumPlane(FR_PLANE_FAR, farPlane); - - //plane.SetPlane(pVerts[0],pVerts[2],pVerts[1]); // can potentially create a plane facing the wrong way - plane.SetPlane(-farPlane.n, pVerts[0]); - cam.SetFrustumPlane(FR_PLANE_NEAR, plane); - - plane.SetPlane(vCamPos, pVerts[3], pVerts[2]); // update plane only if it reduces fov - if (!NotForcePlaneSet || plane.n.Dot(cam.GetFrustumPlane(FR_PLANE_LEFT)->n) < - cam.GetFrustumPlane(FR_PLANE_RIGHT)->n.Dot(cam.GetFrustumPlane(FR_PLANE_LEFT)->n)) - { - cam.SetFrustumPlane(FR_PLANE_RIGHT, plane); - } - - plane.SetPlane(vCamPos, pVerts[1], pVerts[0]); // update plane only if it reduces fov - if (!NotForcePlaneSet || plane.n.Dot(cam.GetFrustumPlane(FR_PLANE_RIGHT)->n) < - cam.GetFrustumPlane(FR_PLANE_LEFT)->n.Dot(cam.GetFrustumPlane(FR_PLANE_RIGHT)->n)) - { - cam.SetFrustumPlane(FR_PLANE_LEFT, plane); - } - - plane.SetPlane(vCamPos, pVerts[0], pVerts[3]); // update plane only if it reduces fov - if (!NotForcePlaneSet || plane.n.Dot(cam.GetFrustumPlane(FR_PLANE_TOP)->n) < - cam.GetFrustumPlane(FR_PLANE_BOTTOM)->n.Dot(cam.GetFrustumPlane(FR_PLANE_TOP)->n)) - { - cam.SetFrustumPlane(FR_PLANE_BOTTOM, plane); - } - - plane.SetPlane(vCamPos, pVerts[2], pVerts[1]); // update plane only if it reduces fov - if (!NotForcePlaneSet || plane.n.Dot(cam.GetFrustumPlane(FR_PLANE_BOTTOM)->n) < - cam.GetFrustumPlane(FR_PLANE_TOP)->n.Dot(cam.GetFrustumPlane(FR_PLANE_BOTTOM)->n)) - { - cam.SetFrustumPlane(FR_PLANE_TOP, plane); - } - - Vec3 arrvPortVertsCamSpace[4]; - for (int i = 0; i < 4; i++) - { - arrvPortVertsCamSpace[i] = pVerts[i] - cam.GetPosition(); - } - cam.SetFrustumVertices(arrvPortVertsCamSpace); - - //cam.UpdateFrustum(); - - if (GetCVars()->e_Portals == 5) - { - float farrColor[4] = {1, 1, 1, 1}; - // GetRenderer()->SetMaterialColor(1,1,1,1); - DrawLine(pVerts[0], pVerts[1]); - GetRenderer()->DrawLabelEx(pVerts[0], 1, farrColor, false, true, "0"); - DrawLine(pVerts[1], pVerts[2]); - GetRenderer()->DrawLabelEx(pVerts[1], 1, farrColor, false, true, "1"); - DrawLine(pVerts[2], pVerts[3]); - GetRenderer()->DrawLabelEx(pVerts[2], 1, farrColor, false, true, "2"); - DrawLine(pVerts[3], pVerts[0]); - GetRenderer()->DrawLabelEx(pVerts[3], 1, farrColor, false, true, "3"); - } -} - -int __cdecl CVisAreaManager__CmpDistToPortal(const void* v1, const void* v2); - -void CVisArea::PreRender(int nReqursionLevel, - CCamera CurCamera, CVisArea* pParent, CVisArea* pCurPortal, - bool* pbOutdoorVisible, PodArray* plstOutPortCameras, bool* pbSkyVisible, bool* pbOceanVisible, - PodArray& lstVisibleAreas, - const SRenderingPassInfo& passInfo) -{ - // mark as rendered - if (m_nRndFrameId != passInfo.GetFrameID()) - { - m_lstCurCamerasIdx = 0; - m_lstCurCamerasLen = 0; - if (m_lstCurCamerasCap) - { - m_lstCurCamerasIdx = s_tmpCameras.size(); - s_tmpCameras.resize(s_tmpCameras.size() + m_lstCurCamerasCap); - } - } - - m_nRndFrameId = passInfo.GetFrameID(); - - if (m_bAffectedByOutLights) - { - GetVisAreaManager()->m_bSunIsNeeded = true; - } - - if (m_lstCurCamerasLen == m_lstCurCamerasCap) - { - int newIdx = s_tmpCameras.size(); - - m_lstCurCamerasCap += max(1, m_lstCurCamerasCap / 2); - s_tmpCameras.resize(newIdx + m_lstCurCamerasCap); - if (m_lstCurCamerasLen) - { - memcpy(&s_tmpCameras[newIdx], &s_tmpCameras[m_lstCurCamerasIdx], m_lstCurCamerasLen * sizeof(CCamera)); - } - - m_lstCurCamerasIdx = newIdx; - } - s_tmpCameras[m_lstCurCamerasIdx + m_lstCurCamerasLen] = CurCamera; - ++m_lstCurCamerasLen; - - if (lstVisibleAreas.Find(this) < 0) - { - lstVisibleAreas.Add(this); - m_nStencilRef = GetRenderer()->EF_AddDeferredClipVolume(this); - } - - // check recursion and portal activity - if (!nReqursionLevel || !m_bActive) - { - return; - } - - if (pParent && m_bThisIsPortal && m_lstConnections.Count() == 1 && // detect entrance - !IsPointInsideVisArea(passInfo.GetCamera().GetPosition())) // detect camera in outdoors - { - AABB boxAreaEx = m_boxArea; - float fZNear = CurCamera.GetNearPlane(); - boxAreaEx.min -= Vec3(fZNear, fZNear, fZNear); - boxAreaEx.max += Vec3(fZNear, fZNear, fZNear); - if (!CurCamera.IsAABBVisible_E(boxAreaEx)) // if portal is invisible - { - return; // stop recursion - } - } - - bool bCanSeeThruThisArea = true; - - // prepare new camera for next areas - if (m_bThisIsPortal && m_lstConnections.Count() && - (this != pCurPortal || !pCurPortal->IsPointInsideVisArea(CurCamera.GetPosition()))) - { - Vec3 vCenter = m_boxArea.GetCenter(); - float fRadius = m_boxArea.GetRadius(); - - Vec3 vPortNorm = (!pParent || pParent == m_lstConnections[0] || m_lstConnections.Count() == 1) ? - m_vConnNormals[0] : m_vConnNormals[1]; - - // exit/entrance portal has only one normal in direction to outdoors, so flip it to the camera - if (m_lstConnections.Count() == 1 && !pParent) - { - vPortNorm = -vPortNorm; - } - - // back face check - Vec3 vPortToCamDir = CurCamera.GetPosition() - vCenter; - if (vPortToCamDir.Dot(vPortNorm) < 0) - { - return; - } - - if (!m_bDoubleSide) - { - if (vPortToCamDir.Dot(m_vConnNormals[0]) < 0) - { - return; - } - } - - Vec3 arrPortVerts[4]; - Vec3 arrPortVertsOtherSide[4]; - bool barrPortVertsOtherSideValid = false; - if (pParent && !vPortNorm.IsEquivalent(Vec3(0, 0, 0), VEC_EPSILON) && vPortNorm.z) - { // up/down portal - int nEven = IsShapeClockwise(); - if (vPortNorm.z > 0) - { - nEven = !nEven; - } - for (int i = 0; i < 4; i++) - { - arrPortVerts[i] = m_lstShapePoints[nEven ? (3 - i) : i] + Vec3(0, 0, m_fHeight) * (vPortNorm.z > 0); - arrPortVertsOtherSide[i] = m_lstShapePoints[nEven ? (3 - i) : i] + Vec3(0, 0, m_fHeight) * (vPortNorm.z < 0); - } - barrPortVertsOtherSideValid = true; - } - else if (!vPortNorm.IsEquivalent(Vec3(0, 0, 0), VEC_EPSILON) && vPortNorm.z == 0) - { // basic portal - Vec3 arrInAreaPoint[2] = {Vec3(0, 0, 0), Vec3(0, 0, 0)}; - int arrInAreaPointId[2] = {-1, -1}; - int nInAreaPointCounter = 0; - - Vec3 arrOutAreaPoint[2] = {Vec3(0, 0, 0), Vec3(0, 0, 0)}; - int nOutAreaPointCounter = 0; - - // find 2 points of portal in this area (or in this outdoors) - for (int i = 0; i < m_lstShapePoints.Count() && nInAreaPointCounter < 2; i++) - { - Vec3 vTestPoint = m_lstShapePoints[i] + Vec3(0, 0, m_fHeight * 0.5f); - CVisArea* pAnotherArea = m_lstConnections[0]; - if ((pParent && (pParent->IsPointInsideVisArea(vTestPoint))) || - (!pParent && (!pAnotherArea->IsPointInsideVisArea(vTestPoint)))) - { - arrInAreaPointId[nInAreaPointCounter] = i; - arrInAreaPoint[nInAreaPointCounter++] = m_lstShapePoints[i]; - } - } - - // find 2 points of portal not in this area (or not in this outdoors) - for (int i = 0; i < m_lstShapePoints.Count() && nOutAreaPointCounter < 2; i++) - { - Vec3 vTestPoint = m_lstShapePoints[i] + Vec3(0, 0, m_fHeight * 0.5f); - CVisArea* pAnotherArea = m_lstConnections[0]; - if ((pParent && (pParent->IsPointInsideVisArea(vTestPoint))) || - (!pParent && (!pAnotherArea->IsPointInsideVisArea(vTestPoint)))) - { - } - else - { - arrOutAreaPoint[nOutAreaPointCounter++] = m_lstShapePoints[i]; - } - } - - if (nInAreaPointCounter == 2) - { // success, take into account volume and portal shape versts order - int nEven = IsShapeClockwise(); - if (arrInAreaPointId[1] - arrInAreaPointId[0] != 1) - { - nEven = !nEven; - } - - arrPortVerts[0] = arrInAreaPoint[nEven]; - arrPortVerts[1] = arrInAreaPoint[nEven] + Vec3(0, 0, m_fHeight); - arrPortVerts[2] = arrInAreaPoint[!nEven] + Vec3(0, 0, m_fHeight); - arrPortVerts[3] = arrInAreaPoint[!nEven]; - - nEven = !nEven; - - arrPortVertsOtherSide[0] = arrOutAreaPoint[nEven]; - arrPortVertsOtherSide[1] = arrOutAreaPoint[nEven] + Vec3(0, 0, m_fHeight); - arrPortVertsOtherSide[2] = arrOutAreaPoint[!nEven] + Vec3(0, 0, m_fHeight); - arrPortVertsOtherSide[3] = arrOutAreaPoint[!nEven]; - barrPortVertsOtherSideValid = true; - } - else - { // something wrong - Warning("CVisArea::PreRender: Invalid portal: %s", m_pVisAreaColdData->m_sName); - return; - } - } - else if (!pParent && vPortNorm.z == 0 && m_lstConnections.Count() == 1) - { // basic entrance portal - Vec3 vBorder = (vPortNorm.Cross(Vec3(0, 0, 1.f))).GetNormalized() * fRadius; - arrPortVerts[0] = vCenter - Vec3(0, 0, 1.f) * fRadius - vBorder; - arrPortVerts[1] = vCenter + Vec3(0, 0, 1.f) * fRadius - vBorder; - arrPortVerts[2] = vCenter + Vec3(0, 0, 1.f) * fRadius + vBorder; - arrPortVerts[3] = vCenter - Vec3(0, 0, 1.f) * fRadius + vBorder; - } - else if (!pParent && vPortNorm.z != 0 && m_lstConnections.Count() == 1) - { // up/down entrance portal - Vec3 vBorder = (vPortNorm.Cross(Vec3(0, 1, 0.f))).GetNormalized() * fRadius; - arrPortVerts[0] = vCenter - Vec3(0, 1, 0.f) * fRadius + vBorder; - arrPortVerts[1] = vCenter + Vec3(0, 1, 0.f) * fRadius + vBorder; - arrPortVerts[2] = vCenter + Vec3(0, 1, 0.f) * fRadius - vBorder; - arrPortVerts[3] = vCenter - Vec3(0, 1, 0.f) * fRadius - vBorder; - } - else - { // something wrong or areabox portal - use simple solution - if (vPortNorm.IsEquivalent(Vec3(0, 0, 0), VEC_EPSILON)) - { - vPortNorm = (vCenter - passInfo.GetCamera().GetPosition()).GetNormalized(); - } - - Vec3 vBorder = (vPortNorm.Cross(Vec3(0, 0, 1.f))).GetNormalized() * fRadius; - arrPortVerts[0] = vCenter - Vec3(0, 0, 1.f) * fRadius - vBorder; - arrPortVerts[1] = vCenter + Vec3(0, 0, 1.f) * fRadius - vBorder; - arrPortVerts[2] = vCenter + Vec3(0, 0, 1.f) * fRadius + vBorder; - arrPortVerts[3] = vCenter - Vec3(0, 0, 1.f) * fRadius + vBorder; - } - - if (GetCVars()->e_Portals == 4) // make color recursion dependent - { - GetRenderer()->SetMaterialColor(1, 1, passInfo.IsGeneralPass(), 1); - } - - Vec3 vPortalFaceCenter = (arrPortVerts[0] + arrPortVerts[1] + arrPortVerts[2] + arrPortVerts[3]) / 4; - vPortToCamDir = CurCamera.GetPosition() - vPortalFaceCenter; - if (vPortToCamDir.GetNormalized().Dot(vPortNorm) < -0.01f) - { - UpdatePortalBlendInfo(); - return; - } - - const bool Upright = (fabsf(vPortNorm.z) < FLT_EPSILON); - CCamera camParent = CurCamera; - - // clip portal quad by camera planes - PodArray& lstPortVertsClipped = s_tmpLstPortVertsClipped; - lstPortVertsClipped.Clear(); - lstPortVertsClipped.AddList(arrPortVerts, 4); - ClipPortalVerticesByCameraFrustum(&lstPortVertsClipped, camParent); - - AABB aabb; - aabb.Reset(); - - if (lstPortVertsClipped.Count() > 2) - { - // find screen space bounds of clipped portal - for (int i = 0; i < lstPortVertsClipped.Count(); i++) - { - Vec3 vSS; - GetRenderer()->ProjectToScreen(lstPortVertsClipped[i].x, lstPortVertsClipped[i].y, lstPortVertsClipped[i].z, &vSS.x, &vSS.y, &vSS.z); - vSS.y = 100 - vSS.y; - aabb.Add(vSS); - } - } - else - { - if (!CVisArea::IsSphereInsideVisArea(CurCamera.GetPosition(), CurCamera.GetNearPlane())) - { - bCanSeeThruThisArea = false; - } - } - - if (lstPortVertsClipped.Count() > 2 && aabb.min.z > 0.01f) - { - PodArray& lstPortVertsSS = s_tmpLstPortVertsSS; - lstPortVertsSS.PreAllocate(4, 4); - - // get 3d positions of portal bounds - { - int i = 0; - float w = (float)GetRenderer()->GetWidth(); - float h = (float)GetRenderer()->GetHeight(); - float d = 0.01f; - - GetRenderer()->UnProjectFromScreen(aabb.min.x * w / 100, aabb.min.y * h / 100, d, &lstPortVertsSS[i].x, &lstPortVertsSS[i].y, &lstPortVertsSS[i].z); - i++; - GetRenderer()->UnProjectFromScreen(aabb.min.x * w / 100, aabb.max.y * h / 100, d, &lstPortVertsSS[i].x, &lstPortVertsSS[i].y, &lstPortVertsSS[i].z); - i++; - GetRenderer()->UnProjectFromScreen(aabb.max.x * w / 100, aabb.max.y * h / 100, d, &lstPortVertsSS[i].x, &lstPortVertsSS[i].y, &lstPortVertsSS[i].z); - i++; - GetRenderer()->UnProjectFromScreen(aabb.max.x * w / 100, aabb.min.y * h / 100, d, &lstPortVertsSS[i].x, &lstPortVertsSS[i].y, &lstPortVertsSS[i].z); - i++; - - CurCamera.m_ScissorInfo.x1 = uint16(CLAMP(aabb.min.x * w / 100, 0, w)); - CurCamera.m_ScissorInfo.y1 = uint16(CLAMP(aabb.min.y * h / 100, 0, h)); - CurCamera.m_ScissorInfo.x2 = uint16(CLAMP(aabb.max.x * w / 100, 0, w)); - CurCamera.m_ScissorInfo.y2 = uint16(CLAMP(aabb.max.y * h / 100, 0, h)); - } - - if (GetCVars()->e_Portals == 4) - { - for (int i = 0; i < lstPortVertsSS.Count(); i++) - { - float farrColor[4] = { float((nReqursionLevel & 1) > 0), float((nReqursionLevel & 2) > 0), float((nReqursionLevel & 4) > 0), 1}; - ColorF c(farrColor[0], farrColor[1], farrColor[2], farrColor[3]); - DrawSphere(lstPortVertsSS[i], 0.002f, c); - GetRenderer()->DrawLabelEx(lstPortVertsSS[i], 0.1f, farrColor, false, true, "%d", i); - } - } - - UpdatePortalCameraPlanes(CurCamera, lstPortVertsSS.GetElements(), Upright, passInfo); - - bCanSeeThruThisArea = - (CurCamera.m_ScissorInfo.x1 < CurCamera.m_ScissorInfo.x2) && - (CurCamera.m_ScissorInfo.y1 < CurCamera.m_ScissorInfo.y2); - } - - if (m_bUseDeepness && bCanSeeThruThisArea && barrPortVertsOtherSideValid) - { - Vec3 vOtherSideBoxMax = SetMinBB(); - Vec3 vOtherSideBoxMin = SetMaxBB(); - for (int i = 0; i < 4; i++) - { - vOtherSideBoxMin.CheckMin(arrPortVertsOtherSide[i] - Vec3(0.01f, 0.01f, 0.01f)); - vOtherSideBoxMax.CheckMax(arrPortVertsOtherSide[i] + Vec3(0.01f, 0.01f, 0.01f)); - } - - bCanSeeThruThisArea = CurCamera.IsAABBVisible_E(AABB(vOtherSideBoxMin, vOtherSideBoxMax)); - } - - if (bCanSeeThruThisArea && pParent && m_lstConnections.Count() == 1) - { // set this camera for outdoor - if (nReqursionLevel >= 1) - { - if (!m_bSkyOnly) - { - if (plstOutPortCameras) - { - plstOutPortCameras->Add(CurCamera); - plstOutPortCameras->Last().m_pPortal = this; - } - if (pbOutdoorVisible) - { - *pbOutdoorVisible = true; - } - } - else if (pbSkyVisible) - { - *pbSkyVisible = true; - } - } - - UpdatePortalBlendInfo(); - return; - } - } - - // sort portals by distance - if (!m_bThisIsPortal && m_lstConnections.Count()) - { - for (int p = 0; p < m_lstConnections.Count(); p++) - { - CVisArea* pNeibVolume = m_lstConnections[p]; - pNeibVolume->m_fDistance = CurCamera.GetPosition().GetDistance((pNeibVolume->m_boxArea.min + pNeibVolume->m_boxArea.max) * 0.5f); - } - - qsort(&m_lstConnections[0], m_lstConnections.Count(), - sizeof(m_lstConnections[0]), CVisAreaManager__CmpDistToPortal); - } - - if (m_bOceanVisible && pbOceanVisible) - { - *pbOceanVisible = true; - } - - // recurse to connections - for (int p = 0; p < m_lstConnections.Count(); p++) - { - CVisArea* pNeibVolume = m_lstConnections[p]; - if (pNeibVolume != pParent) - { - if (!m_bThisIsPortal) - { // skip far portals - float fRadius = (pNeibVolume->m_boxArea.max - pNeibVolume->m_boxArea.min).GetLength() * 0.5f * GetFloatCVar(e_ViewDistRatioPortals) / 60.f; - if (pNeibVolume->m_fDistance * passInfo.GetZoomFactor() > fRadius * pNeibVolume->m_fViewDistRatio) - { - continue; - } - - Vec3 vPortNorm = (this == pNeibVolume->m_lstConnections[0] || pNeibVolume->m_lstConnections.Count() == 1) ? - pNeibVolume->m_vConnNormals[0] : pNeibVolume->m_vConnNormals[1]; - - // back face check - Vec3 vPortToCamDir = CurCamera.GetPosition() - pNeibVolume->GetAABBox()->GetCenter(); - if (vPortToCamDir.Dot(vPortNorm) < 0) - { - continue; - } - } - - if ((bCanSeeThruThisArea || m_lstConnections.Count() == 1) && (m_bThisIsPortal || CurCamera.IsAABBVisible_F(pNeibVolume->m_boxStatics))) - { - pNeibVolume->PreRender(nReqursionLevel - 1, CurCamera, this, pCurPortal, pbOutdoorVisible, plstOutPortCameras, pbSkyVisible, pbOceanVisible, lstVisibleAreas, passInfo); - } - } - } - - if (m_bThisIsPortal) - { - UpdatePortalBlendInfo(); - } -} - -//! return list of visareas connected to specified visarea (can return portals and sectors) -int CVisArea::GetRealConnections(IVisArea** pAreas, int nMaxConnNum, [[maybe_unused]] bool bSkipDisabledPortals) -{ - int nOut = 0; - for (int nArea = 0; nArea < m_lstConnections.Count(); nArea++) - { - if (nOut < nMaxConnNum) - { - pAreas[nOut] = (IVisArea*)m_lstConnections[nArea]; - } - nOut++; - } - return nOut; -} - -//! return list of sectors conected to specified sector or portal (returns sectors only) -// todo: change the way it returns data -int CVisArea::GetVisAreaConnections(IVisArea** pAreas, int nMaxConnNum, bool bSkipDisabledPortals) -{ - int nOut = 0; - if (IsPortal()) - { - /* for(int nArea=0; nAreaIsPortal()); - for (int nArea = 0; nArea < pPortal->m_lstConnections.Count(); nArea++) - { - if (pPortal->m_lstConnections[nArea] != this) - { - if (!bSkipDisabledPortals || pPortal->IsActive()) - { - if (nOut < nMaxConnNum) - { - pAreas[nOut] = (IVisArea*)pPortal->m_lstConnections[nArea]; - } - nOut++; - break; // take first valid connection - } - } - } - } - } - - return min(nMaxConnNum, nOut); -} - -bool CVisArea::IsPortalValid() -{ - int nCount = m_lstConnections.Count(); - if (nCount > 2 || nCount == 0) - { - return false; - } - - for (int i = 0; i < nCount; i++) - { - if (m_vConnNormals[i].IsEquivalent(Vec3(0, 0, 0), VEC_EPSILON)) - { - return false; - } - } - - if (nCount > 1) - { - if (m_vConnNormals[0].Dot(m_vConnNormals[1]) > -0.99f) - { - return false; - } - } - - return true; -} - -bool CVisArea::IsPortalIntersectAreaInValidWay(CVisArea* pPortal) -{ - const Vec3& v1Min = pPortal->m_boxArea.min; - const Vec3& v1Max = pPortal->m_boxArea.max; - const Vec3& v2Min = m_boxArea.min; - const Vec3& v2Max = m_boxArea.max; - - if (v1Max.x > v2Min.x && v2Max.x > v1Min.x) - { - if (v1Max.y > v2Min.y && v2Max.y > v1Min.y) - { - if (v1Max.z > v2Min.z && v2Max.z > v1Min.z) - { - // vertical portal - for (int v = 0; v < m_lstShapePoints.Count(); v++) - { - int nIntersNum = 0; - bool arrIntResult[4] = { 0, 0, 0, 0 }; - for (int p = 0; p < pPortal->m_lstShapePoints.Count() && p < 4; p++) - { - const Vec3& v0 = m_lstShapePoints[v]; - const Vec3& v1 = m_lstShapePoints[(v + 1) % m_lstShapePoints.Count()]; - const Vec3& p0 = pPortal->m_lstShapePoints[p]; - const Vec3& p1 = pPortal->m_lstShapePoints[(p + 1) % pPortal->m_lstShapePoints.Count()]; - - if (Is2dLinesIntersect(v0.x, v0.y, v1.x, v1.y, p0.x, p0.y, p1.x, p1.y)) - { - nIntersNum++; - arrIntResult[p] = true; - } - } - if (nIntersNum == 2 && arrIntResult[0] == arrIntResult[2] && arrIntResult[1] == arrIntResult[3]) - { - return true; - } - } - - // horisontal portal - { - int nBottomPoints = 0, nUpPoints = 0; - for (int p = 0; p < pPortal->m_lstShapePoints.Count() && p < 4; p++) - { - if (IsPointInsideVisArea(pPortal->m_lstShapePoints[p])) - { - nBottomPoints++; - } - } - - for (int p = 0; p < pPortal->m_lstShapePoints.Count() && p < 4; p++) - { - if (IsPointInsideVisArea(pPortal->m_lstShapePoints[p] + Vec3(0, 0, pPortal->m_fHeight))) - { - nUpPoints++; - } - } - - if (nBottomPoints == 0 && nUpPoints == 4) - { - return true; - } - - if (nBottomPoints == 4 && nUpPoints == 0) - { - return true; - } - } - } - } - } - - return false; -} - - -/* -void CVisArea::SetTreeId(int nTreeId) -{ - if(m_nTreeId == nTreeId) - return; - - m_nTreeId = nTreeId; - - for(int p=0; pSetTreeId(nTreeId); -} -*/ -bool CVisArea::IsShapeClockwise() -{ - float fClockWise = - (m_lstShapePoints[0].x - m_lstShapePoints[1].x) * (m_lstShapePoints[2].y - m_lstShapePoints[1].y) - - (m_lstShapePoints[0].y - m_lstShapePoints[1].y) * (m_lstShapePoints[2].x - m_lstShapePoints[1].x); - - return fClockWise > 0; -} - -void CVisArea::DrawAreaBoundsIntoCBuffer([[maybe_unused]] CCullBuffer* pCBuffer) -{ - assert(!"temprary not supported"); - - /* if(m_lstShapePoints.Count()!=4) - return; - - Vec3 arrVerts[8]; - int arrIndices[24]; - - int v=0; - int i=0; - for(int p=0; p<4 && pAddMesh(arrVerts,8,arrIndices,24,&mat);*/ -} - -void CVisArea::ClipPortalVerticesByCameraFrustum(PodArray* pPolygon, const CCamera& cam) -{ - Plane planes[5] = { - *cam.GetFrustumPlane(FR_PLANE_RIGHT), - *cam.GetFrustumPlane(FR_PLANE_LEFT), - *cam.GetFrustumPlane(FR_PLANE_TOP), - *cam.GetFrustumPlane(FR_PLANE_BOTTOM), - *cam.GetFrustumPlane(FR_PLANE_NEAR) - }; - - const PodArray& clipped = s_tmpClipContext.Clip(*pPolygon, planes, 4); - - pPolygon->Clear(); - pPolygon->AddList(clipped); -} - -void CVisArea::GetMemoryUsage(ICrySizer* pSizer) -{ - // pSizer->AddContainer(m_lstEntities[STATIC_OBJECTS]); - //pSizer->AddContainer(m_lstEntities[DYNAMIC_OBJECTS]); - - // TODO: include obects tree - - - if (m_pObjectsTree) - { - SIZER_COMPONENT_NAME(pSizer, "IndoorObjectsTree"); - m_pObjectsTree->GetMemoryUsage(pSizer); - } - - // for(int nStatic=0; nStatic<2; nStatic++) - //for(int i=0; iGetMemoryUsage(); - - pSizer->AddObject(this, sizeof(*this)); -} - -void CVisArea::AddConnectedAreas(PodArray& lstAreas, int nMaxRecursion) -{ - if (lstAreas.Find(this) < 0) - { - lstAreas.Add(this); - - // add connected areas - if (nMaxRecursion) - { - nMaxRecursion--; - - for (int p = 0; p < m_lstConnections.Count(); p++) - { - m_lstConnections[p]->AddConnectedAreas(lstAreas, nMaxRecursion); - } - } - } -} - -bool CVisArea::GetDistanceThruVisAreas(AABB vCurBoxIn, IVisArea* pTargetArea, const AABB& targetBox, int nMaxReqursion, float& fResDist) -{ - return GetDistanceThruVisAreasReq(vCurBoxIn, 0, pTargetArea, targetBox, nMaxReqursion, fResDist, NULL, s_nGetDistanceThruVisAreasCallCounter++); -} - -float DistanceAABB(const AABB& aBox, const AABB& bBox) -{ - float result = 0; - - for (int i = 0; i < 3; ++i) - { - const float& aMin = aBox.min[i]; - const float& aMax = aBox.max[i]; - const float& bMin = bBox.min[i]; - const float& bMax = bBox.max[i]; - - if (aMin > bMax) - { - const float delta = bMax - aMin; - - result += delta * delta; - } - else if (bMin > aMax) - { - const float delta = aMax - bMin; - - result += delta * delta; - } - // else the projection intervals overlap. - } - - return sqrt(result); -} - -bool CVisArea::GetDistanceThruVisAreasReq(AABB vCurBoxIn, float fCurDistIn, IVisArea* pTargetArea, const AABB& targetBox, int nMaxReqursion, float& fResDist, CVisArea* pPrevArea, int nCallID) -{ - if (pTargetArea == this || (pTargetArea == NULL && IsConnectedToOutdoor())) - { // target area is found - fResDist = min(fResDist, fCurDistIn + DistanceAABB(vCurBoxIn, targetBox)); - return true; - } - - // if we already visited this area and last time input distance was smaller - makes no sence to continue - if (nCallID == m_nGetDistanceThruVisAreasLastCallID) - { - if (fCurDistIn >= m_fGetDistanceThruVisAreasMinDistance) - { - return false; - } - } - - m_nGetDistanceThruVisAreasLastCallID = nCallID; - m_fGetDistanceThruVisAreasMinDistance = fCurDistIn; - - fResDist = FLT_MAX; - - bool bFound = false; - - if (nMaxReqursion > 1) - { - for (int p = 0; p < m_lstConnections.Count(); p++) - { - if ((m_lstConnections[p] != pPrevArea) && m_lstConnections[p]->IsActive()) - { - AABB vCurBox = vCurBoxIn; - float fCurDist = fCurDistIn; - float dist = FLT_MAX; - - if (IsPortal()) - { - vCurBox = vCurBoxIn; - fCurDist = fCurDistIn; - } - else - { - vCurBox = *m_lstConnections[p]->GetAABBox(); - fCurDist = fCurDistIn + DistanceAABB(vCurBox, vCurBoxIn); - } - - if (m_lstConnections[p]->GetDistanceThruVisAreasReq(vCurBox, fCurDist, pTargetArea, targetBox, nMaxReqursion - 1, dist, this, nCallID)) - { - bFound = true; - fResDist = min(fResDist, dist); - } - } - } - } - - return bFound; -} - -void CVisArea::OffsetPosition(const Vec3& delta) -{ - m_boxArea.Move(delta); - m_boxStatics.Move(delta); - for (int i = 0; i < m_lstShapePoints.Count(); i++) - { - m_lstShapePoints[i] += delta; - } - if (m_pObjectsTree) - { - m_pObjectsTree->OffsetObjects(delta); - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/VisAreas.h b/Code/CryEngine/Cry3DEngine/VisAreas.h deleted file mode 100644 index 4fbc5ce421..0000000000 --- a/Code/CryEngine/Cry3DEngine/VisAreas.h +++ /dev/null @@ -1,387 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : visibility areas header - - -#ifndef CRYINCLUDE_CRY3DENGINE_VISAREAS_H -#define CRYINCLUDE_CRY3DENGINE_VISAREAS_H -#pragma once - -#include "BasicArea.h" -#include "CullBuffer.h" - -// Unique identifier for each VisArea instance -typedef unsigned int VisAreaId; - -typedef uint64 VisAreaGUID; - -#define ReservedVisAreaBytes 384 - -enum EVisAreaColdDataType -{ - eCDT_Generic = 0, - eCDT_Portal -}; - -struct SGenericColdData -{ - SGenericColdData() - { - m_dataType = eCDT_Generic; - } - - ILINE void ResetGenericData() - { - m_dataType = eCDT_Generic; - } - - EVisAreaColdDataType m_dataType; - char m_sName[64]; -}; - -struct SPortalColdData - : public SGenericColdData -{ - SPortalColdData() - { - m_dataType = eCDT_Portal; - m_pRNTmpData = NULL; - } - - ILINE void ResetPortalData() - { - m_dataType = eCDT_Portal; - } - - struct CRNTmpData* m_pRNTmpData; -}; - -struct CVisArea - : public IVisArea - , public CBasicArea -{ - static void StaticReset(); - - // editor interface - virtual void Update(const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info); - - CVisArea(); - CVisArea(VisAreaGUID visGUID); - virtual ~CVisArea(); - - bool operator ==(const CVisArea& v1) const { return &v1 == this; } - - void Init(); - ILINE SGenericColdData* GetColdData() { return m_pVisAreaColdData; } - ILINE void SetColdDataPtr(SGenericColdData* pColdData) { m_pVisAreaColdData = pColdData; } - bool IsSphereInsideVisArea(const Vec3& vPos, const f32 fRadius); - bool IsPointInsideVisArea(const Vec3& vPos) const; - bool IsBoxOverlapVisArea(const AABB& objBox); - bool ClipToVisArea(bool bInside, Sphere& sphere, Vec3 const& vNormal); - bool FindVisArea(IVisArea* pAnotherArea, int nMaxRecursion, bool bSkipDisabledPortals); - bool FindVisAreaReqursive(IVisArea* pAnotherArea, int nMaxReqursion, bool bSkipDisabledPortals, StaticDynArray& arrVisitedParents); - bool GetDistanceThruVisAreas(AABB vCurBoxIn, IVisArea* pTargetArea, const AABB& targetBox, int nMaxReqursion, float& fResDist); - bool GetDistanceThruVisAreasReq(AABB vCurBoxIn, float fCurDistIn, IVisArea* pTargetArea, const AABB& targetBox, int nMaxReqursion, float& fResDist, CVisArea* pPrevArea, int nCallID); - void FindSurroundingVisArea(int nMaxReqursion, bool bSkipDisabledPortals, PodArray* pVisitedAreas = NULL, int nMaxVisitedAreas = 0, int nDeepness = 0); - void FindSurroundingVisAreaReqursive(int nMaxReqursion, bool bSkipDisabledPortals, PodArray* pVisitedAreas, int nMaxVisitedAreas, int nDeepness, PodArray* pUnavailableAreas); - int GetVisFrameId(); - Vec3 GetConnectionNormal(CVisArea* pPortal); - void PreRender(int nReqursionLevel, CCamera CurCamera, CVisArea* pParent, CVisArea* pCurPortal, bool* pbOutdoorVisible, PodArray* plstOutPortCameras, bool* pbSkyVisible, bool* pbOceanVisible, PodArray& lstVisibleAreas, const SRenderingPassInfo& passInfo); - void UpdatePortalCameraPlanes(CCamera& cam, Vec3* pVerts, bool bMergeFrustums, const SRenderingPassInfo& passInfo); - int GetVisAreaConnections(IVisArea** pAreas, int nMaxConnNum, bool bSkipDisabledPortals = false); - int GetRealConnections(IVisArea** pAreas, int nMaxConnNum, bool bSkipDisabledPortals = false); - bool IsPortalValid(); - bool IsPortalIntersectAreaInValidWay(CVisArea* pPortal); - bool IsPortal() const; - bool IsShapeClockwise(); - bool IsAffectedByOutLights() const { return m_bAffectedByOutLights; } - bool IsActive() { return m_bActive || (GetCVars()->e_Portals == 4); } - void UpdateGeometryBBox(); - void UpdateClipVolume(); - void UpdatePortalBlendInfo(); - void DrawAreaBoundsIntoCBuffer(class CCullBuffer* pCBuffer); - void ClipPortalVerticesByCameraFrustum(PodArray* pPolygon, const CCamera& cam); - void GetMemoryUsage(ICrySizer* pSizer); - bool IsConnectedToOutdoor() const; - bool IsIgnoringGI() const { return m_bIgnoreGI; } - bool IsIgnoringOutdoorAO() const { return m_bIgnoreOutdoorAO; } - - const char* GetName() { return m_pVisAreaColdData->m_sName; } -# if ENGINE_ENABLE_COMPILATION - int SaveHeader(byte*& pData, int& nDataSize); - int SaveObjectsTree(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, byte* pHead); - int GetData(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); - int GetSegmentData(byte*& pData, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); -# endif - template - int LoadHeader_T(T& f, int& nDataSizeLeft, EEndian eEndian, int& objBlockSize); - template - int LoadObjectsTree_T(T& f, int& nDataSizeLeft, int nSID, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, const int objBlockSize); - template - int Load_T(T& f, int& nDataSize, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); - int Load(byte*& f, int& nDataSizeLeft, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); - int Load(AZ::IO::HandleType& fileHandle, int& nDataSizeLeft, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); - const AABB* GetAABBox() const; - const AABB* GetStaticObjectAABBox() const; - void AddConnectedAreas(PodArray& lstAreas, int nMaxRecursion); - void GetShapePoints(const Vec3*& pPoints, size_t& nPoints); - float GetHeight(); - float CalcSignedArea(); - - bool CalcPortalBlendPlanes(Vec3 camPos); - virtual void GetClipVolumeMesh(_smart_ptr& renderMesh, Matrix34& worldTM) const; - virtual AABB GetClipVolumeBBox() const { return *GetStaticObjectAABBox(); } - virtual uint8 GetStencilRef() const { return m_nStencilRef; } - virtual uint GetClipVolumeFlags() const; - virtual bool IsPointInsideClipVolume(const Vec3& vPos) const { return IsPointInsideVisArea(vPos); } - - void OffsetPosition(const Vec3& delta); - static VisAreaGUID GetGUIDFromFile(byte* f, EEndian eEndian); - VisAreaGUID GetGUID() const { return m_nVisGUID; } - - static PodArray m_lUnavailableAreas; - static PodArray s_tmpLstPortVertsClipped; - static PodArray s_tmpLstPortVertsSS; - static PodArray s_tmpPolygonA; - static PodArray s_tmpLstLights; - static CPolygonClipContext s_tmpClipContext; - static PodArray s_tmpCameras; - static int s_nGetDistanceThruVisAreasCallCounter; - - VisAreaGUID m_nVisGUID; - PodArray m_lstConnections; - Vec3 m_vConnNormals[2]; - int m_nRndFrameId; - float m_fGetDistanceThruVisAreasMinDistance; - int m_nGetDistanceThruVisAreasLastCallID; - float m_fPortalBlending; - - PodArray m_lstShapePoints; - float m_fHeight; - - _smart_ptr m_pClipVolumeMesh; - - Vec3 m_vAmbientColor; - float m_fDistance; - float m_fViewDistRatio; - CCamera* m_arrOcclCamera[MAX_RECURSION_LEVELS]; - int m_lstCurCamerasLen; - int m_lstCurCamerasCap; - int m_lstCurCamerasIdx; - uint8 m_nStencilRef; - SGenericColdData* m_pVisAreaColdData; - bool m_bAffectedByOutLights; - bool m_bSkyOnly; - bool m_bOceanVisible; - bool m_bDoubleSide; - bool m_bUseDeepness; - bool m_bUseInIndoors; - bool m_bThisIsPortal; - bool m_bIgnoreSky; - bool m_bActive; - bool m_bIgnoreGI; - bool m_bIgnoreOutdoorAO; -}; - -struct CSWVisArea - : public CVisArea - , public _i_reference_target_t -{ - CSWVisArea() - : CVisArea() - , m_nSlotID(-1) {} - ~CSWVisArea() {} - - void Release() - { - --m_nRefCounter; - if (m_nRefCounter < 0) - { - assert(0); - CryFatalError("Deleting Reference Counted Object Twice"); - } - } - - int Load(byte*& f, int& nDataSizeLeft, int nSID, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, const Vec2& indexOffset); - - int m_nSlotID; -}; - -struct SAABBTreeNode -{ - SAABBTreeNode(PodArray& lstAreas, AABB box, int nMaxRecursion = 0); - ~SAABBTreeNode(); - CVisArea* FindVisarea(const Vec3& vPos); - SAABBTreeNode* GetTopNode(const AABB& box, void** pNodeCache); - bool IntersectsVisAreas(const AABB& box); - int ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal); - void OffsetPosition(const Vec3& delta); - - AABB nodeBox; - PodArray nodeAreas; - SAABBTreeNode* arrChilds[2]; -}; - -struct TTopologicalSorter; - -struct CVisAreaSegmentData -{ - // active vis areas in current segment - std::vector m_visAreaIndices; -}; - -struct CVisAreaManager - : public IVisAreaManager - , Cry3DEngineBase -{ - CVisArea* m_pCurArea, * m_pCurPortal; - PodArray m_lstActiveEntransePortals; - - PodArray m_lstVisAreas; - PodArray m_lstPortals; - PodArray m_lstOcclAreas; - PodArray m_segVisAreas; - PodArray m_segPortals; - PodArray m_segOcclAreas; - PodArray m_lstActiveOcclVolumes; - PodArray m_lstIndoorActiveOcclVolumes; - PodArray m_lstVisibleAreas; - PodArray m_tmpLstUnavailableAreas; - PodArray m_tmpLstLightBoxAreas; - bool m_bOutdoorVisible; - bool m_bSkyVisible; - bool m_bOceanVisible; - bool m_bSunIsNeeded; - PodArray m_lstOutdoorPortalCameras; - PodArray m_lstCallbacks; - SAABBTreeNode* m_pAABBTree; - - CVisAreaManager(); - ~CVisAreaManager(); - void UpdateAABBTree(); - void SetCurAreas(const SRenderingPassInfo& passInfo); - PodArray* GetActiveEntransePortals() { return &m_lstActiveEntransePortals; } - void PortalsDrawDebug(); - bool IsEntityVisible(IRenderNode* pEnt); - bool IsOutdoorAreasVisible() override; - bool IsSkyVisible(); - bool IsOceanVisible(); - CVisArea* CreateVisArea(VisAreaGUID visGUID); - bool DeleteVisArea(CVisArea* pVisArea); - bool SetEntityArea(IRenderNode* pEnt, const AABB& objBox, const float fObjRadiusSqr); - void CheckVis(const SRenderingPassInfo& passInfo); - void DrawVisibleSectors(const SRenderingPassInfo& passInfo, SRendItemSorter& rendItemSorter); - void ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName); - void UpdateVisArea(CVisArea* pArea, const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info); - virtual void UpdateConnections(); - void MoveObjectsIntoList(PodArray* plstVisAreasEntities, const AABB& boxArea, bool bRemoveObjects = false); - IVisArea* GetVisAreaFromPos(const Vec3& vPos); - bool IntersectsVisAreas(const AABB& box, void** pNodeCache = 0); - bool ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal, void* pNodeCache = 0); - bool IsEntityVisAreaVisible(IRenderNode* pEnt, int nMaxReqursion, const CDLight* pLight, const SRenderingPassInfo& passInfo); - void MakeActiveEntransePortalsList(const CCamera* pCamera, PodArray& lstActiveEntransePortals, CVisArea* pThisPortal, const SRenderingPassInfo& passInfo); - void DrawOcclusionAreasIntoCBuffer(CCullBuffer* pCBuffer, const SRenderingPassInfo& passInfo); - bool IsValidVisAreaPointer(CVisArea* pVisArea); - void GetStreamingStatus(int& nLoadedSectors, int& nTotalSectors); - void GetMemoryUsage(ICrySizer* pSizer) const; - bool IsOccludedByOcclVolumes(const AABB& objBox, const SRenderingPassInfo& passInfo, bool bCheckOnlyIndoorVolumes = false); - void GetObjectsAround(Vec3 vExploPos, float fExploRadius, PodArray* pEntList, bool bSkip_ERF_NO_DECALNODE_DECALS = false, bool bSkipDynamicObjects = false); - void IntersectWithBox(const AABB& aabbBox, PodArray* plstResult, bool bOnlyIfVisible); - template - bool Load_T(T& f, int& nDataSize, struct SVisAreaManChunkHeader* pVisAreaManagerChunkHeader, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo); - virtual bool Load(AZ::IO::HandleType& fileHandle, int& nDataSize, struct SVisAreaManChunkHeader* pVisAreaManagerChunkHeader, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable); - virtual bool SetCompiledData(byte* pData, int nDataSize, std::vector** ppStatObjTable, std::vector<_smart_ptr>** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo); - virtual bool GetCompiledData(byte* pData, int nDataSize, std::vector** ppStatObjTable, std::vector<_smart_ptr>** ppMatTable, std::vector** ppStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo); - virtual int GetCompiledDataSize(SHotUpdateInfo* pExportInfo); - void UnregisterEngineObjectsInArea(const SHotUpdateInfo* pExportInfo, PodArray& arrUnregisteredObjects, bool bOnlyEngineObjects); - void PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum); - bool IsEntityVisAreaVisibleReqursive(CVisArea* pVisArea, int nMaxReqursion, PodArray* pUnavailableAreas, const CDLight* pLight, const SRenderingPassInfo& passInfo); - bool IsAABBVisibleFromPoint(AABB& aabb, Vec3 vPos); - bool FindShortestPathToVisArea(CVisArea* pThisArea, CVisArea* pTargetArea, PodArray& arrVisitedAreas, int& nRecursion, const struct Shadowvolume& sv); - - int GetNumberOfVisArea() const; // the function give back the accumlated number of visareas and portals - IVisArea* GetVisAreaById(int nID) const; // give back the visarea interface based on the id (0..GetNumberOfVisArea()) it can be a visarea or a portal - - virtual void AddListener(IVisAreaCallback* pListener); - virtual void RemoveListener(IVisAreaCallback* pListener); - - virtual void CloneRegion(const AABB& region, const Vec3& offset, float zRotation); - virtual void ClearRegion(const AABB& region); - - void InitAABBTree(); - - // ------------------------------------- - - void GetObjectsByType(PodArray& lstObjects, EERType objType, const AABB* pBBox, ObjectTreeQueryFilterCallback filterCallback = nullptr) override; - void GetObjectsByFlags(uint dwFlags, PodArray& lstObjects); - - void GetNearestCubeProbe(float& fMinDistance, int& nMaxPriority, CLightEntity*& pNearestLight, const AABB* pBBox); - - void GetObjects(PodArray& lstObjects, const AABB* pBBox); - CVisArea* GetCurVisArea() { return m_pCurArea ? m_pCurArea : m_pCurPortal; } - void GenerateStatObjAndMatTables(std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, SHotUpdateInfo* pExportInfo); - void OnVisAreaDeleted(IVisArea* pArea); - void ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, IGeneralMemoryHeap* pHeap); - - virtual void PrepareSegmentData(const AABB& box); - virtual void ReleaseInactiveSegments(); - virtual bool CreateSegment(int nSID); - virtual bool DeleteSegment(int nSID, bool bDeleteNow); - virtual bool StreamCompiledData(uint8* pData, int nDataSize, int nSID, std::vector* pStatObjTable, std::vector<_smart_ptr>* pMatTable, std::vector* pStatInstGroupTable, const Vec2& vIndexOffset); - virtual void OffsetPosition(const Vec3& delta); - -private: - void DeleteAllVisAreas(); - - CVisArea* CreateTypeVisArea(); - CVisArea* CreateTypePortal(); - CVisArea* CreateTypeOcclArea(); - - void DeleteVisAreaSegment(int nSID, PodArray& visAreaSegmentData, PodArray& lstVisAreas, PodArray& visAreas, PodArray& deletedVisAreas); - CVisArea* FindVisAreaByGuid(VisAreaGUID guid, PodArray& lstVisAreas); - CSWVisArea* FindFreeVisAreaFromPool(PodArray& visAreas); - template - CSWVisArea* CreateVisAreaFromPool(PodArray& lstVisAreas, PodArray& visAreas, PodArray& visAreaColdData, bool bIsPortal); - template - void ResetVisAreaList(PodArray& lstVisAreas, PodArray& visAreas, PodArray& visAreaColdData); - template - CSWVisArea* CreateTypeArea(PodArray& visAreas, PodArray& visAreaColdData, bool bIsPortal); - - PodArray m_portals; - PodArray m_visAreas; - PodArray m_occlAreas; - - PodArray m_visAreaColdData; - PodArray m_portalColdData; - PodArray m_occlAreaColdData; - - PodArray m_visAreaSegmentData; - PodArray m_portalSegmentData; - PodArray m_occlAreaSegmentData; - - PodArray m_arrDeletedVisArea; - PodArray m_arrDeletedPortal; - PodArray m_arrDeletedOcclArea; - - struct SActiveVerts - { - Vec3 arrvActiveVerts[4]; - }; - -#if defined(OCCLUSIONCULLER_W) - std::vector m_allActiveVerts; -#endif -}; - -#endif // CRYINCLUDE_CRY3DENGINE_VISAREAS_H diff --git a/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.cpp b/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.cpp deleted file mode 100644 index 173aded389..0000000000 --- a/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.cpp +++ /dev/null @@ -1,1148 +0,0 @@ -// Modifications copyright Amazon.com, Inc. or its affiliates. - -/* -Perlin Noise -https://mrl.nyu.edu/~perlin/doc/oscar.html - -Copyright Ken Perlin - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -*/ - -#include "Cry3DEngine_precompiled.h" - -#include "VolumeObjectDataCreate.h" - -#include -#include -#include "Cry_LegacyPhysUtils.h" - -namespace -{ - ////////////////////////////////////////////////////////////////////////// - // Coherent noise function over 1, 2 or 3 dimensions - // (copyright Ken Perlin) - - #define B 0x100 - #define BM 0xff - #define N 0x1000 - #define NP 12 /* 2^N */ - #define NM 0xfff - - #define s_curve(t) (t * t * (3. - 2. * t)) - #define lerp(t, a, b) (a + t * (b - a)) - #define setup(i, b0, b1, r0, r1) \ - t = vec[i] + N; \ - b0 = ((int)t) & BM; \ - b1 = (b0 + 1) & BM; \ - r0 = t - (int)t; \ - r1 = r0 - 1.; - #define at2(rx, ry) (rx * q[0] + ry * q[1]) - #define at3(rx, ry, rz) (rx * q[0] + ry * q[1] + rz * q[2]) - - void init(void); - //double noise1(double); - //double noise2(double *); - double noise3(double*); - //void normalize2(double *); - void normalize3(double*); - - //double PerlinNoise1D(double,double,double,int); - //double PerlinNoise2D(double,double,double,double,int); - float PerlinNoise3D(double, double, double, double, double, int); - - static int pp[B + B + 2]; - //static double g1[B + B + 2]; - //static double g2[B + B + 2][2]; - static double g3[B + B + 2][3]; - static int start = 1; - - //double noise1(double arg) - //{ - // int bx0, bx1; - // double rx0, rx1, sx, t, u, v, vec[1]; - - // vec[0] = arg; - // if (start) { - // start = 0; - // init(); - // } - - // setup(0,bx0,bx1,rx0,rx1); - - // sx = s_curve(rx0); - // u = rx0 * g1[ p[ bx0 ] ]; - // v = rx1 * g1[ p[ bx1 ] ]; - - // return(lerp(sx, u, v)); - //} - - //double noise2(double vec[2]) - //{ - // int bx0, bx1, by0, by1, b00, b10, b01, b11; - // double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v; - // int i, j; - - // if (start) { - // start = 0; - // init(); - // } - - // setup(0, bx0,bx1, rx0,rx1); - // setup(1, by0,by1, ry0,ry1); - - // i = p[ bx0 ]; - // j = p[ bx1 ]; - - // b00 = p[ i + by0 ]; - // b10 = p[ j + by0 ]; - // b01 = p[ i + by1 ]; - // b11 = p[ j + by1 ]; - - // sx = s_curve(rx0); - // sy = s_curve(ry0); - - // q = g2[ b00 ] ; u = at2(rx0,ry0); - // q = g2[ b10 ] ; v = at2(rx1,ry0); - // a = lerp(sx, u, v); - - // q = g2[ b01 ] ; u = at2(rx0,ry1); - // q = g2[ b11 ] ; v = at2(rx1,ry1); - // b = lerp(sx, u, v); - - // return lerp(sy, a, b); - //} - - double noise3(double vec[3]) - { - int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; - double rx0, rx1, ry0, ry1, rz0, rz1, * q, sy, sz, a, b, c, d, t, u, v; - int i, j; - - if (start) - { - start = 0; - init(); - } - - setup(0, bx0, bx1, rx0, rx1); - setup(1, by0, by1, ry0, ry1); - setup(2, bz0, bz1, rz0, rz1); - - i = pp[ bx0 ]; - j = pp[ bx1 ]; - - b00 = pp[ i + by0 ]; - b10 = pp[ j + by0 ]; - b01 = pp[ i + by1 ]; - b11 = pp[ j + by1 ]; - - t = s_curve(rx0); - sy = s_curve(ry0); - sz = s_curve(rz0); - - q = g3[ b00 + bz0 ]; - u = at3(rx0, ry0, rz0); - q = g3[ b10 + bz0 ]; - v = at3(rx1, ry0, rz0); - a = lerp(t, u, v); - - q = g3[ b01 + bz0 ]; - u = at3(rx0, ry1, rz0); - q = g3[ b11 + bz0 ]; - v = at3(rx1, ry1, rz0); - b = lerp(t, u, v); - - c = lerp(sy, a, b); - - q = g3[ b00 + bz1 ]; - u = at3(rx0, ry0, rz1); - q = g3[ b10 + bz1 ]; - v = at3(rx1, ry0, rz1); - a = lerp(t, u, v); - - q = g3[ b01 + bz1 ]; - u = at3(rx0, ry1, rz1); - q = g3[ b11 + bz1 ]; - v = at3(rx1, ry1, rz1); - b = lerp(t, u, v); - - d = lerp(sy, a, b); - - return lerp(sz, c, d); - } - - //void normalize2(double v[2]) - //{ - // double s; - - // s = sqrt(v[0] * v[0] + v[1] * v[1]); - // v[0] = v[0] / s; - // v[1] = v[1] / s; - //} - - void normalize3(double v[3]) - { - double s; - - s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - v[0] = v[0] / s; - v[1] = v[1] / s; - v[2] = v[2] / s; - } - - void init(void) - { - int i, j, k; - - for (i = 0; i < B; i++) - { - pp[i] = i; - //g1[i] = (double)((cry_rand() % (B + B)) - B) / B; - - //for (j = 0 ; j < 2 ; j++) - // g2[i][j] = (double)((cry_rand() % (B + B)) - B) / B; - //normalize2(g2[i]); - - for (j = 0; j < 3; j++) - { - g3[i][j] = cry_random(-1.0f, 1.0f); - } - normalize3(g3[i]); - } - - while (--i) - { - k = pp[i]; - pp[i] = pp[j = cry_random(0, B - 1)]; - pp[j] = k; - } - - for (i = 0; i < B + 2; i++) - { - pp[B + i] = pp[i]; - //g1[B + i] = g1[i]; - //for (j = 0 ; j < 2 ; j++) - // g2[B + i][j] = g2[i][j]; - for (j = 0; j < 3; j++) - { - g3[B + i][j] = g3[i][j]; - } - } - } - - /* --- My harmonic summing functions - PDB --------------------------*/ - - /* - In what follows "alpha" is the weight when the sum is formed. - Typically it is 2, As this approaches 1 the function is noisier. - "beta" is the harmonic scaling/spacing, typically 2. - */ - - //double PerlinNoise1D(double x,double alpha,double beta,int n) - //{ - // int i; - // double val,sum = 0; - // double p,scale = 1; - - // p = x; - // for (i=0;i(sum); - } - - #undef B - #undef BM - #undef N - #undef NP - #undef NM - - ////////////////////////////////////////////////////////////////////////// - - struct VolumeParticle - { - Vec3 p; - float r; - - VolumeParticle() - : p(0, 0, 0) - , r(0) - { - } - }; - - typedef std::vector VolumeDesc; - - ////////////////////////////////////////////////////////////////////////// - - bool ReadVolumeDescription(const char* pFilePath, VolumeDesc& volDesc, float& globalDensity) - { - volDesc.clear(); - globalDensity = 1; - - XmlNodeRef root(gEnv->pSystem->LoadXmlFromFile(pFilePath)); - if (root) - { - int numSprites(root->getChildCount()); - if (numSprites > 0) - { - root->getAttr("Density", globalDensity); - globalDensity = clamp_tpl(globalDensity, 0.0f, 1.0f); - - volDesc.reserve(numSprites); - for (int i(0); i < numSprites; ++i) - { - XmlNodeRef child(root->getChild(i)); - if (child) - { - VolumeParticle vp; - child->getAttr("Pos", vp.p); - child->getAttr("Radius", vp.r); - volDesc.push_back(vp); - } - } - } - } - - return !volDesc.empty(); - } - - ////////////////////////////////////////////////////////////////////////// - - void CalcBoundingBox(const VolumeDesc& volDesc, AABB& bbox) - { - bbox.Reset(); - - if (volDesc.empty()) - { - return; - } - - for (size_t i = 0; i < volDesc.size(); ++i) - { - bbox.Add(volDesc[i].p, volDesc[i].r); - } - } - - ////////////////////////////////////////////////////////////////////////// - - void CalcTightBounds(const AABB& bbox, AABB& tightBounds, float& scale) - { - float max = bbox.max.x - bbox.min.x; - - if (bbox.max.y - bbox.min.y > max) - { - max = bbox.max.y - bbox.min.y; - } - - if (bbox.max.z - bbox.min.z > max) - { - max = bbox.max.z - bbox.min.z; - } - - tightBounds.min.x = -(bbox.max.x - bbox.min.x) / max; - tightBounds.max.x = (bbox.max.x - bbox.min.x) / max; - - tightBounds.min.y = -(bbox.max.y - bbox.min.y) / max; - tightBounds.max.y = (bbox.max.y - bbox.min.y) / max; - - tightBounds.min.z = -(bbox.max.z - bbox.min.z) / max; - tightBounds.max.z = (bbox.max.z - bbox.min.z) / max; - - scale = max * 0.5f; - } - - ////////////////////////////////////////////////////////////////////////// - - void AdjustBoundingBox(AABB& bbox) - { - float max = bbox.max.x - bbox.min.x; - - if (bbox.max.y - bbox.min.y > max) - { - max = bbox.max.y - bbox.min.y; - } - - if (bbox.max.z - bbox.min.z > max) - { - max = bbox.max.z - bbox.min.z; - } - - float adj = (max - (bbox.max.x - bbox.min.x)) * 0.5f; - bbox.min.x -= adj; - bbox.max.x += adj; - - adj = (max - (bbox.max.y - bbox.min.y)) * 0.5f; - bbox.min.y -= adj; - bbox.max.y += adj; - - adj = (max - (bbox.max.z - bbox.min.z)) * 0.5f; - bbox.min.z -= adj; - bbox.max.z += adj; - } - - ////////////////////////////////////////////////////////////////////////// - - inline uint8 TrilinearFilteredLookup(const SVolumeDataSrcB& density, const float lx, const float ly, const float lz) - { - if (lx < 0 || ly < 0 || lz < 0) - { - return 0; - } - - int x = (int) lx; - int y = (int) ly; - int z = (int) lz; - - if (x > (int)density.m_width - 2 || y > (int)density.m_height - 2 || z > (int)density.m_depth - 2) - { - return 0; - } - - const uint8* src = &density[density.Idx(x, y, z)]; - - int lerpX = (int) ((lx - x) * 256.0f); - int lerpY = (int) ((ly - y) * 256.0f); - int lerpZ = (int) ((lz - z) * 256.0f); - - int _s000 = src[0]; - int _s001 = src[1]; - int _s010 = src[density.m_width]; - int _s011 = src[1 + density.m_width]; - - src += density.m_slice; - - int _s100 = src[0]; - int _s101 = src[1]; - int _s110 = src[density.m_width]; - int _s111 = src[1 + density.m_width]; - - int s00 = (_s000 << 8) + (_s001 - _s000) * lerpX; - int s01 = (_s010 << 8) + (_s011 - _s010) * lerpX; - int s0 = ((s00 << 8) + (s01 - s00) * lerpY) >> 8; - - int s10 = (_s100 << 8) + (_s101 - _s100) * lerpX; - int s11 = (_s110 << 8) + (_s111 - _s110) * lerpX; - int s1 = ((s10 << 8) + (s11 - s10) * lerpY) >> 8; - - return ((s0 << 8) + (s1 - s0) * lerpZ) >> 16; - } - - inline int sat(int f) - { - return (f < 0) ? 0 : ((f > 255) ? 255 : f); - } - - void Voxelize(const VolumeDesc& volDesc, float globalDensity, const AABB& bbox, SVolumeDataSrcB& trg) - { - SVolumeDataSrcB tmp(trg.m_width + 2, trg.m_height + 2, trg.m_depth + 2); - - // clear temporary volume - for (size_t i(0); i < tmp.size(); ++i) - { - tmp[i] = 0; - } - - // rasterize spheres - for (size_t i = 0; i < volDesc.size(); ++i) - { - const VolumeParticle& vp(volDesc[i]); - - int sz = (int) floor((float) (trg.m_depth - 1) * ((vp.p.z - vp.r) - bbox.min.z) / (bbox.max.z - bbox.min.z)); - int ez = (int) ceil((float) (trg.m_depth - 1) * ((vp.p.z + vp.r) - bbox.min.z) / (bbox.max.z - bbox.min.z)); - - int sy = (int) floor((float) (trg.m_height - 1) * ((vp.p.y - vp.r) - bbox.min.y) / (bbox.max.y - bbox.min.y)); - int ey = (int) ceil((float) (trg.m_height - 1) * ((vp.p.y + vp.r) - bbox.min.y) / (bbox.max.y - bbox.min.y)); - - int sx = (int) floor((float) (trg.m_width - 1) * ((vp.p.x - vp.r) - bbox.min.x) / (bbox.max.x - bbox.min.x)); - int ex = (int) ceil((float) (trg.m_width - 1) * ((vp.p.x + vp.r) - bbox.min.x) / (bbox.max.x - bbox.min.x)); - - float stepZ = (bbox.max.z - bbox.min.z) / (float) trg.m_depth; - float wz = vp.p.z - (bbox.min.z + ((float) sz + 0.5f) * stepZ); - - for (int z = sz; z <= ez; ++z, wz -= stepZ) - { - float dz2 = wz * wz; - - float stepY = (bbox.max.y - bbox.min.y) / (float) trg.m_height; - float wy = vp.p.y - (bbox.min.y + ((float) sy + 0.5f) * stepY); - - for (int y = sy; y <= ey; ++y, wy -= stepY) - { - float dy2 = wy * wy; - - float stepX = (bbox.max.x - bbox.min.x) / (float) trg.m_width; - float wx = vp.p.x - (bbox.min.x + ((float) sx + 0.5f) * stepX); - - size_t idx = tmp.Idx(sx + 1, y + 1, z + 1); - for (int x = sx; x <= ex; ++x, wx -= stepX, ++idx) - { - float dx2 = wx * wx; - float d = sqrt_tpl(dx2 + dy2 + dz2); - float v = max(1.0f - d / vp.r, 0.0f) * globalDensity; - tmp[idx] = max(tmp[idx], (uint8) (v * 255.0f)); - } - } - } - } - - // perturb volume using Perlin noise - { - float stepGx = 5.0f / (float) trg.m_width; - float stepGy = 5.0f / (float) trg.m_height; - float stepGz = 5.0f / (float) trg.m_depth; - - const float origBias = 0.25f; - const float origFillDens = 1.2f; - - const uint8 bias = (uint8) (origBias * 256.0f); - const uint32 biasNorm = (uint32) (256.0f * 256.0f * (origFillDens / (1.0f - origBias))); - - size_t idx = 0; - - float nz = 0; - float gz = 0; - for (unsigned int z = 0; z < trg.m_depth; ++z, nz += 1.0f, gz += stepGz) - { - float ny = 0; - float gy = 0; - for (unsigned int y = 0; y < trg.m_height; ++y, ny += 1.0f, gy += stepGy) - { - float nx = 0; - float gx = 0; - for (unsigned int x = 0; x < trg.m_width; ++x, nx += 1.0f, gx += stepGx, ++idx) - { - float gtx = (float)nx + 5.0f * PerlinNoise3D(gx, gy, gz, 2.0f, 2.1525f, 5); - float gty = (float)ny + 5.0f * PerlinNoise3D(gx + 21.132f, gy, gz, 2.0f, 2.1525f, 5); - float gtz = (float)nz + 5.0f * PerlinNoise3D(gx, gy + 3.412f, gz, 2.0f, 2.1525f, 5); - - //float val = (float) TrilinearFilteredLookup(tmp, gtx + 1.0f, gty + 1.0f, gtz + 1.0f) / 255.0f; - //trg[idx] = (uint8) (saturate(saturate(val - origBias) / (1.0f - origBias) * origFillDens) * 255.0f); - - uint8 val = TrilinearFilteredLookup(tmp, gtx + 1.0f, gty + 1.0f, gtz + 1.0f); - trg[idx] = sat(sat(val - bias) * biasNorm >> 16); - - //trg[idx] = (uint8) TrilinearFilteredLookup(tmp, gtx + 1.0f, gty + 1.0f, gtz + 1.0f); - } - } - } - } - - //// low pass filter - //{ - // { - // size_t srcIdx = 0; - // for (unsigned int z = 0; z < trg.m_depth; ++z) - // { - // for (unsigned int y = 0; y < trg.m_height; ++y) - // { - // size_t dstIdx = tmp.Idx(1, y+1, z+1); - // for (unsigned int x = 0; x < trg.m_width; ++x, ++srcIdx, ++dstIdx) - // tmp[dstIdx] = trg[srcIdx]; - // } - // } - // } - // { - // size_t dstIdx = 0; - // for (unsigned int z = 0; z < trg.m_depth; ++z) - // { - // for (unsigned int y = 0; y < trg.m_height; ++y) - // { - // const uint8* src = &tmp[tmp.Idx(1, y+1, z+1)]; - // for (unsigned int x = 0; x < trg.m_width; ++x, ++dstIdx, ++src) - // { - // const uint8* srcRow1 = src - tmp.m_slice - 1; - // const uint8* srcRow0 = srcRow1 - tmp.m_width; - // const uint8* srcRow2 = srcRow1 + tmp.m_width; - - // uint32 sum = 0; - // sum += srcRow0[0] + srcRow0[1] + srcRow0[2]; - // sum += srcRow1[0] + (srcRow1[1] << 1) + srcRow1[2]; - // sum += srcRow2[0] + srcRow2[1] + srcRow2[2]; - - // srcRow0 += tmp.m_slice; - // srcRow1 += tmp.m_slice; - // srcRow2 += tmp.m_slice; - - // sum += srcRow0[0] + (srcRow0[1] << 1) + srcRow0[2]; - // sum += (srcRow1[0] << 1) + (srcRow1[1] << 4) + (srcRow1[2] << 1); - // sum += srcRow2[0] + (srcRow2[1] << 1) + srcRow2[2]; - - // srcRow0 += tmp.m_slice; - // srcRow1 += tmp.m_slice; - // srcRow2 += tmp.m_slice; - - // sum += srcRow0[0] + srcRow0[1] + srcRow0[2]; - // sum += srcRow1[0] + (srcRow1[1] << 1) + srcRow1[2]; - // sum += srcRow2[0] + srcRow2[1] + srcRow2[2]; - - // const uint32 weight = 65536 / 48; - // sum *= weight; - // sum >>= 16; - - // trg[dstIdx] = sum; - // } - // } - // } - // } - //} - } - - ////////////////////////////////////////////////////////////////////////// - /* - void DumpAsRAW(SVolumeDataSrcB& v, const char* name) - { - FILE* f(fopen(name, "wb")); - - if (f) - { - for (unsigned int y = 0; y < 64; ++y) - { - for (unsigned int z = 0; z < 64; ++z) - { - for (unsigned int x = 0; x < 64; ++x) - { - uint8 val = v[v.Idx(x,y,z)]; - - fwrite(&val, 1, 1, f); - } - } - } - fclose(f); - } - } - */ - ////////////////////////////////////////////////////////////////////////// - - inline void PerPixelFilteredLookup(uint8* pShadow, const uint8* pDensity, const int s00, const int s01, - const int s10, const int s11, const int lerpX, const int lerpY, const int shadowStrength) - { - int _s00 = pShadow[s00]; - int _s01 = pShadow[s01]; - int _s10 = pShadow[s10]; - int _s11 = pShadow[s11]; - - int s0 = (_s00 << 8) + (_s01 - _s00) * lerpX; - int s1 = (_s10 << 8) + (_s11 - _s10) * lerpX; - int s = ((s0 << 8) + (s1 - s0) * lerpY) >> 8; - //int d = *pDensity * 103; // 103 = 0.4 * 256.0 - int d = *pDensity * shadowStrength; - - // todo: store data 1- - //*pShadow = fastround_positive(s * (1.0f - 0.2f * d)); - *pShadow = s * (65280 - d) >> 24; // 65280 = 1.0 * 255 * 256 - } - - //shadow is propagated from one slice to the next - inline void PerSliceFilteredLookup(uint8* pShadow, const uint8* pDensity, const int duOffset, const int dvOffset, - const int s00, const int s01, const int s10, const int s11, const int lerpX, const int lerpY, const int shadowStrength) - { - for (int v = 0; v < VOLUME_SHADOW_SIZE - 1; ++v) - { - for (int u = 0; u < VOLUME_SHADOW_SIZE - 1; ++u) - { - int offset(duOffset * u + dvOffset * v); - PerPixelFilteredLookup(&pShadow[offset], &pDensity[offset], s00, s01, s10, s11, lerpX, lerpY, shadowStrength); - } - } - } - - inline void PerBlockFilteredLookup(uint8* pShadow, const uint8* pDensity, const int duOffset, const int dvOffset, - const int dwOffset, const int s00, const int s01, const int s10, const int s11, const int lerpX, const int lerpY, const int shadowStrength) - { - for (int w = 1; w < VOLUME_SHADOW_SIZE; ++w) - { - int offset(dwOffset * w); - PerSliceFilteredLookup(&pShadow[offset], &pDensity[offset], duOffset, dvOffset, s00, s01, s10, s11, lerpX, lerpY, shadowStrength); - } - } -} // anonymous namespace - - -bool CreateVolumeObject(const char* filePath, SVolumeDataSrcB& trg, AABB& tightBounds, float& scale) -{ - VolumeDesc volDesc; - float globalDensity(1); - if (ReadVolumeDescription(filePath, volDesc, globalDensity)) - { - AABB bbox; - - CalcBoundingBox(volDesc, bbox); - CalcTightBounds(bbox, tightBounds, scale); - AdjustBoundingBox(bbox); - Voxelize(volDesc, globalDensity, bbox, trg); - //DumpAsRAW(trg, "E:\\TestDensity.raw"); - return true; - } - - return false; -} - - -bool CreateVolumeShadow(const Vec3& lightDir, float shadowStrength, const SVolumeDataSrcB& density, SVolumeDataSrcB& shadows) -{ - for (size_t i(0); i < shadows.size(); ++i) - { - shadows[i] = 255; - } - - if (density.m_width != VOLUME_SHADOW_SIZE || density.m_height != VOLUME_SHADOW_SIZE || density.m_depth != VOLUME_SHADOW_SIZE || - shadows.m_width != VOLUME_SHADOW_SIZE || shadows.m_height != VOLUME_SHADOW_SIZE || shadows.m_depth != VOLUME_SHADOW_SIZE) - { - assert(!"CreateVolumeShadow() -- density and/or shadow volume has invalid dimension!"); - return false; - } - - float sun[3] = {lightDir.x, lightDir.y, lightDir.z}; - - int majAxis = 0; - { - float abssun[3] = { fabsf(sun[0]), fabsf(sun[1]), fabsf(sun[2]) }; - - if (abssun[1] > abssun[0]) - { - majAxis = 1; - } - if (abssun[2] > abssun[majAxis]) - { - majAxis = 2; - } - - // project direction onto the -1..1 cube sides - float fInv = 1.0f / abssun[majAxis]; - - sun[0] *= fInv; - sun[1] *= fInv; - sun[2] *= fInv; - } - - int du[3] = { 0 }; - int dv[3] = { 0 }; - int dw[3] = { 0 }; - - int w = 0; - - if (sun[majAxis] > 0) - { - dw[majAxis] = 1; - } - else - { - dw[majAxis] = -1; - w = VOLUME_SHADOW_SIZE - 1; - } - - int secAxis = (majAxis + 1) % 3; - int thirdAxis = (majAxis + 2) % 3; - - du[secAxis] = 1; - dv[thirdAxis] = 1; - - int duOffset = du[0] + (du[1] + du[2] * VOLUME_SHADOW_SIZE) * VOLUME_SHADOW_SIZE; - int dvOffset = dv[0] + (dv[1] + dv[2] * VOLUME_SHADOW_SIZE) * VOLUME_SHADOW_SIZE; - int dwOffset = dw[0] + (dw[1] + dw[2] * VOLUME_SHADOW_SIZE) * VOLUME_SHADOW_SIZE; - - - float lerpX = sun[secAxis]; - float lerpY = sun[thirdAxis]; - - //if(sun[majAxis]>0) - { - lerpX = -lerpX; - lerpY = -lerpY; - } - - int prevSliceOffset = -dwOffset; - int offset = -w * dwOffset; - - if (lerpX < 0) - { - lerpX += 1.0f; - prevSliceOffset -= duOffset; - offset += duOffset; - } - - if (lerpY < 0) - { - lerpY += 1.0f; - prevSliceOffset -= dvOffset; - offset += dvOffset; - } - - PerBlockFilteredLookup(&shadows[offset], &density[offset], duOffset, dvOffset, dwOffset, - prevSliceOffset, duOffset + prevSliceOffset, dvOffset + prevSliceOffset, duOffset + dvOffset + prevSliceOffset, - (int) (lerpX * 256.0f), (int) (lerpY * 256.0f), (int) (clamp_tpl(shadowStrength, 0.0f, 1.0f) * 256.0f)); - - return true; -} - - -bool CreateDownscaledVolumeObject(const SVolumeDataSrcB& src, SVolumeDataSrcB& trg) -{ - if (src.m_width != 2 * trg.m_width || src.m_height != 2 * trg.m_height || src.m_depth != 2 * trg.m_height) - { - for (size_t i(0); i < trg.size(); ++i) - { - trg[i] = 255; - } - - assert(!"CreateDownscaledVolumeObject() -- src and/or trg volume has invalid dimension!"); - return false; - } - - for (unsigned int z = 0; z < trg.m_depth; ++z) - { - for (unsigned int y = 0; y < trg.m_height; ++y) - { - for (unsigned int x = 0; x < trg.m_width; ++x) - { - trg[trg.Idx(x, y, z)] = (uint8) (0.125f * (src[src.Idx(2 * x, 2 * y, 2 * z)] + - src[src.Idx(2 * x + 1, 2 * y, 2 * z)] + - src[src.Idx(2 * x, 2 * y + 1, 2 * z)] + - src[src.Idx(2 * x + 1, 2 * y + 1, 2 * z)] + - src[src.Idx(2 * x, 2 * y, 2 * z + 1)] + - src[src.Idx(2 * x + 1, 2 * y, 2 * z + 1)] + - src[src.Idx(2 * x, 2 * y + 1, 2 * z + 1)] + - src[src.Idx(2 * x + 1, 2 * y + 1, 2 * z + 1)])); - } - } - } - - return true; -} - - -////////////////////////////////////////////////////////////////////////// - - -namespace -{ - typedef std::vector Points; - typedef std::vector PointIndexCache; - - bool IsPowerOfTwo(unsigned int x) - { - int cnt = 0; - while (x > 0) - { - cnt += x & 1; - x >>= 1; - } - return cnt == 1; - } - - bool GeneratePoints(const SVolumeDataSrcB& src, Points& pts) - { - struct SPointGenerator - { - public: - SPointGenerator(const SVolumeDataSrcB& _src, unsigned int _size, Points& _pts) - : m_src(_src) - , m_pts(_pts) - , m_cache() - { - size_t cacheSize = (m_src.m_width * m_src.m_height * m_src.m_depth + 7) >> 3; - m_cache.resize(cacheSize); - - for (size_t i = 0; i < cacheSize; ++i) - { - m_cache[i] = 0; - } - - if (Traverse(0, 0, 0, _size)) - { - PushPts(0, 0, 0, _size); - } - } - - private: - void PushPt(unsigned int x, unsigned int y, unsigned int z) - { - size_t idx = m_src.Idx(x, y, z); - if ((m_cache[idx >> 3] & (1 << (idx & 7))) == 0) - { - Vec3 p; - p.x = 2.0f * ((float) x / (float) m_src.m_width) - 1.0f; - p.y = 2.0f * ((float) y / (float) m_src.m_height) - 1.0f; - p.z = 2.0f * ((float) z / (float) m_src.m_depth) - 1.0f; - assert(fabs(p.x) <= 1.0f && fabs(p.y) <= 1.0f && fabs(p.z) <= 1.0f); - m_pts.push_back(p); - m_cache[idx >> 3] |= 1 << (idx & 7); - } - } - - void PushPts(unsigned int x, unsigned int y, unsigned int z, unsigned int size) - { - PushPt(x, y, z); - PushPt(x + size, y, z); - PushPt(x, y + size, z); - PushPt(x + size, y + size, z); - PushPt(x, y, z + size); - PushPt(x + size, y, z + size); - PushPt(x, y + size, z + size); - PushPt(x + size, y + size, z + size); - } - - bool Traverse(unsigned int x, unsigned int y, unsigned int z, unsigned int size) - { - if (size == 1) - { - bool isSolid = false; - - unsigned int zs = max((int) z - 1, 0); - unsigned int ze = min(z + 2, m_src.m_depth); - for (; zs < ze; ++zs) - { - unsigned int ys = max((int)y - 1, 0); - unsigned int ye = min(y + 2, m_src.m_height); - for (; ys < ye; ++ys) - { - unsigned int xs = max((int)x - 1, 0); - unsigned int xe = min(x + 2, m_src.m_width); - for (; xs < xe; ++xs) - { - isSolid |= m_src[m_src.Idx(xs, ys, zs)] != 0; - if (isSolid) - { - return true; - } - } - } - } - return false; - } - - unsigned int ns = size >> 1; - - bool isSolid[8]; - isSolid[0] = Traverse(x, y, z, ns); - isSolid[1] = Traverse(x + ns, y, z, ns); - isSolid[2] = Traverse(x, y + ns, z, ns); - isSolid[3] = Traverse(x + ns, y + ns, z, ns); - isSolid[4] = Traverse(x, y, z + ns, ns); - isSolid[5] = Traverse(x + ns, y, z + ns, ns); - isSolid[6] = Traverse(x, y + ns, z + ns, ns); - isSolid[7] = Traverse(x + ns, y + ns, z + ns, ns); - - bool mergeSubtrees = isSolid[0]; - for (int i = 1; i < 8; ++i) - { - mergeSubtrees &= isSolid[i]; - } - - if (!mergeSubtrees) - { - if (isSolid[0]) - { - PushPts(x, y, z, ns); - } - if (isSolid[1]) - { - PushPts(x + ns, y, z, ns); - } - if (isSolid[2]) - { - PushPts(x, y + ns, z, ns); - } - if (isSolid[3]) - { - PushPts(x + ns, y + ns, z, ns); - } - if (isSolid[4]) - { - PushPts(x, y, z + ns, ns); - } - if (isSolid[5]) - { - PushPts(x + ns, y, z + ns, ns); - } - if (isSolid[6]) - { - PushPts(x, y + ns, z + ns, ns); - } - if (isSolid[7]) - { - PushPts(x + ns, y + ns, z + ns, ns); - } - } - - return mergeSubtrees; - } - - private: - const SVolumeDataSrcB& m_src; - Points& m_pts; - PointIndexCache m_cache; - }; - - if (src.m_width != src.m_height || src.m_width != src.m_depth || src.m_height != src.m_depth) - { - return false; - } - - unsigned int size = src.m_width; - - if (!IsPowerOfTwo(size)) - { - return false; - } - - SPointGenerator gen(src, size, pts); - - return true; - } - - void* qhmalloc(size_t s) - { - return new uint8[s]; - } - - void qhfree(void* p) - { - delete [] (uint8*) p; - } -} // anonymous namespace - - -bool CreateVolumeDataHull(const SVolumeDataSrcB& src, SVolumeDataHull& hull) -{ - Points pts; - if (GeneratePoints(src, pts)) - { - Vec3* pPts = &pts[0]; - size_t numPts = pts.size(); - - // compute convex hull - LegacyCryPhysicsUtils::index_t* pIndices = 0; - int numTris = LegacyCryPhysicsUtils::qhull(pPts, (int) numPts, pIndices, qhmalloc); - - if (pIndices) - { - // map used vertices - typedef std::map Vtx2Vtx; - Vtx2Vtx v2v; - for (int i = 0, idx = 0; i < numTris; ++i) - { - if (v2v.find(pIndices[idx]) == v2v.end()) - { - v2v.insert(Vtx2Vtx::value_type(pIndices[idx], -1)); - } - ++idx; - - if (v2v.find(pIndices[idx]) == v2v.end()) - { - v2v.insert(Vtx2Vtx::value_type(pIndices[idx], -1)); - } - ++idx; - - if (v2v.find(pIndices[idx]) == v2v.end()) - { - v2v.insert(Vtx2Vtx::value_type(pIndices[idx], -1)); - } - ++idx; - } - // generate new indices - int newIdx = 0; - { - Vtx2Vtx::iterator it = v2v.begin(); - Vtx2Vtx::iterator itEnd = v2v.end(); - for (; it != itEnd; ++it, ++newIdx) - { - (*it).second = newIdx; - } - } - // write used vertices - { - hull.m_numPts = newIdx; - SAFE_DELETE_ARRAY(hull.m_pPts); - hull.m_pPts = new SVF_P3F[newIdx]; - - Vtx2Vtx::iterator it = v2v.begin(); - Vtx2Vtx::iterator itEnd = v2v.end(); - for (size_t i = 0; it != itEnd; ++it, ++i) - { - assert((*it).second == i); - hull.m_pPts[i].xyz = pPts[(*it).first]; - } - } - // write remapped indices - { - hull.m_numTris = numTris; - SAFE_DELETE_ARRAY(hull.m_pIdx); - hull.m_pIdx = new vtx_idx [numTris * 3]; - - for (int i = 0; i < numTris * 3; ++i) - { - assert(v2v.find(pIndices[i]) != v2v.end()); - hull.m_pIdx[i] = v2v[pIndices[i]]; - } - } - // free temp hull index array - qhfree(pIndices); - } - else - { - hull.m_numPts = 0; - hull.m_numTris = 0; - - SAFE_DELETE_ARRAY(hull.m_pPts); - SAFE_DELETE_ARRAY(hull.m_pIdx); - } - - return true; - } - return false; -} -#undef lerp diff --git a/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.h b/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.h deleted file mode 100644 index 44995bc951..0000000000 --- a/Code/CryEngine/Cry3DEngine/VolumeObjectDataCreate.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTDATACREATE_H -#define CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTDATACREATE_H -#pragma once - -const int VOLUME_SIZE(64); -const int VOLUME_SHADOW_SIZE(32); - - -template -struct SVolumeDataSrc -{ - typedef T VoxelElementType; - - unsigned int m_width; - unsigned int m_height; - unsigned int m_depth; - unsigned int m_slice; - VoxelElementType* m_pData; - - SVolumeDataSrc(unsigned int width, unsigned int height, unsigned int depth) - : m_width(width) - , m_height(height) - , m_depth(depth) - , m_slice(width * depth) - , m_pData(0) - { - m_pData = new VoxelElementType[m_width * m_height * m_depth]; - } - - ~SVolumeDataSrc() - { - SAFE_DELETE_ARRAY(m_pData) - } - - size_t size() const - { - return m_width * m_height * m_depth; - } - - size_t Idx(unsigned int x, unsigned int y, unsigned int z) const - { - //return z * m_width * m_height + y * m_width + x; - return (z * m_height + y) * m_width + x; - } - - T& operator[](size_t idx) - { - return m_pData[idx]; - } - - const T& operator[](size_t idx) const - { - return m_pData[idx]; - } -}; - - -typedef SVolumeDataSrc SVolumeDataSrcB; -typedef SVolumeDataSrc SVolumeDataSrcF; - - -bool CreateVolumeObject(const char* filePath, SVolumeDataSrcB& trg, AABB& tightBounds, float& scale); -bool CreateVolumeShadow(const Vec3& lightDir, float shadowStrength, const SVolumeDataSrcB& density, SVolumeDataSrcB& shadows); -bool CreateDownscaledVolumeObject(const SVolumeDataSrcB& src, SVolumeDataSrcB& trg); - - -struct SVolumeDataHull -{ - SVolumeDataHull() - : m_numPts(0) - , m_numTris(0) - , m_pPts(0) - , m_pIdx(0) - { - } - - ~SVolumeDataHull() - { - SAFE_DELETE_ARRAY(m_pPts); - SAFE_DELETE_ARRAY(m_pIdx); - } - - size_t m_numPts; - size_t m_numTris; - SVF_P3F* m_pPts; - vtx_idx* m_pIdx; -}; - - -bool CreateVolumeDataHull(const SVolumeDataSrcB& src, SVolumeDataHull& hull); - -#endif // CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTDATACREATE_H diff --git a/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.cpp b/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.cpp deleted file mode 100644 index 4cb5298bbb..0000000000 --- a/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" - -#include "VolumeObjectRenderNode.h" -#include "VolumeObjectDataCreate.h" -#include "MatMan.h" -#include "Environment/OceanEnvironmentBus.h" - -#include - - -////////////////////////////////////////////////////////////////////////// -// volume data cache - -class CVolumeDataCache -{ -public: - static CVolumeDataCache& Access(); - -public: - ~CVolumeDataCache(); - - void AddItem(const string& name, CVolumeDataItem* pItem); - void RemoveItem(const string& name); - CVolumeDataItem* GetItem(const string& name) const; - size_t size() const; - -private: - typedef std::map VolumeDataItemMap; - -private: - CVolumeDataCache(); - -private: - VolumeDataItemMap m_cache; -}; - - -CVolumeDataCache& CVolumeDataCache::Access() -{ - static CVolumeDataCache s_inst; - return s_inst; -} - - -CVolumeDataCache::CVolumeDataCache() - : m_cache() -{ -} - - -CVolumeDataCache::~CVolumeDataCache() -{ - assert(m_cache.empty()); -} - - -void CVolumeDataCache::AddItem(const string& name, CVolumeDataItem* pItem) -{ - VolumeDataItemMap::iterator it(m_cache.find(name)); - assert(it == m_cache.end()); - if (it == m_cache.end()) - { - m_cache.insert(VolumeDataItemMap::value_type(name, pItem)); - } -} - - -void CVolumeDataCache::RemoveItem(const string& name) -{ - VolumeDataItemMap::iterator it(m_cache.find(name)); - assert(it != m_cache.end()); - if (it != m_cache.end()) - { - m_cache.erase(it); - } -} - - -CVolumeDataItem* CVolumeDataCache::GetItem(const string& name) const -{ - VolumeDataItemMap::const_iterator it(m_cache.find(name)); - return it != m_cache.end() ? (*it).second : 0; -} - - -size_t CVolumeDataCache::size() const -{ - return m_cache.size(); -} - - -////////////////////////////////////////////////////////////////////////// -// volume data item - -class CVolumeDataItem -{ -public: - static CVolumeDataItem* Create(const char* filePath, const CREVolumeObject* pVolTexFactory); - -public: - void AddRef(); - void Release(); - - bool IsValid() const; - void AddToCache(); - - const SVolumeDataSrcB* GetData() const; - IVolumeTexture* GetVolumeTexture() const; - - const AABB& GetTightBounds() const; - float GetScale() const; - - const SVolumeDataHull* GetHull() const; - _smart_ptr GetHullMesh(); - -private: - CVolumeDataItem(const char* filePath, const CREVolumeObject* pVolTexFactory); - ~CVolumeDataItem(); - -private: - int m_refCount; - bool m_isValid; - bool m_isCached; - AABB m_tightBounds; - float m_scale; - string m_volDataFilePath; - SVolumeDataSrcB* m_pData; - IVolumeTexture* m_pVolTex; - SVolumeDataHull* m_pHull; - _smart_ptr m_pHullMesh; -}; - - -CVolumeDataItem* CVolumeDataItem::Create(const char* filePath, const CREVolumeObject* pVolTexFactory) -{ - return new CVolumeDataItem(filePath, pVolTexFactory); -} - - -CVolumeDataItem::CVolumeDataItem(const char* filePath, const CREVolumeObject* pVolTexFactory) - : m_refCount(1) - , m_isValid(false) - , m_isCached(false) - , m_tightBounds(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_scale(1) - , m_volDataFilePath(filePath) - , m_pData(0) - , m_pVolTex(0) - , m_pHull(0) - , m_pHullMesh(0) -{ - if (filePath && pVolTexFactory) - { - SVolumeDataSrcB* pData = new SVolumeDataSrcB(VOLUME_SIZE, VOLUME_SIZE, VOLUME_SIZE); - if (pData && pData->m_pData) - { - if (CreateVolumeObject(m_volDataFilePath, *pData, m_tightBounds, m_scale)) - { - m_pVolTex = pVolTexFactory->CreateVolumeTexture(); - if (m_pVolTex) - { - m_isValid = m_pVolTex->Create(pData->m_width, pData->m_height, pData->m_depth, pData->m_pData); - } - - m_pHull = new SVolumeDataHull(); - if (CreateVolumeDataHull(*pData, *m_pHull)) - { - m_pHullMesh = gEnv->pRenderer->CreateRenderMeshInitialized(m_pHull->m_pPts, (int) m_pHull->m_numPts, eVF_P3F, - m_pHull->m_pIdx, (int) m_pHull->m_numTris * 3, prtTriangleList, "VolumeObjectHull", "VolumeObjectHull"); - m_isValid &= m_pHullMesh != 0; - } - else - { - m_isValid = false; - } - - // delete hull in sys mem if no debug drawing is needed - SAFE_DELETE(m_pHull); - - m_pData = new SVolumeDataSrcB(VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE); - if (m_pData && m_pData->m_pData) - { - m_isValid &= CreateDownscaledVolumeObject(*pData, *m_pData); - } - else - { - m_isValid = false; - } - } - } - SAFE_DELETE(pData); - } -} - - -CVolumeDataItem::~CVolumeDataItem() -{ - if (m_isCached) - { - assert(CVolumeDataCache::Access().GetItem(m_volDataFilePath) == this); - CVolumeDataCache::Access().RemoveItem(m_volDataFilePath); - } - - SAFE_DELETE(m_pData); - SAFE_RELEASE(m_pVolTex); - SAFE_DELETE(m_pHull); - m_pHullMesh = NULL; -} - - -void CVolumeDataItem::AddRef() -{ - ++m_refCount; -} - - -void CVolumeDataItem::Release() -{ - --m_refCount; - if (m_refCount <= 0) - { - delete this; - } -} - - -bool CVolumeDataItem::IsValid() const -{ - return m_isValid; -} - - -void CVolumeDataItem::AddToCache() -{ - if (m_isValid && !m_isCached) - { - CVolumeDataCache::Access().AddItem(m_volDataFilePath, this); - m_isCached = true; - } -} - - -const SVolumeDataSrcB* CVolumeDataItem::GetData() const -{ - return m_pData; -} - - -IVolumeTexture* CVolumeDataItem::GetVolumeTexture() const -{ - return m_pVolTex; -} - - -const AABB& CVolumeDataItem::GetTightBounds() const -{ - return m_tightBounds; -} - - -float CVolumeDataItem::GetScale() const -{ - return m_scale; -} - - -const SVolumeDataHull* CVolumeDataItem::GetHull() const -{ - return m_pHull; -} - - -_smart_ptr CVolumeDataItem::GetHullMesh() -{ - return m_pHullMesh; -} - - -////////////////////////////////////////////////////////////////////////// -// volume shadow creator - -class CVolumeShadowCreator -{ -public: - static CVolumeShadowCreator* Create(); - -public: - int AddRef(); - int Release(); - - void CalculateShadows(const Vec3& newLightDir, float shadowStrength, const CVolumeDataItem* pVolSrc, IVolumeTexture* pShadDst); - -private: - CVolumeShadowCreator(); - ~CVolumeShadowCreator(); - -private: - int m_refCount; - SVolumeDataSrcB* m_pShad; -}; - - -CVolumeShadowCreator* CVolumeShadowCreator::Create() -{ - return new CVolumeShadowCreator; -} - - -CVolumeShadowCreator::CVolumeShadowCreator() - : m_refCount(1) - , m_pShad(0) -{ -} - - -CVolumeShadowCreator::~CVolumeShadowCreator() -{ -} - - -int CVolumeShadowCreator::AddRef() -{ - ++m_refCount; - return m_refCount; -} - - -int CVolumeShadowCreator::Release() -{ - --m_refCount; - int ref(m_refCount); - if (m_refCount <= 0) - { - delete this; - } - return ref; -} - - -void CVolumeShadowCreator::CalculateShadows(const Vec3& newLightDir, float shadowStrength, const CVolumeDataItem* pVolSrc, IVolumeTexture* pShadDst) -{ - const SVolumeDataSrcB* pSrc(pVolSrc->GetData()); - if (!pSrc) - { - return; - } - - if (!m_pShad || m_pShad->m_width != pSrc->m_width || m_pShad->m_height != pSrc->m_height || m_pShad->m_depth != pSrc->m_depth) - { - SAFE_DELETE(m_pShad); - m_pShad = new SVolumeDataSrcB(pSrc->m_width, pSrc->m_height, pSrc->m_depth); - } - - if (m_pShad) - { - //float t = gEnv->pTimer->GetAsyncCurTime(); - CreateVolumeShadow(newLightDir, shadowStrength, *pSrc, *m_pShad); - //t = gEnv->pTimer->GetAsyncCurTime() - t; - //gEnv->pLog->Log("CreateVolumeShadow(%.3f, %.3f, %.3f) took %.2fms", newLightDir.x, newLightDir.y, newLightDir.z, t * 1000.0f); - pShadDst->Update(m_pShad->m_width, m_pShad->m_height, m_pShad->m_depth, m_pShad->m_pData); - } -} - - -////////////////////////////////////////////////////////////////////////// -// CVolumeObjectRenderNode implementation - -CVolumeShadowCreator* CVolumeObjectRenderNode::ms_pVolShadowCreator(0); -StaticInstance CVolumeObjectRenderNode::ms_volumeObjects; - -ICVar* CVolumeObjectRenderNode::ms_CV_volobj_stats(0); -int CVolumeObjectRenderNode::e_volobj_stats(0); - - -void CVolumeObjectRenderNode::MoveVolumeObjects() -{ - for (VolumeObjectSet::iterator it(ms_volumeObjects.begin()), itEnd(ms_volumeObjects.end()); it != itEnd; ++it) - { - (*it)->Move(); - } - - ////////////////////////////////////////////////////////////////////////// - - if (e_volobj_stats) - { - CryLogAlways("#VolumeObjects = %" PRISIZE_T, ms_volumeObjects.size()); - CryLogAlways("#VolumeDataItems = %" PRISIZE_T, CVolumeDataCache::Access().size()); - e_volobj_stats = 0; - } -} - - -void CVolumeObjectRenderNode::RegisterVolumeObject(CVolumeObjectRenderNode* p) -{ - VolumeObjectSet::iterator it(ms_volumeObjects.find(p)); - assert(it == ms_volumeObjects.end() && "CVolumeObjectRenderNode::RegisterVolumeObject() -- Object already registered!"); - if (it == ms_volumeObjects.end()) - { - ms_volumeObjects.insert(p); - } -} - - -void CVolumeObjectRenderNode::UnregisterVolumeObject(CVolumeObjectRenderNode* p) -{ - VolumeObjectSet::iterator it(ms_volumeObjects.find(p)); - assert(it != ms_volumeObjects.end() && "CVolumeObjectRenderNode::UnregisterVolumeObject() -- Object not registered or previously removed!"); - if (it != ms_volumeObjects.end()) - { - ms_volumeObjects.erase(it); - } -} - - -CVolumeObjectRenderNode::CVolumeObjectRenderNode() - : m_WSBBox() - , m_pos(0, 0, 0) - , m_origin(0, 0, 0) - , m_matOrig() - , m_mat() - , m_matInv() - , m_lastCachedLightDir(0, 0, 0) - , m_tightBoundsOS() - , m_moveProps() - , m_alpha(1) - , m_scale(1) - , m_shadowStrength(0.4f) - , m_pMaterial(0) - , m_pVolDataItem(0) - , m_pVolShadTex(0) -{ - m_matOrig.SetIdentity(); - m_mat.SetIdentity(); - m_matInv.SetIdentity(); - - m_WSBBox = AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)); - m_tightBoundsOS = AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)); - - m_moveProps.m_autoMove = false; - m_moveProps.m_speed = Vec3(0, 0, 0); - m_moveProps.m_spaceLoopBox = Vec3(2000.0f, 2000.0f, 2000.0f); - m_moveProps.m_fadeDistance = 0; - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pRE[i] = (CREVolumeObject*) GetRenderer()->EF_CreateRE(eDATA_VolumeObject); - } - - m_pMaterial = GetMatMan()->LoadMaterial("Materials/VolumeData/Default", false); - - if (!ms_pVolShadowCreator) - { - ms_pVolShadowCreator = CVolumeShadowCreator::Create(); - } - else - { - ms_pVolShadowCreator->AddRef(); - } - - RegisterVolumeObject(this); - - if (!ms_CV_volobj_stats) - { - ms_CV_volobj_stats = REGISTER_CVAR(e_volobj_stats, 0, VF_NULL, ""); - } -} - - -CVolumeObjectRenderNode::~CVolumeObjectRenderNode() -{ - if (ms_pVolShadowCreator->Release() <= 0) - { - ms_pVolShadowCreator = 0; - } - - SAFE_RELEASE(m_pVolShadTex); - SAFE_RELEASE(m_pVolDataItem); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - if (m_pRE[i]) - { - m_pRE[i]->Release(false); - m_pRE[i] = 0; - } - } - - Get3DEngine()->FreeRenderNodeState(this); - - UnregisterVolumeObject(this); -} - - -void CVolumeObjectRenderNode::LoadVolumeData(const char* filePath) -{ - CREVolumeObject* pVolTextureFactory = m_pRE[0]; // ok to use first instance as function is stateless, ptr is not store in objects created below - - CVolumeDataItem* pNewVolDataItem(CVolumeDataCache::Access().GetItem(filePath)); - if (pNewVolDataItem) - { - pNewVolDataItem->AddRef(); - if (m_pVolDataItem) - { - m_pVolDataItem->Release(); - } - m_pVolDataItem = pNewVolDataItem; - InvalidateLastCachedLightDir(); - } - else - { - pNewVolDataItem = CVolumeDataItem::Create(filePath, pVolTextureFactory); - if (pNewVolDataItem && pNewVolDataItem->IsValid()) - { - pNewVolDataItem->AddToCache(); - if (m_pVolDataItem) - { - m_pVolDataItem->Release(); - } - m_pVolDataItem = pNewVolDataItem; - InvalidateLastCachedLightDir(); - } - else - { - SAFE_RELEASE(pNewVolDataItem); - } - } - - SetMatrix(m_matOrig); - - if (m_pVolDataItem && pVolTextureFactory && !m_pVolShadTex) - { - m_pVolShadTex = pVolTextureFactory->CreateVolumeTexture(); - if (!m_pVolShadTex->Create(VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, VOLUME_SHADOW_SIZE, 0)) - { - SAFE_RELEASE(m_pVolShadTex); - } - } -} - - -void CVolumeObjectRenderNode::SetProperties([[maybe_unused]] const SVolumeObjectProperties& properties) -{ -} - - -void CVolumeObjectRenderNode::SetMovementProperties(const SVolumeObjectMovementProperties& properties) -{ - m_moveProps = properties; -} - - -void CVolumeObjectRenderNode::SetMatrix(const Matrix34& mat) -{ - m_matOrig = mat; - float initialScale(m_pVolDataItem ? m_pVolDataItem->GetScale() : 1); - SetMatrixInternal(mat * Matrix33::CreateScale(Vec3(initialScale)), true); -} - - -void CVolumeObjectRenderNode::SetMatrixInternal(const Matrix34& mat, bool updateOrigin) -{ - Get3DEngine()->UnRegisterEntityAsJob(this); - - if (updateOrigin) - { - m_origin = mat.GetTranslation(); - } - - m_pos = mat.GetTranslation(); - m_mat = mat; - m_matInv = mat.GetInverted(); - - m_tightBoundsOS = m_pVolDataItem ? m_pVolDataItem->GetTightBounds() : AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)); - m_WSBBox.SetTransformedAABB(m_mat, m_tightBoundsOS); - - Vec3 scale(m_mat.GetColumn(0).GetLength(), m_mat.GetColumn(1).GetLength(), m_mat.GetColumn(2).GetLength()); - - const float Epsilon = 0.001f; - AZ_Warning( - "VolumeObjectRenderNode", - fabsf(scale.x - scale.y) < Epsilon && fabsf(scale.x - scale.z) < Epsilon && fabsf(scale.y - scale.z) < Epsilon, - "VolumeObjectRenderNode is using non-uniform scale. Forcing to uniform..."); - m_scale = max(max(scale.x, scale.y), scale.z); - - Get3DEngine()->RegisterEntity(this); -} - - -const char* CVolumeObjectRenderNode::GetEntityClassName() const -{ - return "VolumeObject"; -} - - -const char* CVolumeObjectRenderNode::GetName() const -{ - return "VolumeObject"; -} - - -bool CVolumeObjectRenderNode::IsViewerInsideVolume(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPosOS(m_matInv.TransformPoint(cam.GetPosition())); - const Vec3& scale(m_tightBoundsOS.max); - return fabsf(camPosOS.x) < scale.x && fabsf(camPosOS.y) < scale.y && fabsf(camPosOS.z) < scale.z; -} - - -bool CVolumeObjectRenderNode::NearPlaneIntersectsVolume(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam = passInfo.GetCamera(); - - // check if bounding box intersects the near clipping plane - const Plane* pNearPlane(cam.GetFrustumPlane(FR_PLANE_NEAR)); - Vec3 pntOnNearPlane(cam.GetPosition() - pNearPlane->DistFromPlane(cam.GetPosition()) * pNearPlane->n); - Vec3 pntOnNearPlaneOS(m_matInv.TransformPoint(pntOnNearPlane)); - - Vec3 nearPlaneOS_n(m_matInv.TransformVector(pNearPlane->n) /*.GetNormalized()*/); - f32 nearPlaneOS_d(-nearPlaneOS_n.Dot(pntOnNearPlaneOS)); - - // get extreme lengths - float t(fabsf(nearPlaneOS_n.x * m_tightBoundsOS.max.x) + fabsf(nearPlaneOS_n.y * m_tightBoundsOS.max.y) + fabsf(nearPlaneOS_n.z * m_tightBoundsOS.max.z)); - //float t(0.0f); - //if(nearPlaneOS_n.x >= 0) t += -nearPlaneOS_n.x; else t += nearPlaneOS_n.x; - //if(nearPlaneOS_n.y >= 0) t += -nearPlaneOS_n.y; else t += nearPlaneOS_n.y; - //if(nearPlaneOS_n.z >= 0) t += -nearPlaneOS_n.z; else t += nearPlaneOS_n.z; - - float t0(t + nearPlaneOS_d); - float t1(-t + nearPlaneOS_d); - - return t0 * t1 < 0.0f; -} - - -void CVolumeObjectRenderNode::InvalidateLastCachedLightDir() -{ - m_lastCachedLightDir = Vec3(0, 0, 0); -} - - -void CVolumeObjectRenderNode::UpdateShadows() -{ - Vec3 newLightDir(m_p3DEngine->GetSunDirNormalized()); - - float shadowStrength(GetFloatCVar(e_VolObjShadowStrength)); - if (ms_pVolShadowCreator) - { - Vec3 newLightDirLS(m_matInv.TransformVector(newLightDir).GetNormalized()); // 0.999f = 1.56 deg = ??? minutes of TOD update, TODO: make adjustable - if (m_shadowStrength != shadowStrength || newLightDirLS.Dot(m_lastCachedLightDir) < 0.999f) - { - ms_pVolShadowCreator->CalculateShadows(-newLightDirLS, shadowStrength, m_pVolDataItem, m_pVolShadTex); - m_lastCachedLightDir = newLightDirLS; - m_shadowStrength = shadowStrength; - } - } -} - - -Plane CVolumeObjectRenderNode::GetVolumeTraceStartPlane(bool viewerInsideVolume, const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 vdir(cam.GetViewdir()); - Vec3 vpos(cam.GetPosition()); - - if (!viewerInsideVolume) - { - const Vec3 bbp[8] = - { - Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z), - Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z), - Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z), - Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z) - }; - - Plane viewPlane(vdir, -vdir.Dot(vpos)); - - Vec3 p(m_mat * bbp[0]); - float d(viewPlane.DistFromPlane(p)); - - for (int i(1); i < 8; ++i) - { - Vec3 ptmp(m_mat * bbp[i]); - float dtmp(viewPlane.DistFromPlane(ptmp)); - - if (dtmp < d) - { - p = ptmp; - d = dtmp; - } - } - - return Plane(vdir, -vdir.Dot(p)); - } - else - { - return Plane(vdir, -vdir.Dot(vpos)); - } -} - - -float CVolumeObjectRenderNode::GetDistanceToCamera(const SRenderingPassInfo& passInfo) const -{ - const Vec3 bbp[8] = - { - m_mat* Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z), - m_mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z), - m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z), - m_mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z) - }; - - const CCamera& cam(passInfo.GetCamera()); - const Plane* pNearPlane(cam.GetFrustumPlane(FR_PLANE_NEAR)); - const Vec3 camPos(cam.GetPosition()); - - f32 distSq(0.0f); - for (int i(0); i < 8; ++i) - { - float tmpDistSq((bbp[i] - camPos).GetLengthSquared()); - if (tmpDistSq > distSq && pNearPlane->DistFromPlane(bbp[i]) < 0.0f) - { - distSq = tmpDistSq; - } - } - - return sqrt_tpl(distSq); -} - - -void CVolumeObjectRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_3DENGINE; - - // anything to render? - if (passInfo.IsRecursivePass() || !m_pMaterial || !m_pVolDataItem || !m_pVolShadTex || !passInfo.RenderClouds()) - { - return; - } - - IRenderer* pRenderer(GetRenderer()); - - const int fillThreadID = passInfo.ThreadID(); - - // get render objects - CRenderObject* pRO = pRenderer->EF_GetObject_Temp(fillThreadID); - if (!pRO || !m_pRE[fillThreadID]) - { - return; - } - - // update shadow volume - UpdateShadows(); - - // set basic render object properties - pRO->m_II.m_Matrix = m_mat; - pRO->m_fSort = 0; - pRO->m_fDistance = GetDistanceToCamera(passInfo); - - // transform camera into object space - const CCamera& cam(passInfo.GetCamera()); - Vec3 viewerPosWS(cam.GetPosition()); - Vec3 viewerPosOS(m_matInv * viewerPosWS); - - // set render element attributes - bool viewerInsideVolume(IsViewerInsideVolume(passInfo)); - bool nearPlaneIntersectsVolume(NearPlaneIntersectsVolume(passInfo)); - m_pRE[fillThreadID]->m_center = m_pos; - m_pRE[fillThreadID]->m_matInv = m_matInv; - m_pRE[fillThreadID]->m_eyePosInWS = viewerPosWS; - m_pRE[fillThreadID]->m_eyePosInOS = viewerPosOS; - m_pRE[fillThreadID]->m_volumeTraceStartPlane = GetVolumeTraceStartPlane(viewerInsideVolume, passInfo); - m_pRE[fillThreadID]->m_renderBoundsOS = m_tightBoundsOS; - m_pRE[fillThreadID]->m_pHullMesh = m_pVolDataItem->GetHullMesh(); - m_pRE[fillThreadID]->m_viewerInsideVolume = viewerInsideVolume; - m_pRE[fillThreadID]->m_nearPlaneIntersectsVolume = nearPlaneIntersectsVolume; - m_pRE[fillThreadID]->m_alpha = m_alpha; - m_pRE[fillThreadID]->m_scale = m_scale; - m_pRE[fillThreadID]->m_pDensVol = m_pVolDataItem->GetVolumeTexture(); - m_pRE[fillThreadID]->m_pShadVol = m_pVolShadTex; - - float mvd(GetMaxViewDist()); - float d((passInfo.GetCamera().GetPosition() - m_mat.GetTranslation()).GetLength()); - if (d > 0.9f * mvd) - { - float s(clamp_tpl(1.0f - (d - 0.9f * mvd) / (0.1f * mvd), 0.0f, 1.0f)); - m_pRE[fillThreadID]->m_alpha *= s; - } - - // add to renderer - SShaderItem& shaderItem(m_pMaterial->GetShaderItem(0)); - int afterWater(GetObjManager()->IsAfterWater(m_pos, passInfo)); - pRenderer->EF_AddEf(m_pRE[fillThreadID], shaderItem, pRO, passInfo, EFSLIST_TRANSP, afterWater, SRendItemSorter(rParam.rendItemSorter)); - -#if 0 - IRenderAuxGeom* p = pRenderer->GetIRenderAuxGeom(); - if (p) - { - const Matrix34& mat = m_mat; - Vec3 bpp[8] = - { - mat* Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.min.z), - mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.min.z), - - mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z), - mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.min.y, m_tightBoundsOS.max.z), - mat * Vec3(m_tightBoundsOS.max.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z), - mat * Vec3(m_tightBoundsOS.min.x, m_tightBoundsOS.max.y, m_tightBoundsOS.max.z) - }; - - p->SetRenderFlags(e_Def3DPublicRenderflags); - - p->DrawLine(bpp[0], ColorB(255, 0, 0, 255), bpp[1], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[1], ColorB(255, 0, 0, 255), bpp[2], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[2], ColorB(255, 0, 0, 255), bpp[3], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[3], ColorB(255, 0, 0, 255), bpp[0], ColorB(255, 0, 0, 255)); - - p->DrawLine(bpp[4], ColorB(255, 0, 0, 255), bpp[5], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[5], ColorB(255, 0, 0, 255), bpp[6], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[6], ColorB(255, 0, 0, 255), bpp[7], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[7], ColorB(255, 0, 0, 255), bpp[4], ColorB(255, 0, 0, 255)); - - p->DrawLine(bpp[0], ColorB(255, 0, 0, 255), bpp[4], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[1], ColorB(255, 0, 0, 255), bpp[5], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[2], ColorB(255, 0, 0, 255), bpp[6], ColorB(255, 0, 0, 255)); - p->DrawLine(bpp[3], ColorB(255, 0, 0, 255), bpp[7], ColorB(255, 0, 0, 255)); - - const SVolumeDataHull* pHull(m_pVolDataItem->GetHull()); - if (pHull) - { - for (size_t i = 0; i < pHull->m_numTris; ++i) - { - p->DrawTriangle(mat * pHull->m_pPts[pHull->m_pIdx[i * 3]].xyz, ColorB(255, 0, 255, 255), - mat * pHull->m_pPts[pHull->m_pIdx[i * 3 + 1]].xyz, ColorB(255, 0, 255, 255), - mat * pHull->m_pPts[pHull->m_pIdx[i * 3 + 2]].xyz, ColorB(255, 0, 255, 255)); - } - } - } -#endif -} - - -void CVolumeObjectRenderNode::SetMaterial(_smart_ptr pMat) -{ - m_pMaterial = pMat; -} - - -void CVolumeObjectRenderNode::Precache() -{ -} - - -void CVolumeObjectRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "VolumeObjectRenderNode"); - pSizer->AddObject(this, sizeof(*this)); -} - - -void CVolumeObjectRenderNode::Move() -{ - FUNCTION_PROFILER_3DENGINE; - - m_alpha = 1; - - Vec3 pos(m_mat.GetTranslation()); - - ITimer* pTimer(gEnv->pTimer); - if (m_moveProps.m_autoMove) - { - // update position - float deltaTime = pTimer->GetFrameTime(); - - assert(deltaTime >= 0); - - pos += deltaTime * m_moveProps.m_speed; - - // constrain movement to specified loop box - Vec3 loopBoxMin(m_origin - m_moveProps.m_spaceLoopBox); - Vec3 loopBoxMax(m_origin + m_moveProps.m_spaceLoopBox); - - if (pos.x < loopBoxMin.x) - { - pos.x = loopBoxMax.x; - } - if (pos.y < loopBoxMin.y) - { - pos.y = loopBoxMax.y; - } - if (pos.z < loopBoxMin.z) - { - pos.z = loopBoxMax.z; - } - - if (pos.x > loopBoxMax.x) - { - pos.x = loopBoxMin.x; - } - if (pos.y > loopBoxMax.y) - { - pos.y = loopBoxMin.y; - } - if (pos.z > loopBoxMax.z) - { - pos.z = loopBoxMin.z; - } - - // set new position - Matrix34 mat(m_mat); - mat.SetTranslation(pos); - SetMatrixInternal(mat, false); - - // fade out clouds at the borders of the loop box - if (m_moveProps.m_fadeDistance > 0) - { - Vec3 fade(max(m_moveProps.m_spaceLoopBox.x, m_moveProps.m_fadeDistance), - max(m_moveProps.m_spaceLoopBox.y, m_moveProps.m_fadeDistance), - max(m_moveProps.m_spaceLoopBox.z, m_moveProps.m_fadeDistance)); - - fade -= Vec3(fabs(pos.x - m_origin.x), fabs(pos.y - m_origin.y), fabs(pos.z - m_origin.z)); - - m_alpha = clamp_tpl(min(min(fade.x, fade.y), fade.z) / m_moveProps.m_fadeDistance, 0.0f, 1.0f); - } - } - else - { - if ((m_origin - pos).GetLengthSquared() > 1e-4f) - { - Matrix34 mat(m_mat); - mat.SetTranslation(m_origin); - SetMatrixInternal(mat, false); - } - } -} - -void CVolumeObjectRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_WSBBox.Move(delta); - m_pos += delta; - m_origin += delta; - m_matOrig.SetTranslation(m_matOrig.GetTranslation() + delta); - m_mat.SetTranslation(m_mat.GetTranslation() + delta); - m_matInv = m_mat.GetInverted(); -} diff --git a/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.h b/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.h deleted file mode 100644 index 9f0bae3c75..0000000000 --- a/Code/CryEngine/Cry3DEngine/VolumeObjectRenderNode.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTRENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTRENDERNODE_H -#pragma once - -class CREVolumeObject; -class CVolumeDataItem; -class CVolumeShadowCreator; - - -class CVolumeObjectRenderNode - : public IVolumeObjectRenderNode - , public Cry3DEngineBase -{ -public: - static void MoveVolumeObjects(); - -public: - CVolumeObjectRenderNode(); - - // implements IVolumeObjectRenderNode - virtual void LoadVolumeData(const char* filePath); - virtual void SetProperties(const SVolumeObjectProperties& properties); - virtual void SetMovementProperties(const SVolumeObjectMovementProperties& properties); - - // implements IRenderNode - virtual void SetMatrix(const Matrix34& mat); - - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const; - virtual const char* GetName() const; - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - virtual void SetMaterial(_smart_ptr pMat); - virtual _smart_ptr GetMaterial(Vec3* pHitPos = 0); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void Precache(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const AABB GetBBox() const { return m_WSBBox; } - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - - -private: - typedef std::set VolumeObjectSet; - -private: - static void RegisterVolumeObject(CVolumeObjectRenderNode* p); - static void UnregisterVolumeObject(CVolumeObjectRenderNode* p); - -private: - ~CVolumeObjectRenderNode(); - bool IsViewerInsideVolume(const SRenderingPassInfo& passInfo) const; - bool NearPlaneIntersectsVolume(const SRenderingPassInfo& passInfo) const; - void InvalidateLastCachedLightDir(); - void UpdateShadows(); - Plane GetVolumeTraceStartPlane(bool viewerInsideVolume, const SRenderingPassInfo& passInfo) const; - float GetDistanceToCamera(const SRenderingPassInfo& passInfo) const; - void SetMatrixInternal(const Matrix34& mat, bool updateOrigin); - void Move(); - -private: - static CVolumeShadowCreator* ms_pVolShadowCreator; - static StaticInstance ms_volumeObjects; - - static ICVar* ms_CV_volobj_stats; - static int e_volobj_stats; - -private: - AABB m_WSBBox; - - Vec3 m_pos; - Vec3 m_origin; - - Matrix34 m_matOrig; - Matrix34 m_mat; - Matrix34 m_matInv; - - Vec3 m_lastCachedLightDir; - - AABB m_tightBoundsOS; - - SVolumeObjectMovementProperties m_moveProps; - - float m_alpha; - float m_scale; - - float m_shadowStrength; - - _smart_ptr< IMaterial > m_pMaterial; - - CREVolumeObject* m_pRE[RT_COMMAND_BUF_COUNT]; - - CVolumeDataItem* m_pVolDataItem; - IVolumeTexture* m_pVolShadTex; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_VOLUMEOBJECTRENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.cpp b/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.cpp deleted file mode 100644 index 8be76eac1b..0000000000 --- a/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.cpp +++ /dev/null @@ -1,1441 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "Cry3DEngine_precompiled.h" -#include "WaterVolumeRenderNode.h" -#include "VisAreas.h" -#include "MatMan.h" -#include "TimeOfDay.h" -#include -#include "MathConversion.h" - -#include -#include - -////////////////////////////////////////////////////////////////////////// -// private triangulation code -namespace WaterVolumeRenderNodeUtils -{ - template< typename T > - size_t PosOffset(); - - template<> - size_t PosOffset() - { - return 0; - } - - template<> - size_t PosOffset() - { - return offsetof(SVF_P3F_C4B_T2F, xyz); - } - - - template< typename T > - struct VertexAccess - { - VertexAccess(const T* pVertices, size_t numVertices) - : m_pVertices(pVertices) - , m_numVertices(numVertices) - { - } - - const Vec3& operator[] (size_t idx) const - { - assert(idx < m_numVertices); - const T* pVertex = &m_pVertices[ idx ]; - return *(Vec3*) ((size_t) pVertex + PosOffset()); - } - - const size_t GetNumVertices() const - { - return m_numVertices; - } - - private: - const T* m_pVertices; - size_t m_numVertices; - }; - - - template< typename T > - float Area(const VertexAccess& contour) - { - int n = contour.GetNumVertices(); - float area = 0.0f; - - for (int p = n - 1, q = 0; q < n; p = q++) - { - area += contour[p].x * contour[q].y - contour[q].x * contour[p].y; - } - - return area * 0.5f; - } - - bool InsideTriangle(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Px, float Py) - { - float ax = Cx - Bx; - float ay = Cy - By; - float bx = Ax - Cx; - float by = Ay - Cy; - float cx = Bx - Ax; - float cy = By - Ay; - float apx = Px - Ax; - float apy = Py - Ay; - float bpx = Px - Bx; - float bpy = Py - By; - float cpx = Px - Cx; - float cpy = Py - Cy; - - float aCROSSbp = ax * bpy - ay * bpx; - float cCROSSap = cx * apy - cy * apx; - float bCROSScp = bx * cpy - by * cpx; - - const float fEpsilon = -FLT_EPSILON; - return (aCROSSbp >= fEpsilon) && (bCROSScp >= fEpsilon) && (cCROSSap >= fEpsilon); - }; - - template< typename T, typename S > - bool Snip(const VertexAccess& contour, int u, int v, int w, int n, const S* V) - { - float Ax = contour[V[u]].x; - float Ay = contour[V[u]].y; - - float Bx = contour[V[v]].x; - float By = contour[V[v]].y; - - float Cx = contour[V[w]].x; - float Cy = contour[V[w]].y; - - if ((((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))) < 1e-6f) - { - return false; - } - - for (int p = 0; p < n; p++) - { - if ((p == u) || (p == v) || (p == w)) - { - continue; - } - - float Px = contour[V[p]].x; - float Py = contour[V[p]].y; - - if (WaterVolumeRenderNodeUtils::InsideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) - { - return false; - } - } - - return true; - } - - - template< typename T, typename S > - bool Triangulate(const VertexAccess& contour, std::vector& result) - { - // reset result - result.resize(0); - - //C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead - PREFAST_SUPPRESS_WARNING(6255) - // allocate and initialize list of vertices in polygon - int n = contour.GetNumVertices(); - if (n < 3) - { - return false; - } - - S* V = (S*) alloca(n * sizeof(S)); - - // we want a counter-clockwise polygon in V - if (0.0f < Area(contour)) - { - for (int v = 0; v < n; v++) - { - V[v] = v; - } - } - else - { - for (int v = 0; v < n; v++) - { - V[v] = (n - 1) - v; - } - } - - int nv = n; - - // remove nv-2 vertices, creating 1 triangle every time - int count = 2 * nv; // error detection - - for (int m = 0, v = nv - 1; nv > 2; ) - { - // if we loop, it is probably a non-simple polygon - if (0 >= (count--)) - { - return false; // ERROR - probably bad polygon! - } - // three consecutive vertices in current polygon, - int u = v; - if (nv <= u) - { - u = 0; // previous - } - v = u + 1; - if (nv <= v) - { - v = 0; // new v - } - int w = v + 1; - if (nv <= w) - { - w = 0; // next - } - if (Snip(contour, u, v, w, nv, V)) - { - // true names of the vertices - PREFAST_SUPPRESS_WARNING(6385) - S a = V[u]; - S b = V[v]; - S c = V[w]; - - // output triangle - result.push_back(a); - result.push_back(b); - result.push_back(c); - - m++; - - // remove v from remaining polygon - for (int s = v, t = v + 1; t < nv; s++, t++) - { - PREFAST_SUPPRESS_WARNING(6386) - V[s] = V[t]; - } - - nv--; - - // reset error detection counter - count = 2 * nv; - } - } - - return true; - } -} - - -////////////////////////////////////////////////////////////////////////// -// helpers - -inline static Vec3 MapVertexToFogPlane(const Vec3& v, const Plane& p) -{ - const Vec3 projDir(0, 0, 1); - float perpdist = p | v; - float cosine = p.n | projDir; - assert(fabs(cosine) > 1e-4); - float pd_c = -perpdist / cosine; - return v + projDir * pd_c; -} - - -////////////////////////////////////////////////////////////////////////// -// CWaterVolumeRenderNode implementation - -CWaterVolumeRenderNode::CWaterVolumeRenderNode() - : m_volumeType(IWaterVolumeRenderNode::eWVT_Unknown) - , m_volumeID(~0) - , m_volumeDepth(0) - , m_streamSpeed(0) - , m_wvParams() - , m_pMaterial(0) - , m_pWaterBodyIntoMat(0) - , m_pWaterBodyOutofMat(0) - , m_pSerParams(0) - , m_pPhysAreaInput(0) - , m_pPhysArea(0) - , m_waterSurfaceVertices() - , m_waterSurfaceIndices() - , m_parentEntityWorldTM() - , m_nLayerId(0) - , m_fogDensity(0) - , m_fogColor(0.2f, 0.5f, 0.7f) - , m_fogColorAffectedBySun(true) - , m_fogPlane(Vec3(0, 0, 1), 0) - , m_fogPlaneBase(Vec3(0, 0, 1), 0) - , m_fogShadowing(0.5f) - , m_center(0, 0, 0) - , m_WSBBox(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_capFogAtVolumeDepth(false) - , m_caustics(true) - , m_causticIntensity(1.0f) - , m_causticTiling(1.0f) - , m_causticHeight(0.5f) - , m_attachedToEntity(false) -{ - m_pWaterBodyIntoMat = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/WaterFogVolumeInto", false); - m_pWaterBodyOutofMat = GetMatMan()->LoadMaterial("EngineAssets/Materials/Fog/WaterFogVolumeOutof", false); - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pVolumeRE[i] = static_cast(GetRenderer()->EF_CreateRE(eDATA_WaterVolume)); - if (m_pVolumeRE[i]) - { - m_pVolumeRE[i]->m_drawWaterSurface = false; - m_pVolumeRE[i]->m_pParams = &m_wvParams[i]; - } - } - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pSurfaceRE[i] = static_cast(GetRenderer()->EF_CreateRE(eDATA_WaterVolume)); - if (m_pSurfaceRE[i]) - { - m_pSurfaceRE[i]->m_drawWaterSurface = true; - m_pSurfaceRE[i]->m_pParams = &m_wvParams[i]; - } - } - - m_parentEntityWorldTM.SetIdentity(); - m_vOffset = Vec3(ZERO); -} - - -CWaterVolumeRenderNode::~CWaterVolumeRenderNode() -{ - Dephysicalize(); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_pVolumeRE[i]->Release(true); - m_pVolumeRE[i] = 0; - m_pSurfaceRE[i]->Release(true); - m_pSurfaceRE[i] = 0; - } - SAFE_DELETE(m_pSerParams); - SAFE_DELETE(m_pPhysAreaInput); - - Get3DEngine()->FreeRenderNodeState(this); -} - - -void CWaterVolumeRenderNode::SetAreaAttachedToEntity() -{ - m_attachedToEntity = true; -} - - -void CWaterVolumeRenderNode::SetFogDensity(float fogDensity) -{ - m_fogDensity = fogDensity; -} - - -float CWaterVolumeRenderNode::GetFogDensity() const -{ - return m_fogDensity; -} - - -void CWaterVolumeRenderNode::SetFogColor(const Vec3& fogColor) -{ - m_fogColor = fogColor; -} - - -void CWaterVolumeRenderNode::SetFogColorAffectedBySun(bool enable) -{ - m_fogColorAffectedBySun = enable; -} - - -void CWaterVolumeRenderNode::SetFogShadowing(float fogShadowing) -{ - m_fogShadowing = fogShadowing; -} - - -void CWaterVolumeRenderNode::SetCapFogAtVolumeDepth(bool capFog) -{ - m_capFogAtVolumeDepth = capFog; -} - - -void CWaterVolumeRenderNode::SetVolumeDepth(float volumeDepth) -{ - m_volumeDepth = volumeDepth; - - UpdateBoundingBox(); -} - - -void CWaterVolumeRenderNode::SetStreamSpeed(float streamSpeed) -{ - m_streamSpeed = streamSpeed; -} - - -void CWaterVolumeRenderNode::SetCaustics(bool caustics) -{ - m_caustics = caustics; -} - - -void CWaterVolumeRenderNode::SetCausticIntensity(float causticIntensity) -{ - m_causticIntensity = causticIntensity; -} - - -void CWaterVolumeRenderNode::SetCausticTiling(float causticTiling) -{ - m_causticTiling = causticTiling; -} - - -void CWaterVolumeRenderNode::SetCausticHeight(float causticHeight) -{ - m_causticHeight = causticHeight; -} - - -void CWaterVolumeRenderNode::CreateOcean([[maybe_unused]] uint64 volumeID, [[maybe_unused]] /* TBD */ bool keepSerializationParams) -{ -} - - -void CWaterVolumeRenderNode::CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams, int nSID) -{ - const bool serializeWith3DEngine = keepSerializationParams && !IsAttachedToEntity(); - - assert(fabs(fogPlane.n.GetLengthSquared() - 1.0f) < 1e-4 && "CWaterVolumeRenderNode::CreateArea(...) -- Fog plane normal doesn't have unit length!"); - assert(fogPlane.n.Dot(Vec3(0, 0, 1)) > 1e-4f && "CWaterVolumeRenderNode::CreateArea(...) -- Invalid fog plane specified!"); - if (fogPlane.n.Dot(Vec3(0, 0, 1)) <= 1e-4f) - { - return; - } - - assert(numVertices >= 3); - if (numVertices < 3) - { - return; - } - - m_volumeID = volumeID; - m_fogPlane = fogPlane; - m_fogPlaneBase = fogPlane; - m_volumeType = IWaterVolumeRenderNode::eWVT_Area; - - // copy volatile creation params to be able to serialize water volume if needed (only in editor) - if (serializeWith3DEngine) - { - CopyVolatileAreaSerParams(pVertices, numVertices, surfUVScale); - } - - // remove form 3d engine - Get3DEngine()->UnRegisterEntityAsJob(this); - - // Edges pre-pass - break into smaller edges, in case distance threshold too big - PodArray< Vec3 > pTessVertList; - PodArray< SVF_P3F_C4B_T2F > pVertsTemp; - PodArray< uint16 > pIndicesTemp; - - for (uint32 v(0); v < numVertices; ++v) - { - Vec3 in_a = pVertices[v]; - Vec3 in_b = (v < numVertices - 1) ? pVertices[v + 1] : pVertices[0]; // close mesh - - Vec3 vAB = in_b - in_a; - float fLenAB = vAB.len(); - vAB.normalize(); - - pTessVertList.push_back(in_a); - - const float fLenThreshold = 100.0f; // break every 100 meters - Vec3 vNewVert = Vec3(in_a + (vAB * fLenThreshold)); - while (fLenAB > fLenThreshold) - { - pTessVertList.push_back(vNewVert); - - vNewVert = Vec3(vNewVert + (vAB * fLenThreshold)); - vAB = in_b - vNewVert; - fLenAB = vAB.len(); - vAB.normalize(); - } - } - - m_waterSurfaceVertices.resize(pTessVertList.size()); - for (uint32 i = 0; i < pTessVertList.size(); ++i) - { - // project input vertex onto fog plane - m_waterSurfaceVertices[i].xyz = MapVertexToFogPlane(pTessVertList[i], fogPlane); - - // generate texture coordinates - m_waterSurfaceVertices[i].st = Vec2(surfUVScale.x * (pTessVertList[i].x - pTessVertList[0].x), surfUVScale.y * (pTessVertList[i].y - pTessVertList[0].y)); - - pVertsTemp.push_back(m_waterSurfaceVertices[i]); - } - - // generate indices. - // Note: triangulation code not robust, relies on contour/vertices to be declared sequentially and no holes -> too many vertices will lead to stretched results - WaterVolumeRenderNodeUtils::Triangulate(WaterVolumeRenderNodeUtils::VertexAccess(&m_waterSurfaceVertices[0], m_waterSurfaceVertices.size()), m_waterSurfaceIndices); - - // update bounding info - UpdateBoundingBox(); - - // Safety check. - if (m_waterSurfaceIndices.empty()) - { - return; - } - - // Pre-tessellate mesh further - uint32_t iterationCount = 4; - for (uint32 i = 0; i < iterationCount; ++i) - { - uint32 nIndices = m_waterSurfaceIndices.size(); - for (uint32 t = 0; t < nIndices; t += 3) - { - // Get triangle, compute median edge vertex, insert to vertex list - uint16 id_a = m_waterSurfaceIndices[t + 0]; - uint16 id_b = m_waterSurfaceIndices[t + 1]; - uint16 id_c = m_waterSurfaceIndices[t + 2]; - - SVF_P3F_C4B_T2F& vtx_a = m_waterSurfaceVertices[ id_a ]; - SVF_P3F_C4B_T2F& vtx_b = m_waterSurfaceVertices[ id_b ]; - SVF_P3F_C4B_T2F& vtx_c = m_waterSurfaceVertices[ id_c ]; - - SVF_P3F_C4B_T2F vtx_m_ab; - vtx_m_ab.xyz = (vtx_a.xyz + vtx_b.xyz) * 0.5f; - vtx_m_ab.st = (vtx_a.st + vtx_b.st) * 0.5f; - vtx_m_ab.color = vtx_a.color; - - pVertsTemp.push_back(vtx_m_ab); - uint16 id_d = (uint16) pVertsTemp.size() - 1; - - SVF_P3F_C4B_T2F vtx_m_bc; - vtx_m_bc.xyz = (vtx_b.xyz + vtx_c.xyz) * 0.5f; - vtx_m_bc.st = (vtx_b.st + vtx_c.st) * 0.5f; - vtx_m_bc.color = vtx_a.color; - - pVertsTemp.push_back(vtx_m_bc); - uint16 id_e = (uint16) pVertsTemp.size() - 1; - - SVF_P3F_C4B_T2F vtx_m_ca; - vtx_m_ca.xyz = (vtx_a.xyz + vtx_c.xyz) * 0.5f; - vtx_m_ca.st = (vtx_a.st + vtx_c.st) * 0.5f; - vtx_m_ca.color = vtx_a.color; - - pVertsTemp.push_back(vtx_m_ca); - uint16 id_f = (uint16) pVertsTemp.size() - 1; - - // build new indices - - // aed - pIndicesTemp.push_back(id_a); - pIndicesTemp.push_back(id_d); - pIndicesTemp.push_back(id_f); - - // ebd - pIndicesTemp.push_back(id_d); - pIndicesTemp.push_back(id_b); - pIndicesTemp.push_back(id_e); - - // bfd - pIndicesTemp.push_back(id_f); - pIndicesTemp.push_back(id_d); - pIndicesTemp.push_back(id_e); - - // fcd - pIndicesTemp.push_back(id_f); - pIndicesTemp.push_back(id_e); - pIndicesTemp.push_back(id_c); - } - - // update index list for new iteration - m_waterSurfaceIndices.resize(pIndicesTemp.size()); - memcpy(&m_waterSurfaceIndices[0], &pIndicesTemp[0], sizeof(uint16) * pIndicesTemp.size()); - m_waterSurfaceVertices.resize(pVertsTemp.size()); - memcpy(&m_waterSurfaceVertices[0], &pVertsTemp[0], sizeof(SVF_P3F_C4B_T2F) * pVertsTemp.size()); - pIndicesTemp.clear(); - } - - // update reference to vertex and index buffer - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_wvParams[i].m_pVertices = &m_waterSurfaceVertices[0]; - m_wvParams[i].m_numVertices = m_waterSurfaceVertices.size(); - m_wvParams[i].m_pIndices = &m_waterSurfaceIndices[0]; - m_wvParams[i].m_numIndices = m_waterSurfaceIndices.size(); - } - - // add to 3d engine - Get3DEngine()->RegisterEntity(this, nSID, nSID); -} - -void CWaterVolumeRenderNode::CreateRiver(uint64 volumeID, const AZStd::vector& verticies, const AZ::Transform& transform, float uTexCoordBegin, float uTexCoordEnd, const AZ::Vector2& surfUVScale, const AZ::Plane& fogPlane, bool keepSerializationParams, int nSID) -{ - PodArray points; - points.reserve(verticies.size()); - for (auto azPoint : verticies) - { - points.Add(AZVec3ToLYVec3(transform.TransformPoint(azPoint))); - } - - Plane plane = AZPlaneToLyPlane(fogPlane); - CreateRiver(volumeID, points.GetElements(), static_cast(verticies.size()), uTexCoordBegin, uTexCoordEnd, Vec2(surfUVScale.GetX(), surfUVScale.GetY()), plane, keepSerializationParams, nSID); -} - -void CWaterVolumeRenderNode::CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams, int nSID) -{ - const float precisionTolerance = 1e-2f; - - assert(fabs(fogPlane.n.GetLengthSquared() - 1.0f) < precisionTolerance && "CWaterVolumeRenderNode::CreateRiver(...) -- Fog plane normal doesn't have unit length!"); - assert(fogPlane.n.Dot(Vec3(0, 0, 1)) > precisionTolerance && "CWaterVolumeRenderNode::CreateRiver(...) -- Invalid fog plane specified!"); - if (fogPlane.n.Dot(Vec3(0, 0, 1)) <= precisionTolerance) - { - return; - } - - assert(numVertices == 4); - if (numVertices != 4 || !_finite(pVertices[0].x) || !_finite(pVertices[1].x) || !_finite(pVertices[2].x) || !_finite(pVertices[3].x)) - { - return; - } - - m_volumeID = volumeID; - m_fogPlane = fogPlane; - m_fogPlaneBase = fogPlane; - m_volumeType = IWaterVolumeRenderNode::eWVT_River; - - // copy volatile creation params to be able to serialize water volume if needed (only in editor) - if (keepSerializationParams) - { - CopyVolatileRiverSerParams(pVertices, numVertices, uTexCoordBegin, uTexCoordEnd, surfUVScale); - } - - // remove form 3d engine - Get3DEngine()->UnRegisterEntityAsJob(this); - - // generate vertices - m_waterSurfaceVertices.resize(5); - m_waterSurfaceVertices[0].xyz = pVertices[0]; - m_waterSurfaceVertices[1].xyz = pVertices[1]; - m_waterSurfaceVertices[2].xyz = pVertices[2]; - m_waterSurfaceVertices[3].xyz = pVertices[3]; - m_waterSurfaceVertices[4].xyz = 0.25f * (pVertices[0] + pVertices[1] + pVertices[2] + pVertices[3]); - - Vec3 tv0 = Vec3(0, 0, 1.f); - Vec3 tv1 = Vec3(0, 0, -1.f); - Plane planes[4]; - planes[0].SetPlane(pVertices[0], pVertices[1], pVertices[1] + tv0); - planes[1].SetPlane(pVertices[2], pVertices[3], pVertices[3] + tv1); - planes[2].SetPlane(pVertices[0], pVertices[2], pVertices[2] + tv1); - planes[3].SetPlane(pVertices[1], pVertices[3], pVertices[3] + tv0); - - - for (uint32 i(0); i < 5; ++i) - { - // map input vertex onto fog plane - m_waterSurfaceVertices[i].xyz = MapVertexToFogPlane(m_waterSurfaceVertices[i].xyz, fogPlane); - - // generate texture coordinates - float d0(fabsf(planes[0].DistFromPlane(m_waterSurfaceVertices[i].xyz))); - float d1(fabsf(planes[1].DistFromPlane(m_waterSurfaceVertices[i].xyz))); - float d2(fabsf(planes[2].DistFromPlane(m_waterSurfaceVertices[i].xyz))); - float d3(fabsf(planes[3].DistFromPlane(m_waterSurfaceVertices[i].xyz))); - float t(fabsf(d0 + d1) < FLT_EPSILON ? 0.0f : clamp_tpl(d0 / (d0 + d1), 0.0f, 1.0f)); - - Vec2 st = Vec2((1 - t) * fabsf(uTexCoordBegin) + t * fabsf(uTexCoordEnd), fabsf(d2 + d3) < FLT_EPSILON ? 0.0f : clamp_tpl(d2 / (d2 + d3), 0.0f, 1.0f)); - st[0] *= surfUVScale.x; - st[1] *= surfUVScale.y; - - m_waterSurfaceVertices[i].st = st; - } - - // generate indices - m_waterSurfaceIndices.resize(12); - m_waterSurfaceIndices[ 0] = 0; - m_waterSurfaceIndices[ 1] = 1; - m_waterSurfaceIndices[ 2] = 4; - - m_waterSurfaceIndices[ 3] = 1; - m_waterSurfaceIndices[ 4] = 3; - m_waterSurfaceIndices[ 5] = 4; - - m_waterSurfaceIndices[ 6] = 3; - m_waterSurfaceIndices[ 7] = 2; - m_waterSurfaceIndices[ 8] = 4; - - m_waterSurfaceIndices[ 9] = 0; - m_waterSurfaceIndices[10] = 4; - m_waterSurfaceIndices[11] = 2; - - // update bounding info - UpdateBoundingBox(); - - // update reference to vertex and index buffer - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_wvParams[i].m_pVertices = &m_waterSurfaceVertices[0]; - m_wvParams[i].m_numVertices = m_waterSurfaceVertices.size(); - m_wvParams[i].m_pIndices = &m_waterSurfaceIndices[0]; - m_wvParams[i].m_numIndices = m_waterSurfaceIndices.size(); - } - - // add to 3d engine - Get3DEngine()->RegisterEntity(this, nSID, nSID); -} - - -void CWaterVolumeRenderNode::SetAreaPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams) -{ - const bool serializeWith3DEngine = keepSerializationParams && !IsAttachedToEntity(); - - assert(pVertices && numVertices > 3 && m_volumeType == IWaterVolumeRenderNode::eWVT_Area); - if (!pVertices || numVertices <= 3 || m_volumeType != IWaterVolumeRenderNode::eWVT_Area) - { - return; - } - - if (!m_pPhysAreaInput) - { - m_pPhysAreaInput = new SWaterVolumePhysAreaInput; - } - - const Plane& fogPlane(m_fogPlane); - - // generate contour vertices - m_pPhysAreaInput->m_contour.resize(numVertices); - - // map input vertices onto fog plane - if (WaterVolumeRenderNodeUtils::Area(WaterVolumeRenderNodeUtils::VertexAccess(pVertices, numVertices)) > 0.0f) - { - for (unsigned int i(0); i < numVertices; ++i) - { - m_pPhysAreaInput->m_contour[i] = MapVertexToFogPlane(pVertices[i], fogPlane); // flip vertex order as physics expects them CCW - } - } - else - { - for (unsigned int i(0); i < numVertices; ++i) - { - m_pPhysAreaInput->m_contour[i] = MapVertexToFogPlane(pVertices[numVertices - 1 - i], fogPlane); - } - } - - // triangulate contour - WaterVolumeRenderNodeUtils::Triangulate(WaterVolumeRenderNodeUtils::VertexAccess(&m_pPhysAreaInput->m_contour[0], m_pPhysAreaInput->m_contour.size()), m_pPhysAreaInput->m_indices); - - // reset flow - m_pPhysAreaInput->m_flowContour.resize(0); - - if (serializeWith3DEngine) - { - CopyVolatilePhysicsAreaContourSerParams(pVertices, numVertices); - } -} - -void CWaterVolumeRenderNode::SetRiverPhysicsArea(const AZStd::vector& verticies, const AZ::Transform& transform, bool keepSerializationParams) -{ - PodArray points; - points.reserve(verticies.size()); - for (auto azPoint : verticies) - { - points.Add(AZVec3ToLYVec3(transform.TransformPoint(azPoint))); - } - SetRiverPhysicsArea(points.GetElements(), static_cast(verticies.size()), keepSerializationParams); -} - -void CWaterVolumeRenderNode::SetRiverPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams) -{ - assert(pVertices && numVertices > 3 && !(numVertices & 1) && m_volumeType == IWaterVolumeRenderNode::eWVT_River); - if (!pVertices || numVertices <= 3 || (numVertices & 1) || m_volumeType != IWaterVolumeRenderNode::eWVT_River) - { - return; - } - - if (!m_pPhysAreaInput) - { - m_pPhysAreaInput = new SWaterVolumePhysAreaInput; - } - - const Plane& fogPlane(m_fogPlane); - - // generate contour vertices - m_pPhysAreaInput->m_contour.resize(numVertices); - - // map input vertices onto fog plane - if (WaterVolumeRenderNodeUtils::Area(WaterVolumeRenderNodeUtils::VertexAccess(pVertices, numVertices)) > 0.0f) - { - for (unsigned int i(0); i < numVertices; ++i) - { - m_pPhysAreaInput->m_contour[i] = MapVertexToFogPlane(pVertices[i], fogPlane); // flip vertex order as physics expects them CCW - } - } - else - { - for (unsigned int i(0); i < numVertices; ++i) - { - m_pPhysAreaInput->m_contour[i] = MapVertexToFogPlane(pVertices[numVertices - 1 - i], fogPlane); - } - } - - // generate flow along contour - unsigned int h(numVertices / 2); - unsigned int h2(numVertices); - m_pPhysAreaInput->m_flowContour.resize(numVertices); - for (unsigned int i(0); i < h; ++i) - { - if (!i) - { - m_pPhysAreaInput->m_flowContour[i] = (m_pPhysAreaInput->m_contour[i + 1] - m_pPhysAreaInput->m_contour[i]).GetNormalizedSafe() * m_streamSpeed; - } - else if (i == h - 1) - { - m_pPhysAreaInput->m_flowContour[i] = (m_pPhysAreaInput->m_contour[i] - m_pPhysAreaInput->m_contour[i - 1]).GetNormalizedSafe() * m_streamSpeed; - } - else - { - m_pPhysAreaInput->m_flowContour[i] = (m_pPhysAreaInput->m_contour[i + 1] - m_pPhysAreaInput->m_contour[i - 1]).GetNormalizedSafe() * m_streamSpeed; - } - } - - for (unsigned int i(0); i < h; ++i) - { - if (!i) - { - m_pPhysAreaInput->m_flowContour[h2 - 1 - i] = (m_pPhysAreaInput->m_contour[h2 - 1 - i - 1] - m_pPhysAreaInput->m_contour[h2 - 1 - i]).GetNormalizedSafe() * m_streamSpeed; - } - else if (i == h - 1) - { - m_pPhysAreaInput->m_flowContour[h2 - 1 - i] = (m_pPhysAreaInput->m_contour[h2 - 1 - i] - m_pPhysAreaInput->m_contour[h2 - 1 - i + 1]).GetNormalizedSafe() * m_streamSpeed; - } - else - { - m_pPhysAreaInput->m_flowContour[h2 - 1 - i] = (m_pPhysAreaInput->m_contour[h2 - 1 - i - 1] - m_pPhysAreaInput->m_contour[h2 - 1 - i + 1]).GetNormalizedSafe() * m_streamSpeed; - } - } - - // triangulate contour - m_pPhysAreaInput->m_indices.resize(3 * 2 * (numVertices / 2 - 1)); - for (unsigned int i(0); i < h - 1; ++i) - { - m_pPhysAreaInput->m_indices[6 * i + 0] = i; - m_pPhysAreaInput->m_indices[6 * i + 1] = i + 1; - m_pPhysAreaInput->m_indices[6 * i + 2] = h2 - 1 - i - 1; - - m_pPhysAreaInput->m_indices[6 * i + 3] = h2 - 1 - i - 1; - m_pPhysAreaInput->m_indices[6 * i + 4] = h2 - 1 - i; - m_pPhysAreaInput->m_indices[6 * i + 5] = i; - } - - if (keepSerializationParams) - { - CopyVolatilePhysicsAreaContourSerParams(pVertices, numVertices); - } -} - - - -const char* CWaterVolumeRenderNode::GetEntityClassName() const -{ - return "WaterVolume"; -} - - -const char* CWaterVolumeRenderNode::GetName() const -{ - return "WaterVolume"; -} - -IRenderNode* CWaterVolumeRenderNode::Clone() const -{ - CWaterVolumeRenderNode* pWaterVol = new CWaterVolumeRenderNode(); - - // CWaterVolumeRenderNode member vars - pWaterVol->m_volumeType = m_volumeType; - - pWaterVol->m_volumeID = m_volumeID; - - pWaterVol->m_volumeDepth = m_volumeDepth; - pWaterVol->m_streamSpeed = m_streamSpeed; - - pWaterVol->m_pMaterial = m_pMaterial; - pWaterVol->m_pWaterBodyIntoMat = m_pWaterBodyIntoMat; - pWaterVol->m_pWaterBodyOutofMat = m_pWaterBodyOutofMat; - - if (m_pPhysAreaInput != NULL) - { - pWaterVol->m_pPhysAreaInput = new SWaterVolumePhysAreaInput; - *pWaterVol->m_pPhysAreaInput = *m_pPhysAreaInput; - } - else - { - pWaterVol->m_pPhysAreaInput = NULL; - } - - pWaterVol->m_waterSurfaceVertices = m_waterSurfaceVertices; - pWaterVol->m_waterSurfaceIndices = m_waterSurfaceIndices; - - pWaterVol->m_parentEntityWorldTM = m_parentEntityWorldTM; - pWaterVol->m_nLayerId = m_nLayerId; - - pWaterVol->m_fogDensity = m_fogDensity; - pWaterVol->m_fogColor = m_fogColor; - pWaterVol->m_fogColorAffectedBySun = m_fogColorAffectedBySun; - pWaterVol->m_fogShadowing = m_fogShadowing; - - pWaterVol->m_fogPlane = m_fogPlane; - pWaterVol->m_fogPlaneBase = m_fogPlaneBase; - - pWaterVol->m_center = m_center; - pWaterVol->m_WSBBox = m_WSBBox; - - pWaterVol->m_capFogAtVolumeDepth = m_capFogAtVolumeDepth; - pWaterVol->m_attachedToEntity = m_attachedToEntity; - pWaterVol->m_caustics = m_caustics; - - pWaterVol->m_causticIntensity = m_causticIntensity; - pWaterVol->m_causticTiling = m_causticTiling; - pWaterVol->m_causticShadow = m_causticShadow; - pWaterVol->m_causticHeight = m_causticHeight; - - // update reference to vertex and index buffer - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - pWaterVol->m_wvParams[i].m_pVertices = &pWaterVol->m_waterSurfaceVertices[0]; - pWaterVol->m_wvParams[i].m_numVertices = pWaterVol->m_waterSurfaceVertices.size(); - pWaterVol->m_wvParams[i].m_pIndices = &pWaterVol->m_waterSurfaceIndices[0]; - pWaterVol->m_wvParams[i].m_numIndices = pWaterVol->m_waterSurfaceIndices.size(); - } - - //IRenderNode member vars - // We cannot just copy over due to issues with the linked list of IRenderNode objects - CopyIRenderNodeData(pWaterVol); - - return pWaterVol; -} - -inline void TransformPosition(Vec3& pos, const Vec3& localOrigin, const Matrix34& l2w) -{ - pos = pos - localOrigin; - pos = l2w * pos; -} - -void CWaterVolumeRenderNode::Transform(const Vec3& localOrigin, const Matrix34& l2w) -{ - CRY_ASSERT_MESSAGE(!IsAttachedToEntity(), "FIXME: Don't currently support transforming attached water volumes"); - - if (m_pPhysAreaInput != NULL) - { - for (std::vector::iterator it = m_pPhysAreaInput->m_contour.begin(); it != m_pPhysAreaInput->m_contour.end(); ++it) - { - Vec3& pos = *it; - TransformPosition(pos, localOrigin, l2w); - } - - for (std::vector::iterator it = m_pPhysAreaInput->m_flowContour.begin(); it != m_pPhysAreaInput->m_flowContour.end(); ++it) - { - Vec3& pos = *it; - TransformPosition(pos, localOrigin, l2w); - } - } - - for (WaterSurfaceVertices::iterator it = m_waterSurfaceVertices.begin(); it != m_waterSurfaceVertices.end(); ++it) - { - SVF_P3F_C4B_T2F& vert = *it; - TransformPosition(vert.xyz, localOrigin, l2w); - } - - Vec3 origFogPoint = m_fogPlane.n * m_fogPlane.d; - TransformPosition(origFogPoint, localOrigin, l2w); - m_fogPlane.SetPlane(l2w.TransformVector(m_fogPlaneBase.n).GetNormalized(), origFogPoint); - - TransformPosition(m_center, localOrigin, l2w); - - UpdateBoundingBox(); -} - -void CWaterVolumeRenderNode::SetMatrix(const Matrix34& mat) -{ - if (!IsAttachedToEntity()) - { - return; - } - - m_parentEntityWorldTM = mat; - m_fogPlane.SetPlane(m_parentEntityWorldTM.TransformVector(m_fogPlaneBase.n).GetNormalized(), m_parentEntityWorldTM.GetTranslation()); - - UpdateBoundingBox(); -} - - -void CWaterVolumeRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo) -{ - Render_JobEntry(rParam, passInfo, SRendItemSorter(rParam.rendItemSorter)); -} - -void CWaterVolumeRenderNode::Render_JobEntry(const SRendParams& rParam, const SRenderingPassInfo& passInfo, SRendItemSorter rendItemSorter) -{ - FUNCTION_PROFILER_3DENGINE; - - // hack: special case for when inside amphibious vehicle - if (Get3DEngine()->GetOceanRenderFlags() & OCR_NO_DRAW) - { - return; - } - - // anything to render? - if (passInfo.IsRecursivePass() || !m_pMaterial || !m_pWaterBodyIntoMat || !m_pWaterBodyOutofMat || !passInfo.RenderWaterVolumes() || - m_waterSurfaceVertices.empty() || m_waterSurfaceIndices.empty()) - { - return; - } - - if (m_fogDensity == 0) - { - return; - } - - IRenderer* pRenderer(GetRenderer()); - - const int fillThreadID = passInfo.ThreadID(); - - // get render objects - CRenderObject* pROVol = pRenderer->EF_GetObject_Temp(fillThreadID); - CRenderObject* pROSurf = pRenderer->EF_GetObject_Temp(fillThreadID); - if (!pROVol || !pROSurf) - { - return; - } - - if (!m_pSurfaceRE[fillThreadID]) - { - return; - } - - float distToWaterVolumeSurface(GetCameraDistToWaterVolumeSurface(passInfo)); - bool aboveWaterVolumeSurface(distToWaterVolumeSurface > 0.0f); - bool belowWaterVolume(m_capFogAtVolumeDepth && distToWaterVolumeSurface < -m_volumeDepth); - bool insideWaterVolumeSurface2D(IsCameraInsideWaterVolumeSurface2D(passInfo)); - bool insideWaterVolume(insideWaterVolumeSurface2D && !aboveWaterVolumeSurface && !belowWaterVolume); - - // fill parameters to render elements - m_wvParams[fillThreadID].m_viewerInsideVolume = insideWaterVolume; - m_wvParams[fillThreadID].m_viewerCloseToWaterPlane = /*insideWaterVolumeSurface2D && */ fabsf(distToWaterVolumeSurface) < 0.5f; - m_wvParams[fillThreadID].m_viewerCloseToWaterVolume = GetCameraDistSqToWaterVolumeAABB(passInfo) < 9.0f; //Sq dist - - const float hdrMultiplier = m_fogColorAffectedBySun ? 1.0f : ((CTimeOfDay*)Get3DEngine()->GetTimeOfDay())->GetHDRMultiplier(); - - m_wvParams[fillThreadID].m_fogDensity = m_fogDensity; - m_wvParams[fillThreadID].m_fogColor = m_fogColor * hdrMultiplier; - m_wvParams[fillThreadID].m_fogColorAffectedBySun = m_fogColorAffectedBySun; - m_wvParams[fillThreadID].m_fogPlane = m_fogPlane; - m_wvParams[fillThreadID].m_fogShadowing = m_fogShadowing; - - m_wvParams[fillThreadID].m_caustics = m_caustics; - m_wvParams[fillThreadID].m_causticIntensity = m_causticIntensity; - m_wvParams[fillThreadID].m_causticTiling = m_causticTiling; - m_wvParams[fillThreadID].m_causticHeight = m_causticHeight; - - m_wvParams[fillThreadID].m_center = m_center; - m_wvParams[fillThreadID].m_WSBBox = m_WSBBox; - - // if above water render fog together with water surface - bool isFastpath = GetCVars()->e_WaterVolumes == 2 && (distToWaterVolumeSurface > 0.5f || insideWaterVolume); - m_pSurfaceRE[fillThreadID]->m_drawFastPath = isFastpath; - - // submit volume - if (GetCVars()->e_Fog) - { - if ((insideWaterVolume || (!isFastpath && aboveWaterVolumeSurface)) && m_pVolumeRE[fillThreadID]) - { - // fill in data for render object - if (!IsAttachedToEntity()) - { - pROVol->m_II.m_Matrix.SetIdentity(); - } - else - { - pROVol->m_II.m_Matrix = m_parentEntityWorldTM; - } - pROVol->m_fSort = 0; - - // get shader item - SShaderItem& shaderItem(m_wvParams[fillThreadID].m_viewerInsideVolume ? m_pWaterBodyOutofMat->GetShaderItem(0) : m_pWaterBodyIntoMat->GetShaderItem(0)); - - // add to renderer - GetRenderer()->EF_AddEf(m_pVolumeRE[fillThreadID], shaderItem, pROVol, passInfo, EFSLIST_WATER_VOLUMES, aboveWaterVolumeSurface ? 0 : 1, rendItemSorter); - } - } - - // submit surface - { - // fill in data for render object - if (!IsAttachedToEntity()) - { - pROSurf->m_II.m_Matrix.SetIdentity(); - } - else - { - pROSurf->m_II.m_Matrix = m_parentEntityWorldTM; - } - pROSurf->m_fSort = 0; - pROSurf->m_nTextureID = rParam.nTextureID; - - // get shader item - SShaderItem& shaderItem(m_pMaterial->GetShaderItem(0)); - - // add to renderer - // Render water refractive surface between beforeWater / afterWater objects. - GetRenderer()->EF_AddEf(m_pSurfaceRE[fillThreadID], shaderItem, pROSurf, passInfo, EFSLIST_REFRACTIVE_SURFACE, 0, rendItemSorter); - } -} - - -void CWaterVolumeRenderNode::SetMaterial(_smart_ptr pMat) -{ - m_pMaterial = pMat; -} - - -void CWaterVolumeRenderNode::GetMemoryUsage(ICrySizer* pSizer) const -{ - SIZER_COMPONENT_NAME(pSizer, "WaterVolumeNode"); - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pSerParams); - pSizer->AddObject(m_pPhysAreaInput); - pSizer->AddObject(m_waterSurfaceVertices); - pSizer->AddObject(m_waterSurfaceIndices); -} - - -void CWaterVolumeRenderNode::Precache() -{ -} - - -IPhysicalEntity* CWaterVolumeRenderNode::GetPhysics() const -{ - return m_pPhysArea; -} - - -void CWaterVolumeRenderNode::SetPhysics(IPhysicalEntity* pPhysArea) -{ - m_pPhysArea = pPhysArea; -} - - -void CWaterVolumeRenderNode::CheckPhysicalized() -{ - if (!GetPhysics()) - { - Physicalize(); - } -} - - -void CWaterVolumeRenderNode::Physicalize([[maybe_unused]] bool bInstant) -{ - if (IsAttachedToEntity()) - { - return; - } - - Dephysicalize(); - - // setup physical area -} - - -void CWaterVolumeRenderNode::Dephysicalize([[maybe_unused]] bool bKeepIfReferenced) -{ - if (m_pPhysArea) - { - m_pPhysArea = 0; - m_attachedToEntity = false; - } -} - - -float CWaterVolumeRenderNode::GetCameraDistToWaterVolumeSurface(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPos(cam.GetPosition()); - return m_fogPlane.DistFromPlane(camPos); -} - - -float CWaterVolumeRenderNode::GetCameraDistSqToWaterVolumeAABB(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPos(cam.GetPosition()); - return m_WSBBox.GetDistanceSqr(camPos); -} - - -bool CWaterVolumeRenderNode::IsCameraInsideWaterVolumeSurface2D(const SRenderingPassInfo& passInfo) const -{ - const CCamera& cam(passInfo.GetCamera()); - Vec3 camPos(cam.GetPosition()); - - pe_status_area sa; - sa.bUniformOnly = true; - MARK_UNUSED sa.ctr; - if (m_pPhysArea && m_pPhysArea->GetStatus(&sa) && sa.pSurface) - { - pe_status_contains_point scp; - scp.pt = camPos; - return m_pPhysArea->GetStatus(&scp) != 0; - } - - WaterVolumeRenderNodeUtils::VertexAccess ca(&m_waterSurfaceVertices[0], m_waterSurfaceVertices.size()); - for (size_t i(0); i < m_waterSurfaceIndices.size(); i += 3) - { - const Vec3 v0 = m_parentEntityWorldTM.TransformPoint(ca[ m_waterSurfaceIndices[i] ]); - const Vec3 v1 = m_parentEntityWorldTM.TransformPoint(ca[ m_waterSurfaceIndices[i + 1] ]); - const Vec3 v2 = m_parentEntityWorldTM.TransformPoint(ca[ m_waterSurfaceIndices[i + 2] ]); - - if (WaterVolumeRenderNodeUtils::InsideTriangle(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y, camPos.x, camPos.y)) - { - return true; - } - } - - return false; -} - - -void CWaterVolumeRenderNode::UpdateBoundingBox() -{ - m_WSBBox.Reset(); - for (size_t i(0); i < m_waterSurfaceVertices.size(); ++i) - { - m_WSBBox.Add(m_parentEntityWorldTM.TransformPoint(m_waterSurfaceVertices[i].xyz)); - } - - if (IVisArea* pArea = Get3DEngine()->GetVisAreaFromPos(m_WSBBox.GetCenter())) - { - if (m_WSBBox.min.z > pArea->GetAABBox()->min.z) - { - m_WSBBox.min.z = pArea->GetAABBox()->min.z; - } - return; - } - - m_WSBBox.min.z -= m_volumeDepth; - m_center = m_WSBBox.GetCenter(); -} - - -const SWaterVolumeSerialize* CWaterVolumeRenderNode::GetSerializationParams() -{ - if (!m_pSerParams) - { - return 0; - } - - // before returning, copy non-volatile serialization params - m_pSerParams->m_volumeType = m_volumeType; - m_pSerParams->m_volumeID = m_volumeID; - - m_pSerParams->m_pMaterial = m_pMaterial; - - m_pSerParams->m_fogDensity = m_fogDensity; - m_pSerParams->m_fogColor = m_fogColor; - m_pSerParams->m_fogColorAffectedBySun = m_fogColorAffectedBySun; - m_pSerParams->m_fogPlane = m_fogPlane; - m_pSerParams->m_fogShadowing = m_fogShadowing; - - m_pSerParams->m_volumeDepth = m_volumeDepth; - m_pSerParams->m_streamSpeed = m_streamSpeed; - m_pSerParams->m_capFogAtVolumeDepth = m_capFogAtVolumeDepth; - - m_pSerParams->m_caustics = m_caustics; - m_pSerParams->m_causticIntensity = m_causticIntensity; - m_pSerParams->m_causticTiling = m_causticTiling; - m_pSerParams->m_causticHeight = m_causticHeight; - - return m_pSerParams; -} - - -void CWaterVolumeRenderNode::CopyVolatilePhysicsAreaContourSerParams(const Vec3* pVertices, unsigned int numVertices) -{ - if (!m_pSerParams) - { - m_pSerParams = new SWaterVolumeSerialize; - } - - m_pSerParams->m_physicsAreaContour.resize(numVertices); - for (unsigned int i(0); i < numVertices; ++i) - { - m_pSerParams->m_physicsAreaContour[i] = pVertices[i]; - } -} - - -void CWaterVolumeRenderNode::CopyVolatileRiverSerParams(const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale) -{ - if (!m_pSerParams) - { - m_pSerParams = new SWaterVolumeSerialize; - } - - m_pSerParams->m_uTexCoordBegin = uTexCoordBegin; - m_pSerParams->m_uTexCoordEnd = uTexCoordEnd; - - m_pSerParams->m_surfUScale = surfUVScale.x; - m_pSerParams->m_surfVScale = surfUVScale.y; - - m_pSerParams->m_vertices.resize(numVertices); - for (uint32 i(0); i < numVertices; ++i) - { - m_pSerParams->m_vertices[i] = pVertices[i]; - } -} - - -void CWaterVolumeRenderNode::CopyVolatileAreaSerParams(const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale) -{ - if (!m_pSerParams) - { - m_pSerParams = new SWaterVolumeSerialize; - } - - m_pSerParams->m_uTexCoordBegin = 1.0f; - m_pSerParams->m_uTexCoordEnd = 1.0f; - - m_pSerParams->m_surfUScale = surfUVScale.x; - m_pSerParams->m_surfVScale = surfUVScale.y; - - m_pSerParams->m_vertices.resize(numVertices); - for (uint32 i(0); i < numVertices; ++i) - { - m_pSerParams->m_vertices[i] = pVertices[i]; - } -} - - -int OnWaterUpdate(const EventPhysAreaChange* pEvent) -{ - if (pEvent->iForeignData == PHYS_FOREIGN_ID_WATERVOLUME) - { - CWaterVolumeRenderNode* pWVRN = static_cast(pEvent->pForeignData); - pe_status_area sa; - sa.bUniformOnly = true; - MARK_UNUSED sa.ctr; - // Calling GetPhysArea() instead of GetPhysics() to avoid a crash of using bad memory. Refer to [LY-103758] for details on the crash - if (pWVRN->GetPhysArea() != pEvent->pEntity || !pEvent->pEntity->GetStatus(&sa)) - { - return 1; - } - if (pEvent->pContainer) - { - pWVRN->SetAreaAttachedToEntity(); - pWVRN->SetMatrix(Matrix34(Vec3(1), pEvent->qContainer, pEvent->posContainer)); - } - pWVRN->SyncToPhysMesh(QuatT(pEvent->q, pEvent->pos), sa.pSurface, pEvent->depth); - } - return 1; -} - - -void CWaterVolumeRenderNode::SyncToPhysMesh(const QuatT& qtSurface, IGeometry* pSurface, float depth) -{ - mesh_data* pmd; - if (!pSurface || pSurface->GetType() != GEOM_TRIMESH) - { - return; - } - pmd = (mesh_data*)pSurface->GetData(); - if (!pmd) - { - return; - } - bool bResized = m_waterSurfaceVertices.size() != pmd->nVertices; - if (bResized) - { - m_waterSurfaceVertices.resize(pmd->nVertices); - } - Vec2 uvScale = m_pSerParams ? Vec2(m_pSerParams->m_surfUScale, m_pSerParams->m_surfVScale) : Vec2(1.0f, 1.0f); - for (int i = 0; i < pmd->nVertices; i++) - { - m_waterSurfaceVertices[i].xyz = qtSurface * pmd->pVertices[i]; - m_waterSurfaceVertices[i].st = Vec2(pmd->pVertices[i].x * uvScale.x, pmd->pVertices[i].y * uvScale.y); - } - if (m_waterSurfaceIndices.size() != pmd->nTris * 3) - { - m_waterSurfaceIndices.resize(pmd->nTris * 3), bResized = true; - } - for (int i = 0; i < pmd->nTris * 3; i++) - { - m_waterSurfaceIndices[i] = pmd->pIndices[i]; - } - - if (bResized) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_wvParams[i].m_pVertices = &m_waterSurfaceVertices[0]; - m_wvParams[i].m_numVertices = m_waterSurfaceVertices.size(); - m_wvParams[i].m_pIndices = &m_waterSurfaceIndices[0]; - m_wvParams[i].m_numIndices = m_waterSurfaceIndices.size(); - } - } - - m_fogPlane.SetPlane(qtSurface.q * Vec3(0, 0, 1), qtSurface.t); - m_volumeDepth = depth; - UpdateBoundingBox(); -} - -void CWaterVolumeRenderNode::OffsetPosition(const Vec3& delta) -{ - if (m_pRNTmpData) - { - m_pRNTmpData->OffsetPosition(delta); - } - m_vOffset += delta; - m_center += delta; - m_WSBBox.Move(delta); - for (int i = 0; i < (int)m_waterSurfaceVertices.size(); ++i) - { - m_waterSurfaceVertices[i].xyz += delta; - } - - if (m_pPhysAreaInput) - { - for (std::vector::iterator it = m_pPhysAreaInput->m_contour.begin(); it != m_pPhysAreaInput->m_contour.end(); ++it) - { - *it += delta; - } - for (std::vector::iterator it = m_pPhysAreaInput->m_flowContour.begin(); it != m_pPhysAreaInput->m_flowContour.end(); ++it) - { - *it += delta; - } - } - - if (m_pPhysArea) - { - pe_params_pos par_pos; - m_pPhysArea->GetParams(&par_pos); - par_pos.bRecalcBounds |= 2; - par_pos.pos = m_vOffset; - m_pPhysArea->SetParams(&par_pos); - } -} - - diff --git a/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.h b/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.h deleted file mode 100644 index 1805a8647d..0000000000 --- a/Code/CryEngine/Cry3DEngine/WaterVolumeRenderNode.h +++ /dev/null @@ -1,262 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_WATERVOLUMERENDERNODE_H -#define CRYINCLUDE_CRY3DENGINE_WATERVOLUMERENDERNODE_H -#pragma once - - -#include "VertexFormats.h" - - -namespace AZ -{ - class Vector2; - class Plane; -} - -struct SWaterVolumeSerialize -{ - // volume type and id - int32 m_volumeType; - uint64 m_volumeID; - - // material - _smart_ptr m_pMaterial; - - // fog properties - f32 m_fogDensity; - Vec3 m_fogColor; - bool m_fogColorAffectedBySun; - Plane m_fogPlane; - f32 m_fogShadowing; - - f32 m_volumeDepth; - f32 m_streamSpeed; - bool m_capFogAtVolumeDepth; - - // caustic properties - bool m_caustics; - f32 m_causticIntensity; - f32 m_causticTiling; - f32 m_causticHeight; - - // render geometry - f32 m_uTexCoordBegin; - f32 m_uTexCoordEnd; - f32 m_surfUScale; - f32 m_surfVScale; - typedef std::vector< Vec3 > VertexArraySerialize; - VertexArraySerialize m_vertices; - - // physics properties - typedef std::vector< Vec3 > PhysicsAreaContourSerialize; - PhysicsAreaContourSerialize m_physicsAreaContour; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_vertices); - pSizer->AddObject(m_physicsAreaContour); - } -}; - -struct SWaterVolumePhysAreaInput -{ - typedef std::vector< Vec3 > PhysicsVertices; - typedef std::vector< int > PhysicsIndices; - - PhysicsVertices m_contour; - PhysicsVertices m_flowContour; - PhysicsIndices m_indices; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_contour); - pSizer->AddObject(m_flowContour); - pSizer->AddObject(m_indices); - } -}; - -class CWaterVolumeRenderNode - : public IWaterVolumeRenderNode - , public Cry3DEngineBase -{ -public: - // implements IWaterVolumeRenderNode - virtual void SetAreaAttachedToEntity(); - - virtual void SetFogDensity(float fogDensity); - virtual float GetFogDensity() const; - virtual void SetFogColor(const Vec3& fogColor); - virtual void SetFogColorAffectedBySun(bool enable); - virtual void SetFogShadowing(float fogShadowing); - - virtual void SetCapFogAtVolumeDepth(bool capFog); - virtual void SetVolumeDepth(float volumeDepth); - virtual void SetStreamSpeed(float streamSpeed); - - virtual void SetCaustics(bool caustics); - virtual void SetCausticIntensity(float causticIntensity); - virtual void SetCausticTiling(float causticTiling); - virtual void SetCausticHeight(float causticHeight); - virtual void SetAuxPhysParams(pe_params_area* pa) - { - m_auxPhysParams = *pa; - if (m_pPhysArea) - { - m_pPhysArea->SetParams(pa); - } - } - - virtual void CreateOcean(uint64 volumeID, /* TBD */ bool keepSerializationParams = false); - virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = GetDefSID()); - virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = GetDefSID()); - virtual void CreateRiver(uint64 volumeID, const AZStd::vector& verticies, const AZ::Transform& transform, float uTexCoordBegin, float uTexCoordEnd, const AZ::Vector2& surfUVScale, const AZ::Plane& fogPlane, bool keepSerializationParams, int nSID); - - virtual void SetAreaPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams = false); - virtual void SetRiverPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams = false); - virtual void SetRiverPhysicsArea(const AZStd::vector& verticies, const AZ::Transform& transform, bool keepSerializationParams = false); - - void SyncToPhysMesh(const QuatT& qtSurface, IGeometry* pSurface, float depth); - - // implements IRenderNode - virtual EERType GetRenderNodeType(); - virtual const char* GetEntityClassName() const; - virtual const char* GetName() const; - virtual void SetMatrix(const Matrix34& mat); - virtual Vec3 GetPos(bool bWorldOnly = true) const; - virtual void Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo); - virtual void SetMaterial(_smart_ptr pMat); - virtual _smart_ptr GetMaterial(Vec3* pHitPos); - virtual _smart_ptr GetMaterialOverride() { return m_pMaterial; } - virtual float GetMaxViewDist(); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual void Precache(); - - virtual IPhysicalEntity* GetPhysics() const; - virtual void SetPhysics(IPhysicalEntity*); - inline IPhysicalEntity* GetPhysArea() const { return m_pPhysArea; } - - virtual void CheckPhysicalized(); - virtual void Physicalize(bool bInstant = false); - virtual void Dephysicalize(bool bKeepIfReferenced = false); - - virtual const AABB GetBBox() const - { - AABB WSBBox = m_WSBBox; - // Expand bounding box upwards while using caustics to avoid clipping the caustics when the volume goes out of view. - if (m_caustics) - { - WSBBox.max.z += m_causticHeight; - } - return WSBBox; - } - - virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; } - virtual void FillBBox(AABB& aabb); - virtual void OffsetPosition(const Vec3& delta); - - virtual void SetLayerId(uint16 nLayerId) { m_nLayerId = nLayerId; } - virtual uint16 GetLayerId() { return m_nLayerId; } - - void Render_JobEntry(const SRendParams& rParam, const SRenderingPassInfo& passInfo, SRendItemSorter rendItemSorter); - - void Transform(const Vec3& localOrigin, const Matrix34& l2w); - virtual IRenderNode* Clone() const; - -public: - CWaterVolumeRenderNode(); - const SWaterVolumeSerialize* GetSerializationParams(); - float* GetAuxSerializationDataPtr(int& count) - { - // TODO: 'pe_params_area' members between 'volume' and 'growthReserve' are not float only - a member (bConvexBorder) has int type, this should be investigated. - AZ_PUSH_DISABLE_WARNING(,"-Winvalid-offsetof") - count = (offsetof(pe_params_area, growthReserve) - offsetof(pe_params_area, volume)) / sizeof(float) + 1; - AZ_POP_DISABLE_WARNING - return &m_auxPhysParams.volume; - } - -private: - typedef std::vector< SVF_P3F_C4B_T2F > WaterSurfaceVertices; - typedef std::vector< uint16 > WaterSurfaceIndices; - -private: - ~CWaterVolumeRenderNode(); - - float GetCameraDistToWaterVolumeSurface(const SRenderingPassInfo& passInfo) const; - float GetCameraDistSqToWaterVolumeAABB(const SRenderingPassInfo& passInfo) const; - bool IsCameraInsideWaterVolumeSurface2D(const SRenderingPassInfo& passInfo) const; - - void UpdateBoundingBox(); - - void CopyVolatilePhysicsAreaContourSerParams(const Vec3* pVertices, unsigned int numVertices); - void CopyVolatileRiverSerParams(const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale); - - void CopyVolatileAreaSerParams(const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale); - - bool IsAttachedToEntity() const { return m_attachedToEntity; } - - -private: - IWaterVolumeRenderNode::EWaterVolumeType m_volumeType; - uint64 m_volumeID; - - float m_volumeDepth; - float m_streamSpeed; - - CREWaterVolume::SParams m_wvParams[RT_COMMAND_BUF_COUNT]; - - _smart_ptr< IMaterial > m_pMaterial; - _smart_ptr< IMaterial > m_pWaterBodyIntoMat; - _smart_ptr< IMaterial > m_pWaterBodyOutofMat; - - CREWaterVolume* m_pVolumeRE[RT_COMMAND_BUF_COUNT]; - CREWaterVolume* m_pSurfaceRE[RT_COMMAND_BUF_COUNT]; - SWaterVolumeSerialize* m_pSerParams; - - SWaterVolumePhysAreaInput* m_pPhysAreaInput; - IPhysicalEntity* m_pPhysArea; - - WaterSurfaceVertices m_waterSurfaceVertices; - WaterSurfaceIndices m_waterSurfaceIndices; - - Matrix34 m_parentEntityWorldTM; - uint16 m_nLayerId; - - float m_fogDensity; - Vec3 m_fogColor; - bool m_fogColorAffectedBySun; - float m_fogShadowing; - - Plane m_fogPlane; - Plane m_fogPlaneBase; - - Vec3 m_vOffset; - Vec3 m_center; - AABB m_WSBBox; - - bool m_capFogAtVolumeDepth; - bool m_attachedToEntity; - bool m_caustics; - - float m_causticIntensity; - float m_causticTiling; - float m_causticShadow; - float m_causticHeight; - pe_params_area m_auxPhysParams; -}; - - -#endif // CRYINCLUDE_CRY3DENGINE_WATERVOLUMERENDERNODE_H diff --git a/Code/CryEngine/Cry3DEngine/cbuffer.cpp b/Code/CryEngine/Cry3DEngine/cbuffer.cpp deleted file mode 100644 index 57120e0502..0000000000 --- a/Code/CryEngine/Cry3DEngine/cbuffer.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Occlusion (coverage) buffer - -#include "Cry3DEngine_precompiled.h" -#include "cbuffer.h" -#include "StatObj.h" - -class CCoverageBuffer - : public Cry3DEngineBase -{ -public: - // can be used by other classes - static void ClipPolygon(PodArray& PolygonOut, const PodArray& pPolygon, const Plane& ClipPlane); - static void ClipPolygon(PodArray* pPolygon, const Plane& ClipPlane); - static void MatMul4(float* product, const float* a, const float* b); - static void TransformPoint(float out[4], const float m[16], const float in[4]); - -protected: - - static int ClipEdge(const Vec3& v1, const Vec3& v2, const Plane& ClipPlane, Vec3& vRes1, Vec3& vRes2); - -#if defined(WIN32) && defined(_CPU_X86) - inline int fastfround(float f) // note: only positive numbers works correct - { - int i; - __asm fld[f] - __asm fistp[i] - return i; - } -#else - inline int fastfround(float f) { int i; i = (int)(f + 0.5f); return i; } // note: only positive numbers works correct -#endif -}; - -void CCoverageBuffer::TransformPoint(float out[4], const float m[16], const float in[4]) -{ -#define M(row, col) m[col * 4 + row] - out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; - out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; - out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; - out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; -#undef M -} - -void CCoverageBuffer::MatMul4(float* product, const float* a, const float* b) -{ -#define A(row, col) a[(col << 2) + row] -#define B(row, col) b[(col << 2) + row] -#define P(row, col) product[(col << 2) + row] - int i; - for (i = 0; i < 4; i++) - { - float ai0 = A(i, 0), ai1 = A(i, 1), ai2 = A(i, 2), ai3 = A(i, 3); - P(i, 0) = ai0 * B(0, 0) + ai1 * B(1, 0) + ai2 * B(2, 0) + ai3 * B(3, 0); - P(i, 1) = ai0 * B(0, 1) + ai1 * B(1, 1) + ai2 * B(2, 1) + ai3 * B(3, 1); - P(i, 2) = ai0 * B(0, 2) + ai1 * B(1, 2) + ai2 * B(2, 2) + ai3 * B(3, 2); - P(i, 3) = ai0 * B(0, 3) + ai1 * B(1, 3) + ai2 * B(2, 3) + ai3 * B(3, 3); - } -#undef A -#undef B -#undef P -} - -// return number of vertices to add -int CCoverageBuffer::ClipEdge(const Vec3& v1, const Vec3& v2, const Plane& ClipPlane, Vec3& vRes1, Vec3& vRes2) -{ - float d1 = -ClipPlane.DistFromPlane(v1); - float d2 = -ClipPlane.DistFromPlane(v2); - if (d1 < 0 && d2 < 0) - { - return 0; // all clipped = do not add any vertices - } - if (d1 >= 0 && d2 >= 0) - { - vRes1 = v2; - return 1; // both not clipped - add second vertex - } - - // calculate new vertex - Vec3 vIntersectionPoint = v1 + (v2 - v1) * (Ffabs(d1) / (Ffabs(d2) + Ffabs(d1))); - -#ifdef _DEBUG - float fNewDist = -ClipPlane.DistFromPlane(vIntersectionPoint); - assert(Ffabs(fNewDist) < 0.01f); -#endif - - if (d1 >= 0 && d2 < 0) - { // from vis to no vis - vRes1 = vIntersectionPoint; - return 1; - } - else if (d1 < 0 && d2 >= 0) - { // from not vis to vis - vRes1 = vIntersectionPoint; - vRes2 = v2; - return 2; - } - - assert(0); - return 0; -} - -void CCoverageBuffer::ClipPolygon(PodArray& PolygonOut, const PodArray& pPolygon, const Plane& ClipPlane) -{ - PolygonOut.Clear(); - // clip edges, make list of new vertices - for (int i = 0; i < pPolygon.Count(); i++) - { - Vec3 vNewVert1(0, 0, 0), vNewVert2(0, 0, 0); - if (int nNewVertNum = ClipEdge(pPolygon.GetAt(i), pPolygon.GetAt((i + 1) % pPolygon.Count()), ClipPlane, vNewVert1, vNewVert2)) - { - PolygonOut.Add(vNewVert1); - if (nNewVertNum > 1) - { - PolygonOut.Add(vNewVert2); - } - } - } - - // check result -#if !defined(NDEBUG) - for (int i = 0; i < PolygonOut.Count(); i++) - { - float d1 = -ClipPlane.DistFromPlane(PolygonOut.GetAt(i)); - assert(d1 >= -0.01f); - } -#endif - - assert(PolygonOut.Count() == 0 || PolygonOut.Count() >= 3); -} - -void CCoverageBuffer::ClipPolygon(PodArray* pPolygon, const Plane& ClipPlane) -{ - static PodArray PolygonOut; // Keep this list static to not perform reallocation every time. - PolygonOut.Clear(); - ClipPolygon(*pPolygon, PolygonOut, ClipPlane); - pPolygon->Clear(); - pPolygon->AddList(PolygonOut); -} - -bool IsABBBVisibleInFrontOfPlane_FAST(const AABB& objBox, const SPlaneObject& clipPlane) -{ - const f32* p = &objBox.min.x; - if ((clipPlane.plane | Vec3(p[clipPlane.vIdx2.x], p[clipPlane.vIdx2.y], p[clipPlane.vIdx2.z])) > 0) - { - return true; - } - - return false; -} - -CPolygonClipContext::CPolygonClipContext() -{ -} - -void CPolygonClipContext::Reset() -{ - stl::free_container(m_lstPolygonA); - stl::free_container(m_lstPolygonB); -} - -const PodArray& CPolygonClipContext::Clip(const PodArray& poly, const Plane* planes, size_t numPlanes) -{ - m_lstPolygonA.Clear(); - m_lstPolygonB.Clear(); - - m_lstPolygonA.AddList(poly); - - PodArray* src = &m_lstPolygonA, * dst = &m_lstPolygonB; - - for (size_t i = 0; i < numPlanes && src->Count() >= 3; std::swap(src, dst), i++) - { - CCoverageBuffer::ClipPolygon(*dst, *src, planes[i]); - } - - return *src; -} - -const PodArray& CPolygonClipContext::Clip(const Vec3& a, const Vec3& b, const Vec3& c, const Plane* planes, size_t numPlanes) -{ - m_lstPolygonA.Clear(); - m_lstPolygonB.Clear(); - - m_lstPolygonA.Add(a); - m_lstPolygonA.Add(b); - m_lstPolygonA.Add(c); - - PodArray* src = &m_lstPolygonA, * dst = &m_lstPolygonB; - - for (size_t i = 0; i < numPlanes && src->Count() >= 3; std::swap(src, dst), i++) - { - CCoverageBuffer::ClipPolygon(*dst, *src, planes[i]); - } - - return *src; -} - -void CPolygonClipContext::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_lstPolygonA); - pSizer->AddObject(m_lstPolygonB); -} diff --git a/Code/CryEngine/Cry3DEngine/cbuffer.h b/Code/CryEngine/Cry3DEngine/cbuffer.h deleted file mode 100644 index 8ac5021acc..0000000000 --- a/Code/CryEngine/Cry3DEngine/cbuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRY3DENGINE_CBUFFER_H -#define CRYINCLUDE_CRY3DENGINE_CBUFFER_H -#pragma once - -#include - -#define Point2d Vec3 - -struct SPlaneObject -{ - Plane plane; - Vec3_tpl vIdx1, vIdx2; - - void Update() - { - //avoid breaking strict aliasing rules - union f32_u - { - float floatVal; - uint32 uintVal; - }; - f32_u ux; - ux.floatVal = plane.n.x; - f32_u uy; - uy.floatVal = plane.n.y; - f32_u uz; - uz.floatVal = plane.n.z; - uint32 bitX = ux.uintVal >> 31; - uint32 bitY = uy.uintVal >> 31; - uint32 bitZ = uz.uintVal >> 31; - vIdx1.x = aznumeric_caster(bitX * 3 + 0); - vIdx2.x = aznumeric_caster((1 - bitX) * 3 + 0); - vIdx1.y = aznumeric_caster(bitY * 3 + 1); - vIdx2.y = aznumeric_caster((1 - bitY) * 3 + 1); - vIdx1.z = aznumeric_caster(bitZ * 3 + 2); - vIdx2.z = aznumeric_caster((1 - bitZ) * 3 + 2); - } -}; - -class CPolygonClipContext -{ -public: - CPolygonClipContext(); - - void Reset(); - - const PodArray& Clip(const PodArray& poly, const Plane* planes, size_t numPlanes); - const PodArray& Clip(const Vec3& a, const Vec3& b, const Vec3& c, const Plane* planes, size_t numPlanes); - - void GetMemoryUsage(ICrySizer* pSizer) const; - -private: - PodArray m_lstPolygonA; - PodArray m_lstPolygonB; -}; - -#endif // CRYINCLUDE_CRY3DENGINE_CBUFFER_H diff --git a/Code/CryEngine/Cry3DEngine/cry3dengine_files.cmake b/Code/CryEngine/Cry3DEngine/cry3dengine_files.cmake deleted file mode 100644 index 095d1f9d51..0000000000 --- a/Code/CryEngine/Cry3DEngine/cry3dengine_files.cmake +++ /dev/null @@ -1,151 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Cry3DEngine_precompiled.cpp - Cry3DEngineTraits.h - 3dEngineLoad.cpp - VolumeObjectDataCreate.cpp - VolumeObjectRenderNode.cpp - VolumeObjectDataCreate.h - VolumeObjectRenderNode.h - Ocean.cpp - WaterVolumeRenderNode.cpp - Ocean.h - WaterVolumeRenderNode.h - Environment/OceanEnvironmentBus.h - StatObjPhys.cpp - StatObjRend.cpp - StatObjStream.cpp - IndexedMesh.cpp - StatObjConstr.cpp - StatObjLoad.cpp - StatObj_Jobs.cpp - IndexedMesh.h - StatObj.h - ObjMan.cpp - ObjManDraw.cpp - ObjManDrawEntity.cpp - ObjManShadows.cpp - ObjManStreaming.cpp - ObjMan.h - ObjectsTree.cpp - ObjectsTree_MT.cpp - ObjectsTree_Jobs.cpp - ObjectsTree_Serialize.cpp - ObjectsTree.h - ObjectsTree_Serialize_info.h - cbuffer.h - cbuffer.cpp - CCullRenderer.cpp - CCullRenderer.h - CCullThread.cpp - CCullThread.h - CullBuffer.cpp - CullBuffer.h - CZBufferCuller.cpp - CZBufferCuller.h - VMath.hpp - VMath_C.hpp - VMath_NEON.hpp - VMath_Prototypes.hpp - VMath_SSE.hpp - LightEntity.cpp - LightEntity.h - Material_Jobs.cpp - MaterialHelpers.cpp - MaterialHelpers.h - Material.cpp - Material.h - MatMan.cpp - MatMan.h - SurfaceTypeManager.cpp - SurfaceTypeManager.h - PostProcessEffects.cpp - RenderMeshMerger.cpp - RenderMeshUtils.cpp - RenderMeshMerger.h - RenderMeshUtils.h - SkyLightManager.cpp - SkyLightNishita.cpp - TimeOfDay.cpp - SkyLightManager.h - SkyLightNishita.h - SkyLightNishita_info.h - TimeOfDay.h - EnvironmentPreset.h - EnvironmentPreset.cpp - ShadowCache.cpp - ShadowCache.h - PostEffectGroup.cpp - PostEffectGroup.h - VisAreaMan.cpp - VisAreaCompile.cpp - VisAreas.cpp - VisAreaManCompile.cpp - VisArea_Jobs.cpp - BasicArea.cpp - BasicArea.h - VisAreaCompile_info.h - VisAreas.h - GeomCachePredictors.h - DeferredCollisionEvent.cpp - 3DEngineMemory.cpp - 3DEngineMemory.h - Cry3DEngineBase.cpp - Cry3DEngineBase.h - DeferredCollisionEvent.h - resource.h - Cry3DEngine_precompiled.h - 3dEngine.cpp - 3dEngine.h - 3dEngineOctreeCompile.cpp - 3DEngine_Jobs.cpp - 3DEngineLight.cpp - 3DEngineRender.cpp - ClipVolume.cpp - ClipVolume.h - ClipVolumeManager.cpp - ClipVolumeManager.h - cvars.cpp - cvars.h - CloudRenderNode.cpp - CloudsManager.cpp - DistanceCloudRenderNode.cpp - CloudRenderNode.h - CloudsManager.h - Cry_LegacyPhysUtils.h - DistanceCloudRenderNode.h - Decal.cpp - DecalManager.cpp - DecalRenderNode.cpp - DecalManager.h - DecalRenderNode.h - FogVolumeRenderNode.cpp - FogVolumeRenderNode_Jobs.cpp - FogVolumeRenderNode.h - PrismRenderNode.cpp - PrismRenderNode.h - OpticsManager.cpp - OpticsManager.h - GeomCache.cpp - GeomCache.h - GeomCacheRenderNode.cpp - GeomCacheRenderNode.h - GeomCacheManager.cpp - GeomCacheManager.h - GeomCacheDecoder.cpp - GeomCacheDecoder.h - GeomCacheMeshManager.h - GeomCacheMeshManager.cpp - Cry_LegacyPhysUtils.h - Cry_LegacyPhysUtils.cpp -) diff --git a/Code/CryEngine/Cry3DEngine/cry3dengine_shared_files.cmake b/Code/CryEngine/Cry3DEngine/cry3dengine_shared_files.cmake deleted file mode 100644 index 777660a52a..0000000000 --- a/Code/CryEngine/Cry3DEngine/cry3dengine_shared_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Cry3DEngine.cpp -) diff --git a/Code/CryEngine/Cry3DEngine/cry3dengine_test_files.cmake b/Code/CryEngine/Cry3DEngine/cry3dengine_test_files.cmake deleted file mode 100644 index 76c7f272da..0000000000 --- a/Code/CryEngine/Cry3DEngine/cry3dengine_test_files.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - RenderMeshUtils/Tests/Test_RenderMeshUtils.cpp - Tests/Test_Cry3DEngine.cpp - Tests/MockValidationTest.cpp - Tests/MaterialTests.cpp - Tests/OctreeTest.cpp - Cry3DEngine.cpp -) diff --git a/Code/CryEngine/Cry3DEngine/cvars.cpp b/Code/CryEngine/Cry3DEngine/cvars.cpp deleted file mode 100644 index e63c539a85..0000000000 --- a/Code/CryEngine/Cry3DEngine/cvars.cpp +++ /dev/null @@ -1,955 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : console variables used in 3dengine - -#include "Cry3DEngine_precompiled.h" - -#include "3dEngine.h" -#include "IRenderer.h" -#include "IStatObj.h" // MAX_STATOBJ_LODS_NUM -#include "ITimeOfDay.h" - -#include "Environment/OceanEnvironmentBus.h" - -////////////////////////////////////////////////////////////////////////// -void OnTimeOfDayVarChange([[maybe_unused]] ICVar* pArgs) -{ - gEnv->p3DEngine->GetTimeOfDay()->SetTime(Cry3DEngineBase::GetCVars()->e_TimeOfDay); -} - -void OnTimeOfDaySpeedVarChange([[maybe_unused]] ICVar* pArgs) -{ - ITimeOfDay::SAdvancedInfo advInfo; - gEnv->p3DEngine->GetTimeOfDay()->GetAdvancedInfo(advInfo); - advInfo.fAnimSpeed = Cry3DEngineBase::GetCVars()->e_TimeOfDaySpeed; - gEnv->p3DEngine->GetTimeOfDay()->SetAdvancedInfo(advInfo); -} - -void OnCGFStreamingChange([[maybe_unused]] ICVar* pArgs) -{ - if (gEnv->IsEditor()) - { - Cry3DEngineBase::GetCVars()->e_StreamCgf = 0; - } -} - -void OnGsmLodsNumChange(ICVar* pArgs) -{ - Cry3DEngineBase::GetRenderer()->UpdateCachedShadowsLodCount(pArgs->GetIVal()); -} - -void OnDynamicDistanceShadowsVarChange([[maybe_unused]] ICVar* pArgs) -{ - Cry3DEngineBase::Get3DEngine()->SetRecomputeCachedShadows(ShadowMapFrustum::ShadowCacheData::eFullUpdate); -} - -void OnVolumetricFogChanged(ICVar* pArgs) -{ - const ICVar* deferredShadingCVar = gEnv->pConsole->GetCVar("r_DeferredShadingTiled"); - if (deferredShadingCVar->GetIVal() == 0 && pArgs->GetIVal() != 0) - { - gEnv->pLog->LogWarning("e_VolumetricFog is set to 0 when r_DeferredShadingTiled is 0."); - Cry3DEngineBase::GetCVars()->e_VolumetricFog = 0; - } -} - -#if !defined(_RELEASE) -void OnTerrainPerformanceSecondsChanged([[maybe_unused]] ICVar* pArgs) -{ -#ifdef LY_TERRAIN_LEGACY_RUNTIME - AZ::Debug::TerrainProfiler::RefreshFrameProfilerStatus(); -#endif -} -#endif - -void OnDebugDrawChange(ICVar* pArgs) -{ - static bool collectingDrawCalls = false; - - int e_debugDraw = pArgs->GetIVal(); - if (e_debugDraw >= 24 && e_debugDraw <= 25) - { - gEnv->pRenderer->CollectDrawCallsInfo(true); - gEnv->pRenderer->CollectDrawCallsInfoPerNode(true); - collectingDrawCalls = true; - } - else if (collectingDrawCalls) - { - gEnv->pRenderer->CollectDrawCallsInfo(false); - gEnv->pRenderer->CollectDrawCallsInfoPerNode(false); - collectingDrawCalls = false; - } -} - -void CVars::Init() -{ - DefineConstIntCVar(e_Fog, 1, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Activates global height/distance based fog"); - DefineConstIntCVar(e_FogVolumes, 1, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Activates local height/distance based fog volumes"); - REGISTER_CVAR_CB(e_VolumetricFog, 0, VF_NULL, - "Activates volumetric fog", OnVolumetricFogChanged); - DefineConstIntCVar(e_FogVolumesTiledInjection, 1, VF_NULL, - "Activates tiled FogVolume density injection"); - REGISTER_CVAR(e_Entities, 1, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Activates drawing of entities"); - DefineConstIntCVar(e_SkyBox, 1, VF_CHEAT, - "Activates drawing of skybox and moving cloud layers"); - DefineConstIntCVar(e_WaterOcean, e_WaterOceanDefault, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Activates drawing of ocean. \n" - "1: use usual rendering path\n" - "2: use fast rendering path with merged fog"); - - if (!OceanToggle::IsActive()) - { - DefineConstIntCVar(e_WaterOceanBottom, 1, VF_CHEAT, - "Activates drawing bottom of ocean"); - } - - REGISTER_CVAR(e_WaterOceanFFT, 0, VF_NULL, - "Activates fft based ocean"); - - DefineConstIntCVar(e_WaterRipplesDebug, 0, VF_CHEAT, - "Draw water hits that affect water ripple simulation"); - - DefineConstIntCVar(e_DebugDrawShowOnlyCompound, 0, VF_NULL, - "e_DebugDraw shows only Compound (less efficient) static meshes"); - DefineConstIntCVar(e_DebugDrawShowOnlyLod, -1, VF_NULL, - "e_DebugDraw shows only objects showing lod X"); - -#ifdef CONSOLE_CONST_CVAR_MODE - // in console release builds the const cvars work differently (see ISystem.h where CONSOLE_CONST_CVAR_MODE is defined), - // so revert to the version of e_debugdraw that doesn't support mode 24 & 25 which require the OnDebugDrawChange callback - DefineConstIntCVar(e_DebugDraw, 0, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Draw helpers with information for each object (same number negative hides the text)\n" - " 1: Name of the used cgf, polycount, used LOD\n" - " 2: Color coded polygon count\n" - " 3: Show color coded LODs count, flashing color indicates no Lod\n" - " 4: Display object texture memory usage\n" - " 5: Display color coded number of render materials\n" - " 6: Display ambient color\n" - " 7: Display tri count, number of render materials, texture memory\n" - " 8: Free slot\n" - " 9: Free slot\n" - "10: Render geometry with simple lines and triangles\n" - "11: Free slot\n" - "12: Free slot\n" - "13: Display occlusion amount (used during AO computations). Warning: can take a long time to calculate, depending on level size! \n" - "15: Display helpers\n" - "16: Display debug gun\n" - "17: Streaming info (buffer sizes)\n" - "18: Free slot\n" - "19: Physics proxy triangle count\n" - "20: Display Character attachments texture memory usage\n" - "21: Display animated object distance to camera\n" - "22: Display object's current LOD vertex count\n" - "23: Display shadow casters in red\n" - "24: Disabled\n" - "25: Disabled\n" - "----------------debug draw list values. Any of them enable 2d on-screen listing type info debug. Specific values define the list sorting-----------\n" - " 100: tri count\n" - " 101: verts count\n" - " 102: draw calls\n" - " 103: texture memory\n" - " 104: mesh memory" - ); -#else - REGISTER_CVAR_CB(e_DebugDraw, 0, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK | CONST_CVAR_FLAGS, - "Draw helpers with information for each object (same number negative hides the text)\n" - " 1: Name of the used cgf, polycount, used LOD\n" - " 2: Color coded polygon count\n" - " 3: Show color coded LODs count, flashing color indicates no Lod\n" - " 4: Display object texture memory usage\n" - " 5: Display color coded number of render materials\n" - " 6: Display ambient color\n" - " 7: Display tri count, number of render materials, texture memory\n" - " 8: Free slot\n" - " 9: Free slot\n" - "10: Render geometry with simple lines and triangles\n" - "11: Free slot\n" - "12: Free slot\n" - "13: Display occlusion amount (used during AO computations). Warning: can take a long time to calculate, depending on level size! \n" - "15: Display helpers\n" - "16: Display debug gun\n" - "17: Streaming info (buffer sizes)\n" - "18: Free slot\n" - "19: Physics proxy triangle count\n" - "20: Display Character attachments texture memory usage\n" - "21: Display animated object distance to camera\n" - "22: Display object's current LOD vertex count\n" - "23: Display shadow casters in red\n" - "24: Display meshes with no LODs\n" - "25: Display meshes with no LODs, meshes with not enough LODs\n" - "----------------debug draw list values. Any of them enable 2d on-screen listing type info debug. Specific values define the list sorting-----------\n" - " 100: tri count\n" - " 101: verts count\n" - " 102: draw calls\n" - " 103: texture memory\n" - " 104: mesh memory", - OnDebugDrawChange); -#endif - - REGISTER_CVAR(e_DebugDrawLodMinTriangles, 200, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK | CONST_CVAR_FLAGS, - "Minimum number of triangles (lod 0) to show in LOD debug draw"); - -#ifndef _RELEASE - DefineConstIntCVar(e_DebugDrawListSize, 24, VF_DEV_ONLY, "num objects in the list for e_DebugDraw list infodebug"); - REGISTER_STRING_CB_DEV_ONLY("e_DebugDrawListFilter", "", VF_NULL, - "filter for e_DebugDraw list. Combine object type letters to create the filter\n" - "(example: e_DebugDrawListFilter BVC = shows Characters+StatObject). 'all' = no filter.\n" - " C: Character\n" - " S: StatObj (non characters)\n", NULL); - DefineConstIntCVar(e_DebugDrawListBBoxIndex, 0, VF_DEV_ONLY, - "enables BBOX drawing for the 'n' element of the DebugDrawList (starting by 1. 0 = no bbox drawing)."); - REGISTER_COMMAND("e_DebugDrawListCMD", CDebugDrawListMgr::ConsoleCommand, VF_DEV_ONLY, - "Issue commands to control e_DebugDraw list debuginfo behaviour\n" - "'Freeze' (F) - stops refreshing stats\n" - "'Continue' (C) - unfreezes\n" - "'DumpLog' (D) - dumps the current on-screen info into the log"); -#endif - -#if !defined(_RELEASE) - e_pStatObjRenderFilterStr = NULL; - REGISTER_CVAR2("e_StatObjRenderFilter", &e_pStatObjRenderFilterStr, "", VF_NULL, "Debug: Controls which cgfs are rendered, based on input string"); - e_statObjRenderFilterMode = 0; - REGISTER_CVAR2("e_StatObjRenderFilterMode", &e_statObjRenderFilterMode, 0, VF_NULL, "Debug: Controls how e_StatObjRenderFilter is use. 0=disabled 1=include 2=exclude"); -#endif - - DefineConstFloatCVar(e_SunAngleSnapSec, VF_NULL, - "Sun dir snap control"); - DefineConstFloatCVar(e_SunAngleSnapDot, VF_NULL, - "Sun dir snap control"); - - DefineConstIntCVar(e_Roads, 1, VF_CHEAT | VF_CHEAT_ALWAYS_CHECK, - "Activates drawing of road objects"); - - REGISTER_CVAR(e_Decals, 1, VF_NULL | VF_CHEAT_ALWAYS_CHECK, - "Activates drawing of decals (game decals and hand-placed)"); - REGISTER_CVAR(e_DecalsForceDeferred, 0, VF_NULL, - "1 - force to convert all decals to use deferred ones"); - REGISTER_CVAR(e_DecalsDefferedStatic, 1, VF_NULL, - "1 - switch all non-planar decals placed by level designer to deferred"); - REGISTER_CVAR(e_DecalsDefferedDynamic, 1, VF_NULL, - "1 - make all game play decals deferred, 2 - make all game play decals non deferred"); - DefineConstFloatCVar(e_DecalsDefferedDynamicMinSize, VF_CHEAT, - "Convert only dynamic decals bigger than X into deferred"); - DefineConstFloatCVar(e_DecalsDefferedDynamicDepthScale, VF_CHEAT, - "Scale decal projection depth"); - DefineConstFloatCVar(e_DecalsPlacementTestAreaSize, VF_CHEAT, - "Avoid spawning decals on the corners or edges of entity geometry"); - DefineConstFloatCVar(e_DecalsPlacementTestMinDepth, VF_CHEAT, - "Avoid spawning decals on the corners or edges of entity geometry"); - REGISTER_CVAR(e_DecalsMaxTrisInObject, 8000, VF_NULL, - "Do not create decals on objects having more than X triangles"); - REGISTER_CVAR(e_DecalsAllowGameDecals, 1, VF_NULL, - "Allows creation of decals by game (like weapon bullets marks)"); - DefineConstIntCVar(e_DecalsHitCache, 1, VF_CHEAT, - "Use smart hit caching for bullet hits (may cause no decals in some cases)"); - DefineConstIntCVar(e_DecalsMerge, 0, VF_NULL, - "Combine pieces of decals into one render call"); - DefineConstIntCVar(e_DecalsPreCreate, 1, VF_NULL, - "Pre-create decals at load time"); - DefineConstIntCVar(e_DecalsClip, 1, VF_NULL, - "Clip decal geometry by decal bbox"); - DefineConstFloatCVar(e_DecalsRange, VF_NULL, - "Less precision for decals outside this range"); - REGISTER_CVAR(e_DecalsLifeTimeScale, 1.f, VF_NULL, - "Allows to increase or reduce decals life time for different specs"); - REGISTER_CVAR(e_DecalsNeighborMaxLifeTime, 4.f, VF_NULL, - "If not zero - new decals will force old decals to fade in X seconds"); - REGISTER_CVAR(e_DecalsOverlapping, 0, VF_NULL, - "If zero - new decals will not be spawned if the distance to nearest decals less than X"); - DefineConstIntCVar(e_DecalsMaxValidFrames, 600, VF_NULL, - "Number of frames after which not visible static decals are removed"); - REGISTER_CVAR(e_DecalsMaxUpdatesPerFrame, 4, VF_NULL, - "Maximum number of static decal render mesh updates per frame"); - DefineConstIntCVar(e_VegetationBending, 1, VF_NULL, - "Enable vegetation bending (does not affect merged grass)"); - - DefineConstIntCVar(e_ForceDetailLevelForScreenRes, 0, VF_DEPRECATED, - "[DEPRECATED] Force sprite distance and other values used for some specific screen resolution, 0 means current"); - - DefineConstIntCVar(e_Wind, 1, VF_CHEAT, - "Enable global wind calculations, affects vegetations bending animations"); - DefineConstIntCVar(e_WindAreas, 1, VF_CHEAT, - "Debug"); - DefineConstFloatCVar(e_WindBendingDistRatio, VF_CHEAT, - "Wind cutoff distance for bending (linearly attentuated to that distance)"); - REGISTER_CVAR(e_Shadows, 1, VF_NULL, - "Activates drawing of shadows"); - REGISTER_CVAR(e_ShadowsBlendCascades, 1, VF_NULL, - "Blend between shadow cascades: 0=off, 1=on"); - REGISTER_CVAR(e_ShadowsBlendCascadesVal, 0.75f, VF_NULL, - "Size of cascade blend region"); -#if defined(WIN32) - REGISTER_CVAR(e_ShadowsLodBiasFixed, 1, VF_NULL, - "Simplifies mesh for shadow map generation by X LOD levels"); -#else - DefineConstIntCVar(e_ShadowsLodBiasFixed, 0, VF_NULL, - "Simplifies mesh for shadow map generation by X LOD levels"); -#endif - DefineConstIntCVar(e_ShadowsLodBiasInvis, 0, VF_NULL, - "Simplifies mesh for shadow map generation by X LOD levels, if object is not visible in main frame"); - - REGISTER_CVAR(e_Tessellation, 1, VF_NULL, - "HW geometry tessellation 0 = not allowed, 1 = allowed"); - REGISTER_CVAR(e_TessellationMaxDistance, 30.f, VF_NULL, - "Maximum distance from camera in meters to allow tessellation, also affects distance-based displacement fadeout"); - DefineConstIntCVar(e_ShadowsTessellateCascades, 1, VF_NULL, - "Maximum cascade number to render tessellated shadows (0 = no tessellation for sun shadows)"); - DefineConstIntCVar(e_ShadowsTessellateDLights, 0, VF_NULL, - "Disable/enable tessellation for local lights shadows"); - REGISTER_CVAR(e_ShadowsOnAlphaBlend, 0, VF_NULL, - "Enable shadows on alphablended "); - DefineConstIntCVar(e_ShadowsFrustums, 0, VF_CHEAT, - "Debug"); - DefineConstIntCVar(e_ShadowsDebug, 0, VF_CHEAT, - "0=off, 2=visualize shadow maps on the screen"); - REGISTER_CVAR(e_ShadowsCache, 1, VF_NULL, - "Activates drawing of static cached shadows"); - REGISTER_CVAR(e_ShadowsCacheUpdate, 0, VF_NULL, - "Trigger updates of the shadow cache: 0=no update, 1=one update, 2=continuous updates"); - REGISTER_CVAR(e_ShadowsCacheObjectLod, 0, VF_NULL, - "The lod used for rendering objects into the shadow cache. Set to -1 to disable"); - REGISTER_CVAR_CB(e_ShadowsCacheRenderCharacters, 0, VF_NULL, - "Render characters into the shadow cache. 0=disabled, 1=enabled", OnDynamicDistanceShadowsVarChange); - REGISTER_CVAR(e_ShadowsCacheRequireManualUpdate, 0, VF_NULL, - "Sets whether levels must trigger manual updates of the cached shadow maps:\n" - "0=Cached shadows default to Incremental updates. Each cached shadow frustum will traverse and cull the octree each frame (Potentially high CPU/GPU overhead)\n" - "1=Levels must trigger cached shadow updates via script (Preferred: Lowest overhead)\n" - "2=Levels may either trigger cached shadow updates via script or allow cached shadows to update if the user moves too close to the border of the shadowmap"); - REGISTER_CVAR_CB(e_DynamicDistanceShadows, 1, VF_NULL, - "Enable dynamic distance shadows, 0=disable, 1=enable, -1=don't render dynamic distance shadows", OnDynamicDistanceShadowsVarChange); - DefineConstIntCVar(e_ShadowsCascadesDebug, 0, VF_CHEAT, - "0=off, 1=visualize sun shadow cascades on screen"); - REGISTER_CVAR(e_ShadowsPerObjectResolutionScale, 1, VF_NULL, - "Global scale for per object shadow texture resolution\n" - "NOTE: individual texture resolution is rounded to next power of two "); - REGISTER_CVAR(e_ShadowsClouds, 1, VF_NULL, - "Cloud shadows"); // no cheat var because this feature shouldn't be strong enough to affect gameplay a lot - REGISTER_CVAR(e_ShadowsPoolSize, 2048, VF_NULL, - "Set size of shadow pool (e_ShadowsPoolSize*e_ShadowsPoolSize)"); - REGISTER_CVAR(e_ShadowsMaxTexRes, 1024, VF_NULL, - "Set maximum resolution of shadow map\n256(faster), 512(medium), 1024(better quality)"); - REGISTER_CVAR(e_ShadowsResScale, 2.8f, VF_NULL, - "Shadows slope bias for shadowgen"); - REGISTER_CVAR(e_ShadowsAdaptScale, 2.72f, VF_NULL, - "Shadows slope bias for shadowgen"); - REGISTER_CVAR(e_ShadowsSlopeBias, 1.0f, VF_NULL, - "Shadows slope bias for shadowgen"); - REGISTER_CVAR(e_ShadowsSlopeBiasHQ, 0.25f, VF_NULL, - "Shadows slope bias for shadowgen (for high quality mode)"); - REGISTER_CVAR(e_ShadowsConstBias, 1.0f, VF_NULL, - "Shadows slope bias for shadowgen"); - REGISTER_CVAR(e_ShadowsConstBiasHQ, 0.05f, VF_NULL, - "Shadows slope bias for shadowgen (high quality mode)"); - REGISTER_CVAR(e_ShadowsClearShowMaskAtLoad, 1, VF_NULL, - "Clears the shadow mask at level load to remove any bad shadow data from previous level.\n" - "0 = Better perf. It does not clear the shadow which will help set shadowmask texture to be memoryless. This will help reduce gpu bandwidth)\n" - "1 = This will disable the memoryless optimization as it would clear the shadow at level load. Only use this if you see residual shadows from previous level showing up in current level.\n"); - - DefineConstIntCVar(e_ShadowsMasksLimit, 0, VF_NULL, - "Maximum amount of allocated shadow mask textures\n" - "This limits the number of shadow casting lights overlapping\n" - "0=disable limit(unpredictable memory requirements)\n" - "1=one texture (4 channels for 4 lights)\n" - "2=two textures (8 channels for 8 lights), ..."); - - REGISTER_CVAR(e_ShadowsUpdateViewDistRatio, 128, VF_NULL, - "View dist ratio for shadow maps updating for shadowpool"); - DefineConstFloatCVar(e_ShadowsCastViewDistRatioLights, VF_NULL, - "View dist ratio for shadow maps casting for light sources"); - REGISTER_CVAR(e_ShadowsCastViewDistRatio, 0.8f, VF_NULL, - "View dist ratio for shadow maps casting from objects"); - REGISTER_CVAR(e_GsmRange, 3.0f, VF_NULL, - "Size of LOD 0 GSM area (in meters)"); - REGISTER_CVAR(e_GsmRangeStep, 3.0f, VF_NULL, - "Range of next GSM lod is previous range multiplied by step"); - REGISTER_CVAR_CB(e_GsmLodsNum, 5, VF_NULL, - "Number of GSM lods (0..5)", OnGsmLodsNumChange); - DefineConstIntCVar(e_GsmDepthBoundsDebug, 0, VF_NULL, - "Debug GSM bounds regions calculation"); - DefineConstIntCVar(e_GsmStats, 0, VF_CHEAT, - "Show GSM statistics 0=off, 1=enable debug to the screens"); - REGISTER_CVAR(e_RNTmpDataPoolMaxFrames, 16, VF_CHEAT, - "Cache RNTmpData at least for X framres"); - - DefineConstIntCVar(e_AutoPrecacheCameraJumpDist, 16, VF_CHEAT, - "When not 0 - Force full pre-cache of textures, procedural vegetation and shaders\n" - "if camera moved for more than X meters in one frame or on new cut scene start"); - DefineConstIntCVar(e_AutoPrecacheTexturesAndShaders, 0, VF_CHEAT, - "Force auto pre-cache of general textures and shaders"); - DefineConstIntCVar(e_AutoPrecacheCgf, 1, VF_CHEAT, - "Force auto pre-cache of CGF render meshes. 1=pre-cache all meshes around camera. 2=pre-cache only important ones (twice faster)"); - REGISTER_CVAR(e_AutoPrecacheCgfMaxTasks, 8, VF_NULL, - "Maximum number of parallel streaming tasks during pre-caching"); - REGISTER_CVAR(e_TerrainOcclusionCullingMaxDist, 200.f, VF_NULL, - "Max length of ray (for version 1)"); - REGISTER_CVAR(e_StreamPredictionUpdateTimeSlice, 0.4f, VF_NULL, - "Maximum amount of time to spend for scene streaming priority update in milliseconds"); - REGISTER_CVAR(e_StreamAutoMipFactorSpeedThreshold, 0.f, VF_NULL, - "Debug"); - REGISTER_CVAR(e_StreamAutoMipFactorMin, 0.5f, VF_NULL, - "Debug"); - REGISTER_CVAR(e_StreamAutoMipFactorMax, 1.0f, VF_NULL, - "Debug"); - REGISTER_CVAR(e_StreamAutoMipFactorMaxDVD, 0.5f, VF_NULL, - "Debug"); - - REGISTER_CVAR(e_OcclusionCullingViewDistRatio, 0.5f, VF_NULL, - "Skip per object occlusion test for very far objects - culling on tree level will handle it"); - - REGISTER_CVAR(e_Sun, 1, VF_CHEAT, - "Activates sun light source"); - REGISTER_CVAR(e_CoverageBuffer, 1, VF_NULL, - "Activates usage of software coverage buffer.\n" - "1 - camera culling only\n" - "2 - camera culling and light-to-object check"); - REGISTER_CVAR(e_CoverageBufferVersion, 2, VF_NULL, - "1 Vladimir's, 2MichaelK's"); - DefineConstIntCVar(e_CoverageBufferDebug, 0, VF_CHEAT, - "Display content of main camera coverage buffer"); - DefineConstIntCVar(e_CoverageBufferDebugFreeze, 0, VF_CHEAT, - "Freezes view matrix/-frustum "); - DefineConstIntCVar(e_CoverageBufferDrawOccluders, 0, VF_CHEAT, - "Debug draw of occluders for coverage buffer"); - DefineConstIntCVar(e_CoverageBufferTestMode, 2, VF_CHEAT, - "Debug"); - REGISTER_CVAR(e_CoverageBufferBias, 0.05f, VF_NULL, - "Coverage buffer z-biasing"); - REGISTER_CVAR(e_CoverageBufferAABBExpand, 0.020f, VF_NULL, - "expanding the AABB's of the objects to test to avoid z-fighting issues in the Coverage buffer"); - REGISTER_CVAR(e_CoverageBufferEarlyOut, 1, VF_NULL, - "preempting occluder rasterization to avoid stalling in the main thread if rendering is faster"); - REGISTER_CVAR(e_CoverageBufferEarlyOutDelay, 3.0f, VF_NULL, - "Time in ms that rasterizer is allowed to continue working after early out request"); - REGISTER_CVAR(e_CoverageBufferRotationSafeCheck, 0, VF_NULL, - "Coverage buffer safe checking for rotation 0=disabled 1=enabled 2=enabled for out of frustum object"); - DefineConstIntCVar(e_CoverageBufferLightsDebugSide, -1, VF_CHEAT, - "Debug"); - REGISTER_CVAR(e_CoverageBufferDebugDrawScale, 1, VF_CHEAT, - "Debug"); - REGISTER_CVAR(e_CoverageBufferResolution, 128, VF_NULL, - "Resolution of software coverage buffer"); - - REGISTER_CVAR(e_CoverageBufferReproj, 0, VF_NULL, - "Use re-projection technique on CBuffer, 1 simple reproject, 2 additional hole filling, 4 using ocm mesh for occlusion checking"); - REGISTER_CVAR(e_CoverageBufferRastPolyLimit, 500000, VF_NULL, - "maximum amount of polys to rasterize cap, 0 means no limit\ndefault is 500000"); - REGISTER_CVAR(e_CoverageBufferShowOccluder, 0, VF_NULL, - "1 show only meshes used as occluder, 2 show only meshes not used as occluder"); - REGISTER_CVAR(e_CoverageBufferAccurateOBBTest, 0, VF_NULL, - "Checking of OBB boxes instead of AABB or bounding rects"); - DefineConstIntCVar(e_CoverageBufferTolerance, 0, VF_NULL, - "amount of visible pixel that will still identify the object as covered"); - DefineConstIntCVar(e_CoverageBufferOccludersTestMinTrisNum, 0, VF_CHEAT, - "Debug"); - REGISTER_CVAR(e_CoverageBufferOccludersViewDistRatio, 1.0f, VF_CHEAT, - "Debug"); - DefineConstFloatCVar(e_CoverageBufferOccludersLodRatio, VF_CHEAT, - "Debug"); - DefineConstIntCVar(e_CoverageBufferTreeDebug, 0, VF_CHEAT, - "Debug"); - DefineConstIntCVar(e_CoverageBufferMaxAddRenderMeshTime, 2, VF_NULL, - "Max time for unlimited AddRenderMesh"); - REGISTER_CVAR(e_CoverageBufferNumberFramesLatency, 2, VF_NULL, - "Configures the number of frames of latency between the GPU write of the downsample Z-Target and CPU readback of that target.\n" - "0 - Disable CPU readback (For debugging)" - "1 - Coverage buffer uses previous frame's depth information. (Not recommended, CPU may stall waiting on GPU)\n" - "2 - Coverage buffer uses two frame old depth. (Default)\n" - "3 - Coverage buffer uses three frame old depth information."); - - DefineConstIntCVar(e_DynamicLightsMaxCount, 512, VF_CHEAT, - "Sets maximum amount of dynamic light sources"); - - DefineConstIntCVar(e_DynamicLights, 1, VF_CHEAT, - "Activates dynamic light sources"); - DefineConstIntCVar(e_DynamicLightsForceDeferred, 1, VF_CHEAT, - "Convert all lights to deferred (except sun)"); - REGISTER_CVAR(e_DynamicLightsFrameIdVisTest, 1, VF_NULL, - "Use based on last draw frame visibility test"); - DefineConstIntCVar(e_DynamicLightsConsistentSortOrder, 1, VF_NULL, - "Debug"); - - DefineConstIntCVar(e_HwOcclusionCullingWater, 1, VF_NULL, - "Activates usage of HW occlusion test for ocean"); - - DefineConstIntCVar(e_Portals, 1, VF_CHEAT, - "Activates drawing of visareas content (indoors), values 2,3,4 used for debugging"); - DefineConstIntCVar(e_PortalsBigEntitiesFix, 1, VF_CHEAT, - "Enables special processing of big entities like vehicles intersecting portals"); - DefineConstIntCVar(e_PortalsBlend, 1, VF_CHEAT, - "Blend lights and cubemaps of vis areas connected to portals 0=off, 1=on"); - REGISTER_CVAR(e_PortalsMaxRecursion, 8, VF_NULL, - "Maximum number of visareas and portals to traverse for indoor rendering"); - REGISTER_CVAR(e_DynamicLightsMaxEntityLights, 16, VF_NULL, - "Set maximum number of lights affecting object"); - DefineConstFloatCVar(e_MaxViewDistance, VF_CHEAT, - "Far clipping plane distance"); - REGISTER_CVAR(e_MaxViewDistSpecLerp, 1, VF_NULL, - "1 - use max view distance set by designer for very high spec\n0 - for very low spec\nValues between 0 and 1 - will lerp between high and low spec max view distances"); - DefineConstFloatCVar(e_MaxViewDistFullDistCamHeight, VF_CHEAT, - "Debug"); - DefineConstIntCVar(e_WaterVolumes, e_WaterVolumesDefault, VF_CHEAT, - "Activates drawing of water volumes\n" - "1: use usual rendering path\n" - "2: use fast rendering path with merged fog"); - DefineConstIntCVar(e_RenderTransparentUnderWater, e_RenderTransparentUnderWaterDefault, VF_NULL, - "Determines how transparent/alphablended objects are rendered in WaterVolume\n" - "0: they are not rendered under water (fast performance)\n" - "1: they are rendered twice under water and above water (higher quality)"); - if (!OceanToggle::IsActive()) - { - REGISTER_CVAR(e_WaterTessellationAmount, 200, VF_NULL, // being deprecated by Water gem - "Set tessellation amount"); - } - - REGISTER_CVAR(e_WaterTessellationSwathWidth, 12, VF_NULL, - "Set the swath width for the boustrophedonic mesh stripping"); - DefineConstIntCVar(e_BBoxes, 0, VF_CHEAT, - "Activates drawing of bounding boxes"); - - DefineConstIntCVar(e_StreamSaveStartupResultsIntoXML, 0, VF_NULL, - "Save basic information about streaming performance on level start into XML"); - REGISTER_CVAR(e_StreamCgfPoolSize, 24, VF_NULL, - "Render mesh cache size in MB"); - REGISTER_CVAR(e_SQTestBegin, 0, VF_NULL, - "If not zero - start streaming latency unit test"); - REGISTER_CVAR(e_SQTestCount, 0, VF_NULL, - "If not zero - restart test X times"); - REGISTER_CVAR(e_SQTestExitOnFinish, 0, VF_NULL, - "If not zero - shutdown when finished testing"); - REGISTER_CVAR(e_SQTestDistance, 80, VF_NULL, - "Distance to travel"); - REGISTER_CVAR(e_SQTestMip, 1, VF_NULL, - "Mip to wait during test"); - REGISTER_CVAR(e_SQTestMoveSpeed, 10, VF_NULL, - "Camera speed during test (meters/sec)"); - - // Small temp pool size for consoles, editor and pc have much larger capabilities - DefineConstIntCVar(e_3dEngineTempPoolSize, 1024, VF_NULL, - "pool size for temporary allocations in kb, requires app restart"); - - DefineConstIntCVar(e_3dEngineLogAlways, 0, VF_NULL, - "Set maximum verbosity to 3dengine.dll log messages"); - - DefineConstIntCVar(e_CoverCgfDebug, 0, VF_NULL, "Shows the cover setups on cfg files"); - - REGISTER_CVAR(e_StreamCgfMaxTasksInProgress, 32, VF_CHEAT, - "Maximum number of files simultaneously requested from streaming system"); - REGISTER_CVAR(e_StreamCgfMaxNewTasksPerUpdate, 4, VF_CHEAT, - "Maximum number of files requested from streaming system per update"); - REGISTER_CVAR(e_StreamPredictionMaxVisAreaRecursion, 9, VF_CHEAT, - "Maximum number visareas and portals to traverse."); - REGISTER_CVAR(e_StreamPredictionBoxRadius, 1, VF_CHEAT, "Radius of stream prediction box"); - REGISTER_CVAR(e_StreamPredictionTexelDensity, 1, VF_CHEAT, - "Use mesh texture mapping density info for textures streaming"); - REGISTER_CVAR(e_StreamPredictionAlwaysIncludeOutside, 0, VF_CHEAT, - "Always include outside octrees in streaming"); - DefineConstFloatCVar(e_StreamCgfFastUpdateMaxDistance, VF_CHEAT, - "Update streaming priorities for near objects every second frame"); - DefineConstFloatCVar(e_StreamPredictionMinFarZoneDistance, VF_CHEAT, - "Debug"); - DefineConstFloatCVar(e_StreamPredictionMinReportDistance, VF_CHEAT, - "Debug"); - REGISTER_CVAR_CB(e_StreamCgf, 1, VF_REQUIRE_APP_RESTART, - "Enable streaming of static render meshes", OnCGFStreamingChange); - DefineConstIntCVar(e_StreamCgfDebug, 0, VF_NULL, - "Draw helpers and other debug information about CGF streaming\n" - " 1: Draw color coded boxes for objects taking more than e_StreamCgfDebugMinObjSize,\n" - " also shows are the LOD's stored in single CGF or were split into several CGF's\n" - " 2: Trace into console every loading and unloading operation\n" - " 3: Print list of currently active objects taking more than e_StreamCgfDebugMinObjSize KB"); - DefineConstIntCVar(e_StreamCgfDebugMinObjSize, 100, VF_CHEAT, - "Threshold for objects debugging in KB"); - DefineConstIntCVar(e_StreamCgfDebugHeatMap, 0, VF_CHEAT, - "Generate and show mesh streaming heat map\n" - " 1: Generate heat map for entire level\n" - " 2: Show last heat map"); - DefineConstFloatCVar(e_StreamPredictionDistanceFar, VF_CHEAT, - "Prediction distance for streaming, affects far objects"); - DefineConstFloatCVar(e_StreamPredictionDistanceNear, VF_CHEAT, - "Prediction distance for streaming, affects LOD of objects"); - DefineConstFloatCVar(e_StreamCgfVisObjPriority, VF_CHEAT, - "Priority boost for visible objects\n" - "0 - visible objects has no priority over invisible objects, camera direction does not affect streaming\n" - "1 - visible objects has highest priority, in case of trashing will produce even more trashing"); - - DefineConstFloatCVar(e_StreamCgfGridUpdateDistance, VF_CHEAT, - "Update streaming priorities when camera moves more than this value"); - - DefineConstFloatCVar(e_StreamPredictionAhead, VF_CHEAT, - "Use predicted camera position for streaming priority updates"); - - DefineConstFloatCVar(e_StreamPredictionAheadDebug, VF_CHEAT, - "Draw ball at predicted position"); - - DefineConstFloatCVar(e_DissolveDistMax, VF_CHEAT, - "At most how near to object MVD dissolve effect triggers (10% of MVD, clamped to this)"); - - DefineConstFloatCVar(e_DissolveDistMin, VF_CHEAT, - "At least how near to object MVD dissolve effect triggers (10% of MVD, clamped to this)"); - - DefineConstFloatCVar(e_DissolveDistband, VF_CHEAT, - "Over how many meters transition takes place"); - - - DefineConstIntCVar(e_StreamCgfUpdatePerNodeDistance, 1, VF_CHEAT, - "Use node distance as entity distance for far nodex "); - - DefineConstIntCVar(e_ScissorDebug, 0, VF_CHEAT, - "Debug"); - - REGISTER_CVAR(e_OnDemandPhysics, gEnv->IsEditor() ? 0 : 1, VF_NULL, - "Turns on on-demand physicalization (0=off)"); - REGISTER_CVAR(e_OnDemandMaxSize, 20.0f, VF_NULL, - "Specifies the maximum size of vegetation objects that are physicalized on-demand"); - DefineConstIntCVar(e_Sleep, 0, VF_CHEAT, - "Sleep X in C3DEngine::Draw"); - REGISTER_CVAR(e_ObjectLayersActivation, (m_bEditor ? 0 : 1), VF_CHEAT, "Allow game to activate/deactivate object layers"); - DefineConstIntCVar(e_ObjectLayersActivationPhysics, 1, VF_CHEAT, - "Allow game to create/free physics of objects: 0: Disable; 1: All; 2: Water only."); - DefineConstIntCVar(e_Objects, 1, VF_CHEAT, - "Render or not all objects"); - DefineConstIntCVar(e_Render, e_RenderDefault, VF_CHEAT, - "Enable engine rendering"); - DefineConstIntCVar(e_ObjectsTreeBBoxes, 0, VF_CHEAT, - "Debug draw of object tree bboxes"); - /* REGISTER_CVAR(e_obj_tree_min_node_size, 0, VF_CHEAT, - "Debug draw of object tree bboxes"); - REGISTER_CVAR(e_obj_tree_max_node_size, 0, VF_CHEAT, - "Debug draw of object tree bboxes");*/ - REGISTER_CVAR(e_StatObjBufferRenderTasks, 1, VF_NULL, - "1 - occlusion test on render node level, 2 - occlusion test on render mesh level"); - REGISTER_CVAR(e_CheckOcclusion, 1, VF_NULL, "Perform a visible check in check occlusion job"); - - #define DEFAULT_CHECK_OCCLUSION_QUEUE_SIZE 1024 - #define DEFAULT_CHECK_OCCLUSION_OUTPUT_QUEUE_SIZE 4096 - - REGISTER_CVAR(e_CheckOcclusionQueueSize, DEFAULT_CHECK_OCCLUSION_QUEUE_SIZE, VF_NULL, - "Size of queue for data send to check occlusion job"); - REGISTER_CVAR(e_CheckOcclusionOutputQueueSize, DEFAULT_CHECK_OCCLUSION_OUTPUT_QUEUE_SIZE, VF_NULL, - "Size of queue for data send from check occlusion job"); - REGISTER_CVAR(e_StatObjTessellationMaxEdgeLenght, 1.75f, VF_CHEAT, - "Split edges longer than X meters"); - REGISTER_CVAR(e_StatObjTessellationMode, 1, VF_CHEAT, - "Set they way pre-tessellated version of meshes is created: 0 = no pre-tessellation, 1 = load from disk, 2 = generate from normal mesh on loading"); - DefineConstIntCVar(e_StatObjTestOBB, 0, VF_CHEAT, - "Use additional OBB check for culling"); - DefineConstIntCVar(e_ObjStats, 0, VF_CHEAT, - "Show instances count"); - DefineConstIntCVar(e_ObjFastRegister, 1, VF_CHEAT, - "Debug"); - - DefineConstIntCVar(e_OcclusionLazyHideFrames, 0, VF_CHEAT, - "Makes less occluson tests, but it takes more frames to detect invisible objects"); - DefineConstIntCVar(e_OcclusionVolumes, e_OcclusionVolumesDefault, VF_CHEAT, - "Enable occlusion volumes(antiportals)"); - DefineConstFloatCVar(e_OcclusionVolumesViewDistRatio, VF_NULL, - "Controls how far occlusion volumes starts to occlude objects"); - - DefineConstIntCVar(e_PrecacheLevel, 0, VF_NULL, - "Pre-render objects right after level loading"); - REGISTER_CVAR(e_Dissolve, 1, VF_NULL, - "Objects alphatest_noise_fading out on distance and between lods"); - DefineConstIntCVar(e_Lods, 1, VF_NULL, - "Load and use LOD models for static geometry"); - DefineConstIntCVar(e_LodFaceArea, 1, VF_NULL, - "Use geometric mean of faces area to compute LOD"); - DefineConstIntCVar(e_LodsForceUse, 1, VF_NULL, - "Force using LODs even if triangle count do not suit"); - DefineConstFloatCVar(e_LodBoundingBoxDistanceMultiplier, VF_CHEAT, - "e_LodBoundingBoxDistanceMultiplier "); - - REGISTER_CVAR(e_SQTestDelay, 5.f, VF_NULL, - "Time to stabilize the system before camera movements"); - - DefineConstIntCVar(e_Recursion, 1, VF_NULL, - "If 0 - will skip recursive render calls like render into texture"); - DefineConstIntCVar(e_RecursionOcclusionCulling, 0, VF_NULL, - "If 0 - will disable occlusion tests for recursive render calls like render into texture"); - REGISTER_CVAR(e_RecursionViewDistRatio, 0.1f, VF_NULL, - "Set all view distances shorter by factor of X"); - - REGISTER_CVAR(e_Clouds, 1, VF_NULL, - "Enable clouds rendering"); - - REGISTER_CVAR(e_SkyUpdateRate, 0.12f, VF_NULL, - "Percentage of a full dynamic sky update calculated per frame (0..100]."); - DefineConstIntCVar(e_SkyQuality, 1, VF_NULL, - "Quality of dynamic sky: 1 (very high), 2 (high)."); - DefineConstIntCVar(e_SkyType, 1, VF_NULL, - "Type of sky used: 0 (static), 1 (dynamic)."); - - DefineConstIntCVar(e_DisplayMemoryUsageIcon, e_DisplayMemoryUsageIconDefault, VF_NULL, - "Turns On/Off the memory usage icon rendering: 1 on, 0 off."); - - REGISTER_CVAR(e_LodRatio, 6.0f, VF_NULL, - "LOD distance ratio for objects"); - REGISTER_CVAR(e_LodFaceAreaTargetSize, 0.005f, VF_NULL, - "Threshold used for LOD computation."); - REGISTER_CVAR(e_FogVolumeShadingQuality, 0, VF_NULL, - "Fog Volume Shading Quality 0: standard, 1:high (better fog volume interaction)"); - DefineConstFloatCVar(e_LodCompMaxSize, VF_NULL, - "Affects LOD selection for big objects, small number will switch more objects into lower LOD"); - REGISTER_CVAR(e_ViewDistRatio, 60.0f, VF_CVARGRP_IGNOREINREALVAL, - "View distance ratio for objects"); - DefineConstFloatCVar(e_ViewDistCompMaxSize, VF_NULL, - "Affects max view distance for big objects, small number will render less objects"); - DefineConstFloatCVar(e_ViewDistRatioPortals, VF_NULL, - "View distance ratio for portals"); - REGISTER_CVAR(e_ViewDistRatioDetail, 30.0f, VF_NULL, - "View distance ratio for detail objects"); - REGISTER_CVAR(e_ViewDistRatioLights, 50.0f, VF_NULL, - "View distance ratio for light sources"); - REGISTER_CVAR(e_ViewDistRatioCustom, 60.0f, VF_NULL, - "View distance ratio for special marked objects (Players,AI,Vehicles)"); - REGISTER_CVAR(e_ViewDistMin, 0.0f, VF_NULL, - "Min distance on what far objects will be culled out"); - REGISTER_CVAR(e_LodMin, 0, VF_NULL, - "Min LOD for objects"); - REGISTER_CVAR(e_CharLodMin, 0, VF_NULL, - "Min LOD for character objects"); - REGISTER_CVAR(e_LodForceUpdate, 0, VF_NULL, - "When active, recalculate object LOD when rendering instead of using LOD calculated during previous frame."); - REGISTER_CVAR(e_LodMax, MAX_STATOBJ_LODS_NUM - 1, VF_CHEAT, - "Max LOD for objects"); - DefineConstIntCVar(e_LodMinTtris, 300, VF_CHEAT, - "LODs with less triangles will not be used"); - REGISTER_CVAR(e_PhysMinCellSize, 4, VF_NULL, - "Min size of cell in physical entity grid"); - DefineConstIntCVar(e_PhysEntityGridSizeDefault, 4096, VF_NULL, - "Default size of the physical entity grid when there's no terrain."); - REGISTER_CVAR(e_PhysProxyTriLimit, 5000, VF_NULL, - "Maximum allowed triangle count for phys proxies"); - DefineConstIntCVar(e_PhysFoliage, 2, VF_NULL, - "Enables physicalized foliage\n" - "1 - only for dynamic objects\n" - "2 - for static and dynamic)"); - DefineConstIntCVar(e_RenderMeshUpdateAsync, 1, VF_NULL, - "Enables async updating of dynamically updated rendermeshes\n" - "0 - performs a synchronous update\n" - "1 - performs the update in an async job (default))"); - REGISTER_CVAR(e_FoliageWindActivationDist, 0, VF_NULL, - "If the wind is sufficiently strong, visible foliage in this view dist will be forcefully activated"); - - DefineConstIntCVar(e_DeformableObjects, e_DeformableObjectsDefault, VF_NULL, - "Enable / Disable morph based deformable objects"); - - REGISTER_CVAR(e_CullVegActivation, 200, VF_NULL, - "Vegetation activation distance limit; 0 disables visibility-based culling (= unconditional activation)"); - - REGISTER_CVAR(e_PhysOceanCell, e_PhysOceanCellDefault, VF_NULL, - "Cell size for ocean approximation in physics, 0 assumes flat plane"); - - DefineConstFloatCVar(e_JointStrengthScale, VF_NULL, - "Scales the strength of prebroken objects\' joints (for tweaking)"); - - DefineConstFloatCVar(e_VolObjShadowStrength, VF_NULL, - "Self shadow intensity of volume objects [0..1]."); - - REGISTER_CVAR(e_ScreenShot, 0, VF_NULL, - "Make screenshot combined up of multiple rendered frames\n" - "(negative values for multiple frames, positive for a a single frame)\n" - " 1 highres\n" - " 2 360 degree panorama\n" - " 3 Map top-down view\n" - "\n" - "see:\n" - " e_ScreenShotWidth, e_ScreenShotHeight, e_ScreenShotQuality, e_ScreenShotMapCenterX,\n" - " e_ScreenShotMapCenterY, e_ScreenShotMapSize, e_ScreenShotMinSlices, e_ScreenShotDebug"); - - REGISTER_CVAR(e_ScreenShotWidth, 2000, VF_NULL, - "used for all type highres screenshots made by e_ScreenShot to define the\n" - "width of the destination image, 2000 default"); - REGISTER_CVAR(e_ScreenShotHeight, 1500, VF_NULL, - "used for all type highres screenshots made by e_ScreenShot to define the\n" - "height of the destination image, 1500 default"); - REGISTER_CVAR(e_ScreenShotQuality, 30, VF_NULL, - "used for all type highres screenshots made by e_ScreenShot to define the quality\n" - "0=fast, 10 .. 30 .. 100 = extra border in percent (soften seams), negative value to debug"); - REGISTER_CVAR(e_ScreenShotMinSlices, 1, VF_NULL, - "used for all type highres screenshots made by e_ScreenShot to define the amount\n" - "of sub-screenshots for the width and height to generate the image,\n the min count\n" - "will be automatically raised if not sufficient (per screenshot-based)"); - REGISTER_CVAR(e_ScreenShotMapCenterX, 0.0f, VF_NULL, - "param for the centerX position of the camera, see e_ScreenShotMap\n" - "defines the x position of the top left corner of the screenshot-area on the terrain,\n" - "0.0 - 1.0 (0.0 is default)"); - REGISTER_CVAR(e_ScreenShotMapCenterY, 0.0f, VF_NULL, - "param for the centerX position of the camera, see e_ScreenShotMap\n" - "defines the y position of the top left corner of the screenshot-area on the terrain,\n" - "0.0 - 1.0 (0.0 is default)"); - REGISTER_CVAR(e_ScreenShotMapSizeX, 1024.f, VF_NULL, - "param for the size in worldunits of area to make map screenshot, see e_ScreenShotMap\n" - "defines the x position of the bottom right corner of the screenshot-area on the terrain,\n" - "0.0 - 1.0 (1.0 is default)"); - REGISTER_CVAR(e_ScreenShotMapSizeY, 1024.f, VF_NULL, - "param for the size in worldunits of area to make map screenshot, see e_ScreenShotMap\n" - "defines the x position of the bottom right corner of the screenshot-area on the terrain,\n" - "0.0 - 1.0 (1.0 is default)"); - REGISTER_CVAR(e_ScreenShotMapCamHeight, 4000.f, VF_NULL, - "param for top-down-view screenshot creation, defining the camera height for screenshots,\n" - "see e_ScreenShotMap defines the y position of the bottom right corner of the\n" - "screenshot-area on the terrain,\n" - "0.0 - 1.0 (1.0 is default)"); - REGISTER_CVAR(e_ScreenShotMapOrientation, 0, VF_NULL, - "param for rotating the orientation through 90 degrees so the screen shot width is along the X axis\n" - "see e_ScreenShotMap\n" - "0 - 1 (0 is default)"); - REGISTER_CVAR(e_ScreenShotDebug, 0, VF_NULL, - "0 off\n1 show stitching borders\n2 show overlapping areas"); - - DefineConstIntCVar(e_Ropes, 1, VF_CHEAT, - "Turn Rendering of Ropes on/off"); - - DefineConstIntCVar(e_StatObjValidate, e_StatObjValidateDefault, VF_NULL, - "Enable CGF mesh validation during loading"); - - DefineConstIntCVar(e_StatObjPreload, 1, VF_NULL, - "Load level CGF's in efficient way"); - - DefineConstIntCVar(e_PreloadMaterials, 1, VF_NULL, - "Preload level materials from level cache pak and resources list"); - DefineConstIntCVar(e_PreloadDecals, 1, VF_NULL, - "Preload all materials for decals"); - - DefineConstIntCVar(e_StatObjMerge, 1, VF_NULL, - "Enable CGF sub-objects meshes merging"); - DefineConstIntCVar(e_StatObjMergeUseThread, 1, VF_NULL, - "Use a thread to perform sub-objects meshes merging"); - DefineConstIntCVar(e_StatObjMergeMaxTrisPerDrawCall, 500, VF_NULL, - "Skip merging of meshes already having acceptable number of triangles per draw call"); - DefineConstIntCVar(e_StatObjStoreMesh, 0, VF_NULL, - "Store the mesh if enabled, used for cheat detection purposes (they will be stored by default on the dedi server)"); - - DefineConstIntCVar(e_DefaultMaterial, 0, VF_CHEAT, - "use gray illumination as default"); - - REGISTER_CVAR(e_ObjQuality, 0, VF_NULL, - "Object detail quality"); - REGISTER_CVAR(e_LightQuality, 0, VF_NULL, - "Light detail quality. Controls whether lights are created or casts shadows based on the minimum spec level set in the light configuration." - "1: Creates or casts shadows from lights that have the minimum spec level set to low." - "2: Creates or casts shadows from lights that have the minimum spec level set to low or medium." - "3: Creates or casts shadows from lights that have the minimum spec level set to low, medium or high." - "4: Creates or casts shadows from lights that have the minimum spec level set to low, medium, high or very high."); - REGISTER_CVAR(e_ObjShadowCastSpec, 0, VF_NULL, - "Object shadow casting spec. Only objects with Shadow Cast Spec <= e_ObjShadowCastSpec will cast shadows"); - - DefineConstIntCVar(e_LightVolumes, e_LightVolumesDefault, VF_NULL, - "Allows deferred lighting for registered alpha blended geometry\n" - "0 = Off\n" - "1 = Enabled\n" - "2 = Enabled just for sun light\n"); - - DefineConstIntCVar(e_LightVolumesDebug, 0, VF_NULL, - "Display light volumes debug info\n" - "0 = Off\n" - "1 = Enabled\n"); - - e_ScreenShotFileFormat = REGISTER_STRING("e_ScreenShotFileFormat", "tga", VF_NULL, - "Set output image file format for hires screen shots. Can be jpg or tga"); - - e_ScreenShotFileName = REGISTER_STRING("e_ScreenShotFileName", "", VF_NULL, - "Sets the output screen shot name, can include relative directories to @user@/ScreenShots"); - - e_SQTestTextureName = REGISTER_STRING("e_SQTestTextureName", "strfrn_advrt_boards_screen", VF_NULL, - "Reference texture name for streaming latency test"); - e_StreamCgfDebugFilter = REGISTER_STRING("e_StreamCgfDebugFilter", "", VF_NULL, - "Show only items containing specified text"); - - e_CameraGoto = REGISTER_STRING("e_CameraGoto", "0", VF_CHEAT, - "Move cameras to a certain pos/angle"); - e_DebugDrawFilter = REGISTER_STRING("e_DebugDrawFilter", "", VF_NULL, - "Show a specified text on DebugDraw"); - - REGISTER_CVAR_CB(e_TimeOfDay, 0.0f, VF_CHEAT | VF_CHEAT_NOCHECK, "Current Time of Day", OnTimeOfDayVarChange); - REGISTER_CVAR_CB(e_TimeOfDaySpeed, 0.0f, VF_CHEAT | VF_CHEAT_NOCHECK, "Time of Day change speed", OnTimeOfDaySpeedVarChange); - DefineConstIntCVar(e_TimeOfDayDebug, 0, VF_NULL, - "Display time of day current values on screen"); - - - DefineConstFloatCVar(e_CameraRotationSpeed, VF_CHEAT, - "Rotate camera around Z axis for debugging"); - DefineConstIntCVar(e_CameraFreeze, 0, VF_CHEAT, - "Freeze 3dengine camera (good to debug object culling and LOD).\n" - "The view frustum is drawn in write frame.\n" - " 0 = off\n" - " 1 = activated"); - - REGISTER_CVAR(e_GI, 1, VF_NULL, - "Enable/disable global illumination. Default: 1 - enabled"); - - REGISTER_CVAR(e_RenderMeshCollisionTolerance, 0.3f, VF_NULL, - "Min distance between physics-proxy and rendermesh before collision is considered a hole"); - - REGISTER_CVAR(e_WorldSegmentationTest, 0, VF_CHEAT, - "Debug only: simulates multi-segment behavior in the editor"); - - DefineConstIntCVar(e_PrepareDeformableObjectsAtLoadTime, 0, VF_CHEAT, - "Enable to Prepare deformable objects at load time instead on demand, prevents peaks but increases memory usage"); - - DefineConstIntCVar(e_DeferredPhysicsEvents, 1, VF_CHEAT, - "Enable to Perform some physics events deferred as a task/job"); - - REGISTER_CVAR(e_levelStartupFrameNum, 0, VF_NULL, - "Set to number of frames to capture for avg fps computation"); - - REGISTER_CVAR(e_levelStartupFrameDelay, 0, VF_NULL, - "Set to number of frames to wait after level load before beginning fps measuring"); - - REGISTER_CVAR(e_CacheNearestCubePicking, 1, VF_NULL, - "Enable caching nearest cube maps probe picking for alpha blended geometry"); - - - REGISTER_CVAR(e_CGFMaxFileSize, -1, VF_CHEAT, - "will refuse to load any cgf larger than the given filesize (in kb)\n" - "-1 - 1024 (<0 off (default), >0 filesize limit)"); - - REGISTER_CVAR(e_MaxDrawCalls, 0, VF_CHEAT, - "Will not render CGFs past the given amount of drawcalls\n" - "(<=0 off (default), >0 draw calls limit)"); - - REGISTER_CVAR(e_CheckOctreeObjectsBoxSize, 1, VF_NULL, "Warning for crazy sized COctreeNode m_objectsBoxes"); - REGISTER_CVAR(e_DebugGeomPrep, 0, VF_NULL, "enable logging of Geom preparation"); - DefineConstIntCVar(e_GeomCaches, 1, VF_NULL, "Activates drawing of geometry caches"); - REGISTER_CVAR(e_GeomCacheBufferSize, 128, VF_CHEAT, "Geometry cache stream buffer upper limit size in MB. Default: 128"); - REGISTER_CVAR(e_GeomCacheMaxPlaybackFromMemorySize, 16, VF_CHEAT, - "Maximum size of geometry cache animated data in MB before always streaming from disk ignoring the memory playback flag. Default: 16"); - REGISTER_CVAR(e_GeomCachePreferredDiskRequestSize, 1024, VF_CHEAT, - "Preferred disk request size for geometry cache streaming in KB. Default: 1024"); - REGISTER_CVAR(e_GeomCacheMinBufferAheadTime, 2.0f, VF_CHEAT, - "Time in seconds minimum that data will be buffered ahead for geom cache streaming. Default: 2.0"); - REGISTER_CVAR(e_GeomCacheMaxBufferAheadTime, 5.0f, VF_CHEAT, - "Time in seconds maximum that data will be buffered ahead for geom cache streaming. Default: 5.0"); - REGISTER_CVAR(e_GeomCacheDecodeAheadTime, 0.5f, VF_CHEAT, - "Time in seconds that data will be decoded ahead for geom cache streaming. Default: 0.5"); -#ifndef _RELEASE - DefineConstIntCVar(e_GeomCacheDebug, 0, VF_CHEAT, "Show geometry cache debug overlay. Default: 0"); - e_GeomCacheDebugFilter = REGISTER_STRING("e_GeomCacheDebugFilter", "", VF_CHEAT, "Set name filter for e_geomCacheDebug"); - DefineConstIntCVar(e_GeomCacheDebugDrawMode, 0, VF_CHEAT, "Geometry cache debug draw mode\n" - " 0 = normal\n" - " 1 = only animated meshes\n" - " 2 = only static meshes\n" - " 3 = debug instancing"); -#endif - DefineConstIntCVar(e_GeomCacheLerpBetweenFrames, 1, VF_CHEAT, "Interpolate between geometry cache frames. Default: 1"); - - REGISTER_CVAR(e_PermanentRenderObjects, 0, VF_NULL, "Creates permanent render objects for each render node"); - REGISTER_CVAR(e_StaticInstancing, 0, VF_NULL, "Enables instancing of static objects"); - REGISTER_CVAR(e_StaticInstancingMinInstNum, 10, VF_NULL, "Minimum number of common static objects in a tree node before hardware instancing is used."); - - DefineConstIntCVar(e_MemoryProfiling, 0, VF_DEV_ONLY, "Toggle displaying memory usage statistics"); -} diff --git a/Code/CryEngine/Cry3DEngine/cvars.h b/Code/CryEngine/Cry3DEngine/cvars.h deleted file mode 100644 index 359e532eb3..0000000000 --- a/Code/CryEngine/Cry3DEngine/cvars.h +++ /dev/null @@ -1,455 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if defined(CONSOLE_CONST_CVAR_MODE) -# define GetFloatCVar(name) name ## Default -#else -# define GetFloatCVar(name) (Cry3DEngineBase::GetCVars())->name -#endif - -// console variables -struct CVars - : public Cry3DEngineBase -{ - CVars() - { Init(); } - - void Init(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - //default values used for const cvars -#ifdef _RELEASE - enum - { - e_StatObjValidateDefault = 0 - }; // Validate meshes in all but release builds. -#else - enum - { - e_StatObjValidateDefault = 1 - }; // Validate meshes in all but release builds. -#endif -#ifdef CONSOLE_CONST_CVAR_MODE - enum - { - e_DisplayMemoryUsageIconDefault = 0 - }; -#else - enum - { - e_DisplayMemoryUsageIconDefault = 1 - }; -#endif -#define e_PhysOceanCellDefault (0.f) -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(cvars_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - enum - { - e_DeformableObjectsDefault = 1 - }; - enum - { - e_OcclusionVolumesDefault = 1 - }; - enum - { - e_WaterOceanDefault = 1 - }; - enum - { - e_WaterVolumesDefault = 1 - }; - enum - { - e_LightVolumesDefault = 1 - }; -#endif - - -#define e_RenderTransparentUnderWaterDefault (0) -#define e_DecalsDefferedDynamicMinSizeDefault (0.35f) -#define e_DecalsPlacementTestAreaSizeDefault (0.08f) -#define e_DecalsPlacementTestMinDepthDefault (0.05f) -#define e_StreamPredictionDistanceFarDefault (16.f) -#define e_StreamPredictionDistanceNearDefault (0.f) -#define e_StreamCgfVisObjPriorityDefault (0.5f) -#define e_WindBendingDistRatioDefault (0.5f) -#define e_MaxViewDistFullDistCamHeightDefault (1000.f) -#define e_CoverageBufferOccludersLodRatioDefault (0.25f) -#define e_LodCompMaxSizeDefault (6.f) -#define e_LodBoundingBoxDistanceMultiplierDefault (0.1f) -#define e_MaxViewDistanceDefault (-1.f) -#define e_ViewDistCompMaxSizeDefault (64.f) -#define e_ViewDistRatioPortalsDefault (60.f) -#define e_WindDefault (0.1f) -#define e_ShadowsCastViewDistRatioLightsDefault (1.f) -#define e_DecalsRangeDefault (20.f) -#define e_GsmRangeStepExtendedDefault (8.f) -#define e_SunAngleSnapSecDefault (0.1f) -#define e_SunAngleSnapDotDefault (0.999999f) -#define e_OcclusionVolumesViewDistRatioDefault (0.05f) -#define e_JointStrengthScaleDefault (1.f) -#define e_VolObjShadowStrengthDefault (.4f) -#define e_CameraRotationSpeedDefault (0.f) -#define e_DecalsDefferedDynamicDepthScaleDefault (4.0f) -#define e_StreamCgfFastUpdateMaxDistanceDefault (16.f) -#define e_StreamPredictionMinFarZoneDistanceDefault (16.f) -#define e_StreamPredictionMinReportDistanceDefault (0.75f) -#define e_StreamCgfGridUpdateDistanceDefault (0.f) -#define e_StreamPredictionAheadDefault (0.5f) -#define e_StreamPredictionAheadDebugDefault (0.f) -#define e_DissolveDistMaxDefault (8.0f) -#define e_DissolveDistMinDefault (2.0f) -#define e_DissolveDistbandDefault (3.0f) -#define e_RenderMeshCollisionToleranceDefault (0.3f) - -#if _RELEASE -#define e_RenderDefault (1) -#else -#define e_RenderDefault (gEnv->IsDedicated() ? 0 : 1) -#endif - - int e_Decals; - int e_DecalsAllowGameDecals; - int e_CoverageBufferVersion; - DeclareConstFloatCVar(e_FoliageBrokenBranchesDamping); - float e_ShadowsCastViewDistRatio; - float e_OnDemandMaxSize; - float e_MaxViewDistSpecLerp; - float e_StreamAutoMipFactorSpeedThreshold; - DeclareConstFloatCVar(e_DecalsDefferedDynamicMinSize); - DeclareConstIntCVar(e_Objects, 1); - float e_ViewDistRatioCustom; - float e_StreamPredictionUpdateTimeSlice; - DeclareConstIntCVar(e_DisplayMemoryUsageIcon, e_DisplayMemoryUsageIconDefault); - int e_ScreenShotWidth; - DeclareConstIntCVar(e_CoverageBufferTolerance, 0); - int e_ScreenShotDebug; -#if defined(WIN32) - int e_ShadowsLodBiasFixed; -#else - DeclareConstIntCVar(e_ShadowsLodBiasFixed, 0); -#endif - DeclareConstIntCVar(e_FogVolumes, 1); - int e_VolumetricFog; - DeclareConstIntCVar(e_FogVolumesTiledInjection, 1); - DeclareConstIntCVar(e_Render, e_RenderDefault); - int e_Tessellation; - float e_TessellationMaxDistance; - DeclareConstIntCVar(e_ShadowsTessellateCascades, 1); - DeclareConstIntCVar(e_ShadowsTessellateDLights, 0); - int e_CoverageBufferReproj; - int e_CoverageBufferRastPolyLimit; - int e_CoverageBufferShowOccluder; - int e_CoverageBufferNumberFramesLatency; - DeclareConstFloatCVar(e_ViewDistRatioPortals); - DeclareConstFloatCVar(e_CoverageBufferOccludersLodRatio); - DeclareConstIntCVar(e_ObjFastRegister, 1); - float e_ViewDistRatioLights; - DeclareConstIntCVar(e_DebugDraw, 0); - int e_DebugDrawLodMinTriangles; // cvar for min number of triangles in object before displaying lod warnings - ICVar* e_DebugDrawFilter; - DeclareConstIntCVar(e_DebugDrawListSize, 16); - DeclareConstIntCVar(e_DebugDrawListBBoxIndex, 0); -#if !defined(_RELEASE) - const char* e_pStatObjRenderFilterStr; - int e_statObjRenderFilterMode; -#endif - DeclareConstIntCVar(e_AutoPrecacheTexturesAndShaders, 0); - int e_StreamPredictionMaxVisAreaRecursion; - float e_StreamPredictionBoxRadius; - int e_Clouds; - int e_DecalsMaxTrisInObject; - DeclareConstFloatCVar(e_OcclusionVolumesViewDistRatio); - DeclareConstFloatCVar(e_SunAngleSnapDot); - DeclareConstIntCVar(e_PreloadDecals, 1); - int e_WorldSegmentationTest; - float e_DecalsLifeTimeScale; - int e_DecalsForceDeferred; - DeclareConstIntCVar(e_CoverageBufferDebugFreeze, 0); - int e_PhysProxyTriLimit; - float e_FoliageWindActivationDist; - ICVar* e_SQTestTextureName; - int e_ShadowsClouds; - int e_levelStartupFrameDelay; - float e_SkyUpdateRate; - float e_RecursionViewDistRatio; - DeclareConstIntCVar(e_StreamCgfDebugMinObjSize, 100); - int e_CullVegActivation; - int e_StreamPredictionTexelDensity; - int e_StreamPredictionAlwaysIncludeOutside; - DeclareConstIntCVar(e_DynamicLights, 1); - int e_DynamicLightsFrameIdVisTest; - DeclareConstIntCVar(e_ShadowsLodBiasInvis, 0); - float e_CoverageBufferBias; - int e_DynamicLightsMaxEntityLights; - int e_SQTestMoveSpeed; - float e_StreamAutoMipFactorMax; - int e_CoverageBufferAccurateOBBTest; - int e_ObjQuality; - int e_LightQuality; - int e_RNTmpDataPoolMaxFrames; - DeclareConstIntCVar(e_DynamicLightsMaxCount, 512); - int e_StreamCgfPoolSize; - DeclareConstIntCVar(e_StatObjPreload, 1); - DeclareConstIntCVar(e_ShadowsDebug, 0); - DeclareConstIntCVar(e_ShadowsCascadesDebug, 0); - DeclareConstFloatCVar(e_StreamPredictionDistanceNear); - float e_CoverageBufferDebugDrawScale; - DeclareConstIntCVar(e_GsmStats, 0); - DeclareConstIntCVar(e_DynamicLightsForceDeferred, 1); - DeclareConstIntCVar(e_Fog, 1); - float e_TimeOfDay; - DeclareConstIntCVar(e_SkyBox, 1); - float e_CoverageBufferAABBExpand; - int e_CoverageBufferEarlyOut; - float e_CoverageBufferEarlyOutDelay; - int e_Dissolve; - int e_StatObjBufferRenderTasks; - DeclareConstIntCVar(e_StreamCgfUpdatePerNodeDistance, 1); - DeclareConstFloatCVar(e_DecalsDefferedDynamicDepthScale); - DeclareConstIntCVar(e_LightVolumes, e_LightVolumesDefault); - DeclareConstIntCVar(e_LightVolumesDebug, 0); - DeclareConstIntCVar(e_Portals, 1); - DeclareConstIntCVar(e_PortalsBlend, 1); - int e_PortalsMaxRecursion; - float e_StreamAutoMipFactorMaxDVD; - DeclareConstIntCVar(e_CameraFreeze, 0); - DeclareConstFloatCVar(e_StreamPredictionAhead); - DeclareConstFloatCVar(e_FoliageBranchesStiffness); - DeclareConstFloatCVar(e_StreamPredictionMinFarZoneDistance); - int e_StreamCgf; - int e_CheckOcclusion; - int e_CheckOcclusionQueueSize; - int e_CheckOcclusionOutputQueueSize; - DeclareConstIntCVar(e_WaterVolumes, e_WaterVolumesDefault); - DeclareConstIntCVar(e_RenderTransparentUnderWater, e_RenderTransparentUnderWaterDefault); - float e_ScreenShotMapCamHeight; - DeclareConstIntCVar(e_CoverageBufferOccludersTestMinTrisNum, 0); - DeclareConstIntCVar(e_DeformableObjects, e_DeformableObjectsDefault); - - DeclareConstFloatCVar(e_StreamCgfFastUpdateMaxDistance); - DeclareConstIntCVar(e_DecalsClip, 1); - ICVar* e_ScreenShotFileFormat; - ICVar* e_ScreenShotFileName; - int e_CharLodMin; - float e_PhysOceanCell; - DeclareConstIntCVar(e_WindAreas, 1); - DeclareConstFloatCVar(e_WindBendingDistRatio); - float e_SQTestDelay; - int e_PhysMinCellSize; - DeclareConstIntCVar(e_PhysEntityGridSizeDefault, 4096); - int e_StreamCgfMaxTasksInProgress; - int e_StreamCgfMaxNewTasksPerUpdate; - int e_CoverageBufferResolution; - DeclareConstFloatCVar(e_DecalsPlacementTestAreaSize); - DeclareConstFloatCVar(e_DecalsPlacementTestMinDepth); - DeclareConstFloatCVar(e_CameraRotationSpeed); - float e_ScreenShotMapSizeY; - int e_GI; - DeclareConstIntCVar(e_CoverageBufferLightsDebugSide, -1); - DeclareConstIntCVar(e_PortalsBigEntitiesFix, 1); - int e_SQTestBegin; - ICVar* e_CameraGoto; - - DeclareConstFloatCVar(e_StreamPredictionMinReportDistance); - int e_WaterTessellationSwathWidth; - DeclareConstIntCVar(e_RecursionOcclusionCulling, 0); - DeclareConstIntCVar(e_StreamSaveStartupResultsIntoXML, 0); - DeclareConstIntCVar(e_PhysFoliage, 2); - DeclareConstIntCVar(e_RenderMeshUpdateAsync, 1); - DeclareConstIntCVar(e_CoverageBufferTreeDebug, 0); - float e_CoverageBufferOccludersViewDistRatio; - int e_DecalsDefferedDynamic; - DeclareConstIntCVar(e_DefaultMaterial, 0); - int e_ShadowsOcclusionCulling; - int e_LodMin; - DeclareConstIntCVar(e_PreloadMaterials, 1); - DeclareConstIntCVar(e_ObjStats, 0); - DeclareConstIntCVar(e_ShadowsFrustums, 0); - DeclareConstIntCVar(e_OcclusionVolumes, e_OcclusionVolumesDefault); - int e_DecalsDefferedStatic; - DeclareConstIntCVar(e_Roads, 1); - DeclareConstIntCVar(e_DebugDrawShowOnlyCompound, 0); - DeclareConstIntCVar(e_StatObjMergeUseThread, 1); - DeclareConstFloatCVar(e_SunAngleSnapSec); - float e_GsmRangeStep; - float e_LodRatio; - float e_LodFaceAreaTargetSize; - DeclareConstIntCVar(e_CoverageBufferDrawOccluders, 0); - DeclareConstIntCVar(e_ObjectsTreeBBoxes, 0); - DeclareConstIntCVar(e_PrepareDeformableObjectsAtLoadTime, 0); - DeclareConstIntCVar(e_3dEngineTempPoolSize, 1024); - DeclareConstFloatCVar(e_MaxViewDistFullDistCamHeight); - DeclareConstIntCVar(e_VegetationBending, 1); - DeclareConstFloatCVar(e_StreamPredictionAheadDebug); - float e_ShadowsSlopeBias; - float e_ShadowsSlopeBiasHQ; - DeclareConstIntCVar(e_GsmDepthBoundsDebug, 0); - DeclareConstIntCVar(e_TimeOfDayDebug, 0); - int e_WaterTessellationAmount; // being deprecated by Water gem - int e_Entities; - int e_CoverageBuffer; - int e_FogVolumeShadingQuality; - int e_ScreenShotQuality; - int e_levelStartupFrameNum; - DeclareConstIntCVar(e_DecalsPreCreate, 1); - int e_SQTestCount; - float e_GsmRange; - int e_ScreenShotMapOrientation; - int e_ScreenShotHeight; - int e_WaterOceanFFT; - DeclareConstFloatCVar(e_MaxViewDistance); - DeclareConstIntCVar(e_AutoPrecacheCameraJumpDist, 16); - DeclareConstIntCVar(e_LodsForceUse, 1); - DeclareConstIntCVar(e_ForceDetailLevelForScreenRes, 0); - DeclareConstIntCVar(e_3dEngineLogAlways, 0); - DeclareConstIntCVar(e_DecalsHitCache, 1); - DeclareConstIntCVar(e_BBoxes, 0); - float e_TimeOfDaySpeed; - int e_LodMax; - int e_LodForceUpdate; - DeclareConstFloatCVar(e_ViewDistCompMaxSize); - float e_ShadowsAdaptScale; - float e_ScreenShotMapSizeX; - float e_OcclusionCullingViewDistRatio; - DeclareConstIntCVar(e_WaterOceanBottom, 1); - DeclareConstIntCVar(e_WaterRipplesDebug, 0); - int e_OnDemandPhysics; - float e_ShadowsResScale; - DeclareConstIntCVar(e_Recursion, 1); - DeclareConstIntCVar(e_CoverageBufferMaxAddRenderMeshTime, 2); - int e_CoverageBufferRotationSafeCheck; - DeclareConstIntCVar(e_StatObjTestOBB, 0); - DeclareConstIntCVar(e_StatObjValidate, e_StatObjValidateDefault); - DeclareConstIntCVar(e_DecalsMaxValidFrames, 600); - DeclareConstIntCVar(e_DecalsMerge, 0); - int e_SQTestDistance; - float e_ViewDistMin; - float e_StreamAutoMipFactorMin; - DeclareConstIntCVar(e_LodMinTtris, 300); - DeclareConstIntCVar(e_SkyQuality, 1); - DeclareConstIntCVar(e_ScissorDebug, 0); - DeclareConstIntCVar(e_StatObjMergeMaxTrisPerDrawCall, 500); - DeclareConstIntCVar(e_DynamicLightsConsistentSortOrder, 1); - DeclareConstIntCVar(e_StreamCgfDebug, 0); - float e_TerrainOcclusionCullingMaxDist; - float e_StatObjTessellationMaxEdgeLenght; - int e_StatObjTessellationMode; - DeclareConstIntCVar(e_OcclusionLazyHideFrames, 0); - float e_RenderMeshCollisionTolerance; - DeclareConstIntCVar(e_ShadowsMasksLimit, 0); - int e_ShadowsCache; - int e_ShadowsCacheUpdate; - int e_ShadowsCacheObjectLod; - int e_ShadowsCacheRenderCharacters; - int e_ShadowsCacheRequireManualUpdate; - int e_ShadowsPerObject; - int e_DynamicDistanceShadows; - float e_ShadowsPerObjectResolutionScale; - int e_ObjShadowCastSpec; - DeclareConstFloatCVar(e_JointStrengthScale); - int e_AutoPrecacheCgfMaxTasks; - float e_DecalsNeighborMaxLifeTime; - DeclareConstFloatCVar(e_StreamCgfVisObjPriority); - int e_ObjectLayersActivation; - DeclareConstFloatCVar(e_DissolveDistMax); - DeclareConstFloatCVar(e_DissolveDistMin); - DeclareConstFloatCVar(e_DissolveDistband); - int e_ScreenShotMinSlices; - int e_DecalsMaxUpdatesPerFrame; - DeclareConstIntCVar(e_SkyType, 1); - int e_GsmLodsNum; - DeclareConstIntCVar(e_AutoPrecacheCgf, 1); - DeclareConstIntCVar(e_HwOcclusionCullingWater, 1); - DeclareConstIntCVar(e_CoverageBufferTestMode, 2); - DeclareConstIntCVar(e_DeferredPhysicsEvents, 1); - DeclareConstFloatCVar(e_ShadowsCastViewDistRatioLights); - int e_ShadowsUpdateViewDistRatio; - DeclareConstIntCVar(e_Lods, 1); - DeclareConstIntCVar(e_LodFaceArea, 1); - DeclareConstFloatCVar(e_LodBoundingBoxDistanceMultiplier); - float e_ShadowsConstBias; - float e_ShadowsConstBiasHQ; - int e_ShadowsClearShowMaskAtLoad; - DeclareConstIntCVar(e_Ropes, 1); - int e_ShadowsPoolSize; - int e_ShadowsMaxTexRes; - int e_Sun; - DeclareConstFloatCVar(e_DecalsRange); - float e_ScreenShotMapCenterY; - int e_CacheNearestCubePicking; - DeclareConstIntCVar(e_CoverCgfDebug, 0); - DeclareConstFloatCVar(e_StreamCgfGridUpdateDistance); - DeclareConstFloatCVar(e_LodCompMaxSize); - float e_ViewDistRatioDetail; - DeclareConstIntCVar(e_Sleep, 0); - DeclareConstIntCVar(e_Wind, 1); - int e_SQTestMip; - int e_Shadows; - int e_ShadowsBlendCascades; - float e_ShadowsBlendCascadesVal; - DeclareConstIntCVar(e_DebugDrawShowOnlyLod, -1); - int e_ScreenShot; - DeclareConstIntCVar(e_PrecacheLevel, 0); - float e_ScreenShotMapCenterX; - DeclareConstIntCVar(e_CoverageBufferDebug, 0); - DeclareConstIntCVar(e_StatObjMerge, 1); - DeclareConstIntCVar(e_StatObjStoreMesh, 0); - ICVar* e_StreamCgfDebugFilter; - int e_ShadowsOnAlphaBlend; - DeclareConstFloatCVar(e_VolObjShadowStrength); - DeclareConstIntCVar(e_WaterOcean, e_WaterOceanDefault); - float e_ViewDistRatio; - DeclareConstIntCVar(e_ObjectLayersActivationPhysics, 1); - DeclareConstIntCVar(e_StreamCgfDebugHeatMap, 0); - DeclareConstFloatCVar(e_StreamPredictionDistanceFar); - int e_SQTestExitOnFinish; - int e_DecalsOverlapping; - int e_CGFMaxFileSize; - int e_MaxDrawCalls; -#if !defined(_RELEASE) -#endif - - int e_DebugGeomPrep; - - int e_CheckOctreeObjectsBoxSize; - DeclareConstIntCVar(e_GeomCaches, 1); - int e_GeomCacheBufferSize; - int e_GeomCacheMaxPlaybackFromMemorySize; - int e_GeomCachePreferredDiskRequestSize; - float e_GeomCacheMinBufferAheadTime; - float e_GeomCacheMaxBufferAheadTime; - float e_GeomCacheDecodeAheadTime; - DeclareConstIntCVar(e_GeomCacheDebug, 0); - ICVar* e_GeomCacheDebugFilter; - DeclareConstIntCVar(e_GeomCacheDebugDrawMode, 0); - DeclareConstIntCVar(e_GeomCacheLerpBetweenFrames, 1); - - int e_PermanentRenderObjects; - int e_StaticInstancing; - int e_StaticInstancingMinInstNum; - - DeclareConstIntCVar(e_MemoryProfiling, 0); - - -}; diff --git a/Code/CryEngine/Cry3DEngine/resource.h b/Code/CryEngine/Cry3DEngine/resource.h deleted file mode 100644 index c5ff972593..0000000000 --- a/Code/CryEngine/Cry3DEngine/resource.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Cry3DEngine.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Code/CryEngine/CryCommon/CREGeomCache.h b/Code/CryEngine/CryCommon/CREGeomCache.h index 089915988e..6911b8486e 100644 --- a/Code/CryEngine/CryCommon/CREGeomCache.h +++ b/Code/CryEngine/CryCommon/CREGeomCache.h @@ -19,7 +19,7 @@ #if defined(USE_GEOM_CACHES) -#include "../RenderDll/Common/Shaders/Vertex.h" +#include #include class CREGeomCache diff --git a/Code/CryEngine/CryCommon/CRESky.h b/Code/CryEngine/CryCommon/CRESky.h index e1ef7bcaa8..3dfc7d184f 100644 --- a/Code/CryEngine/CryCommon/CRESky.h +++ b/Code/CryEngine/CryCommon/CRESky.h @@ -17,7 +17,7 @@ //============================================================= #include "VertexFormats.h" -#include "../RenderDll/Common/Shaders/Vertex.h" +#include struct SSkyLightRenderParams; diff --git a/Code/CryEngine/CryCommon/CREVolumeObject.h b/Code/CryEngine/CryCommon/CREVolumeObject.h index d84c7b3e50..2137053a8e 100644 --- a/Code/CryEngine/CryCommon/CREVolumeObject.h +++ b/Code/CryEngine/CryCommon/CREVolumeObject.h @@ -55,7 +55,7 @@ public: Matrix34 m_matInv; Vec3 m_eyePosInWS; Vec3 m_eyePosInOS; - Plane m_volumeTraceStartPlane; + Plane_tpl m_volumeTraceStartPlane; AABB m_renderBoundsOS; bool m_viewerInsideVolume; bool m_nearPlaneIntersectsVolume; diff --git a/Code/CryEngine/CryCommon/CREWaterOcean.h b/Code/CryEngine/CryCommon/CREWaterOcean.h index 784588309f..e8ca310d41 100644 --- a/Code/CryEngine/CryCommon/CREWaterOcean.h +++ b/Code/CryEngine/CryCommon/CREWaterOcean.h @@ -25,7 +25,7 @@ public: virtual void mfPrepare(bool bCheckOverflow); virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfGetPlane(Plane& pl); + virtual void mfGetPlane(Plane_tpl& pl); virtual void Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof); void ReleaseOcean(); diff --git a/Code/CryEngine/CryCommon/CREWaterVolume.h b/Code/CryEngine/CryCommon/CREWaterVolume.h index 3e7a0636e6..89102e3097 100644 --- a/Code/CryEngine/CryCommon/CREWaterVolume.h +++ b/Code/CryEngine/CryCommon/CREWaterVolume.h @@ -27,7 +27,7 @@ public: virtual ~CREWaterVolume(); virtual void mfPrepare(bool bCheckOverflow); virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfGetPlane(Plane& pl); + virtual void mfGetPlane(Plane_tpl& pl); virtual void mfCenter(Vec3& vCenter, CRenderObject* pObj); virtual void GetMemoryUsage(ICrySizer* pSizer) const @@ -69,7 +69,7 @@ public: Vec3 m_center; AABB m_WSBBox; - Plane m_fogPlane; + Plane_tpl m_fogPlane; float m_fogDensity; Vec3 m_fogColor; bool m_fogColorAffectedBySun; diff --git a/Code/CryEngine/CryCommon/CryFontBus.h b/Code/CryEngine/CryCommon/CryFontBus.h deleted file mode 100644 index 9922193f42..0000000000 --- a/Code/CryEngine/CryCommon/CryFontBus.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - */ - -#pragma once - -#include - -#include - -namespace AZ -{ - /*! - * Signal LY to create an ICryFont - */ - class CryFontCreationRequests - : public AZ::EBusTraits - { - public: - using MutexType = AZStd::recursive_mutex; - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual bool CreateCryFont([[maybe_unused]] SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams) {return false;} //! return false to fall back to default CryFont initialization - }; - using CryFontCreationRequestBus = AZ::EBus; - -} diff --git a/Code/CryEngine/CryCommon/Cry_Camera.h b/Code/CryEngine/CryCommon/Cry_Camera.h index a744d7335f..56a764d897 100644 --- a/Code/CryEngine/CryCommon/Cry_Camera.h +++ b/Code/CryEngine/CryCommon/Cry_Camera.h @@ -594,7 +594,7 @@ public: ILINE const Vec3& GetFPVertex(int nId) const; //get far-plane vertices ILINE const Vec3& GetPPVertex(int nId) const; //get projection-plane vertices - ILINE const Plane* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; } + ILINE const Plane_tpl* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; } ////////////////////////////////////////////////////////////////////////// // Z-Buffer ranges. @@ -720,7 +720,7 @@ private: Vec3 m_cltn, m_crtn, m_clbn, m_crbn; //this are the 4 vertices of the near-plane in cam-space Vec3 m_cltf, m_crtf, m_clbf, m_crbf; //this are the 4 vertices of the farclip-plane in cam-space - Plane m_fp [FRUSTUM_PLANES]; // + Plane_tpl m_fp [FRUSTUM_PLANES]; // uint32 m_idx1[FRUSTUM_PLANES], m_idy1[FRUSTUM_PLANES], m_idz1[FRUSTUM_PLANES]; // uint32 m_idx2[FRUSTUM_PLANES], m_idy2[FRUSTUM_PLANES], m_idz2[FRUSTUM_PLANES]; // @@ -742,7 +742,7 @@ public: m_crtp = arrvVerts[2]; m_crbp = arrvVerts[3]; } - inline void SetFrustumPlane(int i, const Plane& plane) + inline void SetFrustumPlane(int i, const Plane_tpl& plane) { m_fp[i] = plane; //do not break strict aliasing rules, use union instead of reinterpret_casts @@ -1180,12 +1180,12 @@ inline void CCamera::UpdateFrustum() //------------------------------------------------------------------------------- //--- calculate the six frustum-planes using the frustum edges in world-space --- //------------------------------------------------------------------------------- - m_fp[FR_PLANE_NEAR ] = Plane::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition()); - m_fp[FR_PLANE_RIGHT ] = Plane::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition()); - m_fp[FR_PLANE_LEFT ] = Plane::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition()); - m_fp[FR_PLANE_TOP ] = Plane::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition()); - m_fp[FR_PLANE_BOTTOM] = Plane::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition()); - m_fp[FR_PLANE_FAR ] = Plane::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane + m_fp[FR_PLANE_NEAR ] = Plane_tpl::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition()); + m_fp[FR_PLANE_RIGHT ] = Plane_tpl::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_LEFT ] = Plane_tpl::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_TOP ] = Plane_tpl::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_BOTTOM] = Plane_tpl::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_FAR ] = Plane_tpl::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane uint32 rh = m_Matrix.IsOrthonormalRH(); if (rh == 0) diff --git a/Code/CryEngine/CryCommon/Cry_GeoDistance.h b/Code/CryEngine/CryCommon/Cry_GeoDistance.h index 92c1f65d87..47794c7671 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoDistance.h +++ b/Code/CryEngine/CryCommon/Cry_GeoDistance.h @@ -1168,17 +1168,6 @@ namespace Distance { return fDist2; } - // Compute both the min and max distances of a box to a plane, in the sense of the plane normal. - inline void AABB_Plane(float* pfDistMin, float* pfDistMax, const AABB& box, const Plane& pl) - { - float fDist0 = pl.DistFromPlane(box.min), - fDistX = (box.max.x - box.min.x) * pl.n.x, - fDistY = (box.max.y - box.min.y) * pl.n.y, - fDistZ = (box.max.z - box.min.z) * pl.n.z; - *pfDistMin = fDist0 + min(fDistX, 0.f) + min(fDistY, 0.f) + min(fDistZ, 0.f); - *pfDistMax = fDist0 + max(fDistX, 0.f) + max(fDistY, 0.f) + max(fDistZ, 0.f); - } - //---------------------------------------------------------------------------------- // Distance: Sphere_Triangle //---------------------------------------------------------------------------------- diff --git a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h index c2f556c4b7..89f6d8ebaf 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h +++ b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h @@ -22,7 +22,7 @@ #include namespace Intersect { - inline bool Ray_Plane(const Ray& ray, const Plane& plane, Vec3& output, bool bSingleSidePlane = true) + inline bool Ray_Plane(const Ray& ray, const Plane_tpl& plane, Vec3& output, bool bSingleSidePlane = true) { float cosine = plane.n | ray.direction; @@ -49,7 +49,7 @@ namespace Intersect { return true; //intersection occurred } - inline bool Line_Plane(const Line& line, const Plane& plane, Vec3& output, bool bSingleSidePlane = true) + inline bool Line_Plane(const Line& line, const Plane_tpl& plane, Vec3& output, bool bSingleSidePlane = true) { float cosine = plane.n | line.direction; diff --git a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h index 3f2c7081d7..ab560b7518 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h +++ b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h @@ -945,29 +945,6 @@ namespace Overlap { } } - - /*! - * - * we use the SEPARATING-AXIS-TEST for OBB/Plane overlap. - * - * Example: - * bool result=Overlap::OBB_Plane( pos,obb, plane ); - * - */ - inline bool OBB_Plane(const Vec3& pos, const OBB& obb, const Plane& plane) - { - //the new center-position in world-space - Vec3 p = obb.m33 * obb.c + pos; - //extract the orientation-vectors from the columns of the 3x3 matrix - //and scale them by the half-lengths - Vec3 ax = Vec3(obb.m33.m00, obb.m33.m10, obb.m33.m20) * obb.h.x; - Vec3 ay = Vec3(obb.m33.m01, obb.m33.m11, obb.m33.m21) * obb.h.y; - Vec3 az = Vec3(obb.m33.m02, obb.m33.m12, obb.m33.m22) * obb.h.z; - //check OBB against Plane, using the plane-normal as separating axis - return fabsf(plane | p) < (fabsf(plane.n | ax) + fabsf(plane.n | ay) + fabsf(plane.n | az)); - } - - /*! * * we use the SEPARATING AXIS TEST to check if a triangle and AABB overlap. @@ -1214,7 +1191,7 @@ namespace Overlap { //test if the box intersects the plane of the triangle //compute plane equation of triangle: normal*x+d=0 - Plane plane = Plane::CreatePlane((e0 % e1), v0); + Plane_tpl plane = Plane_tpl::CreatePlane((e0 % e1), v0); Vec3 vmin, vmax; if (plane.n.x > 0.0f) @@ -1505,7 +1482,7 @@ namespace Overlap { //test if the box overlaps the plane of the triangle //compute plane equation of triangle: normal*x+d=0 - Plane plane = Plane::CreatePlane((e0 % e1), v0); + Plane_tpl plane = Plane_tpl::CreatePlane((e0 % e1), v0); Vec3 vmin, vmax; if (plane.n.x > 0.0f) diff --git a/Code/CryEngine/CryCommon/I3DEngine.h b/Code/CryEngine/CryCommon/I3DEngine.h index 8d3801ecb4..883b0a6d3b 100644 --- a/Code/CryEngine/CryCommon/I3DEngine.h +++ b/Code/CryEngine/CryCommon/I3DEngine.h @@ -458,7 +458,7 @@ struct SClipVolumeBlendInfo { static const int BlendPlaneCount = 2; - Plane blendPlanes[BlendPlaneCount]; + Plane_tpl blendPlanes[BlendPlaneCount]; struct IClipVolume* blendVolumes[BlendPlaneCount]; }; diff --git a/Code/CryEngine/CryCommon/IEntityRenderState.h b/Code/CryEngine/CryCommon/IEntityRenderState.h index 912f4632ab..92ff354eff 100644 --- a/Code/CryEngine/CryCommon/IEntityRenderState.h +++ b/Code/CryEngine/CryCommon/IEntityRenderState.h @@ -731,8 +731,8 @@ struct IWaterVolumeRenderNode virtual void SetAuxPhysParams(pe_params_area*) = 0; virtual void CreateOcean(uint64 volumeID, /* TBD */ bool keepSerializationParams = false) = 0; - virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; - virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; + virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane_tpl& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; + virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane_tpl& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; virtual void CreateRiver(uint64 volumeID, const AZStd::vector& verticies, const AZ::Transform& transform, float uTexCoordBegin, float uTexCoordEnd, const AZ::Vector2& surfUVScale, const AZ::Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; virtual void SetAreaPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams = false) = 0; diff --git a/Code/CryEngine/CryCommon/IIndexedMesh.h b/Code/CryEngine/CryCommon/IIndexedMesh.h index 9d0d77ffc8..d7ba19ae6c 100644 --- a/Code/CryEngine/CryCommon/IIndexedMesh.h +++ b/Code/CryEngine/CryCommon/IIndexedMesh.h @@ -22,7 +22,7 @@ #include #include // for AABB #include -#include <../RenderDll/Common/Shaders/Vertex.h> +#include #include // Description: diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index d284394904..7fcbdefebb 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -26,7 +26,7 @@ #include "smartptr.h" #include // <> required for Interfuscator #include "VertexFormats.h" -#include +#include #include #include @@ -52,7 +52,6 @@ struct SShaderItem; class ITexture; struct IMaterial; struct SParam; -class CMaterial; struct SShaderSerializeContext; struct IAnimNode; struct SSkinningData; diff --git a/Code/CryEngine/CryCommon/RendElement.h b/Code/CryEngine/CryCommon/RendElement.h index c3dc1c080d..41bcf2bf67 100644 --- a/Code/CryEngine/CryCommon/RendElement.h +++ b/Code/CryEngine/CryCommon/RendElement.h @@ -119,7 +119,7 @@ struct IRenderElement virtual void mfCenter(Vec3& centr, CRenderObject* pObj) = 0; virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs) = 0; virtual void mfReset() = 0; - virtual void mfGetPlane(Plane& pl) = 0; + virtual void mfGetPlane(Plane_tpl& pl) = 0; virtual void mfExport(struct SShaderSerializeContext& SC) = 0; virtual void mfImport(struct SShaderSerializeContext& SC, uint32& offset) = 0; virtual void mfPrecache(const SShaderItem& SH) = 0; @@ -265,7 +265,7 @@ public: void mfPrecache([[maybe_unused]] const SShaderItem& SH) override {} void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) override { CryFatalError("mfExport has not been implemented for this render element type"); } void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) override { CryFatalError("mfImport has not been implemented for this render element type"); } - void mfGetPlane(Plane& pl) override; + void mfGetPlane(Plane_tpl& pl) override; void* mfGetPointer([[maybe_unused]] ESrcPointer ePT, [[maybe_unused]] int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) override { return nullptr; } uint16 mfGetFlags() override { return m_Flags; } diff --git a/Code/CryEngine/RenderDll/Common/Shaders/Vertex.h b/Code/CryEngine/CryCommon/Vertex.h similarity index 100% rename from Code/CryEngine/RenderDll/Common/Shaders/Vertex.h rename to Code/CryEngine/CryCommon/Vertex.h diff --git a/Code/CryEngine/CryFont/CMakeLists.txt b/Code/CryEngine/CryFont/CMakeLists.txt deleted file mode 100644 index 9e2f29f7b6..0000000000 --- a/Code/CryEngine/CryFont/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -ly_add_target( - NAME CryFont ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} - NAMESPACE Legacy - FILES_CMAKE - cryfont_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::freetype - Legacy::CryCommon -) diff --git a/Code/CryEngine/CryFont/CryFont.cpp b/Code/CryEngine/CryFont/CryFont.cpp deleted file mode 100644 index ab39a0fa4d..0000000000 --- a/Code/CryEngine/CryFont/CryFont.cpp +++ /dev/null @@ -1,845 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CCryFont class. - - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "CryFont.h" -#include "CryPath.h" -#include "FFont.h" -#include "FontTexture.h" -#include "FontRenderer.h" -#include "ILocalizationManager.h" - -#include -#include - -// Static member definitions -const Vec2i CCryFont::defaultGlyphSize = Vec2i(ICryFont::defaultGlyphSizeX, ICryFont::defaultGlyphSizeY); - -#if !defined(_RELEASE) -static void DumpFontTexture(IConsoleCmdArgs* pArgs) -{ - if (pArgs->GetArgCount() != 2) - { - return; - } - - const char* pFontName = pArgs->GetArg(1); - - if (pFontName && *pFontName && *pFontName != '0') - { - string fontFile("@devroot@/"); - fontFile += pFontName; - fontFile += ".bmp"; - - CFFont* pFont = (CFFont*) gEnv->pCryFont->GetFont(pFontName); - if (pFont) - { - pFont->GetFontTexture()->WriteToFile(fontFile.c_str()); - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, "Dumped \"%s\" texture to \"%s\"!", pFontName, fontFile.c_str()); - } - } -} - -static void DumpFontNames([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - string names = gEnv->pCryFont->GetLoadedFontNames(); - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, "Currently loaded fonts: %s", names.c_str()); -} - -static void ReloadFonts([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - gEnv->pCryFont->ReloadAllFonts(); -} -#endif - -namespace -{ - //! Stores paths to styled font assets for a given set of languages - //! This struct stores the XML data contained within the tag of - //! an enclosing definition: - //! - //! - //! - //! - //! - //! - //! - //! - //! - struct FontTagXml - { - //! \return True if all font asset paths are non-empty, false otherwise - bool IsValid() const - { - // Note that "lang" can be empty - return !m_fontFilename.empty() - && !m_boldFontFilename.empty() - && !m_italicFontFilename.empty() - && !m_boldItalicFontFilename.empty(); - } - - string m_lang; //!< Stores a comma-separated list of languages this collection of fonts applies to. - //!< If this is an empty string, it implies that these set of fonts will be applied - //!< by default (when a language is being used but no fonts in the font family are - //!< mapped to that language). - - string m_fontFilename; //!< Font used when no styling is applied. - string m_boldFontFilename; //!< Bold-styled font - string m_italicFontFilename; //!< Italic-styled font - string m_boldItalicFontFilename; //!< Bold-italic-styled font - }; - - //! Stores parsed font family XML data. - //! This struct contains the name of the font family and a list of font - //! file XML data for all the language-specific mappings of this - //! font family. - //! - //! Example XML: - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - //! - struct FontFamilyTagXml - { - //! Returns true if all font file fields were parsed, false otherwise. - bool IsValid() const - { - for (const FontTagXml& fontTagXml : m_fontTagsXml) - { - if (!fontTagXml.IsValid()) - { - return false; - } - } - - // Every font family must have a name - return !m_fontFamilyName.empty(); - } - - string m_fontFamilyName; //!< Value of the "name" font-family tag attribute - AZStd::list m_fontTagsXml; //!< List of child tag data. - }; - - //! Returns true if the XML tree was traversed successfully, false otherwise. - //! - //! Note that, if this function returns true, it simply means that there were - //! no unexpected structure issues with the given XML tree, it doesn't - //! necessarily mean that all the required fields were parsed. - bool ParseFontFamilyXml(const XmlNodeRef& node, FontFamilyTagXml& xmlData) - { - if (!node) - { - return false; - } - - // - if (AZStd::string(node->getTag()) == "fontfamily") - { - const int numAttributes = node->getNumAttributes(); - - if (numAttributes <= 0) - { - // Expecting at least one attribute - return false; - } - - string name; - - for (int i = 0, count = node->getNumAttributes(); i < count; ++i) - { - const char* key = ""; - const char* value = ""; - if (node->getAttributeByIndex(i, &key, &value)) - { - if (string(key) == "name") - { - name = value; - } - else - { - // Unexpected font tag attribute - return false; - } - } - } - - name.Trim(); - if (!name.empty()) - { - xmlData.m_fontFamilyName = name; - } - else - { - // Font family must have a name - return false; - } - } - - // - if (AZStd::string(node->getTag()) == "font") - { - xmlData.m_fontTagsXml.push_back(FontTagXml()); - - string lang; - for (int i = 0, count = node->getNumAttributes(); i < count; ++i) - { - const char* key = ""; - const char* value = ""; - if (node->getAttributeByIndex(i, &key, &value)) - { - if (string(key) == "lang") - { - lang = value; - } - else - { - // Unexpected font tag attribute - return false; - } - } - } - - lang.Trim(); - if (!lang.empty()) - { - xmlData.m_fontTagsXml.back().m_lang = lang; - } - } - - // - else if (AZStd::string(node->getTag()) == "file") - { - const int numAttributes = node->getNumAttributes(); - - if (numAttributes <= 0) - { - // Expecting at least one attribute - return false; - } - - string path; - string tags; - - for (int i = 0, count = node->getNumAttributes(); i < count; ++i) - { - const char* key = ""; - const char* value = ""; - if (node->getAttributeByIndex(i, &key, &value)) - { - if (string(key) == "path") - { - path = value; - } - else if (string(key) == "tags") - { - tags = value; - } - else - { - // Unexpected font tag attribute - return false; - } - } - } - - tags.Trim(); - if (tags.empty()) - { - xmlData.m_fontTagsXml.back().m_fontFilename = path; - } - else if (tags == "b") - { - xmlData.m_fontTagsXml.back().m_boldFontFilename = path; - } - else if (tags == "i") - { - xmlData.m_fontTagsXml.back().m_italicFontFilename = path; - } - else - { - // We'll just assume any other tag indicates bold italic - xmlData.m_fontTagsXml.back().m_boldItalicFontFilename = path; - } - } - - for (int i = 0, count = node->getChildCount(); i < count; ++i) - { - XmlNodeRef child = node->getChild(i); - if (!ParseFontFamilyXml(child, xmlData)) - { - return false; - } - } - - return true; - } - - //! Only attempt XML file load if file exists. - //! There are use-cases where the XML path is not fully known (such as - //! when referencing font family names from font family XML files), and - //! attempting to load the XML files directly via ISystem() methods can - //! produce a lot of warning noise. - XmlNodeRef SafeLoadXmlFromFile(const string& xmlPath) - { - if (gEnv->pCryPak->IsFileExist(xmlPath.c_str())) - { - return GetISystem()->LoadXmlFromFile(xmlPath.c_str()); - } - - return XmlNodeRef(); - } - -} - -CCryFont::CCryFont(ISystem* pSystem) - : m_pSystem(pSystem) - , m_fonts() - , m_rndPropIsRGBA(false) - , m_rndPropHalfTexelOffset(0.5f) -{ - assert(m_pSystem); - - CryLogAlways("Using FreeType %d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH); - - // Persist fonts for application lifetime to prevent unnecessary work - REGISTER_CVAR(r_persistFontFamilies, r_persistFontFamilies, VF_NULL, "Persist loaded font families for lifetime of application."); - -#if !defined(_RELEASE) - REGISTER_COMMAND("r_DumpFontTexture", DumpFontTexture, 0, - "Dumps the specified font's texture to a bitmap file\n" - "Use r_DumpFontTexture to get the loaded font names\n" - "Usage: r_DumpFontTexture "); - REGISTER_COMMAND("r_DumpFontNames", DumpFontNames, 0, - "Logs a list of fonts currently loaded"); - REGISTER_COMMAND("r_ReloadFonts", ReloadFonts, VF_NULL, - "Reload all fonts"); -#endif -} - -CCryFont::~CCryFont() -{ - // Persist fonts for application lifetime to prevent unnecessary work - m_persistedFontFamilies.clear(); - - for (FontMapItor it = m_fonts.begin(), itEnd = m_fonts.end(); it != itEnd; ) - { - CFFont* pFont = it->second; - ++it; // iterate as Release() below will remove font from the map - SAFE_RELEASE(pFont); - } -} - -void CCryFont::Release() -{ - delete this; -} - -IFFont* CCryFont::NewFont(const char* pFontName) -{ - string name = pFontName; - name.MakeLower(); - - FontMapItor it = m_fonts.find(CONST_TEMP_STRING(name.c_str())); - if (it != m_fonts.end()) - { - return it->second; - } - - CFFont* pFont = new CFFont(m_pSystem, this, name.c_str()); - m_fonts.insert(FontMapItor::value_type(name, pFont)); - return pFont; -} - -IFFont* CCryFont::GetFont(const char* pFontName) const -{ - FontMapConstItor it = m_fonts.find(CONST_TEMP_STRING(string(pFontName).MakeLower())); - return it != m_fonts.end() ? it->second : 0; -} - -FontFamilyPtr CCryFont::LoadFontFamily(const char* pFontFamilyName) -{ - FontFamilyPtr fontFamily(nullptr); - string fontFamilyPath; - string fontFamilyFullPath; - - XmlNodeRef root = LoadFontFamilyXml(pFontFamilyName, fontFamilyPath, fontFamilyFullPath); - - if (root) - { - FontFamilyTagXml xmlData; - const bool parseSuccess = ParseFontFamilyXml(root, xmlData); - if (parseSuccess && xmlData.IsValid()) - { - const char* currentLanguage = gEnv->pSystem->GetLocalizationManager()->GetLanguage(); - FontTagXml* defaultFont = nullptr; - FontTagXml* langSpecificFont = nullptr; - - // Note that we don't break out of this for-loop early because we - // want to find both the default font family and the - // language-specific font family. We prefer the lang-specific - // family but will fall back on the default if it doesn't exist. - for (FontTagXml& fontTagXml : xmlData.m_fontTagsXml) - { - if (fontTagXml.m_lang.empty()) - { - defaultFont = &fontTagXml; - } - else - { - int searchPos = 0; - string langToken; - - // "lang" font-tag attribute could be comma-separated - while (!(langToken = fontTagXml.m_lang.Tokenize(",", searchPos)).empty()) - { - if (langToken.Trim() == currentLanguage) - { - langSpecificFont = &fontTagXml; - break; - } - } - } - } - - if (langSpecificFont || defaultFont) - { - // Prefer lang-specific font-family over default, if it exists - FontTagXml* fontTagXml = langSpecificFont ? langSpecificFont : defaultFont; - - // Pre-pend font family's path to make font family XML paths - // relative to font family file - fontTagXml->m_fontFilename = fontFamilyPath + fontTagXml->m_fontFilename; - fontTagXml->m_boldFontFilename = fontFamilyPath + fontTagXml->m_boldFontFilename; - fontTagXml->m_italicFontFilename = fontFamilyPath + fontTagXml->m_italicFontFilename; - fontTagXml->m_boldItalicFontFilename = fontFamilyPath + fontTagXml->m_boldItalicFontFilename; - - IFFont* normal = LoadFont(fontTagXml->m_fontFilename.c_str()); - IFFont* bold = LoadFont(fontTagXml->m_boldFontFilename.c_str()); - IFFont* italic = LoadFont(fontTagXml->m_italicFontFilename.c_str()); - IFFont* boldItalic = LoadFont(fontTagXml->m_boldItalicFontFilename.c_str()); - - // Only continue if all fonts were created successfully - if (normal && bold && italic && boldItalic) - { - fontFamily.reset(new FontFamily(), - [this](FontFamily* pFontFamily) - { - ReleaseFontFamily(pFontFamily); - }); - - // Map the font family name both by path and by name defined - // within the Font Family XML itself. This allows font - // families to also be referenced simply by name. - if (!AddFontFamilyToMaps(fontFamilyFullPath, xmlData.m_fontFamilyName, fontFamily)) - { - SAFE_RELEASE(normal); - SAFE_RELEASE(bold); - SAFE_RELEASE(italic); - SAFE_RELEASE(boldItalic); - - return nullptr; - } - - fontFamily->familyName = xmlData.m_fontFamilyName; - fontFamily->normal = normal; - fontFamily->bold = bold; - fontFamily->italic = italic; - fontFamily->boldItalic = boldItalic; - } - else - { - SAFE_RELEASE(normal); - SAFE_RELEASE(bold); - SAFE_RELEASE(italic); - SAFE_RELEASE(boldItalic); - } - } - } - } - - if (!fontFamily) - { - // Unable to load font family XML, so load font normally and associate - // it with a font family - IFFont* pFont = LoadFont(pFontFamilyName); - - if (pFont) - { - // Create a font family from a single font by assigning all the - // font family stylings to the same font - fontFamily.reset(new FontFamily(), - [this](FontFamily* pFontFamily) - { - ReleaseFontFamily(pFontFamily); - }); - - // Use filepath as familyName so font loading/unloading doesn't break with duplicate file names - fontFamily->familyName = pFontFamilyName; - - if (!AddFontFamilyToMaps(pFontFamilyName, fontFamily->familyName, fontFamily)) - { - SAFE_RELEASE(pFont); - - return nullptr; - } - - // Assign all stylings to the same font - fontFamily->normal = pFont; - fontFamily->bold = pFont; - fontFamily->italic = pFont; - fontFamily->boldItalic = pFont; - - // The other three stylings need to have their ref count - // incremented (even though in this particular case its all the - // same font) because when ReleaseFontFamily executes all fonts - // in the family will be (corresondingly) Release'd. - fontFamily->bold->AddRef(); - fontFamily->italic->AddRef(); - fontFamily->boldItalic->AddRef(); - } - } - - // Persist fonts for application lifetime to prevent unnecessary work - if (r_persistFontFamilies > 0) - { - m_persistedFontFamilies.emplace_back(FontFamilyPtr(fontFamily)); - } - - return fontFamily; -} - -FontFamilyPtr CCryFont::GetFontFamily(const char* pFontFamilyName) -{ - FontFamilyPtr fontFamily = nullptr; - - // The given string could either be: a font family name (defined in font - // family XML), a file path (for regular fonts mapped as font families), - // or just the filename of a font itself. Fonts are mapped by font family - // name or by filepath, so attempt lookup using the map first since it's - // the fastest. - string loweredName = string(pFontFamilyName).Trim().MakeLower(); - auto it = m_fontFamilies.find(PathUtil::MakeGamePath(loweredName).c_str()); - if (it != m_fontFamilies.end()) - { - fontFamily = FontFamilyPtr(it->second); - } - else - { - // Iterate through all fonts, returning the first match where simply - // the filename of a font could be a match. This case will likely be - // hit when text markup references a font that doesn't belong to a - // font family. - for (const auto& fontFamilyIter : m_fontFamilies) - { - const AZStd::string& mappedFontFamilyName = fontFamilyIter.first; - string mappedFilenameNoExtension = PathUtil::GetFileName(mappedFontFamilyName.c_str()); - - string searchStringFilenameNoExtension = PathUtil::GetFileName(loweredName); - - if (mappedFilenameNoExtension == searchStringFilenameNoExtension) - { - fontFamily = FontFamilyPtr(fontFamilyIter.second); - break; - } - } - } - - return fontFamily; -} - -void CCryFont::AddCharsToFontTextures(FontFamilyPtr pFontFamily, const char* pChars, int glyphSizeX, int glyphSizeY) -{ - pFontFamily->normal->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY); - pFontFamily->bold->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY); - pFontFamily->italic->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY); - pFontFamily->boldItalic->AddCharsToFontTexture(pChars, glyphSizeX, glyphSizeY); -} - -void CCryFont::SetRendererProperties(IRenderer* pRenderer) -{ - if (pRenderer) - { - m_rndPropIsRGBA = (pRenderer->GetFeatures() & RFT_RGBA) != 0; - m_rndPropHalfTexelOffset = 0.0f; - } -} - -void CCryFont::GetMemoryUsage(ICrySizer* pSizer) const -{ - if (!pSizer->Add(*this)) - { - return; - } - - pSizer->AddObject(m_fonts); -} - -string CCryFont::GetLoadedFontNames() const -{ - string ret; - for (FontMapConstItor it = m_fonts.begin(), itEnd = m_fonts.end(); it != itEnd; ++it) - { - CFFont* pFont = it->second; - if (pFont) - { - if (!ret.empty()) - { - ret += ","; - } - ret += pFont->GetName(); - } - } - return ret; -} - -void CCryFont::OnLanguageChanged() -{ - ReloadAllFonts(); - - EBUS_EVENT(LanguageChangeNotificationBus, LanguageChanged); -} - -void CCryFont::ReloadAllFonts() -{ - // Persist fonts for application lifetime to prevent unnecessary work - m_persistedFontFamilies.clear(); - - AZStd::list fontFamilyFilenames; - AZStd::list fontFamilyWeakPtrs; - - // Iterate through all currently loaded font families - for (auto it : m_fontFamilyReverseLookup) - { - fontFamilyWeakPtrs.push_back(it.first); - fontFamilyFilenames.push_back(it.second->first); - } - - // Release font-family resources and unmap them - for (auto fontFamily : fontFamilyWeakPtrs) - { - ReleaseFontFamily(fontFamily); - } - - // Reload the font families - for (auto familyFilename : fontFamilyFilenames) - { - LoadFontFamily(familyFilename.c_str()); - } - - // All UI text components need to reload their font assets (both in-game - // and in-editor). - EBUS_EVENT(FontNotificationBus, OnFontsReloaded); -} - -void CCryFont::UnregisterFont(const char* pFontName) -{ - FontMapItor it = m_fonts.find(CONST_TEMP_STRING(pFontName)); - -#if defined(AZ_ENABLE_TRACING) - IFFont* fontPtr = it->second; -#endif - - if (it != m_fonts.end()) - { - m_fonts.erase(it); - } - -#if defined(AZ_ENABLE_TRACING) - // Make sure the font being released isn't currently in use by a font family. - // If it is, the FontFamily will have a dangling pointer and will cause a - // crash when the FontFamily eventually gets released. - for (auto reverseMapEntry : m_fontFamilyReverseLookup) - { - FontFamily* fontFamily = reverseMapEntry.first; - AZ_Assert(fontFamily->normal != fontPtr, - "The following font is being freed but still in use by a FontFamily: %s", - pFontName); - AZ_Assert(fontFamily->italic != fontPtr, - "The following font is being freed but still in use by a FontFamily: %s", - pFontName); - AZ_Assert(fontFamily->bold != fontPtr, - "The following font is being freed but still in use by a FontFamily: %s", - pFontName); - AZ_Assert(fontFamily->boldItalic != fontPtr, - "The following font is being freed but still in use by a FontFamily: %s", - pFontName); - } -#endif -} - -IFFont* CCryFont::LoadFont(const char* pFontName) -{ - string fontName = pFontName; - fontName.MakeLower(); - - IFFont* font = GetFont(fontName); - if (font) - { - font->AddRef(); // use existing loaded font - } - else - { - // attempt to create and load a new font, use the font pathname as the font name - font = NewFont(fontName); - if (!font) - { - string errorMsg = "Error creating a new font named "; - errorMsg += fontName; - errorMsg += "."; - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg.c_str()); - } - else - { - // creating font adds one to its refcount so no need for AddRef here - if (!font->Load(fontName)) - { - string errorMsg = "Error loading a font from "; - errorMsg += fontName; - errorMsg += "."; - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, errorMsg); - font->Release(); - font = nullptr; - } - } - } - - return font; -} - -void CCryFont::ReleaseFontFamily(FontFamily* pFontFamily) -{ - // Ensure that Font Family was mapped prior to destruction - const bool isMapped = m_fontFamilyReverseLookup.find(pFontFamily) != m_fontFamilyReverseLookup.end(); - if (!isMapped) - { - return; - } - - // Note that the FontFamily is mapped both by filename and by "family name" - auto it = m_fontFamilyReverseLookup[pFontFamily]; - m_fontFamilies.erase(it); - string familyName(pFontFamily->familyName); - m_fontFamilies.erase(familyName.MakeLower().c_str()); - - // Reverse lookup is used to avoid needing to store filename path with - // the font family, so we need to remove that entry also. - m_fontFamilyReverseLookup.erase(pFontFamily); - - SAFE_RELEASE(pFontFamily->normal); - SAFE_RELEASE(pFontFamily->bold); - SAFE_RELEASE(pFontFamily->italic); - SAFE_RELEASE(pFontFamily->boldItalic); -} - -bool CCryFont::AddFontFamilyToMaps(const char* pFontFamilyFilename, const char* pFontFamilyName, FontFamilyPtr fontFamily) -{ - if (!pFontFamilyFilename || !pFontFamilyName || !fontFamily.get()) - { - return false; - } - - // We don't support "updating" mapped values. - AZStd::string loweredFilename(PathUtil::MakeGamePath(string(pFontFamilyFilename)).c_str()); - AZStd::to_lower(loweredFilename.begin(), loweredFilename.end()); - if (m_fontFamilies.find(loweredFilename) != m_fontFamilies.end()) - { - string warnMsg; - warnMsg.Format("Couldn't load Font Family '%s': already loaded", pFontFamilyFilename); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str()); - return false; - } - - // Similarly, we don't support Font Family XMLs that have the same font - // family name (we assume all Font Family names are unique). - AZStd::string loweredFontFamilyName(pFontFamilyName); - AZStd::to_lower(loweredFontFamilyName.begin(), loweredFontFamilyName.end()); - if (m_fontFamilies.find(loweredFontFamilyName) != m_fontFamilies.end()) - { - string warnMsg; - warnMsg.Format("Couldn't load Font Family '%s': already loaded", pFontFamilyName); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str()); - return false; - } - - // First, insert by filename - AZStd::pair> insertPair(loweredFilename, fontFamily); - auto iterPosition = m_fontFamilies.insert(insertPair).first; - m_fontFamilyReverseLookup[fontFamily.get()] = iterPosition; - - // Then, by Font Family name - AZStd::pair> nameInsertPair(loweredFontFamilyName, fontFamily); - m_fontFamilies.insert(nameInsertPair); - - return true; -} - -XmlNodeRef CCryFont::LoadFontFamilyXml(const char* pFontFamilyName, string& outputDirectory, string& outputFullPath) -{ - outputFullPath = pFontFamilyName; - outputDirectory = PathUtil::GetPath(pFontFamilyName); - XmlNodeRef root = SafeLoadXmlFromFile(outputFullPath); - - // When parsing a tag in markup, only the font name is given and - // not a path, so we try to build a "best guess" path from the name. - if (!root) - { - string fileNoExtension(PathUtil::GetFileName(pFontFamilyName)); - string fileExtension(PathUtil::GetExt(pFontFamilyName)); - - if (fileExtension.empty()) - { - fileExtension = ".fontfamily"; - } - - // Try: "fonts/fontName.fontfamily" - outputDirectory = string("fonts/"); - outputFullPath = outputDirectory + fileNoExtension + fileExtension; - root = SafeLoadXmlFromFile(outputFullPath); - - // Finally, try: "fonts/fontName/fontName.fontfamily" - if (!root) - { - outputDirectory = string("fonts/") + fileNoExtension + "/"; - outputFullPath = outputDirectory + fileNoExtension + fileExtension; - root = SafeLoadXmlFromFile(outputFullPath); - } - } - - return root; -} - -#endif - diff --git a/Code/CryEngine/CryFont/CryFont.def b/Code/CryEngine/CryFont/CryFont.def deleted file mode 100644 index 43bfe0b13d..0000000000 --- a/Code/CryEngine/CryFont/CryFont.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS - ModuleInitISystem @2 - CryModuleGetMemoryInfo @8 diff --git a/Code/CryEngine/CryFont/CryFont.h b/Code/CryEngine/CryFont/CryFont.h deleted file mode 100644 index 726818f5a7..0000000000 --- a/Code/CryEngine/CryFont/CryFont.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYFONT_CRYFONT_H -#define CRYINCLUDE_CRYFONT_CRYFONT_H -#pragma once - - -#if !defined(USE_NULLFONT_ALWAYS) - -#include -#include -#include -#include - -class CFFont; - - -class CCryFont - : public ICryFont -{ - friend class CFFont; - -public: - - static const Vec2i defaultGlyphSize; //!< Default glyph size indicates that glyphs in the font texture - //!< should be rendered at the maximum resolution supported by - //!< the font texture's glyph cell/slot configuration (configured - //!< via font XML). - -public: - CCryFont(ISystem* pSystem); - virtual ~CCryFont(); - - virtual void Release(); - virtual IFFont* NewFont(const char* pFontName); - virtual IFFont* GetFont(const char* pFontName) const; - virtual FontFamilyPtr LoadFontFamily(const char* pFontFamilyName) override; - virtual FontFamilyPtr GetFontFamily(const char* pFontFamilyName) override; - virtual void AddCharsToFontTextures(FontFamilyPtr pFontFamily, const char* pChars, int glyphSizeX = ICryFont::defaultGlyphSizeX, int glyphSizeY = ICryFont::defaultGlyphSizeY) override; - virtual void SetRendererProperties(IRenderer* pRenderer); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual string GetLoadedFontNames() const; - virtual void OnLanguageChanged() override; - virtual void ReloadAllFonts() override; - -public: - void UnregisterFont(const char* pFontName); - bool RndPropIsRGBA() const { return m_rndPropIsRGBA; } - float RndPropHalfTexelOffset() const { return m_rndPropHalfTexelOffset; } - -private: - typedef std::map FontMap; - typedef FontMap::iterator FontMapItor; - typedef FontMap::const_iterator FontMapConstItor; - - typedef AZStd::map> FontFamilyMap; - typedef AZStd::map FontFamilyReverseLookupMap; - -private: - //! Convenience method for loading fonts - IFFont* LoadFont(const char* fontName); - - //! Called when final FontFamily shared_ptr is destroyed; do not call directly. - void ReleaseFontFamily(FontFamily* pFontFamily); - - //! Adds new entries into both font family maps for the given font family - //! - //! Note that it's not possible to update Font Family mappings with this - //! method. The only way to do that would be to release the font family - //! and re-load it with the new values. - //! - //! \return True only if the Font Family was added to the maps, false for all other cases (such as - //! when the font family is already mapped). - bool AddFontFamilyToMaps(const char* pFontFamilyFilename, const char* pFontFamilyName, FontFamilyPtr fontFamily); - - //! Internal method that (possibly) makes several attempts at locating and loading a given font family XML. - //! \param pFontFamilyName The name of the font family, or path to a font family file. - //! \param outputDirectory Path to loaded font family (no filename), may need resolving with PathUtil::MakeGamePath. - //! \param outputFullPath Full path to loaded font family, may need resolving with PathUtil::MakeGamePath. - XmlNodeRef LoadFontFamilyXml(const char* pFontFamilyName, string& outputDirectory, string& outputFullPath); - -private: - FontMap m_fonts; - FontFamilyMap m_fontFamilies; //!< Map font family names to weak ptrs so we can construct shared_ptrs but not keep a ref ourselves. - FontFamilyReverseLookupMap m_fontFamilyReverseLookup; // m_persistedFontFamilies; //!< Stores persisted fonts (if "persist font families" is enabled) - -}; - -#endif - -#endif // CRYINCLUDE_CRYFONT_CRYFONT_H diff --git a/Code/CryEngine/CryFont/CryFont.rc b/Code/CryEngine/CryFont/CryFont.rc deleted file mode 100644 index 5730d0a537..0000000000 --- a/Code/CryEngine/CryFont/CryFont.rc +++ /dev/null @@ -1,111 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Russian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/CryFont/CryFont_precompiled.cpp b/Code/CryEngine/CryFont/CryFont_precompiled.cpp deleted file mode 100644 index 235fe8e053..0000000000 --- a/Code/CryEngine/CryFont/CryFont_precompiled.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CryFont_precompiled.h" diff --git a/Code/CryEngine/CryFont/CryFont_precompiled.h b/Code/CryEngine/CryFont/CryFont_precompiled.h deleted file mode 100644 index e37845aa35..0000000000 --- a/Code/CryEngine/CryFont/CryFont_precompiled.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#define CRYFONT_EXPORTS - -#include - -#include - -#include -#include -#include -#include - -#define USE_NULLFONT - -#if defined(DEDICATED_SERVER) -#define USE_NULLFONT_ALWAYS 1 -#endif - diff --git a/Code/CryEngine/CryFont/FBitmap.h b/Code/CryEngine/CryFont/FBitmap.h deleted file mode 100644 index 93f5505726..0000000000 --- a/Code/CryEngine/CryFont/FBitmap.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef CRYINCLUDE_CRYFONT_FBITMAP_H -#define CRYINCLUDE_CRYFONT_FBITMAP_H - - -class CFBitmap -{ -public: - CFBitmap(); - ~CFBitmap(); - - int Blur(int iIterations); - int Scale(float fScaleX, float fScaleY); - - int BlitFrom(CFBitmap* pSrc, int iSX, int iSY, int iDX, int iDY, int iW, int iH); - int BlitTo(CFBitmap* pDst, int iDX, int iDY, int iSX, int iSY, int iW, int iH); - - int Create(int iWidth, int iHeight); - int Release(); - - int SaveBitmap(const string& szFileName); - int Get32Bpp(unsigned int** pBuffer) - { - (*pBuffer) = new unsigned int[m_iWidth * m_iHeight]; - - if (!(*pBuffer)) - { - return 0; - } - - int iDataSize = m_iWidth * m_iHeight; - - for (int i = 0; i < iDataSize; i++) - { - (*pBuffer)[i] = (m_pData[i] << 24) | (m_pData[i] << 16) | (m_pData[i] << 8) | (m_pData[i]); - } - - return 1; - } - - int GetWidth() { return m_iWidth; } - int GetHeight() { return m_iHeight; } - - void SetRenderData(void* pRenderData) { m_pIRenderData = pRenderData; }; - void* GetRenderData() { return m_pIRenderData; }; - - void GetMemoryUsage (class ICrySizer* pSizer); - - unsigned char* GetData() { return m_pData; } - -public: - - int m_iWidth; - int m_iHeight; - - unsigned char* m_pData; - void* m_pIRenderData; -}; - - -#endif // CRYINCLUDE_CRYFONT_FBITMAP_H diff --git a/Code/CryEngine/CryFont/FFont.cpp b/Code/CryEngine/CryFont/FFont.cpp deleted file mode 100644 index c028a0827e..0000000000 --- a/Code/CryEngine/CryFont/FFont.cpp +++ /dev/null @@ -1,1550 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Font class. - - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "FFont.h" -#include "CryFont.h" -#include "FontTexture.h" -#include "UnicodeIterator.h" - -#include -#include - -static ColorB ColorTable[10] = -{ - ColorB(0x00, 0x00, 0x00), // black - ColorB(0xff, 0xff, 0xff), // white - ColorB(0x00, 0x00, 0xff), // blue - ColorB(0x00, 0xff, 0x00), // green - ColorB(0xff, 0x00, 0x00), // red - ColorB(0x00, 0xff, 0xff), // cyan - ColorB(0xff, 0xff, 0x00), // yellow - ColorB(0xff, 0x00, 0xff), // purple - ColorB(0xff, 0x80, 0x00), // orange - ColorB(0x8f, 0x8f, 0x8f), // grey -}; - -static const int TabCharCount = 4; -static const size_t MsgBufferSize = 1024; -static const size_t MaxDrawVBQuads = 128; - -CFFont::CFFont(ISystem* pSystem, CCryFont* pCryFont, const char* pFontName) - : m_name(pFontName) - , m_curPath("") - , m_pFontTexture(0) - , m_fontBufferSize(0) - , m_pFontBuffer(0) - , m_texID(-1) - , m_textureVersion(0) - , m_pSystem(pSystem) - , m_pCryFont(pCryFont) - , m_fontTexDirty(false) - , m_effects() - , m_pDrawVB(0) - , m_nRefCount(0) - , m_monospacedFont(false) -{ - assert(m_name.c_str()); - assert(m_pSystem); - assert(m_pCryFont); - - // create default effect - SEffect* pEffect = AddEffect("default"); - pEffect->AddPass(); - - m_pDrawVB = new SVF_P3F_C4B_T2F[MaxDrawVBQuads * 6]; - - AddRef(); -} - -CFFont::~CFFont() -{ - // The font should already be unregistered through a call to - // CFFont::Release() at this point. - CRY_ASSERT(m_pCryFont == nullptr); - - Free(); - - SAFE_DELETE_ARRAY(m_pDrawVB); -} - -int32 CFFont::AddRef() -{ - int32 nRef = CryInterlockedIncrement(&m_nRefCount); - return nRef; -} - -int32 CFFont::Release() -{ - if (m_nRefCount > 0) - { - int32 nRef = CryInterlockedDecrement(&m_nRefCount); - if (nRef < 0) - { - CryFatalError("CBaseResource::Release() called more than once!"); - } - - if (nRef <= 0) - { - if (m_pCryFont) - { - AZStd::lock_guard locker(m_fontMutex); - - // Unregister font so no one can increase it's ref count while it is queued for deletion - m_pCryFont->UnregisterFont(m_name); - m_pCryFont = nullptr; - } - - if (gEnv->pRenderer) - { - gEnv->pRenderer->DeleteFont(this); - } - return 0; - } - return nRef; - } - return 0; -} - -// Load a font from a TTF file -bool CFFont::Load(const char* pFontFilePath, unsigned int width, unsigned int height, unsigned int widthNumSlots, unsigned int heightNumSlots, unsigned int flags, float sizeRatio) -{ - if (!pFontFilePath) - { - return false; - } - - Free(); - - auto pPak = gEnv->pCryPak; - - string fullFile; - if (pPak->IsAbsPath(pFontFilePath)) - { - fullFile = pFontFilePath; - } - else - { - fullFile = m_curPath + pFontFilePath; - } - - int iSmoothMethod = (flags & TTFFLAG_SMOOTH_MASK) >> TTFFLAG_SMOOTH_SHIFT; - int iSmoothAmount = (flags & TTFFLAG_SMOOTH_AMOUNT_MASK) >> TTFFLAG_SMOOTH_AMOUNT_SHIFT; - - AZ::IO::HandleType fileHandle = pPak->FOpen(fullFile.c_str(), "rb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - size_t fileSize = pPak->FGetSize(fileHandle); - if (!fileSize) - { - pPak->FClose(fileHandle); - return false; - } - - unsigned char* pBuffer = new unsigned char[fileSize]; - if (!pPak->FReadRaw(pBuffer, fileSize, 1, fileHandle)) - { - pPak->FClose(fileHandle); - delete [] pBuffer; - return false; - } - - pPak->FClose(fileHandle); - - if (!m_pFontTexture) - { - m_pFontTexture = new CFontTexture(); - } - - if (!m_pFontTexture || !m_pFontTexture->CreateFromMemory(pBuffer, (int)fileSize, width, height, iSmoothMethod, iSmoothAmount, widthNumSlots, heightNumSlots, sizeRatio)) - { - delete [] pBuffer; - return false; - } - - m_monospacedFont = m_pFontTexture->GetMonospaced(); - m_pFontBuffer = pBuffer; - m_fontBufferSize = fileSize; - m_fontTexDirty = false; - m_sizeRatio = sizeRatio; - - InitCache(); - - return true; -} - - -void CFFont::Free() -{ - IRenderer* pRenderer = gEnv->pRenderer; - if (m_texID >= 0 && pRenderer) - { - pRenderer->RemoveTexture(m_texID); - m_texID = -1; - m_textureVersion = 0; - } - - delete m_pFontTexture; - m_pFontTexture = 0; - - delete [] m_pFontBuffer; - m_pFontBuffer = 0; -} - -void CFFont::DrawString(float x, float y, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return; - } - - DrawStringUInternal(x, y, 1.0f, pStr, asciiMultiLine, ctx); -} - -void CFFont::DrawString(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return; - } - - DrawStringUInternal(x, y, z, pStr, asciiMultiLine, ctx); -} - -void CFFont::DrawStringUInternal(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr || !m_pFontTexture || ctx.m_fxIdx >= m_effects.size() || m_effects[ctx.m_fxIdx].m_passes.empty(), 0) - { - return; - } - - AZStd::lock_guard locker(m_fontMutex); - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - pRenderer->DrawStringU(this, x, y, z, pStr, asciiMultiLine, ctx); -} - -ILINE uint32 COLCONV(uint32 clr) -{ - return ((clr & 0xff00ff00) | ((clr & 0xff0000) >> 16) | ((clr & 0xff) << 16)); -} - -void CFFont::RenderCallback(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - AZStd::lock_guard locker(m_fontMutex); - - const size_t fxSize = m_effects.size(); - - IF (fxSize && m_texID == -1 && !InitTexture(), 0) - { - return; - } - - // if the font is about to be deleted then m_pCryFont can be nullptr - if (!m_pCryFont) - { - return; - } - - SVF_P3F_C4B_T2F* pVertex = m_pDrawVB; - size_t vbOffset = 0; - - bool isFontRenderStateSet = false; - TransformationMatrices backupSceneMatrices; - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - int baseState = ctx.m_baseState; - bool overrideViewProjMatrices = ctx.m_overrideViewProjMatrices; - int texId = m_texID; - - // Local function to share code needed when we render the vertex buffer so far - AZStd::function RenderVB = [&pVertex, &vbOffset, pRenderer] - { - gEnv->pRenderer->DrawDynVB(pVertex, 0, vbOffset, 0, prtTriangleList); - vbOffset = 0; - }; - - // Local function that is passed into CreateQuadsForText as the AddQuad function - AddFunction AddQuad = [&pVertex, &vbOffset, RenderVB] - (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const Vec2& tc0, const Vec2& tc1, const Vec2& tc2, const Vec2& tc3, uint32 packedColor) - { - // define char quad - pVertex[vbOffset].xyz = v0; - pVertex[vbOffset].color.dcolor = packedColor; - pVertex[vbOffset].st = tc0; - - pVertex[vbOffset + 1].xyz = v1; - pVertex[vbOffset + 1].color.dcolor = packedColor; - pVertex[vbOffset + 1].st = tc1; - - pVertex[vbOffset + 2].xyz = v2; - pVertex[vbOffset + 2].color.dcolor = packedColor; - pVertex[vbOffset + 2].st = tc2; - - pVertex[vbOffset + 3].xyz = v2; - pVertex[vbOffset + 3].color.dcolor = packedColor; - pVertex[vbOffset + 3].st = tc2; - - pVertex[vbOffset + 4].xyz = v3; - pVertex[vbOffset + 4].color.dcolor = packedColor; - pVertex[vbOffset + 4].st = tc3; - - pVertex[vbOffset + 5].xyz = v0; - pVertex[vbOffset + 5].color.dcolor = packedColor; - pVertex[vbOffset + 5].st = tc0; - - vbOffset += 6; - - if (vbOffset >= MaxDrawVBQuads * 6) - { - RenderVB(); - } - }; - - // Local function that is passed into CreateQuadsForText as the BeginPass function - BeginPassFunction BeginPass = [&pVertex, &vbOffset, &isFontRenderStateSet, &backupSceneMatrices, texId, pRenderer, baseState, RenderVB, overrideViewProjMatrices] - (const SRenderingPass* pPass) - { - // We don't want to set this state before the call to CreateQuadsForText since that calls Prepare, - // which is needed before FontSetTexture - if (!isFontRenderStateSet) - { - pRenderer->FontSetTexture(texId, FILTER_TRILINEAR); - pRenderer->FontSetRenderingState(overrideViewProjMatrices, backupSceneMatrices); - gEnv->pRenderer->FontSetBlending(pPass->m_blendSrc, pPass->m_blendDest, baseState); - isFontRenderStateSet = true; - } - - if (vbOffset > 0) - { - RenderVB(); - } - - gEnv->pRenderer->FontSetBlending(pPass->m_blendSrc, pPass->m_blendDest, baseState); - }; - - CreateQuadsForText(x, y, z, pStr, asciiMultiLine, ctx, AddQuad, BeginPass); - - if (vbOffset > 0) - { - RenderVB(); - } - - // restore the old states - if (isFontRenderStateSet) - { - pRenderer->FontRestoreRenderingState(overrideViewProjMatrices, backupSceneMatrices); - } -} - -Vec2 CFFont::GetTextSize(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - IF (!pStr, 0) - { - return Vec2(0.0f, 0.0f); - } - - return GetTextSizeUInternal(pStr, asciiMultiLine, ctx); -} - -Vec2 CFFont::GetTextSizeUInternal(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - const size_t fxSize = m_effects.size(); - - IF (!pStr || !m_pFontTexture || !fxSize, 0) - { - return Vec2(0, 0); - } - - AZStd::lock_guard locker(m_fontMutex); - - Prepare(pStr, false, ctx.m_requestSize); - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - // This is the "logical" size of the font (in pixels). The actual size of - // the glyphs in the font texture may have additional scaling applied or - // could have been re-rendered at a different size. - Vec2 size = ctx.m_size; - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - // This scaling takes into account the logical size of the font relative - // to any additional scaling applied (such as from "size ratio"). - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - - float maxW = 0; - float maxH = 0; - - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (size_t i = 0, numPasses = fx.m_passes.size(); i < numPasses; ++i) - { - const SRenderingPass* pPass = &fx.m_passes[numPasses - i - 1]; - - // gather pass data - Vec2 offset = pPass->m_posOffset; - - float charX = offset.x; - float charY = offset.y + size.y; - - if (charY > maxH) - { - maxH = charY; - } - - // parse the string, ignoring control characters - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - - ++pChar; - } - case '\n': - { - if (charX > maxW) - { - maxW = charX; - } - - charX = offset.x; - charY += size.y; - - if (charY > maxH) - { - maxH = charY; - } - - continue; - } - break; - case '\r': - { - if (charX > maxW) - { - maxW = charX; - } - - charX = offset.x; - continue; - } - break; - case '\t': - { - if (ctx.m_proportional) - { - charX += TabCharCount * size.x * FONT_SPACE_SIZE; - } - else - { - charX += TabCharCount * size.x * ctx.m_widthScale; - } - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i requestSize = rerenderGlyphs ? ctx.m_requestSize : CCryFont::defaultGlyphSize; - int horizontalAdvance = m_pFontTexture->GetHorizontalAdvance(ch, requestSize); - float advance; - - if (ctx.m_proportional) - { - advance = horizontalAdvance * scaleInfo.scale.x; - } - else - { - advance = size.x * ctx.m_widthScale; - } - - // Adjust "advance" here for kerning purposes - Vec2 kerningOffset(Vec2_Zero); - if (ctx.m_kerningEnabled && nextCh) - { - kerningOffset = m_pFontTexture->GetKerning(ch, nextCh) * scaleInfo.scale.x; - } - - // Adjust char width with tracking only if there is a next character - if (nextCh) - { - charX += ctx.m_tracking; - } - - charX += advance + kerningOffset.x; - } - - if (charX > maxW) - { - maxW = charX; - } - } - - return Vec2(maxW, maxH); -} - -uint32 CFFont::GetNumQuadsForText(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - uint32 numQuads = 0; - - const size_t fxSize = m_effects.size(); - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (size_t j = 0, numPasses = fx.m_passes.size(); j < numPasses; ++j) - { - size_t i = numPasses - j - 1; - bool drawFrame = ctx.m_framed && i == numPasses - 1; - - if (drawFrame) - { - ++numQuads; - } - - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - { - continue; - } - break; - case '\r': - { - continue; - } - break; - case '\t': - { - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - ++numQuads; - } - } - - return numQuads; -} - -uint32 CFFont::WriteTextQuadsToBuffers(SVF_P2F_C4B_T2F_F4B* verts, uint16* indices, uint32 maxQuads, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - AZStd::lock_guard locker(m_fontMutex); - - uint32 numQuadsWritten = 0; - - const size_t fxSize = m_effects.size(); - IF (fxSize && m_texID == -1 && !InitTexture(), 0) - { - return numQuadsWritten; - } - - // if the font is about to be deleted then m_pCryFont can be nullptr - if (!m_pCryFont) - { - return numQuadsWritten; - } - - SVF_P2F_C4B_T2F_F4B* pVertex = verts; - uint16* pIndex = indices; - size_t vbOffset = 0; - size_t ibOffset = 0; - - // Local function that is passed into CreateQuadsForText as the AddQuad function - AddFunction AddQuad = [&pVertex, &pIndex, &vbOffset, &ibOffset, maxQuads, &numQuadsWritten] - (const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const Vec2& tc0, const Vec2& tc1, const Vec2& tc2, const Vec2& tc3, uint32 packedColor) - { - Vec2 xy0(v0); - Vec2 xy1(v1); - Vec2 xy2(v2); - Vec2 xy3(v3); - - AZ_Assert(vbOffset + 3 < maxQuads * 4, "Vertex buffer overflow"); - AZ_Assert(ibOffset + 5 < maxQuads * 6, "Index buffer overflow"); - - // This should never happen but for safety make sure we never write off end of buffers (should hit asserts above if this is the case) - if (numQuadsWritten < maxQuads) - { - // define char quad - pVertex[vbOffset].xy = xy0; - pVertex[vbOffset].color.dcolor = packedColor; - pVertex[vbOffset].st = tc0; - pVertex[vbOffset].texIndex = 0; - pVertex[vbOffset].texHasColorChannel = 0; - pVertex[vbOffset].texIndex2 = 0; - pVertex[vbOffset].pad = 0; - - pVertex[vbOffset + 1].xy = xy1; - pVertex[vbOffset + 1].color.dcolor = packedColor; - pVertex[vbOffset + 1].st = tc1; - pVertex[vbOffset + 1].texIndex = 0; - pVertex[vbOffset + 1].texHasColorChannel = 0; - pVertex[vbOffset + 1].texIndex2 = 0; - pVertex[vbOffset + 1].pad = 0; - - pVertex[vbOffset + 2].xy = xy2; - pVertex[vbOffset + 2].color.dcolor = packedColor; - pVertex[vbOffset + 2].st = tc2; - pVertex[vbOffset + 2].texIndex = 0; - pVertex[vbOffset + 2].texHasColorChannel = 0; - pVertex[vbOffset + 2].texIndex2 = 0; - pVertex[vbOffset + 2].pad = 0; - - pVertex[vbOffset + 3].xy = xy3; - pVertex[vbOffset + 3].color.dcolor = packedColor; - pVertex[vbOffset + 3].st = tc3; - pVertex[vbOffset + 3].texIndex = 0; - pVertex[vbOffset + 3].texHasColorChannel = 0; - pVertex[vbOffset + 3].texIndex2 = 0; - pVertex[vbOffset + 3].pad = 0; - - pIndex[ibOffset] = vbOffset; - pIndex[ibOffset + 1] = vbOffset + 1; - pIndex[ibOffset + 2] = vbOffset + 2; - pIndex[ibOffset + 3] = vbOffset + 2; - pIndex[ibOffset + 4] = vbOffset + 3; - pIndex[ibOffset + 5] = vbOffset + 0; - - vbOffset += 4; - ibOffset += 6; - - ++numQuadsWritten; - } - }; - - // Local function that is passed into CreateQuadsForText as the BeginPass function - BeginPassFunction BeginPass = [] - (const SRenderingPass* /* pPass */) - { - }; - - - CreateQuadsForText(x, y, z, pStr, asciiMultiLine, ctx, AddQuad, BeginPass); - - return numQuadsWritten; -} - -int CFFont::GetFontTextureId() -{ - if (m_texID == -1 && !InitTexture()) - { - return -1; - } - - return m_texID; -} - -uint32 CFFont::GetFontTextureVersion() -{ - return m_textureVersion; -} - -void CFFont::CreateQuadsForText(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx, - AddFunction AddQuad, BeginPassFunction BeginPass) -{ - const size_t fxSize = m_effects.size(); - - Prepare(pStr, true, ctx.m_requestSize); - - const size_t fxIdx = ctx.m_fxIdx < fxSize ? ctx.m_fxIdx : 0; - const SEffect& fx = m_effects[fxIdx]; - - bool isRGB = m_pCryFont->RndPropIsRGBA(); - - float halfTexelShift = m_pCryFont->RndPropHalfTexelOffset(); - - bool passZeroColorOverridden = ctx.IsColorOverridden(); - - uint32 alphaBlend = passZeroColorOverridden ? ctx.m_colorOverride.a : fx.m_passes[0].m_color.a; - if (alphaBlend > 128) - { - ++alphaBlend; // 0..256 for proper blending - } - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - // This is the "logical" size of the font (in pixels). The actual size of - // the glyphs in the font texture may have additional scaling applied or - // could have been re-rendered at a different size. - Vec2 size = ctx.m_size; - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - // This scaling takes into account the logical size of the font relative - // to any additional scaling applied (such as from "size ratio"). - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - - Vec2 baseXY = Vec2(x, y); // in pixels - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(baseXY.x, baseXY.y); - } - - // Apply overscan border - const int flags = ctx.GetFlags(); - if ((flags & eDrawText_2D) && !(flags & eDrawText_IgnoreOverscan)) - { - Vec2 overscanBorder = Vec2(0.0f, 0.0f); - pRenderer->EF_Query(EFQ_OverscanBorders, overscanBorder); - - const float screenWidth = (float)pRenderer->GetOverlayWidth(); - const float screenHeight = (float)pRenderer->GetOverlayHeight(); - Vec2 overscanBorderOffset = ZERO; - if (!(flags & eDrawText_Center)) - { - overscanBorderOffset.x = (overscanBorder.x * screenWidth); - } - if (!(flags & eDrawText_CenterV)) - { - overscanBorderOffset.y = (overscanBorder.y * screenHeight); - } - if (flags & eDrawText_Right) - { - overscanBorderOffset.x = -overscanBorderOffset.x; - } - if (flags & eDrawText_Bottom) - { - overscanBorderOffset.y = -overscanBorderOffset.y; - } - baseXY += overscanBorderOffset; - } - - // snap for pixel perfect rendering (better quality for text) - if (ctx.m_pixelAligned) - { - baseXY.x = floor(baseXY.x); - baseXY.y = floor(baseXY.y); - - // for smaller fonts (half res or less) it's better to average multiple pixels (we don't miss lines) - if (scaleInfo.scale.x < 0.9f) - { - baseXY.x += 0.5f; // try to average two columns (for exact half res) - } - if (scaleInfo.scale.y < 0.9f) - { - baseXY.y += 0.25f; // hand tweaked value to get a good result with tiny font (640x480 underscore in console) - } - } - - for (size_t j = 0, numPasses = fx.m_passes.size(); j < numPasses; ++j) - { - size_t i = numPasses - j - 1; - - const SRenderingPass* pPass = &fx.m_passes[i]; - - if (!i) - { - alphaBlend = 256; - } - - ColorB passColor = !i && passZeroColorOverridden ? ctx.m_colorOverride : fx.m_passes[i].m_color; - - // gather pass data - Vec2 offset = pPass->m_posOffset; // in pixels - - float charX = baseXY.x + offset.x; // in pixels - float charY = baseXY.y + offset.y; // in pixels - - ColorB color = passColor; - - bool drawFrame = ctx.m_framed && i == numPasses - 1; - - BeginPass(pPass); - - if (drawFrame) - { - ColorB tempColor(255, 255, 255, 255); - uint32 frameColor = tempColor.pack_abgr8888(); - if (!isRGB) - { - frameColor = COLCONV(frameColor); - } - - Vec2 textSize = GetTextSizeUInternal(pStr, asciiMultiLine, ctx); - - float x0 = baseXY.x - 12; - float y0 = baseXY.y - 6; - float x1 = baseXY.x + textSize.x + 12; - float y1 = baseXY.y + textSize.y + 6; - - bool culled = false; - IF (ctx.m_clippingEnabled, 0) - { - float clipX = ctx.m_clipX; - float clipY = ctx.m_clipY; - float clipR = ctx.m_clipX + ctx.m_clipWidth; - float clipB = ctx.m_clipY + ctx.m_clipHeight; - - if ((x0 >= clipR) || (y0 >= clipB) || (x1 < clipX) || (y1 < clipY)) - { - culled = true; - } - - x0 = max(clipX, x0); - y0 = max(clipY, y0); - x1 = min(clipR, x1); - y1 = min(clipB, y1); - - //if (!culled && ((x1 - x0 <= 0.0f) || (y1 - y0 <= 0.0f))) - // culled = true; - } - - IF (!culled, 1) - { - Vec3 v0(x0, y0, z); - Vec3 v2(x1, y1, z); - Vec3 v1(v2.x, v0.y, v0.z); // to avoid float->half conversion - Vec3 v3(v0.x, v2.y, v0.z); // to avoid float->half conversion - - if (ctx.m_drawTextFlags & eDrawText_UseTransform) - { - v0 = ctx.m_transform * v0; - v2 = ctx.m_transform * v2; - v1 = ctx.m_transform * v1; - v3 = ctx.m_transform * v3; - } - - Vec2 gradientUvMin, gradientUvMax; - GetGradientTextureCoord(gradientUvMin.x, gradientUvMin.y, gradientUvMax.x, gradientUvMax.y); - - // define the frame quad - Vec2 uv(gradientUvMin.x, gradientUvMax.y); - AddQuad(v0, v1, v2, v3, uv, uv, uv, uv, frameColor); - } - } - - // parse the string, ignoring control characters - uint32_t nextCh = 0; - Unicode::CIterator pChar(pStr); - while (uint32_t ch = *pChar) - { - ++pChar; - nextCh = *pChar; - - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - { - charX = baseXY.x + offset.x; - charY += size.y; - continue; - } - break; - case '\r': - { - charX = baseXY.x + offset.x; - continue; - } - break; - case '\t': - { - if (ctx.m_proportional) - { - charX += TabCharCount * size.x * FONT_SPACE_SIZE; - } - else - { - charX += TabCharCount * size.x * ctx.m_widthScale; - } - continue; - } - break; - case '$': - { - if (ctx.m_processSpecialChars) - { - if (*pChar == '$') - { - ++pChar; - } - else if (isdigit(*pChar)) - { - if (!i) - { - int colorIndex = (*pChar) - '0'; - ColorB newColor = ColorTable[colorIndex]; - color.r = newColor.r; - color.g = newColor.g; - color.b = newColor.b; - // Leave alpha at original value! - } - ++pChar; - continue; - } - else if (*pChar == 'O' || *pChar == 'o') - { - if (!i) - { - color = passColor; - } - ++pChar; - continue; - } - } - } - break; - default: - break; - } - - // get texture coordinates - float texCoord[4]; - - int charOffsetX, charOffsetY; // in font texels - int charSizeX, charSizeY; // in font texels - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i requestSize = rerenderGlyphs ? ctx.m_requestSize : CCryFont::defaultGlyphSize; - m_pFontTexture->GetTextureCoord(m_pFontTexture->GetCharSlot(ch, requestSize), texCoord, charSizeX, charSizeY, charOffsetX, charOffsetY, requestSize); - - int horizontalAdvance = m_pFontTexture->GetHorizontalAdvance(ch, requestSize); - float advance; - - if (ctx.m_proportional) - { - advance = horizontalAdvance * scaleInfo.scale.x; - } - else - { - advance = size.x * ctx.m_widthScale; - } - - Vec2 kerningOffset(Vec2_Zero); - if (ctx.m_kerningEnabled && nextCh) - { - kerningOffset = m_pFontTexture->GetKerning(ch, nextCh) * scaleInfo.scale.x; - } - - float trackingOffset = 0.0f; - if (nextCh) - { - trackingOffset = ctx.m_tracking; - } - - float px = charX + charOffsetX * scaleInfo.scale.x; // in pixels - float py = charY + charOffsetY * scaleInfo.scale.y; // in pixels - float pr = px + charSizeX * scaleInfo.scale.x; - float pb = py + charSizeY * scaleInfo.scale.y; - - // compute clipping - float newX = px; // in pixels - float newY = py; // in pixels - float newR = pr; // in pixels - float newB = pb; // in pixels - - if (ctx.m_clippingEnabled) - { - float clipX = ctx.m_clipX; - float clipY = ctx.m_clipY; - float clipR = ctx.m_clipX + ctx.m_clipWidth; - float clipB = ctx.m_clipY + ctx.m_clipHeight; - - // clip non visible - if ((px >= clipR) || (py >= clipB) || (pr < clipX) || (pb < clipY)) - { - charX += advance + kerningOffset.x + trackingOffset; - continue; - } - // clip partially visible - else - { - float width = horizontalAdvance * scaleInfo.rcpCellWidth; - if ((width <= 0.0f) || (size.y <= 0.0f)) - { - charX += advance + kerningOffset.x + trackingOffset; - continue; - } - - // clip the image to the scissor rect - newX = max(clipX, px); - newY = max(clipY, py); - newR = min(clipR, pr); - newB = min(clipB, pb); - - float rcpWidth = 1.0f / width; - float rcpHeight = 1.0f / size.y; - - float texW = texCoord[2] - texCoord[0]; - float texH = texCoord[3] - texCoord[1]; - - // clip horizontal - texCoord[0] = texCoord[0] + texW * (newX - px) * rcpWidth; - texCoord[2] = texCoord[2] + texW * (newR - pr) * rcpWidth; - - // clip vertical - texCoord[1] = texCoord[1] + texH * (newY - py) * rcpHeight; - texCoord[3] = texCoord[3] + texH * (newB - pb) * rcpHeight; - } - } - - newX += halfTexelShift; - newY += halfTexelShift; - newR += halfTexelShift; - newB += halfTexelShift; - - //int offset = vbLen * 6; - - Vec3 v0(newX, newY, z); - Vec3 v2(newR, newB, z); - Vec3 v1(v2.x, v0.y, v0.z); // to avoid float->half conversion - Vec3 v3(v0.x, v2.y, v0.z); // to avoid float->half conversion - - Vec2 tc0(texCoord[0], texCoord[1]); - Vec2 tc2(texCoord[2], texCoord[3]); - Vec2 tc1(tc2.x, tc0.y); // to avoid float->half conversion - Vec2 tc3(tc0.x, tc2.y); // to avoid float->half conversion - - uint32 packedColor = 0; - { - ColorB tempColor = color; - tempColor.a = ((uint32) tempColor.a * alphaBlend) >> 8; - packedColor = tempColor.pack_abgr8888(); - - if (!isRGB) - { - packedColor = COLCONV(packedColor); - } - } - - if (ctx.m_drawTextFlags & eDrawText_UseTransform) - { - v0 = ctx.m_transform * v0; - v2 = ctx.m_transform * v2; - v1 = ctx.m_transform * v1; - v3 = ctx.m_transform * v3; - } - - AddQuad(v0, v1, v2, v3, tc0, tc1, tc2, tc3, packedColor); - - charX += advance + kerningOffset.x + trackingOffset; - } - } -} - -CFFont::TextScaleInfoInternal CFFont::CalculateScaleInternal(const STextDrawContext& ctx) const -{ - Vec2 size = GetRestoredFontSize(ctx); // in pixel - - IRenderer* pRenderer = gEnv->pRenderer; - AZ_Assert(pRenderer, "gEnv->pRenderer is NULL"); - - if (ctx.m_sizeIn800x600) - { - pRenderer->ScaleCoord(size.x, size.y); - } - - float rcpCellWidth; - Vec2 scale; - - int fontTextureCellWidth = GetFontTexture()->GetCellWidth(); - int fontTextureCellHeight = GetFontTexture()->GetCellHeight(); - - if (ctx.m_proportional) - { - rcpCellWidth = (1.0f / static_cast(fontTextureCellWidth)) * size.x; - scale = Vec2(rcpCellWidth * ctx.m_widthScale, size.y / static_cast(fontTextureCellHeight)); - } - else - { - rcpCellWidth = size.x / 16.0f; - scale = Vec2(rcpCellWidth * ctx.m_widthScale, size.y * ctx.m_widthScale / 16.0f); - } - - return TextScaleInfoInternal(scale, rcpCellWidth); -} - -size_t CFFont::GetTextLength(const char* pStr, const bool asciiMultiLine) const -{ - size_t len = 0; - - // parse the string, ignoring control characters - const char* pChar = pStr; - while (char ch = *pChar++) - { - if ((ch & 0xC0) == 0x80) - { - continue; // Skip UTF-8 continuation bytes, we count only the first byte of a code-point - } - switch (ch) - { - case '\\': - { - if (*pChar != 'n' || !asciiMultiLine) - { - break; - } - ++pChar; - } - case '\n': - case '\r': - case '\t': - { - continue; - } - break; - case '$': - { - if (*pChar == '$') - { - ++pChar; - } - else if (*pChar) - { - ++pChar; - continue; - } - } - break; - default: - break; - } - ++len; - } - - return len; -} - -void CFFont::WrapText(string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx) -{ - result = pStr; - - if (ctx.m_sizeIn800x600) - { - maxWidth = gEnv->pRenderer->ScaleCoordX(maxWidth); - } - - Vec2 strSize = GetTextSizeUInternal(result.c_str(), true, ctx); - - if (strSize.x <= maxWidth) - { - return; - } - - // Assume a given string has multiple lines of text if it's height is - // greater than the height of its font. - const bool multiLine = strSize.y > GetRestoredFontSize(ctx).y; - - int lastSpace = -1; - const char* pLastSpace = NULL; - float lastSpaceWidth = 0.0f; - - float curCharWidth = 0.0f; - float curLineWidth = 0.0f; - float biggestLineWidth = 0.0f; - float widthSum = 0.0f; - - int curChar = 0; - Unicode::CIterator pChar(result.c_str()); - while (uint32_t ch = *pChar) - { - // Dollar sign escape codes. The following scenarios can happen with dollar signs embedded in a string. - // The following character is... - // 1. ... a digit, 'O' or 'o' which indicates a color code. Both characters a skipped in the width calculation. - // 2. ... another dollar sign. Only 1 dollar sign is skipped in the width calculation. - // 3. ... anything else. The dollar sign is processed in the width calculation. - if (ctx.m_processSpecialChars && ch == '$') - { - ++pChar; - char nextChar = *pChar; - - if (isdigit(nextChar) || nextChar == 'O' || nextChar == 'o') - { - ++pChar; - continue; - } - else if (nextChar != '$') - { - --pChar; - } - } - - // get char width and sum it to the line width - // Note: This is not unicode compatible, since char-width depends on surrounding context (ie, combining diacritics etc) - char codepoint[5]; - Unicode::Convert(codepoint, ch); - curCharWidth = GetTextSizeUInternal(codepoint, true, ctx).x; - - // keep track of spaces - // they are good for splitting the string - if (ch == ' ') - { - lastSpace = curChar; - lastSpaceWidth = curLineWidth + curCharWidth; - pLastSpace = pChar.GetPosition(); - assert(*pLastSpace == ' '); - } - - bool prevCharWasNewline = false; - const bool notFirstChar = pChar.GetPosition() != result.c_str(); - if (*pChar && notFirstChar) - { - const char* pPrevCharStr = pChar.GetPosition() - 1; - prevCharWasNewline = pPrevCharStr[0] == '\n'; - } - - // if line exceed allowed width, split it - if (prevCharWasNewline || (curLineWidth + curCharWidth >= maxWidth && (*pChar))) - { - if (prevCharWasNewline) - { - // Reset the current line width to account for newline - curLineWidth = curCharWidth; - widthSum += curLineWidth; - } - else if ((lastSpace > 0) && ((curChar - lastSpace) < 16) && (curChar - lastSpace >= 0)) // 16 is the default threshold - { - *(char*)pLastSpace = '\n'; // This is safe inside UTF-8 because space is single-byte codepoint - - if (lastSpaceWidth > biggestLineWidth) - { - biggestLineWidth = lastSpaceWidth; - } - - curLineWidth = curLineWidth - lastSpaceWidth + curCharWidth; - widthSum += curLineWidth; - } - else - { - const char* pBuf = pChar.GetPosition(); - size_t bytesProcessed = pBuf - result.c_str(); - result.insert(bytesProcessed, '\n'); // Insert the newline, this invalidates the iterator - pBuf = result.c_str() + bytesProcessed; // In case reallocation occurs, we ensure we are inside the new buffer - assert(*pBuf == '\n'); - pChar.SetPosition(pBuf); // pChar once again points inside the target string, at the current character - assert(*pChar == ch); - ++pChar; - ++curChar; - - if (curLineWidth > biggestLineWidth) - { - biggestLineWidth = curLineWidth; - } - - widthSum += curLineWidth; - curLineWidth = curCharWidth; - } - - // if we don't need any more line breaks, then just stop, but for - // multiple lines we can't assume that there aren't any more - // strings to wrap, so continue - if (strSize.x - widthSum <= maxWidth && !multiLine) - { - break; - } - - lastSpaceWidth = 0; - lastSpace = 0; - } - else - { - curLineWidth += curCharWidth; - } - - ++curChar; - ++pChar; - } -} - -void CFFont::GetMemoryUsage (ICrySizer* pSizer) const -{ - pSizer->AddObject(m_name); - pSizer->AddObject(m_curPath); - pSizer->AddObject(m_pFontTexture); - pSizer->AddObject(m_pFontBuffer, m_fontBufferSize); - pSizer->AddObject(m_effects); - pSizer->AddObject(m_pDrawVB, sizeof(SVF_P3F_C4B_T2F) * MaxDrawVBQuads * 6); -} - -void CFFont::GetGradientTextureCoord(float& minU, float& minV, float& maxU, float& maxV) const -{ - const CTextureSlot* pSlot = m_pFontTexture->GetGradientSlot(); - assert(pSlot); - - float invWidth = 1.0f / (float) m_pFontTexture->GetWidth(); - float invHeight = 1.0f / (float) m_pFontTexture->GetHeight(); - - // deflate by one pixel to avoid bilinear filtering on the borders - minU = pSlot->vTexCoord[0] + invWidth; - minV = pSlot->vTexCoord[1] + invHeight; - maxU = pSlot->vTexCoord[0] + (pSlot->iCharWidth - 1) * invWidth; - maxV = pSlot->vTexCoord[1] + (pSlot->iCharHeight - 1) * invHeight; -} - -unsigned int CFFont::GetEffectId(const char* pEffectName) const -{ - if (pEffectName) - { - for (size_t i = 0, numEffects = m_effects.size(); i < numEffects; ++i) - { - if (!strcmp(m_effects[i].m_name.c_str(), pEffectName)) - { - return i; - } - } - } - - return 0; -} - -unsigned int CFFont::GetNumEffects() const -{ - return m_effects.size(); -} - -const char* CFFont::GetEffectName(unsigned int effectId) const -{ - return (effectId < m_effects.size()) ? m_effects[effectId].m_name.c_str() : nullptr; -} - -Vec2 CFFont::GetMaxEffectOffset(unsigned int effectId) const -{ - Vec2 maxOffset(0.0f, 0.0f); - - if (effectId < m_effects.size()) - { - const SEffect& fx = m_effects[effectId]; - - for (size_t i = 0, numPasses = fx.m_passes.size(); i < numPasses; ++i) - { - const SRenderingPass* pPass = &fx.m_passes[numPasses - i - 1]; - - // gather pass data - Vec2 offset = pPass->m_posOffset; - - if (maxOffset.x < offset.x) - { - maxOffset.x = offset.x; - } - - if (maxOffset.y < offset.y) - { - maxOffset.y = offset.y; - } - } - } - - return maxOffset; -} - -bool CFFont::DoesEffectHaveTransparency(unsigned int effectId) const -{ - const size_t fxSize = m_effects.size(); - const size_t fxIdx = effectId < fxSize ? effectId : 0; - const SEffect& fx = m_effects[fxIdx]; - - for (auto& pass : fx.m_passes) - { - // if the alpha is not 255 then there is transparency - if (pass.m_color.a != 255) - { - return true; - } - } - - return false; -} - -void CFFont::AddCharsToFontTexture(const char* pChars, int glyphSizeX, int glyphSizeY) -{ - AZStd::lock_guard locker(m_fontMutex); - Vec2i glyphSize(glyphSizeX, glyphSizeY); - Prepare(pChars, false, glyphSize); -} - -Vec2 CFFont::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph, const STextDrawContext& ctx) const -{ - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - return m_pFontTexture->GetKerning(leftGlyph, rightGlyph) * scaleInfo.scale.x; -} - -float CFFont::GetAscender(const STextDrawContext& ctx) const -{ - return (ctx.m_size.y * m_pFontTexture->GetAscenderToHeightRatio()); -} - -float CFFont::GetBaseline(const STextDrawContext& ctx) const -{ - const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx)); - // Calculate baseline the same way as the font renderer which uses the glyph height * size ratio. - // Adding 1 because FontTexture always adds 1 to the char height in GetTextureCoord - return (round(m_pFontTexture->GetCellHeight() * GetSizeRatio()) + 1.0f) * scaleInfo.scale.y; -} - -bool CFFont::InitTexture() -{ - m_texID = gEnv->pRenderer->FontCreateTexture(m_pFontTexture->GetWidth(), m_pFontTexture->GetHeight(), (uint8*)m_pFontTexture->GetBuffer(), eTF_A8, IRenderer::FontCreateTextureGenMipsDefaultValue, m_name.c_str()); - m_textureVersion = 0; - return m_texID >= 0; -} - -bool CFFont::InitCache() -{ - m_pFontTexture->CreateGradientSlot(); - - // precache (not required but for faster printout later) - const char first = ' '; - const char last = '~'; - char buf[last - first + 2]; - char* p = buf; - - // precache all [normal] printable characters to the string (missing ones are updated on demand) - for (int i = first; i <= last; ++i) - { - *p++ = i; - } - *p = 0; - - Prepare(buf, false); - - return true; -} - -CFFont::SEffect* CFFont::AddEffect(const char* pEffectName) -{ - m_effects.push_back(SEffect(pEffectName)); - return &m_effects[m_effects.size() - 1]; -} - -CFFont::SEffect* CFFont::GetDefaultEffect() -{ - return &m_effects[0]; -} - -void CFFont::Prepare(const char* pStr, bool updateTexture, const Vec2i& glyphSize) -{ - const bool rerenderGlyphs = m_sizeBehavior == SizeBehavior::Rerender; - const Vec2i usedGlyphSize = rerenderGlyphs ? glyphSize : CCryFont::defaultGlyphSize; - bool texUpdateNeeded = m_pFontTexture->PreCacheString(pStr, nullptr, m_sizeRatio, usedGlyphSize, m_fontHintParams) == 1 || m_fontTexDirty; - if (updateTexture && texUpdateNeeded && m_texID >= 0) - { - gEnv->pRenderer->FontUpdateTexture(m_texID, 0, 0, m_pFontTexture->GetWidth(), m_pFontTexture->GetHeight(), (unsigned char*)m_pFontTexture->GetBuffer()); - m_fontTexDirty = false; - ++m_textureVersion; - - // Let any listeners know that the font texture has changed - EBUS_EVENT(FontNotificationBus, OnFontTextureUpdated, this); - } - else - { - m_fontTexDirty = texUpdateNeeded; - } -} - -Vec2 CFFont::GetRestoredFontSize(const STextDrawContext& ctx) const -{ - // Calculate the scale that we need to apply to the text size to ensure - // it's on-screen size is the same regardless of the slot scaling needed - // to fit the glyphs of the font within the font texture slots. - float restoringScale = IFFontConstants::defaultSizeRatio / m_sizeRatio; - return Vec2(ctx.m_size.x * restoringScale, ctx.m_size.y * restoringScale); -} - -#endif - diff --git a/Code/CryEngine/CryFont/FFont.h b/Code/CryEngine/CryFont/FFont.h deleted file mode 100644 index c2eddd7b1d..0000000000 --- a/Code/CryEngine/CryFont/FFont.h +++ /dev/null @@ -1,234 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Font class. - - -#ifndef CRYINCLUDE_CRYFONT_FFONT_H -#define CRYINCLUDE_CRYFONT_FFONT_H -#pragma once - - -#if !defined(USE_NULLFONT_ALWAYS) - -#include -#include -#include -#include -#include "CryFont.h" - -#include - -struct ISystem; -class CFontTexture; - - -class CFFont - : public IFFont - , public IFFont_RenderProxy -{ -public: - //! Determines how characters of different sizes should be handled during render. - enum class SizeBehavior - { - Scale, //!< Default behavior; glyphs rendered at different sizes are rendered on scaled geometry - Rerender //!< Similar to Scale, but the glyph in the font texture is re-rendered to match the target - //!< size, as long as the size isn't greater than the maximum glyph/slot resolution as - //!< configured for the font texture in the font XML. - }; - - //! The hinting visual algorithm to be used (when hinting is enabled) - enum class HintStyle - { - Normal, //!< Default hinting behavior provided by font renderer - Light //!< Produces fuzzier glyphs but more accurately tracks glyph shape - }; - - //! Chooses whether hinting info should be obtained from the font, turned off entirely, or automatically generated - enum class HintBehavior - { - Default, //!< Obtain hinting data from font itself - AutoHint, //!< Procedurally derive hinting information from glyph - NoHinting, //!< Disable hinting entirely - }; - - //! Simple struct used to communicate font hinting parameters to font renderer. - struct FontHintParams - { - FontHintParams() : hintStyle(HintStyle::Normal), hintBehavior(HintBehavior::Default) { } - - HintStyle hintStyle; - HintBehavior hintBehavior; - }; - - struct SRenderingPass - { - ColorB m_color; - Vec2 m_posOffset; - int m_blendSrc; - int m_blendDest; - - SRenderingPass() - : m_color(255, 255, 255, 255) - , m_posOffset(0, 0) - , m_blendSrc(GS_BLSRC_SRCALPHA) - , m_blendDest(GS_BLDST_ONEMINUSSRCALPHA) - { - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - }; - - struct SEffect - { - string m_name; - std::vector m_passes; - - SEffect(const char* name) - : m_name(name) - { - assert(name); - } - - SRenderingPass* AddPass() - { - m_passes.push_back(SRenderingPass()); - return &m_passes[m_passes.size() - 1]; - } - - void ClearPasses() - { - m_passes.resize(0); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_name); - pSizer->AddObject(m_passes); - } - }; - - typedef std::vector Effects; - typedef Effects::iterator EffectsIt; - -public: - virtual int32 AddRef() override; - virtual int32 Release() override; - virtual bool Load(const char* pFontFilePath, unsigned int width, unsigned int height, unsigned int widthNumSlots, unsigned int heightNumSlots, unsigned int flags, float sizeRatio); - virtual bool Load(const char* pXMLFile); - virtual void Free(); - virtual void DrawString(float x, float y, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - virtual void DrawString(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - virtual Vec2 GetTextSize(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - virtual size_t GetTextLength(const char* pStr, const bool asciiMultiLine) const; - virtual void WrapText(string& result, float maxWidth, const char* pStr, const STextDrawContext& ctx); - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual void GetGradientTextureCoord(float& minU, float& minV, float& maxU, float& maxV) const; - virtual unsigned int GetEffectId(const char* pEffectName) const; - virtual unsigned int GetNumEffects() const; - virtual const char* GetEffectName(unsigned int effectId) const; - virtual Vec2 GetMaxEffectOffset(unsigned int effectId) const; - virtual bool DoesEffectHaveTransparency(unsigned int effectId) const; - virtual void AddCharsToFontTexture(const char* pChars, int glyphSizeX = ICryFont::defaultGlyphSizeX, int glyphSizeY = ICryFont::defaultGlyphSizeY) override; - virtual Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph, const STextDrawContext& ctx) const override; - virtual float GetAscender(const STextDrawContext& ctx) const override; - virtual float GetBaseline(const STextDrawContext& ctx) const override; - - virtual uint32 GetNumQuadsForText(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - virtual uint32 WriteTextQuadsToBuffers(SVF_P2F_C4B_T2F_F4B* verts, uint16* indices, uint32 maxQuads, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - virtual int GetFontTextureId(); - virtual uint32 GetFontTextureVersion(); - - virtual float GetSizeRatio() const override { return m_sizeRatio; } - -public: - virtual void RenderCallback(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - -public: - CFFont(ISystem* pSystem, CCryFont* pCryFont, const char* pFontName); - - bool InitTexture(); - bool InitCache(); - - CFontTexture* GetFontTexture() const { return m_pFontTexture; } - const string& GetName() const { return m_name; } - - SEffect* AddEffect(const char* pEffectName); - SEffect* GetDefaultEffect(); - -private: - virtual ~CFFont(); - - void Prepare(const char* pStr, bool updateTexture, const Vec2i& glyphSize = CCryFont::defaultGlyphSize); - void DrawStringUInternal(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - Vec2 GetTextSizeUInternal(const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - - using AddFunction = AZStd::function; - using BeginPassFunction = AZStd::function; - - //! This function is used by both RenderCallback and WriteTextQuadsToBuffers - //! To do this is takes two function pointers that implement the appropriate AddQuad and BeginPass behavior - void CreateQuadsForText(float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx, - AddFunction AddQuad, BeginPassFunction BeginPass); - - struct TextScaleInfoInternal - { - TextScaleInfoInternal(const Vec2& _scale, float _rcpCellWidth) - : scale(_scale), rcpCellWidth(_rcpCellWidth) { } - - Vec2 scale; - float rcpCellWidth; - }; - - TextScaleInfoInternal CalculateScaleInternal(const STextDrawContext& ctx) const; - - Vec2 GetRestoredFontSize(const STextDrawContext& ctx) const; - -private: - string m_name; - string m_curPath; - - CFontTexture* m_pFontTexture; - - size_t m_fontBufferSize; - unsigned char* m_pFontBuffer; - - int m_texID; - uint32 m_textureVersion; - - ISystem* m_pSystem; - - AZStd::recursive_mutex m_fontMutex; //!< Controls access between main and render threads. It's common for one thread - //!< to add un-cached glyphs to the font texture while another is accessing the - //!< font texture. - - CCryFont* m_pCryFont; - - bool m_fontTexDirty; - - Effects m_effects; - - SVF_P3F_C4B_T2F* m_pDrawVB; - - volatile int32 m_nRefCount; - - bool m_monospacedFont; //!< True if this font is fixed/monospaced, false otherwise (obtained from FreeType) - - float m_sizeRatio = IFFontConstants::defaultSizeRatio; - SizeBehavior m_sizeBehavior = SizeBehavior::Scale; //!< Changes how glyphs rendered at different sizes are rendered. - FontHintParams m_fontHintParams; //!< How the font should be hinted when its loaded and rendered to the font texture -}; - -#endif - -#endif // CRYINCLUDE_CRYFONT_FFONT_H diff --git a/Code/CryEngine/CryFont/FFontXML.cpp b/Code/CryEngine/CryFont/FFontXML.cpp deleted file mode 100644 index 1fdd84994e..0000000000 --- a/Code/CryEngine/CryFont/FFontXML.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : XML parsing to load a font. - - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "FFont.h" -#include "FontTexture.h" -#include -#include - -#if defined(WIN32) || defined(WIN64) -# include -# include -#endif - -////////////////////////////////////////////////////////////////////////// -// Xml parser implementation - -enum -{ - - ELEMENT_UNKNOWN = 0, - ELEMENT_FONT = 1, - ELEMENT_EFFECT = 2, - ELEMENT_EFFECTFILE = 3, - ELEMENT_PASS = 4, - ELEMENT_PASS_COLOR = 5, - ELEMENT_PASS_POSOFFSET = 12, - ELEMENT_PASS_BLEND = 14 -}; - -static inline int GetBlendModeFromString(const string& str, bool dst) -{ - int blend = GS_BLSRC_ONE; - - if (str == "zero") - { - blend = dst ? GS_BLDST_ZERO : GS_BLSRC_ZERO; - } - else if (str == "one") - { - blend = dst ? GS_BLDST_ONE : GS_BLSRC_ONE; - } - else if (str == "srcalpha" || - str == "src_alpha") - { - blend = dst ? GS_BLDST_SRCALPHA : GS_BLSRC_SRCALPHA; - } - else if (str == "invsrcalpha" || - str == "inv_src_alpha") - { - blend = dst ? GS_BLDST_ONEMINUSSRCALPHA : GS_BLSRC_ONEMINUSSRCALPHA; - } - else if (str == "dstalpha" || - str == "dst_alpha") - { - blend = dst ? GS_BLDST_DSTALPHA : GS_BLSRC_DSTALPHA; - } - else if (str == "invdstalpha" || - str == "inv_dst_alpha") - { - blend = dst ? GS_BLDST_ONEMINUSDSTALPHA : GS_BLSRC_ONEMINUSDSTALPHA; - } - else if (str == "dstcolor" || - str == "dst_color") - { - blend = GS_BLSRC_DSTCOL; - } - else if (str == "srccolor" || - str == "src_color") - { - blend = GS_BLDST_SRCCOL; - } - else if (str == "invdstcolor" || - str == "inv_dst_color") - { - blend = GS_BLSRC_ONEMINUSDSTCOL; - } - else if (str == "invsrccolor" || - str == "inv_src_color") - { - blend = GS_BLDST_ONEMINUSSRCCOL; - } - - return blend; -} - -class CXmlFontShader -{ -public: - CXmlFontShader(CFFont* pFont) - { - m_pFont = pFont; - m_nElement = ELEMENT_UNKNOWN; - m_pEffect = NULL; - m_pPass = NULL; - m_FontTexSize.set(0, 0); - - static const int defaultSlotWidthSize = 16; - static const int defaultSlotHeightSize = 8; - m_SlotSizes.set(defaultSlotWidthSize, defaultSlotHeightSize); - - m_FontSmoothAmount = 0; - m_FontSmoothMethod = FONT_SMOOTH_NONE; - } - - ~CXmlFontShader() - { - } - - void ScanXmlNodesRecursively(XmlNodeRef node) - { - if (!node) - { - return; - } - - FoundElement(node->getTag()); - - for (int i = 0, count = node->getNumAttributes(); i < count; ++i) - { - const char* key = ""; - const char* value = ""; - if (node->getAttributeByIndex(i, &key, &value)) - { - FoundAttribute(key, value); - } - } - - for (int i = 0, count = node->getChildCount(); i < count; ++i) - { - XmlNodeRef child = node->getChild(i); - ScanXmlNodesRecursively(child); - } - } - -private: - // notify methods - void FoundElement(const string& name) - { - //MessageBox(NULL, string("[" + name + "]").c_str(), "FoundElement", MB_OK); - // process the previous element - switch (m_nElement) - { - case ELEMENT_FONT: - { - if (!m_FontTexSize.x || !m_FontTexSize.y) - { - m_FontTexSize.set(512, 512); - } - - bool fontLoaded = m_pFont->Load(m_strFontPath.c_str(), m_FontTexSize.x, m_FontTexSize.y, m_SlotSizes.x, m_SlotSizes.y, TTFFLAG_CREATE(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio); -#if defined(WIN32) || defined(WIN64) - if (!fontLoaded) - { - TCHAR sysFontPath[MAX_PATH]; - if (SUCCEEDED(SHGetFolderPath(0, CSIDL_FONTS, 0, SHGFP_TYPE_DEFAULT, sysFontPath))) - { - const char* pFontPath = m_strFontPath.c_str(); - const char* pFontName = CryStringUtils::FindFileNameInPath(pFontPath); - - string newFontPath(sysFontPath); - newFontPath += "/"; - newFontPath += pFontName; - m_pFont->Load(newFontPath, m_FontTexSize.x, m_FontTexSize.y, m_SlotSizes.x, m_SlotSizes.y, TTFFLAG_CREATE(m_FontSmoothMethod, m_FontSmoothAmount), m_SizeRatio); - } - } -#endif - } - break; - - default: - break; - } - - // Translate the m_nElement name to a define - if (name == "font") - { - m_nElement = ELEMENT_FONT; - } - else if (name == "effect") - { - m_nElement = ELEMENT_EFFECT; - } - else if (name == "effectfile") - { - m_nElement = ELEMENT_EFFECTFILE; - } - else if (name == "pass") - { - m_pPass = NULL; - m_nElement = ELEMENT_PASS; - if (m_pEffect) - { - m_pPass = m_pEffect->AddPass(); - } - } - else if (name == "color") - { - m_nElement = ELEMENT_PASS_COLOR; - } - else if (name == "pos" || - name == "offset") - { - m_nElement = ELEMENT_PASS_POSOFFSET; - } - else if (name == "blend" || - name == "blending") - { - m_nElement = ELEMENT_PASS_BLEND; - } - else - { - m_nElement = ELEMENT_UNKNOWN; - } - } - - void FoundAttribute(const string& name, const string& value) - { - //MessageBox(NULL, string(name + "\n" + value).c_str(), "FoundAttribute", MB_OK); - switch (m_nElement) - { - case ELEMENT_FONT: - if (name == "path") - { - m_strFontPath = value; - } - else if (name == "w") - { - m_FontTexSize.x = (long)atof(value.c_str()); - } - else if (name == "h") - { - m_FontTexSize.y = (long)atof(value.c_str()); - } - else if (name == "widthslots") - { - m_SlotSizes.x = (int)atoi(value.c_str()); - } - else if (name == "heightslots") - { - m_SlotSizes.y = (int)atoi(value.c_str()); - } - else if (name == "sizeratio") - { - m_SizeRatio = static_cast(atof(value.c_str())); - } - else if (name == "smooth") - { - if (value == "blur") - { - m_FontSmoothMethod = FONT_SMOOTH_BLUR; - } - else if (value == "supersample") - { - m_FontSmoothMethod = FONT_SMOOTH_SUPERSAMPLE; - } - else if (value == "none") - { - m_FontSmoothMethod = FONT_SMOOTH_NONE; - } - } - else if (name == "smooth_amount") - { - m_FontSmoothAmount = (long)atof(value.c_str()); - } - break; - - case ELEMENT_EFFECT: - if (name == "name") - { - if (value == "default") - { - m_pEffect = m_pFont->GetDefaultEffect(); - m_pEffect->ClearPasses(); - } - else - { - m_pEffect = m_pFont->AddEffect(value.c_str()); - } - } - break; - - case ELEMENT_EFFECTFILE: - if (name == "path") - { - m_strFontEffectPath = value; - } - break; - - case ELEMENT_PASS_COLOR: - if (!m_pPass) - { - break; - } - if (name == "r") - { - m_pPass->m_color.r = (uint8)((float)atof(value.c_str()) * 255.0f); - } - else if (name == "g") - { - m_pPass->m_color.g = (uint8)((float)atof(value.c_str()) * 255.0f); - } - else if (name == "b") - { - m_pPass->m_color.b = (uint8)((float)atof(value.c_str()) * 255.0f); - } - else if (name == "a") - { - m_pPass->m_color.a = (uint8)((float)atof(value.c_str()) * 255.0f); - } - break; - - case ELEMENT_PASS_POSOFFSET: - if (!m_pPass) - { - break; - } - if (name == "x") - { - m_pPass->m_posOffset.x = (float)atoi(value.c_str()); - } - else if (name == "y") - { - m_pPass->m_posOffset.y = (float)atoi(value.c_str()); - } - break; - - case ELEMENT_PASS_BLEND: - if (!m_pPass) - { - break; - } - if (name == "src") - { - m_pPass->m_blendSrc = GetBlendModeFromString(value, false); - } - else if (name == "dst") - { - m_pPass->m_blendDest = GetBlendModeFromString(value, true); - } - else if (name == "type") - { - if (value == "modulate") - { - m_pPass->m_blendSrc = GS_BLSRC_SRCALPHA; - m_pPass->m_blendDest = GS_BLDST_ONEMINUSSRCALPHA; - } - else if (value == "additive") - { - m_pPass->m_blendSrc = GS_BLSRC_SRCALPHA; - m_pPass->m_blendDest = GS_BLDST_ONE; - } - } - break; - - default: - case ELEMENT_UNKNOWN: - break; - } - } - -public: - CFFont* m_pFont; - - unsigned long m_nElement; - - CFFont::SEffect* m_pEffect; - CFFont::SRenderingPass* m_pPass; - - string m_strFontPath; - string m_strFontEffectPath; - vector2l m_FontTexSize; - Vec2i m_SlotSizes; - float m_SizeRatio = IFFontConstants::defaultSizeRatio; - - int m_FontSmoothMethod; - int m_FontSmoothAmount; -}; - -////////////////////////////////////////////////////////////////////////// -// Main loading function -bool CFFont::Load(const char* pXMLFile) -{ - m_curPath = ""; - if (pXMLFile) - { - m_curPath = PathUtil::GetPath(pXMLFile); - } - - XmlNodeRef root = GetISystem()->LoadXmlFromFile(pXMLFile); - if (!root) - { - return false; - } - - CXmlFontShader xmlfs(this); - xmlfs.ScanXmlNodesRecursively(root); - - // if this was not a valid font XML file then return false - if (!m_pFontTexture || !m_pFontBuffer) - { - return false; - } - - // if there was a font effect file then parse that for effects - if (!xmlfs.m_strFontEffectPath.empty()) - { - XmlNodeRef fontEffectRoot = GetISystem()->LoadXmlFromFile(xmlfs.m_strFontEffectPath.c_str()); - if (!fontEffectRoot) - { - AZ_Warning("Font", false, "Error parsing font file %s, 'effectfile' pathname %s could not be found.", - pXMLFile, xmlfs.m_strFontEffectPath.c_str()); - return false; - } - - if (m_effects.size() > 1 || (m_effects.size() == 1 && (m_effects[0].m_name != "default" || m_effects[0].m_passes.size() > 1))) - { - AZ_Warning("Font", false, "Error parsing font file %s, 'effectfile' and 'effect' cannot both be used in the same font file.", - pXMLFile); - m_effects.clear(); - } - - // parse the font effects file, adding to this font object - CXmlFontShader xmlfsEffect(this); - xmlfsEffect.ScanXmlNodesRecursively(fontEffectRoot); - } - - return true; -} - -#endif - diff --git a/Code/CryEngine/CryFont/FontRenderer.cpp b/Code/CryEngine/CryFont/FontRenderer.cpp deleted file mode 100644 index 2cf160896b..0000000000 --- a/Code/CryEngine/CryFont/FontRenderer.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// -// Purpose: -// - Render a glyph outline into a bitmap using FreeType 2 - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "FontRenderer.h" - -#include -#include -#include - -#include - -// Sizes are defined in in 26.6 fixed float format (TT_F26Dot6), where -// 1 unit is 1/64 of a pixel. -static const int fractionalPixelUnits = 64; - -namespace -{ - FT_Int32 GetLoadFlags(CFFont::HintBehavior hintBehavior) - { - switch (hintBehavior) - { - case CFFont::HintBehavior::NoHinting: - { - return FT_LOAD_NO_HINTING; - break; - } - case CFFont::HintBehavior::AutoHint: - { - return FT_LOAD_FORCE_AUTOHINT; - break; - } - } - return FT_LOAD_DEFAULT; - } - - FT_Int32 GetLoadTarget(CFFont::HintStyle hintStyle) - { - if (hintStyle == CFFont::HintStyle::Light) - { - return FT_LOAD_TARGET_LIGHT; - } - - return FT_LOAD_TARGET_NORMAL; - } - - FT_Render_Mode GetRenderMode(CFFont::HintStyle hintStyle) - { - // We use the hint style to drive the render mode also. These should - // usually be correlated with each other for best results, even though - // they could technically be different. - if (hintStyle == CFFont::HintStyle::Light) - { - return FT_RENDER_MODE_LIGHT; - } - - return FT_RENDER_MODE_NORMAL; - } -} - -//------------------------------------------------------------------------------------------------- -CFontRenderer::CFontRenderer() - : m_pLibrary(0) - , m_pFace(0) - , m_pGlyph(0) - , m_fSizeRatio(IFFontConstants::defaultSizeRatio) - , m_pEncoding(FONT_ENCODING_UNICODE) - , m_iGlyphBitmapWidth(0) - , m_iGlyphBitmapHeight(0) -{ -} - -//------------------------------------------------------------------------------------------------- -CFontRenderer::~CFontRenderer() -{ - FT_Done_Face(m_pFace); - ; - FT_Done_FreeType(m_pLibrary); - m_pFace = NULL; - m_pLibrary = NULL; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::LoadFromFile(const string& szFileName) -{ - int iError = FT_Init_FreeType(&m_pLibrary); - - if (iError) - { - return 0; - } - - if (m_pFace) - { - FT_Done_Face(m_pFace); - m_pFace = 0; - } - - iError = FT_New_Face(m_pLibrary, szFileName.c_str(), 0, &m_pFace); - - if (iError) - { - return 0; - } - - SetEncoding(FONT_ENCODING_UNICODE); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::LoadFromMemory(unsigned char* pBuffer, int iBufferSize) -{ - int iError = FT_Init_FreeType(&m_pLibrary); - - if (iError) - { - return 0; - } - - if (m_pFace) - { - FT_Done_Face(m_pFace); - m_pFace = 0; - } - iError = FT_New_Memory_Face(m_pLibrary, pBuffer, iBufferSize, 0, &m_pFace); - - if (iError) - { - return 0; - } - - SetEncoding(FONT_ENCODING_UNICODE); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::Release() -{ - FT_Done_Face(m_pFace); - ; - FT_Done_FreeType(m_pLibrary); - m_pFace = NULL; - m_pLibrary = NULL; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::SetGlyphBitmapSize(int iWidth, int iHeight, float sizeRatio) -{ - m_iGlyphBitmapWidth = iWidth; - m_iGlyphBitmapHeight = iHeight; - - // Assign the given scale for texture slots as long as its positive - m_fSizeRatio = sizeRatio > 0.0f ? sizeRatio : m_fSizeRatio; - - FT_Set_Pixel_Sizes(m_pFace, (int)(m_iGlyphBitmapWidth * m_fSizeRatio), (int)(m_iGlyphBitmapHeight * m_fSizeRatio)); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::GetGlyphBitmapSize(int* pWidth, int* pHeight) -{ - if (pWidth) - { - *pWidth = m_iGlyphBitmapWidth; - } - - if (pHeight) - { - *pHeight = m_iGlyphBitmapHeight; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontRenderer::SetEncoding(FT_Encoding pEncoding) -{ - if (FT_Select_Charmap(m_pFace, pEncoding)) - { - return 0; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -int CFontRenderer::GetGlyph(CGlyphBitmap* pGlyphBitmap, int* iHoriAdvance, uint8* iGlyphWidth, uint8* iGlyphHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, int iX, int iY, int iCharCode, const CFFont::FontHintParams& fontHintParams) -{ - FT_Int32 loadFlags = GetLoadFlags(fontHintParams.hintBehavior); - loadFlags |= GetLoadTarget(fontHintParams.hintStyle); - - int iError = FT_Load_Char(m_pFace, iCharCode, loadFlags); - - if (iError) - { - return 0; - } - - FT_Render_Mode renderMode = GetRenderMode(fontHintParams.hintStyle); - - m_pGlyph = m_pFace->glyph; - - iError = FT_Render_Glyph(m_pGlyph, renderMode); - - if (iError) - { - return 0; - } - - if (iHoriAdvance) - { - *iHoriAdvance = m_pGlyph->metrics.horiAdvance / fractionalPixelUnits; - } - - if (iGlyphWidth) - { - *iGlyphWidth = m_pGlyph->bitmap.width; - } - - if (iGlyphHeight) - { - *iGlyphHeight = m_pGlyph->bitmap.rows; - } - - unsigned char* pBuffer = pGlyphBitmap->GetBuffer(); - AZ_Assert(pBuffer, "CGlyphBitmap: bad buffer"); - - uint32 dwGlyphWidth = pGlyphBitmap->GetWidth(); - iCharOffsetX = m_pGlyph->bitmap_left; - iCharOffsetY = (static_cast(round(m_iGlyphBitmapHeight * m_fSizeRatio)) - m_pGlyph->bitmap_top); - - const int textureSlotBufferWidth = pGlyphBitmap->GetWidth(); - const int textureSlotBufferHeight = pGlyphBitmap->GetHeight(); - - // might happen if font characters are too big or cache dimenstions in font.xml is too small "" - const bool charWidthFits = iX + m_pGlyph->bitmap.width <= textureSlotBufferWidth; - const bool charHeightFits = iY + m_pGlyph->bitmap.rows <= textureSlotBufferHeight; - const bool charFitsInSlot = charWidthFits && charHeightFits; - AZ_Error("Font", charFitsInSlot, "Character code %d doesn't fit in font texture; check 'sizeRatio' attribute in font XML or adjust this character's sizing in the font.", iCharCode); - - // Since we might be re-rendering/overwriting a glyph that already exists - // in the font texture, clear the contents of this particular slot so no - // artifacts of the previous glyph remain. - pGlyphBitmap->Clear(); - - // Restrict iteration to smallest of either the texture slot or glyph - // bitmap buffer ranges - const int bufferMaxIterWidth = AZStd::GetMin(textureSlotBufferWidth, m_pGlyph->bitmap.width); - const int bufferMaxIterHeight = AZStd::GetMin(textureSlotBufferHeight, m_pGlyph->bitmap.rows); - - for (int i = 0; i < bufferMaxIterHeight; i++) - { - int iNewY = i + iY; - - for (int j = 0; j < bufferMaxIterWidth; j++) - { - unsigned char cColor = m_pGlyph->bitmap.buffer[(i * m_pGlyph->bitmap.width) + j]; - int iOffset = iNewY * dwGlyphWidth + iX + j; - - if (iOffset >= (int)dwGlyphWidth * m_iGlyphBitmapHeight) - { - continue; - } - - pBuffer[iOffset] = cColor; - // pBuffer[iOffset] = cColor/2+32; // debug - visualize character in a block - } - } - - return 1; -} - -int CFontRenderer::GetGlyphScaled([[maybe_unused]] CGlyphBitmap* pGlyphBitmap, [[maybe_unused]] int* iGlyphWidth, [[maybe_unused]] int* iGlyphHeight, [[maybe_unused]] int iX, [[maybe_unused]] int iY, [[maybe_unused]] float fScaleX, [[maybe_unused]] float fScaleY, [[maybe_unused]] int iCharCode) -{ - return 1; -} - -Vec2 CFontRenderer::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph) -{ - FT_Vector kerningOffsets; - kerningOffsets.x = kerningOffsets.y = 0; - - if (FT_HAS_KERNING(m_pFace)) - { - const FT_UInt leftGlyphIndex = FT_Get_Char_Index(m_pFace, leftGlyph); - const FT_UInt rightGlyphIndex = FT_Get_Char_Index(m_pFace, rightGlyph); - - [[maybe_unused]] FT_Error ftError = FT_Get_Kerning(m_pFace, leftGlyphIndex, rightGlyphIndex, FT_KERNING_DEFAULT, &kerningOffsets); - -#if !defined(_RELEASE) - if (0 != ftError) - { - string warnMsg; - warnMsg.Format("FT_Get_Kerning returned %d", ftError); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, warnMsg.c_str()); - } -#endif - } - - return Vec2(azlossy_cast(kerningOffsets.x / fractionalPixelUnits), azlossy_cast(kerningOffsets.y / fractionalPixelUnits)); -} - -float CFontRenderer::GetAscenderToHeightRatio() -{ - return (static_cast(m_pFace->ascender) / static_cast(m_pFace->height)); -} - -//------------------------------------------------------------------------------------------------- -/* -int CFontRenderer::FT_GetIndex(int iCharCode) -{ -if (iCharCode < 256) -{ -int iIndex = 0; -int iUnicode; - -// try unicode -for (int i = 0; i < m_pFace->num_charmaps; i++) -{ -if ((m_pFace->charmaps[i]->platform_id == 3) && (m_pFace->charmaps[i]->encoding_id == 1)) -{ -iUnicode = i; - -FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]); - -iIndex = FT_Get_Char_Index(m_pFace, iCharCode); - -// not unicode, try ascii -if (iIndex == 0) -{ -for (int i = 0; i < m_pFace->num_charmaps; i++) -{ -if ((m_pFace->charmaps[i]->platform_id == 0) && (m_pFace->charmaps[i]->encoding_id == 0)) -{ -FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]); - -iIndex = FT_Get_Char_Index(m_pFace, iCharCode); - -// not ascii either, reuse unicode default "missing char" -if (iIndex == 0) -{ -FT_Set_Charmap(m_pFace, m_pFace->charmaps[iUnicode]); - -return FT_Get_Char_Index(m_pFace, iCharCode); -} -} -} -} - -return iIndex; -} -} - -return 0; -} -else -{ -for (int i = 0; i < m_pFace->num_charmaps; i++) -{ -if ((m_pFace->charmaps[i]->platform_id == 3) && (m_pFace->charmaps[i]->encoding_id == 1)) -{ -FT_Set_Charmap(m_pFace, m_pFace->charmaps[i]); - -return FT_Get_Char_Index(m_pFace, iCharCode); -} -} - -return 0; -} - -return 0; -} -*/ - -#endif // #if !defined(USE_NULLFONT_ALWAYS) diff --git a/Code/CryEngine/CryFont/FontRenderer.h b/Code/CryEngine/CryFont/FontRenderer.h deleted file mode 100644 index aca26a1e04..0000000000 --- a/Code/CryEngine/CryFont/FontRenderer.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Render a glyph outline into a bitmap using FreeType 2 - -#if !defined(USE_NULLFONT_ALWAYS) - -#ifndef CRYINCLUDE_CRYFONT_FONTRENDERER_H -#define CRYINCLUDE_CRYFONT_FONTRENDERER_H -#pragma once - - - -#include "GlyphBitmap.h" -#include "FFont.h" -#include -#pragma push_macro("generic") -#define generic GenericFromFreeTypeLibrary -#include -#undef generic -#pragma pop_macro("generic") - - -// Corresponds to the Unicode character set. This value covers all versions of the Unicode repertoire, -// including ASCII and Latin-1. Most fonts include a Unicode charmap, but not all of them. -#define FONT_ENCODING_UNICODE (FT_ENCODING_UNICODE) - -// Corresponds to the Microsoft Symbol encoding, used to encode mathematical symbols in the 32..255 character code range. -// For more information, see `http://www.ceviz.net/symbol.htm'. -#define FONT_ENCODING_SYMBOL (FT_ENCODING_MS_SYMBOL) - -// Corresponds to Microsoft's Japanese SJIS encoding. -// More info at `http://langsupport.japanreference.com/encoding.shtml'. See note on multi-byte encodings below. -#define FONT_ENCODING_SJIS (FT_ENCODING_MS_SJIS) - -// Corresponds to the encoding system for Simplified Chinese, as used in China. Only found in some TrueType fonts. -#define FONT_ENCODING_GB2312 (FT_ENCODING_MS_GB2312) - -// Corresponds to the encoding system for Traditional Chinese, as used in Taiwan and Hong Kong. Only found in some TrueType fonts. -#define FONT_ENCODING_BIG5 (FT_ENCODING_MS_BIG5) - -// Corresponds to the Korean encoding system known as Wansung. -// This is a Microsoft encoding that is only found in some TrueType fonts. -// For more information, see `http://www.microsoft.com/typography/unicode/949.txt'. -#define FONT_ENCODING_WANSUNG (FT_ENCODING_MS_WANSUNG) - -// The Korean standard character set (KS C-5601-1992), which corresponds to Windows code page 1361. -// This character set includes all possible Hangeul character combinations. Only found on some rare TrueType fonts. -#define FONT_ENCODING_JOHAB (FT_ENCODING_MS_JOHAB) - - - -//------------------------------------------------------------------------------------ -class CFontRenderer -{ -public: - - CFontRenderer(); - ~CFontRenderer(); - - int LoadFromFile(const string& szFileName); - int LoadFromMemory(unsigned char* pBuffer, int iBufferSize); - int Release(); - - int SetGlyphBitmapSize(int iWidth, int iHeight, float sizeRatio); - int GetGlyphBitmapSize(int* pWidth, int* pHeight); - - int SetSizeRatio(float fSizeRatio) { m_fSizeRatio = fSizeRatio; return 1; }; - float GetSizeRatio() { return m_fSizeRatio; }; - - int SetEncoding(FT_Encoding pEncoding); - FT_Encoding GetEncoding() { return m_pEncoding; }; - - //! Populates the given pGlyphBitmap's buffer from the FreeType bitmap buffer - //! \param iCharCode Used as a character index to retrieve the FreeType glyph and it's associated bitmap buffer for the character - //! \param pGlyphBitmap The FreeType glyph buffer is essentially copied into this CGlyphBitmap buffer - int GetGlyph(CGlyphBitmap* pGlyphBitmap, int* iHoriAdvance, uint8* iGlyphWidth, uint8* iGlyphHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, int iX, int iY, int iCharCode, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams()); - int GetGlyphScaled(CGlyphBitmap* pGlyphBitmap, int* iGlyphWidth, int* iGlyphHeight, int iX, int iY, float fScaleX, float fScaleY, int iCharCode); - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - bool GetMonospaced() const { return FT_IS_FIXED_WIDTH(m_pFace) != 0; } - - Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph); - - float GetAscenderToHeightRatio(); - -private: - - FT_Library m_pLibrary; - FT_Face m_pFace; - FT_GlyphSlot m_pGlyph; - float m_fSizeRatio; - - FT_Encoding m_pEncoding; - - int m_iGlyphBitmapWidth; - int m_iGlyphBitmapHeight; -}; - -#endif // CRYINCLUDE_CRYFONT_FONTRENDERER_H - -#endif // #if !defined(USE_NULLFONT_ALWAYS) diff --git a/Code/CryEngine/CryFont/FontTexture.cpp b/Code/CryEngine/CryFont/FontTexture.cpp deleted file mode 100644 index 8db7484d59..0000000000 --- a/Code/CryEngine/CryFont/FontTexture.cpp +++ /dev/null @@ -1,633 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Purpose: -// - Create and update a texture with the most recently used glyphs - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "FontTexture.h" -#include "UnicodeIterator.h" -#include - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#undef GetCharWidth -#endif - -//------------------------------------------------------------------------------------------------- -CFontTexture::CFontTexture() - : m_wSlotUsage(1) - , m_iWidth(0) - , m_iHeight(0) - , m_fInvWidth(0.0f) - , m_fInvHeight(0.0f) - , m_iCellWidth(0) - , m_iCellHeight(0) - , m_fTextureCellWidth(0) - , m_fTextureCellHeight(0) - , m_iWidthCellCount(0) - , m_iHeightCellCount(0) - , m_nTextureSlotCount(0) - , m_pBuffer(0) - , m_iSmoothMethod(FONT_SMOOTH_NONE) - , m_iSmoothAmount(FONT_SMOOTH_AMOUNT_NONE) -{ -} - -//------------------------------------------------------------------------------------------------- -CFontTexture::~CFontTexture() -{ - Release(); -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::CreateFromFile(const string& szFileName, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount) -{ - if (!m_pGlyphCache.LoadFontFromFile(szFileName)) - { - Release(); - - return 0; - } - - if (!Create(iWidth, iHeight, iSmoothMethod, iSmoothAmount, iWidthCellCount, iHeightCellCount)) - { - return 0; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::CreateFromMemory(unsigned char* pFileData, int iDataSize, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount, float sizeRatio) -{ - if (!m_pGlyphCache.LoadFontFromMemory(pFileData, iDataSize)) - { - Release(); - - return 0; - } - - if (!Create(iWidth, iHeight, iSmoothMethod, iSmoothAmount, iWidthCellCount, iHeightCellCount, sizeRatio)) - { - return 0; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::Create(int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCellCount, int iHeightCellCount, float sizeRatio) -{ - m_pBuffer = new FONT_TEXTURE_TYPE[iWidth * iHeight]; - if (!m_pBuffer) - { - return 0; - } - - memset(m_pBuffer, 0, iWidth * iHeight * sizeof(FONT_TEXTURE_TYPE)); - - if (!(iWidthCellCount * iHeightCellCount)) - { - return 0; - } - - m_iWidth = iWidth; - m_iHeight = iHeight; - m_fInvWidth = 1.0f / (float)iWidth; - m_fInvHeight = 1.0f / (float)iHeight; - - m_iWidthCellCount = iWidthCellCount; - m_iHeightCellCount = iHeightCellCount; - m_nTextureSlotCount = m_iWidthCellCount * m_iHeightCellCount; - - m_iSmoothMethod = iSmoothMethod; - m_iSmoothAmount = iSmoothAmount; - - m_iCellWidth = m_iWidth / m_iWidthCellCount; - m_iCellHeight = m_iHeight / m_iHeightCellCount; - - m_fTextureCellWidth = m_iCellWidth * m_fInvWidth; - m_fTextureCellHeight = m_iCellHeight * m_fInvHeight; - - if (!m_pGlyphCache.Create(FONT_GLYPH_CACHE_SIZE, m_iCellWidth, m_iCellHeight, iSmoothMethod, iSmoothAmount, sizeRatio)) - { - Release(); - - return 0; - } - - if (!CreateSlotList(m_nTextureSlotCount)) - { - Release(); - - return 0; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::Release() -{ - delete[] m_pBuffer; - m_pBuffer = 0; - - ReleaseSlotList(); - - m_pSlotTable.clear(); - - m_pGlyphCache.Release(); - - m_iWidthCellCount = 0; - m_iHeightCellCount = 0; - m_nTextureSlotCount = 0; - - m_iWidth = 0; - m_iHeight = 0; - m_fInvWidth = 0.0f; - m_fInvHeight = 0.0f; - - m_iCellWidth = 0; - m_iCellHeight = 0; - - m_iSmoothMethod = 0; - m_iSmoothAmount = 0; - - m_fTextureCellWidth = 0.0f; - m_fTextureCellHeight = 0.0f; - - m_wSlotUsage = 1; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -uint32 CFontTexture::GetSlotChar(int iSlot) const -{ - return m_pSlotList[iSlot]->cCurrentChar; -} - -//------------------------------------------------------------------------------------------------- -CTextureSlot* CFontTexture::GetCharSlot(uint32 cChar, const Vec2i& glyphSize) -{ - CryFont::FontTexture::CTextureSlotKey slotKey = GetTextureSlotKey(cChar, glyphSize); - CTextureSlotTableItor pItor = m_pSlotTable.find(slotKey); - - if (pItor != m_pSlotTable.end()) - { - return pItor->second; - } - - return 0; -} - -//------------------------------------------------------------------------------------------------- -CTextureSlot* CFontTexture::GetLRUSlot() -{ - uint16 wMaxSlotAge = 0; - CTextureSlot* pLRUSlot = 0; - CTextureSlot* pSlot; - - CTextureSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - pSlot = *pItor; - - if (pSlot->wSlotUsage == 0) - { - return pSlot; - } - else - { - uint16 slotAge = m_wSlotUsage - pSlot->wSlotUsage; - if (slotAge > wMaxSlotAge) - { - pLRUSlot = pSlot; - wMaxSlotAge = slotAge; - } - } - - ++pItor; - } - - return pLRUSlot; -} - -//------------------------------------------------------------------------------------------------- -CTextureSlot* CFontTexture::GetMRUSlot() -{ - uint16 wMinSlotAge = 0xFFFF; - CTextureSlot* pMRUSlot = 0; - CTextureSlot* pSlot; - - CTextureSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - pSlot = *pItor; - - if (pSlot->wSlotUsage != 0) - { - uint16 slotAge = m_wSlotUsage - pSlot->wSlotUsage; - if (slotAge > wMinSlotAge) - { - pMRUSlot = pSlot; - wMinSlotAge = slotAge; - } - } - - ++pItor; - } - - return pMRUSlot; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::PreCacheString(const char* szString, int* pUpdated, float sizeRatio, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams) -{ - Vec2i clampedGlyphSize = ClampGlyphSize(glyphSize, m_iCellWidth, m_iCellHeight); - - uint16 wSlotUsage = m_wSlotUsage++; - int iUpdated = 0; - - uint32 cChar; - for (Unicode::CIterator it(szString); *it; ++it) - { - cChar = *it; - CTextureSlot* pSlot = GetCharSlot(cChar, clampedGlyphSize); - - if (!pSlot) - { - pSlot = GetLRUSlot(); - - if (!pSlot) - { - return 0; - } - - if (!UpdateSlot(pSlot->iTextureSlot, wSlotUsage, cChar, sizeRatio, clampedGlyphSize, fontHintParams)) - { - return 0; - } - - ++iUpdated; - } - else - { - pSlot->wSlotUsage = wSlotUsage; - } - } - - if (pUpdated) - { - *pUpdated = iUpdated; - } - - if (iUpdated) - { - return 1; - } - - return 2; -} - -//------------------------------------------------------------------------------------------------- -void CFontTexture::GetTextureCoord(CTextureSlot* pSlot, float texCoords[4], - int& iCharSizeX, int& iCharSizeY, int& iCharOffsetX, int& iCharOffsetY, - const Vec2i& glyphSize) const -{ - if (!pSlot) - { - return; // expected behavior - } - - // Re-rendered glyphs are stored at smaller sizes than glyphs rendered at - // the (maximum) font texture slot resolution. We scale the returned width - // and height of the (actual) rendered glyph sizes so its transparent to - // callers that the glyph is actually smaller (from being re-rendered). - const float requestSizeWidthScale = AZ::GetMin(1.0f, GetRequestSizeWidthScale(glyphSize)); - const float requestSizeHeightScale = AZ::GetMin(1.0f, GetRequestSizeHeightScale(glyphSize)); - const float invRequestSizeWidthScale = 1.0f / requestSizeWidthScale; - const float invRequestSizeHeightScale = 1.0f / requestSizeHeightScale; - - // The inverse scale grows as the glyph size decreases. Once the glyph size - // reaches the font texture's max slot dimensions, we cap width/height scale - // since the text draw context will apply normal (as opposed to re-rendered) - // scaling. - int iChWidth = static_cast(pSlot->iCharWidth * invRequestSizeWidthScale); - int iChHeight = static_cast(pSlot->iCharHeight * invRequestSizeHeightScale); - - float slotCoord0 = pSlot->vTexCoord[0]; - float slotCoord1 = pSlot->vTexCoord[1]; - texCoords[0] = slotCoord0 - m_fInvWidth; // extra pixel for nicer bilinear filter - texCoords[1] = slotCoord1 - m_fInvHeight; // extra pixel for nicer bilinear filter - - // UV coordinates also must be scaled relative to the re-rendered glyph size - // as well. Width scale must be capped at 1.0f since glyph can't grow - // beyond the slot's resolution. - texCoords[2] = slotCoord0 + (((float)iChWidth * m_fInvWidth) * requestSizeWidthScale); - texCoords[3] = slotCoord1 + (((float)iChHeight * m_fInvHeight) * requestSizeHeightScale); - - iCharSizeX = iChWidth + 1; // extra pixel for nicer bilinear filter - iCharSizeY = iChHeight + 1; // extra pixel for nicer bilinear filter - - // Offsets are scaled accordingly when the rendered glyph size is smaller - // than the glyph/slot dimensions, but otherwise we expect the text draw - // context to apply scaling beyond that. - iCharOffsetX = static_cast(pSlot->iCharOffsetX * invRequestSizeWidthScale); - iCharOffsetY = static_cast(pSlot->iCharOffsetY * invRequestSizeHeightScale); -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::GetCharacterWidth(uint32 cChar) const -{ - CTextureSlotTableItorConst pItor = m_pSlotTable.find(GetTextureSlotKey(cChar)); - - if (pItor == m_pSlotTable.end()) - { - return 0; - } - - const CTextureSlot& rSlot = *pItor->second; - - // For proportional fonts, add one pixel of spacing for aesthetic reasons - int proportionalOffset = GetMonospaced() ? 0 : 1; - - return rSlot.iCharWidth + proportionalOffset; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::GetHorizontalAdvance(uint32 cChar, const Vec2i& glyphSize) const -{ - CTextureSlotTableItorConst pItor = m_pSlotTable.find(GetTextureSlotKey(cChar, glyphSize)); - - if (pItor == m_pSlotTable.end()) - { - return 0; - } - - const CTextureSlot& rSlot = *pItor->second; - - // Re-rendered glyphs are stored at smaller sizes than glyphs rendered at - // the (maximum) font texture slot resolution. We scale the returned width - // and height of the (actual) rendered glyph sizes so its transparent to - // callers that the glyph is actually smaller (from being re-rendered). - const float requestSizeWidthScale = GetRequestSizeWidthScale(glyphSize); - const float invRequestSizeWidthScale = 1.0f / requestSizeWidthScale; - - // Only multiply by 1.0f when glyphsize is greater than cell width because we assume that callers - // will use the font draw text context to scale the value appropriately. - return static_cast(rSlot.iHoriAdvance * AZ::GetMax(1.0f, invRequestSizeWidthScale)); -} - -//------------------------------------------------------------------------------------------------- -/* -int CFontTexture::GetCharHeightByChar(wchar_t cChar) -{ -CTextureSlotTableItor pItor = m_pSlotTable.find(cChar); - -if (pItor != m_pSlotTable.end()) -{ -return pItor->second->iCharHeight; -} - -return 0; -} -*/ - -//------------------------------------------------------------------------------------------------- -int CFontTexture::WriteToFile([[maybe_unused]] const string& szFileName) -{ -#ifdef WIN32 - AZ::IO::FileIOStream outputFile(szFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary); - - if (!outputFile.IsOpen()) - { - return 0; - } - - BITMAPFILEHEADER pHeader; - BITMAPINFOHEADER pInfoHeader; - - memset(&pHeader, 0, sizeof(BITMAPFILEHEADER)); - memset(&pInfoHeader, 0, sizeof(BITMAPINFOHEADER)); - - pHeader.bfType = 0x4D42; - pHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_iWidth * m_iHeight * 3; - pHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - - pInfoHeader.biSize = sizeof(BITMAPINFOHEADER); - pInfoHeader.biWidth = m_iWidth; - pInfoHeader.biHeight = m_iHeight; - pInfoHeader.biPlanes = 1; - pInfoHeader.biBitCount = 24; - pInfoHeader.biCompression = 0; - pInfoHeader.biSizeImage = m_iWidth * m_iHeight * 3; - - outputFile.Write(sizeof(BITMAPFILEHEADER), &pHeader); - outputFile.Write(sizeof(BITMAPINFOHEADER), &pInfoHeader); - - unsigned char cRGB[3]; - - for (int i = m_iHeight - 1; i >= 0; i--) - { - for (int j = 0; j < m_iWidth; j++) - { - cRGB[0] = m_pBuffer[(i * m_iWidth) + j]; - cRGB[1] = *cRGB; - - cRGB[2] = *cRGB; - - outputFile.Write(3, cRGB); - } - } - -#endif - return 1; -} - -//------------------------------------------------------------------------------------------------- -Vec2 CFontTexture::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph) -{ - return m_pGlyphCache.GetKerning(leftGlyph, rightGlyph); -} - -//------------------------------------------------------------------------------------------------- -float CFontTexture::GetAscenderToHeightRatio() -{ - return m_pGlyphCache.GetAscenderToHeightRatio(); -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::CreateSlotList(int iListSize) -{ - int y, x; - - for (int i = 0; i < iListSize; i++) - { - CTextureSlot* pTextureSlot = new CTextureSlot; - - if (!pTextureSlot) - { - return 0; - } - - pTextureSlot->iTextureSlot = i; - pTextureSlot->Reset(); - - y = i / m_iWidthCellCount; - x = i % m_iWidthCellCount; - - pTextureSlot->vTexCoord[0] = (float)(x * m_fTextureCellWidth) + (0.5f / (float)m_iWidth); - pTextureSlot->vTexCoord[1] = (float)(y * m_fTextureCellHeight) + (0.5f / (float)m_iHeight); - - m_pSlotList.push_back(pTextureSlot); - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::ReleaseSlotList() -{ - CTextureSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - delete (*pItor); - - pItor = m_pSlotList.erase(pItor); - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CFontTexture::UpdateSlot(int iSlot, uint16 wSlotUsage, uint32 cChar, float sizeRatio, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams) -{ - CTextureSlot* pSlot = m_pSlotList[iSlot]; - - if (!pSlot) - { - return 0; - } - - CTextureSlotTableItor pItor = m_pSlotTable.find(GetTextureSlotKey(pSlot->cCurrentChar, pSlot->glyphSize)); - - if (pItor != m_pSlotTable.end()) - { - m_pSlotTable.erase(pItor); - } - m_pSlotTable.insert(AZStd::pair(GetTextureSlotKey(cChar, glyphSize), pSlot)); - pSlot->glyphSize = glyphSize; - pSlot->wSlotUsage = wSlotUsage; - pSlot->cCurrentChar = cChar; - - int iWidth = 0; - int iHeight = 0; - - // blit the char glyph into the texture - int x = pSlot->iTextureSlot % m_iWidthCellCount; - int y = pSlot->iTextureSlot / m_iWidthCellCount; - - CGlyphBitmap* pGlyphBitmap; - - if (glyphSize.x > 0 && glyphSize.y > 0) - { - m_pGlyphCache.SetGlyphBitmapSize(glyphSize.x, glyphSize.y, sizeRatio); - } - - if (!m_pGlyphCache.GetGlyph(&pGlyphBitmap, &pSlot->iHoriAdvance, &iWidth, &iHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, cChar, glyphSize, fontHintParams)) - { - return 0; - } - - pSlot->iCharWidth = iWidth; - pSlot->iCharHeight = iHeight; - - // Add a pixel along width and height to avoid artifacts being rendered - // from a previous glyph in this slot due to bilinear filtering. The source - // glyph bitmap buffer is presumed to be cleared prior to FreeType rendering - // to the bitmap. - const int blitWidth = AZ::GetMin(iWidth + 1, m_iCellWidth); - const int blitHeight = AZ::GetMin(iHeight + 1, m_iCellHeight); - - pGlyphBitmap->BlitTo8(m_pBuffer, 0, 0, - blitWidth, blitHeight, x * m_iCellWidth, y * m_iCellHeight, m_iWidth); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -void CFontTexture::CreateGradientSlot() -{ - CTextureSlot* pSlot = GetGradientSlot(); - assert(pSlot->cCurrentChar == (uint32)~0); // 0 needs to be unused spot - - pSlot->Reset(); - pSlot->iCharWidth = m_iCellWidth - 2; - pSlot->iCharHeight = m_iCellHeight - 2; - pSlot->SetNotReusable(); - - int x = pSlot->iTextureSlot % m_iWidthCellCount; - int y = pSlot->iTextureSlot / m_iWidthCellCount; - - assert(sizeof(*m_pBuffer) == sizeof(uint8)); - uint8* pBuffer = &m_pBuffer[x * m_iCellWidth + y * m_iCellHeight * m_iWidth]; - - for (uint32 dwY = 0; dwY < pSlot->iCharHeight; ++dwY) - { - for (uint32 dwX = 0; dwX < pSlot->iCharWidth; ++dwX) - { - pBuffer[dwX + dwY * m_iWidth] = dwY * 255 / (pSlot->iCharHeight - 1); - } - } -} - -//------------------------------------------------------------------------------------------------- -CTextureSlot* CFontTexture::GetGradientSlot() -{ - return m_pSlotList[0]; -} - -//------------------------------------------------------------------------------------------------- -CryFont::FontTexture::CTextureSlotKey CFontTexture::GetTextureSlotKey(uint32 cChar, const Vec2i& glyphSize) const -{ - const Vec2i clampedGlyphSize(ClampGlyphSize(glyphSize, m_iCellWidth, m_iCellHeight)); - return CryFont::FontTexture::CTextureSlotKey(clampedGlyphSize, cChar); -} - -Vec2i CFontTexture::ClampGlyphSize(const Vec2i& glyphSize, int cellWidth, int cellHeight) -{ - const Vec2i maxCellDimensions(cellWidth, cellHeight); - Vec2i clampedGlyphSize(glyphSize); - - const bool hasZeroDimension = glyphSize.x == 0 || glyphSize.y == 0; - const bool isDefaultSize = glyphSize == CCryFont::defaultGlyphSize; - const bool exceedsDimensions = glyphSize.x > cellWidth || glyphSize.y > cellHeight; - const bool useMaxCellDimension = hasZeroDimension || isDefaultSize || exceedsDimensions; - if (useMaxCellDimension) - { - clampedGlyphSize = maxCellDimensions; - } - - return clampedGlyphSize; -} - -#endif // #if !defined(USE_NULLFONT_ALWAYS) diff --git a/Code/CryEngine/CryFont/FontTexture.h b/Code/CryEngine/CryFont/FontTexture.h deleted file mode 100644 index 45d0403f47..0000000000 --- a/Code/CryEngine/CryFont/FontTexture.h +++ /dev/null @@ -1,301 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYFONT_FONTTEXTURE_H -#define CRYINCLUDE_CRYFONT_FONTTEXTURE_H -#pragma once - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "GlyphCache.h" -#include "GlyphBitmap.h" -#include "CryFont.h" -#include "FFont.h" - -typedef uint8 FONT_TEXTURE_TYPE; - -// the number of slots in the glyph cache -// each slot ocupies ((glyph_bitmap_width * glyph_bitmap_height) + 24) bytes -#define FONT_GLYPH_CACHE_SIZE (1) - -// the glyph spacing in font texels between characters in proportional font mode (more correct would be to take the value in the character) -#define FONT_GLYPH_PROP_SPACING (1) - -// the size of a rendered space, this value gets multiplied by the default characted width -#define FONT_SPACE_SIZE (0.5f) - -// don't draw this char (used to avoid drawing color codes) -#define FONT_NOT_DRAWABLE_CHAR (0xffff) - -// smoothing methods -#define FONT_SMOOTH_NONE 0 -#define FONT_SMOOTH_BLUR 1 -#define FONT_SMOOTH_SUPERSAMPLE 2 - -// smoothing amounts -#define FONT_SMOOTH_AMOUNT_NONE 0 -#define FONT_SMOOTH_AMOUNT_2X 1 -#define FONT_SMOOTH_AMOUNT_4X 2 - -//! Stores glyph meta-data read from the font (FreeType). -//! -//! \sa CCacheSlot -typedef struct CTextureSlot -{ - Vec2i glyphSize = CCryFont::defaultGlyphSize; //!< Size of the rendered glyph stored in the font texture - uint16 wSlotUsage; //!< For LRU strategy, 0xffff is never released - uint32 cCurrentChar; //!< ~0 if not used for characters - int iTextureSlot; - int iHoriAdvance; //!< Advance width. See FT_Glyph_Metrics::horiAdvance. - float vTexCoord[2]; //!< Character position in the texture (not yet half texel corrected) - uint8 iCharWidth; //!< Glyph width (in pixel) - uint8 iCharHeight; //!< Glyph height (in pixel) - AZ::s32 iCharOffsetX; //!< Glyph's left-side bearing (in pixels). See FT_GlyphSlotRec::bitmap_left. - AZ::s32 iCharOffsetY; //!< Glyph's top bearing (in pixels). See FT_GlyphSlotRec::bitmap_top. - - void Reset() - { - wSlotUsage = 0; - cCurrentChar = ~0; - iHoriAdvance = 0; - iCharWidth = 0; - iCharHeight = 0; - iCharOffsetX = 0; - iCharOffsetY = 0; - } - - void SetNotReusable() - { - wSlotUsage = 0xffff; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -} CTextureSlot; - - -typedef std::vector CTextureSlotList; -typedef std::vector::iterator CTextureSlotListItor; - -namespace CryFont -{ - namespace FontTexture - { - //! Height and width pair for glyph size mapping - typedef Vec2i CGlyphSizeType; - - //! Pair for mapping a height and width size to a UTF32 character/glyph - typedef AZStd::pair CTextureSlotKey; - - //! Hasher for texture slot table keys (glyphsize-char code pair) - //! - //! Instead of creating our own custom hash, the types are broken down to their - //! native types (ints) and passed to existing hashes that handle those types. - struct HashTextureSlotTableKey - { - typedef CTextureSlotKey ArgumentType; - typedef AZStd::size_t ResultType; - typedef AZStd::pair Int32Pair; - typedef AZStd::pair Int32PairU32Pair; - ResultType operator()(const ArgumentType& value) const - { - // Utiliize existing hash function for pairs of ints - AZStd::hash pairHash; - return pairHash(Int32PairU32Pair(Int32Pair(value.first.x, value.first.y), value.second)); - } - }; - } -} - -//! Maps size-speicifc UTF32 glyphs to their corresponding texture slots -typedef AZStd::unordered_map CTextureSlotTable; - -typedef CTextureSlotTable::iterator CTextureSlotTableItor; -typedef CTextureSlotTable::const_iterator CTextureSlotTableItorConst; - -#ifdef WIN64 -#undef GetCharWidth -#undef GetCharHeight -#endif - -//! Stores the glyphs of a font within a single texture. -//! -//! The texture resolution is configurable, as is the number of slots within -//! the texture. -//! -//! A texture slot contains a single glyph within the font and are uniform -//! size throughout the font texture (each slot occupies the same size -//! regardless of the size of a glyph being stored, so a '.' occupies the -//! same amount of space as a 'W', for example). -//! -//! Font glyph buffers are read from FreeType and copied into the texture. -//! -//! \sa CTextureSlot, CFontRenderer -class CFontTexture -{ -public: - CFontTexture(); - ~CFontTexture(); - - int CreateFromFile(const string& szFileName, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount = 16, int iHeightCharCount = 16); - - //! Default texture slot width/height is 16x8 slots, allowing for 128 glyphs to be stored in the font texture. This was - //! previously 16x16, allowing 256 glyphs to be stored. For reference, there are 95 printable ASCII characters, so by - //! reducing the number of slots, the height of the font texture can be halved (for some nice memory savings). We may - //! want to make this configurable in the font XML (especially for languages with a large number of printable chars). - int CreateFromMemory(unsigned char* pFileData, int iDataSize, int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount, int iHeightCharCount, float sizeRatio); - - int Create(int iWidth, int iHeight, int iSmoothMethod, int iSmoothAmount, int iWidthCharCount = 16, int iHeightCharCount = 16, float sizeRatio = IFFontConstants::defaultSizeRatio); - int Release(); - - int SetEncoding(FT_Encoding pEncoding) { return m_pGlyphCache.SetEncoding(pEncoding); } - FT_Encoding GetEncoding() { return m_pGlyphCache.GetEncoding(); } - - int GetCellWidth() { return m_iCellWidth; } - int GetCellHeight() { return m_iCellHeight; } - - int GetWidth() { return m_iWidth; } - int GetHeight() { return m_iHeight; } - - int GetWidthCellCount() { return m_iWidthCellCount; } - int GetHeightCellCount() { return m_iHeightCellCount; } - - float GetTextureCellWidth() { return m_fTextureCellWidth; } - float GetTextureCellHeight() { return m_fTextureCellHeight; } - - FONT_TEXTURE_TYPE* GetBuffer() { return m_pBuffer; } - - uint32 GetSlotChar(int iSlot) const; - CTextureSlot* GetCharSlot(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize); - CTextureSlot* GetGradientSlot(); - - CTextureSlot* GetLRUSlot(); - CTextureSlot* GetMRUSlot(); - - //! Returns 1 if texture updated, returns 2 if texture not updated, returns 0 on error - //! \param szString A string of glyphs (UTF8) to added to the font texture (if they don't already exist in the font texture) - //! \param pUpdated is the number of slots updated - //! \param sizeRatio A sizing scale that gets applied to all glyphs sizes before they are stored in the font texture. - //! \param glyphSize The resolution to render the glyphs in szString at. - //! \param glyphFlags Controls hinting behavior for glyphs rendered to the font texture. - int PreCacheString(const char* szString, int* pUpdated = 0, float sizeRatio = IFFontConstants::defaultSizeRatio, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams()); - // Arguments: - // pSlot - function does nothing if this pointer is 0 - void GetTextureCoord(CTextureSlot * pSlot, float texCoords[4], int& iCharSizeX, int& iCharSizeY, int& iCharOffsetX, int& iCharOffsetY, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const; - int GetCharacterWidth(uint32 cChar) const; - //! Gets the horizontal advance for the given glyph/char. - //! \param cChar The glyph (UTF32) to get the horizontal advance for. - //! \param glyphSize The rendered size of the glyph to get the advance for (the same glyph could be stored in the font texture at multiple sizes). - int GetHorizontalAdvance(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const; - // int GetCharHeightByChar(wchar_t cChar); - - // useful for special feature rendering interleaved with fonts (e.g. box behind the text) - void CreateGradientSlot(); - - int WriteToFile(const string& szFileName); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pGlyphCache); - pSizer->AddObject(m_pSlotList); - //pSizer->AddContainer(m_pSlotTable); - pSizer->AddObject(m_pBuffer, m_iWidth * m_iHeight * sizeof(FONT_TEXTURE_TYPE)); - } - - bool GetMonospaced() const { return m_pGlyphCache.GetMonospaced(); } - - Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph); - - float GetAscenderToHeightRatio(); - -public: // --------------------------------------------------------------- - - //! Clamps the given glyph size to the given max cell width and height dimensions. - static Vec2i ClampGlyphSize(const Vec2i& glyphSize, int cellWidth, int cellHeight); - -private: // --------------------------------------------------------------- - - int CreateSlotList(int iListSize); - int ReleaseSlotList(); - - //! Updates the given font texture slot with the given glyph (UTF8) with the given parameters. If the glyph doesn't - //! exist in the font texture at the given size, then the glyph will be rendered to the font texture with the given - //! parameters. - //! \param iSlot Index of the texture slot to update within the slot list. - //! \param wSlotUsage Used for LRU strategy to determine how many times a glyph is referenced for retention within the font texture (before eviction). - //! \param cChar UTF32 glyph to store within the slot. - //! \param sizeRatio A sizing scale that should be applied to the glyph before being stored within the font texture. - //! \param glyphSize The size of the glyph to be rendered at within the font texture. - //! \param glyphFlags Specifies hinting behavior that should be applied to the glyph when rendered to the font texture. - int UpdateSlot(int iSlot, uint16 wSlotUsage, uint32 cChar, float sizeRatio, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams()); - - CryFont::FontTexture::CTextureSlotKey GetTextureSlotKey(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const; - - //! Calculates scaling info that should be applied when the rendered glyph size doesn't match the maximum glyph slot resolution. - //! - //! Glyphs can be re-rendered to glyph slots at smaller resolutions for pixel-perfect resolution (rather than applying a scale - //! to glyphs rendered at larger sizes). These scaling values allow clients of the font texture to use the glyphs without regard - //! to whether the glyphs have been re-rendered or not. - float GetRequestSizeWidthScale(const Vec2i& glyphSize) const - { - const int cellWidth = m_iCellWidth == 0 ? 1 : m_iCellWidth; - const float invCellWidth = 1.0f / cellWidth; - return glyphSize.x > 0 ? glyphSize.x * invCellWidth : 1.0f; - } - - //! Calculates scaling info that should be applied when the rendered glyph size doesn't match the maximum glyph slot resolution. - //! - //! Glyphs can be re-rendered to glyph slots at smaller resolutions for pixel-perfect resolution (rather than applying a scale - //! to glyphs rendered at larger sizes). These scaling values allow clients of the font texture to use the glyphs without regard - //! to whether the glyphs have been re-rendered or not. - float GetRequestSizeHeightScale(const Vec2i& glyphSize) const - { - const int cellHeight = m_iCellHeight == 0 ? 1 : m_iCellHeight; - const float invCellHeight = 1.0f / cellHeight; - return glyphSize.y > 0 ? glyphSize.y * invCellHeight : 1.0f; - } - - // -------------------------------- - - int m_iWidth; // whole texture cache width - int m_iHeight; // whole texture cache height - - float m_fInvWidth; - float m_fInvHeight; - - int m_iCellWidth; - int m_iCellHeight; - - float m_fTextureCellWidth; - float m_fTextureCellHeight; - - int m_iWidthCellCount; - int m_iHeightCellCount; - - int m_nTextureSlotCount; - - int m_iSmoothMethod; - int m_iSmoothAmount; - - CGlyphCache m_pGlyphCache; - CTextureSlotList m_pSlotList; - CTextureSlotTable m_pSlotTable; - - FONT_TEXTURE_TYPE* m_pBuffer; // [y*iWidth * x] x=0..iWidth-1, y=0..iHeight-1 - - uint16 m_wSlotUsage; -}; - -#endif // #if !defined(USE_NULLFONT_ALWAYS) - -#endif // CRYINCLUDE_CRYFONT_FONTTEXTURE_H diff --git a/Code/CryEngine/CryFont/GlyphBitmap.cpp b/Code/CryEngine/CryFont/GlyphBitmap.cpp deleted file mode 100644 index 8ae893c317..0000000000 --- a/Code/CryEngine/CryFont/GlyphBitmap.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Purpose: -// - Hold a glyph bitmap and blit it to the main texture - -#include "CryFont_precompiled.h" -#include "GlyphBitmap.h" -#include - - -//------------------------------------------------------------------------------------------------- -CGlyphBitmap::CGlyphBitmap() - : m_iWidth(0) - , m_iHeight(0) - , m_pBuffer(0) -{ -} - -//------------------------------------------------------------------------------------------------- -CGlyphBitmap::~CGlyphBitmap() -{ - Release(); -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::Create(int iWidth, int iHeight) -{ - Release(); - - m_pBuffer = new unsigned char[iWidth * iHeight]; - - if (!m_pBuffer) - { - return 0; - } - - m_iWidth = iWidth; - m_iHeight = iHeight; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::Release() -{ - if (m_pBuffer) - { - delete[] m_pBuffer; - } - m_pBuffer = 0; - m_iWidth = m_iHeight = 0; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::Blur(int iIterations) -{ - int cSum; - int yOffset; - int yupOffset; - int ydownOffset; - - for (int i = 0; i < iIterations; i++) - { - for (int y = 0; y < m_iHeight; y++) - { - yOffset = y * m_iWidth; - - if (y - 1 >= 0) - { - yupOffset = (y - 1) * m_iWidth; - } - else - { - yupOffset = (y) * m_iWidth; - } - - if (y + 1 < m_iHeight) - { - ydownOffset = (y + 1) * m_iWidth; - } - else - { - ydownOffset = (y) * m_iWidth; - } - - for (int x = 0; x < m_iWidth; x++) - { - cSum = m_pBuffer[yupOffset + x] + m_pBuffer[ydownOffset + x]; - - if (x - 1 >= 0) - { - cSum += m_pBuffer[yOffset + x - 1]; - } - else - { - cSum += m_pBuffer[yOffset + x]; - } - - if (x + 1 < m_iWidth) - { - cSum += m_pBuffer[yOffset + x + 1]; - } - else - { - cSum += m_pBuffer[yOffset + x]; - } - - m_pBuffer[yOffset + x] = cSum >> 2; - } - } - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::Scale(float fScaleX, float fScaleY) -{ - int iNewWidth = (int)(m_iWidth * fScaleX); - int iNewHeight = (int)(m_iHeight * fScaleY); - - unsigned char* pNewBuffer = new unsigned char[iNewWidth * iNewHeight]; - - if (!pNewBuffer) - { - return 0; - } - - float xFactor = m_iWidth / (float)iNewWidth; - float yFactor = m_iHeight / (float)iNewHeight; - - float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1; - int xCeil, yCeil, xFloor, yFloor, yNewOffset; - - unsigned char c0, c1, c2, c3; - - for (int y = 0; y < iNewHeight; ++y) - { - yFractioned = y * yFactor; - yFloor = (int)floor_tpl(yFractioned); - yCeil = yFloor + 1; - - if (yCeil >= m_iHeight) - { - yCeil = yFloor; - } - - yFraction = yFractioned - yFloor; - oneMinusY = 1.0f - yFraction; - - yNewOffset = y * iNewWidth; - - for (int x = 0; x < iNewWidth; ++x) - { - xFractioned = x * xFactor; - xFloor = (int)floor_tpl(xFractioned); - xCeil = xFloor + 1; - - if (xCeil >= m_iWidth) - { - xCeil = xFloor; - } - - xFraction = xFractioned - xFloor; - oneMinusX = 1.0f - xFraction; - - c0 = m_pBuffer[yFloor * m_iWidth + xFloor]; - c1 = m_pBuffer[yFloor * m_iWidth + xCeil]; - c2 = m_pBuffer[yCeil * m_iWidth + xFloor]; - c3 = m_pBuffer[yCeil * m_iWidth + xCeil]; - - fR0 = (oneMinusX * c0 + xFraction * c1); - fR1 = (oneMinusX * c2 + xFraction * c3); - - pNewBuffer[yNewOffset + x] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1)); - } - } - - m_iWidth = iNewWidth; - m_iHeight = iNewHeight; - - delete[] m_pBuffer; - m_pBuffer = pNewBuffer; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::Clear() -{ - memset(m_pBuffer, 0, m_iWidth * m_iHeight); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::BlitTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth) -{ - int ySrcOffset, yDestOffset; - - for (int y = 0; y < iSrcHeight; y++) - { - ySrcOffset = (iSrcY + y) * m_iWidth; - yDestOffset = (iDestY + y) * iDestWidth; - - for (int x = 0; x < iSrcWidth; x++) - { - pBuffer[yDestOffset + iDestX + x] = m_pBuffer[ySrcOffset + iSrcX + x]; - } - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::BlitTo32(unsigned int* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth) -{ - int ySrcOffset, yDestOffset; - char cColor; - - for (int y = 0; y < iSrcHeight; y++) - { - ySrcOffset = (iSrcY + y) * m_iWidth; - yDestOffset = (iDestY + y) * iDestWidth; - - for (int x = 0; x < iSrcWidth; x++) - { - cColor = m_pBuffer[ySrcOffset + iSrcX + x]; - - pBuffer[yDestOffset + iDestX + x] = (cColor << 24) | (255 << 16) | (255 << 8) | 255; - } - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::BlitScaledTo8(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth) -{ - int iNewWidth = (int)iDestWidth; - int iNewHeight = (int)iDestHeight; - - unsigned char* pNewBuffer = pBuffer; - - float xFactor = iSrcWidth / (float)iNewWidth; - float yFactor = iSrcHeight / (float)iNewHeight; - - float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1; - int xCeil, yCeil, xFloor, yFloor, yNewOffset; - - unsigned char c0, c1, c2, c3; - - for (int y = 0; y < iNewHeight; ++y) - { - yFractioned = y * yFactor; - yFloor = (int)floor_tpl(yFractioned); - yCeil = yFloor + 1; - - yFraction = yFractioned - yFloor; - oneMinusY = 1.0f - yFraction; - - yNewOffset = y * iDestBufferWidth; - - yFloor += iSrcY; - yCeil += iSrcY; - - if (yCeil >= m_iHeight) - { - yCeil = yFloor; - } - - for (int x = 0; x < iNewWidth; ++x) - { - xFractioned = x * xFactor; - xFloor = (int)floor_tpl(xFractioned); - xCeil = xFloor + 1; - - xFraction = xFractioned - xFloor; - oneMinusX = 1.0f - xFraction; - - xFloor += iSrcY; - xCeil += iSrcY; - - if (xCeil >= m_iWidth) - { - xCeil = xFloor; - } - - c0 = m_pBuffer[yFloor * m_iWidth + xFloor]; - c1 = m_pBuffer[yFloor * m_iWidth + xCeil]; - c2 = m_pBuffer[yCeil * m_iWidth + xFloor]; - c3 = m_pBuffer[yCeil * m_iWidth + xCeil]; - - fR0 = (oneMinusX * c0 + xFraction * c1); - fR1 = (oneMinusX * c2 + xFraction * c3); - - pNewBuffer[yNewOffset + x + iDestX] = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1)); - } - } - - return 1; -} - - -#if defined(__GNUC__) -#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7 -#pragma GCC diagnostic ignored "-Woverflow" -#endif -#endif -//------------------------------------------------------------------------------------------------- -int CGlyphBitmap::BlitScaledTo32(unsigned char* pBuffer, [[maybe_unused]] int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, [[maybe_unused]] int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth) -{ - int iNewWidth = (int)iDestWidth; - int iNewHeight = (int)iDestHeight; - - unsigned char* pNewBuffer = pBuffer; - - float xFactor = iSrcWidth / (float)iNewWidth; - float yFactor = iSrcHeight / (float)iNewHeight; - - float xFractioned, yFractioned, xFraction, yFraction, oneMinusX, oneMinusY, fR0, fR1; - int xCeil, yCeil, xFloor, yFloor, yNewOffset; - - unsigned char c0, c1, c2, c3, cColor; - - for (int y = 0; y < iNewHeight; ++y) - { - yFractioned = y * yFactor; - yFloor = (int)floor_tpl(yFractioned); - yCeil = yFloor + 1; - - yFraction = yFractioned - yFloor; - oneMinusY = 1.0f - yFraction; - - yNewOffset = y * iDestBufferWidth; - - yFloor += iSrcY; - yCeil += iSrcY; - - if (yCeil >= m_iHeight) - { - yCeil = yFloor; - } - - for (int x = 0; x < iNewWidth; ++x) - { - xFractioned = x * xFactor; - xFloor = (int)floor_tpl(xFractioned); - xCeil = xFloor + 1; - - xFraction = xFractioned - xFloor; - oneMinusX = 1.0f - xFraction; - - xFloor += iSrcY; - xCeil += iSrcY; - - if (xCeil >= m_iWidth) - { - xCeil = xFloor; - } - - c0 = m_pBuffer[yFloor * m_iWidth + xFloor]; - c1 = m_pBuffer[yFloor * m_iWidth + xCeil]; - c2 = m_pBuffer[yCeil * m_iWidth + xFloor]; - c3 = m_pBuffer[yCeil * m_iWidth + xCeil]; - - fR0 = (oneMinusX * c0 + xFraction * c1); - fR1 = (oneMinusX * c2 + xFraction * c3); - - cColor = (unsigned char)((oneMinusY * fR0) + (yFraction * fR1)); - - pNewBuffer[yNewOffset + x + iDestX] = 0xffffff | (cColor << 24); - } - } - - return 1; -} -#if defined(__GNUC__) -#if __GNUC__ >= 4 && __GNUC__MINOR__ < 7 -#pragma GCC diagnostic error "-Woverflow" -#endif -#endif -//------------------------------------------------------------------------------------------------- diff --git a/Code/CryEngine/CryFont/GlyphBitmap.h b/Code/CryEngine/CryFont/GlyphBitmap.h deleted file mode 100644 index 3d04a36cf7..0000000000 --- a/Code/CryEngine/CryFont/GlyphBitmap.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Purpose : Hold a glyph bitmap and blit it to the main texture - -#ifndef CRYINCLUDE_CRYFONT_GLYPHBITMAP_H -#define CRYINCLUDE_CRYFONT_GLYPHBITMAP_H - -#pragma once - - -class CGlyphBitmap -{ -public: - CGlyphBitmap(); - ~CGlyphBitmap(); - - int Create(int iWidth, int iHeight); - int Release(); - - unsigned char* GetBuffer() { return m_pBuffer; }; - - int Blur(int iIterations); - int Scale(float fScaleX, float fScaleY); - - int Clear(); - - int BlitTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth); - int BlitTo32(unsigned int* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth); - - int BlitScaledTo8(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth); - int BlitScaledTo32(unsigned char* pBuffer, int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight, int iDestX, int iDestY, int iDestWidth, int iDestHeight, int iDestBufferWidth); - - int GetWidth() { return m_iWidth; } - int GetHeight() { return m_iHeight; } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_pBuffer, m_iWidth * m_iHeight); - } - -private: - - unsigned char* m_pBuffer; - int m_iWidth; - int m_iHeight; -}; - -#endif // CRYINCLUDE_CRYFONT_GLYPHBITMAP_H diff --git a/Code/CryEngine/CryFont/GlyphCache.cpp b/Code/CryEngine/CryFont/GlyphCache.cpp deleted file mode 100644 index 96949009df..0000000000 --- a/Code/CryEngine/CryFont/GlyphCache.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Purpose: -// - Manage and cache glyphs, retrieving them from the renderer as needed - -#include "CryFont_precompiled.h" - -#if !defined(USE_NULLFONT_ALWAYS) - -#include "GlyphCache.h" -#include "FontTexture.h" - - - -//------------------------------------------------------------------------------------------------- -CGlyphCache::CGlyphCache() - : m_dwUsage(1) - , m_iGlyphBitmapWidth(0) - , m_iGlyphBitmapHeight(0) - , m_pScaleBitmap(0) -{ - m_pCacheTable.clear(); - m_pSlotList.clear(); -} - -//------------------------------------------------------------------------------------------------- -CGlyphCache::~CGlyphCache() -{ -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::Create(int iCacheSize, int iGlyphBitmapWidth, int iGlyphBitmapHeight, int iSmoothMethod, int iSmoothAmount, float sizeRatio) -{ - m_iSmoothMethod = iSmoothMethod; - m_iSmoothAmount = iSmoothAmount; - - m_iGlyphBitmapWidth = iGlyphBitmapWidth; - m_iGlyphBitmapHeight = iGlyphBitmapHeight; - - - if (!CreateSlotList(iCacheSize)) - { - ReleaseSlotList(); - - return 0; - } - - int iScaledGlyphWidth = 0; - int iScaledGlyphHeight = 0; - - switch (m_iSmoothMethod) - { - case FONT_SMOOTH_SUPERSAMPLE: - { - switch (m_iSmoothAmount) - { - case FONT_SMOOTH_AMOUNT_2X: - iScaledGlyphWidth = m_iGlyphBitmapWidth << 1; - iScaledGlyphHeight = m_iGlyphBitmapHeight << 1; - break; - case FONT_SMOOTH_AMOUNT_4X: - iScaledGlyphWidth = m_iGlyphBitmapWidth << 2; - iScaledGlyphHeight = m_iGlyphBitmapHeight << 2; - break; - } - } - break; - } - - if (iScaledGlyphWidth) - { - m_pScaleBitmap = new CGlyphBitmap; - - if (!m_pScaleBitmap) - { - Release(); - - return 0; - } - - if (!m_pScaleBitmap->Create(iScaledGlyphWidth, iScaledGlyphHeight)) - { - Release(); - - return 0; - } - - m_pFontRenderer.SetGlyphBitmapSize(iScaledGlyphWidth, iScaledGlyphHeight, sizeRatio); - } - else - { - m_pFontRenderer.SetGlyphBitmapSize(m_iGlyphBitmapWidth, m_iGlyphBitmapHeight, sizeRatio); - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::Release() -{ - ReleaseSlotList(); - - m_pCacheTable.clear(); - - if (m_pScaleBitmap) - { - m_pScaleBitmap->Release(); - - delete m_pScaleBitmap; - - m_pScaleBitmap = 0; - } - - m_iGlyphBitmapWidth = 0; - m_iGlyphBitmapHeight = 0; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::LoadFontFromFile(const string& szFileName) -{ - return m_pFontRenderer.LoadFromFile(szFileName); -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::LoadFontFromMemory(unsigned char* pFileBuffer, int iDataSize) -{ - return m_pFontRenderer.LoadFromMemory(pFileBuffer, iDataSize); -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::ReleaseFont() -{ - m_pFontRenderer.Release(); - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::GetGlyphBitmapSize(int* pWidth, int* pHeight) -{ - if (pWidth) - { - *pWidth = m_iGlyphBitmapWidth; - } - - if (pHeight) - { - *pHeight = m_iGlyphBitmapWidth; - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -void CGlyphCache::SetGlyphBitmapSize(int width, int height, float sizeRatio) -{ - m_pFontRenderer.SetGlyphBitmapSize(width, height, sizeRatio); -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::PreCacheGlyph(uint32 cChar, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams) -{ - CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)); - - if (pItor != m_pCacheTable.end()) - { - pItor->second->dwUsage = m_dwUsage; - - return 1; - } - - CCacheSlot* pSlot = GetLRUSlot(); - - if (!pSlot) - { - return 0; - } - - if (pSlot->dwUsage > 0) - { - UnCacheGlyph(pSlot->cCurrentChar, pSlot->glyphSize); - } - - if (m_pScaleBitmap) - { - int iOffsetMult = 1; - - switch (m_iSmoothAmount) - { - case FONT_SMOOTH_AMOUNT_2X: - iOffsetMult = 2; - break; - case FONT_SMOOTH_AMOUNT_4X: - iOffsetMult = 4; - break; - } - - m_pScaleBitmap->Clear(); - - if (!m_pFontRenderer.GetGlyph(m_pScaleBitmap, &pSlot->iHoriAdvance, &pSlot->iCharWidth, &pSlot->iCharHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, 0, 0, cChar, fontHintParams)) - { - return 0; - } - - pSlot->iCharWidth >>= iOffsetMult >> 1; - pSlot->iCharHeight >>= iOffsetMult >> 1; - - m_pScaleBitmap->BlitScaledTo8(pSlot->pGlyphBitmap.GetBuffer(), 0, 0, m_pScaleBitmap->GetWidth(), m_pScaleBitmap->GetHeight(), 0, 0, pSlot->pGlyphBitmap.GetWidth(), pSlot->pGlyphBitmap.GetHeight(), pSlot->pGlyphBitmap.GetWidth()); - } - else - { - if (!m_pFontRenderer.GetGlyph(&pSlot->pGlyphBitmap, &pSlot->iHoriAdvance, &pSlot->iCharWidth, &pSlot->iCharHeight, pSlot->iCharOffsetX, pSlot->iCharOffsetY, 0, 0, cChar, fontHintParams)) - { - return 0; - } - } - - if (m_iSmoothMethod == FONT_SMOOTH_BLUR) - { - pSlot->pGlyphBitmap.Blur(m_iSmoothAmount); - } - - pSlot->dwUsage = m_dwUsage; - pSlot->cCurrentChar = cChar; - pSlot->glyphSize = glyphSize; - - m_pCacheTable.insert(AZStd::pair(GetCacheSlotKey(cChar, glyphSize), pSlot)); - - return 1; -} - -int CGlyphCache::UnCacheGlyph(uint32 cChar, const Vec2i& glyphSize) -{ - CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)); - - if (pItor != m_pCacheTable.end()) - { - CCacheSlot* pSlot = pItor->second; - - pSlot->Reset(); - - m_pCacheTable.erase(pItor); - - return 1; - } - - return 0; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::GlyphCached(uint32 cChar, const Vec2i& glyphSize) -{ - return (m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)) != m_pCacheTable.end()); -} - -//------------------------------------------------------------------------------------------------- -CCacheSlot* CGlyphCache::GetLRUSlot() -{ - unsigned int dwMinUsage = 0xffffffff; - CCacheSlot* pLRUSlot = 0; - CCacheSlot* pSlot; - - CCacheSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - pSlot = *pItor; - - if (pSlot->dwUsage == 0) - { - return pSlot; - } - else - { - if (pSlot->dwUsage < dwMinUsage) - { - pLRUSlot = pSlot; - dwMinUsage = pSlot->dwUsage; - } - } - - pItor++; - } - - return pLRUSlot; -} - -//------------------------------------------------------------------------------------------------- -CCacheSlot* CGlyphCache::GetMRUSlot() -{ - unsigned int dwMaxUsage = 0; - CCacheSlot* pMRUSlot = 0; - CCacheSlot* pSlot; - - CCacheSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - pSlot = *pItor; - - if (pSlot->dwUsage != 0) - { - if (pSlot->dwUsage > dwMaxUsage) - { - pMRUSlot = pSlot; - dwMaxUsage = pSlot->dwUsage; - } - } - - pItor++; - } - - return pMRUSlot; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::GetGlyph(CGlyphBitmap** pGlyph, int* piHoriAdvance, int* piWidth, int* piHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, uint32 cChar, const Vec2i& glyphSize, const CFFont::FontHintParams& fontHintParams) -{ - CCacheTable::iterator pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)); - - if (pItor == m_pCacheTable.end()) - { - if (!PreCacheGlyph(cChar, glyphSize, fontHintParams)) - { - return 0; - } - } - - pItor = m_pCacheTable.find(GetCacheSlotKey(cChar, glyphSize)); - - pItor->second->dwUsage = m_dwUsage++; - (*pGlyph) = &pItor->second->pGlyphBitmap; - - if (piHoriAdvance) - { - *piHoriAdvance = pItor->second->iHoriAdvance; - } - - if (piWidth) - { - *piWidth = pItor->second->iCharWidth; - } - - if (piHeight) - { - *piHeight = pItor->second->iCharHeight; - } - - iCharOffsetX = pItor->second->iCharOffsetX; - iCharOffsetY = pItor->second->iCharOffsetY; - - return 1; -} - -//------------------------------------------------------------------------------------------------- -Vec2 CGlyphCache::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph) -{ - return m_pFontRenderer.GetKerning(leftGlyph, rightGlyph); -} - -//------------------------------------------------------------------------------------------------- -float CGlyphCache::GetAscenderToHeightRatio() -{ - return m_pFontRenderer.GetAscenderToHeightRatio(); -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::CreateSlotList(int iListSize) -{ - for (int i = 0; i < iListSize; i++) - { - CCacheSlot* pCacheSlot = new CCacheSlot; - - if (!pCacheSlot) - { - return 0; - } - - if (!pCacheSlot->pGlyphBitmap.Create(m_iGlyphBitmapWidth, m_iGlyphBitmapHeight)) - { - delete pCacheSlot; - - return 0; - } - - pCacheSlot->Reset(); - - pCacheSlot->iCacheSlot = i; - - m_pSlotList.push_back(pCacheSlot); - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -int CGlyphCache::ReleaseSlotList() -{ - CCacheSlotListItor pItor = m_pSlotList.begin(); - - while (pItor != m_pSlotList.end()) - { - (*pItor)->pGlyphBitmap.Release(); - - delete (*pItor); - - pItor = m_pSlotList.erase(pItor); - } - - return 1; -} - -//------------------------------------------------------------------------------------------------- -CryFont::GlyphCache::CCacheTableKey CGlyphCache::GetCacheSlotKey(uint32 cChar, const Vec2i& glyphSize) const -{ - const Vec2i clampedGlyphSize = CFontTexture::ClampGlyphSize(glyphSize, m_iGlyphBitmapWidth, m_iGlyphBitmapHeight); - return CryFont::GlyphCache::CCacheTableKey(clampedGlyphSize, cChar); -} - -#endif // #if !defined(USE_NULLFONT_ALWAYS) diff --git a/Code/CryEngine/CryFont/GlyphCache.h b/Code/CryEngine/CryFont/GlyphCache.h deleted file mode 100644 index c0cc1db555..0000000000 --- a/Code/CryEngine/CryFont/GlyphCache.h +++ /dev/null @@ -1,200 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// Purpose: -// - Manage and cache glyphs, retrieving them from the renderer as needed - -#ifndef CRYINCLUDE_CRYFONT_GLYPHCACHE_H -#define CRYINCLUDE_CRYFONT_GLYPHCACHE_H -#pragma once - -#if !defined(USE_NULLFONT_ALWAYS) - -#include -#include "GlyphBitmap.h" -#include "FontRenderer.h" -#include "CryFont.h" -#include - -//! Glyph cache slots store the bitmap buffer and glyph metadata from FreeType. -//! -//! This bitmap buffer is eventually copied to a CFontTexture texture buffer. -//! A glyph cache slot bitmap buffer only holds a single glyph, whereas the -//! CFontTexture stores multiple glyphs in a grid (row/col) format. -typedef struct CCacheSlot -{ - Vec2i glyphSize = CCryFont::defaultGlyphSize; //!< The render resolution of the glyph in the glyph bitmap - unsigned int dwUsage; - int iCacheSlot; - int iHoriAdvance; //!< Advance width. See FT_Glyph_Metrics::horiAdvance. - uint32 cCurrentChar; - - uint8 iCharWidth; //!< Glyph width (in pixel) - uint8 iCharHeight; //!< Glyph height (in pixel) - AZ::s32 iCharOffsetX; //!< Glyph's left-side bearing (in pixels). See FT_GlyphSlotRec::bitmap_left. - AZ::s32 iCharOffsetY; //!< Glyph's top bearing (in pixels). See FT_GlyphSlotRec::bitmap_top. - - CGlyphBitmap pGlyphBitmap; //!< Contains a buffer storing a copy of the glyph from FreeType - - void Reset() - { - dwUsage = 0; - cCurrentChar = ~0; - - iCharWidth = 0; - iCharHeight = 0; - iCharOffsetX = 0; - iCharOffsetY = 0; - - pGlyphBitmap.Clear(); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(pGlyphBitmap); - } -} CCacheSlot; - -namespace CryFont -{ - namespace GlyphCache - { - //! Height and width pair for glyph size mapping - typedef Vec2i CCacheTableGlyphSizeType; - - //! Pair for mapping a height and width size to a UTF32 character/glyph - typedef AZStd::pair CCacheTableKey; - - //! Hasher for glyph cache table keys (glyphsize-char code pair) - //! - //! Instead of creating our own custom hash, the types are broken down to their - //! native types (ints) and passed to existing hashes that handle those types. - struct HashGlyphCacheTableKey - { - typedef CCacheTableKey ArgumentType; - typedef AZStd::size_t ResultType; - typedef AZStd::pair Int32Pair; - typedef AZStd::pair Int32PairU32Pair; - ResultType operator()(const ArgumentType& value) const - { - AZStd::hash pairHash; - return pairHash(Int32PairU32Pair(Int32Pair(value.first.x, value.first.y), value.second)); - } - }; - } -} - -//! Maps size-speicifc UTF32 glyphs to their corresponding cache slots -typedef AZStd::unordered_map CCacheTable; - -typedef std::vector CCacheSlotList; -typedef std::vector::iterator CCacheSlotListItor; - - -#ifdef WIN64 -#undef GetCharWidth -#undef GetCharHeight -#endif - -//! The glyph cache maps UTF32 codepoints to their corresponding FreeType data. -//! -//! This cache is used to associate font glyph info (read from FreeType) with -//! UTF32 codepoints. Ultimately the glyph info will be read into a font texture -//! (CFontTexture) to avoid future FreeType lookups. -//! -//! If a CFontTexture is missing a glyph that is currently stored in the glyph -//! cache, the cached data can be returned instead of having to be rendered from -//! FreeType again. -//! -//! \sa CFontTexture -class CGlyphCache -{ -public: - CGlyphCache(); - ~CGlyphCache(); - - int Create(int iCacheSize, int iGlyphBitmapWidth, int iGlyphBitmapHeight, int iSmoothMethod, int iSmoothAmount, float sizeRatio); - int Release(); - - int LoadFontFromFile(const string& szFileName); - int LoadFontFromMemory(unsigned char* pFileBuffer, int iDataSize); - int ReleaseFont(); - - int SetEncoding(FT_Encoding pEncoding) { return m_pFontRenderer.SetEncoding(pEncoding); }; - FT_Encoding GetEncoding() { return m_pFontRenderer.GetEncoding(); }; - - int GetGlyphBitmapSize(int* pWidth, int* pHeight); - void SetGlyphBitmapSize(int width, int height, float sizeRatio); - - int PreCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams()); - int UnCacheGlyph(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize); - int GlyphCached(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize); - - CCacheSlot* GetLRUSlot(); - CCacheSlot* GetMRUSlot(); - - //! Obtains glyph information for the given UTF32 codepoint. - //! This information is obtained from a CCacheSlot that corresponds to - //! the given codepoint. If the codepoint doesn't exist within the cache - //! table (m_pCacheTable), then the information is obtain from FreeType - //! directly via CFontRenderer. - //! - //! Ultimately the glyph bitmap is copied into a font texture - //! (CFontTexture). Once the glyph is copied into the font texture then - //! the font texture is referenced directly rather than relying on the - //! glyph cache or FreeType. - //! - //! \sa CFontRenderer::GetGlyph, CFontTexture::UpdateSlot - int GetGlyph(CGlyphBitmap** pGlyph, int* piHoriAdvance, int* piWidth, int* piHeight, AZ::s32& iCharOffsetX, AZ::s32& iCharOffsetY, uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize, const CFFont::FontHintParams& glyphFlags = CFFont::FontHintParams()); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_pSlotList); - //pSizer->AddContainer(m_pCacheTable); - pSizer->AddObject(m_pScaleBitmap); - pSizer->AddObject(m_pFontRenderer); - } - - bool GetMonospaced() const { return m_pFontRenderer.GetMonospaced(); } - - Vec2 GetKerning(uint32_t leftGlyph, uint32_t rightGlyph); - - float GetAscenderToHeightRatio(); - -private: - - //! Returns a key for the cache table where the given char is mapped at the given size. - CryFont::GlyphCache::CCacheTableKey GetCacheSlotKey(uint32 cChar, const Vec2i& glyphSize = CCryFont::defaultGlyphSize) const; - - int CreateSlotList(int iListSize); - int ReleaseSlotList(); - - CCacheSlotList m_pSlotList; - CCacheTable m_pCacheTable; - - int m_iGlyphBitmapWidth; - int m_iGlyphBitmapHeight; - - int m_iSmoothMethod; - int m_iSmoothAmount; - - CGlyphBitmap* m_pScaleBitmap; - - CFontRenderer m_pFontRenderer; - - unsigned int m_dwUsage; -}; - -#endif // #if !defined(USE_NULLFONT_ALWAYS) - -#endif // CRYINCLUDE_CRYFONT_GLYPHCACHE_H diff --git a/Code/CryEngine/CryFont/ICryFont.cpp b/Code/CryEngine/CryFont/ICryFont.cpp deleted file mode 100644 index dfbaf65335..0000000000 --- a/Code/CryEngine/CryFont/ICryFont.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Create the font interface. - - -#include "CryFont_precompiled.h" - -#include -#include -#include - -#include "CryFont.h" -#if defined(USE_NULLFONT) -#include "NullFont.h" -#endif - -////////////////////////////////////////////////////////////////////////// -struct CSystemEventListner_Font - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - STLALLOCATOR_CLEANUP; - break; - } - } - } -}; -static CSystemEventListner_Font g_system_event_listener_font; - -/////////////////////////////////////////////// -extern "C" ICryFont * CreateCryFontInterface(ISystem * pSystem) -{ - ModuleInitISystem(pSystem, "CryFont"); - - if (gEnv->IsDedicated()) - { -#if defined(USE_NULLFONT) - return new CCryNullFont(); -#else - // The NULL font implementation must be present for all platforms - // supporting running as a pure dedicated server. - pSystem->GetILog()->LogError("Missing NULL font implementation for dedicated server"); - return NULL; -#endif - } - else - { -#if defined(USE_NULLFONT) && defined(USE_NULLFONT_ALWAYS) - return new CCryNullFont(); -#else - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_font); - return new CCryFont(pSystem); -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -class CEngineModule_CryFont - : public IEngineModule -{ - CRYINTERFACE_SIMPLE(IEngineModule) - CRYGENERATE_SINGLETONCLASS(CEngineModule_CryFont, "EngineModule_CryFont", 0x6758643f43214957, 0x9b920d898d31f434) - - ////////////////////////////////////////////////////////////////////////// - virtual const char* GetName() const { - return "CryFont"; - }; - virtual const char* GetCategory() const { return "CryEngine"; }; - - ////////////////////////////////////////////////////////////////////////// - virtual bool Initialize(SSystemGlobalEnvironment& env, [[maybe_unused]] const SSystemInitParams& initParams) - { - ISystem* pSystem = env.pSystem; - env.pCryFont = CreateCryFontInterface(pSystem); - return env.pCryFont != 0; - } -}; - -CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryFont) - -CEngineModule_CryFont::CEngineModule_CryFont() -{ -}; - -CEngineModule_CryFont::~CEngineModule_CryFont() -{ -}; diff --git a/Code/CryEngine/CryFont/NullFont.cpp b/Code/CryEngine/CryFont/NullFont.cpp deleted file mode 100644 index bddca1bbed..0000000000 --- a/Code/CryEngine/CryFont/NullFont.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Dummy font implementation (dedicated server) - -#include "CryFont_precompiled.h" - -#if defined(USE_NULLFONT) - -#include "NullFont.h" - -CNullFont CCryNullFont::ms_nullFont; - -#endif // USE_NULLFONT diff --git a/Code/CryEngine/CryFont/NullFont.h b/Code/CryEngine/CryFont/NullFont.h deleted file mode 100644 index 94fceeb9b0..0000000000 --- a/Code/CryEngine/CryFont/NullFont.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Dummy font implementation (dedicated server) - - -#ifndef CRYINCLUDE_CRYFONT_NULLFONT_H -#define CRYINCLUDE_CRYFONT_NULLFONT_H -#pragma once - - -#if defined(USE_NULLFONT) - -#include - -class CNullFont - : public IFFont -{ -public: - CNullFont() {} - virtual ~CNullFont() {} - - virtual int32 AddRef() { return 0; }; - virtual int32 Release() { return 0; }; - - virtual bool Load([[maybe_unused]] const char* pFontFilePath, [[maybe_unused]] unsigned int width, [[maybe_unused]] unsigned int height, [[maybe_unused]] unsigned int widthNumSlots, [[maybe_unused]] unsigned int heightNumSlots, [[maybe_unused]] unsigned int flags, [[maybe_unused]] float sizeRatio) { return true; } - virtual bool Load([[maybe_unused]] const char* pXMLFile) { return true; } - virtual void Free() {} - - virtual void DrawString([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {} - virtual void DrawString([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {} - - virtual void DrawStringW([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {} - virtual void DrawStringW([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) {} - - virtual Vec2 GetTextSize([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return Vec2(0.0f, 0.0f); } - virtual Vec2 GetTextSizeW([[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return Vec2(0.0f, 0.0f); } - - virtual size_t GetTextLength([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine) const { return 0; } - virtual size_t GetTextLengthW([[maybe_unused]] const wchar_t* pStr, [[maybe_unused]] const bool asciiMultiLine) const { return 0; } - - virtual void WrapText(string& result, [[maybe_unused]] float maxWidth, const char* pStr, [[maybe_unused]] const STextDrawContext& ctx) { result = pStr; } - virtual void WrapTextW(wstring& result, [[maybe_unused]] float maxWidth, const wchar_t* pStr, [[maybe_unused]] const STextDrawContext& ctx) { result = pStr; } - - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - virtual void GetGradientTextureCoord([[maybe_unused]] float& minU, [[maybe_unused]] float& minV, [[maybe_unused]] float& maxU, [[maybe_unused]] float& maxV) const {} - - virtual unsigned int GetEffectId([[maybe_unused]] const char* pEffectName) const { return 0; } - virtual unsigned int GetNumEffects() const { return 0; } - virtual const char* GetEffectName([[maybe_unused]] unsigned int effectId) const { return nullptr; } - virtual Vec2 GetMaxEffectOffset([[maybe_unused]] unsigned int effectId) const { return Vec2(); } - virtual bool DoesEffectHaveTransparency([[maybe_unused]] unsigned int effectId) const { return false; } - - virtual void AddCharsToFontTexture([[maybe_unused]] const char* pChars, [[maybe_unused]] int glyphSizeX, [[maybe_unused]] int glyphSizeY) override {} - virtual Vec2 GetKerning([[maybe_unused]] uint32_t leftGlyph, [[maybe_unused]] uint32_t rightGlyph, [[maybe_unused]] const STextDrawContext& ctx) const override { return Vec2(); } - virtual float GetAscender([[maybe_unused]] const STextDrawContext& ctx) const override { return 0.0f; } - virtual float GetBaseline([[maybe_unused]] const STextDrawContext& ctx) const override { return 0.0f; } - virtual float GetSizeRatio() const override { return IFFontConstants::defaultSizeRatio; } - virtual uint32 GetNumQuadsForText([[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return 0; } - virtual uint32 WriteTextQuadsToBuffers([[maybe_unused]] SVF_P2F_C4B_T2F_F4B* verts, [[maybe_unused]] uint16* indices, [[maybe_unused]] uint32 maxQuads, [[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float z, [[maybe_unused]] const char* pStr, [[maybe_unused]] const bool asciiMultiLine, [[maybe_unused]] const STextDrawContext& ctx) { return 0; } - virtual int GetFontTextureId() { return -1; } - virtual uint32 GetFontTextureVersion() { return 0; } -}; - -class CCryNullFont - : public ICryFont -{ -public: - virtual void Release() {} - virtual IFFont* NewFont([[maybe_unused]] const char* pFontName) { return &ms_nullFont; } - virtual IFFont* GetFont([[maybe_unused]] const char* pFontName) const { return &ms_nullFont; } - virtual FontFamilyPtr LoadFontFamily([[maybe_unused]] const char* pFontFamilyName) override { CRY_ASSERT(false); return nullptr; } - virtual FontFamilyPtr GetFontFamily([[maybe_unused]] const char* pFontFamilyName) override { CRY_ASSERT(false); return nullptr; } - virtual void AddCharsToFontTextures(FontFamilyPtr pFontFamily, [[maybe_unused]] const char* pChars, [[maybe_unused]] int glyphSizeX, [[maybe_unused]] int glyphSizeY) override {}; - virtual void SetRendererProperties([[maybe_unused]] IRenderer* pRenderer) {} - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - virtual string GetLoadedFontNames() const { return ""; } - virtual void OnLanguageChanged() override { } - virtual void ReloadAllFonts() override { } - -private: - static CNullFont ms_nullFont; -}; - -#endif // USE_NULLFONT - -#endif // CRYINCLUDE_CRYFONT_NULLFONT_H diff --git a/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake b/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CryFont/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CryFont/cryfont_files.cmake b/Code/CryEngine/CryFont/cryfont_files.cmake deleted file mode 100644 index f46a5b5b44..0000000000 --- a/Code/CryEngine/CryFont/cryfont_files.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - CryFont.cpp - FFont.cpp - FFontXML.cpp - FontRenderer.cpp - FontTexture.cpp - GlyphBitmap.cpp - GlyphCache.cpp - ICryFont.cpp - NullFont.cpp - CryFont.h - FBitmap.h - FFont.h - FontRenderer.h - FontTexture.h - GlyphBitmap.h - GlyphCache.h - NullFont.h - resource.h - CryFont_precompiled.h - CryFont_precompiled.cpp -) diff --git a/Code/CryEngine/CryFont/resource.h b/Code/CryEngine/CryFont/resource.h deleted file mode 100644 index ed88839421..0000000000 --- a/Code/CryEngine/CryFont/resource.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#define VS_VERSION_INFO 1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Code/CryEngine/CrySystem/CMakeLists.txt b/Code/CryEngine/CrySystem/CMakeLists.txt index 32ddc4a3a5..1a5593e5d8 100644 --- a/Code/CryEngine/CrySystem/CMakeLists.txt +++ b/Code/CryEngine/CrySystem/CMakeLists.txt @@ -60,8 +60,6 @@ ly_add_target( Legacy::CrySystem.XMLBinary Legacy::RemoteConsoleCore AZ::AzFramework - RUNTIME_DEPENDENCIES - Legacy::Cry3DEngine ) ly_add_source_properties( @@ -92,8 +90,6 @@ ly_add_target( AZ::AzCore Legacy::CryCommon Legacy::CryCommon.EngineSettings.Static - RUNTIME_DEPENDENCIES - Legacy::CryFont ) ################################################################################ diff --git a/Code/CryEngine/CrySystem/CPUDetect.cpp b/Code/CryEngine/CrySystem/CPUDetect.cpp index 9af68a1854..6d924a1514 100644 --- a/Code/CryEngine/CrySystem/CPUDetect.cpp +++ b/Code/CryEngine/CrySystem/CPUDetect.cpp @@ -52,11 +52,7 @@ # define cpuid(op, eax, ebx, ecx, edx) __asm__("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (op) : "cc"); #endif -#if defined(AZ_MONOLITHIC_BUILD) -extern int g_CpuFlags; -#else int g_CpuFlags; -#endif struct SAutoMaxPriority { diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake index 6c55ad5b08..bafe20e506 100644 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake +++ b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake @@ -14,14 +14,3 @@ # NOTE: functions in cmake are global, therefore adding functions to this file # is being avoided to prevent overriding functions declared in other targets platfrom # specific cmake files - -if (LY_MONOLITHIC_GAME) # Only Atom is supported in monolithic builds - set(LY_BUILD_DEPENDENCIES - PUBLIC - Legacy::CryRenderOther - ) -else() - set(LY_RUNTIME_DEPENDENCIES - Legacy::CryRenderMetal - ) -endif() diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index 47fdb362e9..e4fcc82552 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -676,17 +676,11 @@ private: //! @name Initialization routines //@{ bool InitConsole(); - bool InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams); - - bool InitFont(const SSystemInitParams& initParams); bool InitFileSystem(); bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams); bool InitStreamEngine(); - bool Init3DEngine(const SSystemInitParams& initParams); bool InitAudioSystem(const SSystemInitParams& initParams); bool InitShine(const SSystemInitParams& initParams); - bool OpenRenderLibrary(int type, const SSystemInitParams& initParams); - bool OpenRenderLibrary(const char* t_rend, const SSystemInitParams& initParams); //@} @@ -738,9 +732,6 @@ private: bool GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize); #endif - //! \brief Initializes the given IFFont member variable with the given name (internal use only). - bool LoadFontInternal(IFFont*& font, const string& fontName); - public: void EnableFloatExceptions(int type); diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index fcbf0b8215..d293f9ca80 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -43,8 +43,6 @@ #include #include -#include "CryFontBus.h" - #include #include @@ -247,24 +245,6 @@ CUNIXConsole* pUnixConsole; #define LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME "Libs/Localization/localization.xml" -#define LOAD_LEGACY_RENDERER_FOR_EDITOR false // If you set this to true you must also set 'ed_useAtomNativeViewport' to false (see /Code/Sandbox/Editor/ViewManager.cpp) -#define LOAD_LEGACY_RENDERER_FOR_LAUNCHER false - -////////////////////////////////////////////////////////////////////////// -// Where possible, these are defaults used to initialize cvars -// System.cfg can then be used to override them -// This includes the Game DLL, although it is loaded elsewhere - -#define DLL_FONT "CryFont" -#define DLL_3DENGINE "Cry3DEngine" -#define DLL_RENDERER_DX9 "CryRenderD3D9" -#define DLL_RENDERER_DX11 "CryRenderD3D11" -#define DLL_RENDERER_DX12 "CryRenderD3D12" -#define DLL_RENDERER_METAL "CryRenderMetal" -#define DLL_RENDERER_GL "CryRenderGL" -#define DLL_RENDERER_NULL "CryRenderNULL" -#define DLL_SHINE "LyShine" - ////////////////////////////////////////////////////////////////////////// #if defined(WIN32) || defined(LINUX) || defined(APPLE) # define DLL_MODULE_INIT_ISYSTEM "ModuleInitISystem" @@ -1079,58 +1059,6 @@ void CSystem::ShutdownModuleLibraries() #endif // !defined(AZ_MONOLITHIC_BUILD) } -////////////////////////////////////////////////////////////////////////// -bool CSystem::OpenRenderLibrary([[maybe_unused]] const char* t_rend, const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_6 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - - if (gEnv->IsDedicated()) - { - return OpenRenderLibrary(R_NULL_RENDERER, initParams); - } - - if (AZ::Interface::Get()) - { - return OpenRenderLibrary(R_DX11_RENDERER, initParams); - } - else if (azstricmp(t_rend, "DX9") == 0) - { - return OpenRenderLibrary(R_DX9_RENDERER, initParams); - } - else if (azstricmp(t_rend, "DX11") == 0) - { - return OpenRenderLibrary(R_DX11_RENDERER, initParams); - } - else if (azstricmp(t_rend, "DX12") == 0) - { - return OpenRenderLibrary(R_DX12_RENDERER, initParams); - } - else if (azstricmp(t_rend, "GL") == 0) - { - return OpenRenderLibrary(R_GL_RENDERER, initParams); - } - else if (azstricmp(t_rend, "METAL") == 0) - { - return OpenRenderLibrary(R_METAL_RENDERER, initParams); - } - else if (azstricmp(t_rend, "NULL") == 0) - { - return OpenRenderLibrary(R_NULL_RENDERER, initParams); - } - - AZ_Assert(false, "Unknown renderer type: %s", t_rend); - return false; -#endif -} - ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// @@ -1220,126 +1148,6 @@ wstring GetErrorStringUnsupportedGPU(const char* gpuName, unsigned int gpuVendor } #endif -bool CSystem::OpenRenderLibrary(int type, const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION; -#if defined(WIN32) || defined(WIN64) - if (!gEnv->IsDedicated()) - { - unsigned int gpuVendorId = 0, gpuDeviceId = 0, totVidMem = 0; - char gpuName[256]; - Win32SysInspect::DXFeatureLevel featureLevel = Win32SysInspect::DXFL_Undefined; - Win32SysInspect::GetGPUInfo(gpuName, sizeof(gpuName), gpuVendorId, gpuDeviceId, totVidMem, featureLevel); - - if (m_env.IsEditor()) - { -#if defined(EXTERNAL_CRASH_REPORTING) - CrashHandler::CrashHandlerBase::AddAnnotation("dx.feature.level", Win32SysInspect::GetFeatureLevelAsString(featureLevel)); - CrashHandler::CrashHandlerBase::AddAnnotation("gpu.name", gpuName); - CrashHandler::CrashHandlerBase::AddAnnotation("gpu.vendorId", std::to_string(gpuVendorId)); - CrashHandler::CrashHandlerBase::AddAnnotation("gpu.deviceId", std::to_string(gpuDeviceId)); - CrashHandler::CrashHandlerBase::AddAnnotation("gpu.memory", std::to_string(totVidMem)); -#endif - } - else - { - if (featureLevel < Win32SysInspect::DXFL_11_0) - { - const char logMsgFmt[] ("Unsupported GPU configuration!\n- %s (vendor = 0x%.4x, device = 0x%.4x)\n- Dedicated video memory: %d MB\n- Feature level: %s\n"); - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, logMsgFmt, gpuName, gpuVendorId, gpuDeviceId, totVidMem >> 20, GetFeatureLevelAsString(featureLevel)); - -#if !defined(_RELEASE) - const bool allowPrompts = m_env.pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "noprompt") == 0; -#else - const bool allowPrompts = true; -#endif // !defined(_RELEASE) - if (allowPrompts) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue..."); - const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedGPU(gpuName, gpuVendorId, gpuDeviceId).c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY); - if (mbRes == IDCANCEL) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup due to unsupported GPU."); - return false; - } - } - else - { -#if !defined(_RELEASE) - const bool obeyGPUCheck = m_env.pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "anygpu") == 0; -#else - const bool obeyGPUCheck = true; -#endif // !defined(_RELEASE) - if (obeyGPUCheck) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "No prompts allowed and unsupported GPU check active. Treating unsupported GPU as error and exiting."); - return false; - } - } - - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to continue despite unsupported GPU!"); - } - } - } -#endif -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_7 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif - - if (gEnv->IsDedicated()) - { - type = R_NULL_RENDERER; - } - const char* libname = ""; - if (AZ::Interface::Get()) - { - libname = DLL_RENDERER_NULL; - } - else if (type == R_DX9_RENDERER) - { - libname = DLL_RENDERER_DX9; - } - else if (type == R_DX11_RENDERER) - { - libname = DLL_RENDERER_DX11; - } - else if (type == R_DX12_RENDERER) - { - libname = DLL_RENDERER_DX12; - } - else if (type == R_NULL_RENDERER) - { - libname = DLL_RENDERER_NULL; - } - else if (type == R_GL_RENDERER) - { - libname = DLL_RENDERER_GL; - } - else if (type == R_METAL_RENDERER) - { - libname = DLL_RENDERER_METAL; - } - else - { - AZ_Assert(false, "Renderer did not initialize correctly; no valid renderer specified."); - return false; - } - - if (!InitializeEngineModule(libname, "EngineModule_CryRenderer", initParams)) - { - return false; - } - - if (!m_env.pRenderer) - { - AZ_Assert(false, "Renderer did not initialize correctly; it could not be found in the system environment."); - return false; - } - - return true; -} - ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// bool CSystem::InitConsole() @@ -1391,123 +1199,6 @@ ICVar* CSystem::attachVariable (const char* szVarName, int* pContainer, const ch return pVar; } -///////////////////////////////////////////////////////////////////////////////// -bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress("Initializing Renderer..."); - } - - if (m_bEditor) - { - m_env.pConsole->GetCVar("r_Width"); - - // save current screen width/height/bpp, so they can be restored on shutdown - m_iWidth = m_env.pConsole->GetCVar("r_Width")->GetIVal(); - m_iHeight = m_env.pConsole->GetCVar("r_Height")->GetIVal(); - m_iColorBits = m_env.pConsole->GetCVar("r_ColorBits")->GetIVal(); - } - - if (!OpenRenderLibrary(m_rDriver->GetString(), initParams)) - { - return false; - } - -#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_ANDROID) - if (m_rWidthAndHeightAsFractionOfScreenSize->GetFlags() & VF_WASINCONFIG) - { - int displayWidth = 0; - int displayHeight = 0; - if (GetPrimaryPhysicalDisplayDimensions(displayWidth, displayHeight)) - { - // Ideally we would probably want to clamp this at the source, - // but I don't believe cvars support specifying a valid range. - float scaleFactor = 1.0f; - - if(IsTablet()) - { - scaleFactor = AZ::GetClamp(m_rTabletWidthAndHeightAsFractionOfScreenSize->GetFVal(), 0.1f, 1.0f); - } - else - { - scaleFactor = AZ::GetClamp(m_rWidthAndHeightAsFractionOfScreenSize->GetFVal(), 0.1f, 1.0f); - } - - displayWidth *= scaleFactor; - displayHeight *= scaleFactor; - - const int maxWidth = m_rMaxWidth->GetIVal(); - if (maxWidth > 0 && maxWidth < displayWidth) - { - const float widthScaleFactor = static_cast(maxWidth) / static_cast(displayWidth); - displayWidth *= widthScaleFactor; - displayHeight *= widthScaleFactor; - } - - const int maxHeight = m_rMaxHeight->GetIVal(); - if (maxHeight > 0 && maxHeight < displayHeight) - { - const float heightScaleFactor = static_cast(maxHeight) / static_cast(displayHeight); - displayWidth *= heightScaleFactor; - displayHeight *= heightScaleFactor; - } - - m_rWidth->Set(displayWidth); - m_rHeight->Set(displayHeight); - } - } -#endif // defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_ANDROID) - - if (m_env.pRenderer) - { - // This is crucial as textures suffix are hard coded to context and we need to initialize - // the texture semantics to look it up. - m_env.pRenderer->InitTexturesSemantics(); - -#ifdef WIN32 - SCustomRenderInitArgs args; - args.appStartedFromMediaCenter = strstr(initParams.szSystemCmdLine, "ReLaunchMediaCenter") != 0; - - m_hWnd = m_env.pRenderer->Init(0, 0, m_rWidth->GetIVal(), m_rHeight->GetIVal(), m_rColorBits->GetIVal(), m_rDepthBits->GetIVal(), m_rStencilBits->GetIVal(), m_rFullscreen->GetIVal() ? true : false, initParams.bEditor, hinst, hwnd, false, &args, initParams.bShaderCacheGen); - //Timur, Not very clean code, we need to push new hwnd value to the system init params, so other modules can used when initializing. - (const_cast(&initParams))->hWnd = m_hWnd; - - - bool retVal = (initParams.bShaderCacheGen || m_hWnd != 0); - AZ_Assert(retVal, "Renderer failed to initialize correctly."); - return retVal; -#else // WIN32 - WIN_HWND h = m_env.pRenderer->Init(0, 0, m_rWidth->GetIVal(), m_rHeight->GetIVal(), m_rColorBits->GetIVal(), m_rDepthBits->GetIVal(), m_rStencilBits->GetIVal(), m_rFullscreen->GetIVal() ? true : false, initParams.bEditor, hinst, hwnd, false, nullptr, initParams.bShaderCacheGen); - -#if (defined(LINUX) && !defined(AZ_PLATFORM_ANDROID)) - return true; -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_8 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - bool retVal = (initParams.bShaderCacheGen || h != 0); - if (retVal) - { - return true; - } - - AZ_Assert(false, "Renderer failed to initialize correctly."); - return false; -#endif -#endif - } - return true; -} - - - ///////////////////////////////////////////////////////////////////////////////// bool CSystem::InitFileSystem() { @@ -1662,68 +1353,6 @@ bool CSystem::InitStreamEngine() return true; } -///////////////////////////////////////////////////////////////////////////////// -bool CSystem::InitFont(const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - bool fontInited = false; - AZ::CryFontCreationRequestBus::BroadcastResult(fontInited, &AZ::CryFontCreationRequests::CreateCryFont, m_env, initParams); - if (!fontInited && !InitializeEngineModule(DLL_FONT, "EngineModule_CryFont", initParams)) - { - return false; - } - - if (!m_env.pCryFont) - { - AZ_Assert(false, "Font System did not initialize correctly; it could not be found in the system environment"); - return false; - } - - if (gEnv->IsDedicated()) - { - return true; - } - - if (!LoadFontInternal(m_pIFont, "default")) - { - return false; - } - - if (!LoadFontInternal(m_pIFontUi, "default-ui")) - { - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CSystem::Init3DEngine(const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - if (!InitializeEngineModule(DLL_3DENGINE, "EngineModule_Cry3DEngine", initParams)) - { - return false; - } - - if (!m_env.p3DEngine) - { - AZ_Assert(false, "3D Engine did not initialize correctly; it could not be found in the system environment"); - return false; - } - - if (!m_env.p3DEngine->Init()) - { - return false; - } - m_pProcess = m_env.p3DEngine; - m_pProcess->SetFlags(PROC_3DENGINE); - - return true; -} - ////////////////////////////////////////////////////////////////////////// bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) { @@ -2785,42 +2414,6 @@ AZ_POP_DISABLE_WARNING } InlineInitializationProcessing("CSystem::Init InitLocalizations"); - ////////////////////////////////////////////////////////////////////////// - // RENDERER - ////////////////////////////////////////////////////////////////////////// - const bool loadLegacyRenderer = gEnv->IsEditor() ? - LOAD_LEGACY_RENDERER_FOR_EDITOR : - LOAD_LEGACY_RENDERER_FOR_LAUNCHER; - if (loadLegacyRenderer && !startupParams.bSkipRenderer) - { - AZ_Assert(CryMemory::IsHeapValid(), "CryMemory must be valid before initializing renderer."); - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Renderer initialization"); - - if (!InitRenderer(m_hInst, m_hWnd, startupParams)) - { - return false; - } - AZ_Assert(CryMemory::IsHeapValid(), "CryMemory must be valid after initializing renderer."); - if (m_env.pRenderer) - { - bool bMultiGPUEnabled = false; - m_env.pRenderer->EF_Query(EFQ_MultiGPUEnabled, bMultiGPUEnabled); - if (bMultiGPUEnabled) - { - LoadConfiguration("mgpu.cfg"); - } - } - - InlineInitializationProcessing("CSystem::Init InitRenderer"); - - if (m_env.pCryFont) - { - m_env.pCryFont->SetRendererProperties(m_env.pRenderer); - } - - AZ_Assert(m_env.pRenderer || startupParams.bSkipRenderer, "The renderer did not initialize correctly."); - } - #if !defined(AZ_RELEASE_BUILD) && defined(AZ_PLATFORM_ANDROID) m_thermalInfoHandler = AZStd::make_unique(); #endif @@ -2928,24 +2521,10 @@ AZ_POP_DISABLE_WARNING } } - ////////////////////////////////////////////////////////////////////////// - // FONT - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipFont) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Font initialization"); - if (!InitFont(startupParams)) - { - return false; - } - } - - InlineInitializationProcessing("CSystem::Init InitFonts"); - // The last update to the loading screen message was 'Initializing CryFont...' // Compiling the default system textures can be the lengthiest portion of // editor initialization, so it is useful to inform users that they are waiting on - // the necessary default textures to compile, and that they are not waiting on CryFont. + // the necessary default textures to compile. if (m_pUserCallback) { m_pUserCallback->OnInitProgress("First time asset processing - may take a minute..."); @@ -3040,28 +2619,6 @@ AZ_POP_DISABLE_WARNING return false; } - ////////////////////////////////////////////////////////////////////////// - // Init 3d engine - ////////////////////////////////////////////////////////////////////////// - if (loadLegacyRenderer && !startupParams.bSkipRenderer && !startupParams.bShaderCacheGen) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Initializing 3D Engine"); - INDENT_LOG_DURING_SCOPE(); - - if (!Init3DEngine(startupParams)) - { - return false; - } - - // try flush to keep renderer busy - if (m_env.pRenderer) - { - m_env.pRenderer->TryFlush(); - } - - InlineInitializationProcessing("CSystem::Init Init3DEngine"); - } - ////////////////////////////////////////////////////////////////////////// // SERVICE NETWORK ////////////////////////////////////////////////////////////////////////// @@ -4223,24 +3780,3 @@ void CSystem::SetAssertVisible(bool bAssertVisble) { m_bIsAsserting = bAssertVisble; } - -bool CSystem::LoadFontInternal(IFFont*& font, const string& fontName) -{ - font = m_env.pCryFont->NewFont(fontName); - if (!font) - { - AZ_Assert(false, "Could not instantiate the default font."); - return false; - } - - ////////////////////////////////////////////////////////////////////////// - string szFontPath = "Fonts/" + fontName + ".font"; - - if (!font->Load(szFontPath.c_str())) - { - AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Could not load font: %s. Make sure the program is running from the correct working directory.", szFontPath.c_str()); - return false; - } - - return true; -} diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp index 01828175db..a544cef4a5 100644 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ b/Code/CryEngine/CrySystem/SystemRender.cpp @@ -58,75 +58,6 @@ extern CMTSafeHeap* g_pPakHeap; #if defined(AZ_PLATFORM_ANDROID) #include -#elif defined(AZ_PLATFORM_IOS) - -#if defined(AZ_MONOLITHIC_BUILD) -extern bool UIKitGetPrimaryPhysicalDisplayDimensions(int& o_widthPixels, int& o_heightPixels); -#else - -using NativeScreenType = UIScreen; -using NativeWindowType = UIWindow; - -//////////////////////////////////////////////////////////////////////////////// -bool UIKitGetPrimaryPhysicalDisplayDimensions(int& o_widthPixels, int& o_heightPixels) -{ - - NativeScreenType* nativeScreen = [NativeScreenType mainScreen]; - CGRect screenBounds = [nativeScreen bounds]; - CGFloat screenScale = [nativeScreen scale]; - o_widthPixels = static_cast(screenBounds.size.width * screenScale); - o_heightPixels = static_cast(screenBounds.size.height * screenScale); - - const bool isScreenLandscape = o_widthPixels > o_heightPixels; - - UIInterfaceOrientation uiOrientation = UIInterfaceOrientationUnknown; -#if defined(__IPHONE_13_0) || defined(__TVOS_13_0) - if(@available(iOS 13.0, tvOS 13.0, *)) - { - UIWindow* foundWindow = nil; - - //Find the key window - NSArray* windows = [[UIApplication sharedApplication] windows]; - for (UIWindow* window in windows) - { - if (window.isKeyWindow) - { - foundWindow = window; - break; - } - } - - //Check if the key window is found - if(foundWindow) - { - uiOrientation = foundWindow.windowScene.interfaceOrientation; - } - else - { - //If no key window is found create a temporary window in order to extract the orientation - //This can happen as this function gets called before the renderer is initialized - CGRect screenBounds = [[NativeScreenType mainScreen] bounds]; - UIWindow* tempWindow = [[NativeWindowType alloc] initWithFrame: screenBounds]; - uiOrientation = tempWindow.windowScene.interfaceOrientation; - [tempWindow release]; - } - } -#else - uiOrientation = UIApplication.sharedApplication.statusBarOrientation; -#endif - - const bool isInterfaceLandscape = UIInterfaceOrientationIsLandscape(uiOrientation); - if (isScreenLandscape != isInterfaceLandscape) - { - const int width = o_widthPixels; - o_widthPixels = o_heightPixels; - o_heightPixels = width; - } - - return true; -} -#endif - #endif extern int CryMemoryGetAllocatedSize(); @@ -151,8 +82,6 @@ bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthP return true; #elif defined(AZ_PLATFORM_ANDROID) return AZ::Android::Utils::GetWindowSize(o_widthPixels, o_heightPixels); -#elif defined(AZ_PLATFORM_IOS) - return UIKitGetPrimaryPhysicalDisplayDimensions(o_widthPixels, o_heightPixels); #else return false; #endif diff --git a/Code/CryEngine/RenderDll/CMakeLists.txt b/Code/CryEngine/RenderDll/CMakeLists.txt deleted file mode 100644 index 90594c4dd9..0000000000 --- a/Code/CryEngine/RenderDll/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -add_subdirectory(XRenderD3D9) -add_subdirectory(XRenderNULL) diff --git a/Code/CryEngine/RenderDll/Common/AMD/LICENSING.txt b/Code/CryEngine/RenderDll/Common/AMD/LICENSING.txt deleted file mode 100644 index 958befd68b..0000000000 --- a/Code/CryEngine/RenderDll/Common/AMD/LICENSING.txt +++ /dev/null @@ -1,22 +0,0 @@ -Advanced Micro Devices, Inc. -Software License Agreement – Sample Source Code - -IMPORTANT—READ CAREFULLY: Do not install, copy or use the enclosed software, documentation and/or materials until you have carefully read and agreed to the following terms and conditions. This is a legal agreement (“Agreement”) between you (either an individual or an entity) (“You”) and Advanced Micro Devices, Inc. (“AMD”). -If You do not agree to the terms of this Agreement, do not install, copy or use this software, documentation or materials or any portion thereof. By loading or using the software provided herewith, which may include binary code, source code, associated install scripts and online or electronic documentation, or materials or any portion thereof, that is made available by AMD to download from any media (collectively “Software”), You agree to all of the terms of this Agreement. -1. LICENSE: -a. Subject to the terms and conditions of this Agreement, AMD grants You the following non-exclusive, non-transferable, royalty-free, limited copyright license to (i) download, copy, use, modify, and create derivative works of the source code version of the Software and materials associated with this Agreement, including without limitation printed documentation, (collectively, “Materials”) for internal evaluation only with AMD processors or graphics products; and (ii) make and distribute copies of the Materials and derivative works thereof created by You in binary code form only for use only with Your products that support AMD processors and in computer systems including AMD processors or graphics products, provided that You agree to include all copyright legends and other legal notices that may appear in the Software. Additionally, You agree that any distribution of the Materials to a third party, must include a software license agreement with terms and conditions that are at least as restrictive and protective of AMD’s intellectual property rights in the Materials as the terms and conditions set forth herein, including but not limited to the terms and conditions set forth in Sections 4 through 7 herein. Except for the limited license granted herein, You shall have no other rights in the Materials, whether express, implied, arising by estoppel or otherwise. -b. Except as expressly licensed herein, You do not have the right to (i) distribute, rent, lease, sell, sublicense, assign, or otherwise transfer the Materials, in whole or in part, to third parties for commercial or for non-commercial use; or (ii) modify, disassemble, reverse engineer, or decompile the Software, or otherwise reduce any part of the Software to any human readable form. -c. AMD is under no obligation to support or provide maintenance for the Materials or to provide any updates or enhancements to You. -2. FEEDBACK: You may provide AMD feedback, suggestions or opinions as to the Software, its features, and desired enhancements or changes. If You provide feedback, suggestions or opinions to AMD regarding any new features, use, functionality, or change to the Software or any materials related to the Software, You hereby agree to grant, and do grant, AMD all rights needed for AMD to incorporate and commercialize any new feature, use, functionality, or change at no charge or encumbrance to AMD. You agree that AMD may disclose such feedback, suggestions or opinions to any third party in any manner, and You agree that AMD has the ability to sublicense any of the foregoing rights in any feedback, suggestions or opinions or AMD products or services in any form to any third party without restriction. -3. OWNERSHIP AND COPYRIGHT OF MATERIALS: You agree that the Materials are owned by AMD and/or AMD’s licensors (if any), and are protected by United States and foreign intellectual property laws (e.g. patent and copyright laws) and international treaty provisions. You will not remove the copyright notice from the Materials. You agree to prevent any unauthorized copying of the Materials. All title and copyrights in and to the Materials, all copies thereof (in whole or in part, and in any form), and all rights therein shall remain vested in AMD. Except as expressly provided herein, AMD does not grant any express or implied right to You under AMD patents, copyrights, trademarks, or trade secret information and such rights are reserved to AMD and/or its licensors. -4. WARRANTY DISCLAIMER: THE MATERIALS ARE PROVIDED “AS IS” WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, TITLE, OR FITNESS FOR ANY PARTICULAR PURPOSE, OR THOSE ARISING FROM CUSTOM OF TRADE OR COURSE OF USAGE. -FOR CLARIFICATION, THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE MATERIALS REMAINS WITH YOU. AMD DOES NOT WARRANT, GUARANTEE, OR MAKE ANY REPRESENTATIONS AS TO THE CORRECTNESS, ACCURACY, COMPLETENESS, QUALITY, OR RELIABILITY OF THE MATERIALS. AMD DOES NOT WARRANT THAT OPERATION OF THE MATERIALS WILL BE UNINTERRUPTED OR ERROR-FREE. YOU ARE RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH THE USE OF THE MATERIALS, INCLUDING BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO OR LOSS OF DATA, PROGRAMS OR EQUIPMENT, AND UNAVAILABILITY OR INTERRUPTION OF OPERATIONS. Some jurisdictions do not allow for the exclusion or limitation of implied warranties, so the above limitations or exclusions may not apply to You. -5. LIMITATION OF LIABILITY: IN NO EVENT SHALL AMD OR ITS DIRECTORS, OFFICERS, EMPLOYEES AND AGENTS, ITS SUPPLIERS OR ITS LICENSORS BE LIABLE TO YOUOR ANY THIRD PARTIES IN RECEIPT OF THE MATERIALS UNDER ANY THEORY OF LIABILITY, WHETHER EQUITABLE, LEGAL OR COMMON LAW ACTION ARISING HEREUNDER FOR CONTRACT, STRICT LIABILITY, INDEMNITY, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE FOR DAMAGES WHICH, IN THE AGGREGATE EXCEED TEN DOLLARS ($10.00). IN NO EVENT SHALL AMD BE LIABLE FOR ANY CONSEQUENTIAL, INCIDENTAL, PUNITIVE OR SPECIAL DAMAGES, INCLUDING, BUT NOT LIMITED TO LOSS OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION ARISING OUT OF THE USE OF OR INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BY USING THE MATERIALS WITHOUT CHARGE, YOU ACCEPT THIS ALLOCATION OF RISK. Because some jurisdictions prohibit the exclusion or limitation of liability for consequential or incidental damages, the above limitation may not apply to You. -6. EXPORT RESTRICTIONS: You shall adhere to all applicable U.S., European, and other export laws, including but not limited to the U.S. Export Administration Regulations (“EAR”), (15 C.F.R. Sections 730 through 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, You hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the EAR, You will not (1) export, re-export or release to a national of a country in Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code it receives from AMD, or (2) export to Country Groups D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 of EAR). For the most current Country Group listings, or for additional information about the EAR or Your obligations under those regulations, please refer to the U.S. Bureau of Industry and Security’s website at http://www.bis.doc.gov/. -7. U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with “RESTRICTED RIGHTS.” Use, duplication or disclosure by the Government is subject to restrictions as set forth in FAR52.227-14 and DFAR252.227-7013, et seq., or its successor. Use of the Materials by the Government constitutes acknowledgment of AMD’s proprietary rights in them. -8. TERMINATION OF LICENSE: This Agreement will terminate immediately without notice from AMD or judicial resolution if You fail to comply with any provisions of this Agreement. Upon termination of this Agreement, You must delete or destroy all copies of the Materials. -9. SURVIVAL: Sections 1(b)-(c), 2, 3, 4, 5, 6, 7, 9, 10, 11, 12 and 13 shall survive any expiration or termination of this Agreement. -10. APPLICABLE LAWS: Any claim arising under or relating to this Agreement shall be governed by and construed in accordance with the substantive laws of the State of California, without regard to principles of conflict of laws. Each party hereto submits to the jurisdiction of the state and federal courts of Santa Clara County and the Northern District of California for the purposes of all legal proceedings arising out of or relating to this Agreement or the subject matter hereof. Each party waives any objection which it may have to contest such forum. -11. Severability: Should any term of this Agreement be declared void or unenforceable by any court of competent jurisdiction, such declaration shall have no effect on the remaining terms hereof. -12. No Waiver: The failure of either party to enforce any rights granted hereunder or to take action against the other party in the event of any breach hereunder shall not be deemed a waiver by that party as to subsequent enforcement of rights or subsequent actions in the event of future breaches. -13. ENTIRE AGREEMENT: This Agreement constitutes the entire agreement between the parties and supersedes any prior or contemporaneous oral or written agreements with respect to the subject matter of this Agreement. \ No newline at end of file diff --git a/Code/CryEngine/RenderDll/Common/CommonRender.cpp b/Code/CryEngine/RenderDll/Common/CommonRender.cpp deleted file mode 100644 index 87cae00f68..0000000000 --- a/Code/CryEngine/RenderDll/Common/CommonRender.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Crytek Common render helper functions and structures declarations. - - -#include "RenderDll_precompiled.h" - - -// Resource manager internal variables. -ResourceClassMap CBaseResource::m_sResources; -CryCriticalSection CBaseResource::s_cResLock; - -CBaseResource& CBaseResource::operator=([[maybe_unused]] const CBaseResource& Src) -{ - return *this; -} - -bool CBaseResource::IsValid() -{ - AUTO_LOCK(s_cResLock); // Not thread safe without this - - SResourceContainer* pContainer = GetResourcesForClass(m_ClassName); - if (!pContainer) - { - return false; - } - - ResourceClassMapItor itRM = m_sResources.find(m_ClassName); - - if (itRM == m_sResources.end()) - { - return false; - } - if (itRM->second != pContainer) - { - return false; - } - ResourcesMapItor itRL = itRM->second->m_RMap.find(m_NameCRC); - if (itRL == itRM->second->m_RMap.end()) - { - return false; - } - if (itRL->second != this) - { - return false; - } - - return true; -} - -SResourceContainer* CBaseResource::GetResourcesForClass(const CCryNameTSCRC& className) -{ - ResourceClassMapItor itRM = m_sResources.find(className); - if (itRM == m_sResources.end()) - { - return NULL; - } - return itRM->second; -} - -CBaseResource* CBaseResource::GetResource(const CCryNameTSCRC& className, int nID, bool bAddRef) -{ - FUNCTION_PROFILER_RENDER_FLAT - AUTO_LOCK(s_cResLock); // Not thread safe without this - - SResourceContainer* pRL = GetResourcesForClass(className); - if (!pRL) - { - return NULL; - } - - int nIndex = RListIndexFromId(nID); - - //assert(pRL->m_RList.size() > nID); - if (nIndex >= (int)pRL->m_RList.size() || nIndex < 0) - { - return NULL; - } - CBaseResource* pBR = pRL->m_RList[nIndex]; - if (pBR) - { - if (bAddRef) - { - pBR->AddRef(); - } - return pBR; - } - return NULL; -} - -CBaseResource* CBaseResource::GetResource(const CCryNameTSCRC& className, const CCryNameTSCRC& Name, bool bAddRef) -{ - FUNCTION_PROFILER_RENDER_FLAT - AUTO_LOCK(s_cResLock); // Not thread safe without this - - SResourceContainer* pRL = GetResourcesForClass(className); - if (!pRL) - { - return NULL; - } - - CBaseResource* pBR = NULL; - ResourcesMapItor itRL = pRL->m_RMap.find(Name); - if (itRL != pRL->m_RMap.end()) - { - pBR = itRL->second; - if (bAddRef) - { - pBR->AddRef(); - } - return pBR; - } - return NULL; -} - -bool CBaseResource::Register(const CCryNameTSCRC& className, const CCryNameTSCRC& Name) -{ - AUTO_LOCK(s_cResLock); // Not thread safe without this - - SResourceContainer* pRL = GetResourcesForClass(className); - if (!pRL) - { - pRL = new SResourceContainer; - m_sResources.insert(ResourceClassMapItor::value_type(className, pRL)); - } - - assert(pRL); - if (!pRL) - { - return false; - } - - ResourcesMapItor itRL = pRL->m_RMap.find(Name); - if (itRL != pRL->m_RMap.end()) - { - return false; - } - pRL->m_RMap.insert(ResourcesMapItor::value_type(Name, this)); - int nIndex; - if (pRL->m_AvailableIDs.size()) - { - ResourceIds::iterator it = pRL->m_AvailableIDs.end() - 1; - nIndex = RListIndexFromId(*it); - pRL->m_AvailableIDs.erase(it); - assert(nIndex < (int)pRL->m_RList.size()); - pRL->m_RList[nIndex] = this; - } - else - { - nIndex = pRL->m_RList.size(); - pRL->m_RList.push_back(this); - } - m_nID = IdFromRListIndex(nIndex); - m_NameCRC = Name; - m_ClassName = className; - m_nRefCount = 1; - - return true; -} - -bool CBaseResource::UnRegister() -{ - AUTO_LOCK(s_cResLock); // Not thread safe without this - - if (IsValid()) - { - SResourceContainer* pContainer = GetResourcesForClass(m_ClassName); - assert(pContainer); - if (pContainer) - { - pContainer->m_RMap.erase(m_NameCRC); - pContainer->m_RList[RListIndexFromId(m_nID)] = NULL; - pContainer->m_AvailableIDs.push_back(m_nID); - } - return true; - } - return false; -} - -int32 CBaseResource::Release() -{ - IF (m_nRefCount > 0, 1) - { - int32 nRef = CryInterlockedDecrement(&m_nRefCount); - if (nRef < 0) - { - CryFatalError("CBaseResource::Release() called more than once!"); - } - - if (nRef <= 0) - { - UnRegister(); - if (gRenDev && gRenDev->m_pRT) - { - gRenDev->m_pRT->RC_ReleaseBaseResource(this); - } - return 0; - } - return nRef; - } - return 0; -} - -//================================================================= - -SResourceContainer::~SResourceContainer() -{ - for (ResourcesMapItor it = m_RMap.begin(); it != m_RMap.end(); ) - { - CBaseResource* pRes = it->second; - if (pRes && CRenderer::CV_r_printmemoryleaks) - { - iLog->Log("Warning: ~SResourceContainer: Resource %d was not deleted (%d)", pRes->GetID(), pRes->GetRefCounter()); - } - ++it; // advance "it" here because the safe release below usually invalidates "it" (calls m_RMap.erase(it)) - SAFE_RELEASE(pRes); - } - m_RMap.clear(); - m_RList.clear(); - m_AvailableIDs.clear(); -} - -void CBaseResource::ShutDown() -{ - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_releaseallresourcesonexit) - { - ResourceClassMapItor it; - for (it = m_sResources.begin(); it != m_sResources.end(); it++) - { - SResourceContainer* pCN = it->second; - SAFE_DELETE(pCN); - } - m_sResources.clear(); - } -} diff --git a/Code/CryEngine/RenderDll/Common/CommonRender.h b/Code/CryEngine/RenderDll/Common/CommonRender.h deleted file mode 100644 index d7cc4d4339..0000000000 --- a/Code/CryEngine/RenderDll/Common/CommonRender.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#include "Cry_Math.h" - -#include "Defs.h" -#include "Cry_Color.h" -#include -#include -#include "STLGlobalAllocator.h" - -#if defined(NULL_RENDERER) -#define VSCONST_INSTDATA 40 -#define VSCONST_SKINMATRIX (40) -#define NUM_MAX_BONES_PER_GROUP (100) -#define NUM_MAX_BONES_PER_GROUP_WITH_MB (50) -#define VSCONST_NOISE_TABLE 64 - -#else -#define VSCONST_INSTDATA 0 -#define VSCONST_SKINMATRIX 0 -#define VSCONST_NOISE_TABLE 0 -#define NUM_MAX_BONES_PER_GROUP (250) -#define NUM_MAX_BONES_PER_GROUP_WITH_MB (125) - -#endif - - -////////////////////////////////////////////////////////////////////// -class CRenderer; -extern CRenderer* gRenDev; - -class CBaseResource; - -//==================================================================== - -#define CR_LITTLE_ENDIAN - -struct SWaveForm; - -extern bool gbRgb; - -_inline DWORD COLCONV (DWORD clr) -{ - return ((clr & 0xff00ff00) | ((clr & 0xff0000) >> 16) | ((clr & 0xff) << 16)); -} -_inline void COLCONV (ColorF& col) -{ - float v = col[0]; - col[0] = col[2]; - col[2] = v; -} - -_inline void f2d(double* dst, float* src) -{ - for (int i = 0; i < 16; i++) - { - dst[i] = src[i]; - } -} - -_inline void d2f(float* dst, double* src) -{ - for (int i = 0; i < 16; i++) - { - dst[i] = (float)src[i]; - } -} - -//================================================================= - -typedef std::map ResourcesMap; - -typedef ResourcesMap::iterator ResourcesMapItor; - -typedef std::vector > ResourcesList; -typedef std::vector > ResourceIds; - -struct SResourceContainer -{ - ResourcesList m_RList; // List of objects for access by Id's - ResourcesMap m_RMap; // Map of objects for fast searching - ResourceIds m_AvailableIDs; // Available object Id's for efficient ID's assigning after deleting - - SResourceContainer() - { - m_RList.reserve(512); - } - - ~SResourceContainer(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_RList); - pSizer->AddObject(m_RMap); - pSizer->AddObject(m_AvailableIDs); - } -}; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ResourceClassMap; - -typedef ResourceClassMap::iterator ResourceClassMapItor; - -class CBaseResource -{ -private: - // Per resource variables - volatile int32 m_nRefCount; - int m_nID; - CCryNameTSCRC m_ClassName; - CCryNameTSCRC m_NameCRC; - - static ResourceClassMap m_sResources; - -public: - static CryCriticalSection s_cResLock; - - //! Dirty flags will indicate what kind of data was invalidated - enum EDirtyFlags - { - eDeviceResourceDirty = BIT(0), - eDeviceResourceViewDirty = BIT(1), - }; - - // CCryUnknown interface - inline void SetRefCounter(int nRefCounter) { m_nRefCount = nRefCounter; } - virtual int32 AddRef() - { - int32 nRef = CryInterlockedIncrement(&m_nRefCount); - return nRef; - } - virtual int32 Release(); - virtual int GetRefCounter() const { return m_nRefCount; } - - // Increment ref count, if not already scheduled for destruction. - int32 TryAddRef() - { - volatile int nOldRef, nNewRef; - do - { - nOldRef = m_nRefCount; - if (nOldRef == 0) - { - return 0; - } - nNewRef = nOldRef + 1; - } - while (CryInterlockedCompareExchange(alias_cast(&m_nRefCount), nNewRef, nOldRef) != nOldRef); - return nNewRef; - } - - // Constructors. - CBaseResource() - : m_nRefCount(1) {} - CBaseResource(const CBaseResource& Src); - CBaseResource& operator=(const CBaseResource& Src); - - // Destructor. - virtual ~CBaseResource() {}; - - CCryNameTSCRC GetNameCRC() { return m_NameCRC; } - //inline const char *GetName() const { return m_Name.c_str(); } - //inline const char *GetClassName() const { return m_ClassName.c_str(); } - inline int GetID() const { return m_nID; } - inline void SetID(int nID) { m_nID = nID; } - - virtual bool IsValid(); - - static ILINE int RListIndexFromId(int id) { return id - 1; } - static ILINE int IdFromRListIndex(int idx) { return idx + 1; } - - static ResourceClassMap& GetMaps() { return m_sResources; } - static CBaseResource* GetResource(const CCryNameTSCRC& className, int nID, bool bAddRef); - static CBaseResource* GetResource(const CCryNameTSCRC& className, const CCryNameTSCRC& Name, bool bAddRef); - static SResourceContainer* GetResourcesForClass(const CCryNameTSCRC& className); - static void ShutDown(); - - bool Register(const CCryNameTSCRC& resName, const CCryNameTSCRC& Name); - bool UnRegister(); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void InvalidateDeviceResource([[maybe_unused]] uint32 dirtyFlags) {}; -}; - diff --git a/Code/CryEngine/RenderDll/Common/CryNameR.h b/Code/CryEngine/RenderDll/Common/CryNameR.h deleted file mode 100644 index 3984e948fe..0000000000 --- a/Code/CryEngine/RenderDll/Common/CryNameR.h +++ /dev/null @@ -1,506 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_CRYNAMER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_CRYNAMER_H -#pragma once - -#include "CryCrc32.h" - -//#define CHECK_INVALID_ACCESS - -////////////////////////////////////////////////////////////////////////// -class CNameTableR -{ -public: - // Name entry header, immediately after this header in memory starts actual string data. - struct SNameEntryR - { - // Reference count of this string. - int nRefCount; - // Current length of string. - int nLength; - // Size of memory allocated at the end of this class. - int nAllocSize; - // Here in memory starts character buffer of size nAllocSize. - //char data[nAllocSize] - - const char* GetStr() { return (char*)(this + 1); } - void AddRef() { CryInterlockedIncrement(&nRefCount); }; - int Release() { return CryInterlockedDecrement(&nRefCount); }; - int GetMemoryUsage() { return sizeof(SNameEntryR) + strlen(GetStr()); } - int GetLength(){return nLength; } - }; - - static threadID m_nRenderThread; - -private: - typedef AZStd::unordered_map, stl::equality_string_caseless > NameMap; - NameMap m_nameMap; - - void CheckThread() - { -#ifdef CHECK_INVALID_ACCESS - DWORD d = ::GetCurrentThreadId(); - if (m_nRenderThread != 0 && d != m_nRenderThread) - { - __debugbreak(); - } -#endif - } - -public: - - CNameTableR() {} - - ~CNameTableR() - { - for (NameMap::iterator it = m_nameMap.begin(); it != m_nameMap.end(); ++it) - { - CryModuleFree(it->second); - } - } - - // Only finds an existing name table entry, return 0 if not found. - SNameEntryR* FindEntry(const char* str) - { - CheckThread(); - SNameEntryR* pEntry = stl::find_in_map(m_nameMap, str, 0); - return pEntry; - } - - // Finds an existing name table entry, or creates a new one if not found. - SNameEntryR* GetEntry(const char* str) - { - CheckThread(); - - SNameEntryR* pEntry = stl::find_in_map(m_nameMap, str, 0); - if (!pEntry) - { - // Create a new entry. - unsigned int nLen = strlen(str); - unsigned int allocLen = sizeof(SNameEntryR) + (nLen + 1) * sizeof(char); - pEntry = (SNameEntryR*)CryModuleMalloc(allocLen); - assert(pEntry != NULL); - pEntry->nRefCount = 0; - pEntry->nLength = nLen; - pEntry->nAllocSize = allocLen; - // Copy string to the end of name entry. - char* pEntryStr = const_cast(pEntry->GetStr()); - memcpy(pEntryStr, str, nLen + 1); - // put in map. - //m_nameMap.insert( NameMap::value_type(pEntry->GetStr(),pEntry) ); - m_nameMap[pEntry->GetStr()] = pEntry; - } - return pEntry; - } - - // Release existing name table entry. - void Release(SNameEntryR* pEntry) - { - CheckThread(); - - assert(pEntry); - m_nameMap.erase(pEntry->GetStr()); - CryModuleFree(pEntry); - } - int GetMemoryUsage() - { - int nSize = 0; - NameMap::iterator it; - int n = 0; - for (it = m_nameMap.begin(); it != m_nameMap.end(); it++) - { - nSize += strlen(it->first); - nSize += it->second->GetMemoryUsage(); - n++; - } - nSize += n * 8; - - return nSize; - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_nameMap); - } - int GetNumberOfEntries() - { - return m_nameMap.size(); - } - - // Log all names inside CryNameTS table. - void LogNames() - { - NameMap::iterator it; - for (it = m_nameMap.begin(); it != m_nameMap.end(); ++it) - { - SNameEntryR* pNameEntry = it->second; - CryLog("[%4d] %s", pNameEntry->nLength, pNameEntry->GetStr()); - } - } -}; - -////////////////////////////////////////////////////////////////////////// -// Class CCryNameR -////////////////////////////////////////////////////////////////////////// -class CCryNameR -{ -public: - CCryNameR(); - CCryNameR(const CCryNameR& n); - // !!! do not allow implicit conversion as it can lead to subtle bugs when passing const char* values - // to stl algorithms (as operator < will create a CCryNameR and potentially insert into the name table - // while processing the algorithm) - explicit CCryNameR(const char* s); - ~CCryNameR(); - - CCryNameR& operator=(const CCryNameR& n); - CCryNameR& operator=(const char* s); - - bool operator==(const CCryNameR& n) const; - bool operator<(const CCryNameR& n) const; - - operator size_t() const - { - return AZStd::hash_string(m_str, _length()); - } - - bool empty() const - { - return length() == 0; - } - void reset() - { - _release(m_str); - m_str = 0; - } - void addref() - { - _addref(m_str); - } - - const char* c_str() const - { - return (m_str) ? m_str : ""; - } - int length() const - { - return _length(); - }; - - static bool find(const char* str) - { - if (ms_table) - { - return ms_table->FindEntry(str) != 0; - } - return false; - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - //pSizer->AddObject(m_str); - pSizer->AddObject(ms_table); - } - static int GetMemoryUsage() - { - if (ms_table) - { - return ms_table->GetMemoryUsage(); - } - return 0; - } - static int GetNumberOfEntries() - { - if (ms_table) - { - return ms_table->GetNumberOfEntries(); - } - return 0; - } - - static void CreateNameTable() - { - AZ_Assert(!ms_table, "CNameTableR was already created!\n"); - ms_table = new CNameTableR(); - } - - static void ReleaseNameTable() - { - delete ms_table; - ms_table = nullptr; - } - -private: - typedef CNameTableR::SNameEntryR SNameEntry; - - static CNameTableR* ms_table; - - SNameEntry* _entry(const char* pBuffer) const - { - assert(pBuffer); - return ((SNameEntry*)pBuffer) - 1; - } - void _release(const char* pBuffer) - { - if (pBuffer && _entry(pBuffer)->Release() <= 0) - { - if (ms_table) - { - ms_table->Release(_entry(pBuffer)); - } - else - { - CryModuleFree(_entry(pBuffer)); - } - } - } - int _length() const - { - return (m_str) ? _entry(m_str)->nLength : 0; - } - void _addref(const char* pBuffer) - { - if (pBuffer) - { - _entry(pBuffer)->AddRef(); - } - } - - const char* m_str; -}; - -inline CCryNameR::CCryNameR() -{ - m_str = 0; -} - -inline CCryNameR::CCryNameR(const CCryNameR& n) -{ - _addref(n.m_str); - m_str = n.m_str; -} - -inline CCryNameR::CCryNameR(const char* s) -{ - if (!ms_table) - { - m_str = nullptr; - return; - } - - const char* pBuf = 0; - if (s && *s) - { - pBuf = ms_table->GetEntry(s)->GetStr(); - } - - _addref(pBuf); - m_str = pBuf; -} - -inline CCryNameR::~CCryNameR() -{ - _release(m_str); -} - -inline CCryNameR& CCryNameR::operator=(const CCryNameR& n) -{ - _addref(n.m_str); - _release(m_str); - m_str = n.m_str; - return *this; -} - -inline CCryNameR& CCryNameR::operator=(const char* s) -{ - if (!ms_table) - { - return *this; - } - - const char* pBuf = 0; - if (s && *s) - { - pBuf = ms_table->GetEntry(s)->GetStr(); - } - - _addref(pBuf); - _release(m_str); - m_str = pBuf; - return *this; -} - -inline bool CCryNameR::operator==(const CCryNameR& n) const -{ - return m_str == n.m_str; -} - -inline bool CCryNameR::operator<(const CCryNameR& n) const -{ - return m_str < n.m_str; -} - -/////////////////////////////////////////////////////////////////////////////// -// Class CCryNameTSCRC. -////////////////////////////////////////////////////////////////////////// -class CCryNameTSCRC -{ -public: - CCryNameTSCRC(); - CCryNameTSCRC(const CCryNameTSCRC& n); - CCryNameTSCRC(const char* s); - CCryNameTSCRC(const char* s, bool bOnlyFind); - CCryNameTSCRC(uint32 n) { m_nID = n; } - ~CCryNameTSCRC(); - - CCryNameTSCRC& operator=(const CCryNameTSCRC& n); - CCryNameTSCRC& operator=(const char* s); - - operator size_t() const - { - return m_nID; - } - - bool operator==(const CCryNameTSCRC& n) const; - bool operator!=(const CCryNameTSCRC& n) const; - - bool operator==(const char* s) const; - bool operator!=(const char* s) const; - - bool operator<(const CCryNameTSCRC& n) const; - bool operator>(const CCryNameTSCRC& n) const; - - bool empty() const { return m_nID == 0; } - void reset() { m_nID = 0; } - uint32 get() { return m_nID; } - void add(int nAdd) { m_nID += nAdd; } - - AUTO_STRUCT_INFO - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*nothing*/} -private: - - uint32 m_nID; -}; - -////////////////////////////////////////////////////////////////////////// -// CCryNameTSCRC -////////////////////////////////////////////////////////////////////////// -inline CCryNameTSCRC::CCryNameTSCRC() -{ - m_nID = 0; -} - -////////////////////////////////////////////////////////////////////////// -inline CCryNameTSCRC::CCryNameTSCRC(const CCryNameTSCRC& n) -{ - m_nID = n.m_nID; -} - -////////////////////////////////////////////////////////////////////////// -inline CCryNameTSCRC::CCryNameTSCRC(const char* s) -{ - m_nID = 0; - *this = s; -} - -inline CCryNameTSCRC::~CCryNameTSCRC() -{ - m_nID = 0; -} - -////////////////////////////////////////////////////////////////////////// -inline CCryNameTSCRC& CCryNameTSCRC::operator=(const CCryNameTSCRC& n) -{ - m_nID = n.m_nID; - return *this; -} - -////////////////////////////////////////////////////////////////////////// -inline CCryNameTSCRC& CCryNameTSCRC::operator=(const char* s) -{ - assert(s); - if (*s) // if not empty - { - m_nID = CCrc32::ComputeLowercase(s); - } - return *this; -} - - -////////////////////////////////////////////////////////////////////////// -inline bool CCryNameTSCRC::operator==(const CCryNameTSCRC& n) const -{ - return m_nID == n.m_nID; -} - -inline bool CCryNameTSCRC::operator!=(const CCryNameTSCRC& n) const -{ - return !(*this == n); -} - -inline bool CCryNameTSCRC::operator==(const char* str) const -{ - assert(str); - if (*str) // if not empty - { - uint32 nID = CCrc32::ComputeLowercase(str); - return m_nID == nID; - } - return m_nID == 0; -} - -inline bool CCryNameTSCRC::operator!=(const char* str) const -{ - if (!m_nID) - { - return true; - } - if (*str) // if not empty - { - uint32 nID = CCrc32::ComputeLowercase(str); - return m_nID != nID; - } - return false; -} - -inline bool CCryNameTSCRC::operator<(const CCryNameTSCRC& n) const -{ - return m_nID < n.m_nID; -} - -inline bool CCryNameTSCRC::operator>(const CCryNameTSCRC& n) const -{ - return m_nID > n.m_nID; -} - -inline bool operator==(const string& s, const CCryNameTSCRC& n) -{ - return n == s; -} -inline bool operator!=(const string& s, const CCryNameTSCRC& n) -{ - return n != s; -} - -inline bool operator==(const char* s, const CCryNameTSCRC& n) -{ - return n == s; -} -inline bool operator!=(const char* s, const CCryNameTSCRC& n) -{ - return n != s; -} - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_CRYNAMER_H diff --git a/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.cpp b/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.cpp deleted file mode 100644 index 19c6378949..0000000000 --- a/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ShadowUtils.h" -#include "DeferredRenderUtils.h" - -void CDeferredRenderUtils::CreateUnitFrustumMesh(int tessx, int tessy, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - ////////////////////////////////////////////////////////////////////////// - // Geometry generating - ////////////////////////////////////////////////////////////////////////// - - int32 nBaseVertexIndex = 0; - - indBuff.clear(); - indBuff.reserve(indBuff.size() + (tessx * tessy - 1) * 6); //TOFIX: correct number of indices - vertBuff.clear(); - vertBuff.reserve(nBaseVertexIndex + tessx * tessy); - - float pViewport[4] = {0.0f, 0.0f, 1.0f, 1.0f}; - float fViewportMinZ = 0.0f; - float fViewportMaxZ = 1.0f; - - - float szx = 1.0f; - float szy = 1.0f; - - float deltax = szx / (tessx - 1.0f); - float deltay = szy / (tessy - 1.0f); - - SVF_P3F_C4B_T2F vert; - Vec3 tri_vert; - Vec3 a; - Vec3 vPos; - - - - //generate tessellation for far plane - a.z = 1.0f; - - for (int i = 0; i < tessy; i++) - { - for (int j = 0; j < tessx; j++) - { - a.x = j * deltax; - a.y = i * deltay; - - //pre-transform viewport transform vertices in static mesh - vPos.x = (a.x - pViewport[0]) * 2.0f / pViewport[2] - 1.0f; - vPos.y = 1.0f - ((a.y - pViewport[1]) * 2.0f / pViewport[3]); //flip coords for y axis - vPos.z = (a.z - fViewportMinZ) / (fViewportMaxZ - fViewportMinZ); - - - vert.xyz = vPos; - vert.st = Vec2(1.0f, 1.0f); //valid extraction - vertBuff.push_back(vert); - } - } - - //push light origin - vert.xyz = Vec3(0, 0, 0); - vert.st = Vec2(0.0f, 0.0f); //do not extract - vertBuff.push_back(vert); - - //init indices for triangles drawing - for (int i = 0; i < tessy - 1; i++) - { - for (int j = 0; j < tessx - 1; j++) - { - indBuff.push_back((uint16)(i * tessx + j + 1 + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (j + 1) + nBaseVertexIndex)); - - indBuff.push_back((uint16)((i + 1) * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (j + 1) + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + j + nBaseVertexIndex)); - } - } - - //Additional faces - for (int j = 0; j < tessx - 1; j++) - { - indBuff.push_back((uint16)((tessy - 1) * tessx + j + 1 + nBaseVertexIndex)); - indBuff.push_back((uint16)((tessy - 1) * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex));//light origin - last vertex - - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex)); //light origin - last vertex - indBuff.push_back((uint16)(j + nBaseVertexIndex)); - indBuff.push_back((uint16)(j + 1 + nBaseVertexIndex)); - } - - - for (int i = 0; i < tessy - 1; i++) - { - indBuff.push_back((uint16)((i + 1) * tessx + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + nBaseVertexIndex)); - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex)); //light origin - last vertex - - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex));//light origin - last vertex - indBuff.push_back((uint16)(i * tessx + (tessx - 1) + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (tessx - 1) + nBaseVertexIndex)); - } -} - - -//push rectangle mesh -void CDeferredRenderUtils::CreateUnitFrustumMeshTransformed(SRenderLight* pLight, ShadowMapFrustum* pFrustum, int nAxis, int tessx, int tessy, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - //assert(pFrustum!=NULL); - assert(pLight != NULL); - - Vec3& vLightPos = pLight->m_Origin; - f32 fLightRadius = pLight->m_fRadius; - - int32 pViewport[4] = {0, 0, 1, 1}; - - Matrix44A mProjection; - Matrix44A mView; - - if (pFrustum == NULL) - { - //for light source - CShadowUtils::GetCubemapFrustumForLight(pLight, nAxis, g_fOmniLightFov /*pLight->m_fLightFrustumAngle*/ + 3.0f, &mProjection, &mView, false); // 3.0f - offset to make sure that frustums are intersected - } - else - { - if (!pFrustum->bOmniDirectionalShadow) - { - //temporarily disabled since mLightProjMatrix contains pre-multiplied matrix already - //pmProjection = &(pFrustum->mLightProjMatrix); - mProjection = gRenDev->m_IdentityMatrix; - mView = pFrustum->mLightViewMatrix; - } - else - { - //calc one of cubemap's frustums - Matrix33 mRot = (Matrix33(pLight->m_ObjMatrix)); - //rotation for shadow frustums is disabled - CShadowUtils::GetCubemapFrustum(FTYP_OMNILIGHTVOLUME, pFrustum, nAxis, &mProjection, &mView /*, &mRot*/); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Geometry generating - ////////////////////////////////////////////////////////////////////////// - - //add geometry to the existing one - int32 nBaseVertexIndex = vertBuff.size(); - - indBuff.clear(); - indBuff.reserve(indBuff.size() + (tessx * tessy - 1) * 6); //TOFIX: correct number of indices - vertBuff.clear(); - vertBuff.reserve(nBaseVertexIndex + tessx * tessy); - - - float szx = 1.0f; - float szy = 1.0f; - - float deltax = szx / (tessx - 1); - float deltay = szy / (tessy - 1); - - SVF_P3F_C4B_T2F vert; - Vec3 tri_vert; - Vec3 a; - - //generate tessellation for far plane - a.z = 1.0f; - - for (int i = 0; i < tessy; i++) - { - for (int j = 0; j < tessx; j++) - { - a.x = j * deltax; - a.y = i * deltay; - - // A - mathVec3UnProject(&tri_vert, &a, pViewport, &mProjection, &mView, &gRenDev->m_IdentityMatrix, g_CpuFlags); - - //calc vertex expansion in world space coords - Vec3 vLightDir = tri_vert - vLightPos; - vLightDir.Normalize(); - vLightDir.SetLength(fLightRadius * 1.05f); - - vert.xyz = vLightPos + vLightDir; - vert.st = Vec2(0.0f, 0.0f); - vertBuff.push_back(vert); - } - } - - //push light origin - vert.xyz = vLightPos; - vert.st = Vec2(0.0f, 0.0f); - vertBuff.push_back(vert); - - //init indices for triangles drawing - for (int i = 0; i < tessy - 1; i++) - { - for (int j = 0; j < tessx - 1; j++) - { - indBuff.push_back((uint16)(i * tessx + j + 1 + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (j + 1) + nBaseVertexIndex)); - - indBuff.push_back((uint16)((i + 1) * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (j + 1) + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + j + nBaseVertexIndex)); - } - } - - //Additional faces - for (int j = 0; j < tessx - 1; j++) - { - indBuff.push_back((uint16)((tessy - 1) * tessx + j + 1 + nBaseVertexIndex)); - indBuff.push_back((uint16)((tessy - 1) * tessx + j + nBaseVertexIndex)); - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex));//light origin - last vertex - - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex)); //light origin - last vertex - indBuff.push_back((uint16)(j + nBaseVertexIndex)); - indBuff.push_back((uint16)(j + 1 + nBaseVertexIndex)); - } - - - for (int i = 0; i < tessy - 1; i++) - { - indBuff.push_back((uint16)((i + 1) * tessx + nBaseVertexIndex)); - indBuff.push_back((uint16)(i * tessx + nBaseVertexIndex)); - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex)); //light origin - last vertex - - indBuff.push_back((uint16)(tessy * tessx + nBaseVertexIndex));//light origin - last vertex - indBuff.push_back((uint16)(i * tessx + (tessx - 1) + nBaseVertexIndex)); - indBuff.push_back((uint16)((i + 1) * tessx + (tessx - 1) + nBaseVertexIndex)); - } -} - -////////////////////////////////////////////////////////////////////////// -// Approximate with 8 vertices -////////////////////////////////////////////////////////////////////////// -void CreateSimpleLightFrustumMeshTransformed(ShadowMapFrustum* pFrustum, int nFrustNum, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - //SVF_P3F_T2F_T3F - SVF_P3F_C4B_T2F vert; - Vec3 vNDC; - - - assert(pFrustum != NULL); - - indBuff.clear(); - indBuff.reserve(36); - - vertBuff.clear(); - vertBuff.reserve(8); - - //first vertex for cone - //vert.xyz = Vec3(0.0f, 0.0f, 0.0f); - //vert.st = Vec2(0.0f, 0.0f); - //vertBuff.push_back(vert); - - int32 pViewport[4] = {0, 0, 1, 1}; - - Matrix44A* pmProjection; - Matrix44A* pmView; - - Matrix44A mProjectionCM; - Matrix44A mViewCM; - - if (!pFrustum->bOmniDirectionalShadow) - { - //temporarily disabled since mLightProjMatrix contains pre-multiplied matrix already - //pmProjection = &(pFrustum->mLightProjMatrix); - pmProjection = &gRenDev->m_IdentityMatrix; - pmView = &(pFrustum->mLightViewMatrix); - } - else - { - //calc one of cubemap's frustums - CShadowUtils::GetCubemapFrustum(FTYP_OMNILIGHTVOLUME, pFrustum, nFrustNum, &mProjectionCM, &mViewCM); - - pmProjection = &mProjectionCM; - pmView = &mViewCM; - } - - - //Create frustum - for (int i = 0; i < 8; i++) - { - //Generate screen space frustum (CCW faces) - vNDC = Vec3((i == 0 || i == 3 || i == 4 || i == 7) ? 0.0f : 1.0f, - (i == 0 || i == 1 || i == 4 || i == 5) ? 0.0f : 1.0f, - (i == 0 || i == 1 || i == 2 || i == 3) ? 0.0f : 1.0f - ); - //TD: convert math functions to column ordered matrices - Vec3 pvObj(vert.xyz); - mathVec3UnProject(&pvObj, &vNDC, pViewport, pmProjection, pmView, &gRenDev->m_IdentityMatrix, g_CpuFlags); - vert.st = Vec2(0.0f, 0.0f); - vertBuff.push_back(vert); - } - - - //CCW faces - static uint16 nFaces[6][4] = { - {0, 1, 2, 3}, - {4, 7, 6, 5}, - {0, 3, 7, 4}, - {1, 5, 6, 2}, - {0, 4, 5, 1}, - {3, 2, 6, 7} - }; - - //init indices for triangles drawing - for (int i = 0; i < 6; i++) - { - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][1]); - indBuff.push_back((uint16) nFaces[i][2]); - - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][2]); - indBuff.push_back((uint16) nFaces[i][3]); - } -} - -////////////////////////////////////////////////////////////////////////// -//Sphere light volumes -////////////////////////////////////////////////////////////////////////// -void CDeferredRenderUtils::SphereTessR(Vec3& v0, Vec3& v1, Vec3& v2, int depth, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - if (depth == 0) - { - SVF_P3F_C4B_T2F vert; - - int nVertCount = vertBuff.size(); - vert.st = Vec2(0.0f, 0.0f); - - vert.xyz = v0; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - - vert.xyz = v1; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - - vert.xyz = v2; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - } - else - { - Vec3 v01, v12, v02; - - v01 = (v0 + v1).GetNormalized(); - v12 = (v1 + v2).GetNormalized(); - v02 = (v0 + v2).GetNormalized(); - - SphereTessR(v0, v01, v02, depth - 1, indBuff, vertBuff); - SphereTessR(v01, v1, v12, depth - 1, indBuff, vertBuff); - SphereTessR(v12, v02, v01, depth - 1, indBuff, vertBuff); - SphereTessR(v12, v2, v02, depth - 1, indBuff, vertBuff); - } -} - - -void CDeferredRenderUtils::SphereTess(Vec3& v0, Vec3& v1, Vec3& v2, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - int depth; - Vec3 w0, w1, w2; - int i, j, k; - - SVF_P3F_C4B_T2F vert; - - vert.st = Vec2(0.0f, 0.0f); - int nVertCount = vertBuff.size(); - - depth = 2; - for (i = 0; i < depth; i++) - { - for (j = 0; i + j < depth; j++) - { - k = depth - i - j; - - { - w0 = (i * v0 + j * v1 + k * v2) / depth; - w1 = ((i + 1) * v0 + j * v1 + (k - 1) * v2) - / depth; - w2 = (i * v0 + (j + 1) * v1 + (k - 1) * v2) - / depth; - } - - w0.Normalize(); - w1.Normalize(); - w2.Normalize(); - - vert.xyz = w1; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - - vert.xyz = w0; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - - vert.xyz = w2; - vertBuff.push_back(vert); - indBuff.push_back(nVertCount++); - } - } -} - -#define X .525731112119133606f -#define Z .850650808352039932f - -void CDeferredRenderUtils::CreateUnitSphere(int rec, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - static Vec3 verts[12] = - { - Vec3(-X, 0, Z), - Vec3(X, 0, Z), - Vec3(-X, 0, -Z), - Vec3(X, 0, -Z), - Vec3(0, Z, X), - Vec3(0, Z, -X), - Vec3(0, -Z, X), - Vec3(0, -Z, -X), - Vec3(Z, X, 0), - Vec3(-Z, X, 0), - Vec3(Z, -X, 0), - Vec3(-Z, -X, 0) - }; - - static int indices[20][3] = - { - {0, 4, 1}, - {0, 9, 4}, - {9, 5, 4}, - {4, 5, 8}, - {4, 8, 1}, - {8, 10, 1}, - {8, 3, 10}, - {5, 3, 8}, - {5, 2, 3}, - {2, 7, 3}, - {7, 10, 3}, - {7, 6, 10}, - {7, 11, 6}, - {11, 0, 6}, - {0, 1, 6}, - {6, 1, 10}, - {9, 0, 11}, - {9, 11, 2}, - {9, 2, 5}, - {7, 2, 11}, - }; - - indBuff.clear(); - vertBuff.clear(); - - SVF_P3F_C4B_T2F vert; - - vert.st = Vec2(0.0f, 0.0f); - - //debug - /*for(int i=0; i<12; i++) - { - vert.xyz = verts[i]; - vertBuff.push_back(vert); - } - - for (int i = 19; i >= 0; i--) - { - indBuff.push_back( (uint16)indices[i][2] ); - indBuff.push_back( (uint16)indices[i][1] ); - indBuff.push_back( (uint16)indices[i][0] ); - }*/ - - for (int i = 19; i >= 0; i--) - { - Vec3& v0 = verts[indices[i][2]]; - Vec3& v1 = verts[indices[i][1]]; - Vec3& v2 = verts[indices[i][0]]; - //SphereTess(v0, v1, v2, indBuff, vertBuff); - SphereTessR(v0, v1, v2, rec, indBuff, vertBuff); - } -} -#undef X -#undef Z - -void CDeferredRenderUtils::CreateUnitBox(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - SVF_P3F_C4B_T2F vert; - Vec3 vNDC; - - indBuff.clear(); - indBuff.reserve(36); - - vertBuff.clear(); - vertBuff.reserve(8); - - //Create unit box - for (int i = 0; i < 8; i++) - { - //Generate screen space frustum (CCW faces) - vNDC = Vec3((i == 0 || i == 1 || i == 4 || i == 5) ? 0.0f : 1.0f, - (i == 0 || i == 3 || i == 4 || i == 7) ? 0.0f : 1.0f, - (i == 0 || i == 1 || i == 2 || i == 3) ? 0.0f : 1.0f - ); - vert.xyz = vNDC; - vert.st = Vec2(0.0f, 0.0f); - vert.color.dcolor = -1; - vertBuff.push_back(vert); - } - - //CCW faces - uint16 nFaces[6][4] = { - {0, 1, 2, 3}, - {4, 7, 6, 5}, - {0, 3, 7, 4}, - {1, 5, 6, 2}, - {0, 4, 5, 1}, - {3, 2, 6, 7} - }; - - //init indices for triangles drawing - for (int i = 0; i < 6; i++) - { - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][1]); - indBuff.push_back((uint16) nFaces[i][2]); - - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][2]); - indBuff.push_back((uint16) nFaces[i][3]); - } -} - - -////////////////////////////////////////////////////////////////////////// -// Approximate with 8 vertices -////////////////////////////////////////////////////////////////////////// -void CDeferredRenderUtils::CreateSimpleLightFrustumMesh(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - //SVF_P3F_T2F_T3F - SVF_P3F_C4B_T2F vert; - Vec3 vNDC; - - indBuff.clear(); - indBuff.reserve(36); - - vertBuff.clear(); - vertBuff.reserve(8); - - int32 pViewport[4] = {0, 0, 1, 1}; - float fViewportMinZ = 0.0f, fViewportMaxZ = 1.0f; - - - Matrix44A mProjectionCM; - Matrix44A mViewCM; - - Vec3 vPos; - - //Create frustum - for (int i = 0; i < 8; i++) - { - //Generate screen space frustum (CCW faces) - //vNDC = Vec3((i==0 || i==3 || i==4 || i==7) ? 0.0f : 1.0f, - // (i==0 || i==1 || i==4 || i==5) ? 0.0f : 1.0f, - // (i==0 || i==1 || i==2 || i==3) ? 0.0f : 1.0f - // ); - - vNDC = Vec3((i == 0 || i == 1 || i == 4 || i == 5) ? 0.0f : 1.0f, - (i == 0 || i == 3 || i == 4 || i == 7) ? 0.0f : 1.0f, - (i == 0 || i == 1 || i == 2 || i == 3) ? 0.0f : 1.0f); - - - //pre-transform viewport transform vertices in static mesh - vPos.x = (vNDC.x - pViewport[0]) * 2.0f / pViewport[2] - 1.0f; - vPos.y = 1.0f - ((vNDC.y - pViewport[1]) * 2.0f / pViewport[3]); //flip coords for y axis - vPos.z = (vNDC.z - fViewportMinZ) / (fViewportMaxZ - fViewportMinZ); - - vert.xyz = vPos; - vert.st = Vec2(1.0f, 1.0f); //valid extraction - vertBuff.push_back(vert); - } - - - //CCW faces - static uint16 nFaces[6][4] = { - {0, 1, 2, 3}, - {4, 7, 6, 5}, - {0, 3, 7, 4}, - {1, 5, 6, 2}, - {0, 4, 5, 1}, - {3, 2, 6, 7} - }; - - //init indices for triangles drawing - for (int i = 0; i < 6; i++) - { - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][1]); - indBuff.push_back((uint16) nFaces[i][2]); - - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][2]); - indBuff.push_back((uint16) nFaces[i][3]); - } -} - -////////////////////////////////////////////////////////////////////////// -//FS quad -////////////////////////////////////////////////////////////////////////// - -void CDeferredRenderUtils::CreateQuad(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - SVF_P3F_C4B_T2F pScreenQuad[] = - { - { Vec3(0, 0, 0), { - {0} - }, Vec2(0, 0) }, - { Vec3(0, 1, 0), { - {0} - }, Vec2(0, 1) }, - { Vec3(1, 0, 0), { - {0} - }, Vec2(1, 0) }, - { Vec3(1, 1, 0), { - {0} - }, Vec2(1, 1) }, - }; - - vertBuff.clear(); - vertBuff.reserve(4); - - vertBuff.push_back(pScreenQuad[0]); - vertBuff.push_back(pScreenQuad[1]); - vertBuff.push_back(pScreenQuad[2]); - vertBuff.push_back(pScreenQuad[3]); - - indBuff.clear(); -} diff --git a/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.h b/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.h deleted file mode 100644 index 954d1b4c4c..0000000000 --- a/Code/CryEngine/RenderDll/Common/DeferredRenderUtils.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __DEFERRED_RENDER_UTILS_H__ -#define __DEFERRED_RENDER_UTILS_H__ - -#define SDeferMeshVert SVF_P3F_C4B_T2F - -typedef std::vector t_arrDeferredMeshVertBuff; -typedef std::vector t_arrDeferredMeshIndBuff; - -class CDeferredRenderUtils -{ -public: - static void CreateUnitFrustumMesh(int tessx, int tessy, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - static void CreateUnitFrustumMeshTransformed(SRenderLight* pLight, ShadowMapFrustum* pFrustum, int nAxis, int tessx, int tessy, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - static void CreateUnitSphere(int rec, /*SRenderLight* pLight, int depth, */ t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - - static void CreateSimpleLightFrustumMesh(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - static void CreateSimpleLightFrustumMeshTransformed(ShadowMapFrustum* pFrustum, int nFrustNum, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - static void CreateUnitBox(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - - static void CreateQuad(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - - CDeferredRenderUtils(); - ~CDeferredRenderUtils(); -private: - static void SphereTess(Vec3& v0, Vec3& v1, Vec3& v2, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); - static void SphereTessR(Vec3& v0, Vec3& v1, Vec3& v2, int depth, t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff); -}; - -#endif diff --git a/Code/CryEngine/RenderDll/Common/Defs.h b/Code/CryEngine/RenderDll/Common/Defs.h deleted file mode 100644 index 5d3cbf05c4..0000000000 --- a/Code/CryEngine/RenderDll/Common/Defs.h +++ /dev/null @@ -1,165 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include -#include -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(Defs_h) -#endif -#if defined(DEFS_H_NO_SIGNAL_H) -#undef DEFS_H_NO_SIGNAL_H -#else -#include -#endif -#include -#include - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifndef ABS -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#endif - -#if !defined(SIGN) && !defined(DO_AMIGAOS) -#define SIGN(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0)) -#endif - -#define EPSILON 0.001f /* Small value */ -#define SMALL_EPSILON 0.000001f /* Very small value */ -#ifndef _WIN32 -//#define INFINITE 999999000 /* Very large number */ -#endif -#ifndef PI -#define PI 3.14159265358979323f /* You know this number, don't you? */ -#endif -#ifndef M_PI -#define M_PI PI -#endif -#ifndef M_PI_2 -#define M_PI_2 (PI / 2) -#endif //M_PI_2 - -#if !defined(LINUX) && !defined(MAC) - #if defined(COMP_WCC) - #define strcasecmp _stricmp - #define strncasecmp strnicmp - #endif - - #if defined(_MSC_VER) - #define strcasecmp _stricmp - #define strncasecmp _strnicmp - #endif -#endif // !defined(LINUX) && !defined(MAC) - -#ifdef _CPU_X86 - -// This is 'stolen' from someone (I don't remember who anymore). It -// is a nice and fast way to convert a floating point number to int -// (only works on a i386 type processor). -// It is equivalent to 'i=(int)(f+.5)'. -#define FIST_MAGIC ((float)((((65536.0 * 65536.0 * 16) + (65536.0 * 0.5)) * 65536.0))) -_inline long QuickRound (float inval) -{ - double dtemp = FIST_MAGIC + inval; - return ((*(long*)&dtemp) - 0x80000000); -} - -_inline long QuickInt (float inval) -{ - double dtemp = FIST_MAGIC + (inval - .4999f); - return ((*(long*)&dtemp) - 0x80000000); -} - -// This is my own invention derived from the previous one. This converts -// a floating point number to a 16.16 fixed point integer. It is -// equivalent to 'i=(int)(f*65536.)'. -#define FIST_MAGIC2 ((float)((((65536.0 * 16) + (0.5)) * 65536.0))) -inline long QuickInt16 (float inval) -{ - double dtemp = FIST_MAGIC2 + inval; - return ((*(long*)&dtemp) - 0x80000000); -} -#endif //_CPU_X86 - -#ifdef PROC_M68K - -#define FIST_MAGIC ((((65536.0 * 65536.0 * 16) + (65536.0 * 0.5)) * 65536.0)) -inline long QuickRound (float inval) -{ - double dtemp = FIST_MAGIC + inval; - return (*(((long*)&dtemp) + 1)) - 0x80000000; -} - -inline long QuickInt (float inval) -{ - double dtemp = FIST_MAGIC + (inval - .4999); - return (*(((long*)&dtemp) + 1)) - 0x80000000; -} - -#define FIST_MAGIC2 ((((65536.0 * 16) + (0.5)) * 65536.0)) -inline long QuickInt16 (float inval) -{ - double dtemp = FIST_MAGIC2 + inval; - return (*(((long*)&dtemp) + 1)) - 0x80000000; -} -#endif - -#if defined(_CPU_X86) || defined(PROC_M68K) -# define QRound(x) QuickRound(x) -# define QInt(x) QuickInt(x) -# define QInt16(x) QuickInt16(x) -#else -# define QRound(x) ((int)((x) + .5)) -# define QInt(x) ((int)(x)) -# define QInt16(x) ((int)((x) * 65536.)) -#endif - -// @@@ I don't know if there is a better way to convert -// a floating point to 8:24 fixed point (one with constants -// like the tricks above instead of the multiplication). -#define QInt24(x) (QInt16(((x) * 256.0f))) - -#if STATS - #define STAT(x) x -#else - #define STAT(x) -#endif - - -//#define SMALL_Z .01 -#define SMALL_Z 0.1f - -#define USE_OCCLUSION 0 // Experimental feature, will not work in this version. - -// Some useful macros: these should be true at least for 32-bit processors -#define LONGFROM2SHORT(s1, s2) (((short)s1) << 16 | (((short)s2) & 0xffff)) -#define SHORT1FROMLONG(l) (short)(((int)l) >> 16) -#define SHORT2FROMLONG(l) (short)(((int)l) & 0xffff) diff --git a/Code/CryEngine/RenderDll/Common/DevBuffer.h b/Code/CryEngine/RenderDll/Common/DevBuffer.h deleted file mode 100644 index 3866fd069e..0000000000 --- a/Code/CryEngine/RenderDll/Common/DevBuffer.h +++ /dev/null @@ -1,523 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include - -//////////////////////////////////////////////////////////////////////////////////////// -// Usage hints -enum BUFFER_USAGE -{ - BU_IMMUTABLE = 0, // For data that never, ever changes - BU_STATIC, // For long-lived data that changes infrequently (every n-frames) - BU_DYNAMIC, // For short-lived data that changes frequently (every frame) - BU_TRANSIENT, // For very short-lived data that can be considered garbage after first usage - BU_TRANSIENT_RT, // For very short-lived data that can be considered garbage after first usage - BU_WHEN_LOADINGTHREAD_ACTIVE, // yes we can ... because renderloadingthread frames not synced with mainthread frames - BU_MAX -}; - -//////////////////////////////////////////////////////////////////////////////////////// -// Binding flags -enum BUFFER_BIND_TYPE -{ - BBT_VERTEX_BUFFER = 0, - BBT_INDEX_BUFFER, - BBT_MAX -}; - -typedef uintptr_t buffer_handle_t; -typedef uint32 item_handle_t; - -// CRY DX12 -//////////////////////////////////////////////////////////////////////////////////////// -struct SDescriptorBlock -{ - SDescriptorBlock(uint32 id) - : blockID(id) - , pBuffer(NULL) - , size(0) - , offset(~0u) - {} - - const uint32 blockID; - - void* pBuffer; - uint32 size; - uint32 offset; -}; - -class CDeviceBufferManager; -struct ConstantBufferAllocator; - -namespace AzRHI -{ - enum class ConstantBufferUsage : AZ::u8 - { - Static, - Dynamic - }; - - enum class ConstantBufferFlags : AZ::u8 - { - None = 0, - DenyStreaming = BIT(1), // Used by OpenGL for constant buffer streaming - }; - AZ_DEFINE_ENUM_BITWISE_OPERATORS(ConstantBufferFlags) - - class ConstantBuffer - { - public: - ConstantBuffer(uint32 handle); - virtual ~ConstantBuffer(); - - inline D3DBuffer* GetPlatformBuffer() const - { - return m_buffer; - } - - inline AzRHI::ConstantBufferUsage GetUsage() const - { - return m_usage; - } - - inline AzRHI::ConstantBufferFlags GetFlags() const - { - return m_flags; - } - - inline AZ::u32 GetByteOffset() const - { - return m_offset; - } - - inline AZ::u32 GetByteCount() const - { - return m_size; - } - -#if !defined(NULL_RENDERER) - inline AZ::u64 GetCode() const - { -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(DevBuffer_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - return reinterpret_cast(m_buffer) | ((AZ::u64)m_offset << 40); -#endif - } -#endif // !NULL_RENDERER - - void AddRef(); - - AZ::u32 Release(); - - void* BeginWrite(); - - void EndWrite(); - - void UpdateBuffer(const void* data, AZ::u32 size); - - private: - friend class ::CDeviceBufferManager; - friend struct ::ConstantBufferAllocator; - - const char* m_name; - D3DBuffer* m_buffer; - item_handle_t m_handle; - void* m_allocator; - void* m_base_ptr; - AZ::u32 m_offset; - AZ::u32 m_size; - ConstantBufferUsage m_usage; - ConstantBufferFlags m_flags; - AZ::u8 m_used : 1; - AZ::u8 m_dynamic : 1; - AZStd::atomic_uint m_refCount; - - int m_nHeapOffset; - SDescriptorBlock* m_pDescriptorBlock; - }; - - using ConstantBufferPtr = _smart_ptr; - - AZ::u32 GetConstantRegisterCountMax(EHWShaderClass shaderClass); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Pool statistics -struct SDeviceBufferPoolStats - : private NoCopy -{ - string buffer_descr; - size_t bank_size; // size of a pool bank in bytes - size_t num_banks; // number of banks currently allocated - size_t num_allocs; // number of allocs present in the device pool - IDefragAllocatorStats allocator_stats; // backing allocator statistics - - SDeviceBufferPoolStats() - : buffer_descr() - , bank_size() - , num_banks() - , num_allocs() - , allocator_stats() - { memset(&allocator_stats, 0x0, sizeof(allocator_stats)); } - - ~SDeviceBufferPoolStats() {} -}; - -class CVertexBuffer; -class CIndexBuffer; - -class IDeviceBufferManager -{ - friend class CGuardedDeviceBufferManager; - friend class CDeviceManager; -public: - -# ifndef NULL_RENDERER - virtual D3DBuffer* GetD3D(buffer_handle_t handle, size_t* outOffset) = 0; -#endif - virtual void LockDevMan() = 0; - virtual void UnlockDevMan() = 0; - -private: - virtual buffer_handle_t Create_Locked(BUFFER_BIND_TYPE, BUFFER_USAGE, size_t) = 0; - virtual void Destroy_Locked(buffer_handle_t) = 0; - virtual void* BeginRead_Locked(buffer_handle_t handle) = 0; - virtual void* BeginWrite_Locked(buffer_handle_t handle) = 0; - virtual void EndReadWrite_Locked(buffer_handle_t handle) = 0; - virtual bool UpdateBuffer_Locked(buffer_handle_t handle, const void*, size_t) = 0; - virtual size_t Size_Locked(buffer_handle_t) = 0; -}; - -class CDeviceBufferManager : public IDeviceBufferManager -{ - buffer_handle_t Create_Locked(BUFFER_BIND_TYPE, BUFFER_USAGE, size_t) override; - void Destroy_Locked(buffer_handle_t) override; - void* BeginRead_Locked(buffer_handle_t handle) override; - void* BeginWrite_Locked(buffer_handle_t handle) override; - void EndReadWrite_Locked(buffer_handle_t handle) override; - bool UpdateBuffer_Locked(buffer_handle_t handle, const void*, size_t) override; - size_t Size_Locked(buffer_handle_t) override; - -public: - CDeviceBufferManager(); - ~CDeviceBufferManager(); - - //////////////////////////////////////////////////////////////////////////////////////// - // Initialization and destruction and high level update funcationality - bool Init(); - void Update(uint32 frameId, bool called_during_loading); - void ReleaseEmptyBanks(uint32 frameId); - void Sync(uint32 frameId); - bool Shutdown(); - - AzRHI::ConstantBuffer* CreateConstantBuffer( - const char* name, - AZ::u32 size, - AzRHI::ConstantBufferUsage usage, - AzRHI::ConstantBufferFlags flags = AzRHI::ConstantBufferFlags::None); - - //////////////////////////////////////////////////////////////////////////////////////// - // Descriptor blocks - SDescriptorBlock* CreateDescriptorBlock(size_t size); - void ReleaseDescriptorBlock(SDescriptorBlock* pBlock); - - //////////////////////////////////////////////////////////////////////////////////////// - // Locks the global devicebuffer lock - void LockDevMan() override; - void UnlockDevMan() override; - - // Returns the size in bytes of the allocation - size_t Size(buffer_handle_t); - - //////////////////////////////////////////////////////////////////////////////////////// - // Buffer Resource creation methods - // - buffer_handle_t Create(BUFFER_BIND_TYPE, BUFFER_USAGE, size_t); - void Destroy(buffer_handle_t); - - //////////////////////////////////////////////////////////////////////////////////////// - // Manual IO operations - // - // Note: it's an error to NOT end an IO operation with EndReadWrite!!! - // - // Note: If you are writing (updating) a buffer only partially, please be aware that the - // the contents of the untouched areas might be undefined as a copy-on-write semantic - // ensures that the updating of buffers does not synchronize with the GPU at any cost. - // - void* BeginRead(buffer_handle_t handle); - void* BeginWrite(buffer_handle_t handle); - void EndReadWrite(buffer_handle_t handle); - bool UpdateBuffer(buffer_handle_t handle, const void*, size_t); - - //////////////////////////////////////////////////////////////////////////////////////// - // Get Stats back from the devbuffer - bool GetStats(BUFFER_BIND_TYPE, BUFFER_USAGE, SDeviceBufferPoolStats&); - -# ifndef NULL_RENDERER - D3DBuffer* GetD3D(buffer_handle_t handle, size_t* outOffset); -# endif - - ///////////////////////////////////////////////////////////// - // Legacy interface - // - // Use with care, can be removed at any point! - CVertexBuffer* CreateVBuffer(size_t, const AZ::Vertex::Format&, const char*, BUFFER_USAGE usage = BU_STATIC); //waltont given that this is a legacy interface, does it make more sense to just remove it? What is the alternative, new interface? The only place that uses it is BreakableGlass. - void ReleaseVBuffer(CVertexBuffer*); - - CIndexBuffer* CreateIBuffer(size_t, const char*, BUFFER_USAGE usage = BU_STATIC); - void ReleaseIBuffer(CIndexBuffer*); - - bool UpdateVBuffer(CVertexBuffer*, void*, size_t); - bool UpdateIBuffer(CIndexBuffer*, void*, size_t); -}; - -class CGuardedDeviceBufferManager - : public NoCopy -{ -private: - IDeviceBufferManager* m_pDevMan; - -public: - explicit CGuardedDeviceBufferManager(IDeviceBufferManager* pDevMan) - : m_pDevMan(pDevMan) - { - m_pDevMan->LockDevMan(); - } - - ~CGuardedDeviceBufferManager() - { - m_pDevMan->UnlockDevMan(); - } - - inline buffer_handle_t Create(BUFFER_BIND_TYPE type, BUFFER_USAGE usage, size_t size) - { - return m_pDevMan->Create_Locked(type, usage, size); - } - - inline void Destroy(buffer_handle_t handle) - { - return m_pDevMan->Destroy_Locked(handle); - } - - inline void* BeginRead(buffer_handle_t handle) - { - return m_pDevMan->BeginRead_Locked(handle); - } - - inline void* BeginWrite(buffer_handle_t handle) - { - return m_pDevMan->BeginWrite_Locked(handle); - } - - inline void EndReadWrite(buffer_handle_t handle) - { - m_pDevMan->EndReadWrite_Locked(handle); - } - - inline bool UpdateBuffer(buffer_handle_t handle, const void* src, size_t size) - { - return m_pDevMan->UpdateBuffer_Locked(handle, src, size); - } - -# ifndef NULL_RENDERER - inline D3DBuffer* GetD3D(buffer_handle_t handle, size_t* offset) - { - return m_pDevMan->GetD3D(handle, offset); - } -# endif -}; - - -class SRecursiveSpinLock -{ - volatile LONG m_lock; - volatile threadID m_owner; - volatile uint16 m_counter; - - enum - { - SPIN_COUNT = 10 - }; - -public: - - SRecursiveSpinLock() - : m_lock() - , m_owner() - , m_counter() - {} - - ~SRecursiveSpinLock() {} - - void Lock() - { - threadID threadId = CryGetCurrentThreadId(); - int32 iterations = 0; -retry: - IF (CryInterlockedCompareExchange(&(this->m_lock), 1L, 0L) == 0L, 1) - { - assert (m_owner == 0u && m_counter == 0u); - m_owner = threadId; - m_counter = 1; - } - else - { - IF (m_owner == threadId, 1) - { - ++m_counter; - } - else - { - Sleep((1 & isneg(SPIN_COUNT - iterations++))); - goto retry; - } - } - } - - bool TryLock() - { - threadID threadId = CryGetCurrentThreadId(); - IF (CryInterlockedCompareExchange(&m_lock, 1L, 0L) == 0L, 1) - { - assert (m_owner == 0u && m_counter == 0u); - m_owner = threadId; - m_counter = 1; - return true; - } - else - { - IF (m_owner == threadId, 1) - { - ++m_counter; - return true; - } - else - { - return false; - } - } - } - - void Unlock() - { - assert (m_owner == CryGetCurrentThreadId() && m_counter != 0u); - IF ((m_counter -= 1) == 0u, 1) - { - m_owner = 0u; - m_lock = 0L; - MemoryBarrier(); - } - } -}; - -class SRecursiveSpinLocker -{ - SRecursiveSpinLock* lock; -public: - SRecursiveSpinLocker(SRecursiveSpinLock* _lock) - : lock(_lock) - { - lock->Lock(); - } - ~SRecursiveSpinLocker() { lock->Unlock(); } -}; -#define SREC_AUTO_LOCK(x) SRecursiveSpinLocker AZ_JOIN(_lock, __LINE__)(&(x)) - -class CConditonalDevManLock -{ - CDeviceBufferManager* m_pDevBufMan; - int m_Active; -public: - explicit CConditonalDevManLock(CDeviceBufferManager* DevMan, int active) - : m_pDevBufMan(DevMan) - , m_Active(active) - { - if (m_Active) - { - m_pDevBufMan->LockDevMan(); - } - } - - ~CConditonalDevManLock() - { - if (m_Active) - { - m_pDevBufMan->UnlockDevMan(); - } - } -}; - -// WrappedDX11Buffer Flags -#define DX11BUF_DYNAMIC BIT(0) -#define DX11BUF_STRUCTURED BIT(1) -#define DX11BUF_BIND_SRV BIT(2) -#define DX11BUF_BIND_UAV BIT(3) -#define DX11BUF_UAV_APPEND BIT(4) -#define DX11BUF_DRAWINDIRECT BIT(5) -#define DX11BUF_STAGING BIT(6) - -#if !defined(NULL_RENDERER) -struct WrappedDX11Buffer -{ - WrappedDX11Buffer() - : m_pBuffer{} - , m_pSRV{} - , m_pUAV{} - , m_numElements{} - , m_elementSize{} - , m_elementFormat{DXGI_FORMAT_UNKNOWN} - , m_flags(0) - , m_currentBuffer{} - { - } - - ~WrappedDX11Buffer(); - - WrappedDX11Buffer(const WrappedDX11Buffer& src); - WrappedDX11Buffer& operator=(const WrappedDX11Buffer& rhs); - - bool operator==(const WrappedDX11Buffer& other) const; - - D3DUnorderedAccessView* GetUnorderedAccessView() const - { - return m_pUAV[m_currentBuffer]; - } - - D3DShaderResourceView* GetShaderResourceView() const - { - return m_pSRV[m_currentBuffer]; - } - - void Create(uint32 numElements, uint32 elementSize, DXGI_FORMAT elementFormat, uint32 flags, const void* pData, int32 nESRAMOffset = -1); - void Release(); - void UpdateBufferContent(void* pData, size_t nSize); - - static const uint32_t MAX_VIEW_COUNT = 3; - - D3DBuffer* m_pBuffer; - D3DShaderResourceView* m_pSRV[MAX_VIEW_COUNT]; - D3DUnorderedAccessView* m_pUAV[MAX_VIEW_COUNT]; - uint32 m_elementSize; - uint32 m_numElements; - DXGI_FORMAT m_elementFormat; - uint32 m_flags; - uint32_t m_currentBuffer; -}; -#endif diff --git a/Code/CryEngine/RenderDll/Common/FencedIB.h b/Code/CryEngine/RenderDll/Common/FencedIB.h deleted file mode 100644 index 557cd78a9b..0000000000 --- a/Code/CryEngine/RenderDll/Common/FencedIB.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -/////////////////////////////////////////////////////////////////////////////// -// Vertex Data container optmized for direct VideoMemory access on Consoles -// No driver overhead, the lock function returns a direct pointer into Video Memory -// which is used by the GPU -// *NOTE: The programmer has to ensure that the Video Memory is not overwritten -// while beeing used. For this the container provides additional fence and -// wait for fence functions. Also double buffering of the container could be needed -// *NOTE: On non console platforms, this container is using the driver facilities to ensure -// no memory is overwrite. This could mean additional memory allocated by the driver -template -class FencedIB -{ -public: - FencedIB(uint32 nIndexCount, uint32 nIndexStride); - ~FencedIB(); - - IndexType* LockIB(uint32 nLockCount); - void UnlockIB(); - HRESULT Bind(uint32 nOffs); - - uint32 GetIndexCount() const; - - void SetFence(); - void WaitForFence(); - -private: - D3DBuffer* m_pIB; - uint32 m_nIndexCount; - IndexType* m_pLockedData; - uint32 m_nIndexStride; - DeviceFenceHandle m_Fence; -}; - -/////////////////////////////////////////////////////////////////////////////// -template -FencedIB::FencedIB(uint32 nIndexCount, uint32 nIndexStride) - : m_pIB(NULL) - , m_pLockedData(NULL) - , m_nIndexStride(nIndexStride) - , m_nIndexCount(nIndexCount) -{ - HRESULT hr = gRenDev->m_DevMan.CreateDirectAccessBuffer(m_nIndexCount, m_nIndexStride, CDeviceManager::BIND_INDEX_BUFFER, (D3DBuffer**)&m_pIB); - CHECK_HRESULT(hr); - - gRenDev->m_DevMan.CreateFence(m_Fence); -} - -/////////////////////////////////////////////////////////////////////////////// -template -FencedIB::~FencedIB() -{ - UnlockIB(); - if (m_pIB) - { - gRenDev->m_DevMan.DestroyDirectAccessBuffer((D3DBuffer*)m_pIB); - } - - gRenDev->m_DevMan.ReleaseFence(m_Fence); -} - -/////////////////////////////////////////////////////////////////////////////// -template -IndexType* FencedIB::LockIB([[maybe_unused]] uint32 nLockCount) -{ - // Ensure there is enough space in the VB for this data - assert (nLockCount <= m_nIndexCount); - - if (m_pLockedData) - { - return m_pLockedData; - } - - if (m_pIB) - { - gRenDev->m_DevMan.LockDirectAccessBuffer((D3DBuffer*)m_pIB, CDeviceManager::BIND_INDEX_BUFFER, (void**)&m_pLockedData); - } - - return m_pLockedData; -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedIB::UnlockIB() -{ - if (m_pLockedData && m_pIB) - { - gRenDev->m_DevMan.UnlockDirectAccessBuffer((D3DBuffer*)m_pIB, CDeviceManager::BIND_INDEX_BUFFER); -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(FencedIB_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -# else - CDeviceManager::InvalidateCpuCache(m_pLockedData, 0, m_nIndexCount * m_nIndexStride); - CDeviceManager::InvalidateGpuCache((D3DBuffer*)m_pIB, m_pLockedData, 0, m_nIndexCount * m_nIndexStride); -# endif - m_pLockedData = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -HRESULT FencedIB::Bind(uint32 nOffs) -{ - COMPILE_TIME_ASSERT(sizeof(IndexType) == 2 || sizeof(IndexType) == 4); - return gcpRendD3D->FX_SetIStream(m_pIB, nOffs, (sizeof(IndexType) == 2 ? Index16 : Index32)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -uint32 FencedIB::GetIndexCount() const -{ - return m_nIndexCount; -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedIB::SetFence() -{ -#if BUFFER_ENABLE_DIRECT_ACCESS == 1 - gRenDev->m_DevMan.IssueFence(m_Fence); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedIB::WaitForFence() -{ -#if BUFFER_ENABLE_DIRECT_ACCESS == 1 - gRenDev->m_DevMan.SyncFence(m_Fence, true, false); -#endif -} diff --git a/Code/CryEngine/RenderDll/Common/FencedVB.h b/Code/CryEngine/RenderDll/Common/FencedVB.h deleted file mode 100644 index 5f173ea1a1..0000000000 --- a/Code/CryEngine/RenderDll/Common/FencedVB.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -/////////////////////////////////////////////////////////////////////////////// -// Vertex Data container optmized for direct VideoMemory access on Consoles -// No driver overhead, the lock function returns a direct pointer into Video Memory -// which is used by the GPU -// *NOTE: The programmer has to ensure that the Video Memory is not overwritten -// while beeing used. For this the container provides additional fence and -// wait for fence functions. Also double buffering of the container could be needed -// *NOTE: On non console platforms, this container is using the driver facilities to ensure -// no memory is overwrite. This could mean additional memory allocated by the driver -template -class FencedVB -{ -public: - FencedVB(uint32 nVertexCount, uint32 nVertStride); - ~FencedVB(); - - VertexType* LockVB(uint32 nLockCount); - void UnlockVB(); - HRESULT Bind(uint32 StreamNumber = 0, int nBytesOffset = 0, int nStride = 0); - - uint32 GetVertexCount() const; - - void SetFence(); - void WaitForFence(); - -private: - D3DBuffer* m_pVB; - uint32 m_nVertexCount; - - VertexType* m_pLockedData; - uint32 m_nVertStride; - DeviceFenceHandle m_Fence; -}; - -/////////////////////////////////////////////////////////////////////////////// -template -FencedVB::FencedVB(uint32 nVertexCount, uint32 nVertStride) - : m_pVB(NULL) - , m_pLockedData(NULL) - , m_nVertStride(nVertStride) - , m_nVertexCount(nVertexCount) -{ - HRESULT hr = gRenDev->m_DevMan.CreateDirectAccessBuffer(m_nVertexCount, m_nVertStride, CDeviceManager::BIND_VERTEX_BUFFER, (D3DBuffer**)&m_pVB); - CHECK_HRESULT(hr); - - gRenDev->m_DevMan.CreateFence(m_Fence); -} - -/////////////////////////////////////////////////////////////////////////////// -template -FencedVB::~FencedVB() -{ - UnlockVB(); - if (m_pVB) - { - gRenDev->m_DevMan.DestroyDirectAccessBuffer((D3DBuffer*)m_pVB); - } - - gRenDev->m_DevMan.ReleaseFence(m_Fence); -} - -/////////////////////////////////////////////////////////////////////////////// -template -VertexType* FencedVB::LockVB([[maybe_unused]] uint32 nLockCount) -{ - // Ensure there is enough space in the VB for this data - assert (nLockCount <= m_nVertexCount); - - if (m_pLockedData) - { - return m_pLockedData; - } - - if (m_pVB) - { - gRenDev->m_DevMan.LockDirectAccessBuffer((D3DBuffer*)m_pVB, CDeviceManager::BIND_VERTEX_BUFFER, (void**)&m_pLockedData); - } - - return m_pLockedData; -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedVB::UnlockVB() -{ - if (m_pLockedData && m_pVB) - { - gRenDev->m_DevMan.UnlockDirectAccessBuffer((D3DBuffer*)m_pVB, CDeviceManager::BIND_VERTEX_BUFFER); -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(FencedVB_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -# else - CDeviceManager::InvalidateCpuCache(m_pLockedData, 0, m_nVertexCount * m_nVertStride); - CDeviceManager::InvalidateGpuCache((D3DBuffer*)m_pVB, m_pLockedData, 0, m_nVertexCount * m_nVertStride); -# endif - m_pLockedData = NULL; - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -HRESULT FencedVB::Bind(uint32 StreamNumber, int nBytesOffset, int nStride) -{ - HRESULT h = gcpRendD3D->FX_SetVStream(StreamNumber, m_pVB, nBytesOffset, nStride == 0 ? m_nVertStride : nStride); - CHECK_HRESULT(h); - return h; -} - -/////////////////////////////////////////////////////////////////////////////// -template -uint32 FencedVB::GetVertexCount() const -{ - return m_nVertexCount; -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedVB::SetFence() -{ -#if BUFFER_ENABLE_DIRECT_ACCESS == 1 - gRenDev->m_DevMan.IssueFence(m_Fence); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -template -void FencedVB::WaitForFence() -{ -#if BUFFER_ENABLE_DIRECT_ACCESS == 1 - gRenDev->m_DevMan.SyncFence(m_Fence, true, false); -#endif -} diff --git a/Code/CryEngine/RenderDll/Common/FrameProfiler.h b/Code/CryEngine/RenderDll/Common/FrameProfiler.h deleted file mode 100644 index 9856ffb14b..0000000000 --- a/Code/CryEngine/RenderDll/Common/FrameProfiler.h +++ /dev/null @@ -1,206 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// A simple profiler useful for collecting multiple call times per frame -// and displaying their different average statistics. -// For usage, see the bottom of the file - -#pragma once - -#include - -#define PP_CONCAT2(A, B) A##B -#define PP_CONCAT(A, B) PP_CONCAT2(A, B) -// set #if 0 here if you don't want profiling to be compiled in the code -//#if 0 -#ifdef ENABLE_FRAME_PROFILER - -// define PROFILE_RENDERER_DETAILED for additional render device events -// #define PROFILE_RENDERER_DETAILED -#ifdef PROFILE_RENDERER_DETAILED -# define PROFILE_FRAME(id) FRAME_PROFILER_FAST("Renderer:" #id, iSystem, PROFILE_RENDERER, g_bProfilerEnabled) -#else -# define PROFILE_FRAME(id) -#endif - - -#define PROFILE_PS_TIME_SCOPE(EXT) \ - PROFILE_PS_TIME_SCOPE_COND(EXT, true) - -#define PROFILE_PS_TIME_SCOPE_COND(EXT, CONDITION) \ - class CProfilePSTimeScope \ - { \ - bool m_bCondition; \ - CTimeValue m_startTime; \ - public: \ - CProfilePSTimeScope(bool bCondition) \ - { \ - m_bCondition = bCondition; \ - if (bCondition) { \ - m_startTime = iTimer->GetAsyncTime(); } \ - } \ - ~CProfilePSTimeScope() \ - { \ - if (m_bCondition) { \ - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_##EXT += iTimer->GetAsyncTime().GetDifferenceInSeconds(m_startTime); } \ - } \ - } PP_CONCAT(profilePSTimeScope, __LINE__)(CONDITION); -#define PROFILE_DIPS_START \ - CTimeValue TimeDIP = iTimer->GetAsyncTime(); \ - -#define PROFILE_DIPS_END(id) \ - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_fTimeDIPs[id] += iTimer->GetAsyncTime().GetDifferenceInSeconds(TimeDIP); \ - -// to get around a stupid compiler bug (Win32 debug with Edit and Continue enabled) where assert can't be used -#if defined(_DEBUG) -#define FP_CHECK_SHADER if (!gRenDev->m_RP.m_pShader) {__debugbreak(); } -#else -#define FP_CHECK_SHADER -#endif - -#define PROFILE_SHADER_SCOPE \ - class CProfileShaderScope \ - { \ - bool bProfile; \ - bool bDoEnd; \ - float time0; \ - int nNumDips; \ - int nNumPolys; \ - public: \ - CProfileShaderScope() \ - { \ - bDoEnd = true; \ - time0 = 0; \ - nNumDips = 0; \ - nNumPolys = 0; \ - if (CRenderer::CV_r_profileshaders == 1 || (CRenderer::CV_r_profileshaders == 2 && gRenDev->m_RP.m_pCurObject && (gRenDev->m_RP.m_pCurObject->m_ObjFlags & FOB_SELECTED))) \ - { \ - bProfile = true; \ - time0 = iTimer->GetAsyncCurTime(); \ - gRenDev->m_RP.m_fProfileTime = time0; \ - nNumPolys = gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_nPolygons[gRenDev->m_RP.m_nPassGroupDIP]; \ - nNumDips = gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_nDIPs[gRenDev->m_RP.m_nPassGroupDIP]; \ - } \ - else \ - { \ - bProfile = false; \ - } \ - } \ - ~CProfileShaderScope() \ - { End(); } \ - void End() \ - { \ - if (!bDoEnd) { \ - return; } \ - bDoEnd = false; \ - float fTime = 0; \ - if (bProfile) \ - { \ - float time1 = iTimer->GetAsyncCurTime(); \ - fTime = time1 - time0; \ - } \ - \ - if (gRenDev->m_RP.m_pShader && gRenDev->m_RP.m_pCurTechnique) \ - { \ - if (CRenderer::CV_r_profileshaders == 1 || (CRenderer::CV_r_profileshaders == 2 && gRenDev->m_RP.m_pCurObject && (gRenDev->m_RP.m_pCurObject->m_ObjFlags & FOB_SELECTED))) \ - { \ - if (time0 == gRenDev->m_RP.m_fProfileTime) \ - { \ - SProfInfo pi; \ - pi.Time = fTime; \ - pi.NumPolys = gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_nPolygons[gRenDev->m_RP.m_nPassGroupDIP] - nNumPolys; \ - pi.NumDips = gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_nDIPs[gRenDev->m_RP.m_nPassGroupDIP] - nNumDips; \ - FP_CHECK_SHADER; \ - pi.pShader = gRenDev->m_RP.m_pShader; \ - pi.pTechnique = gRenDev->m_RP.m_pCurTechnique; \ - pi.m_nItems = 0; \ - gRenDev->m_RP.m_Profile.AddElem(pi); \ - } \ - } \ - } \ - } \ - } profileShaderScope; - -#define PROFILE_SHADER_START \ - PROFILE_SHADER_SCOPE - -#define PROFILE_SHADER_END \ - profileShaderScope.End(); - -#else -#define PROFILE_FRAME(id) -#define PROFILE_SHADER_SCOPE -#define PROFILE_SHADER_START -#define PROFILE_SHADER_END -#define PROFILE_PS_TIME_SCOPE(EXT) -#define PROFILE_PS_TIME_SCOPE_COND(EXT, CONDITION) -#define PROFILE_DIPS_START -#define PROFILE_DIPS_END(id) -#endif - -#if defined(ENABLE_FRAME_PROFILER_LABELS) - -// define these to instrument push/pop marker for GPU, also added to the internal profiler and CPU Markers - #define PROFILE_LABEL(X) - #define PROFILE_LABEL_PUSH(X) - #define PROFILE_LABEL_POP(X) - -// scope util class for GPU profiling Marker - #define PROFILE_LABEL_SCOPE(X) \ - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Renderer, X); \ - class CProfileLabelScope \ - { \ - const char* m_label; \ - AZ::Debug::EventTrace::ScopedSlice m_slice; \ - public: \ - CProfileLabelScope(const char* label) \ - : m_label(label) \ - , m_slice(label, "Renderer") \ - { PROFILE_LABEL_PUSH(label); } \ - ~CProfileLabelScope() \ - { PROFILE_LABEL_POP(m_label); } \ - } PP_CONCAT(profileLabelScope, __LINE__)(X); - -// scope util class for GPU profiling Marker with a dynamic string name -#define PROFILE_LABEL_SCOPE_DYNAMIC(X) \ - AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Renderer, "%s", X); \ - class CProfileLabelScope \ - { \ - const char* m_label; \ - AZ::Debug::EventTrace::ScopedSlice m_slice; \ - public: \ - CProfileLabelScope(const char* label) \ - : m_label(label) \ - , m_slice(label, "Renderer") \ - { PROFILE_LABEL_PUSH(label); } \ - ~CProfileLabelScope() \ - { PROFILE_LABEL_POP(m_label); } \ - } PP_CONCAT(profileLabelScope, __LINE__)(X); - -#else - #define PROFILE_LABEL(X) - #define PROFILE_LABEL_PUSH(X) - #define PROFILE_LABEL_POP(X) - #define PROFILE_LABEL_SCOPE(X) -#endif - -#define PROFILE_LABEL_SHADER(X) PROFILE_LABEL(X) - - -#if defined(ENABLE_FRAME_PROFILER) && !defined(_RELEASE) - #define FUNCTION_PROFILER_RENDER_FLAT \ - FUNCTION_PROFILER_LEGACYONLY(gEnv->pSystem, PROFILE_RENDERER) \ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::RendererDetailed) -#else - #define FUNCTION_PROFILER_RENDER_FLAT -#endif diff --git a/Code/CryEngine/RenderDll/Common/IColorGradingControllerInt.h b/Code/CryEngine/RenderDll/Common/IColorGradingControllerInt.h deleted file mode 100644 index 117596c7bd..0000000000 --- a/Code/CryEngine/RenderDll/Common/IColorGradingControllerInt.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - - -struct IColorGradingControllerInt - : public IColorGradingController -{ - virtual void RT_SetLayers(const SColorChartLayer* pLayers, uint32 numLayers) = 0; -}; diff --git a/Code/CryEngine/RenderDll/Common/Include_HLSL_CPP_Shared.h b/Code/CryEngine/RenderDll/Common/Include_HLSL_CPP_Shared.h deleted file mode 100644 index 78c9657918..0000000000 --- a/Code/CryEngine/RenderDll/Common/Include_HLSL_CPP_Shared.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#ifdef __cplusplus -// C++ - #pragma once - #pragma pack(push,4) - - #define hlsl_cbuffer(name) struct HLSL_##name - #define hlsl_cbuffer_register(name, reg, slot) \ - enum { SLOT_##name = slot }; \ - struct HLSL_##name - - #define hlsl_int(member) int32 member - #define hlsl_int2(member) Vec2i member - #define hlsl_int3(member) Vec3i member - #define hlsl_int4(member) Vec4i member - #define hlsl_uint(member) uint32 member - #define hlsl_uint2(member) Vec2ui member - #define hlsl_uint3(member) Vec3ui member - #define hlsl_uint4(member) Vec4ui member - #define hlsl_float(member) float member - #define hlsl_float2(member) Vec2 member - #define hlsl_float3(member) Vec3 member - #define hlsl_float4(member) Vec4 member - #define hlsl_matrix44(member) Matrix44 member - #define hlsl_matrix34(member) Matrix34 member -#else //__cplusplus -// HLSL - #define hlsl_cbuffer(name) cbuffer name - #define hlsl_cbuffer_register(name, reg, float) cbuffer name: reg - #define hlsl_int(member) int member - #define hlsl_int2(member) int2 member - #define hlsl_int3(member) int3 member - #define hlsl_int4(member) int4 member - #define hlsl_uint(member) uint member - #define hlsl_uint2(member) uint2 member - #define hlsl_uint3(member) uint3 member - #define hlsl_uint4(member) uint4 member - #define hlsl_float(member) float member - #define hlsl_float2(member) float2 member - #define hlsl_float3(member) float3 member - #define hlsl_float4(member) float4 member - #define hlsl_matrix44(member) float4x4 member - #define hlsl_matrix34(member) float3x4 member -#endif //__cplusplus - -// TODO: include in shaders - -hlsl_cbuffer(PerPassConstantBuffer_GBuffer) -{ - hlsl_float4(g_VS_WorldViewPos); - hlsl_matrix44(g_VS_ViewProjMatr); - hlsl_matrix44(g_VS_ViewProjZeroMatr); -}; - -#if defined(FEATURE_SVO_GI) -hlsl_cbuffer(PerPassConstantBuffer_Svo) -{ - hlsl_float4(PerPass_SvoTreeSettings0); - hlsl_float4(PerPass_SvoTreeSettings1); - hlsl_float4(PerPass_SvoParams0); - hlsl_float4(PerPass_SvoParams1); - hlsl_float4(PerPass_SvoParams2); - hlsl_float4(PerPass_SvoParams3); - hlsl_float4(PerPass_SvoParams4); - hlsl_float4(PerPass_SvoParams5); - hlsl_float4(PerPass_SvoParams6); -}; -#endif - -hlsl_cbuffer(PerSubPassConstantBuffer_ShadowGen) -{ - hlsl_float4(PerShadow_LightPos); - hlsl_float4(PerShadow_ViewPos); - hlsl_float4(PerShadow_FrustumInfo); - hlsl_float4(PerShadow_BiasInfo); -}; - -hlsl_cbuffer(PerInstanceConstantBuffer) -{ - hlsl_matrix34(SPIObjWorldMat); - hlsl_float4(SPIBendInfo); - hlsl_float4(SPIBendInfoPrev); - hlsl_float4(SPIAmbientOpacity); - hlsl_float4(SPIDissolveRef); -}; - -hlsl_cbuffer(PerViewConstantBuffer) -{ - hlsl_float4(PerView_WorldViewPos); - hlsl_float4(PerView_WorldViewPosPrev); - hlsl_matrix44(PerView_ViewProjZeroMatr); - hlsl_matrix44(PerView_ViewProjZeroMatrPrev); - hlsl_matrix44(PerView_ViewProjZeroMatrPrevNearest); - hlsl_float4(PerView_AnimGenParams); - - hlsl_float4(PerView_ViewBasisX); - hlsl_float4(PerView_ViewBasisY); - hlsl_float4(PerView_ViewBasisZ); - - hlsl_matrix44(PerView_ViewProjMatr); - hlsl_matrix44(PerView_ViewProjMatrPrev); - hlsl_matrix44(PerView_ViewMatr); - hlsl_matrix44(PerView_ProjMatr); - hlsl_float4(PerView_TessellationParams); - - hlsl_float4(PerView_ScreenSize); - hlsl_float4(PerView_HPosScale); - hlsl_float4(PerView_ProjRatio); - hlsl_float4(PerView_NearestScaled); - hlsl_float4(PerView_NearFarClipDist); - - hlsl_float4(PerView_FogColor); - - hlsl_matrix44(PerView_FrustumPlaneEquation); - hlsl_float4(PerView_JitterParams); -}; - -hlsl_cbuffer(PerFrameConstantBuffer) -{ - hlsl_float4(PerFrame_VolumetricFogParams); - hlsl_float4(PerFrame_VolumetricFogRampParams); - hlsl_float4(PerFrame_VolumetricFogColorGradientBase); - hlsl_float4(PerFrame_VolumetricFogColorGradientDelta); - hlsl_float4(PerFrame_VolumetricFogColorGradientParams); - hlsl_float4(PerFrame_VolumetricFogColorGradientRadial); - hlsl_float4(PerFrame_VolumetricFogSamplingParams); - hlsl_float4(PerFrame_VolumetricFogDistributionParams); - hlsl_float4(PerFrame_VolumetricFogScatteringParams); - hlsl_float4(PerFrame_VolumetricFogScatteringBlendParams); - hlsl_float4(PerFrame_VolumetricFogScatteringColor); - hlsl_float4(PerFrame_VolumetricFogScatteringSecondaryColor); - hlsl_float4(PerFrame_VolumetricFogHeightDensityParams); - hlsl_float4(PerFrame_VolumetricFogHeightDensityRampParams); - hlsl_float4(PerFrame_VolumetricFogDistanceParams); - hlsl_float4(PerFrame_VolumetricFogGlobalEnvProbe0); - hlsl_float4(PerFrame_VolumetricFogGlobalEnvProbe1); - - hlsl_float4(PerFrame_SvoLightingParams); - - hlsl_float4(PerFrame_Time); - - hlsl_float4(PerFrame_SunColor); - hlsl_float4(PerFrame_SunDirection); - hlsl_float4(PerFrame_HDRParams); - - hlsl_float4(PerFrame_CloudShadingColorSun); - hlsl_float4(PerFrame_CloudShadingColorSky); - hlsl_float4(PerFrame_CloudShadowParams); - hlsl_float4(PerFrame_CloudShadowAnimParams); - - hlsl_float4(PerFrame_CausticsSmoothSunDirection); - - hlsl_float4(PerFrame_DecalZFightingRemedy); - hlsl_float4(PerFrame_WaterLevel); - - hlsl_float4(PerFrame_StereoParams); - hlsl_float4(PerFrame_RandomParams); - - hlsl_uint4(PerFrame_MultiLayerAlphaBlendLayerData); -}; - -#ifdef __cplusplus -// C++ - #pragma pack(pop) - -#else //__cplusplus -// HLSL - -#endif //__cplusplus diff --git a/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.cpp b/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.cpp deleted file mode 100644 index b91bea8e8f..0000000000 --- a/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include -#include - -namespace Render -{ - namespace Debug - { - //========================================================================= - - struct VRAMCategoryInfo - { - VRAMAllocationCategory m_category = VRAM_CATEGORY_INVALID; - const char* m_categoryName = nullptr; - VRAMSubCategoryType m_subcategories; - }; - - struct VRAMAllocationInfo - { - void* m_address = nullptr; - size_t m_byteSize = 0; - string m_allocationName; - VRAMAllocationCategory m_category = VRAM_CATEGORY_INVALID; - VRAMAllocationSubcategory m_subcategory = VRAM_SUBCATEGORY_INVALID; - }; - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::OSStdAllocator> VRAMCategoryType; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::OSStdAllocator> VRAMAllocationRecordsType; - - /** - * VRAMDrillerAllocations: A class that tracks VRAM allocations and categories/subcategories for the allocations - */ - class VRAMDrillerAllocations - { - friend class VRAMDriller; - AZ_CLASS_ALLOCATOR(VRAMDrillerAllocations, AZ::OSAllocator, 0) - - public: - - VRAMDrillerAllocations() {} - ~VRAMDrillerAllocations() - { - m_allocations.clear(); - } - - //========================================================================= - - const VRAMCategoryInfo* RegisterCategory(VRAMAllocationCategory category, const char* categoryName, const VRAMSubCategoryType& subcategories) - { - AZ_Assert(category < VRAM_CATEGORY_INVALID, ("Error, invalid VRAM category")); - - // Insert and populate the category - VRAMCategoryType::pair_iter_bool iterBool = m_categories.insert_key(category); - AZ_Assert(iterBool.second, "VRAM category %u is already registered!", category); - - VRAMCategoryInfo& categoryInfo = iterBool.first->second; - categoryInfo.m_category = category; - categoryInfo.m_categoryName = categoryName; - categoryInfo.m_subcategories = subcategories; - - return &categoryInfo; - } - - void UnregisterAllCategories(AZ::Debug::DrillerOutputStream* output) - { - // Skip if we have no active output - if (output != nullptr) - { - for (AZStd::pair currentCategory : m_categories) - { - output->BeginTag(AZ_CRC("VRAMDriller")); - output->BeginTag(AZ_CRC("UnregisterCategory")); - output->Write(AZ_CRC("Category"), static_cast(currentCategory.first)); - output->EndTag(AZ_CRC("UnregisterCategory")); - output->EndTag(AZ_CRC("VRAMDriller")); - } - } - m_categories.clear(); - } - - const VRAMCategoryType& GetCategoriesMap() - { - return m_categories; - } - - //========================================================================= - - const VRAMAllocationInfo* RegisterAllocation(void* address, size_t byteSize, const char* allocationName, VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory) - { - AZ_Assert(address, ("Error, allocation address is null")); - - // Insert and populate the allocation record - VRAMAllocationRecordsType::pair_iter_bool iterBool = m_allocations.insert_key(address); - - // Turning off the VRAMDriller altogether causes weird allocation errors - AZ_Warning("Driller", iterBool.second, "VRAM memory address 0x%p is already allocated and being tracked! VRAM memory reporting may now be inaccurate.", address); - - VRAMAllocationInfo& allocationInfo = iterBool.first->second; - allocationInfo.m_byteSize = byteSize; - allocationInfo.m_allocationName = allocationName; - allocationInfo.m_category = category; - allocationInfo.m_subcategory = subcategory; - - // Update simple tracking statistics - m_simpleAllocationStatistics[category][subcategory].m_allocatedBytes += byteSize; - m_simpleAllocationStatistics[category][subcategory].m_numberAllocations++; - - return &allocationInfo; - } - - void UnregisterAllocation(void* address) - { - VRAMAllocationRecordsType::iterator iter = m_allocations.find(address); - - // Turning off the VRAMDriller altogether causes weird allocation errors - AZ_Warning("Driller", iter != m_allocations.end(), "VRAM memory address 0x%p does not exist in the records. VRAM memory reporting may now be inaccurate.", address); - - if ( iter != m_allocations.end() ) - { - // Update simple tracking statistics - VRAMAllocationInfo& allocationInfo = iter->second; - m_simpleAllocationStatistics[allocationInfo.m_category][allocationInfo.m_subcategory].m_allocatedBytes -= allocationInfo.m_byteSize; - m_simpleAllocationStatistics[allocationInfo.m_category][allocationInfo.m_subcategory].m_numberAllocations--; - - m_allocations.erase(iter); - } - } - - const VRAMAllocationRecordsType& GetAllocationsMap() - { - return m_allocations; - } - - //========================================================================= - - struct SimpleAllocationStatistics - { - size_t m_allocatedBytes = 0; - size_t m_numberAllocations = 0; - }; - - SimpleAllocationStatistics m_simpleAllocationStatistics[VRAM_CATEGORY_NUMBER_CATEGORIES][VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES]; - - private: - - VRAMCategoryType m_categories; - VRAMAllocationRecordsType m_allocations; - }; - - //========================================================================= - - VRAMDriller::VRAMDriller() - { -#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED - m_platformMemoryInstrumentationRootGroupId = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationRootGroupId, "VRAM", AZ::PlatformMemoryInstrumentation::m_groupRoot); - - m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_TEXTURE] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_TEXTURE], "Texture", m_platformMemoryInstrumentationRootGroupId); - m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER], "Buffer", m_platformMemoryInstrumentationRootGroupId); - m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_MISC] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_MISC], "Misc", m_platformMemoryInstrumentationRootGroupId); - - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_RENDERTARGET] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_RENDERTARGET], "Render Target", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_TEXTURE]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_TEXTURE] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_TEXTURE], "Texture", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_TEXTURE]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_DYNAMIC] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_TEXTURE_DYNAMIC], "Dynamic", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_TEXTURE]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER], "Vertex Buffer", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER], "Index Buffer", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_CONSTANT_BUFFER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_CONSTANT_BUFFER], "Constant Buffer", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_OTHER_BUFFER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_BUFFER_OTHER_BUFFER], "Other Buffer", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_BUFFER]); - m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_MISC_OTHER] = AZ::PlatformMemoryInstrumentation::GetNextGroupId(); - AZ::PlatformMemoryInstrumentation::RegisterGroup(m_platformMemoryInstrumentationSubcategoryIds[VRAM_SUBCATEGORY_MISC_OTHER], "Misc", m_platformMemoryInstrumentationCategoryIds[VRAM_CATEGORY_MISC]); -#endif - BusConnect(); - } - - VRAMDriller::~VRAMDriller() - { - BusDisconnect(); - } - - const char* VRAMDriller::GroupName() const - { - return "RenderingDrillers"; - } - - const char* VRAMDriller::GetName() const - { - return "VRAMDriller"; - } - - const char* VRAMDriller::GetDescription() const - { - return "Reports all VRAM memory allocations."; - } - - void VRAMDriller::Start(const Param* params, int numParams) - { - (void)params; - (void)numParams; - - if (m_allocations) - { - const VRAMCategoryType& categoriesMap = m_allocations->GetCategoriesMap(); - for (VRAMCategoryType::const_iterator iter = categoriesMap.begin(); iter != categoriesMap.end(); ++iter) - { - RegisterCategoryOutput(iter->first, &iter->second); - } - - const VRAMAllocationRecordsType& allocationMap = m_allocations->GetAllocationsMap(); - for (VRAMAllocationRecordsType::const_iterator iter = allocationMap.begin(); iter != allocationMap.end(); ++iter) - { - RegisterAllocationOutput(iter->first, &iter->second); - } - } - } - - void VRAMDriller::Stop() - { - } - - void VRAMDriller::CreateAllocationRecords([[maybe_unused]] unsigned char stackRecordLevels, [[maybe_unused]] bool isMemoryGuard, [[maybe_unused]] bool isMarkUnallocatedMemory) - { - AZ_Assert(m_allocations == nullptr, "Allocation records for the VRAMDriller already exist"); - m_allocations = aznew VRAMDrillerAllocations(); - } - - void VRAMDriller::DestroyAllocationRecords() - { - AZ_Assert(m_allocations != nullptr, "Allocation records for the VRAMDriller do not exist"); - delete m_allocations; - m_allocations = nullptr; - } - - //========================================================================= - - void VRAMDriller::RegisterAllocation(void* address, size_t byteSize, const char* allocationName, VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory) - { - AZ_Assert(category != VRAM_CATEGORY_INVALID, "Invalid VRAM allocation category"); - AZ_Assert(subcategory != VRAM_SUBCATEGORY_INVALID, "No subcategory provided for VRAM Allocation"); - -#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED - AZ::PlatformMemoryInstrumentation::Alloc(address, byteSize, 0, m_platformMemoryInstrumentationSubcategoryIds[subcategory]); -#else - AZ_Assert(m_allocations != nullptr, "Allocation records for the VRAMDriller do not exist!"); - - const VRAMAllocationInfo* info = m_allocations->RegisterAllocation(address, byteSize, allocationName, category, subcategory); - // Skip if we have no active output - if (m_output == nullptr) - { - return; - } - - RegisterAllocationOutput(address, info); -#endif - } - - void VRAMDriller::RegisterAllocationOutput(void* address, const VRAMAllocationInfo* info) - { - AZ_Assert(m_output != nullptr, ("The DrillerOutputStream is null")); - - m_output->BeginTag(AZ_CRC("VRAMDriller")); - m_output->BeginTag(AZ_CRC("RegisterAllocation", 0x992a9780)); - m_output->Write(AZ_CRC("Address", 0x0d4e6f81), address); - m_output->Write(AZ_CRC("Category"), static_cast(info->m_category)); - m_output->Write(AZ_CRC("Subcategory"), static_cast(info->m_subcategory)); - m_output->Write(AZ_CRC("Name", 0x5e237e06), info->m_allocationName.c_str()); - m_output->Write(AZ_CRC("Size", 0xf7c0246a), info->m_byteSize); - m_output->EndTag(AZ_CRC("RegisterAllocation", 0x992a9780)); - m_output->EndTag(AZ_CRC("VRAMDriller")); - } - - void VRAMDriller::UnregisterAllocation(void* address) - { -#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED - AZ::PlatformMemoryInstrumentation::Free(address); -#else - AZ_Assert(m_allocations != nullptr, "Allocation records for the VRAMDriller do not exist!"); - m_allocations->UnregisterAllocation(address); - - // Skip if the driller is not actively capturing - if (m_output == nullptr) - { - return; - } - - m_output->BeginTag(AZ_CRC("VRAMDriller")); - m_output->BeginTag(AZ_CRC("UnRegisterAllocation", 0xea5dc4cd)); - m_output->Write(AZ_CRC("Address", 0x0d4e6f81), address); - m_output->EndTag(AZ_CRC("UnRegisterAllocation", 0xea5dc4cd)); - m_output->EndTag(AZ_CRC("VRAMDriller")); -#endif - } - - //========================================================================= - - void VRAMDriller::RegisterCategory(VRAMAllocationCategory category, const char* categoryName, const VRAMSubCategoryType& subcategories) - { - AZ_Assert(m_allocations != nullptr, "Allocation records for the VRAMDriller do not exist!"); - AZ_Assert(category != VRAM_CATEGORY_INVALID, "Invalid VRAM allocation category"); - AZ_Assert(subcategories.size(), "No subcategory provided for VRAM category"); - - const VRAMCategoryInfo* info = m_allocations->RegisterCategory(category, categoryName, subcategories); - - // Skip if the driller is not actively capturing - if (m_output == nullptr) - { - return; - } - - RegisterCategoryOutput(category, info); - } - - void VRAMDriller::RegisterCategoryOutput(VRAMAllocationCategory category, const VRAMCategoryInfo* info) - { - AZ_Assert(m_output != nullptr, ("The DrillerOutputStream is null")); - AZ_Assert(info != nullptr, ("The VRAMCategoryInfo is null")); - - m_output->BeginTag(AZ_CRC("VRAMDriller")); - m_output->BeginTag(AZ_CRC("RegisterCategory")); - m_output->Write(AZ_CRC("Category"), static_cast(category)); - m_output->Write(AZ_CRC("CategoryName"), info->m_categoryName); - - for (VRAMSubCategoryType::const_iterator iter = info->m_subcategories.begin(); iter != info->m_subcategories.end(); ++iter) - { - const VRAMSubcategory* subcategoryInfo = iter; - m_output->Write(AZ_CRC("SubcategoryId"), static_cast(subcategoryInfo->m_subcategoryId)); - m_output->Write(AZ_CRC("SubcategoryName"), subcategoryInfo->m_subcategoryName); - } - - m_output->EndTag(AZ_CRC("RegisterCategory")); - m_output->EndTag(AZ_CRC("VRAMDriller")); - } - - void VRAMDriller::UnregisterAllCategories() - { - AZ_Assert(m_allocations != nullptr, "Allocation records for the VRAMDriller do not exist!"); - m_allocations->UnregisterAllCategories(m_output); - } - - //========================================================================= - - void VRAMDriller::GetCurrentVRAMStats(VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory, AZStd::string& categoryName, AZStd::string& subcategoryName, size_t& numberBytesAllocated, size_t& numberAllocations) - { - // Verify the category exists - const VRAMCategoryType& categoriesMap = m_allocations->GetCategoriesMap(); - auto categoryIter = categoriesMap.find(category); - if (categoryIter != categoriesMap.end()) - { - // Get the category and subcategory names - const VRAMCategoryInfo& categoryInfo = categoryIter->second; - categoryName = categoryInfo.m_categoryName; - - subcategoryName = "INVALID_SUBCATEGORY"; - for (int subCat=0; subCatm_simpleAllocationStatistics[category][subcategory]; - numberBytesAllocated = stats.m_allocatedBytes; - numberAllocations = stats.m_numberAllocations; - } - } - - //========================================================================= - - }// namespace Debug -} // namespace Render diff --git a/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.h b/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.h deleted file mode 100644 index 837744ebad..0000000000 --- a/Code/CryEngine/RenderDll/Common/Memory/VRAMDriller.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLER_H 1 - -#include -#include -#include -#include - -namespace Render -{ - namespace Debug - { - /** - * VRAMDriller: A class that tracks VRAM allocations and communicates with the Driller - * to log and generate reports for the allocations. - */ - class VRAMDriller - : public AZ::Debug::Driller - , public VRAMDrillerBus::Handler - { - public: - AZ_CLASS_ALLOCATOR(VRAMDriller, AZ::OSAllocator, 0) - - VRAMDriller(); - ~VRAMDriller(); - - void CreateAllocationRecords(unsigned char stackRecordLevels, bool isMemoryGuard, bool isMarkUnallocatedMemory); - void DestroyAllocationRecords(); - - protected: - ////////////////////////////////////////////////////////////////////////// - // Driller - virtual const char* GroupName() const; - virtual const char* GetName() const; - virtual const char* GetDescription() const; - virtual void Start(const Param* params = NULL, int numParams = 0); - virtual void Stop(); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // VRAMDrillerBus - virtual void RegisterCategory(VRAMAllocationCategory category, const char* categoryName, const VRAMSubCategoryType& subcategories); - virtual void UnregisterAllCategories(); - virtual void RegisterAllocation(void* address, size_t byteSize, const char* allocationName, VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory); - virtual void UnregisterAllocation(void* address); - virtual void GetCurrentVRAMStats(VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory, AZStd::string& categoryName, AZStd::string& subcategoryName, size_t& numberBytesAllocated, size_t& numberAllocations); - ////////////////////////////////////////////////////////////////////////// - - // Subfunctions of RegisterCategory and RegisterAllocation. - // Split out due to these parts being called in from both of those functions and the Start function - void RegisterCategoryOutput(VRAMAllocationCategory category, const struct VRAMCategoryInfo* info); - void RegisterAllocationOutput(void* address, const struct VRAMAllocationInfo* info); - - private: - -#if PLATFORM_MEMORY_INSTRUMENTATION_ENABLED - uint16_t m_platformMemoryInstrumentationRootGroupId = 0; - uint16_t m_platformMemoryInstrumentationCategoryIds[Render::Debug::VRAM_CATEGORY_NUMBER_CATEGORIES] = { 0 }; - uint16_t m_platformMemoryInstrumentationSubcategoryIds[Render::Debug::VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES] = { 0 }; -#endif - class VRAMDrillerAllocations* m_allocations = nullptr; - }; - } // namespace Debug -} // namespace Render - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLER_H -#pragma once diff --git a/Code/CryEngine/RenderDll/Common/Memory/VRAMDrillerBus.h b/Code/CryEngine/RenderDll/Common/Memory/VRAMDrillerBus.h deleted file mode 100644 index ba779b2e54..0000000000 --- a/Code/CryEngine/RenderDll/Common/Memory/VRAMDrillerBus.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLERBUS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLERBUS_H 1 - -#include - -namespace Render -{ - namespace Debug - { - enum VRAMAllocationCategory - { - VRAM_CATEGORY_TEXTURE, - VRAM_CATEGORY_BUFFER, - VRAM_CATEGORY_MISC, - - VRAM_CATEGORY_NUMBER_CATEGORIES, - VRAM_CATEGORY_INVALID = VRAM_CATEGORY_NUMBER_CATEGORIES - }; - - enum VRAMAllocationSubcategory - { - VRAM_SUBCATEGORY_TEXTURE_RENDERTARGET, // Rendertarget allocations - VRAM_SUBCATEGORY_TEXTURE_TEXTURE, // Texture resources loaded from a file - VRAM_SUBCATEGORY_TEXTURE_DYNAMIC, // Texture created dynamically at runtime (staging or CPU-updated) - - VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER, // Vertex buffers - VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER, // Index buffers - VRAM_SUBCATEGORY_BUFFER_CONSTANT_BUFFER, // Constant buffers - VRAM_SUBCATEGORY_BUFFER_OTHER_BUFFER, // Other buffers - - VRAM_SUBCATEGORY_MISC_OTHER, // Other - - VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES, - VRAM_SUBCATEGORY_INVALID = VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES, - }; - - struct VRAMSubcategory - { - VRAMSubcategory(VRAMAllocationSubcategory subcategoryId, const char* subcategoryName) - : m_subcategoryId(subcategoryId) - , m_subcategoryName(subcategoryName) - {} - - VRAMAllocationSubcategory m_subcategoryId = VRAM_SUBCATEGORY_INVALID; - const char* m_subcategoryName = nullptr; - }; - - typedef AZStd::vector VRAMSubCategoryType; - - /** - * VRAM allocations driller message. - * - * We use a driller bus so all messages are sending in exclusive matter no other driller messages - * can be triggered at that moment, so we already preserve the calling order. You can assume - * all access code in the driller framework in guarded. You can manually lock the driller mutex are you - * use by using \ref AZ::Debug::DrillerEBusMutex. - */ - class VRAMDrillerMessages - : public AZ::Debug::DrillerEBusTraits - { - public: - virtual ~VRAMDrillerMessages() {} - - // Register a category with a set of subcategories. A category - virtual void RegisterCategory(VRAMAllocationCategory category, const char* categoryName, const VRAMSubCategoryType& subcategories) = 0; - virtual void UnregisterAllCategories() = 0; - - // Functions for registering and unregistering individual VRAM allocations - virtual void RegisterAllocation(void* address, size_t byteSize, const char* allocationName, VRAMAllocationCategory category, VRAMAllocationSubcategory subcategories) = 0; - virtual void UnregisterAllocation(void* address) = 0; - - // Query the most up-to-date information about a specific category and subcategory. - // Returns the category and subcategory names, the number of currently allocated bytes and the current number of allocations - virtual void GetCurrentVRAMStats(VRAMAllocationCategory category, VRAMAllocationSubcategory subcategory, AZStd::string& categoryName, AZStd::string& subcategoryName, size_t& numberBytesAllocated, size_t& numberAllocations) = 0; - }; - - typedef AZ::EBus VRAMDrillerBus; - } // namespace Debug -} // namespace Render - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_MEMORY_VRAMDRILLERBUS_H -#pragma once diff --git a/Code/CryEngine/RenderDll/Common/OcclQuery.h b/Code/CryEngine/RenderDll/Common/OcclQuery.h deleted file mode 100644 index 82edb5c131..0000000000 --- a/Code/CryEngine/RenderDll/Common/OcclQuery.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_OCCLQUERY_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_OCCLQUERY_H -#pragma once - -class COcclusionQuery -{ -public: - COcclusionQuery() - : m_nVisSamples(~0) - , m_nCheckFrame(0) - , m_nDrawFrame(0) - , m_nOcclusionID(0) - { - } - - ~COcclusionQuery() - { - Release(); - } - - void Create(); - void Release(); - - void BeginQuery(); - void EndQuery(); - - uint32 GetVisibleSamples(bool bAsynchronous); - - int GetDrawFrame() const - { - return m_nDrawFrame; - } - - bool IsReady(); - - bool IsCreated() const { return m_nOcclusionID != 0; } - -private: - - int m_nVisSamples; - int m_nCheckFrame; - int m_nDrawFrame; - - UINT_PTR m_nOcclusionID; // this will carry a pointer D3DQuery, so it needs to be 64-bit on Windows 64 -}; - - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_OCCLQUERY_H diff --git a/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.cpp b/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.cpp deleted file mode 100644 index f2475c0b48..0000000000 --- a/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "PerInstanceConstantBufferPool.h" -#include "DevBuffer.h" -#include "RenderView.h" -#include "RenderPipeline.h" -#include "Include_HLSL_CPP_Shared.h" - -#if !defined(NULL_RENDERER) -#include "DriverD3D.h" -#endif - -namespace -{ - void BuildPerInstanceConstantBuffer(HLSL_PerInstanceConstantBuffer* outBuffer, CRenderObject* renderObject, float realTime, float realTimePrev) - { - AZ::u64 objectFlags = renderObject->m_ObjFlags; - - outBuffer->SPIObjWorldMat = renderObject->GetMatrix(); - - SBending* bending = renderObject->m_data.m_pBending; - if (bending != nullptr) - { - outBuffer->SPIBendInfo = bending->GetShaderConstants(realTime); - } - - bending = renderObject->m_data.m_BendingPrev; - if (bending != nullptr) - { - outBuffer->SPIBendInfoPrev = bending->GetShaderConstants(realTimePrev); - } - - outBuffer->SPIAmbientOpacity.x = renderObject->m_II.m_AmbColor.r; - outBuffer->SPIAmbientOpacity.y = renderObject->m_II.m_AmbColor.g; - outBuffer->SPIAmbientOpacity.z = renderObject->m_II.m_AmbColor.b; - outBuffer->SPIAmbientOpacity.w = renderObject->m_fAlpha; - - const bool bDissolve = (objectFlags & (FOB_DISSOLVE_OUT | FOB_DISSOLVE)) != 0; - const bool bDissolveOut = (objectFlags & FOB_DISSOLVE_OUT) != 0; - - outBuffer->SPIDissolveRef.x = bDissolve ? (float)(renderObject->m_DissolveRef) * (1.0f / 255.0f) : 0.0f; - outBuffer->SPIDissolveRef.y = bDissolveOut ? 1.0f : -1.0f; - outBuffer->SPIDissolveRef.z = 0.0f; - outBuffer->SPIDissolveRef.w = 0.0f; - } -} - -PerInstanceConstantBufferPool::PerInstanceConstantBufferPool() - : m_CurrentRenderItem{} - , m_UpdateConstantBuffer{} - , m_UpdateIndirectConstantBuffer{} - , m_PooledConstantBuffer{} -#if defined(FEATURE_SPI_INDEXED_CB) - , m_PooledIndirectConstantBuffer{} -#endif -{ -} - -void PerInstanceConstantBufferPool::Init() -{ - for (AZ::u32 i = 0; i < SPI_NUM_STATIC_INST_CB; ++i) - { - m_PooledConstantBuffer[i] = NULL; - } -#if defined(FEATURE_SPI_INDEXED_CB) - for (AZ::u32 i = 0; i < SPI_NUM_INSTS_PER_CB; ++i) - { - m_PooledIndirectConstantBuffer[i] = NULL; - } -#endif - m_UpdateConstantBuffer = nullptr; - m_UpdateIndirectConstantBuffer = nullptr; -} - -void PerInstanceConstantBufferPool::Shutdown() -{ - for (AZ::u32 i = 0; i < SPI_NUM_STATIC_INST_CB; ++i) - { - SAFE_RELEASE(m_PooledConstantBuffer[i]); - } -#if defined(FEATURE_SPI_INDEXED_CB) - for (AZ::u32 i = 0; i < SPI_NUM_INSTS_PER_CB; ++i) - { - SAFE_RELEASE(m_PooledIndirectConstantBuffer[i]); - } -#endif - SAFE_RELEASE(m_UpdateIndirectConstantBuffer); - SAFE_RELEASE(m_UpdateConstantBuffer); -} - -void PerInstanceConstantBufferPool::Update(CRenderView& renderView, float realTime) -{ -#if !defined(NULL_RENDERER) - - if (m_PooledConstantBuffer[0] == nullptr) - { - auto& bufferManager = gRenDev->m_DevBufMan; - - for (AZ::u32 i = 0; i < SPI_NUM_STATIC_INST_CB; ++i) - { - m_PooledConstantBuffer[i] = bufferManager.CreateConstantBuffer( - "PerInstancePool", - SPI_NUM_INSTS_PER_CB * sizeof(HLSL_PerInstanceConstantBuffer), - AzRHI::ConstantBufferUsage::Dynamic, - AzRHI::ConstantBufferFlags::DenyStreaming); - } - -#ifdef FEATURE_SPI_INDEXED_CB - for (AZ::u32 i = 0; i < SPI_NUM_INSTS_PER_CB; ++i) - { - AZ::u32 data[4] = { i, 0, 0, 0 }; - m_PooledIndirectConstantBuffer[i] = bufferManager.CreateConstantBuffer( - "PerInstanceIndirectPool", - sizeof(AZ::u32) * 4, - AzRHI::ConstantBufferUsage::Static, - AzRHI::ConstantBufferFlags::DenyStreaming); - m_PooledIndirectConstantBuffer[i]->UpdateBuffer(&data, sizeof(AZ::u32) * 4); - } -#endif - - m_UpdateConstantBuffer = bufferManager.CreateConstantBuffer( - "PerInstanceUpdate", - SPI_NUM_INSTS_PER_CB * sizeof(HLSL_PerInstanceConstantBuffer), - AzRHI::ConstantBufferUsage::Dynamic, - AzRHI::ConstantBufferFlags::DenyStreaming); - - AZ::u32 data[4] = { 0, 0, 0, 0 }; - m_UpdateIndirectConstantBuffer = bufferManager.CreateConstantBuffer( - "PerInstanceIndirectUpdate", - sizeof(AZ::u32) * 4, - AzRHI::ConstantBufferUsage::Static, - AzRHI::ConstantBufferFlags::DenyStreaming); - - m_UpdateIndirectConstantBuffer->UpdateBuffer(&data, sizeof(AZ::u32) * 4); - } - - PROFILE_FRAME(UpdatePerInstanceConstants); - AZ_TRACE_METHOD(); - - AZ::u32 nextBufferIdx = 0; - AZ::u32 nextInstanceIdx = 0; - AZ::u32 constantBufferIdxLimit = SPI_NUM_STATIC_INST_CB; - void* mappedData = nullptr; - - // Assign half of the constant buffer budget per eye when in VR mode - if (gcpRendD3D->GetIStereoRenderer()->IsRenderingToHMD()) - { - // For the right eye (rendered second), begin indexing half way into the array - if (gRenDev->m_CurRenderEye == STEREO_EYE_RIGHT) - { - nextBufferIdx = constantBufferIdxLimit / 2; - } - else - { - // For the left eye, just reduce the limit by half - constantBufferIdxLimit /= 2; - } - } - - float realTimePrev = realTime - CRenderer::GetElapsedTime(); - - for (AZ::u32 renderListIdx = EFSLIST_PREPROCESS; renderListIdx < EFSLIST_NUM; renderListIdx++) - { - for (AZ::u32 bAfterWater = 0; bAfterWater < 2; bAfterWater++) - { - auto& renderItems = renderView.GetRenderItems(bAfterWater, renderListIdx); - - for (AZ::u32 itemIndex = 0; itemIndex < renderItems.size(); itemIndex++) - { - SRendItem* renderItem = &renderItems[itemIndex]; - CRenderObject* renderObject = renderItem->pObj; - - if (!renderObject) - { - AZ_Assert(false, "Failed to update static inst buffer pool, index %u - the render object is null", nextBufferIdx); - continue; - } - - if (renderObject->m_PerInstanceConstantBufferKey.IsValid()) - { - continue; - } - - if (nextBufferIdx >= constantBufferIdxLimit) - { - auto* renderer = gEnv->pRenderer; - - int nDrawCalls, nShadowGenDrawCalls; - renderer->GetCurrentNumberOfDrawCalls(nDrawCalls, nShadowGenDrawCalls); - int nTotalDrawCalls = nDrawCalls + nShadowGenDrawCalls; - int nTotalInstanced = nTotalDrawCalls + renderer->GetNumGeomInstanceDrawCalls(); - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Ran out of static inst buffers -- DP: %04d ShadowGen: %04d Total: %04d Instanced: %04d", nDrawCalls, nShadowGenDrawCalls, nTotalDrawCalls, nTotalInstanced); - return; - } - - AzRHI::ConstantBuffer* constantBuffer = m_PooledConstantBuffer[nextBufferIdx]; - if (nextInstanceIdx == 0) - { - mappedData = constantBuffer->BeginWrite(); - if (!mappedData) - { - AZ_Error("Renderer", false, "Failed to update static inst buffer pool, index %u", nextBufferIdx); - return; - } - } - - HLSL_PerInstanceConstantBuffer* outputData = reinterpret_cast(mappedData) + nextInstanceIdx; - BuildPerInstanceConstantBuffer(outputData, renderObject, realTime, realTimePrev); - - renderObject->m_PerInstanceConstantBufferKey.m_Id = nextInstanceIdx + (nextBufferIdx * SPI_NUM_INSTS_PER_CB); -#ifdef FEATURE_SPI_INDEXED_CB - renderObject->m_PerInstanceConstantBufferKey.m_IndirectId = nextInstanceIdx; -#endif - nextInstanceIdx++; - if (nextInstanceIdx == SPI_NUM_INSTS_PER_CB) - { - constantBuffer->EndWrite(); - nextInstanceIdx = 0; - nextBufferIdx++; - } - } - } - } - - if (nextInstanceIdx != 0) - { - m_PooledConstantBuffer[nextBufferIdx]->EndWrite(); - } -#endif -} - -void PerInstanceConstantBufferPool::SetConstantBuffer(SRendItem* renderItem) -{ - CRenderObject* object = renderItem->pObj; - const AZ::u32 directId = object->m_PerInstanceConstantBufferKey.m_Id; - - if (directId == 0xffff) - { - return; - } - - m_CurrentRenderItem = renderItem; - - AZ::u32 bufferIndex = directId / SPI_NUM_INSTS_PER_CB; - - auto& deviceManager = gRenDev->m_DevMan; - -#if (SPI_NUM_INSTS_PER_CB == 1) - deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI); - deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI); -#elif defined(FEATURE_SPI_INDEXED_CB) - AZ::u32 indirectId = object->m_PerInstanceConstantBufferKey.m_IndirectId; - - if (indirectId >= SPI_NUM_INSTS_PER_CB) - { - CryLogAlways("ERROR: SetBuffer - indirect index is invalid"); - return; - } - - deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI); - deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI); - deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex); - deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex); -#else - AZ::u32 itemIndex = directId % SPI_NUM_INSTS_PER_CB; - AZ::u32 first[1] = {itemIndex * static_cast(sizeof(HLSL_PerInstanceConstantBuffer))}; - AZ::u32 count[1] = {static_cast(sizeof(HLSL_PerInstanceConstantBuffer))}; - - deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]); - deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]); -#endif -} - -void PerInstanceConstantBufferPool::UpdateConstantBuffer(ConstantUpdateCB constantUpdateCallback, float realTime) -{ - AZ_Assert(m_CurrentRenderItem, "current render item is null"); - - CRenderObject* renderObject = m_CurrentRenderItem->pObj; - if (!renderObject) - { - AZ_Assert(false, "Failed to update static inst buffer - the current render object is null"); - return; - } - - float realTimePrev = realTime - CRenderer::GetElapsedTime(); - - void* mappedData = m_UpdateConstantBuffer->BeginWrite(); - if (!mappedData) - { - AZ_Error("Renderer", false, "Failed to update static inst buffer"); - return; - } - - BuildPerInstanceConstantBuffer(reinterpret_cast(mappedData), renderObject, realTime, realTimePrev); - - constantUpdateCallback(mappedData); - m_UpdateConstantBuffer->EndWrite(); - - auto& devManager = gRenDev->m_DevMan; - devManager.BindConstantBuffer(eHWSC_Vertex, m_UpdateConstantBuffer, eConstantBufferShaderSlot_SPI); - devManager.BindConstantBuffer(eHWSC_Pixel, m_UpdateConstantBuffer, eConstantBufferShaderSlot_SPI); - -#if defined(FEATURE_SPI_INDEXED_CB) - devManager.BindConstantBuffer(eHWSC_Vertex, m_UpdateIndirectConstantBuffer, eConstantBufferShaderSlot_SPIIndex); - devManager.BindConstantBuffer(eHWSC_Pixel, m_UpdateIndirectConstantBuffer, eConstantBufferShaderSlot_SPIIndex); -#endif -} diff --git a/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.h b/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.h deleted file mode 100644 index 08548b4a98..0000000000 --- a/Code/CryEngine/RenderDll/Common/PerInstanceConstantBufferPool.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "Defs.h" - -#if (defined(WIN32) || defined(APPLE) || defined(LINUX) || defined(USE_FEATURE_SPI_INDEXED_CB_BY_DEFAULT)) - #define FEATURE_SPI_INDEXED_CB - - #if defined(DONT_USE_SPI_INDEXED_CB) - #undef FEATURE_SPI_INDEXED_CB - #endif -#endif - -// DirectX 11.0 -#if defined(WIN32) || defined(LINUX) || defined(APPLE) || defined(USE_FEATURE_SPI_INDEXED_CB_BY_DEFAULT) - - #define SPI_NUM_STATIC_INST_CB_DEFAULT (2048 * 64) - - #ifdef FEATURE_SPI_INDEXED_CB - #define SPI_NUM_INSTS_PER_CB 128 // Must match SPI struct in FXConstantDefs.cfi - #define SPI_NUM_STATIC_INST_CB (SPI_NUM_STATIC_INST_CB_DEFAULT / SPI_NUM_INSTS_PER_CB) - #else - #define SPI_NUM_INSTS_PER_CB 1 - #define SPI_NUM_STATIC_INST_CB SPI_NUM_STATIC_INST_CB_DEFAULT - #endif // FEATURE_SPI_INDEXED_CB - -// DirectX 11.1 and higher -#else - #define SPI_NUM_INSTS_PER_CB 2048 - #define SPI_NUM_STATIC_INST_CB 64 -#endif - -struct SRendItem; - -class IPerInstanceConstantBufferPool -{ - virtual void SetConstantBuffer(SRendItem* renderItem) = 0; -}; - -class PerInstanceConstantBufferPool : public IPerInstanceConstantBufferPool -{ -public: - PerInstanceConstantBufferPool(); - - using ConstantUpdateCB = AZStd::function; - - inline SRendItem* GetCurrentRenderItem() - { - return m_CurrentRenderItem; - } - - void Init(); - void Shutdown(); - - void SetConstantBuffer(SRendItem* renderItem); - void UpdateConstantBuffer(ConstantUpdateCB callback, float realTime); - void Update(CRenderView& renderView, float realTime); - -private: - SRendItem* m_CurrentRenderItem; - - AzRHI::ConstantBuffer* m_PooledConstantBuffer[SPI_NUM_STATIC_INST_CB]; -#if defined(FEATURE_SPI_INDEXED_CB) - AzRHI::ConstantBuffer* m_PooledIndirectConstantBuffer[SPI_NUM_INSTS_PER_CB]; -#endif - - AzRHI::ConstantBuffer* m_UpdateConstantBuffer; - AzRHI::ConstantBuffer* m_UpdateIndirectConstantBuffer; -}; diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.cpp b/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.cpp deleted file mode 100644 index 00307557ad..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.cpp +++ /dev/null @@ -1,869 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "PostEffects.h" -#include "PostProcessUtils.h" -#include "IPostEffectGroup.h" -#include - -#include "../../../Cry3DEngine/Environment/OceanEnvironmentBus.h" - -AZStd::vector< CWaterRipples::SWaterHit, AZ::StdLegacyAllocator > CWaterRipples::s_pWaterHits[RT_COMMAND_BUF_COUNT]; -AZStd::vector< CWaterRipples::SWaterHit, AZ::StdLegacyAllocator > CWaterRipples::s_pWaterHitsMGPU; -AZStd::vector< CWaterRipples::SWaterHitRecord, AZ::StdLegacyAllocator > CWaterRipples::m_DebugWaterHits; -Vec3 CWaterRipples::s_CameraPos = Vec3(ZERO); -Vec2 CWaterRipples::s_SimOrigin = Vec2(ZERO); -int CWaterRipples::s_nUpdateMask; -Vec4 CWaterRipples::s_vParams = Vec4(0.0f, 0.0f, 0.0f, 0.0f); -Vec4 CWaterRipples::s_vLookupParams = Vec4(0.0f, 0.0f, 0.0f, 0.0f); -bool CWaterRipples::s_bInitializeSim; - -int CSunShafts::Initialize() -{ - Release(); - - m_pOcclQuery = new COcclusionQuery; - m_pOcclQuery->Create(); - - return true; -} - -void CSunShafts::Release() -{ - SAFE_DELETE(m_pOcclQuery); -} - -void CSunShafts::Reset([[maybe_unused]] bool bOnSpecChange) -{ -} - -void CSunShafts::OnLostDevice() -{ - Release(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CFilterSharpening::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessFilters) - { - return false; - } - - if (fabs(m_pAmount->GetParam() - 1.0f) + CRenderer::CV_r_Sharpening + CRenderer::CV_r_ChromaticAberration > 0.09f) - { - return true; - } - - return false; -} - -void CFilterSharpening::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(1.0f); - m_pType->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CFilterBlurring::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessFilters) - { - return false; - } - - if (m_pAmount->GetParam() > 0.09f) - { - return true; - } - - return false; -} - -void CFilterBlurring::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); - m_pType->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CUberGamePostProcess::Preprocess() -{ - const float fParamThreshold = 1.0f / 255.0f; - const Vec4 vWhite = Vec4(1.0f, 1.0f, 1.0f, 1.0f); - - bool bEnable = false; - bEnable |= m_pColorTint->GetParamVec4() != vWhite; - bEnable |= m_pNoise->GetParam() > fParamThreshold; - bEnable |= m_pSyncWaveAmplitude->GetParam() > fParamThreshold; - bEnable |= m_pGrainAmount->GetParam() > fParamThreshold; - bEnable |= m_pPixelationScale->GetParam() > fParamThreshold; - - if (m_pInterlationAmount->GetParam() > fParamThreshold || m_pVSyncAmount->GetParam() > fParamThreshold) - { - m_nCurrPostEffectsMask |= ePE_SyncArtifacts; - bEnable = true; - } - - // todo: looks like some game code/flowgraph doing silly stuff - investigate - const float fParamThresholdBackCompatibility = 0.09f; - - if (m_pChromaShiftAmount->GetParam() > fParamThresholdBackCompatibility || m_pFilterChromaShiftAmount->GetParam() > fParamThresholdBackCompatibility) - { - m_nCurrPostEffectsMask |= ePE_ChromaShift; - bEnable = true; - } - - return bEnable; -} - -void CUberGamePostProcess::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_nCurrPostEffectsMask = 0; - - m_pVSyncAmount->ResetParam(0.0f); - m_pVSyncFreq->ResetParam(1.0f); - - const Vec4 vWhite = Vec4(1.0f, 1.0f, 1.0f, 1.0f); - m_pColorTint->ResetParamVec4(vWhite); - - m_pInterlationAmount->ResetParam(0.0f); - m_pInterlationTiling->ResetParam(1.0f); - m_pInterlationRotation->ResetParam(0.0f); - - m_pPixelationScale->ResetParam(0.0f); - m_pNoise->ResetParam(0.0f); - - m_pSyncWaveFreq->ResetParam(0.0f); - m_pSyncWavePhase->ResetParam(0.0f); - m_pSyncWaveAmplitude->ResetParam(0.0f); - - m_pFilterChromaShiftAmount->ResetParam(0.0f); - m_pChromaShiftAmount->ResetParam(0.0f); - - m_pGrainAmount->ResetParam(0.0f); - m_pGrainTile->ResetParam(1.0f); - - m_pMask->Release(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CColorGrading::Preprocess() -{ - // Depreceated: to be removed / replaced by UberPostProcess shader - return false; -} - -void CColorGrading::Reset([[maybe_unused]] bool bOnSpecChange) -{ - // reset user params - m_pSaturationOffset->ResetParam(0.0f); - m_pPhotoFilterColorOffset->ResetParamVec4(Vec4(0.0f, 0.0f, 0.0f, 0.0f)); - m_pPhotoFilterColorDensityOffset->ResetParam(0.0f); - m_pGrainAmountOffset->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CUnderwaterGodRays::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - if (!bQualityCheck) - { - return false; - } - - static ICVar* pVar = iConsole->GetCVar("e_WaterOcean"); - - //bool bOceanVolumeVisible = (gEnv->p3DEngine->GetOceanRenderFlags() & OCR_OCEANVOLUME_VISIBLE) != 0; - bool godRaysEnabled = OceanToggle::IsActive() ? OceanRequest::GetGodRaysEnabled() : (CRenderer::CV_r_water_godrays == 1); - if (godRaysEnabled && m_pAmount->GetParam() > 0.005f) // && bOceanEnabled && bOceanVolumeVisible) - { - float fWatLevel = SPostEffectsUtils::m_fWaterLevel; - if (fWatLevel - 0.1f > gRenDev->GetViewParameters().vOrigin.z) - { - // check water level - - return true; - } - } - - return false; -} - -void CUnderwaterGodRays::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(1.0f); - m_pQuality->ResetParam(1.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CVolumetricScattering::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_High, eSQ_High); - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - if (m_pAmount->GetParam() > 0.005f) - { - return true; - } - - return false; -} - -void CVolumetricScattering::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); - m_pType->ResetParam(0.0f); - m_pQuality->ResetParam(1.0f); - m_pTiling->ResetParam(1.0f); - m_pSpeed->ResetParam(1.0f); - m_pColor->ResetParamVec4(Vec4(0.5f, 0.75f, 1.0f, 1.0f)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Game/Hud specific post-effects -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CAlienInterference::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); - m_pTintColor->ResetParamVec4(Vec4(Vec3(0.85f, 0.95f, 1.25f) * 0.5f, 1.0f)); -} - -bool CAlienInterference::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - if (m_pAmount->GetParam() > 0.09f) - { - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -int CGhostVision::CreateResources() -{ - Release(); - - m_pUserTex1 = CTexture::ForName("EngineAssets/Textures/user_tex1.tif", FT_DONT_STREAM, eTF_Unknown); - m_pUserTex2 = CTexture::ForName("EngineAssets/Textures/user_tex2.tif", FT_DONT_STREAM, eTF_Unknown); - - return true; -} - -void CGhostVision::Release() -{ - SAFE_RELEASE(m_pUserTex1); - SAFE_RELEASE(m_pUserTex2); -} - -void CGhostVision::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pUserValue1->ResetParam(0.0f); - m_pUserValue2->ResetParam(0.0f); - m_pUserValue3->ResetParam(0.0f); - m_pTintColor->ResetParamVec4(Vec4(Vec3(0.85f, 0.95f, 1.25f) * 0.5f, 1.0f)); -} - -bool CGhostVision::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Low, eSQ_Low); - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - if (m_pUserValue1->GetParam() > 0.09f || m_pUserValue2->GetParam() > 0.09f || m_pUserValue3->GetParam() > 0.09f) - { - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool CWaterDroplets::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - if (!bQualityCheck) - { - return false; - } - - const bool bUserActive = m_pAmount->GetParam() > 0.005f; - - bool godRaysEnabled = OceanToggle::IsActive() ? OceanRequest::GetGodRaysEnabled() : (CRenderer::CV_r_water_godrays == 1); - if (godRaysEnabled) - { - return bUserActive; // user enabled override - } - - return false; -} - -void CWaterDroplets::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CWaterFlow::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - if (m_pAmount->GetParam() > 0.005f) - { - return true; - } - - return false; -} - -void CWaterFlow::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CWaterVolume::Preprocess() -{ - if (!gRenDev->m_RP.m_eQuality) - { - return false; - } - - if (m_pAmount->GetParam() > 0.005f) - { - return true; - } - - return false; -} - -void CWaterVolume::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CScreenFrost::Preprocess() -{ - bool bQualityCheck = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Medium, eSQ_Medium); - if (!bQualityCheck) - { - return false; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - if (m_pAmount->GetParam() > 0.09f) - { - return true; - } - - return false; -} - -void CScreenFrost::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); - m_pCenterAmount->ResetParam(1.0f); - m_fRandOffset = 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CRainDrops::CreateResources() -{ - Release(); - - //create texture for HitEffect accumulation - m_bFirstFrame = true; - - // Already generated ? No need to proceed - if (!m_pDropsLst.empty()) - { - return 1; - } - - m_pDropsLst.reserve(m_nMaxDropsCount); - for (int p = 0; p < m_nMaxDropsCount; p++) - { - SRainDrop* pDrop = new SRainDrop; - m_pDropsLst.push_back(pDrop); - } - - return 1; -} - -void CRainDrops::Release() -{ - if (m_pDropsLst.empty()) - { - return; - } - - SRainDropsItor pItor, pItorEnd = m_pDropsLst.end(); - for (pItor = m_pDropsLst.begin(); pItor != pItorEnd; ++pItor) - { - SAFE_DELETE((*pItor)); - } - m_pDropsLst.clear(); -} - - -void CRainDrops::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_bFirstFrame = true; - m_uCurrentDytex = 0; - - m_pAmount->ResetParam(0.0f); - m_pSpawnTimeDistance->ResetParam(0.35f); - m_pSize->ResetParam(5.0f); - m_pSizeVar->ResetParam(2.5f); - m_nAliveDrops = 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CHudSilhouettes::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pActive->ResetParam(0.0f); - m_pAmount->ResetParam(1.0f); - m_pType->ResetParam(1); - - FindIfSilhouettesOptimisedTechAvailable(); -} - -bool CHudSilhouettes::Preprocess() -{ - if ((CRenderer::CV_r_customvisions != 3) || (m_bSilhouettesOptimisedTechAvailable)) - { - if (!CRenderer::CV_r_PostProcessGameFx || - !CRenderer::CV_r_customvisions || - gRenDev->IsPost3DRendererEnabled()) - { - return false; - } - - // no need to proceed - float fType = m_pType->GetParam(); - uint32 nBatchMask = SRendItem::BatchFlags(EFSLIST_GENERAL, gRenDev->m_RP.m_pRLD) | SRendItem::BatchFlags(EFSLIST_TRANSP, gRenDev->m_RP.m_pRLD); - - if ((!(nBatchMask & FB_CUSTOM_RENDER)) && fType == 1.0f) - { - return false; - } - - if (m_pAmount->GetParam() > 0.005f) - { - return true; - } - } - - return false; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CFlashBang::Release() -{ - SAFE_DELETE(m_pGhostImage); -} - -void CFlashBang::Reset([[maybe_unused]] bool bOnSpecChange) -{ - SAFE_DELETE(m_pGhostImage); - m_pActive->ResetParam(0.0f); - m_pTime->ResetParam(2.0f); - m_pDifractionAmount->ResetParam(1.0f); - m_pBlindAmount->ResetParam(0.5f); - m_fBlindAmount = 1.0f; - m_fSpawnTime = 0.0f; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CSoftAlphaTest::Reset([[maybe_unused]] bool bOnSpecChange) -{ -} - -bool CSoftAlphaTest::Preprocess() -{ - uint32 nBatchMask = SRendItem::BatchFlags(EFSLIST_GENERAL, gRenDev->m_RP.m_pRLD); - return CRenderer::CV_r_SoftAlphaTest != 0 && (nBatchMask & FB_SOFTALPHATEST); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CImageGhosting::Preprocess() -{ - CTexture* pPrevFrame = CTexture::s_ptexPrevFrameScaled; - if (!pPrevFrame) - { - m_bInit = true; - return false; - } - - if (m_pAmount->GetParam() > 0.09f) - { - return true; - } - - m_bInit = true; - - return false; -} - -void CImageGhosting::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_bInit = true; - m_pAmount->ResetParam(0.0f); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CFilterKillCamera::Initialize() -{ - m_techName = "KillCameraFilter"; - m_paramName = "psParams"; - return 1; -} - -bool CFilterKillCamera::Preprocess() -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessFilters) - { - return false; - } - - if (m_pActive->GetParam() > 0.0f) - { - const int mode = int_round(m_pMode->GetParam()); - if (mode != m_lastMode) - { - m_blindTimer = 0.0f; - m_lastMode = mode; - } - - return true; - } - - m_blindTimer = 0.0f; - - return false; -} - -void CFilterKillCamera::Reset([[maybe_unused]] bool bOnSpecChange) -{ - // Game controls parameters + reset (removed from here due to a race condition). -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CScreenBlood::Reset([[maybe_unused]] bool bOnSpecChange) -{ - m_pAmount->ResetParam(0.0f); - m_pBorder->ResetParamVec4(Vec4(0.0f, 0.0f, 2.0f, 1.0f)); // Border: x=xOffset y=yOffset z=range w=alpha -} - -bool CScreenBlood::Preprocess() -{ - return (CRenderer::CV_r_PostProcessGameFx && m_pAmount->GetParam() > 0.005f); -} - -////////////////////////////////////////////////////////////////////////// - -bool CPost3DRenderer::Preprocess() -{ - if (IsActive()) - { - // Defer turning off post effect for 5 frames - sometimes the flash is left rendering on the screen - // for a frame, if we don't render the post effect for this frame then junk will be rendered into - // the flash. Currently the post effect is disabled at the latest point in menu code, thus this is the - // simplest/safest fix. - m_deferDisableFrameCountDown = 5; - } - else if (m_deferDisableFrameCountDown > 0) - { - m_deferDisableFrameCountDown--; - } - - const bool bRender = (m_deferDisableFrameCountDown > 0) ? true : false; - return bRender; -} - -void CPost3DRenderer::Reset([[maybe_unused]] bool bOnSpecChange) -{ - // Let game code fully control its active status, otherwise in some situations - // the post effect system will get reset between menus and game and thus this - // will get turned off when undesired -} - -////////////////////////////////////////////////////////////////////////// - -// AZStd visitor class to resolve the effect parameter into the appropriate type -class FetchVisitor -{ -public: - - void SetEffectParam( CEffectParam* effectParameter ) - { - m_effectParam = effectParameter; - } - - void operator()(float param) - { - m_effectParam->SetParam(param); - } - - void operator()(const Vec4& param) - { - m_effectParam->SetParamVec4(param); - } - - void operator()(const AZStd::string& param) - { - m_effectParam->SetParamString(param.c_str()); - } - -private: - - CEffectParam* m_effectParam = nullptr; -}; - -// Helper function to set a CEffectParam from a group, visitor and parameter name -void SetEffectParamFromVisitor( IPostEffectGroup* group, FetchVisitor& fetchVisitor, const char* paramName, CEffectParam* effectParam /* in/out */ ) -{ - PostEffectGroupParam* groupParam = group->GetParam(paramName); - fetchVisitor.SetEffectParam( effectParam ); - AZStd::visit(fetchVisitor, *groupParam); -} - -bool ScreenFader::Preprocess() -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_PostProcessGameFx) - { - return false; - } - - IPostEffectGroupManager* groupManager = gEnv->p3DEngine->GetPostEffectGroups(); - const PostEffectGroupList& toggledGroupList = groupManager->GetGroupsToggledThisFrame(); - bool newScreenPassAdded = false; - - // Iterate over all of the groups that had their enabled/disabled flag toggled this frame - // If the group already exists in the screenpass list, then that should mean it either needs change its - // state to fade-in (if it was actively fading-out), or it needs to change to fade-out (if it was actively fading in or rendering at full opacity) - // Once a group has faded out completely, then it will be removed from the screenpass list. - for ( auto groupIter = toggledGroupList.begin(); groupIter != toggledGroupList.end(); ++groupIter ) - { - IPostEffectGroup* group = (*groupIter); - bool foundGroupInList = false; - for ( ScreenPassList::iterator passIter = m_screenPasses.begin(); passIter != m_screenPasses.end(); ++passIter ) - { - ScreenFaderPass* pass = (*passIter); - if ( pass->m_group == group ) - { - foundGroupInList = true; - if ( group->GetEnable() ) - { - // If the group has changed to enabled, then that means the group was actively fading out before - // Change its state to fade-in, and fade from its existing alpha value. - pass->m_fadingIn = true; - pass->m_fadingOut = false; - pass->m_fadeDirection = 1.0f; - pass->m_fadeDuration = pass->m_fadeInTime; - } - else - { - // If the group has changed to disabled, then that means we were either actively fading in or rendering at full opacity. - // Change its state to fade out and fade from its existing alpha value - pass->m_fadingIn = false; - pass->m_fadingOut = true; - pass->m_fadeDirection = -1.0f; - pass->m_fadeDuration = pass->m_fadeOutTime; - } - break; - } - } - - // If the group was not found, then add it to the list - if ( !foundGroupInList ) - { - FetchVisitor groupParamVisitor; - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_Enable", m_enable ); - bool fadeIn = m_enable->GetParam() ? true : false; - - if ( fadeIn ) - { - // The screen fader is different from the other PostEffects in the PostEffectsGroups. - // We do not want the interpolated parameters when enabling another group since we want to render - // multiple stacked screenfaders. Fetch the parameters from the original PostEffectGroup for this - // screen fader pass - ScreenFaderPass* pass = new ScreenFaderPass(); - pass->m_group = group; - pass->m_fadingIn = true; - pass->m_fadeDirection = 1.0f; - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_FadeColor", m_fadeColor ); - pass->m_currentColor = m_fadeColor->GetParamVec4(); - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_ScreenCoordinates", m_screenCoordinates ); - pass->m_screenCoordinates = m_screenCoordinates->GetParamVec4(); - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_TextureName", m_fadeTextureParam ); - pass->m_fadeTexture = static_cast(m_fadeTextureParam)->GetParamTexture(); - - if (pass->m_fadeTexture) - { - // Since we are manually holding onto a CTexture pointer, make sure we increment the ref count - pass->m_fadeTexture->AddRef(); - } - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_FadeOutTime", m_fadeOutTime ); - pass->m_fadeOutTime = m_fadeOutTime->GetParam(); - - SetEffectParamFromVisitor( group, groupParamVisitor, "ScreenFader_FadeInTime", m_fadeInTime ); - pass->m_fadeInTime = m_fadeInTime->GetParam(); - pass->m_fadeDuration = pass->m_fadeInTime; - - m_screenPasses.push_back( pass ); - newScreenPassAdded = true; - } - } - } - - // If we added a new ScreenPass, then re-sort our ScreenPasses based on the PostEffectGroup's priorities - if ( newScreenPassAdded ) - { - m_screenPasses.sort(SortFaderPasses); - } - - // Update all of the screen passes, removing any that have recently faded out from the list. - auto passIter = m_screenPasses.begin(); - while ( passIter != m_screenPasses.end() ) - { - ScreenFaderPass* pass = (*passIter); - - if ( pass->m_fadingOut && pass->m_currentFadeTime <= 0.0f ) - { - // We have finished fading out. Now clean up the list and remove the pass. - delete pass; - passIter = m_screenPasses.erase(passIter); - } - else if ( pass->m_fadingIn && (pass->m_currentFadeTime >= pass->m_fadeDuration) ) - { - // We have finished fading in. Stay at 100% fade time until fade out is triggered. - pass->m_currentFadeTime = pass->m_fadeDuration; - pass->m_fadingIn = false; - } - ++passIter; - } - - return m_screenPasses.size() > 0; -} - -void ScreenFader::Reset([[maybe_unused]] bool bOnSpecChange) -{ - // Do not clear m_screenPasses here, otherwise global and default PostEffectGroups will be removed -} - -bool ScreenFader::SortFaderPasses(ScreenFaderPass* pass1, ScreenFaderPass* pass2) -{ - return pass1->m_group->GetPriority() < pass2->m_group->GetPriority(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.h b/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.h deleted file mode 100644 index 61bc127f71..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostEffects.h +++ /dev/null @@ -1,1645 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTEFFECTS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTEFFECTS_H -#pragma once - -#include "PostProcessUtils.h" - -#include - -struct MotionBlurObjectParameters -{ - MotionBlurObjectParameters() - : m_renderObject{} - , m_updateFrameId{} - {} - - MotionBlurObjectParameters(CRenderObject* renderObject, const Matrix34A& worldMatrix, AZ::u32 updateFrameId) - : m_worldMatrix(worldMatrix) - , m_renderObject(renderObject) - , m_updateFrameId(updateFrameId) {} - - Matrix34 m_worldMatrix; - CRenderObject* m_renderObject; - AZ::u32 m_updateFrameId; -}; - -////////////////////////////////////////////////////////////////////////// - -class CMotionBlur - : public CPostEffect -{ -public: - CMotionBlur() - { - m_nRenderFlags = 0; - m_nID = ePFX_eMotionBlur; - - // Register technique instance and it's parameters - AddParamBool("MotionBlur_Active", m_pActive, 0); - AddParamFloatNoTransition("FilterRadialBlurring_Amount", m_pRadBlurAmount, 0.0f); - AddParamFloatNoTransition("FilterRadialBlurring_ScreenPosX", m_pRadBlurScreenPosX, 0.5f); - AddParamFloatNoTransition("FilterRadialBlurring_ScreenPosY", m_pRadBlurScreenPosY, 0.5f); - AddParamFloatNoTransition("FilterRadialBlurring_Radius", m_pRadBlurRadius, 1.0f); - AddParamVec4("Global_DirectionalBlur_Vec", m_pDirectionalBlurVec, Vec4(0, 0, 0, 0)); - - for (int idx = 0; idx < AZ_ARRAY_SIZE(m_Objects); ++idx) - { - m_Objects[idx] = AZStd::make_unique(); - } - } - - virtual ~CMotionBlur() - { - Release(); - } - - virtual void Render(); - virtual bool Preprocess(); - - virtual void Release() - { - m_Objects[0]->clear(); - m_Objects[1]->clear(); - m_Objects[2]->clear(); - } - - virtual void Reset([[maybe_unused]] bool bOnSpecChange = false) - { - m_pDirectionalBlurVec->ResetParamVec4(Vec4(0, 0, 0, 0)); - } - - void RenderObjectsVelocity(); - void CopyAndScaleDoFBuffer(CTexture* pSrcTex, CTexture* pDestTex); - void OnBeginFrame(); - float ComputeMotionScale(); - - static void SetupObject(CRenderObject* pObj, const SRenderingPassInfo& passInfo); - static void GetPrevObjToWorldMat(CRenderObject* pObj, Matrix44A& res); - static void InsertNewElements(); - static void FreeData(); - - static const Matrix44A &GetPrevView() - { - return gRenDev->GetPreviousFrameMatrixSet().m_ViewMatrix; - } - - virtual const char* GetName() const - { - return "MotionBlur"; - } - -private: - friend class CMotionBlurPass; - - CEffectParam* m_pRadBlurAmount, * m_pRadBlurScreenPosX, * m_pRadBlurScreenPosY, * m_pRadBlurRadius; - CEffectParam* m_pDirectionalBlurVec; - - //! m_Objects contains motion blur parameters and is triple buffered - //! t0: being written, t-1: current render frame, t-2: previous render frame - static const uint32_t s_maxObjectBuffers = 3; - typedef VectorMap ObjectMap; - static AZStd::unique_ptr m_Objects[s_maxObjectBuffers]; - - //! Thread safe double buffered fill data used to populate the m_Objects buffer - static TSRC_ALIGN CThreadSafeRendererContainer m_FillData[RT_COMMAND_BUF_COUNT]; - - //! The threshold in frames at which we want to discard per-object motion data - static const uint32_t s_discardThreshold = 60; -}; - -struct DepthOfFieldParameters -{ - DepthOfFieldParameters() - : m_bEnabled{false} - {} - - Vec4 m_FocusParams0; - Vec4 m_FocusParams1; - bool m_bEnabled; -}; - -////////////////////////////////////////////////////////////////////////// -// Deprecated: This class is used as a placeholder for parameters, but the -// rendering logic now lives in DepthOfFieldPass. -// -class CDepthOfField - : public CPostEffect -{ -public: - CDepthOfField() - { - m_nRenderFlags = 0; - m_nID = ePFX_eDepthOfField; - AddParamBool("Dof_Active", m_pActive, 0); - AddParamFloatNoTransition("Dof_FocusDistance", m_pFocusDistance, 3.5f); - AddParamFloatNoTransition("Dof_FocusRange", m_pFocusRange, 0.0f); - AddParamFloatNoTransition("Dof_FocusMin", m_pFocusMin, 2.0f); - AddParamFloatNoTransition("Dof_FocusMax", m_pFocusMax, 10.0f); - AddParamFloatNoTransition("Dof_FocusLimit", m_pFocusLimit, 100.0f); - AddParamFloatNoTransition("Dof_CenterWeight", m_pCenterWeight, 1.0f); - AddParamFloatNoTransition("Dof_BlurAmount", m_pBlurAmount, 1.0f); - AddParamBool("Dof_User_Active", m_pUserActive, 0); - AddParamFloatNoTransition("Dof_User_FocusDistance", m_pUserFocusDistance, 3.5f); - AddParamFloatNoTransition("Dof_User_FocusRange", m_pUserFocusRange, 5.0f); - AddParamFloatNoTransition("Dof_User_BlurAmount", m_pUserBlurAmount, 1.0f); - AddParamFloatNoTransition("Dof_Tod_FocusRange", m_pTimeOfDayFocusRange, 1000.0f); - AddParamFloatNoTransition("Dof_Tod_BlurAmount", m_pTimeOfDayBlurAmount, 0.0f); - AddParamFloatNoTransition("Dof_FocusMinZ", m_pFocusMinZ, 0.0f); // 0.4 is good default - AddParamFloatNoTransition("Dof_FocusMinZScale", m_pFocusMinZScale, 0.0f); // 1.0 is good default - - m_fUserFocusRangeCurr = 0; - m_fUserFocusDistanceCurr = 0; - m_fUserBlurAmountCurr = 0; - m_todFocusRange = 0.0f; - m_todBlurAmount = 0.0f; - } - - virtual void Reset([[maybe_unused]] bool bOnSpecChange = false) - { - m_pFocusDistance->ResetParam(3.5f); - m_pFocusRange->ResetParam(0.0f); - m_pCenterWeight->ResetParam(1.0f); - m_pBlurAmount->ResetParam(1.0f); - m_pFocusMin->ResetParam(2.0f); - m_pFocusMax->ResetParam(10.0f); - m_pFocusLimit->ResetParam(100.0f); - m_pActive->ResetParam(0.0f); - m_pUserActive->ResetParam(0.0f); - m_pUserFocusDistance->ResetParam(3.5f); - m_pUserFocusRange->ResetParam(5.0f); - m_pUserBlurAmount->ResetParam(1.0f); - m_pFocusMinZ->ResetParam(0.0f); - m_pFocusMinZScale->ResetParam(0.0f); - - m_fUserFocusRangeCurr = 0; - m_fUserFocusDistanceCurr = 0; - m_fUserBlurAmountCurr = 0; - m_todFocusRange = 0; - m_todBlurAmount = 0; - } - - virtual int CreateResources() { return true; } - virtual void Release() {} - virtual void Render() {} - virtual bool Preprocess() { return false; } - virtual const char* GetName() const { return "DepthOfField"; } - - void UpdateParameters(); - - const DepthOfFieldParameters& GetParameters() const - { - return m_Parameters; - } - -private: - CEffectParam* m_pFocusDistance, * m_pFocusRange, * m_pCenterWeight, * m_pBlurAmount; - CEffectParam* m_pFocusMin, * m_pFocusMax; - CEffectParam* m_pUserActive, * m_pUserFocusDistance, * m_pUserFocusRange, * m_pUserBlurAmount; - CEffectParam* m_pTimeOfDayFocusRange, * m_pTimeOfDayBlurAmount; - CEffectParam* m_pFocusMinZ, * m_pFocusMinZScale, *m_pFocusLimit; - - DepthOfFieldParameters m_Parameters; - - float m_fUserFocusRangeCurr; - float m_fUserFocusDistanceCurr; - float m_fUserBlurAmountCurr; - float m_todFocusRange; - float m_todBlurAmount; -}; - -class CPostAA - : public CPostEffect -{ -public: - CPostAA() - { - m_nRenderFlags = PSP_UPDATE_SCENE_SPECULAR; - m_nID = ePFX_PostAA; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset([[maybe_unused]] bool bOnSpecChange = false) {} - - virtual const char* GetName() const - { - return "PostAA"; - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CSunShafts - : public CPostEffect -{ -public: - CSunShafts() - { - m_nID = ePFX_SunShafts; - m_pOcclQuery = 0; - - AddParamBool("SunShafts_Active", m_pActive, 0); - AddParamInt("SunShafts_Type", m_pShaftsType, 0); // default shafts type - highest quality - AddParamFloatNoTransition("SunShafts_Amount", m_pShaftsAmount, 0.25f); // shafts visibility - AddParamFloatNoTransition("SunShafts_RaysAmount", m_pRaysAmount, 0.25f); // rays visibility - AddParamFloatNoTransition("SunShafts_RaysAttenuation", m_pRaysAttenuation, 5.0f); // rays attenuation - AddParamFloatNoTransition("SunShafts_RaysSunColInfluence", m_pRaysSunColInfluence, 1.0f); // sun color influence - AddParamVec4NoTransition("SunShafts_RaysCustomColor", m_pRaysCustomCol, Vec4(1.0f, 1.0f, 1.0f, 1.0f)); - AddParamFloat("Scratches_Strength", m_pScratchStrength, 0.0f); - AddParamFloat("Scratches_Threshold", m_pScratchThreshold, 0.0f); - AddParamFloat("Scratches_Intensity", m_pScratchIntensity, 0.7f); - m_bShaftsEnabled = false; - m_nVisSampleCount = 0; - } - - - virtual int Initialize(); - virtual void Release(); - virtual void OnLostDevice(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - bool IsVisible(); - bool SunShaftsGen(CTexture* pSunShafts, CTexture* pPingPongRT = 0); - bool MergedSceneDownsampleAndSunShaftsMaskGen(CTexture* pSceneSrc, CTexture* pSceneDst, CTexture* pSunShaftsMaskDst); - void GetSunShaftsParams(Vec4 pParams[2]) - { - pParams[0] = m_pRaysCustomCol->GetParamVec4(); - pParams[1] = Vec4(0, 0, m_pRaysAmount->GetParam(), m_pRaysSunColInfluence->GetParam()); - } - - virtual const char* GetName() const - { - return "MergedSunShaftsEdgeAAColorCorrection"; - } - -private: - - bool m_bShaftsEnabled; - uint32 m_nVisSampleCount; - - // int, float, float, float, vec4 - CEffectParam* m_pShaftsType, * m_pShaftsAmount, * m_pRaysAmount, * m_pRaysAttenuation, * m_pRaysSunColInfluence, * m_pRaysCustomCol; - CEffectParam* m_pScratchStrength, * m_pScratchThreshold, * m_pScratchIntensity; - COcclusionQuery* m_pOcclQuery; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CFilterSharpening - : public CPostEffect -{ -public: - CFilterSharpening() - { - m_nID = ePFX_FilterSharpening; - - AddParamInt("FilterSharpening_Type", m_pType, 0); - AddParamFloat("FilterSharpening_Amount", m_pAmount, 1.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "FilterSharpening"; - } - -private: - - // float, int - CEffectParam* m_pAmount, * m_pType; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CFilterBlurring - : public CPostEffect -{ -public: - CFilterBlurring() - { - m_nID = ePFX_FilterBlurring; - - AddParamInt("FilterBlurring_Type", m_pType, 0); - AddParamFloat("FilterBlurring_Amount", m_pAmount, 0.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "FilterBlurring"; - } - -private: - - // float, int - CEffectParam* m_pAmount, * m_pType; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CUberGamePostProcess - : public CPostEffect -{ -public: - - // Bitmaks used to enable only certain effects or combinations of most expensive effects - enum EPostsProcessMask - { - ePE_SyncArtifacts = (1 << 0), - ePE_RadialBlur = (1 << 1), - ePE_ChromaShift = (1 << 2), - }; - - CUberGamePostProcess() - { - m_nID = ePFX_UberGamePostProcess; - m_nCurrPostEffectsMask = 0; - - AddParamTex("tex_VisualArtifacts_Mask", m_pMask, 0); - - AddParamVec4("clr_VisualArtifacts_ColorTint", m_pColorTint, Vec4(1.0f, 1.0f, 1.0f, 1.0f)); - - AddParamFloat("VisualArtifacts_Vsync", m_pVSyncAmount, 0.0f); - AddParamFloat("VisualArtifacts_VsyncFreq", m_pVSyncFreq, 1.0f); - - AddParamFloat("VisualArtifacts_Interlacing", m_pInterlationAmount, 0.0f); - AddParamFloat("VisualArtifacts_InterlacingTile", m_pInterlationTiling, 1.0f); - AddParamFloat("VisualArtifacts_InterlacingRot", m_pInterlationRotation, 0.0f); - - AddParamFloat("VisualArtifacts_Pixelation", m_pPixelationScale, 0.0f); - AddParamFloat("VisualArtifacts_Noise", m_pNoise, 0.0f); - - AddParamFloat("VisualArtifacts_SyncWaveFreq", m_pSyncWaveFreq, 0.0f); - AddParamFloat("VisualArtifacts_SyncWavePhase", m_pSyncWavePhase, 0.0f); - AddParamFloat("VisualArtifacts_SyncWaveAmplitude", m_pSyncWaveAmplitude, 0.0f); - - AddParamFloat("FilterChromaShift_User_Amount", m_pFilterChromaShiftAmount, 0.0f); // Kept for backward - compatibility - AddParamFloat("FilterArtifacts_ChromaShift", m_pChromaShiftAmount, 0.0f); - - AddParamFloat("FilterGrain_Amount", m_pFilterGrainAmount, 0.0f);// Kept for backward - compatibility - AddParamFloat("FilterArtifacts_Grain", m_pGrainAmount, 0.0f); - AddParamFloatNoTransition("FilterArtifacts_GrainTile", m_pGrainTile, 1.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "UberGamePostProcess"; - } - -private: - CEffectParam* m_pVSyncAmount; - CEffectParam* m_pVSyncFreq; - - CEffectParam* m_pColorTint; - - CEffectParam* m_pInterlationAmount; - CEffectParam* m_pInterlationTiling; - CEffectParam* m_pInterlationRotation; - - CEffectParam* m_pPixelationScale; - CEffectParam* m_pNoise; - - CEffectParam* m_pSyncWaveFreq; - CEffectParam* m_pSyncWavePhase; - CEffectParam* m_pSyncWaveAmplitude; - - CEffectParam* m_pFilterChromaShiftAmount; - CEffectParam* m_pChromaShiftAmount; - - CEffectParam* m_pGrainAmount; - CEffectParam* m_pFilterGrainAmount; // todo: add support - CEffectParam* m_pGrainTile; - - CEffectParam* m_pMask; - - uint8 m_nCurrPostEffectsMask; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -struct SColorGradingMergeParams; - -class CColorGrading - : public CPostEffect -{ -public: - CColorGrading() - { - m_nID = ePFX_ColorGrading; - - // levels adjustment - AddParamFloatNoTransition("ColorGrading_minInput", m_pMinInput, 0.0f); - AddParamFloatNoTransition("ColorGrading_gammaInput", m_pGammaInput, 1.0f); - AddParamFloatNoTransition("ColorGrading_maxInput", m_pMaxInput, 255.0f); - AddParamFloatNoTransition("ColorGrading_minOutput", m_pMinOutput, 0.0f); - AddParamFloatNoTransition("ColorGrading_maxOutput", m_pMaxOutput, 255.0f); - - // generic color adjustment - AddParamFloatNoTransition("ColorGrading_Brightness", m_pBrightness, 1.0f); - AddParamFloatNoTransition("ColorGrading_Contrast", m_pContrast, 1.0f); - AddParamFloatNoTransition("ColorGrading_Saturation", m_pSaturation, 1.0f); - - // filter color - m_pDefaultPhotoFilterColor = Vec4(0.952f, 0.517f, 0.09f, 1.0f); - AddParamVec4NoTransition("clr_ColorGrading_PhotoFilterColor", m_pPhotoFilterColor, m_pDefaultPhotoFilterColor); // use photoshop default orange - AddParamFloatNoTransition("ColorGrading_PhotoFilterColorDensity", m_pPhotoFilterColorDensity, 0.0f); - - // selective color - AddParamVec4NoTransition("clr_ColorGrading_SelectiveColor", m_pSelectiveColor, Vec4(0.0f, 0.0f, 0.0f, 0.0f)), - AddParamFloatNoTransition("ColorGrading_SelectiveColorCyans", m_pSelectiveColorCyans, 0.0f), - AddParamFloatNoTransition("ColorGrading_SelectiveColorMagentas", m_pSelectiveColorMagentas, 0.0f), - AddParamFloatNoTransition("ColorGrading_SelectiveColorYellows", m_pSelectiveColorYellows, 0.0f), - AddParamFloatNoTransition("ColorGrading_SelectiveColorBlacks", m_pSelectiveColorBlacks, 0.0f), - - // mist adjustment - AddParamFloatNoTransition("ColorGrading_GrainAmount", m_pGrainAmount, 0.0f); - AddParamFloatNoTransition("ColorGrading_SharpenAmount", m_pSharpenAmount, 1.0f); - - // user params - AddParamFloatNoTransition("ColorGrading_Saturation_Offset", m_pSaturationOffset, 0.0f); - AddParamVec4NoTransition("ColorGrading_PhotoFilterColor_Offset", m_pPhotoFilterColorOffset, Vec4(0.0f, 0.0f, 0.0f, 0.0f)); - AddParamFloatNoTransition("ColorGrading_PhotoFilterColorDensity_Offset", m_pPhotoFilterColorDensityOffset, 0.0f); - AddParamFloatNoTransition("ColorGrading_GrainAmount_Offset", m_pGrainAmountOffset, 0.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - bool UpdateParams(SColorGradingMergeParams& pMergeParams); - - virtual const char* GetName() const - { - return "ColorGrading"; - } - -private: - - // levels adjustment - CEffectParam* m_pMinInput; - CEffectParam* m_pGammaInput; - CEffectParam* m_pMaxInput; - CEffectParam* m_pMinOutput; - CEffectParam* m_pMaxOutput; - - // generic color adjustment - CEffectParam* m_pBrightness; - CEffectParam* m_pContrast; - CEffectParam* m_pSaturation; - CEffectParam* m_pSaturationOffset; - - // filter color - CEffectParam* m_pPhotoFilterColor; - CEffectParam* m_pPhotoFilterColorDensity; - CEffectParam* m_pPhotoFilterColorOffset; - CEffectParam* m_pPhotoFilterColorDensityOffset; - Vec4 m_pDefaultPhotoFilterColor; - - // selective color - CEffectParam* m_pSelectiveColor; - CEffectParam* m_pSelectiveColorCyans; - CEffectParam* m_pSelectiveColorMagentas; - CEffectParam* m_pSelectiveColorYellows; - CEffectParam* m_pSelectiveColorBlacks; - - // misc adjustments - CEffectParam* m_pGrainAmount; - CEffectParam* m_pGrainAmountOffset; - - CEffectParam* m_pSharpenAmount; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CUnderwaterGodRays - : public CPostEffect -{ -public: - CUnderwaterGodRays() - { - m_nID = ePFX_eUnderwaterGodRays; - - AddParamFloat("UnderwaterGodRays_Amount", m_pAmount, 1.0f); - AddParamInt("UnderwaterGodRays_Quality", m_pQuality, 1); // 0 = low, 1 = med, 2= high, 3= ultra-high, 4= crazy high, and so on - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "UnderwaterGodRays"; - } - -private: - - // float, int - CEffectParam* m_pAmount, * m_pQuality; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CVolumetricScattering - : public CPostEffect -{ -public: - CVolumetricScattering() - { - m_nID = ePFX_eVolumetricScattering; - - AddParamFloat("VolumetricScattering_Amount", m_pAmount, 0.0f); - AddParamFloat("VolumetricScattering_Tilling", m_pTiling, 1.0f); - AddParamFloat("VolumetricScattering_Speed", m_pSpeed, 1.0f); - AddParamVec4("clr_VolumetricScattering_Color", m_pColor, Vec4(0.5f, 0.75f, 1.0f, 1.0f)); - - AddParamInt("VolumetricScattering_Type", m_pType, 0); // 0 = alien environment, 1 = ?, 2 = ?? ??? - AddParamInt("VolumetricScattering_Quality", m_pQuality, 1); // 0 = low, 1 = med, 2= high, 3= ultra-high, 4= crazy high, and so on - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "VolumetricScattering"; - } - -private: - - // float, int, int - CEffectParam* m_pAmount, * m_pTiling, * m_pSpeed, * m_pColor, * m_pType, * m_pQuality; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Game/Hud specific post-effects -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CAlienInterference - : public CPostEffect -{ -public: - CAlienInterference() - { - m_nID = ePFX_eAlienInterference; - - AddParamFloat("AlienInterference_Amount", m_pAmount, 0); - AddParamVec4NoTransition("clr_AlienInterference_Color", m_pTintColor, Vec4(Vec3(0.85f, 0.95f, 1.25f) * 0.5f, 1.0f)); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "AlienInterference"; - } - -private: - - // float - CEffectParam* m_pAmount; - // vec4 - CEffectParam* m_pTintColor; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -class CGhostVision - : public CPostEffect -{ -public: - CGhostVision() - { - m_nID = ePFX_eGhostVision; - - m_pUserTex1 = 0; - m_pUserTex2 = 0; - - AddParamBool("GhostVision_Bool1", m_pUserBool1, 0); - AddParamBool("GhostVision_Bool2", m_pUserBool2, 0); - AddParamBool("GhostVision_Bool3", m_pUserBool3, 0); - AddParamFloat("GhostVision_Amount1", m_pUserValue1, 0); - AddParamFloat("GhostVision_Amount2", m_pUserValue2, 0); - AddParamFloat("GhostVision_Amount3", m_pUserValue3, 0); - AddParamVec4NoTransition("clr_GhostVision_Color", m_pTintColor, Vec4(Vec3(0.55f, 0.55f, 0.55f) * 0.5f, 1.0f)); - } - - virtual int CreateResources(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Release(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "GhostVision"; - } - -private: - // texture - CTexture* m_pUserTex1; - CTexture* m_pUserTex2; - - // bool - CEffectParam* m_pUserBool1; - CEffectParam* m_pUserBool2; - CEffectParam* m_pUserBool3; - - // float - CEffectParam* m_pUserValue1; - CEffectParam* m_pUserValue2; - CEffectParam* m_pUserValue3; - - // vec4 - CEffectParam* m_pTintColor; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -class CWaterDroplets - : public CPostEffect -{ -public: - CWaterDroplets() - { - m_nID = ePFX_eWaterDroplets; - - AddParamFloat("WaterDroplets_Amount", m_pAmount, 0.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "WaterDroplets"; - } - -private: - - // float - CEffectParam* m_pAmount; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CWaterFlow - : public CPostEffect -{ -public: - CWaterFlow() - { - m_nID = ePFX_eWaterFlow; - - AddParamFloat("WaterFlow_Amount", m_pAmount, 0.0f); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "WaterFlow"; - } - -private: - - // float - CEffectParam* m_pAmount; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CWaterRipples - : public CPostEffect -{ - struct SWaterHit - { - SWaterHit() - : worldPos(0.0f, 0.0f) - , scale(1.0f) - , strength(1.0f) - { - } - - SWaterHit(const Vec3& hitWorldPos, const float hitScale, const float hitStrength) - : worldPos(hitWorldPos.x, hitWorldPos.y) - , scale(hitScale) - , strength(hitStrength) - { - } - - Vec2 worldPos; - float scale; - float strength; - }; - -public: - CWaterRipples() - : m_bSnapToCenter(false) - , m_bInitializeSim(true) - { - m_nRenderFlags = 0; - m_nID = ePFX_WaterRipples; - - AddParamFloatNoTransition("WaterRipples_Amount", m_pAmount, 0.0f); - - m_pRipplesGenTechName = "WaterRipplesGen"; - m_pRipplesHitTechName = "WaterRipplesHit"; - m_pRipplesParamName = "WaterRipplesParams"; - - m_fLastSpawnTime = 0.0f; - m_fSimGridSize = 25.0f; - m_fSimGridSnapRange = 5.0f; - - for (uint32 i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - s_pWaterHits[i].reserve(16); - } - - s_nUpdateMask = 0; - } - - static void CreatePhysCallbacks(); - static void ReleasePhysCallbacks(); - virtual bool Preprocess(); - - // Enabled/Disabled if no hits on list to process - call from render thread - bool RT_SimulationStatus(); - - // Add hits to list - called from main thread - static void AddHit(const Vec3& vPos, const float scale, const float strength); - - virtual void Release() - { - Reset(); - } - - void RenderHits(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "WaterRipples"; - } - - Vec4 GetLookupParams() { return s_vLookupParams; } - - void DEBUG_DrawWaterHits(); - -private: - - static int OnEventPhysCollision(const struct EventPhys* pEvent); - -private: - - enum - { - MAX_HITS = 128 - }; - - struct SWaterHitRecord - { - SWaterHit mHit; - float fHeight; - int nCounter; - }; - - CCryNameTSCRC m_pRipplesGenTechName; - CCryNameTSCRC m_pRipplesHitTechName; - CCryNameR m_pRipplesParamName; - - // float - CEffectParam* m_pAmount; - float m_fLastSpawnTime; - float m_fLastUpdateTime; - - float m_fSimGridSize; - float m_fSimGridSnapRange; - - static AZStd::vector< CWaterRipples::SWaterHit, AZ::StdLegacyAllocator > s_pWaterHits[RT_COMMAND_BUF_COUNT]; - static AZStd::vector< CWaterRipples::SWaterHit, AZ::StdLegacyAllocator > s_pWaterHitsMGPU; - static AZStd::vector< CWaterRipples::SWaterHitRecord, AZ::StdLegacyAllocator > m_DebugWaterHits; - static Vec3 s_CameraPos; - static Vec2 s_SimOrigin; - - static int s_nUpdateMask; - static Vec4 s_vParams; - static Vec4 s_vLookupParams; - - static bool s_bInitializeSim; - bool m_bSnapToCenter; - bool m_bInitializeSim; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CWaterVolume - : public CPostEffect -{ -public: - CWaterVolume() - { - m_nRenderFlags = 0; - m_nID = ePFX_WaterVolume; - - AddParamFloatNoTransition("WaterVolume_Amount", m_pAmount, 0.0f); - m_nCurrSimID = 0; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - int GetCurrentPuddle() - { - return m_nCurrSimID; - } - - virtual const char* GetName() const - { - return "WaterVolume"; - } - -private: - - // float - CEffectParam* m_pAmount; - int m_nCurrSimID; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CScreenFrost - : public CPostEffect -{ -public: - CScreenFrost() - { - m_nID = ePFX_eScreenFrost; - - AddParamFloat("ScreenFrost_Amount", m_pAmount, 0.0f); // amount of visible frost - AddParamFloat("ScreenFrost_CenterAmount", m_pCenterAmount, 1.0f); // amount of visible frost in center - - m_fRandOffset = 0; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "ScreenFrost"; - } - -private: - - // float, float - CEffectParam* m_pAmount, * m_pCenterAmount; - float m_fRandOffset; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CRainDrops - : public CPostEffect -{ -public: - CRainDrops() - { - m_nID = ePFX_eRainDrops; - - AddParamFloat("RainDrops_Amount", m_pAmount, 0.0f); // amount of visible droplets - AddParamFloat("RainDrops_SpawnTimeDistance", m_pSpawnTimeDistance, 0.35f); // amount of visible droplets - AddParamFloat("RainDrops_Size", m_pSize, 5.0f); // drop size - AddParamFloat("RainDrops_SizeVariation", m_pSizeVar, 2.5f); // drop size variation - - m_uCurrentDytex = 0; - m_pVelocityProj = Vec3(0, 0, 0); - - m_nAliveDrops = 0; - - m_pPrevView.SetIdentity(); - m_pViewProjPrev.SetIdentity(); - - m_bFirstFrame = true; - } - - virtual ~CRainDrops() - { - Release(); - } - - virtual int CreateResources(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual void Release(); - - virtual const char* GetName() const; - -private: - - // Rain particle properties - struct SRainDrop - { - // set default data - SRainDrop() - : m_pPos(0, 0, 0) - , m_fSize(5.0f) - , m_fSizeVar(2.5f) - , m_fSpawnTime(0.0f) - , m_fLifeTime(2.0f) - , m_fLifeTimeVar(1.0f) - , m_fWeight(1.0f) - , m_fWeightVar(0.25f) - { - } - - // Screen position - Vec3 m_pPos; - // Size and variation (bigger also means more weight) - float m_fSize, m_fSizeVar; - // Spawn time - float m_fSpawnTime; - // Life time and variation - float m_fLifeTime, m_fLifeTimeVar; - // Weight and variation - float m_fWeight, m_fWeightVar; - }; - - //in Preprocess(), check if effect is active - bool IsActiveRain(); - - // Compute current interpolated view matrix - Matrix44 ComputeCurrentView(int iViewportWidth, int iViewportHeight); - - // Spawn a particle - void SpawnParticle(SRainDrop*& pParticle, int iRTWidth, int iRTHeight); - // Update all particles - void UpdateParticles(int iRTWidth, int iRTHeight); - // Generate rain drops map - void RainDropsMapGen(); - // Draw the raindrops - void DrawRaindrops(int iViewportWidth, int iViewportHeight, int iRTWidth, int iRTHeight); - // Apply the blur and movement to it - void ApplyExtinction(CTexture*& rptexPrevRT, int iViewportWidth, int iViewportHeight, int iRTWidth, int iRTHeight); - - // Final draw pass, merge with backbuffer - void DrawFinal(CTexture*& rptexCurrRT); - - // float - CEffectParam* m_pAmount; - CEffectParam* m_pSpawnTimeDistance; - CEffectParam* m_pSize; - CEffectParam* m_pSizeVar; - - uint16 m_uCurrentDytex; - bool m_bFirstFrame; - - //todo: use generic screen particles - typedef std::vector SRainDropsVec; - typedef SRainDropsVec::iterator SRainDropsItor; - SRainDropsVec m_pDropsLst; - - Vec3 m_pVelocityProj; - Matrix44 m_pPrevView; - Matrix44 m_pViewProjPrev; - - int m_nAliveDrops; - static const int m_nMaxDropsCount = 100; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CHudSilhouettes - : public CPostEffect -{ -public: - CHudSilhouettes() - { - m_nRenderFlags = 0; - m_nID = ePFX_HUDSilhouettes; - - m_deferredSilhouettesOptimisedTech = "DeferredSilhouettesOptimised"; - m_psParamName = "psParams"; - m_vsParamName = "vsParams"; - - m_bSilhouettesOptimisedTechAvailable = false; - m_pSilhouetesRT = NULL; - - AddParamBool("HudSilhouettes_Active", m_pActive, 0); - AddParamFloatNoTransition("HudSilhouettes_Amount", m_pAmount, 1.0f); //0.0f gives funky blending result ? investigate - AddParamFloatNoTransition("HudSilhouettes_FillStr", m_pFillStr, 0.15f); - AddParamInt("HudSilhouettes_Type", m_pType, 1); - - FindIfSilhouettesOptimisedTechAvailable(); - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "HUDSilhouettes"; - } - -private: - - void RenderDeferredSilhouettes(float fBlendParam, float fType); - void RenderDeferredSilhouettesOptimised(float fBlendParam, float fType); - - void FindIfSilhouettesOptimisedTechAvailable() - { -#ifndef NULL_RENDERER - if (CShaderMan::s_shPostEffectsGame) - { - m_bSilhouettesOptimisedTechAvailable = (CShaderMan::s_shPostEffectsGame->mfFindTechnique(m_deferredSilhouettesOptimisedTech)) ? true : false; - } -#endif - } - - - CCryNameTSCRC m_deferredSilhouettesOptimisedTech; - CCryNameR m_vsParamName; - CCryNameR m_psParamName; - - // float - CEffectParam* m_pAmount, * m_pFillStr, * m_pType; - CTexture* m_pSilhouetesRT; - - bool m_bSilhouettesOptimisedTechAvailable; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CFlashBang - : public CPostEffect -{ -public: - CFlashBang() - { - m_nID = ePFX_eFlashBang; - - AddParamBool("FlashBang_Active", m_pActive, 0); - AddParamFloat("FlashBang_DifractionAmount", m_pDifractionAmount, 1.0f); - AddParamFloat("FlashBang_Time", m_pTime, 2.0f); // flashbang time duration in seconds - AddParamFloat("FlashBang_BlindAmount", m_pBlindAmount, 0.5f); // flashbang blind time (fraction of frashbang time) - - m_pGhostImage = 0; - m_fBlindAmount = 1.0f; - m_fSpawnTime = 0.0f; - } - - virtual ~CFlashBang() - { - Release(); - } - - virtual bool Preprocess(); - virtual void Release(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "FlashBang"; - } - -private: - - SDynTexture* m_pGhostImage; - - float m_fBlindAmount; - float m_fSpawnTime; - - // float, float - CEffectParam* m_pTime, * m_pDifractionAmount, * m_pBlindAmount; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CSceneRain - : public CPostEffect -{ -public: - CSceneRain() - { - m_nRenderFlags = 0; - m_nID = ePFX_SceneRain; - - m_pConeVB = 0; - m_nConeVBSize = 0; - m_updateFrameCount = 0; - m_bReinit = true; - - AddParamBool("SceneRain_Active", m_pActive, 0); - } - - virtual int CreateResources(); - virtual void Release(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual void OnLostDevice(); - - virtual const char* GetName() const; - - // Rain volume parameters (filled during rain layer/occ generation pass) - SRainParams m_RainVolParams; - -private: - bool m_bReinit; - void* m_pConeVB; - uint16 m_nConeVBSize; - uint32 m_updateFrameCount; - void CreateBuffers(uint16 nVerts, void*& pINVB, SVF_P3F_C4B_T2F* pVtxList); -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CSceneSnow - : public CPostEffect -{ -public: - _smart_ptr m_pSnowFlakeMesh; - CSceneSnow() - { - m_nID = ePFX_SceneSnow; - - AddParamBool("SceneSnow_Active", m_pActive, 0); - - m_nAliveClusters = 0; - m_pSnowFlakeMesh = NULL; - } - - virtual ~CSceneSnow() - { - Release(); - } - - bool IsActiveSnow(); - - virtual int CreateResources(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual void Release(); - - virtual const char* GetName() const; - - // Rain volume parameters (filled during rain layer/occ generation pass) - // Needed for occlusion. - SRainParams m_RainVolParams; - SSnowParams m_SnowVolParams; - -private: - - // Snow particle properties - struct SSnowCluster - { - // set default data - SSnowCluster() - : m_pPos(0, 0, 0) - , m_pPosPrev(0, 0, 0) - , m_fSpawnTime(0.0f) - , m_fLifeTime(4.0f) - , m_fLifeTimeVar(2.5f) - , m_fWeight(0.3f) - , m_fWeightVar(0.1f) - { - } - - // World position - Vec3 m_pPos, m_pPosPrev; - // Spawn time - float m_fSpawnTime; - // Life time and variation - float m_fLifeTime, m_fLifeTimeVar; - // Weight and variation - float m_fWeight, m_fWeightVar; - }; - - // Generate particle cluster mesh - bool GenerateClusterMesh(); - // Spawn a cluster - void SpawnCluster(SSnowCluster*& pCluster); - // Update all clusters - void UpdateClusters(); - // Draw clusters - void DrawClusters(); - // Half resolution composite. - void HalfResComposite(); - - // float - CEffectParam* m_pActive; - - typedef std::vector SSnowClusterVec; - typedef SSnowClusterVec::iterator SSnowClusterItor; - SSnowClusterVec m_pClusterList; - - int m_nSnowFlakeVertCount; - - int m_nAliveClusters; - int m_nNumClusters; - int m_nFlakesPerCluster; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CSoftAlphaTest - : public CPostEffect -{ -public: - CSoftAlphaTest() - { - m_nID = ePFX_eSoftAlphaTest; - m_nRenderFlags = 0; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual const char* GetName() const - { - return "SoftAlphaTest"; - } - -private: -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CImageGhosting - : public CPostEffect -{ -public: - CImageGhosting() - { - m_nRenderFlags = 0; - m_nID = ePFX_ImageGhosting; - AddParamFloat("ImageGhosting_Amount", m_pAmount, 0); - m_bInit = true; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual const char* GetName() const - { - return "ImageGhosting"; - } - -private: - - CEffectParam* m_pAmount; - bool m_bInit; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CFilterKillCamera - : public CPostEffect -{ -public: - - CFilterKillCamera() - { - m_nID = ePFX_FilterKillCamera; - - AddParamBool("FilterKillCamera_Active", m_pActive, 0); - AddParamInt("FilterKillCamera_Mode", m_pMode, 0); - AddParamFloat("FilterKillCamera_GrainStrength", m_pGrainStrength, 0.0f); - AddParamVec4("FilterKillCamera_ChromaShift", m_pChromaShift, Vec4(1.0f, 0.5f, 0.1f, 1.0f)); // xyz = offset, w = strength - AddParamVec4("FilterKillCamera_Vignette", m_pVignette, Vec4(1.0f, 1.0f, 0.5f, 1.4f)); // xy = screen scale, z = radius, w = blind noise vignette scale - AddParamVec4("FilterKillCamera_ColorScale", m_pColorScale, Vec4(1.0f, 1.0f, 1.0f, 1.0f)); - AddParamVec4("FilterKillCamera_Blindness", m_pBlindness, Vec4(0.5f, 0.5f, 1.0f, 0.7f)); // x = blind duration, y = blind fade out duration, z = blindness grey scale, w = blind noise min scale - - m_blindTimer = 0.0f; - m_lastMode = 0; - } - - virtual int Initialize(); - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "FilterKillCamera"; - } - -private: - - CCryNameTSCRC m_techName; - CCryNameR m_paramName; - - CEffectParam* m_pGrainStrength; - CEffectParam* m_pChromaShift; - CEffectParam* m_pVignette; - CEffectParam* m_pColorScale; - CEffectParam* m_pBlindness; - CEffectParam* m_pMode; - float m_blindTimer; - int m_lastMode; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CScreenBlood - : public CPostEffect -{ -public: - CScreenBlood() - { - m_nRenderFlags = 0; - m_nID = ePFX_eScreenBlood; - AddParamFloat("ScreenBlood_Amount", m_pAmount, 0.0f); // damage amount - AddParamVec4("ScreenBlood_Border", m_pBorder, Vec4(0.0f, 0.0f, 2.0f, 1.0f)); // Border: x=xOffset y=yOffset z=range w=alpha - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - virtual const char* GetName() const - { - return "ScreenBlood"; - } - -private: - - CEffectParam* m_pAmount; - CEffectParam* m_pBorder; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class ScreenFader - : public CPostEffect -{ -public: - ScreenFader() - { - m_nID = ePFX_ScreenFader; - - AddParamBool("ScreenFader_Enable", m_enable, false); - AddParamFloatNoTransition("ScreenFader_FadeInTime", m_fadeInTime, 0.0f); - AddParamFloatNoTransition("ScreenFader_FadeOutTime", m_fadeOutTime, 0.0f); - AddParamVec4NoTransition("ScreenFader_ScreenCoordinates", m_screenCoordinates, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); - AddParamVec4NoTransition("ScreenFader_FadeColor", m_fadeColor, Vec4(0.0f, 0.0f, 0.0f, 0.0f)); - AddParamTex("ScreenFader_TextureName", m_fadeTextureParam, 0); - } - - ~ScreenFader() - { - // Clean up our ScenePasses - ScreenPassList::iterator passIter = m_screenPasses.begin(); - while ( passIter != m_screenPasses.end() ) - { - ScreenFaderPass* pass = (*passIter); - delete pass; - passIter = m_screenPasses.erase(passIter); - } - } - - bool Preprocess() override; - virtual void Render() override; - virtual void Reset(bool bOnSpecChange = false) override; - - const char* GetName() const override - { - return "ScreenFader"; - } - -private: - - struct ScreenFaderPass - { - ScreenFaderPass() - { - m_currentColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - m_screenCoordinates = Vec4(0.0f, 0.0f, 1.0f, 1.0f); - } - ~ScreenFaderPass() - { - if ( m_fadeTexture ) - { - m_fadeTexture->Release(); - } - } - - IPostEffectGroup* m_group = nullptr; - CTexture* m_fadeTexture = nullptr; - ColorF m_currentColor; - - // Specified as a 0 -> 1 percentage value for screen coordinates. 0,0,1,1 == fullscreen. - Vec4 m_screenCoordinates; - bool m_fadingIn = false; - bool m_fadingOut = false; - float m_currentFadeTime = 0.0f; - float m_fadeInTime = 0.0f; - float m_fadeOutTime = 0.0f; - float m_fadeDuration = 0.0f; // Helper variable that will be set to the duration of fadeInTime or FadeOutTime - float m_fadeDirection = 0.0f; // Multiplier -1 or +1 - }; - - static bool SortFaderPasses(ScreenFaderPass* pass1, ScreenFaderPass* pass2); - - ScreenFader(const ScreenFader& other) = delete; - ScreenFader(ScreenFader&&) = delete; - - // Screen fader passes will render on top of each other, rather than blend between the previous - // screen fader passes that were set in previous PostEffectGroup files. - // This list will be sorted based on the priority of its PostEffectGroup - typedef AZStd::list ScreenPassList; - ScreenPassList m_screenPasses; - - // Unlike other CPostEffect objects, we do NOT want to read the values that are auto-populated into these variables. - // They will input into ::PreProcess with the blended values between the last two PostEffectGroup layers. - // This system requires the individual values from each active group, not the blended values. - // These variables are re-used as teporary variables when reading variables from the groups. - CEffectParam* m_enable = nullptr; - CEffectParam* m_fadeInTime = nullptr; - CEffectParam* m_fadeOutTime = nullptr; - CEffectParam* m_fadeColor = nullptr; - CEffectParam* m_screenCoordinates = nullptr; - CEffectParam* m_fadeTextureParam = nullptr; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -class CPost3DRenderer - : public CPostEffect -{ -public: - - enum ERenderMeshMode - { - eRMM_Default = 0, - eRMM_Custom, - eRMM_DepthOnly - }; - - enum EPost3DRendererFlags - { - eP3DR_HasSilhouettes = (1 << 0), - eP3DR_DirtyFlashRT = (1 << 1), - eP3DR_ClearOnResolveTempRT = (1 << 2), - eP3DR_ClearOnResolveFlashRT = (1 << 3), - eP3DR_ClearOnResolvePrevBackBufferCopyRT = (1 << 4) - }; - - CPost3DRenderer() - { - m_nID = ePFX_Post3DRenderer; - - AddParamBool("Post3DRenderer_Active", m_pActive, 0); - AddParamFloat("Post3DRenderer_FOVScale", m_pFOVScale, 0.5f); - AddParamFloat("Post3DRenderer_SilhouetteStrength", m_pSilhouetteStrength, 0.3f); - AddParamFloat("Post3DRenderer_EdgeFadeScale", m_pEdgeFadeScale, 0.2f); // Between 0 and 1.0 - AddParamFloat("Post3DRenderer_PixelAspectRatio", m_pPixelAspectRatio, 1.0f); - AddParamVec4("Post3DRenderer_Ambient", m_pAmbient, Vec4(0.0f, 0.0f, 0.0f, 0.2f)); - - m_gammaCorrectionTechName = "Post3DRendererGammaCorrection"; - m_alphaCorrectionTechName = "Post3DRendererAlphaCorrection"; - m_texToTexTechName = "TextureToTexture"; - m_customRenderTechName = "CustomRenderPass"; - m_combineSilhouettesTechName = "Post3DRendererSilhouttes"; - m_silhouetteTechName = "BinocularView"; - - m_psParamName = "psParams"; - m_vsParamName = "vsParams"; - - m_nRenderFlags = 0; - - m_pFlashRT = NULL; - m_pTempRT = NULL; - - m_edgeFadeScale = 0.0f; - m_alpha = 1.0f; - m_groupCount = 0; - m_post3DRendererflags = 0; - m_deferDisableFrameCountDown = 0; - } - - virtual bool Preprocess(); - virtual void Render(); - virtual void Reset(bool bOnSpecChange = false); - - virtual const char* GetName() const - { - return "Post3DRenderer"; - } - -private: - - ILINE bool HasModelsToRender() const - { - SRenderListDesc* pRenderListDesc = gRenDev->m_RP.m_pRLD; - const uint32 batchMask = SRendItem::BatchFlags(EFSLIST_GENERAL, pRenderListDesc) - | SRendItem::BatchFlags(EFSLIST_SKIN, pRenderListDesc) - | SRendItem::BatchFlags(EFSLIST_DECAL, pRenderListDesc) - | SRendItem::BatchFlags(EFSLIST_TRANSP, pRenderListDesc); - return (batchMask & FB_POST_3D_RENDER) ? true : false; - } - - void ClearFlashRT(); - - void RenderGroup(uint8 groupId); - void RenderMeshes(uint8 groupId, float screenRect[4], ERenderMeshMode renderMeshMode = eRMM_Default); - void RenderDepth(uint8 groupId, float screenRect[4], bool bCustomRender = false); - void AlphaCorrection(); - void GammaCorrection(float screenRect[4]); - void RenderSilhouettes(uint8 groupId, float screenRect[4]); - void SilhouetteOutlines(CTexture* pOutlineTex, CTexture* pGlowTex); - void SilhouetteGlow(CTexture* pOutlineTex, CTexture* pGlowTex); - void SilhouetteCombineBlurAndOutline(CTexture* pOutlineTex, CTexture* pGlowTex); - void ApplyShaderQuality(EShaderType shaderType = eST_General); - - void ProcessRenderList(int list, uint32 batchFilter, uint8 groupId, float screenRect[4], bool bCustomRender = false); - void ProcessBatchesList(int listStart, int listEnd, uint32 batchFilter, uint8 groupId, float screenRect[4], bool bCustomRender = false); - - CCryNameTSCRC m_gammaCorrectionTechName; - CCryNameTSCRC m_alphaCorrectionTechName; - CCryNameTSCRC m_texToTexTechName; - CCryNameTSCRC m_customRenderTechName; - CCryNameTSCRC m_combineSilhouettesTechName; - CCryNameTSCRC m_silhouetteTechName; - - CCryNameR m_psParamName; - CCryNameR m_vsParamName; - - CEffectParam* m_pFOVScale; - CEffectParam* m_pAmbient; - CEffectParam* m_pSilhouetteStrength; - CEffectParam* m_pEdgeFadeScale; - CEffectParam* m_pPixelAspectRatio; - - CTexture* m_pFlashRT; - CTexture* m_pTempRT; - - float m_alpha; - float m_edgeFadeScale; - - uint8 m_groupCount; - uint8 m_post3DRendererflags; - uint8 m_deferDisableFrameCountDown; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTEFFECTS_H diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.cpp b/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.cpp deleted file mode 100644 index 1d30fa53cf..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.cpp +++ /dev/null @@ -1,673 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "PostEffects.h" -#include - -void CParamBool::SetParam(float fParam, [[maybe_unused]] bool bForceValue) -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - CParamBoolThreadSafeData* pThreadSafeData = &m_threadSafeData[threadID]; - pThreadSafeData->bParam = (fParam) ? true : false; - pThreadSafeData->bSetThisFrame = true; -} - -float CParamBool::GetParam() -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - return static_cast(m_threadSafeData[threadID].bParam); -} - -void CParamBool::SyncMainWithRender() -{ - CParamBoolThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - CParamBoolThreadSafeData* pProcessData = NULL; - if (bIsMultiThreaded) - { - // If value is set on render thread, then this should override main thread value - pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->bSetThisFrame) - { - pFillData->bParam = pProcessData->bParam; - } - } - - // Reset set value - pFillData->bSetThisFrame = false; - - if (bIsMultiThreaded) - { - // Copy fill data into process data - memcpy(pProcessData, pFillData, sizeof(CParamBoolThreadSafeData)); - } -} - -void CParamInt::SetParam(float fParam, [[maybe_unused]] bool bForceValue) -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - CParamIntThreadSafeData* pThreadSafeData = &m_threadSafeData[threadID]; - pThreadSafeData->nParam = static_cast(fParam); - pThreadSafeData->bSetThisFrame = true; -} - -float CParamInt::GetParam() -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - return static_cast(m_threadSafeData[threadID].nParam); -} -void CParamInt::SyncMainWithRender() -{ - CParamIntThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - CParamIntThreadSafeData* pProcessData = NULL; - if (bIsMultiThreaded) - { - // If value is set on render thread, then this should override main thread value - pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->bSetThisFrame) - { - pFillData->nParam = pProcessData->nParam; - } - } - - // Reset set value - pFillData->bSetThisFrame = false; - - if (bIsMultiThreaded) - { - // Copy fill data into process data - memcpy(pProcessData, pFillData, sizeof(CParamIntThreadSafeData)); - } -} - -void CParamFloat::SetParam(float fParam, [[maybe_unused]] bool bForceValue) -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - CParamFloatThreadSafeData* pThreadSafeData = &m_threadSafeData[threadID]; - pThreadSafeData->fParam = fParam; - pThreadSafeData->bSetThisFrame = true; -} - -float CParamFloat::GetParam() -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - return m_threadSafeData[threadID].fParam; -} - -void CParamFloat::SyncMainWithRender() -{ - // The Effect params can be set/get from both threads, accumulate and sync data here - CParamFloatThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - CParamFloatThreadSafeData* pProcessData = NULL; - if (bIsMultiThreaded) - { - // If value is set on render thread, then this should override main thread value - pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->bSetThisFrame) - { - pFillData->fParam = pProcessData->fParam; - } - } - - // Reset set value - pFillData->bSetThisFrame = false; - - if (bIsMultiThreaded) - { - // Copy fill data into process data - memcpy(pProcessData, pFillData, sizeof(CParamFloatThreadSafeData)); - } -} - -void CParamVec4::SetParamVec4(const Vec4& vParam, [[maybe_unused]] bool bForceValue) -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - CParamVec4ThreadSafeData* pThreadSafeData = &m_threadSafeData[threadID]; - pThreadSafeData->vParam = vParam; - pThreadSafeData->bSetThisFrame = true; -} - -Vec4 CParamVec4::GetParamVec4() -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - return m_threadSafeData[threadID].vParam; -} - -void CParamVec4::SyncMainWithRender() -{ - // The Effect params can be set/get from both threads, accumulate and sync data here - CParamVec4ThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - CParamVec4ThreadSafeData* pProcessData = NULL; - if (bIsMultiThreaded) - { - // If value is set on render thread, then this should override main thread value - pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->bSetThisFrame) - { - pFillData->vParam = pProcessData->vParam; - } - } - - // Reset set value - pFillData->bSetThisFrame = false; - - if (bIsMultiThreaded) - { - // Copy fill data into process data - memcpy(pProcessData, pFillData, sizeof(CParamVec4ThreadSafeData)); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#if !defined(_RELEASE) - -static void SetPostEffectParamF(IConsoleCmdArgs* pArgs) -{ - if (pArgs->GetArgCount() < 3) - { - return; - } - - bool bForceValue = false; - if (pArgs->GetArgCount() > 3) - { - const int iForceValue = (int)atoi(pArgs->GetArg(3)); - if (iForceValue != 0) - { - bForceValue = true; - } - } - - const char* szPostEffectParamName = pArgs->GetArg(1); - const float fValue = (float)atof(pArgs->GetArg(2)); - - I3DEngine* pEngine = gEnv->p3DEngine; - pEngine->SetPostEffectParam(szPostEffectParamName, fValue, bForceValue); -} - -static void GetPostEffectParamF(IConsoleCmdArgs* pArgs) -{ - if (pArgs->GetArgCount() < 2) - { - return; - } - - const char* szPostEffectParamName = pArgs->GetArg(1); - - I3DEngine* pEngine = gEnv->p3DEngine; - float fValue = 0.0f; - pEngine->GetPostEffectParam(szPostEffectParamName, fValue); - CryLogAlways("\nPost effect param value: %f", fValue); -} - -#endif // !defined(_RELEASE) - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CPostEffectsMgr::Init() -{ - m_bPostReset = false; - ClearCache(); - - // Initialize the CRC table - // This is the official polynomial used by CRC-32 - // in PKZip, WinZip and Ethernet. - unsigned int ulPolynomial = 0x04c11db7; - - // 256 values representing ASCII character codes. - for (int i = 0; i <= 0xFF; i++) - { - m_nCRC32Table[i] = CRC32Reflect(i, 8) << 24; - for (int j = 0; j < 8; j++) - { - m_nCRC32Table[i] = (m_nCRC32Table[i] << 1) ^ (m_nCRC32Table[i] & (1 << 31) ? ulPolynomial : 0); - } - m_nCRC32Table[i] = CRC32Reflect(m_nCRC32Table[i], 32); - } //i - - // Register default parameters - AddParamFloat("Global_Brightness", m_pBrightness, 1.0f); // brightness - AddParamFloat("Global_Contrast", m_pContrast, 1.0f); // contrast - AddParamFloat("Global_Saturation", m_pSaturation, 1.0f); // saturation - - AddParamFloat("Global_ColorC", m_pColorC, 0.0f); // cyan amount - AddParamFloat("Global_ColorY", m_pColorY, 0.0f); // yellow amount - AddParamFloat("Global_ColorM", m_pColorM, 0.0f); // magenta amount - AddParamFloat("Global_ColorK", m_pColorK, 0.0f); // darkness amount - - AddParamFloat("Global_ColorHue", m_pColorHue, 0.0f); // image hue rotation - - // User parameters - AddParamFloat("Global_User_Brightness", m_pUserBrightness, 1.0f); // brightness - AddParamFloat("Global_User_Contrast", m_pUserContrast, 1.0f); // contrast - AddParamFloat("Global_User_Saturation", m_pUserSaturation, 1.0f); // saturation - - AddParamFloat("Global_User_ColorC", m_pUserColorC, 0.0f); // cyan amount - AddParamFloat("Global_User_ColorY", m_pUserColorY, 0.0f); // yellow amount - AddParamFloat("Global_User_ColorM", m_pUserColorM, 0.0f); // magenta amount - AddParamFloat("Global_User_ColorK", m_pUserColorK, 0.0f); // darkness amount - - AddParamFloat("Global_User_ColorHue", m_pUserColorHue, 0.0f); // image hue rotation - - AddParamFloat("Global_User_HDRBloom", m_UserHDRBloom, 0.f); // bloom amount - - // Register all post processes - AddEffect(CSceneSnow); - AddEffect(CSceneRain); - AddEffect(CSunShafts); - AddEffect(CDepthOfField); - AddEffect(CMotionBlur); - AddEffect(CUnderwaterGodRays); - AddEffect(CVolumetricScattering); - AddEffect(CRainDrops); - AddEffect(CWaterDroplets); - AddEffect(CWaterFlow); - AddEffect(CScreenFrost); - AddEffect(CAlienInterference); - AddEffect(CFlashBang); - AddEffect(CFilterSharpening); - AddEffect(CFilterBlurring); - AddEffect(CColorGrading); - AddEffect(CHudSilhouettes); - AddEffect(CImageGhosting); - AddEffect(CWaterRipples); - AddEffect(CWaterVolume); - AddEffect(CPostAA); - AddEffect(CFilterKillCamera); - AddEffect(CUberGamePostProcess); - AddEffect(CSoftAlphaTest); - AddEffect(CScreenBlood); - AddEffect(CPost3DRenderer); - AddEffect(CGhostVision); - AddEffect(ScreenFader); - - // Sort all post effects by ID - std::sort(m_pEffects.begin(), m_pEffects.end(), SortEffectsByID); - - // Initialize all post process techniques - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectInitialize()); - m_bCreated = false; - - // Initialize parameters - StringEffectMapItor pItor = m_pNameIdMapGen.begin(), pEnd = m_pNameIdMapGen.end(); - for (; pItor != pEnd; ++pItor) - { - m_pNameIdMap.insert(KeyEffectMapItor::value_type(GetCRC(pItor->first.c_str()), pItor->second)); - } - - m_pNameIdMapGen.clear(); - -#if !defined(_RELEASE) - REGISTER_COMMAND("r_setposteffectparamf", SetPostEffectParamF, VF_CHEAT, "Sets post effect param (float)n" - "Usage: r_setposteffectparamf [posteffectparamname, value, forceValue(OPTIONAL)]\n" - "Example: r_setposteffectparamf HUD3D_FOV 35.0 (Doesn't force value)\n" - "Example: r_setposteffectparamf HUD3D_FOV 35.0 1 (Forces value)\n"); - - REGISTER_COMMAND("r_getposteffectparamf", GetPostEffectParamF, VF_CHEAT, "Outputs post effect param value (float) to log" - "Usage: r_setposteffectparamf [posteffectparamname]\n" - "Example: r_getposteffectparamf HUD3D_FOV\n"); -#endif - - // TESTING - static int r_3MonHack; - static float r_3MonHackHUDFOVX; - static float r_3MonHackHUDFOVY; - static float r_3MonHackLeftCGFOffsetX; - static float r_3MonHackRightCGFOffsetX; - REGISTER_CVAR(r_3MonHack, 0, VF_CHEAT | VF_CHEAT_NOCHECK, "Enables 3 monitor hack hud in center"); - REGISTER_CVAR(r_3MonHackHUDFOVX, 28, VF_CHEAT | VF_CHEAT_NOCHECK, "3 monitor hack hud in center - X FOV"); - REGISTER_CVAR(r_3MonHackHUDFOVY, 60, VF_CHEAT | VF_CHEAT_NOCHECK, "3 monitor hack hud in center - Y FOV"); - REGISTER_CVAR(r_3MonHackLeftCGFOffsetX, 0.93f, VF_CHEAT | VF_CHEAT_NOCHECK, "3 monitor hack hud in center - Adds position offset in X direction to all left CGF planes"); - REGISTER_CVAR(r_3MonHackRightCGFOffsetX, -0.93f, VF_CHEAT | VF_CHEAT_NOCHECK, "3 monitor hack hud in center - Adds position offset in X direction to all right CGF planes"); - - - return 1; -} - -void CPostEffectsMgr::CreateResources() -{ - // Initialize all post process techniques - if (!m_bCreated) - { - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectCreateResources()); - } - m_bCreated = true; -} -void CPostEffectsMgr::ReleaseResources() -{ - if (m_bCreated) - { - std::for_each(m_pEffects.begin(), m_pEffects.end(), container_object_safe_release()); - } - -#ifndef _RELEASE - ClearDebugInfo(); -#endif - - m_bCreated = false; -} - -void CPostEffectsMgr::Release() -{ - // Free all resources - ClearCache(); - - std::for_each(m_pNameIdMap.begin(), m_pNameIdMap.end(), SContainerKeyEffectParamDelete()); - m_pNameIdMap.clear(); - - std::for_each(m_pEffects.begin(), m_pEffects.end(), container_object_safe_release()); - std::for_each(m_pEffects.begin(), m_pEffects.end(), container_object_safe_delete()); - m_pEffects.clear(); - - m_bCreated = false; - -#if !defined(_RELEASE) - IConsole* pConsole = gEnv->pConsole; - if (pConsole) - { - pConsole->RemoveCommand("r_setposteffectparamf"); - pConsole->RemoveCommand("r_getposteffectparamf"); - } -#endif -} - -void CPostEffectsMgr::Reset(bool bOnSpecChange) -{ - ClearCache(); - - m_pBrightness->ResetParam(1.0f); - m_pContrast->ResetParam(1.0f); - m_pSaturation->ResetParam(1.0f); - m_pColorC->ResetParam(0.0f); - m_pColorY->ResetParam(0.0f); - m_pColorM->ResetParam(0.0f); - m_pColorK->ResetParam(0.0f); - m_pColorHue->ResetParam(0.0f); - m_pUserBrightness->ResetParam(1.0f); - m_pUserContrast->ResetParam(1.0f); - m_pUserSaturation->ResetParam(1.0f); - m_pUserColorC->ResetParam(0.0f); - m_pUserColorY->ResetParam(0.0f); - m_pUserColorM->ResetParam(0.0f); - m_pUserColorK->ResetParam(0.0f); - m_pUserColorHue->ResetParam(0.0f); - - if (bOnSpecChange) - { - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectResetOnSpecChange()); - } - else - { - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectReset()); - } -} - -int32 CPostEffectsMgr::GetEffectID(const char* pEffectName) -{ - int32 effectID = ePFX_Invalid; - - CPostEffectsMgr* pPostMgr = PostEffectMgr(); - for (CPostEffectItor pItor = pPostMgr->GetEffects().begin(), pItorEnd = pPostMgr->GetEffects().end(); pItor != pItorEnd; ++pItor) - { - CPostEffect* pCurrEffect = (*pItor); - if (strcmp(pEffectName, pCurrEffect->GetName()) == 0) - { - effectID = pCurrEffect->GetID(); - break; - } - } - - return effectID; -} - -void CPostEffectsMgr::OnLostDevice() -{ - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectOnLostDevice()); -} - -void CPostEffectsMgr::OnBeginFrame() -{ - std::for_each(m_pEffects.begin(), m_pEffects.end(), SContainerPostEffectOnBeginFrame()); -} - -void CPostEffectsMgr::SyncMainWithRender() -{ - KeyEffectMapItor iter; - for (iter = m_pNameIdMap.begin(); iter != m_pNameIdMap.end(); iter++) - { - iter->second->SyncMainWithRender(); - } -} - -// Used only when creating the crc table -uint32 CPostEffectsMgr::CRC32Reflect(uint32 ref, char ch) -{ - uint32 value = 0; - - // Swap bit 0 for bit 7 - // bit 1 for bit 6, etc. - for (int i = 1; i < (ch + 1); i++) - { - if (ref & 1) - { - value |= 1 << (ch - i); - } - ref >>= 1; - } - return value; -} - -uint32 CPostEffectsMgr::GetCRC(const char* pszName) -{ - if (!pszName) - { - assert(false && "CPostEffectsMgr::GetCRC() invalid string passed"); - return 0; - } - - // Once the lookup table has been filled in by the constructor, - // this function creates all CRCs using only the lookup table. - // Be sure to use unsigned variables, because negative values introduce high bits where zero bits are required. - - const char* szPtr = pszName; - uint32 ulCRC = 0xffffffff; // Start out with all bits set high. - unsigned char c; - - while (*szPtr) - { - c = *szPtr++; - if (c >= 'a' && c <= 'z') - { - c -= 32; //convert to uppercase - } - ulCRC = (ulCRC >> 8) ^ m_nCRC32Table[(ulCRC & 0xFF) ^ c]; - } - - // Exclusive OR the result with the beginning value...avoids the % operator - return ulCRC ^ 0xffffffff; -} - -CEffectParam* CPostEffectsMgr::GetByName(const char* pszParam) -{ - assert(pszParam || "mfGetByName: null FX name"); - - uint32 nCurrKey = GetCRC(pszParam); - - int nThreadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - - // cache per-thread - ParamCache* pCache = &m_pParamCache[nThreadID]; - - // Check cache first - if (nCurrKey == pCache->m_nKey && pCache->m_pParam) - { - if (CRenderer::CV_r_PostProcess == 3) - { - m_pEffectParamsUpdated.insert(StringEffectMapItor::value_type(pszParam, pCache->m_pParam)); - } - - return pCache->m_pParam; - } - - KeyEffectMapItor pItor = m_pNameIdMap.find(nCurrKey); - - if (pItor != m_pNameIdMap.end()) - { - pCache->m_pParam = pItor->second; - pCache->m_nKey = nCurrKey; - - if (CRenderer::CV_r_PostProcess == 3) - { - m_pEffectParamsUpdated.insert(StringEffectMapItor::value_type(pszParam, pCache->m_pParam)); - } - - return pCache->m_pParam; - } - - return 0; -} - -float CPostEffectsMgr::GetByNameF(const char* pszParam) -{ - CEffectParam* pParam = GetByName(pszParam); - if (pParam) - { - return pParam->GetParam(); - } - - return 0.0f; -} - -Vec4 CPostEffectsMgr::GetByNameVec4(const char* pszParam) -{ - CEffectParam* pParam = GetByName(pszParam); - if (pParam) - { - return pParam->GetParamVec4(); - } - - return Vec4(0, 0, 0, 0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CPostEffectsMgr::SortEffectsByID(const CPostEffect* p1, const CPostEffect* p2) -{ - return (p1->GetID() < p2->GetID()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CParamTexture::Create(const char* pszFileName) -{ - if (!pszFileName || pszFileName[0] == '\0') - { - return 0; - } - - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - CParamTextureThreadSafeData* pThreadSafeData = &m_threadSafeData[threadID]; - - if (pThreadSafeData->pTexParam) - { - // check if texture is same - if (!azstricmp(pThreadSafeData->pTexParam->GetName(), pszFileName)) - { - return 0; - } - // release texture if required - SAFE_RELEASE(pThreadSafeData->pTexParam); - } - - pThreadSafeData->pTexParam = CTexture::ForName(pszFileName, FT_DONT_STREAM, eTF_Unknown); - pThreadSafeData->bSetThisFrame = true; - assert(pThreadSafeData->pTexParam || "CParamTexture.Create: texture not found!"); - - return 1; -} - -const char* CParamTexture::GetParamString() const -{ - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - const CTexture* texture = m_threadSafeData[threadID].pTexParam; - return texture ? texture->GetName() : ""; -} - -void CParamTexture::Release() -{ - CParamTextureThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - if (bIsMultiThreaded) - { - CParamTextureThreadSafeData* pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->pTexParam != pFillData->pTexParam) - { - SAFE_RELEASE(pProcessData->pTexParam); - pProcessData->bSetThisFrame = true; - } - } - - SAFE_RELEASE(pFillData->pTexParam); - pFillData->bSetThisFrame = true; -} - -void CParamTexture::SyncMainWithRender() -{ - CParamTextureThreadSafeData* pFillData = &m_threadSafeData[gRenDev->m_RP.m_nFillThreadID]; - - const bool bIsMultiThreaded = (gRenDev->m_pRT) ? (gRenDev->m_pRT->IsMultithreaded()) : false; - CParamTextureThreadSafeData* pProcessData = NULL; - if (bIsMultiThreaded) - { - // If value is set on render thread, then this should override main thread value - pProcessData = &m_threadSafeData[gRenDev->m_RP.m_nProcessThreadID]; - if (pProcessData->bSetThisFrame) - { - if (pFillData->bSetThisFrame) - { - // If the main thread also set a texture on the same frame (highly unlikely), then release this texture - // 1st before overriding it with the texture set from the render thread - SAFE_RELEASE(pFillData->pTexParam); - } - pFillData->pTexParam = pProcessData->pTexParam; - } - } - - // Reset set value - pFillData->bSetThisFrame = false; - - if (bIsMultiThreaded) - { - // Copy fill data into process data - memcpy(pProcessData, pFillData, sizeof(CParamTextureThreadSafeData)); - } -} - -CPostEffectsMgr* PostEffectMgr() -{ - return gRenDev->m_pPostProcessMgr; -} diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.h b/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.h deleted file mode 100644 index fa973da560..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcess.h +++ /dev/null @@ -1,736 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _POSTPROCESS_H_ -#define _POSTPROCESS_H_ - -class CShader; -class CTexture; - - -// Declare effects ID - this will also be used as rendering sort order -enum EPostEffectID -{ - ePFX_Invalid = -1, - ePFX_WaterVolume = 0, - ePFX_WaterRipples, - - ePFX_SceneRain, - - // Don't change order of post processes before sunshafts (on pc we doing some trickery to avoid redundant stretchrects) - ePFX_SunShafts, - ePFX_eMotionBlur, - ePFX_ColorGrading, - ePFX_eDepthOfField, - ePFX_HUDSilhouettes, - - ePFX_eSoftAlphaTest, - - ePFX_PostAA, - ePFX_SceneSnow, - - ePFX_eUnderwaterGodRays, - ePFX_eVolumetricScattering, - - // todo: merge all following into UberGamePostProcess - ePFX_FilterSharpening, - ePFX_FilterBlurring, - ePFX_UberGamePostProcess, - - ePFX_eFlashBang, - - ePFX_ImageGhosting, - - ePFX_eRainDrops, - ePFX_eWaterDroplets, - ePFX_eWaterFlow, - ePFX_eScreenBlood, - ePFX_eScreenFrost, - - ePFX_FilterKillCamera, - ePFX_eAlienInterference, - ePFX_eGhostVision, - - ePFX_Post3DRenderer, - - ePFX_ScreenFader, - - ePFX_Max -}; - -// Base effect parameter class, derive all new from this one -class CEffectParam -{ -public: - - CEffectParam(){ } - - virtual ~CEffectParam() - { - Release(); - } - - // Should implement where necessary. For example check CParamTexture - virtual void Release() { } - - // Set parameters - virtual void SetParam([[maybe_unused]] float fParam, [[maybe_unused]] bool bForceValue = false) {} - virtual void SetParamVec4([[maybe_unused]] const Vec4& pParam, [[maybe_unused]] bool bForceValue = false) {} - virtual void SetParamString([[maybe_unused]] const char* pszParam) {} - virtual void ResetParam(float fParam) { SetParam(fParam, true); } - virtual void ResetParamVec4(const Vec4& pParam) { SetParamVec4(pParam, true); } - - // Get parameters - virtual float GetParam() { return 1.0f; } - virtual Vec4 GetParamVec4() { return Vec4(1.0f, 1.0f, 1.0f, 1.0f); } - virtual const char* GetParamString() const { return 0; } - - // Sync main thread data with render thread data - virtual void SyncMainWithRender() {} - - // Create effect parameter - template - static CEffectParam* Create(const T& pParam, bool bSmoothTransition = true) - { - return new ParamT(pParam, bSmoothTransition); - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Bool type effect param -class CParamBool - : public CEffectParam -{ -public: - CParamBool(bool bParam, [[maybe_unused]] bool bSmoothTransition) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - CParamBoolThreadSafeData* pThreadSafeData = &m_threadSafeData[i]; - pThreadSafeData->bParam = bParam; - pThreadSafeData->bSetThisFrame = false; - } - } - - virtual void SetParam(float fParam, bool bForceValue); - virtual float GetParam(); - virtual void SyncMainWithRender(); - -private: - - struct CParamBoolThreadSafeData - { - bool bParam; - bool bSetThisFrame; - }; - - CParamBoolThreadSafeData m_threadSafeData[RT_COMMAND_BUF_COUNT]; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Int type effect param -class CParamInt - : public CEffectParam -{ -public: - CParamInt(int nParam, [[maybe_unused]] bool bSmoothTransition) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - CParamIntThreadSafeData* pThreadSafeData = &m_threadSafeData[i]; - pThreadSafeData->nParam = nParam; - pThreadSafeData->bSetThisFrame = false; - } - } - - virtual void SetParam(float fParam, bool bForceValue); - virtual float GetParam(); - virtual void SyncMainWithRender(); - -private: - - struct CParamIntThreadSafeData - { - int nParam; - bool bSetThisFrame; - }; - - CParamIntThreadSafeData m_threadSafeData[RT_COMMAND_BUF_COUNT]; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Float type effect param -class CParamFloat - : public CEffectParam -{ -public: - CParamFloat(float fParam, bool bSmoothTransition) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - CParamFloatThreadSafeData* pThreadSafeData = &m_threadSafeData[i]; - pThreadSafeData->fParam = fParam; - pThreadSafeData->fFrameParamAcc = fParam; - pThreadSafeData->nFrameSetCount = 0; - pThreadSafeData->bValueForced = false; - } - m_fParamDefault = fParam; - m_bSmoothTransition = bSmoothTransition; - } - - virtual void SetParam(float fParam, bool bForceValue); - virtual float GetParam(); - virtual void SyncMainWithRender(); - -private: - - struct CParamFloatThreadSafeData - { - float fParam; - float fFrameParamAcc; - uint8 nFrameSetCount; - bool bValueForced; - bool bSetThisFrame; - }; - - CParamFloatThreadSafeData m_threadSafeData[RT_COMMAND_BUF_COUNT]; - - float m_fParamDefault; - bool m_bSmoothTransition; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Vec4 type effect param -class CParamVec4 - : public CEffectParam -{ -public: - CParamVec4(const Vec4& vParam, bool bSmoothTransition) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - CParamVec4ThreadSafeData* pThreadSafeData = &m_threadSafeData[i]; - pThreadSafeData->vParam = vParam; - pThreadSafeData->vFrameParamAcc = vParam; - pThreadSafeData->nFrameSetCount = 0; - pThreadSafeData->bValueForced = false; - } - m_vParamDefault = vParam; - m_bSmoothTransition = bSmoothTransition; - } - - virtual void SetParamVec4(const Vec4& vParam, bool bForceValue); - virtual Vec4 GetParamVec4(); - virtual void SyncMainWithRender(); - -private: - - struct CParamVec4ThreadSafeData - { - Vec4 vParam; - Vec4 vFrameParamAcc; - uint8 nFrameSetCount; - bool bValueForced; - bool bSetThisFrame; - }; - - CParamVec4ThreadSafeData m_threadSafeData[RT_COMMAND_BUF_COUNT]; - - Vec4 m_vParamDefault; - bool m_bSmoothTransition; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// CTexture type effect param -class CParamTexture - : public CEffectParam -{ -public: - CParamTexture() - { - Reset(); - } - - CParamTexture([[maybe_unused]] int nInit, [[maybe_unused]] bool bSmoothTransition) - { - Reset(); - } - - virtual ~CParamTexture() - { - Release(); - } - - int Create(const char* pszFileName); - - virtual void Release(); - - virtual void SetParamString(const char* pParam) - { - Create(pParam); - } - - virtual const char* GetParamString() const; - - CTexture* GetParamTexture() const - { - const int threadID = gRenDev->m_pRT ? gRenDev->m_pRT->GetThreadList() : 0; - return m_threadSafeData[threadID].pTexParam; - } - - virtual void SyncMainWithRender(); - -private: - - void Reset() - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - CParamTextureThreadSafeData* pThreadSafeData = &m_threadSafeData[i]; - pThreadSafeData->pTexParam = NULL; - pThreadSafeData->bSetThisFrame = false; - } - } - - struct CParamTextureThreadSafeData - { - CTexture* pTexParam; - bool bSetThisFrame; - }; - - CParamTextureThreadSafeData m_threadSafeData[RT_COMMAND_BUF_COUNT]; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Post processing render flags -enum EPostProcessRenderFlag -{ - PSP_UPDATE_BACKBUFFER = (1 << 0), // updates back-buffer texture for technique - PSP_REQUIRES_UPDATE = (1 << 1), // required calling update member function - PSP_LAST_ENABLED_POSTPROCESS = (1 << 2), // last enabled post process (used to determine if rendering directly to backbuffer required) - PSP_UPDATE_SCENE_SPECULAR = (1 << 3) // updates/overwrites the scene specular texture (s_ptexSceneSpecular) for use in the current effect -}; - -// Post effects base structure interface. All techniques derive from this one. -class CPostEffect -{ -public: - CPostEffect() - : m_pActive(0) - , /*m_nID(ePFX_DefaultID),*/ m_nRenderFlags(PSP_UPDATE_BACKBUFFER) - { - } - - virtual ~CPostEffect() - { - Release(); - } - - // Initialize post processing technique - device access allowed (queries, ...) - virtual int Initialize() { return 1; } - // Create all the resources for the pp effects which don't require the device (such as textures) - virtual int CreateResources() { return 1; } - // Free resources used - virtual void Release() { } - // Preprocess technique - virtual bool Preprocess() { return IsActive(); } - // Some effects might require updating data/parameters, etc - virtual void Update() { }; - // Render technique - virtual void Render() = 0; - // Reset technique state to default - virtual void Reset(bool bOnSpecChange = false) = 0; - // release resources when required - virtual void OnLostDevice() { } - - // Add render element/object to post process (use for custom geometry) - virtual void AddRE([[maybe_unused]] const CRendElementBase* pRE, [[maybe_unused]] const SShaderItem* pShaderItem, [[maybe_unused]] CRenderObject* pObj, [[maybe_unused]] const SRenderingPassInfo& passInfo) { } - // release resources when required - virtual void OnBeginFrame() { } - - // Get technique render flags - int GetRenderFlags() const - { - return m_nRenderFlags; - } - - // Get effect name - virtual const char* GetName() const - { - return "PostEffectDefault"; - } - - // Is technique active ? - virtual bool IsActive() const - { - float fActive = m_pActive->GetParam(); - return (fActive) ? 1 : 0; - } - - inline uint8 GetID() const - { - return m_nID; - } - - -protected: - uint8 m_nRenderFlags; - uint8 m_nID; - CEffectParam* m_pActive; -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -typedef std::map StringEffectMap; -typedef StringEffectMap::iterator StringEffectMapItor; - -typedef std::map KeyEffectMap; -typedef KeyEffectMap::iterator KeyEffectMapItor; - -typedef std::vector< CPostEffect* > CPostEffectVec; -typedef CPostEffectVec::iterator CPostEffectItor; - -# ifndef _RELEASE -#define POSTSEFFECTS_DEBUGINFO_TIMEOUT (1.0f) -struct SPostEffectsDebugInfo -{ - SPostEffectsDebugInfo(CPostEffect* _pEffect) - : pEffect(_pEffect) - , szParamName(NULL) - , fParamVal(0.0f) - , fTimeOut(POSTSEFFECTS_DEBUGINFO_TIMEOUT){} - SPostEffectsDebugInfo(const string& _szParamName, float val) - : pEffect(NULL) - , szParamName(_szParamName) - , fParamVal(val) - , fTimeOut(POSTSEFFECTS_DEBUGINFO_TIMEOUT){} - CPostEffect* pEffect; - string szParamName; - float fParamVal; - float fTimeOut; -}; -typedef std::vector< SPostEffectsDebugInfo > CPostEffectDebugVec; -#endif - - -class CPostEffectsMgr; -CPostEffectsMgr* PostEffectMgr(); - -// Post process effects manager -class CPostEffectsMgr -{ -public: - CPostEffectsMgr() - : m_nPostBlendEffectsFlags(0) - { - ClearCache(); -#ifndef _RELEASE - m_activeEffectsDebug.reserve(16); - m_activeParamsDebug.reserve(32); -#endif - m_bCreated = false; - } - - virtual ~CPostEffectsMgr() - { - Release(); - } - - // Create/Initialize post processing effects - int Init(); - void CreateResources(); - // Free resources used - void Release(); - void ReleaseResources(); - // Reset all post effects - void Reset(bool bOnSpecChange = false); - // Start processing effects - void Begin(); - // End processing effects - void End(); - // release resources when required - void OnLostDevice(); - // release resources when required - void OnBeginFrame(); - // Sync main thread post effect data with render thread post effect data - void SyncMainWithRender(); - - // Get techniques list - CPostEffectVec& GetEffects() - { - return m_pEffects; - } - inline bool IsCreated() - { - return m_pEffects.size() != 0; - } - - // Get post effect - CPostEffect* GetEffect(EPostEffectID nID) - { - assert(nID < ePFX_Max); - return m_pEffects[ nID ]; - } - - // Get post effect ID - int32 GetEffectID(const char* pEffectName); - - // Get name to id map - KeyEffectMap& GetNameIdMap() - { - return m_pNameIdMap; - } - - // Given a string returns corresponding SEffectParam if exists, else returns null - CEffectParam* GetByName(const char* pszParam); - - // Given a string returns containing value if exists, else returns 0 - float GetByNameF(const char* pszParam); - Vec4 GetByNameVec4(const char* pszParam); - - // Register effect - void RegisterEffect(CPostEffect* pEffect) - { - assert(pEffect); - m_pEffects.push_back(pEffect); - } - - // Register a parameter - template - void RegisterParam(const char* pszName, CEffectParam*& pParam, const T& pParamVal, bool bSmoothTransition = true) - { - pParam = CEffectParam::Create< paramT >(pParamVal, bSmoothTransition); - m_pNameIdMapGen.insert(StringEffectMapItor::value_type(pszName, pParam)); - } - - // Current enabled post blending effects - uint8 GetPostBlendEffectsFlags() - { - return m_nPostBlendEffectsFlags; - } - - // Enabled/disable post blending effects - void SetPostBlendEffectsFlags(uint8 nFlags) - { - m_nPostBlendEffectsFlags = nFlags; - } - - friend CPostEffectsMgr* PostEffectMgr(); - - static bool CheckPostProcessQuality(ERenderQuality nMinRQ, EShaderQuality nMinSQ) - { - if (gRenDev->m_RP.m_eQuality >= nMinRQ && gRenDev->EF_GetShaderQuality(eST_PostProcess) >= nMinSQ) - { - return true; - } - - return false; - } - - StringEffectMap* GetDebugParamsUsedInFrame() - { - return &m_pEffectParamsUpdated; - } - -#ifndef _RELEASE - CPostEffectDebugVec& GetActiveEffectsDebug() { return m_activeEffectsDebug; } - CPostEffectDebugVec& GetActiveEffectsParamsDebug() { return m_activeParamsDebug; } - void ClearDebugInfo() - { - m_activeEffectsDebug.clear(); - m_activeParamsDebug.clear(); - } -#endif - - static int SortEffectsByID(const CPostEffect* p1, const CPostEffect* p2); - - // Get techniques list - CPostEffectVec& GetActiveEffects(int threadID) - { - return m_activeEffects[threadID]; - } - -private: - - // Pass a text string to this function and it will return the CRC - uint32 GetCRC(const char* pszName); - // Used only when creating the crc table - uint32 CRC32Reflect(uint32 ref, char ch); - // zero out the cache - void ClearCache() - { -#ifndef _RELEASE - ClearDebugInfo(); -#endif - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_pParamCache[i].m_nKey = 0; - m_pParamCache[i].m_pParam = 0; - } - } - -protected: - - bool m_bPostReset; - bool m_bCreated; - uint8 m_nPostBlendEffectsFlags; - - // Shared parameters - CEffectParam* m_pBrightness, * m_pContrast, * m_pSaturation, * m_pSharpening; - CEffectParam* m_pColorC, * m_pColorY, * m_pColorM, * m_pColorK, * m_pColorHue; - - CEffectParam* m_pUserBrightness, * m_pUserContrast, * m_pUserSaturation, * m_pUserSharpening; - CEffectParam* m_pUserColorC, * m_pUserColorY, * m_pUserColorM, * m_pUserColorK, * m_pUserColorHue; - - // sorry: quick & dirty solution for c2 shipping - custom type handling for HDR setup in cinematics - make this properly after shipping - CEffectParam* m_UserHDRBloom; - - CPostEffectVec m_pEffects; - CPostEffectVec m_activeEffects[RT_COMMAND_BUF_COUNT]; - KeyEffectMap m_pNameIdMap; - StringEffectMap m_pNameIdMapGen; - // for debugging purposes only - StringEffectMap m_pEffectParamsUpdated; -#ifndef _RELEASE - CPostEffectDebugVec m_activeEffectsDebug; - CPostEffectDebugVec m_activeParamsDebug; -#endif - - uint32 m_nCRC32Table[256]; // Lookup table array - - struct ParamCache - { - uint32 m_nKey; - CEffectParam* m_pParam; - } m_pParamCache[RT_COMMAND_BUF_COUNT]; -}; - -////////////////////////////////////////////////////////////////////////////////////////////////// -// Some nice utilities for handling post effects containers -////////////////////////////////////////////////////////////////////////////////////////////////// - -#define AddEffect(ef) PostEffectMgr()->RegisterEffect(CryAlignedNew()) -#define AddParamBool(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val) -#define AddParamInt(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val) -#define AddParamFloat(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val) -#define AddParamVec4(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val) -#define AddParamFloatNoTransition(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val, false) -#define AddParamVec4NoTransition(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val, false) -#define AddParamTex(szName, pParam, val) PostEffectMgr()->RegisterParam((szName), (pParam), val) - -struct container_object_safe_delete -{ - template - void operator()(T* pObj) const - { - CryAlignedDelete(pObj); - } -}; - -struct container_object_safe_release -{ - template - void operator()(T* pObj) const - { - SAFE_RELEASE(pObj); - } -}; - -struct SContainerKeyEffectParamDelete -{ - void operator()(KeyEffectMap::value_type& pObj) - { - SAFE_DELETE(pObj.second); - } -}; - -struct SContainerPostEffectInitialize -{ - void operator() (CPostEffect* pObj) const - { - if (pObj) - { - pObj->Initialize(); - } - } -}; - -struct SContainerPostEffectCreateResources -{ - void operator() (CPostEffect* pObj) const - { - if (pObj) - { - pObj->CreateResources(); - } - } -}; - -struct SContainerPostEffectReset -{ - void operator()(CPostEffect* pObj) const - { - if (pObj) - { - pObj->Reset(); - } - } -}; - -struct SContainerPostEffectResetOnSpecChange -{ - void operator()(CPostEffect* pObj) const - { - if (pObj) - { - pObj->Reset(true); - } - } -}; - -struct SContainerPostEffectOnLostDevice -{ - void operator() (CPostEffect* pObj) const - { - if (pObj) - { - pObj->OnLostDevice(); - } - } -}; - -struct SContainerPostEffectOnBeginFrame -{ - void operator() (CPostEffect* pObj) const - { - if (pObj) - { - pObj->OnBeginFrame(); - } - } -}; - -#endif diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.cpp b/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.cpp deleted file mode 100644 index ea6ee680ed..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.cpp +++ /dev/null @@ -1,688 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Post processing common utilities - - -#include "RenderDll_precompiled.h" -#include "PostProcessUtils.h" -#include "../RendElements/FlareSoftOcclusionQuery.h" - -RECT SPostEffectsUtils::m_pScreenRect; -ITimer* SPostEffectsUtils::m_pTimer; -int SPostEffectsUtils::m_iFrameCounter = 0; -SDepthTexture* SPostEffectsUtils::m_pCurDepthSurface; -CShader* SPostEffectsUtils::m_pCurrShader; -int SPostEffectsUtils::m_nColorMatrixFrameID; -float SPostEffectsUtils::m_fWaterLevel; -float SPostEffectsUtils::m_fOverscanBorderAspectRatio = 1.0f; -Matrix44 SPostEffectsUtils::m_pScaleBias = Matrix44( - 0.5f, 0, 0, 0, - 0, -0.5f, 0, 0, - 0, 0, 1.0f, 0, - 0.5f, 0.5f, 0, 1.0f); - -Vec3 SPostEffectsUtils::m_vRT = Vec3(0, 0, 0); -Vec3 SPostEffectsUtils::m_vLT = Vec3(0, 0, 0); -Vec3 SPostEffectsUtils::m_vLB = Vec3(0, 0, 0); -Vec3 SPostEffectsUtils::m_vRB = Vec3(0, 0, 0); -int SPostEffectsUtils::m_nFrustrumFrameID = 0; - -CTexture* SPostEffectsUtils::m_UpscaleTarget = nullptr; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool SPostEffectsUtils::Create() -{ - assert(gRenDev); - - const SViewport& MainVp = gRenDev->m_MainViewport; - const bool bCreatePostAA = CRenderer::CV_r_AntialiasingMode && !CTexture::IsTextureExist(CTexture::s_ptexPrevBackBuffer[0][0]); - //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - const bool bCreateCaustics = (CRenderer::CV_r_watervolumecaustics && CRenderer::CV_r_watercaustics) && !CTexture::IsTextureExist(CTexture::s_ptexWaterCaustics[0]); - - static ICVar* DolbyCvar = gEnv->pConsole->GetCVar("r_HDRDolby"); - - ETEX_Format nHDRReducedFormat = gRenDev->UseHalfFloatRenderTargets() ? eTF_R11G11B10F : eTF_R10G10B10A2; - - ETEX_Format taaFormat = eTF_R8G8B8A8; - if (CRenderer::CV_r_AntialiasingMode == eAT_TAA) - { - taaFormat = eTF_R16G16B16A16F; - } - - bool taaFormatMismatch = (CRenderer::CV_r_AntialiasingMode && CTexture::s_ptexPrevBackBuffer[0][0] && CTexture::s_ptexPrevBackBuffer[0][0]->GetDstFormat() != taaFormat); - - if (!CTexture::s_ptexBackBufferScaled[0] || taaFormatMismatch || m_pScreenRect.right != MainVp.nWidth || m_pScreenRect.bottom != MainVp.nHeight || bCreatePostAA || bCreateCaustics) - { - assert(gRenDev); - - const int nWidth = gRenDev->GetWidth(); - const int nHeight = gRenDev->GetHeight(); - - // Update viewport info - m_pScreenRect.left = 0; - m_pScreenRect.top = 0; - - m_pScreenRect.right = nWidth; - m_pScreenRect.bottom = nHeight; - - if (CRenderer::CV_r_AntialiasingMode) - { - CreateRenderTarget("$PrevBackBuffer0", CTexture::s_ptexPrevBackBuffer[0][0], nWidth, nHeight, Clr_Unknown, 1, 0, taaFormat, TO_PREVBACKBUFFERMAP0, FT_DONT_RELEASE | FT_USAGE_ALLOWREADSRGB); - CreateRenderTarget("$PrevBackBuffer1", CTexture::s_ptexPrevBackBuffer[1][0], nWidth, nHeight, Clr_Unknown, 1, 0, taaFormat, TO_PREVBACKBUFFERMAP1, FT_DONT_RELEASE | FT_USAGE_ALLOWREADSRGB); - if (gRenDev->m_bDualStereoSupport) - { - CreateRenderTarget("$PrevBackBuffer0_R", CTexture::s_ptexPrevBackBuffer[0][1], nWidth, nHeight, Clr_Unknown, 1, 0, taaFormat, -1, FT_DONT_RELEASE | FT_USAGE_ALLOWREADSRGB); - CreateRenderTarget("$PrevBackBuffer1_R", CTexture::s_ptexPrevBackBuffer[1][1], nWidth, nHeight, Clr_Unknown, 1, 0, taaFormat, -1, FT_DONT_RELEASE | FT_USAGE_ALLOWREADSRGB); - } - } - else - { - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[0][0]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[1][0]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[0][1]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[1][1]); - } - - CreateRenderTarget("$Cached3DHud", CTexture::s_ptexCached3DHud, nWidth, nHeight, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - CreateRenderTarget("$Cached3DHudDownsampled", CTexture::s_ptexCached3DHudScaled, nWidth >> 2, nHeight >> 2, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - // Scaled versions of the scene target - CreateRenderTarget("$BackBufferScaled_d2", CTexture::s_ptexBackBufferScaled[0], nWidth >> 1, nHeight >> 1, Clr_Unknown, 1, 0, eTF_R8G8B8A8, TO_BACKBUFFERSCALED_D2, FT_DONT_RELEASE); - - // Ghosting requires data overframes, need to handle for each GPU in MGPU mode - CreateRenderTarget("$PrevFrameScaled", CTexture::s_ptexPrevFrameScaled, nWidth >> 1, nHeight >> 1, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - CreateRenderTarget("$BackBufferScaledTemp_d2", CTexture::s_ptexBackBufferScaledTemp[0], nWidth >> 1, nHeight >> 1, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - CreateRenderTarget("$WaterVolumeRefl", CTexture::s_ptexWaterVolumeRefl[0], nWidth >> 1, nHeight >> 1, Clr_Unknown, 1, true, nHDRReducedFormat, TO_WATERVOLUMEREFLMAP, FT_DONT_RELEASE); - CreateRenderTarget("$WaterVolumeReflPrev", CTexture::s_ptexWaterVolumeRefl[1], nWidth >> 1, nHeight >> 1, Clr_Unknown, 1, true, nHDRReducedFormat, TO_WATERVOLUMEREFLMAPPREV, FT_DONT_RELEASE); - - CreateRenderTarget("$BackBufferScaled_d4", CTexture::s_ptexBackBufferScaled[1], nWidth >> 2, nHeight >> 2, Clr_Unknown, 1, 0, eTF_R8G8B8A8, TO_BACKBUFFERSCALED_D4, FT_DONT_RELEASE); - CreateRenderTarget("$BackBufferScaledTemp_d4", CTexture::s_ptexBackBufferScaledTemp[1], nWidth >> 2, nHeight >> 2, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - CreateRenderTarget("$BackBufferScaled_d8", CTexture::s_ptexBackBufferScaled[2], nWidth >> 3, nHeight >> 3, Clr_Unknown, 1, 0, eTF_R8G8B8A8, TO_BACKBUFFERSCALED_D8, FT_DONT_RELEASE); - - CreateRenderTarget("$RainDropsAccumRT_0", CTexture::s_ptexRainDropsRT[0], nWidth >> 2, nHeight >> 2, Clr_Unknown, 1, false, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - CreateRenderTarget("$RainDropsAccumRT_1", CTexture::s_ptexRainDropsRT[1], nWidth >> 2, nHeight >> 2, Clr_Unknown, 1, false, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - CreateRenderTarget("$RainSSOcclusion0", CTexture::s_ptexRainSSOcclusion[0], nWidth >> 3, nHeight >> 3, Clr_Unknown, 1, false, eTF_R8G8B8A8); - CreateRenderTarget("$RainSSOcclusion1", CTexture::s_ptexRainSSOcclusion[1], nWidth >> 3, nHeight >> 3, Clr_Unknown, 1, false, eTF_R8G8B8A8); - - CreateRenderTarget("$RainOcclusion", CTexture::s_ptexRainOcclusion, RAIN_OCC_MAP_SIZE, RAIN_OCC_MAP_SIZE, Clr_Unknown, false, false, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - - // Water phys simulation requires data overframes, need to handle for each GPU in MGPU mode - CreateRenderTarget("$WaterRipplesDDN_0", CTexture::s_ptexWaterRipplesDDN, 256, 256, Clr_Unknown, 1, true, eTF_R8G8B8A8, TO_WATERRIPPLESMAP); - if (gRenDev->UseHalfFloatRenderTargets()) - { - CreateRenderTarget("$WaterVolumeDDN", CTexture::s_ptexWaterVolumeDDN, 64, 64, Clr_Unknown, 1, true, eTF_R16G16B16A16F, TO_WATERVOLUMEMAP); - } - else - { - CreateRenderTarget("$WaterVolumeDDN", CTexture::s_ptexWaterVolumeDDN, 64, 64, Clr_Unknown, 1, true, eTF_R8G8B8A8, TO_WATERVOLUMEMAP); - } - - if (CRenderer::CV_r_watervolumecaustics && CRenderer::CV_r_watercaustics) //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - { - const int nCausticRes = clamp_tpl(CRenderer::CV_r_watervolumecausticsresolution, 256, 4096); - CreateRenderTarget("$WaterVolumeCaustics", CTexture::s_ptexWaterCaustics[0], nCausticRes, nCausticRes, Clr_Unknown, 1, false, eTF_R8G8B8A8, TO_WATERVOLUMECAUSTICSMAP); - CreateRenderTarget("$WaterVolumeCausticsTemp", CTexture::s_ptexWaterCaustics[1], nCausticRes, nCausticRes, Clr_Unknown, 1, false, eTF_R8G8B8A8, TO_WATERVOLUMECAUSTICSMAPTEMP); - } - else - { - SAFE_RELEASE(CTexture::s_ptexWaterCaustics[0]); - SAFE_RELEASE(CTexture::s_ptexWaterCaustics[1]); - } - - #if defined(VOLUMETRIC_FOG_SHADOWS) - int fogShadowBufDiv = (CRenderer::CV_r_FogShadows == 2) ? 4 : 2; - CreateRenderTarget("$VolFogShadowBuf0", CTexture::s_ptexVolFogShadowBuf[0], nWidth / fogShadowBufDiv, nHeight / fogShadowBufDiv, Clr_Unknown, 1, 0, eTF_R8G8B8A8, TO_VOLFOGSHADOW_BUF); - CreateRenderTarget("$VolFogShadowBuf1", CTexture::s_ptexVolFogShadowBuf[1], nWidth / fogShadowBufDiv, nHeight / fogShadowBufDiv, Clr_Unknown, 1, 0, eTF_R8G8B8A8); - #endif - - char str[256]; - - // TODO: Only create necessary RTs for minimal ring? - for (int i = 0; i < MAX_OCCLUSION_READBACK_TEXTURES; i++) - { - azsprintf(str, "$FlaresOcclusion_%d", i); - - CreateRenderTarget(str, CTexture::s_ptexFlaresOcclusionRing[i], CFlareSoftOcclusionQuery::s_nIDColMax, CFlareSoftOcclusionQuery::s_nIDRowMax, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE | FT_STAGE_READBACK); - } - - CreateRenderTarget("$FlaresGather", CTexture::s_ptexFlaresGather, CFlareSoftOcclusionQuery::s_nGatherTextureWidth, CFlareSoftOcclusionQuery::s_nGatherTextureHeight, Clr_Unknown, 1, 0, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - } - - return 1; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::Release() -{ - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[0][0]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[1][0]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[0][1]); - SAFE_RELEASE(CTexture::s_ptexPrevBackBuffer[1][1]); - - SAFE_RELEASE(CTexture::s_ptexBackBufferScaled[0]); - SAFE_RELEASE(CTexture::s_ptexBackBufferScaled[1]); - SAFE_RELEASE(CTexture::s_ptexBackBufferScaled[2]); - - SAFE_RELEASE(CTexture::s_ptexBackBufferScaledTemp[0]); - SAFE_RELEASE(CTexture::s_ptexBackBufferScaledTemp[1]); - - SAFE_RELEASE(CTexture::s_ptexWaterVolumeDDN); - SAFE_RELEASE(CTexture::s_ptexWaterVolumeRefl[0]); - SAFE_RELEASE(CTexture::s_ptexWaterVolumeRefl[1]); - SAFE_RELEASE(CTexture::s_ptexWaterCaustics[0]); - SAFE_RELEASE(CTexture::s_ptexWaterCaustics[1]); - - SAFE_RELEASE(CTexture::s_ptexCached3DHud); - SAFE_RELEASE(CTexture::s_ptexCached3DHudScaled); - - SAFE_RELEASE(CTexture::s_ptexPrevFrameScaled); - SAFE_RELEASE(CTexture::s_ptexWaterRipplesDDN); - - SAFE_RELEASE(CTexture::s_ptexRainDropsRT[0]); - SAFE_RELEASE(CTexture::s_ptexRainDropsRT[1]); - - SAFE_RELEASE(CTexture::s_ptexRainSSOcclusion[0]); - SAFE_RELEASE(CTexture::s_ptexRainSSOcclusion[1]); - SAFE_RELEASE(CTexture::s_ptexRainOcclusion); - -#if defined(VOLUMETRIC_FOG_SHADOWS) - SAFE_RELEASE(CTexture::s_ptexVolFogShadowBuf[0]); - SAFE_RELEASE(CTexture::s_ptexVolFogShadowBuf[1]); -#endif - - for (int i = 0; i < MAX_OCCLUSION_READBACK_TEXTURES; i++) - { - SAFE_RELEASE(CTexture::s_ptexFlaresOcclusionRing[i]); - } - SAFE_RELEASE(CTexture::s_ptexFlaresGather); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::GetFullScreenTri(SVF_P3F_C4B_T2F pResult[3], int nTexWidth, int nTexHeight, float z, const RECT * pSrcRegion) -{ - if (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - z = 1.0f - z; - - pResult[0].xyz = Vec3(-0.0f, -0.0f, z); - pResult[0].color.dcolor = ~0U; - pResult[0].st = Vec2(0, 0); - pResult[1].xyz = Vec3(-0.0f, 2.0f, z); - pResult[1].color.dcolor = ~0U; - pResult[1].st = Vec2(0, 2); - pResult[2].xyz = Vec3(2.0f, -0.0f, z); - pResult[2].color.dcolor = ~0U; - pResult[2].st = Vec2(2, 0); - - if (pSrcRegion) - { - const Vec4 vTexCoordsRegion(2.0f*float(pSrcRegion->left) / nTexWidth, - 2.0f*float(pSrcRegion->right) / nTexWidth, - 2.0f*float(pSrcRegion->top) / nTexHeight, - 2.0f*float(pSrcRegion->bottom) / nTexHeight); - pResult[0].st = Vec2(vTexCoordsRegion.x, vTexCoordsRegion.z); - pResult[1].st = Vec2(vTexCoordsRegion.x, vTexCoordsRegion.w); - pResult[2].st = Vec2(vTexCoordsRegion.y, vTexCoordsRegion.z); - } -} - -void SPostEffectsUtils::DrawFullScreenTri(int nTexWidth, int nTexHeight, float z, const RECT * pSrcRegion) -{ - SVF_P3F_C4B_T2F screenTri[3]; - GetFullScreenTri(screenTri, nTexWidth, nTexHeight, z, pSrcRegion); - - CVertexBuffer strip(screenTri, eVF_P3F_C4B_T2F); - gRenDev->DrawPrimitivesInternal(&strip, 3, eptTriangleList); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::DrawScreenQuad([[maybe_unused]] int nTexWidth, [[maybe_unused]] int nTexHeight, float x0, float y0, float x1, float y1) -{ - const float z = (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 1.0f : 0.0f; - - Vec3 vv[4]; - vv[0] = Vec3(x0, y0, z); - vv[1] = Vec3(x0, y1, z); - vv[2] = Vec3(x1, y0, z); - vv[3] = Vec3(x1, y1, z); - SVF_P3F_C4B_T2F pScreenQuad[] = - { - { Vec3(0, 0, 0), { - {0} - }, Vec2(0, 0) }, - { Vec3(0, 0, 0), { - {0} - }, Vec2(0, 1) }, - { Vec3(0, 0, 0), { - {0} - }, Vec2(1, 0) }, - { Vec3(0, 0, 0), { - {0} - }, Vec2(1, 1) }, - }; - - pScreenQuad[0].xyz = vv[0]; - pScreenQuad[1].xyz = vv[1]; - pScreenQuad[2].xyz = vv[2]; - pScreenQuad[3].xyz = vv[3]; - - gRenDev->m_RP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF); - - CVertexBuffer strip(pScreenQuad, eVF_P3F_C4B_T2F); - gRenDev->DrawPrimitivesInternal(&strip, 4, eptTriangleStrip); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::DrawQuad([[maybe_unused]] int nTexWidth, [[maybe_unused]] int nTexHeight, - const Vec2& vxA, const Vec2& vxB, const Vec2& vxC, const Vec2& vxD, - const Vec2& uvA, const Vec2& uvB, const Vec2& uvC, const Vec2& uvD) -{ - const float z = (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 1.0f : 0.0f; - - SVF_P3F_C4B_T2F pScreenQuad[4] = - { - { Vec3(vxA.x, vxA.y, z), { - {0} - }, uvA }, - { Vec3(vxB.x, vxB.y, z), { - {0} - }, uvB }, - { Vec3(vxD.x, vxD.y, z), { - {0} - }, uvD }, - { Vec3(vxC.x, vxC.y, z), { - {0} - }, uvC } - }; - gRenDev->m_RP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF); - - CVertexBuffer strip(pScreenQuad, eVF_P3F_C4B_T2F); - gRenDev->DrawPrimitivesInternal(&strip, 4, eptTriangleStrip); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::GetFullScreenTriWPOS(SVF_P3F_T2F_T3F pResult[3], int nTexWidth, int nTexHeight, float z, const RECT *pSrcRegion) -{ - UpdateFrustumCorners(); - - if (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - z = 1.0f - z; - - pResult[0].p = Vec3(-0.0f, -0.0f, z); - pResult[0].st0 = Vec2(0, 0); - pResult[0].st1 = m_vLT; - pResult[1].p = Vec3(-0.0f, 2.0f, z); - pResult[1].st0 = Vec2(0, 2); - pResult[1].st1 = m_vLB*2.0f - m_vLT; - pResult[2].p = Vec3(2.0f, -0.0f, z); - pResult[2].st0 = Vec2(2, 0); - pResult[2].st1 = m_vRT*2.0f - m_vLT; - - if (pSrcRegion) - { - const Vec4 vTexCoordsRegion(2.0f*float(pSrcRegion->left) / nTexWidth, - 2.0f*float(pSrcRegion->right) / nTexWidth, - 2.0f*float(pSrcRegion->top) / nTexHeight, - 2.0f*float(pSrcRegion->bottom) / nTexHeight); - pResult[0].st0 = Vec2(vTexCoordsRegion.x, vTexCoordsRegion.z); - pResult[1].st0 = Vec2(vTexCoordsRegion.x, vTexCoordsRegion.w); - pResult[2].st0 = Vec2(vTexCoordsRegion.y, vTexCoordsRegion.z); - } -} - -void SPostEffectsUtils::DrawFullScreenTriWPOS(int nTexWidth, int nTexHeight, float z, const RECT *pSrcRegion) -{ - SVF_P3F_T2F_T3F screenTri[3]; - GetFullScreenTriWPOS(screenTri, nTexWidth, nTexHeight, z, pSrcRegion); - - CVertexBuffer strip(&screenTri[0], eVF_P3F_T2F_T3F); - gRenDev->DrawPrimitivesInternal(&strip, 3, eptTriangleList); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::SetTexture(CTexture* pTex, int nStage, int nFilter, int nClamp, bool bSRGBLookup, DWORD dwBorderColor) -{ - if (pTex) - { - STexState TS; - TS.SetFilterMode(nFilter); - TS.SetClampMode(nClamp, nClamp, nClamp); - if (nClamp == TADDR_BORDER) - { - TS.SetBorderColor(dwBorderColor); - } - TS.m_bSRGBLookup = bSRGBLookup; - int nTexState = CTexture::GetTexState(TS); - pTex->Apply(nStage, nTexState); - } - else - { - CTexture::ApplyForID(nStage, 0, -1, -1); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool SPostEffectsUtils::CreateRenderTarget(const char* szTexName, CTexture*& pTex, int nWidth, int nHeight, const ColorF& cClear, [[maybe_unused]] bool bUseAlpha, bool bMipMaps, ETEX_Format eTF, int nCustomID, int nFlags) -{ - // check if parameters are valid - if (!nWidth || !nHeight) - { - return 0; - } - - uint32 flags = nFlags; - flags |= FT_DONT_STREAM | FT_USAGE_RENDERTARGET | (bMipMaps ? FT_FORCE_MIPS : FT_NOMIPS); - - // if texture doesn't exist yet, create it - if (!CTexture::IsTextureExist(pTex)) - { - pTex = CTexture::CreateRenderTarget(szTexName, nWidth, nHeight, cClear, eTT_2D, flags, eTF, nCustomID); - } - else - { - pTex->SetFlags(flags); - pTex->SetWidth(nWidth); - pTex->SetHeight(nHeight); - pTex->CreateRenderTarget(eTF, cClear); - } - - // Following will mess up don't care resolve/restore actions since Fill() sets textures to be cleared on next draw -#if !defined(CRY_USE_METAL) && !defined(OPENGL_ES) - if (pTex) - { - pTex->Clear(); - } -#endif - - return CTexture::IsTextureExist(pTex) ? 1 : 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool SPostEffectsUtils::ShBeginPass(CShader* pShader, const CCryNameTSCRC& TechName, uint32 nFlags) -{ - assert(pShader); - - m_pCurrShader = pShader; - - uint32 nPasses; - m_pCurrShader->FXSetTechnique(TechName); - m_pCurrShader->FXBegin(&nPasses, nFlags); - return m_pCurrShader->FXBeginPass(0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::ShEndPass() -{ - assert(m_pCurrShader); - - m_pCurrShader->FXEndPass(); - m_pCurrShader->FXEnd(); - - m_pCurrShader = 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::ShSetParamVS(const CCryNameR& pParamName, const Vec4& pParam) -{ - assert(m_pCurrShader); - m_pCurrShader->FXSetVSFloat(pParamName, &pParam, 1); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::ShSetParamPS(const CCryNameR& pParamName, const Vec4& pParam) -{ - assert(m_pCurrShader); - m_pCurrShader->FXSetPSFloat(pParamName, &pParam, 1); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::ClearScreen(float r, float g, float b, float a) -{ - static CCryNameTSCRC pTechName("ClearScreen"); - ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - Vec4 pClrScrParms = Vec4(r, g, b, a); - static CCryNameR pParamName("clrScrParams"); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParamName, &pClrScrParms, 1); - - DrawFullScreenTri(iWidth, iHeight); - - ShEndPass(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::PrepareGmemDeferredDecals() -{ - static CCryNameTSCRC pTechName("PrepareGmemDeferredDecals"); - ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - DrawFullScreenTri(iWidth, iHeight); - - ShEndPass(); -} -void SPostEffectsUtils::ClearGmemGBuffer() -{ - static CCryNameTSCRC pTechName("ClearGmemGBuffer"); - ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - DrawFullScreenTri(iWidth, iHeight); - - ShEndPass(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SPostEffectsUtils::UpdateFrustumCorners() -{ - auto& renderPipeline = gRenDev->m_RP; - auto& threadInfo = renderPipeline.m_TI[renderPipeline.m_nProcessThreadID]; - - int nFrameID = threadInfo.m_nFrameID; - if (m_nFrustrumFrameID != nFrameID || CRenderer::CV_r_StereoMode == 1) - { - Vec3 frustumCoords[8]; - gRenDev->GetViewParameters().CalcVerts(frustumCoords); - - m_vRT = frustumCoords[4] - frustumCoords[0]; - m_vLT = frustumCoords[5] - frustumCoords[1]; - m_vLB = frustumCoords[6] - frustumCoords[2]; - m_vRB = frustumCoords[7] - frustumCoords[3]; - - // Swap order when mirrored culling enabled - if ((gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_MIRRORCULL)) - { - m_vLT = frustumCoords[4] - frustumCoords[0]; - m_vRT = frustumCoords[5] - frustumCoords[1]; - m_vRB = frustumCoords[6] - frustumCoords[2]; - m_vLB = frustumCoords[7] - frustumCoords[3]; - } - - m_nFrustrumFrameID = nFrameID; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void SPostEffectsUtils::UpdateOverscanBorderAspectRatio() -{ - if (gRenDev) - { - const float screenWidth = (float)gRenDev->GetWidth(); - const float screenHeight = (float)gRenDev->GetHeight(); - Vec2 overscanBorders = Vec2(0.0f, 0.0f); - gRenDev->EF_Query(EFQ_OverscanBorders, overscanBorders); - - const float aspectX = (screenWidth * (1.0f - (overscanBorders.y * 2.0f))); - const float aspectY = (screenHeight * (1.0f - (overscanBorders.x * 2.0f))); - m_fOverscanBorderAspectRatio = aspectX / max(aspectY, 0.001f); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -Matrix44& SPostEffectsUtils::GetColorMatrix() -{ - CPostEffectsMgr* pPostMgr = PostEffectMgr(); - int nFrameID = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameID; - if (m_nColorMatrixFrameID != nFrameID) - { - // Create color transformation matrices - float fBrightness = pPostMgr->GetByNameF("Global_Brightness"); - float fContrast = pPostMgr->GetByNameF("Global_Contrast"); - float fSaturation = pPostMgr->GetByNameF("Global_Saturation"); - float fColorC = pPostMgr->GetByNameF("Global_ColorC"); - float fColorM = pPostMgr->GetByNameF("Global_ColorM"); - float fColorY = pPostMgr->GetByNameF("Global_ColorY"); - float fColorK = pPostMgr->GetByNameF("Global_ColorK"); - float fColorHue = pPostMgr->GetByNameF("Global_ColorHue"); - - float fUserCyan = pPostMgr->GetByNameF("Global_User_ColorC"); - fColorC = fUserCyan; - - float fUserMagenta = pPostMgr->GetByNameF("Global_User_ColorM"); - fColorM = fUserMagenta; - - float fUserYellow = pPostMgr->GetByNameF("Global_User_ColorY"); - fColorY = fUserYellow; - - float fUserLuminance = pPostMgr->GetByNameF("Global_User_ColorK"); - fColorK = fUserLuminance; - - float fUserHue = pPostMgr->GetByNameF("Global_User_ColorHue"); - fColorHue = fUserHue; - - float fUserBrightness = pPostMgr->GetByNameF("Global_User_Brightness"); - fBrightness = fUserBrightness; - - float fUserContrast = pPostMgr->GetByNameF("Global_User_Contrast"); - fContrast = fUserContrast; - - float fUserSaturation = pPostMgr->GetByNameF("Global_User_Saturation"); // translate to 0 - fSaturation = fUserSaturation; - - // Saturation matrix - Matrix44 pSaturationMat; - - { - float y = 0.3086f, u = 0.6094f, v = 0.0820f, s = clamp_tpl(fSaturation, -1.0f, 100.0f); - - float a = (1.0f - s) * y + s; - float b = (1.0f - s) * y; - float c = (1.0f - s) * y; - float d = (1.0f - s) * u; - float e = (1.0f - s) * u + s; - float f = (1.0f - s) * u; - float g = (1.0f - s) * v; - float h = (1.0f - s) * v; - float i = (1.0f - s) * v + s; - - pSaturationMat.SetIdentity(); - pSaturationMat.SetRow(0, Vec3(a, d, g)); - pSaturationMat.SetRow(1, Vec3(b, e, h)); - pSaturationMat.SetRow(2, Vec3(c, f, i)); - } - - // Create Brightness matrix - Matrix44 pBrightMat; - fBrightness = clamp_tpl(fBrightness, 0.0f, 100.0f); - - pBrightMat.SetIdentity(); - pBrightMat.SetRow(0, Vec3(fBrightness, 0, 0)); - pBrightMat.SetRow(1, Vec3(0, fBrightness, 0)); - pBrightMat.SetRow(2, Vec3(0, 0, fBrightness)); - - // Create Contrast matrix - Matrix44 pContrastMat; - { - float c = clamp_tpl(fContrast, -1.0f, 100.0f); - - pContrastMat.SetIdentity(); - pContrastMat.SetRow(0, Vec3(c, 0, 0)); - pContrastMat.SetRow(1, Vec3(0, c, 0)); - pContrastMat.SetRow(2, Vec3(0, 0, c)); - pContrastMat.SetColumn(3, 0.5f * Vec3(1.0f - c, 1.0f - c, 1.0f - c)); - } - - // Create CMKY matrix - Matrix44 pCMKYMat; - { - Vec4 pCMYKParams = Vec4(fColorC + fColorK, fColorM + fColorK, fColorY + fColorK, 1.0f); - - pCMKYMat.SetIdentity(); - pCMKYMat.SetColumn(3, -Vec3(pCMYKParams.x, pCMYKParams.y, pCMYKParams.z)); - } - - // Create Hue rotation matrix - Matrix44 pHueMat; - { - pHueMat.SetIdentity(); - - const Vec3 pHueVec = Vec3(0.57735026f, 0.57735026f, 0.57735026f); // (normalized(1,1,1) - pHueMat = Matrix34::CreateRotationAA(fColorHue * PI, pHueVec); - pHueMat.SetColumn(3, Vec3(0, 0, 0)); - } - - // Compose final color matrix and set fragment program constants - m_pColorMat = pSaturationMat * (pBrightMat * pContrastMat * pCMKYMat * pHueMat); - - m_nColorMatrixFrameID = nFrameID; - } - - - return m_pColorMat; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.h b/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.h deleted file mode 100644 index 2e8390798e..0000000000 --- a/Code/CryEngine/RenderDll/Common/PostProcess/PostProcessUtils.h +++ /dev/null @@ -1,312 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Post processing common utilities - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H -#pragma once - - -struct SDepthTexture; -class CShader; - -struct SPostEffectsUtils -{ - enum EDepthDownsample - { - eDepthDownsample_None = 0, - - eDepthDownsample_Min, - eDepthDownsample_Max, - }; - - // Create all resources - bool Create(); - - // Release all used resources - void Release(); - - // Create a render target - static bool CreateRenderTarget(const char* szTexName, CTexture*& pTex, int iWidth, int iHeight, const ColorF& cClear, bool bUseAlpha, bool bMipMaps = 0, ETEX_Format pTexFormat = eTF_R8G8B8A8, int nCustomID = -1, int nFlags = 0); - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Utilities to void some code duplication - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // Begins render pass utility - for post process stuff only pass 0 assumed to be used - static bool ShBeginPass(CShader* pShader, const CCryNameTSCRC& TechName, uint32 nFlags = 0); - - // Ends render pass utility - static void ShEndPass(); - - // Set vertex shader constant utility - static void ShSetParamVS(const CCryNameR& pParamName, const Vec4& pParam); - - // Set pixel shader constant utility - static void ShSetParamPS(const CCryNameR& pParamName, const Vec4& pParam); - - static void GetFullScreenTri(SVF_P3F_C4B_T2F pResult[3], int nTexWidth, int nTexHeight, float z = 0, const RECT * pSrcRegion = NULL); - static void GetFullScreenTriWPOS(SVF_P3F_T2F_T3F pResult[3], int nTexWidth, int nTexHeight, float z = 0, const RECT * pSrcRegion = NULL); - - // Draws fullscreen aligned triangle - static void DrawFullScreenTri(int nTexWidth, int nTexHeight, float z = 0, const RECT* pSrcRegion = NULL); - static void DrawFullScreenTriWPOS(int nTexWidth, int nTexHeight, float z = 0, const RECT* pSrcRegion = NULL); - - // Draws static quad. Uv/size offsets handled via vertex shader. - virtual void DrawQuadFS(CShader* pShader, bool bOutputCamVec, int nWidth, int nHeight, float x0 = 0, float y0 = 0, float x1 = 1, float y1 = 1, float z = 0) = 0; - - // Deprecated - use DrawQuadFS. Draws screen aligned quad - static void DrawScreenQuad(int nTexWidth, int nTexHeight, float x0 = 0, float y0 = 0, float x1 = 1, float y1 = 1); - - // Deprecated: Only used in GammaCorrection technique - Draws a generic, non-screen-aligned quad - static void DrawQuad(int nTexWidth, int nTexHeight, - const Vec2& vxA, const Vec2& vxB, const Vec2& vxC, const Vec2& vxD, - const Vec2& uvA = Vec2(0, 0), const Vec2& uvB = Vec2(0, 1), const Vec2& uvC = Vec2(1, 1), const Vec2& uvD = Vec2(1, 0)); - - // Sets a texture - static void SetTexture(CTexture* pTex, int nStage, int nFilter = FILTER_LINEAR, int nClamp = 1, bool bSRGBLookup = false, DWORD dwBorderColor = 0); - - // Copy a texture into other texture - virtual void StretchRect(CTexture* pSrc, CTexture*& pDst, bool bClearAlpha = false, bool bDecodeSrcRGBK = false, bool bEncodeDstRGBK = false, bool bBigDownsample = false, EDepthDownsample depthDownsampleMode = eDepthDownsample_None, bool bBindMultisampled = false, const RECT* srcRegion = NULL) = 0; - - // Copy screen into texture - virtual void CopyScreenToTexture(CTexture*& pDst, const RECT* pSrcRect) = 0; - - // Apply Gaussian blur a texture - virtual void TexBlurGaussian(CTexture* pTex, int nAmount = 1, float fScale = 1.0f, float fDistribution = 5.0f, bool bAlphaOnly = false, CTexture* pMask = 0, bool bSRGB = false, CTexture* pBlurTmp = 0) = 0; - - // Clear active render target region - static void ClearScreen(float r, float g, float b, float a); - - static void UpdateFrustumCorners(); - static void UpdateOverscanBorderAspectRatio(); - - // Special full screen pass utility functions used by GMEM path ///// - static void PrepareGmemDeferredDecals(); - static void ClearGmemGBuffer(); - ///////////////////////////////////////////////////////////////////// - - // Log utility - static void Log(const char* pszMsg) - { - if (gRenDev->m_logFileHandle != AZ::IO::InvalidHandle && pszMsg) - { - gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_pRT->GetThreadList()], pszMsg); - } - } - - // Get current color matrix set up by global color parameters - Matrix44& GetColorMatrix(); - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // Math utils - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // Linear interpolation - static float InterpolateLinear(float p1, float p2, float t) - { - return p1 + (p2 - p1) * t; - }; - - // Cubic interpolation - static float InterpolateCubic(float p1, float p2, float p3, float p4, float t) - { - float t2 = t * t; - return (((-p1 * 2.0f) + (p2 * 5.0f) - (p3 * 4.0f) + p4) / 6.0f) * t2 * t + (p1 + p3 - (2.0f * p2)) * t2 + (((-4.0f * p1) + p2 + (p3 * 4.0f) - p4) / 6.0f) * t + p2; - }; - - // Sine interpolation - static float InterpolateSine(float p1, float p2, float p3, float p4, float t) - { - return p2 + (t * (p3 - p2)) + (sinf(t * PI) * ((p2 + p2) - p1 - p3 + (t * (p1 - (p2 + p2 + p2) + (p3 + p3 + p3) - p4))) / 8.0f); - }; - - // Return normalized random number - static float randf() - { - return cry_random(0.0f, 1.0f); - } - - // Return signed normalized random number - static float srandf() - { - return cry_random(-1.0f, 1.0f); - } - - // Returns a quasi-random sequence of values; for 2d data (2, 3) is the recommended base - static float HaltonSequence(int index, int primeBase) - { - float invBase = 1.0f / (float)primeBase; - float f = invBase; - float result = 0; - - for (int i = index; i > 0; i /= primeBase, f *= invBase) - { - result += f * (float)(i % primeBase); - } - - return result; - } - - // Returns closest power of 2 size - static int GetClosestPow2Size(int size) - { - float fPower = floorf(logf((float)size) / logf(2.0f)); - int nResize = int(powf(2.0f, fPower)); - - // Clamp - if (nResize >= 512) - { - nResize = 512; - } - - return nResize; - } - - static void GetViewMatrix(Matrix44A& viewMatrix, bool bCameraSpace = false) - { - viewMatrix = gRenDev->m_ViewMatrix; - if (bCameraSpace) - { - viewMatrix.m30 = 0.0f; - viewMatrix.m31 = 0.0f; - viewMatrix.m32 = 0.0f; - } - } - - static void GetTextureRect(CTexture* pTexture, RECT* pRect) - { - pRect->left = 0; - pRect->top = 0; - pRect->right = pTexture->GetWidth(); - pRect->bottom = pTexture->GetHeight(); - } - - static float GaussianDistribution1D(float x, float rho) - { - float g = 1.0f / (rho * sqrtf(2.0f * PI)); - g *= expf(-(x * x) / (2.0f * rho * rho)); - return g; - } - - static float GaussianDistribution2D(float x, float y, float rho) - { - float g = 1.0f / (2.0f * PI * rho * rho); - g *= expf(-(x * x + y * y) / (2 * rho * rho)); - return g; - } - - static CTexture* GetTemporalCurrentTarget() - { - return CTexture::s_ptexPrevBackBuffer[SPostEffectsUtils::m_iFrameCounter % 2][gRenDev->m_CurRenderEye]; - } - - static CTexture* GetTemporalHistoryTarget() - { - return CTexture::s_ptexPrevBackBuffer[(SPostEffectsUtils::m_iFrameCounter + 1) % 2][gRenDev->m_CurRenderEye]; - } - - static CTexture* GetCoCCurrentTarget() - { - return CTexture::s_ptexSceneCoCHistory[SPostEffectsUtils::m_iFrameCounter % 2]; - } - - static CTexture* GetCoCHistoryTarget() - { - return CTexture::s_ptexSceneCoCHistory[(SPostEffectsUtils::m_iFrameCounter + 1) % 2]; - } - - static CTexture* AcquireFinalCompositeTarget(bool bNeedHDRTarget) - { - if (bNeedHDRTarget) - { - m_UpscaleTarget = GetTemporalHistoryTarget(); - } - else - { - m_UpscaleTarget = CTexture::s_ptexSceneDiffuse; - } - return m_UpscaleTarget; - } - - static CTexture* GetFinalCompositeTarget() - { - return m_UpscaleTarget; - } - - static CTexture* GetVelocityObjectRT() - { - return CTexture::s_ptexVelocityObjects[gRenDev->m_CurRenderEye]; - } - - static float GetOverscanBorderAspectRatio() - { - return m_fOverscanBorderAspectRatio; - } - -public: - - static SDepthTexture* m_pCurDepthSurface; - static RECT m_pScreenRect; - static ITimer* m_pTimer; - static int m_iFrameCounter; - static int m_nColorMatrixFrameID; - - static CShader* m_pCurrShader; - - Matrix44 m_pView; - Matrix44 m_pProj; - Matrix44 m_pViewProj; - Matrix44 m_pColorMat; - static Matrix44 m_pScaleBias; - static float m_fWaterLevel; - - // frustrum corners - static Vec3 m_vRT, m_vLT, m_vLB, m_vRB; - static int m_nFrustrumFrameID; - -protected: - - SPostEffectsUtils() - { - m_pView.SetIdentity(); - m_pProj.SetIdentity(); - m_pViewProj.SetIdentity(); - m_pColorMat.SetIdentity(); - - m_pCurDepthSurface = NULL; - m_pScreenRect.left = m_pScreenRect.top = 0; - m_pScreenRect.bottom = m_pScreenRect.right = 0; - m_pTimer = NULL; - m_iFrameCounter = 0; - m_nColorMatrixFrameID = -1; - - m_pCurrShader = NULL; - m_fWaterLevel = 0.0; - m_vRT = m_vLT = m_vLB = m_vRB = Vec3(ZERO); - m_nFrustrumFrameID = -1; - } - - virtual ~SPostEffectsUtils() - { - } - - static float m_fOverscanBorderAspectRatio; - -private: - static CTexture* m_UpscaleTarget; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_POSTPROCESS_POSTPROCESSUTILS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.cpp b/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.cpp deleted file mode 100644 index 5ac258be94..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "AbstractMeshElement.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" -#include "../../../CryCommon/VertexFormats.h" - -void AbstractMeshElement::ApplyVert() -{ - if (!GetVertCount()) - { - return; - } - - TempDynVB::CreateFillAndBind(GetVertBufData(), GetVertCount(), 0); - gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); -} - -void AbstractMeshElement::ApplyIndices() -{ - if (!GetIndexCount()) - { - return; - } - - TempDynIB16::CreateFillAndBind(GetIndexBufData(), GetIndexCount()); -} - -void AbstractMeshElement::ApplyMesh() -{ - ApplyVert(); - ApplyIndices(); -} - -void AbstractMeshElement::DrawMeshTriList() -{ - int nVertexBufferCount = GetVertCount(); - int nIndexBufferCount = GetIndexCount(); - if (nVertexBufferCount <= 0 || nIndexBufferCount <= 0) - { - return; - } - gcpRendD3D->FX_Commit(); - gcpRendD3D->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nVertexBufferCount, 0, nIndexBufferCount); -} - -void AbstractMeshElement::DrawMeshWireframe() -{ - int nVertexBufferCount = GetVertCount(); - int nIndexBufferCount = GetIndexCount(); - if (nVertexBufferCount <= 0 || nIndexBufferCount <= 0) - { - return; - } - - const int32 nState = gRenDev->m_RP.m_CurState; - gcpRendD3D->FX_SetState(nState | GS_WIREFRAME); - - gcpRendD3D->FX_Commit(); - gcpRendD3D->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nVertexBufferCount, 0, nIndexBufferCount); - - gcpRendD3D->FX_SetState(nState); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.h b/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.h deleted file mode 100644 index a22e844a93..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/AbstractMeshElement.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ABSTRACTMESHELEMENT_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ABSTRACTMESHELEMENT_H -#pragma once - -struct SVF_P3F_C4B_T2F; -class AbstractMeshElement -{ -protected: - std::vector m_vertBuf; - std::vector m_idxBuf; - bool m_meshDirty; - - virtual void ApplyMesh(); - virtual void ApplyVert(); - virtual void ApplyIndices(); - - // Render the mesh. Must have ApplyMesh called before this to make sure - // all data are copied and all states are set. - void DrawMeshTriList(); - - // Render the mesh in wireframe mode. Primarily for debugging. NO FXCommit needed. - // Must have ApplyMesh called before this to make sure - // all data are copied and all states are set. - void DrawMeshWireframe(); - - // Custom Mesh Generation function. - // Force to generate the mesh only. - // This method doesn't alter the mark-dirty flag - virtual void GenMesh() = 0; - - // Validate the internal mesh representation. - // This regenerates the mesh when the related data is modified - virtual void ValidateMesh() - { - if (m_meshDirty) - { - GenMesh(); - m_meshDirty = false; - } - } - - int GetMeshDataSize() const - { - return m_vertBuf.size() * sizeof(SVF_P3F_C4B_T2F) + m_idxBuf.size() * sizeof(uint16) + sizeof(bool); - } - -public: - AbstractMeshElement() - : m_meshDirty(true) - { - } - virtual ~AbstractMeshElement() {} - - SVF_P3F_C4B_T2F* GetVertBufData() { return &m_vertBuf[0]; } - int GetVertCount() { return m_vertBuf.size(); } - int GetVertBufSize() { return GetVertCount() * sizeof(SVF_P3F_C4B_T2F); } - - uint16* GetIndexBufData() { return &m_idxBuf[0]; } - int GetIndexCount() { return m_idxBuf.size(); } - int GetIndexBufSize() { return GetIndexCount() * sizeof(uint16); } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ABSTRACTMESHELEMENT_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.cpp deleted file mode 100644 index d3016036af..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RendElement.h" -#include "I3DEngine.h" - -void CREBeam::mfPrepare(bool bCheckOverflow) -{ - CRenderer* rd = gRenDev; - - if (bCheckOverflow) - { - rd->FX_CheckOverflow(0, 0, this); - } - - CRenderObject* obj = rd->m_RP.m_pCurObject; - - if (CRenderer::CV_r_beams == 0) - { - rd->m_RP.m_pRE = NULL; - rd->m_RP.m_RendNumIndices = 0; - rd->m_RP.m_RendNumVerts = 0; - } - else - { - const int nThreadID = rd->m_RP.m_nProcessThreadID; - SRenderObjData* pOD = obj->GetObjData(); - if (pOD) - { - SRenderLight* pLight = rd->EF_GetDeferredLightByID(pOD->m_nLightID); - if (pLight && pLight->m_Flags & DLF_PROJECT) - { - rd->m_RP.m_pRE = this; - rd->m_RP.m_RendNumIndices = 0; - rd->m_RP.m_RendNumVerts = 0; - } - else - { - rd->m_RP.m_pRE = NULL; - rd->m_RP.m_RendNumIndices = 0; - rd->m_RP.m_RendNumVerts = 0; - } - } - else - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Render object data is null. This may affect lighting."); - } - } -} - -bool CREBeam::mfCompile([[maybe_unused]] CParserBin& Parser, [[maybe_unused]] SParserFrame& Frame) -{ - return true; -} - - -void CREBeam::SetupGeometry(SVF_P3F_C4B_T2F* pVertices, uint16* pIndices, float fAngleCoeff, float fNear, float fFar) -{ - const int nNumSides = BEAM_RE_CONE_SIDES; - Vec2 rotations[nNumSides]; - float fIncrement = 1.0f / (float)nNumSides; - float fAngle = 0.0f; - for (uint32 i = 0; i < nNumSides; i++) - { - sincos_tpl(fAngle, &rotations[i].x, &rotations[i].y); - fAngle += fIncrement * gf_PI2; - } - - float fScaleNear = fNear * fAngleCoeff; - float fScaleFar = fFar * fAngleCoeff; - - UCol cBlack, cWhite; - cBlack.dcolor = 0; - cWhite.dcolor = 0xFFFFFFFF; - - for (uint32 i = 0; i < nNumSides; i++) //Near Verts - { - pVertices[ i ].xyz = Vec3(fNear, rotations[i].x * fScaleNear, rotations[i].y * fScaleNear); - pVertices[ i ].color = cWhite; - pVertices[ i ].st = Vec2(rotations[i].x, rotations[i].y); - } - - for (uint32 i = 0; i < (nNumSides); i++) // Far verts - { - pVertices[ i + nNumSides].xyz = Vec3(fFar, rotations[i].x * fScaleFar, rotations[i].y * fScaleFar); - pVertices[ i + nNumSides].color = cWhite; - pVertices[ i + nNumSides].st = Vec2(rotations[i].x, rotations[i].y); - } - - uint32 nNearCapVert = nNumSides * 2; - uint32 nFarCapVert = nNumSides * 2 + 1; - - //near cap vert - pVertices[ nNearCapVert ].xyz = Vec3(fNear, 0.0f, 0.0f); - pVertices[ nNearCapVert ].color = cBlack; - pVertices[ nNearCapVert ].st = Vec2(0, 0); - - //far cap vert - pVertices[ nFarCapVert ].xyz = Vec3(fFar, 0.0f, 0.0f); - pVertices[ nFarCapVert ].color = cWhite; - pVertices[ nFarCapVert ].st = Vec2(0, 0); - - for (uint32 i = 0; i < nNumSides; i++) - { - uint32 idx = i * 6; - pIndices[idx] = (i) % (nNumSides); - pIndices[idx + 1] = (i) % (nNumSides) + nNumSides; - pIndices[idx + 2] = (i + 1) % (nNumSides) + nNumSides; - - pIndices[idx + 3] = (i + 1) % (nNumSides) + nNumSides; - pIndices[idx + 4] = (i + 1) % (nNumSides); - pIndices[idx + 5] = (i) % (nNumSides); - } - - for (uint32 i = 0; i < nNumSides; i++) // cap plane near - { - uint32 idx = ((nNumSides) * 6) + (i * 3); - pIndices[idx] = nNearCapVert; - pIndices[idx + 1] = (i) % (nNumSides); - pIndices[idx + 2] = (i + 1) % (nNumSides); - } - - for (uint32 i = 0; i < nNumSides; i++) // cap plane far - { - uint32 idx = ((nNumSides) * 9) + (i * 3); - pIndices[idx] = nFarCapVert; - pIndices[idx + 1] = (i + 1) % (nNumSides) + nNumSides; - pIndices[idx + 2] = (i) % (nNumSides) + nNumSides; - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.h b/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.h deleted file mode 100644 index a002126701..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREBeam.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CREBEAM_H__ -#define __CREBEAM_H__ - -#define BEAM_RE_CONE_SIDES 32 -//============================================================= - - -class CREBeam - : public CRendElementBase -{ -private: - - CCryNameR m_eyePosInWSName; - CCryNameR m_projMatrixName; - CCryNameR m_invProjMatrixName; - CCryNameR m_shadowCoordsName; - CCryNameR m_lightParamsName; - CCryNameR m_sphereParamsName; - CCryNameR m_coneParamsName; - CCryNameR m_lightPosName; - CCryNameR m_miscOffsetsName; - CCryNameR m_sampleOffsetsName; - CCryNameR m_lightDiffuseName; - CCryNameR m_screenScaleName; - -public: - CREBeam() - { - mfSetType(eDATA_Beam); - - m_eyePosInWSName = CCryNameR("eyePosInWS"); - m_projMatrixName = CCryNameR("projMatrix"); - m_invProjMatrixName = CCryNameR("invProjMatrix"); - m_shadowCoordsName = CCryNameR("shadowCoords"); - m_lightParamsName = CCryNameR("lightParams"); - m_sphereParamsName = CCryNameR("sphereParams"); - m_coneParamsName = CCryNameR("coneParams"); - m_lightPosName = CCryNameR("lightPos"); - m_miscOffsetsName = CCryNameR("MiscParams"); - m_sampleOffsetsName = CCryNameR("SampleOffsets"); - m_lightDiffuseName = CCryNameR("lightDiffuse"); - m_screenScaleName = CCryNameR("g_ScreenScale"); - } - - virtual ~CREBeam() - { - } - - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfCompile(CParserBin& Parser, SParserFrame& Frame); - virtual bool mfDraw(CShader* ef, SShaderPass* sl); - virtual void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) {}; - virtual void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) {}; - - void SetupGeometry(SVF_P3F_C4B_T2F* pVertices, uint16* pIndices, float fAngleCoeff, float fNear, float fFar); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -#endif // __CREBEAM_H__ diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.cpp deleted file mode 100644 index f05717ee5b..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : implementation of 3D Client polygons RE. - - -#include "RenderDll_precompiled.h" - - -//=============================================================== - - -TArray CREClientPoly::m_PolysStorage[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - -CRendElementBase* CREClientPoly::mfCopyConstruct(void) -{ - CREClientPoly* cp = new CREClientPoly; - *cp = *this; - return cp; -} - -void CREClientPoly::mfPrepare(bool bCheckOverflow) -{ - CRenderer* rd = gRenDev; - int i, n; - - rd->m_RP.m_CurVFormat = eVF_P3F_C4B_T2F; - - rd->FX_StartMerging(); - CREClientPoly::mRS.NumRendPolys++; - - int savev = rd->m_RP.m_RendNumVerts; - int savei = rd->m_RP.m_RendNumIndices; - - int nThreadID = rd->m_RP.m_nProcessThreadID; - - int nVerts = 0; - int nInds = 0; - if (bCheckOverflow) - { - rd->FX_CheckOverflow(m_sNumVerts, m_sNumIndices, this, &nVerts, &nInds); - } - - if (m_nOffsInd >= (int)(rd->m_RP.m_SysIndexPool[nThreadID].size())) - { - assert(0); - return; - } - - uint16* pSrcInds = &rd->m_RP.m_SysIndexPool[nThreadID][m_nOffsInd]; - n = rd->m_RP.m_RendNumVerts; - uint16* dinds = &rd->m_RP.m_RendIndices[gRenDev->m_RP.m_RendNumIndices]; - for (i = 0; i < nInds; i++, dinds++, pSrcInds++) - { - *dinds = *pSrcInds + n; - } - rd->m_RP.m_RendNumIndices += i; - - UVertStreamPtr ptr = rd->m_RP.m_NextStreamPtr; - byte* OffsTC, * OffsColor; - SVF_P3F_C4B_T2F* pSrc = (SVF_P3F_C4B_T2F*)&rd->m_RP.m_SysVertexPool[nThreadID][m_nOffsVert]; - - OffsTC = rd->m_RP.m_StreamOffsetTC + ptr.PtrB; - OffsColor = rd->m_RP.m_StreamOffsetColor + ptr.PtrB; - for (i = 0; i < nVerts; i++, ptr.PtrB += rd->m_RP.m_StreamStride, OffsTC += rd->m_RP.m_StreamStride, OffsColor += rd->m_RP.m_StreamStride) - { - *(float*)(ptr.PtrB + 0) = pSrc[i].xyz[0]; - *(float*)(ptr.PtrB + 4) = pSrc[i].xyz[1]; - *(float*)(ptr.PtrB + 8) = pSrc[i].xyz[2]; - *(float*)(OffsTC) = pSrc[i].st[0]; - *(float*)(OffsTC + 4) = pSrc[i].st[1]; - *(uint32*)OffsColor = pSrc[i].color.dcolor; - } - - rd->m_RP.m_NextStreamPtr = ptr; - - if (m_nOffsTang >= 0) - { - UVertStreamPtr ptrTang = rd->m_RP.m_NextStreamPtrTang; - SPipTangents* pTangents = (SPipTangents*)&rd->m_RP.m_SysVertexPool[nThreadID][m_nOffsTang]; - for (i = 0; i < nVerts; i++, ptrTang.PtrB += sizeof(SPipTangents)) - { - *(SPipTangents*)(ptrTang.PtrB) = pTangents[i]; - } - rd->m_RP.m_NextStreamPtrTang = ptrTang; - } - - rd->m_RP.m_RendNumVerts += nVerts; - - CREClientPoly::mRS.NumVerts += rd->m_RP.m_RendNumVerts - savev; - CREClientPoly::mRS.NumIndices += rd->m_RP.m_RendNumIndices - savei; -} - - -//======================================================================= - -SClientPolyStat CREClientPoly::mRS; - -void CREClientPoly::mfPrintStat() -{ - /* char str[1024]; - - *gpCurPrX = 4; - sprintf(str, "Num Indices: %i\n", mRS.NumIndices); - gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP); - - *gpCurPrX = 4; - sprintf(str, "Num Verts: %i\n", mRS.NumVerts); - gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP); - - *gpCurPrX = 4; - sprintf(str, "Num Render Client Polys: %i\n", mRS.NumRendPolys); - gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP); - - *gpCurPrX = 4; - sprintf(str, "Num Occluded Client Polys: %i\n", mRS.NumOccPolys); - gRenDev->mfPrintString (str, PS_TRANSPARENT | PS_UP); - - *gpCurPrX = 4; - gRenDev->mfPrintString ("\nClient Polygons status info:\n", PS_TRANSPARENT | PS_UP);*/ -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.h b/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.h deleted file mode 100644 index cd59a16b76..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREClientPoly.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CRECLIENTPOLY_H__ -#define __CRECLIENTPOLY_H__ - -//============================================================= - -struct SClientPolyStat -{ - int NumOccPolys; - int NumRendPolys; - int NumVerts; - int NumIndices; -}; - -class CREClientPoly - : public CRendElementBase -{ -public: - enum eFlags - { - efAfterWater = 1 << 0, - efShadowGen = 1 << 1, - }; - SShaderItem m_Shader; - CRenderObject* m_pObject; - short m_sNumVerts; - short m_sNumIndices; - byte m_nCPFlags; - int m_nOffsVert; - int m_nOffsTang; - int m_nOffsInd; - - SRendItemSorter rendItemSorter; - static SClientPolyStat mRS; - static void mfPrintStat(); - -public: - CREClientPoly() - { - mfSetType(eDATA_ClientPoly); - m_sNumVerts = 0; - m_nCPFlags = 0; - mfUpdateFlags(FCEF_TRANSFORM); - } - - virtual ~CREClientPoly() {}; - - virtual void mfPrepare(bool bCheckOverflow); - virtual CRendElementBase* mfCopyConstruct(void); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_PolysStorage); - } - - static TArray m_PolysStorage[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; -}; - -#endif // __CRECLIENTPOLY2D_H__ diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.cpp deleted file mode 100644 index a8bb6b754e..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "RendElement.h" -#include "CRECloud.h" -#include "../Textures/TextureManager.h" - -#include - -uint32 CRECloud::m_siShadeResolution = 32; -float CRECloud::m_sfAlbedo = 0.9f; -float CRECloud::m_sfExtinction = 80.0f; -float CRECloud::m_sfTransparency = exp(-m_sfExtinction); -float CRECloud::m_sfScatterFactor = m_sfAlbedo * m_sfExtinction * (1.0f / (4.0f * (float)M_PI)); -float CRECloud::m_sfSortAngleErrorTolerance = 0.8f; -float CRECloud::m_sfSortSquareDistanceTolerance = 100.0f; - -void CRECloud::SortParticles(const Vec3& vViewDir, const Vec3& vSortPoint, ESortDirection eDir) -{ - Vec3 partPos; - for (uint32 i = 0; i < m_particles.size(); ++i) - { - partPos = m_particles[i]->GetPosition(); - partPos -= vSortPoint; - m_particles[i]->SetSquareSortDistance(partPos * vViewDir); - } - - switch (eDir) - { - case eSort_TOWARD: - std::sort(m_particles.begin(), m_particles.end(), m_towardComparator); - break; - case eSort_AWAY: - std::sort(m_particles.begin(), m_particles.end(), m_awayComparator); - break; - default: - break; - } -} - -void CRECloud::GetIllumParams(ColorF& specColor, ColorF& diffColor) -{ - CShaderResources* pRes = gRenDev->m_RP.m_pShaderResources; - if (pRes && pRes->HasLMConstants()) - { - specColor = pRes->GetColorValue(EFTT_SPECULAR); - diffColor = pRes->GetColorValue(EFTT_DIFFUSE); - } - else - { - ColorF col = gRenDev->m_RP.m_pSunLight->m_Color; - float fLum = col.Luminance(); - col.NormalizeCol(diffColor); - specColor.a = 1.0f; - specColor = specColor * fLum / 1.5f; - diffColor = gRenDev->m_RP.m_pCurObject->m_II.m_AmbColor / 5.0f; - } -} - -void CRECloud::ShadeCloud([[maybe_unused]] Vec3 vPos) -{ - ColorF specColor, diffColor; - if (gRenDev->m_RP.m_pSunLight) - { - GetIllumParams(specColor, diffColor); - //IlluminateCloud(gRenDev->m_RP.m_pSunLight->m_Origin, vPos, difColor, ambColor, true); - m_CurSpecColor = specColor; - m_CurDiffColor = diffColor; - m_bReshadeCloud = false; - if (gRenDev->m_RP.m_pCurObject && gRenDev->m_RP.m_pCurObject->GetRE()) - { - CREImposter* pRE = (CREImposter*)gRenDev->m_RP.m_pCurObject->GetRE(); - pRE->m_bScreenImposter = true; - } - } -} - -void CRECloud::UpdateWorldSpaceBounds(CRenderObject* pObj) -{ - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - assert(pRE); - if (!pRE) - { - return; - } - pRE->m_WorldSpaceBV = m_boundingBox; - if (m_Flags & FCEF_OLD) - { - Matrix34 mScale = Matrix34::CreateScale(Vec3(m_fScale, m_fScale, m_fScale)); - pRE->m_WorldSpaceBV.Transform(mScale); - } - pRE->m_WorldSpaceBV.Transform(pObj->m_II.m_Matrix); -} - -void CRECloud::mfPrepare(bool bCheckOverflow) -{ - CRenderer* rd = gRenDev; - - if (bCheckOverflow) - { - rd->FX_CheckOverflow(0, 0, this); - } - - CRenderObject* pObj = rd->m_RP.m_pCurObject; - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - SRenderObjData* pOD = pObj->GetObjData(); - assert(pOD); - if (!pOD) - { - return; - } - if (!pRE) - { - pRE = new CREImposter; - pObj->m_pRE = pRE; - pRE->m_State = GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA | GS_ALPHATEST_GREATER; - pRE->m_AlphaRef = 0; - } - - if (pOD->m_fTempVars[0] != pOD->m_fTempVars[1]) - { - pOD->m_fTempVars[1] = pOD->m_fTempVars[0]; - m_bReshadeCloud = true; - } - if (m_Flags & FCEF_OLD) - { - float fCloudRadius = m_boundingBox.GetRadius(); - m_fScale = pOD->m_fTempVars[0] / fCloudRadius; - } - else - { - m_fScale = pOD->m_fTempVars[0]; - } - - ColorF specColor, diffColor; - GetIllumParams(specColor, diffColor); - if (specColor != m_CurSpecColor || diffColor != m_CurDiffColor) - { - m_bReshadeCloud = true; - } - - UpdateWorldSpaceBounds(pObj); - Vec3 vPos = pRE->GetPosition(); - - { - if (m_bReshadeCloud) - { - ShadeCloud(vPos); - } - UpdateImposter(pObj); - } - - rd->m_RP.m_pCurObject = pObj; - rd->m_RP.m_pRE = this; - rd->m_RP.m_RendNumIndices = 0; - rd->m_RP.m_RendNumVerts = 4; - rd->m_RP.m_FirstVertex = 0; -} - -bool CRECloud::mfLoadCloud(const string& name, float fScale, [[maybe_unused]] bool bLocal) -{ - uint32 i; - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(name.c_str(), "rb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - uint32 iNumParticles; - - mfSetFlags(FCEF_OLD); - - gEnv->pCryPak->FRead(&iNumParticles, 1, fileHandle); - if (iNumParticles == 0x238c) - { - char fTexName[128]; - char texName[256]; - gEnv->pCryPak->FRead(&iNumParticles, 1, fileHandle); - int n = 0; - int ch; - do - { - ch = gEnv->pCryPak->Getc(fileHandle); - fTexName[n++] = ch; - if (n > 128) - { - fTexName[127] = ch; - break; - } - } while (ch != 0); - fpStripExtension(fTexName, fTexName); - sprintf_s(texName, "Textures/Clouds/%s.dds", fTexName); - m_pTexParticle = CTexture::ForName(texName, 0, eTF_Unknown); - gEnv->pCryPak->FRead(&m_nNumColorGradients, 1, fileHandle); - //m_pColorGradients = new SColorLevel [m_nNumColorGradients]; - for (i = 0; i < m_nNumColorGradients; i++) - { - float fLevel; - gEnv->pCryPak->FRead(&fLevel, 1, fileHandle); - //m_pColorGradients[i].m_fLevel /= 100.0f; - uint32 iColor; - gEnv->pCryPak->FRead(&iColor, 1, fileHandle); - //m_pColorGradients[i].m_vColor = ColorF(iColor); - } - for (i = 0; i < iNumParticles; ++i) - { - Vec3 vPosition; - short nShadingNum; - short nGroupNum; - short nWidthMin, nWidthMax; - short nLengthMin, nLengthMax; - short nRotMin, nRotMax; - Vec2 vUV[2]; - gEnv->pCryPak->FRead(&vPosition, 1, fileHandle); - gEnv->pCryPak->FRead(&nShadingNum, 1, fileHandle); - gEnv->pCryPak->FRead(&nGroupNum, 1, fileHandle); - gEnv->pCryPak->FRead(&nWidthMin, 1, fileHandle); - gEnv->pCryPak->FRead(&nWidthMax, 1, fileHandle); - gEnv->pCryPak->FRead(&nLengthMin, 1, fileHandle); - gEnv->pCryPak->FRead(&nLengthMax, 1, fileHandle); - gEnv->pCryPak->FRead(&nRotMin, 1, fileHandle); - gEnv->pCryPak->FRead(&nRotMax, 1, fileHandle); - gEnv->pCryPak->FRead(&vUV[0], 1, fileHandle); - gEnv->pCryPak->FRead(&vUV[1], 1, fileHandle); - - vPosition *= 0.001f; - float fWidth = (float)nWidthMin * 0.001f; - float fHeight = (float)nLengthMin * 0.001f; - float fRotMin = (float)nRotMin; - float fRotMax = (float)nRotMax; - Exchange(vPosition.y, vPosition.z); - vUV[0].y = 1.0f - vUV[0].y; - vUV[1].y = 1.0f - vUV[1].y; - Exchange(vUV[0].x, vUV[1].x); - /*int nX = nShadingNum & 0x3; - int nY = nShadingNum >> 2; - vUV[0].x = (float)nX * 0.25f; - vUV[1].x = vUV[0].x + 0.25f; - vUV[0].y = (float)nY * 0.25f; - vUV[1].y = vUV[0].y + 0.25f;*/ - SCloudParticle* pParticle = new SCloudParticle(vPosition, fWidth, fHeight, fRotMin, fRotMax, vUV); - - Vec3 vMin = pParticle->GetPosition() - Vec3(fWidth, fWidth, fHeight); - Vec3 vMax = pParticle->GetPosition() + Vec3(fWidth, fWidth, fHeight); - m_boundingBox.AddPoint(vMin); - m_boundingBox.AddPoint(vMax); - m_particles.push_back(pParticle); - } - Vec3 vCenter = m_boundingBox.GetCenter(); - if (vCenter != Vec3(0, 0, 0)) - { - m_boundingBox.Clear(); - for (i = 0; i < iNumParticles; i++) - { - SCloudParticle* pParticle = m_particles[i]; - pParticle->SetPosition(pParticle->GetPosition() - vCenter); - float fWidth = pParticle->GetRadiusX(); - float fHeight = pParticle->GetRadiusY(); - Vec3 vMin = pParticle->GetPosition() - Vec3(fWidth, fWidth, fHeight); - Vec3 vMax = pParticle->GetPosition() + Vec3(fWidth, fWidth, fHeight); - m_boundingBox.AddPoint(vMin); - m_boundingBox.AddPoint(vMax); - } - } - } - else - { - Vec3 vCenter = Vec3(0, 0, 0); - gEnv->pCryPak->FRead(&vCenter[0], 1, fileHandle); - vCenter = Vec3(0, 0, 0); - - Vec3* pParticlePositions = new Vec3[iNumParticles]; - float* pParticleRadii = new float[iNumParticles]; - ColorF* pParticleColors = new ColorF[iNumParticles]; - - gEnv->pCryPak->FRead(pParticlePositions, iNumParticles, fileHandle); - gEnv->pCryPak->FRead(pParticleRadii, iNumParticles, fileHandle); - gEnv->pCryPak->FRead(pParticleColors, iNumParticles, fileHandle); - - for (i = 0; i < iNumParticles; ++i) - { - if (pParticleRadii[i] < 0.8f) - { - continue; - } - pParticleRadii[i] *= 1.25f; - Exchange(pParticlePositions[i].y, pParticlePositions[i].z); - SCloudParticle* pParticle = new SCloudParticle((pParticlePositions[i] + vCenter) * fScale, pParticleRadii[i] * fScale, pParticleColors[i]); - - float fRadiusX = pParticle->GetRadiusX(); - float fRadiusY = pParticle->GetRadiusX(); - Vec3 vRadius = Vec3(fRadiusX, fRadiusX, fRadiusY); - - //Vec3 Mins = pParticle->GetPosition() - vRadius; - //Vec3 Maxs = pParticle->GetPosition() + vRadius; - //m_boundingBox.AddPoint(Mins); - //m_boundingBox.AddPoint(Maxs); - m_boundingBox.AddPoint(pParticle->GetPosition()); - - m_particles.push_back(pParticle); - } - SAFE_DELETE_ARRAY(pParticleColors); - SAFE_DELETE_ARRAY(pParticleRadii); - SAFE_DELETE_ARRAY(pParticlePositions); - - m_pTexParticle = CTextureManager::Instance()->GetWhiteTexture(); - } - - gEnv->pCryPak->FClose(fileHandle); - - return true; -} - -bool CRECloud::mfCompile(CParserBin& Parser, SParserFrame& Frame) -{ - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(ParticlesFile) - FX_TOKEN(Scale) - FX_END_TOKENS - - bool bRes = true; - float fScale = 1.0f; - string pname; - ColorF col; - - while (Parser.ParseObject(sCommands)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_ParticlesFile: - pname = Parser.GetString(Parser.m_Data); - break; - case eT_Scale: - fScale = Parser.GetFloat(Parser.m_Data); - break; - } - } - - if (!pname.empty()) - { - mfLoadCloud(pname, fScale, false); - } - m_bReshadeCloud = true; - - Parser.EndFrame(OldFrame); - - return bRes; -} - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.h b/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.h deleted file mode 100644 index 603fc953d7..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CRECloud.h +++ /dev/null @@ -1,173 +0,0 @@ - -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CRECLOUD_H__ -#define __CRECLOUD_H__ - -//============================================================= - -#define FCEF_OLD 0x1000 - -class CRECloud - : public CREBaseCloud -{ - friend class CREImposter; - -protected: // datatypes - typedef std::vector ParticleArray; - typedef ParticleArray::iterator ParticleIterator; - typedef ParticleArray::const_iterator ParticleConstIterator; - - typedef std::vector DirectionArray; - typedef DirectionArray::iterator DirectionIterator; - - class ParticleAwayComparator - { - public: - bool operator()(SCloudParticle* pA, SCloudParticle* pB) - { - return ((*pA) < (*pB)); - } - }; - - class ParticleTowardComparator - { - public: - bool operator()(SCloudParticle* pA, SCloudParticle* pB) - { - return ((*pA) > (*pB)); - } - }; - -protected: // data - enum ESortDirection - { - eSort_TOWARD, - eSort_AWAY - }; - - ParticleArray m_particles; // cloud particles - // particle sorting functors for STL sort. - ParticleTowardComparator m_towardComparator; - ParticleAwayComparator m_awayComparator; - - DirectionArray m_lightDirections;// light directions in cloud space (cached) - - SMinMaxBox m_boundingBox; // bounds - - bool m_bUseAnisoLighting; - - Vec3 m_vLastSortViewDir; - Vec3 m_vLastSortCamPos; - Vec3 m_vSortPos; - - float m_fSplitDistance; - bool m_bReshadeCloud; - bool m_bEnabled; - float m_fScale; - - CTexture* m_pTexParticle; - uint32 m_nNumPlanes; - uint32 m_nNumColorGradients; - - ColorF m_CurSpecColor; - ColorF m_CurDiffColor; - float m_fCloudColorScale; // needed for HDR (>=1) - - static uint32 m_siShadeResolution;// the resolution of the viewport used for shading - static float m_sfAlbedo; // the cloud albedo - static float m_sfExtinction; // the extinction of the clouds - static float m_sfTransparency;// the transparency of the clouds - static float m_sfScatterFactor;// How much the clouds scatter - static float m_sfSortAngleErrorTolerance;// how far the view must turn to cause a resort. - static float m_sfSortSquareDistanceTolerance;// how far the view must move to cause a resort. - - -protected: - void SortParticles(const Vec3& vViewDir, const Vec3& vSortPoint, ESortDirection eDir); - void GetIllumParams(ColorF& specColor, ColorF& diffColor); - void ShadeCloud(Vec3 vPos); - void IlluminateCloud(Vec3 vLightPos, Vec3 vObjPos, ColorF cLightColor, ColorF cAmbColor, bool bReset); - void DisplayWithoutImpostor(const CameraViewParameters& camera); - bool mfDisplay(bool bDisplayFrontOfSplit); - void UpdateWorldSpaceBounds(CRenderObject* pObj); - inline float GetScale() { return m_fScale; } - bool UpdateImposter(CRenderObject* pObj); - bool mfLoadCloud(const string& name, float fScale, bool bLocal); - - void ClearParticles() - { - size_t size = m_particles.size(); - for (size_t i(0); i < size; ++i) - { - delete m_particles[i]; - } - m_particles.resize(0); - } - -public: - CRECloud() - : CREBaseCloud() - , m_bUseAnisoLighting(true) - , m_bReshadeCloud(true) - , m_bEnabled(true) - , m_fScale(1.0f) - , m_vLastSortViewDir(Vec3(0, 0, 0)) - , m_vLastSortCamPos(Vec3(0, 0, 0)) - , m_CurSpecColor(Col_White) - , m_CurDiffColor(Col_White) - , m_pTexParticle(NULL) - , m_nNumPlanes(0) - , m_nNumColorGradients(0) - , m_fCloudColorScale(1) - { - mfSetType(eDATA_Cloud); - mfSetFlags(FCEF_TRANSFORM); - } - - virtual ~CRECloud() - { - ClearParticles(); - } - - virtual bool mfCompile(CParserBin& Parser, SParserFrame& Frame); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sl); - - virtual void SetParticles(SCloudParticle* pParticles, int nNumParticles) - { - m_bReshadeCloud = true; - - m_boundingBox.Clear(); - - ClearParticles(); - m_particles.reserve(nNumParticles); - - for (int i = 0; i < nNumParticles; i++) - { - SCloudParticle* pPart = new SCloudParticle; - *pPart = pParticles[i]; - float rx = pPart->GetRadiusX(); - Vec3 vMin = pPart->GetPosition() - Vec3(rx, rx, rx); - Vec3 vMax = pPart->GetPosition() + Vec3(rx, rx, rx); - m_boundingBox.AddPoint(vMin); - m_boundingBox.AddPoint(vMax); - m_particles.push_back(pPart); - } - } - - bool GenerateCloudImposter(CShader* pShader, CShaderResources* pRes, CRenderObject* pObject); -}; - -#endif // __CRECLOUD_H__ diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.cpp deleted file mode 100644 index fd5b8d12d5..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Deferred shading processing render element - -#include "RenderDll_precompiled.h" - - -// constructor/destructor -CREDeferredShading::CREDeferredShading() -{ - // setup screen process renderer type - mfSetType(eDATA_DeferredShading); - mfUpdateFlags(FCEF_TRANSFORM); -} - -CREDeferredShading::~CREDeferredShading() -{ -}; - -// prepare screen processing -void CREDeferredShading:: mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - -void CREDeferredShading::mfReset() -{ -} - -void CREDeferredShading::mfActivate([[maybe_unused]] int iProcess) -{ -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.h b/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.h deleted file mode 100644 index 66aae3a905..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREDeferredShading.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Deferred shading processing render element - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREDEFERREDSHADING_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREDEFERREDSHADING_H -#pragma once - - - -class CREDeferredShading - : public CRendElementBase -{ - friend class CD3D9Renderer; - friend class CGLRenderer; - -public: - - // constructor/destructor - CREDeferredShading(); - - virtual ~CREDeferredShading(); - - // prepare screen processing - virtual void mfPrepare(bool bCheckOverflow); - // render screen processing - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - // begin screen processing - virtual void mfActivate(int iProcess); - // reset - virtual void mfReset(void); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREDEFERREDSHADING_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREFogVolume.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREFogVolume.cpp deleted file mode 100644 index 88cd2d879d..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREFogVolume.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "CREFogVolume.h" -#include // <> required for Interfuscator - - -CREFogVolume::CREFogVolume() - : CRendElementBase() - , m_center(0.0f, 0.0f, 0.0f) - , m_viewerInsideVolume(0) - , m_stencilRef(0) - , m_reserved(0) - , m_localAABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_matWSInv() - , m_fogColor(1, 1, 1, 1) - , m_globalDensity(1) - , m_softEdgesLerp(1, 0) - , m_heightFallOffDirScaled(0, 0, 1) - , m_heightFallOffBasePoint(0, 0, 0) - , m_eyePosInWS(0, 0, 0) - , m_eyePosInOS(0, 0, 0) - , m_rampParams(0, 0, 0) - , m_windOffset(0, 0, 0) - , m_noiseScale(0) - , m_noiseFreq(1, 1, 1) - , m_noiseOffset(0) - , m_noiseElapsedTime(0) -{ - mfSetType(eDATA_FogVolume); - mfUpdateFlags(FCEF_TRANSFORM); - - m_matWSInv.SetIdentity(); -} - - -CREFogVolume::~CREFogVolume() -{ -} - - -void CREFogVolume::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREGameEffect.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREGameEffect.cpp deleted file mode 100644 index ea7c16914e..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREGameEffect.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Render element that uses the IREGameEffect interface for its functionality - -#include "RenderDll_precompiled.h" -#include "CREGameEffect.h" - -//-------------------------------------------------------------------------------------------------- -// Name: CREGameEffect -// Desc: Constructor -//-------------------------------------------------------------------------------------------------- -CREGameEffect::CREGameEffect() -{ - m_pImpl = NULL; - mfSetType(eDATA_GameEffect); - mfUpdateFlags(FCEF_TRANSFORM); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: ~CREGameEffect -// Desc: Destructor -//-------------------------------------------------------------------------------------------------- -CREGameEffect::~CREGameEffect() -{ - SAFE_DELETE(m_pImpl); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: mfPrepare -// Desc: Prepares rendering -//-------------------------------------------------------------------------------------------------- -void CREGameEffect::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; - - if (m_pImpl) - { - m_pImpl->mfPrepare(false); - } -}//------------------------------------------------------------------------------------------------- diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREGeomCache.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREGeomCache.cpp deleted file mode 100644 index bea79db280..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREGeomCache.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Backend part of geometry cache rendering - - -#include "RenderDll_precompiled.h" - -#include -#include - -#if defined(USE_GEOM_CACHES) - -#include "RendElement.h" -#include "CREGeomCache.h" -#include "I3DEngine.h" -#include "../Renderer.h" -#include "../Common/PostProcess/PostEffects.h" - -StaticInstance CREGeomCache::sm_updateList[2]; - -CREGeomCache::CREGeomCache() - : m_geomCacheVertexFormat(eVF_P3F_C4B_T2F) -{ - m_bUpdateFrame[0] = false; - m_bUpdateFrame[1] = false; - m_transformUpdateState[0] = 0; - m_transformUpdateState[1] = 0; - - mfSetType(eDATA_GeomCache); - mfUpdateFlags(FCEF_TRANSFORM); -} - -CREGeomCache::~CREGeomCache() -{ - CryAutoLock lock1(sm_updateList[0]->m_mutex); - CryAutoLock lock2(sm_updateList[1]->m_mutex); - - stl::find_and_erase(sm_updateList[0]->m_geoms, this); - stl::find_and_erase(sm_updateList[1]->m_geoms, this); -} - -void CREGeomCache::InitializeRenderElement(const uint numMeshes, _smart_ptr* pMeshes, uint16 materialId) -{ - m_bUpdateFrame[0] = false; - m_bUpdateFrame[1] = false; - - m_meshFillData[0].clear(); - m_meshFillData[1].clear(); - m_meshRenderData.clear(); - - m_meshFillData[0].reserve(numMeshes); - m_meshFillData[1].reserve(numMeshes); - m_meshRenderData.reserve(numMeshes); - - for (uint i = 0; i < numMeshes; ++i) - { - SMeshRenderData meshRenderData; - meshRenderData.m_pRenderMesh = pMeshes[i]; - m_meshRenderData.push_back(meshRenderData); - m_meshFillData[0].push_back(meshRenderData); - m_meshFillData[1].push_back(meshRenderData); - } - - m_materialId = materialId; -} - -void CREGeomCache::mfPrepare(bool bCheckOverflow) -{ - FUNCTION_PROFILER_RENDER_FLAT - - CRenderer* const pRenderer = gRenDev; - - if (bCheckOverflow) - { - pRenderer->FX_CheckOverflow(0, 0, this); - } - - pRenderer->m_RP.m_CurVFormat = GetVertexFormat(); - pRenderer->m_RP.m_pRE = this; - pRenderer->m_RP.m_FirstVertex = 0; - pRenderer->m_RP.m_FirstIndex = 0; - pRenderer->m_RP.m_RendNumIndices = 0; - pRenderer->m_RP.m_RendNumVerts = 0; -} - -void CREGeomCache::SetupMotionBlur(CRenderObject* pRenderObject, const SRenderingPassInfo& passInfo) -{ - CMotionBlur::SetupObject(pRenderObject, passInfo); - - if (pRenderObject->m_fDistance < CRenderer::CV_r_MotionBlurMaxViewDist) - { - pRenderObject->m_ObjFlags |= FOB_VERTEX_VELOCITY | FOB_MOTION_BLUR; - } -} - -bool CREGeomCache::Update(const int flags, const bool bTessellation) -{ - FUNCTION_PROFILER_RENDER_FLAT - - // Wait until render node update has finished - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - while (m_transformUpdateState[threadId]) - { - CrySleep(0); - } - - // Check if update was successful and if so copy data to render buffer - if (m_bUpdateFrame[threadId]) - { - m_meshRenderData = m_meshFillData[threadId]; - } - - const uint numMeshes = m_meshFillData[threadId].size(); - bool bRet = true; - - for (uint nMesh = 0; nMesh < numMeshes; ++nMesh) - { - SMeshRenderData& meshData = m_meshFillData[threadId][nMesh]; - CRenderMesh* const pRenderMesh = static_cast(meshData.m_pRenderMesh.get()); - - if (pRenderMesh && pRenderMesh->m_Modified[threadId].linked()) - { - // Sync the async render mesh update. This waits for the fill thread started from main thread if it's still running. - // We need to do this manually, because geom caches don't use CREMesh. - pRenderMesh->SyncAsyncUpdate(threadId); - - CRenderMesh* pVertexContainer = pRenderMesh->_GetVertexContainer(); - bool bSucceed = pRenderMesh->RT_CheckUpdate(pVertexContainer, flags | VSM_MASK, bTessellation); - if (bSucceed) - { - pRenderMesh->m_Modified[threadId].erase(); - } - - if (!bSucceed || !pVertexContainer->_HasVBStream(VSF_GENERAL)) - { - bRet = false; - } - } - } - - return bRet; -} - -void CREGeomCache::UpdateModified() -{ - FUNCTION_PROFILER_RENDER_FLAT - - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - AZ_Assert(threadId >= 0 && threadId <= 2, "Container is not expecting this index"); - CryAutoLock lock(sm_updateList[threadId]->m_mutex); - - for (auto iter = sm_updateList[threadId]->m_geoms.begin(); - iter != sm_updateList[threadId]->m_geoms.end(); iter = sm_updateList[threadId]->m_geoms.erase(iter)) - { - CREGeomCache* pRenderElement = *iter; - pRenderElement->Update(0, false); - } -} - -bool CREGeomCache::mfUpdate(int Flags, bool bTessellation) -{ - const bool bRet = Update(Flags, bTessellation); - - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - CryAutoLock lock(sm_updateList[threadId]->m_mutex); - stl::find_and_erase(sm_updateList[threadId]->m_geoms, this); - - m_Flags &= ~FCEF_DIRTY; - return bRet; -} - -volatile int* CREGeomCache::SetAsyncUpdateState(int& threadId) -{ - FUNCTION_PROFILER_RENDER_FLAT - - ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT); - threadId = gRenDev->m_RP.m_nFillThreadID; - - m_bUpdateFrame[threadId] = false; - - CryAutoLock lock(sm_updateList[threadId]->m_mutex); - stl::push_back_unique(sm_updateList[threadId]->m_geoms, this); - - CryInterlockedIncrement(&m_transformUpdateState[threadId]); - return &m_transformUpdateState[threadId]; -} - -DynArray* CREGeomCache::GetMeshFillDataPtr() -{ - FUNCTION_PROFILER_RENDER_FLAT - - assert(gEnv->IsEditor() || !gRenDev->m_pRT->IsRenderThread(true)); - const int threadId = gRenDev->m_RP.m_nFillThreadID; - return &m_meshFillData[threadId]; -} - -DynArray* CREGeomCache::GetRenderDataPtr() -{ - FUNCTION_PROFILER_RENDER_FLAT - - assert(gEnv->IsEditor() || !gRenDev->m_pRT->IsRenderThread(true)); - return &m_meshRenderData; -} - -void CREGeomCache::DisplayFilledBuffer(const int threadId) -{ - if (m_bUpdateFrame[threadId]) - { - // You need to call SetAsyncUpdateState before DisplayFilledBuffer - __debugbreak(); - } - m_bUpdateFrame[threadId] = true; -} - -AZ::Vertex::Format CREGeomCache::GetVertexFormat() const -{ - return m_geomCacheVertexFormat; -} - -bool CREGeomCache::GetGeometryInfo(SGeometryInfo &streams) -{ - ZeroStruct(streams); - streams.vertexFormat = GetVertexFormat(); - streams.nFirstIndex = 0; - streams.nFirstVertex = 0; - streams.nNumIndices = 0; - streams.primitiveType = eptTriangleList; - streams.streamMask = 0; - return true; -} - -#endif diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.cpp deleted file mode 100644 index 6b9f3ed913..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : HDR processing render element - -#include "RenderDll_precompiled.h" - - -// constructor/destructor -CREHDRProcess::CREHDRProcess() -{ - // setup screen process renderer type - mfSetType(eDATA_HDRProcess); - mfUpdateFlags(FCEF_TRANSFORM); -} - -CREHDRProcess::~CREHDRProcess() -{ -}; - -// prepare screen processing -void CREHDRProcess:: mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - -void CREHDRProcess::mfReset() -{ -} - -void CREHDRProcess::mfActivate([[maybe_unused]] int iProcess) -{ -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.h b/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.h deleted file mode 100644 index 04e9269130..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREHDRProcess.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : HDR processing render element - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREHDRPROCESS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREHDRPROCESS_H -#pragma once - - - -// screen processing render element -class CREHDRProcess - : public CRendElementBase -{ - friend class CD3D9Renderer; - friend class CGLRenderer; - -public: - - // constructor/destructor - CREHDRProcess(); - - virtual ~CREHDRProcess(); - - // prepare screen processing - virtual void mfPrepare(bool bCheckOverflow); - // render screen processing - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - // begin screen processing - virtual void mfActivate(int iProcess); - // reset - virtual void mfReset(void); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CREHDRPROCESS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREImposter.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREImposter.cpp deleted file mode 100644 index 385abdc09b..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREImposter.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "RendElement.h" -#include "CREImposter.h" -#include "I3DEngine.h" - -int CREImposter::m_MemUpdated; -int CREImposter::m_MemPostponed; -int CREImposter::m_PrevMemUpdated; -int CREImposter::m_PrevMemPostponed; - -IDynTexture* CREImposter::m_pScreenTexture = NULL; - -bool CREImposter::IsImposterValid(const CameraViewParameters& cam, [[maybe_unused]] float fRadiusX, [[maybe_unused]] float fRadiusY, [[maybe_unused]] float fCamRadiusX, [[maybe_unused]] float fCamRadiusY, - const int iRequiredLogResX, const int iRequiredLogResY, const uint32 dwBestEdge) -{ - if (dwBestEdge != m_nLastBestEdge) - { - return false; - } - - float fTransparency = gRenDev->m_RP.m_pCurObject->m_II.m_AmbColor.a; - if (gRenDev->m_RP.m_pShaderResources) - { - fTransparency *= gRenDev->m_RP.m_pShaderResources->GetStrengthValue(EFTT_OPACITY); - } - if (m_fCurTransparency != fTransparency) - { - m_fCurTransparency = fTransparency; - return false; - } - - // screen impostors should always be updated - if (m_bScreenImposter) - { - m_vFarPoint = Vec3(0, 0, 0); - m_vNearPoint = Vec3(0, 0, 0); - return false; - } - if (m_bSplit) - { - return false; - } - - Vec3 vEye = m_vPos - cam.vOrigin; - float fDistance = vEye.GetLength(); - - if (fDistance < 0.0001f) - { - return false; // to avoid float exceptions - } - vEye /= fDistance; - - Vec3 vOldEye = m_vFarPoint - m_LastViewParameters.vOrigin; - float fOldEyeDist = vOldEye.GetLength(); - - if (fOldEyeDist < 0.0001f) - { - return false; // to avoid float exceptions - } - vOldEye /= fOldEyeDist; - - float fCosAlpha = vEye * vOldEye; // dot product of normalized vectors = cosine - if (fCosAlpha < m_fErrorToleranceCosAngle) - { - return false; - } - - Vec3 curSunDir(gEnv->p3DEngine->GetSunDir().GetNormalized()); - if (m_vLastSunDir.Dot(curSunDir) < 0.995) - { - return false; - } - - // equal pow-of-2 size comparison for consistent look - - if (iRequiredLogResX != m_nLogResolutionX) - { - return false; - } - - if (iRequiredLogResY != m_nLogResolutionY) - { - return false; - } - - if (gRenDev->m_nFrameReset != m_nFrameReset) - { - return false; - } - - return true; -} - -void CREImposter::ReleaseResources() -{ - SAFE_DELETE(m_pTexture); - SAFE_DELETE(m_pScreenTexture); - SAFE_DELETE(m_pFrontTexture); - SAFE_DELETE(m_pTextureDepth); -} - -int IntersectRayAABB(Vec3 p, Vec3 d, SMinMaxBox a, Vec3& q) -{ - float tmin = 0; - float tmax = FLT_MAX; - int i; - const Vec3& min = a.GetMin(); - const Vec3& max = a.GetMax(); - for (i = 0; i < 3; i++) - { - if (fabs(d[i]) < 0.001f) - { - if (p[i] < min[i] || p[i] > max[i]) - { - return 0; - } - } - else - { - float ood = 1.0f / d[i]; - float t1 = (min[i] - p[i]) * ood; - float t2 = (max[i] - p[i]) * ood; - if (t1 > t2) - { - Exchange(t1, t2); - } - if (t1 > tmin) - { - tmin = t1; - } - if (t2 > tmax) - { - tmax = t2; - } - } - } - q = p + d * tmin; - - return 1; -} - -Vec3 CREImposter::GetPosition() -{ - Vec3 vNearest = m_WorldSpaceBV.GetCenter(); - - return vNearest; -} - -void CREImposter::mfPrepare(bool bCheckOverflow) -{ - CRenderer* rd = gRenDev; - if (bCheckOverflow) - { - rd->FX_CheckOverflow(0, 0, this); - } - - CRenderObject* pObj = rd->m_RP.m_pCurObject; - - CShaderResources* pRes = rd->m_RP.m_pShaderResources; - CShader* pShader = rd->m_RP.m_pShader; - int nTech = rd->m_RP.m_nShaderTechnique; - - UpdateImposter(); - - rd->FX_Start(pShader, nTech, pRes, this); - rd->m_RP.m_pCurObject = pObj; - - rd->m_RP.m_pRE = this; - rd->m_RP.m_RendNumIndices = 0; - rd->m_RP.m_RendNumVerts = 4; - rd->m_RP.m_FirstVertex = 0; -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CRELensOptics.h b/Code/CryEngine/RenderDll/Common/RendElements/CRELensOptics.h deleted file mode 100644 index e9c834e042..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CRELensOptics.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CRELENSOPTICS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CRELENSOPTICS_H -#pragma once - -class CRELensOptics - : public CRendElementBase -{ -public: - CRELensOptics(void); - ~CRELensOptics(void); - - virtual bool mfCompile(CParserBin& Parser, SParserFrame& Frame); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) {}; - virtual void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) {}; - - void ProcessGlobalAction(); - - static void ClearResources(); -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CRELENSOPTICS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREMesh.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREMesh.cpp deleted file mode 100644 index ade5ff1ab4..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREMesh.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "CREMeshImpl.h" - -#if !defined(NULL_RENDERER) -#include "XRenderD3D9/DriverD3D.h" -#endif - -void CREMeshImpl::mfReset() -{ -} - -void CREMeshImpl::mfCenter(Vec3& Pos, CRenderObject* pObj) -{ - Vec3 Mins = m_pRenderMesh->m_vBoxMin; - Vec3 Maxs = m_pRenderMesh->m_vBoxMax; - Pos = (Mins + Maxs) * 0.5f; - if (pObj) - { - Pos += pObj->GetTranslation(); - } -} - -void CREMeshImpl::mfGetBBox(Vec3& vMins, Vec3& vMaxs) -{ - vMins = m_pRenderMesh->_GetVertexContainer()->m_vBoxMin; - vMaxs = m_pRenderMesh->_GetVertexContainer()->m_vBoxMax; -} - - -/////////////////////////////////////////////////////////////////// - -void CREMeshImpl::mfPrepare(bool bCheckOverflow) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfPrepare"); - CRenderer* rd = gRenDev; - - if (bCheckOverflow) - { - rd->FX_CheckOverflow(0, 0, this); - } - - IF (!m_pRenderMesh, 0) - { - return; - } - - rd->m_RP.m_CurVFormat = m_pChunk->m_vertexFormat; - - { - rd->m_RP.m_pRE = this; - - rd->m_RP.m_FirstVertex = m_nFirstVertId; - rd->m_RP.m_FirstIndex = m_nFirstIndexId; - rd->m_RP.m_RendNumIndices = m_nNumIndices; - rd->m_RP.m_RendNumVerts = m_nNumVerts; - - if (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & (RBPF_SHADOWGEN) && (gRenDev->m_RP.m_PersFlags2 & RBPF2_DISABLECOLORWRITES)) - { - _smart_ptr pMaterial = (gRenDev->m_RP.m_pCurObject) ? (gRenDev->m_RP.m_pCurObject->m_pCurrMaterial) : NULL; - m_pRenderMesh->AddShadowPassMergedChunkIndicesAndVertices(m_pChunk, pMaterial, rd->m_RP.m_RendNumVerts, rd->m_RP.m_RendNumIndices); - } - } -} - -TRenderChunkArray* CREMeshImpl::mfGetMatInfoList() -{ - return &m_pRenderMesh->m_Chunks; -} - -int CREMeshImpl::mfGetMatId() -{ - return m_pChunk->m_nMatID; -} - -CRenderChunk* CREMeshImpl::mfGetMatInfo() -{ - return m_pChunk; -} - -void CREMeshImpl::mfPrecache(const SShaderItem& SH) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfPrecache"); - CShader* pSH = (CShader*)SH.m_pShader; - IF (!pSH, 0) - { - return; - } - IF (!m_pRenderMesh, 0) - { - return; - } - IF (m_pRenderMesh->_HasVBStream(VSF_GENERAL), 0) - { - return; - } - - mfCheckUpdate(VSM_TANGENTS, gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID); -} - -bool CREMeshImpl::mfUpdate(int Flags, bool bTessellation) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfUpdate"); - FUNCTION_PROFILER_RENDER_FLAT - IF (m_pRenderMesh == NULL, 0) - { - return false; - } - - CRenderer* rd = gRenDev; - const int threadId = rd->m_RP.m_nProcessThreadID; - - bool bSucceed = true; - - CRenderMesh* pVContainer = m_pRenderMesh->_GetVertexContainer(); - - m_pRenderMesh->m_nFlags &= ~FRM_SKINNEDNEXTDRAW; - - if (m_pRenderMesh->m_Modified[threadId].linked() || bTessellation) // TODO: use the modified list also for tessellated meshes - { - m_pRenderMesh->SyncAsyncUpdate(gRenDev->m_RP.m_nProcessThreadID); - - bSucceed = m_pRenderMesh->RT_CheckUpdate(pVContainer, Flags | VSM_MASK, bTessellation); - if (bSucceed) - { - m_pRenderMesh->m_Modified[threadId].erase(); - } - } - - if (!bSucceed || !pVContainer->_HasVBStream(VSF_GENERAL)) - { - return false; - } - - bool bSkinned = (m_pRenderMesh->m_nFlags & (FRM_SKINNED | FRM_SKINNEDNEXTDRAW)) != 0; - if ((Flags | VSM_MASK) & VSM_TANGENTS) - { - if (bSkinned && pVContainer->_HasVBStream(VSF_QTANGENTS)) - { - rd->m_RP.m_FlagsStreams_Stream &= ~VSM_TANGENTS; - rd->m_RP.m_FlagsStreams_Decl &= ~VSM_TANGENTS; - rd->m_RP.m_FlagsStreams_Stream |= (1 << VSF_QTANGENTS); - rd->m_RP.m_FlagsStreams_Decl |= (1 << VSF_QTANGENTS); - } - } - - rd->m_RP.m_CurVFormat = m_pChunk->m_vertexFormat; - m_Flags &= ~FCEF_DIRTY; - - return true; -} - -void* CREMeshImpl::mfGetPointer(ESrcPointer ePT, int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfGetPointer"); - CRenderMesh* pRM = m_pRenderMesh->_GetVertexContainer(); - byte* pD = NULL; - IRenderMesh::ThreadAccessLock lock(pRM); - - switch (ePT) - { - case eSrcPointer_Vert: - pD = pRM->GetPosPtr(*Stride, FSL_READ); - break; - case eSrcPointer_Tex: - pD = pRM->GetUVPtr(*Stride, FSL_READ); - break; - case eSrcPointer_Normal: - pD = pRM->GetNormPtr(*Stride, FSL_READ); - break; - case eSrcPointer_Tangent: - pD = pRM->GetTangentPtr(*Stride, FSL_READ); - break; - case eSrcPointer_Color: - pD = pRM->GetColorPtr(*Stride, FSL_READ); - break; - default: - assert(false); - break; - } - if (m_nFirstVertId && pD) - { - pD += m_nFirstVertId * (*Stride); - } - return pD; -} - -void CREMeshImpl::mfGetPlane(Plane& pl) -{ - - // fixme: plane orientation based on biggest bbox axis - Vec3 pMin, pMax; - mfGetBBox(pMin, pMax); - Vec3 p0 = pMin; - Vec3 p1 = Vec3(pMax.x, pMin.y, pMin.z); - Vec3 p2 = Vec3(pMin.x, pMax.y, pMin.z); - pl.SetPlane(p2, p0, p1); -} - -AZ::Vertex::Format CREMeshImpl::GetVertexFormat() const -{ - if (m_pChunk) - { - return m_pChunk->m_vertexFormat; - } - else if (m_pRenderMesh) - { - return m_pRenderMesh->_GetVertexContainer()->_GetVertexFormat(); - } - return AZ::Vertex::Format(eVF_Unknown); -} -bool CREMeshImpl::GetGeometryInfo(SGeometryInfo &geomInfo) -{ - if (!m_pRenderMesh) - return false; - - CRenderMesh *pVContainer = m_pRenderMesh->_GetVertexContainer(); - - geomInfo.nFirstIndex = m_nFirstIndexId; - geomInfo.nFirstVertex = m_nFirstVertId; - geomInfo.nNumVertices = m_nNumVerts; - geomInfo.nNumIndices = m_nNumIndices; - - geomInfo.vertexFormat = pVContainer->_GetVertexFormat(); - geomInfo.primitiveType = pVContainer->GetPrimitiveType(); - - geomInfo.streamMask = 0; - - const bool bSkinned = (m_pRenderMesh->m_nFlags & (FRM_SKINNED | FRM_SKINNEDNEXTDRAW)) != 0; - if (bSkinned && pVContainer->_HasVBStream(VSF_QTANGENTS)) - geomInfo.streamMask |= BIT(VSF_QTANGENTS); - - { - // Check if needs updating. - //TODO Fix constant | 0x80000000 - //bool bTessEnabled = (pso->m_ShaderFlags_RT & g_HWSR_MaskBit[HWSR_NO_TESSELLATION]) != 0; - bool bTessEnabled = false; - uint32 streamMask = 0; - uint16 nFrameId = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - if (!mfCheckUpdate((uint32)streamMask | 0x80000000, (uint16)nFrameId, bTessEnabled)) - return false; - } - - if (!m_pRenderMesh->FillGeometryInfo(geomInfo)) - return false; - - return true; -} - -bool CREMeshImpl::BindRemappedSkinningData([[maybe_unused]] uint32 guid) -{ -#if !defined(NULL_RENDERER) - CD3D9Renderer *rd = gcpRendD3D; - - SGeometryStreamInfo streamInfo; - CRenderMesh *pRM = m_pRenderMesh->_GetVertexContainer(); - if (pRM->GetRemappedSkinningData(guid, streamInfo)) - { - rd->FX_SetVStream(VSF_HWSKIN_INFO, streamInfo.pStream, streamInfo.nOffset, streamInfo.nStride); - return true; - } -#endif - return false; -} - -#if !defined(NULL_RENDERER) -bool CREMeshImpl::mfPreDraw([[maybe_unused]] SShaderPass *sl) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfPreDraw"); - IF(!m_pRenderMesh, 0) - return false; - - CRenderMesh *pRM = m_pRenderMesh->_GetVertexContainer(); - pRM->PrefetchVertexStreams(); - - // Should never happen. Video buffer is missing - if (!pRM->_HasVBStream(VSF_GENERAL) || !m_pRenderMesh->_HasIBStream()) - return false; - - m_pRenderMesh->BindStreamsToRenderPipeline(); - - m_Flags |= FCEF_PRE_DRAW_DONE; - - return true; -} - -#if !defined(_RELEASE) -inline bool CREMeshImpl::ValidateDraw(EShaderType shaderType) -{ - bool ret = true; - - if (shaderType != eST_General && - shaderType != eST_PostProcess && - shaderType != eST_FX && - shaderType != eST_Glass && - shaderType != eST_Water) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Incorrect shader set for mesh type: %s : %d", m_pRenderMesh->GetSourceName(), shaderType); - ret = false; - } - - if (!(m_Flags&FCEF_PRE_DRAW_DONE)) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "PreDraw not called for mesh: %s", m_pRenderMesh->GetSourceName()); - ret = false; - } - - return ret; -} -#endif - -bool CREMeshImpl::mfDraw(CShader *ef, [[maybe_unused]] SShaderPass *sl) -{ - DETAILED_PROFILE_MARKER("CREMeshImpl::mfDraw"); - FUNCTION_PROFILER_RENDER_FLAT - CD3D9Renderer *r = gcpRendD3D; - -#if !defined(_RELEASE) - if (!ValidateDraw(ef->m_eShaderType)) - { - return false; - } -#endif - - CRenderMesh *pRM = m_pRenderMesh; - if (ef->m_HWTechniques.Num() && pRM->CanRender()) - { - r->FX_DrawIndexedMesh(r->m_RP.m_RendNumGroup >= 0 ? eptHWSkinGroups : pRM->GetPrimitiveType()); - } - return true; -} -#endif diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREMeshImpl.h b/Code/CryEngine/RenderDll/Common/RendElements/CREMeshImpl.h deleted file mode 100644 index d84dde7b4f..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREMeshImpl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -class CREMeshImpl - : public CREMesh -{ -#if !defined(NULL_RENDERER) -public: - // Constant buffer used for tessellation. It has just one constant which tells the hull shader how it needs to offset iPrimitiveID that comes from HW. - WrappedDX11Buffer m_tessCB; -#endif - -public: - virtual struct CRenderChunk* mfGetMatInfo(); - virtual TRenderChunkArray* mfGetMatInfoList(); - virtual int mfGetMatId(); - virtual bool mfPreDraw(SShaderPass* sl); - virtual bool mfIsHWSkinned() - { - return (m_Flags & FCEF_SKINNED) != 0; - } - virtual void mfGetPlane(Plane& pl); - virtual void mfPrepare(bool bCheckOverflow); - virtual void mfReset(); - virtual void mfCenter(Vec3& Pos, CRenderObject* pObj); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void* mfGetPointer(ESrcPointer ePT, int* Stride, EParamType Type, ESrcPointer Dst, int Flags); - virtual bool mfUpdate(int Flags, bool bTessellation = false); - virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs); - virtual void mfPrecache(const SShaderItem& SH); - virtual int Size() - { - int nSize = sizeof(*this); - return nSize; - } - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - bool BindRemappedSkinningData(uint32 guid); - - CREMeshImpl() - { - } - - virtual ~CREMeshImpl() - { - } - -#if !defined(_RELEASE) - inline bool ValidateDraw(EShaderType shaderType); -#endif - - virtual bool GetGeometryInfo(SGeometryInfo &geomInfo) override; - virtual AZ::Vertex::Format GetVertexFormat() const override; - - //protected: - // CREMeshImpl(CREMeshImpl&); - // CREMeshImpl& operator=(CREMeshImpl&); -}; diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREOclusionQuery.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREOclusionQuery.cpp deleted file mode 100644 index 7870c27158..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREOclusionQuery.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RendElement.h" - -void CREOcclusionQuery::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - mfSetType(eDATA_OcclusionQuery); - mfUpdateFlags(FCEF_TRANSFORM); - // m_matWSInv.SetIdentity(); - - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_FirstVertex = 0; - gRenDev->m_RP.m_RendNumVerts = 4; - - if (m_pRMBox && m_pRMBox->m_Chunks.size()) - { - CRenderChunk* pChunk = &m_pRMBox->m_Chunks[0]; - if (pChunk) - { - gRenDev->m_RP.m_RendNumIndices = pChunk->nNumIndices; - gRenDev->m_RP.m_FirstVertex = 0; - gRenDev->m_RP.m_RendNumVerts = pChunk->nNumVerts; - } - } -} - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREPostProcess.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREPostProcess.cpp deleted file mode 100644 index f5dc86b125..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREPostProcess.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Post processing RenderElement - - -#include "RenderDll_precompiled.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -CREPostProcess::CREPostProcess() -{ - mfSetType(eDATA_PostProcess); - mfUpdateFlags(FCEF_TRANSFORM); -} - -CREPostProcess::~CREPostProcess() -{ -} - -void CREPostProcess:: mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; - - if (CRenderer::CV_r_PostProcessReset) - { - CRenderer::CV_r_PostProcessReset = 0; - mfReset(); - } -} - -void CREPostProcess::Reset(bool bOnSpecChange) -{ - if (PostEffectMgr()) - { - PostEffectMgr()->Reset(bOnSpecChange); - } -} - -int CREPostProcess:: mfSetParameter(const char* pszParam, float fValue, bool bForceValue) const -{ - assert((pszParam) && "mfSetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return 0; - } - - pParam->SetParam(fValue, bForceValue); - - return 1; -} - -void CREPostProcess:: mfGetParameter(const char* pszParam, float& fValue) const -{ - assert((pszParam) && "mfGetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return; - } - - fValue = pParam->GetParam(); -} - -int CREPostProcess:: mfSetParameterVec4(const char* pszParam, const Vec4& pValue, bool bForceValue) const -{ - assert((pszParam) && "mfSetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return 0; - } - - pParam->SetParamVec4(pValue, bForceValue); - - return 1; -} - -void CREPostProcess:: mfGetParameterVec4(const char* pszParam, Vec4& pValue) const -{ - assert((pszParam) && "mfGetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return; - } - - pValue = pParam->GetParamVec4(); -} - -int CREPostProcess::mfSetParameterString(const char* pszParam, const char* pszArg) const -{ - assert((pszParam || pszArg) && "mfSetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return 0; - } - - pParam->SetParamString(pszArg); - return 1; -} - -void CREPostProcess::mfGetParameterString(const char* pszParam, const char*& pszArg) const -{ - assert((pszParam) && "mfGetParameter: null parameter"); - - CEffectParam* pParam = PostEffectMgr()->GetByName(pszParam); - if (!pParam) - { - return; - } - - pszArg = pParam->GetParamString(); -} - -int32 CREPostProcess::mfGetPostEffectID(const char* pPostEffectName) const -{ - assert(pPostEffectName && "mfGetParameter: null parameter"); - - return PostEffectMgr()->GetEffectID(pPostEffectName); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREPrismObject.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREPrismObject.cpp deleted file mode 100644 index 696ffe1cb9..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREPrismObject.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) - -#include "CREPrismObject.h" -#include // <> required for Interfuscator - -CREPrismObject::CREPrismObject() - : CRendElementBase() - , m_center(0, 0, 0) -{ - mfSetType(eDATA_PrismObject); - mfUpdateFlags(FCEF_TRANSFORM); -} - -void CREPrismObject::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - - -#endif // EXCLUDE_DOCUMENTATION_PURPOSE diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CRESky.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CRESky.cpp deleted file mode 100644 index b1fe13cfe2..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CRESky.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RendElement.h" -#include "CRESky.h" -#include "Stars.h" -#include "I3DEngine.h" -#include -#include - -#if !defined(NULL_RENDERER) -#include "../../XRenderD3D9/DriverD3D.h" -#endif - -CRESky::CRESky() - : m_skyVertexFormat(eVF_P3F_C4B_T2F) -{ - mfSetType(eDATA_Sky); - mfUpdateFlags(FCEF_TRANSFORM); - m_fTerrainWaterLevel = 0; - m_fAlpha = 1; - m_nSphereListId = 0; - m_fSkyBoxStretching = 1.f; -} - -void CRESky::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - -AZ::Vertex::Format CRESky::GetVertexFormat() const -{ - return m_skyVertexFormat; -} - -bool CRESky::GetGeometryInfo(SGeometryInfo &streams) -{ - ZeroStruct(streams); - streams.vertexFormat = GetVertexFormat(); - streams.primitiveType = eptTriangleList; - return true; -} - -CRESky::~CRESky() -{ -} - - -////////////////////////////////////////////////////////////////////////// -// HDR Sky -////////////////////////////////////////////////////////////////////////// -CREHDRSky::CREHDRSky() - : m_pRenderParams(0) - , m_skyDomeTextureLastTimeStamp(-1) - , m_frameReset(0) - , m_pStars(0) - , m_pSkyDomeTextureMie(0) - , m_pSkyDomeTextureRayleigh(0) - , m_hdrSkyVertexFormat(eVF_P3F_C4B_T2F) -{ - mfSetType(eDATA_HDRSky); - mfUpdateFlags(FCEF_TRANSFORM); - Init(); -} - -void CREHDRSky::GenerateSkyDomeTextures([[maybe_unused]] int32 width, [[maybe_unused]] int32 height) -{ - SAFE_RELEASE(m_pSkyDomeTextureMie); - SAFE_RELEASE(m_pSkyDomeTextureRayleigh); - -#if !defined(NULL_RENDERER) - int creationFlags = FT_STATE_CLAMP | FT_NOMIPS; - - m_pSkyDomeTextureMie = CTexture::Create2DTexture("$SkyDomeTextureMie", width, height, 1, creationFlags, 0, eTF_R16G16B16A16F, eTF_R16G16B16A16F); - m_pSkyDomeTextureMie->SetFilterMode(FILTER_LINEAR); - m_pSkyDomeTextureMie->SetClampingMode(0, 1, 1); - m_pSkyDomeTextureMie->UpdateTexStates(); - - m_pSkyDomeTextureRayleigh = CTexture::Create2DTexture("$SkyDomeTextureRayleigh", width, height, 1, creationFlags, 0, eTF_R16G16B16A16F, eTF_R16G16B16A16F); - m_pSkyDomeTextureRayleigh->SetFilterMode(FILTER_LINEAR); - m_pSkyDomeTextureRayleigh->SetClampingMode(0, 1, 1); - m_pSkyDomeTextureRayleigh->UpdateTexStates(); -#endif -} - -void CREHDRSky::Init() -{ - // The drivers in Qualcomm devices running Android 4.4 and OpenGL ES 3.0 crash - // when running the "Stars" vertex shader. The problem is a combination of using gl_VertexID - // and accessing global arrays. Disabling it for GLES 3.0 devices for now. - if (!m_pStars && GetShaderLanguage() != eSL_GLES3_0) - { - m_pStars = new CStars; - } - - //No longer defer texture creation, MT resource creation now supported - //gRenDev->m_pRT->RC_GenerateSkyDomeTextures(this, SSkyLightRenderParams::skyDomeTextureWidth, SSkyLightRenderParams::skyDomeTextureHeight); - GenerateSkyDomeTextures(SSkyLightRenderParams::skyDomeTextureWidth, SSkyLightRenderParams::skyDomeTextureHeight); -} - -void CREHDRSky::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - //gRenDev->FX_CheckOverflow( 0, 0, this ); - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - -AZ::Vertex::Format CREHDRSky::GetVertexFormat() const -{ - return m_hdrSkyVertexFormat; -} - -bool CREHDRSky::GetGeometryInfo(SGeometryInfo &streams) -{ - ZeroStruct(streams); - streams.vertexFormat = GetVertexFormat(); - streams.primitiveType = eptTriangleList; - return true; -} - -CREHDRSky::~CREHDRSky() -{ - SAFE_DELETE(m_pStars); - - SAFE_RELEASE(m_pSkyDomeTextureMie); - SAFE_RELEASE(m_pSkyDomeTextureRayleigh); -} - -void CREHDRSky::SetCommonMoonParams(CShader* ef, bool bUseMoon) -{ - I3DEngine* p3DEngine(gEnv->p3DEngine); - - Vec3 mr; - p3DEngine->GetGlobalParameter(E3DPARAM_SKY_MOONROTATION, mr); - float moonLati = -gf_PI + gf_PI * mr.x / 180.0f; - float moonLong = 0.5f * gf_PI - gf_PI * mr.y / 180.0f; - - float sinLonR = sinf(-0.5f * gf_PI); - float cosLonR = cosf(-0.5f * gf_PI); - float sinLatR = sinf(moonLati + 0.5f * gf_PI); - float cosLatR = cosf(moonLati + 0.5f * gf_PI); - Vec3 moonTexGenRight(sinLonR * cosLatR, sinLonR * sinLatR, cosLonR); - - Vec4 nsMoonTexGenRight(moonTexGenRight, 0); - static CCryNameR ParamNameTGR("SkyDome_NightMoonTexGenRight"); - ef->FXSetVSFloat(ParamNameTGR, &nsMoonTexGenRight, 1); - - float sinLonU = sinf(moonLong + 0.5f * gf_PI); - float cosLonU = cosf(moonLong + 0.5f * gf_PI); - float sinLatU = sinf(moonLati); - float cosLatU = cosf(moonLati); - Vec3 moonTexGenUp(sinLonU * cosLatU, sinLonU * sinLatU, cosLonU); - - Vec4 nsMoonTexGenUp(moonTexGenUp, 0); - static CCryNameR ParamNameTGU("SkyDome_NightMoonTexGenUp"); - ef->FXSetVSFloat(ParamNameTGU, &nsMoonTexGenUp, 1); - - Vec3 nightMoonDirection; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_DIRECTION, nightMoonDirection); - float nightMoonSize(25.0f - 24.0f * clamp_tpl(p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_SIZE), 0.0f, 1.0f)); - Vec4 nsMoonDirSize(nightMoonDirection, bUseMoon ? nightMoonSize : 9999.0f); - static CCryNameR ParamNameDirSize("SkyDome_NightMoonDirSize"); - ef->FXSetVSFloat(ParamNameDirSize, &nsMoonDirSize, 1); - ef->FXSetPSFloat(ParamNameDirSize, &nsMoonDirSize, 1); -} - -////////////////////////////////////////////////////////////////////////// -// Stars -////////////////////////////////////////////////////////////////////////// - - -CStars::CStars() - : m_numStars(0) - , m_pStarMesh(0) - , m_pShader(0) -{ - if (LoadData()) - { -#ifndef NULL_RENDERER - gRenDev->m_cEF.mfRefreshSystemShader("Stars", gRenDev->m_cEF.s_ShaderStars); - m_pShader = gRenDev->m_cEF.s_ShaderStars; -#endif - } -} - - -CStars::~CStars() -{ - m_pStarMesh = NULL; -} - - - -bool CStars::LoadData() -{ - const uint32 c_fileTag(0x52415453); // "STAR" - const uint32 c_fileVersion(0x00010001); - const char c_fileName[] = "engineassets/sky/stars.dat"; - - auto pPak(gEnv->pCryPak); - if (pPak) - { - CInMemoryFileLoader file(pPak); - if (file.FOpen(c_fileName, "rb")) - { - // read and validate header - size_t itemsRead(0); - uint32 fileTag(0); - itemsRead = file.FRead(&fileTag, 1); - if (itemsRead != 1 || fileTag != c_fileTag) - { - file.FClose(); - return false; - } - - uint32 fileVersion(0); - itemsRead = file.FRead(&fileVersion, 1); - if (itemsRead != 1 || fileVersion != c_fileVersion) - { - file.FClose(); - return false; - } - - // read in stars - file.FRead(&m_numStars, 1); - - SVF_P3S_C4B_T2S* pData(new SVF_P3S_C4B_T2S[6 * m_numStars]); - - for (unsigned int i(0); i < m_numStars; ++i) - { - float ra(0); - file.FRead(&ra, 1); - - float dec(0); - file.FRead(&dec, 1); - - uint8 r(0); - file.FRead(&r, 1); - - uint8 g(0); - file.FRead(&g, 1); - - uint8 b(0); - file.FRead(&b, 1); - - uint8 mag(0); - file.FRead(&mag, 1); - - Vec3 v; - v.x = -cosf(DEG2RAD(dec)) * sinf(DEG2RAD(ra * 15.0f)); - v.y = cosf(DEG2RAD(dec)) * cosf(DEG2RAD(ra * 15.0f)); - v.z = sinf(DEG2RAD(dec)); - - for (int k = 0; k < 6; k++) - { - pData[6 * i + k].xyz = v; - pData[6 * i + k].color.dcolor = (mag << 24) + (b << 16) + (g << 8) + r; - } - } - - m_pStarMesh = gRenDev->CreateRenderMeshInitialized(pData, 6 * m_numStars, eVF_P3S_C4B_T2S, 0, 0, prtTriangleList, "Stars", "Stars"); - - delete [] pData; - - // check if we read entire file - long curPos(file.FTell()); - file.FSeek(0, SEEK_END); - long endPos(file.FTell()); - if (curPos != endPos) - { - file.FClose(); - return false; - } - - file.FClose(); - return true; - } - } - return false; -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREVolumeObject.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREVolumeObject.cpp deleted file mode 100644 index 87127a4e11..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREVolumeObject.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "CREVolumeObject.h" -#include // <> required for Interfuscator -#include - -#if !defined(NULL_RENDERER) -#include "../../XRenderD3D9/DriverD3D.h" -#endif - -////////////////////////////////////////////////////////////////////////// -// - -class CVolumeTexture - : public IVolumeTexture -{ -public: - void Release() override; - bool Create(unsigned int width, unsigned int height, unsigned int depth, unsigned char* pData) override; - bool Update(unsigned int width, unsigned int height, unsigned int depth, const unsigned char* pData) override; - int GetTexID() const override; - uint32 GetWidth() const override { return m_width; } - uint32 GetHeight() const override { return m_height; } - uint32 GetDepth() const override { return m_depth; } - CTexture* GetTexture() const override { return m_pTex; } - CVolumeTexture(); - ~CVolumeTexture(); - -private: - unsigned int m_width; - unsigned int m_height; - unsigned int m_depth; - - static const size_t StagingBufferFrameCount = 2; - AZStd::vector m_StagingData; - uint8_t m_FrameIndex; - - inline uint8_t* GetCurrentStagingData() - { - const size_t sliceSize = m_StagingData.size() / StagingBufferFrameCount; - return &m_StagingData[m_FrameIndex * sliceSize]; - } - - CTexture* m_pTex; -}; - - -CVolumeTexture::CVolumeTexture() - : m_width(0) - , m_height(0) - , m_depth(0) - , m_pTex(0) - , m_FrameIndex(0) -{ -} - - -CVolumeTexture::~CVolumeTexture() -{ - if (m_pTex) - { - gRenDev->RemoveTexture(m_pTex->GetTextureID()); - } -} - - -void CVolumeTexture::Release() -{ - delete this; -} - - -bool CVolumeTexture::Create(unsigned int width, unsigned int height, unsigned int depth, unsigned char* pData) -{ - assert(!m_pTex); - if (!m_pTex) - { - char name[128]; - name[sizeof(name) - 1] = '\0'; - azsnprintf(name, sizeof(name) - 1, "$VolObj_%d", gRenDev->m_TexGenID++); - - const uint32_t totalByteCount = width * height * depth; - m_StagingData.resize(totalByteCount * StagingBufferFrameCount); - - if (pData) - { - uint8_t* currentStagingData = GetCurrentStagingData(); - memcpy(currentStagingData, pData, totalByteCount); - pData = currentStagingData; - } - - int flags(FT_DONT_STREAM); - m_pTex = CTexture::Create3DTexture(name, width, height, depth, 1, flags, pData, eTF_A8, eTF_A8); - - m_width = width; - m_height = height; - m_depth = depth; - } - return m_pTex != 0; -} - - -bool CVolumeTexture::Update([[maybe_unused]] unsigned int width, [[maybe_unused]] unsigned int height, [[maybe_unused]] unsigned int depth, [[maybe_unused]] const unsigned char* pData) -{ - if (!CTexture::IsTextureExist(m_pTex)) - { - return false; - } - - m_FrameIndex ^= m_FrameIndex; - -#if !defined(NULL_RENDERER) - uint8_t* stagingData = GetCurrentStagingData(); - unsigned int cpyWidth = min(width, m_width); - unsigned int cpyHeight = min(height, m_height); - unsigned int cpyDepth = min(depth, m_depth); - memcpy(stagingData, pData, cpyWidth * cpyHeight * cpyDepth); - - m_pTex->UpdateTextureRegion(stagingData, 0, 0, 0, cpyWidth, cpyHeight, cpyDepth, m_pTex->GetDstFormat()); -#endif - - return true; -} - - -int CVolumeTexture::GetTexID() const -{ - return m_pTex ? m_pTex->GetTextureID() : 0; -} - - -////////////////////////////////////////////////////////////////////////// -// - -CREVolumeObject::CREVolumeObject() - : CRendElementBase() - , m_center(0, 0, 0) - , m_matInv() - , m_eyePosInWS(0, 0, 0) - , m_eyePosInOS(0, 0, 0) - , m_volumeTraceStartPlane(Vec3(0, 0, 1), 0) - , m_renderBoundsOS(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_viewerInsideVolume(false) - , m_nearPlaneIntersectsVolume(false) - , m_alpha(1) - , m_scale(1) - , m_pDensVol(0) - , m_pShadVol(0) - , m_pHullMesh(0) -{ - mfSetType(eDATA_VolumeObject); - mfUpdateFlags(FCEF_TRANSFORM); - m_matInv.SetIdentity(); -} - - -CREVolumeObject::~CREVolumeObject() -{ -} - - -void CREVolumeObject::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; - gRenDev->m_RP.m_CurVFormat = eVF_P3F; -} - - -IVolumeTexture* CREVolumeObject::CreateVolumeTexture() const -{ - return new CVolumeTexture(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREWaterOcean.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREWaterOcean.cpp deleted file mode 100644 index f54e69f1ff..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREWaterOcean.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "CREWaterOcean.h" -#include "I3DEngine.h" - -CREWaterOcean::CREWaterOcean() - : CRendElementBase() -{ - mfSetType(eDATA_WaterOcean); - mfUpdateFlags(FCEF_TRANSFORM); - - m_nVerticesCount = 0; - m_nIndicesCount = 0; - - m_pVertDecl = 0; - m_pVertices = 0; - m_pIndices = 0; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -CREWaterOcean::~CREWaterOcean() -{ - ReleaseOcean(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CREWaterOcean::mfGetPlane([[maybe_unused]] Plane& pl) -{ -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CREWaterOcean::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; - gRenDev->m_RP.m_CurVFormat = eVF_P3F_C4B_T2F; - FrameUpdate(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -Vec3 CREWaterOcean ::GetPositionAt(float x, float y) const -{ - //assert( m_pWaterSim ); - if (WaterSimMgr()) - { - return WaterSimMgr()->GetPositionAt((int)x, (int)y); - } - - return Vec3(0, 0, 0); -} - -Vec4* CREWaterOcean::GetDisplaceGrid() const -{ - //assert( m_pWaterSim ); - if (WaterSimMgr()) - { - return WaterSimMgr()->GetDisplaceGrid(); - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CREWaterOcean::UpdateFFT() -{ -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CREWaterVolume.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CREWaterVolume.cpp deleted file mode 100644 index 74b11e94fb..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CREWaterVolume.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "CREWaterVolume.h" - - -CREWaterVolume::CREWaterVolume() - : CRendElementBase() - , m_pParams(0) - , m_pOceanParams(0) - , m_drawWaterSurface(false) - , m_drawFastPath(false) -{ - mfSetType(eDATA_WaterVolume); - mfUpdateFlags(FCEF_TRANSFORM); -} - - -CREWaterVolume::~CREWaterVolume() -{ -} - - -void CREWaterVolume::mfGetPlane(Plane& pl) -{ - pl = m_pParams->m_fogPlane; - pl.d = -pl.d; -} - -void CREWaterVolume::mfCenter(Vec3& vCenter, CRenderObject* pObj) -{ - vCenter = m_pParams->m_center; - if (pObj) - { - vCenter += pObj->GetTranslation(); - } -} - -void CREWaterVolume::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; - gRenDev->m_RP.m_CurVFormat = eVF_P3F_C4B_T2F; -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.cpp b/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.cpp deleted file mode 100644 index ecfd8e1ca8..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "MeshUtil.h" -#include "CameraOrbs.h" -#include "../Textures/Texture.h" -#include "../Textures/TextureManager.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -class ScreenTile - : public AbstractMeshElement -{ -public: - ScreenTile() - { - ValidateMesh(); - } - void GenMesh() - { - const int rowCount = 15; - const int colCount = 25; - MeshUtil::GenScreenTile(-1, -1, 1, 1, ColorF(1, 1, 1, 1), rowCount, colCount, m_vertBuf, m_idxBuf); - } - - void Draw() - { - ApplyMesh(); - gcpRendD3D->FX_Commit(); - DrawMeshTriList(); - } -}; - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&CameraOrbs::FUNC_NAME) -void CameraOrbs::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - - FuncVariableGroup camGroup; - camGroup.SetName("CameraOrbs", "Camera Orbs"); - camGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Illum range", "Illum range", this, MFPtr(SetIllumRange), MFPtr(GetIllumRange))); - camGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Orb Texture", "The texture for orbs", this, MFPtr(SetOrbTex), MFPtr(GetOrbTex))); - camGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Lens Texture", "The texture for lens", this, MFPtr(SetLensTex), MFPtr(GetLensTex))); - camGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable lens texture", "Enable lens texture", this, MFPtr(SetUseLensTex), MFPtr(GetUseLensTex))); - camGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable lens detail shading", "Enable lens detail shading", this, MFPtr(SetEnableLensDetailShading), MFPtr(GetEnableLensDetailShading))); - camGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Lens texture strength", "Lens texture strength", this, MFPtr(SetLensTexStrength), MFPtr(GetLensTexStrength))); - camGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Lens detail shading strength", "Lens detail shading strength", this, MFPtr(SetLensDetailShadingStrength), MFPtr(GetLensDetailShadingStrength))); - camGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Lens detail bumpiness", "Lens detail bumpiness", this, MFPtr(SetLensDetailBumpiness), MFPtr(GetLensDetailBumpiness))); - camGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable orb detail shading", "Enable orb detail shading", this, MFPtr(SetEnableOrbDetailShading), MFPtr(GetEnableOrbDetailShading))); - groups.push_back(camGroup); - - FuncVariableGroup genGroup; - genGroup.SetName("Generator"); - genGroup.AddVariable(new OpticsMFPVariable(e_INT, "Number of orbs", "Number of orbs", this, MFPtr(SetNumOrbs), MFPtr(GetNumOrbs), 0, 1000.0f)); - genGroup.AddVariable(new OpticsMFPVariable(e_INT, "Noise seed", "Noise seed", this, MFPtr(SetNoiseSeed), MFPtr(GetNoiseSeed), -255.0f, 255.0f)); - genGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Color variation", "Color variation", this, MFPtr(SetColorNoise), MFPtr(GetColorNoise))); - genGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size variation", "Size variation", this, MFPtr(SetSizeNoise), MFPtr(GetSizeNoise))); - genGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Rotation variation", "Rotation variation", this, MFPtr(SetRotationNoise), MFPtr(GetRotationNoise))); - groups.push_back(genGroup); - - FuncVariableGroup advShadingGroup; - advShadingGroup.SetName("AdvancedShading", "Advanced Shading"); - advShadingGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable adv shading", "Enable advanced shading mode", this, MFPtr(SetEnableAdvancdShading), MFPtr(GetEnableAdvancedShading))); - advShadingGroup.AddVariable(new OpticsMFPVariable(e_COLOR, "Ambient Diffuse", "Ambient diffuse light (RGBK)", this, MFPtr(SetAmbientDiffuseRGBK), MFPtr(GetAmbientDiffuseRGBK))); - advShadingGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Absorptance", "Absorptance of on-lens dirt", this, MFPtr(SetAbsorptance), MFPtr(GetAbsorptance))); - advShadingGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Transparency", "Transparency of on-lens dirt", this, MFPtr(SetTransparency), MFPtr(GetTransparency))); - advShadingGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Scattering", "Subsurface Scattering of on-lens dirt", this, MFPtr(SetScatteringStrength), MFPtr(GetScatteringStrength))); - groups.push_back(advShadingGroup); -} -#undef MFPtr -#endif - -void CameraOrbs::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pCameraOrbsNode = pNode->findChild("CameraOrbs"); - if (pCameraOrbsNode) - { - float fIllumRadius(m_fIllumRadius); - if (pCameraOrbsNode->getAttr("Illumrange", fIllumRadius)) - { - SetIllumRange(fIllumRadius); - } - - const char* orbTextureName(NULL); - if (pCameraOrbsNode->getAttr("OrbTexture", &orbTextureName)) - { - if (orbTextureName && orbTextureName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(orbTextureName); - SetOrbTex((CTexture*)pTexture); - if (pTexture) - { - pTexture->Release(); - } - } - } - - const char* lensTextureName(NULL); - if (pCameraOrbsNode->getAttr("LensTexture", &lensTextureName)) - { - if (lensTextureName && lensTextureName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(lensTextureName); - SetLensTex((CTexture*)pTexture); - if (pTexture) - { - pTexture->Release(); - } - } - } - - bool bUseLensTex(m_bUseLensTex); - if (pCameraOrbsNode->getAttr("Enablelenstexture", bUseLensTex)) - { - SetUseLensTex(bUseLensTex); - } - - bool bLensDetailShading(m_bLensDetailShading); - if (pCameraOrbsNode->getAttr("Enablelensdetailshading", bLensDetailShading)) - { - SetEnableLensDetailShading(bLensDetailShading); - } - - float fLensTexStrength(m_fLensTexStrength); - if (pCameraOrbsNode->getAttr("Lenstexturestrength", fLensTexStrength)) - { - SetLensTexStrength(fLensTexStrength); - } - - float fLensDetailShadingStrength(m_fLensDetailShadingStrength); - if (pCameraOrbsNode->getAttr("Lensdetailshadingstrength", fLensDetailShadingStrength)) - { - SetLensDetailShadingStrength(fLensDetailShadingStrength); - } - - float fLensDetailBumpiness(m_fLensDetailBumpiness); - if (pCameraOrbsNode->getAttr("Lensdetailbumpiness", fLensDetailBumpiness)) - { - SetLensDetailBumpiness(fLensDetailBumpiness); - } - - bool bOrbDetailShading(m_bOrbDetailShading); - if (pCameraOrbsNode->getAttr("Enableorbdetailshading", bOrbDetailShading)) - { - SetEnableOrbDetailShading(bOrbDetailShading); - } - } - - XmlNodeRef pGeneratorNode = pNode->findChild("Generator"); - if (pGeneratorNode) - { - int numOfOrbs(m_nNumOrbs); - if (pGeneratorNode->getAttr("Numberoforbs", numOfOrbs)) - { - SetNumOrbs(numOfOrbs); - } - - int nNoiseSeed(m_iNoiseSeed); - if (pGeneratorNode->getAttr("Noiseseed", nNoiseSeed)) - { - SetNoiseSeed(nNoiseSeed); - } - - float fColorNoise(m_fClrNoise); - if (pGeneratorNode->getAttr("Colorvariation", fColorNoise)) - { - SetColorNoise(fColorNoise); - } - - float fSizeNoise(m_fSizeNoise); - if (pGeneratorNode->getAttr("Sizevariation", fSizeNoise)) - { - SetSizeNoise(fSizeNoise); - } - - float fRotNoise(m_fRotNoise); - if (pGeneratorNode->getAttr("Rotationvariation", fRotNoise)) - { - SetRotationNoise(fRotNoise); - } - } - - XmlNodeRef pAdvancedShading = pNode->findChild("AdvancedShading"); - if (pAdvancedShading) - { - bool bAdvancedShading(m_bAdvancedShading); - if (pAdvancedShading->getAttr("Enableadvshading", bAdvancedShading)) - { - SetEnableAdvancdShading(bAdvancedShading); - } - - Vec3 vColor(m_cAmbientDiffuse.r, m_cAmbientDiffuse.g, m_cAmbientDiffuse.b); - int nAlpha((int)(m_cAmbientDiffuse.a * 255.0f)); - if (pAdvancedShading->getAttr("AmbientDiffuse", vColor) && pAdvancedShading->getAttr("AmbientDiffuse.alpha", nAlpha)) - { - SetAmbientDiffuseRGBK(ColorF(vColor.x, vColor.y, vColor.z, (float)nAlpha / 255.0f)); - } - - float fAbsorptance(m_fAbsorptance); - if (pAdvancedShading->getAttr("Absorptance", fAbsorptance)) - { - SetAbsorptance(fAbsorptance); - } - - float fTransparency(m_fTransparency); - if (pAdvancedShading->getAttr("Transparency", fTransparency)) - { - SetTransparency(fTransparency); - } - - float fScatteringStrength(m_fScatteringStrength); - if (pAdvancedShading->getAttr("Scattering", fScatteringStrength)) - { - SetScatteringStrength(fScatteringStrength); - } - } -} - -void CameraOrbs::GenMesh() -{ - ScatterOrbs(); - int iTempX, iTempY, iWidth, iHeight; - gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - MeshUtil::GenSprites(m_OrbsList, iWidth / (float)iHeight, true, m_vertBuf, m_idxBuf); - MeshUtil::TrianglizeQuadIndices(m_OrbsList.size(), m_idxBuf); -} - -void CameraOrbs::ScatterOrbs() -{ - stable_rand::setSeed(m_iNoiseSeed); - for (uint32 i = 0; i < m_OrbsList.size(); i++) - { - SpritePoint& sprite = m_OrbsList[i]; - - Vec2& p = sprite.pos; - p.x = stable_rand::randUnit(); - p.y = stable_rand::randUnit(); - - sprite.rotation = m_fRotation * stable_rand::randBias(GetRotationNoise()) * 2 * PI; - sprite.size = m_globalSize * stable_rand::randBias(GetSizeNoise()); - sprite.brightness = m_globalFlareBrightness * stable_rand::randBias(GetBrightnessNoise()); - - ColorF& clr = sprite.color; - ColorF variation(stable_rand::randBias(m_fClrNoise), stable_rand::randBias(m_fClrNoise), stable_rand::randBias(m_fClrNoise)); - clr = variation; - - float clrMax = clr.Max(); - clr /= clrMax; - clr.a = m_globalColor.a; - } -} - -CTexture* CameraOrbs::GetOrbTex() -{ - if (!m_pOrbTex) - { - m_pOrbTex = CTexture::ForName("EngineAssets/Textures/flares/orb_01.tif", FT_DONT_STREAM, eTF_Unknown); - } - return m_pOrbTex; -} - -CTexture* CameraOrbs::GetLensTex() -{ - if (!m_pLensTex) - { - m_pLensTex = CTexture::ForName("EngineAssets/Textures/flares/lens_dirtyglass.tif", FT_DONT_STREAM, eTF_Unknown); - } - - return m_pLensTex; -} - -void CameraOrbs::ApplyOrbFlags([[maybe_unused]] CShader* shader, bool detailShading) const -{ - if (detailShading) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } -} - -void CameraOrbs::ApplyLensDetailParams(CShader* shader, float texStength, float detailStrength, float bumpiness) const -{ - static CCryNameR lensDetailName("lensDetailParams"); - const Vec4 lensDetailParam(texStength, detailStrength, bumpiness, 0); - shader->FXSetPSFloat(lensDetailName, &lensDetailParam, 1); -} - -void CameraOrbs::ApplyAdvancedShadingFlag([[maybe_unused]] CShader* shader) const -{ - if (m_bAdvancedShading) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } -} - -void CameraOrbs::ApplyAdvancedShadingParams(CShader* shader, const ColorF& ambDiffuseRGBK, float absorptance, float transparency, float scattering) const -{ - static CCryNameR ambDiffuseRGBKName("ambientDiffuseRGBK"); - static CCryNameR advShadingName("advShadingParams"); - - static STexState pointTS(FILTER_POINT, true); - CTexture* pAmbTex = CTexture::s_ptexSceneTarget; - pAmbTex->Apply(1, CTexture::GetTexState(pointTS)); - - const Vec4 ambDiffuseRGBKParam(ambDiffuseRGBK.r, ambDiffuseRGBK.g, ambDiffuseRGBK.b, ambDiffuseRGBK.a); - const Vec4 advShadingParam(absorptance, transparency, scattering, 0); - shader->FXSetPSFloat(ambDiffuseRGBKName, &ambDiffuseRGBKParam, 1); - shader->FXSetPSFloat(advShadingName, &advShadingParam, 1); -} - -void CameraOrbs::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux) -{ - static ScreenTile screenTile; - - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("CameraOrbs"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - static CCryNameTSCRC pCameraOrbsTechName("CameraOrbs"); - static CCryNameR lightColorName("lightColorInfo"); - - static STexState bilinearTS(FILTER_LINEAR, true); - bilinearTS.SetBorderColor(0); - bilinearTS.SetClampMode(TADDR_BORDER, TADDR_BORDER, TADDR_BORDER); - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - - shader->FXSetTechnique(pCameraOrbsTechName); - - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - ApplyAdvancedShadingFlag(shader); - ApplyOcclusionBokehFlag(shader); - ApplyOrbFlags(shader, m_bOrbDetailShading); - - shader->FXBeginPass(0); - - const float x = computeMovementLocationX(vSrcProjPos); - const float y = computeMovementLocationY(vSrcProjPos); - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - ApplyVSParam_LightProjPos(shader, Vec3(x, y, aux.linearDepth)); - - const ColorF lightColor = m_globalFlareBrightness * m_globalColor * m_globalColor.a; - const Vec4 lightColorParam(lightColor.r, lightColor.g, lightColor.b, m_fIllumRadius); - shader->FXSetVSFloat(lightColorName, &lightColorParam, 1); - - ApplyLensDetailParams(shader, 1, 1, GetLensDetailBumpiness()); - if (m_globalOcclusionBokeh) - { - ApplyOcclusionPattern(shader); - } - else - { - CTextureManager::Instance()->GetBlackTexture()->Apply(5, CTexture::GetTexState(bilinearTS)); - } - - if (m_bAdvancedShading) - { - ApplyAdvancedShadingParams(shader, GetAmbientDiffuseRGBK(), GetAbsorptance(), GetTransparency(), GetScatteringStrength()); - } - - CTexture* pOrbTex = GetOrbTex() ? GetOrbTex() : CTextureManager::Instance()->GetBlackTexture(); - pOrbTex->Apply(0, CTexture::GetTexState(bilinearTS)); - ValidateMesh(); - ApplyMesh(); - DrawMeshTriList(); - shader->FXEndPass(); - - if (m_bUseLensTex) - { - gRenDev->m_RP.m_FlagsShader_RT = 0; - ApplyOrbFlags(shader, m_bLensDetailShading); - shader->FXBeginPass(1); - if (m_bAdvancedShading) - { - ApplyAdvancedShadingParams(shader, GetAmbientDiffuseRGBK(), GetAbsorptance(), GetTransparency(), GetScatteringStrength()); - } - ApplyLensDetailParams(shader, GetLensTexStrength(), GetLensDetailShadingStrength(), GetLensDetailBumpiness()); - CTexture* pLensTex = GetLensTex() ? GetLensTex() : CTextureManager::Instance()->GetBlackTexture(); - pLensTex->Apply(2, CTexture::GetTexState(bilinearTS)); - screenTile.Draw(); - shader->FXEndPass(); - } - - shader->FXEnd(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.h b/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.h deleted file mode 100644 index ee3e1ed57f..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/CameraOrbs.h +++ /dev/null @@ -1,225 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CAMERAORBS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CAMERAORBS_H -#pragma once - -#include "OpticsElement.h" -#include "AbstractMeshElement.h" - -class CTexture; -class CameraOrbs - : public COpticsElement - , public AbstractMeshElement -{ -private: - _smart_ptr m_pOrbTex; - _smart_ptr m_pLensTex; - - bool m_bUseLensTex : 1; - bool m_bOrbDetailShading : 1; - bool m_bLensDetailShading : 1; - - float m_fLensTexStrength; - float m_fLensDetailShadingStrength; - float m_fLensDetailBumpiness; - - bool m_bAdvancedShading : 1; - ColorF m_cAmbientDiffuse; - float m_fAbsorptance; - float m_fTransparency; - float m_fScatteringStrength; - - int m_nNumOrbs; - float m_fIllumRadius; - float m_fRotation; - - unsigned int m_iNoiseSeed; - float m_fSizeNoise; - float m_fBrightnessNoise; - float m_fRotNoise; - float m_fClrNoise; - - std::vector m_OrbsList; - - static const int MAX_ORBS_NUMBER = 10000; - -protected: - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - void GenMesh(); - void DrawMesh(uint32 vOffset, uint32 iOffset); - void Invalidate() - { - m_meshDirty = true; - } - -public: - - CameraOrbs (const char* name, const int numOrbs = 100) - : COpticsElement(name, 0.19f) - , m_fSizeNoise(0.8f) - , m_fBrightnessNoise(0.4f) - , m_fRotNoise(0.8f) - , m_fClrNoise(0.5f) - , m_fIllumRadius(1.f) - , m_bUseLensTex(0) - , m_bOrbDetailShading(0) - , m_bLensDetailShading(0) - , m_fLensTexStrength(1.f) - , m_fLensDetailShadingStrength(0.157f) - , m_fLensDetailBumpiness(0.073f) - , m_bAdvancedShading(false) - , m_cAmbientDiffuse(LensOpConst::_LO_DEF_CLR_BLK) - , m_fAbsorptance(4.0f) - , m_fTransparency(0.37f) - , m_fScatteringStrength(1.0f) - , m_iNoiseSeed(0) - { - m_Color.a = 1.f; - SetPerspectiveFactor(0.f); - SetRotation(0.7f); - SetNumOrbs(numOrbs); - m_meshDirty = true; - } - -protected: - void ApplyOrbFlags(CShader* shader, bool detailShading) const; - void ApplyLensDetailParams(CShader* shader, float texStength, float detailStrength, float bumpiness) const; - void ApplyAdvancedShadingFlag(CShader* shader) const; - void ApplyAdvancedShadingParams(CShader* shader, const ColorF& ambDiffuseRGBK, float absorptance, float transparency, float scattering) const; - -public: - - void ScatterOrbs(); - - int GetNumOrbs() const { return m_OrbsList.size(); } - void SetNumOrbs(int n) - { - n = clamp_tpl(n, 0, MAX_ORBS_NUMBER); - if (n != m_nNumOrbs) - { - m_nNumOrbs = n; - if (m_nNumOrbs > 0) - { - m_OrbsList.resize(m_nNumOrbs); - } - m_meshDirty = true; - } - } - - EFlareType GetType() { return eFT_CameraOrbs; } - void PreRender([[maybe_unused]] CShader* shader, [[maybe_unused]] Vec3 vSrcWorldPos, [[maybe_unused]] Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux){} - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void PostRender([[maybe_unused]] CShader* shader, [[maybe_unused]] Vec3 vSrcWorldPos, [[maybe_unused]] Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux){} - void Load(IXmlNode* pNode); - - CTexture* GetOrbTex(); - CTexture* GetLensTex(); - void SetOrbTex(CTexture* tex) { m_pOrbTex = tex; } - void SetLensTex(CTexture* tex) { m_pLensTex = tex; } - void SetUseLensTex(bool b) { m_bUseLensTex = b; } - bool GetUseLensTex() { return m_bUseLensTex; } - void SetEnableOrbDetailShading(bool b) { m_bOrbDetailShading = b; } - bool GetEnableOrbDetailShading() { return m_bOrbDetailShading; } - void SetEnableLensDetailShading(bool b) { m_bLensDetailShading = b; } - bool GetEnableLensDetailShading() { return m_bLensDetailShading; } - - void SetSize(float s) - { - COpticsElement::SetSize(s); - m_meshDirty = true; - } - - float GetLensTexStrength() const { return m_fLensTexStrength; } - void SetLensTexStrength(float strength) { m_fLensTexStrength = strength; } - - float GetLensDetailShadingStrength() const { return m_fLensDetailShadingStrength; } - void SetLensDetailShadingStrength(float strength) { m_fLensDetailShadingStrength = strength; } - - float GetLensDetailBumpiness() const { return m_fLensDetailBumpiness; } - void SetLensDetailBumpiness(float bumpiness) { m_fLensDetailBumpiness = bumpiness; } - - float GetRotation() { return m_fRotation; } - void SetRotation(float rot) - { - m_fRotation = rot; - m_meshDirty = true; - } - - int GetNoiseSeed() const { return m_iNoiseSeed; } - void SetNoiseSeed(int s) - { - m_iNoiseSeed = s; - m_meshDirty = true; - } - - float GetSizeNoise() { return m_fSizeNoise; } - void SetSizeNoise(float s) - { - m_fSizeNoise = s; - m_meshDirty = true; - } - - float GetBrightnessNoise() { return m_fBrightnessNoise; } - void SetBrightnessNoise(float b) - { - m_fBrightnessNoise = b; - m_meshDirty = true; - } - - float GetRotationNoise() { return m_fRotNoise; } - void SetRotationNoise(float r) - { - m_fRotNoise = r; - m_meshDirty = true; - } - - float GetColorNoise() { return m_fClrNoise; } - void SetColorNoise(float clrNoise) - { - m_fClrNoise = clrNoise; - m_meshDirty = true; - } - - float GetIllumRange() { return m_fIllumRadius; } - void SetIllumRange(float range) - { - m_fIllumRadius = range; - } - - bool GetEnableAdvancedShading() const { return m_bAdvancedShading; } - void SetEnableAdvancdShading(bool b) { m_bAdvancedShading = b; } - - ColorF GetAmbientDiffuseRGBK() const { return m_cAmbientDiffuse; } - void SetAmbientDiffuseRGBK(ColorF amb) { m_cAmbientDiffuse = amb; } - - float GetAbsorptance() const { return m_fAbsorptance; } - void SetAbsorptance(float a) { m_fAbsorptance = a; } - - float GetTransparency() const { return m_fTransparency; } - void SetTransparency(float t) { m_fTransparency = t; } - - float GetScatteringStrength() const { return m_fScatteringStrength; } - void SetScatteringStrength(float s) { m_fScatteringStrength = s; } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this) + GetMeshDataSize()); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CAMERAORBS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.cpp b/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.cpp deleted file mode 100644 index f31e82b8fd..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ChromaticRing.h" -#include "../Textures/Texture.h" -#include "../CryNameR.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&ChromaticRing::FUNC_NAME) -void ChromaticRing::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - - FuncVariableGroup crGroup; - crGroup.SetName("ChromaticRing", "Chromatic Ring"); - crGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Lock to light", "Lock to light", this, MFPtr(SetLockMovement), MFPtr(IsLockMovement))); - crGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Thickness", "Thickness", this, MFPtr(SetWidth), MFPtr(GetWidth))); - - crGroup.AddVariable(new OpticsMFPVariable(e_INT, "Polygon complexity", "Polygon complexity", this, MFPtr(SetPolyComplexity), MFPtr(GetPolyComplexity), 0, 1024.0f)); - crGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Gradient Texture", "Gradient Texture", this, MFPtr(SetSpectrumTex), MFPtr(GetSpectrumTex))); - crGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable Gradient Texture", "Enable Gradient Texture", this, MFPtr(SetUsingSpectrumTex), MFPtr(IsUsingSpectrumTex))); - - crGroup.AddVariable(new OpticsMFPVariable(e_INT, "Noise seed", "Noise seed", this, MFPtr(SetNoiseSeed), MFPtr(GetNoiseSeed), -255.0f, 255.0f)); - crGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Noise strength", "Noise strength", this, MFPtr(SetNoiseStrength), MFPtr(GetNoiseStrength))); - crGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Completion fading", "the fading ratio at the ends of this arc", this, MFPtr(SetCompletionFading), MFPtr(GetCompletionFading))); - crGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Completion span angle", "The span of this arc in degree", this, MFPtr(SetCompletionSpanAngle), MFPtr(GetCompletionSpanAngle))); - crGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Completion rotation", "The rotation of this arc", this, MFPtr(SetCompletionRotation), MFPtr(GetCompletionRotation))); - - groups.push_back(crGroup); -} -#undef MFPtr -#endif - -void ChromaticRing::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pCameraOrbsNode = pNode->findChild("ChromaticRing"); - if (pCameraOrbsNode) - { - bool bLockMovement(m_bLockMovement); - if (pCameraOrbsNode->getAttr("Locktolight", bLockMovement)) - { - SetLockMovement(bLockMovement); - } - - float fWidth(m_fWidth); - if (pCameraOrbsNode->getAttr("Thickness", fWidth)) - { - SetWidth(fWidth); - } - - int nPolyComplexity(m_nPolyComplexity); - if (pCameraOrbsNode->getAttr("Polygoncomplexity", nPolyComplexity)) - { - SetPolyComplexity(nPolyComplexity); - } - - const char* gradientTexName = NULL; - if (pCameraOrbsNode->getAttr("GradientTexture", &gradientTexName)) - { - if (gradientTexName && gradientTexName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(gradientTexName); - SetSpectrumTex((CTexture*)pTexture); - if (pTexture) - { - pTexture->Release(); - } - } - } - - bool bUseSpectrumTex(m_bUseSpectrumTex); - if (pCameraOrbsNode->getAttr("EnableGradientTexture", bUseSpectrumTex)) - { - SetUsingSpectrumTex(bUseSpectrumTex); - } - - int nNoiseSeed(m_nNoiseSeed); - if (pCameraOrbsNode->getAttr("Noiseseed", nNoiseSeed)) - { - SetNoiseSeed(nNoiseSeed); - } - - float fNoiseStrength(m_fNoiseStrength); - if (pCameraOrbsNode->getAttr("Noisestrength", fNoiseStrength)) - { - SetNoiseStrength(fNoiseStrength); - } - - float fCompletionFading(m_fCompletionFading); - if (pCameraOrbsNode->getAttr("Completionfading", fCompletionFading)) - { - SetCompletionFading(fCompletionFading); - } - - float fTotalAngle(0); - if (pCameraOrbsNode->getAttr("Completionspanangle", fTotalAngle)) - { - SetCompletionSpanAngle(fTotalAngle); - } - - float fCompletionRotation(0); - if (pCameraOrbsNode->getAttr("Completionrotation", fCompletionRotation)) - { - SetCompletionRotation(fCompletionRotation); - } - } -} - -void ChromaticRing::DrawMesh() -{ - gcpRendD3D->FX_Commit(); - DrawMeshTriList(); - DrawMeshWireframe(); -} - -float ChromaticRing::computeDynamicSize(const Vec3& vSrcProjPos, const float maxSize) -{ - Vec2 dir(vSrcProjPos.x - 0.5f, vSrcProjPos.y - 0.5f); - float len = dir.GetLength(); - const float hoopDistFactor = 2.3f; - return len * hoopDistFactor * maxSize; -} - -void ChromaticRing::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("ChromaticRing"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - - static CCryNameTSCRC pChromaticRingTechName("ChromaticRing"); - shader->FXSetTechnique(pChromaticRingTechName); - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - ApplySpectrumTexFlag(shader, m_bUseSpectrumTex); - shader->FXBeginPass(0); - - float newSize = computeDynamicSize(vSrcProjPos, m_globalSize); - - float oldSize = m_globalSize; - m_globalSize = newSize; - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - m_globalSize = oldSize; - ApplyExternTintAndBrightnessVS(shader, m_globalColor, m_globalFlareBrightness); - - static CCryNameR meshCenterName("meshCenterAndBrt"); - float x, y; - if (m_bLockMovement) - { - x = vSrcProjPos.x; - y = vSrcProjPos.y; - } - else - { - x = computeMovementLocationX(vSrcProjPos); - y = computeMovementLocationY(vSrcProjPos); - } - const Vec4 meshCenterParam(x, y, vSrcProjPos.z, m_globalFlareBrightness); - shader->FXSetVSFloat(meshCenterName, &meshCenterParam, 1); - - static STexState bilinearTS(FILTER_LINEAR, true); - bilinearTS.SetBorderColor(0); - bilinearTS.SetClampMode(TADDR_BORDER, TADDR_BORDER, TADDR_BORDER); - if (m_pSpectrumTex == NULL) - { - m_pSpectrumTex = CTexture::ForName("EngineAssets/Textures/flares/spectrum_full.tif", FT_DONT_STREAM, eTF_Unknown); - } - m_pSpectrumTex->Apply(0, CTexture::GetTexState(bilinearTS)); - - ValidateMesh(); - ApplyMesh(); - DrawMesh(); - shader->FXEndPass(); - - shader->FXEnd(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.h b/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.h deleted file mode 100644 index 399927099e..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/ChromaticRing.h +++ /dev/null @@ -1,197 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CHROMATICRING_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CHROMATICRING_H -#pragma once - -#include "OpticsElement.h" -#include "AbstractMeshElement.h" -#include "MeshUtil.h" - -class CTexture; -class ChromaticRing - : public COpticsElement - , public AbstractMeshElement -{ -private: - bool m_bLockMovement : 1; - - _smart_ptr m_pSpectrumTex; - bool m_bUseSpectrumTex : 1; - - int m_nPolyComplexity; - int m_nColorComplexity; - - float m_fWidth; - float m_fNoiseStrength; - int m_nNoiseSeed; - - float m_fCompletionStart; - float m_fCompletionEnd; - float m_fCompletionFading; - -protected: - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - void GenMesh() - { - ColorF c(1, 1, 1, 1); - - int polyComplexity(m_nPolyComplexity); - if (CRenderer::CV_r_FlaresTessellationRatio < 1 && CRenderer::CV_r_FlaresTessellationRatio > 0) - { - polyComplexity = (int)((float)m_nPolyComplexity * CRenderer::CV_r_FlaresTessellationRatio); - } - - MeshUtil::GenHoop( - m_fSize, polyComplexity, m_fWidth, 2, c, - m_fNoiseStrength * m_fSize, m_nNoiseSeed, m_fCompletionStart, m_fCompletionEnd, m_fCompletionFading, - m_vertBuf, m_idxBuf); - } - void DrawMesh(); - void Invalidate() - { - m_meshDirty = true; - } - static float computeDynamicSize(const Vec3& vSrcProjPos, const float maxSize); - -public: - - ChromaticRing(const char* name) - : COpticsElement(name) - , m_bUseSpectrumTex(false) - , m_fWidth(0.5f) - , m_nPolyComplexity(160) - , m_nColorComplexity(2) - , m_fNoiseStrength(0.0f) - , m_fCompletionStart(90.f) - , m_fCompletionEnd(270.f) - , m_fCompletionFading(45.f) - { - SetSize(0.9f); - SetAutoRotation(true); - SetAspectRatioCorrection(false); - - m_meshDirty = true; - } - - EFlareType GetType() { return eFT_ChromaticRing; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - void SetSize(float s) - { - COpticsElement::SetSize(s); - m_meshDirty = true; - } - - bool IsLockMovement() const { return m_bLockMovement; } - void SetLockMovement(bool b) { m_bLockMovement = b; } - - int GetPolyComplexity() { return m_nPolyComplexity; } - void SetPolyComplexity(int polyCplx) - { - if (polyCplx <= 0) - { - polyCplx = 1; - } - else if (polyCplx > 1024) - { - polyCplx = 1024; - } - m_nPolyComplexity = polyCplx; - m_meshDirty = true; - } - - int GetColorComplexity() { return m_nColorComplexity; } - void SetColorComplexity(int clrCplx) - { - if (clrCplx <= 0) - { - clrCplx = 1; - } - m_nColorComplexity = clrCplx; - m_meshDirty = true; - } - - CTexture* GetSpectrumTex() { return m_pSpectrumTex; } - void SetSpectrumTex(CTexture* tex) - { - m_pSpectrumTex = tex; - } - - bool IsUsingSpectrumTex() { return m_bUseSpectrumTex; } - void SetUsingSpectrumTex(bool b) - { - m_bUseSpectrumTex = b; - } - - int GetNoiseSeed() { return m_nNoiseSeed; } - void SetNoiseSeed(int seed) - { - m_nNoiseSeed = seed; - m_meshDirty = true; - } - - float GetWidth() { return m_fWidth; } - void SetWidth(float w) - { - m_fWidth = w; - m_meshDirty = true; - } - - float GetNoiseStrength() { return m_fNoiseStrength; } - void SetNoiseStrength(float noise) - { - m_fNoiseStrength = noise; - m_meshDirty = true; - } - - float GetCompletionFading() { return m_fCompletionFading; } - void SetCompletionFading(float f) - { - m_fCompletionFading = f; - m_meshDirty = true; - } - - float GetCompletionSpanAngle() { return (m_fCompletionEnd - m_fCompletionStart); } - void SetCompletionSpanAngle(float totalAngle) - { - float rotAngle = GetCompletionRotation(); - float halfTotalAngle = totalAngle / 2; - m_fCompletionStart = rotAngle - halfTotalAngle; - m_fCompletionEnd = rotAngle + halfTotalAngle; - m_meshDirty = true; - } - - float GetCompletionRotation() { return (m_fCompletionStart + m_fCompletionEnd) * 0.5f; } - void SetCompletionRotation(float rot) - { - float oldRotAngle = GetCompletionRotation(); - float rotDiff = rot - oldRotAngle; - m_fCompletionStart += rotDiff; - m_fCompletionEnd += rotDiff; - m_meshDirty = true; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this) + GetMeshDataSize()); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_CHROMATICRING_H - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.cpp b/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.cpp deleted file mode 100644 index b24bef854b..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "FlareSoftOcclusionQuery.h" -#include "../CryNameR.h" -#include "../../XRenderD3D9/DriverD3D.h" -#include "../Textures/Texture.h" -#include "I3DEngine.h" - -unsigned char CFlareSoftOcclusionQuery::s_paletteRawCache[s_nIDMax * 4]; -char CFlareSoftOcclusionQuery::s_idHashTable[s_nIDMax]; -int CFlareSoftOcclusionQuery::s_idCount = 0; -int CFlareSoftOcclusionQuery::s_ringReadIdx = 1; -int CFlareSoftOcclusionQuery::s_ringWriteIdx = 0; -int CFlareSoftOcclusionQuery::s_ringSize = MAX_OCCLUSION_READBACK_TEXTURES; - -static bool g_bCreatedGlobalResources = false; - -const float CFlareSoftOcclusionQuery::s_fSectorWidth = (float)s_nGatherEachSectorWidth / (float)s_nGatherTextureWidth; -const float CFlareSoftOcclusionQuery::s_fSectorHeight = (float)s_nGatherEachSectorHeight / (float)s_nGatherTextureHeight; - -float CSoftOcclusionVisiblityFader::UpdateVisibility(const float newTargetVisibility, const float duration) -{ - m_TimeLine.duration = duration; - - if (fabs(newTargetVisibility - m_fTargetVisibility) > 0.1f) - { - m_TimeLine.startValue = m_TimeLine.GetPrevYValue(); - m_fTargetVisibility = newTargetVisibility; - m_TimeLine.rewind(); - } - else if (newTargetVisibility < 0.05f) - { - m_fTargetVisibility = newTargetVisibility; - m_TimeLine.endValue = newTargetVisibility; - } - else - { - m_TimeLine.endValue = m_fTargetVisibility; - } - - // Fade in fixed time (in ms), fade out user controlled - const float fadeInTime = m_TimeLine.duration * (1.0f / 0.15f); - const float fadeOutTime = 1e3f; - float dt = (newTargetVisibility > m_fVisibilityFactor) ? fadeInTime : fadeOutTime; - - m_fVisibilityFactor = m_TimeLine.step(gEnv->pTimer->GetFrameTime() * dt); // interpolate - - return m_fVisibilityFactor; -} - -void ReportIDPoolOverflow(int idCount, int idMax) -{ - iLog->Log("Number of soft occlusion queries [%d] exceeds current allowed range %d", idCount, idMax); -} - -int CFlareSoftOcclusionQuery::GenID() -{ - int hashCode = s_idCount % s_nIDMax; - - while (hashCode < s_nIDMax && s_idHashTable[hashCode]) - { - hashCode++; - } - - if (hashCode >= s_nIDMax) - { - ReportIDPoolOverflow(s_idCount + 1, s_nIDMax); - hashCode = 0; - } - - s_idHashTable[hashCode] = (char)1; - s_idCount++; - - return hashCode; -} - -void CFlareSoftOcclusionQuery::ReleaseID(int id) -{ - if (id < s_nIDMax) - { - s_idHashTable[id] = (char)0; - } -} - -void CFlareSoftOcclusionQuery::InitGlobalResources() -{ - if (g_bCreatedGlobalResources) - { - return; - } - - const uint32 numGPUs = (gRenDev->GetActiveGPUCount() <= MAX_OCCLUSION_READBACK_TEXTURES / 2) ? gRenDev->GetActiveGPUCount() : 1; - s_ringWriteIdx = 0; - s_ringReadIdx = numGPUs; - s_ringSize = MAX_OCCLUSION_READBACK_TEXTURES; - - memset(s_idHashTable, 0, sizeof(s_idHashTable)); - memset(s_paletteRawCache, 0, sizeof(s_paletteRawCache)); - - g_bCreatedGlobalResources = true; -} - -void CFlareSoftOcclusionQuery::GetDomainInTexture(float& out_x0, float& out_y0, float& out_x1, float& out_y1) -{ - out_x0 = (m_nID % s_nIDColMax) * s_fSectorWidth; - out_y0 = (m_nID / s_nIDColMax) * s_fSectorHeight; - out_x1 = out_x0 + s_fSectorWidth; - out_y1 = out_y0 + s_fSectorHeight; -} - -bool CFlareSoftOcclusionQuery::ComputeProjPos(const Vec3& vWorldPos, const Matrix44A& viewMat, const Matrix44A& projMat, Vec3& outProjPos) -{ - static int vp[] = {0, 0, 1, 1}; - if (mathVec3Project(&outProjPos, &vWorldPos, vp, &projMat, &viewMat, &gRenDev->m_IdentityMatrix) == 0.0f) - { - return false; - } - return true; -} - -void CFlareSoftOcclusionQuery::GetSectorSize(float& width, float& height) -{ - width = s_fSectorWidth; - height = s_fSectorWidth; -} - -void CFlareSoftOcclusionQuery::GetOcclusionSectorInfo(SOcclusionSectorInfo& out_Info) -{ - Vec3 vProjectedPos; - if (ComputeProjPos(m_PosToBeChecked, gRenDev->m_ViewMatrix, gRenDev->m_ProjMatrix, vProjectedPos) == false) - { - return; - } - out_Info.lineardepth = clamp_tpl(ComputeLinearDepth(m_PosToBeChecked, gRenDev->m_CameraMatrix, gRenDev->GetViewParameters().fNear, gRenDev->GetViewParameters().fFar), -1.0f, 0.99f); - - out_Info.u0 = vProjectedPos.x - m_fOccPlaneWidth / 2; - out_Info.v0 = vProjectedPos.y - m_fOccPlaneHeight / 2; - out_Info.u1 = vProjectedPos.x + m_fOccPlaneWidth / 2; - out_Info.v1 = vProjectedPos.y + m_fOccPlaneHeight / 2; - - if (out_Info.u0 < 0) - { - out_Info.u0 = 0; - } - if (out_Info.v0 < 0) - { - out_Info.v0 = 0; - } - if (out_Info.u1 > 1) - { - out_Info.u1 = 1; - } - if (out_Info.v1 > 1) - { - out_Info.v1 = 1; - } - - GetDomainInTexture(out_Info.x0, out_Info.y0, out_Info.x1, out_Info.y1); - - out_Info.x0 = out_Info.x0 * 2.0f - 1; - out_Info.y0 = -(out_Info.y0 * 2.0f - 1.0f); - out_Info.x1 = out_Info.x1 * 2.0f - 1; - out_Info.y1 = -(out_Info.y1 * 2.0f - 1.0f); -} - -float CFlareSoftOcclusionQuery::ComputeLinearDepth(const Vec3& worldPos, const Matrix44A& cameraMat, float nearDist, float farDist) -{ - Vec4 out, wPos4; - wPos4.x = worldPos.x; - wPos4.y = worldPos.y; - wPos4.z = worldPos.z; - wPos4.w = 1; - mathVec4Transform((f32*)&out, (f32*)(&cameraMat), (f32*)&wPos4); - if (out.w == 0.0f) - { - return 0; - } - const CameraViewParameters& rc = gRenDev->GetViewParameters(); - float linearDepth = (-out.z - rc.fNear) / (farDist - nearDist); - - return linearDepth; -} - -void CFlareSoftOcclusionQuery::UpdateCachedResults() -{ - int cacheIdx = 4 * m_nID; - m_fOccResultCache = s_paletteRawCache[cacheIdx + 0] / 255.0f; - m_fDirResultCache = (s_paletteRawCache[cacheIdx + 3] / 255.0f) * 2.0f * PI; - sincos_tpl(m_fDirResultCache, &m_DirVecResultCache.y, &m_DirVecResultCache.x); -} - -CTexture* CFlareSoftOcclusionQuery::GetGatherTexture() const -{ - return CTexture::s_ptexFlaresGather; -} - -void CFlareSoftOcclusionQuery::BatchReadResults() -{ - if (!g_bCreatedGlobalResources) - { - return; - } - CTexture::s_ptexFlaresOcclusionRing[s_ringWriteIdx]->GetDevTexture()->AccessCurrStagingResource(0, false, [=](void* pData, uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - unsigned char* pTexBuf = reinterpret_cast(pData); - int validLineStrideBytes = s_nIDColMax * 4; - for (int i = 0; i < s_nIDRowMax; i++) - { - memcpy(s_paletteRawCache + i * validLineStrideBytes, pTexBuf + i * rowPitch, validLineStrideBytes); - } - - return true; - }); -} - -void CFlareSoftOcclusionQuery::ReadbackSoftOcclQuery() -{ - CTexture::s_ptexFlaresOcclusionRing[s_ringWriteIdx]->GetDevTexture()->DownloadToStagingResource(0); - - // sync point. Move to next texture to read and write - s_ringReadIdx = (s_ringReadIdx + 1) % s_ringSize; - s_ringWriteIdx = (s_ringWriteIdx + 1) % s_ringSize; -} - -CTexture* CFlareSoftOcclusionQuery::GetOcclusionTex() -{ - return CTexture::s_ptexFlaresOcclusionRing[s_ringWriteIdx]; -} - -void CSoftOcclusionManager::ComputeVisibility() -{ - static STexState ShadowTexState(FILTER_POINT, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0); - CShader* pShader = CShaderMan::s_ShaderSoftOcclusionQuery; - - gcpRendD3D->FX_ClearTarget(CTexture::s_ptexFlaresGather, Clr_Transparent); - gcpRendD3D->FX_PushRenderTarget(0, CTexture::s_ptexFlaresGather, NULL); - - pShader->FXBeginPass(0); - - const uint32 vertexCount = GetSize() * 4; - - TempDynVB vb(gcpRendD3D); - vb.Allocate(vertexCount); - SVF_P3F_C4B_T2F* pDeviceVBAddr = vb.Lock(); - - for (int i(0), iSoftOcclusionListSize(GetSize()); i < iSoftOcclusionListSize; ++i) - { - CFlareSoftOcclusionQuery* pSoftOcclusion = GetSoftOcclusionQuery(i); - if (pSoftOcclusion == NULL) - { - continue; - } - int offset = i * 4; - - CFlareSoftOcclusionQuery::SOcclusionSectorInfo sInfo; - pSoftOcclusion->GetOcclusionSectorInfo(sInfo); - - for (int k = 0; k < 4; ++k) - { - pDeviceVBAddr[offset + k].color.dcolor = 0xFFFFFFFF; - } - - pDeviceVBAddr[offset + 0].st = Vec2(sInfo.u0 * gcpRendD3D->m_CurViewportScale.x, sInfo.v0 * gcpRendD3D->m_CurViewportScale.y); - pDeviceVBAddr[offset + 1].st = Vec2(sInfo.u1 * gcpRendD3D->m_CurViewportScale.x, sInfo.v0 * gcpRendD3D->m_CurViewportScale.y); - pDeviceVBAddr[offset + 2].st = Vec2(sInfo.u1 * gcpRendD3D->m_CurViewportScale.x, sInfo.v1 * gcpRendD3D->m_CurViewportScale.y); - pDeviceVBAddr[offset + 3].st = Vec2(sInfo.u0 * gcpRendD3D->m_CurViewportScale.x, sInfo.v1 * gcpRendD3D->m_CurViewportScale.y); - - pDeviceVBAddr[offset + 0].xyz = Vec3(sInfo.x0, sInfo.y1, sInfo.lineardepth); - pDeviceVBAddr[offset + 1].xyz = Vec3(sInfo.x1, sInfo.y1, sInfo.lineardepth); - pDeviceVBAddr[offset + 2].xyz = Vec3(sInfo.x1, sInfo.y0, sInfo.lineardepth); - pDeviceVBAddr[offset + 3].xyz = Vec3(sInfo.x0, sInfo.y0, sInfo.lineardepth); - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (pDeviceVBAddr && m_bSuccessGenerateIB) - { - CTexture::s_ptexZTargetScaled->Apply(0, CTexture::GetTexState(ShadowTexState)); - - gcpRendD3D->FX_Commit(); - - if (SUCCEEDED(gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - gcpRendD3D->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, vertexCount, 0, m_IndexBufferCount); - } - } - pShader->FXEndPass(); - gcpRendD3D->FX_PopRenderTarget(0); -} - -bool CSoftOcclusionManager::GenerateIndexBuffer() -{ - m_IndexBufferCount = GetSize() * 2 * 3; - if (m_IndexBufferCount <= 0) - { - return false; - } - - TempDynIB16 ib(gcpRendD3D); - ib.Allocate(m_IndexBufferCount); - uint16* pDeviceIBAddr = ib.Lock(); - - for (int i(0), iSoftOcclusionListSize(GetSize()); i < iSoftOcclusionListSize; ++i) - { - CFlareSoftOcclusionQuery* pSoftOcclusion = GetSoftOcclusionQuery(i); - if (pSoftOcclusion == NULL) - { - continue; - } - int offset0 = i * 6; - int offset1 = i * 4; - pDeviceIBAddr[offset0 + 0] = offset1 + 0; - pDeviceIBAddr[offset0 + 1] = offset1 + 1; - pDeviceIBAddr[offset0 + 2] = offset1 + 2; - pDeviceIBAddr[offset0 + 3] = offset1 + 2; - pDeviceIBAddr[offset0 + 4] = offset1 + 3; - pDeviceIBAddr[offset0 + 5] = offset1 + 0; - } - - ib.Unlock(); - m_IndexBufferOffset = 0; - ib.Bind(); - ib.Release(); - - return true; -} - -void CSoftOcclusionManager::GatherOcclusions() -{ - CShader* pShader = CShaderMan::s_ShaderSoftOcclusionQuery; - static STexState GatherTexState(FILTER_POINT, true); - - gcpRendD3D->FX_ClearTarget(CFlareSoftOcclusionQuery::GetOcclusionTex(), Clr_Transparent); - gcpRendD3D->FX_PushRenderTarget(0, CFlareSoftOcclusionQuery::GetOcclusionTex(), NULL); - - pShader->FXBeginPass(1); - float x0 = 0, y0 = 0, x1 = 0, y1 = 0; - - const uint32 vertexCount = GetSize() * 4; - - TempDynVB vb(gcpRendD3D); - vb.Allocate(vertexCount); - SVF_P3F_C4B_T2F* pDeviceVBAddr = vb.Lock(); - - for (int i = 0, iSoftOcclusionListSize(GetSize()); i < iSoftOcclusionListSize; ++i) - { - CFlareSoftOcclusionQuery* pSoftOcclusion = GetSoftOcclusionQuery(i); - if (pSoftOcclusion == NULL) - { - continue; - } - int offset = i * 4; - pSoftOcclusion->GetDomainInTexture(x0, y0, x1, y1); - for (int k = 0; k < 4; ++k) - { - pDeviceVBAddr[offset + k].st = Vec2((x0 + x1) * 0.5f * gcpRendD3D->m_CurViewportScale.x, (y0 + y1) * 0.5f * gcpRendD3D->m_CurViewportScale.y); - pDeviceVBAddr[offset + k].color.dcolor = 0xFFFFFFFF; - } - x0 = x0 * 2.0f - 1.0f; - y0 = -(y0 * 2.0f - 1.0f); - x1 = x1 * 2.0f - 1.0f; - y1 = -(y1 * 2.0f - 1.0f); - pDeviceVBAddr[offset + 0].xyz = Vec3(x0, y1, 1); - pDeviceVBAddr[offset + 1].xyz = Vec3(x1, y1, 1); - pDeviceVBAddr[offset + 2].xyz = Vec3(x1, y0, 1); - pDeviceVBAddr[offset + 3].xyz = Vec3(x0, y0, 1); - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (pDeviceVBAddr && m_bSuccessGenerateIB) - { - static CCryNameR occlusionNormalizedSizeName("occlusionNormalizedSize"); - const Vec4 occlusionSizeParam(CFlareSoftOcclusionQuery::s_fSectorWidth, CFlareSoftOcclusionQuery::s_fSectorHeight, 0, 0); - pShader->FXSetPSFloat(occlusionNormalizedSizeName, &occlusionSizeParam, 1); - CTexture::s_ptexFlaresGather->Apply(0, CTexture::GetTexState(GatherTexState)); - - gcpRendD3D->FX_Commit(); - - if (SUCCEEDED(gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - gcpRendD3D->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, vertexCount, 0, m_IndexBufferCount); - } - } - pShader->FXEndPass(); - gcpRendD3D->FX_PopRenderTarget(0); -} - -CFlareSoftOcclusionQuery* CSoftOcclusionManager::GetSoftOcclusionQuery(int nIndex) const -{ - if (nIndex >= CFlareSoftOcclusionQuery::s_nIDMax) - { - return NULL; - } - return m_SoftOcclusionQueries[nIndex]; -} - -void CSoftOcclusionManager::AddSoftOcclusionQuery(CFlareSoftOcclusionQuery* pQuery, const Vec3& vPos) -{ - if (m_nPos < CFlareSoftOcclusionQuery::s_nIDMax) - { - pQuery->SetPosToBeChecked(vPos); - m_SoftOcclusionQueries[m_nPos++] = pQuery; - } -} - -bool CSoftOcclusionManager::Begin() -{ - if (GetSize() > 0) - { - m_bSuccessGenerateIB = GenerateIndexBuffer(); - return true; - } - return false; -} - -void CSoftOcclusionManager::End() -{ - m_nPos = 0; -} - -void CSoftOcclusionManager::ClearResources() -{ - for (int i = 0; i < CFlareSoftOcclusionQuery::s_nIDMax; ++i) - { - m_SoftOcclusionQueries[i] = NULL; - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.h b/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.h deleted file mode 100644 index ccdd30e35c..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/FlareSoftOcclusionQuery.h +++ /dev/null @@ -1,218 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H -#pragma once - -#include "IFlares.h" -#include "Cry_Vector2.h" -#include "Timeline.h" - -class CTexture; -class CShader; -class RootOpticsElement; - -class CSoftOcclusionVisiblityFader -{ -public: - CSoftOcclusionVisiblityFader() - : m_fTargetVisibility(-1.0f) - , m_fVisibilityFactor(1.0f) - { - } - - float UpdateVisibility(const float newTargetVisibility, const float duration); - - TimelineFloat m_TimeLine; - float m_fTargetVisibility; - float m_fVisibilityFactor; -}; - -class CFlareSoftOcclusionQuery - : public ISoftOcclusionQuery -{ -public: - static const int s_nIDColMax = 32; - static const int s_nIDRowMax = 32; - static const int s_nIDMax = s_nIDColMax * s_nIDRowMax; - - static const int s_nGatherEachSectorWidth = 8; - static const int s_nGatherEachSectorHeight = 8; - - static const int s_nGatherTextureWidth = s_nGatherEachSectorWidth * s_nIDColMax; - static const int s_nGatherTextureHeight = s_nGatherEachSectorHeight * s_nIDRowMax; - - static const float s_fSectorWidth; - static const float s_fSectorHeight; - -private: - static int s_idCount; - static char s_idHashTable[s_nIDMax]; - static unsigned char s_paletteRawCache[s_nIDMax * 4]; - - static int s_ringReadIdx; - static int s_ringWriteIdx; - static int s_ringSize; - -private: - static int GenID(); - static void ReleaseID(int id); - -public: - CFlareSoftOcclusionQuery(const uint8 numFaders = 0) - : m_fOccPlaneWidth(0.02f) - , m_fOccPlaneHeight(0.02f) - , m_PosToBeChecked(0, 0, 0) - , m_fOccResultCache(1) - , m_numVisibilityFaders(numFaders) - , m_pVisbilityFaders(NULL) - , m_refCount(1) - { - InitGlobalResources(); - m_nID = GenID(); - if (m_numVisibilityFaders > 0) - { - m_pVisbilityFaders = new CSoftOcclusionVisiblityFader[m_numVisibilityFaders]; - } - } - - ~CFlareSoftOcclusionQuery() - { - CRY_ASSERT(m_refCount == 0); - ReleaseID(m_nID); - m_numVisibilityFaders = 0; - SAFE_DELETE_ARRAY(m_pVisbilityFaders); - } - - // Manage multi-thread references - virtual void AddRef() - { - CryInterlockedIncrement(&m_refCount); - } - - virtual void Release() - { - if (CryInterlockedDecrement(&m_refCount) <= 0) - { - delete this; - } - } - - static void InitGlobalResources(); - static void BatchReadResults(); - static void ReadbackSoftOcclQuery(); - static CTexture* GetOcclusionTex(); - - void GetDomainInTexture(float& out_x0, float& out_y0, float& out_x1, float& out_y1); - void GetSectorSize(float& width, float& height); - - struct SOcclusionSectorInfo - { - float x0, y0, x1, y1; - float u0, v0, u1, v1; - float lineardepth; - }; - void GetOcclusionSectorInfo(SOcclusionSectorInfo& out_occlusionSector); - - void UpdateCachedResults(); - int GetID() - { - return m_nID; - } - float GetVisibility() const - { - return m_fOccResultCache; - } - float GetOccResult() const { return m_fOccResultCache; } - float GetDirResult() const { return m_fDirResultCache; } - const Vec2& GetDirVecResult() const {return m_DirVecResultCache; } - bool IsVisible() const { return m_fOccResultCache > 0; } - void SetPosToBeChecked(const Vec3& vPos) - { - m_PosToBeChecked = vPos; - } - - CSoftOcclusionVisiblityFader* GetVisibilityFader(const uint8 index) const - { - return (m_pVisbilityFaders && index < m_numVisibilityFaders) ? &m_pVisbilityFaders[index] : NULL; - } - - void SetOccPlaneSizeRatio(const Vec2& vRatio) { m_fOccPlaneWidth = vRatio.x; m_fOccPlaneHeight = vRatio.y; } - float GetOccPlaneWidth() const { return m_fOccPlaneWidth; } - float GetOccPlaneHeight() const { return m_fOccPlaneHeight; } - - CTexture* GetGatherTexture() const; - - static bool ComputeProjPos(const Vec3& vWorldPos, const Matrix44A& viewMat, const Matrix44A& projMat, Vec3& outProjPos); - static float ComputeLinearDepth(const Vec3& worldPos, const Matrix44A& cameraMat, float nearDist, float farDist); - -private: - uint8 m_numVisibilityFaders; - CSoftOcclusionVisiblityFader* m_pVisbilityFaders; - - int m_nID; - - float m_fOccResultCache; - float m_fDirResultCache; - Vec2 m_DirVecResultCache; - - Vec3 m_PosToBeChecked; - - float m_fOccPlaneWidth; - float m_fOccPlaneHeight; - - volatile int m_refCount; -}; - -class CSoftOcclusionManager -{ -public: - - CSoftOcclusionManager() - { - m_nPos = 0; - m_IndexBufferOffset = 0; - m_IndexBufferCount = 0; - m_bSuccessGenerateIB = false; - } - - void AddSoftOcclusionQuery(CFlareSoftOcclusionQuery* pQuery, const Vec3& vPos); - - bool Begin(); - void End(); - - int GetSize() - { - return m_nPos; - } - - CFlareSoftOcclusionQuery* GetSoftOcclusionQuery(int nIndex) const; - - void GatherOcclusions(); - void ComputeVisibility(); - - void ClearResources(); -private: - - bool GenerateIndexBuffer(); - - bool m_bSuccessGenerateIB; - uint32 m_IndexBufferOffset; - uint32 m_IndexBufferCount; - - int m_nPos; - _smart_ptr m_SoftOcclusionQueries[CFlareSoftOcclusionQuery::s_nIDMax]; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_FLARESOFTOCCLUSIONQUERY_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Ghost.cpp b/Code/CryEngine/RenderDll/Common/RendElements/Ghost.cpp deleted file mode 100644 index cc4d25e31c..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Ghost.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "Ghost.h" -#include "MeshUtil.h" -#include "../Textures/TextureManager.h" - -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&CLensGhost::FUNC_NAME) -void CLensGhost::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - FuncVariableGroup ghostGroup; - ghostGroup.SetName("LensGhost", "Lens Ghost"); - ghostGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Texture", "The texture for lens ghosts", this, MFPtr(SetTexture), MFPtr(GetTexture))); - groups.push_back(ghostGroup); -} -#undef MFPtr -#endif - -void CLensGhost::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pLensGhost = pNode->findChild("LensGhost"); - if (pLensGhost) - { - const char* textureName(NULL); - if (pLensGhost->getAttr("Texture", &textureName)) - { - if (textureName && textureName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(textureName); - SetTexture((CTexture*)pTexture); - //Release this reference because we're no longer going to reference the texture from this pointer - if (pTexture) - { - pTexture->Release(); - } - } - } - } -} - -CTexture* CLensGhost::GetTexture() -{ - if (!m_pTex) - { - m_pTex = CTexture::ForName("EngineAssets/Textures/flares/ghost_grey.tif", FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - } - return m_pTex; -} - -void CLensGhost::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("Ghost"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - CD3D9Renderer* rd = gcpRendD3D; - - static CCryNameTSCRC pGhostTechName("Ghost"); - static CCryNameR texSizeName("baseTexSize"); - static CCryNameR tileInfoName("ghostTileInfo"); - - static STexState bilinearTS(FILTER_LINEAR, true); - bilinearTS.SetBorderColor(0); - bilinearTS.SetClampMode(TADDR_BORDER, TADDR_BORDER, TADDR_BORDER); - - shader->FXSetTechnique(pGhostTechName); - - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - ApplyOcclusionBokehFlag(shader); - shader->FXBeginPass(0); - - CTexture* tex = GetTexture() ? GetTexture() : CTextureManager::Instance()->GetBlackTexture(); - tex->Apply(0, CTexture::GetTexState(bilinearTS)); - - const Vec4 texSizeParam((float)tex->GetWidth(), (float)tex->GetHeight(), 0, 0); - shader->FXSetVSFloat(texSizeName, &texSizeParam, 1); - - if (m_globalOcclusionBokeh) - { - ApplyOcclusionPattern(shader); - } - else - { - CTextureManager::Instance()->GetBlackTexture()->Apply(5, CTexture::GetTexState(bilinearTS)); - } - - shader->FXSetVSFloat(tileInfoName, &m_vTileDefinition, 1); - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - - float x = computeMovementLocationX(vSrcProjPos); - float y = computeMovementLocationY(vSrcProjPos); - - rd->DrawQuad(x, y, x, y, m_globalColor, m_globalFlareBrightness); - shader->FXEndPass(); - - shader->FXEnd(); -} - - -const int CMultipleGhost::MAX_COUNT = 1000; - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&CMultipleGhost::FUNC_NAME) -void CMultipleGhost::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - FuncVariableGroup ghostGroup; - ghostGroup.SetName("MultiGhost", "Multi Ghost"); - ghostGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Texture", "The texture for lens ghosts", this, MFPtr(SetTexture), MFPtr(GetTexture))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_INT, "Count", "The number of ghosts", this, MFPtr(SetCount), MFPtr(GetCount), 0, static_cast(MAX_COUNT))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_INT, "Random Seed", "The Seed of random generator", this, MFPtr(SetRandSeed), MFPtr(GetRandSeed), -255.0f, 255.0f)); - ghostGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Scattering range", "The scattering range for sub ghosts", this, MFPtr(SetRange), MFPtr(GetRange))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "position factor", "multiplier of position", this, MFPtr(SetPositionFactor), MFPtr(GetPositionFactor))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "position offset", "offset of position", this, MFPtr(SetPositionOffset), MFPtr(GetPositionOffset))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "X-axis noise", "the noise of scattering on x-axis", this, MFPtr(SetXOffsetNoise), MFPtr(GetXOffsetNoise))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Y-axis noise", "the noise of scattering on y-axis", this, MFPtr(SetYOffsetNoise), MFPtr(GetYOffsetNoise))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size Variation", "The strength for size variation", this, MFPtr(SetSizeNoise), MFPtr(GetSizeNoise))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Brightness Variation", "The strength for brightness variation", this, MFPtr(SetBrightnessNoise), MFPtr(GetBrightnessNoise))); - ghostGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Color Variation", "The strength for color variation", this, MFPtr(SetColorNoise), MFPtr(GetColorNoise))); - groups.push_back(ghostGroup); -} -#undef MFPtr -#endif - -void CMultipleGhost::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pMultiGhostNode = pNode->findChild("MultiGhost"); - - if (pMultiGhostNode) - { - const char* textureName(NULL); - if (pMultiGhostNode->getAttr("Texture", &textureName)) - { - if (textureName && textureName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(textureName); - SetTexture((CTexture*)pTexture); - if (pTexture) - { - pTexture->Release(); - } - } - } - - int nCount(0); - if (pMultiGhostNode->getAttr("Count", nCount)) - { - SetCount(nCount); - } - - int nRandSeed(0); - if (pMultiGhostNode->getAttr("RandomSeed", nRandSeed)) - { - SetRandSeed(nRandSeed); - } - - Vec2 vRange(m_vRange); - if (pMultiGhostNode->getAttr("Scatteringrange", vRange)) - { - SetRange(vRange); - } - - Vec2 vPositionFactor(m_vPositionFactor); - if (pMultiGhostNode->getAttr("positionfactor", vPositionFactor)) - { - SetPositionFactor(vPositionFactor); - } - - Vec2 vPositionOffset(m_vPositionOffset); - if (pMultiGhostNode->getAttr("positionoffset", vPositionOffset)) - { - SetPositionOffset(vPositionOffset); - } - - float xOffsetNoise(m_fXOffsetNoise); - if (pMultiGhostNode->getAttr("X-axisnoise", xOffsetNoise)) - { - SetXOffsetNoise(xOffsetNoise); - } - - float yOffsetNoise(m_fYOffsetNoise); - if (pMultiGhostNode->getAttr("Y-axisnoise", yOffsetNoise)) - { - SetYOffsetNoise(yOffsetNoise); - } - - float fSizeNoise(m_fSizeNoise); - if (pMultiGhostNode->getAttr("SizeVariation", fSizeNoise)) - { - SetSizeNoise(fSizeNoise); - } - - float fBrightnessNoise(m_fBrightnessNoise); - if (pMultiGhostNode->getAttr("BrightnessVariation", fBrightnessNoise)) - { - SetBrightnessNoise(fBrightnessNoise); - } - - float fColorNoise(m_fColorNoise); - if (pMultiGhostNode->getAttr("ColorVariation", fColorNoise)) - { - SetColorNoise(fColorNoise); - } - } -} - -void CMultipleGhost::SetCount(int count) -{ - if (count < 0) - { - return; - } - m_nCount = min(count, MAX_COUNT); - RemoveAll(); - for (int i = 0; i < m_nCount; i++) - { - CLensGhost* ghost = new CLensGhost("SubGhost"); - ghost->SetAutoRotation(true); - ghost->SetAspectRatioCorrection(true); - ghost->SetOccBokehEnabled(true); - ghost->SetSensorSizeFactor(1); - ghost->SetSensorBrightnessFactor(1); - Add(ghost); - } - m_bContentDirty = true; -} - -void CMultipleGhost::GenGhosts(SAuxParams& aux) -{ - stable_rand::setSeed(GetRandSeed()); - - float rangeStart = m_vRange.x; - float rangeEnd = m_vRange.y; - float span = rangeEnd - rangeStart; - float halfXNoiseRange = span / 2 * m_fXOffsetNoise; - float halfYNoiseRange = span / 2 * m_fYOffsetNoise; - if ((uint)GetCount() != children.size()) - { - SetCount(GetCount()); - } - for (uint i = 0; i < children.size(); i++) - { - CLensGhost* ghost = (CLensGhost*)&*(children[i]); - ghost->SetTexture(GetTexture()); - Vec2 pos; - float axisPos = stable_rand::randPositive() * span + rangeStart; - pos.x = stable_rand::randUnit() * halfXNoiseRange + axisPos * m_vPositionFactor.x + m_vPositionOffset.x; - pos.y = stable_rand::randUnit() * halfYNoiseRange + axisPos * m_vPositionFactor.y + m_vPositionOffset.y; - ghost->SetMovement(pos); - ghost->SetSize(stable_rand::randBias(GetSizeNoise())); - ghost->SetBrightness(stable_rand::randBias(GetBrightnessNoise())); - ColorF variation(stable_rand::randBias(GetColorNoise()), stable_rand::randBias(GetColorNoise()), stable_rand::randBias(GetColorNoise())); - ghost->SetColor(variation); - - ghost->SetDynamicsEnabled(GetDynamicsEnabled()); - ghost->SetDynamicsInvert(GetDynamicsInvert()); - ghost->SetDynamicsOffset(GetDynamicsOffset()); - ghost->SetDynamicsRange(GetDynamicsRange()); - } - validateChildrenGlobalVars(aux); - m_bContentDirty = false; -} - -void CMultipleGhost::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("MultiGhost"); - - if (m_bContentDirty) - { - GenGhosts(aux); - } - - COpticsGroup::Render(shader, vSrcWorldPos, vSrcProjPos, aux); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Ghost.h b/Code/CryEngine/RenderDll/Common/RendElements/Ghost.h deleted file mode 100644 index 2080ff87e7..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Ghost.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GHOST_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GHOST_H -#pragma once - -#include "OpticsElement.h" -#include "OpticsGroup.h" - -class CLensGhost - : public COpticsElement -{ - _smart_ptr m_pTex; - Vec4 m_vTileDefinition; - -protected: -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - -public: - - CLensGhost(const char* name, CTexture* externalTex = NULL) - : COpticsElement(name) - , m_pTex(externalTex) - { - } - - virtual IOpticsElementBase* Clone() - { - return new CLensGhost(*this); - } - - EFlareType GetType() { return eFT_Ghost; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - CTexture* GetTexture(); - void SetTexture(CTexture* tex) { m_pTex = tex; } - - int GetTileIndex() { return (int)m_vTileDefinition.w; } - int GetTotalTileCount() { return (int)m_vTileDefinition.z; } - int GetTileCountX() { return (int)m_vTileDefinition.x; } - int GetTileCountY() { return (int)m_vTileDefinition.y; } - - void SetTileIndex(int idx) - { - if (idx >= 0 && idx <= GetTotalTileCount()) - { - m_vTileDefinition.w = (float)idx; - } - } - - void SetTileCountX(int n) - { - int totalCount = GetTotalTileCount(); - if (totalCount > n * GetTileCountY()) - { - totalCount = n * GetTileCountY(); - } - - SetTileDefinition(n, GetTileCountY(), totalCount, GetTileIndex()); - } - - void SetTileCountY(int n) - { - int totalCount = GetTotalTileCount(); - if (totalCount > GetTileCountX() * n) - { - totalCount = GetTileCountX() * n; - } - - SetTileDefinition(GetTileCountX(), n, totalCount, GetTileIndex()); - } - - void SetTotalTileCount(int t) - { - SetTileDefinition(GetTileCountX(), GetTileCountY(), t, GetTileIndex()); - } - - void SetTileDefinition(int countX, int countY, int totalCount, int index) - { - if (totalCount > countX * countY) - { - return; - } - - m_vTileDefinition.x = (float)countX; - m_vTileDefinition.y = (float)countY; - m_vTileDefinition.z = (float)totalCount; - m_vTileDefinition.w = (float)index; - } - - void SetTileDefinition(Vec4 df) - { - SetTileDefinition((int)df.x, (int)df.y, (int)df.z, (int)df.w); - } -}; - -class CMultipleGhost - : public COpticsGroup -{ -protected: - _smart_ptr m_pTex; - - Vec2 m_vRange; - float m_fXOffsetNoise; - float m_fYOffsetNoise; - Vec2 m_vPositionFactor; - Vec2 m_vPositionOffset; - int m_nCount; - int m_nRandSeed; - - float m_fSizeNoise; - float m_fBrightnessNoise; - float m_fColorNoise; - - bool m_bContentDirty : 1; - -protected: - void InitEditorParamGroups(AZStd::vector& groups); - -public: - CMultipleGhost(const char* name) - : COpticsGroup(name) - , m_nCount(0) - , m_nRandSeed(0) - , m_bContentDirty(true) - , m_fXOffsetNoise(0) - , m_fYOffsetNoise(0) - , m_fSizeNoise(0.4f) - , m_fColorNoise(0.3f) - , m_fBrightnessNoise(0.3f) - { - m_vRange.set(0.1f, 0.7f); - m_vPositionFactor.set(1, 1); - m_vPositionOffset.set(0, 0); - SetSize(0.04f); - SetBrightness(0.3f); - SetCount(20); - } - -public: - static const int MAX_COUNT; - - void GenGhosts(SAuxParams& aux); - - EFlareType GetType() { return eFT_MultiGhosts; } - bool IsGroup() const { return false; } - int GetElementCount() const { return 0; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - CTexture* GetTexture() const { return m_pTex; } - void SetTexture(CTexture* tex) - { - m_pTex = tex; - m_bContentDirty = true; - } - - float GetXOffsetNoise() const { return m_fXOffsetNoise; } - void SetXOffsetNoise(float x) - { - m_fXOffsetNoise = x; - m_bContentDirty = true; - } - - float GetYOffsetNoise() const { return m_fYOffsetNoise; } - void SetYOffsetNoise(float y) - { - m_fYOffsetNoise = y; - m_bContentDirty = true; - } - - Vec2 GetPositionFactor() const { return m_vPositionFactor; } - void SetPositionFactor(Vec2 positionFactor) - { - m_vPositionFactor = positionFactor; - m_bContentDirty = true; - } - - Vec2 GetPositionOffset() const { return m_vPositionOffset; } - void SetPositionOffset(Vec2 offsets) - { - m_vPositionOffset = offsets; - m_bContentDirty = true; - } - - Vec2 GetRange() const { return m_vRange; } - void SetRange(Vec2 range) - { - m_vRange = range; - m_bContentDirty = true; - } - - int GetCount() const { return m_nCount; } - void SetCount(int count); - - int GetRandSeed() const { return m_nRandSeed; } - void SetRandSeed(int n) - { - m_nRandSeed = n; - m_bContentDirty = true; - } - - float GetSizeNoise() const { return m_fSizeNoise; } - void SetSizeNoise(float n) - { - m_fSizeNoise = n; - m_bContentDirty = true; - } - - float GetBrightnessNoise() const { return m_fBrightnessNoise; } - void SetBrightnessNoise(float n) - { - m_fBrightnessNoise = n; - m_bContentDirty = true; - } - - float GetColorNoise() const { return m_fColorNoise; } - void SetColorNoise(float n) - { - m_fColorNoise = n; - m_bContentDirty = true; - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GHOST_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Glow.cpp b/Code/CryEngine/RenderDll/Common/RendElements/Glow.cpp deleted file mode 100644 index f01bacbc7c..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Glow.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "Glow.h" -#include "../Textures/Texture.h" -#include "../CryNameR.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&Glow::FUNC_NAME) -void Glow::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - - FuncVariableGroup glowGroup; - glowGroup.SetName("Glow"); - glowGroup.AddVariable(new OpticsMFPVariable(e_INT, "Polygon factor", "Polygons factor", this, MFPtr(SetPolygonFactor), MFPtr(GetPolygonFactor), 0, 128.0f)); - glowGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Focus factor", "Focus factor", this, MFPtr(SetFocusFactor), MFPtr(GetFocusFactor))); - glowGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Gamma", "Gamma", this, MFPtr(SetGamma), MFPtr(GetGamma))); - groups.push_back(glowGroup); -} -#undef MFPtr -#endif - -void Glow::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pGlowNode = pNode->findChild("Glow"); - if (pGlowNode) - { - int nPolygonFactor(0); - if (pGlowNode->getAttr("Polygonfactor", nPolygonFactor)) - { - SetPolygonFactor(nPolygonFactor); - } - - float fFocusFactor(m_fFocusFactor); - if (pGlowNode->getAttr("Focusfactor", fFocusFactor)) - { - SetFocusFactor(fFocusFactor); - } - - float fGamma(m_fGamma); - if (pGlowNode->getAttr("Gamma", fGamma)) - { - SetGamma(fGamma); - } - } -} - -void Glow::GenMesh() -{ - float ringPos = 1; - MeshUtil::GenDisk(m_fSize, (int)m_fPolyonFactor, 1, true, m_globalColor, &ringPos, m_vertBuf, m_idxBuf); -} - -void Glow::ApplyDistributionParamsPS(CShader* shader) -{ - static CCryNameR lumaParamsName("lumaParams"); - Vec4 lumaParams(m_fFocusFactor, m_fGamma, 0, 0); - shader->FXSetPSFloat(lumaParamsName, &lumaParams, 1); -} - -void Glow::DrawMesh() -{ - gcpRendD3D->FX_Commit(); - DrawMeshTriList(); -} - -void Glow::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("Glow"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - static CCryNameTSCRC pGlowTechName("Glow"); - shader->FXSetTechnique(pGlowTechName); - uint nPass; - - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - shader->FXBeginPass(0); - - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - ApplyExternTintAndBrightnessVS(shader, m_globalColor, m_globalFlareBrightness); - - static CCryNameR meshCenterName("meshCenterAndBrt"); - float x = computeMovementLocationX(vSrcProjPos); - float y = computeMovementLocationY(vSrcProjPos); - const Vec4 meshCenterParam(x, y, vSrcProjPos.z, 1); - shader->FXSetVSFloat(meshCenterName, &meshCenterParam, 1); - - ApplyDistributionParamsPS(shader); - - ValidateMesh(); - ApplyMesh(); - DrawMesh(); - - shader->FXEndPass(); - - shader->FXEnd(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Glow.h b/Code/CryEngine/RenderDll/Common/RendElements/Glow.h deleted file mode 100644 index aab57c5b06..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Glow.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GLOW_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GLOW_H -#pragma once - -#include "OpticsElement.h" -#include "AbstractMeshElement.h" -#include "MeshUtil.h" - -class Glow - : public COpticsElement - , public AbstractMeshElement -{ -private: - static float compositionBufRatio; - -protected: - float m_fFocusFactor; - float m_fPolyonFactor; - float m_fGamma; - -protected: - void ApplyDistributionParamsPS(CShader* shader); - virtual void GenMesh(); - void DrawMesh(); - void Invalidate() - { - m_meshDirty = true; - } - -public: - Glow(const char* name) - : COpticsElement(name) - , m_fFocusFactor(0.3f) - , m_fPolyonFactor(32.f) - , m_fGamma(1) - { - m_Color.a = 1.f; //Max alpha so that the ghost can be seen when it's created - } - - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - - EFlareType GetType() { return eFT_Glow; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - void SetColor(ColorF t) - { - COpticsElement::SetColor(t); - m_meshDirty = true; - } - float GetFocusFactor() const {return m_fFocusFactor; } - void SetFocusFactor(float f) - { - m_fFocusFactor = f; - } - int GetPolygonFactor() const { return (int)m_fPolyonFactor; } - void SetPolygonFactor(int f) - { - if (f < 0) - { - f = 0; - } - else if (f > 128) - { - f = 128; - } - if (m_fPolyonFactor != f) - { - m_fPolyonFactor = (float)f; - m_meshDirty = true; - } - } - float GetGamma() const { return m_fGamma; } - void SetGamma(float gamma) - { - m_fGamma = (float)gamma; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this) + GetMeshDataSize()); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_GLOW_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.cpp b/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.cpp deleted file mode 100644 index de35bf0c45..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ImageSpaceShafts.h" -#include "FlareSoftOcclusionQuery.h" -#include "../CryNameR.h" -#include "Common/Textures/TextureManager.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -CTexture* ImageSpaceShafts::m_pOccBuffer = NULL; -CTexture* ImageSpaceShafts::m_pDraftBuffer = NULL; - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&ImageSpaceShafts::FUNC_NAME) -void ImageSpaceShafts::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - FuncVariableGroup isShaftsGroup; - isShaftsGroup.SetName("ImageSpaceShafts", "Image Space Shafts"); - isShaftsGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "High Quality", "Enable High quality mode", this, MFPtr(SetHighQualityMode), MFPtr(IsHighQualityMode))); - isShaftsGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Gobo Tex", "Gobo texture", this, MFPtr(SetGoboTex), MFPtr(GetGoboTex))); - groups.push_back(isShaftsGroup); -} -#undef MFPtr -#endif - -void ImageSpaceShafts::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pImageSpaceNode = pNode->findChild("ImageSpaceShafts"); - if (pImageSpaceNode) - { - bool bHighQualityMode(m_bHighQualityMode); - if (pImageSpaceNode->getAttr("HighQuality", bHighQualityMode)) - { - SetHighQualityMode(bHighQualityMode); - } - else - { - assert(0); - } - - const char* pGoboTexName = NULL; - if (pImageSpaceNode->getAttr("GoboTex", &pGoboTexName)) - { - if (pGoboTexName && pGoboTexName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(pGoboTexName); - SetGoboTex((CTexture*)pTexture); - //Release this reference because we're no longer going to reference the texture from this pointer - if (pTexture) - { - pTexture->Release(); - } - } - } - else - { - assert(0); - } - } - else - { - assert(0); - } -} - -CTexture* ImageSpaceShafts::GetGoboTex() -{ - if (!m_pGoboTex) - { - m_pGoboTex = CTexture::ForName("EngineAssets/Textures/flares/iris_shaft.tif", FT_DONT_STREAM, eTF_Unknown); - } - return m_pGoboTex; -} - -void ImageSpaceShafts::InitTextures() -{ - float occBufRatio, occDraftRatio, occFinalRatio; - if (m_bHighQualityMode && CRenderer::CV_r_flareHqShafts) - { - occBufRatio = 0.5f; - occDraftRatio = 0.5f; - occFinalRatio = 0.5f; - } - else - { - occBufRatio = 0.25f; - occDraftRatio = 0.4f; - occFinalRatio = 0.45f; - } - - int w = gcpRendD3D->GetWidth(); - int h = gcpRendD3D->GetHeight(); - int flag = FT_DONT_RELEASE | FT_DONT_STREAM; - m_pOccBuffer = CTexture::CreateRenderTarget("$ImageSpaceShaftsOccBuffer", (int)(w * occBufRatio), (int)(h * occBufRatio), Clr_Empty, eTT_2D, flag, eTF_R8G8B8A8); - - ETEX_Format draftTexFormat(eTF_R16G16B16A16); - - m_pDraftBuffer = CTexture::CreateRenderTarget("$ImageSpaceShaftsDraftBuffer", (int)(w * occDraftRatio), (int)(h * occDraftRatio), Clr_Empty, eTT_2D, flag, draftTexFormat); - - m_bTexDirty = false; -} - -static STexState s_isPointTS(FILTER_POINT, true); -static STexState s_isBilinearTS(FILTER_BILINEAR, true); - -void ImageSpaceShafts::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - CD3D9Renderer* rd = gcpRendD3D; - - if (!m_pOccBuffer || m_bTexDirty) - { - InitTextures(); - } - - PROFILE_LABEL_SCOPE("ImagesSpaceShafts"); - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - - static CCryNameTSCRC pImageSpaceShaftsTechName("ImageSpaceShafts"); - shader->FXSetTechnique(pImageSpaceShaftsTechName); - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - static CCryNameR texSizeName("baseTexSize"); - - Vec4 texSizeParam(1, 1, 0, 0); - - { - PROFILE_LABEL_SCOPE("ImagesSpaceShafts-Occ"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - rd->FX_ClearTarget(m_pOccBuffer, Clr_Empty); - rd->FX_PushRenderTarget(0, m_pOccBuffer, NULL, -1, false); - - ApplyGeneralFlags(shader); - shader->FXBeginPass(0); - - CTexture* pGoboTex = ((CTexture*)m_pGoboTex) ? ((CTexture*)m_pGoboTex) : CTextureManager::Instance()->GetBlackTexture(); - pGoboTex->Apply(0, CTexture::GetTexState(s_isBilinearTS)); - CTexture::s_ptexZTargetScaled->Apply(1, CTexture::GetTexState(s_isBilinearTS)); - - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - shader->FXSetVSFloat(texSizeName, &texSizeParam, 1); - - rd->DrawQuad(vSrcProjPos.x, vSrcProjPos.y, vSrcProjPos.x, vSrcProjPos.y, m_globalColor, aux.linearDepth); - shader->FXEndPass(); - - rd->FX_PopRenderTarget(0); - } - - { - PROFILE_LABEL_SCOPE("ImagesSpaceShafts-Gen"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - rd->FX_ClearTarget(m_pDraftBuffer, Clr_Empty); - rd->FX_PushRenderTarget(0, m_pDraftBuffer, NULL, -1, false); - - ApplyGeneralFlags(shader); - shader->FXBeginPass(1); - - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - shader->FXSetVSFloat(texSizeName, &texSizeParam, 1); - m_pOccBuffer->Apply(1, CTexture::GetTexState(s_isBilinearTS)); - - rd->DrawQuad(vSrcProjPos.x, vSrcProjPos.y, vSrcProjPos.x, vSrcProjPos.y, m_globalColor, m_globalShaftBrightness); - shader->FXEndPass(); - - rd->FX_PopRenderTarget(0); - } - - { - PROFILE_LABEL_SCOPE("ImagesSpaceShafts-BLEND"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - m_pDraftBuffer->Apply(1, CTexture::GetTexState(s_isBilinearTS)); - - shader->FXBeginPass(2); - rd->DrawQuad(0, 0, 0, 0, m_globalColor, m_globalShaftBrightness); - shader->FXEndPass(); - } - - shader->FXEnd(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.h b/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.h deleted file mode 100644 index 247322d8a8..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/ImageSpaceShafts.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IMAGESPACESHAFTS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IMAGESPACESHAFTS_H -#pragma once - -#include "OpticsElement.h" - -class CTexture; -class CD3D9Renderer; - -class ImageSpaceShafts - : public COpticsElement -{ -protected: - static CTexture* m_pOccBuffer; - static CTexture* m_pDraftBuffer; - -protected: - bool m_bHighQualityMode; - bool m_bTexDirty; - _smart_ptr m_pGoboTex; - - virtual void InitTextures(); - -public: - - ImageSpaceShafts(const char* name) - : COpticsElement(name) - , m_bTexDirty(true) - , m_bHighQualityMode(false) - { - m_Color.a = 1.f; - SetSize(0.7f); - } - - EFlareType GetType() { return eFT_ImageSpaceShafts; } - - void InitEditorParamGroups(AZStd::vector& groups); - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - bool IsHighQualityMode() const { return m_bHighQualityMode; } - void SetHighQualityMode(bool b) { m_bHighQualityMode = b; m_bTexDirty = true; } - - CTexture* GetGoboTex(); - void SetGoboTex(CTexture* tex) { m_pGoboTex = tex; } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IMAGESPACESHAFTS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Interpolator.h b/Code/CryEngine/RenderDll/Common/RendElements/Interpolator.h deleted file mode 100644 index c2fa0f844f..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Interpolator.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -// Interpolator deals with animations' interpolation. -// These are bare bones interpolators: they take 3 key values as inputs. -// The first two specify the two end points(start and end), and the last one specify the interpolation tweenness (x-value). -// The output is the y-value. -// For additional time-based playback type animation, see Timeline. - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_INTERPOLATOR_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_INTERPOLATOR_H -#pragma once - -template -class Interpolator -{ -protected: - virtual T mix(T v0, T v1, float mixRatio) - { - return (T)(v0 * (1 - mixRatio) + v1 * mixRatio); - } -public: - virtual ~Interpolator(){} - virtual T compute(T start, T end, float xValue) = 0; -}; - -template -class LinearInterp - : public Interpolator -{ -public: - virtual T compute(T start, T end, float xValue) - { - return Interpolator::mix(start, end, xValue); - } -}; - -template -class CubicInterp - : public Interpolator -{ -public: - virtual T compute(T start, T end, float xValue) - { - float x = xValue * xValue * (3 - 2 * xValue); - return Interpolator::mix(start, end, x); - } -}; - -namespace InterpPredef -{ - static LinearInterp Linear_FLOAT; - static LinearInterp Linear_INT; - - static CubicInterp CUBIC_FLOAT; - static CubicInterp CUBIC_INT; -} -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_INTERPOLATOR_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.cpp b/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.cpp deleted file mode 100644 index 3c7f10b9b4..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "IrisShafts.h" -#include "RootOpticsElement.h" -#include "FlareSoftOcclusionQuery.h" -#include "../CryNameR.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" -#include "../Common/Textures/TextureManager.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&IrisShafts::FUNC_NAME) -void IrisShafts::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - FuncVariableGroup irisGroup; - irisGroup.SetName("IrisShafts", "Iris Shafts"); - irisGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable gradient tex", "Enable gradient texture", this, MFPtr(SetEnableSpectrumTex), MFPtr(GetEnableSpectrumTex))); - irisGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Base Tex", "Basic Texture", this, MFPtr(SetBaseTex), MFPtr(GetBaseTex))); - irisGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Gradient Tex", "Gradient Texture", this, MFPtr(SetSpectrumTex), MFPtr(GetSpectrumTex))); - irisGroup.AddVariable(new OpticsMFPVariable(e_INT, "Noise seed", "Noise seed", this, MFPtr(SetNoiseSeed), MFPtr(GetNoiseSeed), -255.0f, 255.0f)); - irisGroup.AddVariable(new OpticsMFPVariable(e_INT, "Complexity", "Complexity of shafts", this, MFPtr(SetComplexity), MFPtr(GetComplexity), 0, 1000.0f)); - irisGroup.AddVariable(new OpticsMFPVariable(e_INT, "Smoothness", "The level of smoothness", this, MFPtr(SetSmoothLevel), MFPtr(GetSmoothLevel), 0, 255.0f)); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Thickness", "Thickness of the shafts", this, MFPtr(SetThickness), MFPtr(GetThickness), 0, 255.0f)); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Thickness noise", "Noise strength of thickness variation", this, MFPtr(SetThicknessNoise), MFPtr(GetThicknessNoise))); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Spread", "Spread of the shafts", this, MFPtr(SetSpread), MFPtr(GetSpread))); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Spread noise", "Noise strength of spread variation", this, MFPtr(SetSpreadNoise), MFPtr(GetSpreadNoise))); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size noise", "Noise strength of shafts' sizes", this, MFPtr(SetSizeNoise), MFPtr(GetSizeNoise))); - irisGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Spacing noise", "Noise strength of shafts' spacing", this, MFPtr(SetSpacingNoise), MFPtr(GetSpacingNoise))); - groups.push_back(irisGroup); -} -#undef MFPtr -#endif - -void IrisShafts::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pIrisShaftsNode = pNode->findChild("IrisShafts"); - - if (pIrisShaftsNode) - { - bool bUseSpectrumTex(m_bUseSpectrumTex); - if (pIrisShaftsNode->getAttr("Enablegradienttex", bUseSpectrumTex)) - { - SetEnableSpectrumTex(bUseSpectrumTex); - } - - const char* baseTextureName = NULL; - if (pIrisShaftsNode->getAttr("BaseTex", &baseTextureName)) - { - if (baseTextureName && baseTextureName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(baseTextureName); - SetBaseTex((CTexture*)pTexture); - //Release this reference because we're no longer going to reference the texture from this pointer - if (pTexture) - { - pTexture->Release(); - } - } - } - - const char* gradientTexName = NULL; - if (pIrisShaftsNode->getAttr("GradientTex", &gradientTexName)) - { - if (gradientTexName && gradientTexName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(gradientTexName); - SetSpectrumTex((CTexture*)pTexture); - //Release this reference because we're no longer going to reference the texture from this pointer - if (pTexture) - { - pTexture->Release(); - } - } - } - - int nNoiseSeed(m_nNoiseSeed); - if (pIrisShaftsNode->getAttr("Noiseseed", nNoiseSeed)) - { - SetNoiseSeed(nNoiseSeed); - } - - int nComplexity(m_nComplexity); - if (pIrisShaftsNode->getAttr("Complexity", nComplexity)) - { - SetComplexity(nComplexity); - } - - int nSmoothLevel(m_nSmoothLevel); - if (pIrisShaftsNode->getAttr("Smoothness", nSmoothLevel)) - { - SetSmoothLevel(nSmoothLevel); - } - - float fThickness(m_fThickness); - if (pIrisShaftsNode->getAttr("Thickness", fThickness)) - { - SetThickness(fThickness); - } - - float fThicknessNoise(m_fThicknessNoiseStrength); - if (pIrisShaftsNode->getAttr("Thicknessnoise", fThicknessNoise)) - { - SetThicknessNoise(fThicknessNoise); - } - - float fSpread(m_fSpread); - if (pIrisShaftsNode->getAttr("Spread", fSpread)) - { - SetSpread(fSpread); - } - - float fThicknessNoiseStrength(m_fThicknessNoiseStrength); - if (pIrisShaftsNode->getAttr("Spreadnoise", fThicknessNoiseStrength)) - { - SetSpreadNoise(fThicknessNoiseStrength); - } - - float fSizeNoiseStrength(m_fSizeNoiseStrength); - if (pIrisShaftsNode->getAttr("Sizenoise", fSizeNoiseStrength)) - { - SetSizeNoise(fSizeNoiseStrength); - } - - float fSpacingNoiseStrength(m_fSpacingNoiseStrength); - if (pIrisShaftsNode->getAttr("Spacingnoise", fSpacingNoiseStrength)) - { - SetSpacingNoise(fSpacingNoiseStrength); - } - } -} - -float IrisShafts::ComputeSpreadParameters(const float spread) -{ - return spread * 75; -} - -int IrisShafts::ComputeDynamicSmoothLevel(int maxLevel, float spanAngle, float threshold) -{ - return min(maxLevel, (int)(spanAngle / threshold)); -} - -void IrisShafts::GenMesh() -{ - stable_rand::setSeed((int)(m_nNoiseSeed * m_fConcentrationBoost)); - - float dirDelta = 1.0f / (float)m_nComplexity; - float halfAngleRange = m_fAngleRange / 2; - ColorF color(1, 1, 1, 1); - - m_vertBuf.clear(); - m_idxBuf.clear(); - - std::vector randomTable; - randomTable.resize(m_nComplexity); - for (int i = 0; i < m_nComplexity; ++i) - { - randomTable[i] = i; - } - for (int i = 0; i < m_nComplexity; ++i) - { - std::swap(randomTable[(int)(stable_rand::randPositive() * m_nComplexity)], randomTable[(int)(stable_rand::randPositive() * m_nComplexity)]); - } - - for (int i = 0; i < m_nComplexity; i++) - { - float spacingNoise = 1 + stable_rand::randUnit() * m_fSpacingNoiseStrength; - - float dirDiff; - if (m_fConcentrationBoost > 1.f && randomTable[i] == m_nComplexity / 2) - { - dirDiff = dirDelta * spacingNoise * 0.05f; - } - else - { - dirDiff = m_fAngleRange * fmod((randomTable[i] * dirDelta + spacingNoise), 1.0f) - halfAngleRange; - } - float dirUnit = m_fPrimaryDir + dirDiff; - float dir = 360 * dirUnit; - - float dirDiffRatio = fabs(dirDiff) / m_fAngleRange; - float sizeBoost = 1 + (m_fConcentrationBoost - 1) * (-1.75f * dirDiffRatio + 2.f); // From center to edge: 2->0.25 - float brightnessBoost = 1 + (m_fConcentrationBoost - 1) * (1 / (15 * (dirDiffRatio + 0.02f)) - 1); // from center to edge: 2.333->-0.994 - - color.a = brightnessBoost; - float size = sizeBoost * (1 + stable_rand::randUnit() * m_fSizeNoiseStrength); - float thickness = m_fThickness * (1 + stable_rand::randUnit() * m_fThicknessNoiseStrength); - float spread = m_fSpread * (1 + stable_rand::randUnit() * m_fSpreadNoiseStrength); - float halfAngle = ComputeSpreadParameters(spread); - int dynSmoothLevel = ComputeDynamicSmoothLevel(m_nSmoothLevel, halfAngle * 2, 1); - if (dynSmoothLevel <= 1) - { - continue; - } - - std::vector vertices; - std::vector indices; - MeshUtil::GenShaft(size, thickness, dynSmoothLevel, dir - halfAngle, dir + halfAngle, color, vertices, indices); - - int generatedPolyonNum = (int)(indices.size() + m_idxBuf.size()) / 3; - if (CRenderer::CV_r_FlaresIrisShaftMaxPolyNum != 0 && generatedPolyonNum > CRenderer::CV_r_FlaresIrisShaftMaxPolyNum) - { - break; - } - - int indexOffset = m_vertBuf.size(); - m_vertBuf.insert(m_vertBuf.end(), vertices.begin(), vertices.end()); - - for (int k = 0, iIndexSize(indices.size()); k < iIndexSize; ++k) - { - m_idxBuf.push_back(indices[k] + indexOffset); - } - } -} - -void IrisShafts::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("IrisShafts"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - static CCryNameTSCRC pIrisShaftsTechName("IrisShafts"); - shader->FXSetTechnique(pIrisShaftsTechName); - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - ApplySpectrumTexFlag(shader, m_bUseSpectrumTex); - shader->FXBeginPass(0); - - if (m_globalOcclusionBokeh) - { - RootOpticsElement* root = GetRoot(); - CFlareSoftOcclusionQuery* occQuery = root->GetOcclusionQuery(); - float occ = occQuery->GetOccResult(); - float interpOcc = root->GetShaftVisibilityFactor(); - - if (occ >= 0.05f && fabs(m_fPrevOcc - occ) > 0.01f) - { - m_fAngleRange = 0.65f * occ * occ + 0.35f; - m_fPrimaryDir = occQuery->GetDirResult() / (2 * PI); - m_fConcentrationBoost = 2.0f - occ; - m_fBrightnessBoost = aznumeric_cast(1 + 2 * pow(occ - 1, 6)); - - m_meshDirty = true; - m_fPrevOcc = occ; - } - else if (occ < 0.05f) - { - m_fAngleRange = 0.33f; - m_fBrightnessBoost = aznumeric_cast(1 + 2 * pow(interpOcc - 1, 6)); - m_fPrevOcc = 0; - m_meshDirty = true; - } - } - else - { - if (m_fAngleRange < 0.999f) - { - m_meshDirty = true; - } - m_fPrimaryDir = 0; - m_fAngleRange = 1; - m_fConcentrationBoost = 1; - m_fBrightnessBoost = 1; - } - - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - ApplyExternTintAndBrightnessVS(shader, m_globalColor, m_globalFlareBrightness); - - static CCryNameR meshCenterName("meshCenterAndBrt"); - const float x = computeMovementLocationX(vSrcProjPos); - const float y = computeMovementLocationY(vSrcProjPos); - const Vec4 meshCenterParam(x, y, vSrcProjPos.z, 1); - shader->FXSetVSFloat(meshCenterName, &meshCenterParam, 1); - - static STexState bilinearTS(FILTER_LINEAR, true); - bilinearTS.SetBorderColor(0); - bilinearTS.SetClampMode(TADDR_BORDER, TADDR_BORDER, TADDR_BORDER); - - CTexture* pBaseTex = ((CTexture*)m_pBaseTex) ? ((CTexture*)m_pBaseTex) : CTextureManager::Instance()->GetBlackTexture(); - pBaseTex->Apply(1, CTexture::GetTexState(bilinearTS)); - - CTexture* pSpectrumTex = (m_bUseSpectrumTex && ((CTexture*)m_pSpectrumTex)) ? ((CTexture*)m_pSpectrumTex) : CTextureManager::Instance()->GetBlackTexture(); - pSpectrumTex->Apply(0, CTexture::GetTexState(bilinearTS)); - - if (m_MaxNumberOfPolygon != CRenderer::CV_r_FlaresIrisShaftMaxPolyNum) - { - m_meshDirty = true; - m_MaxNumberOfPolygon = CRenderer::CV_r_FlaresIrisShaftMaxPolyNum; - } - - ValidateMesh(); - - ApplyMesh(); - DrawMeshTriList(); - - shader->FXEndPass(); - - shader->FXEnd(); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.h b/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.h deleted file mode 100644 index bf147d2ba5..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/IrisShafts.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IRISSHAFTS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IRISSHAFTS_H -#pragma once - -#include "OpticsElement.h" -#include "AbstractMeshElement.h" -#include "MeshUtil.h" - -class CTexture; -class IrisShafts - : public COpticsElement - , public AbstractMeshElement -{ -private: - _smart_ptr m_pBaseTex; - _smart_ptr m_pSpectrumTex; - bool m_bUseSpectrumTex : 1; - - int m_nComplexity; - int m_nSmoothLevel; - int m_nColorComplexity; - - float m_fPrevOcc; - float m_fPrimaryDir; - float m_fAngleRange; - float m_fConcentrationBoost; - float m_fBrightnessBoost; - - float m_fSizeNoiseStrength; - float m_fThicknessNoiseStrength; - float m_fSpreadNoiseStrength; - float m_fSpacingNoiseStrength; - - float m_fSpread; - float m_fThickness; - int m_nNoiseSeed; - - int m_MaxNumberOfPolygon; - -protected: - virtual void GenMesh(); - float ComputeSpreadParameters(const float thickness); - int ComputeDynamicSmoothLevel(int maxLevel, float spanAngle, float threshold); - void Invalidate() - { - m_meshDirty = true; - } - -public: - IrisShafts (const char* name) - : COpticsElement(name, 0.5f) - , m_fThickness(0.3f) - , m_fSpread(0.2f) - , m_nSmoothLevel(2) - , m_nNoiseSeed(81) - , m_pBaseTex(0) - , m_fSizeNoiseStrength(0.8f) - , m_fThicknessNoiseStrength(0.6f) - , m_fSpacingNoiseStrength(0.2f) - , m_fSpreadNoiseStrength(0.0f) - , m_bUseSpectrumTex(false) - , m_fPrimaryDir(0) - , m_fAngleRange(1) - , m_fConcentrationBoost(0) - , m_fPrevOcc(-1.f) - , m_fBrightnessBoost(0) - , m_MaxNumberOfPolygon(0) - { - m_vMovement.x = 1.f; - m_vMovement.y = 1.f; - m_Color.a = 1.f; - - m_pBaseTex = CTexture::ForName("EngineAssets/Textures/flares/iris_shaft.dds", FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - - SetAutoRotation(false); - SetAspectRatioCorrection(true); - SetColorComplexity(2); - SetComplexity(32); - - m_meshDirty = true; - } - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - - EFlareType GetType() { return eFT_IrisShafts; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - bool GetEnableSpectrumTex() const { return m_bUseSpectrumTex; } - void SetEnableSpectrumTex(bool b) { m_bUseSpectrumTex = b; } - - CTexture* GetSpectrumTex() const { return m_pSpectrumTex; } - void SetSpectrumTex(CTexture* tex) { m_pSpectrumTex = tex; } - - CTexture* GetBaseTex() const { return m_pBaseTex; } - void SetBaseTex(CTexture* tex) { m_pBaseTex = tex; } - - int GetNoiseSeed() const { return m_nNoiseSeed; } - void SetNoiseSeed(int seed) - { - m_nNoiseSeed = seed; - m_meshDirty = true; - } - - int GetComplexity() const { return m_nComplexity; } - void SetComplexity(int n) - { - m_nComplexity = n; - m_meshDirty = true; - } - - int GetColorComplexity() const { return m_nColorComplexity; } - void SetColorComplexity(int n) - { - m_nColorComplexity = n; - m_meshDirty = true; - } - - int GetSmoothLevel() const { return m_nSmoothLevel; } - void SetSmoothLevel(int n) - { - m_nSmoothLevel = n; - m_meshDirty = true; - } - - float GetThickness() const { return m_fThickness; } - void SetThickness(float f) - { - m_fThickness = f; - m_meshDirty = true; - } - - float GetSpread() const { return m_fSpread; } - void SetSpread(float s) - { - m_fSpread = s; - m_meshDirty = true; - } - - float GetThicknessNoise() const { return m_fThicknessNoiseStrength; } - void SetThicknessNoise(float noise) - { - m_fThicknessNoiseStrength = noise; - m_meshDirty = true; - } - - float GetSpreadNoise() const { return m_fSpreadNoiseStrength; } - void SetSpreadNoise(float noise) - { - m_fThicknessNoiseStrength = noise; - m_meshDirty = true; - } - - float GetSizeNoise() const { return m_fSizeNoiseStrength; } - void SetSizeNoise(float noise) - { - m_fSizeNoiseStrength = noise; - m_meshDirty = true; - } - - float GetSpacingNoise() const { return m_fSpacingNoiseStrength; } - void SetSpacingNoise(float noise) - { - m_fSpacingNoiseStrength = noise; - m_meshDirty = true; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this) + GetMeshDataSize()); - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_IRISSHAFTS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.cpp b/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.cpp deleted file mode 100644 index e329d3f8ef..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.cpp +++ /dev/null @@ -1,578 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "MeshUtil.h" -#include "../../../CryCommon/VertexFormats.h" -#include "../../../CryCommon/MTPseudoRandom.h" - -using namespace stable_rand; - -CMTRand_int32 randGen; -void stable_rand::setSeed(uint32 seed) {randGen.seed(seed); } -float stable_rand::randUnit() { return randGen.GenerateFloat() * 2.f - 1.f; } -float stable_rand::randPositive() { return randGen.GenerateFloat(); } -float stable_rand::randBias(float noise) { return 1.f + randUnit() * noise; } - -float computeFade(float current, float start, float end, float fadingLength) -{ - if (current < start - fadingLength) - { - return 0; - } - else if (current < start) - { - return 1 - (start - current) / fadingLength; - } - else if (current > end + fadingLength) - { - return 0; - } - else if (current > end) - { - return 1 - (current - end) / fadingLength; - } - else - { - return 1; - } -} - -Vec2 rotate(float x, float y, float rad) -{ - Vec2 ret; - float cosRad = cos(rad); - float sinRad = sin(rad); - ret.x = x * cosRad - y * sinRad; - ret.y = y * cosRad + x * sinRad; - return ret; -} - -void MeshUtil::GenDisk([[maybe_unused]] float radius, int polySides, int ringCount, bool capInnerHole, const ColorF& clr, float* ringPosArray, std::vector& vertOut, std::vector& idxOut) -{ - bool gCollectPosArray = false; - if (ringPosArray == NULL) - { - // create a uniformly spaced setting - ringPosArray = new float[ringCount]; - float ringCountf = (float)ringCount; - for (int i = 0; i < ringCount; i++) - { - ringPosArray[i] = (i + 1) / ringCountf; - } - gCollectPosArray = true; - } - - // Current strategy: whether or not capping, center pivot is always generated only not indexed in later case. - // UV mapping follows polar representation: u for thou, v for theta - DWORD dclr = clr.pack_argb8888(); - vertOut.resize(polySides * ringCount + 1); // rings and the center - - SVF_P3F_C4B_T2F& centerV = vertOut[0]; - centerV.xyz = Vec3(0, 0, 0); - centerV.st = Vec2(0, 0); - centerV.color.dcolor = dclr; - - // Generate all vertices starting from inner rings: - for (int i = 0; i < polySides; i++) - { - float theta = i / (float)polySides; - float angle = 2 * PI * theta; - float x = cos(angle); - float y = sin(angle); - //float noise = randUnit() * noiseStrength; - - for (int r = 0; r < ringCount; r++) - { - float curRingRadius = ringPosArray[r]; - float thou = (r + 1) / (float)(ringCount); - //curRingRadius += noise; // apply translation noise - - SVF_P3F_C4B_T2F& vert = vertOut[i * ringCount + r + 1]; - vert.xyz.Set(x * curRingRadius, y * curRingRadius, 0); - vert.st.set(thou, theta); - - vert.color.dcolor = dclr; - } - } - - // Rings' Indices; - int holeCapperIdxCount = 0; - if (capInnerHole) - { - holeCapperIdxCount = polySides * 3; - } - idxOut.resize(polySides * (ringCount - 1) * 6 + holeCapperIdxCount); - - for (int i = 0; i < polySides; i++) - { - int baseVertIdx0 = i * ringCount; - for (int r = 0; r < ringCount - 1; r++) - { - // counter clock wise: - int a = baseVertIdx0 + r; - int b = a + 1; - int c = (a + ringCount + 1) % vertOut.size(); - int d = (c - 1) % vertOut.size(); - - int baseIdx = (i * (ringCount - 1) + r) * 6 + holeCapperIdxCount; - idxOut[baseIdx] = b; - idxOut[baseIdx + 1] = c; - idxOut[baseIdx + 2] = a; - - idxOut[baseIdx + 3] = a; - idxOut[baseIdx + 4] = c; - idxOut[baseIdx + 5] = d; - } - } - - // indices for the capper: - if (capInnerHole) - { - // inner circle: - // vert: [nPolySide][nRing] - // index: [nPolySide][3] - for (int i = 0; i < polySides; i++) - { - int baseIdx = i * 3; - idxOut[baseIdx] = 0; - idxOut[baseIdx + 1] = 1 + i * ringCount; - idxOut[baseIdx + 2] = (i != (polySides - 1)) ? (2 + i * ringCount) : 1; - } - } - - if (gCollectPosArray) - { - delete [] ringPosArray; - } -} - -//Generate a hoop which consists of specified number of inscribe circles -void MeshUtil::GenHoop(float radius, int polySides, float thickness, int ringCount, const ColorF& clr, float noiseStrength, int noiseSeed, float startAngle, float endAngle, float fadeAngle, std::vector& vertOut, std::vector& idxOut) -{ - // use inscribe circles. Tangent point is at the origin: - setSeed(noiseSeed); - - polySides *= 2; - - if (ringCount < 2) - { - // Log("Warning: Illegal ring count"); - ringCount = 2; - } - - if (endAngle < startAngle) - { - float tmp = endAngle; - endAngle = startAngle; - startAngle = tmp; - } - - float startAngleRad = startAngle / 180 * PI; - float endAngleRad = endAngle / 180 * PI; - float fadeAngleRad = fadeAngle / 180 * PI; - - // Verts: - vertOut.resize(polySides * ringCount); - - float innerRadius = radius - thickness; - float deltaRadius = thickness / (float)(ringCount - 1); - float deltaTheta = 1 / (float)polySides; - - for (int i = 0; i < polySides; i++) - { - float spikeThetaWidth = 0.18f * deltaTheta; - float thetaLinear = i / (float)polySides + randUnit() * 0.5f * deltaTheta - spikeThetaWidth; // old linear mapping - float k = 2.6f * thetaLinear - 1.3f; - float theta = 0.5f + 0.5f * tanf(k) / tanf(1.3f); - float angle = 2 * PI * theta; - float x = cos(angle); - float y = sin(angle); - float fade = computeFade(angle, startAngleRad, endAngleRad, fadeAngleRad); - float noise = randUnit() * noiseStrength; - - for (int r = 0; r < ringCount; r++) - { - float curRingRadius = innerRadius + r * deltaRadius; - float thou = r / (float)(ringCount - 1); - curRingRadius += noise; // apply translation noise - - SVF_P3F_C4B_T2F& vert = vertOut[i * ringCount + r]; - vert.xyz.Set((x - 1) * curRingRadius, y * curRingRadius, 0); - vert.st.set(thou, theta); - - ColorF c(clr.r, clr.g, clr.b, clr.a * fade); - vert.color.dcolor = c.pack_argb8888(); - } - - // generate spikes - i++; - theta += 2 * spikeThetaWidth; - angle = 2 * PI * theta; - x = cos(angle); - y = sin(angle); - for (int r = 0; r < ringCount; r++) - { - float curRingRadius = innerRadius + r * deltaRadius; - float thou = r / (float)(ringCount - 1); - curRingRadius += noise; // apply translation noise - - SVF_P3F_C4B_T2F& vert = vertOut[i * ringCount + r]; - vert.xyz.Set((x - 1) * curRingRadius, y * curRingRadius, 0); - vert.st.set(thou, theta); - - ColorF c(clr.r, clr.g, clr.b, clr.a * fade); - vert.color.dcolor = c.pack_argb8888(); - } - } - - // Indices; - idxOut.resize(polySides * (ringCount - 1) * 6); - for (int i = 0; i < polySides; i++) - { - int baseVertIdx0 = i * ringCount; - for (int r = 0; r < ringCount - 1; r++) - { - // counter clock wise: - int a = baseVertIdx0 + r; - int b = a + 1; - int c = (a + ringCount + 1) % vertOut.size(); - int d = (c - 1) % vertOut.size(); - - int baseIdx = (i * (ringCount - 1) + r) * 6; - idxOut[baseIdx] = b; - idxOut[baseIdx + 1] = c; - idxOut[baseIdx + 2] = a; - - idxOut[baseIdx + 3] = a; - idxOut[baseIdx + 4] = c; - idxOut[baseIdx + 5] = d; - } - } -} - -void MeshUtil::GenTrapezoidFan(int numSideVert, float radius, float startAngleDegree, float endAngleDegree, float centerThickness, const ColorF& clr, std::vector& vertOut, std::vector& idxOut) -{ - if (endAngleDegree < startAngleDegree) - { - float tmp = endAngleDegree; - endAngleDegree = startAngleDegree; - startAngleDegree = tmp; - } - - float startAngle = startAngleDegree / 180 * PI; - float endAngle = endAngleDegree / 180 * PI; - float midAngle = 0.5f * (startAngle + endAngle); - float halfAngleRange = 0.5f * (endAngle - startAngle); - float angleDelta = (endAngle - startAngle) / (numSideVert - 1); - - vertOut.resize(numSideVert * 2); - float dirX = cos(midAngle); - float dirY = sin(midAngle); - DWORD dclr = clr.pack_argb8888(); - for (int i = 0; i < numSideVert; i++) - { - float relativeAngle = i * angleDelta; - float theta = startAngle + relativeAngle; - float x = cos(theta); - float y = sin(theta); - - float angleRatio = (theta - midAngle) / halfAngleRange; - float u = i / (float)(numSideVert - 1); - - SVF_P3F_C4B_T2F& vert = vertOut[i * 2]; - float yRela = angleRatio; - vert.xyz.Set((-yRela * dirY) * centerThickness, (yRela * dirX) * centerThickness, 0); // swap x,y and negate and translate - vert.st.set(u, 0); - vert.color.dcolor = dclr; - - // top: - SVF_P3F_C4B_T2F& vert2 = vertOut[i * 2 + 1]; - vert2.xyz.Set(x * radius, y * radius, 0); - vert2.st.set(u, 1); - vert2.color.dcolor = dclr; - } - - idxOut.resize((numSideVert - 1) * 6); - for (int i = 0; i < numSideVert - 1; i++) - { - int baseVertIdx = i; - int a = baseVertIdx * 2; - int b = a + 2; - int c = b + 1; - int d = a + 1; - - int baseIdx = i * 6; - - idxOut[baseIdx] = b; - idxOut[baseIdx + 1] = c; - idxOut[baseIdx + 2] = a; - - idxOut[baseIdx + 3] = a; - idxOut[baseIdx + 4] = c; - idxOut[baseIdx + 5] = d; - } -} - -void MeshUtil::GenFan(int numSideVert, float radius, float startAngleDegree, float endAngleDegree, const ColorF& clr, std::vector& vertOut, std::vector& idxOut) -{ - if (endAngleDegree < startAngleDegree) - { - float tmp = endAngleDegree; - endAngleDegree = startAngleDegree; - startAngleDegree = tmp; - } - - float startAngle = startAngleDegree / 180 * PI; - float endAngle = endAngleDegree / 180 * PI; - float angleDelta = (endAngle - startAngle) / (numSideVert - 1); - - vertOut.resize(numSideVert + 1); - DWORD dclr = clr.pack_argb8888(); - - // center - SVF_P3F_C4B_T2F& centerVert = vertOut[0]; - centerVert.xyz.Set(0, 0, 0); - centerVert.st.set(0, 0); - centerVert.color.dcolor = dclr; - - for (int i = 0; i < numSideVert; i++) - { - float relativeAngle = i * angleDelta; - float theta = startAngle + relativeAngle; - float x = cos(theta); - float y = sin(theta); - float xLocal = cos(relativeAngle); - float yLocal = sin(relativeAngle); - - // top: - SVF_P3F_C4B_T2F& vert2 = vertOut[i + 1]; - vert2.xyz.Set(x * radius, y * radius, 0); - vert2.st.set(xLocal, yLocal); - vert2.color.dcolor = dclr; - } - - idxOut.resize((numSideVert - 1) * 3); - for (int i = 0; i < numSideVert - 1; i++) - { - int baseVertIdx = i + 1; - - int a = 0; - int b = baseVertIdx; - int c = baseVertIdx + 1; - - int baseIdx = i * 3; - - idxOut[baseIdx] = a; - idxOut[baseIdx + 1] = c; - idxOut[baseIdx + 2] = b; - } -} - -// A shaft/falloff-fan is a simple coarse fan-shaped mesh with odd number of side-vertices. -// It's UV mapping spans a strict rectangular shape (x:[0,1,0] y:[0,1]). -// On top of the fan shape, there's a concentric beam which simulates the spike effect. -void MeshUtil::GenShaft(float radius, float centerThickness, int complexity, float startAngleDegree, float endAngleDegree, const ColorF& clr, std::vector& vertOut, std::vector& idxOut) -{ - if (complexity <= 1) - { - return; - } - - int numSideVert = complexity; - GenTrapezoidFan(numSideVert, radius, startAngleDegree, endAngleDegree, centerThickness, clr, vertOut, idxOut); - - float midAngleDegree = 0.5f * (startAngleDegree + endAngleDegree); - float halfAngleRangeDegree = 0.5f * (endAngleDegree - startAngleDegree); - const float beamWidthFactor = 0.1f; - float beamHalfAngle = halfAngleRangeDegree * beamWidthFactor; - std::vector beamVertOut; - std::vector beamIdxOut; - ColorF clr2 = clr * 1.1f; - - GenTrapezoidFan(2, radius, midAngleDegree - beamHalfAngle, midAngleDegree + beamHalfAngle, centerThickness, clr2, beamVertOut, beamIdxOut); -} - -void MeshUtil::GenStreak(float dir, float radius, float thickness, const ColorF& clr, std::vector& vertOut, std::vector& idxOut) -{ - static const int polySides = 24; - - Matrix33 rotMx; - rotMx.SetRotationAA(dir * PI, Vec3(0, 0, 1)); - - DWORD dclr = clr.pack_argb8888(); - vertOut.resize(polySides + 1); - - SVF_P3F_C4B_T2F& centerV = vertOut[0]; - centerV.xyz = Vec3(0, 0, 0); - centerV.st = Vec2(0, 0); - centerV.color.dcolor = dclr; - - // Generate all vertices - for (int i = 0; i < polySides; i++) - { - float theta = i / (float)polySides; - float angle = 2 * PI * theta; - float x = cos(angle); - float y = sin(angle) * thickness; - - Vec2 scale(x, y); - scale = scale * rotMx; - - x = scale.x; - y = scale.y; - - SVF_P3F_C4B_T2F& vert = vertOut[i + 1]; - vert.xyz.Set(x * radius, y * radius, 0); - vert.st.set(1.0f, theta); - vert.color.dcolor = dclr; - } - - // indices; - int centerIdxCount = polySides * 3; - idxOut.resize(centerIdxCount); - - for (int i = 0; i < polySides; i++) - { - int baseIdx = i * 3; - idxOut[baseIdx] = 0; - idxOut[baseIdx + 1] = 1 + i; - idxOut[baseIdx + 2] = (i != (polySides - 1)) ? (2 + i) : 1; - } -} - -void MeshUtil::GenSprites(std::vector& spriteList, float aspectRatio, bool packPivotPos, std::vector& vertOut, [[maybe_unused]] std::vector& idxOut) -{ - vertOut.resize(spriteList.size() * 4); - - for (unsigned int i = 0; i < spriteList.size(); i++) - { - SpritePoint& sprite = spriteList[i]; - Vec2& pivot = sprite.pos; - - float size = sprite.size; - float rot = sprite.rotation; - ColorF clr = sprite.color; - - float radius = size; - DWORD dclr = clr.pack_argb8888(); - - int vertIdx = i * 4; - - SVF_P3F_C4B_T2F& vert0 = vertOut[vertIdx]; - Vec2 p = rotate(-radius, -radius, rot); - - float zComp; - if (packPivotPos) - { - zComp = (float)(((int)floor((pivot.x * 0.5f + 0.5f) * 4095) << 12) | ((int)floor((pivot.y * 0.5f + 0.5f) * 4095))) / (4096 * 4096); - } - else - { - zComp = rot; - } - - vert0.xyz.Set(p.x / aspectRatio + pivot.x, p.y + pivot.y, zComp); - vert0.color.dcolor = dclr; - vert0.st.set(0, 0); - - SVF_P3F_C4B_T2F& vert1 = vertOut[vertIdx + 1]; - p = rotate(radius, -radius, rot); - vert1.xyz.Set(p.x / aspectRatio + pivot.x, p.y + pivot.y, zComp); - vert1.color.dcolor = dclr; - vert1.st.set(1, 0); - - SVF_P3F_C4B_T2F& vert2 = vertOut[vertIdx + 2]; - p = rotate(radius, radius, rot); - vert2.xyz.Set(p.x / aspectRatio + pivot.x, p.y + pivot.y, zComp); - vert2.color.dcolor = dclr; - vert2.st.set(1, 1); - - SVF_P3F_C4B_T2F& vert3 = vertOut[vertIdx + 3]; - p = rotate(-radius, radius, rot); - vert3.xyz.Set(p.x / aspectRatio + pivot.x, p.y + pivot.y, zComp); - vert3.color.dcolor = dclr; - vert3.st.set(0, 1); - } -} - -void MeshUtil::TrianglizeQuadIndices(int quadCount, std::vector& idxOut) -{ - idxOut.resize(quadCount * 6); - for (int i = 0; i < quadCount; i++) - { - int baseVertIdx = i * 4; - int a = baseVertIdx; - int b = a + 1; - int c = b + 1; - int d = c + 1; - - int baseIdx = i * 6; - - idxOut[baseIdx] = b; - idxOut[baseIdx + 1] = c; - idxOut[baseIdx + 2] = a; - - idxOut[baseIdx + 3] = c; - idxOut[baseIdx + 4] = a; - idxOut[baseIdx + 5] = d; - } -} - -void MeshUtil::GenScreenTile(float x0, float y0, float x1, float y1, ColorF clr, int rowCount, int columnCount, std::vector& vertOut, std::vector& idxOut) -{ - int yCount = rowCount + 1; - int xCount = columnCount + 1; - vertOut.resize(xCount * yCount); - - DWORD dclr = clr.pack_argb8888(); - - float xSpan = x1 - x0; - float ySpan = y1 - y0; - float xDelta = xSpan / columnCount; - float yDelta = ySpan / rowCount; - float uDelta = 1.f / columnCount; - float vDelta = 1.f / rowCount; - - for (int j = 0; j < yCount; j++) - { - for (int i = 0; i < xCount; i++) - { - SVF_P3F_C4B_T2F& vert = vertOut[ i + j * xCount ]; - vert.xyz.Set(x0 + xDelta * i, y0 + yDelta * j, 0); - vert.st.set(uDelta * i, vDelta * j); - vert.color.dcolor = dclr; - } - } - - idxOut.resize(rowCount * columnCount * 6); - for (int j = 0; j < rowCount; j++) - { - for (int i = 0; i < columnCount; i++) - { - int a = i + j * xCount; - int b = a + 1; - int c = (i + 1) + (j + 1) * xCount; - int d = c - 1; - - int baseIdx = (i + j * columnCount) * 6; - idxOut[ baseIdx + 0 ] = b; - idxOut[ baseIdx + 1 ] = c; - idxOut[ baseIdx + 2 ] = a; - - idxOut[ baseIdx + 3 ] = a; - idxOut[ baseIdx + 4 ] = c; - idxOut[ baseIdx + 5 ] = d; - } - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.h b/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.h deleted file mode 100644 index 57ffa2de1f..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/MeshUtil.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_MESHUTIL_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_MESHUTIL_H -#pragma once - -#include "../../../CryCommon/VertexFormats.h" - -namespace stable_rand -{ - void setSeed(uint32 seed); - float randUnit(); - float randPositive(); - float randBias(float noise); -} - -struct SpritePoint -{ - Vec2 pos; - float size; - float brightness; - float rotation; - ColorF color; - - SpritePoint(const Vec2& _pos, float _brightness) - : pos(_pos) - , brightness(_brightness) - , size(0.1f) - , rotation(0) - { - color.set(1, 1, 1, 1); - } - SpritePoint() - : brightness(1) - , size(0.1f) - , rotation(0) - { - pos.set(0, 0); - color.set(1, 1, 1, 1); - } -}; - -class MeshUtil -{ -public: - static void GenDisk(float radius, int polySides, int ringCount, bool capInnerHole, const ColorF& clr, float* ringPosArray, std::vector& vertOut, std::vector& idxOut); - - static void GenHoop(float radius, int polySides, float thickness, int ringCount, const ColorF& clr, float noiseStrength, int noiseSeed, float startAngle, float endAngle, float fadeAngle, std::vector& vertOut, std::vector& idxOut); - static void GenTrapezoidFan(int numSideVert, float radius, float startAngleDegree, float endAngleDegree, float centerThickness, const ColorF& clr, std::vector& vertOut, std::vector& idxOut); - static void GenFan(int numSideVert, float radius, float startAngleDegree, float endAngleDegree, const ColorF& clr, std::vector& vertOut, std::vector& idxOut); - - //A falloff fan is a simple coarse fan-shaped mesh with odd number of side-vertices. - //It's UV mapping spans a strict rectanglular shape (x:[0,1,0] y:[0,1]). - //On top of the fan shape, there's a concentric beam which simulates the spike effect. - static void GenShaft(float radius, float centerThickness, int complexity, float startAngleDegree, float endAngleDegree, const ColorF& clr, std::vector& vertOut, std::vector& idxOut); - static void GenStreak(float dir, float radius, float thickness, const ColorF& clr, std::vector& vertOut, std::vector& idxOut); - static void GenSprites(std::vector& spriteList, float aspectRatio, bool packPivotPos, std::vector& vertOut, std::vector& idxOut); - static void TrianglizeQuadIndices(int quadCount, std::vector& idxOut); - static void GenScreenTile(float x0, float y0, float x1, float y1, ColorF clr, int rowCount, int columnCount, std::vector& vertOut, std::vector& idxOut); -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_MESHUTIL_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.cpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.cpp deleted file mode 100644 index 1db2c3c72e..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "OpticsElement.h" -#include "../CryNameR.h" -#include "../../XRenderD3D9/DriverD3D.h" -#include "RootOpticsElement.h" -#include "../Textures/Texture.h" -#include "../Common/Textures/TextureManager.h" -#include "FlareSoftOcclusionQuery.h" - -#if defined(FLARES_SUPPORT_EDITING) -AZStd::vector COpticsElement::GetEditorParamGroups() -{ - if (m_paramGroups.empty()) - { - InitEditorParamGroups(m_paramGroups); - } - - return m_paramGroups; -} - -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&COpticsElement::FUNC_NAME) -void COpticsElement::InitEditorParamGroups(AZStd::vector& groups) -{ - FuncVariableGroup baseGroup; - baseGroup.SetName("Common"); - baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size", "Size", this, MFPtr(SetSize), MFPtr(GetSize))); - baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Perspective factor", "Perspective factor", this, MFPtr(SetPerspectiveFactor), MFPtr(GetPerspectiveFactor))); - baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Distance Fading factor", "Distance fading factor", this, MFPtr(SetDistanceFadingFactor), MFPtr(GetDistanceFadingFactor))); - baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Brightness", "Brightness", this, MFPtr(SetBrightness), MFPtr(GetBrightness))); - baseGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Position", "The relative position to light", this, MFPtr(SetMovement), MFPtr(GetMovement))); - baseGroup.AddVariable(new OpticsMFPVariable(e_COLOR, "Tint", "Basic tint", this, MFPtr(SetColor), MFPtr(GetColor))); - baseGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Orbit angle", "The rotation angle of the virtual light source", this, MFPtr(SetOrbitAngle), MFPtr(GetOrbitAngle))); - baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Occlusion Interaction", "Enable various flare interaction with the occlusion", this, MFPtr(SetOccBokehEnabled), MFPtr(IsOccBokehEnabled))); - baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Auto Rotation", "Enable Auto Rotation around the pivot", this, MFPtr(SetAutoRotation), MFPtr(HasAutoRotation))); - baseGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Correct Aspect Ratio", "Correct aspect ratio", this, MFPtr(SetAspectRatioCorrection), MFPtr(HasAspectRatioCorrection))); - groups.push_back(baseGroup); - - FuncVariableGroup sensorGroup; - sensorGroup.SetName("Sensor"); - sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Sensor image size variation factor", "sensor image size variation factor", this, MFPtr(SetSensorSizeFactor), MFPtr(GetSensorSizeFactor))); - sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Sensor image brightness variation factor", "sensor image brightness variation factor", this, MFPtr(SetSensorBrightnessFactor), MFPtr(GetSensorBrightnessFactor))); - groups.push_back(sensorGroup); - - FuncVariableGroup xformGroup; - xformGroup.SetName("Transformation"); - xformGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Scale", "Scale", this, MFPtr(SetScale), MFPtr(GetScale))); - xformGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Translation", "Translation", this, MFPtr(SetTranslation), MFPtr(GetTranslation))); - xformGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Rotation", "Rotation", this, MFPtr(SetRotation), MFPtr(GetRotation))); - groups.push_back(xformGroup); - - FuncVariableGroup dynamicsGroup; - dynamicsGroup.SetName("Dynamics"); - dynamicsGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable", "Enable.", this, MFPtr(SetDynamicsEnabled), MFPtr(GetDynamicsEnabled))); - dynamicsGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Trigger Invert", "Invert the trigger area.", this, MFPtr(SetDynamicsInvert), MFPtr(GetDynamicsInvert))); - dynamicsGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Trigger Offset", "Offset from the center of the screen.", this, MFPtr(SetDynamicsOffset), MFPtr(GetDynamicsOffset))); - dynamicsGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Trigger Range", "How much influence the trigger has.", this, MFPtr(SetDynamicsRange), MFPtr(GetDynamicsRange))); - dynamicsGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Trigger Falloff", "Falloff strength of the trigger area.", this, MFPtr(SetDynamicsFalloff), MFPtr(GetDynamicsFalloff))); - groups.push_back(dynamicsGroup); -} -#undef MFPtr -#endif - -void COpticsElement::Load(IXmlNode* pNode) -{ - XmlNodeRef pCommonNode = pNode->findChild("Common"); - if (pCommonNode) - { - float fSize(m_fSize); - if (pCommonNode->getAttr("Size", fSize)) - { - SetSize(fSize); - } - - float fPerspectiveFactor(m_fPerpectiveFactor); - if (pCommonNode->getAttr("Perspectivefactor", fPerspectiveFactor)) - { - SetPerspectiveFactor(fPerspectiveFactor); - } - - float fDistanceFadingFactor = m_fDistanceFadingFactor; - if (pCommonNode->getAttr("DistanceFadingfactor", fDistanceFadingFactor)) - { - SetDistanceFadingFactor(fDistanceFadingFactor); - } - - float fBrightness = m_fBrightness; - if (pCommonNode->getAttr("Brightness", fBrightness)) - { - SetBrightness(fBrightness); - } - - Vec2 vPos(m_vMovement); - if (pCommonNode->getAttr("Position", vPos)) - { - SetMovement(vPos); - } - - Vec3 color(m_Color.r, m_Color.g, m_Color.b); - int nAlpha((int)(m_Color.a * 255.0f)); - if (pCommonNode->getAttr("Tint", color) && pCommonNode->getAttr("Tint.alpha", nAlpha)) - { - SetColor(ColorF(color.x, color.y, color.z, (float)nAlpha / 255.0f)); - } - - float fOrbitAngle(m_fOrbitAngle); - if (pCommonNode->getAttr("Orbitangle", fOrbitAngle)) - { - SetOrbitAngle(fOrbitAngle); - } - - bool bOcclusionBokeh(m_bOcclusionBokeh); - if (pCommonNode->getAttr("OcclusionInteraction", bOcclusionBokeh)) - { - SetOccBokehEnabled(bOcclusionBokeh); - } - - bool bAutoRotation(m_bAutoRotation); - if (pCommonNode->getAttr("AutoRotation", bAutoRotation)) - { - SetAutoRotation(bAutoRotation); - } - - bool bCorrectAspectRatio(m_bCorrectAspectRatio); - if (pCommonNode->getAttr("CorrectAspectRatio", bCorrectAspectRatio)) - { - SetAspectRatioCorrection(bCorrectAspectRatio); - } - } - - XmlNodeRef pSensorNode = pNode->findChild("Sensor"); - if (pSensorNode) - { - float fSensorSizeFactor(m_fSensorSizeFactor); - if (pSensorNode->getAttr("Sensorimagesizevariationfactor", fSensorSizeFactor)) - { - SetSensorSizeFactor(fSensorSizeFactor); - } - - float fSensorBrightnessFactor = m_fSensorBrightnessFactor; - if (pSensorNode->getAttr("Sensorimagebrightnessvariationfactor", fSensorBrightnessFactor)) - { - SetSensorBrightnessFactor(fSensorBrightnessFactor); - } - } - - XmlNodeRef pTransformationNode = pNode->findChild("Transformation"); - if (pTransformationNode) - { - Vec2 vScale(xform_scale); - if (pTransformationNode->getAttr("Scale", vScale)) - { - SetScale(vScale); - } - - Vec2 vTranslation(xform_translate); - if (pTransformationNode->getAttr("Translation", vTranslation)) - { - SetTranslation(vTranslation); - } - - float fRotation(xform_rotation); - if (pTransformationNode->getAttr("Rotation", fRotation)) - { - SetRotation(fRotation); - } - } - - XmlNodeRef pDynamicsNode = pNode->findChild("Dynamics"); - if (pDynamicsNode) - { - bool bEnable(m_bEnabled); - if (pDynamicsNode->getAttr("Enable", bEnable)) - { - SetDynamicsEnabled(bEnable); - } - - bool bDynamicInvert(m_bDynamicsInvert); - if (pDynamicsNode->getAttr("TriggerInvert", bDynamicInvert)) - { - SetDynamicsInvert(bDynamicInvert); - } - - Vec2 vDynamicsOffset(m_vDynamicsOffset); - if (pDynamicsNode->getAttr("TriggerOffset", vDynamicsOffset)) - { - SetDynamicsOffset(vDynamicsOffset); - } - - float fDynamicsRange(m_fDynamicsRange); - if (pDynamicsNode->getAttr("TriggerRange", fDynamicsRange)) - { - SetDynamicsRange(fDynamicsRange); - } - - float fDynamicsFalloff(m_fDynamicsFalloff); - if (pDynamicsNode->getAttr("TriggerFalloff", fDynamicsFalloff)) - { - SetDynamicsFalloff(fDynamicsFalloff); - } - } -} - -RootOpticsElement* COpticsElement::GetRoot() -{ - IOpticsElementBase* parent = this; - do - { - parent = parent->GetParent(); - if (parent == NULL) - { - return NULL; - } - } while (parent->GetType() != eFT_Root); - return (RootOpticsElement*)parent; -} - -void COpticsElement::validateGlobalVars(SAuxParams& aux) -{ - if (m_pParent) - { - m_globalPerpectiveFactor = m_fPerpectiveFactor * m_pParent->m_globalPerpectiveFactor; - m_globalDistanceFadingFactor = m_fDistanceFadingFactor * m_pParent->m_globalDistanceFadingFactor; - m_globalSensorSizeFactor = m_fSensorSizeFactor * m_pParent->m_globalSensorSizeFactor; - float sensorSizeFactor = 1 + m_globalSensorSizeFactor * aux.sensorVariationValue; - - m_globalSensorBrightnessFactor = m_fSensorBrightnessFactor * m_pParent->m_globalSensorBrightnessFactor; - float sensorBrightnessFactor = fabs(1 + m_globalSensorBrightnessFactor * aux.sensorVariationValue); - - float perspectiveShortening = 1 + m_globalPerpectiveFactor * (aux.perspectiveShortening - 1); - m_globalSize = m_fSize * m_pParent->m_globalSize * perspectiveShortening * sensorSizeFactor; // remember to multiply the additional perspective factor - - if (aux.bMultiplyColor) - { - m_globalColor = m_Color * m_pParent->m_globalColor; - } - else - { - m_globalColor = ColorF(m_Color.r + m_pParent->m_globalColor.r, - m_Color.g + m_pParent->m_globalColor.g, - m_Color.b + m_pParent->m_globalColor.b, - m_Color.a * m_pParent->m_globalColor.a); - } - - float fading = clamp_tpl(1 - 1000.f * m_globalDistanceFadingFactor * aux.linearDepth, 0.0f, 1.f); - float brightness = m_fBrightness * sensorBrightnessFactor * fading; - m_globalFlareBrightness = brightness * m_pParent->m_globalFlareBrightness; - m_globalShaftBrightness = brightness * m_pParent->m_globalShaftBrightness; - - m_globalMovement.x = m_vMovement.x * m_pParent->m_globalMovement.x; - m_globalMovement.y = m_vMovement.y * m_pParent->m_globalMovement.y; - - if (!m_pParent->m_globalTransform.IsIdentity()) - { - m_globalTransform = m_mxTransform * m_pParent->m_globalTransform; - } - else - { - m_globalTransform = m_mxTransform; - } - - m_globalOrbitAngle = m_fOrbitAngle + m_pParent->m_globalOrbitAngle; - m_globalOcclusionBokeh = m_bOcclusionBokeh & m_pParent->m_globalOcclusionBokeh; - m_globalAutoRotation = m_bAutoRotation & m_pParent->m_bAutoRotation; - m_globalCorrectAspectRatio = m_bCorrectAspectRatio & m_pParent->m_bCorrectAspectRatio; - } -} - -void COpticsElement::updateXformMatrix() -{ - Matrix33 scaleMx; - scaleMx.SetScale(Vec3(xform_scale.x, xform_scale.y, 1)); - Matrix33 rotMx; - rotMx.SetRotationAA(xform_rotation * 2.0f * PI, Vec3(0, 0, 1)); - Matrix33 combine = rotMx * scaleMx; - combine.SetColumn(2, Vec3(xform_translate.x, xform_translate.y, 1)); - SetTransform(combine); -} - -const Vec3 COpticsElement::computeOrbitPos(const Vec3& vSrcProjPos, float orbitAngle) -{ - if (orbitAngle < 0.01f && orbitAngle > -0.01f) - { - return vSrcProjPos; - } - - const Vec2 oriVec (vSrcProjPos.x - 0.5f, vSrcProjPos.y - 0.5f); - float orbitSin = 0.0f, orbitCos = 0.0f; - sincos_tpl(orbitAngle, &orbitSin, &orbitCos); - const Vec2 resultVec = Vec2(oriVec.x * orbitCos - oriVec.y * orbitSin, oriVec.y * orbitCos + oriVec.x * orbitSin); - return Vec3(resultVec.x + 0.5f, resultVec.y + 0.5f, vSrcProjPos.z); -} - -void COpticsElement::ApplyVSParam_WPosAndSize(CShader* shader, const Vec3& wpos) -{ - static CCryNameR wPosAndSizeName("wposAndSize"); - Vec4 wPosAndSizeParam(wpos, m_globalSize); - shader->FXSetVSFloat(wPosAndSizeName, &wPosAndSizeParam, 1); -} - -void COpticsElement::ApplyOcclusionPattern(CShader* shader) -{ - if (GetRoot() == NULL) - { - return; - } - - static STexState bilinearTS(FILTER_LINEAR, true); - - CFlareSoftOcclusionQuery* pSoftOcclusionQuery = GetRoot()->GetOcclusionQuery(); - if (pSoftOcclusionQuery && pSoftOcclusionQuery->GetGatherTexture()) - { - CTexture* pGatherTex = pSoftOcclusionQuery->GetGatherTexture(); - pGatherTex->Apply(5, CTexture::GetTexState(bilinearTS)); - - float x0 = 0, y0 = 0, x1 = 0, y1 = 0; - pSoftOcclusionQuery->GetDomainInTexture(x0, y0, x1, y1); - float width, height; - pSoftOcclusionQuery->GetSectorSize(width, height); - - static CCryNameR occPatternInfoName("occPatternInfo"); - const Vec4 occPatternInfo((x0 + x1) * 0.5f, (y0 + y1) * 0.5f, width, height); - shader->FXSetPSFloat(occPatternInfoName, &occPatternInfo, 1); - } - else - { - CTextureManager::Instance()->GetBlackTexture()->Apply(5, CTexture::GetTexState(bilinearTS)); - } -} - -void COpticsElement::ApplyOcclusionBokehFlag([[maybe_unused]] CShader* shader) -{ - if (m_globalOcclusionBokeh) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE3]; - } -} - -void COpticsElement::ApplySpectrumTexFlag([[maybe_unused]] CShader* shader, bool enabled) -{ - if (enabled) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } -} - -void COpticsElement::ApplyExternTintAndBrightnessVS(CShader* shader, ColorF& cExTint, float fExBrt) -{ - static CCryNameR exTintName("externTint"); - Vec4 exTintParam(cExTint.r * fExBrt, cExTint.g * fExBrt, cExTint.b * fExBrt, cExTint.a); - shader->FXSetVSFloat(exTintName, &exTintParam, 1); -} - -void COpticsElement::ApplyVSParam_Xform(CShader* shader, Matrix33& mx33) -{ - static CCryNameR xformName("xform"); - Matrix44 mx44(mx33); - mx44.Transpose(); - shader->FXSetVSFloat(xformName, reinterpret_cast(mx44.GetData()), 3); -} - -void COpticsElement::ApplyVSParam_Dynamics(CShader* shader, const Vec3& lightProjPos) -{ - static CCryNameR dynamicsName("dynamics"); - - float fTriggerArea = 1.0f; - if (m_bDynamics) - { - float fRange = 1.0f / max(0.01f, m_fDynamicsRange); - float fFalloff = m_fDynamicsFalloff; - - Vec2 vProjPos; - vProjPos.x = (lightProjPos.x * 2.f - 1.f) + m_vDynamicsOffset.x; - vProjPos.y = (lightProjPos.y * 2.f - 1.f) + m_vDynamicsOffset.y; - - fTriggerArea = vProjPos.GetLength(); - fTriggerArea = m_bDynamicsInvert ? 1.0f - fTriggerArea : fTriggerArea; - fTriggerArea = powf(clamp_tpl(1.f - fTriggerArea * fRange, 0.f, 1.f), fFalloff); - } - - Vec4 dynamicsParam(fTriggerArea, 1, 1, 1); - shader->FXSetVSFloat(dynamicsName, &dynamicsParam, 1); -} - -void COpticsElement::ApplyGeneralFlags([[maybe_unused]] CShader* shader) -{ - if (m_globalAutoRotation) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - if (m_globalCorrectAspectRatio) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } -} - -void COpticsElement::ApplyVSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos) -{ - static CCryNameR ccrName("lightProjPos"); - Vec4 lpposParam(lightProjPos.x, lightProjPos.y, lightProjPos.z, 0); - shader->FXSetVSFloat(ccrName, &lpposParam, 1); -} - -void COpticsElement::ApplyPSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos) -{ - static CCryNameR ccrName("lightProjPos"); - Vec4 lpposParam(lightProjPos.x, lightProjPos.y, lightProjPos.z, 0); - shader->FXSetPSFloat(ccrName, &lpposParam, 1); -} - -void COpticsElement::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.h b/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.h deleted file mode 100644 index 7e9cfad6e3..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsElement.h +++ /dev/null @@ -1,343 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSELEMENT_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSELEMENT_H -#pragma once - -#include "CryString.h" -#include "Cry_Vector2.h" -#include "Cry_Vector3.h" -#include "Cry_Matrix33.h" -#include "Cry_Color.h" -#include "IFlares.h" - -class CD3D9Renderer; -class CTexture; -class RootOpticsElement; - -namespace LensOpConst -{ - static Vec4 _LO_DEF_VEC4(1.f, 1.f, 1.f, 0.f); - static Vec2 _LO_DEF_VEC2(0.f, 0.f); - static Vec2 _LO_DEF_VEC2_I(1.f, 1.f); - static Vec2 _LO_DEF_ANGLE(-90.f, 90.f); - static Matrix33 _LO_DEF_MX33(IDENTITY); - static ColorF _LO_DEF_CLR(1.f, 1.f, 1.f, 0.2f); - static ColorF _LO_DEF_CLR_BLK(0.f, 0.f, 0.f, 0.0f); - static float _LO_MIN(1e-6f); -} - -typedef MFPVariable OpticsMFPVariable; -typedef void (IOpticsElementBase::* Optics_MFPtr)(void); - -class COpticsElement - : public IOpticsElementBase -{ -public: - struct SAuxParams - { - float perspectiveShortening; - float linearDepth; - float distance; - float sensorVariationValue; - float viewAngleFalloff; - bool attachToSun; - bool bMultiplyColor; - bool bForceRender; - }; - -private: - Vec2 xform_scale; - Vec2 xform_translate; - float xform_rotation; - -protected: - COpticsElement* m_pParent; - Vec2 m_globalMovement; - Matrix33 m_globalTransform; - ColorF m_globalColor; - float m_globalFlareBrightness; - float m_globalShaftBrightness; - float m_globalSize; - float m_globalPerpectiveFactor; - float m_globalDistanceFadingFactor; - float m_globalOrbitAngle; - float m_globalSensorSizeFactor; - float m_globalSensorBrightnessFactor; - bool m_globalAutoRotation : 1; - bool m_globalCorrectAspectRatio : 1; - bool m_globalOcclusionBokeh : 1; - - string m_name; - bool m_bEnabled : 1; - -protected: - - Matrix33 m_mxTransform; - float m_fSize; - float m_fPerpectiveFactor; - float m_fDistanceFadingFactor; - ColorF m_Color; - float m_fBrightness; - Vec2 m_vMovement; - float m_fOrbitAngle; - float m_fSensorSizeFactor; - float m_fSensorBrightnessFactor; - Vec2 m_vDynamicsOffset; - float m_fDynamicsRange; - float m_fDynamicsFalloff; - bool m_bAutoRotation : 1; - bool m_bCorrectAspectRatio : 1; - bool m_bOcclusionBokeh : 1; - bool m_bDynamics : 1; - bool m_bDynamicsInvert : 1; - -#if defined(FLARES_SUPPORT_EDITING) - AZStd::vector m_paramGroups; -#endif -public: - - COpticsElement (const char* name, float size = 0.3f, const float brightness = 1.0f, const ColorF& color = LensOpConst::_LO_DEF_CLR) - : m_pParent(0) - , m_bEnabled(true) - , m_fPerpectiveFactor(0) - , m_globalPerpectiveFactor(1) - , m_fOrbitAngle(0) - , m_bOcclusionBokeh(false) - , m_fSensorSizeFactor(0) - , m_fSensorBrightnessFactor(0) - , m_fDistanceFadingFactor(1) - { - m_name = name; - m_vMovement = Vec2(1.f, 1.f); - m_fSize = size; - m_Color = color; - m_mxTransform = LensOpConst::_LO_DEF_MX33; - - m_globalMovement = LensOpConst::_LO_DEF_VEC2_I; - m_globalTransform = Matrix33::CreateIdentity(); - m_globalColor.Set(1.f, 1.f, 1.f, 1.f); - m_globalFlareBrightness = 1.f; - m_globalShaftBrightness = 1.f; - m_globalSize = 1; - m_fBrightness = brightness; - m_bAutoRotation = false; - m_bCorrectAspectRatio = true; - - xform_scale.set(1.f, 1.f); - xform_rotation = 0.f; - xform_translate.set(0.f, 0.f); - - m_bDynamics = false; - m_vDynamicsOffset.set(0.f, 0.f); - m_fDynamicsRange = 1.f; - m_bDynamicsInvert = false; - m_fDynamicsFalloff = 1.f; - } - - virtual ~COpticsElement() - { - } - - virtual void Load(IXmlNode* pNode); - - COpticsElement(const COpticsElement& copyFrom) - { - *this = copyFrom; -#if defined(FLARES_SUPPORT_EDITING) - m_paramGroups.clear(); -#endif - } - - IOpticsElementBase* GetParent() const - { - return m_pParent; - } - - RootOpticsElement* GetRoot(); - - string GetName() const { return m_name; } - void SetName(const char* newName) - { - m_name = newName; - } - bool IsEnabled() const { return m_bEnabled; } - float GetSize() const { return m_fSize; } - float GetPerspectiveFactor() const { return m_fPerpectiveFactor; } - float GetDistanceFadingFactor() const { return m_fDistanceFadingFactor; } - float GetBrightness() const { return m_fBrightness; } - ColorF GetColor() const { return m_Color; } - Vec2 GetMovement() const { return m_vMovement; } - float GetOrbitAngle() const {return m_fOrbitAngle; } - float GetSensorSizeFactor() const { return m_fSensorSizeFactor; } - float GetSensorBrightnessFactor() const { return m_fSensorBrightnessFactor; } - bool IsOccBokehEnabled() const { return m_bOcclusionBokeh; } - bool HasAutoRotation() const { return m_bAutoRotation; } - bool HasAspectRatioCorrection() const { return m_bCorrectAspectRatio; } - - void SetEnabled(bool b) override { m_bEnabled = b; } - void SetSize(float s) override { m_fSize = s; } - void SetPerspectiveFactor(float p) override { m_fPerpectiveFactor = p; } - void SetDistanceFadingFactor(float p) override { m_fDistanceFadingFactor = p; } - void SetBrightness(float b) override { m_fBrightness = b; } - void SetColor(ColorF color) { m_Color = color; Invalidate(); } - void SetMovement(Vec2 movement) - { - m_vMovement = movement; - if (fabs(m_vMovement.x) < 0.0001f) - { - m_vMovement.x = 0.001f; - } - if (fabs(m_vMovement.y) < 0.0001f) - { - m_vMovement.y = 0.001f; - } - } - void SetTransform(const Matrix33& xform) override { m_mxTransform = xform; } - void SetOccBokehEnabled(bool b) override { m_bOcclusionBokeh = b; } - void SetOrbitAngle(float orbitAngle) override { m_fOrbitAngle = orbitAngle; } - void SetSensorSizeFactor(float sizeFactor) override { m_fSensorSizeFactor = sizeFactor; } - void SetSensorBrightnessFactor(float brtFactor) override { m_fSensorBrightnessFactor = brtFactor; } - void SetAutoRotation(bool b) override { m_bAutoRotation = b; } - void SetAspectRatioCorrection(bool b) override { m_bCorrectAspectRatio = b; } - - void SetParent(COpticsElement* pParent) - { - m_pParent = pParent; - } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - bool IsVisible() const - { - return m_globalColor.a > LensOpConst::_LO_MIN && m_globalFlareBrightness > LensOpConst::_LO_MIN; - } - - virtual void Render([[maybe_unused]] SLensFlareRenderParam* pParam, [[maybe_unused]] const Vec3& vPos){assert(0); } - -protected: - void updateXformMatrix(); - virtual void Invalidate() {} - -public: - void SetScale(Vec2 scale) - { - xform_scale = scale; - updateXformMatrix(); - } - void SetRotation(float rot) - { - xform_rotation = rot; - updateXformMatrix(); - } - void SetTranslation(Vec2 xlation) - { - xform_translate = xlation; - updateXformMatrix(); - } - Vec2 GetScale() { return xform_scale; } - Vec2 GetTranslation() { return xform_translate; } - float GetRotation() { return xform_rotation; } - - void SetDynamicsEnabled(bool enable) { m_bDynamics = enable; } - void SetDynamicsOffset(Vec2 offset) { m_vDynamicsOffset = offset; } - void SetDynamicsRange(float range) { m_fDynamicsRange = range; } - void SetDynamicsInvert(bool invert) { m_bDynamicsInvert = invert; } - void SetDynamicsFalloff(float falloff) { m_fDynamicsFalloff = falloff; } - - bool GetDynamicsEnabled() const { return m_bDynamics; } - Vec2 GetDynamicsOffset() const { return m_vDynamicsOffset; } - float GetDynamicsRange() const { return m_fDynamicsRange; } - bool GetDynamicsInvert() const { return m_bDynamicsInvert; } - float GetDynamicsFalloff() const { return m_fDynamicsFalloff; } - - virtual void AddElement([[maybe_unused]] IOpticsElementBase* pElement) {} - virtual void InsertElement([[maybe_unused]] int nPos, [[maybe_unused]] IOpticsElementBase* pElement) {} - virtual void Remove([[maybe_unused]] int i) {} - virtual void RemoveAll() {} - virtual int GetElementCount() const {return 0; } - virtual IOpticsElementBase* GetElementAt([[maybe_unused]] int i) const - { -#ifndef RELEASE - iLog->Log("ERROR"); - __debugbreak(); -#endif - return 0; - } - -#if defined(FLARES_SUPPORT_EDITING) - virtual AZStd::vector GetEditorParamGroups(); -#endif - -protected: - -#if defined(FLARES_SUPPORT_EDITING) - virtual void InitEditorParamGroups(AZStd::vector& groups); -#endif - -public: - - virtual void validateGlobalVars(SAuxParams& aux); - - float computeMovementLocationX(const Vec3& vSrcProjPos) - { - return (vSrcProjPos.x - 0.5f) * m_globalMovement.x + 0.5f; - } - - float computeMovementLocationY(const Vec3& vSrcProjPos) - { - return (vSrcProjPos.y - 0.5f) * m_globalMovement.y + 0.5f; - } - - static const Vec3 computeOrbitPos(const Vec3& vSrcProjPos, float orbitAngle); - void ApplyVSParam_WPosAndSize(CShader* shader, const Vec3& wpos); - - void ApplyOcclusionPattern(CShader* shader); - void ApplyGeneralFlags(CShader* shader); - void ApplyOcclusionBokehFlag(CShader* shader); - void ApplySpectrumTexFlag(CShader* shader, bool enabled); - void ApplyExternTintAndBrightnessVS(CShader* shader, ColorF& cExTint, float fExBrt); - void ApplyVSParam_Xform(CShader* shader, Matrix33& mx33); - void ApplyVSParam_Dynamics(CShader* shader, const Vec3& projPos); - void ApplyPSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos); - void ApplyVSParam_LightProjPos(CShader* shader, const Vec3& lightProjPos); - - void ApplyCommonVSParams(CShader* shader, const Vec3& wpos, const Vec3& lightProjPos) - { - //If aspect ratio correction is on (default) we want to adjust the global - //transform to re-scale the flare geometry to keep a constant size regardless of - //the window's aspect ratio. - //This used to be handled in the shader with params passed from a method ApplyVSParams_ScreenWidthHeight. - //But that only applied to ghost flares and why bother doing that per-vertex when we can do it once - //per constant buffer. - if (HasAspectRatioCorrection()) - { - const float inverseAspectRatio = static_cast(gEnv->pRenderer->GetHeight()) / static_cast(gEnv->pRenderer->GetWidth()); - - //Adjust the entire base to avoid warping when rotation is applied - const Vec3 adjustedXBasis = m_globalTransform.GetRow(0) * inverseAspectRatio; - m_globalTransform.SetRow(0, adjustedXBasis); - } - - ApplyVSParam_WPosAndSize(shader, wpos); - ApplyVSParam_Xform(shader, m_globalTransform); - ApplyVSParam_Dynamics(shader, lightProjPos); - } - - virtual EFlareType GetType() { return eFT__Base__; } - virtual bool IsGroup() const { return false; } - - virtual void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux) = 0; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSELEMENT_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.cpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.cpp deleted file mode 100644 index ab56dcd0e3..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "OpticsFactory.h" - -#include "RootOpticsElement.h" -#include "OpticsElement.h" -#include "Ghost.h" -#include "Glow.h" -#include "ChromaticRing.h" -#include "CameraOrbs.h" -#include "IrisShafts.h" -#include "Streaks.h" -#include "ImageSpaceShafts.h" -#include "OpticsReference.h" -#include "OpticsProxy.h" -#include "OpticsPredef.hpp" - -IOpticsElementBase* COpticsFactory::Create(EFlareType type) const -{ - switch (type) - { - case eFT_Root: - return new RootOpticsElement; - case eFT_Group: - return new COpticsGroup("[Group]"); - case eFT_Ghost: - return new CLensGhost("Ghost"); - case eFT_MultiGhosts: - return new CMultipleGhost("Multi Ghost"); - case eFT_Glow: - return new Glow("Glow"); - case eFT_IrisShafts: - return new IrisShafts("Iris Shafts"); - case eFT_ChromaticRing: - return new ChromaticRing("Chromatic Ring"); - case eFT_CameraOrbs: - return new CameraOrbs("Orbs"); - case eFT_ImageSpaceShafts: - return new ImageSpaceShafts("Vol Shafts"); - case eFT_Streaks: - return new Streaks("Streaks"); - case eFT_Reference: - return new COpticsReference("Reference"); - case eFT_Proxy: - return new COpticsProxy("Proxy"); - default: - return NULL; - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.h b/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.h deleted file mode 100644 index ce92dd30a5..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsFactory.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSFACTORY_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSFACTORY_H -#pragma once - -#include "IFlares.h" - -class COpticsFactory -{ -private: - COpticsFactory(){} - -public: - static COpticsFactory* GetInstance() - { - static COpticsFactory instance; - return &instance; - } - - IOpticsElementBase* Create(EFlareType type) const; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSFACTORY_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.cpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.cpp deleted file mode 100644 index 2efbe07696..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "../CryNameR.h" -#include "../../XRenderD3D9/DriverD3D.h" -#include "../Textures/Texture.h" -#include "OpticsGroup.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&COpticsGroup::FUNC_NAME) -void COpticsGroup::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); -} -#undef MFPtr -#endif - -void COpticsGroup::_init() -{ - SetSize(1.f); - SetAutoRotation(true); -} - -COpticsGroup::COpticsGroup(const char* name, COpticsElement* ghost, ...) - : COpticsElement(name) -{ - _init(); - - va_list arg; - va_start(arg, ghost); - - COpticsElement* curArg; - while ((curArg = va_arg(arg, COpticsElement*)) != NULL) - { - Add(curArg); - } - - va_end(arg); -} - -COpticsGroup& COpticsGroup::Add(IOpticsElementBase* pElement) -{ - children.push_back(pElement); - ((COpticsElement*)&*pElement)->SetParent(this); - return *this; -} - -void COpticsGroup::InsertElement(int nPos, IOpticsElementBase* pElement) -{ - children.insert(children.begin() + nPos, pElement); - ((COpticsElement*)&*pElement)->SetParent(this); -} - -void COpticsGroup::Remove(int i) -{ - children.erase(children.begin() + i); -} - -void COpticsGroup::RemoveAll() -{ - children.clear(); -} - -int COpticsGroup::GetElementCount() const { return children.size(); } - -IOpticsElementBase* COpticsGroup::GetElementAt(int i) const { return children.at(i); } - -void COpticsGroup::SetElementAt(int i, IOpticsElementBase* elem) -{ - if (i < 0 || i > GetElementCount()) - { - return; - } - children[i] = elem; - ((COpticsElement*)&*children[i])->SetParent(this); -} - -void COpticsGroup::validateGlobalVars(SAuxParams& aux) -{ - COpticsElement::validateGlobalVars(aux); - validateChildrenGlobalVars(aux); -} -void COpticsGroup::validateChildrenGlobalVars(SAuxParams& aux) -{ - for (uint i = 0; i < children.size(); i++) - { - ((COpticsElement*)GetElementAt(i))->validateGlobalVars(aux); - } -} - -void COpticsGroup::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux) -{ - PROFILE_LABEL_SCOPE("LensEfxGroup"); - - for (uint i = 0; i < children.size(); i++) - { - if (GetElementAt(i)->IsEnabled()) - { - ((COpticsElement*)GetElementAt(i))->Render(shader, vSrcWorldPos, vSrcProjPos, aux); - } - } -} - -void COpticsGroup::GetMemoryUsage(ICrySizer* pSizer) const -{ - for (int i = 0, iChildSize(children.size()); i < iChildSize; ++i) - { - children[i]->GetMemoryUsage(pSizer); - } - pSizer->AddObject(this, sizeof(*this)); -} - -void COpticsGroup::Invalidate() -{ - for (int i = 0, iChildSize(children.size()); i < iChildSize; ++i) - { - children[i]->Invalidate(); - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.h b/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.h deleted file mode 100644 index 61a6ae0178..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsGroup.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSGROUP_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSGROUP_H -#pragma once - -#include "OpticsElement.h" - -class COpticsGroup - : public COpticsElement -{ -protected: - std::vector children; - void _init(); - -public: - - COpticsGroup(const char* name = "[Unnamed_Group]") - : COpticsElement(name) { _init(); }; - COpticsGroup(const char* name, COpticsElement* elem, ...); - virtual ~COpticsGroup(){} - - COpticsGroup& Add(IOpticsElementBase* pElement); - void Remove(int i); - void RemoveAll(); - virtual int GetElementCount() const; - IOpticsElementBase* GetElementAt(int i) const; - - void AddElement(IOpticsElementBase* pElement) { Add(pElement); } - void InsertElement(int nPos, IOpticsElementBase* pElement); - void SetElementAt(int i, IOpticsElementBase* elem); - void Invalidate(); - - bool IsGroup() const { return true; } - void validateChildrenGlobalVars(SAuxParams& aux); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual EFlareType GetType() { return eFT_Group; } - virtual void validateGlobalVars(SAuxParams& aux); - - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - -#if defined(FLARES_SUPPORT_EDITING) - virtual void InitEditorParamGroups(AZStd::vector& groups); -#endif - -public: - static COpticsGroup predef_simpleCamGhost; - static COpticsGroup predef_cheapCamGhost; - static COpticsGroup predef_multiGlassGhost; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSGROUP_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsPredef.hpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsPredef.hpp deleted file mode 100644 index 791fc42d46..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsPredef.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "OpticsElement.h" -#include "RootOpticsElement.h" -#include "Ghost.h" -#include "Glow.h" -#include "ChromaticRing.h" -#include "IrisShafts.h" -#include "Streaks.h" -#include "CameraOrbs.h" - -class OpticsPredef -{ -public: - COpticsGroup PREDEF_MULTIGLASS_GHOST; - -private: - void InitPredef() - { - static CTexture* s_pCenterFlare = CTexture::ForName("EngineAssets/Textures/flares/lens_flare1-wide.tif", FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - - PREDEF_MULTIGLASS_GHOST.SetName("[Multi-glass Reflection]"); - - Glow* rotStreak = new Glow("RotatingStreak"); - rotStreak->SetSize(0.28f); - rotStreak->SetAutoRotation(true); - rotStreak->SetFocusFactor(-0.18f); - rotStreak->SetBrightness(6.f); - rotStreak->SetScale(Vec2(0.034f, 25.f)); - PREDEF_MULTIGLASS_GHOST.Add(rotStreak); - - CameraOrbs* orbs = new CameraOrbs("Orbs"); - orbs->SetIllumRange(1.2f); - orbs->SetUseLensTex(true); - PREDEF_MULTIGLASS_GHOST.Add(orbs); - - ChromaticRing* ring = new ChromaticRing("Forward Ring"); - PREDEF_MULTIGLASS_GHOST.Add(ring); - - ChromaticRing* backRing = new ChromaticRing("Backward Ring"); - backRing->SetCompletionFading(10.f); - backRing->SetCompletionSpanAngle(25.f); - PREDEF_MULTIGLASS_GHOST.Add(backRing); - - CLensGhost* centerCorona = new CLensGhost("Center Corona"); - centerCorona->SetTexture(s_pCenterFlare); - centerCorona->SetSize(0.6f); - PREDEF_MULTIGLASS_GHOST.Add(centerCorona); - } - OpticsPredef() - { - InitPredef(); - } - - OpticsPredef(OpticsPredef const& copy); - void operator=(OpticsPredef const& copy); - -public: - static OpticsPredef* GetInstance() - { - static OpticsPredef instance; - return &instance; - } -}; diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.cpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.cpp deleted file mode 100644 index 20a9033622..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "OpticsProxy.h" - -#if defined(FLARES_SUPPORT_EDITING) -AZStd::vector COpticsProxy::GetEditorParamGroups() -{ - return AZStd::vector(); -} -#endif - -COpticsProxy::COpticsProxy(const char* name) - : m_bEnable(false) - , m_name(name) - , m_pOpticsReference(NULL) -{ -} - -void COpticsProxy::Load(IXmlNode* pNode) -{ - XmlNodeRef pProxy = pNode->findChild("Proxy"); - if (pProxy) - { - const char* referenceName(NULL); - if (pProxy->getAttr("Reference", &referenceName)) - { - if (referenceName && referenceName[0]) - { - int nReferenceIndex(-1); - if (gEnv->pOpticsManager->Load(referenceName, nReferenceIndex)) - { - IOpticsElementBase* pOptics = gEnv->pOpticsManager->GetOptics(nReferenceIndex); - if (pOptics->GetType() == eFT_Reference) - { - m_pOpticsReference = (COpticsReference*)gEnv->pOpticsManager->GetOptics(nReferenceIndex); - } - } - } - } - } -} - -void COpticsProxy::GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const -{ -} - -void COpticsProxy::Invalidate() -{ -} - -void COpticsProxy::Render(SLensFlareRenderParam* pParam, const Vec3& vPos) -{ - if (m_pOpticsReference) - { - m_pOpticsReference->Render(pParam, vPos); - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.h b/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.h deleted file mode 100644 index e21f5eb3a6..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsProxy.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSPROXY_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSPROXY_H -#pragma once - -#include "OpticsReference.h" - -class COpticsProxy - : public IOpticsElementBase -{ -public: - - COpticsProxy(const char* name); - ~COpticsProxy(){} - - EFlareType GetType() { return eFT_Proxy; } - bool IsGroup() const { return false; } - - string GetName() const { return m_name; } - void SetName(const char* ch_name) { m_name = ch_name; } - void Load(IXmlNode* pNode); - - IOpticsElementBase* GetParent() const { return NULL; } - - bool IsEnabled() const { return m_bEnable; } - void SetEnabled(bool b) { m_bEnable = b; } - - void AddElement([[maybe_unused]] IOpticsElementBase* pElement) {} - void InsertElement([[maybe_unused]] int nPos, [[maybe_unused]] IOpticsElementBase* pElement) {} - void Remove([[maybe_unused]] int i) {} - void RemoveAll() {} - int GetElementCount() const { return 0; } - IOpticsElementBase* GetElementAt([[maybe_unused]] int i) const { return NULL; } - - void GetMemoryUsage(ICrySizer* pSizer) const; - void Invalidate(); - - void Render(SLensFlareRenderParam* pParam, const Vec3& vPos); - - void SetOpticsReference(IOpticsElementBase* pReference) - { - if (pReference->GetType() == eFT_Reference) - { - m_pOpticsReference = (COpticsReference*)pReference; - } - } - IOpticsElementBase* GetOpticsReference() const - { - return m_pOpticsReference; - } -#if defined(FLARES_SUPPORT_EDITING) - AZStd::vector GetEditorParamGroups(); -#endif - -public: - - bool m_bEnable; - string m_name; - _smart_ptr m_pOpticsReference; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSPROXY_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.cpp b/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.cpp deleted file mode 100644 index d93b5a17b0..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "OpticsReference.h" - -#if defined(FLARES_SUPPORT_EDITING) -AZStd::vector COpticsReference::GetEditorParamGroups() -{ - return AZStd::vector(); -} -#endif - -COpticsReference::COpticsReference(const char* name) - : m_name(name) -{ -} - -void COpticsReference::Load([[maybe_unused]] IXmlNode* pNode) -{ -} - -void COpticsReference::AddElement(IOpticsElementBase* pElement) -{ - m_OpticsList.push_back(pElement); -} - -void COpticsReference::InsertElement(int nPos, IOpticsElementBase* pElement) -{ - if (nPos < 0 || nPos >= (int)m_OpticsList.size()) - { - return; - } - m_OpticsList.insert(m_OpticsList.begin() + nPos, pElement); -} - -void COpticsReference::Remove(int i) -{ - if (i < 0 || i >= (int)m_OpticsList.size()) - { - return; - } - m_OpticsList.erase(m_OpticsList.begin() + i); -} - -void COpticsReference::RemoveAll() -{ - m_OpticsList.clear(); -} - -int COpticsReference::GetElementCount() const -{ - return m_OpticsList.size(); -} - -IOpticsElementBase* COpticsReference::GetElementAt(int i) const -{ - if (i < 0 || i >= (int)m_OpticsList.size()) - { - return NULL; - } - return m_OpticsList[i]; -} - -void COpticsReference::GetMemoryUsage(ICrySizer* pSizer) const -{ - for (int i = 0, iSize(m_OpticsList.size()); i < iSize; ++i) - { - m_OpticsList[i]->GetMemoryUsage(pSizer); - } -} - -void COpticsReference::Invalidate() -{ - for (int i = 0, iSize(m_OpticsList.size()); i < iSize; ++i) - { - m_OpticsList[i]->Invalidate(); - } -} - -void COpticsReference::Render(SLensFlareRenderParam* pParam, const Vec3& vPos) -{ - for (int i = 0, iSize(m_OpticsList.size()); i < iSize; ++i) - { - m_OpticsList[i]->Render(pParam, vPos); - } -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.h b/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.h deleted file mode 100644 index 0c8db4d7d0..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/OpticsReference.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSREFERENCE_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSREFERENCE_H -#pragma once - -#include "IFlares.h" - -class COpticsReference - : public IOpticsElementBase -{ -public: - -#if defined(FLARES_SUPPORT_EDITING) - AZStd::vector GetEditorParamGroups(); -#endif - - COpticsReference(const char* name); - ~COpticsReference(){} - - EFlareType GetType() { return eFT_Reference; } - bool IsGroup() const { return false; } - - string GetName() const { return m_name; } - void SetName(const char* ch_name) { m_name = ch_name; } - void Load(IXmlNode* pNode); - - IOpticsElementBase* GetParent() const { return NULL; } - - bool IsEnabled() const { return true; } - void SetEnabled([[maybe_unused]] bool b) {} - void AddElement(IOpticsElementBase* pElement); - void InsertElement(int nPos, IOpticsElementBase* pElement); - void Remove(int i); - void RemoveAll(); - int GetElementCount() const; - IOpticsElementBase* GetElementAt(int i) const; - - void GetMemoryUsage(ICrySizer* pSizer) const; - void Invalidate(); - - void Render(SLensFlareRenderParam* pParam, const Vec3& vPos); - -public: - string m_name; - std::vector m_OpticsList; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_OPTICSREFERENCE_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/RendElement.cpp b/Code/CryEngine/RenderDll/Common/RendElements/RendElement.cpp deleted file mode 100644 index c0e83ac804..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/RendElement.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : common RE functions. - - -#include "RenderDll_precompiled.h" - -//TArray CRendElementBase::m_AllREs; - -CRendElement CRendElement::m_RootGlobal; -CRendElement CRendElement::m_RootRelease[4]; - -//=============================================================== - -CryCriticalSection m_sREResLock; - -//============================================================================ - -void CRendElement::ShutDown() -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_releaseallresourcesonexit) - { - return; - } - - AUTO_LOCK(m_sREResLock); // Not thread safe without this - - CRendElement* pRE; - CRendElement* pRENext; - for (pRE = CRendElement::m_RootGlobal.m_NextGlobal; pRE != &CRendElement::m_RootGlobal; pRE = pRENext) - { - pRENext = pRE->m_NextGlobal; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_printmemoryleaks) - { - iLog->Log("Warning: CRendElementBase::ShutDown: RenderElement %s was not deleted", pRE->mfTypeString()); - } - pRE->Release(); - } -} - -void CRendElement::Tick() -{ -#ifndef STRIP_RENDER_THREAD - assert(gRenDev->m_pRT->IsMainThread(true)); -#endif - int nFrameID = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - int nFrame = nFrameID - 3; - CRendElement& Root = CRendElement::m_RootRelease[nFrame & 3]; - CRendElement* pRENext = NULL; - - for (CRendElement* pRE = Root.m_NextGlobal; pRE != &Root; pRE = pRENext) - { - pRENext = pRE->m_NextGlobal; - SAFE_DELETE(pRE); - } -} - -void CRendElement::Cleanup() -{ - gRenDev->m_pRT->FlushAndWait(); - - AUTO_LOCK(m_sREResLock); // Not thread safe without this - - for (int i = 0; i < 4; ++i) - { - CRendElement& Root = CRendElement::m_RootRelease[i]; - CRendElement* pRENext = NULL; - - for (CRendElement* pRE = Root.m_NextGlobal; pRE != &Root; pRE = pRENext) - { - pRENext = pRE->m_NextGlobal; - SAFE_DELETE(pRE); - } - } -} - -CRendElement::CRendElement() -{ - m_Type = eDATA_Unknown; - if (!m_RootGlobal.m_NextGlobal) - { - m_RootGlobal.m_NextGlobal = &m_RootGlobal; - m_RootGlobal.m_PrevGlobal = &m_RootGlobal; - for (int i = 0; i < 4; i++) - { - m_RootRelease[i].m_NextGlobal = &m_RootRelease[i]; - m_RootRelease[i].m_PrevGlobal = &m_RootRelease[i]; - } - } -} - - -CRendElement::~CRendElement() -{ - assert(m_Type == eDATA_Unknown || m_Type == eDATA_Particle || m_Type == eDATA_GPUParticle || m_Type == eDATA_Gem || m_Type == eDATA_VolumeObject); - - //@TODO: Fix later, prevent crash on exit in single executable - if (this == &m_RootRelease[0] || this == &m_RootRelease[1] || this == &m_RootRelease[2] || this == &m_RootRelease[3] || this == &m_RootGlobal) - { - return; - } - - AUTO_LOCK(m_sREResLock); - UnlinkGlobal(); -} - -void CRendElement::Release(bool bForce) -{ - CRendElementBase* pThis = (CRendElementBase*)this; - pThis->m_Flags |= FCEF_DELETED; - - m_Type = eDATA_Unknown; - if (bForce) - { - delete this; - return; - } - int nFrame = gRenDev->GetFrameID(false); - - AUTO_LOCK(m_sREResLock); - CRendElement& Root = CRendElement::m_RootRelease[nFrame & 3]; - UnlinkGlobal(); - LinkGlobal(&Root); -} - -CRendElementBase::CRendElementBase() -{ - m_Flags = 0; - m_nFrameUpdated = 0xffff; - m_CustomData = NULL; - m_NextGlobal = NULL; - m_PrevGlobal = NULL; - int i; - for (i = 0; i < MAX_CUSTOM_TEX_BINDS_NUM; i++) - { - m_CustomTexBind[i] = -1; - } - - AUTO_LOCK(m_sREResLock); - LinkGlobal(&m_RootGlobal); -} -CRendElementBase::~CRendElementBase() -{ - if ((m_Flags & FCEF_ALLOC_CUST_FLOAT_DATA) && m_CustomData) - { - delete [] ((float*)m_CustomData); - m_CustomData = 0; - } -} - -const char* CRendElement::mfTypeString() -{ - switch (m_Type) - { - case eDATA_Sky: - return "Sky"; - case eDATA_Beam: - return "Beam"; - case eDATA_ClientPoly: - return "ClientPoly"; - case eDATA_Flare: - return "Flare"; - case eDATA_Terrain: - return "Terrain"; - case eDATA_SkyZone: - return "SkyZone"; - case eDATA_Mesh: - return "Mesh"; - case eDATA_Imposter: - return "Imposter"; - case eDATA_LensOptics: - return "LensOptics"; - case eDATA_OcclusionQuery: - return "OcclusionQuery"; - case eDATA_Particle: - return "Particle"; - case eDATA_GPUParticle: - return "GPUParticle"; - case eDATA_PostProcess: - return "PostProcess"; - case eDATA_HDRProcess: - return "HDRProcess"; - case eDATA_Cloud: - return "Cloud"; - case eDATA_HDRSky: - return "HDRSky"; - case eDATA_FogVolume: - return "FogVolume"; - case eDATA_WaterVolume: - return "WaterVolume"; - case eDATA_WaterOcean: - return "WaterOcean"; - case eDATA_VolumeObject: - return "VolumeObject"; - case eDATA_PrismObject: - return "PrismObject"; - case eDATA_DeferredShading: - return "DeferredShading"; - case eDATA_GameEffect: - return "GameEffect"; - case eDATA_BreakableGlass: - return "BreakableGlass"; - case eDATA_GeomCache: - return "GeomCache"; - case eDATA_Gem: - return "Gem"; - default: - { - CRY_ASSERT(false); - return "Unknown"; - } - } -} - -CRendElementBase* CRendElementBase::mfCopyConstruct(void) -{ - CRendElementBase* re = new CRendElementBase; - *re = *this; - return re; -} -void CRendElementBase::mfCenter(Vec3& centr, [[maybe_unused]] CRenderObject* pObj) -{ - centr(0, 0, 0); -} -void CRendElementBase::mfGetPlane(Plane& pl) -{ - pl.n = Vec3(0, 0, 1); - pl.d = 0; -} - -//============================================================================= - -void* SRendItem::mfGetPointerCommon(ESrcPointer ePT, int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) -{ - int j; - switch (ePT) - { - case eSrcPointer_Vert: - *Stride = gRenDev->m_RP.m_StreamStride; - return gRenDev->m_RP.m_StreamPtr.PtrB; - - case eSrcPointer_Color: - *Stride = gRenDev->m_RP.m_StreamStride; - return gRenDev->m_RP.m_StreamPtr.PtrB + gRenDev->m_RP.m_StreamOffsetColor; - - case eSrcPointer_Tex: - case eSrcPointer_TexLM: - *Stride = gRenDev->m_RP.m_StreamStride; - j = ePT - eSrcPointer_Tex; - return gRenDev->m_RP.m_StreamPtr.PtrB + gRenDev->m_RP.m_StreamOffsetTC + j * 16; - } - return NULL; -} - diff --git a/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.cpp b/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.cpp deleted file mode 100644 index 3ca6e4e8a6..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "RootOpticsElement.h" -#include "FlareSoftOcclusionQuery.h" -#include "../Textures/Texture.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include "stdarg.h" - -enum EVisFader -{ - VISFADER_FLARE = 0, - VISFADER_SHAFT, - VISFADER_NUM -}; - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&RootOpticsElement::FUNC_NAME) -void RootOpticsElement::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsGroup::InitEditorParamGroups(groups); - - FuncVariableGroup rootGroup; - rootGroup.SetName("GlobalSettings", "Global Settings"); - rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable Occlusion", "Enable Occlusion", this, MFPtr(SetOcclusionEnabled), MFPtr(IsOcclusionEnabled))); - rootGroup.AddVariable(new OpticsMFPVariable(e_VEC2, "Occlusion Size", "The size for occlusion plane", this, MFPtr(SetOccSize), MFPtr(GetOccSize))); - rootGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Flare fade time", "The duration of flare afterimage fading in seconds", this, MFPtr(SetFlareFadingDuration), MFPtr(GetFlareFadingDuration))); - rootGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Shaft fade time", "The duration of shaft afterimage fading in seconds", this, MFPtr(SetShaftFadingDuration), MFPtr(GetShaftFadingDuration))); - rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light color", "light color can affect flare color", this, MFPtr(SetAffectedByLightColor), MFPtr(IsAffectedByLightColor))); - rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light radius", "light radius can affect flare fading", this, MFPtr(SetAffectedByLightRadius), MFPtr(IsAffectedByLightRadius))); - rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Affected by light FOV", "light projection FOV can affect flare fading", this, MFPtr(SetAffectedByLightFOV), MFPtr(IsAffectedByLightFOV))); - rootGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Multiply Color", "Select one of between Multiply and Addition about color calculation. If true, Multiply will be chosen.", this, MFPtr(SetMultiplyColor), MFPtr(IsMultiplyColor))); - groups.push_back(rootGroup); - - FuncVariableGroup sensorGroup; - sensorGroup.SetName("Sensor"); - sensorGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Custom Sensor Variation Map", "Enable Custom Sensor Variation Map", this, MFPtr(SetCustomSensorVariationMapEnabled), MFPtr(IsCustomSensorVariationMapEnabled))); - sensorGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Effective Sensor Size", "The size of image-able part of the sensor", this, MFPtr(SetEffectiveSensorSize), MFPtr(GetEffectiveSensorSize))); - groups.push_back(sensorGroup); -} -#undef MFPtr -#endif - -void RootOpticsElement::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pGloabalSettingsNode = pNode->findChild("GlobalSettings"); - if (pGloabalSettingsNode) - { - bool bOcclusionEnabled(m_bOcclusionEnabled); - if (pGloabalSettingsNode->getAttr("EnableOcclusion", bOcclusionEnabled)) - { - SetOcclusionEnabled(bOcclusionEnabled); - } - - Vec2 occlusionSize(m_OcclusionSize); - if (pGloabalSettingsNode->getAttr("OcclusionSize", occlusionSize)) - { - SetOccSize(occlusionSize); - } - - float fFlareTimelineDuration(m_fFlareTimelineDuration); - if (pGloabalSettingsNode->getAttr("Flarefadetime", fFlareTimelineDuration)) - { - SetFlareFadingDuration(fFlareTimelineDuration); - } - - float fShaftTimelineDuration(m_fShaftTimelineDuration); - if (pGloabalSettingsNode->getAttr("Flarefadetime", fShaftTimelineDuration)) - { - SetShaftFadingDuration(fShaftTimelineDuration); - } - - bool bAffectedByLightColor(m_bAffectedByLightColor); - if (pGloabalSettingsNode->getAttr("Affectedbylightcolor", bAffectedByLightColor)) - { - SetAffectedByLightColor(bAffectedByLightColor); - } - - bool bAffectedByLightRadius(m_bAffectedByLightRadius); - if (pGloabalSettingsNode->getAttr("Affectedbylightradius", bAffectedByLightRadius)) - { - SetAffectedByLightRadius(bAffectedByLightRadius); - } - - bool bAffectedByLightFOV(m_bAffectedByLightFOV); - if (pGloabalSettingsNode->getAttr("AffectedbylightFOV", bAffectedByLightFOV)) - { - SetAffectedByLightFOV(bAffectedByLightFOV); - } - - bool bMultiplyColor(m_bMultiplyColor); - if (pGloabalSettingsNode->getAttr("MultiplyColor", bMultiplyColor)) - { - SetMultiplyColor(bMultiplyColor); - } - } - - XmlNodeRef pSensorNode = pNode->findChild("Sensor"); - if (pSensorNode) - { - bool bCustomSensorVariationMap(m_bCustomSensorVariationMap); - if (pSensorNode->getAttr("CustomSensorVariationMap", bCustomSensorVariationMap)) - { - SetCustomSensorVariationMapEnabled(bCustomSensorVariationMap); - } - - float fEffectiveSensorSize(m_fEffectiveSensorSize); - if (pSensorNode->getAttr("EffectiveSensorSize", fEffectiveSensorSize)) - { - SetEffectiveSensorSize(fEffectiveSensorSize); - } - } -} - -void RootOpticsElement::SetOcclusionQuery(CFlareSoftOcclusionQuery* query) -{ - m_pOccQuery = query; -} - -float RootOpticsElement::GetFlareVisibilityFactor() const -{ - CSoftOcclusionVisiblityFader* pFader = m_pOccQuery ? m_pOccQuery->GetVisibilityFader(VISFADER_FLARE) : NULL; - return pFader ? pFader->m_fVisibilityFactor : 0.0f; -} - -float RootOpticsElement::GetShaftVisibilityFactor() const -{ - CSoftOcclusionVisiblityFader* pFader = m_pOccQuery ? m_pOccQuery->GetVisibilityFader(VISFADER_SHAFT) : NULL; - return pFader ? pFader->m_fVisibilityFactor : 0.0f; -} - -void RootOpticsElement::SetVisibilityFactor(float f) -{ - f = clamp_tpl(f, 0.f, 1.f); - - if (m_pOccQuery) - { - for (uint i = 0; i < VISFADER_NUM; ++i) - { - if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(i)) - { - pFader->m_fVisibilityFactor = f; - } - } - } -} - -CTexture* RootOpticsElement::GetOcclusionPattern() -{ - return m_pOccQuery->GetGatherTexture(); -} - -void RootOpticsElement::validateGlobalVars(SAuxParams& aux) -{ - m_globalPerpectiveFactor = m_fPerpectiveFactor; - m_globalDistanceFadingFactor = m_flareLight.m_bAttachToSun ? 0.0f : m_fDistanceFadingFactor; - m_globalSensorBrightnessFactor = m_fSensorBrightnessFactor; - m_globalSensorSizeFactor = m_fSensorSizeFactor; - m_globalSize = m_fSize; - m_globalFlareBrightness = GetBrightness(); - m_globalMovement = m_vMovement; - - if (m_bAffectedByLightColor) - { - if (aux.bMultiplyColor) - { - m_globalColor = ColorF(m_Color.r * m_flareLight.m_cLdrClr.r, m_Color.g * m_flareLight.m_cLdrClr.g, m_Color.b * m_flareLight.m_cLdrClr.b, m_Color.a); - } - else - { - m_globalColor = ColorF(m_Color.r + m_flareLight.m_cLdrClr.r, m_Color.g + m_flareLight.m_cLdrClr.g, m_Color.b + m_flareLight.m_cLdrClr.b, m_Color.a); - } - - m_globalFlareBrightness *= m_flareLight.m_fClrMultiplier; - } - else - { - m_globalColor = m_Color; - } - - if (m_bAffectedByLightRadius) - { - m_globalFlareBrightness *= clamp_tpl(1 - aux.distance / m_flareLight.m_fRadius, 0.0f, 1.0f); - } - - if (m_bAffectedByLightFOV) - { - m_globalFlareBrightness *= aux.viewAngleFalloff; - } - - float fShaftVisibilityFactor = aux.bForceRender ? 1.0f : GetShaftVisibilityFactor(); - float fFlareVisibilityFactor = aux.bForceRender ? 1.0f : GetFlareVisibilityFactor(); - - m_globalShaftBrightness = m_globalFlareBrightness * fShaftVisibilityFactor; - m_globalFlareBrightness *= fFlareVisibilityFactor; - - m_globalOcclusionBokeh = m_bOcclusionBokeh & IsOcclusionEnabled(); - m_globalCorrectAspectRatio = m_globalCorrectAspectRatio; - m_globalAutoRotation = m_globalAutoRotation; - m_globalOrbitAngle = m_fOrbitAngle; - m_globalTransform = m_mxTransform; - - COpticsGroup::validateChildrenGlobalVars(aux); -} - -void RootOpticsElement::Render(SLensFlareRenderParam* pParam, const Vec3& vPos) -{ - if (pParam == NULL) - { - return; - } - - if (!pParam->IsValid()) - { - return; - } - - SFlareLight light; - light.m_vPos = vPos; - light.m_fRadius = 10000.0f; - light.m_bAttachToSun = false; - light.m_cLdrClr = ColorF(1, 1, 1, 1); - light.m_fClrMultiplier = 1; - light.m_fViewAngleFalloff = 1; - - ProcessAll((CShader*)pParam->pShader, light, true, pParam->pCamera); -} - -bool RootOpticsElement::ProcessAll(CShader* shader, SFlareLight& light, bool bForceRender, CCamera* pCamera) -{ - CD3D9Renderer* pRD = gcpRendD3D; - - Vec3 vSrcWorldPos = light.m_vPos; - Vec3 vSrcProjPos; - - m_flareLight = light; - float linearDepth = 0; - float distance = 0; - - if (pCamera) - { - Matrix44A mProj, mView; - mathMatrixPerspectiveFov(&mProj, pCamera->GetFov(), pCamera->GetProjRatio(), pCamera->GetNearPlane(), pCamera->GetFarPlane()); - mathMatrixLookAt(&mView, pCamera->GetPosition(), pCamera->GetPosition() + pCamera->GetViewdir(), Vec3(0, 0, 1)); - if (!CFlareSoftOcclusionQuery::ComputeProjPos(vSrcWorldPos, mView, mProj, vSrcProjPos)) - { - return false; - } - linearDepth = clamp_tpl(CFlareSoftOcclusionQuery::ComputeLinearDepth(vSrcWorldPos, mView, pCamera->GetNearPlane(), pCamera->GetFarPlane()), -1.0f, 0.99f); - distance = mView.GetTranslation().GetDistance(vSrcWorldPos); - } - else - { - if (!CFlareSoftOcclusionQuery::ComputeProjPos(vSrcWorldPos, pRD->m_ViewMatrix, pRD->m_ProjMatrix, vSrcProjPos)) - { - return false; - } - - if (pRD->m_RP.m_TI[pRD->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - vSrcProjPos.z = 1.0f - vSrcProjPos.z; - } - - const CameraViewParameters& rc = gRenDev->GetViewParameters(); - linearDepth = clamp_tpl(CFlareSoftOcclusionQuery::ComputeLinearDepth(vSrcWorldPos, pRD->m_CameraMatrix, rc.fNear, rc.fFar), -1.0f, 0.99f); - distance = pRD->GetViewParameters().vOrigin.GetDistance(vSrcWorldPos); - } - - if (GetElementCount() <= 0 || !IsEnabled()) - { - return false; - } - - if (!bForceRender && (linearDepth <= 0 || !IsVisibleBasedOnLight(light, distance))) - { - return false; - } - - bool bVisible(!IsOcclusionEnabled()); - - if (!bVisible && !bForceRender) - { - float curTargetVisibility = 0.0f; - m_fFlareVisibilityFactor = m_fShaftVisibilityFactor = 0.0f; - - if (m_pOccQuery) - { - curTargetVisibility = m_pOccQuery->GetVisibility(); - - if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(VISFADER_FLARE)) - { - m_fFlareVisibilityFactor = pFader->UpdateVisibility(curTargetVisibility, m_fFlareTimelineDuration); - } - - if (CSoftOcclusionVisiblityFader* pFader = m_pOccQuery->GetVisibilityFader(VISFADER_SHAFT)) - { - m_fShaftVisibilityFactor = pFader->UpdateVisibility(curTargetVisibility, m_fShaftTimelineDuration); - } - } - - bVisible = IsVisible(); - } - - if (bVisible || bForceRender) - { - SAuxParams aux; - aux.linearDepth = linearDepth; - aux.distance = distance; - float x = vSrcProjPos.x * 2 - 1; - float y = vSrcProjPos.y * 2 - 1; - float unitLenSq = (x * x + y * y); - aux.sensorVariationValue = clamp_tpl((1 - powf(unitLenSq, 0.25f)) * 2 - 1, -1.0f, 1.0f); - aux.perspectiveShortening = clamp_tpl(10.f * (1.f - vSrcProjPos.z), 0.0f, 2.0f); - aux.viewAngleFalloff = light.m_fViewAngleFalloff; - aux.attachToSun = light.m_bAttachToSun; - aux.bMultiplyColor = IsMultiplyColor(); - aux.bForceRender = bForceRender; - - // The legacy entity system does not allow for overriding the color, brightness and size of lens flares. - // The new component systems does allow for overriding these values so we apply them only when valid - if (light.m_opticsParams.m_isValid) - { - SetColor(light.m_opticsParams.m_color); - SetBrightness(light.m_opticsParams.m_brightness); - SetSize(light.m_opticsParams.m_size); - } - validateGlobalVars(aux); - if (bForceRender || m_globalFlareBrightness > 0.001f || m_globalShaftBrightness > 0.001f) - { - gcpRendD3D->m_RP.m_PersFlags2 |= RBPF2_LENS_OPTICS_COMPOSITE; - COpticsGroup::Render(shader, vSrcWorldPos, vSrcProjPos, aux); - } - } - - return true; -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.h b/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.h deleted file mode 100644 index db614ce8a8..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/RootOpticsElement.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ROOTOPTICSELEMENT_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ROOTOPTICSELEMENT_H -#pragma once - -#include "OpticsGroup.h" -#include "Timeline.h" - -class CRenderObject; -class CFlareSoftOcclusionQuery; - -class RootOpticsElement - : public COpticsGroup -{ -public: - struct SFlareLight - { - Vec3 m_vPos; - ColorF m_cLdrClr; - float m_fClrMultiplier; - float m_fRadius; - float m_fViewAngleFalloff; - bool m_bAttachToSun; - SOpticsInstanceParameters m_opticsParams; - }; - -private: - - bool m_bChromaticAbrEnabled : 1; - bool m_bLateralChromaticAbr : 1; - float m_fChromaticAbrOffset; - float m_fChromaticAbrDir; - - float m_fEffectiveSensorSize; - bool m_bCustomSensorVariationMap : 1; - - bool m_bPostBlur : 1; - float m_fPostBlurAmount; - - bool m_bOcclusionEnabled : 1; - float m_fFlareVisibilityFactor; - float m_fShaftVisibilityFactor; - float m_fFlareTimelineDuration; - float m_fShaftTimelineDuration; - CFlareSoftOcclusionQuery* m_pOccQuery; - - bool m_bAffectedByLightColor : 1; - bool m_bAffectedByLightRadius : 1; - bool m_bAffectedByLightFOV : 1; - SFlareLight m_flareLight; - Vec2 m_OcclusionSize; - bool m_bMultiplyColor : 1; - -public: - - RootOpticsElement() - : COpticsGroup("@root") - , m_bChromaticAbrEnabled(false) - , m_bLateralChromaticAbr(false) - , m_fChromaticAbrOffset(0.002f) - , m_fChromaticAbrDir(0.785f) - , m_bOcclusionEnabled(true) - , m_fFlareVisibilityFactor(1) - , m_fShaftVisibilityFactor(1) - , m_pOccQuery(NULL) - , m_fEffectiveSensorSize(0.8f) - , m_bCustomSensorVariationMap(false) - , m_bAffectedByLightColor(false) - , m_bAffectedByLightRadius(false) - , m_bAffectedByLightFOV(true) - , m_bPostBlur(false) - , m_fPostBlurAmount(0) - , m_bMultiplyColor(true) - { - SetFlareFadingDuration(0.2f); - SetShaftFadingDuration(1.0f); - m_OcclusionSize = Vec2(0.02f, 0.02f); - m_fPerpectiveFactor = 1; - } - - ~RootOpticsElement() - { - } - - EFlareType GetType() { return eFT_Root; } - void validateGlobalVars(SAuxParams& aux); - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - - void Load(IXmlNode* pNode); - - using COpticsGroup::Render; - void Render(SLensFlareRenderParam* pParam, const Vec3& vPos); - bool ProcessAll(CShader* shader, SFlareLight& light, bool bForceRender = false, CCamera* pCamera = NULL); - - IOpticsElementBase* GetParent() const { return NULL; } - - float GetEffectiveSensorSize() const { return m_fEffectiveSensorSize; } - void SetEffectiveSensorSize(float s) { m_fEffectiveSensorSize = s; } - - bool IsCustomSensorVariationMapEnabled() const { return m_bCustomSensorVariationMap; } - void SetCustomSensorVariationMapEnabled(bool b) { m_bCustomSensorVariationMap = b; } - - bool IsVisible() const { return (m_fFlareVisibilityFactor > 0.0f) || (m_fShaftVisibilityFactor > 0.0f); } - bool IsVisibleBasedOnLight(const SFlareLight& light, float distance) const - { - return (!m_bAffectedByLightRadius || distance < light.m_fRadius) && - (!m_bAffectedByLightColor || ((light.m_cLdrClr.r > LensOpConst::_LO_MIN || light.m_cLdrClr.g > LensOpConst::_LO_MIN || light.m_cLdrClr.b > LensOpConst::_LO_MIN) && light.m_fClrMultiplier > LensOpConst::_LO_MIN)) && - (!m_bAffectedByLightFOV || light.m_fViewAngleFalloff > LensOpConst::_LO_MIN); - } - bool IsOcclusionEnabled() const { return m_bOcclusionEnabled; } - void SetOcclusionEnabled(bool b) - { - m_bOcclusionEnabled = b; - if (!b) - { - SetVisibilityFactor(1.0f); - } - } - - void SetOcclusionQuery(CFlareSoftOcclusionQuery* query); - CFlareSoftOcclusionQuery* GetOcclusionQuery() { return m_pOccQuery; } - - float GetFlareVisibilityFactor() const; - float GetShaftVisibilityFactor() const; - void SetVisibilityFactor(float f); - Vec2 GetOccSize() const - { - return m_OcclusionSize; - } - void SetOccSize(Vec2 vSize) - { - m_OcclusionSize = vSize; - } - - CTexture* GetOcclusionPattern(); - - float GetFlareFadingDuration() const { return m_fFlareTimelineDuration / 1e3f; } - void SetFlareFadingDuration(float d) { m_fFlareTimelineDuration = d * 1e3f; } - - float GetShaftFadingDuration() const { return m_fShaftTimelineDuration / 1e3f; } - void SetShaftFadingDuration(float d) { m_fShaftTimelineDuration = d * 1e3f; } - - bool IsAffectedByLightColor() const { return m_bAffectedByLightColor; } - void SetAffectedByLightColor(bool b) { m_bAffectedByLightColor = b; } - - bool IsAffectedByLightRadius() const { return m_bAffectedByLightRadius; } - void SetAffectedByLightRadius(bool b) { m_bAffectedByLightRadius = b; } - - bool IsAffectedByLightFOV() const { return m_bAffectedByLightFOV; } - void SetAffectedByLightFOV(bool b) { m_bAffectedByLightFOV = b; } - - bool IsMultiplyColor() const { return m_bMultiplyColor; } - void SetMultiplyColor(bool b) { m_bMultiplyColor = b; } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_ROOTOPTICSELEMENT_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Stars.h b/Code/CryEngine/RenderDll/Common/RendElements/Stars.h deleted file mode 100644 index e0c72f2655..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Stars.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_STARS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_STARS_H -#pragma once -class CStars -{ -public: - CStars(); - ~CStars(); - - void Render(bool bUseMoon); - -private: - bool LoadData(); - -private: - uint32 m_numStars; - _smart_ptr m_pStarMesh; - CShader* m_pShader; -}; - -#endif // #ifndef _STARS_H_ diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Streaks.cpp b/Code/CryEngine/RenderDll/Common/RendElements/Streaks.cpp deleted file mode 100644 index 3e7f3626fe..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Streaks.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "Streaks.h" -#include "RootOpticsElement.h" -#include "../CryNameR.h" -#include "../../RenderDll/XRenderD3D9/DriverD3D.h" - -#if defined(FLARES_SUPPORT_EDITING) -#define MFPtr(FUNC_NAME) (Optics_MFPtr)(&Streaks::FUNC_NAME) -void Streaks::InitEditorParamGroups(AZStd::vector& groups) -{ - COpticsElement::InitEditorParamGroups(groups); - - FuncVariableGroup streakGroup; - streakGroup.SetName("Streaks", "Streaks"); - streakGroup.AddVariable(new OpticsMFPVariable(e_BOOL, "Enable gradient tex", "Enable gradient texture", this, MFPtr(SetEnableSpectrumTex), MFPtr(GetEnableSpectrumTex))); - streakGroup.AddVariable(new OpticsMFPVariable(e_TEXTURE2D, "Gradient Tex", "Gradient Texture", this, MFPtr(SetSpectrumTex), MFPtr(GetSpectrumTex))); - streakGroup.AddVariable(new OpticsMFPVariable(e_INT, "Noise seed", "Noise seed", this, MFPtr(SetNoiseSeed), MFPtr(GetNoiseSeed), -255.0f, 255.0f)); - streakGroup.AddVariable(new OpticsMFPVariable(e_INT, "Streak count", "Number of streaks to generate", this, MFPtr(SetStreakCount), MFPtr(GetStreakCount), 0, 1000.0f)); - streakGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Thickness", "Thickness of the shafts", this, MFPtr(SetThickness), MFPtr(GetThickness))); - streakGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Thickness noise", "Noise strength of thickness variation", this, MFPtr(SetThicknessNoise), MFPtr(GetThicknessNoise))); - streakGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Size noise", "Noise strength of shafts' sizes", this, MFPtr(SetSizeNoise), MFPtr(GetSizeNoise))); - streakGroup.AddVariable(new OpticsMFPVariable(e_FLOAT, "Spacing noise", "Noise strength of shafts' spacing", this, MFPtr(SetSpacingNoise), MFPtr(GetSpacingNoise))); - groups.push_back(streakGroup); -} -#undef MFPtr -#endif - -void Streaks::Load(IXmlNode* pNode) -{ - COpticsElement::Load(pNode); - - XmlNodeRef pStreakNode = pNode->findChild("Streaks"); - - if (pStreakNode) - { - bool bUseSpectrumTex(m_bUseSpectrumTex); - if (pStreakNode->getAttr("Enablegradienttex", bUseSpectrumTex)) - { - SetEnableSpectrumTex(bUseSpectrumTex); - } - - const char* gradientTexName = NULL; - if (pStreakNode->getAttr("GradientTex", &gradientTexName)) - { - if (gradientTexName && gradientTexName[0]) - { - ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(gradientTexName); - SetSpectrumTex((CTexture*)pTexture); - if (pTexture) - { - pTexture->Release(); - } - } - } - - int nNoiseSeed(m_nNoiseSeed); - if (pStreakNode->getAttr("Noiseseed", nNoiseSeed)) - { - SetNoiseSeed(nNoiseSeed); - } - - int nStreakCount(m_nStreakCount); - if (pStreakNode->getAttr("Streakcount", nStreakCount)) - { - SetStreakCount(nStreakCount); - } - - float fThickness(m_fThickness); - if (pStreakNode->getAttr("Thickness", fThickness)) - { - SetThickness(fThickness); - } - - float fThicknessNoiseStrength(m_fThicknessNoiseStrength); - if (pStreakNode->getAttr("Thicknessnoise", fThicknessNoiseStrength)) - { - SetThicknessNoise(fThicknessNoiseStrength); - } - - float fSizeNoiseStrength(m_fSizeNoiseStrength); - if (pStreakNode->getAttr("Sizenoise", fSizeNoiseStrength)) - { - SetSizeNoise(fSizeNoiseStrength); - } - - float fSpacingNoiseStrength(m_fSpacingNoiseStrength); - if (pStreakNode->getAttr("Spacingnoise", fSpacingNoiseStrength)) - { - SetSpacingNoise(fSpacingNoiseStrength); - } - } -} - -void Streaks::DrawMesh() -{ - gcpRendD3D->FX_Commit(); - DrawMeshTriList(); -} - -void Streaks::GenMesh() -{ - stable_rand::setSeed((int)m_nNoiseSeed); - float dirDelta = 1.0f / (float)(m_separatedMeshList.size()); - - ColorF tint(1, 1, 1, 1); - for (uint32 i = 0; i < m_separatedMeshList.size(); i++) - { - float spacingNoise = 1 + stable_rand::randUnit() * m_fSpacingNoiseStrength; - - float dirUnit = (i * dirDelta + spacingNoise); - float dir = dirUnit; - - float randRadius = (1 + stable_rand::randUnit() * m_fSizeNoiseStrength); - float thickness = m_fThickness * (1 + stable_rand::randUnit() * m_fThicknessNoiseStrength); - - std::vector& vBuf = (m_separatedMeshList[i]); - MeshUtil::GenStreak(dir, randRadius, thickness, tint, vBuf, m_separatedMeshIndices); - } -} - -void Streaks::ApplySingleMesh(int n) -{ - m_vertBuf = m_separatedMeshList[n]; - m_idxBuf = m_separatedMeshIndices; - ApplyMesh(); -} - -void Streaks::Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, [[maybe_unused]] SAuxParams& aux) -{ - if (!IsVisible()) - { - return; - } - - PROFILE_LABEL_SCOPE("DRAW_Streaks"); - - gRenDev->m_RP.m_FlagsShader_RT = 0; - - vSrcProjPos = computeOrbitPos(vSrcProjPos, m_globalOrbitAngle); - shader->FXSetTechnique("Streaks"); - uint nPass; - shader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - ApplyGeneralFlags(shader); - ApplySpectrumTexFlag(shader, m_bUseSpectrumTex); - shader->FXBeginPass(0); - - // common params - ApplyCommonVSParams(shader, vSrcWorldPos, vSrcProjPos); - ApplyExternTintAndBrightnessVS(shader, m_globalColor, m_globalFlareBrightness); - - // meshCenter and brightness params - static CCryNameR meshCenterName("meshCenterAndBrt"); - float x = computeMovementLocationX(vSrcProjPos); - float y = computeMovementLocationY(vSrcProjPos); - Vec4 meshCenterParam(x, y, vSrcProjPos.z, 1); - shader->FXSetVSFloat(meshCenterName, &meshCenterParam, 1); - - // spectrum texture: - static STexState bilinearTS(FILTER_LINEAR, true); - bilinearTS.SetBorderColor(0); - bilinearTS.SetClampMode(TADDR_BORDER, TADDR_BORDER, TADDR_BORDER); - - if (m_bUseSpectrumTex) - { - if (m_pSpectrumTex == NULL) - { - m_pSpectrumTex = CTexture::ForName("EngineAssets/Textures/flares/spectrum_full.tif", FT_DONT_STREAM, eTF_Unknown); - if (m_pSpectrumTex) - { - m_pSpectrumTex->Release(); - } - } - m_pSpectrumTex->Apply(0, CTexture::GetTexState(bilinearTS)); - } - - ValidateMesh(); - for (uint32 i = 0; i < m_separatedMeshList.size(); i++) - { - ApplySingleMesh(i); - DrawMesh(); - } - shader->FXEndPass(); - shader->FXEnd(); -} - -void Streaks::GetMemoryUsage(ICrySizer* pSizer) const -{ - int nVertexSize(0); - for (int i = 0, iSize(m_separatedMeshList.size()); i < iSize; ++i) - { - nVertexSize += m_separatedMeshList[i].size() * sizeof(SVF_P3F_C4B_T2F); - } - pSizer->AddObject(this, sizeof(*this) + GetMeshDataSize() + nVertexSize + m_separatedMeshIndices.size() * sizeof(uint16)); -} diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Streaks.h b/Code/CryEngine/RenderDll/Common/RendElements/Streaks.h deleted file mode 100644 index 63c679acf5..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Streaks.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_STREAKS_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_STREAKS_H -#pragma once - -#include "OpticsElement.h" -#include "AbstractMeshElement.h" -#include "MeshUtil.h" - -class CTexture; -class Streaks - : public COpticsElement - , public AbstractMeshElement -{ -private: - _smart_ptr m_pSpectrumTex; - bool m_bUseSpectrumTex; - - int m_nStreakCount; - int m_nColorComplexity; - - // noise strengths - float m_fSizeNoiseStrength; - float m_fThicknessNoiseStrength; - float m_fSpacingNoiseStrength; - - float m_fThickness; - int m_nNoiseSeed; - -protected: - std::vector< std::vector > m_separatedMeshList; - std::vector< uint16 > m_separatedMeshIndices; - - // !Override - virtual void GenMesh(); - virtual void ApplySingleMesh(int n); - virtual void DrawMesh(); - void Invalidate() - { - m_meshDirty = true; - } - -public: - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ctor - Streaks (const char* name) - : COpticsElement(name, 0.5f) - , m_fThickness(0.3f) - , m_nNoiseSeed(81) - , m_fSizeNoiseStrength(0.8f) - , m_fThicknessNoiseStrength(0.6f) - , m_fSpacingNoiseStrength(0.2f) - , m_bUseSpectrumTex(false) - { - m_vMovement.x = 1.f; - m_vMovement.y = 1.f; - m_Color.a = 1.f; - - SetAutoRotation(false); - SetAspectRatioCorrection(true); - SetColorComplexity(2); - SetStreakCount(1); - - m_meshDirty = true; - } - -#if defined(FLARES_SUPPORT_EDITING) - void InitEditorParamGroups(AZStd::vector& groups); -#endif - EFlareType GetType() { return eFT_Streaks; } - void Render(CShader* shader, Vec3 vSrcWorldPos, Vec3 vSrcProjPos, SAuxParams& aux); - void Load(IXmlNode* pNode); - - bool GetEnableSpectrumTex() const { return m_bUseSpectrumTex; } - void SetEnableSpectrumTex(bool b) { m_bUseSpectrumTex = b; } - - CTexture* GetSpectrumTex() const { return m_pSpectrumTex; } - void SetSpectrumTex(CTexture* tex) { m_pSpectrumTex = tex; } - - int GetNoiseSeed() const { return m_nNoiseSeed; } - void SetNoiseSeed(int seed) - { - m_nNoiseSeed = seed; - m_meshDirty = true; - } - - int GetStreakCount() const { return m_nStreakCount; } - void SetStreakCount(int n) - { - m_nStreakCount = n; - m_separatedMeshList.resize(n); - m_meshDirty = true; - } - - int GetColorComplexity() const { return m_nColorComplexity; } - void SetColorComplexity(int n) - { - m_nColorComplexity = n; - m_meshDirty = true; - } - - float GetThickness() const { return m_fThickness; } - void SetThickness(float f) - { - m_fThickness = f; - m_meshDirty = true; - } - - float GetThicknessNoise() const { return m_fThicknessNoiseStrength; } - void SetThicknessNoise(float noise) - { - m_fThicknessNoiseStrength = noise; - m_meshDirty = true; - } - - float GetSizeNoise() const { return m_fSizeNoiseStrength; } - void SetSizeNoise(float noise) - { - m_fSizeNoiseStrength = noise; - m_meshDirty = true; - } - - float GetSpacingNoise() const { return m_fSpacingNoiseStrength; } - void SetSpacingNoise(float noise) - { - m_fSpacingNoiseStrength = noise; - m_meshDirty = true; - } - - void GetMemoryUsage(ICrySizer* pSizer) const; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_STREAKS_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Timeline.h b/Code/CryEngine/RenderDll/Common/RendElements/Timeline.h deleted file mode 100644 index b6c7d59fae..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Timeline.h +++ /dev/null @@ -1,159 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_TIMELINE_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_TIMELINE_H -#pragma once - -#include "Interpolator.h" - -template -class Timeline -{ -public: - enum LoopMode - { - NORMAL, REVERSE, LOOP - }; - -protected: - T prevYValue; - float prevXValue; - -public: - Interpolator* pInterp; - T startValue; - T endValue; - LoopMode loopMode; - float duration; // in milliseconds - float currentTime; // in milliseconds - - void init(T start, T end, float _duration, Interpolator* interp) - { - SetInterpolationRange(start, end); - prevYValue = start; - prevXValue = 0; - this->duration = _duration; - loopMode = NORMAL; - - pInterp = interp; - } - -protected: - float computeTimeStepping(float curTime, float elapsedMs) - { - switch (loopMode) - { - case NORMAL: - curTime += elapsedMs; - if (curTime > duration) - { - return duration; - } - case REVERSE: - curTime -= elapsedMs; - if (curTime < 0) - { - return 0; - } - case LOOP: - curTime += elapsedMs; - if (curTime > duration) - { - return fmod(curTime, duration); - } - } - - return curTime; - } - - void positCursorByRatio(float ratio) - { - switch (loopMode) - { - case NORMAL: - currentTime = ratio * duration; - break; - case REVERSE: - currentTime = (1 - ratio) * duration; - break; - case LOOP: - break; - } - } - -public: - - virtual ~Timeline() {} - Timeline(T start, T end, float _duration, Interpolator* interp) - { - currentTime = 0; - init(start, end, _duration, interp); - } - - Timeline(Interpolator* interp) - { - currentTime = 0; - init(0, 1, 1000, interp); - } - - // Accumulate time and produce the interpolated value accordingly - virtual T step(float elapsedMs) - { - currentTime = computeTimeStepping(currentTime, elapsedMs); - prevXValue = currentTime / duration; - - prevYValue = pInterp->compute(startValue, endValue, prevXValue); - return prevYValue; - } - - // Rewind the current time to initial position - virtual void rewind() - { - positCursorByRatio(0); - } - - void SetInterpolationRange(T start, T end) - { - startValue = start; - endValue = end; - } - - float GetPrevXValue() { return prevXValue; } - T GetPrevYValue() { return prevYValue; } -}; - -namespace { - float tempFloat0 = 0; - float tempFloat1 = 1; - int tempInt0 = 0; - int tempInt1 = 1; -} - -class TimelineFloat - : public Timeline -{ -public: - TimelineFloat() - : Timeline(0, 1, 1000, &InterpPredef::CUBIC_FLOAT) {} -}; - -class TimelineInt - : public Timeline -{ -public: - TimelineInt() - : Timeline(0, 1, 1000, &InterpPredef::CUBIC_INT) {} -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_TIMELINE_H diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.cpp b/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.cpp deleted file mode 100644 index 1bd6a5a6ae..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.cpp +++ /dev/null @@ -1,853 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Polygon math helper functions optimized for breakable glass sim - - -#include "RenderDll_precompiled.h" -#include "PolygonMath2D.h" - -#ifndef RELEASE -#define ASSERT_NUM_POLY_SIDES(numPts) {if (numPts < 0 || numPts > POLY_ARRAY_SIZE) { \ - CRY_ASSERT_MESSAGE(0, "[BreakGlassSystem Error]: Polygon too large, need to increase array sizes."); \ - CryLogAlways("[BreakGlassSystem Error]: Polygon too large, need to increase array sizes."); } \ -} -#else -#define ASSERT_NUM_POLY_SIDES(numPts) -#endif - -//-------------------------------------------------------------------------------------------------- -// Name: PointInTriangle2D -// Desc: Determines if a point is in the specified triangle -//-------------------------------------------------------------------------------------------------- -bool PointInTriangle2D(const Vec2& pt, const Vec2& a, const Vec2& b, const Vec2& c) -{ - float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; - float cCROSSap, bCROSScp, aCROSSbp; - - ax = c.x - b.x; - ay = c.y - b.y; - bx = a.x - c.x; - by = a.y - c.y; - cx = b.x - a.x; - cy = b.y - a.y; - - apx = pt.x - a.x; - apy = pt.y - a.y; - bpx = pt.x - b.x; - bpy = pt.y - b.y; - cpx = pt.x - c.x; - cpy = pt.y - c.y; - - aCROSSbp = ax * bpy - ay * bpx; - cCROSSap = cx * apy - cy * apx; - bCROSScp = bx * cpy - by * cpx; - - float ra = (float)fsel(aCROSSbp, 1.0f, 0.0f); - float rb = (float)fsel(cCROSSap, 1.0f, 0.0f); - float rc = (float)fsel(bCROSScp, 1.0f, 0.0f); - - return (ra + rb + rc) > 2.5f; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: TriangleIsConvex2D -// Desc: Determines if a triangle is convex (angle at B less than 180 degrees) -//-------------------------------------------------------------------------------------------------- -bool TriangleIsConvex2D(const Vec2& a, const Vec2& b, const Vec2& c) -{ - const Vec2 ba = a - b; - const Vec2 bc = c - b; - - const float cross = ba.x * bc.y - bc.x * ba.y; - return (cross < 0.0f); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: LineCircleIntersect2D -// Desc: Finds the intersection points (if any) between a line and circle -// Note: Returns the number of intersection points (0, 1 or 2) -//-------------------------------------------------------------------------------------------------- -int LineCircleIntersect2D(const Vec2& pt0, const Vec2& pt1, const Vec2& center, const float radiusSq, float& intersectA, float& intersectB) -{ - int numIntersects = 0; - - const Vec2 lineSegment = pt1 - pt0; - const Vec2 circleToLine = pt0 - center; - - // Check if there is an intersection - const float a = lineSegment.Dot(lineSegment); - const float b = 2.0f * circleToLine.Dot(lineSegment); - const float c = circleToLine.Dot(circleToLine) - radiusSq; - - float discriminant = b * b - 4 * a * c; - float isIntersection = min(discriminant, a); - - if (isIntersection >= 0.0f) - { - // Find exact intersection points (assuming infinite length line) - discriminant = sqrtf(discriminant); - float inv2A = 1.0f / (a + a); - - intersectA = (-b + discriminant) * inv2A; - intersectB = (-b - discriminant) * inv2A; - - // Found if either value valid - if (intersectA >= 0.0f && intersectA <= 1.0f) - { - ++numIntersects; - } - - if (intersectB >= 0.0f && intersectB <= 1.0f) - { - ++numIntersects; - } - } - - return numIntersects; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: PointInPolygon2D -// Desc: Determines if a point is in the specified polygon -// Note: Taken from "Cry_GeoOverlap.h" and cut down for our specific tests -//-------------------------------------------------------------------------------------------------- -bool PointInPolygon2D(const Vec2& pt, const Vec2* pPolygon, const int numPts) -{ - bool count = false; - - if (pPolygon) - { - for (int i = 0, j = 1; i < numPts; ++i, ++j) - { - j = (j == numPts) ? 0 : j; - - const Vec2& l0 = pPolygon[i]; - const Vec2& l1 = pPolygon[j]; - - if ((((l1.y < pt.y) && (pt.y < l0.y)) || ((l0.y < pt.y) && (pt.y < l1.y))) - && (pt.x < (l0.x - l1.x) * (pt.y - l1.y) / (l0.y - l1.y) + l1.x)) - { - count = !count; - } - } - } - - return count; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: CalculatePolygonArea2D -// Desc: Calculates the area covered by a 2D polygon -//-------------------------------------------------------------------------------------------------- -float CalculatePolygonArea2D(const Vec2* pPolygon, const int numPts) -{ - float area = 0.0f; - - if (pPolygon && numPts > 0) - { - for (int i = numPts - 1, j = 0; j < numPts; i = j++) - { - area += pPolygon[i].x * pPolygon[j].y; - area -= pPolygon[j].x * pPolygon[i].y; - } - } - - return area * 0.5f; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: CalculatePolygonBounds2D -// Desc: Calculates the AA size of a 2D polygon -//-------------------------------------------------------------------------------------------------- -Vec2 CalculatePolygonBounds2D(const Vec2* pPolygon, const int numPts) -{ - Vec2 bounds(Vec2_Zero); - - if (pPolygon && numPts > 0) - { - Vec2 minPt = pPolygon[0], maxPt = pPolygon[0]; - - for (int i = 1; i < numPts; ++i) - { - minPt.x = min(minPt.x, pPolygon[i].x); - minPt.y = min(minPt.y, pPolygon[i].y); - - maxPt.x = max(maxPt.x, pPolygon[i].x); - maxPt.y = max(maxPt.y, pPolygon[i].y); - } - - bounds = maxPt - minPt; - } - - return bounds; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: CalculatePolygonCenter2D -// Desc: Calculates the center of a 2D polygon -//-------------------------------------------------------------------------------------------------- -Vec2 CalculatePolygonCenter2D(const Vec2* pPolygon, const int numPts) -{ - Vec2 center(0.0f, 0.0f); - - if (pPolygon && numPts > 0) - { - const float size = (float)numPts; - - for (int i = 0; i < numPts; ++i) - { - center += pPolygon[i]; - } - - center /= size; - } - - return center; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: CalculatePolygonSharedPerimeter2D -// Desc: Calculates the connected percentage of fragments -// Note: Returns fraction of perimeter connected in two float params -//-------------------------------------------------------------------------------------------------- -bool CalculatePolygonSharedPerimeter2D(const Vec2* pPolygonA, const int numPtsA, const Vec2* pPolygonB, const int numPtsB, float& connectionA, float& connectionB) -{ - // Default values - const int minPolySize = 3; - connectionA = connectionB = 0.0f; - - ASSERT_NUM_POLY_SIDES(numPtsA); - ASSERT_NUM_POLY_SIDES(numPtsB); - - if (pPolygonA && numPtsA >= minPolySize && numPtsA <= POLY_ARRAY_SIZE - && pPolygonB && numPtsB >= minPolySize && numPtsB <= POLY_ARRAY_SIZE) - { - // Check for shared polygon points - TPolyIndexArray polyAShared, polyBShared; - - for (int i = 0; i < numPtsA; ++i) - { - for (int j = 0; j < numPtsB; ++j) - { - // Store matching points - if (pPolygonA[i] == pPolygonB[j]) - { - polyAShared.push_back(i); - polyBShared.push_back(j); - } - } - } - - // Valid connection found when two or more points shared - const bool connFound = (polyAShared.size() >= 2); - - // Calculate fraction of A that is shared - if (connFound) - { - // Calculate squared length of A's perimeter shared - const uint polyASize = polyAShared.size() - 1; - - for (uint i = 0; i < polyASize; ++i) - { - const Vec2& pt = pPolygonA[polyAShared[i]]; - const Vec2& nextPt = pPolygonA[polyAShared[i + 1]]; - - connectionA += (nextPt - pt).GetLength2(); - } - - // Calculate remaining squared perimeter length - float polyAPerimSq = connectionA; - int polyIndex = polyAShared.back(); - - while (polyIndex != polyAShared[0]) - { - polyIndex = (polyIndex + 1 == numPtsA) ? 0 : polyIndex + 1; - int nextPolyIndex = (polyIndex + 1 == numPtsA) ? 0 : polyIndex + 1; - - const Vec2& pt = pPolygonA[polyIndex]; - const Vec2& nextPt = pPolygonA[nextPolyIndex]; - - polyAPerimSq += (nextPt - pt).GetLength2(); - } - - // Convert to fraction - connectionA = sqrtf(connectionA / polyAPerimSq); - } - - // Calculate fraction of B that is shared - if (connFound) - { - // Calculate squared length of B's perimeter shared - const uint polyBSize = polyBShared.size() - 1; - - for (uint i = 0; i < polyBSize; ++i) - { - const Vec2& pt = pPolygonB[polyBShared[i]]; - const Vec2& nextPt = pPolygonB[polyBShared[i + 1]]; - - connectionB += (nextPt - pt).GetLength2(); - } - - // Calculate remaining squared perimeter length - float polyBPerimSq = connectionB; - int polyIndex = polyBShared.back(); - - while (polyIndex != polyBShared[0]) - { - polyIndex = (polyIndex + 1 == numPtsB) ? 0 : polyIndex + 1; - int nextPolyIndex = (polyIndex + 1 == numPtsB) ? 0 : polyIndex + 1; - - const Vec2& pt = pPolygonB[polyIndex]; - const Vec2& nextPt = pPolygonB[nextPolyIndex]; - - polyBPerimSq += (nextPt - pt).GetLength2(); - } - - // Convert to fraction - connectionB = sqrtf(connectionB / polyBPerimSq); - } - - // Successful - return true; - } - - return false; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: TriangulatePolygon2D -// Desc: Generates triangles from a polygon's in-order point list -//-------------------------------------------------------------------------------------------------- -void TriangulatePolygon2D(const Vec2* pPolygon, const int numPolyPts, PodArray* pVertices, PodArray* pIndices) -{ - ASSERT_NUM_POLY_SIDES(numPolyPts); - - if (pPolygon && numPolyPts >= 3 && numPolyPts <= POLY_ARRAY_SIZE && (pVertices || pIndices)) - { - int numPts = numPolyPts; - int numTris = numPts - 2; - - // Offset for output vertex data - int vertOffset = 0; - - if (pVertices) - { - vertOffset = pVertices->Count(); - pVertices->resize(vertOffset + numTris * 3); - } - - // Offset for output index data - int indOffset = 0; - - if (pIndices) - { - indOffset = pIndices->Count(); - pIndices->resize(indOffset + numTris * 3); - } - - // Simple case, push single triangle - if (numTris == 1) - { - if (pVertices) - { - (*pVertices)[vertOffset] = pPolygon[0]; - (*pVertices)[vertOffset + 1] = pPolygon[1]; - (*pVertices)[vertOffset + 2] = pPolygon[2]; - } - - if (pIndices) - { - (*pIndices)[indOffset] = 0; - (*pIndices)[indOffset + 1] = 1; - (*pIndices)[indOffset + 2] = 2; - } - } - - // Complex case, need to triangulate full point list - else if (numTris > 1) - { - // Initialise outline list as pIndices - TPolyIndexArray outline; - outline.resize(numPts); - - for (int i = 0; i < numPts; ++i) - { - outline[i] = i; - } - - // Already know the expected number of triangles - for (int i = 0; i < numTris; ++i) - { - int* pIterBegin = outline.begin(); - int* pIterEnd = outline.end(); - - int* pIterA = pIterBegin; - int* pIterB = pIterBegin; - int* pIterC = pIterBegin; - ++pIterB; - ++pIterC; - ++pIterC; - - // Loop around entire list and check for ears - for (int j = 0; j < numPts; ++j) - { - const Vec2& a = pPolygon[*pIterA]; - const Vec2& b = pPolygon[*pIterB]; - const Vec2& c = pPolygon[*pIterC]; - - // Valid ear triangles will be convex (internal angle < 180) - if (TriangleIsConvex2D(a, b, c)) - { - // Check valid triangles against all other outline points - int* pIterPt = pIterBegin; - bool isEar = true; - - do - { - if (pIterPt != pIterA && pIterPt != pIterB && pIterPt != pIterC) - { - const Vec2& pt = pPolygon[*pIterPt]; - - // When we have a point in the triangle, it means this is *not* an ear - if (PointInTriangle2D(pt, a, b, c)) - { - isEar = false; - break; - } - } - - ++pIterPt; - } while (pIterPt != pIterEnd); - - // Create triangle and clip ear when found - if (isEar) - { - if (pVertices) - { - (*pVertices)[vertOffset] = pPolygon[*pIterA]; - (*pVertices)[vertOffset + 1] = pPolygon[*pIterB]; - (*pVertices)[vertOffset + 2] = pPolygon[*pIterC]; - } - - if (pIndices) - { - (*pIndices)[indOffset] = *pIterA; - (*pIndices)[indOffset + 1] = *pIterB; - (*pIndices)[indOffset + 2] = *pIterC; - } - - // If ear is last point, erase immediately - if (*pIterB == *pIterEnd) - { - outline.pop_back(); - } - - // May need to shuffle points along (rather than erase) - else - { - while (pIterC != pIterEnd) - { - *pIterB = *pIterC; - ++pIterB; - ++pIterC; - - // Need to handle looping case - if (pIterB == pIterEnd) - { - pIterB = pIterBegin; - } - } - - outline.pop_back(); - } - - // Done with this ear - break; - } - } - - // Try next triangle - ++pIterA; - ++pIterB; - ++pIterC; - - // Treat outline as a ring buffer - pIterBegin = outline.begin(); - pIterEnd = outline.end(); - - if (pIterC == pIterEnd) - { - pIterC = pIterBegin; - } - else if (pIterB == pIterEnd) - { - pIterB = pIterBegin; - } - } - - // Clipped one ear point - --numPts; - vertOffset += 3; - indOffset += 3; - } - } - } -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: FindPolygonCircleSplitPoints -// Desc: Common code to finds the split points for SplitPolygonAroundPoint() varations -//-------------------------------------------------------------------------------------------------- -struct SPolyCircleSplit -{ - int A, B, ANext, BNext, numPtsToMove; - Vec2 ptA, ptB, ptMid; - bool allPtsInsideCircle, validSegment, cyclicSegment; -}; - -bool FindPolygonCircleSplitPoints(const Vec2* pPolygon, const int numPts, const Vec2& splitPt, const float splitRadius, SPolyCircleSplit& split) -{ - // Default data - const int invalidPt = -1; - split.A = split.B = invalidPt; - split.allPtsInsideCircle = true; - - if (pPolygon && numPts >= 3) - { - const float splitRadiusSq = splitRadius * splitRadius; - float intersectA, intersectB; - - // Loop round polygon - for (int i = 0; i < numPts; ++i) - { - // Check segment for intersection - int j = (i + 1 == numPts) ? 0 : i + 1; - - float tA, tB; - int numIntersects = LineCircleIntersect2D(pPolygon[i], pPolygon[j], splitPt, splitRadiusSq, tA, tB); - - // Store line intersection points if found - if (numIntersects == 1) - { - tA = (tA < 0.0f || tA > 1.0f) ? tB : tA; - - if (split.A == invalidPt) - { - split.A = i; - intersectA = tA; - } - else - { - split.B = i; - intersectB = tA; - break; - } - } - - // Can be a case where the circle intersects fully on one line. This - // means we can't really split the polygon though, so early out - else if (numIntersects == 2) - { - split.A = split.B = invalidPt; - intersectA = intersectB = 0.0f; - break; - } - - // Check if we still have all points inside the circle - if (split.allPtsInsideCircle) - { - const float distSq = (pPolygon[i] - splitPt).GetLength2(); - - if (distSq > splitRadiusSq) - { - split.allPtsInsideCircle = false; - } - } - } - - // Valid polygon segment? - if (split.validSegment = (split.A >= 0 && split.B >= 0 && split.A != split.B)) - { - // May need to swap points to ensure generating inner polygon - const float splitADistSq = (pPolygon[split.A] - splitPt).GetLength2(); - - if (splitADistSq < splitRadiusSq) - { - int temp = split.A; - split.A = split.B; - split.B = temp; - } - - // Calculate how many points in cut segment - split.cyclicSegment = split.A > split.B; - split.numPtsToMove = split.cyclicSegment ? (split.B + numPts) - split.A : split.B - split.A; - - if (split.numPtsToMove > 0) - { - // Calculate intersect points - split.ANext = (split.A + 1 == numPts) ? 0 : split.A + 1; - split.BNext = (split.B + 1 == numPts) ? 0 : split.B + 1; - - split.ptA = pPolygon[split.A] * intersectA + pPolygon[split.ANext] * (1.0f - intersectA); - split.ptB = pPolygon[split.B] * intersectB + pPolygon[split.BNext] * (1.0f - intersectB); - - // Extra mid-point lying on circle, for use with the outer polygon only - split.ptMid = (split.ptA + split.ptB) * 0.5f; - split.ptMid = splitPt + (split.ptMid - splitPt).Normalize() * splitRadius; - } - else - { - split.validSegment = false; - } - } - } - - return (split.validSegment && split.numPtsToMove > 0); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: SplitPolygonAroundPoint -// Desc: Splits a polygon outline along the radial line around the point -// Note: Removes verts from input data, then creates the INNER polygon piece. -// Does not do anything if polygon fully contains circle -//-------------------------------------------------------------------------------------------------- -void SplitPolygonAroundPoint(TPolygonArray& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline) -{ - const Vec2* pOutlinePts = outline.begin(); - const int outlineSize = outline.size(); - - // Build inner polygon if both split points where found, and they create a valid segment - SPolyCircleSplit split; - if (FindPolygonCircleSplitPoints(pOutlinePts, outlineSize, splitPt, splitRadius, split)) - { - // Create new inner polygon from split points and old polygon segment (if arrays large enough) - if (split.numPtsToMove > 0 && split.numPtsToMove <= POLY_ARRAY_SIZE - 2) - { - splitInnerOutline.resize(split.numPtsToMove + 2); - - splitInnerOutline[0] = split.ptA; - splitInnerOutline[split.numPtsToMove + 1] = split.ptB; - - for (int i = 1; i < split.numPtsToMove + 1; ++i) - { - int j = split.A + i; - j = (j >= outlineSize) ? j - outlineSize : j; - - splitInnerOutline[i] = pOutlinePts[j]; - } - } - else - { - splitInnerOutline.clear(); - } - - // Cyclic segment - need to delete both ends, then add intersect points - if (split.cyclicSegment) - { - const int numStartPts = split.B + 1; - const int numEndPts = outlineSize - (split.A + 1); - const bool canAddMidPt = (numStartPts + numEndPts >= 3); - - if (numEndPts > 0) - { - outline.erase(split.A + 1, numEndPts); - } - - if (numStartPts > 0) - { - outline.erase(0, numStartPts); - } - - outline.push_back(split.ptA); - if (canAddMidPt) - { - outline.push_back(split.ptMid); - } - outline.push_back(split.ptB); - } - - // Contiguous segment - single delete then insert intersect points - else - { - outline.erase(split.ANext, split.numPtsToMove); - - const bool splitTouchesEnd = (split.B == outlineSize - 1); - const bool canAddMidPt = (split.numPtsToMove >= 3); - if (splitTouchesEnd) - { - outline.push_back(split.ptA); - if (canAddMidPt) - { - outline.push_back(split.ptMid); - } - outline.push_back(split.ptB); - } - else - { - outline.insert_before(split.ptB, split.A + 1); - if (canAddMidPt) - { - outline.insert_before(split.ptMid, split.A + 1); - } - outline.insert_before(split.ptA, split.A + 1); - } - } - } - - // If failed, might be the case where entire polygon is inside - else if (split.allPtsInsideCircle) - { - // Move the polygon to the output list - splitInnerOutline.resize(outlineSize); - - for (int i = 0; i < outlineSize; ++i) - { - splitInnerOutline[i] = pOutlinePts[i]; - } - - outline.clear(); - } -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: SplitPolygonAroundPoint -// Desc: Splits a polygon outline along the radial line around the point -// Note: Removes verts from input data, then creates the INNER polygon piece. -// Does not do anything if polygon fully contains circle -//-------------------------------------------------------------------------------------------------- -void SplitPolygonAroundPoint(PodArray& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline) -{ - const Vec2* pOutlinePts = outline.begin(); - const int outlineSize = outline.Count(); - - // Build inner polygon if both split points where found, and they create a valid segment - SPolyCircleSplit split; - if (FindPolygonCircleSplitPoints(pOutlinePts, outlineSize, splitPt, splitRadius, split)) - { - // Create new inner polygon from split points and old polygon segment - splitInnerOutline.resize(split.numPtsToMove + 2); - - splitInnerOutline[0] = split.ptA; - splitInnerOutline[split.numPtsToMove + 1] = split.ptB; - - for (int i = 1; i < split.numPtsToMove + 1; ++i) - { - int j = split.A + i; - j = (j >= outlineSize) ? j - outlineSize : j; - - splitInnerOutline[i] = pOutlinePts[j]; - } - - // Cyclic segment - need to delete both ends, then add intersect points - if (split.cyclicSegment) - { - const int numStartPts = split.B + 1; - const int numEndPts = outlineSize - (split.A + 1); - - if (numEndPts > 0) - { - outline.Delete(split.A + 1, numEndPts); - } - - if (numStartPts > 0) - { - outline.Delete(0, numStartPts); - } - - outline.push_back(split.ptA); - outline.push_back(split.ptMid); - outline.push_back(split.ptB); - } - - // Contiguous segment - single delete then insert intersect points - else - { - outline.Delete(split.ANext, split.numPtsToMove); - - const bool splitTouchesEnd = split.B == outlineSize - 1; - if (splitTouchesEnd) - { - outline.push_back(split.ptA); - outline.push_back(split.ptMid); - outline.push_back(split.ptB); - } - else - { - outline.InsertBefore(split.ptB, split.A + 1); - outline.InsertBefore(split.ptMid, split.A + 1); - outline.InsertBefore(split.ptA, split.A + 1); - } - } - } - - // If failed, might be the case where entire polygon is inside - else if (split.allPtsInsideCircle) - { - // Move the polygon to the output list - splitInnerOutline.resize(outlineSize); - - for (int i = 0; i < outlineSize; ++i) - { - splitInnerOutline[i] = pOutlinePts[i]; - } - - outline.Clear(); - } -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: PolygonInCircle2D -// Desc: Determines if a polygon is contained within the specified circle -//-------------------------------------------------------------------------------------------------- -EPolygonInCircle2D PolygonInCircle2D(const Vec2& center, const float radius, const Vec2* pPolygon, const int numPts) -{ - EPolygonInCircle2D state = EPolygonInCircle2D_Outside; - - if (pPolygon && numPts >= 3) - { - const float radiusSq = radius * radius; - - Vec2 centerDir; - float centerDistSq; - int numPtsOutside = 0; - - // Check state of each point - for (int i = 0; i < numPts; ++i) - { - centerDir = center - pPolygon[i]; - centerDistSq = centerDir.GetLength2(); - - if (centerDistSq > radiusSq) - { - ++numPtsOutside; - } - } - - // Determine state - if (numPtsOutside == numPts) - { - state = EPolygonInCircle2D_Outside; - } - else if (numPtsOutside > 0) - { - state = EPolygonInCircle2D_Overlap; - } - else - { - state = EPolygonInCircle2D_Inside; - } - } - - return state; -}//------------------------------------------------------------------------------------------------- diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.h b/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.h deleted file mode 100644 index fd8cc1b292..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Utils/PolygonMath2D.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_POLYGONMATH2D_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_POLYGONMATH2D_H -#pragma once - -#include "CryFixedArray.h" - -//================================================================================================== -// Name: FixedPodArray -// Desc: Extension of CryFixedArray to add useful functionality -// Note: This should be promoted into CryFixedArray in the long term -// Author: Chris Bunner -//================================================================================================== -template -class FixedPodArray - : public CryFixedArray -{ - typedef CryFixedArray CFA; - -public: - ILINE void resize(const uint size) - { - if (size <= N) - { - CFA::m_curSize[0] = size; - } - else - { - CryLogAlways("FixedPodArray::resize() failing as size too large - NOT resizing array"); - CRY_ASSERT_MESSAGE(0, "FixedPodArray::resize() failing as size too large - NOT resizing array"); - } - } - - ILINE void erase(const uint index, const uint count = 1) - { - const uint size = CFA::m_curSize[0]; - - if (index == size - count) - { - // Simple remove - CFA::m_curSize[0] -= count; - } - else if (index + count < size) - { - // Shuffle set of elements along - const uint range = size - (index + count); - memmove(&CFA::at(index), &CFA::at(index + count), sizeof(T) * range); - - CFA::m_curSize[0] -= count; - } - else - { - CryLogAlways("FixedPodArray::erase() failing as element range invalid - NOT removing element"); - CRY_ASSERT_MESSAGE(0, "FixedPodArray::erase() failing as element range invalid - NOT removing element"); - } - } - - ILINE void insert_before(const T& elem, const uint index) - { - const uint size = CFA::m_curSize[0]; - - if (index < size && size < N) - { - // Shuffle set of elements along - const uint count = size - index; - memmove(&CFA::at(index + 1), &CFA::at(index), sizeof(T) * count); - - // Add new element - memcpy(&CFA::at(index), &elem, sizeof(T)); - ++CFA::m_curSize[0]; - } - else - { - CryLogAlways("FixedPodArray::insert_before() failing as element index invalid - NOT inserting element"); - CRY_ASSERT_MESSAGE(0, "FixedPodArray::insert_before() failing as element index invalid - NOT inserting element"); - } - } - - ILINE int find(const T& elem) - { - const uint size = CFA::m_curSize[0]; - const int invalid = -1; - - int index = invalid; - - for (uint i = 0; i < size; ++i) - { - if (CFA::at(i) == elem) - { - index = i; - break; - } - } - - return index; - } -}; - -//================================================================================================== -// Name: PolygonMath2D -// Desc: Polygon math helper functions optimized for breakable glass sim -// Note: Functions often assume clockwise polygon point order -// Author: Chris Bunner -//================================================================================================== - -// Common polygon array types -#define POLY_ARRAY_SIZE 45 - -typedef FixedPodArray TPolygonArray; -typedef FixedPodArray TPolyIndexArray; - -// 2D triangle helpers -bool PointInTriangle2D(const Vec2& pt, const Vec2& a, const Vec2& b, const Vec2& c); -bool TriangleIsConvex2D(const Vec2& a, const Vec2& b, const Vec2& c); - -// 2D intersection helpers -int LineCircleIntersect2D(const Vec2& pt0, const Vec2& pt1, const Vec2& center, const float radiusSq, float& intersectA, float& intersectB); - -// 2D polygon helpers -bool PointInPolygon2D(const Vec2& pt, const Vec2* pPolygon, const int numPts); - -float CalculatePolygonArea2D(const Vec2* pPolygon, const int numPts); -Vec2 CalculatePolygonBounds2D(const Vec2* pPolygon, const int numPts); -Vec2 CalculatePolygonCenter2D(const Vec2* pPolygon, const int numPts); -bool CalculatePolygonSharedPerimeter2D(const Vec2* pPolygonA, const int numPtsA, const Vec2* pPolygonB, const int numPtsB, float& connectionA, float& connectionB); - -void TriangulatePolygon2D(const Vec2* pPolygon, const int numPolyPts, PodArray* pVertices, PodArray* pIndices); -void SplitPolygonAroundPoint(TPolygonArray& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline); -void SplitPolygonAroundPoint(PodArray& outline, const Vec2& splitPt, const float splitRadius, TPolygonArray& splitInnerOutline); - -// Helper with result enum -enum EPolygonInCircle2D -{ - EPolygonInCircle2D_Inside = 0, - EPolygonInCircle2D_Outside, - EPolygonInCircle2D_Overlap -}; - -EPolygonInCircle2D PolygonInCircle2D(const Vec2& center, const float radius, const Vec2* pPolygon, const int numPts); - -#endif // _POLYGON_MATH_2D_ diff --git a/Code/CryEngine/RenderDll/Common/RendElements/Utils/SpatialHashGrid.h b/Code/CryEngine/RenderDll/Common/RendElements/Utils/SpatialHashGrid.h deleted file mode 100644 index be70d9e8c1..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendElements/Utils/SpatialHashGrid.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_SPATIALHASHGRID_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDELEMENTS_UTILS_SPATIALHASHGRID_H -#pragma once - -#if GLASSCFG_USE_HASH_GRID - -//================================================================================================== -// Name: CSpatialHashGrid -// Desc: Templated 2D spatial hashing grid spanning positively from origin -// Author: Chris Bunner -//================================================================================================== -template -class CSpatialHashGrid -{ -public: - CSpatialHashGrid(const float gridWidth, const float gridHeight); - ~CSpatialHashGrid(); - - uint32 HashPosition(const float x, const float y); - void AddElementToGrid(const float x, const float y, const T& elem); - void AddElementToGrid(const uint32 index, const T& elem); - void RemoveElementFromGrid(const float x, const float y, const T& elem); - void RemoveElementFromGrid(const uint32 index, const T& elem); - - void ClearGrid(); - -#ifndef RELEASE - void DebugDraw(); -#endif - - // Bucket accessors - ILINE const CryFixedArray* const GetBucket(const uint32 index) - { - return (index < m_area) ? &m_buckets[index] : NULL; - } - - ILINE uint32 GetNumBuckets() - { - return m_area; - } - - // Resizing - ILINE void Resize(const float gridWidth, const float gridHeight) - { - m_invCellWidth = m_fGridSize / gridWidth; - m_invCellHeight = m_fGridSize / gridHeight; - } - -private: - CSpatialHashGrid(const CSpatialHashGrid& rhs); - CSpatialHashGrid& operator = (const CSpatialHashGrid& rhs); - - uint32 m_gridSize; - uint32 m_area; - - float m_fGridSize; - float m_invCellWidth; - float m_invCellHeight; - - CryFixedArray m_buckets[GridSize * GridSize]; -};//------------------------------------------------------------------------------------------------ - -//-------------------------------------------------------------------------------------------------- -// Name: Constructor -//-------------------------------------------------------------------------------------------------- -template -CSpatialHashGrid::CSpatialHashGrid(const float gridWidth, const float gridHeight) - : m_gridSize(GridSize) - , m_area(GridSize * GridSize) - , m_fGridSize((float)GridSize) -{ - Resize(gridWidth, gridHeight); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: Destructor -//-------------------------------------------------------------------------------------------------- -template -CSpatialHashGrid::~CSpatialHashGrid() -{ -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: HashPosition -// Desc: Hashes a position to cell index and performs simple bounds checking -//-------------------------------------------------------------------------------------------------- -template -uint32 CSpatialHashGrid::HashPosition(const float x, const float y) -{ - const uint32 actualCellIndex = (uint32)(y * m_invCellHeight * m_fGridSize + x * m_invCellWidth); - const uint32 errorCellIndex = (uint32) - 1; - - float cellX = x * m_invCellWidth; - float cellY = y * m_invCellHeight; - - // Handle out of bounds - cellX = (float)fsel(cellX, cellX, -1.0f); - cellX = (float)fsel(m_fGridSize - cellX, cellX, -1.0f); - cellY = (float)fsel(cellY, cellY, -1.0f); - cellY = (float)fsel(m_fGridSize - cellY, cellY, -1.0f); - - cellX = min(cellX, cellY); - - const uint32 cellIndex = (cellX < 0.0f) ? errorCellIndex : actualCellIndex; - return cellIndex; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: AddElementToGrid -// Desc: Hashes and adds a unique element to the grid buckets -//-------------------------------------------------------------------------------------------------- -template -void CSpatialHashGrid::AddElementToGrid(const float x, const float y, const T& elem) -{ - uint32 elemCell = HashPosition(x, y); - AddElementToGrid(elemCell, elem); -} - -template -void CSpatialHashGrid::AddElementToGrid(const uint32 index, const T& elem) -{ - if (index < m_area) - { - // Only add unique elements - CryFixedArray* pBucket = &m_buckets[index]; - const uint numElems = pBucket->size(); - const T* pElems = pBucket->begin(); - int elemIndex = -1; - - if (numElems < BucketSize) - { - for (uint i = 0; i < numElems; ++i) - { - if (pElems[i] == elem) - { - elemIndex = i; - break; - } - } - - if (elemIndex == -1) - { - pBucket->push_back(elem); - } - } - } -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: RemoveElementFromGrid -// Desc: Hashes and removes an element from the grid buckets -//-------------------------------------------------------------------------------------------------- -template -void CSpatialHashGrid::RemoveElementFromGrid(const float x, const float y, const T& elem) -{ - uint32 elemCell = HashPosition(x, y); - RemoveElementFromGrid(elemCell, elem); -} - -template -void CSpatialHashGrid::RemoveElementFromGrid(const uint32 index, const T& elem) -{ - if (index < m_area) - { - CryFixedArray* pBucket = &m_buckets[index]; - const uint numElems = pBucket->size(); - T* pElems = pBucket->begin(); - - for (uint i = 0; i < numElems; ++i) - { - if (pElems[i] == elem) - { - pElems[i] = pElems[numElems - 1]; - pBucket->pop_back(); - break; - } - } - } -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: ClearGrid -// Desc: Clears all grid buckets -//-------------------------------------------------------------------------------------------------- -template -void CSpatialHashGrid::ClearGrid() -{ - for (uint32 i = 0; i < m_area; ++i) - { - m_buckets[i].clear(); - } -}//------------------------------------------------------------------------------------------------- - -#ifndef RELEASE -//-------------------------------------------------------------------------------------------------- -// Name: DebugDraw -// Desc: Draws the grid element counts to the screen -//-------------------------------------------------------------------------------------------------- -template -void CSpatialHashGrid::DebugDraw() -{ - IRenderAuxGeom* pRenderer = gEnv->pRenderer->GetIRenderAuxGeom(); - SAuxGeomRenderFlags oldFlags = pRenderer->GetRenderFlags(); - - SAuxGeomRenderFlags newFlags = e_Def2DPublicRenderflags; - newFlags.SetCullMode(e_CullModeNone); - newFlags.SetDepthWriteFlag(e_DepthWriteOff); - newFlags.SetAlphaBlendMode(e_AlphaBlended); - pRenderer->SetRenderFlags(newFlags); - - // Draw black backing - const float invWidth = 1.0f / (float)gEnv->pRenderer->GetWidth(); - const float invHeight = 1.0f / (float)gEnv->pRenderer->GetHeight(); - - const float minX = (322.5f - m_fGridSize * 15.0f) * invWidth; - const float maxX = (322.5f) * invWidth; - const float minY = (370.0f) * invHeight; - const float maxY = (370.0f + m_fGridSize * 15.0f) * invHeight; - - Vec3 quad[6] = - { - Vec3(minX, minY, 0.0f), - Vec3(minX, maxY, 0.0f), - Vec3(maxX, maxY, 0.0f), - - Vec3(minX, minY, 0.0f), - Vec3(maxX, maxY, 0.0f), - Vec3(maxX, minY, 0.0f) - }; - - pRenderer->DrawTriangles(quad, 6, ColorB(0, 0, 0, 127)); - pRenderer->SetRenderFlags(oldFlags); - - // Draw hash grid data - const ColorF col[8] = - { - ColorF(0.0f, 0.0f, 0.0f, 1.0f), - ColorF(1.0f, 0.0f, 0.0f, 1.0f), - ColorF(0.5f, 1.0f, 0.0f, 1.0f), - ColorF(0.0f, 1.0f, 0.0f, 1.0f), - ColorF(0.0f, 1.0f, 0.5f, 1.0f), - ColorF(0.0f, 0.5f, 1.0f, 1.0f), - ColorF(0.0f, 0.0f, 1.0f, 1.0f), - ColorF(0.5f, 0.0f, 1.0f, 1.0f), - }; - - float x = 315.0f, y = 370.0f; - - for (uint32 i = 0; i < m_gridSize; ++i) - { - for (uint32 j = 0; j < m_gridSize; ++j) - { - int index = i * m_gridSize + j; - int count = (int)m_buckets[index].size(); - ColorF textCol = col[min < int > (count, 7)]; - - if (count > 0) - { - textCol.r = textCol.r * 0.4f + 0.6f; - textCol.g = textCol.g * 0.4f + 0.6f; - textCol.b = textCol.b * 0.4f + 0.6f; - } - - gEnv->pRenderer->Draw2dLabel(x, y, 1.0f, &textCol.r, false, "%i", count); - y += 15.0f; - } - - x -= 15.0f; - y = 370.0f; - } -}//------------------------------------------------------------------------------------------------- -#endif // !RELEASE - -#endif // GLASSCFG_USE_HASH_GRID -#endif // _SPATIAL_HASH_GRID_ diff --git a/Code/CryEngine/RenderDll/Common/RenderAuxGeom.cpp b/Code/CryEngine/RenderDll/Common/RenderAuxGeom.cpp deleted file mode 100644 index 8330c278fe..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderAuxGeom.cpp +++ /dev/null @@ -1,2310 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RenderAuxGeom.h" -#include - -#if defined(ENABLE_RENDER_AUX_GEOM) - -static inline uint32 PackColor(const ColorB& col) -{ - return(((uint8) (col.a) << 24) + - ((uint8) (col.r) << 16) + - ((uint8) (col.g) << 8) + - ((uint8) (col.b))); -} - -static inline ColorB -ScaleColor(ColorB color, float scale) -{ - Vec3 col((float) color.r, (float) color.g, (float) color.b); - col *= scale; - return(ColorB((uint8) col.x, (uint8)col.y, (uint8) col.z, color.a)); -} - -static inline uint32 AlphaFlags(const ColorB& colV) -{ - if (colV.a > 0 && colV.a < 0xFF) - { - return e_AlphaBlended; - } - return 0; -} - -CAuxGeomCB::CAuxGeomCB(IRenderAuxGeomImpl* pRenderAuxGeom) - : m_pRenderAuxGeom(pRenderAuxGeom) - , m_lastFlushPos(0) -{ - assert(m_pRenderAuxGeom != 0); - m_cbCurrent = AddCBuffer(); -} - -CAuxGeomCB::~CAuxGeomCB() -{ - for (CBList::iterator it = m_cbData.begin(); it != m_cbData.end(); ++it) - { - delete *it; - } -} - - -void CAuxGeomCB::SetRenderFlags(const SAuxGeomRenderFlags& renderFlags) -{ - // make sure caller only tries to set public bits - assert(0 == (renderFlags.m_renderFlags & ~e_PublicParamsMask)); - m_cbCurrent->m_curRenderFlags = renderFlags; -} - - -SAuxGeomRenderFlags CAuxGeomCB::GetRenderFlags() -{ - return(m_cbCurrent->m_curRenderFlags); -} - - -void CAuxGeomCB::DrawPoint(const Vec3& v, const ColorB& col, uint8 size) -{ - assert(size > 0); - SAuxVertex* pVertex(0); - AddPrimitive(pVertex, 1, CreatePointRenderFlags(size)); - - pVertex->xyz = v; - pVertex->color.dcolor = PackColor(col); -} - - -void CAuxGeomCB::DrawPoints(const Vec3* v, uint32 numPoints, const ColorB& col, uint8 size) -{ - assert(size > 0); - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreatePointRenderFlags(size)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } -} - - -void CAuxGeomCB::DrawPoints(const Vec3* v, uint32 numPoints, const ColorB* col, uint8 size) -{ - assert(size > 0); - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreatePointRenderFlags(size)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } -} - -void CAuxGeomCB::DrawLine(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, float thickness) -{ - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, 2, CreateLineRenderFlags(false) | AlphaFlags(colV0) | AlphaFlags(colV1)); - - pVertices[ 0 ].xyz = v0; - pVertices[ 0 ].color.dcolor = PackColor(colV0); - pVertices[ 1 ].xyz = v1; - pVertices[ 1 ].color.dcolor = PackColor(colV1); - } - else - { - DrawThickLine(v0, colV0, v1, colV1, thickness); - } -} - - -void CAuxGeomCB::DrawLines(const Vec3* v, uint32 numPoints, const ColorB& col, float thickness) -{ - assert((numPoints >= 2) && (0 == (numPoints & 1))); - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreateLineRenderFlags(false) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } - } - else - { - for (uint32 i(0); i < numPoints; i += 2) - { - DrawThickLine(v[ i ], col, v[ i + 1], col, thickness); - } - } -} - - -void CAuxGeomCB::DrawLines(const Vec3* v, uint32 numPoints, const ColorB* col, float thickness) -{ - assert((numPoints >= 2) && (0 == (numPoints & 1))); - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreateLineRenderFlags(false)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } - } - else - { - for (uint32 i(0); i < numPoints; i += 2) - { - DrawThickLine(v[ i ], col[ i ], v[ i + 1], col[ i + 1 ], thickness); - } - } -} - - -void CAuxGeomCB::DrawLines(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB& col, float thickness) -{ - assert(numPoints >= 2); - assert((numIndices >= 2) && (0 == (numIndices & 1))); - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, numIndices, CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } - - memcpy(pIndices, ind, sizeof(pIndices[0]) * numIndices); - } - else - { - for (uint32 i(0); i < numIndices; i += 2) - { - DrawThickLine(v[ ind[ i ] ], col, v[ ind[ i + 1 ] ], col, thickness); - } - } -} - - -void CAuxGeomCB::DrawLines(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB* col, float thickness) -{ - assert(numPoints >= 2); - assert((numIndices >= 2) && (0 == (numIndices & 1))); - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, numIndices, CreateLineRenderFlags(true)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } - - memcpy(pIndices, ind, sizeof(pIndices[0]) * numIndices); - } - else - { - for (uint32 i(0); i < numIndices; i += 2) - { - DrawThickLine(v[ ind[ i ] ], col[ ind[ i ] ], v[ ind[ i + 1 ] ], col[ ind[ i + 1 ] ], thickness); - } - } -} - - -void CAuxGeomCB::DrawPolyline(const Vec3* v, uint32 numPoints, bool closed, const ColorB& col, float thickness) -{ - assert(numPoints >= 2); - assert(!closed || numPoints >= 3); // if "closed" then we need at least three vertices - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, (false != closed) ? 2 * numPoints : 2 * (numPoints - 1), CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } - - for (uint32 i(0); i < numPoints - 1; ++i) - { - pIndices[ 0 ] = i; - pIndices[ 1 ] = i + 1; - pIndices += 2; - } - if (false != closed) - { - pIndices[ 0 ] = numPoints - 1; - pIndices[ 1 ] = 0; - } - } - else - { - for (uint32 i(0); i < numPoints - 1; ++i) - { - DrawThickLine(v[ i ], col, v[ i + 1 ], col, thickness); - } - if (false != closed) - { - DrawThickLine(v[ numPoints - 1 ], col, v[ 0 ], col, thickness); - } - } -} - - -void CAuxGeomCB::DrawPolyline(const Vec3* v, uint32 numPoints, bool closed, const ColorB* col, float thickness) -{ - assert(numPoints >= 2); - assert(!closed || numPoints >= 3); // if "closed" then we need at least three vertices - - if (thickness <= 1.0f) - { - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, (false != closed) ? 2 * numPoints : 2 * (numPoints - 1), CreateLineRenderFlags(true)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } - - for (uint32 i(0); i < numPoints - 1; ++i) - { - pIndices[ 0 ] = i; - pIndices[ 1 ] = i + 1; - pIndices += 2; - } - if (false != closed) - { - pIndices[ 0 ] = numPoints - 1; - pIndices[ 1 ] = 0; - } - } - else - { - for (uint32 i(0); i < numPoints - 1; ++i) - { - DrawThickLine(v[ i ], col[ i ], v[ i + 1 ], col[ i + 1 ], thickness); - } - if (false != closed) - { - DrawThickLine(v[ numPoints - 1 ], col[ numPoints - 1 ], v[ 0 ], col[ 0 ], thickness); - } - } -} - - -void CAuxGeomCB::DrawThickLine(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, float thickness) -{ - assert(thickness > 0.0f); - assert(0 != gRenDev); - - // allocate space for two triangles - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, 6, CreateTriangleRenderFlags(false) | e_TriListParam_ProcessThickLines); - - // Encode paramaters for thick line in vertex memory. - // The actual "aux render" implementation has to process these before feeding it to the GPU. - // This was done as implementation needs access to several render specific informations - // (see D3DRenderAuxGeom.cpp for an implementation). - pVertices[ 0 ].xyz = v0; - pVertices[ 0 ].color.dcolor = PackColor(colV0); - pVertices[ 1 ].xyz = v1; - pVertices[ 1 ].color.dcolor = PackColor(colV1); - - pVertices[ 2 ].xyz = Vec3(thickness, 0.0f, 0.0f); -} - - -void CAuxGeomCB::DrawTriangle(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, const Vec3& v2, const ColorB& colV2) -{ - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, 3, CreateTriangleRenderFlags(false)); - - pVertices[ 0 ].xyz = v0; - pVertices[ 0 ].color.dcolor = PackColor(colV0); - - pVertices[ 1 ].xyz = v1; - pVertices[ 1 ].color.dcolor = PackColor(colV1); - - pVertices[ 2 ].xyz = v2; - pVertices[ 2 ].color.dcolor = PackColor(colV2); -} - - -void CAuxGeomCB::DrawTriangles(const Vec3* v, uint32 numPoints, const ColorB& col) -{ - assert((numPoints >= 3) && (0 == (numPoints % 3))); - - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreateTriangleRenderFlags(false)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } -} - - -void CAuxGeomCB::DrawTriangles(const Vec3* v, uint32 numPoints, const ColorB* col) -{ - assert((numPoints >= 3) && (0 == (numPoints % 3))); - - SAuxVertex* pVertices(0); - AddPrimitive(pVertices, numPoints, CreateTriangleRenderFlags(false)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } -} - - -void CAuxGeomCB::DrawTriangles(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB& col) -{ - assert(numPoints >= 3); - assert((numIndices >= 3) && (0 == (numIndices % 3))); - - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, numIndices, CreateTriangleRenderFlags(true)); - - uint32 color(PackColor(col)); - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = color; - } - - memcpy(pIndices, ind, sizeof(pIndices[0]) * numIndices); -} - - -void CAuxGeomCB::DrawTriangles(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB* col) -{ - assert(numPoints >= 3); - assert((numIndices >= 3) && (0 == (numIndices % 3))); - - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - AddIndexedPrimitive(pVertices, numPoints, pIndices, numIndices, CreateTriangleRenderFlags(true)); - - for (uint32 i(0); i < numPoints; ++i) - { - pVertices[ i ].xyz = v[ i ]; - pVertices[ i ].color.dcolor = PackColor(col[ i ]); - } - - memcpy(pIndices, ind, sizeof(pIndices[0]) * numIndices); -} - -void CAuxGeomCB::DrawQuad(float width, float height, const Matrix34& matWorld, const ColorB& col, bool drawShaded) -{ - if (width <= 0.0f && height <= 0.0f) - { - return; - } - - SAuxDrawObjParams* pDrawParams(0); - AddObject(pDrawParams, CreateObjectRenderFlags(eDOT_Quad)); - - Matrix34 scaleMatrix = Matrix33::CreateScale(Vec3(width, 1.0f, height)); - Matrix34 finalMatrix = matWorld * scaleMatrix; - - Matrix33 rotationMatrix; - matWorld.GetRotation33(rotationMatrix); - - pDrawParams->m_matWorld = finalMatrix; - pDrawParams->m_matWorldRotation = rotationMatrix; - pDrawParams->m_color = PackColor(col); - pDrawParams->m_size = max(width, height) * 0.5f; - pDrawParams->m_shaded = drawShaded; -} - - -void CAuxGeomCB::DrawAABB(const AABB& aabb, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle) -{ - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - - if (eBBD_Extremes_Color_Encoded == bbDrawStyle) - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 8, pIndices, 36, CreateTriangleRenderFlags(true)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - pIndices[ 6 ] = 7; - pIndices[ 7 ] = 6; - pIndices[ 8 ] = 5; - pIndices[ 9 ] = 7; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 4; - - pIndices[ 12 ] = 3; - pIndices[ 13 ] = 2; - pIndices[ 14 ] = 6; - pIndices[ 15 ] = 3; - pIndices[ 16 ] = 6; - pIndices[ 17 ] = 7; - - pIndices[ 18 ] = 4; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 1; - pIndices[ 21 ] = 4; - pIndices[ 22 ] = 1; - pIndices[ 23 ] = 0; - - pIndices[ 24 ] = 1; - pIndices[ 25 ] = 5; - pIndices[ 26 ] = 6; - pIndices[ 27 ] = 1; - pIndices[ 28 ] = 6; - pIndices[ 29 ] = 2; - - pIndices[ 30 ] = 4; - pIndices[ 31 ] = 0; - pIndices[ 32 ] = 3; - pIndices[ 33 ] = 4; - pIndices[ 34 ] = 3; - pIndices[ 35 ] = 7; - } - - uint32 color(PackColor(col)); - uint32 colorMin(PackColor(ColorB(15, 15, 15, col.a))); - uint32 colorMax(PackColor(ColorB(255, 255, 255, col.a))); - - pVertices[ 0 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ 0 ].color.dcolor = colorMin; - pVertices[ 1 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ 6 ].color.dcolor = colorMax; - pVertices[ 7 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ 7 ].color.dcolor = color; - } - else - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - - pVertices[ 0 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ 0 ].color.dcolor = color; - pVertices[ 1 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ 6 ].color.dcolor = color; - pVertices[ 7 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ 7 ].color.dcolor = color; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 24, pIndices, 36, CreateTriangleRenderFlags(true)); - - Vec3 xyz(aabb.min.x, aabb.min.y, aabb.min.z); - Vec3 xyZ(aabb.min.x, aabb.min.y, aabb.max.z); - Vec3 xYz(aabb.min.x, aabb.max.y, aabb.min.z); - Vec3 xYZ(aabb.min.x, aabb.max.y, aabb.max.z); - Vec3 Xyz(aabb.max.x, aabb.min.y, aabb.min.z); - Vec3 XyZ(aabb.max.x, aabb.min.y, aabb.max.z); - Vec3 XYz(aabb.max.x, aabb.max.y, aabb.min.z); - Vec3 XYZ(aabb.max.x, aabb.max.y, aabb.max.z); - - uint32 colDown(PackColor(ScaleColor(col, 0.5f))); - pVertices[ 0 ].xyz = xyz; - pVertices[ 0 ].color.dcolor = colDown; - pVertices[ 1 ].xyz = xYz; - pVertices[ 1 ].color.dcolor = colDown; - pVertices[ 2 ].xyz = XYz; - pVertices[ 2 ].color.dcolor = colDown; - pVertices[ 3 ].xyz = Xyz; - pVertices[ 3 ].color.dcolor = colDown; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - uint32 colTop(PackColor(col)); - pVertices[ 4 ].xyz = xyZ; - pVertices[ 4 ].color.dcolor = colTop; - pVertices[ 5 ].xyz = XyZ; - pVertices[ 5 ].color.dcolor = colTop; - pVertices[ 6 ].xyz = XYZ; - pVertices[ 6 ].color.dcolor = colTop; - pVertices[ 7 ].xyz = xYZ; - pVertices[ 7 ].color.dcolor = colTop; - - pIndices[ 6 ] = 4; - pIndices[ 7 ] = 5; - pIndices[ 8 ] = 6; - pIndices[ 9 ] = 4; - pIndices[ 10 ] = 6; - pIndices[ 11 ] = 7; - - uint32 colBack(PackColor(ScaleColor(col, 0.6f))); - pVertices[ 8 ].xyz = xyz; - pVertices[ 8 ].color.dcolor = colBack; - pVertices[ 9 ].xyz = Xyz; - pVertices[ 9 ].color.dcolor = colBack; - pVertices[ 10 ].xyz = XyZ; - pVertices[ 10 ].color.dcolor = colBack; - pVertices[ 11 ].xyz = xyZ; - pVertices[ 11 ].color.dcolor = colBack; - - pIndices[ 12 ] = 8; - pIndices[ 13 ] = 9; - pIndices[ 14 ] = 10; - pIndices[ 15 ] = 8; - pIndices[ 16 ] = 10; - pIndices[ 17 ] = 11; - - uint32 colFront(PackColor(ScaleColor(col, 0.9f))); - pVertices[ 12 ].xyz = xYz; - pVertices[ 12 ].color.dcolor = colFront; - pVertices[ 13 ].xyz = xYZ; - pVertices[ 13 ].color.dcolor = colFront; - pVertices[ 14 ].xyz = XYZ; - pVertices[ 14 ].color.dcolor = colFront; - pVertices[ 15 ].xyz = XYz; - pVertices[ 15 ].color.dcolor = colFront; - - pIndices[ 18 ] = 12; - pIndices[ 19 ] = 13; - pIndices[ 20 ] = 14; - pIndices[ 21 ] = 12; - pIndices[ 22 ] = 14; - pIndices[ 23 ] = 15; - - uint32 colLeft(PackColor(ScaleColor(col, 0.7f))); - pVertices[ 16 ].xyz = xyz; - pVertices[ 16 ].color.dcolor = colLeft; - pVertices[ 17 ].xyz = xyZ; - pVertices[ 17 ].color.dcolor = colLeft; - pVertices[ 18 ].xyz = xYZ; - pVertices[ 18 ].color.dcolor = colLeft; - pVertices[ 19 ].xyz = xYz; - pVertices[ 19 ].color.dcolor = colLeft; - - pIndices[ 24 ] = 16; - pIndices[ 25 ] = 17; - pIndices[ 26 ] = 18; - pIndices[ 27 ] = 16; - pIndices[ 28 ] = 18; - pIndices[ 29 ] = 19; - - uint32 colRight(PackColor(ScaleColor(col, 0.8f))); - pVertices[ 20 ].xyz = Xyz; - pVertices[ 20 ].color.dcolor = colRight; - pVertices[ 21 ].xyz = XYz; - pVertices[ 21 ].color.dcolor = colRight; - pVertices[ 22 ].xyz = XYZ; - pVertices[ 22 ].color.dcolor = colRight; - pVertices[ 23 ].xyz = XyZ; - pVertices[ 23 ].color.dcolor = colRight; - - pIndices[ 30 ] = 20; - pIndices[ 31 ] = 21; - pIndices[ 32 ] = 22; - pIndices[ 33 ] = 20; - pIndices[ 34 ] = 22; - pIndices[ 35 ] = 23; - } - } -} - - -void CAuxGeomCB::DrawAABBs(const AABB* aabbs, uint32 aabbCount, bool bSolid, const ColorB& col, - const EBoundingBoxDrawStyle& bbDrawStyle) -{ - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - - if (eBBD_Extremes_Color_Encoded == bbDrawStyle) - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8 * aabbCount, pIndices, 24 * aabbCount, CreateLineRenderFlags(true)); - - for (size_t i = 0; i < aabbCount; ++i) - { - size_t n = i * 24; - size_t nv = i * 8; - pIndices[ n + 0 ] = 0; - pIndices[ n + 1 ] = nv + 1; - pIndices[ n + 2 ] = 1; - pIndices[ n + 3 ] = nv + 2; - pIndices[ n + 4 ] = 2; - pIndices[ n + 5 ] = nv + 3; - pIndices[ n + 6 ] = 3; - pIndices[ n + 7 ] = nv + 0; - - pIndices[ n + 8 ] = 4; - pIndices[ n + 9 ] = nv + 5; - pIndices[ n + 10 ] = 5; - pIndices[ n + 11 ] = nv + 6; - pIndices[ n + 12 ] = 6; - pIndices[ n + 13 ] = nv + 7; - pIndices[ n + 14 ] = 7; - pIndices[ n + 15 ] = nv + 4; - - pIndices[ n + 16 ] = 0; - pIndices[ n + 17 ] = nv + 4; - pIndices[ n + 18 ] = 1; - pIndices[ n + 19 ] = nv + 5; - pIndices[ n + 20 ] = 2; - pIndices[ n + 21 ] = nv + 6; - pIndices[ n + 22 ] = 3; - pIndices[ n + 23 ] = nv + 7; - } - } - else - { - AddIndexedPrimitive(pVertices, 8 * aabbCount, pIndices, 36 * aabbCount, CreateTriangleRenderFlags(true)); - - for (size_t i = 0; i < aabbCount; ++i) - { - size_t n = i * 36; - size_t nv = i * 8; - - pIndices[ n + 0 ] = nv + 0; - pIndices[ n + 1 ] = nv + 1; - pIndices[ n + 2 ] = nv + 2; - pIndices[ n + 3 ] = nv + 0; - pIndices[ n + 4 ] = nv + 2; - pIndices[ n + 5 ] = nv + 3; - - pIndices[ n + 6 ] = nv + 7; - pIndices[ n + 7 ] = nv + 6; - pIndices[ n + 8 ] = nv + 5; - pIndices[ n + 9 ] = nv + 7; - pIndices[ n + 10 ] = nv + 5; - pIndices[ n + 11 ] = nv + 4; - - pIndices[ n + 12 ] = nv + 3; - pIndices[ n + 13 ] = nv + 2; - pIndices[ n + 14 ] = nv + 6; - pIndices[ n + 15 ] = nv + 3; - pIndices[ n + 16 ] = nv + 6; - pIndices[ n + 17 ] = nv + 7; - - pIndices[ n + 18 ] = nv + 4; - pIndices[ n + 19 ] = nv + 5; - pIndices[ n + 20 ] = nv + 1; - pIndices[ n + 21 ] = nv + 4; - pIndices[ n + 22 ] = nv + 1; - pIndices[ n + 23 ] = nv + 0; - - pIndices[ n + 24 ] = nv + 1; - pIndices[ n + 25 ] = nv + 5; - pIndices[ n + 26 ] = nv + 6; - pIndices[ n + 27 ] = nv + 1; - pIndices[ n + 28 ] = nv + 6; - pIndices[ n + 29 ] = nv + 2; - - pIndices[ n + 30 ] = nv + 4; - pIndices[ n + 31 ] = nv + 0; - pIndices[ n + 32 ] = nv + 3; - pIndices[ n + 33 ] = nv + 4; - pIndices[ n + 34 ] = nv + 3; - pIndices[ n + 35 ] = nv + 7; - } - } - - uint32 color(PackColor(col)); - uint32 colorMin(PackColor(ColorB(15, 15, 15, col.a))); - uint32 colorMax(PackColor(ColorB(255, 255, 255, col.a))); - - for (size_t i = 0; i < aabbCount; ++i) - { - const AABB& aabb = aabbs[i]; - - size_t n = i * 8; - pVertices[ n + 0 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ n + 0 ].color.dcolor = colorMin; - pVertices[ n + 1 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ n + 1 ].color.dcolor = color; - pVertices[ n + 2 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ n + 2 ].color.dcolor = color; - pVertices[ n + 3 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ n + 3 ].color.dcolor = color; - pVertices[ n + 4 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ n + 4 ].color.dcolor = color; - pVertices[ n + 5 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ n + 5 ].color.dcolor = color; - pVertices[ n + 6 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ n + 6 ].color.dcolor = colorMax; - pVertices[ n + 7 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ n + 7 ].color.dcolor = color; - } - } - else - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8 * aabbCount, pIndices, 24 * aabbCount, CreateLineRenderFlags(true)); - - uint32 color(PackColor(col)); - - for (size_t i = 0; i < aabbCount; ++i) - { - const AABB& aabb = aabbs[i]; - size_t nv = i * 24; - size_t n = i * 8; - - pVertices[ nv + 0 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ nv + 0 ].color.dcolor = color; - pVertices[ nv + 1 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ nv + 1 ].color.dcolor = color; - pVertices[ nv + 2 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ nv + 2 ].color.dcolor = color; - pVertices[ nv + 3 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ nv + 3 ].color.dcolor = color; - pVertices[ nv + 4 ].xyz = Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ nv + 4 ].color.dcolor = color; - pVertices[ nv + 5 ].xyz = Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ nv + 5 ].color.dcolor = color; - pVertices[ nv + 6 ].xyz = Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ nv + 6 ].color.dcolor = color; - pVertices[ nv + 7 ].xyz = Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ nv + 7 ].color.dcolor = color; - - pIndices[ n + 0 ] = nv + 0; - pIndices[ n + 1 ] = nv + 1; - pIndices[ n + 2 ] = nv + 1; - pIndices[ n + 3 ] = nv + 2; - pIndices[ n + 4 ] = nv + 2; - pIndices[ n + 5 ] = nv + 3; - pIndices[ n + 6 ] = nv + 3; - pIndices[ n + 7 ] = nv + 0; - - pIndices[ n + 8 ] = nv + 4; - pIndices[ n + 9 ] = nv + 5; - pIndices[ n + 10 ] = nv + 5; - pIndices[ n + 11 ] = nv + 6; - pIndices[ n + 12 ] = nv + 6; - pIndices[ n + 13 ] = nv + 7; - pIndices[ n + 14 ] = nv + 7; - pIndices[ n + 15 ] = nv + 4; - - pIndices[ n + 16 ] = nv + 0; - pIndices[ n + 17 ] = nv + 4; - pIndices[ n + 18 ] = nv + 1; - pIndices[ n + 19 ] = nv + 5; - pIndices[ n + 20 ] = nv + 2; - pIndices[ n + 21 ] = nv + 6; - pIndices[ n + 22 ] = nv + 3; - pIndices[ n + 23 ] = nv + 7; - } - } - else - { - AddIndexedPrimitive(pVertices, 24 * aabbCount, pIndices, 36 * aabbCount, CreateTriangleRenderFlags(true)); - - for (size_t i = 0; i < aabbCount; ++i) - { - const AABB& aabb = aabbs[i]; - - size_t n = i * 36; - size_t nv = i * 24; - - Vec3 xyz(aabb.min.x, aabb.min.y, aabb.min.z); - Vec3 xyZ(aabb.min.x, aabb.min.y, aabb.max.z); - Vec3 xYz(aabb.min.x, aabb.max.y, aabb.min.z); - Vec3 xYZ(aabb.min.x, aabb.max.y, aabb.max.z); - Vec3 Xyz(aabb.max.x, aabb.min.y, aabb.min.z); - Vec3 XyZ(aabb.max.x, aabb.min.y, aabb.max.z); - Vec3 XYz(aabb.max.x, aabb.max.y, aabb.min.z); - Vec3 XYZ(aabb.max.x, aabb.max.y, aabb.max.z); - - uint32 colDown(PackColor(ScaleColor(col, 0.5f))); - pVertices[ nv + 0 ].xyz = xyz; - pVertices[ nv + 0 ].color.dcolor = colDown; - pVertices[ nv + 1 ].xyz = xYz; - pVertices[ nv + 1 ].color.dcolor = colDown; - pVertices[ nv + 2 ].xyz = XYz; - pVertices[ nv + 2 ].color.dcolor = colDown; - pVertices[ nv + 3 ].xyz = Xyz; - pVertices[ nv + 3 ].color.dcolor = colDown; - - pIndices[ n + 0 ] = nv + 0; - pIndices[ n + 1 ] = nv + 1; - pIndices[ n + 2 ] = nv + 2; - pIndices[ n + 3 ] = nv + 0; - pIndices[ n + 4 ] = nv + 2; - pIndices[ n + 5 ] = nv + 3; - - uint32 colTop(PackColor(col)); - pVertices[ nv + 4 ].xyz = xyZ; - pVertices[ nv + 4 ].color.dcolor = colTop; - pVertices[ nv + 5 ].xyz = XyZ; - pVertices[ nv + 5 ].color.dcolor = colTop; - pVertices[ nv + 6 ].xyz = XYZ; - pVertices[ nv + 6 ].color.dcolor = colTop; - pVertices[ nv + 7 ].xyz = xYZ; - pVertices[ nv + 7 ].color.dcolor = colTop; - - pIndices[ n + 6 ] = nv + 4; - pIndices[ n + 7 ] = nv + 5; - pIndices[ n + 8 ] = nv + 6; - pIndices[ n + 9 ] = nv + 4; - pIndices[ n + 10 ] = nv + 6; - pIndices[ n + 11 ] = nv + 7; - - uint32 colBack(PackColor(ScaleColor(col, 0.6f))); - pVertices[ nv + 8 ].xyz = xyz; - pVertices[ nv + 8 ].color.dcolor = colBack; - pVertices[ nv + 9 ].xyz = Xyz; - pVertices[ nv + 9 ].color.dcolor = colBack; - pVertices[ nv + 10 ].xyz = XyZ; - pVertices[ nv + 10 ].color.dcolor = colBack; - pVertices[ nv + 11 ].xyz = xyZ; - pVertices[ nv + 11 ].color.dcolor = colBack; - - pIndices[ n + 12 ] = nv + 8; - pIndices[ n + 13 ] = nv + 9; - pIndices[ n + 14 ] = nv + 10; - pIndices[ n + 15 ] = nv + 8; - pIndices[ n + 16 ] = nv + 10; - pIndices[ n + 17 ] = nv + 11; - - uint32 colFront(PackColor(ScaleColor(col, 0.9f))); - pVertices[ nv + 12 ].xyz = xYz; - pVertices[ nv + 12 ].color.dcolor = colFront; - pVertices[ nv + 13 ].xyz = xYZ; - pVertices[ nv + 13 ].color.dcolor = colFront; - pVertices[ nv + 14 ].xyz = XYZ; - pVertices[ nv + 14 ].color.dcolor = colFront; - pVertices[ nv + 15 ].xyz = XYz; - pVertices[ nv + 15 ].color.dcolor = colFront; - - pIndices[ n + 18 ] = nv + 12; - pIndices[ n + 19 ] = nv + 13; - pIndices[ n + 20 ] = nv + 14; - pIndices[ n + 21 ] = nv + 12; - pIndices[ n + 22 ] = nv + 14; - pIndices[ n + 23 ] = nv + 15; - - uint32 colLeft(PackColor(ScaleColor(col, 0.7f))); - pVertices[ nv + 16 ].xyz = xyz; - pVertices[ nv + 16 ].color.dcolor = colLeft; - pVertices[ nv + 17 ].xyz = xyZ; - pVertices[ nv + 17 ].color.dcolor = colLeft; - pVertices[ nv + 18 ].xyz = xYZ; - pVertices[ nv + 18 ].color.dcolor = colLeft; - pVertices[ nv + 19 ].xyz = xYz; - pVertices[ nv + 19 ].color.dcolor = colLeft; - - pIndices[ n + 24 ] = nv + 16; - pIndices[ n + 25 ] = nv + 17; - pIndices[ n + 26 ] = nv + 18; - pIndices[ n + 27 ] = nv + 16; - pIndices[ n + 28 ] = nv + 18; - pIndices[ n + 29 ] = nv + 19; - - uint32 colRight(PackColor(ScaleColor(col, 0.8f))); - pVertices[ nv + 20 ].xyz = Xyz; - pVertices[ nv + 20 ].color.dcolor = colRight; - pVertices[ nv + 21 ].xyz = XYz; - pVertices[ nv + 21 ].color.dcolor = colRight; - pVertices[ nv + 22 ].xyz = XYZ; - pVertices[ nv + 22 ].color.dcolor = colRight; - pVertices[ nv + 23 ].xyz = XyZ; - pVertices[ nv + 23 ].color.dcolor = colRight; - - pIndices[ n + 30 ] = nv + 20; - pIndices[ n + 31 ] = nv + 21; - pIndices[ n + 32 ] = nv + 22; - pIndices[ n + 33 ] = nv + 20; - pIndices[ n + 34 ] = nv + 22; - pIndices[ n + 35 ] = nv + 23; - } - } - } -} - -void CAuxGeomCB::DrawAABB(const AABB& aabb, const Matrix34& matWorld, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle) -{ - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - - if (eBBD_Extremes_Color_Encoded == bbDrawStyle) - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 8, pIndices, 36, CreateTriangleRenderFlags(true)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - pIndices[ 6 ] = 7; - pIndices[ 7 ] = 6; - pIndices[ 8 ] = 5; - pIndices[ 9 ] = 7; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 4; - - pIndices[ 12 ] = 3; - pIndices[ 13 ] = 2; - pIndices[ 14 ] = 6; - pIndices[ 15 ] = 3; - pIndices[ 16 ] = 6; - pIndices[ 17 ] = 7; - - pIndices[ 18 ] = 4; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 1; - pIndices[ 21 ] = 4; - pIndices[ 22 ] = 1; - pIndices[ 23 ] = 0; - - pIndices[ 24 ] = 1; - pIndices[ 25 ] = 5; - pIndices[ 26 ] = 6; - pIndices[ 27 ] = 1; - pIndices[ 28 ] = 6; - pIndices[ 29 ] = 2; - - pIndices[ 30 ] = 4; - pIndices[ 31 ] = 0; - pIndices[ 32 ] = 3; - pIndices[ 33 ] = 4; - pIndices[ 34 ] = 3; - pIndices[ 35 ] = 7; - } - - uint32 color(PackColor(col)); - uint32 colorMin(PackColor(ColorB(15, 15, 15, col.a))); - uint32 colorMax(PackColor(ColorB(255, 255, 255, col.a))); - - pVertices[ 0 ].xyz = matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ 0 ].color.dcolor = colorMin; - pVertices[ 1 ].xyz = matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ 6 ].color.dcolor = colorMax; - pVertices[ 7 ].xyz = matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ 7 ].color.dcolor = color; - } - else - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - - pVertices[ 0 ].xyz = matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.min.z); - pVertices[ 0 ].color.dcolor = color; - pVertices[ 1 ].xyz = matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.min.z); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.min.z); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.min.z); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.max.z); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.max.z); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.max.z); - pVertices[ 6 ].color.dcolor = color; - pVertices[ 7 ].xyz = matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.max.z); - pVertices[ 7 ].color.dcolor = color; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 24, pIndices, 36, CreateTriangleRenderFlags(true)); - - Vec3 xyz(matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.min.z)); - Vec3 xyZ(matWorld * Vec3(aabb.min.x, aabb.min.y, aabb.max.z)); - Vec3 xYz(matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.min.z)); - Vec3 xYZ(matWorld * Vec3(aabb.min.x, aabb.max.y, aabb.max.z)); - Vec3 Xyz(matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.min.z)); - Vec3 XyZ(matWorld * Vec3(aabb.max.x, aabb.min.y, aabb.max.z)); - Vec3 XYz(matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.min.z)); - Vec3 XYZ(matWorld * Vec3(aabb.max.x, aabb.max.y, aabb.max.z)); - - uint32 colDown(PackColor(ScaleColor(col, 0.5f))); - pVertices[ 0 ].xyz = xyz; - pVertices[ 0 ].color.dcolor = colDown; - pVertices[ 1 ].xyz = xYz; - pVertices[ 1 ].color.dcolor = colDown; - pVertices[ 2 ].xyz = XYz; - pVertices[ 2 ].color.dcolor = colDown; - pVertices[ 3 ].xyz = Xyz; - pVertices[ 3 ].color.dcolor = colDown; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - uint32 colTop(PackColor(col)); - pVertices[ 4 ].xyz = xyZ; - pVertices[ 4 ].color.dcolor = colTop; - pVertices[ 5 ].xyz = XyZ; - pVertices[ 5 ].color.dcolor = colTop; - pVertices[ 6 ].xyz = XYZ; - pVertices[ 6 ].color.dcolor = colTop; - pVertices[ 7 ].xyz = xYZ; - pVertices[ 7 ].color.dcolor = colTop; - - pIndices[ 6 ] = 4; - pIndices[ 7 ] = 5; - pIndices[ 8 ] = 6; - pIndices[ 9 ] = 4; - pIndices[ 10 ] = 6; - pIndices[ 11 ] = 7; - - uint32 colBack(PackColor(ScaleColor(col, 0.6f))); - pVertices[ 8 ].xyz = xyz; - pVertices[ 8 ].color.dcolor = colBack; - pVertices[ 9 ].xyz = Xyz; - pVertices[ 9 ].color.dcolor = colBack; - pVertices[ 10 ].xyz = XyZ; - pVertices[ 10 ].color.dcolor = colBack; - pVertices[ 11 ].xyz = xyZ; - pVertices[ 11 ].color.dcolor = colBack; - - pIndices[ 12 ] = 8; - pIndices[ 13 ] = 9; - pIndices[ 14 ] = 10; - pIndices[ 15 ] = 8; - pIndices[ 16 ] = 10; - pIndices[ 17 ] = 11; - - uint32 colFront(PackColor(ScaleColor(col, 0.9f))); - pVertices[ 12 ].xyz = xYz; - pVertices[ 12 ].color.dcolor = colFront; - pVertices[ 13 ].xyz = xYZ; - pVertices[ 13 ].color.dcolor = colFront; - pVertices[ 14 ].xyz = XYZ; - pVertices[ 14 ].color.dcolor = colFront; - pVertices[ 15 ].xyz = XYz; - pVertices[ 15 ].color.dcolor = colFront; - - pIndices[ 18 ] = 12; - pIndices[ 19 ] = 13; - pIndices[ 20 ] = 14; - pIndices[ 21 ] = 12; - pIndices[ 22 ] = 14; - pIndices[ 23 ] = 15; - - uint32 colLeft(PackColor(ScaleColor(col, 0.7f))); - pVertices[ 16 ].xyz = xyz; - pVertices[ 16 ].color.dcolor = colLeft; - pVertices[ 17 ].xyz = xyZ; - pVertices[ 17 ].color.dcolor = colLeft; - pVertices[ 18 ].xyz = xYZ; - pVertices[ 18 ].color.dcolor = colLeft; - pVertices[ 19 ].xyz = xYz; - pVertices[ 19 ].color.dcolor = colLeft; - - pIndices[ 24 ] = 16; - pIndices[ 25 ] = 17; - pIndices[ 26 ] = 18; - pIndices[ 27 ] = 16; - pIndices[ 28 ] = 18; - pIndices[ 29 ] = 19; - - uint32 colRight(PackColor(ScaleColor(col, 0.8f))); - pVertices[ 20 ].xyz = Xyz; - pVertices[ 20 ].color.dcolor = colRight; - pVertices[ 21 ].xyz = XYz; - pVertices[ 21 ].color.dcolor = colRight; - pVertices[ 22 ].xyz = XYZ; - pVertices[ 22 ].color.dcolor = colRight; - pVertices[ 23 ].xyz = XyZ; - pVertices[ 23 ].color.dcolor = colRight; - - pIndices[ 30 ] = 20; - pIndices[ 31 ] = 21; - pIndices[ 32 ] = 22; - pIndices[ 33 ] = 20; - pIndices[ 34 ] = 22; - pIndices[ 35 ] = 23; - } - } -} - - -void CAuxGeomCB::DrawOBB(const OBB& obb, const Vec3& pos, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle) -{ - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - - if (eBBD_Extremes_Color_Encoded == bbDrawStyle) - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 8, pIndices, 36, CreateTriangleRenderFlags(true)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - pIndices[ 6 ] = 7; - pIndices[ 7 ] = 6; - pIndices[ 8 ] = 5; - pIndices[ 9 ] = 7; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 4; - - pIndices[ 12 ] = 3; - pIndices[ 13 ] = 2; - pIndices[ 14 ] = 6; - pIndices[ 15 ] = 3; - pIndices[ 16 ] = 6; - pIndices[ 17 ] = 7; - - pIndices[ 18 ] = 4; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 1; - pIndices[ 21 ] = 4; - pIndices[ 22 ] = 1; - pIndices[ 23 ] = 0; - - pIndices[ 24 ] = 1; - pIndices[ 25 ] = 5; - pIndices[ 26 ] = 6; - pIndices[ 27 ] = 1; - pIndices[ 28 ] = 6; - pIndices[ 29 ] = 2; - - pIndices[ 30 ] = 4; - pIndices[ 31 ] = 0; - pIndices[ 32 ] = 3; - pIndices[ 33 ] = 4; - pIndices[ 34 ] = 3; - pIndices[ 35 ] = 7; - } - - uint32 color(PackColor(col)); - uint32 colorMin(PackColor(ColorB(15, 15, 15, col.a))); - uint32 colorMax(PackColor(ColorB(255, 255, 255, col.a))); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - pVertices[ 0 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.min.z) + pos; - pVertices[ 0 ].color.dcolor = colorMin; - pVertices[ 1 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.min.z) + pos; - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.min.z) + pos; - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.min.z) + pos; - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.max.z) + pos; - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.max.z) + pos; - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.max.z) + pos; - pVertices[ 6 ].color.dcolor = colorMax; - pVertices[ 7 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.max.z) + pos; - pVertices[ 7 ].color.dcolor = color; - } - else - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - pVertices[ 0 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.min.z) + pos; - pVertices[ 0 ].color.dcolor = color; - pVertices[ 1 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.min.z) + pos; - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.min.z) + pos; - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.min.z) + pos; - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.max.z) + pos; - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.max.z) + pos; - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.max.z) + pos; - pVertices[ 6 ].color.dcolor = color; - pVertices[ 7 ].xyz = obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.max.z) + pos; - pVertices[ 7 ].color.dcolor = color; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 24, pIndices, 36, CreateTriangleRenderFlags(true)); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - Vec3 xyz(obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.min.z) + pos); - Vec3 xyZ(obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.max.z) + pos); - Vec3 xYz(obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.min.z) + pos); - Vec3 xYZ(obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.max.z) + pos); - Vec3 Xyz(obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.min.z) + pos); - Vec3 XyZ(obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.max.z) + pos); - Vec3 XYz(obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.min.z) + pos); - Vec3 XYZ(obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.max.z) + pos); - - uint32 colDown(PackColor(ScaleColor(col, 0.5f))); - pVertices[ 0 ].xyz = xyz; - pVertices[ 0 ].color.dcolor = colDown; - pVertices[ 1 ].xyz = xYz; - pVertices[ 1 ].color.dcolor = colDown; - pVertices[ 2 ].xyz = XYz; - pVertices[ 2 ].color.dcolor = colDown; - pVertices[ 3 ].xyz = Xyz; - pVertices[ 3 ].color.dcolor = colDown; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - uint32 colTop(PackColor(col)); - pVertices[ 4 ].xyz = xyZ; - pVertices[ 4 ].color.dcolor = colTop; - pVertices[ 5 ].xyz = XyZ; - pVertices[ 5 ].color.dcolor = colTop; - pVertices[ 6 ].xyz = XYZ; - pVertices[ 6 ].color.dcolor = colTop; - pVertices[ 7 ].xyz = xYZ; - pVertices[ 7 ].color.dcolor = colTop; - - pIndices[ 6 ] = 4; - pIndices[ 7 ] = 5; - pIndices[ 8 ] = 6; - pIndices[ 9 ] = 4; - pIndices[ 10 ] = 6; - pIndices[ 11 ] = 7; - - uint32 colBack(PackColor(ScaleColor(col, 0.6f))); - pVertices[ 8 ].xyz = xyz; - pVertices[ 8 ].color.dcolor = colBack; - pVertices[ 9 ].xyz = Xyz; - pVertices[ 9 ].color.dcolor = colBack; - pVertices[ 10 ].xyz = XyZ; - pVertices[ 10 ].color.dcolor = colBack; - pVertices[ 11 ].xyz = xyZ; - pVertices[ 11 ].color.dcolor = colBack; - - pIndices[ 12 ] = 8; - pIndices[ 13 ] = 9; - pIndices[ 14 ] = 10; - pIndices[ 15 ] = 8; - pIndices[ 16 ] = 10; - pIndices[ 17 ] = 11; - - uint32 colFront(PackColor(ScaleColor(col, 0.9f))); - pVertices[ 12 ].xyz = xYz; - pVertices[ 12 ].color.dcolor = colFront; - pVertices[ 13 ].xyz = xYZ; - pVertices[ 13 ].color.dcolor = colFront; - pVertices[ 14 ].xyz = XYZ; - pVertices[ 14 ].color.dcolor = colFront; - pVertices[ 15 ].xyz = XYz; - pVertices[ 15 ].color.dcolor = colFront; - - pIndices[ 18 ] = 12; - pIndices[ 19 ] = 13; - pIndices[ 20 ] = 14; - pIndices[ 21 ] = 12; - pIndices[ 22 ] = 14; - pIndices[ 23 ] = 15; - - uint32 colLeft(PackColor(ScaleColor(col, 0.7f))); - pVertices[ 16 ].xyz = xyz; - pVertices[ 16 ].color.dcolor = colLeft; - pVertices[ 17 ].xyz = xyZ; - pVertices[ 17 ].color.dcolor = colLeft; - pVertices[ 18 ].xyz = xYZ; - pVertices[ 18 ].color.dcolor = colLeft; - pVertices[ 19 ].xyz = xYz; - pVertices[ 19 ].color.dcolor = colLeft; - - pIndices[ 24 ] = 16; - pIndices[ 25 ] = 17; - pIndices[ 26 ] = 18; - pIndices[ 27 ] = 16; - pIndices[ 28 ] = 18; - pIndices[ 29 ] = 19; - - uint32 colRight(PackColor(ScaleColor(col, 0.8f))); - pVertices[ 20 ].xyz = Xyz; - pVertices[ 20 ].color.dcolor = colRight; - pVertices[ 21 ].xyz = XYz; - pVertices[ 21 ].color.dcolor = colRight; - pVertices[ 22 ].xyz = XYZ; - pVertices[ 22 ].color.dcolor = colRight; - pVertices[ 23 ].xyz = XyZ; - pVertices[ 23 ].color.dcolor = colRight; - - pIndices[ 30 ] = 20; - pIndices[ 31 ] = 21; - pIndices[ 32 ] = 22; - pIndices[ 33 ] = 20; - pIndices[ 34 ] = 22; - pIndices[ 35 ] = 23; - } - } -} - - -void CAuxGeomCB::DrawOBB(const OBB& obb, const Matrix34& matWorld, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle) -{ - SAuxVertex* pVertices(0); - vtx_idx* pIndices(0); - - if (eBBD_Extremes_Color_Encoded == bbDrawStyle) - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 8, pIndices, 36, CreateTriangleRenderFlags(true)); - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - pIndices[ 6 ] = 7; - pIndices[ 7 ] = 6; - pIndices[ 8 ] = 5; - pIndices[ 9 ] = 7; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 4; - - pIndices[ 12 ] = 3; - pIndices[ 13 ] = 2; - pIndices[ 14 ] = 6; - pIndices[ 15 ] = 3; - pIndices[ 16 ] = 6; - pIndices[ 17 ] = 7; - - pIndices[ 18 ] = 4; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 1; - pIndices[ 21 ] = 4; - pIndices[ 22 ] = 1; - pIndices[ 23 ] = 0; - - pIndices[ 24 ] = 1; - pIndices[ 25 ] = 5; - pIndices[ 26 ] = 6; - pIndices[ 27 ] = 1; - pIndices[ 28 ] = 6; - pIndices[ 29 ] = 2; - - pIndices[ 30 ] = 4; - pIndices[ 31 ] = 0; - pIndices[ 32 ] = 3; - pIndices[ 33 ] = 4; - pIndices[ 34 ] = 3; - pIndices[ 35 ] = 7; - } - - uint32 color(PackColor(col)); - uint32 colorMin(PackColor(ColorB(15, 15, 15, col.a))); - uint32 colorMax(PackColor(ColorB(255, 255, 255, col.a))); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - pVertices[ 0 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.min.z)); - pVertices[ 0 ].color.dcolor = colorMin; - pVertices[ 1 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.min.z)); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.min.z)); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.min.z)); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.max.z)); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.max.z)); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.max.z)); - pVertices[ 6 ].color.dcolor = colorMax; - pVertices[ 7 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.max.z)); - pVertices[ 7 ].color.dcolor = color; - } - else - { - if (false == bSolid) - { - AddIndexedPrimitive(pVertices, 8, pIndices, 24, CreateLineRenderFlags(true) | AlphaFlags(col)); - - uint32 color(PackColor(col)); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - pVertices[ 0 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.min.z)); - pVertices[ 0 ].color.dcolor = color; - pVertices[ 1 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.min.z)); - pVertices[ 1 ].color.dcolor = color; - pVertices[ 2 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.min.z)); - pVertices[ 2 ].color.dcolor = color; - pVertices[ 3 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.min.z)); - pVertices[ 3 ].color.dcolor = color; - pVertices[ 4 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.min.y, aabb.max.z)); - pVertices[ 4 ].color.dcolor = color; - pVertices[ 5 ].xyz = matWorld * (obb.m33 * Vec3(aabb.min.x, aabb.max.y, aabb.max.z)); - pVertices[ 5 ].color.dcolor = color; - pVertices[ 6 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.max.y, aabb.max.z)); - pVertices[ 6 ].color.dcolor = color; - pVertices[ 7 ].xyz = matWorld * (obb.m33 * Vec3(aabb.max.x, aabb.min.y, aabb.max.z)); - pVertices[ 7 ].color.dcolor = color; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 1; - pIndices[ 3 ] = 2; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - pIndices[ 6 ] = 3; - pIndices[ 7 ] = 0; - - pIndices[ 8 ] = 4; - pIndices[ 9 ] = 5; - pIndices[ 10 ] = 5; - pIndices[ 11 ] = 6; - pIndices[ 12 ] = 6; - pIndices[ 13 ] = 7; - pIndices[ 14 ] = 7; - pIndices[ 15 ] = 4; - - pIndices[ 16 ] = 0; - pIndices[ 17 ] = 4; - pIndices[ 18 ] = 1; - pIndices[ 19 ] = 5; - pIndices[ 20 ] = 2; - pIndices[ 21 ] = 6; - pIndices[ 22 ] = 3; - pIndices[ 23 ] = 7; - } - else - { - AddIndexedPrimitive(pVertices, 24, pIndices, 36, CreateTriangleRenderFlags(true)); - - AABB aabb(obb.c - obb.h, obb.c + obb.h); - Vec3 xyz(matWorld * (obb.m33* Vec3(aabb.min.x, aabb.min.y, aabb.min.z))); - Vec3 xyZ(matWorld * (obb.m33* Vec3(aabb.min.x, aabb.min.y, aabb.max.z))); - Vec3 xYz(matWorld * (obb.m33* Vec3(aabb.min.x, aabb.max.y, aabb.min.z))); - Vec3 xYZ(matWorld * (obb.m33* Vec3(aabb.min.x, aabb.max.y, aabb.max.z))); - Vec3 Xyz(matWorld * (obb.m33* Vec3(aabb.max.x, aabb.min.y, aabb.min.z))); - Vec3 XyZ(matWorld * (obb.m33* Vec3(aabb.max.x, aabb.min.y, aabb.max.z))); - Vec3 XYz(matWorld * (obb.m33* Vec3(aabb.max.x, aabb.max.y, aabb.min.z))); - Vec3 XYZ(matWorld * (obb.m33* Vec3(aabb.max.x, aabb.max.y, aabb.max.z))); - - uint32 colDown(PackColor(ScaleColor(col, 0.5f))); - pVertices[ 0 ].xyz = xyz; - pVertices[ 0 ].color.dcolor = colDown; - pVertices[ 1 ].xyz = xYz; - pVertices[ 1 ].color.dcolor = colDown; - pVertices[ 2 ].xyz = XYz; - pVertices[ 2 ].color.dcolor = colDown; - pVertices[ 3 ].xyz = Xyz; - pVertices[ 3 ].color.dcolor = colDown; - - pIndices[ 0 ] = 0; - pIndices[ 1 ] = 1; - pIndices[ 2 ] = 2; - pIndices[ 3 ] = 0; - pIndices[ 4 ] = 2; - pIndices[ 5 ] = 3; - - uint32 colTop(PackColor(col)); - pVertices[ 4 ].xyz = xyZ; - pVertices[ 4 ].color.dcolor = colTop; - pVertices[ 5 ].xyz = XyZ; - pVertices[ 5 ].color.dcolor = colTop; - pVertices[ 6 ].xyz = XYZ; - pVertices[ 6 ].color.dcolor = colTop; - pVertices[ 7 ].xyz = xYZ; - pVertices[ 7 ].color.dcolor = colTop; - - pIndices[ 6 ] = 4; - pIndices[ 7 ] = 5; - pIndices[ 8 ] = 6; - pIndices[ 9 ] = 4; - pIndices[ 10 ] = 6; - pIndices[ 11 ] = 7; - - uint32 colBack(PackColor(ScaleColor(col, 0.6f))); - pVertices[ 8 ].xyz = xyz; - pVertices[ 8 ].color.dcolor = colBack; - pVertices[ 9 ].xyz = Xyz; - pVertices[ 9 ].color.dcolor = colBack; - pVertices[ 10 ].xyz = XyZ; - pVertices[ 10 ].color.dcolor = colBack; - pVertices[ 11 ].xyz = xyZ; - pVertices[ 11 ].color.dcolor = colBack; - - pIndices[ 12 ] = 8; - pIndices[ 13 ] = 9; - pIndices[ 14 ] = 10; - pIndices[ 15 ] = 8; - pIndices[ 16 ] = 10; - pIndices[ 17 ] = 11; - - uint32 colFront(PackColor(ScaleColor(col, 0.9f))); - pVertices[ 12 ].xyz = xYz; - pVertices[ 12 ].color.dcolor = colFront; - pVertices[ 13 ].xyz = xYZ; - pVertices[ 13 ].color.dcolor = colFront; - pVertices[ 14 ].xyz = XYZ; - pVertices[ 14 ].color.dcolor = colFront; - pVertices[ 15 ].xyz = XYz; - pVertices[ 15 ].color.dcolor = colFront; - - pIndices[ 18 ] = 12; - pIndices[ 19 ] = 13; - pIndices[ 20 ] = 14; - pIndices[ 21 ] = 12; - pIndices[ 22 ] = 14; - pIndices[ 23 ] = 15; - - uint32 colLeft(PackColor(ScaleColor(col, 0.7f))); - pVertices[ 16 ].xyz = xyz; - pVertices[ 16 ].color.dcolor = colLeft; - pVertices[ 17 ].xyz = xyZ; - pVertices[ 17 ].color.dcolor = colLeft; - pVertices[ 18 ].xyz = xYZ; - pVertices[ 18 ].color.dcolor = colLeft; - pVertices[ 19 ].xyz = xYz; - pVertices[ 19 ].color.dcolor = colLeft; - - pIndices[ 24 ] = 16; - pIndices[ 25 ] = 17; - pIndices[ 26 ] = 18; - pIndices[ 27 ] = 16; - pIndices[ 28 ] = 18; - pIndices[ 29 ] = 19; - - uint32 colRight(PackColor(ScaleColor(col, 0.8f))); - pVertices[ 20 ].xyz = Xyz; - pVertices[ 20 ].color.dcolor = colRight; - pVertices[ 21 ].xyz = XYz; - pVertices[ 21 ].color.dcolor = colRight; - pVertices[ 22 ].xyz = XYZ; - pVertices[ 22 ].color.dcolor = colRight; - pVertices[ 23 ].xyz = XyZ; - pVertices[ 23 ].color.dcolor = colRight; - - pIndices[ 30 ] = 20; - pIndices[ 31 ] = 21; - pIndices[ 32 ] = 22; - pIndices[ 33 ] = 20; - pIndices[ 34 ] = 22; - pIndices[ 35 ] = 23; - } - } -} - - - -void CAuxGeomCB::DrawSphere(const Vec3& pos, float radius, const ColorB& col, bool drawShaded) -{ - if (radius > 0.0f) - { - SAuxDrawObjParams* pDrawParams(0); - AddObject(pDrawParams, CreateObjectRenderFlags(eDOT_Sphere)); - - pDrawParams->m_matWorld = Matrix34::CreateTranslationMat(pos) * Matrix33::CreateScale(Vec3(radius, radius, radius)); - pDrawParams->m_matWorldRotation.SetIdentity(); - pDrawParams->m_color = PackColor(col); - pDrawParams->m_size = radius; - pDrawParams->m_shaded = drawShaded; - } -} - -void CAuxGeomCB::DrawDisk(const Vec3& pos, const Vec3& dir, float radius, const ColorB& col, bool drawShaded) -{ - if (radius > 0.0f && dir.GetLengthSquared() > 0.0f) - { - SAuxDrawObjParams* pDrawParams(0); - AddObject(pDrawParams, CreateObjectRenderFlags(eDOT_Disk)); - - Vec3 direction(dir.normalized()); - Vec3 orthogonal(direction.GetOrthogonal().normalized()); - - Matrix33 matRot; - matRot.SetIdentity(); - matRot.SetColumn(0, orthogonal); - matRot.SetColumn(1, direction); - matRot.SetColumn(2, orthogonal.Cross(direction)); - - pDrawParams->m_matWorld = Matrix34::CreateTranslationMat(pos) * matRot * Matrix33::CreateScale(Vec3(radius, 1.0, radius)); - pDrawParams->m_matWorldRotation = matRot; - pDrawParams->m_color = PackColor(col); - pDrawParams->m_size = radius; - pDrawParams->m_shaded = drawShaded; - } -} - -void CAuxGeomCB::DrawCone(const Vec3& pos, const Vec3& dir, float radius, float height, const ColorB& col, bool drawShaded) -{ - if (radius > 0.0f && height > 0.0f && dir.GetLengthSquared() > 0.0f) - { - SAuxDrawObjParams* pDrawParams(0); - AddObject(pDrawParams, CreateObjectRenderFlags(eDOT_Cone)); - - Vec3 direction(dir.normalized()); - Vec3 orthogonal(direction.GetOrthogonal().normalized()); - - Matrix33 matRot; - matRot.SetIdentity(); - matRot.SetColumn(0, orthogonal); - matRot.SetColumn(1, direction); - matRot.SetColumn(2, orthogonal.Cross(direction)); - - pDrawParams->m_matWorld = Matrix34::CreateTranslationMat(pos) * matRot * Matrix33::CreateScale(Vec3(radius, height, radius)); - pDrawParams->m_matWorldRotation = matRot; - pDrawParams->m_color = PackColor(col); - pDrawParams->m_size = max(radius, height * 0.5f); - pDrawParams->m_shaded = drawShaded; - } -} - - -void CAuxGeomCB::DrawCylinder(const Vec3& pos, const Vec3& dir, float radius, float height, const ColorB& col, bool drawShaded) -{ - if (radius > 0.0f && height > 0.0f && dir.GetLengthSquared() > 0.0f) - { - SAuxDrawObjParams* pDrawParams(0); - AddObject(pDrawParams, CreateObjectRenderFlags(eDOT_Cylinder)); - - Vec3 direction(dir.normalized()); - Vec3 orthogonal(direction.GetOrthogonal().normalized()); - - Matrix33 matRot; - matRot.SetIdentity(); - matRot.SetColumn(0, orthogonal); - matRot.SetColumn(1, direction); - matRot.SetColumn(2, orthogonal.Cross(direction)); - - pDrawParams->m_matWorld = Matrix34::CreateTranslationMat(pos) * matRot * Matrix33::CreateScale(Vec3(radius, height, radius)); - pDrawParams->m_matWorldRotation = matRot; - pDrawParams->m_color = PackColor(col); - pDrawParams->m_size = max(radius, height * 0.5f); - pDrawParams->m_shaded = drawShaded; - } -} - - -void CAuxGeomCB::DrawBone(const Vec3& p, const Vec3& c, ColorB col) -{ - Vec3 vBoneVec = c - p; - float fBoneLength = vBoneVec.GetLength(); - - if (fBoneLength < 1e-4) - { - return; - } - - Matrix33 m33 = Matrix33::CreateRotationV0V1(Vec3(1, 0, 0), vBoneVec / fBoneLength); - Matrix34 m34 = Matrix34(m33, p); - - f32 t = min(0.01f, fBoneLength * 0.05f); - - //bone points in x-direction - Vec3 s = Vec3(ZERO); - Vec3 m0 = Vec3(t, +t, +t); - Vec3 m1 = Vec3(t, -t, +t); - Vec3 m2 = Vec3(t, -t, -t); - Vec3 m3 = Vec3(t, +t, -t); - Vec3 e = Vec3(fBoneLength, 0, 0); - - Vec3 VBuffer[6]; - ColorB CBuffer[6]; - - VBuffer[0] = m34 * s; - CBuffer[0] = RGBA8(0xff, 0x1f, 0x1f, 0x00); //start of bone (joint) - - VBuffer[1] = m34 * m0; - CBuffer[1] = col; - VBuffer[2] = m34 * m1; - CBuffer[2] = col; - VBuffer[3] = m34 * m2; - CBuffer[3] = col; - VBuffer[4] = m34 * m3; - CBuffer[4] = col; - - VBuffer[5] = m34 * e; - CBuffer[5] = RGBA8(0x07, 0x0f, 0x1f, 0x00); //end of bone - - - DrawLine(VBuffer[0], CBuffer[0], VBuffer[1], CBuffer[1]); - DrawLine(VBuffer[0], CBuffer[0], VBuffer[2], CBuffer[2]); - DrawLine(VBuffer[0], CBuffer[0], VBuffer[3], CBuffer[3]); - DrawLine(VBuffer[0], CBuffer[0], VBuffer[4], CBuffer[4]); - - DrawLine(VBuffer[1], CBuffer[1], VBuffer[2], CBuffer[2]); - DrawLine(VBuffer[2], CBuffer[2], VBuffer[3], CBuffer[3]); - DrawLine(VBuffer[3], CBuffer[3], VBuffer[4], CBuffer[4]); - DrawLine(VBuffer[4], CBuffer[4], VBuffer[1], CBuffer[1]); - - DrawLine(VBuffer[5], CBuffer[5], VBuffer[1], CBuffer[1]); - DrawLine(VBuffer[5], CBuffer[5], VBuffer[2], CBuffer[2]); - DrawLine(VBuffer[5], CBuffer[5], VBuffer[3], CBuffer[3]); - DrawLine(VBuffer[5], CBuffer[5], VBuffer[4], CBuffer[4]); -} - -#include "CommonRender.h" - - -void CAuxGeomCB::RenderText(Vec3 pos, SDrawTextInfo& ti, const char* format, va_list args) -{ - if (format && !gEnv->IsDedicated()) - { - char str[512]; - - vsnprintf_s(str, sizeof(str), sizeof(str) - 1, format, args); - str[sizeof(str) - 1] = '\0'; - gEnv->pRenderer->DrawTextQueued(pos, ti, str); - } -} - -void CAuxGeomCB::Flush() -{ - Flush(false); -} - -void CAuxGeomCB::Flush(bool reset) -{ - size_t lastFlushPos = GetLastFlushPos(); - size_t curFlushPos = GetCurFlushPos(); - if ((lastFlushPos < curFlushPos) || reset) - { - UpdateLastFlushPos(); - SAuxGeomCBRawDataPackaged data = SAuxGeomCBRawDataPackaged(AccessData()); - m_pRenderAuxGeom->Flush(data, lastFlushPos, curFlushPos, reset); - } -} - -void CAuxGeomCB::UpdateLastFlushPos() -{ - bool shouldUpdate = true; - - // If stereo is enabled then we don't want to reset the flush position UNLESS we're rendering the second eye. Otherwise, - // the aux geom will only get drawn to the first eye. - if (gEnv->pRenderer->IsStereoEnabled()) - { - if (gEnv->pRenderer->GetIStereoRenderer()->GetStatus() == IStereoRenderer::Status::kRenderingFirstEye) - { - shouldUpdate = false; - } - } - - if (shouldUpdate) - { - m_lastFlushPos = GetCurFlushPos(); - } -} - -void CAuxGeomCB::Commit([[maybe_unused]] uint frames) -{ - Flush(); -} - -void CAuxGeomCB::Process() -{ - m_pRenderAuxGeom->FlushTextMessages(m_cbCurrent->m_TextMessages, true); - m_lastFlushPos = 0; - m_cbCurrent->Reset(); -} - -// Note: Runs on MainThread in RC_EndFrame before enqueing the the render command -void CAuxGeomCBMainThread::Commit(uint frames) -{ - m_cbCurrent->SetUsed(true); - m_cbCurrent->SetCount(frames); - - Flush(true); - - assert(m_cbCurrent->m_curTransMatIdx == -1); - m_cbCurrent->m_curTransMatIdx = -1; - - m_cbCurrent->SetUsed(true); - m_cbCurrent->SetCount(frames); - - // Select the next buffer. Note that between m_CBReady[2] and m_cbCurrent all being uniquely allocated, this works out to a triple buffering scenario. - // This allows us to not have to change shared code with the other classes that reference m_cbCurrent as the currently active buffer. - // NOTE: In this case, there does not appear to be any reason to require the atomic interlocked exchange. - // It appears they only use the InterlockedExchange to do the swap in one line of code. - const unsigned char nextBuffer = m_currentReadyBuffer + 1; - m_currentReadyBuffer = (nextBuffer == c_numCBReadyBuffers) ? 0 : nextBuffer; - m_cbCurrent = (SAuxGeomCBRawData*)CryInterlockedExchangePointer((void* volatile*)&m_CBReady[m_currentReadyBuffer], m_cbCurrent); - - m_lastFlushPos = 0; - - m_cbCurrent->Reset(); -} - -// Note: Runs on RenderThread in RT_EndFrame -void CAuxGeomCBMainThread::Process() -{ - m_pRenderAuxGeom->FlushTextMessages(m_CBReady[m_currentReadyBuffer]->m_TextMessages, true); - m_CBReady[m_currentReadyBuffer]->SetUsed(false); -} - - -void CAuxGeomCBWorkerThread::Flush() -{ -} - -void CAuxGeomCBWorkerThread::Commit(uint frames) -{ - m_cbCurrent->SetUsed(true); - m_cbCurrent->SetCount(frames); - - Flush(); - - assert(m_cbCurrent->m_curTransMatIdx == -1); - m_cbCurrent->m_curTransMatIdx = -1; - - m_cbCurrent = (SAuxGeomCBRawData*)CryInterlockedExchangePointer((void* volatile*)&m_CBReady, m_cbCurrent); - - if (!m_cbCurrent) - { - for (CBList::iterator it = m_cbData.begin(); it != m_cbData.end(); ++it) - { - if (!(*it)->IsUsed()) - { - m_cbCurrent = *it; - } - } - - if (!m_cbCurrent) - { - m_cbCurrent = AddCBuffer(); - } - } - - m_lastFlushPos = 0; - - m_cbCurrent->Reset(); -} - -void CAuxGeomCBWorkerThread::Process() -{ - if (SAuxGeomCBRawData* current = (SAuxGeomCBRawData*)CryInterlockedExchangePointer((void* volatile*)&m_CBReady, 0)) - { - if (m_cbProcessed) - { - m_cbProcessed->SetUsed(false); - } - - m_cbProcessed = current; - } - - if (SAuxGeomCBRawData* processed = m_cbProcessed) - { - if (size_t curFlushPos = processed->m_auxPushBuffer.size()) - { - SAuxGeomCBRawDataPackaged data = SAuxGeomCBRawDataPackaged(processed); - m_pRenderAuxGeom->Flush(data, 0, curFlushPos); - } - - m_pRenderAuxGeom->FlushTextMessages(processed->m_TextMessages, false); - - if (processed->Count() == 1) - { - processed->SetUsed(false); - m_cbProcessed = 0; - } - } -} - - -void CAuxGeomCB::SAuxGeomCBRawData::GetSortedPushBuffer(size_t begin, size_t end, AuxSortedPushBuffer& auxSortedPushBuffer) const -{ - assert(begin < end); - assert(end <= m_auxPushBuffer.size()); - - auxSortedPushBuffer.reserve(end - begin); - auxSortedPushBuffer.resize(0); - - for (AuxPushBuffer::const_iterator it(m_auxPushBuffer.begin() + begin), itEnd(m_auxPushBuffer.begin() + end); it != itEnd; ++it) - { - auxSortedPushBuffer.push_back(&(*it)); - } - - std::sort(auxSortedPushBuffer.begin(), auxSortedPushBuffer.end(), PushBufferSortFunc()); -} - - -void CAuxGeomCB::AddPushBufferEntry(uint32 numVertices, uint32 numIndices, const SAuxGeomRenderFlags& renderFlags) -{ - assert(numVertices > 0); - - AuxPushBuffer& auxPushBuffer(AccessData()->m_auxPushBuffer); - - EPrimType primType(GetPrimType(renderFlags)); - if (false == auxPushBuffer.empty() && - auxPushBuffer[ auxPushBuffer.size() - 1 ].m_renderFlags == renderFlags && - auxPushBuffer[ auxPushBuffer.size() - 1 ].m_transMatrixIdx == GetTransMatrixIndex() && - (e_PtList == primType || e_LineList == primType || e_TriList == primType)) - { - // Perform a runtime optimization (pre-merging) which effectively reduces the number of PB entries created. - // We can merge this entry with the previous one as its render flags match with the ones of the previous entry - // (e.g. merges consecutive DrawLine(...) calls with same render flags into one PB entry). - - // Only done for non-indexed primitives as otherwise there would be the additional overhead of patching - // the indices for each push buffer entry. Indices already and still have to be patched during rendering - // anyway (merging) so in case of indexed primitives there'd be no real benefit. Also, merging up too many - // indexed primitves could potentially produce a push buffer entry which cannot be rendered as it exceeds - // the vb/ib buffer size for auxiliary geometries in the renderer. - SAuxPushBufferEntry& lastPBEntry(auxPushBuffer[ auxPushBuffer.size() - 1 ]); - lastPBEntry.m_numVertices += numVertices; - lastPBEntry.m_numIndices += numIndices; - } - else - { - // create new push buffer entry - auxPushBuffer.push_back(SAuxPushBufferEntry(numVertices, numIndices, - AccessData()->m_auxVertexBuffer.size(), AccessData()->m_auxIndexBuffer.size(), GetTransMatrixIndex(), renderFlags)); - } -} - - -void CAuxGeomCB::AddPrimitive(SAuxVertex*& pVertices, uint32 numVertices, const SAuxGeomRenderFlags& renderFlags) -{ - assert(numVertices > 0); - - // add push buffer entry to allow later merging of batches commited via DP - AddPushBufferEntry(numVertices, 0, renderFlags); - - // get vertex ptr - AuxVertexBuffer& auxVertexBuffer(AccessData()->m_auxVertexBuffer); - AuxVertexBuffer::size_type oldVBSize(auxVertexBuffer.size()); - auxVertexBuffer.resize(oldVBSize + numVertices); - pVertices = &auxVertexBuffer[ oldVBSize ]; -} - -void CAuxGeomCB::AddIndexedPrimitive(SAuxVertex*& pVertices, uint32 numVertices, vtx_idx*& pIndices, uint32 numIndices, const SAuxGeomRenderFlags& renderFlags) -{ - assert(numVertices > 0); - assert(numIndices > 0); - - // add push buffer entry to allow later merging of batches commited via DIP - AddPushBufferEntry(numVertices, numIndices, renderFlags); - - // get vertex ptr - AuxVertexBuffer& auxVertexBuffer(AccessData()->m_auxVertexBuffer); - AuxVertexBuffer::size_type oldVBSize(auxVertexBuffer.size()); - auxVertexBuffer.resize(oldVBSize + numVertices); - pVertices = &auxVertexBuffer[ oldVBSize ]; - - // get index ptr - AuxIndexBuffer& auxIndexBuffer(AccessData()->m_auxIndexBuffer); - AuxIndexBuffer::size_type oldIBSize(auxIndexBuffer.size()); - auxIndexBuffer.resize(oldIBSize + numIndices); - pIndices = &auxIndexBuffer[ oldIBSize ]; -} - - -void CAuxGeomCB::AddObject(SAuxDrawObjParams*& pDrawParams, const SAuxGeomRenderFlags& renderFlags) -{ - // create new push buffer entry - AuxPushBuffer& auxPushBuffer(AccessData()->m_auxPushBuffer); - AuxDrawObjParamBuffer& auxDrawObjParamBuffer(AccessData()->m_auxDrawObjParamBuffer); - auxPushBuffer.push_back(SAuxPushBufferEntry(auxDrawObjParamBuffer.size(), GetTransMatrixIndex(), renderFlags)); - - // get draw param buffer ptr - AuxDrawObjParamBuffer::size_type oldSize(auxDrawObjParamBuffer.size()); - auxDrawObjParamBuffer.resize(oldSize + 1); - pDrawParams = &auxDrawObjParamBuffer[ oldSize ]; -} - - -void CAuxGeomCB::SAuxGeomCBRawData::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(&m_auxPushBuffer, m_auxPushBuffer.capacity() * sizeof(AuxPushBuffer::value_type)); - pSizer->AddObject(&m_auxVertexBuffer, m_auxVertexBuffer.capacity() * sizeof(AuxVertexBuffer::value_type)); - pSizer->AddObject(&m_auxIndexBuffer, m_auxIndexBuffer.capacity() * sizeof(AuxIndexBuffer::value_type)); - pSizer->AddObject(&m_auxDrawObjParamBuffer, m_auxDrawObjParamBuffer.capacity() * sizeof(AuxDrawObjParamBuffer::value_type)); - pSizer->AddObject(m_TextMessages); -} - -#endif // #if defined(ENABLE_RENDER_AUX_GEOM) diff --git a/Code/CryEngine/RenderDll/Common/RenderAuxGeom.h b/Code/CryEngine/RenderDll/Common/RenderAuxGeom.h deleted file mode 100644 index 946330b2bd..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderAuxGeom.h +++ /dev/null @@ -1,635 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _RENDERAUXGEOM_H_ -#define _RENDERAUXGEOM_H_ - -#if defined(ENABLE_PROFILING_CODE) || !defined(_RELEASE) -# define ENABLE_RENDER_AUX_GEOM -#endif - -#if defined(ENABLE_RENDER_AUX_GEOM) - -#include "IRenderAuxGeom.h" -#include "VertexFormats.h" -#include -#include - -class ICrySizer; -class CAuxGeomCB; -struct SAuxGeomCBRawDataPackaged; - - -struct IRenderAuxGeomImpl -{ -public: - virtual ~IRenderAuxGeomImpl(){} - virtual void Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset = false) = 0; - virtual void RT_Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset = false) = 0; - - virtual void FlushTextMessages(CTextMessages& tMessages, bool reset) = 0; -}; - - -class CAuxGeomCB - : public IRenderAuxGeom -{ -public: - // interface - virtual void SetRenderFlags(const SAuxGeomRenderFlags& renderFlags); - virtual SAuxGeomRenderFlags GetRenderFlags(); - - virtual void DrawPoint(const Vec3& v, const ColorB& col, uint8 size = 1); - virtual void DrawPoints(const Vec3* v, uint32 numPoints, const ColorB& col, uint8 size = 1); - virtual void DrawPoints(const Vec3* v, uint32 numPoints, const ColorB* col, uint8 size = 1); - - virtual void DrawLine(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, float thickness = 1.0f); - virtual void DrawLines(const Vec3* v, uint32 numPoints, const ColorB& col, float thickness = 1.0f); - virtual void DrawLines(const Vec3* v, uint32 numPoints, const ColorB* col, float thickness = 1.0f); - virtual void DrawLines(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB& col, float thickness = 1.0f); - virtual void DrawLines(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB* col, float thickness = 1.0f); - virtual void DrawPolyline(const Vec3* v, uint32 numPoints, bool closed, const ColorB& col, float thickness = 1.0f); - virtual void DrawPolyline(const Vec3* v, uint32 numPoints, bool closed, const ColorB* col, float thickness = 1.0f); - - virtual void DrawTriangle(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, const Vec3& v2, const ColorB& colV2); - virtual void DrawTriangles(const Vec3* v, uint32 numPoints, const ColorB& col); - virtual void DrawTriangles(const Vec3* v, uint32 numPoints, const ColorB* col); - virtual void DrawTriangles(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB& col); - virtual void DrawTriangles(const Vec3* v, uint32 numPoints, const vtx_idx* ind, uint32 numIndices, const ColorB* col); - - virtual void DrawQuad(float width, float height, const Matrix34& matWorld, const ColorB& col, bool drawShaded = true); - - virtual void DrawAABB(const AABB& aabb, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle); - virtual void DrawAABBs(const AABB* aabbs, uint32 aabbCount, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle); - virtual void DrawAABB(const AABB& aabb, const Matrix34& matWorld, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle); - - virtual void DrawOBB(const OBB& obb, const Vec3& pos, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle); - virtual void DrawOBB(const OBB& obb, const Matrix34& matWorld, bool bSolid, const ColorB& col, const EBoundingBoxDrawStyle& bbDrawStyle); - - virtual void DrawSphere(const Vec3& pos, float radius, const ColorB& col, bool drawShaded = true); - virtual void DrawDisk(const Vec3& pos, const Vec3& dir, float radius, const ColorB& col, bool drawShaded = true); - virtual void DrawCone(const Vec3& pos, const Vec3& dir, float radius, float height, const ColorB& col, bool drawShaded = true); - virtual void DrawCylinder(const Vec3& pos, const Vec3& dir, float radius, float height, const ColorB& col, bool drawShaded = true); - - virtual void DrawBone(const Vec3& rParent, const Vec3& rBone, ColorB col); - - virtual void RenderText(Vec3 pos, SDrawTextInfo& ti, const char* format, va_list args); - - void Flush(bool reset); - virtual void Flush(); - virtual void Commit(uint frames = 0); - virtual void Process(); - -public: - enum EPrimType - { - e_PtList, - e_LineList, - e_LineListInd, - e_TriList, - e_TriListInd, - e_Obj, - - e_NumPrimTypes, - - e_PrimTypeInvalid - }; - - enum EAuxDrawObjType - { - eDOT_Sphere, - eDOT_Cone, - eDOT_Cylinder, - eDOT_Disk, - eDOT_Quad, - }; - - struct SAuxDrawObjParams - { - SAuxDrawObjParams() - { - m_matWorld.SetIdentity(); - m_matWorldRotation.SetIdentity(); - m_color = 0; - m_size = 0; - m_shaded = false; - } - - Matrix34 m_matWorld; - Matrix33 m_matWorldRotation; - uint32 m_color; - float m_size; - bool m_shaded; - }; - - struct SAuxPushBufferEntry - { - SAuxPushBufferEntry() - { - } - - SAuxPushBufferEntry(uint32 numVertices, uint32 numIndices, uint32 vertexOffs, uint32 indexOffs, uint32 transMatrixIdx, const SAuxGeomRenderFlags& renderFlags) - : m_numVertices(numVertices) - , m_numIndices(numIndices) - , m_vertexOffs(vertexOffs) - , m_indexOffs(indexOffs) - , m_transMatrixIdx(transMatrixIdx) - , m_renderFlags(renderFlags) - { - } - - SAuxPushBufferEntry(uint32 drawParamOffs, uint32 transMatrixIdx, const SAuxGeomRenderFlags& renderFlags) - : m_numVertices(0) - , m_numIndices(0) - , m_vertexOffs(drawParamOffs) - , m_indexOffs(0) - , m_transMatrixIdx(transMatrixIdx) - , m_renderFlags(renderFlags) - { - assert(e_Obj == GetPrimType(m_renderFlags)); - } - - bool GetDrawParamOffs(uint32& drawParamOffs) const - { - if (e_Obj == GetPrimType(m_renderFlags)) - { - drawParamOffs = m_vertexOffs; - return(true); - } - return(false); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - uint32 m_numVertices; - uint32 m_numIndices; - uint32 m_vertexOffs; - uint32 m_indexOffs; - int m_transMatrixIdx; - SAuxGeomRenderFlags m_renderFlags; - }; - - typedef std::vector< SAuxPushBufferEntry > AuxPushBuffer; - typedef std::vector< const SAuxPushBufferEntry* > AuxSortedPushBuffer; - typedef std::vector< SAuxVertex > AuxVertexBuffer; - typedef std::vector< vtx_idx > AuxIndexBuffer; - typedef std::vector< SAuxDrawObjParams > AuxDrawObjParamBuffer; - typedef stl::aligned_vector AuxOrthoMatrixBuffer; - - struct SAuxGeomCBRawData - { - public: - SAuxGeomCBRawData() - : m_isUsed(false) - , m_curRenderFlags(e_Def3DPublicRenderflags) - , m_curTransMatIdx(-1) - , m_uCount(0) {} - - void GetSortedPushBuffer(size_t begin, size_t end, AuxSortedPushBuffer& auxSortedPushBuffer) const; - void GetMemoryUsage(ICrySizer* pSizer) const; - - void Reset() - { - m_auxPushBuffer.resize(0); - m_auxVertexBuffer.resize(0); - m_auxIndexBuffer.resize(0); - m_auxDrawObjParamBuffer.resize(0); - m_auxOrthoMatrices.resize(0); - m_TextMessages.Clear(); - - m_curRenderFlags = e_Def3DPublicRenderflags; - m_curTransMatIdx = -1; - m_uCount = 0; - } - - bool IsUsed() - { - return m_isUsed; - } - - void SetUsed(bool used) - { - m_isUsed = used; - } - - - void SetCount(uint count) - { - m_uCount = count; - } - - uint Count() - { - return m_uCount > 0 ? m_uCount-- : m_uCount; - } - - public: - AuxPushBuffer m_auxPushBuffer; - AuxVertexBuffer m_auxVertexBuffer; - AuxIndexBuffer m_auxIndexBuffer; - AuxDrawObjParamBuffer m_auxDrawObjParamBuffer; - AuxOrthoMatrixBuffer m_auxOrthoMatrices; - CTextMessages m_TextMessages; - SAuxGeomRenderFlags m_curRenderFlags; - int m_curTransMatIdx; - uint m_uCount; - bool m_isUsed; - }; - -public: - // c/dtor - CAuxGeomCB(IRenderAuxGeomImpl* pRenderAuxGeom); - virtual ~CAuxGeomCB(); - - // get methods for private flags - static EPrimType GetPrimType(const SAuxGeomRenderFlags& renderFlags); - static bool IsThickLine(const SAuxGeomRenderFlags& renderFlags); - static EAuxDrawObjType GetAuxObjType(const SAuxGeomRenderFlags& renderFlags); - static uint8 GetPointSize(const SAuxGeomRenderFlags& renderFlags); - - // memory usage - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->Add(*this); - for (CBList::const_iterator it = m_cbData.begin(); it != m_cbData.end(); ++it) - { - (*it)->GetMemoryUsage(pSizer); - } - } - - void FreeMemory() - { - for (CBList::iterator it = m_cbData.begin(); it != m_cbData.end(); ++it) - { - stl::reconstruct(**it); - } - } - - // setting orthogonal projection - void SetOrthoMode(bool enable, Matrix44A* pMatrix = 0) - { - if (enable) - { - assert(pMatrix); - m_cbCurrent->m_curTransMatIdx = m_cbCurrent->m_auxOrthoMatrices.size(); - m_cbCurrent->m_auxOrthoMatrices.push_back(*pMatrix); - } - else - { - m_cbCurrent->m_curTransMatIdx = -1; - } - } - -private: - enum EAuxGeomPrivateRenderflagBitMasks - { - // public field starts at bit 22 - - e_PrimTypeShift = 19, - e_PrimTypeMask = 0x7 << e_PrimTypeShift, - - e_PrivateRenderflagsMask = (1 << 19) - 1 - }; - - enum EAuxGeomPrivateRenderflags - { - // for non-indexed triangles - e_TriListParam_ProcessThickLines = 0x00000001, - - // for triangles - - // for lines - - // for points - - // for objects - }; - -private: - uint32 CreatePointRenderFlags(uint8 size); - uint32 CreateLineRenderFlags(bool indexed); - uint32 CreateTriangleRenderFlags(bool indexed); - uint32 CreateObjectRenderFlags(const EAuxDrawObjType& objType); - - void DrawThickLine(const Vec3& v0, const ColorB& colV0, const Vec3& v1, const ColorB& colV1, float thickness); - - void AddPushBufferEntry(uint32 numVertices, uint32 numIndices, const SAuxGeomRenderFlags& renderFlags); - void AddPrimitive(SAuxVertex*& pVertices, uint32 numVertices, const SAuxGeomRenderFlags& renderFlags); - void AddIndexedPrimitive(SAuxVertex*& pVertices, uint32 numVertices, vtx_idx*& pIndices, uint32 numIndices, const SAuxGeomRenderFlags& renderFlags); - void AddObject(SAuxDrawObjParams*& pDrawParams, const SAuxGeomRenderFlags& renderFlags); - - -protected: - size_t GetLastFlushPos() const - { - return m_lastFlushPos; - } - - size_t GetCurFlushPos() const - { - return m_cbCurrent->m_auxPushBuffer.size(); - } - - void UpdateLastFlushPos(); - - int GetTransMatrixIndex() const - { - return m_cbCurrent->m_curTransMatIdx; - } - - SAuxGeomCBRawData* AccessData() - { - return m_cbCurrent; - } - -protected: - struct PushBufferSortFunc - { - bool operator() (const SAuxPushBufferEntry* lhs, const SAuxPushBufferEntry* rhs) const - { - if (lhs->m_renderFlags.m_renderFlags != rhs->m_renderFlags.m_renderFlags) - { - return lhs->m_renderFlags.m_renderFlags < rhs->m_renderFlags.m_renderFlags; - } - - return lhs->m_transMatrixIdx < rhs->m_transMatrixIdx; - } - }; - - IRenderAuxGeomImpl* m_pRenderAuxGeom; - - size_t m_lastFlushPos; - - typedef std::list CBList; - CBList m_cbData; - - SAuxGeomCBRawData* m_cbCurrent; - - SAuxGeomCBRawData* AddCBuffer() - { - SAuxGeomCBRawData* ptr = new SAuxGeomCBRawData; - m_cbData.push_back(ptr); - return ptr; - } -}; - - -class CAuxGeomCBMainThread - : public CAuxGeomCB -{ -public: - // Triple-buffered including base class's m_cbCurrent - static const int c_numCBReadyBuffers = 2; - CAuxGeomCBMainThread(IRenderAuxGeomImpl* pRenderAuxGeom) - : CAuxGeomCB(pRenderAuxGeom) - { - for (int i = 0; i < c_numCBReadyBuffers; ++i) - { - m_CBReady[i] = AddCBuffer(); - } - } - virtual void Commit(uint frames = 0); - virtual void Process(); - -protected: - SAuxGeomCBRawData* volatile m_CBReady[c_numCBReadyBuffers]; - unsigned char m_currentReadyBuffer = 0; -}; - -class CAuxGeomCBWorkerThread - : public CAuxGeomCB -{ - SAuxGeomCBRawData* m_cbProcessed = nullptr; - SAuxGeomCBRawData* volatile m_CBReady = nullptr; - -public: - CAuxGeomCBWorkerThread(IRenderAuxGeomImpl* pRenderAuxGeom) - : CAuxGeomCB(pRenderAuxGeom) - , m_cbProcessed(0) {} - virtual void Flush(); - virtual void Commit(uint frames = 0); - virtual void Process(); -}; - -// package CAuxGeomCB::SAuxGeomCBRawData ptr via seperate struct as nested types cannot be forward declared -struct SAuxGeomCBRawDataPackaged -{ - SAuxGeomCBRawDataPackaged(CAuxGeomCB::SAuxGeomCBRawData* pData) - : m_pData(pData) - { - assert(m_pData); - } - - CAuxGeomCB::SAuxGeomCBRawData* m_pData; -}; - - -inline uint32 CAuxGeomCB::CreatePointRenderFlags(uint8 size) -{ - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_PtList << e_PrimTypeShift) | size); -} - - -inline uint32 CAuxGeomCB::CreateLineRenderFlags(bool indexed) -{ - if (false != indexed) - { - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_LineListInd << e_PrimTypeShift)); - } - else - { - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_LineList << e_PrimTypeShift)); - } -} - - -inline uint32 CAuxGeomCB::CreateTriangleRenderFlags(bool indexed) -{ - if (false != indexed) - { - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_TriListInd << e_PrimTypeShift)); - } - else - { - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_TriList << e_PrimTypeShift)); - } -} - - -inline uint32 CAuxGeomCB::CreateObjectRenderFlags(const EAuxDrawObjType& objType) -{ - return(m_cbCurrent->m_curRenderFlags.m_renderFlags | (e_Obj << e_PrimTypeShift) | objType); -} - - -inline CAuxGeomCB::EPrimType CAuxGeomCB::GetPrimType(const SAuxGeomRenderFlags& renderFlags) -{ - uint32 primType((renderFlags.m_renderFlags & e_PrimTypeMask) >> e_PrimTypeShift); - switch (primType) - { - case e_PtList: - { - return(e_PtList); - } - case e_LineList: - { - return(e_LineList); - } - case e_LineListInd: - { - return(e_LineListInd); - } - case e_TriList: - { - return(e_TriList); - } - case e_TriListInd: - { - return(e_TriListInd); - } - case e_Obj: - default: - { - assert(e_Obj == primType); - return(e_Obj); - } - } -} - - -inline bool CAuxGeomCB::IsThickLine(const SAuxGeomRenderFlags& renderFlags) -{ - EPrimType primType(GetPrimType(renderFlags)); - assert(e_TriList == primType); - - if (e_TriList == primType) - { - return(0 != (renderFlags.m_renderFlags & e_TriListParam_ProcessThickLines)); - } - else - { - return(false); - } -} - - -inline CAuxGeomCB::EAuxDrawObjType CAuxGeomCB::GetAuxObjType(const SAuxGeomRenderFlags& renderFlags) -{ - assert(e_Obj == GetPrimType(renderFlags)); - - uint32 objType((renderFlags.m_renderFlags & e_PrivateRenderflagsMask)); - switch (objType) - { - case eDOT_Sphere: - default: - { - assert(eDOT_Sphere == objType); - return(eDOT_Sphere); - } - case eDOT_Disk: - { - assert(eDOT_Disk == objType); - return(eDOT_Disk); - } - case eDOT_Quad: - { - assert(eDOT_Quad == objType); - return(eDOT_Quad); - } - case eDOT_Cone: - { - assert(eDOT_Cone == objType); - return(eDOT_Cone); - } - case eDOT_Cylinder: - { - assert(eDOT_Cylinder == objType); - return(eDOT_Cylinder); - } - } -} - - -inline uint8 CAuxGeomCB::GetPointSize(const SAuxGeomRenderFlags& renderFlags) -{ - EPrimType primType(GetPrimType(renderFlags)); - assert(e_PtList == primType); - - if (e_PtList == primType) - { - return(renderFlags.m_renderFlags & e_PrivateRenderflagsMask); - } - else - { - return(0); - } -} - -#endif // #if defined(ENABLE_RENDER_AUX_GEOM) - -class CAuxGeomCB_Null - : public IRenderAuxGeom -{ -public: - // interface - virtual void SetRenderFlags([[maybe_unused]] const SAuxGeomRenderFlags& renderFlags) {} - virtual SAuxGeomRenderFlags GetRenderFlags() {return SAuxGeomRenderFlags(); } - - virtual void DrawPoint([[maybe_unused]] const Vec3& v, [[maybe_unused]] const ColorB& col, [[maybe_unused]] uint8 size = 1) {} - virtual void DrawPoints([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col, [[maybe_unused]] uint8 size = 1) {} - virtual void DrawPoints([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col, [[maybe_unused]] uint8 size = 1) {} - - virtual void DrawLine([[maybe_unused]] const Vec3& v0, [[maybe_unused]] const ColorB& colV0, [[maybe_unused]] const Vec3& v1, [[maybe_unused]] const ColorB& colV1, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawPolyline([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] bool closed, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness = 1.0f) {} - virtual void DrawPolyline([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] bool closed, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness = 1.0f) {} - - virtual void DrawTriangle([[maybe_unused]] const Vec3& v0, [[maybe_unused]] const ColorB& colV0, [[maybe_unused]] const Vec3& v1, [[maybe_unused]] const ColorB& colV1, [[maybe_unused]] const Vec3& v2, [[maybe_unused]] const ColorB& colV2) {} - virtual void DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col) {} - virtual void DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col) {} - virtual void DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB& col) {} - virtual void DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB* col) {} - - virtual void DrawQuad([[maybe_unused]] float width, [[maybe_unused]] float height, [[maybe_unused]] const Matrix34& matWorld, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded = true) {} - - virtual void DrawAABB([[maybe_unused]] const AABB& aabb, [[maybe_unused]] bool bSolid, [[maybe_unused]] const ColorB& col, [[maybe_unused]] const EBoundingBoxDrawStyle& bbDrawStyle) {} - virtual void DrawAABBs([[maybe_unused]] const AABB* aabbs, [[maybe_unused]] uint32 aabbCount, [[maybe_unused]] bool bSolid, [[maybe_unused]] const ColorB& col, [[maybe_unused]] const EBoundingBoxDrawStyle& bbDrawStyle) {} - virtual void DrawAABB([[maybe_unused]] const AABB& aabb, [[maybe_unused]] const Matrix34& matWorld, [[maybe_unused]] bool bSolid, [[maybe_unused]] const ColorB& col, [[maybe_unused]] const EBoundingBoxDrawStyle& bbDrawStyle) {} - - virtual void DrawOBB([[maybe_unused]] const OBB& obb, [[maybe_unused]] const Vec3& pos, [[maybe_unused]] bool bSolid, [[maybe_unused]] const ColorB& col, [[maybe_unused]] const EBoundingBoxDrawStyle& bbDrawStyle) {} - virtual void DrawOBB([[maybe_unused]] const OBB& obb, [[maybe_unused]] const Matrix34& matWorld, [[maybe_unused]] bool bSolid, [[maybe_unused]] const ColorB& col, [[maybe_unused]] const EBoundingBoxDrawStyle& bbDrawStyle) {} - - virtual void DrawSphere([[maybe_unused]] const Vec3& pos, [[maybe_unused]] float radius, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded = true) {} - virtual void DrawDisk([[maybe_unused]] const Vec3& pos, [[maybe_unused]] const Vec3& dir, [[maybe_unused]] float radius, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded = true) {} - virtual void DrawCone([[maybe_unused]] const Vec3& pos, [[maybe_unused]] const Vec3& dir, [[maybe_unused]] float radius, [[maybe_unused]] float height, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded = true) {} - virtual void DrawCylinder([[maybe_unused]] const Vec3& pos, [[maybe_unused]] const Vec3& dir, [[maybe_unused]] float radius, [[maybe_unused]] float height, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded = true) {} - - virtual void DrawBone([[maybe_unused]] const Vec3& rParent, [[maybe_unused]] const Vec3& rBone, [[maybe_unused]] ColorB col) {} - - virtual void RenderText([[maybe_unused]] Vec3 pos, [[maybe_unused]] SDrawTextInfo& ti, [[maybe_unused]] const char* format, [[maybe_unused]] va_list args) {} - - virtual void Flush() {} - virtual void Commit([[maybe_unused]] uint frames = 0) {} - virtual void Process() {} - -public: - CAuxGeomCB_Null() {} - ~CAuxGeomCB_Null() {} -}; - -#endif // #ifndef _RENDERAUXGEOM_H_ diff --git a/Code/CryEngine/RenderDll/Common/RenderCapabilities.h b/Code/CryEngine/RenderDll/Common/RenderCapabilities.h deleted file mode 100644 index 84e5042272..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderCapabilities.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDERCAPABILITIES_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDERCAPABILITIES_H -#pragma once - -#include -#include - -namespace RenderCapabilities -{ - // GPU Vendor ID list - static const unsigned int s_gpuVendorIdNVIDIA = 0x10de; - static const unsigned int s_gpuVendorIdAMD = 0x1002; - static const unsigned int s_gpuVendorIdIntel = 0x8086; - static const unsigned int s_gpuVendorIdQualcomm = 0x5143; - static const unsigned int s_gpuVendorIdSamsung = 0x1099; - static const unsigned int s_gpuVendorIdARM = 0x13B5; - - //Note that for platforms that don't support texture views, you are still allowed to create a single view, that view must "match" the creation parameters of - //the texture. - bool SupportsTextureViews(); - - // Test to determine if stencil textures are supported - bool SupportsStencilTextures(); - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - // Test to determine how much MRT bpp is available. (-1 means no restriction) - int GetAvailableMRTbpp(); - - // Tests to see if GMEM 128bpp path is supported. - bool Supports128bppGmemPath(); - - // Tests to see if GMEM 256bpp path is supported. - bool Supports256bppGmemPath(); - - // Tests to see if the device can support enough renderTargets. - bool SupportsRenderTargets(int numRTs); -#endif - -#if defined(OPENGL_ES) - bool SupportsHalfFloatRendering(); -#endif - -#if defined(OPENGL_ES) || defined(OPENGL) - uint32 GetDeviceGLVersion(); -#endif - - //Check if Depth clipping API is enabled - bool SupportsDepthClipping(); - - // Flags for Frame Buffer Fetch capabilities - enum - { - FBF_ALL_COLORS = 0,// Can fetch from any color render target that is bound. - FBF_COLOR0, // Some devices only allows fetching from the first color render target. - FBF_DEPTH, // Can fetch the depth value from the attached buffer. - FBF_STENCIL, // Can fetch the stencil value from the attached buffer. - FBF_COUNT - }; - - using FrameBufferFetchMask = AZStd::bitset; - - FrameBufferFetchMask GetFrameBufferFetchCapabilities(); - - // Extracting this out as to not pollute rest of code base with a bunch of "if defined(OPENGL_ES)" - bool SupportsPLSExtension(); - - bool SupportsDualSourceBlending(); - - bool SupportsStructuredBuffer(EShaderStage stage); - - bool SupportsIndependentBlending(); -} - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDERCAPABILITIES_H diff --git a/Code/CryEngine/RenderDll/Common/RenderMesh.cpp b/Code/CryEngine/RenderDll/Common/RenderMesh.cpp deleted file mode 100644 index 357731fc6d..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderMesh.cpp +++ /dev/null @@ -1,5233 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "IIndexedMesh.h" -#include "CGFContent.h" -#include "GeomQuery.h" -#include "RenderMesh.h" -#include "PostProcess/PostEffects.h" -#include "QTangent.h" -#include - -#if !defined(NULL_RENDERER) -#include "XRenderD3D9/DriverD3D.h" -#endif - -#define RENDERMESH_ASYNC_MEMCPY_THRESHOLD (1 << 10) -#define MESH_DATA_DEFAULT_ALIGN (128u) - -#ifdef MESH_TESSELLATION_RENDERER -// Rebuilding the adjaency information needs access to system copies of the buffers. Needs fixing -#undef BUFFER_ENABLE_DIRECT_ACCESS -#define BUFFER_ENABLE_DIRECT_ACCESS 0 -#endif - -namespace -{ - class CConditionalLock - { - public: - CConditionalLock(CryCriticalSection& lock, bool doConditionalLock) - : m_critSection(lock) - , m_doConditionalLock(doConditionalLock) - { - if (m_doConditionalLock) - { - m_critSection.Lock(); - } - } - ~CConditionalLock() - { - if (m_doConditionalLock) - { - m_critSection.Unlock(); - } - } - - private: - CryCriticalSection& m_critSection; - bool m_doConditionalLock = false; - }; - - static inline void RelinkTail(util::list& instance, util::list& list, int threadId) - { - // Conditional lock logic - When multi-threaded rendering is enabled, - // this data is double buffered and we must only lock when attempting - // to modify the fill thread data. Only the render thread should - // access the process thread data so we don't need to lock in that case. - // In single-threaded rendering (editor) we must always lock because - // the data is not double buffered. - bool isRenderThread = gRenDev->m_pRT->IsRenderThread(); - bool doConditionalLock = !isRenderThread || threadId == gRenDev->m_pRT->CurThreadFill() || CRenderer::CV_r_multithreaded == 0; - - CConditionalLock lock(CRenderMesh::m_sLinkLock, doConditionalLock); - instance.relink_tail(&list); - } - - struct SMeshPool - { - IGeneralMemoryHeap* m_MeshDataPool; - IGeneralMemoryHeap* m_MeshInstancePool; - void* m_MeshDataMemory; - void* m_MeshInstanceMemory; - CryCriticalSection m_MeshPoolCS; - SMeshPoolStatistics m_MeshDataPoolStats; - SMeshPool() - : m_MeshPoolCS() - , m_MeshDataPool() - , m_MeshInstancePool() - , m_MeshDataMemory() - , m_MeshInstanceMemory() - , m_MeshDataPoolStats() - {} - }; - static SMeshPool s_MeshPool; - - ////////////////////////////////////////////////////////////////////////// - static void* AllocateMeshData(size_t nSize, size_t nAlign = MESH_DATA_DEFAULT_ALIGN, [[maybe_unused]] bool bFlush = false) - { - nSize = (nSize + (nAlign - 1)) & ~(nAlign - 1); - - if (s_MeshPool.m_MeshDataPool && s_MeshPool.m_MeshDataPoolStats.nPoolSize > nSize) - { -try_again: - s_MeshPool.m_MeshPoolCS.Lock(); - void* ptr = s_MeshPool.m_MeshDataPool->Memalign(nAlign, nSize, "RENDERMESH_POOL"); - if (ptr) - { - s_MeshPool.m_MeshDataPoolStats.nPoolInUse += s_MeshPool.m_MeshDataPool->UsableSize(ptr); - s_MeshPool.m_MeshDataPoolStats.nPoolInUsePeak = - std::max( - s_MeshPool.m_MeshDataPoolStats.nPoolInUsePeak, - s_MeshPool.m_MeshDataPoolStats.nPoolInUse); - s_MeshPool.m_MeshPoolCS.Unlock(); - return ptr; - } - else - { - s_MeshPool.m_MeshPoolCS.Unlock(); - // Clean up the stale mesh temporary data - and do it from the main thread. - if (gRenDev->m_pRT->IsMainThread() && CRenderMesh::ClearStaleMemory(false, gRenDev->m_RP.m_nFillThreadID)) - { - goto try_again; - } - else if (gRenDev->m_pRT->IsRenderThread() && CRenderMesh::ClearStaleMemory(false, gRenDev->m_RP.m_nProcessThreadID)) - { - goto try_again; - } - } - s_MeshPool.m_MeshPoolCS.Lock(); - s_MeshPool.m_MeshDataPoolStats.nFallbacks += nSize; - s_MeshPool.m_MeshPoolCS.Unlock(); - } - return CryModuleMemalign(nSize, nAlign); - } - - ////////////////////////////////////////////////////////////////////////// - static void FreeMeshData(void* ptr) - { - if (ptr == NULL) - { - return; - } - { - AUTO_LOCK(s_MeshPool.m_MeshPoolCS); - size_t nSize = 0u; - if (s_MeshPool.m_MeshDataPool && (nSize = s_MeshPool.m_MeshDataPool->Free(ptr)) > 0) - { - s_MeshPool.m_MeshDataPoolStats.nPoolInUse -= - (nSize < s_MeshPool.m_MeshDataPoolStats.nPoolInUse) ? nSize : s_MeshPool.m_MeshDataPoolStats.nPoolInUse; - return; - } - } - CryModuleMemalignFree(ptr); - } - - template - static Type* AllocateMeshData(size_t nCount = 1) - { - void* pStorage = AllocateMeshData(sizeof(Type) * nCount, std::max((size_t)TARGET_DEFAULT_ALIGN, (size_t)__alignof(Type))); - if (!pStorage) - { - return NULL; - } - Type* pTypeArray = reinterpret_cast(pStorage); - for (size_t i = 0; i < nCount; ++i) - { - new (pTypeArray + i)Type; - } - return pTypeArray; - } - - static bool InitializePool() - { - if (gRenDev->CV_r_meshpoolsize > 0) - { - if (s_MeshPool.m_MeshDataPool || s_MeshPool.m_MeshDataMemory) - { - CryFatalError("render meshpool already initialized"); - return false; - } - size_t poolSize = static_cast(gRenDev->CV_r_meshpoolsize) * 1024U; - s_MeshPool.m_MeshDataMemory = CryModuleMemalign(poolSize, 128u); - if (!s_MeshPool.m_MeshDataMemory) - { - CryFatalError("could not allocate render meshpool"); - return false; - } - - // Initialize the actual pool - s_MeshPool.m_MeshDataPool = gEnv->pSystem->GetIMemoryManager()->CreateGeneralMemoryHeap( - s_MeshPool.m_MeshDataMemory, poolSize, "RENDERMESH_POOL"); - s_MeshPool.m_MeshDataPoolStats.nPoolSize = poolSize; - } - if (gRenDev->CV_r_meshinstancepoolsize && !s_MeshPool.m_MeshInstancePool) - { - size_t poolSize = static_cast(gRenDev->CV_r_meshinstancepoolsize) * 1024U; - s_MeshPool.m_MeshInstanceMemory = CryModuleMemalign(poolSize, 128u); - if (!s_MeshPool.m_MeshInstanceMemory) - { - CryFatalError("could not allocate render mesh instance pool"); - return false; - } - - s_MeshPool.m_MeshInstancePool = gEnv->pSystem->GetIMemoryManager()->CreateGeneralMemoryHeap( - s_MeshPool.m_MeshInstanceMemory, poolSize, "RENDERMESH_INSTANCE_POOL"); - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUse = 0; - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUsePeak = 0; - s_MeshPool.m_MeshDataPoolStats.nInstancePoolSize = gRenDev->CV_r_meshinstancepoolsize * 1024; - } - return true; - } - - static void ShutdownPool() - { - if (s_MeshPool.m_MeshDataPool) - { - s_MeshPool.m_MeshDataPool->Release(); - s_MeshPool.m_MeshDataPool = NULL; - } - if (s_MeshPool.m_MeshDataMemory) - { - CryModuleMemalignFree(s_MeshPool.m_MeshDataMemory); - s_MeshPool.m_MeshDataMemory = NULL; - } - if (s_MeshPool.m_MeshInstancePool) - { - s_MeshPool.m_MeshInstancePool->Cleanup(); - s_MeshPool.m_MeshInstancePool->Release(); - s_MeshPool.m_MeshInstancePool = NULL; - } - if (s_MeshPool.m_MeshInstanceMemory) - { - CryModuleMemalignFree(s_MeshPool.m_MeshInstanceMemory); - s_MeshPool.m_MeshInstanceMemory = NULL; - } - } - - static void* AllocateMeshInstanceData(size_t size, size_t align) - { - if (s_MeshPool.m_MeshInstancePool) - { - if (void* ptr = s_MeshPool.m_MeshInstancePool->Memalign(align, size, "rendermesh instance data")) - { -# if !defined(_RELEASE) - AUTO_LOCK(s_MeshPool.m_MeshPoolCS); - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUsePeak = std::max( - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUsePeak, - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUse += size); -# endif - return ptr; - } - } - return CryModuleMemalign(size, align); - } - - static void FreeMeshInstanceData(void* ptr) - { - if (s_MeshPool.m_MeshInstancePool) - { - size_t size = s_MeshPool.m_MeshInstancePool->UsableSize(ptr); - if (size) - { -# if !defined(_RELEASE) - AUTO_LOCK(s_MeshPool.m_MeshPoolCS); - s_MeshPool.m_MeshDataPoolStats.nInstancePoolInUse -= size; -# endif - s_MeshPool.m_MeshInstancePool->Free(ptr); - return; - } - } - CryModuleMemalignFree(ptr); - } -} - -#define alignup(alignment, value) ((((uintptr_t)(value)) + ((alignment) - 1)) & (~((uintptr_t)(alignment) - 1))) -#define alignup16(value) alignup(16, value) - -namespace -{ - inline uint32 GetCurrentRenderFrameID() - { - ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT); - return gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - }; -} - -#if defined(USE_VBIB_PUSH_DOWN) -static inline bool VidMemPushDown(void* pDst, const void* pSrc, size_t nSize, void* pDst1 = NULL, const void* pSrc1 = NULL, size_t nSize1 = 0, int cachePosStride = -1, void* pFP16Dst = NULL, uint32 nVerts = 0) -{ -} - #define ASSERT_LOCK -static std::vector g_MeshCleanupVec; //for cleanup of meshes itself -#else - #define ASSERT_LOCK assert((m_nVerts == 0) || pData) -#endif - -#if !defined(_RELEASE) -ILINE void CheckVideoBufferAccessViolation([[maybe_unused]] CRenderMesh& mesh) -{ - //LogWarning("CRenderMesh::LockVB: accessing video buffer for cgf=%s",mesh.GetSourceName()); -} - #define MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT CheckVideoBufferAccessViolation(*this) -#else - #define MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT -#endif - -CryCriticalSection CRenderMesh::m_sLinkLock; - -// Additional streams stride -int32 CRenderMesh::m_cSizeStream[VSF_NUM] = -{ - -1, - sizeof(SPipTangents), // VSF_TANGENTS - sizeof(SPipQTangents), // VSF_QTANGENTS - sizeof(SVF_W4B_I4S), // VSF_HWSKIN_INFO - sizeof(SVF_P3F), // VSF_VERTEX_VELOCITY -# if ENABLE_NORMALSTREAM_SUPPORT - sizeof(SPipNormal), // VSF_NORMALS -#endif -}; - -util::list CRenderMesh::m_MeshList; -util::list CRenderMesh::m_MeshGarbageList[MAX_RELEASED_MESH_FRAMES]; -util::list CRenderMesh::m_MeshDirtyList[2]; -util::list CRenderMesh::m_MeshModifiedList[2]; - -int CRenderMesh::Release() -{ - long refCnt = CryInterlockedDecrement(&m_nRefCounter); -# if !defined(_RELEASE) - if (refCnt < 0) - { - CryLogAlways("CRenderMesh::Release() called so many times on rendermesh that refcount became negative"); - if (CRenderer::CV_r_BreakOnError) - { - __debugbreak(); - } - } -# endif - if (refCnt == 0) - { - AUTO_LOCK(m_sLinkLock); -# if !defined(_RELEASE) - if (m_nFlags & FRM_RELEASED) - { - CryLogAlways("CRenderMesh::Release() mesh already in the garbage list (double delete pending)"); - if (CRenderer::CV_r_BreakOnError) - { - __debugbreak(); - } - } -# endif - m_nFlags |= FRM_RELEASED; - int nFrame = gRenDev->GetFrameID(false); - util::list* garbage = &CRenderMesh::m_MeshGarbageList[nFrame & (MAX_RELEASED_MESH_FRAMES - 1)]; - m_Chain.relink_tail(garbage); - } - - return refCnt; -} - -CRenderMesh::CRenderMesh() -{ -#if defined(USE_VBIB_PUSH_DOWN) - m_VBIBFramePushID = 0; -#endif - memset(m_VBStream, 0x0, sizeof(m_VBStream)); - - SMeshStream* streams = (SMeshStream*)AllocateMeshInstanceData(sizeof(SMeshStream) * VSF_NUM, 64u); - for (signed i = 0; i < VSF_NUM; ++i) - { - new (m_VBStream[i] = &streams[i])SMeshStream(); - } - - m_keepSysMesh = false; - m_nLastRenderFrameID = 0; - m_nLastSubsetGCRenderFrameID = 0; - m_nThreadAccessCounter = 0; - for (size_t i = 0; i < 2; ++i) - { - m_asyncUpdateState[i] = m_asyncUpdateStateCounter[i] = 0; - } - -# if !defined(_RELEASE) && defined(RM_CATCH_EXCESSIVE_LOCKS) - m_lockTime = 0.f; -# endif -} - -CRenderMesh::CRenderMesh (const char* szType, const char* szSourceName, bool bLock) -{ - memset(m_VBStream, 0x0, sizeof(m_VBStream)); - - SMeshStream* streams = (SMeshStream*)AllocateMeshInstanceData(sizeof(SMeshStream) * VSF_NUM, 64u); - for (signed i = 0; i < VSF_NUM; ++i) - { - new (m_VBStream[i] = &streams[i])SMeshStream(); - } - - m_keepSysMesh = false; - m_nRefCounter = 0; - m_nLastRenderFrameID = 0; - m_nLastSubsetGCRenderFrameID = 0; - - m_sType = szType; - m_sSource = szSourceName; - - m_vBoxMin = m_vBoxMax = Vec3(0, 0, 0); //used for hw occlusion test - m_nVerts = 0; - m_nInds = 0; - m_vertexFormat = AZ::Vertex::Format(eVF_P3F_C4B_T2F); - m_pVertexContainer = NULL; - - { - AUTO_LOCK(m_sLinkLock); - m_Chain.relink_tail(&m_MeshList); - } - m_nPrimetiveType = eptTriangleList; - - // m_nFrameRender = 0; - //m_nFrameUpdate = 0; - m_nClientTextureBindID = 0; -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - m_pTrisMap = NULL; -#endif - - m_pCachePos = NULL; - m_nFrameRequestCachePos = 0; - m_nFlagsCachePos = 0; - - m_nFrameRequestCacheUVs = 0; - m_nFlagsCacheUVs = 0; - - _SetRenderMeshType(eRMT_Static); - - m_nFlags = 0; - m_fGeometricMeanFaceArea = 0.f; - m_nLod = 0; - -#if defined(USE_VBIB_PUSH_DOWN) - m_VBIBFramePushID = 0; -#endif - - m_nThreadAccessCounter = 0; - for (size_t i = 0; i < 2; ++i) - { - m_asyncUpdateState[i] = m_asyncUpdateStateCounter[i] = 0; - } - - IF (bLock, 0)//when called from another thread like the Streaming AsyncCallbackCGF, we need to lock it - { - LockForThreadAccess(); - } -} - -void CRenderMesh::Cleanup() -{ - FreeDeviceBuffers(false); - FreeSystemBuffers(); - - m_meshSubSetIndices.clear(); - - if (m_pVertexContainer) - { - m_pVertexContainer->m_lstVertexContainerUsers.Delete(this); - m_pVertexContainer = NULL; - } - - for (int i = 0; i < m_lstVertexContainerUsers.Count(); i++) - { - if (m_lstVertexContainerUsers[i]->GetVertexContainer() == this) - { - m_lstVertexContainerUsers[i]->m_pVertexContainer = NULL; - } - } - m_lstVertexContainerUsers.Clear(); - - ReleaseRenderChunks(&m_ChunksSkinned); - ReleaseRenderChunks(&m_ChunksSubObjects); - ReleaseRenderChunks(&m_Chunks); - - m_ChunksSubObjects.clear(); - m_Chunks.clear(); - -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - SAFE_DELETE(m_pTrisMap); -#endif - - for (size_t i = 0; i < 2; ++i) - { - m_asyncUpdateState[i] = m_asyncUpdateStateCounter[i] = 0; - } - - for (int i = 0; i < VSF_NUM; ++i) - { - if (m_VBStream[i]) - { - m_VBStream[i]->~SMeshStream(); - } - } - FreeMeshInstanceData(m_VBStream[0]); - memset(m_VBStream, 0, sizeof(m_VBStream)); - - for (size_t j = 0; j < 2; ++j) - { - for (size_t i = 0, end = m_CreatedBoneIndices[j].size(); i < end; ++i) - { - delete[] m_CreatedBoneIndices[j][i].pStream; - } - } - for (size_t i = 0, end = m_RemappedBoneIndices.size(); i < end; ++i) - { - if (m_RemappedBoneIndices[i].refcount && m_RemappedBoneIndices[i].guid != ~0u) - { - CryLogAlways("remapped bone indices with refcount '%d' still around for '%s 0x%p\n", m_RemappedBoneIndices[i].refcount, m_sSource.c_str(), this); - } - if (m_RemappedBoneIndices[i].buffer != ~0u) - { - // Unregister the allocation with the VRAM driller - void* address = reinterpret_cast(m_RemappedBoneIndices[i].buffer); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, UnregisterAllocation, address); - - gRenDev->m_DevBufMan.Destroy(m_RemappedBoneIndices[i].buffer); - } - } -} - -////////////////////////////////////////////////////////////////////////// -CRenderMesh::~CRenderMesh() -{ - // make sure to stop and delete all mesh subset indice tasks - ASSERT_IS_RENDER_THREAD(gRenDev->m_pRT); - - int nThreadID = gRenDev->m_RP.m_nProcessThreadID; - for (int i = 0; i < RT_COMMAND_BUF_COUNT; SyncAsyncUpdate(i++)) - { - ; - } - - // make sure no subset rendermesh job is still running which uses this mesh - for (int j = 0; j < RT_COMMAND_BUF_COUNT; ++j) - { - size_t nNumSubSetRenderMeshJobs = m_meshSubSetRenderMeshJobs[j].size(); - for (size_t i = 0; i < nNumSubSetRenderMeshJobs; ++i) - { - SMeshSubSetIndicesJobEntry& rSubSetJob = m_meshSubSetRenderMeshJobs[j][i]; - if (rSubSetJob.m_pSrcRM == this) - { - rSubSetJob.jobExecutor.WaitForCompletion(); - rSubSetJob.m_pSrcRM = NULL; - } - } - } - - // remove ourself from deferred subset mesh garbage collection - for (size_t i = 0; i < m_deferredSubsetGarbageCollection[nThreadID].size(); ++i) - { - if (m_deferredSubsetGarbageCollection[nThreadID][i] == this) - { - m_deferredSubsetGarbageCollection[nThreadID][i] = NULL; - } - } - - assert(m_nThreadAccessCounter == 0); - - { - AUTO_LOCK(m_sLinkLock); - for (int i = 0; i < 2; ++i) - { - m_Dirty[i].erase(), m_Modified[i].erase(); - } - m_Chain.erase(); - } - - Cleanup(); -} - -void CRenderMesh::ReleaseRenderChunks(TRenderChunkArray* pChunks) -{ - if (pChunks) - { - for (size_t i = 0, c = pChunks->size(); i != c; ++i) - { - CRenderChunk& rChunk = pChunks->at(i); - - if (rChunk.pRE) - { - CREMeshImpl* pRE = static_cast(rChunk.pRE); - pRE->Release(false); - pRE->m_pRenderMesh = NULL; - rChunk.pRE = 0; - } - } - } -} - -SMeshStream* CRenderMesh::GetVertexStream(int nStream, uint32 nFlags) -{ - SMeshStream*& pMS = m_VBStream[nStream]; - IF (!pMS && (nFlags & FSL_WRITE), 0) - { - pMS = new (AllocateMeshInstanceData(sizeof(SMeshStream), alignof(SMeshStream)))SMeshStream; - } - return pMS; -} - -void* CRenderMesh::LockVB(int nStream, uint32 nFlags, int nVerts, int* nStride, [[maybe_unused]] bool prefetchIB, [[maybe_unused]] bool inplaceCachePos) -{ - FUNCTION_PROFILER_RENDERER; -# if !defined(_RELEASE) - if (!m_nThreadAccessCounter) - { - CryLogAlways("rendermesh must be locked via LockForThreadAccess() before LockIB/VB is called"); - if (CRenderer::CV_r_BreakOnError) - { - __debugbreak(); - } - } -#endif - const int threadId = gRenDev->m_RP.m_nFillThreadID; - - if (!CanRender()) // if allocation failure suffered, don't lock anything anymore - { - return NULL; - } - - SREC_AUTO_LOCK(m_sResLock);//need lock as resource must not be updated concurrently - SMeshStream* MS = GetVertexStream(nStream, nFlags); - -#if defined(USE_VBIB_PUSH_DOWN) - m_VBIBFramePushID = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - if (nFlags == FSL_SYSTEM_CREATE || nFlags == FSL_SYSTEM_UPDATE) - { - MS->m_nLockFlags &= ~FSL_VBIBPUSHDOWN; - } -#endif - - assert(nVerts <= (int)m_nVerts); - if (nVerts > (int)m_nVerts) - { - nVerts = m_nVerts; - } - if (nStride) - { - *nStride = GetStreamStride(nStream); - } - - m_nFlags |= FRM_READYTOUPLOAD; - - byte* pD; - - if (nFlags == FSL_SYSTEM_CREATE) - { -lSysCreate: - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (!MS->m_pUpdateData) - { - uint32 nSize = GetStreamSize(nStream); - pD = reinterpret_cast(AllocateMeshData(nSize)); - if (!pD) - { - return NULL; - } - MS->m_pUpdateData = pD; - } - else - { - pD = (byte*)MS->m_pUpdateData; - } - //MS->m_nFrameRequest = nFrame; - MS->m_nLockFlags = (FSL_SYSTEM_CREATE | (MS->m_nLockFlags & FSL_LOCKED)); - return pD; - } - else - if (nFlags == FSL_SYSTEM_UPDATE) - { -lSysUpdate: - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (!MS->m_pUpdateData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - CopyStreamToSystemForUpdate(*MS, GetStreamSize(nStream)); - } - assert(nStream || MS->m_pUpdateData); - if (!MS->m_pUpdateData) - { - return NULL; - } - //MS->m_nFrameRequest = nFrame; - pD = (byte*)MS->m_pUpdateData; - MS->m_nLockFlags = (nFlags | (MS->m_nLockFlags & FSL_LOCKED)); - return pD; - } - else if (nFlags == FSL_READ) - { - if (!MS) - { - return NULL; - } - RelinkTail(m_Dirty[threadId], m_MeshDirtyList[threadId], threadId); - if (MS->m_pUpdateData) - { - pD = (byte*)MS->m_pUpdateData; - return pD; - } - nFlags = FSL_READ | FSL_VIDEO; - } - - if (nFlags == (FSL_READ | FSL_VIDEO)) - { - if (!MS) - { - return NULL; - } - RelinkTail(m_Dirty[threadId], m_MeshDirtyList[threadId], threadId); -# if !BUFFER_ENABLE_DIRECT_ACCESS || defined(NULL_RENDERER) - if (gRenDev->m_pRT && gRenDev->m_pRT->IsMultithreaded()) - { - // Always use system copy in MT mode - goto lSysUpdate; - } - else -# endif - { - buffer_handle_t nVB = MS->m_nID; - if (nVB == ~0u) - { - return NULL; - } - // Try to lock device buffer in single-threaded mode - if (!MS->m_pLockedData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - MS->m_pLockedData = gRenDev->m_DevBufMan.BeginRead(nVB); - if (MS->m_pLockedData) - { - MS->m_nLockFlags |= FSL_LOCKED; - } - } - if (MS->m_pLockedData) - { - ++MS->m_nLockCount; - pD = (byte*)MS->m_pLockedData; - return pD; - } - } - } - if (nFlags == (FSL_VIDEO_CREATE)) - { - // Only consoles support direct uploading to vram, but as the data is not - // double buffered in the non-dynamic case, only creation is supported - // DX11 has to use the deferred context to call map, which is not threadsafe - // DX9 can experience huge stalls if resources are used while rendering is performed - buffer_handle_t nVB = ~0u; -# if BUFFER_ENABLE_DIRECT_ACCESS && !defined(NULL_RENDERER) - nVB = MS->m_nID; - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - if ((nVB != ~0u && (MS->m_nFrameCreate != nFrame || MS->m_nElements != m_nVerts)) || !CRenderer::CV_r_buffer_enable_lockless_updates) -# endif - goto lSysCreate; - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (nVB == ~0u && !CreateVidVertices(nStream)) - { - RT_AllocationFailure("Create VB-Stream", GetStreamSize(nStream, m_nVerts)); - return NULL; - } - nVB = MS->m_nID; - if (!MS->m_pLockedData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - if ((MS->m_pLockedData = gRenDev->m_DevBufMan.BeginWrite(nVB)) == NULL) - { - return NULL; - } - MS->m_nLockFlags |= FSL_DIRECT | FSL_LOCKED; - } - ++MS->m_nLockCount; - pD = (byte*)MS->m_pLockedData; - return pD; - } - if (nFlags == (FSL_VIDEO_UPDATE)) - { - goto lSysUpdate; - } - - return NULL; -} - -vtx_idx* CRenderMesh::LockIB(uint32 nFlags, int nOffset, [[maybe_unused]] int nInds) -{ - FUNCTION_PROFILER_RENDERER; - - byte* pD; -# if !defined(_RELEASE) - if (!m_nThreadAccessCounter) - { - CryLogAlways("rendermesh must be locked via LockForThreadAccess() before LockIB/VB is called"); - if (CRenderer::CV_r_BreakOnError) - { - __debugbreak(); - } - } -#endif - if (!CanRender()) // if allocation failure suffered, don't lock anything anymore - { - return NULL; - } - - const int threadId = gRenDev->m_RP.m_nFillThreadID; - - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - SREC_AUTO_LOCK(m_sResLock);//need lock as resource must not be updated concurrently - -#if defined(USE_VBIB_PUSH_DOWN) - m_VBIBFramePushID = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - if (nFlags == FSL_SYSTEM_CREATE || nFlags == FSL_SYSTEM_UPDATE) - { - m_IBStream.m_nLockFlags &= ~FSL_VBIBPUSHDOWN; - } -#endif - m_nFlags |= FRM_READYTOUPLOAD; - - assert(nInds <= (int)m_nInds); - if (nFlags == FSL_SYSTEM_CREATE) - { -lSysCreate: - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (!m_IBStream.m_pUpdateData) - { - uint32 nSize = m_nInds * sizeof(vtx_idx); - pD = reinterpret_cast(AllocateMeshData(nSize)); - if (!pD) - { - return NULL; - } - m_IBStream.m_pUpdateData = (vtx_idx*)pD; - } - else - { - pD = (byte*)m_IBStream.m_pUpdateData; - } - //m_IBStream.m_nFrameRequest = nFrame; - m_IBStream.m_nLockFlags = (nFlags | (m_IBStream.m_nLockFlags & FSL_LOCKED)); - return (vtx_idx*)&pD[nOffset]; - } - else - if (nFlags == FSL_SYSTEM_UPDATE) - { -lSysUpdate: - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (!m_IBStream.m_pUpdateData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - CopyStreamToSystemForUpdate(m_IBStream, sizeof(vtx_idx) * m_nInds); - } - assert(m_IBStream.m_pUpdateData); - if (!m_IBStream.m_pUpdateData) - { - return NULL; - } - //m_IBStream.m_nFrameRequest = nFrame; - pD = (byte*)m_IBStream.m_pUpdateData; - m_IBStream.m_nLockFlags = (nFlags | (m_IBStream.m_nLockFlags & FSL_LOCKED)); - return (vtx_idx*)&pD[nOffset]; - } - else if (nFlags == FSL_READ) - { - RelinkTail(m_Dirty[threadId], m_MeshDirtyList[threadId], threadId); - if (m_IBStream.m_pUpdateData) - { - pD = (byte*)m_IBStream.m_pUpdateData; - return (vtx_idx*)&pD[nOffset]; - } - nFlags = FSL_READ | FSL_VIDEO; - } - - if (nFlags == (FSL_READ | FSL_VIDEO)) - { - RelinkTail(m_Dirty[threadId], m_MeshDirtyList[threadId], threadId); - buffer_handle_t nIB = m_IBStream.m_nID; - if (nIB == ~0u) - { - return NULL; - } - if (gRenDev->m_pRT && gRenDev->m_pRT->IsMultithreaded()) - { - // Always use system copy in MT mode - goto lSysUpdate; - } - else - { - // TODO: make smart caching mesh algorithm for consoles - if (!m_IBStream.m_pLockedData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - m_IBStream.m_pLockedData = gRenDev->m_DevBufMan.BeginRead(nIB); - if (m_IBStream.m_pLockedData) - { - m_IBStream.m_nLockFlags |= FSL_LOCKED; - } - } - if (m_IBStream.m_pLockedData) - { - pD = (byte*)m_IBStream.m_pLockedData; - ++m_IBStream.m_nLockCount; - return (vtx_idx*)&pD[nOffset]; - } - } - } - if (nFlags == (FSL_VIDEO_CREATE)) - { - // Only consoles support direct uploading to vram, but as the data is not - // double buffered, only creation is supported - // DX11 has to use the deferred context to call map, which is not threadsafe - // DX9 can experience huge stalls if resources are used while rendering is performed - buffer_handle_t nIB = -1; -# if BUFFER_ENABLE_DIRECT_ACCESS && !defined(NULL_RENDERER) - nIB = m_IBStream.m_nID; - if ((nIB != ~0u && (m_IBStream.m_nFrameCreate || m_IBStream.m_nElements != m_nInds)) || !CRenderer::CV_r_buffer_enable_lockless_updates) -# endif - goto lSysCreate; - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - if (m_IBStream.m_nID == ~0u) - { - size_t bufferSize = m_nInds * sizeof(vtx_idx); - nIB = (m_IBStream.m_nID = gRenDev->m_DevBufMan.Create(BBT_INDEX_BUFFER, (BUFFER_USAGE)m_eType, bufferSize)); - m_IBStream.m_nFrameCreate = nFrame; - - // Register the allocation with the VRAM driller - void* address = reinterpret_cast(nIB); - const char* bufferName = GetSourceName(); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterAllocation, address, bufferSize, bufferName, Render::Debug::VRAM_CATEGORY_BUFFER, Render::Debug::VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER); - } - if (nIB == ~0u) - { - RT_AllocationFailure("Create IB-Stream", m_nInds * sizeof(vtx_idx)); - return NULL; - } - m_IBStream.m_nElements = m_nInds; - if (!m_IBStream.m_pLockedData) - { - MESSAGE_VIDEO_BUFFER_ACC_ATTEMPT; - if ((m_IBStream.m_pLockedData = gRenDev->m_DevBufMan.BeginWrite(nIB)) == NULL) - { - return NULL; - } - m_IBStream.m_nLockFlags |= FSL_DIRECT | FSL_LOCKED; - } - ++m_IBStream.m_nLockCount; - pD = (byte*)m_IBStream.m_pLockedData; - return (vtx_idx*)&pD[nOffset]; - } - if (nFlags == (FSL_VIDEO_UPDATE)) - { - goto lSysUpdate; - } - - assert(0); - - return NULL; -} - -ILINE void CRenderMesh::UnlockVB(int nStream) -{ - SREC_AUTO_LOCK(m_sResLock); - SMeshStream* pMS = GetVertexStream(nStream, 0); - if (pMS && pMS->m_nLockFlags & FSL_LOCKED) - { - assert(pMS->m_nLockCount); - if ((--pMS->m_nLockCount) == 0) - { - gRenDev->m_DevBufMan.EndReadWrite(pMS->m_nID); - pMS->m_nLockFlags &= ~FSL_LOCKED; - pMS->m_pLockedData = NULL; - } - } - if (pMS && (pMS->m_nLockFlags & FSL_WRITE) && (pMS->m_nLockFlags & (FSL_SYSTEM_CREATE | FSL_SYSTEM_UPDATE))) - { - pMS->m_nLockFlags &= ~(FSL_SYSTEM_CREATE | FSL_SYSTEM_UPDATE); - pMS->m_nFrameRequest = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - } -} - -ILINE void CRenderMesh::UnlockIB() -{ - SREC_AUTO_LOCK(m_sResLock); - if (m_IBStream.m_nLockFlags & FSL_LOCKED) - { - assert(m_IBStream.m_nLockCount); - if ((--m_IBStream.m_nLockCount) == 0) - { - gRenDev->m_DevBufMan.EndReadWrite(m_IBStream.m_nID); - m_IBStream.m_nLockFlags &= ~FSL_LOCKED; - m_IBStream.m_pLockedData = NULL; - } - } - if ((m_IBStream.m_nLockFlags & FSL_WRITE) && (m_IBStream.m_nLockFlags & (FSL_SYSTEM_CREATE | FSL_SYSTEM_UPDATE))) - { - m_IBStream.m_nLockFlags &= ~(FSL_SYSTEM_CREATE | FSL_SYSTEM_UPDATE); - m_IBStream.m_nFrameRequest = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - } -} - -void CRenderMesh::UnlockStream(int nStream) -{ - UnlockVB(nStream); - SREC_AUTO_LOCK(m_sResLock); - - if (nStream == VSF_GENERAL) - { - if (m_nFlagsCachePos && m_pCachePos) - { - uint32 i; - int nStride; - byte* pDst = (byte*)LockVB(nStream, FSL_SYSTEM_UPDATE, m_nVerts, &nStride); - assert(pDst); - if (pDst) - { - for (i = 0; i < m_nVerts; i++) - { - Vec3f16* pVDst = (Vec3f16*)pDst; - *pVDst = m_pCachePos[i]; - pDst += nStride; - } - } - m_nFlagsCachePos = 0; - } - - if (m_nFlagsCacheUVs && m_UVCache.size() > 0) - { - int nStride; - byte* streamStart = (byte*)LockVB(nStream, FSL_SYSTEM_UPDATE, m_nVerts, &nStride); - - // Iterate over the cached uv coordinates and write them to the vertex buffer stream - for (int uvSet = 0; uvSet < m_UVCache.size(); ++uvSet) - { - if (m_UVCache[uvSet]) - { - uint texCoordOffset = 0; - GetVertexFormat().TryCalculateOffset(texCoordOffset, AZ::Vertex::AttributeUsage::TexCoord, uvSet); - byte* texCoord = streamStart + texCoordOffset; - - assert(streamStart); - if (streamStart) - { - for (uint32 i = 0; i < m_nVerts; i++) - { - Vec2f16* pVDst = (Vec2f16*)texCoord; - *pVDst = m_UVCache[uvSet][i]; - texCoord += nStride; - } - } - } - } - m_nFlagsCacheUVs = 0; - } - } - - SMeshStream* pMS = GetVertexStream(nStream, 0); - IF (pMS, 1) - { - pMS->m_nLockFlags &= ~(FSL_WRITE | FSL_READ | FSL_SYSTEM | FSL_VIDEO); - } -} -void CRenderMesh::UnlockIndexStream() -{ - - UnlockIB(); - m_IBStream.m_nLockFlags &= ~(FSL_WRITE | FSL_READ | FSL_SYSTEM | FSL_VIDEO); -} - -bool CRenderMesh::CopyStreamToSystemForUpdate(SMeshStream& MS, size_t nSize) -{ - FUNCTION_PROFILER_RENDERER; - SREC_AUTO_LOCK(m_sResLock); - if (!MS.m_pUpdateData) - { - buffer_handle_t nVB = MS.m_nID; - if (nVB == ~0u) - { - return false; - } - void* pSrc = MS.m_pLockedData; - if (!pSrc) - { - pSrc = gRenDev->m_DevBufMan.BeginRead(nVB); - MS.m_nLockFlags |= FSL_LOCKED; - } - assert(pSrc); - if (!pSrc) - { - return false; - } - ++MS.m_nLockCount; - byte* pD = reinterpret_cast(AllocateMeshData(nSize, MESH_DATA_DEFAULT_ALIGN, false)); - if (pD) - { - cryMemcpy(pD, pSrc, nSize); - if (MS.m_nLockFlags & FSL_LOCKED) - { - if ((--MS.m_nLockCount) == 0) - { - MS.m_nLockFlags &= ~FSL_LOCKED; - MS.m_pLockedData = NULL; - gRenDev->m_DevBufMan.EndReadWrite(nVB); - } - } - MS.m_pUpdateData = pD; - m_nFlags |= FRM_READYTOUPLOAD; - return true; - } - } - return false; -} - -size_t CRenderMesh::SetMesh_Int(CMesh& mesh, [[maybe_unused]] int nSecColorsSetOffset, uint32 flags) -{ - LOADING_TIME_PROFILE_SECTION; - char* pVBuff = NULL; - SPipTangents* pTBuff = NULL; - SPipQTangents* pQTBuff = NULL; - SVF_P3F* pVelocities = NULL; - SPipNormal* pNBuff = NULL; - uint32 nVerts = mesh.GetVertexCount(); - uint32 nInds = mesh.GetIndexCount(); - vtx_idx* pInds = NULL; - - //AUTO_LOCK(m_sResLock);//need a resource lock as mesh could be reseted due to allocation failure - LockForThreadAccess(); - - ReleaseRenderChunks(&m_ChunksSkinned); - - m_vBoxMin = mesh.m_bbox.min; - m_vBoxMax = mesh.m_bbox.max; - - m_fGeometricMeanFaceArea = mesh.m_geometricMeanFaceArea; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Render Chunks. - ////////////////////////////////////////////////////////////////////////// - uint32 numSubsets = mesh.GetSubSetCount(); - - uint32 numChunks = 0; - for (uint32 i = 0; i < numSubsets; i++) - { - if (mesh.m_subsets[i].nNumIndices == 0) - { - continue; - } - - if (mesh.m_subsets[i].nMatFlags & MTL_FLAG_NODRAW) - { - continue; - } - - ++numChunks; - } - m_Chunks.reserve(numChunks); - - // Determine the vertex format of each chunk based on the properties of the mesh - mesh.SetSubmeshVertexFormats(); - - for (uint32 i = 0; i < numSubsets; i++) - { - CRenderChunk ChunkInfo; - - if (mesh.m_subsets[i].nNumIndices == 0) - { - continue; - } - - if (mesh.m_subsets[i].nMatFlags & MTL_FLAG_NODRAW) - { - continue; - } - - //add empty chunk, because PodArray is not working with STL-vectors - m_Chunks.push_back(ChunkInfo); - - uint32 num = m_Chunks.size(); - CRenderChunk* pChunk = &m_Chunks[num - 1]; - - pChunk->nFirstIndexId = mesh.m_subsets[i].nFirstIndexId; - pChunk->nNumIndices = mesh.m_subsets[i].nNumIndices; - pChunk->nFirstVertId = mesh.m_subsets[i].nFirstVertId; - pChunk->nNumVerts = mesh.m_subsets[i].nNumVerts; - pChunk->m_nMatID = mesh.m_subsets[i].nMatID; - pChunk->m_nMatFlags = mesh.m_subsets[i].nMatFlags; - pChunk->m_vertexFormat = mesh.m_subsets[i].vertexFormat; - if (mesh.m_subsets[i].nPhysicalizeType == PHYS_GEOM_TYPE_NONE) - { - pChunk->m_nMatFlags |= MTL_FLAG_NOPHYSICALIZE; - } - - float texelAreaDensity = 1.0f; - - if (!(flags & FSM_IGNORE_TEXELDENSITY)) - { - float posArea; - float texArea; - const char* errorText = ""; - - if (mesh.m_subsets[i].fTexelDensity > 0.00001f) - { - texelAreaDensity = mesh.m_subsets[i].fTexelDensity; - } - else - { - const bool ok = mesh.ComputeSubsetTexMappingAreas(i, posArea, texArea, errorText); - if (ok) - { - texelAreaDensity = texArea / posArea; - } - else - { - // Commented out to prevent spam (contact Moritz Finck or Marco Corbetta for details) - // gEnv->pLog->LogError("Failed to compute texture mapping density for mesh '%s': ?%s", GetSourceName(), errorText); - } - } - } - - pChunk->m_texelAreaDensity = texelAreaDensity; - -#define VALIDATE_CHUCKS -#if defined(_DEBUG) && defined(VALIDATE_CHUCKS) - size_t indStart(pChunk->nFirstIndexId); - size_t indEnd(pChunk->nFirstIndexId + pChunk->nNumIndices); - for (size_t j(indStart); j < indEnd; ++j) - { - size_t vtxStart(pChunk->nFirstVertId); - size_t vtxEnd(pChunk->nFirstVertId + pChunk->nNumVerts); - size_t curIndex0(mesh.m_pIndices[ j ]); // absolute indexing - size_t curIndex1(mesh.m_pIndices[ j ] + vtxStart); // relative indexing using base vertex index - AZ_Assert((curIndex0 >= vtxStart && curIndex0 < vtxEnd) || (curIndex1 >= vtxStart && curIndex1 < vtxEnd), "Index is out of mesh vertices' range!"); - } -#endif - } - - ////////////////////////////////////////////////////////////////////////// - // Create RenderElements. - ////////////////////////////////////////////////////////////////////////// - int nCurChunk = 0; - for (int i = 0; i < mesh.GetSubSetCount(); i++) - { - SMeshSubset& subset = mesh.m_subsets[i]; - if (subset.nNumIndices == 0) - { - continue; - } - - if (subset.nMatFlags & MTL_FLAG_NODRAW) - { - continue; - } - - CRenderChunk* pRenderChunk = &m_Chunks[nCurChunk++]; - CREMeshImpl* pRenderElement = (CREMeshImpl*) gRenDev->EF_CreateRE(eDATA_Mesh); - - // Cross link render chunk with render element. - pRenderChunk->pRE = pRenderElement; - AssignChunk(pRenderChunk, pRenderElement); - if (subset.nNumVerts <= 500 && !mesh.m_pBoneMapping && !(flags & FSM_NO_TANGENTS)) - { - pRenderElement->mfUpdateFlags(FCEF_MERGABLE); - } - - if (mesh.m_pBoneMapping) - { - pRenderElement->mfUpdateFlags(FCEF_SKINNED); - } - } - if (mesh.m_pBoneMapping) - { - m_nFlags |= FRM_SKINNED; - } - - ////////////////////////////////////////////////////////////////////////// - // Create system vertex buffer in system memory. - ////////////////////////////////////////////////////////////////////////// -#if ENABLE_NORMALSTREAM_SUPPORT - if (flags & FSM_ENABLE_NORMALSTREAM) - { - m_nFlags |= FRM_ENABLE_NORMALSTREAM; - } -#endif - - m_nVerts = nVerts; - m_nInds = 0; - m_vertexFormat = mesh.GetMeshGroupVertexFormat(); - - pVBuff = (char*)LockVB(VSF_GENERAL, FSL_VIDEO_CREATE); - // stop initializing if allocation failed - if (pVBuff == NULL) - { - m_nVerts = 0; - goto error; - } - -# if ENABLE_NORMALSTREAM_SUPPORT - if (m_nFlags & FRM_ENABLE_NORMALSTREAM) - { - pNBuff = (SPipNormal*)LockVB(VSF_NORMALS, FSL_VIDEO_CREATE); - } -# endif - - if (!(flags & FSM_NO_TANGENTS)) - { - if (mesh.m_pQTangents) - { - pQTBuff = (SPipQTangents*)LockVB(VSF_QTANGENTS, FSL_VIDEO_CREATE); - } - else - { - pTBuff = (SPipTangents*)LockVB(VSF_TANGENTS, FSL_VIDEO_CREATE); - } - - // stop initializing if allocation failed - if (pTBuff == NULL && pQTBuff == NULL) - { - goto error; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Copy indices. - ////////////////////////////////////////////////////////////////////////// - m_nInds = nInds; - pInds = LockIB(FSL_VIDEO_CREATE); - - // stop initializing if allocation failed - if (m_nInds && pInds == NULL) - { - m_nInds = 0; - goto error; - } - - if (flags & FSM_VERTEX_VELOCITY) - { - pVelocities = (SVF_P3F*)LockVB(VSF_VERTEX_VELOCITY, FSL_VIDEO_CREATE); - - // stop initializing if allocation failed - if (pVelocities == NULL) - { - goto error; - } - } - - - // Copy data to mesh - { - SSetMeshIntData setMeshIntData = - { - &mesh, - pVBuff, - pTBuff, - pQTBuff, - pVelocities, - nVerts, - nInds, - pInds, - flags, - pNBuff - }; - SetMesh_IntImpl(setMeshIntData); - } - - - // unlock all streams - UnlockVB(VSF_GENERAL); -#if ENABLE_NORMALSTREAM_SUPPORT - if (m_nFlags & FRM_ENABLE_NORMALSTREAM) - { - UnlockVB(VSF_NORMALS); - } -# endif - UnlockIB(); - - if (!(flags & FSM_NO_TANGENTS)) - { - if (mesh.m_pQTangents) - { - UnlockVB(VSF_QTANGENTS); - } - else - { - UnlockVB(VSF_TANGENTS); - } - } - - if (flags & FSM_VERTEX_VELOCITY) - { - UnlockVB(VSF_VERTEX_VELOCITY); - } - - ////////////////////////////////////////////////////////////////////////// - // Copy skin-streams. - ////////////////////////////////////////////////////////////////////////// - if (mesh.m_pBoneMapping) - { - SetSkinningDataCharacter(mesh, mesh.m_pBoneMapping, mesh.m_pExtraBoneMapping); - } - - // Create device buffers immediately in non-multithreaded mode - if (!gRenDev->m_pRT->IsMultithreaded() && (flags & FSM_CREATE_DEVICE_MESH)) - { - CheckUpdate(VSM_MASK); - } - - UnLockForThreadAccess(); - return Size(SIZE_ONLY_SYSTEM); - -error: - UnLockForThreadAccess(); - RT_AllocationFailure("Generic Streaming Error", 0); - return ~0U; -} - -size_t CRenderMesh::SetMesh(CMesh& mesh, int nSecColorsSetOffset, uint32 flags, bool requiresLock) -{ - LOADING_TIME_PROFILE_SECTION; - - size_t resultingSize = ~0U; -# ifdef USE_VBIB_PUSH_DOWN - requiresLock = true; -# endif - if (requiresLock) - { - SREC_AUTO_LOCK(m_sResLock); - resultingSize = SetMesh_Int(mesh, nSecColorsSetOffset, flags); - } - else - { - resultingSize = SetMesh_Int(mesh, nSecColorsSetOffset, flags); - } - - return resultingSize; -} - -void CRenderMesh::SetSkinningDataVegetation(struct SMeshBoneMapping_uint8* pBoneMapping) -{ - LockForThreadAccess(); - SVF_W4B_I4S* pSkinBuff = (SVF_W4B_I4S*)LockVB(VSF_HWSKIN_INFO, FSL_VIDEO_CREATE); - - // stop initializing if allocation failed - if (pSkinBuff == NULL) - { - return; - } - - for (uint32 i = 0; i < m_nVerts; i++) - { - // get bone IDs - uint16 b0 = pBoneMapping[i].boneIds[0]; - uint16 b1 = pBoneMapping[i].boneIds[1]; - uint16 b2 = pBoneMapping[i].boneIds[2]; - uint16 b3 = pBoneMapping[i].boneIds[3]; - - // get weights - const uint8 w0 = pBoneMapping[i].weights[0]; - const uint8 w1 = pBoneMapping[i].weights[1]; - const uint8 w2 = pBoneMapping[i].weights[2]; - const uint8 w3 = pBoneMapping[i].weights[3]; - - // if weight is zero set bone ID to zero as the bone has no influence anyway, - // this will fix some issue with incorrectly exported models (e.g. system freezes on ATI cards when access invalid bones) - if (w0 == 0) - { - b0 = 0; - } - if (w1 == 0) - { - b1 = 0; - } - if (w2 == 0) - { - b2 = 0; - } - if (w3 == 0) - { - b3 = 0; - } - - pSkinBuff[i].indices[0] = b0; - pSkinBuff[i].indices[1] = b1; - pSkinBuff[i].indices[2] = b2; - pSkinBuff[i].indices[3] = b3; - - pSkinBuff[i].weights.bcolor[0] = w0; - pSkinBuff[i].weights.bcolor[1] = w1; - pSkinBuff[i].weights.bcolor[2] = w2; - pSkinBuff[i].weights.bcolor[3] = w3; - - // if (pBSStreamTemp) - // pSkinBuff[i].boneSpace = pBSStreamTemp[i]; - } - UnlockVB(VSF_HWSKIN_INFO); - UnLockForThreadAccess(); - - CreateRemappedBoneIndicesPair(~0u, m_ChunksSkinned); -} - -void CRenderMesh::SetSkinningDataCharacter([[maybe_unused]] CMesh& mesh, struct SMeshBoneMapping_uint16* pBoneMapping, [[maybe_unused]] struct SMeshBoneMapping_uint16* pExtraBoneMapping) -{ - SVF_W4B_I4S* pSkinBuff = (SVF_W4B_I4S*)LockVB(VSF_HWSKIN_INFO, FSL_VIDEO_CREATE); - - // stop initializing if allocation failed - if (pSkinBuff == NULL) - { - return; - } - - for (uint32 i = 0; i < m_nVerts; i++) - { - // get bone IDs - uint16 b0 = pBoneMapping[i].boneIds[0]; - uint16 b1 = pBoneMapping[i].boneIds[1]; - uint16 b2 = pBoneMapping[i].boneIds[2]; - uint16 b3 = pBoneMapping[i].boneIds[3]; - - // get weights - const uint8 w0 = pBoneMapping[i].weights[0]; - const uint8 w1 = pBoneMapping[i].weights[1]; - const uint8 w2 = pBoneMapping[i].weights[2]; - const uint8 w3 = pBoneMapping[i].weights[3]; - - // if weight is zero set bone ID to zero as the bone has no influence anyway, - // this will fix some issue with incorrectly exported models (e.g. system freezes on ATI cards when access invalid bones) - if (w0 == 0) - { - b0 = 0; - } - if (w1 == 0) - { - b1 = 0; - } - if (w2 == 0) - { - b2 = 0; - } - if (w3 == 0) - { - b3 = 0; - } - - pSkinBuff[i].indices[0] = b0; - pSkinBuff[i].indices[1] = b1; - pSkinBuff[i].indices[2] = b2; - pSkinBuff[i].indices[3] = b3; - - pSkinBuff[i].weights.bcolor[0] = w0; - pSkinBuff[i].weights.bcolor[1] = w1; - pSkinBuff[i].weights.bcolor[2] = w2; - pSkinBuff[i].weights.bcolor[3] = w3; - } - - UnlockVB(VSF_HWSKIN_INFO); - -#if !defined(NULL_RENDERER) - if (pExtraBoneMapping && m_extraBonesBuffer.m_numElements == 0 && m_nVerts) - { - std::vector pExtraBones; - pExtraBones.resize(m_nVerts); - for (uint32 i = 0; i < m_nVerts; i++) - { - // get bone IDs - uint16 b0 = pExtraBoneMapping[i].boneIds[0]; - uint16 b1 = pExtraBoneMapping[i].boneIds[1]; - uint16 b2 = pExtraBoneMapping[i].boneIds[2]; - uint16 b3 = pExtraBoneMapping[i].boneIds[3]; - - // get weights - const uint8 w0 = pExtraBoneMapping[i].weights[0]; - const uint8 w1 = pExtraBoneMapping[i].weights[1]; - const uint8 w2 = pExtraBoneMapping[i].weights[2]; - const uint8 w3 = pExtraBoneMapping[i].weights[3]; - - if (w0 == 0) - { - b0 = 0; - } - if (w1 == 0) - { - b1 = 0; - } - if (w2 == 0) - { - b2 = 0; - } - if (w3 == 0) - { - b3 = 0; - } - - pExtraBones[i].indices[0] = b0; - pExtraBones[i].indices[1] = b1; - pExtraBones[i].indices[2] = b2; - pExtraBones[i].indices[3] = b3; - - pExtraBones[i].weights.bcolor[0] = w0; - pExtraBones[i].weights.bcolor[1] = w1; - pExtraBones[i].weights.bcolor[2] = w2; - pExtraBones[i].weights.bcolor[3] = w3; - } - - m_extraBonesBuffer.Create(pExtraBones.size(), sizeof(SVF_W4B_I4S), DXGI_FORMAT_UNKNOWN, DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, &pExtraBones[0]); - } -#endif - - CreateRemappedBoneIndicesPair(~0u, m_Chunks); -} - -uint CRenderMesh::GetSkinningWeightCount() const -{ -#if !defined(NULL_RENDERER) - if (_HasVBStream(VSF_HWSKIN_INFO)) - { - return m_extraBonesBuffer.m_numElements > 0 ? 8 : 4; - } -#endif - - return 0; -} - -IIndexedMesh* CRenderMesh::GetIndexedMesh(IIndexedMesh* pIdxMesh) -{ - struct MeshDataLock - { - MeshDataLock(CRenderMesh* pMesh) - : _Mesh(pMesh) { _Mesh->LockForThreadAccess(); } - ~MeshDataLock() { _Mesh->UnLockForThreadAccess(); } - CRenderMesh* _Mesh; - }; - MeshDataLock _lock(this); - - if (!pIdxMesh) - { - pIdxMesh = gEnv->p3DEngine->CreateIndexedMesh(); - } - - // catch failed allocation of IndexedMesh - if (pIdxMesh == NULL) - { - return NULL; - } - - CMesh* const pMesh = pIdxMesh->GetMesh(); - - uint32 numTexCoords = m_vertexFormat.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord); - - // These functions also re-allocate the streams - pIdxMesh->SetVertexCount(m_nVerts); - pIdxMesh->SetTexCoordCount(m_nVerts, numTexCoords); - pIdxMesh->SetTangentCount(m_nVerts); - pIdxMesh->SetIndexCount(m_nInds); - pIdxMesh->SetSubSetCount(m_Chunks.size()); - - strided_pointer pVtx; - strided_pointer pTangs; - pVtx.data = (Vec3*)GetPosPtr(pVtx.iStride, FSL_READ); - - bool texCoordAllocationSucceeded = true; - AZStd::vector> stridedTexCoordPointers; - stridedTexCoordPointers.resize(numTexCoords); - for (int streamIndex = 0; streamIndex < stridedTexCoordPointers.size(); ++streamIndex) - { - stridedTexCoordPointers[streamIndex].data = (Vec2*)GetUVPtr(stridedTexCoordPointers[streamIndex].iStride, FSL_READ, streamIndex); - if (stridedTexCoordPointers[streamIndex].data == nullptr || !pMesh->GetStreamPtr(CMesh::TEXCOORDS, streamIndex)) - { - texCoordAllocationSucceeded = false; - break; - } - } - pTangs.data = (SPipTangents*)GetTangentPtr(pTangs.iStride, FSL_READ); - - // don't copy if some src, or dest buffer is NULL (can happen because of failed allocations) - if (pVtx.data == NULL || (pMesh->m_pPositions == NULL && pMesh->m_pPositionsF16 == NULL) || - !texCoordAllocationSucceeded || - pTangs.data == NULL || pMesh->m_pTangents == NULL) - { - UnlockStream(VSF_GENERAL); - delete pIdxMesh; - return NULL; - } - - - for (uint32 i = 0; i < m_nVerts; i++) - { - pMesh->m_pPositions[i] = pVtx[i]; - pMesh->m_pNorms [i] = SMeshNormal(Vec3(0, 0, 1));//pNorm[i]; - pMesh->m_pTangents [i] = SMeshTangents(pTangs[i]); - } - - for (int streamIndex = 0; streamIndex < stridedTexCoordPointers.size(); ++streamIndex) - { - SMeshTexCoord* meshTextureCoordinates = pMesh->GetStreamPtr(CMesh::TEXCOORDS, streamIndex); - for (uint32 i = 0; i < m_nVerts; ++i) - { - meshTextureCoordinates[i] = SMeshTexCoord(stridedTexCoordPointers[streamIndex][i]); - } - } - - uint offset = 0; - if (m_vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::Color)) - { - strided_pointer pColors; - pColors.data = (SMeshColor*)GetColorPtr(pColors.iStride, FSL_READ); - pIdxMesh->SetColorCount(m_nVerts); - SMeshColor* colorStream = pMesh->GetStreamPtr(CMesh::COLORS); - for (int i = 0; i < (int)m_nVerts; i++) - { - colorStream[i] = pColors[i]; - } - } - UnlockStream(VSF_GENERAL); - - vtx_idx* pInds = GetIndexPtr(FSL_READ); - for (int i = 0; i < (int)m_nInds; i++) - { - pMesh->m_pIndices[i] = pInds[i]; - } - UnlockIndexStream(); - - SVF_W4B_I4S* pSkinBuff = (SVF_W4B_I4S*)LockVB(VSF_HWSKIN_INFO, FSL_READ); - if (pSkinBuff) - { - pIdxMesh->AllocateBoneMapping(); - for (int i = 0; i < (int)m_nVerts; i++) - { - for (int j = 0; j < 4; j++) - { - pMesh->m_pBoneMapping[i].boneIds[j] = pSkinBuff[i].indices[j]; - pMesh->m_pBoneMapping[i].weights[j] = pSkinBuff[i].weights.bcolor[j]; - } - } - UnlockVB(VSF_HWSKIN_INFO); - } - - for (int i = 0; i < (int)m_Chunks.size(); i++) - { - pIdxMesh->SetSubsetIndexVertexRanges(i, m_Chunks[i].nFirstIndexId, m_Chunks[i].nNumIndices, m_Chunks[i].nFirstVertId, m_Chunks[i].nNumVerts); - pIdxMesh->SetSubsetMaterialId(i, m_Chunks[i].m_nMatID); - const int nMatFlags = m_Chunks[i].m_nMatFlags; - const int nPhysicalizeType = (nMatFlags & MTL_FLAG_NOPHYSICALIZE) - ? PHYS_GEOM_TYPE_NONE - : ((nMatFlags & MTL_FLAG_NODRAW) ? PHYS_GEOM_TYPE_OBSTRUCT : PHYS_GEOM_TYPE_DEFAULT); - pIdxMesh->SetSubsetMaterialProperties(i, nMatFlags, nPhysicalizeType, m_Chunks[i].m_vertexFormat); - - const SMeshSubset& mss = pIdxMesh->GetSubSet(i); - Vec3 vCenter; - vCenter.zero(); - for (uint32 j = mss.nFirstIndexId; j < mss.nFirstIndexId + mss.nNumIndices; j++) - { - vCenter += pMesh->m_pPositions[pMesh->m_pIndices[j]]; - } - if (mss.nNumIndices) - { - vCenter /= (float)mss.nNumIndices; - } - float fRadius = 0; - for (uint32 j = mss.nFirstIndexId; j < mss.nFirstIndexId + mss.nNumIndices; j++) - { - fRadius = max(fRadius, (pMesh->m_pPositions[pMesh->m_pIndices[j]] - vCenter).len2()); - } - fRadius = sqrt_tpl(fRadius); - pIdxMesh->SetSubsetBounds(i, vCenter, fRadius); - } - - return pIdxMesh; -} - -void CRenderMesh::GenerateQTangents() -{ - // FIXME: This needs to be cleaned up. Breakable foliage shouldn't need both streams, and this shouldn't be duplicated - // between here and CryAnimation. - LockForThreadAccess(); - int srcStride = 0; - void* pSrcD = LockVB(VSF_TANGENTS, FSL_READ, 0, &srcStride); - if (pSrcD) - { - int dstStride = 0; - void* pDstD = LockVB(VSF_QTANGENTS, FSL_VIDEO_CREATE, 0, &dstStride); - assert(pDstD); - if (pDstD) - { - SPipTangents* pTangents = (SPipTangents*)pSrcD; - SPipQTangents* pQTangents = (SPipQTangents*)pDstD; - MeshTangentsFrameToQTangents( - pTangents, srcStride, m_nVerts, - pQTangents, dstStride); - } - UnlockVB(VSF_QTANGENTS); - } - UnlockVB(VSF_TANGENTS); - UnLockForThreadAccess(); -} - -void CRenderMesh::CreateChunksSkinned() -{ - ReleaseRenderChunks(&m_ChunksSkinned); - - TRenderChunkArray& arrSrcMats = m_Chunks; - TRenderChunkArray& arrNewMats = m_ChunksSkinned; - arrNewMats.resize (arrSrcMats.size()); - for (int i = 0; i < arrSrcMats.size(); ++i) - { - CRenderChunk& rSrcMat = arrSrcMats[i]; - CRenderChunk& rNewMat = arrNewMats[i]; - rNewMat = rSrcMat; - CREMeshImpl* re = (CREMeshImpl*) rSrcMat.pRE; - if (re) - { - rNewMat.pRE = (CREMeshImpl*) gRenDev->EF_CreateRE(eDATA_Mesh); - CRendElement* pNext = rNewMat.pRE->m_NextGlobal; - CRendElement* pPrev = rNewMat.pRE->m_PrevGlobal; - *(CREMeshImpl*)rNewMat.pRE = *re; - if (rNewMat.pRE->m_pChunk) // affects the source mesh!! will only work correctly if the source is deleted after copying - { - rNewMat.pRE->m_pChunk = &rNewMat; - } - rNewMat.pRE->m_NextGlobal = pNext; - rNewMat.pRE->m_PrevGlobal = pPrev; - rNewMat.pRE->m_pRenderMesh = this; - rNewMat.pRE->m_CustomData = NULL; - } - } -} - -int CRenderMesh::GetRenderChunksCount(_smart_ptr pMaterial, int& nRenderTrisCount) -{ - int nCount = 0; - nRenderTrisCount = 0; - - const uint32 ni = (uint32)m_Chunks.size(); - for (uint32 i = 0; i < ni; i++) - { - CRenderChunk* pChunk = &m_Chunks[i]; - CRendElementBase* pREMesh = pChunk->pRE; - - SShaderItem* pShaderItem = &pMaterial->GetShaderItem(pChunk->m_nMatID); - - CShaderResources* pR = (CShaderResources*)pShaderItem->m_pShaderResources; - CShader* pS = (CShader*)pShaderItem->m_pShader; - if (pREMesh && pS && pR) - { - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW) - { - continue; - } - - if (pS->m_Flags2 & EF2_NODRAW) - { - continue; - } - - if (pChunk->nNumIndices) - { - nRenderTrisCount += pChunk->nNumIndices / 3; - nCount++; - } - } - } - - return nCount; -} - -void CRenderMesh::CopyTo(IRenderMesh* _pDst, int nAppendVtx, [[maybe_unused]] bool bDynamic, bool fullCopy) -{ - CRenderMesh* pDst = (CRenderMesh*)_pDst; -#ifdef USE_VBIB_PUSH_DOWN - SREC_AUTO_LOCK(m_sResLock); -#endif - TRenderChunkArray& arrSrcMats = m_Chunks; - TRenderChunkArray& arrNewMats = pDst->m_Chunks; - //pDst->m_bMaterialsWasCreatedInRenderer = true; - arrNewMats.resize (arrSrcMats.size()); - int i; - for (i = 0; i < arrSrcMats.size(); ++i) - { - CRenderChunk& rSrcMat = arrSrcMats[i]; - CRenderChunk& rNewMat = arrNewMats[i]; - rNewMat = rSrcMat; - rNewMat.nNumVerts += ((m_nVerts - 2 - rNewMat.nNumVerts - rNewMat.nFirstVertId) >> 31) & nAppendVtx; - CREMeshImpl* re = (CREMeshImpl*) rSrcMat.pRE; - if (re) - { - AZ_Assert(!re->m_CustomData, "Trying to copy a render mesh after custom data has been set."); // Custom data cannot be copied over (used by Terrain and Decals) - rNewMat.pRE = (CREMeshImpl*) gRenDev->EF_CreateRE(eDATA_Mesh); - CRendElement* pNext = rNewMat.pRE->m_NextGlobal; - CRendElement* pPrev = rNewMat.pRE->m_PrevGlobal; - *(CREMeshImpl*)rNewMat.pRE = *re; - if (rNewMat.pRE->m_pChunk) // affects the source mesh!! will only work correctly if the source is deleted after copying - { - rNewMat.pRE->m_pChunk = &rNewMat; - rNewMat.pRE->m_pChunk->nNumVerts += ((m_nVerts - 2 - re->m_pChunk->nNumVerts - re->m_pChunk->nFirstVertId) >> 31) & nAppendVtx; - } - rNewMat.pRE->m_NextGlobal = pNext; - rNewMat.pRE->m_PrevGlobal = pPrev; - rNewMat.pRE->m_pRenderMesh = pDst; - rNewMat.pRE->m_CustomData = NULL; - } - } - LockForThreadAccess(); - pDst->LockForThreadAccess(); - pDst->m_nVerts = m_nVerts + nAppendVtx; - if (fullCopy) - { - pDst->m_vertexFormat = m_vertexFormat; - for (i = 0; i < VSF_NUM; i++) - { - void* pSrcD = LockVB(i, FSL_READ); - if (pSrcD) - { - void* pDstD = pDst->LockVB(i, FSL_VIDEO_CREATE); - assert(pDstD); - if (pDstD) - { - cryMemcpy(pDstD, pSrcD, GetStreamSize(i), MC_CPU_TO_GPU); - } - pDst->UnlockVB(i); - } - UnlockVB(i); - } - - pDst->m_nInds = m_nInds; - void* pSrcD = LockIB(FSL_READ); - if (pSrcD) - { - void* pDstD = pDst->LockIB(FSL_VIDEO_CREATE); - assert(pDstD); - if (pDstD) - { - cryMemcpy(pDstD, pSrcD, m_nInds * sizeof(vtx_idx), MC_CPU_TO_GPU); - } - pDst->UnlockIB(); - } - - pDst->m_eType = m_eType; - pDst->m_nFlags = m_nFlags; - } - UnlockIB(); - UnLockForThreadAccess(); - pDst->UnLockForThreadAccess(); -} - -// set effector for all chunks -void CRenderMesh::SetCustomTexID(int nCustomTID) -{ - if (m_Chunks.size()) - { - for (int i = 0; i < m_Chunks.size(); i++) - { - CRenderChunk* pChunk = &m_Chunks[i]; - if (pChunk->pRE) - { - pChunk->pRE->m_CustomTexBind[0] = nCustomTID; - } - } - } -} - -void CRenderMesh::SetChunk(int nIndex, CRenderChunk& inChunk) -{ - if (!inChunk.nNumIndices || !inChunk.nNumVerts || m_nInds == 0) - { - return; - } - - CRenderChunk* pRenderChunk = NULL; - - if (nIndex < 0 || nIndex >= m_Chunks.size()) - { - // add new chunk - CRenderChunk matinfo; - m_Chunks.push_back(matinfo); - pRenderChunk = &m_Chunks.back(); - - pRenderChunk->pRE = (CREMeshImpl*) gRenDev->EF_CreateRE(eDATA_Mesh); - pRenderChunk->pRE->m_CustomTexBind[0] = m_nClientTextureBindID; - } - else - { - // use present chunk - pRenderChunk = &m_Chunks[nIndex]; - } - - pRenderChunk->m_nMatID = inChunk.m_nMatID; - pRenderChunk->m_nMatFlags = inChunk.m_nMatFlags; - - pRenderChunk->nFirstIndexId = inChunk.nFirstIndexId; - pRenderChunk->nNumIndices = MAX(inChunk.nNumIndices, 0); - pRenderChunk->nFirstVertId = inChunk.nFirstVertId; - pRenderChunk->nNumVerts = MAX(inChunk.nNumVerts, 0); - pRenderChunk->nSubObjectIndex = inChunk.nSubObjectIndex; - - pRenderChunk->m_texelAreaDensity = inChunk.m_texelAreaDensity; - - pRenderChunk->m_vertexFormat = inChunk.m_vertexFormat; - - // update chunk RE - if (pRenderChunk->pRE) - { - AssignChunk(pRenderChunk, (CREMeshImpl*) pRenderChunk->pRE); - } - CRY_ASSERT(!pRenderChunk->pRE || pRenderChunk->pRE->m_pChunk->nFirstIndexId < 60000); // TODO: do we need to compare with 60000 if vertex indices are 32-bit? - CRY_ASSERT(pRenderChunk->nFirstIndexId + pRenderChunk->nNumIndices <= m_nInds); -} - -void CRenderMesh::SetChunk(_smart_ptr pNewMat, int nFirstVertId, int nVertCount, int nFirstIndexId, int nIndexCount, float texelAreaDensity, const AZ::Vertex::Format& vertexFormat, int nIndex) -{ - CRenderChunk chunk; - - if (pNewMat) - { - chunk.m_nMatFlags = pNewMat->GetFlags(); - } - - if (nIndex < 0 || nIndex >= m_Chunks.size()) - { - chunk.m_nMatID = m_Chunks.size(); - } - else - { - chunk.m_nMatID = nIndex; - } - - chunk.nFirstVertId = nFirstVertId; - chunk.nNumVerts = nVertCount; - - chunk.nFirstIndexId = nFirstIndexId; - chunk.nNumIndices = nIndexCount; - - chunk.m_texelAreaDensity = texelAreaDensity; - chunk.m_vertexFormat = vertexFormat; - SetChunk(nIndex, chunk); -} - -//================================================================================================================ - -bool CRenderMesh::PrepareCachePos() -{ - if (!m_pCachePos && m_vertexFormat.Has16BitFloatPosition()) - { - m_pCachePos = AllocateMeshData(m_nVerts); - if (m_pCachePos) - { - m_nFrameRequestCachePos = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - return true; - } - } - return false; -} - -bool CRenderMesh::CreateCachePos(byte* pSrc, uint32 nStrideSrc, uint nFlags) -{ - PROFILE_FRAME(Mesh_CreateCachePos); - if (m_vertexFormat.Has16BitFloatPosition()) - { - #ifdef USE_VBIB_PUSH_DOWN - SREC_AUTO_LOCK(m_sResLock);//on USE_VBIB_PUSH_DOWN tick is executed in renderthread - #endif - m_nFlagsCachePos = (nFlags & FSL_WRITE) != 0; - m_nFrameRequestCachePos = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - if ((nFlags & FSL_READ) && m_pCachePos) - { - return true; - } - if ((nFlags == FSL_SYSTEM_CREATE) && m_pCachePos) - { - return true; - } - if (!m_pCachePos) - { - m_pCachePos = AllocateMeshData(m_nVerts); - } - if (m_pCachePos) - { - if (nFlags == FSL_SYSTEM_UPDATE || (nFlags & FSL_READ)) - { - for (uint32 i = 0; i < m_nVerts; i++) - { - Vec3f16* pVSrc = (Vec3f16*)pSrc; - m_pCachePos[i] = pVSrc->ToVec3(); - pSrc += nStrideSrc; - } - } - return true; - } - } - return false; -} - -bool CRenderMesh::CreateUVCache(byte* source, uint32 sourceStride, uint flags, uint32 uvSetIndex) -{ - PROFILE_FRAME(Mesh_CreateUVCache); - - AZ::Vertex::AttributeType attributeType = AZ::Vertex::AttributeType::NumTypes; - uint offset = 0; - bool hasUVSetAtIndex = m_vertexFormat.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::TexCoord, uvSetIndex, offset, attributeType); - - // If the vertex format has a uv set at the given index - // And the vertex format uses 16 bit floats to represent that uv set - if (hasUVSetAtIndex && (attributeType == AZ::Vertex::AttributeType::Float16_2)) - { - m_nFlagsCacheUVs = (flags & FSL_WRITE) != 0; - m_nFrameRequestCacheUVs = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID; - // Increase the size of the cached uvs vector if it is not big enough for the given uv set, and fill any new slots with nullptr - if (uvSetIndex >= m_UVCache.size()) - { - m_UVCache.resize(uvSetIndex + 1, nullptr); - } - - // Return true if the uv cache has already been created and does not need to be updated - if ((flags & FSL_READ) && m_UVCache[uvSetIndex]) - { - return true; - } - if ((flags == FSL_SYSTEM_CREATE) && m_UVCache[uvSetIndex]) - { - return true; - } - - // If the cache doesn't exist yet, allocate memory for it - if (!m_UVCache[uvSetIndex]) - { - m_UVCache[uvSetIndex] = AllocateMeshData(m_nVerts); - } - - if (m_UVCache[uvSetIndex]) - { - // If the new or existing cache needs to be updated, fill it with the source data - if (flags == FSL_SYSTEM_UPDATE || (flags & FSL_READ)) - { - source += offset; - - for (uint32 i = 0; i < m_nVerts; i++) - { - Vec2f16* pVSrc = (Vec2f16*)source; - m_UVCache[uvSetIndex][i] = pVSrc->ToVec2(); - source += sourceStride; - } - } - return true; - } - } - return false; -} - -byte* CRenderMesh::GetPosPtrNoCache(int32& nStride, uint32 nFlags) -{ - int nStr = 0; - byte* pData = NULL; - pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr, true); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - return pData; -} - -byte* CRenderMesh::GetPosPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetPosPtr); - int nStr = 0; - byte* pData = NULL; - pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr, true, true); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - - if (!CreateCachePos(pData, nStr, nFlags)) - { - nStride = nStr; - return pData; - } - - pData = (byte*)m_pCachePos; - nStride = sizeof(Vec3); - return pData; -} - -vtx_idx* CRenderMesh::GetIndexPtr(uint32 nFlags, int32 nOffset) -{ - vtx_idx* pData = LockIB(nFlags, nOffset, 0); - assert((m_nInds == 0) || pData); - return pData; -} - -byte* CRenderMesh::GetColorPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetColorPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - uint colorOffset = 0; - if (_GetVertexFormat().TryCalculateOffset(colorOffset, AZ::Vertex::AttributeUsage::Color)) - { - return &pData[colorOffset]; - } - return NULL; -} -byte* CRenderMesh::GetNormPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetNormPtr); - int nStr = 0; - byte* pData = 0; -# if ENABLE_NORMALSTREAM_SUPPORT - pData = (byte*)LockVB(VSF_NORMALS, nFlags, 0, &nStr); - if (pData) - { - nStride = sizeof(Vec3); - return pData; - } -# endif - pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - uint normalOffset = 0; - if (_GetVertexFormat().TryCalculateOffset(normalOffset, AZ::Vertex::AttributeUsage::Normal)) - { - return &pData[normalOffset]; - } - return NULL; -} -byte* CRenderMesh::GetUVPtrNoCache(int32& nStride, uint32 nFlags, uint32 uvSetIndex) -{ - PROFILE_FRAME(Mesh_GetUVPtrNoCache); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - uint texCoordOffset = 0; - if (_GetVertexFormat().TryCalculateOffset(texCoordOffset, AZ::Vertex::AttributeUsage::TexCoord, uvSetIndex)) - { - return &pData[texCoordOffset]; - } - return NULL; -} -byte* CRenderMesh::GetUVPtr(int32& nStride, uint32 nFlags, uint32 uvSetIndex) -{ - PROFILE_FRAME(Mesh_GetUVPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_GENERAL, nFlags, 0, &nStr); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - - bool result; - { - SREC_AUTO_LOCK(m_sResLock); - result = CreateUVCache(pData, nStr, nFlags, uvSetIndex); - } - - if (!result) - { - nStride = nStr; - uint texCoordOffset = 0; - if (_GetVertexFormat().TryCalculateOffset(texCoordOffset, AZ::Vertex::AttributeUsage::TexCoord, uvSetIndex)) - { - return &pData[texCoordOffset]; - } - } - else - { - pData = (byte*)m_UVCache[uvSetIndex]; - nStride = sizeof(Vec2); - return pData; - } - - return NULL; -} - -byte* CRenderMesh::GetTangentPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetTangentPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_TANGENTS, nFlags, 0, &nStr); - //ASSERT_LOCK; - if (!pData) - { - pData = (byte*)LockVB(VSF_QTANGENTS, nFlags, 0, &nStr); - } - if (!pData) - { - return NULL; - } - nStride = nStr; - return pData; -} -byte* CRenderMesh::GetQTangentPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetQTangentPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_QTANGENTS, nFlags, 0, &nStr); - //ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - return pData; -} - -byte* CRenderMesh::GetHWSkinPtr(int32& nStride, uint32 nFlags, [[maybe_unused]] bool remapped) -{ - PROFILE_FRAME(Mesh_GetHWSkinPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_HWSKIN_INFO, nFlags, 0, &nStr); - if (!pData) - { - return NULL; - } - nStride = nStr; - return pData; -} - -byte* CRenderMesh::GetVelocityPtr(int32& nStride, uint32 nFlags) -{ - PROFILE_FRAME(Mesh_GetMorphTargetPtr); - int nStr = 0; - byte* pData = (byte*)LockVB(VSF_VERTEX_VELOCITY, nFlags, 0, &nStr); - ASSERT_LOCK; - if (!pData) - { - return NULL; - } - nStride = nStr; - return pData; -} - -bool CRenderMesh::IsEmpty() -{ - ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT) - SMeshStream * pMS = GetVertexStream(VSF_GENERAL, 0); - return (!m_nVerts || (!pMS || pMS->m_nID == ~0u || !pMS->m_pUpdateData) || (!_HasIBStream() && !m_IBStream.m_pUpdateData)); -} - -//================================================================================================================ - -bool CRenderMesh::CheckUpdate(uint32 nStreamMask) -{ - CRenderMesh* pRM = _GetVertexContainer(); - if (pRM) - { - return gRenDev->m_pRT->RC_CheckUpdate2(this, pRM, nStreamMask); - } - return false; -} - -void CRenderMesh::RT_AllocationFailure([[maybe_unused]] const char* sPurpose, [[maybe_unused]] uint32 nSize) -{ - SREC_AUTO_LOCK(m_sResLock); - Cleanup(); - m_nVerts = 0; - m_nInds = 0; - m_nFlags |= FRM_ALLOCFAILURE; -# if !defined(_RELEASE) && !defined(NULL_RENDERER) - CryLogAlways("rendermesh '%s(%s)' suffered from a buffer allocation failure for \"%s\" size %d bytes on thread 0x%" PRI_THREADID, m_sSource.c_str(), m_sType.c_str(), sPurpose, nSize, CryGetCurrentThreadId()); -# endif -} - - -#ifdef MESH_TESSELLATION_RENDERER -namespace -{ - template - class SAdjVertCompare - { - public: - SAdjVertCompare(const AZ::Vertex::Format& vertexFormat) - : m_vertexFormat(vertexFormat) - {} - inline bool operator()(const int i1, const int i2) const - { - uint stride = m_vertexFormat.GetStride(); - uint offset = 0; - m_vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::Position); - const VecPos* pVert1 = (const VecPos*)&m_pVerts[i1 * stride + offset]; - const VecPos* pVert2 = (const VecPos*)&m_pVerts[i2 * stride + offset]; - if (pVert1->x < pVert2->x) - { - return true; - } - if (pVert1->x > pVert2->x) - { - return false; - } - if (pVert1->y < pVert2->y) - { - return true; - } - if (pVert1->y > pVert2->y) - { - return false; - } - return pVert1->z < pVert2->z; - } - const byte* m_pVerts; - AZ::Vertex::Format m_vertexFormat; - }; -} - -template -void CRenderMesh::BuildAdjacency(const byte* pVerts, const AZ::Vertex::Format& vertexFormat, unsigned int nVerts, const vtx_idx* pIndexBuffer, uint nTrgs, std::vector& pTxtAdjBuffer) -{ - SAdjVertCompare compare(vertexFormat); - compare.m_pVerts = pVerts; - - // this array will contain indices of vertices sorted by float3 position - so that we could find vertices with equal positions (they have to be adjacent in the array) - std::vector arrSortedVertIDs; - // we allocate a bit more (by one) because we will need extra element for scan operation (lower) - arrSortedVertIDs.resize(nVerts + 1); - for (int iv = 0; iv < nVerts; ++iv) - { - arrSortedVertIDs[iv] = iv; - } - - std::sort(arrSortedVertIDs.begin(), arrSortedVertIDs.end() - 1, compare); - - // Get vertex stride, offset, and bytelength for position and texture coordinates - uint stride = vertexFormat.GetStride(); - uint positionOffset = 0; - vertexFormat.TryCalculateOffset(positionOffset, AZ::Vertex::AttributeUsage::Position); - uint texCoordOffset = 0; - vertexFormat.TryCalculateOffset(texCoordOffset, AZ::Vertex::AttributeUsage::TexCoord); - uint texCoordByteLength = vertexFormat.GetAttributeByteLength(AZ::Vertex::AttributeUsage::TexCoord); - - // compute how many unique vertices are there, also setup links from each vertex to master vertex - std::vector arrLinkToMaster; - arrLinkToMaster.resize(nVerts); - int nUniqueVertices = 0; - for (int iv0 = 0; iv0 < nVerts; ) - { - int iMaster = arrSortedVertIDs[iv0]; - arrLinkToMaster[iMaster] = iMaster; - int iv1 = iv0 + 1; - for (; iv1 < nVerts; ++iv1) - { - // if slave vertex != master vertex - if (*(VecPos*)&pVerts[arrSortedVertIDs[iv1] * stride + positionOffset] != *(VecPos*)&pVerts[iMaster * stride + positionOffset]) - { - break; - } - arrLinkToMaster[arrSortedVertIDs[iv1]] = iMaster; - } - iv0 = iv1; - ++nUniqueVertices; - } - if (nUniqueVertices == nVerts) - { // no need to recode anything - the mesh is perfect - return; - } - // compute how many triangles connect to every master vertex - std::vector& arrConnectedTrianglesCount = arrSortedVertIDs; - for (int i = 0; i < arrConnectedTrianglesCount.size(); ++i) - { - arrConnectedTrianglesCount[i] = 0; - } - for (int it = 0; it < nTrgs; ++it) - { - const vtx_idx* pTrg = &pIndexBuffer[it * 3]; - int iMasterVertex0 = arrLinkToMaster[pTrg[0]]; - int iMasterVertex1 = arrLinkToMaster[pTrg[1]]; - int iMasterVertex2 = arrLinkToMaster[pTrg[2]]; - if (iMasterVertex0 == iMasterVertex1 || iMasterVertex0 == iMasterVertex2 || iMasterVertex1 == iMasterVertex2) - { - continue; // degenerate triangle - skip it - } - ++arrConnectedTrianglesCount[iMasterVertex0]; - ++arrConnectedTrianglesCount[iMasterVertex1]; - ++arrConnectedTrianglesCount[iMasterVertex2]; - } - // scan - std::vector& arrFirstConnectedTriangle = arrSortedVertIDs; - for (int iv = 0; iv < nVerts; ++iv) - { - arrFirstConnectedTriangle[iv + 1] += arrFirstConnectedTriangle[iv]; - } - { - int iTmp = arrFirstConnectedTriangle[0]; - arrFirstConnectedTriangle[0] = 0; - for (int iv = 0; iv < nVerts; ++iv) - { - int iTmp1 = arrFirstConnectedTriangle[iv + 1]; - arrFirstConnectedTriangle[iv + 1] = iTmp; - iTmp = iTmp1; - } - } - // create a list of triangles for each master vertex - std::vector arrConnectedTriangles; - arrConnectedTriangles.resize(arrFirstConnectedTriangle[nVerts]); - for (int it = 0; it < nTrgs; ++it) - { - const vtx_idx* pTrg = &pIndexBuffer[it * 3]; - int iMasterVertex0 = arrLinkToMaster[pTrg[0]]; - int iMasterVertex1 = arrLinkToMaster[pTrg[1]]; - int iMasterVertex2 = arrLinkToMaster[pTrg[2]]; - if (iMasterVertex0 == iMasterVertex1 || iMasterVertex0 == iMasterVertex2 || iMasterVertex1 == iMasterVertex2) - { - continue; // degenerate triangle - skip it - } - arrConnectedTriangles[arrFirstConnectedTriangle[iMasterVertex0]++] = it; - arrConnectedTriangles[arrFirstConnectedTriangle[iMasterVertex1]++] = it; - arrConnectedTriangles[arrFirstConnectedTriangle[iMasterVertex2]++] = it; - } - // return scan array to initial state - { - int iTmp = arrFirstConnectedTriangle[0]; - arrFirstConnectedTriangle[0] = 0; - for (int iv = 0; iv < nVerts; ++iv) - { - int iTmp1 = arrFirstConnectedTriangle[iv + 1]; - arrFirstConnectedTriangle[iv + 1] = iTmp; - iTmp = iTmp1; - } - } - // find matches for boundary edges - for (int it = 0; it < nTrgs; ++it) - { - const vtx_idx* pTrg = &pIndexBuffer[it * 3]; - for (int ie = 0; ie < 3; ++ie) - { - // fix the corner here - { - int ivCorner = pTrg[ie]; - memcpy(&pTxtAdjBuffer[it * 12 + 9 + ie], &pVerts[arrLinkToMaster[ivCorner] * stride + texCoordOffset], texCoordByteLength); - } - // proceed with fixing the edges - int iv0 = pTrg[ie]; - int iMasterVertex0 = arrLinkToMaster[iv0]; - - int iv1 = pTrg[(ie + 1) % 3]; - int iMasterVertex1 = arrLinkToMaster[iv1]; - if (iMasterVertex0 == iMasterVertex1) - { // some degenerate case - skip it - continue; - } - // find a triangle that has both iMasterVertex0 and iMasterVertex1 - for (int i0 = arrFirstConnectedTriangle[iMasterVertex0]; i0 < arrFirstConnectedTriangle[iMasterVertex0 + 1]; ++i0) - { - int iOtherTriangle = arrConnectedTriangles[i0]; - if (iOtherTriangle >= it) // we are going to stick to this other triangle only if it's index is less than ours - { - continue; - } - const vtx_idx* pOtherTrg = &pIndexBuffer[iOtherTriangle * 3]; - int iRecode0 = -1; - int iRecode1 = -1; - // setup recode indices - for (int ieOther = 0; ieOther < 3; ++ieOther) - { - if (arrLinkToMaster[pOtherTrg[ieOther]] == iMasterVertex0) - { - iRecode0 = pOtherTrg[ieOther]; - } - else if (arrLinkToMaster[pOtherTrg[ieOther]] == iMasterVertex1) - { - iRecode1 = pOtherTrg[ieOther]; - } - } - if (iRecode0 != -1 && iRecode1 != -1) - { // this triangle is our neighbor - memcpy(&pTxtAdjBuffer[it * 12 + 3 + ie * 2], &pVerts[iRecode0 * stride + texCoordOffset], texCoordByteLength); - memcpy(&pTxtAdjBuffer[it * 12 + 3 + ie * 2 + 1], &pVerts[iRecode1 * stride + texCoordOffset], texCoordByteLength); - } - } - } - } -} -#endif //#ifdef MESH_TESSELLATION_RENDERER - -bool CRenderMesh::RT_CheckUpdate(CRenderMesh* pVContainer, uint32 nStreamMask, [[maybe_unused]] bool bTessellation, bool stall) -{ - PrefetchLine(&m_IBStream, 0); - - CRenderer* rd = gRenDev; - int nThreadID = rd->m_RP.m_nProcessThreadID; - int nFrame = rd->m_RP.m_TI[nThreadID].m_nFrameUpdateID; - bool bSkinned = (m_nFlags & (FRM_SKINNED | FRM_SKINNEDNEXTDRAW)) != 0; - - if (nStreamMask & 0x80000000) // Disable skinning in instancing mode - { - bSkinned = false; - } - - m_nFlags &= ~FRM_SKINNEDNEXTDRAW; - - IF (!CanRender(), 0) - { - return false; - } - - FUNCTION_PROFILER_RENDER_FLAT - AZ_TRACE_METHOD(); - PrefetchVertexStreams(); - - PrefetchLine(pVContainer->m_VBStream, 0); - SMeshStream* pMS = pVContainer->GetVertexStream(VSF_GENERAL, 0); - - if ((m_pVertexContainer || m_nVerts > 2) && pMS) - { - PrefetchLine(pVContainer->m_VBStream, 128); - if (pMS->m_pUpdateData && pMS->m_nFrameAccess != nFrame) - { - pMS->m_nFrameAccess = nFrame; - if (pMS->m_nFrameRequest > pMS->m_nFrameUpdate) - { - { - PROFILE_FRAME(Mesh_CheckUpdateUpdateGBuf); - if (!(pMS->m_nLockFlags & FSL_WRITE)) - { - if (!pVContainer->UpdateVidVertices(VSF_GENERAL, stall)) - { - RT_AllocationFailure("Update General Stream", GetStreamSize(VSF_GENERAL, m_nVerts)); - return false; - } - pMS->m_nFrameUpdate = nFrame; - } - else - { - if (pMS->m_nID == ~0u) - { - return false; - } - } - } - } - } - // Set both tangent flags - if (nStreamMask & VSM_TANGENTS) - { - nStreamMask |= VSM_TANGENTS; - } - - // Additional streams updating - if (nStreamMask & VSM_MASK) - { - int i; - uint32 iMask = 1; - - for (i = 1; i < VSF_NUM; i++) - { - iMask = iMask << 1; - - pMS = pVContainer->GetVertexStream(i, 0); - if ((nStreamMask & iMask) && pMS) - { - if (pMS->m_pUpdateData && pMS->m_nFrameAccess != nFrame) - { - pMS->m_nFrameAccess = nFrame; - if (pMS->m_nFrameRequest > pMS->m_nFrameUpdate) - { - // Update the device buffer - PROFILE_FRAME(Mesh_CheckUpdateUpdateGBuf); - if (!(pMS->m_nLockFlags & FSL_WRITE)) - { - if (!pVContainer->UpdateVidVertices(i, stall)) - { - RT_AllocationFailure("Update VB Stream", GetStreamSize(i, m_nVerts)); - return false; - } - if (i == VSF_HWSKIN_INFO && pVContainer->m_RemappedBoneIndices.size() == 1) - { - // Just locking the VB stream doesn't store any information about the GUID so - // if the HWSKIN_INFO has been locked and we only have one set of remapped bone - // indices we will assume they are the same set. This is a valid assumption in non - // legacy code, as we will only have the one set loaded from the asset. - if (!gRenDev->m_DevBufMan.UpdateBuffer(pVContainer->m_RemappedBoneIndices[0].buffer, - pMS->m_pUpdateData, - pVContainer->GetVerticesCount() * pVContainer->GetStreamStride(VSF_HWSKIN_INFO))) - { - RT_AllocationFailure("Update VB Stream", GetStreamSize(i, m_nVerts)); - return false; - } - } - pMS->m_nFrameUpdate = nFrame; - } - else - if (i != VSF_HWSKIN_INFO) - { - if (pMS->m_nID == ~0u) - { - return false; - } - } - } - } - } - } - } - }//if (m_pVertexContainer || m_nVerts > 2) - - m_IBStream.m_nFrameAccess = nFrame; - const bool bIndUpdateNeeded = (m_IBStream.m_pUpdateData != NULL) && (m_IBStream.m_nFrameRequest > m_IBStream.m_nFrameUpdate); - if (bIndUpdateNeeded) - { - PROFILE_FRAME(Mesh_CheckUpdate_UpdateInds); - if (!(pVContainer->m_IBStream.m_nLockFlags & FSL_WRITE)) - { - if (!UpdateVidIndices(m_IBStream, stall)) - { - RT_AllocationFailure("Update IB Stream", m_nInds * sizeof(vtx_idx)); - return false; - } - m_IBStream.m_nFrameUpdate = nFrame; - } - else if (pVContainer->m_IBStream.m_nID == ~0u) - { - return false; - } - } - -#ifdef MESH_TESSELLATION_RENDERER - // Build UV adjacency - if ((bTessellation && m_adjBuffer.m_numElements == 0) // if needed and not built already - || (bIndUpdateNeeded && m_adjBuffer.m_numElements > 0)) // if already built but needs update - { - if (!(pVContainer->m_IBStream.m_nLockFlags & FSL_WRITE) - && (pVContainer->_HasVBStream(VSF_NORMALS))) - { - if (m_vertexFormat.Has16BitFloatTextureCoordinates()) - { - UpdateUVCoordsAdjacency(m_IBStream, m_vertexFormat); - } - else if (m_vertexFormat.Has32BitFloatTextureCoordinates()) - { - UpdateUVCoordsAdjacency(m_IBStream, m_vertexFormat); - } - } - } -#endif - - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - for (size_t i = 0, end0 = pVContainer->m_DeletedBoneIndices[threadId].size(); i < end0; ++i) - { - for (size_t j = 0, end1 = pVContainer->m_RemappedBoneIndices.size(); j < end1; ++j) - { - if (pVContainer->m_RemappedBoneIndices[j].guid == pVContainer->m_DeletedBoneIndices[threadId][i]) - { - SBoneIndexStream& stream = pVContainer->m_RemappedBoneIndices[j]; - if (stream.buffer != ~0u) - { - // Unregister the allocation with the VRAM driller - void* address = reinterpret_cast(stream.buffer); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, UnregisterAllocation, address); - - gRenDev->m_DevBufMan.Destroy(stream.buffer); - } - pVContainer->m_RemappedBoneIndices.erase(pVContainer->m_RemappedBoneIndices.begin() + j); - break; - } - } - } - pVContainer->m_DeletedBoneIndices[threadId].clear(); - for (size_t i = 0, end = pVContainer->m_CreatedBoneIndices[threadId].size(); i < end; ++i) - { - bool bFound = false; - SBoneIndexStreamRequest& rBoneIndexStreamRequest = pVContainer->m_CreatedBoneIndices[threadId][i]; - const uint32 guid = rBoneIndexStreamRequest.guid; - for (size_t j = 0, numIndices = m_RemappedBoneIndices.size(); j < numIndices; ++j) - { - if (m_RemappedBoneIndices[j].guid == guid && m_RemappedBoneIndices[j].refcount) - { - bFound = true; - ++m_RemappedBoneIndices[j].refcount; - } - } - - if (bFound == false) - { - size_t bufferSize = pVContainer->GetVerticesCount() * pVContainer->GetStreamStride(VSF_HWSKIN_INFO); - SBoneIndexStream stream; - stream.buffer = gRenDev->m_DevBufMan.Create(BBT_VERTEX_BUFFER, BU_STATIC, bufferSize); - stream.guid = guid; - stream.refcount = rBoneIndexStreamRequest.refcount; - gRenDev->m_DevBufMan.UpdateBuffer(stream.buffer, rBoneIndexStreamRequest.pStream, pVContainer->GetVerticesCount() * pVContainer->GetStreamStride(VSF_HWSKIN_INFO)); - pVContainer->m_RemappedBoneIndices.push_back(stream); - - // Register the allocation with the VRAM driller - void* address = reinterpret_cast(stream.buffer); - const char* bufferName = GetSourceName(); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterAllocation, address, bufferSize, bufferName, Render::Debug::VRAM_CATEGORY_BUFFER, Render::Debug::VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER); - } - - delete[] rBoneIndexStreamRequest.pStream; - } - pVContainer->m_CreatedBoneIndices[threadId].clear(); - - return true; -} - -void CRenderMesh::ReleaseVB(int nStream) -{ - UnlockVB(nStream); - if (SMeshStream* pMS = GetVertexStream(nStream, 0)) - { - if (pMS->m_nID != ~0u) - { - // Unregister the allocation with the VRAM driller - void* address = reinterpret_cast(pMS->m_nID); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, UnregisterAllocation, address); - - gRenDev->m_DevBufMan.Destroy(pMS->m_nID); - pMS->m_nID = ~0u; - } - pMS->m_nElements = 0; - pMS->m_nFrameUpdate = -1; - pMS->m_nFrameCreate = -1; - } -} - -void CRenderMesh::ReleaseIB() -{ - UnlockIB(); - if (m_IBStream.m_nID != ~0u) - { - // Unregister the allocation with the VRAM driller - void* address = reinterpret_cast(m_IBStream.m_nID); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, UnregisterAllocation, address); - - gRenDev->m_DevBufMan.Destroy(m_IBStream.m_nID); - m_IBStream.m_nID = ~0u; - } - m_IBStream.m_nElements = 0; - m_IBStream.m_nFrameUpdate = -1; - m_IBStream.m_nFrameCreate = -1; -} - -bool CRenderMesh::UpdateIndices_Int( - const vtx_idx* pNewInds - , int nInds - , int nOffsInd - , uint32 copyFlags) -{ - AZ_TRACE_METHOD(); - - //LockVB operates now on a per mesh lock, any thread may access - //ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT) - - //SREC_AUTO_LOCK(m_sResLock); - - // Resize the index buffer - if (m_nInds != nInds) - { - FreeIB(); - m_nInds = nInds; - } - if (!nInds) - { - assert(!m_IBStream.m_pUpdateData); - return true; - } - - vtx_idx* pDst = LockIB(FSL_VIDEO_CREATE, 0, nInds); - if (pDst && pNewInds) - { - if (copyFlags & FSL_ASYNC_DEFER_COPY && nInds * sizeof(vtx_idx) < RENDERMESH_ASYNC_MEMCPY_THRESHOLD) - { - cryAsyncMemcpy( - &pDst[nOffsInd], - pNewInds, - nInds * sizeof(vtx_idx), - MC_CPU_TO_GPU | copyFlags, - SetAsyncUpdateState()); - } - else - { - cryMemcpy( - &pDst[nOffsInd], - pNewInds, - nInds * sizeof(vtx_idx), - MC_CPU_TO_GPU); - UnlockIndexStream(); - } - } - else - { - return false; - } - - return true; -} - -bool CRenderMesh::UpdateVertices_Int( - const void* pVertBuffer - , int nVertCount - , int nOffset - , int nStream - , uint32 copyFlags) -{ - AZ_TRACE_METHOD(); - //LockVB operates now on a per mesh lock, any thread may access - // ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT) - - int nStride; - - //SREC_AUTO_LOCK(m_sResLock); - - // Resize the vertex buffer - if (m_nVerts != nVertCount) - { - for (int i = 0; i < VSF_NUM; i++) - { - FreeVB(i); - } - m_nVerts = nVertCount; - } - if (!m_nVerts) - { - return true; - } - - byte* pDstVB = (byte*)LockVB(nStream, FSL_VIDEO_CREATE, nVertCount, &nStride); - assert((nVertCount == 0) || pDstVB); - if (pDstVB && pVertBuffer) - { - if (copyFlags & FSL_ASYNC_DEFER_COPY && nStride * nVertCount < RENDERMESH_ASYNC_MEMCPY_THRESHOLD) - { - cryAsyncMemcpy( - &pDstVB[nOffset], - pVertBuffer, - nStride * nVertCount, - MC_CPU_TO_GPU | copyFlags, - SetAsyncUpdateState()); - } - else - { - cryMemcpy( - &pDstVB[nOffset], - pVertBuffer, - nStride * nVertCount, - MC_CPU_TO_GPU); - UnlockStream(nStream); - } - } - else - { - return false; - } - - return true; -} - -bool CRenderMesh::UpdateVertices( - const void* pVertBuffer - , int nVertCount - , int nOffset - , int nStream - , uint32 copyFlags - , bool requiresLock) -{ - bool result = false; - if (requiresLock) - { - SREC_AUTO_LOCK(m_sResLock); - result = UpdateVertices_Int(pVertBuffer, nVertCount, nOffset, nStream, copyFlags); - } - else - { - result = UpdateVertices_Int(pVertBuffer, nVertCount, nOffset, nStream, copyFlags); - } - return result; -} - -bool CRenderMesh::UpdateIndices( - const vtx_idx* pNewInds - , int nInds - , int nOffsInd - , uint32 copyFlags - , bool requiresLock) -{ - bool result = false; - if (requiresLock) - { - SREC_AUTO_LOCK(m_sResLock); - result = UpdateIndices_Int(pNewInds, nInds, nOffsInd, copyFlags); - } - else - { - result = UpdateIndices_Int(pNewInds, nInds, nOffsInd, copyFlags); - } - return result; -} - -bool CRenderMesh::UpdateVidIndices(SMeshStream& IBStream, [[maybe_unused]] bool stall) -{ - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - AZ_TRACE_METHOD(); - - assert(gRenDev->m_pRT->IsRenderThread()); - - SREC_AUTO_LOCK(m_sResLock); - - assert(gRenDev->m_pRT->IsRenderThread()); - - int nInds = m_nInds; - - if (!nInds) - { - // 0 size index buffer creation crashes on deprecated platform - assert(nInds); - return false; - } - - if (IBStream.m_nElements != m_nInds && _HasIBStream()) - { - ReleaseIB(); - } - - if (IBStream.m_nID == ~0u) - { - const size_t bufferSize = nInds * sizeof(vtx_idx); - IBStream.m_nID = gRenDev->m_DevBufMan.Create(BBT_INDEX_BUFFER, (BUFFER_USAGE)m_eType, bufferSize); - IBStream.m_nElements = m_nInds; - IBStream.m_nFrameCreate = gRenDev->m_RP.m_TI[gRenDev->m_pRT->IsMainThread() ? gRenDev->m_RP.m_nFillThreadID : gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - // Register the allocation with the VRAM driller - void* address = reinterpret_cast(IBStream.m_nID); - const char* bufferName = GetSourceName(); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterAllocation, address, bufferSize, bufferName, Render::Debug::VRAM_CATEGORY_BUFFER, Render::Debug::VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER); - } - if (IBStream.m_nID != ~0u) - { - UnlockIndexStream(); - if (m_IBStream.m_pUpdateData) - { - return gRenDev->m_DevBufMan.UpdateBuffer(IBStream.m_nID, IBStream.m_pUpdateData, m_nInds * sizeof(vtx_idx)); - } - } - return false; -} - -bool CRenderMesh::CreateVidVertices(int nStream) -{ - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - AZ_TRACE_METHOD(); - - SREC_AUTO_LOCK(m_sResLock); - - if (gRenDev->m_bDeviceLost) - { - return false; - } - - assert (!_HasVBStream(nStream)); - SMeshStream* pMS = GetVertexStream(nStream, FSL_WRITE); - int nSize = GetStreamSize(nStream, m_nVerts); - pMS->m_nID = gRenDev->m_DevBufMan.Create(BBT_VERTEX_BUFFER, (BUFFER_USAGE)m_eType, nSize); - pMS->m_nElements = m_nVerts; - pMS->m_nFrameCreate = gRenDev->m_RP.m_TI - [gRenDev->m_pRT->IsMainThread() - ? gRenDev->m_RP.m_nFillThreadID - : gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - // Register the allocation with the VRAM driller - void* address = reinterpret_cast(pMS->m_nID); - const char* bufferName = GetSourceName(); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterAllocation, address, nSize, bufferName, Render::Debug::VRAM_CATEGORY_BUFFER, Render::Debug::VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER); - - return (pMS->m_nID != ~0u); -} - -bool CRenderMesh::UpdateVidVertices(int nStream, [[maybe_unused]] bool stall) -{ - AZ_TRACE_METHOD(); - - assert(gRenDev->m_pRT->IsRenderThread()); - - SREC_AUTO_LOCK(m_sResLock); - - assert(nStream < VSF_NUM); - SMeshStream* pMS = GetVertexStream(nStream, FSL_WRITE); - - if (m_nVerts != pMS->m_nElements && _HasVBStream(nStream)) - { - ReleaseVB(nStream); - } - - if (pMS->m_nID == ~0u) - { - if (!CreateVidVertices(nStream)) - { - return false; - } - } - if (pMS->m_nID != ~0u) - { - UnlockStream(nStream); - if (pMS->m_pUpdateData) - { - return gRenDev->m_DevBufMan.UpdateBuffer(pMS->m_nID, pMS->m_pUpdateData, GetStreamSize(nStream)); - ; - } - else - { - assert(0); - } - } - return false; -} - -#ifdef MESH_TESSELLATION_RENDERER -template -bool CRenderMesh::UpdateUVCoordsAdjacency(SMeshStream& IBStream, const AZ::Vertex::Format& vertexFormat) -{ - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - AZ_TRACE_METHOD(); - - assert(gRenDev->m_pRT->IsRenderThread()); - - SREC_AUTO_LOCK(m_sResLock); - - int nInds = m_nInds * 4; - - if (!nInds) - { - // 0 size index buffer creation crashes on deprecated platform - assert(nInds); - return false; - } - - SMeshStream* pMS = GetVertexStream(VSF_GENERAL); - - if (IBStream.m_nID != ~0u && pMS) - { - if (m_IBStream.m_pUpdateData) - { - bool bRes = true; - std::vector pTxtAdjBuffer; - - // create triangles with adjacency - byte* pVertexStream = (byte*)pMS->m_pUpdateData; - uint stride = vertexFormat.GetStride(); - uint offset = 0; - // Only handle one uv set for now. - if ((m_vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::TexCoord)) && pVertexStream) - { - int nTrgs = m_nInds / 3; - pTxtAdjBuffer.resize(nTrgs * 12); - int nVerts = GetNumVerts(); - for (int n = 0; n < nTrgs; ++n) - { - // fill in the dummy adjacency first - VecUV* pDst = &pTxtAdjBuffer[n * 12]; - vtx_idx* pSrc = (vtx_idx*)m_IBStream.m_pUpdateData + n * 3; - // triangle itself - memcpy(&pDst[0], &pVertexStream[pSrc[0] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[1], &pVertexStream[pSrc[1] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[2], &pVertexStream[pSrc[2] * stride + offset], sizeof(VecUV)); - - // adjacency by edges - memcpy(&pDst[3], &pVertexStream[pSrc[0] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[4], &pVertexStream[pSrc[1] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[5], &pVertexStream[pSrc[1] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[6], &pVertexStream[pSrc[2] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[7], &pVertexStream[pSrc[2] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[8], &pVertexStream[pSrc[0] * stride + offset], sizeof(VecUV)); - // adjacency by corners - memcpy(&pDst[9], &pVertexStream[pSrc[0] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[10], &pVertexStream[pSrc[1] * stride + offset], sizeof(VecUV)); - memcpy(&pDst[11], &pVertexStream[pSrc[2] * stride + offset], sizeof(VecUV)); - } - - // now real adjacency is computed - BuildAdjacency(pVertexStream, vertexFormat, nVerts, (vtx_idx*)m_IBStream.m_pUpdateData, nTrgs, pTxtAdjBuffer); - - m_adjBuffer.Create(pTxtAdjBuffer.size(), sizeof(Vec2f16), DXGI_FORMAT_R16G16_FLOAT, DX11BUF_BIND_SRV, &pTxtAdjBuffer[0]); - - if constexpr (sizeof(VecUV) == sizeof(Vec2f16)) - { - m_adjBuffer.Create(pTxtAdjBuffer.size(), sizeof(VecUV), DXGI_FORMAT_R16G16_FLOAT, DX11BUF_BIND_SRV, &pTxtAdjBuffer[0]); - } - else - { - m_adjBuffer.Create(pTxtAdjBuffer.size(), sizeof(VecUV), DXGI_FORMAT_R32G32_FLOAT, DX11BUF_BIND_SRV, &pTxtAdjBuffer[0]); - } - - // HS needs to know iPatchID offset for each drawcall, so we pass this offset in the constant buffer - // currently texture buffer is created, but when parser support for cbuffer is added (AI: AndreyK), we - // need to change the below call to: - // ((CREMeshImpl*) m_Chunks[iChunk].pRE)->m_tessCB.Create(4, sizeof(int), (DXGI_FORMAT)0, &myBuffer[0], D3D11_BIND_CONSTANT_BUFFER); - for (int iChunk = 0; iChunk < m_Chunks.size(); ++iChunk) - { - int myBuffer[4]; - myBuffer[0] = m_Chunks[iChunk].nFirstIndexId / 3; - ((CREMeshImpl*) m_Chunks[iChunk].pRE)->m_tessCB.Create(4, sizeof(int), DXGI_FORMAT_R32_SINT, DX11BUF_BIND_SRV, &myBuffer[0]); - } - } - - return bRes; - } - } - - return false; -} -#endif //#ifdef MESH_TESSELLATION_RENDERER - -void CRenderMesh::Render(const SRendParams& rParams, CRenderObject* pObj, _smart_ptr pMaterial, const SRenderingPassInfo& passInfo, bool bSkinned) -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_RENDERER, g_bProfilerEnabled); - - IF (!CanRender(), 0) - { - return; - } - - int nList = rParams.nRenderList; - int nAW = rParams.nAfterWater; - CRenderer* rd = gRenDev; - -#if !defined(_RELEASE) - const char* szExcl = CRenderer::CV_r_excludemesh->GetString(); - if (szExcl[0] && m_sSource) - { - char szMesh[1024]; - cry_strcpy(szMesh, this->m_sSource); - azstrlwr(szMesh, AZ_ARRAY_SIZE(szMesh)); - if (szExcl[0] == '!') - { - if (!strstr(&szExcl[1], m_sSource)) - { - return; - } - } - else - if (strstr(szExcl, m_sSource)) - { - return; - } - } -#endif - - if (rd->m_pDefaultMaterial && pMaterial) - { - pMaterial = rd->m_pDefaultMaterial; - } - - assert(pMaterial); - - if (!pMaterial || !m_nVerts || !m_nInds || m_Chunks.empty()) - { - return; - } - - pObj->m_pRenderNode = rParams.pRenderNode; - pObj->m_pCurrMaterial = pMaterial; - - if (rParams.nHUDSilhouettesParams || rParams.nVisionParams || rParams.pInstance) - { - SRenderObjData* pOD = rd->EF_GetObjData(pObj, true, passInfo.ThreadID()); - - pOD->m_nHUDSilhouetteParams = rParams.nHUDSilhouettesParams; - pOD->m_uniqueObjectId = reinterpret_cast(rParams.pInstance); - } - - - assert(!(pObj->m_ObjFlags & FOB_BENDED)); - - const bool bSG = passInfo.IsShadowPass(); - - if (gRenDev->CV_r_MotionVectors && passInfo.IsGeneralPass() && ((pObj->m_ObjFlags & FOB_DYNAMIC_OBJECT) != 0)) - { - CMotionBlur::SetupObject(pObj, passInfo); - } - - TRenderChunkArray* pChunks = bSkinned ? &m_ChunksSkinned : &m_Chunks; - - if (pChunks) - { - const uint32 ni = (uint32)pChunks->size(); - for (uint32 i = 0; i < ni; i++) - { - CRenderChunk* pChunk = &pChunks->at(i); - CRendElementBase* pREMesh = pChunk->pRE; - - SShaderItem& ShaderItem = pMaterial->GetShaderItem(pChunk->m_nMatID); - - CShaderResources* pR = (CShaderResources*)ShaderItem.m_pShaderResources; - CShader* pS = (CShader*)ShaderItem.m_pShader; - if (pREMesh && pS && pR) - { - if (pS->m_Flags2 & EF2_NODRAW) - { - continue; - } - - if (bSG && (pMaterial->GetSafeSubMtl(pChunk->m_nMatID)->GetFlags() & MTL_FLAG_NOSHADOW)) - { - continue; - } - - rd->EF_AddEf_NotVirtual(pREMesh, ShaderItem, pObj, passInfo, nList, nAW, SRendItemSorter(rParams.rendItemSorter)); - } - } - } -} - - -void CRenderMesh::SetREUserData(float* pfCustomData, [[maybe_unused]] float fFogScale, [[maybe_unused]] float fAlpha) -{ - for (int i = 0; i < m_Chunks.size(); i++) - { - if (m_Chunks[i].pRE) - { - m_Chunks[i].pRE->m_CustomData = pfCustomData; - } - } -} - -void CRenderMesh::AddRenderElements(_smart_ptr pIMatInfo, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nList, int nAW) -{ - SRendItemSorter rendItemSorter = passInfo.IsShadowPass() ? SRendItemSorter::CreateShadowPassRendItemSorter(passInfo) : SRendItemSorter::CreateRendItemSorter(passInfo); - - assert(!(pObj->m_ObjFlags & FOB_BENDED)); - //assert (!pObj->GetInstanceInfo(0)); - assert(pIMatInfo); - - if (!_GetVertexContainer()->m_nVerts || !m_Chunks.size() || !pIMatInfo) - { - return; - } - - if (gRenDev->m_pDefaultMaterial && gRenDev->m_pTerrainDefaultMaterial) - { - pIMatInfo = gRenDev->m_pDefaultMaterial; - } - - for (int i = 0; i < m_Chunks.size(); i++) - { - CRenderChunk* pChunk = &m_Chunks[i]; - CREMeshImpl* pOrigRE = (CREMeshImpl*) pChunk->pRE; - - // get material - - SShaderItem& shaderItem = pIMatInfo->GetShaderItem(pChunk->m_nMatID); - - // if (nTechniqueID > 0) - // shaderItem.m_nTechnique = shaderItem.m_pShader->GetTechniqueID(shaderItem.m_nTechnique, nTechniqueID); - - if (shaderItem.m_pShader && pOrigRE)// && pMat->nNumIndices) - { - TArray* pREs = shaderItem.m_pShader->GetREs(shaderItem.m_nTechnique); - - assert(pOrigRE->m_pChunk->nFirstIndexId < 60000); - - if (!pREs || !pREs->Num()) - { - gRenDev->EF_AddEf_NotVirtual(pOrigRE, shaderItem, pObj, passInfo, nList, nAW, rendItemSorter); - } - else - { - gRenDev->EF_AddEf_NotVirtual(pREs->Get(0), shaderItem, pObj, passInfo, nList, nAW, rendItemSorter); - } - } - } //i -} - -void CRenderMesh::AddRE(_smart_ptr pMaterial, CRenderObject* obj, IShader* ef, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter) -{ - if (!m_nVerts || !m_Chunks.size()) - { - return; - } - - assert(!(obj->m_ObjFlags & FOB_BENDED)); - - for (int i = 0; i < m_Chunks.size(); i++) - { - if (!m_Chunks[i].pRE) - { - continue; - } - - SShaderItem& SH = pMaterial->GetShaderItem(); - if (ef) - { - SH.m_pShader = ef; - } - if (SH.m_pShader) - { - assert(m_Chunks[i].pRE->m_pChunk->nFirstIndexId < 60000); - - TArray* pRE = SH.m_pShader->GetREs(SH.m_nTechnique); - if (!pRE || !pRE->Num()) - { - gRenDev->EF_AddEf_NotVirtual(m_Chunks[i].pRE, SH, obj, passInfo, nList, nAW, rendItemSorter); - } - else - { - gRenDev->EF_AddEf_NotVirtual(SH.m_pShader->GetREs(SH.m_nTechnique)->Get(0), SH, obj, passInfo, nList, nAW, rendItemSorter); - } - } - } -} - -size_t CRenderMesh::GetMemoryUsage(ICrySizer* pSizer, EMemoryUsageArgument nType) const -{ - size_t nSize = 0; - switch (nType) - { - case MEM_USAGE_COMBINED: - nSize = Size(SIZE_ONLY_SYSTEM) + Size(SIZE_VB | SIZE_IB); - break; - case MEM_USAGE_ONLY_SYSTEM: - nSize = Size(SIZE_ONLY_SYSTEM); - break; - case MEM_USAGE_ONLY_VIDEO: - nSize = Size(SIZE_VB | SIZE_IB); - return nSize; - break; - case MEM_USAGE_ONLY_STREAMS: - nSize = Size(SIZE_ONLY_SYSTEM) + Size(SIZE_VB | SIZE_IB); - - if (pSizer) - { - SIZER_COMPONENT_NAME(pSizer, "STREAM MESH"); - pSizer->AddObject((void*)this, nSize); - } - - // Not add overhead allocations. - return nSize; - break; - } - - { - nSize += sizeof(*this); - for (int i = 0; i < (int)m_Chunks.capacity(); i++) - { - if (i < m_Chunks.size()) - { - nSize += m_Chunks[i].Size(); - } - else - { - nSize += sizeof(CRenderChunk); - } - } - for (int i = 0; i < (int)m_ChunksSkinned.capacity(); i++) - { - if (i < m_ChunksSkinned.size()) - { - nSize += m_ChunksSkinned.at(i).Size(); - } - else - { - nSize += sizeof(CRenderChunk); - } - } - } - - if (pSizer) - { - pSizer->AddObject((void*)this, nSize); - -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - if (m_pTrisMap) - { - SIZER_COMPONENT_NAME(pSizer, "Hash map"); - nSize += stl::size_of_map(*m_pTrisMap); - } -#endif - - for (MeshSubSetIndices::const_iterator it = m_meshSubSetIndices.begin(); it != m_meshSubSetIndices.end(); ++it) - { - // Collect memory usage for index sub-meshes. - it->second->GetMemoryUsage(pSizer, nType); - } - } - - return nSize; -} - -void CRenderMesh::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - { - SIZER_COMPONENT_NAME(pSizer, "Vertex Data"); - for (uint32 i = 0; i < VSF_NUM; i++) - { - if (SMeshStream* pMS = GetVertexStream(i, 0)) - { - if (pMS->m_pUpdateData) - { - pSizer->AddObject(pMS->m_pUpdateData, GetStreamSize(i)); - } - } - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "FP16 Cache"); - if (m_pCachePos) - { - pSizer->AddObject(m_pCachePos, m_nVerts * sizeof(Vec3)); - } - for (int i = 0; i < m_UVCache.size(); ++i) - { - if (m_UVCache[i]) - { - pSizer->AddObject(m_UVCache[i], m_nVerts * sizeof(Vec2)); - } - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "Mesh Chunks"); - pSizer->AddObject(m_Chunks); - } - { - SIZER_COMPONENT_NAME(pSizer, "Mesh Skinned Chunks"); - pSizer->AddObject(m_ChunksSkinned); - } - -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - { - SIZER_COMPONENT_NAME(pSizer, "Hash map"); - pSizer->AddObject(m_pTrisMap); - } -#endif - for (MeshSubSetIndices::const_iterator it = m_meshSubSetIndices.begin(); it != m_meshSubSetIndices.end(); ++it) - { - // Collect memory usage for index sub-meshes. - it->second->GetMemoryUsage(pSizer); - } -} - -int CRenderMesh::GetAllocatedBytes(bool bVideoMem) const -{ - if (!bVideoMem) - { - return Size(SIZE_ONLY_SYSTEM); - } - else - { - return Size(SIZE_VB | SIZE_IB); - } -} - -int CRenderMesh::GetTextureMemoryUsage(const _smart_ptr pMaterial, ICrySizer* pSizer, bool bStreamedIn) const -{ - // If no input material use internal render mesh material. - if (!pMaterial) - { - return 0; - } - - int textureSize = 0; - std::set used; - for (int a = 0; a < m_Chunks.size(); a++) - { - const CRenderChunk* pChunk = &m_Chunks[a]; - - // Override default material - const SShaderItem& shaderItem = pMaterial->GetShaderItem(pChunk->m_nMatID); - if (!shaderItem.m_pShaderResources) - { - continue; - } - - const CShaderResources* pRes = (const CShaderResources*)shaderItem.m_pShaderResources; - for (auto iter = pRes->m_TexturesResourcesMap.begin(); iter != pRes->m_TexturesResourcesMap.end(); ++iter) - { - const CTexture* pTexture = iter->second.m_Sampler.m_pTex; - if (!pTexture) - { - continue; - } - - if (used.find(pTexture) != used.end()) // Already used in size calculation. - { - continue; - } - used.insert(pTexture); - - int nTexSize = bStreamedIn ? pTexture->GetDeviceDataSize() : pTexture->GetDataSize(); - textureSize += nTexSize; - - if (pSizer) - { - pSizer->AddObject(pTexture, nTexSize); - } - } - } - return textureSize; -} - -float CRenderMesh::GetAverageTrisNumPerChunk(_smart_ptr pMat) -{ - float fTrisNum = 0; - float fChunksNum = 0; - - for (int m = 0; m < m_Chunks.size(); m++) - { - const CRenderChunk& chunk = m_Chunks[m]; - if ((chunk.m_nMatFlags & MTL_FLAG_NODRAW) || !chunk.pRE) - { - continue; - } - - _smart_ptr pCustMat; - if (pMat && chunk.m_nMatID < pMat->GetSubMtlCount()) - { - pCustMat = pMat->GetSubMtl(chunk.m_nMatID); - } - else - { - pCustMat = pMat; - } - - if (!pCustMat) - { - continue; - } - - const IShader* pShader = pCustMat->GetShaderItem().m_pShader; - - if (!pShader) - { - continue; - } - - if (pShader->GetFlags2() & EF2_NODRAW) - { - continue; - } - - fTrisNum += chunk.nNumIndices / 3; - fChunksNum++; - } - - return fChunksNum ? (fTrisNum / fChunksNum) : 0; -} - -void CRenderMesh::InitTriHash(_smart_ptr pMaterial) -{ -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - - SAFE_DELETE(m_pTrisMap); - m_pTrisMap = new TrisMap; - - int nPosStride = 0; - int nIndCount = m_nInds; - const byte* pPositions = GetPosPtr(nPosStride, FSL_READ); - const vtx_idx* pIndices = GetIndexPtr(FSL_READ); - - iLog->Log("CRenderMesh::InitTriHash: Tris=%d, Verts=%d, Name=%s ...", nIndCount / 3, GetVerticesCount(), GetSourceName() ? GetSourceName() : "Null"); - - if (pIndices && pPositions && m_Chunks.size() && nIndCount && GetVerticesCount()) - { - for (uint32 ii = 0; ii < (uint32)m_Chunks.size(); ii++) - { - CRenderChunk* pChunk = &m_Chunks[ii]; - - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - // skip transparent and alpha test - const SShaderItem& shaderItem = pMaterial->GetShaderItem(pChunk->m_nMatID); - if (!shaderItem.IsZWrite() || !shaderItem.m_pShaderResources || shaderItem.m_pShaderResources->IsAlphaTested()) - { - continue; - } - - if (shaderItem.m_pShader && shaderItem.m_pShader->GetFlags() & EF_DECAL) - { - continue; - } - - uint32 nFirstIndex = pChunk->nFirstIndexId; - uint32 nLastIndex = pChunk->nFirstIndexId + pChunk->nNumIndices; - - for (uint32 i = nFirstIndex; i < nLastIndex; i += 3) - { - int32 I0 = pIndices[i + 0]; - int32 I1 = pIndices[i + 1]; - int32 I2 = pIndices[i + 2]; - - Vec3 v0 = *(Vec3*)&pPositions[nPosStride * I0]; - Vec3 v1 = *(Vec3*)&pPositions[nPosStride * I1]; - Vec3 v2 = *(Vec3*)&pPositions[nPosStride * I2]; - - AABB triBox; - triBox.min = triBox.max = v0; - triBox.Add(v1); - triBox.Add(v2); - - float fRayLen = CRenderer::CV_r_RenderMeshHashGridUnitSize / 2; - triBox.min -= Vec3(fRayLen, fRayLen, fRayLen); - triBox.max += Vec3(fRayLen, fRayLen, fRayLen); - - AABB aabbCell; - - aabbCell.min = triBox.min / CRenderer::CV_r_RenderMeshHashGridUnitSize; - aabbCell.min.x = floor(aabbCell.min.x); - aabbCell.min.y = floor(aabbCell.min.y); - aabbCell.min.z = floor(aabbCell.min.z); - - aabbCell.max = triBox.max / CRenderer::CV_r_RenderMeshHashGridUnitSize; - aabbCell.max.x = ceil(aabbCell.max.x); - aabbCell.max.y = ceil(aabbCell.max.y); - aabbCell.max.z = ceil(aabbCell.max.z); - - for (float x = aabbCell.min.x; x < aabbCell.max.x; x++) - { - for (float y = aabbCell.min.y; y < aabbCell.max.y; y++) - { - for (float z = aabbCell.min.z; z < aabbCell.max.z; z++) - { - AABB cellBox; - cellBox.min = Vec3(x, y, z) * CRenderer::CV_r_RenderMeshHashGridUnitSize; - cellBox.max = cellBox.min + Vec3(CRenderer::CV_r_RenderMeshHashGridUnitSize, CRenderer::CV_r_RenderMeshHashGridUnitSize, CRenderer::CV_r_RenderMeshHashGridUnitSize); - cellBox.min -= Vec3(fRayLen, fRayLen, fRayLen); - cellBox.max += Vec3(fRayLen, fRayLen, fRayLen); - if (!Overlap::AABB_Triangle(cellBox, v0, v1, v2)) - { - continue; - } - - int key = (int)(x * 256.f * 256.f + y * 256.f + z); - PodArray >* pTris = &(*m_pTrisMap)[key]; - std::pair t(i, pChunk->m_nMatID); - if (pTris->Find(t) < 0) - { - pTris->Add(t); - } - } - } - } - } - } - } - - iLog->LogPlus(" ok (%" PRISIZE_T ")", m_pTrisMap->size()); - -#endif -} - - -const PodArray >* CRenderMesh::GetTrisForPosition([[maybe_unused]] const Vec3& vPos, _smart_ptr pMaterial) -{ -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - - if (!m_pTrisMap) - { - AUTO_LOCK(m_getTrisForPositionLock); - if (!m_pTrisMap) - { - InitTriHash(pMaterial); - } - } - - Vec3 vCellMin = vPos / CRenderer::CV_r_RenderMeshHashGridUnitSize; - vCellMin.x = floor(vCellMin.x); - vCellMin.y = floor(vCellMin.y); - vCellMin.z = floor(vCellMin.z); - - int key = (int)(vCellMin.x * 256.f * 256.f + vCellMin.y * 256.f + vCellMin.z); - - const TrisMap::iterator& iter = (*m_pTrisMap).find(key); - if (iter != (*m_pTrisMap).end()) - { - return &iter->second; - } -#else - AZ_Assert(false, "NOT IMPLEMENTED: CRenderMesh::GetTrisForPosition(const Vec3& vPos, _smart_ptr pMaterial)"); -#endif - - return 0; -} - -void CRenderMesh::UpdateBBoxFromMesh() -{ - PROFILE_FRAME(UpdateBBoxFromMesh); - - AABB aabb; - aabb.Reset(); - - int nVertCount = _GetVertexContainer()->GetVerticesCount(); - int nPosStride = 0; - const byte* pPositions = GetPosPtr(nPosStride, FSL_READ); - const vtx_idx* pIndices = GetIndexPtr(FSL_READ); - - if (!pIndices || !pPositions) - { - assert(!"Mesh is not ready"); - return; - } - - for (int32 a = 0; a < m_Chunks.size(); a++) - { - CRenderChunk* pChunk = &m_Chunks[a]; - - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - uint32 nFirstIndex = pChunk->nFirstIndexId; - uint32 nLastIndex = pChunk->nFirstIndexId + pChunk->nNumIndices; - - for (uint32 i = nFirstIndex; i < nLastIndex; i++) - { - int32 I0 = pIndices[i]; - if (I0 < nVertCount) - { - Vec3 v0 = *(Vec3*)&pPositions[nPosStride * I0]; - aabb.Add(v0); - } - else - { - assert(!"Index is out of range"); - } - } - } - - if (!aabb.IsReset()) - { - m_vBoxMax = aabb.max; - m_vBoxMin = aabb.min; - } -} - -static void ExtractBoneIndicesAndWeights(uint16* outIndices, Vec4& outWeights, const JointIdType* aBoneRemap, const uint16* indices, UCol weights) -{ - // Get 8-bit weights as floats - outWeights[0] = weights.bcolor[0]; - outWeights[1] = weights.bcolor[1]; - outWeights[2] = weights.bcolor[2]; - outWeights[3] = weights.bcolor[3]; - - // Get bone indices - if (aBoneRemap) - { - outIndices[0] = aBoneRemap[indices[0]]; - outIndices[1] = aBoneRemap[indices[1]]; - outIndices[2] = aBoneRemap[indices[2]]; - outIndices[3] = aBoneRemap[indices[3]]; - } - else - { - outIndices[0] = indices[0]; - outIndices[1] = indices[1]; - outIndices[2] = indices[2]; - outIndices[3] = indices[3]; - } -} - -static void BlendDualQuats(DualQuat& outBone, Array aBoneLocs, const uint16* indices, const Vec4 outWeights) -{ - outBone = aBoneLocs[indices[0]] * outWeights[0] + - aBoneLocs[indices[1]] * outWeights[1] + - aBoneLocs[indices[2]] * outWeights[2] + - aBoneLocs[indices[3]] * outWeights[3]; - - outBone.Normalize(); -} - -static void BlendMatrices(Matrix34& outBone, Array aBoneLocs, const uint16* indices, const Vec4 outWeights) -{ - outBone = (aBoneLocs[indices[0]] * outWeights[0]) + - (aBoneLocs[indices[1]] * outWeights[1]) + - (aBoneLocs[indices[2]] * outWeights[2]) + - (aBoneLocs[indices[3]] * outWeights[3]); -} - -struct PosNormData -{ - strided_pointer aPos; - strided_pointer aNorm; - strided_pointer aVert; - strided_pointer aQTan; - strided_pointer aTan2; - - void GetPosNorm(PosNorm& ran, int nV) - { - // Position - ran.vPos = aPos[nV]; - - // Normal - if (aNorm.data) - { - ran.vNorm = aNorm[nV]; - } - else if (aVert.data) - { - ran.vNorm = aVert[nV].normal.GetN(); - } - else if (aTan2.data) - { - ran.vNorm = aTan2[nV].GetN(); - } - else if (aQTan.data) - { - ran.vNorm = aQTan[nV].GetN(); - } - } -}; - -// To do: replace with VSF_MORPHBUDDY support -#define SKIN_MORPHING 0 - -struct SkinnedPosNormData - : PosNormData -{ - SSkinningData const* pSkinningData; - -#if SKIN_MORPHING - strided_pointer aMorphing; -#endif - - strided_pointer aSkinning; - - - SkinnedPosNormData() {} - - void GetPosNorm(PosNorm& ran, int nV) - { - PosNormData::GetPosNorm(ran, nV); - - #if SKIN_MORPHING - if (aShapeDeform && aMorphing) - { - SVF_P3F_P3F_I4B const& morph = aMorphing[nV]; - uint8 idx = (uint8)morph.index.dcolor; - float fDeform = aShapeDeform[idx]; - if (fDeform < 0.0f) - { - ran.vPos = morph.thin * (-fDeform) + ran.vPos * (fDeform + 1); - } - else if (fDeform > 0.f) - { - ran.vPos = ran.vPos * (1 - fDeform) + morph.fat * fDeform; - } - } - - /*if (!g_arrExtMorphStream.empty()) - ran.vPos += g_arrExtMorphStream[nV];*/ - #endif - - // Skinning - if (pSkinningData) - { - uint16 indices[4]; - Vec4 weights; - ExtractBoneIndicesAndWeights(indices, weights, pSkinningData->pRemapTable, &aSkinning[nV].indices[0], aSkinning[nV].weights); - - if (pSkinningData->nHWSkinningFlags & eHWS_Skinning_Matrix) - { - Matrix34 m; - BlendMatrices( - m, - ArrayT(pSkinningData->pBoneMatrices, (int)pSkinningData->nNumBones), - indices, - weights); - ran <<= m; - } - else - { - // Transform the vertex with skinning. - DualQuat dq; - BlendDualQuats( - dq, - ArrayT(pSkinningData->pBoneQuatsS, (int)pSkinningData->nNumBones), - indices, - weights); - ran <<= dq; - } - } - } -}; - -float CRenderMesh::GetExtent(EGeomForm eForm) -{ - if (eForm == GeomForm_Vertices) - { - return (float)m_nVerts; - } - CGeomExtent& ext = m_Extents.Make(eForm); - if (!ext) - { - LockForThreadAccess(); - - vtx_idx* pInds = GetIndexPtr(FSL_READ); - strided_pointer aPos; - aPos.data = (Vec3*)GetPosPtr(aPos.iStride, FSL_READ); - if (pInds && aPos.data) - { - // Iterate chunks to track renderable verts - bool* aValidVerts = new bool[m_nVerts]; - memset(aValidVerts, 0, m_nVerts); - TRenderChunkArray& aChunks = !m_ChunksSkinned.empty() ? m_ChunksSkinned : m_Chunks; - for (int c = 0; c < aChunks.size(); ++c) - { - const CRenderChunk& chunk = aChunks[c]; - if (chunk.pRE && !(chunk.m_nMatFlags & (MTL_FLAG_NODRAW | MTL_FLAG_REQUIRE_FORWARD_RENDERING))) - { - assert(uint32(chunk.nFirstVertId + chunk.nNumVerts) <= m_nVerts); - memset(aValidVerts + chunk.nFirstVertId, 1, chunk.nNumVerts); - } - } - - int nParts = TriMeshPartCount(eForm, GetIndicesCount()); - ext.ReserveParts(nParts); - for (int i = 0; i < nParts; i++) - { - int aIndices[3]; - Vec3 aVec[3]; - for (int v = TriIndices(aIndices, i, eForm) - 1; v >= 0; v--) - { - aVec[v] = aPos[ pInds[aIndices[v]] ]; - } - ext.AddPart(aValidVerts[ pInds[aIndices[0]] ] ? max(TriExtent(eForm, aVec), 0.f) : 0.f); - } - delete[] aValidVerts; - } - - UnlockStream(VSF_GENERAL); - UnlockIndexStream(); - UnLockForThreadAccess(); - } - return ext.TotalExtent(); -} - -void CRenderMesh::GetRandomPos(PosNorm& ran, EGeomForm eForm, SSkinningData const* pSkinning) -{ - LockForThreadAccess(); - - SkinnedPosNormData vdata; - vdata.aPos.data = (Vec3*)GetPosPtr(vdata.aPos.iStride, FSL_READ); - if (vdata.aPos.data) - { - // Check possible sources for normals. -#if ENABLE_NORMALSTREAM_SUPPORT - if (!GetStridedArray(vdata.aNorm, VSF_NORMALS)) -#endif - if (_GetVertexFormat() != eVF_P3S_N4B_C4B_T2S || !GetStridedArray(vdata.aVert, VSF_GENERAL)) - { - if (!GetStridedArray(vdata.aTan2, VSF_TANGENTS)) - { - GetStridedArray(vdata.aQTan, VSF_QTANGENTS); - } - } - - vtx_idx* pInds = GetIndexPtr(FSL_READ); - - vdata.pSkinningData = pSkinning; - if (vdata.pSkinningData) - { - GetStridedArray(vdata.aSkinning, VSF_HWSKIN_INFO); - #if SKIN_MORPHING - GetStridedArray(vdata.aMorphing, VSF_HWSKIN_SHAPEDEFORM_INFO); - #endif - } - - // Choose part. - if (eForm == GeomForm_Vertices) - { - if (m_nInds == 0) - { - ran.zero(); - } - else - { - int nIndex = cry_random(0U, m_nInds - 1); - vdata.GetPosNorm(ran, pInds[nIndex]); - } - } - else - { - CGeomExtent const& extent = m_Extents[eForm]; - if (!extent.NumParts()) - { - ran.zero(); - } - else - { - int aIndices[3]; - int nPart = extent.RandomPart(); - int nVerts = TriIndices(aIndices, nPart, eForm); - - // Extract vertices, blend. - PosNorm aRan[3]; - while (--nVerts >= 0) - { - vdata.GetPosNorm(aRan[nVerts], pInds[aIndices[nVerts]]); - } - TriRandomPos(ran, eForm, aRan, true); - } - } - } - - UnLockForThreadAccess(); - UnlockStream(VSF_GENERAL); - UnlockStream(VSF_QTANGENTS); - UnlockStream(VSF_TANGENTS); - UnlockStream(VSF_HWSKIN_INFO); -} - -int CRenderChunk::Size() const -{ - size_t nSize = sizeof(*this); - return static_cast(nSize); -} - -void CRenderMesh::Size(uint32 nFlags, ICrySizer* pSizer) const -{ - uint32 i; - if (!nFlags) // System size - { - for (i = 0; i < VSF_NUM; i++) - { - if (SMeshStream* pMS = GetVertexStream(i)) - { - if (pMS->m_pUpdateData) - { - pSizer->AddObject(pMS->m_pUpdateData, GetStreamSize(i)); - } - } - } - if (m_IBStream.m_pUpdateData) - { - pSizer->AddObject(m_IBStream.m_pUpdateData, m_nInds * sizeof(vtx_idx)); - } - - if (m_pCachePos) - { - pSizer->AddObject(m_pCachePos, m_nVerts * sizeof(Vec3)); - } - } -} - -size_t CRenderMesh::Size(uint32 nFlags) const -{ - size_t nSize = 0; - uint32 i; - if (nFlags == SIZE_ONLY_SYSTEM) // System size - { - for (i = 0; i < VSF_NUM; i++) - { - if (SMeshStream* pMS = GetVertexStream(i)) - { - if (pMS->m_pUpdateData) - { - nSize += GetStreamSize(i); - } - } - } - if (m_IBStream.m_pUpdateData) - { - nSize += m_nInds * sizeof(vtx_idx); - } - - if (m_pCachePos) - { - nSize += m_nVerts * sizeof(Vec3); - } - } - if (nFlags & SIZE_VB) // VB size - { - for (i = 0; i < VSF_NUM; i++) - { - if (_HasVBStream(i)) - { - nSize += GetStreamSize(i); - } - } - } - if (nFlags & SIZE_IB) // IB size - { - if (_HasIBStream()) - { - nSize += m_nInds * sizeof(vtx_idx); - } - } - - return nSize; -} - -void CRenderMesh::FreeDeviceBuffers(bool bRestoreSys) -{ - uint32 i; - - for (i = 0; i < VSF_NUM; i++) - { - if (_HasVBStream(i)) - { - if (bRestoreSys) - { - LockForThreadAccess(); - void* pSrc = LockVB(i, FSL_READ | FSL_VIDEO); - void* pDst = LockVB(i, FSL_SYSTEM_CREATE); - cryMemcpy(pDst, pSrc, GetStreamSize(i)); - UnLockForThreadAccess(); - } - ReleaseVB(i); - } - } - - if (_HasIBStream()) - { - if (bRestoreSys) - { - LockForThreadAccess(); - void* pSrc = LockIB(FSL_READ | FSL_VIDEO); - void* pDst = LockIB(FSL_SYSTEM_CREATE); - cryMemcpy(pDst, pSrc, m_nInds * sizeof(vtx_idx)); - UnLockForThreadAccess(); - } - ReleaseIB(); - } -} - -void CRenderMesh::FreeVB(int nStream) -{ - if (SMeshStream* pMS = GetVertexStream(nStream)) - { - if (pMS->m_pUpdateData) - { - FreeMeshData(pMS->m_pUpdateData); - pMS->m_pUpdateData = NULL; - } - } -} - -void CRenderMesh::FreeIB() -{ - if (m_IBStream.m_pUpdateData) - { - FreeMeshData(m_IBStream.m_pUpdateData); - m_IBStream.m_pUpdateData = NULL; - } -} - -void CRenderMesh::FreeSystemBuffers() -{ - uint32 i; - - for (i = 0; i < VSF_NUM; i++) - { - FreeVB(i); - } - FreeIB(); - - FreeMeshData(m_pCachePos); - m_pCachePos = NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::DebugDraw(const struct SGeometryDebugDrawInfo& info, uint32 nVisibleChunksMask, [[maybe_unused]] float fExtrdueScale) -{ - IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); - LockForThreadAccess(); - - const Matrix34& mat = info.tm; - - const bool bNoCull = info.bNoCull; - const bool bNoLines = info.bNoLines; - const bool bExtrude = info.bExtrude; - - SAuxGeomRenderFlags prevRenderFlags = pRenderAuxGeom->GetRenderFlags(); - SAuxGeomRenderFlags renderFlags = prevRenderFlags; - renderFlags.SetDepthWriteFlag(e_DepthWriteOff); - if (bNoCull) - { - renderFlags.SetCullMode(e_CullModeNone); - } - pRenderAuxGeom->SetRenderFlags(renderFlags); - - const ColorB lineColor = info.lineColor; - const ColorB color = info.color; - -#ifdef WIN32 - const unsigned int kMaxBatchSize = 20000; - static std::vector s_vertexBuffer; - static std::vector s_indexBuffer; - s_vertexBuffer.reserve(kMaxBatchSize); - s_indexBuffer.reserve(kMaxBatchSize * 2); - s_vertexBuffer.resize(0); - s_indexBuffer.resize(0); - uint32 currentIndexBase = 0; -#endif - - const int32 chunkCount = m_Chunks.size(); - for (int32 currentChunkIndex = 0; currentChunkIndex < chunkCount; ++currentChunkIndex) - { - const CRenderChunk* pChunk = &m_Chunks[currentChunkIndex]; - - if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE) - { - continue; - } - - if (!((1 << currentChunkIndex) & nVisibleChunksMask)) - { - continue; - } - - int posStride = 1; - const byte* pPositions = GetPosPtr(posStride, FSL_READ); - const vtx_idx* pIndices = GetIndexPtr(FSL_READ); - const uint32 numVertices = GetVerticesCount(); - const uint32 indexStep = 3; - uint32 numIndices = pChunk->nNumIndices; - - // Make sure number of indices is a multiple of 3. - uint32 indexRemainder = numIndices % indexStep; - if (indexRemainder != 0) - { - numIndices -= indexRemainder; - } - - const uint32 firstIndex = pChunk->nFirstIndexId; - const uint32 lastIndex = firstIndex + pChunk->nNumIndices; - - for (uint32 i = firstIndex; i < lastIndex; i += indexStep) - { - int32 I0 = pIndices[ i ]; - int32 I1 = pIndices[ i + 1 ]; - int32 I2 = pIndices[ i + 2 ]; - - assert((uint32)I0 < numVertices); - assert((uint32)I1 < numVertices); - assert((uint32)I2 < numVertices); - - Vec3 v0, v1, v2; - v0 = *(Vec3*)&pPositions[ posStride * I0 ]; - v1 = *(Vec3*)&pPositions[ posStride * I1 ]; - v2 = *(Vec3*)&pPositions[ posStride * I2 ]; - - v0 = mat.TransformPoint(v0); - v1 = mat.TransformPoint(v1); - v2 = mat.TransformPoint(v2); - - if (bExtrude) - { - // Push vertices towards the camera to alleviate z-fighting. - Vec3 cameraPosition = gEnv->pRenderer->GetCamera().GetPosition(); - const float VertexToCameraOffsetAmount = 0.02f; - v0 = Lerp(v0, cameraPosition, VertexToCameraOffsetAmount); - v1 = Lerp(v1, cameraPosition, VertexToCameraOffsetAmount); - v2 = Lerp(v2, cameraPosition, VertexToCameraOffsetAmount); - } - -#ifdef WIN32 - s_vertexBuffer.push_back(v0); - s_vertexBuffer.push_back(v1); - s_vertexBuffer.push_back(v2); - - if (!bNoLines) - { - s_indexBuffer.push_back(currentIndexBase); - s_indexBuffer.push_back(currentIndexBase + 1); - s_indexBuffer.push_back(currentIndexBase + 1); - s_indexBuffer.push_back(currentIndexBase + 2); - s_indexBuffer.push_back(currentIndexBase + 2); - s_indexBuffer.push_back(currentIndexBase); - - currentIndexBase += indexStep; - } - - // Need to limit batch size, because the D3D aux geometry renderer - // can only process 32768 vertices and 65536 indices - const size_t vertexBufferSize = s_vertexBuffer.size(); - const bool bOverLimit = vertexBufferSize > kMaxBatchSize; - const bool bLastTriangle = (i == (lastIndex - indexStep)); - - if (bOverLimit || bLastTriangle) - { - // Draw all triangles of the chunk in one go for better batching - pRenderAuxGeom->DrawTriangles(&s_vertexBuffer[0], s_vertexBuffer.size(), color); - - if (!bNoLines) - { - const size_t indexBufferSize = s_indexBuffer.size(); - pRenderAuxGeom->DrawLines(&s_vertexBuffer[0], vertexBufferSize, &s_indexBuffer[0], indexBufferSize, lineColor); - - s_indexBuffer.resize(0); - currentIndexBase = 0; - } - - s_vertexBuffer.resize(0); - } -#else - pRenderAuxGeom->DrawTriangle(v0, color, v1, color, v2, color); - - if (!bNoLines) - { - pRenderAuxGeom->DrawLine(v0, lineColor, v1, lineColor); - pRenderAuxGeom->DrawLine(v1, lineColor, v2, lineColor); - pRenderAuxGeom->DrawLine(v2, lineColor, v0, lineColor); - } -#endif - } - } - - pRenderAuxGeom->SetRenderFlags(prevRenderFlags); - UnLockForThreadAccess(); -} - - -//=========================================================================================================== -void CRenderMesh::PrintMeshLeaks() -{ - AUTO_LOCK(m_sLinkLock); - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - CRenderMesh* pRM = iter->item<& CRenderMesh::m_Chain>(); - Warning("--- CRenderMesh '%s' leak after level unload", (!pRM->m_sSource.empty() ? pRM->m_sSource.c_str() : "NO_NAME")); - __debugbreak(); - } -} - -bool CRenderMesh::ClearStaleMemory(bool bLocked, int threadId) -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER); - bool cleared = false; - bool bKeepSystem = false; - CConditionalLock lock(m_sLinkLock, !bLocked); - // Clean up the stale mesh temporary data - for (util::list* iter = m_MeshDirtyList[threadId].next, * pos = iter->next; iter != &m_MeshDirtyList[threadId]; iter = pos, pos = pos->next) - { - CRenderMesh* pRM = iter->item<& CRenderMesh::m_Dirty>(threadId); - if (pRM->m_sResLock.TryLock() == false) - { - continue; - } - // If the mesh data is still being read, skip it. The stale data will be picked up at a later point - if (pRM->m_nThreadAccessCounter) - { -# if !defined(_RELEASE) && defined(RM_CATCH_EXCESSIVE_LOCKS) - if (gEnv->pTimer->GetAsyncTime().GetSeconds() - pRM->m_lockTime > 32.f) - { - CryError("data lock for mesh '%s:%s' held longer than 32 seconds", (pRM->m_sType ? pRM->m_sType : "unknown"), (pRM->m_sSource ? pRM->m_sSource : "unknown")); - if (CRenderer::CV_r_BreakOnError) - { - __debugbreak(); - } - } -# endif - goto dirty_done; - } - - bKeepSystem = pRM->m_keepSysMesh; - - if (!bKeepSystem && pRM->m_pCachePos) - { - FreeMeshData(pRM->m_pCachePos); - pRM->m_pCachePos = NULL; - cleared = true; - } - - // In DX11 we cannot lock device buffers efficiently from the MT, - // so we have to keep system copy. On UMA systems we can clear the buffer - // and access VRAM directly - #if BUFFER_ENABLE_DIRECT_ACCESS && !defined(NULL_RENDERER) - if (!bKeepSystem) - { - for (int i = 0; i < VSF_NUM; i++) - { - pRM->FreeVB(i); - } - pRM->FreeIB(); - cleared = true; - } - #endif - - // ToDo: only remove this mesh from the dirty list if no stream contains dirty data anymore - pRM->m_Dirty[threadId].erase(); -dirty_done: - pRM->m_sResLock.Unlock(); - } - - return cleared; -} - -void CRenderMesh::UpdateModifiedMeshes(bool bLocked, int threadId) -{ - AZ_TRACE_METHOD(); - FUNCTION_PROFILER_LEGACYONLY(gEnv->pSystem, PROFILE_RENDERER); - - // - // DX12 synchronizes render mesh updates at this point, because we can - // batch multiple copies together and potentially forward them off - // to a copy command list. - // -#ifdef CRY_USE_DX12 - const bool bBlock = true; -#else - const bool bBlock = gRenDev->m_pRT->m_eVideoThreadMode != SRenderThread::eVTM_Disabled; -#endif - - CConditionalLock lock(m_sLinkLock, !bLocked); - // Update device buffers on modified meshes - for (util::list* iter = m_MeshModifiedList[threadId].next, * pos = iter->next; iter != &m_MeshModifiedList[threadId]; iter = pos, pos = pos->next) - { - CRenderMesh* pRM = iter->item<& CRenderMesh::m_Modified>(threadId); - -#ifdef CRY_USE_DX12 - pRM->m_sResLock.Lock(); - const bool bDoUpdate = true; -#else - if (pRM->m_sResLock.TryLock() == false) - { - continue; - } - const bool bDoUpdate = !pRM->m_nThreadAccessCounter; -#endif - - if (bDoUpdate) - { - if (pRM->SyncAsyncUpdate(gRenDev->m_RP.m_nProcessThreadID, bBlock) == true) - { - // ToDo : - // - mark the mesh to not update itself if depending on how the async update was scheduled - // - returns true if no streams need further processing - if (pRM->RT_CheckUpdate(pRM, VSM_MASK, false, true)) - { - pRM->m_Modified[threadId].erase(); - } - } - } - pRM->m_sResLock.Unlock(); - } -} - -// Mesh garbage collector -void CRenderMesh::UpdateModified() -{ - SRenderThread* pRT = gRenDev->m_pRT; - ASSERT_IS_RENDER_THREAD(pRT); - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - - // Call the update and clear functions with bLocked == true even if the lock - // was previously released in the above scope. The resasoning behind this is - // that only the renderthread can access the below lists as they are double - // buffered. Note: As the Lock/Unlock functions can come from the mainthread - // and from any other thread, they still have guarded against contention! - // The only exception to this is if we have no render thread, as there is no - // double buffering in that case - so always lock. - - UpdateModifiedMeshes(pRT->IsMultithreaded(), threadId); -} - - -// Mesh garbage collector -void CRenderMesh::Tick() -{ - ASSERT_IS_RENDER_THREAD(gRenDev->m_pRT) - const threadID threadId = gRenDev->m_pRT->IsMultithreaded() ? gRenDev->m_RP.m_nProcessThreadID : threadID(1); - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - // Remove deleted meshes from the list completely - bool deleted = false; - { - AUTO_LOCK(m_sLinkLock); - util::list* garbage = &CRenderMesh::m_MeshGarbageList[nFrame & (MAX_RELEASED_MESH_FRAMES - 1)]; - while (garbage != garbage->prev) - { - CRenderMesh* pRM = garbage->next->item<& CRenderMesh::m_Chain>(); - SAFE_DELETE(pRM); - deleted = true; - } - } - // If an instance pool is used, try to reclaim any used pages if there are any - if (deleted && s_MeshPool.m_MeshInstancePool) - { - s_MeshPool.m_MeshInstancePool->Cleanup(); - } - - // Call the clear functions with bLocked == true even if the lock - // was previously released in the above scope. The resasoning behind this is - // that only the renderthread can access the below lists as they are double - // buffered. Note: As the Lock/Unlock functions can come from the mainthread - // and from any other thread, they still have guarded against contention! - - ClearStaleMemory(true, threadId); -} - -void CRenderMesh::Initialize() -{ - InitializePool(); -} - -void CRenderMesh::ShutDown() -{ - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_releaseallresourcesonexit) - { - AUTO_LOCK(m_sLinkLock); - while (&CRenderMesh::m_MeshList != CRenderMesh::m_MeshList.prev) - { - CRenderMesh* pRM = CRenderMesh::m_MeshList.next->item<& CRenderMesh::m_Chain>(); - PREFAST_ASSUME(pRM); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_printmemoryleaks) - { - float fSize = pRM->Size(SIZE_ONLY_SYSTEM) / 1024.0f / 1024.0f; - iLog->Log("Warning: CRenderMesh::ShutDown: RenderMesh leak %s: %0.3fMb", pRM->m_sSource.c_str(), fSize); - } - SAFE_RELEASE_FORCE(pRM); - } - } - new (&CRenderMesh::m_MeshList) util::list(); - new (&CRenderMesh::m_MeshGarbageList) util::list(); - new (&CRenderMesh::m_MeshDirtyList) util::list(); - new (&CRenderMesh::m_MeshModifiedList) util::list(); - - ShutdownPool(); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::KeepSysMesh(bool keep) -{ - m_keepSysMesh = keep; -} - -void CRenderMesh::UnKeepSysMesh() -{ - m_keepSysMesh = false; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::SetVertexContainer(IRenderMesh* pBuf) -{ - if (m_pVertexContainer) - { - ((CRenderMesh*)m_pVertexContainer)->m_lstVertexContainerUsers.Delete(this); - } - - m_pVertexContainer = (CRenderMesh*)pBuf; - - if (m_pVertexContainer && ((CRenderMesh*)m_pVertexContainer)->m_lstVertexContainerUsers.Find(this) < 0) - { - ((CRenderMesh*)m_pVertexContainer)->m_lstVertexContainerUsers.Add(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::AssignChunk(CRenderChunk* pChunk, CREMeshImpl* pRE) -{ - pRE->m_pChunk = pChunk; - pRE->m_pRenderMesh = this; - pRE->m_nFirstIndexId = pChunk->nFirstIndexId; - pRE->m_nNumIndices = pChunk->nNumIndices; - pRE->m_nFirstVertId = pChunk->nFirstVertId; - pRE->m_nNumVerts = pChunk->nNumVerts; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::InitRenderChunk(CRenderChunk& rChunk) -{ - AZ_Assert(rChunk.nNumIndices > 0, "Render chunk must have > 0 indices"); - AZ_Assert(rChunk.nNumVerts > 0, "Render chunk must have > 0 vertices"); - - if (!rChunk.pRE) - { - rChunk.pRE = (CREMeshImpl*) gRenDev->EF_CreateRE(eDATA_Mesh); - rChunk.pRE->m_CustomTexBind[0] = m_nClientTextureBindID; - } - - // update chunk RE - if (rChunk.pRE) - { - AssignChunk(&rChunk, (CREMeshImpl*) rChunk.pRE); - } - AZ_Assert(rChunk.nFirstIndexId + rChunk.nNumIndices <= m_nInds, "First index of the chunk + number of indices for the chunk must be <= the total number of indices for the mesh."); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::SetRenderChunks(CRenderChunk* pInputChunksArray, int nCount, bool bSubObjectChunks) -{ - TRenderChunkArray* pChunksArray = &m_Chunks; - if (bSubObjectChunks) - { - pChunksArray = &m_ChunksSubObjects; - } - - ReleaseRenderChunks(pChunksArray); - - pChunksArray->resize(nCount); - for (int i = 0; i < nCount; i++) - { - CRenderChunk& rChunk = (*pChunksArray)[i]; - rChunk = pInputChunksArray[i]; - InitRenderChunk(rChunk); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderMesh::GarbageCollectSubsetRenderMeshes() -{ - uint32 nFrameID = GetCurrentRenderFrameID(); - m_nLastSubsetGCRenderFrameID = nFrameID; - for (MeshSubSetIndices::iterator it = m_meshSubSetIndices.begin(); it != m_meshSubSetIndices.end(); ) - { - IRenderMesh* pRM = it->second; - if (abs((int)nFrameID - (int)((CRenderMesh*)pRM)->m_nLastRenderFrameID) > DELETE_SUBSET_MESHES_AFTER_NOTUSED_FRAMES) - { - // this mesh not relevant anymore. - it = m_meshSubSetIndices.erase(it); - } - else - { - ++it; - } - } -} - -volatile int* CRenderMesh::SetAsyncUpdateState() -{ - SREC_AUTO_LOCK(m_sResLock); - ASSERT_IS_MAIN_THREAD(gRenDev->m_pRT); - int threadID = gRenDev->m_RP.m_nFillThreadID; - if (m_asyncUpdateStateCounter[threadID] == 0) - { - m_asyncUpdateStateCounter[threadID] = 1; - LockForThreadAccess(); - } - CryInterlockedIncrement(&m_asyncUpdateState[threadID]); - - for (auto& chunk : m_Chunks) - { - if (chunk.pRE) - { - chunk.pRE->mfUpdateFlags(FCEF_DIRTY); - } - } - - return &m_asyncUpdateState[threadID]; -} - -bool CRenderMesh::SyncAsyncUpdate(int threadID, bool block) -{ - // If this mesh is being asynchronously prepared, wait for the job to finish prior to uploading - // the vertices to vram. - SREC_AUTO_LOCK(m_sResLock); - if (m_asyncUpdateStateCounter[threadID]) - { - { - AZ_TRACE_METHOD(); - FRAME_PROFILER_LEGACYONLY("CRenderMesh::SyncAsyncUpdate() sync", gEnv->pSystem, PROFILE_RENDERER); - int iter = 0; - while (m_asyncUpdateState[threadID]) - { - if (!block) - { - return false; - } - CrySleep(iter > 10 ? 1 : 0); - ++iter; - } - } - UnlockStream(VSF_GENERAL); - UnlockStream(VSF_TANGENTS); - UnlockStream(VSF_VERTEX_VELOCITY); -# if ENABLE_NORMALSTREAM_SUPPORT - UnlockStream(VSF_NORMALS); -# endif - UnlockIndexStream(); - m_asyncUpdateStateCounter[threadID] = 0; - UnLockForThreadAccess(); - } - return true; -} - -void CRenderMesh::CreateRemappedBoneIndicesPair(const uint pairGuid, const TRenderChunkArray& Chunks) -{ - SREC_AUTO_LOCK(m_sResLock); - // check already created remapped bone indices - for (size_t i = 0, end = m_RemappedBoneIndices.size(); i < end; ++i) - { - if (m_RemappedBoneIndices[i].guid == pairGuid && m_RemappedBoneIndices[i].refcount) - { - ++m_RemappedBoneIndices[i].refcount; - return; - } - } - - // check already currently in flight remapped bone indices - const int threadId = gRenDev->m_RP.m_nFillThreadID; - for (size_t i = 0, end = m_CreatedBoneIndices[threadId].size(); i < end; ++i) - { - if (m_CreatedBoneIndices[threadId][i].guid == pairGuid) - { - ++m_CreatedBoneIndices[threadId][i].refcount; - return; - } - } - - - IRenderMesh::ThreadAccessLock access_lock(this); - - int32 stride; - vtx_idx* indices = GetIndexPtr(FSL_READ); - uint32 vtxCount = GetVerticesCount(); - std::vector touched(vtxCount, false); - const SVF_W4B_I4S* pIndicesWeights = (SVF_W4B_I4S*)GetHWSkinPtr(stride, FSL_READ); - SVF_W4B_I4S* remappedIndices = new SVF_W4B_I4S[vtxCount]; - - for (size_t j = 0; j < Chunks.size(); ++j) - { - const CRenderChunk& chunk = Chunks[j]; - for (size_t k = chunk.nFirstIndexId; k < chunk.nFirstIndexId + chunk.nNumIndices; ++k) - { - const vtx_idx vIdx = indices[k]; - if (touched[vIdx]) - { - continue; - } - touched[vIdx] = true; -#if 1 - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = pIndicesWeights[vIdx].weights.bcolor[l]; - remappedIndices[vIdx].indices[l] = pIndicesWeights[vIdx].indices[l]; - } -#else - // Sokov: The code below doesn't look really safe/logical: - // 1) Calling CreateRemappedBoneIndicesPair() assumes that bones are used, - // so why to check m_bUsesBones here? Do we have cases when some chunks use bones - // and some others do not use bones? - // 2) There is a risk, that some unaware code uses bones but forgets to - // set m_bUsesBones to 'true' so it leads to killing all linking (see '= 0;'). - if (chunk.m_bUsesBones) - { - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = pIndicesWeights[vIdx].weights.bcolor[l]; - remappedIndices[vIdx].indices[l] = pIndicesWeights[vIdx].indices[l]; - } - } - else - { - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = 0; - remappedIndices[vIdx].indices[l] = 0; - } - } -#endif - } - } - UnlockStream(VSF_HWSKIN_INFO); - UnlockIndexStream(); - - m_CreatedBoneIndices[threadId].push_back(SBoneIndexStreamRequest(pairGuid, remappedIndices)); - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); -} - - -void CRenderMesh::CreateRemappedBoneIndicesPair(const DynArray& arrRemapTable, const uint pairGuid) -{ - SREC_AUTO_LOCK(m_sResLock); - // check already created remapped bone indices - for (size_t i = 0, end = m_RemappedBoneIndices.size(); i < end; ++i) - { - if (m_RemappedBoneIndices[i].guid == pairGuid && m_RemappedBoneIndices[i].refcount) - { - ++m_RemappedBoneIndices[i].refcount; - return; - } - } - - // check already currently in flight remapped bone indices - const int threadId = gRenDev->m_RP.m_nFillThreadID; - for (size_t i = 0, end = m_CreatedBoneIndices[threadId].size(); i < end; ++i) - { - if (m_CreatedBoneIndices[threadId][i].guid == pairGuid) - { - ++m_CreatedBoneIndices[threadId][i].refcount; - return; - } - } - - IRenderMesh::ThreadAccessLock access_lock(this); - - int32 stride; - vtx_idx* const indices = GetIndexPtr(FSL_READ); - uint32 vtxCount = GetVerticesCount(); - std::vector touched(vtxCount, false); - const SVF_W4B_I4S* pIndicesWeights = (const SVF_W4B_I4S*)GetHWSkinPtr(stride, FSL_READ); - SVF_W4B_I4S* remappedIndices = new SVF_W4B_I4S[vtxCount]; - - for (size_t j = 0; j < m_Chunks.size(); ++j) - { - const CRenderChunk& chunk = m_Chunks[j]; - for (size_t k = chunk.nFirstIndexId; k < chunk.nFirstIndexId + chunk.nNumIndices; ++k) - { - const vtx_idx vIdx = indices[k]; - if (touched[vIdx]) - { - continue; - } - touched[vIdx] = true; -#if 1 - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = pIndicesWeights[vIdx].weights.bcolor[l]; - remappedIndices[vIdx].indices[l] = arrRemapTable[pIndicesWeights[vIdx].indices[l]]; - } -#else - // Sokov: The code below doesn't look really safe/logical: - // 1) Calling CreateRemappedBoneIndicesPair() assumes that bones are used, - // so why to check m_bUsesBones here? Do we have cases when some chunks use bones - // and some others do not use bones? - // 2) There is a risk, that some unaware code uses bones but forgets to - // set m_bUsesBones to 'true' so it leads to killing all linking (see '= 0;'). - if (chunk.m_bUsesBones) - { - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = pIndicesWeights[vIdx].weights.bcolor[l]; - remappedIndices[vIdx].indices[l] = arrRemapTable[pIndicesWeights[vIdx].indices[l]]; - } - } - else - { - for (int l = 0; l < 4; ++l) - { - remappedIndices[vIdx].weights.bcolor[l] = 0; - remappedIndices[vIdx].indices[l] = 0; - } - } -#endif - } - } - UnlockStream(VSF_HWSKIN_INFO); - UnlockIndexStream(); - - m_CreatedBoneIndices[threadId].push_back(SBoneIndexStreamRequest(pairGuid, remappedIndices)); - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); -} - -void CRenderMesh::ReleaseRemappedBoneIndicesPair(const uint pairGuid) -{ - if (gRenDev->m_pRT->IsMultithreaded() && gRenDev->m_pRT->IsMainThread(true)) - { - gRenDev->m_pRT->RC_ReleaseRemappedBoneIndices(this, pairGuid); - return; - } - - SREC_AUTO_LOCK(m_sResLock); - size_t deleted = ~0u; - const int threadId = gRenDev->m_RP.m_nProcessThreadID; - bool bFound = false; - - for (size_t i = 0, end = m_RemappedBoneIndices.size(); i < end; ++i) - { - if (m_RemappedBoneIndices[i].guid == pairGuid) - { - bFound = true; - if (--m_RemappedBoneIndices[i].refcount == 0) - { - deleted = i; - break; - } - } - } - - if (deleted != ~0u) - { - m_DeletedBoneIndices[threadId].push_back(pairGuid); - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - } - - // Check for created but not yet remapped bone indices - if (!bFound) - { - for (size_t i = 0, end = m_CreatedBoneIndices[threadId].size(); i < end; ++i) - { - if (m_CreatedBoneIndices[threadId][i].guid == pairGuid) - { - bFound = true; - if (--m_CreatedBoneIndices[threadId][i].refcount == 0) - { - deleted = i; - break; - } - } - } - - if (deleted != ~0u) - { - m_DeletedBoneIndices[threadId].push_back(pairGuid); - RelinkTail(m_Modified[threadId], m_MeshModifiedList[threadId], threadId); - } - } -} -// Notes: Cry's LockForThreadAccess is not locking anything here, it only increments m_nThreadAccessCounter but m_nThreadAccessCounter is not used to block multithreading access to CRenderMesh -// This is dangerous as the name of function suggests a lock but it actually doesn't lock. There might be quite a few misuse of this function and as the result the data is not protected in multithread. -// The system needs a deeper overhauling later. -void CRenderMesh::LockForThreadAccess() -{ - ++m_nThreadAccessCounter; - -# if !defined(_RELEASE) && defined(RM_CATCH_EXCESSIVE_LOCKS) - m_lockTime = (m_lockTime > 0.f) ? m_lockTime : gEnv->pTimer->GetAsyncTime().GetSeconds(); -# endif -} -void CRenderMesh::UnLockForThreadAccess() -{ - --m_nThreadAccessCounter; - if (m_nThreadAccessCounter < 0) - { - __debugbreak(); // if this triggers, a mismatch betweend rendermesh thread access lock/unlock has occured - } -# if !defined(_RELEASE) && defined(RM_CATCH_EXCESSIVE_LOCKS) - m_lockTime = 0.f; -# endif -} -void CRenderMesh::GetPoolStats(SMeshPoolStatistics* stats) -{ - memcpy(stats, &s_MeshPool.m_MeshDataPoolStats, sizeof(SMeshPoolStatistics)); -} - -void* CRenderMesh::operator new(size_t size) -{ - return AllocateMeshInstanceData(size, alignof(CRenderMesh)); -} - -void CRenderMesh::operator delete(void* ptr) -{ - FreeMeshInstanceData(ptr); -} - -#if !defined(NULL_RENDERER) -D3DBuffer* CRenderMesh::_GetD3DVB(int nStream, size_t* offs) const -{ - if (SMeshStream* pMS = GetVertexStream(nStream)) - { - IF (pMS->m_nID != ~0u, 1) - { - return gRenDev->m_DevBufMan.GetD3D(pMS->m_nID, offs); - } - } - return NULL; -} - -D3DBuffer* CRenderMesh::_GetD3DIB(size_t* offs) const -{ - IF (m_IBStream.m_nID != ~0u, 1) - { - return gRenDev->m_DevBufMan.GetD3D(m_IBStream.m_nID, offs); - } - return NULL; -} -#endif - - -void CRenderMesh::BindStreamsToRenderPipeline() -{ -#if !defined(NULL_RENDERER) - CRenderMesh *pRenderMesh = this; - - HRESULT h; - CD3D9Renderer *rd = (CD3D9Renderer*)gRenDev; - CRenderMesh *pRM = pRenderMesh->_GetVertexContainer(); - void* pIB = NULL; - size_t nOffs = 0; - - size_t streamStride[VSF_NUM] = { 0 }; - size_t offset[VSF_NUM] = { 0 }; - const void *pVB[VSF_NUM] = { NULL }; - - pIB = rd->m_DevBufMan.GetD3D(pRenderMesh->GetIBStream(), &nOffs); - pVB[0] = rd->m_DevBufMan.GetD3D(pRM->GetVBStream(VSF_GENERAL), &offset[0]); - h = rd->FX_SetVStream(0, pVB[0], offset[0], pRM->GetStreamStride(VSF_GENERAL)); - - for (int i = 1, mask = 1 << 1; i < VSF_NUM; ++i, mask <<= 1) - { - if (rd->m_RP.m_FlagsStreams_Stream & (mask) && pRM->_HasVBStream(i)) - { - streamStride[i] = pRM->GetStreamStride(i); - pVB[i] = rd->m_DevBufMan.GetD3D(pRM->GetVBStream(i), &offset[i]); - } - } - - for (int i = 1, mask = 1 << 1; i < VSF_NUM; ++i, mask <<= 1) - { - if (rd->m_RP.m_FlagsStreams_Stream & (mask) && pVB[i]) - { - rd->m_RP.m_PersFlags1 |= RBPF1_USESTREAM << i; - h = rd->FX_SetVStream(i, pVB[i], offset[i], streamStride[i]); - } - else if (rd->m_RP.m_PersFlags1 & (RBPF1_USESTREAM << i)) - { - rd->m_RP.m_PersFlags1 &= ~(RBPF1_USESTREAM << i); - h = rd->FX_SetVStream(i, NULL, 0, 0); - } - } - -#ifdef MESH_TESSELLATION_RENDERER - if (CHWShader_D3D::s_pCurInstHS && pRenderMesh->m_adjBuffer.GetShaderResourceView()) - { - // This buffer contains texture coordinates for triangle itself and its neighbors, in total 12 texture coordinates per triangle. - D3DShaderResourceView* SRVs[] = { pRenderMesh->m_adjBuffer.GetShaderResourceView() }; - gcpRendD3D->GetDeviceContext().DSSetShaderResources(15, 1, SRVs); - } -#endif - - // 8 weights skinning. setting the last 4 weights - if (pRenderMesh->m_extraBonesBuffer.GetShaderResourceView()) - { - D3DShaderResourceView* SRVs[] = { pRenderMesh->m_extraBonesBuffer.GetShaderResourceView() }; - gcpRendD3D->GetDeviceContext().VSSetShaderResources(14, 1, SRVs); - } - - assert(pIB); - h = rd->FX_SetIStream(pIB, nOffs, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - -#endif //if !defined(NULL_RENDERER) -} - -bool CRenderMesh::GetRemappedSkinningData([[maybe_unused]] uint32 guid, [[maybe_unused]] CRendElementBase::SGeometryStreamInfo &streamInfo) -{ -#if !defined(NULL_RENDERER) - size_t offset = 0; - const void *pVB = 0; - - for (size_t i = 0, end = m_RemappedBoneIndices.size(); i < end; ++i) - { - CRenderMesh::SBoneIndexStream &stream = m_RemappedBoneIndices[i]; - if (stream.guid != guid) - continue; - if (stream.buffer != ~0u) - { - pVB = gRenDev->m_DevBufMan.GetD3D(stream.buffer, &offset); - streamInfo.nOffset = offset; - streamInfo.nStride = GetStreamStride(VSF_HWSKIN_INFO); - streamInfo.pStream = pVB; - return true; - } - } -#endif //if !defined(NULL_RENDERER) - return m_RemappedBoneIndices.size() == 0u; -} - -bool CRenderMesh::FillGeometryInfo([[maybe_unused]] CRendElementBase::SGeometryInfo &geom) -{ -#if !defined(NULL_RENDERER) - - CRenderMesh *pRenderMeshForVertices = _GetVertexContainer(); - size_t nOffs = 0; - - if (!_HasIBStream()) - return false; - - if (!pRenderMeshForVertices->CanRender()) - return false; - - geom.indexStream.pStream = gRenDev->m_DevBufMan.GetD3D(GetIBStream(), &nOffs); - geom.indexStream.nOffset = nOffs; - geom.indexStream.nStride = (sizeof(vtx_idx) == 2 ? Index16 : Index32); - geom.streamMask = 0; - geom.nMaxVertexStreams = 0; - for (int nStream = 0; nStream < VSF_NUM; ++nStream) - { - if (pRenderMeshForVertices->_HasVBStream(nStream)) - { - nOffs = 0; - geom.vertexStream[nStream].pStream = gRenDev->m_DevBufMan.GetD3D(pRenderMeshForVertices->GetVBStream(nStream), &nOffs); - geom.vertexStream[nStream].nOffset = nOffs; - geom.vertexStream[nStream].nStride = pRenderMeshForVertices->GetStreamStride(nStream); - - if (geom.vertexStream[nStream].pStream) - { - geom.nMaxVertexStreams = nStream + 1; - } - - //geom.streamMask |= 1 << nStream; - } - else - { - geom.vertexStream[nStream].pStream = 0; - geom.vertexStream[nStream].nOffset = 0; - geom.vertexStream[nStream].nStride = 0; - } - } - - if (m_RemappedBoneIndices.size() > 0) - { - if (GetRemappedSkinningData(geom.bonesRemapGUID, geom.vertexStream[VSF_HWSKIN_INFO])) - { - if (geom.nMaxVertexStreams <= VSF_HWSKIN_INFO) - { - geom.nMaxVertexStreams = VSF_HWSKIN_INFO + 1; - } - } - } - - geom.pSkinningExtraBonesBuffer = &m_extraBonesBuffer; - -#ifdef MESH_TESSELLATION_RENDERER - geom.pTessellationAdjacencyBuffer = &m_adjBuffer; -#else - geom.pTessellationAdjacencyBuffer = nullptr; -#endif - -#endif //if !defined(NULL_RENDERER) - - return true; -} - -CThreadSafeRendererContainer CRenderMesh::m_deferredSubsetGarbageCollection[RT_COMMAND_BUF_COUNT]; -CThreadSafeRendererContainer CRenderMesh::m_meshSubSetRenderMeshJobs[RT_COMMAND_BUF_COUNT]; - - -#if RENDERMESH_CPP_TRAIT_BUFFER_ENABLE_DIRECT_ACCESS || defined(CRY_USE_DX12) - #ifdef BUFFER_ENABLE_DIRECT_ACCESS - #undef BUFFER_ENABLE_DIRECT_ACCESS - #define BUFFER_ENABLE_DIRECT_ACCESS 1 - #endif -#endif - diff --git a/Code/CryEngine/RenderDll/Common/RenderMesh.h b/Code/CryEngine/RenderDll/Common/RenderMesh.h deleted file mode 100644 index 2a5f6a1938..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderMesh.h +++ /dev/null @@ -1,613 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __RENDERMESH_H__ -#define __RENDERMESH_H__ - -#include -#include -#include -#include -#include -#include "Shaders/Vertex.h" -#include - -// Enable the below to get fatal error is some holds a rendermesh buffer lock for longer than 1 second -//#define RM_CATCH_EXCESSIVE_LOCKS - -#define DELETE_SUBSET_MESHES_AFTER_NOTUSED_FRAMES 30 - -struct SMeshSubSetIndicesJobEntry -{ - AZ::LegacyJobExecutor jobExecutor; - _smart_ptr m_pSrcRM; // source mesh to create a new index mesh from - _smart_ptr m_pIndexRM; // when finished: newly created index mesh for this mask, else NULL - uint64 m_nMeshSubSetMask; // mask to use - - void CreateSubSetRenderMesh(); -}; - -class RenderMesh_hash_int32 -{ -public: - ILINE size_t operator()(int32 key) const - { - return stl::hash_uint32()((uint32)key); - } -}; - -struct SBufInfoTable -{ - int OffsTC; - int OffsColor; - int OffsNorm; -}; - -struct SMeshStream -{ - buffer_handle_t m_nID; // device buffer handle from device buffer manager - void* m_pUpdateData; // system buffer for updating (used for async. mesh updates) - void* m_pLockedData; // locked device buffer data (hmm, not a good idea to store) - uint32 m_nLockFlags : 16; - uint32 m_nLockCount : 16; - uint32 m_nElements; - int32 m_nFrameAccess; - int32 m_nFrameRequest; - int32 m_nFrameUpdate; - int32 m_nFrameCreate; - - SMeshStream() - { - m_nID = ~0u; - m_pUpdateData = NULL; - m_pLockedData = NULL; - m_nFrameRequest = 0; - m_nFrameUpdate = -1; - m_nFrameAccess = -1; - m_nFrameCreate = -1; - m_nLockFlags = 0; - m_nLockCount = 0; - m_nElements = 0; - } - - ~SMeshStream() { memset(this, 0x0, sizeof(*this)); } -}; - -// CRenderMesh::m_nFlags -#define FRM_RELEASED 1 -#define FRM_DEPRECTATED_FLAG 2 -#define FRM_READYTOUPLOAD 4 -#define FRM_ALLOCFAILURE 8 -#define FRM_SKINNED 0x10 -#define FRM_SKINNEDNEXTDRAW 0x20 // no proper support yet for objects that can be skinned and not skinned. -#define FRM_ENABLE_NORMALSTREAM 0x40 - -#define MAX_RELEASED_MESH_FRAMES (2) - -struct SSetMeshIntData -{ - CMesh* m_pMesh; - char* m_pVBuff; - SPipTangents* m_pTBuff; - SPipQTangents* m_pQTBuff; - SVF_P3F* m_pVelocities; - uint32 m_nVerts; - uint32 m_nInds; - vtx_idx* m_pInds; - uint32 m_flags; - Vec3* m_pNormalsBuff; -}; - - -class CRenderMesh - : public IRenderMesh -{ - friend class CREMeshImpl; - -public: - - static void ClearJobResources(); - -private: - friend class CD3D9Renderer; - - SMeshStream m_IBStream; - SMeshStream* m_VBStream[VSF_NUM]; - struct SBoneIndexStream - { - buffer_handle_t buffer; - uint32 guid; - uint32 refcount; - }; - - struct SBoneIndexStreamRequest - { - SBoneIndexStreamRequest(uint32 _guid, SVF_W4B_I4S* _pStream) - : pStream(_pStream) - , guid(_guid) - , refcount(1) {} - - SVF_W4B_I4S* pStream; - uint32 guid; - uint32 refcount; - }; - - std::vector m_RemappedBoneIndices; - std::vector< SBoneIndexStreamRequest > m_CreatedBoneIndices[2]; - std::vector< uint32 > m_DeletedBoneIndices[2]; - - uint32 m_nInds; - uint32 m_nVerts; - int m_nRefCounter; - AZ::Vertex::Format m_vertexFormat; // Base stream vertex format (optional streams are hardcoded: VSF_) - - Vec3* m_pCachePos; // float positions (cached) - int m_nFrameRequestCachePos; - - std::vector m_UVCache; // float UVs (cached) - int m_nFrameRequestCacheUVs; - - CRenderMesh* m_pVertexContainer; - PodArray m_lstVertexContainerUsers; - -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - typedef AZStd::unordered_map >, RenderMesh_hash_int32> TrisMap; - TrisMap* m_pTrisMap; -#endif - - SRecursiveSpinLock m_sResLock; - - AZStd::atomic m_nThreadAccessCounter;// counter to ensure that no system rendermesh streams are freed since they are in use - volatile int m_asyncUpdateState[2]; - int m_asyncUpdateStateCounter[2]; - - eRenderPrimitiveType m_nPrimetiveType : 8; - ERenderMeshType m_eType : 4; - uint16 m_nFlags : 8; // FRM_ - int16 m_nLod : 4; // used for LOD debug visualization - bool m_keepSysMesh : 1; - bool m_nFlagsCachePos : 1; // only checked for FSL_WRITE, which can be represented as a single bit - bool m_nFlagsCacheUVs : 1; - - - -public: - enum ESizeUsageArg - { - SIZE_ONLY_SYSTEM = 0, - SIZE_VB = 1, - SIZE_IB = 2, - }; - -private: - SMeshStream* GetVertexStream(int nStream, uint32 nFlags = 0); - SMeshStream* GetVertexStream(int nStream, [[maybe_unused]] uint32 nFlags = 0) const { return m_VBStream[nStream]; } - bool UpdateVidIndices(SMeshStream& IBStream, bool stall = true); - - bool CreateVidVertices(int nStream = VSF_GENERAL); - bool UpdateVidVertices(int nStream, bool stall = true); - - bool CopyStreamToSystemForUpdate(SMeshStream& MS, size_t nSize); - - void ReleaseVB(int nStream); - void ReleaseIB(); - - void InitTriHash(_smart_ptr pMaterial); - - bool CreateCachePos(byte* pSrc, uint32 nStrideSrc, uint32 nFlags); - bool PrepareCachePos(); - bool CreateUVCache(byte* pSrc, uint32 nStrideSrc, uint32 nFlags, uint32 uvSetIndex); - - //Internal versions of funcs - no lock - bool UpdateVertices_Int(const void* pVertBuffer, int nVertCount, int nOffset, int nStream, uint32 copyFlags); - bool UpdateIndices_Int(const vtx_idx* pNewInds, int nInds, int nOffsInd, uint32 copyFlags); - size_t SetMesh_Int(CMesh& mesh, int nSecColorsSetOffset, uint32 flags); - -#ifdef MESH_TESSELLATION_RENDERER - template - bool UpdateUVCoordsAdjacency(SMeshStream& IBStream, const AZ::Vertex::Format& vertexFormat); - - template - static void BuildAdjacency(const byte* pVerts, const AZ::Vertex::Format& vertexFormat, uint nVerts, const vtx_idx* pIndexBuffer, uint nTrgs, std::vector& pTxtAdjBuffer); -#endif - - void Cleanup(); - -public: - - void AddShadowPassMergedChunkIndicesAndVertices(CRenderChunk* pCurrentChunk, _smart_ptr pMaterial, int& rNumVertices, int& rNumIndices); - static bool RenderChunkMergeAbleInShadowPass(CRenderChunk* pPreviousChunk, CRenderChunk* pCurrentChunk, _smart_ptr pMaterial); - - inline void PrefetchVertexStreams() const - { - for (int i = 0; i < VSF_NUM; CryPrefetch(m_VBStream[i++])) - { - ; - } - } - - void SetMesh_IntImpl(SSetMeshIntData data); - - //! constructor - //! /param szSource this pointer is stored - make sure the memory stays - CRenderMesh(const char* szType, const char* szSourceName, bool bLock = false); - CRenderMesh(); - - //! destructor - ~CRenderMesh(); - - virtual bool CanRender(){return (m_nFlags & FRM_ALLOCFAILURE) == 0; } - - virtual void AddRef() - { -# if !defined(_RELEASE) - if (m_nFlags & FRM_RELEASED) - { - CryFatalError("CRenderMesh::AddRef() mesh already in the garbage list (resurrecting deleted mesh)"); - } -# endif - CryInterlockedIncrement(&m_nRefCounter); - } - virtual int Release(); - void ReleaseForce() - { - while (true) - { - int nRef = Release(); - if (nRef <= 0) - { - return; - } - } - } - - // ---------------------------------------------------------------- - // Helper functions - _inline int GetStreamStride(int nStream) const override - { - if (nStream == VSF_GENERAL) - { - return m_vertexFormat.GetStride(); - } - else - { - return m_cSizeStream[nStream]; - } - } - - _inline uint32 _GetFlags() const { return m_nFlags; } - _inline int GetStreamSize(int nStream, int nVerts = 0) const { return GetStreamStride(nStream) * (nVerts ? nVerts : m_nVerts); } - _inline const buffer_handle_t GetVBStream(int nStream) const - { - if (!m_VBStream[nStream]) - { - return ~0u; - } - return m_VBStream[nStream]->m_nID; - } - _inline const buffer_handle_t GetIBStream() const { return m_IBStream.m_nID; } - _inline bool _HasVBStream(int nStream) const { return m_VBStream[nStream] && m_VBStream[nStream]->m_nID != ~0u; } - _inline bool _HasIBStream() const { return m_IBStream.m_nID != ~0u; } - _inline int _IsVBStreamLocked(int nStream) const - { - if (!m_VBStream[nStream]) - { - return 0; - } - return (m_VBStream[nStream]->m_nLockFlags & FSL_LOCKED); - } - _inline int _IsIBStreamLocked() const { return m_IBStream.m_nLockFlags & FSL_LOCKED; } - _inline AZ::Vertex::Format _GetVertexFormat() const { return m_vertexFormat; } - _inline void _SetVertexFormat(const AZ::Vertex::Format& vertexFormat) { m_vertexFormat = vertexFormat; } - _inline int GetNumVerts() const override { return m_nVerts; } - _inline void _SetNumVerts(int nVerts) { m_nVerts = max(nVerts, 0); } - _inline int GetNumInds() const override { return m_nInds; } - _inline void _SetNumInds(int nInds) { m_nInds = nInds; } - _inline const eRenderPrimitiveType GetPrimitiveType() const override { return m_nPrimetiveType; } - _inline void _SetPrimitiveType(const eRenderPrimitiveType nPrimType) { m_nPrimetiveType = nPrimType; } - _inline void _SetRenderMeshType(ERenderMeshType eType) { m_eType = eType; } - _inline CRenderMesh* _GetVertexContainer() - { - if (m_pVertexContainer) - { - return m_pVertexContainer; - } - return this; - } -# if !defined(NULL_RENDERER) - D3DBuffer* _GetD3DVB(int nStream, size_t* offs) const; - D3DBuffer* _GetD3DIB(size_t* offs) const; -# endif - - size_t Size(uint32 nFlags) const; - void Size(uint32 nFlags, ICrySizer* pSizer) const; - - void* LockVB(int nStream, uint32 nFlags, int nVerts = 0, int* nStride = NULL, bool prefetchIB = false, bool inplaceCachePos = false); - - template - T* GetStridedArray(strided_pointer& arr, EStreamIDs stream) - { - arr.data = (T*)LockVB(stream, FSL_READ, 0, &arr.iStride); - assert(!arr.data || arr.iStride >= sizeof(T)); - return arr.data; - } - - vtx_idx* LockIB(uint32 nFlags, int nOffset = 0, int nInds = 0); - void UnlockVB(int nStream); - void UnlockIB(); - - bool RT_CheckUpdate(CRenderMesh* pVContainer, uint32 nStreamMask, bool bTessellation = false, bool stall = true); - void RT_SetMeshCleanup(); - void RT_AllocationFailure(const char* sPurpose, uint32 nSize); - bool CheckUpdate(uint32 nStreamMask) override; - void AssignChunk(CRenderChunk * pChunk, class CREMeshImpl * pRE); - void InitRenderChunk(CRenderChunk& rChunk); - - void FreeVB(int nStream); - void FreeIB(); - void FreeDeviceBuffers(bool bRestoreSys); - void FreeSystemBuffers(); - void FreePreallocatedData(); - - bool SyncAsyncUpdate(int threadId, bool block = true); - - //=========================================================================================== - // IRenderMesh interface - virtual const char* GetTypeName() { return m_sType; } - virtual const char* GetSourceName() const { return m_sSource; } - - virtual int GetIndicesCount() { return m_nInds; } - virtual int GetVerticesCount() { return m_nVerts; } - - virtual AZ::Vertex::Format GetVertexFormat() { return m_vertexFormat; } - virtual ERenderMeshType GetMeshType() { return m_eType; } - - virtual void SetSkinned(bool bSkinned = true) override - { - if (bSkinned) - { - m_nFlags |= FRM_SKINNED; - } - else - { - m_nFlags &= ~FRM_SKINNED; - } - }; - virtual uint GetSkinningWeightCount() const override; - - virtual float GetGeometricMeanFaceArea() const{ return m_fGeometricMeanFaceArea; } - - virtual void NextDrawSkinned() { m_nFlags |= FRM_SKINNEDNEXTDRAW; } - - virtual void GenerateQTangents(); - virtual void CreateChunksSkinned(); - virtual void CopyTo(IRenderMesh* pDst, int nAppendVtx = 0, bool bDynamic = false, bool fullCopy = true); - virtual void SetSkinningDataVegetation(struct SMeshBoneMapping_uint8* pBoneMapping); - virtual void SetSkinningDataCharacter(CMesh& mesh, struct SMeshBoneMapping_uint16* pBoneMapping, struct SMeshBoneMapping_uint16* pExtraBoneMapping); - // Creates an indexed mesh from this render mesh (accepts an optional pointer to an IIndexedMesh object that should be used) - virtual IIndexedMesh* GetIndexedMesh(IIndexedMesh* pIdxMesh = 0); - virtual int GetRenderChunksCount(_smart_ptr pMat, int& nRenderTrisCount); - - virtual IRenderMesh* GenerateMorphWeights() { return NULL; } - virtual IRenderMesh* GetMorphBuddy() { return NULL; } - virtual void SetMorphBuddy([[maybe_unused]] IRenderMesh* pMorph) {} - - // Create render buffers from render mesh. Returns the final size of the render mesh or ~0U on failure - virtual size_t SetMesh(CMesh& mesh, int nSecColorsSetOffset, uint32 flags, bool requiresLock); - - // Update system vertices buffer - virtual bool UpdateVertices(const void* pVertBuffer, int nVertCount, int nOffset, int nStream, uint32 copyFlags, bool requiresLock = true); - // Update system indices buffer - virtual bool UpdateIndices(const vtx_idx* pNewInds, int nInds, int nOffsInd, uint32 copyFlags, bool requiresLock = true); - - virtual void SetCustomTexID(int nCustomTID); - virtual void SetChunk(int nIndex, CRenderChunk& chunk); - virtual void SetChunk(_smart_ptr pNewMat, int nFirstVertId, int nVertCount, int nFirstIndexId, int nIndexCount, float texelAreaDensity, const AZ::Vertex::Format& vertexFormat, int nMatID = 0); - - virtual void SetRenderChunks(CRenderChunk* pChunksArray, int nCount, bool bSubObjectChunks); - - virtual TRenderChunkArray& GetChunks() { return m_Chunks; } - virtual TRenderChunkArray& GetChunksSkinned() { return m_ChunksSkinned; } - virtual TRenderChunkArray& GetChunksSubObjects() { return m_ChunksSubObjects; } - virtual IRenderMesh* GetVertexContainer() { return _GetVertexContainer(); } - virtual void SetVertexContainer(IRenderMesh* pBuf); - - virtual void Render(const struct SRendParams& rParams, CRenderObject* pObj, _smart_ptr pMaterial, const SRenderingPassInfo& passInfo, bool bSkinned = false); - virtual void Render(CRenderObject* pObj, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - virtual void AddRenderElements(_smart_ptr pIMatInfo, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nSortId = EFSLIST_GENERAL, int nAW = 1); - virtual void SetREUserData(float* pfCustomData, float fFogScale = 0, float fAlpha = 1); - virtual void AddRE(_smart_ptr pMaterial, CRenderObject* pObj, IShader* pEf, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter); - - virtual void DrawImmediately(); - - virtual byte* GetPosPtrNoCache(int32& nStride, uint32 nFlags); - virtual byte* GetPosPtr(int32& nStride, uint32 nFlags); - virtual byte* GetNormPtr(int32& nStride, uint32 nFlags); - virtual byte* GetColorPtr(int32& nStride, uint32 nFlags); - virtual byte* GetUVPtrNoCache(int32& nStride, uint32 nFlags, uint32 uvSetIndex = 0); - virtual byte* GetUVPtr(int32& nStride, uint32 nFlags, uint32 uvSetIndex = 0); - - virtual byte* GetTangentPtr(int32& nStride, uint32 nFlags); - virtual byte* GetQTangentPtr(int32& nStride, uint32 nFlags); - - virtual byte* GetHWSkinPtr(int32& nStride, uint32 nFlags, bool remapped = false); - virtual byte* GetVelocityPtr(int32& nStride, uint32 nFlags); - - virtual void UnlockStream(int nStream); - virtual void UnlockIndexStream(); - - virtual vtx_idx* GetIndexPtr(uint32 nFlags, int32 nOffset = 0); - virtual const PodArray >* GetTrisForPosition(const Vec3& vPos, _smart_ptr pMaterial); - virtual float GetExtent(EGeomForm eForm); - virtual void GetRandomPos(PosNorm& ran, EGeomForm eForm, SSkinningData const* pSkinning = NULL); - virtual uint32* GetPhysVertexMap() { return NULL; } - virtual bool IsEmpty(); - - virtual size_t GetMemoryUsage(ICrySizer* pSizer, EMemoryUsageArgument nType) const; - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual float GetAverageTrisNumPerChunk(_smart_ptr pMat); - virtual int GetTextureMemoryUsage(const _smart_ptr pMaterial, ICrySizer* pSizer = NULL, bool bStreamedIn = true) const; - // Get allocated only in video memory or only in system memory. - virtual int GetAllocatedBytes(bool bVideoMem) const; - - virtual void SetBBox(const Vec3& vBoxMin, const Vec3& vBoxMax) { m_vBoxMin = vBoxMin; m_vBoxMax = vBoxMax; } - virtual void GetBBox(Vec3& vBoxMin, Vec3& vBoxMax) { vBoxMin = m_vBoxMin; vBoxMax = m_vBoxMax; }; - virtual void UpdateBBoxFromMesh(); - - // Debug draw this render mesh. - virtual void DebugDraw(const struct SGeometryDebugDrawInfo& info, uint32 nVisibleChunksMask = ~0, float fExtrdueScale = 0.01f); - virtual void KeepSysMesh(bool keep); - virtual void UnKeepSysMesh(); - virtual void LockForThreadAccess(); - virtual void UnLockForThreadAccess(); - - virtual void SetMeshLod(int nLod) { m_nLod = nLod; } - - virtual volatile int* SetAsyncUpdateState(); - void CreateRemappedBoneIndicesPair(const uint pairGuid, const TRenderChunkArray& Chunks); - virtual void CreateRemappedBoneIndicesPair(const DynArray& arrRemapTable, const uint pairGuid); - virtual void ReleaseRemappedBoneIndicesPair(const uint pairGuid); - - virtual void OffsetPosition(const Vec3& delta) { m_vBoxMin += delta; m_vBoxMax += delta; } - - IRenderMesh* GetRenderMeshForSubsetMask(SRenderObjData* pOD, uint64 nMeshSubSetMask, _smart_ptr pMaterial, const SRenderingPassInfo& passInfo); - void GarbageCollectSubsetRenderMeshes(); - void CreateSubSetRenderMesh(); - - void ReleaseRenderChunks(TRenderChunkArray* pChunks); - - void BindStreamsToRenderPipeline(); - - bool GetRemappedSkinningData(uint32 guid, CRendElementBase::SGeometryStreamInfo &streamInfo); - bool FillGeometryInfo(CRendElementBase::SGeometryInfo &geomInfo); - - // -------------------------------------------------------------- - // Members - - static int32 m_cSizeStream[VSF_NUM]; - - // When modifying or traversing any of the lists below, be sure to always hold the link lock - static CryCriticalSection m_sLinkLock; - - // intrusive list entries - a mesh can be in multiple lists at the same time - util::list m_Chain; // mesh will either be in the mesh list or garbage mesh list - util::list m_Dirty[2]; // if linked, mesh has volatile data (data read back from vram) - util::list m_Modified[2]; // if linked, mesh has modified data (to be uploaded to vram) - - // The static list heads, corresponds to the entries above - static util::list m_MeshList; - static util::list m_MeshGarbageList[MAX_RELEASED_MESH_FRAMES]; - static util::list m_MeshDirtyList[2]; - static util::list m_MeshModifiedList[2]; - - TRenderChunkArray m_Chunks; - TRenderChunkArray m_ChunksSubObjects; // Chunks of sub-objects. - TRenderChunkArray m_ChunksSkinned; - - int m_nClientTextureBindID; - Vec3 m_vBoxMin; - Vec3 m_vBoxMax; - - float m_fGeometricMeanFaceArea; - CGeomExtents m_Extents; - - // Frame id when this render mesh was last rendered. - uint32 m_nLastRenderFrameID; - uint32 m_nLastSubsetGCRenderFrameID; - - string m_sType; //!< pointer to the type name in the constructor call - string m_sSource; //!< pointer to the source name in the constructor call - - // For debugging purposes to catch longstanding data accesses -# if !defined(_RELEASE) && defined(RM_CATCH_EXCESSIVE_LOCKS) - AZStd::atomic m_lockTime; -# endif - - typedef VectorMap > MeshSubSetIndices; - MeshSubSetIndices m_meshSubSetIndices; - - static TSRC_ALIGN CThreadSafeRendererContainer m_meshSubSetRenderMeshJobs[RT_COMMAND_BUF_COUNT]; - static TSRC_ALIGN CThreadSafeRendererContainer m_deferredSubsetGarbageCollection[RT_COMMAND_BUF_COUNT]; - -#ifdef RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT - CryCriticalSection m_getTrisForPositionLock; -#endif - -#if !defined(NULL_RENDERER) - WrappedDX11Buffer m_extraBonesBuffer; -#ifdef MESH_TESSELLATION_RENDERER - WrappedDX11Buffer m_adjBuffer; // buffer containing adjacency information to fix displacement seams -#endif -#endif - - static void Initialize(); - static void ShutDown(); - static void Tick(); - static void UpdateModified(); - static void UpdateModifiedMeshes(bool bLocked, int threadId); - static bool ClearStaleMemory(bool bLocked, int threadId); - static void PrintMeshLeaks(); - static void GetPoolStats(SMeshPoolStatistics* stats); - - void* operator new(size_t size); - void operator delete(void* ptr); - - static void FinalizeRendItems(int nThreadID); -}; - -////////////////////////////////////////////////////////////////////// -// General VertexBuffer created by CreateVertexBuffer() function -class CVertexBuffer -{ -public: - CVertexBuffer() - { - m_nVerts = 0; - } - CVertexBuffer(void* pData, const AZ::Vertex::Format& vertexFormat, int nVerts = 0) - { - m_VS.m_pLocalData = pData; - m_vertexFormat = vertexFormat; - m_nVerts = nVerts; - } -#ifdef _RENDERER - ~CVertexBuffer(); -#endif - - SBufferStream m_VS; - AZ::Vertex::Format m_vertexFormat; - int32 m_nVerts; -}; - -class CIndexBuffer -{ -public: - CIndexBuffer() - { - m_nInds = 0; - } - - CIndexBuffer(uint16* pData) - { - m_VS.m_pLocalData = pData; - m_nInds = 0; - } -#ifdef _RENDERER - ~CIndexBuffer(); -#endif - - SBufferStream m_VS; - int32 m_nInds; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RENDERMESH_H diff --git a/Code/CryEngine/RenderDll/Common/RenderMesh_Render.cpp b/Code/CryEngine/RenderDll/Common/RenderMesh_Render.cpp deleted file mode 100644 index 634a6eb8d0..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderMesh_Render.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include - -#include "RenderMesh.h" - -#include "PostProcess/PostEffects.h" - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -namespace -{ - inline uint32 GetCurrentRenderFrameID(const SRenderingPassInfo& passInfo) - { - return gRenDev->m_RP.m_TI[passInfo.ThreadID()].m_nFrameUpdateID; - }; -} - - -/////////////////////////////////////////////////////////////////////////////// -void CRenderMesh::Render(CRenderObject* pObj, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - _smart_ptr pMaterial = pObj->m_pCurrMaterial; - - if (!pMaterial || !m_nVerts || !m_nInds || m_Chunks.empty() || (m_nFlags & FRM_ALLOCFAILURE) != 0) - { - return; - } - - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_RENDERER, g_bProfilerEnabled); - - IF (!CanRender(), 0) - { - return; - } - - CRenderer* __restrict rd = gRenDev; - bool bSkinned = (GetChunksSkinned().size() && (pObj->m_ObjFlags & (FOB_SKINNED))); - - uint64 nMeshSubSetMask = 0; -#if !defined(_RELEASE) - const char* szExcl = CRenderer::CV_r_excludemesh->GetString(); - if (szExcl[0] && m_sSource) - { - char szMesh[1024]; - cry_strcpy(szMesh, this->m_sSource); - azstrlwr(szMesh, AZ_ARRAY_SIZE(szMesh)); - if (szExcl[0] == '!') - { - if (!strstr(&szExcl[1], m_sSource)) - { - return; - } - } - else - if (strstr(szExcl, m_sSource)) - { - return; - } - } -#endif - - if (rd->m_pDefaultMaterial && pMaterial) - { - pMaterial = rd->m_pDefaultMaterial; - } - - assert(pMaterial); - - if (!pMaterial) - { - return; - } - - m_nLastRenderFrameID = GetCurrentRenderFrameID(passInfo); - - ////////////////////////////////////////////////////////////////////////// - if (!m_meshSubSetIndices.empty() && abs((int)m_nLastRenderFrameID - (int)m_nLastSubsetGCRenderFrameID) > DELETE_SUBSET_MESHES_AFTER_NOTUSED_FRAMES) - { - m_deferredSubsetGarbageCollection[passInfo.ThreadID()].push_back(this); - } - - ////////////////////////////////////////////////////////////////////////// - bool bRenderBreakableWithMultipleDrawCalls = false; - if (pObj->m_ObjFlags & FOB_MESH_SUBSET_INDICES && m_nVerts >= 3) - { - SRenderObjData* pOD = pObj->GetObjData(); - if (pOD) - { - if (pOD->m_nSubObjHideMask != 0) - { - IRenderMesh* pRM = GetRenderMeshForSubsetMask(pOD, pOD->m_nSubObjHideMask, pMaterial, passInfo); - // if pRM is null, it means that this subset rendermesh is not computed yet, thus we render it with multiple draw calls - if (pRM) - { - static_cast(pRM)->CRenderMesh::Render(pObj, passInfo, rendItemSorter); - pOD->m_nSubObjHideMask = 0; - return; - } - // compute the needed mask - const uint32 ni = m_ChunksSubObjects.size(); - nMeshSubSetMask = pOD->m_nSubObjHideMask & (((uint64)1 << ni) - 1); - pOD->m_nSubObjHideMask = 0; - bRenderBreakableWithMultipleDrawCalls = true; - } - } - } - - int nList = EFSLIST_GENERAL; - - const int nAW = (pObj->m_ObjFlags & FOB_AFTER_WATER) || (pObj->m_ObjFlags & FOB_NEAREST) ? 1 : 0; - - ////////////// - if (gRenDev->CV_r_MotionVectors && passInfo.IsGeneralPass() && ((pObj->m_ObjFlags & FOB_DYNAMIC_OBJECT) != 0)) - { - CMotionBlur::SetupObject(pObj, passInfo); - } - - TRenderChunkArray* pChunks = bSkinned ? &m_ChunksSkinned : &m_Chunks; - // for rendering with multiple drawcalls, use ChunksSubObjects - if (bRenderBreakableWithMultipleDrawCalls) - { - pChunks = &m_ChunksSubObjects; - } - - const uint32 ni = (uint32)pChunks->size(); - - CRenderChunk* pPrevChunk = NULL; - for (uint32 i = 0; i < ni; i++) - { - CRenderChunk* pChunk = &pChunks->at(i); - CRendElementBase* __restrict pREMesh = pChunk->pRE; - - SShaderItem& ShaderItem = pMaterial->GetShaderItem(pChunk->m_nMatID); - CShaderResources* pR = (CShaderResources*)ShaderItem.m_pShaderResources; - CShader* __restrict pS = (CShader*)ShaderItem.m_pShader; - - if (pR && pR->IsDeforming()) - { - pObj->m_ObjFlags |= FOB_MOTION_BLUR; - } - - // don't render this chunk if the hide mask for it is set - if (bRenderBreakableWithMultipleDrawCalls && (nMeshSubSetMask & ((uint64)1 << pChunk->nSubObjectIndex))) - { - goto SkipChunk; - } - - if (pREMesh == NULL || pS == NULL || pR == NULL) - { - goto SkipChunk; - } - - if (pS->m_Flags2 & EF2_NODRAW) - { - goto SkipChunk; - } - - if (passInfo.IsShadowPass() && (pR->m_ResFlags & MTL_FLAG_NOSHADOW)) - { - goto SkipChunk; - } - - if (passInfo.IsShadowPass() && !passInfo.IsDisableRenderChunkMerge() && CRenderMesh::RenderChunkMergeAbleInShadowPass(pPrevChunk, pChunk, pMaterial)) - { - continue; // skip the merged chunk, but keep the PrevChunkReference for further merging - } - PrefetchLine(pREMesh, 0); - PrefetchLine(pObj, 0); - rd->EF_AddEf_NotVirtual(pREMesh, ShaderItem, pObj, passInfo, nList, nAW, rendItemSorter); - - pPrevChunk = pChunk; - continue; -SkipChunk: - pPrevChunk = NULL; - } -} - -void CRenderMesh::AddShadowPassMergedChunkIndicesAndVertices(CRenderChunk* pCurrentChunk, _smart_ptr pMaterial, int& rNumVertices, int& rNumIndices) -{ - if (m_Chunks.size() == 0) - { - return; - } - - if (gRenDev->m_RP.m_pCurObject->m_ObjFlags & (FOB_SKINNED)) - { - return; - } - - if (pMaterial == NULL) - { - return; - } - - AUTO_LOCK(pMaterial->GetSubMaterialResizeLock()); - for (uint32 i = (uint32)(pCurrentChunk - &m_Chunks[0]) + 1; i < (uint32)m_Chunks.size(); ++i) - { - if (!CRenderMesh::RenderChunkMergeAbleInShadowPass(pCurrentChunk, &m_Chunks[i], pMaterial)) - { - return; - } - - rNumVertices += m_Chunks[i].nNumVerts; - rNumIndices += m_Chunks[i].nNumIndices; - } -} - -bool CRenderMesh::RenderChunkMergeAbleInShadowPass(CRenderChunk* pPreviousChunk, CRenderChunk* pCurrentChunk, _smart_ptr pMaterial) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_MergeShadowDrawcalls) - { - return false; - } - - if (pPreviousChunk == NULL || pCurrentChunk == NULL || pMaterial == NULL) - { - return false; - } - - SShaderItem& rCurrentShaderItem = pMaterial->GetShaderItem(pCurrentChunk->m_nMatID); - SShaderItem& rPreviousShaderItem = pMaterial->GetShaderItem(pPreviousChunk->m_nMatID); - - CShaderResources* pCurrentShaderResource = (CShaderResources*)rCurrentShaderItem.m_pShaderResources; - CShaderResources* pPreviousShaderResource = (CShaderResources*)rPreviousShaderItem.m_pShaderResources; - - CShader* pCurrentShader = (CShader*)rCurrentShaderItem.m_pShader; - CShader* pPreviousShader = (CShader*)rPreviousShaderItem.m_pShader; - - if (!pCurrentShaderResource || !pPreviousShaderResource || !pCurrentShader || !pPreviousShader) - { - return false; - } - - bool bCurrentAlphaTested = pCurrentShaderResource->CShaderResources::IsAlphaTested(); - bool bPreviousAlphaTested = pPreviousShaderResource->CShaderResources::IsAlphaTested(); - - if (bCurrentAlphaTested != bPreviousAlphaTested) - { - return false; - } - - if (bCurrentAlphaTested) - { - const SEfResTexture* pCurrentResTex = pCurrentShaderResource->GetTextureResource(EFTT_DIFFUSE); - const SEfResTexture* pPreviousResTex = pPreviousShaderResource->GetTextureResource(EFTT_DIFFUSE); - - const CTexture* pCurrentDiffuseTex = pCurrentResTex ? pCurrentResTex->m_Sampler.m_pTex : nullptr; - const CTexture* pPreviousDiffuseTex = pPreviousResTex ? pPreviousResTex->m_Sampler.m_pTex : nullptr; - - if (pCurrentDiffuseTex != pPreviousDiffuseTex) - { - return false; - } - } - - if (((pPreviousShaderResource->m_ResFlags & MTL_FLAG_NOSHADOW) != 0) || ((pCurrentShaderResource->m_ResFlags & MTL_FLAG_NOSHADOW) != 0)) - { - return false; - } - - if ((pPreviousShaderResource->m_ResFlags & MTL_FLAG_2SIDED) != (pCurrentShaderResource->m_ResFlags & MTL_FLAG_2SIDED)) - { - return false; - } - - if (((pPreviousShader->m_Flags & EF_NODRAW) != 0) || ((pCurrentShader->m_Flags & EF_NODRAW) != 0)) - { - return false; - } - - return true; -} - -// break-ability support -IRenderMesh* CRenderMesh::GetRenderMeshForSubsetMask([[maybe_unused]] SRenderObjData* pOD, uint64 nMeshSubSetMask, _smart_ptr pMaterial, const SRenderingPassInfo& passInfo) -{ - // TODO: If only one bit is set in mask - there is no need to build new index buffer - small part of main index buffer can be re-used - // TODO: Add auto releasing of not used for long time index buffers - // TODO: Take into account those induces when computing render mesh memory size for CGF streaming - // TODO: Support for multiple materials - - assert(nMeshSubSetMask != 0); - - IRenderMesh* pSrcRM = this; - TRenderChunkArray& renderChunks = m_ChunksSubObjects; - - uint32 nChunkCount = renderChunks.size(); - nMeshSubSetMask &= (((uint64)1 << nChunkCount) - 1); - - // try to find the index mesh in the already finished list - const MeshSubSetIndices::iterator meshSubSet = m_meshSubSetIndices.find(nMeshSubSetMask); - - if (meshSubSet != m_meshSubSetIndices.end()) - { - return meshSubSet->second; - } - - // subset mesh was not found, start job to create one - SMeshSubSetIndicesJobEntry* pSubSetJob = m_meshSubSetRenderMeshJobs[passInfo.ThreadID()].push_back_new(); - pSubSetJob->m_pSrcRM = pSrcRM; - pSubSetJob->m_pIndexRM = NULL; - pSubSetJob->m_nMeshSubSetMask = nMeshSubSetMask; - - pSubSetJob->jobExecutor.StartJob([pSubSetJob]() - { - pSubSetJob->CreateSubSetRenderMesh(); - }); // Legacy JobManager used SJobState::SetBlocking - - return NULL; -} - -void CRenderMesh::FinalizeRendItems(int nThreadID) -{ - // perform all requiered garbage collections - m_deferredSubsetGarbageCollection[nThreadID].CoalesceMemory(); - for (size_t i = 0; i < m_deferredSubsetGarbageCollection[nThreadID].size(); ++i) - { - if (m_deferredSubsetGarbageCollection[nThreadID][i]) - { - m_deferredSubsetGarbageCollection[nThreadID][i]->GarbageCollectSubsetRenderMeshes(); - } - } - m_deferredSubsetGarbageCollection[nThreadID].resize(0); - - // add all newly generated subset meshes - bool bJobsStillRunning = false; - size_t nNumSubSetRenderMeshJobs = m_meshSubSetRenderMeshJobs[nThreadID].size(); - for (size_t i = 0; i < nNumSubSetRenderMeshJobs; ++i) - { - SMeshSubSetIndicesJobEntry& rSubSetJob = m_meshSubSetRenderMeshJobs[nThreadID][i]; - if (rSubSetJob.jobExecutor.IsRunning()) - { - bJobsStillRunning = true; - } - else if (rSubSetJob.m_pSrcRM) // finished job, which needs to be assigned - { - CRenderMesh* pSrcMesh = static_cast(rSubSetJob.m_pSrcRM.get()); - // check that we didn't create the same subset mesh twice, if we did, clean up the duplicate - if (pSrcMesh->m_meshSubSetIndices.find(rSubSetJob.m_nMeshSubSetMask) == pSrcMesh->m_meshSubSetIndices.end()) - { - pSrcMesh->m_meshSubSetIndices.insert(std::make_pair(rSubSetJob.m_nMeshSubSetMask, rSubSetJob.m_pIndexRM)); - } - - // mark job as assigned - rSubSetJob.m_pIndexRM = NULL; - rSubSetJob.m_pSrcRM = NULL; - } - } - if (!bJobsStillRunning) - { - m_meshSubSetRenderMeshJobs[nThreadID].resize(0); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CRenderMesh::ClearJobResources() -{ - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (size_t j = 0; j < m_deferredSubsetGarbageCollection[i].size(); ++j) - { - if (m_deferredSubsetGarbageCollection[i][j]) - { - m_deferredSubsetGarbageCollection[i][j]->GarbageCollectSubsetRenderMeshes(); - } - } - stl::free_container(m_deferredSubsetGarbageCollection[i]); - - for (size_t j = 0; j < m_deferredSubsetGarbageCollection[i].size(); ++j) - { - m_meshSubSetRenderMeshJobs[i][j].jobExecutor.WaitForCompletion(); - } - stl::free_container(m_meshSubSetRenderMeshJobs[i]); - } -} - -void SMeshSubSetIndicesJobEntry::CreateSubSetRenderMesh() -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - CRenderMesh* pSrcMesh = static_cast(m_pSrcRM.get()); - - TRenderChunkArray& renderChunks = pSrcMesh->m_ChunksSubObjects; - uint32 nChunkCount = renderChunks.size(); - - - pSrcMesh->LockForThreadAccess(); - if (vtx_idx* pInds = pSrcMesh->GetIndexPtr(FSL_READ)) - { - TRenderChunkArray newChunks; - newChunks.reserve(3); - - int nMatId = -1; - PodArray lstIndices; - for (uint32 c = 0; c < nChunkCount; c++) - { - CRenderChunk& srcChunk = renderChunks[c]; - if (0 == (m_nMeshSubSetMask & ((uint64)1 << srcChunk.nSubObjectIndex))) - { - uint32 nLastIndex = lstIndices.size(); - lstIndices.AddList(&pInds[srcChunk.nFirstIndexId], srcChunk.nNumIndices); - if (newChunks.empty() || nMatId != srcChunk.m_nMatID) - { - // New chunk needed. - newChunks.push_back(srcChunk); - newChunks.back().nFirstIndexId = nLastIndex; - newChunks.back().nNumIndices = 0; - newChunks.back().nNumVerts = 0; - newChunks.back().pRE = 0; - } - nMatId = srcChunk.m_nMatID; - newChunks.back().nNumIndices += srcChunk.nNumIndices; - newChunks.back().nNumVerts = max((int)srcChunk.nFirstVertId + (int)srcChunk.nNumVerts - (int)newChunks.back().nFirstVertId, (int)newChunks.back().nNumVerts); - } - } - pSrcMesh->UnLockForThreadAccess(); - - IRenderMesh::SInitParamerers params; - SVF_P3S_C4B_T2S tempVertex; - params.pVertBuffer = &tempVertex; - params.nVertexCount = 1; - params.vertexFormat = eVF_P3S_C4B_T2S; - params.pIndices = lstIndices.GetElements(); - params.nIndexCount = lstIndices.Count(); - params.nPrimetiveType = prtTriangleList; - params.eType = eRMT_Static; - params.nRenderChunkCount = 1; - params.bOnlyVideoBuffer = false; - params.bPrecache = false; - _smart_ptr pIndexMesh = gRenDev->CreateRenderMesh(pSrcMesh->m_sType, pSrcMesh->m_sSource, ¶ms); - pIndexMesh->SetVertexContainer(pSrcMesh); - if (!newChunks.empty()) - { - pIndexMesh->SetRenderChunks(&newChunks.front(), newChunks.size(), false); - pIndexMesh->SetBBox(pSrcMesh->m_vBoxMin, pSrcMesh->m_vBoxMax); - } - m_pIndexRM = pIndexMesh; - } -} - diff --git a/Code/CryEngine/RenderDll/Common/RenderMesh_SetMesh.cpp b/Code/CryEngine/RenderDll/Common/RenderMesh_SetMesh.cpp deleted file mode 100644 index b8e9c70632..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderMesh_SetMesh.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RenderMesh.h" -#include "IIndexedMesh.h" - -#define TRANSFER_ALIGNMENT 1 - -static void transfer_writecombined(void* pDst, const void* pSrc, size_t size) -{ - cryMemcpy(pDst, pSrc, size, MC_CPU_TO_GPU); -} - -template -struct StreamCompactor; - -template -uint32 CompactStream(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) -{ - return StreamCompactor::Compact(buffer, data, mesh, beg, end); -} - -// Override for the VSF_GENERAL stream that can be used with arbitrary vertex data -template -uint32 CompactStream(uint8(&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end, const AZ::Vertex::Format& vertexFormat) -{ - return StreamCompactor::Compact(buffer, data, mesh, beg, end, vertexFormat); -} - -template -struct StreamCompactor -{ - static void CompactPositions(uint8* stagingBuffer, [[maybe_unused]] SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end, uint32 streamIndex, uint32 vertexStride, uint32 attributeOffset, uint32 attributeByteLength) - { - if (mesh.Has32BitPositions()) - { - Vec3* positions = mesh.GetStreamPtr(CMesh::POSITIONS, streamIndex); - AZ_Assert(attributeByteLength == sizeof(Vec3), "Mesh uses three 32 bit floats for positions, but vertex format is expecting a different size"); - for (size_t i = 0; i < end; ++i) - { - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &positions[beg + i], attributeByteLength); - } - } - else if (mesh.Has16BitPositions()) - { - Vec3f16* positions = mesh.GetStreamPtr(CMesh::POSITIONSF16, streamIndex); - AZ_Assert(attributeByteLength == sizeof(Vec3f16), "Mesh uses three 16 bit floats for positions, but vertex format is expecting a different size"); - for (size_t i = 0; i < end; ++i) - { - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &positions[beg + i], attributeByteLength); - } - } - else - { - AZ_Assert(false, "Mesh has no per-vertex positions."); - } - } - - static void CompactNormals(SVF_P3S_N4B_C4B_T2S* pVBuff, SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) - { - SMeshNormal* normals = mesh.GetStreamPtr(CMesh::NORMALS); - if (normals) - { - for (size_t i = 0; i < end; ++i) - { - Vec3 n = normals[beg + i].GetN(); - - pVBuff[i].normal.bcolor[0] = (byte)(n[0] * 127.5f + 128.0f); - pVBuff[i].normal.bcolor[1] = (byte)(n[1] * 127.5f + 128.0f); - pVBuff[i].normal.bcolor[2] = (byte)(n[2] * 127.5f + 128.0f); - - SwapEndian(pVBuff[i].normal.dcolor); - } - } - } - - static void CompactColors(uint8* stagingBuffer, [[maybe_unused]] SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end, uint32 streamIndex, uint32 vertexStride, uint32 attributeOffset, uint32 attributeByteLength) - { - SMeshColor* colors = mesh.GetStreamPtr(CMesh::COLORS, streamIndex); - if (colors) - { - for (size_t i = 0; i < end; ++i) - { - ColorB color = colors[beg + i].GetRGBA(); - UCol uColor; - uColor.bcolor[0] = color.b; - uColor.bcolor[1] = color.g; - uColor.bcolor[2] = color.r; - uColor.bcolor[3] = color.a; - SwapEndian(uColor.dcolor); - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &uColor, attributeByteLength); - } - } - else - { - for (size_t i = 0; i < end; ++i) - { - UCol defaultColor; - defaultColor.dcolor = ~0; - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &defaultColor, attributeByteLength); - } - } - } - - static void CompactUVs(uint8* stagingBuffer, [[maybe_unused]] SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end, uint32 streamIndex, uint32 vertexStride, uint32 attributeOffset, uint32 attributeByteLength) - { - SMeshTexCoord* texCoords = mesh.GetStreamPtr(CMesh::TEXCOORDS, streamIndex); - if (texCoords) - { - for (size_t i = 0; i < end; ++i) - { - SMeshTexCoord meshTexCoord = texCoords[beg + i]; - // If the vertex format uses two 32 bit floats for texture coordinates, copy them to the staging buffer - if (attributeByteLength == sizeof(Vec2)) - { - Vec2 texCoord = meshTexCoord.GetUV(); - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &texCoord, attributeByteLength); - } - // If the vertex format uses two 16 bit floats for texture coordinates, convert the CMesh texture coordinates to 16 bit floats and then copy them to the staging buffer - else if (attributeByteLength == sizeof(Vec2f16)) - { - Vec2f16 texCoord; - meshTexCoord.ExportTo(texCoord); - memcpy(stagingBuffer + i * vertexStride + attributeOffset, &texCoord, attributeByteLength); - } - else - { - AZ_Assert(false, "Invalid byte length for texture coordinates"); - } - } - } - } - - static uint32 Compact(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end, const AZ::Vertex::Format& vertexFormat) - { - if (data.m_pVBuff) - { - - size_t dstPad = (size_t)&data.m_pVBuff[beg * vertexFormat.GetStride()] & (TRANSFER_ALIGNMENT - 1); - uint8* stagingBuffer = &buffer[dstPad]; - uint32 amount = min((uint32)(end - beg), (uint32)(Size / vertexFormat.GetStride())); - - if (mesh.m_pP3S_C4B_T2S) - { - // Do a straight copy of mesh data that has already been interleaved - memcpy(stagingBuffer, &mesh.m_pP3S_C4B_T2S[beg], sizeof(SVF_P3S_C4B_T2S) * amount); - } - else - { - uint32 attributeCount = 0; - const uint8* attributes = vertexFormat.GetAttributes(attributeCount); - int attributeCounter[(int)AZ::Vertex::AttributeUsage::NumUsages] = { 0 }; - uint32 attributeOffset = 0; - // Iterate over each attribute in the vertex format and interleave that attribute into the staging buffer - - for (uint ii = 0; ii < attributeCount; ++ii) - { - const uint8 attribute = attributes[ii]; - const AZ::Vertex::AttributeUsage usage = AZ::Vertex::Attribute::GetUsage(attribute); - switch (usage) - { - case AZ::Vertex::AttributeUsage::Position: - CompactPositions(stagingBuffer, data, mesh, beg, amount, attributeCounter[(int)AZ::Vertex::AttributeUsage::Position], vertexFormat.GetStride(), attributeOffset, AZ::Vertex::Attribute::GetByteLength(attribute)); - break; - case AZ::Vertex::AttributeUsage::Color: - CompactColors(stagingBuffer, data, mesh, beg, amount, attributeCounter[(int)AZ::Vertex::AttributeUsage::Color], vertexFormat.GetStride(), attributeOffset, AZ::Vertex::Attribute::GetByteLength(attribute)); - break; - case AZ::Vertex::AttributeUsage::TexCoord: - CompactUVs(stagingBuffer, data, mesh, beg, amount, attributeCounter[(int)AZ::Vertex::AttributeUsage::TexCoord], vertexFormat.GetStride(), attributeOffset, AZ::Vertex::Attribute::GetByteLength(attribute)); - break; - default: - AZ_Assert(false, "No case to handle per vertex data in the VSF_GENERAL stream for usage %d.", AZ::Vertex::Attribute::GetUsage(attribute)); - break; - } - // Keep track of the offset of the current attribute - attributeOffset += AZ::Vertex::Attribute::GetByteLength(attribute); - // Keep track of the number of attributes with a given usage so we can use that to index into the CMesh's vertex streams for that usage - attributeCounter[static_cast(usage)]++; - } - } - transfer_writecombined(&data.m_pVBuff[beg * vertexFormat.GetStride()], &buffer[dstPad], amount * vertexFormat.GetStride()); - return amount; - } - - CryFatalError("CRenderMesh::SetMesh_Impl: invalid vertex format for general stream"); - return 0; - } -}; - -template -struct StreamCompactor -{ - static uint32 Compact(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) - { - if (mesh.m_pTangents == NULL || data.m_pTBuff == NULL) - { - return end; - } - - uint32 dstPad = 0; - - SPipTangents* pTBuff = alias_cast(&buffer[dstPad]); - uint32 amount = min((uint32)(end - beg), (uint32)(Size / sizeof(pTBuff[0]))); - - for (size_t i = 0; i < amount; ++i) - { - mesh.m_pTangents[beg + i].ExportTo(pTBuff[i]); - } - - transfer_writecombined(&data.m_pTBuff[beg], &buffer[dstPad], amount * sizeof(data.m_pTBuff[0])); - - return amount; - } -}; - -template -struct StreamCompactor -{ - static uint32 Compact(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) - { - if (mesh.m_pQTangents == NULL || data.m_pQTBuff == NULL) - { - return end; - } - - uint32 dstPad = 0; - - SPipQTangents* pQTBuff = alias_cast(&buffer[dstPad]); - uint32 amount = min((uint32)(end - beg), (uint32)(Size / sizeof(pQTBuff[0]))); - - for (size_t i = 0; i < amount; ++i) - { - mesh.m_pQTangents[beg + i].ExportTo(pQTBuff[i]); - } - - transfer_writecombined(&data.m_pQTBuff[beg], &buffer[dstPad], amount * sizeof(pQTBuff[0])); - - return amount; - } -}; - -#if ENABLE_NORMALSTREAM_SUPPORT -template -struct StreamCompactor -{ - static uint32 Compact(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) - { - if (mesh.m_pNorms == NULL || data.m_pNormalsBuff == NULL) - { - return end; - } - - uint32 dstPad = 0; - - uint32 amount = min((uint32)(end - beg), (uint32)(Size / sizeof(data.m_pNormalsBuff[0]))); - memcpy(&buffer[dstPad], &mesh.m_pNorms[beg], amount * sizeof(data.m_pNormalsBuff[0])); - transfer_writecombined(&data.m_pNormalsBuff[beg], &buffer[dstPad], amount * sizeof(data.m_pNormalsBuff[0])); - - return amount; - } -}; -#endif - -template -struct StreamCompactor -{ - static uint32 Compact(uint8 (&buffer)[Size], SSetMeshIntData& data, [[maybe_unused]] CMesh& mesh, uint32 beg, uint32 end) - { - if (data.m_pVelocities == NULL) - { - return end; - } - - uint32 dstPad = 0; - - uint32 amount = min((uint32)(end - beg), (uint32)(Size / sizeof(data.m_pVelocities[0]))); - memset(&buffer[dstPad], 0x0, amount * sizeof(data.m_pVelocities[0])); - transfer_writecombined(&data.m_pVelocities[beg], &buffer[dstPad], amount * sizeof(data.m_pVelocities[0])); - - return amount; - } -}; - - -template -uint32 CompactIndices(uint8 (&buffer)[Size], SSetMeshIntData& data, CMesh& mesh, uint32 beg, uint32 end) -{ - if (mesh.m_pIndices == NULL || data.m_pInds == NULL) - { - return end; - } - - uint32 dstPad = 0; - - uint32 amount = min((uint32)(end - beg), (uint32)(Size / sizeof(mesh.m_pIndices[0]))); - memcpy(&buffer[dstPad], &mesh.m_pIndices[beg], amount * sizeof(mesh.m_pIndices[0])); - transfer_writecombined(&data.m_pInds[beg], &buffer[dstPad], amount * sizeof(data.m_pInds[0])); - return amount; -} - -typedef _MS_ALIGN (128) uint8 AlignedStagingBufferT[(8 << 10) + 128]; - -void CRenderMesh::SetMesh_IntImpl(SSetMeshIntData data) -{ - CMesh& mesh = *data.m_pMesh; - AlignedStagingBufferT stagingBuffer; - - ////////////////////////////////////////////////////////////////////////// - // Compact the seperate streams from the CMesh instance into a general - ////////////////////////////////////////////////////////////////////////// - for (uint32 iter = 0; iter < data.m_nVerts; iter += CompactStream(stagingBuffer, data, mesh, iter, data.m_nVerts, m_vertexFormat)) - { - ; - } - for (uint32 iter = 0; iter < data.m_nVerts; iter += CompactStream(stagingBuffer, data, mesh, iter, data.m_nVerts)) - { - ; - } - for (uint32 iter = 0; iter < data.m_nVerts; iter += CompactStream(stagingBuffer, data, mesh, iter, data.m_nVerts)) - { - ; - } -# if ENABLE_NORMALSTREAM_SUPPORT - for (uint32 iter = 0; iter < data.m_nVerts; iter += CompactStream(stagingBuffer, data, mesh, iter, data.m_nVerts)) - { - ; - } -# endif - for (uint32 iter = 0; iter < data.m_nVerts; iter += CompactStream(stagingBuffer, data, mesh, iter, data.m_nVerts)) - { - ; - } - for (uint32 iter = 0; iter < data.m_nInds; iter += CompactIndices(stagingBuffer, data, mesh, iter, data.m_nInds)) - { - ; - } -} diff --git a/Code/CryEngine/RenderDll/Common/RenderPipeline.cpp b/Code/CryEngine/RenderDll/Common/RenderPipeline.cpp deleted file mode 100644 index e8331eec19..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderPipeline.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "Shadow_Renderer.h" -#include "RenderView.h" - -int SRendItem::m_RecurseLevel[RT_COMMAND_BUF_COUNT]; -int SRendItem::m_StartFrust[RT_COMMAND_BUF_COUNT][MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS]; -int SRendItem::m_EndFrust[RT_COMMAND_BUF_COUNT][MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS]; -int SRendItem::m_ShadowsStartRI[RT_COMMAND_BUF_COUNT][MAX_SHADOWMAP_FRUSTUMS]; -int SRendItem::m_ShadowsEndRI[RT_COMMAND_BUF_COUNT][MAX_SHADOWMAP_FRUSTUMS]; diff --git a/Code/CryEngine/RenderDll/Common/RenderPipeline.h b/Code/CryEngine/RenderDll/Common/RenderPipeline.h deleted file mode 100644 index d07bf7598b..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderPipeline.h +++ /dev/null @@ -1,1267 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include "Shadow_Renderer.h" -#include "../Common/PerInstanceConstantBufferPool.h" -#include -#include -//==================================================================== - -#define MAX_HWINST_PARAMS 32768 - -#define MAX_REND_OBJECTS 16384 -#define TEMP_REND_OBJECTS_POOL 2048 -#define MAX_REND_GEOMS_IN_BATCH 16 - - -#define MAX_REND_SHADERS 4096 -#define MAX_REND_SHADER_RES 16384 -#define MAX_REND_LIGHTS 32 -#define MAX_DEFERRED_LIGHTS 256 -#define SG_SORT_GROUP 0 -#define MAX_SHADOWMAP_LOD 20 -#define MAX_SHADOWMAP_FRUSTUMS 1024 -#define MAX_SORT_GROUPS 64 -#define MAX_INSTANCES_THRESHOLD_HW 8 -#define MAX_LIST_ORDER 2 // 0 = before water, 1 = after water -#define MAX_PREDICTION_ZONES MAX_STREAM_PREDICTION_ZONES - -#define CULLER_MAX_CAMS 4 - -#define HW_INSTANCING_ENABLED - -class CRenderView; - -struct SViewport -{ - int nX, nY, nWidth, nHeight; - float fMinZ, fMaxZ; - SViewport() - : nX(0) - , nY(0) - , nWidth(0) - , nHeight(0) - , fMinZ(0.0f) - , fMaxZ(0.0f) - {} - - SViewport(int nNewX, int nNewY, int nNewWidth, int nNewHeight) - : nX(nNewX) - , nY(nNewY) - , nWidth(nNewWidth) - , nHeight(nNewHeight) - , fMinZ(0.0f) - , fMaxZ(0.0f) - { - } - _inline friend bool operator != (const SViewport& m1, const SViewport& m2) - { - if (m1.nX != m2.nX || m1.nY != m2.nY || m1.nWidth != m2.nWidth || m1.nHeight != m2.nHeight || m1.fMinZ != m2.fMinZ || m1.fMaxZ != m2.fMaxZ) - { - return true; - } - return false; - } - _inline friend bool operator == (const SViewport& m1, const SViewport& m2) - { - return !(m1 != m2); - } -}; - -struct SRenderListDesc -{ - int m_nStartRI[MAX_LIST_ORDER][EFSLIST_NUM]; - int m_nEndRI[MAX_LIST_ORDER][EFSLIST_NUM]; - int m_nBatchFlags[MAX_LIST_ORDER][EFSLIST_NUM]; -}; - -typedef union UnINT64 -{ - uint64 SortVal; - struct - { - uint32 Low; - uint32 High; - }i; -} UnINT64; - -#define FB_IGNORE_SG_MASK 0x100000 - -// FIXME: probably better to sort by shaders (Currently sorted by resources) -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(RenderPipeline_h) -#endif -struct SRendItem -{ - uint32 SortVal; - IRenderElement* pElem; - union - { - uint32 ObjSort; - float fDist; - }; - CRenderObject* pObj; - uint32 nBatchFlags; - uint32 nOcclQuery : 16; - enum - { - kOcclQueryInvalid = 0xFFFFU - }; - uint32 nStencRef : 8; - uint8 nTextureID; - SRendItemSorter rendItemSorter; - - union QuickCopy - { - uint64 data[4]; - char bytes[32]; - }; - - //================================================== - static void* mfGetPointerCommon(ESrcPointer ePT, int* Stride, EParamType Type, ESrcPointer Dst, int Flags); - - static _inline void mfGet(uint32 nVal, int& nTechnique, CShader*& Shader, CShaderResources*& Res) - { - Shader = (CShader*)CShaderMan::s_pContainer->m_RList[CBaseResource::RListIndexFromId((nVal >> 6) & (MAX_REND_SHADERS - 1))]; - //Shader = (CShader *)CShaderMan::m_pContainer->m_RList[(nVal>>20) & (MAX_REND_SHADERS-1)]; - nTechnique = (nVal & 0x3f); - if (nTechnique == 0x3f) - { - nTechnique = -1; - } - int nRes = (nVal >> 18) & (MAX_REND_SHADER_RES - 1); - //int nRes = (nVal>>6) & (MAX_REND_SHADER_RES-1); - Res = (nRes) ? CShader::s_ShaderResources_known[nRes] : NULL; - } - static _inline CShader* mfGetShader(uint32 flag) - { - return (CShader*)CShaderMan::s_pContainer->m_RList[CBaseResource::RListIndexFromId((flag >> 6) & (MAX_REND_SHADERS - 1))]; - //return (CShader *)CShaderMan::m_pContainer->m_RList[(flag>>20) & (MAX_REND_SHADERS-1)]; - } - static _inline CShaderResources* mfGetRes(uint32 nVal) - { - int nRes = (nVal >> 18) & (MAX_REND_SHADER_RES - 1); - return ((nRes) ? CShader::s_ShaderResources_known[nRes] : NULL); - } - static bool IsListEmpty(int nList, [[maybe_unused]] int nProcessID, SRenderListDesc* pRLD) - { - int nREs = pRLD->m_nEndRI[0][nList] - pRLD->m_nStartRI[0][nList]; - nREs += pRLD->m_nEndRI[1][nList] - pRLD->m_nStartRI[1][nList]; - - if (!nREs) - { - return true; - } - return false; - } - - static bool IsListEmpty(int nList, [[maybe_unused]] int nProcessID, SRenderListDesc* pRLD, int nAW) - { - int nREs = pRLD->m_nEndRI[nAW][nList] - pRLD->m_nStartRI[nAW][nList]; - - if (!nREs) - { - return true; - } - return false; - } - - static uint32 BatchFlags(int nList, SRenderListDesc* pRLD) - { - uint32 nBatchFlags = 0; - int nREs = pRLD->m_nEndRI[0][nList] - pRLD->m_nStartRI[0][nList]; - if (nREs) - { - nBatchFlags |= pRLD->m_nBatchFlags[0][nList]; - } - nREs = pRLD->m_nEndRI[1][nList] - pRLD->m_nStartRI[1][nList]; - if (nREs) - { - nBatchFlags |= pRLD->m_nBatchFlags[1][nList]; - } - return nBatchFlags; - } - - // Sort by SortVal member of RI - static void mfSortPreprocess(SRendItem* First, int Num); - // Sort by distance - static void mfSortByDist(SRendItem* First, int Num, bool bDecals, bool InvertedOrder = false); - // Sort by light - static void mfSortByLight(SRendItem* First, int Num, bool bSort, const bool bIgnoreRePtr, bool bSortDecals); - // Special sorting for ZPass (compromise between depth and batching) - static void mfSortForZPass(SRendItem* First, int Num); - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - // Free all renditem lists. Renderer must be flushed. - static CThreadSafeWorkerContainer& RendItems(int threadIndex, int listOrder, int listNum); - - static int m_RecurseLevel[RT_COMMAND_BUF_COUNT]; - static int m_StartFrust[RT_COMMAND_BUF_COUNT][MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS]; - static int m_EndFrust[RT_COMMAND_BUF_COUNT][MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS]; - static int m_ShadowsStartRI[RT_COMMAND_BUF_COUNT][MAX_SHADOWMAP_FRUSTUMS]; - static int m_ShadowsEndRI[RT_COMMAND_BUF_COUNT][MAX_SHADOWMAP_FRUSTUMS]; -}; - -//================================================================== - -struct SShaderPass; - -union UVertStreamPtr -{ - void* Ptr; - byte* PtrB; - SVF_P3F_C4B_T4B_N3F2* PtrVF_P3F_C4B_T4B_N3F2; -}; - -//================================================================== - -#define MAX_DYNVBS 4 - -//================================================================== - -#define GS_HIZENABLE 0x00010000 -//================================================================== - -#if defined(NULL_RENDERER) -struct SOnDemandD3DStreamProperties -{ -}; - -struct SOnDemandD3DVertexDeclaration -{ -}; - -struct SOnDemandD3DVertexDeclarationCache -{ -}; -#else -struct SOnDemandD3DStreamProperties -{ - D3D11_INPUT_ELEMENT_DESC* m_pElements; - uint32 m_nNumElements; -}; - -struct SOnDemandD3DVertexDeclaration -{ - AZStd::vector m_Declaration; -}; - -struct SOnDemandD3DVertexDeclarationCache -{ - ID3D11InputLayout* m_pDeclaration; -}; - -template -class FencedIB; -template -class FencedVB; - -struct SVertexDeclaration -{ - int StreamMask; - AZ::Vertex::Format VertexFormat; - int InstAttrMask; - AZStd::vector m_Declaration; - ID3D11InputLayout* m_pDeclaration = nullptr; - - // This caching structure is only used for auto-generated vertex formats for instanced renders. - // The caching format was previously invalid because it cached ID3D11InputLayout based only on the - // vertex format declaration, rather than based on the vertex format declaration with the vertex shader input - // table since a different IA layout will be generated whether a vertex shader uses different inputs or not - void* m_vertexShader = nullptr; - - ~SVertexDeclaration() - { - SAFE_RELEASE(m_pDeclaration); - } -}; - -#endif - -struct SMSAA -{ - SMSAA() - : Type(0) - , Quality(0) - , m_pDepthTex(0) - , m_pZBuffer(0) - { - } - - UINT Type; - DWORD Quality; -#if defined(NULL_RENDERER) - void* m_pDepthTex; - void* m_pZBuffer; -#else - D3DTexture* m_pDepthTex; - ID3D11DepthStencilView* m_pZBuffer; -#endif -}; - -struct SProfInfo -{ - int NumPolys; - int NumDips; - CShader* pShader; - SShaderTechnique* pTechnique; - double Time; - int m_nItems; - SProfInfo() - { - NumPolys = 0; - NumDips = 0; - pShader = NULL; - pTechnique = NULL; - m_nItems = 0; - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(pShader); - pSizer->AddObject(pTechnique); - } -}; - -struct SRTargetStat -{ - string m_Name; - uint32 m_nSize; - uint32 m_nWidth; - uint32 m_nHeight; - ETEX_Format m_eTF; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_Name); - } -}; - - -struct SPipeStat -{ -#if !defined(_RELEASE) - int m_NumRendHWInstances; - int m_RendHWInstancesPolysAll; - int m_RendHWInstancesPolysOne; - int m_RendHWInstancesDIPs; - int m_NumTextChanges; - int m_NumRTChanges; - int m_NumStateChanges; - int m_NumRendSkinnedObjects; - int m_NumVShadChanges; - int m_NumPShadChanges; - int m_NumGShadChanges; - int m_NumDShadChanges; - int m_NumHShadChanges; - int m_NumCShadChanges; - int m_NumVShaders; - int m_NumPShaders; - int m_NumGShaders; - int m_NumDShaders; - int m_NumHShaders; - int m_NumRTs; - int m_NumSprites; - int m_NumSpriteDIPS; - int m_NumSpritePolys; - int m_NumSpriteUpdates; - int m_NumSpriteAltasesUsed; - int m_NumSpriteCellsUsed; - int m_NumQIssued; - int m_NumQOccluded; - int m_NumQNotReady; - int m_NumQStallTime; - int m_NumImpostersUpdates; - int m_NumCloudImpostersUpdates; - int m_NumImpostersDraw; - int m_NumCloudImpostersDraw; - int m_NumTextures; - uint32 m_NumShadowPoolFrustums; - uint32 m_NumShadowPoolAllocsThisFrame; - uint32 m_NumShadowMaskChannels; - uint32 m_NumTiledShadingSkippedLights; -#endif - int m_NumPSInstructions; - int m_NumVSInstructions; - int m_RTCleared; - int m_RTClearedSize; - int m_RTCopied; - int m_RTCopiedSize; - int m_RTSize; - - CHWShader* m_pMaxPShader; - CHWShader* m_pMaxVShader; - void* m_pMaxPSInstance; - void* m_pMaxVSInstance; - - size_t m_ManagedTexturesStreamSysSize; - size_t m_ManagedTexturesStreamVidSize; - size_t m_ManagedTexturesSysMemSize; - size_t m_ManagedTexturesVidMemSize; - size_t m_DynTexturesSize; - size_t m_MeshUpdateBytes; - size_t m_DynMeshUpdateBytes; - float m_fOverdraw; - float m_fSkinningTime; - float m_fPreprocessTime; - float m_fSceneTimeMT; - float m_fTexUploadTime; - float m_fTexRestoreTime; - float m_fOcclusionTime; - float m_fRenderTime; - float m_fEnvCMapUpdateTime; - float m_fEnvTextUpdateTime; - - int m_ImpostersSizeUpdate; - int m_CloudImpostersSizeUpdate; - -#if REFRACTION_PARTIAL_RESOLVE_STATS - float m_fRefractionPartialResolveEstimatedCost; - int m_refractionPartialResolveCount; - int m_refractionPartialResolvePixelCount; -#endif - -#if defined(ENABLE_PROFILING_CODE) - int m_NumRendMaterialBatches; - int m_NumRendGeomBatches; - int m_NumRendInstances; - - int m_nDIPs[EFSLIST_NUM]; - int m_nInsts; - int m_nInstCalls; - int m_nPolygons[EFSLIST_NUM]; - int m_nPolygonsByTypes[EFSLIST_NUM][EVCT_NUM][2]; -#endif - -#if defined(ENABLE_ART_RT_TIME_ESTIMATE) - float m_actualRenderTimeMinusPost; -#endif - - float m_fTimeDIPs[EFSLIST_NUM]; - float m_fTimeDIPsZ; - float m_fTimeDIPsAO; - float m_fTimeDIPsRAIN; - float m_fTimeDIPsDeferredLayers; - float m_fTimeDIPsSprites; -} _ALIGN(128); - - -//Batch flags. -// - When adding/removing batch flags, please, update sBatchList static list in D3DRendPipeline.cpp -enum EBatchFlags -{ - FB_GENERAL = 0x1, - FB_TRANSPARENT = 0x2, - FB_SKIN = 0x4, - FB_Z = 0x8, - FB_FUR = 0x10, - FB_ZPREPASS = 0x20, - FB_PREPROCESS = 0x40, - FB_MOTIONBLUR = 0x80, - FB_POST_3D_RENDER = 0x100, - FB_MULTILAYERS = 0x200, - FB_COMPILED_OBJECT = 0x400, - FB_CUSTOM_RENDER = 0x800, - FB_SOFTALPHATEST = 0x1000, - FB_LAYER_EFFECT = 0x2000, - FB_WATER_REFL = 0x4000, - FB_WATER_CAUSTIC = 0x8000, - FB_DEBUG = 0x10000, - FB_PARTICLES_THICKNESS = 0x20000, - FB_TRANSPARENT_AFTER_DOF = 0x40000, // for transparent render element skip Depth of field effect - FB_EYE_OVERLAY = 0x80000, - - FB_MASK = 0xfffff //! FB flags cannot exceed 0xfffff -}; - - -// Commit flags -#define FC_TARGETS 1 -#define FC_GLOBAL_PARAMS 2 -#define FC_PER_INSTANCE_PARAMS 4 -#define FC_MATERIAL_PARAMS 0x10 -#define FC_ALL 0x1f - - -// m_RP.m_Flags -#define RBF_NEAREST 0x10000 - -// m_RP.m_TI.m_PersFlags -#define RBPF_DRAWTOTEXTURE (1 << 16) // 0x10000 -#define RBPF_MIRRORCAMERA (1 << 17) // 0x20000 -#define RBPF_MIRRORCULL (1 << 18) // 0x40000 - -#define RBPF_ZPASS (1 << 19) // 0x80000 -#define RBPF_SHADOWGEN (1 << 20) // 0x100000 - -#define RBPF_FP_DIRTY (1 << 21) // 0x200000 - -#define RBPF_NO_SHADOWGEN (1 << 22) - -#define RBPF_IMPOSTERGEN (1 << 23) -#define RBPF_MAKESPRITE (1 << 24) // 0x1000000 -// CRY DX12 -#define RBPF_FP_MATRIXDIRTY (1 << 25) - -#define RBPF_HDR (1 << 26) -#define RBPF_REVERSE_DEPTH (1 << 27) -#define RBPF_ENCODE_HDR (1 << 29) -#define RBPF_OBLIQUE_FRUSTUM_CLIPPING (1 << 30) - - -// m_RP.m_PersFlags1 -#define RBPF1_USESTREAM (1 << 0) -#define RBPF1_USESTREAM_MASK ((1 << VSF_NUM) - 1) - -#define RBPF1_IN_CLEAR (1 << 17) - -#define RBPF1_SKIP_AFTER_POST_PROCESS (1 << 18) - -// m_RP.m_PersFlags2 -#define RBPF2_NOSHADERFOG (1 << 0) -#define RBPF2_RAINRIPPLES (1 << 1) -#define RBPF2_NOALPHABLEND (1 << 2) -#define RBPF2_SINGLE_FORWARD_LIGHT_PASS (1 << 3) -#define RBPF2_MSAA_RESTORE_SAMPLE_MASK (1 << 4) -#define RBPF2_READMASK_RESERVED_STENCIL_BIT (1 << 5) -#define RBPF2_POST_3D_RENDERER_PASS (1 << 6) -#define RBPF2_LENS_OPTICS_COMPOSITE (1 << 7) -#define RBPF2_HDR_FP16 (1 << 9) -#define RBPF2_CUSTOM_SHADOW_PASS (1 << 10) -#define RBPF2_CUSTOM_RENDER_PASS (1 << 11) -// UNUSED: (1<<12) - -#define RBPF2_COMMIT_CM (1 << 13) -#define RBPF2_ZPREPASS (1 << 14) - -#define RBPF2_FORWARD_SHADING_PASS (1 << 15) - -#define RBPF2_MSAA_STENCILCULL (1 << 16) - -#define RBPF2_THERMAL_RENDERMODE_TRANSPARENT_PASS (1 << 17) -#define RBPF2_NOALPHATEST (1 << 18) -#define RBPF2_WATERRIPPLES (1 << 19) -#define RBPF2_ALLOW_DEFERREDSHADING (1 << 20) - -#define RBPF2_COMMIT_PF (1 << 21) -#define RBPF2_MSAA_SAMPLEFREQ_PASS (1 << 22) -#define RBPF2_DRAWTOCUBE (1 << 23) - -#define RBPF2_MOTIONBLURPASS (1 << 24) -#define RBPF2_MATERIALLAYERPASS (1 << 25) -#define RBPF2_DISABLECOLORWRITES (1 << 26) - -#define RBPF2_NOPOSTAA (1 << 27) -#define RBPF2_SKIN (1 << 28) - -#define RBPF2_LIGHTSHAFTS (1 << 29) -#define RBPF2_WRITEMASK_RESERVED_STENCIL_BIT (1 << 30) // 0x010 -#define RBPF2_HALFRES_PARTICLES (1 << 31) - -// m_RP.m_FlagsPerFlush -#define RBSI_LOCKCULL 0x2 -#define RBSI_EXTERN_VMEM_BUFFERS 0x800000 -#define RBSI_INSTANCED 0x10000000 -#define RBSI_CUSTOM_PREVMATRIX 0x20000000 - -// m_RP.m_ShaderLightMask -#define SLMF_DIRECT 0 -#define SLMF_POINT 1 -#define SLMF_PROJECTED 2 -#define SLMF_TYPE_MASK (SLMF_POINT | SLMF_PROJECTED) - -#define SLMF_LTYPE_SHIFT 8 -#define SLMF_LTYPE_BITS 4 - -struct SLightPass -{ - SRenderLight* pLights[4]; - uint32 nStencLTMask; - uint32 nLights; - uint32 nLTMask; - bool bRect; - RectI rc; -}; - -#define MAX_STREAMS 16 - -struct SStreamInfo -{ - const void* pStream; - int nOffset; - int nStride; - - SStreamInfo() {} - SStreamInfo(const void* stream, int offset, int stride) - : pStream(stream) - , nOffset(offset) - , nStride(stride) {} - - SStreamInfo& operator=(const CRendElementBase::SGeometryStreamInfo& stream) - { - pStream = stream.pStream; - nOffset = stream.nOffset; - nStride = stream.nStride; - return *this; - } - - inline bool operator==(const SStreamInfo& other) const - { - return pStream == other.pStream && nOffset == other.nOffset && nStride == other.nStride; - } -}; - -struct SFogState -{ - bool m_bEnable; - ColorF m_FogColor; - ColorF m_CurColor; - - bool operator != (const SFogState& fs) const - { - return m_FogColor != fs.m_FogColor; - } -}; - -enum EShapeMeshType -{ - SHAPE_PROJECTOR = 0, - SHAPE_PROJECTOR1, - SHAPE_PROJECTOR2, - SHAPE_CLIP_PROJECTOR, - SHAPE_CLIP_PROJECTOR1, - SHAPE_CLIP_PROJECTOR2, - SHAPE_SIMPLE_PROJECTOR, - SHAPE_SPHERE, - SHAPE_BOX, - SHAPE_MAX, -}; - -struct SThreadInfo -{ - uint32 m_PersFlags; // Never reset - float m_RealTime; - - Matrix44A m_matView = Matrix44A(IDENTITY); - Matrix44A m_matProj = Matrix44A(IDENTITY); - - CCamera m_cam; // current camera - int m_nFrameID; // with recursive calls, access through GetFrameID(true) - uint32 m_nFrameUpdateID; // without recursive calls, access through GetFrameID(false) - int m_arrZonesRoundId[MAX_PREDICTION_ZONES]; // rounds ID from 3D engine, useful for texture streaming - SFogState m_FS; - CRenderObject* m_pIgnoreObject; - - Plane m_pObliqueClipPlane; - bool m_bObliqueClipPlane; - - byte m_eCurColorOp; - byte m_eCurAlphaOp; - byte m_eCurColorArg; - byte m_eCurAlphaArg; - bool m_sRGBWrite { - false - }; - - PerFrameParameters m_perFrameParameters; - - ~SThreadInfo() {} - SThreadInfo& operator = (const SThreadInfo& ti) - { - if (&ti == this) - { - return *this; - } - m_PersFlags = ti.m_PersFlags; - m_RealTime = ti.m_RealTime; - m_matView = ti.m_matView; - m_matProj = ti.m_matProj; - m_cam = ti.m_cam; - m_nFrameID = ti.m_nFrameID; - m_nFrameUpdateID = ti.m_nFrameUpdateID; - for (int z = 0; z < MAX_PREDICTION_ZONES; z++) - { - m_arrZonesRoundId[z] = ti.m_arrZonesRoundId[z]; - } - m_FS = ti.m_FS; - m_perFrameParameters = ti.m_perFrameParameters; - m_pIgnoreObject = ti.m_pIgnoreObject; - memcpy(&m_pObliqueClipPlane, &ti.m_pObliqueClipPlane, sizeof(m_pObliqueClipPlane)); - m_bObliqueClipPlane = ti.m_bObliqueClipPlane; - m_eCurColorOp = ti.m_eCurColorOp; - m_eCurAlphaOp = ti.m_eCurAlphaOp; - m_eCurColorArg = ti.m_eCurColorArg; - m_eCurAlphaArg = ti.m_eCurAlphaArg; - m_sRGBWrite = ti.m_sRGBWrite; - return *this; - } -}; - - -#ifdef STRIP_RENDER_THREAD -struct SSingleThreadInfo - : public SThreadInfo -{ - SThreadInfo& operator[] (const int) {return *this; } - const SThreadInfo& operator[] (const int) const {return *this; } -}; -#endif - - -// Render pipeline structure -struct SRenderPipeline -{ - CShader* m_pShader; - CShader* m_pReplacementShader; - CRenderObject* m_pCurObject; - CRenderObject* m_pIdendityRenderObject; - IRenderElement* m_pRE; - CRendElementBase* m_pEventRE; - int m_RendNumVerts; - uint32 m_nBatchFilter; // Batch flags ( FB_ ) - SShaderTechnique* m_pRootTechnique; - SShaderTechnique* m_pCurTechnique; - SShaderPass* m_pCurPass; - uint32 m_CurPassBitMask; - int m_nShaderTechnique; - int m_nShaderTechniqueType; - CShaderResources* m_pShaderResources; - CRenderObject* m_pPrevObject; - int m_nLastRE; - TArray m_RIs[MAX_REND_GEOMS_IN_BATCH]; - - ColorF m_CurGlobalColor; - - float m_fMinDistance; // min distance to texture - uint64 m_ObjFlags; // Instances flag for batch (merged) - int m_Flags; // Reset on start pipeline - - EShapeMeshType m_nDeferredPrimitiveID; - int m_nZOcclusionBufferID; - - threadID m_nFillThreadID; - threadID m_nProcessThreadID; - SThreadInfo m_TI[RT_COMMAND_BUF_COUNT]; - SThreadInfo m_OldTI[MAX_RECURSION_LEVELS]; - // SFogVolumeData container will be used to accumulate the fog volume influences. - CThreadSafeRendererContainer m_fogVolumeContibutionsData[RT_COMMAND_BUF_COUNT]; - - uint32 m_PersFlags1; // Persistent flags - never reset - uint32 m_PersFlags2; // Persistent flags - never reset - int m_FlagsPerFlush; // Flags which resets for each shader flush - uint32 m_nCommitFlags; - uint32 m_FlagsStreams_Decl; - uint32 m_FlagsStreams_Stream; - AZ::Vertex::Format m_CurVFormat; - uint32 m_FlagsShader_LT; // Shader light mask - uint64 m_FlagsShader_RT; // Shader runtime mask - uint32 m_FlagsShader_MD; // Shader texture modificator mask - uint32 m_FlagsShader_MDV; // Shader vertex modificator mask - uint32 m_nShaderQuality; - - void (* m_pRenderFunc)(); - - uint32 m_CurGPRAllocStateCommit; - uint32 m_CurGPRAllocState; - int m_CurHiZState; - - uint32 m_CurState; - uint32 m_StateOr; - uint32 m_StateAnd; - int m_CurAlphaRef; - uint32 m_MaterialStateOr; - uint32 m_MaterialStateAnd; - int m_MaterialAlphaRef; - uint32 m_ForceStateOr; - uint32 m_ForceStateAnd; - bool m_bIgnoreObjectAlpha; - ECull m_eCull; - uint32 m_previousPersFlags = 0; - - int m_CurStencilState; - uint32 m_CurStencMask; - uint32 m_CurStencWriteMask; - uint32 m_CurStencRef; - int m_CurStencilRefAndMask; - int m_CurStencilCullFunc; - - SStreamInfo m_VertexStreams[MAX_STREAMS]; - void* m_pIndexStream; - - uint32 m_IndexStreamOffset; - RenderIndexType m_IndexStreamType; - - bool m_bFirstPass; - uint32 m_nNumRendPasses; - int m_NumShaderInstructions; - - string m_sExcludeShader; - - TArray m_Profile; - - CCamera m_PrevCamera; - - SRenderListDesc* m_pRLD; - - uint32 m_nRendFlags; - bool m_bUseHDR; - int m_nPassGroupID; // EFSLIST_ pass type - int m_nPassGroupDIP; // EFSLIST_ pass type - int m_nSortGroupID; - uint32 m_nFlagsShaderBegin; - uint8 m_nCurrResolveBounds[4]; - - Vec2 m_CurDownscaleFactor; - - ERenderQuality m_eQuality; - - TArray m_SMFrustums[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - TArray m_SMCustomFrustumIDs[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - CThreadSafeWorkerContainer m_arrCustomShadowMapFrustumData[RT_COMMAND_BUF_COUNT]; - - struct SShadowFrustumToRender - { - ShadowMapFrustum* pFrustum; - int nRecursiveLevel; - int nLightID; - SRenderLight* pLight; - } _ALIGN(16); - TArray SShadowFrustumToRenderList[RT_COMMAND_BUF_COUNT]; - TArray m_DLights[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - SLightPass m_LPasses[MAX_REND_LIGHTS]; - float m_fProfileTime; - - struct ShadowInfo - { - ShadowMapFrustum* m_pCurShadowFrustum; - Vec3 vViewerPos; - int m_nOmniLightSide; - } m_ShadowInfo; - - DynArray m_DeferredDecals[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - bool m_isDeferrredNormalDecals[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - - UVertStreamPtr m_StreamPtrTang; - UVertStreamPtr m_NextStreamPtrTang; - - UVertStreamPtr m_StreamPtr; - UVertStreamPtr m_NextStreamPtr; - int m_StreamStride; - uint m_StreamOffsetTC; - uint m_StreamOffsetColor; - - float m_fLastWaterFOVUpdate; - Vec3 m_LastWaterViewdirUpdate; - Vec3 m_LastWaterUpdirUpdate; - Vec3 m_LastWaterPosUpdate; - float m_fLastWaterUpdate; - int m_nLastWaterFrameID; - - bool m_depthWriteStateUsed; - -#if !defined(NULL_RENDERER) - SMSAA m_MSAAData; - bool IsMSAAEnabled() const { return m_MSAAData.Type > 0; } - - enum - { - nNumParticleVertexIndexBuffer = 3 - }; - - // particle date for writing directly to VMEM - FencedVB* m_pParticleVertexBuffer[nNumParticleVertexIndexBuffer]; - FencedIB * m_pParticleIndexBuffer[nNumParticleVertexIndexBuffer]; - - // During writing, we only expose the base Video Memory pointer - // and the offsets to the next free memory in this buffer - byte* m_pParticleVertexVideoMemoryBase[nNumParticleVertexIndexBuffer]; - byte* m_pParticleindexVideoMemoryBase[nNumParticleVertexIndexBuffer]; - - uint32 m_nParticleVertexOffset[nNumParticleVertexIndexBuffer]; - uint32 m_nParticleIndexOffset[nNumParticleVertexIndexBuffer]; - - // total amount of allocated memory for particle vertex/index buffers - uint32 m_nParticleVertexBufferAvailableMemory; - uint32 m_nParticleIndexBufferAvailableMemory; - - - int m_nStreamOffset[3]; // deprecated! - - AZ::Vertex::Format m_vertexFormats[eVF_Max]; - SOnDemandD3DVertexDeclaration m_D3DVertexDeclarations[eVF_Max]; - AZStd::unordered_map m_D3DVertexDeclarationCache[1 << VSF_NUM][2]; // [StreamMask][Morph][VertexFormatCRC] - SOnDemandD3DStreamProperties m_D3DStreamProperties[VSF_NUM]; - - TArray m_CustomVD; -#else - bool IsMSAAEnabled() const { return false; } -#endif - - uint16* m_RendIndices; - uint16* m_SysRendIndices; - byte* m_SysArray; - int m_SizeSysArray; - - TArray m_SysVertexPool[RT_COMMAND_BUF_COUNT]; - TArray m_SysIndexPool[RT_COMMAND_BUF_COUNT]; - - int m_RendNumGroup; - int m_RendNumIndices; - int m_FirstIndex; - int m_FirstVertex; - - // members for external vertex/index buffers -#if !defined(NULL_RENDERER) - FencedVB* m_pExternalVertexBuffer; - FencedIB* m_pExternalIndexBuffer; - int m_nExternalVertexBufferFirstIndex; - int m_nExternalVertexBufferFirstVertex; -#endif - - // [Shader System TO DO] - change this so that we don't deal with static slots assignments - // The following structure is practically used only once to set Instance texture coord matrix. - SEfResTexture* m_ShaderTexResources[MAX_TMU]; - - int m_Frame; - int m_FrameMerge; - - float m_fCurOpacity; - - SPipeStat m_PS[RT_COMMAND_BUF_COUNT]; - DynArray m_RTStats; - - int m_MaxVerts; - int m_MaxTris; - - int m_RECustomTexBind[8]; - int m_ShadowCustomTexBind[8]; - bool m_ShadowCustomComparisonSampling[8]; - - CRenderView* m_pCurrentFillView; - CRenderView* m_pCurrentRenderView; - std::shared_ptr m_pRenderViews[RT_COMMAND_BUF_COUNT]; - //=================================================================== - // Input render data - SRenderLight* m_pSunLight; - CThreadSafeWorkerContainer m_TempObjects[RT_COMMAND_BUF_COUNT]; - CRenderObject* m_ObjectsPool; - uint32 m_nNumObjectsInPool; - -#if !defined(_RELEASE) - //=================================================================== - // Drawcall count debug view - per Node - r_stats 6 - IRenderer::RNDrawcallsMapNode m_pRNDrawCallsInfoPerNode[RT_COMMAND_BUF_COUNT]; - - // Functionality for retrieving previous frames stats to use this frame - IRenderer::RNDrawcallsMapNode m_pRNDrawCallsInfoPerNodePreviousFrame[RT_COMMAND_BUF_COUNT]; - - //=================================================================== - // Drawcall count debug view - per mesh - perf hud renderBatchStats - IRenderer::RNDrawcallsMapMesh m_pRNDrawCallsInfoPerMesh[RT_COMMAND_BUF_COUNT]; - - // Functionality for retrieving previous frames stats to use this frame - IRenderer::RNDrawcallsMapMesh m_pRNDrawCallsInfoPerMeshPreviousFrame[RT_COMMAND_BUF_COUNT]; -#endif - - //================================================================ - // Render elements.. - - class CREHDRProcess* m_pREHDR; - class CREDeferredShading* m_pREDeferredShading; - class CREPostProcess* m_pREPostProcess; - - //================================================================= - // WaveForm tables - static const uint32 sSinTableCount = 1024; - float m_tSinTable[sSinTableCount]; - - // For explicit geometry cache motion blur - Matrix44A* m_pPrevMatrix; - -public: - SRenderPipeline() - : m_pShader(0) - , m_nShaderTechnique(-1) - , m_pCurTechnique(NULL) - , m_pREPostProcess(NULL) - , m_CurDownscaleFactor(Vec2(1.0f, 1.0f)) - , m_IndexStreamOffset(~0) - , m_IndexStreamType(Index16) - , m_ObjectsPool(NULL) - {} - - ~SRenderPipeline() - { -#if !defined(NULL_RENDERER) - for (unsigned int i = 0, n = m_CustomVD.Num(); i < n; i++) - { - delete m_CustomVD[i]; - } -#endif - } - - _inline SShaderTechnique* GetStartTechnique() const - { - if (m_pShader) - { - return m_pShader->mfGetStartTechnique(m_nShaderTechnique); - } - return NULL; - } - - static const uint32 sNumObjectsInPool = 1024; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - // don't add the following as these are intermediate members (might be NULL) and already accounted for - //pSizer->AddObject( m_pCurPass ); - //pSizer->AddObject( m_pCurTechnique ); - //pSizer->AddObject( m_pRootTechnique ); - - pSizer->AddObject(m_pSunLight); - pSizer->AddObject(m_sExcludeShader); - pSizer->AddObject(m_Profile); - - pSizer->AddObject(m_SysArray, m_SizeSysArray); - for (uint32 i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - pSizer->AddObject(m_TempObjects[i]); - for (uint32 j = 0; j < MAX_RECURSION_LEVELS; ++j) - { - pSizer->AddObject(m_DLights[i][j]); - } - pSizer->AddObject(m_SysVertexPool[i]); - pSizer->AddObject(m_SysIndexPool[i]); - pSizer->AddObject(m_fogVolumeContibutionsData[i]); - } - pSizer->AddObject(m_RIs); - pSizer->AddObject(m_RTStats); - } - - void SetRenderElement(IRenderElement* renderElement) - { - m_pRE = renderElement; - } -}; - -extern CryCriticalSection m_sREResLock; - -/////////////////////////////////////////////////////////////////////////////// -// sort opeartors for render items -struct SCompareItemPreprocess -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - if (a.nBatchFlags != b.nBatchFlags) - { - return a.nBatchFlags < b.nBatchFlags; - } - - return a.SortVal < b.SortVal; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareRendItem -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - /// Nearest objects should be rendered first - int nNearA = (a.ObjSort & FOB_HAS_PREVMATRIX); - int nNearB = (b.ObjSort & FOB_HAS_PREVMATRIX); - if (nNearA != nNearB) // Sort by nearest flag - { - return nNearA > nNearB; - } - - if (a.SortVal != b.SortVal) // Sort by shaders - { - return a.SortVal < b.SortVal; - } - - if (a.nTextureID != b.nTextureID) - { - return a.nTextureID < b.nTextureID; // Sort by object custom texture (usually terrain sector texture) - } - - if (a.pElem != b.pElem) // Sort by geometry - { - return a.pElem < b.pElem; - } - - return (a.ObjSort & 0xFFFF) < (b.ObjSort & 0xFFFF); // Sort by distance - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareRendItemZPass -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - const int layerSize = 50; // Note: ObjSort contains round(entityDist * 2) for meshes - - // Sort by nearest flag - int nNearA = (a.ObjSort & FOB_HAS_PREVMATRIX); - int nNearB = (b.ObjSort & FOB_HAS_PREVMATRIX); - if (nNearA != nNearB) - { - return nNearA > nNearB; - } - - if (a.SortVal != b.SortVal) // Sort by shaders - { - return a.SortVal < b.SortVal; - } - - // Sort by depth/distance layers - int depthLayerA = (a.ObjSort & 0xFFFF) / layerSize; - int depthLayerB = (b.ObjSort & 0xFFFF) / layerSize; - if (depthLayerA != depthLayerB) - { - return depthLayerA < depthLayerB; - } - - if (a.nStencRef != b.nStencRef) - { - return a.nStencRef < b.nStencRef; - } - if (a.nTextureID != b.nTextureID) - { - return a.nTextureID < b.nTextureID; // Sort by object custom texture (usually terrain sector texture) - } - - // Sorting by geometry less important than sorting by shaders - //if (a.Item != b.Item) // Sort by geometry - // return a.Item < b.Item; - - return (a.ObjSort & 0xFFFF) < (b.ObjSort & 0xFFFF); // Sort by distance - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareItem_Decal -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - uint32 objSortA_Low(a.ObjSort & 0xFFFF); - uint32 objSortA_High(a.ObjSort & ~0xFFFF); - uint32 objSortB_Low(b.ObjSort & 0xFFFF); - uint32 objSortB_High(b.ObjSort & ~0xFFFF); - - if (objSortA_Low != objSortB_Low) - { - return objSortA_Low < objSortB_Low; - } - - if (a.SortVal != b.SortVal) - { - return a.SortVal < b.SortVal; - } - - return objSortA_High < objSortB_High; - } -}; - -struct SCompareItem_Terrain -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - IRenderElement* pREa = a.pElem; - IRenderElement* pREb = b.pElem; - - if (pREa->GetCustomTexBind(0) != pREb->GetCustomTexBind(0)) - { - return pREa->GetCustomTexBind(0) < pREb->GetCustomTexBind(0); - } - - return a.ObjSort < b.ObjSort; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareItem_TerrainLayers -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - //if (a.ObjSort != b.ObjSort) - // return a.ObjSort < b.ObjSort; - - float pSurfTypeA = ((float*)a.pElem->GetCustomData())[8]; - float pSurfTypeB = ((float*)b.pElem->GetCustomData())[8]; - if (pSurfTypeA != pSurfTypeB) - { - return (pSurfTypeA < pSurfTypeB); - } - - pSurfTypeA = ((float*)a.pElem->GetCustomData())[9]; - pSurfTypeB = ((float*)b.pElem->GetCustomData())[9]; - if (pSurfTypeA != pSurfTypeB) - { - return (pSurfTypeA < pSurfTypeB); - } - - pSurfTypeA = ((float*)a.pElem->GetCustomData())[11]; - pSurfTypeB = ((float*)b.pElem->GetCustomData())[11]; - return (pSurfTypeA < pSurfTypeB); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareDist -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - if (fcmp(a.fDist, b.fDist)) - { - return a.rendItemSorter.ParticleCounter() < b.rendItemSorter.ParticleCounter(); - } - - return (a.fDist > b.fDist); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareDistInverted -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - if (fcmp(a.fDist, b.fDist)) - { - return a.rendItemSorter.ParticleCounter() > b.rendItemSorter.ParticleCounter(); - } - - return (a.fDist < b.fDist); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareByRenderingPass -{ - bool operator()(const SRendItem& rA, const SRendItem& rB) const - { - return rA.rendItemSorter.IsRecursivePass() < rB.rendItemSorter.IsRecursivePass(); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareByOnlyStableFlagsOctreeID -{ - bool operator()(const SRendItem& rA, const SRendItem& rB) const - { - return rA.rendItemSorter < rB.rendItemSorter; - } -}; diff --git a/Code/CryEngine/RenderDll/Common/RenderThread.cpp b/Code/CryEngine/RenderDll/Common/RenderThread.cpp deleted file mode 100644 index f90c8e58b2..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderThread.cpp +++ /dev/null @@ -1,3862 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include -#include -#include "RenderAuxGeom.h" -#include "IColorGradingControllerInt.h" -#include "PostProcess/PostEffects.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RENDERTHREAD_CPP_SECTION_1 1 -#define RENDERTHREAD_CPP_SECTION_2 2 -#define RENDERTHREAD_CPP_SECTION_3 3 -#define RENDERTHREAD_CPP_SECTION_4 4 -#define RENDERTHREAD_CPP_SECTION_5 5 -#define RENDERTHREAD_CPP_SECTION_6 6 -#define RENDERTHREAD_CPP_SECTION_7 7 -#define RENDERTHREAD_CPP_SECTION_8 8 -#endif - -#if !defined(NULL_RENDERER) -#include -#endif - -#include "MainThreadRenderRequestBus.h" -#include "Common/RenderView.h" -#include "Common/Textures/TextureManager.h" -#include "GraphicsPipeline/FurBendData.h" - -#include -#include -#include -#include - -#ifdef STRIP_RENDER_THREAD - #define m_nCurThreadFill 0 - #define m_nCurThreadProcess 0 -#endif - -#define MULTITHREADED_RESOURCE_CREATION - -#ifdef WIN32 -HWND SRenderThread::GetRenderWindowHandle() -{ - return (HWND)gRenDev->GetHWND(); -} -#endif - -CryCriticalSection SRenderThread::s_rcLock; - -# define LOADINGLOCK_COMMANDQUEUE (void)0; - -void CRenderThread::Run() -{ - //f_Log = fopen("Mouse.txt", "w"); - //fclose(f_Log); - - CryThreadSetName(threadID(THREADID_NULL), RENDER_THREAD_NAME); - gEnv->pSystem->GetIThreadTaskManager()->MarkThisThreadForDebugging(RENDER_THREAD_NAME, true); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - threadID renderThreadId = ::GetCurrentThreadId(); - gRenDev->m_pRT->m_nRenderThread = renderThreadId; - CNameTableR::m_nRenderThread = renderThreadId; - gEnv->pCryPak->SetRenderThreadId(AZStd::this_thread::get_id()); - //SetThreadAffinityMask(GetCurrentThread(), 2); - m_started.Set(); - - gRenDev->m_pRT->Process(); - - // Check pointers, it's not guaranteed that system is still valid. - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - gEnv->pSystem->GetIThreadTaskManager()->MarkThisThreadForDebugging(RENDER_THREAD_NAME, false); - } -} - -void CRenderThreadLoading::Run() -{ - CryThreadSetName(threadID(THREADID_NULL), RENDER_LOADING_THREAD_NAME); - gEnv->pSystem->GetIThreadTaskManager()->MarkThisThreadForDebugging(RENDER_LOADING_THREAD_NAME, true); - threadID renderThreadId = ::GetCurrentThreadId(); - gRenDev->m_pRT->m_nRenderThreadLoading = renderThreadId; - CNameTableR::m_nRenderThread = renderThreadId; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - - // We aren't interested in file access from the render loading thread, and this - // would overwrite the real render thread id - //gEnv->pCryPak->SetRenderThreadId( renderThreadId ); - m_started.Set(); - - gRenDev->m_pRT->ProcessLoading(); - - // Check pointers, it's not guaranteed that system is still valid. - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - gEnv->pSystem->GetIThreadTaskManager()->MarkThisThreadForDebugging(RENDER_LOADING_THREAD_NAME, false); - } -} - -void SRenderThread::SwitchMode(bool bEnableVideo) -{ - if (bEnableVideo) - { - assert(IsRenderThread()); - if (m_pThreadLoading) - { - return; - } -#if !defined(STRIP_RENDER_THREAD) - SSystemGlobalEnvironment* pEnv = iSystem->GetGlobalEnvironment(); - if (pEnv && !pEnv->bTesting && !pEnv->IsEditor() && pEnv->pi.numCoresAvailableToProcess > 1 && CRenderer::CV_r_multithreaded > 0) - { - m_pThreadLoading = new CRenderThreadLoading(1); - } - m_eVideoThreadMode = eVTM_Active; - m_bQuitLoading = false; - StartRenderLoadingThread(); -#endif - } - else - { - m_eVideoThreadMode = eVTM_ProcessingStop; - } -} - -SRenderThread::SRenderThread() -{ - m_eVideoThreadMode = eVTM_Disabled; - m_nRenderThreadLoading = 0; - m_pThreadLoading = 0; - m_pLoadtimeCallback = 0; - m_bEndFrameCalled = false; - m_bBeginFrameCalled = false; - m_bQuitLoading = false; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - m_FlushFinishedCondition = CreateEvent(NULL, FALSE, FALSE, "FlushFinishedCondition"); -#endif - Init(2); -} - -threadID CNameTableR::m_nRenderThread = 0; - -void SRenderThread::Init(int nCPU) -{ - m_bQuit = false; -#ifndef STRIP_RENDER_THREAD - m_nCurThreadFill = 0; - m_nCurThreadProcess = 0; -#endif - InitFlushCond(); - m_nRenderThread = ::GetCurrentThreadId(); - CNameTableR::m_nRenderThread = m_nRenderThread; - m_nMainThread = m_nRenderThread; - m_bSuccessful = true; - m_pThread = NULL; - m_fTimeIdleDuringLoading = 0; - m_fTimeBusyDuringLoading = 0; -#if !defined(STRIP_RENDER_THREAD) - SSystemGlobalEnvironment* pEnv = iSystem->GetGlobalEnvironment(); - if (pEnv && !pEnv->bTesting && !pEnv->IsDedicated() && !pEnv->IsEditor() && pEnv->pi.numCoresAvailableToProcess > 1 && CRenderer::CV_r_multithreaded > 0) - { - m_nCurThreadProcess = 1; - m_pThread = new CRenderThread(nCPU); - } -#ifndef CONSOLE_CONST_CVAR_MODE - else - { - CRenderer::CV_r_multithreaded = 0; - } -#endif -#else//STRIP_RENDER_THREAD - #ifndef CONSOLE_CONST_CVAR_MODE - CRenderer::CV_r_multithreaded = 0; - #endif -#endif//STRIP_RENDER_THREAD - gRenDev->m_RP.m_nProcessThreadID = threadID(m_nCurThreadProcess); - gRenDev->m_RP.m_nFillThreadID = threadID(m_nCurThreadFill); - - for (uint32 i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_Commands[i].Free(); - m_Commands[i].Create(300 * 1024); // 300 to stop growing in MP levels - m_Commands[i].SetUse(0); - gRenDev->m_fTimeWaitForMain[i] = 0; - gRenDev->m_fTimeWaitForRender[i] = 0; - gRenDev->m_fTimeProcessedRT[i] = 0; - gRenDev->m_fTimeProcessedGPU[i] = 0; - } - m_eVideoThreadMode = eVTM_Disabled; -} - -SRenderThread::~SRenderThread() -{ - QuitRenderLoadingThread(); - QuitRenderThread(); -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - CloseHandle(m_FlushFinishedCondition); -#endif -} - -void SRenderThread::ValidateThreadAccess(ERenderCommand eRC) -{ - if (!IsMainThread() && !gRenDev->m_bStartLevelLoading) - { - CryFatalError("Trying to add a render command from a non-main thread, eRC = %d", (int)eRC); - } -} - -//============================================================================================== -// NOTE: Render commands can be added from main thread only - -bool SRenderThread::RC_CreateDevice() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) || defined(CREATE_DEVICE_ON_MAIN_THREAD) - return gRenDev->RT_CreateDevice(); -#else - if (IsRenderThread()) - { - return gRenDev->RT_CreateDevice(); - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateDevice, 0); - EndCommand(p); - - FlushAndWait(); - - return !IsFailed(); -#endif -} - -void SRenderThread::RC_ResetDevice() -{ - AZ_TRACE_METHOD(); -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) || defined(CREATE_DEVICE_ON_MAIN_THREAD) - gRenDev->RT_Reset(); -#else - if (IsRenderThread()) - { - gRenDev->RT_Reset(); - return; - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ResetDevice, 0); - EndCommand(p); - - FlushAndWait(); -#endif -} - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - -void SRenderThread::RC_PreloadTextures() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return CTexture::RT_Precache(); - } - LOADINGLOCK_COMMANDQUEUE - { - byte* p = AddCommand(eRC_PreloadTextures, 0); - EndCommand(p); - FlushAndWait(); - } -} - -void SRenderThread::RC_Init() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - - if (IsRenderThread()) - { - return gRenDev->RT_Init(); - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_Init, 0); - EndCommand(p); - - FlushAndWait(); -} -void SRenderThread::RC_ShutDown(uint32 nFlags) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return gRenDev->RT_ShutDown(nFlags); - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ShutDown, 4); - AddDWORD(p, nFlags); - - FlushAndWait(); -} - - -void SRenderThread::RC_ResetGlass() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ResetGlass(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ResetGlass, 0); - EndCommand(p); -} - - -void SRenderThread::RC_ResetToDefault() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->ResetToDefault(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ResetToDefault, 0); - EndCommand(p); -} - -void SRenderThread::RC_ParseShader (CShader* pSH, uint64 nMaskGen, uint32 flags, CShaderResources* pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread(true)) - { - return gRenDev->m_cEF.RT_ParseShader(pSH, nMaskGen, flags, pRes); - } - - if (!IsMainThread(true)) - { - pSH->AddRef(); - if (pRes) - { - pRes->AddRef(); - } - - AZStd::function runOnMainThread = [this, pSH, nMaskGen, flags, pRes]() - { - RC_ParseShader(pSH, nMaskGen, flags, pRes); - - pSH->Release(); - if (pRes) - { - pRes->Release(); - } - - // Make sure any materials using this shader get updated appropriately. - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->UpdateShaderItems(); - } - }; - - EBUS_QUEUE_FUNCTION(AZ::MainThreadRenderRequestBus, runOnMainThread); - return; - } - - LOADINGLOCK_COMMANDQUEUE - pSH->AddRef(); - if (pRes) - { - pRes->AddRef(); - } - byte* p = AddCommand(eRC_ParseShader, 12 + 2 * sizeof(void*)); - AddPointer(p, pSH); - AddPointer(p, pRes); - AddDWORD64(p, nMaskGen); - AddDWORD(p, flags); - EndCommand(p); -} - -void SRenderThread::RC_UpdateShaderItem (SShaderItem* pShaderItem, _smart_ptr pMaterial) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread(true)) - { - return gRenDev->RT_UpdateShaderItem(pShaderItem, pMaterial.get()); - } - - if (!IsMainThread(true)) - { - AZStd::function runOnMainThread = [this, pShaderItem, pMaterial]() - { - RC_UpdateShaderItem(pShaderItem, pMaterial); - }; - - EBUS_QUEUE_FUNCTION(AZ::MainThreadRenderRequestBus, runOnMainThread); - return; - } - - LOADINGLOCK_COMMANDQUEUE - // We pass the raw pointer instead of the smart_ptr because writing/reading smart pointers from - // the render thread queue causes the ref count to be increased incorrectly in some platforms (e.g. 32 bit architectures). - // Because of this we manually increment the reference count before adding it to the queue and decrement it when we finish using it in the RenderThread. - IMaterial* materialRawPointer = pMaterial.get(); - if (materialRawPointer) - { - // Add a reference to prevent it from getting deleted before the RenderThread process the message. - materialRawPointer->AddRef(); - } - - if (m_eVideoThreadMode == eVTM_Disabled) - { - byte* p = AddCommand(eRC_UpdateShaderItem, sizeof(pShaderItem) + sizeof(materialRawPointer)); - AddPointer(p, pShaderItem); - AddPointer(p, materialRawPointer); - EndCommand(p); - } - else - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_UpdateShaderItem, sizeof(pShaderItem) + sizeof(materialRawPointer), m_CommandsLoading); - AddPointer(p, pShaderItem); - AddPointer(p, pMaterial); - EndCommandTo(p, m_CommandsLoading); - } -} - -void SRenderThread::RC_RefreshShaderResourceConstants(SShaderItem* shaderItem, IMaterial* material) -{ - if (IsRenderThread()) - { - return gRenDev->RT_RefreshShaderResourceConstants(shaderItem); - } - - LOADINGLOCK_COMMANDQUEUE; - - if (material) - { - // Add a reference to prevent it from getting deleted before the RenderThread process the message. - material->AddRef(); - } - - if (m_eVideoThreadMode == eVTM_Disabled) - { - byte* p = AddCommand(eRC_RefreshShaderResourceConstants, sizeof(SShaderItem*) + sizeof(IMaterial*)); - AddPointer(p, shaderItem); - AddPointer(p, material); - EndCommand(p); - } - else - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_RefreshShaderResourceConstants, sizeof(SShaderItem*) + sizeof(IMaterial*), m_CommandsLoading); - AddPointer(p, shaderItem); - AddPointer(p, material); - EndCommandTo(p, m_CommandsLoading); - } -} - -void SRenderThread::RC_SetShaderQuality(EShaderType eST, EShaderQuality eSQ) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return gRenDev->m_cEF.RT_SetShaderQuality(eST, eSQ); - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetShaderQuality, 8); - AddDWORD(p, eST); - AddDWORD(p, eSQ); - EndCommand(p); -} - - - -void SRenderThread::RC_ReleaseVBStream(void* pVB, int nStream) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ReleaseVBStream(pVB, nStream); - return; - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseVBStream, 4 + sizeof(void*)); - AddPointer(p, pVB); - AddDWORD(p, nStream); - EndCommand(p); -} - -void SRenderThread::RC_ForceMeshGC(bool instant, bool wait) -{ - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION; - - if (IsRenderThread()) - { - CRenderMesh::Tick(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ForceMeshGC, 0); - EndCommand(p); - - if (instant) - { - if (wait) - { - FlushAndWait(); - } - else - { - SyncMainWithRender(); - } - } -} - - -void SRenderThread::RC_DevBufferSync() -{ - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION; - - if (IsRenderThread()) - { - gRenDev->m_DevBufMan.Sync(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DevBufferSync, 0); - EndCommand(p); -} - -void SRenderThread::RC_ReleasePostEffects() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - if (gRenDev->m_pPostProcessMgr) - { - gRenDev->m_pPostProcessMgr->ReleaseResources(); - } - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleasePostEffects, 0); - EndCommand(p); -} - -void SRenderThread::RC_ResetPostEffects(bool bOnSpecChange) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - if (gRenDev->m_RP.m_pREPostProcess) - { - gRenDev->m_RP.m_pREPostProcess->Reset(bOnSpecChange); - } - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(bOnSpecChange ? eRC_ResetPostEffectsOnSpecChange : eRC_ResetPostEffects, 0); - EndCommand(p); - FlushAndWait(); -} - -void SRenderThread::RC_DisableTemporalEffects() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return gRenDev->RT_DisableTemporalEffects(); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DisableTemporalEffects, 0); - EndCommand(p); -} - -void SRenderThread::RC_UpdateTextureRegion(CTexture* pTex, const byte* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return pTex->RT_UpdateTextureRegion(data, nX, nY, nZ, USize, VSize, ZSize, eTFSrc); - } - - LOADINGLOCK_COMMANDQUEUE - int nSize = CTexture::TextureDataSize(USize, VSize, ZSize, pTex->GetNumMips(), 1, eTFSrc); - byte* pData = new byte[nSize]; - cryMemcpy(pData, data, nSize); - pTex->AddRef(); - - if (m_eVideoThreadMode == eVTM_Disabled) - { - byte* p = AddCommand(eRC_UpdateTexture, 28 + 2 * sizeof(void*)); - AddPointer(p, pTex); - AddPointer(p, pData); - AddDWORD(p, nX); - AddDWORD(p, nY); - AddDWORD(p, nZ); - AddDWORD(p, USize); - AddDWORD(p, VSize); - AddDWORD(p, ZSize); - AddDWORD(p, eTFSrc); - EndCommand(p); - } - else - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_UpdateTexture, 28 + 2 * sizeof(void*), m_CommandsLoading); - AddPointer(p, pTex); - AddPointer(p, pData); - AddDWORD(p, nX); - AddDWORD(p, nY); - AddDWORD(p, nZ); - AddDWORD(p, USize); - AddDWORD(p, VSize); - AddDWORD(p, ZSize); - AddDWORD(p, eTFSrc); - EndCommandTo(p, m_CommandsLoading); - } -} - -bool SRenderThread::RC_DynTexUpdate(SDynTexture* pTex, int nNewWidth, int nNewHeight) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return pTex->RT_Update(nNewWidth, nNewHeight); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DynTexUpdate, 8 + sizeof(void*)); - AddPointer(p, pTex); - AddDWORD(p, nNewWidth); - AddDWORD(p, nNewHeight); - EndCommand(p); - - return true; -} - -void SRenderThread::RC_EntityDelete(IRenderNode* pRenderNode) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return SDynTexture_Shadow::RT_EntityDelete(pRenderNode); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_EntityDelete, sizeof(void*)); - AddPointer(p, pRenderNode); - EndCommand(p); -} - -void TexBlurAnisotropicVertical(CTexture* pTex, int nAmount, float fScale, float fDistribution, bool bAlphaOnly); - -void SRenderThread::RC_TexBlurAnisotropicVertical(CTexture* Tex, float fAnisoScale) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - TexBlurAnisotropicVertical(Tex, 1, 8 * max(1.0f - min(fAnisoScale / 100.0f, 1.0f), 0.2f), 1, false); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_TexBlurAnisotropicVertical, 4 + sizeof(void*)); - AddPointer(p, Tex); - AddFloat(p, fAnisoScale); - EndCommand(p); -} - -bool SRenderThread::RC_CreateDeviceTexture(CTexture* pTex, const byte* pData[6]) -{ - AZ_TRACE_METHOD(); -#if !defined(MULTITHREADED_RESOURCE_CREATION) - if (IsRenderThread()) -#endif - { - return pTex->RT_CreateDeviceTexture(pData); - } - -#if !defined(MULTITHREADED_RESOURCE_CREATION) - if (pTex->IsAsyncDevTexCreation()) - { - return !IsFailed(); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateDeviceTexture, 7 * sizeof(void*)); - AddPointer(p, pTex); - for (int i = 0; i < 6; i++) - { - AddPointer(p, pData[i]); - } - EndCommand(p); - FlushAndWait(); - - return !IsFailed(); -#endif -} - -void SRenderThread::RC_CopyDataToTexture( - void* pkVoid, unsigned int uiStartMip, unsigned int uiEndMip) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - CTexture* pkTexture = (CTexture*) pkVoid; - pkTexture->StreamCopyMipsTexToMem(uiStartMip, uiEndMip, true, NULL); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CopyDataToTexture, 8 + sizeof(void*)); - AddPointer(p, pkVoid); - AddDWORD(p, uiStartMip); - AddDWORD(p, uiEndMip); - EndCommand(p); - // -- kenzo: removing this causes crashes because the texture - // might have already been destroyed. This needs to be fixed - // somehow that the createtexture doesn't require the renderthread - // (PC only issue) - FlushAndWait(); -} - -void SRenderThread::RC_ClearTarget(void* pkVoid, const ColorF& kColor) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - CTexture* pkTexture = (CTexture*) pkVoid; - gRenDev->RT_ClearTarget(pkTexture, kColor); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ClearTarget, sizeof(void*) + sizeof(ColorF)); - AddPointer(p, pkVoid); - AddColor(p, kColor); - EndCommand(p); - FlushAndWait(); -} - -void SRenderThread::RC_CreateResource(SResourceAsync* pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_CreateResource(pRes); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateResource, sizeof(void*)); - AddPointer(p, pRes); - EndCommand(p); -} - -void SRenderThread::RC_StartVideoThread() -{ - AZ_TRACE_METHOD(); - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_StartVideoThread, 0); - EndCommand(p); -} - -void SRenderThread::RC_StopVideoThread() -{ - AZ_TRACE_METHOD(); - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_StopVideoThread, 0); - EndCommand(p); -} - -void SRenderThread::RC_PreactivateShaders() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - CHWShader::RT_PreactivateShaders(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PreactivateShaders, 0); - EndCommand(p); -} - -void SRenderThread::RC_PrecacheShader(CShader* pShader, SShaderCombination& cmb, bool bForce, bool bCompressedOnly, CShaderResources* pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderLoadingThread()) - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_PrecacheShader, sizeof(void*) * 2 + 8 + sizeof(SShaderCombination), m_CommandsLoading); - pShader->AddRef(); - if (pRes) - { - pRes->AddRef(); - } - AddPointer(p, pShader); - memcpy(p, &cmb, sizeof(cmb)); - p += sizeof(SShaderCombination); - AddDWORD(p, bForce); - AddDWORD(p, bCompressedOnly); - AddPointer(p, pRes); - EndCommandTo(p, m_CommandsLoading); - } - else if (IsRenderThread()) - { - pShader->mfPrecache(cmb, bForce, bCompressedOnly, pRes); - return; - } - else - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PrecacheShader, sizeof(void*) * 2 + 8 + sizeof(SShaderCombination)); - pShader->AddRef(); - if (pRes) - { - pRes->AddRef(); - } - AddPointer(p, pShader); - memcpy(p, &cmb, sizeof(cmb)); - p += sizeof(SShaderCombination); - AddDWORD(p, bForce); - AddDWORD(p, bCompressedOnly); - AddPointer(p, pRes); - EndCommand(p); - } -} - -void SRenderThread::RC_ReleaseBaseResource(CBaseResource* pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderLoadingThread()) - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_ReleaseBaseResource, sizeof(void*), m_CommandsLoading); - AddPointer(p, pRes); - EndCommandTo(p, m_CommandsLoading); - } - else if (IsRenderThread()) - { - SAFE_DELETE(pRes); - return; - } - else - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseBaseResource, sizeof(void*)); - AddPointer(p, pRes); - EndCommand(p); - } -} - -void SRenderThread::RC_ReleaseFont(IFFont* font) -{ - AZ_TRACE_METHOD(); - if (IsRenderLoadingThread()) - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_ReleaseFont, sizeof(void*), m_CommandsLoading); - AddPointer(p, font); - EndCommandTo(p, m_CommandsLoading); - } - else if (IsRenderThread()) - { - SAFE_DELETE(font); - return; - } - else - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseFont, sizeof(void*)); - AddPointer(p, font); - EndCommand(p); - } -} - -void SRenderThread::RC_ReleaseSurfaceResource(SDepthTexture* pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - if (pRes) - { - pRes->Release(true); - } - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseSurfaceResource, sizeof(void*)); - AddPointer(p, pRes); - EndCommand(p); -} - -void SRenderThread::RC_ReleaseResource(SResourceAsync* pRes) -{ - RC_ReleaseResource(AZStd::unique_ptr(pRes)); -} - -void SRenderThread::RC_ReleaseResource(AZStd::unique_ptr pRes) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ReleaseResource(pRes.release()); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseResource, sizeof(void*)); - // Move owner over the SResourceAsync over to the renderer command queue - AddPointer(p, pRes.release()); - EndCommand(p); -} - -void SRenderThread::RC_UnbindTMUs() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_UnbindTMUs(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_UnbindTMUs, 0); - EndCommand(p); -} - -void SRenderThread::RC_UnbindResources() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_UnbindResources(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_UnbindResources, 0); - EndCommand(p); -} - -void SRenderThread::RC_ReleaseRenderResources() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ReleaseRenderResources(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseRenderResources, 0); - EndCommand(p); -} -void SRenderThread::RC_CreateRenderResources() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_CreateRenderResources(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateRenderResources, 0); - EndCommand(p); -} - -void SRenderThread::RC_CreateSystemTargets() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - CTexture::CreateSystemTargets(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateSystemTargets, 0); - EndCommand(p); -} - -void SRenderThread::RC_PrecacheDefaultShaders() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_PrecacheDefaultShaders(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PrecacheDefaultShaders, 0); - EndCommand(p); -} - -void SRenderThread::RC_RelinkTexture(CTexture* pTex) -{ - if (IsRenderThread(true)) - { - pTex->RT_Relink(); - return; - } - - if (!IsMainThread(true)) - { - AZStd::function runOnMainThread = [this, pTex]() - { - RC_RelinkTexture(pTex); - }; - - EBUS_QUEUE_FUNCTION(AZ::MainThreadRenderRequestBus, runOnMainThread); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_RelinkTexture, sizeof(void*)); - AddPointer(p, pTex); - EndCommand(p); -} - -void SRenderThread::RC_UnlinkTexture(CTexture* pTex) -{ - if (IsRenderThread()) - { - pTex->RT_Unlink(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_UnlinkTexture, sizeof(void*)); - AddPointer(p, pTex); - EndCommand(p); -} - -void SRenderThread::RC_CreateREPostProcess(CRendElementBase** re) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return gRenDev->RT_CreateREPostProcess(re); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CreateREPostProcess, sizeof(void*)); - AddPointer(p, re); - EndCommand(p); - - FlushAndWait(); -} - -bool SRenderThread::RC_CheckUpdate2(CRenderMesh* pMesh, CRenderMesh* pVContainer, uint32 nStreamMask) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return pMesh->RT_CheckUpdate(pVContainer, nStreamMask); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_UpdateMesh2, 8 + 2 * sizeof(void*)); - AddPointer(p, pMesh); - AddPointer(p, pVContainer); - AddDWORD(p, nStreamMask); - EndCommand(p); - - FlushAndWait(); - - return !IsFailed(); -} - -void SRenderThread::RC_ReleaseVB(buffer_handle_t nID) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->m_DevBufMan.Destroy(nID); - return; - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseVB, sizeof(buffer_handle_t)); - AddDWORD64(p, nID); - EndCommand(p); -} -void SRenderThread::RC_ReleaseIB(buffer_handle_t nID) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->m_DevBufMan.Destroy(nID); - return; - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseIB, sizeof(buffer_handle_t)); - AddDWORD64(p, nID); - EndCommand(p); -} - -void SRenderThread::RC_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_DrawDynVB(pBuf, pInds, nVerts, nInds, nPrimType); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DrawDynVB, Align4(20 + sizeof(SVF_P3F_C4B_T2F) * nVerts + sizeof(uint16) * nInds)); - AddData(p, pBuf, sizeof(SVF_P3F_C4B_T2F) * nVerts); - AddData(p, pInds, sizeof(uint16) * nInds); - AddDWORD(p, nVerts); - AddDWORD(p, nInds); - AddDWORD(p, (int)nPrimType); - EndCommand(p); -} - -void SRenderThread::RC_DrawDynUiPrimitiveList(IRenderer::DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices) -{ - AZ_TRACE_METHOD(); - - if (IsRenderThread()) - { - // When this is called on the render thread we do not currently combine the draw calls since we would - // have to allocate a new buffer to do so using RT_DrawDynVBUI. - // We could avoid the allocate by having a RT_DrawDynUiPrimitiveList which was only used - // when RC_DrawDynUiPrimitiveList is called on the render thread. It would have to do some - // fancy stuff with TempDynVB. Currently we are optimizing the case where there is a separate - // render thread so this is not a priority. - for (const IRenderer::DynUiPrimitive& primitive : primitives) - { - gRenDev->RT_DrawDynVBUI(primitive.m_vertices, primitive.m_indices, primitive.m_numVertices, primitive.m_numIndices, prtTriangleList); - } - return; - } - - size_t vertsSizeInBytes = Align4(sizeof(SVF_P2F_C4B_T2F_F4B) * totalNumVertices); - size_t indsSizeInBytes = Align4(sizeof(uint16) * totalNumIndices); - - LOADINGLOCK_COMMANDQUEUE - const size_t fixedCommandSize = 5 * sizeof(uint32); // accounts for the 5 calls to AddDWORD below - byte* p = AddCommand(eRC_DrawDynVBUI, fixedCommandSize + vertsSizeInBytes + indsSizeInBytes); - - // we can't use AddPtr for each primitive since that adds a length then memcpy's the pointer - // we want all the vertices added to the queue as one length plus one data chunk. - // Same for indices. - - // We know SVF_P2F_C4B_T2F_F4B is a multiple of 4 bytes so no padding needed - AddDWORD(p, vertsSizeInBytes); - for (const IRenderer::DynUiPrimitive& primitive : primitives) - { - memcpy(p, primitive.m_vertices, sizeof(SVF_P2F_C4B_T2F_F4B) * primitive.m_numVertices); - p += sizeof(SVF_P2F_C4B_T2F_F4B) * primitive.m_numVertices; - } - - AddDWORD(p, indsSizeInBytes); - // when copying the indicies we have to adjust them to be the correct index in the combined vertex buffer - uint16 vbOffset = 0; - for (const IRenderer::DynUiPrimitive& primitive : primitives) - { - uint16* pIndex = reinterpret_cast(p); - for (int i = 0; i < primitive.m_numIndices; ++i) - { - pIndex[i] = primitive.m_indices[i] + vbOffset; - } - p += sizeof(uint16) * primitive.m_numIndices; - vbOffset += primitive.m_numVertices; - } - // uint16 is not a multiple of 4 bytes so if there is an odd number of indices we need to pad - unsigned pad = indsSizeInBytes - sizeof(uint16) * totalNumIndices; - p += pad; - - AddDWORD(p, totalNumVertices); - AddDWORD(p, totalNumIndices); - AddDWORD(p, (int)prtTriangleList); - EndCommand(p); -} - -void SRenderThread::RC_Draw2dImageStretchMode(bool bStretch) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_Draw2dImageStretchMode(bStretch); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_Draw2dImageStretchMode, sizeof(DWORD)); - AddDWORD(p, (DWORD)bStretch); - EndCommand(p); -} - -void SRenderThread::RC_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, float r, float g, float b, float a, float z) -{ - AZ_TRACE_METHOD(); - DWORD col = D3DRGBA(r, g, b, a); - - if (IsRenderThread()) - { - // don't render using fixed function pipeline when video mode is active - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_Draw2dImage(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z); - } - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_Draw2dImage, 44 + sizeof(void*)); - AddFloat(p, xpos); - AddFloat(p, ypos); - AddFloat(p, w); - AddFloat(p, h); - AddPointer(p, pTexture); - AddFloat(p, s0); - AddFloat(p, t0); - AddFloat(p, s1); - AddFloat(p, t1); - AddFloat(p, angle); - AddDWORD(p, col); - AddFloat(p, z); - EndCommand(p); -} - -void SRenderThread::RC_Push2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, float r, float g, float b, float a, float z, float stereoDepth) -{ - AZ_TRACE_METHOD(); - DWORD col = D3DRGBA(r, g, b, a); - - if (IsRenderThread()) - { - gRenDev->RT_Push2dImage(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z, stereoDepth); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_Push2dImage, 48 + sizeof(void*)); - AddFloat(p, xpos); - AddFloat(p, ypos); - AddFloat(p, w); - AddFloat(p, h); - AddPointer(p, pTexture); - AddFloat(p, s0); - AddFloat(p, t0); - AddFloat(p, s1); - AddFloat(p, t1); - AddFloat(p, angle); - AddDWORD(p, col); - AddFloat(p, z); - AddFloat(p, stereoDepth); - EndCommand(p); -} - -void SRenderThread::RC_Draw2dImageList() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_Draw2dImageList(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_Draw2dImageList, 0); - EndCommand(p); -} - -void SRenderThread::RC_DrawImageWithUV(float xpos, float ypos, float z, float w, float h, int textureid, float* s, float* t, float r, float g, float b, float a, bool filtered) -{ - AZ_TRACE_METHOD(); - DWORD col = D3DRGBA(r, g, b, a); - if (IsRenderThread()) - { - gRenDev->RT_DrawImageWithUV(xpos, ypos, z, w, h, textureid, s, t, col, filtered); - return; - } - - int i; - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DrawImageWithUV, 32 + 8 * 4); - AddFloat(p, xpos); - AddFloat(p, ypos); - AddFloat(p, z); - AddFloat(p, w); - AddFloat(p, h); - AddDWORD(p, textureid); - for (i = 0; i < 4; i++) - { - AddFloat(p, s[i]); - } - for (i = 0; i < 4; i++) - { - AddFloat(p, t[i]); - } - AddDWORD(p, col); - AddDWORD(p, filtered); - EndCommand(p); -} - -void SRenderThread::RC_SetState(int State, int AlphaRef) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->FX_SetState(State, AlphaRef); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetState, 8); - AddDWORD(p, State); - AddDWORD(p, AlphaRef); - EndCommand(p); -} - -void SRenderThread::RC_SetStencilState(int st, uint32 nStencRef, uint32 nStencMask, uint32 nStencWriteMask, bool bForceFullReadMask) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->FX_SetStencilState(st, nStencRef, nStencMask, nStencWriteMask, bForceFullReadMask); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetStencilState, 20); - AddDWORD(p, st); - AddDWORD(p, nStencRef); - AddDWORD(p, nStencMask); - AddDWORD(p, nStencWriteMask); - AddDWORD(p, bForceFullReadMask); - EndCommand(p); -} - -void SRenderThread::RC_SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->EF_SetColorOp(eCo, eAo, eCa, eAa); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetColorOp, 16); - - AddDWORD(p, eCo); - AddDWORD(p, eAo); - AddDWORD(p, eCa); - AddDWORD(p, eAa); - - EndCommand(p); -} - -void SRenderThread::RC_SetSrgbWrite(bool srgbWrite) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->EF_SetSrgbWrite(srgbWrite); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetSrgbWrite, 4); - - AddDWORD(p, srgbWrite); - - EndCommand(p); -} - -void SRenderThread::RC_PushWireframeMode(int nMode) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->FX_PushWireframeMode(nMode); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushWireframeMode, 4); - AddDWORD(p, nMode); - EndCommand(p); -} - -void SRenderThread::RC_PopWireframeMode() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->FX_PopWireframeMode(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PopWireframeMode, 0); - EndCommand(p); -} - - -void SRenderThread::RC_SetCull(int nMode) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_SetCull(nMode); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetCull, 4); - AddDWORD(p, nMode); - EndCommand(p); -} - -void SRenderThread::RC_SetScissor(bool bEnable, int sX, int sY, int sWdt, int sHgt) -{ - if (IsRenderThread()) - { - gRenDev->RT_SetScissor(bEnable, sX, sY, sWdt, sHgt); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetScissor, sizeof(DWORD) * 5); - AddDWORD(p, bEnable); - AddDWORD(p, sX); - AddDWORD(p, sY); - AddDWORD(p, sWdt); - AddDWORD(p, sHgt); - EndCommand(p); -} - -void SRenderThread::RC_PushProfileMarker(const char* label) -{ - AZ_TRACE_METHOD(); - if (IsRenderLoadingThread()) - { - return; - } - if (IsRenderThread()) - { - gRenDev->SetProfileMarker(label, CRenderer::ESPM_PUSH); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushProfileMarker, sizeof(void*)); - AddPointer(p, label); - EndCommand(p); -} - -void SRenderThread::RC_PopProfileMarker(const char* label) -{ - AZ_TRACE_METHOD(); - if (IsRenderLoadingThread()) - { - return; - } - if (IsRenderThread()) - { - gRenDev->SetProfileMarker(label, CRenderer::ESPM_POP); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PopProfileMarker, sizeof(void*)); - AddPointer(p, label); - EndCommand(p); -} - -void SRenderThread::RC_ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX, int nScaledY) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ReadFrameBuffer(pRGB, nImageX, nSizeX, nSizeY, eRBType, bRGBA, nScaledX, nScaledY); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReadFrameBuffer, 28 + sizeof(void*)); - AddPointer(p, pRGB); - AddDWORD(p, nImageX); - AddDWORD(p, nSizeX); - AddDWORD(p, nSizeY); - AddDWORD(p, eRBType); - AddDWORD(p, bRGBA); - AddDWORD(p, nScaledX); - AddDWORD(p, nScaledY); - EndCommand(p); - - FlushAndWait(); -} - -void SRenderThread::RC_SetCamera() -{ - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - size_t commandSize = sizeof(Matrix44) * 3 + sizeof(CameraViewParameters); - byte* pData = AddCommand(eRC_SetCamera, Align4(commandSize)); - - gRenDev->GetProjectionMatrix((float*)&pData[0]); - gRenDev->GetModelViewMatrix((float*)&pData[sizeof(Matrix44)]); - *(Matrix44*)((float*)&pData[sizeof(Matrix44) * 2]) = gRenDev->m_CameraZeroMatrix[m_nCurThreadFill]; - *(CameraViewParameters*)(&pData[sizeof(Matrix44) * 3]) = gRenDev->GetViewParameters(); - - if (gRenDev->m_RP.m_TI[m_nCurThreadFill].m_PersFlags & RBPF_OBLIQUE_FRUSTUM_CLIPPING) - { - Matrix44A mObliqueProjMatrix; - mObliqueProjMatrix.SetIdentity(); - - Plane pPlane = gRenDev->m_RP.m_TI[m_nCurThreadFill].m_pObliqueClipPlane; - - mObliqueProjMatrix.m02 = pPlane.n[0]; - mObliqueProjMatrix.m12 = pPlane.n[1]; - mObliqueProjMatrix.m22 = pPlane.n[2]; - mObliqueProjMatrix.m32 = pPlane.d; - - Matrix44* mProj = (Matrix44*)&pData[0]; - *mProj = (*mProj) * mObliqueProjMatrix; - - gRenDev->m_RP.m_TI[m_nCurThreadFill].m_PersFlags &= ~RBPF_OBLIQUE_FRUSTUM_CLIPPING; - } - - pData += Align4(commandSize); - EndCommand(pData); - } - else - { - gRenDev->RT_SetCameraInfo(); - } -} - -void SRenderThread::RC_PostLoadLevel() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_PostLevelLoading(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PostLevelLoading, 0); - EndCommand(p); -} - -void SRenderThread::RC_PushFog() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushFog, 0); - EndCommand(p); - } - else - { - gRenDev->EF_PushFog(); - } -} - -void SRenderThread::RC_PopFog() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PopFog, 0); - EndCommand(p); - } - else - { - gRenDev->EF_PopFog(); - } -} - -void SRenderThread::RC_PushVP() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushVP, 0); - EndCommand(p); - } - else - { - gRenDev->FX_PushVP(); - } -} - -void SRenderThread::RC_PopVP() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PopVP, 0); - EndCommand(p); - } - else - { - gRenDev->FX_PopVP(); - } -} - -void SRenderThread::RC_RenderTextMessages() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_RenderTextMessages, 0); - EndCommand(p); - } - else - { - gRenDev->RT_RenderTextMessages(); - } -} - -void SRenderThread::RC_FlushTextureStreaming(bool bAbort) -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_FlushTextureStreaming, sizeof(DWORD)); - AddDWORD(p, bAbort); - EndCommand(p); - } - else - { - CTexture::RT_FlushStreaming(bAbort); - } -} - -void SRenderThread::RC_ReleaseSystemTextures() -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseSystemTextures, 0); - EndCommand(p); - } - else - { - CTextureManager::Instance()->Release(); - CTexture::ReleaseSystemTextures(); - } -} - -void SRenderThread::RC_SetEnvTexRT(SEnvTexture* pEnvTex, int nWidth, int nHeight, bool bPush) -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetEnvTexRT, 12 + sizeof(void*)); - AddPointer(p, pEnvTex); - AddDWORD(p, nWidth); - AddDWORD(p, nHeight); - AddDWORD(p, bPush); - EndCommand(p); - } - else - { - pEnvTex->m_pTex->RT_SetRT(0, nWidth, nHeight, bPush); - } -} - - -void SRenderThread::RC_SetEnvTexMatrix(SEnvTexture* pEnvTex) -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetEnvTexMatrix, sizeof(void*)); - AddPointer(p, pEnvTex); - EndCommand(p); - } - else - { - pEnvTex->RT_SetMatrix(); - } -} - -void SRenderThread::RC_PushRT(int nTarget, CTexture* pTex, SDepthTexture* pDS, int nS) -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushRT, 8 + 2 * sizeof(void*)); - AddDWORD(p, nTarget); - AddPointer(p, pTex); - AddPointer(p, pDS); - AddDWORD(p, nS); - EndCommand(p); - } - else - { - gRenDev->RT_PushRenderTarget(nTarget, pTex, pDS, nS); - } -} -void SRenderThread::RC_PopRT(int nTarget) -{ - AZ_TRACE_METHOD(); - if (!IsRenderThread()) - { - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PopRT, 4); - AddDWORD(p, nTarget); - EndCommand(p); - } - else - { - gRenDev->RT_PopRenderTarget(nTarget); - } -} - -void SRenderThread::RC_ForceSwapBuffers() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_ForceSwapBuffers(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ForceSwapBuffers, 0); - EndCommand(p); -} - -void SRenderThread::RC_SwitchToNativeResolutionBackbuffer() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_SwitchToNativeResolutionBackbuffer(true); - return; - } - else - { - gRenDev->SetViewport(0, 0, gRenDev->GetOverlayWidth(), gRenDev->GetOverlayHeight()); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SwitchToNativeResolutionBackbuffer, 0); - EndCommand(p); -} - -void SRenderThread::RC_BeginFrame() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_BeginFrame(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_BeginFrame, 0); - EndCommand(p); -} -void SRenderThread::RC_EndFrame(bool bWait) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_EndFrame(); - SyncMainWithRender(); - return; - } - if (!bWait && CheckFlushCond()) - { - return; - } - - LOADINGLOCK_COMMANDQUEUE - gRenDev->GetIRenderAuxGeom()->Commit(); // need to issue flush of main thread's aux cb before EndFrame (otherwise it is processed after p3dDev->EndScene()) - byte* p = AddCommand(eRC_EndFrame, 0); - EndCommand(p); - SyncMainWithRender(); -} - -void SRenderThread::RC_PrecacheResource(ITexture* pTP, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter) -{ - if (IsRenderThread()) - { - gRenDev->PrecacheTexture(pTP, fMipFactor, fTimeToReady, Flags, nUpdateId, nCounter); - return; - } - - if (pTP == NULL) - { - return; - } - - pTP->AddRef(); - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PrecacheTexture, 20 + sizeof(void*)); - AddPointer(p, pTP); - AddFloat(p, fMipFactor); - AddFloat(p, fTimeToReady); - AddDWORD(p, Flags); - AddDWORD(p, nUpdateId); - AddDWORD(p, nCounter); - EndCommand(p); -} - -void SRenderThread::RC_ReleaseDeviceTexture(CTexture* pTexture) -{ - AZ_TRACE_METHOD(); - if (!strcmp(pTexture->GetName(), "EngineAssets/TextureMsg/ReplaceMe.tif")) - { - pTexture = pTexture; - } - - if (IsRenderThread()) - { - CryOptionalAutoLock lock(m_lockRenderLoading, m_eVideoThreadMode != eVTM_Disabled); - pTexture->RT_ReleaseDevice(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ReleaseDeviceTexture, sizeof(void*)); - AddPointer(p, pTexture); - EndCommand(p); - - FlushAndWait(); -} - -void SRenderThread::RC_TryFlush() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return; - } - - // do nothing if the render thread is still busy - if (CheckFlushCond()) - { - return; - } - - LOADINGLOCK_COMMANDQUEUE - gRenDev->GetIRenderAuxGeom()->Flush(); // need to issue flush of main thread's aux cb before EndFrame (otherwise it is processed after p3dDev->EndScene()) - SyncMainWithRender(); -} - -void SRenderThread::RC_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_DrawLines(v, nump, col, flags, fGround); - } - else - { - LOADINGLOCK_COMMANDQUEUE - // since we use AddData(...) - we need to allocate 4 bytes (DWORD) more because AddData(...) adds hidden data size into command buffer - byte* p = AddCommand(eRC_DrawLines, Align4(sizeof(int) + 2 * sizeof(int) + sizeof(float) + nump * sizeof(Vec3) + sizeof(ColorF))); - AddDWORD(p, nump); - AddColor(p, col); - AddDWORD(p, flags); - AddFloat(p, fGround); - AddData (p, v, nump * sizeof(Vec3)); - EndCommand(p); - } -} - -void SRenderThread::RC_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_DrawStringU(pFont, x, y, z, pStr, asciiMultiLine, ctx); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_DrawStringU, Align4(16 + sizeof(void*) + sizeof(STextDrawContext) + TextCommandSize(pStr))); - AddPointer(p, pFont); - AddFloat(p, x); - AddFloat(p, y); - AddFloat(p, z); - AddDWORD(p, asciiMultiLine ? 1 : 0); - new(p) STextDrawContext(ctx); - p += sizeof(STextDrawContext); - AddText(p, pStr); - EndCommand(p); -} -void SRenderThread::RC_ClearTargetsImmediately(int8 nType, uint32 nFlags, const ColorF& vColor, float depth) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - switch (nType) - { - case 0: - gRenDev->EF_ClearTargetsImmediately(nFlags); - return; - case 1: - gRenDev->EF_ClearTargetsImmediately(nFlags, vColor, depth, 0); - return; - case 2: - gRenDev->EF_ClearTargetsImmediately(nFlags, vColor); - return; - case 3: - gRenDev->EF_ClearTargetsImmediately(nFlags, depth, 0); - return; - } - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_ClearTargetsImmediately, Align4(12 + sizeof(ColorF))); - AddDWORD(p, nType); - AddDWORD(p, nFlags); - AddColor(p, vColor); - AddFloat(p, depth); - EndCommand(p); -} - -void SRenderThread::RC_SetViewport(int x, int y, int width, int height, int id) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_SetViewport(x, y, width, height, id); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetViewport, 20); - AddDWORD(p, x); - AddDWORD(p, y); - AddDWORD(p, width); - AddDWORD(p, height); - AddDWORD(p, id); - EndCommand(p); -} - -void SRenderThread::RC_RenderScene(int nFlags, RenderFunc pRenderFunc) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_RenderScene(nFlags, gRenDev->m_RP.m_TI[m_nCurThreadProcess], pRenderFunc); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_RenderScene, Align4(8 + sizeof(void*) + sizeof(SThreadInfo))); - AddDWORD(p, nFlags); - AddTI(p, gRenDev->m_RP.m_TI[m_nCurThreadFill]); - AddPointer(p, (void*)pRenderFunc); - AddDWORD(p, SRendItem::m_RecurseLevel[m_nCurThreadFill]); - EndCommand(p); -} - -void SRenderThread::RC_PrepareStereo(int mode, int output) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_PrepareStereo(mode, output); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PrepareStereo, 8); - AddDWORD(p, mode); - AddDWORD(p, output); - EndCommand(p); -} - -void SRenderThread::RC_CopyToStereoTex(int channel) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_CopyToStereoTex(channel); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CopyToStereoTex, 4); - AddDWORD(p, channel); - EndCommand(p); -} - -void SRenderThread::RC_SetStereoEye(int eye) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->m_CurRenderEye = eye; - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetStereoEye, 4); - AddDWORD(p, eye); - EndCommand(p); -} - -void SRenderThread::RC_AuxFlush([[maybe_unused]] IRenderAuxGeomImpl* pAux, [[maybe_unused]] SAuxGeomCBRawDataPackaged& data, [[maybe_unused]] size_t begin, [[maybe_unused]] size_t end, [[maybe_unused]] bool reset) -{ - AZ_TRACE_METHOD(); -#if defined(ENABLE_RENDER_AUX_GEOM) - if (IsRenderThread()) - { - pAux->RT_Flush(data, begin, end); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_AuxFlush, 4 * sizeof(void*) + sizeof(uint32)); - AddPointer(p, pAux); - AddPointer(p, data.m_pData); - AddPointer(p, (void*) begin); - AddPointer(p, (void*) end); - AddDWORD (p, (uint32) reset); - EndCommand(p); -#endif -} - -void SRenderThread::RC_SetTexture(int nTex, int nUnit) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - CTexture::ApplyForID(nUnit, nTex, -1, -1); - return; - } - - LOADINGLOCK_COMMANDQUEUE - int nState = CTexture::GetByID(nTex)->GetDefState(); - byte* p = AddCommand(eRC_SetTexture, 12); - AddDWORD(p, nTex); - AddDWORD(p, nUnit); - AddDWORD(p, nState); - EndCommand(p); -} - -bool SRenderThread::RC_OC_ReadResult_Try(uint32 nDefaultNumSamples, CREOcclusionQuery* pRE) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return pRE->RT_ReadResult_Try(nDefaultNumSamples); - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_OC_ReadResult_Try, 4 + sizeof(void*)); - AddDWORD(p, (uint32)nDefaultNumSamples); - AddPointer(p, pRE); - EndCommand(p); - - return true; -} - -void SRenderThread::RC_CGCSetLayers(IColorGradingControllerInt* pController, const SColorChartLayer* pLayers, uint32 numLayers) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - pController->RT_SetLayers(pLayers, numLayers); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_CGCSetLayers, 4 + sizeof(void*)); - AddPointer(p, pController); - AddDWORD(p, (uint32)numLayers); - EndCommand(p); - - if (numLayers) - { - const size_t copySize = sizeof(SColorChartLayer) * numLayers; - SColorChartLayer* pLayersDst = (SColorChartLayer*) m_Commands[m_nCurThreadFill].Grow(copySize); - memcpy(pLayersDst, pLayers, copySize); - } -} - -void SRenderThread::RC_GenerateSkyDomeTextures(CREHDRSky* pSky, int32 width, int32 height) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - pSky->GenerateSkyDomeTextures(width, height); - return; - } - - LOADINGLOCK_COMMANDQUEUE - - if (m_eVideoThreadMode == eVTM_Disabled) - { - byte* p = AddCommand(eRC_GenerateSkyDomeTextures, sizeof(void*) + sizeof(int32) * 2); - AddPointer(p, pSky); - AddDWORD(p, width); - AddDWORD(p, height); - EndCommand(p); - } - else - { - // Move command into loading queue, which will be executed in first render frame after loading is done - byte* p = AddCommandTo(eRC_GenerateSkyDomeTextures, sizeof(void*) + sizeof(int32) * 2, m_CommandsLoading); - AddPointer(p, pSky); - AddDWORD(p, width); - AddDWORD(p, height); - EndCommandTo(p, m_CommandsLoading); - } -} - -void SRenderThread::RC_SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_SetRendererCVar(pCVar, pArgText, bSilentMode); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_SetRendererCVar, sizeof(void*) + TextCommandSize(pArgText) + 4); - AddPointer(p, pCVar); - AddText(p, pArgText); - AddDWORD(p, bSilentMode ? 1 : 0); - EndCommand(p); -} - -void SRenderThread::RC_RenderDebug(bool bRenderStats) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_RenderDebug(bRenderStats); - return; - } - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_RenderDebug, 0); - EndCommand(p); -} - -void SRenderThread::RC_PushSkinningPoolId(uint32 poolId) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - gRenDev->RT_SetSkinningPoolId(poolId); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_PushSkinningPoolId, 4); - AddDWORD(p, poolId); - EndCommand(p); -} - -void SRenderThread::RC_ReleaseRemappedBoneIndices(IRenderMesh* pRenderMesh, uint32 guid) -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - pRenderMesh->ReleaseRemappedBoneIndicesPair(guid); - return; - } - - LOADINGLOCK_COMMANDQUEUE - pRenderMesh->AddRef(); // don't allow mesh deletion while this command is pending - byte* p = AddCommand(eRC_ReleaseRemappedBoneIndices, sizeof(void*) + 4); - AddPointer(p, pRenderMesh); - AddDWORD(p, guid); - EndCommand(p); -} - -void SRenderThread::RC_InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) -{ - AZ_TRACE_METHOD(); - - if (IsRenderThread()) - { - gRenDev->RT_InitializeVideoRenderer(pVideoRenderer); - return; - } - - LOADINGLOCK_COMMANDQUEUE; - byte* p = AddCommand(eRC_InitializeVideoRenderer, sizeof(AZ::VideoRenderer::IVideoRenderer*)); - AddPointer(p, pVideoRenderer); - EndCommand(p); - - // We want to block until the resources have been created. - SyncMainWithRender(); -} - -void SRenderThread::RC_CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) -{ - AZ_TRACE_METHOD(); - - if (IsRenderThread()) - { - gRenDev->RT_CleanupVideoRenderer(pVideoRenderer); - return; - } - - LOADINGLOCK_COMMANDQUEUE; - byte* p = AddCommand(eRC_CleanupVideoRenderer, sizeof(AZ::VideoRenderer::IVideoRenderer*)); - AddPointer(p, pVideoRenderer); - EndCommand(p); - - // We want to block until the cleanup is complete. - SyncMainWithRender(); -} - -void SRenderThread::RC_DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) -{ - AZ_TRACE_METHOD(); - - if (IsRenderThread()) - { - gRenDev->RT_DrawVideoRenderer(pVideoRenderer, drawArguments); - return; - } - - LOADINGLOCK_COMMANDQUEUE; - byte* p = AddCommand(eRC_DrawVideoRenderer, sizeof(AZ::VideoRenderer::IVideoRenderer*) + sizeof(AZ::VideoRenderer::DrawArguments)); - AddPointer(p, pVideoRenderer); - memcpy(p, &drawArguments, sizeof(AZ::VideoRenderer::DrawArguments)); - p += sizeof(AZ::VideoRenderer::DrawArguments); - EndCommand(p); -} - -void SRenderThread::EnqueueRenderCommand(RenderCommandCB command) -{ - if (IsRenderThread()) - { - command(); - return; - } - - LOADINGLOCK_COMMANDQUEUE - byte* p = AddCommand(eRC_AzFunction, sizeof(RenderCommandCB)); - new (p) RenderCommandCB(AZStd::move(command)); - p += sizeof(RenderCommandCB); - EndCommand(p); -} - -//=========================================================================================== - -#ifdef DO_RENDERSTATS -#define START_PROFILE_RT Time = iTimer->GetAsyncTime(); -#define END_PROFILE_PLUS_RT(Dst) Dst += iTimer->GetAsyncTime().GetDifferenceInSeconds(Time); -#define END_PROFILE_RT(Dst) Dst = iTimer->GetAsyncTime().GetDifferenceInSeconds(Time); -#else -#define START_PROFILE_RT -#define END_PROFILE_PLUS_RT(Dst) -#define END_PROFILE_RT(Dst) -#endif - -#if defined(AZ_PROFILE_TELEMETRY) -static const char* GetRenderCommandName(ERenderCommand renderCommand) -{ - switch (renderCommand) - { - // Please add to this list if you have a case that needs watching - case eRC_PreloadTextures: - return "PreloadTextures"; - case eRC_ParseShader: - return "ParseShader"; - case eRC_RenderScene: - return "RenderScene"; - case eRC_AzFunction: - return "AzFunction"; - } - return ""; -} -#endif - -void SRenderThread::ProcessCommands(bool loadTimeProcessing) -{ - AZ_TRACE_METHOD(); -#ifndef STRIP_RENDER_THREAD - assert (IsRenderThread()); - if (!CheckFlushCond()) - { - return; - } - -#if !defined (NULL_RENDERER) - DWORD nDeviceOwningThreadID = gcpRendD3D->GetBoundThreadID(); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gcpRendD3D->BindContextToThread(CryGetCurrentThreadId()); - } -# endif -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - if (CRenderer::CV_r_multithreaded) - { - m_kDXGLContextHandle.Set(&gcpRendD3D->GetDevice()); - } - if (m_eVideoThreadMode == eVTM_Disabled) - { - m_kDXGLDeviceContextHandle.Set(&gcpRendD3D->GetDeviceContext(), !CRenderer::CV_r_multithreaded); - } -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION - - -#ifdef DO_RENDERSTATS - CTimeValue Time; -#endif - - int threadId = m_nCurThreadProcess; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - int n = 0; - m_bSuccessful = true; - m_hResult = S_OK; - byte* pP; - while (n < (int)m_Commands[threadId].Num()) - { - pP = &m_Commands[threadId][n]; - n += sizeof(int); - byte nC = (byte) * ((int*)pP); - -#if !defined(_RELEASE) - // Ensure that the command hasn't been processed already - int* pProcessed = (int*)(pP + sizeof(int)); - IF_UNLIKELY (*pProcessed) - { - __debugbreak(); - } - *pProcessed = 1; - n += sizeof(int); -#endif - - AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::RendererDetailed, "SRenderThread::ProcessCommands::Command: %s (%d)", GetRenderCommandName(static_cast(nC)), nC); - - switch (nC) - { - case eRC_CreateDevice: - m_bSuccessful &= gRenDev->RT_CreateDevice(); - break; - case eRC_ResetDevice: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_Reset(); - } - break; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - case eRC_ReleasePostEffects: - if (gRenDev->m_pPostProcessMgr) - { - gRenDev->m_pPostProcessMgr->ReleaseResources(); - } - break; - case eRC_ResetPostEffects: - if (gRenDev->m_RP.m_pREPostProcess) - { - gRenDev->m_RP.m_pREPostProcess->mfReset(); - } - break; - case eRC_ResetPostEffectsOnSpecChange: - if (gRenDev->m_RP.m_pREPostProcess) - { - gRenDev->m_RP.m_pREPostProcess->Reset(true); - } - break; - case eRC_DisableTemporalEffects: - gRenDev->RT_DisableTemporalEffects(); - break; - case eRC_ResetGlass: - gRenDev->RT_ResetGlass(); - break; - case eRC_ResetToDefault: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->ResetToDefault(); - } - break; - case eRC_Init: - gRenDev->RT_Init(); - break; - case eRC_ShutDown: - { - uint32 nFlags = ReadCommand(n); - gRenDev->RT_ShutDown(nFlags); - } - break; - case eRC_ForceSwapBuffers: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_ForceSwapBuffers(); - } - break; - case eRC_SwitchToNativeResolutionBackbuffer: - { - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_SwitchToNativeResolutionBackbuffer(true); - } - } - break; - case eRC_BeginFrame: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_BeginFrame(); - } - else - { - m_bBeginFrameCalled = true; - } - break; - case eRC_EndFrame: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_EndFrame(); - } - else - { - // RLT handles precache commands - so all texture streaming prioritisation - // needs to happen here. Scheduling and device texture management will happen - // on the RT later. - CTexture::RLT_LoadingUpdate(); - - m_bEndFrameCalled = true; - gRenDev->m_nFrameSwapID++; - } - break; - case eRC_PreloadTextures: - CTexture::RT_Precache(); - break; - case eRC_PrecacheTexture: - { - ITexture* pTP = ReadCommand(n); - - float fMipFactor = ReadCommand(n); - float fTimeToReady = ReadCommand(n); - int Flags = ReadCommand(n); - int nUpdateId = ReadCommand(n); - int nCounter = ReadCommand(n); - gRenDev->PrecacheTexture(pTP, fMipFactor, fTimeToReady, Flags, nUpdateId, nCounter); - - pTP->Release(); - } - break; - case eRC_ClearTargetsImmediately: - { - uint32 nType = ReadCommand(n); - uint32 nFlags = ReadCommand(n); - ColorF vColor = ReadCommand(n); - float fDepth = ReadCommand(n); - if (m_eVideoThreadMode != eVTM_Disabled) - { - nFlags &= ~FRT_CLEAR_IMMEDIATE; - switch (nType) - { - case 0: - gRenDev->EF_ClearTargetsLater(nFlags); - break; - case 1: - gRenDev->EF_ClearTargetsLater(nFlags, vColor, fDepth, 0); - break; - case 2: - gRenDev->EF_ClearTargetsLater(nFlags, vColor); - break; - case 3: - gRenDev->EF_ClearTargetsLater(nFlags, fDepth, 0); - break; - } - } - switch (nType) - { - case 0: - gRenDev->EF_ClearTargetsImmediately(nFlags); - break; - case 1: - gRenDev->EF_ClearTargetsImmediately(nFlags, vColor, fDepth, 0); - break; - case 2: - gRenDev->EF_ClearTargetsImmediately(nFlags, vColor); - break; - case 3: - gRenDev->EF_ClearTargetsImmediately(nFlags, fDepth, 0); - break; - } - } - break; - case eRC_ReadFrameBuffer: - { - byte* pRGB = ReadCommand(n); - int nImageX = ReadCommand(n); - int nSizeX = ReadCommand(n); - int nSizeY = ReadCommand(n); - ERB_Type RBType = ReadCommand(n); - int bRGBA = ReadCommand(n); - int nScaledX = ReadCommand(n); - int nScaledY = ReadCommand(n); - gRenDev->RT_ReadFrameBuffer(pRGB, nImageX, nSizeX, nSizeY, RBType, bRGBA, nScaledX, nScaledY); - } - break; - case eRC_UpdateShaderItem: - { - SShaderItem* pShaderItem = ReadCommand(n); - // The material is necessary at this point because an UpdateShaderItem may have been queued - // for a material that was subsequently released and would have been deleted, thus resulting in a - // dangling pointer and a crash; this keeps it alive until this render command can complete - IMaterial* pMaterial = ReadCommand(n); - gRenDev->RT_UpdateShaderItem(pShaderItem, pMaterial); - if (pMaterial) - { - // Release the reference we added when we submitted the command. - pMaterial->Release(); - } - } - break; - case eRC_RefreshShaderResourceConstants: - { - SShaderItem* shaderItem = ReadCommand(n); - // The material is necessary at this point because an RefreshShaderResourceConstants may have been queued - // for a material that was subsequently released and would have been deleted, thus resulting in a - // dangling pointer and a crash; this keeps it alive until this render command can complete - IMaterial* material = ReadCommand(n); - gRenDev->RT_RefreshShaderResourceConstants(shaderItem); - if (material) - { - // Release the reference we added when we submitted the command. - material->Release(); - } - } - break; - case eRC_ReleaseDeviceTexture: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - CTexture* pTexture = ReadCommand(n); - pTexture->RT_ReleaseDevice(); - } - break; - case eRC_AuxFlush: - { -#if defined(ENABLE_RENDER_AUX_GEOM) - IRenderAuxGeomImpl* pAux = ReadCommand(n); - CAuxGeomCB::SAuxGeomCBRawData* pData = ReadCommand(n); - size_t begin = ReadCommand(n); - size_t end = ReadCommand(n); - bool reset = ReadCommand(n) != 0; - - if (m_eVideoThreadMode == eVTM_Disabled) - { - SAuxGeomCBRawDataPackaged data = SAuxGeomCBRawDataPackaged(pData); - pAux->RT_Flush(data, begin, end, reset); - } -#endif - } - break; - case eRC_SetTexture: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - int nTex = ReadCommand(n); - int nUnit = ReadCommand(n); - int nState = ReadCommand(n); - CTexture::ApplyForID(nUnit, nTex, nState, -1); - } - break; - case eRC_DrawLines: - { - int nump = ReadCommand(n); - ColorF col = ReadCommand(n); - int flags = ReadCommand(n); - float fGround = ReadCommand(n); - - - Vec3* pv = (Vec3*)&m_Commands[threadId][n += 4]; - n += nump * sizeof(Vec3); - - gRenDev->RT_DrawLines(pv, nump, col, flags, fGround); - } - break; - case eRC_DrawStringU: - { - IFFont_RenderProxy* pFont = ReadCommand(n); - float x = ReadCommand(n); - float y = ReadCommand(n); - float z = ReadCommand(n); - bool asciiMultiLine = ReadCommand(n) != 0; - const STextDrawContext* pCtx = (const STextDrawContext*) &m_Commands[threadId][n]; - n += sizeof(STextDrawContext); - const char* pStr = ReadTextCommand(n); - - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_DrawStringU(pFont, x, y, z, pStr, asciiMultiLine, *pCtx); - } - } - break; - case eRC_SetState: - { - int nState = ReadCommand(n); - int nAlphaRef = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->FX_SetState(nState, nAlphaRef); - } - } - break; - case eRC_PushWireframeMode: - { - int nMode = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->FX_PushWireframeMode(nMode); - } - } - break; - case eRC_PopWireframeMode: - { - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->FX_PopWireframeMode(); - } - } - break; - case eRC_SetCull: - { - int nMode = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_SetCull(nMode); // nMode - } - } - break; - case eRC_SetScissor: - { - bool bEnable = ReadCommand(n) != 0; - int sX = (int)ReadCommand(n); - int sY = (int)ReadCommand(n); - int sWdt = (int)ReadCommand(n); - int sHgt = (int)ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_SetScissor(bEnable, sX, sY, sWdt, sHgt); - } - } - break; - case eRC_SetStencilState: - { - int st = ReadCommand(n); - uint32 nStencRef = ReadCommand(n); - uint32 nStencMask = ReadCommand(n); - uint32 nStencWriteMask = ReadCommand(n); - bool bForceFullReadMask = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->FX_SetStencilState(st, nStencRef, nStencMask, nStencWriteMask, bForceFullReadMask); - } - } - break; - case eRC_UpdateTexture: - { - CTexture* pTexture = ReadCommand(n); - byte* pData = ReadCommand(n); - int nX = ReadCommand(n); - int nY = ReadCommand(n); - int nZ = ReadCommand(n); - int nUSize = ReadCommand(n); - int nVSize = ReadCommand(n); - int nZSize = ReadCommand(n); - ETEX_Format eTFSrc = (ETEX_Format)ReadCommand(n); - pTexture->RT_UpdateTextureRegion(pData, nX, nY, nZ, nUSize, nVSize, nZSize, eTFSrc); - delete [] pData; - pTexture->Release(); - } - break; - case eRC_CreateResource: - { - SResourceAsync* pRA = ReadCommand(n); - gRenDev->RT_CreateResource(pRA); - } - break; - case eRC_ReleaseResource: - { - SResourceAsync* pRes = ReadCommand(n); - gRenDev->RT_ReleaseResource(pRes); - } - break; - case eRC_ReleaseRenderResources: - gRenDev->RT_ReleaseRenderResources(); - break; - case eRC_UnbindTMUs: - gRenDev->RT_UnbindTMUs(); - break; - case eRC_UnbindResources: - gRenDev->RT_UnbindResources(); - break; - case eRC_CreateRenderResources: - gRenDev->RT_CreateRenderResources(); - break; - case eRC_CreateSystemTargets: - CTexture::CreateSystemTargets(); - break; - case eRC_PrecacheDefaultShaders: - gRenDev->RT_PrecacheDefaultShaders(); - break; - case eRC_ReleaseSurfaceResource: - { - SDepthTexture* pRes = ReadCommand(n); - if (pRes) - { - pRes->Release(true); - } - } - break; - case eRC_ReleaseBaseResource: - { - CBaseResource* pRes = ReadCommand(n); - RC_ReleaseBaseResource(pRes); - } - break; - case eRC_ReleaseFont: - { - IFFont* font = ReadCommand(n); - RC_ReleaseFont(font); - } - break; - case eRC_UpdateMesh2: - assert(m_eVideoThreadMode == eVTM_Disabled); - { - CRenderMesh* pMesh = ReadCommand(n); - CRenderMesh* pVContainer = ReadCommand(n); - uint32 nStreamMask = ReadCommand(n); - pMesh->RT_CheckUpdate(pVContainer, nStreamMask); - } - break; - case eRC_CreateDeviceTexture: - { - CryOptionalAutoLock lock(m_lockRenderLoading, loadTimeProcessing); - CTexture* pTex = ReadCommand(n); - const byte* pData[6]; - for (int i = 0; i < 6; i++) - { - pData[i] = ReadCommand(n); - } - m_bSuccessful = pTex->RT_CreateDeviceTexture(pData); - } - break; - case eRC_CopyDataToTexture: - { - void* pkTexture = ReadCommand(n); - unsigned int uiStartMip = ReadCommand(n); - unsigned int uiEndMip = ReadCommand(n); - - RC_CopyDataToTexture(pkTexture, uiStartMip, uiEndMip); - } - break; - case eRC_ClearTarget: - { - void* pkTexture = ReadCommand(n); - ColorF kColor = ReadCommand(n); - - RC_ClearTarget(pkTexture, kColor); - } - break; - case eRC_CreateREPostProcess: - { - CRendElementBase** pRE = ReadCommand(n); - gRenDev->RT_CreateREPostProcess(pRE); - } - break; - - case eRC_DrawDynVB: - { - pP = &m_Commands[threadId][0]; - uint32 nSize = *(uint32*)&pP[n]; - SVF_P3F_C4B_T2F* pBuf = (SVF_P3F_C4B_T2F*)&pP[n + 4]; - n += nSize + 4; - nSize = *(uint32*)&pP[n]; - uint16* pInds = (nSize > 0) ? (uint16*)&pP[n + 4] : nullptr; - n += nSize + 4; - int nVerts = ReadCommand(n); - int nInds = ReadCommand(n); - const PublicRenderPrimitiveType nPrimType = (PublicRenderPrimitiveType)ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_DrawDynVB(pBuf, pInds, nVerts, nInds, nPrimType); - } - } - break; - case eRC_Draw2dImage: - { - START_PROFILE_RT; - - float xpos = ReadCommand(n); - float ypos = ReadCommand(n); - float w = ReadCommand(n); - float h = ReadCommand(n); - CTexture* pTexture = ReadCommand(n); - float s0 = ReadCommand(n); - float t0 = ReadCommand(n); - float s1 = ReadCommand(n); - float t1 = ReadCommand(n); - float angle = ReadCommand(n); - int col = ReadCommand(n); - float z = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_Draw2dImage(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z); - } - END_PROFILE_PLUS_RT(gRenDev->m_fRTTimeMiscRender); - } - break; - case eRC_DrawDynVBUI: - { - pP = &m_Commands[threadId][0]; - uint32 nSize = *(uint32*)&pP[n]; - SVF_P2F_C4B_T2F_F4B* pBuf = (SVF_P2F_C4B_T2F_F4B*)&pP[n + 4]; - n += nSize + 4; - nSize = *(uint32*)&pP[n]; - uint16* pInds = (nSize > 0) ? (uint16*)&pP[n + 4] : nullptr; - n += nSize + 4; - int nVerts = ReadCommand(n); - int nInds = ReadCommand(n); - const PublicRenderPrimitiveType nPrimType = (PublicRenderPrimitiveType)ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_DrawDynVBUI(pBuf, pInds, nVerts, nInds, nPrimType); - } - } - break; - - case eRC_Draw2dImageStretchMode: - { - START_PROFILE_RT; - - int mode = ReadCommand(n); - gRenDev->RT_Draw2dImageStretchMode(mode); - END_PROFILE_PLUS_RT(gRenDev->m_fRTTimeMiscRender); - } - break; - case eRC_Push2dImage: - { - float xpos = ReadCommand(n); - float ypos = ReadCommand(n); - float w = ReadCommand(n); - float h = ReadCommand(n); - CTexture* pTexture = ReadCommand(n); - float s0 = ReadCommand(n); - float t0 = ReadCommand(n); - float s1 = ReadCommand(n); - float t1 = ReadCommand(n); - float angle = ReadCommand(n); - int col = ReadCommand(n); - float z = ReadCommand(n); - float stereoDepth = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_Push2dImage(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z, stereoDepth); - } - } - break; - case eRC_Draw2dImageList: - { - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_Draw2dImageList(); - } - } - break; - case eRC_DrawImageWithUV: - if (m_eVideoThreadMode == eVTM_Disabled) - { - pP = &m_Commands[threadId][n]; - gRenDev->RT_DrawImageWithUV(*(float*)pP, // xpos - *(float*)&pP[4], // ypos - *(float*)&pP[8], // z - *(float*)&pP[12], // w - *(float*)&pP[16], // h - *(int*)&pP[20], // textureid - (float*)&pP[24], // s - (float*)&pP[40], // t - *(int*)&pP[56], // col - *(int*)&pP[60] != 0); // filtered - } - n += 64; - break; - case eRC_PushProfileMarker: - { - char* label = ReadCommand(n); - gRenDev->PushProfileMarker(label); - } - break; - case eRC_PopProfileMarker: - { - char* label = ReadCommand(n); - gRenDev->PopProfileMarker(label); - } - break; - case eRC_SetCamera: - { - START_PROFILE_RT; - - Matrix44A ProjMat = ReadCommand(n); - Matrix44A ViewMat = ReadCommand(n); - Matrix44A CameraZeroMat = ReadCommand(n); - CameraViewParameters viewParameters = ReadCommand(n); - - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->SetMatrices(ProjMat.GetData(), ViewMat.GetData()); - gRenDev->m_CameraZeroMatrix[threadId] = CameraZeroMat; - gRenDev->SetViewParameters(viewParameters); - - gRenDev->RT_SetCameraInfo(); - } - - END_PROFILE_PLUS_RT(gRenDev->m_fRTTimeMiscRender); - } - break; - case eRC_AzFunction: - { - // Lock only when processing on the RenderLoadThread - multiple AzFunctions make calls that cause crashes if invoked concurrently with render - CryOptionalAutoLock lock(m_lockRenderLoading, loadTimeProcessing); - - // We "build" the command from the buffer memory (instead of copying it) - RenderCommandCB* command = alias_cast(reinterpret_cast(&m_Commands[threadId][n])); - (*command)(); - // We need to destroy the object that we created using placement new. - command->~RenderCommandCB(); - n += Align4(sizeof(RenderCommandCB)); - } - break; - case eRC_ReleaseVBStream: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - void* pVB = ReadCommand(n); - int nStream = ReadCommand(n); - gRenDev->RT_ReleaseVBStream(pVB, nStream); - } - break; - case eRC_ReleaseVB: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - buffer_handle_t nID = ReadCommand(n); - gRenDev->m_DevBufMan.Destroy(nID); - } - break; - case eRC_ReleaseIB: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - buffer_handle_t nID = ReadCommand(n); - gRenDev->m_DevBufMan.Destroy(nID); - } - break; - case eRC_RenderScene: - { - START_PROFILE_RT; - - int nFlags = ReadCommand(n); - SThreadInfo TI; - LoadUnaligned((uint32*)&m_Commands[threadId][n], TI); - n += sizeof(SThreadInfo); - RenderFunc pRenderFunc = ReadCommand(n); - int nR = ReadCommand(n); - int nROld = SRendItem::m_RecurseLevel[threadId]; - SRendItem::m_RecurseLevel[threadId] = nR; - // when we are in video mode, don't execute the command - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_RenderScene(nFlags, TI, pRenderFunc); - } - else - { - // cleanup when showing loading render screen - if (nR == 1) - { - //////////////////////////////////////////////// - // wait till all SRendItems for this frame have finished preparing - gRenDev->GetFinalizeRendItemJobExecutor(gRenDev->m_RP.m_nProcessThreadID)->WaitForCompletion(); - gRenDev->GetFinalizeShadowRendItemJobExecutor(gRenDev->m_RP.m_nProcessThreadID)->WaitForCompletion(); - - //////////////////////////////////////////////// - // to non-thread safe remaing work for *::Render functions - CRenderMesh::FinalizeRendItems(gRenDev->m_RP.m_nProcessThreadID); - CMotionBlur::InsertNewElements(); - FurBendData::Get().InsertNewElements(); - } - } - SRendItem::m_RecurseLevel[threadId] = nROld; - - END_PROFILE_PLUS_RT(gRenDev->m_fRTTimeSceneRender); - } - break; - case eRC_PrepareStereo: - { - int mode = ReadCommand(n); - int output = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_PrepareStereo(mode, output); - } - } - break; - case eRC_CopyToStereoTex: - { - int channel = ReadCommand(n); - gRenDev->RT_CopyToStereoTex(channel); - } - break; - case eRC_SetStereoEye: - { - int eye = ReadCommand(n); - gRenDev->m_CurRenderEye = eye; - } - break; - case eRC_DynTexUpdate: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - SDynTexture* pTex = ReadCommand(n); - int nNewWidth = ReadCommand(n); - int nNewHeight = ReadCommand(n); - pTex->RT_Update(nNewWidth, nNewHeight); - } - break; - case eRC_ParseShader: - { - CShader* pSH = ReadCommand(n); - CShaderResources* pRes = ReadCommand(n); - uint64 nMaskGen = ReadCommand(n); - uint32 nFlags = ReadCommand(n); - - gRenDev->m_cEF.RT_ParseShader(pSH, nMaskGen, nFlags, pRes); - pSH->Release(); - if (pRes) - { - pRes->Release(); - } - } - break; - case eRC_SetShaderQuality: - { - EShaderType eST = (EShaderType) ReadCommand(n); - EShaderQuality eSQ = (EShaderQuality) ReadCommand(n); - gRenDev->m_cEF.RT_SetShaderQuality(eST, eSQ); - } - break; - case eRC_PushFog: - gRenDev->EF_PushFog(); - break; - case eRC_PopFog: - gRenDev->EF_PopFog(); - break; - case eRC_PushVP: - gRenDev->FX_PushVP(); - break; - case eRC_PopVP: - gRenDev->FX_PopVP(); - break; - case eRC_RenderTextMessages: - gRenDev->RT_RenderTextMessages(); - break; - case eRC_FlushTextureStreaming: - { - bool bAbort = ReadCommand(n) != 0; - CTexture::RT_FlushStreaming(bAbort); - } - break; - case eRC_ReleaseSystemTextures: - CTextureManager::Instance()->Release(); - CTexture::ReleaseSystemTextures(); - break; - case eRC_SetEnvTexRT: - { - SEnvTexture* pTex = ReadCommand(n); - int nWidth = ReadCommand(n); - int nHeight = ReadCommand(n); - int bPush = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - pTex->m_pTex->RT_SetRT(0, nWidth, nHeight, bPush); - } - } - break; - case eRC_SetEnvTexMatrix: - { - SEnvTexture* pTex = ReadCommand(n); - pTex->RT_SetMatrix(); - } - break; - case eRC_PushRT: - assert (m_eVideoThreadMode == eVTM_Disabled); - { - int nTarget = ReadCommand(n); - CTexture* pTex = ReadCommand(n); - SDepthTexture* pDS = ReadCommand(n); - int nS = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_PushRenderTarget(nTarget, pTex, pDS, nS); - } - } - break; - case eRC_PopRT: - { - int nTarget = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_PopRenderTarget(nTarget); - } - } - break; - case eRC_EntityDelete: - { - IRenderNode* pRN = ReadCommand(n); - SDynTexture_Shadow::RT_EntityDelete(pRN); - } - break; - case eRC_PreactivateShaders: - { - CHWShader::RT_PreactivateShaders(); - } - break; - case eRC_PrecacheShader: - { - CShader* pShader = ReadCommand(n); - SShaderCombination cmb = ReadCommand(n); - bool bForce = ReadCommand(n) != 0; - bool bCompressedOnly = ReadCommand(n) != 0; - CShaderResources* pRes = ReadCommand(n); - - pShader->mfPrecache(cmb, bForce, bCompressedOnly, pRes); - - SAFE_RELEASE(pRes); - pShader->Release(); - } - break; - case eRC_SetViewport: - { - int nX = ReadCommand(n); - int nY = ReadCommand(n); - int nWidth = ReadCommand(n); - int nHeight = ReadCommand(n); - int nID = ReadCommand(n); - // when we are in video mode, don't execute the command - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_SetViewport(nX, nY, nWidth, nHeight, nID); - } - } - break; - case eRC_TexBlurAnisotropicVertical: - { - CTexture* pTex = ReadCommand(n); - float fAnisoScale = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - TexBlurAnisotropicVertical(pTex, 1, 8 * max(1.0f - min(fAnisoScale / 100.0f, 1.0f), 0.2f), 1, false); - } - } - break; - - case eRC_OC_ReadResult_Try: - { - uint32 nDefaultNumSamples = ReadCommand(n); - CREOcclusionQuery* pRE = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - pRE->RT_ReadResult_Try(nDefaultNumSamples); - } - } - break; - - case eRC_PostLevelLoading: - { - gRenDev->RT_PostLevelLoading(); - } - break; - - case eRC_StartVideoThread: - m_eVideoThreadMode = eVTM_RequestStart; - break; - case eRC_StopVideoThread: - m_eVideoThreadMode = eVTM_RequestStop; - break; - - case eRC_CGCSetLayers: - { - IColorGradingControllerInt* pController = ReadCommand(n); - uint32 numLayers = ReadCommand(n); - const SColorChartLayer* pLayers = numLayers ? (const SColorChartLayer*) &m_Commands[threadId][n] : 0; - n += sizeof(SColorChartLayer) * numLayers; - if (m_eVideoThreadMode == eVTM_Disabled) - { - pController->RT_SetLayers(pLayers, numLayers); - } - } - break; - - case eRC_GenerateSkyDomeTextures: - { - CREHDRSky* pSky = ReadCommand(n); - int32 width = ReadCommand(n); - int32 height = ReadCommand(n); - pSky->GenerateSkyDomeTextures(width, height); - } - break; - - case eRC_SetRendererCVar: - { - ICVar* pCVar = ReadCommand(n); - const char* pArgText = ReadTextCommand(n); - const bool bSilentMode = ReadCommand(n) != 0; - - gRenDev->RT_SetRendererCVar(pCVar, pArgText, bSilentMode); - } - break; - - case eRC_RenderDebug: - { - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->RT_RenderDebug(); - } - else - { - gRenDev->RT_RenderTextMessages(); - } - } - break; - - case eRC_ForceMeshGC: - if (m_eVideoThreadMode == eVTM_Disabled) - { - CRenderMesh::Tick(); - } - break; - - case eRC_DevBufferSync: - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->m_DevBufMan.Sync(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - } - break; - - case eRC_UnlinkTexture: - { - CTexture* tex = ReadCommand(n); - tex->RT_Unlink(); - } - break; - - case eRC_RelinkTexture: - { - CTexture* tex = ReadCommand(n); - tex->RT_Relink(); - } - break; - - case eRC_PushSkinningPoolId: - gRenDev->RT_SetSkinningPoolId(ReadCommand< uint32 >(n)); - break; - case eRC_ReleaseRemappedBoneIndices: - { - IRenderMesh* pRenderMesh = ReadCommand(n); - uint32 guid = ReadCommand(n); - pRenderMesh->ReleaseRemappedBoneIndicesPair(guid); - pRenderMesh->Release(); - } - break; - - case eRC_SetColorOp: - { - int eCo = ReadCommand(n); - int eAo = ReadCommand(n); - int eCa = ReadCommand(n); - int eAa = ReadCommand(n); - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->EF_SetColorOp(eCo, eAo, eCa, eAa); - } - } - break; - - case eRC_SetSrgbWrite: - { - bool srgbWrite = ReadCommand(n) != 0; - if (m_eVideoThreadMode == eVTM_Disabled) - { - gRenDev->EF_SetSrgbWrite(srgbWrite); - } - } - break; - - case eRC_InitializeVideoRenderer: - { - AZ::VideoRenderer::IVideoRenderer* pVideoRenderer = ReadCommand(n); - gRenDev->RT_InitializeVideoRenderer(pVideoRenderer); - } - break; - - case eRC_CleanupVideoRenderer: - { - AZ::VideoRenderer::IVideoRenderer* pVideoRenderer = ReadCommand(n); - gRenDev->RT_CleanupVideoRenderer(pVideoRenderer); - } - break; - - case eRC_DrawVideoRenderer: - { - AZ::VideoRenderer::IVideoRenderer* pVideoRenderer = ReadCommand(n); - const AZ::VideoRenderer::DrawArguments drawArguments = ReadCommand(n); - gRenDev->RT_DrawVideoRenderer(pVideoRenderer, drawArguments); - } - break; - - default: - { - assert(0); - } - break; - } - } - -#if !defined (NULL_RENDERER) - if (m_eVideoThreadMode == eVTM_Disabled) - { - gcpRendD3D->BindContextToThread(nDeviceOwningThreadID); - } -# endif - -#endif//STRIP_RENDER_THREAD -} - -void SRenderThread::Process() -{ - AZ_TRACE_METHOD(); - while (true) - { - CTimeValue Time = iTimer->GetAsyncTime(); - - if (m_bQuit) - { - SignalFlushFinishedCond(); - break;//put it here to safely shut down - } - - WaitFlushCond(); - - const uint64 start = CryGetTicks(); - - CTimeValue TimeAfterWait = iTimer->GetAsyncTime(); - gRenDev->m_fTimeWaitForMain[m_nCurThreadProcess] += TimeAfterWait.GetDifferenceInSeconds(Time); - if (gRenDev->m_bStartLevelLoading) - { - m_fTimeIdleDuringLoading += TimeAfterWait.GetDifferenceInSeconds(Time); - } - - float fT = 0.f; - - if (m_eVideoThreadMode == eVTM_Disabled) - { - //gRenDev->m_fRTTimeBeginFrame = 0; - //gRenDev->m_fRTTimeEndFrame = 0; - gRenDev->m_fRTTimeSceneRender = 0; - gRenDev->m_fRTTimeMiscRender = 0; - - ProcessCommands(false /*loadTimeProcessing*/); - - CTimeValue TimeAfterProcess = iTimer->GetAsyncTime(); - fT = TimeAfterProcess.GetDifferenceInSeconds(TimeAfterWait); - gRenDev->m_fTimeProcessedRT[m_nCurThreadProcess] += fT; - - if (m_eVideoThreadMode == eVTM_RequestStart) - { - } - - SignalFlushFinishedCond(); - } - - if (gRenDev->m_bStartLevelLoading) - { - m_fTimeBusyDuringLoading += fT; - } -#if !defined (NULL_RENDERER) - if (m_eVideoThreadMode == eVTM_RequestStart) - { - uint32 frameId = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - DWORD nDeviceOwningThreadID = gcpRendD3D->GetBoundThreadID(); - gcpRendD3D->BindContextToThread(CryGetCurrentThreadId()); - gRenDev->m_DevBufMan.Sync(frameId); // make sure no request are flying when switching to render loading thread - - // Guarantee default resources - gRenDev->InitSystemResources(0); - - // Create another render thread; - SwitchMode(true); - - { - CTimeValue lastTime = gEnv->pTimer->GetAsyncTime(); - CTimeValue workingStart = lastTime; - CTimeValue workingEnd = lastTime; - - while (m_eVideoThreadMode != eVTM_ProcessingStop) - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Renderer, "Loading Frame"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(RenderThread_cpp) -#endif - frameId += 1; - - const CTimeValue curTime = gEnv->pTimer->GetAsyncTime(); - const CTimeValue deltaTime = curTime - lastTime; - const CTimeValue workingTime = workingEnd - workingStart; - - const float deltaTimeInSeconds = AZStd::max(deltaTime.GetSeconds(), 0.0f); - - lastTime = curTime; - - // If we spent less than half of the last frame doing anything, try to spend most of that time sleeping this frame. - // This will help us spend less time in the lock while presenting when vsync is enabled. - if (workingTime.GetValue() < (deltaTime.GetValue() / 2)) - { - const uint32_t sleepTime = AZStd::min(aznumeric_cast(deltaTime.GetMilliSeconds()) / 2, 16); - CrySleep(sleepTime); - } - - workingStart = gEnv->pTimer->GetAsyncTime(); - - { - CryAutoLock lock(m_lockRenderLoading); - gRenDev->m_DevBufMan.Update(frameId, true); - } - - if (m_pLoadtimeCallback) - { - CryAutoLock lock(m_lockRenderLoading); - m_pLoadtimeCallback->LoadtimeUpdate(deltaTimeInSeconds); - } - - { - //////////////////////////////////////////////// - // wait till all SRendItems for this frame have finished preparing - const threadID processThreadID = gRenDev->m_RP.m_nProcessThreadID; - gRenDev->GetFinalizeRendItemJobExecutor(processThreadID)->WaitForCompletion(); - gRenDev->GetFinalizeShadowRendItemJobExecutor(processThreadID)->WaitForCompletion(); - - { - CryAutoLock lock(m_lockRenderLoading); - - gRenDev->SetViewport(0, 0, gRenDev->GetOverlayWidth(), gRenDev->GetOverlayHeight()); - - SPostEffectsUtils::AcquireFinalCompositeTarget(false); - - if (m_pLoadtimeCallback) - { - m_pLoadtimeCallback->LoadtimeRender(); - } - - gRenDev->m_DevBufMan.ReleaseEmptyBanks(frameId); - - workingEnd = gEnv->pTimer->GetAsyncTime(); - - gRenDev->RT_PresentFast(); - - CRenderMesh::Tick(); - CTexture::RT_LoadingUpdate(); - } - } - - // Make sure we aren't running with thousands of FPS with VSync disabled - gRenDev->LimitFramerate(120, true); - -#if defined(SUPPORT_DEVICE_INFO_MSG_PROCESSING) - gcpRendD3D->DevInfo().ProcessSystemEventQueue(); -#endif - } - } - if (m_pThreadLoading) - { - QuitRenderLoadingThread(); - } - m_eVideoThreadMode = eVTM_Disabled; - - if (m_bBeginFrameCalled) - { - m_bBeginFrameCalled = false; - gRenDev->RT_BeginFrame(); - } - if (m_bEndFrameCalled) - { - m_bEndFrameCalled = false; - gRenDev->RT_EndFrame(); - } - gcpRendD3D->BindContextToThread(nDeviceOwningThreadID); - } -#endif - const uint64 elapsed = CryGetTicks() - start; - gEnv->pSystem->GetCurrentUpdateTimeStats().RenderTime = elapsed; - } -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - m_kDXGLDeviceContextHandle.Set(NULL, !CRenderer::CV_r_multithreaded); - m_kDXGLContextHandle.Set(NULL); -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION -} - -void SRenderThread::ProcessLoading() -{ - AZ_TRACE_METHOD(); - while (true) - { - float fTime = iTimer->GetAsyncCurTime(); - WaitFlushCond(); - if (m_bQuitLoading) - { - SignalFlushFinishedCond(); - break;//put it here to safely shut down - } - float fTimeAfterWait = iTimer->GetAsyncCurTime(); - gRenDev->m_fTimeWaitForMain[m_nCurThreadProcess] += fTimeAfterWait - fTime; - if (gRenDev->m_bStartLevelLoading) - { - m_fTimeIdleDuringLoading += fTimeAfterWait - fTime; - } - - ProcessCommands(true /*loadTimeProcessing*/); - - SignalFlushFinishedCond(); - float fTimeAfterProcess = iTimer->GetAsyncCurTime(); - gRenDev->m_fTimeProcessedRT[m_nCurThreadProcess] += fTimeAfterProcess - fTimeAfterWait; - if (gRenDev->m_bStartLevelLoading) - { - m_fTimeBusyDuringLoading += fTimeAfterProcess - fTimeAfterWait; - } - if (m_eVideoThreadMode == eVTM_RequestStop) - { - // Switch to general render thread - SwitchMode(false); - } - } -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - m_kDXGLDeviceContextHandle.Set(NULL, !CRenderer::CV_r_multithreaded); - m_kDXGLContextHandle.Set(NULL); -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION -} - -#ifndef STRIP_RENDER_THREAD -// Flush current frame and wait for result (main thread only) -void SRenderThread::FlushAndWait() -{ - AZ_TRACE_METHOD(); - if (IsRenderThread()) - { - return; - } - - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_RENDERER); - - if (!m_pThread) - { - return; - } - - SyncMainWithRender(); - SyncMainWithRender(); -} -#endif//STRIP_RENDER_THREAD - -// Flush current frame without waiting (should be called from main thread) -void SRenderThread::SyncMainWithRender() -{ - AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::Renderer); - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_RENDERER); - -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - if (m_bQuit && m_pThread && !m_pThread->IsRunning()) - { - // We're in shutdown and the render thread is not running. - // We should not attempt to wait for the render thread to signal us. - return; - } -#endif // defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - - if (!IsMultithreaded()) - { - gRenDev->SyncMainWithRender(); - gRenDev->m_fTimeProcessedRT[m_nCurThreadProcess] = 0; - gRenDev->m_fTimeWaitForMain[m_nCurThreadProcess] = 0; - gRenDev->m_fTimeWaitForGPU[m_nCurThreadProcess] = 0; - return; - } - -#ifndef STRIP_RENDER_THREAD - CTimeValue time = iTimer->GetAsyncTime(); - WaitFlushFinishedCond(); - - CPostEffectsMgr* pPostEffectMgr = PostEffectMgr(); - if (pPostEffectMgr) - { - // Must be called before the thread ID's get swapped - pPostEffectMgr->SyncMainWithRender(); - } - - gRenDev->SyncMainWithRender(); - - gRenDev->m_fTimeWaitForRender[m_nCurThreadFill] = iTimer->GetAsyncTime().GetDifferenceInSeconds(time); - // gRenDev->ToggleMainThreadAuxGeomCB(); - gRenDev->m_RP.m_TI[m_nCurThreadProcess].m_nFrameUpdateID = gRenDev->m_RP.m_TI[m_nCurThreadFill].m_nFrameUpdateID; - gRenDev->m_RP.m_TI[m_nCurThreadProcess].m_nFrameID = gRenDev->m_RP.m_TI[m_nCurThreadFill].m_nFrameID; - m_nCurThreadProcess = m_nCurThreadFill; - m_nCurThreadFill = (m_nCurThreadProcess + 1) & 1; - gRenDev->m_RP.m_nProcessThreadID = threadID(m_nCurThreadProcess); - gRenDev->m_RP.m_nFillThreadID = threadID(m_nCurThreadFill); - m_Commands[m_nCurThreadFill].SetUse(0); - gRenDev->m_fTimeProcessedRT[m_nCurThreadProcess] = 0; - gRenDev->m_fTimeWaitForMain[m_nCurThreadProcess] = 0; - gRenDev->m_fTimeWaitForGPU[m_nCurThreadProcess] = 0; - - gRenDev->m_RP.m_pCurrentRenderView = gRenDev->m_RP.m_pRenderViews[gRenDev->m_RP.m_nProcessThreadID].get(); - gRenDev->m_RP.m_pCurrentFillView = gRenDev->m_RP.m_pRenderViews[gRenDev->m_RP.m_nFillThreadID].get(); - gRenDev->m_RP.m_pCurrentRenderView->PrepareForRendering(); - - SignalFlushCond(); -#endif -} - -void SRenderThread::QuitRenderThread() -{ - AZ_TRACE_METHOD(); - if (IsMultithreaded() && m_pThread) - { - SignalQuitCond(); -#if defined(USE_LOCKS_FOR_FLUSH_SYNC) - FlushAndWait(); -#endif - m_pThread->WaitForThread(); - SAFE_DELETE(m_pThread); - -#if !defined(STRIP_RENDER_THREAD) - m_nCurThreadProcess = m_nCurThreadFill; -#endif - } - m_bQuit = 1; -} - -void SRenderThread::QuitRenderLoadingThread() -{ - AZ_TRACE_METHOD(); - if (IsMultithreaded() && m_pThreadLoading) - { - FlushAndWait(); - m_bQuitLoading = true; - m_pThreadLoading->WaitForThread(); - SAFE_DELETE(m_pThreadLoading); - m_nRenderThreadLoading = 0; - CNameTableR::m_nRenderThread = m_nRenderThread; - } -} - -bool SRenderThread::IsFailed() -{ - AZ_TRACE_METHOD(); - return !m_bSuccessful; -} - -bool CRenderer::FlushRTCommands(bool bWait, bool bImmediatelly, bool bForce) -{ - AZ_TRACE_METHOD(); - SRenderThread* pRT = m_pRT; - IF (!pRT, 0) - { - return true; - } - if (pRT->IsRenderThread(true)) - { - SSystemGlobalEnvironment* pEnv = iSystem->GetGlobalEnvironment(); - if (pEnv && pEnv->IsEditor()) - { - CPostEffectsMgr* pPostEffectMgr = PostEffectMgr(); - if (pPostEffectMgr) - { - pPostEffectMgr->SyncMainWithRender(); - } - } - return true; - } - if (!bForce && (!m_bStartLevelLoading || !pRT->IsMultithreaded())) - { - return false; - } - if (!bImmediatelly && pRT->CheckFlushCond()) - { - return false; - } - if (bWait) - { - pRT->FlushAndWait(); - } - - return true; -} - -bool CRenderer::ForceFlushRTCommands() -{ - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION; - return FlushRTCommands(true, true, true); -} - -// Must be executed from main thread -void SRenderThread::WaitFlushFinishedCond() -{ - AZ_TRACE_METHOD(); - CTimeValue time = iTimer->GetAsyncTime(); - -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_LockFlushNotify.Lock(); - while (*(volatile int*)&m_nFlush) - { -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - m_LockFlushNotify.Unlock(); - MsgWaitForMultipleObjects(1, &m_FlushFinishedCondition, FALSE, 1, QS_ALLINPUT); - m_LockFlushNotify.Lock(); - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - if (m_bQuit && m_pThread && !m_pThread->IsRunning()) - { - // We're in shutdown and the render thread is not running. - // We should not attempt to wait for the render thread to signal us - - // we force signal the flush condition to exit out of this wait loop. - m_nFlush = 0; - } -#else - const int OneHunderdMilliseconds = 100; - bool timedOut = !(m_FlushFinishedCondition.TimedWait(m_LockFlushNotify, OneHunderdMilliseconds)); -#if defined(AZ_PLATFORM_IOS) && !defined(_RELEASE) - // When we trigger asserts or warnings from a thread other than the main thread, the dialog box has to be - // presented from the main thread. So, we need to pump the system event loop while the main thread is waiting. - // We're using locks for waiting on iOS. This means that once the main thread goes into the wait, it's not - // going to be able to pump system events. To handle this, we use a timed wait with 100ms. In most cases, - // the render thread will complete within 100ms. But, when we need to display a dialog from the render thread, - // it times out and pumps the system event loop so we can display the dialog. After that, since m_nFlush is still - // true, we will go back into the wait and let the render thread complete. - if (timedOut) - { - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - } -#endif -#endif - } - m_LockFlushNotify.Unlock(); -#else - READ_WRITE_BARRIER - while (*(volatile int*)&m_nFlush) - { -#ifdef WIN32 - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - Sleep(0); -#elif defined(AZ_PLATFORM_MAC) && !defined(_RELEASE) - // On MacOS, we display blocking alerts(dialogs) to provide notifications to users(eg: assert failed). - // These alerts(NSAlert) can be triggered only from the main thread. If we run into an assert on the render thread, - // this block of code ensures that the alert is displayed on the main thread and we're not deadlocked with render thread. - if (!gEnv->IsEditor()) - { - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - } -#endif - READ_WRITE_BARRIER - } -#endif -} - -// Must be executed from render thread -void SRenderThread::WaitFlushCond() -{ - AZ_TRACE_METHOD(); - AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::Renderer); - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_RENDERER); - - CTimeValue time = iTimer->GetAsyncTime(); -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_LockFlushNotify.Lock(); - while (!*(volatile int*)&m_nFlush) - { - m_FlushCondition.Wait(m_LockFlushNotify); - } - m_LockFlushNotify.Unlock(); -#else - READ_WRITE_BARRIER - while (!*(volatile int*)&m_nFlush) - { - if (m_bQuit) - { - break; - } - ::Sleep(0); - READ_WRITE_BARRIER - } -#endif -} - -#undef m_nCurThreadFill -#undef m_nCurThreadProcess diff --git a/Code/CryEngine/RenderDll/Common/RenderThread.h b/Code/CryEngine/RenderDll/Common/RenderThread.h deleted file mode 100644 index ca5514b405..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderThread.h +++ /dev/null @@ -1,798 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Render thread commands processing. - - -#pragma once - -#include -#include "UnalignedBlit.h" - -// Remove this include once the restricted platform separation process is complete -#include "RendererDefs.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RENDERTHREAD_H_SECTION_1 1 -#define RENDERTHREAD_H_SECTION_2 2 -#define RENDERTHREAD_H_SECTION_3 3 -#endif - -#if defined(ANDROID) -#include -#include -#endif - -#define RENDER_THREAD_NAME "RenderThread" -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_H_SECTION_1 - #include AZ_RESTRICTED_FILE(RenderThread_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - #define RENDER_THREAD_PRIORITY THREAD_PRIORITY_NORMAL -#endif - -#define RENDER_LOADING_THREAD_NAME "RenderLoadingThread" - -typedef void (* RenderFunc)(void); - -//==================================================================== - -struct IRenderAuxGeomImpl; -struct SAuxGeomCBRawDataPackaged; -struct IColorGradingControllerInt; -struct SColorChartLayer; -class CRenderMesh; -struct SDynTexture; -struct STexStreamInState; -struct SDepthTexture; - -#if RENDERTHREAD_H_TRAIT_USE_LOCKS_FOR_FLUSH_SYNC -#define USE_LOCKS_FOR_FLUSH_SYNC -#elif defined(WIN32) -#define USE_LOCKS_FOR_FLUSH_SYNC -#define USE_HANDLE_FOR_FINAL_FLUSH_SYNC -#endif - -enum ERenderCommand -{ - eRC_Unknown = 0, - eRC_Init, - eRC_ShutDown, - eRC_CreateDevice, - eRC_ResetDevice, - eRC_SuspendDevice, - eRC_ResumeDevice, - eRC_BeginFrame, - eRC_EndFrame, - eRC_ClearTargetsImmediately, - eRC_RenderTextMessages, - eRC_FlushTextureStreaming, - eRC_ReleaseSystemTextures, - eRC_PreloadTextures, - eRC_ReadFrameBuffer, - eRC_ForceSwapBuffers, - eRC_SwitchToNativeResolutionBackbuffer, - - eRC_DrawLines, - eRC_DrawStringU, - eRC_UpdateTexture, - eRC_UpdateMesh2, - eRC_ReleaseBaseResource, - eRC_ReleaseFont, - eRC_ReleaseSurfaceResource, - eRC_ReleaseIB, - eRC_ReleaseVB, - eRC_ReleaseVBStream, - eRC_CreateResource, - eRC_ReleaseResource, - eRC_ReleaseRenderResources, - eRC_PrecacheDefaultShaders, - eRC_UnbindTMUs, - eRC_UnbindResources, - eRC_CreateRenderResources, - eRC_CreateSystemTargets, - eRC_CreateDeviceTexture, - eRC_CopyDataToTexture, - eRC_ClearTarget, - eRC_CreateREPostProcess, - eRC_ParseShader, - eRC_SetShaderQuality, - eRC_UpdateShaderItem, - eRC_RefreshShaderResourceConstants, - eRC_ReleaseDeviceTexture, - eRC_FlashRender, - eRC_FlashRenderLockless, - eRC_AuxFlush, - eRC_RenderScene, - eRC_PrepareStereo, - eRC_CopyToStereoTex, - eRC_SetStereoEye, - eRC_SetCamera, - - eRC_PushProfileMarker, - eRC_PopProfileMarker, - - eRC_PostLevelLoading, - eRC_SetState, - eRC_PushWireframeMode, - eRC_PopWireframeMode, - eRC_SetCull, - eRC_SetScissor, - eRC_SetStencilState, - eRC_SelectGPU, - eRC_DrawDynVB, - eRC_DrawDynVBUI, - eRC_Draw2dImage, - eRC_Draw2dImageStretchMode, - eRC_Push2dImage, - eRC_PushUITexture, - eRC_Draw2dImageList, - eRC_DrawImageWithUV, - - eRC_PreprGenerateFarTrees, - eRC_DynTexUpdate, - eRC_PushFog, - eRC_PopFog, - eRC_PushVP, - eRC_PopVP, - eRC_SetEnvTexRT, - eRC_SetEnvTexMatrix, - eRC_PushRT, - eRC_PopRT, - eRC_SetViewport, - eRC_TexBlurAnisotropicVertical, - - eRC_OC_ReadResult_Try, - - eRC_CGCSetLayers, - eRC_EntityDelete, - eRC_ForceMeshGC, - eRC_DevBufferSync, - - // streaming queries - eRC_PrecacheTexture, - eRC_SetTexture, - - eRC_StartVideoThread, - eRC_StopVideoThread, - - eRC_RenderDebug, - eRC_PreactivateShaders, - eRC_PrecacheShader, - - eRC_RelinkTexture, - eRC_UnlinkTexture, - - eRC_ReleasePostEffects, - eRC_ResetPostEffects, - eRC_ResetPostEffectsOnSpecChange, - eRC_DisableTemporalEffects, - - eRC_ResetGlass, - eRC_ResetToDefault, - - eRC_GenerateSkyDomeTextures, - - eRC_PushSkinningPoolId, - - eRC_ReleaseRemappedBoneIndices, - - eRC_SetRendererCVar, - eRC_SetColorOp, - eRC_SetSrgbWrite, - - eRC_InitializeVideoRenderer, - eRC_CleanupVideoRenderer, - eRC_DrawVideoRenderer, - - eRC_AzFunction -}; - -//==================================================================== - -struct CRenderThread - : CrySimpleThread<> -{ - int m_nCPU; - CRenderThread(int nCPU) - { - m_nCPU = CLAMP(nCPU, 1, 5); - } - - virtual ~CRenderThread() - { - // Stop thread task. - Stop(); - } - - CryEvent m_started; - -protected: - virtual void Run(); -}; -struct CRenderThreadLoading - : public CRenderThread -{ - CRenderThreadLoading(int nCPU) - : CRenderThread(nCPU) {} -protected: - virtual void Run(); -}; - -struct SRenderThread -{ - CRenderThread* m_pThread; - CRenderThreadLoading* m_pThreadLoading; - ILoadtimeCallback* m_pLoadtimeCallback; - CryMutex m_lockRenderLoading; - AZStd::mutex m_CommandsMutex; - bool m_bQuit; - bool m_bQuitLoading; - bool m_bSuccessful; - bool m_bBeginFrameCalled; - bool m_bEndFrameCalled; -#ifndef STRIP_RENDER_THREAD - int m_nCurThreadProcess; - int m_nCurThreadFill; -#endif -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - int m_nFlush; - CryMutex m_LockFlushNotify; - CryConditionVariable m_FlushCondition; -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - HANDLE m_FlushFinishedCondition; -#else - CryConditionVariable m_FlushFinishedCondition; -#endif -#else - volatile int m_nFlush; -#endif - threadID m_nRenderThread; - threadID m_nRenderThreadLoading; - threadID m_nMainThread; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_H_SECTION_2 - #include AZ_RESTRICTED_FILE(RenderThread_h) -#endif - HRESULT m_hResult; -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - SDXGLContextThreadLocalHandle m_kDXGLContextHandle; - SDXGLDeviceContextThreadLocalHandle m_kDXGLDeviceContextHandle; -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION - float m_fTimeIdleDuringLoading; - float m_fTimeBusyDuringLoading; - TArray m_Commands[RT_COMMAND_BUF_COUNT]; // m_nCurThreadFill shows which commands are filled by main thread - - // The below loading queue contains all commands that were submitted and require full device access during loading. - // Will be blit into the first render frame's command queue after loading and subsequently resized to 0. - TArray m_CommandsLoading; - - static CryCriticalSection s_rcLock; - - enum EVideoThreadMode - { - eVTM_Disabled = 0, - eVTM_RequestStart, - eVTM_Active, - eVTM_RequestStop, - eVTM_ProcessingStop, - }; - EVideoThreadMode m_eVideoThreadMode; - - SRenderThread(); - ~SRenderThread(); - - inline void SignalFlushFinishedCond() - { -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_LockFlushNotify.Lock(); -#endif - m_nFlush = 0; -#ifdef USE_LOCKS_FOR_FLUSH_SYNC -#if defined(USE_HANDLE_FOR_FINAL_FLUSH_SYNC) - SetEvent(m_FlushFinishedCondition); -#else - m_FlushFinishedCondition.Notify(); -#endif - m_LockFlushNotify.Unlock(); -#else - READ_WRITE_BARRIER -#endif - } - - inline void SignalFlushCond() - { -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_LockFlushNotify.Lock(); -#endif - m_nFlush = 1; -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_FlushCondition.Notify(); - m_LockFlushNotify.Unlock(); -#else - READ_WRITE_BARRIER -#endif - } - - inline void SignalQuitCond() - { -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_LockFlushNotify.Lock(); -#endif - m_bQuit = 1; -#ifdef USE_LOCKS_FOR_FLUSH_SYNC - m_FlushCondition.Notify(); - m_LockFlushNotify.Unlock(); -#else - READ_WRITE_BARRIER -#endif - } - - void WaitFlushCond(); - -#ifdef WIN32 - HWND GetRenderWindowHandle(); -#endif - - void WaitFlushFinishedCond(); - - inline void InitFlushCond() - { - m_nFlush = 0; -#if !defined(USE_LOCKS_FOR_FLUSH_SYNC) - READ_WRITE_BARRIER -#endif - } - - inline bool CheckFlushCond() - { -#if !defined(USE_LOCKS_FOR_FLUSH_SYNC) - READ_WRITE_BARRIER -#endif - return *(int*)&m_nFlush != 0; - } - - static constexpr size_t RenderThreadStackSize = 128ull * 1024ull; - - void StartRenderThread() - { - if (m_pThread != NULL) - { - int32 renderThreadPriority = RENDER_THREAD_PRIORITY; -#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_MAC) - //Apple recommends to never use 0 as a render thread priority. - //In this case we are getting the max thread priority and going 2 levels below for ideal performance. - int thread_policy; - sched_param thread_sched_param; - pthread_getschedparam(pthread_self(), &thread_policy, &thread_sched_param); - renderThreadPriority = sched_get_priority_max(thread_policy) - 2; -#endif - - m_pThread->Start(AFFINITY_MASK_RENDERTHREAD, RENDER_THREAD_NAME, renderThreadPriority, RenderThreadStackSize); - m_pThread->m_started.Wait(); - } - } - - void StartRenderLoadingThread() - { - if (m_pThreadLoading != NULL) - { - m_pThreadLoading->Start(AFFINITY_MASK_USERTHREADS, RENDER_THREAD_NAME, RENDER_THREAD_PRIORITY + 1, RenderThreadStackSize); - m_pThreadLoading->m_started.Wait(); - } - } - - bool IsFailed(); - void ValidateThreadAccess(ERenderCommand eRC); - - _inline size_t Align4(size_t value) - { - return (value + 3) & ~((size_t)3); - } - - _inline byte* AddCommandTo(ERenderCommand eRC, size_t nParamBytes, TArray& queue) - { - AZ_Assert(nParamBytes == Align4(nParamBytes), "Input nParamBytes is %" PRISIZE_T " bytes, which not aligned to 4 bytes.", nParamBytes); - - m_CommandsMutex.lock(); - - assert(m_pThread != NULL); - uint32 cmdSize = sizeof(uint32) + nParamBytes; -#if !defined(_RELEASE) - cmdSize += sizeof(uint32); -#endif - byte* ptr = queue.Grow(cmdSize); - AddDWORD(ptr, eRC); -#if !defined(_RELEASE) - // Processed flag - AddDWORD(ptr, 0); -#endif - return ptr; - } - - _inline void EndCommandTo([[maybe_unused]] byte* ptr, [[maybe_unused]] TArray& queue) - { -#ifndef _RELEASE - if (ptr - queue.Data() != queue.Num()) - { - CryFatalError("Bad render command size - check the parameters and round each up to 4-byte boundaries [expected queue size = %" PRISIZE_T ", actual size = %u]", (size_t)(ptr - queue.Data()), queue.Num()); - } -#endif - m_CommandsMutex.unlock(); - } - - _inline byte* AddCommand(ERenderCommand eRC, size_t nParamBytes) - { - AZ_Assert(nParamBytes == Align4(nParamBytes), "Input nParamBytes is %" PRISIZE_T " bytes, which not aligned to 4 bytes.", nParamBytes); - -#ifdef STRIP_RENDER_THREAD - return NULL; -#else - return AddCommandTo(eRC, nParamBytes, m_Commands[m_nCurThreadFill]); -#endif - } - - _inline void EndCommand(byte* ptr) - { -#ifndef STRIP_RENDER_THREAD - EndCommandTo(ptr, m_Commands[m_nCurThreadFill]); -#endif - } - - _inline void AddDWORD(byte*& ptr, uint32 nVal) - { - *(uint32*)ptr = nVal; - ptr += sizeof(uint32); - } - _inline void AddDWORD64(byte*& ptr, uint64 nVal) - { - StoreUnaligned((uint32*)ptr, nVal); // uint32 because command list maintains 4-byte alignment - ptr += sizeof(uint64); - } - _inline void AddTI(byte*& ptr, SThreadInfo& TI) - { - memcpy((SThreadInfo*)ptr, &TI, sizeof(SThreadInfo)); - ptr += sizeof(SThreadInfo); - } - _inline void AddRenderingPassInfo(byte*& ptr, SRenderingPassInfo* pPassInfo) - { - memcpy((SRenderingPassInfo*)ptr, pPassInfo, sizeof(SRenderingPassInfo)); - ptr += sizeof(SRenderingPassInfo); - } - _inline void AddFloat(byte*& ptr, const float fVal) - { - *(float*)ptr = fVal; - ptr += sizeof(float); - } - _inline void AddVec3(byte*& ptr, const Vec3& cVal) - { - *(Vec3*)ptr = cVal; - ptr += sizeof(Vec3); - } - _inline void AddColor(byte*& ptr, const ColorF& cVal) - { - float* fData = (float*)ptr; - fData[0] = cVal[0]; - fData[1] = cVal[1]; - fData[2] = cVal[2]; - fData[3] = cVal[3]; - ptr += sizeof(ColorF); - } - _inline void AddColorB(byte*& ptr, const ColorB& cVal) - { - ptr[0] = cVal[0]; - ptr[1] = cVal[1]; - ptr[2] = cVal[2]; - ptr[3] = cVal[3]; - ptr += sizeof(ColorB); - } - _inline void AddPointer(byte*& ptr, const void* pVal) - { - StoreUnaligned((uint32*)ptr, pVal); // uint32 because command list maintains 4-byte alignment - ptr += sizeof(void*); - } - _inline void AddData(byte*& ptr, const void* pData, int nLen) - { - unsigned pad = (unsigned)-nLen % 4; - AddDWORD(ptr, nLen + pad); - memcpy(ptr, pData, nLen); - ptr += nLen + pad; - } - _inline void AddText(byte*& ptr, const char* pText) - { - int nLen = strlen(pText) + 1; - unsigned pad = (unsigned)-nLen % 4; - AddDWORD(ptr, nLen); - memcpy(ptr, pText, nLen); - ptr += nLen + pad; - } - _inline size_t TextCommandSize(const char* pText) - { - return 4 + Align4(strlen(pText) + 1); - } - _inline void AddText(byte*& ptr, const wchar_t* pText) - { - int nLen = (wcslen(pText) + 1) * sizeof(wchar_t); - unsigned pad = (unsigned)-nLen % 4; - AddDWORD(ptr, nLen); - memcpy(ptr, pText, nLen); - ptr += nLen + pad; - } - _inline size_t TextCommandSize(const wchar_t* pText) - { - return 4 + Align4((wcslen(pText) + 1) * sizeof(wchar_t)); - } - template - T ReadCommand(int& nIndex) - { - T Res; - LoadUnaligned((uint32*)&m_Commands[m_nCurThreadProcess][nIndex], Res); - nIndex += (sizeof(T) + 3) & ~((size_t)3); - return Res; - } - template - T ReadTextCommand(int& nIndex) - { - unsigned int strLen = ReadCommand(nIndex); - T Res = (T)&m_Commands[m_nCurThreadProcess][nIndex]; - nIndex += strLen; - nIndex = (nIndex + 3) & ~((size_t)3); - return Res; - } - - _inline threadID GetCurrentThreadId(bool bAlwaysCheck = false) - { -#ifdef STRIP_RENDER_THREAD - return m_nRenderThread; -#else - if (!bAlwaysCheck && m_nRenderThread == m_nMainThread) - { - return m_nRenderThread; - } - - return ::GetCurrentThreadId(); -#endif - } - void SwitchMode(bool enableVideo); - - void Init(int nCPU); - void QuitRenderThread(); - void QuitRenderLoadingThread(); - void SyncMainWithRender(); - void FlushAndWait(); - void ProcessCommands(bool loadTimeProcessing); - void Process(); // Render thread - void ProcessLoading(); // Loading thread - int GetThreadList(); -#if defined(AZ_PLATFORM_ANDROID) - bool IsRenderThread(bool bAlwaysCheck = true); - bool IsRenderLoadingThread(bool bAlwaysCheck = true); -#else - bool IsRenderThread(bool bAlwaysCheck = false); - bool IsRenderLoadingThread(bool bAlwaysCheck = false); -#endif - bool IsMainThread(bool bAlwaysCheck = false); - bool IsMultithreaded(); - int CurThreadFill() const; - void RC_Init(); - void RC_ShutDown(uint32 nFlags); - bool RC_CreateDevice(); - void RC_ResetDevice(); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERTHREAD_H_SECTION_3 - #include AZ_RESTRICTED_FILE(RenderThread_h) -#endif - void RC_PreloadTextures(); - void RC_ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX, int nScaledY); - bool RC_CreateDeviceTexture(CTexture* pTex, const byte* pData[6]); - void RC_CopyDataToTexture(void* pkTexture, unsigned int uiStartMip, unsigned int uiEndMip); - void RC_ClearTarget(void* pkTexture, const ColorF& kColor); - void RC_CreateResource(SResourceAsync* pRes); - void RC_ReleaseRenderResources(); - void RC_PrecacheDefaultShaders(); - void RC_UnbindResources(); - void RC_UnbindTMUs(); - void RC_FreeObject(CRenderObject* pObj); - void RC_CreateRenderResources(); - void RC_CreateSystemTargets(); - void RC_ReleaseBaseResource(CBaseResource* pRes); - void RC_ReleaseFont(IFFont* font); - void RC_ReleaseSurfaceResource(SDepthTexture* pRes); - void RC_ReleaseResource(SResourceAsync* pRes); - void RC_ReleaseResource(AZStd::unique_ptr pRes); - void RC_RelinkTexture(CTexture* pTex); - void RC_UnlinkTexture(CTexture* pTex); - void RC_CreateREPostProcess(CRendElementBase** re); - bool RC_CheckUpdate2(CRenderMesh* pMesh, CRenderMesh* pVContainer, uint32 nStreamMask); - void RC_ReleaseVB(buffer_handle_t nID); - void RC_ReleaseIB(buffer_handle_t nID); - void RC_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType); - void RC_DrawDynUiPrimitiveList(IRenderer::DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices); - void RC_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, float r, float g, float b, float a, float z); - void RC_Draw2dImageStretchMode(bool bStretch); - void RC_Push2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, float r, float g, float b, float a, float z, float stereoDepth); - void RC_PushUITexture(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, CTexture* pTarget, float r, float g, float b, float a); - void RC_Draw2dImageList(); - void RC_DrawImageWithUV(float xpos, float ypos, float z, float w, float h, int texture_id, float s[4], float t[4], float r, float g, float b, float a, bool filtered = true); - void RC_UpdateTextureRegion(CTexture* pTex, const byte* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc); - void RC_SetState(int State, int AlphaRef); - void RC_SetStencilState(int st, uint32 nStencRef, uint32 nStencMask, uint32 nStencWriteMask, bool bForceFullReadMask); - void RC_SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa); - void RC_SetSrgbWrite(bool srgbWrite); - void RC_PushWireframeMode(int nMode); - void RC_PopWireframeMode(); - void RC_SetCull(int nMode); - void RC_SetScissor(bool bEnable, int sX, int sY, int sWdt, int sHgt); - void RC_PreactivateShaders(); - void RC_PrecacheShader(CShader* pShader, SShaderCombination& cmb, bool bForce, bool bCompressedOnly, CShaderResources* pRes); - void RC_PushProfileMarker(const char* label); - void RC_PopProfileMarker(const char* label); - void RC_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround); - void RC_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx); - void RC_ReleaseDeviceTexture(CTexture* pTex); - void RC_PrecacheResource(ITexture* pTP, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter = 1); - void RC_ClearTargetsImmediately(int8 nType, uint32 nFlags, const ColorF& vColor, float depth); - void RC_RenderTextMessages(); - void RC_FlushTextureStreaming(bool bAbort); - void RC_ReleaseSystemTextures(); - void RC_AuxFlush(IRenderAuxGeomImpl* pAux, SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset); - void RC_ParseShader (CShader* pSH, uint64 nMaskGen, uint32 flags, CShaderResources* pRes); - void RC_SetShaderQuality(EShaderType eST, EShaderQuality eSQ); - void RC_UpdateShaderItem(SShaderItem* pShaderItem, _smart_ptr pMaterial); - void RC_RefreshShaderResourceConstants(SShaderItem* pShaderItem, IMaterial* pMaterial); - void RC_SetCamera(); - void RC_RenderScene(int nFlags, RenderFunc pRenderFunc); - void RC_BeginFrame(); - void RC_EndFrame(bool bWait); - void RC_TryFlush(); - void RC_PrepareStereo(int mode, int output); - void RC_CopyToStereoTex(int channel); - void RC_SetStereoEye(int eye); - bool RC_DynTexUpdate(SDynTexture* pTex, int nNewWidth, int nNewHeight); - void RC_PushFog(); - void RC_PopFog(); - void RC_PushVP(); - void RC_PopVP(); - void RC_ForceSwapBuffers(); - void RC_SwitchToNativeResolutionBackbuffer(); - - void RC_StartVideoThread(); - void RC_StopVideoThread(); - void RT_StartVideoThread(); - void RT_StopVideoThread(); - - void RC_PostLoadLevel(); - void RC_SetEnvTexRT(SEnvTexture* pEnvTex, int nWidth, int nHeight, bool bPush); - void RC_SetEnvTexMatrix(SEnvTexture* pEnvTex); - void RC_PushRT(int nTarget, CTexture* pTex, SDepthTexture* pDS, int nS); - void RC_PopRT(int nTarget); - void RC_TexBlurAnisotropicVertical(CTexture* Tex, float fAnisoScale); - void RC_EntityDelete(IRenderNode* pRenderNode); - void RC_SetTexture(int nTex, int nUnit); - - bool RC_OC_ReadResult_Try(uint32 nDefaultNumSamples, CREOcclusionQuery* pRE); - - void RC_SetViewport(int x, int y, int width, int height, int id = 0); - - void RC_ReleaseVBStream(void* pVB, int nStream); - void RC_ForceMeshGC(bool instant = false, bool wait = false); - void RC_DevBufferSync(); - - void RC_ReleasePostEffects(); - void RC_ResetPostEffects(bool bOnSpecChange = false); - void RC_ResetGlass(); - void RC_DisableTemporalEffects(); - void RC_ResetToDefault(); - - void RC_CGCSetLayers(IColorGradingControllerInt* pController, const SColorChartLayer* pLayers, uint32 numLayers); - - void RC_GenerateSkyDomeTextures(CREHDRSky* pSky, int32 width, int32 height); - - void RC_SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false); - - void RC_RenderDebug(bool bRenderStats = true); - void RC_PushSkinningPoolId(uint32); - void RC_ReleaseRemappedBoneIndices(IRenderMesh* pRenderMesh, uint32 guid); - - void RC_InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer); - void RC_CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer); - void RC_DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments); - - using RenderCommandCB = AZStd::function; - void EnqueueRenderCommand(RenderCommandCB command); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - for (uint32 i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - pSizer->AddObject(m_Commands[i]); - } - } -} _ALIGN(128);//align to cache line - -_inline int SRenderThread::GetThreadList() -{ -#ifdef STRIP_RENDER_THREAD - return m_nCurThreadFill; -#else - if (IsRenderThread()) - { - return m_nCurThreadProcess; - } - - return m_nCurThreadFill; -#endif -} - -_inline bool SRenderThread::IsRenderThread(bool bAlwaysCheck) -{ -#ifdef STRIP_RENDER_THREAD - return true; -#else - threadID threadId = this->GetCurrentThreadId(bAlwaysCheck); - - return (threadId == m_nRenderThreadLoading || threadId == m_nRenderThread); -#endif -} - -_inline bool SRenderThread::IsRenderLoadingThread(bool bAlwaysCheck) -{ -#ifdef STRIP_RENDER_THREAD - return false; -#else - threadID threadId = this->GetCurrentThreadId(bAlwaysCheck); - - return threadId == m_nRenderThreadLoading; -#endif -} - -_inline bool SRenderThread::IsMainThread(bool bAlwaysCheck) -{ -#ifdef STRIP_RENDER_THREAD - return false; -#else - threadID threadId = this->GetCurrentThreadId(bAlwaysCheck); - - return threadId == m_nMainThread; -#endif -} - -_inline bool SRenderThread::IsMultithreaded() -{ -#ifdef STRIP_RENDER_THREAD - return false; -#else - return m_pThread != NULL; -#endif -} - -_inline int SRenderThread::CurThreadFill() const -{ -#ifdef STRIP_RENDER_THREAD - return 0; -#else - return m_nCurThreadFill; -#endif -} - -#ifdef STRIP_RENDER_THREAD -_inline void SRenderThread::FlushAndWait() -{ - return; -} -#endif diff --git a/Code/CryEngine/RenderDll/Common/RenderView.cpp b/Code/CryEngine/RenderDll/Common/RenderView.cpp deleted file mode 100644 index 3eafcaef8c..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderView.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RenderView.h" - -CRenderView::CRenderView() -{ - InitRenderItems(); -} - -CRenderView::~CRenderView() -{ - FreeRenderItems(); -} - -void CRenderView::ClearRenderItems() -{ - - for (int i = 0; i < MAX_LIST_ORDER; i++) - { - for (int j = 0; j < EFSLIST_NUM; j++) - { - m_renderItems[i][j].clear(); - } - } -} - -void CRenderView::FreeRenderItems() -{ - for (int i = 0; i < MAX_LIST_ORDER; i++) - { - for (int j = 0; j < EFSLIST_NUM; j++) - { - m_renderItems[i][j].resize(0); - } - } -} - -void CRenderView::InitRenderItems() -{ - threadID nThreadId = CryGetCurrentThreadId(); - - for (int i = 0; i < MAX_LIST_ORDER; i++) - { - for (int j = 0; j < EFSLIST_NUM; j++) - { - m_renderItems[i][j].Init(); - m_renderItems[i][j].SetNonWorkerThreadID(nThreadId); - } - } -} - -void CRenderView::PrepareForRendering() -{ - for (int i = 0; i < MAX_LIST_ORDER; i++) - { - for (int j = 0; j < EFSLIST_NUM; j++) - { - //m_renderItems[i][j].CoalesceMemory(); - //m_RenderListDesc[0].m_nEndRI[i][j] = m_renderItems[i][j].size(); - } - } - //ClearBatchFlags(); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderView::PrepareForWriting() -{ - // Clear batch flags. - ZeroStruct(m_BatchFlags); -} - -////////////////////////////////////////////////////////////////////////// -CThreadSafeWorkerContainer& CRenderView::GetRenderItems(int nAfterWater, int nRenderList) -{ - m_renderItems[nAfterWater][nRenderList].CoalesceMemory(); - return m_renderItems[nAfterWater][nRenderList]; -} - -uint32 CRenderView::GetBatchFlags(int recusrion, int nAfterWater, int nRenderList) const -{ - return m_BatchFlags[recusrion][nAfterWater][nRenderList]; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderView::AddRenderItem(IRenderElement* pElem, CRenderObject* RESTRICT_POINTER pObj, const SShaderItem& pSH, - uint32 nList, int nAafterWater, uint32 nBatchFlags, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - nBatchFlags |= (pSH.m_nPreprocessFlags & FSPR_MASK); - - size_t nIndex = ~0; - SRendItem* ri = m_renderItems[nAafterWater][nList].push_back_new(nIndex); - - ri->pObj = pObj; - - ri->nOcclQuery = SRendItem::kOcclQueryInvalid; - if (nList == EFSLIST_TRANSP || nList == EFSLIST_HALFRES_PARTICLES) - { - ri->fDist = pObj->m_fDistance + pObj->m_fSort; - } - else - { - ri->ObjSort = (pObj->m_ObjFlags & 0xffff0000) | pObj->m_nSort; - } - ri->nBatchFlags = nBatchFlags; - ri->nStencRef = pObj->m_nClipVolumeStencilRef + 1; // + 1, we start at 1. 0 is reserved for MSAAed areas. - - ri->rendItemSorter = rendItemSorter; - - CShader* pShader = (CShader*)pSH.m_pShader; - uint32 nResID = pSH.m_pShaderResources ? ((CShaderResources*)(pSH.m_pShaderResources))->m_Id : 0; - assert(nResID < CShader::s_ShaderResources_known.size()); - - ri->SortVal = (nResID << 18) | (pShader->mfGetID() << 6) | (pSH.m_nTechnique & 0x3f); - ri->pElem = pElem; - - // add flags atomically, if this one is not set already - volatile LONG* pBatchFlags = reinterpret_cast(&m_BatchFlags[passInfo.GetRecursiveLevel()][nAafterWater][nList]); - CryInterlockedOr(pBatchFlags, nBatchFlags); - - // update shadow pass flags if needed - if (nList == EFSLIST_SHADOW_GEN && !(nBatchFlags & FB_IGNORE_SG_MASK)) - { - volatile LONG* pShadowGenMask = reinterpret_cast(passInfo.ShadowGenMaskAddress()); - uint32 nOrFlags = 1 << passInfo.ShadowFrustumSide(); - CryInterlockedOr(pShadowGenMask, nOrFlags); - } -} diff --git a/Code/CryEngine/RenderDll/Common/RenderView.h b/Code/CryEngine/RenderDll/Common/RenderView.h deleted file mode 100644 index 08e133226b..0000000000 --- a/Code/CryEngine/RenderDll/Common/RenderView.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include - -#include "RenderPipeline.h" - -// This class encapsulate all renderbale information to render a camera view. -// It stores list of render items added by 3D engine -class CRenderView -{ -public: - CRenderView(); - ~CRenderView(); - - void FreeRenderItems(); - void ClearRenderItems(); - void InitRenderItems(); - - CThreadSafeWorkerContainer& GetRenderItems(int nAfterWater, int nRenderList); - uint32 GetBatchFlags(int recusrion, int nAfterWater, int nRenderList) const; - - void AddRenderItem(IRenderElement* pElem, CRenderObject* RESTRICT_POINTER pObj, const SShaderItem& pSH, - uint32 nList, int nAafterWater, uint32 nBatchFlags, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - - void PrepareForRendering(); - - void PrepareForWriting(); - - static CRenderView* CurrentRenderView() { return gRenDev->m_RP.m_pCurrentRenderView; } - static CRenderView* CurrentFillView() { return gRenDev->m_RP.m_pCurrentFillView; } - static CRenderView* GetRenderViewForThread(int thread) { return gRenDev->GetRenderViewForThread(thread); } - -private: - CThreadSafeWorkerContainer m_renderItems[MAX_LIST_ORDER][EFSLIST_NUM]; - - uint32 m_BatchFlags[MAX_REND_RECURSION_LEVELS][MAX_LIST_ORDER][EFSLIST_NUM]; - -public: - SRenderListDesc m_RenderListDesc[MAX_REND_RECURSION_LEVELS]; - -private: - CCamera m_camera; // Current camera - CameraViewParameters m_viewParameters; - -}; - -typedef std::shared_ptr CRenderViewPtr; diff --git a/Code/CryEngine/RenderDll/Common/Renderer.cpp b/Code/CryEngine/RenderDll/Common/Renderer.cpp deleted file mode 100644 index 9a548283a7..0000000000 --- a/Code/CryEngine/RenderDll/Common/Renderer.cpp +++ /dev/null @@ -1,8561 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Abstract renderer API - - -#include "RenderDll_precompiled.h" - -#include -#include -#include "Shadow_Renderer.h" -#include "IStatObj.h" -#include "I3DEngine.h" -#include "IMovieSystem.h" -#include "IIndexedMesh.h" -#include "BitFiddling.h" // IntegerLog2() -#include "ImageExtensionHelper.h" // CImageExtensionHelper -#include "Textures/Image/CImage.h" -#include "Textures/TextureManager.h" -#include "Textures/TextureStreamPool.h" -#include "PostProcess/PostEffects.h" -#include "RendElements/CRELensOptics.h" -#include "IStereoRenderer.h" -#include "../../Cry3DEngine/Environment/OceanEnvironmentBus.h" -#include - -#include -#include - -#include "RendElements/OpticsFactory.h" - -#include "GraphicsPipeline/FurBendData.h" - -#include "IGeomCache.h" -#include "ITimeOfDay.h" -#include - -#include "StatObjBus.h" -#include "RenderBus.h" - -#include "RenderCapabilities.h" -#include "RenderView.h" - -#if !defined(NULL_RENDERER) -#include "DriverD3D.h" //Needed for eGT_256bpp_PATH -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RENDERER_CPP_SECTION_1 1 -#define RENDERER_CPP_SECTION_2 2 -#define RENDERER_CPP_SECTION_4 4 -#define RENDERER_CPP_SECTION_5 5 -#define RENDERER_CPP_SECTION_7 7 -#define RENDERER_CPP_SECTION_8 8 -#define RENDERER_CPP_SECTION_9 9 -#define RENDERER_CPP_SECTION_10 10 -#define RENDERER_CPP_SECTION_11 11 -#define RENDERER_CPP_SECTION_12 12 -#define RENDERER_CPP_SECTION_13 13 -#define RENDERER_CPP_SECTION_14 14 -#define RENDERER_CPP_SECTION_15 15 -#define RENDERER_CPP_SECTION_16 16 -#define RENDERER_CPP_SECTION_17 17 -#endif - -#if defined(LINUX) -#include "ILog.h" -#endif -#include "IShader.h" -#include "Renderer.h" - -#include -#include -#include "Maestro/Types/AnimParamType.h" -#include - -#if defined(AZ_PLATFORM_WINDOWS) // Scrubber friendly define negation - #if defined(OPENGL) // Scrubber friendly define negation - #else - #ifdef ENABLE_FRAME_PROFILER_LABELS - // This is need for D3DPERF_ functions - __pragma(comment(lib, "d3d9.lib")) - #endif - #endif -#endif - -namespace -{ - class CConditonalLock - { - CryCriticalSection& _lock; - bool _bActive; - public: - CConditonalLock(CryCriticalSection& lock, bool bActive) - : _lock(lock) - , _bActive(bActive) - { - if (_bActive) - { - _lock.Lock(); - } - } - ~CConditonalLock() - { - if (_bActive) - { - _lock.Unlock(); - } - } - }; -} - - -bool QueryIsFullscreen(); - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) -string D3DDebug_GetLastMessage(); -#endif - -////////////////////////////////////////////////////////////////////////// -// Globals. -////////////////////////////////////////////////////////////////////////// -CRenderer* gRenDev = nullptr; - -#define RENDERER_DEFAULT_FONT "Fonts/default.xml" - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -#if !defined(RENDERER_DEFAULT_MESHPOOLSIZE) -# define RENDERER_DEFAULT_MESHPOOLSIZE (0U) -#endif -#if !defined(RENDERER_DEFAULT_MESHINSTANCEPOOLSIZE) -# define RENDERER_DEFAULT_MESHINSTANCEPOOLSIZE (0U) -#endif - -int g_CpuFlags = 0; - -CNameTableR* CCryNameR::ms_table = nullptr; - -////////////////////////////////////////////////////////////////////////// -// Pool allocators. -////////////////////////////////////////////////////////////////////////// -SDynTexture_PoolAlloc* g_pSDynTexture_PoolAlloc = 0; -////////////////////////////////////////////////////////////////////////// - -// per-frame profilers: collect the information for each frame for -// displaying statistics at the beginning of each frame -//#define PROFILER(ID,NAME) DEFINE_FRAME_PROFILER(ID,NAME) -//#include "FrameProfilers-list.h" -//#undef PROFILER - -/// Used to delete none pre-allocated RenderObject pool elements -struct SDeleteNonePoolRenderObjs -{ - SDeleteNonePoolRenderObjs(CRenderObject* pPoolStart, CRenderObject* pPoolEnd) - : m_pPoolStart(pPoolStart) - , m_pPoolEnd(pPoolEnd) {} - - void operator()(CRenderObject** pData) const - { - // Delete elements outside of pool range - if (*pData && (*pData < m_pPoolStart || *pData > m_pPoolEnd)) - { - delete *pData; - } - } - - CRenderObject* m_pPoolStart; - CRenderObject* m_pPoolEnd; -}; - -/// Used by console auto completion. -struct STextureNameAutoComplete - : public IConsoleArgumentAutoComplete -{ - virtual int GetCount() const - { - SResourceContainer* pRC = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (!pRC) - { - return 0; - } - return pRC->m_RMap.size(); - } - virtual const char* GetValue(int nIndex) const - { - SResourceContainer* pRC = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (!pRC || pRC->m_RMap.empty()) - { - return ""; - } - nIndex %= pRC->m_RMap.size(); - ResourcesMap::const_iterator it = pRC->m_RMap.begin(); - std::advance(it, nIndex); - CTexture* pTex = (CTexture*)it->second; - if (pTex) - { - return pTex->GetSourceName(); - } - return ""; - } -} g_TextureNameAutoComplete; - -// Common render console variables -int CRenderer::CV_r_ApplyToonShading; -int CRenderer::CV_r_GraphicsPipeline; -int CRenderer::CV_r_PostProcess_CB; -int CRenderer::CV_r_PostProcess; -float CRenderer::CV_r_dofMinZ; -float CRenderer::CV_r_dofMinZScale; -float CRenderer::CV_r_dofMinZBlendMult; -int CRenderer::CV_r_vsync; -int CRenderer::CV_r_OldBackendSkip; -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) -float CRenderer::CV_r_overrideRefreshRate = 0; -int CRenderer::CV_r_overrideScanlineOrder = 0; -int CRenderer::CV_r_overrideDXGIOutput = 0; -int CRenderer::CV_r_overrideDXGIOutputFS = 0; -#endif -#if defined(WIN32) || defined(WIN64) -int CRenderer::CV_r_FullscreenPreemption = 1; -#endif -AllocateConstIntCVar(CRenderer, CV_e_DebugTexelDensity); -int CRenderer::CV_r_flush; -int CRenderer::CV_r_minimizeLatency = 0; -AllocateConstIntCVar(CRenderer, CV_r_statsMinDrawcalls); -AllocateConstIntCVar(CRenderer, CV_r_stats); -AllocateConstIntCVar(CRenderer, CV_r_profiler); -float CRenderer::CV_r_profilerTargetFPS; -int CRenderer::CV_r_log = 0; -AllocateConstIntCVar(CRenderer, CV_r_logTexStreaming); -AllocateConstIntCVar(CRenderer, CV_r_logShaders); -int CRenderer::CV_r_logVBuffers; -AllocateConstIntCVar(CRenderer, CV_r_logVidMem); -AllocateConstIntCVar(CRenderer, CV_r_predicatedtiling); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -int CRenderer::CV_r_DeferredShadingSortLights; -int CRenderer::CV_r_DeferredShadingAmbientSClear; -int CRenderer::CV_r_msaa; -int CRenderer::CV_r_msaa_samples; -int CRenderer::CV_r_msaa_quality; -int CRenderer::CV_r_msaa_debug; -float CRenderer::CV_r_msaa_threshold_normal; -float CRenderer::CV_r_msaa_threshold_depth; - -int CRenderer::CV_r_BreakOnError; -int CRenderer::CV_r_D3D12SubmissionThread; -int CRenderer::CV_r_ReprojectOnlyStaticObjects; -int CRenderer::CV_r_ReverseDepth; - -int CRenderer::CV_r_EnableDebugLayer; -int CRenderer::CV_r_NoDraw; - -AllocateConstIntCVar(CRenderer, CV_r_multithreaded); -// CRY DX12 -AllocateConstIntCVar(CRenderer, CV_r_multithreadedDrawing); -AllocateConstIntCVar(CRenderer, CV_r_multithreadedDrawingActiveThreshold); - -int CRenderer::CV_r_multigpu; -AllocateConstIntCVar(CRenderer, CV_r_texturecompiling); -AllocateConstIntCVar(CRenderer, CV_r_texturecompilingIndicator); -AllocateConstIntCVar(CRenderer, CV_r_TexturesDebugBandwidth); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreaming); -AllocateConstIntCVar(CRenderer, CV_r_TexturesStreamingDebug); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingnoupload); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingonlyvideo); -int CRenderer::CV_r_texturesstreamingsync; -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingResidencyEnabled); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingUpdateType); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingPrecacheRounds); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingSuppress); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingPostponeMips); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingPostponeThresholdKB); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingPostponeThresholdMip); -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingMinReadSizeKB); -int CRenderer::CV_r_texturesstreamingSkipMips; -int CRenderer::CV_r_texturesstreamingMinUsableMips; -int CRenderer::CV_r_texturesstreamingJobUpdate; -#if defined(TEXSTRM_DEFERRED_UPLOAD) -int CRenderer::CV_r_texturesstreamingDeferred; -#endif -#if defined(SUPPORTS_INPLACE_TEXTURE_STREAMING) -int CRenderer::CV_r_texturesstreamingInPlace; -#endif -float CRenderer::CV_r_texturesstreamingResidencyTimeTestLimit; -float CRenderer::CV_r_rain_maxviewdist; -float CRenderer::CV_r_rain_maxviewdist_deferred; -float CRenderer::CV_r_measureoverdrawscale; -float CRenderer::CV_r_texturesstreamingResidencyTime; -float CRenderer::CV_r_texturesstreamingResidencyThrottle; -AllocateConstIntCVar(CRenderer, CV_r_texturesstreamingmipfading); -int CRenderer::CV_r_TexturesStreamPoolSize; -int CRenderer::CV_r_TexturesStreamPoolSecondarySize; -int CRenderer::CV_r_texturesskiplowermips; -int CRenderer::CV_r_rendertargetpoolsize; -float CRenderer::CV_r_TexturesStreamingMaxRequestedMB; -int CRenderer::CV_r_TexturesStreamingMaxRequestedJobs; -float CRenderer::CV_r_TexturesStreamingMipBias; -int CRenderer::CV_r_TexturesStreamingMipClampDVD; -int CRenderer::CV_r_TexturesStreamingDisableNoStreamDuringLoad; -float CRenderer::CV_r_TextureLodDistanceRatio; - - -int CRenderer::CV_r_buffer_banksize; -int CRenderer::CV_r_constantbuffer_banksize; -int CRenderer::CV_r_constantbuffer_watermark; -int CRenderer::CV_r_buffer_sli_workaround; -int CRenderer::CV_r_transient_pool_size; -AllocateConstIntCVar(CRenderer, CV_r_buffer_enable_lockless_updates); -AllocateConstIntCVar(CRenderer, CV_r_enable_full_gpu_sync); -int CRenderer::CV_r_buffer_pool_max_allocs; -int CRenderer::CV_r_buffer_pool_defrag_static; -int CRenderer::CV_r_buffer_pool_defrag_dynamic; -int CRenderer::CV_r_buffer_pool_defrag_max_moves; - -int CRenderer::CV_r_dyntexmaxsize; -int CRenderer::CV_r_dyntexatlascloudsmaxsize; - -AllocateConstIntCVar(CRenderer, CV_r_texpostponeloading); -AllocateConstIntCVar(CRenderer, CV_r_texpreallocateatlases); -int CRenderer::CV_r_texatlassize; -int CRenderer::CV_r_texminanisotropy; -int CRenderer::CV_r_texmaxanisotropy; -AllocateConstIntCVar(CRenderer, CV_r_texlog); -AllocateConstIntCVar(CRenderer, CV_r_texnoload); -AllocateConstIntCVar(CRenderer, CV_r_texBlockOnLoad); - -AllocateConstIntCVar(CRenderer, CV_r_debugrendermode); -AllocateConstIntCVar(CRenderer, CV_r_debugrefraction); - -int CRenderer::CV_r_VRAMDebug; -int CRenderer::CV_r_DebugLightLayers; - -int CRenderer::CV_r_DeferredShadingTiled; -int CRenderer::CV_r_DeferredShadingTiledHairQuality; -int CRenderer::CV_r_DeferredShadingTiledDebugDirect; -int CRenderer::CV_r_DeferredShadingTiledDebugIndirect; -int CRenderer::CV_r_DeferredShadingTiledDebugAccumulation; -int CRenderer::CV_r_DeferredShadingTiledDebugAlbedo; -int CRenderer::CV_r_DeferredShadingSSS; -int CRenderer::CV_r_DeferredShadingFilterGBuffer; - -int CRenderer::CV_r_UsePersistentRTForModelHUD; - -AllocateConstIntCVar(CRenderer, CV_r_deferredshadingLightVolumes); -AllocateConstIntCVar(CRenderer, CV_r_deferredDecals); -AllocateConstIntCVar(CRenderer, CV_r_deferredDecalsDebug); -AllocateConstIntCVar(CRenderer, CV_r_deferredDecalsOnDynamicObjects); - -AllocateConstIntCVar(CRenderer, CV_r_deferredshadingDBTstencil); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingScissor); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingLBuffersFmt); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingDepthBoundsTest); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingDebug); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingDebugGBuffer); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingAmbient); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingEnvProbes); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingAmbientLights); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingLights); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingAreaLights); -AllocateConstIntCVar(CRenderer, CV_r_DeferredShadingStencilPrepass); -int CRenderer::CV_r_CBufferUseNativeDepth; - - -float CRenderer::CV_r_DeferredShadingLightLodRatio; -float CRenderer::CV_r_DeferredShadingLightStencilRatio; - -int CRenderer::CV_r_HDRDebug; -int CRenderer::CV_r_HDRBloom; -int CRenderer::CV_r_HDRBloomQuality; - -int CRenderer::CV_r_ToneMapTechnique; -int CRenderer::CV_r_ColorSpace; -int CRenderer::CV_r_ToneMapExposureType; -float CRenderer::CV_r_ToneMapManualExposureValue; - -AllocateConstIntCVar(CRenderer, CV_r_HDRVignetting); -AllocateConstIntCVar(CRenderer, CV_r_HDRTexFormat); - -int CRenderer::CV_r_HDRDolbyDynamicMetadata; - -int CRenderer::CV_r_HDRDolbyScurve; -float CRenderer::CV_r_HDRDolbyScurveSourceMin; -float CRenderer::CV_r_HDRDolbyScurveSourceMid; -float CRenderer::CV_r_HDRDolbyScurveSourceMax; -float CRenderer::CV_r_HDRDolbyScurveSlope; -float CRenderer::CV_r_HDRDolbyScurveScale; -float CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMin; -float CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMid; -float CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMax; -float CRenderer::CV_r_HDRDolbyScurveVisionTargetMin; -float CRenderer::CV_r_HDRDolbyScurveVisionTargetMid; -float CRenderer::CV_r_HDRDolbyScurveVisionTargetMax; - -float CRenderer::CV_r_HDREyeAdaptationSpeed; -int CRenderer::CV_r_HDREyeAdaptationMode; -float CRenderer::CV_r_HDRGrainAmount; - -float CRenderer::CV_r_Sharpening; -float CRenderer::CV_r_ChromaticAberration; - -AllocateConstIntCVar(CRenderer, CV_r_geominstancing); -AllocateConstIntCVar(CRenderer, CV_r_geominstancingdebug); -AllocateConstIntCVar(CRenderer, CV_r_materialsbatching); -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) || defined(USE_SILHOUETTEPOM_CVAR) -int CRenderer::CV_r_SilhouettePOM; -#endif -#ifdef WATER_TESSELLATION_RENDERER -int CRenderer::CV_r_WaterTessellationHW; -#endif -int CRenderer::CV_r_tessellationdebug; -float CRenderer::CV_r_tessellationtrianglesize; -float CRenderer::CV_r_displacementfactor; - -int CRenderer::CV_r_batchtype; -int CRenderer::CV_r_geominstancingthreshold; -int CRenderer::m_iGeomInstancingThreshold = 0; // 0 means not set yet - -int CRenderer::CV_r_beams; - -AllocateConstIntCVar(CRenderer, CV_r_DebugLightVolumes); - -AllocateConstIntCVar(CRenderer, CV_r_UseShadowsPool); - -float CRenderer::CV_r_ShadowsBias; -float CRenderer::CV_r_ShadowsAdaptionRangeClamp; -float CRenderer::CV_r_ShadowsAdaptionSize; -float CRenderer::CV_r_ShadowsAdaptionMin; -float CRenderer::CV_r_ShadowsParticleKernelSize; -float CRenderer::CV_r_ShadowsParticleJitterAmount; -float CRenderer::CV_r_ShadowsParticleAnimJitterAmount; -float CRenderer::CV_r_ShadowsParticleNormalEffect; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_16 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - -AllocateConstIntCVar(CRenderer, CV_r_ShadowGenMode); - -AllocateConstIntCVar(CRenderer, CV_r_ShadowsUseClipVolume); -AllocateConstIntCVar(CRenderer, CV_r_shadowtexformat); -AllocateConstIntCVar(CRenderer, CV_r_ShadowsMaskResolution); -AllocateConstIntCVar(CRenderer, CV_r_ShadowsMaskDownScale); -AllocateConstIntCVar(CRenderer, CV_r_ShadowsStencilPrePass); -int CRenderer::CV_r_ShadowsDepthBoundNV; -int CRenderer::CV_r_ShadowsPCFiltering; -float CRenderer::CV_r_shadow_jittering; -int CRenderer::CV_r_ShadowPoolMaxTimeslicedUpdatesPerFrame; -int CRenderer::CV_r_ShadowCastingLightsMaxCount; -AllocateConstIntCVar(CRenderer, CV_r_ShadowsGridAligned); -AllocateConstIntCVar(CRenderer, CV_r_ShadowPass); -AllocateConstIntCVar(CRenderer, CV_r_ShadowGen); -AllocateConstIntCVar(CRenderer, CV_r_ShadowPoolMaxFrames); -int CRenderer::CV_r_ShadowsCache; -int CRenderer::CV_r_ShadowsCacheFormat; -int CRenderer::CV_r_ShadowsScreenSpace; -int CRenderer::CV_r_ShadowsNearestMapResolution; -int CRenderer::CV_r_HeightMapAO; -float CRenderer::CV_r_HeightMapAOAmount; -float CRenderer::CV_r_HeightMapAORange; -float CRenderer::CV_r_HeightMapAOResolution; -float CRenderer::CV_r_RenderMeshHashGridUnitSize; - -AllocateConstIntCVar(CRenderer, CV_r_TerrainAO); -AllocateConstIntCVar(CRenderer, CV_r_TerrainAO_FadeDist); - -AllocateConstIntCVar(CRenderer, CV_r_debuglights); -AllocateConstIntCVar(CRenderer, CV_r_lightssinglepass); - -AllocateConstIntCVar(CRenderer, CV_r_impostersdraw); -float CRenderer::CV_r_imposterratio; -int CRenderer::CV_r_impostersupdateperframe; -AllocateConstIntCVar(CRenderer, CV_r_shaderslazyunload); -AllocateConstIntCVar(CRenderer, CV_r_shadersdebug); -#if !defined(CONSOLE) -int CRenderer::CV_r_shadersorbis; -int CRenderer::CV_r_shadersdx10; -int CRenderer::CV_r_shadersdx11; -int CRenderer::CV_r_shadersGL4; -int CRenderer::CV_r_shadersGLES3; -int CRenderer::CV_r_shadersMETAL; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_14 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - -int CRenderer::CV_r_shadersPlatform; -#endif -AllocateConstIntCVar(CRenderer, CV_r_shadersignoreincludeschanging); -int CRenderer::CV_r_shaderspreactivate; -int CRenderer::CV_r_shadersAllowCompilation; -AllocateConstIntCVar(CRenderer, CV_r_shadersediting); -AllocateConstIntCVar(CRenderer, CV_r_shaderscompileautoactivate); -AllocateConstIntCVar(CRenderer, CV_r_shadersremotecompiler); -int CRenderer::CV_r_shadersasynccompiling; -int CRenderer::CV_r_shadersasyncactivation; -int CRenderer::CV_r_shadersasyncmaxthreads; -int CRenderer::CV_r_shaderscachedeterministic; -AllocateConstIntCVar(CRenderer, CV_r_shadersprecachealllights); -AllocateConstIntCVar(CRenderer, CV_r_ReflectTextureSlots); -int CRenderer::CV_r_shaderssubmitrequestline; -int CRenderer::CV_r_shadersuseinstancelookuptable; -int CRenderer::CV_r_shaderslogcachemisses; -int CRenderer::CV_r_shadersImport; -int CRenderer::CV_r_shadersExport; -int CRenderer::CV_r_shadersCacheUnavailableShaders; -AllocateConstIntCVar(CRenderer, CV_r_ShadersUseLLVMDirectXCompiler); - -AllocateConstIntCVar(CRenderer, CV_r_meshprecache); -int CRenderer::CV_r_meshpoolsize; -int CRenderer::CV_r_meshinstancepoolsize; - -AllocateConstIntCVar(CRenderer, CV_r_ZPassDepthSorting); -float CRenderer::CV_r_ZPrepassMaxDist; -int CRenderer::CV_r_usezpass; - -AllocateConstIntCVar(CRenderer, CV_r_TransparentPasses); -AllocateConstIntCVar(CRenderer, CV_r_TranspDepthFixup); -AllocateConstIntCVar(CRenderer, CV_r_SoftAlphaTest); -AllocateConstIntCVar(CRenderer, CV_r_usehwskinning); -AllocateConstIntCVar(CRenderer, CV_r_usemateriallayers); -AllocateConstIntCVar(CRenderer, CV_r_ParticlesSoftIsec); -AllocateConstIntCVar(CRenderer, CV_r_ParticlesRefraction); -int CRenderer::CV_r_ParticlesHalfRes; -AllocateConstIntCVar(CRenderer, CV_r_ParticlesHalfResAmount); -AllocateConstIntCVar(CRenderer, CV_r_ParticlesHalfResBlendMode); -AllocateConstIntCVar(CRenderer, CV_r_ParticlesInstanceVertices); -float CRenderer::CV_r_ParticlesAmountGI; -int CRenderer::CV_r_ParticlesGpuMaxEmitCount; - -int CRenderer::CV_r_AntialiasingMode_CB; -int CRenderer::CV_r_AntialiasingMode; -float CRenderer::CV_r_AntialiasingNonTAASharpening; -int CRenderer::CV_r_AntialiasingTAAJitterPattern; -float CRenderer::CV_r_AntialiasingTAAClampingFactor; -float CRenderer::CV_r_AntialiasingTAANewFrameWeight; -float CRenderer::CV_r_AntialiasingTAASharpening; -AllocateConstIntCVar(CRenderer, CV_r_AntialiasingTAAUseAntiFlickerFilter); -AllocateConstIntCVar(CRenderer, CV_r_AntialiasingTAAUseJitterMipBias); -AllocateConstIntCVar(CRenderer, CV_r_AntialiasingTAAUseVarianceClamping); -AllocateConstIntCVar(CRenderer, CV_r_AntialiasingModeDebug); -AllocateConstIntCVar(CRenderer, CV_r_AntialiasingModeEditor); - - -Vec2 CRenderer::s_overscanBorders(0, 0); - -AllocateConstIntCVar(CRenderer, CV_r_MotionVectors); -AllocateConstIntCVar(CRenderer, CV_r_MotionVectorsTransparency); -AllocateConstIntCVar(CRenderer, CV_r_MotionVectorsDebug); -float CRenderer::CV_r_MotionVectorsTransparencyAlphaThreshold; -int CRenderer::CV_r_MotionBlur; -int CRenderer::CV_r_RenderMotionBlurAfterHDR; -int CRenderer::CV_r_MotionBlurScreenShot; -int CRenderer::CV_r_MotionBlurQuality; -int CRenderer::CV_r_MotionBlurGBufferVelocity; -float CRenderer::CV_r_MotionBlurThreshold; -float CRenderer::CV_r_MotionBlurShutterSpeed; -float CRenderer::CV_r_MotionBlurCameraMotionScale; -float CRenderer::CV_r_MotionBlurMaxViewDist; - -AllocateConstIntCVar(CRenderer, CV_r_customvisions); - -AllocateConstIntCVar(CRenderer, CV_r_snow); -AllocateConstIntCVar(CRenderer, CV_r_snow_halfres); -AllocateConstIntCVar(CRenderer, CV_r_snow_displacement); -AllocateConstIntCVar(CRenderer, CV_r_snowFlakeClusters); - -AllocateConstIntCVar(CRenderer, CV_r_rain); -AllocateConstIntCVar(CRenderer, CV_r_rain_ignore_nearest); -float CRenderer::CV_r_rainamount; -float CRenderer::CV_r_rainDistMultiplier; -float CRenderer::CV_r_rainOccluderSizeTreshold; - -int CRenderer::CV_r_SSReflections; -int CRenderer::CV_r_SSReflHalfRes; -int CRenderer::CV_r_ssdo; -int CRenderer::CV_r_ssdoHalfRes; -int CRenderer::CV_r_ssdoColorBleeding; -float CRenderer::CV_r_ssdoRadius; -float CRenderer::CV_r_ssdoRadiusMin; -float CRenderer::CV_r_ssdoRadiusMax; -float CRenderer::CV_r_ssdoAmountDirect; -float CRenderer::CV_r_ssdoAmountAmbient; -float CRenderer::CV_r_ssdoAmountReflection; - -AllocateConstIntCVar(CRenderer, CV_r_dof); - -AllocateConstIntCVar(CRenderer, CV_r_measureoverdraw); -AllocateConstIntCVar(CRenderer, CV_r_printmemoryleaks); -AllocateConstIntCVar(CRenderer, CV_r_releaseallresourcesonexit); - -int CRenderer::CV_r_rc_autoinvoke; - -int CRenderer::CV_r_Refraction; -int CRenderer::CV_r_sunshafts; - -AllocateConstIntCVar(CRenderer, CV_r_MergeShadowDrawcalls); - -int CRenderer::CV_r_PostProcessReset; -AllocateConstIntCVar(CRenderer, CV_r_PostProcessFilters); -AllocateConstIntCVar(CRenderer, CV_r_PostProcessGameFx); - -int CRenderer::CV_r_colorRangeCompression; - -int CRenderer::CV_r_colorgrading; -int CRenderer::CV_r_colorgrading_selectivecolor; -AllocateConstIntCVar(CRenderer, CV_r_colorgrading_levels); -AllocateConstIntCVar(CRenderer, CV_r_colorgrading_filters); -int CRenderer::CV_r_colorgrading_charts; -int CRenderer::CV_r_ColorgradingChartsCache; - -AllocateConstIntCVar(CRenderer, CV_r_cloudsupdatealways); -AllocateConstIntCVar(CRenderer, CV_r_cloudsdebug); - -AllocateConstIntCVar(CRenderer, CV_r_showdyntextures); -int CRenderer::CV_r_ShowDynTexturesMaxCount; -ICVar* CRenderer::CV_r_ShowDynTexturesFilter; -AllocateConstIntCVar(CRenderer, CV_r_shownormals); -AllocateConstIntCVar(CRenderer, CV_r_showlines); -float CRenderer::CV_r_normalslength; -AllocateConstIntCVar(CRenderer, CV_r_showtangents); -AllocateConstIntCVar(CRenderer, CV_r_showtimegraph); -AllocateConstIntCVar(CRenderer, CV_r_DebugFontRendering); -AllocateConstIntCVar(CRenderer, CV_profileStreaming); -AllocateConstIntCVar(CRenderer, CV_r_graphstyle); -AllocateConstIntCVar(CRenderer, CV_r_showbufferusage); - -ICVar* CRenderer::CV_r_ShaderCompilerServer; -ICVar* CRenderer::CV_r_ShaderEmailTags; -ICVar* CRenderer::CV_r_ShaderEmailCCs; -int CRenderer::CV_r_ShaderCompilerPort; -int CRenderer::CV_r_ShaderCompilerDontCache; -int CRenderer::CV_r_AssetProcessorShaderCompiler = 0; - -int CRenderer::CV_r_flares = FLARES_DEFAULT_VAL; -AllocateConstIntCVar(CRenderer, CV_r_flareHqShafts); -float CRenderer::CV_r_FlaresChromaShift; -int CRenderer::CV_r_FlaresIrisShaftMaxPolyNum; -float CRenderer::CV_r_FlaresTessellationRatio; - -int CRenderer::CV_r_envcmresolution; -int CRenderer::CV_r_envtexresolution; -float CRenderer::CV_r_waterupdateFactor; -float CRenderer::CV_r_waterupdateDistance; -float CRenderer::CV_r_envcmupdateinterval; -float CRenderer::CV_r_envtexupdateinterval; -int CRenderer::CV_r_SlimGBuffer; -AllocateConstIntCVar(CRenderer, CV_r_waterreflections); -AllocateConstIntCVar(CRenderer, CV_r_waterreflections_quality); -float CRenderer::CV_r_waterreflections_min_visible_pixels_update; -float CRenderer::CV_r_waterreflections_minvis_updatefactormul; -float CRenderer::CV_r_waterreflections_minvis_updatedistancemul; -int CRenderer::CV_r_watercaustics; //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. -float CRenderer::CV_r_watercausticsdistance; -int CRenderer::CV_r_watervolumecaustics; -int CRenderer::CV_r_watervolumecausticsdensity; -int CRenderer::CV_r_watervolumecausticsresolution; -float CRenderer::CV_r_watervolumecausticssnapfactor; -float CRenderer::CV_r_watervolumecausticsmaxdistance; -AllocateConstIntCVar(CRenderer, CV_r_water_godrays); -float CRenderer::CV_r_water_godrays_distortion; -AllocateConstIntCVar(CRenderer, CV_r_texNoAnisoAlphaTest); -AllocateConstIntCVar(CRenderer, CV_r_reflections); -AllocateConstIntCVar(CRenderer, CV_r_reflections_quality); -float CRenderer::CV_r_waterreflections_offset; -AllocateConstIntCVar(CRenderer, CV_r_reloadshaders); -AllocateConstIntCVar(CRenderer, CV_r_detailtextures); -float CRenderer::CV_r_detaildistance; -AllocateConstIntCVar(CRenderer, CV_r_texbindmode); -AllocateConstIntCVar(CRenderer, CV_r_nodrawshaders); -int CRenderer::CV_r_nodrawnear; -float CRenderer::CV_r_DrawNearZRange; -float CRenderer::CV_r_DrawNearFarPlane; -float CRenderer::CV_r_drawnearfov; -int CRenderer::CV_r_DrawNearShadows; -AllocateConstIntCVar(CRenderer, CV_r_profileshaders); -AllocateConstIntCVar(CRenderer, CV_r_ProfileShadersSmooth); -AllocateConstIntCVar(CRenderer, CV_r_ProfileShadersGroupByName); -ICVar* CRenderer::CV_r_excludeshader; -ICVar* CRenderer::CV_r_excludemesh; - -float CRenderer::CV_r_gamma; -float CRenderer::CV_r_contrast; -float CRenderer::CV_r_brightness; - -AllocateConstIntCVar(CRenderer, CV_r_nohwgamma); - -int CRenderer::CV_r_scissor; - -AllocateConstIntCVar(CRenderer, CV_r_wireframe); -int CRenderer::CV_r_GetScreenShot; - -AllocateConstIntCVar(CRenderer, CV_r_character_nodeform); - -AllocateConstIntCVar(CRenderer, CV_r_ZPassOnly); - -int CRenderer::CV_r_ShowVideoMemoryStats; - -ICVar* CRenderer::CV_r_ShowTexture = NULL; -ICVar* CRenderer::CV_r_TexturesStreamingDebugfilter = NULL; -int CRenderer::CV_r_TexturesStreamingDebugMinSize; -int CRenderer::CV_r_TexturesStreamingDebugMinMip; -AllocateConstIntCVar(CRenderer, CV_r_TexturesStreamingDebugDumpIntoLog); - -AllocateConstIntCVar(CRenderer, CV_r_ShowLightBounds); - -AllocateConstIntCVar(CRenderer, CV_r_MergeRenderChunks); -AllocateConstIntCVar(CRenderer, CV_r_TextureCompressor); - -int CRenderer::CV_r_ParticlesTessellation; -int CRenderer::CV_r_ParticlesTessellationTriSize; - -float CRenderer::CV_r_ZFightingDepthScale; -float CRenderer::CV_r_ZFightingExtrude; - -float CRenderer::CV_r_TexelsPerMeter; -float CRenderer::s_previousTexelsPerMeter = -1.0f; - -int CRenderer::CV_r_ConditionalRendering; -int CRenderer::CV_r_enableAltTab; -int CRenderer::CV_r_StereoDevice; -int CRenderer::CV_r_StereoMode; -int CRenderer::CV_r_StereoOutput; -int CRenderer::CV_r_StereoFlipEyes; -float CRenderer::CV_r_StereoStrength; -float CRenderer::CV_r_StereoEyeDist; -float CRenderer::CV_r_StereoScreenDist; -float CRenderer::CV_r_StereoNearGeoScale; -float CRenderer::CV_r_StereoHudScreenDist; -float CRenderer::CV_r_StereoGammaAdjustment; -int CRenderer::CV_r_ConsoleBackbufferWidth; -int CRenderer::CV_r_ConsoleBackbufferHeight; - -// constant used to indicate that CustomResMax should be set to the maximum allowable by device resources -const int CRenderer::s_CustomResMaxSize_USE_MAX_RESOURCES = -1; -int CRenderer::CV_r_CustomResMaxSize; -int CRenderer::CV_r_CustomResWidth; -int CRenderer::CV_r_CustomResHeight; -int CRenderer::CV_r_CustomResPreview; -int CRenderer::CV_r_Supersampling; -int CRenderer::CV_r_SupersamplingFilter; - -float CRenderer::CV_r_FogDepthTest; -#if defined(VOLUMETRIC_FOG_SHADOWS) -int CRenderer::CV_r_FogShadows; -int CRenderer::CV_r_FogShadowsMode; -#endif -int CRenderer::CV_r_FogShadowsWater; - -AllocateConstIntCVar(CRenderer, CV_r_RainDropsEffect); - -AllocateConstIntCVar(CRenderer, CV_r_RefractionPartialResolves); -AllocateConstIntCVar(CRenderer, CV_r_RefractionPartialResolvesDebug); - -AllocateConstIntCVar(CRenderer, CV_r_Batching); - -AllocateConstIntCVar(CRenderer, CV_r_Unlit); -AllocateConstIntCVar(CRenderer, CV_r_HideSunInCubemaps); - -AllocateConstIntCVar(CRenderer, CV_r_ParticlesDebug); - -// Confetti David Srour: Upscaling Quality for Metal -AllocateConstIntCVar(CRenderer, CV_r_UpscalingQuality); - -//Clears GMEM G-Buffer -AllocateConstIntCVar(CRenderer, CV_r_ClearGMEMGBuffer); - -// Enables fast math for metal shaders -AllocateConstIntCVar(CRenderer, CV_r_MetalShadersFastMath); - -int CRenderer::CV_r_CubeDepthMapResolution; - -int CRenderer::CV_r_SkipNativeUpscale; -int CRenderer::CV_r_SkipRenderComposites; - -// Confetti David Srour: Global VisArea/Portals blend weight for GMEM path -float CRenderer::CV_r_GMEMVisAreasBlendWeight; - -// Confetti David Srour: 0 = disable, 1= 256bpp GMEM path, 2 = 128bpp GMEM path -int CRenderer::CV_r_EnableGMEMPath; - -// Confetti David Srour: 0 = regular postproc, 1 = mobile pipeline with compute -int CRenderer::CV_r_EnableGMEMPostProcCS; - -// Confetti David Srour: Used to reduce draw calls during DOF's gathers -int CRenderer::CV_r_GMEM_DOF_Gather1_Quality; -int CRenderer::CV_r_GMEM_DOF_Gather2_Quality; - -int CRenderer::CV_r_RainUseStencilMasking; - -// Confetti Thomas Zeng: 0 = diable, 1 = enable -int CRenderer::CV_r_EnableComputeDownSampling; - -// Confetti Vera -float CRenderer::CV_r_CubeDepthMapFarPlane; - -int CRenderer::CV_r_ForceFixedPointRenderTargets; - -// Fur control parameters -int CRenderer::CV_r_Fur; -int CRenderer::CV_r_FurShellPassCount; -int CRenderer::CV_r_FurShowBending; -int CRenderer::CV_r_FurDebug; -int CRenderer::CV_r_FurDebugOneShell; -int CRenderer::CV_r_FurFinPass; -int CRenderer::CV_r_FurFinShadowPass; -float CRenderer::CV_r_FurMovementBendingBias; -float CRenderer::CV_r_FurMaxViewDist; - -#if defined(ENABLE_RENDER_AUX_GEOM) -int CRenderer::CV_r_enableauxgeom; -#endif - -int CRenderer::CV_r_ParticleVerticePoolSize; -int CRenderer::CV_r_GeomCacheInstanceThreshold; -int CRenderer::CV_r_VisAreaClipLightsPerPixel; - -int CRenderer::CV_r_VolumetricFog = 0; -int CRenderer::CV_r_VolumetricFogTexScale; -int CRenderer::CV_r_VolumetricFogTexDepth; -float CRenderer::CV_r_VolumetricFogReprojectionBlendFactor; -int CRenderer::CV_r_VolumetricFogSample; -int CRenderer::CV_r_VolumetricFogShadow; -int CRenderer::CV_r_VolumetricFogDownscaledSunShadow; -int CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio; -int CRenderer::CV_r_VolumetricFogReprojectionMode; -float CRenderer::CV_r_VolumetricFogMinimumLightBulbSize; -float CRenderer::CV_r_ResolutionScale = 1.0f; -int CRenderer::CV_r_OutputShaderSourceFiles = 0; - -// Specular antialiasing -int CRenderer::CV_r_SpecularAntialiasing = 1; - -// Console -float CRenderer::CV_r_minConsoleFontSize; -float CRenderer::CV_r_maxConsoleFontSize; - -// Linux -int CRenderer::CV_r_linuxSkipWindowCreation = 0; - -// Graphics programmers: Use these in your code for local tests/debugging. -// Delete all references in your code before you submit -int CRenderer::CV_r_GraphicsTest00; -int CRenderer::CV_r_GraphicsTest01; -int CRenderer::CV_r_GraphicsTest02; -int CRenderer::CV_r_GraphicsTest03; -int CRenderer::CV_r_GraphicsTest04; -int CRenderer::CV_r_GraphicsTest05; -int CRenderer::CV_r_GraphicsTest06; -int CRenderer::CV_r_GraphicsTest07; -int CRenderer::CV_r_GraphicsTest08; -int CRenderer::CV_r_GraphicsTest09; - -////////////////////////////////////////////////////////////////////// - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - -static void ShadersPrecacheList([[maybe_unused]] IConsoleCmdArgs* Cmd) -{ - gRenDev->m_cEF.mfPrecacheShaders(false); -} -static void ShadersStatsList([[maybe_unused]] IConsoleCmdArgs* Cmd) -{ - gRenDev->m_cEF.mfPrecacheShaders(true); -} -static void GetShaderList([[maybe_unused]] IConsoleCmdArgs* Cmd) -{ - gRenDev->m_cEF.mfGetShaderList(); -} - -template -void ShadersOptimizeHelper(CallableT setupParserBin, const char* logString) -{ - setupParserBin(); - CryLogAlways("\nStarting shaders optimizing for %s...", logString); - AZStd::string str = "@usercache@/" + gRenDev->m_cEF.m_ShadersCache; - iLog->Log("Optimize shader cache folder: '%s'", gRenDev->m_cEF.m_ShadersCache.c_str()); - gRenDev->m_cEF.mfOptimiseShaders(str.c_str(), false); -} - -static void ShadersOptimise([[maybe_unused]] IConsoleCmdArgs* Cmd) -{ - if (CRenderer::CV_r_shadersdx11) - { - ShadersOptimizeHelper(CParserBin::SetupForD3D11, "DX11"); - } - if (CRenderer::CV_r_shadersGL4) - { - ShadersOptimizeHelper(CParserBin::SetupForGL4, "GLSL 4"); - } - if (CRenderer::CV_r_shadersGLES3) - { - ShadersOptimizeHelper(CParserBin::SetupForGLES3, " GLSL-ES 3"); - } - if (CRenderer::CV_r_shadersorbis) - { - ShadersOptimizeHelper(CParserBin::SetupForOrbis, "Orbis"); - } - if (CRenderer::CV_r_shadersMETAL) - { - ShadersOptimizeHelper(CParserBin::SetupForMETAL, "METAL"); - } -} - -#endif - -static void OnChange_CV_r_PostProcess(ICVar* pCVar) -{ - if (!pCVar) - { - return; - } - - if (gRenDev->m_pRT && !gRenDev->m_pRT->IsRenderThread()) - { - gRenDev->m_pRT->FlushAndWait(); - } - - gRenDev->CV_r_PostProcess = pCVar->GetIVal(); -} - -// Track all AA conditions/dependencies in one place. Set corresponding cvars. -static void OnChange_CV_r_AntialiasingMode(ICVar* pCVar) -{ - if (!pCVar) - { - return; - } - - if (gRenDev->m_pRT && !gRenDev->m_pRT->IsRenderThread()) - { - gRenDev->m_pRT->FlushAndWait(); - } - - - int32 nVal = pCVar->GetIVal(); - nVal = min(eAT_AAMODES_COUNT - 1, nVal); -#if defined(OPENGL_ES) - if ((nVal == static_cast(eAT_SMAA1TX)) || (nVal == static_cast(eAT_TAA))) - { - AZ_Warning("Rendering", false, "SMAA and TAA are not supported on this platform. Fallback to FXAA"); - nVal = eAT_FXAA; - } -#endif - -#if defined (CRY_USE_METAL) || defined (OPENGL_ES) - // We don't support switching to 128bpp after initialization of the gmem path. - if (CD3D9Renderer::EGmemPath::eGT_256bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && nVal == static_cast(eAT_TAA)) - { - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "TAA is not supported on 256bpp mode. Either switch to 128bpp or enable TAA at init so that the correct gmem mode is picked during initialization"); - nVal = eAT_FXAA; - } -#endif - - ICVar* pMSAA = gEnv->pConsole->GetCVar("r_MSAA"); - ICVar* pMSAASamples = gEnv->pConsole->GetCVar("r_MSAA_samples"); - AZ_Assert(pMSAA, "r_MSAA is not a valid cvar"); - AZ_Assert(pMSAASamples, "r_MSAA_samples is not a valid cvar"); - pMSAA->Set(0); - pMSAASamples->Set(0); - - pCVar->Set(nVal); - gRenDev->CV_r_AntialiasingMode = nVal; -} - -static const char* showRenderTargetHelp = - "Displays render targets - for debug purpose\n" - "[Usage]\n" - "r_ShowRenderTarget -l : list all available render targets\n" - "r_ShowRenderTarget -l hdr : list all available render targets whose name contain 'hdr'\n" - "r_ShowRenderTarget -nf zpass : show any render targets whose name contain 'zpass' with no filtering in 2x2(default) table\n" - "r_ShowRenderTarget -c:3 pass : show any render targets whose name contain 'pass' in 3x3 table\n" - "r_ShowRenderTarget z hdr : show any render targets whose name contain either 'z' or 'hdr'\n" - "r_ShowRenderTarget scene:rg scene:b : show any render targets whose name contain 'scene' first with red-green channels only and then with a blue channel only\n" - "r_ShowRenderTarget scenetarget:rgba:2 : show any render targets whose name contain 'scenetarget' with all channels multiplied by 2\n" - "r_ShowRenderTarget scene:b hdr:a : show any render targets whose name contain 'scene' with a blue channel only and ones whose name contain 'hdr' with an alpha channel only\n" - "r_ShowRenderTarget -e $ztarget : show a render target whose name exactly matches '$ztarget'\n" - "r_ShowRenderTarget -s scene : separately shows each channel of any 'scene' render targets\n" - "r_ShowRenderTarget -k scene : shows any 'scene' render targets with RGBK decoding\n" - "r_ShowRenderTarget -a scene : shows any 'scene' render targets with 101110/8888 aliasing"; - -void CRenderer::Cmd_ShowRenderTarget(IConsoleCmdArgs* pArgs) -{ - int argCount = pArgs->GetArgCount(); - - gRenDev->m_showRenderTargetInfo.Reset(); - - if (argCount <= 1) - { - string help = showRenderTargetHelp; - int curPos = 0; - string line = help.Tokenize("\n", curPos); - while (false == line.empty()) - { - gEnv->pLog->Log(line); - line = help.Tokenize("\n", curPos); - } - return; - } - - // Check for '-l'. - for (int i = 1; i < argCount; ++i) - { - if (strcmp(pArgs->GetArg(i), "-l") == 0) - { - gRenDev->m_showRenderTargetInfo.bShowList = true; - break; - } - } - - // Check for '-c:*'. - for (int i = 1; i < argCount; ++i) - { - if (strlen(pArgs->GetArg(i)) > 3 && strncmp(pArgs->GetArg(i), "-c:", 3) == 0) - { - gRenDev->m_showRenderTargetInfo.col = atoi(pArgs->GetArg(i) + 3); - if (gRenDev->m_showRenderTargetInfo.col <= 0) - { - gRenDev->m_showRenderTargetInfo.col = 2; - } - } - } - - // Now gather all render targets. - std::vector allRTs; - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - ResourcesMapItor it; - for (it = pRL->m_RMap.begin(); it != pRL->m_RMap.end(); ++it) - { - CTexture* tp = (CTexture*)it->second; - if (tp && !tp->IsNoTexture()) - { - if ((tp->GetFlags() & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) && tp->GetDevTexture()) - { - allRTs.push_back(tp); - } - } - } - - // Process actual arguments with possible '-nf', '-f', '-e' options. - bool bNoRegularArgs = true; - bool bFiltered = true; - bool bExactMatch = false; - bool bRGBKEncoded = false; - bool bAliased = false; - bool bWeightedChannels = false; - bool bSplitChannels = false; - - for (int i = 1; i < argCount; ++i) - { - const char* pCurArg = pArgs->GetArg(i); - - bool bColOption = strlen(pCurArg) > 3 && strncmp(pCurArg, "-c:", 3) == 0; - if (strcmp(pCurArg, "-l") == 0 || bColOption) - { - continue; - } - - if (strcmp(pCurArg, "-nf") == 0) - { - bFiltered = false; - } - else if (strcmp(pCurArg, "-f") == 0) - { - bFiltered = true; - } - else if (strcmp(pCurArg, "-e") == 0) - { - bExactMatch = true; - } - else if (strcmp(pCurArg, "-k") == 0) - { - bRGBKEncoded = true; - } - else if (strcmp(pCurArg, "-a") == 0) - { - bAliased = true; - } - else if (strcmp(pCurArg, "-s") == 0) - { - bSplitChannels = true; - } - else - { - bNoRegularArgs = false; - string argTxt = pCurArg, nameTxt, channelTxt, mulTxt; - argTxt.MakeLower(); - float multiplier = 1.0f; - size_t pos = argTxt.find(':'); - if (pos == string::npos) - { - nameTxt = argTxt; - channelTxt = "rgba"; - } - else - { - nameTxt = argTxt.substr(0, pos); - channelTxt = argTxt.substr(pos + 1, string::npos); - pos = channelTxt.find(':'); - if (pos != string::npos) - { - mulTxt = channelTxt.substr(pos + 1, string::npos); - multiplier = static_cast(atof(mulTxt.c_str())); - if (multiplier <= 0) - { - multiplier = 1.0f; - } - } - bWeightedChannels = true; - } - - Vec4 channelWeight(0, 0, 0, 0); - if (channelTxt.find('r') != string::npos) - { - channelWeight.x = 1.0f; - } - if (channelTxt.find('g') != string::npos) - { - channelWeight.y = 1.0f; - } - if (channelTxt.find('b') != string::npos) - { - channelWeight.z = 1.0f; - } - if (channelTxt.find('a') != string::npos) - { - channelWeight.w = 1.0f; - } - - channelWeight *= multiplier; - - for (size_t k = 0; k < allRTs.size(); ++k) - { - string texName = allRTs[k]->GetName(); - texName.MakeLower(); - bool bMatch = false; - if (bExactMatch) - { - bMatch = texName == nameTxt; - } - else - { - bMatch = texName.find(nameTxt.c_str()) != string::npos; - } - if (bMatch) - { - SShowRenderTargetInfo::RT rt; - rt.bFiltered = bFiltered; - rt.bRGBKEncoded = bRGBKEncoded; - rt.bAliased = bAliased; - rt.textureID = allRTs[k]->GetID(); - rt.channelWeight = channelWeight; - - if (bSplitChannels) - { - const Vec4 channels[4] = { Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), Vec4(0, 0, 0, 1) }; - - for (int j = 0; j < 4; ++j) - { - rt.channelWeight = bWeightedChannels ? channelWeight : Vec4(1, 1, 1, 1); - rt.channelWeight.x *= channels[j].x; - rt.channelWeight.y *= channels[j].y; - rt.channelWeight.z *= channels[j].z; - rt.channelWeight.w *= channels[j].w; - - if (rt.channelWeight[j] > 0.0f) - { - gRenDev->m_showRenderTargetInfo.rtList.push_back(rt); - } - } - } - else - { - gRenDev->m_showRenderTargetInfo.rtList.push_back(rt); - } - } - } - } - } - - if (bNoRegularArgs && gRenDev->m_showRenderTargetInfo.bShowList) // This means showing all items. - { - for (size_t k = 0; k < allRTs.size(); ++k) - { - SShowRenderTargetInfo::RT rt; - rt.bFiltered = true; // Doesn't matter, actually. - rt.textureID = allRTs[k]->GetID(); - gRenDev->m_showRenderTargetInfo.rtList.push_back(rt); - } - } -} - -static void cmd_OverscanBorders(IConsoleCmdArgs* pParams) -{ - int argCount = pParams->GetArgCount(); - - if (argCount > 1) - { - CRenderer::s_overscanBorders.x = clamp_tpl((float)atof(pParams->GetArg(1)), 0.0f, 25.0f) * 0.01f; - - if (argCount > 2) - { - CRenderer::s_overscanBorders.y = clamp_tpl((float)atof(pParams->GetArg(2)), 0.0f, 25.0f) * 0.01f; - } - else - { - CRenderer::s_overscanBorders.y = CRenderer::s_overscanBorders.x; - } - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, "Overscan Borders: Left/Right %G %% , Top/Bottom %G %%", - CRenderer::s_overscanBorders.x * 100.0f, CRenderer::s_overscanBorders.y * 100.0f); - } -} - -static void OnChange_r_OverscanBorderScale([[maybe_unused]] ICVar* pCVar) -{ - const float maxOverscanBorderScale = 0.5f; - CRenderer::s_overscanBorders.x = clamp_tpl(CRenderer::s_overscanBorders.x, 0.0f, maxOverscanBorderScale); - CRenderer::s_overscanBorders.y = clamp_tpl(CRenderer::s_overscanBorders.y, 0.0f, maxOverscanBorderScale); -} - -static void OnChange_CV_r_CubeDepthMapResolution(ICVar* /*pCVar*/) -{ -} - -static void OnChange_CV_r_SkipRenderComposites([[maybe_unused]] ICVar* pCVar) -{ - AZ_Warning("Rendering", pCVar->GetIVal() == 0 || (pCVar->GetIVal() == 1 && CRenderer::CV_r_flares == 0), "r_SkipRenderComposites was set to 1 while r_Flares was enabled, setting r_Flares to 0."); - CRenderer::CV_r_flares = 0; -} - -static void OnChange_CV_r_DebugLightLayers(ICVar* pCVar) -{ - int value = pCVar->GetIVal(); - - CRenderer::CV_r_DeferredShadingTiledDebugDirect = 0; - CRenderer::CV_r_DeferredShadingTiledDebugIndirect = 0; - CRenderer::CV_r_DeferredShadingTiledDebugAlbedo = 0; - CRenderer::CV_r_DeferredShadingTiledDebugAccumulation = 0; - - // Reset HDR to defaults - CRenderer::CV_r_HDRDebug = 0; - - ICVar* pFogVar = gEnv->pConsole->GetCVar("e_Fog"); - AZ_Assert(pFogVar, "Fog CVar is missing"); - pFogVar->Set(1); - - enum TiledDebugIndirect - { - TILED_DEBUG_INDIRECT_NONE = 3, - TILED_DEBUG_INDIRECT_DIFF = 2, - TILED_DEBUG_INDIRECT_DIFF_SPEC = 1 - }; - - enum TiledDebugAccum - { - TILED_DEBUG_ACCUM_DIFF = 1 - }; - - enum DebugLayer - { - DEBUG_LAYER_DIRECT_DIFFUSE = 1, - DEBUG_LAYER_INDIRECT_DIFFUSE, - DEBUG_LAYER_SPECULAR, - DEBUG_LAYER_AO, - DEBUG_LAYER_TEXTURES, - DEBUG_LAYER_FOG, - DEBUG_LAYER_HDR - }; - - if (value >= DEBUG_LAYER_DIRECT_DIFFUSE) - { - CRenderer::CV_r_DeferredShadingTiledDebugIndirect = TILED_DEBUG_INDIRECT_NONE; - CRenderer::CV_r_DeferredShadingTiledDebugAlbedo = 1; - CRenderer::CV_r_DeferredShadingTiledDebugAccumulation = TILED_DEBUG_ACCUM_DIFF; - - pFogVar->Set(0); - - CRenderer::CV_r_HDRDebug = 1; - CRenderer::CV_r_HDREyeAdaptationMode = 1; - } - if (value >= DEBUG_LAYER_INDIRECT_DIFFUSE) - { - CRenderer::CV_r_DeferredShadingTiledDebugIndirect = TILED_DEBUG_INDIRECT_DIFF; - } - if (value >= DEBUG_LAYER_SPECULAR) - { - CRenderer::CV_r_DeferredShadingTiledDebugIndirect = TILED_DEBUG_INDIRECT_DIFF_SPEC; - CRenderer::CV_r_DeferredShadingTiledDebugAccumulation = 0; - } - if (value >= DEBUG_LAYER_AO) - { - CRenderer::CV_r_DeferredShadingTiledDebugIndirect = 0; - } - if (value >= DEBUG_LAYER_TEXTURES) - { - CRenderer::CV_r_DeferredShadingTiledDebugAlbedo = 0; - } - if (value >= DEBUG_LAYER_FOG) - { - pFogVar->Set(1); - } - if (value >= DEBUG_LAYER_HDR) - { - CRenderer::CV_r_HDRDebug = 0; - } -} - -static void OnChange_CV_r_DeferredShadingTiled([[maybe_unused]] ICVar* pCVar) -{ -#if defined (AZ_PLATFORM_MAC) - // We don't support deferred shading tiled on macOS yet so always force the cvar to 0 - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "Deferred Shading Tiled is not supported on macOS"); - CRenderer::CV_r_DeferredShadingTiled = 0; -#elif defined(OPENGL) - // We don't support deferred shading tiled on any OpenGL targets yet so always force the cvar to 0 - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "Deferred Shading Tiled is not supported when using OpenGL"); - CRenderer::CV_r_DeferredShadingTiled = 0; -#endif -} - -static void OnChange_CV_r_Fur([[maybe_unused]] ICVar* pCVar) -{ - -#if defined (CRY_USE_METAL) || defined (OPENGL_ES) - // We don't support fur on gmem/pls path yet so always force the cvar to 0 - if (CD3D9Renderer::EGmemPath::eGT_REGULAR_PATH != gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "Fur is not supported on gmem/pls for mobile"); - CRenderer::CV_r_Fur = 0; - } -#endif -} - -static void OnChange_CV_r_SunShafts([[maybe_unused]] ICVar* pCVar) -{ -#if defined (AZ_PLATFORM_MAC) - // We don't support sunshaft settings greater than 1 on macOS yet so always force the cvar to 1 - AZ_Warning("Rendering", pCVar->GetIVal() > 1, "Sunshaft value settings above 1 are not supported on macOS"); - if (pCVar->GetIVal() >= 1) - { - CRenderer::CV_r_sunshafts = 1; - } - else - { - CRenderer::CV_r_sunshafts = 0; - } -#endif -} - -static void OnChange_CV_r_SSDO([[maybe_unused]] ICVar* pCVar) -{ - -#if defined (CRY_USE_METAL) || defined (OPENGL_ES) - // We don't support switching to 128bpp after initialization of the gmem path. - if (CD3D9Renderer::EGmemPath::eGT_256bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "SSDO is not supported on 256bpp mode. Either switch to 128bpp or enable r_ssdo at init so that the correct gmem mode is picked during initialization"); - CRenderer::CV_r_ssdo = 0; - } -#endif -} - -static void OnChange_CV_r_SSReflections([[maybe_unused]] ICVar* pCVar) -{ - -#if defined (CRY_USE_METAL) || defined (OPENGL_ES) - // We don't support switching to 128bpp after initialization of the gmem path. - if (CD3D9Renderer::EGmemPath::eGT_256bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "SSReflections are not supported on 256bpp mode. Either switch to 128bpp or enable r_SSReflections at init so that the correct gmem mode is picked during initialization"); - CRenderer::CV_r_SSReflections = 0; - } -#endif -} - -static void OnChange_CV_r_MotionBlur([[maybe_unused]] ICVar* pCVar) -{ - -#if defined (CRY_USE_METAL) || defined (OPENGL_ES) - // We don't support switching to 128bpp after initialization of the gmem path. - if (CD3D9Renderer::EGmemPath::eGT_256bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - AZ_Warning("Rendering", pCVar->GetIVal() == 0, "MotionBlur is not supported on 256bpp mode. Either switch to 128bpp or enable r_MotionBlur at init so that the correct gmem mode is picked during initialization"); - CRenderer::CV_r_MotionBlur = 0; - } -#endif -} - -static void OnChange_CV_r_TexelsPerMeter(ICVar* pCVar) -{ - if (pCVar && pCVar->GetFVal() == CRenderer::s_previousTexelsPerMeter) - { - CRenderer::CV_r_TexelsPerMeter = 0.0f; - } - - ICVar* pCV_e_sketch_mode = gEnv->pConsole->GetCVar("e_sketch_mode"); - if (pCV_e_sketch_mode) - { - pCV_e_sketch_mode->Set(CRenderer::CV_r_TexelsPerMeter > 0.0f ? 4 : 0); - } - CRenderer::s_previousTexelsPerMeter = CRenderer::CV_r_TexelsPerMeter; -} - -static void OnChange_CV_r_ShadersAllowCompiliation([[maybe_unused]] ICVar* pCVar) -{ - // disable async activation. Can be a problem though if some shader cache files were opened async/streamed - // before this. - CRenderer::CV_r_shadersasyncactivation = 0; - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Changing r_ShadersAllowCompilation at runtime can cause problems. Please set it in your system.cfg or user.cfg instead."); -} - -static void OnChange_CV_r_flares([[maybe_unused]] ICVar* pCVar) -{ - AZ_Warning("Rendering", pCVar->GetIVal() == 0 || (pCVar->GetIVal() == 1 && CRenderer::CV_r_SkipRenderComposites == 0), "r_SkipRenderComposites is set to 1, r_flares will have no effect."); -} - -static void OnChange_CV_r_FlaresTessellationRatio([[maybe_unused]] ICVar* pCVar) -{ - gEnv->pOpticsManager->Invalidate(); -} - -static void GetLogVBuffersStatic([[maybe_unused]] ICVar* pCVar) -{ - gRenDev->GetLogVBuffers(); -} - -static void OnChangeShadowJitteringCVar(ICVar* pCVar) -{ - gRenDev->SetShadowJittering(pCVar->GetFVal()); -} - -static void OnChange_CachedShadows([[maybe_unused]] ICVar* pCVar) -{ - CTexture::GenerateCachedShadowMaps(); - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->SetShadowsGSMCache(true); - gEnv->p3DEngine->SetRecomputeCachedShadows(ShadowMapFrustum::ShadowCacheData::eFullUpdate); - } -} - -void CRenderer::ChangeGeomInstancingThreshold([[maybe_unused]] ICVar* pVar) -{ - // get user value - m_iGeomInstancingThreshold = CV_r_geominstancingthreshold; - - // auto - if (m_iGeomInstancingThreshold < 0) - { - int nGPU = gRenDev->GetFeatures() & RFT_HW_MASK; - - if (nGPU == RFT_HW_ATI) - { - CRenderer::m_iGeomInstancingThreshold = 2; // seems to help in performance on all cards - } - else - if (nGPU == RFT_HW_NVIDIA) - { - CRenderer::m_iGeomInstancingThreshold = 8; // - } - else - { - CRenderer::m_iGeomInstancingThreshold = 7; // might be a good start - can be tweaked further - } - } - - iLog->Log(" Used GeomInstancingThreshold is %d", m_iGeomInstancingThreshold); -} - -RendererAssetListener::RendererAssetListener(IRenderer* renderer) - : m_renderer(renderer) -{ -} - -void RendererAssetListener::Connect() -{ - BusConnect(AZ_CRC("dds", 0x780234cb)); - BusConnect(AZ_CRC("cgf", 0x3bbd9566)); - BusConnect(AZ_CRC("cfx", 0xd8a99944)); - BusConnect(AZ_CRC("cfi", 0xb219b9b6)); -} - -void RendererAssetListener::Disconnect() -{ - BusDisconnect(); -} - -void RendererAssetListener::OnFileChanged(AZStd::string assetName) -{ - // Do not pass on resource updates until the engine is up and running - if (gEnv->pSystem && gEnv->p3DEngine) - { - m_renderer->EF_ReloadFile_Request(assetName.c_str()); - } -} - -CRenderer::CRenderer() - : m_assetListener(this) -{ - static_assert(LegacyInternal::JobExecutorPool::NumPools == AZ_ARRAY_SIZE(CRenderer::m_SkinningDataPool), "JobExecutorPool and Skinning data pool size mismatch"); - CCryNameR::CreateNameTable(); -} - -void CRenderer::InitRenderer() -{ - if (!gRenDev) - { - gRenDev = this; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - - m_cEF.m_Bin.m_pCEF = &m_cEF; - - m_bDualStereoSupport = false; - - m_bShaderCacheGen = false; - m_bSystemResourcesInit = 0; - - m_bSystemTargetsInit = 0; - m_bIsWindowActive = true; - - m_bShadowsEnabled = true; - m_bCloudShadowsEnabled = true; - -#if defined(VOLUMETRIC_FOG_SHADOWS) - m_bVolFogShadowsEnabled = false; - m_bVolFogCloudShadowsEnabled = false; -#endif - - m_nDisableTemporalEffects = 0; - - m_nPoolIndex = 0; - m_nPoolIndexRT = 0; - - m_ReqViewportScale = m_CurViewportScale = m_PrevViewportScale = Vec2(1, 1); - - m_UseGlobalMipBias = 0; - m_nCurMinAniso = 1; - m_nCurMaxAniso = 16; - m_wireframe_mode = R_SOLID_MODE; - m_wireframe_mode_prev = R_SOLID_MODE; - m_RP.m_StateOr = 0; - m_RP.m_StateAnd = -1; - - m_pSpriteVerts = NULL; - m_pSpriteInds = NULL; - - m_nativeWidth = 0; - m_nativeHeight = 0; - m_backbufferWidth = 0; - m_backbufferHeight = 0; - m_numSSAASamples = 1; - - m_screenShotType = 0; - - REGISTER_CVAR3("r_ApplyToonShading", CV_r_ApplyToonShading, 0, VF_NULL, - "Disable/Enable Toon Shading render mode\n" - " 0: Off\n" - " 1: Toon Shading on\n"); - - REGISTER_CVAR3("r_GraphicsPipeline", CV_r_GraphicsPipeline, 0, VF_NULL, - "Toggles new optimized graphics pipeline\n" - " 0: Off\n" - " 1: Just fullscreen passes\n" - " 2: Just scene passes\n" - " 3: All passes\n"); - - REGISTER_CVAR3_CB("r_DebugLightLayers", CV_r_DebugLightLayers, 0, VF_DUMPTODISK, - "1 - Direct lighting, diffuse only.\n" - "2 - Add environment ambient lighting, diffuse only.\n" - "3 - Add specular term.\n" - "4 - Add AO.\n" - "5 - Add textures.\n" - "6 - Add fog.\n" - "7 - Add tone mapping / bloom / color grading.\n", - OnChange_CV_r_DebugLightLayers); - - REGISTER_CVAR3_CB("r_DeferredShadingTiled", CV_r_DeferredShadingTiled, 0, VF_DUMPTODISK, - "Toggles tiled shading using a compute shader\n" - "1 - Tiled forward shading for transparent objects\n" - "2 - Tiled deferred and forward shading\n" - "3 - Tiled deferred and forward shading with debug info\n" - "4 - Light coverage visualization\n", - OnChange_CV_r_DeferredShadingTiled); - - REGISTER_CVAR3("r_DeferredShadingTiledHairQuality", CV_r_DeferredShadingTiledHairQuality, 2, VF_DUMPTODISK, - "Tiled shading hair quality\n" - "0 - Regular forward shading\n" - "1 - Tiled shading on selected assets and more accurate probe blending\n" - "2 - Full tiled shading with high quality shadow filter\n"); - - REGISTER_CVAR3("r_DeferredShadingTiledDebugDirect", CV_r_DeferredShadingTiledDebugDirect, 0, VF_DUMPTODISK, - "1 - Disables translucent BRDF.\n" - "2 - Disables all direct lighting.\n"); - - REGISTER_CVAR3("r_DeferredShadingTiledDebugIndirect", CV_r_DeferredShadingTiledDebugIndirect, 0, VF_DUMPTODISK, - "Incrementally disables stages of the indirect lighting pipeline.\n" - "3 - Disables Ambient Diffuse\n" - "2 - Disables Ambient Specular\n" - "1 - Disables AO and SSR\n"); - - REGISTER_CVAR3("r_DeferredShadingTiledDebugAccumulation", CV_r_DeferredShadingTiledDebugAccumulation, 0, VF_DUMPTODISK, - "Toggles layered debug visualization of deferred lighting contributions\n" - "1 - Show Only Accumulated Diffuse\n" - "2 - Show Only Accumulated Specular\n"); - - REGISTER_CVAR3("r_DeferredShadingTiledDebugAlbedo", CV_r_DeferredShadingTiledDebugAlbedo, 0, VF_DUMPTODISK, - "Toggles layered debug visualization of deferred lighting contributions\n" - "1 - Force white albedo value\n"); - - REGISTER_CVAR3("r_DeferredShadingSSS", CV_r_DeferredShadingSSS, DEF_SHAD_SSS_DEFAULT_VAL, VF_DUMPTODISK, - "Toggles deferred subsurface scattering (requires full deferred shading)"); - - REGISTER_CVAR3("r_DeferredShadingFilterGBuffer", CV_r_DeferredShadingFilterGBuffer, 0, VF_DUMPTODISK, - "Enables filtering of GBuffer to reduce specular aliasing.\n"); - - DefineConstIntCVar3("r_DeferredShadingLightVolumes", CV_r_deferredshadingLightVolumes, 1, VF_DUMPTODISK, - "Toggles Light volumes for deferred shading.\n" - "Usage: r_DeferredShadingLightVolumes [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredDecals", CV_r_deferredDecals, 1, VF_DUMPTODISK, - "Toggles deferred decals.\n" - "Usage: r_DeferredDecals [0/1]\n" - "Default is 1 (enabled), 0 Disabled. "); - - DefineConstIntCVar3("r_deferredDecalsDebug", CV_r_deferredDecalsDebug, 0, VF_DUMPTODISK, - "Display decals debug info.\n" - "Usage: r_deferredDecalsDebug [0/1]"); - - DefineConstIntCVar3("r_deferredDecalsOnDynamicObjects", CV_r_deferredDecalsOnDynamicObjects, 0, VF_DUMPTODISK, - "Render deferred decals on dynamic objects.\n" - "Usage: r_deferredDecalsOnDynamicObjects [0/1]"); - - DefineConstIntCVar3("r_DeferredShadingEnvProbes", CV_r_DeferredShadingEnvProbes, 1, VF_DUMPTODISK, - "Toggles deferred environment probes rendering.\n" - "Usage: r_DeferredShadingEnvProbes [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingStencilPrepass", CV_r_DeferredShadingStencilPrepass, 1, VF_DUMPTODISK, - "Toggles deferred shading stencil pre pass.\n" - "Usage: r_DeferredShadingStencilPrepass [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingScissor", CV_r_DeferredShadingScissor, 1, VF_DUMPTODISK, - "Toggles deferred shading scissor test.\n" - "Usage: r_DeferredShadingScissor [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingLBuffersFmt", CV_r_DeferredShadingLBuffersFmt, 1, VF_NULL, - "Toggles light buffers format.\n" - "Usage: r_DeferredShadingLBuffersFmt [0/1/2] \n" - "Default is 1 (R11G11B10F), 0: R16G16B16A16F 2: Use optimized format for gmem : diffuseAcc 8 (R8) bits instead of 64 and SpeculaAcc 32 bits (R10G10B10A2) instead of 64."); - - - DefineConstIntCVar3("r_DeferredShadingDepthBoundsTest", CV_r_DeferredShadingDepthBoundsTest, DEF_SHAD_DBT_DEFAULT_VAL, - VF_DUMPTODISK, - "Toggles deferred shading depth bounds test.\n" - "Usage: r_DeferredShadingDepthBoundsTest [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingDBTstencil", CV_r_deferredshadingDBTstencil, DEF_SHAD_DBT_STENCIL_DEFAULT_VAL, - VF_DUMPTODISK, - "Toggles deferred shading combined depth bounds test + stencil test.\n" - "Usage: r_DeferredShadingDBTstencil [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingDebug", CV_r_DeferredShadingDebug, 0, VF_DUMPTODISK, - "Toggles deferred shading debug.\n" - "Usage: r_DeferredShadingDebug [0/1]\n" - " 0 disabled (Default)\n" - " 1: Visualize g-buffer and l-buffers\n" - " 2: Debug deferred lighting fillrate (brighter colors means more expensive)\n"); - - DefineConstIntCVar3("r_DebugGBuffer", CV_r_DeferredShadingDebugGBuffer, 0, VF_DEV_ONLY, - "Debug view for gbuffer attributes\n" - " 0 - Disabled\n" - " 1 - Normals\n" - " 2 - Smoothness\n" - " 3 - Reflectance\n" - " 4 - Albedo\n" - " 5 - Lighting model\n" - " 6 - Translucency\n" - " 7 - Sun self-shadowing\n" - " 8 - Subsurface scattering\n" - " 9 - Specular validation overlay\n" - ); - - DefineConstIntCVar3("r_DeferredShadingLights", CV_r_DeferredShadingLights, 1, VF_DUMPTODISK, - "Enables/Disables lights processing.\n" - "Usage: r_DeferredShadingLights [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingAmbientLights", CV_r_DeferredShadingAmbientLights, 1, VF_DUMPTODISK, - "Enables/Disables ambient lights.\n" - "Usage: r_DeferredShadingAmbientLights [0/1]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_DeferredShadingAreaLights", CV_r_DeferredShadingAreaLights, 1, VF_DUMPTODISK, - "Enables/Disables more complex area lights processing.\n" - "Usage: r_DeferredShadingAreaLights [0/1]\n" - "Default is 0 (disabled)"); - - DefineConstIntCVar3("r_DeferredShadingAmbient", CV_r_DeferredShadingAmbient, 1, VF_DUMPTODISK, - "Enables/Disables ambient processing.\n" - "Usage: r_DeferredShadingAmbient [0/1/2]\n" - " 0: no ambient passes (disabled)\n" - " 1: vis areas and outdoor ambient (default)\n" - " 2: only outdoor (debug vis areas mode)\n"); - - REGISTER_CVAR3("r_DeferredShadingLightLodRatio", CV_r_DeferredShadingLightLodRatio, 1.0f, VF_DUMPTODISK, - "Sets deferred shading light intensity threshold.\n" - "Usage: r_DeferredShadingLightLodRatio [value]\n" - "Default is 0.1"); - - REGISTER_CVAR3("r_DeferredShadingLightStencilRatio", CV_r_DeferredShadingLightStencilRatio, 0.21f, VF_DUMPTODISK, - "Sets screen ratio for deferred lights to use stencil (eg: 0.2 - 20% of screen).\n" - "Usage: r_DeferredShadingLightStencilRatio [value]\n" - "Default is 0.2"); - - - REGISTER_CVAR3("r_DeferredShadingSortLights", CV_r_DeferredShadingSortLights, 0, VF_CHEAT, - "Sorts deferred lights\n" - "Usage: r_DeferredShadingSortLights [0/1/2/3]\n" - " 0: no sorting\n" - " 1: sort by screen space influence area\n" - " 2: lights that are already in the shadowmap pool are processed first\n" - " 3: first sort by presence in the shadowmap pool and then by screen space influence area\n" - "Default is 0 (off)"); - - REGISTER_CVAR3("r_DeferredShadingAmbientSClear", CV_r_DeferredShadingAmbientSClear, 1, VF_NULL, - "Clear stencil buffer after ambient pass (prevents artifacts on Nvidia hw)\n"); - - ICVar* hdrDebug = REGISTER_CVAR3("r_HDRDebug", CV_r_HDRDebug, 0, VF_NULL, - "Toggles HDR debugging info (to debug HDR/eye adaptation)\n" - "Usage: r_HDRDebug\n" - "0 off (default)\n" - "1 show gamma-corrected scene target without HDR processing\n" - "2 identify illegal colors (grey=normal, red=NotANumber, green=negative)\n" - "3 display internal HDR textures\n" - "4 display HDR range adaptation\n" - "5 debug merged posts composition mask\n"); - if (hdrDebug) - { - hdrDebug->SetLimits(0.0f, 5.0f); - } - - REGISTER_CVAR3("r_ToneMapTechnique", CV_r_ToneMapTechnique, 0, VF_NULL, - "Toggles Tonemapping technique\n" - "Usage: r_ToneMapTechnique\n" - "0 Uncharted 2 Filmic curve by J Hable (default)\n" - "1 Linear operator\n" - "2 Exponential operator\n" - "3 Reinhard operator\n" - "4 Cheap ALU based filmic curve from John Hable\n"); - - REGISTER_CVAR3("r_ColorSpace", CV_r_ColorSpace, 0, VF_NULL, - "Toggles Color Space conversion\n" - "Usage: r_ColorSpace\n" - "0 sRGB0 - Most accurate (default)\n" - "1 sRGB1 - Cheap approximation\n" - "2 sRGB2 - Cheapest approximation\n"); - - REGISTER_CVAR3("r_ToneMapManualExposureValue", CV_r_ToneMapManualExposureValue, 1, VF_NULL, - "Set the manual exposure value for cheaper tonemap techniques\n" - "Usage: r_ToneMapManualExposureValue\n" - "Default is 1.0\n"); - - REGISTER_CVAR3("r_ToneMapExposureType", CV_r_ToneMapExposureType, 0, VF_NULL, - "Set the type of exposure to be used by tonemap operators\n" - "Usage: r_ToneMapExposureType\n" - "Default is 0\n" - "0 Auto exposure\n" - "1 Manual exposure\n"); - - REGISTER_CVAR3("r_HDRBloom", CV_r_HDRBloom, 1, VF_NULL, - "Enables bloom/glare.\n" - "Usage: r_HDRBloom [0/1]\n"); - - REGISTER_CVAR3("r_HDRBloomQuality", CV_r_HDRBloomQuality, 2, VF_NULL, - "Set bloom quality (0: low, 1: medium, 2: high)\n"); - - DefineConstIntCVar3("r_HDRVignetting", CV_r_HDRVignetting, 1, VF_DUMPTODISK, - "HDR viggneting\n" - "Usage: r_HDRVignetting [Value]\n" - "Default is 1 (enabled)"); - - DefineConstIntCVar3("r_HDRTexFormat", CV_r_HDRTexFormat, 0, VF_DUMPTODISK, - "HDR texture format. \n" - "Usage: r_HDRTexFormat [Value] 0:(low precision - cheaper/faster), 1:(high precision)\n" - "Default is 0"); - - // Dolby Parameters - REGISTER_CVAR3("r_HDRDolbyDynamicMetadata", CV_r_HDRDolbyDynamicMetadata, 1, VF_DUMPTODISK, "Enable Dolby Dynamic Metadata (provides Dolby Vision screen with min/max/mid of the current image, in order to improve image quality)"); - REGISTER_CVAR3("r_HDRDolbyScurve", CV_r_HDRDolbyScurve, 1, VF_DUMPTODISK, "Enable Dolby S-Curve (transformation from source intensity range to cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveSourceMin", CV_r_HDRDolbyScurveSourceMin, 0.001f, VF_DUMPTODISK, "Set Dolby S-Curve Source minimum intensity (in source units)."); - REGISTER_CVAR3("r_HDRDolbyScurveSourceMid", CV_r_HDRDolbyScurveSourceMid, 0.4f, VF_DUMPTODISK, "Set Dolby S-Curve Source midpoint intensity (in source units)."); - REGISTER_CVAR3("r_HDRDolbyScurveSourceMax", CV_r_HDRDolbyScurveSourceMax, 10000.0f, VF_DUMPTODISK, "Set Dolby S-Curve Source maximum intensity (in source units)."); - REGISTER_CVAR3("r_HDRDolbyScurveSlope", CV_r_HDRDolbyScurveSlope, 1.0f, VF_DUMPTODISK, "Set Dolby S-Curve Slope (similar to gamma)."); - REGISTER_CVAR3("r_HDRDolbyScurveScale", CV_r_HDRDolbyScurveScale, 1.0f, VF_DUMPTODISK, "Set Dolby S-Curve Multiplier (similar to brightness)."); - REGISTER_CVAR3("r_HDRDolbyScurveRGBPQTargetMin", CV_r_HDRDolbyScurveRGBPQTargetMin, 0.001f, VF_DUMPTODISK, "Set Dolby S-Curve RGBPQ (e.g. Maui) Target minimum intensity (in cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveRGBPQTargetMid", CV_r_HDRDolbyScurveRGBPQTargetMid, 50.0f, VF_DUMPTODISK, "Set Dolby S-Curve RGBPQ (e.g. Maui) Target midpoint intensity (in cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveRGBPQTargetMax", CV_r_HDRDolbyScurveRGBPQTargetMax, 2000.0f, VF_DUMPTODISK, "Set Dolby S-Curve RGBPQ (e.g. Maui) Target midpoint (average) intensity (in cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveVisionTargetMin", CV_r_HDRDolbyScurveVisionTargetMin, 0.001f, VF_DUMPTODISK, "Set Dolby S-Curve Vision (e.g. Vizio) Target minimum intensity (in cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveVisionTargetMid", CV_r_HDRDolbyScurveVisionTargetMid, 50.0f, VF_DUMPTODISK, "Set Dolby S-Curve Vision (e.g. Vizio) Target midpoint intensity (in cd/m^2)."); - REGISTER_CVAR3("r_HDRDolbyScurveVisionTargetMax", CV_r_HDRDolbyScurveVisionTargetMax, 800.0f, VF_DUMPTODISK, "Set Dolby S-Curve Vision (e.g. Vizio) Target maximum intensity (in cd/m^2)."); - - // Eye Adaptation - REGISTER_CVAR3("r_HDREyeAdaptationSpeed", CV_r_HDREyeAdaptationSpeed, 1.0f, VF_NULL, - "HDR rendering eye adaptation speed\n" - "Usage: r_EyeAdaptationSpeed [Value]"); - - REGISTER_CVAR3("r_HDREyeAdaptationMode", CV_r_HDREyeAdaptationMode, 2, VF_DUMPTODISK, - "Set the eye adaptation (auto exposure) mode.\n" - " 1: Standard auto exposure (using EV values)\n" - " 2: Legacy auto exposure for backwards compatibility (CE 3.6 to 3.8.1)"); - - REGISTER_CVAR3("r_HDRGrainAmount", CV_r_HDRGrainAmount, 0.0f, VF_NULL, - "HDR camera grain amount\n" - "Usage: r_HDRGrainAmount [Value]"); - - REGISTER_CVAR3("r_ChromaticAberration", CV_r_ChromaticAberration, 0.0f, VF_NULL, - "Chromatic aberration amount\n" - "Usage: r_ChromaticAberration [Value]"); - - REGISTER_CVAR3("r_Sharpening", CV_r_Sharpening, 0.0f, VF_NULL, - "Image sharpening amount\n" - "Usage: r_Sharpening [Value]"); - - REGISTER_CVAR3("r_Beams", CV_r_beams, 1, VF_NULL, - "Toggles volumetric light beams.\n" - "Usage: r_Beams [0/1]\n"); - - REGISTER_CVAR3_CB("r_GeomInstancingThreshold", CV_r_geominstancingthreshold, -1, VF_NULL, - "If the instance count gets bigger than the specified value the instancing feature is used.\n" - "Usage: r_GeomInstancingThreshold [Num]\n" - "Default is -1 (automatic depending on hardware, used value can be found in the log)", - ChangeGeomInstancingThreshold); - - REGISTER_CVAR3("r_BatchType", CV_r_batchtype, 0, VF_NULL, - "0 - CPU friendly.\n" - "1 - GPU friendly.\n" - "2 - Automatic.\n"); - -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) || defined(USE_SILHOUETTEPOM_CVAR) - REGISTER_CVAR3("r_SilhouettePOM", CV_r_SilhouettePOM, 0, VF_NULL, - "Enables use of silhouette parallax occlusion mapping.\n" - "Usage: r_SilhouettePOM [0/1]"); -#endif -#ifdef WATER_TESSELLATION_RENDERER - REGISTER_CVAR3("r_WaterTessellationHW", CV_r_WaterTessellationHW, 0, VF_NULL, - "Enables hw water tessellation.\n" - "Usage: r_WaterTessellationHW [0/1]"); -#endif - - REGISTER_CVAR3("r_TessellationDebug", CV_r_tessellationdebug, 0, VF_NULL, - "1 - Factor visualizing.\n" - "Default is 0"); - REGISTER_CVAR3("r_TessellationTriangleSize", CV_r_tessellationtrianglesize, 8.0f, VF_NULL, - "Desired triangle size for screen-space tessellation.\n" - "Default is 10."); - REGISTER_CVAR3("r_UseDisplacementFactor", CV_r_displacementfactor, 0.2f, VF_NULL, - "Global displacement amount.\n" - "Default is 0.4f."); - - DefineConstIntCVar3("r_GeomInstancing", CV_r_geominstancing, GEOM_INSTANCING_DEFAULT_VAL, VF_NULL, - "Toggles HW geometry instancing.\n" - "Usage: r_GeomInstancing [0/1]\n" - "Default is 1 (on). Set to 0 to disable geom. instancing."); - - DefineConstIntCVar3("r_GeomInstancingDebug", CV_r_geominstancingdebug, 0, VF_NULL, - "Toggles HW geometry instancing debug display.\n" - "Usage: r_GeomInstancingDebug [0/1/2]\n" - "Default is 0 (off). Set to 1 to add GPU markers around instanced objects. 2 will visually highlight them as well."); - - DefineConstIntCVar3("r_MaterialsBatching", CV_r_materialsbatching, 1, VF_NULL, - "Toggles materials batching.\n" - "Usage: r_MaterialsBatching [0/1]\n" - "Default is 1 (on). Set to 0 to disable."); - - DefineConstIntCVar3("r_ImpostersDraw", CV_r_impostersdraw, 1, VF_NULL, - "Toggles imposters drawing.\n" - "Usage: r_ImpostersDraw [0/1]\n" - "Default is 1 (on). Set to 0 to disable imposters."); - REGISTER_CVAR3("r_ImposterRatio", CV_r_imposterratio, 1, VF_NULL, - "Allows to scale the texture resolution of imposters (clouds)\n" - "Usage: r_ImposterRatio [1..]\n" - "Default is 1 (1:1 normal). Bigger values can help to save texture space\n" - "(e.g. value 2 results in 1/4 texture memory usage)"); - REGISTER_CVAR3("r_ImpostersUpdatePerFrame", CV_r_impostersupdateperframe, 6000, VF_NULL, - "How many kilobytes to update per-frame.\n" - "Usage: r_ImpostersUpdatePerFrame [1000-30000]\n" - "Default is 6000 (6 megabytes)"); - - DefineConstIntCVar3("r_ZPassDepthSorting", CV_r_ZPassDepthSorting, ZPASS_DEPTH_SORT_DEFAULT_VAL, VF_NULL, - "Toggles Z pass depth sorting.\n" - "Usage: r_ZPassDepthSorting [0/1/2]\n" - "0: No depth sorting\n" - "1: Sort by depth layers (default)\n" - "2: Sort by distance\n"); - - REGISTER_CVAR3("r_ZPrepassMaxDist", CV_r_ZPrepassMaxDist, 16.0f, VF_NULL, - "Set ZPrepass max dist.\n" - "Usage: r_ZPrepassMaxDist (16.0f default) [distance in meters]\n"); - - REGISTER_CVAR3("r_UseZPass", CV_r_usezpass, 2, VF_RENDERER_CVAR, - "Toggles g-buffer pass.\n" - "Usage: r_UseZPass [0/1/2]\n" - "0: Disable Z-pass (not recommended, this disables any g-buffer rendering)\n" - "1: Enable Z-pass (g-buffer only)\n" - "2: Enable Z-pass (g-buffer and additional Z-prepass)"); - - DefineConstIntCVar3("r_TransparentPasses", CV_r_TransparentPasses, 1, VF_NULL, - "Toggles rendering of transparent/alpha blended objects.\n"); - - DefineConstIntCVar3("r_TranspDepthFixup", CV_r_TranspDepthFixup, 1, VF_NULL, - "Write approximate depth for certain transparent objects before post effects\n" - "Usage: r_TranspDepthFixup [0/1]\n" - "Default is 1 (enabled)\n"); - - DefineConstIntCVar3("r_SoftAlphaTest", CV_r_SoftAlphaTest, 1, VF_NULL, - "Toggles post processed soft alpha test for shaders supporting this\n" - "Usage: r_SoftAlphaTest [0/1]\n" - "Default is 1 (enabled)\n"); - - DefineConstIntCVar3("r_UseHWSkinning", CV_r_usehwskinning, 1, VF_NULL, - "Toggles HW skinning.\n" - "Usage: r_UseHWSkinning [0/1]\n" - "Default is 1 (on). Set to 0 to disable HW-skinning."); - DefineConstIntCVar3("r_UseMaterialLayers", CV_r_usemateriallayers, 2, VF_NULL, - "Enables material layers rendering.\n" - "Usage: r_UseMaterialLayers [0/1/2]\n" - "Default is 2 (optimized). Set to 1 for enabling but with optimization disabled (for debug)."); - - DefineConstIntCVar3("r_ParticlesSoftIsec", CV_r_ParticlesSoftIsec, 1, VF_NULL, - "Enables particles soft intersections.\n" - "Usage: r_ParticlesSoftIsec [0/1]"); - - DefineConstIntCVar3("r_ParticlesRefraction", CV_r_ParticlesRefraction, 1, VF_NULL, - "Enables refractive particles.\n" - "Usage: r_ParticlesRefraction [0/1]"); - - REGISTER_CVAR3("r_ParticlesHalfRes", CV_r_ParticlesHalfRes, 0, VF_NULL, - "Enables (1) or forces (2) rendering of particles in a half-resolution buffer.\n" - "Usage: r_ParticlesHalfRes [0/1/2]"); - - DefineConstIntCVar3("r_ParticlesHalfResBlendMode", CV_r_ParticlesHalfResBlendMode, 0, VF_NULL, - "Specifies which particles can be rendered in half resolution.\n" - "Usage: r_ParticlesHalfResBlendMode [0=alpha / 1=additive]"); - - DefineConstIntCVar3("r_ParticlesHalfResAmount", CV_r_ParticlesHalfResAmount, 0, VF_NULL, - "Sets particle half-res buffer to half (0) or quarter (1) screen size.\n" - "Usage: r_ParticlesHalfResForce [0/1]"); - - DefineConstIntCVar3("r_ParticlesInstanceVertices", CV_r_ParticlesInstanceVertices, 1, VF_NULL, - "Enable instanced-vertex rendering.\n" - "Usage: r_ParticlesInstanceVertices [0/1]"); - - REGISTER_CVAR3("r_ParticlesAmountGI", CV_r_ParticlesAmountGI, 0.15f, VF_NULL, - "Global illumination amount for particles without material.\n" - "Usage: r_ParticlesAmountGI [n]"); - - REGISTER_CVAR3("r_MSAA", CV_r_msaa, 0, VF_NULL, - "Enables hw multisampling antialiasing.\n" - "Usage: r_MSAA [0/1]\n" - "Default: 0 (off).\n" - "1: enabled + default reference quality mode\n"); - REGISTER_CVAR3("r_MSAA_samples", CV_r_msaa_samples, 0, VF_NULL, - "Number of subsamples used when hw multisampled antialiasing is enabled.\n" - "Usage: r_MSAA_samples N (where N is a number >= 0). Attention, N must be supported by given video hardware!\n" - "Default: 0. Please note that various hardware implements special MSAA modes via certain combinations of\n" - "r_MSAA_quality and r_MSAA_samples."); - REGISTER_CVAR3("r_MSAA_quality", CV_r_msaa_quality, 0, VF_NULL, - "Quality level used when multisampled antialiasing is enabled.\n" - "Usage: r_MSAA_quality N (where N is a number >= 0). Attention, N must be supported by given video hardware!\n" - "Default: 0. Please note that various hardware implements special MSAA modes via certain combinations of\n" - "r_MSAA_quality and r_MSAA_samples."); - REGISTER_CVAR3("r_MSAA_debug", CV_r_msaa_debug, 0, VF_NULL, - "Enable debugging mode for msaa.\n" - "Usage: r_MSAA_debug N (where N is debug mode > 0)\n" - "Default: 0. disabled. Note debug modes share target with post processing, disable post processing for correct visualization. \n" - "1 disable sample frequency pass\n" - "2 visualize sample frequency mask\n"); - - // This values seem a good performance/quality balance for a Crysis style level (note that they might need re-adjust for different projects) - REGISTER_CVAR3("r_MSAA_threshold_depth", CV_r_msaa_threshold_depth, 0.1f, VF_NULL, - "Set depth threshold to be used for custom resolve sub-samples masking\n"); - REGISTER_CVAR3("r_MSAA_threshold_normal", CV_r_msaa_threshold_normal, 0.9f, VF_NULL, - "Set normals threshold to be used for custom resolve sub-samples masking\n"); - - REGISTER_CVAR3("r_UseSpecularAntialiasing", CV_r_SpecularAntialiasing, 1, VF_NULL, - "Enable specular antialiasing.\n" - "Usage: r_UseSpecularAntialiasing [0/1]"); - - static string aaModesDesc = "Enables post process based anti-aliasing modes.\nUsage: r_AntialiasingMode [n]\n"; - - for (int i = 0; i < eAT_AAMODES_COUNT; ++i) - { - string mode; - mode.Format("%d: %s\n", i, s_pszAAModes[i]); - aaModesDesc.append(mode); - } - - REGISTER_CVAR3_CB("r_AntialiasingMode", CV_r_AntialiasingMode_CB, eAT_DEFAULT_AA, VF_NULL, aaModesDesc.c_str(), OnChange_CV_r_AntialiasingMode); - CV_r_AntialiasingMode = CV_r_AntialiasingMode_CB; - - REGISTER_CVAR3("r_AntialiasingNonTAASharpening", CV_r_AntialiasingNonTAASharpening, 0.f, VF_NULL, - "Enables non-TAA sharpening.\n"); - - REGISTER_CVAR3("r_AntialiasingTAAJitterPattern", CV_r_AntialiasingTAAJitterPattern, 7, VF_NULL, - "Selects TAA sampling pattern.\n" - " 0: no subsamples\n 1: 2x\n 2: 3x\n 3: 4x\n 4: 8x\n 5: sparse grid 8x8\n 6: random\n 7: Halton 8x\n 8: Halton random"); - - DefineConstIntCVar3("r_AntialiasingTAAUseJitterMipBias", CV_r_AntialiasingTAAUseJitterMipBias, 1, VF_NULL, - "Allows mip map biasing on textures when jitter is enabled\n"); - - DefineConstIntCVar3("r_AntialiasingTAAUseVarianceClamping", CV_r_AntialiasingTAAUseVarianceClamping, 0, VF_NULL, - "Allows variance-based color clipping. Decreases ghosting but may increase flickering artifacts.\n"); - - DefineConstIntCVar3("r_AntialiasingModeDebug", CV_r_AntialiasingModeDebug, 0, VF_NULL, - "Enables AA debugging views\n" - "Usage: r_AntialiasingModeDebug [n]" - "1: Display edge detection" - "2: Zoom image 2x" - "3: Zoom image 2x + display edge detection" - "4: Zoom image 4x, etc"); - - DefineConstIntCVar3("r_AntialiasingTAAUseAntiFlickerFilter", CV_r_AntialiasingTAAUseAntiFlickerFilter, 1, VF_NULL, - "Enables TAA anti-flicker filtering.\n"); - - REGISTER_CVAR3("r_AntialiasingTAAClampingFactor", CV_r_AntialiasingTAAClampingFactor, 1.25f, VF_NULL, - "Controls the history clamping factor for TAA. Higher values will cause more ghosting but less flickering. Acceptable values between 0.75 and 2.0\n"); - - REGISTER_CVAR3("r_AntialiasingTAANewFrameWeight", CV_r_AntialiasingTAANewFrameWeight, 0.05f, VF_NULL, - "The weight controlling how much of the current frame is used when integrating with the exponential history buffer.\n"); - - REGISTER_CVAR3("r_AntialiasingTAASharpening", CV_r_AntialiasingTAASharpening, 0.1f, VF_NULL, - "Enables TAA sharpening.\n"); - - DefineConstIntCVar3("CV_r_AntialiasingModeEditor", CV_r_AntialiasingModeEditor, 1, VF_NULL, - "Sets antialiasing modes to editing mode (disables jitter on modes using camera jitter which can cause flickering of helper objects)\n" - "Usage: CV_r_AntialiasingModeEditor [0/1]"); - - DefineConstIntCVar3("r_MotionVectors", CV_r_MotionVectors, 1, VF_NULL, - "Enables generation of motion vectors for dynamic objects\n"); - - DefineConstIntCVar3("r_MotionVectorsTransparency", CV_r_MotionVectorsTransparency, 1, VF_NULL, - "Enables generation of motion vectors for transparent objects\n"); - - REGISTER_CVAR3("r_MotionVectorsTransparencyAlphaThreshold", CV_r_MotionVectorsTransparencyAlphaThreshold, 0.25f, VF_NULL, - "Transparent object alpha threshold. If the alpha is above this threshold the object will generate motion vectors.\n" - "Usage: r_MotionVectorsTransparencyAlphaThreshold (val)\n" - "Default is 0.25. 0 - disabled\n"); - - DefineConstIntCVar3("r_MotionVectorsDebug", CV_r_MotionVectorsDebug, 0, VF_NULL, - "Enables motion vector debug visualization.\n"); - - REGISTER_CVAR3_CB("r_MotionBlur", CV_r_MotionBlur, 2, VF_NULL, - "Enables per object and camera motion blur.\n" - "Usage: r_MotionBlur [0/1/2/3]\n" - "Default is 1 (camera motion blur on).\n" - "1: camera motion blur\n" - "2: camera and object motion blur\n" - "3: debug mode\n", OnChange_CV_r_MotionBlur); - - REGISTER_CVAR3("r_RenderMotionBlurAfterHDR", CV_r_RenderMotionBlurAfterHDR, 0, VF_NULL, - "Forces Motion Blur To Render After HDR processing.\n" - "Usage: r_MotionBlur [0/1]\n" - "Default is 0 (Motion Blur Before HDR).\n" - "0: Motion Blur Applied Before HDR Processing (Luminance Measurement, Bloom, Tonemapping)\n" - "1: Motion Blur Applied After HDR Processing (Luminance Measurement, Bloom, Tonemapping)\n"); - - REGISTER_CVAR3("r_MotionBlurScreenShot", CV_r_MotionBlurScreenShot, 0, VF_NULL, - "Enables motion blur during high res screen captures" - "Usage: r_MotionBlur [0/1]\n" - "0: motion blur disabled for screen shot (default)\n" - "1: motion blur enabled for screen shot\n"); - - REGISTER_CVAR3("r_MotionBlurQuality", CV_r_MotionBlurQuality, 1, VF_NULL, - "Set motion blur sample count.\n" - "Usage: r_MotionBlurQuality [0/1]\n" - "0 - low quality, 1 - medium quality, 2 - high quality\n"); - - REGISTER_CVAR3("r_MotionBlurGBufferVelocity", CV_r_MotionBlurGBufferVelocity, 1, VF_NULL, - "Pack velocity output in g-buffer.\n" - "Usage: r_MotionBlurGBufferVelocity [0/1]\n" - "Default is 1 (enabled). 0 - disabled\n"); - - REGISTER_CVAR3("r_MotionBlurThreshold", CV_r_MotionBlurThreshold, 0.0001f, VF_NULL, - "Object motion blur velocity threshold.\n" - "Usage: r_MotionBlurThreshold (val)\n" - "Default is 0.0001. 0 - disabled\n"); - - REGISTER_CVAR3("r_MotionBlurShutterSpeed", CV_r_MotionBlurShutterSpeed, 250.0f, 0, - "Sets camera exposure time for motion blur as 1/x seconds.\n" - "Default: 250 (1/250 of a second)"); - - REGISTER_CVAR3("r_MotionBlurCameraMotionScale", CV_r_MotionBlurCameraMotionScale, 0.2f, 0, - "Reduces motion blur for camera movements to account for a fixed focus point of the viewer.\n" - "Default: 0.2"); - - REGISTER_CVAR3("r_MotionBlurMaxViewDist", CV_r_MotionBlurMaxViewDist, 16.0f, 0, - "Sets motion blur max view distance for objects.\n" - "Usage: r_MotionBlurMaxViewDist [0...1]\n" - "Default is 16 meters"); - - DefineConstIntCVar3("r_CustomVisions", CV_r_customvisions, CUSTOMVISIONS_DEFAULT_VAL, VF_NULL, - "Enables custom visions, like heatvision, binocular view, etc.\n" - "Usage: r_CustomVisions [0/1/2/3]\n" - "Default is 0 (disabled). 1 enables. 2 - cheaper version, no post processing. 3 - cheaper post version"); - - DefineConstIntCVar3("r_Snow", CV_r_snow, 2, VF_NULL, - "Enables snow rendering\n" - "Usage: r_Snow [0/1/2]\n" - "0 - disabled\n" - "1 - enabled\n" - "2 - enabled with snow occlusion"); - - DefineConstIntCVar3("r_SnowHalfRes", CV_r_snow_halfres, 0, VF_NULL, - "When enabled, snow renders at half resolution to conserve fill rate.\n" - "Usage: r_SnowHalfRes [0/1]\n" - "0 - disabled\n" - "1 - enabled\n"); - - DefineConstIntCVar3("r_SnowDisplacement", CV_r_snow_displacement, 0, VF_NULL, - "Enables displacement for snow accumulation\n" - "Usage: r_SnowDisplacement [0/1]\n" - "0 - disabled\n" - "1 - enabled"); - - DefineConstIntCVar3("r_SnowFlakeClusters", CV_r_snowFlakeClusters, 100, VF_NULL, - "Number of snow flake clusters.\n" - "Usage: r_SnowFlakeClusters [n]"); - - DefineConstIntCVar3("r_Rain", CV_r_rain, 2, VF_NULL, - "Enables rain rendering\n" - "Usage: r_Rain [0/1/2]\n" - "0 - disabled" - "1 - enabled" - "2 - enabled with rain occlusion"); - - REGISTER_CVAR3("r_RainAmount", CV_r_rainamount, 1.0f, VF_NULL, - "Sets rain amount\n" - "Usage: r_RainAmount"); - - REGISTER_CVAR3("r_RainMaxViewDist", CV_r_rain_maxviewdist, 32.0f, VF_NULL, - "Sets rain max view distance\n" - "Usage: r_RainMaxViewDist"); - - REGISTER_CVAR3("r_RainMaxViewDist_Deferred", CV_r_rain_maxviewdist_deferred, 40.f, VF_NULL, - "Sets maximum view distance (in meters) for deferred rain reflection layer\n" - "Usage: r_RainMaxViewDist_Deferred [n]"); - - REGISTER_CVAR3("r_RainDistMultiplier", CV_r_rainDistMultiplier, 2.f, VF_NULL, "Rain layer distance from camera multiplier"); - - REGISTER_CVAR3("r_RainOccluderSizeTreshold", CV_r_rainOccluderSizeTreshold, 25.f, VF_NULL, "Only objects bigger than this size will occlude rain"); - - REGISTER_CVAR3_CB("r_SSReflections", CV_r_SSReflections, 0, VF_NULL, - "Glossy screen space reflections [0/1]\n", OnChange_CV_r_SSReflections); - REGISTER_CVAR3("r_SSReflHalfRes", CV_r_SSReflHalfRes, 1, VF_NULL, - "Toggles rendering reflections in half resolution\n"); - REGISTER_CVAR3_CB("r_ssdo", CV_r_ssdo, 1, VF_NULL, "Screen Space Directional Occlusion [0/1]\n", OnChange_CV_r_SSDO); - REGISTER_CVAR3("r_ssdoHalfRes", CV_r_ssdoHalfRes, 2, VF_NULL, - "Apply SSDO bandwidth optimizations\n" - "0 - Full resolution (not recommended)\n" - "1 - Use lower resolution depth\n" - "2 - Low res depth except for small camera FOVs to avoid artifacts\n" - "3 - Half resolution output"); - REGISTER_CVAR3("r_ssdoColorBleeding", CV_r_ssdoColorBleeding, 1, VF_NULL, - "Enables AO color bleeding to avoid overly dark occlusion on bright surfaces (requires tiled deferred shading)\n" - "Usage: r_ssdoColorBleeding [0/1]\n"); - REGISTER_CVAR3("r_ssdoRadius", CV_r_ssdoRadius, 1.2f, VF_NULL, "SSDO radius"); - REGISTER_CVAR3("r_ssdoRadiusMin", CV_r_ssdoRadiusMin, 0.04f, VF_NULL, "Min clamped SSDO radius"); - REGISTER_CVAR3("r_ssdoRadiusMax", CV_r_ssdoRadiusMax, 0.20f, VF_NULL, "Max clamped SSDO radius"); - REGISTER_CVAR3("r_ssdoAmountDirect", CV_r_ssdoAmountDirect, 2.0f, VF_NULL, "Strength of occlusion applied to light sources"); - REGISTER_CVAR3("r_ssdoAmountAmbient", CV_r_ssdoAmountAmbient, 1.0f, VF_NULL, "Strength of occlusion applied to probe irradiance"); - REGISTER_CVAR3("r_ssdoAmountReflection", CV_r_ssdoAmountReflection, 1.5f, VF_NULL, "Strength of occlusion applied to probe specular"); - - DefineConstIntCVar3("r_RainIgnoreNearest", CV_r_rain_ignore_nearest, 1, VF_NULL, - "Disables rain wet/reflection layer for nearest objects\n" - "Usage: r_RainIgnoreNearest [0/1]\n"); - - DefineConstIntCVar3("r_DepthOfField", CV_r_dof, DOF_DEFAULT_VAL, VF_NULL, - "Enables depth of field.\n" - "Usage: r_DepthOfField [0/1/2]\n" - "Default is 0 (disabled). 1 enables, 2 hdr time of day dof enabled"); - - DefineConstIntCVar3("r_DebugLightVolumes", CV_r_DebugLightVolumes, 0, VF_NULL, - "0=Disable\n" - "1=Enable\n" - "Usage: r_DebugLightVolumes[0/1]"); - - DefineConstIntCVar3("r_UseShadowsPool", CV_r_UseShadowsPool, SHADOWS_POOL_DEFAULT_VAL, VF_NULL, - "0=Disable\n" - "1=Enable\n" - "Usage: r_UseShadowsPool[0/1]"); - - REGISTER_CVAR3("r_ShadowsBias", CV_r_ShadowsBias, 0.00008f, VF_DUMPTODISK, //-0.00002 - "Select shadow map blurriness if r_ShadowsBias is activated.\n" - "Usage: r_ShadowsBias [0.1 - 16]"); - - REGISTER_CVAR3("r_ShadowsAdaptionRangeClamp", CV_r_ShadowsAdaptionRangeClamp, 0.02f, VF_DUMPTODISK, //-0.00002 - "maximum range between caster and reciever to take into account.\n" - "Usage: r_ShadowsAdaptionRangeClamp [0.0 - 1.0], default 0.01"); - - REGISTER_CVAR3("r_ShadowsAdaptionSize", CV_r_ShadowsAdaptionSize, 0.3f, VF_DUMPTODISK, //-0.00002 - "Select shadow map blurriness if r_ShadowsBias is activated.\n" - "Usage: r_ShadowsAdaptoinSize [0 for none - 10 for rapidly changing]"); - - REGISTER_CVAR3("r_ShadowsAdaptionMin", CV_r_ShadowsAdaptionMin, 0.35f, VF_DUMPTODISK, //-0.00002 - "starting kernel size, to avoid blocky shadows.\n" - "Usage: r_ShadowsAdaptionMin [0.0 for blocky - 1.0 for blury], 0.35 is default"); - - REGISTER_CVAR3("r_ShadowsParticleKernelSize", CV_r_ShadowsParticleKernelSize, 1.f, VF_DUMPTODISK, - "Blur kernel size for particles shadows.\n" - "Usage: r_ShadowsParticleKernelSize [0.0 hard edge - x for blur], 1. is default"); - - REGISTER_CVAR3("r_ShadowsParticleJitterAmount", CV_r_ShadowsParticleJitterAmount, 0.5f, VF_DUMPTODISK, - "Amount of jittering for particles shadows.\n" - "Usage: r_ShadowsParticleJitterAmount [x], 0.5 is default"); - - REGISTER_CVAR3("r_ShadowsParticleAnimJitterAmount", CV_r_ShadowsParticleAnimJitterAmount, 1.f, VF_DUMPTODISK, - "Amount of animated jittering for particles shadows.\n" - "Usage: r_ShadowsParticleJitterAmount [x], 1. is default"); - - REGISTER_CVAR3("r_ShadowsParticleNormalEffect", CV_r_ShadowsParticleNormalEffect, 1.f, VF_DUMPTODISK, - "Shadow taps on particles affected by normal and intensity (breaks lines and uniformity of shadows).\n" - "Usage: r_ShadowsParticleNormalEffect [x], 1. is default"); - - DefineConstIntCVar3("r_ShadowGenMode", CV_r_ShadowGenMode, 1, VF_NULL, - "0=Use Frustums Mask\n" - "1=Regenerate all sides\n" - "Usage: r_ShadowGenMode [0/1]"); - - REGISTER_CVAR3_CB("r_ShadowsCache", CV_r_ShadowsCache, 0, VF_NULL, - "Replace all sun cascades above cvar value with cached (static) shadow map: 0=no cached shadows, 1=replace first cascade and up, 2=replace second cascade and up,...", - OnChange_CachedShadows); - - REGISTER_CVAR3_CB("r_ShadowsCacheFormat", CV_r_ShadowsCacheFormat, 1, VF_NULL, - "0=use D32 texture format for shadow cache\n" - "1=use D16 texture format for shadow cache\n", - OnChange_CachedShadows); - - REGISTER_STRING_CB("r_ShadowsCacheResolutions", "", VF_RENDERER_CVAR, "Shadow cache resolution per cascade. ", OnChange_CachedShadows); - - REGISTER_CVAR3("r_ShadowsNearestMapResolution", CV_r_ShadowsNearestMapResolution, 4096, VF_REQUIRE_APP_RESTART, - "Nearest shadow map resolution. Default: 4096"); - - REGISTER_CVAR3("r_ShadowsScreenSpace", CV_r_ShadowsScreenSpace, 0, VF_NULL, - "Include screen space tracing into shadow computations\n" - "Helps reducing artifacts caused by limited shadow map resolution and biasing\n" - "Applied only in the near range and supposed to be used mostly in the cutscenes for better shadows on character faces"); - - DefineConstIntCVar3("r_ShadowsUseClipVolume", CV_r_ShadowsUseClipVolume, SHADOWS_CLIP_VOL_DEFAULT_VAL, VF_DUMPTODISK, - ".\n" - "Usage: r_ShadowsUseClipVolume [0=Disable/1=Enable"); - - DefineConstIntCVar3("r_ShadowTexFormat", CV_r_shadowtexformat, 0, VF_NULL, - "0=use D32 texture format for depth map\n" - "1=use D16 texture format for depth map\n" - "2=use D24S8 texture format for depth map\n" - "Usage: r_ShadowTexFormat [0-2]"); - - DefineConstIntCVar3("r_ShadowsMaskResolution", CV_r_ShadowsMaskResolution, 0, VF_NULL, - "0=per pixel shadow mask\n" - "1=horizontal half resolution shadow mask\n" - "2=horizontal and vertical half resolution shadow mask\n" - "Usage: r_ShadowsMaskResolution [0/1/2]"); - DefineConstIntCVar3("r_ShadowsMaskDownScale", CV_r_ShadowsMaskDownScale, 0, VF_NULL, - "Saves video memory by using lower resolution for shadow masks except first one\n" - "0=per pixel shadow mask\n" - "1=half resolution shadow mask\n" - "Usage: r_ShadowsMaskDownScale [0/1]"); - REGISTER_CVAR3("r_CBufferUseNativeDepth", CV_r_CBufferUseNativeDepth, CBUFFER_NATIVE_DEPTH_DEAFULT_VAL, VF_NULL, - "1= enable, 0 = disable\n" - "Usage: r_CBufferUseNativeDepth [0/1]"); - DefineConstIntCVar3("r_ShadowsStencilPrePass", CV_r_ShadowsStencilPrePass, 1, VF_NULL, - "1=Use Stencil pre-pass for shadows\n" - "Usage: r_ShadowsStencilPrePass [0/1]"); - REGISTER_CVAR3("r_ShadowsDepthBoundNV", CV_r_ShadowsDepthBoundNV, 0, VF_NULL, - "1=use NV Depth Bound extension\n" - "Usage: r_ShadowsDepthBoundNV [0/1]"); - REGISTER_CVAR3("r_ShadowsPCFiltering", CV_r_ShadowsPCFiltering, 1, VF_NULL, - "1=use PCF for shadows\n" - "Usage: r_ShadowsPCFiltering [0/1]"); - REGISTER_CVAR3_CB("r_ShadowJittering", CV_r_shadow_jittering, 3.4f, VF_NULL, - "Shadow map jittering radius.\n" - "In PC the only use of this cvar is to instantly see the effects of diferent jittering values,\n" - "because any value set here will be overwritten by ToD animation (only in PC) as soon as ToD changes.\n" - "Usage: r_ShadowJittering [0=off]", OnChangeShadowJitteringCVar); - SetShadowJittering(CV_r_shadow_jittering); // need to do this because the registering process can modify the default value (getting it from the .cfg) and will not notify the call back - DefineConstIntCVar3("r_DebugLights", CV_r_debuglights, 0, VF_CHEAT, - "Display dynamic lights for debugging.\n" - "Usage: r_DebugLights [0/1/2/3]\n" - "Default is 0 (off). Set to 1 to display centers of light sources,\n" - "or set to 2 to display light centers and attenuation spheres, 3 to get light properties to the screen"); - DefineConstIntCVar3("r_ShadowsGridAligned", CV_r_ShadowsGridAligned, 1, VF_DUMPTODISK, - "Selects algorithm to use for shadow mask generation:\n" - "0 - Disable shadows snapping\n" - "1 - Enable shadows snapping"); - DefineConstIntCVar3("r_ShadowPass", CV_r_ShadowPass, 1, VF_NULL, - "Process shadow pass"); - DefineConstIntCVar3("r_ShadowGen", CV_r_ShadowGen, 1, VF_NULL, - "0=disable shadow map updates, 1=enable shadow map updates"); - DefineConstIntCVar3("r_ShadowPoolMaxFrames", CV_r_ShadowPoolMaxFrames, 30, VF_NULL, - "Maximum number of frames a shadow can exist in the pool"); - REGISTER_CVAR3("r_ShadowPoolMaxTimeslicedUpdatesPerFrame", CV_r_ShadowPoolMaxTimeslicedUpdatesPerFrame, 1, VF_NULL, - "Max number of time sliced shadow pool updates allowed per frame"); - REGISTER_CVAR3("r_ShadowCastingLightsMaxCount", CV_r_ShadowCastingLightsMaxCount, 32, VF_REQUIRE_APP_RESTART, - "Maximum number of simultaneously visible shadow casting lights"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_17 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - - REGISTER_CVAR3_CB("r_HeightMapAO", CV_r_HeightMapAO, 1, VF_NULL, - "Large Scale Ambient Occlusion based on height map approximation of the scene\n" - "0=off, 1=quarter resolution, 2=half resolution, 3=full resolution", - OnChange_CachedShadows); - REGISTER_CVAR3("r_HeightMapAOAmount", CV_r_HeightMapAOAmount, 1.0f, VF_NULL, - "Height Map Ambient Occlusion Amount"); - REGISTER_CVAR3_CB("r_HeightMapAOResolution", CV_r_HeightMapAOResolution, 2048, VF_NULL, - "Texture resolution of the height map used for HeightMapAO", OnChange_CachedShadows); - REGISTER_CVAR3_CB("r_HeightMapAORange", CV_r_HeightMapAORange, 1000.f, VF_NULL, - "Range of height map AO around viewer in meters", OnChange_CachedShadows); - - REGISTER_CVAR3("r_RenderMeshHashGridUnitSize", CV_r_RenderMeshHashGridUnitSize, .5f, VF_NULL, "Controls density of render mesh triangle indexing structures"); - - DefineConstIntCVar3("r_TerrainAO", CV_r_TerrainAO, 7, 0, "7=Activate terrain AO deferred passes"); - DefineConstIntCVar3("r_TerrainAO_FadeDist", CV_r_TerrainAO_FadeDist, 8, 0, "Controls sky light fading in tree canopy in Z direction"); - - DefineConstIntCVar3("r_LightsSinglePass", CV_r_lightssinglepass, 1, VF_NULL, ""); - - DefineConstIntCVar3("r_ShowDynTextures", CV_r_showdyntextures, 0, VF_NULL, - "Display a dyn. textures, filtered by r_ShowDynTexturesFilter\n" - "Usage: r_ShowDynTextures 0/1/2\n" - "Default is 0. Set to 1 to show all dynamic textures or 2 to display only the ones used in this frame\n" - "Textures are sorted by memory usage"); - - REGISTER_CVAR3("r_ShowDynTexturesMaxCount", CV_r_ShowDynTexturesMaxCount, 36, VF_NULL, - "Allows to adjust number of textures shown on the screen\n" - "Usage: r_ShowDynTexturesMaxCount [1...36]\n" - "Default is 36"); - - CV_r_ShowDynTexturesFilter = REGISTER_STRING("r_ShowDynTexturesFilter", "*", VF_NULL, - "Usage: r_ShowDynTexturesFilter *end\n" - "Usage: r_ShowDynTexturesFilter *mid*\n" - "Usage: r_ShowDynTexturesFilter start*\n" - "Default is *. Set to 'pattern' to show only specific textures (activate r_ShowDynTextures)"); - - CV_r_ShaderCompilerServer = REGISTER_STRING("r_ShaderCompilerServer", "127.0.0.1", VF_NULL, - "Usage: r_ShaderCompilerServer 127.0.0.1 \n" - "Default is 127.0.0.1 "); - - { - const SFileVersion& ver = gEnv->pSystem->GetFileVersion(); - - char versionString[128]; - memset(versionString, 0, sizeof(versionString)); - azsprintf(versionString, "Build Version: %d.%d.%d.%d", ver.v[3], ver.v[2], ver.v[1], ver.v[0]); - - CV_r_ShaderEmailTags = REGISTER_STRING("r_ShaderEmailTags", versionString, VF_NULL, - "Adds optional tags to shader error emails e.g. own name or build run\n" - "Usage: r_ShaderEmailTags \"some set of tags or text\" \n" - "Default is build version "); - } - - { - CV_r_ShaderEmailCCs = REGISTER_STRING("r_ShaderEmailCCs", "", VF_NULL, - "Adds optional CC addresses to shader error emails\n" - "Usage: r_ShaderEmailCCs \"email1@your_domain.com;email2@your_domain.com\" \n" - "Default is empty "); - } - - REGISTER_CVAR3("r_ShaderCompilerPort", CV_r_ShaderCompilerPort, 61453, VF_NULL, - "set user defined port of the shader compile server.\n" - "Usage: r_ShaderCompilerPort 61453 #\n" - "Default is 61453"); - - REGISTER_CVAR3("r_ShaderCompilerDontCache", CV_r_ShaderCompilerDontCache, 0, VF_NULL, - "Disables caching on server side.\n" - "Usage: r_ShaderCompilerDontCache 0 #\n" - "Default is 0"); - - REGISTER_CVAR3("r_RC_AutoInvoke", CV_r_rc_autoinvoke, (gEnv->pSystem->IsDevMode() ? 1 : 0), VF_NULL, - "Enable calling the resource compiler (rc.exe) to compile assets at run-time if the date check\n" - "shows that the destination is older or does not exist.\n" - "Usage: r_RC_AutoInvoke 0 (default is 1)"); - - REGISTER_CVAR3("r_dofMinZ", CV_r_dofMinZ, 0.0f, VF_NULL, - "Set dof min z distance, anything behind this distance will get out focus. (good default value 0.4) \n"); - - REGISTER_CVAR3("r_dofMinZScale", CV_r_dofMinZScale, 0.0f, VF_NULL, - "Set dof min z out of focus strenght (good default value - 1.0f)\n"); - - REGISTER_CVAR3("r_dofMinZBlendMult", CV_r_dofMinZBlendMult, 1.0f, VF_NULL, - "Set dof min z blend multiplier (bigger value means faster blendind transition)\n"); - - REGISTER_CVAR3("r_Refraction", CV_r_Refraction, 1, VF_NULL, - "Enables refraction.\n" - "Usage: r_Refraction [0/1]\n" - "Default is 1 (on). Set to 0 to disable."); - - REGISTER_CVAR3_CB("r_sunshafts", CV_r_sunshafts, SUNSHAFTS_DEFAULT_VAL, VF_NULL, - "Enables sun shafts.\n" - "Usage: r_sunshafts [0/1/2]\n" - "Usage: r_sunshafts = 2: enabled with occlusion\n" - "Default is 1 (on). Set to 0 to disable.", - OnChange_CV_r_SunShafts); - - REGISTER_CVAR3_CB("r_PostProcessEffects", CV_r_PostProcess_CB, 1, VF_NULL, - "Enables post processing special effects.\n" - "Usage: r_PostProcessEffects [0/1/2]\n" - "Default is 1 (enabled). 2 enables and displays active effects", - OnChange_CV_r_PostProcess); - CV_r_PostProcess = CV_r_PostProcess_CB; - - DefineConstIntCVar3("r_PostProcessFilters", CV_r_PostProcessFilters, 1, VF_CHEAT, - "Enables post processing special effects filters.\n" - "Usage: r_PostProcessEffectsFilters [0/1]\n" - "Default is 1 (enabled). 0 disabled"); - - DefineConstIntCVar3("r_PostProcessGameFx", CV_r_PostProcessGameFx, 1, VF_CHEAT, - "Enables post processing special effects game fx.\n" - "Usage: r_PostProcessEffectsGameFx [0/1]\n" - "Default is 1 (enabled). 0 disabled"); - - REGISTER_CVAR3("r_PostProcessReset", CV_r_PostProcessReset, 0, VF_CHEAT, - "Enables post processing special effects reset.\n" - "Usage: r_PostProcessEffectsReset [0/1]\n" - "Default is 0 (disabled). 1 enabled"); - - - DefineConstIntCVar3("r_MergeShadowDrawcalls", CV_r_MergeShadowDrawcalls, 1, VF_NULL, - "Enabled Merging of RenderChunks for ShadowRendering\n" - "Default is 1 (enabled). 0 disabled"); - - REGISTER_CVAR3("r_ColorRangeCompression", CV_r_colorRangeCompression, 0, VF_NULL, - "Enables color range compression to account for the limited RGB range of TVs.\n" - " 0: Disabled (full extended range)\n" - " 1: Range 16-235\n"); - - REGISTER_CVAR3("r_ColorGrading", CV_r_colorgrading, COLOR_GRADING_DEFAULT_VAL, VF_NULL, - "Enables color grading.\n" - "Usage: r_ColorGrading [0/1]"); - - REGISTER_CVAR3("r_ColorGradingSelectiveColor", CV_r_colorgrading_selectivecolor, 1, VF_NULL, - "Enables color grading.\n" - "Usage: r_ColorGradingSelectiveColor [0/1]"); - - DefineConstIntCVar3("r_ColorGradingLevels", CV_r_colorgrading_levels, 1, VF_NULL, - "Enables color grading.\n" - "Usage: r_ColorGradingLevels [0/1]"); - - DefineConstIntCVar3("r_ColorGradingFilters", CV_r_colorgrading_filters, 1, VF_NULL, - "Enables color grading.\n" - "Usage: r_ColorGradingFilters [0/1]"); - - REGISTER_CVAR3("r_ColorGradingCharts", CV_r_colorgrading_charts, 1, VF_NULL, - "Enables color grading via color charts.\n" - "Usage: r_ColorGradingCharts [0/1]"); - - REGISTER_CVAR3("r_ColorGradingChartsCache", CV_r_ColorgradingChartsCache, 4, VF_CVARGRP_IGNOREINREALVAL, // Needs to be ignored from cvar group state otherwise some adv graphic options will show as custom when using multi GPU due to mgpu.cfg being reloaded after changing syspec and graphic options have changed - "Enables color grading charts update caching.\n" - "Usage: r_ColorGradingCharts [0/1/2/etc]\n" - "Default is 4 (update every 4 frames), 0 - always update, 1- update every other frame"); - - DefineConstIntCVar3("r_CloudsUpdateAlways", CV_r_cloudsupdatealways, 0, VF_NULL, - "Toggles updating of clouds each frame.\n" - "Usage: r_CloudsUpdateAlways [0/1]\n" - "Default is 0 (off)"); - DefineConstIntCVar3("r_CloudsDebug", CV_r_cloudsdebug, 0, VF_NULL, - "Toggles debugging mode for clouds." - "Usage: r_CloudsDebug [0/1/2]\n" - "Usage: r_CloudsDebug = 1: render just screen imposters\n" - "Usage: r_CloudsDebug = 2: render just non-screen imposters\n" - "Default is 0 (off)"); - - REGISTER_CVAR3("r_DynTexMaxSize", CV_r_dyntexmaxsize, 48, VF_NULL, ""); // 48 Mb - DefineConstIntCVar3("r_TexPreallocateAtlases", CV_r_texpreallocateatlases, TEXPREALLOCATLAS_DEFAULT_VAL, VF_NULL, ""); - REGISTER_CVAR3("r_TexAtlasSize", CV_r_texatlassize, 1024, VF_NULL, ""); // 1024x1024 - - DefineConstIntCVar3("r_TexPostponeLoading", CV_r_texpostponeloading, 1, VF_NULL, ""); - REGISTER_CVAR3("r_DynTexAtlasCloudsMaxSize", CV_r_dyntexatlascloudsmaxsize, 32, VF_NULL, ""); // 32 Mb - - const int defaultbuffer_bank_size = 4; - const int default_transient_bank_size = 4; - const int default_cb_bank_size = 4; - const int defaultt_cb_watermark = 64; - const int defaultbuffer_pool_max_allocs = 0xfff0; - const int defaultbuffer_pool_defrag = 0; - - REGISTER_CVAR3("r_buffer_banksize", CV_r_buffer_banksize, defaultbuffer_bank_size, VF_CHEAT, "the bank size in MB for buffer pooling"); - REGISTER_CVAR3("r_constantbuffer_banksize", CV_r_constantbuffer_banksize, default_cb_bank_size, VF_CHEAT, "the bank size in MB for constant buffers pooling"); - REGISTER_CVAR3("r_constantbuffer_watermarm", CV_r_constantbuffer_watermark, defaultt_cb_watermark, VF_CHEAT, "the threshold aftyer which constants buffers will reclaim memory"); - REGISTER_CVAR3("r_buffer_sli_workaround", CV_r_buffer_sli_workaround, 0, VF_NULL, "enable SLI workaround for buffer pooling"); - REGISTER_CVAR3("r_transient_pool_size", CV_r_transient_pool_size, default_transient_bank_size, VF_CHEAT, "the bank size in MB for the transient pool"); - DefineConstIntCVar3("r_buffer_enable_lockless_updates", CV_r_buffer_enable_lockless_updates, 1, VF_CHEAT, "enable/disable lockless buffer updates on platforms that support them"); - DefineConstIntCVar3("r_enable_full_gpu_sync", CV_r_enable_full_gpu_sync, 0, VF_CHEAT, "enable full gpu synchronization for debugging purposes on the every buffer I/O operation (debugging only)"); - REGISTER_CVAR3("r_buffer_pool_max_allocs", CV_r_buffer_pool_max_allocs, defaultbuffer_pool_max_allocs, VF_CHEAT, "the maximum number of allocations per buffer pool if defragmentation is enabled"); - REGISTER_CVAR3("r_buffer_pool_defrag_static", CV_r_buffer_pool_defrag_static, defaultbuffer_pool_defrag, VF_CHEAT, "enable/disable runtime defragmentation of static buffers"); - REGISTER_CVAR3("r_buffer_pool_defrag_dynamic", CV_r_buffer_pool_defrag_dynamic, defaultbuffer_pool_defrag, VF_CHEAT, "enable/disable runtime defragmentation of dynamic buffers"); - REGISTER_CVAR3("r_buffer_pool_defrag_max_moves", CV_r_buffer_pool_defrag_max_moves, 64, VF_CHEAT, "maximum number of moves the defragmentation system is allowed to perform per frame"); - - REGISTER_CVAR3("r_TexMinAnisotropy", CV_r_texminanisotropy, 0, VF_REQUIRE_LEVEL_RELOAD, - "Specifies the minimum level allowed for anisotropic texture filtering.\n" - "0(default) means abiding by the filtering setting in each material, except possibly being capped by r_TexMaxAnisotropy."); - REGISTER_CVAR3("r_TexMaxAnisotropy", CV_r_texmaxanisotropy, TEXMAXANISOTROPY_DEFAULT_VAL, VF_REQUIRE_LEVEL_RELOAD, - "Specifies the maximum level allowed for anisotropic texture filtering."); - DefineConstIntCVar3("r_TexNoAnisoAlphaTest", CV_r_texNoAnisoAlphaTest, TEXNOANISOALPHATEST_DEFAULT_VAL, VF_DUMPTODISK, - "Disables anisotropic filtering on alpha-tested geometry like vegetation.\n"); - DefineConstIntCVar3("r_TexLog", CV_r_texlog, 0, VF_NULL, - "Configures texture information logging.\n" - "Usage: r_TexLog #\n" - "where # represents:\n" - " 0: Texture logging off\n" - " 1: Texture information logged to screen\n" - " 2: All loaded textures logged to 'UsedTextures.txt'\n" - " 3: Missing textures logged to 'MissingTextures.txt"); - DefineConstIntCVar3("r_TexNoLoad", CV_r_texnoload, 0, VF_NULL, - "Disables loading of textures.\n" - "Usage: r_TexNoLoad [0/1]\n" - "When 1 texture loading is disabled."); - DefineConstIntCVar3("r_TexBlockOnLoad", CV_r_texBlockOnLoad, 0, VF_NULL, - "When loading a texture, block until resource compiler has finished compiling it.\n" - "Usage: r_TexBlockOnLoad [0/1]\n" - "When 1 renderer will block and wait on the resource compiler."); - - REGISTER_CVAR3("r_RenderTargetPoolSize", CV_r_rendertargetpoolsize, 0, VF_NULL, - "Size of pool for render targets in MB.\n" - "Default is 50(MB)."); - - REGISTER_CVAR3("r_texturesskiplowermips", CV_r_texturesskiplowermips, 0, VF_NULL, - "Enabled skipping lower mips for deprecated platform.\n"); - - int nDefaultTexPoolSize = 512; - - REGISTER_CVAR3("r_TexturesStreamPoolSize", CV_r_TexturesStreamPoolSize, nDefaultTexPoolSize, VF_NULL, - "Size of texture streaming pool in MB.\n"); - - REGISTER_CVAR3("r_TexturesStreamPoolSecondarySize", CV_r_TexturesStreamPoolSecondarySize, 0, VF_NULL, - "Size of secondary pool for textures in MB."); - - REGISTER_CVAR3("r_TexturesStreamingSync", CV_r_texturesstreamingsync, 0, VF_RENDERER_CVAR, - "Force only synchronous texture streaming.\n" - "All textures will be streamed in the main thread. Useful for debug purposes.\n" - "Usage: r_TexturesStreamingSync [0/1]\n" - "Default is 0 (off)."); - DefineConstIntCVar3("r_TexturesStreamingResidencyEnabled", CV_r_texturesstreamingResidencyEnabled, 1, VF_NULL, - "Toggle for resident textures streaming support.\n" - "Usage: r_TexturesStreamingResidencyEnabled [toggle]" - "Default is 0, 1 for enabled"); - REGISTER_CVAR3("r_TexturesStreamingResidencyTimeTestLimit", CV_r_texturesstreamingResidencyTimeTestLimit, 5.0f, VF_NULL, - "Time limit to use for mip thrashing calculation in seconds.\n" - "Usage: r_TexturesStreamingResidencyTimeTestLimit [time]" - "Default is 5 seconds"); - REGISTER_CVAR3("r_TexturesStreamingResidencyTime", CV_r_texturesstreamingResidencyTime, 10.0f, VF_NULL, - "Time to keep textures resident for before allowing them to be removed from memory.\n" - "Usage: r_TexturesStreamingResidencyTime [Time]\n" - "Default is 10 seconds"); - REGISTER_CVAR3("r_TexturesStreamingResidencyThrottle", CV_r_texturesstreamingResidencyThrottle, 0.5f, VF_NULL, - "Ratio for textures to become resident.\n" - "Usage: r_TexturesStreamingResidencyThrottle [ratio]" - "Default is 0.5" - "Max is 1.0 means textures will become resident sooner, Min 0.0 means textures will not become resident"); - REGISTER_CVAR3("r_TexturesStreamingMaxRequestedMB", CV_r_TexturesStreamingMaxRequestedMB, 2.f, VF_NULL, - "Maximum amount of texture data requested from streaming system in MB.\n" - "Usage: r_TexturesStreamingMaxRequestedMB [size]\n" - "Default is 2.0(MB)"); - - DefineConstIntCVar3("r_TexturesStreamingPostponeMips", CV_r_texturesstreamingPostponeMips, 0, VF_NULL, - "Postpone loading of high res mipmaps to improve resolution ballance of texture streaming.\n" - "Usage: r_TexturesStreamingPostponeMips [0/1]\n" - "Default is 1 (on)."); - - DefineConstIntCVar3("r_TexturesStreamingPostponeThresholdKB", CV_r_texturesstreamingPostponeThresholdKB, 1024, VF_NULL, - "Threshold used to postpone high resolution mipmap loads in KB.\n" - "Usage: r_TexturesStreamingPostponeThresholdKB [size]\n" - "Default is 1024(KB)"); - DefineConstIntCVar3("r_texturesstreamingPostponeThresholdMip", CV_r_texturesstreamingPostponeThresholdMip, 1, VF_NULL, - "Threshold used to postpone high resolution mipmaps.\n" - "Usage: r_texturesstreamingPostponeThresholdMip [count]\n" - "Default is 1"); - DefineConstIntCVar3("r_TexturesStreamingMinReadSizeKB", CV_r_texturesstreamingMinReadSizeKB, 64, VF_NULL, - "Minimal read portion in KB.\n" - "Usage: r_TexturesStreamingMinReadSizeKB [size]\n" - "Default is 32(KB)"); - REGISTER_CVAR3("r_texturesstreamingSkipMips", CV_r_texturesstreamingSkipMips, 0, VF_NULL, - "Number of top mips to ignore when streaming.\n"); - REGISTER_CVAR3("r_texturesstreamingMinUsableMips", CV_r_texturesstreamingMinUsableMips, 7, VF_NULL, - "Minimum number of mips a texture should be able to use after applying r_texturesstreamingSkipMips.\n"); - REGISTER_CVAR3("r_texturesstreamingJobUpdate", CV_r_texturesstreamingJobUpdate, 1, VF_NULL, - "Enable texture streaming update job"); -#if defined(TEXSTRM_DEFERRED_UPLOAD) - REGISTER_CVAR3("r_texturesstreamingDeferred", CV_r_texturesstreamingDeferred, 1, VF_NULL, - "When enabled textures will be uploaded through a deferred context.\n"); -#endif -#if defined(SUPPORTS_INPLACE_TEXTURE_STREAMING) - REGISTER_CVAR3("r_texturesstreamingInPlace", CV_r_texturesstreamingInPlace, 1, VF_NULL, - "When enabled textures will stream directly into video memory.\n"); -#endif - REGISTER_CVAR3("r_TexturesStreamingMaxRequestedJobs", CV_r_TexturesStreamingMaxRequestedJobs, 32, VF_NULL, - "Maximum number of tasks submitted to streaming system.\n" - "Usage: r_TexturesStreamingMaxRequestedJobs [jobs number]\n" - "Default is 32 jobs"); - DefineConstIntCVar3("r_TexturesStreamingUpdateType", CV_r_texturesstreamingUpdateType, TEXSTREAMING_UPDATETYPE_DEFAULT_VAL, VF_NULL, - "Texture streaming update type.\n" - "Default is 0"); - DefineConstIntCVar3("r_TexturesStreamingPrecacheRounds", CV_r_texturesstreamingPrecacheRounds, 1, VF_NULL, - "Number of precache rounds to include in active streamed texture lists.\n" - "Default is 1"); - DefineConstIntCVar3("r_TexturesStreamingSuppress", CV_r_texturesstreamingSuppress, 0, VF_NULL, - "Force unloading of all textures and suppress new stream tasks.\n" - "Default is 0"); - REGISTER_CVAR3("r_TexturesStreamingMipBias", CV_r_TexturesStreamingMipBias, 0, VF_NULL, - "Controls how texture LOD depends from distance to the objects.\n" - "Increasing this value will reduce amount of memory required for textures.\n" - "Usage: r_TexturesStreamingMipBias [-4..0..4]\n" - "Default is 0."); - REGISTER_CVAR3("r_TexturesStreamingMipClampDVD", CV_r_TexturesStreamingMipClampDVD, 1, VF_NULL, - "Clamp the texture mip level to certain value when streaming from DVD. 1 will never allow highest mips to be loaded for example.\n" - "Usage: r_TexturesStreamingMipClampDVD [0..4]\n" - "Default is 1."); - REGISTER_CVAR3("r_TexturesStreamingDisableNoStreamDuringLoad", CV_r_TexturesStreamingDisableNoStreamDuringLoad, 0, VF_NULL, - "Load time optimisation. When enabled, textures flagged as non-streaming will still be streamed during level load, but will have a " - "high priority stream request added in RT_Precache. Once streamed in, the texture will remain resident\n"); - DefineConstIntCVar3("r_TexturesStreamingMipFading", CV_r_texturesstreamingmipfading, 1, VF_NULL, - "Controls how the new texture MIP appears after being streamed in.\n" - "This variable influences only a visual quality of appearing texture details.\n" - "Usage: r_TexturesStreamingMipFading [0/1]\n" - "Default is 1 (enabled)."); - DefineConstIntCVar3("r_TexturesStreamingNoUpload", CV_r_texturesstreamingnoupload, 0, VF_NULL, - "Disable uploading data into texture from system memory. Useful for debug purposes.\n" - "Usage: r_TexturesStreamingNoUpload [0/1]\n" - "Default is 0 (off)."); - DefineConstIntCVar3("r_TexturesStreamingOnlyVideo", CV_r_texturesstreamingonlyvideo, 0, VF_NULL, - "Don't store system memory copy of texture. Applicable only for PC.\n" - "Usage: r_TexturesStreamingOnlyVideo [0/1]\n" - "Default is 0 (off)."); - - DefineConstIntCVar3("r_TexturesDebugBandwidth", CV_r_TexturesDebugBandwidth, 0, VF_CHEAT, - "Replaces all material textures with a small white texture to debug texture bandwidth utilization\n"); - - DefineConstIntCVar3("r_TexturesStreaming", CV_r_texturesstreaming, TEXSTREAMING_DEFAULT_VAL, VF_REQUIRE_APP_RESTART, - "Enables direct streaming of textures from disk during game.\n" - "Usage: r_TexturesStreaming [0/1/2]\n" - "Default is 0 (off). All textures save in native format with mips in a\n" - "cache file. Textures are then loaded into texture memory from the cache."); - - DefineConstIntCVar3("r_TexturesStreamingDebug", CV_r_TexturesStreamingDebug, 0, VF_CHEAT, - "Enables textures streaming debug mode. (Log uploads and remove unnecessary mip levels)\n" - "Usage: r_TexturesStreamingDebug [0/1/2]\n" - "Default is 0 (off)." - "1 - texture streaming log." - "2 - Show textures hit-parade based on streaming priorities" - "3 - Show textures hit-parade based on the memory consumed"); - CV_r_TexturesStreamingDebugfilter = REGISTER_STRING("r_TexturesStreamingDebugFilter", "", VF_CHEAT, "Filters displayed textures by name in texture streaming debug mode\n"); - REGISTER_CVAR3("r_TexturesStreamingDebugMinSize", CV_r_TexturesStreamingDebugMinSize, 100, VF_NULL, - "Filters displayed textures by size in texture streaming debug mode"); - REGISTER_CVAR3("r_TexturesStreamingDebugMinMip", CV_r_TexturesStreamingDebugMinMip, 100, VF_NULL, - "Filters displayed textures by loaded mip in texture streaming debug mode"); - DefineConstIntCVar3("r_TexturesStreamingDebugDumpIntoLog", CV_r_TexturesStreamingDebugDumpIntoLog, 0, VF_NULL, - "Dump content of current texture streaming debug screen into log"); - REGISTER_CVAR3("r_TextureLodDistanceRatio", CV_r_TextureLodDistanceRatio, -1, VF_NULL, - "Controls dynamic LOD system for textures used in materials.\n" - "Usage: r_TextureLodDistanceRatio [-1, 0 and bigger]\n" - "Default is -1 (completely off). Value 0 will set full LOD to all textures used in frame.\n" - "Values bigger than 0 will activate texture LOD selection depending on distance to the objects."); - - DefineConstIntCVar3("r_TextureCompiling", CV_r_texturecompiling, 1, VF_NULL, - "Enables Run-time compilation and subsequent injection of changed textures from disk during editing.\n" - "Usage: r_TextureCompiling [0/1]\n" - "Default is 1 (on). Changes are tracked and passed through to the rendering.\n" - "Compilation can also be muted by the r_RC_AutoInvoke config."); - DefineConstIntCVar3("r_TextureCompilingIndicator", CV_r_texturecompilingIndicator, 0, VF_NULL, - "Replaces the textures which are currently compiled by a violet indicator-texture.\n" - "Usage: r_TextureCompilingIndicator [-1/0/1]\n" - "Default is 0 (off). Textures are silently replaced by their updated versions without any indication.\n" - "Negative values will also stop show indicators for compilation errors.\n" - "Positive values will show indicators whenever a texture is subject to imminent changes.\n"); - -#ifndef STRIP_RENDER_THREAD - DefineConstIntCVar3("r_MultiThreaded", CV_r_multithreaded, MULTITHREADED_DEFAULT_VAL, VF_NULL, - "0=disabled, 1=enabling rendering in separate thread,\n" - "2(default)=automatic detection\n" - "should be activated before rendering"); -#endif - DefineConstIntCVar3("r_MultiThreadedDrawing", CV_r_multithreadedDrawing, 0, VF_NULL, - " 0=disabled,\n" - " N=number of concurrent draw recording jobs,\n" - " -1=Number is as large as the number of available worker threads"); - DefineConstIntCVar3("r_MultiThreadedDrawingActiveThreshold", CV_r_multithreadedDrawingActiveThreshold, 0, VF_NULL, - " 0=disabled,\n" - " N=minimum number of draws per job,\n" - "If there are not enough draws for all jobs it will dial down the number of jobs."); - REGISTER_CVAR3("r_MultiGPU", CV_r_multigpu, 1, VF_NULL, - "Toggles MGPU support. Should usually be set before startup.\n" - " 0: force off\n" - " 1: automatic detection (reliable with SLI, does not respect driver app profiles with Crossfire)\n"); - - DefineConstIntCVar3("r_ShowNormals", CV_r_shownormals, 0, VF_CHEAT, - "Toggles visibility of normal vectors.\n" - "Usage: r_ShowNormals [0/1]" - "Default is 0 (off)."); - DefineConstIntCVar3("r_ShowLines", CV_r_showlines, 0, VF_CHEAT, - "Toggles visibility of wireframe overlay.\n" - "Usage: r_ShowLines [0/1]\n" - "Default is 0 (off)."); - REGISTER_CVAR3("r_NormalsLength", CV_r_normalslength, 0.2f, VF_CHEAT, - "Sets the length of displayed vectors.\n" - "r_NormalsLength 0.2\n" - "Default is 0.2 (meters). Used with r_ShowTangents and r_ShowNormals."); - DefineConstIntCVar3("r_ShowTangents", CV_r_showtangents, 0, VF_CHEAT, - "Toggles visibility of three tangent space vectors.\n" - "Usage: r_ShowTangents [0/1]\n" - "Default is 0 (off)."); - DefineConstIntCVar3("r_ShowTimeGraph", CV_r_showtimegraph, 0, VF_NULL, - "Configures graphic display of frame-times.\n" - "Usage: r_ShowTimeGraph [0/1/2]\n" - "\t1: Graph displayed as points." - "\t2: Graph displayed as lines." - "Default is 0 (off)."); -#ifndef EXCLUDE_DOCUMENTATION_PURPOSE - DefineConstIntCVar3("r_DebugFontRendering", CV_r_DebugFontRendering, 0, VF_CHEAT, - "0=off, 1=display various features of the font rendering to verify function and to document usage"); -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - DefineConstIntCVar3("profileStreaming", CV_profileStreaming, 0, VF_NULL, - "Profiles streaming of different assets.\n" - "Usage: profileStreaming [0/1/2]\n" - "\t1: Graph displayed as points." - "\t2: Graph displayed as lines." - "Default is 0 (off)."); - DefineConstIntCVar3("r_GraphStyle", CV_r_graphstyle, 0, VF_NULL, ""); - DefineConstIntCVar3("r_ShowBufferUsage", CV_r_showbufferusage, 0, VF_NULL, - "Shows usage of statically allocated buffers.\n" - "Usage: r_ShowBufferUSage [0/1]\n" - "Default is 0 (off)."); - REGISTER_CVAR3_CB("r_LogVBuffers", CV_r_logVBuffers, 0, VF_CHEAT | VF_CONST_CVAR, - "Logs vertex buffers in memory to 'LogVBuffers.txt'.\n" - "Usage: r_LogVBuffers [0/1]\n" - "Default is 0 (off).", - GetLogVBuffersStatic); - DefineConstIntCVar3("r_LogTexStreaming", CV_r_logTexStreaming, 0, VF_CHEAT, - "Logs streaming info to Direct3DLogStreaming.txt\n" - "0: off\n" - "1: normal\n" - "2: extended"); - DefineConstIntCVar3("r_LogShaders", CV_r_logShaders, 0, VF_CHEAT, - "Logs shaders info to Direct3DLogShaders.txt\n" - "0: off\n" - "1: normal\n" - "2: extended"); - -#if defined(WIN32) || defined(WIN64) - const int r_flush_default = 0; -#else - const int r_flush_default = 1; // TODO: Check if r_flush should be disabled on other platforms as well -#endif - REGISTER_CVAR3("r_Flush", CV_r_flush, r_flush_default, VF_NULL, ""); - - REGISTER_CVAR3("r_minimizeLatency", CV_r_minimizeLatency, 0, VF_REQUIRE_APP_RESTART, - "Initializes and drives renderer to minimize display latency as much as possible.\n" - "As such only a double buffer swap chain will be created.\n" - "Maximum frame latency will be set to 1 on DXGI-supporting platforms\n" - "as well as frames flushed after Present() if r_Flush is enabled."); - - DefineConstIntCVar3("r_ShadersDebug", CV_r_shadersdebug, 0, VF_DUMPTODISK, - "Enable special logging when shaders become compiled\n" - "Usage: r_ShadersDebug [0/1/2/3/4]\n" - " 1 = assembly into directory Main/{Game}/shaders/cache/d3d9\n" - " 2 = compiler input into directory Main/{Game}/testcg\n" - " 3 = compiler input with debug information (useful for PIX etc./{Game}/testcg_1pass\n" - " 4 = compiler input with debug information, but optimized shaders\n" - "Default is 0 (off)"); - -#if !defined(CONSOLE) - REGISTER_CVAR3("r_ShadersOrbis", CV_r_shadersorbis, 0, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersDX11", CV_r_shadersdx11, 0, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersGL4", CV_r_shadersGL4, 0, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersGLES3", CV_r_shadersGLES3, 0, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersMETAL", CV_r_shadersMETAL, 0, VF_NULL, ""); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_15 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - REGISTER_CVAR3("r_ShadersPlatform", CV_r_shadersPlatform, static_cast(AZ::PlatformID::PLATFORM_MAX), VF_NULL, ""); -#endif - - DefineConstIntCVar3("r_ShadersIgnoreIncludesChanging", CV_r_shadersignoreincludeschanging, 0, VF_NULL, ""); - DefineConstIntCVar3("r_ShadersLazyUnload", CV_r_shaderslazyunload, 0, VF_NULL, ""); - - REGISTER_CVAR3("r_ShadersPreactivate", CV_r_shaderspreactivate, SHADERS_PREACTIVATE_DEFAULT_VAL, VF_DUMPTODISK, ""); - - REGISTER_CVAR3_CB("r_ShadersAllowCompilation", CV_r_shadersAllowCompilation, SHADERS_ALLOW_COMPILATION_DEFAULT_VAL, VF_NULL, "", OnChange_CV_r_ShadersAllowCompiliation); - - DefineConstIntCVar3("r_ShadersRemoteCompiler", CV_r_shadersremotecompiler, 0, VF_DUMPTODISK, "Enables remote shader compilation on dedicated machine"); - REGISTER_CVAR3("r_ShadersAsyncCompiling", CV_r_shadersasynccompiling, 1, VF_NULL, - "Enable asynchronous shader compiling\n" - "Usage: r_ShadersAsyncCompiling [0/1/2/3]\n" - " 0 = off, (stalling) shaders compiling\n" - " 1 = on, shaders are compiled in parallel, missing shaders are rendered in yellow\n" - " 2 = on, shaders are compiled in parallel, missing shaders are not rendered\n" - " 3 = on, shaders are compiled in parallel in precache mode"); - REGISTER_CVAR3("r_ShadersAsyncActivation", CV_r_shadersasyncactivation, 1, VF_NULL, - "Enable asynchronous shader activation\n" - "Usage: r_ShadersAsyncActivation [0/1]\n" - " 0 = off, (stalling) synchronous shaders activation\n" - " 1 = on, shaders are activated/streamed asynchronously\n"); - - DefineConstIntCVar3("r_ShadersEditing", CV_r_shadersediting, 0, VF_NULL, "Force all cvars to settings, which allow shader editing"); - - DefineConstIntCVar3("r_ShadersCompileAutoActivate", CV_r_shaderscompileautoactivate, 0, VF_NULL, "Automatically reenable shader compilation if outdated shader is detected"); - - REGISTER_CVAR3("r_AssetProcessorShaderCompiler", CV_r_AssetProcessorShaderCompiler, 0, VF_NULL, - "Enables using the Asset Processor as a proxy for the shader compiler if its not reachable directly.\n" - "Usage: r_AssetProcessorShaderCompiler 1\n" - "Default is 0 (disabled)"); - - DefineConstIntCVar3("r_ReflectTextureSlots", CV_r_ReflectTextureSlots, 1, VF_NULL, "Reflect texture slot information from shader"); - - REGISTER_CVAR3("r_ShadersAsyncMaxThreads", CV_r_shadersasyncmaxthreads, 1, VF_DUMPTODISK, ""); - REGISTER_CVAR3("r_ShadersCacheDeterministic", CV_r_shaderscachedeterministic, 1, VF_NULL, "Ensures that 2 shaderCaches built from the same source are binary equal"); - DefineConstIntCVar3("r_ShadersPrecacheAllLights", CV_r_shadersprecachealllights, 1, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersSubmitRequestline", CV_r_shaderssubmitrequestline, 1, VF_NULL, ""); - REGISTER_CVAR3("r_ShadersUseInstanceLookUpTable", CV_r_shadersuseinstancelookuptable, 0, VF_NULL, - "Use lookup table to search for shader instances. Speeds up the process, but uses more memory. Handy for shader generation."); - - bool bShaderLogCacheMisses = true; -#if defined(_RELEASE) - bShaderLogCacheMisses = false; -#endif - REGISTER_CVAR3("r_ShadersLogCacheMisses", CV_r_shaderslogcachemisses, bShaderLogCacheMisses ? 2 : 0, VF_NULL, - "Log all shader caches misses on HD (both level and global shader cache misses).\n" - "0 = No logging to disk or TTY\n" - "1 = Logging to disk only\n" - "2 = Logging to disk and TTY (default)"); - - REGISTER_CVAR3("r_ShadersImport", CV_r_shadersImport, 0, VF_NULL, - "0 = Off\n" - "1 = Import pre-parsed shader reflection information from .fxb files if they exist for a related .cfx which skips expensive parsing of .cfx files in RT_ParseShader. If a .fxb exists for a shader but an individual permutation is missing, then fallback to the slow .cfx parsing for that permutation." - "2 = Import from the .fxb files, but do not fallback if import fails. Missing shader permutations from .fxb files will be ignored." - "3 = Same behavior as 1, but only when running Performance/Release configurations. Debug/Profile builds will disable this and set it to 0 (for an improved development experience). This allows us to continue compiling shaders in Debug/Profile configurations and run optimally in Performance/Release"); - - REGISTER_CVAR3("r_ShadersExport", CV_r_shadersExport, 1, VF_NULL, - "0 off, 1 allow export of .fxb files during shader cache generation."); - - REGISTER_CVAR3("r_ShadersCacheUnavailableShaders", CV_r_shadersCacheUnavailableShaders, 0, VF_NULL, - "0 off (default), 1 cache unavailable shaders to avoid requesting their compilation in future executions."); - - DefineConstIntCVar3("r_ShadersUseLLVMDirectXCompiler", CV_r_ShadersUseLLVMDirectXCompiler, 0, VF_NULL, - "Shaders will be compiled using the LLVM DirectX Shader Compiler (GL4, GLES3 and METAL).\n" - "Usage: r_ShadersUseLLVMDirectXCompiler 1\n" - "Default is 0 (disabled)"); - - DefineConstIntCVar3("r_DebugRenderMode", CV_r_debugrendermode, 0, VF_CHEAT, ""); - DefineConstIntCVar3("r_DebugRefraction", CV_r_debugrefraction, 0, VF_CHEAT, - "Debug refraction usage. Displays red instead of refraction\n" - "Usage: r_DebugRefraction\n" - "Default is 0 (off)"); - - DefineConstIntCVar3("r_MeshPrecache", CV_r_meshprecache, 1, VF_NULL, ""); - REGISTER_CVAR3("r_MeshPoolSize", CV_r_meshpoolsize, RENDERER_DEFAULT_MESHPOOLSIZE, VF_NULL, - "The size of the pool for render data in kilobytes. " - "Disabled by default on PC (mesh data allocated on heap)." - "Enabled by default on consoles. Requires app restart to change."); - REGISTER_CVAR3("r_MeshInstancePoolSize", CV_r_meshinstancepoolsize, RENDERER_DEFAULT_MESHINSTANCEPOOLSIZE, VF_NULL, - "The size of the pool for volatile render data in kilobytes. " - "Disabled by default on PC (mesh data allocated on heap)." - "Enabled by default on consoles. Requires app restart to change."); - - CV_r_excludeshader = REGISTER_STRING("r_ExcludeShader", "0", VF_CHEAT, - "Exclude the named shader from the render list.\n" - "Usage: r_ExcludeShader ShaderName\n" - "Sometimes this is useful when debugging."); - - CV_r_excludemesh = REGISTER_STRING("r_ExcludeMesh", "", VF_CHEAT, - "Exclude or ShowOnly the named mesh from the render list.\n" - "Usage: r_ExcludeShader Name\n" - "Usage: r_ExcludeShader !Name\n" - "Sometimes this is useful when debugging."); - - DefineConstIntCVar3("r_ProfileShaders", CV_r_profileshaders, 0, VF_CHEAT, - "Enables display of render profiling information.\n" - "Usage: r_ProfileShaders [0/1]\n" - "Default is 0 (off). Set to 1 to display profiling\n" - "of rendered shaders."); - DefineConstIntCVar3("r_ProfileShadersSmooth", CV_r_ProfileShadersSmooth, 4, VF_CHEAT, - "Smooth time information.\n" - "Usage: r_ProfileShadersSmooth [0-10]"); - DefineConstIntCVar3("r_ProfileShadersGroupByName", CV_r_ProfileShadersGroupByName, 1, VF_CHEAT, - "Group items by name ignoring RT flags.\n" - "Usage: r_ProfileShaders [0/1]"); - - /* REGISTER_CVAR3("r_EnvCMWrite", CV_r_envcmwrite, 0, VF_NULL, - "Writes cube-map textures to disk.\n" - "Usage: r_EnvCMWrite [0/1]\n" - "Default is 0 (off). The textures are written to 'Cube_posx.jpg'\n" - "'Cube_negx.jpg',...,'Cube_negz.jpg'. At least one of the real-time\n" - "cube-map shaders should be present in the current scene."); - */ - REGISTER_CVAR3("r_EnvCMResolution", CV_r_envcmresolution, 1, VF_DUMPTODISK, - "Sets resolution for target environment cubemap, in pixels.\n" - "Usage: r_EnvCMResolution #\n" - "where # represents:\n" - "\t0: 64\n" - "\t1: 128\n" - "\t2: 256\n" - "Default is 2 (256 by 256 pixels)."); - - REGISTER_CVAR3("r_EnvTexResolution", CV_r_envtexresolution, ENVTEXRES_DEFAULT_VAL, VF_DUMPTODISK, - "Sets resolution for 2d target environment texture, in pixels.\n" - "Usage: r_EnvTexResolution #\n" - "where # represents:\n" - " 0: 64\n" - " 1: 128\n" - " 2: 256\n" - " 3: 512\n" - "Default is 3 (512 by 512 pixels)."); - - REGISTER_CVAR3("r_WaterUpdateDistance", CV_r_waterupdateDistance, 2.0f, VF_NULL, ""); - - REGISTER_CVAR3("r_WaterUpdateFactor", CV_r_waterupdateFactor, 0.01f, VF_DUMPTODISK | VF_CVARGRP_IGNOREINREALVAL, // Needs to be ignored from cvar group state otherwise some adv graphic options will show as custom when using multi GPU due to mgpu.cfg being reloaded after changing syspec and graphic options have changed, - "Distance factor for water reflected texture updating.\n" - "Usage: r_WaterUpdateFactor 0.01\n" - "Default is 0.01. 0 means update every frame"); - - REGISTER_CVAR3("r_EnvCMupdateInterval", CV_r_envcmupdateinterval, 0.04f, VF_DUMPTODISK, - "Sets the interval between environmental cube map texture updates.\n" - "Usage: r_EnvCMupdateInterval #\n" - "Default is 0.1."); - REGISTER_CVAR3("r_EnvTexUpdateInterval", CV_r_envtexupdateinterval, 0.001f, VF_DUMPTODISK, - "Sets the interval between environmental 2d texture updates.\n" - "Usage: r_EnvTexUpdateInterval 0.001\n" - "Default is 0.001."); - - // Slimming of GBuffers by encoding full RGB channels into more efficient YCbCr channels which require - // less storage for the CbCr channels (ie. 24(8+8+8) bits to 16(8+4+4) bits). - // This allows the packing of different component channels into the G-Buffers, saving the cost of 3 extra channels. - // 4 + 4 + 4 = 12 bytes of saving per pixel in the G-Buffer, assuming RGBA8 format - // Slimmed down GBuffer encoding scheme: - // Texture Channels: R G B A - // - // Normal Map Texture Normal.x Normal.y Specular Y (YCrCb) Smoothness (6bit) + Light (2bit) - // Diffuse Texture Albedo.x Albedo.y Albedo.z Specular CrCb (4+4 bit) - // Specular (One Channel Only) Occlusion N/A N/A N/A - REGISTER_CVAR3("r_SlimGBuffer", CV_r_SlimGBuffer,0, VF_REQUIRE_APP_RESTART, - "Optimize the gbuffer render targets use.\n" - "Usage:r_SlimGBuffer 1\n"); - - DefineConstIntCVar3("r_WaterReflections", CV_r_waterreflections, 1, VF_DUMPTODISK, - "Toggles water reflections.\n" - "Usage: r_WaterReflections [0/1]\n" - "Default is 1 (water reflects)."); - - DefineConstIntCVar3("r_WaterReflectionsQuality", CV_r_waterreflections_quality, WATERREFLQUAL_DEFAULT_VAL, VF_DUMPTODISK, - "Activates water reflections quality setting.\n" - "Usage: r_WaterReflectionsQuality [0/1/2/3]\n" - "Default is 0 (terrain only), 1 (terrain + particles), 2 (terrain + particles + brushes), 3 (everything)"); - - REGISTER_CVAR3("r_WaterReflectionsMinVisiblePixelsUpdate", CV_r_waterreflections_min_visible_pixels_update, 0.05f, VF_DUMPTODISK, - "Activates water reflections if visible pixels above a certain threshold."); - - REGISTER_CVAR3("r_WaterReflectionsMinVisUpdateFactorMul", CV_r_waterreflections_minvis_updatefactormul, 20.0f, VF_DUMPTODISK, - "Activates update factor multiplier when water mostly occluded."); - REGISTER_CVAR3("r_WaterReflectionsMinVisUpdateDistanceMul", CV_r_waterreflections_minvis_updatedistancemul, 10.0f, VF_DUMPTODISK, - "Activates update distance multiplier when water mostly occluded."); - - REGISTER_CVAR3("r_WaterCaustics", CV_r_watercaustics, 1, VF_RENDERER_CVAR, // deprecating soon, moving to the Water Gem - "Toggles under water caustics.\n" - "Usage: r_WaterCaustics [0/1]\n" - "Default is 1 (enabled)."); - - REGISTER_CVAR3("r_WaterCausticsDistance", CV_r_watercausticsdistance, 100.0f, VF_NULL, - "Toggles under water caustics max distance.\n" - "Usage: r_WaterCausticsDistance\n" - "Default is 100.0 meters"); - - REGISTER_CVAR3("r_WaterVolumeCaustics", CV_r_watervolumecaustics, WATERVOLCAUSTICS_DEFAULT_VAL, VF_NULL, - "Toggles advanced water caustics for watervolumes.\n" - "Usage: r_WaterVolumeCaustics [0/1]\n" - "Default is 0 (disabled). 1 - enables."); - - REGISTER_CVAR3("r_WaterVolumeCausticsDensity", CV_r_watervolumecausticsdensity, 128, VF_NULL, - "Density/resolution of watervolume caustic grid.\n" - "Usage: r_WaterVolumeCausticsDensity [16/256]\n" - "Default is 256"); - - REGISTER_CVAR3("r_WaterVolumeCausticsRes", CV_r_watervolumecausticsresolution, 512, VF_NULL, - "Resolution of watervoluem caustics texture.\n" - "Usage: r_WaterVolumeCausticsRes [n]\n" - "Default is 1024"); - - REGISTER_CVAR3("r_WaterVolumeCausticsSnapFactor", CV_r_watervolumecausticssnapfactor, 1.0f, VF_NULL, - "Distance in which to snap the vertex grid/projection (to avoid aliasing).\n" - "Usage: r_WaterVolumeCausticsSnapFactor [n]\n" - "Default is 1.0"); - - REGISTER_CVAR3("r_WaterVolumeCausticsMaxDist", CV_r_watervolumecausticsmaxdistance, 35.0f, VF_NULL, - "Maximum distance in which caustics are visible.\n" - "Usage: r_WaterVolumeCausticsMaxDist [n]\n" - "Default is 35"); - - if (!OceanToggle::IsActive()) - { - DefineConstIntCVar3("r_WaterGodRays", CV_r_water_godrays, 1, VF_NULL, - "Enables under water god rays.\n" - "Usage: r_WaterGodRays [0/1]\n" - "Default is 1 (enabled)."); - - REGISTER_CVAR3("r_WaterGodRaysDistortion", CV_r_water_godrays_distortion, 1, VF_NULL, - "Set the amount of distortion when underwater.\n" - "Usage: r_WaterGodRaysDistortion [n]\n" - "Default is 1."); - } - - - DefineConstIntCVar3("r_Reflections", CV_r_reflections, 1, VF_DUMPTODISK, - "Toggles reflections.\n" - "Usage: r_Reflections [0/1]\n" - "Default is 1 (reflects)."); - - REGISTER_CVAR3("r_ReflectionsOffset", CV_r_waterreflections_offset, 0.0f, VF_NULL, ""); - - DefineConstIntCVar3("r_ReflectionsQuality", CV_r_reflections_quality, 3, VF_DUMPTODISK, - "Toggles reflections quality.\n" - "Usage: r_ReflectionsQuality [0/1/2/3]\n" - "Default is 0 (terrain only), 1 (terrain + particles), 2 (terrain + particles + brushes), 3 (everything)"); - - DefineConstIntCVar3("r_DetailTextures", CV_r_detailtextures, 1, VF_DUMPTODISK, - "Toggles detail texture overlays.\n" - "Usage: r_DetailTextures [0/1]\n" - "Default is 1 (detail textures on)."); - - DefineConstIntCVar3("r_ReloadShaders", CV_r_reloadshaders, 0, VF_CHEAT, - "Reloads shaders.\n" - "Usage: r_ReloadShaders [0/1]\n" - "Default is 0. Set to 1 to reload shaders."); - - REGISTER_CVAR3("r_DetailDistance", CV_r_detaildistance, 6.0f, VF_DUMPTODISK, - "Distance used for per-pixel detail layers blending.\n" - "Usage: r_DetailDistance (1-20)\n" - "Default is 6."); - - DefineConstIntCVar3("r_TexBindMode", CV_r_texbindmode, 0, VF_CHEAT, - "Enable texture overrides.\n" - "Usage: r_TexBindMode [0/1/2/4/5/6/7/8/9/10/11]\n" - "\t1 - Force gray non-font maps\n" - "\t5 - Force flat normal maps\n" - "\t6 - Force white diffuse maps\n" - "\t7 - Force diffuse maps to use mipmapdebug texture\n" - "\t8 - Colour code diffuse maps to show minimum uploaded mip [0:green,1:cyan,2:blue,3:purple,4:magenta,5:yellow,6:orange,7:red,higher:white]\n" - "\t9 - Colour code diffuse maps to show textures streaming in in green and out in red\n" - "\t10 - Colour code diffuse maps that have requested a lower mip than the lowest available [-3: red, -2: yellow, -1: green]\n" - "\t11 - Force white diffuse map and flat normal map\n" - "\t12 - Visualise textures that have more or less mips in memory than needed\n" - "Default is 0 (disabled)."); - DefineConstIntCVar3("r_NoDrawShaders", CV_r_nodrawshaders, 0, VF_CHEAT, - "Disable entire render pipeline.\n" - "Usage: r_NoDrawShaders [0/1]\n" - "Default is 0 (render pipeline enabled). Used for debugging and profiling."); - REGISTER_CVAR3("r_DrawNearShadows", CV_r_DrawNearShadows, 0, VF_NULL, - "Enable shadows for near objects.\n" - "Usage: r_DrawNearShadows [0/1]\n"); - REGISTER_CVAR3("r_NoDrawNear", CV_r_nodrawnear, 0, VF_RENDERER_CVAR, - "Disable drawing of near objects.\n" - "Usage: r_NoDrawNear [0/1]\n" - "Default is 0 (near objects are drawn)."); - REGISTER_CVAR3("r_DrawNearZRange", CV_r_DrawNearZRange, 0.12f, VF_NULL, - "Default is 0.1."); - REGISTER_CVAR3("r_DrawNearFarPlane", CV_r_DrawNearFarPlane, 40.0f, VF_NULL, - "Default is 40."); - REGISTER_CVAR3("r_DrawNearFoV", CV_r_drawnearfov, 60.0f, VF_NULL, - "Sets the FoV for drawing of near objects.\n" - "Usage: r_DrawNearFoV [n]\n" - "Default is 60."); - - REGISTER_CVAR3_CB("r_Flares", CV_r_flares, FLARES_DEFAULT_VAL, VF_DUMPTODISK, - "Toggles lens flare effect.\n" - "Usage: r_Flares [0/1]\n" - "Default is 1 (on).", - OnChange_CV_r_flares); - - DefineConstIntCVar3("r_FlareHqShafts", CV_r_flareHqShafts, FLARES_HQSHAFTS_DEFAULT_VAL, VF_DUMPTODISK, - "Toggles high quality mode for point light shafts.\n" - "Usage: r_FlareHqShafts [0/1]\n" - "Default is 1 (on)."); - - REGISTER_CVAR3("r_FlaresChromaShift", CV_r_FlaresChromaShift, 6.0f, VF_NULL, - "Set flares chroma shift amount.\n" - "Usage: r_FlaresChromaShift [n]\n" - "Default is 6\n" - "0 Disables"); - - REGISTER_CVAR3("r_FlaresIrisShaftMaxPolyNum", CV_r_FlaresIrisShaftMaxPolyNum, 200, VF_NULL, - "Set the maximum number of polygon of IrisShaft.\n" - "Usage : r_FlaresIrisShaftMaxPolyNum [n]\n" - "Default is 200\n" - "0 Infinite"); - - REGISTER_CVAR3_CB("r_FlaresTessellationRatio", CV_r_FlaresTessellationRatio, 1, VF_NULL, - "Set the tessellation rate of flares. 1 is the original mesh.\n" - "Usage : r_FlaresTessellationRatio 0.5\n" - "Default is 1.0\n" - "Range is from 0 to 1", OnChange_CV_r_FlaresTessellationRatio); - - REGISTER_CVAR3("r_Gamma", CV_r_gamma, 1.0f, VF_DUMPTODISK, - "Adjusts the graphics card gamma correction (fast, needs hardware support, also affects HUD and desktop)\n" - "r_NoHWGamma must be set to 0 for this to have an effect.\n" - "Usage: r_Gamma 1.0\n" - "1 off (default)"); - REGISTER_CVAR3("r_Brightness", CV_r_brightness, 0.5f, VF_DUMPTODISK, - "Sets the display brightness (fast, needs hardware support, also affects HUD and desktop)\n" - "r_NoHWGamma must be set to 0 for this to have an effect.\n" - "Usage: r_Brightness 0.5\n" - "Default is 0.5."); - REGISTER_CVAR3("r_Contrast", CV_r_contrast, 0.5f, VF_DUMPTODISK, - "Sets the display contrast (fast, needs hardware support, also affects HUD and desktop)\n" - "r_NoHWGamma must be set to 0 for this to have an effect.\n" - "Usage: r_Contrast 0.5\n" - "Default is 0.5."); - - DefineConstIntCVar3("r_NoHWGamma", CV_r_nohwgamma, 2, VF_DUMPTODISK, - "Sets renderer to ignore hardware gamma correction.\n" - "Usage: r_NoHWGamma [0/1/2]\n" - "0 - allow hardware gamma correction\n" - "1 - disable hardware gamma correction\n" - "2 - disable hardware gamma correction in Editor\n"); - - REGISTER_CVAR3("r_Scissor", CV_r_scissor, 1, VF_RENDERER_CVAR, "Enables scissor test"); - - DefineConstIntCVar3("r_wireframe", CV_r_wireframe, R_SOLID_MODE, VF_CHEAT, "Toggles wireframe rendering mode"); - - REGISTER_CVAR3_CB("r_GetScreenShot", CV_r_GetScreenShot, 0, VF_NULL, - AZStd::string::format - ( - "To capture one screenshot (variable is set to 0 after capturing)\n" - "%d = do not take a screenshot (default)\n" - "%d = take a screenshot and another HDR screenshot if HDR is enabled\n" - "%d = take a screenshot\n", - static_cast(ScreenshotType::None), - static_cast(ScreenshotType::HdrAndNormal), - static_cast(ScreenshotType::Normal) - ).c_str(), - []([[maybe_unused]] ICVar* pArgs) - { - // Do not accept other values, since ScreenshotType::NormalWithFilepath = 3 is reserved for internal use. - if (CV_r_GetScreenShot != static_cast(ScreenshotType::None) && - CV_r_GetScreenShot != static_cast(ScreenshotType::HdrAndNormal) && - CV_r_GetScreenShot != static_cast(ScreenshotType::Normal)) - { - CV_r_GetScreenShot = static_cast(ScreenshotType::None); - iLog->LogWarning("Screenshot type not supported!"); - } - } - ); - - DefineConstIntCVar3("r_Character_NoDeform", CV_r_character_nodeform, 0, VF_NULL, ""); - - REGISTER_CVAR3("r_Log", CV_r_log, 0, VF_CHEAT, - "Logs rendering information to Direct3DLog.txt.\n" - "Use negative values to log a single frame.\n" - "Usage: r_Log +/-[0/1/2/3/4]\n" - "\t1: Logs a list of all shaders without profile info.\n" - "\t2: Log contains a list of all shaders with profile info.\n" - "\t3: Logs all API function calls.\n" - "\t4: Highly detailed pipeline log, including all passes,\n" - "\t\t\tstates, lights and pixel/vertex shaders.\n" - "Default is 0 (off). Use this function carefully, because\n" - "log files grow very quickly."); - - DefineConstIntCVar3("r_LogVidMem", CV_r_logVidMem, 0, VF_CHEAT, - "Logs vid mem information to VidMemLog.txt."); - - DefineConstIntCVar3("r_Stats", CV_r_stats, 0, VF_CHEAT, - "Toggles render statistics.\n" - "0=disabled,\n" - "1=global render stats,\n" - "2=print shaders for selected object,\n" - "3=CPU times of render passes and video memory usage,\n" - "4=CPU times of render passes,\n" - "5=Occlusion query calls (calls to mfDraw/mfReadResult_Now/mfReadResult_Try),\n" - "6=display per-instance drawcall count,\n" - "8=Info about instanced DIPs,\n" - "13=print info about cleared RT's,\n" - "Usage: r_Stats [0/1/n]"); - - DefineConstIntCVar3("r_statsMinDrawCalls", CV_r_statsMinDrawcalls, 0, VF_CHEAT, - "Minimum drawcall amount to display for use with r_Stats 6"); - - DefineConstIntCVar3("r_profiler", CV_r_profiler, 0, VF_NULL, - "Display render pipeline profiler.\n" - " 0: Disabled\n" - " 1: Basic overview\n" - " 2: Detailed pass stats\n"); - - REGISTER_CVAR3("r_profilerTargetFPS", CV_r_profilerTargetFPS, 30.0f, VF_NULL, - "Target framerate for application."); - - REGISTER_CVAR3("r_VSync", CV_r_vsync, 1, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Toggles vertical sync.\n" - "0: Disabled\n" - "1: Enabled\n" - "2: Enabled, use asynchronous swaps on deprecated platform"); - - REGISTER_CVAR3("r_OldBackendSkip", CV_r_OldBackendSkip, 0, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Ignores old backend processing.\n" - "0: Old backend is on\n" - "1: Old backend is skipped\n" - "2: Old backend shadows are skipped\n"); - -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - REGISTER_CVAR3("r_overrideRefreshRate", CV_r_overrideRefreshRate, 0, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Enforces specified refresh rate when running in fullscreen (0=off)."); - REGISTER_CVAR3("r_overrideScanlineOrder", CV_r_overrideScanlineOrder, 0, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Enforces specified scanline order when running in fullscreen.\n" - "0=off,\n" - "1=progressive,\n" - "2=interlaced (upper field first),\n" - "3=interlaced (lower field first)\n" - "Usage: r_overrideScanlineOrder [0/1/2/3]"); - REGISTER_CVAR3("r_overrideDXGIOutput", CV_r_overrideDXGIOutput, 0, VF_REQUIRE_APP_RESTART, - "Specifies index of display to use for output (0=primary display)."); - REGISTER_CVAR3("r_overrideDXGIOutputFS", CV_r_overrideDXGIOutputFS, 0, VF_NULL, - "Specifies index of display to use for full screen output (0=primary display)."); -#endif -#if defined(WIN32) || defined(WIN64) - REGISTER_CVAR3("r_FullscreenPreemption", CV_r_FullscreenPreemption, 1, VF_NULL, - "While in fullscreen activities like notification pop ups of other applications won't cause a mode switch back into windowed mode."); -#endif - DefineConstIntCVar3("r_PredicatedTiling", CV_r_predicatedtiling, 0, VF_REQUIRE_APP_RESTART, - "Toggles predicated tiling mode (deprecated platform only)\n" - "Usage: r_PredicatedTiling [0/1]"); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - DefineConstIntCVar3("r_MeasureOverdraw", CV_r_measureoverdraw, 0, VF_CHEAT, - "Activate a special rendering mode that visualize the rendering cost of each pixel by color.\n" - "0=off,\n" - "1=pixel shader instructions,\n" - "2=pass count,\n" - "3=vertex shader instructions,\n" - "4=overdraw estimation with Hi-Z (deprecated),\n" - "Usage: r_MeasureOverdraw [0/1/2/3/4]"); - REGISTER_CVAR3("r_MeasureOverdrawScale", CV_r_measureoverdrawscale, 1.5f, VF_CHEAT, ""); - - DefineConstIntCVar3("r_PrintMemoryLeaks", CV_r_printmemoryleaks, 0, VF_NULL, ""); - DefineConstIntCVar3("r_ReleaseAllResourcesOnExit", CV_r_releaseallresourcesonexit, 1, VF_NULL, ""); - - REGISTER_CVAR3("r_ShowVideoMemoryStats", CV_r_ShowVideoMemoryStats, 0, VF_NULL, ""); - REGISTER_COMMAND("r_ShowRenderTarget", &Cmd_ShowRenderTarget, VF_CHEAT, showRenderTargetHelp); - - REGISTER_CVAR3("r_VRAMDebug", CV_r_VRAMDebug, 0, VF_NULL, - "Display debug information for VRAM heaps on platforms where we have direct access to video memory\n" - "\t0: Disabled\n" - "\t1: VRAM heap statistics and occupancy visualization enabled"); - - REGISTER_CVAR3("r_BreakOnError", CV_r_BreakOnError, 0, VF_NULL, "calls debugbreak on illegal behaviour"); - REGISTER_CVAR3("r_D3D12SubmissionThread", CV_r_D3D12SubmissionThread, 1, VF_NULL, "run DX12 command queue submission tasks from a dedicated thread"); - - REGISTER_CVAR3("r_ReprojectOnlyStaticObjects", CV_r_ReprojectOnlyStaticObjects, 1, VF_NULL, "Forces a split in the zpass, to prevent moving object from beeing reprojected"); - REGISTER_CVAR3("r_ReverseDepth", CV_r_ReverseDepth, 1, VF_NULL, "Use 1-z depth rendering for increased depth precision"); - - REGISTER_CVAR3("r_EnableDebugLayer", CV_r_EnableDebugLayer, 0, VF_NULL, "DX12: Enable Debug Layer"); - REGISTER_CVAR3("r_NoDraw", CV_r_NoDraw, 0, VF_NULL, "Disable submitting of certain draw operations: 1-(Do not process render objects at all), 2-(Do not submit individual render objects), 3-(No DrawIndexed)"); - - // show texture debug routine + auto completion - CV_r_ShowTexture = REGISTER_STRING("r_ShowTexture", "", VF_CHEAT, "Displays loaded texture - for debug purpose\n"); - gEnv->pConsole->RegisterAutoComplete("r_ShowTexture", &g_TextureNameAutoComplete); - - DefineConstIntCVar3("r_ShowLightBounds", CV_r_ShowLightBounds, 0, VF_CHEAT, - "Display light bounds - for debug purpose\n" - "Usage: r_ShowLightBounds [0=off/1=on]"); - DefineConstIntCVar3("r_MergeRenderChunks", CV_r_MergeRenderChunks, 1, VF_NULL, ""); - - REGISTER_CVAR3("r_ParticlesTessellation", CV_r_ParticlesTessellation, 1, VF_NULL, "Enables particle tessellation for higher quality lighting. (DX11 only)"); - REGISTER_CVAR3("r_ParticlesTessellationTriSize", CV_r_ParticlesTessellationTriSize, 16, VF_NULL, "Sets particles tessellation triangle screen space size in pixels (DX11 only)"); - - REGISTER_CVAR3("r_ZFightingDepthScale", CV_r_ZFightingDepthScale, 0.995f, VF_CHEAT, "Controls anti z-fighting measures in shaders (scaling homogeneous z)."); - REGISTER_CVAR3("r_ZFightingExtrude", CV_r_ZFightingExtrude, 0.001f, VF_CHEAT, "Controls anti z-fighting measures in shaders (extrusion along normal in world units)."); - - REGISTER_CVAR3_CB("r_TexelsPerMeter", CV_r_TexelsPerMeter, 0, VF_ALWAYSONCHANGE, - "Enables visualization of the color coded \"texels per meter\" ratio for objects in view.\n" - "The checkerboard pattern displayed represents the mapping of the assigned diffuse\n" - "texture onto the object's uv space. One block in the pattern represents 8x8 texels.\n" - "Usage: r_TexelsPerMeter [n] (where n is the desired number of texels per meter; 0 = off)", - OnChange_CV_r_TexelsPerMeter); - - REGISTER_CVAR3("r_enableAltTab", CV_r_enableAltTab, 1, VF_NULL, - "Toggles alt tabbing in and out of fullscreen when the game is not in devmode.\n" - "Usage: r_enableAltTab [toggle]\n" - "Notes: Should only be added to system.cfg and requires a restart"); - - REGISTER_CVAR3("r_StereoDevice", CV_r_StereoDevice, 0, VF_REQUIRE_APP_RESTART | VF_DUMPTODISK, - "Sets stereo device (only possible before app start)\n" - "Usage: r_StereoDevice [0/1/2/3/4]\n" - "0: No stereo support (default)\n" - "1: Frame compatible formats (side-by-side, interlaced, anaglyph)\n" - "2: HDMI 1.4\n" - "3: Stereo driver (PC only, NVidia or AMD)\n" - "4: Dualhead (PC only, two projectors or iZ3D screen)\n" - "100: Auto-detect device for platform"); - - REGISTER_CVAR3("r_StereoMode", CV_r_StereoMode, 0, VF_DUMPTODISK, - "Sets stereo rendering mode.\n" - "Usage: r_StereoMode [0=off/1]\n" - "1: Dual rendering\n"); - - REGISTER_CVAR3("r_StereoOutput", CV_r_StereoOutput, 0, VF_DUMPTODISK, - "Sets stereo output. Output depends on the stereo monitor\n" - "Usage: r_StereoOutput [0=off/1/2/3/4/5/6/...]\n" - "0: Standard\n" - "1: IZ3D\n" - "2: Checkerboard\n" - "3: Above and Below (not supported)\n" - "4: Side by Side\n" - "5: Line by Line (Interlaced)\n" - "6: Anaglyph\n" - "7: VR Device (Oculus/Vive)\n" - ); - - REGISTER_CVAR3("r_StereoFlipEyes", CV_r_StereoFlipEyes, 0, VF_DUMPTODISK, - "Flip eyes in stereo mode.\n" - "Usage: r_StereoFlipEyes [0=off/1=on]\n" - "0: don't flip\n" - "1: flip\n"); - - REGISTER_CVAR3("r_StereoStrength", CV_r_StereoStrength, 1.0f, VF_DUMPTODISK, - "Multiplier which influences the strength of the stereo effect."); - - REGISTER_CVAR3("r_StereoEyeDist", CV_r_StereoEyeDist, 0.02f, VF_DUMPTODISK, - "[For 3D TV] Maximum separation between stereo images in percentage of the screen."); - - REGISTER_CVAR3("r_StereoScreenDist", CV_r_StereoScreenDist, 0.25f, VF_DUMPTODISK, - "Distance to plane where stereo parallax converges to zero."); - - REGISTER_CVAR3("r_StereoNearGeoScale", CV_r_StereoNearGeoScale, 0.65f, VF_DUMPTODISK, - "Scale for near geometry (weapon) that gets pushed into the screen"); - - REGISTER_CVAR3("r_StereoHudScreenDist", CV_r_StereoHudScreenDist, 0.5f, VF_DUMPTODISK, - "Distance to plane where hud stereo parallax converges to zero.\n" - "If not zero, HUD needs to be rendered two times."); - - REGISTER_CVAR3("r_StereoGammaAdjustment", CV_r_StereoGammaAdjustment, 0.12f, VF_DUMPTODISK, - "Additional adjustment to the graphics card gamma correction when Stereo is enabled.\n" - "Usage: r_StereoGammaAdjustment [offset]" - "0: off"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - const int DEVICE_WIDTH = 1152; - const int DEVICE_HEIGHT = 720; -#endif - - REGISTER_CVAR3("r_ConsoleBackbufferWidth", CV_r_ConsoleBackbufferWidth, DEVICE_WIDTH, VF_DUMPTODISK, - "console specific backbuffer resolution - width"); - REGISTER_CVAR3("r_ConsoleBackbufferHeight", CV_r_ConsoleBackbufferHeight, DEVICE_HEIGHT, VF_DUMPTODISK, - "console specific backbuffer resolution - height"); - - REGISTER_CVAR3("r_ConditionalRendering", CV_r_ConditionalRendering, 0, VF_NULL, "Enables conditional rendering ."); - - REGISTER_CVAR3("r_CustomResMaxSize", CV_r_CustomResMaxSize, s_CustomResMaxSize_USE_MAX_RESOURCES, VF_NULL, "Maximum resolution of custom resolution rendering. A value of -1 sets the maximum to the upper limit of the device."); - REGISTER_CVAR3("r_CustomResWidth", CV_r_CustomResWidth, 0, VF_NULL, "Width of custom resolution rendering"); - REGISTER_CVAR3("r_CustomResHeight", CV_r_CustomResHeight, 0, VF_NULL, "Height of custom resolution rendering"); - REGISTER_CVAR3("r_CustomResPreview", CV_r_CustomResPreview, 1, VF_NULL, "Enable/disable preview of custom resolution rendering in viewport" - "(0 - no preview, 1 - scaled to match viewport, 2 - custom resolution clipped to viewport"); - REGISTER_CVAR3("r_Supersampling", CV_r_Supersampling, 1, VF_NULL, "Use supersampled antialiasing" - "(1 - 1x1 no SSAA, 2 - 2x2, 3 - 3x3 ...)"); - REGISTER_CVAR3("r_SupersamplingFilter", CV_r_SupersamplingFilter, 0, VF_NULL, "Filter method to use when resolving supersampled output" - "\n0 - Box filter" - "\n1 - Tent filter" - "\n2 - Gaussian filter" - "\n3 - Lanczos filter"); - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - REGISTER_COMMAND("r_PrecacheShaderList", &ShadersPrecacheList, VF_NULL, ""); - REGISTER_COMMAND("r_StatsShaderList", &ShadersStatsList, VF_NULL, ""); - REGISTER_COMMAND("r_OptimiseShaders", &ShadersOptimise, VF_NULL, ""); - REGISTER_COMMAND("r_GetShaderList", &GetShaderList, VF_NULL, ""); -#endif - - DefineConstIntCVar3("r_TextureCompressor", CV_r_TextureCompressor, 1, VF_DUMPTODISK, - "Defines which texture compressor is used (fallback is DirectX)\n" - "Usage: r_TextureCompressor [0/1]\n" - "0 uses DirectX, 1 uses squish if possible"); - - REGISTER_CVAR3("r_FogDepthTest", CV_r_FogDepthTest, -0.0005f, VF_NULL, - "Enables per-pixel culling for deferred volumetric fog pass.\n" - "Fog computations for all pixels closer than a given depth value will be skipped.\n" - "Usage: r_FogDepthTest z with...\n" - " z = 0, culling disabled\n" - " z > 0, fixed linear world space culling depth\n" - " z < 0, optimal culling depth will be computed automatically based on camera direction and fog settings"); - -#if defined(VOLUMETRIC_FOG_SHADOWS) - REGISTER_CVAR3("r_FogShadows", CV_r_FogShadows, 0, VF_NULL, - "Enables deferred volumetric fog shadows\n" - "Usage: r_FogShadows [0/1/2]\n" - " 0: off\n" - " 1: standard resolution\n" - " 2: reduced resolution\n"); - REGISTER_CVAR3("r_FogShadowsMode", CV_r_FogShadowsMode, 0, VF_NULL, - "Ray-casting mode for shadowed fog\n" - "Usage: r_FogShadowsMode [0/1]\n" - " 0: brute force shadowmap sampling\n" - " 1: optimized shadowmap sampling\n"); -#endif - REGISTER_CVAR3("r_FogShadowsWater", CV_r_FogShadowsWater, 1, VF_NULL, "Enables volumetric fog shadows for watervolumes"); - - DefineConstIntCVar3("r_RainDropsEffect", CV_r_RainDropsEffect, 1, VF_CHEAT, - "Enable RainDrops effect.\n" - "Usage: r_RainDropEffect [0/1/2]\n" - "0: force off\n" - "1: on (default)\n" - "2: on (forced)"); - - DefineConstIntCVar3("r_RefractionPartialResolves", CV_r_RefractionPartialResolves, 2, VF_NULL, - "Do a partial screen resolve before refraction\n" - "Usage: r_RefractionPartialResolves [0/1]\n" - "0: disable \n" - "1: enable conservatively (non-optimal)\n" - "2: enable (default)"); - - DefineConstIntCVar3("r_RefractionPartialResolvesDebug", CV_r_RefractionPartialResolvesDebug, 0, VF_NULL, - "Toggle refraction partial resolves debug display\n" - "Usage: r_RefractionPartialResolvesDebug [0/1]\n" - "0: disable \n" - "1: Additive 2d area \n" - "2: Bounding boxes \n" - "3: Alpha overlay with varying colours \n"); - - DefineConstIntCVar3("r_Batching", CV_r_Batching, 1, VF_NULL, - "Enable/disable render items batching\n" - "Usage: r_Batching [0/1]\n"); - - DefineConstIntCVar3("r_Unlit", CV_r_Unlit, 0, VF_CHEAT, - "Render just diffuse texture with no lighting (for most materials)."); - - DefineConstIntCVar3("r_HideSunInCubemaps", CV_r_HideSunInCubemaps, 1, VF_NULL, - "Stops the sun being drawn during cubemap generation.\n"); - - // more details: http://en.wikipedia.org/wiki/Overscan -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_8 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - REGISTER_COMMAND("r_OverscanBorders", &cmd_OverscanBorders, VF_NULL, - "Changes the size of the overscan borders for the left/right and top/bottom\n" - "of the screen for adjusting the title safe area. This is for logo placements\n" - "and text printout to account for the TV overscan and is mostly needed for consoles.\n" - "If only one value is specified, the overscan borders for left/right and top/bottom\n" - "are set simultaneously, but you may also specify different percentages for left/right\n" - "and top/bottom.\n" - "Usage: r_OverscanBorders [0..25]\n" - " r_OverscanBorders [0..25] [0..25]\n" - "Default is 0=off, >0 defines the size of the overscan borders for left/right\n" - "or top/bottom as percentages of the whole screen size (e.g. 7.5)."); - -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) - float overscanBorderScale = 0.0f; -#else - float overscanBorderScale = 0.03f; // Default consoles to sensible overscan border -#endif - REGISTER_CVAR3_CB("r_OverscanBorderScaleX", s_overscanBorders.x, overscanBorderScale, VF_NULL, - "Sets the overscan border width scale\n" - "Usage: r_OverscanBorderScaleX [0.0->0.25]", - OnChange_r_OverscanBorderScale); - - REGISTER_CVAR3_CB("r_OverscanBorderScaleY", s_overscanBorders.y, overscanBorderScale, VF_NULL, - "Sets the overscan border height scale\n" - "Usage: r_OverscanBorderScaleY [0.0->0.25]", - OnChange_r_OverscanBorderScale); - - REGISTER_CVAR2("r_UsePersistentRTForModelHUD", &CV_r_UsePersistentRTForModelHUD, 0, VF_NULL, - "Uses a seperate RT to render models for the ModelHud Renderer"); - -#if defined(ENABLE_RENDER_AUX_GEOM) - const int defValAuxGeomEnable = 1; - REGISTER_CVAR2("r_enableAuxGeom", &CV_r_enableauxgeom, defValAuxGeomEnable, VF_REQUIRE_APP_RESTART, "Enables aux geometry rendering."); -#endif - - REGISTER_CVAR2("r_ParticleVerticePoolSize", &CV_r_ParticleVerticePoolSize, 15360, VF_REQUIRE_APP_RESTART, "Max Number of Particle Vertices to support"); - - DefineConstIntCVar3("r_ParticlesDebug", CV_r_ParticlesDebug, 0, VF_NULL, - "Particles debugging\n" - "Usage: \n" - "0 disabled\n" - "1 particles screen coverage (red = bad, blue = good)\n" - "2 particles overdraw (white = really bad, red = bad, blue = good)"); - - REGISTER_CVAR3("r_GeomCacheInstanceThreshold", CV_r_GeomCacheInstanceThreshold, 10, VF_NULL, "Threshold after which instancing is used to draw geometry cache pieces"); - - REGISTER_CVAR3("r_VisAreaClipLightsPerPixel", CV_r_VisAreaClipLightsPerPixel, 1, VF_NULL, "Per pixel light/cubemap culling for vis areas: 0=off, 1=on"); - REGISTER_CVAR3("r_OutputShaderSourceFiles", CV_r_OutputShaderSourceFiles, 0, VF_NULL, "If true, HLSL and GLSL files will be saved in the USER\\Shader\\* folders during shader compilation. Does not work on console or mobile targets."); - - REGISTER_CVAR3("r_VolumetricFogTexScale", CV_r_VolumetricFogTexScale, 10, VF_NULL, - "Width and height scale factor (divided by screen resolution) for volume texture.\n" - "Acceptable value is more than equal 2.\n" - ); - REGISTER_CVAR3("r_VolumetricFogTexDepth", CV_r_VolumetricFogTexDepth, 32, VF_NULL, - "Depth resolution of volume texture.\n" - "Huge value runs out of performance and video memory.\n" - ); - REGISTER_CVAR3("r_VolumetricFogReprojectionBlendFactor", CV_r_VolumetricFogReprojectionBlendFactor, 0.9f, VF_NULL, - "Adjust the blend factor of temporal reprojection.\n" - "Acceptable value is between 0 and 1.\n" - "0 means temporal reprojecton is off.\n" - ); - REGISTER_CVAR3("r_VolumetricFogSample", CV_r_VolumetricFogSample, 0, VF_NULL, - "Adjust number of sample points.\n" - "0: 1 sample point in a voxel\n" - "1: 2 sample points in a voxel\n" - "2: 4 sample points in a voxel\n" - ); - REGISTER_CVAR3("r_VolumetricFogShadow", CV_r_VolumetricFogShadow, 1, VF_NULL, - "Adjust shadow sample count per sample point.\n" - "0: 1 shadow sample per sample point\n" - "1: 2 shadow samples per sample point \n" - "2: 3 shadow samples per sample point\n" - "3: 4 shadow samples per sample point\n" - ); - - // Confetti David Srour: Upscaling Quality for Metal - DefineConstIntCVar3("r_UpscalingQuality", CV_r_UpscalingQuality, 0, VF_NULL, - "iOS Metal Upscaling Quality\n" - "Usage: \n" - "0 Point\n" - "1 Bilinear\n" - "2 Bicubic\n" - "3 Lanczos\n"); - - //Clears GMEM G-Buffer through a shader. Has support for fixed point - DefineConstIntCVar3("r_ClearGMEMGBuffer", CV_r_ClearGMEMGBuffer, 0, VF_NULL, - "GMEM G-Buffer Clear\n" - "Usage: \n" - "0 no clearing\n" - "1 full screen clear pass before Z-Pass. Done through a shader and supports fixed point\n" - "2 full screen clear pass before Z-Pass. Done through loadactions (faster)\n"); - - // Enables fast math for metal shaders - DefineConstIntCVar3("r_MetalShadersFastMath", CV_r_MetalShadersFastMath, 1, VF_NULL, - "Metal shaders fast math. Default is 1.\n" - "Usage: \n" - "0 Dont use fast math\n" - "1 Use fast math\n"); - - - // Confetti David Srour: GMEM paths - REGISTER_CVAR3("r_EnableGMEMPath", CV_r_EnableGMEMPath, 0, VF_REQUIRE_APP_RESTART, - "Mobile GMEM Paths\n" - "Usage: \n" - "0 Standard Rendering\n" - "1 256bpp GMEM Path\n" - "2 128bpp GMEM Path\n"); - - REGISTER_CVAR3("r_GMEM_DOF_Gather1_Quality", CV_r_GMEM_DOF_Gather1_Quality, 3, VF_REQUIRE_APP_RESTART, - "Value represents # of taps squared for 1st gather pass.\n" - "Usage: \n" - "Clamped between 1 & 7 (default is 3)\n"); - - REGISTER_CVAR3("r_GMEM_DOF_Gather2_Quality", CV_r_GMEM_DOF_Gather2_Quality, 2, VF_REQUIRE_APP_RESTART, - "Value represents # of taps squared for second gather pass.\n" - "Usage: \n" - "Clamped between 1 & 7 (default is 2)\n"); - - REGISTER_CVAR3("r_EnableGMEMPostProcCS", CV_r_EnableGMEMPostProcCS, 0, VF_REQUIRE_APP_RESTART, - "GMEM Compute Postprocess Pipeline\n" - "Usage: \n" - "0 Compute disabled with postprocessing on GMEM path\n" - "1 Compute enabled with postprocessing on GMEM path\n"); - - REGISTER_CVAR3("r_RainUseStencilMasking", CV_r_RainUseStencilMasking, 0, VF_REQUIRE_APP_RESTART, - "GMEM Deferred Rain enable stencil masking\n" - "Usage: \n" - "0 Use single pass rain on GMEM path\n" - "1 Generate stencil mask for rain on GMEM path\n"); - - // Confetti David Srour: Global VisArea/Portals blend weight for GMEM path - REGISTER_CVAR3("r_GMEMVisAreasBlendWeight", CV_r_GMEMVisAreasBlendWeight, 1, VF_NULL, - "Global VisArea/Portal Blend Weight for GMEM Render Path\n" - "GMEM render path doesn't support per-portal blend weight.\n" - "0.f to 1.f weight\n"); - - REGISTER_CVAR3("r_ForceFixedPointRenderTargets", CV_r_ForceFixedPointRenderTargets, 0, VF_NULL, - "Forces the engine to use fixed point render targets instead of floating point ones.\n" - "This variable is respected on Android OpenGL ES only\n" - "0 Off\n" - "1 ON\n"); - - REGISTER_CVAR3_CB("r_Fur", CV_r_Fur, 1, VF_NULL, - "Specifies how fur is rendered:\n" - "0: Fur is disabled - objects using Fur shader appear similar to Illum\n" - "1: Alpha blended transparent passes\n" - "2: Alpha tested opaque passes", - OnChange_CV_r_Fur); - - REGISTER_CVAR3("r_FurShellPassCount", CV_r_FurShellPassCount, 64, VF_NULL, - "Number of passes to perform for rendering fur shells"); - - REGISTER_CVAR3("r_FurShowBending", CV_r_FurShowBending, 0, VF_DEV_ONLY, - "Toggles visibility of fur bending vectors."); - - REGISTER_CVAR3("r_FurDebug", CV_r_FurDebug, 0, VF_DEV_ONLY, - "Debug visualizers for fur.\n" - "0: off\n" - "1: base/tip sample validity (red = base valid; green = tip valid; yellow = both valid)\n" - "2: base/tip selection (red = base chosen; green = tip chosen)\n" - "3: show offscreen UVs for base deferred sample (gray = onscreen)\n" - "4: show offscreen UVs for tip deferred sample (gray = onscreen)\n" - "5: show final lighting with all base lighting selected\n" - "6: show final lighting with all tip lighting selected\n" - "7: visualize fur length scaling\n" - "8: visualize fur animation bending velocity"); - - REGISTER_CVAR3("r_FurDebugOneShell", CV_r_FurDebugOneShell, 0, VF_DEV_ONLY, - "Debug cvar to draw only the specified shell number for fur. 0 = disabled."); - - REGISTER_CVAR3("r_FurFinPass", CV_r_FurFinPass, 0, VF_NULL, - "Toggles view orthogonal fin pass for fur. 0 = disabled."); - - REGISTER_CVAR3("r_FurFinShadowPass", CV_r_FurFinShadowPass, 1, VF_NULL, - "Toggles view orthogonal fin pass for fur in shadow passes. 0 = disabled."); - - REGISTER_CVAR3("r_FurMovementBendingBias", CV_r_FurMovementBendingBias, 0.1f, VF_NULL, - "Bias for fur bending from animation & movement. Closer to 1 causes fur to bend back faster."); - - REGISTER_CVAR3("r_FurMaxViewDist", CV_r_FurMaxViewDist, 32.0f, VF_NULL, - "Maximum view distance for fur shell passes."); - - REGISTER_CVAR3("r_EnableComputeDownSampling", CV_r_EnableComputeDownSampling, 0, VF_NULL, - "Metal compute down sample\n" - "Usage: \n" - "0 Off\n" - "1 ON\n"); - - REGISTER_CVAR3("r_VolumetricFogDownscaledSunShadow", CV_r_VolumetricFogDownscaledSunShadow, 1, VF_NULL, - "Enable replacing sun shadow maps with downscaled shadow maps or static shadow map if possible.\n" - "0: disabled\n" - "1: replace first and second cascades with downscaled shadow maps. the others are replaced with static shadow map if possible.\n" - "2: replace first, second, and third cascades with downscaled shadow maps. the others are replaced with static shadow map if possible.\n" - ); - REGISTER_CVAR3("r_VolumetricFogDownscaledSunShadowRatio", CV_r_VolumetricFogDownscaledSunShadowRatio, 1, VF_NULL, - "Set downscale ratio for sun shadow maps\n" - "0: 1/4 downscaled sun shadow maps\n" - "1: 1/8 downscaled sun shadow maps\n" - "2: 1/16 downscaled sun shadow maps\n" - ); - REGISTER_CVAR3("r_VolumetricFogReprojectionMode", CV_r_VolumetricFogReprojectionMode, 1, VF_NULL, - "Set the mode of ghost reduction for temporal reprojection.\n" - "0: conservative\n" - "1: advanced" - ); - REGISTER_CVAR3("r_VolumetricFogMinimumLightBulbSize", CV_r_VolumetricFogMinimumLightBulbSize, 0.4f, VF_NULL, - "Adjust the minimum size threshold for light attenuation bulb size. Small bulb size causes the light flicker." - ); - - REGISTER_CVAR2("r_ResolutionScale", &CV_r_ResolutionScale, CV_r_ResolutionScale, VF_NULL, - "Scales the resolution for better performance. A value of 1 indicates no scaling.\n" - "Minimum value 0.25: Scale resolution by 25% in width and height (retains the aspect ratio).\n" - "Maximum value 4: Scale resolution by 400%\n" - ); - - REGISTER_CVAR3_CB("r_GPUParticleDepthCubemapResolution", CV_r_CubeDepthMapResolution, 256, VF_EXPERIMENTAL, - "The resolution for the cubemaps used by the cubemap depth collision feature for GPU particles", - OnChange_CV_r_CubeDepthMapResolution); - - REGISTER_CVAR3("r_SkipNativeUpscale", CV_r_SkipNativeUpscale, 0, VF_NULL, - "Renders to the back buffer during the final post processing step and skips the native upscale.\n" - "Used when a second upscale already exists to avoid having two upscales.\n" - "0: Does not skip native upscale. \n" - "1: Skips native upscale." - ); - - REGISTER_CVAR3_CB("r_SkipRenderComposites", CV_r_SkipRenderComposites, 0, VF_NULL, - "Skips the RenderComposites call for rendering Flares and Grain. Can be used as an\n" - "optimization to avoid a full screen render when these effects are not being used." - "0: Does not skip RenderComposites. \n" - "1: Skips RenderComposites", - OnChange_CV_r_SkipRenderComposites); - - REGISTER_CVAR3("r_minConsoleFontSize", CV_r_minConsoleFontSize, 19.0f, VF_NULL, - "Minimum size used for scaling the font when rendering the console" - ); - - REGISTER_CVAR3("r_maxConsoleFontSize", CV_r_maxConsoleFontSize, 24.0f, VF_NULL, - "Maximum size used for scaling the font when rendering the console" - ); - - REGISTER_CVAR3("r_linuxSkipWindowCreation", CV_r_linuxSkipWindowCreation, 0, VF_NULL, - "0: Create a rendering window like normal" - "1: (Linux Only) Skip window creation and only render to an offscreen pixel buffer surface. Screenshots can still be captured with r_GetScreenShot." - ); - - REGISTER_CVAR3("r_GraphicsTest00", CV_r_GraphicsTest00, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest01", CV_r_GraphicsTest01, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest02", CV_r_GraphicsTest02, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest03", CV_r_GraphicsTest03, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest04", CV_r_GraphicsTest04, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest05", CV_r_GraphicsTest05, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest06", CV_r_GraphicsTest06, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest07", CV_r_GraphicsTest07, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest08", CV_r_GraphicsTest08, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - REGISTER_CVAR3("r_GraphicsTest09", CV_r_GraphicsTest09, 0, VF_DEV_ONLY, "Graphics programmers: Use in your code for misc graphics tests/debugging."); - -#ifndef NULL_RENDERER - AZ::Debug::DrillerManager* drillerManager = nullptr; - EBUS_EVENT_RESULT(drillerManager, AZ::ComponentApplicationBus, GetDrillerManager); - if (drillerManager && !gEnv->IsEditor()) - { - // Create the VRAM driller - m_vramDriller = aznew Render::Debug::VRAMDriller(); - m_vramDriller->CreateAllocationRecords(false, false, false); - drillerManager->Register(m_vramDriller); - - // Register categories and subcategories - Render::Debug::VRAMSubCategoryType textureSubcategories; - textureSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_TEXTURE_TEXTURE, "Texture Assets")); - textureSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_TEXTURE_RENDERTARGET, "Rendertargets")); - textureSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_TEXTURE_DYNAMIC, "Dynamic Textures")); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterCategory, Render::Debug::VRAM_CATEGORY_TEXTURE, "Texture", textureSubcategories); - - Render::Debug::VRAMSubCategoryType meshSubcategories; - meshSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_BUFFER_VERTEX_BUFFER, "Vertex Buffers")); - meshSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_BUFFER_INDEX_BUFFER, "Index Buffers")); - meshSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_BUFFER_CONSTANT_BUFFER, "Constant Buffers")); - meshSubcategories.push_back(Render::Debug::VRAMSubcategory(Render::Debug::VRAM_SUBCATEGORY_BUFFER_OTHER_BUFFER, "Other Buffers")); - EBUS_EVENT(Render::Debug::VRAMDrillerBus, RegisterCategory, Render::Debug::VRAM_CATEGORY_BUFFER, "Buffer", meshSubcategories); - } - - m_DevMan.Init(); -#endif - - m_cClearColor = ColorF(0, 0, 0, 128.0f / 255.0f); // 128 is default GBuffer value - m_clearBackground = false; - m_pDefaultFont = NULL; - m_TexGenID = 1; - m_VSync = CV_r_vsync; -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - m_overrideRefreshRate = CV_r_overrideRefreshRate; - m_overrideScanlineOrder = CV_r_overrideScanlineOrder; -#endif - m_Features = 0; - m_bVendorLibInitialized = false; - - // Initialize SThreadInfo and PerFrameParameters - for (uint32 id = 0; id < RT_COMMAND_BUF_COUNT; ++id) - { - memset(&m_RP.m_TI[id].m_perFrameParameters, 0, sizeof(PerFrameParameters)); - m_RP.m_TI[id].m_nFrameID = -2; - m_RP.m_TI[id].m_FS.m_bEnable = true; - } - - m_bPauseTimer = 0; - m_fPrevTime = -1.0f; - - m_CurFontColor = Col_White; - - m_bUseHWSkinning = CV_r_usehwskinning != 0; - - m_bSwapBuffers = true; - -#if defined(_DEBUG) && defined(WIN32) - if (CV_r_printmemoryleaks) - { - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - } -#endif - - m_nUseZpass = CV_r_usezpass; - - m_nShadowPoolHeight = m_nShadowPoolWidth = 0; - - m_cloudShadowTexId = 0; - m_cloudShadowSpeed = Vec3(0, 0, 0); - m_cloudShadowTiling = 1; - m_cloudShadowInvert = false; - m_cloudShadowBrightness = 1; - - m_nGPUs = 1; - - //assert(!(FOB_MASK_AFFECTS_MERGING & 0xffff)); - //assert(sizeof(CRenderObject) == 256); -#if !defined(PLATFORM_64BIT) && !defined(ANDROID) - // Disabled this check for ShaderCache Gen, it is only a performacne thingy for last gen consoles anyway - //STATIC_CHECK(sizeof(CRenderObject) == 128, CRenderObject); -#endif - STATIC_CHECK(!(FOB_MASK_AFFECTS_MERGING & 0xffff), FOB_MASK_AFFECTS_MERGING); - - if (!g_pSDynTexture_PoolAlloc) - { - g_pSDynTexture_PoolAlloc = new SDynTexture_PoolAlloc(stl::FHeap().FreeWhenEmpty(true)); - } - - //m_RP.m_VertPosCache.m_nBufSize = 500000 * sizeof(Vec3); - //m_RP.m_VertPosCache.m_pBuf = new byte [gRenDev->m_RP.m_VertPosCache.m_nBufSize]; - - m_pDefaultMaterial = NULL; - m_pTerrainDefaultMaterial = NULL; - - m_ViewMatrix.SetIdentity(); - m_CameraMatrix.SetIdentity(); - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_CameraZeroMatrix[i].SetIdentity(); - } - - for (int i = 0; i < MAX_NUM_VIEWPORTS; ++i) - { - for (int j = 0; j < 2; ++j) - { - m_PreviousFrameMatrixSets[i][j].m_ViewMatrix.SetIdentity(); - m_PreviousFrameMatrixSets[i][j].m_ProjMatrix.SetIdentity(); - m_PreviousFrameMatrixSets[i][j].m_ViewProjMatrix.SetIdentity(); - m_PreviousFrameMatrixSets[i][j].m_ViewNoTranslateMatrix.SetIdentity(); - m_PreviousFrameMatrixSets[i][j].m_ViewProjNoTranslateMatrix.SetIdentity(); - m_PreviousFrameMatrixSets[i][j].m_WorldViewPosition.zero(); - } - } - - m_CameraMatrixNearest.SetIdentity(); - - m_ProjMatrix.SetIdentity(); - m_TranspOrigCameraProjMatrix.SetIdentity(); - m_ViewProjMatrix.SetIdentity(); - m_ViewProjNoTranslateMatrix.SetIdentity(); - m_ViewProjInverseMatrix.SetIdentity(); - m_IdentityMatrix.SetIdentity(); - - m_TemporalJitterClipSpace = Vec4(0.0f); - - m_RP.m_nZOcclusionBufferID = -1; - - m_RP.m_nCurrResolveBounds[0] = m_RP.m_nCurrResolveBounds[1] = m_RP.m_nCurrResolveBounds[2] = m_RP.m_nCurrResolveBounds[3] = 0; - - for (int i = 0; i < SIZEOF_ARRAY(m_TempMatrices); i++) - { - for (int j = 0; j < SIZEOF_ARRAY(m_TempMatrices[0]); j++) - { - m_TempMatrices[i][j].SetIdentity(); - } - } - - CParserBin::m_bParseFX = true; - //CParserBin::m_bEmbeddedSearchInfo = false; - if (gEnv->IsEditor()) - { - CParserBin::m_bEditable = true; - } -#ifndef CONSOLE_CONST_CVAR_MODE - CV_e_DebugTexelDensity = 0; -#endif - m_nFlushAllPendingTextureStreamingJobs = 0; - m_fTexturesStreamingGlobalMipFactor = 0.f; - - m_fogCullDistance = 0.0f; - - m_pDebugRenderNode = NULL; - - m_bCollectDrawCallsInfo = false; - m_bCollectDrawCallsInfoPerNode = false; - - m_nMeshPoolTimeoutCounter = nMeshPoolMaxTimeoutCounter; - - // Init Thread Safe Worker Containers - threadID nThreadId = CryGetCurrentThreadId(); - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_RP.m_arrCustomShadowMapFrustumData[i].Init(); - m_RP.m_arrCustomShadowMapFrustumData[i].SetNonWorkerThreadID(nThreadId); - m_RP.m_TempObjects[i].Init(); - m_RP.m_TempObjects[i].SetNonWorkerThreadID(nThreadId); - } - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_RP.m_pRenderViews[i].reset(new CRenderView); - } - m_RP.m_pCurrentRenderView = m_RP.m_pRenderViews[0].get(); - m_RP.m_pCurrentFillView = m_RP.m_pRenderViews[0].get(); - m_pRT = new SRenderThread; - m_pRT->StartRenderThread(); - - m_ShadowFrustumMGPUCache.Init(); - RegisterSyncWithMainListener(&m_ShadowFrustumMGPUCache); - - // on console some float values in vertex formats can be 16 bit - iLog->Log("CRenderer sizeof(Vec2f16)=%" PRISIZE_T " sizeof(Vec3f16)=%" PRISIZE_T "", sizeof(Vec2f16), sizeof(Vec3f16)); - CRenderMesh::Initialize(); -} - -CRenderer::~CRenderer() -{ - //Code now moved to Release() - - CCryNameR::ReleaseNameTable(); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::PostInit() -{ - LOADING_TIME_PROFILE_SECTION; - - ////////////////////////////////////////////////////////////////////////// - // Initialize the shader system - ////////////////////////////////////////////////////////////////////////// - m_cEF.mfPostInit(); - - // Initialize asset messaging listener - m_assetListener.Connect(); - -#if !defined(NULL_RENDERER) - ////////////////////////////////////////////////////////////////////////// - // Load internal renderer font. - ////////////////////////////////////////////////////////////////////////// - if (gEnv->pCryFont) - { - m_pDefaultFont = gEnv->pCryFont->GetFont("default"); - if (!m_pDefaultFont) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Error getting default font"); - } - } - - if (!m_bShaderCacheGen) - { - // Create system resources while in fast load phase - gEnv->pRenderer->InitSystemResources(FRR_SYSTEM_RESOURCES); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// - -void CRenderer::Release() -{ - m_assetListener.Disconnect(); - - // Reminder for Andrey/AntonKap: this needs to be properly handled - //SAFE_DELETE(g_pSDynTexture_PoolAlloc) - //g_pSDynTexture_PoolAlloc = NULL; - - RemoveSyncWithMainListener(&m_ShadowFrustumMGPUCache); - m_ShadowFrustumMGPUCache.Release(); - CRenderMesh::ShutDown(); - CHWShader::mfCleanupCache(); - - if (!m_DevBufMan.Shutdown()) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR_DBGBRK, "could not free all buffers from CDevBufferMan!"); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_9 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - - if (g_shaderGeneralHeap) - { - g_shaderGeneralHeap->Release(); - } - - // Shutdown the VRAM driller - if (m_vramDriller) - { - EBUS_EVENT(Render::Debug::VRAMDrillerBus, UnregisterAllCategories); - - AZ::Debug::DrillerManager* drillerManager = nullptr; - EBUS_EVENT_RESULT(drillerManager, AZ::ComponentApplicationBus, GetDrillerManager); - if (drillerManager) - { - drillerManager->Unregister(m_vramDriller); - delete m_vramDriller; - m_vramDriller = nullptr; - } - } - - gRenDev = NULL; -} - -////////////////////////////////////////////////////////////////////// -void CRenderer::AddRenderDebugListener(IRenderDebugListener* pRenderDebugListener) -{ - stl::push_back_unique(m_listRenderDebugListeners, pRenderDebugListener); -} - -////////////////////////////////////////////////////////////////////// -void CRenderer::RemoveRenderDebugListener(IRenderDebugListener* pRenderDebugListener) -{ - stl::find_and_erase(m_listRenderDebugListeners, pRenderDebugListener); -} - -////////////////////////////////////////////////////////////////////// -void CRenderer::TextToScreenColor(int x, int y, float r, float g, float b, float a, const char* format, ...) -{ - // if(!cVars->e_text_info) - // return; - - char buffer[512]; - va_list args; - va_start(args, format); - if (azvsnprintf(buffer, sizeof(buffer), format, args) == -1) - { - buffer[sizeof(buffer) - 1] = 0; - } - va_end(args); - - WriteXY((int)(8 * x), (int)(6 * y), 1, 1, r, g, b, a, buffer); -} - -////////////////////////////////////////////////////////////////////// -void CRenderer::TextToScreen(float x, float y, const char* format, ...) -{ - // if(!cVars->e_text_info) - // return; - - char buffer[512]; - va_list args; - va_start(args, format); - if (azvsnprintf(buffer, sizeof(buffer), format, args) == -1) - { - buffer[sizeof(buffer) - 1] = 0; - } - va_end(args); - - WriteXY((int)(8 * x), (int)(6 * y), 1, 1, 1, 1, 1, 1, buffer); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::Draw2dText(float posX, float posY, const char* pStr, const SDrawTextInfo& ti) -{ - Draw2dTextWithDepth(posX, posY, 1.0f, pStr, ti); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::Draw2dTextWithDepth(float posX, float posY, float posZ, const char* pStr, const SDrawTextInfo& ti) -{ - IF (!m_pDefaultFont, 0) - { - return; - } - - IFFont* pFont = m_pDefaultFont; - - const float r = CLAMP(ti.color[0], 0.0f, 1.0f); - const float g = CLAMP(ti.color[1], 0.0f, 1.0f); - const float b = CLAMP(ti.color[2], 0.0f, 1.0f); - const float a = CLAMP(ti.color[3], 0.0f, 1.0f); - - STextDrawContext ctx; - ctx.SetBaseState(GS_NODEPTHTEST); - ctx.SetColor(ColorF(r, g, b, a)); - ctx.SetCharWidthScale(1.0f); - ctx.EnableFrame((ti.flags & eDrawText_Framed) != 0); - - if (ti.flags & eDrawText_Monospace) - { - if (ti.flags & eDrawText_FixedSize) - { - ctx.SetSizeIn800x600(false); - } - ctx.SetSize(Vec2(UIDRAW_TEXTSIZEFACTOR * ti.xscale, UIDRAW_TEXTSIZEFACTOR * ti.yscale)); - ctx.SetCharWidthScale(0.5f); - ctx.SetProportional(false); - - if (ti.flags & eDrawText_800x600) - { - ScaleCoordInternal(posX, posY); - } - } - else if (ti.flags & eDrawText_FixedSize) - { - ctx.SetSizeIn800x600(false); - ctx.SetSize(Vec2(UIDRAW_TEXTSIZEFACTOR * ti.xscale, UIDRAW_TEXTSIZEFACTOR * ti.yscale)); - ctx.SetProportional(true); - - if (ti.flags & eDrawText_800x600) - { - ScaleCoordInternal(posX, posY); - } - } - else - { - ctx.SetSizeIn800x600(true); - ctx.SetProportional(false); - ctx.SetCharWidthScale(0.5f); - ctx.SetSize(Vec2(UIDRAW_TEXTSIZEFACTOR * ti.xscale, UIDRAW_TEXTSIZEFACTOR * ti.yscale)); - } - - // align left/right/center - if (ti.flags & (eDrawText_Center | eDrawText_CenterV | eDrawText_Right)) - { - Vec2 textSize = pFont->GetTextSize(pStr, true, ctx); - - // If we're using virtual 800x600 coordinates, convert the text size from - // pixels to that before using it as an offset. - if (ctx.m_sizeIn800x600) - { - float width = 1.0f; - float height = 1.0f; - ScaleCoordInternal(width, height); - textSize.x /= width; - textSize.y /= height; - } - - if (ti.flags & eDrawText_Center) - { - posX -= textSize.x * 0.5f; - } - else if (ti.flags & eDrawText_Right) - { - posX -= textSize.x; - } - - if (ti.flags & eDrawText_CenterV) - { - posY -= textSize.y * 0.5f; - } - } - - // Pass flags so that overscan borders can be applied if necessary - ctx.SetFlags(ti.flags); - - pFont->DrawString(posX, posY, posZ, pStr, true, ctx); -} - -void CRenderer::PrintToScreen(float x, float y, float size, const char* buf) -{ - SDrawTextInfo ti; - ti.xscale = size * 0.5f / 8; - ti.yscale = size * 1.f / 8; - ti.color[0] = 1; - ti.color[1] = 1; - ti.color[2] = 1; - ti.color[3] = 1; - ti.flags = eDrawText_800x600 | eDrawText_2D; - Draw2dText(x, y, buf, ti); -} - -void CRenderer::WriteXY(int x, int y, float xscale, float yscale, float r, float g, float b, float a, const char* format, ...) -{ - ////////////////////////////////////////////////////////////////////// - // Write a string to the screen - ////////////////////////////////////////////////////////////////////// - - va_list args; - - char buffer[512]; - - // Check for the presence of a D3D device - // Format the string - va_start(args, format); - if (azvsnprintf(buffer, sizeof(buffer), format, args) == -1) - { - buffer[sizeof(buffer) - 1] = 0; - } - va_end(args); - - SDrawTextInfo ti; - ti.xscale = xscale; - ti.yscale = yscale; - ti.color[0] = r; - ti.color[1] = g; - ti.color[2] = b; - ti.color[3] = a; - ti.flags = eDrawText_800x600 | eDrawText_2D; - Draw2dText((float)x, (float)y, buffer, ti); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::DrawTextQueued(Vec3 pos, SDrawTextInfo& ti, const char* text) -{ - int nT = m_pRT->GetThreadList(); - if (text && !gEnv->IsDedicated()) - { - // ti.yscale is currently ignored, input struct can be refactored - - ColorB col(ColorF(ti.color[0], ti.color[1], ti.color[2], ti.color[3])); - - m_TextMessages[nT].PushEntry_Text(pos, col, ti.xscale, ti.flags, text); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::DrawTextQueued(Vec3 pos, SDrawTextInfo& ti, const char* format, va_list args) -{ - int nT = m_pRT->GetThreadList(); - if (format && !gEnv->IsDedicated()) - { - char str[512]; - - vsnprintf_s(str, sizeof(str), sizeof(str) - 1, format, args); - str[sizeof(str) - 1] = 0; - - // ti.yscale is currently ignored, input struct can be refactored - - ColorB col(ColorF(ti.color[0], ti.color[1], ti.color[2], ti.color[3])); - - m_TextMessages[nT].PushEntry_Text(pos, col, ti.xscale, ti.flags, str); - } -} - -////////////////////////////////////////////////////////////////////// -void CRenderer::EF_RenderTextMessages() -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - - CTextMessages& textMessage = m_TextMessages[m_RP.m_nFillThreadID]; - if (!textMessage.empty()) - { - RenderTextMessages(textMessage); - textMessage.Clear(false); - } -} - -void CRenderer::RenderTextMessages(CTextMessages& messages) -{ - bool prevFog = EnableFog(false); //save previous fog value returned by EnableFog - int vx, vy, vw, vh; - GetViewport(&vx, &vy, &vw, &vh); - - while (const CTextMessages::CTextMessageHeader* pEntry = messages.GetNextEntry()) - { - const CTextMessages::SText* pText = pEntry->CastTo_Text(); - - Vec3 vPos(0, 0, 0); - int nDrawFlags = 0; - const char* szText = 0; - Vec4 vColor(1, 1, 1, 1); - float fSize = 0; - - if (pText) - { - nDrawFlags = pText->m_nDrawFlags; - szText = pText->GetText(); - vPos = pText->m_vPos; - vColor = pText->m_Color.toVec4() * 1.0f / 255.0f; - fSize = pText->m_fFontSize; - } - - bool b800x600 = (nDrawFlags & eDrawText_800x600) != 0; - - float fMaxPosX = 100.0f; - float fMaxPosY = 100.0f; - - if (!b800x600) - { - fMaxPosX = (float)vw; - fMaxPosY = (float)vh; - } - - float sx, sy, sz; - - if (!(nDrawFlags & eDrawText_2D)) - { - float fDist = 1; //GetDistance(pTextInfo->pos,GetCamera().GetPosition()); - - float K = GetCamera().GetFarPlane() / fDist; - if (fDist > GetCamera().GetFarPlane() * 0.5) - { - vPos = GetCamera().GetPosition() + K * (vPos - GetCamera().GetPosition()); - } - - ProjectToScreen(vPos.x, vPos.y, vPos.z, &sx, &sy, &sz); - - if (!b800x600) - { - // ProjectToScreen() returns virtual screen values in range [0-100], while the Draw2dTextWithDepth() method expects screen coords. - // Correcting sx, sy values if not in virtual screen mode (sz is depth in range [0-1], and does not need to be altered). - sx = vw ? (sx / 100.f) * vw : sx; - sy = vh ? (sy / 100.f) * vh : sy; - } - } - else - { - if (b800x600) - { - // Make 2D coords in range 0-100 - sx = (vPos.x) / vw * 100; - sy = (vPos.y) / vh * 100; - } - else - { - sx = vPos.x; - sy = vPos.y; - } - - sz = vPos.z; - } - - if (sx >= 0 && sx <= fMaxPosX) - { - if (sy >= 0 && sy <= fMaxPosY) - { - if (sz >= 0 && sz <= 1) - { - // calculate size - float sizeX; - float sizeY; - if (nDrawFlags & eDrawText_FixedSize) - { - sizeX = fSize; - sizeY = fSize; - //sizeX = pTextInfo->font_size * 800.0f/vw; - //sizeY = pTextInfo->font_size * 500.0f/vh; - } - else - { - sizeX = sizeY = (1.0f - (float)(sz)) * 32.f * fSize; - sizeX *= 0.5f; - } - - if (szText) - { - // print - SDrawTextInfo ti; - ti.flags = nDrawFlags; - ti.color[0] = vColor.x; - ti.color[1] = vColor.y; - ti.color[2] = vColor.z; - ti.color[3] = vColor.w; - ti.xscale = sizeX; - ti.yscale = sizeY; - if (nDrawFlags & eDrawText_DepthTest) - { - sz = 1.0f - 2.0f * sz; - } - else - { - sz = 1.0f; - } - if (b800x600) - { - Draw2dTextWithDepth(0.01f * 800 * sx, 0.01f * 600 * sy, sz, szText, ti); - } - else - { - Draw2dTextWithDepth(sx, sy, sz, szText, ti); - } - } - } - } - } - } - - //If fog was enabled before we disabled it here, re-enable it - if (prevFog) - { - EnableFog(true); - } -} - -void CRenderer::RT_RenderTextMessages() -{ - ASSERT_IS_RENDER_THREAD(m_pRT) - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_RENDERER); - AZ_TRACE_METHOD(); - - int nT = m_pRT->GetThreadList(); - - if (gEnv->IsDedicated() || (m_pRT && m_pRT->m_eVideoThreadMode != SRenderThread::eVTM_Disabled)) - { - m_TextMessages[nT].Clear(); - return; - } - - bool resetTextMessages = true; - - // If stereo is enabled then we don't want to reset the flush position UNLESS we're rendering the second eye. Otherwise, - // the text will only get drawn to the first eye. - if (gEnv->pRenderer->IsStereoEnabled()) - { - if (gEnv->pRenderer->GetIStereoRenderer()->GetStatus() == IStereoRenderer::Status::kRenderingFirstEye) - { - resetTextMessages = false; - } - } - - RenderTextMessages(m_TextMessages[nT]); - m_TextMessages[nT].Clear(!resetTextMessages); -} - -#if !defined(LINUX) && !defined(APPLE) -#pragma pack (push) -#pragma pack (1) -typedef struct -{ - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -} TargaHeader_t; -#pragma pack (pop) -#else -typedef struct -{ - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index _PACK, colormap_length _PACK; - unsigned char colormap_size; - unsigned short x_origin _PACK, y_origin _PACK, width _PACK, height _PACK; - unsigned char pixel_size, attributes; -} TargaHeader_t; -#endif - -bool CRenderer::SaveTga(unsigned char* sourcedata, int sourceformat, int w, int h, const char* filename, bool flip) const -{ - //assert(0); - // return CImage::SaveTga(sourcedata,sourceformat,w,h,filename,flip); - - if (flip) - { - int size = w * (sourceformat / 8); - unsigned char* tempw = new unsigned char[size]; - unsigned char* src1 = sourcedata; - unsigned char* src2 = sourcedata + (w * (sourceformat / 8)) * (h - 1); - for (int k = 0; k < h / 2; k++) - { - memcpy(tempw, src1, size); - memcpy(src1, src2, size); - memcpy(src2, tempw, size); - src1 += size; - src2 -= size; - } - delete[] tempw; - } - - - unsigned char* oldsourcedata = sourcedata; - - if (sourceformat == FORMAT_8_BIT) - { - unsigned char* desttemp = new unsigned char[w * h * 3]; - memset(desttemp, 0, w * h * 3); - - unsigned char* destptr = desttemp; - unsigned char* srcptr = sourcedata; - - unsigned char col; - - for (int k = 0; k < w * h; k++) - { - col = *srcptr++; - *destptr++ = col; - *destptr++ = col; - *destptr++ = col; - } - - sourcedata = desttemp; - - sourceformat = FORMAT_24_BIT; - } - - TargaHeader_t header; - - memset(&header, 0, sizeof(header)); - header.image_type = 2; - header.width = w; - header.height = h; - header.pixel_size = sourceformat; - - unsigned char* data = new unsigned char[w * h * (sourceformat >> 3)]; - unsigned char* dest = data; - unsigned char* source = sourcedata; - - //memcpy(dest,source,w*h*(sourceformat>>3)); - - for (int ax = 0; ax < h; ax++) - { - for (int by = 0; by < w; by++) - { - unsigned char r, g, b, a; - r = *source; - source++; - g = *source; - source++; - b = *source; - source++; - if (sourceformat == FORMAT_32_BIT) - { - a = *source; - source++; - } - *dest = b; - dest++; - *dest = g; - dest++; - *dest = r; - dest++; - if (sourceformat == FORMAT_32_BIT) - { - *dest = a; - dest++; - } - } - } - - AZ::IO::HandleType fileHandle = fxopen(filename, "wb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - //("Cannot save %s\n",filename); - delete[] data; - return (false); - } - - if (!gEnv->pFileIO->Write(fileHandle, &header, sizeof(header))) - { - //CLog::LogToFile("Cannot save %s\n",filename); - delete[] data; - gEnv->pFileIO->Close(fileHandle); - return (false); - } - - if (!gEnv->pFileIO->Write(fileHandle, data, w * h * (sourceformat >> 3))) - { - //CLog::LogToFile("Cannot save %s\n",filename); - delete[] data; - gEnv->pFileIO->Close(fileHandle); - return (false); - } - - gEnv->pFileIO->Close(fileHandle); - - delete[] data; - if (sourcedata != oldsourcedata) - { - delete[] sourcedata; - } - - - return (true); -} - -//================================================================ - -void CRenderer::EF_ReleaseInputShaderResource(SInputShaderResources* pRes) -{ - pRes->Cleanup(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -//#include "../Common/Character/CryModel.h" - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_10 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -void CRenderer::ForceSwapBuffers() -{ - m_pRT->RC_ForceSwapBuffers(); - ForceFlushRTCommands(); -} - -// Initializes the default textures as well as texture semantics -void CRenderer::InitTexturesSemantics() -{ - CTextureManager::Instance()->LoadMaterialTexturesSemantics(); -} - -void CRenderer::InitSystemResources([[maybe_unused]] int nFlags) -{ - LOADING_TIME_PROFILE_SECTION; - if (!m_bSystemResourcesInit || m_bDeviceLost == 2) - { - iLog->Log("*** Init system render resources ***"); - - bool bPrecache = CTexture::s_bPrecachePhase; - CTexture::s_bPrecachePhase = false; - - ForceFlushRTCommands(); - m_cEF.mfPreloadBinaryShaders(); - m_cEF.mfLoadBasicSystemShaders(); - m_cEF.mfLoadDefaultSystemShaders(); - - // The following two lines will initiate the Texture manager instance and load all - // default textures and create engine textures - CTextureManager::Instance()->Init(); - CTexture::LoadDefaultSystemTextures(); - - m_pRT->RC_CreateRenderResources(); - m_pRT->RC_PrecacheDefaultShaders(); - m_pRT->RC_CreateSystemTargets(); - ForceFlushRTCommands(); - - CTexture::s_bPrecachePhase = bPrecache; - - if (m_bDeviceLost == 2) - { - m_bDeviceLost = 0; - } - m_bSystemResourcesInit = 1; - } -} - -void CRenderer::FreeResources(int nFlags) -{ - if (iLog) - { - iLog->Log("*** Start clearing render resources ***"); - } - - if (m_bEditor) - { - return; - } - - CTimeValue tBegin = gEnv->pTimer->GetAsyncTime(); - - // Throughout this function, we are queuing up a lot of work to execute on the render thread while also manipulating - // global state on both the render and main threads. We need to call ForceFlushRTCommands to synchronize the main and - // render threads whenever we are manipulating global state on either of these threads. - ForceFlushRTCommands(); - - AZ::RenderNotificationsBus::Broadcast(&AZ::RenderNotifications::OnRendererFreeResources, nFlags); - -#if !defined(_RELEASE) - ClearDrawCallsInfo(); -#endif - CHWShader::mfFlushPendedShadersWait(-1); - - EF_ReleaseDeferredData(); - - if (nFlags & FRR_FLUSH_TEXTURESTREAMING) - { - m_pRT->RC_FlushTextureStreaming(true); - } - - if (nFlags & FRR_DELETED_MESHES) - { - for (size_t i = 0; i < MAX_RELEASED_MESH_FRAMES; ++i) - { - m_pRT->RC_ForceMeshGC(false, false); - } - ForceFlushRTCommands(); - } - - if (nFlags & FRR_SHADERS) - { - gRenDev->m_cEF.ShutDown(); - } - - if (nFlags & FRR_RP_BUFFERS) - { - ForceFlushRTCommands(); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - TArray& storage = CREClientPoly::m_PolysStorage[i][j]; - storage.SetUse(storage.Capacity()); - for (size_t poly = 0, polyCount = storage.Capacity(); poly != polyCount; ++poly) - { - if (storage[poly]) - { - storage[poly]->Release(false); - } - } - storage.Free(); - - m_RP.m_SMFrustums[i][j].Free(); - m_RP.m_SMCustomFrustumIDs[i][j].Free(); - m_RP.m_DLights[i][j].Free(); - m_RP.m_DeferredDecals[i][j].clear(); - } - - m_RP.m_arrCustomShadowMapFrustumData[i].clear(); - m_RP.m_fogVolumeContibutionsData[i].clear(); - } - - for (int i = 0; i < sizeof(m_RP.m_RIs) / sizeof(m_RP.m_RIs[0]); ++i) - { - m_RP.m_RIs[i].Free(); - } - - stl::for_each_array(m_RP.m_SysVertexPool, stl::container_freer()); - stl::for_each_array(m_RP.m_SysIndexPool, stl::container_freer()); - - // Reset render views - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_RP.m_pRenderViews[i]->FreeRenderItems(); - } - - for (ShadowFrustumListsCache::iterator it = m_FrustumsCache.begin(); - it != m_FrustumsCache.end(); ++it) - { - SAFE_DELETE(it->second); - } - } - - if (nFlags & (FRR_SYSTEM | FRR_OBJECTS)) - { - CMotionBlur::FreeData(); - FurBendData::Get().FreeData(); - - for (int i = 0; i < 3; ++i) - { - m_SkinningDataPool[i].FreePoolMemory(); - } - - ForceFlushRTCommands(); - - // Get object pool range - CRenderObject* pObjPoolStart = &m_RP.m_ObjectsPool[0]; - CRenderObject* pObjPoolEnd = &m_RP.m_ObjectsPool[m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT]; - - // Delete all items that have not been allocated from the object pool - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_RP.m_TempObjects[i].clear(SDeleteNonePoolRenderObjs(pObjPoolStart, pObjPoolEnd)); - } - } - - if (nFlags & FRR_TEXTURES) - { - // Release the system textures on the render thread and then force that task to be completed - // before shutting down the texture system - m_pRT->RC_ReleaseSystemTextures(); - ForceFlushRTCommands(); - - CTexture::ShutDown(); - } - - if (nFlags & FRR_OBJECTS) - { - for (uint32 j = 0; j < RT_COMMAND_BUF_COUNT; j++) - { - m_RP.m_TempObjects[j].clear(); - } - if (m_RP.m_ObjectsPool) - { - for (int j = 0; j < (int)(m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT); j++) - { - CRenderObject* pRendObj = &m_RP.m_ObjectsPool[j]; - pRendObj->~CRenderObject(); - } - - CryModuleMemalignFree(m_RP.m_ObjectsPool); - m_RP.m_ObjectsPool = NULL; - SAFE_DELETE(m_RP.m_pIdendityRenderObject); - m_RP.m_nNumObjectsInPool = 0; - } - } - - if (nFlags == FRR_ALL) - { - ForceFlushRTCommands(); - CRendElementBase::ShutDown(); - } - else - if (nFlags & FRR_RENDERELEMENTS) - { - CRendElement::Cleanup(); - } - - if (nFlags & FRR_POST_EFFECTS) - { - m_pRT->RC_ReleasePostEffects(); - ForceFlushRTCommands(); - } - - if (nFlags & FRR_SYSTEM_RESOURCES) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - stl::free_container(m_RP.SShadowFrustumToRenderList[i]); - } - - // Free sprite vertices (indices are packed into the same buffer so no need to free them explicitly); - CryModuleMemalignFree(m_pSpriteVerts); - m_pSpriteVerts = NULL; - m_pSpriteInds = NULL; - - m_p3DEngineCommon.m_RainOccluders.Release(true); - m_p3DEngineCommon.m_CausticInfo.Release(); - - m_pRT->RC_UnbindResources(); - m_pRT->RC_ResetGlass(); - m_pRT->RC_ForceMeshGC(false, false); - m_cEF.mfReleaseSystemShaders(); - ForceFlushRTCommands(); - - m_pRT->RC_ReleaseRenderResources(); - ForceFlushRTCommands(); - - if (m_pPostProcessMgr) - { - m_pPostProcessMgr->ReleaseResources(); - } - ForceFlushRTCommands(); - - m_pRT->RC_FlushTextureStreaming(true); - ForceFlushRTCommands(); - - m_pRT->RC_ReleaseSystemTextures(); - ForceFlushRTCommands(); - - m_pRT->RC_UnbindTMUs(); - - // This function calls FlushAndWait internally in order to synchronize the main and render threads - CRendElement::Cleanup(); - - // sync dev buffer only once per frame, to prevent syncing to the currently rendered frame - // which would result in a deadlock - if (nFlags & (FRR_SYSTEM_RESOURCES | FRR_DELETED_MESHES)) - { - m_pRT->RC_DevBufferSync(); - ForceFlushRTCommands(); - } - - PrintResourcesLeaks(); - - if (!m_bDeviceLost) - { - m_bDeviceLost = 2; - } - m_bSystemResourcesInit = 0; - } - - - - // free flare queries - CRELensOptics::ClearResources(); - - if ((nFlags & FRR_RESTORE) && !(nFlags & FRR_SYSTEM)) - { - m_cEF.mfInit(); - } - - CTimeValue tDeltaTime = gEnv->pTimer->GetAsyncTime() - tBegin; - if (iLog) - { - iLog->Log("*** Clearing render resources took %.1f msec ***", tDeltaTime.GetMilliSeconds()); - } -} - -Vec2 CRenderer::SetViewportDownscale(float xscale, float yscale) -{ -#ifdef WIN32 - // refuse to downscale in editor or if MSAA is enabled - if (gEnv->IsEditor() || m_RP.IsMSAAEnabled()) - { - m_ReqViewportScale = Vec2(1, 1); - return m_ReqViewportScale; - } - - // PC can have awkward resolutions. When setting to full scale, take it as literal (below rounding - // to multiple of 8 might not work as intended for some resolutions). - if (xscale >= 1.0f && yscale >= 1.0f) - { - m_ReqViewportScale = Vec2(1, 1); - return m_ReqViewportScale; - } -#endif - - float fWidth = float(GetWidth()); - float fHeight = float(GetHeight()); - - int xres = int(fWidth * xscale); - int yres = int(fHeight * yscale); - - // clamp to valid value - xres = CLAMP(xres, 128, GetWidth()); - yres = CLAMP(yres, 128, GetHeight()); - - // round down to multiple of 8 - xres &= ~0x7; - yres &= ~0x7; - - m_ReqViewportScale.x = float(xres) / fWidth; - m_ReqViewportScale.y = float(yres) / fHeight; - - return m_ReqViewportScale; -} - -EScreenAspectRatio CRenderer::GetScreenAspect(int nWidth, int nHeight) -{ - EScreenAspectRatio eSA = eAspect_Unknown; - - float fNeed16_9 = 16.0f / 9.0f; - float fNeed16_10 = 16.0f / 10.0f; - float fNeed4_3 = 4.0f / 3.0f; - - float fCur = (float)nWidth / (float)nHeight; - if (fabs(fCur - fNeed16_9) < 0.1f) - { - eSA = eAspect_16_9; - } - - if (fabs(fCur - fNeed4_3) < 0.1f) - { - eSA = eAspect_4_3; - } - - if (fabs(fCur - fNeed16_10) < 0.1f) - { - eSA = eAspect_16_10; - } - - return eSA; -} - -bool CRenderer::WriteTGA(const byte* dat, int wdt, int hgt, const char* name, int src_bits_per_pixel, int dest_bits_per_pixel) -{ - return ::WriteTGA(dat, wdt, hgt, name, src_bits_per_pixel, dest_bits_per_pixel); -} - -bool CRenderer::WriteDDS([[maybe_unused]] const byte* dat, [[maybe_unused]] int wdt, [[maybe_unused]] int hgt, [[maybe_unused]] int Size, [[maybe_unused]] const char* nam, [[maybe_unused]] ETEX_Format eFDst, [[maybe_unused]] int NumMips) -{ -#if (defined(WIN32) || defined(WIN64)) && !defined(NULL_RENDERER) - bool bRet = true; - - byte* data = NULL; - if (Size == 3) - { - data = new byte[wdt * hgt * 4]; - for (int i = 0; i < wdt * hgt; i++) - { - data[i * 4 + 0] = dat[i * 3 + 0]; - data[i * 4 + 1] = dat[i * 3 + 1]; - data[i * 4 + 2] = dat[i * 3 + 2]; - data[i * 4 + 3] = 255; - } - dat = data; - } - char name[256]; - fpStripExtension(nam, name); - cry_strcat(name, ".dds"); - - bool bMips = false; - if (NumMips != 1) - { - bMips = true; - } - int nDxtSize; - byte* dst = CTexture::Convert(dat, wdt, hgt, NumMips, eTF_R8G8B8A8, eFDst, nDxtSize, true); - if (dst) - { - ::WriteDDS(dst, wdt, hgt, 1, name, eFDst, NumMips, eTT_2D); - delete[] dst; - } - if (data) - { - delete[] data; - } - - return bRet; -#else - return false; -#endif -} - -void CRenderer::EF_SetShaderMissCallback(ShaderCacheMissCallback callback) -{ - m_cEF.m_ShaderCacheMissCallback = callback; -} - -const char* CRenderer::EF_GetShaderMissLogPath() -{ - return m_cEF.m_ShaderCacheMissPath.c_str(); -} - -string* CRenderer::EF_GetShaderNames(int& nNumShaders) -{ - nNumShaders = m_cEF.m_ShaderNames.size(); - return nNumShaders ? &m_cEF.m_ShaderNames[0] : NULL; -} - -IShader* CRenderer::EF_LoadShader([[maybe_unused]] const char* name, [[maybe_unused]] int flags, [[maybe_unused]] uint64 nMaskGen) -{ -#ifdef NULL_RENDERER - return m_cEF.s_DefaultShader; -#else - return m_cEF.mfForName(name, flags, NULL, nMaskGen); -#endif -} - -void CRenderer::EF_SetShaderQuality(EShaderType eST, EShaderQuality eSQ) -{ - m_pRT->RC_SetShaderQuality(eST, eSQ); - - if (gEnv->p3DEngine) - { - gEnv->p3DEngine->GetMaterialManager()->RefreshMaterialRuntime(); - } -} - -uint64 CRenderer::EF_GetRemapedShaderMaskGen(const char* name, uint64 nMaskGen, bool bFixup) -{ - return m_cEF.mfGetRemapedShaderMaskGen(name, nMaskGen, bFixup); -} - -uint64 CRenderer::EF_GetShaderGlobalMaskGenFromString(const char* szShaderName, const char* szShaderGen, uint64 nMaskGen) -{ - if (!m_cEF.mfUsesGlobalFlags(szShaderName)) - { - return nMaskGen; - } - - return m_cEF.mfGetShaderGlobalMaskGenFromString(szShaderGen); -} - -// inverse of EF_GetShaderMaskGenFromString -AZStd::string CRenderer::EF_GetStringFromShaderGlobalMaskGen(const char* szShaderName, uint64 nMaskGen) -{ - if (!m_cEF.mfUsesGlobalFlags(szShaderName)) - { - return "\0"; - } - - return m_cEF.mfGetShaderBitNamesFromGlobalMaskGen(nMaskGen); -} - -SShaderItem CRenderer::EF_LoadShaderItem([[maybe_unused]] const char* szName, [[maybe_unused]] bool bShare, [[maybe_unused]] int flags, [[maybe_unused]] SInputShaderResources* Res, [[maybe_unused]] uint64 nMaskGen) -{ - LOADING_TIME_PROFILE_SECTION; - -#ifdef NULL_RENDERER - return m_cEF.s_DefaultShaderItem; -#else - return m_cEF.mfShaderItemForName(szName, bShare, flags, Res, nMaskGen); -#endif -} - -////////////////////////////////////////////////////////////////////////// -bool CRenderer::EF_ReloadFile_Request(const char* szFileName) -{ - // if its a source or destination texture, then post it into the queue to avoid render deadlocks: - if (IResourceCompilerHelper::IsSourceImageFormatSupported(szFileName)) - { - // Replace image extensions with .dds extensions. - char realName[MAX_PATH + 1]; - azstrncpy(realName, MAX_PATH, szFileName, MAX_PATH); - char* szExt = (char*)fpGetExtension(realName); - azstrncpy(szExt, MAX_PATH - (szExt - realName), ".dds", 4); - return CTexture::ReloadFile_Request(realName); // post in queue - } - else if (IResourceCompilerHelper::IsGameImageFormatSupported(szFileName)) - { - return CTexture::ReloadFile_Request(szFileName); // post in queue - } - - // the texture reader did not queue it, so try reloading it directly : - return EF_ReloadFile(szFileName); -} - -bool CRenderer::EF_ReloadFile(const char* szFileName) -{ - if (!szFileName) - { - return false; //might want to check this it hits - } - char realName[MAX_PATH + 1]; - azstrncpy(realName, MAX_PATH, szFileName, MAX_PATH); - const char* szExt = fpGetExtension(realName); - - if (IResourceCompilerHelper::IsSourceImageFormatSupported(szExt) || - IResourceCompilerHelper::IsGameImageFormatSupported(szExt)) //note: it was also looking for .pcx... removed it - { - CRY_ASSERT_MESSAGE(false, "You must call EF_ReloadFile_Request for texture assets."); - } - else if (szExt && !azstricmp(szExt, ".cgf")) - { - IStatObj* pStatObjectToReload = (gEnv && gEnv->p3DEngine) ? gEnv->p3DEngine->FindStatObjectByFilename(realName) : nullptr; - if (pStatObjectToReload) - { - pStatObjectToReload->Refresh(FRO_GEOMETRY | FRO_SHADERS | FRO_TEXTURES); - return true; - } - return false; - } - else if (szExt && (!azstricmp(szExt, ".cfx") || (!CV_r_shadersignoreincludeschanging && !azstricmp(szExt, ".cfi")))) - { - gRenDev->m_cEF.m_Bin.InvalidateCache(); - // This is a temporary fix so that shaders would reload during hot update. - bool bRet = gRenDev->m_cEF.mfReloadAllShaders(FRO_SHADERS, 0); - if (gEnv && gEnv->p3DEngine) - { - gEnv->p3DEngine->UpdateShaderItems(); - } - return bRet; - // return gRenDev->m_cEF.mfReloadFile(drn, nmf, FRO_SHADERS); - } -#if defined(USE_GEOM_CACHES) - else if (szExt && !azstricmp(szExt, ".cax")) - { - IGeomCache* pGeomCache = (gEnv && gEnv->p3DEngine) ? gEnv->p3DEngine->FindGeomCacheByFilename(realName) : nullptr; - if (pGeomCache) - { - pGeomCache->Reload(); - } - } -#endif //defined(USE_GEOM_CACHES) - return false; -} - -void CRenderer::EF_ReloadShaderFiles([[maybe_unused]] int nCategory) -{ - //gRenDev->m_cEF.mfLoadFromFiles(nCategory); -} - -void CRenderer::EF_ReloadTextures() -{ - CTexture::ReloadTextures(); -} - -_smart_ptr CRenderer::EF_LoadImage(const char* szFileName, uint32 nFlags) -{ - return CImageFile::mfLoad_file(szFileName, nFlags); -} - -bool CRenderer::EF_RenderEnvironmentCubeHDR(int size, Vec3& Pos, TArray& vecData) -{ - return CTexture::RenderEnvironmentCMHDR(size, Pos, vecData); -} - -int CRenderer::EF_LoadLightmap(const char* name) -{ - CTexture* tp = (CTexture*)EF_LoadTexture(name, FT_DONT_STREAM | FT_STATE_CLAMP | FT_NOMIPS); - if (tp->IsTextureLoaded()) - { - return tp->GetID(); - } - else - { - return -1; - } -} - -ITexture* CRenderer::EF_GetTextureByID(int Id) -{ - if (Id > 0) - { - CTexture* tp = CTexture::GetByID(Id); - if (tp) - { - return tp; - } - } - return NULL; -} - -ITexture* CRenderer::EF_GetTextureByName(const char* nameTex, uint32 flags) -{ - if (nameTex) - { - INDENT_LOG_DURING_SCOPE(true, "While trying to find texture '%s' flags=0x%x...", nameTex, flags); - - const char* ext = fpGetExtension(nameTex); - if (ext != 0 && (azstricmp(ext, ".tif") == 0 || azstricmp(ext, ".hdr") == 0 || azstricmp(ext, ".png") == 0)) - { - // for compilable files, register by the dds file name (to not load it twice) - char nameDDS[256]; - fpStripExtension(nameTex, nameDDS); - cry_strcat(nameDDS, ".dds"); - - return CTexture::GetByName(nameDDS, flags); - } - else - { - return CTexture::GetByName(nameTex, flags); - } - } - - return NULL; -} - -ITexture* CRenderer::EF_LoadTexture(const char* nameTex, const uint32 flags) -{ - if (nameTex) - { - INDENT_LOG_DURING_SCOPE(true, "While trying to load texture '%s' flags=0x%x...", nameTex, flags); - - //if its a source image format try to load the dds - const char* ext = fpGetExtension(nameTex); - if (ext != 0 && (azstricmp(ext, ".tif") == 0 || azstricmp(ext, ".hdr") == 0 || azstricmp(ext, ".png") == 0)) - { - // for compilable files, register by the dds file name (to not load it twice) - char nameDDS[256]; - fpStripExtension(nameTex, nameDDS); - cry_strcat(nameDDS, ".dds"); - -#if AZ_LOADSCREENCOMPONENT_ENABLED - if (GetISystem() && GetISystem()->GetGlobalEnvironment() && GetISystem()->GetGlobalEnvironment()->mMainThreadId == CryGetCurrentThreadId()) - { - EBUS_EVENT(LoadScreenBus, UpdateAndRender); - } -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - return CTexture::ForName(nameDDS, flags, eTF_Unknown); - } - else - { -#if AZ_LOADSCREENCOMPONENT_ENABLED - if (GetISystem() && GetISystem()->GetGlobalEnvironment() && GetISystem()->GetGlobalEnvironment()->mMainThreadId == CryGetCurrentThreadId()) - { - EBUS_EVENT(LoadScreenBus, UpdateAndRender); - } -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - return CTexture::ForName(nameTex, flags, eTF_Unknown); - } - } - - return NULL; -} - -ITexture* CRenderer::EF_LoadDefaultTexture(const char* nameTex) -{ - if (nameTex) - { - return CTextureManager::Instance()->GetDefaultTexture(nameTex); - } - return nullptr; -} - -ITexture* CRenderer::EF_LoadCubemapTexture(const char* nameTex, const uint32 flags) -{ - ITexture* cubeMap = EF_LoadTexture(nameTex, flags); - // Explicitly set the texture type for the texture for the cases where it is not loaded - // at this time but the renderer still tries to bind it. On devices running Metal not doing this - // causes the metal validation to fail as the texture uses black, a 2D texture, as a replacement - // for an unloaded cubemap. Now the texture can choose to use black cubemap instead and make - // the validation layer happy. - if (cubeMap) - { - cubeMap->SetTextureType(eTT_Cube); - } - return cubeMap; -} - -bool SShaderItem::Update() -{ - if (!(m_pShader->GetFlags() & EF_LOADED)) - { - return false; - } - if ((uint32)m_nTechnique > 1000 && m_nTechnique != -1) // HACK HACK HACK - { - CCryNameTSCRC Name(m_nTechnique); - if (!gRenDev->m_cEF.mfUpdateTechnik(*this, Name)) - { - return false; - } - } - - uint32 nPreprocessFlags = PostLoad(); - - // force the write to m_nPreprocessFlags to be last - // to ensure the main thread has all correct data when the shaderitem is used - // (m_nPreprocessFlags can indicate a not yet initialized shaderitem) - MemoryBarrier(); - m_nPreprocessFlags = nPreprocessFlags; - return true; -} - -bool SShaderItem::RefreshResourceConstants() -{ - return gRenDev->m_cEF.mfRefreshResourceConstants(*this); -} -void CRenderer::EF_StartEf(const SRenderingPassInfo& passInfo) -{ - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_RENDERER); - AZ_TRACE_METHOD(); - int i; - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = passInfo.ThreadID(); - int nR = passInfo.GetRecursiveLevel(); - assert(nR < MAX_REND_RECURSION_LEVELS); - if (nR == 0) - { - SRendItem::m_RecurseLevel[nThreadID] = -1; - CRenderView::CurrentFillView()->ClearRenderItems(); - - m_RP.m_TempObjects[nThreadID].resize(0); - m_nShadowGenId[nThreadID] = 0; - - //SG frustums - for (i = 0; i < MAX_SHADOWMAP_FRUSTUMS; i++) - { - SRendItem::m_ShadowsStartRI[nThreadID][i] = 0; - SRendItem::m_ShadowsEndRI[nThreadID][i] = 0; - } - - for (i = 0; i < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS); i++) - { - SRendItem::m_StartFrust[nThreadID][i] = 0; - SRendItem::m_EndFrust[nThreadID][i] = 0; - } - - // Clear all cached lists of shadow frustums - for (ShadowFrustumListsCache::iterator it = m_FrustumsCache.begin(); it != m_FrustumsCache.end(); ++it) - { - if (it->second) - { - it->second->Clear(); - } - } - - EF_RemovePolysFromScene(); - m_RP.m_fogVolumeContibutionsData[nThreadID].resize(0); - //If we clear these flags during the recursion pass, it causes flickering and popping of objects. - passInfo.GetRenderView()->PrepareForWriting(); - } - -#ifndef _RELEASE - if (nR >= MAX_REND_RECURSION_LEVELS) - { - CryLogAlways("nR (%d) >= MAX_REND_RECURSION_LEVELS (%d)\n", nR, MAX_REND_RECURSION_LEVELS); - __debugbreak(); // otherwise about to go out of bounds in the loop below - } -#endif - - m_RP.m_DeferredDecals[nThreadID][nR].clear(); - m_RP.m_isDeferrredNormalDecals[nThreadID][nR] = false; - - FurBendData::Get().OnBeginFrame(); - - CPostEffectsMgr* pPostEffectMgr = PostEffectMgr(); - - if (pPostEffectMgr) - { - pPostEffectMgr->OnBeginFrame(); - } - - SRendItem::m_RecurseLevel[nThreadID]++; - - EF_ClearLightsList(); - EF_ClearDeferredLightsList(); -} - -void CRenderer::RT_PostLevelLoading() -{ - int nThreadID = m_pRT->GetThreadList(); - m_RP.m_fogVolumeContibutionsData[nThreadID].reserve(2048); - - m_cEF.m_Bin.InvalidateCache(); - CHWShader::mfCleanupCache(); - CResFile::m_nMaxOpenResFiles = 4; -} - -void CRenderer::RT_DisableTemporalEffects() -{ - m_nDisableTemporalEffects = GetActiveGPUCount(); -} - -void CRenderer::DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const -{ - m_pRT->RC_DrawStringU(pFont, x, y, z, pStr, asciiMultiLine, ctx); -} - -void CRenderer::RT_CreateREPostProcess(CRendElementBase** re) -{ - *re = new CREPostProcess; -} - -IRenderElement* CRenderer::EF_CreateRE(EDataType edt) -{ - CRendElementBase* re = NULL; - switch (edt) - { - case eDATA_Mesh: - re = new CREMeshImpl; - break; - case eDATA_Imposter: - re = new CREImposter; - break; - case eDATA_HDRProcess: - re = new CREHDRProcess; - break; - - case eDATA_DeferredShading: - re = new CREDeferredShading; - break; - - case eDATA_OcclusionQuery: - re = new CREOcclusionQuery; - break; - - case eDATA_LensOptics: - re = new CRELensOptics; - break; - case eDATA_Cloud: - re = new CRECloud; - break; - case eDATA_Sky: - re = new CRESky; - break; - - case eDATA_HDRSky: - re = new CREHDRSky; - break; - - case eDATA_Beam: - re = new CREBeam; - break; - - case eDATA_PostProcess: - re = new CREPostProcess; - break; - - case eDATA_FogVolume: - re = new CREFogVolume; - break; - - case eDATA_WaterVolume: - re = new CREWaterVolume; - break; - - case eDATA_WaterOcean: - re = new CREWaterOcean; - break; - case eDATA_VolumeObject: - re = new CREVolumeObject; - break; -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) - case eDATA_PrismObject: - re = new CREPrismObject; - break; -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - - case eDATA_GameEffect: - re = new CREGameEffect; - break; -#if defined(USE_GEOM_CACHES) - case eDATA_GeomCache: - re = new CREGeomCache; - break; -#endif - case eDATA_Gem: - // For gems we return a base element which will be accessed through the IRenderElement interface. - // The gem is expected to provide a delegate that implement the IRenderElementDelegate interface - re = new CRendElementBase(); - break; - } - return re; -} - -void CRenderer::EF_RemovePolysFromScene() -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - - for (int i = 0; i < MAX_RECURSION_LEVELS; i++) - { - CREClientPoly::m_PolysStorage[m_RP.m_nFillThreadID][i].SetUse(0); - } - m_RP.m_SysVertexPool[m_RP.m_nFillThreadID].SetUse(0); - m_RP.m_SysIndexPool[m_RP.m_nFillThreadID].SetUse(0); -} - -CRenderObject* CRenderer::EF_AddPolygonToScene(SShaderItem& si, int numPts, const SVF_P3F_C4B_T2F* verts, const SPipTangents* tangs, CRenderObject* obj, const SRenderingPassInfo& passInfo, uint16* inds, int ninds, int nAW, const SRendItemSorter& rendItemSorter) -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = m_RP.m_nFillThreadID; - const uint32 nPersFlags = m_RP.m_TI[nThreadID].m_PersFlags; - - assert(si.m_pShader && si.m_pShaderResources); - if (!si.m_pShader || !si.m_pShaderResources) - { - Warning("CRenderer::EF_AddPolygonToScene without shader..."); - return NULL; - } - if (si.m_nPreprocessFlags == -1) - { - if (!si.Update()) - { - return obj; - } - } - - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - if (recursiveLevel < 0) - { - return NULL; - } - - int num = CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel].Num(); - CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel].GrowReset(1); - - CREClientPoly* pl = CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel][num]; - if (!pl) - { - pl = new CREClientPoly; - CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel][num] = pl; - } - - pl->m_Shader = si; - pl->m_sNumVerts = numPts; - pl->m_pObject = obj; - pl->m_nCPFlags = 0; - pl->rendItemSorter = rendItemSorter; - if (nAW) - { - pl->m_nCPFlags |= CREClientPoly::efAfterWater; - } - if (passInfo.IsShadowPass()) - { - pl->m_nCPFlags |= CREClientPoly::efShadowGen; - } - - int nSize = AZ::Vertex::Format(eVF_P3F_C4B_T2F).GetStride() * numPts; - int nOffs = m_RP.m_SysVertexPool[nThreadID].Num(); - SVF_P3F_C4B_T2F* vt = (SVF_P3F_C4B_T2F*)m_RP.m_SysVertexPool[nThreadID].GrowReset(nSize); - pl->m_nOffsVert = nOffs; - for (int i = 0; i < numPts; i++, vt++) - { - vt->xyz = verts[i].xyz; - vt->st = verts[i].st; - vt->color.dcolor = verts[i].color.dcolor; - } - if (tangs) - { - nSize = sizeof(SPipTangents) * numPts; - nOffs = m_RP.m_SysVertexPool[nThreadID].Num(); - SPipTangents* t = (SPipTangents*)m_RP.m_SysVertexPool[nThreadID].GrowReset(nSize); - pl->m_nOffsTang = nOffs; - for (int i = 0; i < numPts; i++, t++) - { - *t = tangs[i]; - } - } - else - { - pl->m_nOffsTang = -1; - } - - - pl->m_nOffsInd = m_RP.m_SysIndexPool[nThreadID].Num(); - - if (inds && ninds) - { - uint16* dstind = m_RP.m_SysIndexPool[nThreadID].Grow(ninds); - memcpy(dstind, inds, ninds * sizeof(uint16)); - pl->m_sNumIndices = ninds; - } - else - { - uint16* dstind = m_RP.m_SysIndexPool[nThreadID].Grow((numPts - 2) * 3); - for (int i = 0; i < numPts - 2; i++, dstind += 3) - { - dstind[0] = 0; - dstind[1] = i + 1; - dstind[2] = i + 2; - } - pl->m_sNumIndices = (numPts - 2) * 3; - } - - return obj; -} - -CRenderObject* CRenderer::EF_AddPolygonToScene(SShaderItem& si, CRenderObject* obj, const SRenderingPassInfo& passInfo, int numPts, int ninds, SVF_P3F_C4B_T2F*& verts, SPipTangents*& tangs, uint16*& inds, int nAW, [[maybe_unused]] const SRendItemSorter& rendItemSorter) -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = m_RP.m_nFillThreadID; - const uint32 nPersFlags = m_RP.m_TI[nThreadID].m_PersFlags; - - assert(si.m_pShader && si.m_pShaderResources); - if (!si.m_pShader || !si.m_pShaderResources) - { - Warning("CRenderer::EF_AddPolygonToScene without shader..."); - return NULL; - } - if (si.m_nPreprocessFlags == -1) - { - if (!si.Update()) - { - return obj; - } - } - - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); - - int num = CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel].Num(); - CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel].GrowReset(1); - - CREClientPoly* pl = CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel][num]; - if (!pl) - { - pl = new CREClientPoly; - CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel][num] = pl; - } - - pl->m_Shader = si; - pl->m_pObject = obj; - if (nAW) - { - pl->m_nCPFlags |= CREClientPoly::efAfterWater; - } - if (passInfo.IsShadowPass()) - { - pl->m_nCPFlags |= CREClientPoly::efShadowGen; - } - - ////////////////////////////////////////////////////////////////////////// - // allocate buffer space for caller to fill - - pl->m_sNumVerts = numPts; - pl->m_nOffsVert = m_RP.m_SysVertexPool[nThreadID].Num(); - pl->m_nOffsTang = m_RP.m_SysVertexPool[nThreadID].Num() + sizeof(SVF_P3F_C4B_T2F) * numPts; - m_RP.m_SysVertexPool[nThreadID].GrowReset((sizeof(SVF_P3F_C4B_T2F) + sizeof(SPipTangents)) * numPts); - verts = (SVF_P3F_C4B_T2F*)&m_RP.m_SysVertexPool[nThreadID][pl->m_nOffsVert]; - tangs = (SPipTangents*)&m_RP.m_SysVertexPool[nThreadID][pl->m_nOffsTang]; - - pl->m_sNumIndices = ninds; - pl->m_nOffsInd = m_RP.m_SysIndexPool[nThreadID].Num(); - inds = m_RP.m_SysIndexPool[nThreadID].Grow(ninds); - - ////////////////////////////////////////////////////////////////////////// - - return obj; -} - -void CRenderer::EF_AddClientPolys([[maybe_unused]] const SRenderingPassInfo& passInfo) -{ -#if !defined(NULL_RENDERER) - AZ_TRACE_METHOD(); - uint32 i; - CREClientPoly* pl; - - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = m_pRT->GetThreadList(); - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); - - const SThreadInfo& rTI = m_RP.m_TI[nThreadID]; - const uint32 nPersFlags = rTI.m_PersFlags; - - for (i = 0; i < CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel].Num(); i++) - { - pl = CREClientPoly::m_PolysStorage[nThreadID][recursiveLevel][i]; - - CShader* pShader = (CShader*)pl->m_Shader.m_pShader; - CShaderResources* const __restrict pShaderResources = static_cast(pl->m_Shader.m_pShaderResources); - SShaderTechnique* pTech = pl->m_Shader.GetTechnique(); - - uint32 nBatchFlags = FB_GENERAL; - - if (pl->m_Shader.m_nPreprocessFlags & FSPR_MASK) - { - passInfo.GetRenderView()->AddRenderItem(pl, pl->m_pObject, pl->m_Shader, EFSLIST_PREPROCESS, 0, FB_GENERAL, passInfo, pl->rendItemSorter); - } - - if (pShader->GetFlags() & EF_DECAL) // || pl->m_pObject && (pl->m_pObject->m_ObjFlags & FOB_DECAL)) - { - if (pTech && pTech->m_nTechnique[TTYPE_Z] > 0 && (pShader && (pShader->m_Flags & EF_SUPPORTSDEFERREDSHADING))) - { - nBatchFlags |= FB_Z; - } - - if (!passInfo.IsShadowPass() && !(pl->m_nCPFlags & CREClientPoly::efShadowGen)) - { - passInfo.GetRenderView()->AddRenderItem(pl, pl->m_pObject, pl->m_Shader, EFSLIST_DECAL, pl->m_nCPFlags & CREClientPoly::efAfterWater, nBatchFlags, passInfo, pl->rendItemSorter); - } - else if (passInfo.IsShadowPass() && (pl->m_nCPFlags & CREClientPoly::efShadowGen)) - { - passInfo.GetRenderView()->AddRenderItem(pl, pl->m_pObject, pl->m_Shader, EFSLIST_SHADOW_GEN, SG_SORT_GROUP, FB_GENERAL, passInfo, pl->rendItemSorter); - } - } - else - { - uint32 list = EFSLIST_GENERAL; - if (pl->m_pObject->m_fAlpha < 1.0f || (pShaderResources && pShaderResources->IsTransparent())) - { - list = EFSLIST_TRANSP; - } - nBatchFlags |= FB_TRANSPARENT; - passInfo.GetRenderView()->AddRenderItem(pl, pl->m_pObject, pl->m_Shader, list, pl->m_nCPFlags & CREClientPoly::efAfterWater, nBatchFlags, passInfo, pl->rendItemSorter); - } - } -#endif -} - - -// Dynamic lights -bool CRenderer::EF_IsFakeDLight(const CDLight* Source) -{ - if (!Source) - { - iLog->Log("Warning: EF_IsFakeDLight: NULL light source\n"); - return true; - } - - bool bIgnore = false; - if (Source->m_Flags & (DLF_FAKE)) - { - bIgnore = true; - } - - return bIgnore; -} - -void CRenderer::EF_CheckLightMaterial(CDLight* pLight, uint16 nRenderLightID, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - ASSERT_IS_MAIN_THREAD(m_pRT); - const int32 nThreadID = m_RP.m_nFillThreadID; - const int32 recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); - - if (!(m_RP.m_TI[nThreadID].m_PersFlags & RBPF_IMPOSTERGEN)) - { - // Add render element if light has mtl bound - IShader* pShader = pLight->m_Shader.m_pShader; - TArray* pRendElemBase = pShader ? pLight->m_Shader.m_pShader->GetREs(pLight->m_Shader.m_nTechnique) : 0; - if (pRendElemBase && !pRendElemBase->empty()) - { - pLight->m_pObject[recursiveLevel] = EF_GetObject_Temp(passInfo.ThreadID()); - pLight->m_pObject[recursiveLevel]->m_fAlpha = 1.0f; - pLight->m_pObject[recursiveLevel]->m_II.m_AmbColor = Vec3(0, 0, 0); - - SRenderObjData* pOD = EF_GetObjData(pLight->m_pObject[recursiveLevel], true, passInfo.ThreadID()); - - pOD->m_fTempVars[0] = 0; - pOD->m_fTempVars[1] = 0; - pOD->m_fTempVars[3] = pLight->m_fRadius; - pOD->m_nLightID = nRenderLightID; - - pLight->m_pObject[recursiveLevel]->m_II.m_AmbColor = pLight->m_Color; - pLight->m_pObject[recursiveLevel]->m_II.m_Matrix = pLight->m_ObjMatrix; - - CRendElementBase* pRE = pRendElemBase->Get(0); - const int32 nList = (pRE->mfGetType() != eDATA_LensOptics) ? EFSLIST_TRANSP : EFSLIST_LENSOPTICS; - - if (pRE->mfGetType() == eDATA_Beam) - { - pLight->m_Flags |= DLF_LIGHT_BEAM; - } - - int32 nAW; - if (OceanToggle::IsActive() && !OceanRequest::OceanIsEnabled()) - { - nAW = 1; - } - else - { - const float fWaterLevel = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : gEnv->p3DEngine->GetWaterLevel(); - const float fCamZ = m_RP.m_TI[nThreadID].m_cam.GetPosition().z; - nAW = ((fCamZ - fWaterLevel) * (pLight->m_Origin.z - fWaterLevel) > 0) ? 1 : 0; - } - - EF_AddEf(pRE, pLight->m_Shader, pLight->m_pObject[recursiveLevel], passInfo, nList, nAW, rendItemSorter); - } - } -} - -void CRenderer::EF_ADDDlight(CDLight* Source, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - if (!Source) - { - iLog->Log("Warning: EF_ADDDlight: NULL light source\n"); - return; - } - - ASSERT_IS_MAIN_THREAD(m_pRT) - - bool bIgnore = EF_IsFakeDLight(Source); - - int nThreadID = m_RP.m_nFillThreadID; - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); - - SRenderLight* pNew = NULL; - if (bIgnore) - { - Source->m_Id = -1; - } - else - { - assert((Source->m_Flags & DLF_LIGHTTYPE_MASK) != 0); - Source->m_Id = (int16)m_RP.m_DLights[nThreadID][recursiveLevel].Num(); - if (Source->m_Id >= 32) - { - Source->m_Id = -1; - return; - } - pNew = m_RP.m_DLights[nThreadID][recursiveLevel].AddIndex(1); - memcpy(pNew, Source, sizeof(SRenderLight)); - } - EF_PrecacheResource(Source, (m_RP.m_TI[nThreadID].m_cam.GetPosition() - Source->m_Origin).GetLengthSquared() / max(0.001f, Source->m_fRadius * Source->m_fRadius), 0.1f, 0, 0); -} - -bool CRenderer::EF_AddDeferredDecal(const SDeferredDecal& rDecal) -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - - int nThreadID = m_RP.m_nFillThreadID; - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); - if (recursiveLevel < 0) - { - iLog->Log("Warning: CRenderer::EF_AddDeferredDecal: decal adding before calling EF_StartEf"); - return false; - } - - if (m_RP.m_DeferredDecals[nThreadID][recursiveLevel].size() < 1024) - { - m_RP.m_DeferredDecals[nThreadID][recursiveLevel].push_back(rDecal); - int nLastElem = m_RP.m_DeferredDecals[nThreadID][recursiveLevel].size() - 1; - - SDeferredDecal& rDecalCopy = m_RP.m_DeferredDecals[nThreadID][recursiveLevel].at(nLastElem); - - ////////////////////////////////////////////////////////////////////////// - _smart_ptr pDecalMaterial = rDecalCopy.pMaterial; - if (pDecalMaterial == NULL) - { - AZ_WarningOnce("Renderer", pDecalMaterial == NULL, "Decal missing material."); - return false; - } - - SShaderItem& sItem = pDecalMaterial->GetShaderItem(0); - if (sItem.m_pShaderResources == NULL) - { - assert(0); - return false; - } - - if (SEfResTexture* pNormalRes0 = sItem.m_pShaderResources->GetTextureResource((uint16)EFTT_NORMALS)) - { - if (pNormalRes0->m_Sampler.m_pITex) - { - rDecalCopy.nFlags |= DECAL_HAS_NORMAL_MAP; - m_RP.m_isDeferrredNormalDecals[nThreadID][recursiveLevel] = true; - } - else - { - rDecalCopy.nFlags &= ~DECAL_HAS_NORMAL_MAP; - } - } - - if (SEfResTexture* pSpecularRes0 = sItem.m_pShaderResources->GetTextureResource((uint16)EFTT_SPECULAR)) - { - if (pSpecularRes0->m_Sampler.m_pITex) - { - rDecalCopy.nFlags |= DECAL_HAS_SPECULAR_MAP; - } - else - { - rDecalCopy.nFlags &= ~DECAL_HAS_SPECULAR_MAP; - } - } - ////////////////////////////////////////////////////////////////////////// - - if IsCVarConstAccess(constexpr) (CV_r_deferredDecalsDebug) - { - Vec3 vCenter = rDecalCopy.projMatrix.GetTranslation(); - float fSize = rDecalCopy.projMatrix.GetColumn(2).GetLength(); - Vec3 vSize(fSize, fSize, fSize); - AABB aabbCenter(vCenter - vSize * 0.05f, vCenter + vSize * 0.05f); - GetIRenderAuxGeom()->DrawAABB(aabbCenter, false, Col_Yellow, eBBD_Faceted); - GetIRenderAuxGeom()->DrawLine(vCenter, Col_Red, vCenter + rDecalCopy.projMatrix.GetColumn(0), Col_Red); - GetIRenderAuxGeom()->DrawLine(vCenter, Col_Green, vCenter + rDecalCopy.projMatrix.GetColumn(1), Col_Green); - GetIRenderAuxGeom()->DrawLine(vCenter, Col_Blue, vCenter + rDecalCopy.projMatrix.GetColumn(2), Col_Blue); - } - - return true; - } - return false; -} - -void CRenderer::EF_ClearLightsList() -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - assert(SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID] >= 0); - m_RP.m_DLights[m_RP.m_nFillThreadID][SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID]].SetUse(0); - m_RP.m_SMFrustums[m_RP.m_nFillThreadID][SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID]].SetUse(0); - m_RP.m_SMCustomFrustumIDs[m_RP.m_nFillThreadID][SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID]].SetUse(0); - - if (SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID] == 0) - { - m_RP.m_arrCustomShadowMapFrustumData[m_RP.m_nFillThreadID].resize(0); - } -} - -inline Matrix44 ToLightMatrix(const Ang3& angle) -{ - Matrix33 ViewMatZ = Matrix33::CreateRotationZ(-angle.x); - Matrix33 ViewMatX = Matrix33::CreateRotationX(-angle.y); - Matrix33 ViewMatY = Matrix33::CreateRotationY(+angle.z); - return Matrix44(ViewMatX * ViewMatY * ViewMatZ).GetTransposed(); -} - -bool CRenderer::EF_UpdateDLight(SRenderLight* dl) -{ - if (!dl) - { - return false; - } - - float fTime = iTimer->GetCurrTime() * dl->GetAnimSpeed(); - - const uint32 nStyle = dl->m_nLightStyle; - - const IAnimNode* pLightAnimNode = 0; - - ILightAnimWrapper* pLightAnimWrapper = dl->m_pLightAnim; - IF (pLightAnimWrapper, 0) - { - pLightAnimNode = pLightAnimWrapper->GetNode(); - IF (!pLightAnimNode, 0) - { - pLightAnimWrapper->Resolve(); - pLightAnimNode = pLightAnimWrapper->GetNode(); - } - } - - IF (pLightAnimNode, 0) - { - //TODO: This may require further optimizations. - IAnimTrack* pPosTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::Position); - IAnimTrack* pRotTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::Rotation); - IAnimTrack* pColorTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::LightDiffuse); - IAnimTrack* pDiffMultTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::LightDiffuseMult); - IAnimTrack* pRadiusTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::LightRadius); - IAnimTrack* pSpecMultTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::LightSpecularMult); - IAnimTrack* pHDRDynamicTrack = pLightAnimNode->GetTrackForParameter(AnimParamType::LightHDRDynamic); - - Range timeRange = const_cast(pLightAnimNode)->GetSequence()->GetTimeRange(); - float time = (dl->m_Flags & DLF_TRACKVIEW_TIMESCRUBBING) ? dl->m_fTimeScrubbed : fTime; - float phase = static_cast(dl->m_nLightPhase) / 100.0f; - - if (pPosTrack && pPosTrack->GetNumKeys() > 0 && - !(pPosTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - Vec3 vOffset(0, 0, 0); - float duration = max(pPosTrack->GetKeyTime(pPosTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pPosTrack->GetValue(timeNormalized, vOffset); - dl->m_Origin = dl->m_BaseOrigin + vOffset; - } - - if (pRotTrack && pRotTrack->GetNumKeys() > 0 && - !(pRotTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - Vec3 vRot(0, 0, 0); - float duration = max(pRotTrack->GetKeyTime(pRotTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pRotTrack->GetValue(timeNormalized, vRot); - static_cast(dl)->SetMatrix( - dl->m_BaseObjMatrix * Matrix34::CreateRotationXYZ(Ang3(DEG2RAD(vRot.x), DEG2RAD(vRot.y), DEG2RAD(vRot.z))), - false); - } - - if (pColorTrack && pColorTrack->GetNumKeys() > 0 && - !(pColorTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - Vec3 vColor(dl->m_Color.r, dl->m_Color.g, dl->m_Color.b); - float duration = max(pColorTrack->GetKeyTime(pColorTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pColorTrack->GetValue(timeNormalized, vColor); - dl->m_Color = ColorF(vColor.x / 255.0f, vColor.y / 255.0f, vColor.z / 255.0f); - } - else - { - dl->m_Color = dl->m_BaseColor; - } - - if (pDiffMultTrack && pDiffMultTrack->GetNumKeys() > 0 && - !(pDiffMultTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - float diffMult = 1.0; - float duration = max(pDiffMultTrack->GetKeyTime(pDiffMultTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pDiffMultTrack->GetValue(timeNormalized, diffMult); - dl->m_Color *= diffMult; - } - - if (pRadiusTrack && pRadiusTrack->GetNumKeys() > 0 && - !(pRadiusTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - float radius = dl->m_fRadius; - float duration = max(pRadiusTrack->GetKeyTime(pRadiusTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pRadiusTrack->GetValue(timeNormalized, radius); - dl->m_fRadius = radius; - } - - if (pSpecMultTrack && pSpecMultTrack->GetNumKeys() > 0 && - !(pSpecMultTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - float specMult = dl->m_SpecMult; - float duration = max(pSpecMultTrack->GetKeyTime(pSpecMultTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pSpecMultTrack->GetValue(timeNormalized, specMult); - dl->m_SpecMult = specMult; - } - - if (pHDRDynamicTrack && pHDRDynamicTrack->GetNumKeys() > 0 && - !(pHDRDynamicTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)) - { - float hdrDynamic = dl->m_fHDRDynamic; - float duration = max(pHDRDynamicTrack->GetKeyTime(pHDRDynamicTrack->GetNumKeys() - 1), 0.001f); - float timeNormalized = static_cast(fmod(time + phase * duration, duration)); - pHDRDynamicTrack->GetValue(timeNormalized, hdrDynamic); - dl->m_fHDRDynamic = hdrDynamic; - } - } - else if (nStyle > 0 && nStyle < CLightStyle::s_LStyles.Num() && CLightStyle::s_LStyles[nStyle]) - { - CLightStyle* ls = CLightStyle::s_LStyles[nStyle]; - - const float fRecipMaxInt8 = 1.0f / 255.0f; - - // Add user light phase - float fPhaseFromID = ((float)dl->m_nLightPhase) * fRecipMaxInt8; - fTime += (fPhaseFromID - floorf(fPhaseFromID)) * ls->m_TimeIncr; - - ls->mfUpdate(fTime); - - // It's possible the use of m_Color could be broken if ls->m_Color.a is being used for blending/fading, - // because we moved probe blending out of the alpha channel into m_fProbeAttenuation. This code wasn't tested - // after those changes as it only appears to be used in legacy code paths (light animation via old ScriptBind - // system and/or legacy LensFlareComponent). (9/20/2017, see LY-64767) - dl->m_Color = dl->m_BaseColor * ls->m_Color; - dl->m_SpecMult = dl->m_BaseSpecMult * ls->m_Color.a; - dl->m_Origin = dl->m_BaseOrigin + ls->m_vPosOffset; - } - else - { - dl->m_Color = dl->m_BaseColor; - } - - return false; -} - -void CRenderer::FX_ApplyShaderQuality(const EShaderType eST) -{ - SShaderProfile* const pSP = &m_cEF.m_ShaderProfiles[eST]; - const uint64 quality = g_HWSR_MaskBit[HWSR_QUALITY]; - const uint64 quality1 = g_HWSR_MaskBit[HWSR_QUALITY1]; - m_RP.m_FlagsShader_RT &= ~(quality | quality1); - int nQuality = (int)pSP->GetShaderQuality(); - m_RP.m_nShaderQuality = nQuality; - switch (nQuality) - { - case eSQ_Medium: - m_RP.m_FlagsShader_RT |= quality; - break; - case eSQ_High: - m_RP.m_FlagsShader_RT |= quality1; - break; - case eSQ_VeryHigh: - m_RP.m_FlagsShader_RT |= (quality | quality1); - break; - } -} - -EShaderQuality CRenderer::EF_GetShaderQuality(EShaderType eST) -{ - SShaderProfile* pSP = &m_cEF.m_ShaderProfiles[eST]; - int nQuality = (int)pSP->GetShaderQuality(); - - switch (nQuality) - { - case eSQ_Low: - return eSQ_Low; - case eSQ_Medium: - return eSQ_Medium; - case eSQ_High: - return eSQ_High; - case eSQ_VeryHigh: - return eSQ_VeryHigh; - } - - return eSQ_Low; -} - -ERenderQuality CRenderer::EF_GetRenderQuality() const -{ - return (ERenderQuality)m_RP.m_eQuality; -} - -int CRenderer::RT_CurThreadList() -{ - return m_pRT->GetThreadList(); -} - -namespace { - // util funtion to write to the provided output memory - template - void WriteQueryResult(void* pOutput, [[maybe_unused]] uint32 nOutputSize, const T& rQueryResult) - { -#if !defined(_RELEASE) - if (pOutput == NULL) - { - CryFatalError("No Output Storage Specified"); - } - if (sizeof(T) != nOutputSize) - { - CryFatalError("Insufficient storage for EF_Query Output"); - } -#endif - *alias_cast(pOutput) = rQueryResult; - } - - // util function to read POD types from query parameters - template - T ReadQueryParameter(void* pInput, [[maybe_unused]] uint32 nInputSize) - { -#if !defined(_RELEASE) - if (pInput == NULL) - { - CryFatalError("No Input Storage Specified"); - } - if (sizeof(T) != nInputSize) - { - CryFatalError("Insufficient storage for EF_Query Input"); - } -#endif - return *alias_cast(pInput); - } -} - -void CRenderer::EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1) -{ - switch (eQuery) - { - case EFQ_DeleteMemoryArrayPtr: - { - char* pPtr = ReadQueryParameter(pInOut0, nInOutSize0); - delete[] pPtr; - } - break; - - case EFQ_DeleteMemoryPtr: - { - char* pPtr = ReadQueryParameter(pInOut0, nInOutSize0); - delete pPtr; - } - break; - - case EFQ_LightSource: - { - assert(SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID] >= 0); - uint16 nLightId = ReadQueryParameter(pInOut0, nInOutSize0); - if (m_RP.m_DLights[m_RP.m_nFillThreadID][SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID]].Num() > nLightId) - { - WriteQueryResult(pInOut1, nInOutSize1, &m_RP.m_DLights[m_RP.m_nFillThreadID][SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID]][nLightId]); - } - } - break; - - case EFQ_MainThreadList: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_nFillThreadID); - } - break; - - case EFQ_RenderThreadList: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_nProcessThreadID); - } - break; - - case EFQ_RenderMultithreaded: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(m_pRT->IsMultithreaded())); - } - break; - - case EFQ_IncrementFrameID: - { - m_RP.m_TI[m_pRT->GetThreadList()].m_nFrameID += 1; - } - break; - - case EFQ_DeviceLost: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(m_bDeviceLost != 0)); - } - break; - - case EFQ_RecurseLevel: - { - WriteQueryResult(pInOut0, nInOutSize0, SRendItem::m_RecurseLevel[m_pRT->GetThreadList()]); - } - break; - - case EFQ_Alloc_APITextures: - { - int nSize = 0; - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp || tp->IsNoTexture()) - { - continue; - } - if (!(tp->GetFlags() & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET))) - { - nSize += tp->GetDeviceDataSize(); - } - } - } - WriteQueryResult(pInOut0, nInOutSize0, nSize); - } - break; - - case EFQ_Alloc_APIMesh: - { - uint32 nSize = 0; - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - CRenderMesh* pRM = iter->item<&CRenderMesh::m_Chain>(); - nSize += static_cast(pRM->Size(CRenderMesh::SIZE_VB)); - nSize += static_cast(pRM->Size(CRenderMesh::SIZE_IB)); - } - WriteQueryResult(pInOut0, nInOutSize0, nSize); - } - break; - - case EFQ_Alloc_Mesh_SysMem: - { - uint32 nSize = 0; - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - CRenderMesh* pRM = iter->item<&CRenderMesh::m_Chain>(); - nSize += static_cast(pRM->Size(CRenderMesh::SIZE_ONLY_SYSTEM)); - } - WriteQueryResult(pInOut0, nInOutSize0, nSize); - } - break; - - case EFQ_Mesh_Count: - { - uint32 nCount = 0; - AUTO_LOCK(CRenderMesh::m_sLinkLock); - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - ++nCount; - } - WriteQueryResult(pInOut0, nInOutSize0, nCount); - } - break; - - case EFQ_GetAllMeshes: - { - //Get render mesh lock, to ensure that the mesh list doesn't change while we're copying - AUTO_LOCK(CRenderMesh::m_sLinkLock); - IRenderMesh** ppMeshes = NULL; - uint32 nSize = 0; - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - ++nSize; - } - if (pInOut0 && nSize) - { - //allocate the array. The calling function is responsible for cleaning it up. - ppMeshes = new IRenderMesh*[nSize]; - nSize = 0; - for (util::list* iter = CRenderMesh::m_MeshList.next; iter != &CRenderMesh::m_MeshList; iter = iter->next) - { - ppMeshes[nSize] = iter->item<&CRenderMesh::m_Chain>(); - ; - nSize++; - } - } - WriteQueryResult(pInOut0, nInOutSize0, ppMeshes); - WriteQueryResult(pInOut1, nInOutSize1, nSize); - } - break; - - case EFQ_GetAllTextures: - { - AUTO_LOCK(CBaseResource::s_cResLock); - - SRendererQueryGetAllTexturesParam* pParam = (SRendererQueryGetAllTexturesParam*)(pInOut0); - pParam->pTextures = NULL; - pParam->numTextures = 0; - - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - for (ResourcesMapItor itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp || tp->IsNoTexture()) - { - continue; - } - ++pParam->numTextures; - } - - if (pParam->numTextures > 0) - { - pParam->pTextures = new _smart_ptr[pParam->numTextures]; - - uint32 texIdx = 0; - for (ResourcesMapItor itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp || tp->IsNoTexture()) - { - continue; - } - pParam->pTextures[texIdx++] = tp; - } - } - } - } - break; - - case EFQ_GetAllTexturesRelease: - { - SRendererQueryGetAllTexturesParam* pParam = (SRendererQueryGetAllTexturesParam*)(pInOut0); - SAFE_DELETE_ARRAY(pParam->pTextures); - } - break; - - case EFQ_TexturesPoolSize: - { - uint32 streamPoolSize = (uint32)(CRenderer::GetTexturesStreamPoolSize() * 1024 * 1024); - WriteQueryResult(pInOut0, nInOutSize0, streamPoolSize); - } - break; - - case EFQ_RenderTargetPoolSize: - { - WriteQueryResult(pInOut0, nInOutSize0, (CRenderer::CV_r_rendertargetpoolsize + 2) * 1024 * 1024); - } - break; - - case EFQ_HDRModeEnabled: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(IsHDRModeEnabled() ? 1 : 0)); - } - break; - - case EFQ_ParticlesTessellation: - { -#if defined(PARTICLES_TESSELLATION_RENDERER) - WriteQueryResult(pInOut0, nInOutSize0, m_bDeviceSupportsTessellation && CV_r_ParticlesTessellation != 0); -#else - WriteQueryResult(pInOut0, nInOutSize0, false); -#endif - } - break; - - case EFQ_WaterTessellation: - { -#if defined(WATER_TESSELLATION_RENDERER) - WriteQueryResult(pInOut0, nInOutSize0, m_bDeviceSupportsTessellation && CV_r_WaterTessellationHW != 0); -#else - WriteQueryResult(pInOut0, nInOutSize0, false); -#endif - } - break; - - case EFQ_MeshTessellation: - { -#if defined(MESH_TESSELLATION_RENDERER) - WriteQueryResult(pInOut0, nInOutSize0, m_bDeviceSupportsTessellation); -#else - WriteQueryResult(pInOut0, nInOutSize0, false); -#endif - } - break; - -#ifndef _RELEASE - case EFQ_GetShadowPoolFrustumsNum: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_PS[m_RP.m_nFillThreadID].m_NumShadowPoolFrustums); - } - break; - - case EFQ_GetShadowPoolAllocThisFrameNum: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_PS[m_RP.m_nFillThreadID].m_NumShadowPoolAllocsThisFrame); - } - break; - - case EFQ_GetShadowMaskChannelsNum: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_PS[m_RP.m_nFillThreadID].m_NumShadowMaskChannels); - } - break; - - case EFQ_GetTiledShadingSkippedLightsNum: - { - WriteQueryResult(pInOut0, nInOutSize0, m_RP.m_PS[m_RP.m_nFillThreadID].m_NumTiledShadingSkippedLights); - } - break; -#endif - - case EFQ_MultiGPUEnabled: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(GetActiveGPUCount() > 1 ? 1 : 0)); - } - break; - - // deprecated, always enabled - case EFQ_sLinearSpaceShadingEnabled: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(1)); - } - break; - - case EFQ_SetDrawNearFov: - { - CV_r_drawnearfov = ReadQueryParameter(pInOut0, nInOutSize0); - } - break; - - case EFQ_GetDrawNearFov: - { - WriteQueryResult(pInOut0, nInOutSize0, CV_r_drawnearfov); - } - break; - - case EFQ_TextureStreamingEnabled: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(CRenderer::CV_r_texturesstreaming ? 1 : 0)); - } - break; - - case EFQ_MSAAEnabled: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(m_RP.IsMSAAEnabled() ? 1 : 0)); - } - break; - - case EFQ_AAMode: - { - const uint32 nMode = CRenderer::CV_r_AntialiasingMode; - WriteQueryResult(pInOut0, nInOutSize0, s_pszAAModes[nMode]); - } - break; - - case EFQ_GetShaderCombinations: - case EFQ_SetShaderCombinations: - case EFQ_CloseShaderCombinations: - { - // no longer used, can be ignored - } - break; - - case EFQ_Fullscreen: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(QueryIsFullscreen() ? 1 : 0)); - } - break; - - case EFQ_GetTexStreamingInfo: - { -#ifndef NULL_RENDERER - STextureStreamingStats* stats = (STextureStreamingStats*)(pInOut0); - if (stats) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_11 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - stats->nCurrentPoolSize = CTexture::s_pPoolMgr->GetReservedSize(); // s_nStatsStreamPoolInUseMem; -#endif - stats->nStreamedTexturesSize = CTexture::s_nStatsStreamPoolInUseMem; - - stats->nStaticTexturesSize = CTexture::s_nStatsCurManagedNonStreamedTexMem; - stats->bPoolOverflow = CTexture::s_pTextureStreamer->IsOverflowing(); - stats->bPoolOverflowTotally = CTexture::s_bOutOfMemoryTotally; - CTexture::s_bOutOfMemoryTotally = false; - stats->nMaxPoolSize = CRenderer::GetTexturesStreamPoolSize() * 1024 * 1024; - stats->nThroughput = (CTexture::s_nStreamingTotalTime > 0.f) ? size_t((double)CTexture::s_nStreamingThroughput / CTexture::s_nStreamingTotalTime) : 0; - -#ifndef _RELEASE - stats->nNumTexturesPerFrame = gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_NumTextures; -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_12 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif - - if (stats->bComputeReuquiredTexturesPerFrame) - { - stats->nRequiredStreamedTexturesCount = 0; - stats->nRequiredStreamedTexturesSize = 0; - - AUTO_LOCK(CBaseResource::s_cResLock); - - // compute all sizes - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp || tp->IsNoTexture() || !tp->IsStreamed()) - { - continue; - } - - const STexStreamingInfo* pTSI = tp->GetStreamingInfo(); - if (!pTSI) - { - continue; - } - - int nPersMip = tp->GetNumMipsNonVirtual() - tp->GetNumPersistentMips(); - bool bStale = CTexture::s_pTextureStreamer->StatsWouldUnload(tp); - int nCurMip = bStale ? nPersMip : tp->GetRequiredMipNonVirtual(); - if (tp->IsForceStreamHighRes()) - { - nCurMip = 0; - } - nCurMip = min(nCurMip, nPersMip); - - int nTexSize = tp->StreamComputeDevDataSize(nCurMip); - - stats->nRequiredStreamedTexturesSize += nTexSize; - ++stats->nRequiredStreamedTexturesCount; - } - } - } - - stats->bPoolOverflow = CTexture::s_pTextureStreamer->IsOverflowing(); - stats->bPoolOverflowTotally = CTexture::s_bOutOfMemoryTotally; - CTexture::s_bOutOfMemoryTotally = 0; - } - if (pInOut1) - { - WriteQueryResult(pInOut1, nInOutSize1, static_cast(CTexture::s_nStreamingTotalTime > 0.f && stats != NULL)); - } -#endif // NULL_RENDERER - } - break; - - case EFQ_GetShaderCacheInfo: - { - SShaderCacheStatistics* pStats = (SShaderCacheStatistics*)(pInOut0); - if (pStats) - { - memcpy(pStats, &m_cEF.m_ShaderCacheStats, sizeof(SShaderCacheStatistics)); - pStats->m_bShaderCompileActive = CV_r_shadersAllowCompilation != 0; - } - } - break; - - case EFQ_OverscanBorders: - { - WriteQueryResult(pInOut0, nInOutSize0, s_overscanBorders); - } - break; - - case EFQ_NumActivePostEffects: - { - int nSize = 0; - if (CV_r_PostProcess && PostEffectMgr()) - { - //assume query is from main thread - nSize = PostEffectMgr()->GetActiveEffects(m_RP.m_nFillThreadID).size(); - } - - WriteQueryResult(pInOut0, nInOutSize0, nSize); - } - break; - - case EFQ_GetFogCullDistance: - { - WriteQueryResult(pInOut0, nInOutSize0, m_fogCullDistance); - } - break; - - case EFQ_GetMaxRenderObjectsNum: - { - WriteQueryResult(pInOut0, nInOutSize0, MAX_REND_OBJECTS); - } - break; - - case EFQ_IsRenderLoadingThreadActive: - { - WriteQueryResult(pInOut0, nInOutSize0, static_cast(m_pRT && m_pRT->m_pThreadLoading ? 1 : 0)); - } - break; - - case EFQ_GetSkinningDataPoolSize: - { - int nSkinningPoolSize = 0; - for (int i = 0; i < 3; ++i) - { - nSkinningPoolSize += m_SkinningDataPool[i].AllocatedMemory(); - } - WriteQueryResult(pInOut0, nInOutSize0, nSkinningPoolSize); - } - break; - - case EFQ_GetMeshPoolInfo: - { - if (SMeshPoolStatistics* stats = (SMeshPoolStatistics*)(pInOut0)) - { - CRenderMesh::GetPoolStats(stats); - } - } - break; - - case EFQ_GetViewportDownscaleFactor: - { - WriteQueryResult(pInOut0, nInOutSize0, m_CurViewportScale); - } - break; - case EFQ_ReverseDepthEnabled: - { - const uint32 nThreadID = m_pRT->GetThreadList(); - uint32 nReverseDepth = gRenDev->m_RP.m_TI[nThreadID].m_PersFlags & RBPF_REVERSE_DEPTH; - - WriteQueryResult(pInOut0, nInOutSize0, nReverseDepth); - } - break; - case EFQ_GetLastD3DDebugMessage: - { -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) - class D3DDebugMessage - : public ID3DDebugMessage - { - public: - D3DDebugMessage(const char* pMsg) - : m_msg(pMsg) {} - - virtual void Release() { delete this; } - virtual const char* GetMessage() const { return m_msg.c_str(); } - - protected: - string m_msg; - }; - - if (pInOut0) - { - *((ID3DDebugMessage**) pInOut0) = new D3DDebugMessage(D3DDebug_GetLastMessage()); - } -#endif - break; - } - - default: - assert(0); - } -} - -void CRenderer::ForceGC(){ gRenDev->m_pRT->RC_ForceMeshGC(false); } - -//================================================================================================================ - -_smart_ptr CRenderer::CreateRenderMesh(const char* szType, const char* szSourceName, IRenderMesh::SInitParamerers* pInitParams, ERenderMeshType eBufType) -{ - if (pInitParams) - { - return CreateRenderMeshInitialized(pInitParams->pVertBuffer, pInitParams->nVertexCount, pInitParams->vertexFormat, pInitParams->pIndices, pInitParams->nIndexCount, pInitParams->nPrimetiveType, szType, szSourceName, - pInitParams->eType, pInitParams->nRenderChunkCount, pInitParams->nClientTextureBindID, 0, 0, pInitParams->bOnlyVideoBuffer, pInitParams->bPrecache, pInitParams->pTangents, pInitParams->bLockForThreadAccess, pInitParams->pNormals); - } - - // make material table with clean elements - _smart_ptr pRenderMesh = new CRenderMesh(szType, szSourceName); - pRenderMesh->_SetRenderMeshType(eBufType); - - return pRenderMesh.get(); -} - -// Creates the RenderMesh with the materials, secondary buffer (system buffer) -// indices and perhaps some other stuff initialized. -// NOTE: if the pVertBuffer is NULL, the system buffer doesn't get initialized with any values -// (trash may be in it) -_smart_ptr CRenderer::CreateRenderMeshInitialized( - const void* pVertBuffer, int nVertCount, const AZ::Vertex::Format& vertexFormat, - const vtx_idx* pIndices, int nIndices, - const PublicRenderPrimitiveType nPrimetiveType, const char* szType, const char* szSourceName, ERenderMeshType eBufType, - int nMatInfoCount, int nClientTextureBindID, - bool(* PrepareBufferCallback)(IRenderMesh*, bool), - void* CustomData, bool bOnlyVideoBuffer, bool bPrecache, - const SPipTangents* pTangents, bool bLockForThreadAcc, Vec3* pNormals) -{ - FUNCTION_PROFILER_RENDERER; - - _smart_ptr pRenderMesh = new CRenderMesh(szType, szSourceName, bLockForThreadAcc); - pRenderMesh->_SetRenderMeshType(eBufType); - pRenderMesh->LockForThreadAccess(); - - // make mats info list - pRenderMesh->m_Chunks.reserve(nMatInfoCount); - pRenderMesh->_SetVertexFormat(vertexFormat); - pRenderMesh->_SetNumVerts(nVertCount); - pRenderMesh->_SetNumInds(nIndices); - - // copy vert buffer - if (pVertBuffer && !PrepareBufferCallback && !bOnlyVideoBuffer) - { - pRenderMesh->UpdateVertices(pVertBuffer, nVertCount, 0, VSF_GENERAL, 0u, false); - if (pTangents) - { - pRenderMesh->UpdateVertices(pTangents, nVertCount, 0, VSF_TANGENTS, 0u, false); - } -#if ENABLE_NORMALSTREAM_SUPPORT - if (pNormals) - { - pRenderMesh->UpdateVertices(pNormals, nVertCount, 0, VSF_NORMALS, 0u, false); - } -#endif - } - - if (CustomData) - { - CryFatalError("CRenderMesh::CustomData not supported anymore. Will be removed from interface"); - } - - if (pIndices) - { - pRenderMesh->UpdateIndices(pIndices, nIndices, 0, 0u, false); - } - pRenderMesh->_SetPrimitiveType(GetInternalPrimitiveType(nPrimetiveType)); - - pRenderMesh->m_nClientTextureBindID = nClientTextureBindID; - - // Precache for static buffers - if (CV_r_meshprecache && pRenderMesh->GetNumVerts() && bPrecache && !m_bDeviceLost && m_pRT->IsRenderThread()) - { - pRenderMesh->CheckUpdate(-1); - } - - pRenderMesh->UnLockForThreadAccess(); - return pRenderMesh.get(); -} - -//======================================================================= - -void CRenderer::SetWhiteTexture() -{ - m_pRT->RC_SetTexture(CTextureManager::Instance()->GetWhiteTexture()->GetID(), 0); -} - -int CRenderer::GetWhiteTextureId() const -{ - const int textureId = (CTextureManager::Instance()->GetWhiteTexture()) ? CTextureManager::Instance()->GetWhiteTexture()->GetID() : -1; - return textureId; -} - -int CRenderer::GetBlackTextureId() const -{ - const int textureId = (CTextureManager::Instance()->GetBlackTexture()) ? CTextureManager::Instance()->GetBlackTexture()->GetID() : -1; - return textureId; -} - -void CRenderer::SetTexture(int tnum) -{ - m_pRT->RC_SetTexture(tnum, 0); -} - -void CRenderer::SetTexture(int tnum, int nUnit) -{ - m_pRT->RC_SetTexture(tnum, nUnit); -} - -// used for sprite generation -void CRenderer::SetTextureAlphaChannelFromRGB(byte* pMemBuffer, int nTexSize) -{ - // set alpha channel - for (int y = 0; y < nTexSize; y++) - { - for (int x = 0; x < nTexSize; x++) - { - int t = (x + nTexSize * y) * 4; - if (abs(pMemBuffer[t + 0] - pMemBuffer[0 + 0]) < 2 && - abs(pMemBuffer[t + 1] - pMemBuffer[0 + 1]) < 2 && - abs(pMemBuffer[t + 2] - pMemBuffer[0 + 2]) < 2) - { - pMemBuffer[t + 3] = 0; - } - else - { - pMemBuffer[t + 3] = 255; - } - - // set border alpha to 0 - if (x == 0 || y == 0 || x == nTexSize - 1 || y == nTexSize - 1) - { - pMemBuffer[t + 3] = 0; - } - } - } -} - -//============================================================================= -// Precaching -bool CRenderer::EF_PrecacheResource(IRenderMesh* _pPB, _smart_ptr pMaterial, float fMipFactor, [[maybe_unused]] float fTimeToReady, int nFlags, int nUpdateId) -{ - int i; - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreaming) - { - return true; - } - - CRenderMesh* pPB = (CRenderMesh*)_pPB; - - for (i = 0; i < pPB->m_Chunks.size(); i++) - { - CRenderChunk* pChunk = &pPB->m_Chunks[i]; - assert(!"do pre-cache with real materials"); - - assert(0); - - //@TODO: Timur - assert(pMaterial && "RenderMesh must have material"); - CShaderResources* pSR = (CShaderResources*)pMaterial->GetShaderItem(pChunk->m_nMatID).m_pShaderResources; - if (!pSR) - { - continue; - } - if (pSR->m_nFrameLoad != m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameID) - { - pSR->m_nFrameLoad = m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameID; - pSR->m_fMinMipFactorLoad = 999999.0f; - } - else - if (fMipFactor >= pSR->m_fMinMipFactorLoad) - { - continue; - } - - pSR->m_fMinMipFactorLoad = fMipFactor; - for (auto& iter : pSR->m_TexturesResourcesMap ) - { - SEfResTexture* pTexture = &(iter.second); - CTexture* tp = static_cast (pTexture->m_Sampler.m_pITex); - if (!tp) - { - continue; - } - fMipFactor *= pTexture->GetTiling(0) * pTexture->GetTiling(1); - m_pRT->RC_PrecacheResource(tp, fMipFactor, 0, nFlags, nUpdateId); - } - } - return true; -} - -bool CRenderer::EF_PrecacheResource(CDLight* pLS, float fMipFactor, [[maybe_unused]] float fTimeToReady, int Flags, int nUpdateId) -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_RENDERER, g_bProfilerEnabled); - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreaming) - { - return true; - } - - ITexture* pLightTexture = pLS->m_pLightImage ? pLS->m_pLightImage : NULL; - if (pLightTexture) - { - m_pRT->RC_PrecacheResource(pLightTexture, fMipFactor, 0, Flags, nUpdateId); - } - if (pLS->GetDiffuseCubemap()) - { - m_pRT->RC_PrecacheResource(pLS->GetDiffuseCubemap(), fMipFactor, 0, Flags, nUpdateId); - } - if (pLS->GetSpecularCubemap()) - { - m_pRT->RC_PrecacheResource(pLS->GetSpecularCubemap(), fMipFactor, 0, Flags, nUpdateId); - } - return true; -} - -void CRenderer::PrecacheTexture(ITexture* pTP, float fMipFactor, [[maybe_unused]] float fTimeToReady, int Flags, int nUpdateId, int nCounter) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreaming) - { - return; - } - - assert(m_pRT->IsRenderThread()); - - if (pTP) - { - ((CTexture*)pTP)->CTexture::PrecacheAsynchronously(fMipFactor, Flags, nUpdateId, nCounter); - } -} - -bool CRenderer::EF_PrecacheResource([[maybe_unused]] IShader* pSH, [[maybe_unused]] float fMipFactor, [[maybe_unused]] float fTimeToReady, [[maybe_unused]] int Flags) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreaming) - { - return true; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -// HDR_UPPERNORM -> factor used when converting from [0,32768] high dynamic range images -// to [0,1] low dynamic range images; 32768 = 2^(2^4-1), 4 exponent bits -// LDR_UPPERNORM -> factor used when converting from [0,1] low dynamic range images -// to 8bit outputs - -#define HDR_UPPERNORM 1.0f // factor set to 1.0, to be able to see content in our rather dark HDR images -#define LDR_UPPERNORM 255.0f - -////////////////////////////////////////////////////////////////////////// -// NOTE: AMD64 port: implement -#define PROCESS_IN_PARALLEL - -// Squish uses non-standard inline friend templates which Recode cannot parse -#if !defined(__RECODE__) && defined(USING_SQUISH_SDK) -#include -#endif - -// number of bytes per block per type -#define BLOCKSIZE_BC1 8 -#define BLOCKSIZE_BC2 16 -#define BLOCKSIZE_BC3 16 -#define BLOCKSIZE_BC4 8 -#define BLOCKSIZE_BC5 16 -#define BLOCKSIZE_BC6 16 -#define BLOCKSIZE_BC7 16 - -#if !defined(__RECODE__) && defined(USING_SQUISH_SDK) -struct SCompressRowData -{ - struct squish::sqio* pSqio; - byte* destinationData; - const byte* sourceData; - int row; - int width; - int height; - int blockWidth; - int blockHeight; - int pixelStride; - int rowStride; - int blockStride; - int sourceChannels; - int destinationChannels; - int offs; -}; - -static void DXTDecompressRow(SCompressRowData data) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); -#if defined(WIN32) - SCOPED_DISABLE_FLOAT_EXCEPTIONS; -#endif - - byte* dst = data.destinationData + (data.row * data.rowStride); - const byte* src = data.sourceData + ((data.row >> 2) * data.blockStride); - - for (int x = 0; x < data.width; x += data.blockWidth) - { - uint8 values[4][4][4]; - - // decode - data.pSqio->decoder((uint8*)values, const_cast(static_cast(src)), data.pSqio->flags); - - // transfer - for (int by = 0; by < data.blockHeight; by += 1) - { - byte* bdst = ((uint8*)dst) + (by * data.rowStride); - - for (int bx = 0; bx < data.blockWidth; bx += 1) - { - bdst[bx * data.pixelStride + 0] = data.sourceChannels <= 0 ? 0U : (values[by][bx][0] + data.offs); - bdst[bx * data.pixelStride + 1] = data.sourceChannels <= 1 ? bdst[bx * data.pixelStride + 0] : (values[by][bx][1] + data.offs); - bdst[bx * data.pixelStride + 2] = data.sourceChannels <= 1 ? bdst[bx * data.pixelStride + 0] : (values[by][bx][2] + data.offs); - bdst[bx * data.pixelStride + 3] = data.sourceChannels <= 3 ? 255U : (values[by][bx][3]); - } - } - - dst += data.blockWidth * data.pixelStride; - src += data.pSqio->blocksize; - } -} - -static void DXTDecompressRowFloat(SCompressRowData data) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); -#if defined(WIN32) - SCOPED_DISABLE_FLOAT_EXCEPTIONS; -#endif - - byte* dst = data.destinationData + (data.row * data.rowStride); - const byte* src = data.sourceData + ((data.row >> 2) * data.blockStride); - - for (int x = 0; x < data.width; x += data.blockWidth) - { - byte values[4][4][4]; - - // decode - data.pSqio->decoder((byte*)values, const_cast(static_cast(src)), data.pSqio->flags); - - // transfer - for (int by = 0; by < data.blockHeight; by += 1) - { - byte* bdst = ((byte*)dst) + (by * data.rowStride); - - for (int bx = 0; bx < data.blockWidth; bx += 1) - { - bdst[bx * data.pixelStride + 0] = data.sourceChannels <= 0 ? 0U : std::min((byte)255, (byte)floorf(values[by][bx][0] * LDR_UPPERNORM / HDR_UPPERNORM + 0.5f)); - bdst[bx * data.pixelStride + 1] = data.sourceChannels <= 1 ? bdst[bx * data.pixelStride + 0] : std::min((uint8)255, (uint8)floorf(values[by][bx][1] * LDR_UPPERNORM / HDR_UPPERNORM + 0.5f)); - bdst[bx * data.pixelStride + 2] = data.sourceChannels <= 1 ? bdst[bx * data.pixelStride + 0] : std::min((uint8)255, (uint8)floorf(values[by][bx][2] * LDR_UPPERNORM / HDR_UPPERNORM + 0.5f)); - bdst[bx * data.pixelStride + 3] = data.sourceChannels <= 3 ? 255U : 255U; - } - } - - dst += data.blockWidth * data.pixelStride; - src += data.pSqio->blocksize; - } -} - -static void DXTCompressRow(SCompressRowData data) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); -#if defined(WIN32) - SCOPED_DISABLE_FLOAT_EXCEPTIONS; -#endif - - byte* dst = data.destinationData + ((data.row >> 2) * data.blockStride); - const byte* src = data.sourceData + (data.row * data.rowStride); - - for (int x = 0; x < data.width; x += data.blockWidth) - { - byte values[4][4][4]; - - // transfer - for (int by = 0; by < data.blockHeight; by += 1) - { - const byte* bsrc = src + (by * data.rowStride); - - for (int bx = 0; bx < data.blockWidth; bx += 1) - { - values[by][bx][0] = data.destinationChannels <= 0 ? 0U : bsrc[bx * data.pixelStride + 0] - data.offs; - values[by][bx][1] = data.destinationChannels <= 1 ? values[by][bx][0] : bsrc[bx * data.pixelStride + 1] - data.offs; - values[by][bx][2] = data.destinationChannels <= 1 ? values[by][bx][0] : bsrc[bx * data.pixelStride + 2] - data.offs; - values[by][bx][3] = data.destinationChannels <= 3 ? 255U : bsrc[bx * data.pixelStride + 3]; - } - } - // encode - data.pSqio->encoder((float*)values, 0xFFFF, (void*)dst, data.pSqio->flags); - - src += data.blockWidth * data.pixelStride; - dst += data.pSqio->blocksize; - } -} - -static void DXTCompressRowFloat(SCompressRowData data) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); -#if defined(WIN32) - SCOPED_DISABLE_FLOAT_EXCEPTIONS; -#endif - - byte* dst = data.destinationData + ((data.row >> 2) * data.blockStride); - const byte* src = data.sourceData + (data.row * data.rowStride); - - for (int x = 0; x < data.width; x += data.blockWidth) - { - float values[4][4][4]; - - // transfer - for (int by = 0; by < data.blockHeight; by += 1) - { - const byte* bsrc = src + (by * data.rowStride); - - for (int bx = 0; bx < data.blockWidth; bx += 1) - { - values[by][bx][0] = data.destinationChannels <= 0 ? 0U : bsrc[bx * data.pixelStride + 0] * HDR_UPPERNORM / LDR_UPPERNORM; - values[by][bx][1] = data.destinationChannels <= 1 ? values[by][bx][0] : bsrc[bx * data.pixelStride + 1] * HDR_UPPERNORM / LDR_UPPERNORM; - values[by][bx][2] = data.destinationChannels <= 1 ? values[by][bx][0] : bsrc[bx * data.pixelStride + 2] * HDR_UPPERNORM / LDR_UPPERNORM; - values[by][bx][3] = data.destinationChannels <= 3 ? 255U : 1.0f; - } - } - - // encode - data.pSqio->encoder((float*)values, 0xFFFF, (void*)dst, data.pSqio->flags); - - src += data.blockWidth * data.pixelStride; - dst += data.pSqio->blocksize; - } -} - -#endif // #if !defined(__RECODE__) && defined(USING_SQUISH_SDK) - -bool CRenderer::DXTDecompress([[maybe_unused]] const byte* sourceData, [[maybe_unused]] const size_t srcFileSize, [[maybe_unused]] byte* destinationData, [[maybe_unused]] int width, [[maybe_unused]] int height, [[maybe_unused]] int mips, [[maybe_unused]] ETEX_Format sourceFormat, bool bUseHW, [[maybe_unused]] int nDstBytesPerPix) -{ - if (bUseHW) - { - return false; - } - - // Squish uses non-standard inline friend templates which Recode cannot parse -#if !defined(__RECODE__) && defined(USING_SQUISH_SDK) - int flags = 0; - int offs = 0; - int sourceChannels = 4; - switch (sourceFormat) - { - case eTF_BC1: - sourceChannels = 4; - flags = squish::kBtc1; - break; - case eTF_BC2: - sourceChannels = 4; - flags = squish::kBtc2; - break; - case eTF_BC3: - sourceChannels = 4; - flags = squish::kBtc3; - break; - case eTF_BC4U: - sourceChannels = 1; - flags = squish::kBtc4; - break; - case eTF_BC5U: - sourceChannels = 2; - flags = squish::kBtc5 + squish::kColourMetricUnit; - break; - case eTF_BC6UH: - sourceChannels = 3; - flags = squish::kBtc6; - break; - case eTF_BC7: - sourceChannels = 4; - flags = squish::kBtc7; - break; - - case eTF_BC4S: - sourceChannels = 1; - flags = squish::kBtc4 + squish::kSignedInternal + squish::kSignedExternal; - offs = 0x80; - break; - case eTF_BC5S: - sourceChannels = 2; - flags = squish::kBtc5 + squish::kSignedInternal + squish::kSignedExternal + squish::kColourMetricUnit; - offs = 0x80; - break; - case eTF_BC6SH: - sourceChannels = 3; - flags = squish::kBtc6 + squish::kSignedInternal + squish::kSignedExternal; - offs = 0x80; - break; - - // unsupported input - default: - return false; - } - - squish::sqio::dtp datatype = !CImageExtensionHelper::IsRangeless(sourceFormat) ? squish::sqio::DT_U8 : squish::sqio::DT_F23; - - if (nDstBytesPerPix == 4) - { - datatype = squish::sqio::DT_U8; - } - // else if (nDstBytesPerPix == 8) - // datatype = squish::sqio::DT_U16; - // else if (nDstBytesPerPix == 16) - // datatype = squish::sqio::DT_F23; - else - { - // unsupported output - return false; - } - - struct squish::sqio sqio = squish::GetSquishIO(width, height, datatype, flags); - - const int blockChannels = 4; - const int blockWidth = 4; - const int blockHeight = 4; - - SCompressRowData data; - data.pSqio = &sqio; - data.destinationData = destinationData; - data.sourceData = sourceData; - data.width = width; - data.height = height; - data.blockWidth = blockWidth; - data.blockHeight = blockHeight; - data.pixelStride = blockChannels * sizeof(uint8); - data.rowStride = data.pixelStride * width; - data.blockStride = sqio.blocksize * (width >> 2); - data.sourceChannels = sourceChannels; - data.offs = offs; - - if ((datatype == squish::sqio::DT_U8) && (nDstBytesPerPix == 4)) - { - for (int y = 0; y < height; y += blockHeight) - { - data.row = y; - DXTDecompressRow(data); - } - } - else if ((datatype == squish::sqio::DT_F23) && (nDstBytesPerPix == 4)) - { - for (int y = 0; y < height; y += blockHeight) - { - data.row = y; - DXTDecompressRowFloat(data); - } - } - else - { - // implement decode to 16bit and floats - assert(0); - delete[] destinationData; - return false; - } - - return true; -#else - return false; -#endif -} - -bool CRenderer::DXTCompress(const byte* sourceData, int width, int height, [[maybe_unused]] ETEX_Format destinationFormat, bool bUseHW, bool bGenMips, int nSrcBytesPerPix, [[maybe_unused]] MIPDXTcallback callback) -{ - if (bUseHW) - { - return false; - } - if (bGenMips) - { - return false; - } - if IsCVarConstAccess(constexpr) (CV_r_TextureCompressor == 0) - { - return false; - } - -#ifdef WIN32 - if (IsBadReadPtr(sourceData, width * height * nSrcBytesPerPix)) - { - assert(0); - iLog->Log("Warning: CRenderer::DXTCompress: invalid data passed to the function"); - return false; - } -#endif - -#if !defined(__RECODE__) && defined(USING_SQUISH_SDK) - int flags = 0; - int offs = 0; - int destinationChannels = 4; - switch (destinationFormat) - { - // fastest encoding parameters possible - case eTF_BC1: - destinationChannels = 4; - flags = squish::kBtc1 + squish::kColourMetricPerceptual + squish::kColourRangeFit + squish::kExcludeAlphaFromPalette; - break; - case eTF_BC2: - destinationChannels = 4; - flags = squish::kBtc2 + squish::kColourMetricPerceptual + squish::kColourRangeFit /*squish::kWeightColourByAlpha*/; - break; - case eTF_BC3: - destinationChannels = 4; - flags = squish::kBtc3 + squish::kColourMetricPerceptual + squish::kColourRangeFit /*squish::kWeightColourByAlpha*/; - break; - case eTF_BC4U: - destinationChannels = 1; - flags = squish::kBtc4 + squish::kColourMetricUniform; - break; - case eTF_BC5U: - destinationChannels = 2; - flags = squish::kBtc5 + squish::kColourMetricUnit; - break; - case eTF_BC6UH: - destinationChannels = 3; - flags = squish::kBtc6 + squish::kColourMetricPerceptual + squish::kColourRangeFit; - break; - case eTF_BC7: - destinationChannels = 4; - flags = squish::kBtc7 + squish::kColourMetricPerceptual + squish::kColourRangeFit; - break; - - case eTF_BC4S: - destinationChannels = 1; - flags = squish::kBtc4 + squish::kSignedInternal + squish::kSignedExternal + squish::kColourMetricUniform; - offs = 0x80; - break; - case eTF_BC5S: - destinationChannels = 2; - flags = squish::kBtc5 + squish::kSignedInternal + squish::kSignedExternal + squish::kColourMetricUnit; - offs = 0x80; - break; - case eTF_BC6SH: - destinationChannels = 3; - flags = squish::kBtc6 + squish::kSignedInternal + squish::kSignedExternal; - offs = 0x80; - break; - - // unsupported output - default: - return false; - } - - squish::sqio::dtp datatype = !CImageExtensionHelper::IsRangeless(destinationFormat) ? squish::sqio::DT_U8 : squish::sqio::DT_F23; - - if (nSrcBytesPerPix == 4) - { - datatype = squish::sqio::DT_U8; - } - // else if (nSrcBytesPerPix == 8) - // datatype = squish::sqio::DT_U16; - // else if (nSrcBytesPerPix == 16) - // datatype = squish::sqio::DT_F23; - else - { - // unsupported input - return false; - } - - struct squish::sqio sqio = squish::GetSquishIO(width, height, datatype, flags); - - uint8* destinationData = new uint8[sqio.compressedsize]; - if (!destinationData) - { - return false; - } - - const int blockChannels = 4; - const int blockWidth = 4; - const int blockHeight = 4; - - SCompressRowData data; - data.pSqio = &sqio; - data.destinationData = destinationData; - data.sourceData = sourceData; - data.width = width; - data.height = height; - data.blockWidth = blockWidth; - data.blockHeight = blockHeight; - data.pixelStride = blockChannels * sizeof(uint8); - data.rowStride = data.pixelStride * width; - data.blockStride = sqio.blocksize * (width >> 2); - data.destinationChannels = destinationChannels; - data.offs = offs; - - if ((datatype == squish::sqio::DT_U8) && (nSrcBytesPerPix == 4)) - { - for (int y = 0; y < height; y += blockHeight) - { - data.row = y; - DXTCompressRow(data); - } - } - else if ((datatype == squish::sqio::DT_F23) && (nSrcBytesPerPix == 4)) - { - for (int y = 0; y < height; y += blockHeight) - { - data.row = y; - DXTCompressRowFloat(data); - } - } - else - { - // implement encode from 16bit and floats - assert(0); - delete[] destinationData; - return false; - } - - - (*callback)(destinationData, sqio.compressedsize, NULL); - delete[] destinationData; - - return true; -#else - return false; -#endif -} -bool CRenderer::WriteJPG(const byte* dat, int wdt, int hgt, char* name, int src_bits_per_pixel, int nQuality) -{ - return ::WriteJPG(dat, wdt, hgt, name, src_bits_per_pixel, nQuality); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::GetThreadIDs(threadID& mainThreadID, threadID& renderThreadID) const -{ - if (m_pRT) - { - mainThreadID = m_pRT->m_nMainThread; - renderThreadID = m_pRT->m_nRenderThread; - } - else - { - mainThreadID = renderThreadID = gEnv->mMainThreadId; - } -} -////////////////////////////////////////////////////////////////////////// -void CRenderer::PostLevelLoading() -{ - int nThreadID = m_pRT->GetThreadList(); - m_RP.m_fogVolumeContibutionsData[nThreadID].reserve(2048); -} - -const char* CRenderer::GetTextureFormatName(ETEX_Format eTF) -{ - return CTexture::NameForTextureFormat(eTF); -} - -int CRenderer::GetTextureFormatDataSize(int nWidth, int nHeight, int nDepth, int nMips, ETEX_Format eTF) -{ - return CTexture::TextureDataSize(nWidth, nHeight, nDepth, nMips, 1, eTF); -} - - -////////////////////////////////////////////////////////////////////////// -ERenderType CRenderer::GetRenderType() const -{ -#if defined(NULL_RENDERER) - return eRT_Null; -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_CPP_SECTION_13 - #include AZ_RESTRICTED_FILE(Renderer_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(CRY_USE_METAL) - return eRT_Metal; -#elif defined(OPENGL) - return eRT_OpenGL; -#elif defined(CRY_USE_DX12) - return eRT_DX12; -#else - return eRT_DX11; -#endif -} -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void IRenderer::SDrawCallCountInfo::Update(CRenderObject* pObj, IRenderMesh* pRM) -{ - SRenderPipeline& RESTRICT_REFERENCE rRP = gRenDev->m_RP; - if (((IRenderNode*)pObj->m_pRenderNode)) - { - pPos = pObj->GetTranslation(); - - if (meshName[0] == '\0') - { - const char* pMeshName = pRM->GetSourceName(); - if (pMeshName) - { - const size_t nameLen = strlen(pMeshName); - - // truncate if necessary - if (nameLen >= sizeof(meshName)) - { - pMeshName += nameLen - (sizeof(meshName) - 1); - } - cry_strcpy(meshName, pMeshName); - } - - const char* pTypeName = pRM->GetTypeName(); - if (pTypeName) - { - cry_strcpy(typeName, pTypeName); - } - } - - if (rRP.m_nBatchFilter & (FB_MOTIONBLUR | FB_CUSTOM_RENDER | FB_POST_3D_RENDER | FB_SOFTALPHATEST | FB_DEBUG)) - { - nMisc++; - } - else - if (!(rRP.m_TI[rRP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN)) - { - if (rRP.m_nBatchFilter & FB_GENERAL) - { - if (rRP.m_nPassGroupID == EFSLIST_TRANSP) - { - nTransparent++; - } - else - { - nGeneral++; - } - } - else if (rRP.m_nBatchFilter & (FB_Z | FB_ZPREPASS)) - { - nZpass++; - } - } - else - { - nShadows++; - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void S3DEngineCommon::Update(threadID nThreadID) -{ - I3DEngine* p3DEngine = gEnv->p3DEngine; - - // Camera vis area - IVisArea* pCamVisArea = p3DEngine->GetVisAreaFromPos(gRenDev->GetViewParameters().vOrigin); - m_pCamVisAreaInfo.nFlags &= ~VAF_MASK; - if (pCamVisArea) - { - m_pCamVisAreaInfo.nFlags |= VAF_EXISTS_FOR_POSITION; - if (pCamVisArea->IsConnectedToOutdoor()) - { - m_pCamVisAreaInfo.nFlags |= VAF_CONNECTED_TO_OUTDOOR; - } - if (pCamVisArea->IsAffectedByOutLights()) - { - m_pCamVisAreaInfo.nFlags |= VAF_AFFECTED_BY_OUT_LIGHTS; - } - } - - // Update ocean info - m_OceanInfo.m_fWaterLevel = OceanToggle::IsActive() ? OceanRequest::GetWaterLevel(gRenDev->GetViewParameters().vOrigin) : p3DEngine->GetWaterLevel(&gRenDev->GetViewParameters().vOrigin); - m_OceanInfo.m_nOceanRenderFlags = p3DEngine->GetOceanRenderFlags(); - - if IsCVarConstAccess(constexpr) (bool( CRenderer::CV_r_rain)) - { - const int nFrmID = gRenDev->GetFrameID(); - if (m_RainInfo.nUpdateFrameID != nFrmID) - { - UpdateRainInfo(nThreadID); - UpdateSnowInfo(nThreadID); - m_RainInfo.nUpdateFrameID = nFrmID; - } - } - - // Release rain occluders - if (CRenderer::CV_r_rain < 2 || m_RainInfo.bDisableOcclusion) - { - m_RainOccluders.Release(); - stl::free_container(m_RainOccluders.m_arrCurrOccluders[nThreadID]); - m_RainInfo.bApplyOcclusion = false; - } -} - -void S3DEngineCommon::UpdateRainInfo(threadID nThreadID) -{ - gEnv->p3DEngine->GetRainParams(m_RainInfo); - - bool bProcessedAll = true; - const uint32 numGPUs = gRenDev->GetActiveGPUCount(); - for (uint32 i = 0; i < numGPUs; ++i) - { - bProcessedAll &= m_RainOccluders.m_bProcessed[i]; - } - const bool bUpdateOcc = bProcessedAll; - if (bUpdateOcc) - { - m_RainOccluders.Release(); - } - - const Vec3 vCamPos = gRenDev->GetViewParameters().vOrigin; - const float fUnderWaterAtten = clamp_tpl(vCamPos.z - m_OceanInfo.m_fWaterLevel + 1.f, 0.f, 1.f); - m_RainInfo.fCurrentAmount *= fUnderWaterAtten; - - //#define RAIN_DEBUG -#ifndef RAIN_DEBUG - if (m_RainInfo.fCurrentAmount < 0.05f) - { - return; - } -#endif - -#ifdef RAIN_DEBUG - m_RainInfo.fAmount = 1.f; - m_RainInfo.fCurrentAmount = 1.f; - m_RainInfo.fRadius = 2000.f; - m_RainInfo.fFakeGlossiness = 0.5f; - m_RainInfo.fFakeReflectionAmount = 1.5f; - m_RainInfo.fDiffuseDarkening = 0.5f; - m_RainInfo.fRainDropsAmount = 0.5f; - m_RainInfo.fRainDropsSpeed = 1.f; - m_RainInfo.fRainDropsLighting = 1.f; - m_RainInfo.fMistAmount = 3.f; - m_RainInfo.fMistHeight = 8.f; - m_RainInfo.fPuddlesAmount = 1.5f; - m_RainInfo.fPuddlesMaskAmount = 1.0f; - m_RainInfo.fPuddlesRippleAmount = 2.0f; - m_RainInfo.fSplashesAmount = 1.3f; - - m_RainInfo.vColor.Set(1, 1, 1); - m_RainInfo.vWorldPos.Set(0, 0, 0); -#endif - - UpdateRainOccInfo(nThreadID); -} - -void S3DEngineCommon::UpdateSnowInfo(int nThreadID) -{ - gEnv->p3DEngine->GetSnowSurfaceParams(m_SnowInfo.m_vWorldPos, m_SnowInfo.m_fRadius, m_SnowInfo.m_fSnowAmount, m_SnowInfo.m_fFrostAmount, m_SnowInfo.m_fSurfaceFreezing); - gEnv->p3DEngine->GetSnowFallParams(m_SnowInfo.m_nSnowFlakeCount, m_SnowInfo.m_fSnowFlakeSize, m_SnowInfo.m_fSnowFallBrightness, m_SnowInfo.m_fSnowFallGravityScale, m_SnowInfo.m_fSnowFallWindScale, m_SnowInfo.m_fSnowFallTurbulence, m_SnowInfo.m_fSnowFallTurbulenceFreq); - - //#define RAIN_DEBUG -#ifndef RAIN_DEBUG - if (m_SnowInfo.m_fSnowAmount < 0.05f && m_SnowInfo.m_fFrostAmount < 0.05f) - { - return; - } -#endif - - UpdateRainOccInfo(nThreadID); -} - - -void S3DEngineCommon::UpdateRainOccInfo(int nThreadID) -{ - bool bSnowEnabled = (m_SnowInfo.m_fSnowAmount > 0.05f || m_SnowInfo.m_fFrostAmount > 0.05f) && m_SnowInfo.m_fRadius > 0.05f; - - bool bProcessedAll = true; - const uint32 numGPUs = gRenDev->GetActiveGPUCount(); - for (uint32 i = 0; i < numGPUs; ++i) - { - bProcessedAll &= m_RainOccluders.m_bProcessed[i]; - } - const bool bUpdateOcc = bProcessedAll; // there is no field called bForecedUpdate in RainOccluders - m_RainOccluders.bForceUpdate || bProcessedAll; - if (bUpdateOcc) - { - m_RainOccluders.Release(); - } - - // Get the rendering camera position from the renderer - const Vec3 vCamPos = gEnv->p3DEngine->GetRenderingCamera().GetPosition(); - bool bDisableOcclusion = m_RainInfo.bDisableOcclusion; - static bool bOldDisableOcclusion = true; // set to true to allow update at first run - - if (CRenderer::CV_r_rain == 2 && !bDisableOcclusion) - { - N3DEngineCommon::ArrOccluders& arrOccluders = m_RainOccluders.m_arrOccluders; - static const unsigned int nMAX_OCCLUDERS = bSnowEnabled ? 768 : 512; - static const float rainBBHalfSize = 18.f; - - if (bUpdateOcc) - { - // Choose world position and radius. - // Snow takes priority since occlusion has a much stronger impact on it. - Vec3 vWorldPos = bSnowEnabled ? m_SnowInfo.m_vWorldPos : m_RainInfo.vWorldPos; - float fRadius = bSnowEnabled ? m_SnowInfo.m_fRadius : m_RainInfo.fRadius; - float fViewerArea = bSnowEnabled ? 128.f : 32.f; // Snow requires further view distance, otherwise obvious "unoccluded" snow regions become visible. - float fOccArea = fViewerArea; - - // Rain volume BB - AABB bbRainVol(fRadius); - bbRainVol.Move(vWorldPos); - - // Visible area BB (Expanded to BB diagonal length to allow rotation) - AABB bbViewer(fViewerArea); - bbViewer.Move(vCamPos); - - // Area around viewer/rain source BB - AABB bbArea(bbViewer); - bbArea.ClipToBox(bbRainVol); - - // Snap BB to grid - Vec3 vSnapped = bbArea.min / rainBBHalfSize; - bbArea.min.Set(floor_tpl(vSnapped.x), floor_tpl(vSnapped.y), floor_tpl(vSnapped.z)); - bbArea.min *= rainBBHalfSize; - vSnapped = bbArea.max / rainBBHalfSize; - bbArea.max.Set(ceil_tpl(vSnapped.x), ceil_tpl(vSnapped.y), ceil_tpl(vSnapped.z)); - bbArea.max *= rainBBHalfSize; - - // If occlusion map info dirty - static float fOccTreshold = CRenderer::CV_r_rainOccluderSizeTreshold; - static float fOldRadius = fRadius; - const AABB& oldAreaBounds = m_RainInfo.areaAABB; - if (!oldAreaBounds.min.IsEquivalent(bbArea.min) - || !oldAreaBounds.max.IsEquivalent(bbArea.max) - || fOldRadius != fRadius //m_RainInfo.fRadius - || bOldDisableOcclusion != bDisableOcclusion - || fOccTreshold != CRenderer::CV_r_rainOccluderSizeTreshold) - { - // Get occluders inside area - AZ::u32 numAllOccluders = 0; - const AZ::u32 numAZStaticMeshOccluders = gEnv->p3DEngine->GetObjectsByTypeInBox(eERType_StaticMeshRenderComponent, bbArea); - const AZ::u32 numAZSkinnedMeshOccluders = gEnv->p3DEngine->GetObjectsByTypeInBox(eERType_SkinnedMeshRenderComponent, bbArea); - - numAllOccluders = numAZStaticMeshOccluders + numAZSkinnedMeshOccluders; - - AZStd::vector occluders(numAllOccluders); - - //Retrieve all AZ static mesh components in the bounding box - if (numAZStaticMeshOccluders > 0) - { - gEnv->p3DEngine->GetObjectsByTypeInBox(eERType_StaticMeshRenderComponent, bbArea, &occluders[0]); - } - //Retrieve all AZ skinned mesh components in the bounding box - if (numAZSkinnedMeshOccluders > 0) - { - gEnv->p3DEngine->GetObjectsByTypeInBox(eERType_SkinnedMeshRenderComponent, bbArea, &occluders[numAZStaticMeshOccluders]); - } - - // Set to new values, will be needed for other rain passes - m_RainInfo.areaAABB = bbArea; - fOccTreshold = CRenderer::CV_r_rainOccluderSizeTreshold; - fOldRadius = fRadius; - - AABB geomBB(AABB::RESET); - const size_t occluderLimit = min(numAllOccluders, nMAX_OCCLUDERS); - arrOccluders.resize(occluderLimit); - // Filter occluders and get bounding box - for (AZStd::vector::const_iterator it = occluders.begin(); - it != occluders.end() && m_RainOccluders.m_nNumOccluders < occluderLimit; - it++) - { - IRenderNode* pRndNode = *it; - if (pRndNode) - { - const AABB& aabb = pRndNode->GetBBox(); - const Vec3 vDiag = aabb.max - aabb.min; - const float fSqrFlatRadius = Vec2(vDiag.x, vDiag.y).GetLength2(); - const unsigned nRndNodeFlags = pRndNode->GetRndFlags(); - // TODO: rainoccluder should be the only flag tested - // (ie. enabled ONLY for small subset of geometry assets - means going through all assets affected by rain) - if ((fSqrFlatRadius < CRenderer::CV_r_rainOccluderSizeTreshold) - || !(nRndNodeFlags & ERF_RAIN_OCCLUDER) - || (nRndNodeFlags & (ERF_COLLISION_PROXY | ERF_RAYCAST_PROXY | ERF_HIDDEN))) - { - continue; - } - - N3DEngineCommon::SRainOccluder rainOccluder; - IStatObj* pObj = pRndNode->GetEntityStatObj(0, 0, &rainOccluder.m_WorldMat); - if (pObj) - { - const size_t nPrevIdx = m_RainOccluders.m_nNumOccluders; - if (pObj->GetFlags() & STATIC_OBJECT_COMPOUND) - { - const Matrix34A matParentTM = rainOccluder.m_WorldMat; - int nSubCount = pObj->GetSubObjectCount(); - for (int nSubId = 0; nSubId < nSubCount && m_RainOccluders.m_nNumOccluders < occluderLimit; nSubId++) - { - IStatObj::SSubObject* pSubObj = pObj->GetSubObject(nSubId); - if (pSubObj->bIdentityMatrix) - { - rainOccluder.m_WorldMat = matParentTM; - } - else - { - rainOccluder.m_WorldMat = matParentTM * pSubObj->localTM; - } - - IStatObj* pSubStatObj = pSubObj->pStatObj; - if (pSubStatObj && pSubStatObj->GetRenderMesh()) - { - rainOccluder.m_RndMesh = pSubStatObj->GetRenderMesh(); - arrOccluders[m_RainOccluders.m_nNumOccluders++] = rainOccluder; - } - } - } - else if (pObj->GetRenderMesh()) - { - rainOccluder.m_RndMesh = pObj->GetRenderMesh(); - arrOccluders[m_RainOccluders.m_nNumOccluders++] = rainOccluder; - } - - if (m_RainOccluders.m_nNumOccluders > nPrevIdx) - { - geomBB.Add(pRndNode->GetBBox()); - } - } - } - } - const bool bProcess = m_RainOccluders.m_nNumOccluders == 0; - for (uint32 i = 0; i < numGPUs; ++i) - { - m_RainOccluders.m_bProcessed[i] = bProcess; - } - m_RainInfo.bApplyOcclusion = m_RainOccluders.m_nNumOccluders > 0; - - geomBB.ClipToBox(bbArea); - - // Clip to ocean level - if (OceanToggle::IsActive()) - { - if (OceanRequest::OceanIsEnabled()) - { - geomBB.min.z = max(geomBB.min.z, OceanRequest::GetOceanLevel()) - 0.5f; - } - } - else - { - geomBB.min.z = max(geomBB.min.z, gEnv->p3DEngine->GetWaterLevel()) - 0.5f; - } - - float fWaterOffset = m_OceanInfo.m_fWaterLevel - geomBB.min.z; - fWaterOffset = (float)fsel(fWaterOffset, fWaterOffset, 0.0f); - - geomBB.min.z += fWaterOffset - 0.5f; - geomBB.max.z += fWaterOffset; - - Vec3 vSnappedCenter = bbArea.GetCenter() / rainBBHalfSize; - vSnappedCenter.Set(floor_tpl(vSnappedCenter.x), floor_tpl(vSnappedCenter.y), floor_tpl(vSnappedCenter.z)); - vSnappedCenter *= rainBBHalfSize; - - AABB occBB(fOccArea); - occBB.Move(vSnappedCenter); - occBB.min.z = max(occBB.min.z, geomBB.min.z); - occBB.max.z = min(occBB.max.z, geomBB.max.z); - - // Generate rotation matrix part-way from identity - // - Typical shadow filtering issues at grazing angles - Quat qOcc = m_RainInfo.qRainRotation; - qOcc.SetSlerp(qOcc, Quat::CreateIdentity(), 0.75f); - Matrix44 matRot(Matrix33(qOcc.GetInverted())); - - // Get occlusion transformation matrix - Matrix44& matOccTrans = m_RainInfo.matOccTrans; - Matrix44 matScale; - matOccTrans.SetIdentity(); - matOccTrans.SetTranslation(-occBB.min); - matScale.SetIdentity(); - const Vec3 vScale(occBB.max - occBB.min); - matScale.m00 = 1.f / vScale.x; - matScale.m11 = 1.f / vScale.y; - matScale.m22 = 1.f / vScale.z; - matOccTrans = matRot * matScale * matOccTrans; - } - } - -#if (defined(WIN32) || defined(WIN64)) && !defined(_RELEASE) - if (m_RainOccluders.m_nNumOccluders >= nMAX_OCCLUDERS) - { - CryWarning(VALIDATOR_MODULE_3DENGINE, VALIDATOR_WARNING, - "Reached max rain occluder limit (Max: %i), some objects may have been discarded!", nMAX_OCCLUDERS); - } -#endif - - m_RainOccluders.m_arrCurrOccluders[nThreadID].resize(m_RainOccluders.m_nNumOccluders); - std::copy(arrOccluders.begin(), arrOccluders.begin() + m_RainOccluders.m_nNumOccluders, m_RainOccluders.m_arrCurrOccluders[nThreadID].begin()); - } - - bOldDisableOcclusion = bDisableOcclusion; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -namespace WaterVolumeStaticData { - void GetMemoryUsage(ICrySizer* pSizer); -} - -void CRenderer::GetMemoryUsage(ICrySizer* pSizer) -{ - // should be called by all derived classes - for (uint32 i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - pSizer->AddObject(m_TextMessages[i]); - } - pSizer->AddObject(m_RP); - pSizer->AddObject(m_pRT); -# if 0 //XXXXXXXXXXXXXXXXXXXXXXX - pSizer->AddObject(m_DevBufMan); -# endif - WaterVolumeStaticData::GetMemoryUsage(pSizer); -} - -// retrieves the bandwidth calculations for the audio streaming -void CRenderer::GetBandwidthStats([[maybe_unused]] float* fBandwidthRequested) -{ -#if !defined (_RELEASE) - if (fBandwidthRequested) - { - *fBandwidthRequested = (CTexture::s_nBytesSubmittedToStreaming + CTexture::s_nBytesRequiredNotSubmitted) / 1024.0f; - } -#endif -} - - -////////////////////////////////////////////////////////////////////////// -void CRenderer::SetTextureStreamListener([[maybe_unused]] ITextureStreamListener* pListener) -{ -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - CTexture::s_pStreamListener = pListener; -#endif -} -////////////////////////////////////////////////////////////////////////// -float CRenderer::GetGPUFrameTime() -{ -#if defined(CRY_USE_METAL) || defined(ANDROID) - // TODO: if this won't work consider different frame time calculation - return gEnv->pTimer->GetRealFrameTime(); -#else -#if 0 - //If we are CPU bound and the GPU is starved for data, this causes idle time on the GPU - //between events, so the gpu timer events cannot be relied upon - - if (GpuTimerEvent::s_eventCount[GpuTimerEvent::s_readIdx] > 0) - { - LARGE_INTEGER ticksPerSecond; - QueryPerformanceFrequency(&ticksPerSecond); - - //Grab GPU frame time - assume first event - return GpuTimerEvent::s_events[GpuTimerEvent::s_readIdx][0].totalTime / (double)ticksPerSecond.QuadPart; - } - return 0.f; -#else - int nThr = m_pRT->GetThreadList(); - float fGPUidle = m_fTimeGPUIdlePercent[nThr] * 0.01f; // normalise % - float fGPUload = 1.0f - fGPUidle; // normalised non-idle time - float fGPUtime = (m_fTimeProcessedGPU[nThr] * fGPUload); //GPU time in seconds - return fGPUtime; -#endif -#endif -} - -void CRenderer::GetRenderTimes(SRenderTimes& outTimes) -{ - int nThr = m_pRT->GetThreadList(); - //Query render times on main thread - outTimes.fWaitForMain = m_fTimeWaitForMain[nThr]; - outTimes.fWaitForRender = m_fTimeWaitForRender[nThr]; - outTimes.fWaitForGPU = m_fTimeWaitForGPU[nThr]; - outTimes.fTimeProcessedRT = m_fTimeProcessedRT[nThr]; - outTimes.fTimeProcessedRTScene = m_RP.m_PS[nThr].m_fRenderTime; - outTimes.fTimeProcessedGPU = m_fTimeProcessedGPU[nThr]; - outTimes.fTimeGPUIdlePercent = m_fTimeGPUIdlePercent[nThr]; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::PreShutDown() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::PostShutDown() -{ - if (CTextureManager::InstanceExists()) - CTextureManager::Instance()->Release(); -} - -////////////////////////////////////////////////////////////////////////// - -bool CRenderer::IsCustomRenderModeEnabled([[maybe_unused]] uint32 nRenderModeMask) -{ - assert(nRenderModeMask); - - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CRenderer::IsPost3DRendererEnabled() const -{ - CPostEffectsMgr* pPostEffectMgr = PostEffectMgr(); - if (!pPostEffectMgr || !pPostEffectMgr->IsCreated()) - { - return false; - } - - CPostEffect* pPost3DRenderer = pPostEffectMgr->GetEffect(ePFX_Post3DRenderer); - if (pPost3DRenderer) - { - return pPost3DRenderer->IsActive(); - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_SetPostEffectParam(const char* pParam, float fValue, bool bForceValue) -{ - if (pParam && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfSetParameter(pParam, fValue, bForceValue); - } -} - -void CRenderer::EF_SetPostEffectParamVec4(const char* pParam, const Vec4& pValue, bool bForceValue) -{ - if (pParam && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfSetParameterVec4(pParam, pValue, bForceValue); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_SetPostEffectParamString(const char* pParam, const char* pszArg) -{ - if (pParam && pszArg && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfSetParameterString(pParam, pszArg); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_GetPostEffectParam(const char* pParam, float& fValue) -{ - if (pParam && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfGetParameter(pParam, fValue); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_GetPostEffectParamVec4(const char* pParam, Vec4& pValue) -{ - if (pParam && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfGetParameterVec4(pParam, pValue); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_GetPostEffectParamString(const char* pParam, const char*& pszArg) -{ - if (pParam && m_RP.m_pREPostProcess) - { - m_RP.m_pREPostProcess->mfGetParameterString(pParam, pszArg); - } -} - -////////////////////////////////////////////////////////////////////////// -int32 CRenderer::EF_GetPostEffectID(const char* pPostEffectName) -{ - if (pPostEffectName && m_RP.m_pREPostProcess) - { - return m_RP.m_pREPostProcess->mfGetPostEffectID(pPostEffectName); - } - return ePFX_Invalid; -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_ResetPostEffects(bool bOnSpecChange) -{ - m_pRT->RC_ResetPostEffects(bOnSpecChange); -} - -void CRenderer::SyncPostEffects() -{ - if (PostEffectMgr()) - { - PostEffectMgr()->SyncMainWithRender(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_DisableTemporalEffects() -{ - m_pRT->RC_DisableTemporalEffects(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - -void CRenderer::EF_AddWaterSimHit(const Vec3& vPos, const float scale, const float strength) -{ - CPostEffectsMgr* pPostEffectsMgr = PostEffectMgr(); - if (pPostEffectsMgr) - { - CWaterRipples* pWaterRipplesTech = (CWaterRipples*)pPostEffectsMgr->GetEffect(ePFX_WaterRipples); - if (pWaterRipplesTech) - { - pWaterRipplesTech->AddHit(vPos, scale, strength); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CRenderer::EF_DrawWaterSimHits() -{ - if (CPostEffectsMgr* pPostEffectsMgr = PostEffectMgr()) - { - if (CWaterRipples* pWaterRipplesTech = (CWaterRipples*)pPostEffectsMgr->GetEffect(ePFX_WaterRipples)) - { - pWaterRipplesTech->DEBUG_DrawWaterHits(); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CRenderer::SetTexturePrecaching(bool stat) -{ - CTexture::s_bPrecachePhase = stat; -} - -IOpticsElementBase* CRenderer::CreateOptics([[maybe_unused]] EFlareType type) const -{ -#ifdef NULL_RENDERER - return NULL; -#else - return COpticsFactory::GetInstance()->Create(type); -#endif -} - -void CRenderer::RT_UpdateLightVolumes([[maybe_unused]] int32 nFlags, [[maybe_unused]] int32 nRecurseLevel) -{ - AZ_TRACE_METHOD(); - gEnv->p3DEngine->GetLightVolumes(m_RP.m_nProcessThreadID, m_pLightVols, m_nNumVols); -} -////////////////////////////////////////////////////////////////////////// - -SSkinningData* CRenderer::EF_CreateSkinningData(uint32 nNumBones, bool bNeedJobSyncVar, bool bUseMatrixSkinning) -{ - AZ_TRACE_METHOD(); - int nList = m_nPoolIndex % 3; - - uint32 skinningFlags = bUseMatrixSkinning ? eHWS_Skinning_Matrix : 0; - - uint32 nNeededSize = Align(sizeof(SSkinningData), 16); - - size_t boneSize = bUseMatrixSkinning ? sizeof(Matrix34) : sizeof(DualQuat); - - nNeededSize += Align(nNumBones * boneSize, 16); - byte* pData = m_SkinningDataPool[nList].Allocate(nNeededSize); - - SSkinningData* pSkinningRenderData = alias_cast(pData); - pData += Align(sizeof(SSkinningData), 16); - - pSkinningRenderData->pAsyncJobExecutor = bNeedJobSyncVar ? m_jobExecutorPool.Allocate() : nullptr; - pSkinningRenderData->pAsyncDataJobExecutor = bNeedJobSyncVar ? m_jobExecutorPool.Allocate() : nullptr; - - if (bUseMatrixSkinning) - { - pSkinningRenderData->pBoneMatrices = alias_cast(pData); - pSkinningRenderData->pBoneQuatsS = nullptr; - } - else - { - pSkinningRenderData->pBoneQuatsS = alias_cast(pData); - pSkinningRenderData->pBoneMatrices = nullptr; - } - - pData += Align(nNumBones * boneSize, 16); - - pSkinningRenderData->pRemapTable = NULL; - pSkinningRenderData->pCustomData = NULL; - pSkinningRenderData->nNumBones = nNumBones; - pSkinningRenderData->nHWSkinningFlags = skinningFlags; - pSkinningRenderData->pPreviousSkinningRenderData = NULL; - pSkinningRenderData->pCharInstCB = FX_AllocateCharInstCB(pSkinningRenderData, m_nPoolIndex); - pSkinningRenderData->remapGUID = ~0u; - - pSkinningRenderData->pNextSkinningData = NULL; - pSkinningRenderData->pMasterSkinningDataList = &pSkinningRenderData->pNextSkinningData; - - return pSkinningRenderData; -} - -SSkinningData* CRenderer::EF_CreateRemappedSkinningData(uint32 nNumBones, SSkinningData* pSourceSkinningData, uint32 nCustomDataSize, uint32 pairGuid) -{ - assert(pSourceSkinningData); - assert(pSourceSkinningData->nNumBones >= nNumBones); // don't try to remap more bones than exist - - int nList = m_nPoolIndex % 3; - - uint32 nNeededSize = Align(sizeof(SSkinningData), 16); - nNeededSize += Align(nCustomDataSize, 16); - - byte* pData = m_SkinningDataPool[nList].Allocate(nNeededSize); - - SSkinningData* pSkinningRenderData = alias_cast(pData); - pData += Align(sizeof(SSkinningData), 16); - - pSkinningRenderData->pRemapTable = NULL; - - pSkinningRenderData->pCustomData = nCustomDataSize ? alias_cast(pData) : NULL; - pData += nCustomDataSize ? Align(nCustomDataSize, 16) : 0; - - pSkinningRenderData->nNumBones = nNumBones; - pSkinningRenderData->nHWSkinningFlags = pSourceSkinningData->nHWSkinningFlags; - pSkinningRenderData->pPreviousSkinningRenderData = NULL; - - // use actual bone information from original skinning data - pSkinningRenderData->pBoneQuatsS = pSourceSkinningData->pBoneQuatsS; - pSkinningRenderData->pBoneMatrices = pSourceSkinningData->pBoneMatrices; - pSkinningRenderData->pAsyncJobExecutor = pSourceSkinningData->pAsyncJobExecutor; - pSkinningRenderData->pAsyncDataJobExecutor = pSourceSkinningData->pAsyncDataJobExecutor; - - pSkinningRenderData->pCharInstCB = pSourceSkinningData->pCharInstCB; - - pSkinningRenderData->remapGUID = pairGuid; - pSkinningRenderData->pNextSkinningData = NULL; - pSkinningRenderData->pMasterSkinningDataList = &pSourceSkinningData->pNextSkinningData; - - return pSkinningRenderData; -} - -void CRenderer::RT_SetSkinningPoolId(uint32 poolId) -{ - m_nPoolIndexRT = poolId; -} - -void CRenderer::EF_ClearSkinningDataPool() -{ - AZ_TRACE_METHOD(); - m_pRT->RC_PushSkinningPoolId(++m_nPoolIndex); - m_SkinningDataPool[m_nPoolIndex % 3].ClearPool(); - FX_ClearCharInstCB(m_nPoolIndex); - - m_jobExecutorPool.AdvanceCurrent(); -} - -int CRenderer::EF_GetSkinningPoolID() -{ - return m_nPoolIndex; -} - -// If the render pipeline has a reference to this shader item, set it to nullptr to avoid a dangling pointer -void CRenderer::ClearShaderItem(SShaderItem* pShaderItem) -{ - if (pShaderItem->m_pShaderResources && gRenDev->m_pRT && gRenDev->m_pRT->IsRenderThread()) - { - CShaderResources* shaderResources = static_cast(pShaderItem->m_pShaderResources); - if (gRenDev->m_RP.m_pShaderResources == shaderResources) - { - gRenDev->m_RP.m_pShaderResources = nullptr; - } - - for (int i = 0; i < EFTT_MAX; ++i) - { - SEfResTexture* pTexture = shaderResources->GetTextureResource(i); - if (gRenDev->m_RP.m_ShaderTexResources[i] == pTexture) - { - gRenDev->m_RP.m_ShaderTexResources[i] = nullptr; - } - } -/* @barled - adibugbug - put back in place!!! - for (auto iter = shaderResources->m_TexturesResourcesMap.begin(); iter != shaderResources->m_TexturesResourcesMap.end(); ++iter) - { - SEfResTexture* pTexture = &iter->second; - uint16 nSlot = iter->first; - if (gRenDev->m_RP.m_ShaderTexResources[nSlot] == pTexture) - { // Notice the usage of pointer for the comparison - should be revisited? - gRenDev->m_RP.m_ShaderTexResources[nSlot] = nullptr; - } - } -*/ - } -} - -void CRenderer::UpdateShaderItem(SShaderItem* pShaderItem, _smart_ptr pMaterial) -{ - bool bShaderReloaded = false; -#if !defined(_RELEASE) || (defined(WIN32) || defined(WIN64)) - IShader* pShader = pShaderItem->m_pShader; - if (pShader) - { - bShaderReloaded = (pShader->GetFlags() & EF_RELOADED) != 0; - } -#endif - - if (pShaderItem->m_nPreprocessFlags == -1 || bShaderReloaded) - { - CRenderer::ForceUpdateShaderItem(pShaderItem, pMaterial); - } -} - -void CRenderer::RefreshShaderResourceConstants(SShaderItem* pShaderItem, IMaterial* pMaterial) -{ - m_pRT->RC_RefreshShaderResourceConstants(pShaderItem, pMaterial); -} - -void CRenderer::ForceUpdateShaderItem(SShaderItem* pShaderItem, _smart_ptr pMaterial) -{ - m_pRT->RC_UpdateShaderItem(pShaderItem, pMaterial); -} - -void CRenderer::RT_UpdateShaderItem(SShaderItem* pShaderItem, IMaterial* material) -{ - AZ_TRACE_METHOD(); - CShader* pShader = static_cast(pShaderItem->m_pShader); - if (pShader) - { - pShader->m_Flags &= ~EF_RELOADED; - pShaderItem->Update(); - } - - if (material) - { - // We received a raw pointer to the material instead of a smart_ptr because writing/reading smart pointers from - // the render thread queue causes the ref count to be increased incorrectly in some platforms (e.g. 32 bit architectures). - // In order to keep the material reference "alive" we manually increment the reference count and decrement it when we finish using it. - material->AddRef(); - AZStd::function runOnMainThread = [material]() - { - // Updating the material flags after the shader has been parse and loaded. - material->UpdateFlags(); - // Remove reference that we added. - material->Release(); - }; - - EBUS_QUEUE_FUNCTION(AZ::MainThreadRenderRequestBus, runOnMainThread); - } -} - -void CRenderer::RT_RefreshShaderResourceConstants(SShaderItem* shaderItem) const -{ - if (CShader* shader = static_cast(shaderItem->m_pShader)) - { - if (shaderItem->RefreshResourceConstants()) - { - shaderItem->m_pShaderResources->UpdateConstants(shader); - } - } -} - -void CRenderer::GetClampedWindowSize(int& widthPixels, int& heightPixels) -{ - const int maxWidth = gEnv->pConsole->GetCVar("r_maxWidth")->GetIVal(); - const int maxHeight = gEnv->pConsole->GetCVar("r_maxheight")->GetIVal(); - - if (maxWidth > 0 && maxWidth < widthPixels) - { - const float widthScaleFactor = static_cast(maxWidth) / static_cast(widthPixels); - widthPixels = aznumeric_cast(widthPixels * widthScaleFactor); - heightPixels = aznumeric_cast(heightPixels * widthScaleFactor); - } - - if (maxHeight > 0 && maxHeight < heightPixels) - { - const float heightScaleFactor = static_cast(maxHeight) / static_cast(heightPixels); - widthPixels = aznumeric_cast(widthPixels * heightScaleFactor); - heightPixels = aznumeric_cast(heightPixels * heightScaleFactor); - } -} - -CRenderView* CRenderer::GetRenderViewForThread(int nThreadID) -{ - return m_RP.m_pRenderViews[nThreadID].get(); -} - -bool CRenderer::UseHalfFloatRenderTargets() -{ -#if defined(OPENGL_ES) && !defined(AZ_PLATFORM_LINUX) - // When using OpenGL ES on Linux, DXGL_GL_EXTENSION_SUPPORTED(EXT_color_buffer_half_float) returns false, - // however with at least the Mesa driver, half float render targets are natively supported. - return RenderCapabilities::SupportsHalfFloatRendering() && (!CRenderer::CV_r_ForceFixedPointRenderTargets); -#else - return true; -#endif -} - -Matrix44A CRenderer::GetCameraMatrix() -{ - return m_CameraMatrix; -} - -void CRenderer::SyncMainWithRender() -{ - const uint numListeners = m_syncMainWithRenderListeners.size(); - for (uint i = 0; i < numListeners; ++i) - { - m_syncMainWithRenderListeners[i]->SyncMainWithRender(); - } -} - -void CRenderer::RegisterSyncWithMainListener(ISyncMainWithRenderListener* pListener) -{ - stl::push_back_unique(m_syncMainWithRenderListeners, pListener); -} - -void CRenderer::RemoveSyncWithMainListener(const ISyncMainWithRenderListener* pListener) -{ - stl::find_and_erase(m_syncMainWithRenderListeners, pListener); -} - -void CRenderer::UpdateCachedShadowsLodCount([[maybe_unused]] int nGsmLods) const -{ - OnChange_CachedShadows(NULL); -} - -ITexture* CRenderer::GetWhiteTexture() -{ - return CTextureManager::Instance()->GetWhiteTexture(); -} - -ITexture* CRenderer::GetTextureForName(const char* name, uint32 nFlags, ETEX_Format eFormat) -{ - return CTexture::ForName(name, nFlags, eFormat); -} - -int CRenderer::GetRecursionLevel() -{ - return SRendItem::m_RecurseLevel[GetRenderPipeline()->m_nProcessThreadID]; -} - -int CRenderer::GetIntegerConfigurationValue(const char* varName, int defaultValue) -{ - ICVar* var = varName ? gEnv->pConsole->GetCVar(varName) : nullptr; - AZ_Assert(var, "Unable to find cvar: %s", varName) - return var ? var->GetIVal() : defaultValue; -} - -float CRenderer::GetFloatConfigurationValue(const char* varName, float defaultValue) -{ - ICVar* var = varName ? gEnv->pConsole->GetCVar(varName) : nullptr; - AZ_Assert(var, "Unable to find cvar: %s", varName) - return var ? var->GetFVal() : defaultValue; -} - -bool CRenderer::GetBooleanConfigurationValue(const char* varName, bool defaultValue) -{ - ICVar* var = varName ? gEnv->pConsole->GetCVar(varName) : nullptr; - AZ_Assert(var, "Unable to find cvar: %s", varName) - return var ? (var->GetIVal() != 0) : defaultValue; -} - -// Methods exposed to external libraries -void CRenderer::ApplyDepthTextureState(int unit, int nFilter, bool clamp) -{ - CTexture::ApplyDepthTextureState(unit, nFilter, clamp); -} - -ITexture* CRenderer::GetZTargetTexture() -{ - return CTexture::GetZTargetTexture(); -} - -int CRenderer::GetTextureState(const STexState& TS) -{ - return CTexture::GetTextureState(TS); -} - -uint32 CRenderer::TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, const ETEX_Format eTF, ETEX_TileMode eTM) -{ - return CTexture::TextureDataSize(nWidth, nHeight, nDepth, nMips, nSlices, eTF, eTM); -} - -void CRenderer::ApplyForID(int nID, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit, bool useWhiteDefault) -{ - CTexture::ApplyForID(nID, nTUnit, nTState, nTexMaterialSlot, nSUnit, useWhiteDefault); -} - -ITexture* CRenderer::Create3DTexture(const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst) -{ - return CTexture::Create3DTexture(szName, nWidth, nHeight, nDepth, nMips, nFlags, pData, eTFSrc, eTFDst); -} - -bool CRenderer::IsTextureExist(const ITexture* pTex) -{ - return CTexture::IsTextureExist(pTex); -} - -const char* CRenderer::NameForTextureFormat(ETEX_Format eTF) -{ - return CTexture::NameForTextureFormat(eTF); -} - -const char* CRenderer::NameForTextureType(ETEX_Type eTT) -{ - return CTexture::NameForTextureType(eTT); -} - -bool CRenderer::IsVideoThreadModeEnabled() -{ - return m_pRT->m_eVideoThreadMode != SRenderThread::eVTM_Disabled; -} - -IDynTexture* CRenderer::CreateDynTexture2(uint32 nWidth, uint32 nHeight, uint32 nTexFlags, const char* szSource, ETexPool eTexPool) -{ - return new SDynTexture2(nWidth, nHeight, nTexFlags, szSource, eTexPool); -} - -uint32 CRenderer::GetCurrentTextureAtlasSize() -{ - return SDynTexture::s_CurTexAtlasSize; -} - -void CRenderer::RT_InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) -{ - AZ_Assert(pVideoRenderer != nullptr, "Expected video player to be passed in"); - - AZ::VideoRenderer::VideoTexturesDesc videoTexturesDesc; - if (pVideoRenderer && pVideoRenderer->GetVideoTexturesDesc(videoTexturesDesc)) - { - AZ::VideoRenderer::VideoTextures videoTextures; - - auto InitVideoTexture = [](const AZ::VideoRenderer::VideoTextureDesc& videoTextureDesc, uint32 flags) -> uint32 - { - uint32 resultTextureId = 0; - if (videoTextureDesc.m_used) - { - CTexture* pCreatedPlaneTexture = CTexture::Create2DTexture(videoTextureDesc.m_name, videoTextureDesc.m_width, videoTextureDesc.m_height, 1, flags, nullptr, videoTextureDesc.m_format, videoTextureDesc.m_format); - if (pCreatedPlaneTexture != nullptr) - { - resultTextureId = pCreatedPlaneTexture->GetTextureID(); - } - } - return resultTextureId; - }; - - videoTextures.m_outputTextureId = InitVideoTexture(videoTexturesDesc.m_outputTextureDesc, FT_USAGE_RENDERTARGET); - - for (uint32 videoIndex = 0; videoIndex < AZ::VideoRenderer::MaxInputTextureCount; videoIndex++) - { - videoTextures.m_inputTextureIds[videoIndex] = InitVideoTexture(videoTexturesDesc.m_inputTextureDescs[videoIndex], 0); - } - - pVideoRenderer->NotifyTexturesCreated(videoTextures); - } -} - -void CRenderer::RT_CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) -{ - AZ_Assert(pVideoRenderer != nullptr, "Expected video player to be passed in"); - - AZ::VideoRenderer::VideoTextures videoTextures; - if (pVideoRenderer && pVideoRenderer->GetVideoTextures(videoTextures)) - { - auto ReleaseVideoTexture = [](uint32 textureId) - { - if (textureId != 0) - { - if (CTexture* pTexture = CTexture::GetByID(textureId)) - { - pTexture->Release(); - } - } - }; - - ReleaseVideoTexture(videoTextures.m_outputTextureId); - - for (uint32 textureId : videoTextures.m_inputTextureIds) - { - ReleaseVideoTexture(textureId); - } - - pVideoRenderer->NotifyTexturesDestroyed(); - } -} - -#ifndef _RELEASE -int CRenderer::GetDrawCallsPerNode(IRenderNode* pRenderNode) -{ - uint32 t = m_RP.m_nFillThreadID; - IRenderer::RNDrawcallsMapNodeItor iter = m_RP.m_pRNDrawCallsInfoPerNode[t].find(pRenderNode); - if (iter != m_RP.m_pRNDrawCallsInfoPerNode[t].end()) - { - SDrawCallCountInfo& pInfo = iter->second; - uint32 nDrawcalls = pInfo.nShadows + pInfo.nZpass + pInfo.nGeneral + pInfo.nTransparent + pInfo.nMisc; - return nDrawcalls; - } - - return 0; -} -#endif diff --git a/Code/CryEngine/RenderDll/Common/Renderer.h b/Code/CryEngine/RenderDll/Common/Renderer.h deleted file mode 100644 index 7f731ec623..0000000000 --- a/Code/CryEngine/RenderDll/Common/Renderer.h +++ /dev/null @@ -1,2733 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "TextMessages.h" // CTextMessages -#include "RenderAuxGeom.h" -#include "Shaders/Vertex.h" -#include -#include -#include -#include -#include - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RENDERER_H_SECTION_1 1 -#define RENDERER_H_SECTION_2 2 -#define RENDERER_H_SECTION_3 3 -#define RENDERER_H_SECTION_4 4 -#define RENDERER_H_SECTION_5 5 -#define RENDERER_H_SECTION_6 6 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_1 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif - -typedef void (PROCRENDEF)(SShaderPass* l, int nPrimType); - -#define USE_NATIVE_DEPTH 1 - -enum eAntialiasingType -{ - eAT_NOAA = 0, - eAT_FXAA, - eAT_SMAA1TX, - eAT_TAA, - eAT_AAMODES_COUNT, - - eAT_DEFAULT_AA = eAT_TAA, - - eAT_NOAA_MASK = (1 << eAT_NOAA), - eAT_FXAA_MASK = (1 << eAT_FXAA), - eAT_SMAA_MASK = (1 << eAT_SMAA1TX), - eAT_TAA_MASK = (1 << eAT_TAA), - - eAT_TEMPORAL_MASK = (eAT_TAA_MASK | eAT_SMAA_MASK), - eAT_JITTER_MASK = (eAT_TAA_MASK) -}; - -static const char* s_pszAAModes[eAT_AAMODES_COUNT] = -{ - "NO AA", - "FXAA", - "SMAA 1tx", - "TAA" -}; - -struct ICVar; -struct ShadowMapFrustum; -struct IStatObj; -struct SShaderPass; -class CD3DStereoRenderer; -class IOpticsManager; -struct SDynTexture2; -struct SDepthTexture; -namespace Render -{ - namespace Debug - { - class VRAMDriller; - } -} - -typedef int (* pDrawModelFunc)(void); - -#define RENDER_LOCK_CS(csLock) CryAutoCriticalSection __AL__##__FILE__##_LINE(csLock) - -//============================================================= - -#define D3DRGBA(r, g, b, a) \ - ((((int)((a) * 255)) << 24) | (((int)((r) * 255)) << 16) \ - | (((int)((g) * 255)) << 8) | (int)((b) * 255) \ - ) - -#define CONSOLES_BACKBUFFER_WIDTH CRenderer::CV_r_ConsoleBackbufferWidth -#define CONSOLES_BACKBUFFER_HEIGHT CRenderer::CV_r_ConsoleBackbufferHeight - -// Assuming 24 bits of depth precision -#define DBT_SKY_CULL_DEPTH 0.99999994f - -#define DEF_SHAD_DBT_DEFAULT_VAL 1 - -#if defined(AZ_PLATFORM_IOS) || defined (AZ_PLATFORM_ANDROID) - #define TEXSTREAMING_DEFAULT_VAL 0 -#else - #define TEXSTREAMING_DEFAULT_VAL 1 -#endif - - -#define GEOM_INSTANCING_DEFAULT_VAL 1 -#define COLOR_GRADING_DEFAULT_VAL 1 -#define SUNSHAFTS_DEFAULT_VAL 2 -#define HDR_RANGE_ADAPT_DEFAULT_VAL 0 -#define HDR_RENDERING_DEFAULT_VAL 1 -#define SHADOWS_POOL_DEFAULT_VAL 1 -#define SHADOWS_CLIP_VOL_DEFAULT_VAL 1 -#define SHADOWS_BLUR_DEFAULT_VAL 3 -#define TEXPREALLOCATLAS_DEFAULT_VAL 0 -#define TEXMAXANISOTROPY_DEFAULT_VAL 8 -#if defined(CONSOLE) - #define TEXNOANISOALPHATEST_DEFAULT_VAL 1 -#else - #define TEXNOANISOALPHATEST_DEFAULT_VAL 0 -#endif -#define ENVTEXRES_DEFAULT_VAL 3 -#define WATERREFLQUAL_DEFAULT_VAL 4 -#define DOF_DEFAULT_VAL 2 -#define SHADERS_ALLOW_COMPILATION_DEFAULT_VAL 1 -#define SHADERS_PREACTIVATE_DEFAULT_VAL 3 -#define CUSTOMVISIONS_DEFAULT_VAL 3 -#define FLARES_DEFAULT_VAL 1 -#define WATERVOLCAUSTICS_DEFAULT_VAL 1 -#define FLARES_HQSHAFTS_DEFAULT_VAL 1 -#define DEF_SHAD_DBT_STENCIL_DEFAULT_VAL 1 -#define DEF_SHAD_SSS_DEFAULT_VAL 1 - -#define MULTITHREADED_DEFAULT_VAL 1 -#define ZPASS_DEPTH_SORT_DEFAULT_VAL 1 -#define TEXSTREAMING_UPDATETYPE_DEFAULT_VAL 1 - -#if defined(WIN32) || defined(APPLE) || defined(LINUX) || defined(SET_CBUFFER_NATIVE_DEPTH_DEAFULT_VAL_TO_1) - #define CBUFFER_NATIVE_DEPTH_DEAFULT_VAL 1 -#else - #define CBUFFER_NATIVE_DEPTH_DEAFULT_VAL 0 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_2 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif - -////////////////////////////////////////////////////////////////////// -// Class to manage memory for Skinning Renderer Data -class CSkinningDataPool -{ -public: - CSkinningDataPool() - : m_pPool(NULL) - , m_pPages(NULL) - , m_nPoolSize(0) - , m_nPoolUsed(0) - , m_nPageAllocated(0) - {} - - ~CSkinningDataPool() - { - // free temp pages - SPage* pPage = m_pPages; - while (pPage) - { - SPage* pPageToDelete = pPage; - pPage = pPage->pNext; - - CryModuleMemalignFree(pPageToDelete); - } - - // free pool - CryModuleMemalignFree(m_pPool); - } - - byte* Allocate(size_t nBytes) - { - // If available use allocated page space - uint32 nPoolUsed = ~0; - do - { - nPoolUsed = *const_cast(&m_nPoolUsed); - size_t nPoolFree = m_nPoolSize - nPoolUsed; - if (nPoolFree < nBytes) - { - break; // not enough memory, use fallback - } - if (CryInterlockedCompareExchange(alias_cast(&m_nPoolUsed), nPoolUsed + nBytes, nPoolUsed) == nPoolUsed) - { - return &m_pPool[nPoolUsed]; - } - } while (true); - - // Create memory - byte* pMemory = alias_cast(CryModuleMemalign(Align(nBytes, 16) + 16, 16)); - SPage* pNewPage = alias_cast(pMemory); - - // Assign page - volatile SPage* pPages = 0; - do - { - pPages = *(const_cast(&m_pPages)); - pNewPage->pNext = alias_cast(pPages); - } while (CryInterlockedCompareExchangePointer(alias_cast(&m_pPages), pNewPage, (void*)pPages) != pPages); - - CryInterlockedAdd((volatile int*)&m_nPageAllocated, nBytes); - - return pMemory + 16; - } - - void ClearPool() - { - m_nPoolUsed = 0; - if (m_nPageAllocated) - { - // free temp pages - SPage* pPage = m_pPages; - while (pPage) - { - SPage* pPageToDelete = pPage; - pPage = pPage->pNext; - - CryModuleMemalignFree(pPageToDelete); - } - - // adjust pool size - CryModuleMemalignFree(m_pPool); - m_nPoolSize += m_nPageAllocated; - m_pPool = alias_cast(CryModuleMemalign(m_nPoolSize, 16)); - - // reset state - m_pPages = NULL; - m_nPageAllocated = 0; - } - } - - void FreePoolMemory() - { - // free temp pages - SPage* pPage = m_pPages; - while (pPage) - { - SPage* pPageToDelete = pPage; - pPage = pPage->pNext; - - CryModuleMemalignFree(pPageToDelete); - } - - // free pool - CryModuleMemalignFree(m_pPool); - - m_pPool = NULL; - m_pPages = NULL; - m_nPoolSize = 0; - m_nPoolUsed = 0; - m_nPageAllocated = 0; - } - - size_t AllocatedMemory() - { - return m_nPoolSize + m_nPageAllocated; - } -private: - struct SPage - { - SPage* pNext; - }; - - byte* m_pPool; - SPage* m_pPages; - size_t m_nPoolSize; - size_t m_nPoolUsed; - size_t m_nPageAllocated; -}; - -namespace LegacyInternal -{ - class JobExecutorPool final - { - public: - static const AZ::u32 NumPools = 3; // Skinning data is triple buffered, see usage of m_SkinningDataPool - - void AdvanceCurrent() - { - m_current = (m_current + 1) % JobExecutorPool::NumPools; - auto& currentAllocatedList = m_allocated[m_current]; - - // Move all current instances to the free list - m_freeList.reserve(m_freeList.size() + currentAllocatedList.size()); - for (auto& allocatedEntry : currentAllocatedList) - { - m_freeList.emplace_back(std::move(allocatedEntry)); - } - currentAllocatedList.clear(); - } - - AZ::LegacyJobExecutor* Allocate() - { - auto& currentAllocatedList = m_allocated[m_current]; - - if (!m_freeList.empty()) - { - // move from the freelist - currentAllocatedList.emplace_back(std::move(m_freeList.back())); - m_freeList.pop_back(); - } - else - { - currentAllocatedList.emplace_back(AZStd::make_unique()); - } - - return currentAllocatedList.back().get(); - } - - private: - // We point to instances because LegacyJobExecutor instances are not movable - using JobExecutorList = AZStd::vector>; - - JobExecutorList m_allocated[JobExecutorPool::NumPools]; - JobExecutorList m_freeList; - AZ::u32 m_current = 0; - }; -} - -////////////////////////////////////////////////////////////////////// -class CFillRateManager - : private stl::PSyncDebug -{ -public: - CFillRateManager() - : m_fTotalPixels(0.f) - , m_fMaxPixels(1e9f) - {} - void Reset() - { - m_fTotalPixels = 0.f; - m_afPixels.resize(0); - } - float GetMaxPixels() const - { - return m_fMaxPixels; - } - void AddPixelCount(float fPixels); - void ComputeMaxPixels(); - -private: - float m_fTotalPixels; - float m_fMaxPixels; - FastDynArray m_afPixels; -}; - -////////////////////////////////////////////////////////////////////// -// 3D engine duplicated data for non-thread safe data -namespace N3DEngineCommon -{ - struct SOceanInfo - { - SOceanInfo() - : m_nOceanRenderFlags(0) - , m_fWaterLevel(0.0f) - , m_vMeshParams(0.0f, 0.0f, 0.0f, 0.0f) { }; - Vec4 m_vMeshParams; - float m_fWaterLevel; - uint8 m_nOceanRenderFlags; - }; - - struct SVisAreaInfo - { - SVisAreaInfo() - : nFlags(0) - { - }; - uint32 nFlags; - }; - - struct SRainOccluder - { - SRainOccluder() - : m_RndMesh(0) - , m_WorldMat(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0) {} - _smart_ptr m_RndMesh; - Matrix34 m_WorldMat; - }; - - typedef std::vector ArrOccluders; - - struct SRainOccluders - { - ArrOccluders m_arrOccluders; - ArrOccluders m_arrCurrOccluders[RT_COMMAND_BUF_COUNT]; - size_t m_nNumOccluders; - bool m_bProcessed[MAX_GPU_NUM]; - - SRainOccluders() - : m_nNumOccluders(0) - { - for (int i = 0; i < MAX_GPU_NUM; ++i) - { - m_bProcessed[i] = true; - } - } - ~SRainOccluders() { Release(); } - void Release(bool bAll = false) - { - stl::free_container(m_arrOccluders); - m_nNumOccluders = 0; - if (bAll) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - stl::free_container(m_arrCurrOccluders[i]); - } - } - for (int i = 0; i < MAX_GPU_NUM; ++i) - { - m_bProcessed[i] = true; - } - } - }; - - struct SCausticInfo - { - SCausticInfo() - : m_pCausticQuadMesh(0) - , m_nCausticMeshWidth(0) - , m_nCausticMeshHeight(0) - , m_nCausticQuadTaps(0) - , m_nVertexCount(0) - , m_nIndexCount(0) - { - } - - ~SCausticInfo() { Release(); } - void Release() - { - m_pCausticQuadMesh = NULL; - } - - _smart_ptr m_pCausticQuadMesh; - uint32 m_nCausticMeshWidth; - uint32 m_nCausticMeshHeight; - uint32 m_nCausticQuadTaps; - uint32 m_nVertexCount; - uint32 m_nIndexCount; - - Matrix44A m_mCausticMatr; - Matrix34 m_mCausticViewMatr; - }; -} - -struct S3DEngineCommon -{ - enum EVisAreaFlags - { - VAF_EXISTS_FOR_POSITION = (1 << 0), - VAF_CONNECTED_TO_OUTDOOR = (1 << 1), - VAF_AFFECTED_BY_OUT_LIGHTS = (1 << 2), - VAF_MASK = VAF_EXISTS_FOR_POSITION | VAF_CONNECTED_TO_OUTDOOR | VAF_AFFECTED_BY_OUT_LIGHTS - }; - - N3DEngineCommon::SVisAreaInfo m_pCamVisAreaInfo; - N3DEngineCommon::SOceanInfo m_OceanInfo; - N3DEngineCommon::SRainOccluders m_RainOccluders; - N3DEngineCommon::SCausticInfo m_CausticInfo; - SRainParams m_RainInfo; - SSnowParams m_SnowInfo; - - void Update(threadID nThreadID); - void UpdateRainInfo(threadID nThreadID); - void UpdateRainOccInfo(int nThreadID); - void UpdateSnowInfo(int nThreadID); -}; - -struct SShowRenderTargetInfo -{ - SShowRenderTargetInfo() { Reset(); } - void Reset() - { - bShowList = false; - bDisplayTransparent = false; - col = 2; - rtList.clear(); - } - - bool bShowList; - bool bDisplayTransparent; - int col; - struct RT - { - int textureID; - Vec4 channelWeight; - bool bFiltered; - bool bRGBKEncoded; - bool bAliased; - }; - std::vector rtList; -}; - -struct SRenderTileInfo -{ - SRenderTileInfo() { nPosX = nPosY = nGridSizeX = nGridSizeY = 0.f; } - f32 nPosX, nPosY, nGridSizeX, nGridSizeY; -}; - -class RendererAssetListener - : public AzFramework::LegacyAssetEventBus::MultiHandler -{ -public: - RendererAssetListener(IRenderer* renderer); - void Connect(); - void Disconnect(); - - void OnFileChanged(AZStd::string assetName) override; -private: - IRenderer* m_renderer; -}; - - -////////////////////////////////////////////////////////////////////// -struct SRenderPipeline; -class CRenderer - : public IRenderer -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_3 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif -{ -public: - - DEFINE_ALIGNED_DATA(Matrix44A, m_IdentityMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ViewMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_CameraMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_CameraZeroMatrix[RT_COMMAND_BUF_COUNT], 16); - - DEFINE_ALIGNED_DATA(Matrix44A, m_ProjMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ProjNoJitterMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_TranspOrigCameraProjMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ViewProjMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ViewProjNoJitterMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ViewProjNoTranslateMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_ViewProjInverseMatrix, 16); - DEFINE_ALIGNED_DATA(Matrix44A, m_TempMatrices[4][8], 16); - - struct PreviousFrameMatrixSet - { - Vec3 m_WorldViewPosition; - - Matrix44A m_ViewMatrix; - Matrix44A m_ViewNoTranslateMatrix; - - // These are always de-jittered. - Matrix44A m_ProjMatrix; - Matrix44A m_ViewProjMatrix; - Matrix44A m_ViewProjNoTranslateMatrix; - }; - - PreviousFrameMatrixSet m_PreviousFrameMatrixSets[MAX_NUM_VIEWPORTS][2]; - - const PreviousFrameMatrixSet& GetPreviousFrameMatrixSet() const - { - return m_PreviousFrameMatrixSets[m_CurViewportID][m_CurRenderEye]; - } - - static float GetRealTime() - { - const auto& renderPipeline = gRenDev->m_RP; - return renderPipeline.m_TI[renderPipeline.m_nProcessThreadID].m_RealTime; - } - - static float GetElapsedTime() - { - return gEnv->pTimer->GetFrameTime(); - } - - DEFINE_ALIGNED_DATA(Matrix44A, m_CameraMatrixNearest, 16); //[RT_COMMAND_BUF_COUNT][2], 16); - - float m_TemporalJitterMipBias; - Vec4 m_TemporalJitterClipSpace; - - byte m_bDeviceLost; - byte m_bSystemResourcesInit; - byte m_bSystemTargetsInit; - bool m_bAquireDeviceThread; - bool m_bInitialized; - bool m_bDualStereoSupport; - - SRenderThread* m_pRT; - - virtual SRenderPipeline* GetRenderPipeline() override { return &m_RP; } - virtual SRenderThread* GetRenderThread() override { return m_pRT; } - virtual CShaderMan* GetShaderManager() override { return &m_cEF; } - virtual uint32 GetFrameReset() override { return m_nFrameReset; } - virtual CDeviceBufferManager* GetDeviceBufferManager() override { return &m_DevBufMan; } - - // Shaders pipeline states - //============================================================================================================= - CDeviceManager m_DevMan; - CDeviceBufferManager m_DevBufMan; - SRenderPipeline m_RP; - //============================================================================================================= - - float m_fTimeWaitForMain[RT_COMMAND_BUF_COUNT]; - float m_fTimeWaitForRender[RT_COMMAND_BUF_COUNT]; - float m_fTimeProcessedRT[RT_COMMAND_BUF_COUNT]; - float m_fTimeProcessedGPU[RT_COMMAND_BUF_COUNT]; - float m_fTimeWaitForGPU[RT_COMMAND_BUF_COUNT]; - float m_fTimeGPUIdlePercent[RT_COMMAND_BUF_COUNT]; - - float m_fRTTimeEndFrame; - float m_fRTTimeSceneRender; - float m_fRTTimeMiscRender; - - int m_CurVertBufferSize; - int m_CurIndexBufferSize; - - int m_VSync; - int m_Predicated; - int m_MSAA; - int m_MSAA_quality; - int m_MSAA_samples; - int m_deskwidth, m_deskheight; - int m_nHDRType; - - // Index of the current viewport used for rendering. - int m_CurViewportID; - // Index of the current eye used for rendering. - int m_CurRenderEye; - -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - float m_overrideRefreshRate; - int m_overrideScanlineOrder; -#endif - -#if defined(WIN32) || defined(WIN64) - int m_prefMonX, m_prefMonY, m_prefMonWidth, m_prefMonHeight; -#endif - - int m_nStencilMaskRef; - - byte m_bDeviceSupportsInstancing; - - uint32 m_bDeviceSupports_NVDBT : 1; - - uint32 m_bDeviceSupportsFP16Separate : 1; - uint32 m_bDeviceSupportsFP16Filter : 1; - uint32 m_bDeviceSupportsR32FRendertarget : 1; - uint32 m_bDeviceSupportsVertexTexture : 1; - uint32 m_bDeviceSupportsTessellation : 1; - uint32 m_bDeviceSupportsGeometryShaders : 1; - - uint32 m_bEditor : 1; // Render instance created from editor - uint32 m_bShaderCacheGen : 1; // Render instance create from shader cache gen mode - uint32 m_bUseHWSkinning : 1; - uint32 m_bShadersPresort : 1; - uint32 m_bEndLevelLoading : 1; - uint32 m_bLevelUnloading : 1; - uint32 m_bStartLevelLoading : 1; - uint32 m_bInLevel : 1; - uint32 m_bUseWaterTessHW : 1; - uint32 m_bUseSilhouettePOM : 1; - uint32 m_bUseSpecularAntialiasing : 1; - uint32 m_UseGlobalMipBias : 1; - uint32 m_bIsWindowActive : 1; - uint32 m_bInShutdown : 1; - uint32 m_bDeferredDecals : 1; - uint32 m_bShadowsEnabled : 1; - uint32 m_bCloudShadowsEnabled : 1; -#if defined(VOLUMETRIC_FOG_SHADOWS) - uint32 m_bVolFogShadowsEnabled : 1; - uint32 m_bVolFogCloudShadowsEnabled : 1; -#endif - - uint8 m_nDisableTemporalEffects; - bool m_bUseGPUFriendlyBatching[2]; - uint32 m_nGPULimited; // How many frames we are GPU limited - int8 m_nCurMinAniso; - int8 m_nCurMaxAniso; - - uint32 m_nShadowPoolHeight; - uint32 m_nShadowPoolWidth; - - ICVar* m_CVWidth; - ICVar* m_CVHeight; - ICVar* m_CVFullScreen; - ICVar* m_CVColorBits; - ICVar* m_CVDisplayInfo; - - ColorF m_CurFontColor; - - SFogState m_FSStack[8]; - int m_nCurFSStackLevel; - - AZStd::string m_apiVersion; - AZStd::string m_adapterDescription; - DWORD m_Features; - int m_MaxTextureSize; - size_t m_MaxTextureMemory; - int m_nShadowTexSize; - - float m_fLastGamma; - float m_fLastBrightness; - float m_fLastContrast; - float m_fDeltaGamma; - uint32 m_nLastNoHWGamma; - - float m_fogCullDistance; - - static Vec2 s_overscanBorders; - static float s_previousTexelsPerMeter; - - static int CV_r_UsePersistentRTForModelHUD; - - enum - { - nMeshPoolMaxTimeoutCounter = 150 /*150 ms*/ - }; - int m_nMeshPoolTimeoutCounter; - - // Cached verts/inds used for sprites - SVF_P3F_C4B_T2F* m_pSpriteVerts; - uint16* m_pSpriteInds; - - // Rendering Drillers - Render::Debug::VRAMDriller* m_vramDriller = nullptr; - -protected: - - typedef std::list TListRenderDebugListeners; - TListRenderDebugListeners m_listRenderDebugListeners; - - SShowRenderTargetInfo m_showRenderTargetInfo; - - static void Cmd_ShowRenderTarget(IConsoleCmdArgs* pArgs); - -public: - - - // ---- - virtual ITexture* GetWhiteTexture() override;// { return CTexture::s_ptexWhite; } - virtual ITexture* GetTextureForName(const char* name, uint32 nFlags, ETEX_Format eFormat) override;// { return CTexture::ForName(name, nFlags, eFormat); } - - virtual Matrix44A& GetViewProjectionMatrix() override { return m_ViewProjMatrix; } - virtual void SetTranspOrigCameraProjMatrix(Matrix44A& matrix) { m_TranspOrigCameraProjMatrix = matrix; } - - - // - - CRenderer(); - virtual ~CRenderer(); - - virtual void InitRenderer(); - - virtual void PostInit(); - - virtual void PostLevelLoading(); - - void PreShutDown(); - void PostShutDown(); - - // Multithreading support -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_4 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif - - virtual void DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const; - virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const = 0; - - virtual void RT_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround) = 0; - - virtual void RT_PresentFast() = 0; - - virtual int RT_CurThreadList(); - virtual void RT_BeginFrame() = 0; - virtual void RT_EndFrame() = 0; - virtual void RT_EndFrame([[maybe_unused]] bool isLoading) {}; - virtual void RT_ForceSwapBuffers() = 0; - virtual void RT_SwitchToNativeResolutionBackbuffer(bool resolveBackBuffer) = 0; - virtual void RT_Init() = 0; - virtual void RT_ShutDown(uint32 nFlags) = 0; - virtual bool RT_CreateDevice() = 0; - virtual void RT_Reset() = 0; - virtual void RT_RenderTextMessages(); - virtual void RT_SetCull(int nMode) = 0; - virtual void RT_SetScissor(bool bEnable, int x, int y, int width, int height) = 0; - virtual void RT_RenderScene(int nFlags, SThreadInfo& TI, RenderFunc pRenderFunc) = 0; - virtual void RT_PrepareStereo(int mode, int output) = 0; - virtual void RT_CopyToStereoTex(int channel) = 0; - virtual void RT_UpdateTrackingStates() = 0; - virtual void RT_DisplayStereo() = 0; - virtual void RT_SetCameraInfo() = 0; - virtual void RT_SetStereoCamera() = 0; - virtual void RT_CreateResource(SResourceAsync* pRes) = 0; - virtual void RT_ReleaseResource(SResourceAsync* pRes) = 0; - virtual void RT_ReleaseRenderResources() = 0; - virtual void RT_UnbindResources() = 0; - virtual void RT_UnbindTMUs() = 0; - virtual void RT_CreateRenderResources() = 0; - virtual void RT_PrecacheDefaultShaders() = 0; - virtual void RT_ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX, int nScaledY) = 0; - virtual void RT_CreateREPostProcess(CRendElementBase** re); - virtual void RT_ReleaseVBStream(void* pVB, int nStream) = 0; - virtual void RT_ReleaseCB(void* pCB) = 0; - virtual void RT_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType) = 0; - virtual void RT_DrawDynVBUI(SVF_P2F_C4B_T2F_F4B* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType) = 0; - virtual void RT_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z) = 0; - virtual void RT_Draw2dImageStretchMode(bool bStretch) = 0; - virtual void RT_Push2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z, float stereoDepth) = 0; - virtual void RT_Draw2dImageList() = 0; - virtual void RT_DrawImageWithUV(float xpos, float ypos, float z, float w, float h, int texture_id, float* s, float* t, DWORD col, bool filtered = true) = 0; - - virtual void RT_PushRenderTarget(int nTarget, CTexture* pTex, SDepthTexture* pDS, int nS) = 0; - virtual void RT_PopRenderTarget(int nTarget) = 0; - virtual void RT_SetViewport(int x, int y, int width, int height, int id = 0) = 0; - virtual void RT_ClearTarget(ITexture* pTex, const ColorF& color) = 0; - virtual void RT_RenderDebug(bool bRenderStats = true) = 0; - virtual void RT_SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false) = 0; - - virtual void RT_PostLevelLoading(); - - void RT_DisableTemporalEffects(); - - virtual bool FlushRTCommands(bool bWait, bool bImmediatelly, bool bForce); - virtual bool ForceFlushRTCommands(); - - virtual int GetOcclusionBuffer(uint16* pOutOcclBuffer, Matrix44* pmCamBuffer) = 0; - virtual void WaitForParticleBuffer(threadID nThreadId) = 0; - - virtual void RequestFlushAllPendingTextureStreamingJobs(int nFrames) { m_nFlushAllPendingTextureStreamingJobs = nFrames; } - virtual void SetTexturesStreamingGlobalMipFactor(float fFactor) { m_fTexturesStreamingGlobalMipFactor = fFactor; } - - virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, bool bSilentMode = false) = 0; - - virtual void EF_ClearTargetsImmediately(uint32 nFlags) = 0; - virtual void EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil) = 0; - virtual void EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors) = 0; - virtual void EF_ClearTargetsImmediately(uint32 nFlags, float fDepth, uint8 nStencil) = 0; - - virtual void EF_ClearTargetsLater(uint32 nFlags) = 0; - virtual void EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil) = 0; - virtual void EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors) = 0; - virtual void EF_ClearTargetsLater(uint32 nFlags, float fDepth, uint8 nStencil) = 0; - - virtual void EF_SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa) = 0; - virtual void EF_SetSrgbWrite(bool sRGBWrite) = 0; - - virtual Matrix44A GetIdentityMatrix() { return m_IdentityMatrix; } - - - //=============================================================================== - - virtual void AddRenderDebugListener(IRenderDebugListener* pRenderDebugListener); - virtual void RemoveRenderDebugListener(IRenderDebugListener* pRenderDebugListener); - - virtual ERenderType GetRenderType() const; - - virtual WIN_HWND Init(int x, int y, int width, int height, unsigned int cbpp, int zbpp, int sbits, bool fullscreen, bool isEditor, WIN_HINSTANCE hinst, WIN_HWND Glhwnd = 0, bool bReInit = false, const SCustomRenderInitArgs* pCustomArgs = 0, bool bShaderCacheGen = false) = 0; - - virtual WIN_HWND GetCurrentContextHWND() { return GetHWND(); }; - virtual bool IsCurrentContextMainVP() { return true; } - - virtual int GetFeatures() {return m_Features; } - virtual const void SetApiVersion(const AZStd::string& apiVersion) { m_apiVersion = apiVersion; } - virtual const void SetAdapterDescription(const AZStd::string& adapterDescription) { m_adapterDescription = adapterDescription; } - virtual const AZStd::string& GetApiVersion() const { return m_apiVersion; } - virtual const AZStd::string& GetAdapterDescription() const { return m_adapterDescription; } - - unsigned long GetNvidiaDriverVersion() const { return m_nvidiaDriverVersion; } - void SetNvidiaDriverVersion(unsigned long version) { m_nvidiaDriverVersion = version; } - - virtual int GetNumGeomInstances() const - { -#if !defined(RELEASE) - return m_RP.m_PS[m_RP.m_nProcessThreadID].m_nInsts; -#else - return 0; -#endif - }; - - virtual int GetNumGeomInstanceDrawCalls() const - { -#if !defined(RELEASE) - return m_RP.m_PS[m_RP.m_nProcessThreadID].m_nInstCalls; -#else - return 0; -#endif - }; - - virtual int GetCurrentNumberOfDrawCalls() const - { - int nDIPs = 0; -#if defined(ENABLE_PROFILING_CODE) - int nThr = m_pRT->GetThreadList(); - for (int i = 0; i < EFSLIST_NUM; i++) - { - nDIPs += m_RP.m_PS[nThr].m_nDIPs[i]; - } -#endif - return nDIPs; - } - - virtual void GetCurrentNumberOfDrawCalls([[maybe_unused]] int& nGeneral, [[maybe_unused]] int& nShadowGen) const - { -#if defined(ENABLE_PROFILING_CODE) - int nDIPs = 0; - int nThr = m_pRT->GetThreadList(); - for (int i = 0; i < EFSLIST_NUM; i++) - { - if (i == EFSLIST_SHADOW_GEN) - { - continue; - } - nDIPs += m_RP.m_PS[nThr].m_nDIPs[i]; - } - nGeneral = nDIPs; - nShadowGen = m_RP.m_PS[nThr].m_nDIPs[EFSLIST_SHADOW_GEN]; -#endif - } - - virtual int GetCurrentNumberOfDrawCalls([[maybe_unused]] uint32 EFSListMask) const - { - int nDIPs = 0; -#if defined(ENABLE_PROFILING_CODE) - int nThr = m_pRT->GetThreadList(); - for (uint32 i = 0; i < EFSLIST_NUM; i++) - { - if ((1 << i) & EFSListMask) - { - nDIPs += m_RP.m_PS[nThr].m_nDIPs[i]; - } - } -#endif - return nDIPs; - } - - virtual float GetCurrentDrawCallRTTimes(uint32 EFSListMask) const - { - float fDIPTimes = 0.0f; - int nThr = m_pRT->GetThreadList(); - for (uint32 i = 0; i < EFSLIST_NUM; i++) - { - if ((1 << i) & EFSListMask) - { - fDIPTimes += m_RP.m_PS[nThr].m_fTimeDIPs[i]; - } - } - return fDIPTimes; - } - - virtual void SetDebugRenderNode(IRenderNode* pRenderNode) - { - m_pDebugRenderNode = pRenderNode; - } - - virtual bool IsDebugRenderNode(IRenderNode* pRenderNode) const - { - return (m_pDebugRenderNode && m_pDebugRenderNode == pRenderNode); - } - - //! Fills array of all supported video formats (except low resolution formats) - //! Returns number of formats, also when called with NULL - virtual int EnumDisplayFormats(SDispFormat* formats) = 0; - - //! Return all supported by video card video AA formats - virtual int EnumAAFormats(SAAFormat* formats) = 0; - - //! Changes resolution of the window/device (doen't require to reload the level - virtual bool ChangeResolution(int nNewWidth, int nNewHeight, int nNewColDepth, int nNewRefreshHZ, bool bFullScreen, bool bForceReset) = 0; - virtual bool CheckDeviceLost() { return false; }; - - virtual EScreenAspectRatio GetScreenAspect(int nWidth, int nHeight); - - virtual Vec2 SetViewportDownscale(float xscale, float yscale); - - virtual void Release(); - virtual void FreeResources(int nFlags); - virtual void InitSystemResources(int nFlags); - virtual void InitTexturesSemantics(); - - bool HasLoadedDefaultResources() override { return m_bSystemResourcesInit == 1; } - - virtual void BeginFrame() = 0; - virtual void RenderDebug(bool bRenderStats = true) = 0; - virtual void EndFrame() = 0; - virtual void LimitFramerate(const int maxFPS, const bool bUseSleep) = 0; - - virtual void ForceSwapBuffers(); - - virtual void TryFlush() = 0; - - virtual void Reset (void) = 0; - - virtual void SetCamera(const CCamera& cam) = 0; - virtual void SetViewport(int x, int y, int width, int height, int id = 0) = 0; - virtual void SetScissor(int x = 0, int y = 0, int width = 0, int height = 0) = 0; - virtual void GetViewport(int* x, int* y, int* width, int* height) const = 0; - - virtual void SetState(int State, int AlphaRef = -1) - { - m_pRT->RC_SetState(State, AlphaRef); - } - - virtual void SetStencilState(int st, uint32 nStencRef, uint32 nStencMask, uint32 nStencWriteMask, bool bForceFullReadMask) - { - m_pRT->RC_SetStencilState(st, nStencRef, nStencMask, nStencWriteMask, bForceFullReadMask); - } - - virtual void PushWireframeMode(int mode) - { - m_pRT->RC_PushWireframeMode(mode); - } - virtual void PopWireframeMode() - { - m_pRT->RC_PopWireframeMode(); - } - - virtual void FX_PushWireframeMode(int mode) = 0; - virtual void FX_PopWireframeMode() = 0; - - virtual void SetCullMode (int mode = R_CULL_BACK) = 0; - virtual void EnableVSync(bool enable) = 0; - - virtual void DrawPrimitivesInternal(CVertexBuffer* src, int vert_num, const eRenderPrimitiveType prim_type) = 0; - - virtual bool ChangeDisplay(unsigned int width, unsigned int height, unsigned int cbpp) = 0; - virtual void ChangeViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height, bool bMainViewport = false, float scaleWidth = 1.0f, float scaleHeight = 1.0f) = 0; - - virtual bool SaveTga(unsigned char* sourcedata, int sourceformat, int w, int h, const char* filename, bool flip) const; - - //download an image to video memory. 0 in case of failure - virtual unsigned int DownLoadToVideoMemory(const byte* data, int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false) = 0; - virtual void UpdateTextureInVideoMemory(uint32 tnum, const byte* newdata, int posx, int posy, int w, int h, ETEX_Format eTFSrc = eTF_R8G8B8A8, int posz = 0, int sizez = 1) = 0; - virtual unsigned int DownLoadToVideoMemory3D(const byte* data, int w, int h, int d, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false) = 0; - virtual unsigned int DownLoadToVideoMemoryCube(const byte* data, int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false) = 0; - - virtual bool DXTCompress(const byte* raw_data, int nWidth, int nHeight, ETEX_Format eTF, bool bUseHW, bool bGenMips, int nSrcBytesPerPix, MIPDXTcallback callback); - virtual bool DXTDecompress(const byte* srcData, size_t srcFileSize, byte* dstData, int nWidth, int nHeight, int nMips, ETEX_Format eSrcTF, bool bUseHW, int nDstBytesPerPix); - virtual bool SetGammaDelta(float fGamma) = 0; - - virtual void RemoveTexture(unsigned int TextureId) = 0; - - virtual void SetTexture(int tnum); - virtual void SetTexture(int tnum, int nUnit); - virtual void SetWhiteTexture(); - virtual int GetWhiteTextureId() const; - virtual int GetBlackTextureId() const; - - // Methods exposed to external libraries - virtual void ApplyDepthTextureState(int unit, int nFilter, bool clamp) override; - virtual ITexture* GetZTargetTexture() override; - virtual int GetTextureState(const STexState& TS) override; - virtual uint32 TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, const ETEX_Format eTF, ETEX_TileMode eTM = eTM_None) override; - virtual void ApplyForID(int nID, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit, bool useWhiteDefault) override; - virtual ITexture* Create3DTexture(const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst) override; - virtual bool IsTextureExist(const ITexture* pTex) override; - virtual const char* NameForTextureFormat(ETEX_Format eTF) override; - virtual const char* NameForTextureType(ETEX_Type eTT) override; - virtual bool IsVideoThreadModeEnabled() override; - virtual IDynTexture* CreateDynTexture2(uint32 nWidth, uint32 nHeight, uint32 nTexFlags, const char* szSource, ETexPool eTexPool) override; - virtual uint32 GetCurrentTextureAtlasSize() override; - - virtual void PrintToScreen(float x, float y, float size, const char* buf); - virtual void TextToScreen(float x, float y, const char* format, ...); - virtual void TextToScreenColor(int x, int y, float r, float g, float b, float a, const char* format, ...); - - int GetRecursionLevel() override; - - int GetIntegerConfigurationValue(const char* varName, int defaultValue) override; - float GetFloatConfigurationValue(const char* varName, float defaultValue) override; - bool GetBooleanConfigurationValue(const char* varName, bool defaultValue) override; - - void WriteXY(int x, int y, float xscale, float yscale, float r, float g, float b, float a, const char* message, ...) PRINTF_PARAMS(10, 11); - void Draw2dText(float posX, float posY, const char* pStr, const SDrawTextInfo& ti); - void Draw2dTextWithDepth(float posX, float posY, float posZ, const char* pStr, const SDrawTextInfo& ti); - - virtual void DrawTextQueued(Vec3 pos, SDrawTextInfo& ti, const char* text); - virtual void DrawTextQueued(Vec3 pos, SDrawTextInfo& ti, const char* format, va_list args); - - virtual void Draw2dImage(float xpos, float ypos, float w, float h, int texture_id, float s0 = 0, float t0 = 0, float s1 = 1, float t1 = 1, float angle = 0, float r = 1, float g = 1, float b = 1, float a = 1, float z = 1) = 0; - virtual void Push2dImage(float xpos, float ypos, float w, float h, int texture_id, float s0 = 0, float t0 = 0, float s1 = 1, float t1 = 1, float angle = 0, - float r = 1, float g = 1, float b = 1, float a = 1, float z = 1, float stereoDepth = 0) = 0; - virtual void Draw2dImageList() = 0; - - virtual void ResetToDefault() = 0; - - virtual void PrintResourcesLeaks() = 0; - - ILINE const bool IsEditorMode() const - { -#if defined(CONSOLE) - return false; -#else - return (m_bEditor != 0); -#endif - } - - ILINE const bool IsShaderCacheGenMode() const - { -#if defined(CONSOLE) - return false; -#else - return (m_bShaderCacheGen != 0); -#endif - } - - inline float ScaleCoordXInternal(float value) const - { - value *= float(m_CurViewport.nWidth) / 800.0f; - return (value); - } - virtual float ScaleCoordX(float value) const - { - return ScaleCoordXInternal(value); - } - inline float ScaleCoordYInternal(float value) const - { - value *= float(m_CurViewport.nHeight) / 600.0f; - return (value); - } - virtual float ScaleCoordY(float value) const - { - return ScaleCoordYInternal(value); - } - inline void ScaleCoordInternal(float& x, float& y) const - { - int viewPortX, viewPortY, viewPortW, viewPortH; - GetViewport(&viewPortX, &viewPortY, &viewPortW, &viewPortH); - x *= viewPortW / 800.0f; - y *= viewPortH / 600.0f; - } - virtual void ScaleCoord(float& x, float& y) const - { - ScaleCoordInternal(x, y); - } - - void SetWidth(int nW) { m_width = nW; } - void SetHeight(int nH) { m_height = nH; } - - virtual int GetWidth() const { return (m_width); } - virtual int GetHeight() const { return (m_height); } - - virtual int GetOverlayWidth() const { return m_nativeWidth; } - virtual int GetOverlayHeight() const { return m_nativeHeight; } - - void SetPixelAspectRatio(float fPAR) {m_pixelAspectRatio = fPAR; } - virtual float GetPixelAspectRatio() const { return (m_pixelAspectRatio); } - - int GetBackbufferWidth() { return m_backbufferWidth; } - int GetBackbufferHeight() { return m_backbufferHeight; } - - void GetClampedWindowSize(int& widthPixels, int& heightPixels); - - inline int GetMaxSquareRasterDimension() const override - { - // m_MaxTextureSize is actually maxTextureDimension. Since MaxResolution refers to a 2D raster, the upper limit on a square raster is (m_MaxTextureSize/2) - return (CV_r_CustomResMaxSize == s_CustomResMaxSize_USE_MAX_RESOURCES) ? (m_MaxTextureSize / 2) : clamp_tpl(CV_r_CustomResMaxSize, 32, (m_MaxTextureSize / 2)); - } - - virtual bool IsStereoEnabled() const { return false; } - - virtual float GetNearestRangeMax() const { return (CV_r_DrawNearZRange); } - - // Get mipmap distance factor (depends on screen width, screen height and aspect ratio) - - _inline float GetMipDistFactor() { return TANGENT30_2 * TANGENT30_2 / (GetHeight() * GetHeight()); } - - virtual int GetWireframeMode() { return(m_wireframe_mode); } - - - _inline const CCamera& GetCamera(void) { return(m_RP.m_TI[m_pRT->GetThreadList()].m_cam); } - - virtual const CameraViewParameters& GetViewParameters() override - { - return(m_RP.m_TI[m_pRT->GetThreadList()].m_cam.m_viewParameters); - } - - virtual void SetViewParameters(const CameraViewParameters& viewParameters) override - { - m_RP.m_TI[m_pRT->GetThreadList()].m_cam.m_viewParameters = viewParameters; - } - - virtual CRenderView* GetRenderViewForThread(int nThreadID) final; - Matrix44A GetCameraMatrix(); - - void GetPolyCount([[maybe_unused]] int& nPolygons, [[maybe_unused]] int& nShadowPolys) const - { -#if defined(ENABLE_PROFILING_CODE) - nPolygons = GetPolyCount(); - nShadowPolys = m_RP.m_PS[m_RP.m_nFillThreadID].m_nPolygons[EFSLIST_SHADOW_GEN]; - nShadowPolys += m_RP.m_PS[m_RP.m_nFillThreadID].m_nPolygons[EFSLIST_SHADOW_PASS]; - nPolygons -= nShadowPolys; -#endif - } - - int GetPolyCount() const - { -#if defined(ENABLE_PROFILING_CODE) - int nPolys = 0; - for (int i = 0; i < EFSLIST_NUM; i++) - { - nPolys += m_RP.m_PS[m_pRT->IsMainThread()?m_RP.m_nFillThreadID:m_RP.m_nProcessThreadID].m_nPolygons[i]; - } - return nPolys; -#else - return 0; -#endif - } - - virtual void SetMaterialColor(float r, float g, float b, float a) = 0; - - virtual bool WriteDDS(const byte* dat, int wdt, int hgt, int Size, const char* name, ETEX_Format eF, int NumMips); - virtual bool WriteTGA(const byte* dat, int wdt, int hgt, const char* name, int src_bits_per_pixel, int dest_bits_per_pixel); - virtual bool WriteJPG(const byte* dat, int wdt, int hgt, char* name, int src_bits_per_pixel, int nQuality = 100); - - virtual void GetMemoryUsage(ICrySizer* Sizer); - - virtual void GetBandwidthStats(float* fBandwidthRequested); - - virtual void SetTextureStreamListener(ITextureStreamListener* pListener); - - virtual void GetLogVBuffers() = 0; - - virtual int GetFrameID(bool bIncludeRecursiveCalls = true) - { - int nThreadID = m_pRT ? m_pRT->GetThreadList() : 0; - if (bIncludeRecursiveCalls) - { - return m_RP.m_TI[nThreadID].m_nFrameID; - } - return m_RP.m_TI[nThreadID].m_nFrameUpdateID; - } - - // GPU being updated - virtual int32 RT_GetCurrGpuID() const override - { - return gRenDev->m_nFrameSwapID % gRenDev->GetActiveGPUCount(); - } - - // Project/UnProject. Returns true if successful. - virtual bool ProjectToScreen(float ptx, float pty, float ptz, - float* sx, float* sy, float* sz) = 0; - virtual int UnProject(float sx, float sy, float sz, - float* px, float* py, float* pz, - const float modelMatrix[16], - const float projMatrix[16], - const int viewport[4]) = 0; - virtual int UnProjectFromScreen(float sx, float sy, float sz, - float* px, float* py, float* pz) = 0; - - virtual void EF_RenderTextMessages(); - void RenderTextMessages(CTextMessages& messages); - - // Shadow Mapping - virtual bool PrepareDepthMap(ShadowMapFrustum* SMSource, int nFrustumLOD = 0, bool bClearPool = false) = 0; - virtual void DrawAllShadowsOnTheScreen() = 0; - virtual void OnEntityDeleted(IRenderNode* pRenderNode) = 0; - - //for editor - virtual void GetModelViewMatrix(float* mat) = 0; - virtual void GetProjectionMatrix(float* mat) = 0; - virtual void SetMatrices(float* pProjMat, float* pViewMat) = 0; - - virtual void ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX = -1, int nScaledY = -1) = 0; - - //misc - virtual bool ScreenShot(const char* filename = NULL, int width = 0) = 0; - - virtual int GetColorBpp() { return m_cbpp; } - virtual int GetDepthBpp() { return m_zbpp; } - virtual int GetStencilBpp() { return m_sbpp; } - - virtual int ScreenToTexture(int nTexID) = 0; - - virtual void LockParticleVideoMemory([[maybe_unused]] uint32 nId) {} - virtual void UnLockParticleVideoMemory([[maybe_unused]] uint32 nId){} - - virtual void ActivateLayer([[maybe_unused]] const char* pLayerName, [[maybe_unused]] bool activate) {} - - virtual void FlushPendingTextureTasks() - { - if (m_pRT) - { - m_pRT->RC_FlushTextureStreaming(true); - FlushRTCommands(true, true, true); - } - } - - void SetShadowJittering (float shadowJittering) - { - m_shadowJittering = shadowJittering; - } - float GetShadowJittering() const { return m_shadowJittering; } - - // Shaders/Shaders support - // RE - RenderElement - bool m_bTimeProfileUpdated; - int m_PrevProfiler; - int m_nCurSlotProfiler; - - AZ::IO::HandleType m_logFileHandle; - AZ::IO::HandleType m_logFileStrHandle; - AZ::IO::HandleType m_logFileShHandle; - inline void Logv(int RecLevel, const char* format, ...) - { - va_list argptr; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - for (int i = 0; i < RecLevel; i++) - { - AZ::IO::Print(m_logFileHandle, " "); - } - va_start (argptr, format); - AZ::IO::PrintV(m_logFileHandle, format, argptr); - va_end (argptr); - } - } - inline void LogStrv(int RecLevel, const char* format, ...) - { - va_list argptr; - - if (m_logFileStrHandle != AZ::IO::InvalidHandle) - { - for (int i = 0; i < RecLevel; i++) - { - AZ::IO::Print(m_logFileStrHandle, " "); - } - va_start (argptr, format); - AZ::IO::PrintV(m_logFileStrHandle, format, argptr); - va_end (argptr); - } - } - inline void LogShv(int RecLevel, const char* format, ...) - { - va_list argptr; - - if (m_logFileShHandle != AZ::IO::InvalidHandle) - { - for (int i = 0; i < RecLevel; i++) - { - AZ::IO::Print(m_logFileShHandle, " "); - } - va_start (argptr, format); - AZ::IO::PrintV(m_logFileShHandle, format, argptr); - va_end (argptr); - gEnv->pFileIO->Flush(m_logFileShHandle); - } - } - _inline void Log(const char* str) - { - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(m_logFileHandle, str); - } - } - - void EF_AddClientPolys(const SRenderingPassInfo& passInfo); - void EF_RemovePolysFromScene(); - - bool FX_TryToMerge(CRenderObject* pNewObject, CRenderObject* pOldObject, IRenderElement* pRE, bool bResIdentical); - virtual void* FX_AllocateCharInstCB(SSkinningData*, uint32) { return NULL; } - virtual void FX_ClearCharInstCB(uint32) {} - - void EF_TransformDLights(); - void EF_IdentityDLights(); - - _inline void* EF_GetPointer(ESrcPointer ePT, int* Stride, EParamType Type, ESrcPointer Dst, int Flags) - { - void* p; - - if (m_RP.m_pRE) - { - p = m_RP.m_pRE->mfGetPointer(ePT, Stride, Type, Dst, Flags); - } - else - { - p = SRendItem::mfGetPointerCommon(ePT, Stride, Type, Dst, Flags); - } - - return p; - } - inline void FX_StartMerging() - { - if (m_RP.m_FrameMerge != m_RP.m_Frame) - { - m_RP.m_FrameMerge = m_RP.m_Frame; - int Size = m_RP.m_CurVFormat.GetStride(); - m_RP.m_StreamStride = Size; - m_RP.m_CurVFormat.TryCalculateOffset(m_RP.m_StreamOffsetColor, AZ::Vertex::AttributeUsage::Color); - m_RP.m_CurVFormat.TryCalculateOffset(m_RP.m_StreamOffsetTC, AZ::Vertex::AttributeUsage::TexCoord); - m_RP.m_NextStreamPtr = m_RP.m_StreamPtr; - m_RP.m_NextStreamPtrTang = m_RP.m_StreamPtrTang; - } - } - - _inline void EF_PushFog() - { - assert(m_pRT->IsRenderThread()); - int nLevel = m_nCurFSStackLevel; - if (nLevel >= 8) - { - return; - } - memcpy(&m_FSStack[nLevel], &m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS, sizeof(SFogState)); - m_nCurFSStackLevel++; - } - _inline void EF_PopFog() - { - assert(m_pRT->IsRenderThread()); - int nLevel = m_nCurFSStackLevel; - if (nLevel <= 0) - { - return; - } - nLevel--; - bool bFog = m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_bEnable; - if (m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS != m_FSStack[nLevel]) - { - memcpy(&m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS, &m_FSStack[nLevel], sizeof(SFogState)); - SetFogColor(m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_FogColor); - } - else - { - m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_bEnable = m_FSStack[nLevel].m_bEnable; - } - bool bNewFog = m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_bEnable; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_bEnable = bFog; - EnableFog(bNewFog); - m_nCurFSStackLevel--; - } - - //================================================================================ - SViewport m_MainRTViewport; - SViewport m_MainViewport; - - SViewport m_CurViewport; - SViewport m_NewViewport; - bool m_bViewportDirty; - bool m_bViewportDisabled; - - int m_nCurVPStackLevel; - SViewport m_VPStack[8]; - _inline void FX_PushVP() - { - int nLevel = m_nCurVPStackLevel; - if (nLevel >= 8) - { - return; - } - memcpy(&m_VPStack[nLevel], &m_NewViewport, sizeof(SViewport)); - m_nCurVPStackLevel++; - } - _inline void FX_PopVP() - { - int nLevel = m_nCurVPStackLevel; - if (nLevel <= 0) - { - return; - } - nLevel--; - if (m_NewViewport != m_VPStack[nLevel]) - { - memcpy(&m_NewViewport, &m_VPStack[nLevel], sizeof(SViewport)); - m_bViewportDirty = true; - } - m_nCurVPStackLevel--; - } - - - void EF_AddRTStat(CTexture* pTex, int nFlags = 0, int nW = -1, int nH = -1); - void EF_PrintRTStats(const char* szName); - - int FX_ApplyShadowQuality(); - - static eAntialiasingType FX_GetAntialiasingType() - { - return (eAntialiasingType) ((uint32)1 << min(CV_r_AntialiasingMode, eAT_AAMODES_COUNT - 1)); - } - - inline float GetTemporalJitterMipBias() const - { - return m_TemporalJitterMipBias; - } - - void FX_ApplyShaderQuality(const EShaderType eST); - - virtual EShaderQuality EF_GetShaderQuality(EShaderType eST); - virtual ERenderQuality EF_GetRenderQuality() const; - - void RefreshSystemShaders(); - uint32 EF_BatchFlags(SShaderItem& SH, CRenderObject* pObj, IRenderElement* re, const SRenderingPassInfo& passInfo); - - virtual void FX_PipelineShutdown(bool bFastShutdown = false) = 0; - - virtual IOpticsElementBase* CreateOptics(EFlareType type) const; - - virtual bool EF_PrecacheResource(IShader* pSH, float fMipFactor, float fTimeToReady, int Flags); - virtual bool EF_PrecacheResource(SShaderItem* pSI, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter) = 0; - virtual bool EF_PrecacheResource(ITexture* pTP, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter) = 0; - virtual bool EF_PrecacheResource(IRenderMesh* pPB, _smart_ptr pMaterial, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId); - virtual bool EF_PrecacheResource(CDLight* pLS, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId); - - virtual CRenderObject* EF_AddPolygonToScene(SShaderItem& si, int numPts, const SVF_P3F_C4B_T2F* verts, const SPipTangents* tangs, CRenderObject* obj, const SRenderingPassInfo& passInfo, uint16* inds, int ninds, int nAW, const SRendItemSorter& rendItemSorter); - virtual CRenderObject* EF_AddPolygonToScene(SShaderItem& si, CRenderObject* obj, const SRenderingPassInfo& passInfo, int numPts, int ninds, SVF_P3F_C4B_T2F*& verts, SPipTangents*& tangs, uint16*& inds, int nAW, const SRendItemSorter& rendItemSorter); - - virtual void FX_CheckOverflow(int nVerts, int nInds, IRenderElement* re, int* nNewVerts = NULL, int* nNewInds = NULL) override; - virtual void FX_Start(CShader* ef, int nTech, CShaderResources* Res, IRenderElement* re) override; - - virtual int GenerateTextureId() override { return m_TexGenID++; } - - //========================================================== - // external interface for shaders - //========================================================== - - AZ::LegacyJobExecutor m_ComputeVerticesJobExecutors[RT_COMMAND_BUF_COUNT]; - - CFillRateManager m_FillRateManager; - - void FinalizeRendItems(int nThreadID); - void FinalizeRendItems_ReorderShadowRendItems(int nThreadID); - void FinalizeRendItems_FindShadowFrustums(int nThreadID); - void FinalizeRendItems_ReorderRendItems(int nThreadID); - void FinalizeRendItems_ReorderRendItemList(int nAW, int nList, int nThreadID); - void FinalizeRendItems_SortRenderLists(int nThreadID); - - void FinalizeShadowRendItems(int nThreadID); - void RegisterFinalizeShadowJobs(int nThreadID); - - // Summary: - virtual void BeginSpawningGeneratingRendItemJobs(int nThreadID); - virtual void BeginSpawningShadowGeneratingRendItemJobs(int nThreadID); - virtual void EndSpawningGeneratingRendItemJobs(); - - AZ::LegacyJobExecutor* GetGenerateRendItemJobExecutor() override; - AZ::LegacyJobExecutor* GetGenerateShadowRendItemJobExecutor() override; - AZ::LegacyJobExecutor* GetGenerateRendItemJobExecutorPreProcess() override; - AZ::LegacyJobExecutor* GetFinalizeRendItemJobExecutor(int nThreadID) override; - AZ::LegacyJobExecutor* GetFinalizeShadowRendItemJobExecutor(int nThreadID) override; - - - // Shaders management - virtual void EF_SetShaderMissCallback(ShaderCacheMissCallback callback); - virtual const char* EF_GetShaderMissLogPath(); - virtual string* EF_GetShaderNames(int& nNumShaders); - virtual IShader* EF_LoadShader (const char* name, int flags = 0, uint64 nMaskGen = 0); - virtual SShaderItem EF_LoadShaderItem (const char* name, bool bShare, int flags = 0, SInputShaderResources* Res = NULL, uint64 nMaskGen = 0); - virtual uint64 EF_GetRemapedShaderMaskGen(const char* name, uint64 nMaskGen = 0, bool bFixup = 0); - - virtual uint64 EF_GetShaderGlobalMaskGenFromString(const char* szShaderName, const char* szShaderGen, uint64 nMaskGen = 0); - virtual AZStd::string EF_GetStringFromShaderGlobalMaskGen(const char* szShaderName, uint64 nMaskGen = 0); - - // reload file - virtual bool EF_ReloadFile(const char* szFileName); - virtual bool EF_ReloadFile_Request(const char* szFileName); - virtual void EF_ReloadShaderFiles (int nCategory); - virtual void EF_ReloadTextures(); - virtual int EF_LoadLightmap(const char* nameTex); - virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray& vecData); - virtual ITexture* EF_GetTextureByID(int Id); - virtual ITexture* EF_GetTextureByName(const char* name, uint32 flags = 0); - virtual ITexture* EF_LoadTexture(const char* nameTex, uint32 flags = 0); - virtual ITexture* EF_LoadCubemapTexture(const char* nameTex, uint32 flags = 0); - virtual ITexture* EF_LoadDefaultTexture(const char* nameTex); - - virtual const SShaderProfile& GetShaderProfile(EShaderType eST) const; - virtual void EF_SetShaderQuality(EShaderType eST, EShaderQuality eSQ); - - virtual _smart_ptr EF_LoadImage(const char* szFileName, uint32 nFlags); - - // Create new RE of type (edt) - virtual IRenderElement* EF_CreateRE (EDataType edt); - - // Begin using shaders - virtual void EF_StartEf (const SRenderingPassInfo& passInfo); - - virtual SRenderObjData* EF_GetObjData(CRenderObject* pObj, bool bCreate, int nThreadID); - SRenderObjData* FX_GetObjData(CRenderObject* pObj, int nThreadID); - - // Get Object for RE transformation - virtual CRenderObject* EF_GetObject_Temp (int nThreadID); - CRenderObject* EF_DuplicateRO(CRenderObject* pObj, const SRenderingPassInfo& passInfo); - - // Add shader to the list (virtual) - virtual void EF_AddEf (IRenderElement* pRE, SShaderItem& pSH, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter); - - // Add shader to the list - void EF_AddEf_NotVirtual (IRenderElement* pRE, SShaderItem& pSH, CRenderObject* pObj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter); - - // Draw all shaded REs in the list - virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo) = 0; - - virtual void EF_InvokeShadowMapRenderJobs(int nFlags) = 0; - // 2d interface for shaders - virtual void EF_EndEf2D(bool bSort) = 0; - - // Dynamic lights - virtual bool EF_IsFakeDLight (const CDLight* Source); - virtual void EF_ADDDlight(CDLight* Source, const SRenderingPassInfo& passInfo); - virtual bool EF_AddDeferredDecal(const SDeferredDecal& rDecal); - virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight); - virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - virtual TArray* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight); - SRenderLight* EF_GetDeferredLightByID(const uint16 nLightID, const eDeferredLightType eLightType = eDLT_DeferredLight); - virtual void EF_ClearDeferredLightsList(); - virtual void EF_ReleaseDeferredData(); - virtual void EF_ReleaseInputShaderResource(SInputShaderResources* pRes); - virtual void EF_ClearLightsList(); - virtual bool EF_UpdateDLight(SRenderLight* pDL); - void EF_CheckLightMaterial(CDLight* pLight, uint16 nRenderLightID, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - - // Water sim hits - virtual void EF_AddWaterSimHit(const Vec3& vPos, float scale, float strength); - virtual void EF_DrawWaterSimHits(); - - virtual void EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1); - virtual void FX_SetState(int st, int AlphaRef = -1, int RestoreState = 0) = 0; - void FX_SetStencilState(int st, uint32 nStencRef, uint32 nStencMask, uint32 nStencWriteMask, bool bForceFullReadMask = false); - - ////////////////////////////////////////////////////////////////////////// - // Deferred ambient passes - - virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume); - virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pVolume, const SClipVolumeBlendInfo& blendInfo); - - virtual void EF_ClearDeferredClipVolumesList(); - - ////////////////////////////////////////////////////////////////////////// - // Post processing effects interfaces - - virtual void EF_SetPostEffectParam(const char* pParam, float fValue, bool bForceValue = false); - virtual void EF_SetPostEffectParamVec4(const char* pParam, const Vec4& pValue, bool bForceValue = false); - virtual void EF_SetPostEffectParamString(const char* pParam, const char* pszArg); - - virtual void EF_GetPostEffectParam(const char* pParam, float& fValue); - virtual void EF_GetPostEffectParamVec4(const char* pParam, Vec4& pValue); - virtual void EF_GetPostEffectParamString(const char* pParam, const char*& pszArg); - - virtual int32 EF_GetPostEffectID(const char* pPostEffectName); - - virtual void EF_ResetPostEffects(bool bOnSpecChange = false); - - virtual void SyncPostEffects(); - - virtual void EF_DisableTemporalEffects(); - - virtual void ForceGC(); - - virtual void RT_ResetGlass() {} - - // create/delete RenderMesh object - virtual _smart_ptr CreateRenderMesh( - const char* szType - , const char* szSourceName - , IRenderMesh::SInitParamerers* pInitParams = NULL - , ERenderMeshType eBufType = eRMT_Static - ); - - virtual _smart_ptr CreateRenderMeshInitialized( - const void* pVertBuffer, int nVertCount, const AZ::Vertex::Format& vertexFormat, - const vtx_idx* pIndices, int nIndices, - const PublicRenderPrimitiveType nPrimetiveType, const char* szType, const char* szSourceName, ERenderMeshType eBufType = eRMT_Static, - int nMatInfoCount = 1, int nClientTextureBindID = 0, - bool (* PrepareBufferCallback)(IRenderMesh*, bool) = NULL, - void* CustomData = NULL, - bool bOnlyVideoBuffer = false, bool bPrecache = true, const SPipTangents* pTangents = NULL, bool bLockForThreadAcc = false, Vec3* pNormals = NULL); - - virtual int GetMaxActiveTexturesARB() { return 0; } - - ////////////////////////////////////////////////////////////////////// - // Replacement functions for the Font engine ( vlad: for font can be used old functions ) - virtual bool FontUpdateTexture(int nTexId, int X, int Y, int USize, int VSize, byte* pData) = 0; - virtual void FontSetTexture(int nTexId, int nFilterMode) = 0; - virtual void FontSetRenderingState(bool overrideViewProjMatrices, TransformationMatrices& backupMatrices) = 0; - virtual void FontSetBlending(int src, int dst, int baseState) = 0; - virtual void FontRestoreRenderingState(bool overrideViewProjMatrices, const TransformationMatrices& restoringMatrices) = 0; - - ////////////////////////////////////////////////////////////////////// - // Used for pausing timer related stuff (eg: for texture animations, and shader 'time' parameter) - void PauseTimer(bool bPause) { m_bPauseTimer = bPause; } - virtual IShaderPublicParams* CreateShaderPublicParams(); - - virtual void GetThreadIDs(threadID& mainThreadID, threadID& renderThreadID) const; - - enum ESPM - { - ESPM_PUSH = 0, ESPM_POP = 1 - }; - virtual void SetProfileMarker([[maybe_unused]] const char* label, [[maybe_unused]] ESPM mode) const {}; - - virtual uint16 PushFogVolumeContribution(const SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo); - void GetFogVolumeContribution(uint16 idx, SFogVolumeData& fogVolData) const; - virtual void PushFogVolume([[maybe_unused]] class CREFogVolume* pFogVolume, [[maybe_unused]] const SRenderingPassInfo& passInfo) {assert(false); } - - virtual int GetMaxTextureSize() { return m_MaxTextureSize; } - - virtual void SetCloudShadowsParams(int nTexID, const Vec3& speed, float tiling, bool invert, float brightness) - { - m_cloudShadowTexId = nTexID; - m_cloudShadowSpeed = speed; - m_cloudShadowTiling = tiling; - m_cloudShadowInvert = invert; - m_cloudShadowBrightness = brightness; - } - int GetCloudShadowTextureId() const { return m_cloudShadowTexId; } - - virtual ShadowFrustumMGPUCache* GetShadowFrustumMGPUCache() { return &m_ShadowFrustumMGPUCache; } - - virtual const StaticArray& GetCachedShadowsResolution() const { return m_CachedShadowsResolution; } - virtual void SetCachedShadowsResolution(const StaticArray& arrResolutions) { m_CachedShadowsResolution = arrResolutions; } - virtual void UpdateCachedShadowsLodCount(int nGsmLods) const override; - - bool IsHDRModeEnabled() const - { - // If there's no support for floating point render targets, we disable HDR. - return (gRenDev && gRenDev->UseHalfFloatRenderTargets()) && !CV_r_measureoverdraw && !m_wireframe_mode; - } - - bool IsShadowPassEnabled() const - { - return (CV_r_ShadowPass && CV_r_usezpass && !m_wireframe_mode) ? true : false; - } - - bool IsCustomRenderModeEnabled(uint32 nRenderModeMask); - virtual bool IsPost3DRendererEnabled() const; - - virtual const char* GetTextureFormatName(ETEX_Format eTF); - virtual int GetTextureFormatDataSize(int nWidth, int nHeight, int nDepth, int nMips, ETEX_Format eTF); - virtual void SetDefaultMaterials(_smart_ptr pDefMat, _smart_ptr pTerrainDefMat) { m_pDefaultMaterial = pDefMat; m_pTerrainDefaultMaterial = pTerrainDefMat; } - virtual byte* GetTextureSubImageData32([[maybe_unused]] byte* pData, [[maybe_unused]] int nDataSize, [[maybe_unused]] int nX, [[maybe_unused]] int nY, [[maybe_unused]] int nW, [[maybe_unused]] int nH, [[maybe_unused]] CTexture* pTex){return 0; } - - virtual void PrecacheTexture(ITexture* pTP, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter = 1); - - virtual SSkinningData* EF_CreateSkinningData(uint32 nNumBones, bool bNeedJobSyncVar, bool bUseMatrixSkinning = false); - virtual SSkinningData* EF_CreateRemappedSkinningData(uint32 nNumBones, SSkinningData* pSourceSkinningData, uint32 nCustomDataSize, uint32 pairGuid); - virtual void EF_ClearSkinningDataPool(); - virtual int EF_GetSkinningPoolID(); - - - bool EF_GetParticleListAndBatchFlags(uint32& nBatchFlags, int& nList, SShaderItem& shaderItem, CRenderObject* pRO, const SRenderingPassInfo& passInfo); - virtual void ClearShaderItem(SShaderItem* pShaderItem); - virtual void UpdateShaderItem(SShaderItem* pShaderItem, _smart_ptr pMaterial); - virtual void ForceUpdateShaderItem(SShaderItem* pShaderItem, _smart_ptr pMaterial); - virtual void RefreshShaderResourceConstants(SShaderItem* pShaderItem, IMaterial* pMaterial); - - void RT_UpdateShaderItem (SShaderItem* pShaderItem, IMaterial* material); - void RT_RefreshShaderResourceConstants(SShaderItem* shaderItem) const; - - bool UseHalfFloatRenderTargets(); - - virtual bool LoadShaderStartupCache() - { - return m_cEF.LoadShaderStartupCache(); - } - - virtual void UnloadShaderStartupCache() - { - m_cEF.UnloadShaderStartupCache(); - } - - virtual bool LoadShaderLevelCache() { return false; } - virtual void UnloadShaderLevelCache() {} - - void SyncMainWithRender(); - - virtual void RegisterSyncWithMainListener(ISyncMainWithRenderListener* pListener); - virtual void RemoveSyncWithMainListener(const ISyncMainWithRenderListener* pListener); - - void InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) final - { - m_pRT->RC_InitializeVideoRenderer(pVideoRenderer); - } - void RT_InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer); - - void CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) final - { - m_pRT->RC_CleanupVideoRenderer(pVideoRenderer); - } - void RT_CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer); - - void DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) final - { - m_pRT->RC_DrawVideoRenderer(pVideoRenderer, drawArguments); - } - virtual void RT_DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) = 0; - -protected: - int m_width, m_height, m_cbpp, m_zbpp, m_sbpp; - int m_nativeWidth, m_nativeHeight; - int m_backbufferWidth, m_backbufferHeight; - int m_numSSAASamples; - int m_wireframe_mode, m_wireframe_mode_prev; - uint32 m_nGPUs; // Use GetActiveGPUCount() to read - float m_drawNearFov; - float m_pixelAspectRatio; - float m_shadowJittering; - StaticArray m_CachedShadowsResolution; - CTextMessages m_TextMessages[RT_COMMAND_BUF_COUNT]; // [ThreadID], temporary stores 2d/3d text messages to render them at the end of the frame - - CSkinningDataPool m_SkinningDataPool[3]; // Tripple Buffered for motion blur - LegacyInternal::JobExecutorPool m_jobExecutorPool; - - uint32 m_nShadowGenId[RT_COMMAND_BUF_COUNT]; - - int m_cloudShadowTexId; - Vec3 m_cloudShadowSpeed; - float m_cloudShadowTiling; - bool m_cloudShadowInvert; - float m_cloudShadowBrightness; - -public: - // these ids can be used for tripple (or more) buffered structures - // they are incremented in RenderWorld on the mainthread - // use m_nPoolIndex from the mainthread (or jobs which are synced before Renderworld) - // and m_nPoolIndexRT from the renderthread - // right now the skinning data pool and particle are using this id - uint32 m_nPoolIndex; - uint32 m_nPoolIndexRT; - - - bool m_bVendorLibInitialized; - - _inline uint32 GetActiveGPUCount() const - { - return CV_r_multigpu > 0 ? m_nGPUs : 1; - } - - CCamera m_prevCamera; // camera from previous frame - - uint32 m_nFrameLoad; - uint32 m_nFrameReset; - uint32 m_nFrameSwapID; // without recursive calls, access through GetFrameID(false) - - ColorF m_cClearColor; - bool m_clearBackground; - int m_NumResourceSlots; - int m_NumSamplerSlots; - - //////////////////////////////////////////////////////// - // downscaling viewport information. - - // Set from CrySystem via IRenderer interface - Vec2 m_ReqViewportScale; - - // Updated in RT_EndFrame. Fixed across the whole frame. - Vec2 m_CurViewportScale; - Vec2 m_PrevViewportScale; - - // a RECT that represents the full screen size, accounting for above scaling - RECT m_FullResRect; - // same, but half resolution in each direction - RECT m_HalfResRect; - - virtual void SetCurDownscaleFactor(Vec2 sf) = 0; - - //////////////////////////////////////////////////////// - - class CPostEffectsMgr* m_pPostProcessMgr; - class CWater* m_pWaterSimMgr; - - // Used for pausing timer related stuff (eg: for texture animations, and shader 'time' parameter) - bool m_bPauseTimer; - float m_fPrevTime; - uint8 m_nUseZpass : 2; - bool m_bCollectDrawCallsInfo; - bool m_bCollectDrawCallsInfoPerNode; - - // HDR rendering stuff - int m_dwHDRCropWidth; - int m_dwHDRCropHeight; - - S3DEngineCommon m_p3DEngineCommon; - - typedef std::map< uint64, PodArray* > ShadowFrustumListsCache; - ShadowFrustumListsCache m_FrustumsCache; - - ShadowFrustumMGPUCache m_ShadowFrustumMGPUCache; - - //Debug Gun - IRenderNode* m_pDebugRenderNode; - - //===================================================================== - // Shaders interface - CShaderMan m_cEF; - _smart_ptr m_pDefaultMaterial; - _smart_ptr m_pTerrainDefaultMaterial; - - int m_TexGenID; - - IFFont* m_pDefaultFont; - - //================================================================= - // Light volumes data - - struct SLightVolume* m_pLightVols; - uint32 m_nNumVols; - - void RT_UpdateLightVolumes(int32 nFlags, int32 nRecurseLevel); - void RT_SetSkinningPoolId(uint32); - - _inline void RT_SetLightVolumeShaderFlags(uint8 nNumLights) - { - const uint64 lightVolume = g_HWSR_MaskBit[HWSR_LIGHTVOLUME0]; - m_RP.m_FlagsShader_RT &= ~lightVolume; - IF (nNumLights > 0, 1) - { - m_RP.m_FlagsShader_RT |= lightVolume; - } - } - - //================================================================= - // High res screen shot - - int m_screenShotType; - virtual void StartScreenShot(int e_ScreenShotType) { m_screenShotType = e_ScreenShotType; } - virtual void EndScreenShot([[maybe_unused]] int e_ScreenShotType) { m_screenShotType = 0; } - - //================================================================= - - virtual void SetClearColor(const Vec3& vColor) { m_cClearColor.r = vColor[0]; m_cClearColor.g = vColor[1]; m_cClearColor.b = vColor[2]; } - - virtual void SetClearBackground(bool clearBackground) { m_clearBackground = clearBackground; } - - static void ChangeGeomInstancingThreshold(ICVar* pVar = 0); - - static int m_iGeomInstancingThreshold; // internal value, auto mapped depending on GPU hardware, 0 means not set yet - - ////////////////////////////////////////////////////////////////////// - // console variables - ////////////////////////////////////////////////////////////////////// - - //------------------int cvars------------------------------- - - static ICVar* CV_r_ShowDynTexturesFilter; - static ICVar* CV_r_ShaderCompilerServer; - static int CV_r_AssetProcessorShaderCompiler; // If true, will forward requests for shader compilation to the Asset Processor instead of the server directly. - static ICVar* CV_r_ShaderEmailTags; - static ICVar* CV_r_ShaderEmailCCs; - static ICVar* CV_r_excludeshader; - static ICVar* CV_r_excludemesh; - static ICVar* CV_r_ShowTexture; - static ICVar* CV_r_TexturesStreamingDebugfilter; - - //declare cvars differing on platforms - static int CV_r_vsync; - static int CV_r_OldBackendSkip; -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - static float CV_r_overrideRefreshRate; - static int CV_r_overrideScanlineOrder; - static int CV_r_overrideDXGIOutput; - static int CV_r_overrideDXGIOutputFS; -#endif -#if defined(WIN32) || defined(WIN64) - static int CV_r_FullscreenPreemption; -#endif - - static int CV_r_DebugLightLayers; - - static int CV_r_ApplyToonShading; - static int CV_r_GraphicsPipeline; - - static int CV_r_DeferredShadingTiled; - static int CV_r_DeferredShadingTiledHairQuality; - static int CV_r_DeferredShadingTiledDebugDirect; - static int CV_r_DeferredShadingTiledDebugIndirect; - static int CV_r_DeferredShadingTiledDebugAccumulation; - static int CV_r_DeferredShadingTiledDebugAlbedo; - static int CV_r_DeferredShadingSSS; - static int CV_r_DeferredShadingFilterGBuffer; - - DeclareStaticConstIntCVar(CV_r_MotionVectors, 1); - DeclareStaticConstIntCVar(CV_r_MotionVectorsTransparency, 1); - DeclareStaticConstIntCVar(CV_r_MotionVectorsDebug, 0); - static float CV_r_MotionVectorsTransparencyAlphaThreshold; - static int CV_r_MotionBlur; - static int CV_r_RenderMotionBlurAfterHDR; - static int CV_r_MotionBlurScreenShot; - static int CV_r_MotionBlurQuality; - static int CV_r_MotionBlurGBufferVelocity; - static float CV_r_MotionBlurThreshold; - static int CV_r_flush; - static int CV_r_minimizeLatency; - static int CV_r_texatlassize; - static int CV_r_DeferredShadingSortLights; - static int CV_r_DeferredShadingAmbientSClear; - static int CV_r_batchtype; -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) || defined(USE_SILHOUETTEPOM_CVAR) - //HACK: make sure we can only use it for dx11 - static int CV_r_SilhouettePOM; -#else - enum - { - CV_r_SilhouettePOM = 0 - }; -#endif -#ifdef WATER_TESSELLATION_RENDERER - static int CV_r_WaterTessellationHW; -#else - enum - { - CV_r_WaterTessellationHW = 0 - }; -#endif - static int CV_r_tessellationdebug; - static float CV_r_tessellationtrianglesize; - static float CV_r_displacementfactor; - static int CV_r_geominstancingthreshold; - static int CV_r_ShadowsDepthBoundNV; - static int CV_r_ShadowsPCFiltering; - static int CV_r_rc_autoinvoke; - static int CV_r_Refraction; - static int CV_r_PostProcessReset; - static int CV_r_colorRangeCompression; - static int CV_r_colorgrading_selectivecolor; - static int CV_r_colorgrading_charts; - static int CV_r_ColorgradingChartsCache; - static int CV_r_ShaderCompilerPort; - static int CV_r_ShowDynTexturesMaxCount; - static int CV_r_ShaderCompilerDontCache; - static int CV_r_dyntexmaxsize; - static int CV_r_dyntexatlascloudsmaxsize; - static int CV_r_texminanisotropy; - static int CV_r_texmaxanisotropy; - static int CV_r_texturesskiplowermips; - static int CV_r_rendertargetpoolsize; - static int CV_r_texturesstreamingsync; - static int CV_r_ConditionalRendering; - static int CV_r_watercaustics; //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - static int CV_r_watervolumecaustics; - static int CV_r_watervolumecausticsdensity; - static int CV_r_watervolumecausticsresolution; -#if !defined(CONSOLE) - static int CV_r_shadersorbis; - static int CV_r_shadersdx10; - static int CV_r_shadersdx11; - static int CV_r_shadersGL4; - static int CV_r_shadersGLES3; - static int CV_r_shadersMETAL; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_5 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif - - static int CV_r_shadersPlatform; -#endif - // static int CV_r_envcmwrite; - static int CV_r_shaderspreactivate; - DeclareStaticConstIntCVar(CV_r_shadersremotecompiler, 0); - static int CV_r_shadersasynccompiling; - static int CV_r_shadersasyncactivation; - static int CV_r_shadersasyncmaxthreads; - static int CV_r_shaderscachedeterministic; - static int CV_r_shaderssubmitrequestline; - static int CV_r_shadersuseinstancelookuptable; - static int CV_r_shaderslogcachemisses; - static int CV_r_shadersImport; - static int CV_r_shadersExport; - static int CV_r_shadersCacheUnavailableShaders; - DeclareStaticConstIntCVar(CV_r_ShadersUseLLVMDirectXCompiler, 0); - static int CV_r_meshpoolsize; - static int CV_r_meshinstancepoolsize; - static int CV_r_multigpu; - static int CV_r_msaa; - static int CV_r_msaa_samples; - static int CV_r_msaa_quality; - static int CV_r_msaa_debug; - static int CV_r_impostersupdateperframe; - static int CV_r_beams; - static int CV_r_nodrawnear; - static int CV_r_DrawNearShadows; - static int CV_r_scissor; - static int CV_r_usezpass; - static int CV_r_ShowVideoMemoryStats; - static int CV_r_TexturesStreamingDebugMinSize; - static int CV_r_TexturesStreamingDebugMinMip; - static int CV_r_enableAltTab; - static int CV_r_StereoDevice; - static int CV_r_StereoMode; - static int CV_r_StereoOutput; - static int CV_r_StereoFlipEyes; - static int CV_r_GetScreenShot; - enum class ScreenshotType : int // define as int to match the CVar - { - None = 0, - HdrAndNormal = 1, - Normal = 2, - // Now for internal ScreenshotRequestBus use only. - NormalWithFilepath = 3, - NormalToBuffer = 4 - }; - - static int CV_r_BreakOnError; - - static int CV_r_TexturesStreamPoolSize; //plz do not access directly, always by GetTexturesStreamPoolSize() - static int CV_r_TexturesStreamPoolSecondarySize; - static inline int GetTexturesStreamPoolSize() - { - int poolSize = CV_r_TexturesStreamPoolSize + CV_r_TexturesStreamPoolSecondarySize; - return gEnv->IsEditor() - ? max(poolSize, 512) - : poolSize; - } - - static int CV_r_ReprojectOnlyStaticObjects; - static int CV_r_D3D12SubmissionThread; - static int CV_r_ReverseDepth; - - // DX12 related cvars - static int CV_r_EnableDebugLayer; - static int CV_r_NoDraw; - - //declare in release mode constant cvars - DeclareStaticConstIntCVar(CV_r_stats, 0); - DeclareStaticConstIntCVar(CV_r_statsMinDrawcalls, 0); - DeclareStaticConstIntCVar(CV_r_profiler, 0); - static float CV_r_profilerTargetFPS; - DeclareStaticConstIntCVar(CV_r_ShadowPoolMaxFrames, 30); - static int CV_r_log; - static int CV_r_VRAMDebug; - DeclareStaticConstIntCVar(CV_r_logTexStreaming, 0); - DeclareStaticConstIntCVar(CV_r_logShaders, 0); - static int CV_r_logVBuffers; - DeclareStaticConstIntCVar(CV_r_logVidMem, 0); - DeclareStaticConstIntCVar(CV_r_predicatedtiling, 0); - DeclareStaticConstIntCVar(CV_r_useESRAM, 1); - DeclareStaticConstIntCVar(CV_r_multithreaded, MULTITHREADED_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_multithreadedDrawing, 0); - DeclareStaticConstIntCVar(CV_r_multithreadedDrawingActiveThreshold, 0); - DeclareStaticConstIntCVar(CV_r_deferredshadingLightVolumes, 1); - DeclareStaticConstIntCVar(CV_r_deferredDecals, 1); - DeclareStaticConstIntCVar(CV_r_deferredDecalsDebug, 0); - DeclareStaticConstIntCVar(CV_r_deferredDecalsOnDynamicObjects, 0); - DeclareStaticConstIntCVar(CV_r_DeferredShadingLBuffersFmt, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingScissor, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingDebug, 0); - DeclareStaticConstIntCVar(CV_r_DeferredShadingDebugGBuffer, 0); - DeclareStaticConstIntCVar(CV_r_DeferredShadingEnvProbes, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingAmbient, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingAmbientLights, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingLights, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingAreaLights, 1); - DeclareStaticConstIntCVar(CV_r_DeferredShadingStencilPrepass, 1); - static int CV_r_HDRDebug; - static int CV_r_HDRBloom; - static int CV_r_HDRBloomQuality; - static int CV_r_ToneMapTechnique; - static int CV_r_ColorSpace; - static int CV_r_ToneMapExposureType; - static float CV_r_ToneMapManualExposureValue; - DeclareStaticConstIntCVar(CV_r_HDRVignetting, 1); - DeclareStaticConstIntCVar(CV_r_HDRTexFormat, 0); - static int CV_r_HDREyeAdaptationMode; - DeclareStaticConstIntCVar(CV_r_geominstancing, GEOM_INSTANCING_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_geominstancingdebug, 0); - DeclareStaticConstIntCVar(CV_r_materialsbatching, 1); - DeclareStaticConstIntCVar(CV_r_DebugLightVolumes, 0); - DeclareStaticConstIntCVar(CV_r_UseShadowsPool, SHADOWS_POOL_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_shadowtexformat, 0); - DeclareStaticConstIntCVar(CV_r_ShadowsMaskResolution, 0); - DeclareStaticConstIntCVar(CV_r_ShadowsMaskDownScale, 0); - static int CV_r_CBufferUseNativeDepth; - DeclareStaticConstIntCVar(CV_r_ShadowsStencilPrePass, 1); - DeclareStaticConstIntCVar(CV_r_ShadowsGridAligned, 1); - DeclareStaticConstIntCVar(CV_r_ShadowPass, 1); - DeclareStaticConstIntCVar(CV_r_ShadowGen, 1); - DeclareStaticConstIntCVar(CV_r_ShadowsUseClipVolume, SHADOWS_CLIP_VOL_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_ShadowGenMode, 1); - static int CV_r_ShadowsCache; - static int CV_r_ShadowsCacheFormat; - static int CV_r_ShadowsNearestMapResolution; - static int CV_r_ShadowsScreenSpace; - DeclareStaticConstIntCVar(CV_r_TerrainAO, 7); - DeclareStaticConstIntCVar(CV_r_TerrainAO_FadeDist, 8); - DeclareStaticConstIntCVar(CV_r_debuglights, 0); - DeclareStaticConstIntCVar(CV_r_DeferredShadingDepthBoundsTest, DEF_SHAD_DBT_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_deferredshadingDBTstencil, DEF_SHAD_DBT_STENCIL_DEFAULT_VAL); - static int CV_r_sunshafts; - DeclareStaticConstIntCVar(CV_r_MergeShadowDrawcalls, 1); - static int CV_r_PostProcess_CB; - static int CV_r_PostProcess; - DeclareStaticConstIntCVar(CV_r_PostProcessFilters, 1); - DeclareStaticConstIntCVar(CV_r_PostProcessGameFx, 1); - static int CV_r_colorgrading; - DeclareStaticConstIntCVar(CV_r_colorgrading_levels, 1); - DeclareStaticConstIntCVar(CV_r_colorgrading_filters, 1); - DeclareStaticConstIntCVar(CV_r_cloudsupdatealways, 0); - DeclareStaticConstIntCVar(CV_r_cloudsdebug, 0); - DeclareStaticConstIntCVar(CV_r_showdyntextures, 0); - DeclareStaticConstIntCVar(CV_r_shownormals, 0); - DeclareStaticConstIntCVar(CV_r_showlines, 0); - DeclareStaticConstIntCVar(CV_r_showtangents, 0); - DeclareStaticConstIntCVar(CV_r_showtimegraph, 0); - DeclareStaticConstIntCVar(CV_r_DebugFontRendering, 0); - DeclareStaticConstIntCVar(CV_profileStreaming, 0); - DeclareStaticConstIntCVar(CV_r_graphstyle, 0); - DeclareStaticConstIntCVar(CV_r_showbufferusage, 0); - DeclareStaticConstIntCVar(CV_r_profileshaders, 0); - DeclareStaticConstIntCVar(CV_r_ProfileShadersSmooth, 4); - DeclareStaticConstIntCVar(CV_r_ProfileShadersGroupByName, 1); - DeclareStaticConstIntCVar(CV_r_texpostponeloading, 1); - DeclareStaticConstIntCVar(CV_r_texpreallocateatlases, TEXPREALLOCATLAS_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_texlog, 0); - DeclareStaticConstIntCVar(CV_r_texnoload, 0); - DeclareStaticConstIntCVar(CV_r_texturecompiling, 1); - DeclareStaticConstIntCVar(CV_r_texBlockOnLoad, 0); - DeclareStaticConstIntCVar(CV_r_texturecompilingIndicator, 0); - DeclareStaticConstIntCVar(CV_r_TexturesDebugBandwidth, 0); - DeclareStaticConstIntCVar(CV_r_texturesstreaming, TEXSTREAMING_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_TexturesStreamingDebug, 0); - DeclareStaticConstIntCVar(CV_r_texturesstreamingnoupload, 0); - DeclareStaticConstIntCVar(CV_r_texturesstreamingonlyvideo, 0); - DeclareStaticConstIntCVar(CV_r_texturesstreamingResidencyEnabled, 1); - DeclareStaticConstIntCVar(CV_r_texturesstreamingmipfading, 1); - DeclareStaticConstIntCVar(CV_r_texturesstreamingUpdateType, TEXSTREAMING_UPDATETYPE_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_texturesstreamingPrecacheRounds, 1); - DeclareStaticConstIntCVar(CV_r_texturesstreamingSuppress, 0); - static int CV_r_texturesstreamingSkipMips; - static int CV_r_texturesstreamingMinUsableMips; - static int CV_r_texturesstreamingJobUpdate; -#if defined(TEXSTRM_DEFERRED_UPLOAD) - static int CV_r_texturesstreamingDeferred; -#endif - DeclareStaticConstIntCVar(CV_r_texturesstreamingPostponeMips, 0); - DeclareStaticConstIntCVar(CV_r_texturesstreamingPostponeThresholdKB, 1024); - DeclareStaticConstIntCVar(CV_r_texturesstreamingPostponeThresholdMip, 1); - DeclareStaticConstIntCVar(CV_r_texturesstreamingMinReadSizeKB, 64); -#if defined(SUPPORTS_INPLACE_TEXTURE_STREAMING) - static int CV_r_texturesstreamingInPlace; -#endif - DeclareStaticConstIntCVar(CV_r_lightssinglepass, 1); - static int CV_r_envcmresolution; - static int CV_r_envtexresolution; - DeclareStaticConstIntCVar(CV_r_waterreflections, 1); - DeclareStaticConstIntCVar(CV_r_waterreflections_quality, WATERREFLQUAL_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_water_godrays, 1); - DeclareStaticConstIntCVar(CV_r_reflections, 1); - DeclareStaticConstIntCVar(CV_r_reflections_quality, 3); - DeclareStaticConstIntCVar(CV_r_dof, DOF_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_texNoAnisoAlphaTest, TEXNOANISOALPHATEST_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_reloadshaders, 0); - DeclareStaticConstIntCVar(CV_r_detailtextures, 1); - DeclareStaticConstIntCVar(CV_r_texbindmode, 0); - DeclareStaticConstIntCVar(CV_r_nodrawshaders, 0); - DeclareStaticConstIntCVar(CV_r_shadersdebug, 0); - DeclareStaticConstIntCVar(CV_r_shadersignoreincludeschanging, 0); - DeclareStaticConstIntCVar(CV_r_shaderslazyunload, 0); - static int CV_r_shadersAllowCompilation; - DeclareStaticConstIntCVar(CV_r_shaderscompileautoactivate, 0); - DeclareStaticConstIntCVar(CV_r_shadersediting, 0); - DeclareStaticConstIntCVar(CV_r_shadersprecachealllights, 1); - DeclareStaticConstIntCVar(CV_r_ReflectTextureSlots, 1); - DeclareStaticConstIntCVar(CV_r_debugrendermode, 0); - DeclareStaticConstIntCVar(CV_r_debugrefraction, 0); - DeclareStaticConstIntCVar(CV_r_meshprecache, 1); - DeclareStaticConstIntCVar(CV_r_impostersdraw, 1); - static int CV_r_flares; - DeclareStaticConstIntCVar(CV_r_flareHqShafts, FLARES_HQSHAFTS_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_ZPassDepthSorting, ZPASS_DEPTH_SORT_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_TransparentPasses, 1); - DeclareStaticConstIntCVar(CV_r_TranspDepthFixup, 1); - DeclareStaticConstIntCVar(CV_r_SoftAlphaTest, 1); - DeclareStaticConstIntCVar(CV_r_usehwskinning, 1); - DeclareStaticConstIntCVar(CV_r_usemateriallayers, 2); - DeclareStaticConstIntCVar(CV_r_ParticlesSoftIsec, 1); - DeclareStaticConstIntCVar(CV_r_ParticlesRefraction, 1); - static int CV_r_ParticlesTessellation; - static int CV_r_ParticlesTessellationTriSize; - static float CV_r_ParticlesAmountGI; - static int CV_r_ParticlesGpuMaxEmitCount; - static int CV_r_ParticlesHalfRes; - DeclareStaticConstIntCVar(CV_r_ParticlesHalfResAmount, 0); - DeclareStaticConstIntCVar(CV_r_ParticlesHalfResBlendMode, 0); - DeclareStaticConstIntCVar(CV_r_ParticlesInstanceVertices, 1); - DeclareStaticConstIntCVar(CV_r_AntialiasingModeEditor, 1); - DeclareStaticConstIntCVar(CV_r_AntialiasingModeDebug, 0); - DeclareStaticConstIntCVar(CV_r_rain, 2); - DeclareStaticConstIntCVar(CV_r_rain_ignore_nearest, 1); - DeclareStaticConstIntCVar(CV_r_snow, 2); - DeclareStaticConstIntCVar(CV_r_snow_halfres, 0); - DeclareStaticConstIntCVar(CV_r_snow_displacement, 0); - DeclareStaticConstIntCVar(CV_r_snowFlakeClusters, 100); - DeclareStaticConstIntCVar(CV_r_customvisions, CUSTOMVISIONS_DEFAULT_VAL); - DeclareStaticConstIntCVar(CV_r_nohwgamma, 2); - DeclareStaticConstIntCVar(CV_r_wireframe, 0); - DeclareStaticConstIntCVar(CV_r_printmemoryleaks, 0); - DeclareStaticConstIntCVar(CV_r_releaseallresourcesonexit, 1); - DeclareStaticConstIntCVar(CV_r_character_nodeform, 0); - DeclareStaticConstIntCVar(CV_r_ZPassOnly, 0); - DeclareStaticConstIntCVar(CV_r_measureoverdraw, 0); - DeclareStaticConstIntCVar(CV_r_ShowLightBounds, 0); - DeclareStaticConstIntCVar(CV_r_MergeRenderChunks, 1); - DeclareStaticConstIntCVar(CV_r_TextureCompressor, 1); - DeclareStaticConstIntCVar(CV_r_TexturesStreamingDebugDumpIntoLog, 0); - DeclareStaticConstIntCVar(CV_e_DebugTexelDensity, 0); - DeclareStaticConstIntCVar(CV_r_RainDropsEffect, 1); - DeclareStaticConstIntCVar(CV_r_RefractionPartialResolves, 2); - DeclareStaticConstIntCVar(CV_r_RefractionPartialResolvesDebug, 0); - DeclareStaticConstIntCVar(CV_r_Batching, 1); - DeclareStaticConstIntCVar(CV_r_Unlit, 0); - DeclareStaticConstIntCVar(CV_r_HideSunInCubemaps, 1); - DeclareStaticConstIntCVar(CV_r_ParticlesDebug, 0); - - // Confetti David Srour: Upscaling Quality (Metal only at the moment) - DeclareStaticConstIntCVar(CV_r_UpscalingQuality, 0); - //Clears GMEM G-Buffer - DeclareStaticConstIntCVar(CV_r_ClearGMEMGBuffer, 0); - - // 0 = disable, 1 = enables fast math for metal shaders - DeclareStaticConstIntCVar(CV_r_MetalShadersFastMath, 1); - // Confetti Vera - static int CV_r_CubeDepthMapResolution; - - // Specular Antialiasing - static int CV_r_SpecularAntialiasing; - - //--------------float cvars---------------------- - - - static float CV_r_ZPrepassMaxDist; - static float CV_r_FlaresChromaShift; - static int CV_r_FlaresIrisShaftMaxPolyNum; - static float CV_r_FlaresTessellationRatio; - - static float CV_r_msaa_threshold_normal; - static float CV_r_msaa_threshold_depth; - - static float CV_r_drawnearfov; - static float CV_r_measureoverdrawscale; - static float CV_r_DeferredShadingLightLodRatio; - static float CV_r_DeferredShadingLightStencilRatio; - static float CV_r_rainDistMultiplier; - static float CV_r_rainOccluderSizeTreshold; - - static float CV_r_HDREyeAdaptationSpeed; - static float CV_r_HDRGrainAmount; - - static int CV_r_HDRDolbyDynamicMetadata; - static int CV_r_HDRDolbyScurve; - static float CV_r_HDRDolbyScurveSourceMin; - static float CV_r_HDRDolbyScurveSourceMid; - static float CV_r_HDRDolbyScurveSourceMax; - static float CV_r_HDRDolbyScurveSlope; - static float CV_r_HDRDolbyScurveScale; - static float CV_r_HDRDolbyScurveRGBPQTargetMin; - static float CV_r_HDRDolbyScurveRGBPQTargetMax; - static float CV_r_HDRDolbyScurveRGBPQTargetMid; - static float CV_r_HDRDolbyScurveVisionTargetMin; - static float CV_r_HDRDolbyScurveVisionTargetMax; - static float CV_r_HDRDolbyScurveVisionTargetMid; - - static float CV_r_Sharpening; - static float CV_r_ChromaticAberration; - static float CV_r_dofMinZ; - static float CV_r_dofMinZScale; - static float CV_r_dofMinZBlendMult; - static float CV_r_ShadowsBias; - static float CV_r_ShadowsAdaptionRangeClamp; - static float CV_r_ShadowsAdaptionSize; - static float CV_r_ShadowsAdaptionMin; - static float CV_r_ShadowsParticleKernelSize; - static float CV_r_ShadowsParticleJitterAmount; - static float CV_r_ShadowsParticleAnimJitterAmount; - static float CV_r_ShadowsParticleNormalEffect; -private: - static float CV_r_shadow_jittering; // dont use this directly for rendering. use m_shadowJittering or GetShadowJittering() instead; -public: - static int CV_r_ShadowPoolMaxTimeslicedUpdatesPerFrame; - static int CV_r_ShadowCastingLightsMaxCount; - static int CV_r_HeightMapAO; - static float CV_r_HeightMapAOAmount; - static float CV_r_HeightMapAOResolution; - static float CV_r_HeightMapAORange; - static float CV_r_RenderMeshHashGridUnitSize; - static float CV_r_normalslength; - static float CV_r_TexelsPerMeter; - static float CV_r_TexturesStreamingMaxRequestedMB; - static int CV_r_TexturesStreamingMaxRequestedJobs; - static float CV_r_TexturesStreamingMipBias; - static int CV_r_TexturesStreamingMipClampDVD; - static int CV_r_TexturesStreamingDisableNoStreamDuringLoad; - static float CV_r_texturesstreamingResidencyTimeTestLimit; - static float CV_r_texturesstreamingResidencyTime; - static float CV_r_texturesstreamingResidencyThrottle; - static float CV_r_envcmupdateinterval; - static float CV_r_envtexupdateinterval; - static int CV_r_SlimGBuffer; - static float CV_r_TextureLodDistanceRatio; - static float CV_r_water_godrays_distortion; - static float CV_r_waterupdateFactor; - static float CV_r_waterupdateDistance; - static float CV_r_waterreflections_min_visible_pixels_update; - static float CV_r_waterreflections_minvis_updatefactormul; - static float CV_r_waterreflections_minvis_updatedistancemul; - static float CV_r_waterreflections_offset; - static float CV_r_watercausticsdistance; - static float CV_r_watervolumecausticssnapfactor; - static float CV_r_watervolumecausticsmaxdistance; - static float CV_r_detaildistance; - static float CV_r_DrawNearZRange; - static float CV_r_DrawNearFarPlane; - static float CV_r_imposterratio; - static float CV_r_rainamount; - static float CV_r_MotionBlurShutterSpeed; - static float CV_r_MotionBlurCameraMotionScale; - static float CV_r_MotionBlurMaxViewDist; - static float CV_r_gamma; - static float CV_r_contrast; - static float CV_r_brightness; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERER_H_SECTION_6 - #include AZ_RESTRICTED_FILE(Renderer_h) -#endif - static float CV_r_ZFightingDepthScale; - static float CV_r_ZFightingExtrude; - static float CV_r_StereoStrength; - static float CV_r_StereoEyeDist; - static float CV_r_StereoScreenDist; - static float CV_r_StereoNearGeoScale; - static float CV_r_StereoHudScreenDist; - static float CV_r_StereoGammaAdjustment; - static int CV_r_ConsoleBackbufferWidth; - static int CV_r_ConsoleBackbufferHeight; - - static int CV_r_AntialiasingMode_CB; - static int CV_r_AntialiasingMode; - static float CV_r_AntialiasingNonTAASharpening; - static int CV_r_AntialiasingTAAJitterPattern; - DeclareStaticConstIntCVar(CV_r_AntialiasingTAAUseAntiFlickerFilter, 1); - DeclareStaticConstIntCVar(CV_r_AntialiasingTAAUseJitterMipBias, 1); - DeclareStaticConstIntCVar(CV_r_AntialiasingTAAUseVarianceClamping, 0); - static float CV_r_AntialiasingTAAClampingFactor; - static float CV_r_AntialiasingTAANewFrameWeight; - static float CV_r_AntialiasingTAASharpening; - static float CV_r_FogDepthTest; -#if defined(VOLUMETRIC_FOG_SHADOWS) - static int CV_r_FogShadows; - static int CV_r_FogShadowsMode; -#endif - static int CV_r_FogShadowsWater; - - static float CV_r_rain_maxviewdist; - static float CV_r_rain_maxviewdist_deferred; - - static int CV_r_SSReflections; - static int CV_r_SSReflHalfRes; - static int CV_r_ssdo; - static int CV_r_ssdoHalfRes; - static int CV_r_ssdoColorBleeding; - static float CV_r_ssdoRadius; - static float CV_r_ssdoRadiusMin; - static float CV_r_ssdoRadiusMax; - static float CV_r_ssdoAmountDirect; - static float CV_r_ssdoAmountAmbient; - static float CV_r_ssdoAmountReflection; - - // constant used to indicate that CustomResMax should be set to the maximum allowable by device resources - static const int s_CustomResMaxSize_USE_MAX_RESOURCES; - static int CV_r_CustomResMaxSize; - static int CV_r_CustomResWidth; - static int CV_r_CustomResHeight; - static int CV_r_CustomResPreview; - static int CV_r_Supersampling; - static int CV_r_SupersamplingFilter; - -#if defined(ENABLE_RENDER_AUX_GEOM) - static int CV_r_enableauxgeom; -#endif - - static int CV_r_buffer_banksize; - static int CV_r_constantbuffer_banksize; - static int CV_r_constantbuffer_watermark; - static int CV_r_transient_pool_size; - static int CV_r_buffer_sli_workaround; - DeclareStaticConstIntCVar(CV_r_buffer_enable_lockless_updates, 1); - DeclareStaticConstIntCVar(CV_r_enable_full_gpu_sync, 0); - static int CV_r_buffer_pool_max_allocs; - static int CV_r_buffer_pool_defrag_static; - static int CV_r_buffer_pool_defrag_dynamic; - static int CV_r_buffer_pool_defrag_max_moves; - - static int CV_r_ParticleVerticePoolSize; - - static int CV_r_GeomCacheInstanceThreshold; - - static int CV_r_VisAreaClipLightsPerPixel; - static int CV_r_OutputShaderSourceFiles; - - static int CV_r_VolumetricFog; - static int CV_r_VolumetricFogTexScale; - static int CV_r_VolumetricFogTexDepth; - static float CV_r_VolumetricFogReprojectionBlendFactor; - static int CV_r_VolumetricFogSample; - static int CV_r_VolumetricFogShadow; - static int CV_r_VolumetricFogDownscaledSunShadow; - static int CV_r_VolumetricFogDownscaledSunShadowRatio; - static int CV_r_VolumetricFogReprojectionMode; - static float CV_r_VolumetricFogMinimumLightBulbSize; - - static float CV_r_ResolutionScale; - - // Confetti David Srour: Global VisArea/Portals blend weight for GMEM path - static float CV_r_GMEMVisAreasBlendWeight; - - // Confetti David Srour: 0 = disable, 1= 256bpp GMEM path, 2 = 128bpp GMEM path - static int CV_r_EnableGMEMPath; - - // Confetti David Srour: 0 = GMEM postproc w/out CS, 1 = GMEM postproc w/ CS - static int CV_r_EnableGMEMPostProcCS; - - // Confetti David Srour: Used to reduce draw calls during DOF's gathers - static int CV_r_GMEM_DOF_Gather1_Quality; - static int CV_r_GMEM_DOF_Gather2_Quality; - - static int CV_r_RainUseStencilMasking; - - // Confetti Thomas Zeng: 0 = disable, 1 = enable - static int CV_r_EnableComputeDownSampling; - - static int CV_r_ForceFixedPointRenderTargets; - - // Confetti Vera - static float CV_r_CubeDepthMapFarPlane; - - // Fur control parameters - static int CV_r_Fur; - static int CV_r_FurShellPassCount; - static int CV_r_FurShowBending; - static int CV_r_FurDebug; - static int CV_r_FurDebugOneShell; - static int CV_r_FurFinPass; - static int CV_r_FurFinShadowPass; - static float CV_r_FurMovementBendingBias; - static float CV_r_FurMaxViewDist; - - static int CV_r_SkipNativeUpscale; - static int CV_r_SkipRenderComposites; - - static float CV_r_minConsoleFontSize; - static float CV_r_maxConsoleFontSize; - - // Linux CVARS - static int CV_r_linuxSkipWindowCreation; - - // Graphics programmers: Use these in your code for local tests/debugging. - // Delete all references in your code before you submit - static int CV_r_GraphicsTest00; - static int CV_r_GraphicsTest01; - static int CV_r_GraphicsTest02; - static int CV_r_GraphicsTest03; - static int CV_r_GraphicsTest04; - static int CV_r_GraphicsTest05; - static int CV_r_GraphicsTest06; - static int CV_r_GraphicsTest07; - static int CV_r_GraphicsTest08; - static int CV_r_GraphicsTest09; - - //--------------end cvars------------------------ - - - virtual void MakeMatrix([[maybe_unused]] const Vec3& pos, [[maybe_unused]] const Vec3& angles, [[maybe_unused]] const Vec3& scale, [[maybe_unused]] Matrix34* mat){assert(0); }; - - - virtual WIN_HWND GetHWND() = 0; - - void SetTextureAlphaChannelFromRGB(byte* pMemBuffer, int nTexSize); - - void EnableSwapBuffers(bool bEnable) { m_bSwapBuffers = bEnable; } - bool m_bSwapBuffers; - - virtual void SetTexturePrecaching(bool stat); - - virtual void EnableGPUTimers2([[maybe_unused]] bool bEnabled) {}; - virtual void AllowGPUTimers2([[maybe_unused]] bool bAllow) {} - - virtual const RPProfilerStats* GetRPPStats([[maybe_unused]] ERenderPipelineProfilerStats eStat, [[maybe_unused]] bool bCalledFromMainThread = true) const { return nullptr; } - virtual const RPProfilerStats* GetRPPStatsArray([[maybe_unused]] bool bCalledFromMainThread = true) const { return nullptr; } - - virtual int GetPolygonCountByType([[maybe_unused]] uint32 EFSList, [[maybe_unused]] EVertexCostTypes vct, [[maybe_unused]] uint32 z, [[maybe_unused]] bool bCalledFromMainThread = true) { return 0; } - - //platform specific - virtual void RT_InsertGpuCallback([[maybe_unused]] uint32 context, [[maybe_unused]] GpuCallbackFunc callback) {} - virtual void EnablePipelineProfiler(bool bEnable) = 0; - - virtual float GetGPUFrameTime(); - virtual void GetRenderTimes(SRenderTimes& outTimes); - - virtual void LogShaderImportMiss([[maybe_unused]] const CShader* pShader) {} - -#if !defined(_RELEASE) - //Get debug draw call stats stat - virtual RNDrawcallsMapMesh& GetDrawCallsInfoPerMesh(bool mainThread = true) - { - if (mainThread) - { - return m_RP.m_pRNDrawCallsInfoPerMesh[m_RP.m_nFillThreadID]; - } - else - { - return m_RP.m_pRNDrawCallsInfoPerMesh[m_RP.m_nProcessThreadID]; - } - } - - // Added functionality for retrieving previous frames stats to use this frame - virtual RNDrawcallsMapMesh& GetDrawCallsInfoPerMeshPreviousFrame(bool mainThread = true) - { - if (mainThread) - { - return m_RP.m_pRNDrawCallsInfoPerMeshPreviousFrame[m_RP.m_nFillThreadID]; - } - else - { - return m_RP.m_pRNDrawCallsInfoPerMeshPreviousFrame[m_RP.m_nProcessThreadID]; - } - } - virtual RNDrawcallsMapNode& GetDrawCallsInfoPerNodePreviousFrame(bool mainThread = true) - { - if (mainThread) - { - return m_RP.m_pRNDrawCallsInfoPerNodePreviousFrame[m_RP.m_nFillThreadID]; - } - else - { - return m_RP.m_pRNDrawCallsInfoPerNodePreviousFrame[m_RP.m_nProcessThreadID]; - } - } - - virtual int GetDrawCallsPerNode(IRenderNode* pRenderNode); - - //Routine to perform an emergency flush of a particular render node from the stats, as not all render node holders are delay-deleted - virtual void ForceRemoveNodeFromDrawCallsMap(IRenderNode* pNode) - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - IRenderer::RNDrawcallsMapNodeItor pItor = m_RP.m_pRNDrawCallsInfoPerNode[ i ].find(pNode); - if (pItor != m_RP.m_pRNDrawCallsInfoPerNode[ i ].end()) - { - m_RP.m_pRNDrawCallsInfoPerNode[ i ].erase(pItor); - } - } - } - - void ClearDrawCallsInfo() - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - m_RP.m_pRNDrawCallsInfoPerMesh[i].swap(m_RP.m_pRNDrawCallsInfoPerMeshPreviousFrame[i]); - m_RP.m_pRNDrawCallsInfoPerMesh[i].clear(); - m_RP.m_pRNDrawCallsInfoPerNode[i].swap(m_RP.m_pRNDrawCallsInfoPerNodePreviousFrame[i]); - m_RP.m_pRNDrawCallsInfoPerNode[i].clear(); - } - } -#endif - - virtual void CollectDrawCallsInfo(bool status) - { - m_bCollectDrawCallsInfo = status; - } - - virtual void CollectDrawCallsInfoPerNode(bool status) - { - m_bCollectDrawCallsInfoPerNode = status; - } - - virtual void EnableLevelUnloading(bool enable) - { - gRenDev->m_bLevelUnloading = enable; - } - - virtual void EnableBatchMode(bool enable) - { - RENDER_LOCK_CS(SRenderThread::s_rcLock); - if (enable) - { - gRenDev->m_bEndLevelLoading = false; - gRenDev->m_bStartLevelLoading = true; - } - else - { - gRenDev->m_bEndLevelLoading = true; - gRenDev->m_bStartLevelLoading = false; - } - } - - // When a level load fails, the system event for ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_END will not be called, so we need to do some cleanup here. - // This is to ensure the renderer no longer thinks we are rendering a loading screen after the level load failed. - virtual void OnLevelLoadFailed() - { -#if AZ_LOADSCREENCOMPONENT_ENABLED - EBUS_EVENT(LoadScreenBus, Stop); -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - gRenDev->m_bEndLevelLoading = true; - gRenDev->m_bStartLevelLoading = false; - } - - virtual bool IsStereoModeChangePending() - { - return false; - } - - int m_nFlushAllPendingTextureStreamingJobs; - float m_fTexturesStreamingGlobalMipFactor; - -protected: - - AZ::LegacyJobExecutor m_generateRendItemJobExecutor; - AZ::LegacyJobExecutor m_generateRendItemPreProcessJobExecutor; - AZ::LegacyJobExecutor m_generateShadowRendItemJobExecutor; - AZ::LegacyJobExecutor m_finalizeRendItemsJobExecutor[RT_COMMAND_BUF_COUNT]; - AZ::LegacyJobExecutor m_finalizeShadowRendItemsJobExecutor[RT_COMMAND_BUF_COUNT]; - -private: - std::vector m_syncMainWithRenderListeners; - RendererAssetListener m_assetListener; - - unsigned long m_nvidiaDriverVersion = 0; -}; - - -#include "CommonRender.h" - -#define SKY_BOX_SIZE 32.f diff --git a/Code/CryEngine/RenderDll/Common/RendererAPI.h b/Code/CryEngine/RenderDll/Common/RendererAPI.h deleted file mode 100644 index 1035851dd4..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendererAPI.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Main header included by every file in Renderer. - -#pragma once - -#if defined(RENDERER_API) -#error RENDERER_API should only be defined in this header -#endif - -#if defined(RENDERER_EXPORTS) - #define RENDERER_API __declspec(dllexport) - #define RENDERER_API_EXTERN -#else - #define RENDERER_API __declspec(dllimport) - #define RENDERER_API_EXTERN extern -#endif - diff --git a/Code/CryEngine/RenderDll/Common/RendererDefs.h b/Code/CryEngine/RenderDll/Common/RendererDefs.h deleted file mode 100644 index 9dad69f471..0000000000 --- a/Code/CryEngine/RenderDll/Common/RendererDefs.h +++ /dev/null @@ -1,815 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#ifndef _WINSOCKAPI_ -# define _WINSOCKAPI_ -# define _DID_SKIP_WINSOCK_ -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RENDERERDEFS_H_SECTION_1 1 -#define RENDERERDEFS_H_SECTION_2 2 -#define RENDERERDEFS_H_SECTION_3 3 -#define RENDERERDEFS_H_SECTION_4 4 -#define RENDERERDEFS_H_SECTION_5 5 -#define RENDERERDEFS_H_SECTION_6 6 -#define RENDERERDEFS_H_SECTION_7 7 -#define RENDERERDEFS_H_SECTION_8 8 -#define RENDERERDEFS_H_SECTION_9 9 -#define RENDERERDEFS_H_SECTION_10 10 -#define RENDERERDEFS_H_SECTION_11 11 -#define RENDERERDEFS_H_SECTION_12 12 -#define RENDERERDEFS_H_SECTION_13 13 -#define RENDERERDEFS_H_SECTION_14 14 -#define RENDERERDEFS_H_SECTION_15 15 -#define RENDERERDEFS_H_SECTION_16 16 -#define RENDERERDEFS_H_SECTION_17 17 -#define RENDERERDEFS_H_SECTION_18 18 -#define RENDERERDEFS_H_SECTION_19 19 -#define RENDERERDEFS_H_SECTION_20 20 -#endif - -#define SUPPORTS_WINDOWS_10_SDK false -#if _MSC_VER -#include -#undef SUPPORTS_WINDOWS_10_SDK -#define SUPPORTS_WINDOWS_10_SDK (VER_PRODUCTBUILD > 9600) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_1 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#else -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) -#define RENDERERDEFS_H_TRAIT_SUPPORT_BAKED_MESHES_AND_DECALS 1 -#endif - -#define RENDERERDEFS_H_TRAIT_CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS 0 - -#if defined(WIN32) || defined(WIN64) -#define RENDERERDEFS_H_TRAIT_SUPPORT_D3D_DEBUG_RUNTIME 1 -#endif - -#if defined(APPLE) -#define RENDERERDEFS_H_TRAIT_DEFINE_D3DPOOL 1 -#endif - -#define RENDERERDEFS_H_TRAIT_ALIAS_D3DOK 0 -#define RENDERMESH_CPP_TRAIT_BUFFER_ENABLE_DIRECT_ACCESS 0 - -#if defined(MOBILE) -#define RENDERTHREAD_H_TRAIT_USE_LOCKS_FOR_FLUSH_SYNC 1 -#endif - -#if defined(WIN64) -#define PLANNINGTEXTURESTREAMER_JOBS_CPP_TRAIT_JOB_INITKEYS_PREFETCH 1 -#endif - -#define TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_ETT_2D_EARLY_OUT 1 -#define TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_FORMATCOMPATIBLE 1 -#define TEXTURESTREAMING_CPP_TRAIT_TRYCOMMIT_COPYMIPS 1 -#define TEXTURESTREAMING_CPP_TRAIT_COPYMIPS_MOVEENGINE 0 -#define TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_SRCTILEMODE_CHECK 0 - -#define D3DFXPIPELINE_CPP_TRAIT_CLEARVIEW 1 - -#if defined(IOS) -#define D3DGPUPARTICLEENGINE_CPP_TRAIT_BEGINUPDATE_INIT_COMPUTE 1 -#endif - -#define D3DHWSHADER_H_TRAIT_DEFINE_D3D_BLOB 0 - -#if defined(OPENGL) || defined(CRY_USE_METAL) -#define D3DHWSHADERCOMPILING_CPP_TRAIT_VERTEX_FORMAT 1 -#else -#define D3DHWSHADERCOMPILING_CPP_TRAIT_VERTEX_FORMAT 0 -#endif - -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) -#define D3DRENDERRE_CPP_TRAIT_MFDRAW_SETDEPTHSURF 1 -#endif - -#define D3DRENDERRE_CPP_TRAIT_MFDRAW_USEINSTANCING 1 - -#if defined(AZ_PLATFORM_WINDOWS) -#define D3DSTEREO_CPP_TRAIT_SELECTDEFAULTDEVICE_STEREODEVICEDRIVER 1 -#endif - -#if defined(WIN32) -#define D3DSYSTEM_CPP_TRAIT_SETWINDOW_REGISTERWINDOWMESSAGEHANDLER 1 -#endif - -#define DRIVERD3D_CPP_TRAIT_CALCULATERESOLUTIONS_1080 0 - -#if defined(IOS) || defined(ANDROID) -#define DRIVERD3D_CPP_TRAIT_HANDLEDISPLAYPROPERTYCHANGES_FULLSCREEN 1 -#endif - -#if defined(IOS) || defined(ANDROID) -#define DRIVERD3D_CPP_TRAIT_HANDLEDISPLAYPROPERTYCHANGES_NATIVERES 1 -#endif - -#define DRIVERD3D_CPP_TRAIT_HANDLEDISPLAYPROPERTYCHANGES_CALCRESOLUTIONS 1 - -#define DRIVERD3D_CPP_TRAIT_RT_ENDFRAME_NOTIMPL 0 - -#if defined(_WIN32) -#define DRIVERD3D_CPP_TRAIT_ONSYSTEMEVENT_EVENTMOVE 1 -#endif - -#if defined (WIN32) -#define DRIVERD3D_H_TRAIT_DEFSAVETEXTURE 1 -#endif - -#if defined(WIN32) -#define DRIVERD3D_H_TRAIT_DEFREGISTEREDWINDOWHANDLER 1 -#endif - -#if defined (WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) -#define DRIVERD3D_H_TRAIT_DEFOCCLUSIONTEXTURESVALID 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_CSIMPLEGPUTIMER_SETQUERYSTART 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_RELEASE_RELEASEQUERY 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_INIT_CREATEQUERY 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_START_PRIMEQUERY 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_STOP_ENDQUERY 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_CPP_TRAIT_UPDATETIME_GETDATA 1 -#endif - -#if defined(WIN32) -#define GPUTIMER_H_TRAIT_DEFINEQUERIES 1 -#endif - -#if defined(LINUX) || defined(APPLE) -#define NULL_SYSTEM_TRAIT_INIT_RETURNTHIS 1 -#endif - -#endif - -#if defined(WIN64) && defined (CRY_USE_DX12) -#define CRY_INTEGRATE_DX12 -#endif - -#ifdef _DEBUG -#define GFX_DEBUG -#endif - -//defined in DX9, but not DX10 -#if RENDERERDEFS_H_TRAIT_ALIAS_D3DOK || defined(OPENGL) -#define D3D_OK S_OK -#endif - -#if !defined(CRY_USE_DX12) && !defined(OPENGL) && !defined(_RELEASE) -# define RENDERER_ENABLE_BREAK_ON_ERROR 0 ///< Define causes compile errors on DX12 and OpenGL -#endif -#if !defined(RENDERER_ENABLE_BREAK_ON_ERROR) -# define RENDERER_ENABLE_BREAK_ON_ERROR 0 -#endif -#if RENDERER_ENABLE_BREAK_ON_ERROR -# include -namespace detail -{ - const char* ToString(long const hr); - bool CheckHResult(long const hr, bool breakOnError, const char* file, const int line); -} -//# undef FAILED -//# define FAILED(x) (detail::CheckHResult((x), false, __FILE__, __LINE__)) -# define CHECK_HRESULT(x) (detail::CheckHResult((x), true, __FILE__, __LINE__)) -#else -# define CHECK_HRESULT(x) (!FAILED(x)) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_6 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#if defined(OPENGL) && (defined(DEBUG) || defined(_DEBUG)) -#define LY_ENABLE_OPENGL_ERROR_CHECKING -#endif -namespace O3de -{ - namespace OpenGL - { -#if defined(LY_ENABLE_OPENGL_ERROR_CHECKING) - unsigned int CheckError(); - void ClearErrors(); -#else - inline unsigned int CheckError() { return 0; } - inline void ClearErrors() {} -#endif - } -} - -// enable support for D3D11.1 features if the platform supports it -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_2 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(CRY_USE_DX12) -# define DEVICE_SUPPORTS_D3D11_1 -#endif - -#ifdef _DEBUG -#define CRTDBG_MAP_ALLOC -#endif //_DEBUG - -#undef USE_STATIC_NAME_TABLE -#define USE_STATIC_NAME_TABLE - -#if !defined(_RELEASE) -#define ENABLE_FRAME_PROFILER -#endif - -#if !defined(NULL_RENDERER) && (!defined(_RELEASE) || defined(PERFORMANCE_BUILD)) -#define ENABLE_PROFILING_GPU_TIMERS -#define ENABLE_FRAME_PROFILER_LABELS -#endif - -#ifdef ENABLE_FRAME_PROFILER -# define PROFILE 1 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_7 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#ifdef ENABLE_SCUE_VALIDATION -enum EVerifyType -{ - eVerify_Normal, - eVerify_ConstantBuffer, - eVerify_VertexBuffer, - eVerify_SRVTexture, - eVerify_SRVBuffer, - eVerify_UAVTexture, - eVerify_UAVBuffer, -}; -#endif - -#if __HAS_SSE__ -// includes , include it before platform.h -#include -#define CONST_INT32_PS(N, V3, V2, V1, V0) \ - const _MM_ALIGN16 int _##N[] = { V0, V1, V2, V3 }; /*little endian!*/ \ - const F32vec4 N = _mm_load_ps((float*)_##N); -#endif - -// enable support for baked meshes and decals on PC -#if RENDERERDEFS_H_TRAIT_SUPPORT_BAKED_MESHES_AND_DECALS -//#define RENDER_MESH_TRIANGLE_HASH_MAP_SUPPORT // CryTek removed this #define in 3.8. Not sure if we should strip out all related code or not, or if it may be a useful feature. -#define TEXTURE_GET_SYSTEM_COPY_SUPPORT -#endif - -#if defined(_CPU_SSE) && !defined(WIN64) -#define __HAS_SSE__ 1 -#endif - -#define MAX_REND_RECURSION_LEVELS 2 - -#if defined(OPENGL) -#define CRY_OPENGL_ADAPT_CLIP_SPACE 1 -#define CRY_OPENGL_FLIP_Y 1 -#define CRY_OPENGL_MODIFY_PROJECTIONS !CRY_OPENGL_ADAPT_CLIP_SPACE -#endif // defined(OPENGL) - -#ifdef STRIP_RENDER_THREAD -#define m_nCurThreadFill 0 -#define m_nCurThreadProcess 0 -#endif - -#ifdef STRIP_RENDER_THREAD -#define ASSERT_IS_RENDER_THREAD(rt) -#define ASSERT_IS_MAIN_THREAD(rt) -#else -#define ASSERT_IS_RENDER_THREAD(rt) assert((rt)->IsRenderThread()); -#define ASSERT_IS_MAIN_THREAD(rt) assert((rt)->IsMainThread()); -#define ASSERT_IS_MAIN_OR_RENDER_THREAD(rt) assert((rt)->IsMainThread() || (rt)->IsRenderThread()); -#endif - -//#define ASSERT_IN_SHADER( expr ) assert( expr ); -#define ASSERT_IN_SHADER(expr) - -#define _USE_MATH_DEFINES -#include - -// windows desktop API available for usage -#if defined(WIN32) || defined(WIN64) -#define WINDOWS_DESKTOP_API -#endif - -#if (defined(WIN32) || defined(WIN64)) && !defined(OPENGL) -#define LEGACY_D3D9_INCLUDE -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_3 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#if !defined(NULL_RENDERER) - -// all D3D10 blob related functions and struct will be deprecated in next DirectX APIs -// and replaced with regular D3DBlob counterparts -#define D3D10CreateBlob D3DCreateBlob - -// Direct3D11 includes -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_9 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(OPENGL) -#include "CryLibrary.h" -// enable metal for ios device only. Emulator is not supported for now. -#if TARGET_OS_IPHONE || TARGET_OS_TV -#ifndef __IPHONE_9_0 -#define __IPHONE_9_0 90000 -#endif // __IPHONE_9_0 -#endif - -#if defined(CRY_USE_METAL) -#include -#else -#include "XRenderD3D9/DXGL/CryDXGL.hpp" -#endif -#elif defined(CRY_USE_DX12) -#include "CryLibrary.h" -typedef uintptr_t SOCKET; -#else - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_4 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#elif defined(WIN32) || defined(WIN64) -#include "d3d11.h" -#endif - -#if defined(LEGACY_D3D9_INCLUDE) -#include "d3d9.h" -#endif - -#endif -#else //defined(NULL_RENDERER) -#if defined(WIN32) -#include "windows.h" -#endif -#if (defined(LINUX) || defined(APPLE)) && !defined(DXGI_FORMAT_DEFINED) -#include -#endif -#endif - -#ifdef _DID_SKIP_WINSOCK_ -# undef _WINSOCKAPI_ -# undef _DID_SKIP_WINSOCK_ -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_5 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#if !defined(_RELEASE) -#define ENABLE_TEXTURE_STREAM_LISTENER -#endif - -/////////////////////////////////////////////////////////////////////////////// -/* BUFFER ACCESS -* Confetti Note -- David: -* Buffer access related defines have been moved down as some preproc. if-branches rely on CRY_USE_METAL. -*/ -/////////////////////////////////////////////////////////////////////////////// -// BUFFER_ENABLE_DIRECT_ACCESS -// stores pointers to actual backing storage of vertex buffers. Can only be used on architectures -// that have a unified memory architecture and further guarantee that buffer storage does not change -// on repeated accesses. -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_10 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(CRY_USE_DX12) || defined(CRY_USE_METAL) -# define BUFFER_ENABLE_DIRECT_ACCESS 1 -#endif - -// BUFFER_USE_STAGED_UPDATES -// On platforms that support staging buffers, special buffers are allocated that act as a staging area -// for updating buffer contents on the fly. - -// when staged updates are disabled CPU will have direct access to the pool's buffers' content -// and update data directly. This cuts memory consumption and reduces the number of copies. -// GPU won't be used to update buffer content but it will be used to perform defragmentation. -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_11 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -# undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(CRY_USE_METAL) -# define BUFFER_USE_STAGED_UPDATES 0 -#else -# define BUFFER_USE_STAGED_UPDATES 1 -#endif - -// BUFFER_SUPPORT_TRANSIENT_POOLS -// On d3d11 we want to separate the fire-and-forget allocations from the longer lived dynamic ones -#if !defined(NULL_RENDERER) && ((!defined(CONSOLE) && !defined(CRY_USE_DX12)) || defined(CRY_USE_METAL)) -# define BUFFER_SUPPORT_TRANSIENT_POOLS 1 -#else -# define BUFFER_SUPPORT_TRANSIENT_POOLS 0 -#endif - -#ifndef BUFFER_ENABLE_DIRECT_ACCESS -# define BUFFER_ENABLE_DIRECT_ACCESS 0 -#endif - -// CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS -// Enable if we have direct access to video memory and the device manager -// should manage constant buffers -#if BUFFER_ENABLE_DIRECT_ACCESS == 1 -# if RENDERERDEFS_H_TRAIT_CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS || defined (CRY_USE_DX12) -# define CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS 1 -# else -# define CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS 0 -# endif -#else -# define CONSTANT_BUFFER_ENABLE_DIRECT_ACCESS 0 -#endif - -#if BUFFER_ENABLE_DIRECT_ACCESS && (defined(WIN32) || defined(WIN64)) && !defined(CRY_USE_DX12) -# error BUFFER_ENABLE_DIRECT_ACCESS is not supported on windows platforms -#endif - -#if defined(WIN32) -# define FEATURE_SILHOUETTE_POM -#elif defined(WIN64) -# define FEATURE_SILHOUETTE_POM -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_12 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#elif defined(LINUX) -# define FEATURE_SILHOUETTE_POM -#elif defined(APPLE) -# define FEATURE_SILHOUETTE_POM -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_13 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#if !defined(_RELEASE) && !defined(NULL_RENDERER) && RENDERERDEFS_H_TRAIT_SUPPORT_D3D_DEBUG_RUNTIME && !defined(OPENGL) -# define SUPPORT_D3D_DEBUG_RUNTIME -#endif - -#if defined(NULL_RENDERER) -# define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_14 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -# undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -# define SUPPORT_DEVICE_INFO -# if defined(WIN32) || defined(WIN64) -# define SUPPORT_DEVICE_INFO_MSG_PROCESSING -# define SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES -# endif -#endif - -#include - -#if !defined(NULL_RENDERER) -# if defined(CRY_USE_DX12) -# include "XRenderD3D9/DX12/CryDX12.hpp" -# elif defined(DEVICE_SUPPORTS_D3D11_1) -# if defined(AZ_RESTRICTED_PLATFORM) -# define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_15 -# include AZ_RESTRICTED_FILE(RendererDefs_h) -# endif -# if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -# undef AZ_RESTRICTED_SECTION_IMPLEMENTED -# else - typedef IDXGIFactory1 DXGIFactory; - typedef IDXGIDevice1 DXGIDevice; - typedef IDXGIAdapter1 DXGIAdapter; - typedef IDXGIOutput DXGIOutput; - typedef IDXGISwapChain DXGISwapChain; - typedef ID3D11DeviceContextX D3DDeviceContext; - typedef ID3D11DeviceX D3DDevice; -# endif -# else - typedef IDXGIFactory1 DXGIFactory; -# if !defined(ANDROID) && !defined(APPLE) && !defined(LINUX) && !defined(SKIP_TYPEDEF_OF_IDXGIDEVICE1) - typedef IDXGIDevice1 DXGIDevice; -# endif - typedef IDXGIAdapter1 DXGIAdapter; - typedef IDXGIOutput DXGIOutput; - typedef IDXGISwapChain DXGISwapChain; - typedef ID3D11DeviceContext D3DDeviceContext; - typedef ID3D11Device D3DDevice; -# endif - -typedef ID3D11InputLayout D3DVertexDeclaration; -typedef ID3D11VertexShader D3DVertexShader; -typedef ID3D11PixelShader D3DPixelShader; -typedef ID3D11Resource D3DResource; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_16 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -typedef ID3D11Resource D3DBaseTexture; -#endif - -typedef ID3D11Texture2D D3DTexture; -typedef ID3D11Texture3D D3DVolumeTexture; -typedef ID3D11Texture2D D3DCubeTexture; -typedef ID3D11Buffer D3DBuffer; -typedef ID3D11ShaderResourceView D3DShaderResourceView; -typedef ID3D11UnorderedAccessView D3DUnorderedAccessView; -typedef ID3D11RenderTargetView D3DSurface; -typedef ID3D11DepthStencilView D3DDepthSurface; -typedef ID3D11View D3DBaseView; -typedef ID3D11Query D3DQuery; -typedef D3D11_VIEWPORT D3DViewPort; -typedef D3D11_RECT D3DRectangle; -typedef DXGI_FORMAT D3DFormat; -typedef D3D11_PRIMITIVE_TOPOLOGY D3DPrimitiveType; -typedef ID3D10Blob D3DBlob; -typedef ID3D11SamplerState D3DSamplerState; - -#if !defined(USE_D3DX) - -// this should be moved into seperate D3DX defintion file which should still be used -// for console builds, until everything in the engine has been cleaned up which still -// references this - -#if defined(APPLE) -//interface is also a objective c keyword -typedef struct ID3DXConstTable ID3DXConstTable; -typedef struct ID3DXConstTable* LPD3DXCONSTANTTABLE; -#else -typedef interface ID3DXConstTable ID3DXConstTable; -typedef interface ID3DXConstTable* LPD3DXCONSTANTTABLE; -#endif - - - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_19 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - -#if RENDERERDEFS_H_TRAIT_DEFINE_D3DPOOL || defined(CRY_USE_DX12) -// D3DPOOL define still used as function parameters, so defined to backwards compatible with D3D9 -typedef enum _D3DPOOL -{ - D3DPOOL_DEFAULT = 0, - D3DPOOL_MANAGED = 1, - D3DPOOL_SYSTEMMEM = 2, - D3DPOOL_SCRATCH = 3, - D3DPOOL_FORCE_DWORD = 0x7fffffff -} D3DPOOL; -#endif - -#endif - -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | \ - ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24)) -#endif // defined(MAKEFOURCC) - -#endif // !defined(WIN32) && !defined(WIN64) - -const int32 g_nD3D10MaxSupportedSubres = (6 * 15); -////////////////////////////////////////////////////////////////////////// -#else -typedef void D3DTexture; -typedef void D3DSurface; -typedef void D3DShaderResourceView; -typedef void D3DUnorderedAccessView; -typedef void D3DDepthSurface; -typedef void D3DSamplerState; -typedef int D3DFormat; -typedef void D3DBuffer; -#endif // NULL_RENDERER -////////////////////////////////////////////////////////////////////////// - -#define USAGE_WRITEONLY 8 - -////////////////////////////////////////////////////////////////////////// -// Linux specific defines for Renderer. -////////////////////////////////////////////////////////////////////////// - -#if defined(_AMD64_) && !defined(LINUX) -#include -#endif - -#define SIZEOF_ARRAY(arr) (sizeof(arr) / sizeof((arr)[0])) - -#ifdef DEBUGALLOC - -#include -#define DEBUG_CLIENTBLOCK new(_NORMAL_BLOCK, __FILE__, __LINE__) -#define new DEBUG_CLIENTBLOCK - -// memman -#define calloc(s, t) _calloc_dbg(s, t, _NORMAL_BLOCK, __FILE__, __LINE__) -#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) -#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) - -#endif - -#include -#include - -#define MAX_TMU 32 -#define MAX_STREAMS 16 - -//! Include main interfaces. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -enum eRenderPrimitiveType : int8 -{ -#if defined(NULL_RENDERER) - eptUnknown = -1, - eptTriangleList, - eptTriangleStrip, - eptLineList, - eptLineStrip, - eptPointList, -#else - eptUnknown = -1, - eptTriangleList = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, - eptTriangleStrip = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, - eptLineList = D3D11_PRIMITIVE_TOPOLOGY_LINELIST, - eptLineStrip = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, - eptPointList = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, - ept1ControlPointPatchList = D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST, - ept2ControlPointPatchList = D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, - ept3ControlPointPatchList = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, - ept4ControlPointPatchList = D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, -#endif - - // non-real primitives, used for logical batching - eptHWSkinGroups = 0x3f -}; - -inline eRenderPrimitiveType GetInternalPrimitiveType(PublicRenderPrimitiveType t) -{ - switch (t) - { - case prtTriangleList: - default: - return eptTriangleList; - case prtTriangleStrip: - return eptTriangleStrip; - case prtLineList: - return eptLineList; - case prtLineStrip: - return eptLineStrip; - } -} - -#if !defined(NULL_RENDERER) -# if defined(WIN32) -# define SUPPORT_FLEXIBLE_INDEXBUFFER // supports 16 as well as 32 bit indices AND index buffer bind offset -# elif defined(WIN64) -# define SUPPORT_FLEXIBLE_INDEXBUFFER // supports 16 as well as 32 bit indices AND index buffer bind offset -# elif defined(AZ_RESTRICTED_PLATFORM) -# define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_17 -# include AZ_RESTRICTED_FILE(RendererDefs_h) -# elif defined(LINUX) -# define SUPPORT_FLEXIBLE_INDEXBUFFER // supports 16 as well as 32 bit indices AND index buffer bind offset -# elif defined(APPLE) -# define SUPPORT_FLEXIBLE_INDEXBUFFER // supports 16 as well as 32 bit indices AND index buffer bind offset -# endif -#endif - -enum RenderIndexType : int -{ -#if defined(SUPPORT_FLEXIBLE_INDEXBUFFER) - Index16 = DXGI_FORMAT_R16_UINT, - Index32 = DXGI_FORMAT_R32_UINT -#else - Index16, - Index32 -#endif -}; - -// Interfaces from the Game -extern ILog* iLog; -extern IConsole* iConsole; -extern ITimer* iTimer; -extern ISystem* iSystem; - - - -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) -# define VOLUMETRIC_FOG_SHADOWS -#endif - -#if ((defined(AZ_PLATFORM_WINDOWS) && !defined(OPENGL)) || defined(AZ_PLATFORM_MAC)) && !defined(CRY_USE_DX12) && !defined(RELEASE) -# define ENABLE_NULL_D3D11DEVICE -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_18 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - - -// Enable to eliminate DevTextureDataSize calls during stream updates - costs 4 bytes per mip header -#define TEXSTRM_STORE_DEVSIZES - -#ifndef TEXSTRM_BYTECENTRIC_MEMORY -#define TEXSTRM_TEXTURECENTRIC_MEMORY -#endif - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) && !defined(OPENGL) && !defined(CRY_INTEGRATE_DX12) -#define TEXSTRM_DEFERRED_UPLOAD -#endif - -#if !defined(CONSOLE) -#define TEXSTRM_COMMIT_COOLDOWN -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION RENDERERDEFS_H_SECTION_20 - #include AZ_RESTRICTED_FILE(RendererDefs_h) -#endif - -#if defined(_RELEASE) -# define EXCLUDE_RARELY_USED_R_STATS -#endif - -#include -#include diff --git a/Code/CryEngine/RenderDll/Common/Renderer_Jobs.cpp b/Code/CryEngine/RenderDll/Common/Renderer_Jobs.cpp deleted file mode 100644 index 6d692087f4..0000000000 --- a/Code/CryEngine/RenderDll/Common/Renderer_Jobs.cpp +++ /dev/null @@ -1,1143 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Abstract renderer API - - -#include "RenderDll_precompiled.h" - -#include "Shadow_Renderer.h" -#include "IStatObj.h" -#include "I3DEngine.h" -#include "IMovieSystem.h" -#include "IIndexedMesh.h" -#include "BitFiddling.h" // IntegerLog2() -#include "ImageExtensionHelper.h" // CImageExtensionHelper -#include "IResourceCompilerHelper.h" - -#include "Textures/Image/CImage.h" -#include "Textures/TextureManager.h" -#include "PostProcess/PostEffects.h" -#include "RendElements/CRELensOptics.h" - -#include "RendElements/OpticsFactory.h" - -#include "XRenderD3D9/GraphicsPipeline/FurBendData.h" -#include "XRenderD3D9/GraphicsPipeline/FurPasses.h" -#include "RenderView.h" - -/////////////////////////////////////////// -// moved from "../CryCommon/branchmask.h" -// helper functions for branch elimination -// -// msb/lsb - most/less significant byte -// -// mask - 0xFFFFFFFF -// nz - not zero -// zr - is zero - -ILINE const uint32 nz2msb(const uint32 x) -{ - return -(int32)x | x; -} - -ILINE const uint32 msb2mask(const uint32 x) -{ - return (int32)(x) >> 31; -} - -ILINE const uint32 nz2one(const uint32 x) -{ - return nz2msb(x) >> 31; // int((bool)x); -} - -ILINE const uint32 nz2mask(const uint32 x) -{ - return (int32)msb2mask(nz2msb(x)); // -(int32)(bool)x; -} - -ILINE const uint32 iselmask(const uint32 mask, uint32 x, const uint32 y)// select integer with mask (0xFFFFFFFF or 0x0 only!!!) -{ - return (x & mask) | (y & ~mask); -} - - -ILINE const uint32 mask_nz_nz(const uint32 x, const uint32 y)// mask if( x != 0 && y != 0) -{ - return msb2mask(nz2msb(x) & nz2msb(y)); -} - -ILINE const uint32 mask_nz_zr(const uint32 x, const uint32 y)// mask if( x != 0 && y == 0) -{ - return msb2mask(nz2msb(x) & ~nz2msb(y)); -} - - -ILINE const uint32 mask_zr_zr(const uint32 x, const uint32 y)// mask if( x == 0 && y == 0) -{ - return ~nz2mask(x | y); -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -struct SCompareByShadowFrustumID -{ - bool operator()(const SRendItem& rA, const SRendItem& rB) const - { - return rA.rendItemSorter.ShadowFrustumID() < rB.rendItemSorter.ShadowFrustumID(); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -struct SCompareByLightIds -{ - bool operator()(const SRenderPipeline::SShadowFrustumToRender& rA, const SRenderPipeline::SShadowFrustumToRender& rB) const - { - if (rA.nLightID != rB.nLightID) - { - return rA.nLightID < rB.nLightID; - } - else - { - if (rA.pFrustum->m_eFrustumType != rB.pFrustum->m_eFrustumType) - { - return int(rA.pFrustum->m_eFrustumType) < int(rB.pFrustum->m_eFrustumType); - } - else - { - return rA.pFrustum->nShadowMapLod < rB.pFrustum->nShadowMapLod; - } - } - } -}; - -/////////////////////////////////////////////////////////////////////////////// -static inline void HandleForceFlags(int& nList, int& nAW, uint32& nBatchFlags, const uint32 nShaderFlags, const uint32 nShaderFlags2, CRenderObject* obj) -{ - // Force rendering in last place - // branchless - - const int32 sort1 = nz2mask(nShaderFlags2 & EF2_FORCE_DRAWLAST); - const int32 sort2 = nz2one(nShaderFlags2 & EF2_FORCE_DRAWFIRST); - float fSort = static_cast(100000 * (sort1 + sort2)); - - if (nShaderFlags2 & EF2_FORCE_ZPASS && !((nShaderFlags & EF_REFRACTIVE) && (nBatchFlags & FB_MULTILAYERS))) - { - nBatchFlags |= FB_Z; - } - - { - // below branchlessw version of: - //if (nShaderFlags2 & EF2_FORCE_TRANSPASS ) nList = EFSLIST_TRANSP; - //else if (nShaderFlags2 & EF2_FORCE_GENERALPASS) nList = EFSLIST_GENERAL; - //else if (nShaderFlags2 & EF2_FORCE_WATERPASS ) nList = EFSLIST_WATER; - - uint32 mb1 = nShaderFlags2 & EF2_FORCE_TRANSPASS; - uint32 mb2 = nShaderFlags2 & EF2_FORCE_GENERALPASS; - uint32 mb3 = nShaderFlags2 & EF2_FORCE_WATERPASS; - - mb1 = nz2msb(mb1); - mb2 = nz2msb(mb2) & ~mb1; - mb3 = nz2msb(mb3) & ~(mb1 ^ mb2); - - mb1 = msb2mask(mb1); - mb2 = msb2mask(mb2); - mb3 = msb2mask(mb3); - - const uint32 mask = mb1 | mb2 | mb3; - mb1 &= EFSLIST_TRANSP; - mb2 &= EFSLIST_GENERAL; - mb3 &= EFSLIST_WATER; - - nList = iselmask(mask, mb1 | mb2 | mb3, nList); - } - - - // if (nShaderFlags2 & EF2_AFTERHDRPOSTPROCESS) // now it's branchless - { - uint32 predicate = nz2mask(nShaderFlags2 & EF2_AFTERHDRPOSTPROCESS); - - const uint32 mask = nz2mask(nShaderFlags2 & EF2_FORCE_DRAWLAST); - nList = iselmask(predicate, iselmask(mask, EFSLIST_AFTER_POSTPROCESS, EFSLIST_AFTER_HDRPOSTPROCESS), nList); - } - - if (nShaderFlags2 & EF2_AFTERPOSTPROCESS) - { - nList = EFSLIST_AFTER_POSTPROCESS; - } - - //if (nShaderFlags2 & EF2_FORCE_DRAWAFTERWATER) nAW = 1; -> branchless - nAW |= nz2one(nShaderFlags2 & EF2_FORCE_DRAWAFTERWATER); - - obj->m_fSort += fSort; -} - -/////////////////////////////////////////////////////////////////////////////// -#if !defined(NULL_RENDERER) -static void HandleOldRTMask(CRenderObject* obj) -{ - const uint64 objFlags = obj->m_ObjFlags; - obj->m_nRTMask = 0; - if (objFlags & (FOB_NEAREST | FOB_DECAL_TEXGEN_2D | FOB_DISSOLVE | FOB_GLOBAL_ILLUMINATION | FOB_SOFT_PARTICLE)) - { - if (objFlags & FOB_DECAL_TEXGEN_2D) - { - obj->m_nRTMask |= g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D]; - } - - if (objFlags & FOB_NEAREST) - { - obj->m_nRTMask |= g_HWSR_MaskBit[HWSR_NEAREST]; - } - - if (objFlags & FOB_DISSOLVE) - { - obj->m_nRTMask |= g_HWSR_MaskBit[HWSR_DISSOLVE]; - } - - if (objFlags & FOB_GLOBAL_ILLUMINATION) - { - obj->m_nRTMask |= g_HWSR_MaskBit[HWSR_GLOBAL_ILLUMINATION]; - } - - if (gRenDev->CV_r_ParticlesSoftIsec && (objFlags & FOB_SOFT_PARTICLE)) - { - obj->m_nRTMask |= g_HWSR_MaskBit[HWSR_SOFT_PARTICLE]; - } - } - - obj->m_ObjFlags |= FOB_UPDATED_RTMASK; -} -#endif - - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_AddEf_NotVirtual([[maybe_unused]] IRenderElement* re, [[maybe_unused]] SShaderItem& SH, [[maybe_unused]] CRenderObject* obj, [[maybe_unused]] const SRenderingPassInfo& passInfo, [[maybe_unused]] int nList, [[maybe_unused]] int nAW, [[maybe_unused]] const SRendItemSorter& rendItemSorter) -{ -#ifndef NULL_RENDERER - int nThreadID = passInfo.ThreadID(); - assert(nList > 0 && nList < EFSLIST_NUM); - - if (!re || !SH.m_pShader) - { - return; - } - - // shader item is not set up yet - if (SH.m_nPreprocessFlags == -1) - { - return; - } - - CShader* const __restrict pSH = (CShader*)SH.m_pShader; - const uint32 nShaderFlags = pSH->m_Flags; - if (nShaderFlags & EF_NODRAW) - { - return; - } - const uint32 nMaterialLayers = obj->m_nMaterialLayers; - - CShaderResources* const __restrict pShaderResources = (CShaderResources*)SH.m_pShaderResources; - // Need to differentiate between something rendered with cloak layer material, and sorted with cloak. - // e.g. ironsight glows on gun should be sorted with cloak to not write depth - can be inconsistent with no depth from gun. - - - // store AABBs for all FOB_NEAREST objects for r_DrawNearest - // TODO (bethelz) TRENDRIL: Remove draw nearest shadow hackery. - IF (CV_r_DrawNearShadows && obj->m_ObjFlags & FOB_NEAREST, 0) - { - if (IRenderNode* pRenderNode = static_cast(obj->m_pRenderNode)) - { - size_t nID = ~0; - CustomShadowMapFrustumData* pCustomShadowFrustumData = m_RP.m_arrCustomShadowMapFrustumData[nThreadID].push_back_new(nID); - // The local bounds already contain rotated so just apply translation to that - pRenderNode->GetLocalBounds(pCustomShadowFrustumData->aabb); - pCustomShadowFrustumData->aabb.min += obj->GetTranslation(); - pCustomShadowFrustumData->aabb.max += obj->GetTranslation(); - } - } - - if (passInfo.IsShadowPass()) - { - if (pSH->m_HWTechniques.Num() && pSH->m_HWTechniques[0]->m_nTechnique[TTYPE_SHADOWGEN] >= 0) - { - passInfo.GetRenderView()->AddRenderItem(re, obj, SH, EFSLIST_SHADOW_GEN, SG_SORT_GROUP, FB_GENERAL, passInfo, rendItemSorter); - } - return; - } - - // Discard 0 alpha blended geometry - this should be discarded earlier on 3dengine side preferably - if (fzero(obj->m_fAlpha)) - { - return; - } - if (pShaderResources && pShaderResources->::CShaderResources::IsInvisible()) - { - return; - } - - if (!(obj->m_ObjFlags & FOB_UPDATED_RTMASK)) - { - HandleOldRTMask(obj); - } - - uint32 nBatchFlags = EF_BatchFlags(SH, obj, re, passInfo); - - const uint32 nRenderlistsFlags = (FB_PREPROCESS | FB_TRANSPARENT); - if (nBatchFlags & nRenderlistsFlags) - { - if (nBatchFlags & FB_PREPROCESS) - { - EShaderType eSHType = pSH->GetShaderType(); - - // Prevent water usage on non-water specific meshes (it causes reflections updates). Todo: this should be checked in editor side and not allow such usage - if (eSHType != eST_Water || (eSHType == eST_Water && nList == EFSLIST_WATER)) - { - passInfo.GetRenderView()->AddRenderItem(re, obj, SH, EFSLIST_PREPROCESS, 0, nBatchFlags, passInfo, rendItemSorter); - } - } - - if ((nBatchFlags & FB_TRANSPARENT) && nList == EFSLIST_GENERAL) - { - // Refractive objects go into same list as transparent objects - partial resolves support - // arbitrary ordering between transparent and refractive correctly. - nList = EFSLIST_TRANSP; - } - } - - // FogVolume contribution for transparencies isn't needed when volumetric fog is turned on. - // TODO (bethelz) Not a great place for this. - if ((((nBatchFlags & FB_TRANSPARENT) || (pSH->GetFlags2() & EF2_HAIR)) && CRenderer::CV_r_VolumetricFog == 0) - || passInfo.IsRecursivePass() /* account for recursive scene traversal done in forward fashion*/) - { - // Check if we need high fog volume shading quality - static ICVar* pCVarFogVolumeShadingQuality = gEnv->pConsole->GetCVar("e_FogVolumeShadingQuality"); - bool fogVolumeShadingQuality = pShaderResources && (pShaderResources->GetResFlags() & MTL_FLAG_FOG_VOLUME_SHADING_QUALITY_HIGH) && (pCVarFogVolumeShadingQuality->GetIVal() > 0); - - - SRenderObjData* pOD = obj->GetObjData(); - if (pOD && ( fogVolumeShadingQuality || (pOD->m_FogVolumeContribIdx[nThreadID] == (uint16) - 1) ) ) - { - I3DEngine* pEng = gEnv->p3DEngine; - - SFogVolumeData fogVolData; - if (obj->m_pRenderNode) - { - // Pass the AABB of the object to in order to retrieve fog contribution. - pEng->TraceFogVolumes(obj->m_pRenderNode->GetBBox().GetCenter(), obj->m_pRenderNode->GetBBox(), fogVolData, passInfo, fogVolumeShadingQuality); - } - // TODO (bethelz) Decouple fog volume color from renderer. Just store in render obj data. - pOD->m_FogVolumeContribIdx[nThreadID] = CRenderer::PushFogVolumeContribution(fogVolData, passInfo); - } - } - - nBatchFlags &= ~(FB_Z & (nList ^ EFSLIST_GENERAL)); - - nList = (nBatchFlags & FB_SKIN) ? EFSLIST_SKIN : nList; - nList = (nBatchFlags & FB_EYE_OVERLAY) ? EFSLIST_EYE_OVERLAY : nList; - - if (pSH->GetShaderDrawType() == eSHDT_Fur) - { - nList = FurPasses::GetInstance().GetFurRenderList(); - nBatchFlags |= FB_FUR | FB_Z; - - // Opacity and emissive cause incorrect fur rendering, as transparency for shell passes - // is set up elsewhere. Override the material/objects settings for opacity and emissive. - nBatchFlags &= ~FB_TRANSPARENT; - pShaderResources->SetStrengthValue(EFTT_EMITTANCE, 0.0f); - pShaderResources->SetStrengthValue(EFTT_OPACITY, 1.0f); - obj->m_fAlpha = 1.0f; - - FurBendData::Get().SetupObject(*obj, passInfo); - } - - const uint32 nShaderFlags2 = pSH->m_Flags2; - const uint32 ObjDecalFlag = obj->m_ObjFlags & FOB_DECAL; - - // make sure decals go into proper render list - if ((ObjDecalFlag || (nShaderFlags & EF_DECAL))) - { - nBatchFlags |= FB_Z; - nList = EFSLIST_DECAL; - - if (ObjDecalFlag == 0 && pShaderResources) - { - obj->m_nSort = pShaderResources->m_SortPrio; - } - } - - // Enable tessellation for water geometry - obj->m_ObjFlags |= (pSH->m_Flags2 & EF2_HW_TESSELLATION && pSH->m_eShaderType == eST_Water) ? FOB_ALLOW_TESSELLATION : 0; - - const uint32 nForceFlags = (EF2_FORCE_DRAWLAST | EF2_FORCE_DRAWFIRST | EF2_FORCE_ZPASS | EF2_FORCE_TRANSPASS | EF2_FORCE_GENERALPASS | EF2_FORCE_DRAWAFTERWATER | EF2_FORCE_WATERPASS | EF2_AFTERHDRPOSTPROCESS | EF2_AFTERPOSTPROCESS); - - if (nShaderFlags2 & nForceFlags) - { - HandleForceFlags(nList, nAW, nBatchFlags, nShaderFlags, nShaderFlags2, obj); - } - - { - if (nShaderFlags & (EF_REFRACTIVE | EF_FORCEREFRACTIONUPDATE)) - { - SRenderObjData* pOD = EF_GetObjData(obj, CRenderer::CV_r_RefractionPartialResolves == 2, passInfo.ThreadID()); // Creating objData for objs without one - - if (obj->m_pRenderNode && pOD) - { - const int32 align16 = (16 - 1); - const int32 shift16 = 4; - if IsCVarConstAccess(constexpr) (bool(CRenderer::CV_r_RefractionPartialResolves)) - { - AABB aabb; - IRenderNode* pRenderNode = static_cast(obj->m_pRenderNode); - pRenderNode->FillBBox(aabb); - - int iOut[4]; - - passInfo.GetCamera().CalcScreenBounds(&iOut[0], &aabb, CRenderer::GetWidth(), CRenderer::GetHeight()); - pOD->m_screenBounds[0] = min(iOut[0] >> shift16, 255); - pOD->m_screenBounds[1] = min(iOut[1] >> shift16, 255); - pOD->m_screenBounds[2] = min((iOut[2] + align16) >> shift16, 255); - pOD->m_screenBounds[3] = min((iOut[3] + align16) >> shift16, 255); - -#if REFRACTION_PARTIAL_RESOLVE_DEBUG_VIEWS - if (CRenderer::CV_r_RefractionPartialResolvesDebug == eRPR_DEBUG_VIEW_3D_BOUNDS) - { - // Debug bounding box view for refraction partial resolves - IRenderAuxGeom* pAuxRenderer = gEnv->pRenderer->GetIRenderAuxGeom(); - if (pAuxRenderer) - { - SAuxGeomRenderFlags oldRenderFlags = pAuxRenderer->GetRenderFlags(); - - SAuxGeomRenderFlags newRenderFlags; - newRenderFlags.SetDepthTestFlag(e_DepthTestOff); - newRenderFlags.SetAlphaBlendMode(e_AlphaBlended); - pAuxRenderer->SetRenderFlags(newRenderFlags); - - const bool bSolid = true; - const ColorB solidColor(64, 64, 255, 64); - pAuxRenderer->DrawAABB(aabb, bSolid, solidColor, eBBD_Faceted); - - const ColorB wireframeColor(255, 0, 0, 255); - pAuxRenderer->DrawAABB(aabb, !bSolid, wireframeColor, eBBD_Faceted); - - // Set previous Aux render flags back again - pAuxRenderer->SetRenderFlags(oldRenderFlags); - } - } -#endif - } - else if (nShaderFlags & EF_FORCEREFRACTIONUPDATE) - { - pOD->m_screenBounds[0] = 0; - pOD->m_screenBounds[1] = 0; - pOD->m_screenBounds[2] = min((CRenderer::GetWidth()) >> shift16, 255); - pOD->m_screenBounds[3] = min((CRenderer::GetHeight()) >> shift16, 255); - } - } - } - - // final step, for post 3d items, remove them from any other list than POST_3D_RENDER - // (have to do this here as the batch needed to go through the normal nList assign path first) - nBatchFlags = iselmask(nz2mask(nBatchFlags & FB_POST_3D_RENDER), FB_POST_3D_RENDER, nBatchFlags); - - // No need to sort opaque passes by water/after water. Ensure always on same list for more coherent sorting - nAW |= nz2one((nList == EFSLIST_GENERAL) | (nList == EFSLIST_DECAL)); - m_RP.m_pRenderViews[nThreadID]->AddRenderItem(re, obj, SH, nList, nAW, nBatchFlags, passInfo, rendItemSorter); - } -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_AddEf (IRenderElement* re, SShaderItem& pSH, CRenderObject* obj, const SRenderingPassInfo& passInfo, int nList, int nAW, const SRendItemSorter& rendItemSorter) -{ - EF_AddEf_NotVirtual (re, pSH, obj, passInfo, nList, nAW, rendItemSorter); -} - -////////////////////////////////////////////////////////////////////////// -uint16 CRenderer::PushFogVolumeContribution(const SFogVolumeData& fogVolData, const SRenderingPassInfo& passInfo) -{ - int nThreadID = passInfo.ThreadID(); - - const size_t maxElems((1 << (sizeof(uint16) * 8)) - 1); - size_t numElems(m_RP.m_fogVolumeContibutionsData[nThreadID].size()); - assert(numElems < maxElems); - if (numElems >= maxElems) - { - return (uint16) - 1; - } - - size_t nIndex = ~0; - m_RP.m_fogVolumeContibutionsData[nThreadID].push_back(fogVolData, nIndex); - - return static_cast(nIndex); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::GetFogVolumeContribution(uint16 idx, SFogVolumeData& fogVolData ) const -{ - int nThreadID = m_RP.m_nProcessThreadID; - if (idx >= m_RP.m_fogVolumeContibutionsData[nThreadID].size()) - { - fogVolData.fogColor= ColorF(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - fogVolData = m_RP.m_fogVolumeContibutionsData[nThreadID][idx]; - } -} - -////////////////////////////////////////////////////////////////////////// -uint32 CRenderer::EF_BatchFlags(SShaderItem& SH, CRenderObject* pObj, [[maybe_unused]] IRenderElement* renderElement, const SRenderingPassInfo& passInfo) -{ - - uint32 nFlags = SH.m_nPreprocessFlags & FB_MASK; - SShaderTechnique* const __restrict pTech = SH.GetTechnique(); - CShaderResources* const __restrict pR = (CShaderResources*)SH.m_pShaderResources; - CShader* const __restrict pS = (CShader*)SH.m_pShader; - - float fAlpha = pObj->m_fAlpha; - uint32 uTransparent = (bool)(fAlpha < 1.0f); - const uint64 ObjFlags = pObj->m_ObjFlags; - - if (!passInfo.IsRecursivePass() && pTech) - { - CryPrefetch(pTech->m_nTechnique); - CryPrefetch(pR); - - //if (pObj->m_fAlpha < 1.0f) nFlags |= FB_TRANSPARENT; - nFlags |= FB_TRANSPARENT * uTransparent; - - if (!((nFlags & FB_Z) && (!(pObj->m_RState & OS_NODEPTH_WRITE) || (pS->m_Flags2 & EF2_FORCE_ZPASS)))) - { - nFlags &= ~FB_Z; - } - - if ((ObjFlags & FOB_DISSOLVE) || (ObjFlags & FOB_DECAL) || CRenderer::CV_r_usezpass != 2 || pObj->m_fDistance > CRenderer::CV_r_ZPrepassMaxDist) - { - nFlags &= ~FB_ZPREPASS; - } - - if (ObjFlags & FOB_RENDER_TRANS_AFTER_DOF) - { - nFlags |= FB_TRANSPARENT_AFTER_DOF; - } - - pObj->m_ObjFlags |= (nFlags & FB_ZPREPASS) ? FOB_ZPREPASS : 0; - - if (pTech->m_nTechnique[TTYPE_DEBUG] > 0 && 0 != (ObjFlags & FOB_SELECTED)) - { - nFlags |= FB_DEBUG; - } - - const uint32 nMaterialLayers = pObj->m_nMaterialLayers; - const uint32 DecalFlags = pS->m_Flags & EF_DECAL; - - if (passInfo.IsShadowPass()) - { - nFlags &= ~FB_PREPROCESS; - } - - nFlags &= ~(FB_PREPROCESS & uTransparent); - - AZ_PUSH_DISABLE_WARNING(, "-Wconstant-logical-operand") - if ((nMaterialLayers & ~uTransparent) && CV_r_usemateriallayers) - AZ_POP_DISABLE_WARNING - { - const uint32 nResourcesNoDrawFlags = static_cast(pR)->CShaderResources::GetMtlLayerNoDrawFlags(); - - // if ((nMaterialLayers & MTL_LAYER_BLEND_DYNAMICFROZEN) && !(nResourcesNoDrawFlags & MTL_LAYER_FROZEN)) - uint32 uMask = mask_nz_zr(nMaterialLayers & MTL_LAYER_BLEND_DYNAMICFROZEN, nResourcesNoDrawFlags & MTL_LAYER_FROZEN); - nFlags |= FB_MULTILAYERS & uMask; - } - - if (pTech->m_nTechnique[TTYPE_MOTIONBLURPASS] > 0 && CV_r_MotionVectors && CV_r_MotionVectorsTransparency) - { - // Combine material and runtime opacity. - const float opacity = pR->GetStrengthValue(EFTT_OPACITY) * fAlpha; - const bool isNotADecal = ((ObjFlags & FOB_DECAL) | DecalFlags) == 0; - const bool isAboveAlphaThreshold = opacity >= CV_r_MotionVectorsTransparencyAlphaThreshold; - - // We do not want to generate motion for decals, since they adhere to surfaces. - if (isNotADecal && isAboveAlphaThreshold) - { - nFlags |= FB_MOTIONBLUR; - } - } - - SRenderObjData* pOD = pObj->GetObjData(); - if (pTech->m_nTechnique[TTYPE_CUSTOMRENDERPASS] > 0) - { - const uint32 customvisions = CRenderer::CV_r_customvisions; - const uint32 nHUDSilhouettesParams = (pOD && pOD->m_nHUDSilhouetteParams); - if (customvisions && nHUDSilhouettesParams) - { - nFlags |= FB_CUSTOM_RENDER; - } - } - } - else - if (passInfo.IsRecursivePass() && pTech && m_RP.m_TI[passInfo.ThreadID()].m_PersFlags & RBPF_MIRRORCAMERA) - { - nFlags &= (FB_TRANSPARENT | FB_GENERAL); - nFlags |= FB_TRANSPARENT * uTransparent; // if (pObj->m_fAlpha < 1.0f) nFlags |= FB_TRANSPARENT; - } - - { - //if ( (objFlags & FOB_ONLY_Z_PASS) || CV_r_ZPassOnly) && !(nFlags & (FB_TRANSPARENT))) - put it to the mask - const uint32 mask = mask_nz_zr((uint32)CV_r_ZPassOnly, nFlags & (FB_TRANSPARENT)); - - nFlags = iselmask(mask, FB_Z, nFlags); - } - - int nShaderFlags = (SH.m_pShader ? SH.m_pShader->GetFlags() : 0); - if ((CRenderer::CV_r_RefractionPartialResolves && nShaderFlags & EF_REFRACTIVE) || (nShaderFlags & EF_FORCEREFRACTIONUPDATE)) - { - pObj->m_ObjFlags |= FOB_REQUIRES_RESOLVE; - } - - return nFlags; -} - -/////////////////////////////////////////////////////////////////////////////// -SRenderObjData* CRenderer::EF_GetObjData(CRenderObject* pObj, [[maybe_unused]] bool bCreate, [[maybe_unused]] int nThreadID) -{ - return pObj->GetObjData(); -} - -/////////////////////////////////////////////////////////////////////////////// -SRenderObjData* CRenderer::FX_GetObjData(CRenderObject* pObj, [[maybe_unused]] int nThreadID) -{ - return pObj->GetObjData(); -} -/////////////////////////////////////////////////////////////////////////////// -CRenderObject* CRenderer::EF_GetObject_Temp(int nThreadID) -{ - CThreadSafeWorkerContainer & Objs = m_RP.m_TempObjects[nThreadID]; - - size_t nId = ~0; - CRenderObject** ppObj = Objs.push_back_new(nId); - CRenderObject* pObj = NULL; - - if (*ppObj == NULL) - { - *ppObj = aznew CRenderObject(); - } - pObj = *ppObj; - - - pObj->AssignId(nId); - pObj->Init(); - return pObj; -} - -/////////////////////////////////////////////////////////////////////////////// -CRenderObject* CRenderer::EF_DuplicateRO(CRenderObject* pObj, const SRenderingPassInfo& passInfo) -{ - CRenderObject* pObjNew = CRenderer::EF_GetObject_Temp(passInfo.ThreadID()); - pObjNew->CloneObject(pObj); - return pObjNew; -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeRendItems_ReorderShadowRendItems([[maybe_unused]] int nThreadID) -{ -#ifndef NULL_RENDERER - //////////////////////////////////////////////// - // shadow rend items - auto& rShadowRI = CRenderView::GetRenderViewForThread(nThreadID)->GetRenderItems(SG_SORT_GROUP, EFSLIST_SHADOW_GEN); - size_t nShadowRISize = rShadowRI.size(); - if (nShadowRISize) - { - SRendItem* pShadowRI = &rShadowRI[0]; - std::sort(pShadowRI, pShadowRI + nShadowRISize, SCompareByShadowFrustumID()); - - int nCurrentShadowRecur = 0; - for (size_t i = 0; i < nShadowRISize; ++i) - { - if (rShadowRI[i].rendItemSorter.ShadowFrustumID() != nCurrentShadowRecur) - { - assert(nCurrentShadowRecur < MAX_SHADOWMAP_FRUSTUMS); - SRendItem::m_ShadowsEndRI[nThreadID][nCurrentShadowRecur] = i; - SRendItem::m_ShadowsStartRI[nThreadID][rShadowRI[i].rendItemSorter.ShadowFrustumID()] = i; - - nCurrentShadowRecur = rShadowRI[i].rendItemSorter.ShadowFrustumID(); - } - } - - assert(nCurrentShadowRecur < MAX_SHADOWMAP_FRUSTUMS); - SRendItem::m_ShadowsEndRI[nThreadID][nCurrentShadowRecur] = nShadowRISize; - } -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeRendItems_FindShadowFrustums(int nThreadID) -{ - //////////////////////////////////////////////// - // shadow frustums - for (int nRecursionLevel = 0; nRecursionLevel < MAX_REND_RECURSION_LEVELS; ++nRecursionLevel) - { - m_RP.m_SMFrustums[nThreadID][nRecursionLevel].SetUse(0); - m_RP.m_SMCustomFrustumIDs[nThreadID][nRecursionLevel].SetUse(0); - } - - if (m_RP.SShadowFrustumToRenderList[nThreadID].size()) - { - std::sort(m_RP.SShadowFrustumToRenderList[nThreadID].begin(), m_RP.SShadowFrustumToRenderList[nThreadID].end(), SCompareByLightIds()); - - int nCurrentLightId = m_RP.SShadowFrustumToRenderList[nThreadID][0].nLightID; - int nCurRecusiveLevel = m_RP.SShadowFrustumToRenderList[nThreadID][0].nRecursiveLevel; - SRendItem::m_StartFrust[nThreadID][nCurrentLightId] = m_RP.m_SMFrustums[nThreadID][nCurRecusiveLevel].Num(); - for (int i = 0; i < (int)m_RP.SShadowFrustumToRenderList[nThreadID].size(); ++i) - { - SRenderPipeline::SShadowFrustumToRender& rToRender = m_RP.SShadowFrustumToRenderList[nThreadID][i]; - if (rToRender.pFrustum->nShadowGenMask != 0) - { - ShadowMapFrustum* pCopyFrustumTo = m_RP.m_SMFrustums[nThreadID][rToRender.nRecursiveLevel].AddIndex(1); - memcpy(pCopyFrustumTo, rToRender.pFrustum, sizeof(ShadowMapFrustum)); - - const int nFrustumIndex = m_RP.m_SMFrustums[nThreadID][nCurRecusiveLevel].Num() - 1; - // put shadow frustum into right ligh id group - if (rToRender.pFrustum->m_eFrustumType != ShadowMapFrustum::e_PerObject && rToRender.pFrustum->m_eFrustumType != ShadowMapFrustum::e_Nearest) - { - if (rToRender.nLightID != nCurrentLightId) - { - SRendItem::m_EndFrust[nThreadID][nCurrentLightId] = nFrustumIndex; - SRendItem::m_StartFrust[nThreadID][rToRender.nLightID] = nFrustumIndex; - - nCurrentLightId = rToRender.nLightID; - nCurRecusiveLevel = rToRender.nRecursiveLevel; - } - } - else - { - m_RP.m_SMCustomFrustumIDs[nThreadID][rToRender.nRecursiveLevel].Add(nFrustumIndex); - } - } - } - - // Store the end index to use when iterating over the shadow frustums. - SRendItem::m_EndFrust[nThreadID][nCurrentLightId] = m_RP.m_SMFrustums[nThreadID][nCurRecusiveLevel].Num(); - m_RP.SShadowFrustumToRenderList[nThreadID].SetUse(0); - } -} - -/////////////////////////////////////////////////////////////////////////////// -AZ::LegacyJobExecutor* CRenderer::GetGenerateRendItemJobExecutor() -{ - return &m_generateRendItemJobExecutor; -} - -/////////////////////////////////////////////////////////////////////////////// -AZ::LegacyJobExecutor* CRenderer::GetGenerateShadowRendItemJobExecutor() -{ - return &m_generateShadowRendItemJobExecutor; -} - -/////////////////////////////////////////////////////////////////////////////// -AZ::LegacyJobExecutor* CRenderer::GetGenerateRendItemJobExecutorPreProcess() -{ - return &m_generateRendItemPreProcessJobExecutor; -} - -/////////////////////////////////////////////////////////////////////////////// -AZ::LegacyJobExecutor* CRenderer::GetFinalizeRendItemJobExecutor(int nThreadID) -{ - return &m_finalizeRendItemsJobExecutor[nThreadID]; -} - -/////////////////////////////////////////////////////////////////////////////// -AZ::LegacyJobExecutor* CRenderer::GetFinalizeShadowRendItemJobExecutor(int nThreadID) -{ - return &m_finalizeShadowRendItemsJobExecutor[nThreadID]; -} - -////////////////////////////////////////////////////////////////////////// -// IShaderPublicParams implementation class. -////////////////////////////////////////////////////////////////////////// - -struct CShaderPublicParams - : public IShaderPublicParams -{ - CShaderPublicParams() - { - m_nRefCount = 0; - } - - virtual void AddRef() { m_nRefCount++; }; - virtual void Release() - { - if (--m_nRefCount <= 0) - { - delete this; - } - }; - - virtual void SetParamCount(int nParam) { m_shaderParams.resize(nParam); } - virtual int GetParamCount() const { return m_shaderParams.size(); }; - - virtual SShaderParam& GetParam(int nIndex) - { - assert(nIndex >= 0 && nIndex < (int)m_shaderParams.size()); - return m_shaderParams[nIndex]; - } - - virtual const SShaderParam& GetParam(int nIndex) const - { - assert(nIndex >= 0 && nIndex < (int)m_shaderParams.size()); - return m_shaderParams[nIndex]; - } - - virtual SShaderParam* GetParamByName(const char* pszName) - { - for (int32 i = 0; i < m_shaderParams.size(); i++) - { - if (azstricmp(pszName, m_shaderParams[i].m_Name.c_str()) == 0) - { - return &m_shaderParams[i]; - } - } - - return 0; - } - - virtual const SShaderParam* GetParamByName(const char* pszName) const - { - for (int32 i = 0; i < m_shaderParams.size(); i++) - { - if (azstricmp(pszName, m_shaderParams[i].m_Name.c_str()) == 0) - { - return &m_shaderParams[i]; - } - } - - return 0; - } - - virtual SShaderParam* GetParamBySemantic(uint8 eParamSemantic) - { - for (int i = 0; i < m_shaderParams.size(); ++i) - { - if (m_shaderParams[i].m_eSemantic == eParamSemantic) - { - return &m_shaderParams[i]; - } - } - - return NULL; - } - - - virtual const SShaderParam* GetParamBySemantic(uint8 eParamSemantic) const - { - for (int i = 0; i < m_shaderParams.size(); ++i) - { - if (m_shaderParams[i].m_eSemantic == eParamSemantic) - { - return &m_shaderParams[i]; - } - } - - return NULL; - } - - virtual void SetParam(int nIndex, const SShaderParam& param) - { - assert(nIndex >= 0 && nIndex < (int)m_shaderParams.size()); - - m_shaderParams[nIndex] = param; - } - - virtual void AddParam(const SShaderParam& param) - { - // shouldn't add existing parameter ? - m_shaderParams.push_back(param); - } - - virtual void RemoveParamByName(const char* pszName) - { - for (int32 i = 0; i < m_shaderParams.size(); i++) - { - if (azstricmp(pszName, m_shaderParams[i].m_Name.c_str()) == 0) - { - m_shaderParams.erase(m_shaderParams.begin() + i); - } - } - } - - virtual void RemoveParamBySemantic(uint8 eParamSemantic) - { - for (int i = 0; i < m_shaderParams.size(); ++i) - { - if (eParamSemantic == m_shaderParams[i].m_eSemantic) - { - m_shaderParams.erase(m_shaderParams.begin() + i); - } - } - } - - virtual void SetParam(const char* pszName, UParamVal& pParam, EParamType nType = eType_FLOAT, uint8 eSemantic = 0) - { - int32 i; - - for (i = 0; i < m_shaderParams.size(); i++) - { - if (azstricmp(pszName, m_shaderParams[i].m_Name.c_str()) == 0) - { - break; - } - } - - if (i == m_shaderParams.size()) - { - SShaderParam pr; - pr.m_Name = pszName; - pr.m_Type = nType; - pr.m_eSemantic = eSemantic; - m_shaderParams.push_back(pr); - } - - SShaderParam::SetParam(pszName, &m_shaderParams, pParam); - } - - virtual void SetShaderParams(const AZStd::vector& pParams) - { - m_shaderParams = pParams; - } - - virtual void AssignToRenderParams(struct SRendParams& rParams) - { - if (!m_shaderParams.empty()) - { - rParams.pShaderParams = &m_shaderParams; - } - } - - virtual AZStd::vector* GetShaderParams() - { - if (m_shaderParams.empty()) - { - return 0; - } - - return &m_shaderParams; - } - - virtual const AZStd::vector* GetShaderParams() const - { - if (m_shaderParams.empty()) - { - return 0; - } - - return &m_shaderParams; - } - - virtual uint8 GetSemanticByName(const char* szName) - { - static_assert(ECGP_COUNT <= 0xff, "8 bits are not enough to store all ECGParam values"); - - if (strcmp(szName, "WrinkleMask0") == 0) - { - return ECGP_PI_WrinklesMask0; - } - if (strcmp(szName, "WrinkleMask1") == 0) - { - return ECGP_PI_WrinklesMask1; - } - if (strcmp(szName, "WrinkleMask2") == 0) - { - return ECGP_PI_WrinklesMask2; - } - - return ECGP_Unknown; - } - -private: - int m_nRefCount; - AZStd::vector m_shaderParams; -}; - -////////////////////////////////////////////////////////////////////////// -IShaderPublicParams* CRenderer::CreateShaderPublicParams() -{ - return new CShaderPublicParams; -} - -void CMotionBlur::SetupObject(CRenderObject* renderObject, const SRenderingPassInfo& passInfo) -{ - assert(renderObject); - - uint32 fillThreadId = passInfo.ThreadID(); - - if (passInfo.IsRecursivePass()) - { - return; - } - - SRenderObjData* const __restrict renderObjectData = renderObject->GetObjData(); - if (!renderObjectData) - { - return; - } - - renderObject->m_ObjFlags &= ~FOB_HAS_PREVMATRIX; - if (renderObjectData->m_uniqueObjectId != 0 && renderObject->m_fDistance < CRenderer::CV_r_MotionBlurMaxViewDist) - { - const AZ::u32 currentFrameId = passInfo.GetMainFrameID(); - const AZ::u32 bufferIndex = (currentFrameId) % CMotionBlur::s_maxObjectBuffers; - const uintptr_t objectId = renderObjectData ? renderObjectData->m_uniqueObjectId : 0; - if (!m_Objects[bufferIndex]) - { - return; - } - - auto currentIt = m_Objects[bufferIndex]->find(objectId); - if (currentIt != m_Objects[bufferIndex]->end()) - { - const AZ::u32 lastBufferIndex = (currentFrameId - 1) % CMotionBlur::s_maxObjectBuffers; - - auto historyIt = m_Objects[lastBufferIndex]->find(objectId); - if (historyIt != m_Objects[lastBufferIndex]->end()) - { - MotionBlurObjectParameters* currentParameters = ¤tIt->second; - MotionBlurObjectParameters* historyParameters = &historyIt->second; - currentParameters->m_worldMatrix = renderObject->m_II.m_Matrix; - - const float fThreshold = CRenderer::CV_r_MotionBlurThreshold; - if (renderObject->m_ObjFlags & (FOB_NEAREST | FOB_MOTION_BLUR) || - !Matrix34::IsEquivalent(historyParameters->m_worldMatrix, currentParameters->m_worldMatrix, fThreshold)) - { - renderObject->m_ObjFlags |= FOB_HAS_PREVMATRIX; - } - - currentParameters->m_updateFrameId = currentFrameId; - currentParameters->m_renderObject = renderObject; - return; - } - } - - m_FillData[fillThreadId].push_back(ObjectMap::value_type(objectId, MotionBlurObjectParameters(renderObject, renderObject->m_II.m_Matrix, currentFrameId))); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -void SRendItem::mfSortPreprocess(SRendItem* First, int Num) -{ - std::sort(First, First + Num, SCompareItemPreprocess()); -} - -////////////////////////////////////////////////////////////////////////// -void SRendItem::mfSortForZPass(SRendItem* First, int Num) -{ - std::sort(First, First + Num, SCompareRendItemZPass()); -} - -////////////////////////////////////////////////////////////////////////// -void SRendItem::mfSortByLight(SRendItem* First, int Num, bool bSort, const bool bIgnoreRePtr, bool bSortDecals) -{ - if (bSort) - { - if (bIgnoreRePtr) - { - std::sort(First, First + Num, SCompareItem_TerrainLayers()); - } - else - { - if (bSortDecals) - { - std::sort(First, First + Num, SCompareItem_Decal()); - } - else - { - std::sort(First, First + Num, SCompareRendItem()); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void SRendItem::mfSortByDist(SRendItem* First, int Num, bool bDecals, bool InvertedOrder) -{ - //Note: Temporary use stable sort for flickering hair (meshes within the same skin attachment don't have a deterministic sort order) - int i; - if (!bDecals) - { - //Pre-pass to bring in the first 8 entries. 8 cache requests can be in flight - const int iPrefetchLoopLastIndex = min_branchless(8, Num); - for (i = 0; i < iPrefetchLoopLastIndex; i++) - { - //It's safe to prefetch NULL - PrefetchLine(First[i].pObj, offsetof(CRenderObject, m_fSort)); - } - - const int iLastValidIndex = Num - 1; - - //Note: this seems like quite a bit of work to do some prefetching but this code was generating a - // level 2 cache miss per iteration of the loop - Rich S - for (i = 0; i < Num; i++) - { - SRendItem* pRI = &First[i]; - int iPrefetchIndex = min_branchless(i + 8, iLastValidIndex); - PrefetchLine(First[iPrefetchIndex].pObj, offsetof(CRenderObject, m_fSort)); - CRenderObject* pObj = pRI->pObj; // no need to flush, data is only read - assert(pObj); - - // We're prefetching on m_fSort, we're still getting some L2 cache misses on access to m_fDistance, - // but moving them closer in memory is complicated due to an aligned array that's nestled in there... - float fAddDist = pObj->m_fSort; - pRI->fDist = pObj->m_fDistance + fAddDist; - } - - - if (InvertedOrder) - { - std::stable_sort(First, First + Num, SCompareDistInverted()); - } - else - { - std::stable_sort(First, First + Num, SCompareDist()); - } - } - else - { - std::stable_sort(First, First + Num, SCompareItem_Decal()); - } -} - -int16 CTexture::StreamCalculateMipsSignedFP(float fMipFactor) const -{ - assert(IsStreamed()); - const uint32 nMaxExtent = max(m_nWidth, m_nHeight); - float currentMipFactor = fMipFactor * nMaxExtent * nMaxExtent * gRenDev->GetMipDistFactor(); - float fMip = (0.5f * logf(max(currentMipFactor, 0.1f)) / LN2 + (CRenderer::CV_r_TexturesStreamingMipBias + gRenDev->m_fTexturesStreamingGlobalMipFactor)); - int nMip = static_cast(floorf(fMip * 256.0f)); - const int nNewMip = min(nMip, (m_nMips - m_CacheFileHeader.m_nMipsPersistent) << 8); - return (int16)nNewMip; -} - -float CTexture::StreamCalculateMipFactor(int16 nMipsSigned) const -{ - float fMip = nMipsSigned / 256.0f; - float currentMipFactor = expf((fMip - (CRenderer::CV_r_TexturesStreamingMipBias + gRenDev->m_fTexturesStreamingGlobalMipFactor)) * 2.0f * LN2); - - const uint32 nMaxExtent = max(m_nWidth, m_nHeight); - float fMipFactor = currentMipFactor / (nMaxExtent * nMaxExtent * gRenDev->GetMipDistFactor()); - - return fMipFactor; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - diff --git a/Code/CryEngine/RenderDll/Common/ResFile.cpp b/Code/CryEngine/RenderDll/Common/ResFile.cpp deleted file mode 100644 index 64ce7e7f06..0000000000 --- a/Code/CryEngine/RenderDll/Common/ResFile.cpp +++ /dev/null @@ -1,2044 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : implementation file - - -#include "RenderDll_precompiled.h" -#include "ResFile.h" -#include "Pak/CryPakUtils.h" - -CResFile CResFile::m_Root(nullptr); -CResFile CResFile::m_RootStream(nullptr); -int CResFile::m_nNumOpenResources = 0; -uint32 CResFile::m_nSizeComprDir; -uint32 CResFile::m_nMaxOpenResFiles = MAX_OPEN_RESFILES; - -namespace -{ - CryCriticalSection g_cResLock; - CryCriticalSection g_cAsyncResLock; -} - -bool CResFile::IsStreaming() -{ - if (m_RootStream.m_NextStream && - m_RootStream.m_NextStream != m_RootStream.m_PrevStream) - { - return true; - } - - return false; -} - -// Directory garbage collector (must be executed in render thread) -void CResFile::Tick() -{ - if (!m_RootStream.m_NextStream) - { - m_RootStream.m_NextStream = &m_RootStream; - m_RootStream.m_PrevStream = &m_RootStream; - } - //return; - - AUTO_LOCK(g_cAsyncResLock); - - int nCurFrame = gRenDev->m_nFrameSwapID; - uint32 nFrameDif = 300; // Release the directories in 300 frames (approx 10 secs) - CResFile* pRF, * pNext; - for (pRF = m_RootStream.m_PrevStream; pRF != &m_RootStream; pRF = pNext) - { - pNext = pRF->m_PrevStream; - assert(pRF->m_pStreamInfo); - if (!pRF->m_pStreamInfo) - { - pRF->UnlinkStream(); - continue; - } - if (pRF->m_bDirStreaming || pRF->m_pStreamInfo->m_EntriesQueue.size()) - { - continue; // Still streaming - } - if (nCurFrame - pRF->m_nLastTickStreamed > nFrameDif) - { - pRF->UnlinkStream(); - pRF->mfReleaseDir(); - } - } -} - -void CResFile::mfTickStreaming() -{ - m_nLastTickStreamed = gRenDev->m_nFrameSwapID; - UnlinkStream(); - LinkStream(&m_RootStream); -} - -void CResFile::mfDeactivate([[maybe_unused]] bool bReleaseDir) -{ - AUTO_LOCK(g_cResLock); // Not thread safe without this - - if (m_fileHandle != AZ::IO::InvalidHandle) - { - mfFlush(); - gEnv->pCryPak->FClose(m_fileHandle); - m_fileHandle = AZ::IO::InvalidHandle; - } - - if (m_bActive) - { - m_nNumOpenResources--; - } - m_bActive = false; - - Unlink(); -} - -bool CResFile::mfActivate(bool bFirstTime) -{ - AUTO_LOCK(g_cResLock); // Not thread safe without this - - if (!m_bActive) - { - Relink(&m_Root); - if (m_nNumOpenResources >= (int)m_nMaxOpenResFiles) - { - if (m_nNumOpenResources) - { - CResFile* rf = m_Root.m_Prev; - assert(rf && (rf->m_fileHandle != AZ::IO::InvalidHandle || m_pStreamInfo)); - rf->mfDeactivate(false); - } - } - - LOADING_TIME_PROFILE_SECTION(iSystem); - CDebugAllowFileAccess dafa; - - int nFlags = !m_pLookupDataMan || m_pLookupDataMan->IsReadOnly() ? 0 : AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK; - - // don't open the file if we are trying to stream the data, defeats the idea of streaming it - if (!m_pStreamInfo) - { - if (!bFirstTime && m_szAccess[0] == 'w') - { - char szAcc[16]; - azstrcpy(szAcc, AZ_ARRAY_SIZE(szAcc), m_szAccess); - szAcc[0] = 'r'; - m_fileHandle = gEnv->pCryPak->FOpen(m_name.c_str(), szAcc, nFlags | AZ::IO::IArchive::FOPEN_HINT_DIRECT_OPERATION); - } - else - { - m_fileHandle = gEnv->pCryPak->FOpen(m_name.c_str(), m_szAccess, nFlags | AZ::IO::IArchive::FOPEN_HINT_DIRECT_OPERATION); - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("CResFile::Activate - Can't open resource file <%s>", m_name.c_str()); - Unlink(); - return false; - } - } - - m_nNumOpenResources++; - m_bActive = true; - } - if (!bFirstTime && !m_bDirValid) - { - mfPrepareDir(); - } - - return true; -} - -CResFile::CResFile(const char* name) -{ - m_name = name; - m_fileHandle = AZ::IO::InvalidHandle; - m_bActive = false; - m_nOffsDir = 0; - m_bSwapEndianRead = false; - m_bSwapEndianWrite = false; - m_pLookupData = NULL; - m_pLookupDataMan = NULL; - - m_Next = m_Prev = NULL; - m_NextStream = m_PrevStream = NULL; - m_pStreamInfo = NULL; - m_bDirty = false; - m_bDirValid = false; - m_bDirCompressed = false; - m_bDirStreaming = false; - m_pCompressedDir = NULL; - m_nComprDirSize = 0; - m_nNumFilesUnique = 0; - m_nNumFilesRef = 0; - m_bDirCompressed = false; - m_nOffset = OFFSET_BIG_POSITIVE; - - // If the root hasn't been set up before and this isn't a statically created - // CResFile (like the root/root stream), then lazy init the resource list - if (!m_Root.m_Next && name) - { - m_Root.m_name = "Root"; - m_RootStream.m_name = "RootStream"; - m_Root.m_Next = &m_Root; - m_Root.m_Prev = &m_Root; - m_RootStream.m_NextStream = &m_RootStream; - m_RootStream.m_PrevStream = &m_RootStream; - } -} - -CResFile::~CResFile() -{ - if (this != &m_Root && this != &m_RootStream) - { - mfClose(); - } - else - { - assert(CResFile::m_nNumOpenResources == 0); - } -} - -void CResFile::mfSetError(const char* er, ...) -{ - char buffer[1024]; - va_list args; - va_start(args, er); - if (azvsnprintf(buffer, sizeof(buffer), er, args) == -1) - { - buffer[sizeof(buffer) - 1] = 0; - } - m_ermes = buffer; - va_end(args); -} - -SResFileLookupData* CResFile::GetLookupData(bool bCreate, uint32 CRC, float fVersion) const -{ - if (m_pLookupDataMan) - { - CCryNameTSCRC name = m_pLookupDataMan->AdjustName(m_name.c_str()); - SResFileLookupData* pData = m_pLookupDataMan->GetData(name); - uint32 nMinor = (int)(((float)fVersion - (float)(int)fVersion) * 10.1f); - uint32 nMajor = (int)fVersion; - - if (bCreate && (!pData || (CRC && pData->m_CRC32 != CRC) || pData->m_CacheMinorVer != nMinor || pData->m_CacheMajorVer != nMajor || pData->m_OffsetDir != m_nOffsDir || pData->m_NumOfFilesUnique != m_nNumFilesUnique || pData->m_NumOfFilesRef != m_nNumFilesRef)) - { - m_pLookupDataMan->AddData(this, CRC); - pData = m_pLookupDataMan->GetData(name); - m_pLookupDataMan->MarkDirty(true); - assert(pData); - } - - return pData; - } - - return NULL; -} - -const char* CResFile::mfGetError(void) -{ - if (m_ermes.size()) - { - return m_ermes.c_str(); - } - else - { - return NULL; - } -} - -int CResFile::mfGetResourceSize() -{ - if (m_fileHandle == AZ::IO::InvalidHandle) - { - return 0; - } - - AUTO_LOCK(g_cResLock); // Not thread safe without this - - gEnv->pCryPak->FSeek(m_fileHandle, 0, SEEK_END); - uint64_t length = gEnv->pCryPak->FTell(m_fileHandle); - gEnv->pCryPak->FSeek(m_fileHandle, 0, SEEK_SET); - - return aznumeric_cast(length); -} - -uint64 CResFile::mfGetModifTime() -{ - if (!mfActivate(false)) - { - return 0; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - return 0; - } - - return gEnv->pCryPak->GetModificationTime(m_fileHandle); -} - -bool CResFile::mfFileExist(CCryNameTSCRC name) -{ - SDirEntry* de = mfGetEntry(name); - if (!de) - { - return false; - } - assert(name == de->Name); - return true; -} - -bool CResFile::mfFileExist(const char* name) -{ - return mfFileExist(CCryNameTSCRC(name)); -} - -void CResStreamDirCallback::StreamAsyncOnComplete([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) -{ - /* - SResStreamInfo *pStreamInfo = (SResStreamInfo*)pStream->GetUserData(); - assert(pStreamInfo); - if (!pStreamInfo) - return; - SShaderCache *pCache = pStreamInfo->m_pCache; - CResFile *pRes = pStreamInfo->m_pRes; - IF(!pRes,0)return; - assert(pRes->m_bDirStreaming); - - if (nError == ) - pStreamInfo->m_nRequestCount--; - - // are all requests processed ? - if (pStreamInfo->m_nRequestCount == 0) - { - // check if both requests were valid ! - pRes->m_bDirValid = true; - } - */ -} - -void CResStreamDirCallback::StreamOnComplete(IReadStream* pStream, unsigned nError) -{ - SResStreamInfo* pStreamInfo = (SResStreamInfo*)pStream->GetUserData(); - assert(pStreamInfo); - if (!pStreamInfo) - { - return; - } - - CryAutoLock lock(pStreamInfo->m_StreamLock); - - CResFile* pRes = pStreamInfo->m_pRes; - IF (!pRes, 0) - { - return; - } - assert(pRes->m_bDirStreaming); - - if (!nError) - { - pStreamInfo->m_nDirRequestCount--; - } - - for (std::vector::iterator it = pStreamInfo->m_dirReadStreams.begin(); - it != pStreamInfo->m_dirReadStreams.end(); ++it) - { - if (pStream == *it) - { - pStreamInfo->m_dirReadStreams.erase(it); - break; - } - } - - // all requests processed ? - if (pStreamInfo->m_dirReadStreams.size() == 0) - { - // were all requests processed successfully - if (pStreamInfo->m_nDirRequestCount == 0) - { - // check if both requests were valid ! - pRes->m_bDirValid = true; - } - - pRes->m_bDirStreaming = false; - } - - SShaderCache* pCache = pStreamInfo->m_pCache; - pCache->Release(); -} - -int CResFile::mfLoadDir(SResStreamInfo* pStreamInfo) -{ - int nRes = 1; - if (pStreamInfo) - { - // if we are streaming the data, we need the lookup data to be valid! - if (m_pLookupData == NULL) - { - return -1; - } - - mfTickStreaming(); - if (m_bDirStreaming) - { - return -1; - } - m_bDirStreaming = true; - - int nSizeDir = m_nNumFilesUnique * sizeof(SDirEntry); - int nSizeDirRef = m_nNumFilesRef * sizeof(SDirEntry); - - if (nSizeDir) - { - m_Dir.resize(m_nNumFilesUnique); - - StreamReadParams StrParams; - StrParams.nFlags = 0; - StrParams.dwUserData = (DWORD_PTR)pStreamInfo; - StrParams.nLoadTime = 1; - StrParams.nMaxLoadTime = 4; - StrParams.pBuffer = &m_Dir[0]; - StrParams.nOffset = m_nOffsDir; - StrParams.nSize = nSizeDir; - pStreamInfo->m_pCache->AddRef(); - - CryAutoLock lock(pStreamInfo->m_StreamLock); - pStreamInfo->m_dirReadStreams.push_back(iSystem->GetStreamEngine()->StartRead( - eStreamTaskTypeShader, m_name.c_str(), &pStreamInfo->m_CallbackDir, &StrParams)); - pStreamInfo->m_nDirRequestCount++; - } - - if (nSizeDirRef) - { - m_DirRef.resize(m_nNumFilesRef); - - StreamReadParams StrParams; - StrParams.nFlags = 0; - StrParams.dwUserData = (DWORD_PTR)pStreamInfo; - StrParams.nLoadTime = 1; - StrParams.nMaxLoadTime = 4; - StrParams.pBuffer = &m_DirRef[0]; - StrParams.nOffset = m_nOffsDir + nSizeDir; - StrParams.nSize = nSizeDirRef; - pStreamInfo->m_pCache->AddRef(); - - CryAutoLock lock(pStreamInfo->m_StreamLock); - pStreamInfo->m_dirReadStreams.push_back(iSystem->GetStreamEngine()->StartRead( - eStreamTaskTypeShader, m_name.c_str(), &pStreamInfo->m_CallbackDir, &StrParams)); - pStreamInfo->m_nDirRequestCount++; - } - - nRes = -1; - } - else - { - if (gEnv->pCryPak->FSeek(m_fileHandle, m_nOffsDir, SEEK_SET) > 0) - { - mfSetError("Open - Directory reading error"); - return 0; - } - - int nSize = m_nNumFilesUnique * sizeof(SDirEntry); - //int nSizeDir = m_nComprDirSize ? m_nComprDirSize : nSize; - if (m_nNumFilesUnique) - { - m_Dir.resize(m_nNumFilesUnique); - if (gEnv->pCryPak->FReadRaw(&m_Dir[0], 1, nSize, m_fileHandle) != nSize) - { - mfSetError("Open - Directory reading error"); - m_Dir.clear(); - return 0; - } - } - - if (m_nNumFilesRef) - { - nSize = m_nNumFilesRef * sizeof(SDirEntryRef); - //int nSizeDir = m_nComprDirSize ? m_nComprDirSize : nSize; - m_DirRef.resize(m_nNumFilesRef); - if (gEnv->pCryPak->FReadRaw(&m_DirRef[0], 1, nSize, m_fileHandle) != nSize) - { - mfSetError("Open - Directory reading error"); - m_DirRef.clear(); - return 0; - } - } - } - m_bDirValid = false; - if (!m_nComprDirSize && nRes == 1) - { - m_bDirValid = true; - if (m_bSwapEndianRead) - { - if (m_nNumFilesUnique) - { - SwapEndian(&m_Dir[0], (size_t)m_nNumFilesUnique, eBigEndian); - } - if (m_nNumFilesRef) - { - SwapEndian(&m_DirRef[0], (size_t)m_nNumFilesRef, eBigEndian); - } - } - } - return nRes; -} - -bool CResFile::mfPrepareDir() -{ - if (m_bDirValid) - { - return true; - } - assert(!m_Dir.size()); - SDirEntry* pFileDir = NULL; - if (m_pCompressedDir) - { - assert(!m_Dir.size()); - pFileDir = new SDirEntry[m_nNumFilesUnique]; - if (m_version == RESVERSION_DEBUG) - { - memcpy(pFileDir, m_pCompressedDir, sizeof(SDirEntry) * m_nNumFilesUnique); - } - else - { - CryFatalError("Bad Version: %d!", m_version); - } - m_Dir.resize(m_nNumFilesUnique); - for (uint32 i = 0; i < m_nNumFilesUnique; i++) - { - SDirEntry* deS = &m_Dir[i]; - SDirEntry& fdent = pFileDir[i]; - if (m_bSwapEndianRead) - { - SwapEndian(fdent, eBigEndian); - } - deS->Name = fdent.Name; - deS->size = fdent.size; - deS->offset = fdent.offset; - deS->flags = fdent.flags; - } - m_nSizeComprDir += m_nComprDirSize; - m_bDirValid = true; - } - else - { -#ifndef NDEBUG - int nRes = -#endif - mfLoadDir(m_pStreamInfo); - assert(nRes); - } - - return true; -} - -void CResFile::mfReleaseDir() -{ - // Never unload directory which wasn't flushed yet - if (m_bDirty) - { - return; - } - if (m_bDirStreaming) - { - return; - } - if (m_pStreamInfo && m_pStreamInfo->m_EntriesQueue.size()) - { - return; - } - - if (m_bDirValid) - { - uint32 i; - for (i = 0; i < m_Dir.size(); i++) - { - SDirEntry* de = &m_Dir[i]; - assert(!(de->flags & RF_NOTSAVED)); - mfCloseEntry(de, false); - } - - m_DirOpen.clear(); - //m_Dir.clear(); - ResDir r; - m_Dir.swap(r); - - m_bDirValid = false; - } - else - { - assert(!m_Dir.size()); - } -} - -int CResFile::mfOpen(int type, CResFileLookupDataMan* pMan, SResStreamInfo* pStreamInfo) -{ - SFileResHeader frh; - SDirEntry fden; - - PROFILE_FRAME(Resource_Open); - - if (m_name.c_str()[0] == 0) - { - mfSetError("Open - No Resource name"); - return 0; - } - int nRes = 1; - m_bSwapEndianWrite = (type & RA_ENDIANS) != 0; - m_bSwapEndianRead = m_bSwapEndianWrite; - m_pLookupDataMan = pMan; - type &= ~RA_ENDIANS; - if (type == RA_READ) - { - m_szAccess = "rb"; - } - else - if (type == (RA_WRITE | RA_READ)) - { - m_szAccess = "r+b"; - } - else - if (type & RA_CREATE) - { - m_szAccess = "w+b"; - } - else - { - mfSetError("Open - Wrong access mode"); - return 0; - } - m_typeaccess = type; - - if (type & RA_READ) - { - m_pStreamInfo = pStreamInfo; - } - - mfActivate(true); - - AUTO_LOCK(g_cResLock); // Not thread safe without this - - if (!m_bActive) - { - if (type & (RA_WRITE | RA_CREATE)) - { - bool fileExists = gEnv->pCryPak->IsFileExist(m_name.c_str()); - if (fileExists) - { - m_ermes.clear(); - - mfActivate(true); - } - } - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("Open - Can't open resource file <%s>", m_name.c_str()); - return 0; - } - } - - if (type & RA_READ) - { - // check the preloaded dir data, to see if we can get the dir data from there - CCryNameTSCRC name = m_pLookupDataMan->AdjustName(m_name.c_str()); - if (m_pLookupDataMan) - { - m_pLookupData = m_pLookupDataMan->GetData(name); - } - if (m_pLookupData) - { - m_version = m_pLookupDataMan->GetResVersion(); - m_nNumFilesUnique = m_pLookupData->m_NumOfFilesUnique; - m_nNumFilesRef = m_pLookupData->m_NumOfFilesRef; - m_nOffsDir = m_pLookupData->m_OffsetDir; - m_nComprDirSize = 0;//m_pResDirData->size_dir; - } - else - { - // make sure lookupdata is available when we are streaming the data - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("Open - no file handle (lookupdata not found, while streaming data?)"); - return 0; - } - - // Detect file endianness automatically. - if (gEnv->pCryPak->FReadRaw(&frh, 1, sizeof(frh), m_fileHandle) != sizeof(frh)) - { - mfSetError("Open - Reading fault"); - return 0; - } - if (m_bSwapEndianRead) - { - SwapEndian(frh, eBigEndian); - } - if (frh.hid != IDRESHEADER) - { - mfSetError("Open - Wrong header MagicID"); - return 0; - } - if (frh.ver != RESVERSION_DEBUG) - { - mfSetError("Open - Wrong version number"); - return 0; - } - m_version = frh.ver; - if (!frh.num_files) - { - mfSetError("Open - Empty resource file"); - return 0; - } - - m_nNumFilesUnique = frh.num_files; - m_nNumFilesRef = frh.num_files_ref; - m_nOffsDir = frh.ofs_dir; - m_nComprDirSize = 0; //frh.size_dir; - } - - if (pStreamInfo) - { - m_pStreamInfo->m_pRes = this; - } - - m_bDirCompressed = false; - nRes = mfLoadDir(pStreamInfo); - } - else - { - frh.hid = IDRESHEADER; - int ver = RES_COMPRESSION; - frh.ver = ver; - frh.num_files = 0; - frh.ofs_dir = -1; - frh.num_files_ref = 0; - m_version = ver; - m_nOffsDir = sizeof(frh); - SFileResHeader frhTemp, * pFrh; - pFrh = &frh; - if (m_bSwapEndianWrite) - { - frhTemp = frh; - SwapEndian(frhTemp, eBigEndian); - pFrh = &frhTemp; - } - if (gEnv->pCryPak->FWrite(pFrh, 1, sizeof(frh), m_fileHandle) != sizeof(frh)) - { - mfSetError("Open - Writing fault"); - return 0; - } - m_nComprDirSize = 0; - m_bDirCompressed = false; - m_nNumFilesUnique = 0; - m_nNumFilesRef = 0; - m_pCompressedDir = NULL; - m_bDirValid = true; - } - - return nRes; -} - -bool CResFile::mfClose(void) -{ - AUTO_LOCK(g_cResLock); // Not thread safe without this - - assert(!m_bDirStreaming); - assert(!m_pStreamInfo || !m_pStreamInfo->m_EntriesQueue.size()); - - //if (m_bDirStreaming || (m_pStreamInfo && m_pStreamInfo->m_EntriesQueue.size())) - // Warning("Warning: CResFile::mfClose: Streaming task is in progress!"); - UnlinkStream(); - - if (m_typeaccess != RA_READ) - { - mfFlush(); - } - - // Close the handle and release directory - mfDeactivate(true); - assert(!m_bDirty); - mfReleaseDir(); - - SAFE_DELETE_ARRAY(m_pCompressedDir); - - return true; -} - -struct ResDirSortByName -{ - bool operator () (const SDirEntry& left, const SDirEntry& right) const - { - return left.Name < right.Name; - } - bool operator () (const CCryNameTSCRC left, const SDirEntry& right) const - { - return left < right.Name; - } - bool operator () (const SDirEntry& left, CCryNameTSCRC right) const - { - return left.Name < right; - } -}; -struct ResDirRefSortByName -{ - bool operator () (const SDirEntryRef& left, const SDirEntryRef& right) const - { - return left.Name < right.Name; - } - bool operator () (const CCryNameTSCRC left, const SDirEntryRef& right) const - { - return left < right.Name; - } - bool operator () (const SDirEntryRef& left, CCryNameTSCRC right) const - { - return left.Name < right; - } -}; -struct ResDirOpenSortByName -{ - bool operator () (const SDirEntryOpen& left, const SDirEntryOpen& right) const - { - return left.Name < right.Name; - } - bool operator () (const CCryNameTSCRC left, const SDirEntryOpen& right) const - { - return left < right.Name; - } - bool operator () (const SDirEntryOpen& left, CCryNameTSCRC right) const - { - return left.Name < right; - } -}; - -SDirEntryOpen* CResFile::mfGetOpenEntry(SDirEntry* de) -{ - ResDirOpenIt it = std::lower_bound(m_DirOpen.begin(), m_DirOpen.end(), de->Name, ResDirOpenSortByName()); - if (it != m_DirOpen.end() && de->Name == (*it).Name) - { - return &(*it); - } - return NULL; -} -SDirEntryOpen* CResFile::mfOpenEntry(SDirEntry* de, [[maybe_unused]] bool readingIntoEntryData) -{ - SDirEntryOpen* pOE = NULL; - ResDirOpenIt it = std::lower_bound(m_DirOpen.begin(), m_DirOpen.end(), de->Name, ResDirOpenSortByName()); - if (it == m_DirOpen.end() || de->Name != (*it).Name) - { - AUTO_LOCK(g_cAsyncResLock); - SDirEntryOpen OE; - OE.Name = de->Name; - OE.curOffset = 0; - OE.pData = NULL; - m_DirOpen.insert(it, OE); - it = std::lower_bound(m_DirOpen.begin(), m_DirOpen.end(), de->Name, ResDirOpenSortByName()); - return &(*it); - } - pOE = &(*it); - pOE->curOffset = 0; - assert(pOE->pData || !readingIntoEntryData); - //SAFE_DELETE_ARRAY(pOE->pData); - - return pOE; -} -bool CResFile::mfCloseEntry(SDirEntry* de, bool bEraseOpenEntry) -{ - ResDirOpenIt it = std::lower_bound(m_DirOpen.begin(), m_DirOpen.end(), de->Name, ResDirOpenSortByName()); - if (it == m_DirOpen.end() || de->Name != (*it).Name) - { - return false; - } - SDirEntryOpen& OE = (*it); - OE.curOffset = 0; - if (de->flags & RF_TEMPDATA) - { - if (OE.pData) - { - delete[] (char*)OE.pData; - OE.pData = NULL; - } - } - if (bEraseOpenEntry) - { - AUTO_LOCK(g_cAsyncResLock); - m_DirOpen.erase(it); - } - - return true; -} - -SDirEntry* CResFile::mfGetEntry(CCryNameTSCRC name, bool* pAsync) -{ - if (pAsync) - { - *pAsync = m_bDirStreaming; - if (m_bDirStreaming) - { - return 0; - } - } - - if (!m_Dir.size() || m_bDirStreaming) - { - if (!mfActivate(false)) - { - return NULL; - } - if (!m_Dir.size() || m_bDirStreaming) - { - if (pAsync && m_bDirStreaming) - { - *pAsync = true; - } - return NULL; - } - } - - ResDirIt it = std::lower_bound(m_Dir.begin(), m_Dir.end(), name, ResDirSortByName()); - if (it != m_Dir.end() && name == (*it).Name) - { - assert(m_bDirValid); - return &(*it); - } - ResDirRefIt itRef = std::lower_bound(m_DirRef.begin(), m_DirRef.end(), name, ResDirRefSortByName()); - if (itRef != m_DirRef.end() && name == (*itRef).Name) - { - assert(m_bDirValid); - SDirEntryRef& rref = (*itRef); - return &m_Dir[rref.ref]; - } - return NULL; -} - -int CResFile::mfFileClose(SDirEntry* de) -{ - if (!(de->flags & RF_NOTSAVED)) - { - mfCloseEntry(de); - } - - return 0; -} -int CResFile::mfFileAdd(SDirEntry* de) -{ - AUTO_LOCK(g_cResLock); // Not thread safe without this - - assert(!m_pStreamInfo); - - if (m_typeaccess == RA_READ) - { - mfSetError("FileAdd - wrong access mode"); - return 0; - } - CCryNameTSCRC name = de->Name; - ResDirIt it = std::lower_bound(m_Dir.begin(), m_Dir.end(), name, ResDirSortByName()); - if (it != m_Dir.end() && name == (*it).Name) - { - return m_Dir.size(); - } - - if (de->offset == 0) - { - de->offset = m_nOffset++; - } - - if (de->size != 0) - { - if (!m_Dir.size()) - { - mfActivate(false); - } - - it = std::lower_bound(m_Dir.begin(), m_Dir.end(), name, ResDirSortByName()); - if (it != m_Dir.end() && name == (*it).Name) - { - return m_Dir.size(); - } - - SDirEntry newDE; - newDE = *de; - newDE.flags |= RF_NOTSAVED; - m_Dir.insert(it, newDE); - m_bDirty = true; - } - return m_Dir.size(); -} - -// Lets unpack the entry asynchronously -void CResStreamCallback::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) -{ - SResStreamEntry* pEntry = (SResStreamEntry*)pStream->GetUserData(); - SResStreamInfo* pStreamInfo = pEntry->m_pParent; - assert(pStreamInfo); - if (!pStreamInfo) - { - return; - } - //CryHeapCheck(); - CResFile* pRes = pStreamInfo->m_pRes; - assert(pRes->m_bDirValid); - - if (nError) - { - pRes->mfSetError("FileRead - Error during streaming data"); - return; - } - - SDirEntry* pDE = pRes->mfGetEntry(pEntry->m_Name); - byte* pBuf = (byte*)pStream->GetBuffer(); - assert(pBuf); - byte* pData = NULL; - - int32 size; - { - size = pDE->size; - pData = new byte[size]; - if (!pData) - { - pRes->mfSetError("FileRead - Allocation fault"); - } - else - { - memcpy(pData, pBuf, size); - } - } - { - AUTO_LOCK(g_cAsyncResLock); - - SDirEntryOpen* pOE = pRes->mfGetOpenEntry(pDE); - if (pOE) - { - pDE->flags |= RF_TEMPDATA; - pOE->nSize = size; - pOE->pData = pData; - } - else - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "mfGetOpenEntry() returned NULL, possibly because r_shadersAllowCompilation=1 and r_shadersAsyncActivation=1. Try r_shadersAsyncActivation=0 in your user.cfg."); - } - } -} -// Release the data synchronously -void CResStreamCallback::StreamOnComplete(IReadStream* pStream, unsigned nError) -{ - SResStreamEntry* pEntry = (SResStreamEntry*)pStream->GetUserData(); - SResStreamInfo* pStreamInfo = pEntry->m_pParent; - assert(pStreamInfo); - if (!pStreamInfo) - { - return; - } - SShaderCache* pCache = pStreamInfo->m_pCache; - uint32 i; - bool bFound = false; - - CryAutoLock lock(pStreamInfo->m_StreamLock); - - //CryHeapCheck(); - if (!nError) - { - for (i = 0; i < pStreamInfo->m_EntriesQueue.size(); i++) - { - SResStreamEntry* pE = pStreamInfo->m_EntriesQueue[i]; - if (pE == pEntry) - { - SAFE_DELETE(pE); - pStreamInfo->m_EntriesQueue.erase(pStreamInfo->m_EntriesQueue.begin() + i); - bFound = true; - break; - } - } - assert(bFound); - } - pCache->Release(); -} - -int CResFile::mfFileRead(SDirEntry* de) -{ - uint32 size = 0; - - SDirEntryOpen* pOE = mfOpenEntry(de); - - if (pOE->pData) - { - return pOE->nSize; - } - - if (!mfActivate(false)) - { - return 0; - } - - AUTO_LOCK(g_cResLock); // Not thread safe without this - - //if (strstr(m_name, "FPVS") && m_Dir.size()==3) - { - //int nnn = 0; - } - if (m_pStreamInfo) - { - mfTickStreaming(); - if (!m_bDirValid) - { - assert(m_bDirStreaming); - return -1; - } - - CryAutoLock lock(m_pStreamInfo->m_StreamLock); - - SResStreamEntry* pEntry; - { - //AUTO_LOCK(g_cAsyncResLock); - pEntry = m_pStreamInfo->AddEntry(de->Name); - if (!pEntry) // Already processing - { - return -1; - } - } - if (pOE->pData) - { - return pOE->nSize; - } - StreamReadParams StrParams; - StrParams.nFlags = 0; - StrParams.dwUserData = (DWORD_PTR)pEntry; - StrParams.nLoadTime = 1; - StrParams.nMaxLoadTime = 4; - // StrParams.nPriority = 0; - StrParams.pBuffer = NULL; - StrParams.nOffset = de->offset; - StrParams.nSize = de->size; - m_pStreamInfo->m_pCache->AddRef(); - //Warning("Warning: CResFile::mfFileRead: '%s' Ref: %d", m_name.c_str(), n); - pEntry->m_readStream = iSystem->GetStreamEngine()->StartRead(eStreamTaskTypeShader, m_name.c_str(), &m_pStreamInfo->m_Callback, &StrParams); - return -1; - } - else - if (de->flags & RF_COMPRESS) - { - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset, SEEK_SET) > 0) - { - mfSetError("FileRead - Seek error"); - return 0; - } - - byte* buf = new byte[de->size]; - if (!buf) - { - mfSetError("FileRead - Allocation fault"); - return 0; - } - if (m_version == RESVERSION_DEBUG) - { - gEnv->pCryPak->FReadRaw(buf, de->size, 1, m_fileHandle); - pOE->pData = new byte[de->size - 20]; - de->flags |= RF_TEMPDATA; - if (!pOE->pData) - { - SAFE_DELETE_ARRAY(buf); - mfSetError("FileRead - Allocation fault"); - return 0; - } - memcpy(pOE->pData, &buf[10], de->size - 20); - } - else - { - CryFatalError("Bad Version: %d!", m_version); - return 0; - } - - delete[] buf; - - pOE->nSize = size; - return size; - } - - pOE->pData = new byte[de->size]; - pOE->nSize = de->size; - de->flags |= RF_TEMPDATA; - if (!pOE->pData) - { - mfSetError("FileRead - Allocation fault"); - return 0; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("FileRead - Invalid file handle"); - return 0; - } - - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset, SEEK_SET) > 0) - { - mfSetError("FileRead - Seek error"); - return 0; - } - - if (gEnv->pCryPak->FReadRaw(pOE->pData, 1, de->size, m_fileHandle) != de->size) - { - mfSetError("FileRead - Reading fault"); - return 0; - } - - //if (strstr(m_name, "FPVS") && m_Dir.size()==3) - { - //gEnv->pCryPak->FSeek(m_fileHandle, 0, SEEK_END); - //int nSize = gEnv->pCryPak->FTell(m_fileHandle); - //int nnn = 0; - } - - return de->size; -} - -byte* CResFile::mfFileReadCompressed(SDirEntry* de, uint32& nSizeDecomp, uint32& nSizeComp) -{ - if (!mfActivate(false)) - { - return NULL; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("FileReadCompressed - Invalid file handle"); - return 0; - } - - if (de->flags & RF_COMPRESS) - { - if (de->offset >= 0x10000000) - { - return NULL; - } - - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset, SEEK_SET) > 0) - { - mfSetError("FileReadCompressed - Seek error"); - return 0; - } - - byte* buf = new byte[de->size]; - if (!buf) - { - mfSetError("FileRead - Allocation fault"); - return 0; - } - if (m_version == RESVERSION_DEBUG) - { - gEnv->pCryPak->FReadRaw(buf, 10, 1, m_fileHandle); - gEnv->pCryPak->FReadRaw(buf, de->size - 20, 1, m_fileHandle); - nSizeDecomp = de->size - 20; - nSizeComp = de->size - 20; - } - else - { - CryFatalError("Bad Version: %d!", m_version); - return 0; - } - return buf; - } - - nSizeComp = nSizeDecomp = de->size; - byte* buf = new byte[de->size]; - - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset, SEEK_SET) > 0) - { - mfSetError("FileReadCompressed - Seek error"); - delete[] buf; - return 0; - } - - if (gEnv->pCryPak->FReadRaw(buf, 1, de->size, m_fileHandle) != de->size) - { - mfSetError("FileRead - Reading fault"); - delete[] buf; - return 0; - } - return buf; -} - -int CResFile::mfFileRead(CCryNameTSCRC name) -{ - SDirEntry* de = mfGetEntry(name); - - if (!de) - { - mfSetError("FileRead - Wrong FileId"); - return 0; - } - return mfFileRead(de); -} - -int CResFile::mfFileRead(const char* name) -{ - return mfFileRead(CCryNameTSCRC(name)); -} - -int CResFile::mfFileWrite(CCryNameTSCRC name, void* data) -{ - SDirEntry* de = mfGetEntry(name); - - if (!de) - { - mfSetError("FileWrite - Wrong FileId"); - return 0; - } - if (!data) - { - mfSetError("FileWrite - Wrong data"); - return 0; - } - - if (!mfActivate(false)) - { - return 0; - } - - if (de->flags & RF_COMPRESS) - { - assert(0); - return 0; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("FileWrite - Invalid file handle"); - return 0; - } - - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset, SEEK_SET) > 0) - { - mfSetError("FileWrite - Seek error"); - return 0; - } - - if (gEnv->pCryPak->FWrite(data, 1, de->size, m_fileHandle) != de->size) - { - mfSetError("FileWrite - Writing fault"); - return 0; - } - - return de->size; -} - -void CResFile::mfFileRead2(SDirEntry* de, int size, void* buf) -{ - if (!buf) - { - mfSetError("FileRead - Wrong data"); - return; - } - SDirEntryOpen* pOE = mfOpenEntry(de, false); - - if (pOE->pData) - { - memcpy(buf, (byte*)(pOE->pData) + pOE->curOffset, size); - pOE->curOffset += size; - return; - } - if (!mfActivate(false)) - { - return; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("FileRead2 - Invalid file handle"); - return; - } - - if (gEnv->pCryPak->FSeek(m_fileHandle, de->offset + pOE->curOffset, SEEK_SET) > 0) - { - mfSetError("FileRead2 - Seek error"); - return; - } - - if (gEnv->pCryPak->FReadRaw(buf, 1, size, m_fileHandle) != size) - { - mfSetError("FileRead - Reading fault"); - return; - } - pOE->curOffset += size; -} - -void CResFile::mfFileRead2(CCryNameTSCRC name, int size, void* buf) -{ - SDirEntry* de = mfGetEntry(name); - if (!de) - { - mfSetError("FileRead2 - wrong file id"); - return; - } - return mfFileRead2(de, size, buf); -} - -void* CResFile::mfFileGetBuf(SDirEntry* de) -{ - SDirEntryOpen* pOE = mfGetOpenEntry(de); - if (!pOE) - { - return NULL; - } - return pOE->pData; -} - -void* CResFile::mfFileGetBuf(CCryNameTSCRC name) -{ - SDirEntry* de = mfGetEntry(name); - if (!de) - { - mfSetError("FileGetBuf - wrong file id"); - return NULL; - } - return mfFileGetBuf(de); -} - -int CResFile::mfFileSeek(SDirEntry* de, int ofs, int type) -{ - int m; - - mfActivate(false); - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("FileSeek - Invalid file handle"); - return -1; - } - - AUTO_LOCK(g_cResLock); // Not thread safe without this - - SDirEntryOpen* pOE = mfOpenEntry(de, false); - - switch (type) - { - case SEEK_CUR: - pOE->curOffset += ofs; - m = gEnv->pCryPak->FSeek(m_fileHandle, de->offset + pOE->curOffset, SEEK_SET); - break; - - case SEEK_SET: - m = gEnv->pCryPak->FSeek(m_fileHandle, de->offset + ofs, SEEK_SET); - pOE->curOffset = ofs; - break; - - case SEEK_END: - pOE->curOffset = de->size - ofs; - m = gEnv->pCryPak->FSeek(m_fileHandle, de->offset + pOE->curOffset, SEEK_SET); - break; - - default: - mfSetError("FileSeek - wrong seek type"); - return -1; - } - - return m; -} - -int CResFile::mfFileSeek(CCryNameTSCRC name, int ofs, int type) -{ - SDirEntry* de = mfGetEntry(name); - - if (!de) - { - mfSetError("FileSeek - invalid file id"); - return -1; - } - return mfFileSeek(de, ofs, type); -} - -int CResFile::mfFileSeek(char* name, int ofs, int type) -{ - return mfFileSeek(CCryNameTSCRC(name), ofs, type); -} - -int CResFile::mfFileLength(SDirEntry* de) -{ - return de->size; -} - -int CResFile::mfFileLength(CCryNameTSCRC name) -{ - SDirEntry* de = mfGetEntry(name); - - if (!de) - { - mfSetError("FileLength - invalid file id"); - return -1; - } - return mfFileLength(de); -} - -int CResFile::mfFileLength(char* name) -{ - return mfFileLength(CCryNameTSCRC(name)); -} - -int CResFile::mfFlushDir(long nOffset, [[maybe_unused]] bool bOptimise) -{ - uint32 i; -#ifdef _DEBUG - // Check for sorted array and duplicated values - ResDir Sorted; - for (i = 0; i < m_Dir.size(); i++) - { - SDirEntry& DE = m_Dir[i]; - ResDirIt it = std::lower_bound(Sorted.begin(), Sorted.end(), DE.Name, ResDirSortByName()); - if (it != Sorted.end() && DE.Name == (*it).Name) - { - assert(0); // Duplicated value - continue; - } - Sorted.insert(it, DE); - } - assert(Sorted.size() == m_Dir.size()); - for (i = 0; i < m_Dir.size(); i++) - { - SDirEntry& DE1 = m_Dir[i]; - SDirEntry& DE2 = Sorted[i]; - assert(DE1.Name == DE2.Name); - } - - ResDirRef SortedRef; - for (i = 0; i < m_DirRef.size(); i++) - { - SDirEntryRef& DE = m_DirRef[i]; - ResDirRefIt it = std::lower_bound(SortedRef.begin(), SortedRef.end(), DE.Name, ResDirRefSortByName()); - if (it != SortedRef.end() && DE.Name == (*it).Name) - { - assert(0); // Duplicated value - continue; - } - SortedRef.insert(it, DE); - } - assert(SortedRef.size() == m_DirRef.size()); - for (i = 0; i < m_DirRef.size(); i++) - { - SDirEntryRef& DE1 = m_DirRef[i]; - SDirEntryRef& DE2 = SortedRef[i]; - assert(DE1.Name == DE2.Name); - } - - // Make sure references are correct - if (bOptimise) - { - for (i = 0; i < m_DirRef.size(); i++) - { - SDirEntryRef& r = m_DirRef[i]; - assert(r.ref < m_Dir.size()); - } - } -#endif - - TArray FDir; - TArray FDirRef; - FDir.ReserveNoClear(m_Dir.size()); - FDirRef.ReserveNoClear(m_DirRef.size()); - - for (i = 0; i < (int)m_Dir.size(); i++) - { - SDirEntry* de = &m_Dir[i]; - SDirEntry& fden = FDir[i]; - fden.Name = de->Name; - fden.size = de->size; - assert(de->offset > 0); - fden.offset = de->offset; - fden.flags = de->flags; - if (m_bSwapEndianWrite) - { - SwapEndian(fden, eBigEndian); - } - } - for (i = 0; i < (int)m_DirRef.size(); i++) - { - SDirEntryRef* de = &m_DirRef[i]; - SDirEntryRef& fden = FDirRef[i]; - fden.Name = de->Name; - fden.ref = de->ref; - assert(de->ref >= 0); - if (m_bSwapEndianWrite) - { - SwapEndian(fden, eBigEndian); - } - } - gEnv->pCryPak->FSeek(m_fileHandle, nOffset, SEEK_SET); - int sizeUn = FDir.Num() * sizeof(SDirEntry); - int sizeRef = FDirRef.Num() * sizeof(SDirEntryRef); - byte* buf = NULL; - if (m_bDirCompressed) - { -#if RES_COMPRESSION == RESVERSION_DEBUG - buf = new byte [sizeUn]; - memcpy(buf, (byte*)&FDir[0], sizeUn); -#else - COMPILE_TIME_ASSERT(0); -#endif - } - else - { - buf = new byte[sizeUn + sizeRef]; - memcpy(buf, &FDir[0], sizeUn); - if (sizeRef) - { - memcpy(&buf[sizeUn], &FDirRef[0], sizeRef); - } - } - if (gEnv->pCryPak->FWrite(buf, 1, sizeUn + sizeRef, m_fileHandle) != sizeUn + sizeRef) - { - mfSetError("FlushDir - Writing fault"); - return false; - } - m_nOffsDir = nOffset; - m_nNumFilesUnique = FDir.Num(); - m_nNumFilesRef = FDirRef.Num(); - SAFE_DELETE_ARRAY(m_pCompressedDir); - if (m_bDirCompressed) - { - m_nComprDirSize = sizeUn; - m_pCompressedDir = new byte[sizeUn]; - memcpy(m_pCompressedDir, buf, sizeUn); - } - SAFE_DELETE_ARRAY(buf); - m_bDirValid = true; - - SResFileLookupData* pLookup = GetLookupData(false, 0, 0); - - if (pLookup) - { - pLookup->m_NumOfFilesRef = m_nNumFilesRef; - pLookup->m_NumOfFilesUnique = m_nNumFilesUnique; - pLookup->m_OffsetDir = nOffset; - m_pLookupDataMan->MarkDirty(true); - m_pLookupDataMan->Flush(); - } - return sizeUn + sizeRef; -} - -int CResFile::mfFlush(bool bOptimise) -{ - SFileResHeader frh; - - PROFILE_FRAME(Resource_Flush); - - // For compatibility with old builds - bOptimise = false; - - int nSizeDir = m_DirRef.size() * sizeof(SDirEntryRef) + m_Dir.size() * sizeof(SDirEntry); - - if (m_typeaccess == RA_READ) - { - mfSetError("Flush - wrong access mode"); - return nSizeDir; - } - AUTO_LOCK(g_cResLock); // Not thread safe without this - - if (m_pLookupDataMan) - { - m_pLookupDataMan->Flush(); - } - - if (!m_bDirty) - { - return nSizeDir; - } - m_bDirty = false; - if (!mfActivate(false)) - { - return nSizeDir; - } - - if (m_fileHandle == AZ::IO::InvalidHandle) - { - mfSetError("Flush - Invalid file handle"); - return 0; - } - - int i; - uint32 j; - - int nSizeCompr = 0; - - int nUpdate = 0; - int nSizeUpdate = 0; - - const size_t numDirRefs = m_Dir.size(); - TArray* pRefs = NULL; - if (!bOptimise) - { - pRefs = new TArray[numDirRefs]; - } - - // Make a list of all references - for (i = 0; i < (int)m_Dir.size(); i++) - { - SDirEntry* de = &m_Dir[i]; - if (de->offset < 0) - { - assert(de->flags & RF_NOTSAVED); - bool bFound = false; - for (j = 0; j < m_Dir.size(); j++) - { - if (i == j) - { - continue; - } - SDirEntry* d = &m_Dir[j]; - if (d->offset == -de->offset) - { - if (bOptimise) - { - SDirEntryRef r; - r.Name = de->Name; - r.ref = d->offset; - m_DirRef.push_back(r); - mfCloseEntry(de); - m_Dir.erase(m_Dir.begin() + i); - i--; - } - else - { - pRefs[j].AddElem(i); - } - bFound = true; - break; - } - } - assert(bFound); - } - } - - nSizeDir = m_DirRef.size() * sizeof(SDirEntryRef) + m_Dir.size() * sizeof(SDirEntry); - - const int nFiles = m_Dir.size(); - long nSeek = m_nOffsDir; - for (i = 0; i < nFiles; i++) - { - SDirEntry* de = &m_Dir[i]; - assert(de->offset >= 0); - if (de->flags & RF_NOTSAVED) - { - SDirEntryOpen* pOE = mfGetOpenEntry(de); - de->flags &= ~RF_NOTSAVED; - nUpdate++; - nSizeUpdate += de->size; - - if (de->offset >= 0) - { - assert(pOE && pOE->pData); - if (!pOE || !pOE->pData) - { - continue; - } - gEnv->pCryPak->FSeek(m_fileHandle, nSeek, SEEK_SET); - if (de->flags & RF_COMPRESS) - { - byte* buf = NULL; -#if RES_COMPRESSION == RESVERSION_DEBUG - buf = new byte [de->size + 20]; - memcpy(buf, ">>rawbuf>>", 10); - memcpy(buf + 10, (byte*)pOE->pData, de->size); - memcpy(buf + 10 + de->size, "<size += 20; -#else - COMPILE_TIME_ASSERT(0); -#endif - if (gEnv->pCryPak->FWrite(buf, 1, de->size, m_fileHandle) != de->size) - { - mfSetError("Flush - Writing fault"); - } - if (!(de->flags & RF_COMPRESSED)) - { - delete[] buf; - } - nSizeCompr += de->size; - } - else - if (!pOE->pData || (gEnv->pCryPak->FWrite(pOE->pData, 1, de->size, m_fileHandle) != de->size)) - { - mfSetError("Flush - Writing fault"); - continue; - } - - mfCloseEntry(de); - if (bOptimise) - { - for (j = 0; j < m_DirRef.size(); j++) - { - SDirEntryRef& r = m_DirRef[j]; - if (r.ref == de->offset) - { - nUpdate++; - r.ref = i; - } - } - } - de->offset = nSeek; - nSeek += de->size; - } - } - // Update reference entries - if (pRefs) - { - PREFAST_ASSUME(i < numDirRefs); - for (j = 0; j < pRefs[i].Num(); j++) - { - nUpdate++; - SDirEntry* d = &m_Dir[pRefs[i][j]]; - d->offset = de->offset; - d->size = de->size; - d->flags = de->flags; - d->flags &= ~RF_NOTSAVED; - } - } - } - SAFE_DELETE_ARRAY(pRefs); - - if (!nUpdate) - { - return nSizeDir; - } - m_bDirCompressed = false; //bCompressDir; - int sizeDir = mfFlushDir(nSeek, bOptimise); - assert(sizeDir == nSizeDir); - - frh.hid = IDRESHEADER; - int ver = RES_COMPRESSION; - frh.ver = ver; - frh.num_files = m_Dir.size(); - frh.num_files_ref = m_DirRef.size(); - frh.ofs_dir = nSeek; - //frh.size_dir = sizeDir; - m_version = ver; - SFileResHeader frhTemp, * pFrh; - pFrh = &frh; - if (m_bSwapEndianWrite) - { - frhTemp = frh; - SwapEndian(frhTemp, eBigEndian); - pFrh = &frhTemp; - } - gEnv->pCryPak->FSeek(m_fileHandle, 0, SEEK_SET); - if (gEnv->pCryPak->FWrite(pFrh, 1, sizeof(frh), m_fileHandle) != sizeof(frh)) - { - mfSetError("Flush - Writing fault"); - return nSizeDir; - } - gEnv->pCryPak->FFlush(m_fileHandle); - //if (strstr(m_name, "FPVS") && frh.num_files==4) - { - //gEnv->pCryPak->FSeek(m_fileHandle, 0, SEEK_END); - //int nSize = gEnv->pCryPak->FTell(m_fileHandle); - //mfDeactivate(); - //int nnn = 0; - } - - return sizeDir; -} - -int CResFile::Size() -{ - int nSize = sizeof(CResFile); - - uint32 i; - for (i = 0; i < m_Dir.size(); i++) - { - SDirEntry& DE = m_Dir[i]; - nSize += sizeof(SDirEntry); - SDirEntryOpen* pOE = mfGetOpenEntry(&DE); - if (pOE) - { - nSize += sizeof(SDirEntryOpen); - if (pOE->pData && (DE.flags & RF_TEMPDATA)) - { - nSize += DE.size; - } - } - } - - return nSize; -} - -void CResFile::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_Dir); - pSizer->AddObject(m_DirOpen); -} - -ResDir* CResFile::mfGetDirectory() -{ - return &m_Dir; -} - -//====================================================================== - -void fpStripExtension (const char* const in, char* const out, const size_t bytes) -{ - assert(in && out && (bytes || in == out)); // if this hits, check the call site - const size_t inlen = strlen(in); - ptrdiff_t len = inlen - 1; - - if (len <= 1) - { - assert(bytes >= 2); // if this hits, bad buffer was passed in - cry_strcpy(out, bytes, in); - return; - } - - while (in[len]) - { - if (in[len] == '.') - { - int n = (int)len; - while (in[n] != 0) - { - if (in[n] == '+') - { - assert(bytes > inlen); // if this hits, bad buffer was passed in - cry_strcpy(out, bytes, in); - return; - } - n++; - } - break; - } - len--; - if (!len) - { - assert(bytes > inlen); // if this hits, bad buffer was passed in - cry_strcpy(out, bytes, in); - return; - } - } - assert(bytes > len); // if this hits, bad buffer was passed in - cry_strcpy(out, bytes, in, len); -} - -//return a pointer to the last dot after the last slash -const char* fpGetExtension(const char* in) -{ - if (!in) - { - return nullptr; - } - - const char* ls1 = strrchr(in, '\\'); - const char* ls2 = strrchr(in, '/'); - const char* sb = in; - - if (ls1) - { - sb = ls1; - } - - if (ls2 > sb) - { - sb = ls2; - } - - return strrchr(sb, '.'); -} - -void fpAddExtension(char* path, const char* extension, size_t bytes) -{ - assert(path && extension && bytes); // if this hits, check the call site - char* src; - - assert(*path); // if this hits, src underflow - src = path + strlen(path) - 1; - - while (*src != '/' && src != path) - { - if (*src == '.') - { - return; // it has an extension - } - src--; - } - - assert(bytes > strlen(path) + strlen(extension)); // if this hits, bad buffer was passed in - azstrcat(path, bytes, extension); -} - -void fpConvertDOSToUnixName(char* dst, const char* src, [[maybe_unused]] size_t bytes) -{ - assert(dst && src && bytes); // if this hits, check the call site - assert(bytes > strlen(src)); // if this hits, bad buffer was passed in - while (*src) - { - if (*src == '\\') - { - *dst = '/'; - } - else - { - *dst = *src; - } - dst++; - src++; - } - *dst = 0; -} - -void fpConvertUnixToDosName(char* dst, const char* src, [[maybe_unused]] size_t bytes) -{ - assert(dst && src && bytes); // if this hits, check the call site - assert(bytes > strlen(src)); // if this hits, bad buffer was passed in - while (*src) - { - if (*src == '/') - { - *dst = '\\'; - } - else - { - *dst = *src; - } - dst++; - src++; - } - *dst = 0; -} - -void fpUsePath(const char* name, const char* path, char* dst, size_t bytes) -{ - assert(name && dst && bytes); // if this hits, check the call site - - if (!path) - { - assert(bytes > strlen(name)); // if this hits, bad buffer was passed in - azstrcpy(dst, bytes, name); - return; - } - - assert(bytes > strlen(path)); // if this hits, bad buffer was passed in - azstrcpy(dst, bytes, path); - - assert(*path); // if this hits, path underflow - char c = path[strlen(path) - 1]; - if (c != '/' && c != '\\') - { - assert(bytes > strlen(path) + strlen(name) + 1); // it this hits, bad buffer was passed in - azstrcat(dst, bytes, "/"); - } - else - { - assert(bytes > strlen(path) + strlen(name)); // it this hits, bad buffer was passed in - } - azstrcat(dst, bytes, name); -} - -#include "TypeInfo_impl.h" -#include "ResFile_info.h" -#ifndef AZ_MONOLITHIC_BUILD -#include "Name_TypeInfo.h" -#endif diff --git a/Code/CryEngine/RenderDll/Common/ResFile.h b/Code/CryEngine/RenderDll/Common/ResFile.h deleted file mode 100644 index 0908f01f01..0000000000 --- a/Code/CryEngine/RenderDll/Common/ResFile.h +++ /dev/null @@ -1,314 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __RESFILE_H__ -#define __RESFILE_H__ - -#include "CryName.h" - -#define IDRESHEADER (('K' << 24) + ('C' << 16) + ('P' << 8) + 'C') -#define RESVERSION_DEBUG 12 // Uncompressed - -// defines the current compression for any files written -#define RES_COMPRESSION RESVERSION_DEBUG - -// Resource files flags -#define RF_NOTSAVED 1 -#define RF_COMPRESS 4 -#define RF_TEMPDATA 8 -#define RF_COMPRESSED 0x80 -#define RF_RES_$TOKENS 0x20 -#define RF_RES_$ (RF_RES_$TOKENS) - -struct SResFileLookupData; -class CResFileLookupDataMan; - -// Resource header -struct SFileResHeader -{ - uint32 hid; - int ver; - int num_files; - //int num_files_ref; - uint32 ofs_dir; - uint32 num_files_ref; - AUTO_STRUCT_INFO -}; - -#define MAX_FILE_NAME 256 - -#define OFFSET_BIG_POSITIVE 0x20000000 - -struct SDirEntryOpen -{ - CCryNameTSCRC Name; - uint32 curOffset; - void* pData; - int nSize; - - SDirEntryOpen() - { - pData = NULL; - nSize = 0; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -// Internal file entry -struct SDirEntry -{ - CCryNameTSCRC Name; - uint32 size : 24; - uint32 flags : 8; // RF_ - int32 offset; - - SDirEntry() - { - size = 0; - flags = 0; - offset = 0; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - - AUTO_STRUCT_INFO -}; - -struct SDirEntryRef -{ - CCryNameTSCRC Name; - uint32 ref; - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - - AUTO_STRUCT_INFO -}; - -//typedef std::map ResFilesMap; -//typedef ResFilesMap::iterator ResFilesMapItor; - -// Resource access types -#define RA_READ 1 -#define RA_WRITE 2 -#define RA_CREATE 4 -#define RA_ENDIANS 8 - - -// Resource optimize flags -#define RO_HEADERS_IN_BEGIN 1 -#define RO_HEADERS_IN_END 2 -#define RO_HEADER_FILE 4 -#define RO_SORT_ALPHA_ASC 8 -#define RO_SORT_ALPHA_DESC 0x10 - -#define MAX_OPEN_RESFILES 64 -typedef AZStd::vector ResDir; -typedef ResDir::iterator ResDirIt; - -typedef AZStd::vector ResDirRef; -typedef ResDirRef::iterator ResDirRefIt; - -typedef AZStd::vector ResDirOpen; -typedef ResDirOpen::iterator ResDirOpenIt; - -#define MAX_DIR_SIZE (2 * 1024 * 1024) // Directory size in memory (consoles only) - -class CResFile -{ - friend class CResStreamCallback; - friend class CResStreamDirCallback; - friend class CResFileLookupDataMan; - friend class CShaderSerialize; - -private: - string m_name; - const char* m_szAccess; - AZ::IO::HandleType m_fileHandle; - ResDir m_Dir; - ResDirRef m_DirRef; - ResDirOpen m_DirOpen; - byte* m_pCompressedDir; - int m_typeaccess; - uint32 m_nNumFilesUnique; - uint32 m_nNumFilesRef; - uint32 m_nOffsDir; - uint32 m_nComprDirSize; - int32 m_nOffset; - byte m_bSwapEndianRead : 1; - byte m_bSwapEndianWrite : 1; - byte m_bDirty : 1; - byte m_bDirValid : 1; - byte m_bDirStreaming : 1; - byte m_bDirCompressed : 1; - byte m_bActive : 1; - uint32 m_nLastTickStreamed; - string m_ermes; - int m_version; - SResStreamInfo* m_pStreamInfo; - - const SResFileLookupData* m_pLookupData; - class CResFileLookupDataMan* m_pLookupDataMan; - - static CResFile m_Root; - static CResFile m_RootStream; - static uint32 m_nSizeComprDir; - CResFile* m_Next; - CResFile* m_Prev; - CResFile* m_NextStream; - CResFile* m_PrevStream; - - bool mfActivate(bool bFirstTime); - - _inline void Relink(CResFile* Before) - { - if (m_Next && m_Prev) - { - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - } - m_Next = Before->m_Next; - Before->m_Next->m_Prev = this; - Before->m_Next = this; - m_Prev = Before; - } - _inline void Unlink() - { - if (!m_Next || !m_Prev) - { - return; - } - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - m_Next = m_Prev = NULL; - } - _inline void Link(CResFile* Before) - { - if (m_Next || m_Prev) - { - return; - } - m_Next = Before->m_Next; - Before->m_Next->m_Prev = this; - Before->m_Next = this; - m_Prev = Before; - } - - _inline void UnlinkStream() - { - if (!m_NextStream || !m_PrevStream) - { - return; - } - m_NextStream->m_PrevStream = m_PrevStream; - m_PrevStream->m_NextStream = m_NextStream; - m_NextStream = m_PrevStream = NULL; - } - _inline void LinkStream(CResFile* Before) - { - if (m_NextStream || m_PrevStream) - { - return; - } - m_NextStream = Before->m_NextStream; - Before->m_NextStream->m_PrevStream = this; - Before->m_NextStream = this; - m_PrevStream = Before; - } - -public: - CResFile(const char* name); - ~CResFile(); - - _inline CResFileLookupDataMan* GetLookupMan() const - { - return m_pLookupDataMan; - } - - SResFileLookupData* GetLookupData(bool bCreate, uint32 CRC, float fVersion) const; - - const char* mfGetError(void); - void mfSetError(const char* er, ...); - const char* mfGetFileName() const {return m_name.c_str(); } - int mfGetVersion() { return m_version; } - void mfDeactivate(bool bReleaseDir); - - void mfTickStreaming(); - - int mfOpen(int type, CResFileLookupDataMan* pMan, SResStreamInfo* pStreamInfo = NULL); - bool mfClose(); - int mfFlush(bool bCompressDir = false); - int mfFlushDir(long nSeek, bool bOptimise); - bool mfPrepareDir(); - int mfLoadDir(SResStreamInfo* pStreamInfo); - void mfReleaseDir(); - - int mfGetNumFiles() { return m_Dir.size(); } - - byte* mfFileReadCompressed(SDirEntry* de, uint32& nSizeDecomp, uint32& nSizeComp); - - int mfFileRead(SDirEntry* de); - int mfFileRead(const char* name); - int mfFileRead(CCryNameTSCRC name); - - int mfFileWrite(CCryNameTSCRC name, void* data); - - void mfFileRead2(SDirEntry* de, int size, void* buf); - void mfFileRead2(CCryNameTSCRC name, int size, void* buf); - - void* mfFileGetBuf(SDirEntry* de); - void* mfFileGetBuf(CCryNameTSCRC name); - - int mfFileSeek(SDirEntry* de, int offs, int type); - int mfFileSeek(CCryNameTSCRC name, int offs, int type); - int mfFileSeek(char* name, int offs, int type); - - int mfFileLength(SDirEntry* de); - int mfFileLength(CCryNameTSCRC name); - int mfFileLength(char* name); - - int mfFileAdd(SDirEntry* de); - - bool mfIsDirty() { return m_bDirty; } - bool mfIsDirStreaming() { return m_bDirStreaming; } - - //int mfFileDelete(SDirEntry *de); - //int mfFileDelete(CCryNameTSCRC name); - //int mfFileDelete(char* name); - - bool mfFileExist(CCryNameTSCRC name); - bool mfFileExist(const char* name); - - int mfFileClose(SDirEntry* de); - bool mfCloseEntry(SDirEntry* de, bool bEraseOpenEntry = true); - SDirEntryOpen* mfOpenEntry(SDirEntry* de, bool readingIntoEntryData = true); - SDirEntryOpen* mfGetOpenEntry(SDirEntry* de); - SDirEntry* mfGetEntry(CCryNameTSCRC name, bool* bAsync = NULL); - ResDir* mfGetDirectory(); - - AZ::IO::HandleType mfGetHandle() { return m_fileHandle; } - int mfGetResourceSize(); - - uint64 mfGetModifTime(); - - int Size(); - void GetMemoryUsage(ICrySizer* pSizer) const; - - static void Tick(); - static bool IsStreaming(); - - static uint32 m_nMaxOpenResFiles; - static int m_nNumOpenResources; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RESFILE_H diff --git a/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.cpp b/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.cpp deleted file mode 100644 index 8c0b859591..0000000000 --- a/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "Pak/CryPakUtils.h" -#include "ResFileLookupDataMan.h" -#include "ResFile.h" -#include -#include - -#include "Shaders/Shader.h" - -////////////////////////////////////////////////////////////////////////// - -SResFileLookupDataDisk::SResFileLookupDataDisk(const struct SResFileLookupData& inLookup) -{ - m_NumOfFilesUnique = inLookup.m_NumOfFilesUnique; - m_NumOfFilesRef = inLookup.m_NumOfFilesRef; - m_OffsetDir = inLookup.m_OffsetDir; - m_CRC32 = inLookup.m_CRC32; - m_CacheMajorVer = inLookup.m_CacheMajorVer; - m_CacheMinorVer = inLookup.m_CacheMinorVer; -} - -#ifdef USE_PARTIAL_ACTIVATION -unsigned int SResFileLookupData::GetDirOffset( - const CCryNameTSCRC& dirEntryName) const -{ - if (m_resdirlookup.size() == 0) - { - return 0; - } - - /* - if (m_resdirlookup.size() > 0) - { - char acTmp[1024]; - sprintf(acTmp, "dir values: "); - OutputDebugString(acTmp); - for (unsigned int ui = 0; ui < m_resdirlookup.size(); ++ui) - { - sprintf(acTmp, " %u ", m_resdirlookup[ui]); - OutputDebugString(acTmp); - } - sprintf(acTmp, " \n"); - OutputDebugString(acTmp); - } - */ - - unsigned int uiOffset = 0; - for (; uiOffset < m_resdirlookup.size() - 1; ++uiOffset) - { - if (m_resdirlookup[uiOffset + 1] > dirEntryName) - { - break; - } - } - - return uiOffset; -} -#endif - -////////////////////////////////////////////////////////////////////////// - -CResFileLookupDataMan::CResFileLookupDataMan() - : m_TotalDirStored(0) -{ - m_bDirty = false; - m_bReadOnly = true; - - m_VersionInfo.m_ResVersion = RES_COMPRESSION; - - float fVersion = FX_CACHE_VER; - azsprintf(m_VersionInfo.m_szCacheVer, "Ver: %.1f", fVersion); -} - -CResFileLookupDataMan::~CResFileLookupDataMan() -{ - if (m_bDirty) - { - Flush(); - } - Clear(); -} - -CCryNameTSCRC CResFileLookupDataMan::AdjustName(const char* szName) -{ - char acTmp[1024]; - int nSize = gRenDev->m_cEF.m_szCachePath.size(); - if (!_strnicmp(szName, gRenDev->m_cEF.m_szCachePath.c_str(), nSize)) - { - azstrcpy(acTmp, AZ_ARRAY_SIZE(acTmp), &szName[nSize]); - } - else if (!_strnicmp(szName, "Levels", 6)) - { - const char* acNewName = strstr(szName, "ShaderCache"); - assert(acNewName); - PREFAST_ASSUME(acNewName); - azstrcpy(acTmp, AZ_ARRAY_SIZE(acTmp), acNewName); - } - else - { - azstrcpy(acTmp, AZ_ARRAY_SIZE(acTmp), szName); - } - - return acTmp; -} - - -////////////////////////////////////////////////////////////////////////// - -void CResFileLookupDataMan::Clear() -{ - m_Data.clear(); -} - -void CResFileLookupDataMan::Flush() -{ - if (!m_bDirty) - { - return; - } - SaveData(m_Path.c_str(), CParserBin::m_bEndians); - m_bDirty = false; -} - -bool CResFileLookupDataMan::LoadData( - const char* acFilename, bool bSwapEndianRead, bool bReadOnly) -{ - m_Path = acFilename; - - m_bReadOnly = bReadOnly; - - int nFlags = bReadOnly ? 0 : AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK; - - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(acFilename, "rb", nFlags); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - uint32 hid; - - SVersionInfo versionInfo; - - gEnv->pCryPak->FReadRaw(&hid, sizeof(uint32), 1, fileHandle); - gEnv->pCryPak->FReadRaw(&versionInfo, sizeof(SVersionInfo), 1, fileHandle); - - if (bSwapEndianRead) - { - SwapEndian(hid, eBigEndian); - SwapEndian(versionInfo, eBigEndian); - } - - if (hid != IDRESHEADER) - { - gEnv->pCryPak->FClose(fileHandle); - return false; - } - if (versionInfo.m_ResVersion != RESVERSION_DEBUG) - { - gEnv->pCryPak->FClose(fileHandle); - return false; - } - - float fVersion = FX_CACHE_VER; - char cacheVer[16] = {0}; - azsprintf(cacheVer, "Ver: %.1f", fVersion); - if (strcmp(cacheVer, versionInfo.m_szCacheVer)) - { - gEnv->pCryPak->FClose(fileHandle); - return false; - } - - m_VersionInfo = versionInfo; - - unsigned int uiCount; - gEnv->pCryPak->FReadRaw(&uiCount, sizeof(unsigned int), 1, fileHandle); - - if (bSwapEndianRead) - { - SwapEndian(uiCount, eBigEndian); - } - - CCryNameTSCRC name; - SDirEntry dirEntry; - CCryNameTSCRC dirEntryName; - unsigned int ui; - for (ui = 0; ui < uiCount; ++ui) - { - gEnv->pCryPak->FReadRaw(&name, sizeof(CCryNameTSCRC), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(name, eBigEndian); - } - - SResFileLookupDataDisk dirDataDisk; - -#ifndef USE_PARTIAL_ACTIVATION - - gEnv->pCryPak->FReadRaw(&dirDataDisk, sizeof(SResFileLookupDataDisk), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(dirDataDisk, eBigEndian); - } - SResFileLookupData dirData(dirDataDisk); - -#else - - gEnv->pCryPak->FReadRaw(&dirData.m_NumOfFilesUnique, sizeof(int), 1, fileHandle); - gEnv->pCryPak->FReadRaw(&dirData.m_NumOfFilesRef, sizeof(int), 1, fileHandle); - gEnv->pCryPak->FReadRaw(&dirData.m_OffsetDir, sizeof(uint32), 1, fileHandle); - gEnv->pCryPak->FReadRaw(&dirData.m_CRC32, sizeof(uint32), 1, fileHandle); - - if (bSwapEndianRead) - { - SwapEndian(dirData.m_NumOfFilesUnique, eBigEndian); - SwapEndian(dirData.m_NumOfFilesRef, eBigEndian); - SwapEndian(dirData.m_OffsetDir, eBigEndian); - SwapEndian(dirData.m_CRC32, eBigEndian); - } - - gEnv->pCryPak->FReadRaw(&dirData.m_ContainsResDir, sizeof(bool), 1, fileHandle); - unsigned int uiDirSize; - gEnv->pCryPak->FReadRaw(&uiDirSize, sizeof(unsigned int), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(uiDirSize, eBigEndian); - } - if (dirData.m_ContainsResDir) - { - dirData.m_resdir.reserve(uiDirSize); - for (unsigned int uj = 0; uj < uiDirSize; ++uj) - { - gEnv->pCryPak->FReadRaw(&dirEntry, sizeof(SDirEntry), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(dirEntry, eBigEndian); - } - dirData.m_resdir.push_back(dirEntry); - } - } - else - { - dirData.m_resdirlookup.reserve(uiDirSize); - for (unsigned int uj = 0; uj < uiDirSize; ++uj) - { - gEnv->pCryPak->FReadRaw(&dirEntryName, sizeof(CCryNameTSCRC), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(dirEntryName, eBigEndian); - } - dirData.m_resdirlookup.push_back(dirEntryName); - } - } -#endif - - m_Data[name] = dirData; - } - - gEnv->pCryPak->FReadRaw(&uiCount, sizeof(unsigned int), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(uiCount, eBigEndian); - } - for (ui = 0; ui < uiCount; ++ui) - { - gEnv->pCryPak->FReadRaw(&name, sizeof(CCryNameTSCRC), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(name, eBigEndian); - } - - SCFXLookupData CFXData; - gEnv->pCryPak->FReadRaw(&CFXData, sizeof(CFXData), 1, fileHandle); - if (bSwapEndianRead) - { - SwapEndian(CFXData, eBigEndian); - } - - m_CFXData[name] = CFXData; - } - - gEnv->pCryPak->FClose(fileHandle); - - return true; -} - -void CResFileLookupDataMan::SaveData( - const char* acFilename, bool bSwapEndianWrite) const -{ - // ignore invalid file access for lookupdata because it shouldn't be written - // when shaders no compile is set anyway - CDebugAllowFileAccess ignoreInvalidFileAccess; - - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(acFilename, "w+b"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return; - } - - using ByteStoreType = AZStd::vector; - ByteStoreType byteStore; - AZ::IO::ByteContainerStream byteStream(&byteStore); - - uint32 hid = IDRESHEADER; - - SVersionInfo versionInfo; - versionInfo.m_ResVersion = RES_COMPRESSION; - - float fVersion = FX_CACHE_VER; - azsprintf(versionInfo.m_szCacheVer, "Ver: %.1f", fVersion); - - if (bSwapEndianWrite) - { - SwapEndian(hid, eBigEndian); - SwapEndian(versionInfo, eBigEndian); - } - - byteStream.Write(&hid); - byteStream.Write(&versionInfo); - - unsigned int uiCount = m_Data.size(); - if (bSwapEndianWrite) - { - SwapEndian(uiCount, eBigEndian); - } - byteStream.Write(&uiCount); - - for (TFileResDirDataMap::const_iterator it = m_Data.begin(); it != m_Data.end(); ++it) - { - CCryNameTSCRC name = it->first; - if (bSwapEndianWrite) - { - SwapEndian(name, eBigEndian); - } - byteStream.Write(&name); - -#ifndef USE_PARTIAL_ACTIVATION - SResFileLookupDataDisk header(it->second); - if (bSwapEndianWrite) - { - SwapEndian(header, eBigEndian); - } - byteStream.Write(&header); -#else - const SResFileLookupData& header = it->second; - int numOfFilesUnique = header.m_NumOfFilesUnique; - int numOfFilesRef = header.m_NumOfFilesRef; - uint32 offsetDir = header.m_OffsetDir; - uint32 crc = header.m_CRC32; - if (bSwapEndianWrite) - { - SwapEndian(numOfFilesUnique, eBigEndian); - SwapEndian(numOfFilesRef, eBigEndian); - SwapEndian(offsetDir, eBigEndian); - SwapEndian(crc, eBigEndian); - } - byteStream.Write(&numOfFilesUnique); - byteStream.Write(&numOfFilesRef); - byteStream.Write(&offsetDir); - byteStream.Write(&crc); - - byteStream.Write(&header.m_ContainsResDir); - - if (header.m_ContainsResDir) - { - unsigned int uiDirSize = header.m_resdir.size(); - if (bSwapEndianWrite) - { - SwapEndian(uiDirSize, eBigEndian); - } - byteStream.Write(&uiDirSize); - - for (ResDir::const_iterator it2 = header.m_resdir.begin(); it2 != header.m_resdir.end(); ++it2) - { - SDirEntry dirEntry = *it2; - if (bSwapEndianWrite) - { - SwapEndian(dirEntry, eBigEndian); - } - byteStream.Write(&dirEntry); - } - } - else - { - unsigned int uiDirSize = header.m_resdirlookup.size(); - if (bSwapEndianWrite) - { - SwapEndian(uiDirSize, eBigEndian); - } - byteStream.Write(&uiDirSize); - - for (TResDirNames::const_iterator it2 = header.m_resdirlookup.begin(); it2 != header.m_resdirlookup.end(); ++it2) - { - CCryNameTSCRC dirEntryName = *it2; - if (bSwapEndianWrite) - { - SwapEndian(dirEntryName, eBigEndian); - } - byteStream.Write(&dirEntryName); - } - } -#endif - } - - uiCount = m_CFXData.size(); - if (bSwapEndianWrite) - { - SwapEndian(uiCount, eBigEndian); - } - byteStream.Write(&uiCount); - for (TFileCFXDataMap::const_iterator it = m_CFXData.begin(); it != m_CFXData.end(); ++it) - { - CCryNameTSCRC name = it->first; - if (bSwapEndianWrite) - { - SwapEndian(name, eBigEndian); - } - byteStream.Write(&name); - SCFXLookupData CFXData = it->second; - if (bSwapEndianWrite) - { - SwapEndian(CFXData, eBigEndian); - } - byteStream.Write(&CFXData); - } - - gEnv->pCryPak->FWrite(byteStream.GetData()->data(), byteStream.GetLength(), 1, fileHandle); - gEnv->pCryPak->FClose(fileHandle); -} - -void CResFileLookupDataMan::AddData(const CResFile* pResFile, uint32 CRC) -{ - if (pResFile == 0) - { - return; - } - - SResFileLookupData data; - - // store the dir data - data.m_OffsetDir = pResFile->m_nOffsDir; - data.m_NumOfFilesUnique = pResFile->m_nNumFilesUnique; - data.m_NumOfFilesRef = pResFile->m_nNumFilesRef; - - float fVersion = FX_CACHE_VER; - uint32 nMinor = (int)(((float)fVersion - (float)(int)fVersion) * 10.1f); - uint32 nMajor = (int)fVersion; - data.m_CacheMinorVer = nMinor; - data.m_CacheMajorVer = nMajor; - - data.m_CRC32 = CRC; - -#ifdef USE_PARTIAL_ACTIVATION - // create the lookup data for the resdir - if (pResFile->m_Dir.size() < 128) - { - data.m_ContainsResDir = true; - - m_TotalDirStored++; - - // just copy the whole vector - data.m_resdir = pResFile->m_Dir; - /* - data.m_resdir.reserve(pResFile->m_Dir.size()); - for (unsigned int ui = 0; ui < pResFile->m_Dir.size(); ++ui) - { - data.m_resdir.push_back(pResFile->m_Dir[0]); - } - memcpy(&data.m_resdir[0], &pResFile->m_Dir[0], sizeof(SDirEntry) * pResFile->m_Dir.size()); - */ - } - else - { - data.m_ContainsResDir = false; - - unsigned int entries = 0; - unsigned int entriesPerSlice = MAX_DIR_BUFFER_SIZE / sizeof(SDirEntry); - while ((entries * entriesPerSlice) < pResFile->m_Dir.size()) - { - data.m_resdirlookup.push_back(pResFile->m_Dir[entries * entriesPerSlice].Name); - entries++; - } - } -#endif - - const char* acOrigFilename = pResFile->mfGetFileName(); - AddDataCFX(acOrigFilename, CRC); - - // remove the user info, if available - CCryNameTSCRC name = AdjustName(acOrigFilename); - - // simply overwrite the data if it was already in here - m_Data[name] = data; -} - -void CResFileLookupDataMan::AddDataCFX(const char* acOrigFilename, uint32 CRC) -{ - char nm[256], nmDir[512]; -#ifdef AZ_COMPILER_MSVC - _splitpath_s(acOrigFilename, NULL, 0, nmDir, AZ_ARRAY_SIZE(nmDir), nm, AZ_ARRAY_SIZE(nm), NULL, 0); -#else - _splitpath(acOrigFilename, NULL, nmDir, nm, NULL); -#endif - { - char* s = strchr(nm, '@'); - //assert(s); - if (s) - { - s[0] = 0; - } - } - - CCryNameTSCRC nameCFX = nm; - SCFXLookupData CFX; - CFX.m_CRC32 = CRC; - m_CFXData[nameCFX] = CFX; -} - -void CResFileLookupDataMan::RemoveData(uint32 CRC) -{ - { - TFileResDirDataMap tmpData; - for (TFileResDirDataMap::iterator it = m_Data.begin(); it != m_Data.end(); ++it) - { - SResFileLookupData& data = it->second; - if (data.m_CRC32 != CRC) - { - tmpData[it->first] = data; - } - } - m_Data.swap(tmpData); - } - - { - TFileCFXDataMap tmpData; - for (TFileCFXDataMap::iterator it = m_CFXData.begin(); it != m_CFXData.end(); ++it) - { - SCFXLookupData& data = it->second; - if (data.m_CRC32 != CRC) - { - tmpData[it->first] = data; - } - } - m_CFXData.swap(tmpData); - } -} - -SResFileLookupData* CResFileLookupDataMan::GetData( - const CCryNameTSCRC& name) -{ - TFileResDirDataMap::iterator it = m_Data.find(name); - if (it == m_Data.end()) - { - return 0; - } - - return &it->second; -} -SCFXLookupData* CResFileLookupDataMan::GetDataCFX( - const char* szPath) -{ - char nm[256]; -#ifdef AZ_COMPILER_MSVC - _splitpath_s(szPath, NULL, 0, NULL, 0, nm, AZ_ARRAY_SIZE(nm), NULL, 0); -#else - _splitpath(szPath, NULL, NULL, nm, NULL); -#endif - CCryNameTSCRC name = nm; - TFileCFXDataMap::iterator it = m_CFXData.find(name); - if (it == m_CFXData.end()) - { - return 0; - } - - return &it->second; -} - -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.h b/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.h deleted file mode 100644 index 6089d7d86e..0000000000 --- a/Code/CryEngine/RenderDll/Common/ResFileLookupDataMan.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __RESFILELOOKUPDATAMAN_H__ -#define __RESFILELOOKUPDATAMAN_H__ - -#include "ResFile.h" - -typedef std::vector TResDirNames; - -struct SResFileLookupDataDisk -{ - int m_NumOfFilesUnique; - int m_NumOfFilesRef; - uint32 m_OffsetDir; - uint32 m_CRC32; - uint16 m_CacheMajorVer; - uint16 m_CacheMinorVer; - - SResFileLookupDataDisk() {} - SResFileLookupDataDisk(const struct SResFileLookupData& inLookup); - - AUTO_STRUCT_INFO -}; -struct SResFileLookupData -{ - int m_NumOfFilesUnique; - int m_NumOfFilesRef; - uint32 m_OffsetDir; - uint32 m_CRC32; - uint16 m_CacheMajorVer; - uint16 m_CacheMinorVer; - - SResFileLookupData() {} - SResFileLookupData(const SResFileLookupDataDisk& inLookup) - { - m_NumOfFilesUnique = inLookup.m_NumOfFilesUnique; - m_NumOfFilesRef = inLookup.m_NumOfFilesRef; - m_OffsetDir = inLookup.m_OffsetDir; - m_CRC32 = inLookup.m_CRC32; - m_CacheMajorVer = inLookup.m_CacheMajorVer; - m_CacheMinorVer = inLookup.m_CacheMinorVer; - } - -#ifdef USE_PARTIAL_ACTIVATION - bool m_ContainsResDir; - - TResDirNames m_resdirlookup; - ResDir m_resdir; - - unsigned int GetDirOffset(const CCryNameTSCRC& dirEntryName) const; -#endif -}; - -struct SCFXLookupData -{ - uint32 m_CRC32; - SCFXLookupData() {} - AUTO_STRUCT_INFO -}; - -#define MAX_DIR_BUFFER_SIZE 300000 - -typedef std::map TFileResDirDataMap; -typedef std::map TFileCFXDataMap; - -class CResFile; - -struct SVersionInfo -{ - SVersionInfo() - : m_ResVersion(0) - { memset(m_szCacheVer, 0, sizeof(m_szCacheVer)); } - - int m_ResVersion; - char m_szCacheVer[16]; - - AUTO_STRUCT_INFO -}; - -class CResFileLookupDataMan -{ -public: - CResFileLookupDataMan(); - ~CResFileLookupDataMan(); - - void Clear(); - void Flush(); - - CCryNameTSCRC AdjustName(const char* szName); - int GetResVersion() const { return m_VersionInfo.m_ResVersion; } - - bool LoadData(const char* acFilename, bool bSwapEndianRead, bool bReadOnly); - void SaveData(const char* acFilename, bool bSwapEndianWrite) const; - - bool IsReadOnly() { return m_bReadOnly; } - - void AddData(const CResFile* pResFile, uint32 CRC); - void AddDataCFX(const char* szPath, uint32 CRC); - void RemoveData(uint32 CRC); - - SResFileLookupData* GetData(const CCryNameTSCRC& name); - SCFXLookupData* GetDataCFX(const char* szPath); - void MarkDirty(bool bDirty) { m_bDirty = bDirty; } - - -protected: - - string m_Path; - SVersionInfo m_VersionInfo; - TFileResDirDataMap m_Data; - TFileCFXDataMap m_CFXData; - unsigned int m_TotalDirStored; - byte m_bDirty : 1; - byte m_bReadOnly : 1; -}; - -#endif // __RESFILELOOKUPDATAMAN_H__ diff --git a/Code/CryEngine/RenderDll/Common/ResFile_info.h b/Code/CryEngine/RenderDll/Common/ResFile_info.h deleted file mode 100644 index 9390eccd1a..0000000000 --- a/Code/CryEngine/RenderDll/Common/ResFile_info.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RESFILE_INFO_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RESFILE_INFO_H -#pragma once - -#include "ResFile.h" - -STRUCT_INFO_BEGIN(SFileResHeader) -STRUCT_VAR_INFO(hid, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(ver, TYPE_INFO(int)) -STRUCT_VAR_INFO(num_files, TYPE_INFO(int)) -//STRUCT_VAR_INFO(num_files_ref, TYPE_INFO(int)) -STRUCT_VAR_INFO(ofs_dir, TYPE_INFO(int)) -STRUCT_VAR_INFO(num_files_ref, TYPE_INFO(uint32)) -STRUCT_INFO_END(SFileResHeader) - -STRUCT_INFO_BEGIN(SResFileLookupDataDisk) -STRUCT_VAR_INFO(m_NumOfFilesUnique, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_NumOfFilesRef, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_OffsetDir, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_CRC32, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_CacheMajorVer, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_CacheMinorVer, TYPE_INFO(uint16)) -STRUCT_INFO_END(SResFileLookupDataDisk) - -STRUCT_INFO_BEGIN(SCFXLookupData) -STRUCT_VAR_INFO(m_CRC32, TYPE_INFO(uint32)) -STRUCT_INFO_END(SCFXLookupData) - -STRUCT_INFO_BEGIN(CCryNameTSCRC) -STRUCT_VAR_INFO(m_nID, TYPE_INFO(int)) -STRUCT_INFO_END(CCryNameTSCRC) - -STRUCT_INFO_BEGIN(SDirEntry) -STRUCT_VAR_INFO(Name, TYPE_INFO(CCryNameTSCRC)) -STRUCT_BITFIELD_INFO(size, TYPE_INFO(uint32), 24) -STRUCT_BITFIELD_INFO(flags, TYPE_INFO(uint32), 8) -STRUCT_VAR_INFO(offset, TYPE_INFO(int32)) -STRUCT_INFO_END(SDirEntry) - -STRUCT_INFO_BEGIN(SDirEntryRef) -STRUCT_VAR_INFO(Name, TYPE_INFO(CCryNameTSCRC)) -STRUCT_VAR_INFO(ref, TYPE_INFO(uint32)) -STRUCT_INFO_END(SDirEntryRef) - -STRUCT_INFO_BEGIN(SShaderBinHeader) -STRUCT_VAR_INFO(m_Magic, TYPE_INFO(FOURCC)) -STRUCT_VAR_INFO(m_CRC32, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_VersionLow, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_VersionHigh, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_nOffsetStringTable, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nOffsetParamsLocal, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nTokens, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nSourceCRC32, TYPE_INFO(uint32)) -STRUCT_INFO_END(SShaderBinHeader) - -STRUCT_INFO_BEGIN(SShaderBinParamsHeader) -STRUCT_VAR_INFO(nMask, TYPE_INFO(uint64)) -STRUCT_VAR_INFO(nstaticMask, TYPE_INFO(uint64)) -STRUCT_VAR_INFO(nName, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(nParams, TYPE_INFO(int32)) -STRUCT_VAR_INFO(nFuncs, TYPE_INFO(int32)) -STRUCT_INFO_END(SShaderBinParamsHeader) - -STRUCT_INFO_BEGIN(SVersionInfo) -STRUCT_VAR_INFO(m_ResVersion, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_szCacheVer, TYPE_ARRAY(16, TYPE_INFO(char))) -STRUCT_INFO_END(SVersionInfo) - -#if defined(SHADERS_SERIALIZING) - -STRUCT_INFO_BEGIN(SSShaderCacheHeader) -STRUCT_VAR_INFO(m_SizeOf, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_szVer, TYPE_ARRAY(16, TYPE_INFO(char))) -STRUCT_VAR_INFO(m_MajorVer, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_MinorVer, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_CRC32, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_SourceCRC32, TYPE_INFO(uint32)) -STRUCT_INFO_END(SSShaderCacheHeader) - -#endif - -STRUCT_INFO_BEGIN(SShaderCacheHeaderItem) -STRUCT_VAR_INFO(m_nVertexFormat, TYPE_INFO(byte)) -STRUCT_VAR_INFO(m_Class, TYPE_INFO(byte)) -STRUCT_VAR_INFO(m_nInstBinds, TYPE_INFO(byte)) -STRUCT_VAR_INFO(m_StreamMask_Stream, TYPE_INFO(byte)) -STRUCT_VAR_INFO(m_StreamMask_Decl, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(m_nInstructions, TYPE_INFO(short)) -STRUCT_VAR_INFO(m_CRC32, TYPE_INFO(uint32)) -//STRUCT_VAR_INFO(m_DeviceObjectID, TYPE_INFO(int)) -STRUCT_INFO_END(SShaderCacheHeaderItem) - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_RESFILE_INFO_H diff --git a/Code/CryEngine/RenderDll/Common/ReverseDepth.h b/Code/CryEngine/RenderDll/Common/ReverseDepth.h deleted file mode 100644 index f5107b8483..0000000000 --- a/Code/CryEngine/RenderDll/Common/ReverseDepth.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __REVERSE_DEPTH_H__ -#define __REVERSE_DEPTH_H__ - -//#include "Cry_Matrix44.h" - -struct ReverseDepthHelper -{ - static Matrix44 Convert(const Matrix44& m) - { - Matrix44 result = m; - result.m02 = -m.m02 + m.m03; - result.m12 = -m.m12 + m.m13; - result.m22 = -m.m22 + m.m23; - result.m32 = -m.m32 + m.m33; - - return result; - } - - static D3DViewPort Convert(const D3DViewPort& vp) - { - D3DViewPort result = vp; - result.MinDepth = 1.0f - vp.MaxDepth; - result.MaxDepth = 1.0f - vp.MinDepth; - - return result; - } - - static uint32 ConvertDepthFunc(uint32 nState) - { - uint32 nDepthFuncRemapped = nState & GS_DEPTHFUNC_MASK; - - switch (nState & GS_DEPTHFUNC_MASK) - { - case GS_DEPTHFUNC_LESS: - nDepthFuncRemapped = GS_DEPTHFUNC_GREAT; - break; - - case GS_DEPTHFUNC_LEQUAL: - nDepthFuncRemapped = GS_DEPTHFUNC_GEQUAL; - break; - - case GS_DEPTHFUNC_GREAT: - nDepthFuncRemapped = GS_DEPTHFUNC_LESS; - break; - - case GS_DEPTHFUNC_GEQUAL: - nDepthFuncRemapped = GS_DEPTHFUNC_LEQUAL; - break; - } - - nState &= ~GS_DEPTHFUNC_MASK; - nState |= nDepthFuncRemapped; - - return nState; - } -}; - -#endif // __REVERSE_DEPTH_H__ diff --git a/Code/CryEngine/RenderDll/Common/Shaders/CShader.h b/Code/CryEngine/RenderDll/Common/Shaders/CShader.h deleted file mode 100644 index ea47769e6d..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/CShader.h +++ /dev/null @@ -1,702 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CSHADER_H__ -#define __CSHADER_H__ - -#include "CShaderBin.h" -#include "ShaderSerialize.h" -#include "ShaderCache.h" -#include "../ResFileLookupDataMan.h" - -#include -#include - -#include - -struct SRenderBuf; -class CRendElementBase; -struct SEmitter; -struct SParticleInfo; -struct SPartMoveStage; -struct SSunFlare; - -//=================================================================== - -#define MAX_ENVLIGHTCUBEMAPS 16 -#define ENVLIGHTCUBEMAP_SIZE 16 -#define MAX_ENVLIGHTCUBEMAPSCANDIST_UPDATE 16 -#define MAX_ENVLIGHTCUBEMAPSCANDIST_THRESHOLD 2 - -#define MAX_ENVCUBEMAPS 16 -#define MAX_ENVCUBEMAPSCANDIST_THRESHOLD 1 - -#define MAX_ENVTEXTURES 16 -#define MAX_ENVTEXSCANDIST 0.1f - -//=============================================================================== - -struct SMacroFX -{ - string m_szMacro; - uint32 m_nMask; -}; - -typedef AZStd::unordered_map, stl::equality_string > FXMacro; - -typedef FXMacro::iterator FXMacroItor; - -////////////////////////////////////////////////////////////////////////// -// Helper class for shader parser, holds temporary strings vector etc... -////////////////////////////////////////////////////////////////////////// -struct CShaderParserHelper -{ - CShaderParserHelper() - { - } - ~CShaderParserHelper() - { - } - - char* GetTempStringArray(int nIndex, int nLen) - { - m_tempString.reserve(nLen + 1); - return (char*)&(m_tempStringArray[nIndex])[0]; - } - - std::vector m_tempStringArray[32]; - std::vector m_tempString; -}; -extern CShaderParserHelper* g_pShaderParserHelper; - -enum EShaderFlagType -{ - eSFT_Global = 0, - eSFT_Runtime, - eSFT_MDV, - eSFT_LT, -}; - -enum EShaderFilterOperation -{ - eSFO_Expand = 0, // expand all permutations of the mask - eSFO_And, // and against the mask - eSFO_Eq, // set the mask -}; - -// includes or excludes -struct CShaderListFilter -{ - CShaderListFilter() - : m_bInclude(true) - {} - - bool m_bInclude; - string m_ShaderName; - - struct Predicate - { - Predicate() - : m_Negated(false) - , m_Flags(eSFT_Global) - , m_Op(eSFO_And) - , m_Mask(0) - {} - - bool m_Negated; - EShaderFlagType m_Flags; - EShaderFilterOperation m_Op; - uint64 m_Mask; - }; - std::vector m_Predicates; -}; - -//============================================================================== - -#define PD_INDEXED 1 -#define PD_MERGED 4 - -//============================================================================== -// [Shader System] - the following structures represent the raw data parsed from -// the shaders. It is in a way part of a processor semi reflection mechanism. -// To Do: inherit and share usage -//------------------------------------------------------------------------------ -struct SParamDB -{ - const char* szName; - const char* szAliasName; - ECGParam eParamType; - uint32 nFlags; - void (* ParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGParam* vpp, int nComp, CShader* ef); - SParamDB() - : szName(nullptr) - , szAliasName(nullptr) - , eParamType(ECGP_Unknown) - , nFlags(0) - , ParserFunc(nullptr) - { - } - SParamDB(const char* inName, ECGParam ePrmType, uint32 inFlags) - { - szName = inName; - szAliasName = NULL; - nFlags = inFlags; - ParserFunc = NULL; - eParamType = ePrmType; - } - SParamDB(const char* inName, ECGParam ePrmType, uint32 inFlags, void (*InParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGParam * vpp, int nComp, CShader * ef)) - { - szName = inName; - szAliasName = NULL; - nFlags = inFlags; - ParserFunc = InParserFunc; - eParamType = ePrmType; - } -}; - -struct SSamplerDB -{ - const char* szName; - ECGSampler eSamplerType; - uint32 nFlags; - void (* ParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGSampler* vpp, CShader* ef); - SSamplerDB() - { - szName = NULL; - nFlags = 0; - ParserFunc = NULL; - eSamplerType = ECGS_Unknown; - } - SSamplerDB(const char* inName, ECGSampler ePrmType, uint32 inFlags) - { - szName = inName; - nFlags = inFlags; - ParserFunc = NULL; - eSamplerType = ePrmType; - } - SSamplerDB(const char* inName, ECGSampler ePrmType, uint32 inFlags, void (*InParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGSampler * vpp, CShader * ef)) - { - szName = inName; - nFlags = inFlags; - ParserFunc = InParserFunc; - eSamplerType = ePrmType; - } -}; - -//------------------------------------------------------------------------------ -// [Shaders System] -// szName- a texture functional name which is only used here - possibly obsolete. -// The texture type is not a type but a slot mapping - should be changed -// nFlags- does not seem to be in use. Should be tested if used / removed if possible. -// ParserFunc - is not set anywhere and should be removed. -//------------------------------------------------------------------------------ -struct STextureDB -{ - const char* szName; - ECGTexture eTextureType; - uint32 nFlags; - void (* ParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGTexture* vpp, CShader* ef); - STextureDB() - { - szName = NULL; - nFlags = 0; - ParserFunc = NULL; - eTextureType = ECGT_Unknown; - } - STextureDB(const char* inName, ECGTexture ePrmType, uint32 inFlags) - { - szName = inName; - nFlags = inFlags; - ParserFunc = NULL; - eTextureType = ePrmType; - } - STextureDB(const char* inName, ECGTexture ePrmType, uint32 inFlags, void (*InParserFunc)(const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGTexture * vpp, CShader * ef)) - { - szName = inName; - nFlags = inFlags; - ParserFunc = InParserFunc; - eTextureType = ePrmType; - } -}; - - -enum EShaderCacheMode -{ - eSC_Normal = 0, - eSC_BuildGlobal = 2, - eSC_BuildGlobalList = 3, - eSC_Preactivate = 4, -}; - -enum EShaderLanguage -{ - eSL_Unknown, - eSL_Orbis, - eSL_D3D11, - eSL_GL4_1, - eSL_GL4_4, - eSL_GLES3_0, - eSL_GLES3_1, - eSL_METAL, - eSL_Jasper, - - eSL_MAX -}; - -EShaderLanguage GetShaderLanguage(); - -const char *GetShaderLanguageName(); - -const char *GetShaderLanguageResourceName(); - -AZStd::string GetShaderListFilename(); - -////////////////////////////////////////////////////////////////////////// -class CShaderMan - : public ISystemEventListener -#if defined(SHADERS_SERIALIZING) - , public CShaderSerialize -#endif - , public Terrain::TerrainShaderRequestBus::Handler - , public AZ::MaterialNotificationEventBus::Handler -{ - friend class CShader; - friend class CParserBin; - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - - void OnShaderLoaded(IShader* shader) override; - -private: - CTexAnim* mfReadTexSequence(const char *name, int Flags, bool bFindOnly); - int mfReadTexSequence(STexSamplerRT* smp, const char* name, int Flags, bool bFindOnly); - - CShader* mfNewShader(const char* szName); - - void mfCompileLevelsList(std::vector& List, char* scr); - bool mfCompileShaderLevelPolicies(SShaderLevelPolicies* pPL, char* scr); - bool mfCompileShaderGen(SShaderGen* shg, char* scr); - SShaderGenBit* mfCompileShaderGenProperty(char* scr); - - void mfSetResourceTexState(SEfResTexture* Tex); - CTexture* mfTryToLoadTexture(const char* nameTex, STexSamplerRT* smp, int Flags, bool bFindOnly); - CTexture* mfFindResourceTexture(const char* nameTex, const char* path, int Flags, SEfResTexture* Tex); - CTexture* mfLoadResourceTexture(const char* nameTex, const char* path, int Flags, SEfResTexture* Tex); - - - bool mfLoadResourceTexture(ResourceSlotIndex Id, SInputShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail = false); - bool mfLoadResourceTexture(ResourceSlotIndex Id, CShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail = false); - - void mfLoadDefaultTexture(ResourceSlotIndex Id, CShaderResources& RS, EEfResTextures Alias); - - void mfCheckShaderResTextures(TArray& Dst, CShader* ef, CShaderResources* Res); - void mfCheckShaderResTexturesHW(TArray& Dst, CShader* ef, CShaderResources* Res); - CTexture* mfCheckTemplateTexName(const char* mapname, ETEX_Type eTT); - - CShader* mfCompile(CShader* ef, char* scr); - - bool mfUpdateMergeStatus(SShaderTechnique* hs, std::vector* p); - void mfRefreshResources(CShaderResources* Res); - - bool mfReloadShaderFile(const char* szName, int nFlags); -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - bool CheckAllFilesAreWritable(const char* szDir) const; -#endif - - AZStd::mutex m_shaderLoadMutex; - -public: - char* m_pCurScript; - CShaderManBin m_Bin; - CResFileLookupDataMan m_ResLookupDataMan[2]; // CACHE_READONLY, CACHE_USER - - const char* mfTemplateTexIdToName(int Id); - SShaderGenComb* mfGetShaderGenInfo(const char* nmFX); - - bool mfReloadShaderIncludes(const char* szPath, int nFlags); - bool mfReloadAllShaders(int nFlags, uint32 nFlagsHW); - bool mfReloadFile(const char* szPath, const char* szName, int nFlags); - - void ParseShaderProfiles(); - void ParseShaderProfile(char* scr, SShaderProfile* pr); - - EEfResTextures mfCheckTextureSlotName(const char* mapname); - SParamDB* mfGetShaderParamDB(const char* szSemantic); - const char* mfGetShaderParamName(ECGParam ePR); - - bool mfParseParamComp(int comp, SCGParam* pCurParam, const char* szSemantic, char* params, const char* szAnnotations, SShaderFXParams& FXParams, CShader* ef, uint32 nParamFlags, EHWShaderClass eSHClass, bool bExpressionOperand); - bool mfParseCGParam(char* scr, const char* szAnnotations, SShaderFXParams& FXParams, CShader* ef, std::vector* pParams, int nComps, uint32 nParamFlags, EHWShaderClass eSHClass, bool bExpressionOperand); - bool mfParseFXParameter(SShaderFXParams& FXParams, SFXParam* pr, const char* ParamName, CShader* ef, bool bInstParam, int nParams, std::vector* pParams, EHWShaderClass eSHClass, bool bExpressionOperand); - - bool mfParseFXTexture(SShaderFXParams& FXParams, SFXTexture* pr, const char* ParamName, CShader* ef, int nParams, std::vector* pParams, EHWShaderClass eSHClass); - bool mfParseFXSampler(SShaderFXParams& FXParams, SFXSampler* pr, const char* ParamName, CShader* ef, int nParams, std::vector* pParams, EHWShaderClass eSHClass); - - void mfCheckObjectDependParams(std::vector& PNoObj, std::vector& PObj, EHWShaderClass eSH, CShader* pFXShader); - - void mfBeginFrame(); - - void mfGetShaderListPath(stack_string& nameOut, int nType); - -public: - bool m_bInitialized; - bool m_bLoadedSystem; - - AZStd::string m_ShadersPath; - AZStd::string m_ShadersCache; - AZStd::string m_ShadersFilter; - AZStd::string m_ShadersMergeCachePath; - AZStd::string m_szCachePath; - - int m_nFrameForceReload; - - char m_HWPath[128]; - - CShader* m_pCurShader; - static SResourceContainer* s_pContainer; // List/Map of objects for shaders resource class - - std::vector m_ShaderNames; - - static CCryNameTSCRC s_cNameHEAD; - - static CShader* s_DefaultShader; - static CShader* s_shPostEffects; // engine specific post process effects - static CShader* s_shPostDepthOfField; // depth of field - static CShader* s_shPostMotionBlur; - static CShader* s_shPostSunShafts; - - // Deferred rendering passes - static CShader* s_shDeferredShading; - static CShader* s_ShaderDeferredCaustics; - static CShader* s_ShaderDeferredRain; - static CShader* s_ShaderDeferredSnow; - -#ifndef NULL_RENDERER - static CShader* s_ShaderFPEmu; - static CShader* s_ShaderUI; - static CShader* s_ShaderFallback; - static CShader* s_ShaderStars; - static CShader* s_ShaderShadowBlur; - static CShader* s_ShaderShadowMaskGen; -#if defined(FEATURE_SVO_GI) - static CShader* s_ShaderSVOGI; -#endif - static CShader* s_shHDRPostProcess; - static CShader* s_shPostEffectsGame; // game specific post process effects - static CShader* s_shPostAA; - static CShader* s_ShaderDebug; - static CShader* s_ShaderLensOptics; - static CShader* s_ShaderSoftOcclusionQuery; - static CShader* s_ShaderLightStyles; - static CShader* s_ShaderCommon; - static CShader* s_ShaderOcclTest; - static CShader* s_ShaderDXTCompress; - static CShader* s_ShaderStereo; - static CShader* s_ShaderFur; - static CShader* s_ShaderVideo; -#else - static SShaderItem s_DefaultShaderItem; -#endif - - AZStd::unordered_set m_systemShaders; - - const SInputShaderResources* m_pCurInputResources; - SShaderGen* m_pGlobalExt; - SShaderGen* m_staticExt; // Shader gen info for static flags (Statics.ext) - uint64 m_staticFlags; // Enabled global flags used for generating the shaders. - SShaderLevelPolicies* m_pLevelsPolicies; - - Vec4 m_TempVecs[16]; - Vec4 m_RTRect; - std::vector m_SGC; - - int m_nCombinationsProcess; - int m_nCombinationsProcessOverall; - int m_nCombinationsCompiled; - int m_nCombinationsEmpty; - - EShaderCacheMode m_eCacheMode; - - bool m_bActivatePhase; - const char* m_szShaderPrecache; - - FXShaderCacheCombinations m_ShaderCacheCombinations[2]; - FXShaderCacheCombinations m_ShaderCacheExportCombinations; - AZ::IO::HandleType m_FPCacheCombinations[2]; - - typedef std::vector ShaderCacheMissesVec; - ShaderCacheMissesVec m_ShaderCacheMisses; - string m_ShaderCacheMissPath; - ShaderCacheMissCallback m_ShaderCacheMissCallback; - - SShaderCacheStatistics m_ShaderCacheStats; - - uint32 m_nFrameLastSubmitted; - uint32 m_nFrameSubmit; - SShaderProfile m_ShaderProfiles[eST_Max]; - SShaderProfile m_ShaderFixedProfiles[eSQ_Max]; - - int m_bActivated; - - CShaderParserHelper m_shaderParserHelper; - - bool m_bReload; - - - // Shared common global flags data - - // Map used for storing automatically-generated flags and mapping old shader names masks to generated ones - // map< shader flag names, mask > - typedef std::map< string, uint64 > MapNameFlags; - typedef MapNameFlags::iterator MapNameFlagsItor; - MapNameFlags m_pShaderCommonGlobalFlag; - - MapNameFlags m_pSCGFlagLegacyFix; - uint64 m_nSGFlagsFix; - - // Map stored for convenience mapping betweens old flags and new ones - // map < shader name , map< shader flag names, mask > > - typedef std::map< string, MapNameFlags* > ShaderMapNameFlags; - typedef ShaderMapNameFlags::iterator ShaderMapNameFlagsItor; - ShaderMapNameFlags m_pShadersGlobalFlags; - - typedef std::map ShaderExt; - typedef ShaderExt::iterator ShaderExtItor; - ShaderExt m_ShaderExts; - PerFrameParameters m_PF; - - // Concatenated list of shader names using automatic masks generation - string m_pShadersRemapList; - - // Helper functors for cleaning up - - struct SShaderMapNameFlagsContainerDelete - { - void operator()(ShaderMapNameFlags::value_type& pObj) - { - SAFE_DELETE(pObj.second); - } - }; - -public: - CShaderMan() - { - m_bInitialized = false; - m_bLoadedSystem = false; - s_DefaultShader = NULL; - m_pGlobalExt = NULL; - m_staticExt = nullptr; - m_staticFlags = 0; - g_pShaderParserHelper = &m_shaderParserHelper; - m_nCombinationsProcess = -1; - m_nCombinationsProcessOverall = -1; - m_nCombinationsCompiled = -1; - m_nCombinationsEmpty = -1; - m_szShaderPrecache = NULL; - memset(m_TempVecs, 0, sizeof(Vec4) * 16); - memset(&m_RTRect, 0, sizeof(Vec4)); - m_eCacheMode = eSC_Normal; - m_nFrameSubmit = 1; - - Terrain::TerrainShaderRequestBus::Handler::BusConnect(); - AZ::MaterialNotificationEventBus::Handler::BusConnect(); - } - - void ShutDown(); - void mfReleaseShaders(); - - SShaderGen* mfCreateShaderGenInfo(const char* szName, bool bRuntime); - void mfRemapShaderGenInfoBits(const char* szName, SShaderGen* pShGen); - - uint64 mfGetRemapedShaderMaskGen(const char* szName, uint64 nMaskGen = 0, bool bFixup = 0); - string mfGetShaderBitNamesFromMaskGen(const char* szName, uint64 nMaskGen); - - bool mfUsesGlobalFlags(const char* szShaderName); - AZStd::string mfGetShaderBitNamesFromGlobalMaskGen(uint64 nMaskGen); - uint64 mfGetShaderGlobalMaskGenFromString(const char* szShaderGen); - - void mfInitGlobal(void); - void mfInitLevelPolicies(void); - void mfInitLookups(void); - - void InitStaticFlags(); - void AddStaticFlag(EHWSSTFlag flag); - void RemoveStaticFlag(EHWSSTFlag flag); - bool HasStaticFlag(EHWSSTFlag flag); - - void mfPreloadShaderExts(void); - void mfInitCommonGlobalFlags(void); - void mfInitCommonGlobalFlagsLegacyFix(void); - bool mfRemapCommonGlobalFlagsWithLegacy(void); - void mfCreateCommonGlobalFlags(const char* szName); - void mfSaveCommonGlobalFlagsToDisk(const char* szName, uint32 nMaskCount); - - void mfInit(void); - void mfPostInit(void); - void mfSortResources(); - CShaderResources* mfCreateShaderResources(const SInputShaderResources* Res, bool bShare); - bool mfRefreshResourceConstants(CShaderResources* Res); - inline bool mfRefreshResourceConstants(SShaderItem& SI) { return mfRefreshResourceConstants((CShaderResources*)SI.m_pShaderResources); } - bool mfUpdateTechnik (SShaderItem& SI, CCryNameTSCRC& Name); - SShaderItem mfShaderItemForName (const char* szName, bool bShare, int flags, SInputShaderResources* Res = NULL, uint64 nMaskGen = 0); - CShader* mfForName (const char* name, int flags, const CShaderResources* Res = NULL, uint64 nMaskGen = 0); - - bool mfRefreshSystemShader(const char* szName, CShader*& pSysShader) - { - if (!pSysShader) - { - CryComment("Load System Shader (refresh) '%s'...", szName); - - pSysShader = mfForName(szName, EF_SYSTEM); - if (pSysShader) - { - if (pSysShader->m_Flags & EF_NOTFOUND) - { - pSysShader = NULL; - CryComment("Load System Shader Failed %s", szName); - return false; - } - CryComment("ok"); - m_systemShaders.emplace(pSysShader); - return true; - } - } - - return false; - } - - void RT_ParseShader(CShader* pSH, uint64 nMaskGen, uint32 flags, CShaderResources* Res); - void RT_SetShaderQuality(EShaderType eST, EShaderQuality eSQ); - - void CreateShaderMaskGenString(const CShader* pSH, stack_string& flagString); - void CreateShaderExportRequestLine(const CShader* pSH, stack_string& exportString); - - SFXParam* mfGetFXParameter(std::vector& Params, const char* param); - SFXSampler* mfGetFXSampler(std::vector& Params, const char* param); - SFXTexture* mfGetFXTexture(std::vector& Params, const char* param); - const char* mfParseFX_Parameter (const string& buf, EParamType eType, const char* szName); - void mfParseFX_Annotations_Script (char* buf, CShader * ef, std::vector&Structs, bool* bPublic, CCryNameR techStart[2]); - void mfParseFX_Annotations (char* buf, CShader * ef, std::vector&Structs, bool* bPublic, CCryNameR techStart[2]); - void mfParseFXTechnique_Annotations_Script (char* buf, CShader* ef, std::vector& Structs, SShaderTechnique* pShTech, bool* bPublic, std::vector& techParams); - void mfParseFXTechnique_Annotations (char* buf, CShader* ef, std::vector& Structs, SShaderTechnique* pShTech, bool* bPublic, std::vector& techParams); - void mfParseFXSampler_Annotations_Script (char* buf, CShader* ef, std::vector& Structs, STexSamplerFX* pSamp); - void mfParseFXSampler_Annotations (char* buf, CShader* ef, std::vector& Structs, STexSamplerFX* pSamp); - void mfParseFX_Global (SFXParam & pr, CShader * ef, std::vector&Structs, CCryNameR techStart[2]); - bool mfParseDummyFX_Global (std::vector&Structs, char* annot, CCryNameR techStart[2]); - const string& mfParseFXTechnique_GenerateShaderScript (std::vector& Structs, FXMacro& Macros, std::vector& Params, std::vector& AffectedParams, const char* szEntryFunc, CShader* ef, EHWShaderClass eSHClass, const char* szShaderName, uint32& nAffectMask, const char* szType); - bool mfParseFXTechnique_MergeParameters (std::vector& Structs, std::vector& Params, std::vector& AffectedFunc, SFXStruct* pMainFunc, CShader* ef, EHWShaderClass eSHClass, const char* szShaderName, std::vector& NewParams); - CTexture* mfParseFXTechnique_LoadShaderTexture (STexSamplerRT* smp, const char* szName, SShaderPass* pShPass, CShader* ef, int nIndex, byte ColorOp, byte AlphaOp, byte ColorArg, byte AlphaArg); - bool mfParseFXTechnique_LoadShader (const char* szShaderCom, SShaderPass* pShPass, CShader* ef, std::vector& Samplers, std::vector& Structs, std::vector& Params, FXMacro& Macros, EHWShaderClass eSHClass); - bool mfParseFXTechniquePass (char* buf, char* annotations, SShaderTechnique* pShTech, CShader* ef, std::vector& Samplers, std::vector& Structs, std::vector& Params); - bool mfParseFXTechnique_CustomRE (char* buf, const char* name, SShaderTechnique* pShTech, CShader* ef); - SShaderTechnique* mfParseFXTechnique (char* buf, char* annotations, CShader* ef, std::vector& Samplers, std::vector& Structs, std::vector& Params, bool* bPublic, std::vector& techParams); - bool mfParseFXSampler(char* buf, char* name, char* annotations, CShader* ef, std::vector& Samplers, std::vector& Structs); - bool mfParseLightStyle(CLightStyle* ls, char* buf); - bool mfParseFXLightStyle(char* buf, int nID, CShader* ef, std::vector& Structs); - CShader* mfParseFX (char* buf, CShader* ef, CShader* efGen, uint64 nMaskGen); - void mfPostLoadFX(CShader * efT, std::vector&techParams, CCryNameR techStart[2]); - bool mfParseDummyFX(char* buf, std::vector& ShaderNames, const char* szName); - bool mfAddFXShaderNames(const char* szName, std::vector* ShaderNames, bool bUpdateCRC); - bool mfInitShadersDummy(bool bUpdateCRC); - - uint64 mfGetRTForName(char* buf); - uint32 mfGetGLForName(char* buf, CShader* ef); - - void mfFillGenMacroses(SShaderGen* shG, TArray& buf, uint64 nMaskGen); - bool mfModifyGenFlags(CShader* efGen, const CShaderResources* pRes, uint64& nMaskGen, uint64& nMaskGenHW); - - bool mfGatherShadersList(const char* szPath, bool bCheckIncludes, bool bUpdateCRC, std::vector* Names); - void mfGatherFilesList(const char* szPath, std::vector& Names, int nLevel, bool bUseFilter, bool bMaterial = false); - int mfInitShadersList(std::vector* ShaderNames); - void mfSetDefaults(void); - void mfLoadSystemShader(const char* szName, CShader*& pStorage); - void mfReleaseSystemShaders (); - void mfLoadBasicSystemShaders (); - void mfLoadDefaultSystemShaders (); - void mfCloseShadersCache(int nID); - void mfInitShadersCacheMissLog(); - - void mfInitShadersCache(byte bForLevel, FXShaderCacheCombinations* Combinations = NULL, const char* pCombinations = NULL, int nType = 0); - void mfMergeShadersCombinations(FXShaderCacheCombinations* Combinations, int nType); - void mfInsertNewCombination(SShaderCombIdent& Ident, EHWShaderClass eCL, const char* name, int nID, string* Str = NULL, byte bStore = 1); - const char* mfGetLevelListName() const; - void mfExportShaders(); - - bool mfReleasePreactivatedShaderData(); - bool mfPreactivateShaders2(const char* szPak, const char* szPath, bool bPersistent, const char* szBindRoot); - bool mfPreactivate2(CResFileLookupDataMan& LevelLookup, const AZStd::string& pathPerLevel, const AZStd::string& pathGlobal, bool bVS, bool bPersistent); - - bool mfPreloadBinaryShaders(); - - bool LoadShaderStartupCache(); - void UnloadShaderStartupCache(); - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - void AddCombination(SCacheCombination& cmb, FXShaderCacheCombinations& CmbsMap, CHWShader* pHWS); - void AddGLCombinations(CShader* pSH, std::vector& CmbsGL); - void AddLTCombinations(SCacheCombination& cmb, FXShaderCacheCombinations& CmbsMap, CHWShader* pHWS); - void AddRTCombinations(FXShaderCacheCombinations& CmbsMap, CHWShader* pHWS, CShader* pSH, FXShaderCacheCombinations* Combinations); - void AddGLCombination(FXShaderCacheCombinations& CmbsMap, SCacheCombination& cc); - void FilterShaderCombinations(std::vector& Cmbs, const std::vector& Filters); - void mfPrecacheShaders(bool bStatsOnly); - void mfGetShaderList(); - void _PrecacheShaderList(bool bStatsOnly); - void mfOptimiseShaders(const char* szFolder, bool bForce); - void mfMergeShaders(); - void _MergeShaders(); - void mfAddRTCombinations(FXShaderCacheCombinations& CmbsMapSrc, FXShaderCacheCombinations& CmbsMapDst, CHWShader* pSH, bool bListOnly); - void mfAddRTCombination_r(int nComb, FXShaderCacheCombinations& CmbsMapDst, SCacheCombination* cmb, CHWShader* pSH, bool bAutoPrecache); - void mfAddLTCombinations(SCacheCombination* cmb, FXShaderCacheCombinations& CmbsMapDst); - void mfAddLTCombination(SCacheCombination* cmb, FXShaderCacheCombinations& CmbsMapDst, DWORD dwL); -#endif - - int Size() - { - int nSize = sizeof(*this); - - nSize += m_SGC.capacity(); - nSize += m_Bin.Size(); - - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_Bin); - pSizer->AddObject(m_SGC); - pSizer->AddObject(m_ShaderNames); - pSizer->AddObject(m_ShaderCacheCombinations[0]); - pSizer->AddObject(m_ShaderCacheCombinations[1]); - } - - void RefreshShader(const AZStd::string_view name, CShader* shader) override - { - mfRefreshSystemShader(name.data(), shader); - } - - void ReleaseShader(CShader* shader) const override - { - SAFE_RELEASE_FORCE(shader); - } - - static float EvalWaveForm(SWaveForm* wf); - static float EvalWaveForm(SWaveForm2* wf); - static float EvalWaveForm2(SWaveForm* wf, float frac); -}; - -//===================================================================== - -#endif // __CSHADER_H__ diff --git a/Code/CryEngine/RenderDll/Common/Shaders/CShaderBin.h b/Code/CryEngine/RenderDll/Common/Shaders/CShaderBin.h deleted file mode 100644 index 274a412283..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/CShaderBin.h +++ /dev/null @@ -1,363 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CSHADERBIN_H__ -#define __CSHADERBIN_H__ - -#include -#include - -#ifndef FOURCC -typedef DWORD FOURCC; -#endif - -struct SShaderTechParseParams -{ - CCryNameR techName[TTYPE_MAX]; -}; - -class CShaderMan; - -struct SShaderBinHeader -{ - FOURCC m_Magic; - uint32 m_CRC32; - uint16 m_VersionLow; - uint16 m_VersionHigh; - uint32 m_nOffsetStringTable; - uint32 m_nOffsetParamsLocal; - uint32 m_nTokens; - uint32 m_nSourceCRC32; - - SShaderBinHeader() - { - memset(this, 0, sizeof(*this)); - } - - AUTO_STRUCT_INFO -}; - -struct SShaderBinParamsHeader -{ - uint64 nMask; - uint64 nstaticMask; - uint32 nName; - int32 nParams; - int32 nSamplers; - int32 nTextures; - int32 nFuncs; - - SShaderBinParamsHeader() - { - memset(this, 0, sizeof(*this)); - } - - AUTO_STRUCT_INFO -}; - -struct SParamCacheInfo -{ - typedef std::vector > AffectedFuncsVec; - typedef std::vector > AffectedParamsVec; - - uint32 m_dwName; - uint64 m_nMaskGenFX; - uint64 m_maskGenStatic; - AffectedFuncsVec m_AffectedFuncs; - AffectedParamsVec m_AffectedParams; - AffectedParamsVec m_AffectedSamplers; - AffectedParamsVec m_AffectedTextures; - - SParamCacheInfo() - : m_dwName(0) - , m_nMaskGenFX(0) - , m_maskGenStatic(0) - {}; - - int Size() - { - return sizeof(SParamCacheInfo) + sizeofVector(m_AffectedFuncs) + sizeofVector(m_AffectedParams) + sizeofVector(m_AffectedSamplers) + sizeofVector(m_AffectedTextures); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_AffectedFuncs); - pSizer->AddObject(m_AffectedParams); - pSizer->AddObject(m_AffectedSamplers); - pSizer->AddObject(m_AffectedTextures); - } -}; - -# define MAX_FXBIN_CACHE 32 - -struct SShaderBin -{ - typedef AZStd::vector ParamsCacheVec; - static SShaderBin s_Root; - static uint32 s_nCache; - static uint32 s_nMaxFXBinCache; - - SShaderBin* m_Next; - SShaderBin* m_Prev; - - uint32 m_CRC32; - uint32 m_dwName; - char* m_szName; - uint32 m_SourceCRC32; - bool m_bLocked; - bool m_bReadOnly; - bool m_bInclude; - FXShaderToken m_TokenTable; - ShaderTokensVec m_Tokens; - - // Local shader info (after parsing) - uint32 m_nOffsetLocalInfo; - uint32 m_nCurCacheParamsID; - uint32 m_nCurParamsID; - ParamsCacheVec m_ParamsCache; - - SShaderBin() - : m_Next(nullptr) - , m_Prev(nullptr) - , m_CRC32(0) - , m_dwName(0) - , m_szName(nullptr) - , m_SourceCRC32(0) - , m_bLocked(false) - , m_bReadOnly(true) - , m_bInclude(false) - , m_nOffsetLocalInfo(0) - , m_nCurCacheParamsID(-1) - , m_nCurParamsID(-1) - { - if (!s_Root.m_Next) - { - s_Root.m_Next = &s_Root; - s_Root.m_Prev = &s_Root; - } - } - - ~SShaderBin() - { - if (m_szName) - { - g_shaderBucketAllocator.deallocate((void*) m_szName); - } - } - - void SetName(const char* name) - { - if (m_szName) - { - g_shaderBucketAllocator.deallocate((void*) m_szName); - m_szName = nullptr; - } - - if (name[0]) - { - m_szName = (char*) g_shaderBucketAllocator.allocate(strlen(name) + 1); - azstrcpy(m_szName, strlen(name) + 1, name); - } - } - - _inline void Unlink() - { - if (!m_Next || !m_Prev) - { - return; - } - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - m_Next = m_Prev = NULL; - } - _inline void Link(SShaderBin* Before) - { - if (m_Next || m_Prev) - { - return; - } - m_Next = Before->m_Next; - Before->m_Next->m_Prev = this; - Before->m_Next = this; - m_Prev = Before; - } - _inline bool IsReadOnly() { return m_bReadOnly; } - _inline void Lock() { m_bLocked = true; } - _inline void Unlock() { m_bLocked = false; } - - uint32 ComputeCRC(); - void SetCRC(uint32 nCRC) { m_CRC32 = nCRC; } - - int Size() - { - int nSize = sizeof(SShaderBin); - nSize += sizeOfV(m_TokenTable); - nSize += sizeofVector(m_Tokens); - nSize += sizeOfV(m_ParamsCache); - - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_TokenTable); - pSizer->AddObject(m_Tokens); - pSizer->AddObject(m_ParamsCache); - } - - void* operator new (size_t sz) - { - return g_shaderBucketAllocator.allocate(sz); - } - - void operator delete (void* p) - { - g_shaderBucketAllocator.deallocate(p); - } - -private: - SShaderBin(const SShaderBin&); - SShaderBin& operator = (const SShaderBin&); -}; - - -#define FXP_PARAMS_DIRTY 1 -#define FXP_SAMPLERS_DIRTY 2 -#define FXP_TEXTURES_DIRTY 4 - -typedef std::vector::iterator FXParamsIt; -typedef std::vector::iterator FXSamplersOldIt; -typedef std::vector::iterator FXSamplersIt; -typedef std::vector::iterator FXTexturesIt; -struct SShaderFXParams -{ - uint32 m_nFlags; // FXP_DIRTY - - std::vector m_FXParams; - std::vector m_FXSamplers; - std::vector m_FXTextures; - std::vector m_FXSamplersOld; // Equivalent to FXTexSamplers elsewhere - - AZStd::vector m_PublicParams; - - SShaderFXParams() - { - m_nFlags = 0; - } - int Size() - { - int nSize = sizeOfV(m_FXParams); - nSize += sizeOfV(m_FXSamplers); - nSize += sizeOfV(m_FXTextures); - nSize += sizeOfV(m_PublicParams); - - nSize += sizeOfV(m_FXSamplersOld); - - return nSize; - } -}; - - -typedef std::map FXShaderBinValidCRC; -typedef FXShaderBinValidCRC::iterator FXShaderBinValidCRCItor; - -typedef std::map FXShaderBinPath; -typedef FXShaderBinPath::iterator FXShaderBinPathItor; - -class CShaderManBin -{ - friend class CShaderMan; - - SShaderBin* LoadBinShader(AZ::IO::HandleType binFileHandle, const char* szName, const char* szNameBin, bool bReadParams); - SShaderBin* SaveBinShader(uint32 nSourceCRC32, const char* szName, bool bInclude, AZ::IO::HandleType srcFileHandle); - bool SaveBinShaderLocalInfo(SShaderBin* pBin, uint32 dwName, uint64 nMaskGenFX, uint64 maskGenStatic, TArray& Funcs, std::vector& Params, std::vector& Samplers, std::vector& Textures); - SParamCacheInfo* GetParamInfo(SShaderBin* pBin, uint32 dwName, uint64 nMaskGenFX, uint64 maskGenStatic); - - void AddGenMacroses(SShaderGen* shG, CParserBin& Parser, uint64 nMaskGen, bool ignoreShaderGenMask = false); - - bool ParseBinFX_Global_Annotations(CParserBin & Parser, SParserFrame & Frame, bool* bPublic, CCryNameR techStart[2]); - bool ParseBinFX_Global(CParserBin & Parser, SParserFrame & Frame, bool* bPublic, CCryNameR techStart[2]); - bool ParseBinFX_Sampler_Annotations_Script(CParserBin& Parser, SParserFrame& Frame, STexSamplerFX* pSampler); - bool ParseBinFX_Sampler_Annotations(CParserBin& Parser, SParserFrame& Frame, STexSamplerFX* pSampler); - bool ParseBinFX_Sampler(CParserBin& Parser, SParserFrame& Data, uint32 dwName, SParserFrame Annotations, EToken samplerType); - bool ParseBinFX_Sampler(CParserBin& Parser, SParserFrame& Data, SFXSampler& Sampl); - bool ParseBinFX_Texture(CParserBin& Parser, SParserFrame& Data, SFXTexture& Sampl); - - void InitShaderDependenciesList(CParserBin& Parser, SCodeFragment* pFunc, TArray& bChecked, TArray& AffectedFuncs); - void CheckFragmentsDependencies(CParserBin& Parser, TArray& bChecked, TArray& AffectedFuncs); - void CheckStructuresDependencies(CParserBin& Parser, SCodeFragment* pFrag, TArray& bChecked, TArray& AffectedFunc); - - void AddParameterToScript(CParserBin& Parser, SFXParam* pr, PodArray& SHData, EHWShaderClass eSHClass, int nCB); - void AddSamplerToScript(CParserBin& Parser, SFXSampler* pr, PodArray& SHData, EHWShaderClass eSHClass); - void AddTextureToScript(CParserBin& Parser, SFXTexture* pr, PodArray& SHData, EHWShaderClass eSHClass); - void AddAffectedParameter(CParserBin& Parser, std::vector& AffectedParams, TArray& AffectedFunc, SFXParam* pParam, EHWShaderClass eSHClass, uint32 dwType, SShaderTechnique* pShTech); - void AddAffectedSampler(CParserBin& Parser, std::vector& AffectedSamplers, TArray& AffectedFunc, SFXSampler* pParam, EHWShaderClass eSHClass, uint32 dwType, SShaderTechnique* pShTech); - void AddAffectedTexture(CParserBin& Parser, std::vector& AffectedTextures, TArray& AffectedFunc, SFXTexture* pParam, EHWShaderClass eSHClass, uint32 dwType, SShaderTechnique* pShTech); - bool ParseBinFX_Technique_Pass_PackParameters (CParserBin& Parser, std::vector& AffectedParams, TArray& AffectedFunc, SCodeFragment* pFunc, EHWShaderClass eSHClass, uint32 dwSHName, std::vector& PackedParams, TArray& Replaces, TArray& NewTokens, TArray& bMerged); - bool ParseBinFX_Technique_Pass_GenerateShaderData(CParserBin& Parser, FXMacroBin& Macros, SShaderFXParams& FXParams, uint32 dwSHName, EHWShaderClass eSHClass, uint64& nGenMask, uint32 dwSHType, PodArray& SHData, SShaderTechnique* pShTech); - bool ParseBinFX_Technique_Pass_LoadShader(CParserBin& Parser, FXMacroBin& Macros, SParserFrame& SHFrame, SShaderTechnique* pShTech, SShaderPass* pPass, EHWShaderClass eSHClass, SShaderFXParams& FXParams); - bool ParseBinFX_Technique_Pass(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pTech); - bool ParseBinFX_Technique_Annotations_String(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pSHTech, std::vector& techParams, bool* bPublic); - bool ParseBinFX_Technique_Annotations(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pSHTech, std::vector& techParams, bool* bPublic); - bool ParseBinFX_Technique_CustomRE(CParserBin& Parser, SParserFrame& Frame, SParserFrame& Name, SShaderTechnique* pShTech); - SShaderTechnique* ParseBinFX_Technique(CParserBin& Parser, SParserFrame& Data, SParserFrame Annotations, std::vector& techParams, bool* bPublic); - bool ParseBinFX_LightStyle_Val(CParserBin& Parser, SParserFrame& Frame, CLightStyle* ls); - bool ParseBinFX_LightStyle(CParserBin& Parser, SParserFrame& Frame, int nStyle); - - void MergeTextureSlots(SShaderTexSlots* master, SShaderTexSlots* overlay); - SShaderTexSlots* GetTextureSlots(CParserBin& Parser, SShaderBin* pBin, CShader* ef, int nTech = 0, int nPass = 0); - - SShaderBin* SearchInCache(const char* szName, bool bInclude); - bool AddToCache(SShaderBin* pSB, bool bInclude); - bool DeleteFromCache(SShaderBin* pSB); - - SFXParam* mfAddFXParam(SShaderFXParams& FXP, const SFXParam* pParam); - SFXParam* mfAddFXParam(CShader* pSH, const SFXParam* pParam); - - void mfAddFXSampler(CShader* pSH, const SFXSampler* pParam); - void mfAddFXTexture(CShader* pSH, const SFXTexture* pParam); - - void mfAddFXSampler(CShader* pSH, const STexSamplerFX* pSamp); - void mfGeneratePublicFXParams(CShader* pSH, CParserBin& Parser); - -public: - CShaderManBin(); - SShaderBin* GetBinShader(const char* szName, bool bInclude, uint32 nRefCRC32, bool* pbChanged = NULL); - bool ParseBinFX(SShaderBin* pBin, CShader* ef, uint64 nMaskGen); - bool ParseBinFX_Dummy(SShaderBin* pBin, std::vector& ShaderNames, const char* szName); - - SShaderFXParams& mfGetFXParams(CShader* pSH); - void mfRemoveFXParams(CShader* pSH); - int mfSizeFXParams(uint32& nCount); - void mfReleaseFXParams(); - - void InvalidateCache(bool bIncludesOnly = false); - - CShaderMan* m_pCEF; - FXShaderBinPath m_BinPaths; - FXShaderBinValidCRC m_BinValidCRCs; - - bool m_bBinaryShadersLoaded; - - typedef std::map ShaderFXParams; - typedef ShaderFXParams::iterator ShaderFXParamsItor; - ShaderFXParams m_ShaderFXParams; - - - int Size(); - void GetMemoryUsage(ICrySizer* pSizer) const; -}; - -//===================================================================== - -#endif // __CSHADERBIN_H__ diff --git a/Code/CryEngine/RenderDll/Common/Shaders/Parser.cpp b/Code/CryEngine/RenderDll/Common/Shaders/Parser.cpp deleted file mode 100644 index 22e66c393c..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/Parser.cpp +++ /dev/null @@ -1,1322 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -const char* kWhiteSpace = " ,"; -char* pCurCommand; - -void SkipCharacters (char** buf, const char* toSkip) -{ - char theChar; - char* skip; - - while ((theChar = **buf) != 0) - { - if (theChar >= 0x20) - { - skip = (char*) toSkip; - while (*skip) - { - if (theChar == *skip) - { - break; - } - ++skip; - } - if (*skip == 0) - { - return; - } - } - ++*buf; - } -} - -void RemoveCR(char* pbuf) -{ - while (*pbuf) - { - if (*pbuf == 0xd) - { - *pbuf = 0x20; - } - pbuf++; - } -} - -FXMacro sStaticMacros; - -bool SkipChar(unsigned int ch) -{ - // Return true if ch is any of the first 0x20 ascii characters - bool res = ch <= 0x20; - - // Also return true if ch is any of the following commented characters - res |= (ch - 0x21) < 2; // !" - res |= (ch - 0x26) < 10; // &'()*+,-./ - res |= (ch - 0x3A) < 6; // :;<=>? - res |= ch == 0x5B; // [ - res |= ch == 0x5D; // ] - res |= (ch - 0x7B) < 3; // {|} - - return res; -} - -// Determine is this preprocessor directive belongs to first pass or second one -bool fxIsFirstPass(char* buf) -{ - char com[1024]; - char tok[256]; - fxFillCR(&buf, com); - char* s = com; - while (*s != 0) - { - fxFillPr(&s, tok); - if (tok[0] == '%' && tok[1] == '_') - { - return false; - } - } - return true; -} - -static void fxAddMacro(const char* Name, const char* Macro, FXMacro& Macros) -{ - SMacroFX pr; - - if (Name[0] == '%') - { - pr.m_nMask = shGetHex(&Macro[0]); -#ifdef _DEBUG - FXMacroItor it = Macros.find(CONST_TEMP_STRING(Name)); - if (it != Macros.end()) - { - assert(0); - } -#endif - } - else - { - pr.m_nMask = 0; - } - pr.m_szMacro = Macro ? Macro : ""; - FXMacroItor it = Macros.find(CONST_TEMP_STRING(Name)); - if (it != Macros.end()) - { - Macros.erase(Name); - } - Macros.insert(FXMacroItor::value_type(Name, pr)); - - /*it = Macros.find(Name); - if (it != Macros.end()) - { - int nnn = 0; - }*/ -} - -void fxParserInit(void) -{ -#if !defined(NULL_RENDERER) && defined(D3DX_SDK_VERSION) - // Needed for a workaround for the optimization rule problem of DXSDKJune10's HLSL Compiler (9.29.952.3111) - // See: http://support.microsoft.com/kb/2448404 - // Causes cracks in tessellated meshes - char sdkVer[4]; - azitoa(D3DX_SDK_VERSION, sdkVer, 4); - fxAddMacro("D3DX_SDK_VERSION", sdkVer, sStaticMacros); -#else - fxAddMacro("D3DX_SDK_VERSION", "0", sStaticMacros); -#endif -} - -void fxRegisterEnv([[maybe_unused]] const char* szStr) -{ - // deprecated -} - -char* fxFillPr (char** buf, char* dst) -{ - int n = 0; - char ch; - while ((ch = **buf) != 0) - { - if (!SkipChar(ch)) - { - break; - } - ++*buf; - } - char* pStart = *buf; - while ((ch = **buf) != 0) - { - if (SkipChar(ch)) - { - break; - } - dst[n++] = ch; - ++*buf; - } - dst[n] = 0; - return pStart; -} - -char* fxFillPrC (char** buf, char* dst) -{ - int n = 0; - char ch; - while ((ch = **buf) != 0) - { - if (!SkipChar(ch)) - { - break; - } - ++*buf; - } - char* pStart = *buf; - while ((ch = **buf) != 0) - { - if (ch != ',' && SkipChar(ch)) - { - break; - } - dst[n++] = ch; - ++*buf; - } - dst[n] = 0; - return pStart; -} - -char* fxFillNumber (char** buf, char* dst) -{ - int n = 0; - char ch; - while ((ch = **buf) != 0) - { - if (!SkipChar(ch)) - { - break; - } - ++*buf; - } - char* pStart = *buf; - while ((ch = **buf) != 0) - { - if (ch != '.' && SkipChar(ch)) - { - break; - } - dst[n++] = ch; - ++*buf; - } - dst[n] = 0; - return pStart; -} - -int shFill(char** buf, char* dst, int nSize) -{ - int n = 0; - SkipCharacters (buf, kWhiteSpace); - - while (**buf > 0x20) - { - dst[n++] = **buf; - ++*buf; - - if (nSize > 0 && n == nSize) - { - break; - } - } - - dst[n] = 0; - return n; -} -int fxFill(char** buf, char* dst, int nSize) -{ - int n = 0; - SkipCharacters (buf, kWhiteSpace); - - while (**buf != ';') - { - if (**buf == 0) - { - break; - } - dst[n++] = **buf; - ++*buf; - - if (nSize > 0 && n == nSize) - { - dst[n - 1] = 0; - return 1; - } - } - - PREFAST_ASSUME(*buf); - dst[n] = 0; - if (**buf == ';') - { - ++*buf; - } - return n; -} - -int fxFillCR(char** buf, char* dst) -{ - int n = 0; - SkipCharacters (buf, kWhiteSpace); - while (**buf != 0xa) - { - if (**buf == 0) - { - break; - } - dst[n++] = **buf; - ++*buf; - } - dst[n] = 0; - return n; -} - -//================================================================================ - -bool shGetBool(char* buf) -{ - if (!buf) - { - return false; - } - - if (!_strnicmp(buf, "yes", 3)) - { - return true; - } - - if (!_strnicmp(buf, "true", 4)) - { - return true; - } - - if (!_strnicmp(buf, "on", 2)) - { - return true; - } - - if (!strncmp(buf, "1", 1)) - { - return true; - } - - return false; -} - -float shGetFloat(const char* buf) -{ - if (!buf) - { - return 0; - } - float f = 0; - -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%f", &f); - assert(res); - - return f; -} - -void shGetFloat(const char* buf, float* v1, float* v2) -{ - if (!buf) - { - return; - } - float f = 0, f1 = 0; - - int n = azsscanf(buf, "%f %f", &f, &f1); - if (n == 1) - { - *v1 = f; - *v2 = f; - } - else - { - *v1 = f; - *v2 = f1; - } -} - -int shGetInt(const char* buf) -{ - if (!buf) - { - return 0; - } - int i = 0; - - if (buf[0] == '0' && buf[1] == 'x') - { -#ifndef NDEBUG - int res = -#endif - azsscanf(&buf[2], "%x", &i); - assert(res); - } - else - { -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%i", &i); - assert(res); - } - - return i; -} - -int shGetHex(const char* buf) -{ - if (!buf) - { - return 0; - } - int i = 0; -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%x", &i); - assert(res); - - return i; -} - -uint64 shGetHex64(const char* buf) -{ - if (!buf) - { - return 0; - } -#if defined(__GNUC__) - unsigned long long i = 0; -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%llx", &i); - assert(res); - return (uint64)i; -#else - uint64 i = 0; -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%I64x", &i); - assert(res); - return i; -#endif -} - -void shGetVector(char* buf, Vec3& v) -{ - if (!buf) - { - return; - } -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%f %f %f", &v[0], &v[1], &v[2]); - assert(res); -} - -void shGetVector(char* buf, float v[3]) -{ - if (!buf) - { - return; - } -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%f %f %f", &v[0], &v[1], &v[2]); - assert(res); -} - -void shGetVector4(char* buf, Vec4& v) -{ - if (!buf) - { - return; - } -#ifndef NDEBUG - int res = -#endif - azsscanf(buf, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w); - assert(res); -} - -static struct SColAsc -{ - const char* nam; - ColorF col; - - SColAsc(const char* name, const ColorF& c) - { - nam = name; - col = c; - } -} sCols[] = -{ - SColAsc("Aquamarine", Col_Aquamarine), - SColAsc("Black", Col_Black), - SColAsc("Blue", Col_Blue), - SColAsc("BlueViolet", Col_BlueViolet), - SColAsc("Brown", Col_Brown), - SColAsc("CadetBlue", Col_CadetBlue), - SColAsc("Coral", Col_Coral), - SColAsc("CornflowerBlue", Col_CornflowerBlue), - SColAsc("Cyan", Col_Cyan), - SColAsc("DarkGray", Col_DarkGray), - SColAsc("DarkGrey", Col_DarkGrey), - SColAsc("DarkGreen", Col_DarkGreen), - SColAsc("DarkOliveGreen", Col_DarkOliveGreen), - SColAsc("DarkOrchid", Col_DarkOrchid), - SColAsc("DarkSlateBlue", Col_DarkSlateBlue), - SColAsc("DarkSlateGray", Col_DarkSlateGray), - SColAsc("DarkSlateGrey", Col_DarkSlateGrey), - SColAsc("DarkTurquoise", Col_DarkTurquoise), - SColAsc("DarkWood", Col_DarkWood), - SColAsc("DeepPink", Col_DeepPink), - SColAsc("DimGray", Col_DimGray), - SColAsc("DimGrey", Col_DimGrey), - SColAsc("FireBrick", Col_FireBrick), - SColAsc("ForestGreen", Col_ForestGreen), - SColAsc("Gold", Col_Gold), - SColAsc("Goldenrod", Col_Goldenrod), - SColAsc("Gray", Col_Gray), - SColAsc("Grey", Col_Grey), - SColAsc("Green", Col_Green), - SColAsc("GreenYellow", Col_GreenYellow), - SColAsc("IndianRed", Col_IndianRed), - SColAsc("Khaki", Col_Khaki), - SColAsc("LightBlue", Col_LightBlue), - SColAsc("LightGray", Col_LightGray), - SColAsc("LightGrey", Col_LightGrey), - SColAsc("LightSteelBlue", Col_LightSteelBlue), - SColAsc("LightWood", Col_LightWood), - SColAsc("Lime", Col_Lime), - SColAsc("LimeGreen", Col_LimeGreen), - SColAsc("Magenta", Col_Magenta), - SColAsc("Maroon", Col_Maroon), - SColAsc("MedianWood", Col_MedianWood), - SColAsc("MediumAquamarine", Col_MediumAquamarine), - SColAsc("MediumBlue", Col_MediumBlue), - SColAsc("MediumForestGreen", Col_MediumForestGreen), - SColAsc("MediumGoldenrod", Col_MediumGoldenrod), - SColAsc("MediumOrchid", Col_MediumOrchid), - SColAsc("MediumSeaGreen", Col_MediumSeaGreen), - SColAsc("MediumSlateBlue", Col_MediumSlateBlue), - SColAsc("MediumSpringGreen", Col_MediumSpringGreen), - SColAsc("MediumTurquoise", Col_MediumTurquoise), - SColAsc("MediumVioletRed", Col_MediumVioletRed), - SColAsc("MidnightBlue", Col_MidnightBlue), - SColAsc("Navy", Col_Navy), - SColAsc("NavyBlue", Col_NavyBlue), - SColAsc("Orange", Col_Orange), - SColAsc("OrangeRed", Col_OrangeRed), - SColAsc("Orchid", Col_Orchid), - SColAsc("PaleGreen", Col_PaleGreen), - SColAsc("Pink", Col_Pink), - SColAsc("Plum", Col_Plum), - SColAsc("Red", Col_Red), - SColAsc("Salmon", Col_Salmon), - SColAsc("SeaGreen", Col_SeaGreen), - SColAsc("Sienna", Col_Sienna), - SColAsc("SkyBlue", Col_SkyBlue), - SColAsc("SlateBlue", Col_SlateBlue), - SColAsc("SpringGreen", Col_SpringGreen), - SColAsc("SteelBlue", Col_SteelBlue), - SColAsc("Tan", Col_Tan), - SColAsc("Thistle", Col_Thistle), - SColAsc("Turquoise", Col_Turquoise), - SColAsc("Violet", Col_Violet), - SColAsc("VioletRed", Col_VioletRed), - SColAsc("Wheat", Col_Wheat), - SColAsc("White", Col_White), - SColAsc("Yellow", Col_Yellow), - SColAsc("YellowGreen", Col_YellowGreen), - - SColAsc(NULL, ColorF(1.0f, 1.0f, 1.0f)) -}; - -#include - -void shGetColor(const char* buf, ColorF& v) -{ - char name[64]; - int n; - - if (!buf) - { - v = Col_White; - return; - } - if (buf[0] == '{') - { - buf++; - } - if (isalpha((unsigned char)buf[0])) - { - n = 0; - float scal = 1; - azstrcpy(name, AZ_ARRAY_SIZE(name), buf); - char nm[64]; - if (strchr(buf, '*')) - { - while (buf[n] != '*') - { - if (buf[n] == 0x20) - { - break; - } - nm[n] = buf[n]; - n++; - } - nm[n] = 0; - if (buf[n] == 0x20) - { - while (buf[n] != '*') - { - n++; - } - } - n++; - while (buf[n] == 0x20) - { - n++; - } - scal = shGetFloat(&buf[n]); - azstrcpy(name, AZ_ARRAY_SIZE(name), nm); - } - n = 0; - while (sCols[n].nam) - { - if (!azstricmp(sCols[n].nam, name)) - { - v = sCols[n].col; - if (scal != 1) - { - v.ScaleCol(scal); - } - return; - } - n++; - } - } - n = 0; - while (true) - { - if (n == 4) - { - break; - } - char par[64]; - par[0] = 0; - fxFillNumber((char**)&buf, par); - if (!par[0]) - { - break; - } - v[n++] = (float)atof(par); - } - - //v.Clamp(); -} - -void shGetColor(char* buf, float v[4]) -{ - char name[64]; - - if (!buf) - { - v[0] = 1.0f; - v[1] = 1.0f; - v[2] = 1.0f; - v[3] = 1.0f; - return; - } - if (isalpha((unsigned char)buf[0])) - { - int n = 0; - float scal = 1; - azstrcpy(name, AZ_ARRAY_SIZE(name), buf); - char nm[64]; - if (strchr(buf, '*')) - { - while (buf[n] != '*') - { - if (buf[n] == 0x20) - { - break; - } - nm[n] = buf[n]; - n++; - } - nm[n] = 0; - if (buf[n] == 0x20) - { - while (buf[n] != '*') - { - n++; - } - } - n++; - while (buf[n] == 0x20) - { - n++; - } - scal = shGetFloat(&buf[n]); - azstrcpy(name, AZ_ARRAY_SIZE(name), nm); - } - n = 0; - while (sCols[n].nam) - { - if (!azstricmp(sCols[n].nam, name)) - { - v[0] = sCols[n].col[0]; - v[1] = sCols[n].col[1]; - v[2] = sCols[n].col[2]; - v[3] = sCols[n].col[3]; - if (scal != 1) - { - v[0] *= scal; - v[1] *= scal; - v[2] *= scal; - } - return; - } - n++; - } - } - int n = azsscanf(buf, "%f %f %f %f", &v[0], &v[1], &v[2], &v[3]); - switch (n) - { - case 0: - v[0] = v[1] = v[2] = v[3] = 1.0f; - break; - - case 1: - v[1] = v[2] = v[3] = 1.0f; - break; - - case 2: - v[2] = v[3] = 1.0f; - break; - - case 3: - v[3] = 1.0f; - break; - } - //v.Clamp(); -} - -//========================================================================================= - -char* GetAssignmentText (char** buf) -{ - SkipCharacters (buf, kWhiteSpace); - char* result = *buf; - - char theChar; - - PREFAST_SUPPRESS_WARNING(28182) - while ((theChar = **buf) != 0) - { - if (theChar == '[') - { - while ((theChar = **buf) != ']') - { - if (theChar == 0 || theChar == ';') - { - break; - } - ++*buf; - } - continue; - } - if (theChar <= 0x20 || theChar == ';') - { - break; - } - ++*buf; - } - - PREFAST_ASSUME(*buf); - **buf = 0; - if (theChar) - { - ++*buf; - } - return result; -} - -char* GetSubText (char** buf, char open, char close) -{ - if (**buf == 0 || **buf != open) - { - return 0; - } - ++*buf; - char* result = *buf; - - char theChar; - long skip = 1; - - if (open == close) - { - open = 0; - } - while ((theChar = **buf) != 0) - { - if (theChar == open) - { - ++skip; - } - if (theChar == close) - { - if (--skip == 0) - { - **buf = 0; - ++*buf; - break; - } - } - ++*buf; - } - return result; -} - -_inline static int IsComment(char** buf) -{ - if (!(*buf)) - { - return 0; - } - - if ((*buf)[0] == '/' && (*buf)[1] == '/') - { - return 2; - } - - if ((*buf)[0] == '/' && (*buf)[1] == '*') - { - return 3; - } - - return 0; -} - -void SkipComments(char** buf, bool bSkipWhiteSpace) -{ - int n; - static int m; - - n = IsComment(buf); - while (n) - { - switch (n) - { - case 2: - // skip comment lines. - *buf = strchr (*buf, '\n'); - if (*buf && bSkipWhiteSpace) - { - SkipCharacters (buf, kWhiteSpace); - } - break; - - case 3: - // skip comment blocks. - m = 0; - do - { - *buf = strchr (*buf, '*'); - if (!(*buf)) - { - break; - } - if ((*buf)[-1] == '/') - { - *buf += 1; - m++; - } - else - if ((*buf)[1] == '/') - { - *buf += 2; - m--; - } - else - { - *buf += 1; - } - } while (m); - if (!(*buf)) - { - iLog->Log ("Warning: Comment lines aren't closed\n"); - break; - } - if (bSkipWhiteSpace) - { - SkipCharacters (buf, kWhiteSpace); - } - break; - } - n = IsComment(buf); - } -} - -void fxSkipTillCR(char** buf) -{ - char ch; - while ((ch = **buf) != 0) - { - if (ch == 0xa) - { - break; - } - ++*buf; - } -} - -bool fxCheckMacroses(char** str, int nPass) -{ - char tmpBuf[1024]; - byte bRes[64]; - byte bOr[64]; - int nLevel = 0; - int i; - while (true) - { - SkipCharacters(str, kWhiteSpace); - if (**str == '(') - { - ++*str; - int n = 0; - int nD = 0; - while (true) - { - if (**str == '(') - { - n++; - } - else - if (**str == ')') - { - if (!n) - { - tmpBuf[nD] = 0; - ++*str; - break; - } - n--; - } - else - if (**str == 0) - { - return false; - } - tmpBuf[nD++] = **str; - ++*str; - } - char* s = &tmpBuf[0]; - bRes[nLevel] = fxCheckMacroses(&s, nPass); - nLevel++; - bOr[nLevel] = 255; - } - else - { - int n = 0; - while (true) - { - if (**str == '|' || **str == '&' || **str == 0) - { - break; - } - if (**str <= 0x20) - { - break; - } - tmpBuf[n++] = **str; - ++*str; - } - tmpBuf[n] = 0; - if (tmpBuf[0] != 0) - { - char* s = tmpBuf; - bool bNeg = false; - if (s[0] == '!') - { - bNeg = true; - s++; - } - const SMacroBinFX* pFound; - if (isdigit((unsigned)s[0])) - { - if ((s[0] == '0' && s[1] == 'x') || s[0] != 0) - { - pFound = (SMacroBinFX*)1; - } - else - { - pFound = NULL; - } - } - else - { - bool bKey = false; - uint32 nTok = CParserBin::NextToken(s, tmpBuf, bKey); - if (nTok == eT_unknown) - { - nTok = CParserBin::GetCRC32(tmpBuf); - } - pFound = CParserBin::FindMacro(nTok, CParserBin::GetStaticMacroses()); - } - bRes[nLevel] = (pFound) ? true : false; - if (bNeg) - { - bRes[nLevel] = !bRes[nLevel]; - } - nLevel++; - bOr[nLevel] = 255; - } - else - { - assert(0); - } - } - SkipCharacters(str, kWhiteSpace); - if (**str == 0) - { - break; - } - char* s = *str; - if (s[0] == '|' && s[1] == '|') - { - bOr[nLevel] = true; - *str = s + 2; - } - else - if (s[0] == '&' && s[1] == '&') - { - bOr[nLevel] = false; - *str = s + 2; - } - else - { - assert(0); - } - } - byte Res = false; - for (i = 0; i < nLevel; i++) - { - if (!i) - { - Res = bRes[i]; - } - else - { - assert(bOr[i] != 255); - if (bOr[i]) - { - Res = Res | bRes[i]; - } - else - { - Res = Res & bRes[i]; - } - } - } - return Res != 0; -} - -bool fxIgnorePreprBlock(char** buf) -{ - int nLevel = 0; - bool bEnded = false; - SkipCharacters (buf, kWhiteSpace); - SkipComments(buf, true); - PREFAST_SUPPRESS_WARNING(6011) - while (**buf != 0) - { - char ch = **buf; - while (ch && SkipChar((unsigned)ch)) - { - while ((ch = **buf) != 0) - { - if (ch == '/' && IsComment(buf)) - { - break; - } - if (!SkipChar(ch)) - { - break; - } - ++*buf; - } - SkipComments(buf, true); - ch = **buf; - } - char* posS = *buf; - char* st = posS; - PREFAST_ASSUME(posS); - if (*posS == '#') - { - posS++; - if (SkipChar(posS[0])) - { - while ((ch = *posS) != 0) - { - if (!SkipChar(ch)) - { - break; - } - posS++; - } - } - if (posS[0] == 'i' && posS[1] == 'f') - { - nLevel++; - *buf = posS + 2; - continue; - } - if (!strncmp(posS, "endif", 5)) - { - if (!nLevel) - { - *buf = st; - bEnded = true; - break; - } - nLevel--; - *buf = posS + 4; - } - else - if (!strncmp(posS, "else", 4) || !strncmp(posS, "elif", 4)) - { - if (!nLevel) - { - *buf = st; - break; - } - *buf = posS + 4; - } - } - ch = **buf; - while (ch) - { - if (ch == '/' && IsComment(buf)) - { - break; - } - if (SkipChar((unsigned)ch)) - { - break; - } - ++*buf; - ch = **buf; - } - } - PREFAST_ASSUME(*buf); - if (!**buf) - { - assert(0); - Warning("Couldn't find #endif directive for associated #ifdef"); - return false; - } - - return bEnded; -} - -int shGetObject (char** buf, STokenDesc* tokens, char** name, char** data) -{ -start: - if (!*buf) - { - return 0; - } - SkipCharacters (buf, kWhiteSpace); - SkipComments(buf, true); - - if (!(*buf) || !**buf) - { - return -2; - } - - char* b = *buf; - if (b[0] == '#') - { - char nam[1024]; - bool bPrepr = false; - if (!strncmp(b, "#if", 3)) - { - bPrepr = true; - fxFillPr(buf, nam); - fxFillCR(buf, nam); - char* s = &nam[0]; - bool bRes = fxCheckMacroses(&s, 0); - if (b[2] == 'n') - { - bRes = !bRes; - } - if (!bRes) - { - sfxIFDef.AddElem(false); - fxIgnorePreprBlock(buf); - } - else - { - sfxIFDef.AddElem(false); - } - } - else - if (!strncmp(b, "#else", 5)) - { - fxFillPr(buf, nam); - bPrepr = true; - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - assert(0); - Warning("#else without #ifdef"); - return false; - } - if (sfxIFDef[nLevel] == true) - { - bool bEnded = fxIgnorePreprBlock(buf); - if (!bEnded) - { - assert(0); - Warning("#else or #elif after #else"); - return -1; - } - } - } - else - if (!strncmp(b, "#elif", 5)) - { - fxFillPr(buf, nam); - bPrepr = true; - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - assert(0); - Warning("#elif without #ifdef"); - return -1; - } - if (sfxIFDef[nLevel] == true) - { - fxIgnorePreprBlock(buf); - } - else - { - fxFillCR(buf, nam); - char* s = &nam[0]; - bool bRes = fxCheckMacroses(&s, 0); - if (!bRes) - { - fxIgnorePreprBlock(buf); - } - else - { - sfxIFDef[nLevel] = true; - } - } - } - else - if (!strncmp(b, "#endif", 6)) - { - fxFillPr(buf, nam); - bPrepr = true; - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - assert(0); - Warning("#endif without #ifdef"); - return -1; - } - sfxIFDef.Remove(nLevel); - } - if (bPrepr) - { - goto start; - } - } - - STokenDesc* ptokens = tokens; - while (tokens->id != 0) - { - if (!_strnicmp(tokens->token, *buf, strlen(tokens->token))) - { - pCurCommand = *buf; - break; - } - ++tokens; - } - if (tokens->id == 0) - { - char* p = strchr (*buf, '\n'); - - char pp[1024]; - if (p) - { - cry_strcpy(pp, *buf, (size_t)(p - *buf)); - *buf = p; - } - else - { - cry_strcpy(pp, *buf); - } - - iLog->Log ("Warning: Found token '%s' which was not one of the list (Skipping).\n", pp); - while (ptokens->id != 0) - { - iLog->Log (" %s\n", ptokens->token); - ptokens++; - } - return 0; - } - *buf += strlen (tokens->token); - SkipCharacters (buf, kWhiteSpace); - - *name = GetSubText (buf, 0x27, 0x27); - SkipCharacters (buf, kWhiteSpace); - - if (**buf == '=') - { - ++*buf; - *data = GetAssignmentText (buf); - } - else - { - *data = GetSubText (buf, '(', ')'); - if (!*data) - { - *data = GetSubText (buf, '{', '}'); - } - } - - - return tokens->id; -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/Parser.h b/Code/CryEngine/RenderDll/Common/Shaders/Parser.h deleted file mode 100644 index 8a21c49375..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/Parser.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -struct STokenDesc -{ - int id; - const char* token; -}; -int shGetObject(char** buf, STokenDesc* tokens, char** name, char** data); - - -extern const char* kWhiteSpace; -extern FXMacro sStaticMacros; - -bool SkipChar(unsigned int ch); - -void fxParserInit(void); - -void SkipCharacters(char** buf, const char* toSkip); -void RemoveCR(char* buf); -void SkipComments(char** buf, bool bSkipWhiteSpace); - -bool fxIsFirstPass(char* buf); -void fxRegisterEnv(const char* szStr); - -int shFill(char** buf, char* dst, int nSize = -1); -int fxFill(char** buf, char* dst, int nSize = -1); -char* fxFillPr (char** buf, char* dst); -char* fxFillPrC (char** buf, char* dst); -char* fxFillNumber (char** buf, char* dst); -int fxFillCR(char** buf, char* dst); - -bool shGetBool(char* buf); -float shGetFloat(const char* buf); -void shGetFloat(const char* buf, float* v1, float* v2); -int shGetInt(const char* buf); -int shGetHex(const char* buf); -uint64 shGetHex64(const char* buf); -void shGetVector(char* buf, Vec3& v); -void shGetVector(char* buf, float v[3]); -void shGetVector4(char* buf, vec4_t& v); -void shGetColor(const char* buf, ColorF& v); -void shGetColor(char* buf, float v[4]); -int shGetVar (char** buf, char** vr, char** val); diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.cpp deleted file mode 100644 index 71c99907f9..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.cpp +++ /dev/null @@ -1,3730 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Script parser implementations. - - -#include "RenderDll_precompiled.h" -#include "CryCrc32.h" -#include "../RenderCapabilities.h" -#include -#include - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define PARSERBIN_CPP_SECTION_1 1 -#define PARSERBIN_CPP_SECTION_2 2 -#endif - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) -#include "../../XRenderD3D9/DriverD3D.h" // for gcpRendD3D -#endif - -const char* g_KeyTokens[eT_max]; -TArray sfxIFDef; - -bool CParserBin::m_bEditable; -uint32 CParserBin::m_nPlatform; -AZ::PlatformID CParserBin::m_targetPlatform = AZ::PlatformID::PLATFORM_MAX; -bool CParserBin::m_bEndians; -bool CParserBin::m_bParseFX = true; -bool CParserBin::m_bShaderCacheGen = false; - -ShaderBucketAllocator g_shaderBucketAllocator; - -IGeneralMemoryHeap* g_shaderGeneralHeap = nullptr; - -CParserBin::CParserBin(SShaderBin* pBin) -{ - m_pCurBinShader = pBin; - m_pCurShader = NULL; - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} -CParserBin::CParserBin(SShaderBin* pBin, CShader* pSH) -{ - m_pCurBinShader = pBin; - m_pCurShader = pSH; - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -CParserBin::~CParserBin() -{ - sfxIFIgnore.clear(); - sfxIFDef.clear(); - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); -} - -void CParserBin::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_FULL_SHUTDOWN: - { - sfxIFIgnore.clear(); - sfxIFDef.clear(); - } - break; - } -} - -uint32 CParserBin::GetCRC32(const char* szStr) -{ - uint32 nGen = CCrc32::Compute(szStr); - assert(nGen >= eT_user_first); - - return nGen; -} - -FXMacroBin CParserBin::m_StaticMacros; - -void CParserBin::Init() -{ - // Register key tokens - fxTokenKey("#include", eT_include); - fxTokenKey("#define", eT_define); - fxTokenKey("#undefine", eT_undefine); - fxTokenKey("#define", eT_define_2); - fxTokenKey("#fetchinst", eT_fetchinst); - fxTokenKey("#if", eT_if); - fxTokenKey("#ifdef", eT_ifdef); - fxTokenKey("#ifndef", eT_ifndef); - fxTokenKey("#if", eT_if_2); - fxTokenKey("#ifdef", eT_ifdef_2); - fxTokenKey("#ifndef", eT_ifndef_2); - fxTokenKey("#endif", eT_endif); - fxTokenKey("#else", eT_else); - fxTokenKey("#elif", eT_elif); - fxTokenKey("#warning", eT_warning); - fxTokenKey("#register_env", eT_register_env); - fxTokenKey("#ifcvar", eT_ifcvar); - fxTokenKey("#ifncvar", eT_ifncvar); - fxTokenKey("#elifcvar", eT_elifcvar); - fxTokenKey("#skip", eT_skip); - fxTokenKey("#skip_(", eT_skip_1); - fxTokenKey("#skip_)", eT_skip_2); - - fxTokenKey("|", eT_or); - fxTokenKey("&", eT_and); - - fxTokenKey("(", eT_br_rnd_1); - fxTokenKey(")", eT_br_rnd_2); - fxTokenKey("[", eT_br_sq_1); - fxTokenKey("]", eT_br_sq_2); - fxTokenKey("{", eT_br_cv_1); - fxTokenKey("}", eT_br_cv_2); - fxTokenKey("<", eT_br_tr_1); - fxTokenKey(">", eT_br_tr_2); - fxTokenKey(",", eT_comma); - fxTokenKey(".", eT_dot); - fxTokenKey(":", eT_colon); - fxTokenKey(";", eT_semicolumn); - fxTokenKey("!", eT_excl); - fxTokenKey("\"", eT_quote); - fxTokenKey("'", eT_sing_quote); - - fxTokenKey("s0", eT_s0); - fxTokenKey("s1", eT_s1); - fxTokenKey("s2", eT_s2); - fxTokenKey("s3", eT_s3); - fxTokenKey("s4", eT_s4); - fxTokenKey("s5", eT_s5); - fxTokenKey("s6", eT_s6); - fxTokenKey("s7", eT_s7); - fxTokenKey("s8", eT_s8); - fxTokenKey("s9", eT_s9); - fxTokenKey("s10", eT_s10); - fxTokenKey("s11", eT_s11); - fxTokenKey("s12", eT_s12); - fxTokenKey("s13", eT_s13); - fxTokenKey("s14", eT_s14); - fxTokenKey("s15", eT_s15); - - fxTokenKey("t0", eT_t0); - fxTokenKey("t1", eT_t1); - fxTokenKey("t2", eT_t2); - fxTokenKey("t3", eT_t3); - fxTokenKey("t4", eT_t4); - fxTokenKey("t5", eT_t5); - fxTokenKey("t6", eT_t6); - fxTokenKey("t7", eT_t7); - fxTokenKey("t8", eT_t8); - fxTokenKey("t9", eT_t9); - fxTokenKey("t10", eT_t10); - fxTokenKey("t11", eT_t11); - fxTokenKey("t12", eT_t12); - fxTokenKey("t13", eT_t13); - fxTokenKey("t14", eT_t14); - fxTokenKey("t15", eT_t15); - - fxTokenKey("//", eT_comment); - - fxTokenKey("?", eT_question); - fxTokenKey("=", eT_eq); - fxTokenKey("+", eT_plus); - fxTokenKey("-", eT_minus); - fxTokenKey("/", eT_div); - fxTokenKey("*", eT_mul); - fxTokenKey("dot", eT_dot_math); - fxTokenKey("mul", eT_mul_math); - fxTokenKey("sqrt", eT_sqrt_math); - fxTokenKey("exp", eT_exp_math); - fxTokenKey("log", eT_log_math); - fxTokenKey("log2", eT_log2_math); - fxTokenKey("sin", eT_sin_math); - fxTokenKey("cos", eT_cos_math); - fxTokenKey("sincos", eT_sincos_math); - fxTokenKey("floor", eT_floor_math); - fxTokenKey("floor", eT_ceil_math); - fxTokenKey("frac", eT_frac_math); - fxTokenKey("lerp", eT_lerp_math); - fxTokenKey("abs", eT_abs_math); - fxTokenKey("clamp", eT_clamp_math); - fxTokenKey("min", eT_min_math); - fxTokenKey("max", eT_max_math); - fxTokenKey("length", eT_length_math); - - fxTokenKey("%_LT_LIGHTS", eT__LT_LIGHTS); - fxTokenKey("%_LT_NUM", eT__LT_NUM); - fxTokenKey("%_LT_HASPROJ", eT__LT_HASPROJ); - fxTokenKey("%_LT_0_TYPE", eT__LT_0_TYPE); - fxTokenKey("%_LT_1_TYPE", eT__LT_1_TYPE); - fxTokenKey("%_LT_2_TYPE", eT__LT_2_TYPE); - fxTokenKey("%_LT_3_TYPE", eT__LT_3_TYPE); - fxTokenKey("%_TT_TEXCOORD_MATRIX", eT__TT_TEXCOORD_MATRIX); - fxTokenKey("%_TT_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE", eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE); - fxTokenKey("%_TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE", eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE); - fxTokenKey("%_TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT", eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT); - fxTokenKey("%_TT_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL", eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL); - fxTokenKey("%_TT_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM", eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM); - fxTokenKey("%_TT_TEXCOORD_PROJ", eT__TT_TEXCOORD_PROJ); - fxTokenKey("%_VT_TYPE", eT__VT_TYPE); - fxTokenKey("%_VT_TYPE_MODIF", eT__VT_TYPE_MODIF); - fxTokenKey("%_VT_BEND", eT__VT_BEND); - fxTokenKey("%_VT_DET_BEND", eT__VT_DET_BEND); - fxTokenKey("%_VT_GRASS", eT__VT_GRASS); - fxTokenKey("%_VT_WIND", eT__VT_WIND); - fxTokenKey("%_VT_DEPTH_OFFSET", eT__VT_DEPTH_OFFSET); - fxTokenKey("%_FT_TEXTURE", eT__FT_TEXTURE); - fxTokenKey("%_FT_TEXTURE1", eT__FT_TEXTURE1); - fxTokenKey("%_FT_NORMAL", eT__FT_NORMAL); - fxTokenKey("%_FT_PSIZE", eT__FT_PSIZE); - fxTokenKey("%_FT_DIFFUSE", eT__FT_DIFFUSE); - fxTokenKey("%_FT_SPECULAR", eT__FT_SPECULAR); - fxTokenKey("%_FT_TANGENT_STREAM", eT__FT_TANGENT_STREAM); - fxTokenKey("%_FT_QTANGENT_STREAM", eT__FT_QTANGENT_STREAM); - fxTokenKey("%_FT_SKIN_STREAM", eT__FT_SKIN_STREAM); - fxTokenKey("%_FT_VERTEX_VELOCITY_STREAM", eT__FT_VERTEX_VELOCITY_STREAM); - fxTokenKey("%_FT_SRGBWRITE", eT__FT_SRGBWRITE); - fxTokenKey("%_FT0_COP", eT__FT0_COP); - fxTokenKey("%_FT0_AOP", eT__FT0_AOP); - fxTokenKey("%_FT0_CARG1", eT__FT0_CARG1); - fxTokenKey("%_FT0_CARG2", eT__FT0_CARG2); - fxTokenKey("%_FT0_AARG1", eT__FT0_AARG1); - fxTokenKey("%_FT0_AARG2", eT__FT0_AARG2); - - fxTokenKey("%_VS", eT__VS); - fxTokenKey("%_PS", eT__PS); - fxTokenKey("%_GS", eT__GS); - fxTokenKey("%_HS", eT__HS); - fxTokenKey("%_DS", eT__DS); - fxTokenKey("%_CS", eT__CS); - - FX_REGISTER_TOKEN(_g_SkinQuat); - - FX_REGISTER_TOKEN(tex2D); - FX_REGISTER_TOKEN(tex2Dproj); - FX_REGISTER_TOKEN(tex3D); - FX_REGISTER_TOKEN(texCUBE); - FX_REGISTER_TOKEN(sampler1D); - FX_REGISTER_TOKEN(sampler2D); - FX_REGISTER_TOKEN(sampler3D); - FX_REGISTER_TOKEN(samplerCUBE); - FX_REGISTER_TOKEN(SamplerState); - FX_REGISTER_TOKEN(SamplerComparisonState); - FX_REGISTER_TOKEN(sampler_state); - FX_REGISTER_TOKEN(Texture2D); - FX_REGISTER_TOKEN(Texture2DArray); - FX_REGISTER_TOKEN(Texture2DMS); - FX_REGISTER_TOKEN(RWTexture2D); - FX_REGISTER_TOKEN(RWTexture2DArray); - FX_REGISTER_TOKEN(TextureCube); - FX_REGISTER_TOKEN(TextureCubeArray); - FX_REGISTER_TOKEN(Texture3D); - FX_REGISTER_TOKEN(RWTexture3D); - - FX_REGISTER_TOKEN(float); - FX_REGISTER_TOKEN(float2); - FX_REGISTER_TOKEN(float3); - FX_REGISTER_TOKEN(float4); - FX_REGISTER_TOKEN(float4x4); - FX_REGISTER_TOKEN(float3x4); - FX_REGISTER_TOKEN(float2x4); - FX_REGISTER_TOKEN(float3x3); - FX_REGISTER_TOKEN(half); - FX_REGISTER_TOKEN(half2); - FX_REGISTER_TOKEN(half3); - FX_REGISTER_TOKEN(half4); - FX_REGISTER_TOKEN(half4x4); - FX_REGISTER_TOKEN(half3x4); - FX_REGISTER_TOKEN(half2x4); - FX_REGISTER_TOKEN(half3x3); - FX_REGISTER_TOKEN(bool); - FX_REGISTER_TOKEN(int); - FX_REGISTER_TOKEN(int2); - FX_REGISTER_TOKEN(int4); - FX_REGISTER_TOKEN(uint); - FX_REGISTER_TOKEN(uint2); - FX_REGISTER_TOKEN(uint4); - - FX_REGISTER_TOKEN(inout); - FX_REGISTER_TOKEN(asm); - - FX_REGISTER_TOKEN(struct); - FX_REGISTER_TOKEN(sampler); - FX_REGISTER_TOKEN(const); - FX_REGISTER_TOKEN(static); - FX_REGISTER_TOKEN(groupshared); - FX_REGISTER_TOKEN(TEXCOORDN); - FX_REGISTER_TOKEN(TEXCOORD0); - FX_REGISTER_TOKEN(TEXCOORD1); - FX_REGISTER_TOKEN(TEXCOORD2); - FX_REGISTER_TOKEN(TEXCOORD3); - FX_REGISTER_TOKEN(TEXCOORD4); - FX_REGISTER_TOKEN(TEXCOORD5); - FX_REGISTER_TOKEN(TEXCOORD6); - FX_REGISTER_TOKEN(TEXCOORD7); - FX_REGISTER_TOKEN(TEXCOORD8); - FX_REGISTER_TOKEN(TEXCOORD9); - FX_REGISTER_TOKEN(TEXCOORD10); - FX_REGISTER_TOKEN(TEXCOORD11); - FX_REGISTER_TOKEN(TEXCOORD12); - FX_REGISTER_TOKEN(TEXCOORD13); - FX_REGISTER_TOKEN(TEXCOORD14); - FX_REGISTER_TOKEN(TEXCOORD15); - FX_REGISTER_TOKEN(TEXCOORD16); - FX_REGISTER_TOKEN(TEXCOORD17); - FX_REGISTER_TOKEN(TEXCOORD18); - FX_REGISTER_TOKEN(TEXCOORD19); - FX_REGISTER_TOKEN(TEXCOORD20); - FX_REGISTER_TOKEN(TEXCOORD21); - FX_REGISTER_TOKEN(TEXCOORD22); - FX_REGISTER_TOKEN(TEXCOORD23); - FX_REGISTER_TOKEN(TEXCOORD24); - FX_REGISTER_TOKEN(TEXCOORD25); - FX_REGISTER_TOKEN(TEXCOORD26); - FX_REGISTER_TOKEN(TEXCOORD27); - FX_REGISTER_TOKEN(TEXCOORD28); - FX_REGISTER_TOKEN(TEXCOORD29); - FX_REGISTER_TOKEN(TEXCOORD30); - FX_REGISTER_TOKEN(TEXCOORD31); - FX_REGISTER_TOKEN(TEXCOORDN_centroid); - FX_REGISTER_TOKEN(TEXCOORD0_centroid); - FX_REGISTER_TOKEN(TEXCOORD1_centroid); - FX_REGISTER_TOKEN(TEXCOORD2_centroid); - FX_REGISTER_TOKEN(TEXCOORD3_centroid); - FX_REGISTER_TOKEN(TEXCOORD4_centroid); - FX_REGISTER_TOKEN(TEXCOORD5_centroid); - FX_REGISTER_TOKEN(TEXCOORD6_centroid); - FX_REGISTER_TOKEN(TEXCOORD7_centroid); - FX_REGISTER_TOKEN(TEXCOORD8_centroid); - FX_REGISTER_TOKEN(TEXCOORD9_centroid); - FX_REGISTER_TOKEN(TEXCOORD10_centroid); - FX_REGISTER_TOKEN(TEXCOORD11_centroid); - FX_REGISTER_TOKEN(TEXCOORD12_centroid); - FX_REGISTER_TOKEN(TEXCOORD13_centroid); - FX_REGISTER_TOKEN(TEXCOORD14_centroid); - FX_REGISTER_TOKEN(TEXCOORD15_centroid); - FX_REGISTER_TOKEN(TEXCOORD16_centroid); - FX_REGISTER_TOKEN(TEXCOORD17_centroid); - FX_REGISTER_TOKEN(TEXCOORD18_centroid); - FX_REGISTER_TOKEN(TEXCOORD19_centroid); - FX_REGISTER_TOKEN(TEXCOORD20_centroid); - FX_REGISTER_TOKEN(TEXCOORD21_centroid); - FX_REGISTER_TOKEN(TEXCOORD22_centroid); - FX_REGISTER_TOKEN(TEXCOORD23_centroid); - FX_REGISTER_TOKEN(TEXCOORD24_centroid); - FX_REGISTER_TOKEN(TEXCOORD25_centroid); - FX_REGISTER_TOKEN(TEXCOORD26_centroid); - FX_REGISTER_TOKEN(TEXCOORD27_centroid); - FX_REGISTER_TOKEN(TEXCOORD28_centroid); - FX_REGISTER_TOKEN(TEXCOORD29_centroid); - FX_REGISTER_TOKEN(TEXCOORD30_centroid); - FX_REGISTER_TOKEN(TEXCOORD31_centroid); - FX_REGISTER_TOKEN(COLOR0); - - FX_REGISTER_TOKEN(packoffset); - FX_REGISTER_TOKEN(register); - FX_REGISTER_TOKEN(return ); - FX_REGISTER_TOKEN(vsregister); - FX_REGISTER_TOKEN(psregister); - FX_REGISTER_TOKEN(gsregister); - FX_REGISTER_TOKEN(dsregister); - FX_REGISTER_TOKEN(hsregister); - FX_REGISTER_TOKEN(csregister); - FX_REGISTER_TOKEN(slot); - FX_REGISTER_TOKEN(vsslot); - FX_REGISTER_TOKEN(psslot); - FX_REGISTER_TOKEN(gsslot); - FX_REGISTER_TOKEN(dsslot); - FX_REGISTER_TOKEN(hsslot); - FX_REGISTER_TOKEN(csslot); - FX_REGISTER_TOKEN(color); - - FX_REGISTER_TOKEN(Buffer); - FX_REGISTER_TOKEN(RWBuffer); - FX_REGISTER_TOKEN(StructuredBuffer); - FX_REGISTER_TOKEN(RWStructuredBuffer); - FX_REGISTER_TOKEN(ByteAddressBuffer); - FX_REGISTER_TOKEN(RWByteAddressBuffer); - FX_REGISTER_TOKEN(RasterizerOrderedBuffer); - FX_REGISTER_TOKEN(RasterizerOrderedByteAddressBuffer); - FX_REGISTER_TOKEN(RasterizerOrderedStructuredBuffer); - - FX_REGISTER_TOKEN(Position); - FX_REGISTER_TOKEN(Allways); - - FX_REGISTER_TOKEN(STANDARDSGLOBAL); - - FX_REGISTER_TOKEN(technique); - FX_REGISTER_TOKEN(string); - FX_REGISTER_TOKEN(UIName); - FX_REGISTER_TOKEN(UIDescription); - FX_REGISTER_TOKEN(UIWidget); - FX_REGISTER_TOKEN(UIWidget0); - FX_REGISTER_TOKEN(UIWidget1); - FX_REGISTER_TOKEN(UIWidget2); - FX_REGISTER_TOKEN(UIWidget3); - - FX_REGISTER_TOKEN(Texture); - FX_REGISTER_TOKEN(Filter); - FX_REGISTER_TOKEN(MinFilter); - FX_REGISTER_TOKEN(MagFilter); - FX_REGISTER_TOKEN(MipFilter); - FX_REGISTER_TOKEN(AddressU); - FX_REGISTER_TOKEN(AddressV); - FX_REGISTER_TOKEN(AddressW); - FX_REGISTER_TOKEN(BorderColor); - FX_REGISTER_TOKEN(AnisotropyLevel); - FX_REGISTER_TOKEN(sRGBLookup); - FX_REGISTER_TOKEN(Global); - - FX_REGISTER_TOKEN(LINEAR); - FX_REGISTER_TOKEN(POINT); - FX_REGISTER_TOKEN(NONE); - FX_REGISTER_TOKEN(ANISOTROPIC); - FX_REGISTER_TOKEN(MIN_MAG_MIP_POINT); - FX_REGISTER_TOKEN(MIN_MAG_MIP_LINEAR); - FX_REGISTER_TOKEN(MIN_MAG_LINEAR_MIP_POINT); - FX_REGISTER_TOKEN(COMPARISON_MIN_MAG_LINEAR_MIP_POINT); - FX_REGISTER_TOKEN(MINIMUM_MIN_MAG_MIP_LINEAR); - FX_REGISTER_TOKEN(MAXIMUM_MIN_MAG_MIP_LINEAR); - - FX_REGISTER_TOKEN(Clamp); - FX_REGISTER_TOKEN(Border); - FX_REGISTER_TOKEN(Wrap); - FX_REGISTER_TOKEN(Mirror); - - FX_REGISTER_TOKEN(Script); - - FX_REGISTER_TOKEN(RenderOrder); - FX_REGISTER_TOKEN(ProcessOrder); - FX_REGISTER_TOKEN(RenderCamera); - FX_REGISTER_TOKEN(RenderType); - FX_REGISTER_TOKEN(RenderFilter); - FX_REGISTER_TOKEN(RenderColorTarget1); - FX_REGISTER_TOKEN(RenderDepthStencilTarget); - FX_REGISTER_TOKEN(ClearSetColor); - FX_REGISTER_TOKEN(ClearSetDepth); - FX_REGISTER_TOKEN(ClearTarget); - FX_REGISTER_TOKEN(RenderTarget_IDPool); - FX_REGISTER_TOKEN(RenderTarget_UpdateType); - FX_REGISTER_TOKEN(RenderTarget_Width); - FX_REGISTER_TOKEN(RenderTarget_Height); - FX_REGISTER_TOKEN(GenerateMips); - - FX_REGISTER_TOKEN(PreProcess); - FX_REGISTER_TOKEN(PostProcess); - FX_REGISTER_TOKEN(PreDraw); - - FX_REGISTER_TOKEN(WaterReflection); - FX_REGISTER_TOKEN(Panorama); - - FX_REGISTER_TOKEN(WaterPlaneReflected); - FX_REGISTER_TOKEN(PlaneReflected); - FX_REGISTER_TOKEN(Current); - - FX_REGISTER_TOKEN(CurObject); - FX_REGISTER_TOKEN(CurScene); - FX_REGISTER_TOKEN(RecursiveScene); - FX_REGISTER_TOKEN(CopyScene); - - FX_REGISTER_TOKEN(Refractive); - FX_REGISTER_TOKEN(ForceRefractionUpdate); - FX_REGISTER_TOKEN(Heat); - - FX_REGISTER_TOKEN(DepthBuffer); - FX_REGISTER_TOKEN(DepthBufferTemp); - FX_REGISTER_TOKEN(DepthBufferOrig); - - FX_REGISTER_TOKEN($ScreenSize); - FX_REGISTER_TOKEN(WaterReflect); - FX_REGISTER_TOKEN(FogColor); - - FX_REGISTER_TOKEN(Color); - FX_REGISTER_TOKEN(Depth); - - FX_REGISTER_TOKEN($RT_2D); - FX_REGISTER_TOKEN($RT_Cube); - - FX_REGISTER_TOKEN(pass); - FX_REGISTER_TOKEN(CustomRE); - FX_REGISTER_TOKEN(Style); - - FX_REGISTER_TOKEN(VertexShader); - FX_REGISTER_TOKEN(PixelShader); - FX_REGISTER_TOKEN(GeometryShader); - FX_REGISTER_TOKEN(DomainShader); - FX_REGISTER_TOKEN(HullShader); - FX_REGISTER_TOKEN(ComputeShader); - FX_REGISTER_TOKEN(ZEnable); - FX_REGISTER_TOKEN(ZWriteEnable); - FX_REGISTER_TOKEN(CullMode); - FX_REGISTER_TOKEN(SrcBlend); - FX_REGISTER_TOKEN(DestBlend); - FX_REGISTER_TOKEN(AlphaBlendEnable); - FX_REGISTER_TOKEN(AlphaFunc); - FX_REGISTER_TOKEN(AlphaRef); - FX_REGISTER_TOKEN(ZFunc); - FX_REGISTER_TOKEN(ColorWriteEnable); - FX_REGISTER_TOKEN(IgnoreMaterialState); - - FX_REGISTER_TOKEN(None); - FX_REGISTER_TOKEN(Disable); - FX_REGISTER_TOKEN(CCW); - FX_REGISTER_TOKEN(CW); - FX_REGISTER_TOKEN(Back); - FX_REGISTER_TOKEN(Front); - - FX_REGISTER_TOKEN(Never); - FX_REGISTER_TOKEN(Less); - FX_REGISTER_TOKEN(Equal); - FX_REGISTER_TOKEN(LEqual); - FX_REGISTER_TOKEN(LessEqual); - FX_REGISTER_TOKEN(NotEqual); - FX_REGISTER_TOKEN(GEqual); - FX_REGISTER_TOKEN(GreaterEqual); - FX_REGISTER_TOKEN(Greater) - FX_REGISTER_TOKEN(Always); - - FX_REGISTER_TOKEN(RED); - FX_REGISTER_TOKEN(GREEN); - FX_REGISTER_TOKEN(BLUE); - FX_REGISTER_TOKEN(ALPHA); - - FX_REGISTER_TOKEN(ONE); - FX_REGISTER_TOKEN(ZERO); - FX_REGISTER_TOKEN(SRC_COLOR); - FX_REGISTER_TOKEN(SrcColor); - FX_REGISTER_TOKEN(ONE_MINUS_SRC_COLOR); - FX_REGISTER_TOKEN(InvSrcColor); - FX_REGISTER_TOKEN(SRC_ALPHA); - FX_REGISTER_TOKEN(SrcAlpha); - FX_REGISTER_TOKEN(ONE_MINUS_SRC_ALPHA); - FX_REGISTER_TOKEN(InvSrcAlpha); - FX_REGISTER_TOKEN(DST_ALPHA); - FX_REGISTER_TOKEN(DestAlpha); - FX_REGISTER_TOKEN(ONE_MINUS_DST_ALPHA); - FX_REGISTER_TOKEN(InvDestAlpha); - FX_REGISTER_TOKEN(DST_COLOR); - FX_REGISTER_TOKEN(DestColor); - FX_REGISTER_TOKEN(ONE_MINUS_DST_COLOR); - FX_REGISTER_TOKEN(InvDestColor); - FX_REGISTER_TOKEN(SRC_ALPHA_SATURATE); - - FX_REGISTER_TOKEN(NULL); - - FX_REGISTER_TOKEN(cbuffer); - FX_REGISTER_TOKEN(PER_BATCH); - FX_REGISTER_TOKEN(PER_INSTANCE); - FX_REGISTER_TOKEN(PER_FRAME); - FX_REGISTER_TOKEN(PER_MATERIAL); - FX_REGISTER_TOKEN(PER_SHADOWGEN); - - FX_REGISTER_TOKEN(ShaderType); - FX_REGISTER_TOKEN(ShaderDrawType); - FX_REGISTER_TOKEN(PreprType); - FX_REGISTER_TOKEN(Public); - FX_REGISTER_TOKEN(NoPreview); - FX_REGISTER_TOKEN(LocalConstants); - FX_REGISTER_TOKEN(Cull); - FX_REGISTER_TOKEN(SupportsAttrInstancing); - FX_REGISTER_TOKEN(SupportsConstInstancing); - FX_REGISTER_TOKEN(SupportsDeferredShading); - FX_REGISTER_TOKEN(SupportsFullDeferredShading); - FX_REGISTER_TOKEN(Decal); - FX_REGISTER_TOKEN(DecalNoDepthOffset); - FX_REGISTER_TOKEN(NoChunkMerging); - FX_REGISTER_TOKEN(ForceTransPass); - FX_REGISTER_TOKEN(AfterHDRPostProcess); - FX_REGISTER_TOKEN(AfterPostProcess); - FX_REGISTER_TOKEN(ForceZpass); - FX_REGISTER_TOKEN(ForceWaterPass); - FX_REGISTER_TOKEN(ForceDrawLast); - FX_REGISTER_TOKEN(ForceDrawFirst); - FX_REGISTER_TOKEN(ForceDrawAfterWater); - FX_REGISTER_TOKEN(DepthFixup); - FX_REGISTER_TOKEN(SingleLightPass); - FX_REGISTER_TOKEN(HWTessellation); - FX_REGISTER_TOKEN(VertexColors); - FX_REGISTER_TOKEN(WaterParticle); - FX_REGISTER_TOKEN(AlphaBlendShadows); - FX_REGISTER_TOKEN(ZPrePass); - - FX_REGISTER_TOKEN(VT_DetailBendingGrass); - FX_REGISTER_TOKEN(VT_DetailBending); - FX_REGISTER_TOKEN(VT_WindBending); - - FX_REGISTER_TOKEN(Light); - FX_REGISTER_TOKEN(Shadow); - FX_REGISTER_TOKEN(Fur); - FX_REGISTER_TOKEN(General); - FX_REGISTER_TOKEN(Terrain); - FX_REGISTER_TOKEN(Overlay); - FX_REGISTER_TOKEN(NoDraw); - FX_REGISTER_TOKEN(Custom); - FX_REGISTER_TOKEN(Sky); - FX_REGISTER_TOKEN(OceanShore); - FX_REGISTER_TOKEN(Hair); - FX_REGISTER_TOKEN(Compute); - FX_REGISTER_TOKEN(SkinPass); - FX_REGISTER_TOKEN(ForceGeneralPass); - FX_REGISTER_TOKEN(EyeOverlay); - - FX_REGISTER_TOKEN(Metal); - FX_REGISTER_TOKEN(Ice); - FX_REGISTER_TOKEN(Water); - FX_REGISTER_TOKEN(FX); - FX_REGISTER_TOKEN(HDR); - FX_REGISTER_TOKEN(Glass); - FX_REGISTER_TOKEN(Vegetation); - FX_REGISTER_TOKEN(Particle); - FX_REGISTER_TOKEN(GenerateSprites); - FX_REGISTER_TOKEN(GenerateClouds); - FX_REGISTER_TOKEN(ScanWater); - - FX_REGISTER_TOKEN(NoLights); - FX_REGISTER_TOKEN(NoMaterialState); - FX_REGISTER_TOKEN(PositionInvariant); - FX_REGISTER_TOKEN(TechniqueZ); - FX_REGISTER_TOKEN(TechniqueZPrepass); - FX_REGISTER_TOKEN(TechniqueShadowGen); - FX_REGISTER_TOKEN(TechniqueMotionBlur); - FX_REGISTER_TOKEN(TechniqueCustomRender); - FX_REGISTER_TOKEN(TechniqueEffectLayer); - FX_REGISTER_TOKEN(TechniqueDebug); - FX_REGISTER_TOKEN(TechniqueSoftAlphaTest); - FX_REGISTER_TOKEN(TechniqueWaterRefl); - FX_REGISTER_TOKEN(TechniqueWaterCaustic); - FX_REGISTER_TOKEN(TechniqueThickness); - - FX_REGISTER_TOKEN(KeyFrameParams); - FX_REGISTER_TOKEN(KeyFrameRandColor); - FX_REGISTER_TOKEN(KeyFrameRandIntensity); - FX_REGISTER_TOKEN(KeyFrameRandSpecMult); - FX_REGISTER_TOKEN(KeyFrameRandPosOffset); - FX_REGISTER_TOKEN(Speed); - - FX_REGISTER_TOKEN(Beam); - FX_REGISTER_TOKEN(LensOptics); - FX_REGISTER_TOKEN(Cloud); - FX_REGISTER_TOKEN(Ocean); - - FX_REGISTER_TOKEN(Model); - FX_REGISTER_TOKEN(StartRadius); - FX_REGISTER_TOKEN(EndRadius); - FX_REGISTER_TOKEN(StartColor); - FX_REGISTER_TOKEN(EndColor); - FX_REGISTER_TOKEN(LightStyle); - FX_REGISTER_TOKEN(Length); - - FX_REGISTER_TOKEN(RGBStyle); - FX_REGISTER_TOKEN(Scale); - FX_REGISTER_TOKEN(Blind); - FX_REGISTER_TOKEN(SizeBlindScale); - FX_REGISTER_TOKEN(SizeBlindBias); - FX_REGISTER_TOKEN(IntensBlindScale); - FX_REGISTER_TOKEN(IntensBlindBias); - FX_REGISTER_TOKEN(MinLight); - FX_REGISTER_TOKEN(DistFactor); - FX_REGISTER_TOKEN(DistIntensityFactor); - FX_REGISTER_TOKEN(FadeTime); - FX_REGISTER_TOKEN(Layer); - FX_REGISTER_TOKEN(Importance); - FX_REGISTER_TOKEN(VisAreaScale); - - FX_REGISTER_TOKEN(Poly); - FX_REGISTER_TOKEN(Identity); - FX_REGISTER_TOKEN(FromObj); - FX_REGISTER_TOKEN(FromLight); - FX_REGISTER_TOKEN(Fixed); - - FX_REGISTER_TOKEN(ParticlesFile); - - FX_REGISTER_TOKEN(Gravity); - FX_REGISTER_TOKEN(WindDirection); - FX_REGISTER_TOKEN(WindSpeed); - FX_REGISTER_TOKEN(WaveHeight); - FX_REGISTER_TOKEN(DirectionalDependence); - FX_REGISTER_TOKEN(ChoppyWaveFactor); - FX_REGISTER_TOKEN(SuppressSmallWavesFactor); - - FX_REGISTER_TOKEN(x); - FX_REGISTER_TOKEN(y); - FX_REGISTER_TOKEN(z); - FX_REGISTER_TOKEN(w); - FX_REGISTER_TOKEN(r); - FX_REGISTER_TOKEN(g); - FX_REGISTER_TOKEN(b); - FX_REGISTER_TOKEN(a); - - FX_REGISTER_TOKEN(true); - FX_REGISTER_TOKEN(false); - - FX_REGISTER_TOKEN(0); - FX_REGISTER_TOKEN(1); - FX_REGISTER_TOKEN(2); - FX_REGISTER_TOKEN(3); - FX_REGISTER_TOKEN(4); - FX_REGISTER_TOKEN(5); - FX_REGISTER_TOKEN(6); - FX_REGISTER_TOKEN(7); - FX_REGISTER_TOKEN(8); - FX_REGISTER_TOKEN(9); - FX_REGISTER_TOKEN(10); - FX_REGISTER_TOKEN(11); - FX_REGISTER_TOKEN(12); - FX_REGISTER_TOKEN(13); - FX_REGISTER_TOKEN(14); - FX_REGISTER_TOKEN(15); - FX_REGISTER_TOKEN(16); - FX_REGISTER_TOKEN(17); - FX_REGISTER_TOKEN(18); - FX_REGISTER_TOKEN(19); - FX_REGISTER_TOKEN(20); - FX_REGISTER_TOKEN(21); - FX_REGISTER_TOKEN(22); - FX_REGISTER_TOKEN(23); - FX_REGISTER_TOKEN(24); - - FX_REGISTER_TOKEN(ORBIS); - FX_REGISTER_TOKEN(PCDX11); - FX_REGISTER_TOKEN(GL4); - FX_REGISTER_TOKEN(GLES3); - FX_REGISTER_TOKEN(METAL); - FX_REGISTER_TOKEN(OSXMETAL); - FX_REGISTER_TOKEN(IOSMETAL); - - FX_REGISTER_TOKEN(STANDARDSGLOBAL); - - FX_REGISTER_TOKEN(GLES3_0); - - FX_REGISTER_TOKEN(Load); - FX_REGISTER_TOKEN(Sample); - FX_REGISTER_TOKEN(Gather); - FX_REGISTER_TOKEN(GatherRed); - FX_REGISTER_TOKEN(GatherGreen); - FX_REGISTER_TOKEN(GatherBlue); - FX_REGISTER_TOKEN(GatherAlpha); - - FXMacroItor it; - for (it = sStaticMacros.begin(); it != sStaticMacros.end(); it++) - { - bool bKey = false; - uint32 nName = CParserBin::fxToken(it->first.c_str(), &bKey); - if (!bKey) - { - nName = GetCRC32(it->first.c_str()); - } - SMacroFX* pr = &it->second; - uint32 nMacros = 0; - uint32 Macro[64]; - if (pr->m_szMacro[0]) - { - char* szBuf = (char*)pr->m_szMacro.c_str(); - SkipCharacters (&szBuf, " "); - if (!szBuf[0]) - { - break; - } - char com[1024]; - bKey = false; - uint32 dwToken = CParserBin::NextToken(szBuf, com, bKey); - if (!bKey) - { - dwToken = GetCRC32(com); - } - Macro[nMacros++] = dwToken; - } - AddMacro(nName, Macro, nMacros, pr->m_nMask, m_StaticMacros); - } - sStaticMacros.clear(); - - if (!CParserBin::m_bShaderCacheGen) - { -#if defined(CRY_USE_METAL) - SetupForMETAL(); -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION PARSERBIN_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(ParserBin_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(OPENGL_ES) && DXGL_INPUT_GLSL - SetupForGLES3(); -#elif defined(OPENGL) && DXGL_INPUT_GLSL - SetupForGL4(); -#else - SetupForD3D11(); -#endif - } -} - -void CParserBin::SetupTargetPlatform() -{ -#if !defined(CONSOLE) - if (CParserBin::m_bShaderCacheGen) - { - m_targetPlatform = static_cast(CRenderer::CV_r_shadersPlatform); - } - else -#endif // !defined(CONSOLE) - { - m_targetPlatform = AZ::g_currentPlatform; - } -} - -void CParserBin::SetupForD3D11() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - - uint32 nMacro[1] = {eT_1}; - - AddMacro(CParserBin::fxToken("PCDX11"), nMacro, 1, 0, m_StaticMacros); - - m_nPlatform = SF_D3D11; - - SetupShadersCacheAndFilter(); - - SetupFeatureDefines(); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - -void CParserBin::SetupForGL4() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - uint32 nMacro[1] = {eT_1}; - - AddMacro(CParserBin::fxToken("GL4"), nMacro, 1, 0, m_StaticMacros); - - if (!gRenDev->IsShaderCacheGenMode()) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_ShadersUseLLVMDirectXCompiler) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_LLVM_DIRECTX_SHADER_COMPILER); - } - } - - m_nPlatform = SF_GL4; - - SetupShadersCacheAndFilter(); - - SetupFeatureDefines(); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - -void CParserBin::SetupForGLES3() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - uint32 nMacro[1] = {eT_1}; - - AddMacro(CParserBin::fxToken("GLES3"), nMacro, 1, 0, m_StaticMacros); - // Forcing small uniform buffers since OpenGLES only guarantees 16k of space for uniform blocks. - // We don't do it per device because that would add extra permutations. - AddMacro(CParserBin::GetCRC32("SMALL_UNIFORM_BUFFERS"), nMacro, 1, 0, m_StaticMacros); - - m_nPlatform = SF_GLES3; - if (!gRenDev->IsShaderCacheGenMode()) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_ShadersUseLLVMDirectXCompiler) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_LLVM_DIRECTX_SHADER_COMPILER); - } -#if defined(OPENGL_ES) - AZ_Assert(gcpRendD3D, "Null CD3D9Renderer"); - uint32 glVersion = RenderCapabilities::GetDeviceGLVersion(); - AZ_Assert(glVersion >= DXGLES_VERSION_30, "Invalid OpenGL version %lu", static_cast(glVersion)); - if (glVersion == DXGLES_VERSION_30) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_GLES3_0); - } - - if (!gcpRendD3D->UseHalfFloatRenderTargets()) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_FIXED_POINT); - } -#endif // defined(OPENGL_ES) - } - - SetupShadersCacheAndFilter(); - SetupFeatureDefines(); - SetupForGMEM(CRenderer::CV_r_EnableGMEMPath); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - - -void CParserBin::RemoveGMEMStaticFlags() -{ - gRenDev->m_cEF.RemoveStaticFlag(HWSST_GMEM_256BPP); - gRenDev->m_cEF.RemoveStaticFlag(HWSST_GMEM_128BPP); - gRenDev->m_cEF.RemoveStaticFlag(HWSST_GMEM_PLS); - gRenDev->m_cEF.RemoveStaticFlag(HWSST_GMEM_VELOCITY_BUFFER); - gRenDev->m_cEF.RemoveStaticFlag(HWSST_GMEM_RT_GREATER_FOUR); - gRenDev->m_cEF.RemoveStaticFlag(HWSST_FEATURE_FETCH_DEPTHSTENCIL); -} - -void CParserBin::SetupGMEMCommonStaticFlags() -{ -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - if (RenderCapabilities::SupportsPLSExtension()) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_GMEM_PLS); - } - - // TAA and motion blur need an extra render target to write the objects velocity. - if (CRenderer::CV_r_MotionBlur > 0 || (gRenDev->FX_GetAntialiasingType() & eAT_TEMPORAL_MASK) != 0) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_GMEM_VELOCITY_BUFFER); - } - - // Ensure that the device can support at least 5 render targets - GBUFFER A, GBUFFER B, GBUFFER C, Lin Depth/Stencil and Velocity - if (RenderCapabilities::SupportsRenderTargets(CD3D9Renderer::s_gmemLargeRTCount)) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_GMEM_RT_GREATER_FOUR); - } - - RenderCapabilities::FrameBufferFetchMask fetchCapabilities = RenderCapabilities::GetFrameBufferFetchCapabilities(); - if (fetchCapabilities.test(RenderCapabilities::FBF_DEPTH) && fetchCapabilities.test(RenderCapabilities::FBF_STENCIL)) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_FEATURE_FETCH_DEPTHSTENCIL); - } -#endif // defined(OPENGL_ES) || defined(CRY_USE_METAL) -} - -void CParserBin::SetupForMETAL() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - uint32 nMacro[1] = {eT_1}; - - AddMacro(CParserBin::fxToken("METAL"), nMacro, 1, 0, m_StaticMacros); - - switch (m_targetPlatform) - { - case AZ::PlatformID::PLATFORM_APPLE_OSX: - AddMacro(CParserBin::fxToken("OSXMETAL"), nMacro, 1, 0, m_StaticMacros); - break; - case AZ::PlatformID::PLATFORM_APPLE_IOS: - AddMacro(CParserBin::fxToken("IOSMETAL"), nMacro, 1, 0, m_StaticMacros); - break; - default: - AZ_Assert(false, "Invalid platform id (%s) for Metal shader setup", AZ::GetPlatformName(m_targetPlatform)); - return; - } - - - if (!gRenDev->IsShaderCacheGenMode()) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_ShadersUseLLVMDirectXCompiler) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_LLVM_DIRECTX_SHADER_COMPILER); - } - } - - m_nPlatform = SF_METAL; - SetupShadersCacheAndFilter(); - SetupFeatureDefines(); - SetupForGMEM(CRenderer::CV_r_EnableGMEMPath); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - -void CParserBin::SetupForGMEM([[maybe_unused]] int const gmemPath) -{ - AZ_Assert(m_nPlatform == SF_METAL || m_nPlatform == SF_GLES3, "Invalid platform (%d) for setup up GMEM"); - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - uint32 nMacro[1] = { eT_1 }; - - CD3D9Renderer::EGmemPath enabledGmemPath; - CD3D9Renderer::EGmemPathState gmemState; - assert(gcpRendD3D); - enabledGmemPath = gcpRendD3D->FX_GetEnabledGmemPath(&gmemState); - const char* strUnsupportedFeats = "CParserBin::SetupForGMEM: cannot use 256bpp GMEM path due to SSDO or SSR being used! It is recommended to disable these features on mobile platforms. Forcing 128bpp path instead."; - const char* strUnsupportedGmem256 = "CParserBin::SetupForGMEM: 256bpp GMEM path not supported on this device! Forcing 128bpp GMEM path instead."; - const char* strUnsupportedGmem128 = "CParserBin::SetupForGMEM: 128bpp GMEM path not supported on this device! Forcing regular render path instead."; - - switch (gmemPath) - { - case 0: - RemoveGMEMStaticFlags(); - break; - case 1: - { - // Does devices allow this path? - if (CD3D9Renderer::eGT_DEV_UNSUPPORTED == gmemState) - { - CryLogAlways(strUnsupportedGmem256); - SetupForGMEM(2); - return; - } - - // Some deferred passes don't fit in the 256bpp path and must be resolved. - // We can delay these passes until after the GMEM section, however the effect will be a frame behind. - // This causes ghosting artifacts. Since the 128bpp path must resolve after the G-Buffer pass anyways, - // it can also process the data for these deferred passes in time. - // This will obviously set back performance... but the following effects are very performance heavy and - // should not be used on mobile devices in most cases. - if (CD3D9Renderer::eGT_OK != gmemState && CD3D9Renderer::eGT_128bpp_PATH == enabledGmemPath) - { - CryLogAlways(strUnsupportedFeats); - SetupForGMEM(2); - return; - } - else - { - assert(CD3D9Renderer::eGT_OK == gmemState); - } - - RemoveGMEMStaticFlags(); - SetupGMEMCommonStaticFlags(); - gRenDev->m_cEF.AddStaticFlag(HWSST_GMEM_256BPP); - break; - } - case 2: - { - // Does devices allow this path? - if (CD3D9Renderer::eGT_DEV_UNSUPPORTED == gmemState && CD3D9Renderer::eGT_REGULAR_PATH == enabledGmemPath) - { - CryLogAlways(strUnsupportedGmem128); - SetupForGMEM(0); - return; - } - else - { - assert(CD3D9Renderer::eGT_128bpp_PATH == enabledGmemPath); - } - - RemoveGMEMStaticFlags(); - SetupGMEMCommonStaticFlags(); - gRenDev->m_cEF.AddStaticFlag(HWSST_GMEM_128BPP); - break; - } - default: - CRY_ASSERT(0); - } -#endif -} - -void CParserBin::SetupForOrbis() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - uint32 nMacro[1] = {eT_1}; - AddMacro(CParserBin::fxToken("ORBIS"), nMacro, 1, 0, m_StaticMacros); - m_nPlatform = SF_ORBIS; - - SetupShadersCacheAndFilter(); - - SetupFeatureDefines(); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - -void CParserBin::SetupForJasper() -{ - CleanPlatformMacros(); - SetupTargetPlatform(); - uint32 nMacro[1] = { eT_1 }; - - m_nPlatform = SF_JASPER; - - SetupShadersCacheAndFilter(); - - AddMacro(CParserBin::fxToken("JASPER"), nMacro, 1, 0, m_StaticMacros); - - SetupFeatureDefines(); - gRenDev->m_cEF.m_Bin.InvalidateCache(); - gRenDev->m_cEF.mfInitLookups(); - - SAFE_DELETE(gRenDev->m_cEF.m_pGlobalExt); - gRenDev->m_cEF.m_pGlobalExt = gRenDev->m_cEF.mfCreateShaderGenInfo("RunTime", true); -} - -CCryNameTSCRC CParserBin::GetPlatformSpecName(CCryNameTSCRC orgName) -{ - CCryNameTSCRC nmTemp = orgName; - if (CParserBin::m_nPlatform == SF_D3D11) - { - nmTemp.add(0x200); - } - else - if (CParserBin::m_nPlatform == SF_GL4) - { - nmTemp.add(0x300); - } - else - if (CParserBin::m_nPlatform == SF_GLES3) - { - nmTemp.add(0x800); - } -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION PARSERBIN_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(ParserBin_cpp) -#endif - // Confetti Nicholas Baldwin: adding metal shader language support - else - if (CParserBin::m_nPlatform == SF_METAL) - { - nmTemp.add(0x900); - } - else - if (CParserBin::m_bEndians) - { - nmTemp.add(0x500); - } - - return nmTemp; -} - -uint32 CParserBin::fxTokenKey(const char* szToken, EToken eTC) -{ - g_KeyTokens[eTC] = szToken; - return eTC; -} - -uint32 CParserBin::fxToken(const char* szToken, bool* bKey) -{ - for (int i = 0; i < eT_max; i++) - { - if (!g_KeyTokens[i]) - { - continue; - } - if (!strcmp(szToken, g_KeyTokens[i])) - { - if (bKey) - { - *bKey = true; - } - return i; - } - } - if (bKey) - { - *bKey = false; - } - return eT_unknown; -} -/*uint32 CParserBin::NewUserToken(uint32 nToken, const char* psToken, bool bUseFinalTable) -{ - const string tmpstr = psToken; - return NewUserToken(nToken,tmpstr,bUseFinalTable); -}*/ -uint32 CParserBin::NewUserToken(uint32 nToken, const char* psToken, bool bUseFinalTable) -{ - if (nToken != eT_unknown) - { - return nToken; - } - nToken = GetCRC32(psToken); - - if (bUseFinalTable) - { - FXShaderTokenItor itor = std::lower_bound(m_TokenTable.begin(), m_TokenTable.end(), nToken, SortByToken()); - if (itor != m_TokenTable.end() && (*itor).Token == nToken) - { - assert(!strcmp((*itor).SToken.c_str(), psToken)); - return nToken; - } - STokenD TD; - TD.SToken = psToken; - TD.Token = nToken; - m_TokenTable.insert(itor, TD); - } - else - { - SShaderBin* pBin = m_pCurBinShader; - assert(pBin); - FXShaderTokenItor itor = std::lower_bound(pBin->m_TokenTable.begin(), pBin->m_TokenTable.end(), nToken, SortByToken()); - if (itor != pBin->m_TokenTable.end() && (*itor).Token == nToken) - { - assert(!strcmp((*itor).SToken.c_str(), psToken)); - return nToken; - } - STokenD TD; - TD.SToken = psToken; - TD.Token = nToken; - pBin->m_TokenTable.insert(itor, TD); - } - - return nToken; -} - -uint32 CParserBin::NextToken(char*& buf, char* com, bool& bKey) -{ - char ch; - int n = 0; - while ((ch = *buf) != 0) - { - // Iterate until a special character that indicates we've reached the end of a token is found - if (SkipChar(ch)) - { - break; - } - com[n++] = ch; - ++buf; - if (ch == '/') - { - break; - } - } - // If the first character of buf returns true for SkipChar (or buf is zero-length) - if (!n) - { - // And that character is not a space - if (ch != ' ') - { - // The special character is the token that needs to be returned - com[n++] = ch; - ++buf; - } - } - com[n] = 0; - // Check to see if com is a key token, and return the enum for that token - uint32 dwToken = fxToken(com, &bKey); - return dwToken; -} - -bool CParserBin::AddMacro(uint32 dwName, const uint32* pMacro, int nMacroTokens, uint64 nMask, FXMacroBin& Macro) -{ - // Use 'lower_bound' instead of 'find' to avoid double traversal of the - // underlying tree. Iterator reused as insertion hint to 'insert()'. - FXMacroBinItor it = Macro.lower_bound(dwName); - - SMacroBinFX* macro; - if (it != Macro.end() && it->first == dwName) - { - macro = &it->second; - } - else - { - // Creates empty vector - no allocation. - macro = &Macro.insert(it, FXMacroBinItor::value_type(dwName, SMacroBinFX()))->second; - } - macro->m_nMask = nMask; - if (nMacroTokens) - { - macro->m_Macro.resize(nMacroTokens); - memcpy(¯o->m_Macro[0], pMacro, nMacroTokens * sizeof(uint32)); - } - else - { - macro->m_Macro.clear(); - } - return true; -} - -bool CParserBin::RemoveMacro(uint32 dwName, FXMacroBin& Macro) -{ - FXMacroBinItor it = Macro.find(dwName); - if (it == Macro.end()) - { - return false; - } - else - { - Macro.erase(dwName); - } - return true; -} - -void CParserBin::CleanPlatformMacros() -{ - RemoveMacro(CParserBin::fxToken("ORBIS"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("PCDX11"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("GL4"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("GLES3"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("METAL"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("OSXMETAL"), m_StaticMacros); - RemoveMacro(CParserBin::fxToken("IOSMETAL"), m_StaticMacros); -} - -const SMacroBinFX* CParserBin::FindMacro(uint32 dwName, FXMacroBin& Macro) -{ - FXMacroBinItor it = Macro.find(dwName); - if (it != Macro.end()) - { - return &it->second; - } - return NULL; -} - -bool CParserBin::GetBool(SParserFrame& Frame) -{ - if (Frame.IsEmpty()) - { - return true; - } - EToken eT = GetToken(Frame); - if (eT == eT_true || eT == eT_1) - { - return true; - } - if (eT == eT_false || eT == eT_0) - { - return false; - } - CRY_ASSERT(0); - return false; -} - -CCryNameR CParserBin::GetNameString(SParserFrame& Frame) -{ - if (Frame.IsEmpty()) - { - return CCryNameR(""); - } - - stack_string Str; - int nCur = Frame.m_nFirstToken; - int nLast = Frame.m_nLastToken; - while (nCur <= nLast) - { - int nTok = m_Tokens[nCur++]; - const char* szStr = GetString(nTok); - if (Str.size() && !SkipChar(Str[Str.size() - 1]) && !SkipChar(szStr[0])) - { - Str += " "; - } - Str += szStr; - } - return CCryNameR(Str.c_str()); -} - -string CParserBin::GetString(SParserFrame& Frame) -{ - if (Frame.IsEmpty()) - { - return ""; - } - - stack_string Str; - int nCur = Frame.m_nFirstToken; - int nLast = Frame.m_nLastToken; - while (nCur <= nLast) - { - int nTok = m_Tokens[nCur++]; - const char* szStr = GetString(nTok); - if (Str.size() && !SkipChar(Str[Str.size() - 1]) && !SkipChar(szStr[0])) - { - Str += " "; - } - Str += szStr; - } - return string(Str.c_str()); -} - -const char* CParserBin::GetString(uint32 nToken, FXShaderToken& Table, bool bOnlyKey) -{ - FXShaderTokenItor it; - if (nToken < eT_max) - { - assert(g_KeyTokens[nToken]); - return g_KeyTokens[nToken]; - } - if (!bOnlyKey) - { - it = std::lower_bound(Table.begin(), Table.end(), nToken, SortByToken()); - if (it != Table.end() && (*it).Token == nToken) - { - return (*it).SToken.c_str(); - } - } - - CRY_ASSERT(0); - return ""; -} - -const char* CParserBin::GetString(uint32 nToken, bool bOnlyKey) -{ - return GetString(nToken, m_TokenTable, bOnlyKey); -} - -static void sCR(TArray& Text, int nLevel) -{ - Text.AddElem('\n'); - for (int i = 0; i < nLevel; i++) - { - Text.AddElem(' '); - Text.AddElem(' '); - } -} - -bool CParserBin::CorrectScript(uint32* pTokens, uint32& i, uint32 nT, TArray& Text) -{ - - int nTex = Text.Num() - 1; - int nTT = nTex; - while (nTex > 0) - { - char c = Text[nTex]; - if (c <= 32) - { - nTex++; - break; - } - nTex--; - } - if (strncmp(&Text[nTex], "float", 5)) - { - CRY_ASSERT(0); - iLog->Log("Wrong script tokens..."); - return false; - } - memset(&Text[nTex], 0x20202020, nTT - nTex + 1); - i++; - while (i < nT) - { - uint32 nTok = pTokens[i]; - if (nTok == eT_semicolumn) - { - return true; - } - i++; - } - return false; -} - -bool CParserBin::ConvertToAscii(uint32* pTokens, uint32 nT, FXShaderToken& Table, TArray& Text, bool bInclSkipTokens) -{ - uint32 i; - bool bRes = true; - - int nLevel = 0; - for (i = 0; i < nT; i++) - { - uint32 nToken = pTokens[i]; - if (nToken == 0) - { - Text.Copy("\n", 1); - continue; - } - if (!bInclSkipTokens) - { - if (nToken == eT_skip) - { - i++; - continue; - } - if (nToken == eT_skip_1) - { - while (i < nT) - { - nToken = pTokens[i]; - if (nToken == eT_skip_2) - { - break; - } - i++; - } - assert(i < nT); - continue; - } - } - const char* szStr = GetString(nToken, Table, false); - assert(szStr); - if (!szStr || !szStr[0]) - { - bRes = CParserBin::CorrectScript(pTokens, i, nT, Text); - } - else - { - if (nToken == eT_semicolumn || nToken == eT_br_cv_1) - { - if (nToken == eT_br_cv_1) - { - sCR(Text, nLevel); - nLevel++; - } - Text.Copy(szStr, strlen(szStr)); - if (nToken == eT_semicolumn) - { - if (i + 1 < nT && pTokens[i + 1] == eT_br_cv_2) - { - sCR(Text, nLevel - 1); - } - else - { - sCR(Text, nLevel); - } - } - else - if (i + 1 < nT) - { - if (pTokens[i + 1] < eT_br_rnd_1 || pTokens[i + 1] >= eT_float) - { - sCR(Text, nLevel); - } - } - } - else - { - if (i + 1 < nT) - { - if (Text.Num()) - { - char cPrev = Text[Text.Num() - 1]; - if (!SkipChar((uint8)cPrev) && !SkipChar((uint8)szStr[0])) - { - Text.AddElem(' '); - } - } - } - Text.Copy(szStr, strlen(szStr)); - if (nToken == eT_br_cv_2) - { - nLevel--; - if (i + 1 < nT && pTokens[i + 1] != eT_semicolumn) - { - sCR(Text, nLevel); - } - } - } - } - } - Text.AddElem(0); - - return bRes; -} - -void CParserBin::MergeTable(SShaderBin* pBin) -{ - FXShaderTokenItor it = m_TokenTable.begin(); - FXShaderTokenItor end = m_TokenTable.end(); - FXShaderTokenItor bit = pBin->m_TokenTable.begin(); - FXShaderTokenItor bend = pBin->m_TokenTable.end(); - - FXShaderToken newTable; - newTable.reserve(m_TokenTable.size() + pBin->m_TokenTable.size()); - while (true) - { - STokenD* last = newTable.size() ? &(*newTable.rbegin()) : NULL; - - unsigned mask = 0; - mask |= (bit != bend) << 0; - mask |= (it != end) << 1; - - switch (mask) - { - // No iterators valid anymore, nothing left to do - case 0x0: - goto done; - - // Other iterator valid, internal iterator invalid - case 0x1: - if (!last || bit->Token != last->Token) - { - newTable.push_back(*bit); - } - ++bit; - break; - - // Other iterator invalid, internal iterator valid - case 0x2: - if (!last || it->Token != last->Token) - { - newTable.push_back(*it); - } - ++it; - break; - - // Noth iterators valid - case 0x3: - { - STokenD& iTD = (*it); - STokenD& oTD = (*bit); - if (iTD.Token < oTD.Token) - { - if (!last || it->Token != last->Token) - { - newTable.push_back(*it); - } - ++it; - } - else - { - if (!last || bit->Token != last->Token) - { - newTable.push_back(*bit); - } - ++bit; - } - } - break; - } - ; - } - - // Verify that the merging results in a sorted table -# if defined _DEBUG - for (std::size_t i = 1; i < newTable.size(); ++i) - { - assert (newTable[i - 1].Token <= newTable[i].Token); - } -# endif - -done: - swap(newTable, m_TokenTable); -} - -bool CParserBin::IgnorePreprocessBlock(const uint32* pTokens, uint32& nT, int nMaxTokens, PodArray& tokensBuffer, int nPass) -{ - int nLevel = 0; - bool bEnded = false; - while (*pTokens != 0) - { - if ((int)nT >= nMaxTokens) - { - break; - } - uint32 nToken = NextToken(pTokens, nT, nMaxTokens - 1); - if (nToken >= eT_if && nToken <= eT_ifndef_2) - { - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, nMaxTokens, false, tokensBuffer); - } - nLevel++; - continue; - } - if (nToken == eT_endif) - { - if (!nLevel) - { - bEnded = true; - nT--; - break; - } - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, nMaxTokens, true, tokensBuffer); - } - nLevel--; - } - else - if (nToken == eT_else || nToken == eT_elif) - { - if (!nLevel) - { - nT--; - break; - } - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, nMaxTokens, nToken == eT_else, tokensBuffer); - } - } - } - if ((int)nT >= nMaxTokens) - { - CRY_ASSERT(0); - Warning("Couldn't find #endif directive for associated #ifdef"); - return false; - } - - return bEnded; -} - -void CParserBin::InsertSkipTokens(const uint32* pTokens, uint32 nStart, [[maybe_unused]] uint32 nTokens, bool bSingle, PodArray& tokensBuffer) -{ - SParserFrame Fr; - Fr.m_nFirstToken = nStart; - Fr.m_nLastToken = nStart; - - if (!bSingle) - { - uint32 nS = nStart + 1; - CheckIfExpression(pTokens, nS, 0); - Fr.m_nLastToken = nS - 1; - } - - if (Fr.m_nLastToken - Fr.m_nFirstToken == 0) - { - tokensBuffer.push_back(eT_skip); - tokensBuffer.push_back(pTokens[Fr.m_nFirstToken]); - } - else - { - tokensBuffer.push_back(eT_skip_1); - while (Fr.m_nFirstToken <= Fr.m_nLastToken) - { - tokensBuffer.push_back(pTokens[Fr.m_nFirstToken]); - Fr.m_nFirstToken++; - } - tokensBuffer.push_back(eT_skip_2); - } -} - -bool CParserBin::CheckIfExpression(const uint32* pTokens, uint32& nT, int nPass, uint64* nMask) -{ - uint32 tmpBuf[64] = {0}; - byte bRes[64] = {0}; - byte bOr[64] = {0}; - int nLevel = 0; - int i; - while (true) - { - uint32 nToken = pTokens[nT]; - if (nToken == eT_br_rnd_1) // check for '(' - { - nT++; - int n = 0; - int nD = 0; - while (true) - { - int nTok = pTokens[nT]; - if (nTok == eT_br_rnd_1) // check for '(' - { - n++; - } - else - if (nTok == eT_br_rnd_2) // check for ')' - { - if (!n) - { - tmpBuf[nD] = 0; - nT++; - break; - } - n--; - } - else - if (nTok == 0) - { - return false; - } - tmpBuf[nD++] = nTok; - nT++; - } - uint32 nT2 = 0; - bRes[nLevel] = CheckIfExpression(&tmpBuf[0], nT2, nPass, nMask); - nLevel++; - bOr[nLevel] = 255; - } - else - { - uint32 nTok = pTokens[nT++]; - bool bNeg = false; - if (nTok == eT_excl) - { - bNeg = true; - nTok = pTokens[nT++]; - } - const SMacroBinFX* pFound = FindMacro(nTok, m_Macros[nPass]); - if (!pFound) - { - pFound = FindMacro(nTok, m_StaticMacros); - } - if (!pFound && !nPass) - { - pFound = FindMacro(nTok, m_Macros[1]); - } - bRes[nLevel] = (pFound) ? true : false; - - if (pFound && nMask) - { - *nMask |= pFound->m_nMask; - } - - if (nTok == eT_1) - { - bRes[nLevel] = true; - } - if (bNeg) - { - bRes[nLevel] = !bRes[nLevel]; - } - nLevel++; - bOr[nLevel] = 255; - } - uint32 nTok = pTokens[nT]; - if (nTok == eT_or) - { - bOr[nLevel] = true; - nT++; - assert (pTokens[nT] == eT_or); - if (pTokens[nT] == eT_or) - { - nT++; - } - } - else - if (nTok == eT_and) - { - bOr[nLevel] = false; - nT++; - assert (pTokens[nT] == eT_and); - if (pTokens[nT] == eT_and) - { - nT++; - } - } - else - { - break; - } - } - byte Res = false; - for (i = 0; i < nLevel; i++) - { - if (!i) - { - Res = bRes[i]; - } - else - { - assert(bOr[i] != 255); - if (bOr[i]) - { - Res = Res | bRes[i]; - } - else - { - Res = Res & bRes[i]; - } - } - } - return Res != 0; -} - -void CParserBin::BuildSearchInfo() -{ - /* int i; - for (i=0; i& Dst = m_KeyOffsets[nToken]; - Dst.push_back(i); - } - else - { - FXShaderTokenItor itor = m_Table.find(nToken); - if (itor != m_Table.end()) - itor->second.Offsets.push_back(i); - else - { - CRY_ASSERT(0); - } - } - } - m_bEmbeddedSearchInfo = true;*/ -} - -bool CParserBin::PreprocessTokens(ShaderTokensVec& Tokens, int nPass, PodArray& tokensBuffer) -{ - bool bRet = true; - uint32 nTokenParam; - - uint32 nT = 0; - const uint32* pTokens = &Tokens[0]; - const uint32 nTSize = Tokens.size(); - while (nT < nTSize) - { - uint32 nToken = NextToken(pTokens, nT, nTSize - 1); - if (!nToken) - { - break; - } - bool bFirst = false; - switch (nToken) - { - case eT_include: - { - nTokenParam = pTokens[nT++]; - const char* szName = GetString(nTokenParam, false); - assert(szName); - SShaderBin* pBin = gRenDev->m_cEF.m_Bin.GetBinShader(szName, true, 0); - if (!pBin) - { - AZ_Assert(false, "Fatal error: could not find required shader include file '%s'", szName); - return false; - } - else - { - assert(pBin); - MergeTable(pBin); - pBin->Lock(); - bool result = PreprocessTokens(pBin->m_Tokens, nPass, tokensBuffer); - pBin->Unlock(); - - if(!result) - { - // PreprocessTokens will output an error message, no need for one here - return false; - } - } - } - break; - case eT_define: - case eT_define_2: - { - uint32 nMacro = 0; - int n = nPass; - uint64 nMask = 0; - nTokenParam = pTokens[nT++]; - /*const char *szname = GetString(nTokenParam); - if (!_stricmp(szname, "%_SHADOW_GEN")) - { - int nnn = 0; - }*/ - const uint32* pMacro = &pTokens[nT]; - while (pMacro[nMacro]) - { - nMacro++; - } - if (nToken == eT_define_2) - { - n = 1; - if (nMacro) - { - nMask = GetInt(pMacro[0]); - } - } - else - { - for (uint32 i = 0; i < m_IfAffectMask.Num(); i++) - { - nMask |= m_IfAffectMask[i]; - } - } - AddMacro(nTokenParam, pMacro, nMacro, nMask, m_Macros[n]); - - if (nPass == 0) - { - if (sfxIFDef.Num()) - { - AddMacro(nTokenParam, pMacro, nMacro, nMask, m_Macros[1]); - } - - tokensBuffer.push_back(eT_define_2); - tokensBuffer.push_back(nTokenParam); - tokensBuffer.AddList((uint32*)pMacro, nMacro + 1); - } - nT += nMacro + 1; - } - break; - case eT_undefine: - { - nTokenParam = pTokens[nT++]; - int n = nPass; - FXMacroBinItor it = m_Macros[nPass].find(nTokenParam); - if (it == m_Macros[n].end() && !nPass) - { - it = m_Macros[1].find(nTokenParam); - n = 1; - } - if (it == m_Macros[n].end()) - { - Warning("Couldn't find macro '%s'", GetString(nTokenParam)); - } - else - { - m_Macros[n].erase(nTokenParam); - } - } - break; - case eT_if: - case eT_ifdef: - case eT_ifndef: - bFirst = true; - case eT_if_2: - case eT_ifdef_2: - case eT_ifndef_2: - if ((nPass == 0 && !bFirst) || (nPass == 1 && bFirst)) - { - if (nPass == 1) - { - CRY_ASSERT(0); - } - - sfxIFIgnore.AddElem(true); - sfxIFDef.AddElem(false); - tokensBuffer.push_back(nToken); - - uint64 nIfMask = 0; - uint32 nS = nT; - CheckIfExpression(pTokens, nT, 0, &nIfMask); - tokensBuffer.AddList((uint32*)pTokens + nS, nT - nS); - - m_IfAffectMask.AddElem(nIfMask); - } - else - { - uint64 nIfMask = 0; - sfxIFIgnore.AddElem(false); - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, nTSize, false, tokensBuffer); - } - bool bRes = CheckIfExpression(pTokens, nT, nPass, &nIfMask); - m_IfAffectMask.AddElem(nIfMask); - if (nToken == eT_ifndef || nToken == eT_ifndef_2) - { - bRes = !bRes; - } - if (!bRes) - { - IgnorePreprocessBlock(pTokens, nT, nTSize, tokensBuffer, nPass); - sfxIFDef.AddElem(false); - } - else - { - sfxIFDef.AddElem(true); - } - } - break; - case eT_elif: - { - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - CRY_ASSERT(0); - Warning("#elif without #ifdef"); - return false; - } - if (sfxIFIgnore[nLevel] == true) - { - tokensBuffer.push_back(nToken); - } - else - { - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, Tokens.size(), false, tokensBuffer); - } - if (sfxIFDef[nLevel] == true) - { - IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - } - else - { - uint64 nIfMask = 0; - bool bRes = CheckIfExpression(pTokens, nT, nPass, &nIfMask); - if (!bRes) - { - IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - } - else - { - sfxIFDef[nLevel] = true; - } - - m_IfAffectMask[nLevel] = nIfMask; - } - } - } - break; - case eT_else: - { - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - CRY_ASSERT(0); - Warning("#else without #ifdef"); - return false; - } - if (sfxIFIgnore[nLevel] == true) - { - tokensBuffer.push_back(nToken); - } - else - { - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, Tokens.size(), true, tokensBuffer); - } - if (sfxIFDef[nLevel] == true) - { - bool bEnded = IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - if (!bEnded) - { - CRY_ASSERT(0); - Warning("#else or #elif after #else"); - return false; - } - } - } - } - break; - case eT_endif: - { - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - CRY_ASSERT(0); - Warning("#endif without #ifdef"); - return false; - } - if (sfxIFIgnore[nLevel] == true) - { - tokensBuffer.push_back(nToken); - } - else - if (!nPass) - { - InsertSkipTokens(pTokens, nT - 1, Tokens.size(), true, tokensBuffer); - } - sfxIFDef.Remove(nLevel); - sfxIFIgnore.Remove(nLevel); - m_IfAffectMask.Remove(nLevel); - } - break; - case eT_warning: - { - const char* szStr = GetString(pTokens[nT++]); - Warning(szStr); - } - break; - case eT_register_env: - { - const char* szStr = GetString(pTokens[nT++]); - fxRegisterEnv(szStr); - } - break; - case eT_ifcvar: - case eT_ifncvar: - { - const char* szStr = GetString(pTokens[nT++]); - sfxIFIgnore.AddElem(false); - ICVar* pVar = iConsole->GetCVar(szStr); - int nVal = 0; - if (!pVar) - { - iLog->Log("Warning: couldn't find variable '%s'", szStr); - } - else - { - nVal = pVar->GetIVal(); - } - if (nToken == eT_ifncvar) - { - nVal = !nVal; - } - if (!nVal) - { - IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - sfxIFDef.AddElem(false); - } - else - { - sfxIFDef.AddElem(true); - } - } - break; - case eT_elifcvar: - { - int nLevel = sfxIFDef.Num() - 1; - if (nLevel < 0) - { - CRY_ASSERT(0); - Warning("#elifcvar without #ifcvar or #ifdef"); - return false; - } - sfxIFIgnore.AddElem(false); - if (sfxIFDef[nLevel] == true) - { - IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - } - else - { - const char* szStr = GetString(pTokens[nT++]); - ICVar* pVar = iConsole->GetCVar(szStr); - int nVal = 0; - if (!pVar) - { - iLog->Log("Warning: couldn't find variable '%s'", szStr); - } - else - { - nVal = pVar->GetIVal(); - } - if (!nVal) - { - IgnorePreprocessBlock(pTokens, nT, Tokens.size(), tokensBuffer, nPass); - } - else - { - sfxIFDef[nLevel] = true; - } - } - } - break; - default: - { - FXMacroBinItor it = m_Macros[nPass].find(nToken); - if (it != m_Macros[nPass].end()) - { - // Found macro - SMacroBinFX* pM = &it->second; - for (uint32 i = 0; i < pM->m_Macro.size(); i++) - { - tokensBuffer.push_back(pM->m_Macro[i]); - } - } - else - { - tokensBuffer.push_back(nToken); - } - } - break; - } - } - - return bRet; -} - -bool CParserBin::Preprocess(int nPass, ShaderTokensVec& Tokens, FXShaderToken* pSrcTable) -{ - bool bRes = true; - - m_IfAffectMask.Reserve(5); - m_IfAffectMask.SetUse(0); - sfxIFDef.SetUse(0); - sfxIFIgnore.SetUse(0); - - m_Macros[nPass].clear(); - - // Use a buffer to process tokens, transfer to the - // real storage in Tokens once we know the full quantity - enum - { - TOKENS_BUFFER_SIZE = 90000 - }; - - PodArray tokensBuffer(TOKENS_BUFFER_SIZE); - - m_TokenTable = *pSrcTable; - bRes = PreprocessTokens(Tokens, nPass, tokensBuffer); -#ifndef _RELEASE - if (tokensBuffer.Size() > TOKENS_BUFFER_SIZE) - { - CryLogAlways("CParserBin::Preprocess: tokenBuffer has been exceeded (buffer=%u, count=%u). Adjust buffer size to remove unnecessary allocs.", TOKENS_BUFFER_SIZE, tokensBuffer.Size()); - } -#endif - m_Tokens.reserve(tokensBuffer.Size()); - m_Tokens.SetUse(0); - m_Tokens.Copy(tokensBuffer.GetElements(), tokensBuffer.Count()); - - if (!nPass) - { - BuildSearchInfo(); - } - - assert(!sfxIFDef.Num()); - assert(!sfxIFIgnore.Num()); - return bRes; -} - -int CParserBin::CopyTokens(SParserFrame& Fragment, std::vector& NewTokens) -{ - if (Fragment.IsEmpty()) - { - return 0; - } - int nCopy = Fragment.m_nLastToken - Fragment.m_nFirstToken + 1; - int nStart = NewTokens.size(); - NewTokens.resize(nStart + nCopy); - memcpy(&NewTokens[nStart], &m_Tokens[Fragment.m_nFirstToken], nCopy * sizeof(uint32)); - - return nCopy; -} - -int CParserBin::CopyTokens(SCodeFragment* pCF, PodArray& SHData, TArray& Replaces, TArray& NewTokens, uint32 nID) -{ - int nRepl = -1; - uint32 i; - - for (i = 0; i < Replaces.size(); i++) - { - SCodeFragment* pFR = &Replaces[i]; - - if (pFR->m_dwName == nID) - { - break; - } - } - if (i != Replaces.size()) - { - assert (!(i & 1)); - nRepl = i; - } - int nDst = SHData.size(); - int nSrc = pCF->m_nFirstToken; - uint32* pSrc = &m_Tokens[0]; - int nSize = pCF->m_nLastToken - nSrc + 1; - if (nRepl >= 0) - { - int nDstStart = nDst; - uint32* pSrc2 = &NewTokens[0]; - while (nSrc <= (int)pCF->m_nLastToken) - { - if (nRepl >= (int)Replaces.size() || Replaces[nRepl].m_dwName != nID) - { - int nCopy = pCF->m_nLastToken - nSrc + 1; - SHData.resize(nDst + nCopy); - memcpy(&SHData[nDst], &pSrc[nSrc], nCopy * sizeof(uint32)); - nSrc += nCopy; - nDst += nCopy; - } - else - { - int nCopy = Replaces[nRepl].m_nFirstToken - nSrc; - if (nCopy) - { - assert(nCopy > 0); - SHData.resize(nDst + nCopy); - memcpy(&SHData[nDst], &pSrc[nSrc], nCopy * sizeof(uint32)); - nSrc += nCopy + (Replaces[nRepl].m_nLastToken - Replaces[nRepl].m_nFirstToken + 1); - nDst += nCopy; - } - nRepl++; - nCopy = Replaces[nRepl].m_nLastToken - Replaces[nRepl].m_nFirstToken + 1; - SHData.resize(nDst + nCopy); - memcpy(&SHData[nDst], &pSrc2[Replaces[nRepl].m_nFirstToken], nCopy * sizeof(uint32)); - nDst += nCopy; - nRepl++; - } - } - return SHData.size() - nDstStart; - } - else - { - SHData.resize(nDst + nSize); - memcpy(&SHData[nDst], &pSrc[nSrc], nSize * sizeof(uint32)); - return nSize; - } -} - -int32 CParserBin::FindToken(uint32 nStart, uint32 nLast, const uint32* pTokens, uint32 nToken) -{ - while (nStart <= nLast) - { - if (pTokens[nStart] == nToken) - { - return nStart; - } - nStart++; - } - return -1; -} - -int32 CParserBin::FindToken(uint32 nStart, uint32 nLast, uint32 nToken) -{ - if (nStart >= m_Tokens.size() || nLast >= m_Tokens.size()) - { - return -1; - } - - //if (!m_bEmbeddedSearchInfo) - return FindToken(nStart, nLast, &m_Tokens[0], nToken); - /*std::vector *pSI; - if (nToken < eT_max) - { - if (nToken >= m_KeyOffsets.size()) - return -1; - pSI = &m_KeyOffsets[nToken]; - } - else - { - FXShaderTokenItor itor = m_Table.find(nToken); - if (itor == m_Table.end()) - return -1; - pSI = &itor->second.Offsets; - } - for (int i=0; isize(); i++) - { - int nOffs = (*pSI)[i]; - if (nOffs>=nStart && nOffs<=nLast) - return nOffs; - } - return -1;*/ -} - -int32 CParserBin::FindToken(uint32 nStart, uint32 nLast, const uint32* pToks) -{ - uint32* pTokens = &m_Tokens[0]; - while (nStart <= nLast) - { - int n = 0; - uint32 nTok = pToks[n]; - while (nTok) - { - if (pTokens[nStart] == nTok) - { - return nStart; - } - n++; - nTok = pToks[n]; - } - nStart++; - } - return -1; -} - -static ETokenStorageClass sCheckForModificator(uint32 nToken) -{ - switch (nToken) - { - case eT_const: - return eTS_const; - case eT_static: - return eTS_static; - case eT_shared: - return eTS_shared; - case eT_groupshared: - return eTS_groupshared; - default: - return eTS_default; - } -} -int CParserBin::GetNextToken(uint32& nStart, ETokenStorageClass& nTokenStorageClass) -{ - uint32* pTokens = &m_Tokens[0]; - uint32 nTokensSize = m_Tokens.size(); - ETokenStorageClass nNewTokenStorageClass = eTS_default; - while (true) - { - bool bFunction = false; - - if (m_CurFrame.m_nCurToken >= m_CurFrame.m_nLastToken) - { - return -1; - } - - uint32 nToken; - if ((nToken = pTokens[m_CurFrame.m_nCurToken]) == eT_unknown) - { - return -2; - } - - nStart = m_CurFrame.m_nCurToken; - - if (nToken == eT_quote) - { - m_CurFrame.m_nCurToken++; - continue; - } - if (nToken == eT_skip) - { - m_CurFrame.m_nCurToken += 2; - continue; - } - if (nToken == eT_skip_1) - { - while (m_CurFrame.m_nCurToken <= m_CurFrame.m_nLastToken) - { - nToken = pTokens[m_CurFrame.m_nCurToken++]; - if (nToken == eT_skip_2) - { - break; - } - } - continue; - } - - // Check for storage class- if existing, add all tokens in line (its global constant - should not go to any constant buffer) - nNewTokenStorageClass = sCheckForModificator(nToken); - if (nNewTokenStorageClass != eTS_default) - { - nTokenStorageClass = nNewTokenStorageClass; - - SCodeFragment Fr; - Fr.m_eType = eFT_StorageClass; // Set code fragment type - Fr.m_nFirstToken = m_CurFrame.m_nCurToken; // Set first token offset for code fragment - while (pTokens[m_CurFrame.m_nCurToken] != eT_semicolumn) - { - if (m_CurFrame.m_nCurToken + 1 == nTokensSize) - { - break; - } - //const char *pszToken0 = GetString( pTokens[m_CurFrame.m_nCurToken] ); // handy for debugging - do not remove for now plz - m_CurFrame.m_nCurToken++; - } - - Fr.m_nLastToken = m_CurFrame.m_nCurToken++; // Set last token offset to code fragment - Fr.m_dwName = pTokens[Fr.m_nLastToken - 1]; // Set fragment name (this is used for parser to search and discard fragments of code if not used in functions or structures) - m_CodeFragments.push_back(Fr); // Finally add to list - - //const char *pszToken0 = GetString( Fr.m_dwName ); // handy for debugging - do not remove for now plz - - continue; - } - - // if preprocessor - if (nToken >= eT_include && nToken <= eT_elifcvar) - { - SCodeFragment Fr; - Fr.m_nFirstToken = m_CurFrame.m_nCurToken; - if (nToken >= eT_if && nToken <= eT_elif || nToken == eT_define || nToken == eT_define_2) - { - while (pTokens[m_CurFrame.m_nCurToken]) - { - if (m_CurFrame.m_nCurToken + 1 == nTokensSize) - { - break; - } - m_CurFrame.m_nCurToken++; - } - } - Fr.m_nLastToken = m_CurFrame.m_nCurToken++; - m_CodeFragments.push_back(Fr); - } - else - { - m_CurFrame.m_nCurToken = nStart; - // Check for function - uint32 nLastTok = nStart; - uint32 nFnName; - int nBrIndex = -1; - if (m_CurFrame.m_nCurToken + 4 < m_CurFrame.m_nLastToken) - { - uint32 nFnRet = pTokens[m_CurFrame.m_nCurToken]; - // DX11 stuff - uint32 nCur = m_CurFrame.m_nCurToken + 1; - uint32 nCount = 0; - while (nFnRet == eT_br_sq_1) - { - nCount++; - nLastTok = FindToken(nCur, m_CurFrame.m_nLastToken, eT_br_sq_2); - if (nLastTok > 0) - { - nLastTok++; - nFnRet = pTokens[nLastTok]; - if (nFnRet == eT_skip) - { - pTokens[nLastTok + 1] = eT_skip; - nLastTok += 2; - nFnRet = pTokens[nLastTok]; - } - nCur = nLastTok + 1; - } - } - nFnName = pTokens[nLastTok + 1]; - //const char *szFn = GetString(nFnName); - if (pTokens[nLastTok + 2] == eT_br_rnd_1) - { - nBrIndex = nLastTok + 3; - nLastTok = FindToken(nLastTok + 3, m_CurFrame.m_nLastToken, eT_br_cv_1); - int nRecurse = 0; - while (nLastTok <= m_CurFrame.m_nLastToken) - { - uint32 nT = pTokens[nLastTok]; - if (nT == eT_br_cv_1) - { - nRecurse++; - } - else - if (nT == eT_br_cv_2) - { - nRecurse--; - if (nRecurse == 0) - { - bFunction = true; - break; - } - } - nLastTok++; - } - } - } - if (bFunction) - { - // check for function if expressions - assert (nBrIndex > 0); - uint32 nIdTok = FindToken(nBrIndex, m_CurFrame.m_nLastToken, eT_br_rnd_2); - assert(nIdTok > 0); - if (nIdTok > 0 && pTokens[nIdTok + 1] != eT_br_cv_1) - { - nIdTok++; - while (pTokens[nIdTok] != eT_br_cv_1) - { - if (pTokens[nIdTok] == eT_skip) - { - pTokens[nIdTok + 1] = eT_skip; - nIdTok += 2; - } - else - if (pTokens[nIdTok] == eT_skip_1) - { - while (pTokens[nIdTok] != eT_skip_2) - { - pTokens[nIdTok++] = eT_skip; - } - pTokens[nIdTok++] = eT_skip; - } - else - { - nIdTok++; - } - } - } - - SCodeFragment Fr; - Fr.m_nFirstToken = m_CurFrame.m_nCurToken; - Fr.m_nLastToken = nLastTok; - Fr.m_dwName = nFnName; -#ifdef _DEBUG - //Fr.m_Name = GetString(nFnName); -#endif - Fr.m_eType = eFT_Function; - m_CodeFragments.push_back(Fr); - m_CurFrame.m_nCurToken = nLastTok + 1; - } - else - { - m_eToken = (EToken)nToken; - assert(m_eToken < eT_user_first); - m_CurFrame.m_nCurToken++; - break; - } - } - } - return 1; -} - -bool CParserBin::FXGetAssignmentData(SParserFrame& Frame) -{ - bool bRes = true; - - Frame.m_nFirstToken = m_CurFrame.m_nCurToken; - uint32 nLastToken = m_CurFrame.m_nCurToken; - while (nLastToken <= m_CurFrame.m_nLastToken) - { - uint32 nTok = m_Tokens[nLastToken++]; - if (nTok == eT_quote) - { - while (nLastToken <= m_CurFrame.m_nLastToken) - { - nTok = m_Tokens[nLastToken++]; - if (nTok == eT_quote) - { - break; - } - } - } - else - if (nTok == eT_semicolumn) - { - break; - } - } - Frame.m_nLastToken = nLastToken - 2; - if (m_Tokens[nLastToken] == eT_semicolumn) - { - m_CurFrame.m_nCurToken = nLastToken + 1; - } - else - { - m_CurFrame.m_nCurToken = nLastToken; - } - - return bRes; -} - -bool CParserBin::FXGetAssignmentData2(SParserFrame& Frame) -{ - bool bRes = true; - - Frame.m_nFirstToken = m_CurFrame.m_nCurToken; - uint32 nLastToken = m_CurFrame.m_nCurToken; - uint32 nTok = m_Tokens[nLastToken]; - if (nTok == eT_br_cv_1) - { - nLastToken++; - while (nLastToken + 1 <= m_CurFrame.m_nLastToken) - { - nTok = m_Tokens[nLastToken]; - if (nTok == eT_semicolumn) - { - break; - } - nLastToken++; - } - } - else - if (nTok == eT_br_rnd_1) - { - nLastToken++; - int n = 1; - while (nLastToken + 1 <= m_CurFrame.m_nLastToken) - { - nTok = m_Tokens[nLastToken]; - if (nTok == eT_semicolumn || nTok == eT_br_tr_1 || nTok == eT_eq) - { - assert(!n); - break; - } - if (nTok == eT_br_rnd_1) - { - n++; - } - else - if (nTok == eT_br_rnd_2) - { - n--; - } - nLastToken++; - } - } - else - { - while (nLastToken <= m_CurFrame.m_nLastToken) - { - nTok = m_Tokens[nLastToken]; - if (nTok == eT_semicolumn || nTok == eT_br_rnd_1 || nTok == eT_br_cv_1 || nTok == eT_br_tr_1) - { - break; - } - nLastToken++; - } - } - - Frame.m_nLastToken = nLastToken - 1; - if (m_Tokens[nLastToken] == eT_semicolumn) - { - m_CurFrame.m_nCurToken = nLastToken + 1; - } - else - { - m_CurFrame.m_nCurToken = nLastToken; - } - - return bRes; -} - - -bool CParserBin::GetAssignmentData(SParserFrame& Frame) -{ - bool bRes = true; - - Frame.m_nFirstToken = m_CurFrame.m_nCurToken; - uint32 nLastToken = m_CurFrame.m_nCurToken; - uint32* pTokens = &m_Tokens[0]; - uint32 nTok = pTokens[nLastToken + 1]; - if (nTok == eT_br_sq_1 || nTok == eT_br_rnd_1) - { - EToken eTClose = nTok == eT_br_sq_1 ? eT_br_sq_2 : eT_br_rnd_2; - nLastToken += 2; - while (nLastToken <= m_CurFrame.m_nLastToken) - { - nTok = pTokens[nLastToken]; - if (nTok == eTClose || nTok == eT_semicolumn) - { - if (nTok == eT_semicolumn) - { - nLastToken--; - } - break; - } - nLastToken++; - } - } - Frame.m_nLastToken = nLastToken; - - nLastToken++; - - if (pTokens[nLastToken] == eT_semicolumn) - { - m_CurFrame.m_nCurToken = nLastToken + 1; - } - else - { - m_CurFrame.m_nCurToken = nLastToken; - } - - return bRes; -} - -bool CParserBin::GetSubData(SParserFrame& Frame, EToken eT1, EToken eT2) -{ - - Frame.m_nFirstToken = 0; - Frame.m_nLastToken = 0; - uint32 nTok = m_Tokens[m_CurFrame.m_nCurToken]; - if (nTok != eT1) - { - return false; - } - m_CurFrame.m_nCurToken++; - Frame.m_nFirstToken = m_CurFrame.m_nCurToken; - uint32 nCurToken = m_CurFrame.m_nCurToken; - int skip = 1; - while (nCurToken <= m_CurFrame.m_nLastToken) - { - nTok = m_Tokens[nCurToken]; - if (nTok == eT1) - { - skip++; - } - else - if (nTok == eT2) - { - if (--skip == 0) - { - Frame.m_nLastToken = nCurToken - 1; - nCurToken++; - break; - } - } - nCurToken++; - } - if (Frame.IsEmpty()) - { - Frame.Reset(); - } - if (nCurToken <= m_CurFrame.m_nLastToken && m_Tokens[nCurToken] == eT_semicolumn) - { - m_CurFrame.m_nCurToken = nCurToken + 1; - } - else - { - m_CurFrame.m_nCurToken = nCurToken; - } - - return (Frame.m_nFirstToken <= Frame.m_nLastToken); -} - - -ETokenStorageClass CParserBin::ParseObject(SFXTokenBin* pTokens) -{ - assert(m_CurFrame.m_nFirstToken <= m_CurFrame.m_nLastToken); - - if (m_CurFrame.m_nCurToken + 1 >= m_CurFrame.m_nLastToken) - { - return eTS_invalid; - } - if (m_Tokens.size() <= m_CurFrame.m_nCurToken) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Attempted out-of-bounds access in CParserBin::ParseObject"); - return eTS_invalid; - } - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_unknown) - { - return eTS_invalid; - } - - ETokenStorageClass nTokenStorageClass = eTS_default; - int nRes = GetNextToken(m_nFirstToken, nTokenStorageClass); - if (nRes < 0) - { - return eTS_invalid; - } - - m_Name.Reset(); - m_Assign.Reset(); - m_Value.Reset(); - m_Data.Reset(); - m_Annotations.Reset(); - - SFXTokenBin* pT = pTokens; - while (pTokens->id != 0) - { - if (pTokens->id == m_eToken) - { - break; - } - pTokens++; - } - if (pTokens->id == 0) - { - pTokens = pT; - const char* tokenName = GetString(m_eToken); - Warning ("FXBin parser found token '%s' which was not one of the list (Skipping).\n", tokenName); - while (pTokens->id != 0) - { - Warning(" %s\n", GetString(pTokens->id)); - pTokens++; - } - AZ_Assert(false, "FXBin parser found token '%s' which was not one of the list (Skipping).\n", tokenName); -#ifdef _DEBUG - TArray Text; - SParserFrame Fr; - Fr.m_nFirstToken = max(m_CurFrame.m_nFirstToken, m_CurFrame.m_nCurToken - 5); - Fr.m_nLastToken = m_CurFrame.m_nLastToken; - ConvertToAscii(&m_Tokens[Fr.m_nFirstToken], Fr.m_nLastToken - Fr.m_nFirstToken + 1, m_TokenTable, Text); -#endif - return eTS_invalid; - } - - bool bAnnot = false; - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_br_tr_1) - { - GetSubData(m_Annotations, eT_br_tr_1, eT_br_tr_2); - bAnnot = true; - } - - GetAssignmentData(m_Name); - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_colon) - { - m_CurFrame.m_nCurToken++; // skip the ':' - GetAssignmentData(m_Assign); - } - - if (!bAnnot) - { - GetSubData(m_Annotations, eT_br_tr_1, eT_br_tr_2); - } - if (m_CurFrame.m_nCurToken <= m_CurFrame.m_nLastToken) - { - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_eq) - { - m_CurFrame.m_nCurToken++; // skip the '=' - FXGetAssignmentData2(m_Value); - } - - GetSubData(m_Data, eT_br_cv_1, eT_br_cv_2); - } - - if (m_CurFrame.m_nCurToken <= m_CurFrame.m_nLastToken && m_Tokens[m_CurFrame.m_nCurToken] == eT_semicolumn) - { - m_CurFrame.m_nCurToken++; - } - - return nTokenStorageClass; -} - -ETokenStorageClass CParserBin::ParseObject(SFXTokenBin* pTokens, int& nIndex) -{ - assert(m_CurFrame.m_nFirstToken <= m_CurFrame.m_nLastToken); - - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_unknown) - { - return eTS_invalid; - } - if (m_CurFrame.m_nCurToken + 1 >= m_CurFrame.m_nLastToken) - { - return eTS_invalid; - } - - ETokenStorageClass nTokenStorageClass = eTS_default; - int nRes = GetNextToken(m_nFirstToken, nTokenStorageClass); - if (nRes < 0) - { - return eTS_invalid; - } - - m_Name.Reset(); - m_Assign.Reset(); - m_Value.Reset(); - m_Data.Reset(); - m_Annotations.Reset(); - - SFXTokenBin* pT = pTokens; - while (pTokens->id != 0) - { - if (pTokens->id == m_eToken) - { - break; - } - pTokens++; - } - if (pTokens->id == 0) - { - pTokens = pT; - Warning ("Warning: FXBin parser found token '%s' which was not one of the list (Skipping).\n", GetString(m_eToken)); - while (pTokens->id != 0) - { - Warning(" %s\n", GetString(pTokens->id)); - pTokens++; - } - CRY_ASSERT(0); -#ifdef _DEBUG - TArray Text; - SParserFrame Fr; - Fr.m_nFirstToken = max(m_CurFrame.m_nFirstToken, m_CurFrame.m_nCurToken - 5); - Fr.m_nLastToken = m_CurFrame.m_nLastToken; - ConvertToAscii(&m_Tokens[Fr.m_nFirstToken], Fr.m_nLastToken - Fr.m_nFirstToken + 1, m_TokenTable, Text); -#endif - return eTS_invalid; - } - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_br_sq_1) - { - m_CurFrame.m_nCurToken++; - nIndex = GetInt(m_Tokens[m_CurFrame.m_nCurToken++]); - } - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_sing_quote) - { - GetSubData(m_Name, eT_sing_quote, eT_sing_quote); - } - else - if (m_Tokens[m_CurFrame.m_nCurToken] != eT_eq) - { - m_Name.m_nFirstToken = m_Name.m_nLastToken = m_CurFrame.m_nCurToken++; - } - - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_eq) - { - m_CurFrame.m_nCurToken++; - FXGetAssignmentData(m_Data); - } - else - { - GetSubData(m_Data, eT_br_cv_1, eT_br_cv_2); - } - - if (m_Tokens[m_CurFrame.m_nCurToken] == eT_semicolumn || m_Tokens[m_CurFrame.m_nCurToken] == eT_quote) - { - m_CurFrame.m_nCurToken++; - } - - return nTokenStorageClass; -} - -bool CParserBin::JumpSemicolumn(uint32& nStart, uint32 nEnd) -{ - while (nStart <= nEnd) - { - uint32 nTok = m_Tokens[nStart++]; - if (nTok == eT_semicolumn) - { - return true; - } - } - return false; -} - -SParserFrame CParserBin::BeginFrame(SParserFrame& Frame) -{ - SParserFrame RetFrame = m_CurFrame; - m_CurFrame = Frame; - m_eToken = eT_unknown; - m_CurFrame.m_nCurToken = Frame.m_nFirstToken; - - return RetFrame; -} - -void CParserBin::EndFrame(SParserFrame& Frame) -{ - m_CurFrame = Frame; -} - -void SFXParam::PostLoad(CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign) -{ - m_Annotations = Parser.GetNameString(Annotations); - if (!Values.IsEmpty()) - { - if (Parser.GetToken(Values) == eT_br_cv_1) - { - Values.m_nFirstToken++; - int32 nFind = Parser.FindToken(Values.m_nFirstToken, Values.m_nLastToken, eT_br_cv_2); - assert(nFind > 0 && Values.m_nLastToken == nFind); - if (nFind > 0) - { - Values.m_nLastToken--; - } - } - m_Values = Parser.GetString(Values); - } - m_Semantic = Parser.GetNameString(Assign); - m_Name = Parser.GetString(Name); - - m_nFlags = 0; - if (m_ComponentCount == 1 && m_RegisterCount <= 1) - { - m_nFlags |= PF_SCALAR; - } - if (m_eType == eType_INT) - { - m_nFlags |= PF_INTEGER; - } - else - if (m_eType == eType_BOOL) - { - m_nFlags |= PF_BOOL; - } - else - if (m_eType != eType_FLOAT && m_eType != eType_HALF) - { - CRY_ASSERT(0); - } - - if (Annotations.IsEmpty()) - { - return; - } - - bool bIsUniformRegisterOffset = false; - - uint32 nCur = Annotations.m_nFirstToken; - uint32 nLast = Annotations.m_nLastToken; - uint32* pTokens = &Parser.m_Tokens[0]; - while (nCur <= nLast) - { - uint32 nTok = pTokens[nCur++]; - if (nTok == eT_register || nTok == eT_psregister || nTok == eT_vsregister || nTok == eT_gsregister || nTok == eT_dsregister || nTok == eT_hsregister || nTok == eT_csregister) - { - m_nFlags |= PF_CUSTOM_BINDED; - { - uint32 nTok2 = pTokens[nCur++]; - if (nTok2 != eT_eq) - { - CRY_ASSERT(0); - } - else - { - nTok2 = pTokens[nCur++]; - const char* szReg = Parser.GetString(nTok2); - assert(szReg[0] == 'c'); - - int registerOffset = atoi(&szReg[1]); - - if (nTok == eT_register) - { - m_Register[eHWSC_Vertex] = registerOffset; - m_Register[eHWSC_Pixel] = m_Register[eHWSC_Vertex]; - if (CParserBin::PlatformSupportsGeometryShaders()) - { - m_Register[eHWSC_Geometry] = m_Register[eHWSC_Vertex]; - } - if (CParserBin::PlatformSupportsDomainShaders()) - { - m_Register[eHWSC_Domain] = m_Register[eHWSC_Vertex]; - } - if (CParserBin::PlatformSupportsHullShaders()) - { - m_Register[eHWSC_Hull] = m_Register[eHWSC_Vertex]; - } - if (CParserBin::PlatformSupportsComputeShaders()) - { - m_Register[eHWSC_Compute] = m_Register[eHWSC_Vertex]; - } - bIsUniformRegisterOffset = true; - } - else - if (nTok == eT_vsregister) - { - m_Register[eHWSC_Vertex] = registerOffset; - } - else - if (nTok == eT_psregister) - { - m_Register[eHWSC_Pixel] = registerOffset; - } - else - if (CParserBin::PlatformSupportsGeometryShaders() && nTok == eT_gsregister) - { - m_Register[eHWSC_Geometry] = registerOffset; - } - else - if (CParserBin::PlatformSupportsDomainShaders() && nTok == eT_dsregister) - { - m_Register[eHWSC_Domain] = registerOffset; - m_Register[eHWSC_Vertex] = m_Register[eHWSC_Domain]; - } - else - if (CParserBin::PlatformSupportsHullShaders() && nTok == eT_hsregister) - { - m_Register[eHWSC_Hull] = registerOffset; - m_Register[eHWSC_Vertex] = m_Register[eHWSC_Hull]; - } - else - if (CParserBin::PlatformSupportsComputeShaders() && nTok == eT_csregister) - { - m_Register[eHWSC_Compute] = registerOffset; - m_Register[eHWSC_Vertex] = m_Register[eHWSC_Compute]; - } - } - } - } - else - if (nTok == eT_Position) - { - m_nFlags |= PF_POSITION; - } - else - { - if (nTok == eT_string) - { - uint32 nTokName = pTokens[nCur++]; - if (nTokName == eT_UIWidget || nTokName == eT_UIWidget0) - { - uint32 nTok0 = pTokens[nCur++]; - uint32 nTok1 = pTokens[nCur++]; - if (nTok0 == eT_eq && nTok1 == eT_quote) - { - nTok = pTokens[nCur++]; - if (nTok == eT_color) - { - m_nFlags |= PF_TWEAKABLE_MASK; - } - else - { - m_nFlags |= PF_TWEAKABLE_0; - } - } - } - else - if (nTokName == eT_UIWidget1) - { - m_nFlags |= PF_TWEAKABLE_1; - } - else - if (nTokName == eT_UIWidget2) - { - m_nFlags |= PF_TWEAKABLE_2; - } - else - if (nTokName == eT_UIWidget3) - { - m_nFlags |= PF_TWEAKABLE_3; - } - } - } - if (!Parser.JumpSemicolumn(nCur, nLast)) - { - return; - } - } - - if ((m_nFlags & PF_TWEAKABLE_MASK) && !bIsUniformRegisterOffset) - { - AZ_Assert(false, "Tweakables must use 'register'. They cannot have different register offsets per stage."); - } -} - -void SFXSampler::PostLoad(CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign) -{ - m_Annotations = Parser.GetNameString(Annotations); - if (!Values.IsEmpty()) - { - if (Parser.GetToken(Values) == eT_br_cv_1) - { - Values.m_nFirstToken++; - int32 nFind = Parser.FindToken(Values.m_nFirstToken, Values.m_nLastToken, eT_br_cv_2); - assert(nFind > 0 && Values.m_nLastToken == nFind); - if (nFind > 0) - { - Values.m_nLastToken--; - } - } - m_Values = Parser.GetString(Values); - } - m_Semantic = Parser.GetNameString(Assign); - m_Name = Parser.GetString(Name); - m_nFlags = 0; - - if (!Assign.IsEmpty()) - { - uint32 nCur = Assign.m_nFirstToken; - uint32 nLast = Assign.m_nLastToken; - uint32* pTokens = &Parser.m_Tokens[0]; - while (nCur <= nLast) - { - uint32 nTok = pTokens[nCur++]; - if (nTok == eT_register) - { - m_nFlags |= PF_CUSTOM_BINDED; - { - uint32 nTok2 = pTokens[nCur++]; - if (nTok2 != eT_br_rnd_1) - { - CRY_ASSERT(0); - } - else - { - nTok2 = pTokens[nCur++]; - const char* szReg = Parser.GetString(nTok2); - while (szReg[0] == 's' || szReg[0] == 't') - { - ++szReg; - } - assert(isdigit(szReg[0])); - m_Register[eHWSC_Vertex] = - m_Register[eHWSC_Pixel] = - m_Register[eHWSC_Geometry] = - m_Register[eHWSC_Domain] = - m_Register[eHWSC_Hull] = - m_Register[eHWSC_Compute] = atoi(&szReg[0]); - - uint32 tok2 = pTokens[nCur++]; - if (tok2 != eT_br_rnd_2) - { - CRY_ASSERT(0); - } - } - } - } - } - } - - if (!Annotations.IsEmpty()) - { - uint32 nCur = Annotations.m_nFirstToken; - uint32 nLast = Annotations.m_nLastToken; - uint32* pTokens = &Parser.m_Tokens[0]; - while (nCur <= nLast) - { - uint32 nTok = pTokens[nCur++]; - if (nTok == eT_psslot || nTok == eT_vsslot || nTok == eT_gsslot || nTok == eT_dsslot || nTok == eT_hsslot || nTok == eT_csslot || nTok == eT_slot) - { - m_nFlags |= PF_CUSTOM_BINDED; - { - uint32 nTok2 = pTokens[nCur++]; - if (nTok2 != eT_eq) - { - CRY_ASSERT(0); - } - else - { - nTok2 = pTokens[nCur++]; - const char* szReg = Parser.GetString(nTok2); - assert(isdigit(szReg[0])); - if (nTok == eT_vsslot || nTok == eT_slot) - { - m_Register[eHWSC_Vertex] = atoi(&szReg[0]); - } - else - if (nTok == eT_psslot || nTok == eT_slot) - { - m_Register[eHWSC_Pixel] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsGeometryShaders() && nTok == eT_gsslot || nTok == eT_slot) - { - m_Register[eHWSC_Geometry] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsDomainShaders() && nTok == eT_dsslot || nTok == eT_slot) - { - m_Register[eHWSC_Domain] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsHullShaders() && nTok == eT_hsslot || nTok == eT_slot) - { - m_Register[eHWSC_Hull] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsComputeShaders() && nTok == eT_csslot || nTok == eT_slot) - { - m_Register[eHWSC_Compute] = atoi(&szReg[0]); - } - } - } - } - if (!Parser.JumpSemicolumn(nCur, nLast)) - { - break; - } - } - } -} - -void SFXTexture::PostLoad(CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign) -{ - m_Annotations = Parser.GetNameString(Annotations); - if (!Values.IsEmpty()) - { - if (Parser.GetToken(Values) == eT_br_cv_1) - { - Values.m_nFirstToken++; - int32 nFind = Parser.FindToken(Values.m_nFirstToken, Values.m_nLastToken, eT_br_cv_2); - - assert(nFind > 0 && Values.m_nLastToken == nFind); - if (nFind > 0) - Values.m_nLastToken--; - } - if (Parser.GetToken(Values) == eT_quote) - { - Values.m_nFirstToken++; - int32 nFind = Parser.FindToken(Values.m_nFirstToken, Values.m_nLastToken, eT_quote); - assert(nFind > 0 && Values.m_nLastToken == nFind); - if (nFind > 0) - { - Values.m_nLastToken--; - } - } - m_Values = Parser.GetString(Values); - } - m_Semantic = Parser.GetNameString(Assign); - m_Name = Parser.GetString(Name); - m_nFlags = 0; - - if (!Assign.IsEmpty()) - { - uint32 nCur = Assign.m_nFirstToken; - uint32 nLast = Assign.m_nLastToken; - uint32* pTokens = &Parser.m_Tokens[0]; - while (nCur <= nLast) - { - uint32 nTok = pTokens[nCur++]; - if (nTok == eT_register) - { - m_nFlags |= PF_CUSTOM_BINDED; - { - uint32 nTok2 = pTokens[nCur++]; - if (nTok2 != eT_br_rnd_1) - { - CRY_ASSERT(0); - } - else - { - nTok2 = pTokens[nCur++]; - const char* szReg = Parser.GetString(nTok2); - while (szReg[0] == 's' || szReg[0] == 't') - { - ++szReg; - } - assert(isdigit(szReg[0])); - m_Register[eHWSC_Vertex] = - m_Register[eHWSC_Pixel] = - m_Register[eHWSC_Geometry] = - m_Register[eHWSC_Domain] = - m_Register[eHWSC_Hull] = - m_Register[eHWSC_Compute] = atoi(&szReg[0]); - - uint32 tok2 = pTokens[nCur++]; - if (tok2 != eT_br_rnd_2) - { - CRY_ASSERT(0); - } - } - } - } - } - } - - if (!Annotations.IsEmpty()) - { - uint32 nCur = Annotations.m_nFirstToken; - uint32 nLast = Annotations.m_nLastToken; - uint32* pTokens = &Parser.m_Tokens[0]; - while (nCur <= nLast) - { - uint32 nTok = pTokens[nCur++]; - if (nTok == eT_psslot || nTok == eT_vsslot || nTok == eT_gsslot || nTok == eT_dsslot || nTok == eT_hsslot || nTok == eT_csslot || nTok == eT_slot) - { - m_nFlags |= PF_CUSTOM_BINDED; - { - uint32 nTok2 = pTokens[nCur++]; - if (nTok2 != eT_eq) - { - CRY_ASSERT(0); - } - else - { - nTok2 = pTokens[nCur++]; - const char* szReg = Parser.GetString(nTok2); - assert(isdigit(szReg[0])); - if (nTok == eT_vsslot || nTok == eT_slot) - { - m_Register[eHWSC_Vertex] = atoi(&szReg[0]); - } - else - if (nTok == eT_psslot || nTok == eT_slot) - { - m_Register[eHWSC_Pixel] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsGeometryShaders() && nTok == eT_gsslot || nTok == eT_slot) - { - m_Register[eHWSC_Geometry] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsDomainShaders() && nTok == eT_dsslot || nTok == eT_slot) - { - m_Register[eHWSC_Domain] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsHullShaders() && nTok == eT_hsslot || nTok == eT_slot) - { - m_Register[eHWSC_Hull] = atoi(&szReg[0]); - } - else - if (CParserBin::PlatformSupportsComputeShaders() && nTok == eT_csslot || nTok == eT_slot) - { - m_Register[eHWSC_Compute] = atoi(&szReg[0]); - } - } - } - } - else - { - switch (nTok) - { - case eT_float: - case eT_float2: - case eT_float3: - case eT_float4: - case eT_uint: - case eT_uint2: - case eT_uint4: - case eT_int: - case eT_int2: - case eT_int4: - m_Type = nTok; - break; - default: - break; - } - } - - if (!Parser.JumpSemicolumn(nCur, nLast)) - { - break; - } - } - } -} - -byte CParserBin::GetCompareFunc(EToken eT) -{ - switch (eT) - { - case eT_None: - case eT_Disable: - return eCF_Disable; - case eT_Never: - return eCF_Never; - case eT_Less: - return eCF_Less; - case eT_Equal: - return eCF_Equal; - case eT_LEqual: - case eT_LessEqual: - return eCF_LEqual; - case eT_Greater: - return eCF_Greater; - case eT_NotEqual: - return eCF_NotEqual; - case eT_GEqual: - case eT_GreaterEqual: - return eCF_NotEqual; - case eT_Always: - return eCF_Always; - default: - Warning("unknown CompareFunc parameter '%s' (Skipping)\n", GetString(eT)); - } - return eCF_Less; -} - -int CParserBin::GetSrcBlend(EToken eT) -{ - switch (eT) - { - case eT_ONE: - return GS_BLSRC_ONE; - case eT_ZERO: - return GS_BLSRC_ZERO; - case eT_DST_COLOR: - case eT_DestColor: - return GS_BLSRC_DSTCOL; - case eT_ONE_MINUS_DST_COLOR: - case eT_InvDestColor: - return GS_BLSRC_ONEMINUSDSTCOL; - case eT_SRC_ALPHA: - case eT_SrcAlpha: - return GS_BLSRC_SRCALPHA; - case eT_ONE_MINUS_SRC_ALPHA: - case eT_InvSrcAlpha: - return GS_BLSRC_ONEMINUSSRCALPHA; - case eT_DST_ALPHA: - case eT_DestAlpha: - return GS_BLSRC_DSTALPHA; - case eT_ONE_MINUS_DST_ALPHA: - case eT_InvDestAlpha: - return GS_BLSRC_ONEMINUSDSTALPHA; - case eT_SRC_ALPHA_SATURATE: - return GS_BLSRC_ALPHASATURATE; - - default: - { - Warning("unknown SrcBlend parameter '%s' (Skipping)\n", GetString(eT)); - CRY_ASSERT(0); - } - } - return GS_BLSRC_ONE; -} - -int CParserBin::GetDstBlend(EToken eT) -{ - switch (eT) - { - case eT_ONE: - return GS_BLDST_ONE; - case eT_ZERO: - return GS_BLDST_ZERO; - case eT_SRC_COLOR: - case eT_SrcColor: - return GS_BLDST_SRCCOL; - case eT_ONE_MINUS_SRC_COLOR: - case eT_InvSrcColor: - return GS_BLDST_ONEMINUSSRCCOL; - case eT_SRC_ALPHA: - case eT_SrcAlpha: - return GS_BLDST_SRCALPHA; - case eT_ONE_MINUS_SRC_ALPHA: - case eT_InvSrcAlpha: - return GS_BLDST_ONEMINUSSRCALPHA; - case eT_DST_ALPHA: - case eT_DestAlpha: - return GS_BLDST_DSTALPHA; - case eT_ONE_MINUS_DST_ALPHA: - case eT_InvDestAlpha: - return GS_BLDST_ONEMINUSDSTALPHA; - - default: - { - Warning("unknown DstBlend parameter '%s' (Skipping)\n", GetString(eT)); - CRY_ASSERT(0); - } - } - return GS_BLDST_ONE; -} - -void CParserBin::SetupFeatureDefines() -{ - // globally remove all features here and selectively re-enable them based on project defines and platform validation - RemoveMacro(CParserBin::GetCRC32("FEATURE_MESH_TESSELLATION"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_SELF_SHADOWS"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_PARTICLES_TESSELLATION"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_SPI_CONSTANT_BUFFERS"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_SPI_INDEXED_CB"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_GEOMETRY_SHADERS"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_SVO_GI"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_8_BONE_SKINNING"), m_StaticMacros); - RemoveMacro(CParserBin::GetCRC32("FEATURE_DUAL_SOURCE_BLENDING"), m_StaticMacros); - - uint32 nEnable[1] = { eT_1 }; -#if defined(MESH_TESSELLATION) - if (m_nPlatform == SF_D3D11 || m_nPlatform == SF_GL4) - { - AddMacro(CParserBin::GetCRC32("FEATURE_MESH_TESSELLATION"), nEnable, 1, 0, m_StaticMacros); - } -#endif - -#if defined(FEATURE_DEFERRED_SHADING_SELF_SHADOWS) - // Confetti Nicholas Baldwin: adding metal shader language support - if (m_nPlatform == SF_D3D11 || m_nPlatform == SF_GL4 || m_nPlatform == SF_GLES3 || m_nPlatform == SF_METAL) - { - AddMacro(CParserBin::GetCRC32("FEATURE_SELF_SHADOWS"), nEnable, 1, 0, m_StaticMacros); - } -#endif -#if defined(PARTICLES_TESSELLATION) - if (m_nPlatform == SF_D3D11 || m_nPlatform == SF_JASPER || m_nPlatform == SF_ORBIS || m_nPlatform == SF_GL4) - { - AddMacro(CParserBin::GetCRC32("FEATURE_PARTICLES_TESSELLATION"), nEnable, 1, 0, m_StaticMacros); - } -#endif - - if (m_nPlatform == SF_JASPER || m_nPlatform == SF_ORBIS || m_nPlatform == SF_D3D11 || m_nPlatform == SF_GL4 || m_nPlatform == SF_GLES3 || m_nPlatform == SF_METAL) - { - AddMacro(CParserBin::GetCRC32("FEATURE_SPI_CONSTANT_BUFFERS"), nEnable, 1, 0, m_StaticMacros); - } - - if (m_nPlatform == SF_D3D11 || m_nPlatform == SF_GL4 || m_nPlatform == SF_GLES3 || m_nPlatform == SF_METAL) - { -#if defined(FEATURE_SPI_INDEXED_CB) - AddMacro(CParserBin::GetCRC32("FEATURE_SPI_INDEXED_CB"), nEnable, 1, 0, m_StaticMacros); -#endif - } - - if (m_nPlatform & (SF_D3D11 | SF_ORBIS | SF_JASPER | SF_GL4)) - { - AddMacro(CParserBin::GetCRC32("FEATURE_GEOMETRY_SHADERS"), nEnable, 1, 0, m_StaticMacros); - } - -#if defined(FEATURE_SVO_GI) - AddMacro(CParserBin::GetCRC32("FEATURE_SVO_GI"), nEnable, 1, 0, m_StaticMacros); -#endif - - if (m_nPlatform & (SF_D3D11 | SF_ORBIS | SF_JASPER | SF_GL4)) - { - AddMacro(CParserBin::GetCRC32("FEATURE_DUAL_SOURCE_BLENDING"), nEnable, 1, 0, m_StaticMacros); - } - -#if defined(AZ_PLATFORM_MAC) - const bool isMacOpenGl = true; -#else - const bool isMacOpenGl = false; -#endif - - if ((m_nPlatform & (SF_D3D11 | SF_ORBIS | SF_JASPER)) || (isMacOpenGl == false && m_nPlatform & (SF_GL4))) - { - // Disable FEATURE_8_BONE_SKINNING because structurebuffer sb_SkinExtraBlendWeights is not handled in the code currently. - // AddMacro(CParserBin::GetCRC32("FEATURE_8_BONE_SKINNING"), nEnable, 1, 0, m_StaticMacros); - } - -#if !defined(NULL_RENDERER) - if (!gRenDev->IsShaderCacheGenMode()) - { - if (!RenderCapabilities::SupportsDepthClipping()) - { - gRenDev->m_cEF.AddStaticFlag(HWSST_NO_DEPTH_CLIPPING); - } - } -#endif // !defined(NULL_RENDERER) -} - -void CParserBin::SetupShadersCacheAndFilter() -{ - const char* shaderLanguageName = GetShaderLanguageName(); - - gRenDev->m_cEF.m_ShadersCache = AZStd::string::format("%s%s/", g_shaderCache, shaderLanguageName); - gRenDev->m_cEF.m_ShadersFilter = shaderLanguageName; -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.h b/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.h deleted file mode 100644 index eae9e0559c..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ParserBin.h +++ /dev/null @@ -1,1045 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Script parser declarations. - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_PARSERBIN_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_PARSERBIN_H -#pragma once - -#include "ShaderCache.h" -#include "ShaderAllocator.h" - -namespace AZ -{ - enum class PlatformID; -} - -extern TArray sfxIFDef; - -typedef TArray ShaderTokensVec; - -// key tokens -enum EToken -{ - eT_unknown = 0, - eT_include = 1, - eT_define = 2, - eT_define_2 = 3, - eT_undefine = 4, - - eT_fetchinst = 5, - eT_if = 6, - eT_ifdef = 7, - eT_ifndef = 8, - eT_if_2 = 9, - eT_ifdef_2 = 10, - eT_ifndef_2 = 11, - eT_elif = 12, - - eT_endif = 13, - eT_else = 14, - eT_or = 15, - eT_and = 16, - eT_warning = 17, - eT_register_env = 18, - eT_ifcvar = 19, - eT_ifncvar = 20, - eT_elifcvar = 21, - eT_skip = 22, - eT_skip_1 = 23, - eT_skip_2 = 24, - - eT_br_rnd_1 = 25, - eT_br_rnd_2 = 26, - eT_br_sq_1 = 27, - eT_br_sq_2 = 28, - eT_br_cv_1 = 29, - eT_br_cv_2 = 30, - eT_br_tr_1 = 31, - eT_br_tr_2 = 32, - eT_comma = 33, - eT_dot = 34, - eT_colon = 35, - eT_semicolumn = 36, - eT_excl = 37, // ! - eT_quote = 38, - eT_sing_quote = 39, - - eT_question = 40, - eT_eq = 41, - eT_plus = 42, - eT_minus = 43, - eT_div = 44, - eT_mul = 45, - eT_dot_math = 46, - eT_mul_math = 47, - eT_sqrt_math = 48, - eT_exp_math = 49, - eT_log_math = 50, - eT_log2_math = 51, - eT_sin_math = 52, - eT_cos_math = 53, - eT_sincos_math = 54, - eT_floor_math = 55, - eT_ceil_math = 56, - eT_frac_math = 57, - eT_lerp_math = 58, - eT_abs_math = 59, - eT_clamp_math = 60, - eT_min_math = 61, - eT_max_math = 62, - eT_length_math = 63, - - eT_tex2D, - eT_tex2Dproj, - eT_tex3D, - eT_texCUBE, - eT_SamplerState, - eT_SamplerComparisonState, - eT_sampler_state, - eT_Texture2D, - eT_RWTexture2D, - eT_RWTexture2DArray, - eT_Texture2DArray, - eT_Texture2DMS, - eT_TextureCube, - eT_TextureCubeArray, - eT_Texture3D, - eT_RWTexture3D, - - eT_float, - eT_float2, - eT_float3, - eT_float4, - eT_float4x4, - eT_float3x4, - eT_float2x4, - eT_float3x3, - eT_half, - eT_half2, - eT_half3, - eT_half4, - eT_half4x4, - eT_half3x4, - eT_half2x4, - eT_half3x3, - eT_bool, - eT_int, - eT_int2, - eT_int4, - eT_uint, - eT_uint2, - eT_uint4, - eT_sampler1D, - eT_sampler2D, - eT_sampler3D, - eT_samplerCUBE, - eT_const, - - eT_inout, - - eT_struct, - eT_sampler, - eT_TEXCOORDN, - eT_TEXCOORD0, - eT_TEXCOORD1, - eT_TEXCOORD2, - eT_TEXCOORD3, - eT_TEXCOORD4, - eT_TEXCOORD5, - eT_TEXCOORD6, - eT_TEXCOORD7, - eT_TEXCOORD8, - eT_TEXCOORD9, - eT_TEXCOORD10, - eT_TEXCOORD11, - eT_TEXCOORD12, - eT_TEXCOORD13, - eT_TEXCOORD14, - eT_TEXCOORD15, - eT_TEXCOORD16, - eT_TEXCOORD17, - eT_TEXCOORD18, - eT_TEXCOORD19, - eT_TEXCOORD20, - eT_TEXCOORD21, - eT_TEXCOORD22, - eT_TEXCOORD23, - eT_TEXCOORD24, - eT_TEXCOORD25, - eT_TEXCOORD26, - eT_TEXCOORD27, - eT_TEXCOORD28, - eT_TEXCOORD29, - eT_TEXCOORD30, - eT_TEXCOORD31, - eT_TEXCOORDN_centroid, - eT_TEXCOORD0_centroid, - eT_TEXCOORD1_centroid, - eT_TEXCOORD2_centroid, - eT_TEXCOORD3_centroid, - eT_TEXCOORD4_centroid, - eT_TEXCOORD5_centroid, - eT_TEXCOORD6_centroid, - eT_TEXCOORD7_centroid, - eT_TEXCOORD8_centroid, - eT_TEXCOORD9_centroid, - eT_TEXCOORD10_centroid, - eT_TEXCOORD11_centroid, - eT_TEXCOORD12_centroid, - eT_TEXCOORD13_centroid, - eT_TEXCOORD14_centroid, - eT_TEXCOORD15_centroid, - eT_TEXCOORD16_centroid, - eT_TEXCOORD17_centroid, - eT_TEXCOORD18_centroid, - eT_TEXCOORD19_centroid, - eT_TEXCOORD20_centroid, - eT_TEXCOORD21_centroid, - eT_TEXCOORD22_centroid, - eT_TEXCOORD23_centroid, - eT_TEXCOORD24_centroid, - eT_TEXCOORD25_centroid, - eT_TEXCOORD26_centroid, - eT_TEXCOORD27_centroid, - eT_TEXCOORD28_centroid, - eT_TEXCOORD29_centroid, - eT_TEXCOORD30_centroid, - eT_TEXCOORD31_centroid, - eT_COLOR0, - eT_static, - eT_shared, - eT_groupshared, - eT_packoffset, - eT_register, - eT_return, - eT_vsregister, - eT_psregister, - eT_gsregister, - eT_dsregister, - eT_hsregister, - eT_csregister, - - eT_slot, - eT_vsslot, - eT_psslot, - eT_gsslot, - eT_dsslot, - eT_hsslot, - eT_csslot, - - - eT_StructuredBuffer, - eT_RWStructuredBuffer, - eT_ByteAddressBuffer, - eT_RWByteAddressBuffer, - eT_Buffer, - eT_RWBuffer, - eT_RasterizerOrderedBuffer, - eT_RasterizerOrderedByteAddressBuffer, - eT_RasterizerOrderedStructuredBuffer, - - eT_color, - eT_Position, - eT_Allways, - - eT_STANDARDSGLOBAL, - - eT_technique, - eT_string, - eT_UIName, - eT_UIDescription, - eT_UIWidget, - eT_UIWidget0, - eT_UIWidget1, - eT_UIWidget2, - eT_UIWidget3, - - eT_Texture, - eT_Filter, - eT_MinFilter, - eT_MagFilter, - eT_MipFilter, - eT_AddressU, - eT_AddressV, - eT_AddressW, - eT_BorderColor, - eT_sRGBLookup, - - eT_LINEAR, - eT_POINT, - eT_NONE, - eT_ANISOTROPIC, - eT_MIN_MAG_MIP_POINT, - eT_MIN_MAG_MIP_LINEAR, - eT_MIN_MAG_LINEAR_MIP_POINT, - eT_COMPARISON_MIN_MAG_LINEAR_MIP_POINT, - eT_MINIMUM_MIN_MAG_MIP_LINEAR, - eT_MAXIMUM_MIN_MAG_MIP_LINEAR, - - eT_Clamp, - eT_Border, - eT_Wrap, - eT_Mirror, - - eT_Script, - eT_comment, - eT_asm, - - eT_RenderOrder, - eT_ProcessOrder, - eT_RenderCamera, - eT_RenderType, - eT_RenderFilter, - eT_RenderColorTarget1, - eT_RenderDepthStencilTarget, - eT_ClearSetColor, - eT_ClearSetDepth, - eT_ClearTarget, - eT_RenderTarget_IDPool, - eT_RenderTarget_UpdateType, - eT_RenderTarget_Width, - eT_RenderTarget_Height, - eT_GenerateMips, - - eT_PreProcess, - eT_PostProcess, - eT_PreDraw, - - eT_WaterReflection, - eT_Panorama, - - eT_WaterPlaneReflected, - eT_PlaneReflected, - eT_Current, - - eT_CurObject, - eT_CurScene, - eT_RecursiveScene, - eT_CopyScene, - - eT_Refractive, - eT_ForceRefractionUpdate, - eT_Heat, - - eT_DepthBuffer, - eT_DepthBufferTemp, - eT_DepthBufferOrig, - - eT_$ScreenSize, - eT_WaterReflect, - eT_FogColor, - - eT_Color, - eT_Depth, - - eT_$RT_2D, - eT_$RT_Cube, - - eT_pass, - eT_CustomRE, - eT_Style, - - eT_VertexShader, - eT_PixelShader, - eT_GeometryShader, - eT_HullShader, - eT_DomainShader, - eT_ComputeShader, - eT_ZEnable, - eT_ZWriteEnable, - eT_CullMode, - eT_SrcBlend, - eT_DestBlend, - eT_AlphaBlendEnable, - eT_AlphaFunc, - eT_AlphaRef, - eT_ZFunc, - eT_ColorWriteEnable, - eT_IgnoreMaterialState, - - eT_None, - eT_Disable, - eT_CCW, - eT_CW, - eT_Back, - eT_Front, - - eT_Never, - eT_Less, - eT_Equal, - eT_LEqual, - eT_LessEqual, - eT_NotEqual, - eT_GEqual, - eT_GreaterEqual, - eT_Greater, - eT_Always, - - eT_RED, - eT_GREEN, - eT_BLUE, - eT_ALPHA, - - eT_ONE, - eT_ZERO, - eT_SRC_COLOR, - eT_SrcColor, - eT_ONE_MINUS_SRC_COLOR, - eT_InvSrcColor, - eT_SRC_ALPHA, - eT_SrcAlpha, - eT_ONE_MINUS_SRC_ALPHA, - eT_InvSrcAlpha, - eT_DST_ALPHA, - eT_DestAlpha, - eT_ONE_MINUS_DST_ALPHA, - eT_InvDestAlpha, - eT_DST_COLOR, - eT_DestColor, - eT_ONE_MINUS_DST_COLOR, - eT_InvDestColor, - eT_SRC_ALPHA_SATURATE, - - eT_NULL, - - eT_cbuffer, - eT_PER_BATCH, - eT_PER_INSTANCE, - eT_PER_FRAME, - eT_PER_MATERIAL, - eT_PER_SHADOWGEN, - - eT_ShaderType, - eT_ShaderDrawType, - eT_PreprType, - eT_Public, - eT_NoPreview, - eT_LocalConstants, - eT_Cull, - eT_SupportsAttrInstancing, - eT_SupportsConstInstancing, - eT_SupportsDeferredShading, - eT_SupportsFullDeferredShading, - eT_Decal, - eT_DecalNoDepthOffset, - eT_NoChunkMerging, - eT_ForceTransPass, - eT_AfterHDRPostProcess, - eT_AfterPostProcess, - eT_ForceZpass, - eT_ForceWaterPass, - eT_ForceDrawLast, - eT_ForceDrawFirst, - eT_ForceDrawAfterWater, - eT_DepthFixup, - eT_SingleLightPass, - eT_HWTessellation, - eT_WaterParticle, - eT_AlphaBlendShadows, - eT_ZPrePass, - - eT_Light, - eT_Shadow, - eT_Fur, - eT_General, - eT_Terrain, - eT_Overlay, - eT_NoDraw, - eT_Custom, - eT_Sky, - eT_OceanShore, - eT_Hair, - eT_Compute, - eT_ForceGeneralPass, - eT_SkinPass, - eT_EyeOverlay, - - eT_Metal, - eT_Ice, - eT_Water, - eT_FX, - eT_HDR, - eT_Glass, - eT_Vegetation, - eT_Particle, - eT_GenerateSprites, - eT_GenerateClouds, - eT_ScanWater, - - eT_NoLights, - eT_NoMaterialState, - eT_PositionInvariant, - - //------------------------------------------------------------------------- - // Technique Order - //------------------------------------------------------------------------- - // Remark: The following technique has to be first Technique as we are subtracting it to get - // index of technique's slots. - // Warning: if technique slots order is changed they should be well reflected in other files - // such as 'IShader.h' which defines the order of the techniques' slots as per 'EShaderTechniqueID'. - // This is all matched in the method 'CShaderMan::mfPostLoadFX' during load. - //------------------------------------------------------------------------- - eT_TechniqueZ, - eT_TechniqueShadowGen, - eT_TechniqueMotionBlur, - eT_TechniqueCustomRender, - eT_TechniqueEffectLayer, - eT_TechniqueDebug, - eT_TechniqueSoftAlphaTest, - eT_TechniqueWaterRefl, - eT_TechniqueWaterCaustic, - eT_TechniqueZPrepass, - eT_TechniqueThickness, - - eT_TechniqueMax, - //------------------------------------------------------------------------- - - eT_KeyFrameParams, - eT_KeyFrameRandColor, - eT_KeyFrameRandIntensity, - eT_KeyFrameRandSpecMult, - eT_KeyFrameRandPosOffset, - eT_Speed, - - eT_Beam, - eT_LensOptics, - eT_Cloud, - eT_Ocean, - - eT_Model, - eT_StartRadius, - eT_EndRadius, - eT_StartColor, - eT_EndColor, - eT_LightStyle, - eT_Length, - - eT_RGBStyle, - eT_Scale, - eT_Blind, - eT_SizeBlindScale, - eT_SizeBlindBias, - eT_IntensBlindScale, - eT_IntensBlindBias, - eT_MinLight, - eT_DistFactor, - eT_DistIntensityFactor, - eT_FadeTime, - eT_Layer, - eT_Importance, - eT_VisAreaScale, - - eT_Poly, - eT_Identity, - eT_FromObj, - eT_FromLight, - eT_Fixed, - - eT_ParticlesFile, - - eT_Gravity, - eT_WindDirection, - eT_WindSpeed, - eT_WaveHeight, - eT_DirectionalDependence, - eT_ChoppyWaveFactor, - eT_SuppressSmallWavesFactor, - - eT__LT_LIGHTS, - eT__LT_NUM, - eT__LT_HASPROJ, - eT__LT_0_TYPE, - eT__LT_1_TYPE, - eT__LT_2_TYPE, - eT__LT_3_TYPE, - eT__TT_TEXCOORD_MATRIX, - eT__TT_TEXCOORD_PROJ, - eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE, - eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE, - eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT, - eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL, - eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM, - eT__VT_TYPE, - eT__VT_TYPE_MODIF, - eT__VT_BEND, - eT__VT_DET_BEND, - eT__VT_GRASS, - eT__VT_WIND, - eT__VT_DEPTH_OFFSET, - eT__FT_TEXTURE, - eT__FT_TEXTURE1, - eT__FT_NORMAL, - eT__FT_PSIZE, - eT__FT_DIFFUSE, - eT__FT_SPECULAR, - eT__FT_TANGENT_STREAM, - eT__FT_QTANGENT_STREAM, - eT__FT_SKIN_STREAM, - eT__FT_VERTEX_VELOCITY_STREAM, - eT__FT_SRGBWRITE, - eT__FT0_COP, - eT__FT0_AOP, - eT__FT0_CARG1, - eT__FT0_CARG2, - eT__FT0_AARG1, - eT__FT0_AARG2, - - eT__VS, - eT__PS, - eT__GS, - eT__HS, - eT__DS, - eT__CS, - - eT__g_SkinQuat, - - eT_x, - eT_y, - eT_z, - eT_w, - eT_r, - eT_g, - eT_b, - eT_a, - - eT_true, - eT_false, - - eT_0, - eT_1, - eT_2, - eT_3, - eT_4, - eT_5, - eT_6, - eT_7, - eT_8, - eT_9, - eT_10, - eT_11, - eT_12, - eT_13, - eT_14, - eT_15, - eT_16, - eT_17, - eT_18, - eT_19, - eT_20, - eT_21, - eT_22, - eT_23, - eT_24, - - eT_AnisotropyLevel, - - eT_ORBIS, - eT_PCDX11, - eT_GL4, - eT_GLES3, - eT_METAL, - eT_OSXMETAL, - eT_IOSMETAL, - - eT_VT_DetailBendingGrass, - eT_VT_DetailBending, - eT_VT_WindBending, - eT_VertexColors, - - eT_s0, - eT_s1, - eT_s2, - eT_s3, - eT_s4, - eT_s5, - eT_s6, - eT_s7, - eT_s8, - eT_s9, - eT_s10, - eT_s11, - eT_s12, - eT_s13, - eT_s14, - eT_s15, - - eT_t0, - eT_t1, - eT_t2, - eT_t3, - eT_t4, - eT_t5, - eT_t6, - eT_t7, - eT_t8, - eT_t9, - eT_t10, - eT_t11, - eT_t12, - eT_t13, - eT_t14, - eT_t15, - - eT_Global, - - eT_GLES3_0, - - eT_Load, - eT_Sample, - eT_Gather, - eT_GatherRed, - eT_GatherGreen, - eT_GatherBlue, - eT_GatherAlpha, - - eT_max, - eT_user_first = eT_max + 1 -}; - -enum ETokenStorageClass -{ - eTS_invalid = 0, - eTS_default, - eTS_static, - eTS_const, - eTS_shared, - eTS_groupshared -}; - -struct SFXTokenBin -{ - uint32 id; -}; - -#define FX_BEGIN_TOKENS \ - static SFXTokenBin sCommands[] = { -#define FX_END_TOKENS \ - { eT_unknown } \ - }; - -#define FX_TOKEN(id) \ - { Parser.fxTokenKey(#id, eT_##id) }, - -#define FX_REGISTER_TOKEN(id) fxTokenKey(#id, eT_##id); - - -extern const char* g_KeyTokens[]; - -struct SMacroBinFX -{ - AZStd::vector m_Macro; - uint64 m_nMask; -}; - -class CParserBin; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXMacroBin; -typedef FXMacroBin::iterator FXMacroBinItor; - -struct SParserFrame -{ - uint32 m_nFirstToken; - uint32 m_nLastToken; - uint32 m_nCurToken; - SParserFrame(uint32 nFirstToken, uint32 nLastToken) - { - m_nFirstToken = nFirstToken; - m_nLastToken = nLastToken; - m_nCurToken = m_nFirstToken; - } - SParserFrame() - { - m_nFirstToken = 0; - m_nLastToken = 0; - m_nCurToken = m_nFirstToken; - } - _inline void Reset() - { - m_nFirstToken = 0; - m_nLastToken = 0; - m_nCurToken = m_nFirstToken; - } - _inline bool IsEmpty() - { - if (!m_nFirstToken && !m_nLastToken) - { - return true; - } - return (m_nLastToken < m_nFirstToken); - } -}; - -enum EFragmentType -{ - eFT_Unknown, - eFT_Function, - eFT_Structure, - eFT_Sampler, - eFT_ConstBuffer, - eFT_StorageClass -}; - -struct SCodeFragment -{ - uint32 m_nFirstToken; - uint32 m_nLastToken; - uint32 m_dwName; - EFragmentType m_eType; -#ifdef _DEBUG - //string m_Name; -#endif - SCodeFragment() - { - m_nFirstToken = 0; - m_nLastToken = 0; - m_dwName = 0; - m_eType = eFT_Unknown; - } -}; - -struct SortByToken -{ - bool operator () (const STokenD& left, const STokenD& right) const - { - return left.Token < right.Token; - } - bool operator () (const uint32 left, const STokenD& right) const - { - return left < right.Token; - } - bool operator () (const STokenD& left, uint32 right) const - { - return left.Token < right; - } -}; - -// Confetti Nicholas Baldwin: adding metal shader language support -#define SF_JASPER 0x0200000 -#define SF_METAL 0x04000000 -#define SF_GLES3 0x08000000 -#define SF_D3D11 0x10000000 -#define SF_ORBIS 0x20000000 -#define SF_GL4 0x80000000 -#define SF_PLATFORM 0xfc000000 - -class CParserBin - : public ISystemEventListener -{ - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - - friend class CShaderManBin; - friend class CHWShader_D3D; - friend struct SFXParam; - friend struct SFXSampler; - friend struct SFXTexture; - friend class CREBeam; - friend class CRECloud; - - //bool m_bEmbeddedSearchInfo; - struct SShaderBin* m_pCurBinShader; - CShader* m_pCurShader; - TArray m_Tokens; - FXMacroBin m_Macros[2]; - FXShaderToken m_TokenTable; - TArray m_IfAffectMask; - //std::vector> m_KeyOffsets; - EToken m_eToken; - uint32 m_nFirstToken; - TArray m_CodeFragments; - //std::vector m_Parameters; - //std::vector m_Samplers; - - SParserFrame m_CurFrame; - - SParserFrame m_Name; - SParserFrame m_Assign; - SParserFrame m_Annotations; - SParserFrame m_Value; - SParserFrame m_Data; - - static FXMacroBin m_StaticMacros; - - TArray sfxIFIgnore; - -public: - CParserBin(SShaderBin* pBin); - CParserBin(SShaderBin* pBin, CShader* pSH); - ~CParserBin(); - SParserFrame& GetData() {return m_Data; } - const char* GetString(uint32 nToken, bool bOnlyKey = false); - string GetString(SParserFrame& Frame); - SParserFrame BeginFrame(SParserFrame& Frame); - void EndFrame(SParserFrame& Frame); - ETokenStorageClass ParseObject(SFXTokenBin* pTokens, int& nIndex); - ETokenStorageClass ParseObject(SFXTokenBin* pTokens); - - static FXMacroBin& GetStaticMacroses() { return m_StaticMacros; } - static const char* GetString(uint32 nToken, FXShaderToken& Table, bool bOnlyKey = false); - CCryNameR GetNameString(SParserFrame& Frame); - void BuildSearchInfo(); - bool PreprocessTokens(ShaderTokensVec& Tokens, int nPass, PodArray& tokensBuffer); - bool Preprocess(int nPass, ShaderTokensVec& Tokens, FXShaderToken* pSrcTable); - static const SMacroBinFX* FindMacro(uint32 dwName, FXMacroBin& Macro); - static bool AddMacro(uint32 dwToken, const uint32* pMacro, int nMacroTokens, uint64 nMask, FXMacroBin& Macro); - static bool RemoveMacro(uint32 dwToken, FXMacroBin& Macro); - static void CleanPlatformMacros(); - uint32 NewUserToken(uint32 nToken, const char* psToken, bool bUseFinalTable); - //uint32 NewUserToken(uint32 nToken, const string& sToken, bool bUseFinalTable); - void MergeTable(SShaderBin* pBin); - bool CheckIfExpression(const uint32* pTokens, uint32& nT, int nPass, uint64* nMask = 0); - bool IgnorePreprocessBlock(const uint32* pTokens, uint32& nT, int nMaxTokens, PodArray& tokensBuffer, int nPass); - static bool CorrectScript(uint32* pTokens, uint32& i, uint32 nT, TArray& Text); - static bool ConvertToAscii(uint32* pTokens, uint32 nT, FXShaderToken& Table, TArray& Text, bool bInclSkipTokens = false); - bool GetBool(SParserFrame& Frame); - _inline uint32* GetTokens(int nStart) { return &m_Tokens[nStart]; } - _inline int GetNumTokens() { return m_Tokens.size(); } - _inline EToken GetToken() { return m_eToken; } - _inline EToken GetToken(SParserFrame& Frame) - { - assert(!Frame.IsEmpty()); - return (EToken)m_Tokens[Frame.m_nFirstToken]; - } - _inline uint32 FirstToken() { return m_nFirstToken; } - _inline int GetInt(uint32 nToken) - { - const char* szStr = GetString(nToken); - if (szStr[0] == '0' && szStr[1] == 'x') - { - int i = 0; -#ifndef NDEBUG - int res = -#endif - azsscanf(&szStr[2], "%x", &i); - assert(res != 0); - return i; - } - return atoi(szStr); - } - _inline float GetFloat(SParserFrame& Frame) - { - return (float)atof(GetString(Frame).c_str()); - } - static _inline uint32 NextToken(const uint32* pTokens, uint32& nCur, uint32 nLast) - { - while (nCur <= nLast) - { - uint32 nToken = pTokens[nCur++]; - if (nToken == eT_skip) - { - nCur++; - continue; - } - if (nToken == eT_skip_1) - { - while (nCur <= nLast) - { - nToken = pTokens[nCur++]; - if (nToken == eT_skip_2) - { - break; - } - } - continue; - } - return nToken; - } - return 0; - } - - byte GetCompareFunc(EToken eT); - int GetSrcBlend(EToken eT); - int GetDstBlend(EToken eT); - - void InsertSkipTokens(const uint32* pTokens, uint32 nStart, uint32 nTokens, bool bSingle, PodArray& tokensBuffer); - int GetNextToken(uint32& nStart, ETokenStorageClass& nTokenStorageClass); - bool FXGetAssignmentData(SParserFrame& Frame); - bool FXGetAssignmentData2(SParserFrame& Frame); - bool GetAssignmentData(SParserFrame& Frame); - bool GetSubData(SParserFrame& Frame, EToken eT1, EToken eT2); - static int32 FindToken(uint32 nStart, uint32 nLast, const uint32* pTokens, uint32 nToken); - int32 FindToken(uint32 nStart, uint32 nLast, uint32 nToken); - int32 FindToken(uint32 nStart, uint32 nLast, const uint32* pTokens); - int CopyTokens(SParserFrame& Fragment, std::vector& NewTokens); - int CopyTokens(SCodeFragment* pCF, PodArray& SHData, TArray& Replaces, TArray& NewTokens, uint32 nID); - static _inline void AddDefineToken(uint32 dwToken, ShaderTokensVec& Tokens) - { - Tokens.push_back(eT_define); - Tokens.push_back(dwToken); - Tokens.push_back(0); - } - static _inline void AddDefineToken(uint32 dwToken, uint32 dwToken2, ShaderTokensVec& Tokens) - { - Tokens.push_back(eT_define); - Tokens.push_back(dwToken); - Tokens.push_back(dwToken2); - Tokens.push_back(0); - } - bool JumpSemicolumn(uint32& nStart, uint32 nEnd); - - static uint32 fxToken(const char* szToken, bool* bKey = NULL); - static uint32 fxTokenKey(const char* szToken, EToken eT = eT_unknown); - static uint32 GetCRC32(const char* szStr); - //! Gets the next token from the buffer - //! @param buf The buffer that is being parsed - //! @param com Buffer into which the complete token is written - //! @param bKey Set to true if the token is a 'key' token, false otherwise. Key tokens are enumerated by EToken, with corresponding string values set int CParserBin::Init(). - //! @return Returns the enum of the key token if bKey is true, eT_unknown otherwise - static uint32 NextToken(char*& buf, char* com, bool& bKey); - static void Init(); - static void RemovePlatformDefines(); - static void SetupForOrbis(); - static void SetupForD3D9(); - static void SetupForD3D11(); - static void SetupForGL4(); - static void SetupForGLES3(); - static void SetupForMETAL(); - static void SetupTargetPlatform(); - // Confetti David Srour: sets up GMEM path related macros - // 0 = no gmem, 1 = 256bpp, 2 = 128bpp (matches the r_enableGMEMPath cvar) - static void SetupForGMEM(int gmemPath); - static void SetupGMEMCommonStaticFlags(); - static void RemoveGMEMStaticFlags(); - static void SetupForJasper(); - static void SetupFeatureDefines(); - static void SetupShadersCacheAndFilter(); - static CCryNameTSCRC GetPlatformSpecName(CCryNameTSCRC orgName); - - static bool PlatformSupportsConstantBuffers(){return (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_GLES3 || CParserBin::m_nPlatform == SF_METAL); }; - static bool PlatformSupportsGeometryShaders(){return (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4); } - static bool PlatformSupportsHullShaders(){return (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4); } - static bool PlatformSupportsDomainShaders(){return (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4); } - static bool PlatformSupportsComputeShaders() - { - bool ret = (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_METAL || CParserBin::m_nPlatform == SF_GLES3); - return ret; - } - static bool PlatformIsConsole(){return (CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER); }; - - static bool m_bEditable; - static uint32 m_nPlatform; // Shader language - static AZ::PlatformID m_targetPlatform; // Platform - static bool m_bEndians; - static bool m_bParseFX; - static bool m_bShaderCacheGen; -}; - -char* fxFillPr (char** buf, char* dst); - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_PARSERBIN_H diff --git a/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.cpp b/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.cpp deleted file mode 100644 index 874dec6c48..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "PoundPoundParser.h" -#include - -class PoundPoundContext::Impl -{ -public: - Impl() : m_ownedLayer(nullptr) - {} - ~Impl() - { - delete m_ownedLayer; - } - - void Preprocess(char** buf); - bool IsEndOfBuffer(char** buf, bool* layerSwitch); - void SetDefine(const AZStd::string &name, const AZStd::string &value) - { - m_macros[name] = value; - } - -private: - class Layer { - public: - Layer* m_ownedNextLayer; - enum struct IfState { - noIf, - activeIf, - triggeredIf, - dormantIf, - activeElse, - dormantElse - }; - IfState m_ifState; - - enum struct InterdictionState { - interdictionActive, - interdictionPaused - }; - InterdictionState m_interdictionState; - - char* m_oldBuffer; - char* m_ownedIncludeBuffer; - - Layer(Layer* layer) - : m_ownedNextLayer(layer) - , m_ifState(IfState::noIf) - , m_interdictionState(InterdictionState::interdictionActive) - , m_oldBuffer(nullptr) - , m_ownedIncludeBuffer(nullptr) - { - } - - ~Layer() - { - delete[] m_ownedIncludeBuffer; - delete m_ownedNextLayer; - } - }; - - AZStd::string ConsumeLine(char** buf); - using Tokens = AZStd::vector; - Tokens TokenizeLine(char** buf, const char* regex); - - void EvaluateIf(const Tokens& tokens); - - void ProcessIf(char** buf); - void ProcessElif(char** buf); - void ProcessElse(char** buf); - void ProcessEndif(char** buf); - void ProcessDefine(char** buf); - void ProcessUndef(char** buf); - void ProcessInclude(char** buf); - - Layer *m_ownedLayer; - using Macros = AZStd::unordered_map; - Macros m_macros; -}; - -void PoundPoundContext::Impl::Preprocess(char** buf) -{ - bool layerSwitch; - - // We should only get called when the buffer is pointing at a ## directive - do - { - // Handle the if/elif/else/endif directives. These always need to be processed because of scope stacking - if (!strncmp(*buf, "##if", 4)) - { - *buf += 4; - ProcessIf(buf); - } - else if (!strncmp(*buf, "##elif", 6)) - { - *buf += 6; - ProcessElif(buf); - } - else if (!strncmp(*buf, "##else", 6)) - { - *buf += 6; - ProcessElse(buf); - } - else if (!strncmp(*buf, "##endif", 7)) - { - *buf += 7; - ProcessEndif(buf); - } - - // If the interdiction is active, these ## directives can be ignored - else if (m_ownedLayer != nullptr && m_ownedLayer->m_interdictionState == Layer::InterdictionState::interdictionActive) - { - if (!strncmp(*buf, "##define", 8) || !strncmp(*buf, "##undef", 7) || !strncmp(*buf, "##include_restricted", 20)) - { - ConsumeLine(buf); - } - else - { - AZ_Assert(false, "unknown ## directive"); - } - } - - // Otherwise, process the non-if related tokens - else - { - if (!strncmp(*buf, "##define", 8)) - { - *buf += 8; - ProcessDefine(buf); - } - else if (!strncmp(*buf, "##undef", 7)) - { - *buf += 7; - ProcessUndef(buf); - } - else if (!strncmp(*buf, "##include_restricted", 20)) - { - *buf += 20; - ProcessInclude(buf); - } - else - { - AZ_Assert(false, "unknown ## directive"); - } - } - - // We've processed the token line. If we aren't interdicting the text, let the caller process normally - if (!m_ownedLayer - || m_ownedLayer->m_interdictionState == Layer::InterdictionState::interdictionPaused) - { - return; - } - - // We are interdicting, so keep going until we find another ## directive or we run out of buffer - while (!IsEndOfBuffer(buf, &layerSwitch)) - { - if (**buf == '#' && (*buf)[1] == '#') - { - break; - } - ++(*buf); - } - - // Return if we are at EOB, otherwise start parsing the next ## directive. - } while (!IsEndOfBuffer(buf, &layerSwitch)); -} - -bool PoundPoundContext::Impl::IsEndOfBuffer(char** buf, bool* layerSwitch) -{ - // Standard non-variant EOB cases - if (*buf == nullptr) - { - return true; - } - if (**buf != 0) - { - return false; - } - - // At this point we have hit a zero in the buffer. If there are no layers active, then we are truly - // at the end of parseable text - if (m_ownedLayer == nullptr) - { - return true; - } - - // Otherwise, we must be at the end of a ##include file. Indicate a layer switch (because the caller may need to - // reparse past comments/whitespace), then restore the previous layer and delete this one. - AZ_Assert(m_ownedLayer->m_ownedIncludeBuffer != nullptr, "#include buffer is missing"); - AZ_Assert(m_ownedLayer->m_ifState == Layer::IfState::noIf, "Reached end of #include buffer while #if was still in scope"); - *layerSwitch = true; - auto next = m_ownedLayer->m_ownedNextLayer; - *buf = m_ownedLayer->m_oldBuffer; - m_ownedLayer->m_ownedNextLayer = nullptr; - delete m_ownedLayer; - m_ownedLayer = next; - - // We don't know whether the new layer is at EOB, so we now have to check it. - return IsEndOfBuffer(buf, layerSwitch); -} - -AZStd::string PoundPoundContext::Impl::ConsumeLine(char** buf) -{ - // Copy the remainder of the line into a scratch buffer, consuming the text including the EOL in the buffer - auto start = *buf; - char ch; - while ((ch = **buf) != 0) - { - if (ch == '\n') - { - break; - } - ++(*buf); - } - auto lineLen = *buf - start; - auto lineBuf = new char[lineLen + 1]; - azstrncpy(lineBuf, lineLen + 1, start, lineLen); - // Make sure to have a null-terminated buffer - lineBuf[lineLen] = '\0'; - - if (**buf == '\n') - { - ++(*buf); - } - - AZStd::string result(lineBuf); - delete[] lineBuf; - return result; -} - -// Use regex to parse text into tokens -PoundPoundContext::Impl::Tokens PoundPoundContext::Impl::TokenizeLine(char** buf, const char* pattern) -{ - AZStd::vector tokens; - - auto lineBuf = ConsumeLine(buf); - AZStd::cmatch match; - if (AZStd::regex_search(lineBuf.c_str(), match, AZStd::regex(pattern))) - { - // First pattern is always the entire string - for (unsigned i = 1; i < match.size(); ++i) - { - if (match[i].matched) - { - tokens.push_back(match[i].str().c_str()); - } - } - } - - return tokens; -} - -// Handles evaluating the conditional we support. ##if NAME will simply test for the existance of the NAME macro, pausing the -// interdiction if it is true. ## NAME == VALUE will convert either both sides to values (if they are macros) and then compare, -// pausing interdiction if the two sides equate. Everything is done as strings. -void PoundPoundContext::Impl::EvaluateIf(const Tokens& tokens) -{ - auto tokenCount = tokens.size(); - switch (tokenCount) - { - case 1: - { - auto finder = m_macros.find(tokens[0]); - if (finder != m_macros.end()) - { - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionPaused; - m_ownedLayer->m_ifState = Layer::IfState::triggeredIf; - } - } - break; - - case 3: - { - AZ_Assert(tokens[1] == "==", "Unknown operator %s in ##if/##elif", tokens[1].c_str()); - - // Expand both sides of the file as needed - auto finder = m_macros.find(tokens[0]); - AZStd::string value1 = (finder == m_macros.end()) ? tokens[0] : finder->second; - finder = m_macros.find(tokens[2]); - AZStd::string value2 = (finder == m_macros.end()) ? tokens[2] : finder->second; - - // start reading again if true - if (value1 == value2) - { - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionPaused; - m_ownedLayer->m_ifState = Layer::IfState::triggeredIf; - } - } - break; - - default: - AZ_Assert(false, "Malformed ##if/##elif condition"); - break; - } -} - -void PoundPoundContext::Impl::ProcessIf(char** buf) -{ - auto oldLayer = m_ownedLayer; - m_ownedLayer = new Layer(oldLayer); - - // Initialize the layer state based on parent state - m_ownedLayer->m_ifState = Layer::IfState::activeIf; - bool parseIf = true; - if (oldLayer != nullptr) - { - // Look at the parent's if state (if the parent is an #include file, we know it is active so no - // need to test for weird combos there) and make sure to start disabled if the parent is disabled. - // There are possible modes of nesting here that haven't been handled... - switch (oldLayer->m_ifState) - { - case Layer::IfState::activeIf: - case Layer::IfState::triggeredIf: - AZ_Assert(false, "unimplemented ##if state"); - break; - - case Layer::IfState::dormantIf: - case Layer::IfState::dormantElse: - m_ownedLayer->m_ifState = Layer::IfState::dormantIf; - parseIf = false; - break; - } - } - - // Mark the layer as interdicted until we know it isn't - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionActive; - auto tokens = TokenizeLine(buf, "\\s*(\\w+)\\s*(==)?\\s*(\\w+)?\\s*$"); - if (parseIf) - { - EvaluateIf(tokens); - } -} - -void PoundPoundContext::Impl::ProcessElif(char** buf) -{ - AZ_Assert(m_ownedLayer != nullptr, "missing ##if state"); - switch (m_ownedLayer->m_ifState) - { - case Layer::IfState::dormantIf: - case Layer::IfState::triggeredIf: - ConsumeLine(buf); - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionActive; - break; - - case Layer::IfState::activeIf: - { - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionActive; - auto tokens = TokenizeLine(buf, "\\s*(\\w+)\\s*(==)?\\s*(\\w+)?\\s*$"); - EvaluateIf(tokens); - break; - } - - case Layer::IfState::dormantElse: - case Layer::IfState::activeElse: - case Layer::IfState::noIf: - AZ_Assert(false, "##elif not permitted here"); - break; - } -} - -void PoundPoundContext::Impl::ProcessElse(char** buf) -{ - ConsumeLine(buf); - - AZ_Assert(m_ownedLayer != nullptr, "missing ##if state"); - switch (m_ownedLayer->m_ifState) - { - case Layer::IfState::activeIf: - m_ownedLayer->m_ifState = Layer::IfState::activeElse; - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionPaused; - break; - - case Layer::IfState::dormantIf: - case Layer::IfState::triggeredIf: - m_ownedLayer->m_ifState = Layer::IfState::dormantElse; - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionActive; - break; - - case Layer::IfState::noIf: - case Layer::IfState::activeElse: - case Layer::IfState::dormantElse: - AZ_Assert(false, "##else not permitted here"); - break; - } -} - -void PoundPoundContext::Impl::ProcessEndif(char** buf) -{ - ConsumeLine(buf); - - AZ_Assert(m_ownedLayer != nullptr, "missing ##if state"); - AZ_Assert(m_ownedLayer != nullptr, "##else not permitted"); - AZ_Assert(m_ownedLayer->m_ifState != Layer::IfState::noIf, "##else not permitted"); - - auto next = m_ownedLayer->m_ownedNextLayer; - m_ownedLayer->m_ownedNextLayer = nullptr; - delete m_ownedLayer; - m_ownedLayer = next; -} - -void PoundPoundContext::Impl::ProcessDefine(char** buf) -{ - auto tokens = TokenizeLine(buf, "\\s*(\\w+)\\s+(\\w+)?\\s*$"); - auto count = tokens.size(); - AZ_Assert(count == 1 || count == 2, "malformed ##define"); - - auto finder = m_macros.find(tokens[0]); - AZ_Assert(finder == m_macros.end(), "duplicate ##define %s", tokens[0].c_str()); - - m_macros[tokens[0]] = (count == 2) ? tokens[1] : "1"; -} - -void PoundPoundContext::Impl::ProcessUndef(char** buf) -{ - auto tokens = TokenizeLine(buf, "\\s*(\\w+)\\s*$"); - AZ_Assert(tokens.size() == 1, "malformed ##undef"); - - auto finder = m_macros.find(tokens[0]); - if (finder != m_macros.end()) - { - m_macros.erase(finder); - } -} - -#if defined(AZ_PLATFORM_WINDOWS) -# define AZ_PATH_SEPARATOR_TOKEN "\\" -#else -# define AZ_PATH_SEPARATOR_TOKEN "/" -#endif - -void PoundPoundContext::Impl::ProcessInclude(char** buf) -{ - auto tokens = TokenizeLine(buf, "\\s*\\(\\s*(\\w+)\\s*,\\s*(\\w+)\\s*\\)\\s*$"); - - m_ownedLayer = new Layer(m_ownedLayer); - m_ownedLayer->m_interdictionState = Layer::InterdictionState::interdictionPaused; - - // Look for our root file and platform tokens - AZ_Assert(tokens.size() == 2, "Malformed ##include_restricted"); - auto platform = m_macros.find(tokens[1]); - AZ_Assert(platform != m_macros.end(), "Can't expand %s", tokens[1].c_str()); - - // Compute and open the filename - auto restrictedFile = platform->second + AZ_PATH_SEPARATOR_TOKEN + tokens[0] + "_" + platform->second + ".cfr"; - char nameFile[256]; - sprintf_s(nameFile, "%sCryFX/%s", gRenDev->m_cEF.m_ShadersPath.c_str(), restrictedFile.c_str()); - AZ::IO::HandleType includeFileHandle = gEnv->pCryPak->FOpen(nameFile, "rb"); - AZ_Assert(includeFileHandle != AZ::IO::InvalidHandle, "Couldn't open file %s", nameFile); - - // Read the file into a new buffer which we will substitute back into the stream. - gEnv->pCryPak->FSeek(includeFileHandle, 0, SEEK_END); - auto readSize = gEnv->pCryPak->FTell(includeFileHandle); - m_ownedLayer->m_ownedIncludeBuffer = new char[readSize + 1]; - m_ownedLayer->m_ownedIncludeBuffer[readSize] = 0; - gEnv->pCryPak->FSeek(includeFileHandle, 0, SEEK_SET); - gEnv->pCryPak->FRead(m_ownedLayer->m_ownedIncludeBuffer, readSize, includeFileHandle); - gEnv->pCryPak->FClose(includeFileHandle); - - // Remember the old buffer pointer, then insert our new pointer - m_ownedLayer->m_oldBuffer = *buf; - *buf = m_ownedLayer->m_ownedIncludeBuffer; - - // Prepare the file just as the calling file had been prepared - RemoveCR(m_ownedLayer->m_ownedIncludeBuffer); -} - - -PoundPoundContext::PoundPoundContext([[maybe_unused]] const AZStd::string& shadersFilter) - : m_impl(new Impl) -{ -#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - if (shadersFilter == #PrivateName) \ - { \ - m_impl->SetDefine("AZ_RESTRICTED_PLATFORM", #privatename); \ - } -#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) - AZ_EXPAND_FOR_RESTRICTED_PLATFORM -#else - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#endif -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif -} - -PoundPoundContext::~PoundPoundContext() -{ - delete m_impl; -} - -void PoundPoundContext::PreprocessLines(char** buf) -{ - m_impl->Preprocess(buf); -} - -bool PoundPoundContext::IsEndOfBuffer(char** buf, bool* layerSwitch) -{ - return m_impl->IsEndOfBuffer(buf, layerSwitch); -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.h b/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.h deleted file mode 100644 index 0ffa726283..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/PoundPoundParser.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// This is the interface object that handles the ## directive processing in the shader files. It -// pre-processes the text stream in a C-like manner, removing chunks of text from the input stream -// so that they never enter the token stream. -// -// supported directives: -// ##if - works like C #if, currently supports only the following tests: -// ##if token - enables the branch if token is defined -// ##if token1 == token2 - will first try to expand the two tokens, then will string compare the result. -// If a token isn't expanded, it will be used as the string to compare. -// ##elif - just like C #if, same caveats as ##if -// ##else - just like C #else -// ##endif - just like C #endif -// ##define - just like C define, but doesn't support parenthesis so it is just the token -// ##undef - just like C undef -// ##include_restricted(rootfile, macro) - -// This will build a filename using macro and rootfile and then process it. For example, given -// ##include_restricted(shader_cfx, AZ_RESTRICTED_PLATFORM) and AZ_RESTRICTED_PLATFORM set to "banana", -// it will open and process a file called "banana/shader_cfx_banana.cfr". - -class PoundPoundContext -{ -public: - explicit PoundPoundContext(const AZStd::string& shadersFilter); - PoundPoundContext(const PoundPoundContext& other) = delete; - void operator=(const PoundPoundContext& other) = delete; - ~PoundPoundContext(); - - // Call this function when encountering ## in the input stream. It will consume all text starting with the ## - // until it reaches a state where regular token parsing might be enabled again - void PreprocessLines(char** buf); - - // Callers need to use this function to test for the end of the buffer because we handle switching from an - // include file back to the #including file inside this function. The layerSwitch bool is needed so that the - // caller can know that they need to possibly start scanning for comments/whitespace again due to the change - // in which buffer is being scanned - bool IsEndOfBuffer(char** buf, bool* layerSwitch); - -private: - class Impl; - Impl *m_impl; -}; diff --git a/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.cpp b/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.cpp deleted file mode 100644 index f1eb11d9ce..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.cpp +++ /dev/null @@ -1,1481 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "RemoteCompiler.h" -#include "../RenderCapabilities.h" - -#include - -#include -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define REMOTECOMPILER_CPP_SECTION_1 1 -#define REMOTECOMPILER_CPP_SECTION_2 2 -#define REMOTECOMPILER_CPP_SECTION_3 3 -#define REMOTECOMPILER_CPP_SECTION_4 4 -#endif - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#undef AZ_RESTRICTED_SECTION -#define REMOTECOMPILER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) -#endif - -namespace NRemoteCompiler -{ - //Debugging the network connection problems can be tricky without verbose logging, more verbose - //than anyone would like on by default. This is a special situation in which if logging is off by default - //we would normally use a define or cvar to turn verbose logging on. However you really can't do - //that here because of networking, you can't easily break or open the console and enter the - //cvar command to turn verbose logging on fast enough to catch logs around the error condition without - //causing different code paths due to breaking. So this is an automatic verbose logging var that is off - //by default and turns on for a limited number of log lines after the error is logged then automaticly - //turns itself off so we are not spammed for to long so as to not adversely affect the rest of the systems. - int s_verboselogging = 0; - bool VerboseLogging(bool start = false) - { - if(start) - { - s_verboselogging = 100; - return true; - } - - if(s_verboselogging > 0) - { - s_verboselogging--; - return true; - } - return false; - } - - // Note: Cry's original source uses little endian as their internal communication endianness - // so this new code will do the same. - - - // RemoteProxyState: store the current state of things required to communicate to the remote server - // via the Engine Connection, so that its outside this interface and protected from the details of it. - class RemoteProxyState - { - public: - unsigned int m_remoteRequestCRC; - unsigned int m_remoteResponseCRC; - unsigned int m_nextAssignedToken; - bool m_unitTestMode; - bool m_engineConnectionCallbackInstalled; // lazy-install it. - - typedef AZStd::function TResponseCallback; - - RemoteProxyState() - { - m_engineConnectionCallbackInstalled = false; - m_unitTestMode = false; - m_remoteRequestCRC = AZ_CRC("ShaderCompilerProxyRequest"); - m_remoteResponseCRC = AZ_CRC("ShaderCompilerProxyResponse"); - m_nextAssignedToken = 0; - } - - void SetUnitTestMode(bool newMode) - { - m_unitTestMode = newMode; - } - - bool SubmitRequestAndBlockForResponse(std::vector& inout) - { - unsigned int chosenToken = m_nextAssignedToken++; - AzFramework::SocketConnection* engineConnection = AzFramework::SocketConnection::GetInstance(); - - if (!m_unitTestMode) - { - // if we're not in unit test mode, we NEED an engine connection - if (!engineConnection) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Compile: no engine connection present, but r_AssetProcessorShaderCompiler is set in config!\n"); - VerboseLogging(true); - return false; - } - - // install the callback the first time its needed: - if (!m_engineConnectionCallbackInstalled) - { - // (AddTypeCallback is assumed to be thread safe.) - - m_engineConnectionCallbackInstalled = true; - engineConnection->AddMessageHandler(m_remoteResponseCRC, std::bind(&RemoteProxyState::OnReceiveRemoteResponse, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - } - } - - // the plan: Create a wait event - // then raise the event when we get a response from the server - // then wait for the event to be raised. - - CryEvent waitEvent; - - { - CryAutoLock protector(m_mapProtector); // scoped lock on the map - - // now create an anonymous function that will copy the data and set the waitevent when the callback is triggered: - m_responsesAwaitingCallback[chosenToken] = [&inout, &waitEvent](const void* payload, unsigned int payloadSize) - { - inout.resize(payloadSize); - memcpy(inout.data(), payload, payloadSize); - waitEvent.Set(); - }; - } - - if (m_unitTestMode) - { - // if we're unit testing, there WILL BE NO ENGINE CONNECTION - // we must respond as if we're the engine connection - // you can assume the payload has already been unit tested to conform. - // instead, just write the data to the buffer as expected: - - std::vector newData; - - if (memcmp(inout.data(), "empty", 5) == 0) - { - // unit test to send empty - } - else if (memcmp(inout.data(), "incomplete", 10) == 0) - { - // unit test to send incomplete data. - newData.push_back('x'); - } - else if (memcmp(inout.data(), "corrupt", 7) == 0) - { - // unit test to send corrupt data - std::string testString("CDCDCDCDCDCDCDCD"); - newData.assign(testString.begin(), testString.end()); - } - else if ((memcmp(inout.data(), "compile_failure", 15) == 0) || (memcmp(inout.data(), "success", 7) == 0)) - { - // simulate compile failure response - // [payload length 4 bytes (LITTLE ENDIAN) ] [status 1 byte] [payload] - // and payload consists of - // [ uncompressed size (NETWORK BYTE ORDER) ] [payload (compressed)] - bool isFail = (memcmp(inout.data(), "compile_failure", 15) == 0); - std::string failreason("decompressed_plaintext"); - - size_t uncompressed_size = failreason.size(); - size_t compressed_size = uncompressed_size; - std::vector compressedData; - compressed_size = uncompressed_size * 2; - compressedData.resize(compressed_size); - - gEnv->pSystem->CompressDataBlock(failreason.data(), failreason.size(), compressedData.data(), compressed_size); - compressedData.resize(compressed_size); - - // first four bytes are payload size. - // firth byte is status - unsigned int payloadSize = 4 + compressed_size; - newData.resize(4 + 1 + payloadSize); - uint8 status_code = isFail ? 0x05 : 0x01; // 5 is fail, 1 is ok - - unsigned int uncompressed_size_le = uncompressed_size; - SwapEndian(uncompressed_size_le); - - memcpy(newData.data(), &payloadSize, 4); - memcpy(newData.data() + 4, &status_code, 0x01); // 0x05 = error compiling - - memcpy(newData.data() + 4 + 1, &uncompressed_size_le, 4); - memcpy(newData.data() + 4 + 1 + 4, compressedData.data(), compressedData.size()); - } - else - { - newData.clear(); - } - - // place the messageID at the end: - newData.resize(newData.size() + 4); // for the messageID - unsigned int swappedToken = chosenToken; - SwapEndian(swappedToken); - memcpy(newData.data() + newData.size() - 4, &swappedToken, 4); - - OnReceiveRemoteResponse(m_remoteResponseCRC, AzFramework::AssetSystem::DEFAULT_SERIAL, newData.data(), newData.size()); - } - else // note: This else is inside the endif so that it only takes the second branch if UNIT TEST MODE is present. - { - // append the messageID: - inout.resize(inout.size() + 4); // for the messageID - unsigned int swappedToken = chosenToken; - SwapEndian(swappedToken); - memcpy(inout.data() + inout.size() - 4, &swappedToken, 4); - - if (!engineConnection->SendMsg(m_remoteRequestCRC, inout.data(), inout.size())) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::SubmitRequestAndBlockForResponse() : unable to send via engine connection, but r_AssetProcessorShaderCompiler is set in config!\n"); - VerboseLogging(true); - return false; - } - } - - if (!waitEvent.Wait(10000)) - { - // failure to get response! - AZ_Error("RemoteCompiler", false, "CShaderSrv::SubmitRequestAndBlockForResponse() : no response received!\n"); - VerboseLogging(true); - CryAutoLock protector(m_mapProtector); - m_responsesAwaitingCallback.erase(chosenToken); - - if(!gEnv->IsInToolMode()) - { - EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Remote Shader Compiler", "Unable to connect to Remote Shader Compiler", false); - } - return false; - } - - // wait succeeded! We got a response! Unblock and return! - return true; - } - - private: - - CryMutex m_mapProtector; - std::unordered_map m_responsesAwaitingCallback; - - void OnReceiveRemoteResponse([[maybe_unused]] unsigned int messageID, unsigned int /*serial*/, const void* payload, unsigned int payloadSize) - { - // peel back to inner payload: - if (payloadSize < 4) - { - // indicate error! - AZ_Error("RemoteCompiler", false, " CShaderSrv::OnReceiveRemoteREsponse() : truncated message from shader compiler proxy"); - VerboseLogging(true); - return; - } - - // last four bytes are expected to be the response ID - const uint8* payload_start = reinterpret_cast(payload); - const uint8* end_payload = payload_start + payloadSize; - const uint8* messageIDPtr = end_payload - 4; - - unsigned int responseId = *reinterpret_cast(messageIDPtr); - SwapEndian(responseId); - - CryAutoLock protector(m_mapProtector); - auto callbackToCall = m_responsesAwaitingCallback.find(responseId); - if (callbackToCall == m_responsesAwaitingCallback.end()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::OnReceiveRemoteResponse() : Unexpected response from shader compiler proxy."); - VerboseLogging(true); - return; - } - // give only the inner payload back to the callee! - - callbackToCall->second(payload_start, payloadSize - sizeof(unsigned int)); - m_responsesAwaitingCallback.erase(callbackToCall); - } - }; - CShaderSrv::CShaderSrv() - { - m_unitTestMode = false; - Init(); - } - - void CShaderSrv::Init() - { - static RemoteProxyState proxyState; - m_remoteState = &proxyState; - - int result = AZ::AzSock::Startup(); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Init() : Could not init root socket\n"); - VerboseLogging(true); - return; - } - - m_RequestLineRootFolder = ""; - - AZ::IO::FixedMaxPathString projectUserPath; - if (auto settingsRegistry{ AZ::SettingsRegistry::Get() }; settingsRegistry != nullptr) - { - settingsRegistry->Get(projectUserPath, AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath); - } - - if (!projectUserPath.empty()) - { - m_RequestLineRootFolder.assign(projectUserPath.c_str(), projectUserPath.size()); - } - - if (m_RequestLineRootFolder.empty()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Init() : Game folder has not been specified\n"); - VerboseLogging(true); - } - } - - CShaderSrv& CShaderSrv::Instance() - { - static CShaderSrv g_ShaderSrv; - return g_ShaderSrv; - } - - EShaderCompiler CShaderSrv::GetShaderCompiler() const - { - EShaderCompiler shaderCompiler = eSC_Unknown; - - EShaderLanguage shaderLanguage = GetShaderLanguage(); - switch (shaderLanguage) - { - case eSL_Orbis: - shaderCompiler = eSC_Orbis_DXC; - break; - - case eSL_Jasper: - shaderCompiler = eSC_Jasper_FXC; - break; - - case eSL_D3D11: - shaderCompiler = eSC_D3D11_FXC; - break; - - case eSL_GL4_1: - case eSL_GL4_4: - case eSL_GLES3_0: - case eSL_GLES3_1: - shaderCompiler = gRenDev->m_cEF.HasStaticFlag(HWSST_LLVM_DIRECTX_SHADER_COMPILER) ? eSC_GLSL_LLVM_DXC : eSC_GLSL_HLSLcc; - break; - - case eSL_METAL: - shaderCompiler = gRenDev->m_cEF.HasStaticFlag(HWSST_LLVM_DIRECTX_SHADER_COMPILER) ? eSC_METAL_LLVM_DXC : eSC_METAL_HLSLcc; - break; - } - - return shaderCompiler; - } - - const char *CShaderSrv::GetShaderCompilerName() const - { - // NOTE: These strings are used in the CrySCompilerServer tool as IDs. - static const char *shaderCompilerNames[eSC_MAX] = - { - "Unknown", - "Orbis_DXC", - "D3D11_FXC", - "GLSL_HLSLcc", - "METAL_HLSLcc", - "GLSL_LLVM_DXC", - "METAL_LLVM_DXC", - "Jasper_FXC" - }; - - EShaderCompiler shaderCompiler = GetShaderCompiler(); - return shaderCompilerNames[shaderCompiler]; - } - - const char* CShaderSrv::GetPlatformName() const - { - const char *platformName = "Unknown"; - - switch (CParserBin::m_targetPlatform) - { - case AZ::PlatformID::PLATFORM_WINDOWS_64: - platformName = "PC"; - break; - case AZ::PlatformID::PLATFORM_ANDROID_64: - platformName = "Android"; - break; - case AZ::PlatformID::PLATFORM_APPLE_OSX: - platformName = "Mac"; - break; - case AZ::PlatformID::PLATFORM_APPLE_IOS: - platformName = "iOS"; - break; - case AZ::PlatformID::PLATFORM_LINUX_64: - platformName = "Linux"; - break; -#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - case AZ::PlatformID::PLATFORM_##PUBLICNAME: \ - platformName = #PrivateName;\ - break; -#if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) - AZ_EXPAND_FOR_RESTRICTED_PLATFORM -#else - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#endif -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif - default: - AZ_Assert(false, "Unknown shader platform"); - break; - } - - return platformName; - } - - AZStd::string CShaderSrv::GetShaderCompilerFlags([[maybe_unused]] EHWShaderClass eClass, [[maybe_unused]] UPipelineState pipelineState, [[maybe_unused]] uint32 MDVMask) const - { - AZStd::string flags = ""; - - EShaderCompiler shaderCompiler = GetShaderCompiler(); - switch (shaderCompiler) - { - // ---------------------------------------- - case eSC_Orbis_DXC: - { - flags = "%s %s \"%s\" \"%s\""; - - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) - #endif - - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) - #endif - - #if defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE_EXPLICIT(Shaders/RemoteCompiler_cpp, provo) - #endif - #if defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE_EXPLICIT(Shaders/RemoteCompiler_cpp, jasper) - #endif - #if defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE_EXPLICIT(Shaders/RemoteCompiler_cpp, salem) - #endif - } - break; - - // ---------------------------------------- - case eSC_Jasper_FXC: - case eSC_D3D11_FXC: - { - const char* extraFlags = ""; - - const char* debugFlags = ""; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 3) - { - debugFlags = " /Zi /Od"; // Debug information - } - else if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 4) - { - debugFlags = " /Zi /O3"; // Debug information, optimized shaders - } - - flags = AZStd::move(AZStd::string::format("/nologo /E %%s /T %%s /Zpr /Gec %s %s /Fo \"%%s\" \"%%s\"", extraFlags, debugFlags)); - } - break; - - // ---------------------------------------- - case eSC_GLSL_HLSLcc: - { - // Translate flags for HLSLCrossCompiler compiler. All flags come from 'Code\Tools\HLSLCrossCompiler\include\hlslcc.h' - unsigned int translateFlags = - 0x1 | // Each constant buffer will have its own uniform block - 0x100 | // Invert clip space position Y - 0x200 | // Convert clip sapce position Z - 0x400 | // Avoid resource bindings and locations - 0x800 | // Do not use an array for temporary registers - 0x8000 | // Do not add GLSL version macro - 0x10000; // Avoid shader image load store extension - - EShaderLanguage shaderLanguage = GetShaderLanguage(); - switch (shaderLanguage) - { - case eSL_GL4_1: - case eSL_GL4_4: - { - const char* glVer = (shaderLanguage == eSL_GL4_1) ? "410" : "440"; - flags = AZStd::move(AZStd::string::format("-lang=%s -flags=%u -fxc=\"%%s /nologo /E %%s /T %%s /Zpr /Gec /Fo\" -out=\"%%s\" -in=\"%%s\"", glVer, translateFlags)); - } - break; - - case eSL_GLES3_0: - { - translateFlags |= - 0x20000 | // Syntactic workarounds for driver bugs found in Qualcomm devices running OpenGL ES 3.0 - 0x40000; // Add half support - - flags = AZStd::move(AZStd::string::format("-lang=es300 -flags=%u -fxc=\"%%s /nologo /E %%s /T %%s /Zpr /Gec /Fo\" -out=\"%%s\" -in=\"%%s\"", translateFlags)); - } - break; - - case eSL_GLES3_1: - { - translateFlags |= - 0x40000; // Add half support - - flags = AZStd::move(AZStd::string::format("-lang=es310 -flags=%u -fxc=\"%%s /nologo /E %%s /T %%s /Zpr /Gec /Fo\" -out=\"%%s\" -in=\"%%s\"", translateFlags)); - } - break; - - default: - AZ_Assert(false, "Non-GLSL shader language used with the GLSL HLSLcc compiler."); - break; - } - } - break; - - // ---------------------------------------- - case eSC_METAL_HLSLcc: - { - // Translate flags for HLSLCrossCompilerMETAL compiler. All flags come from 'Code\Tools\HLSLCrossCompilerMETAL\include\hlslcc.h' - unsigned int translateFlags = - //0x40000 |// Add half support - 0x1 | // Each constant buffer will have its own uniform block - 0x100 | // Declare inputs and outputs with their semantic name appended - 0x200 | // Combine texture/sampler pairs used together into samplers named "texturename_X_samplernamC" - 0x400 | // Attribute and uniform explicit location qualifiers are disabled (even if the language version supports that) - 0x800; // Global uniforms are not stored in a struct - - flags = AZStd::move(AZStd::string::format("-lang=metal -flags=%u -fxc=\"%%s /nologo /E %%s /T %%s /Zpr /Gec /Fo\" -out=\"%%s\" -in=\"%%s\"", translateFlags)); - } - break; - - // ---------------------------------------- - case eSC_GLSL_LLVM_DXC: - { - // Translate flags for DirectXShaderCompiler GLSL compiler. All flags come from 'DirectXShaderCompiler\src\tools\clang\tools\dxcGL\HLSLCrossCompiler\include\hlslcc.h' - unsigned int translateFlags = - 0x1 | // Each constant buffer will have its own uniform block - 0x100 | // Invert clip space position Y - 0x200 | // Convert clip sapce position Z - 0x400 | // Avoid resource bindings and locations - 0x800 | // Do not use an array for temporary registers - 0x8000 | // Do not add GLSL version macro - 0x10000| // Avoid shader image load store extension - 0x20000; // Declare dynamically indexed constant buffers as an array of floats - - EShaderLanguage shaderLanguage = GetShaderLanguage(); - switch (shaderLanguage) - { - case eSL_GL4_1: - case eSL_GL4_4: - { - const char* glVer = (shaderLanguage == eSL_GL4_1) ? "410" : "440"; - flags = AZStd::move(AZStd::string::format("-translate_flags %u -translate %s -E %%s -T %%s -Zpr -not_use_legacy_cbuf_load -Gfa -Fo \"%%s\" \"%%s\"", translateFlags, glVer)); - } - break; - - case eSL_GLES3_0: - case eSL_GLES3_1: - { - const char* glesVer = (shaderLanguage == eSL_GLES3_0) ? "es300" : "es310"; - flags = AZStd::move(AZStd::string::format("-translate_flags %u -translate %s -E %%s -T %%s -Zpr -not_use_legacy_cbuf_load -Gfa -Fo \"%%s\" \"%%s\"", translateFlags, glesVer)); - } - break; - - default: - AZ_Assert(false, "Non-GLSL shader language used with the LLVM DXC compiler."); - break; - } - } - break; - - // ---------------------------------------- - case eSC_METAL_LLVM_DXC: - { - // Translate flags for DirectXShaderCompiler Metal compiler. All flags come from 'DirectXShaderCompiler\src\tools\clang\tools\dxcMetal\HLSLCrossCompilerMETAL\include\hlslcc.h' - unsigned int translateFlags = - 0x1 | // Each constant buffer will have its own uniform block - 0x100 | // Declare inputs and outputs with their semantic name appended - 0x200 | // Combine texture/sampler pairs used together into samplers named "texturename_X_samplername" - 0x400 | // Attribute and uniform explicit location qualifiers are disabled (even if the language version supports that) - 0x800 | // Global uniforms are not stored in a struct - 0x2000; // Do not use an array for temporary registers - - #if defined(AZ_PLATFORM_MAC) - translateFlags |= 0x1000; // Declare dynamically indexed constant buffers as an array of floats - #endif - - flags = AZStd::move(AZStd::string::format("-translate_flags %u -translate metal -E %%s -T %%s -Zpr -not_use_legacy_cbuf_load -Gfa -Fo \"%%s\" \"%%s\"", translateFlags)); - } - break; - - // ---------------------------------------- - case eSC_Unknown: - default: - AZ_Assert(false, "Unknown shader compiler"); - break; - } - - return flags; - } - - string CShaderSrv::CreateXMLNode(const string& rTag, const string& rValue) const - { - string Tag = rTag; - Tag += "=\""; - Tag += rValue; - Tag += "\" "; - return Tag; - } - - string CShaderSrv::TransformToXML(const string& rIn) const - { - string Out; - for (size_t a = 0, Size = rIn.size(); a < Size; a++) - { - const char C = rIn.c_str()[a]; - if (C == '&') - { - Out += "&"; - } - else - if (C == '<') - { - Out += "<"; - } - else - if (C == '>') - { - Out += ">"; - } - else - if (C == '\"') - { - Out += """; - } - else - if (C == '\'') - { - Out += "'"; - } - else - { - Out += C; - } - } - return Out; - } - - bool CShaderSrv::CreateRequest(std::vector& rVec, - std::vector >& rNodes) const - { - string Request = "(Request.c_str(), &Request.c_str()[Request.size() + 1]); - return true; - } - - bool CShaderSrv::RequestLine(const SCacheCombination& cmb, const string& rLine) const - { - const string List(string(GetShaderLanguageName()) + "/" + cmb.Name.c_str() + "ShaderList.txt"); - return RequestLine(List, rLine); - } - - bool CShaderSrv::CommitPLCombinations(std::vector& rVec) - { - const uint32 STEPSIZE = 32; -#if defined(AZ_ENABLE_TRACING) - float T0 = iTimer->GetAsyncCurTime(); -#endif - for (uint32 i = 0; i < rVec.size(); i += STEPSIZE) - { - string Line; - string levelRequest; - - levelRequest.Format("<%d>%s", rVec[i].nCount, rVec[i].CacheName.c_str()); - Line = levelRequest; - for (uint32 j = 1; j < STEPSIZE && i + j < rVec.size(); j++) - { - Line += string(";"); - levelRequest.Format("<%d>%s", rVec[i + j].nCount, rVec[i + j].CacheName.c_str()); - Line += levelRequest; - } - if (!RequestLine(rVec[i], Line)) - { - return false; - } - } -#if defined(AZ_ENABLE_TRACING) - float T1 = iTimer->GetAsyncCurTime(); -#endif - if(VerboseLogging()) - { - AZ_TracePrintf("RemoteCompiler", "CShaderSrv::CommitPLCombinations() : %3.3f to commit %" PRISIZE_T " Combinations\n", T1 - T0, rVec.size()); - } - - return true; - } - - EServerError CShaderSrv::Compile(std::vector& rVec, - const char* pProfile, - const char* pProgram, - const char* pEntry, - const char* pCompileFlags, - const char* pIdent) const - { - std::vector CompileData; - std::vector > Nodes; - - Nodes.push_back(std::pair(string("JobType"), string("Compile"))); - Nodes.push_back(std::pair(string("Profile"), string(pProfile))); - Nodes.push_back(std::pair(string("Program"), string(pProgram))); - Nodes.push_back(std::pair(string("Entry"), string(pEntry))); - Nodes.push_back(std::pair(string("CompileFlags"), string(pCompileFlags))); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) -#endif - - // Any fields coming after "HashStop" will not contribute to the hash calculated on the Remote Shader Compiler Server for its local cache. - Nodes.push_back(std::pair(string("HashStop"), string("1"))); - Nodes.push_back(std::pair(string("ShaderRequest"), string(pIdent))); - Nodes.push_back(std::pair(string("Project"), string(m_RequestLineRootFolder.c_str()))); - Nodes.push_back(std::pair(string("Platform"), string(GetPlatformName()))); - Nodes.push_back(std::pair(string("Compiler"), string(GetShaderCompilerName()))); - Nodes.push_back(std::pair(string("Language"), string(GetShaderLanguageName()))); - - if (gRenDev->CV_r_ShaderEmailTags && gRenDev->CV_r_ShaderEmailTags->GetString() && - strlen(gRenDev->CV_r_ShaderEmailTags->GetString()) > 0) - { - Nodes.push_back(std::pair(string("Tags"), string(gRenDev->CV_r_ShaderEmailTags->GetString()))); - } - - if (gRenDev->CV_r_ShaderEmailCCs && gRenDev->CV_r_ShaderEmailCCs->GetString() && - strlen(gRenDev->CV_r_ShaderEmailCCs->GetString()) > 0) - { - Nodes.push_back(std::pair(string("EmailCCs"), string(gRenDev->CV_r_ShaderEmailCCs->GetString()))); - } - - if (gRenDev->CV_r_ShaderCompilerDontCache) - { - Nodes.push_back(std::pair(string("Caching"), string("0"))); - } - - //Nodes.push_back(std::pair(string("ShaderRequest",string(pShaderRequestLine))); - - EServerError errCompile = ESOK; - int nRetries = 3; - do - { - if (errCompile != ESOK) - { - Sleep(5000); - } - - if (!CreateRequest(CompileData, Nodes)) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Compile() : failed composing Request XML\n"); - VerboseLogging(true); - return ESFailed; - } - - errCompile = Send(CompileData); - } while (errCompile == ESRecvFailed && nRetries-- > 0); - - rVec = CompileData; - - if (errCompile != ESOK) - { - bool logError = true; - const char* why = ""; - switch (errCompile) - { - case ESNetworkError: - why = "Network Error"; - break; - case ESSendFailed: - why = "Send Failed"; - break; - case ESRecvFailed: - why = "Receive Failed"; - break; - case ESInvalidState: - why = "Invalid Return State (compile issue ?!?)"; - break; - case ESCompileError: - logError = false; - why = ""; - break; - case ESFailed: - why = ""; - break; - } - if (logError) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Compile() : failed to compile %s (%s)", pEntry, why); - VerboseLogging(true); - } - } - return errCompile; - } - - EServerError CShaderSrv::GetShaderList(std::vector& rVec) const - { - std::vector GetShaderListData; - std::vector > Nodes; - - Nodes.push_back(std::pair(string("JobType"), string("GetShaderList"))); - Nodes.push_back(std::pair(string("Project"), string(m_RequestLineRootFolder.c_str()))); - Nodes.push_back(std::pair(string("Platform"), string(GetPlatformName()))); - Nodes.push_back(std::pair(string("Compiler"), string(GetShaderCompilerName()))); - Nodes.push_back(std::pair(string("Language"), string(GetShaderLanguageName()))); - Nodes.push_back(std::pair(string("ShaderList"), string(GetShaderListFilename().c_str()))); - - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) - #endif - - EServerError errShaderGetList = ESOK; - int nRetries = 3; - do - { - if (errShaderGetList != ESOK) - { - Sleep(5000); - } - - if (!CreateRequest(GetShaderListData, Nodes)) - { - AZ_Error("RemoteCompler", false, "ERROR: CShaderSrv::GetShaderList(): failed composing Request XML\n"); - VerboseLogging(true); - return ESFailed; - } - - errShaderGetList = Send(GetShaderListData); - } while (errShaderGetList == ESRecvFailed && nRetries-- > 0); - - rVec = GetShaderListData; - - if (errShaderGetList != ESOK) - { - bool logError = true; - const char* why = ""; - switch (errShaderGetList) - { - case ESNetworkError: - why = "Network Error"; - break; - case ESSendFailed: - why = "Send Failed"; - break; - case ESRecvFailed: - why = "Receive Failed"; - break; - case ESInvalidState: - why = "Invalid Return State (compile issue ?!?)"; - break; - case ESFailed: - why = ""; - break; - } - if (logError) - { - AZ_Error("RemoteCompiler", false, "ERROR: CShaderSrv::GetShaderList(): failed to get shader list (%s)", why); - VerboseLogging(true); - } - } - return errShaderGetList; - } - - bool CShaderSrv::RequestLine(const string& rList, const string& rString) const - { - if (!gRenDev->CV_r_shaderssubmitrequestline) - { - return true; - } - - std::vector CompileData; - std::vector > Nodes; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION REMOTECOMPILER_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(RemoteCompiler_cpp) -#endif - - Nodes.push_back(std::pair(string("JobType"), string("RequestLine"))); - Nodes.push_back(std::pair(string("ShaderRequest"), rString)); - Nodes.push_back(std::pair(string("Project"), m_RequestLineRootFolder)); - Nodes.push_back(std::pair(string("Platform"), string(GetPlatformName()))); - Nodes.push_back(std::pair(string("Compiler"), string(GetShaderCompilerName()))); - Nodes.push_back(std::pair(string("Language"), string(GetShaderLanguageName()))); - Nodes.push_back(std::pair(string("ShaderList"), rList)); - - if (!CreateRequest(CompileData, Nodes)) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::RequestLine() : failed composing Request XML\n"); - VerboseLogging(true); - return false; - } - - return (Send(CompileData) == ESOK); - } - - bool CShaderSrv::Send(AZSOCKET Socket, const char* pBuffer, uint32 Size) const - { - //size_t w; - size_t wTotal = 0; - while (wTotal < Size) - { - int result = AZ::AzSock::Send(Socket, pBuffer + wTotal, Size - wTotal, 0); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Send() : failed (%s)\n", AZ::AzSock::GetStringForError(result)); - VerboseLogging(true); - return false; - } - wTotal += (size_t)result; - } - return true; - } - - bool CShaderSrv::Send(AZSOCKET Socket, std::vector& rCompileData) const - { - const uint64 Size = static_cast(rCompileData.size()); - if(Size == 0) - { - return Send(Socket, (const char*) &Size, sizeof(Size));//send 0... if Size is 0 then (const char*)&rCompileData[0] cannot be accessed. - } - - return Send(Socket, (const char*)&Size, sizeof(Size)) && - Send(Socket, (const char*)&rCompileData[0], static_cast(Size)); - } - -#define MAX_TIME_TO_WAIT 100000 - - EServerError CShaderSrv::Recv(AZSOCKET Socket, std::vector& rCompileData) const - { - const size_t Offset = 5;//version 2 has 4byte size and 1 byte state - // const uint32 Size = static_cast(rCompileData.size()); - // return Send(Socket,(const char*)&Size,4) || - // Send(Socket,(const char*)&rCompileData[0],Size); - - - // delete[] optionsBuffer; - uint32 nMsgLength = 0; - uint32 nTotalRecived = 0; - const size_t BLOCKSIZE = 4 * 1024; - const size_t SIZELIMIT = 1024 * 1024; - rCompileData.resize(0); - rCompileData.reserve(64 * 1024); - int CurrentPos = 0; - while (rCompileData.size() < SIZELIMIT) - { - rCompileData.resize(CurrentPos + BLOCKSIZE); - - int Recived = SOCKET_ERROR; - int waitingtime = 0; - while (Recived < 0) - { - Recived = AZ::AzSock::Recv(Socket, reinterpret_cast(&rCompileData[CurrentPos]), BLOCKSIZE, 0); - if (AZ::AzSock::SocketErrorOccured(Recived)) - { - AZ::AzSock::AzSockError error = AZ::AzSock::AzSockError(Recived); - if (error == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK) - { - // are we out of time - if (waitingtime > MAX_TIME_TO_WAIT) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Recv() : Out of time during waiting %d seconds on block, sys_net_errno=%s\n", MAX_TIME_TO_WAIT, AZ::AzSock::GetStringForError(Recived)); - VerboseLogging(true); - return ESRecvFailed; - } - - waitingtime += 5; - - // sleep a bit and try again - Sleep(5); - } - else - { - // count on retry to fix this after a small sleep - AZ_Error("RemoteCompiler", false, "CShaderSrv::Recv() : at offset %lu: sys_net_errno=%s\n", (unsigned long)rCompileData.size(), AZ::AzSock::GetStringForError(Recived)); - VerboseLogging(true); - return ESRecvFailed; - } - } - } - - if (Recived >= 0) - { - nTotalRecived += Recived; - } - - if (nTotalRecived >= 4) - { - nMsgLength = *(uint32*)&rCompileData[0] + Offset; - } - - if (Recived == 0 || nTotalRecived == nMsgLength) - { - rCompileData.resize(nTotalRecived); - break; - } - CurrentPos += Recived; - } - - return ProcessResponse(rCompileData); - } - - // given a data vector, check to see if its an error or a success situation. - // if its an error, replace the buffer with the uncompressed error string if possible. - EServerError CShaderSrv::ProcessResponse(std::vector& rCompileData) const - { - // so internally the message is like this - // [payload length 4 bytes] [status 1 byte] [payload] - // note that the length of the payload is given, not the total length of the message - // which is actually payload length + [4 bytes + 1 byte status] - - const size_t OffsetToPayload = sizeof(unsigned int) + sizeof(uint8); // probably 5 bytes - - if (rCompileData.size() < OffsetToPayload) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::ProcessResponse() : data incomplete from server (only %i bytes received)\n", static_cast(rCompileData.size())); - VerboseLogging(true); - rCompileData.clear(); - return ESRecvFailed; - } - - uint32 payloadSize = *(uint32*)&rCompileData[0]; - uint8 state = rCompileData[4]; - - if (payloadSize + OffsetToPayload != rCompileData.size()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::ProcessResponse() : data incomplete from server - expected %i bytes, got %i bytes\n", static_cast(payloadSize + OffsetToPayload), static_cast(rCompileData.size())); - VerboseLogging(true); - rCompileData.clear(); - return ESRecvFailed; - } - - if (rCompileData.size() > OffsetToPayload) // ie, not a zero-byte payload - { - // move the payload to the beginning of the array, so that the first byte is the first byte of the payload - memmove(&rCompileData[0], &rCompileData[OffsetToPayload], rCompileData.size() - OffsetToPayload); - rCompileData.resize(rCompileData.size() - OffsetToPayload); - } - else - { - rCompileData.clear(); - } - - // decompress datablock if available. - if (rCompileData.size() > sizeof(unsigned int)) // theres a datablock, which is compressed and there's enough data in there for a header of 4 bytes and payload - { - // [4 bytes - size of uncompressed message in network order][compressed payload message] - // Decompress incoming payload - std::vector rCompressedData; - rCompressedData.swap(rCompileData); - - uint32 nSrcUncompressedLen = *(uint32*)&rCompressedData[0]; - SwapEndian(nSrcUncompressedLen); - - size_t nUncompressedLen = (size_t)nSrcUncompressedLen; - - // Maximum size allowed for a shader in bytes - static const size_t maxShaderSize = 10ull * (1024ull * 1024ull); // 10 MB - - if (nUncompressedLen > maxShaderSize) - { - // Shader too big, something is wrong. - rCompileData.clear(); // don't propogate "something is wrong" data - return ESFailed; - } - - rCompileData.resize(nUncompressedLen); - if (nUncompressedLen > 0) - { - if (!gEnv->pSystem->DecompressDataBlock(&rCompressedData[4], rCompressedData.size() - 4, &rCompileData[0], nUncompressedLen)) - { - rCompileData.clear(); // don't propogate corrupted data - return ESFailed; - } - } - } - - if (state != 1) //1==ECSJS_DONE state on server, dont change! - { - // getting here means SOME sort of error occurred. - // don't print compile errors here, they'll be handled later - if (state == 5) //5==ECSJS_COMPILE_ERROR state on server, dont change! - { - return ESCompileError; - } - - AZ_Error("RemoteCompiler", false, "CShaderSrv::ProcessResponse() : data contains invalid return status: state = %d \n", state); - VerboseLogging(true); - - return ESInvalidState; - } - return ESOK; - } - - void CShaderSrv::Tokenize(tdEntryVec& rRet, const string& Tokens, const string& Separator) const - { - rRet.clear(); - string::size_type Pt; - string::size_type Start = 0; - string::size_type SSize = Separator.size(); - - while ((Pt = Tokens.find(Separator, Start)) != string::npos) - { - string SubStr = Tokens.substr(Start, Pt - Start); - rRet.push_back(SubStr); - Start = Pt + SSize; - } - - rRet.push_back(Tokens.substr(Start)); - } - - EServerError CShaderSrv::Send(std::vector& rCompileData) const - { - if (rCompileData.size() > std::numeric_limits::max()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::Send() : compile data too big to send.\n"); - VerboseLogging(true); - return ESFailed; - } - - // this function expects to block until a response is received or failure occurs. - AzFramework::SocketConnection* engineConnection = AzFramework::SocketConnection::GetInstance(); - bool useAssetProcessor = ((CRenderer::CV_r_AssetProcessorShaderCompiler != 0) && (engineConnection) && (engineConnection->IsConnected())); - - if (m_unitTestMode) - { - useAssetProcessor = true; // always test asset processor-based code - } - - if (useAssetProcessor) - { - EServerError resultFromConnection = SendRequestViaEngineConnection(rCompileData); - if (resultFromConnection != ESOK) - { - return resultFromConnection; - } - } - else - { - EServerError resultFromSocket = SendRequestViaSocket(rCompileData); - - if (resultFromSocket != ESOK) - { - return resultFromSocket; - } - } - - if (rCompileData.size() < 4) - { - return ESFailed; - } - - return ESOK; - } - - EServerError CShaderSrv::SendRequestViaSocket(std::vector& rCompileData) const - { - AZSOCKET Socket = AZ_SOCKET_INVALID; - int Err = SOCKET_ERROR; - - // generate the list of servers to make the request to: - tdEntryVec ServerVec; - if (gEnv->pConsole->GetCVar("r_ShaderCompilerServer")) - { - Tokenize(ServerVec, gEnv->pConsole->GetCVar("r_ShaderCompilerServer")->GetString(), ","); - } - - if (ServerVec.empty()) - { - ServerVec.push_back("localhost"); - } - - if(VerboseLogging()) - { - AZ_TracePrintf("RemoteCompler", "INFO: CShaderSrv::SendRequestViaSocket(): connect to remote shader compiler server: %s...\n", gRenDev->CV_r_ShaderCompilerServer->GetString()); - } - - //connect - //try each entry in the list from front to back - bool didconnect = false; - bool sent = false; - bool received = false; - for (uint32 nServer = 0; nServer < ServerVec.size(); nServer++) - { - string Server = ServerVec[nServer]; - - //try 3 times each in turn - for (uint32 nRetries = 0; nRetries < 3; nRetries++) - { - if(nRetries) - { - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): retry % i to connect to: %s...\n", nRetries, Server.c_str()); - VerboseLogging(true); - } - else - { - if(VerboseLogging()) - { - AZ_TracePrintf("RemoteCompler", "INFO: CShaderSrv::SendRequestViaSocket(): connect to: %s...\n", Server.c_str()); - } - } - - //create the socket - Socket = AZ::AzSock::Socket(); - - //if anything went wrong creating the socket, this was not a valid try, so try again - if (!AZ::AzSock::IsAzSocketValid(Socket)) - { - if (nRetries) - { - nRetries--; - } - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): can't create client socket: error %s\n", AZ::AzSock::GetStringForError(Socket)); - VerboseLogging(true); - } - else - { - //we have a socket, try to connect - AZ::AzSock::SetSocketOption(Socket, AZ::AzSock::AzSocketOption::REUSEADDR, true); - AZ::AzSock::AzSocketAddress socketAddress; - socketAddress.SetAddress(Server.c_str(), gRenDev->CV_r_ShaderCompilerPort); - - Err = AZ::AzSock::Connect(Socket, socketAddress); - if (AZ::AzSock::SocketErrorOccured(Err)) - { - //connect failed, see if it failed because we don't have enough buffer, if so its not a legit fail of this server, retry - - // if buffer is full try sleeping a bit before retrying - // (if you keep getting this issue then try using same shutdown mechanism as server is doing (see server code)) - // (for more info on windows side check : http://www.proxyplus.cz/faq/articles/EN/art10002.htm) - if (Err == static_cast(AZ::AzSock::AzSockError::eASE_ENOBUFS)) - { - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): ENOBUFS: the buffer is full, try again in 5 seconds. %s (sys_net_errno=%s, retrying %d)\n", Server.c_str(), AZ::AzSock::GetStringForError(Err), nRetries); - VerboseLogging(true); - if (nRetries) - { - nRetries--; - } - //wait 5 seconds before retry - Sleep(5000); - } - else - { - //legit fail to connect, retry - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): could not connect to %s (sys_net_errno=%s, retrying %d)\n", Server.c_str(), AZ::AzSock::GetStringForError(Err), nRetries); - VerboseLogging(true); - - //wait 1 second before retry - Sleep(1000); - } - - //close the socket for a retry - AZ::AzSock::CloseSocket(Socket); - Socket = AZ_SOCKET_INVALID; - } - else - { - if(VerboseLogging()) - { - AZ_TracePrintf("RemoteCompiler", "INFO: CShaderSrv::SendRequestViaSocket(): connected to: %s...\n", Server.c_str()); - } - - didconnect = true; - //we connected, send - if (!Send(Socket, rCompileData)) - { - //send failed - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): failed to send: sys_net_errno=%s\n", AZ::AzSock::GetStringForError(Err)); - VerboseLogging(true); - - //wait 1 second before retry - Sleep(1000); - - AZ::AzSock::CloseSocket(Socket); - Socket = AZ_SOCKET_INVALID; - } - else - { - sent = true; - //send succeeded, wait for recv - EServerError Error = Recv(Socket, rCompileData); - if (Error != ESOK) - { - //recv failed - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): failed to recv: EServerError=%i\n", Error); - VerboseLogging(true); - - //wait 1 second before retry - Sleep(1000); - - AZ::AzSock::CloseSocket(Socket); - Socket = AZ_SOCKET_INVALID; - } - else - { - received = true; - //we are done, it succeeded - //shutdown the client side of the socket because we are done listening - if(VerboseLogging()) - { - AZ_TracePrintf("RemoteCompler", "INFO: CShaderSrv::SendRequestViaSocket(): shader request succeeded.\n"); - } - - Err = AZ::AzSock::Shutdown(Socket, SD_BOTH); - if (Err == SOCKET_ERROR) - { - AZ_Warning("RemoteCompiler", false, "WARN: CShaderSrv::SendRequestViaSocket(): succeeded but and got error shutting down socket: sys_net_errno=%s\n", AZ::AzSock::GetStringForError(Err)); - VerboseLogging(true); - } - else - { - //put this in the else because OSX can have a problem calling closesocket on a failed shutdown of a socket - AZ::AzSock::CloseSocket(Socket); - } - Socket = AZ_SOCKET_INVALID; - return ESOK; - } - } - } - } - } - } - - //we failed - AZ::AzSock::CloseSocket(Socket); - Socket = AZ_SOCKET_INVALID; - rCompileData.resize(0); - - if (didconnect) - { - const AZStd::string title = "Remote Shader Compiler"; - const AZStd::string message = AZStd::string::format("We connected to the server but failed to compile the shader!"); - AZ_Error("RemoteCompiler", false, "ERROR: CShaderSrv::SendRequestViaSocket(): %s\n", message.c_str()); - VerboseLogging(true); - if(!gEnv->IsInToolMode()) - { - EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, title, message, false); - } - } - else - { - const AZStd::string title = "Remote Shader Compiler"; - const AZStd::string message = AZStd::string::format("Unable to connect to Remote Shader Compiler at %s", gRenDev->CV_r_ShaderCompilerServer->GetString()); - AZ_Error("RemoteCompiler", false, "ERROR: CShaderSrv::SendRequestViaSocket(): %s\n", message.c_str()); - VerboseLogging(true); - if(!gEnv->IsInToolMode()) - { - AZStd::vector options; - options.push_back("OK"); - EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayBlockingDialog, title, message, options); - } - } - return ESNetworkError; - } - - bool CShaderSrv::EncapsulateRequestInEngineConnectionProtocol(std::vector& rCompileData) const - { - if (rCompileData.empty()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::EncapsulateRequestInEngineConnectionProtocol() : Engine Connection was unable to send the message - zero bytes size."); - VerboseLogging(true); - return false; - } - - string serverList = gEnv->pConsole->GetCVar("r_ShaderCompilerServer")->GetString(); - unsigned int serverListLength = static_cast(serverList.size()); - unsigned short serverPort = static_cast(gEnv->pConsole->GetCVar("r_ShaderCompilerPort")->GetIVal()); - - if (serverListLength == 0) - { - AZ_Error("RemoteCompiler", false, "r_ShaderCompilerServer cvar is empty - no servers to send to. This CVAR should contain the list of servers to send shader compiler requests to."); - return false; - } - - // we're packing at the end because sometimes, you don't need to copy the data in that case. - std::size_t originalSize = rCompileData.size(); - - // a null the string a null the port the length of the string - rCompileData.resize(originalSize + 1 + serverListLength + 1 + sizeof(serverPort) + sizeof(unsigned int)); - uint8* dataStart = rCompileData.data() + originalSize; - *dataStart = 0; // null - ++dataStart; - memcpy(dataStart, serverList.c_str(), serverList.size()); // server list data - dataStart += serverList.size(); - *dataStart = 0; // null - ++dataStart; - - SwapEndian(serverPort); - SwapEndian(serverListLength); - - memcpy(dataStart, &serverPort, sizeof(serverPort)); // server port - dataStart += sizeof(serverPort); - memcpy(dataStart, &serverListLength, sizeof(serverListLength)); // server list length - dataStart += sizeof(serverListLength); - - // check for buffer overrun - assert(reinterpret_cast(dataStart) - reinterpret_cast(rCompileData.data()) == rCompileData.size()); - return true; - } - - EServerError CShaderSrv::SendRequestViaEngineConnection(std::vector& rCompileData) const - { - // use the asset processor instead of direct socket. - // wrap it up in a protocol structure - very straight forward - the requestID followed by the data - // the protocol already takes care of the data size, underneath, so no need to send that - - // what we need include the information about what server(s) to connect to. - // we can append to the end of the compile data so as to avoid copying unless we need to - - if (!EncapsulateRequestInEngineConnectionProtocol(rCompileData)) - { - return ESFailed; - } - - if (!m_remoteState->SubmitRequestAndBlockForResponse(rCompileData)) - { - rCompileData.clear(); - AZ_Error("RemoteCompiler", false, "CShaderSrv::SendRequestViaEngineConnection() : Engine Connection was unable to send the message."); - VerboseLogging(true); - return ESNetworkError; - } - - if (rCompileData.empty()) - { - AZ_Error("RemoteCompiler", false, "CShaderSrv::SendRequestViaEngineConnection() : Recv data empty from server (didn't receive anything)\n"); - VerboseLogging(true); - - const AZStd::string title = "Remote Shader Compiler"; - const AZStd::string message = "Unable to connect to Remote Shader Compiler"; - if(!gEnv->IsInToolMode()) - { - EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, title, message, false); - } - return ESRecvFailed; - } - - // Check for error embedded in the response! - return ProcessResponse(rCompileData); - } - - void CShaderSrv::EnableUnitTestingMode(bool mode) - { - m_unitTestMode = mode; - m_remoteState->SetUnitTestMode(mode); - } - -} // end namespace - diff --git a/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.h b/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.h deleted file mode 100644 index 9d413a5138..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/RemoteCompiler.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_REMOTECOMPILER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_REMOTECOMPILER_H -#pragma once - -#include - -namespace NRemoteCompiler -{ - typedef std::vector tdEntryVec; - - enum EServerError - { - ESOK, - ESFailed, - ESInvalidState, - ESCompileError, - ESNetworkError, - ESSendFailed, - ESRecvFailed, - }; - - enum EShaderCompiler - { - eSC_Unknown, - eSC_Orbis_DXC, - eSC_D3D11_FXC, - eSC_GLSL_HLSLcc, - eSC_METAL_HLSLcc, - eSC_GLSL_LLVM_DXC, - eSC_METAL_LLVM_DXC, - eSC_Jasper_FXC, - eSC_MAX - }; - - class RemoteProxyState; - - class CShaderSrv - { - public: - // the main entry into this system - // on return, rVec contains the response vector, or an error string, if failed - EServerError Compile(std::vector& rVec, const char* pProfile, const char* pProgram, const char* pEntry, const char* pCompileFlags, const char* pIdent) const; - - EServerError GetShaderList(std::vector& rVec) const; - - bool CommitPLCombinations(std::vector& rVec); - - // RequestLine causes the remote compiler to compile without expecting a response. - bool RequestLine(const string& rList, const string& rString) const; - - EShaderCompiler GetShaderCompiler() const; - const char *GetShaderCompilerName() const; - - AZStd::string GetShaderCompilerFlags(EHWShaderClass eClass, UPipelineState pipelineState, uint32 MDVMask) const; - - static CShaderSrv& Instance(); - - - private: - // UNIT TEST things can go here. - friend class ShaderSrvUnitTestAccessor; - - bool m_unitTestMode; - void EnableUnitTestingMode(bool mode); // used during cry unit test launcher - - EServerError SendRequestViaEngineConnection(std::vector& rCompileData) const; - - // socket implementation here - EServerError SendRequestViaSocket(std::vector& rCompileData) const; - bool Send(AZSOCKET Socket, const char* pBuffer, uint32 Size) const; - bool Send(AZSOCKET Socket, std::vector& rCompileData) const; - EServerError Recv(AZSOCKET Socket, std::vector& rCompileData) const; - - // internal utilities - bool CreateRequest(std::vector& rVec, std::vector >& rNodes) const; - - bool EncapsulateRequestInEngineConnectionProtocol(std::vector& rCompileData) const; - - const char* GetPlatformName() const; - - RemoteProxyState* m_remoteState; - - // root path added to each request line to store the data per game (eg. MyGame\) - string m_RequestLineRootFolder; - - CShaderSrv(); - EServerError Send(std::vector& rCompileData) const; - - void Tokenize(tdEntryVec& rRet, const string& Tokens, const string& Separator) const; - string TransformToXML(const string& rIn) const; - string CreateXMLNode(const string& rTag, const string& rValue) const; - bool RequestLine(const SCacheCombination& cmb, const string& rLine) const; - - void Init(); - void Terminate(); - - // given a payload of response data from the actual shader server - // decompress and parse it. - EServerError ProcessResponse(std::vector& rCompileData) const; - }; -} -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_REMOTECOMPILER_H - diff --git a/Code/CryEngine/RenderDll/Common/Shaders/RemoteShaderCompilerUnitTests.cpp b/Code/CryEngine/RenderDll/Common/Shaders/RemoteShaderCompilerUnitTests.cpp deleted file mode 100644 index b0bcf1e702..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/RemoteShaderCompilerUnitTests.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include -#include -#include -#include -#include -#include "Mocks/IConsoleMock.h" -#include "Mocks/ICVarMock.h" -#include "Mocks/ISystemMock.h" -#include "RemoteCompiler.h" - - -namespace AZ -{ - class SettingsRegistrySimpleMock; - using NiceSettingsRegistrySimpleMock = ::testing::NiceMock; - - class SettingsRegistrySimpleMock : public AZ::SettingsRegistryInterface - { - public: - MOCK_CONST_METHOD1(GetType, Type(AZStd::string_view)); - MOCK_CONST_METHOD2(Visit, bool(Visitor&, AZStd::string_view)); - MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view)); - MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&)); - MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&)); - - MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view)); - MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view)); - MOCK_CONST_METHOD2(Get, bool(u64&, AZStd::string_view)); - MOCK_CONST_METHOD2(Get, bool(double&, AZStd::string_view)); - MOCK_CONST_METHOD2(Get, bool(AZStd::string&, AZStd::string_view)); - MOCK_CONST_METHOD2(Get, bool(FixedValueString&, AZStd::string_view)); - MOCK_CONST_METHOD3(GetObject, bool(void*, Uuid, AZStd::string_view)); - - MOCK_METHOD2(Set, bool(AZStd::string_view, bool)); - MOCK_METHOD2(Set, bool(AZStd::string_view, s64)); - MOCK_METHOD2(Set, bool(AZStd::string_view, u64)); - MOCK_METHOD2(Set, bool(AZStd::string_view, double)); - MOCK_METHOD2(Set, bool(AZStd::string_view, AZStd::string_view)); - MOCK_METHOD2(Set, bool(AZStd::string_view, const char*)); - MOCK_METHOD3(SetObject, bool(AZStd::string_view, const void*, Uuid)); - - MOCK_METHOD1(Remove, bool(AZStd::string_view)); - - MOCK_METHOD3(MergeCommandLineArgument, bool(AZStd::string_view, AZStd::string_view, const CommandLineArgumentSettings&)); - MOCK_METHOD2(MergeSettings, bool(AZStd::string_view, Format)); - MOCK_METHOD4(MergeSettingsFile, bool(AZStd::string_view, Format, AZStd::string_view, AZStd::vector*)); - MOCK_METHOD5( - MergeSettingsFolder, - bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector*)); - }; -} // namespace AZ - - -namespace NRemoteCompiler -{ - using ::testing::NiceMock; - using ::testing::Return; - using ::testing::DoAll; - - using SystemAllocatorScope = AZ::AllocatorScope; - - // define a dummy compressor decompressor that simply does nothing. - // the actual ISystem::Decompress / Compress should be tested in isolation in the unit it lives in. - // this is expected to fit both of these functions: - //virtual bool CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level = 3) = 0; - //virtual bool DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize) = 0; - // it operates by copying the input into the output and the input size into the output size and always returning true. - AZ_PUSH_DISABLE_WARNING(4100, "-Wunknown-warning-option") - ACTION(MockCompressDecompress) - { - AZ_Assert(arg3 >= arg1, "MockCompressDecompress would overrun buffer (%i must be >= %i)", (int)arg3, (int)arg1); - if (arg3 < arg1) - { - return false; - } - - memcpy(arg2, arg0, arg1); - arg3 = arg1; - return true; - }; - AZ_POP_DISABLE_WARNING - - using ::UnitTest::AllocatorsTestFixture; - - class RemoteCompilerTest - : public AllocatorsTestFixture - , public SystemAllocatorScope - { - public: - - const int m_fakePortNumber = 12345; - - void SetUp() override - { - using namespace ::testing; - - AllocatorsTestFixture::SetUp(); - SystemAllocatorScope::ActivateAllocators(); - - m_priorEnv = gEnv; - m_priorSettingsRegistry = AZ::SettingsRegistry::Get(); - - m_data.reset(new DataMembers); - - AZ::SettingsRegistry::Register(&m_data->m_settings); - - ON_CALL(m_data->m_console, GetCVar(_)) - .WillByDefault(Return(&m_data->m_cvarMock)); - - ON_CALL(m_data->m_system, CompressDataBlock(_, _, _, _, _)) - .WillByDefault(MockCompressDecompress()); - - ON_CALL(m_data->m_system, DecompressDataBlock(_, _, _, _)) - .WillByDefault(MockCompressDecompress()); - - ON_CALL(m_data->m_cvarMock, GetIVal()) - .WillByDefault(Return(m_fakePortNumber)); - - memset(&m_data->m_stubEnv, 0, sizeof(SSystemGlobalEnvironment)); - m_data->m_stubEnv.pConsole = &m_data->m_console; - m_data->m_stubEnv.pSystem = &m_data->m_system; - gEnv = &m_data->m_stubEnv; - } - - void TearDown() override - { - gEnv = m_priorEnv; - AZ::SettingsRegistry::Unregister(&m_data->m_settings); - if (m_priorSettingsRegistry) - { - AZ::SettingsRegistry::Register(m_priorSettingsRegistry); - } - m_data.reset(); - SystemAllocatorScope::DeactivateAllocators(); - AllocatorsTestFixture::TearDown(); - } - - struct DataMembers - { - NiceMock m_system; - NiceMock m_console; - NiceMock m_cvarMock; - AZ::NiceSettingsRegistrySimpleMock m_settings; - SSystemGlobalEnvironment m_stubEnv; - }; - - AZStd::unique_ptr m_data; - - SSystemGlobalEnvironment* m_priorEnv = nullptr; - AZ::SettingsRegistryInterface* m_priorSettingsRegistry = nullptr; - }; - - // allow punch through to PRIVATE functions so that they do not need to be made PUBLIC. - class ShaderSrvUnitTestAccessor - : public CShaderSrv - { - public: - ShaderSrvUnitTestAccessor() - : CShaderSrv() - { - CShaderSrv::EnableUnitTestingMode(true); - } - EServerError SendRequestViaEngineConnection(std::vector& rCompileData) const - { - return CShaderSrv::SendRequestViaEngineConnection(rCompileData); - } - - bool EncapsulateRequestInEngineConnectionProtocol(std::vector& rCompileData) const - { - return CShaderSrv::EncapsulateRequestInEngineConnectionProtocol(rCompileData); - } - }; - - TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithNoGameName_Fails) - { - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString regResult; - EXPECT_CALL(m_data->m_settings, Get(regResult, _)); - - AZ_TEST_START_TRACE_SUPPRESSION; - ShaderSrvUnitTestAccessor srv; - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithValidGameName_Succeeds) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - } - - TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_EmptyData_Fails) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - std::vector testVector; - - AZ_TEST_START_TRACE_SUPPRESSION; - EXPECT_FALSE(srv.EncapsulateRequestInEngineConnectionProtocol(testVector)); // empty vector error condition - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above to have thrown an AZ_ERROR - } - - TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidData_EmptyServerList_Fails) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return("")); // empty server list - - std::vector testVector; - std::string testString("_-=!-"); - testVector.insert(testVector.begin(), testString.begin(), testString.end()); - - AZ_TEST_START_TRACE_SUPPRESSION; - EXPECT_FALSE(srv.EncapsulateRequestInEngineConnectionProtocol(testVector)); // empty vector error condition - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // expect the above to have thrown an AZ_ERROR - } - - TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidInputs_Succeeds) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - std::vector testVector; - std::string testString("_-=!-"); - testVector.insert(testVector.begin(), testString.begin(), testString.end()); - - EXPECT_TRUE(srv.EncapsulateRequestInEngineConnectionProtocol(testVector)); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_EmptyData_Fails) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - std::vector testVector; - std::string testString("empty"); - - // test for empty data - RecvFailed expected (error emitted) - AZ_TEST_START_TRACE_SUPPRESSION; - testString = "empty"; - testVector.assign(testString.begin(), testString.end()); - EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_IncompleteData_Fails) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - std::vector testVector; - std::string testString("incomplete"); - testVector.assign(testString.begin(), testString.end()); - - // test for incomplete data - RecvFailed expected - AZ_TEST_START_TRACE_SUPPRESSION; - EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CorruptData_Fails) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - std::vector testVector; - std::string testString("corrupt"); - testVector.assign(testString.begin(), testString.end()); - - // test for incomplete data - RecvFailed expected - AZ_TEST_START_TRACE_SUPPRESSION; - EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CompileError_Fails_ReturnsText) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - std::vector testVector; - std::string testString("corrupt"); - testVector.assign(testString.begin(), testString.end()); - // test for an actual compile error - decompressed compile error expected to be attached. - testString = "compile_failure"; - testVector.assign(testString.begin(), testString.end()); - EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESCompileError); - // validate the compile error decompressed successfully - const char* expected_decode = "decompressed_plaintext"; - EXPECT_EQ(testVector.size(), strlen(expected_decode)); - EXPECT_EQ(memcmp(testVector.data(), expected_decode, strlen(expected_decode)), 0); - } - - TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_ValidInput_Succeeds_ReturnsText) - { - // when we construct the server it calls get on the game name - using namespace ::testing; - AZ::SettingsRegistryInterface::FixedValueString projectName; - EXPECT_CALL(m_data->m_settings, Get(projectName, _)) - .WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true))); - - ShaderSrvUnitTestAccessor srv; - - // After this, it will repeatedly call get cvar to get the server address: - const char* testList = "10.20.30.40"; - EXPECT_CALL(m_data->m_cvarMock, GetString()) - .WillRepeatedly(Return(testList)); - - AZStd::string testString = "success"; - std::vector testVector; - testVector.assign(testString.begin(), testString.end()); - - EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESOK); - - // validate that the result decompressed successfully - its expected to contain "decompressed_plaintext" - const char* expected_decode = "decompressed_plaintext"; - EXPECT_EQ(testVector.size(), strlen(expected_decode)); - EXPECT_EQ(memcmp(testVector.data(), expected_decode, strlen(expected_decode)), 0); - } -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/Shader.h b/Code/CryEngine/RenderDll/Common/Shaders/Shader.h deleted file mode 100644 index d4825bfaa2..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/Shader.h +++ /dev/null @@ -1,1515 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Shaders declarations. - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_SHADER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_SHADER_H -#pragma once - - -#include "../Defs.h" -#include "Vertex.h" - -#include -#include -#include "ShaderResources.h" - -// bump this value up if you want to invalidate shader cache (e.g. changed some code or .ext file) -// #### VIP NOTE ####: DON'T USE MORE THAN ONE DECIMAL PLACE!!!! else it doesn't work... -#define FX_CACHE_VER 10.5f -#define FX_SER_CACHE_VER 1.4f // Shader serialization version (FX_CACHE_VER + FX_SER_CACHE_VER) - -// Maximum 1 digit here -// The version determines the parse logic in the shader cache gen, these values cannot overlap -#define SHADER_LIST_VER 4 -#define SHADER_SERIALISE_VER (SHADER_LIST_VER + 1) - -//#define SHADER_NO_SOURCES 1 // If this defined all binary shaders (.fxb) should be located in Game folder (not user) -#if !defined(NULL_RENDERER) -#define SHADERS_SERIALIZING 1 // Enables shaders serializing (Export/Import) to/from .fxb files -#endif - -struct SShaderPass; -class CShader; -class CRendElementBase; -class CResFile; -struct SEnvTexture; -struct SParserFrame; -struct SPreprocessTree; -struct SEmptyCombination; -struct SShaderCombination; -struct SShaderCache; -struct SShaderDevCache; -struct SCGParam; -struct SSFXParam; -struct SSFXSampler; -struct SSFXTexture; - - -enum eCompareFunc -{ - eCF_Disable, - eCF_Never, - eCF_Less, - eCF_Equal, - eCF_LEqual, - eCF_Greater, - eCF_NotEqual, - eCF_GEqual, - eCF_Always -}; - - -struct SPair -{ - string m_szMacroName; - string m_szMacro; - uint32 m_nMask; -}; - -#if defined(MOBILE) - #define GEOMETRYSHADER_SUPPORT false -#else - #define GEOMETRYSHADER_SUPPORT true -#endif - -//------------------------------------------------------------------------------ -// SFX structures are the structures gathered from the shader during shader parsing -// and associated later on to a binding slot / buffer. -// They represent constants, textures and samplers. -//------------------------------------------------------------------------------ -struct SFXBaseParam -{ - CCryNameR m_Name; // Parameter name - std::vector m_dwName; - uint32 m_nFlags; - short m_nArray; // Number of parameters - CCryNameR m_Annotations; // Additional parameters (between <>) - CCryNameR m_Semantic; // Parameter semantic type (after ':') - CCryNameR m_Values; // Parameter values (after '=') - byte m_eType; // Type per usage - - // [Shader System] register offset per shader stage (class) - VS, PS, GS... - // This needs to be unified for all stages (and renamed as m_RegisterOffset) - short m_Register[eHWSC_Num]; - - SFXBaseParam() - { - m_nArray = 0; - m_nFlags = 0; - for (int i = 0; i < eHWSC_Num; i++) - { - m_Register[i] = 10000; - } - } - - uint32 GetFlags() { return m_nFlags; } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_dwName); - } -}; - -//------------------------------------------------------------------------------ -// An SFXParam is the constant data gathered from the shader parsing. -// Example of usage - In Matrix 3x4: m_nParams = 3, m_nComps = 4 -// Needs some more refactor to fully use SFXBaseParam. -//------------------------------------------------------------------------------ -struct SFXParam : SFXBaseParam -{ - short m_RegisterCount; - short m_ComponentCount; - int8 m_BindingSlot; // the CB slot - - // [Shaders System] - the following needs to be removed as part of the unified offset. - // The next two parameters are only valid after the gather stage for final parameters - AZ::u8 m_OffsetStageSetter; // which stage set the offset - AZ::u8 m_StagesUsage; // Adding visibility to who's using the param - - SFXParam() - { - m_RegisterCount = 0; - m_ComponentCount = 0; - m_BindingSlot = -1; - m_OffsetStageSetter = eHWSC_Vertex; - m_StagesUsage = (1 << eHWSC_Vertex); - } - - ~SFXParam() {} - - void GetParamComp(uint32 nOffset, CryFixedStringT<128>& param); - void GetCompName(uint32 nId, CryFixedStringT<128>& name); - string GetValueForName(const char* szName, EParamType& eType); - void PostLoad(class CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign); - void PostLoad(); - bool Export(SShaderSerializeContext& SC); - bool Import(SShaderSerializeContext& SC, SSFXParam* pPR); - - uint32 Size() - { - uint32 nSize = sizeof(SFXParam); - nSize += sizeofVector(m_dwName); - return nSize; - } - - inline bool operator == (const SFXParam& m) const - { - if (m_Name == m.m_Name && m_Annotations == m.m_Annotations && m_Semantic == m.m_Semantic && m_Values == m.m_Values && - m_RegisterCount == m.m_RegisterCount && m_ComponentCount == m.m_ComponentCount && m_nFlags == m.m_nFlags && m_Register[0] == m.m_Register[0] && m_Register[1] == m.m_Register[1] && - m_eType == m.m_eType) - { - return true; - } - return false; - } -}; - -//------------------------------------------------------------------------------ -// An SFX structure is the structure gathered from the shader during -// parsing and associated later on. -//------------------------------------------------------------------------------ -struct SFXSampler : SFXBaseParam -{ - int m_nTexState; - - SFXSampler() - { - m_nTexState = -1; - } - ~SFXSampler() {} - - void PostLoad(class CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign); - void PostLoad(); - bool Export(SShaderSerializeContext& SC); - bool Import(SShaderSerializeContext& SC, SSFXSampler* pPR); - - uint32 Size() - { - uint32 nSize = sizeof(SFXSampler); - nSize += sizeofVector(m_dwName); - return nSize; - } - - inline bool operator == (const SFXSampler& m) const - { - if (m_Name == m.m_Name && m_Annotations == m.m_Annotations && m_Semantic == m.m_Semantic && m_Values == m.m_Values && - m_nArray == m.m_nArray && m_nFlags == m.m_nFlags && m_Register[0] == m.m_Register[0] && m_Register[1] == m.m_Register[1] && - m_eType == m.m_eType && m_nTexState == m.m_nTexState) - { - return true; - } - return false; - } -}; - -//------------------------------------------------------------------------------ -// An SFX structure is the structure gathered from the shader during -// parsing and associated later on. -// SFXTexture - This structure contains a meta data gathered during shader parsing. -// It doesn't contain the actual texture data and doesn't apply to the binding directly -// but used as the data associated with the SCGTexture binding structure. -//------------------------------------------------------------------------------ -struct SFXTexture : SFXBaseParam -{ - uint32 m_nTexFlags; - string m_szTexture; // Texture source name - string m_szUIName; // UI name - string m_szUIDesc; // UI description - bool m_bSRGBLookup; // Lookup - byte m_Type; // Data type (float, float4, etc) - - SFXTexture() - { - m_bSRGBLookup = false; - m_Type = 0; - m_nTexFlags = 0; - } - - ~SFXTexture() {} - - uint32 GetTexFlags() { return m_nTexFlags; } - void PostLoad(class CParserBin& Parser, SParserFrame& Name, SParserFrame& Annotations, SParserFrame& Values, SParserFrame& Assign); - void PostLoad(); - bool Export(SShaderSerializeContext& SC); - bool Import(SShaderSerializeContext& SC, SSFXTexture* pPR); - - uint32 Size() - { - uint32 nSize = sizeof(SFXTexture); - //nSize += m_Name.capacity(); - nSize += sizeofVector(m_dwName); - //nSize += m_Values.capacity(); - return nSize; - } - - inline bool operator == (const SFXTexture& m) const - { - if (m_Name == m.m_Name && m_Annotations == m.m_Annotations && m_Semantic == m.m_Semantic && m_Values == m.m_Values && - m_nArray == m.m_nArray && m_nFlags == m.m_nFlags && m_Register[0] == m.m_Register[0] && m_Register[1] == m.m_Register[1] && - m_eType == m.m_eType && m_bSRGBLookup == m.m_bSRGBLookup && m_szTexture == m.m_szTexture) - { - return true; - } - return false; - } -}; - -//------------------------------------------------------------------------------ -struct STokenD -{ - //std::vector Offsets; - uint32 Token; - string SToken; - unsigned Size() { return sizeof(STokenD) /*+ sizeofVector(Offsets)*/ + SToken.capacity(); } - void GetMemoryUsage(ICrySizer* pSizer) const { pSizer->AddObject(SToken); } -}; -typedef AZStd::vector FXShaderToken; -typedef FXShaderToken::iterator FXShaderTokenItor; - -struct SFXStruct -{ - string m_Name; - string m_Struct; - SFXStruct() - { - } -}; - -enum ETexFilter -{ - eTEXF_None, - eTEXF_Point, - eTEXF_Linear, - eTEXF_Anisotropic, -}; - -//============================================================================= -// Vertex programms / Vertex shaders (VP/VS) - -static _inline float* sfparam(Vec3 param) -{ - static float sparam[4]; - sparam[0] = param.x; - sparam[1] = param.y; - sparam[2] = param.z; - sparam[3] = 1.0f; - - return &sparam[0]; -} - -static _inline float* sfparam(float param) -{ - static float sparam[4]; - sparam[0] = param; - sparam[1] = 0; - sparam[2] = 0; - sparam[3] = 1.0f; - return &sparam[0]; -} - -static _inline float* sfparam(float param0, float param1, float param2, float param3) -{ - static float sparam[4]; - sparam[0] = param0; - sparam[1] = param1; - sparam[2] = param2; - sparam[3] = param3; - return &sparam[0]; -} - -_inline char* sGetFuncName(const char* pFunc) -{ - static char func[128]; - const char* b = pFunc; - if (*b == '[') - { - const char* s = strchr(b, ']'); - if (s) - { - b = s + 1; - } - while (*b <= 0x20) - { - b++; - } - } - while (*b > 0x20) - { - b++; - } - while (*b <= 0x20) - { - b++; - } - int n = 0; - while (*b > 0x20 && *b != '(') - { - func[n++] = *b++; - } - func[n] = 0; - - return func; -} - -enum ERenderOrder -{ - eRO_PreProcess, - eRO_PostProcess, - eRO_PreDraw -}; - -enum ERTUpdate -{ - eRTUpdate_Unknown, - eRTUpdate_Always, - eRTUpdate_WaterReflect -}; - -struct SHRenderTarget - : public IRenderTarget -{ - int m_nRefCount; - ERenderOrder m_eOrder; - int m_nProcessFlags; // FSPR_ flags - string m_TargetName; - int m_nWidth; - int m_nHeight; - ETEX_Format m_eTF; - int m_nIDInPool; - ERTUpdate m_eUpdateType; - CTexture* m_pTarget[2]; - bool m_bTempDepth; - ColorF m_ClearColor; - float m_fClearDepth; - uint32 m_nFlags; - uint32 m_nFilterFlags; - int m_refSamplerID; - - SHRenderTarget() - { - m_nRefCount = 1; - m_eOrder = eRO_PreProcess; - m_pTarget[0] = NULL; - m_pTarget[1] = NULL; - m_bTempDepth = true; - m_ClearColor = Col_Black; - m_fClearDepth = 1.f; - m_nFlags = 0; - m_nFilterFlags = 0xffffffff; - m_nProcessFlags = 0; - m_nIDInPool = -1; - m_nWidth = 256; - m_nHeight = 256; - m_eTF = eTF_R8G8B8A8; - m_eUpdateType = eRTUpdate_Unknown; - m_refSamplerID = -1; - } - virtual void Release() - { - m_nRefCount--; - if (m_nRefCount) - { - return; - } - delete this; - } - virtual void AddRef() - { - m_nRefCount++; - } - SEnvTexture* GetEnv2D(); - SEnvTexture* GetEnvCM(); - - void GetMemoryUsage(ICrySizer* pSizer) const; -}; - -//============================================================================= -// Hardware shaders - -#define SHADER_BIND_TEXTURE 0x2000 -#define SHADER_BIND_SAMPLER 0x4000 - -//============================================================================= - -struct SShaderCacheHeaderItem -{ - AZ::u32 m_nVertexFormat; - byte m_Class; - byte m_nInstBinds; - byte m_StreamMask_Stream; - uint32 m_CRC32; - uint16 m_StreamMask_Decl; - int16 m_nInstructions; - SShaderCacheHeaderItem() - { - memset(this, 0, sizeof(SShaderCacheHeaderItem)); - } - AUTO_STRUCT_INFO -}; - -#define MAX_VAR_NAME 512 -struct SShaderCacheHeaderItemVar -{ - int m_Reg; - short m_nCount; - char m_Name[MAX_VAR_NAME]; - SShaderCacheHeaderItemVar() - { - memset(this, 0, sizeof(SShaderCacheHeaderItemVar)); - } -}; - -struct SCompressedData -{ - byte* m_pCompressedShader; - uint32 m_nSizeCompressedShader; - uint32 m_nSizeDecompressedShader; - - SCompressedData() - { - m_pCompressedShader = NULL; - m_nSizeCompressedShader = 0; - m_nSizeDecompressedShader = 0; - } - int Size() - { - int nSize = sizeof(SCompressedData); - if (m_pCompressedShader) - { - nSize += m_nSizeCompressedShader; - } - return nSize; - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - //pSizer->AddObject(this, sizeof(SCompressedData)); - if (m_pCompressedShader) - { - pSizer->AddObject(m_pCompressedShader, m_nSizeCompressedShader); - } - } -}; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXDeviceShader; -typedef FXDeviceShader::iterator FXDeviceShaderItor; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXCompressedShader; -typedef FXCompressedShader::iterator FXCompressedShaderItor; -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXCompressedShaderRemap; -typedef FXCompressedShaderRemap::iterator FXCompressedShaderRemapItor; -struct SHWActivatedShader -{ - bool m_bPersistent; - FXCompressedShader m_CompressedShaders; - FXCompressedShaderRemap m_Remap; - ~SHWActivatedShader(); - - int Size(); - void GetMemoryUsage(ICrySizer* pSizer) const; -}; -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXCompressedShaders; -typedef FXCompressedShaders::iterator FXCompressedShadersItor; - -#define CACHE_READONLY 0 -#define CACHE_USER 1 - -struct SOptimiseStats -{ - int nEntries; - int nUniqueEntries; - int nSizeUncompressed; - int nSizeCompressed; - int nTokenDataSize; - int nDirDataSize; - SOptimiseStats() - { - nEntries = 0; - nUniqueEntries = 0; - nSizeUncompressed = 0; - nSizeCompressed = 0; - nTokenDataSize = 0; - nDirDataSize = 0; - } -}; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXShaderCache; -typedef FXShaderCache::iterator FXShaderCacheItor; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXShaderDevCache; -typedef FXShaderDevCache::iterator FXShaderDevCacheItor; - -typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> FXShaderCacheNames; -typedef FXShaderCacheNames::iterator FXShaderCacheNamesItor; - - -//==================================================================== -// HWShader run-time flags - -enum EHWSRMaskBit -{ - HWSR_FOG = 0, - - HWSR_AMBIENT, - - HWSR_ALPHATEST, - HWSR_ALPHABLEND, - - HWSR_HDR_MODE, // deprecated: this flag is redundant and can be dropped, since rendering always HDR since CE3 - HWSR_HDR_ENCODE, - - HWSR_INSTANCING_ATTR, - - HWSR_VERTEX_VELOCITY, - HWSR_SKINNING_DUAL_QUAT, - HWSR_SKINNING_DQ_LINEAR, - HWSR_SKINNING_MATRIX, - - HWSR_OBJ_IDENTITY, - HWSR_DETAIL_OVERLAY, - HWSR_NEAREST, - HWSR_NOZPASS, - HWSR_DISSOLVE, - HWSR_APPLY_TOON_SHADING, - HWSR_NO_TESSELLATION, - HWSR_PER_INSTANCE_CB_TEMP, - - HWSR_QUALITY, - HWSR_QUALITY1, - - HWSR_SAMPLE0, - HWSR_SAMPLE1, - HWSR_SAMPLE2, - HWSR_SAMPLE3, - HWSR_SAMPLE4, - HWSR_SAMPLE5, - - HWSR_DEBUG0, - HWSR_DEBUG1, - HWSR_DEBUG2, - HWSR_DEBUG3, - - HWSR_CUBEMAP0, - - HWSR_DECAL_TEXGEN_2D, - - HWSR_SHADOW_MIXED_MAP_G16R16, - HWSR_HW_PCF_COMPARE, - HWSR_SHADOW_JITTERING, - HWSR_POINT_LIGHT, - HWSR_LIGHT_TEX_PROJ, - - HWSR_PARTICLE_SHADOW, - HWSR_SOFT_PARTICLE, - HWSR_OCEAN_PARTICLE, - HWSR_GLOBAL_ILLUMINATION, - HWSR_ANIM_BLEND, - HWSR_ENVIRONMENT_CUBEMAP, - HWSR_MOTION_BLUR, - - HWSR_SPRITE, - - HWSR_LIGHTVOLUME0, - HWSR_LIGHTVOLUME1, - - HWSR_TILED_SHADING, - - HWSR_VOLUMETRIC_FOG, - - HWSR_REVERSE_DEPTH, - HWSR_GPU_PARTICLE_SHADOW_PASS, - HWSR_GPU_PARTICLE_DEPTH_COLLISION, - HWSR_GPU_PARTICLE_TURBULENCE, - HWSR_GPU_PARTICLE_UV_ANIMATION, - HWSR_GPU_PARTICLE_NORMAL_MAP, - HWSR_GPU_PARTICLE_GLOW_MAP, - HWSR_GPU_PARTICLE_CUBEMAP_DEPTH_COLLISION, - HWSR_GPU_PARTICLE_WRITEBACK_DEATH_LOCATIONS, - HWSR_GPU_PARTICLE_TARGET_ATTRACTION, - HWSR_GPU_PARTICLE_SHAPE_ANGLE, - HWSR_GPU_PARTICLE_SHAPE_BOX, - HWSR_GPU_PARTICLE_SHAPE_POINT, - HWSR_GPU_PARTICLE_SHAPE_CIRCLE, - HWSR_GPU_PARTICLE_SHAPE_SPHERE, - HWSR_GPU_PARTICLE_WIND, - - HWSR_MULTI_LAYER_ALPHA_BLEND, - HWSR_ADDITIVE_BLENDING, - HWSR_APPLY_SSDO, - HWSR_FOG_VOLUME_HIGH_QUALITY_SHADER, - - - HWSR_SRGB0, - HWSR_SRGB1, - HWSR_SRGB2, - - HWSR_DEPTHFIXUP, - HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION, - HWSR_SLIM_GBUFFER, - - HWSR_MAX -}; - -extern uint64 g_HWSR_MaskBit[HWSR_MAX]; - -// HWShader global flags (m_Flags) -#define HWSG_SUPPORTS_LIGHTING 0x20 -#define HWSG_SUPPORTS_MULTILIGHTS 0x40 -#define HWSG_SUPPORTS_MODIF 0x80 -#define HWSG_SUPPORTS_VMODIF 0x100 -#define HWSG_WASGENERATED 0x200 -#define HWSG_NOSPECULAR 0x400 -#define HWSG_SYNC 0x800 -#define HWSG_CACHE_USER 0x1000 -//#define HWSG_AUTOENUMTC 0x1000 -#define HWSG_UNIFIEDPOS 0x2000 -#define HWSG_DEFAULTPOS 0x4000 -#define HWSG_PROJECTED 0x8000 -#define HWSG_NOISE 0x10000 -#define HWSG_PRECACHEPHASE 0x20000 -#define HWSG_FP_EMULATION 0x40000 - -// HWShader per-instance Modificator flags (SHWSInstance::m_MDMask) -// Vertex shader specific - -// Texture projected flags -#define HWMD_TEXCOORD_PROJ 0x1 -// Texture transform flag -#define HWMD_TEXCOORD_MATRIX 0x100 -// Object linear texgen flag -#define HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE 0x1000 -#define HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE 0x2000 -#define HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT 0x4000 -#define HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL 0x8000 -#define HWMD_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM 0x10000 - - -#define HWMD_TEXCOORD_FLAG_MASK (0xfffff000 | 0xf00) - -// HWShader per-instance vertex modificator flags (SHWSInstance::m_MDVMask) -// Texture projected flags (4 bits) -#define HWMDV_TYPE 0 - - -// HWShader input flags (passed via mfSet function) -#define HWSF_SETPOINTERSFORSHADER 1 -#define HWSF_SETPOINTERSFORPASS 2 -#define HWSF_PRECACHE 4 -#define HWSF_SETTEXTURES 8 -#define HWSF_FAKE 0x10 - -#define HWSF_INSTANCED 0x20 -#define HWSF_NEXT 0x100 -#define HWSF_PRECACHE_INST 0x200 -#define HWSF_STORECOMBINATION 0x400 -#define HWSF_STOREDATA 0x800 - -// Static flags -enum EHWSSTFlag -{ - HWSST_Invalid = -1, -#undef FX_STATIC_FLAG -#define FX_STATIC_FLAG(flag) HWSST_##flag, -#include "ShaderStaticFlags.inl" - HWSST_MAX -}; - -class CHWShader - : public CBaseResource -{ - static CCryNameTSCRC s_sClassNameVS; - static CCryNameTSCRC s_sClassNamePS; - -public: - EHWShaderClass m_eSHClass; - //EHWSProfile m_eHWProfile; - SShaderCache* m_pGlobalCache; - - static struct SD3DShader* s_pCurPS; - static struct SD3DShader* s_pCurVS; - static struct SD3DShader* s_pCurGS; - static struct SD3DShader* s_pCurDS; - static struct SD3DShader* s_pCurHS; - static struct SD3DShader* s_pCurCS; - - string m_Name; - string m_NameSourceFX; - string m_EntryFunc; - uint64 m_nMaskAnd_RT; - uint64 m_nMaskOr_RT; - uint64 m_nMaskGenShader; // Masked/Optimised m_nMaskGenFX for this specific HW shader - uint64 m_nMaskGenFX; // FX Shader should be parsed with this flags - uint64 m_nMaskSetFX; // AffectMask GL for parser tree - uint64 m_maskGenStatic; // Mask for global static flags used for generating the shader. - - uint32 m_nPreprocessFlags; - int m_nFrame; - int m_nFrameLoad; - int m_Flags; - uint32 m_CRC32; - uint32 m_dwShaderType; - -public: - CHWShader() - { - m_nFrame = 0; - m_nFrameLoad = 0; - m_Flags = 0; - m_nMaskGenShader = 0; - m_nMaskAnd_RT = -1; - m_nMaskOr_RT = 0; - m_CRC32 = 0; - m_nMaskGenFX = 0; - m_nMaskSetFX = 0; - m_eSHClass = eHWSC_Vertex; - m_pGlobalCache = NULL; - } - virtual ~CHWShader() {} - - //EHWSProfile mfGetHWProfile(uint32 nFlags); - -#if !defined (NULL_RENDERER) - - static CHWShader* mfForName(const char* name, const char* nameSource, uint32 CRC32, const char* szEntryFunc, EHWShaderClass eClass, TArray& SHData, FXShaderToken* pTable, uint32 dwType, CShader* pFX, uint64 nMaskGen = 0, uint64 nMaskGenFX = 0); -#endif - static void mfReloadScript(const char* szPath, const char* szName, int nFlags, uint64 nMaskGen); - static void mfFlushPendedShadersWait(int nMaxAllowed); - inline const char* GetName() - { - return m_Name.c_str(); - } - virtual int Size() = 0; - virtual void GetMemoryUsage(ICrySizer* Sizer) const = 0; - virtual void mfReset([[maybe_unused]] uint32 CRC32) {} - virtual bool mfSetV(int nFlags = 0) = 0; - virtual bool mfAddEmptyCombination(CShader* pSH, uint64 nRT, uint64 nGL, uint32 nLT) = 0; - virtual bool mfStoreEmptyCombination(SEmptyCombination& Comb) = 0; - virtual const char* mfGetCurScript() {return NULL; } - virtual const char* mfGetEntryName() = 0; - virtual void mfUpdatePreprocessFlags(SShaderTechnique* pTech) = 0; - virtual bool mfFlushCacheFile() = 0; - virtual bool mfPrecache(SShaderCombination& cmb, bool bForce, bool bFallback, bool bCompressedOnly, CShader* pSH, CShaderResources* pRes) = 0; - - virtual bool Export(SShaderSerializeContext& SC) = 0; - static CHWShader* Import(SShaderSerializeContext& SC, int nOffs, uint32 CRC32, CShader* pSH); - - // Vertex shader specific functions - virtual AZ::Vertex::Format mfVertexFormat(bool& bUseTangents, bool& bUseLM, bool& bUseHWSkin, bool& bUseVertexVelocity) = 0; - - virtual const char* mfGetActivatedCombinations(bool bForLevel) = 0; - - static const char* mfProfileString(EHWShaderClass eClass); - static const char* mfClassString(EHWShaderClass eClass); - static EHWShaderClass mfStringProfile(const char* profile); - static EHWShaderClass mfStringClass(const char* szClass); - static void mfGenName(uint64 GLMask, uint64 RTMask, uint32 LightMask, uint32 MDMask, uint32 MDVMask, uint64 PSS, uint64 STMask, EHWShaderClass eClass, char* dstname, int nSize, byte bType); - - static void mfCleanupCache(); - - static CCryNameTSCRC mfGetClassName(EHWShaderClass eClass) - { - if (eClass == eHWSC_Vertex) - { - return s_sClassNameVS; - } - else - { - return s_sClassNamePS; - } - } - - static const char* GetCurrentShaderCombinations(bool bForLevel); - static bool PreactivateShaders(); - static void RT_PreactivateShaders(); - - static byte* mfIgnoreRemapsFromCache(int nRemaps, byte* pP); - static byte* mfIgnoreBindsFromCache(int nParams, byte* pP); -#if !defined(CONSOLE) - static bool mfOptimiseCacheFile(SShaderCache* pCache, bool bForce, SOptimiseStats* Stats); -#endif - static SShaderDevCache* mfInitDevCache(const char* name, CHWShader* pSH); - static SShaderCache* mfInitCache(const char* name, CHWShader* pSH, bool bCheckValid, uint32 CRC32, bool bReadOnly, bool bAsync = false); - static bool _OpenCacheFile(float fVersion, SShaderCache* pCache, CHWShader* pSH, bool bCheckValid, uint32 CRC32, int nCache, CResFile* pRF, bool bReadOnly); - static bool mfOpenCacheFile(const char* szName, float fVersion, SShaderCache* pCache, CHWShader* pSH, bool bCheckValid, uint32 CRC32, bool bReadOnly); - static void mfValidateTokenData(CResFile* pRF); - static FXShaderCacheNames m_ShaderCacheList; - static FXShaderCache m_ShaderCache; - - // Import/Export - static bool ImportSamplers(SShaderSerializeContext& SC, struct SCHWShader* pSHW, byte*& pData, std::vector& Samplers); - static bool ImportParams(SShaderSerializeContext& SC, SCHWShader* pSHW, byte*& pData, std::vector& Params); - - static FXCompressedShaders m_CompressedShaders; -}; - -_inline void SortLightTypes(int Types[4], int nCount) -{ - switch (nCount) - { - case 2: - if (Types[0] > Types[1]) - { - Exchange(Types[0], Types[1]); - } - break; - case 3: - if (Types[0] > Types[1]) - { - Exchange(Types[0], Types[1]); - } - if (Types[0] > Types[2]) - { - Exchange(Types[0], Types[2]); - } - if (Types[1] > Types[2]) - { - Exchange(Types[1], Types[2]); - } - break; - case 4: - { - for (int i = 0; i < 4; i++) - { - for (int j = i; j < 4; j++) - { - if (Types[i] > Types[j]) - { - Exchange(Types[i], Types[j]); - } - } - } - } - break; - } -} - -//========================================================================= -// Dynamic lights evaluating via shaders - -enum ELightStyle -{ - eLS_Intensity, - eLS_RGB, -}; - -enum ELightMoveType -{ - eLMT_Wave, - eLMT_Patch, -}; - -struct SLightMove -{ - ELightMoveType m_eLMType; - SWaveForm m_Wave; - Vec3 m_Dir; - float m_fSpeed; - - int Size() - { - int nSize = sizeof(SLightMove); - return nSize; - } -}; - -struct SLightStyleKeyFrame -{ - ColorF cColor; // xyz: color, w: spec mult - Vec3 vPosOffset; // position offset - - SLightStyleKeyFrame() - { - cColor = ColorF(Col_Black); - vPosOffset = Vec3(ZERO); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -class CLightStyle -{ -public: - - CLightStyle() - : m_Color(Col_White) - , m_vPosOffset(ZERO) - , m_LastTime(0.0f) - , m_TimeIncr(60.0f) - , m_bRandColor(0) - , m_bRandIntensity(0) - , m_bRandPosOffset(0) - , m_bRandSpecMult(0) - { - } - - static TArray s_LStyles; - TArray m_Map; - - ColorF m_Color; // xyz: color, w: spec mult - Vec3 m_vPosOffset; // position offset - - float m_TimeIncr; - float m_LastTime; - - uint8 m_bRandColor : 1; - uint8 m_bRandIntensity : 1; - uint8 m_bRandPosOffset : 1; - uint8 m_bRandSpecMult : 1; - - int Size() - { - int nSize = sizeof(CLightStyle); - nSize += m_Map.GetMemoryUsage(); - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->Add(*this); - pSizer->AddObject(m_Map); - } - - static _inline CLightStyle* mfGetStyle(uint32 nStyle, float fTime) - { - if (nStyle >= s_LStyles.Num() || !s_LStyles[nStyle]) - { - return NULL; - } - s_LStyles[nStyle]->mfUpdate(fTime); - return s_LStyles[nStyle]; - } - - void mfUpdate(float fTime); -}; - - -//========================================================================= -// HW Shader Layer - -#define SHPF_AMBIENT 0x100 -#define SHPF_HASLM 0x200 -#define SHPF_SHADOW 0x400 -#define SHPF_RADIOSITY 0x800 -#define SHPF_ALLOW_SPECANTIALIAS 0x1000 -#define SHPF_BUMP 0x2000 -#define SHPF_NOMATSTATE 0x4000 -#define SHPF_FORCEZFUNC 0x8000 - - -// Shader pass definition for HW shaders -struct SShaderPass -{ - uint32 m_RenderState; // Render state flags - signed char m_eCull; - uint8 m_AlphaRef; - - uint16 m_PassFlags; // Different usefull Pass flags (SHPF_) - - CHWShader* m_VShader; // Pointer to the vertex shader for the current pass - CHWShader* m_PShader; // Pointer to fragment shader - CHWShader* m_GShader; // Pointer to the geometry shader for the current pass - CHWShader* m_HShader; // Pointer to the hull shader for the current pass - CHWShader* m_DShader; // Pointer to the domain shader for the current pass - CHWShader* m_CShader; // Pointer to the compute shader for the current pass - SShaderPass(); - - int Size() - { - int nSize = sizeof(SShaderPass); - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_VShader); - pSizer->AddObject(m_PShader); - pSizer->AddObject(m_GShader); - pSizer->AddObject(m_HShader); - pSizer->AddObject(m_DShader); - pSizer->AddObject(m_CShader); - } - void mfFree() - { - SAFE_RELEASE(m_VShader); - SAFE_RELEASE(m_PShader); - SAFE_RELEASE(m_GShader); - SAFE_RELEASE(m_HShader); - SAFE_RELEASE(m_DShader); - SAFE_RELEASE(m_CShader); - } - - void AddRefsToShaders() - { - if (m_VShader) - { - m_VShader->AddRef(); - } - if (m_PShader) - { - m_PShader->AddRef(); - } - if (m_GShader) - { - m_GShader->AddRef(); - } - if (m_DShader) - { - m_DShader->AddRef(); - } - if (m_HShader) - { - m_HShader->AddRef(); - } - if (m_CShader) - { - m_CShader->AddRef(); - } - } - -private: - SShaderPass& operator = (const SShaderPass& sl); -}; - -//=================================================================================== -// Hardware Stage for HW only Shaders - -#define FHF_FIRSTLIGHT 8 -#define FHF_FORANIM 0x10 -#define FHF_TERRAIN 0x20 -#define FHF_NOMERGE 0x40 -#define FHF_DETAILPASS 0x80 -#define FHF_LIGHTPASS 0x100 -#define FHF_FOGPASS 0x200 -#define FHF_PUBLIC 0x400 -#define FHF_NOLIGHTS 0x800 -#define FHF_POSITION_INVARIANT 0x1000 -#define FHF_RE_CLOUD 0x20000 -#define FHF_TRANSPARENT 0x40000 -#define FHF_WASZWRITE 0x80000 -#define FHF_USE_GEOMETRY_SHADER 0x100000 -#define FHF_USE_HULL_SHADER 0x200000 -#define FHF_USE_DOMAIN_SHADER 0x400000 -#define FHF_RE_LENSOPTICS 0x1000000 - - -struct SShaderTechnique -{ - CShader* m_shader; - CCryNameR m_NameStr; - CCryNameTSCRC m_NameCRC; - TArray m_Passes; // General passes - int m_Flags; // Different flags (FHF_) - uint32 m_nPreprocessFlags; - int8 m_nTechnique[TTYPE_MAX]; // Next technique in sequence - TArray m_REs; // List of all render elements registered in the shader - TArray m_RTargets; - float m_fProfileTime; - - int Size() - { - uint32 i; - int nSize = sizeof(SShaderTechnique); - for (i = 0; i < m_Passes.Num(); i++) - { - nSize += m_Passes[i].Size(); - } - nSize += m_RTargets.GetMemoryUsage(); - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->Add(*this); - pSizer->AddObject(m_Passes); - pSizer->AddObject(m_REs); - pSizer->AddObject(m_RTargets); - } - - SShaderTechnique(CShader* shader) - { - m_shader = shader; - uint32 i; - for (i = 0; i < TTYPE_MAX; i++) - { - m_nTechnique[i] = -1; - } - for (i = 0; i < m_REs.Num(); i++) - { - SAFE_DELETE(m_REs[i]); - } - m_REs.Free(); - - m_Flags = 0; - m_nPreprocessFlags = 0; - m_fProfileTime = 0; - } - SShaderTechnique& operator = (const SShaderTechnique& sl) - { - memcpy(this, &sl, sizeof(SShaderTechnique)); - if (sl.m_Passes.Num()) - { - m_Passes.Copy(sl.m_Passes); - for (uint32 i = 0; i < sl.m_Passes.Num(); i++) - { - SShaderPass* d = &m_Passes[i]; - d->AddRefsToShaders(); - } - } - if (sl.m_REs.Num()) - { - m_REs.Create(sl.m_REs.Num()); - for (uint32 i = 0; i < sl.m_REs.Num(); i++) - { - if (sl.m_REs[i]) - { - m_REs[i] = sl.m_REs[i]->mfCopyConstruct(); - } - } - } - - return *this; - } - - ~SShaderTechnique() - { - for (uint32 i = 0; i < m_Passes.Num(); i++) - { - SShaderPass* sl = &m_Passes[i]; - - sl->mfFree(); - } - for (uint32 i = 0; i < m_REs.Num(); i++) - { - CRendElementBase* pRE = m_REs[i]; - pRE->Release(false); - } - m_REs.Free(); - m_Passes.Free(); - } - void UpdatePreprocessFlags(CShader* pSH); - - void* operator new(size_t Size) { void* ptr = CryModuleMalloc(Size); memset(ptr, 0, Size); return ptr; } - void* operator new(size_t Size, [[maybe_unused]] const std::nothrow_t& nothrow) - { - void* ptr = CryModuleMalloc(Size); - if (ptr) - { - memset(ptr, 0, Size); - } - return ptr; - } - void operator delete(void* Ptr) { CryModuleFree(Ptr); } -}; - -//=============================================================================== - -// General Shader structure -class CShader - : public IShader - , public CBaseResource -{ - static CCryNameTSCRC s_sClassName; - -public: - string m_NameFile; // } FIXME: This fields order is very important - string m_NameShader; - EShaderDrawType m_eSHDType; // } Check CShader::operator = in ShaderCore.cpp for more info - - uint32 m_Flags; // Different flags EF_ (see IShader.h) - uint32 m_Flags2; // Different flags EF2_ (see IShader.h) - uint32 m_nMDV; // Vertex modificator flags - uint32 m_NameShaderICRC; - - AZ::Vertex::Format m_vertexFormat; // Base vertex format for the shader (see VertexFormats.h) - ECull m_eCull; // Global culling type - - TArray m_HWTechniques; // Hardware techniques - int m_nMaskCB; - - EShaderType m_eShaderType; // [Shader System TO DO] - possibly change to be data driven - - uint64 m_nMaskGenFX; - uint64 m_maskGenStatic; // Static global flags used for generating the shader. - SShaderGen* m_ShaderGenParams; // BitMask params used in automatic script generation - SShaderGen* m_ShaderGenStaticParams; - SShaderTexSlots* m_ShaderTexSlots[TTYPE_MAX]; // filled out with data of the used texture slots for a given technique - // (might be NULL if this data isn't gathered) - std::vector* m_DerivedShaders; - CShader* m_pGenShader; - - int m_nRefreshFrame; // Current frame for shader reloading (to avoid multiple reloading) - uint32 m_SourceCRC32; - uint32 m_CRC32; - - //============================================================================ - - inline int mfGetID() { return CBaseResource::GetID(); } - - void mfFree(); - CShader() - : m_eSHDType(eSHDT_General) - , m_Flags(0) - , m_Flags2(0) - , m_nMDV(0) - , m_NameShaderICRC(0) - , m_vertexFormat(eVF_P3F_C4B_T2F) - , m_eCull((ECull) - 1) - , m_nMaskCB(0) - , m_eShaderType(eST_General) - , m_nMaskGenFX(0) - , m_ShaderGenParams(nullptr) - , m_DerivedShaders(nullptr) - , m_pGenShader(nullptr) - , m_nRefreshFrame(0) - , m_SourceCRC32(0) - , m_CRC32(0) - , m_ShaderGenStaticParams(nullptr) - , m_maskGenStatic(0) - { - memset(m_ShaderTexSlots, 0, sizeof(m_ShaderTexSlots)); - } - virtual ~CShader(); - - //=================================================================================== - - // IShader interface - virtual int AddRef() { return CBaseResource::AddRef(); } - virtual int Release() - { - if (m_Flags & EF_SYSTEM) - { - return -1; - } - return CBaseResource::Release(); - } - virtual int ReleaseForce() - { - m_Flags &= ~EF_SYSTEM; - int nRef = 0; - while (true) - { - nRef = Release(); - if (nRef <= 0) - { - break; - } - } - return nRef; - } - - virtual int GetID() { return CBaseResource::GetID(); } - virtual int GetRefCounter() const { return CBaseResource::GetRefCounter(); } - virtual const char* GetName() { return m_NameShader.c_str(); } - virtual const char* GetName() const { return m_NameShader.c_str(); } - - // D3D Effects interface - virtual bool FXSetTechnique(const CCryNameTSCRC& Name); - virtual bool FXSetPSFloat(const CCryNameR& NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetCSFloat(const CCryNameR& NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetVSFloat(const CCryNameR& NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetGSFloat(const CCryNameR& NameParam, const Vec4 fParams[], int nParams) override; - - virtual bool FXSetPSFloat(const char* NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetCSFloat(const char* NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetVSFloat(const char* NameParam, const Vec4 fParams[], int nParams) override; - virtual bool FXSetGSFloat(const char* NameParam, const Vec4 fParams[], int nParams) override; - - virtual bool FXBegin(uint32* uiPassCount, uint32 nFlags) override; - virtual bool FXBeginPass(uint32 uiPass) override; - virtual bool FXCommit(const uint32 nFlags) override; - virtual bool FXEndPass() override; - virtual bool FXEnd() override; - - virtual int GetFlags() const { return m_Flags; } - virtual int GetFlags2() const { return m_Flags2; } - virtual void SetFlags2(int Flags) { m_Flags2 |= Flags; } - virtual void ClearFlags2(int Flags) { m_Flags2 &= ~Flags; } - - virtual bool Reload(int nFlags, const char* szShaderName); -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - virtual void mfFlushCache(); -#endif - - void mfFlushPendedShaders(); - - virtual int GetTechniqueID(int nTechnique, int nRegisteredTechnique) - { - if (nTechnique < 0) - { - nTechnique = 0; - } - if ((int)m_HWTechniques.Num() <= nTechnique) - { - return -1; - } - SShaderTechnique* pTech = m_HWTechniques[nTechnique]; - return pTech->m_nTechnique[nRegisteredTechnique]; - } - virtual TArray* GetREs (int nTech) - { - if (nTech < 0) - { - nTech = 0; - } - if (nTech < (int)m_HWTechniques.Num()) - { - SShaderTechnique* pTech = m_HWTechniques[nTech]; - return &pTech->m_REs; - } - return NULL; - } - virtual int GetTexId (); - virtual unsigned int GetUsedTextureTypes (void); - virtual AZ::Vertex::Format GetVertexFormat(void) { return m_vertexFormat; } - virtual uint64 GetGenerationMask() { return m_nMaskGenFX; } - virtual ECull GetCull(void) - { - if (m_HWTechniques.Num()) - { - SShaderTechnique* pTech = m_HWTechniques[0]; - if (pTech->m_Passes.Num()) - { - return (ECull)pTech->m_Passes[0].m_eCull; - } - } - return eCULL_None; - } - virtual SShaderGen* GetGenerationParams() - { - if (m_ShaderGenParams) - { - return m_ShaderGenParams; - } - if (m_pGenShader) - { - return m_pGenShader->m_ShaderGenParams; - } - return NULL; - } - - size_t GetNumberOfUVSets() override - { - SShaderGen* shaderGenParams = GetGenerationParams(); - if (shaderGenParams) - { - for (int i = 0; i < shaderGenParams->m_BitMask.Num(); i++) - { - // A material with any of the following shader gen params is using 2 uv sets - if (shaderGenParams->m_BitMask[i]->m_ParamName == "%BLENDLAYER_UV_SET_2" || - shaderGenParams->m_BitMask[i]->m_ParamName == "%EMITTANCE_MAP_UV_SET_2" || - shaderGenParams->m_BitMask[i]->m_ParamName == "%DETAIL_MAPPING_UV_SET_2") - { - if (shaderGenParams->m_BitMask[i]->m_Mask & m_nMaskGenFX) - { - return 2; - } - } - } - } - - return 1; - } - - virtual SShaderTexSlots* GetUsedTextureSlots(int nTechnique); - - virtual AZStd::vector& GetPublicParams(); - virtual EShaderType GetShaderType() { return m_eShaderType; } - virtual EShaderDrawType GetShaderDrawType() const { return m_eSHDType; } - virtual uint32 GetVertexModificator() { return m_nMDV; } - - //======================================================================================= - - bool mfPrecache(SShaderCombination& cmb, bool bForce, bool bCompressedOnly, CShaderResources* pRes); - - SShaderTechnique* mfFindTechnique(const CCryNameTSCRC& name) - { - uint32 i; - for (i = 0; i < m_HWTechniques.Num(); i++) - { - SShaderTechnique* pTech = m_HWTechniques[i]; - if (pTech->m_NameCRC == name) - { - return pTech; - } - } - return NULL; - } - SShaderTechnique* mfGetStartTechnique(int nTechnique); - // CRY DX12 - SShaderTechnique* GetTechnique(int nStartTechnique, int nRequestedTechnique); - - virtual ITexture* GetBaseTexture(int* nPass, int* nTU); - - CShader& operator = (const CShader& src); - CTexture* mfFindBaseTexture(TArray& Passes, int* nPass, int* nTU); - - int mfSize(); - - // All loaded shaders resources list - static TArray s_ShaderResources_known; - - virtual int Size([[maybe_unused]] int Flags) - { - return mfSize(); - } - - virtual void GetMemoryUsage(ICrySizer* Sizer) const; - void* operator new(size_t Size) { void* ptr = CryModuleMalloc(Size); memset(ptr, 0, Size); return ptr; } - void* operator new(size_t Size, [[maybe_unused]] const std::nothrow_t& nothrow) - { - void* ptr = CryModuleMalloc(Size); - if (ptr) - { - memset(ptr, 0, Size); - } - return ptr; - } - void operator delete(void* Ptr) { CryModuleFree(Ptr); } - - static CCryNameTSCRC mfGetClassName() - { - return s_sClassName; - } -}; - -inline SShaderTechnique* SShaderItem::GetTechnique() const -{ - int nTech = m_nTechnique; - if (nTech < 0) - { - nTech = 0; - } - CShader* pSH = (CShader*)m_pShader; - - if (pSH && !pSH->m_HWTechniques.empty()) - { - CryPrefetch(&pSH->m_HWTechniques[0]); - - assert(m_nTechnique < 0 || pSH->m_HWTechniques.Num() == 0 || nTech < (int)pSH->m_HWTechniques.Num()); - if (nTech < (int)pSH->m_HWTechniques.Num()) - { - return pSH->m_HWTechniques[nTech]; - } - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// - - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_SHADER_H diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderAllocator.h b/Code/CryEngine/RenderDll/Common/Shaders/ShaderAllocator.h deleted file mode 100644 index 0c66626d0d..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderAllocator.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_SHADERALLOCATOR_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_SHADERS_SHADERALLOCATOR_H -#pragma once - -#include "CryMemoryAllocator.h" -#include "IMemory.h" - -typedef cry_crt_node_allocator ShaderBucketAllocator; - -extern ShaderBucketAllocator g_shaderBucketAllocator; -extern IGeneralMemoryHeap* g_shaderGeneralHeap; - -template -class STLShaderAllocator -{ -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLShaderAllocator other; - }; - - STLShaderAllocator() throw() { } - STLShaderAllocator(const STLShaderAllocator&) throw() { } - template - STLShaderAllocator(const STLShaderAllocator&) throw() { } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - pointer ret = NULL; - - (void)hint; - size_t sz = std::max(n * sizeof(T), 1); - if (sz <= ShaderBucketAllocator::MaxSize) - { - ret = static_cast(g_shaderBucketAllocator.allocate(sz)); - } - else - { - ret = static_cast(g_shaderGeneralHeap->Malloc(sz, NULL)); - } - - return ret; - } - - void deallocate(pointer p, size_type n = 1) - { - (void)n; - if (p) - { - if (g_shaderGeneralHeap && !g_shaderGeneralHeap->Free(p)) - { - g_shaderBucketAllocator.deallocate(p); - } - } - } - - size_type max_size() const throw() - { - return INT_MAX; - } - - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } - - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLShaderAllocator&) const {return true; } - bool operator!=(const STLShaderAllocator&) const {return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) { } -}; - -#endif diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.cpp deleted file mode 100644 index 9963685743..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.cpp +++ /dev/null @@ -1,2612 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "RemoteCompiler.h" -#include "../RenderCapabilities.h" - -#include -#include -#include - -uint32 SShaderCombIdent::PostCreate() -{ - FUNCTION_PROFILER_RENDER_FLAT - // using actual CRC is to expensive, so replace with cheaper version with - // has more changes of hits - //uint32 hash = CCrc32::Compute(&m_RTMask, sizeof(SShaderCombIdent)-sizeof(uint32)); - const uint32* acBuffer = alias_cast(&m_RTMask); - int len = (sizeof(SShaderCombIdent) - sizeof(uint32)) / sizeof(uint32); - uint32 hash = 5381; - while (len--) - { - int c = *acBuffer++; - // hash = hash*33 + c - hash = ((hash << 5) + hash) + c; - } - - m_nHash = hash; - m_MDVMask &= ~SF_PLATFORM; - return hash; -} - -bool CShader::mfPrecache(SShaderCombination& cmb, bool bForce, bool bCompressedOnly, CShaderResources* pRes) -{ - bool bRes = true; - - if (!CRenderer::CV_r_shadersAllowCompilation && !bForce) - { - return bRes; - } - - int nAsync = CRenderer::CV_r_shadersasynccompiling; - CRenderer::CV_r_shadersasynccompiling = 0; - - uint32 i, j; - - //is this required? Messing with the global render state? - //gRenDev->m_RP.m_pShader = this; - //gRenDev->m_RP.m_pCurTechnique = NULL; - - for (i = 0; i < m_HWTechniques.Num(); i++) - { - SShaderTechnique* pTech = m_HWTechniques[i]; - for (j = 0; j < pTech->m_Passes.Num(); j++) - { - SShaderPass& Pass = pTech->m_Passes[j]; - SShaderCombination c = cmb; - gRenDev->m_RP.m_FlagsShader_MD = cmb.m_MDMask; - if (Pass.m_PShader) - { - bRes &= Pass.m_PShader->mfPrecache(cmb, bForce, false, bCompressedOnly, this, pRes); - } - cmb.m_MDMask = gRenDev->m_RP.m_FlagsShader_MD; - if (Pass.m_VShader) - { - bRes &= Pass.m_VShader->mfPrecache(cmb, bForce, false, bCompressedOnly, this, pRes); - } - cmb = c; - } - } - CRenderer::CV_r_shadersasynccompiling = nAsync; - - return bRes; -} - -SShaderGenComb* CShaderMan::mfGetShaderGenInfo(const char* nmFX) -{ - SShaderGenComb* c = NULL; - uint32 i; - for (i = 0; i < m_SGC.size(); i++) - { - c = &m_SGC[i]; - if (!azstricmp(c->Name.c_str(), nmFX)) - { - break; - } - } - SShaderGenComb cmb; - if (i == m_SGC.size()) - { - c = NULL; - cmb.pGen = mfCreateShaderGenInfo(nmFX, false); - cmb.Name = CCryNameR(nmFX); - m_SGC.push_back(cmb); - c = &m_SGC[i]; - } - return c; -} - -static uint64 sGetGL(char** s, CCryNameR& name, uint32& nHWFlags) -{ - uint32 i; - - nHWFlags = 0; - SShaderGenComb* c = NULL; - const char* m = strchr(name.c_str(), '@'); - if (!m) - { - m = strchr(name.c_str(), '/'); - } - assert(m); - if (!m) - { - return -1; - } - char nmFX[128]; - char nameExt[128]; - nameExt[0] = 0; - cry_strcpy(nmFX, name.c_str(), (size_t)(m - name.c_str())); - c = gRenDev->m_cEF.mfGetShaderGenInfo(nmFX); - if (!c || !c->pGen || !c->pGen->m_BitMask.Num()) - { - return 0; - } - uint64 nGL = 0; - SShaderGen* pG = c->pGen; - for (i = 0; i < pG->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = pG->m_BitMask[i]; - if (pBit->m_nDependencySet & (SHGD_HW_BILINEARFP16 | SHGD_HW_SEPARATEFP16)) - { - nHWFlags |= pBit->m_nDependencySet; - } - } - while (true) - { - char theChar; - int n = 0; - while ((theChar = **s) != 0) - { - if (theChar == ')' || theChar == '|') - { - nameExt[n] = 0; - break; - } - nameExt[n++] = theChar; - ++*s; - } - if (!nameExt[0]) - { - break; - } - for (i = 0; i < pG->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = pG->m_BitMask[i]; - if (!azstricmp(pBit->m_ParamName.c_str(), nameExt)) - { - nGL |= pBit->m_Mask; - break; - } - } - if (i == pG->m_BitMask.Num()) - { - if (!strncmp(nameExt, "0x", 2)) - { - //nGL |= shGetHex(&nameExt[2]); - } - else - { - //assert(0); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug) - { - iLog->Log("WARNING: Couldn't find global flag '%s' in shader '%s' (skipped)", nameExt, c->Name.c_str()); - } - } - } - if (**s == '|') - { - ++*s; - } - } - return nGL; -} - -static uint64 sGetFlag(char** s, SShaderGen* shaderGenInfo) -{ - if (!shaderGenInfo) - { - return 0; - } - - uint32 i = 0; - uint64 mask = 0; - char name[128] = {0}; - while (true) - { - char theChar; - int n = 0; - while ((theChar = **s) != 0) - { - if (theChar == ')' || theChar == '|') - { - name[n] = 0; - break; - } - name[n++] = theChar; - ++*s; - } - if (!name[0]) - { - break; - } - for (i = 0; i < shaderGenInfo->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = shaderGenInfo->m_BitMask[i]; - if (!azstricmp(pBit->m_ParamName.c_str(), name)) - { - mask |= pBit->m_Mask; - break; - } - } - - if (i == shaderGenInfo->m_BitMask.Num()) - { - AZ_Warning("ShaderCache", false, "Couldn't find runtime flag '%s' (skipped)", name); - } - - if (**s == '|') - { - ++*s; - } - } - return mask; -} - -static int sEOF(bool bFromFile, char* pPtr, AZ::IO::HandleType fileHandle) -{ - int nStatus; - if (bFromFile) - { - nStatus = gEnv->pCryPak->FEof(fileHandle); - } - else - { - SkipCharacters(&pPtr, kWhiteSpace); - if (!*pPtr) - { - nStatus = 1; - } - else - { - nStatus = 0; - } - } - return nStatus; -} - -void CShaderMan::mfCloseShadersCache(int nID) -{ - if (m_FPCacheCombinations[nID]) - { - gEnv->pCryPak->FClose(m_FPCacheCombinations[nID]); - m_FPCacheCombinations[nID] = 0; - } -} - -void sSkipLine(char*& s) -{ - if (!s) - { - return; - } - - char* sEnd = strchr(s, '\n'); - if (sEnd) - { - sEnd++; - s = sEnd; - } -} - -static void sIterateHW_r(FXShaderCacheCombinations* Combinations, SCacheCombination& cmb, int i, uint64 nHW, const char* szName) -{ - string str; - gRenDev->m_cEF.mfInsertNewCombination(cmb.Ident, cmb.eCL, szName, 0, &str, false); - CCryNameR nm = CCryNameR(str.c_str()); - FXShaderCacheCombinationsItor it = Combinations->find(nm); - if (it == Combinations->end()) - { - cmb.CacheName = str.c_str(); - Combinations->insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - } - for (int j = i; j < 64; j++) - { - if (((uint64)1 << j) & nHW) - { - cmb.Ident.m_GLMask &= ~((uint64)1 << j); - sIterateHW_r(Combinations, cmb, j + 1, nHW, szName); - cmb.Ident.m_GLMask |= ((uint64)1 << j); - sIterateHW_r(Combinations, cmb, j + 1, nHW, szName); - } - } -} - -void CShaderMan::mfGetShaderListPath(stack_string& nameOut, int nType) -{ - if (nType == 0) - { - nameOut = stack_string(m_szCachePath.c_str()) + stack_string("shaders/shaderlist.txt"); - } - else - { - nameOut = stack_string(m_szCachePath.c_str()) + stack_string("shaders/cache/shaderlistactivate.txt"); - } -} - -void CShaderMan::mfMergeShadersCombinations(FXShaderCacheCombinations* Combinations, int nType) -{ - FXShaderCacheCombinationsItor itor; - for (itor = m_ShaderCacheCombinations[nType].begin(); itor != m_ShaderCacheCombinations[nType].end(); itor++) - { - SCacheCombination* cmb = &itor->second; - FXShaderCacheCombinationsItor it = Combinations->find(cmb->CacheName); - if (it == Combinations->end()) - { - Combinations->insert(FXShaderCacheCombinationsItor::value_type(cmb->CacheName, *cmb)); - } - } -} - -//========================================================================================================================================== - -struct CompareCombItem -{ - bool operator()(const SCacheCombination& p1, const SCacheCombination& p2) const - { - int n = azstricmp(p1.Name.c_str(), p2.Name.c_str()); - if (n) - { - return n < 0; - } - n = p1.nCount - p2.nCount; - if (n) - { - return n > 0; - } - return (azstricmp(p1.CacheName.c_str(), p2.CacheName.c_str()) < 0); - } -}; - -#define g_szTestResults "TestResults" - -void CShaderMan::mfInitShadersCacheMissLog() -{ - m_ShaderCacheMissCallback = 0; - m_ShaderCacheMissPath = ""; - - // don't access the HD if we don't have any logging to file enabled - if (!CRenderer::CV_r_shaderslogcachemisses) - { - return; - } - - // create valid path - gEnv->pCryPak->MakeDir(g_szTestResults); - - m_ShaderCacheMissPath = string("@usercache@\\Shaders\\ShaderCacheMisses.txt"); // do we want this here, or maybe in @log@ ? - - // load data which is already stored - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - gEnv->pFileIO->Open(m_ShaderCacheMissPath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle); - if (fileHandle != AZ::IO::InvalidHandle) - { - char str[2048]; - int nLine = 0; - - while (!gEnv->pFileIO->Eof(fileHandle)) - { - nLine++; - str[0] = 0; - AZ::IO::FGetS(str, 2047, fileHandle); - if (!str[0]) - { - continue; - } - - // remove new line at end - int len = strlen(str); - if (len > 0) - { - str[strlen(str) - 1] = 0; - } - - m_ShaderCacheMisses.push_back(str); - } - - std::sort(m_ShaderCacheMisses.begin(), m_ShaderCacheMisses.end()); - - gEnv->pFileIO->Close(fileHandle); - fileHandle = AZ::IO::InvalidHandle; - } -} - -void CShaderMan::mfInitShadersCache(byte bForLevel, FXShaderCacheCombinations* Combinations, const char* pCombinations, int nType) -{ - COMPILE_TIME_ASSERT(SHADER_LIST_VER != SHADER_SERIALISE_VER); - - char str[2048]; - bool bFromFile = (Combinations == NULL); - stack_string nameComb; - m_ShaderCacheExportCombinations.clear(); - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - if (bFromFile) - { - if (!gRenDev->IsEditorMode() && !CRenderer::CV_r_shadersdebug && !gRenDev->IsShaderCacheGenMode()) - { - return; - } - mfGetShaderListPath(nameComb, nType); - fileHandle = gEnv->pCryPak->FOpen(nameComb.c_str(), "r+"); - if (fileHandle == AZ::IO::InvalidHandle) - { - fileHandle = gEnv->pCryPak->FOpen(nameComb.c_str(), "w+"); - } - if (fileHandle == AZ::IO::InvalidHandle) - { - AZ::IO::HandleType statusdstFileHandle = AZ::IO::InvalidHandle; - gEnv->pFileIO->Open(nameComb.c_str(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, statusdstFileHandle); - - if (statusdstFileHandle != AZ::IO::InvalidHandle) - { - gEnv->pFileIO->Close(statusdstFileHandle); - CrySetFileAttributes(str, FILE_ATTRIBUTE_ARCHIVE); - fileHandle = gEnv->pCryPak->FOpen(nameComb.c_str(), "r+"); - } - } - m_FPCacheCombinations[nType] = fileHandle; - Combinations = &m_ShaderCacheCombinations[nType]; - } - - int nLine = 0; - char* pPtr = (char*)pCombinations; - char* ss; - if (fileHandle != AZ::IO::InvalidHandle || !bFromFile) - { - while (!sEOF(bFromFile, pPtr, fileHandle)) - { - nLine++; - - str[0] = 0; - if (bFromFile) - { - gEnv->pCryPak->FGets(str, 2047, fileHandle); - } - else - { - fxFillCR(&pPtr, str); - } - if (!str[0]) - { - continue; - } - - if (str[0] == '/' && str[1] == '/') // commented line e.g. // BadLine: Metal@Common_ShadowPS(%BIllum@IlluminationPS(%DIFFUSE|%ENVCMAMB|%ALPHAGLOW|%STAT_BRANCHING)(%_RT_AMBIENT|%_RT_BUMP|%_RT_GLOW)(101)(0)(0)(ps_2_0) - { - continue; - } - - bool bExportEntry = false; - int size = strlen(str); - if (str[size - 1] == 0xa) - { - str[size - 1] = 0; - } - SCacheCombination cmb; - char* s = str; - SkipCharacters(&s, kWhiteSpace); - if (s[0] != '<') - { - continue; - } - char* st; - if (!bForLevel) - { - int nVer = atoi(&s[1]); - if (nVer != SHADER_LIST_VER) - { - if (nVer == SHADER_SERIALISE_VER && bFromFile) - { - bExportEntry = true; - } - else - { - continue; - } - } - if (s[2] != '>') - { - continue; - } - s += 3; - } - else - { - st = s; - s = strchr(&st[1], '>'); - if (!s) - { - continue; - } - cmb.nCount = atoi(st); - s++; - } - if (bForLevel == 2) - { - st = s; - if (s[0] != '<') - { - continue; - } - s = strchr(st, '>'); - if (!s) - { - continue; - } - int nVer = atoi(&st[1]); - - if (nVer != SHADER_LIST_VER) - { - if (nVer == SHADER_SERIALISE_VER) - { - bExportEntry = true; - } - else - { - continue; - } - } - s++; - } - st = s; - s = strchr(s, '('); - char name[128]; - if (s) - { - memcpy(name, st, s - st); - name[s - st] = 0; - cmb.Name = name; - s++; - } - else - { - continue; - } - uint32 nHW = 0; - cmb.Ident.m_GLMask = sGetGL(&s, cmb.Name, nHW); - if (cmb.Ident.m_GLMask == -1) - { - const char* szFileName = nameComb.c_str(); - if (szFileName) - { - iLog->Log("Error: Error in '%s' file (Line: %d)", szFileName, nLine); - } - else - { - assert(!bFromFile); - iLog->Log("Error: Error in non-file shader (Line: %d)", nLine); - } - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ++ss; - cmb.Ident.m_RTMask = sGetFlag(&s, gRenDev->m_cEF.m_pGlobalExt); - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ++ss; - cmb.Ident.m_LightMask = shGetHex(s); - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ++ss; - cmb.Ident.m_MDMask = shGetHex(s); - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ++ss; - cmb.Ident.m_MDVMask = shGetHex(s); - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ss + 1; - cmb.Ident.m_pipelineState.opaque = shGetHex64(s); - - ss = strchr(s, '('); - if (!ss) - { - sSkipLine(s); - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - return; - } - s = ss + 1; - cmb.Ident.m_STMask = sGetFlag(&s, gRenDev->m_cEF.m_staticExt); - - s = strchr(s, '('); - if (s) - { - s++; - cmb.eCL = CHWShader::mfStringClass(s); - assert (cmb.eCL < eHWSC_Num); - } - else - { - cmb.eCL = eHWSC_Num; - } - if constexpr (true || cmb.eCL < eHWSC_Num) - { - CCryNameR nm = CCryNameR(st); - if (bExportEntry) - { - FXShaderCacheCombinationsItor it = m_ShaderCacheExportCombinations.find(nm); - if (it == m_ShaderCacheExportCombinations.end()) - { - cmb.CacheName = nm; - m_ShaderCacheExportCombinations.insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - } - } - else - { - FXShaderCacheCombinationsItor it = Combinations->find(nm); - if (it != Combinations->end()) - { - //assert(false); - } - else - { - cmb.CacheName = nm; - Combinations->insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - } - if (nHW) - { - for (int j = 0; j < 64; j++) - { - if (((uint64)1 << j) & nHW) - { - cmb.Ident.m_GLMask &= ~((uint64)1 << j); - sIterateHW_r(Combinations, cmb, j + 1, nHW, name); - cmb.Ident.m_GLMask |= ((uint64)1 << j); - sIterateHW_r(Combinations, cmb, j + 1, nHW, name); - cmb.Ident.m_GLMask &= ~((uint64)1 << j); - } - } - } - } - } - else - { - iLog->Log("Error: Error in '%s' file (Line: %d)", nameComb.c_str(), nLine); - } - } - } -} - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) -static void sResetDepend_r(SShaderGen* pGen, SShaderGenBit* pBit, SCacheCombination& cm) -{ - if (!pBit->m_DependResets.size()) - { - return; - } - uint32 i, j; - - for (i = 0; i < pBit->m_DependResets.size(); i++) - { - const char* c = pBit->m_DependResets[i].c_str(); - for (j = 0; j < pGen->m_BitMask.Num(); j++) - { - SShaderGenBit* pBit1 = pGen->m_BitMask[j]; - if (!azstricmp(pBit1->m_ParamName.c_str(), c)) - { - cm.Ident.m_RTMask &= ~pBit1->m_Mask; - sResetDepend_r(pGen, pBit1, cm); - break; - } - } - } -} - -static void sSetDepend_r(SShaderGen* pGen, SShaderGenBit* pBit, SCacheCombination& cm) -{ - if (!pBit->m_DependSets.size()) - { - return; - } - uint32 i, j; - - for (i = 0; i < pBit->m_DependSets.size(); i++) - { - const char* c = pBit->m_DependSets[i].c_str(); - for (j = 0; j < pGen->m_BitMask.Num(); j++) - { - SShaderGenBit* pBit1 = pGen->m_BitMask[j]; - if (!azstricmp(pBit1->m_ParamName.c_str(), c)) - { - cm.Ident.m_RTMask |= pBit1->m_Mask; - sSetDepend_r(pGen, pBit1, cm); - break; - } - } - } -} - -// Support for single light only -static bool sIterateDL(DWORD& dwDL) -{ - int nLights = dwDL & 0xf; - int nType[4]; - int i; - - if (!nLights) - { - dwDL = 1; - return true; - } - for (i = 0; i < nLights; i++) - { - nType[i] = (dwDL >> (SLMF_LTYPE_SHIFT + (i * SLMF_LTYPE_BITS))) & ((1 << SLMF_LTYPE_BITS) - 1); - } - switch (nLights) - { - case 1: - if ((nType[0] & 3) < 2) - { - nType[0]++; - } - else - { - return false; - } - break; - case 2: - if ((nType[0] & 3) == SLMF_DIRECT) - { - nType[0] = SLMF_POINT; - nType[1] = SLMF_POINT; - } - else - { - nLights = 3; - nType[0] = SLMF_DIRECT; - nType[1] = SLMF_POINT; - nType[2] = SLMF_POINT; - } - break; - case 3: - if ((nType[0] & 3) == SLMF_DIRECT) - { - nType[0] = SLMF_POINT; - nType[1] = SLMF_POINT; - nType[2] = SLMF_POINT; - } - else - { - nLights = 4; - nType[0] = SLMF_DIRECT; - nType[1] = SLMF_POINT; - nType[2] = SLMF_POINT; - nType[3] = SLMF_POINT; - } - break; - case 4: - if ((nType[0] & 3) == SLMF_DIRECT) - { - nType[0] = SLMF_POINT; - nType[1] = SLMF_POINT; - nType[2] = SLMF_POINT; - nType[3] = SLMF_POINT; - } - else - { - return false; - } - } - dwDL = nLights; - for (i = 0; i < nLights; i++) - { - dwDL |= nType[i] << (SLMF_LTYPE_SHIFT + i * SLMF_LTYPE_BITS); - } - return true; -} - -/*static bool sIterateDL(DWORD& dwDL) -{ - int nLights = dwDL & 0xf; - int nType[4]; - int i; - - if (!nLights) - { - dwDL = 1; - return true; - } - for (i=0; i> (SLMF_LTYPE_SHIFT + (i*SLMF_LTYPE_BITS))) & ((1<CacheName.c_str(), ')'); - c = strchr(&c[1], ')'); - int len = (int)(c - cmb->CacheName.c_str() + 1); - assert(len < sizeof(str)); - cry_strcpy(str, cmb->CacheName.c_str(), len); - cry_strcat(str, "("); - azsprintf(sLT, "%x", (uint32)dwL); - cry_strcat(str, sLT); - c = strchr(&c[2], ')'); - cry_strcat(str, c); - CCryNameR nm = CCryNameR(str); - cm.CacheName = nm; - FXShaderCacheCombinationsItor it = CmbsMapDst.find(nm); - if (it == CmbsMapDst.end()) - { - CmbsMapDst.insert(FXShaderCacheCombinationsItor::value_type(nm, cm)); - } -} - -void CShaderMan::mfAddLTCombinations(SCacheCombination* cmb, FXShaderCacheCombinations& CmbsMapDst) -{ - if (!CRenderer::CV_r_shadersprecachealllights) - { - return; - } - - DWORD dwL = 0; // 0 lights - bool bRes = false; - do - { - // !HACK: Do not iterate multiple lights for low spec - if ((cmb->Ident.m_RTMask & (g_HWSR_MaskBit[HWSR_QUALITY] | g_HWSR_MaskBit[HWSR_QUALITY1])) || (dwL & 0xf) <= 1) - { - mfAddLTCombination(cmb, CmbsMapDst, dwL); - } - bRes = sIterateDL(dwL); - } while (bRes); -} - - -void CShaderMan::mfAddRTCombination_r(int nComb, FXShaderCacheCombinations& CmbsMapDst, SCacheCombination* cmb, CHWShader* pSH, bool bAutoPrecache) -{ - uint32 i, j, n; - uint32 dwType = pSH->m_dwShaderType; - if (!dwType) - { - return; - } - for (i = nComb; i < m_pGlobalExt->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = m_pGlobalExt->m_BitMask[i]; - if (bAutoPrecache && !(pBit->m_Flags & (SHGF_AUTO_PRECACHE | SHGF_LOWSPEC_AUTO_PRECACHE))) - { - continue; - } - - // Precache this flag on low-spec only - if (pBit->m_Flags & SHGF_LOWSPEC_AUTO_PRECACHE) - { - if (cmb->Ident.m_RTMask & (g_HWSR_MaskBit[HWSR_QUALITY] | g_HWSR_MaskBit[HWSR_QUALITY1])) - { - continue; - } - } - // Only in runtime used - if (pBit->m_Flags & SHGF_RUNTIME) - { - continue; - } - for (n = 0; n < pBit->m_PrecacheNames.size(); n++) - { - if (pBit->m_PrecacheNames[n] == dwType) - { - break; - } - } - if (n < pBit->m_PrecacheNames.size()) - { - SCacheCombination cm; - cm = *cmb; - cm.Ident.m_RTMask &= ~pBit->m_Mask; - cm.Ident.m_RTMask |= (pBit->m_Mask ^ cmb->Ident.m_RTMask) & pBit->m_Mask; - if (!bAutoPrecache) - { - uint64 nBitSet = pBit->m_Mask & cmb->Ident.m_RTMask; - if (nBitSet) - { - sSetDepend_r(m_pGlobalExt, pBit, cm); - } - else - { - sResetDepend_r(m_pGlobalExt, pBit, cm); - } - } - - char str[1024]; - const char* c = strchr(cmb->CacheName.c_str(), '('); - const size_t len = (size_t)(c - cmb->CacheName.c_str()); - cry_strcpy(str, cmb->CacheName.c_str(), len); - const char* c1 = strchr(&c[1], '('); - cry_strcat(str, c, (size_t)(c1 - c)); - cry_strcat(str, "("); - SShaderGen* pG = m_pGlobalExt; - stack_string sRT; - for (j = 0; j < pG->m_BitMask.Num(); j++) - { - SShaderGenBit* pBit2 = pG->m_BitMask[j]; - if (pBit2->m_Mask & cm.Ident.m_RTMask) - { - if (!sRT.empty()) - { - sRT += "|"; - } - sRT += pBit2->m_ParamName.c_str(); - } - } - cry_strcat(str, sRT.c_str()); - c1 = strchr(&c1[1], ')'); - cry_strcat(str, c1); - CCryNameR nm = CCryNameR(str); - cm.CacheName = nm; - // HACK: don't allow unsupported quality mode - uint64 nQMask = g_HWSR_MaskBit[HWSR_QUALITY] | g_HWSR_MaskBit[HWSR_QUALITY1]; - if ((cm.Ident.m_RTMask & nQMask) != nQMask) - { - FXShaderCacheCombinationsItor it = CmbsMapDst.find(nm); - if (it == CmbsMapDst.end()) - { - CmbsMapDst.insert(FXShaderCacheCombinationsItor::value_type(nm, cm)); - } - } - if (pSH->m_Flags & (HWSG_SUPPORTS_MULTILIGHTS | HWSG_SUPPORTS_LIGHTING)) - { - mfAddLTCombinations(&cm, CmbsMapDst); - } - mfAddRTCombination_r(i + 1, CmbsMapDst, &cm, pSH, bAutoPrecache); - } - } -} - -void CShaderMan::mfAddRTCombinations(FXShaderCacheCombinations& CmbsMapSrc, FXShaderCacheCombinations& CmbsMapDst, CHWShader* pSH, bool bListOnly) -{ - if (pSH->m_nFrameLoad == gRenDev->GetFrameID()) - { - return; - } - pSH->m_nFrameLoad = gRenDev->GetFrameID(); - uint32 dwType = pSH->m_dwShaderType; - if (!dwType) - { - return; - } - const char* str2 = pSH->mfGetEntryName(); - FXShaderCacheCombinationsItor itor; - for (itor = CmbsMapSrc.begin(); itor != CmbsMapSrc.end(); itor++) - { - SCacheCombination* cmb = &itor->second; - const char* c = strchr(cmb->Name.c_str(), '@'); - if (!c) - { - c = strchr(cmb->Name.c_str(), '/'); - } - assert(c); - if (!c) - { - continue; - } - if (azstricmp(&c[1], str2)) - { - continue; - } - /*if (!azstricmp(str2, "MetalReflVS")) - { - if (cmb->nGL == 0x1093) - { - int nnn = 0; - } - }*/ - if (bListOnly) - { - if (pSH->m_Flags & (HWSG_SUPPORTS_MULTILIGHTS | HWSG_SUPPORTS_LIGHTING)) - { - mfAddLTCombinations(cmb, CmbsMapDst); - } - mfAddRTCombination_r(0, CmbsMapDst, cmb, pSH, true); - } - else - { - mfAddRTCombination_r(0, CmbsMapDst, cmb, pSH, false); - } - } -} -#endif // CONSOLE - -void GenerateMaskString(SShaderGen* shaderInfo, uint64 mask, stack_string& maskStr) -{ - if (!shaderInfo || !mask) - { - return; - } - - for (unsigned i = 0; i < shaderInfo->m_BitMask.Num(); ++i) - { - SShaderGenBit* pBit = shaderInfo->m_BitMask[i]; - if (pBit->m_Mask & mask) - { - if (!maskStr.empty()) - { - maskStr += "|"; - } - maskStr += pBit->m_ParamName.c_str(); - } - } -} - - -void CShaderMan::mfInsertNewCombination(SShaderCombIdent& Ident, EHWShaderClass eCL, const char* name, int nID, string* Str, byte bStore) -{ - char str[2048]; - if (!m_FPCacheCombinations[nID] && bStore) - { - return; - } - - stack_string sGL; - stack_string sRT; - stack_string staticMask; - uint32 i, j; - SShaderGenComb* c = NULL; - if (Ident.m_GLMask) - { - const char* m = strchr(name, '@'); - if (!m) - { - m = strchr(name, '/'); - } - assert(m); - char nmFX[128]; - if (m) - { - cry_strcpy(nmFX, name, (size_t)(m - name)); - c = mfGetShaderGenInfo(nmFX); - if (c && c->pGen && c->pGen->m_BitMask.Num()) - { - SShaderGen* pG = c->pGen; - for (i = 0; i < 64; i++) - { - if (Ident.m_GLMask & ((uint64)1 << i)) - { - for (j = 0; j < pG->m_BitMask.Num(); j++) - { - SShaderGenBit* pBit = pG->m_BitMask[j]; - if (pBit->m_Mask & (Ident.m_GLMask & ((uint64)1 << i))) - { - if (!sGL.empty()) - { - sGL += "|"; - } - sGL += pBit->m_ParamName.c_str(); - break; - } - } - } - } - } - } - } - - GenerateMaskString(m_pGlobalExt, Ident.m_RTMask, sRT); - GenerateMaskString(m_staticExt, Ident.m_STMask, staticMask); - - uint32 nLT = Ident.m_LightMask; - if (bStore == 1 && Ident.m_LightMask) - { - nLT = 1; - } - azsprintf(str, "<%d>%s(%s)(%s)(%x)(%x)(%x)(%llx)(%s)(%s)", SHADER_LIST_VER, name, sGL.c_str(), sRT.c_str(), nLT, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_pipelineState.opaque, staticMask.c_str(), CHWShader::mfClassString(eCL)); - if (!bStore) - { - if (Str) - { - *Str = str; - } - return; - } - CCryNameR nm; - if (str[0] == '<' && str[2] == '>') - { - nm = CCryNameR(&str[3]); - } - else - { - nm = CCryNameR(str); - } - FXShaderCacheCombinationsItor it = m_ShaderCacheCombinations[nID].find(nm); - if (it != m_ShaderCacheCombinations[nID].end()) - { - return; - } - SCacheCombination cmb; - cmb.Name = name; - cmb.CacheName = nm; - cmb.Ident = Ident; - cmb.eCL = eCL; - { - stack_string nameOut; - mfGetShaderListPath(nameOut, nID); - - static CryCriticalSection s_cResLock; - AUTO_LOCK(s_cResLock); // Not thread safe without this - - if (m_FPCacheCombinations[nID]) - { - m_ShaderCacheCombinations[nID].insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - gEnv->pCryPak->FPrintf(m_FPCacheCombinations[nID], "%s\n", str); - gEnv->pCryPak->FFlush(m_FPCacheCombinations[nID]); - } - } - if (Str) - { - *Str = str; - } -} - -inline bool sCompareComb(const SCacheCombination& a, const SCacheCombination& b) -{ - int32 dif; - - char shader1[128], shader2[128]; - char* tech1 = NULL, * tech2 = NULL; - azstrcpy(shader1, 128, a.Name.c_str()); - azstrcpy(shader2, 128, b.Name.c_str()); - char* c = strchr(shader1, '@'); - if (!c) - { - c = strchr(shader1, '/'); - } - //assert(c); - if (c) - { - *c = 0; - tech1 = c + 1; - } - c = strchr(shader2, '@'); - if (!c) - { - c = strchr(shader2, '/'); - } - //assert(c); - if (c) - { - *c = 0; - tech2 = c + 1; - } - - dif = azstricmp(shader1, shader2); - if (dif != 0) - { - return dif < 0; - } - - if (tech1 == NULL && tech2 != NULL) - { - return true; - } - if (tech1 != NULL && tech2 == NULL) - { - return false; - } - - if (tech1 != NULL && tech2 != NULL) - { - dif = azstricmp(tech1, tech2); - if (dif != 0) - { - return dif < 0; - } - } - - if (a.Ident.m_GLMask != b.Ident.m_GLMask) - { - return a.Ident.m_GLMask < b.Ident.m_GLMask; - } - - if (a.Ident.m_STMask != b.Ident.m_STMask) - { - return a.Ident.m_STMask < b.Ident.m_STMask; - } - - if (a.Ident.m_RTMask != b.Ident.m_RTMask) - { - return a.Ident.m_RTMask < b.Ident.m_RTMask; - } - - if (a.Ident.m_pipelineState.opaque != b.Ident.m_pipelineState.opaque) - { - return a.Ident.m_pipelineState.opaque < b.Ident.m_pipelineState.opaque; - } - - if (a.Ident.m_FastCompare1 != b.Ident.m_FastCompare1) - { - return a.Ident.m_FastCompare1 < b.Ident.m_FastCompare1; - } - - if (a.Ident.m_FastCompare2 != b.Ident.m_FastCompare2) - { - return a.Ident.m_FastCompare2 < b.Ident.m_FastCompare2; - } - - return false; -} - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - -void CShaderMan::AddGLCombinations(CShader* pSH, std::vector& CmbsGL) -{ - int i, j; - uint64 nMask = 0; - if (pSH->m_pGenShader) - { - SShaderGen* pG = pSH->m_pGenShader->m_ShaderGenParams; - for (i = 0; i < pG->m_BitMask.size(); i++) - { - SShaderGenBit* pB = pG->m_BitMask[i]; - SCacheCombination cc; - cc.Name = pB->m_ParamName; - for (j = 0; j < m_pGlobalExt->m_BitMask.size(); j++) - { - SShaderGenBit* pB1 = m_pGlobalExt->m_BitMask[j]; - if (pB1->m_ParamName == pB->m_ParamName) - { - nMask |= pB1->m_Mask; - break; - } - } - } - } - else - { - SCacheCombination cc; - cc.Ident.m_GLMask = 0; - CmbsGL.push_back(cc); - } -} - -void CShaderMan::AddGLCombination(FXShaderCacheCombinations& CmbsMap, SCacheCombination& cmb) -{ - char str[1024]; - const char* st = cmb.CacheName.c_str(); - if (st[0] == '<') - { - st += 3; - } - const char* s = strchr(st, '@'); - char name[128]; - if (!s) - { - s = strchr(st, '/'); - } - if (s) - { - memcpy(name, st, s - st); - name[s - st] = 0; - } - else - { - azstrcpy(name, 128, st); - } -#ifdef __GNUC__ - sprintf(str, "%s(%llx)(%x)(%x)", name, cmb.Ident.m_GLMask, cmb.Ident.m_MDMask, cmb.Ident.m_MDVMask); -#else - azsprintf(str, "%s(%I64x)(%x)(%x)", name, cmb.Ident.m_GLMask, cmb.Ident.m_MDMask, cmb.Ident.m_MDVMask); -#endif - CCryNameR nm = CCryNameR(str); - FXShaderCacheCombinationsItor it = CmbsMap.find(nm); - if (it == CmbsMap.end()) - { - cmb.CacheName = nm; - cmb.Name = nm; - CmbsMap.insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - } -} - -void CShaderMan::AddCombination(SCacheCombination& cmb, FXShaderCacheCombinations& CmbsMap, [[maybe_unused]] CHWShader* pHWS) -{ - char str[2048]; - azsprintf(str, "%s(%llx)(%llx)(%d)(%d)(%d)(%llx)(%llx)", cmb.Name.c_str(), cmb.Ident.m_GLMask, cmb.Ident.m_RTMask, cmb.Ident.m_LightMask, cmb.Ident.m_MDMask, cmb.Ident.m_MDVMask, cmb.Ident.m_pipelineState.opaque, cmb.Ident.m_STMask); - CCryNameR nm = CCryNameR(str); - FXShaderCacheCombinationsItor it = CmbsMap.find(nm); - if (it == CmbsMap.end()) - { - cmb.CacheName = nm; - CmbsMap.insert(FXShaderCacheCombinationsItor::value_type(nm, cmb)); - } -} - -void CShaderMan::AddLTCombinations(SCacheCombination& cmb, FXShaderCacheCombinations& CmbsMap, CHWShader* pHWS) -{ - assert(pHWS->m_Flags & HWSG_SUPPORTS_LIGHTING); - - // Just single light support - - // Directional light - cmb.Ident.m_LightMask = 1; - AddCombination(cmb, CmbsMap, pHWS); - - // Point light - cmb.Ident.m_LightMask = 0x101; - AddCombination(cmb, CmbsMap, pHWS); - - // Projected light - cmb.Ident.m_LightMask = 0x201; - AddCombination(cmb, CmbsMap, pHWS); -} - -void CShaderMan::AddRTCombinations(FXShaderCacheCombinations& CmbsMap, CHWShader* pHWS, CShader* pSH, FXShaderCacheCombinations* Combinations) -{ - SCacheCombination cmb; - - uint32 nType = pHWS->m_dwShaderType; - - uint32 i, j; - SShaderGen* pGen = m_pGlobalExt; - int nBits = 0; - - uint32 nBitsPlatform = 0; - if (CParserBin::m_nPlatform == SF_ORBIS) - { - nBitsPlatform |= SHGD_HW_ORBIS; - } - else - if (CParserBin::m_nPlatform == SF_D3D11) - { - nBitsPlatform |= SHGD_HW_DX11; - } - else - if (CParserBin::m_nPlatform == SF_GL4) - { - nBitsPlatform |= SHGD_HW_GL4; - } - else - if (CParserBin::m_nPlatform == SF_GLES3) - { - nBitsPlatform |= SHGD_HW_GLES3; - } - // Confetti Nicholas Baldwin: adding metal shader language support - else - if (CParserBin::m_nPlatform == SF_METAL) - { - nBitsPlatform |= SHGD_HW_METAL; - } - - uint64 BitMask[64]; - memset(BitMask, 0, sizeof(BitMask)); - - // Make a mask of flags affected by this type of shader - uint64 nRTMask = 0; - uint64 nSetMask = 0; - - if (nType) - { - for (i = 0; i < pGen->m_BitMask.size(); i++) - { - SShaderGenBit* pBit = pGen->m_BitMask[i]; - if (!pBit->m_Mask) - { - continue; - } - if (pBit->m_Flags & SHGF_RUNTIME) - { - continue; - } - if (nBitsPlatform & pBit->m_nDependencyReset) - { - continue; - } - for (j = 0; j < pBit->m_PrecacheNames.size(); j++) - { - if (pBit->m_PrecacheNames[j] == nType) - { - if (nBitsPlatform & pBit->m_nDependencySet) - { - nSetMask |= pBit->m_Mask; - continue; - } - BitMask[nBits++] = pBit->m_Mask; - nRTMask |= pBit->m_Mask; - break; - } - } - } - } - if (nBits > 10) - { - CryLog("WARNING: Number of runtime bits for shader '%s' - %d: exceed 10 (too many combinations will be produced)...", pHWS->GetName(), nBits); - } - if (nBits > 30) - { - CryLog("Error: Ignore..."); - return; - } - - cmb.eCL = pHWS->m_eSHClass; - string szName = string(pSH->GetName()); - szName += string("@") + string(pHWS->m_EntryFunc.c_str()); - cmb.Name = szName; - cmb.Ident.m_GLMask = pHWS->m_nMaskGenShader; - - // For unknown shader type just add combinations from the list - if (!nType) - { - FXShaderCacheCombinationsItor itor; - for (itor = Combinations->begin(); itor != Combinations->end(); itor++) - { - SCacheCombination* c = &itor->second; - if (c->Name == cmb.Name && c->Ident.m_GLMask == pHWS->m_nMaskGenFX) - { - cmb = *c; - AddCombination(cmb, CmbsMap, pHWS); - } - } - return; - } - - cmb.Ident.m_LightMask = 0; - cmb.Ident.m_MDMask = 0; - cmb.Ident.m_MDVMask = 0; - cmb.Ident.m_RTMask = 0; - cmb.Ident.m_STMask = 0; - - int nIterations = 1 << nBits; - for (i = 0; i < nIterations; i++) - { - cmb.Ident.m_RTMask = nSetMask; - cmb.Ident.m_LightMask = 0; - for (j = 0; j < nBits; j++) - { - if ((1 << j) & i) - { - cmb.Ident.m_RTMask |= BitMask[j]; - } - } - /*if (cmb.nRT == 0x40002) - { - int nnn = 0; - }*/ - AddCombination(cmb, CmbsMap, pHWS); - if (pHWS->m_Flags & HWSG_SUPPORTS_LIGHTING) - { - AddLTCombinations(cmb, CmbsMap, pHWS); - } - } -} - -void CShaderMan::_PrecacheShaderList(bool bStatsOnly) -{ - float t0 = gEnv->pTimer->GetAsyncCurTime(); - - if (!m_pGlobalExt) - { - return; - } - - m_eCacheMode = eSC_BuildGlobalList; - - uint32 nSaveFeatures = gRenDev->m_Features; - int nAsync = CRenderer::CV_r_shadersasynccompiling; - if (nAsync != 3) - { - CRenderer::CV_r_shadersasynccompiling = 0; - } - - // Command line shaders precaching - gRenDev->m_Features |= RFT_HW_SM20 | RFT_HW_SM2X | RFT_HW_SM30; - m_bActivatePhase = false; - FXShaderCacheCombinations* Combinations = &m_ShaderCacheCombinations[0]; - - std::vector Cmbs; - std::vector CmbsRT; - FXShaderCacheCombinations CmbsMap; - char str1[128], str2[128]; - - // Extract global combinations only (including MD and MDV) - for (FXShaderCacheCombinationsItor itor = Combinations->begin(); itor != Combinations->end(); itor++) - { - SCacheCombination* cmb = &itor->second; - FXShaderCacheCombinationsItor it = CmbsMap.find(cmb->CacheName); - if (it == CmbsMap.end()) - { - CmbsMap.insert(FXShaderCacheCombinationsItor::value_type(cmb->CacheName, *cmb)); - } - } - for (FXShaderCacheCombinationsItor itor = CmbsMap.begin(); itor != CmbsMap.end(); itor++) - { - SCacheCombination* cmb = &itor->second; - Cmbs.push_back(*cmb); - } - - mfExportShaders(); - - int nEmpty = 0; - int nProcessed = 0; - int nCompiled = 0; - int nMaterialCombinations = 0; - - if (Cmbs.size() >= 1) - { - std::stable_sort(Cmbs.begin(), Cmbs.end(), sCompareComb); - - nMaterialCombinations = Cmbs.size(); - - m_nCombinationsProcess = Cmbs.size(); - m_bReload = true; - m_nCombinationsCompiled = 0; - m_nCombinationsEmpty = 0; - for (int i = 0; i < Cmbs.size(); i++) - { - SCacheCombination* cmb = &Cmbs[i]; - azstrcpy(str1, 128, cmb->Name.c_str()); - char* c = strchr(str1, '@'); - if (!c) - { - c = strchr(str1, '/'); - } - //assert(c); - if (c) - { - *c = 0; - m_szShaderPrecache = &c[1]; - } - else - { - c = strchr(str1, '('); - if (c) - { - *c = 0; - m_szShaderPrecache = ""; - } - } - gRenDev->m_RP.m_FlagsShader_RT = 0; - gRenDev->m_RP.m_FlagsShader_LT = 0; - gRenDev->m_RP.m_FlagsShader_MD = 0; - gRenDev->m_RP.m_FlagsShader_MDV = 0; - m_staticFlags = cmb->Ident.m_STMask; - CShader* pSH = CShaderMan::mfForName(str1, 0, NULL, cmb->Ident.m_GLMask); - - gRenDev->m_RP.m_pShader = pSH; - assert(gRenDev->m_RP.m_pShader != 0); - - std::vector* pCmbs = &Cmbs; - FXShaderCacheCombinations CmbsMapRTSrc; - FXShaderCacheCombinations CmbsMapRTDst; - - for (int m = 0; m < pSH->m_HWTechniques.Num(); m++) - { - SShaderTechnique* pTech = pSH->m_HWTechniques[m]; - for (int n = 0; n < pTech->m_Passes.Num(); n++) - { - SShaderPass* pPass = &pTech->m_Passes[n]; - if (pPass->m_PShader) - { - pPass->m_PShader->m_nFrameLoad = -10; - } - if (pPass->m_VShader) - { - pPass->m_VShader->m_nFrameLoad = -10; - } - } - } - - for (; i < Cmbs.size(); i++) - { - SCacheCombination* cmba = &Cmbs[i]; - azstrcpy(str2, 128, cmba->Name.c_str()); - c = strchr(str2, '@'); - if (!c) - { - c = strchr(str2, '/'); - } - assert(c); - if (c) - { - *c = 0; - } - if (azstricmp(str1, str2) || cmb->Ident.m_GLMask != cmba->Ident.m_GLMask || cmb->Ident.m_STMask != cmba->Ident.m_STMask) - { - break; - } - CmbsMapRTSrc.insert(FXShaderCacheCombinationsItor::value_type(cmba->CacheName, *cmba)); - } - // surrounding for(;;i++) will increment this again - i--; - m_nCombinationsProcess -= CmbsMapRTSrc.size(); - - for (FXShaderCacheCombinationsItor itor = CmbsMapRTSrc.begin(); itor != CmbsMapRTSrc.end(); itor++) - { - SCacheCombination* cmb2 = &itor->second; - azstrcpy(str2, 128, cmb2->Name.c_str()); - FXShaderCacheCombinationsItor it = CmbsMapRTDst.find(cmb2->CacheName); - if (it == CmbsMapRTDst.end()) - { - CmbsMapRTDst.insert(FXShaderCacheCombinationsItor::value_type(cmb2->CacheName, *cmb2)); - } - } - - for (int m = 0; m < pSH->m_HWTechniques.Num(); m++) - { - SShaderTechnique* pTech = pSH->m_HWTechniques[m]; - for (int n = 0; n < pTech->m_Passes.Num(); n++) - { - SShaderPass* pPass = &pTech->m_Passes[n]; - if (pPass->m_PShader) - { - mfAddRTCombinations(CmbsMapRTSrc, CmbsMapRTDst, pPass->m_PShader, true); - } - if (pPass->m_VShader) - { - mfAddRTCombinations(CmbsMapRTSrc, CmbsMapRTDst, pPass->m_VShader, true); - } - } - } - - CmbsRT.clear(); - for (FXShaderCacheCombinationsItor itor = CmbsMapRTDst.begin(); itor != CmbsMapRTDst.end(); itor++) - { - SCacheCombination* cmb2 = &itor->second; - CmbsRT.push_back(*cmb2); - } - pCmbs = &CmbsRT; - m_nCombinationsProcessOverall = CmbsRT.size(); - m_nCombinationsProcess = 0; - - CmbsMapRTDst.clear(); - CmbsMapRTSrc.clear(); - uint32 nFlags = HWSF_PRECACHE | HWSF_STOREDATA; - if (bStatsOnly) - { - nFlags |= HWSF_FAKE; - } - for (int jj = 0; jj < pCmbs->size(); jj++) - { - m_nCombinationsProcess++; - SCacheCombination* cmba = &(*pCmbs)[jj]; - c = (char*)strchr(cmba->Name.c_str(), '@'); - if (!c) - { - c = (char*)strchr(cmba->Name.c_str(), '/'); - } - assert(c); - if (!c) - { - continue; - } - m_szShaderPrecache = &c[1]; - for (int m = 0; m < pSH->m_HWTechniques.Num(); m++) - { - SShaderTechnique* pTech = pSH->m_HWTechniques[m]; - for (int n = 0; n < pTech->m_Passes.Num(); n++) - { - SShaderPass* pPass = &pTech->m_Passes[n]; - gRenDev->m_RP.m_FlagsShader_RT = cmba->Ident.m_RTMask; - gRenDev->m_RP.m_FlagsShader_LT = cmba->Ident.m_LightMask; - gRenDev->m_RP.m_FlagsShader_MD = cmba->Ident.m_MDMask; - gRenDev->m_RP.m_FlagsShader_MDV = cmba->Ident.m_MDVMask; - // Adjust some flags for low spec - CHWShader* shaders[] = { pPass->m_PShader, pPass->m_VShader }; - for (int i2 = 0; i2 < 2; i2++) - { - CHWShader* shader = shaders[i2]; - if (shader && (!m_szShaderPrecache || !azstricmp(m_szShaderPrecache, shader->m_EntryFunc.c_str()) != 0)) - { - uint64 nFlagsOrigShader_RT = gRenDev->m_RP.m_FlagsShader_RT & shader->m_nMaskAnd_RT | shader->m_nMaskOr_RT; - uint64 nFlagsOrigShader_GL = shader->m_nMaskGenShader; - uint32 nFlagsOrigShader_LT = gRenDev->m_RP.m_FlagsShader_LT; - - shader->mfSetV(nFlags); - - if (nFlagsOrigShader_RT != gRenDev->m_RP.m_FlagsShader_RT || nFlagsOrigShader_GL != shader->m_nMaskGenShader || nFlagsOrigShader_LT != gRenDev->m_RP.m_FlagsShader_LT) - { - m_nCombinationsEmpty++; - if (!bStatsOnly) - { - shader->mfAddEmptyCombination(pSH, nFlagsOrigShader_RT, nFlagsOrigShader_GL, nFlagsOrigShader_LT); - } - shader->m_nMaskGenShader = nFlagsOrigShader_GL; - } - } - } - - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_GL4) - { - CHWShader* d3d11Shaders[] = { pPass->m_GShader, pPass->m_HShader, pPass->m_CShader, pPass->m_DShader }; - for (int i2 = 0; i2 < 4; i2++) - { - CHWShader* shader = d3d11Shaders[i2]; - if (shader && (!m_szShaderPrecache || !azstricmp(m_szShaderPrecache, shader->m_EntryFunc.c_str()) != 0)) - { - shader->mfSetV(nFlags); - } - } - } - - if (bStatsOnly) - { - static int nLastCombs = 0; - if (m_nCombinationsCompiled != nLastCombs && !(m_nCombinationsCompiled & 0x7f)) - { - nLastCombs = m_nCombinationsCompiled; - CryLog("-- Processed: %d, Compiled: %d, Referenced (Empty): %d...", m_nCombinationsProcess, m_nCombinationsCompiled, m_nCombinationsEmpty); - } - } -#ifdef WIN32 - if (!m_bActivatePhase) - { - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - } -#endif - } - } - pSH->mfFlushPendedShaders(); - iLog->Update(); - IRenderer* pRenderer = gEnv->pRenderer; - if (pRenderer) - { - pRenderer->FlushRTCommands(true, true, true); - } - } - - pSH->mfFlushCache(); - - // HACK HACK HACK: - // should be bigger than 0, but could cause issues right now when checking for RT - // combinations when no shadertype is defined and the previous shader line - // was still async compiling -- needs fix in HWShader for m_nMaskGenFX - CHWShader::mfFlushPendedShadersWait(0); - if (!m_bActivatePhase) - { - SAFE_RELEASE(pSH); - } - - nProcessed += m_nCombinationsProcess; - nCompiled += m_nCombinationsCompiled; - nEmpty += m_nCombinationsEmpty; - - m_nCombinationsProcess = 0; - m_nCombinationsCompiled = 0; - m_nCombinationsEmpty = 0; - } - } - CHWShader::mfFlushPendedShadersWait(-1); - - - // Optimise shader resources - SOptimiseStats Stats; - for (FXShaderCacheNamesItor it = CHWShader::m_ShaderCacheList.begin(); it != CHWShader::m_ShaderCacheList.end(); it++) - { - const char* szName = it->first.c_str(); - SShaderCache* c = CHWShader::mfInitCache(szName, NULL, false, it->second, false); - if (c) - { - SOptimiseStats _Stats; - CHWShader::mfOptimiseCacheFile(c, false, &_Stats); - Stats.nEntries += _Stats.nEntries; - Stats.nUniqueEntries += _Stats.nUniqueEntries; - Stats.nSizeCompressed += _Stats.nSizeCompressed; - Stats.nSizeUncompressed += _Stats.nSizeUncompressed; - Stats.nTokenDataSize += _Stats.nTokenDataSize; - } - c->Release(); - } - - CHWShader::m_ShaderCacheList.clear(); - - m_eCacheMode = eSC_Normal; - m_bReload = false; - m_szShaderPrecache = NULL; - m_bActivatePhase = false; - CRenderer::CV_r_shadersasynccompiling = nAsync; - - gRenDev->m_Features = nSaveFeatures; - - float t1 = gEnv->pTimer->GetAsyncCurTime(); - CryLogAlways("All shaders combinations compiled in %.2f seconds", (t1 - t0)); - CryLogAlways("Combinations: (Material: %d, Processed: %d; Compiled: %d; Removed: %d)", nMaterialCombinations, nProcessed, nCompiled, nEmpty); - CryLogAlways("-- Shader cache overall stats: Entries: %d, Unique Entries: %d, Size: %d, Compressed Size: %d, Token data size: %d", Stats.nEntries, Stats.nUniqueEntries, Stats.nSizeUncompressed, Stats.nSizeCompressed, Stats.nTokenDataSize); - - m_nCombinationsProcess = -1; - m_nCombinationsCompiled = -1; - m_nCombinationsEmpty = -1; -} - -#endif - -void CHWShader::mfGenName(uint64 GLMask, uint64 RTMask, uint32 LightMask, uint32 MDMask, uint32 MDVMask, uint64 PSS, uint64 STMask, EHWShaderClass eClass, char* dstname, int nSize, byte bType) -{ - assert(dstname); - dstname[0] = 0; - - char str[32]; - if (bType != 0 && GLMask) - { - azsprintf(str, "(GL%llx)", GLMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0) - { - azsprintf(str, "(RT%llx)", RTMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0 && LightMask) - { - azsprintf(str, "(LT%x)", LightMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0 && MDMask) - { - azsprintf(str, "(MD%x)", MDMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0 && MDVMask) - { - azsprintf(str, "(MDV%x)", MDVMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0 && PSS) - { - azsprintf(str, "(PSS%llx)", PSS); - cry_strcat(dstname, nSize, str); - } - if (bType != 0 && STMask) - { - azsprintf(str, "(ST%llx)", STMask); - cry_strcat(dstname, nSize, str); - } - if (bType != 0) - { - azsprintf(str, "(%s)", mfClassString(eClass)); - cry_strcat(dstname, nSize, str); - } -} - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - -void CShaderMan::mfPrecacheShaders(bool bStatsOnly) -{ - AZ_Assert(CRenderer::CV_r_shadersPlatform != static_cast(AZ::PlatformID::PLATFORM_MAX), "You must set a shaders platform (r_shadersPlatform) before precaching the shaders"); - CHWShader::mfFlushPendedShadersWait(-1); - - if (CRenderer::CV_r_shadersorbis) - { -#ifdef WATER_TESSELLATION_RENDERER - CRenderer::CV_r_WaterTessellationHW = 0; -#endif - gRenDev->m_bDeviceSupportsFP16Filter = true; - gRenDev->m_bDeviceSupportsFP16Separate = false; - gRenDev->m_bDeviceSupportsGeometryShaders = true; - gRenDev->m_Features |= RFT_HW_SM30; - - CParserBin::m_bShaderCacheGen = true; - - gRenDev->m_Features |= RFT_HW_SM50; - CParserBin::SetupForOrbis(); - CryLogAlways("\nStarting shader compilation for Orbis..."); - mfInitShadersList(NULL); - mfPreloadShaderExts(); - _PrecacheShaderList(bStatsOnly); - } - else - if (CRenderer::CV_r_shadersdx11) - { - gRenDev->m_bDeviceSupportsFP16Filter = true; - gRenDev->m_bDeviceSupportsFP16Separate = false; - gRenDev->m_bDeviceSupportsTessellation = true; - gRenDev->m_bDeviceSupportsGeometryShaders = true; - gRenDev->m_Features |= RFT_HW_SM30; - - CParserBin::m_bShaderCacheGen = true; - - gRenDev->m_Features |= RFT_HW_SM50; - CParserBin::SetupForD3D11(); - CryLogAlways("\nStarting shader compilation for D3D11..."); - mfInitShadersList(NULL); - mfPreloadShaderExts(); - _PrecacheShaderList(bStatsOnly); - } - else - if (CRenderer::CV_r_shadersGL4) - { - gRenDev->m_bDeviceSupportsFP16Filter = true; - gRenDev->m_bDeviceSupportsFP16Separate = false; - gRenDev->m_bDeviceSupportsTessellation = true; - gRenDev->m_bDeviceSupportsGeometryShaders = true; - gRenDev->m_Features |= RFT_HW_SM30; - - CParserBin::m_bShaderCacheGen = true; - - gRenDev->m_Features |= RFT_HW_SM50; - CParserBin::SetupForGL4(); - CryLogAlways("\nStarting shader compilation for GLSL 4..."); - mfInitShadersList(NULL); - mfPreloadShaderExts(); - _PrecacheShaderList(bStatsOnly); - } - else - if (CRenderer::CV_r_shadersGLES3) - { - gRenDev->m_bDeviceSupportsFP16Filter = true; - gRenDev->m_bDeviceSupportsFP16Separate = false; - gRenDev->m_bDeviceSupportsTessellation = false; - gRenDev->m_bDeviceSupportsGeometryShaders = false; - gRenDev->m_Features |= RFT_HW_SM30; - - CParserBin::m_bShaderCacheGen = true; - - gRenDev->m_Features |= RFT_HW_SM50; - CParserBin::SetupForGLES3(); - CryLogAlways("\nStarting shader compilation for GLSL-ES 3..."); - mfInitShadersList(NULL); - mfPreloadShaderExts(); - _PrecacheShaderList(bStatsOnly); - } - else - if (CRenderer::CV_r_shadersMETAL) - { - AZ_Assert(CRenderer::CV_r_shadersPlatform == static_cast(AZ::PlatformID::PLATFORM_APPLE_OSX) || CRenderer::CV_r_shadersPlatform == static_cast(AZ::PlatformID::PLATFORM_APPLE_IOS), "Invalid platform (%d) for metal shaders", CRenderer::CV_r_shadersPlatform); - gRenDev->m_bDeviceSupportsFP16Filter = true; - gRenDev->m_bDeviceSupportsFP16Separate = false; - gRenDev->m_bDeviceSupportsTessellation = false; - gRenDev->m_bDeviceSupportsGeometryShaders = false; - gRenDev->m_Features |= RFT_HW_SM30; - - CParserBin::m_bShaderCacheGen = true; - - gRenDev->m_Features |= RFT_HW_SM50; - CParserBin::SetupForMETAL(); - CryLogAlways("\nStarting shader compilation for METAL..."); - mfInitShadersList(NULL); - mfPreloadShaderExts(); - _PrecacheShaderList(bStatsOnly); - } - -#if defined(AZ_PLATFORM_WINDOWS) - CRenderer::CV_r_shadersPlatform = static_cast(AZ::PlatformID::PLATFORM_WINDOWS_64); - CParserBin::SetupForD3D11(); -#elif defined(AZ_PLATFORM_MAC) - CRenderer::CV_r_shadersPlatform = static_cast(AZ::PlatformID::PLATFORM_APPLE_OSX); - CParserBin::SetupForMETAL(); -#endif - - gRenDev->m_cEF.m_Bin.InvalidateCache(); -} - -void CShaderMan::mfGetShaderList() -{ - if (CRenderer::CV_r_shadersorbis) - { - CParserBin::m_bShaderCacheGen = true; - CParserBin::SetupForOrbis(); - } - else - if (CRenderer::CV_r_shadersdx11) - { - CParserBin::m_bShaderCacheGen = true; - CParserBin::SetupForD3D11(); - CryLogAlways("\nGet shader list for D3D11..."); - } - else - if (CRenderer::CV_r_shadersGL4) - { - CParserBin::m_bShaderCacheGen = true; - CParserBin::SetupForGL4(); - CryLogAlways("\nGet shader list for GLSL 4..."); - } - else - if (CRenderer::CV_r_shadersGLES3) - { - CParserBin::m_bShaderCacheGen = true; - CParserBin::SetupForGLES3(); - CryLogAlways("\nGet shader list for GLSL-ES 3..."); - } - else - if (CRenderer::CV_r_shadersMETAL) - { - CParserBin::m_bShaderCacheGen = true; - CParserBin::SetupForMETAL(); - CryLogAlways("\nGet shader list for METAL..."); - } - - std::vector Data; - if (NRemoteCompiler::ESOK == NRemoteCompiler::CShaderSrv::Instance().GetShaderList(Data)) - { - CryLogAlways("\nGet shader list Succeeded...\nStart Writing shader list to @user@\\cache\\shaders\\shaderlist.txt ..."); - mfCloseShadersCache(0); - mfCloseShadersCache(1); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen("@user@\\cache\\shaders\\shaderlist.txt", "w+b"); - if (fileHandle != AZ::IO::InvalidHandle) - { - size_t writtenSoFar = 0; - size_t remaining = Data.size(); - while (remaining) - { - writtenSoFar += gEnv->pCryPak->FWrite(Data.data() + writtenSoFar, 1, remaining, fileHandle); - remaining -= writtenSoFar; - } - gEnv->pCryPak->FClose(fileHandle); - CryLogAlways("\nFinished writing shader list to @user@\\cache\\shaders\\shaderlist.txt ..."); - } - else - { - CryLogAlways("\nFailed writing shader list to @user@\\cache\\shaders\\shaderlist.txt ..."); - } - } - else - { - CryLogAlways("\nGet shader list Failed..."); - } - - CParserBin::SetupForD3D11(); -} - -void CShaderMan::mfExportShaders() -{ -} - -void CShaderMan::mfOptimiseShaders(const char* szFolder, bool bForce) -{ - CHWShader::mfFlushPendedShadersWait(-1); - - float t0 = gEnv->pTimer->GetAsyncCurTime(); - SShaderCache* pCache; - uint32 i; - - std::vector Names; - mfGatherFilesList(szFolder, Names, 0, false); - - SOptimiseStats Stats; - for (i = 0; i < Names.size(); i++) - { - const char* szName = Names[i].c_str(); - constexpr AZStd::string_view userCache = "@usercache@/"; - if (szName == userCache) - { - szName += userCache.size(); - } - pCache = CHWShader::mfInitCache(szName, NULL, false, 0, false); - if (!pCache || !pCache->m_pRes[CACHE_USER]) - { - continue; - } - SOptimiseStats _Stats; - CHWShader::mfOptimiseCacheFile(pCache, bForce, &_Stats); - Stats.nEntries += _Stats.nEntries; - Stats.nUniqueEntries += _Stats.nUniqueEntries; - Stats.nSizeCompressed += _Stats.nSizeCompressed; - Stats.nSizeUncompressed += _Stats.nSizeUncompressed; - Stats.nTokenDataSize += _Stats.nTokenDataSize; - Stats.nDirDataSize += _Stats.nDirDataSize; - pCache->Release(); - } - - float t1 = gEnv->pTimer->GetAsyncCurTime(); - CryLog("-- All shaders combinations optimized in %.2f seconds", t1 - t0); - CryLog("-- Shader cache overall stats: Entries: %d, Unique Entries: %d, Size: %.3f, Compressed Size: %.3f, Token data size: %.3f, Directory Size: %.3f Mb", Stats.nEntries, Stats.nUniqueEntries, Stats.nSizeUncompressed / 1024.0f / 1024.0f, Stats.nSizeCompressed / 1024.0f / 1024.0f, Stats.nTokenDataSize / 1024.0f / 1024.0f, Stats.nDirDataSize / 1024.0f / 1024.0f); -} - -struct SMgData -{ - CCryNameTSCRC Name; - int nSize; - uint32 CRC; - uint32 flags; - byte* pData; - int nID; - byte bProcessed; -}; - -static int snCurListID; -typedef std::map ShaderData; -typedef ShaderData::iterator ShaderDataItor; - -static void sAddToList(SShaderCache* pCache, ShaderData& Data) -{ - uint32 i; - CResFile* pRes = pCache->m_pRes[CACHE_USER]; - ResDir* Dir = pRes->mfGetDirectory(); - for (i = 0; i < Dir->size(); i++) - { - SDirEntry* pDE = &(*Dir)[i]; - if (pDE->Name == CShaderMan::s_cNameHEAD) - { - continue; - } - ShaderDataItor it = Data.find(pDE->Name); - if (it == Data.end()) - { - SMgData d; - d.nSize = pRes->mfFileRead(pDE); - SDirEntryOpen* pOE = pRes->mfGetOpenEntry(pDE); - assert(pOE); - if (!pOE) - { - continue; - } - d.flags = pDE->flags; - if (pDE->flags & RF_RES_$) - { - d.pData = new byte[d.nSize]; - memcpy(d.pData, pOE->pData, d.nSize); - d.bProcessed = 0; - d.Name = pDE->Name; - d.CRC = 0; - d.nID = snCurListID++; - Data.insert(ShaderDataItor::value_type(d.Name, d)); - continue; - } - if (d.nSize < sizeof(SShaderCacheHeaderItem)) - { - assert(0); - continue; - } - d.pData = new byte[d.nSize]; - memcpy(d.pData, pOE->pData, d.nSize); - SShaderCacheHeaderItem* pItem = (SShaderCacheHeaderItem*)d.pData; - d.bProcessed = 0; - d.Name = pDE->Name; - d.CRC = pItem->m_CRC32; - d.nID = snCurListID++; - Data.insert(ShaderDataItor::value_type(d.Name, d)); - } - } -} - -struct SNameData -{ - CCryNameR Name; - bool bProcessed; -}; - -void CShaderMan::_MergeShaders() -{ - float t0 = gEnv->pTimer->GetAsyncCurTime(); - SShaderCache* pCache; - uint32 i, j; - - std::vector NM; - std::vector Names; - mfGatherFilesList(m_ShadersMergeCachePath.c_str(), NM, 0, true); - for (i = 0; i < NM.size(); i++) - { - SNameData dt; - dt.bProcessed = false; - dt.Name = NM[i]; - Names.push_back(dt); - } - - uint32 CRC32 = 0; - for (i = 0; i < Names.size(); i++) - { - if (Names[i].bProcessed) - { - continue; - } - Names[i].bProcessed = true; - const char* szNameA = Names[i].Name.c_str(); - iLog->Log(" Merging shader resource '%s'...", szNameA); - char szDrv[16], szDir[256], szName[256], szExt[32], szName1[256], szName2[256]; -#ifdef AZ_COMPILER_MSVC - _splitpath_s(szNameA, szDrv, szDir, szName, szExt); -#else - _splitpath(szNameA, szDrv, szDir, szName, szExt); -#endif - azsprintf(szName1, "%s%s", szName, szExt); - uint32 nLen = strlen(szName1); - pCache = CHWShader::mfInitCache(szNameA, NULL, false, CRC32, false); - SResFileLookupData* pData; - if (pCache->m_pRes[CACHE_USER]) - { - pData = pCache->m_pRes[CACHE_USER]->GetLookupData(false, 0, 0); - if (pData) - { - CRC32 = pData->m_CRC32; - } - } - else - if (pCache->m_pRes[CACHE_READONLY]) - { - pData = pCache->m_pRes[CACHE_READONLY]->GetLookupData(false, 0, 0); - if (pData) - { - CRC32 = pData->m_CRC32; - } - } - else - { - assert(0); - } - ShaderData Data; - snCurListID = 0; - sAddToList(pCache, Data); - SAFE_RELEASE(pCache); - for (j = i + 1; j < Names.size(); j++) - { - if (Names[j].bProcessed) - { - continue; - } - const char* szNameB = Names[j].Name.c_str(); -#ifdef AZ_COMPILER_MSVC - _splitpath_s(szNameB, szDrv, szDir, szName, szExt); -#else - _splitpath(szNameB, szDrv, szDir, szName, szExt); -#endif - azsprintf(szName2, "%s%s", szName, szExt); - if (!azstricmp(szName1, szName2)) - { - Names[j].bProcessed = true; - SShaderCache* pCache1 = CHWShader::mfInitCache(szNameB, NULL, false, 0, false); - pData = pCache1->m_pRes[CACHE_USER]->GetLookupData(false, 0, 0); - assert(pData && pData->m_CRC32 == CRC32); - if (!pData || pData->m_CRC32 != CRC32) - { - Warning("WARNING: CRC mismatch for %s", szNameB); - } - sAddToList(pCache1, Data); - SAFE_RELEASE(pCache1); - } - } - char szDest[256]; - cry_strcpy(szDest, m_ShadersCache.c_str()); - const char* p = &szNameA[strlen(szNameA) - nLen - 2]; - while (*p != '/' && *p != '\\') - { - p--; - } - cry_strcat(szDest, p + 1); - pCache = CHWShader::mfInitCache(szDest, NULL, true, CRC32, false); - CResFile* pRes = pCache->m_pRes[CACHE_USER]; - pRes->mfClose(); - pRes->mfOpen(RA_CREATE, &gRenDev->m_cEF.m_ResLookupDataMan[CACHE_USER]); - - pRes->GetLookupData(true, CRC32, FX_CACHE_VER); - pRes->mfFlush(); - - int nDeviceShadersCounter = 0x10000000; - ShaderDataItor it; - for (it = Data.begin(); it != Data.end(); it++) - { - SMgData* pD = &it->second; - SDirEntry de; - de.Name = pD->Name; - de.size = pD->nSize; - de.flags = pD->flags; - if (pD->flags & RF_RES_$) - { - de.flags &= ~RF_COMPRESS; - } - else - { - de.flags |= RF_COMPRESS; - de.offset = nDeviceShadersCounter++; - } - byte* pNew = new byte[de.size]; - memcpy(pNew, pD->pData, pD->nSize); - de.flags |= RF_TEMPDATA; - pRes->mfFileAdd(&de); - SDirEntryOpen* pOE = pRes->mfOpenEntry(&de); - pOE->pData = pNew; - } - for (it = Data.begin(); it != Data.end(); it++) - { - SMgData* pD = &it->second; - delete [] pD->pData; - } - Data.clear(); - pRes->mfFlush(); - iLog->Log(" ...%d result items...", pRes->mfGetNumFiles()); - pCache->Release(); - } - - mfOptimiseShaders(gRenDev->m_cEF.m_ShadersCache.c_str(), true); - - float t1 = gEnv->pTimer->GetAsyncCurTime(); - CryLog("All shaders files merged in %.2f seconds", t1 - t0); -} - -void CShaderMan::mfMergeShaders() -{ - CHWShader::mfFlushPendedShadersWait(-1); - - CParserBin::SetupForD3D11(); - _MergeShaders(); -} - -////////////////////////////////////////////////////////////////////////// -bool CShaderMan::CheckAllFilesAreWritable(const char* szDir) const -{ -#if (defined(WIN32) || defined(WIN64)) - assert(szDir); - - auto pack = gEnv->pCryPak; - assert(pack); - - string sPathWithFilter = string(szDir) + "/*"; - - // Search files that match filter specification. - AZ::IO::ArchiveFileIterator handle; - if (handle = pack->FindFirst(sPathWithFilter.c_str()); handle) - { - do - { - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) != AZ::IO::FileDesc::Attribute::Subdirectory) - { - string fullpath = string(szDir) + "/" + string(handle.m_filename.data(), handle.m_filename.size()); - - AZ::IO::HandleType outFileHandle = pack->FOpen(fullpath.c_str(), "rb"); - if (outFileHandle == AZ::IO::InvalidHandle) - { - handle = pack->FindNext(handle); - continue; - } - if (pack->IsInPak(outFileHandle)) - { - pack->FClose(outFileHandle); - handle = pack->FindNext(handle); - continue; - } - pack->FClose(outFileHandle); - - outFileHandle = pack->FOpen(fullpath.c_str(), "ab"); - - if (outFileHandle != AZ::IO::InvalidHandle) - { - pack->FClose(outFileHandle); - } - else - { - gEnv->pLog->LogError("ERROR: Shader cache is not writable (file: '%s')", fullpath.c_str()); - return false; - } - } - - handle = pack->FindNext(handle); - } while (handle); - - pack->FindClose(handle); - - gEnv->pLog->LogToFile("Shader cache directory '%s' was successfully tested for being writable", szDir); - } - else - { - CryLog("Shader cache directory '%s' does not exist", szDir); - } - -#endif - - return true; -} - -#endif // CONSOLE - -bool CShaderMan::mfPreloadBinaryShaders() -{ - LOADING_TIME_PROFILE_SECTION; - AZ_TRACE_METHOD(); - // don't preload binary shaders if we are in editing mode - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersediting) - { - return false; - } - - // don't load all binary shaders twice - if (m_Bin.m_bBinaryShadersLoaded) - { - return true; - } - - bool bFound = iSystem->GetIPak()->LoadPakToMemory("Engine/ShadersBin.pak", AZ::IO::IArchive::eInMemoryPakLocale_CPU); - if (!bFound) - { - return false; - } - -#ifndef _RELEASE - // also load shaders pak file to memory because shaders are also read, when data not found in bin, and to check the CRC - // of the source shaders against the binary shaders in non release mode - iSystem->GetIPak()->LoadPakToMemory("Engine/Shaders.pak", AZ::IO::IArchive::eInMemoryPakLocale_CPU); -#endif - - AZStd::string allFilesPath = m_ShadersCache + "/*"; - - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst (allFilesPath.c_str()); - if (!handle) - { - return false; - } - std::vector FilesCFX; - std::vector FilesCFI; - - do - { - if (gEnv->pSystem && gEnv->pSystem->IsQuitting()) - { - return false; - } - if (handle.m_filename.front() == '.') - { - continue; - } - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - continue; - } - const char* szExt = fpGetExtension(handle.m_filename.data()); - if (!azstricmp(szExt, ".cfib")) - { - FilesCFI.emplace_back(handle.m_filename.data(), handle.m_filename.size()); - } - else - if (!azstricmp(szExt, ".cfxb")) - { - FilesCFX.emplace_back(handle.m_filename.data(), handle.m_filename.size()); - } - } while (handle = gEnv->pCryPak->FindNext(handle)); - - if (FilesCFX.size() + FilesCFI.size() > MAX_FXBIN_CACHE) - { - SShaderBin::s_nMaxFXBinCache = FilesCFX.size() + FilesCFI.size(); - } - uint32 i; - char sName[256]; - - { - LOADING_TIME_PROFILE_SECTION_NAMED("CShaderMan::mfPreloadBinaryShaders(): FilesCFI"); - for (i = 0; i < FilesCFI.size(); i++) - { - if (gEnv->pSystem && gEnv->pSystem->IsQuitting()) - { - return false; - } - - const string& file = FilesCFI[i]; - cry_strcpy(sName, file.c_str()); - fpStripExtension(sName, sName); - [[maybe_unused]] SShaderBin* pBin = m_Bin.GetBinShader(sName, true, 0); - AZ_Error("Rendering", pBin, "Error pre-loading binary shader %s", file.c_str()); - } - } - - { - LOADING_TIME_PROFILE_SECTION_NAMED("CShaderMan::mfPreloadBinaryShaders(): FilesCFX"); - for (i = 0; i < FilesCFX.size(); i++) - { - if (gEnv->pSystem && gEnv->pSystem->IsQuitting()) - { - return false; - } - - const string& file = FilesCFX[i]; - cry_strcpy(sName, file.c_str()); - fpStripExtension(sName, sName); - [[maybe_unused]] SShaderBin* pBin = m_Bin.GetBinShader(sName, false, 0); - AZ_Error("Rendering", pBin, "Error pre-loading binary shader %s", file.c_str()); - } - } - - gEnv->pCryPak->FindClose (handle); - - // Unload pak from memory. - iSystem->GetIPak()->LoadPakToMemory("Engine/ShadersBin.pak", AZ::IO::IArchive::eInMemoryPakLocale_Unload); - -#ifndef _RELEASE - iSystem->GetIPak()->LoadPakToMemory("Engine/Shaders.pak", AZ::IO::IArchive::eInMemoryPakLocale_Unload); -#endif - - m_Bin.m_bBinaryShadersLoaded = true; - - return SShaderBin::s_nMaxFXBinCache > 0; -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.h b/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.h deleted file mode 100644 index 55e6c9f9b4..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCache.h +++ /dev/null @@ -1,446 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -// Shader cache directory -#define g_shaderCache "Shaders/Cache/" - -#define CONCAT_PATHS(a, b) a b - -struct SPreprocessMasks -{ - uint64 nRT, nRTSet; - uint64 nGL, nGLSet; - uint32 nLT, nLTSet; - uint32 nMD, nMDSet; - uint32 nMDV, nMDVSet; -}; - -typedef std::map MapPreprocessFlags; -typedef MapPreprocessFlags::iterator MapPreprocessFlagsItor; - -struct SPreprocessNode -{ - TArray m_Expression; - int m_nNode; - uint64 m_RTMask; - uint64 m_GLMask; - uint32 m_LTMask; - uint32 m_MDMask; - uint32 m_MDVMask; - std::vector m_Nodes[2]; - short m_nCode[2]; // 0 - No Code, 1 - Has Code, -1 - Depends - SPreprocessNode() - { - m_nNode = 0; - m_RTMask = 0; - m_GLMask = 0; - m_LTMask = 0; - m_MDMask = 0; - m_MDVMask = 0; - m_nCode[0] = m_nCode[1] = 0; - } - ~SPreprocessNode() - { - uint32 i; - for (i = 0; i < m_Nodes[0].size(); i++) - { - SAFE_DELETE(m_Nodes[0][i]); - } - for (i = 0; i < m_Nodes[1].size(); i++) - { - SAFE_DELETE(m_Nodes[1][i]); - } - } -}; - -struct SPreprocessFlagDesc -{ - CCryNameR m_Name; - uint64 m_nFlag; - bool m_bWasReferenced; - SPreprocessFlagDesc() { m_nFlag = 0; m_bWasReferenced = true; } -}; - -struct SPreprocessTree -{ - static std::vector s_GLDescs; - static std::vector s_RTDescs; - static std::vector s_LTDescs; - std::vector m_GLDescsLocal; - std::vector m_MDDescs; - std::vector m_MDVDescs; - - static MapPreprocessFlags s_MapFlags; - MapPreprocessFlags m_MapFlagsLocal; - - std::vector m_Root; - ~SPreprocessTree() - { - uint32 i; - for (i = 0; i < m_Root.size(); i++) - { - SAFE_DELETE(m_Root[i]); - } - m_Root.clear(); - } - CShader* m_pSH; -}; - -//======================================================================================================= - -struct SShaderLevelPolicies -{ - std::vector m_WhiteGlobalList; - std::vector m_WhitePerLevelList; -}; -// CRY DX12 -union UPipelineState // Pipeline state relevant for shader instantiation -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(ShaderCache_h) -#endif - uint64 opaque; - UPipelineState() - : opaque(0) { - } -}; -static_assert(sizeof(UPipelineState) == sizeof(uint64), "UPipelineState needs to be 64 bit"); - -struct SShaderCombIdent -{ - uint64 m_RTMask; // run-time mask - uint64 m_GLMask; // global mask - uint64 m_STMask; // static mask - UPipelineState m_pipelineState; - union - { - struct - { - uint32 m_LightMask; // light mask - uint32 m_MDMask; // texture coordinates modifier mask - uint32 m_MDVMask; // vertex modifier mask | SF_PLATFORM - uint32 m_nHash; - }; - struct - { - uint64 m_FastCompare1; - uint64 m_FastCompare2; - }; - }; - - SShaderCombIdent(uint64 nRT, uint64 nGL, uint32 nLT, uint32 nMD, uint32 nMDV) - { - m_RTMask = nRT; - m_GLMask = nGL; - m_LightMask = nLT; - m_MDMask = nMD; - m_MDVMask = nMDV; - m_nHash = 0; - m_STMask = 0; - } - SShaderCombIdent(uint64 nGL, const SShaderCombIdent& Ident) - { - *this = Ident; - m_GLMask = nGL; - } - - SShaderCombIdent() - { - m_RTMask = 0; - m_GLMask = 0; - m_LightMask = 0; - m_MDMask = 0; - m_MDVMask = 0; - m_nHash = 0; - m_STMask = 0; - } - - uint32 PostCreate(); -}; - -//========================================================================================================================== - -class CResStreamDirCallback - : public IStreamCallback -{ - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError); - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); -}; -class CResStreamCallback - : public IStreamCallback -{ - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError); - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); -}; - -struct SResStreamEntry -{ - struct SResStreamInfo* m_pParent; - CCryNameTSCRC m_Name; - IReadStreamPtr m_readStream; -}; - -struct SResStreamInfo -{ - SShaderCache* m_pCache; - CResFile* m_pRes; - CResStreamCallback m_Callback; - CResStreamDirCallback m_CallbackDir; - - CryCriticalSection m_StreamLock; - std::vector m_EntriesQueue; - - std::vector m_dirReadStreams; - int m_nDirRequestCount; - - SResStreamInfo(SShaderCache* pCache) - { - m_pCache = pCache; - m_pRes = NULL; - m_nDirRequestCount = 0; - } - ~SResStreamInfo() - { - assert (m_EntriesQueue.empty() && m_dirReadStreams.empty()); - } - void AbortJobs() - { - using std::swap; - - CryAutoLock lock(m_StreamLock); - - // Copy the list here, as the streaming callback can modify the list - std::vector entries = m_EntriesQueue; - - for (size_t i = 0, c = entries.size(); i != c; ++i) - { - SResStreamEntry* pEntry = entries[i]; - if (pEntry->m_readStream) - { - pEntry->m_readStream->Abort(); - } - } - - - // Copy the list here, as the streaming callback can modify the list - std::vector dirStreams = m_dirReadStreams; - - for (size_t i = 0, c = dirStreams.size(); i != c; ++i) - { - IReadStream* pReadStream = dirStreams[i]; - if (pReadStream) - { - pReadStream->Abort(); - } - } - } - SResStreamEntry* AddEntry(CCryNameTSCRC Name) - { - uint32 i; - for (i = 0; i < m_EntriesQueue.size(); i++) - { - SResStreamEntry* pE = m_EntriesQueue[i]; - if (pE->m_Name == Name) - { - break; - } - } - if (i == m_EntriesQueue.size()) - { - SResStreamEntry* pEntry = new SResStreamEntry; - pEntry->m_pParent = this; - pEntry->m_Name = Name; - m_EntriesQueue.push_back(pEntry); - return pEntry; - } - return NULL; - } - void Release() - { - assert(m_EntriesQueue.empty()); - delete this; - } - -private: - SResStreamInfo(const SResStreamInfo&); - SResStreamInfo& operator = (const SResStreamInfo&); -}; - -struct SShaderDevCache -{ - int m_nRefCount; - CCryNameR m_Name; - - FXDeviceShader m_DeviceShaders; - - SShaderDevCache() - { - m_nRefCount = 1; - } - SShaderDevCache(const CCryNameR& name) - :m_Name(name) - { - m_nRefCount = 1; - } - int Size(); - void GetMemoryUsage(ICrySizer* pSizer) const; - int Release() - { - m_nRefCount--; - if (m_nRefCount) - { - return m_nRefCount; - } - delete this; - return 0; - } - ~SShaderDevCache() {}; -}; - - -struct SShaderCache -{ - volatile int32 m_nRefCount; - CCryNameR m_Name; - class CResFile* m_pRes[2]; - SResStreamInfo* m_pStreamInfo; - uint32 m_nPlatform; - bool m_bReadOnly[2]; - bool m_bValid[2]; - bool m_bNeedPrecache; - SShaderCache() - { - m_nPlatform = 0; - m_nRefCount = 1; - m_pStreamInfo = NULL; - m_pRes[0] = m_pRes[1] = NULL; - m_bValid[0] = m_bValid[1] = false; - m_bReadOnly[0] = m_bReadOnly[1] = false; - m_bNeedPrecache = false; - } - bool isValid(); - int Size(); - void GetMemoryUsage(ICrySizer* pSizer) const; - void Cleanup(); - int AddRef() { return CryInterlockedIncrement(&m_nRefCount); } - int Release(bool bDelete = true) - { - int nRef = CryInterlockedDecrement(&m_nRefCount); - if (nRef || !bDelete) - { - return nRef; - } - delete this; - return 0; - } - ~SShaderCache(); -}; - -struct SEmptyCombination -{ - uint64 nRTOrg; - uint64 nGLOrg; - uint32 nLTOrg; - uint64 nRTNew; - uint64 nGLNew; - uint32 nLTNew; - uint32 nMD; - uint32 nMDV; - uint64 nST; - class CHWShader* pShader; - - using Combinations = AZStd::vector; - static Combinations s_Combinations; -}; - -//========================================================================================================================== - -struct SShaderCombination -{ - uint64 m_RTMask; - uint32 m_LTMask; - uint32 m_MDMask; - uint32 m_MDVMask; - UPipelineState m_pipelineState; - SShaderCombination() - { - m_RTMask = 0; - m_LTMask = 0; - m_MDMask = 0; - m_MDVMask = 0; - } -}; - - -struct SCacheCombination -{ - CCryNameR Name; - CCryNameR CacheName; - SShaderCombIdent Ident; - uint32 nCount; - EHWShaderClass eCL; - SCacheCombination() - { - nCount = 0; - eCL = eHWSC_Vertex; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - -struct SShaderGenComb -{ - CCryNameR Name; - SShaderGen* pGen; - - SShaderGenComb() - : Name() - , pGen(nullptr) - { - } - - ~SShaderGenComb() - { - //SAFE_RELEASE(pGen); - } - - _inline SShaderGenComb (const SShaderGenComb& src) - : Name(src.Name) - , pGen(src.pGen) - { - if (pGen) - { - pGen->m_nRefCount++; - } - } - - _inline SShaderGenComb& operator = (const SShaderGenComb& src) - { - this->~SShaderGenComb(); - new(this)SShaderGenComb(src); - return *this; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(Name); - pSizer->AddObject(pGen); - } -}; - -typedef std::map FXShaderCacheCombinations; -typedef FXShaderCacheCombinations::iterator FXShaderCacheCombinationsItor; -typedef std::map > FXShaderCacheCombinationsList; -typedef FXShaderCacheCombinationsList::iterator FXShaderCacheCombinationsListItor; diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.cpp deleted file mode 100644 index b6a6119cfa..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.cpp +++ /dev/null @@ -1,908 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "CryHeaders.h" -#include "../Shadow_Renderer.h" - -#if defined(WIN32) || defined(WIN64) -#include -#include -#elif defined(LINUX) -#endif - -static void sParseTexMatrix([[maybe_unused]] const char* szScr, const char* szAnnotations, std::vector* pSamplers, SCGParam* vpp, [[maybe_unused]] int nComp, [[maybe_unused]] CShader* ef) -{ - uint32 i; - const char* szSampler = gRenDev->m_cEF.mfParseFX_Parameter(szAnnotations, eType_STRING, "Sampler"); - assert (szSampler); - if (szSampler) - { - for (i = 0; i < pSamplers->size(); i++) - { - STexSamplerFX* sm = &(*pSamplers)[i]; - if (!azstricmp(sm->m_szName.c_str(), szSampler)) - { - vpp->m_nID = (UINT_PTR)sm->m_pTarget; - break; - } - } - } -} - -//====================================================================================== - -// PB = Per-Batch -// PI = Per-Instance -// SI = Per-Instance Static -// PF = Per-Frame -// PM = Per-Material -// SG = Shadow-Generation - -#define PARAM(a, b) #a, b -static SParamDB sParams[] = -{ - SParamDB(PARAM(SI_AlphaTest, ECGP_SI_AlphaTest), 0), - SParamDB(PARAM(SI_AmbientOpacity, ECGP_SI_AmbientOpacity), 0), - SParamDB(PARAM(SI_ObjectAmbColComp, ECGP_SI_ObjectAmbColComp), 0), - SParamDB(PARAM(SI_BendInfo, ECGP_SI_BendInfo), 0), - SParamDB(PARAM(SI_PrevBendInfo, ECGP_SI_PrevBendInfo), 0), - - SParamDB(PARAM(PI_ViewProjection, ECGP_Matr_PI_ViewProj), 0), - - SParamDB(PARAM(PI_Composite, ECGP_Matr_PI_Composite), 0), - SParamDB(PARAM(PB_UnProjMatrix, ECGP_Matr_PB_UnProjMatrix), 0), - SParamDB(PARAM(PB_ProjMatrix, ECGP_Matr_PB_ProjMatrix), 0), - SParamDB(PARAM(PB_TerrainBaseMatrix, ECGP_Matr_PB_TerrainBase), 0), - SParamDB(PARAM(PB_TerrainLayerGen, ECGP_Matr_PB_TerrainLayerGen), 0), - SParamDB(PARAM(PI_TransObjMatrix, ECGP_Matr_PI_Obj_T), 0), // Due to some bug in Parser, ObjMatrix_T or something - - SParamDB(PARAM(PB_GmemStencilValue, ECGP_PB_GmemStencilValue), 0), - SParamDB(PARAM(PI_MotionBlurData, ECGP_PI_MotionBlurData), 0), - - SParamDB(PARAM(PI_TessParams, ECGP_PI_TessParams), 0), - - SParamDB(PARAM(PB_TempMatr0, ECGP_Matr_PB_Temp4_0), PD_INDEXED), - SParamDB(PARAM(PB_TempMatr1, ECGP_Matr_PB_Temp4_1), PD_INDEXED), - SParamDB(PARAM(PB_TempMatr2, ECGP_Matr_PB_Temp4_2), PD_INDEXED), - SParamDB(PARAM(PB_TempMatr3, ECGP_Matr_PB_Temp4_3), PD_INDEXED), - SParamDB(PARAM(PI_TexMatrix, ECGP_Matr_PI_TexMatrix), 0, sParseTexMatrix), // used for reflections (water) matrix - SParamDB(PARAM(PI_TCGMatrix, ECGP_Matr_PI_TCGMatrix), PD_INDEXED), - SParamDB(PARAM(PB_DLightsInfo, ECGP_PB_DLightsInfo), 0), - - SParamDB(PARAM(PM_DiffuseColor, ECGP_PM_DiffuseColor), 0), - SParamDB(PARAM(PM_SpecularColor, ECGP_PM_SpecularColor), 0), - SParamDB(PARAM(PM_EmissiveColor, ECGP_PM_EmissiveColor), 0), - SParamDB(PARAM(PM_DeformWave, ECGP_PM_DeformWave), 0), - SParamDB(PARAM(PM_DetailTiling, ECGP_PM_DetailTiling), 0), - SParamDB(PARAM(PM_TexelDensity, ECGP_PM_TexelDensity), 0), - SParamDB(PARAM(PM_UVMatrixDiffuse, ECGP_PM_UVMatrixDiffuse), 0), - SParamDB(PARAM(PM_UVMatrixCustom, ECGP_PM_UVMatrixCustom), 0), - SParamDB(PARAM(PM_UVMatrixEmissiveMultiplier, ECGP_PM_UVMatrixEmissiveMultiplier), 0), - SParamDB(PARAM(PM_UVMatrixEmittance, ECGP_PM_UVMatrixEmittance), 0), - SParamDB(PARAM(PM_UVMatrixDetail, ECGP_PM_UVMatrixDetail), 0), - - SParamDB(PARAM(PI_OSCameraPos, ECGP_PI_OSCameraPos), 0), - SParamDB(PARAM(PB_BlendTerrainColInfo, ECGP_PB_BlendTerrainColInfo), 0), - SParamDB(PARAM(PI_Ambient, ECGP_PI_Ambient), 0), - SParamDB(PARAM(PI_VisionParams, ECGP_PI_VisionParams), 0), - SParamDB(PARAM(PB_VisionMtlParams, ECGP_PB_VisionMtlParams), 0), - - SParamDB(PARAM(PB_IrregKernel, ECGP_PB_IrregKernel), 0), - - SParamDB(PARAM(PB_TFactor, ECGP_PB_TFactor), 0), - SParamDB(PARAM(PB_TempData, ECGP_PB_TempData), PD_INDEXED | 0), - SParamDB(PARAM(PB_RTRect, ECGP_PB_RTRect), 0), - SParamDB(PARAM(PI_AvgFogVolumeContrib, ECGP_PI_AvgFogVolumeContrib), 0), - SParamDB(PARAM(PI_NumInstructions, ECGP_PI_NumInstructions), PD_INDEXED), - SParamDB(PARAM(PB_FromRE, ECGP_PB_FromRE), PD_INDEXED | 0), - SParamDB(PARAM(PB_ObjVal, ECGP_PB_ObjVal), PD_INDEXED), - SParamDB(PARAM(PI_TextureTileSize, ECGP_PI_TextureTileSize), 0), - SParamDB(PARAM(PI_MotionBlurInfo, ECGP_PI_MotionBlurInfo), 0), - SParamDB(PARAM(PI_ParticleParams, ECGP_PI_ParticleParams), 0), - SParamDB(PARAM(PI_ParticleSoftParams, ECGP_PI_ParticleSoftParams), 0), - SParamDB(PARAM(PI_ParticleExtParams, ECGP_PI_ParticleExtParams), 0), - SParamDB(PARAM(PI_ParticleAlphaTest, ECGP_PI_ParticleAlphaTest), 0), - SParamDB(PARAM(PI_ParticleEmissiveColor, ECGP_PI_ParticleEmissiveColor), 0), - SParamDB(PARAM(PB_ScreenSize, ECGP_PB_ScreenSize), 0), - - SParamDB(PARAM(PI_OceanMat, ECGP_Matr_PI_OceanMat), 0), - - SParamDB(PARAM(PI_WrinklesMask0, ECGP_PI_WrinklesMask0), 0), - SParamDB(PARAM(PI_WrinklesMask1, ECGP_PI_WrinklesMask1), 0), - SParamDB(PARAM(PI_WrinklesMask2, ECGP_PI_WrinklesMask2), 0), - - SParamDB(PARAM(PB_ClipVolumeParams, ECGP_PB_ClipVolumeParams), 0), - - SParamDB(PARAM(PB_ResInfoDiffuse, ECGP_PB_ResInfoDiffuse), 0), - SParamDB(PARAM(PB_FromObjSB, ECGP_PB_FromObjSB), 0), - SParamDB(PARAM(PB_TexelDensityParam, ECGP_PB_TexelDensityParam), 0), - SParamDB(PARAM(PB_TexelDensityColor, ECGP_PB_TexelDensityColor), 0), - SParamDB(PARAM(PB_TexelsPerMeterInfo, ECGP_PB_TexelsPerMeterInfo), 0), - - SParamDB(PARAM(PB_WaterRipplesLookupParams, ECGP_PB_WaterRipplesLookupParams), 0), - SParamDB(PARAM(PB_SkinningExtraWeights, ECGP_PB_SkinningExtraWeights), 0), - - SParamDB(PARAM(PI_FurLODInfo, ECGP_PI_FurLODInfo), 0), - SParamDB(PARAM(PI_FurParams, ECGP_PI_FurParams), 0), - SParamDB(PARAM(PI_PrevObjWorldMatrix, ECGP_PI_PrevObjWorldMatrix), 0), - - SParamDB() -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -const char* CShaderMan::mfGetShaderParamName(ECGParam ePR) -{ - int n = 0; - const char* szName; - szName = sParams[n].szName; - while (szName) - { - if (sParams[n].eParamType == ePR) - { - return szName; - } - n++; - szName = sParams[n].szName; - } - if (ePR == ECGP_PM_Tweakable) - { - return "PM_Tweakable"; - } - return NULL; -} - -SParamDB* CShaderMan::mfGetShaderParamDB(const char* szSemantic) -{ - const char* szName; - int n = 0; - szName = sParams[n].szName; - while (szName) - { - int nLen = strlen(szName); - if (!_strnicmp(szName, szSemantic, nLen) || (sParams[n].szAliasName && !_strnicmp(sParams[n].szAliasName, szSemantic, strlen(sParams[n].szAliasName)))) - { - return &sParams[n]; - } - n++; - szName = sParams[n].szName; - } - return NULL; -} - -bool CShaderMan::mfParseParamComp(int comp, SCGParam* pCurParam, const char* szSemantic, char* params, const char* szAnnotations, SShaderFXParams& FXParams, CShader* ef, uint32 nParamFlags, [[maybe_unused]] EHWShaderClass eSHClass, bool bExpressionOperand) -{ - if (comp >= 4 || comp < -1) - { - return false; - } - if (!pCurParam) - { - return false; - } - if (comp > 0) - { - pCurParam->m_Flags &= ~PF_SINGLE_COMP; - } - else - { - pCurParam->m_Flags |= PF_SINGLE_COMP; - } - if (!szSemantic || !szSemantic[0]) - { - if (!pCurParam->m_pData) - { - pCurParam->m_pData = new SParamData; - } - pCurParam->m_pData->d.fData[comp] = shGetFloat(params); - if (!((nParamFlags >> comp) & PF_TWEAKABLE_0)) - { - pCurParam->m_eCGParamType = (ECGParam)((int)pCurParam->m_eCGParamType | (int)(ECGP_PB_Scalar << (comp * 8))); - } - else - { - pCurParam->m_eCGParamType = (ECGParam)((int)pCurParam->m_eCGParamType | (int)(ECGP_PM_Tweakable << (comp * 8))); - if (!bExpressionOperand) - { - pCurParam->m_eCGParamType = (ECGParam)((int)pCurParam->m_eCGParamType | (int)ECGP_PM_Tweakable); - pCurParam->m_Flags |= PF_MATERIAL | PF_SINGLE_COMP; - } - } - return true; - } - if (!azstricmp(szSemantic, "NULL")) - { - return true; - } - if (szSemantic[0] == '(') - { - pCurParam->m_eCGParamType = ECGP_PM_Tweakable; - pCurParam->m_Flags |= PF_SINGLE_COMP | PF_MATERIAL; - return true; - } - const char* szName; - int n = 0; - szName = sParams[n].szName; - while (szName) - { - int nLen = strlen(szName); - if (!_strnicmp(szName, szSemantic, nLen) || (sParams[n].szAliasName && !_strnicmp(sParams[n].szAliasName, szSemantic, strlen(sParams[n].szAliasName)))) - { - if (sParams[n].nFlags & PD_MERGED) - { - pCurParam->m_Flags |= PF_CANMERGED; - } - if (!_strnicmp(szName, "PI_", 3)) - { - pCurParam->m_Flags |= PF_INSTANCE; - } - else - if (!_strnicmp(szName, "SI_", 3)) - { - pCurParam->m_Flags |= PF_INSTANCE; - } - else - if (!_strnicmp(szName, "PF_", 3)) - { - AZ_Assert(false, "PF_ no longer supported"); - } - else - if (!_strnicmp(szName, "PM_", 3)) - { - pCurParam->m_Flags |= PF_MATERIAL; - } - else - if (!_strnicmp(szName, "SG_", 3)) - { - AZ_Assert(false, "SG_ no longer supported"); - } - static_assert(ECGP_COUNT <= 256, "ECGParam does not fit into 1 byte."); - if (comp > 0) - { - pCurParam->m_eCGParamType = (ECGParam)((int)pCurParam->m_eCGParamType | (int)(sParams[n].eParamType << (comp * 8))); - } - else - { - pCurParam->m_eCGParamType = sParams[n].eParamType; - } - AZ_Assert(pCurParam->m_RegisterCount == 1, "Should be in default value as pCurParam is just initialized"); - - if (sParams[n].nFlags & PD_INDEXED) - { - if (szSemantic[nLen] == '[') - { - int nID = shGetInt(&szSemantic[nLen + 1]); - assert(nID < 256); - if (comp > 0) - { - nID <<= (comp * 8); - } - pCurParam->m_nID |= nID; - } - } - if (sParams[n].ParserFunc) - { - sParams[n].ParserFunc(params ? params : szSemantic, szAnnotations, &FXParams.m_FXSamplersOld, pCurParam, comp, ef); - } - break; - } - n++; - szName = sParams[n].szName; - } - if (!szName) - { - return false; - } - return true; -} - -bool CShaderMan::mfParseCGParam(char* scr, const char* szAnnotations, SShaderFXParams& FXParams, CShader* ef, std::vector* pParams, [[maybe_unused]] int nComps, uint32 nParamFlags, EHWShaderClass eSHClass, bool bExpressionOperand) -{ - char* name; - long cmd; - char* params; - char* data; - - int nComp = 0; - - enum - { - eComp = 1, eParam, eName - }; - static STokenDesc commands[] = - { - {eName, "Name"}, - {eComp, "Comp"}, - {eParam, "Param"}, - {0, 0} - }; - SCGParam vpp; -#if defined(AZ_ENABLE_TRACING) - int n = pParams->size(); -#endif - bool bRes = true; - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eName: - vpp.m_Name = data; - break; - case eComp: - { - if (nComp < 4) - { - bRes &= mfParseParamComp(nComp, &vpp, name, params, szAnnotations, FXParams, ef, nParamFlags, eSHClass, bExpressionOperand); - nComp++; - } - } - break; - case eParam: - if (!name) - { - name = params; - } - bRes &= mfParseParamComp(-1, &vpp, name, params, szAnnotations, FXParams, ef, nParamFlags, eSHClass, bExpressionOperand); - break; - } - } - - AZ_Assert(n == pParams->size(), ""); - pParams->push_back(vpp); - - AZ_Assert(bRes, "Error: CShaderMan::mfParseCGParam - bRes is false"); - return bRes; -} - -bool CShaderMan::mfParseFXParameter(SShaderFXParams& FXParams, SFXParam* pr, const char* ParamName, CShader* ef, [[maybe_unused]] bool bInstParam, int nParams, std::vector* pParams, EHWShaderClass eSHClass, bool bExpressionOperand) -{ - SCGParam CGpr; - char scr[256]; - - uint32 nParamFlags = pr->GetFlags(); - - CryFixedStringT<512> Semantic = "Name="; - Semantic += ParamName; - Semantic += " "; - int nComps = 0; - if (!pr->m_Semantic.empty()) - { - Semantic += "Param="; - Semantic += pr->m_Semantic.c_str(); - nComps = pr->m_ComponentCount; - } - else - { - for (int i = 0; i < pr->m_ComponentCount; i++) - { - if (i) - { - Semantic += " "; - } - CryFixedStringT<128> cur; - pr->GetParamComp(i, cur); - if (cur.empty()) - { - break; - } - nComps++; - if ((cur.at(0) == '-' && isdigit(uint8(cur.at(1)))) || isdigit(uint8(cur.at(0)))) - { - azsprintf(scr, "Comp = %s", cur.c_str()); - } - else - { - azsprintf(scr, "Comp '%s'", cur.c_str()); - } - Semantic += scr; - } - } - // Process parameters only with semantics - if (nComps) - { - uint32 nOffs = pParams->size(); - bool bRes = mfParseCGParam((char*)Semantic.c_str(), pr->m_Annotations.c_str(), FXParams, ef, pParams, nComps, nParamFlags, eSHClass, bExpressionOperand); - AZ_Assert(bRes, "Error: CShaderMan::mfParseFXParameter - bRes is false"); - - // pParams->size() > nOffs means we Added 1 new param into pParams in mfParseCGParam - if (pParams->size() > nOffs) - { - //assert(pBind->m_nComponents == 1); - SCGParam& p = (*pParams)[nOffs]; - p.m_RegisterOffset = -1; - p.m_RegisterCount = nParams; - p.m_Flags |= nParamFlags; - if (p.m_Flags & PF_AUTOMERGED) - { - if (!p.m_pData) - { - p.m_pData = new SParamData; - } - const char* src = p.m_Name.c_str(); - for (uint32 i = 0; i < 4; i++) - { - char param[128]; - char dig = i + 0x30; - while (*src) - { - if (src[0] == '_' && src[1] == '_' && src[2] == dig) - { - int n = 0; - src += 3; - while (src[n]) - { - if (src[n] == '_' && src[n + 1] == '_') - { - break; - } - param[n] = src[n]; - n++; - } - param[n] = 0; - src += n; - if (param[0]) - { - p.m_pData->m_CompNames[i] = param; - } - break; - } - else - { - src++; - } - } - } - } - } - return bRes; - } - // Parameter without semantic - return false; -} - -// SM_ - material slots -// SR_ - global engine RT's -static SSamplerDB sSamplers[] = -{ - SSamplerDB(PARAM(SM_Diffuse, ECGS_MatSlot_Diffuse), 0), - SSamplerDB(PARAM(SM_Normalmap, ECGS_MatSlot_Normalmap), 0), - SSamplerDB(PARAM(SM_Glossmap, ECGS_MatSlot_Gloss), 0), - SSamplerDB(PARAM(SM_Env, ECGS_MatSlot_Env), 0), - SSamplerDB(PARAM(SS_Shadow0, ECGS_Shadow0), 0), - SSamplerDB(PARAM(SS_Shadow1, ECGS_Shadow1), 0), - SSamplerDB(PARAM(SS_Shadow2, ECGS_Shadow2), 0), - SSamplerDB(PARAM(SS_Shadow3, ECGS_Shadow3), 0), - SSamplerDB(PARAM(SS_Shadow4, ECGS_Shadow4), 0), - SSamplerDB(PARAM(SS_Shadow5, ECGS_Shadow5), 0), - SSamplerDB(PARAM(SS_Shadow6, ECGS_Shadow6), 0), - SSamplerDB(PARAM(SS_Shadow7, ECGS_Shadow7), 0), - SSamplerDB(PARAM(SS_TrilinearClamp, ECGS_TrilinearClamp), 0), - SSamplerDB(PARAM(SS_MaterialAnisoHighWrap, ECGS_MatAnisoHighWrap), 0), - SSamplerDB(PARAM(SS_MaterialAnisoLowWrap, ECGS_MatAnisoLowWrap), 0), - SSamplerDB(PARAM(SS_MaterialTrilinearWrap, ECGS_MatTrilinearWrap), 0), - SSamplerDB(PARAM(SS_MaterialBilinearWrap, ECGS_MatBilinearWrap), 0), - SSamplerDB(PARAM(SS_MaterialTrilinearClamp, ECGS_MatTrilinearClamp), 0), - SSamplerDB(PARAM(SS_MaterialBilinearClamp, ECGS_MatBilinearClamp), 0), - SSamplerDB(PARAM(SS_MaterialAnisoHighBorder, ECGS_MatAnisoHighBorder), 0), - SSamplerDB(PARAM(SS_MaterialTrilinearBorder, ECGS_MatTrilinearBorder), 0), - SSamplerDB() -}; - -bool CShaderMan::mfParseFXSampler([[maybe_unused]] SShaderFXParams& FXParams, SFXSampler* pr, [[maybe_unused]] const char* ParamName, [[maybe_unused]] CShader* ef, [[maybe_unused]] int nParams, std::vector* pParams, [[maybe_unused]] EHWShaderClass eSHClass) -{ - SCGSampler CGpr; - CGpr.m_nStateHandle = pr->m_nTexState; - if (pr->m_Semantic.empty() && pr->m_Values.empty()) - { - if (CGpr.m_nStateHandle >= 0) - { - pParams->push_back(CGpr); - return true; - } - return false; - } - const char* szSemantic = pr->m_Semantic.c_str(); - const char* szName; - int n = 0; - szName = sSamplers[n].szName; - while (szName) - { - if (!azstricmp(szName, szSemantic)) - { - AZ_PUSH_DISABLE_WARNING(,"-Wtautological-constant-out-of-range-compare") - assert(sSamplers[n].eSamplerType < 256); - AZ_POP_DISABLE_WARNING - CGpr.m_eCGSamplerType = sSamplers[n].eSamplerType; - pParams->push_back(CGpr); - break; - } - n++; - szName = sSamplers[n].szName; - } - if (!szName) - { - return false; - } - return true; -} - - -// TM_ - material slots -// TR_ - global engine RT's -static STextureDB sTextures[] = -{ - STextureDB(PARAM(TM_Diffuse, ECGT_MatSlot_Diffuse), 0), - STextureDB(PARAM(TM_Normalmap, ECGT_MatSlot_Normals), 0), - STextureDB(PARAM(TM_BumpHeight, ECGT_MatSlot_Height), 0), - STextureDB(PARAM(TM_Glossmap, ECGT_MatSlot_Specular), 0), - STextureDB(PARAM(TM_Env, ECGT_MatSlot_Env), 0), - STextureDB(PARAM(TM_SubSurface, ECGT_MatSlot_SubSurface), 0), - STextureDB(PARAM(TM_GlossNormalA, ECGT_MatSlot_Smoothness), 0), - STextureDB(PARAM(TM_DecalOverlay, ECGT_MatSlot_DecalOverlay), 0), - STextureDB(PARAM(TM_Custom, ECGT_MatSlot_Custom), 0), - STextureDB(PARAM(TM_CustomSecondary, ECGT_MatSlot_CustomSecondary), 0), - STextureDB(PARAM(TM_Opacity, ECGT_MatSlot_Opacity), 0), - STextureDB(PARAM(TM_Detail, ECGT_MatSlot_Detail), 0), - STextureDB(PARAM(TM_Emittance, ECGT_MatSlot_Emittance), 0), - STextureDB(PARAM(TM_Occlusion, ECGT_MatSlot_Occlusion), 0), - STextureDB(PARAM(TM_Specular2, ECGT_MatSlot_Specular2), 0), - STextureDB(PARAM(TSF_Slot0, ECGT_SF_Slot0), 0), - STextureDB(PARAM(TSF_Slot1, ECGT_SF_Slot1), 0), - STextureDB(PARAM(TSF_SlotY, ECGT_SF_SlotY), 0), - STextureDB(PARAM(TSF_SlotU, ECGT_SF_SlotU), 0), - STextureDB(PARAM(TSF_SlotV, ECGT_SF_SlotV), 0), - STextureDB(PARAM(TSF_SlotA, ECGT_SF_SlotA), 0), - STextureDB(PARAM(TS_Shadow0, ECGT_Shadow0), 0), - STextureDB(PARAM(TS_Shadow1, ECGT_Shadow1), 0), - STextureDB(PARAM(TS_Shadow2, ECGT_Shadow2), 0), - STextureDB(PARAM(TS_Shadow3, ECGT_Shadow3), 0), - STextureDB(PARAM(TS_Shadow4, ECGT_Shadow4), 0), - STextureDB(PARAM(TS_Shadow5, ECGT_Shadow5), 0), - STextureDB(PARAM(TS_Shadow6, ECGT_Shadow6), 0), - STextureDB(PARAM(TS_Shadow7, ECGT_Shadow7), 0), - STextureDB(PARAM(TS_ShadowMask, ECGT_ShadowMask), 0), - STextureDB(PARAM(TS_ZTarget, ECGT_ZTarget), 0), - STextureDB(PARAM(TS_ZTargetScaled, ECGT_ZTargetScaled), 0), - STextureDB(PARAM(TS_ZTargetMS, ECGT_ZTargetMS), 0), - STextureDB(PARAM(TS_ShadowMaskZTarget, ECGT_ShadowMaskZTarget), 0), - STextureDB(PARAM(TS_SceneNormalsBent, ECGT_SceneNormalsBent), 0), - STextureDB(PARAM(TS_SceneNormals, ECGT_SceneNormals), 0), - STextureDB(PARAM(TS_SceneDiffuse, ECGT_SceneDiffuse), 0), - STextureDB(PARAM(TS_SceneSpecular, ECGT_SceneSpecular), 0), - STextureDB(PARAM(TS_SceneDiffuseAcc, ECGT_SceneDiffuseAcc), 0), - STextureDB(PARAM(TS_SceneSpecularAcc, ECGT_SceneSpecularAcc), 0), - STextureDB(PARAM(TS_SceneNormalsMapMS, ECGT_SceneNormalsMapMS), 0), - STextureDB(PARAM(TS_SceneDiffuseAccMS, ECGT_SceneDiffuseAccMS), 0), - STextureDB(PARAM(TS_SceneSpecularAccMS, ECGT_SceneSpecularAccMS), 0), - STextureDB(PARAM(TS_VolumetricClipVolumeStencil, ECGT_VolumetricClipVolumeStencil), 0), - STextureDB(PARAM(TS_VolumetricFog, ECGT_VolumetricFog), 0), - STextureDB(PARAM(TS_VolumetricFogGlobalEnvProbe0, ECGT_VolumetricFogGlobalEnvProbe0), 0), - STextureDB(PARAM(TS_VolumetricFogGlobalEnvProbe1, ECGT_VolumetricFogGlobalEnvProbe1), 0), - - STextureDB() -}; - - -//------------------------------------------------------------------------------ -// Starting point for texture data during shader parse stage. -// Based on the texture name, this function will prepare the binding data (SCGTexture) -// that will be held within the list of parameters to be bound to the shader. -// -// Important - the resources are loaded according to the order of arrival. -// -// Texture Structures and Their Usage: -// SCGTexture - texture binding structure used for the bind of the resource to the HW -// SFXTexture - Any SFX structure will be the structure gathered from the shader during -// parsing and associated later on. This structure contains a meta data regarding the -// texture such as UI name and hints, usage, type and other flags. -// It doesn't contain the actual texture data and doesn't apply to the binding directly -// but used as the data associated with the SCGTexture binding structure. -// SEfResTexture - the actual data representing a texture and its associated sampler. -//------------------------------------------------------------------------------ -bool CShaderMan::mfParseFXTexture( - [[maybe_unused]] SShaderFXParams& FXParams, SFXTexture* pr, [[maybe_unused]] const char* ParamName, - [[maybe_unused]] CShader* ef, [[maybe_unused]] int nParams, std::vector* pParams, [[maybe_unused]] EHWShaderClass eSHClass) -{ - SCGTexture CGpr; - if (pr->m_Semantic.empty()) - { // No texture semantic is assigned - assign textures according to usage ($, # or name) - // Semantic is the name text associated with the resource in the shader right after - // the name of the resource. - // Example: - // Texture2D sceneDepthSampler : TS_ZTarget; - here TS_ZTarget is the semantic - if (pr->m_szTexture.size()) - { - const char* nameTex = pr->m_szTexture.c_str(); - - // FT_DONT_STREAM = disable streaming for explicitly specified textures - if (nameTex[0] == '$') - { // Maps the name to the pointer in the static array it will be stored at. - // [Shaders System] - refactor to use map to store any dynamic name usage. - CGpr.m_pTexture = mfCheckTemplateTexName(nameTex, eTT_MaxTexType /*unused*/); - } - else if (strchr(nameTex, '#')) // test for " #" to skip max material names - { - CGpr.m_pAnimInfo = mfReadTexSequence(nameTex, pr->GetTexFlags() | FT_DONT_STREAM, false); - } - - // load texture by name (no context) - if (!CGpr.m_pTexture && !CGpr.m_pAnimInfo) - { - CGpr.m_pTexture = (CTexture*)gRenDev->EF_LoadTexture(nameTex, pr->GetTexFlags() | FT_DONT_STREAM); - } - - if (CGpr.m_pTexture) - { - CGpr.m_pTexture->AddRef(); - } - - CGpr.m_bSRGBLookup = pr->m_bSRGBLookup; - CGpr.m_bGlobal = false; - - pParams->push_back(CGpr); - return true; - } - - return false; - } - - const char* szSemantic = pr->m_Semantic.c_str(); - const char* szName; - int n = 0; - - // Texture semantic exists and will be used to compare to the semantic texture table - // Handling textures that are not material based textures, but parsed from the shader. - // An example of this will be: Texture2D sceneGBufferA : TS_SceneNormals; - szName = sTextures[n].szName; - while (szName) - { // Run over all slots and try to associates the semantic name. - // The semantic enum will be used in 'mfSetTexture' for setting texture - // loading and default properties. - if (!azstricmp(szName, szSemantic)) - { - static_assert(ECGT_COUNT <= 256, "ECGTexture does not fit into 1 byte."); - // Set the association with the texture enum as per above - CGpr.m_eCGTextureType = sTextures[n].eTextureType; - CGpr.m_bSRGBLookup = pr->m_bSRGBLookup; - CGpr.m_bGlobal = false; - pParams->push_back(CGpr); - break; - } - n++; - szName = sTextures[n].szName; - } - return szName != nullptr; -} - -//=========================================================================================== -bool SShaderParam::GetValue(const char* szName, AZStd::vector* Params, float* v, int nID) -{ - bool bRes = false; - - for (int i = 0; i < Params->size(); i++) - { - SShaderParam* sp = &(*Params)[i]; - if (!sp) - { - continue; - } - - if (azstricmp(sp->m_Name.c_str(), szName) == 0) - { - bRes = true; - switch (sp->m_Type) - { - case eType_HALF: - case eType_FLOAT: - v[nID] = sp->m_Value.m_Float; - break; - case eType_SHORT: - v[nID] = (float)sp->m_Value.m_Short; - break; - case eType_INT: - case eType_TEXTURE_HANDLE: - v[nID] = (float)sp->m_Value.m_Int; - break; - - case eType_VECTOR: - v[0] = sp->m_Value.m_Vector[0]; - v[1] = sp->m_Value.m_Vector[1]; - v[2] = sp->m_Value.m_Vector[2]; - break; - - case eType_FCOLOR: - case eType_FCOLORA: - v[0] = sp->m_Value.m_Color[0]; - v[1] = sp->m_Value.m_Color[1]; - v[2] = sp->m_Value.m_Color[2]; - v[3] = sp->m_Value.m_Color[3]; - break; - - case eType_STRING: - assert(0); - bRes = false; - break; - case eType_UNKNOWN: - assert(0); - bRes = false; - break; - } - - break; - } - } - - return bRes; -} - -bool SShaderParam::GetValue(uint8 eSemantic, AZStd::vector* Params, float* v, int nID) -{ - bool bRes = false; - for (int i = 0; i < Params->size(); i++) - { - SShaderParam* sp = &(*Params)[i]; - if (!sp) - { - continue; - } - - if (sp->m_eSemantic == eSemantic) - { - bRes = true; - switch (sp->m_Type) - { - case eType_HALF: - case eType_FLOAT: - v[nID] = sp->m_Value.m_Float; - break; - case eType_SHORT: - v[nID] = (float)sp->m_Value.m_Short; - break; - case eType_INT: - case eType_TEXTURE_HANDLE: - v[nID] = (float)sp->m_Value.m_Int; - break; - - case eType_VECTOR: - v[0] = sp->m_Value.m_Vector[0]; - v[1] = sp->m_Value.m_Vector[1]; - v[2] = sp->m_Value.m_Vector[2]; - break; - - case eType_FCOLOR: - v[0] = sp->m_Value.m_Color[0]; - v[1] = sp->m_Value.m_Color[1]; - v[2] = sp->m_Value.m_Color[2]; - v[3] = sp->m_Value.m_Color[3]; - break; - - case eType_STRING: - assert(0); - bRes = false; - break; - - case eType_UNKNOWN: - assert(0); - bRes = false; - break; - } - - break; - } - } - - return bRes; -} - -bool sGetPublic(const CCryNameR& n, float* v, int nID) -{ - CRenderer* rd = gRenDev; - bool bFound = false; - CShaderResources* pRS; - const char* cName = n.c_str(); - pRS = rd->m_RP.m_pShaderResources; - if (pRS) - { - bFound = SShaderParam::GetValue(cName, &pRS->m_ShaderParams, v, nID); - } - if (!bFound && rd->m_RP.m_pShader) - { - auto& PublicParams = rd->m_cEF.m_Bin.mfGetFXParams(rd->m_RP.m_pShader).m_PublicParams; - bFound = SShaderParam::GetValue(cName, &PublicParams, v, nID); - } - - return bFound; -} - -SParamData::~SParamData() -{ -} - -SParamData::SParamData(const SParamData& sp) -{ - for (int i = 0; i < 4; i++) - { - m_CompNames[i] = sp.m_CompNames[i]; - d.nData64[i] = sp.d.nData64[i]; - } -} - -SCGTexture::~SCGTexture() -{ - if (!m_pAnimInfo) - { - SAFE_RELEASE(m_pTexture); - m_pAnimInfo = nullptr; - } - else - { - SAFE_RELEASE(m_pAnimInfo); - m_pTexture = nullptr; - } -} -SCGTexture::SCGTexture(const SCGTexture& sp) - : SCGBind(sp) -{ - if (!sp.m_pAnimInfo) - { - m_pAnimInfo = nullptr; - m_pTexture = sp.m_pTexture; - if (m_pTexture) - { - m_pTexture->AddRef(); - } - } - else - { - m_pTexture = nullptr; - m_pAnimInfo = sp.m_pAnimInfo; - if (m_pAnimInfo) - { - m_pAnimInfo->AddRef(); - } - } - - m_eCGTextureType = sp.m_eCGTextureType; - m_bSRGBLookup = sp.m_bSRGBLookup; - m_bGlobal = sp.m_bGlobal; -} - -CTexture* SCGTexture::GetTexture() const -{ - if (m_pAnimInfo && m_pAnimInfo->m_Time && gRenDev->m_bPauseTimer == 0) - { - assert(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime >= 0); - uint32 m = (uint32)(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime / m_pAnimInfo->m_Time) % (m_pAnimInfo->m_NumAnimTexs); - assert(m < (uint32)m_pAnimInfo->m_TexPics.Num()); - - return m_pAnimInfo->m_TexPics[m]; - } - - return m_pTexture; -} - diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.h b/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.h deleted file mode 100644 index a4bb2255fd..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderComponents.h +++ /dev/null @@ -1,510 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "../Defs.h" -#include "ShadersResourcesGroups/PerFrame.h" - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(ShaderComponents_h) -#endif - -#define PF_SINGLE_COMP 2 -#define PF_DONTALLOW_DYNMERGE 4 -#define PF_INTEGER 8 -#define PF_BOOL 0x10 -#define PF_POSITION 0x20 -#define PF_MATRIX 0x40 -#define PF_SCALAR 0x80 -#define PF_TWEAKABLE_0 0x100 -#define PF_TWEAKABLE_1 0x200 -#define PF_TWEAKABLE_2 0x400 -#define PF_TWEAKABLE_3 0x800 -#define PF_TWEAKABLE_MASK 0xf00 -#define PF_MERGE_MASK 0xff000 -#define PF_MERGE 0x1000 -#define PF_INSTANCE 0x100000 -#define PF_MATERIAL 0x200000 -#define PF_CUSTOM_BINDED 0x1000000 -#define PF_CANMERGED 0x2000000 -#define PF_AUTOMERGED 0x4000000 -#define PF_GLOBAL 0x10000000 - -enum ECGParam -{ - ECGP_Unknown, - - ECGP_SI_AmbientOpacity, - ECGP_SI_ObjectAmbColComp, - ECGP_SI_BendInfo, - ECGP_SI_PrevBendInfo, - ECGP_SI_AlphaTest, - ECGP_Matr_PI_Obj_T, - ECGP_PB_GmemStencilValue, - ECGP_PI_MotionBlurData, - ECGP_PI_TessParams, - ECGP_Matr_PI_ViewProj, - ECGP_Matr_PI_Composite, - ECGP_Matr_PI_ObjOrigComposite, - ECGP_PI_OSCameraPos, - ECGP_PI_Ambient, - ECGP_PI_VisionParams, - ECGP_PB_VisionMtlParams, - ECGP_PI_AvgFogVolumeContrib, - ECGP_PI_NumInstructions, - ECGP_PI_TextureTileSize, - ECGP_PI_MotionBlurInfo, - ECGP_PI_ParticleParams, - ECGP_PI_ParticleSoftParams, - ECGP_PI_ParticleExtParams, - ECGP_PI_ParticleAlphaTest, - ECGP_PI_ParticleEmissiveColor, - ECGP_PI_WrinklesMask0, - ECGP_PI_WrinklesMask1, - ECGP_PI_WrinklesMask2, - ECGP_Matr_PI_OceanMat, - - ECGP_PB_Scalar, - ECGP_Matr_PB_ProjMatrix, - ECGP_Matr_PB_UnProjMatrix, - - ECGP_Matr_PB_Camera, - ECGP_Matr_PB_Camera_I, - ECGP_Matr_PB_Camera_T, - ECGP_Matr_PB_Camera_IT, - - ECGP_Matr_PB_Temp4_0, - ECGP_Matr_PB_Temp4_1, - ECGP_Matr_PB_Temp4_2, - ECGP_Matr_PB_Temp4_3, - ECGP_Matr_PB_TerrainBase, - ECGP_Matr_PB_TerrainLayerGen, - ECGP_Matr_PI_TexMatrix, - ECGP_Matr_PI_TCGMatrix, - - ECGP_PM_Tweakable, - ECGP_PM_DiffuseColor, - ECGP_PM_SpecularColor, - ECGP_PM_EmissiveColor, - ECGP_PM_DeformWave, - ECGP_PM_DetailTiling, - ECGP_PM_TexelDensity, - ECGP_PM_UVMatrixDiffuse, - ECGP_PM_UVMatrixCustom, - ECGP_PM_UVMatrixEmissiveMultiplier, - ECGP_PM_UVMatrixEmittance, - ECGP_PM_UVMatrixDetail, - - ECGP_PB_BlendTerrainColInfo, - - ECGP_PB_DLightsInfo, - ECGP_PB_IrregKernel, - ECGP_PB_TFactor, - ECGP_PB_TempData, - ECGP_PB_RTRect, - ECGP_PB_FromRE, - ECGP_PB_ObjVal, - ECGP_PB_ScreenSize, - - ECGP_PB_ClipVolumeParams, - - ECGP_PB_ResInfoDiffuse, - ECGP_PB_FromObjSB, - ECGP_PB_TexelDensityParam, - ECGP_PB_TexelDensityColor, - ECGP_PB_TexelsPerMeterInfo, - - ECGP_PB_WaterRipplesLookupParams, - ECGP_PB_SkinningExtraWeights, - - ECGP_PI_FurLODInfo, - ECGP_PI_FurParams, - ECGP_PI_PrevObjWorldMatrix, - - ECGP_COUNT, -}; - -enum EOperation -{ - eOp_Unknown, - eOp_Add, - eOp_Sub, - eOp_Div, - eOp_Mul, - eOp_Log, -}; - -//----------------------------------------------------------------------------- -// This is the binding structure that represents any parameter parsed by the shader parser -// and is to be bound in the shader. -//----------------------------------------------------------------------------- -struct SCGBind -{ - CCryNameR m_Name; - uint32 m_Flags; - - // m_BindingSlot - For constants it represents the buffer binding slot, for example B0, B1.. - // For textures and samplers it is the actual binding slot / offset. - short m_BindingSlot; - - // m_RegisterOffset - For constants it is the register offset within the binding slot group - // For textures and samplers the offset simply uses the MSB to indicate the usage. - // A texture will be SHADER_BIND_TEXTURE while a sampler will be SHADER_BIND_SAMPLER - // [Shader System] - possibly change / remove MSB usage. - short m_RegisterOffset; - - // m_RegisterCount - number of vectors used by the parameters. - // Example: matrix 4x4 will require 4 vectors. - int m_RegisterCount; - - SCGBind() - { - m_RegisterCount = 1; - m_RegisterOffset = -2; - m_BindingSlot = 0; - m_Flags = 0; - } - SCGBind (const SCGBind& sb) - { - m_Name = sb.m_Name; - m_RegisterOffset = sb.m_RegisterOffset; - m_BindingSlot = sb.m_BindingSlot; - m_RegisterCount = sb.m_RegisterCount; - m_Flags = sb.m_Flags; - } - SCGBind& operator = (const SCGBind& sb) - { - this->~SCGBind(); - new(this)SCGBind(sb); - return *this; - } - int Size() - { - return sizeof(SCGBind); - } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct SParamData -{ - CCryNameR m_CompNames[4]; - union UData - { - uint64 nData64[4]; - uint32 nData32[4]; - float fData[4]; - } d; - SParamData() - { - memset(&d, 0, sizeof(UData)); - } - ~SParamData(); - SParamData(const SParamData& sp); - SParamData& operator = (const SParamData& sp) - { - this->~SParamData(); - new(this)SParamData(sp); - return *this; - } - unsigned Size() { return sizeof(SParamData); } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -struct SCGLiteral -{ - int m_nIndex; - //Vec4 m_vVec; - unsigned Size() { return sizeof(SCGLiteral); } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -//----------------------------------------------------------------------------- -// This is the binding structure for constant data parsed by the shader parser -// and is to be bound in the shader. -//----------------------------------------------------------------------------- -struct SCGParam - : SCGBind -{ - ECGParam m_eCGParamType; - SParamData* m_pData; - UINT_PTR m_nID; - SCGParam() - { - m_eCGParamType = ECGP_Unknown; - m_pData = NULL; - m_nID = 0; - } - ~SCGParam() - { - SAFE_DELETE(m_pData); - } - SCGParam(const SCGParam& sp) - : SCGBind(sp) - { - m_eCGParamType = sp.m_eCGParamType; - m_nID = sp.m_nID; - if (sp.m_pData) - { - m_pData = new SParamData; - *m_pData = *sp.m_pData; - } - else - { - m_pData = NULL; - } - } - SCGParam& operator = (const SCGParam& sp) - { - this->~SCGParam(); - new(this)SCGParam(sp); - return *this; - } - bool operator != (const SCGParam& sp) const - { - if (sp.m_RegisterOffset == m_RegisterOffset && - sp.m_Name == m_Name && - sp.m_nID == m_nID && - sp.m_RegisterCount == m_RegisterCount && - sp.m_eCGParamType == m_eCGParamType && - sp.m_BindingSlot == m_BindingSlot && - sp.m_Flags == m_Flags && - !sp.m_pData && !m_pData) - { - return false; - } - return true; - } - - const CCryNameR GetParamCompName(int nComp) const - { - if (!m_pData) - { - return CCryNameR("None"); - } - return m_pData->m_CompNames[nComp]; - } - - int Size() - { - int nSize = sizeof(SCGParam); - if (m_pData) - { - nSize += m_pData->Size(); - } - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_pData); - } -}; - - -enum ECGSampler -{ - ECGS_Unknown, - ECGS_MatSlot_Diffuse, - ECGS_MatSlot_Normalmap, - ECGS_MatSlot_Gloss, - ECGS_MatSlot_Env, - ECGS_Shadow0, - ECGS_Shadow1, - ECGS_Shadow2, - ECGS_Shadow3, - ECGS_Shadow4, - ECGS_Shadow5, - ECGS_Shadow6, - ECGS_Shadow7, - ECGS_TrilinearClamp, - ECGS_MatAnisoHighWrap, - ECGS_MatAnisoLowWrap, - ECGS_MatTrilinearWrap, - ECGS_MatBilinearWrap, - ECGS_MatTrilinearClamp, - ECGS_MatBilinearClamp, - ECGS_MatAnisoHighBorder, - ECGS_MatTrilinearBorder, - ECGS_COUNT -}; - -struct SCGSampler - : SCGBind -{ - int m_nStateHandle; - ECGSampler m_eCGSamplerType; - SCGSampler() - { - m_nStateHandle = -1; - m_eCGSamplerType = ECGS_Unknown; - } - ~SCGSampler() - { - } - SCGSampler(const SCGSampler& sp) - : SCGBind(sp) - { - m_eCGSamplerType = sp.m_eCGSamplerType; - m_nStateHandle = sp.m_nStateHandle; - } - SCGSampler& operator = (const SCGSampler& sp) - { - this->~SCGSampler(); - new(this)SCGSampler(sp); - return *this; - } - bool operator != (const SCGSampler& sp) const - { - if (sp.m_RegisterOffset == m_RegisterOffset && - sp.m_Name == m_Name && - sp.m_nStateHandle == m_nStateHandle && - sp.m_RegisterCount == m_RegisterCount && - sp.m_eCGSamplerType == m_eCGSamplerType && - sp.m_BindingSlot == m_BindingSlot && - sp.m_Flags == m_Flags) - { - return false; - } - return true; - } - - int Size() - { - int nSize = sizeof(SCGSampler); - return nSize; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const - { - } -}; - - - -enum ECGTexture -{ - ECGT_Unknown, - ECGT_MatSlot_Diffuse, // @adiblev - move this to the end in order to support dynamically growing number - ECGT_MatSlot_Normals, - ECGT_MatSlot_Height, - ECGT_MatSlot_Specular, - ECGT_MatSlot_Env, - ECGT_MatSlot_SubSurface, - ECGT_MatSlot_Smoothness, - ECGT_MatSlot_DecalOverlay, - ECGT_MatSlot_Custom, - ECGT_MatSlot_CustomSecondary, - ECGT_MatSlot_Opacity, - ECGT_MatSlot_Detail, - ECGT_MatSlot_Emittance, - ECGT_MatSlot_Occlusion, - ECGT_MatSlot_Specular2, - ECGT_SF_Slot0, - ECGT_SF_Slot1, - ECGT_SF_SlotY, - ECGT_SF_SlotU, - ECGT_SF_SlotV, - ECGT_SF_SlotA, - ECGT_Shadow0, - ECGT_Shadow1, - ECGT_Shadow2, - ECGT_Shadow3, - ECGT_Shadow4, - ECGT_Shadow5, - ECGT_Shadow6, - ECGT_Shadow7, - ECGT_ShadowMask, - ECGT_ZTarget, - ECGT_ZTargetScaled, - ECGT_ZTargetMS, - ECGT_ShadowMaskZTarget, - ECGT_SceneNormalsBent, - ECGT_SceneNormals, - ECGT_SceneDiffuse, - ECGT_SceneSpecular, - ECGT_SceneDiffuseAcc, - ECGT_SceneSpecularAcc, - ECGT_SceneNormalsMapMS, - ECGT_SceneDiffuseAccMS, - ECGT_SceneSpecularAccMS, - ECGT_VolumetricClipVolumeStencil, - ECGT_VolumetricFog, - ECGT_VolumetricFogGlobalEnvProbe0, - ECGT_VolumetricFogGlobalEnvProbe1, - ECGT_COUNT -}; - -class CTexAnim; - -//----------------------------------------------------------------------------- -// This is the binding structure for texture data parsed by the shader parser -// as well as its binding to the shader (bind slot). -//----------------------------------------------------------------------------- -struct SCGTexture : SCGBind -{ - CTexture* m_pTexture; - CTexAnim* m_pAnimInfo; - ECGTexture m_eCGTextureType; - bool m_bSRGBLookup; - bool m_bGlobal; - - SCGTexture() - { - m_pTexture = nullptr; - m_pAnimInfo = nullptr; - m_eCGTextureType = ECGT_Unknown; - m_bSRGBLookup = false; - m_bGlobal = false; - } - ~SCGTexture(); - SCGTexture(const SCGTexture& sp); - SCGTexture& operator = (const SCGTexture& sp) - { - this->~SCGTexture(); - new(this)SCGTexture(sp); - return *this; - } - bool operator != (const SCGTexture& sp) const - { - if (sp.m_RegisterOffset == m_RegisterOffset && - sp.m_Name == m_Name && - sp.m_pTexture == m_pTexture && - sp.m_RegisterCount == m_RegisterCount && - sp.m_eCGTextureType == m_eCGTextureType && - sp.m_BindingSlot == m_BindingSlot && - sp.m_Flags == m_Flags && - sp.m_pAnimInfo == m_pAnimInfo && - sp.m_bSRGBLookup == m_bSRGBLookup && - sp.m_bGlobal == m_bGlobal) - { - return false; - } - return true; - } - - CTexture* GetTexture() const; - - int Size() - { - int nSize = sizeof(SCGTexture); - return nSize; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const - { - } -}; diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCore.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderCore.cpp deleted file mode 100644 index 237d33d2aa..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderCore.cpp +++ /dev/null @@ -1,3763 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : implementation of the Shaders manager. - - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "CryHeaders.h" -#include "CryPath.h" -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SHADERCORE_CPP_SECTION_1 1 -#define SHADERCORE_CPP_SECTION_2 2 -#endif - -CShader* CShaderMan::s_DefaultShader; -CShader* CShaderMan::s_shPostEffects; -CShader* CShaderMan::s_shPostDepthOfField; -CShader* CShaderMan::s_shPostMotionBlur; -CShader* CShaderMan::s_shPostSunShafts; -CShader* CShaderMan::s_shDeferredShading; -CShader* CShaderMan::s_ShaderDeferredCaustics; -CShader* CShaderMan::s_ShaderDeferredRain; -CShader* CShaderMan::s_ShaderDeferredSnow; -#ifndef NULL_RENDERER -CShader* CShaderMan::s_ShaderFPEmu; -CShader* CShaderMan::s_ShaderUI; -CShader* CShaderMan::s_ShaderFallback; -CShader* CShaderMan::s_ShaderStars; - -CShader* CShaderMan::s_ShaderShadowBlur; -CShader* CShaderMan::s_ShaderShadowMaskGen; -#if defined(FEATURE_SVO_GI) -CShader* CShaderMan::s_ShaderSVOGI; -#endif -CShader* CShaderMan::s_shHDRPostProcess; -CShader* CShaderMan::s_ShaderDebug; -CShader* CShaderMan::s_ShaderLensOptics; -CShader* CShaderMan::s_ShaderSoftOcclusionQuery; -CShader* CShaderMan::s_ShaderLightStyles; -CShader* CShaderMan::s_shPostEffectsGame; -CShader* CShaderMan::s_shPostAA; -CShader* CShaderMan::s_ShaderCommon; -CShader* CShaderMan::s_ShaderOcclTest; -CShader* CShaderMan::s_ShaderDXTCompress = nullptr; -CShader* CShaderMan::s_ShaderStereo = nullptr; -CShader* CShaderMan::s_ShaderFur = nullptr; -CShader* CShaderMan::s_ShaderVideo = nullptr; -#else -SShaderItem CShaderMan::s_DefaultShaderItem; -#endif - -CCryNameTSCRC CShaderMan::s_cNameHEAD; - -TArray CShader::s_ShaderResources_known; // Based on BatteryPark -TArray CLightStyle::s_LStyles; - -SResourceContainer* CShaderMan::s_pContainer; // List/Map of objects for shaders resource class -FXCompressedShaders CHWShader::m_CompressedShaders; - -uint64 g_HWSR_MaskBit[HWSR_MAX]; -AZStd::pair g_HWSST_Flags[] = -{ -#undef FX_STATIC_FLAG -#define FX_STATIC_FLAG(flag) AZStd::make_pair("%ST_"#flag, 0), -#include "ShaderStaticFlags.inl" -}; - -bool gbRgb; - -//////////////////////////////////////////////////////////////////////////////// -// Pool for texture modificators - -#if POOL_TEXMODIFICATORS - -SEfTexModPool::ModificatorList SEfTexModPool::s_pool; -volatile int SEfTexModPool::s_lockState = 0; - -SEfTexModificator* SEfTexModPool::Add(SEfTexModificator& mod) -{ - mod.m_crc = CCrc32::Compute((const char*)&mod, sizeof(SEfTexModificator) - sizeof(uint16) - sizeof(uint32)); - ModificatorList::iterator it = s_pool.find(mod.m_crc); - if (it != s_pool.end()) - { - ++((*it).second->m_refs); - return it->second; - } - mod.m_refs = 1; - SEfTexModificator* pMod = new SEfTexModificator(mod); - s_pool.insert(std::pair(mod.m_crc, pMod)); - - return pMod; -} - -void SEfTexModPool::AddRef(SEfTexModificator* pMod) -{ - Lock(); - if (pMod) - { - ++(pMod->m_refs); - } - Unlock(); -} - -void SEfTexModPool::Remove(SEfTexModificator* pMod) -{ - Lock(); - Remove_NoLock(pMod); - Unlock(); -} - -void SEfTexModPool::Remove_NoLock(SEfTexModificator* pMod) -{ - if (pMod) - { - if (pMod->m_refs > 1) - { - --(pMod->m_refs); - } - else - { - ModificatorList::iterator it = s_pool.find(pMod->m_crc); - if (it != s_pool.end()) - { - delete pMod; - s_pool.erase(it); - } - } - } -} - -void SEfTexModPool::Update(SEfTexModificator*& pMod, SEfTexModificator& newMod) -{ - Lock(); - if (pMod) - { - if (pMod->m_refs == 1) - { - *pMod = newMod; - } - else if (memcmp(pMod, &newMod, sizeof(SEfTexModificator) - sizeof(uint16) - sizeof(uint32))) // Ignore reference count and crc - { - Remove_NoLock(pMod); - pMod = Add(newMod); - } - } - else - { - pMod = Add(newMod); - } - Unlock(); -} - -void SEfTexModPool::Lock(void) -{ - CrySpinLock(&s_lockState, 0, 1); - // Locked -} - -void SEfTexModPool::Unlock(void) -{ - CrySpinLock(&s_lockState, 1, 0); - // Unlocked -} -#endif - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - - -EShaderLanguage GetShaderLanguage() -{ - EShaderLanguage shaderLanguage = eSL_Unknown; - if (CParserBin::m_nPlatform == SF_ORBIS) - { - shaderLanguage = eSL_Orbis; - } - else if (CParserBin::m_nPlatform == SF_D3D11) - { - shaderLanguage = eSL_D3D11; - } - else if (CParserBin::m_nPlatform == SF_GL4) - { - shaderLanguage = eSL_GL4_4; - } - else if (CParserBin::m_nPlatform == SF_GLES3) - { - shaderLanguage = gRenDev->m_cEF.HasStaticFlag(HWSST_GLES3_0) ? eSL_GLES3_0 : eSL_GLES3_1; - } - else if (CParserBin::m_nPlatform == SF_METAL) - { - shaderLanguage = eSL_METAL; - } - else if (CParserBin::m_nPlatform == SF_JASPER) - { - shaderLanguage = eSL_Jasper; - } - - return shaderLanguage; -} - -const char* GetShaderLanguageName() -{ - static const char *platformNames[eSL_MAX] = - { - "Unknown", - "Orbis", - "D3D11", - "GL4", - "GL4", - "GLES3", - "GLES3", - "METAL", - "Jasper" - }; - - EShaderLanguage shaderLanguage = GetShaderLanguage(); - return platformNames[shaderLanguage]; -} - -const char* GetShaderLanguageResourceName() -{ - static const char *platformResourceNames[eSL_MAX] = - { - "(UNK)", - "(O)", - "(DX1)", - "(G4)", - "(G4)", - "(E3)", - "(E3)", - "(MET)", - "(JAS)" - }; - - EShaderLanguage shaderLanguage = GetShaderLanguage(); - return platformResourceNames[shaderLanguage]; -} - -AZStd::string GetShaderListFilename() -{ - return AZStd::string::format("ShaderList_%s.txt", GetShaderLanguageName()); -} - - -////////////////////////////////////////////////////////////////////////// -// Global shader parser helper pointer. -CShaderParserHelper* g_pShaderParserHelper = 0; - -//================================================================================================= - -int CShader::GetTexId() -{ - CTexture* tp = (CTexture*)GetBaseTexture(NULL, NULL); - if (!tp) - { - return -1; - } - return tp->GetTextureID(); -} - -int CShader::mfSize() -{ - uint32 i; - - int nSize = sizeof(CShader); - nSize += m_NameFile.capacity(); - nSize += m_NameShader.capacity(); - nSize += m_HWTechniques.GetMemoryUsage(); - for (i = 0; i < m_HWTechniques.Num(); i++) - { - nSize += m_HWTechniques[i]->Size(); - } - - return nSize; -} - -void CShader::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->Add(*this); - pSizer->AddObject(m_NameFile); - pSizer->AddObject(m_NameShader); - pSizer->AddObject(m_HWTechniques); -} - -void CShader::mfFree() -{ - uint32 i; - - for (i = 0; i < m_HWTechniques.Num(); i++) - { - SShaderTechnique* pTech = m_HWTechniques[i]; - SAFE_DELETE(pTech); - } - m_HWTechniques.Free(); - - //SAFE_DELETE(m_ShaderGenParams); - m_Flags &= ~(EF_PARSE_MASK | EF_NODRAW); - m_nMDV = 0; -} - -CShader::~CShader() -{ - gRenDev->m_cEF.m_Bin.mfRemoveFXParams(this); - - if (m_pGenShader && m_pGenShader->m_DerivedShaders) - { - uint32 i; - for (i = 0; i < m_pGenShader->m_DerivedShaders->size(); i++) - { - CShader* pSH = (*m_pGenShader->m_DerivedShaders)[i]; - if (pSH == this) - { - (*m_pGenShader->m_DerivedShaders)[i] = NULL; - break; - } - } - assert(i != m_pGenShader->m_DerivedShaders->size()); - } - mfFree(); - - SAFE_RELEASE(m_pGenShader); - SAFE_DELETE(m_DerivedShaders); -} - -CShader& CShader::operator = (const CShader& src) -{ - uint32 i; - - mfFree(); - - int Offs = (int)(INT_PTR)&(((CShader*)0)->m_eSHDType); - byte* d = (byte*)this; - byte* s = (byte*)&src; - memcpy(&d[Offs], &s[Offs], sizeof(CShader) - Offs); - - m_NameShader = src.m_NameShader; - m_NameFile = src.m_NameFile; - m_NameShaderICRC = src.m_NameShaderICRC; - - if (src.m_HWTechniques.Num()) - { - m_HWTechniques.Create(src.m_HWTechniques.Num()); - for (i = 0; i < src.m_HWTechniques.Num(); i++) - { - m_HWTechniques[i] = new SShaderTechnique(this); - *m_HWTechniques[i] = *src.m_HWTechniques[i]; - m_HWTechniques[i]->m_shader = this; // copy operator will override m_shader - } - } - - return *this; -} - -SShaderPass::SShaderPass() -{ - m_RenderState = GS_DEPTHWRITE; - - m_PassFlags = 0; - m_AlphaRef = ~0; - - m_VShader = NULL; - m_PShader = NULL; - m_GShader = NULL; - m_DShader = NULL; - m_HShader = NULL; -} - - -bool SShaderItem::IsMergable(SShaderItem& PrevSI) -{ - if (!PrevSI.m_pShader) - { - return true; - } - CShaderResources* pRP = (CShaderResources*)PrevSI.m_pShaderResources; - CShaderResources* pR = (CShaderResources*)m_pShaderResources; - if (pRP && pR) - { - if (pRP->m_AlphaRef != pR->m_AlphaRef) - { - return false; - } - if (pRP->GetStrengthValue(EFTT_OPACITY) != pR->GetStrengthValue(EFTT_OPACITY)) - { - return false; - } - if (pRP->m_pDeformInfo != pR->m_pDeformInfo) - { - return false; - } - if ((pRP->m_ResFlags & MTL_FLAG_2SIDED) != (pR->m_ResFlags & MTL_FLAG_2SIDED)) - { - return false; - } - if ((pRP->m_ResFlags & MTL_FLAG_NOSHADOW) != (pR->m_ResFlags & MTL_FLAG_NOSHADOW)) - { - return false; - } - if (m_pShader->GetCull() != PrevSI.m_pShader->GetCull()) - { - return false; - } - } - return true; -} - -void SShaderTechnique::UpdatePreprocessFlags([[maybe_unused]] CShader* pSH) -{ - uint32 i; - for (i = 0; i < m_Passes.Num(); i++) - { - SShaderPass* pPass = &m_Passes[i]; - if (pPass->m_PShader) - { - pPass->m_PShader->mfUpdatePreprocessFlags(this); - } - } -} - -SShaderTechnique* CShader::mfGetStartTechnique(int nTechnique) -{ - FUNCTION_PROFILER_RENDER_FLAT - SShaderTechnique* pTech; - if (m_HWTechniques.Num()) - { - pTech = m_HWTechniques[0]; - if (nTechnique > 0) - { - assert(nTechnique < (int)m_HWTechniques.Num()); - if (nTechnique < (int)m_HWTechniques.Num()) - { - pTech = m_HWTechniques[nTechnique]; - } - else - { - iLog->Log("ERROR: CShader::mfGetStartTechnique: Technique %d for shader '%s' is out of range", nTechnique, GetName()); - } - } - } - else - { - pTech = NULL; - } - - return pTech; -} -SShaderTechnique* CShader::GetTechnique(int nStartTechnique, int nRequestedTechnique) -{ - SShaderTechnique* pTech = 0; - if (m_HWTechniques.Num()) - { - pTech = m_HWTechniques[0]; - if (nStartTechnique > 0) - { - assert(nStartTechnique < (int)m_HWTechniques.Num()); - if (nStartTechnique < (int)m_HWTechniques.Num()) - { - pTech = m_HWTechniques[nStartTechnique]; - } - else - { - LogWarning("ERROR: CShader::GetTechnique: Technique %d for shader '%s' is out of range", nStartTechnique, GetName()); - } - } - } - else - { - pTech = nullptr; - } - - if (!pTech || - pTech->m_nTechnique[nRequestedTechnique] < 0 || - pTech->m_nTechnique[nRequestedTechnique] >= (int)m_HWTechniques.Num()) - { - LogWarning("ERROR: CShader::GetTechnique: No Technique (%d,%d) for shader '%s' ", nStartTechnique, nRequestedTechnique, GetName()); - return nullptr; - } - pTech = m_HWTechniques[pTech->m_nTechnique[nRequestedTechnique]]; - - return pTech; -} - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) -void CShader::mfFlushCache() -{ - uint32 n, m; - - mfFlushPendedShaders(); - - if (SEmptyCombination::s_Combinations.size()) - { - // Flush the cache before storing any empty combinations - CHWShader::mfFlushPendedShadersWait(-1); - for (m = 0; m < SEmptyCombination::s_Combinations.size(); m++) - { - SEmptyCombination& Comb = SEmptyCombination::s_Combinations[m]; - Comb.pShader->mfStoreEmptyCombination(Comb); - } - SEmptyCombination::s_Combinations.clear(); - } - - for (m = 0; m < m_HWTechniques.Num(); m++) - { - SShaderTechnique* pTech = m_HWTechniques[m]; - for (n = 0; n < pTech->m_Passes.Num(); n++) - { - SShaderPass* pPass = &pTech->m_Passes[n]; - if (pPass->m_PShader) - { - pPass->m_PShader->mfFlushCacheFile(); - } - if (pPass->m_VShader) - { - pPass->m_VShader->mfFlushCacheFile(); - } - } - } -} -#endif - -void CShaderResources::PostLoad(CShader* pSH) -{ - AdjustForSpec(); - if (pSH && (pSH->m_Flags & EF_SKY)) - { - SEfResTexture* pTextureRes = GetTextureResource(EFTT_DIFFUSE); - if (pTextureRes && !pTextureRes->m_Name.empty()) - { - char sky[128]; - char path[1024]; - - azstrcpy(sky, AZ_ARRAY_SIZE(sky), pTextureRes->m_Name.c_str()); - int size = strlen(sky); - const char* ext = fpGetExtension(sky); - if (size > 0) - { - while (sky[size] != '_') - { - size--; - if (!size) - { - break; - } - } - } - sky[size] = 0; - if (size) - { - m_pSky = new SSkyInfo; - sprintf_s(path, "%s_12%s", sky, ext); - m_pSky->m_SkyBox[0] = CTexture::ForName(path, 0, eTF_Unknown); - sprintf_s(path, "%s_34%s", sky, ext); - m_pSky->m_SkyBox[1] = CTexture::ForName(path, 0, eTF_Unknown); - sprintf_s(path, "%s_5%s", sky, ext); - m_pSky->m_SkyBox[2] = CTexture::ForName(path, 0, eTF_Unknown); - } - } - } - - UpdateConstants(pSH); -} - -SShaderTexSlots* CShader::GetUsedTextureSlots(int nTechnique) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_ReflectTextureSlots) - { - return NULL; - } - if (nTechnique < 0 || nTechnique >= TTYPE_MAX) - { - return NULL; - } - return m_ShaderTexSlots[nTechnique]; -} - -AZStd::vector& CShader::GetPublicParams() -{ - SShaderFXParams& FXP = gRenDev->m_cEF.m_Bin.mfGetFXParams(this); - return FXP.m_PublicParams; -} - -CTexture* CShader::mfFindBaseTexture([[maybe_unused]] TArray& Passes, [[maybe_unused]] int* nPass, [[maybe_unused]] int* nTU) -{ - return NULL; -} - -ITexture* CShader::GetBaseTexture(int* nPass, int* nTU) -{ - for (uint32 i = 0; i < m_HWTechniques.Num(); i++) - { - SShaderTechnique* hw = m_HWTechniques[i]; - CTexture* tx = mfFindBaseTexture(hw->m_Passes, nPass, nTU); - if (tx) - { - return tx; - } - } - if (nPass) - { - *nPass = -1; - } - if (nTU) - { - *nTU = -1; - } - return NULL; -} - -unsigned int CShader::GetUsedTextureTypes (void) -{ - uint32 nMask = 0xffffffff; - - return nMask; -} - -//================================================================================ - -void CShaderMan::mfReleaseShaders () -{ - CCryNameTSCRC Name = CShader::mfGetClassName(); - - AUTO_LOCK(CBaseResource::s_cResLock); - - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - int n = 0; - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); ) - { - CShader* sh = (CShader*)itor->second; - itor++; - if (!sh) - { - continue; - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_printmemoryleaks && !(sh->m_Flags & EF_SYSTEM)) - { - iLog->Log("Warning: CShaderMan::mfClearAll: Shader %s was not deleted (%d)", sh->GetName(), sh->GetRefCounter()); - } - SAFE_RELEASE(sh); - n++; - } - } -} - -void CShaderMan::ShutDown(void) -{ - uint32 i; - - m_Bin.InvalidateCache(); - - mfReleaseSystemShaders(); - gRenDev->ForceFlushRTCommands(); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_releaseallresourcesonexit) - { - //if (gRenDev->m_cEF.m_bInitialized) - // mfReleaseShaders(); - - for (i = 0; i < CShader::s_ShaderResources_known.Num(); i++) - { - CShaderResources* pSR = CShader::s_ShaderResources_known[i]; - if (!pSR) - { - continue; - } - if (i) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_printmemoryleaks) - { - iLog->Log("Warning: CShaderMan::mfClearAll: Shader resource %p was not deleted", pSR); - } - } - delete pSR; - } - CShader::s_ShaderResources_known.Free(); - } - - { - AZStd::unique_lock lock(m_shaderLoadMutex); - - m_ShaderNames.clear(); - - std::for_each(m_pShadersGlobalFlags.begin(), m_pShadersGlobalFlags.end(), SShaderMapNameFlagsContainerDelete()); - - m_pShadersGlobalFlags.clear(); - m_pShaderCommonGlobalFlag.clear(); - } - - - CCryNameTSCRC Name; - - SAFE_DELETE(m_pGlobalExt); - - for (i = 0; i < CLightStyle::s_LStyles.Num(); i++) - { - delete CLightStyle::s_LStyles[i]; - } - CLightStyle::s_LStyles.Free(); - m_SGC.clear(); - m_ShaderCacheCombinations[0].clear(); - m_ShaderCacheCombinations[1].clear(); - m_ShaderCacheExportCombinations.clear(); - SAFE_DELETE(m_pGlobalExt); - mfCloseShadersCache(0); - mfCloseShadersCache(1); - - m_bInitialized = false; - - Terrain::TerrainShaderRequestBus::Handler::BusDisconnect(); - AZ::MaterialNotificationEventBus::Handler::BusDisconnect(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CShaderMan:: mfCreateCommonGlobalFlags([[maybe_unused]] const char* szName) -{ - // Create globals.txt - - assert(szName); - uint32 nCurrMaskCount = 0; - const char* pszShaderExtPath = "Shaders/"; - - char dirn[256]; - cry_strcpy(dirn, pszShaderExtPath); - cry_strcat(dirn, "*"); - - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst (dirn); - if (!handle)// failed search - { - return; - } - - do - { - // Scan for extension script files - add common flags names into globals list - - if (handle.m_filename.front() == '.' || (handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - continue; - } - - const char* pszExt = PathUtil::GetExt(handle.m_filename.data()); - if (azstricmp(pszExt, "ext")) - { - continue; - } - - - char pszFileName[256]; - azsnprintf(pszFileName, AZ_ARRAY_SIZE(pszFileName), "%s%.*s", pszShaderExtPath, aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - if (AZ::IO::FileIOBase::GetInstance()->Open(pszFileName, AZ::IO::OpenMode::ModeRead, fileHandle)) - { - - AZ::u64 fileSize = 0; - AZ::u64 bytesRead = 0; - AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileSize); - char* buf = new char [fileSize + 1]; - AZ::IO::FileIOBase::GetInstance()->Read(fileHandle, buf, fileSize, false, &bytesRead); - AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); - buf[bytesRead] = 0; - - // Check if global flags are common - char* pCurrOffset = strstr(buf, "UsesCommonGlobalFlags"); - if (pCurrOffset) - { - AZStd::unique_lock lock(m_shaderLoadMutex); - - // add shader to list - string pszShaderName = PathUtil::GetFileName(handle.m_filename.data()); - pszShaderName.MakeUpper(); - m_pShadersRemapList += string("%") + pszShaderName; - - pCurrOffset = strstr(pCurrOffset, "Name"); - while (pCurrOffset) - { - pCurrOffset += 4; - char dummy[256] = "\n"; - char name[256] = "\n"; -#ifndef NDEBUG - int res = -#endif - azsscanf(pCurrOffset, "%s %s", dummy -#if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS - , (unsigned int)AZ_ARRAY_SIZE(dummy) -#endif - , name -#if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS - , (unsigned int)AZ_ARRAY_SIZE(name) -#endif - ); // Get flag name.. - assert(res); - - string pszNameFlag = name; - pszNameFlag.MakeUpper(); - - MapNameFlagsItor pCheck = m_pShaderCommonGlobalFlag.find(pszNameFlag); - if (pCheck == m_pShaderCommonGlobalFlag.end()) - { - m_pShaderCommonGlobalFlag.insert(MapNameFlagsItor::value_type(pszNameFlag, 0)); - if (++nCurrMaskCount >= 64) // sanity check - { - assert(0); - break; - } - } - pCurrOffset = strstr(pCurrOffset, "Name"); - } - } - - SAFE_DELETE_ARRAY(buf); - } - - if (nCurrMaskCount >= 64) - { - break; - } - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); - - if (nCurrMaskCount >= 64) - { - iLog->Log("ERROR: CShaderMan::mfCreateCommonGlobalFlags: too many common global flags"); - } - - uint64 nCurrGenMask = 0; - - { - AZStd::unique_lock lock(m_shaderLoadMutex); - - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin(); - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - for (; pIter != pEnd; ++pIter, ++nCurrGenMask) - { - // Set mask value - pIter->second = ((uint64)1) << nCurrGenMask; - } - } - - mfRemapCommonGlobalFlagsWithLegacy(); -#if !defined (_RELEASE) - if (nCurrMaskCount > 0) - { - mfSaveCommonGlobalFlagsToDisk(szName, nCurrMaskCount); - } -#endif -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CShaderMan::mfSaveCommonGlobalFlagsToDisk(const char* szName, [[maybe_unused]] uint32 nMaskCount) -{ - // Write all flags - assert(nMaskCount); - - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(szName, "w"); - if (fileHandle != AZ::IO::InvalidHandle) - { - gEnv->pCryPak->FPrintf(fileHandle, "FX_CACHE_VER %f\n", FX_CACHE_VER); - gEnv->pCryPak->FPrintf(fileHandle, "%s\n\n", m_pShadersRemapList.c_str()); - - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin(); - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - - for (; pIter != pEnd; ++pIter) - { - gEnv->pCryPak->FPrintf(fileHandle, "%s " -#if defined(__GNUC__) - "%llx\n" -#else - "%I64x\n" -#endif - , (pIter->first).c_str(), pIter->second); - } - - gEnv->pCryPak->FClose(fileHandle); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CShaderMan::mfInitCommonGlobalFlagsLegacyFix(void) -{ - // Store original values since common material flags where introduced - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%ALPHAGLOW", (uint64)0x2)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%ALPHAMASK_DETAILMAP", (uint64)0x4)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%ANISO_SPECULAR", (uint64)0x8)); - - // 0x10 is unused - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%BUMP_DIFFUSE", (uint64)0x20)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%CHARACTER_DECAL", (uint64)0x40)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%CUSTOM_SPECULAR", (uint64)0x400)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%DECAL", (uint64)0x800)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%DETAIL_BENDING", (uint64)0x1000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%DETAIL_BUMP_MAPPING", (uint64)0x2000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%DISABLE_RAIN_PASS", (uint64)0x4000)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%ENVIRONMENT_MAP", (uint64)0x10000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%EYE_OVERLAY", (uint64)0x20000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%GLOSS_DIFFUSEALPHA", (uint64)0x40000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%GLOSS_MAP", (uint64)0x80000)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%GRADIENT_COLORING", (uint64)0x100000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%GRASS", (uint64)0x200000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%IRIS", (uint64)0x400000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%LEAVES", (uint64)0x800000)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%NANOSUIT_EFFECTS", (uint64)0x1000000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%OFFSET_BUMP_MAPPING", (uint64)0x2000000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%PARALLAX_OCCLUSION_MAPPING", (uint64)0x8000000)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%REALTIME_MIRROR_REFLECTION", (uint64)0x10000000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%REFRACTION_MAP", (uint64)0x20000000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%RIM_LIGHTING", (uint64)0x40000000)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%SPECULARPOW_GLOSSALPHA", (uint64)0x80000000)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%TEMP_TERRAIN", (uint64)0x200000000ULL)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%TEMP_VEGETATION", (uint64)0x400000000ULL)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%TERRAINHEIGHTADAPTION", (uint64)0x800000000ULL)); - - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%TWO_SIDED_SORTING", (uint64)0x1000000000ULL)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%VERTCOLORS", (uint64)0x2000000000ULL)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%WIND_BENDING", (uint64)0x4000000000ULL)); - m_pSCGFlagLegacyFix.insert(MapNameFlagsItor::value_type("%WRINKLE_BLENDING", (uint64)0x8000000000ULL)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CShaderMan::mfRemapCommonGlobalFlagsWithLegacy(void) -{ - MapNameFlagsItor pFixIter = m_pSCGFlagLegacyFix.begin(); - MapNameFlagsItor pFixEnd = m_pSCGFlagLegacyFix.end(); - - AZStd::unique_lock lock(m_shaderLoadMutex); - - MapNameFlagsItor pCommonGlobalsEnd = m_pShaderCommonGlobalFlag.end(); - - bool bRemaped = false; - for (; pFixIter != pFixEnd; ++pFixIter) - { - MapNameFlagsItor pFoundMatch = m_pShaderCommonGlobalFlag.find(pFixIter->first); - if (pFoundMatch != pCommonGlobalsEnd) - { - // Found a match, replace value - uint64 nRemapedMask = pFixIter->second; - uint64 nOldMask = pFoundMatch->second; - pFoundMatch->second = nRemapedMask; - - // Search for duplicates and swap with old mask - MapNameFlagsItor pCommonGlobalsIter = m_pShaderCommonGlobalFlag.begin(); - for (; pCommonGlobalsIter != pCommonGlobalsEnd; ++pCommonGlobalsIter) - { - if (pFoundMatch != pCommonGlobalsIter && pCommonGlobalsIter->second == nRemapedMask) - { - pCommonGlobalsIter->second = nOldMask; - bRemaped = true; - break; - } - } - } - } - - // Create existing flags mask - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin(); - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - m_nSGFlagsFix = 0; - for (; pIter != pEnd; ++pIter) - { - m_nSGFlagsFix |= (pIter->second); - } - - return bRemaped; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CShaderMan::mfInitCommonGlobalFlags(void) -{ - mfInitCommonGlobalFlagsLegacyFix(); - - AZStd::string pszGlobalsPath = m_szCachePath + CONCAT_PATHS(g_shaderCache,"globals.txt"); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(pszGlobalsPath.c_str(), "r", AZ::IO::IArchive::FOPEN_HINT_QUIET); - if (fileHandle != AZ::IO::InvalidHandle) - { - char str[256] = "\n"; - char name[128] = "\n"; - - gEnv->pCryPak->FGets(str, 256, fileHandle); - if (strstr(str, "FX_CACHE_VER")) - { - float fCacheVer = 0.0f; -#ifndef NDEBUG - int res = -#endif - azsscanf(str, "%s %f", - name, -#if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS - (unsigned int)AZ_ARRAY_SIZE(name), -#endif - &fCacheVer); - assert(res); - if (!azstricmp(name, "FX_CACHE_VER") && fabs(FX_CACHE_VER - fCacheVer) >= 0.01f) - { - gEnv->pCryPak->FClose(fileHandle); - // re-create common global flags (shader cache bumped) - mfCreateCommonGlobalFlags(pszGlobalsPath.c_str()); - - return; - } - } - - // get shader that need remapping slist - gEnv->pCryPak->FGets(str, 256, fileHandle); - - uint32 nCurrMaskCount = 0; - { - AZStd::unique_lock lock(m_shaderLoadMutex); - - m_pShadersRemapList = str; - - while (!gEnv->pCryPak->FEof(fileHandle)) - { - uint64 nGenMask = 0; - gEnv->pCryPak->FGets(str, 256, fileHandle); - - if (azsscanf(str, "%s " -#if defined(__GNUC__) - "%llx" -#else - "%I64x" -#endif - , name, -#if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS - (unsigned int)AZ_ARRAY_SIZE(name), -#endif - &nGenMask) > 1) - { - m_pShaderCommonGlobalFlag.insert(MapNameFlagsItor::value_type(name, nGenMask)); - nCurrMaskCount++; - } - } - } - - gEnv->pCryPak->FClose(fileHandle); - - if (mfRemapCommonGlobalFlagsWithLegacy()) - { - mfSaveCommonGlobalFlagsToDisk(pszGlobalsPath.c_str(), nCurrMaskCount); - } - - return; - } - - // create common global flags - not existing globals.txt - mfCreateCommonGlobalFlags(pszGlobalsPath.c_str()); -} - -void CShaderMan::mfInitLookups() -{ - m_ResLookupDataMan[CACHE_READONLY].Clear(); - AZStd::string dirdatafilename(m_ShadersCache); - dirdatafilename += "lookupdata.bin"; - m_ResLookupDataMan[CACHE_READONLY].LoadData(dirdatafilename.c_str(), CParserBin::m_bEndians, true); - - m_ResLookupDataMan[CACHE_USER].Clear(); - dirdatafilename = m_szCachePath + m_ShadersCache; - dirdatafilename += "lookupdata.bin"; - m_ResLookupDataMan[CACHE_USER].LoadData(dirdatafilename.c_str(), CParserBin::m_bEndians, false); -} -void CShaderMan::mfInitLevelPolicies(void) -{ - SAFE_DELETE(m_pLevelsPolicies); - - SShaderLevelPolicies* pPL = NULL; - char szN[256]; - cry_strcpy(szN, "Shaders/"); - cry_strcat(szN, "Levels.txt"); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(szN, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET); - if (fileHandle != AZ::IO::InvalidHandle) - { - pPL = new SShaderLevelPolicies; - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileSize); - char* buf = new char [fileSize + 1]; - if (buf) - { - buf[fileSize] = 0; - gEnv->pCryPak->FRead(buf, fileSize, fileHandle); - mfCompileShaderLevelPolicies(pPL, buf); - delete [] buf; - } - gEnv->pCryPak->FClose(fileHandle); - } - m_pLevelsPolicies = pPL; -} - -void CShaderMan::mfInitGlobal (void) -{ - SAFE_DELETE(m_pGlobalExt); - SShaderGen* pShGen = mfCreateShaderGenInfo("RunTime", true); - -#if defined(_RELEASE) - AZ_Assert(pShGen, "Fatal error: could not find required shader 'RunTime'. This is typically placed in @assets@/shaders.pak for release builds. Make sure BuildReleaseAuxiliaryContent.py has been run and all shaders have been included in the release packaging build."); -#endif - - m_pGlobalExt = pShGen; - if (pShGen) - { - uint32 i; - - for (i = 0; i < pShGen->m_BitMask.Num(); i++) - { - SShaderGenBit* gb = pShGen->m_BitMask[i]; - if (!gb) - { - continue; - } - if (gb->m_ParamName == "%_RT_FOG") - { - g_HWSR_MaskBit[HWSR_FOG] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_AMBIENT") - { - g_HWSR_MaskBit[HWSR_AMBIENT] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_HDR_ENCODE") - { - g_HWSR_MaskBit[HWSR_HDR_ENCODE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_ALPHATEST") - { - g_HWSR_MaskBit[HWSR_ALPHATEST] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_HDR_MODE") - { - g_HWSR_MaskBit[HWSR_HDR_MODE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_NEAREST") - { - g_HWSR_MaskBit[HWSR_NEAREST] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SHADOW_MIXED_MAP_G16R16") - { - g_HWSR_MaskBit[HWSR_SHADOW_MIXED_MAP_G16R16] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_HW_PCF_COMPARE") - { - g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE0") - { - g_HWSR_MaskBit[HWSR_SAMPLE0] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE1") - { - g_HWSR_MaskBit[HWSR_SAMPLE1] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE2") - { - g_HWSR_MaskBit[HWSR_SAMPLE2] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE3") - { - g_HWSR_MaskBit[HWSR_SAMPLE3] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_ALPHABLEND") - { - g_HWSR_MaskBit[HWSR_ALPHABLEND] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_QUALITY") - { - g_HWSR_MaskBit[HWSR_QUALITY] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_QUALITY1") - { - g_HWSR_MaskBit[HWSR_QUALITY1] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_INSTANCING_ATTR") - { - g_HWSR_MaskBit[HWSR_INSTANCING_ATTR] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_NOZPASS") - { - g_HWSR_MaskBit[HWSR_NOZPASS] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_NO_TESSELLATION") - { - g_HWSR_MaskBit[HWSR_NO_TESSELLATION] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_APPLY_TOON_SHADING") - { - g_HWSR_MaskBit[HWSR_APPLY_TOON_SHADING] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_VERTEX_VELOCITY") - { - g_HWSR_MaskBit[HWSR_VERTEX_VELOCITY] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_OBJ_IDENTITY") - { - g_HWSR_MaskBit[HWSR_OBJ_IDENTITY] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SKINNING_DUAL_QUAT") - { - g_HWSR_MaskBit[HWSR_SKINNING_DUAL_QUAT] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SKINNING_DQ_LINEAR") - { - g_HWSR_MaskBit[HWSR_SKINNING_DQ_LINEAR] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SKINNING_MATRIX") - { - g_HWSR_MaskBit[HWSR_SKINNING_MATRIX] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DISSOLVE") - { - g_HWSR_MaskBit[HWSR_DISSOLVE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SOFT_PARTICLE") - { - g_HWSR_MaskBit[HWSR_SOFT_PARTICLE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_LIGHT_TEX_PROJ") - { - g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SHADOW_JITTERING") - { - g_HWSR_MaskBit[HWSR_SHADOW_JITTERING] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_PARTICLE_SHADOW") - { - g_HWSR_MaskBit[HWSR_PARTICLE_SHADOW] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_BLEND_WITH_TERRAIN_COLOR") - { - // Just leaving this here for backwards compatibility - nothing to do - } - else - if (gb->m_ParamName == "%_RT_SPRITE") - { - g_HWSR_MaskBit[HWSR_SPRITE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEBUG0") - { - g_HWSR_MaskBit[HWSR_DEBUG0] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEBUG1") - { - g_HWSR_MaskBit[HWSR_DEBUG1] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEBUG2") - { - g_HWSR_MaskBit[HWSR_DEBUG2] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEBUG3") - { - g_HWSR_MaskBit[HWSR_DEBUG3] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_POINT_LIGHT") - { - g_HWSR_MaskBit[HWSR_POINT_LIGHT] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_CUBEMAP0") - { - g_HWSR_MaskBit[HWSR_CUBEMAP0] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DECAL_TEXGEN_2D") - { - g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_OCEAN_PARTICLE") - { - g_HWSR_MaskBit[HWSR_OCEAN_PARTICLE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE4") - { - g_HWSR_MaskBit[HWSR_SAMPLE4] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SAMPLE5") - { - g_HWSR_MaskBit[HWSR_SAMPLE5] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_FOG_VOLUME_HIGH_QUALITY_SHADER") - { - g_HWSR_MaskBit[HWSR_FOG_VOLUME_HIGH_QUALITY_SHADER] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_APPLY_SSDO") - { - g_HWSR_MaskBit[HWSR_APPLY_SSDO] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_GLOBAL_ILLUMINATION") - { - g_HWSR_MaskBit[HWSR_GLOBAL_ILLUMINATION] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_ANIM_BLEND") - { - g_HWSR_MaskBit[HWSR_ANIM_BLEND] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_MOTION_BLUR") - { - g_HWSR_MaskBit[HWSR_MOTION_BLUR] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_ENVIRONMENT_CUBEMAP") - { - g_HWSR_MaskBit[HWSR_ENVIRONMENT_CUBEMAP] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_LIGHTVOLUME0") - { - g_HWSR_MaskBit[HWSR_LIGHTVOLUME0] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_LIGHTVOLUME1") - { - g_HWSR_MaskBit[HWSR_LIGHTVOLUME1] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_TILED_SHADING") - { - g_HWSR_MaskBit[HWSR_TILED_SHADING] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_VOLUMETRIC_FOG") - { - g_HWSR_MaskBit[HWSR_VOLUMETRIC_FOG] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_REVERSE_DEPTH") - { - g_HWSR_MaskBit[HWSR_REVERSE_DEPTH] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHADOW_PASS") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHADOW_PASS] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_GPU_PARTICLE_DEPTH_COLLISION") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_DEPTH_COLLISION] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_GPU_PARTICLE_TURBULENCE") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_TURBULENCE] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_GPU_PARTICLE_UV_ANIMATION") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_UV_ANIMATION] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_NORMAL_MAP") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_NORMAL_MAP] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_GLOW_MAP") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_GLOW_MAP] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_CUBEMAP_DEPTH_COLLISION") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_CUBEMAP_DEPTH_COLLISION] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_WRITEBACK_DEATH_LOCATIONS") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_WRITEBACK_DEATH_LOCATIONS] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_TARGET_ATTRACTION") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_TARGET_ATTRACTION] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHAPE_ANGLE") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHAPE_ANGLE] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHAPE_BOX") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHAPE_BOX] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHAPE_POINT") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHAPE_POINT] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHAPE_CIRCLE") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHAPE_CIRCLE] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_SHAPE_SPHERE") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHAPE_SPHERE] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_GPU_PARTICLE_WIND") - { - g_HWSR_MaskBit[HWSR_GPU_PARTICLE_WIND] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_MULTI_LAYER_ALPHA_BLEND") - { - g_HWSR_MaskBit[HWSR_MULTI_LAYER_ALPHA_BLEND] = gb->m_Mask; - } - else if (gb->m_ParamName == "%_RT_ADDITIVE_BLENDING") - { - g_HWSR_MaskBit[HWSR_ADDITIVE_BLENDING] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SRGB0") - { - g_HWSR_MaskBit[HWSR_SRGB0] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SRGB1") - { - g_HWSR_MaskBit[HWSR_SRGB1] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SRGB2") - { - g_HWSR_MaskBit[HWSR_SRGB2] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_SLIM_GBUFFER") - { - g_HWSR_MaskBit[HWSR_SLIM_GBUFFER] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEFERRED_RENDER_TARGET_OPTIMIZATION") - { - g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION] = gb->m_Mask; - } - else - if (gb->m_ParamName == "%_RT_DEPTHFIXUP") - { - g_HWSR_MaskBit[HWSR_DEPTHFIXUP] = gb->m_Mask; - } - else - { - AZ_Assert(false, "Invalid shader param %s", gb->m_ParamName.c_str()); - } - } - } -} - -void CShaderMan::InitStaticFlags() -{ - SAFE_DELETE(m_staticExt); - m_staticExt = mfCreateShaderGenInfo("Statics", true); - if (m_staticExt) - { - AZ_Assert(m_staticExt->m_BitMask.Num() == AZ_ARRAY_SIZE(g_HWSST_Flags), "Mismatch static flags count. Expected %u flags but got %u instead", AZ_ARRAY_SIZE(g_HWSST_Flags), m_staticExt->m_BitMask.Num()); - for (unsigned i = 0; i < m_staticExt->m_BitMask.Num(); ++i) - { - SShaderGenBit* gb = m_staticExt->m_BitMask[i]; - if (!gb) - { - continue; - } - - auto found = AZStd::find_if(std::begin(g_HWSST_Flags), std::end(g_HWSST_Flags), [&gb](const AZStd::pair& element) { return azstricmp(element.first, gb->m_ParamName) == 0; }); - if (found != std::end(g_HWSST_Flags)) - { - found->second = gb->m_Mask; - } - else - { - AZ_Error("Renderer", false, "Invalid static flag param %s", gb->m_ParamName.c_str()); - } - } - } -} - -void CShaderMan::AddStaticFlag(EHWSSTFlag flag) -{ - if (!m_staticExt) - { - InitStaticFlags(); - } - - AZ_Assert(static_cast(flag) >= 0 && static_cast(flag) < AZ_ARRAY_SIZE(g_HWSST_Flags), "Invalid static flag %d", static_cast(flag)); - m_staticFlags |= g_HWSST_Flags[flag].second; -} - -void CShaderMan::RemoveStaticFlag(EHWSSTFlag flag) -{ - if (!m_staticExt) - { - InitStaticFlags(); - } - - AZ_Assert(static_cast(flag) >= 0 && static_cast(flag) < AZ_ARRAY_SIZE(g_HWSST_Flags), "Invalid static flag %d", static_cast(flag)); - m_staticFlags &= ~g_HWSST_Flags[flag].second; -} - -bool CShaderMan::HasStaticFlag(EHWSSTFlag flag) -{ - if (!m_staticExt) - { - InitStaticFlags(); - } - - AZ_Assert(static_cast(flag) >= 0 && static_cast(flag) < AZ_ARRAY_SIZE(g_HWSST_Flags), "Invalid static flag %d", static_cast(flag)); - return (m_staticFlags & g_HWSST_Flags[flag].second) != 0; -} - -void CShaderMan::mfInit (void) -{ - LOADING_TIME_PROFILE_SECTION; - s_cNameHEAD = CCryNameTSCRC("HEAD"); - - CTexture::Init(); - - if (!m_bInitialized) - { - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); - - m_ShadersPath = "Shaders/HWScripts/"; - m_ShadersMergeCachePath = "Shaders/MergeCache/"; -#if defined(LINUX32) - m_ShadersCache = CONCAT_PATHS(g_shaderCache, "LINUX32/"); -#elif defined(LINUX64) - m_ShadersCache = CONCAT_PATHS(g_shaderCache, "LINUX64/"); -#elif defined(MAC) - m_ShadersCache = CONCAT_PATHS(g_shaderCache, "Mac/"); -#elif defined(IOS) - m_ShadersCache = CONCAT_PATHS(g_shaderCache, "iOS/"); -#else - m_ShadersCache = CONCAT_PATHS(g_shaderCache, "D3D11"); -#endif - m_szCachePath = "@usercache@/"; - - if (CRenderer::CV_r_shadersImport == 3) - { -#if defined(PERFORMANCE_BUILD) || defined(_RELEASE) - // Disable all runtime shader compilation and force use of the shader importing system in Performance and Release builds only - // We want to still build shaders in Profile builds so we do not miss generating new permutations - CRenderer::CV_r_shadersAllowCompilation = 0; -#else - // Disable shader importing and allow r_shadersAllowCompilation and r_shadersremotecompiler to be used to compile shaders at runtime - CRenderer::CV_r_shadersImport = 0; -#endif - } - -#ifndef CONSOLE_CONST_CVAR_MODE - if (CRenderer::CV_r_shadersediting) - { - CRenderer::CV_r_shadersAllowCompilation = 1; // allow compilation - CRenderer::CV_r_shaderslogcachemisses = 0; // don't bother about cache misses - CRenderer::CV_r_shaderspreactivate = 0; // don't load the level caches - CParserBin::m_bEditable = true; - CRenderer::CV_r_shadersImport = 0; // don't allow shader importing - - ICVar* pPakPriortyCVar = gEnv->pConsole->GetCVar("sys_PakPriority"); - if (pPakPriortyCVar) - { - pPakPriortyCVar->Set(0); // shaders are loaded from disc, always - } - ICVar* pInvalidFileAccessCVar = gEnv->pConsole->GetCVar("sys_PakLogInvalidFileAccess"); - if (pInvalidFileAccessCVar) - { - pInvalidFileAccessCVar->Set(0); // don't bother logging invalid access when editing shaders - } - } -#endif - if (CRenderer::CV_r_shadersAllowCompilation) - { - CRenderer::CV_r_shadersasyncactivation = 0; - - // don't allow shader importing when shader compilation is enabled. - AZ_Warning("Rendering", CRenderer::CV_r_shadersImport == 0, "Warning: Shader compilation is enabled, but shader importing was requested. Disabling r_shadersImport."); - CRenderer::CV_r_shadersImport = 0; - } - - // make sure correct paks are open - shaders.pak will be unloaded from memory after init - gEnv->pCryPak->OpenPack("@assets@", "Shaders.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY); -#if defined(AZ_PLATFORM_ANDROID) - // When the ShaderCache.pak is inside the APK the initialization process takes for ever (around 4 minutes to initialize the engine). - // Loading it into memory during the initialization seems to bypass the issue. - // All paks are unloaded from memory after the game init (during the ESYSTEM_EVENT_GAME_POST_INIT_DONE event). - // LY-40729 is tracking the problem. Once that's fixed this need to be removed. - gEnv->pCryPak->OpenPack("@assets@", "shaderCache.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY); -#endif - ParseShaderProfiles(); - - fxParserInit(); - CParserBin::Init(); - CResFile::Tick(); - - //CShader::m_Shaders_known.Alloc(MAX_SHADERS); - //memset(&CShader::m_Shaders_known[0], 0, sizeof(CShader *)*MAX_SHADERS); - - mfInitGlobal(); - InitStaticFlags(); - mfInitLevelPolicies(); - - //mfInitLookups(); - - // Generate/or load globals.txt - if not existing or shader cache version bumped - mfInitCommonGlobalFlags(); - - mfPreloadShaderExts(); - - if (CRenderer::CV_r_shadersAllowCompilation && !gRenDev->IsShaderCacheGenMode()) - { - mfInitShadersList(&m_ShaderNames); - } - - mfInitShadersCacheMissLog(); - -#if !defined(NULL_RENDERER) - if (!gRenDev->IsEditorMode() && !gRenDev->IsShaderCacheGenMode()) - { - const char* shaderPakDir = "@assets@"; - const char* shaderPakPath = "shaderCache.pak"; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SHADERCORE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(ShaderCore_cpp) -#endif - - if (CRenderer::CV_r_shaderspreactivate == 3) - { - gEnv->pCryPak->LoadPakToMemory(shaderPakPath, AZ::IO::IArchive::eInMemoryPakLocale_CPU); - - mfPreactivateShaders2("", "shaders/cache/", true, shaderPakDir); - - gEnv->pCryPak->LoadPakToMemory(shaderPakPath, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - } - else if (CRenderer::CV_r_shaderspreactivate) - { - mfPreactivateShaders2("", "shadercache/", true, shaderPakDir); - } - } - -#endif - - if (CRenderer::CV_r_shadersAllowCompilation) - { - mfInitShadersCache(false, NULL, NULL, 0); - if (CRenderer::CV_r_shaderspreactivate == 2) - { - mfInitShadersCache(false, NULL, NULL, 1); - } - } - -#if !defined(CONSOLE) && !defined(NULL_RENDERER) - if (!CRenderer::CV_r_shadersAllowCompilation) - { - AZStd::string cgpShaders = m_ShadersCache + "cgpshaders"; - AZStd::string cgvShaders = m_ShadersCache + "cgvshaders"; - - // make sure we can write to the shader cache - if (!CheckAllFilesAreWritable(cgpShaders.c_str()) || - !CheckAllFilesAreWritable(cgvShaders.c_str())) - { - // message box causes problems in fullscreen - // MessageBox(0,"WARNING: Shader cache cannot be updated\n\n" - // "files are write protected / media is read only / windows user setting don't allow file changes","CryEngine",MB_ICONEXCLAMATION|MB_OK); - gEnv->pLog->LogError("ERROR: Shader cache cannot be updated (files are write protected / media is read only / windows user setting don't allow file changes)"); - } - } -#endif // WIN - - mfSetDefaults(); - - //mfPrecacheShaders(NULL); - - // flash all the current commands (parse default shaders) - gRenDev->m_pRT->FlushAndWait(); - - m_bInitialized = true; - } - //mfPrecacheShaders(); -} - -bool CShaderMan::LoadShaderStartupCache() -{ - const char* shaderPakDir = "@assets@/ShaderCacheStartup.pak"; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SHADERCORE_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(ShaderCore_cpp) -#endif - - return gEnv->pCryPak->OpenPack("@assets@", shaderPakDir, AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY | AZ::IO::IArchive::FLAGS_PATH_REAL); -} - -void CShaderMan::UnloadShaderStartupCache() -{ - // Called from the MT so need to flush RT - IF (gRenDev->m_pRT, 1) - { - gRenDev->m_pRT->FlushAndWait(); - } - -#if defined(SHADERS_SERIALIZING) - // Free all import data allowing us to close the startup pack - ClearSResourceCache(); -#endif - - gEnv->pCryPak->ClosePack("ShaderCacheStartup.pak"); -} - -void CShaderMan::mfPostInit() -{ - LOADING_TIME_PROFILE_SECTION; -#if !defined(NULL_RENDERER) - CTexture::PostInit(); - - if (!gRenDev->IsEditorMode() && !gRenDev->IsShaderCacheGenMode()) - { - mfPreloadBinaryShaders(); - } -#endif - - // (enabled also for NULL Renderer, so at least the default shader is initialized) - if (!gRenDev->IsShaderCacheGenMode()) - { - mfLoadDefaultSystemShaders(); - } -} - -void CShaderMan::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - break; - } - } -} - -void CShaderMan::ParseShaderProfile(char* scr, SShaderProfile* pr) -{ - char* name; - long cmd; - char* params; - char* data; - - enum - { - eUseNormalAlpha = 1 - }; - static STokenDesc commands[] = - { - {eUseNormalAlpha, "UseNormalAlpha"}, - - {0, 0} - }; - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eUseNormalAlpha: - pr->m_nShaderProfileFlags |= SPF_LOADNORMALALPHA; - break; - } - } -} - -void CShaderMan::ParseShaderProfiles() -{ - int i; - - for (i = 0; i < eSQ_Max; i++) - { - m_ShaderFixedProfiles[i].m_iShaderProfileQuality = i; - m_ShaderFixedProfiles[i].m_nShaderProfileFlags = 0; - } - - char* name; - long cmd; - char* params; - char* data; - - enum - { - eProfile = 1, eVersion - }; - static STokenDesc commands[] = - { - {eProfile, "Profile"}, - {eVersion, "Version"}, - - {0, 0} - }; - - char* scr = NULL; - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen("Shaders/ShaderProfiles.txt", "rb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileSize); - scr = new char [fileSize + 1]; - if (scr) - { - scr[fileSize] = 0; - gEnv->pCryPak->FRead(scr, fileSize, fileHandle); - gEnv->pCryPak->FClose(fileHandle); - } - } - char* pScr = scr; - if (scr) - { - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eProfile: - { - SShaderProfile* pr = NULL; - assert(name); - PREFAST_ASSUME(name); - if (!azstricmp(name, "Low")) - { - pr = &m_ShaderFixedProfiles[eSQ_Low]; - } - else - { - pr = &m_ShaderFixedProfiles[eSQ_High]; - } - if (pr) - { - ParseShaderProfile(params, pr); - } - break; - } - case eVersion: - break; - } - } - } - SAFE_DELETE_ARRAY(pScr); -} - -const SShaderProfile& CRenderer::GetShaderProfile(EShaderType eST) const -{ - assert((int)eST < sizeof(m_cEF.m_ShaderProfiles) / sizeof(SShaderProfile)); - - return m_cEF.m_ShaderProfiles[eST]; -} - -void CShaderMan::RT_SetShaderQuality(EShaderType eST, EShaderQuality eSQ) -{ - eSQ = CLAMP(eSQ, eSQ_Low, eSQ_VeryHigh); - if (eST == eST_All) - { - for (int i = 0; i < eST_Max; i++) - { - m_ShaderProfiles[i] = m_ShaderFixedProfiles[eSQ]; - m_ShaderProfiles[i].m_iShaderProfileQuality = eSQ; // good? - } - } - else - { - m_ShaderProfiles[eST] = m_ShaderFixedProfiles[eSQ]; - m_ShaderProfiles[eST].m_iShaderProfileQuality = eSQ; // good? - } - if (eST == eST_All || eST == eST_General) - { - m_Bin.InvalidateCache(); - mfReloadAllShaders(FRO_FORCERELOAD, 0); - } -} - -#if !defined(NULL_RENDERER) -static byte bFirst = 1; - -static bool sLoadShader(const char* szName, CShader*& pStorage) -{ - CShader* ef = NULL; - bool bRes = true; - if (bFirst) - { - CryComment("Load System Shader '%s'...", szName); - } - ef = gRenDev->m_cEF.mfForName(szName, EF_SYSTEM); - if (bFirst) - { - if (!ef || (ef->m_Flags & EF_NOTFOUND)) - { - Warning("Load System Shader Failed %s", szName); - bRes = false; - } - else - { - CryComment("ok"); - } - } - pStorage = ef; - return bRes; -} -#endif - -void CShaderMan::mfReleaseSystemShaders () -{ -#ifndef NULL_RENDERER - SAFE_RELEASE_FORCE(s_DefaultShader); - SAFE_RELEASE_FORCE(s_ShaderDebug); - SAFE_RELEASE_FORCE(s_ShaderLensOptics); - SAFE_RELEASE_FORCE(s_ShaderSoftOcclusionQuery); - SAFE_RELEASE_FORCE(s_ShaderOcclTest); - SAFE_RELEASE_FORCE(s_ShaderStereo); - SAFE_RELEASE_FORCE(s_ShaderDXTCompress); - SAFE_RELEASE_FORCE(s_ShaderCommon); -#if defined(FEATURE_SVO_GI) - SAFE_RELEASE_FORCE(s_ShaderSVOGI); -#endif - SAFE_RELEASE_FORCE(s_ShaderShadowBlur); - SAFE_RELEASE_FORCE(s_shPostEffectsGame); - SAFE_RELEASE_FORCE(s_shPostAA); - SAFE_RELEASE_FORCE(s_shPostEffects); - SAFE_RELEASE_FORCE(s_ShaderFallback); - SAFE_RELEASE_FORCE(s_ShaderFPEmu); - SAFE_RELEASE_FORCE(s_ShaderUI); - SAFE_RELEASE_FORCE(s_ShaderLightStyles); - SAFE_RELEASE_FORCE(s_ShaderShadowMaskGen); - SAFE_RELEASE_FORCE(s_shHDRPostProcess); - SAFE_RELEASE_FORCE(s_shPostDepthOfField); - SAFE_RELEASE_FORCE(s_shPostMotionBlur); - SAFE_RELEASE_FORCE(s_shPostSunShafts); - SAFE_RELEASE_FORCE(s_ShaderDeferredCaustics); - SAFE_RELEASE_FORCE(s_shDeferredShading); - SAFE_RELEASE_FORCE(s_ShaderDeferredRain); - SAFE_RELEASE_FORCE(s_ShaderDeferredSnow); - SAFE_RELEASE_FORCE(s_ShaderStars); - SAFE_RELEASE_FORCE(s_ShaderFur); - SAFE_RELEASE_FORCE(s_ShaderVideo); - m_bLoadedSystem = false; - m_systemShaders.clear(); -#endif -} - -void CShaderMan::OnShaderLoaded([[maybe_unused]] IShader* shader) -{ -#if defined(AZ_ENABLE_TRACING) && defined(_RELEASE) - static bool displayedErrorOnce = false; - - if((shader->GetFlags() & EF_NOTFOUND) && m_systemShaders.find(shader) != m_systemShaders.end()) - { - static constexpr char message[] = "Unable to find system shader '%s'. This will likely cause rendering issues, including a black screen. Please make sure all required shaders are included in your pak files."; - - AZ_Error("ShaderCore", false, message, shader->GetName()); - - if(!displayedErrorOnce) - { - displayedErrorOnce = true; - - AZStd::string displayMessage = AZStd::string::format(message, shader->GetName()); - displayMessage.append(" Check Game.log for the complete list of missing shaders."); - - AZ::NativeUI::NativeUIRequestBus::Broadcast(&AZ::NativeUI::NativeUIRequestBus::Events::DisplayOkDialog, "Missing System Shader", displayMessage.c_str(), false); - } - } -#endif -} - -#if !defined(NULL_RENDERER) -void CShaderMan::mfLoadSystemShader(const char* szName, CShader*& pStorage) -{ - sLoadShader(szName, pStorage); - m_systemShaders.emplace(pStorage); -} -#endif - -void CShaderMan::mfLoadBasicSystemShaders() -{ - LOADING_TIME_PROFILE_SECTION; - if (!s_DefaultShader) - { - s_DefaultShader = mfNewShader(""); - s_DefaultShader->m_NameShader = ""; - s_DefaultShader->m_Flags |= EF_SYSTEM; - } -#ifndef NULL_RENDERER - if (!m_bLoadedSystem && !gRenDev->IsShaderCacheGenMode()) - { - mfLoadSystemShader("Fallback", s_ShaderFallback); - mfLoadSystemShader("FixedPipelineEmu", s_ShaderFPEmu); - mfLoadSystemShader("UI", s_ShaderUI); - - mfRefreshSystemShader("Stereo", CShaderMan::s_ShaderStereo); - mfRefreshSystemShader("Video", CShaderMan::s_ShaderVideo); - } -#endif -} - -void CShaderMan::mfLoadDefaultSystemShaders() -{ - LOADING_TIME_PROFILE_SECTION; - if (!s_DefaultShader) - { - s_DefaultShader = mfNewShader(""); - s_DefaultShader->m_NameShader = ""; - s_DefaultShader->m_Flags |= EF_SYSTEM; - } -#ifndef NULL_RENDERER - if (!m_bLoadedSystem) - { - m_bLoadedSystem = true; - - mfLoadSystemShader("Fallback", s_ShaderFallback); - mfLoadSystemShader("FixedPipelineEmu", s_ShaderFPEmu); - mfLoadSystemShader("UI", s_ShaderUI); - mfLoadSystemShader("Light", s_ShaderLightStyles); - - mfLoadSystemShader("ShadowMaskGen", s_ShaderShadowMaskGen); - mfLoadSystemShader("HDRPostProcess", s_shHDRPostProcess); - - mfLoadSystemShader("PostEffects", s_shPostEffects); - -#if defined(FEATURE_SVO_GI) - mfRefreshSystemShader("Total_Illumination", CShaderMan::s_ShaderSVOGI); -#endif - mfRefreshSystemShader("Common", CShaderMan::s_ShaderCommon); - mfRefreshSystemShader("Debug", CShaderMan::s_ShaderDebug); - mfRefreshSystemShader("DeferredCaustics", CShaderMan::s_ShaderDeferredCaustics); - mfRefreshSystemShader("DeferredRain", CShaderMan::s_ShaderDeferredRain); - mfRefreshSystemShader("DeferredSnow", CShaderMan::s_ShaderDeferredSnow); - mfRefreshSystemShader("DeferredShading", CShaderMan::s_shDeferredShading); - mfRefreshSystemShader("DepthOfField", CShaderMan::s_shPostDepthOfField); - mfRefreshSystemShader("DXTCompress", CShaderMan::s_ShaderDXTCompress); - mfRefreshSystemShader("LensOptics", CShaderMan::s_ShaderLensOptics); - mfRefreshSystemShader("SoftOcclusionQuery", CShaderMan::s_ShaderSoftOcclusionQuery); - mfRefreshSystemShader("MotionBlur", CShaderMan::s_shPostMotionBlur); - mfRefreshSystemShader("OcclusionTest", CShaderMan::s_ShaderOcclTest); - mfRefreshSystemShader("PostEffectsGame", CShaderMan::s_shPostEffectsGame); - mfRefreshSystemShader("PostAA", CShaderMan::s_shPostAA); - mfRefreshSystemShader("ShadowBlur", CShaderMan::s_ShaderShadowBlur); - mfRefreshSystemShader("Sunshafts", CShaderMan::s_shPostSunShafts); - mfRefreshSystemShader("Fur", CShaderMan::s_ShaderFur); - } -#endif -} - -void CShaderMan::mfSetDefaults (void) -{ -#ifndef NULL_RENDERER - mfReleaseSystemShaders(); - mfLoadBasicSystemShaders(); -#else - mfLoadBasicSystemShaders(); - s_DefaultShaderItem.m_pShader = s_DefaultShader; - SInputShaderResources ShR; - s_DefaultShaderItem.m_pShaderResources = new CShaderResources(&ShR); -#endif - - memset(&gRenDev->m_cEF.m_PF, 0, sizeof(PerFrameParameters)); - - if (gRenDev->IsEditorMode()) - { - gRenDev->RefreshSystemShaders(); - } - -#if !defined(NULL_RENDERER) - bFirst = 0; -#endif - - m_bInitialized = true; -} - -bool CShaderMan::mfGatherShadersList(const char* szPath, bool bCheckIncludes, bool bUpdateCRC, std::vector* Names) -{ - char nmf[256]; - char dirn[256]; - - cry_strcpy(dirn, szPath); - cry_strcat(dirn, "*"); - - bool bChanged = false; - - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(dirn); - if (!handle) - { - return bChanged; - } - do - { - if (handle.m_filename.front() == '.') - { - continue; - } - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - char ddd[256]; - azsnprintf(ddd, AZ_ARRAY_SIZE(ddd), "%s%.*s/", szPath, aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - - bChanged = mfGatherShadersList(ddd, bCheckIncludes, bUpdateCRC, Names); - if (bChanged) - { - break; - } - continue; - } - cry_strcpy(nmf, szPath); - cry_strcat(nmf, handle.m_filename.data()); - int len = strlen(nmf) - 1; - while (len >= 0 && nmf[len] != '.') - { - len--; - } - if (len <= 0) - { - continue; - } - if (bCheckIncludes) - { - if (!azstricmp(&nmf[len], ".cfi")) - { - fpStripExtension(handle.m_filename.data(), nmf); - SShaderBin* pBin = m_Bin.GetBinShader(nmf, true, 0, &bChanged); - - // If any include file was not found in the read only cache, we'll need to update the CRCs - if (pBin && pBin->IsReadOnly() == false) - { - bChanged = true; - } - - if (bChanged) - { - break; - } - } - continue; - } - if (azstricmp(&nmf[len], ".cfx")) - { - continue; - } - fpStripExtension(handle.m_filename.data(), nmf); - mfAddFXShaderNames(nmf, Names, bUpdateCRC); - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); - - return bChanged; -} - -void CShaderMan::mfGatherFilesList(const char* szPath, std::vector& Names, int nLevel, bool bUseFilter, bool bMaterial) -{ - char nmf[256]; - char dirn[256]; - - cry_strcpy(dirn, szPath); - cry_strcat(dirn, "*"); - - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(dirn); - if (!handle) - { - return; - } - do - { - if (handle.m_filename.front() == '.') - { - continue; - } - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - if (!bUseFilter || nLevel != 1 || !azstricmp(handle.m_filename.data(), m_ShadersFilter.c_str())) - { - char ddd[256]; - azsnprintf(ddd, AZ_ARRAY_SIZE(ddd), "%s%.*s/", szPath, aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - - mfGatherFilesList(ddd, Names, nLevel + 1, bUseFilter, bMaterial); - } - continue; - } - cry_strcpy(nmf, szPath); - cry_strcat(nmf, handle.m_filename.data()); - int len = strlen(nmf) - 1; - while (len >= 0 && nmf[len] != '.') - { - len--; - } - if (len <= 0) - { - continue; - } - if (!bMaterial && azstricmp(&nmf[len], ".fxcb")) - { - continue; - } - if (bMaterial && azstricmp(&nmf[len], ".mtl")) - { - continue; - } - Names.push_back(CCryNameR(nmf)); - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); -} - -int CShaderMan::mfInitShadersList(std::vector* Names) -{ - // Detect include changes -#ifndef NULL_RENDERER - bool bChanged = -#endif - mfGatherShadersList(m_ShadersPath.c_str(), true, false, Names); - - if (gRenDev->m_bShaderCacheGen) - { - // flush out EXT files, so we reload them again after proper per-platform setup - for (ShaderExtItor it = gRenDev->m_cEF.m_ShaderExts.begin(); it != gRenDev->m_cEF.m_ShaderExts.end(); ++it) - { - delete it->second; - } - gRenDev->m_cEF.m_ShaderExts.clear(); - gRenDev->m_cEF.m_SGC.clear(); - - m_ShaderCacheCombinations[0].clear(); - m_ShaderCacheCombinations[1].clear(); - m_ShaderCacheExportCombinations.clear(); - mfCloseShadersCache(0); - mfInitShadersCache(false, NULL, NULL, 0); - } - -#ifndef NULL_RENDERER - mfGatherShadersList(m_ShadersPath.c_str(), false, bChanged, Names); - return m_ShaderNames.size(); -#else - return 0; -#endif -} - -void CShaderMan::mfPreloadShaderExts(void) -{ - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst ("Shaders/*.ext"); - if (!handle) - { - return; - } - do - { - if (handle.m_filename.front() == '.') - { - continue; - } - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - continue; - } - - if (!azstricmp(handle.m_filename.data(), "runtime.ext") || !azstricmp(handle.m_filename.data(), "statics.ext")) - { - continue; - } - char s[256]; - fpStripExtension(handle.m_filename.data(), s); -#ifndef NDEBUG - SShaderGen* pShGen = -#endif - mfCreateShaderGenInfo(s, false); - assert(pShGen); - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); -} - - -//=================================================================== - -CShader* CShaderMan::mfNewShader(const char* szName) -{ - CShader* pSH; - - CCryNameTSCRC className = CShader::mfGetClassName(); - CCryNameTSCRC Name = szName; - CBaseResource* pBR = CBaseResource::GetResource(className, Name, false); - if (!pBR) - { - pSH = new CShader; - pSH->Register(className, Name); - } - else - { - pSH = (CShader*)pBR; - pSH->AddRef(); - } - if (!s_pContainer) - { - s_pContainer = CBaseResource::GetResourcesForClass(className); - } - - if (pSH->GetID() >= MAX_REND_SHADERS) - { - SAFE_RELEASE(pSH); - iLog->Log("ERROR: MAX_REND_SHADERS hit\n"); - return NULL; - } - - return pSH; -} - -//========================================================= - -bool CShaderMan::mfUpdateMergeStatus(SShaderTechnique* hs, std::vector* p) -{ - if (!p) - { - return false; - } - for (uint32 n = 0; n < p->size(); n++) - { - if ((*p)[n].m_Flags & PF_DONTALLOW_DYNMERGE) - { - hs->m_Flags |= FHF_NOMERGE; - break; - } - } - if (hs->m_Flags & FHF_NOMERGE) - { - return true; - } - return false; -} - - -//================================================================================================= - -SEnvTexture* SHRenderTarget::GetEnv2D() -{ - CRenderer* rd = gRenDev; - SEnvTexture* pEnvTex = NULL; - if (m_nIDInPool >= 0) - { - assert(m_nIDInPool < (int)CTexture::s_CustomRT_2D->Num()); - if (m_nIDInPool < (int)CTexture::s_CustomRT_2D->Num()) - { - pEnvTex = &(*CTexture::s_CustomRT_2D)[m_nIDInPool]; - } - } - else - { - const CCamera& cam = rd->GetCamera(); - Matrix33 orientation = Matrix33(cam.GetMatrix()); - Ang3 Angs = CCamera::CreateAnglesYPR(orientation); - Vec3 Pos = cam.GetPosition(); - bool bReflect = false; - if (m_nFlags & (FRT_CAMERA_REFLECTED_PLANE | FRT_CAMERA_REFLECTED_WATERPLANE)) - { - bReflect = true; - } - pEnvTex = CTexture::FindSuitableEnvTex(Pos, Angs, true, 0, false, rd->m_RP.m_pShader, rd->m_RP.m_pShaderResources, rd->m_RP.m_pCurObject, bReflect, rd->m_RP.m_pRE, NULL); - } - return pEnvTex; -} - -void SHRenderTarget::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->Add(*this); - pSizer->AddObject(m_TargetName); - pSizer->AddObject(m_pTarget[0]); - pSizer->AddObject(m_pTarget[1]); -} - -void CShaderResources::CreateModifiers(SInputShaderResources* pInRes) -{ - for (auto iter = m_TexturesResourcesMap.begin(); iter != m_TexturesResourcesMap.end(); ++iter) - { - uint slotIdx = iter->first; - SEfResTexture* pDst = &(iter->second); - - pDst->m_Ext.m_nUpdateFlags = 0; - - SEfResTexture* pInTex = pInRes->GetTextureResource(slotIdx); - if (!pInTex || !pInTex->m_Ext.m_pTexModifier) - { - continue; - } - - pInTex->m_Ext.m_nUpdateFlags = 0; - pInTex->m_Ext.m_nLastRecursionLevel = -1; - SEfTexModificator* pMod = pInTex->m_Ext.m_pTexModifier; - - - if (pMod->m_eTGType >= ETG_Max) - { - pMod->m_eTGType = ETG_Stream; - } - if (pMod->m_eRotType >= ETMR_Max) - { - pMod->m_eRotType = ETMR_NoChange; - } - - if (pMod->m_eMoveType[0] >= ETMM_Max) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] >= ETMM_Max) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eMoveType[0] == ETMM_Pan && (pMod->m_OscAmplitude[0] == 0 || pMod->m_OscRate[0] == 0)) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] == ETMM_Pan && (pMod->m_OscAmplitude[1] == 0 || pMod->m_OscRate[1] == 0)) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eMoveType[0] == ETMM_Fixed && pMod->m_OscRate[0] == 0) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] == ETMM_Fixed && pMod->m_OscRate[1] == 0) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eMoveType[0] == ETMM_Constant && (pMod->m_OscAmplitude[0] == 0 || pMod->m_OscRate[0] == 0)) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] == ETMM_Constant && (pMod->m_OscAmplitude[1] == 0 || pMod->m_OscRate[1] == 0)) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eMoveType[0] == ETMM_Stretch && (pMod->m_OscAmplitude[0] == 0 || pMod->m_OscRate[0] == 0)) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] == ETMM_Stretch && (pMod->m_OscAmplitude[1] == 0 || pMod->m_OscRate[1] == 0)) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eMoveType[0] == ETMM_StretchRepeat && (pMod->m_OscAmplitude[0] == 0 || pMod->m_OscRate[0] == 0)) - { - pMod->m_eMoveType[0] = ETMM_NoChange; - } - if (pMod->m_eMoveType[1] == ETMM_StretchRepeat && (pMod->m_OscAmplitude[1] == 0 || pMod->m_OscRate[1] == 0)) - { - pMod->m_eMoveType[1] = ETMM_NoChange; - } - - if (pMod->m_eTGType != ETG_Stream) - { - m_ResFlags |= MTL_FLAG_NOTINSTANCED; - } - - pInTex->UpdateForCreate(slotIdx); - if (pInTex->m_Ext.m_nUpdateFlags & HWMD_TEXCOORD_FLAG_MASK) - { - SEfTexModificator* pDstMod = new SEfTexModificator; - *pDstMod = *pMod; - SAFE_DELETE(pDst->m_Ext.m_pTexModifier); - pDst->m_Ext.m_pTexModifier = pDstMod; - } - else - { - if (pDst->m_Sampler.m_eTexType == eTT_Auto2D) - { - if (!pDst->m_Ext.m_pTexModifier) - { - m_ResFlags |= MTL_FLAG_NOTINSTANCED; - SEfTexModificator* pDstMod = new SEfTexModificator; - *pDstMod = *pMod; - pDst->m_Ext.m_pTexModifier = pDstMod; - } - } - - if (pMod->m_bTexGenProjected) - { - pDst->m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_PROJ; - } - } - } -} - -int32 GetTextCoordGenObjLinearFlag(int textSlot) -{ - switch (static_cast(textSlot)) - { - case EFTT_DIFFUSE: - return HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE; - case EFTT_DETAIL_OVERLAY: - return HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL; - case EFTT_DECAL_OVERLAY: - return HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT; - case EFTT_EMITTANCE: - return HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE; - case EFTT_CUSTOM: - return HWMD_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM; - default: - return 0; - } -} - -void SEfResTexture::UpdateForCreate(int textSlot) -{ - FUNCTION_PROFILER_RENDER_FLAT - - SEfTexModificator* pMod = m_Ext.m_pTexModifier; - if (!pMod) - { - return; - } - - m_Ext.m_nUpdateFlags = 0; - - ETEX_Type eTT = (ETEX_Type)m_Sampler.m_eTexType; - if (eTT == eTT_Auto2D && m_Sampler.m_pTarget) - { - SEnvTexture* pEnv = m_Sampler.m_pTarget->GetEnv2D(); - assert(pEnv); - if (pEnv && pEnv->m_pTex) - { - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_PROJ | GetTextCoordGenObjLinearFlag(textSlot); - } - } - - bool bTr = false; - - if (pMod->m_Tiling[0] == 0) - { - pMod->m_Tiling[0] = 1.0f; - } - if (pMod->m_Tiling[1] == 0) - { - pMod->m_Tiling[1] = 1.0f; - } - - bTr = pMod->isModified(); - - if (pMod->m_eTGType != ETG_Stream) - { - switch (pMod->m_eTGType) - { - case ETG_World: - case ETG_Camera: - m_Ext.m_nUpdateFlags |= GetTextCoordGenObjLinearFlag(textSlot); - break; - } - } - - if (bTr) - { - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_MATRIX; - } - - - if (pMod->m_bTexGenProjected) - { - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_PROJ; - } -} - -// Update TexGen and TexTransform matrices for current material texture -void SEfResTexture::Update(int nTSlot) -{ - FUNCTION_PROFILER_RENDER_FLAT - PrefetchLine(m_Sampler.m_pTex, 0); - CRenderer* rd = gRenDev; - - assert(nTSlot < MAX_TMU); - rd->m_RP.m_ShaderTexResources[nTSlot] = this; - - const SEfTexModificator* const pMod = m_Ext.m_pTexModifier; - - if(!pMod) - { - if (IsTextureModifierSupportedForTextureMap(static_cast(nTSlot))) - { - rd->m_RP.m_FlagsShader_MD |= m_Ext.m_nUpdateFlags; - } - } - else - { - UpdateWithModifier(nTSlot); - } -} - -void SEfResTexture::UpdateWithModifier(int nTSlot) -{ - CRenderer* rd = gRenDev; - int nFrameID = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameID; - - // Skip update if the modifier was updated (same frame id, except frame id with default value -1, and same recursion level) - if (m_Ext.m_nFrameUpdated != -1 && m_Ext.m_nFrameUpdated == nFrameID && m_Ext.m_nLastRecursionLevel == SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID]) - { - if (IsTextureModifierSupportedForTextureMap(static_cast(nTSlot))) - { - rd->m_RP.m_FlagsShader_MD |= m_Ext.m_nUpdateFlags; - } - - return; - } - - m_Ext.m_nFrameUpdated = nFrameID; - m_Ext.m_nLastRecursionLevel = SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID]; - m_Ext.m_nUpdateFlags = 0; - - ETEX_Type eTT = (ETEX_Type)m_Sampler.m_eTexType; - SEfTexModificator* pMod = m_Ext.m_pTexModifier; - if (eTT == eTT_Auto2D && m_Sampler.m_pTarget) - { - SEnvTexture* pEnv = m_Sampler.m_pTarget->GetEnv2D(); - assert(pEnv); - if (pEnv && pEnv->m_pTex) - { - pMod->m_TexGenMatrix = Matrix44A(rd->m_RP.m_pCurObject->m_II.m_Matrix).GetTransposed() * pEnv->m_Matrix; - pMod->m_TexGenMatrix = pMod->m_TexGenMatrix.GetTransposed(); - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_PROJ | GetTextCoordGenObjLinearFlag(nTSlot); - } - } - - bool bTr = false; - Plane Pl; - Plane PlTr; - - const float fTiling0 = pMod->m_Tiling[0]; - const float fTiling1 = pMod->m_Tiling[1]; - pMod->m_Tiling[0] = (float)fsel(-fabsf(fTiling0), 1.0f, fTiling0); - pMod->m_Tiling[1] = (float)fsel(-fabsf(fTiling1), 1.0f, fTiling1); - - if (pMod->isModified()) - { - pMod->m_TexMatrix.SetIdentity(); - float fTime = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - - bTr = true; - - switch (pMod->m_eRotType) - { - case ETMR_Fixed: - { - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - -pMod->m_RotOscCenter[0], -pMod->m_RotOscCenter[1], -pMod->m_RotOscCenter[2], 1); - - if (pMod->m_RotOscAmplitude[0]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationX(Word2Degr(pMod->m_RotOscAmplitude[0]) * PI / 180.0f); - } - if (pMod->m_RotOscAmplitude[1]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationY(Word2Degr(pMod->m_RotOscAmplitude[1]) * PI / 180.0f); - } - if (pMod->m_RotOscAmplitude[2]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationZ(Word2Degr(pMod->m_RotOscAmplitude[2]) * PI / 180.0f); - } - - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - pMod->m_RotOscCenter[0], pMod->m_RotOscCenter[1], pMod->m_RotOscCenter[2], 1); - } - break; - - case ETMR_Constant: - { - fTime *= 1000.0f; - float fxAmp = Word2Degr(pMod->m_RotOscAmplitude[0]) * fTime * PI / 180.0f + Word2Degr(pMod->m_RotOscPhase[0]); - float fyAmp = Word2Degr(pMod->m_RotOscAmplitude[1]) * fTime * PI / 180.0f + Word2Degr(pMod->m_RotOscPhase[1]); - float fzAmp = Word2Degr(pMod->m_RotOscAmplitude[2]) * fTime * PI / 180.0f + Word2Degr(pMod->m_RotOscPhase[2]); - - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - -pMod->m_RotOscCenter[0], -pMod->m_RotOscCenter[1], -pMod->m_RotOscCenter[2], 1); - - //rotation matrix - if (fxAmp) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix44A(Matrix33::CreateRotationX(fxAmp)).GetTransposed(); - } - if (fyAmp) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix44A(Matrix33::CreateRotationY(fyAmp)).GetTransposed(); - } - if (fzAmp) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix44A(Matrix33::CreateRotationZ(fzAmp)).GetTransposed(); - } - - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - pMod->m_RotOscCenter[0], pMod->m_RotOscCenter[1], pMod->m_RotOscCenter[2], 1); - } - break; - - case ETMR_Oscillated: - { - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - -pMod->m_RotOscCenter[0], -pMod->m_RotOscCenter[1], -pMod->m_RotOscCenter[2], 1); - - float S_X = fTime * Word2Degr(pMod->m_RotOscRate[0]); - float S_Y = fTime * Word2Degr(pMod->m_RotOscRate[1]); - float S_Z = fTime * Word2Degr(pMod->m_RotOscRate[2]); - - float d_X = Word2Degr(pMod->m_RotOscAmplitude[0]) * sin_tpl(2.0f * PI * ((S_X - floor_tpl(S_X)) + Word2Degr(pMod->m_RotOscPhase[0]))); - float d_Y = Word2Degr(pMod->m_RotOscAmplitude[1]) * sin_tpl(2.0f * PI * ((S_Y - floor_tpl(S_Y)) + Word2Degr(pMod->m_RotOscPhase[1]))); - float d_Z = Word2Degr(pMod->m_RotOscAmplitude[2]) * sin_tpl(2.0f * PI * ((S_Z - floor_tpl(S_Z)) + Word2Degr(pMod->m_RotOscPhase[2]))); - - if (d_X) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationX(d_X); - } - if (d_Y) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationY(d_Y); - } - if (d_Z) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationZ(d_Z); - } - - //translation matrix for rotation center - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - pMod->m_RotOscCenter[0], pMod->m_RotOscCenter[1], pMod->m_RotOscCenter[2], 1); - } - break; - } - - - float Su = rd->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime * pMod->m_OscRate[0]; - float Sv = rd->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime * pMod->m_OscRate[1]; - switch (pMod->m_eMoveType[0]) - { - case ETMM_Pan: - { - float du = pMod->m_OscAmplitude[0] * sin_tpl(2.0f * PI * (Su - floor_tpl(Su)) + 2.f * PI * pMod->m_OscPhase[0]); - pMod->m_TexMatrix(3, 0) = du; - } - break; - case ETMM_Fixed: - { - float du = pMod->m_OscRate[0]; - pMod->m_TexMatrix(3, 0) = du; - } - break; - case ETMM_Constant: - { - float du = pMod->m_OscAmplitude[0] * Su; //(Su - floor_tpl(Su)); - pMod->m_TexMatrix(3, 0) = du; - } - break; - case ETMM_Jitter: - { - if (pMod->m_LastTime[0] < 1.0f || pMod->m_LastTime[0] > Su + 1.0f) - { - pMod->m_LastTime[0] = pMod->m_OscPhase[0] + floor_tpl(Su); - } - if (Su - pMod->m_LastTime[0] > 1.0f) - { - pMod->m_CurrentJitter[0] = cry_random(0.0f, pMod->m_OscAmplitude[0]); - pMod->m_LastTime[0] = pMod->m_OscPhase[0] + floor_tpl(Su); - } - pMod->m_TexMatrix(3, 0) = pMod->m_CurrentJitter[0]; - } - break; - case ETMM_Stretch: - { - float du = pMod->m_OscAmplitude[0] * sin_tpl(2.0f * PI * (Su - floor_tpl(Su)) + 2.0f * PI * pMod->m_OscPhase[0]); - pMod->m_TexMatrix(0, 0) = 1.0f + du; - } - break; - case ETMM_StretchRepeat: - { - float du = pMod->m_OscAmplitude[0] * sin_tpl(0.5f * PI * (Su - floor_tpl(Su)) + 2.0f * PI * pMod->m_OscPhase[0]); - pMod->m_TexMatrix(0, 0) = 1.0f + du; - } - break; - } - - switch (pMod->m_eMoveType[1]) - { - case ETMM_Pan: - { - float dv = pMod->m_OscAmplitude[1] * sin_tpl(2.0f * PI * (Sv - floor_tpl(Sv)) + 2.0f * PI * pMod->m_OscPhase[1]); - pMod->m_TexMatrix(3, 1) = dv; - } - break; - case ETMM_Fixed: - { - float dv = pMod->m_OscRate[1]; - pMod->m_TexMatrix(3, 1) = dv; - } - break; - case ETMM_Constant: - { - float dv = pMod->m_OscAmplitude[1] * Sv; //(Sv - floor_tpl(Sv)); - pMod->m_TexMatrix(3, 1) = dv; - } - break; - case ETMM_Jitter: - { - if (pMod->m_LastTime[1] < 1.0f || pMod->m_LastTime[1] > Sv + 1.0f) - { - pMod->m_LastTime[1] = pMod->m_OscPhase[1] + floor_tpl(Sv); - } - if (Sv - pMod->m_LastTime[1] > 1.0f) - { - pMod->m_CurrentJitter[1] = cry_random(0.0f, pMod->m_OscAmplitude[1]); - pMod->m_LastTime[1] = pMod->m_OscPhase[1] + floor_tpl(Sv); - } - pMod->m_TexMatrix(3, 1) = pMod->m_CurrentJitter[1]; - } - break; - case ETMM_Stretch: - { - float dv = pMod->m_OscAmplitude[1] * sin_tpl(2.0f * PI * (Sv - floor_tpl(Sv)) + 2.0f * PI * pMod->m_OscPhase[1]); - pMod->m_TexMatrix(1, 1) = 1.0f + dv; - } - break; - case ETMM_StretchRepeat: - { - float dv = pMod->m_OscAmplitude[1] * sin_tpl(0.5f * PI * (Sv - floor_tpl(Sv)) + 2.0f * PI * pMod->m_OscPhase[1]); - pMod->m_TexMatrix(1, 1) = 1.0f + dv; - } - break; - } - - if (pMod->m_Offs[0] != 0.0f || - pMod->m_Offs[1] != 0.0f || - pMod->m_Tiling[0] != 1.0f || - pMod->m_Tiling[1] != 1.0f || - pMod->m_Rot[0] != 0.0f || - pMod->m_Rot[1] != 0.0f || - pMod->m_Rot[2] != 0.0f) - { - float du = pMod->m_Offs[0]; - float dv = pMod->m_Offs[1]; - float su = pMod->m_Tiling[0]; - float sv = pMod->m_Tiling[1]; - - if (pMod->m_Rot[0]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationX(Word2Degr(pMod->m_Rot[0]) * PI / 180.0f); - } - if (pMod->m_Rot[1]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationY(Word2Degr(pMod->m_Rot[1]) * PI / 180.0f); - } - if (pMod->m_Rot[2]) - { - pMod->m_TexMatrix = pMod->m_TexMatrix * Matrix33::CreateRotationZ(Word2Degr(pMod->m_Rot[2]) * PI / 180.0f); - } - - pMod->m_TexMatrix = pMod->m_TexMatrix * - Matrix44(su, 0, 0, 0, - 0, sv, 0, 0, - 0, 0, 1, 0, - du, dv, 0, 1); - } - } - else - { // This can be avoided - why would you have an empty modulator? - pMod->m_TexMatrix.SetIdentity(); - } - - if (pMod->m_eTGType != ETG_Stream) - { - switch (pMod->m_eTGType) - { - case ETG_World: - { - m_Ext.m_nUpdateFlags |= GetTextCoordGenObjLinearFlag(nTSlot); - for (int i = 0; i < 4; i++) - { - memset(&Pl, 0, sizeof(Pl)); - float* fPl = (float*)&Pl; - fPl[i] = 1.0f; - if (rd->m_RP.m_pCurObject) - { - PlTr = TransformPlane2_NoTrans(Matrix44A(rd->m_RP.m_pCurObject->m_II.m_Matrix).GetTransposed(), Pl); - } - else - { - // LY-60094 - TexGenType of "World" will give incorrect results - AZ_Warning("Rendering", false, "Warning: Material has TexGenType of 'World', but the requested object is unavailable while generating the TexGen Matrix. Results may be incorrect."); - PlTr = TransformPlane2_NoTrans(Matrix44A(rd->m_RP.m_pIdendityRenderObject->m_II.m_Matrix).GetTransposed(), Pl); - } - pMod->m_TexGenMatrix(i, 0) = PlTr.n.x; - pMod->m_TexGenMatrix(i, 1) = PlTr.n.y; - pMod->m_TexGenMatrix(i, 2) = PlTr.n.z; - pMod->m_TexGenMatrix(i, 3) = PlTr.d; - } - } - break; - case ETG_Camera: - { - m_Ext.m_nUpdateFlags |= GetTextCoordGenObjLinearFlag(nTSlot); - for (int i = 0; i < 4; i++) - { - memset(&Pl, 0, sizeof(Pl)); - float* fPl = (float*)&Pl; - fPl[i] = 1.0f; - PlTr = TransformPlane2_NoTrans(rd->m_ViewMatrix, Pl); - pMod->m_TexGenMatrix(i, 0) = PlTr.n.x; - pMod->m_TexGenMatrix(i, 1) = PlTr.n.y; - pMod->m_TexGenMatrix(i, 2) = PlTr.n.z; - pMod->m_TexGenMatrix(i, 3) = PlTr.d; - } - } - break; - } - } - - if (bTr) - { - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_MATRIX; - pMod->m_TexMatrix(0, 3) = pMod->m_TexMatrix(0, 2); - pMod->m_TexMatrix(1, 3) = pMod->m_TexMatrix(1, 2); - pMod->m_TexMatrix(2, 3) = pMod->m_TexMatrix(2, 2); - } - - - if (pMod->m_bTexGenProjected) - { - m_Ext.m_nUpdateFlags |= HWMD_TEXCOORD_PROJ; - } - - if (IsTextureModifierSupportedForTextureMap(static_cast(nTSlot))) - { - rd->m_RP.m_FlagsShader_MD |= m_Ext.m_nUpdateFlags; - } -} - -//--------------------------------------------------------------------------- -// Wave evaluator - -float CShaderMan::EvalWaveForm(SWaveForm* wf) -{ - int val; - - float Amp; - float Freq; - float Phase; - float Level; - - if (wf->m_Flags & WFF_LERP) - { - val = (int)(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime * 597.0f); - val &= SRenderPipeline::sSinTableCount - 1; - float fLerp = gRenDev->m_RP.m_tSinTable[val] * 0.5f + 0.5f; - - if (wf->m_Amp != wf->m_Amp1) - { - Amp = LERP(wf->m_Amp, wf->m_Amp1, fLerp); - } - else - { - Amp = wf->m_Amp; - } - - if (wf->m_Freq != wf->m_Freq1) - { - Freq = LERP(wf->m_Freq, wf->m_Freq1, fLerp); - } - else - { - Freq = wf->m_Freq; - } - - if (wf->m_Phase != wf->m_Phase1) - { - Phase = LERP(wf->m_Phase, wf->m_Phase1, fLerp); - } - else - { - Phase = wf->m_Phase; - } - - if (wf->m_Level != wf->m_Level1) - { - Level = LERP(wf->m_Level, wf->m_Level1, fLerp); - } - else - { - Level = wf->m_Level; - } - } - else - { - Level = wf->m_Level; - Amp = wf->m_Amp; - Phase = wf->m_Phase; - Freq = wf->m_Freq; - } - - switch (wf->m_eWFType) - { - case eWF_None: - Warning("WARNING: CShaderMan::EvalWaveForm called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->GetName()); - break; - - case eWF_Sin: - val = (int)((gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime * Freq + Phase) * (float)SRenderPipeline::sSinTableCount); - return Amp * gRenDev->m_RP.m_tSinTable[val & (SRenderPipeline::sSinTableCount - 1)] + Level; - - // Other wave types aren't supported anymore - case eWF_HalfSin: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHalfSin: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_SawTooth: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvSawTooth: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Square: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Triangle: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Hill: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHill: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - default: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - break; - } - return 1; -} - -float CShaderMan::EvalWaveForm(SWaveForm2* wf) -{ - int val; - - switch (wf->m_eWFType) - { - case eWF_None: - //Warning( 0,0,"WARNING: CShaderMan::EvalWaveForm called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->GetName()); - break; - - case eWF_Sin: - val = (int)((gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime * wf->m_Freq + wf->m_Phase) * (float)SRenderPipeline::sSinTableCount); - return wf->m_Amp * gRenDev->m_RP.m_tSinTable[val & (SRenderPipeline::sSinTableCount - 1)] + wf->m_Level; - - // Other wave types aren't supported anymore - case eWF_HalfSin: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHalfSin: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_SawTooth: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvSawTooth: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Square: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Triangle: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Hill: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHill: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - default: - Warning("WARNING: CShaderMan::EvalWaveForm: bad WaveType '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - break; - } - return 1; -} - -float CShaderMan::EvalWaveForm2(SWaveForm* wf, float frac) -{ - int val; - - if (!(wf->m_Flags & WFF_CLAMP)) - { - switch (wf->m_eWFType) - { - case eWF_None: - Warning("CShaderMan::EvalWaveForm2 called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->GetName()); - break; - - case eWF_Sin: - val = QRound((frac * wf->m_Freq + wf->m_Phase) * (float)SRenderPipeline::sSinTableCount); - val &= (SRenderPipeline::sSinTableCount - 1); - return wf->m_Amp * gRenDev->m_RP.m_tSinTable[val] + wf->m_Level; - - // Other wave types aren't supported anymore - case eWF_SawTooth: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvSawTooth: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Square: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Triangle: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Hill: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHill: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - default: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - break; - } - } - else - { - switch (wf->m_eWFType) - { - case eWF_None: - Warning("Warning: CShaderMan::EvalWaveForm2 called with 'EWF_None' in Shader '%s'\n", gRenDev->m_RP.m_pShader->GetName()); - break; - - case eWF_Sin: - val = QRound((frac * wf->m_Freq + wf->m_Phase) * (float)SRenderPipeline::sSinTableCount); - val &= (SRenderPipeline::sSinTableCount - 1); - return wf->m_Amp * gRenDev->m_RP.m_tSinTable[val] + wf->m_Level; - - // Other wave types aren't supported anymore - case eWF_SawTooth: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvSawTooth: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Square: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Triangle: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_Hill: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - case eWF_InvHill: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - assert(0); - return 0; - - default: - Warning("Warning: CShaderMan::EvalWaveForm2: bad EWF '%d' in Shader '%s'\n", wf->m_eWFType, gRenDev->m_RP.m_pShader->GetName()); - break; - } - } - return 1; -} - - -void CShaderMan::mfBeginFrame() -{ - LOADING_TIME_PROFILE_SECTION; -} - -void CHWShader::mfCleanupCache() -{ - FXShaderCacheItor FXitor; - for (FXitor = m_ShaderCache.begin(); FXitor != m_ShaderCache.end(); FXitor++) - { - SShaderCache* sc = FXitor->second; - if (!sc) - { - continue; - } - sc->Cleanup(); - } - assert (CResFile::m_nNumOpenResources == 0); - CResFile::m_nMaxOpenResFiles = 4; -} - -EHWShaderClass CHWShader::mfStringProfile(const char* profile) -{ - EHWShaderClass Profile = eHWSC_Num; - if (!strncmp(profile, "vs_5_0", 6) || !strncmp(profile, "vs_4_0", 6) || !strncmp(profile, "vs_3_0", 6)) - { - Profile = eHWSC_Vertex; - } - else - if (!strncmp(profile, "ps_5_0", 6) || !strncmp(profile, "ps_4_0", 6) || !strncmp(profile, "ps_3_0", 6)) - { - Profile = eHWSC_Pixel; - } - else - if (!strncmp(profile, "gs_5_0", 6) || !strncmp(profile, "gs_4_0", 6)) - { - Profile = eHWSC_Geometry; - } - else - if (!strncmp(profile, "hs_5_0", 6)) - { - Profile = eHWSC_Hull; - } - else - if (!strncmp(profile, "ds_5_0", 6)) - { - Profile = eHWSC_Domain; - } - else - if (!strncmp(profile, "cs_5_0", 6)) - { - Profile = eHWSC_Compute; - } - else - { - assert(0); - } - - return Profile; -} -EHWShaderClass CHWShader::mfStringClass(const char* szClass) -{ - EHWShaderClass Profile = eHWSC_Num; - if (!_strnicmp(szClass, "VS", 2)) - { - Profile = eHWSC_Vertex; - } - else - if (!_strnicmp(szClass, "PS", 2)) - { - Profile = eHWSC_Pixel; - } - else - if (!_strnicmp(szClass, "GS", 2)) - { - Profile = eHWSC_Geometry; - } - else - if (!_strnicmp(szClass, "HS", 2)) - { - Profile = eHWSC_Hull; - } - else - if (!_strnicmp(szClass, "DS", 2)) - { - Profile = eHWSC_Domain; - } - else - if (!_strnicmp(szClass, "CS", 2)) - { - Profile = eHWSC_Compute; - } - else - { - assert(0); - } - - return Profile; -} -const char* CHWShader::mfProfileString(EHWShaderClass eClass) -{ - const char* szProfile = "Unknown"; - switch (eClass) - { - case eHWSC_Vertex: - szProfile = "vs_5_0"; - break; - case eHWSC_Pixel: - szProfile = "ps_5_0"; - break; - case eHWSC_Geometry: - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4) - { - szProfile = "gs_5_0"; - } - else - { - assert(0); - } - break; - case eHWSC_Domain: - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4) - { - szProfile = "ds_5_0"; - } - else - { - assert(0); - } - break; - case eHWSC_Hull: - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4) - { - szProfile = "hs_5_0"; - } - else - { - assert(0); - } - break; - case eHWSC_Compute: - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_METAL || CParserBin::m_nPlatform == SF_GLES3) - { - szProfile = "cs_5_0"; - } - else - { - assert(0); - } - break; - default: - assert(0); - } - return szProfile; -} -const char* CHWShader::mfClassString(EHWShaderClass eClass) -{ - const char* szClass = "Unknown"; - switch (eClass) - { - case eHWSC_Vertex: - szClass = "VS"; - break; - case eHWSC_Pixel: - szClass = "PS"; - break; - case eHWSC_Geometry: - szClass = "GS"; - break; - case eHWSC_Domain: - szClass = "DS"; - break; - case eHWSC_Hull: - szClass = "HS"; - break; - case eHWSC_Compute: - szClass = "CS"; - break; - default: - assert(0); - } - return szClass; -} - -//========================================================================================================== - -inline bool sCompareRes(CShaderResources* a, CShaderResources* b) -{ - if (!a || !b) - { - return a < b; - } - - if (a->m_AlphaRef != b->m_AlphaRef) - { - return a->m_AlphaRef < b->m_AlphaRef; - } - - if (a->GetStrengthValue(EFTT_OPACITY) != b->GetStrengthValue(EFTT_OPACITY)) - { - return a->GetStrengthValue(EFTT_OPACITY) < b->GetStrengthValue(EFTT_OPACITY); - } - - if (a->m_pDeformInfo != b->m_pDeformInfo) - { - return a->m_pDeformInfo < b->m_pDeformInfo; - } - - if (a->m_RTargets.Num() != b->m_RTargets.Num()) - { - return a->m_RTargets.Num() < b->m_RTargets.Num(); - } - - if ((a->m_ResFlags & MTL_FLAG_2SIDED) != (b->m_ResFlags & MTL_FLAG_2SIDED)) - { - return (a->m_ResFlags & MTL_FLAG_2SIDED) < (b->m_ResFlags & MTL_FLAG_2SIDED); - } - - // [Shader System TO DO] - optimize - should be data driven based on marked slots only - - uint16 testSlots[] = { - EFTT_SPECULAR , - EFTT_DIFFUSE , - EFTT_NORMALS , - EFTT_ENV , - EFTT_DECAL_OVERLAY , - EFTT_DETAIL_OVERLAY , - EFTT_MAX - }; - - ITexture *pTA = nullptr, *pTB = nullptr; - for (int i=0 ; testSlots[i] != EFTT_MAX; i++) - { - uint16 texSlot = testSlots[i]; - SEfResTexture* pTexResA = a->GetTextureResource(texSlot); - SEfResTexture* pTexResB = b->GetTextureResource(texSlot); - pTA = pTexResA ? pTexResA->m_Sampler.m_pITex : nullptr; - pTB = pTexResB ? pTexResB->m_Sampler.m_pITex : nullptr; - - if (pTA != pTB) - { - return pTA < pTB; - } - } - return (pTA < pTB); -} - -inline bool sIdenticalRes(CShaderResources* a, CShaderResources* b) -{ - if (a->m_AlphaRef != b->m_AlphaRef) - { - return false; - } - - if (a->GetStrengthValue(EFTT_OPACITY) != b->GetStrengthValue(EFTT_OPACITY)) - { - return false; - } - - if (a->m_pDeformInfo != b->m_pDeformInfo) - { - return false; - } - - if (a->m_RTargets.Num() != b->m_RTargets.Num()) - { - return false; - } - - if ((a->m_ResFlags & (MTL_FLAG_2SIDED | MTL_FLAG_ADDITIVE)) != (b->m_ResFlags & (MTL_FLAG_2SIDED | MTL_FLAG_ADDITIVE))) - { - return false; - } - - // [Shader System TO DO] - revisit this comparison!!! - for (int texSlot = 0; texSlot < EFTT_MAX; texSlot++) - { - SEfResTexture* pTextureA = a->GetTextureResource(texSlot); - if (pTextureA && pTextureA->IsHasModificators()) - return false; - - SEfResTexture* pTextureB = b->GetTextureResource(texSlot); - if (pTextureB && pTextureB->IsHasModificators()) - return false; - - // [Shader System] - To Do - test and add this for being more correct - // Finally compare the pointer to the texture resource itself -// if (pTextureA->m_Sampler.m_pITex != pTextureB->m_Sampler.m_pITex) -// return false; - } - - const float emissiveIntensity = a->GetStrengthValue(EFTT_EMITTANCE); - if (emissiveIntensity != b->GetStrengthValue(EFTT_EMITTANCE)) - { - return false; - } - if (emissiveIntensity > 0) - { - if (a->GetColorValue(EFTT_EMITTANCE) != b->GetColorValue(EFTT_EMITTANCE)) - { - return false; - } - } - - return true; -} - -inline bool sCompareShd(CBaseResource* a, CBaseResource* b) -{ - if (!a || !b) - { - return a < b; - } - - CShader* pA = (CShader*)a; - CShader* pB = (CShader*)b; - SShaderPass* pPA = NULL; - SShaderPass* pPB = NULL; - if (pA->m_HWTechniques.Num() && pA->m_HWTechniques[0]->m_Passes.Num()) - { - pPA = &pA->m_HWTechniques[0]->m_Passes[0]; - } - if (pB->m_HWTechniques.Num() && pB->m_HWTechniques[0]->m_Passes.Num()) - { - pPB = &pB->m_HWTechniques[0]->m_Passes[0]; - } - if (!pPA || !pPB) - { - return pPA < pPB; - } - - if (pPA->m_VShader != pPB->m_VShader) - { - return pPA->m_VShader < pPB->m_VShader; - } - return (pPA->m_PShader < pPB->m_PShader); -} - -void CShaderMan::mfSortResources() -{ - uint32 i; - for (i = 0; i < MAX_TMU; i++) - { - gRenDev->m_RP.m_ShaderTexResources[i] = NULL; - } - iLog->Log("-- Presort shaders by states..."); - //return; - std::sort(&CShader::s_ShaderResources_known.begin()[1], CShader::s_ShaderResources_known.end(), sCompareRes); - - int nGroups = 20000; - CShaderResources* pPrev = nullptr; - - // Now that the shader resources has been sorted, run over them and create groups of - // identical resources. - for (i = 1; i < CShader::s_ShaderResources_known.Num(); i++) - { - CShaderResources* pRes = CShader::s_ShaderResources_known[i]; - if (pRes) - { - pRes->m_Id = i; - pRes->m_IdGroup = i; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_materialsbatching) - { - if (pPrev) - { - if (!sIdenticalRes(pRes, pPrev)) - { - nGroups++; - } - } - pRes->m_IdGroup = nGroups; - } - pPrev = pRes; - } - } - iLog->Log("--- [Shaders System] : %d Shaders Resources, %d Shaders Resource groups.", CShader::s_ShaderResources_known.Num(), nGroups - 20000); - - // now run over the list of active (compiled binary) shaders - { - AUTO_LOCK(CBaseResource::s_cResLock); - - SResourceContainer* pRL = CShaderMan::s_pContainer; - assert(pRL); - if (pRL) - { - std::sort(pRL->m_RList.begin(), pRL->m_RList.end(), sCompareShd); - for (i = 0; i < pRL->m_RList.size(); i++) - { - CShader* pSH = (CShader*)pRL->m_RList[i]; - if (pSH) - { - pSH->SetID(CBaseResource::IdFromRListIndex(i)); - } - } - - pRL->m_AvailableIDs.clear(); - for (i = 0; i < pRL->m_RList.size(); i++) - { - CShader* pSH = (CShader*)pRL->m_RList[i]; - if (!pSH) - { - pRL->m_AvailableIDs.push_back(CBaseResource::IdFromRListIndex(i)); - } - } - } - } -} - -//--------------------------------------------------------------------------- - -void CLightStyle::mfUpdate(float fTime) -{ - float m = fTime * m_TimeIncr; - // if (m != m_LastTime) - { - m_LastTime = m; - if (m_Map.Num()) - { - if (m_Map.Num() == 1) - { - m_Color = m_Map[0].cColor; - } - else - { - int first = (int)QInt(m); - int second = (first + 1); - float fLerp = m - (float)first; - - // Interpolate between key-frames - // todo: try different interpolation method - - ColorF& cColA = m_Map[first % m_Map.Num()].cColor; - ColorF& cColB = m_Map[second % m_Map.Num()].cColor; - m_Color = LERP(cColA, cColB, fLerp); - - Vec3& vPosA = m_Map[first % m_Map.Num()].vPosOffset; - Vec3& vPosB = m_Map[second % m_Map.Num()].vPosOffset; - m_vPosOffset = LERP(vPosA, vPosB, fLerp); - } - } - } -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderFXParseBin.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderFXParseBin.cpp deleted file mode 100644 index 5ee836ede0..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderFXParseBin.cpp +++ /dev/null @@ -1,6356 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include -#include -#include "UnalignedBlit.h" - -#include "DeviceManager/Enums.h" -#include "PoundPoundParser.h" - -static FOURCC FOURCC_SHADERBIN = MAKEFOURCC('F', 'X', 'B', '0'); - - -SShaderBin SShaderBin::s_Root; -uint32 SShaderBin::s_nCache = 0; -uint32 SShaderBin::s_nMaxFXBinCache = MAX_FXBIN_CACHE; -CShaderManBin::CShaderManBin() -{ - m_pCEF = gRenDev ? &gRenDev->m_cEF : nullptr; -} - -int CShaderManBin::Size() -{ - SShaderBin* pSB; - int nSize = 0; - nSize += sizeOfMapStr(m_BinPaths); - nSize += m_BinValidCRCs.size() * sizeof(bool) * sizeof(stl::MapLikeStruct); - - for (pSB = SShaderBin::s_Root.m_Prev; pSB != &SShaderBin::s_Root; pSB = pSB->m_Prev) - { - nSize += pSB->Size(); - } - return nSize; -} - -void CShaderManBin::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_BinPaths); - pSizer->AddObject(m_BinValidCRCs); - - SShaderBin* pSB; - for (pSB = SShaderBin::s_Root.m_Prev; pSB != &SShaderBin::s_Root; pSB = pSB->m_Prev) - { - pSB->GetMemoryUsage(pSizer); - } -} - -uint32 SShaderBin::ComputeCRC() -{ - if (!m_Tokens.size()) - { - return 0; - } - uint32 CRC32; - if (CParserBin::m_bEndians) - { - DWORD* pT = new DWORD [m_Tokens.size()]; - memcpy(pT, &m_Tokens[0], m_Tokens.size() * sizeof(uint32)); - SwapEndian(pT, (size_t)m_Tokens.size(), eBigEndian); - CRC32 = CCrc32::Compute((char*)pT, m_Tokens.size() * sizeof(uint32)); - delete [] pT; - } - else - { - CRC32 = CCrc32::Compute((char*)&m_Tokens[0], m_Tokens.size() * sizeof(uint32)); - } - int nCur = 0; - Lock(); - while (nCur >= 0) - { - nCur = CParserBin::FindToken(nCur, m_Tokens.size() - 1, &m_Tokens[0], eT_include); - if (nCur >= 0) - { - nCur++; - uint32 nTokName = m_Tokens[nCur]; - const char* szNameInc = CParserBin::GetString(nTokName, m_TokenTable); - SShaderBin* pBinIncl = gRenDev->m_cEF.m_Bin.GetBinShader(szNameInc, true, 0); - AZ_Assert(pBinIncl, "Error loading shader '%s' while trying to compute the shader CRC.", szNameInc); - if (pBinIncl) - { - CRC32 += pBinIncl->ComputeCRC(); - } - } - } - Unlock(); - - return CRC32; -} - -SShaderBin* CShaderManBin::SaveBinShader( - uint32 nSourceCRC32, const char* szName, bool bInclude, AZ::IO::HandleType srcFileHandle) -{ - SShaderBin* pBin = new SShaderBin; - - CParserBin Parser(pBin); - - int nSize = gEnv->pCryPak->FGetSize(srcFileHandle); - char* buf = new char [nSize + 1]; - char* pBuf = buf; - buf[nSize] = 0; - gEnv->pCryPak->FSeek(srcFileHandle, 0, SEEK_SET); - gEnv->pCryPak->FRead(buf, nSize, srcFileHandle); - - RemoveCR(buf); - const char* whiteSpace = " "; - - { - // Hold the parsing context used to get rid of the ## directives. The constructor will - // take care of setting AZ_RESTRICTED_PLATFORM appropriately - PoundPoundContext poundPoundContext(m_pCEF->m_ShadersFilter); - - // Keep parsing until we hit the real EOB. - bool layerSwitch; - while (!poundPoundContext.IsEndOfBuffer(&buf, &layerSwitch)) - { - // This loop handles stripping the input text of comments, whitespace, and the - // ## include directives - do - { - SkipCharacters(&buf, whiteSpace); - SkipComments(&buf, true); - - // If we find the ## characters, preprocess the token lines, allowing it to consume - // any disabled text between ## directives and then whitespace and comments again - while (buf[0] == '#' && buf[1] == '#') - { - poundPoundContext.PreprocessLines(&buf); - SkipCharacters(&buf, whiteSpace); - SkipComments(&buf, true); - } - - // We need to be able to catch the case where a ##include file has hit end of buffer, - // but not the parent buffer, in which case we have to keep skipping whitespace and - // comments again - layerSwitch = false; - } while (!poundPoundContext.IsEndOfBuffer(&buf, &layerSwitch) && layerSwitch); - - // Quit parsing if we have hit the real EOB. - if (poundPoundContext.IsEndOfBuffer(&buf, &layerSwitch)) - { - break; - } - - char com[1024]; - bool bKey = false; - uint32 dwToken = CParserBin::NextToken(buf, com, bKey); - // If the token is not a key token, find/create a user token for it. - dwToken = Parser.NewUserToken(dwToken, com, false); - pBin->m_Tokens.push_back(dwToken); - - SkipCharacters (&buf, whiteSpace); - SkipComments (&buf, true); - if (dwToken == eT_include) - { - // Skip whitespace to get to the < or " bracket for the include - SkipCharacters(&buf, whiteSpace); - AZ_Assert(*buf == '"' || *buf == '<', "Error saving shader %s. Include should be followed by \" or <.", szName); - char brak = *buf; - ++buf; - int n = 0; - - // Get the value in-between the include brackets - while (*buf != brak) - { - if (*buf <= 0x20) - { - AZ_Assert(false, "Error saving shader %s. Invalid special character found between include brackets.", szName); - break; - } - com[n++] = *buf; - ++buf; - } - if (*buf == brak) - { - ++buf; - } - com[n] = 0; - - fpStripExtension(com, com); - - // Get or load the included shader - GetBinShader(com, true, 0); - - dwToken = CParserBin::fxToken(com, NULL); - dwToken = Parser.NewUserToken(dwToken, com, false); - pBin->m_Tokens.push_back(dwToken); - } - else if (dwToken == eT_if || dwToken == eT_ifdef || dwToken == eT_ifndef) - { - bool bFirst = fxIsFirstPass(buf); - if (!bFirst) - { - if (dwToken == eT_if) - { - dwToken = eT_if_2; - } - else if (dwToken == eT_ifdef) - { - dwToken = eT_ifdef_2; - } - else - { - dwToken = eT_ifndef_2; - } - pBin->m_Tokens[pBin->m_Tokens.size() - 1] = dwToken; - } - } - else if (dwToken == eT_define) - { - shFill(&buf, com); - if (com[0] == '%') - { - pBin->m_Tokens[pBin->m_Tokens.size() - 1] = eT_define_2; - } - dwToken = Parser.NewUserToken(eT_unknown, com, false); - pBin->m_Tokens.push_back(dwToken); - - TArray macro; - while (*buf == 0x20 || *buf == 0x9) - { - buf++; - } - while (*buf != 0xa) - { - if (*buf == '\\') - { - macro.AddElem('\n'); - while (*buf != '\n') - { - buf++; - } - buf++; - continue; - } - macro.AddElem(*buf); - buf++; - } - macro.AddElem(0); - int n = macro.Num() - 2; - while (n >= 0 && macro[n] <= 0x20) - { - macro[n] = 0; - n--; - } - char* b = ¯o[0]; - while (*b) - { - SkipCharacters (&b, whiteSpace); - SkipComments (&b, true); - if (!b || !b[0]) - { - break; - } - bKey = false; - dwToken = CParserBin::NextToken(b, com, bKey); - dwToken = Parser.NewUserToken(dwToken, com, false); - if (dwToken == eT_if || dwToken == eT_ifdef || dwToken == eT_ifndef) - { - bool bFirst = fxIsFirstPass(b); - if (!bFirst) - { - if (dwToken == eT_if) - { - dwToken = eT_if_2; - } - else - if (dwToken == eT_ifdef) - { - dwToken = eT_ifdef_2; - } - else - { - dwToken = eT_ifndef_2; - } - } - } - pBin->m_Tokens.push_back(dwToken); - } - pBin->m_Tokens.push_back(0); - } - } - } - if (pBin->m_Tokens.size() == 0 || !pBin->m_Tokens[0]) - { - pBin->m_Tokens.push_back(eT_skip); - } - - pBin->SetCRC(pBin->ComputeCRC()); - pBin->m_bReadOnly = false; - - char nameFile[256]; - sprintf_s(nameFile, "%s%s.%s", m_pCEF->m_ShadersCache.c_str(), szName, bInclude ? "cfib" : "cfxb"); - stack_string szDst = stack_string(m_pCEF->m_szCachePath.c_str()) + stack_string(nameFile); - const char* szFileName = szDst; - - AZ::IO::HandleType dstFileHandle = gEnv->pCryPak->FOpen(szFileName, "wb", AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK); - if (dstFileHandle != AZ::IO::InvalidHandle) - { - SShaderBinHeader Header; - Header.m_nTokens = pBin->m_Tokens.size(); - Header.m_Magic = FOURCC_SHADERBIN; - Header.m_CRC32 = pBin->m_CRC32; - float fVersion = FX_CACHE_VER; - Header.m_VersionLow = (uint16)(((float)fVersion - (float)(int)fVersion) * 10.1f); - Header.m_VersionHigh = (uint16)fVersion; - Header.m_nOffsetStringTable = pBin->m_Tokens.size() * sizeof(DWORD) + sizeof(Header); - Header.m_nOffsetParamsLocal = 0; - Header.m_nSourceCRC32 = nSourceCRC32; - SShaderBinHeader hdTemp, * pHD; - pHD = &Header; - if (CParserBin::m_bEndians) - { - hdTemp = Header; - SwapEndian(hdTemp, eBigEndian); - pHD = &hdTemp; - } - gEnv->pCryPak->FWrite((void*)pHD, sizeof(Header), 1, dstFileHandle); - if (CParserBin::m_bEndians) - { - DWORD* pT = new DWORD [pBin->m_Tokens.size()]; - memcpy(pT, &pBin->m_Tokens[0], pBin->m_Tokens.size() * sizeof(DWORD)); - SwapEndian(pT, (size_t)pBin->m_Tokens.size(), eBigEndian); - gEnv->pCryPak->FWrite((void*)pT, pBin->m_Tokens.size() * sizeof(DWORD), 1, dstFileHandle); - delete [] pT; - } - else - { - gEnv->pCryPak->FWrite(&pBin->m_Tokens[0], pBin->m_Tokens.size() * sizeof(DWORD), 1, dstFileHandle); - } - FXShaderTokenItor itor; - for (itor = pBin->m_TokenTable.begin(); itor != pBin->m_TokenTable.end(); itor++) - { - STokenD T = *itor; - if (CParserBin::m_bEndians) - { - SwapEndian(T.Token, eBigEndian); - } - gEnv->pCryPak->FWrite(&T.Token, sizeof(DWORD), 1, dstFileHandle); - gEnv->pCryPak->FWrite(T.SToken.c_str(), T.SToken.size() + 1, 1, dstFileHandle); - } - Header.m_nOffsetParamsLocal = aznumeric_caster(gEnv->pCryPak->FTell(dstFileHandle)); - gEnv->pCryPak->FSeek(dstFileHandle, 0, SEEK_SET); - if (CParserBin::m_bEndians) - { - hdTemp = Header; - SwapEndian(hdTemp, eBigEndian); - pHD = &hdTemp; - } - gEnv->pCryPak->FWrite((void*)pHD, sizeof(Header), 1, dstFileHandle); - gEnv->pCryPak->FClose(dstFileHandle); - } - else - { - iLog->LogWarning("WARN: CShaderManBin::SaveBinShader: Cannot write shader to file '%s'.", nameFile); - pBin->m_bReadOnly = true; - } - - SAFE_DELETE_ARRAY(pBuf); - - return pBin; -} - -//========================================================================================================================================= - -static void sParseCSV(string& sFlt, std::vector& Filters) -{ - const char* cFlt = sFlt.c_str(); - char Flt[64]; - int nFlt = 0; - while (true) - { - char c = *cFlt++; - if (!c) - { - break; - } - if (SkipChar((unsigned char)c)) - { - if (nFlt) - { - Flt[nFlt] = 0; - Filters.push_back(string(Flt)); - nFlt = 0; - } - continue; - } - Flt[nFlt++] = c; - } - if (nFlt) - { - Flt[nFlt] = 0; - Filters.push_back(string(Flt)); - } -} - -//=========================================================================================================================== - -struct FXParamsSortByName -{ - bool operator () (const SFXParam& left, const SFXParam& right) const - { - return left.m_dwName[0] < right.m_dwName[0]; - } - bool operator () (const uint32 left, const SFXParam& right) const - { - return left < right.m_dwName[0]; - } - bool operator () (const SFXParam& left, uint32 right) const - { - return left.m_dwName[0] < right; - } -}; -struct FXSamplersOldSortByName -{ - bool operator () (const STexSamplerFX& left, const STexSamplerFX& right) const - { - return left.m_szName < right.m_szName; - } - bool operator () (const string left, const STexSamplerFX& right) const - { - return left < right.m_szName; - } - bool operator () (const STexSamplerFX& left, string right) const - { - return left.m_szName < right; - } -}; -struct FXSamplersSortByName -{ - bool operator () (const SFXSampler& left, const SFXSampler& right) const - { - return left.m_dwName[0] < right.m_dwName[0]; - } - bool operator () (const uint32 left, const SFXSampler& right) const - { - return left < right.m_dwName[0]; - } - bool operator () (const SFXSampler& left, const uint32 right) const - { - return left.m_dwName[0] < right; - } -}; -struct FXTexturesSortByName -{ - bool operator () (const SFXTexture& left, const SFXTexture& right) const - { - return left.m_dwName[0] < right.m_dwName[0]; - } - bool operator () (const uint32 left, const SFXTexture& right) const - { - return left < right.m_dwName[0]; - } - bool operator () (const SFXTexture& left, const uint32 right) const - { - return left.m_dwName[0] < right; - } -}; - -int CShaderManBin::mfSizeFXParams(uint32& nCount) -{ - nCount = m_ShaderFXParams.size(); - int nSize = sizeOfMap(m_ShaderFXParams); - return nSize; -} - -void CShaderManBin::mfReleaseFXParams() -{ - m_ShaderFXParams.clear(); -} - -SShaderFXParams& CShaderManBin::mfGetFXParams(CShader* pSH) -{ - CCryNameTSCRC s = pSH->GetNameCRC(); - ShaderFXParamsItor it = m_ShaderFXParams.find(s); - if (it != m_ShaderFXParams.end()) - { - return it->second; - } - SShaderFXParams pr; - std::pair insertLocation = - m_ShaderFXParams.insert(std::pair(s, pr)); - CRY_ASSERT(insertLocation.second); - return insertLocation.first->second; -} - -void CShaderManBin::mfRemoveFXParams(CShader* pSH) -{ - CCryNameTSCRC s = pSH->GetNameCRC(); - ShaderFXParamsItor it = m_ShaderFXParams.find(s); - if (it != m_ShaderFXParams.end()) - { - m_ShaderFXParams.erase(it); - } -} - -SFXParam* CShaderManBin::mfAddFXParam(SShaderFXParams& FXP, const SFXParam* pParam) -{ - FXParamsIt it = std::lower_bound(FXP.m_FXParams.begin(), FXP.m_FXParams.end(), pParam->m_dwName[0], FXParamsSortByName()); - if (it != FXP.m_FXParams.end() && pParam->m_dwName[0] == (*it).m_dwName[0]) - { - SFXParam& pr = *it; - pr.m_nFlags = pParam->m_nFlags; - int n = 6; - SFXParam& p = *it; - for (int i = 0; i < n; i++) - { - if (p.m_Register[i] == 10000) - { - p.m_Register[i] = pParam->m_Register[i]; - } - } - //CRY_ASSERT(p == *pParam); - return &(*it); - } - FXP.m_FXParams.insert(it, *pParam); - it = std::lower_bound(FXP.m_FXParams.begin(), FXP.m_FXParams.end(), pParam->m_dwName[0], FXParamsSortByName()); - SFXParam* pFX = &(*it); - if (pFX->m_Semantic.empty() && pFX->m_Values.c_str()[0] == '(') - { - pFX->m_BindingSlot = eConstantBufferShaderSlot_PerMaterial; - } - FXP.m_nFlags |= FXP_PARAMS_DIRTY; - - return pFX; -} -SFXParam* CShaderManBin::mfAddFXParam(CShader* pSH, const SFXParam* pParam) -{ - if (!pParam) - { - return NULL; - } - - SShaderFXParams& FXP = mfGetFXParams(pSH); - return mfAddFXParam(FXP, pParam); -} -void CShaderManBin::mfAddFXSampler(CShader* pSH, const STexSamplerFX* pSamp) -{ - if (!pSamp) - { - return; - } - - SShaderFXParams& FXP = mfGetFXParams(pSH); - - FXSamplersOldIt it = std::lower_bound(FXP.m_FXSamplersOld.begin(), FXP.m_FXSamplersOld.end(), pSamp->m_szName, FXSamplersOldSortByName()); - if (it != FXP.m_FXSamplersOld.end() && pSamp->m_szName == (*it).m_szName) - { - CRY_ASSERT(*it == *pSamp); - return; - } - FXP.m_FXSamplersOld.insert(it, *pSamp); - FXP.m_nFlags |= FXP_SAMPLERS_DIRTY; -} -void CShaderManBin::mfAddFXSampler(CShader* pSH, const SFXSampler* pSamp) -{ - if (!pSamp) - { - return; - } - - SShaderFXParams& FXP = mfGetFXParams(pSH); - - FXSamplersIt it = std::lower_bound(FXP.m_FXSamplers.begin(), FXP.m_FXSamplers.end(), pSamp->m_dwName[0], FXSamplersSortByName()); - if (it != FXP.m_FXSamplers.end() && pSamp->m_dwName[0] == (*it).m_dwName[0]) - { - CRY_ASSERT(*it == *pSamp); - return; - } - FXP.m_FXSamplers.insert(it, *pSamp); - FXP.m_nFlags |= FXP_SAMPLERS_DIRTY; -} - -//------------------------------------------------------------------------------ -// Add a new texture to the shader's textures array based on the texture name -//------------------------------------------------------------------------------ -void CShaderManBin::mfAddFXTexture(CShader* pSH, const SFXTexture* pTexture) -{ - if (!pTexture) - { - return; - } - - SShaderFXParams& FXP = mfGetFXParams(pSH); - FXTexturesIt it = std::lower_bound(FXP.m_FXTextures.begin(), FXP.m_FXTextures.end(), pTexture->m_dwName[0], FXTexturesSortByName()); - - if (it != FXP.m_FXTextures.end() && pTexture->m_dwName[0] == (*it).m_dwName[0]) - { - CRY_ASSERT(*it == *pTexture); - return; - } - FXP.m_FXTextures.insert(it, *pTexture); - FXP.m_nFlags |= FXP_TEXTURES_DIRTY; -} - -void CShaderManBin::mfGeneratePublicFXParams(CShader* pSH, CParserBin& Parser) -{ - SShaderFXParams& FXP = mfGetFXParams(pSH); - if (!(FXP.m_nFlags & FXP_PARAMS_DIRTY)) - { - return; - } - FXP.m_nFlags &= ~FXP_PARAMS_DIRTY; - - uint32 i; - // Generate public parameters - for (i = 0; i < FXP.m_FXParams.size(); i++) - { - SFXParam* pr = &FXP.m_FXParams[i]; - uint32 nFlags = pr->GetFlags(); - if (nFlags & PF_AUTOMERGED) - { - continue; - } - if (nFlags & PF_TWEAKABLE_MASK) - { - const char* szName = Parser.GetString(pr->m_dwName[0]); - // Avoid duplicating of public parameters - int32 j; - for (j = 0; j < FXP.m_PublicParams.size(); j++) - { - SShaderParam* p = &FXP.m_PublicParams[j]; - if (azstricmp(p->m_Name.c_str(), szName) == 0) - { - break; - } - } - if (j == FXP.m_PublicParams.size()) - { - SShaderParam sp; - sp.m_Name = szName; - EParamType eType; - string szWidget = pr->GetValueForName("UIWidget", eType); - const char* szVal = pr->m_Values.c_str(); - if (szWidget == "color") - { - sp.m_Type = eType_FCOLOR; - if (szVal[0] == '{') - { - szVal++; - } - [[maybe_unused]] int n = azsscanf(szVal, "%f, %f, %f, %f", &sp.m_Value.m_Color[0], &sp.m_Value.m_Color[1], &sp.m_Value.m_Color[2], &sp.m_Value.m_Color[3]); - AZ_Warning("Shaders", n == 4, "color value only has %d components", n); - } - else if (szWidget == "colora") - { - sp.m_Type = eType_FCOLORA; - if (szVal[0] == '{') - { - szVal++; - } - [[maybe_unused]] int n = azsscanf(szVal, "%f, %f, %f, %f", &sp.m_Value.m_Color[0], &sp.m_Value.m_Color[1], &sp.m_Value.m_Color[2], &sp.m_Value.m_Color[3]); - AZ_Warning("Shaders", n == 4, "color value only has %d components", n); - } - else - { - sp.m_Type = eType_FLOAT; - sp.m_Value.m_Float = (float)atof(szVal); - } - - bool bAdd = true; - if (!pr->m_Annotations.empty() && gRenDev->IsEditorMode()) - { - //EParamType eType; - string sFlt = pr->GetValueForName("Filter", eType); - bool bUseScript = true; - if (!sFlt.empty()) - { - std::vector Filters; - sParseCSV(sFlt, Filters); - string strShader = Parser.m_pCurShader->GetName(); - uint32 h; - for (h = 0; h < Filters.size(); h++) - { - if (!_strnicmp(Filters[h].c_str(), strShader.c_str(), Filters[h].size())) - { - break; - } - } - if (h == Filters.size()) - { - bUseScript = false; - bAdd = false; - } - } - - if (bUseScript) - { - sp.m_Script = pr->m_Annotations.c_str(); - } - } - - if (bAdd) - { - FXP.m_PublicParams.push_back(sp); - } - } - } - } -} - -SParamCacheInfo* CShaderManBin::GetParamInfo(SShaderBin* pBin, uint32 dwName, uint64 nMaskGenFX, uint64 maskGenStatic) -{ - const int n = pBin->m_ParamsCache.size(); - for (int i = 0; i < n; i++) - { - SParamCacheInfo* pInf = &pBin->m_ParamsCache[i]; - if (pInf->m_dwName == dwName && pInf->m_nMaskGenFX == nMaskGenFX && pInf->m_maskGenStatic == maskGenStatic) - { - pBin->m_nCurParamsID = i; - return pInf; - } - } - pBin->m_nCurParamsID = -1; - return NULL; -} - -bool CShaderManBin::SaveBinShaderLocalInfo(SShaderBin* pBin, uint32 dwName, uint64 nMaskGenFX, uint64 maskGenStatic, TArray& Funcs, std::vector& Params, std::vector& Samplers, std::vector& Textures) -{ - if (GetParamInfo(pBin, dwName, nMaskGenFX, maskGenStatic)) - { - return true; - } - - if (pBin->IsReadOnly() && !gEnv->IsEditor()) // if in the editor, allow params to be added in-memory, but not saved to disk - { - return false; - } - TArray EParams; - TArray ESamplers; - TArray ETextures; - TArray EFuncs; - for (uint32 i = 0; i < Params.size(); i++) - { - SFXParam& pr = Params[i]; - CRY_ASSERT(pr.m_dwName.size()); - if (pr.m_dwName.size()) - { - EParams.push_back(pr.m_dwName[0]); - } - } - for (uint32 i = 0; i < Samplers.size(); i++) - { - SFXSampler& pr = Samplers[i]; - CRY_ASSERT(pr.m_dwName.size()); - if (pr.m_dwName.size()) - { - ESamplers.push_back(pr.m_dwName[0]); - } - } - for (uint32 i = 0; i < Textures.size(); i++) - { - SFXTexture& pr = Textures[i]; - CRY_ASSERT(pr.m_dwName.size()); - if (pr.m_dwName.size()) - { - ETextures.push_back(pr.m_dwName[0]); - } - } - pBin->m_nCurParamsID = pBin->m_ParamsCache.size(); - pBin->m_ParamsCache.push_back(SParamCacheInfo()); - SParamCacheInfo& pr = pBin->m_ParamsCache.back(); - pr.m_nMaskGenFX = nMaskGenFX; - pr.m_maskGenStatic = maskGenStatic; - pr.m_dwName = dwName; - pr.m_AffectedFuncs.assign(Funcs.begin(), Funcs.end()); - pr.m_AffectedParams.assign(EParams.begin(), EParams.end()); - pr.m_AffectedSamplers.assign(ESamplers.begin(), ESamplers.end()); - pr.m_AffectedTextures.assign(ETextures.begin(), ETextures.end()); - if (pBin->IsReadOnly()) - { - return false; - } - AZ::IO::HandleType binFileHandle = gEnv->pCryPak->FOpen(pBin->m_szName, "r+b", AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK); - CRY_ASSERT(binFileHandle != AZ::IO::InvalidHandle); - if (binFileHandle == AZ::IO::InvalidHandle) - { - return false; - } - gEnv->pCryPak->FSeek(binFileHandle, 0, SEEK_END); - uint64_t nSeek = gEnv->pCryPak->FTell(binFileHandle); - CRY_ASSERT(nSeek > 0); - if (nSeek == 0) - { - return false; - } - SShaderBinParamsHeader sd; - int32* pFuncs = &Funcs[0]; - int32* pParams = EParams.size() ? &EParams[0] : NULL; - int32* pSamplers = ESamplers.size() ? &ESamplers[0] : NULL; - int32* pTextures = ETextures.size() ? &ETextures[0] : NULL; - sd.nMask = nMaskGenFX; - sd.nstaticMask = maskGenStatic; - sd.nName = dwName; - sd.nFuncs = Funcs.size(); - sd.nParams = EParams.size(); - sd.nSamplers = ESamplers.size(); - sd.nTextures = ETextures.size(); - if (CParserBin::m_bEndians) - { - SwapEndian(sd, eBigEndian); - EFuncs = Funcs; - if (EParams.size()) - { - SwapEndian(&EParams[0], (size_t)EParams.size(), eBigEndian); - } - if (ESamplers.size()) - { - SwapEndian(&ESamplers[0], (size_t)ESamplers.size(), eBigEndian); - } - if (ETextures.size()) - { - SwapEndian(&ETextures[0], (size_t)ETextures.size(), eBigEndian); - } - SwapEndian(&EFuncs[0], (size_t)EFuncs.size(), eBigEndian); - pFuncs = &EFuncs[0]; - } - gEnv->pCryPak->FWrite(&sd, sizeof(sd), 1, binFileHandle); - - if (EParams.size()) - { - gEnv->pCryPak->FWrite(pParams, EParams.size(), sizeof(int32), binFileHandle); - } - if (ESamplers.size()) - { - gEnv->pCryPak->FWrite(pSamplers, ESamplers.size(), sizeof(int32), binFileHandle); - } - if (ETextures.size()) - { - gEnv->pCryPak->FWrite(pTextures, ETextures.size(), sizeof(int32), binFileHandle); - } - gEnv->pCryPak->FWrite(pFuncs, Funcs.size(), sizeof(int32), binFileHandle); - gEnv->pCryPak->FClose(binFileHandle); - - return true; -} - -SShaderBin* CShaderManBin::LoadBinShader(AZ::IO::HandleType fpBin, const char* szName, const char* szNameBin, bool bReadParams) -{ - LOADING_TIME_PROFILE_SECTION(iSystem); - - gEnv->pCryPak->FSeek(fpBin, 0, SEEK_SET); - SShaderBinHeader Header; - size_t sizeRead = gEnv->pCryPak->FReadRaw(&Header, 1, sizeof(SShaderBinHeader), fpBin); - if (sizeRead != sizeof(SShaderBinHeader)) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read header for %s in CShaderManBin::LoadBinShader. Expected %" PRISIZE_T ", got %" PRISIZE_T "", szName, sizeof(SShaderBinHeader), sizeRead); - return NULL; - } - - if (CParserBin::m_bEndians) - { - SwapEndian(Header, eBigEndian); - } - float fVersion = FX_CACHE_VER; - uint16 MinorVer = (uint16)(((float)fVersion - (float)(int)fVersion) * 10.1f); - uint16 MajorVer = (uint16)fVersion; - bool bCheckValid = CRenderer::CV_r_shadersAllowCompilation != 0; - if (bCheckValid && (Header.m_VersionLow != MinorVer || Header.m_VersionHigh != MajorVer || Header.m_Magic != FOURCC_SHADERBIN)) - { - return NULL; - } - if (Header.m_VersionHigh > 10) - { - return NULL; - } - SShaderBin* pBin = new SShaderBin; - - pBin->m_SourceCRC32 = Header.m_nSourceCRC32; - pBin->m_nOffsetLocalInfo = Header.m_nOffsetParamsLocal; - - uint32 CRC32 = Header.m_CRC32; - pBin->m_CRC32 = CRC32; - pBin->m_Tokens.resize(Header.m_nTokens); - sizeRead = gEnv->pCryPak->FReadRaw(&pBin->m_Tokens[0], sizeof(uint32), Header.m_nTokens, fpBin); - if (sizeRead != Header.m_nTokens) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read Tokens for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T "", szName, Header.m_nTokens, sizeRead); - return NULL; - } - if (CParserBin::m_bEndians) - { - SwapEndian(&pBin->m_Tokens[0], (size_t)Header.m_nTokens, eBigEndian); - } - - int nSizeTable = Header.m_nOffsetParamsLocal - Header.m_nOffsetStringTable; - if (nSizeTable < 0) - { - return NULL; - } - else if (nSizeTable > 0) - { - char* bufTable = new char[nSizeTable]; - char* bufT = bufTable; - sizeRead = gEnv->pCryPak->FReadRaw(bufTable, 1, nSizeTable, fpBin); - if (sizeRead != nSizeTable) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read bufTable for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T "", szName, nSizeTable, sizeRead); - return NULL; - } - char* bufEnd = &bufTable[nSizeTable]; - - // First pass to count the tokens - uint32 nTokens(0); - while (bufTable < bufEnd) - { - STokenD TD; - LoadUnaligned(bufTable, TD.Token); - int nIncr = 4 + strlen(&bufTable[4]) + 1; - bufTable += nIncr; - ++nTokens; - } - - pBin->m_TokenTable.reserve(nTokens); - bufTable = bufT; - while (bufTable < bufEnd) - { - STokenD TD; - LoadUnaligned(bufTable, TD.Token); - if (CParserBin::m_bEndians) - { - SwapEndian(TD.Token, eBigEndian); - } - FXShaderTokenItor itor = std::lower_bound(pBin->m_TokenTable.begin(), pBin->m_TokenTable.end(), TD.Token, SortByToken()); - assert (itor == pBin->m_TokenTable.end() || (*itor).Token != TD.Token); - TD.SToken = &bufTable[4]; - pBin->m_TokenTable.insert(itor, TD); - int nIncr = 4 + strlen(&bufTable[4]) + 1; - bufTable += nIncr; - } - SAFE_DELETE_ARRAY(bufT); - } - - //if (CRenderer::CV_r_shadersnocompile) - // bReadParams = false; - if (bReadParams) - { - int nSeek = pBin->m_nOffsetLocalInfo; - gEnv->pCryPak->FSeek(fpBin, nSeek, SEEK_SET); - while (true) - { - SShaderBinParamsHeader sd; - int nSize = gEnv->pCryPak->FReadRaw(&sd, 1, sizeof(sd), fpBin); - if (nSize != sizeof(sd)) - { - break; - } - if (CParserBin::m_bEndians) - { - SwapEndian(sd, eBigEndian); - } - - if (sd.nParams < 0 || sd.nSamplers < 0 || sd.nTextures < 0 || sd.nFuncs < 0) - { - AZ_Assert(false, "Error attempting to read shader binary %s. You may need to delete and re-compile this shader binary from your cache folder.", szNameBin); - return nullptr; - } - - SParamCacheInfo pr; - int n = pBin->m_ParamsCache.size(); - pBin->m_ParamsCache.push_back(pr); - SParamCacheInfo& prc = pBin->m_ParamsCache[n]; - prc.m_dwName = sd.nName; - prc.m_nMaskGenFX = sd.nMask; - prc.m_maskGenStatic = sd.nstaticMask; - prc.m_AffectedParams.resize(sd.nParams); - prc.m_AffectedSamplers.resize(sd.nSamplers); - prc.m_AffectedTextures.resize(sd.nTextures); - prc.m_AffectedFuncs.resize(sd.nFuncs); - - if (sd.nParams) - { - nSize = gEnv->pCryPak->FReadRaw(&prc.m_AffectedParams[0], sizeof(int32), sd.nParams, fpBin); - if (nSize != sd.nParams) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read m_AffectedParams for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T "", szName, sd.nParams, sizeRead); - return NULL; - } - if (CParserBin::m_bEndians) - { - SwapEndian(&prc.m_AffectedParams[0], sd.nParams, eBigEndian); - } - } - if (sd.nSamplers) - { - nSize = gEnv->pCryPak->FReadRaw(&prc.m_AffectedSamplers[0], sizeof(int32), sd.nSamplers, fpBin); - if (nSize != sd.nSamplers) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read m_AffectedSamplers for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T, szName, sd.nSamplers, sizeRead); - return NULL; - } - if (CParserBin::m_bEndians) - { - SwapEndian(&prc.m_AffectedSamplers[0], sd.nSamplers, eBigEndian); - } - } - if (sd.nTextures) - { - nSize = gEnv->pCryPak->FReadRaw(&prc.m_AffectedTextures[0], sizeof(int32), sd.nTextures, fpBin); - if (nSize != sd.nTextures) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read m_AffectedTextures for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T, szName, sd.nTextures, sizeRead); - return NULL; - } - if (CParserBin::m_bEndians) - { - SwapEndian(&prc.m_AffectedTextures[0], sd.nTextures, eBigEndian); - } - } - - CRY_ASSERT(sd.nFuncs > 0); - nSize = gEnv->pCryPak->FReadRaw(&prc.m_AffectedFuncs[0], sizeof(int32), sd.nFuncs, fpBin); - if (nSize != sd.nFuncs) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Failed to read nFuncs for %s in CShaderManBin::LoadBinShader. Expected %d, got %" PRISIZE_T "", szName, sd.nFuncs, sizeRead); - return NULL; - } - if (CParserBin::m_bEndians) - { - SwapEndian(&prc.m_AffectedFuncs[0], sd.nFuncs, eBigEndian); - } - - nSeek += (sd.nFuncs) * sizeof(int32) + sizeof(sd); - } - } - - char nameLwr[256]; - cry_strcpy(nameLwr, szName); - azstrlwr(nameLwr, AZ_ARRAY_SIZE(nameLwr)); - pBin->SetName(szNameBin); - pBin->m_dwName = CParserBin::GetCRC32(nameLwr); - - return pBin; -} - -SShaderBin* CShaderManBin::SearchInCache(const char* szName, bool bInclude) -{ - char nameFile[256], nameLwr[256]; - cry_strcpy(nameLwr, szName); - azstrlwr(nameLwr, AZ_ARRAY_SIZE(nameLwr)); - sprintf_s(nameFile, "%s.%s", nameLwr, bInclude ? "cfi" : "cfx"); - uint32 dwName = CParserBin::GetCRC32(nameFile); - - SShaderBin* pSB; - for (pSB = SShaderBin::s_Root.m_Prev; pSB != &SShaderBin::s_Root; pSB = pSB->m_Prev) - { - if (pSB->m_dwName == dwName) - { - pSB->Unlink(); - pSB->Link(&SShaderBin::s_Root); - return pSB; - } - } - return NULL; -} - -bool CShaderManBin::AddToCache(SShaderBin* pSB, bool bInclude) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_shadersediting) - { - if (SShaderBin::s_nCache >= SShaderBin::s_nMaxFXBinCache) - { - SShaderBin* pS; - for (pS = SShaderBin::s_Root.m_Prev; pS != &SShaderBin::s_Root; pS = pS->m_Prev) - { - if (!pS->m_bLocked) - { - DeleteFromCache(pS); - break; - } - } - } - CRY_ASSERT(SShaderBin::s_nCache < SShaderBin::s_nMaxFXBinCache); - } - - pSB->m_bInclude = bInclude; - pSB->Link(&SShaderBin::s_Root); - SShaderBin::s_nCache++; - - return true; -} - -bool CShaderManBin::DeleteFromCache(SShaderBin* pSB) -{ - CRY_ASSERT(pSB != &SShaderBin::s_Root); - pSB->Unlink(); - SAFE_DELETE(pSB); - SShaderBin::s_nCache--; - - return true; -} - -void CShaderManBin::InvalidateCache(bool bIncludesOnly) -{ - SShaderBin* pSB, * Next; - for (pSB = SShaderBin::s_Root.m_Next; pSB != &SShaderBin::s_Root; pSB = Next) - { - Next = pSB->m_Next; - if (bIncludesOnly && !pSB->m_bInclude) - { - continue; - } - DeleteFromCache(pSB); - } - SShaderBin::s_nMaxFXBinCache = MAX_FXBIN_CACHE; - m_bBinaryShadersLoaded = false; - - g_shaderBucketAllocator.cleanup(); - -#if defined(SHADERS_SERIALIZING) - // Clear our .fxb cache if we are deleting our shader binary cache. - // We end up initializing part of the shader system with D3D11 as the platform - // and then switch to the real platform soon after, so make sure this cache is clean. - gRenDev->m_cEF.ClearSResourceCache(); -#endif -} - -#define SEC5_FILETIME 10*1000*1000*5 - - -SShaderBin* CShaderManBin::GetBinShader(const char* szName, bool bInclude, uint32 nRefCRC, bool* pbChanged) -{ - //static float sfTotalTime = 0.0f; - - if (pbChanged) - { - if (gRenDev->IsEditorMode()) - { - *pbChanged = false; - } - } - - //float fTime0 = iTimer->GetAsyncCurTime(); - - SShaderBin* pSHB = SearchInCache(szName, bInclude); - if (pSHB) - { - return pSHB; - } - SShaderBinHeader Header[2]; - memset(&Header, 0, 2 * sizeof(SShaderBinHeader)); - char nameFile[256], nameBin[256]; - AZ::IO::HandleType srcFileHandle = AZ::IO::InvalidHandle; - sprintf_s(nameFile, "%sCryFX/%s.%s", gRenDev->m_cEF.m_ShadersPath.c_str(), szName, bInclude ? "cfi" : "cfx"); -#if !defined(_RELEASE) - uint32 nSourceCRC32 = 0; - { - srcFileHandle = gEnv->pCryPak->FOpen(nameFile, "rb"); - nSourceCRC32 = srcFileHandle != AZ::IO::InvalidHandle ? gEnv->pCryPak->ComputeCRC(nameFile) : 0; - } -#endif - //char szPath[1024]; - //getcwd(szPath, 1024); - sprintf_s(nameBin, "%s%s.%s", m_pCEF->m_ShadersCache.c_str(), szName, bInclude ? "cfib" : "cfxb"); - AZ::IO::HandleType dstFileHandle = AZ::IO::InvalidHandle; - int i = 0, n = 2; - - // don't load from the shadercache.pak when in editing mode - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersediting) - { - i = 1; - } - - AZStd::string szDst = m_pCEF->m_szCachePath + nameBin; - byte bValid = 0; - float fVersion = FX_CACHE_VER; - for (; i < n; i++) - { - if (dstFileHandle != AZ::IO::InvalidHandle) - { - gEnv->pCryPak->FClose(dstFileHandle); - } - if (!i) - { - if (n == 2) - { - char nameLwr[256]; - sprintf_s(nameLwr, "%s.%s", szName, bInclude ? "cfi" : "cfx"); - azstrlwr(nameLwr, AZ_ARRAY_SIZE(nameLwr)); - uint32 dwName = CParserBin::GetCRC32(nameLwr); - FXShaderBinValidCRCItor itor = m_BinValidCRCs.find(dwName); - if (itor != m_BinValidCRCs.end()) - { - CRY_ASSERT(itor->second == false); - continue; - } - } - dstFileHandle = gEnv->pCryPak->FOpen(nameBin, "rb"); - } - else - { - dstFileHandle = gEnv->pCryPak->FOpen(szDst.c_str(), "rb", AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK); - } - if (dstFileHandle == AZ::IO::InvalidHandle) - { - continue; - } - else - { - gEnv->pCryPak->FReadRaw(&Header[i], 1, sizeof(SShaderBinHeader), dstFileHandle); - if (CParserBin::m_bEndians) - { - SwapEndian(Header[i], eBigEndian); - } - -#if !defined(_RELEASE) - // check source crc changes - if (nSourceCRC32 && nSourceCRC32 != Header[i].m_nSourceCRC32) - { - bValid |= 1 << i; - } - else -#endif - { - uint16 MinorVer = (uint16)(((float)fVersion - (float)(int)fVersion) * 10.1f); - uint16 MajorVer = (uint16)fVersion; - if (Header[i].m_VersionLow != MinorVer || Header[i].m_VersionHigh != MajorVer || Header[i].m_Magic != FOURCC_SHADERBIN) - { - bValid |= 4 << i; - } - else - if (nRefCRC && Header[i].m_CRC32 != nRefCRC) - { - bValid |= 0x10 << i; - } - } - } - if (!(bValid & (0x15 << i))) - { - break; - } - } - if (i == n) - { -#if !defined(_RELEASE) && !defined(CONSOLE_CONST_CVAR_MODE) - { - char acTemp[512]; - if (bValid & 1) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader '%s' source crc mismatch", nameBin); - } - if (bValid & 4) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader '%s' version mismatch (Cache: %d.%d, Expected: %.1f)", nameBin, Header[0].m_VersionHigh, Header[0].m_VersionLow, fVersion); - } - if (bValid & 0x10) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader '%s' CRC mismatch", nameBin); - } - - if (bValid & 2) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader USER '%s' source crc mismatch", nameBin); - } - if (bValid & 8) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader USER '%s' version mismatch (Cache: %d.%d, Expected: %.1f)", nameBin, Header[1].m_VersionHigh, Header[1].m_VersionLow, fVersion); - } - if (bValid & 0x20) - { - sprintf_s(acTemp, 512, "WARNING: Bin FXShader USER '%s' CRC mismatch", nameBin); - } - - if (bValid) - { - LogWarningEngineOnly(acTemp); - } - - if (dstFileHandle != AZ::IO::InvalidHandle) - { - gEnv->pCryPak->FClose(dstFileHandle); - dstFileHandle = AZ::IO::InvalidHandle; - } - - if (srcFileHandle != AZ::IO::InvalidHandle) - { - // enable shader compilation again, and show big error message - if (!CRenderer::CV_r_shadersAllowCompilation) - { - if (CRenderer::CV_r_shaderscompileautoactivate) - { - CRenderer::CV_r_shadersAllowCompilation = 1; - CRenderer::CV_r_shadersasyncactivation = 0; - - gEnv->pLog->LogError("ERROR: LOADING BIN SHADER - REACTIVATING SHADER COMPILATION !"); - } - else - { - static bool bShowMessageBox = true; - - if (bShowMessageBox) - { - AZStd::string result; - EBUS_EVENT_RESULT(result, AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Invalid ShaderCache", acTemp, true); - if (result == "Cancel") - { - DebugBreak(); - } - else if (!result.empty()) - { - bShowMessageBox = false; - Sleep(33); - } - else - { - Warning("Invalid ShaderCache"); - } - } - } - } - - if (CRenderer::CV_r_shadersAllowCompilation) - { - pSHB = SaveBinShader(nSourceCRC32, szName, bInclude, srcFileHandle); - CRY_ASSERT(!pSHB->m_Next); - if (pbChanged) - { - *pbChanged = true; - } - - // remove the entries in the looupdata, to be sure that level and global caches have also become invalid for these shaders! - gRenDev->m_cEF.m_ResLookupDataMan[CACHE_READONLY].RemoveData(Header[0].m_CRC32); - gRenDev->m_cEF.m_ResLookupDataMan[CACHE_USER].RemoveData(Header[1].m_CRC32); - - // has the shader been successfully written to the dest address - dstFileHandle = gEnv->pCryPak->FOpen(szDst.c_str(), "rb", AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FOPEN_ONDISK); - if (dstFileHandle != AZ::IO::InvalidHandle) - { - SAFE_DELETE(pSHB); - i = 1; - } - } - } - } -#endif - } - if (srcFileHandle != AZ::IO::InvalidHandle) - { - gEnv->pCryPak->FClose(srcFileHandle); - srcFileHandle = AZ::IO::InvalidHandle; - } - - if (!CRenderer::CV_r_shadersAllowCompilation) - { - if (pSHB == 0 && dstFileHandle == AZ::IO::InvalidHandle) - { - //do only perform the necessary stuff - dstFileHandle = gEnv->pCryPak->FOpen(nameBin, "rb"); - } - } - if (pSHB == 0 && dstFileHandle != AZ::IO::InvalidHandle) - { - sprintf_s(nameFile, "%s.%s", szName, bInclude ? "cfi" : "cfx"); - pSHB = LoadBinShader(dstFileHandle, nameFile, i == 0 ? nameBin : szDst.c_str(), !bInclude); - gEnv->pCryPak->FClose(dstFileHandle); - dstFileHandle = AZ::IO::InvalidHandle; - AZ_Assert(pSHB, "Error loading binary shader '%s'.", nameFile); - } - - if (pSHB) - { - if (i == 0) - { - pSHB->m_bReadOnly = true; - } - else - { - pSHB->m_bReadOnly = false; - } - - AddToCache(pSHB, bInclude); - if (!bInclude) - { - char nm[128]; - nm[0] = '$'; - azstrcpy(&nm[1], AZ_ARRAY_SIZE(nm) - 1, szName); - CCryNameTSCRC NM = CParserBin::GetPlatformSpecName(nm); - FXShaderBinPathItor it = m_BinPaths.find(NM); - if (it == m_BinPaths.end()) - { - m_BinPaths.insert(FXShaderBinPath::value_type(NM, i == 0 ? nameBin : szDst.c_str())); - } - else - { - it->second = (i == 0) ? nameBin : szDst.c_str(); - } - } - } - else - { - if (dstFileHandle != AZ::IO::InvalidHandle) - { - Warning("Error: Failed to get binary shader '%s'", nameFile); - } - else - { - sprintf_s(nameFile, "%s.%s", szName, bInclude ? "cfi" : "cfx"); - const char* matName = 0; - if (m_pCEF && m_pCEF->m_pCurInputResources) - { - matName = m_pCEF->m_pCurInputResources->m_szMaterialName; - } - iLog->LogWarning("WARN: Shader \"%s\" doesn't exist (used in material \"%s\")", nameFile, matName != 0 ? matName : "$unknown$"); - } - } - - /* - sfTotalTime += iTimer->GetAsyncCurTime() - fTime0; - - { - char acTmp[1024]; - sprintf_s(acTmp, "Parsing of bin took: %f \n", sfTotalTime); - OutputDebugString(acTmp); - } - */ - - return pSHB; -} - -void CShaderManBin::AddGenMacroses(SShaderGen* shG, CParserBin& Parser, uint64 nMaskGen, bool ignoreShaderGenMask /*=false*/) -{ - if (!nMaskGen || !shG) - { - return; - } - - uint32 dwMacro = eT_1; - for (uint32 i = 0; i < shG->m_BitMask.Num(); i++) - { - if (shG->m_BitMask[i]->m_Mask & nMaskGen) - { - Parser.AddMacro(shG->m_BitMask[i]->m_dwToken, &dwMacro, 1, ignoreShaderGenMask ? 0 : shG->m_BitMask[i]->m_Mask, Parser.m_Macros[1]); - } - } -} - -bool CShaderManBin::ParseBinFX_Global_Annotations(CParserBin& Parser, SParserFrame& Frame, bool* bPublic, [[maybe_unused]] CCryNameR techStart[2]) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(ShaderType) - FX_TOKEN(ShaderDrawType) - FX_TOKEN(PreprType) - FX_TOKEN(Public) - FX_TOKEN(NoPreview) - FX_TOKEN(LocalConstants) - FX_TOKEN(Cull) - FX_TOKEN(SupportsAttrInstancing) - FX_TOKEN(SupportsConstInstancing) - FX_TOKEN(SupportsDeferredShading) - FX_TOKEN(SupportsFullDeferredShading) - FX_TOKEN(Decal) - FX_TOKEN(DecalNoDepthOffset) - FX_TOKEN(HWTessellation) - FX_TOKEN(ZPrePass) - FX_TOKEN(VertexColors) - FX_TOKEN(NoChunkMerging) - FX_TOKEN(ForceTransPass) - FX_TOKEN(AfterHDRPostProcess) - FX_TOKEN(AfterPostProcess) - FX_TOKEN(ForceZpass) - FX_TOKEN(ForceWaterPass) - FX_TOKEN(ForceDrawLast) - FX_TOKEN(ForceDrawFirst) - FX_TOKEN(Hair) - FX_TOKEN(SkinPass) - FX_TOKEN(ForceGeneralPass) - FX_TOKEN(ForceDrawAfterWater) - FX_TOKEN(DepthFixup) - FX_TOKEN(SingleLightPass) - FX_TOKEN(Refractive) - FX_TOKEN(ForceRefractionUpdate) - FX_TOKEN(WaterParticle) - FX_TOKEN(VT_DetailBending) - FX_TOKEN(VT_DetailBendingGrass) - FX_TOKEN(VT_WindBending) - FX_TOKEN(AlphaBlendShadows) - FX_TOKEN(EyeOverlay) - FX_END_TOKENS - - int nIndex; - CShader* ef = Parser.m_pCurShader; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_Public: - if (bPublic) - { - *bPublic = true; - } - break; - - case eT_NoPreview: - if (!ef) - { - break; - } - ef->m_Flags |= EF_NOPREVIEW; - break; - - case eT_Decal: - if (!ef) - { - break; - } - ef->m_Flags |= EF_DECAL; - ef->m_nMDV |= MDV_DEPTH_OFFSET; - break; - - case eT_DecalNoDepthOffset: - if (!ef) - { - break; - } - ef->m_Flags |= EF_DECAL; - break; - - - case eT_LocalConstants: - if (!ef) - { - break; - } - ef->m_Flags |= EF_LOCALCONSTANTS; - break; - - case eT_VT_DetailBending: - if (!ef) - { - break; - } - ef->m_nMDV |= MDV_DET_BENDING; - break; - case eT_VT_DetailBendingGrass: - if (!ef) - { - break; - } - ef->m_nMDV |= MDV_DET_BENDING | MDV_DET_BENDING_GRASS; - break; - case eT_VT_WindBending: - if (!ef) - { - break; - } - ef->m_nMDV |= MDV_WIND; - break; - - case eT_NoChunkMerging: - if (!ef) - { - break; - } - ef->m_Flags |= EF_NOCHUNKMERGING; - break; - - case eT_SupportsAttrInstancing: - if (!ef) - { - break; - } - if (gRenDev->m_bDeviceSupportsInstancing) - { - ef->m_Flags |= EF_SUPPORTSINSTANCING_ATTR; - } - break; - case eT_SupportsConstInstancing: - if (!ef) - { - break; - } - if (gRenDev->m_bDeviceSupportsInstancing) - { - ef->m_Flags |= EF_SUPPORTSINSTANCING_CONST; - } - break; - - case eT_SupportsDeferredShading: - if (!ef) - { - break; - } - ef->m_Flags |= EF_SUPPORTSDEFERREDSHADING_MIXED; - break; - - case eT_SupportsFullDeferredShading: - if (!ef) - { - break; - } - ef->m_Flags |= EF_SUPPORTSDEFERREDSHADING_FULL; - break; - - case eT_ForceTransPass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_TRANSPASS; - break; - - case eT_AfterHDRPostProcess: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_AFTERHDRPOSTPROCESS; - break; - - case eT_AfterPostProcess: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_AFTERPOSTPROCESS; - break; - - case eT_ForceZpass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_ZPASS; - break; - - case eT_ForceWaterPass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_WATERPASS; - break; - - case eT_ForceDrawLast: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_DRAWLAST; - break; - case eT_ForceDrawFirst: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_DRAWFIRST; - break; - - case eT_Hair: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_HAIR; - break; - - case eT_ForceGeneralPass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_GENERALPASS; - break; - - case eT_ForceDrawAfterWater: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_FORCE_DRAWAFTERWATER; - break; - case eT_DepthFixup: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_DEPTH_FIXUP; - break; - case eT_SingleLightPass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_SINGLELIGHTPASS; - break; - case eT_WaterParticle: - if (!ef) - { - break; - } - ef->m_Flags |= EF_WATERPARTICLE; - break; - case eT_Refractive: - if (!ef) - { - break; - } - ef->m_Flags |= EF_REFRACTIVE; - break; - case eT_ForceRefractionUpdate: - if (!ef) - { - break; - } - ef->m_Flags |= EF_FORCEREFRACTIONUPDATE; - break; - - case eT_ZPrePass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_ZPREPASS; - break; - - case eT_HWTessellation: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_HW_TESSELLATION; - break; - - case eT_AlphaBlendShadows: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_ALPHABLENDSHADOWS; - break; - - case eT_SkinPass: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_SKINPASS; - break; - - case eT_EyeOverlay: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_EYE_OVERLAY; - break; - - case eT_VertexColors: - if (!ef) - { - break; - } - ef->m_Flags2 |= EF2_VERTEXCOLORS; - break; - - case eT_ShaderDrawType: - { - if (!ef) - { - break; - } - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_Light) - { - ef->m_eSHDType = eSHDT_Light; - } - else - if (eT == eT_Shadow) - { - ef->m_eSHDType = eSHDT_Shadow; - } - else - if (eT == eT_Fur) - { - ef->m_eSHDType = eSHDT_Fur; - } - else - if (eT == eT_General) - { - ef->m_eSHDType = eSHDT_General; - } - else - if (eT == eT_Terrain) - { - ef->m_eSHDType = eSHDT_Terrain; - } - else - if (eT == eT_Overlay) - { - ef->m_eSHDType = eSHDT_Overlay; - } - else - if (eT == eT_NoDraw) - { - ef->m_eSHDType = eSHDT_NoDraw; - ef->m_Flags |= EF_NODRAW; - } - else - if (eT == eT_Custom) - { - ef->m_eSHDType = eSHDT_CustomDraw; - } - else - if (eT == eT_Sky) - { - ef->m_eSHDType = eSHDT_Sky; - ef->m_Flags |= EF_SKY; - } - else - if (eT == eT_OceanShore) - { - ef->m_eSHDType = eSHDT_OceanShore; - } - else - { - Warning("Unknown shader draw type '%s'", Parser.GetString(eT)); - CRY_ASSERT(0); - } - } - break; - - case eT_ShaderType: - { - if (!ef) - { - break; - } - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_General) - { - ef->m_eShaderType = eST_General; - } - else - if (eT == eT_Metal) - { - ef->m_eShaderType = eST_Metal; - } - else - if (eT == eT_Ice) - { - ef->m_eShaderType = eST_Ice; - } - else - if (eT == eT_Shadow) - { - ef->m_eShaderType = eST_Shadow; - } - else - if (eT == eT_Water) - { - ef->m_eShaderType = eST_Water; - } - else - if (eT == eT_FX) - { - ef->m_eShaderType = eST_FX; - } - else - if (eT == eT_PostProcess) - { - ef->m_eShaderType = eST_PostProcess; - } - else - if (eT == eT_HDR) - { - ef->m_eShaderType = eST_HDR; - } - else - if (eT == eT_Sky) - { - ef->m_eShaderType = eST_Sky; - } - else - if (eT == eT_Glass) - { - ef->m_eShaderType = eST_Glass; - } - else - if (eT == eT_Vegetation) - { - // Do nothing here - } - else - if (eT == eT_Particle) - { - // Do nothing here - } - else - if (eT == eT_Terrain) - { - //Do nothing here - } - else - if (eT == eT_Compute) - { - ef->m_eShaderType = eST_Compute; - } - else - { - Warning("Unknown shader type '%s'", Parser.GetString(eT)); - CRY_ASSERT(0); - } - } - break; - - case eT_PreprType: - { - if (!ef) - { - break; - } - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_GenerateSprites) - { - ; // We can't get of the token without cleaning out all the content but we can make it not do anything; - } - else - if (eT == eT_GenerateClouds) - { - ef->m_Flags2 |= EF2_PREPR_GENCLOUDS; - } - else - if (eT == eT_ScanWater) - { - ef->m_Flags2 |= EF2_PREPR_SCANWATER; - } - else - { - Warning("Unknown preprocess type '%s'", Parser.GetString(eT)); - CRY_ASSERT(0); - } - } - break; - - case eT_Cull: - { - if (!ef) - { - break; - } - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_None || eT == eT_NONE) - { - ef->m_eCull = eCULL_None; - } - else - if (eT == eT_CCW || eT == eT_Back) - { - ef->m_eCull = eCULL_Back; - } - else - if (eT == eT_CW || eT == eT_Front) - { - ef->m_eCull = eCULL_Front; - } - else - { - CRY_ASSERT(0); - } - } - break; - - default: - CRY_ASSERT(0); - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Global(CParserBin& Parser, SParserFrame& Frame, bool* bPublic, CCryNameR techStart[2]) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(string) - FX_END_TOKENS - - int nIndex; - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_string: - { - eT = Parser.GetToken(Parser.m_Name); - CRY_ASSERT(eT == eT_Script); - bRes &= ParseBinFX_Global_Annotations(Parser, Parser.m_Data, bPublic, techStart); - } - break; - - default: - CRY_ASSERT(0); - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -static int sGetTAddress(uint32 nToken) -{ - switch (nToken) - { - case eT_Clamp: - return TADDR_CLAMP; - case eT_Border: - return TADDR_BORDER; - case eT_Wrap: - return TADDR_WRAP; - case eT_Mirror: - return TADDR_MIRROR; - default: - CRY_ASSERT(0); - } - return -1; -} - -void STexSamplerFX::PostLoad() -{ - SHRenderTarget* pRt = m_pTarget; - if (!pRt) - { - return; - } - if (!_strnicmp(m_szTexture.c_str(), "$RT_2D", 6)) - { - if (pRt->m_nIDInPool >= 0) - { - if ((int)CTexture::s_CustomRT_2D->Num() <= pRt->m_nIDInPool) - { - CTexture::s_CustomRT_2D->Expand(pRt->m_nIDInPool + 1); - } - } - pRt->m_pTarget[0] = CTexture::s_ptexRT_2D; - } -} - -bool CShaderManBin::ParseBinFX_Sampler_Annotations_Script(CParserBin& Parser, SParserFrame& Frame, STexSamplerFX* pSampler) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(RenderOrder) - FX_TOKEN(ProcessOrder) - FX_TOKEN(RenderCamera) - FX_TOKEN(RenderType) - FX_TOKEN(RenderFilter) - FX_TOKEN(RenderColorTarget1) - FX_TOKEN(RenderDepthStencilTarget) - FX_TOKEN(ClearSetColor) - FX_TOKEN(ClearSetDepth) - FX_TOKEN(ClearTarget) - FX_TOKEN(RenderTarget_IDPool) - FX_TOKEN(RenderTarget_UpdateType) - FX_TOKEN(RenderTarget_Width) - FX_TOKEN(RenderTarget_Height) - FX_TOKEN(GenerateMips) - FX_END_TOKENS - - SHRenderTarget * pRt = new SHRenderTarget; - int nIndex; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_RenderOrder: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_PreProcess) - { - pRt->m_eOrder = eRO_PreProcess; - } - else - if (eT == eT_PostProcess) - { - pRt->m_eOrder = eRO_PostProcess; - } - else - if (eT == eT_PreDraw) - { - pRt->m_eOrder = eRO_PreDraw; - } - else - { - CRY_ASSERT(0); - Warning("Unknown RenderOrder type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_ProcessOrder: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_WaterReflection) - { - pRt->m_nProcessFlags = FSPR_SCANTEXWATER; - } - else - { - CRY_ASSERT(0); - Warning("Unknown ProcessOrder type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_RenderCamera: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_WaterPlaneReflected) - { - pRt->m_nFlags |= FRT_CAMERA_REFLECTED_WATERPLANE; - } - else - if (eT == eT_PlaneReflected) - { - pRt->m_nFlags |= FRT_CAMERA_REFLECTED_PLANE; - } - else - if (eT == eT_Current) - { - pRt->m_nFlags |= FRT_CAMERA_CURRENT; - } - else - { - CRY_ASSERT(0); - Warning("Unknown RenderCamera type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_GenerateMips: - pRt->m_nFlags |= FRT_GENERATE_MIPS; - break; - - case eT_RenderType: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_CurObject) - { - pRt->m_nFlags |= FRT_RENDTYPE_CUROBJECT; - } - else - if (eT == eT_CurScene) - { - pRt->m_nFlags |= FRT_RENDTYPE_CURSCENE; - } - else - if (eT == eT_RecursiveScene) - { - pRt->m_nFlags |= FRT_RENDTYPE_RECURSIVECURSCENE; - } - else - if (eT == eT_CopyScene) - { - pRt->m_nFlags |= FRT_RENDTYPE_COPYSCENE; - } - else - { - CRY_ASSERT(0); - Warning("Unknown RenderType type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_RenderFilter: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_Refractive) - { - pRt->m_nFilterFlags |= FRF_REFRACTIVE; - } - else - if (eT == eT_Heat) - { - pRt->m_nFilterFlags |= FRF_HEAT; - } - else - { - CRY_ASSERT(0); - Warning("Unknown RenderFilter type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_RenderDepthStencilTarget: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_DepthBuffer || eT == eT_DepthBufferTemp) - { - pRt->m_bTempDepth = true; - } - else - if (eT == eT_DepthBufferOrig) - { - pRt->m_bTempDepth = false; - } - else - { - CRY_ASSERT(0); - Warning("Unknown RenderDepthStencilTarget type '%s'", Parser.GetString(eT)); - } - } - break; - - case eT_RenderTarget_IDPool: - pRt->m_nIDInPool = Parser.GetInt(Parser.GetToken(Parser.m_Data)); - CRY_ASSERT(pRt->m_nIDInPool >= 0 && pRt->m_nIDInPool < 64); - break; - - case eT_RenderTarget_Width: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_$ScreenSize) - { - pRt->m_nWidth = -1; - } - else - { - pRt->m_nWidth = Parser.GetInt(eT); - } - } - break; - - case eT_RenderTarget_Height: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_$ScreenSize) - { - pRt->m_nHeight = -1; - } - else - { - pRt->m_nHeight = Parser.GetInt(eT); - } - } - break; - - case eT_RenderTarget_UpdateType: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_WaterReflect) - { - pRt->m_eUpdateType = eRTUpdate_WaterReflect; - } - else - if (eT == eT_Allways) - { - pRt->m_eUpdateType = eRTUpdate_Always; - } - else - { - CRY_ASSERT(0); - } - } - break; - - case eT_ClearSetColor: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_FogColor) - { - pRt->m_nFlags |= FRT_CLEAR_FOGCOLOR; - } - else - { - string sStr = Parser.GetString(Parser.m_Data); - shGetColor(sStr.c_str(), pRt->m_ClearColor); - } - } - break; - - case eT_ClearSetDepth: - pRt->m_fClearDepth = Parser.GetFloat(Parser.m_Data); - break; - - case eT_ClearTarget: - { - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_Color) - { - pRt->m_nFlags |= FRT_CLEAR_COLOR; - } - else - if (eT == eT_Depth) - { - pRt->m_nFlags |= FRT_CLEAR_DEPTH; - } - else - { - CRY_ASSERT(0); - Warning("Unknown ClearTarget type '%s'", Parser.GetString(eT)); - } - } - break; - - default: - CRY_ASSERT(0); - } - } - if (pRt->m_eOrder == eRO_PreProcess) - { - Parser.m_pCurShader->m_Flags |= EF_PRECACHESHADER; - } - pSampler->m_pTarget = pRt; - pSampler->PostLoad(); - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Sampler_Annotations(CParserBin& Parser, SParserFrame& Annotations, STexSamplerFX* pSampler) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Annotations); - - FX_BEGIN_TOKENS - FX_TOKEN(string) - FX_END_TOKENS - - int nIndex = 0; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - SCodeFragment Fr; - switch (eT) - { - case eT_string: - { - eT = Parser.GetToken(Parser.m_Name); - CRY_ASSERT(eT == eT_Script); - bRes &= ParseBinFX_Sampler_Annotations_Script(Parser, Parser.m_Data, pSampler); - } - break; - - default: - CRY_ASSERT(0); - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Sampler(CParserBin& Parser, SParserFrame& Frame, uint32 dwName, SParserFrame Annotations, EToken samplerType) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(string) - FX_TOKEN(Texture) - FX_TOKEN(MinFilter) - FX_TOKEN(MagFilter) - FX_TOKEN(MipFilter) - FX_TOKEN(AddressU) - FX_TOKEN(AddressV) - FX_TOKEN(AddressW) - FX_TOKEN(BorderColor) - FX_TOKEN(AnisotropyLevel) - FX_TOKEN(sRGBLookup) - FX_TOKEN(Global) - FX_END_TOKENS - - STexSamplerFX samp; - STexState ST; - DWORD dwBorderColor = 0; - uint32 nFilter = 0; - uint32 nFiltMin = 0; - uint32 nFiltMip = 0; - uint32 nFiltMag = 0; - uint32 nAddressU = 0; - uint32 nAddressV = 0; - uint32 nAddressW = 0; - uint32 nAnisotropyLevel = 0; - - int nIndex = -1; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_string: - { - eT = Parser.GetToken(Parser.m_Name); - - SParserFrame stringData = Parser.m_Data; - - // string could have ""s still, if so trim them off. - if (Parser.GetToken(stringData) == eT_quote) - { - stringData.m_nFirstToken++; - stringData.m_nLastToken--; - } - -#if SHADER_REFLECT_TEXTURE_SLOTS - if (eT == eT_UIName) - { - samp.m_szUIName = Parser.GetString(stringData); - } - else if (eT == eT_UIDescription) - { - samp.m_szUIDescription = Parser.GetString(stringData); - } -#endif - } - break; - - case eT_Texture: - samp.m_szTexture = Parser.GetString(Parser.m_Data); - break; - - case eT_BorderColor: - { - string Str = Parser.GetString(Parser.m_Data); - ColorF colBorder = Col_Black; - shGetColor(Str.c_str(), colBorder); - dwBorderColor = colBorder.pack_argb8888(); - ST.m_bActive = true; - } - break; - - case eT_sRGBLookup: - ST.m_bSRGBLookup = Parser.GetBool(Parser.m_Data); - break; - - case eT_Global: - break; - - case eT_AnisotropyLevel: - nAnisotropyLevel = Parser.GetToken(Parser.m_Data); - break; - - case eT_Filter: - nFilter = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_MinFilter: - nFiltMin = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_MagFilter: - nFiltMag = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_MipFilter: - nFiltMip = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_AddressU: - nAddressU = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - case eT_AddressV: - nAddressV = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - case eT_AddressW: - nAddressW = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - - default: - CRY_ASSERT(0); - } - } - - samp.m_szName = Parser.GetString(dwName); - if (nFilter > 0) - { - switch (nFilter) - { - case eT_MIN_MAG_MIP_POINT: - ST.SetFilterMode(FILTER_POINT); - break; - case eT_MIN_MAG_MIP_LINEAR: - ST.SetFilterMode(FILTER_TRILINEAR); - break; - case eT_MIN_MAG_LINEAR_MIP_POINT: - ST.SetFilterMode(FILTER_BILINEAR); - break; - case eT_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: - ST.SetFilterMode(FILTER_BILINEAR); - ST.SetComparisonFilter(true); - break; - default: - { - assert(0); - } - break; - } - } - - if (nFiltMag > 0 && nFiltMin > 0 && nFiltMip > 0) - { - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_LINEAR) - { - ST.SetFilterMode(FILTER_TRILINEAR); - } - else - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_POINT) - { - ST.SetFilterMode(FILTER_BILINEAR); - } - else - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_NONE) - { - ST.SetFilterMode(FILTER_LINEAR); - } - else - if (nFiltMag == eT_POINT && nFiltMin == eT_POINT && nFiltMip == eT_POINT) - { - ST.SetFilterMode(FILTER_POINT); - } - else - if (nFiltMag == eT_POINT && nFiltMin == eT_POINT && nFiltMip == eT_NONE) - { - ST.SetFilterMode(FILTER_NONE); - } - else - if (nFiltMag == eT_ANISOTROPIC || nFiltMin == eT_ANISOTROPIC) - { - if (nAnisotropyLevel == eT_0 + 4) - { - ST.SetFilterMode(FILTER_ANISO4X); - } - else - if (nAnisotropyLevel == eT_0 + 8) - { - ST.SetFilterMode(FILTER_ANISO8X); - } - else - if (nAnisotropyLevel == eT_0 + 16) - { - ST.SetFilterMode(FILTER_ANISO16X); - } - else - { - ST.SetFilterMode(FILTER_ANISO2X); - } - } - else - { - Warning("!Unknown sampler filter mode (Min=%s, Mag=%s, Mip=%s) for sampler '%s'", Parser.GetString(nFiltMin), Parser.GetString(nFiltMag), Parser.GetString(nFiltMip), samp.m_szName.c_str()); - CRY_ASSERT(0); - } - } - else - { - ST.SetFilterMode(-1); - } - - ST.SetClampMode(nAddressU, nAddressV, nAddressW); - ST.SetBorderColor(dwBorderColor); - - samp.m_nTexState = CTexture::GetTexState(ST); - samp.m_nSlotId = m_pCEF->mfCheckTextureSlotName(samp.m_szTexture); - - if (!Annotations.IsEmpty()) - { - bRes &= ParseBinFX_Sampler_Annotations(Parser, Annotations, &samp); - } - - switch (samplerType) - { - case eT_sampler1D: - samp.m_eTexType = eTT_1D; - break; - case eT_sampler2D: - case eT_Texture2D: - samp.m_eTexType = eTT_2D; - break; - case eT_Texture2DArray: - samp.m_eTexType = eTT_2DArray; - break; - case eT_Texture2DMS: - samp.m_eTexType = eTT_2DMS; - break; - case eT_sampler3D: - case eT_Texture3D: - samp.m_eTexType = eTT_3D; - break; - case eT_samplerCUBE: - case eT_TextureCube: - samp.m_eTexType = eTT_Cube; - break; - case eT_TextureCubeArray: - samp.m_eTexType = eTT_CubeArray; - break; - default: -#if !defined(_RELEASE) - __debugbreak(); -#endif - samp.m_eTexType = eTT_2D; - break; - } - - mfAddFXSampler(Parser.m_pCurShader, &samp); - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Sampler(CParserBin& Parser, SParserFrame& Frame, SFXSampler& Sampl) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(string) - FX_TOKEN(Filter) - FX_TOKEN(MinFilter) - FX_TOKEN(MagFilter) - FX_TOKEN(MipFilter) - FX_TOKEN(AddressU) - FX_TOKEN(AddressV) - FX_TOKEN(AddressW) - FX_TOKEN(BorderColor) - FX_TOKEN(AnisotropyLevel) - FX_TOKEN(sRGBLookup) - FX_TOKEN(Global) - FX_END_TOKENS - - STexState ST; - DWORD dwBorderColor = 0; - uint32 nFilter = 0; - uint32 nFiltMin = 0; - uint32 nFiltMip = 0; - uint32 nFiltMag = 0; - uint32 nAddressU = 0; - uint32 nAddressV = 0; - uint32 nAddressW = 0; - uint32 nAnisotropyLevel = 0; - - int nIndex = -1; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_BorderColor: - { - string Str = Parser.GetString(Parser.m_Data); - ColorF colBorder = Col_Black; - shGetColor(Str.c_str(), colBorder); - dwBorderColor = colBorder.pack_argb8888(); - ST.m_bActive = true; - } - break; - - case eT_sRGBLookup: - ST.m_bSRGBLookup = Parser.GetBool(Parser.m_Data); - break; - - case eT_AnisotropyLevel: - nAnisotropyLevel = Parser.GetToken(Parser.m_Data); - break; - - case eT_Filter: - nFilter = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - - case eT_MinFilter: - nFiltMin = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_MagFilter: - nFiltMag = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_MipFilter: - nFiltMip = Parser.GetToken(Parser.m_Data); - ST.m_bActive = true; - break; - case eT_AddressU: - nAddressU = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - case eT_AddressV: - nAddressV = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - case eT_AddressW: - nAddressW = sGetTAddress(Parser.GetToken(Parser.m_Data)); - ST.m_bActive = true; - break; - - default: - CRY_ASSERT(0); - } - } - - if (nFilter > 0) - { - switch (nFilter) - { - case eT_MIN_MAG_MIP_POINT: - ST.SetFilterMode(FILTER_POINT); - break; - case eT_MIN_MAG_LINEAR_MIP_POINT: - ST.SetFilterMode(FILTER_BILINEAR); - break; - case eT_MIN_MAG_MIP_LINEAR: - ST.SetFilterMode(FILTER_TRILINEAR); - break; - case eT_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: - ST.SetFilterMode(FILTER_BILINEAR); - ST.SetComparisonFilter(true); - break; - default: - { - CRY_ASSERT(0); - } - break; - } - } - if (nFiltMag > 0 && nFiltMin > 0 && nFiltMip > 0) - { - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_LINEAR) - { - ST.SetFilterMode(FILTER_TRILINEAR); - } - else - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_POINT) - { - ST.SetFilterMode(FILTER_BILINEAR); - } - else - if (nFiltMag == eT_LINEAR && nFiltMin == eT_LINEAR && nFiltMip == eT_NONE) - { - ST.SetFilterMode(FILTER_LINEAR); - } - else - if (nFiltMag == eT_POINT && nFiltMin == eT_POINT && nFiltMip == eT_POINT) - { - ST.SetFilterMode(FILTER_POINT); - } - else - if (nFiltMag == eT_POINT && nFiltMin == eT_POINT && nFiltMip == eT_NONE) - { - ST.SetFilterMode(FILTER_NONE); - } - else - if (nFiltMag == eT_ANISOTROPIC || nFiltMin == eT_ANISOTROPIC) - { - if (nAnisotropyLevel == eT_0 + 4) - { - ST.SetFilterMode(FILTER_ANISO4X); - } - else - if (nAnisotropyLevel == eT_0 + 8) - { - ST.SetFilterMode(FILTER_ANISO8X); - } - else - if (nAnisotropyLevel == eT_0 + 16) - { - ST.SetFilterMode(FILTER_ANISO16X); - } - else - { - ST.SetFilterMode(FILTER_ANISO2X); - } - } - else - { - Warning("!Unknown sampler filter mode (Min=%s, Mag=%s, Mip=%s) for sampler '%s'", Parser.GetString(nFiltMin), Parser.GetString(nFiltMag), Parser.GetString(nFiltMip), Sampl.m_Name.c_str()); - CRY_ASSERT(0); - } - } - else - { - ST.SetFilterMode(-1); - } - - if (ST.m_bActive) - { - ST.SetClampMode(nAddressU, nAddressV, nAddressW); - ST.SetBorderColor(dwBorderColor); - - Sampl.m_nTexState = CTexture::GetTexState(ST); - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Texture(CParserBin& Parser, SParserFrame& Frame, SFXTexture& Tex) -{ - bool bRes = true; - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(Texture) - FX_TOKEN(UIName) - FX_TOKEN(UIDescription) - FX_TOKEN(sRGBLookup) - FX_TOKEN(Global) - FX_TOKEN(slot) - FX_TOKEN(vsslot) - FX_TOKEN(psslot) - FX_TOKEN(hsslot) - FX_TOKEN(dsslot) - FX_TOKEN(gsslot) - FX_TOKEN(csslot) - FX_END_TOKENS - - int nIndex = -1; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_Texture: - { - Tex.m_szTexture = Parser.GetString(Parser.m_Data); - } - break; - case eT_UIName: - { - if (Parser.GetToken(Parser.m_Data) == eT_quote) - { - Parser.m_Data.m_nFirstToken++; - Parser.m_Data.m_nLastToken--; - } - Tex.m_szUIName = Parser.GetString(Parser.m_Data); - } - break; - case eT_UIDescription: - { - if (Parser.GetToken(Parser.m_Data) == eT_quote) - { - Parser.m_Data.m_nFirstToken++; - Parser.m_Data.m_nLastToken--; - } - Tex.m_szUIDesc = Parser.GetString(Parser.m_Data); - } - break; - - case eT_sRGBLookup: - Tex.m_bSRGBLookup = Parser.GetBool(Parser.m_Data); - break; - - case eT_Global: - Tex.m_nFlags |= PF_GLOBAL; - break; - - case eT_slot: - case eT_vsslot: - case eT_psslot: - case eT_hsslot: - case eT_dsslot: - case eT_gsslot: - case eT_csslot: - break; - - default: - CRY_ASSERT(0); - } - } - - - Parser.EndFrame(OldFrame); - - return bRes; -} - -void CShaderManBin::AddAffectedParameter(CParserBin& Parser, std::vector& AffectedParams, TArray& AffectedFunc, SFXParam* pParam, EHWShaderClass eSHClass, [[maybe_unused]] uint32 dwType, SShaderTechnique* pShTech) -{ - static uint32 eT_ShadowGen[] = {CParserBin::GetCRC32("ShadowGenVS"), CParserBin::GetCRC32("ShadowGenPS"), CParserBin::GetCRC32("ShadowGenGS")}; - if (!CParserBin::PlatformSupportsConstantBuffers()) - { - //if (pParam->m_Name.c_str()[0] != '_') - { - if (!(Parser.m_pCurShader->m_Flags & EF_LOCALCONSTANTS)) - { - if (pParam->m_Register[eSHClass] >= 0 && pParam->m_Register[eSHClass] < 10000) - { - if ((pShTech->m_Flags & FHF_NOLIGHTS) && pParam->m_BindingSlot == eConstantBufferShaderSlot_PerMaterial && !(pParam->m_nFlags & PF_TWEAKABLE_MASK)) - { - return; - } - if (pParam->m_Semantic.empty() && pParam->m_Values.c_str()[0] == '(') - { - pParam->m_BindingSlot = eConstantBufferShaderSlot_PerMaterial; - } - AffectedParams.push_back(*pParam); - return; - } - } - } - } - else - if (pParam->m_BindingSlot == eConstantBufferShaderSlot_PerMaterial) - { - if (pParam->m_Register[eSHClass] < 0 || pParam->m_Register[eSHClass] >= 1000) - { - return; - } - } - - int nFlags = pParam->GetFlags(); - bool bCheckAffect = CParserBin::m_bParseFX ? true : false; - - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_GLES3 || CParserBin::m_nPlatform == SF_METAL) - { - CRY_ASSERT(eSHClass < eHWSC_Num); - if (((nFlags & PF_TWEAKABLE_MASK) || pParam->m_Values.c_str()[0] == '(') && pParam->m_Register[eSHClass] >= 0 && pParam->m_Register[eSHClass] < 1000) - { - bCheckAffect = false; - } - } - for (uint32 j = 0; j < AffectedFunc.size(); j++) - { - SCodeFragment* pCF = &Parser.m_CodeFragments[AffectedFunc[j]]; - if (!bCheckAffect || Parser.FindToken(pCF->m_nFirstToken, pCF->m_nLastToken, pParam->m_dwName[0]) >= 0) - { - AffectedParams.push_back(*pParam); - break; - } - } -} - -void CShaderManBin::InitShaderDependenciesList(CParserBin& Parser, SCodeFragment* pFunc, TArray& bChecked, TArray& AffectedFunc) -{ - uint32 i; - const uint32 numFrags = Parser.m_CodeFragments.size(); - - for (i = 0; i < numFrags; ++i) - { - if (bChecked[i]) - { - continue; - } - SCodeFragment* s = &Parser.m_CodeFragments[i]; - if (!s->m_dwName) - { - bChecked[i] = 1; - continue; - } - if (s->m_eType == eFT_Function || s->m_eType == eFT_StorageClass) - { - if (Parser.FindToken(pFunc->m_nFirstToken, pFunc->m_nLastToken, s->m_dwName) >= 0) - { - bChecked[i] = 1; - AffectedFunc.push_back(i); - InitShaderDependenciesList(Parser, s, bChecked, AffectedFunc); - } - } - } -} - -void CShaderManBin::AddAffectedSampler(CParserBin& Parser, std::vector& AffectedSamplers, TArray& AffectedFunc, SFXSampler* pSampler, [[maybe_unused]] EHWShaderClass eSHClass, [[maybe_unused]] uint32 dwType, [[maybe_unused]] SShaderTechnique* pShTech) -{ - for (uint32 j = 0; j < AffectedFunc.size(); j++) - { - SCodeFragment* pCF = &Parser.m_CodeFragments[AffectedFunc[j]]; - if (Parser.FindToken(pCF->m_nFirstToken, pCF->m_nLastToken, pSampler->m_dwName[0]) >= 0) - { - AffectedSamplers.push_back(*pSampler); - break; - } - } -} -void CShaderManBin::AddAffectedTexture(CParserBin& Parser, std::vector& AffectedTextures, TArray& AffectedFunc, SFXTexture* pTexture, [[maybe_unused]] EHWShaderClass eSHClass, [[maybe_unused]] uint32 dwType, [[maybe_unused]] SShaderTechnique* pShTech) -{ - for (uint32 j = 0; j < AffectedFunc.size(); j++) - { - SCodeFragment* pCF = &Parser.m_CodeFragments[AffectedFunc[j]]; - if (Parser.FindToken(pCF->m_nFirstToken, pCF->m_nLastToken, pTexture->m_dwName[0]) >= 0) - { - AffectedTextures.push_back(*pTexture); - break; - } - } -} - -void CShaderManBin::CheckStructuresDependencies(CParserBin& Parser, SCodeFragment* pFrag, TArray& bChecked, TArray& AffectedFunc) -{ - uint32 i; - const uint32 numFrags = Parser.m_CodeFragments.size(); - - for (i = 0; i < numFrags; ++i) - { - if (bChecked[i]) - { - continue; - } - SCodeFragment* s = &Parser.m_CodeFragments[i]; - if (s->m_eType == eFT_Structure) - { - if (Parser.FindToken(pFrag->m_nFirstToken, pFrag->m_nLastToken, s->m_dwName) >= 0) - { - bChecked[i] = 1; - AffectedFunc.push_back(i); - CheckStructuresDependencies(Parser, s, bChecked, AffectedFunc); - } - } - } -} - -void CShaderManBin::CheckFragmentsDependencies(CParserBin& Parser, TArray& bChecked, TArray& AffectedFrags) -{ - uint32 i, j; - const uint32 numFuncs = AffectedFrags.size(); - const uint32 numFrags = Parser.m_CodeFragments.size(); - - for (i = 0; i < numFuncs; ++i) - { - int nFunc = AffectedFrags[i]; - SCodeFragment* pFunc = &Parser.m_CodeFragments[nFunc]; - for (j = 0; j < numFrags; j++) - { - SCodeFragment* s = &Parser.m_CodeFragments[j]; - if (bChecked[j]) - { - continue; - } - - if (s->m_eType == eFT_Sampler || s->m_eType == eFT_Structure) - { - if (Parser.FindToken(pFunc->m_nFirstToken, pFunc->m_nLastToken, s->m_dwName) >= 0) - { - bChecked[j] = 1; - AffectedFrags.push_back(j); - if (s->m_eType == eFT_Structure) - { - CheckStructuresDependencies(Parser, s, bChecked, AffectedFrags); - } - } - } - else if (s->m_eType == eFT_ConstBuffer) - { - // Make sure cbuffer declaration does not get stripped - bChecked[j] = 1; - AffectedFrags.push_back(j); - } - } - } -} - -//================================================================================================= - -struct SFXRegisterBin -{ - int nReg; - int nComp; - int m_nCB; - uint32 m_nFlags; - EParamType eType; - uint32 dwName; - CCryNameR m_Value; - SFXRegisterBin() - { - eType = eType_UNKNOWN; - m_nCB = -1; - } -}; - -struct SFXPackedName -{ - uint32 dwName[4]; - - SFXPackedName() - { - dwName[0] = dwName[1] = dwName[2] = dwName[3] = 0; - } -}; - -inline bool Compar(const SFXRegisterBin& a, const SFXRegisterBin& b) -{ - if (CParserBin::PlatformSupportsConstantBuffers()) - { - if (a.m_nCB != b.m_nCB) - { - return a.m_nCB < b.m_nCB; - } - } - if (a.nReg != b.nReg) - { - return a.nReg < b.nReg; - } - if (a.nComp != b.nComp) - { - return a.nComp < b.nComp; - } - return false; -} - -static void sFlushRegs(CParserBin& Parser, int nReg, SFXRegisterBin* MergedRegs[4], std::vector& NewParams, EHWShaderClass eSHClass, std::vector& PackedNames) -{ - NewParams.resize(NewParams.size() + 1); - PackedNames.resize(PackedNames.size() + 1); - SFXParam& p = NewParams[NewParams.size() - 1]; - SFXPackedName& pN = PackedNames[PackedNames.size() - 1]; - int nMaxComp = -1; - int j; - - int nCompMerged = 0; - EParamType eType = eType_UNKNOWN; - int nCB = -1; - for (j = 0; j < 4; j++) - { - if (MergedRegs[j] && MergedRegs[j]->eType != eType_UNKNOWN) - { - if (nCB == -1) - { - nCB = MergedRegs[j]->m_nCB; - } - else - if (nCB != MergedRegs[j]->m_nCB) - { - CRY_ASSERT(0); - } - if (eType == eType_UNKNOWN) - { - eType = MergedRegs[j]->eType; - } - else - if (eType != MergedRegs[j]->eType) - { - //CRY_ASSERT(0); - } - } - } - for (j = 0; j < 4; j++) - { - char s[16]; - sprintf_s(s, "__%d", j); - p.m_Name = stack_string(p.m_Name.c_str()) + s; - if (MergedRegs[j]) - { - if (MergedRegs[j]->m_nFlags & PF_TWEAKABLE_MASK) - { - p.m_nFlags |= (PF_TWEAKABLE_0 << j); - } - p.m_nFlags |= MergedRegs[j]->m_nFlags & ~(PF_TWEAKABLE_MASK | PF_SCALAR | PF_SINGLE_COMP | PF_MERGE_MASK); - nMaxComp = max(nMaxComp, j); - pN.dwName[j] = MergedRegs[j]->dwName; - if (nCompMerged) - { - p.m_Values = stack_string(p.m_Values.c_str()) += ", "; - } - p.m_Name = stack_string(p.m_Name.c_str()) + Parser.GetString(pN.dwName[j]); - p.m_Values = stack_string(p.m_Values.c_str()) + MergedRegs[j]->m_Value.c_str(); - nCompMerged++; - } - else - { - if (nCompMerged) - { - p.m_Values = stack_string(p.m_Values.c_str()) + ", "; - } - p.m_Values = stack_string(p.m_Values.c_str()) + "NULL"; - nCompMerged++; - } - } - p.m_ComponentCount = nMaxComp + 1; - if (eSHClass == eHWSC_Geometry && !CParserBin::PlatformSupportsGeometryShaders()) - { - return; - } - if (eSHClass == eHWSC_Domain && !CParserBin::PlatformSupportsDomainShaders()) - { - return; - } - if (eSHClass == eHWSC_Hull && !CParserBin::PlatformSupportsHullShaders()) - { - return; - } - if (eSHClass == eHWSC_Compute && !CParserBin::PlatformSupportsComputeShaders()) - { - return; - } - - // Get packed name token. - p.m_dwName.push_back(Parser.NewUserToken(eT_unknown, p.m_Name.c_str(), true)); //pass by crysting so that string references work. - CRY_ASSERT(eSHClass < eHWSC_Num); - p.m_Register[eSHClass] = nReg; - if (eSHClass == eHWSC_Domain || eSHClass == eHWSC_Hull || eSHClass == eHWSC_Compute) - { - p.m_Register[eHWSC_Vertex] = nReg; - } - p.m_RegisterCount = 1; - if (eType == eType_HALF) - { - eType = eType_FLOAT; - } - p.m_eType = eType; - CRY_ASSERT(eType != eType_UNKNOWN); - p.m_BindingSlot = nCB; - p.m_nFlags |= PF_AUTOMERGED; -} - -static EToken sCompToken[4] = {eT_x, eT_y, eT_z, eT_w}; -bool CShaderManBin::ParseBinFX_Technique_Pass_PackParameters (CParserBin& Parser, std::vector& AffectedParams, TArray& AffectedFunc, [[maybe_unused]] SCodeFragment* pFunc, EHWShaderClass eSHClass, uint32 dwSHName, std::vector& PackedParams, TArray& Replaces, TArray& NewTokens, TArray& bMerged) -{ - bool bRes = true; - - uint32 i, j; - - std::vector Registers; - std::vector PackedNames; - for (i = 0; i < AffectedParams.size(); i++) - { - SFXParam* pr = &AffectedParams[i]; - if (pr->m_Annotations.empty()) - { - continue; // Parameter doesn't have custom register definition - } - const char* src = strstr(pr->m_Annotations.c_str(), "register"); - if (src) - { - char* b = (char*)&src[8]; - SkipCharacters (&b, kWhiteSpace); - CRY_ASSERT(b[0] == '='); - b++; - SkipCharacters (&b, kWhiteSpace); - CRY_ASSERT(b[0] == 'c'); - if (b[0] == 'c') - { - int nReg = atoi(&b[1]); - b++; - while (*b != '.' && *b != ';') - { - if (*b == 0) // Vector without swizzling - { - break; - } - b++; - } - if (*b == '.') - { - bMerged[i] = 0xff; - b++; - int nComp = -1; - switch (b[0]) - { - case 'x': - case 'r': - nComp = 0; - break; - case 'y': - case 'g': - nComp = 1; - break; - case 'z': - case 'b': - nComp = 2; - break; - case 'w': - case 'a': - nComp = 3; - break; - default: - CRY_ASSERT(0); - } - if (nComp >= 0) - { - pr->m_nFlags |= PF_MERGE; - SFXRegisterBin rg; - rg.nReg = nReg; - rg.nComp = nComp; - rg.dwName = pr->m_dwName[0]; - rg.m_Value = pr->m_Values; - rg.m_nFlags = pr->m_nFlags; - rg.eType = (EParamType)pr->m_eType; - rg.m_nCB = pr->m_BindingSlot; - CRY_ASSERT(rg.m_Value.c_str()[0]); - Registers.push_back(rg); - } - } - } - } - } - if (Registers.empty()) - { - return false; - } - std::sort(Registers.begin(), Registers.end(), Compar); - int nReg = -1; - int nCB = -1; - SFXRegisterBin* MergedRegs[4]; - MergedRegs[0] = MergedRegs[1] = MergedRegs[2] = MergedRegs[3] = NULL; - for (i = 0; i < Registers.size(); i++) - { - SFXRegisterBin* rg = &Registers[i]; - if ((!CParserBin::PlatformSupportsConstantBuffers() && rg->nReg != nReg) || (CParserBin::PlatformSupportsConstantBuffers() && (rg->m_nCB != nCB || rg->nReg != nReg))) - { - if (nReg >= 0) - { - sFlushRegs(Parser, nReg, MergedRegs, PackedParams, eSHClass, PackedNames); - } - nReg = rg->nReg; - nCB = rg->m_nCB; - MergedRegs[0] = MergedRegs[1] = MergedRegs[2] = MergedRegs[3] = NULL; - } - CRY_ASSERT(!MergedRegs[rg->nComp]); - if (MergedRegs[rg->nComp]) - { - Warning("register c%d (comp: %d) is used by the %s shader '%s' already", rg->nReg, rg->nComp, eSHClass == eHWSC_Pixel ? "pixel" : "vertex", Parser.GetString(dwSHName)); - CRY_ASSERT(0); - } - MergedRegs[rg->nComp] = rg; - } - if (MergedRegs[0] || MergedRegs[1] || MergedRegs[2] || MergedRegs[3]) - { - sFlushRegs(Parser, nReg, MergedRegs, PackedParams, eSHClass, PackedNames); - } - - // Replace new parameters in shader tokens - for (uint32 n = 0; n < AffectedFunc.size(); n++) - { - SCodeFragment* st = &Parser.m_CodeFragments[AffectedFunc[n]]; - //const char *szName = Parser.GetString(st->m_dwName); - - for (i = 0; i < PackedParams.size(); i++) - { - SFXParam* pr = &PackedParams[i]; - SFXPackedName* pn = &PackedNames[i]; - for (j = 0; j < 4; j++) - { - uint32 nP = pn->dwName[j]; - if (nP == 0) - { - continue; - } - int32 nPos = st->m_nFirstToken; - while (true) - { - nPos = Parser.FindToken(nPos, st->m_nLastToken, nP); - if (nPos < 0) - { - break; - } - SCodeFragment Fr; - Fr.m_nFirstToken = Fr.m_nLastToken = nPos; - Fr.m_dwName = n; - Replaces.push_back(Fr); - - Fr.m_nFirstToken = NewTokens.size(); - NewTokens.push_back(pr->m_dwName[0]); - NewTokens.push_back(eT_dot); - NewTokens.push_back(sCompToken[j]); - Fr.m_nLastToken = NewTokens.size() - 1; - Replaces.push_back(Fr); - nPos++; - } - } - } - } - - for (i = 0; i < Replaces.size(); i += 2) - { - SCodeFragment* pFR1 = &Replaces[i]; - for (j = i + 2; j < Replaces.size(); j += 2) - { - SCodeFragment* pFR2 = &Replaces[j]; - if (pFR1->m_dwName != pFR2->m_dwName) - { - continue; - } - if (pFR2->m_nFirstToken < pFR1->m_nFirstToken) - { - std::swap(Replaces[i], Replaces[j]); - std::swap(Replaces[i + 1], Replaces[j + 1]); - } - } - } - - return bRes; -} - -//=================================================================================================== - -void CShaderManBin::AddParameterToScript(CParserBin& Parser, SFXParam* pr, PodArray& SHData, EHWShaderClass eSHClass, int nCB) -{ - char str[256]; - int nReg = pr->m_Register[eSHClass]; - if (pr->m_eType == eType_BOOL) - { - SHData.push_back(eT_bool); - } - else - if (pr->m_eType == eType_INT) - { - SHData.push_back(eT_int); - } - else - { - int nVal = pr->m_RegisterCount * 4 + pr->m_ComponentCount; - EToken eT = eT_unknown; - switch (nVal) - { - case 4 + 1: - eT = (pr->m_eType == eType_FLOAT) ? eT_float : eT_half; - break; - case 4 + 2: - //eT = eT_float2; - eT = (pr->m_eType == eType_FLOAT) ? eT_float2 : eT_half2; - break; - case 4 + 3: - //eT = eT_float3; - eT = (pr->m_eType == eType_FLOAT) ? eT_float3 : eT_half3; - break; - case 4 + 4: - //eT = eT_float4; - eT = (pr->m_eType == eType_FLOAT) ? eT_float4 : eT_half4; - break; - case 2 * 4 + 4: - //eT = eT_float2x4; - eT = (pr->m_eType == eType_FLOAT) ? eT_float2x4 : eT_half2x4; - break; - case 3 * 4 + 4: - //eT = eT_float3x4; - eT = (pr->m_eType == eType_FLOAT) ? eT_float3x4 : eT_half3x4; - break; - case 4 * 4 + 4: - //eT = eT_float4x4; - eT = (pr->m_eType == eType_FLOAT) ? eT_float4x4 : eT_half4x4; - break; - case 3 * 4 + 3: - //eT = eT_float3x3; - eT = (pr->m_eType == eType_FLOAT) ? eT_float3x3 : eT_half3x3; - break; - } - CRY_ASSERT(eT != eT_unknown); - if (eT == eT_unknown) - { - return; - } - SHData.push_back(eT); - } - for (uint32 i = 0; i < pr->m_dwName.size(); i++) - { - SHData.push_back(pr->m_dwName[i]); - } - - if (nReg >= 0 && nReg < 10000) - { - SHData.push_back(eT_colon); - if (nCB == eConstantBufferShaderSlot_PerMaterial) - { - SHData.push_back(eT_packoffset); - } - else - { - SHData.push_back(eT_register); - } - SHData.push_back(eT_br_rnd_1); - sprintf_s(str, "c%d", nReg); - SHData.push_back(Parser.NewUserToken(eT_unknown, str, true)); - SHData.push_back(eT_br_rnd_2); - } - SHData.push_back(eT_semicolumn); -} - -void CShaderManBin::AddSamplerToScript(CParserBin& Parser, SFXSampler* pr, PodArray& SHData, EHWShaderClass eSHClass) -{ - char str[256]; - int nReg = pr->m_Register[eSHClass]; - if (pr->m_eType == eSType_Sampler) - { - SHData.push_back(eT_SamplerState); - } - else - if (pr->m_eType == eSType_SamplerComp) - { - SHData.push_back(eT_SamplerComparisonState); - } - else - { - CRY_ASSERT(0); - } - for (uint32 i = 0; i < pr->m_dwName.size(); i++) - { - SHData.push_back(pr->m_dwName[i]); - } - - if (nReg >= 0 && nReg < 10000) - { - SHData.push_back(eT_colon); - SHData.push_back(eT_register); - SHData.push_back(eT_br_rnd_1); - azsprintf(str, "s%d", nReg); - SHData.push_back(Parser.NewUserToken(eT_unknown, str, true)); - SHData.push_back(eT_br_rnd_2); - } - SHData.push_back(eT_semicolumn); -} -void CShaderManBin::AddTextureToScript(CParserBin& Parser, SFXTexture* pr, PodArray& SHData, EHWShaderClass eSHClass) -{ - char str[256]; - int nReg = pr->m_Register[eSHClass]; - if (pr->m_eType == eTT_2D) - { - SHData.push_back(eT_Texture2D); - } - else - if (pr->m_eType == eTT_3D) - { - SHData.push_back(eT_Texture3D); - } - else - if (pr->m_eType == eTT_2DArray) - { - SHData.push_back(eT_Texture2DArray); - } - else - if (pr->m_eType == eTT_2DMS) - { - SHData.push_back(eT_Texture2DMS); - } - else - if (pr->m_eType == eTT_Cube) - { - SHData.push_back(eT_TextureCube); - } - else - if (pr->m_eType == eTT_CubeArray) - { - SHData.push_back(eT_TextureCubeArray); - } - else - { - CRY_ASSERT(0); - } - if (pr->m_Type != eT_unknown) - { - SHData.push_back(eT_br_tr_1); - SHData.push_back(pr->m_Type); - SHData.push_back(eT_br_tr_2); - } - for (uint32 i = 0; i < pr->m_dwName.size(); i++) - { - SHData.push_back(pr->m_dwName[i]); - } - - if (nReg >= 0 && nReg < 10000) - { - SHData.push_back(eT_colon); - SHData.push_back(eT_register); - SHData.push_back(eT_br_rnd_1); - azsprintf(str, "t%d", nReg); - SHData.push_back(Parser.NewUserToken(eT_unknown, str, true)); - SHData.push_back(eT_br_rnd_2); - } - SHData.push_back(eT_semicolumn); -} - -static EToken GeneratedConstantBufferNames[] = { eT_PER_BATCH, eT_PER_INSTANCE, eT_PER_MATERIAL }; - -bool CShaderManBin::ParseBinFX_Technique_Pass_GenerateShaderData(CParserBin& Parser, FXMacroBin& Macros, SShaderFXParams& FXParams, uint32 dwSHName, EHWShaderClass eSHClass, uint64& nAffectMask, uint32 dwSHType, PodArray& SHData, SShaderTechnique* pShTech) -{ - LOADING_TIME_PROFILE_SECTION(iSystem); - CRY_ASSERT(gRenDev->m_pRT->IsRenderThread()); - - bool bRes = true; - - std::vector AffectedParams; - std::vector AffectedSamplers; - std::vector AffectedTextures; - - uint32 i, j; - uint32 nNum; - static TArray AffectedFragments; - AffectedFragments.reserve(120); - AffectedFragments.SetUse(0); - - for (nNum = 0; nNum < Parser.m_CodeFragments.size(); nNum++) - { - if (dwSHName == Parser.m_CodeFragments[nNum].m_dwName) - { - break; - } - } - if (nNum == Parser.m_CodeFragments.size()) - { - AZ_Assert(false, "Couldn't find entry function '%s'", Parser.GetString(dwSHName)); - return false; - } - - SCodeFragment* pFunc = &Parser.m_CodeFragments[nNum]; - SShaderBin* pBin = Parser.m_pCurBinShader; - SParamCacheInfo* pCache = GetParamInfo(pBin, pFunc->m_dwName, Parser.m_pCurShader->m_nMaskGenFX, Parser.m_pCurShader->m_maskGenStatic); - if (pCache) - { - AffectedFragments.SetUse(0); - AffectedFragments.reserve(pCache->m_AffectedFuncs.size()); - if (pCache->m_AffectedFuncs.empty() == false) - { - AffectedFragments.Copy(&pCache->m_AffectedFuncs[0], pCache->m_AffectedFuncs.size()); - } - } - else - { - AffectedFragments.push_back(nNum); - if (CParserBin::m_bParseFX) - { - TArray bChecked; - bChecked.resize(Parser.m_CodeFragments.size()); - if (bChecked.size() > 0) - { - memset(&bChecked[0], 0, sizeof(byte) * bChecked.size()); - } - bChecked[nNum] = 1; - InitShaderDependenciesList(Parser, pFunc, bChecked, AffectedFragments); - CheckFragmentsDependencies(Parser, bChecked, AffectedFragments); - } - else - { - for (i = 0; i < Parser.m_CodeFragments.size(); i++) - { - if (i != nNum) - { - AffectedFragments.push_back(i); - } - } - } - } - - nAffectMask = 0; - for (i = 0; i < AffectedFragments.size(); i++) - { - SCodeFragment* s = &Parser.m_CodeFragments[AffectedFragments[i]]; - if (s->m_eType != eFT_Function && s->m_eType != eFT_Structure && s->m_eType != eFT_ConstBuffer && s->m_eType != eFT_StorageClass) - { - continue; - } - FXMacroBinItor itor; - for (itor = Macros.begin(); itor != Macros.end(); ++itor) - { - SMacroBinFX* pr = &itor->second; - if (!pr->m_nMask) - { - continue; - } - if ((pr->m_nMask & nAffectMask) == pr->m_nMask) - { - continue; - } - uint32 dwName = itor->first; - if (Parser.FindToken(s->m_nFirstToken, s->m_nLastToken, dwName) >= 0) - { - nAffectMask |= pr->m_nMask; - } - } - } - - // Generate list of params before first preprocessor pass for affected functions - TArray bMerged; - bMerged.Reserve(FXParams.m_FXParams.size()); - if (pCache) - { - for (i = 0; i < pCache->m_AffectedParams.size(); i++) - { - uint32 nParam = pCache->m_AffectedParams[i]; - FXParamsIt it = std::lower_bound(FXParams.m_FXParams.begin(), FXParams.m_FXParams.end(), nParam, FXParamsSortByName()); - if (it != FXParams.m_FXParams.end() && nParam == (*it).m_dwName[0]) - { - SFXParam& pr = (*it); - if (!(pr.GetFlags() & PF_AUTOMERGED)) - { - if (pr.m_Semantic.empty() && pr.m_Values.c_str()[0] == '(') - { - pr.m_BindingSlot = eConstantBufferShaderSlot_PerMaterial; - } - AffectedParams.push_back(pr); - } - } - } - for (i = 0; i < pCache->m_AffectedSamplers.size(); i++) - { - uint32 nParam = pCache->m_AffectedSamplers[i]; - FXSamplersIt it = std::lower_bound(FXParams.m_FXSamplers.begin(), FXParams.m_FXSamplers.end(), nParam, FXSamplersSortByName()); - if (it != FXParams.m_FXSamplers.end() && nParam == (*it).m_dwName[0]) - { - SFXSampler& pr = (*it); - AffectedSamplers.push_back(pr); - } - } - for (i = 0; i < pCache->m_AffectedTextures.size(); i++) - { - uint32 nParam = pCache->m_AffectedTextures[i]; - FXTexturesIt it = std::lower_bound(FXParams.m_FXTextures.begin(), FXParams.m_FXTextures.end(), nParam, FXTexturesSortByName()); - if (it != FXParams.m_FXTextures.end() && nParam == (*it).m_dwName[0]) - { - SFXTexture& pr = (*it); - AffectedTextures.push_back(pr); - } - } - } - else - { - for (i = 0; i < FXParams.m_FXParams.size(); i++) - { - SFXParam* pr = &FXParams.m_FXParams[i]; - if (!(pr->GetFlags() & PF_AUTOMERGED)) - { - AddAffectedParameter(Parser, AffectedParams, AffectedFragments, pr, eSHClass, dwSHType, pShTech); - } - } - for (i = 0; i < FXParams.m_FXSamplers.size(); i++) - { - SFXSampler* pr = &FXParams.m_FXSamplers[i]; - AddAffectedSampler(Parser, AffectedSamplers, AffectedFragments, pr, eSHClass, dwSHType, pShTech); - } - for (i = 0; i < FXParams.m_FXTextures.size(); i++) - { - SFXTexture* pr = &FXParams.m_FXTextures[i]; - AddAffectedTexture(Parser, AffectedTextures, AffectedFragments, pr, eSHClass, dwSHType, pShTech); - } - } - - if (CParserBin::m_bParseFX) - { - FXMacroBinItor itor; - for (itor = Macros.begin(); itor != Macros.end(); ++itor) - { - if (itor->second.m_nMask && !(itor->second.m_nMask & nAffectMask)) - { - continue; - } - SHData.push_back(eT_define); - SHData.push_back(itor->first); - SHData.push_back(0); - } - std::vector PackedParams; - TArray Replaces; - TArray NewTokens; - ParseBinFX_Technique_Pass_PackParameters (Parser, AffectedParams, AffectedFragments, pFunc, eSHClass, dwSHName, PackedParams, Replaces, NewTokens, bMerged); - - if (!pCache) - { - // Update new parameters in shader structures - for (i = 0; i < PackedParams.size(); i++) - { - SFXParam* pr = &PackedParams[i]; - AffectedParams.push_back(*pr); - } - if (CRenderer::CV_r_shadersAllowCompilation) - { - SaveBinShaderLocalInfo(pBin, pFunc->m_dwName, Parser.m_pCurShader->m_nMaskGenFX, Parser.m_pCurShader->m_maskGenStatic, AffectedFragments, AffectedParams, AffectedSamplers, AffectedTextures); - } - } - else - { - for (i = 0; i < pCache->m_AffectedParams.size(); i++) - { - int32 nParam = pCache->m_AffectedParams[i]; - for (j = 0; j < PackedParams.size(); j++) - { - SFXParam& pr = PackedParams[j]; - if (pr.m_dwName[0] == nParam) - { - AffectedParams.push_back(pr); - break; - } - } - } - } - - // Update FX parameters - for (i = 0; i < AffectedParams.size(); i++) - { - SFXParam* pr = &AffectedParams[i]; - mfAddFXParam(FXParams, pr); - } - - // Include all affected functions/structures/parameters in the final script - if (CParserBin::PlatformSupportsConstantBuffers()) // use CB scopes for D3D10 shaders - { - int8 nPrevCB = -1; - std::vector ParamsData; - - for (i = 0; i < AffectedParams.size(); i++) - { - SFXParam& pr = AffectedParams[i]; - if (bMerged[i] == 0xff) - { - continue; - } - if (pr.m_BindingSlot >= 0) - { - ParamsData.push_back(&pr); - } - } - - const int shaderClassIndex = (eSHClass == eHWSC_Vertex) ? 0 : (eSHClass == eHWSC_Pixel) ? 1 : 2; - - std::sort(ParamsData.begin(), ParamsData.end(), - [shaderClassIndex](const SFXParam* a, const SFXParam* b) - { - const uint16 bindSlot0 = a->m_BindingSlot; - const uint16 bindSlot1 = b->m_BindingSlot; - const int16 register0 = a->m_Register[shaderClassIndex]; - const int16 register1 = b->m_Register[shaderClassIndex]; - - if (bindSlot0 != bindSlot1) - { - return (bindSlot0 < bindSlot1); - } - return (register0 < register1); - }); - - // First we need to declare semantic variables (in CB scopes in case of DX11) - for (i = 0; i < ParamsData.size(); i++) - { - SFXParam* pPr = ParamsData[i]; - int nCB = pPr->m_BindingSlot; - nCB = pPr->m_BindingSlot; - if (nPrevCB != nCB) - { - if (nPrevCB != -1) - { - SHData.push_back(eT_br_cv_2); - SHData.push_back(eT_semicolumn); - } - SHData.push_back(eT_cbuffer); - - AZ_Assert(nCB < AZ_ARRAY_SIZE(GeneratedConstantBufferNames), "Trying to generate a constant buffer at an invalid slot"); - SHData.push_back(GeneratedConstantBufferNames[nCB]); - SHData.push_back(eT_colon); - SHData.push_back(eT_register); - char str[32]; - sprintf_s(str, "b%d", nCB); - SHData.push_back(eT_br_rnd_1); - SHData.push_back(Parser.NewUserToken(eT_unknown, str, true)); - SHData.push_back(eT_br_rnd_2); - SHData.push_back(eT_br_cv_1); - } - nPrevCB = nCB; - AddParameterToScript(Parser, pPr, SHData, eSHClass, nCB); - } - if (nPrevCB >= 0) - { - nPrevCB = -1; - SHData.push_back(eT_br_cv_2); - SHData.push_back(eT_semicolumn); - } - - for (i = 0; i < AffectedSamplers.size(); i++) - { - SFXSampler* pr = &AffectedSamplers[i]; - AddSamplerToScript(Parser, pr, SHData, eSHClass); - } - for (i = 0; i < AffectedTextures.size(); i++) - { - SFXTexture* pr = &AffectedTextures[i]; - AddTextureToScript(Parser, pr, SHData, eSHClass); - } - } - else - { - // Update affected parameters in script -#ifdef _DEBUG - for (i = 0; i < AffectedParams.size(); i++) - { - SFXParam* pr = &AffectedParams[i]; - for (j = i + 1; j < AffectedParams.size(); j++) - { - SFXParam* pr1 = &AffectedParams[j]; - if (pr->m_dwName[0] == pr1->m_dwName[0]) - { - CRY_ASSERT(0); - } - } - } -#endif - for (i = 0; i < AffectedParams.size(); i++) - { - SFXParam* pr = &AffectedParams[i]; - // Ignore parameters which where packed - if (bMerged[i] == 0xff) - { - continue; - } - AddParameterToScript(Parser, pr, SHData, eSHClass, -1); - } - } - - // Generate fragment tokens - for (i = 0; i < Parser.m_CodeFragments.size(); i++) - { - int h = -1; - SCodeFragment* cf = &Parser.m_CodeFragments[i]; - if (cf->m_dwName) - { - for (h = 0; h < (int)AffectedFragments.size(); h++) - { - if (AffectedFragments[h] == i) - { - break; - } - } - if (h == AffectedFragments.size()) - { - continue; - } - } - - Parser.CopyTokens(cf, SHData, Replaces, NewTokens, h); - if (cf->m_eType == eFT_Sampler) - { - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_GLES3 || CParserBin::m_nPlatform == SF_METAL) - { - int nT = Parser.m_Tokens[cf->m_nLastToken - 1]; - //CRY_ASSERT(nT >= eT_s0 && nT <= eT_s15); - if (nT >= eT_s0 && nT <= eT_s15) - { - nT = nT - eT_s0 + eT_t0; - SHData.push_back(eT_colon); - SHData.push_back(eT_register); - SHData.push_back(eT_br_rnd_1); - SHData.push_back(nT); - SHData.push_back(eT_br_rnd_2); - } - } - SHData.push_back(eT_semicolumn); - } - } - } - return bRes; -} - -bool CShaderManBin::ParseBinFX_Technique_Pass_LoadShader([[maybe_unused]] CParserBin& Parser, [[maybe_unused]] FXMacroBin& Macros, [[maybe_unused]] SParserFrame& SHFrame, [[maybe_unused]] SShaderTechnique* pShTech, [[maybe_unused]] SShaderPass* pPass, [[maybe_unused]] EHWShaderClass eSHClass, [[maybe_unused]] SShaderFXParams& FXParams) -{ - assert (gRenDev->m_pRT->IsRenderThread()); - - LOADING_TIME_PROFILE_SECTION(iSystem); - bool bRes = true; - -#ifndef NULL_RENDERER - - CRY_ASSERT(!SHFrame.IsEmpty()); - - uint32 dwSHName; - uint32 dwSHType = 0; - - uint32* pTokens = &Parser.m_Tokens[0]; - - dwSHName = pTokens[SHFrame.m_nFirstToken]; - uint32 nCur = SHFrame.m_nFirstToken + 1; - uint32 nTok = pTokens[nCur]; - if (nTok != eT_br_rnd_1) - { - nCur += 2; - nTok = pTokens[nCur]; - } - nCur++; - assert (nTok == eT_br_rnd_1); - if (nTok == eT_br_rnd_1) - { - nTok = pTokens[nCur]; - if (nTok != eT_br_rnd_2) - { - CRY_ASSERT(!"Local function parameters aren't supported anymore"); - } - } - nCur++; - if (nCur <= SHFrame.m_nLastToken) - { - dwSHType = pTokens[nCur]; - } - - enum - { - SHDATA_BUFFER_SIZE = 131072 - }; - - uint64 nGenMask = 0; - PodArray SHDataBuffer(SHDATA_BUFFER_SIZE); - bRes &= ParseBinFX_Technique_Pass_GenerateShaderData(Parser, Macros, FXParams, dwSHName, eSHClass, nGenMask, dwSHType, SHDataBuffer, pShTech); -#if !defined(_RELEASE) - if (SHDataBuffer.size() > SHDATA_BUFFER_SIZE) - { - CryLogAlways("CShaderManBin::ParseBinFX_Technique_Pass_LoadShader: SHDataBuffer has been exceeded (buffer=%u, count=%u). Adjust buffer size to remove unnecessary allocs", SHDATA_BUFFER_SIZE, SHDataBuffer.Size()); - } -#endif - TArray SHData(0, SHDataBuffer.Size()); - SHData.Copy(SHDataBuffer.GetElements(), SHDataBuffer.size()); - - CHWShader* pSH = NULL; - bool bValidShader = false; - - CShader* efSave = gRenDev->m_RP.m_pShader; - gRenDev->m_RP.m_pShader = Parser.m_pCurShader; - CRY_ASSERT(gRenDev->m_RP.m_pShader != 0); - if (bRes && (!CParserBin::m_bParseFX || !SHData.empty())) - { - const char* szName = Parser.GetString(dwSHName); - char str[1024]; - sprintf_s(str, "%s@%s", Parser.m_pCurShader->m_NameShader.c_str(), szName); - pSH = CHWShader::mfForName(str, Parser.m_pCurShader->m_NameFile, Parser.m_pCurShader->m_CRC32, szName, eSHClass, SHData, &Parser.m_TokenTable, dwSHType, Parser.m_pCurShader, nGenMask, Parser.m_pCurShader->m_nMaskGenFX); - } - if (pSH) - { - bValidShader = true; - - if (eSHClass == eHWSC_Vertex) - { - pPass->m_VShader = pSH; - } - else - if (eSHClass == eHWSC_Pixel) - { - pPass->m_PShader = pSH; - } - else - if (CParserBin::PlatformSupportsGeometryShaders() && eSHClass == eHWSC_Geometry) - { - pPass->m_GShader = pSH; - } - else - if (CParserBin::PlatformSupportsDomainShaders() && eSHClass == eHWSC_Domain) - { - pPass->m_DShader = pSH; - } - else - if (CParserBin::PlatformSupportsHullShaders() && eSHClass == eHWSC_Hull) - { - pPass->m_HShader = pSH; - } - else - if (CParserBin::PlatformSupportsComputeShaders() && eSHClass == eHWSC_Compute) - { - pPass->m_CShader = pSH; - } - else - { - CryLog("Unsupported/unrecognised shader: %s[%d]", pSH->m_Name.c_str(), eSHClass); - } - } - - gRenDev->m_RP.m_pShader = efSave; -#endif - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Technique_Pass(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pShTech) -{ - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(VertexShader) - FX_TOKEN(PixelShader) - FX_TOKEN(GeometryShader) - FX_TOKEN(DomainShader) - FX_TOKEN(HullShader) - FX_TOKEN(ComputeShader) - FX_TOKEN(ZEnable) - FX_TOKEN(ZWriteEnable) - FX_TOKEN(CullMode) - FX_TOKEN(SrcBlend) - FX_TOKEN(DestBlend) - FX_TOKEN(AlphaBlendEnable) - FX_TOKEN(AlphaFunc) - FX_TOKEN(AlphaRef) - FX_TOKEN(ZFunc) - FX_TOKEN(ColorWriteEnable) - FX_TOKEN(IgnoreMaterialState) - FX_END_TOKENS - - bool bRes = true; - int n = pShTech->m_Passes.Num(); - pShTech->m_Passes.ReserveNew(n + 1); - SShaderPass* sm = &pShTech->m_Passes[n]; - sm->m_eCull = -1; - sm->m_AlphaRef = ~0; - - SParserFrame VS, PS, GS, DS, HS, CS; - FXMacroBin VSMacro, PSMacro, GSMacro, DSMacro, HSMacro, CSMacro; - - byte ZFunc = eCF_LEqual; - - byte ColorWriteMask = 0xff; - - byte AlphaFunc = eCF_Disable; - byte AlphaRef = 0; - int State = GS_DEPTHWRITE; - - signed char Cull = -1; - int nIndex; - EToken eSrcBlend = eT_unknown; - EToken eDstBlend = eT_unknown; - bool bBlend = false; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_VertexShader: - VS = Parser.m_Data; - VSMacro = Parser.m_Macros[1]; - break; - case eT_PixelShader: - PS = Parser.m_Data; - PSMacro = Parser.m_Macros[1]; - break; - case eT_GeometryShader: - GS = Parser.m_Data; - GSMacro = Parser.m_Macros[1]; - break; - case eT_DomainShader: - DS = Parser.m_Data; - DSMacro = Parser.m_Macros[1]; - break; - case eT_HullShader: - HS = Parser.m_Data; - HSMacro = Parser.m_Macros[1]; - break; - case eT_ComputeShader: - CS = Parser.m_Data; - CSMacro = Parser.m_Macros[1]; - break; - - case eT_ZEnable: - if (Parser.GetBool(Parser.m_Data)) - { - State &= ~GS_NODEPTHTEST; - } - else - { - State |= GS_NODEPTHTEST; - } - break; - case eT_ZWriteEnable: - if (Parser.GetBool(Parser.m_Data)) - { - State |= GS_DEPTHWRITE; - } - else - { - State &= ~GS_DEPTHWRITE; - } - break; - case eT_CullMode: - eT = Parser.GetToken(Parser.m_Data); - if (eT == eT_None) - { - Cull = eCULL_None; - } - else - if (eT == eT_CCW || eT == eT_Back) - { - Cull = eCULL_Back; - } - else - if (eT == eT_CW || eT == eT_Front) - { - Cull = eCULL_Front; - } - else - { - Warning("unknown CullMode parameter '%s' (Skipping)\n", Parser.GetString(eT)); - CRY_ASSERT(0); - } - break; - case eT_AlphaFunc: - AlphaFunc = Parser.GetCompareFunc(Parser.GetToken(Parser.m_Data)); - break; - case eT_ColorWriteEnable: - { - if (ColorWriteMask == 0xff) - { - ColorWriteMask = 0; - } - uint32 nCur = Parser.m_Data.m_nFirstToken; - while (nCur <= Parser.m_Data.m_nLastToken) - { - uint32 nT = Parser.m_Tokens[nCur++]; - if (nT == eT_or) - { - continue; - } - if (nT == eT_0) - { - ColorWriteMask |= 0; - } - else - if (nT == eT_RED) - { - ColorWriteMask |= 1; - } - else - if (nT == eT_GREEN) - { - ColorWriteMask |= 2; - } - else - if (nT == eT_BLUE) - { - ColorWriteMask |= 4; - } - else - if (nT == eT_ALPHA) - { - ColorWriteMask |= 8; - } - else - { - Warning("unknown WriteMask parameter '%s' (Skipping)\n", Parser.GetString(eT)); - } - } - } - break; - case eT_ZFunc: - ZFunc = Parser.GetCompareFunc(Parser.GetToken(Parser.m_Data)); - sm->m_PassFlags |= SHPF_FORCEZFUNC; - break; - case eT_AlphaRef: - AlphaRef = Parser.GetInt(Parser.GetToken(Parser.m_Data)); - break; - case eT_SrcBlend: - eSrcBlend = Parser.GetToken(Parser.m_Data); - break; - case eT_DestBlend: - eDstBlend = Parser.GetToken(Parser.m_Data); - break; - case eT_AlphaBlendEnable: - bBlend = Parser.GetBool(Parser.m_Data); - break; - - case eT_IgnoreMaterialState: - sm->m_PassFlags |= SHPF_NOMATSTATE; - break; - - default: - CRY_ASSERT(0); - } - } - - if (bBlend && eSrcBlend && eDstBlend) - { - int nSrc = Parser.GetSrcBlend(eSrcBlend); - int nDst = Parser.GetDstBlend(eDstBlend); - if (nSrc >= 0 && nDst >= 0) - { - State |= nSrc; - State |= nDst; - } - } - if (ColorWriteMask != 0xff) - { - for (int i = 0; i < 4; i++) - { - if (!(ColorWriteMask & (1 << i))) - { - State |= GS_NOCOLMASK_R << i; - } - } - } - - if (AlphaFunc) - { - switch (AlphaFunc) - { - case eCF_Greater: - State |= GS_ALPHATEST_GREATER; - break; - case eCF_GEqual: - State |= GS_ALPHATEST_GEQUAL; - break; - case eCF_Less: - State |= GS_ALPHATEST_LESS; - break; - case eCF_LEqual: - State |= GS_ALPHATEST_LEQUAL; - break; - default: - CRY_ASSERT(0); - } - } - - switch (ZFunc) - { - case eCF_Equal: - State |= GS_DEPTHFUNC_EQUAL; - break; - case eCF_Greater: - State |= GS_DEPTHFUNC_GREAT; - break; - case eCF_GEqual: - State |= GS_DEPTHFUNC_GEQUAL; - break; - case eCF_Less: - State |= GS_DEPTHFUNC_LESS; - break; - case eCF_NotEqual: - State |= GS_DEPTHFUNC_NOTEQUAL; - break; - case eCF_LEqual: - State |= GS_DEPTHFUNC_LEQUAL; - break; - case eCF_Always: - State |= GS_DEPTHFUNC_ALWAYS; - break; - default: - CRY_ASSERT(0); - } - - sm->m_RenderState = State; - sm->m_eCull = Cull; - - mfGeneratePublicFXParams(Parser.m_pCurShader, Parser); - SShaderFXParams& FXParams = mfGetFXParams(Parser.m_pCurShader); - - if (!VS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, VSMacro, VS, pShTech, sm, eHWSC_Vertex, FXParams); - } - if (!PS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, PSMacro, PS, pShTech, sm, eHWSC_Pixel, FXParams); - } - if (CParserBin::PlatformSupportsGeometryShaders() && !GS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, GSMacro, GS, pShTech, sm, eHWSC_Geometry, FXParams); - } - if (CParserBin::PlatformSupportsHullShaders() && !HS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, HSMacro, HS, pShTech, sm, eHWSC_Hull, FXParams); - } - if (CParserBin::PlatformSupportsDomainShaders() && !DS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, DSMacro, DS, pShTech, sm, eHWSC_Domain, FXParams); - } - if (CParserBin::PlatformSupportsComputeShaders() && !CS.IsEmpty()) - { - bRes &= ParseBinFX_Technique_Pass_LoadShader(Parser, CSMacro, CS, pShTech, sm, eHWSC_Compute, FXParams); - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_LightStyle_Val(CParserBin& Parser, SParserFrame& Frame, CLightStyle* ls) -{ - int i; - char str[64]; - const char* pstr1, * pstr2; - SLightStyleKeyFrame pKeyFrame; - - ls->m_Map.Free(); - string sr = Parser.GetString(Frame); - const char* lstr = sr.c_str(); - - // First count the keyframes - size_t nKeyFrames = 0; - while (true) - { - pstr1 = strchr(lstr, '|'); - if (!pstr1) - { - break; - } - pstr2 = strchr(pstr1 + 1, '|'); - if (!pstr2) - { - break; - } - if (pstr2 - pstr1 - 1 > 0) - { - ++nKeyFrames; - } - lstr = pstr2; - } - ls->m_Map.reserve(nKeyFrames); - - lstr = sr.c_str(); - int n = 0; - while (true) - { - pstr1 = strchr(lstr, '|'); - if (!pstr1) - { - break; - } - pstr2 = strchr(pstr1 + 1, '|'); - if (!pstr2) - { - break; - } - if (pstr2 - pstr1 - 1 > 0) - { - azstrncpy(str, AZ_ARRAY_SIZE(str), pstr1 + 1, pstr2 - pstr1 - 1); - str[pstr2 - pstr1 - 1] = 0; - i = azsscanf(str, "%f %f %f %f %f %f %f", &pKeyFrame.cColor.r, &pKeyFrame.cColor.g, &pKeyFrame.cColor.b, &pKeyFrame.cColor.a, - &pKeyFrame.vPosOffset.x, &pKeyFrame.vPosOffset.y, &pKeyFrame.vPosOffset.z); - switch (i) - { - case 1: - { - // Only luminance updates - pKeyFrame.cColor.g = pKeyFrame.cColor.b = pKeyFrame.cColor.r; - pKeyFrame.cColor.a = 1.0f; - pKeyFrame.vPosOffset = Vec3(0); - } - break; - - case 3: - { - // No position/spec mult updates - pKeyFrame.cColor.a = 1.0f; - pKeyFrame.vPosOffset = Vec3(0); - } - break; - - case 4: - { - // No position - pKeyFrame.vPosOffset = Vec3(0); - } - break; - - default: - break; - } - ls->m_Map.AddElem(pKeyFrame); - n++; - } - - lstr = pstr2; - } - ls->m_Map.Shrink(); - CRY_ASSERT(ls->m_Map.Num() == n); - if (ls->m_Map.Num() == n) - { - return true; - } - return false; -} - -bool CShaderManBin::ParseBinFX_LightStyle(CParserBin& Parser, SParserFrame& Frame, int nStyle) -{ - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(KeyFrameParams) - FX_TOKEN(KeyFrameRandColor) - FX_TOKEN(KeyFrameRandIntensity) - FX_TOKEN(KeyFrameRandSpecMult) - FX_TOKEN(KeyFrameRandPosOffset) - FX_TOKEN(Speed) - FX_END_TOKENS - - bool bRes = true; - - Parser.m_pCurShader->m_Flags |= EF_LIGHTSTYLE; - if (CLightStyle::s_LStyles.Num() <= (uint32)nStyle) - { - CLightStyle::s_LStyles.ReserveNew(nStyle + 1); - } - CLightStyle* ls = CLightStyle::s_LStyles[nStyle]; - if (!ls) - { - ls = new CLightStyle; - ls->m_LastTime = 0; - ls->m_Color = Col_White; - CLightStyle::s_LStyles[nStyle] = ls; - } - ls->m_TimeIncr = 60; - int nIndex; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_KeyFrameRandColor: - ls->m_bRandColor = Parser.GetBool(Parser.m_Data); - break; - - case eT_KeyFrameRandIntensity: - ls->m_bRandIntensity = Parser.GetBool(Parser.m_Data); - break; - - case eT_KeyFrameRandSpecMult: - ls->m_bRandSpecMult = Parser.GetBool(Parser.m_Data); - break; - - case eT_KeyFrameRandPosOffset: - ls->m_bRandPosOffset = Parser.GetBool(Parser.m_Data); - break; - - case eT_KeyFrameParams: - bRes &= ParseBinFX_LightStyle_Val(Parser, Parser.m_Data, ls); - break; - - case eT_Speed: - ls->m_TimeIncr = Parser.GetFloat(Parser.m_Data); - break; - default: - CRY_ASSERT(0); - } - } - - if (ls->m_Map.Num() && (ls->m_bRandPosOffset || ls->m_bRandIntensity || ls->m_bRandSpecMult || ls->m_bRandColor)) - { - int32 nCount = ls->m_Map.Num(); - for (int f = 0; f < nCount; ++f) - { - SLightStyleKeyFrame& pKeyFrame = ls->m_Map[f]; - if (ls->m_bRandPosOffset) - { - pKeyFrame.vPosOffset = Vec3(cry_random(-1.0f, 1.0f), cry_random(-1.0f, 1.0f), cry_random(-1.0f, 1.0f)); - } - - if (ls->m_bRandColor) - { - pKeyFrame.cColor *= ColorF(cry_random(0.0f, 1.0f), cry_random(0.0f, 1.0f), cry_random(0.0f, 1.0f), 1.0f); - } - - if (ls->m_bRandIntensity) - { - pKeyFrame.cColor *= cry_random(0.0f, 1.0f); - } - - if (ls->m_bRandSpecMult) - { - pKeyFrame.cColor.a = cry_random(0.0f, 1.0f); - } - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Technique_Annotations_String(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pShTech, std::vector& techParams, bool* bPublic) -{ - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(Public) - FX_TOKEN(NoLights) - FX_TOKEN(NoMaterialState) - FX_TOKEN(PositionInvariant) - FX_TOKEN(TechniqueZ) - FX_TOKEN(TechniqueZPrepass) - FX_TOKEN(TechniqueShadowGen) - FX_TOKEN(TechniqueMotionBlur) - FX_TOKEN(TechniqueCustomRender) - FX_TOKEN(TechniqueEffectLayer) - FX_TOKEN(TechniqueDebug) - FX_TOKEN(TechniqueSoftAlphaTest) - FX_TOKEN(TechniqueWaterRefl) - FX_TOKEN(TechniqueWaterCaustic) - FX_TOKEN(TechniqueThickness) - FX_END_TOKENS - - bool bRes = true; - int nIndex; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_Public: - if (pShTech) - { - pShTech->m_Flags |= FHF_PUBLIC; - } - else - if (bPublic) - { - *bPublic = true; - } - break; - - case eT_PositionInvariant: - if (pShTech) - { - pShTech->m_Flags |= FHF_POSITION_INVARIANT; - } - break; - - case eT_NoLights: - if (pShTech) - { - pShTech->m_Flags |= FHF_NOLIGHTS; - } - break; - - case eT_NoMaterialState: - if (Parser.m_pCurShader) - { - Parser.m_pCurShader->m_Flags2 |= EF2_IGNORERESOURCESTATES; - } - break; - - // Note: When adding/removing batch flags, please, update sDescList in D3DRendPipeline.cpp - case eT_TechniqueDebug: - { - } - - case eT_TechniqueZ: - case eT_TechniqueZPrepass: - case eT_TechniqueShadowGen: - case eT_TechniqueMotionBlur: - case eT_TechniqueCustomRender: - case eT_TechniqueEffectLayer: - case eT_TechniqueSoftAlphaTest: - case eT_TechniqueWaterRefl: - case eT_TechniqueWaterCaustic: - case eT_TechniqueThickness: - { - if (!Parser.m_pCurShader) - { - break; - } - - static const uint32 pTechTable[eT_TechniqueMax - eT_TechniqueZ] = - { - TTYPE_Z, //eT_TechniqueZ - TTYPE_SHADOWGEN, //eT_TechniqueShadowGen - TTYPE_MOTIONBLURPASS, //eT_TechniqueMotionBlur - TTYPE_CUSTOMRENDERPASS, //eT_TechniqueCustomRender - TTYPE_EFFECTLAYER, //eT_TechniqueEffectLayer - TTYPE_DEBUG, //eT_TechniqueDebug - TTYPE_SOFTALPHATESTPASS, //eT_TechniqueSoftAlphaTest - TTYPE_WATERREFLPASS, //eT_TechniqueWaterRefl - TTYPE_WATERCAUSTICPASS, //eT_TechniqueWaterCaustic - TTYPE_ZPREPASS, //eT_TechniqueZPrepass - TTYPE_PARTICLESTHICKNESSPASS //eT_TechniqueThickness - }; - - const CCryNameR pszNameTech = Parser.GetNameString(Parser.m_Data); - int idx = techParams.size() - 1; - CRY_ASSERT(idx >= 0); - CRY_ASSERT(eT - eT_TechniqueZ >= 0); - techParams[idx].techName[ pTechTable[eT - eT_TechniqueZ] ] = pszNameTech; - } - break; - - default: - CRY_ASSERT(0); - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Technique_Annotations(CParserBin& Parser, SParserFrame& Frame, SShaderTechnique* pShTech, std::vector& techParams, bool* bPublic) -{ - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(string) - FX_END_TOKENS - - bool bRes = true; - int nIndex; - - while (Parser.ParseObject(sCommands, nIndex)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_string: - { - eT = Parser.GetToken(Parser.m_Name); - CRY_ASSERT(eT == eT_Script); - bRes &= ParseBinFX_Technique_Annotations_String(Parser, Parser.m_Data, pShTech, techParams, bPublic); - } - break; - - default: - CRY_ASSERT(0); - } - } - - Parser.EndFrame(OldFrame); - - return bRes; -} - -bool CShaderManBin::ParseBinFX_Technique_CustomRE(CParserBin& Parser, SParserFrame& Frame, SParserFrame& Name, SShaderTechnique* pShTech) -{ - uint32 nName = Parser.GetToken(Name); - - if (nName == eT_LensOptics) - { - CRELensOptics* ps = new CRELensOptics; - if (ps->mfCompile(Parser, Frame)) - { - pShTech->m_REs.AddElem(ps); - pShTech->m_Flags |= FHF_RE_LENSOPTICS; - return true; - } - else - { - delete ps; - } - } -#if 0 - else - if (nName == eT_Cloud) - { - CRECloud* ps = new CRECloud; - if (ps->mfCompile(Parser, Frame)) - { - pShTech->m_REs.AddElem(ps); - pShTech->m_Flags |= FHF_RE_CLOUD; - return true; - } - else - { - delete ps; - } - } -#endif - else - if (nName == eT_Beam) - { - CREBeam* ps = new CREBeam; - if (ps->mfCompile(Parser, Frame)) - { - pShTech->m_REs.AddElem(ps); - } - else - { - delete ps; - } - } - else - if (nName == eT_Ocean) - { - CRY_ASSERT(0); - } - - return true; -} - -SShaderTechnique* CShaderManBin::ParseBinFX_Technique(CParserBin& Parser, SParserFrame& Frame, SParserFrame Annotations, std::vector& techParams, bool* bPublic) -{ - LOADING_TIME_PROFILE_SECTION(iSystem); - - SParserFrame OldFrame = Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(pass) - FX_TOKEN(CustomRE) - FX_TOKEN(Style) - FX_END_TOKENS - - bool bRes = true; - SShaderTechnique* pShTech = NULL; - if (Parser.m_pCurShader) - { - pShTech = new SShaderTechnique(Parser.m_pCurShader); - } - - if (Parser.m_pCurShader) - { - SShaderTechParseParams ps; - techParams.push_back(ps); - } - - if (!Annotations.IsEmpty()) - { - ParseBinFX_Technique_Annotations(Parser, Annotations, pShTech, techParams, bPublic); - } - - while (Parser.ParseObject(sCommands)) - { - EToken eT = Parser.GetToken(); - switch (eT) - { - case eT_pass: - if (pShTech) - { - bRes &= ParseBinFX_Technique_Pass(Parser, Parser.m_Data, pShTech); - } - break; - - case eT_Style: - if (pShTech) - { - ParseBinFX_LightStyle(Parser, Parser.m_Data, Parser.GetInt(Parser.GetToken(Parser.m_Name))); - } - break; - - case eT_CustomRE: - if (pShTech) - { - bRes &= ParseBinFX_Technique_CustomRE(Parser, Parser.m_Data, Parser.m_Name, pShTech); - } - break; - - default: - CRY_ASSERT(0); - } - } - - if (bRes) - { - if (Parser.m_pCurShader && pShTech) - { - Parser.m_pCurShader->m_HWTechniques.AddElem(pShTech); - } - } - else - { - techParams.pop_back(); - } - - Parser.EndFrame(OldFrame); - - return pShTech; -} - -float g_fTimeA; - -bool CShaderManBin::ParseBinFX(SShaderBin* pBin, CShader* ef, uint64 nMaskGen) -{ - LOADING_TIME_PROFILE_SECTION_ARGS(pBin->m_szName); - - bool bRes = true; - - float fTimeA = iTimer->GetAsyncCurTime(); - -#if !defined(SHADER_NO_SOURCES) - CParserBin Parser(pBin, ef); - - CShader* efGen = ef->m_pGenShader; - - if (efGen && efGen->m_ShaderGenParams) - { - AddGenMacroses(efGen->m_ShaderGenParams, Parser, nMaskGen); - } - - if (ef->m_ShaderGenStaticParams) - { - // Just add the defines and not the masks because they could clash with the gen params masks. - AddGenMacroses(ef->m_ShaderGenStaticParams, Parser, ef->m_maskGenStatic, true); - } - - pBin->Lock(); - Parser.Preprocess(0, pBin->m_Tokens, &pBin->m_TokenTable); - ef->m_CRC32 = pBin->m_CRC32; - ef->m_SourceCRC32 = pBin->m_SourceCRC32; - pBin->Unlock(); -#endif - -#if defined(SHADER_NO_SOURCES) - iLog->LogError("ERROR: Couldn't find binary shader '%s' (0x%x)", ef->GetName(), ef->m_nMaskGenFX); - return false; -#else - SParserFrame Frame(0, (Parser.m_Tokens.size() > 0 ? Parser.m_Tokens.size() - 1 : 0)); - Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(static) - FX_TOKEN(half) - FX_TOKEN(half2) - FX_TOKEN(half3) - FX_TOKEN(half4) - FX_TOKEN(half2x4) - FX_TOKEN(half3x4) - FX_TOKEN(half4x4) - FX_TOKEN(float) - FX_TOKEN(float2) - FX_TOKEN(float3) - FX_TOKEN(float4) - FX_TOKEN(float2x4) - FX_TOKEN(float3x4) - FX_TOKEN(float4x4) - FX_TOKEN(bool) - FX_TOKEN(int) - FX_TOKEN(struct) - FX_TOKEN(sampler1D) - FX_TOKEN(sampler2D) - FX_TOKEN(sampler3D) - FX_TOKEN(samplerCUBE) - FX_TOKEN(Texture2D) - FX_TOKEN(RWTexture2D) - FX_TOKEN(RWTexture2DArray) - FX_TOKEN(Texture2DArray) - FX_TOKEN(Texture2DMS) - FX_TOKEN(TextureCube) - FX_TOKEN(TextureCubeArray) - FX_TOKEN(Texture3D) - FX_TOKEN(RWTexture3D) - FX_TOKEN(technique) - FX_TOKEN(SamplerState) - FX_TOKEN(SamplerComparisonState) - FX_TOKEN(Buffer) - FX_TOKEN(RWBuffer) - FX_TOKEN(StructuredBuffer) - FX_TOKEN(RWStructuredBuffer) - FX_TOKEN(ByteAddressBuffer) - FX_TOKEN(RWByteAddressBuffer) - FX_TOKEN(cbuffer) - FX_TOKEN(RasterizerOrderedBuffer) - FX_TOKEN(RasterizerOrderedByteAddressBuffer) - FX_TOKEN(RasterizerOrderedStructuredBuffer) - FX_END_TOKENS - - std::vector techParams; - CCryNameR techStart[2]; - - // From MemReplay analysis of shader params, 200 should be more than enough space - static decltype(SShaderFXParams::m_FXParams) s_tempFXParams; - s_tempFXParams.reserve(200); - s_tempFXParams.clear(); - - SShaderFXParams& FXP = mfGetFXParams(Parser.m_pCurShader); - FXP.m_FXParams.swap(s_tempFXParams); - - ef->mfFree(); - - assert (ef->m_HWTechniques.Num() == 0); - - ETokenStorageClass nTokenStorageClass = Parser.ParseObject(sCommands); - while (nTokenStorageClass) - { - EToken eT = Parser.GetToken(); - SCodeFragment Fr; - SFXParam P; - string szR; - switch (eT) - { - case eT_struct: - case eT_cbuffer: - Fr.m_nFirstToken = Parser.FirstToken(); - Fr.m_nLastToken = Parser.m_CurFrame.m_nCurToken - 1; - Fr.m_dwName = Parser.m_Tokens[Fr.m_nFirstToken + 1]; -#ifdef _DEBUG - //Fr.m_Name = Parser.GetString(Fr.m_dwName); -#endif - Fr.m_eType = (eT == eT_cbuffer) ? eFT_ConstBuffer : eFT_Structure; - Parser.m_CodeFragments.push_back(Fr); - break; - - case eT_SamplerState: - case eT_SamplerComparisonState: - { - SFXSampler Pr; - Parser.CopyTokens(Parser.m_Name, Pr.m_dwName); - if (eT == eT_SamplerState) - { - Pr.m_eType = eSType_Sampler; - } - else - if (eT == eT_SamplerComparisonState) - { - Pr.m_eType = eSType_SamplerComp; - } - else - { - CRY_ASSERT(0); - } - - uint32 nTokAssign = 0; - if (Parser.m_Assign.IsEmpty() && !Parser.m_Value.IsEmpty()) - { - nTokAssign = Parser.m_Tokens[Parser.m_Value.m_nFirstToken]; - if (nTokAssign == eT_br_cv_1) - { - nTokAssign = Parser.m_Tokens[Parser.m_Value.m_nFirstToken + 1]; - } - } - else - if (!Parser.m_Assign.IsEmpty()) - { - nTokAssign = Parser.m_Tokens[Parser.m_Assign.m_nFirstToken]; - } - Pr.PostLoad(Parser, Parser.m_Name, Parser.m_Annotations, Parser.m_Value, Parser.m_Assign); - - bRes &= ParseBinFX_Sampler(Parser, Parser.m_Data, Pr); - - mfAddFXSampler(Parser.m_pCurShader, &Pr); - } - break; - - case eT_Texture2D: - case eT_Texture2DMS: - case eT_Texture2DArray: - case eT_TextureCube: - case eT_TextureCubeArray: - case eT_Texture3D: - { - SFXTexture Pr; - Parser.CopyTokens(Parser.m_Name, Pr.m_dwName); - - if (eT == eT_Texture2D) - { - Pr.m_eType = eTT_2D; - } - else - if (eT == eT_Texture2DMS) - { - Pr.m_eType = eTT_2DMS; - } - else - if (eT == eT_Texture2DArray) - { - Pr.m_eType = eTT_2DArray; - } - else - if (eT == eT_Texture3D) - { - Pr.m_eType = eTT_3D; - } - else - if (eT == eT_TextureCube) - { - Pr.m_eType = eTT_Cube; - } - else - if (eT == eT_TextureCubeArray) - { - Pr.m_eType = eTT_CubeArray; - } - else - { - CRY_ASSERT(0); - } - - Pr.PostLoad(Parser, Parser.m_Name, Parser.m_Annotations, Parser.m_Value, Parser.m_Assign); - - bRes &= ParseBinFX_Texture(Parser, Parser.m_Data, Pr); - bRes &= ParseBinFX_Texture(Parser, Parser.m_Annotations, Pr); - - // Texture2D something = TS_identifiersearch; - if (!azstrnicmp(Pr.m_Values.c_str(), "TM_", 3) || - !azstrnicmp(Pr.m_Values.c_str(), "TS_", 3) || - !azstrnicmp(Pr.m_Values.c_str(), "TP_", 3)) - { - Pr.m_Semantic = Pr.m_Values; - Pr.m_szTexture = ""; - Pr.m_Values = ""; - } - - // Texture2D something = "filepathsearch"; - // Texture2D something = $databasesearch; - if (Pr.m_Values.c_str()[0]) - { - Pr.m_Semantic = ""; - Pr.m_szTexture = Pr.m_Values.c_str(); - Pr.m_Values = ""; - } - - mfAddFXTexture(Parser.m_pCurShader, &Pr); - } - break; - - case eT_int: - case eT_bool: - case eT_half: - case eT_half2: - case eT_half3: - case eT_half4: - case eT_half2x4: - case eT_half3x4: - case eT_half4x4: - case eT_float: - case eT_float2: - case eT_float3: - case eT_float4: - case eT_float2x4: - case eT_float3x4: - case eT_float4x4: - { - SFXParam Pr; - Parser.CopyTokens(Parser.m_Name, Pr.m_dwName); - - if (eT == eT_float2x4 || eT == eT_half2x4) - { - Pr.m_RegisterCount = 2; - } - else - if (eT == eT_float3x4 || eT == eT_half3x4) - { - Pr.m_RegisterCount = 3; - } - else - if (eT == eT_float4x4 || eT == eT_half4x4) - { - Pr.m_RegisterCount = 4; - } - else - { - Pr.m_RegisterCount = 1; - } - - if (eT == eT_float || eT == eT_half || eT == eT_int || eT == eT_bool) - { - Pr.m_ComponentCount = 1; - } - else - if (eT == eT_float2 || eT == eT_half2) - { - Pr.m_ComponentCount = 2; - } - else - if (eT == eT_float3 || eT == eT_half3) - { - Pr.m_ComponentCount = 3; - } - else - if (eT == eT_float4 || eT == eT_float2x4 || eT == eT_float3x4 || eT == eT_float4x4 || - eT == eT_half4 || eT == eT_half2x4 || eT == eT_half3x4 || eT == eT_half4x4) - { - Pr.m_ComponentCount = 4; - } - - if (eT == eT_int) - { - Pr.m_eType = eType_INT; - } - else - if (eT == eT_bool) - { - Pr.m_eType = eType_BOOL; - } - else - if (eT >= eT_half && eT <= eT_half3x3) - { - Pr.m_eType = eType_HALF; - } - else - { - Pr.m_eType = eType_FLOAT; - } - - if (!Parser.m_Assign.IsEmpty() && Parser.GetToken(Parser.m_Assign) == eT_STANDARDSGLOBAL) - { - ParseBinFX_Global(Parser, Parser.m_Annotations, NULL, techStart); - } - else - { - uint32 nTokAssign = 0; - if (Parser.m_Assign.IsEmpty() && !Parser.m_Value.IsEmpty()) - { - nTokAssign = Parser.m_Tokens[Parser.m_Value.m_nFirstToken]; - if (nTokAssign == eT_br_cv_1) - { - nTokAssign = Parser.m_Tokens[Parser.m_Value.m_nFirstToken + 1]; - } - } - else - if (!Parser.m_Assign.IsEmpty()) - { - nTokAssign = Parser.m_Tokens[Parser.m_Assign.m_nFirstToken]; - } - if (nTokAssign) - { - const char* assign = Parser.GetString(nTokAssign); - if (!assign[0] || !_strnicmp(assign, "PB_", 3)) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerBatch; - } - else - if (!_strnicmp(assign, "PI_", 3) || !_strnicmp(assign, "SI_", 3)) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerInstanceLegacy; - } - else - if (!_strnicmp(assign, "PM_", 3)) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerMaterial; - } - else - if (!_strnicmp(assign, "register", 8)) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerBatch; - } - else - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerBatch; - } - } - else - if (CParserBin::m_nPlatform & (SF_D3D11 | SF_ORBIS | SF_JASPER | SF_GL4 | SF_GLES3 | SF_METAL)) - { - uint32 nTokName = Parser.GetToken(Parser.m_Name); - const char* name = Parser.GetString(nTokName); - if (!strncmp(name, "PI_", 3)) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerInstanceLegacy; - } - else - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerBatch; - } - } - - Pr.PostLoad(Parser, Parser.m_Name, Parser.m_Annotations, Parser.m_Value, Parser.m_Assign); - - EParamType eType; - string szReg = Pr.GetValueForName("register", eType); - if (!szReg.empty()) - { - CRY_ASSERT(szReg[0] == 'c'); - Pr.m_Register[eHWSC_Vertex] = atoi(&szReg[1]); - Pr.m_Register[eHWSC_Pixel] = Pr.m_Register[eHWSC_Vertex]; - - if (CParserBin::PlatformSupportsGeometryShaders()) - { - Pr.m_Register[eHWSC_Geometry] = Pr.m_Register[eHWSC_Vertex]; - } - if (CParserBin::PlatformSupportsDomainShaders()) - { - Pr.m_Register[eHWSC_Domain] = Pr.m_Register[eHWSC_Vertex]; - } - } - uint32 prFlags = Pr.GetFlags(); - if (prFlags & PF_TWEAKABLE_MASK) - { - Pr.m_BindingSlot = eConstantBufferShaderSlot_PerMaterial; - CRY_ASSERT(prFlags & PF_CUSTOM_BINDED); - } - mfAddFXParam(Parser.m_pCurShader, &Pr); - } - } - break; - - case eT_sampler1D: - case eT_sampler2D: - case eT_sampler3D: - case eT_samplerCUBE: - { - Fr.m_nFirstToken = Parser.FirstToken(); - - uint32 nTokenOffset = 1; - - // For DX11 style texture definitions, need to parse out templated type. Also unlike HLSL we *require* it. - if (eT == eT_Texture2DMS || eT == eT_Texture2D || eT == eT_Texture2DArray || eT == eT_TextureCube || eT == eT_TextureCubeArray || eT == eT_Texture3D) - { - // Texture2DMS is particular case, requires (at minimum) type to be specified - parse Texture2DMS tokens - // Texture2D for typeless resources, is also a particular case, type has to explicitly be specified - parse Texture2D tokens - nTokenOffset = 4; - - if (Parser.m_Tokens[Fr.m_nFirstToken + 1] != eT_br_tr_1 || // < - Parser.m_Tokens[Fr.m_nFirstToken + 3] != eT_br_tr_2) // > - { - // Parser.m_Tokens[Fr.m_nFirstToken + 2] is the templated type, e.g. float4 - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR_DBGBRK, "[SHADERS] FAILED TO PARSE '%s': Invalid Texture definition without templated type:", ef->GetName()); - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR_DBGBRK, "[SHADERS] %s %s %s %s" - , Parser.GetString(Parser.m_Tokens[Fr.m_nFirstToken]) - , Parser.GetString(Parser.m_Tokens[Fr.m_nFirstToken + 1]) - , Parser.GetString(Parser.m_Tokens[Fr.m_nFirstToken + 2]) - , Parser.GetString(Parser.m_Tokens[Fr.m_nFirstToken + 3]) - ); - break; - } - } - - Fr.m_nLastToken = Fr.m_nFirstToken + nTokenOffset; - if (!Parser.m_Assign.IsEmpty()) - { - Fr.m_nLastToken = Parser.m_Assign.m_nLastToken; - } - Fr.m_dwName = Parser.m_Tokens[Fr.m_nFirstToken + nTokenOffset]; - Fr.m_eType = eFT_Sampler; - Parser.m_CodeFragments.push_back(Fr); - - //// handy for debugging - do not remove plz - //const char *pszToken0 = Parser.GetString( Parser.m_Tokens[Fr.m_nFirstToken] ); - //const char *pszToken1 = Parser.GetString( Parser.m_Tokens[Fr.m_nFirstToken+1] ); - //const char *pszToken2 = Parser.GetString( Parser.m_Tokens[Fr.m_nFirstToken+2] ); - - bRes &= ParseBinFX_Sampler(Parser, Parser.m_Data, Fr.m_dwName, Parser.m_Annotations, eT); - } - break; - - case eT_Buffer: - case eT_RWBuffer: - case eT_StructuredBuffer: - case eT_RWStructuredBuffer: - case eT_ByteAddressBuffer: - case eT_RWByteAddressBuffer: - case eT_RWTexture2D: - case eT_RWTexture2DArray: - case eT_RWTexture3D: - case eT_RasterizerOrderedBuffer: - case eT_RasterizerOrderedByteAddressBuffer: - case eT_RasterizerOrderedStructuredBuffer: - { - Fr.m_nFirstToken = Parser.FirstToken(); - Fr.m_nLastToken = Fr.m_nFirstToken + 1; - if (!Parser.m_Assign.IsEmpty()) - { - Fr.m_nLastToken = Parser.m_Assign.m_nLastToken + 1; - } - Fr.m_dwName = Parser.m_Tokens[Parser.m_Name.m_nFirstToken]; - Fr.m_eType = eFT_Structure; - Parser.m_CodeFragments.push_back(Fr); - } - break; - - case eT_technique: - { - uint32 nToken = Parser.m_Tokens[Parser.m_Name.m_nFirstToken]; - const char* szName = Parser.GetString(nToken); - SShaderTechnique* pShTech = ParseBinFX_Technique(Parser, Parser.m_Data, Parser.m_Annotations, techParams, NULL); - if (szName) - { - pShTech->m_NameStr = szName; - pShTech->m_NameCRC = szName; - } - } - break; - - default: - //CRY_ASSERT(0); - break; - } - - nTokenStorageClass = Parser.ParseObject(sCommands); - } - - FXP.m_FXParams.swap(s_tempFXParams); - FXP.m_FXParams.reserve(FXP.m_FXParams.size() + s_tempFXParams.size()); - FXP.m_FXParams.insert(FXP.m_FXParams.end(), s_tempFXParams.begin(), s_tempFXParams.end()); - - m_pCEF->mfPostLoadFX(ef, techParams, techStart); - -#if SHADER_REFLECT_TEXTURE_SLOTS - for (uint32 i = 0; i < min((uint32)TTYPE_MAX, ef->m_HWTechniques.size()); i++) - { - if (!ef->GetUsedTextureSlots(i)) - { - ef->m_ShaderTexSlots[i] = GetTextureSlots(Parser, pBin, ef, i, -1); - } - } - - for (uint32 i = 0; i < min((uint32)TTYPE_MAX, ef->m_HWTechniques.size()); i++) - { - if (ef->m_ShaderTexSlots[i]) - { - SShaderTechParseParams* linkedTechs = &techParams[i]; - - // look through linked techniques (e.g. general has links to zpass, shadowgen, etc) - for (int j = 0; j < TTYPE_MAX; j++) - { - // if we have a linked technique - if (!linkedTechs->techName[j].empty()) - { - // find it in our technique list - for (int k = 0; k < ef->m_HWTechniques.size(); k++) - { - if (linkedTechs->techName[j] == ef->m_HWTechniques[k]->m_NameStr) - { - // merge slots - any slots that are empty in the master will be filled with the overlay - // This leaves the general/main technique authoratitve on slots, but stops slots disappearing - // if they're still used in some sub-pass - MergeTextureSlots(ef->m_ShaderTexSlots[i], ef->m_ShaderTexSlots[k]); - break; - } - } - } - } - } - } -#endif - - g_fTimeA += iTimer->GetAsyncCurTime() - fTimeA; - - return bRes; -#endif -} - -void CShaderManBin::MergeTextureSlots(SShaderTexSlots* master, SShaderTexSlots* overlay) -{ - if (!master || !overlay) - { - return; - } - /* [Shader System] - TO DO: switch back to the map usage and replace with this - for (auto& iter : overlay->m_UsedTextureSlots) - { - auto masterIter = master->m_UsedTextureSlots.find(iter->first); - if (masterIter == master->m_UsedTextureSlots.end()) // slot was not found - insert the overlay one - { - // these structures are never deleted so we can safely share pointers - // without ref counting. See below in GetTextureSlots for the allocation - master->m_UsedTextureSlots[iter->first] = iter->second; - } - } -*/ - // [Shader System] - TO DO - replace this part with code above after testing - for (int i = 0; i < EFTT_MAX; i++) - { - // these structures are never deleted so we can safely share pointers - // without ref counting. See below in GetTextureSlots for the allocation - if (master->m_UsedTextureSlots[i] == NULL && overlay->m_UsedTextureSlots[i] != NULL) - { - master->m_UsedTextureSlots[i] = overlay->m_UsedTextureSlots[i]; - } - } -} - -// [Shader System TO DO] - this methods needs to be either removed or become full data driven -SShaderTexSlots* CShaderManBin::GetTextureSlots([[maybe_unused]] CParserBin& Parser, [[maybe_unused]] SShaderBin* pBin, [[maybe_unused]] CShader* ef, [[maybe_unused]] int nTech, int nPass) -{ -#if !SHADER_REFLECT_TEXTURE_SLOTS - return NULL; -#else - TArray referencedSamplers; - - bool bIterPasses = false; - int nMaxPasses = 1; - - if (nPass == -1) - { - bIterPasses = true; - nPass = 0; - } - - if (nTech < 0 || nPass < 0) - { - return NULL; - } - - // if the technique's pixel shader exists - if (ef->m_HWTechniques.size() && nTech < ef->m_HWTechniques.size() && - ef->m_HWTechniques[nTech]->m_Passes.size() && nPass < ef->m_HWTechniques[nTech]->m_Passes.size() && - ef->m_HWTechniques[nTech]->m_Passes[nPass].m_PShader) - { - if (bIterPasses) - { - nMaxPasses = ef->m_HWTechniques[nTech]->m_Passes.size(); - } - - for (int nPassIter = nPass; nPassIter < nMaxPasses; nPassIter++) - { - uint32 dwEntryFuncName = Parser.GetCRC32(ef->m_HWTechniques[nTech]->m_Passes[nPassIter].m_PShader->m_EntryFunc); - - // get the cached info for the entry func - SParamCacheInfo* pCache = GetParamInfo(pBin, dwEntryFuncName, ef->m_nMaskGenFX, ef->m_maskGenStatic); - - if (pCache) - { - // loop over affected fragments from this entry func - SParamCacheInfo::AffectedFuncsVec& AffectedFragments = pCache->m_AffectedFuncs; - for (uint32 i = 0; i < AffectedFragments.size(); i++) - { - SCodeFragment* s = &Parser.m_CodeFragments[AffectedFragments[i]]; - - // if it's a sampler, include this sampler name CRC - if (s->m_eType == eFT_Sampler) - { - referencedSamplers.AddElem(s->m_dwName); - } - } - } - else - { - return NULL; - } - } - } - else - { - return NULL; - } - - uint32 dependencySlots = 0; - - // check the gen params - SShaderGen* genParams = ef->GetGenerationParams(); - if (genParams) - { - for (uint32 i = 0; i < genParams->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = genParams->m_BitMask[i]; - if (!pBit || (!pBit->m_nDependencySet && !pBit->m_nDependencyReset)) - { - continue; - } - - // if any dependency set/reset is allowed for a texture, we must be conservative - // and count this slot as used - uint32 setReset = pBit->m_nDependencySet | pBit->m_nDependencyReset; - - // bitmask will fail if we have > 32 fixed texture slots - CRY_ASSERT(EFTT_MAX <= 32); - - if (setReset & SHGD_TEX_MASK) - { - if (setReset & SHGD_TEX_NORMALS) - { - dependencySlots |= 1 << EFTT_NORMALS; - } - - if (setReset & SHGD_TEX_HEIGHT) - { - dependencySlots |= 1 << EFTT_HEIGHT; - } - - if (setReset & SHGD_TEX_DETAIL) - { - dependencySlots |= 1 << EFTT_DETAIL_OVERLAY; - } - - if (setReset & SHGD_TEX_SECOND_SMOOTHNESS) - { - dependencySlots |= 1 << EFTT_SECOND_SMOOTHNESS; - } - - if (setReset & SHGD_TEX_SPECULAR) - { - dependencySlots |= 1 << EFTT_SPECULAR; - } - - if (setReset & SHGD_TEX_ENVCM) - { - dependencySlots |= 1 << EFTT_ENV; - } - - if (setReset & SHGD_TEX_SUBSURFACE) - { - dependencySlots |= 1 << EFTT_SUBSURFACE; - } - - if (setReset & SHGD_TEX_DECAL) - { - dependencySlots |= 1 << EFTT_DECAL_OVERLAY; - } - - if (setReset & SHGD_TEX_CUSTOM) - { - dependencySlots |= 1 << EFTT_CUSTOM; - } - - if (setReset & SHGD_TEX_CUSTOM_SECONDARY) - { - dependencySlots |= 1 << EFTT_CUSTOM_SECONDARY; - } - - if (setReset & SHGD_TEX_OCC) - { - dependencySlots |= 1 << EFTT_OCCLUSION; - } - - if (setReset & SHGD_TEX_SPECULAR_2) - { - dependencySlots |= 1 << EFTT_SPECULAR_2; - } - - if (setReset & SHGD_TEX_EMITTANCE) - { - // Both emittance and decal overlay (emissive intensity) are set by SHGD_TEX_EMITTANCE - dependencySlots |= 1 << EFTT_EMITTANCE; - dependencySlots |= 1 << EFTT_DECAL_OVERLAY; - } - } - } - } - else - { - return NULL; - } - - // since we might find samplers referencing a slot more than once, - // keep track of the priority of each sampler found. - int namePriority[EFTT_MAX]; // [Shader System TO DO] - data driven please! - memset(namePriority, 0, sizeof(namePriority)); - - // deliberately 'leaking', these are kept around permanently (this info is only gathered in the editor), - // and cleaned up at shutdown when the app memory is released. - SShaderTexSlots* pSlots = new SShaderTexSlots; - - // Priority order: - // 0 = forced in because of the dependency set as above, can be overridden if we find a better sampler - // 1 = referenced from the shader but doesn't include a UIName - // 2 = includes a UIName but isn't directly referenced. In the case we've forced the sampler because of dependency, - // this is probably more descriptive than a priority=1 sampler - // 3 = both from above, referenced and has UIName. We shouldn't find multiple samplers like this, shader samplers - // should be set up so only ever one sampler using a slot has a UIName. - enum - { - PRIORITY_REFERENCED = 0x1, PRIORITY_HASUINAME = 0x2 - }; - - SShaderFXParams& FXP = mfGetFXParams(ef); - - // loop over all samplers for this shader - FXSamplersOldIt it = FXP.m_FXSamplersOld.begin(); - FXSamplersOldIt end = FXP.m_FXSamplersOld.end(); - for (; it != end; ++it) - { - int slot = it->m_nSlotId; - - // if the slot is invalid this texture refers something else, skip it - if (slot == EFTT_MAX) // [Shader System TO DO] - data driven - { - continue; - } - - uint32 dwName = Parser.GetCRC32(it->m_szName); - - // check if this sampler must be included for dependency set/reset reasons - bool dependency = (dependencySlots & (1 << slot)) > 0; - - // check if this sampler is referenced from the shader - bool referenced = referencedSamplers.Find(dwName) >= 0; - - if (dependency || referenced) - { - // calculate priority. See above. - int priority = (referenced ? PRIORITY_REFERENCED : 0) | (it->m_szUIName.length() ? PRIORITY_HASUINAME : 0); - SShaderTextureSlot* pUsedTexSlot = pSlots->m_UsedTextureSlots[slot]; - - // if we don't have this slot filled yet, create a new slot - if (!pUsedTexSlot) - { - // !!IMPORTANT!! - if these slots are deleted/cleaned instead of being allowed to live forever, - // MAKE SURE you refcount or refactor MergeTextureSlots above - as it will share pointers. - pUsedTexSlot = new SShaderTextureSlot; - - pUsedTexSlot->m_Name = it->m_szUIName; - pUsedTexSlot->m_Description = it->m_szUIDescription; - pUsedTexSlot->m_TexType = it->m_eTexType; - - // store current priority - namePriority[slot] = priority; - pSlots->m_UsedTextureSlots[slot] = pUsedTexSlot; // insertion to the map - } - else - { - // we shouldn't encounter two samplers that are used and have a UIName for the same slot, - // error in this case - if (priority == (PRIORITY_REFERENCED | PRIORITY_HASUINAME) && priority == namePriority[slot]) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Encountered two samplers with UINames referenced for same slot in shader '%s': '%s' and '%s'\n", - ef->GetName(), pUsedTexSlot->m_Name.c_str(), it->m_szUIName.c_str()); - CRY_ASSERT(0); - } - // override if we have a higher priority - else if (priority > namePriority[slot]) - { - pUsedTexSlot->m_Name = it->m_szUIName; - pUsedTexSlot->m_Description = it->m_szUIDescription; - pUsedTexSlot->m_TexType = it->m_eTexType; - - namePriority[slot] = priority; - } - } - } - } - - return pSlots; -#endif -} - -bool CShaderManBin::ParseBinFX_Dummy(SShaderBin* pBin, std::vector& ShaderNames, const char* szName) -{ - bool bRes = true; - CParserBin Parser(pBin, NULL); - - pBin->Lock(); - bool preprocessResult = Parser.Preprocess(0, pBin->m_Tokens, &pBin->m_TokenTable); - pBin->Unlock(); - - if(!preprocessResult) - { - // Preprocess already outputs an error, no need to do so here. - return false; - } - - SParserFrame Frame(0, Parser.m_Tokens.size() - 1); - Parser.BeginFrame(Frame); - - FX_BEGIN_TOKENS - FX_TOKEN(static) - FX_TOKEN(half) - FX_TOKEN(half2) - FX_TOKEN(half3) - FX_TOKEN(half4) - FX_TOKEN(half2x4) - FX_TOKEN(half3x4) - FX_TOKEN(half4x4) - FX_TOKEN(float) - FX_TOKEN(float2) - FX_TOKEN(float3) - FX_TOKEN(float4) - FX_TOKEN(float2x4) - FX_TOKEN(float3x4) - FX_TOKEN(float4x4) - FX_TOKEN(bool) - FX_TOKEN(int) - FX_TOKEN(Buffer) - FX_TOKEN(RWBuffer) - FX_TOKEN(StructuredBuffer) - FX_TOKEN(RWStructuredBuffer) - FX_TOKEN(cbuffer) - FX_TOKEN(struct) - FX_TOKEN(sampler1D) - FX_TOKEN(sampler2D) - FX_TOKEN(sampler3D) - FX_TOKEN(samplerCUBE) - FX_TOKEN(technique) - FX_TOKEN(SamplerState) - FX_TOKEN(SamplerComparisonState) - FX_TOKEN(Texture2D) - FX_TOKEN(RWTexture2D) - FX_TOKEN(RWTexture2DArray) - FX_TOKEN(Texture2DArray) - FX_TOKEN(Texture2DMS) - FX_TOKEN(TextureCube) - FX_TOKEN(TextureCubeArray) - FX_TOKEN(Texture3D) - FX_TOKEN(RWTexture3D) - FX_TOKEN(RasterizerOrderedBuffer) - FX_TOKEN(RasterizerOrderedByteAddressBuffer) - FX_TOKEN(RasterizerOrderedStructuredBuffer) - FX_END_TOKENS - - std::vector techParams; - CCryNameR techStart[2]; - bool bPublic = false; - std::vector PubTechniques; - - ETokenStorageClass nTokenStorageClass; - - nTokenStorageClass = Parser.ParseObject(sCommands); - while (nTokenStorageClass) - { - EToken eT = Parser.GetToken(); - SCodeFragment Fr; - switch (eT) - { - case eT_half: - case eT_float: - if (!Parser.m_Assign.IsEmpty() && Parser.GetToken(Parser.m_Assign) == eT_STANDARDSGLOBAL) - { - ParseBinFX_Global(Parser, Parser.m_Annotations, &bPublic, techStart); - } - break; - case eT_Buffer: - case eT_RWBuffer: - case eT_StructuredBuffer: - case eT_RWStructuredBuffer: - case eT_cbuffer: - case eT_struct: - case eT_SamplerState: - case eT_SamplerComparisonState: - case eT_int: - case eT_bool: - - case eT_half2: - case eT_half3: - case eT_half4: - case eT_half2x4: - case eT_half3x4: - case eT_half4x4: - - case eT_float2: - case eT_float3: - case eT_float4: - case eT_float2x4: - case eT_float3x4: - case eT_float4x4: - - case eT_Texture2D: - case eT_RWTexture2D: - case eT_Texture2DMS: - case eT_Texture2DArray: - case eT_RWTexture2DArray: - case eT_TextureCube: - case eT_TextureCubeArray: - case eT_Texture3D: - case eT_RWTexture3D: - case eT_sampler1D: - case eT_sampler2D: - case eT_sampler3D: - case eT_samplerCUBE: - case eT_RasterizerOrderedBuffer: - case eT_RasterizerOrderedByteAddressBuffer: - case eT_RasterizerOrderedStructuredBuffer: - break; - - case eT_technique: - { - uint32 nToken = Parser.m_Tokens[Parser.m_Name.m_nFirstToken]; - bool bPublicTechnique = false; - ParseBinFX_Technique(Parser, Parser.m_Data, Parser.m_Annotations, techParams, &bPublicTechnique); - if (bPublicTechnique) - { - const char* name = Parser.GetString(nToken); - PubTechniques.push_back(name); - } - } - break; - - default: - CRY_ASSERT(0); - } - nTokenStorageClass = Parser.ParseObject(sCommands); - } - - if (bPublic) - { - ShaderNames.push_back(szName); - } - if (PubTechniques.size()) - { - uint32 i; - for (i = 0; i < PubTechniques.size(); i++) - { - string str = szName; - str += "."; - str += PubTechniques[i]; - ShaderNames.push_back(str); - } - } - - return bRes; -} - -inline bool CompareInstParams(const SCGParam& a, const SCGParam& b) -{ - return (a.m_RegisterOffset < b.m_RegisterOffset); -} - -void CShaderMan::mfPostLoadFX(CShader* ef, std::vector& techParams, [[maybe_unused]] CCryNameR techStart[2]) -{ - ef->m_HWTechniques.Shrink(); - - uint32 i; - - CRY_ASSERT(techParams.size() == ef->m_HWTechniques.Num()); - for (i = 0; i < ef->m_HWTechniques.Num(); i++) - { - SShaderTechnique* hw = ef->m_HWTechniques[i]; - SShaderTechParseParams* ps = &techParams[i]; - uint32 n; - for (n = 0; n < TTYPE_MAX; n++) - { - if (ps->techName[n].c_str()[0]) - { - if (hw->m_NameStr == ps->techName[n]) - { - iLog->LogWarning("WARN: technique '%s' refers to itself as the next technique (ignored)", hw->m_NameStr.c_str()); - } - else - { - uint32 j; - for (j = 0; j < ef->m_HWTechniques.Num(); j++) - { - SShaderTechnique* hw2 = ef->m_HWTechniques[j]; - if (hw2->m_NameStr == ps->techName[n]) - { - hw->m_nTechnique[n] = j; - break; - } - } - if (j == ef->m_HWTechniques.Num()) - { - iLog->LogWarning("WARN: couldn't find technique '%s' in the sequence for technique '%s' (ignored)", ps->techName[n].c_str(), hw->m_NameStr.c_str()); - } - } - } - } - - SShaderTechnique* hwZWrite = (hw->m_nTechnique[TTYPE_Z] >= 0) ? ef->m_HWTechniques[hw->m_nTechnique[TTYPE_Z]] : NULL; - hwZWrite = (hw->m_nTechnique[TTYPE_ZPREPASS] >= 0) ? ef->m_HWTechniques[hw->m_nTechnique[TTYPE_ZPREPASS]] : hwZWrite; - if (hwZWrite && hwZWrite->m_Passes.Num()) - { - SShaderPass* pass = &hwZWrite->m_Passes[0]; - if (pass->m_RenderState & GS_DEPTHWRITE) - { - hw->m_Flags |= FHF_WASZWRITE; - } - } - - bool bTransparent = true; - for (uint32 j = 0; j < hw->m_Passes.Num(); j++) - { - SShaderPass* pass = &hw->m_Passes[j]; - if (CParserBin::PlatformSupportsGeometryShaders() && pass->m_GShader) - { - hw->m_Flags |= FHF_USE_GEOMETRY_SHADER; - } - if (CParserBin::PlatformSupportsHullShaders() && pass->m_HShader) - { - hw->m_Flags |= FHF_USE_HULL_SHADER; - } - if (CParserBin::PlatformSupportsDomainShaders() && pass->m_DShader) - { - hw->m_Flags |= FHF_USE_DOMAIN_SHADER; - } - if (!(pass->m_RenderState & GS_BLEND_MASK)) - { - bTransparent = false; - } - } - if (bTransparent) - { - hw->m_Flags |= FHF_TRANSPARENT; - } - } -} - -//=========================================================================================== - -void STexSamplerRT::Update() -{ - if (m_pAnimInfo && m_pAnimInfo->m_Time && gRenDev->m_bPauseTimer == 0) - { - CRY_ASSERT(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime >= 0); - uint32 m = (uint32)(gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime / m_pAnimInfo->m_Time) % (m_pAnimInfo->m_NumAnimTexs); - CRY_ASSERT(m < (uint32)m_pAnimInfo->m_TexPics.Num()); - - if (m_pTex && (m_pTex != m_pAnimInfo->m_TexPics[m])) - { - m_pTex->Release(); - - m_pTex = m_pAnimInfo->m_TexPics[m]; - - m_pTex->AddRef(); - } - } -} - -void SFXParam::GetCompName(uint32 nId, CryFixedStringT<128>& name) -{ - if (nId < 0 || nId > 3) - { - name = ""; - return; - } - - char nm[16]; - sprintf_s(nm, "__%d", nId); - const char* s = strstr(m_Name.c_str(), nm); - - if (!s) - { - name = ""; - return; - } - - s += 3; - - uint32 n; - for (n = 0; s[n] != 0; ++n) - { - if (s[n] <= 0x20 || (s[n] == '_' && s[n + 1] == '_')) - { - break; - } - } - name.append(s, n); -} - -void SFXParam::GetParamComp(uint32 nOffset, CryFixedStringT<128>& param) -{ - const char* szValue = m_Values.c_str(); - - if (!szValue[0]) - { - param = ""; - return; - } - - if (szValue[0] == '{') - { - ++szValue; - } - - for (uint32 n = 0; n != nOffset; ++n) - { - while (szValue[0] != ',' && szValue[0] != ';' && szValue[0] != '}' && szValue[0] != 0) - { - ++szValue; - } - - if (szValue[0] == ';' || szValue[0] == '}' || szValue[0] == 0) - { - param = ""; - return; - } - - ++szValue; - } - - while (*szValue == ' ' || *szValue == 8) - { - ++szValue; - } - - uint32 n; - for (n = 0; szValue[n] != 0; ++n) - { - if (szValue[n] == ',' || szValue[n] == ';' || szValue[n] == '}') - { - break; - } - } - param.append(szValue, n); -} - -string SFXParam::GetValueForName(const char* szName, EParamType& eType) -{ - eType = eType_UNKNOWN; - if (m_Annotations.empty()) - { - return ""; - } - - char buf[256]; - char tok[128]; - char* szA = (char*)m_Annotations.c_str(); - SkipCharacters(&szA, kWhiteSpace); - while (true) - { - if (!fxFill(&szA, buf)) - { - break; - } - char* b = buf; - fxFillPr(&b, tok); - eType = eType_UNKNOWN; - if (!azstricmp(tok, "string")) - { - eType = eType_STRING; - } - else - if (!azstricmp(tok, "float")) - { - eType = eType_FLOAT; - } - else - if (!azstricmp(tok, "half")) - { - eType = eType_HALF; - } - - if (eType != eType_UNKNOWN) - { - if (!fxFillPr(&b, tok)) - { - continue; - } - if (azstricmp(tok, szName)) - { - continue; - } - SkipCharacters(&b, kWhiteSpace); - if (b[0] == '=') - { - b++; - if (!fxFillPrC(&b, tok)) - { - break; - } - } - return tok; - } - else - { - if (azstricmp(tok, szName)) - { - continue; - } - eType = eType_STRING; - if (!fxFillPr(&b, tok)) - { - continue; - } - if (tok[0] == '=') - { - if (!fxFillPr(&b, tok)) - { - break; - } - } - return tok; - } - } - - return ""; -} - -const char* CShaderMan::mfParseFX_Parameter (const string& script, EParamType eType, const char* szName) -{ - static char sRet[128]; - int nLen = script.length(); - char* pTemp = new char [nLen + 1]; - azstrcpy(pTemp, nLen + 1, script.c_str()); - sRet[0] = 0; - char* buf = pTemp; - - char* name; - long cmd; - char* data; - - enum - { - eString = 1 - }; - - static STokenDesc commands[] = - { - {eString, "String"}, - - {0, 0} - }; - - while ((cmd = shGetObject (&buf, commands, &name, &data)) > 0) - { - switch (cmd) - { - case eString: - { - if (eType != eType_STRING) - { - break; - } - char* szScr = data; - if (*szScr == '"') - { - szScr++; - } - int n = 0; - while (szScr[n] != 0) - { - if (szScr[n] == '"') - { - szScr[n] = ' '; - } - n++; - } - if (!azstricmp(szName, name)) - { - azstrcpy(sRet, AZ_ARRAY_SIZE(sRet), data); - break; - } - } - break; - } - } - - SAFE_DELETE_ARRAY(pTemp); - - if (sRet[0]) - { - return sRet; - } - else - { - return NULL; - } -} - -//------------------------------------------------------------------------------ -// Searches the constant params array for a desired constant based on name. -// Can be optimized if has performance hit. -//------------------------------------------------------------------------------ -SFXParam* CShaderMan::mfGetFXParameter(std::vector& Params, const char* param) -{ - uint32 j; - for (j = 0; j < Params.size(); j++) - { - SFXParam* pr = &Params[j]; - char nameParam[256]; - int n = 0; - const char* szSrc = pr->m_Name.c_str(); - while (*szSrc != 0) - { - if (*szSrc == '[') - { - break; - } - nameParam[n++] = *szSrc; - szSrc++; - } - nameParam[n] = 0; - if (!azstricmp(nameParam, param)) - { - return pr; - } - } - return NULL; -} - -//------------------------------------------------------------------------------ -// Searches the samplers params array for a desired sampler based on name. -// Can be optimized if has performance hit. -//------------------------------------------------------------------------------ -SFXSampler* CShaderMan::mfGetFXSampler(std::vector& Params, const char* param) -{ - uint32 j; - for (j = 0; j < Params.size(); j++) - { - SFXSampler* pr = &Params[j]; - char nameParam[256]; - int n = 0; - const char* szSrc = pr->m_Name.c_str(); - while (*szSrc != 0) - { - if (*szSrc == '[') - { - break; - } - nameParam[n++] = *szSrc; - szSrc++; - } - nameParam[n] = 0; - if (!azstricmp(nameParam, param)) - { - return pr; - } - } - return NULL; -} - -//------------------------------------------------------------------------------ -// Searches the texture params array for a desired texture based on name. -// Can be optimized if has performance hit. -//------------------------------------------------------------------------------ -SFXTexture* CShaderMan::mfGetFXTexture(std::vector& Params, const char* param) -{ - uint32 j; - for (j = 0; j < Params.size(); j++) - { - SFXTexture* pr = &Params[j]; - char nameParam[256]; - int n = 0; - const char* szSrc = pr->m_Name.c_str(); - while (*szSrc != 0) - { - if (*szSrc == '[') - { - break; - } - nameParam[n++] = *szSrc; - szSrc++; - } - nameParam[n] = 0; - if (!azstricmp(nameParam, param)) - { - return pr; - } - } - return NULL; -} - - -// We have to parse part of the shader to enumerate public techniques -bool CShaderMan::mfAddFXShaderNames(const char* szName, std::vector* ShaderNames, bool bUpdateCRC) -{ - bool bRes = true; - SShaderBin* pBin = m_Bin.GetBinShader(szName, false, 0); - if (!pBin) - { - return false; - } - if (bUpdateCRC) - { - uint32 nCRC32 = pBin->ComputeCRC(); - if (nCRC32 != pBin->m_CRC32) - { - FXShaderBinValidCRCItor itor = gRenDev->m_cEF.m_Bin.m_BinValidCRCs.find(pBin->m_dwName); - if (itor == gRenDev->m_cEF.m_Bin.m_BinValidCRCs.end()) - { - gRenDev->m_cEF.m_Bin.m_BinValidCRCs.insert(FXShaderBinValidCRCItor::value_type(pBin->m_dwName, false)); - } - - m_Bin.DeleteFromCache(pBin); - pBin = m_Bin.GetBinShader(szName, false, nCRC32); - if (!pBin) - { - return false; - } - } - } - - // Do not parse techniques for consoles - if (ShaderNames) - { - bRes &= m_Bin.ParseBinFX_Dummy(pBin, *ShaderNames, szName); - } - - return bRes; -} - -CTexture* CShaderMan::mfParseFXTechnique_LoadShaderTexture (STexSamplerRT* smp, const char* szName, [[maybe_unused]] SShaderPass* pShPass, [[maybe_unused]] CShader* ef, [[maybe_unused]] int nIndex, [[maybe_unused]] byte ColorOp, [[maybe_unused]] byte AlphaOp, [[maybe_unused]] byte ColorArg, [[maybe_unused]] byte AlphaArg) -{ - CTexture* tp = NULL; - if (!szName || !szName[0] || gRenDev->m_bShaderCacheGen) // Sampler without texture specified - { - return NULL; - } - - if (szName[0] == '$') - { - tp = mfCheckTemplateTexName(szName, (ETEX_Type)smp->m_eTexType); - if (tp) - { - tp->AddRef(); - } - } - else - { - smp->m_nTexFlags |= FT_DONT_STREAM; // disable streaming for explicitly specified textures - } - if (!tp) - { - tp = mfTryToLoadTexture(szName, smp, smp->GetTexFlags(), false); - } - - return tp; -} - diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderParse.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderParse.cpp deleted file mode 100644 index 9ba4abc9a8..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderParse.cpp +++ /dev/null @@ -1,851 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : implementation of the Shaders parser part of shaders manager. - - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "CryHeaders.h" -#include "CryPath.h" -#include - -#if defined(WIN32) || defined(WIN64) -#include -#include -#elif defined(LINUX) -#endif - - -//============================================================ -// Compile functions -//============================================================ - -SShaderGenBit* CShaderMan::mfCompileShaderGenProperty(char* scr) -{ - char* name; - long cmd; - char* params; - char* data; - - SShaderGenBit* shgm = new SShaderGenBit; - - enum - { - eName = 1, eProperty, eDescription, eMask, eHidden, eRuntime, ePrecache, eDependencySet, eDependencyReset, eDependFlagSet, eDependFlagReset, eAutoPrecache, eLowSpecAutoPrecache - }; - static STokenDesc commands[] = - { - {eName, "Name"}, - {eProperty, "Property"}, - {eDescription, "Description"}, - {eMask, "Mask"}, - {eHidden, "Hidden"}, - {ePrecache, "Precache"}, - {eRuntime, "Runtime"}, - {eAutoPrecache, "AutoPrecache"}, - {eLowSpecAutoPrecache, "LowSpecAutoPrecache"}, - {eDependencySet, "DependencySet"}, - {eDependencyReset, "DependencyReset"}, - {eDependFlagSet, "DependFlagSet"}, - {eDependFlagReset, "DependFlagReset"}, - - {0, 0} - }; - - shgm->m_PrecacheNames.reserve(45); - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eName: - shgm->m_ParamName = data; - shgm->m_dwToken = CCrc32::Compute(data); - break; - - case eProperty: - if (gRenDev->IsEditorMode()) - { - shgm->m_ParamProp = data; - } - break; - - case eDescription: - if (gRenDev->IsEditorMode()) - { - shgm->m_ParamDesc = data; - } - break; - - case eHidden: - shgm->m_Flags |= SHGF_HIDDEN; - break; - - case eRuntime: - shgm->m_Flags |= SHGF_RUNTIME; - break; - - case eAutoPrecache: - shgm->m_Flags |= SHGF_AUTO_PRECACHE; - break; - case eLowSpecAutoPrecache: - shgm->m_Flags |= SHGF_LOWSPEC_AUTO_PRECACHE; - break; - - case ePrecache: - shgm->m_PrecacheNames.push_back(CParserBin::GetCRC32(data)); - shgm->m_Flags |= SHGF_PRECACHE; - break; - - case eDependFlagSet: - shgm->m_DependSets.push_back(data); - break; - - case eDependFlagReset: - shgm->m_DependResets.push_back(data); - break; - - case eMask: - if (data && data[0]) - { - if (data[0] == '0' && (data[1] == 'x' || data[1] == 'X')) - { - shgm->m_Mask = shGetHex64(&data[2]); - } - else - { - shgm->m_Mask = shGetInt(data); - } - } - break; - - case eDependencySet: - if (data && data[0]) - { - if (!azstricmp(data, "$LM_Diffuse")) - { - shgm->m_nDependencySet |= SHGD_LM_DIFFUSE; - } - else - if (!azstricmp(data, "$TEX_Detail")) - { - shgm->m_nDependencySet |= SHGD_TEX_DETAIL; - } - else - if (!azstricmp(data, "$TEX_Normals")) - { - shgm->m_nDependencySet |= SHGD_TEX_NORMALS; - } - else - if (!azstricmp(data, "$TEX_Height")) - { - shgm->m_nDependencySet |= SHGD_TEX_HEIGHT; - } - else - if (!azstricmp(data, "$TEX_SecondSmoothness")) - { - shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else - if (!azstricmp(data, "$TEX_Specular")) - { - shgm->m_nDependencySet |= SHGD_TEX_SPECULAR; - } - else - if (!azstricmp(data, "$TEX_EnvCM")) - { - shgm->m_nDependencySet |= SHGD_TEX_ENVCM; - } - else - if (!azstricmp(data, "$TEX_Subsurface")) - { - shgm->m_nDependencySet |= SHGD_TEX_SUBSURFACE; - } - else - if (!azstricmp(data, "$HW_BilinearFP16")) - { - shgm->m_nDependencySet |= SHGD_HW_BILINEARFP16; - } - else - if (!azstricmp(data, "$HW_SeparateFP16")) - { - shgm->m_nDependencySet |= SHGD_HW_SEPARATEFP16; - } - else - if (!azstricmp(data, "$TEX_Custom")) - { - shgm->m_nDependencySet |= SHGD_TEX_CUSTOM; - } - else - if (!azstricmp(data, "$TEX_CustomSecondary")) - { - shgm->m_nDependencySet |= SHGD_TEX_CUSTOM_SECONDARY; - } - else - if (!azstricmp(data, "$TEX_Occ")) - { - shgm->m_nDependencySet |= SHGD_TEX_OCC; - } - else - if (!azstricmp(data, "$HW_WaterTessellation")) - { - shgm->m_nDependencySet |= SHGD_HW_WATER_TESSELLATION; - } - else - if (!azstricmp(data, "$HW_SilhouettePom")) - { - shgm->m_nDependencySet |= SHGD_HW_SILHOUETTE_POM; - } - else - if (!azstricmp(data, "$HW_SpecularAntialiasing")) - { - shgm->m_nDependencySet |= SHGD_HW_SAA; - } - else - if (!azstricmp(data, "$UserEnabled")) - { - shgm->m_nDependencySet |= SHGD_USER_ENABLED; - } - else - if (!azstricmp(data, "$HW_ORBIS")) - { - shgm->m_nDependencySet |= SHGD_HW_ORBIS; - } - else - if (!azstricmp(data, "$HW_DX11")) - { - shgm->m_nDependencySet |= SHGD_HW_DX11; - } - else - if (!azstricmp(data, "$HW_GL4")) - { - shgm->m_nDependencySet |= SHGD_HW_GL4; - } - else - if (!azstricmp(data, "$HW_GLES3")) - { - shgm->m_nDependencySet |= SHGD_HW_GLES3; - } - else - if (!azstricmp(data, "$TEX_Emittance")) - { - shgm->m_nDependencySet |= SHGD_TEX_EMITTANCE; - } - - // backwards compatible names - else if (!azstricmp(data, "$HW_METAL")) - { - shgm->m_nDependencySet |= SHGD_HW_METAL; - } - else if (!azstricmp(data, "$TEX_Bump")) - { - shgm->m_nDependencySet |= SHGD_TEX_NORMALS; - } - else if (!azstricmp(data, "$TEX_BumpHeight")) - { - shgm->m_nDependencySet |= SHGD_TEX_HEIGHT; - } - else if (!azstricmp(data, "$TEX_Translucency")) - { - shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else if (!azstricmp(data, "$TEX_BumpDif")) - { - shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else if (!azstricmp(data, "$TEX_Gloss")) - { - shgm->m_nDependencySet |= SHGD_TEX_SPECULAR; - } - - else - { - assert(0); - } - } - break; - - case eDependencyReset: - if (data && data[0]) - { - if (!azstricmp(data, "$LM_Diffuse")) - { - shgm->m_nDependencyReset |= SHGD_LM_DIFFUSE; - } - else - if (!azstricmp(data, "$TEX_Detail")) - { - shgm->m_nDependencyReset |= SHGD_TEX_DETAIL; - } - else - if (!azstricmp(data, "$TEX_Normals")) - { - shgm->m_nDependencyReset |= SHGD_TEX_NORMALS; - } - else - if (!azstricmp(data, "$TEX_Height")) - { - shgm->m_nDependencyReset |= SHGD_TEX_HEIGHT; - } - else - if (!azstricmp(data, "$TEX_SecondSmoothness")) - { - shgm->m_nDependencyReset |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else - if (!azstricmp(data, "$TEX_Specular")) - { - shgm->m_nDependencyReset |= SHGD_TEX_SPECULAR; - } - else - if (!azstricmp(data, "$TEX_EnvCM")) - { - shgm->m_nDependencyReset |= SHGD_TEX_ENVCM; - } - else - if (!azstricmp(data, "$TEX_Subsurface")) - { - shgm->m_nDependencyReset |= SHGD_TEX_SUBSURFACE; - } - else - if (!azstricmp(data, "$HW_BilinearFP16")) - { - shgm->m_nDependencyReset |= SHGD_HW_BILINEARFP16; - } - else - if (!azstricmp(data, "$HW_SeparateFP16")) - { - shgm->m_nDependencyReset |= SHGD_HW_SEPARATEFP16; - } - else - if (!azstricmp(data, "$TEX_Custom")) - { - shgm->m_nDependencyReset |= SHGD_TEX_CUSTOM; - } - else - if (!azstricmp(data, "$TEX_CustomSecondary")) - { - shgm->m_nDependencyReset |= SHGD_TEX_CUSTOM_SECONDARY; - } - else - if (!azstricmp(data, "$TEX_Occ")) - { - shgm->m_nDependencyReset |= SHGD_TEX_OCC; - } - else - if (!azstricmp(data, "$TEX_Decal")) - { - shgm->m_nDependencyReset |= SHGD_TEX_DECAL; - } - else - if (!azstricmp(data, "$HW_WaterTessellation")) - { - shgm->m_nDependencyReset |= SHGD_HW_WATER_TESSELLATION; - } - else - if (!azstricmp(data, "$HW_SilhouettePom")) - { - shgm->m_nDependencyReset |= SHGD_HW_SILHOUETTE_POM; - } - else - if (!azstricmp(data, "$HW_SpecularAntialiasing")) - { - shgm->m_nDependencyReset |= SHGD_HW_SAA; - } - else - if (!azstricmp(data, "$UserEnabled")) - { - shgm->m_nDependencyReset |= SHGD_USER_ENABLED; - } - else - if (!azstricmp(data, "$HW_DX11")) - { - shgm->m_nDependencyReset |= SHGD_HW_DX11; - } - else - if (!azstricmp(data, "$HW_GL4")) - { - shgm->m_nDependencyReset |= SHGD_HW_GL4; - } - else - if (!azstricmp(data, "$HW_GLES3")) - { - shgm->m_nDependencyReset |= SHGD_HW_GLES3; - } - else - if (!azstricmp(data, "$HW_METAL")) - { - shgm->m_nDependencyReset |= SHGD_HW_METAL; - } - else - if (!azstricmp(data, "$HW_ORBIS")) - { - shgm->m_nDependencyReset |= SHGD_HW_ORBIS; - } - else - if (!azstricmp(data, "$TEX_Emittance")) - { - shgm->m_nDependencyReset |= SHGD_TEX_EMITTANCE; - } - - // backwards compatible names - else - if (!azstricmp(data, "$TEX_Bump")) - { - shgm->m_nDependencySet |= SHGD_TEX_NORMALS; - } - else - if (!azstricmp(data, "$TEX_BumpHeight")) - { - shgm->m_nDependencySet |= SHGD_TEX_HEIGHT; - } - else - if (!azstricmp(data, "$TEX_Translucency")) - { - shgm->m_nDependencyReset |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else - if (!azstricmp(data, "$TEX_BumpDif")) - { - shgm->m_nDependencySet |= SHGD_TEX_SECOND_SMOOTHNESS; - } - else - if (!azstricmp(data, "$TEX_Gloss")) - { - shgm->m_nDependencySet |= SHGD_TEX_SPECULAR; - } - - else - { - assert(0); - } - } - break; - } - } - shgm->m_NameLength = strlen(shgm->m_ParamName.c_str()); - - return shgm; -} - -bool CShaderMan::mfCompileShaderGen(SShaderGen* shg, char* scr) -{ - char* name; - long cmd; - char* params; - char* data; - - SShaderGenBit* shgm; - - enum - { - eProperty = 1, eVersion, eUsesCommonGlobalFlags - }; - static STokenDesc commands[] = - { - {eProperty, "Property"}, - {eVersion, "Version"}, - {eUsesCommonGlobalFlags, "UsesCommonGlobalFlags"}, - {0, 0} - }; - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eProperty: - shgm = mfCompileShaderGenProperty(params); - if (shgm) - { - shg->m_BitMask.AddElem(shgm); - } - break; - - case eUsesCommonGlobalFlags: - break; - - case eVersion: - break; - } - } - - return shg->m_BitMask.Num() != 0; -} - -void CShaderMan::mfCompileLevelsList(std::vector& List, char* scr) -{ - char* name; - long cmd; - char* params; - char* data; - - enum - { - eName = 1, eVersion - }; - static STokenDesc commands[] = - { - {eName, "Name"}, - {0, 0} - }; - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eName: - if (data && data[0]) - { - List.push_back(string("Levels/") + string(data) + string("/")); - } - break; - } - } -} - -bool CShaderMan::mfCompileShaderLevelPolicies(SShaderLevelPolicies* pPL, char* scr) -{ - char* name; - long cmd; - char* params; - char* data; - - enum - { - eGlobalList = 1, ePerLevelList, eVersion - }; - static STokenDesc commands[] = - { - {eGlobalList, "GlobalList"}, - {ePerLevelList, "PerLevelList"}, - {eVersion, "Version"}, - {0, 0} - }; - - while ((cmd = shGetObject (&scr, commands, &name, ¶ms)) > 0) - { - data = NULL; - if (name) - { - data = name; - } - else - if (params) - { - data = params; - } - - switch (cmd) - { - case eGlobalList: - mfCompileLevelsList(pPL->m_WhiteGlobalList, params); - break; - case ePerLevelList: - mfCompileLevelsList(pPL->m_WhitePerLevelList, params); - break; - - case eVersion: - break; - } - } - - return pPL->m_WhiteGlobalList.size() != 0; -} - -string CShaderMan::mfGetShaderBitNamesFromMaskGen(const char* szFileName, uint64 nMaskGen) -{ - // debug/helper function: returns ShaderGen bit names string based on nMaskGen - - if (!nMaskGen) - { - return "NO_FLAGS"; - } - - string pszShaderName = PathUtil::GetFileName(szFileName); - pszShaderName.MakeUpper(); - - ShaderMapNameFlagsItor pShaderRmp = m_pShadersGlobalFlags.find(pszShaderName.c_str()); - if (pShaderRmp == m_pShadersGlobalFlags.end() || !pShaderRmp->second) - { - return "NO_FLAGS"; - } - - string pszShaderBitNames; - - // get shader bit names - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin(); - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - for (; pIter != pEnd; ++pIter) - { - if (nMaskGen & pIter->second) - { - pszShaderBitNames += pIter->first.c_str(); - } - } - - return pszShaderBitNames; -} - -void CShaderMan::mfRemapShaderGenInfoBits(const char* szName, SShaderGen* pShGen) -{ - // No data to proceed - if (!pShGen || pShGen->m_BitMask.empty()) - { - return; - } - - // Check if shader uses common flags at all - string pszShaderName = PathUtil::GetFileName(szName); - pszShaderName.MakeUpper(); - if ((int32) m_pShadersRemapList.find(pszShaderName.c_str()) < 0) - { - return; - } - - MapNameFlags* pOldShaderFlags = 0; - if (m_pShadersGlobalFlags.find(pszShaderName.c_str()) == m_pShadersGlobalFlags.end()) - { - AZStd::unique_lock lock(m_shaderLoadMutex); - - pOldShaderFlags = new MapNameFlags; - m_pShadersGlobalFlags.insert(ShaderMapNameFlagsItor::value_type(pszShaderName.c_str(), pOldShaderFlags)); - } - - uint32 nBitCount = pShGen->m_BitMask.size(); - for (uint32 b = 0; b < nBitCount; ++b) - { - SShaderGenBit* pGenBit = pShGen->m_BitMask[b]; - if (!pGenBit) - { - continue; - } - - // Store old shader flags - if (pOldShaderFlags) - { - pOldShaderFlags->insert(MapNameFlagsItor::value_type(pGenBit->m_ParamName.c_str(), pGenBit->m_Mask)); - } - - // lookup for name - and update mask value - MapNameFlagsItor pRemaped = m_pShaderCommonGlobalFlag.find(pGenBit->m_ParamName.c_str()); - if (pRemaped != m_pShaderCommonGlobalFlag.end()) - { - pGenBit->m_Mask = pRemaped->second; - } - - } -} - -bool CShaderMan::mfUsesGlobalFlags(const char* szShaderName) -{ - // Check if shader uses common flags at all - string pszName = PathUtil::GetFileName(szShaderName); - - AZStd::unique_lock lock(m_shaderLoadMutex); - - string pszShaderNameUC = pszName; - pszShaderNameUC.MakeUpper(); - if ((int32) m_pShadersRemapList.find(pszShaderNameUC.c_str()) < 0) - { - return false; - } - - return true; -} - -uint64 CShaderMan::mfGetShaderGlobalMaskGenFromString(const char* szShaderGen) -{ - assert(szShaderGen); - if (!szShaderGen || szShaderGen[0] == '\0') - { - return 0; - } - - AZStd::unique_lock lock(m_shaderLoadMutex); - - uint64 nMaskGen = 0; - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - - char* pCurrOffset = (char*)szShaderGen; - while (pCurrOffset) - { - char* pBeginOffset = (char*)strstr(pCurrOffset, "%"); - assert(pBeginOffset); - PREFAST_ASSUME(pBeginOffset); - pCurrOffset = (char*)strstr(pBeginOffset + 1, "%"); - - char pCurrFlag[64] = "\0"; - int nLen = pCurrOffset ? pCurrOffset - pBeginOffset : strlen(pBeginOffset); - memcpy(pCurrFlag, pBeginOffset, nLen); - - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.find(pCurrFlag); - if (pIter != pEnd) - { - nMaskGen |= pIter->second; - } - } - - return nMaskGen; -} - -AZStd::string CShaderMan::mfGetShaderBitNamesFromGlobalMaskGen(uint64 nMaskGen) -{ - if (!nMaskGen) - { - return "\0"; - } - - AZStd::string shaderBitNames = "\0"; - MapNameFlagsItor pIter = m_pShaderCommonGlobalFlag.begin(); - MapNameFlagsItor pEnd = m_pShaderCommonGlobalFlag.end(); - for (; pIter != pEnd; ++pIter) - { - if (nMaskGen & pIter->second) - { - shaderBitNames += pIter->first.c_str(); - } - } - - return shaderBitNames; -} - -uint64 CShaderMan::mfGetRemapedShaderMaskGen(const char* szName, uint64 nMaskGen, bool bFixup) -{ - if (!nMaskGen) - { - return 0; - } - - AZStd::unique_lock lock(m_shaderLoadMutex); - - uint64 nMaskGenRemaped = 0; - string szShaderName = PathUtil::GetFileName(szName);// some shaders might be using concatenated names (eg: terrain.layer), get only first name - szShaderName.MakeUpper(); - ShaderMapNameFlagsItor pShaderRmp = m_pShadersGlobalFlags.find(szShaderName.c_str()); - - if (pShaderRmp == m_pShadersGlobalFlags.end() || !pShaderRmp->second) - { - return nMaskGen; - } - - if (bFixup) - { - // if some flag was removed, disable in mask - nMaskGen = nMaskGen & m_nSGFlagsFix; - return nMaskGen; - } - - // old bitmask - remap to common shared bitmasks - for (uint64 j = 0; j < 64; ++j) - { - uint64 nMask = (((uint64)1) << j); - if (nMaskGen & nMask) - { - MapNameFlagsItor pIter = pShaderRmp->second->begin(); - MapNameFlagsItor pEnd = pShaderRmp->second->end(); - for (; pIter != pEnd; ++pIter) - { - // found match - enable bit for remapped mask - if ((pIter->second) & nMask) - { - MapNameFlagsItor pMatchIter = m_pShaderCommonGlobalFlag.find(pIter->first); - if (pMatchIter != m_pShaderCommonGlobalFlag.end()) - { - nMaskGenRemaped |= pMatchIter->second; - } - - break; - } - } - } - } - - return nMaskGenRemaped; -} - - -SShaderGen* CShaderMan::mfCreateShaderGenInfo(const char* szName, bool bRuntime) -{ - CCryNameTSCRC s = szName; - if (!bRuntime) - { - ShaderExtItor it = m_ShaderExts.find(s); - if (it != m_ShaderExts.end()) - { - return it->second; - } - } - SShaderGen* pShGen = NULL; - char szN[256]; - cry_strcpy(szN, "Shaders/"); - cry_strcat(szN, szName); - cry_strcat(szN, ".ext"); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(szN, "rb", AZ::IO::IArchive::FOPEN_HINT_QUIET); - if (fileHandle != AZ::IO::InvalidHandle) - { - pShGen = new SShaderGen; - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetInstance()->Size(fileHandle, fileSize); - char* buf = new char [fileSize + 1]; - if (buf) - { - buf[fileSize] = 0; - gEnv->pCryPak->FRead(buf, fileSize, fileHandle); - mfCompileShaderGen(pShGen, buf); - mfRemapShaderGenInfoBits(szName, pShGen); - delete [] buf; - } - gEnv->pCryPak->FClose(fileHandle); - } - if (pShGen && !bRuntime) - { - pShGen->m_BitMask.Shrink(); - m_ShaderExts.insert(std::pair(s, pShGen)); - } - - return pShGen; -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.cpp deleted file mode 100644 index 7f4c6478df..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.cpp +++ /dev/null @@ -1,859 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ShaderResources.h" -#include "GraphicsPipeline/Common/GraphicsPipelineStateSet.h" - -#include -#include - -#ifndef NULL_RENDERER - #include "DriverD3D.h" -#endif // ! NULL_RENDERER - -enum MaterialRegister -{ - MaterialRegister_DiffuseColor = 0, // float4 - MaterialRegister_SpecularColor = 1, // float4 - MaterialRegister_EmissiveColor = 2, // float4 - MaterialRegister_DeformWave = 3, // float2x4 - MaterialRegister_DetailTiling = 5, // float4 - MaterialRegister_TexelDensity = 6, // float4 - MaterialRegister_UVMatrixDiffuse = 7, // float4x4 - MaterialRegister_UVMatrixCustom = 11,// float4x4 - MaterialRegister_UVMatrixEmissiveMultiplier = 15,// float4x4 - MaterialRegister_UVMatrixEmittance = 19,// float4x4 - MaterialRegister_UVMatrixDetail = 23,// float4x4 - - // Reflected constants are appended after the fixed ones. - MaterialRegister_MaxFixed = 27 -}; - -namespace UVTransform -{ - struct TextureSlot - { - EEfResTextures m_Slot; - MaterialRegister m_RegisterOffset; - }; - - TextureSlot g_SupportedSlots[] = - { - { EFTT_DIFFUSE, MaterialRegister_UVMatrixDiffuse }, - { EFTT_CUSTOM, MaterialRegister_UVMatrixCustom }, - { EFTT_DECAL_OVERLAY, MaterialRegister_UVMatrixEmissiveMultiplier }, - { EFTT_EMITTANCE, MaterialRegister_UVMatrixEmittance }, - { EFTT_DETAIL_OVERLAY, MaterialRegister_UVMatrixDetail } - }; - - inline TextureSlot GetSupportedSlot(AZ::u32 index) - { - return g_SupportedSlots[index]; - } - - inline AZ::u32 GetSupportedSlotCount() - { - return AZ_ARRAY_SIZE(g_SupportedSlots); - } -} - -void CShaderResources::Reset() -{ - m_TexturesResourcesMap.clear(); - m_Id = 0; - m_IdGroup = 0; - m_pDeformInfo = NULL; - m_pSky = NULL; - m_ConstantBuffer = NULL; - m_nMtlLayerNoDrawFlags = 0; - - m_Constants.resize(MaterialRegister_MaxFixed); -} - -void CShaderResources::ConvertToInputResource(SInputShaderResources* pDst) -{ - pDst->m_ResFlags = m_ResFlags; - pDst->m_AlphaRef = m_AlphaRef; - pDst->m_VoxelCoverage = m_VoxelCoverage; - - pDst->m_SortPrio = m_SortPrio; - if (m_pDeformInfo) - { - pDst->m_DeformInfo = *m_pDeformInfo; - } - else - { - pDst->m_DeformInfo.m_eType = eDT_Unknown; - } - - pDst->m_TexturePath = m_TexturePath; - if (m_pDeformInfo) - { - pDst->m_DeformInfo = *m_pDeformInfo; - } - - // Copy all used textures data - pDst->m_TexturesResourcesMap = m_TexturesResourcesMap; - - ToInputLM(pDst->m_LMaterial); -} - -size_t CShaderResources::GetResourceMemoryUsage(ICrySizer* pSizer) -{ - size_t nCurrentElementSize(0); - size_t nTotalSize(0); - - SIZER_COMPONENT_NAME(pSizer, "CShaderResources"); - for (auto &iter : m_TexturesResourcesMap ) - { - SEfResTexture* pTexture = &(iter.second); - if (pTexture->m_Sampler.m_pITex) - { - nCurrentElementSize = pTexture->m_Sampler.m_pITex->GetDataSize(); - pSizer->AddObject(pTexture->m_Sampler.m_pITex, nCurrentElementSize); - nTotalSize += nCurrentElementSize; - IResourceCollector* pColl = pSizer->GetResourceCollector(); - if (pColl) - { - pColl->AddResource(pTexture->m_Sampler.m_pITex->GetName(), nCurrentElementSize); - } - } - } - - return nTotalSize; -} - -void CShaderResources::Release() -{ -#ifndef NULL_RENDERER - AZ_Assert(gRenDev && gRenDev->m_pRT, "renderer not initialized"); - gRenDev->m_pRT->EnqueueRenderCommand([this]() - { - if (!CryInterlockedDecrement(&m_nRefCounter)) - { - delete this; - } - }); -#endif -} - -void CShaderResources::Cleanup() -{ - m_TexturesResourcesMap.clear(); - - SAFE_DELETE(m_pDeformInfo); - - if (m_pSky) - { - for (size_t i = 0; i < sizeof(m_pSky->m_SkyBox) / sizeof(m_pSky->m_SkyBox[0]); ++i) - { - SAFE_RELEASE(m_pSky->m_SkyBox[i]); - } - SAFE_DELETE(m_pSky); - } - ReleaseConstants(); - - // Not thread safe main thread can potentially access this destroyed entry in mfCreateShaderResources() - // (if flushing of unloaded textures (UnloadLevel) is not complete before pre-loading of new materials) - // [Shader System TO DO] - test and fix - if (CShader::s_ShaderResources_known.Num() > m_Id && CShader::s_ShaderResources_known[m_Id] == this) - { - CShader::s_ShaderResources_known[m_Id] = NULL; - } -} - -CShaderResources::~CShaderResources() -{ - Cleanup(); - - if (gRenDev->m_RP.m_pShaderResources == this) - { - gRenDev->m_RP.m_pShaderResources = NULL; - } -} - -CShaderResources::CShaderResources() -{ - // Only do expensive DX12 resource set building for PC DX12 -#if defined(CRY_USE_DX12) - m_pipelineStateCache = AZStd::make_shared(); -#endif - Reset(); -} - -CShaderResources::CShaderResources(SInputShaderResources* pSrc) -{ - assert(pSrc); - PREFAST_ASSUME(pSrc); - - // Only do expensive DX12 resource set building for PC DX12 -#if defined(CRY_USE_DX12) - m_pipelineStateCache = AZStd::make_shared(); -#endif - Reset(); - - if (!pSrc) - return; - - m_szMaterialName = pSrc->m_szMaterialName; - m_TexturePath = pSrc->m_TexturePath; - m_ResFlags = pSrc->m_ResFlags; - m_AlphaRef = pSrc->m_AlphaRef; - m_VoxelCoverage = pSrc->m_VoxelCoverage; - - m_SortPrio = pSrc->m_SortPrio; - m_ShaderParams = pSrc->m_ShaderParams; - if (pSrc->m_DeformInfo.m_eType) - { - m_pDeformInfo = new SDeformInfo; - *m_pDeformInfo = pSrc->m_DeformInfo; - } - - for (auto it = pSrc->m_TexturesResourcesMap.begin(), end = pSrc->m_TexturesResourcesMap.end(); it != end; ++it) - { - const SEfResTexture& texture = it->second; - // Omit any resources with no texture present - if (!texture.m_Name.empty() || texture.m_Sampler.m_pTex) - { - m_TexturesResourcesMap[it->first] = texture; - } - } - - SetInputLM(pSrc->m_LMaterial); -} - -CShaderResources& CShaderResources::operator=(const CShaderResources& src) -{ - Cleanup(); - SBaseShaderResources::operator = (src); - - m_TexturesResourcesMap = src.m_TexturesResourcesMap; - m_Constants = src.m_Constants; - m_IdGroup = src.m_IdGroup; - return *this; -} - -CShaderResources* CShaderResources::Clone() const -{ - CShaderResources* pSR = new CShaderResources(); - *pSR = *this; - pSR->m_nRefCounter = 1; - for (uint32 i = 0; i < CShader::s_ShaderResources_known.Num(); i++) - { - if (!CShader::s_ShaderResources_known[i]) - { - pSR->m_Id = i; - CShader::s_ShaderResources_known[i] = pSR; - return pSR; - } - } - if (CShader::s_ShaderResources_known.Num() >= MAX_REND_SHADER_RES) - { - Warning("ERROR: CShaderMan::mfCreateShaderResources: MAX_REND_SHADER_RESOURCES hit"); - pSR->Release(); - return CShader::s_ShaderResources_known[1]; - } - pSR->m_Id = CShader::s_ShaderResources_known.Num(); - CShader::s_ShaderResources_known.AddElem(pSR); - - return pSR; -} - -void CShaderResources::SetInputLM(const CInputLightMaterial& lm) -{ - ColorF* pDst = (ColorF*)&m_Constants[0]; - - memcpy(pDst, lm.m_Channels, min(int(EFTT_MAX), MaterialRegister_DiffuseColor / 2) * sizeof(lm.m_Channels[0])); - - const float fMinStepSignedFmt = (1.0f / 127.0f) * 255.0f; - const float fSmoothness = max(fMinStepSignedFmt, lm.m_Smoothness) / 255.0f; - const float fAlpha = lm.m_Opacity; - - pDst[MaterialRegister_DiffuseColor] = lm.m_Diffuse; - pDst[MaterialRegister_SpecularColor] = lm.m_Specular; - pDst[MaterialRegister_EmissiveColor] = lm.m_Emittance; - - pDst[MaterialRegister_DiffuseColor][3] = fAlpha; - pDst[MaterialRegister_SpecularColor][3] = fSmoothness; -} - -void CShaderResources::ToInputLM(CInputLightMaterial& lm) -{ - if (!m_Constants.size()) - { - return; - } - - ColorF* pDst = (ColorF*)&m_Constants[0]; - - lm.m_Diffuse = pDst[MaterialRegister_DiffuseColor]; - lm.m_Specular = pDst[MaterialRegister_SpecularColor]; - lm.m_Emittance = pDst[MaterialRegister_EmissiveColor]; - - lm.m_Opacity = pDst[MaterialRegister_DiffuseColor][3]; - lm.m_Smoothness = pDst[MaterialRegister_SpecularColor][3] * 255.0f; -} - -ColorF CShaderResources::GetColorValue(EEfResTextures slot) const -{ - if (!m_Constants.size()) - { - return Col_Black; - } - - int majoroffs; - switch (slot) - { - case EFTT_DIFFUSE: - majoroffs = MaterialRegister_DiffuseColor; - break; - case EFTT_SPECULAR: - majoroffs = MaterialRegister_SpecularColor; - break; - case EFTT_OPACITY: - return Col_White; - case EFTT_SMOOTHNESS: - return Col_White; - case EFTT_EMITTANCE: - majoroffs = MaterialRegister_EmissiveColor; - break; - default: - return Col_White; - } - - return reinterpret_cast(m_Constants[majoroffs]); -} - -float CShaderResources::GetStrengthValue(EEfResTextures slot) const -{ - if (!m_Constants.size()) - { - return Col_Black.a; - } - - int majoroffs, minoroffs; - switch (slot) - { - case EFTT_DIFFUSE: - return 1.0f; - case EFTT_SPECULAR: - return 1.0f; - case EFTT_OPACITY: - majoroffs = MaterialRegister_DiffuseColor; - minoroffs = 3; - break; - case EFTT_SMOOTHNESS: - majoroffs = MaterialRegister_SpecularColor; - minoroffs = 3; - break; - case EFTT_EMITTANCE: - majoroffs = MaterialRegister_EmissiveColor; - minoroffs = 3; - break; - default: - return 1.0f; - } - - ColorF* pDst = (ColorF*)&m_Constants[0]; - return pDst[majoroffs][minoroffs]; -} - -void CShaderResources::SetColorValue(EEfResTextures slot, const ColorF& color) -{ - if (!m_Constants.size()) - { - return; - } - - // NOTE: ideally the switch goes away and values are indexed directly - int majoroffs; - switch (slot) - { - case EFTT_DIFFUSE: - majoroffs = MaterialRegister_DiffuseColor; - break; - case EFTT_SPECULAR: - majoroffs = MaterialRegister_SpecularColor; - break; - case EFTT_OPACITY: - return; - case EFTT_SMOOTHNESS: - return; - case EFTT_EMITTANCE: - majoroffs = MaterialRegister_EmissiveColor; - break; - default: - return; - } - - ColorF* pDst = (ColorF*)&m_Constants[0]; - pDst[majoroffs] = ColorF(color.toVec3(), pDst[majoroffs][3]); -} - -void CShaderResources::SetStrengthValue(EEfResTextures slot, float value) -{ - if (!m_Constants.size()) - { - return; - } - - // NOTE: ideally the switch goes away and values are indexed directly - int majoroffs, minoroffs; - switch (slot) - { - case EFTT_DIFFUSE: - return; - case EFTT_SPECULAR: - return; - case EFTT_OPACITY: - majoroffs = MaterialRegister_DiffuseColor; - minoroffs = 3; - break; - case EFTT_SMOOTHNESS: - majoroffs = MaterialRegister_SpecularColor; - minoroffs = 3; - break; - case EFTT_EMITTANCE: - majoroffs = MaterialRegister_EmissiveColor; - minoroffs = 3; - break; - default: - return; - } - - ColorF* pDst = (ColorF*)&m_Constants[0]; - pDst[majoroffs][minoroffs] = value; -} -#ifndef NULL_RENDERER -void CShaderResources::UpdateConstants(IShader* pISH) -{ - if (gRenDev && gRenDev->m_pRT) - { - pISH->AddRef(); - this->AddRef(); - - gRenDev->m_pRT->EnqueueRenderCommand([this, pISH]() - { - -#if defined(CRY_USE_METAL) - //On metal the dynamic constant buffer usage assumes it will be updated every frame - //Since that is not the case with material properties use static option. - AzRHI::ConstantBufferUsage usage = AzRHI::ConstantBufferUsage::Static; -#else - AzRHI::ConstantBufferUsage usage = AzRHI::ConstantBufferUsage::Dynamic; -#endif - - Rebuild(pISH, usage); - pISH->Release(); - this->Release(); - }); - } -} - -namespace -{ - void WriteConstants(SFXParam* requestedParameter, AZStd::vector& parameters, AZStd::vector& outConstants) - { - const AZ::u32 parameterFlags = requestedParameter->GetFlags(); - const AZ::u8 paramStageSetter = requestedParameter->m_OffsetStageSetter; - const AZ::u32 registerOffset = requestedParameter->m_Register[paramStageSetter]; - AZ_Assert(registerOffset < outConstants.size(), "Requested parameter beyond the bounds of the constant buffer."); - float* outputData = &outConstants[registerOffset][0]; - - for (AZ::u32 componentIdx = 0; componentIdx < 4; componentIdx++) - { - if (parameterFlags & PF_AUTOMERGED) - { - CryFixedStringT<128> name; - requestedParameter->GetCompName(componentIdx, name); - SShaderParam::GetValue(name.c_str(), ¶meters, outputData, componentIdx); - } - else - { - SShaderParam::GetValue(requestedParameter->m_Name.c_str(), ¶meters, outputData, componentIdx); - } - } - } - - // Creates a parameters list for populating the constants in the Constant Buffer and returns the minimum and maximum slot offset - // of the newly added parameters taking their size into account for the maximum offset. - // NOTE: the minimum and maximum slot offsets MUST be initialized outside (min=10000, max=0) for the gathering to be valid. - void AddShaderParamToArray( - SShaderFXParams& inParameters, FixedDynArray& outParameters, - EHWShaderClass shaderClass, AZ::s32 &minSlotOffset, AZ::s32 &maxSlotOffset ) - { - for (int n = 0; n < inParameters.m_FXParams.size(); n++) - { - SFXParam* parameter = &inParameters.m_FXParams[n]; - if (parameter->m_nFlags & PF_MERGE) - { - continue; - } - - if (parameter->m_BindingSlot == eConstantBufferShaderSlot_PerMaterial) - { - if (parameter->m_Register[shaderClass] < 0 || parameter->m_Register[shaderClass] >= 10000) - { - continue; - } - - // Run over all existing parameters and look for the name entry - size_t findIdx = 0; - for (; findIdx < outParameters.size(); findIdx++) - { - // The name entry was found - break with its index to prevent double insertion - if (outParameters[findIdx]->m_Name == parameter->m_Name) - { - // Add the current usage to the marked usage - outParameters[findIdx]->m_StagesUsage |= ((0x1 << shaderClass) & 0xff); - break; - } - } - - // No existing entry for that name was found - add it. (otherwise ignore to avoid adding twice) - // Taking the first occurrence is not the optimal solution as it might leave gaps in constants offsets. - // A better solution would be to eliminate duplicates first with close grouping heuristics. - if (findIdx == outParameters.size()) - { - outParameters.push_back(parameter); - parameter->m_OffsetStageSetter = shaderClass; - parameter->m_StagesUsage = ((0x1 << shaderClass) & 0xff); - minSlotOffset = AZStd::GetMin(minSlotOffset, static_cast(parameter->m_Register[shaderClass])); - maxSlotOffset = AZStd::GetMax(maxSlotOffset, static_cast(parameter->m_Register[shaderClass] + parameter->m_RegisterCount)); - } - } - } - } -} - -void CShaderResources::Rebuild(IShader* abstractShader, AzRHI::ConstantBufferUsage usage) -{ - AZ_TRACE_METHOD(); - CShader* shader = (CShader*)abstractShader; - - // Do not attempt to update constant buffers for shaders that are not compiled or parsed. - // We can hit this case easily when r_shadersImport >= 2 under two primary scenarios: - // 1) We want to render an object with a shader that was never compiled because it was never added to the shader list from the Remote Shader Compiler. - // This is resolved by running the game in Debug or Profile and properly building your shader permutation list and rebuilding your shader paks. - // 2) The shader permutation was never compiled because it was never intended to render, but it is still loaded into memory and active. - // This occurs when a material's submaterial is unused, for example when a nodraw shader is attached as a submaterial. - // The material system naively attempts to update shader constants for all submaterial's shader techniques/passes - // via CMatInfo::RefreshShaderResourceConstants(), so we do not want to attempt to upload shader constants for shader permutations that will never be used. - if (!(shader->m_Flags & EF_LOADED)) - { - return; - } - - // Build list of used parameters and fill constant buffer scratchpad - SShaderFXParams& parameterRegistry = gRenDev->m_cEF.m_Bin.mfGetFXParams(shader); - const size_t parameterCount = parameterRegistry.m_FXParams.size(); - const size_t parameterByteCount = parameterCount * sizeof(SFXParam*); - - // Added this as a precaution - AZ_Assert((eHWSC_Num < 8), "More than 8 shader stages - m_StagesUsage can only represent 8, please adjust it to AZ::u16" ); - - FixedDynArray usedParameters; - PREFAST_SUPPRESS_WARNING(6255) usedParameters.set(ArrayT((SFXParam**)alloca((int)parameterByteCount), (int)parameterCount)); - - AZ::s32 registerStart = 10000; - AZ::s32 registerCountMax = 0; - for (AZ::u32 techniqueIdx = 0; techniqueIdx < (int)shader->m_HWTechniques.Num(); techniqueIdx++) - { - SShaderTechnique* technique = shader->m_HWTechniques[techniqueIdx]; - for (AZ::u32 passIdx = 0; passIdx < technique->m_Passes.Num(); passIdx++) - { - const SShaderPass* pass = &technique->m_Passes[passIdx]; - const CHWShader* shaders[] = { pass->m_VShader, pass->m_PShader, pass->m_GShader, pass->m_HShader, pass->m_DShader, pass->m_CShader }; - - for (EHWShaderClass shaderClass = EHWShaderClass(0); shaderClass < eHWSC_Num; shaderClass = EHWShaderClass(shaderClass + 1)) - { - if (shaders[shaderClass]) - { - AddShaderParamToArray(parameterRegistry, usedParameters, shaderClass, registerStart, registerCountMax); - } - } - } - } - - // Ordering the slots according to the Vertex Shader's slots offsets. The order is valid in most cases with - // the exception when the different stages have different slots offsets, however the slots' offsets range - // is always valid since it's covered by the minimum and maximum gathering that happens during the - // slots go over. - AZStd::sort(usedParameters.begin(), usedParameters.end(), [] (const SFXParam* lhs, const SFXParam* rhs) - { - return lhs->m_Register[0] < rhs->m_Register[0]; - }); - - if (usedParameters.size()) - { - // Validate and resize constant buffer scratchpad to match our reflection data. - { - AZ_Assert(registerStart < registerCountMax, "invalid constant buffer register interval"); - - if(registerCountMax > m_Constants.size()) - { - m_Constants.resize(registerCountMax); - } - } - - // Copies local shader tweakable values to the shaders local scratchpad. Then for each used parameter - // copies that data into the constant buffer. - { - AZStd::vector publicParameters = shader->GetPublicParams(); - if (publicParameters.size()) - { - for (AZ::u32 techniqueIdx = 0; techniqueIdx < m_ShaderParams.size(); techniqueIdx++) - { - SShaderParam& tweakable = m_ShaderParams[techniqueIdx]; - for (AZ::u32 j = 0; j < publicParameters.size(); j++) - { - SShaderParam& outParameter = publicParameters[j]; - if (outParameter.m_Name == tweakable.m_Name) - { - tweakable.CopyType(outParameter); - outParameter.CopyValueNoString(tweakable); // there should not be 'string' values set to shader - break; - } - } - } - - for (AZ::u32 i = 0; i < usedParameters.size(); i++) - { - WriteConstants(usedParameters[i], publicParameters, m_Constants); - } - } - } - } - - // Update common parameters - { - // Updating the texture modifiers - SEfResTexture* pTextureRes = nullptr; - for (AZ::u32 i = 0; i < UVTransform::GetSupportedSlotCount(); ++i) - { - const EEfResTextures slot = UVTransform::GetSupportedSlot(i).m_Slot; - const AZ::u32 registerOffset = UVTransform::GetSupportedSlot(i).m_RegisterOffset; - Matrix44 matrix(IDENTITY); - - pTextureRes = GetTextureResource (slot); - if (pTextureRes && pTextureRes->m_Ext.m_pTexModifier) - { - pTextureRes->Update(slot); - matrix = pTextureRes->m_Ext.m_pTexModifier->m_TexMatrix; - } - *reinterpret_cast(&m_Constants[registerOffset]) = matrix; - } - - Vec4 texelDensity(0.0f, 0.0f, 1.0f, 1.0f); - Vec4 detailTiling(1.0f); - - // [Shader System TO DO] - move that to be data driven - pTextureRes = GetTextureResource(EFTT_NORMALS); - if (pTextureRes && pTextureRes->m_Sampler.m_pTex) - { - texelDensity.x = (float)pTextureRes->m_Sampler.m_pTex->GetWidth(); - texelDensity.y = (float)pTextureRes->m_Sampler.m_pTex->GetHeight(); - texelDensity.z = 1.0f / std::max(1.0f, texelDensity.x); - texelDensity.w = 1.0f / std::max(1.0f, texelDensity.y); - } - - pTextureRes = GetTextureResource(EFTT_DETAIL_OVERLAY); - if (pTextureRes && pTextureRes->m_Ext.m_pTexModifier) - { - pTextureRes->Update(EFTT_DETAIL_OVERLAY); - detailTiling.x = pTextureRes->m_Ext.m_pTexModifier->m_Tiling[0]; - detailTiling.y = pTextureRes->m_Ext.m_pTexModifier->m_Tiling[1]; - detailTiling.z = 1.0f / detailTiling.x; - detailTiling.w = 1.0f / detailTiling.y; - } - - Vec4 deformWave0(0); - Vec4 deformWave1(0); - if (IsDeforming()) - { - deformWave0.x = m_pDeformInfo->m_WaveX.m_Freq; - deformWave0.y = m_pDeformInfo->m_WaveX.m_Phase; - deformWave0.z = m_pDeformInfo->m_WaveX.m_Amp; - deformWave0.w = m_pDeformInfo->m_WaveX.m_Level; - deformWave1.x = 1.0f / m_pDeformInfo->m_fDividerX; - } - - // We store the alpha test value into the last channel of deform wave (see GetMaterial_AlphaTest()). - deformWave1.w = m_AlphaRef; - - m_Constants[MaterialRegister_TexelDensity] = texelDensity; - m_Constants[MaterialRegister_DetailTiling] = detailTiling; - m_Constants[MaterialRegister_DeformWave + 0] = deformWave0; - m_Constants[MaterialRegister_DeformWave + 1] = deformWave1; - } - - SAFE_RELEASE(m_ConstantBuffer); - - if (m_Constants.size()) - { - m_ConstantBuffer = gcpRendD3D->m_DevBufMan.CreateConstantBuffer( - "PerMaterial", - m_Constants.size() * sizeof(Vec4), - usage, - AzRHI::ConstantBufferFlags::None); - - m_ConstantBuffer->UpdateBuffer(&m_Constants[0], m_Constants.size() * sizeof(Vec4)); - - // Only do expensive DX12 resource set building for PC DX12 -#if defined(CRY_USE_DX12) - if (!m_pCompiledResourceSet) - { - m_pCompiledResourceSet = CDeviceObjectFactory::GetInstance().CreateResourceSet(); - } - - m_pCompiledResourceSet->Clear(); - m_pCompiledResourceSet->Fill(shader, this, EShaderStage_AllWithoutCompute); - m_pCompiledResourceSet->Build(); -#endif - } -} - -void CShaderResources::CloneConstants(const IRenderShaderResources* pISrc) -{ - CShaderResources* pSrc = (CShaderResources*)pISrc; - - if (!pSrc) - { - m_Constants.clear(); - SAFE_RELEASE(m_ConstantBuffer); - return; - } - else - { - m_Constants = pSrc->m_Constants; - { - AzRHI::ConstantBuffer*& pCB0Dst = m_ConstantBuffer; - AzRHI::ConstantBuffer*& pCB0Src = pSrc->m_ConstantBuffer; - if (pCB0Src) - { - pCB0Src->AddRef(); - } - if (pCB0Dst) - { - pCB0Dst->Release(); - } - pCB0Dst = pCB0Src; - } - } -} - -void CShaderResources::ReleaseConstants() -{ - m_Constants.clear(); - - if (m_ConstantBuffer) - { - AzRHI::ConstantBuffer* constantBuffer = m_ConstantBuffer; - m_ConstantBuffer = nullptr; - - gRenDev->m_pRT->EnqueueRenderCommand([constantBuffer]() - { - constantBuffer->Release(); - }); - } -} - -static void AdjustSamplerState(SEfResTexture* pTex, bool bUseGlobalMipBias) -{ - int nTS = pTex->m_Sampler.m_nTexState; - if (nTS < 0 || nTS >= (int)CTexture::s_TexStates.size()) - { - return; - } - int8 nAniso = min(CRenderer::CV_r_texminanisotropy, CRenderer::CV_r_texmaxanisotropy); - if (nAniso < 1) - { - return; - } - STexState* pTS = &CTexture::s_TexStates[nTS]; - STexState ST = *pTS; - - float mipBias = 0.0f; - if (bUseGlobalMipBias) - { - mipBias = gRenDev->GetTemporalJitterMipBias(); - } - - if (ST.m_nAnisotropy == nAniso && ST.m_MipBias == mipBias) - { - return; - } - ST.m_pDeviceState = NULL; //otherwise state change is not applied - ST.m_MipBias = mipBias; - - if (nAniso >= 16) - { - ST.m_nMipFilter = - ST.m_nMinFilter = - ST.m_nMagFilter = FILTER_ANISO16X; - } - else if (nAniso >= 8) - { - ST.m_nMipFilter = - ST.m_nMinFilter = - ST.m_nMagFilter = FILTER_ANISO8X; - } - else if (nAniso >= 4) - { - ST.m_nMipFilter = - ST.m_nMinFilter = - ST.m_nMagFilter = FILTER_ANISO4X; - } - else if (nAniso >= 2) - { - ST.m_nMipFilter = - ST.m_nMinFilter = - ST.m_nMagFilter = FILTER_ANISO2X; - } - else - { - ST.m_nMipFilter = - ST.m_nMinFilter = - ST.m_nMagFilter = FILTER_TRILINEAR; - } - - ST.m_nAnisotropy = nAniso; - pTex->m_Sampler.m_nTexState = CTexture::GetTexState(ST); -} - -// [Shader System TO DO] - delete this hard coded method. Move to data driven -void CShaderResources::AdjustForSpec() -{ - // Note: Anisotropic filtering for smoothness maps is deliberately disabled, otherwise - // mip transitions become too obvious when using maps pre-filtered with normal variance - uint16 SamplersModulatorsIdx[] = { - EFTT_DIFFUSE, - EFTT_NORMALS, - EFTT_SPECULAR, - EFTT_CUSTOM, - EFTT_CUSTOM_SECONDARY, - EFTT_EMITTANCE, - 0xffff, - }; - - for (uint32 pos = 0; SamplersModulatorsIdx[pos] != 0xffff ; pos++) - { - SEfResTexture* pTextureRes = GetTextureResource(SamplersModulatorsIdx[pos]); - if (pTextureRes) - { - AdjustSamplerState(pTextureRes, true); - } - } -} -#endif diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.h b/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.h deleted file mode 100644 index 763f2b9670..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderResources.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "DeviceManager/Enums.h" - -//============================================================================== -//! This class provide all necessary resources to the shader extracted from material definition. -//------------------------------------------------------------------------------ -class CShaderResources - : public IRenderShaderResources - , public SBaseShaderResources -{ -private: - // Dynamically managed vector of all required shaders constants - - // This array will be copied to the (Per Material) constant buffer when ready. - AZStd::vector m_Constants; - - // The actual constant buffer to be binded as the Per material CB - AzRHI::ConstantBuffer* m_ConstantBuffer; - -public: - TexturesResourcesMap m_TexturesResourcesMap; // A map of texture used by the shader - SDeformInfo* m_pDeformInfo; // 4 bytes - Per Texture modulator info - TArray m_RTargets; // 4 - SSkyInfo* m_pSky; // [Shader System TO DO] - disconnect and remove! - uint16 m_Id; // Id of the shader resource in the frame's SR list - s_ShaderResources_known - uint16 m_IdGroup; // Id of the SR group for this SR in the frame's SR list. Starts at 20,000 - - ///////////////////////////////////////////////////// - float m_fMinMipFactorLoad; - int m_nRefCounter; - int m_nFrameLoad; - - // Only do expensive DX12 resource set building for PC DX12 -#if defined(CRY_USE_DX12) - // Compiled resource set. - // For DX12 will prepare list of textures in the global heap. - AZStd::shared_ptr m_pCompiledResourceSet; - AZStd::shared_ptr m_pipelineStateCache; -#endif - - uint8 m_nMtlLayerNoDrawFlags; - -public: - - bool TextureSlotExists(ResourceSlotIndex slotId) const - { - auto iter = m_TexturesResourcesMap.find(slotId); - return (iter != m_TexturesResourcesMap.end()) ? true : false; - } - - SEfResTexture* GetTextureResource(ResourceSlotIndex slotId) - { - auto iter = m_TexturesResourcesMap.find(slotId); - return (iter != m_TexturesResourcesMap.end()) ? &iter->second : nullptr; - } - - TexturesResourcesMap* GetTexturesResourceMap() - { - return &m_TexturesResourcesMap; - } - - inline AzRHI::ConstantBuffer* GetConstantBuffer() - { - return m_ConstantBuffer; - } - - int Size() const - { - int nSize = sizeof(CShaderResources); - for ( auto iter=m_TexturesResourcesMap.begin() ; iter != m_TexturesResourcesMap.end() ; ++iter ) - { - nSize += iter->second.Size(); - } - - nSize += sizeofVector(m_Constants); - nSize += m_RTargets.GetMemoryUsage(); - if (m_pDeformInfo) - { - nSize += m_pDeformInfo->Size(); - } - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const final - { - pSizer->AddObject(this, sizeof(*this)); - - for ( auto iter=m_TexturesResourcesMap.begin() ; iter != m_TexturesResourcesMap.end() ; ++iter ) - { - pSizer->AddObject(iter->second); - } - - - pSizer->AddObject(m_Constants); - pSizer->AddObject(m_RTargets); - pSizer->AddObject(m_pDeformInfo); - SBaseShaderResources::GetMemoryUsage(pSizer); - } - - CShaderResources(); - CShaderResources& operator=(const CShaderResources& src); - CShaderResources(struct SInputShaderResources* pSrc); - - void PostLoad(CShader* pSH); - void AdjustForSpec(); - void CreateModifiers(SInputShaderResources* pInRes); - virtual void UpdateConstants(IShader* pSH) final; - virtual void CloneConstants(const IRenderShaderResources* pSrc) final; - virtual int GetResFlags() final { return m_ResFlags; } - virtual void SetMaterialName(const char* szName) final { m_szMaterialName = szName; } - virtual SSkyInfo* GetSkyInfo() final { return m_pSky; } - virtual const float& GetAlphaRef() const final { return m_AlphaRef; } - virtual void SetAlphaRef(float alphaRef) final { m_AlphaRef = alphaRef; } - - virtual AZStd::vector& GetParameters() final { return m_ShaderParams; } - virtual ColorF GetFinalEmittance() final - { - const float kKiloScale = 1000.0f; - return GetColorValue(EFTT_EMITTANCE) * GetStrengthValue(EFTT_EMITTANCE) * (kKiloScale / RENDERER_LIGHT_UNIT_SCALE); - } - virtual float GetVoxelCoverage() final { return ((float)m_VoxelCoverage) * (1.0f / 255.0f); } - - virtual void SetMtlLayerNoDrawFlags(uint8 nFlags) final { m_nMtlLayerNoDrawFlags = nFlags; } - virtual uint8 GetMtlLayerNoDrawFlags() const final { return m_nMtlLayerNoDrawFlags; } - - void Rebuild(IShader* pSH, AzRHI::ConstantBufferUsage usage = AzRHI::ConstantBufferUsage::Dynamic); - void ReleaseConstants(); - - void Reset(); - - bool IsDeforming() const - { - return (m_pDeformInfo && m_pDeformInfo->m_fDividerX != 0); - } - - bool HasLMConstants() const { return (m_Constants.size() > 0); } - virtual void SetInputLM(const CInputLightMaterial& lm) final; - virtual void ToInputLM(CInputLightMaterial& lm) final; - - virtual ColorF GetColorValue(EEfResTextures slot) const final; - virtual float GetStrengthValue(EEfResTextures slot) const final; - - virtual void SetColorValue(EEfResTextures slot, const ColorF& color) final; - virtual void SetStrengthValue(EEfResTextures slot, float value) final; - - ~CShaderResources(); - virtual void Release() final; - virtual void AddRef() final { CryInterlockedIncrement(&m_nRefCounter); } - virtual void ConvertToInputResource(SInputShaderResources* pDst) final; - virtual CShaderResources* Clone() const final; - virtual void SetShaderParams(SInputShaderResources* pDst, IShader* pSH) final; - - virtual size_t GetResourceMemoryUsage(ICrySizer* pSizer) final; - - void Cleanup(); -}; -typedef _smart_ptr CShaderResourcesPtr; diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderScript.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderScript.cpp deleted file mode 100644 index f1d0cacc45..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderScript.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "CryHeaders.h" -#include "../Common/Shaders/RemoteCompiler.h" -#include -#include - -#include - -#ifndef NULL_RENDERER -#include "DriverD3D.h" -#endif - -#if defined(WIN32) || defined(WIN64) -#include -#include -#endif - -extern char* gShObjectNotFound; - -//================================================================================================= - -bool CShader::Reload(int nFlags, const char* szShaderName) -{ - CShader* pShaderGen = NULL; - if (m_ShaderGenParams) - { - pShaderGen = this; - } - else - if (m_pGenShader) - { - pShaderGen = m_pGenShader; - } - uint32 nFl = EF_RELOAD; - if (nFlags & FRO_FORCERELOAD) - { - nFl |= EF_FORCE_RELOAD; - } - if (pShaderGen && pShaderGen->m_DerivedShaders) - { - for (uint32 i = 0; i < pShaderGen->m_DerivedShaders->size(); i++) - { - CShader* pShader = (*pShaderGen->m_DerivedShaders)[i]; - if (!pShader) - { - continue; - } - if (pShader->m_nRefreshFrame == gRenDev->m_cEF.m_nFrameForceReload) - { - continue; - } - pShader->m_nRefreshFrame = gRenDev->m_cEF.m_nFrameForceReload; - - gRenDev->m_cEF.mfForName(szShaderName, pShader->m_Flags | nFl, NULL, pShader->m_nMaskGenFX); - } - } - else - { - assert(!m_nMaskGenFX); - gRenDev->m_cEF.mfForName(szShaderName, m_Flags | nFl, NULL, m_nMaskGenFX); - } - - return true; -} - -bool CShaderMan::mfReloadShaderIncludes(const char* szPath, int nFlags) -{ - assert(szPath); - - bool bChanged = false; - char dirn[256]; - cry_strcpy(dirn, szPath); - cry_strcat(dirn, "*"); - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst (dirn); - if (handle) - { - do - { - if (handle.m_filename.front() == '.') - { - continue; - } - if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - char ddd[256]; - azsnprintf(ddd, AZ_ARRAY_SIZE(ddd), "%s%.*s/", szPath, aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - - bChanged = mfReloadShaderIncludes(ddd, nFlags); - continue; - } - char nmf[256]; - cry_strcpy(nmf, szPath); - cry_strcat(nmf, handle.m_filename.data()); - int len = strlen(nmf) - 1; - while (len >= 0 && nmf[len] != '.') - { - len--; - } - if (len <= 0) - { - continue; - } - if (!azstricmp(&nmf[len], ".cfi")) - { - fpStripExtension(handle.m_filename.data(), nmf); - bool bCh = false; - m_Bin.GetBinShader(nmf, true, 0, &bCh); - if (bCh) - { - bChanged = true; - mfReloadFile(szPath, handle.m_filename.data(), nFlags); - } - } - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); - } - return bChanged; -} - -bool CShaderMan::mfReloadAllShaders([[maybe_unused]] int nFlags, [[maybe_unused]] uint32 nFlagsHW) -{ - bool bState = true; - m_nFrameForceReload++; - - gRenDev->FlushRTCommands(true, true, true); - m_Bin.InvalidateCache(); - CHWShader::mfFlushPendedShadersWait(-1); - -#ifndef NULL_RENDERER - // Ensure all shaders are unbound before forcing a reload of all shaders - gRenDev->m_pRT->RC_UnbindResources(); - if (!gRenDev->IsShaderCacheGenMode()) - { - gRenDev->m_pRT->RC_ResetToDefault(); - } - gRenDev->FlushRTCommands(true, true, true); - - CDebugAllowFileAccess ignoreInvalidFileAccess; - - // Check include changing - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_shadersignoreincludeschanging) - { - mfReloadShaderIncludes(m_ShadersPath.c_str(), nFlags); - } - CCryNameTSCRC Name = CShader::mfGetClassName(); - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CShader* pS = (CShader*)itor->second; - if (!pS) - { - continue; - } - if (nFlagsHW) - { - if (!pS->m_pGenShader) - { - continue; - } - SShaderGen* pGen = pS->m_pGenShader->m_ShaderGenParams; - assert(pGen); - if (!pGen) - { - continue; - } - uint32 i; - SShaderGenBit* pBit; - for (i = 0; i < pGen->m_BitMask.Num(); i++) - { - pBit = pGen->m_BitMask[i]; - if ((pBit->m_nDependencySet | pBit->m_nDependencyReset) & nFlagsHW) - { - break; - } - } - if (i == pGen->m_BitMask.Num()) - { - continue; - } - pS->Reload(nFlags | FRO_FORCERELOAD, pS->GetName()); - } - else - { - char name[256]; - sprintf_s(name, "%sCryFX/%s.cfx", m_ShadersPath.c_str(), pS->GetName()); - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(name, "rb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - uint32 nSourceCRC32 = gEnv->pCryPak->ComputeCRC(name); - gEnv->pCryPak->FClose(fileHandle); - if ((nFlags & FRO_FORCERELOAD) || nSourceCRC32 != pS->m_SourceCRC32) - { - pS->m_SourceCRC32 = nSourceCRC32; - pS->Reload(nFlags, pS->GetName()); - } - } - } - } - } - - //Force all PSOs to be rebuilt - CDeviceObjectFactory::GetInstance().InvalidatePSOCache(); - //Tell the graphics pipeline to reset and throw out existing PSOs since they're now invalid - gcpRendD3D->GetGraphicsPipeline().Reset(); - -#endif - - gRenDev->FlushRTCommands(true, true, true); - CHWShader::mfFlushPendedShadersWait(-1); - - return bState; -} - -// Recursively iterate through all the shaders included by pBin to see if any match szShaderName -// Returns true if there is a match, meaning pBin is affected by szShaderName. -static bool sCheckAffecting_r(SShaderBin* pBin, const char* szShaderName) -{ - pBin->Lock(); - int nTok = 0; - // Check first level - while (nTok >= 0) - { - // For each include that is found, check to see if it matches szShaderName - nTok = CParserBin::FindToken(nTok, pBin->m_Tokens.size() - 1, &pBin->m_Tokens[0], eT_include); - if (nTok >= 0) - { - // If an include was found, check to see if it matches szShaderName - nTok++; - uint32 nTokName = pBin->m_Tokens[nTok]; - const char* szNameInc = CParserBin::GetString(nTokName, pBin->m_TokenTable); - if (!azstricmp(szNameInc, szShaderName)) - { - // If szShaderName matches the included shader, then pBin is affected by that shader - // Since nTok is >= 0, breaking here will result in returning 'true' - break; - } - } - } - // Check each of the included shaders recursively - if (nTok < 0) - { - nTok = 0; - while (nTok >= 0) - { - nTok = CParserBin::FindToken(nTok, pBin->m_Tokens.size() - 1, &pBin->m_Tokens[0], eT_include); - if (nTok >= 0) - { - // For each include that is found, check to see if it matches szShaderName - nTok++; - uint32 nTokName = pBin->m_Tokens[nTok]; - const char* szNameInc = CParserBin::GetString(nTokName, pBin->m_TokenTable); - if (!azstricmp(szNameInc, szShaderName)) - { - // If szShaderName matches the included shader, then pBin is affected by that shader - // Since nTok is >= 0, breaking here will result in returning 'true' - break; - } - SShaderBin* pBinIncl = gRenDev->m_cEF.m_Bin.GetBinShader(szNameInc, true, 0); - if (!pBinIncl) - { - AZ_Assert(false, "Error attempting to load shader %s while checking all the shaders included by %s.", szNameInc, pBin->m_szName); - break; - } - // Since the included file did not match szShaderName, recursively check all of its included shaders to see if they match - bool bAffect = sCheckAffecting_r(pBinIncl, szShaderName); - if (bAffect) - { - // One of the included shaders matched szShaderName - // Since nTok is >= 0, breaking here will result in returning 'true' - break; - } - } - } - } - pBin->Unlock(); - // Return true if a shader was found that matched szShaderName, false otherwise - return (nTok >= 0); -} - -bool CShaderMan::mfReloadFile([[maybe_unused]] const char* szPath, const char* szName, int nFlags) -{ - CHWShader::mfFlushPendedShadersWait(-1); - - m_nFrameForceReload++; - - const char* szExt = fpGetExtension(szName); - if (!azstricmp(szExt, ".cfx")) - { - m_bReload = true; - char szShaderName[256]; - cry_strcpy(szShaderName, szName, (size_t)(szExt - szName)); - azstrlwr(szShaderName, AZ_ARRAY_SIZE(szShaderName)); - - // Check if this shader already loaded - CBaseResource* pBR = CBaseResource::GetResource(CShader::mfGetClassName(), szShaderName, false); - if (pBR) - { - CShader* pShader = (CShader*)pBR; - pShader->Reload(nFlags, szShaderName); - } - m_bReload = false; - } - else - if (!azstricmp(szExt, ".cfi")) - { - CCryNameTSCRC Name = CShader::mfGetClassName(); - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - m_bReload = true; - char szShaderName[256]; - cry_strcpy(szShaderName, szName, (size_t)(szExt - szName)); - azstrlwr(szShaderName, AZ_ARRAY_SIZE(szShaderName)); - SShaderBin* pBin = m_Bin.GetBinShader(szShaderName, true, 0); - bool bAffect = false; - - // Since this is a .cfi file, iterate through the existing resources to see if any of them are including it and consequently must be re-loaded - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CShader* sh = (CShader*)itor->second; - if (!sh || !sh->GetName()[0]) - { - continue; - } - pBin = m_Bin.GetBinShader(sh->GetName(), false, 0); - if (!pBin) - { - continue; - } - - // Recursively check to see if sh is affected by the .cfi that is being reloaded - bAffect = sCheckAffecting_r(pBin, szShaderName); - if (bAffect) - { - // If sh is affected, it also needs to be reloaded - sh->Reload(nFlags | FRO_FORCERELOAD, sh->GetName()); - } - } - } - m_bReload = false; - } - - - return false; -} - -//============================================================================= - -void CShaderMan::mfFillGenMacroses(SShaderGen* shG, TArray& buf, uint64 nMaskGen) -{ - uint32 i; - - if (!nMaskGen || !shG) - { - return; - } - - for (i = 0; i < shG->m_BitMask.Num(); i++) - { - if (shG->m_BitMask[i]->m_Mask & nMaskGen) - { - char macro[256]; -#if defined(__GNUC__) - sprintf_s(macro, "#define %s 0x%llx\n", shG->m_BitMask[i]->m_ParamName.c_str(), (unsigned long long)shG->m_BitMask[i]->m_Mask); -#else - sprintf_s(macro, "#define %s 0x%I64x\n", shG->m_BitMask[i]->m_ParamName.c_str(), (uint64)shG->m_BitMask[i]->m_Mask); -#endif - int size = strlen(macro); - int nOffs = buf.Num(); - buf.Grow(size); - memcpy(&buf[nOffs], macro, size); - } - } -} - - -bool CShaderMan::mfModifyGenFlags(CShader* efGen, const CShaderResources* pRes, uint64& nMaskGen, uint64& nMaskGenH) -{ - if (!efGen || !efGen->m_ShaderGenParams) - { - return false; - } - uint64 nAndMaskHW = -1; - uint64 nMaskGenHW = 0; - - // Remove non-used flags first - unsigned int i = 0; - SShaderGen* pGen = efGen->m_ShaderGenParams; - int j; - - //char _debug_[256]; - //sprintf_s( _debug_, "curr shadergen %I64x %I64x\n", nMaskGen, nMaskGenH); - //OutputDebugString(_debug_); - - if (nMaskGen) - { - for (j = 0; j < 64; j++) - { - uint64 nMask = (((uint64)1) << j); - if (nMaskGen & nMask) - { - for (i = 0; i < pGen->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = pGen->m_BitMask[i]; - if (pBit->m_Mask & nMask) - { - break; - } - } - - if (i == pGen->m_BitMask.Num()) - { - nMaskGen &= ~nMask; - } - } - } - } - - for (i = 0; i < pGen->m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = pGen->m_BitMask[i]; - if (!pBit || (!pBit->m_nDependencySet && !pBit->m_nDependencyReset)) - { - continue; - } - if (pRes) - { - if (pBit->m_nDependencySet & SHGD_TEX_NORMALS) - { - if (pRes->TextureSlotExists(EFTT_NORMALS)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_NORMALS) - { - if (!pRes->TextureSlotExists(EFTT_NORMALS)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - if (pBit->m_nDependencySet & SHGD_TEX_HEIGHT) - { - if (pRes->TextureSlotExists(EFTT_HEIGHT)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_HEIGHT) - { - if (!pRes->TextureSlotExists(EFTT_HEIGHT)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_DETAIL) - { - if (pRes->TextureSlotExists(EFTT_DETAIL_OVERLAY)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_DETAIL) - { - if (!pRes->TextureSlotExists(EFTT_DETAIL_OVERLAY)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_SECOND_SMOOTHNESS) - { - if (pRes->TextureSlotExists(EFTT_SECOND_SMOOTHNESS)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_SECOND_SMOOTHNESS) - { - if (!pRes->TextureSlotExists(EFTT_SECOND_SMOOTHNESS)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_SPECULAR) - { - if (pRes->TextureSlotExists(EFTT_SPECULAR)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_SPECULAR) - { - if (!pRes->TextureSlotExists(EFTT_SPECULAR)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_ENVCM) - { - if (pRes->TextureSlotExists(EFTT_ENV)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_ENVCM) - { - if (!pRes->TextureSlotExists(EFTT_ENV)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_SUBSURFACE) - { - if (pRes->TextureSlotExists(EFTT_SUBSURFACE)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_SUBSURFACE) - { - if (!pRes->TextureSlotExists(EFTT_SUBSURFACE)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_DECAL) - { - if (pRes->TextureSlotExists(EFTT_DECAL_OVERLAY)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_DECAL) - { - if (!pRes->TextureSlotExists(EFTT_DECAL_OVERLAY)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_CUSTOM) - { - if (pRes->TextureSlotExists(EFTT_CUSTOM)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_CUSTOM) - { - if (!pRes->TextureSlotExists(EFTT_CUSTOM)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_CUSTOM_SECONDARY) - { - if (pRes->TextureSlotExists(EFTT_CUSTOM_SECONDARY)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_CUSTOM_SECONDARY) - { - if (!pRes->TextureSlotExists(EFTT_CUSTOM_SECONDARY)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_SPECULAR_2) - { - if (pRes->TextureSlotExists(EFTT_SPECULAR_2)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_SPECULAR_2) - { - if (!pRes->TextureSlotExists(EFTT_SPECULAR_2)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - if (pBit->m_nDependencySet & SHGD_TEX_EMITTANCE) - { - // If either the emittance or the decal overlay (emissive intensity) are used, SHGD_TEX_EMITTANCE should be defined - if (pRes->TextureSlotExists(EFTT_EMITTANCE) || pRes->TextureSlotExists(EFTT_DECAL_OVERLAY)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_EMITTANCE) - { - // If neither the emittance nor the decal overlay (emissive intensity) are used, SHGD_TEX_EMITTANCE should not be defined - if (!pRes->TextureSlotExists(EFTT_EMITTANCE) && !pRes->TextureSlotExists(EFTT_DECAL_OVERLAY)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - - - if (pBit->m_nDependencySet & SHGD_TEX_OCC) - { - if (pRes->TextureSlotExists(EFTT_OCCLUSION)) - { - nMaskGen |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_TEX_OCC) - { - if (!pRes->TextureSlotExists(EFTT_OCCLUSION)) - { - nMaskGen &= ~pBit->m_Mask; - } - } - } - - // Specific case - for user gl flags (eg: TEMP_TERRAIN, TEMP_VEGETATION) - // this is needed since we now use common shader global flags - else define inside shader.cfi will override correct shared value - if (pBit->m_nDependencySet & SHGD_USER_ENABLED) - { - nMaskGen |= pBit->m_Mask; - } - - //if (m_nCombinationsProcess < 0 || m_bActivatePhase) - { - if (pBit->m_nDependencySet & SHGD_HW_BILINEARFP16) - { - nAndMaskHW &= ~pBit->m_Mask; - if (gRenDev->m_bDeviceSupportsFP16Filter) - { - nMaskGenHW |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_HW_BILINEARFP16) - { - nAndMaskHW &= ~pBit->m_Mask; - if (!gRenDev->m_bDeviceSupportsFP16Filter) - { - nMaskGenHW &= ~pBit->m_Mask; - } - } - if (pBit->m_nDependencySet & SHGD_HW_SEPARATEFP16) - { - nAndMaskHW &= ~pBit->m_Mask; - if (gRenDev->m_bDeviceSupportsFP16Separate) - { - nMaskGenHW |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_HW_SEPARATEFP16) - { - nAndMaskHW &= ~pBit->m_Mask; - if (!gRenDev->m_bDeviceSupportsFP16Separate) - { - nMaskGenHW &= ~pBit->m_Mask; - } - } - - if (CParserBin::m_bShaderCacheGen) - { - // during shader cache gen, disable the special features in non D3D11 mode, and just accept - // the lines as they come in D3D11 mode - if (CParserBin::m_nPlatform != SF_D3D11 && CParserBin::m_nPlatform != SF_JASPER && CParserBin::m_nPlatform != SF_GL4 && CParserBin::m_nPlatform != SF_ORBIS) - { - if (pBit->m_nDependencySet & SHGD_HW_WATER_TESSELLATION) - { - nAndMaskHW &= ~pBit->m_Mask; - } - if (pBit->m_nDependencySet & SHGD_HW_SILHOUETTE_POM) - { - nAndMaskHW &= ~pBit->m_Mask; - } - } - } - else - { - PREFAST_SUPPRESS_WARNING(6326) - bool bWaterTessHW = CRenderer::CV_r_WaterTessellationHW != 0 && gRenDev->m_bDeviceSupportsTessellation; - if (pBit->m_nDependencySet & SHGD_HW_WATER_TESSELLATION) - { - nAndMaskHW &= ~pBit->m_Mask; - if (bWaterTessHW) - { - nMaskGenHW |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_HW_WATER_TESSELLATION) - { - nAndMaskHW &= ~pBit->m_Mask; - if (!bWaterTessHW) - { - nMaskGenHW &= ~pBit->m_Mask; - } - } - - PREFAST_SUPPRESS_WARNING(6326) - const bool useSilhouettePOM = CRenderer::CV_r_SilhouettePOM != 0; - if (pBit->m_nDependencySet & SHGD_HW_SILHOUETTE_POM) - { - nAndMaskHW &= ~pBit->m_Mask; - if (useSilhouettePOM) - { - nMaskGenHW |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_HW_SILHOUETTE_POM) - { - nAndMaskHW &= ~pBit->m_Mask; - if (!useSilhouettePOM) - { - nMaskGenHW &= ~pBit->m_Mask; - } - } - - PREFAST_SUPPRESS_WARNING(6326) - const bool useSAA = CRenderer::CV_r_SpecularAntialiasing != 0; - if (pBit->m_nDependencySet & SHGD_HW_SAA) - { - nAndMaskHW &= ~pBit->m_Mask; - if (useSAA) - { - nMaskGenHW |= pBit->m_Mask; - } - } - if (pBit->m_nDependencyReset & SHGD_HW_SAA) - { - nAndMaskHW &= ~pBit->m_Mask; - if (!useSAA) - { - nMaskGenHW &= ~pBit->m_Mask; - } - } - } - } - } - nMaskGen &= nAndMaskHW; - nMaskGenH |= nMaskGenHW; - - //sprintf_s( _debug_, "remap shadergen %I64x %I64x\n", nMaskGen, nMaskGenH); - //OutputDebugString(_debug_); - - - return true; -} - -bool CShaderMan::mfUpdateTechnik (SShaderItem& SI, CCryNameTSCRC& Name) -{ - CShader* pSH = (CShader*)SI.m_pShader; - if (!(pSH->m_Flags & EF_LOADED)) - { - return false; - } - uint32 i; - for (i = 0; i < pSH->m_HWTechniques.Num(); i++) - { - SShaderTechnique* pTech = pSH->m_HWTechniques[i]; - //if (!(pTech->m_Flags & FHF_PUBLIC)) - // continue; - if (pTech->m_NameCRC == Name) - { - break; - } - } - if (i == pSH->m_HWTechniques.Num()) - { - SI.m_nTechnique = -1; - Warning("ERROR: CShaderMan::mfUpdateTechnik: couldn't find public technique for shader '%s'", pSH->GetName()); - } - else - { - SI.m_nTechnique = i; - } - - return true; -} - -SShaderItem CShaderMan::mfShaderItemForName (const char* nameEf, bool bShare, int flags, SInputShaderResources* Res, uint64 nMaskGen) -{ - SShaderItem SI; - - CShaderResources* pResource = NULL; - if (Res) - { - SI.m_pShaderResources = mfCreateShaderResources(Res, bShare); - pResource = (CShaderResources*)SI.m_pShaderResources; - pResource->m_ShaderParams = Res->m_ShaderParams; - m_pCurInputResources = Res; - } - - string strShader = nameEf; - string strTechnique; - string strNew = strShader.SpanExcluding("."); - if (strNew.size() != strShader.size()) - { - string second = string(&strShader.c_str()[strNew.size() + 1]); - strShader = strNew; - strTechnique = second; - } - - if (SI.m_pShaderResources) - { - const threadID currentThread = CryGetCurrentThreadId(); - threadID renderThread, mainThread; - - gEnv->pRenderer->GetThreadIDs(mainThread, renderThread); - - if (currentThread == mainThread) - { - mfRefreshResources((CShaderResources*)SI.m_pShaderResources); - } - else - { - AZStd::function runOnMainThread = [this, SI]() - { - mfRefreshResources((CShaderResources*)SI.m_pShaderResources); - }; - - EBUS_QUEUE_FUNCTION(AZ::MainThreadRenderRequestBus, runOnMainThread); - } - } - - char shadName[256]; - if (nameEf && nameEf[0]) - { - cry_strcpy(shadName, strShader.c_str()); - } - else - { - shadName[0] = 0; - } - - SI.m_pShader = mfForName(shadName, flags, (CShaderResources*)SI.m_pShaderResources, nMaskGen); - - // Get technique - if (strTechnique.size()) - { - CCryNameTSCRC nTech(strTechnique.c_str()); - if (!mfUpdateTechnik(SI, nTech)) - { - SI.m_nTechnique = nTech.get(); // Postpone - } - } - SI.m_nPreprocessFlags = -1; - if (Res) - { - SI.m_pShaderResources = pResource; - if (pResource) - { - pResource->CreateModifiers(Res); - } - } - m_pCurInputResources = NULL; - return SI; -} - - -CShader* CShaderMan::mfForName (const char* nameSh, int flags, const CShaderResources* Res, uint64 nMaskGen) -{ - CShader* ef, * efGen; - int id; - - if (!nameSh || !nameSh[0]) - { - Warning("Warning: CShaderMan::mfForName: NULL name\n"); - s_DefaultShader->AddRef(); - return s_DefaultShader; - } - - char nameEf[256]; - char nameNew[256]; - char nameRes[256]; - - uint64 nMaskGenHW = 0; - uint64 maskGenStatic = m_staticFlags; - - cry_strcpy(nameEf, nameSh); - - cry_strcpy(nameRes, nameEf); - - cry_strcat(nameRes, GetShaderLanguageResourceName()); - - if (maskGenStatic) - { - cry_strcat(nameRes, AZStd::string::format("(ST%llx)", maskGenStatic).c_str()); - } - - ef = NULL; - efGen = NULL; - - // Check if this shader already loaded - CBaseResource* pBR = CBaseResource::GetResource(CShader::mfGetClassName(), nameRes, false); - bool bGenModified = false; - ef = (CShader*)pBR; - if (ef && ef->m_ShaderGenParams) - { - efGen = ef; - - mfModifyGenFlags(efGen, Res, nMaskGen, nMaskGenHW); - bGenModified = true; - azsprintf(nameNew, "%s(%llx)", nameRes, nMaskGen); - pBR = CBaseResource::GetResource(CShader::mfGetClassName(), nameNew, false); - ef = (CShader*)pBR; - if (ef) - { - // Update the flags if HW specs changed - ef->m_nMaskGenFX = nMaskGen | nMaskGenHW; - assert(ef->m_pGenShader == efGen); - } - } - - if (ef) - { - if (!(flags & EF_RELOAD)) - { - ef->AddRef(); - ef->m_Flags |= flags; - return ef; - } - else - { - ef->mfFree(); - ef->m_Flags |= EF_RELOADED; - } - } - - if (!efGen) - { - sprintf_s(nameNew, "Shaders/%s.ext", nameEf); - SShaderGen* pShGen = mfCreateShaderGenInfo(nameEf, false); - - if (pShGen) - { - efGen = mfNewShader(nameRes); - efGen->SetRefCounter(0); // Hack: to avoid leaks in shader-gen's - efGen->m_NameShader = nameRes; - efGen->m_ShaderGenParams = pShGen; - } - } - if (!(flags & EF_RELOAD) || !ef) - { - if (efGen) - { - // Change gen flags based on dependency on resources info - if (!bGenModified) - { - //nMaskGen = gRenDev->EF_GetRemapedShaderMaskGen(nameSh, nMaskGen | nMaskGenHW); - mfModifyGenFlags(efGen, Res, nMaskGen, nMaskGenHW); - } - sprintf_s(nameNew, "%s(%llx)", nameRes, nMaskGen); - ef = mfNewShader(nameNew); - if (!ef) - { - return s_DefaultShader; - } - - ef->m_nMaskGenFX = nMaskGen | nMaskGenHW; - ef->m_maskGenStatic = maskGenStatic; - ef->m_ShaderGenStaticParams = m_staticExt; - ef->m_pGenShader = efGen; - } - if (efGen && ef) - { - assert(efGen != ef); - if (!efGen->m_DerivedShaders) - { - efGen->m_DerivedShaders = new std::vector; - } - efGen->m_DerivedShaders->push_back(ef); - efGen->AddRef(); - } - if (!ef) - { - ef = mfNewShader(nameRes); - if (!ef) - { - return s_DefaultShader; - } - - ef->m_maskGenStatic = maskGenStatic; - ef->m_ShaderGenStaticParams = m_staticExt; - } - } - id = ef->GetID(); - ef->m_NameShader = nameEf; - ef->m_NameShaderICRC = CCrc32::ComputeLowercase(nameEf); - -#ifndef NULL_RENDERER - // Check for the new cryFX format - sprintf_s(nameNew, "%sCryFX/%s.cfx", m_ShadersPath.c_str(), nameEf); - ef->m_NameFile = nameNew; - ef->m_Flags |= flags; - gRenDev->m_pRT->RC_ParseShader(ef, nMaskGen | nMaskGenHW, flags, (CShaderResources*)Res); - return ef; -#endif - - return ef; -} - -void CShaderMan::CreateShaderExportRequestLine(const CShader* pSH, stack_string& exportString) -{ - if (pSH) - { - exportString.Format("<%d>%s/%s(", SHADER_SERIALISE_VER, pSH->GetName(), pSH->GetName()); - CreateShaderMaskGenString(pSH, exportString); - exportString += ")()(0)(0)(0)(VS)"; //fake normal request line format - } -} - -void CShaderMan::CreateShaderMaskGenString(const CShader* pSH, stack_string& flagString) -{ - uint64 glMask = pSH->m_nMaskGenFX; - - if (glMask) - { - SShaderGenComb* c = NULL; - c = mfGetShaderGenInfo(pSH->GetName()); - if (c && c->pGen && c->pGen->m_BitMask.Num()) - { - bool bFirstTime = true; - SShaderGen* pG = c->pGen; - for (uint32 i = 0; i < 64; i++) - { - if (glMask & ((uint64)1 << i)) - { - for (uint32 j = 0; j < pG->m_BitMask.Num(); j++) - { - SShaderGenBit* pBit = pG->m_BitMask[j]; - if (pBit->m_Mask & (glMask & ((uint64)1 << i))) - { - if (bFirstTime) - { - bFirstTime = false; - } - else - { - flagString += "|"; - } - - flagString += pBit->m_ParamName.c_str(); - break; - } - } - } - } - } - } -} - -void CShaderMan::RT_ParseShader(CShader* pSH, uint64 nMaskGen, uint32 flags, [[maybe_unused]] CShaderResources* pRes) -{ - CDebugAllowFileAccess ignoreInvalidFileAccess; - - bool bSuccess = false; -#ifdef SHADERS_SERIALIZING - if (CRenderer::CV_r_shadersImport) - { - // Do not try and import fxb during cache generation - // PC would need to support import of console data - if (!gRenDev->IsShaderCacheGenMode()) - { - ShaderImportResults importResults = ImportShader(pSH, m_Bin); - - if (importResults == SHADER_IMPORT_SUCCESS) - { - bSuccess = true; - } - else - { -#ifdef SHADER_SERIALIZE_VERBOSE - { - stack_string flagString; - CreateShaderMaskGenString(pSH, flagString); - - CryLog("[CShaderSerialize] Failed to import shader %s (0x%p) flags: 0x%llx 0x%x (%s)\n", pSH->GetName(), pSH, pSH->m_nMaskGenFX, pSH->m_nMDV, flagString.empty() ? "0" : flagString.c_str()); - } -#endif - - pSH->m_Flags |= EF_FAILED_IMPORT; - - if (CRenderer::CV_r_shadersImport == 2) - { - // Do not fallback to the slow path unless we have a valid permutation in our lookup table (most optimal path) - return; - } - else - { - // If importResults == SHADER_IMPORT_MISSING_ENTRY, then allow the fallback path if we have a valid .fxb file - // for this shader, but the current permutation is missing from the lookup table. - // This will fallback to the slow path to parse the .cfx for this shader permutation - if (importResults == SHADER_IMPORT_FAILURE) - { - // No .fxb was exported for this .cfx, so do not fallback. - return; - } - } - } - } - } -#endif - if (!bSuccess) - { -#if !defined(SHADER_NO_SOURCES) - SShaderBin* pBin = m_Bin.GetBinShader(pSH->m_NameShader, false, 0); - if (pBin) -#endif - { -#if !defined(SHADER_NO_SOURCES) - if (flags & EF_FORCE_RELOAD) - { - uint32 nCRC32 = pBin->ComputeCRC(); - if (nCRC32 != pBin->m_CRC32) - { - FXShaderBinValidCRCItor itor = gRenDev->m_cEF.m_Bin.m_BinValidCRCs.find(pBin->m_dwName); - if (itor == gRenDev->m_cEF.m_Bin.m_BinValidCRCs.end()) - { - gRenDev->m_cEF.m_Bin.m_BinValidCRCs.insert(FXShaderBinValidCRCItor::value_type(pBin->m_dwName, false)); - } - - m_Bin.DeleteFromCache(pBin); - pBin = m_Bin.GetBinShader(pSH->m_NameShader, false, nCRC32); - } - } -#endif - bSuccess = m_Bin.ParseBinFX(pBin, pSH, nMaskGen); -#ifdef SHADERS_SERIALIZING - if (CRenderer::CV_r_shadersExport && gRenDev->IsShaderCacheGenMode()) - { - //Shader compilation must be enabled for export, to allow reading the token table from the fxcbs in the USER dir - int oldAllowCompilation = CRenderer::CV_r_shadersAllowCompilation; - CRenderer::CV_r_shadersAllowCompilation = 1; - - if (bSuccess) - { - // CheckFXBExists() used to only be queried here; however, that function will create the SResource under certain - // conditions if it does not exist and can erroneously cause ExportShader to not be called on the first time a shader .fxb - // is created. - if (!DoesSResourceExist(pSH) || !CheckFXBExists(pSH)) - { - bool shaderExported = ExportShader(pSH, m_Bin); -#ifdef SHADER_SERIALIZE_VERBOSE - if (!shaderExported) - { - CryLog("[CShaderSerialize] ExportShader failed for shader %s\n", pSH->GetName()); - } -#else - AZ_UNUSED(shaderExported); -#endif - } -#ifdef SHADER_SERIALIZE_VERBOSE - else - { - CryLog("[CShaderSerialize] Not exporting shader %s, it already exists\n", pSH->GetName()); - } -#endif - } - - CRenderer::CV_r_shadersAllowCompilation = oldAllowCompilation; - } -#endif - } - else - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "[SHADERS] Failed to load shader '%s'!", pSH->m_NameShader.c_str()); - pSH->m_Flags |= EF_NOTFOUND; - } - } - pSH->m_Flags |= EF_LOADED; - - EBUS_QUEUE_EVENT(AZ::MaterialNotificationEventBus, OnShaderLoaded, pSH); -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.cpp deleted file mode 100644 index 28904ff7c2..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.cpp +++ /dev/null @@ -1,999 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#ifdef SHADERS_SERIALIZING - -bool CShaderSerialize::_OpenSResource(float fVersion, SSShaderRes* pSR, CShader* pSH, int nCache, CResFile* pRF, bool bReadOnly) -{ - assert(nCache == CACHE_USER || nCache == CACHE_READONLY); - - SSShaderCacheHeader hd; - ZeroStruct(hd); - bool bValid = true; - bool bCheckValid = true; - if (!CRenderer::CV_r_shadersAllowCompilation) - { - bCheckValid = false; - } - - //uint64 writeTimeCFX=0; - - //See if resfile is in assets dir - if (!pRF->mfOpen(RA_READ | (CParserBin::m_bEndians ? RA_ENDIANS : 0), NULL, NULL)) - { - pRF->mfClose(); - bValid = false; - } - - if (bValid) - { - pRF->mfFileSeek(CShaderMan::s_cNameHEAD, 0, SEEK_SET); - pRF->mfFileRead2(CShaderMan::s_cNameHEAD, sizeof(SSShaderCacheHeader), &hd); - if (CParserBin::m_bEndians) - { - SwapEndian(hd, eBigEndian); - } - - if (hd.m_SizeOf != sizeof(SSShaderCacheHeader)) - { - bValid = false; - } - else if (fVersion && (hd.m_MajorVer != (int)fVersion || hd.m_MinorVer != (int)(((float)fVersion - (float)(int)fVersion) * 10.1f))) - { - bValid = false; - - //if (CRenderer::CV_r_shadersdebug==2) - { - LogWarning("WARNING: Shader resource '%s' version mismatch (Resource: %s, Expected: %.1f)", pRF->mfGetFileName(), hd.m_szVer, fVersion); - } - } - - if (bCheckValid) - { - char nameSrc[256]; - sprintf_s(nameSrc, "%sCryFX/%s.%s", gRenDev->m_cEF.m_ShadersPath.c_str(), pSH->GetName(), "cfx"); - uint32 srcCRC = pSH->m_SourceCRC32; - - if (!srcCRC) - { - srcCRC = gEnv->pCryPak->ComputeCRC(nameSrc); - pSH->m_SourceCRC32 = srcCRC; //Propagate to shader, prevent recalculation - } - - if (srcCRC && srcCRC != hd.m_SourceCRC32) - { - bValid = false; - - //if (CRenderer::CV_r_shadersdebug==2) - { - LogWarning("WARNING: Shader resource '%s' src CRC mismatch", pRF->mfGetFileName()); - } - } - } - - // If we failed a version or CRC check, close our resource file since we may try opening it again later - if (!bValid) - { - pRF->mfClose(); - } - - if (bValid && nCache == CACHE_USER) - { - pRF->mfClose(); - if (!pRF->mfOpen(RA_READ | (CParserBin::m_bEndians ? RA_ENDIANS : 0) | RA_WRITE, NULL, NULL)) - { - pRF->mfClose(); - bValid = false; - } - } - } - if (!bValid && nCache == CACHE_USER && !bReadOnly && pSH->m_CRC32) //Create ResFile - { - if (!pRF->mfOpen(RA_CREATE | (CParserBin::m_bEndians ? RA_ENDIANS : 0), NULL, NULL)) - { - return false; - } - - SDirEntry de; - de.Name = CShaderMan::s_cNameHEAD; - de.size = sizeof(SSShaderCacheHeader); - hd.m_SizeOf = sizeof(SSShaderCacheHeader); - hd.m_MinorVer = (int)(((float)fVersion - (float)(int)fVersion) * 10.1f); - hd.m_MajorVer = (int)fVersion; - hd.m_CRC32 = pSH->m_CRC32; - hd.m_SourceCRC32 = pSH->m_SourceCRC32; - sprintf_s(hd.m_szVer, "Ver: %.1f", fVersion); - SSShaderCacheHeader hdTemp, * pHD; - pHD = &hd; - if (CParserBin::m_bEndians) - { - hdTemp = hd; - SwapEndian(hdTemp, eBigEndian); - pHD = &hdTemp; - } - - //create dir - pRF->mfFileAdd(&de); - //open dir and populate data - SDirEntryOpen* pOpenDir = pRF->mfOpenEntry(&de); - pOpenDir->pData = pHD; - pOpenDir->nSize = de.size; - - pRF->mfFlush(); - bValid = true; - } - - if (!bValid) - { - SAFE_DELETE(pRF); - } - - if (pSR->m_pRes[nCache] && (pSR->m_pRes[nCache] != pRF)) - { - SAFE_DELETE(pSR->m_pRes[nCache]); - } - - pSR->m_pRes[nCache] = pRF; - pSR->m_Header[nCache] = hd; - pSR->m_bReadOnly[nCache] = bReadOnly; - - if (bValid && !pSH->m_CRC32) - { - pSH->m_CRC32 = hd.m_CRC32; - } - - return bValid; -} - -bool CShaderSerialize::OpenSResource(const char* szName, SSShaderRes* pSR, CShader* pSH, bool bDontUseUserFolder, bool bReadOnly) -{ - stack_string szReadOnly = szName; - - // ShaderCacheGen behavior: - // CACHE_READONLY is not really used when exporting the .fxb, so we append the @usercache@ alias to the relative shader path - // here as well. We cannot just leave this as the relative Shaders/Cache/Foo.fxb value because then it creates a new - // file in the asset cache as @assets@/Shaders/Cache/Foo.fxb, which is illegal (since only AP has the authority to write here) - // Game runtime behavior: - // We can't simply set both the CACHE_READONLY and CACHE_USER entries to be the same file path because then the shader caching - // system treats these entries the same. CACHE_READONLY acts more as a template while CACHE_USER is the actual file with all - // of the shader permutation entries. They need different file names (that have the same relative shader path) in order - // for the CResFiles to be treated differently by the caching system. - if (gRenDev->IsShaderCacheGenMode()) - { - szReadOnly = stack_string(gRenDev->m_cEF.m_szCachePath.c_str()) + stack_string(szName); - } - - CResFile* rfRO = new CResFile(szReadOnly); - float fVersion = FX_CACHE_VER + FX_SER_CACHE_VER; - bool bValidRO = _OpenSResource(fVersion, pSR, pSH, bDontUseUserFolder ? CACHE_READONLY : CACHE_USER, rfRO, bReadOnly); - - bool bValidUser = false; -#if !defined(SHADER_NO_SOURCES) - CResFile* rfUser; - if (!bDontUseUserFolder) - { - stack_string szUser = stack_string(gRenDev->m_cEF.m_szCachePath.c_str()) + stack_string(szName); - rfUser = new CResFile(szUser.c_str()); - bValidUser = _OpenSResource(fVersion, pSR, pSH, CACHE_USER, rfUser, bReadOnly); - } -#endif - - return (bValidRO || bValidUser); -} - -bool CShaderSerialize::CreateSResource(CShader* pSH, SSShaderRes* pSR, [[maybe_unused]] CCryNameTSCRC& SName, bool bDontUseUserFolder, bool bReadOnly) -{ - AZStd::string dstName; - dstName.reserve(512); - - if (m_customSerialisePath.size()) - { - dstName = m_customSerialisePath.c_str(); - } - dstName += gRenDev->m_cEF.m_ShadersCache; - dstName += pSH->GetName(); - dstName += ".fxb"; - - bool bRes = OpenSResource(dstName.c_str(), pSR, pSH, bDontUseUserFolder, bReadOnly); - AZ_Error("CShaderSerialize", bRes, "Failed to open '%s' with bDontUseUserFolder=%s and bReadOnly=%s", dstName.c_str(), bDontUseUserFolder ? "True" : "False", bReadOnly ? "True" : "False"); - - return bRes; -} - -SSShaderRes* CShaderSerialize::InitSResource(CShader* pSH, bool bDontUseUserFolder, bool bReadOnly) -{ - SSShaderRes* pSR = NULL; - stack_string shaderName = pSH->GetName(); - shaderName += "_GLOBAL"; - CCryNameTSCRC SName = CCryNameTSCRC(shaderName.c_str()); - FXSShaderResItor itS = m_SShaderResources.find(SName); -#if SHADER_NO_SOURCES - bool bCheckValid = false; -#else - bool bCheckValid = true; -#endif - if (itS != m_SShaderResources.end()) - { - pSR = itS->second; - pSR->m_nRefCount++; - if (bCheckValid) - { - int nCache[2] = {-1, -1}; - if (!bReadOnly || bDontUseUserFolder) - { - nCache[0] = CACHE_USER; - } - else - if (!bDontUseUserFolder || bReadOnly) - { - nCache[0] = CACHE_USER; - nCache[1] = CACHE_READONLY; - } - for (int i = 0; i < 2; i++) - { - if (nCache[i] < 0 || !pSR->m_pRes[i]) - { - continue; - } - - //if the shader has a CRC then we can test, generally it is only valid during cache gen - if (pSH->m_CRC32 != 0 && pSR->m_Header[i].m_CRC32 != pSH->m_CRC32) - { - //CryLogAlways("CRC check failed in serialise: 0x%x source: 0x%x\n", pSR->m_Header[i].m_CRC32, pSH->m_CRC32); - SAFE_DELETE(pSR->m_pRes[i]); - } - } - bool bValid = true; - if (!bReadOnly && !pSR->m_pRes[CACHE_USER]) - { - bValid = false; - } - else - if ((!bDontUseUserFolder || bReadOnly) && !pSR->m_pRes[CACHE_READONLY] && !pSR->m_pRes[CACHE_USER]) - { - bValid = false; - } - if (!bValid) - { - CreateSResource(pSH, pSR, SName, bDontUseUserFolder, bReadOnly); - } - else - { - //printf("Reusing existing .fxb for %s\n", pSH->GetName() ); - } - } - } - else - { - pSR = new SSShaderRes; - bool bRes = CreateSResource(pSH, pSR, SName, bDontUseUserFolder, bReadOnly); - - if (bRes) - { - m_SShaderResources.insert(FXSShaderResItor::value_type(SName, pSR)); - } - else - { - SAFE_DELETE(pSR); - } - } - - if (pSH->m_CRC32 == 0 && pSR) - { - if (pSR->m_pRes[CACHE_READONLY]) - { - pSH->m_CRC32 = pSR->m_Header[CACHE_READONLY].m_CRC32; - } - else if (pSR->m_pRes[CACHE_USER]) - { - pSH->m_CRC32 = pSR->m_Header[CACHE_USER].m_CRC32; - } - } - - return pSR; -} - -void CShaderSerialize::ClearSResourceCache() -{ - const FXSShaderResItor end_it = m_SShaderResources.end(); - FXSShaderResItor it = m_SShaderResources.begin(); - - for (; it != end_it; it++) - { - SAFE_DELETE(it->second); - } - - m_SShaderResources.clear(); -} - -bool CShaderSerialize::DoesSResourceExist(CShader* pSH) -{ - stack_string shaderName = pSH->GetName(); - shaderName += "_GLOBAL"; - CCryNameTSCRC SName = CCryNameTSCRC(shaderName.c_str()); - FXSShaderResItor itS = m_SShaderResources.find(SName); - if (itS != m_SShaderResources.end()) - { - return true; - } - - return false; -} - -bool CShaderSerialize::ExportHWShader(CHWShader* pShader, SShaderSerializeContext& SC) -{ - if (!pShader) - { - return false; - } - - bool bRes = pShader->Export(SC); - - return bRes; -} -CHWShader* CShaderSerialize::ImportHWShader(SShaderSerializeContext& SC, int nOffs, uint32 CRC32, CShader* pSH) -{ - CHWShader* pRes = CHWShader::Import(SC, nOffs, CRC32, pSH); - - return pRes; -} - -void CShaderSerialize::ExportHWShaderStage(SShaderSerializeContext& SC, CHWShader* shader, uint32& outShaderOffset) -{ - if ( shader ) - { - outShaderOffset = SC.Data.Num(); - if ( !ExportHWShader(shader,SC) ) - { - outShaderOffset = -1; - CryFatalError("Shader export failed."); - } - } - else - { - outShaderOffset = -1; - } -} - -bool CShaderSerialize::ExportShader(CShader* pSH, CShaderManBin& binShaderMgr) -{ -#ifdef SHADER_SERIALIZE_VERBOSE - CryLogAlways("[CShaderSerialize] ExportShader: %s flags: 0x%llx mdvFlags: 0x%x\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV); -#endif - - bool bRes = true; - - //Use user folder on export? - SSShaderRes* pSR = InitSResource(pSH, false /*((gRenDev->m_cEF.m_nCombinations > 0) || !CRenderer::CV_r_shadersuserfolder)*/, false); - - uint32 i; - int j; - - if (!pSR || !pSR->m_pRes[CACHE_USER]) - { - return false; - } - - SShaderSerializeContext SC; - - SC.SSR.m_eSHDType = pSH->m_eSHDType; - SC.SSR.m_Flags = pSH->m_Flags; - SC.SSR.m_Flags2 = pSH->m_Flags2; - SC.SSR.m_nMDV = pSH->m_nMDV; - SC.SSR.m_vertexFormatEnum = pSH->m_vertexFormat.GetEnum(); - SC.SSR.m_eCull = pSH->m_eCull; - //SC.SSR.m_nMaskCB = pSH->m_nMaskCB; //maskCB generated on HW shader activation - SC.SSR.m_eShaderType = pSH->m_eShaderType; - SC.SSR.m_nMaskGenFX = pSH->m_nMaskGenFX; - - SC.SSR.m_nTechniques = pSH->m_HWTechniques.Num(); - - SShaderFXParams& params = binShaderMgr.mfGetFXParams(pSH); - - SC.SSR.m_nPublicParams = params.m_PublicParams.size(); - for (i = 0; i < SC.SSR.m_nPublicParams; i++) - { - SSShaderParam PR; - SShaderParam& P = params.m_PublicParams[i]; - PR.m_nameIdx = SC.AddString(P.m_Name.c_str()); - PR.m_Type = P.m_Type; - PR.m_Value = P.m_Value; - PR.m_nScriptOffs = SC.AddString(P.m_Script.c_str()); - PR.m_eSemantic = P.m_eSemantic; - SC.Params.Add(PR); - } - - SC.SSR.m_nFXParams = params.m_FXParams.size(); - for (i = 0; i < SC.SSR.m_nFXParams; i++) - { - params.m_FXParams[i].Export(SC); - } - - SC.SSR.m_nFXSamplers = params.m_FXSamplers.size(); - for (i = 0; i < SC.SSR.m_nFXSamplers; i++) - { - params.m_FXSamplers[i].Export(SC); - } - - SC.SSR.m_nFXTextures = params.m_FXTextures.size(); - for (i = 0; i < SC.SSR.m_nFXTextures; i++) - { - params.m_FXTextures[i].Export(SC); - } - - SC.SSR.m_nFXTexSamplers = params.m_FXSamplersOld.size(); - for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++) - { - params.m_FXSamplersOld[i].Export(SC); - } - - SC.SSR.m_nFXTexRTs = SC.FXTexRTs.Num(); - - for (i = 0; i < SC.SSR.m_nTechniques; i++) - { - SSShaderTechnique ST; - SShaderTechnique* pT = pSH->m_HWTechniques[i]; - ST.m_nPreprocessFlags = pT->m_nPreprocessFlags; - ST.m_nNameOffs = SC.AddString(pT->m_NameStr.c_str()); - ST.m_Flags = pT->m_Flags; - - int TECH_MAX = TTYPE_MAX; - - for (j = 0; j < TECH_MAX; j++) - { - ST.m_nTechnique[j] = pT->m_nTechnique[j]; - } - ST.m_nREs = pT->m_REs.Num(); - - ST.m_nPassesOffs = SC.Passes.Num(); - ST.m_nPasses = pT->m_Passes.Num(); - SC.SSR.m_nPasses += ST.m_nPasses; - for (j = 0; j < ST.m_nPasses; j++) - { - SSShaderPass PS; - SShaderPass& P = pT->m_Passes[j]; - PS.m_RenderState = P.m_RenderState; - PS.m_eCull = P.m_eCull; - PS.m_AlphaRef = P.m_AlphaRef; - PS.m_PassFlags = P.m_PassFlags; - - assert(!(SC.Data.Num() & 0x3)); - - ExportHWShaderStage( SC, P.m_VShader, PS.m_nVShaderOffs ); - ExportHWShaderStage( SC, P.m_HShader, PS.m_nHShaderOffs ); - ExportHWShaderStage( SC, P.m_DShader, PS.m_nDShaderOffs ); - ExportHWShaderStage( SC, P.m_GShader, PS.m_nGShaderOffs ); - ExportHWShaderStage( SC, P.m_PShader, PS.m_nPShaderOffs ); - ExportHWShaderStage( SC, P.m_CShader, PS.m_nCShaderOffs ); - - - SC.Passes.Add(PS); - } - - ST.m_nREsOffs = (ST.m_nREs > 0) ? SC.Data.Num() : -1; - for (j = 0; j < ST.m_nREs; j++) - { - CRendElementBase* pRE = pT->m_REs[j]; - uint32 type = pRE->m_Type; - sAddData(SC.Data, type); - pRE->mfExport(SC); - sAlignData(SC.Data, 4); - } - SC.Techniques.AddElem(ST); - } - - TArray Data; - - //DEBUG - prevent Data reallocs - //Data.Alloc(1024*1024); - - uint32 nPublicParamsOffset; - uint32 nFXParamsOffset; - uint32 nFXSamplersOffset; - uint32 nFXTexturesOffset; - uint32 nFXTexSamplersOffset; - uint32 nFXTexRTsOffset; - uint32 nTechOffset; - uint32 nPassOffset; - uint32 nStringsOffset; - uint32 nDataOffset; - - //sAddData(Data, SC.SSR); - SC.SSR.Export(Data); - sAddDataArray(Data, SC.Params, nPublicParamsOffset); - sAddDataArray(Data, SC.FXParams, nFXParamsOffset); - sAddDataArray(Data, SC.FXSamplers, nFXSamplersOffset); - sAddDataArray(Data, SC.FXTextures, nFXTexturesOffset); - sAddDataArray(Data, SC.FXTexSamplers, nFXTexSamplersOffset); - sAddDataArray(Data, SC.FXTexRTs, nFXTexRTsOffset); - sAddDataArray(Data, SC.Techniques, nTechOffset); - sAddDataArray(Data, SC.Passes, nPassOffset); - sAddDataArray_POD(Data, SC.Strings, nStringsOffset); - sAddDataArray_POD(Data, SC.Data, nDataOffset); - - SSShader* pSSR = (SSShader*)&Data[0]; - pSSR->m_nPublicParamsOffset = nPublicParamsOffset; - pSSR->m_nFXParamsOffset = nFXParamsOffset; - pSSR->m_nFXSamplersOffset = nFXSamplersOffset; - pSSR->m_nFXTexturesOffset = nFXTexturesOffset; - pSSR->m_nFXTexSamplersOffset = nFXTexSamplersOffset; - pSSR->m_nFXTexRTsOffset = nFXTexRTsOffset; - pSSR->m_nTechOffset = nTechOffset; - pSSR->m_nPassOffset = nPassOffset; - pSSR->m_nStringsOffset = nStringsOffset; - pSSR->m_nDataOffset = nDataOffset; - pSSR->m_nDataSize = SC.Data.Num(); - pSSR->m_nStringsSize = SC.Strings.Num(); - - if (CParserBin::m_bEndians) - { - SwapEndian(pSSR->m_nPublicParamsOffset, eBigEndian); - SwapEndian(pSSR->m_nFXParamsOffset, eBigEndian); - SwapEndian(pSSR->m_nFXSamplersOffset, eBigEndian); - SwapEndian(pSSR->m_nFXTexturesOffset, eBigEndian); - SwapEndian(pSSR->m_nFXTexRTsOffset, eBigEndian); - SwapEndian(pSSR->m_nTechOffset, eBigEndian); - SwapEndian(pSSR->m_nPassOffset, eBigEndian); - SwapEndian(pSSR->m_nStringsOffset, eBigEndian); - SwapEndian(pSSR->m_nDataOffset, eBigEndian); - SwapEndian(pSSR->m_nDataSize, eBigEndian); - SwapEndian(pSSR->m_nStringsSize, eBigEndian); - } - - int nLen = Data.Num(); - SDirEntry de; - char sName[128]; - sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic); - de.Name = CCryNameTSCRC(sName); - de.size = nLen; - - de.flags |= RF_COMPRESS; - pSR->m_pRes[CACHE_USER]->mfFileAdd(&de); - - //create open dir and populate data - SDirEntryOpen* pOpenDir = pSR->m_pRes[CACHE_USER]->mfOpenEntry(&de); - pOpenDir->pData = &Data[0]; - pOpenDir->nSize = de.size; - - //Preserve modification time - - pSR->m_pRes[CACHE_USER]->mfFlush(); - - return bRes; -} - -float g_fTime0; -float g_fTime1; -float g_fTime2; - -bool CShaderSerialize::CheckFXBExists(CShader* pSH) -{ - SSShaderRes* pSR = InitSResource(pSH, false, true); - if (!pSR || (!pSR->m_Header[CACHE_USER].m_CRC32 && !pSR->m_Header[CACHE_READONLY].m_CRC32)) - { - return false; - } - - char sName[128]; - sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic); - - CCryNameTSCRC CName = CCryNameTSCRC(sName); - SDirEntry* pDE = NULL; - CResFile* pRes = NULL; - - for (int i = 0; i < 2; i++) - { - pRes = pSR->m_pRes[i]; - if (!pRes) - { - continue; - } - pDE = pRes->mfGetEntry(CName); - - if (pDE) - { - return true; - } - } - return false; -} - - -CShaderSerialize::ShaderImportResults CShaderSerialize::ImportShader(CShader* pSH, CShaderManBin& binShaderMgr) -{ - if (CParserBin::m_bEndians) - { - CryFatalError("CShaderSerialize - cross platform import not supported"); - } - - float fTime0 = iTimer->GetAsyncCurTime(); - - SSShaderRes* pSR = NULL; - uint32 i; - int j; - char sName[128]; - sprintf_s(sName, "(%llx)(%llx)", pSH->m_nMaskGenFX, pSH->m_maskGenStatic); - CCryNameTSCRC CName = CCryNameTSCRC(sName); - SDirEntry* pDE = NULL; - CResFile* pRes = NULL; - - // Not found yet - if (!pDE || !pRes) - { - //try global cache - pSR = InitSResource(pSH, !CRenderer::CV_r_shadersAllowCompilation, true); - - if (pSR && (pSR->m_Header[CACHE_USER].m_CRC32 != 0 || pSR->m_Header[CACHE_READONLY].m_CRC32 != 0)) - { - for (i = 0; i < 2; i++) - { - pRes = pSR->m_pRes[i]; - if (!pRes) - { - continue; - } - pDE = pRes->mfGetEntry(CName); - if (pDE) - { - break; - } - } - } - - if (!pDE && !pSR) - { - // The .cfx has no associated .fxb, so this is a guaranteed failure on import. - return SHADER_IMPORT_FAILURE; - } - else if (!pDE) - { - // We have a shader import table but this specific permutation is missing - return SHADER_IMPORT_MISSING_ENTRY; - } - } - - CShader* pSave = gRenDev->m_RP.m_pShader; - gRenDev->m_RP.m_pShader = pSH; - assert(gRenDev->m_RP.m_pShader != 0); - - pRes->mfFileRead(pDE); - byte* pData = (byte*)pRes->mfFileGetBuf(pDE); - if (!pData) - { - // Malformed fxb - return SHADER_IMPORT_FAILURE; - } - - //printf("[CShaderSerialize] Import Shader: %s flags: 0x%llx mdvFlags: 0x%x from %s cache %s\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV, bLoadedFromLevel ? "LEVEL" : "GLOBAL", pSR->m_pRes[i]->mfGetFileName()); - - byte* pSrc = pData; - g_fTime0 += iTimer->GetAsyncCurTime() - fTime0; - - float fTime1 = iTimer->GetAsyncCurTime(); - - SShaderFXParams& fxParams = binShaderMgr.mfGetFXParams(pSH); - - SShaderSerializeContext SC; - SC.SSR.Import(pSrc); - -#ifdef SHADER_SERIALIZE_VERBOSE - CryLog("[CShaderSerialize] Import Shader: %s flags: 0x%llx mdvFlags: 0x%x from global cache %s\n", pSH->GetName(), pSH->m_nMaskGenFX, pSH->m_nMDV, pSR->m_pRes[i]->mfGetFileName()); -#endif - - if (SC.SSR.m_nPublicParams) - { - SC.Params.ReserveNoClear(SC.SSR.m_nPublicParams); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.Params[0], &pSrc[SC.SSR.m_nPublicParamsOffset], sizeof(SSShaderParam) * SC.SSR.m_nPublicParams); - } - else - { - uint32 offset = SC.SSR.m_nPublicParamsOffset; - for (i = 0; i < SC.SSR.m_nPublicParams; i++) - { - SC.Params[i].Import(&pSrc[offset]); - offset += sizeof(SSShaderParam); - } - } - } - - if (SC.SSR.m_nFXParams) - { - SC.FXParams.ReserveNoClear(SC.SSR.m_nFXParams); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.FXParams[0], &pSrc[SC.SSR.m_nFXParamsOffset], sizeof(SSFXParam) * SC.SSR.m_nFXParams); - } - else - { - uint32 offset = SC.SSR.m_nFXParamsOffset; - for (i = 0; i < SC.SSR.m_nFXParams; i++) - { - SC.FXParams[i].Import(&pSrc[offset]); - offset += sizeof(SSFXParam); - } - } - } - - if (SC.SSR.m_nFXSamplers) - { - SC.FXSamplers.ReserveNoClear(SC.SSR.m_nFXSamplers); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.FXSamplers[0], &pSrc[SC.SSR.m_nFXSamplersOffset], sizeof(SSFXSampler) * SC.SSR.m_nFXSamplers); - } - else - { - uint32 offset = SC.SSR.m_nFXSamplersOffset; - for (i = 0; i < SC.SSR.m_nFXSamplers; i++) - { - SC.FXSamplers[i].Import(&pSrc[offset]); - offset += sizeof(SSTexSamplerFX); - } - } - } - - if (SC.SSR.m_nFXTextures) - { - SC.FXTextures.ReserveNoClear(SC.SSR.m_nFXTextures); - memcpy(&SC.FXTextures[0], &pSrc[SC.SSR.m_nFXTexturesOffset], sizeof(SSFXTexture) * SC.SSR.m_nFXTextures); - } - - if (SC.SSR.m_nFXTexSamplers) - { - SC.FXTexSamplers.ReserveNoClear(SC.SSR.m_nFXTexSamplers); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.FXTexSamplers[0], &pSrc[SC.SSR.m_nFXTexSamplersOffset], sizeof(SSTexSamplerFX) * SC.SSR.m_nFXTexSamplers); - } - else - { - uint32 offset = SC.SSR.m_nFXTexSamplersOffset; - for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++) - { - SC.FXTexSamplers[i].Import(&pSrc[offset]); - offset += sizeof(SSTexSamplerFX); - } - } - } - - if (SC.SSR.m_nFXTexRTs) - { - SC.FXTexRTs.ReserveNoClear(SC.SSR.m_nFXTexRTs); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.FXTexRTs[0], &pSrc[SC.SSR.m_nFXTexRTsOffset], sizeof(SSHRenderTarget) * SC.SSR.m_nFXTexRTs); - } - else - { - uint32 offset = SC.SSR.m_nFXTexRTsOffset; - for (i = 0; i < SC.SSR.m_nFXTexRTs; i++) - { - SC.FXTexRTs[i].Import(&pSrc[offset]); - offset += sizeof(SSHRenderTarget); - } - } - } - - if (SC.SSR.m_nTechniques) - { - SC.Techniques.ReserveNoClear(SC.SSR.m_nTechniques); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.Techniques[0], &pSrc[SC.SSR.m_nTechOffset], sizeof(SSShaderTechnique) * SC.SSR.m_nTechniques); - } - else - { - uint32 offset = SC.SSR.m_nTechOffset; - for (i = 0; i < SC.SSR.m_nTechniques; i++) - { - SC.Techniques[i].Import(&pSrc[offset]); - offset += sizeof(SSShaderTechnique); - } - } - } - - if (SC.SSR.m_nPasses) - { - SC.Passes.ReserveNoClear(SC.SSR.m_nPasses); - - if (!CParserBin::m_bEndians) - { - memcpy(&SC.Passes[0], &pSrc[SC.SSR.m_nPassOffset], sizeof(SSShaderPass) * SC.SSR.m_nPasses); - } - else - { - uint32 offset = SC.SSR.m_nPassOffset; - for (i = 0; i < SC.SSR.m_nPasses; i++) - { - SC.Passes[i].Import(&pSrc[offset]); - offset += sizeof(SSShaderPass); - } - } - } - - if (SC.SSR.m_nStringsSize) - { - SC.Strings.ReserveNoClear(SC.SSR.m_nStringsSize); - memcpy(&SC.Strings[0], &pSrc[SC.SSR.m_nStringsOffset], SC.SSR.m_nStringsSize); - } - - if (SC.SSR.m_nDataSize) - { - SC.Data.ReserveNoClear(SC.SSR.m_nDataSize); - memcpy(&SC.Data[0], &pSrc[SC.SSR.m_nDataOffset], SC.SSR.m_nDataSize); - } - - pRes->mfFileClose(pDE); - - g_fTime1 += iTimer->GetAsyncCurTime() - fTime1; - - float fTime2 = iTimer->GetAsyncCurTime(); - - pSH->m_eSHDType = SC.SSR.m_eSHDType; - - //TODO |= on flags? will we lose flags at runtime - pSH->m_Flags = SC.SSR.m_Flags; - pSH->m_Flags2 = SC.SSR.m_Flags2; - pSH->m_nMDV = SC.SSR.m_nMDV; - - AZ_Assert(SC.SSR.m_vertexFormatEnum < eVF_Max, "Bad vertex format index. Is the shader cache out of date?"); - pSH->m_vertexFormat = gRenDev->m_RP.m_vertexFormats[SC.SSR.m_vertexFormatEnum]; - - pSH->m_eCull = SC.SSR.m_eCull; - pSH->m_eShaderType = SC.SSR.m_eShaderType; - pSH->m_nMaskGenFX = SC.SSR.m_nMaskGenFX; - - fxParams.m_PublicParams.reserve(fxParams.m_PublicParams.size() + SC.SSR.m_nPublicParams); - - for (i = 0; i < SC.SSR.m_nPublicParams; i++) - { - SSShaderParam& PR = SC.Params[i]; - SShaderParam P; - const char* pName = sString(PR.m_nameIdx, SC.Strings); - P.m_Name = pName; - P.m_Type = PR.m_Type; - P.m_Value = PR.m_Value; - P.m_Script = sString(PR.m_nScriptOffs, SC.Strings); - fxParams.m_PublicParams.push_back(P); - } - - fxParams.m_FXParams.reserve(fxParams.m_FXParams.size() + SC.SSR.m_nFXParams); - - for (i = 0; i < SC.SSR.m_nFXParams; i++) - { - SFXParam fxParam; - fxParam.Import(SC, &SC.FXParams[i]); - fxParams.m_FXParams.push_back(fxParam); - } - - fxParams.m_FXSamplersOld.reserve(fxParams.m_FXSamplersOld.size() + SC.SSR.m_nFXTexSamplers); - - for (i = 0; i < SC.SSR.m_nFXTexSamplers; i++) - { - STexSamplerFX fxTexSampler; - fxTexSampler.Import(SC, &SC.FXTexSamplers[i]); - fxParams.m_FXSamplersOld.push_back(fxTexSampler); - } - - fxParams.m_FXSamplers.reserve(fxParams.m_FXSamplers.size() + SC.SSR.m_nFXSamplers); - - for (i = 0; i < SC.SSR.m_nFXSamplers; i++) - { - SFXSampler fxSampler; - fxSampler.Import(SC, &SC.FXSamplers[i]); - fxParams.m_FXSamplers.push_back(fxSampler); - } - - fxParams.m_FXTextures.reserve(fxParams.m_FXTextures.size() + SC.SSR.m_nFXTextures); - - for (i = 0; i < SC.SSR.m_nFXTextures; i++) - { - SFXTexture fxTexture; - fxTexture.Import(SC, &SC.FXTextures[i]); - fxParams.m_FXTextures.push_back(fxTexture); - } - - for (i = 0; i < SC.SSR.m_nTechniques; i++) - { - SSShaderTechnique& ST = SC.Techniques[i]; - SShaderTechnique* pT = new SShaderTechnique(pSH); - pT->m_NameStr = sString(ST.m_nNameOffs, SC.Strings); - pT->m_NameCRC = pT->m_NameStr.c_str(); - pT->m_Flags = ST.m_Flags; - pT->m_nPreprocessFlags = ST.m_nPreprocessFlags; - for (j = 0; j < TTYPE_MAX; j++) - { - pT->m_nTechnique[j] = ST.m_nTechnique[j]; - } - - if (ST.m_nPasses) - { - int nOffs = ST.m_nPassesOffs; - pT->m_Passes.reserve(ST.m_nPasses); - for (j = 0; j < ST.m_nPasses; j++) - { - SSShaderPass& PS = SC.Passes[j + nOffs]; - SShaderPass* P = pT->m_Passes.AddIndex(1); - P->m_RenderState = PS.m_RenderState; - P->m_eCull = PS.m_eCull; - P->m_AlphaRef = PS.m_AlphaRef; - P->m_PassFlags = PS.m_PassFlags; - - P->m_VShader = ImportHWShader(SC, PS.m_nVShaderOffs, pSH->m_CRC32, pSH); - P->m_PShader = ImportHWShader(SC, PS.m_nPShaderOffs, pSH->m_CRC32, pSH); - P->m_GShader = ImportHWShader(SC, PS.m_nGShaderOffs, pSH->m_CRC32, pSH); - P->m_HShader = ImportHWShader(SC, PS.m_nHShaderOffs, pSH->m_CRC32, pSH); - P->m_DShader = ImportHWShader(SC, PS.m_nDShaderOffs, pSH->m_CRC32, pSH); - P->m_CShader = ImportHWShader(SC, PS.m_nCShaderOffs, pSH->m_CRC32, pSH); - } - } - - uint32 nREOffset = ST.m_nREsOffs; - - for (j = 0; j < ST.m_nREs; j++) - { - EDataType dataType = *((EDataType*)&SC.Data[nREOffset]); - - if (CParserBin::m_bEndians) - { - SwapEndianEnum(dataType, eBigEndian); - } - - nREOffset += sizeof(EDataType); - - switch (dataType) - { - case eDATA_LensOptics: - { - CRELensOptics* pLensOptics = new CRELensOptics; - pLensOptics->mfImport(SC, nREOffset); - pT->m_REs.push_back(pLensOptics); - } - break; - case eDATA_Beam: - { - CREBeam* pBeam = new CREBeam; - pBeam->mfImport(SC, nREOffset); - pT->m_REs.push_back(pBeam); - } - break; - - default: - CryFatalError("Render element not supported for shader serialising"); - break; - } - - //expects 4 byte aligned - assert(!(nREOffset & 3)); - } - - pSH->m_HWTechniques.AddElem(pT); - } - gRenDev->m_RP.m_pShader = pSave; - - g_fTime2 += iTimer->GetAsyncCurTime() - fTime2; - - return SHADER_IMPORT_SUCCESS; -} - -#endif diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.h b/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.h deleted file mode 100644 index a6d3f92fbb..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderSerialize.h +++ /dev/null @@ -1,1118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __SHADERSERIALIZE_H__ -#define __SHADERSERIALIZE_H__ - -#if defined(SHADERS_SERIALIZING) - -#include "../ResFile.h" - -// Enable this for verbose messages related to r_shadersExport and r_shadersImport -//#define SHADER_SERIALIZE_VERBOSE - -// -// console enums taken from d3d9types.h -// - -enum X360AddressModes -{ - X360TADDRESS_WRAP = 0, - X360TADDRESS_MIRROR = 1, - X360TADDRESS_CLAMP = 2, - X360TADDRESS_MIRRORONCE = 3, - X360TADDRESS_BORDER_HALF = 4, - X360TADDRESS_MIRRORONCE_BORDER_HALF = 5, - X360TADDRESS_BORDER = 6, - X360TADDRESS_MIRRORONCE_BORDER = 7, -}; - -enum X360FilterType -{ - X360TEXF_NONE = 2, - X360TEXF_POINT = 0, - X360TEXF_LINEAR = 1, - X360TEXF_ANISOTROPIC = 4, -}; - -inline void sAlignData(TArray& Dst, uint32 align) -{ - if (align > 0 && (Dst.Num() & (align - 1))) - { - const byte PAD = 0; - int pad = align - (Dst.Num() & (align - 1)); - - for (int i = 0; i < pad; i++) - { - Dst.push_back(PAD); - } - } -} - -template -void sAddData(TArray& Dst, T Src, uint32 align = 0) -{ - int nSize = sizeof(T); - byte* pDst = Dst.Grow(nSize); - - if (CParserBin::m_bEndians) - { - T data = Src; - SwapEndian(data, eBigEndian); - memcpy(pDst, &data, nSize); - } - else - { - memcpy(pDst, &Src, nSize); - } - - if (align > 0) - { - sAlignData(Dst, align); - } -} - -template -void sAddDataArray_POD(TArray& Dst, TArray& Src, uint32& nOffs, uint32 align = 0) -{ - nOffs = Dst.Num(); - int nSize = sizeof(T) * Src.Num(); - if (!nSize) - { - return; - } - T* pDst = (T*)Dst.Grow(nSize); - - if (CParserBin::m_bEndians) - { - for (uint32 i = 0; i < Src.size(); i++) - { - T d = Src[i]; - SwapEndian(d, eBigEndian); - memcpy(pDst, &d, sizeof(T)); - pDst++; - } - } - else - { - memcpy(pDst, &Src[0], nSize); - } - - if (align > 0) - { - sAlignData(Dst, align); - } -} - -template -void sExport(TArray& dst, T& data) -{ -#if defined(AZ_ENABLE_TRACING) - int startNum = dst.Num(); -#endif - - data.Export(dst); - - // DEBUG: Check we wrote the data we expected - // Only works on native export since structures are different sizes on console :( - if (!CParserBin::m_bEndians) - { - AZ_Assert(dst.Num() - startNum == sizeof(T), "ShaderSerialize export size mismatch"); - } -} - -template -void sAddDataArray(TArray& Dst, TArray& Src, uint32& nOffs, uint32 align = 0) -{ - nOffs = Dst.Num(); - int nSize = sizeof(T) * Src.Num(); - if (!nSize) - { - return; - } - - if (CParserBin::m_bEndians) - { - int startNum = Dst.Num(); - - for (uint32 i = 0; i < Src.size(); i++) - { - sExport(Dst, Src[i]); - } - - // DEBUG - compare src and dest, check export was successful - if (!CParserBin::m_bEndians) - { - if (memcmp(&Src[0], &Dst[startNum], nSize) != 0) - { - CryFatalError("Copy failed"); - } - } - } - else - { - byte* pDst = Dst.Grow(nSize); - memcpy(pDst, &Src[0], nSize); - } - - if (align > 0) - { - sAlignData(Dst, align); - } -} - -template -void SwapEndianEnum(T& e, bool bSwapEndian) -{ - uint32 enumConv = e; - SwapEndian(enumConv, bSwapEndian); - e = (T)enumConv; -} - -struct SSShaderCacheHeader -{ - int m_SizeOf; - char m_szVer[16]; - int m_MajorVer; - int m_MinorVer; - uint32 m_CRC32; - uint32 m_SourceCRC32; - SSShaderCacheHeader() - { - memset(this, 0, sizeof(*this)); - } - AUTO_STRUCT_INFO -}; - - -struct SSShaderRes -{ - int m_nRefCount; - CResFile* m_pRes[2]; - SSShaderCacheHeader m_Header[2]; - bool m_bReadOnly[2]; - SSShaderRes() - { - m_nRefCount = 1; - m_pRes[0] = NULL; - m_pRes[1] = NULL; - m_bReadOnly[0] = true; - m_bReadOnly[1] = true; - } - ~SSShaderRes() - { - SAFE_DELETE(m_pRes[0]); - SAFE_DELETE(m_pRes[1]); - } -}; -typedef std::map FXSShaderRes; -typedef FXSShaderRes::iterator FXSShaderResItor; - -struct SSShader -{ - uint64 m_nMaskGenFX; - - EShaderDrawType m_eSHDType; - - uint32 m_Flags; - uint32 m_Flags2; - uint32 m_nMDV; - - uint32 m_vertexFormatEnum; // Base vertex format for the shader (see VertexFormats.h) - ECull m_eCull; // Global culling type - - EShaderType m_eShaderType; - - uint32 m_nTechniques; - uint32 m_nPasses; - uint32 m_nPublicParams; - uint32 m_nFXParams; - uint32 m_nFXSamplers; - uint32 m_nFXTextures; - uint32 m_nFXTexSamplers; - uint32 m_nFXTexRTs; - uint32 m_nDataSize; - uint32 m_nStringsSize; - - uint32 m_nPublicParamsOffset; - uint32 m_nFXParamsOffset; - uint32 m_nFXSamplersOffset; - uint32 m_nFXTexturesOffset; - uint32 m_nFXTexSamplersOffset; - uint32 m_nFXTexRTsOffset; - uint32 m_nTechOffset; - uint32 m_nPassOffset; - uint32 m_nStringsOffset; - uint32 m_nDataOffset; - - SSShader() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nMaskGenFX); - sAddData(dst, (uint32)m_eSHDType); - sAddData(dst, m_Flags); - sAddData(dst, m_Flags2); - sAddData(dst, m_nMDV); - sAddData(dst, m_vertexFormatEnum); - sAddData(dst, (uint32)m_eCull); - sAddData(dst, (uint32)m_eShaderType); - sAddData(dst, m_nTechniques); - sAddData(dst, m_nPasses); - sAddData(dst, m_nPublicParams); - sAddData(dst, m_nFXParams); - sAddData(dst, m_nFXSamplers); - sAddData(dst, m_nFXTextures); - sAddData(dst, m_nFXTexSamplers); - sAddData(dst, m_nFXTexRTs); - sAddData(dst, m_nDataSize); - sAddData(dst, m_nStringsSize); - - sAddData(dst, m_nPublicParamsOffset); - sAddData(dst, m_nFXParamsOffset); - sAddData(dst, m_nFXSamplersOffset); - sAddData(dst, m_nFXTexturesOffset); - sAddData(dst, m_nFXTexSamplersOffset); - sAddData(dst, m_nFXTexRTsOffset); - sAddData(dst, m_nTechOffset); - sAddData(dst, m_nPassOffset); - sAddData(dst, m_nStringsOffset); - sAddData(dst, m_nDataOffset); - - uint32 PAD = 0; - sAddData(dst, PAD); //pad to 64bit - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nMaskGenFX, eBigEndian); - SwapEndianEnum(m_eSHDType, eBigEndian); - ; - SwapEndian(m_Flags, eBigEndian); - ; - SwapEndian(m_Flags2, eBigEndian); - SwapEndian(m_nMDV, eBigEndian); - SwapEndianEnum(m_vertexFormatEnum, eBigEndian); - SwapEndianEnum(m_eCull, eBigEndian); - SwapEndianEnum(m_eShaderType, eBigEndian); - SwapEndian(m_nTechniques, eBigEndian); - SwapEndian(m_nPasses, eBigEndian); - SwapEndian(m_nPublicParams, eBigEndian); - SwapEndian(m_nFXParams, eBigEndian); - SwapEndian(m_nFXSamplers, eBigEndian); - SwapEndian(m_nFXTextures, eBigEndian); - SwapEndian(m_nFXTexSamplers, eBigEndian); - SwapEndian(m_nFXTexRTs, eBigEndian); - SwapEndian(m_nDataSize, eBigEndian); - SwapEndian(m_nStringsSize, eBigEndian); - SwapEndian(m_nPublicParamsOffset, eBigEndian); - SwapEndian(m_nFXParamsOffset, eBigEndian); - SwapEndian(m_nFXSamplersOffset, eBigEndian); - SwapEndian(m_nFXTexturesOffset, eBigEndian); - SwapEndian(m_nFXTexSamplersOffset, eBigEndian); - SwapEndian(m_nFXTexRTsOffset, eBigEndian); - SwapEndian(m_nTechOffset, eBigEndian); - SwapEndian(m_nPassOffset, eBigEndian); - SwapEndian(m_nStringsOffset, eBigEndian); - SwapEndian(m_nDataOffset, eBigEndian); - } - } -}; - -struct SSShaderParam -{ - uint32 m_nameIdx; - EParamType m_Type; - UParamVal m_Value; - int m_nScriptOffs; - uint8 m_eSemantic; - - SSShaderParam() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nameIdx); - sAddData(dst, (uint32)m_Type); - - int sizeWritten = 0; - - switch (m_Type) - { - case eType_BYTE: - sAddData(dst, m_Value.m_Byte); - sizeWritten = sizeof(m_Value.m_Byte); - break; - case eType_BOOL: - sAddData(dst, m_Value.m_Bool); - sizeWritten = sizeof(m_Value.m_Bool); - break; - case eType_SHORT: - sAddData(dst, m_Value.m_Short); - sizeWritten = sizeof(m_Value.m_Short); - break; - case eType_INT: - sAddData(dst, m_Value.m_Int); - sizeWritten = sizeof(m_Value.m_Int); - break; - case eType_HALF: - //half behaves like float? - sAddData(dst, m_Value.m_Float); - sizeWritten = sizeof(m_Value.m_Float); - break; - case eType_FLOAT: - sAddData(dst, m_Value.m_Float); - sizeWritten = sizeof(m_Value.m_Float); - break; - case eType_FCOLOR: - { - for (int i = 0; i < 4; i++) - { - sAddData(dst, m_Value.m_Color[i]); - } - sizeWritten = sizeof(m_Value.m_Color); - } - break; - case eType_VECTOR: - { - for (int i = 0; i < 3; i++) - { - sAddData(dst, m_Value.m_Vector[i]); - } - sizeWritten = sizeof(m_Value.m_Vector); - } - break; - - //case eType_STRING, - //case eType_TEXTURE_HANDLE: - //case eType_CAMERA: - //case eType_UNKNOWN: - default: - CryFatalError("Shader param type not valid for export\n"); - break; - } - - //Pad to union size - byte PAD = 0; - uint32 nPadding = sizeof(UParamVal) - sizeWritten; - - for (uint32 i = 0; i < nPadding; i++) - { - sAddData(dst, PAD); - } - - sAddData(dst, m_nScriptOffs); - sAddData(dst, m_eSemantic); - - // Align for struct padding - sAlignData(dst, 8); - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nameIdx, eBigEndian); - SwapEndianEnum(m_Type, eBigEndian); - - for (int i = 0; i < 4; i++) - { - SwapEndian(m_Value.m_Color[i], eBigEndian); - } - SwapEndian(m_nScriptOffs, eBigEndian); - SwapEndian(m_eSemantic, eBigEndian); - } - } -}; - -struct SSShaderTechnique -{ - int m_nNameOffs; - int m_nPassesOffs; - int m_nPasses; - int m_Flags; - int8 m_nTechnique[TTYPE_MAX]; //use CONSOLE_MAX for now, PC not supported - int m_nREsOffs; - int m_nREs; - uint32 m_nPreprocessFlags; - - SSShaderTechnique() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - sAddData(dst, m_nNameOffs); - sAddData(dst, m_nPassesOffs); - sAddData(dst, m_nPasses); - sAddData(dst, m_Flags); - - // TTYPE_MAX is different on console! - int TECH_MAX = TTYPE_MAX; - - for (int i = 0; i < TECH_MAX; i++) - { - sAddData(dst, m_nTechnique[i]); - } - - sAlignData(dst, 4); - - sAddData(dst, m_nREsOffs); - sAddData(dst, m_nREs); - sAddData(dst, m_nPreprocessFlags); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - //Cannot import non native data due to TTYPE_MAX being different on different platforms - CryFatalError("SSShaderTechnique non-native import not supported"); - - SwapEndian(m_nNameOffs, eBigEndian); - SwapEndian(m_nPassesOffs, eBigEndian); - SwapEndian(m_nPasses, eBigEndian); - SwapEndian(m_Flags, eBigEndian); - - for (int i = 0; i < TTYPE_MAX; i++) - { - SwapEndian(m_nTechnique[i], eBigEndian); - } - - SwapEndian(m_nREsOffs, eBigEndian); - SwapEndian(m_nREs, eBigEndian); - SwapEndian(m_nPreprocessFlags, eBigEndian); - } - } -}; - -struct SSShaderPass -{ - uint32 m_RenderState; - int8 m_eCull; - uint8 m_AlphaRef; - uint16 m_PassFlags; - - uint32 m_nVShaderOffs; - uint32 m_nPShaderOffs; - uint32 m_nGShaderOffs; - uint32 m_nDShaderOffs; - uint32 m_nCShaderOffs; - uint32 m_nHShaderOffs; - - uint32 m_nRenderElemOffset; - - void Export(TArray& dst) - { - sAddData(dst, m_RenderState); - sAddData(dst, m_eCull); - sAddData(dst, m_AlphaRef); - sAddData(dst, m_PassFlags); - - sAddData(dst, m_nVShaderOffs); - sAddData(dst, m_nPShaderOffs); - -#if 1 - //if (CParserBin::PlatformSupportsGeometryShaders() && - // CParserBin::PlatformSupportsHullShaders() && - // CParserBin::PlatformSupportsDomainShaders() && - // CParserBin::PlatformSupportsComputeShaders()) - { - sAddData(dst, m_nGShaderOffs); - sAddData(dst, m_nDShaderOffs); - sAddData(dst, m_nCShaderOffs); - sAddData(dst, m_nHShaderOffs); - } -#endif - - sAddData(dst, m_nRenderElemOffset); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_RenderState, eBigEndian); - SwapEndian(m_eCull, eBigEndian); - SwapEndian(m_AlphaRef, eBigEndian); - SwapEndian(m_PassFlags, eBigEndian); - - SwapEndian(m_nVShaderOffs, eBigEndian); - SwapEndian(m_nPShaderOffs, eBigEndian); - SwapEndian(m_nGShaderOffs, eBigEndian); - SwapEndian(m_nDShaderOffs, eBigEndian); - SwapEndian(m_nCShaderOffs, eBigEndian); - SwapEndian(m_nHShaderOffs, eBigEndian); - - SwapEndian(m_nRenderElemOffset, eBigEndian); - } - } -}; - -struct SSLightEval -{}; - -struct SCHWShader -{ - uint64 m_nMaskGenShader; - uint64 m_nMaskGenFX; - uint64 m_nMaskAnd_RT; - uint64 m_nMaskOr_RT; - - int m_Flags; - uint32 m_nsNameSourceFX; - uint32 m_nsName; - uint32 m_nsEntryFunc; - EHWShaderClass m_eSHClass; - uint32 m_nTokens; - uint32 m_nTableEntries; - uint32 m_nSamplers; - uint32 m_nParams; - uint32 m_dwShaderType; - - SCHWShader() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nMaskGenShader); - sAddData(dst, m_nMaskGenFX); - sAddData(dst, m_nMaskAnd_RT); - sAddData(dst, m_nMaskOr_RT); - sAddData(dst, m_Flags); - sAddData(dst, m_nsNameSourceFX); - sAddData(dst, m_nsName); - sAddData(dst, m_nsEntryFunc); - sAddData(dst, (uint32)m_eSHClass); - sAddData(dst, m_nTokens); - sAddData(dst, m_nTableEntries); - sAddData(dst, m_nSamplers); - sAddData(dst, m_nParams); - sAddData(dst, m_dwShaderType); - - //uint32 PAD=0; - //sAddData(dst, PAD); //pad up to 64bit align due to uint64 - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nMaskGenShader, eBigEndian); - SwapEndian(m_nMaskGenFX, eBigEndian); - SwapEndian(m_nsNameSourceFX, eBigEndian); - SwapEndian(m_nsName, eBigEndian); - SwapEndian(m_nsEntryFunc, eBigEndian); - SwapEndianEnum(m_eSHClass, eBigEndian); - SwapEndian(m_nTokens, eBigEndian); - SwapEndian(m_nTableEntries, eBigEndian); - SwapEndian(m_nSamplers, eBigEndian); - SwapEndian(m_nParams, eBigEndian); - SwapEndian(m_dwShaderType, eBigEndian); - } - } -}; - -struct SSTexSamplerFX -{ - int m_nsName; - int m_nsNameTexture; - - int m_eTexType; - int m_nSamplerSlot; - uint32 m_nFlags; - uint32 m_nTexFlags; - int m_nRTIdx; - uint32 m_bTexState; - STexState ST; - - SSTexSamplerFX() - { - // if any of these assert fails it means the platform headers have changed - // we must update the cached equivalents (see top of file) - - memset(this, 0, sizeof(SSTexSamplerFX)); - } - - SSTexSamplerFX(const SSTexSamplerFX& rhs) - { - memcpy(this, &rhs, sizeof(SSTexSamplerFX)); - } - - SSTexSamplerFX& operator = (const SSTexSamplerFX& rhs) - { - memcpy(this, &rhs, sizeof(SSTexSamplerFX)); - return *this; - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nsName); - sAddData(dst, m_nsNameTexture); - sAddData(dst, m_eTexType); - sAddData(dst, m_nSamplerSlot); - sAddData(dst, m_nFlags); - sAddData(dst, m_nTexFlags); - sAddData(dst, m_nRTIdx); - sAddData(dst, m_bTexState); - - sAddData(dst, ST.m_nMinFilter); - sAddData(dst, ST.m_nMagFilter); - sAddData(dst, ST.m_nMipFilter); - sAddData(dst, ST.m_nAddressU); - sAddData(dst, ST.m_nAddressV); - sAddData(dst, ST.m_nAddressW); - sAddData(dst, ST.m_nAnisotropy); - sAddData(dst, ST.padding); - sAddData(dst, ST.m_dwBorderColor); - - sAddData(dst, ST.m_MipBias); - - uint64 iPad = 0; - sAddData(dst, iPad); //m_pDeviceState - sAddData(dst, ST.m_bActive); - sAddData(dst, ST.m_bComparison); - sAddData(dst, ST.m_bSRGBLookup); - byte bPad = 0; - sAddData(dst, bPad); - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nsName, eBigEndian); - SwapEndian(m_nsNameTexture, eBigEndian); - SwapEndian(m_eTexType, eBigEndian); - SwapEndian(m_nSamplerSlot, eBigEndian); - SwapEndian(m_nFlags, eBigEndian); - SwapEndian(m_nTexFlags, eBigEndian); - SwapEndian(m_nRTIdx, eBigEndian); - SwapEndian(m_bTexState, eBigEndian); - SwapEndian(ST.m_dwBorderColor, eBigEndian); - SwapEndian(ST.m_bActive, eBigEndian); - SwapEndian(ST.m_bComparison, eBigEndian); - SwapEndian(ST.m_bSRGBLookup, eBigEndian); - } - - ST.PostCreate(); - } -}; - -struct SSHRenderTarget -{ - ERenderOrder m_eOrder; - int m_nProcessFlags; // FSPR_ flags - uint32 m_nsTargetName; - int m_nWidth; - int m_nHeight; - ETEX_Format m_eTF; - int m_nIDInPool; - ERTUpdate m_eUpdateType; - uint32 m_bTempDepth; - ColorF m_ClearColor; - float m_fClearDepth; - uint32 m_nFlags; - uint32 m_nFilterFlags; - - SSHRenderTarget() - { - memset(this, 0, sizeof(SSHRenderTarget)); - } - - // = operator to ensure padding is copied - SSHRenderTarget& operator = (const SSHRenderTarget& rhs) - { - memcpy(this, &rhs, sizeof(SSHRenderTarget)); - return *this; - } - - void Export(TArray& dst) - { - sAddData(dst, (uint32)m_eOrder); - sAddData(dst, m_nProcessFlags); - sAddData(dst, m_nsTargetName); - sAddData(dst, m_nWidth); - sAddData(dst, m_nHeight); - - sAddData(dst, (uint8)m_eTF); - byte PAD = 0; - sAddData(dst, PAD); - sAddData(dst, PAD); - sAddData(dst, PAD); - - sAddData(dst, m_nIDInPool); - sAddData(dst, (uint32)m_eUpdateType); - sAddData(dst, m_bTempDepth); - sAddData(dst, m_ClearColor.r); - sAddData(dst, m_ClearColor.g); - sAddData(dst, m_ClearColor.b); - sAddData(dst, m_ClearColor.a); - sAddData(dst, m_fClearDepth); - sAddData(dst, m_nFlags); - sAddData(dst, m_nFilterFlags); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndianEnum(m_eOrder, eBigEndian); - SwapEndian(m_nProcessFlags, eBigEndian); - SwapEndian(m_nsTargetName, eBigEndian); - SwapEndian(m_nWidth, eBigEndian); - SwapEndian(m_nHeight, eBigEndian); - SwapEndianEnum(m_eTF, eBigEndian); - SwapEndian(m_nIDInPool, eBigEndian); - SwapEndianEnum(m_eUpdateType, eBigEndian); - SwapEndian(m_bTempDepth, eBigEndian); - SwapEndian(m_ClearColor.r, eBigEndian); - SwapEndian(m_ClearColor.g, eBigEndian); - SwapEndian(m_ClearColor.b, eBigEndian); - SwapEndian(m_ClearColor.a, eBigEndian); - SwapEndian(m_fClearDepth, eBigEndian); - SwapEndian(m_nFlags, eBigEndian); - SwapEndian(m_nFilterFlags, eBigEndian); - } - } -}; - -struct SSFXParam -{ - int m_nsName; // Parameter name - uint32 m_nFlags; - short m_nParameters; // Number of paramters - short m_nComps; // Number of components in single parameter - uint32 m_nsAnnotations; // Additional parameters (between <>) - uint32 m_nsSemantic; // Parameter app handling type (after ':') - uint32 m_nsValues; // Parameter values (after '=') - byte m_eType; // EParamType - int8 m_nCB; - - short m_nRegister[eHWSC_Num]; - - SSFXParam() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nsName); - sAddData(dst, m_nFlags); - sAddData(dst, m_nParameters); - sAddData(dst, m_nComps); - sAddData(dst, m_nsAnnotations); - sAddData(dst, m_nsSemantic); - sAddData(dst, m_nsValues); - sAddData(dst, m_eType); - sAddData(dst, m_nCB); - - for (int i = 0; i < eHWSC_Num; i++) - { - sAddData(dst, m_nRegister[i]); - } - - // Align for struct padding - sAlignData(dst, 8); - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nsName, eBigEndian); - SwapEndian(m_nFlags, eBigEndian); - SwapEndian(m_nParameters, eBigEndian); - SwapEndian(m_nComps, eBigEndian); - SwapEndian(m_nsAnnotations, eBigEndian); - SwapEndian(m_nsSemantic, eBigEndian); - SwapEndian(m_nsValues, eBigEndian); - SwapEndian(m_eType, eBigEndian); - SwapEndian(m_nCB, eBigEndian); - - for (int i = 0; i < eHWSC_Num; i++) - { - SwapEndian(m_nRegister[i], eBigEndian); - } - } - } -}; - -struct SSFXSampler -{ - int m_nsName; // Parameter name - uint32 m_nFlags; - short m_nArray; // Number of paramters - uint32 m_nsAnnotations; // Additional parameters (between <>) - uint32 m_nsSemantic; // Parameter app handling type (after ':') - uint32 m_nsValues; // Parameter values (after '=') - byte m_eType; // EParamType - - short m_nRegister[eHWSC_Num]; - - SSFXSampler() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nsName); - sAddData(dst, m_nFlags); - sAddData(dst, m_nArray); - sAddData(dst, m_nsAnnotations); - sAddData(dst, m_nsSemantic); - sAddData(dst, m_nsValues); - sAddData(dst, m_eType); - - for (int i = 0; i < eHWSC_Num; i++) - { - sAddData(dst, m_nRegister[i]); - } - - // Align for struct padding - sAlignData(dst, 8); - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nsName, eBigEndian); - SwapEndian(m_nFlags, eBigEndian); - SwapEndian(m_nArray, eBigEndian); - SwapEndian(m_nsAnnotations, eBigEndian); - SwapEndian(m_nsSemantic, eBigEndian); - SwapEndian(m_nsValues, eBigEndian); - SwapEndian(m_eType, eBigEndian); - - for (int i = 0; i < eHWSC_Num; i++) - { - SwapEndian(m_nRegister[i], eBigEndian); - } - } - } -}; -struct SSFXTexture -{ - int m_nsName; // Parameter name - int m_nsNameTexture; - uint32 m_nFlags; - short m_nArray; // Number of paramters - uint32 m_nsAnnotations; // Additional parameters (between <>) - uint32 m_nsSemantic; // Parameter app handling type (after ':') - uint32 m_nsValues; // Parameter values (after '=') - bool m_bSRGBLookup; - byte m_eType; // EParamType - - short m_nRegister[eHWSC_Num]; - - SSFXTexture() - { - memset(this, 0, sizeof(*this)); - } - - void Export(TArray& dst) - { - [[maybe_unused]] uint32 startOffset = dst.Num(); - - sAddData(dst, m_nsName); - sAddData(dst, m_nsNameTexture); - sAddData(dst, m_nFlags); - sAddData(dst, m_nArray); - sAddData(dst, m_nsAnnotations); - sAddData(dst, m_nsSemantic); - sAddData(dst, m_nsValues); - sAddData(dst, m_eType); - sAddData(dst, m_bSRGBLookup); - - for (int i = 0; i < eHWSC_Num; i++) - { - sAddData(dst, m_nRegister[i]); - } - - // Align for struct padding - sAlignData(dst, 8); - - AZ_Assert(dst.Num() - startOffset == sizeof(*this), "ShaderSerialize export size mismatch"); - } - - void Import(const byte* pData) - { - memcpy(this, pData, sizeof(*this)); - - if (CParserBin::m_bEndians) - { - SwapEndian(m_nsName, eBigEndian); - SwapEndian(m_nsNameTexture, eBigEndian); - SwapEndian(m_nFlags, eBigEndian); - SwapEndian(m_nArray, eBigEndian); - SwapEndian(m_nsAnnotations, eBigEndian); - SwapEndian(m_nsSemantic, eBigEndian); - SwapEndian(m_nsValues, eBigEndian); - SwapEndian(m_eType, eBigEndian); - SwapEndian(m_bSRGBLookup, eBigEndian); - - for (int i = 0; i < eHWSC_Num; i++) - { - SwapEndian(m_nRegister[i], eBigEndian); - } - } - } -}; - -struct SShaderSerializeContext -{ - SSShader SSR; - TArray Params; - TArray FXParams; - TArray FXSamplers; - TArray FXTextures; - TArray FXTexSamplers; - TArray FXTexRTs; - TArray Techniques; - TArray Passes; - TArray Strings; - TArray Data; - - std::map m_strTable; - - uint32 AddString(const char* pStr) - { - uint32 crc = CCrc32::Compute(pStr); - - std::map::iterator strIt = m_strTable.find(crc); - - if (strIt != m_strTable.end()) - { - uint32 offset = strIt->second; - - // Debug, check strings are correct -#if 0 - if (strcmp(&Strings[offset], pStr)) - { - CryLogAlways("Error: %s is not %s\n", pStr, &Strings[offset]); - } -#endif - - return offset; - } - - uint32 nChars = Strings.Num(); - m_strTable[crc] = nChars; - Strings.AddString(pStr); - return nChars; - } -}; - -class CShaderSerialize -{ - friend class CShaderMan; - friend class CShaderManBin; - -public: - enum ShaderImportResults - { - SHADER_IMPORT_SUCCESS, // Shader mask exists in the fxb lookup table - SHADER_IMPORT_MISSING_ENTRY, // We have a valid fxb lookup table, but the current permutation is missing - SHADER_IMPORT_FAILURE, // No fxb table exists for this entire shader - }; - - void ClearSResourceCache(); - -private: - bool _OpenSResource(float fVersion, SSShaderRes* pSR, CShader* pSH, int nCache, CResFile* pRF, bool bReadOnly); - bool OpenSResource(const char* szName, SSShaderRes* pSR, CShader* pSH, bool bDontUseUserFolder, bool bReadOnly); - bool CreateSResource(CShader* pSH, SSShaderRes* pSR, CCryNameTSCRC& SName, bool bDontUseUserFolder, bool bReadOnly); - SSShaderRes* InitSResource(CShader* pSH, bool bDontUseUserFolder, bool bReadOnly); - - // Simple query to see if the SResource exists in the hash table - bool DoesSResourceExist(CShader* pSH); - - // Helper function to abstract calling ExportHWShader per shader stage - void ExportHWShaderStage(SShaderSerializeContext& SC, CHWShader* shader, uint32& outShaderOffset); - - bool ExportHWShader(CHWShader* pShader, struct SShaderSerializeContext& SC); - - CHWShader* ImportHWShader(SShaderSerializeContext& SC, int nOffs, uint32 CRC32, CShader* pSH); - - bool ExportShader(CShader* pSH, CShaderManBin& binShaderMgr); - ShaderImportResults ImportShader(CShader* pSH, CShaderManBin& binShaderMgr); - bool CheckFXBExists(CShader* pSH); - - FXSShaderRes m_SShaderResources; - string m_customSerialisePath; -}; - -_inline const char* sString(int nOffs, TArray& Strings) -{ - return &Strings[nOffs]; -} - -#endif // SHADERS_SERIALIZING - -#endif - diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderStaticFlags.inl b/Code/CryEngine/RenderDll/Common/Shaders/ShaderStaticFlags.inl deleted file mode 100644 index 84c122fbba..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderStaticFlags.inl +++ /dev/null @@ -1,22 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -FX_STATIC_FLAG(GMEM_128BPP) -FX_STATIC_FLAG(GMEM_256BPP) -FX_STATIC_FLAG(GMEM_PLS) -FX_STATIC_FLAG(LLVM_DIRECTX_SHADER_COMPILER) -FX_STATIC_FLAG(FIXED_POINT) -FX_STATIC_FLAG(GMEM_RT_GREATER_FOUR) -FX_STATIC_FLAG(NO_DEPTH_CLIPPING) -FX_STATIC_FLAG(FEATURE_FETCH_DEPTHSTENCIL) -FX_STATIC_FLAG(GMEM_VELOCITY_BUFFER) -FX_STATIC_FLAG(GLES3_0) diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShaderTemplate.cpp b/Code/CryEngine/RenderDll/Common/Shaders/ShaderTemplate.cpp deleted file mode 100644 index 79a74c35a9..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShaderTemplate.cpp +++ /dev/null @@ -1,1239 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "I3DEngine.h" -#include "CryHeaders.h" -#include "StringUtils.h" // stristr() -#include "../Common/Textures/TextureHelpers.h" -#include "../Common/Textures/TextureManager.h" - -#if defined(WIN32) || defined(WIN64) -#include -#include -#elif defined(LINUX) - -#endif - -//=============================================================================== -#if !defined(_RELEASE) - // Texture names to be used for error / process loading indications - static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMe.tif"; -#else - // Some of the textures here will direct to the regular DefaultSolids_diff to prevent eye catching - // bug textures in release mode - static const char* szReplaceMe = "EngineAssets/TextureMsg/ReplaceMeRelease.tif"; -#endif - -//=============================================================================== -CShaderResources* CShaderMan::mfCreateShaderResources(const SInputShaderResources* Res, bool bShare) -{ - uint16 i, j; - SInputShaderResources localCopySR = *Res; // pay attention to this local copy - - // prepare local resources for cache-check, textures are looked up but not triggered for load - for ( auto& iter : localCopySR.m_TexturesResourcesMap ) - { - SEfResTexture* pTextureRes = &(iter.second); - - // Store off the previous texture's flags before we clean up the sampler slot - uint32 textureFlags = (pTextureRes->m_Sampler.m_pTex) ? pTextureRes->m_Sampler.m_pTex->GetFlags() : 0; - - pTextureRes->m_Sampler.Cleanup(); - if (!pTextureRes->m_Name.empty()) - { // If the texture that used to exist in this resource slot was created as an alpha texture - // e.g. - a gloss map stored in the alpha channel of a normal map (see CShaderMan::mfRefreshResources for some - // extra details on the texture slots that use the FT_ALPHA texture path), we need to pass the FT_ALPHA flag - // into mfFindResourceTexture so it can find the actual texture resource. - const uint32 alphaTextureFlags = textureFlags & FT_ALPHA; - - // Find the actual texture resource according to the given name - pTextureRes->m_Sampler.m_pTex = mfFindResourceTexture( - pTextureRes->m_Name.c_str(), localCopySR.m_TexturePath.c_str(), - pTextureRes->m_Sampler.GetTexFlags() | alphaTextureFlags, pTextureRes); - - if (pTextureRes->m_Sampler.m_pTex) - { // increase usage counter if texture was found - pTextureRes->m_Sampler.m_pTex->AddRef(); - } - } -/* [Shader System TO DO] - verify if possible to remove slot - else - { - AZ_Warning( "ShadersSystem", false, "CShaderMan::mfCreateShaderResources - texture name does not exist at slot %d - removing slot", iter->first); - pLocalCopySR.m_TexturesResourcesMap.erase(iter); - } -*/ - } - - // check local resources vs' global cache - int nFree = -1; - for (i = 1; i < CShader::s_ShaderResources_known.Num(); i++) // first entry is a null entry - { - // NOT thread safe can be modified from render thread in SRenderShaderResources dtor () - // (if flushing of unloaded textures (UnloadLevel) is not complete before pre-loading of new materials) - CShaderResources* pLoadedSRes = CShader::s_ShaderResources_known[i]; - if (!pLoadedSRes) - { - nFree = i; // find the first free slot in the bank - if (!bShare || Res->m_ShaderParams.size()) - { - break; - } - continue; - } - if (!bShare || Res->m_ShaderParams.size()) - { - continue; - } - - // [Shader System TO DO] - see if can be replaced with unified compare function - if (localCopySR.m_ResFlags == pLoadedSRes->GetResFlags() && - localCopySR.m_LMaterial.m_Opacity == pLoadedSRes->GetStrengthValue(EFTT_OPACITY) && - localCopySR.m_LMaterial.m_Emittance.a == pLoadedSRes->GetStrengthValue(EFTT_EMITTANCE) && - localCopySR.m_AlphaRef == pLoadedSRes->GetAlphaRef() && - localCopySR.m_TexturePath == pLoadedSRes->m_TexturePath) - { - // if there is not shader deformation or both deformations are identical - if ((!pLoadedSRes->m_pDeformInfo && !localCopySR.m_DeformInfo.m_eType) || (pLoadedSRes->m_pDeformInfo && *pLoadedSRes->m_pDeformInfo == localCopySR.m_DeformInfo)) - { - // [Shader System TO DO] - optimize - // The following code runs over all slots and verify a match between current shader and - // loaded shaders If no match - break and add to the loaded. - for (j = 0; j < EFTT_MAX; j++) - { - SEfResTexture* pLoadedTexRes = pLoadedSRes->GetTextureResource(j); - SEfResTexture* pShaderTexRes = localCopySR.GetTextureResource(j); - - // No loaded (cached) texture slot or no texture name for this slot - if (!pLoadedTexRes || pLoadedTexRes->m_Name.empty()) - { - if (!pShaderTexRes || pShaderTexRes->m_Name.empty()) - { // match - no texture slot or texture name - move to the next slot - continue; - } - - // slot exists but cannot be found in the resource - no shaders match - try the next cached shader - break; - } - // Cached slot entry with texture name exists - test to see if exists for the current shader - else if (!pShaderTexRes || pShaderTexRes->m_Name.empty()) - { - break; // texture slot doesn't exist / no texture name for current shader - no match - move to next cached shader - } - - // both slots exist - run a full comparison between the two shaders (current and cached) - if (*pLoadedTexRes != *pShaderTexRes) - { - break; // no match - move to the next cached shader - } - } - - // The two shader resources fully match - return the cached shader resource (no need to load) - if (j == EFTT_MAX) - { - pLoadedSRes->AddRef(); // add usage count to this loaded shader resource - return pLoadedSRes; - } - } - } - } - - // The current shader resource does not exist - create a dynamic copy to be loaded and - // insert to the cached resources bank. - CShaderResources* pSR = new CShaderResources(&localCopySR); - pSR->m_nRefCounter = 1; - if (!CShader::s_ShaderResources_known.Num()) - { - CShader::s_ShaderResources_known.AddIndex(1); - CShaderResources* pSRNULL = new CShaderResources; - pSRNULL->m_nRefCounter = 1; - CShader::s_ShaderResources_known[0] = pSRNULL; - } - else if (nFree < 0 && CShader::s_ShaderResources_known.Num() >= MAX_REND_SHADER_RES) - { - Warning("ERROR: CShaderMan::mfCreateShaderResources: MAX_REND_SHADER_RESOURCES hit"); - pSR->Release(); - return CShader::s_ShaderResources_known[1]; - } - if (nFree > 0) - { - pSR->m_Id = nFree; - pSR->m_IdGroup = pSR->m_Id; - CShader::s_ShaderResources_known[nFree] = pSR; - } - else - { - pSR->m_Id = CShader::s_ShaderResources_known.Num(); - pSR->m_IdGroup = pSR->m_Id; - CShader::s_ShaderResources_known.AddElem(pSR); - } - - return pSR; -} - -void CShaderResources::SetShaderParams(SInputShaderResources* pDst, IShader* pSH) -{ - ReleaseParams(); - m_ShaderParams = pDst->m_ShaderParams; - - UpdateConstants(pSH); -} - - -uint32 SShaderItem::PostLoad() -{ - uint32 nPreprocessFlags = 0; - CShader* pSH = (CShader*)m_pShader; - CShaderResources* pR = (CShaderResources*)m_pShaderResources; - - if (pSH->m_Flags2 & EF2_PREPR_GENCLOUDS) - { - nPreprocessFlags |= FSPR_GENCLOUDS; - } - if (pSH->m_Flags2 & EF2_PREPR_SCANWATER) - { - nPreprocessFlags |= FSPR_SCANTEXWATER | FB_PREPROCESS; - } - - nPreprocessFlags |= FB_GENERAL; - const SShaderTechnique* pTech = GetTechnique(); - if (pR) - { - pR->PostLoad(pSH); - - for (auto& iter : pR->m_TexturesResourcesMap ) - { - SEfResTexture* pTexture = &(iter.second); - bool is2DTexture = (pTexture->m_Sampler.m_eTexType == eTT_Auto2D || pTexture->m_Sampler.m_eTexType == eTT_Dyn2D); - - if (!pTexture->m_Sampler.m_pTarget) - { - continue; - } - - if (is2DTexture) - { - if (gRenDev->m_RP.m_eQuality == eRQ_Low) - { - pTexture->m_Sampler.m_eTexType = eTT_2D; - } - pR->m_ResFlags |= MTL_FLAG_NOTINSTANCED; - nPreprocessFlags |= FSPR_SCANTEX; - } - pR->m_RTargets.AddElem(pTexture->m_Sampler.m_pTarget); - } - } - - if (pTech && pTech->m_Passes.Num() && (pTech->m_Passes[0].m_RenderState & GS_ALPHATEST_MASK)) - { - if (pR && !pR->m_AlphaRef) - { - pR->m_AlphaRef = 0.5f; - } - } - - // Update persistent batch flags - if (pTech) - { - if (pTech->m_nTechnique[TTYPE_Z] > 0) - { - nPreprocessFlags |= FB_Z; - - // ZPrepass only for non-alpha tested/blended geometry (decals, terrain). - // We assume vegetation is special case due to potential massive overdraw - if (pTech->m_nTechnique[TTYPE_ZPREPASS] > 0) - { - const bool bAlphaTested = (pR && pR->IsAlphaTested()); - if (!bAlphaTested) - { - nPreprocessFlags |= FB_ZPREPASS; - } - } - } - - if (!(pTech->m_Flags & FHF_POSITION_INVARIANT) && ((pTech->m_Flags & FHF_TRANSPARENT) || (pR && pR->IsTransparent()))) - { - nPreprocessFlags |= FB_TRANSPARENT; - } - - if (pTech->m_nTechnique[TTYPE_WATERREFLPASS] > 0) - { - nPreprocessFlags |= FB_WATER_REFL; - } - - if (pTech->m_nTechnique[TTYPE_WATERCAUSTICPASS] > 0) - { - nPreprocessFlags |= FB_WATER_CAUSTIC; - } - - if ((pSH->m_Flags2 & EF2_SKINPASS)) - { - nPreprocessFlags |= FB_SKIN; - } - - if (CRenderer::CV_r_SoftAlphaTest && pTech->m_nTechnique[TTYPE_SOFTALPHATESTPASS] > 0) - { - nPreprocessFlags |= FB_SOFTALPHATEST; - } - - if (pSH->m_Flags2 & EF2_EYE_OVERLAY) - { - nPreprocessFlags |= FB_EYE_OVERLAY; - } - - if (pSH->m_Flags & EF_REFRACTIVE) - { - if (CRenderer::CV_r_Refraction) - { - nPreprocessFlags |= FB_TRANSPARENT; - } - else - { - AZ_Warning("ShadersSystem", false, - "Shader %s use refraction but it's not enabled for this configuration. Check the value of the CVAR r_Refraction.", - pSH->m_NameShader.c_str()); - } - } - } - - if (pTech) - { - nPreprocessFlags |= pTech->m_nPreprocessFlags; - } - - if (nPreprocessFlags & FSPR_MASK) - { - nPreprocessFlags |= FB_PREPROCESS; - } - - return nPreprocessFlags; -} - -//------------------------------------------------------------------------------ -// [Shader System TO DO] - remove and replace with data driven from the shader files -// This method should be per shader type and not generic to the entire engine. - -// This method associates fixed slots with known contextual material textures -// The engine slots are left unhandled and will be assigned through the -// shader and engine side - explore how! -//------------------------------------------------------------------------------ -EEfResTextures CShaderMan::mfCheckTextureSlotName(const char* mapname) -{ - EEfResTextures slot = EFTT_UNKNOWN; - - if (!azstricmp(mapname, "$Diffuse")) - { - slot = EFTT_DIFFUSE; - } - else if (!azstricmp(mapname, "$Normal")) - { - slot = EFTT_NORMALS; - } - else if (!azstricmp(mapname, "$Specular")) - { - slot = EFTT_SPECULAR; - } - else if (!azstricmp(mapname, "$Env")) - { - slot = EFTT_ENV; - } - else if (!azstricmp(mapname, "$Detail")) - { - slot = EFTT_DETAIL_OVERLAY; - } - else if (!azstricmp(mapname, "$SecondSmoothness")) - { - slot = EFTT_SECOND_SMOOTHNESS; - } - else if (!azstricmp(mapname, "$Height")) - { - slot = EFTT_HEIGHT; - } - else if (!azstricmp(mapname, "$DecalOverlay")) - { - slot = EFTT_DECAL_OVERLAY; - } - else if (!azstricmp(mapname, "$Subsurface")) - { - slot = EFTT_SUBSURFACE; - } - else if (!azstricmp(mapname, "$CustomMap")) - { // Used as Diffuse 2 when BlendLayer is enabled - slot = EFTT_CUSTOM; - } - else if (!azstricmp(mapname, "$Specular2")) - { // Used as Specular 2 when BlendLayer is enabled - slot = EFTT_SPECULAR_2; - } - else if (!azstricmp(mapname, "$CustomSecondaryMap")) - { // Used as Normal 2 when BlendLayer is enabled - slot = EFTT_CUSTOM_SECONDARY; - } - else if (!azstricmp(mapname, "$Opacity")) - { // Used as Blend Map for BlendLayer is enabled - slot = EFTT_OPACITY; - } - else if (!azstricmp(mapname, "$Smoothness")) - { - slot = EFTT_SMOOTHNESS; - } - else if (!azstricmp(mapname, "$Emittance")) - { - slot = EFTT_EMITTANCE; - } - else if (!azstricmp(mapname, "$Occlusion")) - { - slot = EFTT_OCCLUSION; - } - // backwards compatible names - else if (!azstricmp(mapname, "$Cubemap")) - { - slot = EFTT_ENV; - } - else if (!azstricmp(mapname, "$Translucency")) - { - slot = EFTT_SECOND_SMOOTHNESS; - } - else if (!azstricmp(mapname, "$BumpDiffuse")) - { - slot = EFTT_SECOND_SMOOTHNESS; //EFTT_BUMP_DIFFUSE; - } - else if (!azstricmp(mapname, "$BumpHeight")) - { - slot = EFTT_HEIGHT; //EFTT_BUMP_HEIGHT; - } - else if (!azstricmp(mapname, "$Bump")) - { - slot = EFTT_NORMALS; //EFTT_BUMP; - } - else if (!azstricmp(mapname, "$Gloss")) - { - slot = EFTT_SPECULAR; //EFTT_GLOSS; - } - else if (!azstricmp(mapname, "$GlossNormalA")) - { - slot = EFTT_SMOOTHNESS; //EFTT_GLOSS_NORMAL_A; - } - - return slot; -} - -//------------------------------------------------------------------------------ -// [Shader System TO DO] - data driven per update frequencies and the slots map -//------------------------------------------------------------------------------ -CTexture* CShaderMan::mfCheckTemplateTexName(const char* mapname, [[maybe_unused]] ETEX_Type eTT) -{ - CTexture* TexPic = NULL; - if (mapname[0] != '$') - { - return NULL; - } - - { - EEfResTextures slot = mfCheckTextureSlotName(mapname); - - if (slot != EFTT_MAX) - { - return &(*CTexture::s_ShaderTemplates)[slot]; - } - } - - if (!azstricmp(mapname, "$ShadowPoolAtlas")) - { - TexPic = CTexture::s_ptexRT_ShadowPool; - } - else - if (!azstrnicmp(mapname, "$ShadowID", 9)) - { - int n = atoi(&mapname[9]); - TexPic = CTexture::s_ptexShadowID[n]; - } - else - if (!azstricmp(mapname, "$FromRE") || !azstricmp(mapname, "$FromRE0")) - { - TexPic = CTexture::s_ptexFromRE[0]; - } - else - if (!azstricmp(mapname, "$FromRE1")) - { - TexPic = CTexture::s_ptexFromRE[1]; - } - else - if (!azstricmp(mapname, "$FromRE2")) - { - TexPic = CTexture::s_ptexFromRE[2]; - } - else - if (!azstricmp(mapname, "$FromRE3")) - { - TexPic = CTexture::s_ptexFromRE[3]; - } - else - if (!azstricmp(mapname, "$FromRE4")) - { - TexPic = CTexture::s_ptexFromRE[4]; - } - else - if (!azstricmp(mapname, "$FromRE5")) - { - TexPic = CTexture::s_ptexFromRE[5]; - } - else - if (!azstricmp(mapname, "$FromRE6")) - { - TexPic = CTexture::s_ptexFromRE[6]; - } - else - if (!azstricmp(mapname, "$FromRE7")) - { - TexPic = CTexture::s_ptexFromRE[7]; - } - else - if (!azstricmp(mapname, "$VolObj_Density")) - { - TexPic = CTexture::s_ptexVolObj_Density; - } - else - if (!azstricmp(mapname, "$VolObj_Shadow")) - { - TexPic = CTexture::s_ptexVolObj_Shadow; - } - else - if (!azstricmp(mapname, "$ColorChart")) - { - TexPic = CTexture::s_ptexColorChart; - } - else - if (!azstricmp(mapname, "$FromObj")) - { - TexPic = CTexture::s_ptexFromObj; - } - else - if (!azstricmp(mapname, "$SvoTree")) - { - TexPic = CTexture::s_ptexSvoTree; - } - else - if (!azstricmp(mapname, "$SvoTris")) - { - TexPic = CTexture::s_ptexSvoTris; - } - else - if (!azstricmp(mapname, "$SvoGlobalCM")) - { - TexPic = CTexture::s_ptexSvoGlobalCM; - } - else - if (!azstricmp(mapname, "$SvoRgbs")) - { - TexPic = CTexture::s_ptexSvoRgbs; - } - else - if (!azstricmp(mapname, "$SvoNorm")) - { - TexPic = CTexture::s_ptexSvoNorm; - } - else - if (!azstricmp(mapname, "$SvoOpac")) - { - TexPic = CTexture::s_ptexSvoOpac; - } - else - if (!azstricmp(mapname, "$FromObjCM")) - { - TexPic = CTexture::s_ptexFromObjCM; - } - else - if (!azstrnicmp(mapname, "$White", 6)) - { - TexPic = CTextureManager::Instance()->GetWhiteTexture(); - } - else - if (!azstrnicmp(mapname, "$RT_2D", 6)) - { - TexPic = CTexture::s_ptexRT_2D; - } - else - if (!azstricmp(mapname, "$PrevFrameScaled")) - { - TexPic = CTexture::s_ptexPrevFrameScaled; - } - else - if (!azstricmp(mapname, "$BackBuffer")) - { - TexPic = CTexture::s_ptexBackBuffer; - } - else - if (!azstricmp(mapname, "$ModelHUD")) - { - TexPic = CTexture::s_ptexModelHudBuffer; - } - else - if (!azstricmp(mapname, "$BackBufferScaled_d2")) - { - TexPic = CTexture::s_ptexBackBufferScaled[0]; - } - else - if (!azstricmp(mapname, "$BackBufferScaled_d4")) - { - TexPic = CTexture::s_ptexBackBufferScaled[1]; - } - else - if (!azstricmp(mapname, "$BackBufferScaled_d8")) - { - TexPic = CTexture::s_ptexBackBufferScaled[2]; - } - else - if (!azstricmp(mapname, "$HDR_BackBuffer")) - { - TexPic = CTexture::s_ptexSceneTarget; - } - else - if (!azstricmp(mapname, "$HDR_BackBufferScaled_d2")) - { - TexPic = CTexture::s_ptexHDRTargetScaled[0]; - } - else - if (!azstricmp(mapname, "$HDR_BackBufferScaled_d4")) - { - TexPic = CTexture::s_ptexHDRTargetScaled[1]; - } - else - if (!azstricmp(mapname, "$HDR_BackBufferScaled_d8")) - { - TexPic = CTexture::s_ptexHDRTargetScaled[2]; - } - else - if (!azstricmp(mapname, "$HDR_FinalBloom")) - { - TexPic = CTexture::s_ptexHDRFinalBloom; - } - else - if (!azstricmp(mapname, "$HDR_TargetPrev")) - { - TexPic = CTexture::s_ptexHDRTargetPrev; - } - else - if (!azstricmp(mapname, "$HDR_AverageLuminance")) - { - TexPic = CTexture::s_ptexHDRMeasuredLuminanceDummy; - } - else - if (!azstricmp(mapname, "$ZTarget")) - { - TexPic = CTexture::s_ptexZTarget; - } - else - if (!azstricmp(mapname, "$ZTargetScaled")) - { - TexPic = CTexture::s_ptexZTargetScaled; - } - else - if (!azstricmp(mapname, "$ZTargetScaled2")) - { - TexPic = CTexture::s_ptexZTargetScaled2; - } - else - if (!azstricmp(mapname, "$SceneTarget")) - { - TexPic = CTexture::s_ptexSceneTarget; - } - else - if (!azstricmp(mapname, "$CloudsLM")) - { - TexPic = CTexture::s_ptexCloudsLM; - } - else - if (!azstricmp(mapname, "$WaterVolumeDDN")) - { - TexPic = CTexture::s_ptexWaterVolumeDDN; - } - else - if (!azstricmp(mapname, "$WaterVolumeReflPrev")) - { - TexPic = CTexture::s_ptexWaterVolumeRefl[1]; - } - else - if (!azstricmp(mapname, "$WaterVolumeRefl")) - { - TexPic = CTexture::s_ptexWaterVolumeRefl[0]; - } - else - if (!azstricmp(mapname, "$WaterVolumeCaustics")) - { - TexPic = CTexture::s_ptexWaterCaustics[0]; - } - else - if (!azstricmp(mapname, "$WaterVolumeCausticsTemp")) - { - TexPic = CTexture::s_ptexWaterCaustics[1]; - } - else - if (!azstricmp(mapname, "$SceneNormalsMap")) - { - TexPic = CTexture::s_ptexSceneNormalsMap; - } - else - if (!azstricmp(mapname, "$SceneNormalsMapMS")) - { - TexPic = CTexture::s_ptexSceneNormalsMapMS; - } - else - if (!azstricmp(mapname, "$SceneDiffuse")) - { - TexPic = CTexture::s_ptexSceneDiffuse; - } - else - if (!azstricmp(mapname, "$SceneSpecular")) - { - TexPic = CTexture::s_ptexSceneSpecular; - } - else - if (!azstricmp(mapname, "$SceneNormalsBent")) - { - TexPic = CTexture::s_ptexSceneNormalsBent; - } - else - if (!azstricmp(mapname, "$SceneDiffuseAcc")) - { - TexPic = CTexture::s_ptexCurrentSceneDiffuseAccMap; - } - else - if (!azstricmp(mapname, "$SceneSpecularAcc")) - { - TexPic = CTexture::s_ptexSceneSpecularAccMap; - } - else - if (!azstricmp(mapname, "$SceneDiffuseAccMS")) - { - TexPic = CTexture::s_ptexSceneDiffuseAccMapMS; - } - else - if (!azstricmp(mapname, "$SceneSpecularAccMS")) - { - TexPic = CTexture::s_ptexSceneSpecularAccMapMS; - } - else - if (!azstricmp(mapname, "$DefaultEnvironmentProbe")) - { - TexPic = CTexture::s_defaultEnvironmentProbeDummy; - } - - return TexPic; -} - -//------------------------------------------------------------------------------ -// [Shader System TO DO] - remove and replace with data driven from the shader files -//------------------------------------------------------------------------------ -const char* CShaderMan::mfTemplateTexIdToName(int Id) -{ - switch (Id) - { - case EFTT_DIFFUSE: - return "Diffuse"; - case EFTT_SPECULAR: - return "Gloss"; - case EFTT_NORMALS: - return "Bump"; - case EFTT_ENV: - return "Environment"; - case EFTT_SUBSURFACE: - return "SubSurface"; - case EFTT_CUSTOM: - return "CustomMap"; - case EFTT_CUSTOM_SECONDARY: - return "CustomSecondaryMap"; - case EFTT_DETAIL_OVERLAY: - return "Detail"; - case EFTT_OPACITY: - return "Opacity"; - case EFTT_DECAL_OVERLAY: - return "Decal"; - case EFTT_OCCLUSION: - return "Occlusion"; - case EFTT_SPECULAR_2: - return "Specular2"; - case EFTT_SMOOTHNESS: - return "GlossNormalA"; - case EFTT_EMITTANCE: - return "Emittance"; - default: - return "Unknown"; - } -} - -CTexAnim* CShaderMan::mfReadTexSequence(const char* na, int Flags, [[maybe_unused]] bool bFindOnly) -{ - char prefix[_MAX_PATH]; - char postfix[_MAX_PATH]; - char* nm; - int i, j, l, m; - char nam[_MAX_PATH]; - int n; - CTexture* tx, * tp; - int startn, endn, nums; - char name[_MAX_PATH]; - - tx = NULL; - - cry_strcpy(name, na); - const char* ext = fpGetExtension (na); - fpStripExtension(name, name); - - char chSep = '#'; - nm = strchr(name, chSep); - if (!nm) - { - nm = strchr(name, '$'); - if (!nm) - { - return 0; - } - chSep = '$'; - } - - float fSpeed = 0.05f; - { - char nName[_MAX_PATH]; - azstrcpy(nName, _MAX_PATH, name); - nm = strchr(nName, '('); - if (nm) - { - name[nm - nName] = 0; - char* speed = &nName[nm - nName + 1]; - nm = strchr(speed, ')'); - if (nm) - { - speed[nm - speed] = 0; - } - fSpeed = (float)atof(speed); - } - } - - j = 0; - n = 0; - l = -1; - m = -1; - while (name[n]) - { - if (name[n] == chSep) - { - j++; - if (l == -1) - { - l = n; - } - } - else - if (l >= 0 && m < 0) - { - m = n; - } - n++; - } - if (!j) - { - return 0; - } - - cry_strcpy(prefix, name, l); - - char dig[_MAX_PATH]; - l = 0; - if (m < 0) - { - startn = 0; - endn = 999; - postfix[0] = 0; - } - else - { - while (isdigit((unsigned char)name[m])) - { - dig[l++] = name[m]; - m++; - } - dig[l] = 0; - startn = strtol(dig, NULL, 10); - m++; - - l = 0; - while (isdigit((unsigned char)name[m])) - { - dig[l++] = name[m]; - m++; - } - dig[l] = 0; - endn = strtol(dig, NULL, 10); - - azstrcpy(postfix, AZ_ARRAY_SIZE(postfix), &name[m]); - } - - nums = endn - startn + 1; - - n = 0; - char frm[256]; - char frd[4]; - - frd[0] = j + '0'; - frd[1] = 0; - - cry_strcpy(frm, "%s%."); - cry_strcat(frm, frd); - cry_strcat(frm, "d%s%s"); - CTexAnim* ta = NULL; - for (i = 0; i < nums; i++) - { - sprintf_s(nam, frm, prefix, startn + i, postfix, ext); - tp = (CTexture*)gRenDev->EF_LoadTexture(nam, Flags); - if (!tp || !tp->IsLoaded()) - { - if (tp) - { - tp->Release(); - } - break; - } - if (!ta) - { - ta = new CTexAnim; - ta->m_bLoop = true; - ta->m_Time = fSpeed; - } - - ta->m_TexPics.AddElem(tp); - n++; - } - - if (ta) - { - ta->m_NumAnimTexs = ta->m_TexPics.Num(); - } - - return ta; -} - -int CShaderMan::mfReadTexSequence(STexSamplerRT *smp, const char *na, int Flags, bool bFindOnly) -{ - if (smp->m_pAnimInfo) - { - assert(0); - return 0; - } - - CTexAnim* ta = mfReadTexSequence(na, Flags, bFindOnly); - if (ta) - { - smp->m_pAnimInfo = ta; - SAFE_RELEASE(smp->m_pTex); - return ta->m_NumAnimTexs; - } - - return 0; -} - -void CShaderMan::mfSetResourceTexState(SEfResTexture* Tex) -{ - if (Tex) - { - STexState ST; - ST.SetFilterMode(Tex->m_Filter); - ST.SetClampMode(Tex->m_bUTile ? TADDR_WRAP : TADDR_CLAMP, Tex->m_bVTile ? TADDR_WRAP : TADDR_CLAMP, Tex->m_bUTile ? TADDR_WRAP : TADDR_CLAMP); - Tex->m_Sampler.m_nTexState = CTexture::GetTexState(ST); - } -} - -CTexture* CShaderMan::mfTryToLoadTexture(const char* nameTex, STexSamplerRT* smp, int Flags, bool bFindOnly) -{ - CTexture* tx = NULL; - if (nameTex && strchr(nameTex, '#')) // test for " #" to skip max material names - { - int n = mfReadTexSequence(smp, nameTex, Flags, bFindOnly); - //If we were able to read the texture animation, those textures will all be loaded and set into smp->m_pAnimInfo->m_TexPics by mfReadTexSequence. - //Other code is dependent on some texture being returned here though, so Just return the first one in the animation. - if (n > 0 && smp->m_pAnimInfo && !smp->m_pAnimInfo->m_TexPics.empty()) - { - smp->m_pAnimInfo->m_TexPics[0]->AddRef(); - return smp->m_pAnimInfo->m_TexPics[0]; - } - } - if (!tx) - { - if (bFindOnly) - { - tx = (CTexture*)gRenDev->EF_GetTextureByName(nameTex, Flags); - } - else - { - tx = (CTexture*)gRenDev->EF_LoadTexture(nameTex, Flags); - } - } - - return tx; -} - -CTexture* CShaderMan::mfFindResourceTexture(const char* nameTex, [[maybe_unused]] const char* path, int Flags, SEfResTexture* Tex) -{ - mfSetResourceTexState(Tex); - - return mfTryToLoadTexture(nameTex, Tex ? &Tex->m_Sampler : NULL, Flags, true); -} - -CTexture* CShaderMan::mfLoadResourceTexture(const char* nameTex, [[maybe_unused]] const char* path, int Flags, SEfResTexture* Tex) -{ - mfSetResourceTexState(Tex); - - return mfTryToLoadTexture(nameTex, Tex ? &Tex->m_Sampler : NULL, Flags, false); -} - - -bool CShaderMan::mfLoadResourceTexture(ResourceSlotIndex Id, SInputShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail) -{ - SEfResTexture* pTextureRes = RS.GetTextureResource(Id); - - if (!pTextureRes || pTextureRes->m_Name.empty()) - return false; - - // Texture slot and texture name exist - STexSamplerRT& texSampler(pTextureRes->m_Sampler); - - // No texture or texture not loaded - try to load it - if (!texSampler.m_pTex || !texSampler.m_pTex->IsTextureLoaded()) - { - texSampler.m_pTex = mfLoadResourceTexture( pTextureRes->m_Name.c_str(), RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes); - } - - bool bTextureLoadSuccess = texSampler.m_pTex->IsTextureLoaded(); - // Texture was not successfully loaded but is marked for placeholder loading on fail - if (!bTextureLoadSuccess && bReplaceMeOnFail) - { - texSampler.m_pTex = mfLoadResourceTexture( szReplaceMe, RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes); - } - return bTextureLoadSuccess; -} - -bool CShaderMan::mfLoadResourceTexture(ResourceSlotIndex Id, CShaderResources& RS, uint32 CustomFlags, bool bReplaceMeOnFail) -{ - SEfResTexture* pTextureRes = RS.GetTextureResource(Id); - - // Texture slot does not exist - if (!pTextureRes) - return false; - - STexSamplerRT& texSampler(pTextureRes->m_Sampler); - bool bTextureLoaded = texSampler.m_pTex && texSampler.m_pTex->IsTextureLoaded(); - - if (!pTextureRes->m_Name.empty()) - { // texture can be retrieved - if (!bTextureLoaded || (CustomFlags & FT_ALPHA)) - { - SAFE_RELEASE(texSampler.m_pTex); - texSampler.m_pTex = mfLoadResourceTexture(pTextureRes->m_Name.c_str(), RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes); - } - - if (!bTextureLoaded && texSampler.m_pTex->IsTextureMissing()) - { - TextureWarning(pTextureRes->m_Name.c_str(), "Texture file is missing: '%s%s' in material \'%s\'", RS.m_TexturePath.c_str(), pTextureRes->m_Name.c_str(), RS.m_szMaterialName); - } - - bTextureLoaded = texSampler.m_pTex->IsTextureLoaded(); - if (!bTextureLoaded && bReplaceMeOnFail) - { - texSampler.m_pTex = mfLoadResourceTexture("EngineAssets/TextureMsg/ReplaceMe.tif", RS.m_TexturePath.c_str(), texSampler.GetTexFlags() | CustomFlags, pTextureRes); - } - } - - return bTextureLoaded; -} - -//------------------------------------------------------------------------------ -// Notice - the function will actively add the marked slot if it does not exist. -//------------------------------------------------------------------------------ -void CShaderMan::mfLoadDefaultTexture(ResourceSlotIndex Id, CShaderResources& RS, EEfResTextures Def) -{ - RS.m_TexturesResourcesMap[Id].m_Sampler.m_pTex = TextureHelpers::LookupTexDefault(Def); -} - -//------------------------------------------------------------------------------ -// Mark refresh required if any texture slot contains a texture -bool CShaderMan::mfRefreshResourceConstants(CShaderResources* Res) -{ - if (!Res) - return false; - - for (auto iter = Res->m_TexturesResourcesMap.begin(); iter != Res->m_TexturesResourcesMap.end(); ++iter) - { - SEfResTexture* pTexture = &iter->second; - if (pTexture->m_Sampler.m_pTex) - { // marked changed if the sampler contains pointer to a texture - return true; - } - } - return false; -} - -//------------------------------------------------------------------------------ -// [Shader System] - TO DO : be very careful when optimizing this as it can lead -// to loss / uncorrelated of texture slots. -//------------------------------------------------------------------------------ -void CShaderMan::mfRefreshResources(CShaderResources* Res) -{ - if (Res) - { - for (int i = 0; i < EFTT_MAX; i++) - { - int Flags = 0; - if (i == EFTT_NORMALS) - { - if ((!Res->TextureSlotExists(i) || Res->m_TexturesResourcesMap[i].m_Name.empty())) - { - continue; - } - - Flags |= FT_TEX_NORMAL_MAP; - if (!Res->TextureSlotExists(i)) // add a slot - { - Res->m_TexturesResourcesMap[i].Cleanup(); - } - - if (!mfLoadResourceTexture((EEfResTextures)i, *Res, Flags)) - { - mfLoadDefaultTexture((EEfResTextures)i, *Res, (EEfResTextures)i); - } - - // Support for gloss in regular normal map - CTexture* pTexN = (Res->TextureSlotExists(i) ? Res->m_TexturesResourcesMap[i].m_Sampler.m_pTex : NULL); - if (pTexN && (pTexN->GetFlags() & FT_HAS_ATTACHED_ALPHA)) - { - Res->m_TexturesResourcesMap[EFTT_SMOOTHNESS].m_Name = pTexN->GetSourceName(); - if (!mfLoadResourceTexture(EFTT_SMOOTHNESS, *Res, Flags | FT_ALPHA)) - { - mfLoadDefaultTexture(EFTT_SMOOTHNESS, *Res, (EEfResTextures)i); - } - } - - continue; - } - else - if (i == EFTT_HEIGHT) - { - if (!Res->TextureSlotExists(EFTT_NORMALS) || !Res->m_TexturesResourcesMap[EFTT_NORMALS].m_Sampler.m_pTex) - { - continue; - } - if (!Res->TextureSlotExists(i)) - { - continue; //Res->AddTextureMap(i); - } - mfLoadResourceTexture((EEfResTextures)i, *Res, Flags); - } - else - if (i == EFTT_CUSTOM_SECONDARY) - { - if ((!Res->TextureSlotExists(i) || Res->m_TexturesResourcesMap[i].m_Name.empty())) - { - continue; - } - - if (!Res->TextureSlotExists(i)) - { // adds the slot - Res->m_TexturesResourcesMap[i].Cleanup(); - } - - if (!mfLoadResourceTexture((EEfResTextures)i, *Res, Flags)) - { - mfLoadDefaultTexture((EEfResTextures)i, *Res, (EEfResTextures)i); - } - - // Support for gloss in blend layer normal map - CTexture* pTexN = (Res->TextureSlotExists(i) ? Res->m_TexturesResourcesMap[i].m_Sampler.m_pTex : NULL); - if (pTexN && (pTexN->GetFlags() & FT_HAS_ATTACHED_ALPHA)) - { - Res->m_TexturesResourcesMap[EFTT_SECOND_SMOOTHNESS].m_Name = pTexN->GetSourceName(); - if (!mfLoadResourceTexture(EFTT_SECOND_SMOOTHNESS, *Res, Flags | FT_ALPHA)) - { - mfLoadDefaultTexture(EFTT_SECOND_SMOOTHNESS, *Res, EFTT_SMOOTHNESS); - } - } - - continue; - } - - SEfResTexture* Tex = Res->GetTextureResource(i); - if (!Tex) - { - continue; - } - - // TODO: fix this bug at the root, a texture is allocated even though "nearest_cubemap"-named textures should be NULL - if (Tex->m_Sampler.m_eTexType == eTT_NearestCube) - { - SAFE_RELEASE(Tex->m_Sampler.m_pTex); - Tex->m_Sampler.m_pTex = CTexture::s_ptexFromObjCM; - } - - if (!Tex->m_Sampler.m_pTex) - { - if (Tex->m_Sampler.m_eTexType == eTT_NearestCube) - { - Tex->m_Sampler.m_pTex = CTexture::s_ptexFromObjCM; - } - else - if (Tex->m_Sampler.m_eTexType == eTT_Dyn2D) - { - // This block was for loading Flash files - } - else - if (Tex->m_Sampler.m_eTexType == eTT_Auto2D) - { - if (i == EFTT_ENV) - { - mfSetResourceTexState(Tex); - - SAFE_RELEASE(Tex->m_Sampler.m_pTarget); - Tex->m_Sampler.m_pTarget = new SHRenderTarget; - - Tex->m_Sampler.m_pTex = CTexture::s_ptexRT_2D; - Tex->m_Sampler.m_pTarget->m_pTarget[0] = CTexture::s_ptexRT_2D; - - Tex->m_Sampler.m_pTarget->m_bTempDepth = true; - Tex->m_Sampler.m_pTarget->m_eOrder = eRO_PreProcess; - Tex->m_Sampler.m_pTarget->m_eTF = eTF_R8G8B8A8; - Tex->m_Sampler.m_pTarget->m_nIDInPool = -1; - Tex->m_Sampler.m_pTarget->m_nFlags |= FRT_RENDTYPE_RECURSIVECURSCENE | FRT_CAMERA_CURRENT; - Tex->m_Sampler.m_pTarget->m_nFlags |= FRT_CLEAR_DEPTH | FRT_CLEAR_STENCIL | FRT_CLEAR_COLOR; - } - } - else - if (Tex->m_Sampler.m_eTexType == eTT_User) - { - Tex->m_Sampler.m_pTex = NULL; - } - else - { - mfLoadResourceTexture((EEfResTextures)i, *Res, Flags); - } - } - - // assign streaming priority based on the importance (sampler slot) - if (Tex && Tex->m_Sampler.m_pITex && Tex->m_Sampler.m_pITex->IsTextureLoaded() && Tex->m_Sampler.m_pITex->IsStreamedVirtual()) - { - CTexture* tp = (CTexture*)Tex->m_Sampler.m_pITex; - tp->SetStreamingPriority(EFTT_MAX - i); - } - } - } - - mfRefreshResourceConstants(Res); -} diff --git a/Code/CryEngine/RenderDll/Common/Shaders/ShadersResourcesGroups/PerFrame.h b/Code/CryEngine/RenderDll/Common/Shaders/ShadersResourcesGroups/PerFrame.h deleted file mode 100644 index 209b2021a2..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shaders/ShadersResourcesGroups/PerFrame.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _PER_FRAME_RESOURCE_GROUP_ -#define _PER_FRAME_RESOURCE_GROUP_ - -struct PerFrameParameters -{ - int m_FrameID; - - Vec3 m_WaterLevel; - Vec4 m_HDRParams; - - float m_SunSpecularMultiplier; - float m_MidDayIndicator; // during day [0..1] where noon is 1.0 and going towards 0 at night - - Vec3 m_DecalZFightingRemedy; - - Vec3 m_CloudShadingColorSun; - Vec3 m_CloudShadingColorSky; - Vec4 m_CloudShadowParams; - Vec4 m_CloudShadowAnimParams; - - Vec4 m_CausticsParams; - Vec3 m_CausticsSunDirection; - - Vec4 m_VolumetricFogParams; - Vec4 m_VolumetricFogRampParams; - Vec4 m_VolumetricFogColorGradientBase; - Vec4 m_VolumetricFogColorGradientDelta; - Vec4 m_VolumetricFogColorGradientParams; - Vec4 m_VolumetricFogColorGradientRadial; - Vec4 m_VolumetricFogSamplingParams; - Vec4 m_VolumetricFogDistributionParams; - Vec4 m_VolumetricFogScatteringParams; - Vec4 m_VolumetricFogScatteringBlendParams; - Vec4 m_VolumetricFogScatteringColor; - Vec4 m_VolumetricFogScatteringSecondaryColor; - Vec4 m_VolumetricFogHeightDensityParams; - Vec4 m_VolumetricFogHeightDensityRampParams; - Vec4 m_VolumetricFogDistanceParams; -}; - -#endif // _PER_FRAME_RESOURCE_GROUP_ diff --git a/Code/CryEngine/RenderDll/Common/ShadowUtils.cpp b/Code/CryEngine/RenderDll/Common/ShadowUtils.cpp deleted file mode 100644 index 73fc5e2a1b..0000000000 --- a/Code/CryEngine/RenderDll/Common/ShadowUtils.cpp +++ /dev/null @@ -1,797 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ShadowUtils.h" - -bool CShadowUtils::bShadowFrustumCacheValid = false; - -void CShadowUtils::CalcDifferentials(const CCamera& cam, float fViewWidth, [[maybe_unused]] float fViewHeight, float& fFragSizeX) -{ - Vec3 vNearEdge = cam.GetEdgeN(); - - float fWorldWidthDiv2 = abs(vNearEdge.x); - - fFragSizeX = (fWorldWidthDiv2 * 2.0f) / fViewWidth; -} - -void CShadowUtils::CalcScreenToWorldExpansionBasis(const CCamera& cam, const Vec2& vJitter, float fViewWidth, float fViewHeight, Vec3& vWBasisX, Vec3& vWBasisY, Vec3& vWBasisZ, bool bWPos) -{ - const Matrix34& camMatrix = cam.GetMatrix(); - - Vec3 vNearEdge = cam.GetEdgeN(); - - //all values are in camera space - float fFar = cam.GetFarPlane(); - float fNear = abs(vNearEdge.y); - float fWorldWidthDiv2 = abs(vNearEdge.x); - float fWorldHeightDiv2 = abs(vNearEdge.z); - - float k = fFar / fNear; - - Vec3 vNearX = camMatrix.GetColumn0().GetNormalized() * fWorldWidthDiv2; - Vec3 vNearY = camMatrix.GetColumn2().GetNormalized() * fWorldHeightDiv2; - - Vec3 vJitterShiftX = vNearX * vJitter.x; - Vec3 vJitterShiftY = vNearY * vJitter.y; - - Vec3 vStereoShift = camMatrix.GetColumn0().GetNormalized() * cam.GetAsymL() + camMatrix.GetColumn2() * cam.GetAsymB(); - - Vec3 vZ = (camMatrix.GetColumn1().GetNormalized() * fNear + vStereoShift + vJitterShiftX + vJitterShiftY) * k; // size of vZ is the distance from camera pos to near plane - Vec3 vX = camMatrix.GetColumn0().GetNormalized() * (fWorldWidthDiv2 * k); - Vec3 vY = camMatrix.GetColumn2().GetNormalized() * (fWorldHeightDiv2 * k); - - //WPos basis adjustments - if (bWPos) - { - vZ = vZ - vX; - vX *= (2.0f / fViewWidth); - - vZ = vZ + vY; - vY *= -(2.0f / fViewHeight); - } - - vWBasisX = vX; - vWBasisY = vY; - vWBasisZ = vZ; -} - -void CShadowUtils::ProjectScreenToWorldExpansionBasis(const Matrix44r& mShadowTexGen, const CCamera& cam, const Vec2& vJitter, float fViewWidth, float fViewHeight, Vec4r& vWBasisX, Vec4r& vWBasisY, Vec4r& vWBasisZ, Vec4r& vCamPos, bool bWPos, SRenderTileInfo* pSTileInfo) -{ - const Matrix34& camMatrix = cam.GetMatrix(); - const bool bTileRendering = pSTileInfo && (pSTileInfo->nGridSizeX > 1 || pSTileInfo->nGridSizeY > 1); - - Vec3 vNearEdge = cam.GetEdgeN(); - - //all values are in camera space - float fFar = cam.GetFarPlane(); - float fNear = abs(vNearEdge.y); - float fWorldWidthDiv2 = abs(vNearEdge.x); - float fWorldHeightDiv2 = abs(vNearEdge.z); - - float k = fFar / fNear; - - //simple non-general hack to shift stereo with off center projection - Vec3 vStereoShift = camMatrix.GetColumn0().GetNormalized() * cam.GetAsymL() + camMatrix.GetColumn2() * cam.GetAsymB(); - - Vec3 vNearX = camMatrix.GetColumn0().GetNormalized() * fWorldWidthDiv2; - Vec3 vNearY = camMatrix.GetColumn2().GetNormalized() * fWorldHeightDiv2; - Vec3 vNearZ = camMatrix.GetColumn1().GetNormalized() * fNear; - - Vec3 vJitterShiftX = vNearX * vJitter.x; - Vec3 vJitterShiftY = vNearY * vJitter.y; - - Vec3 vZ = (vNearZ + vJitterShiftX + vJitterShiftY + vStereoShift) * k; // size of vZ is the distance from camera pos to near plane - - Vec3 vX = camMatrix.GetColumn0().GetNormalized() * fWorldWidthDiv2 * k; - Vec3 vY = camMatrix.GetColumn2().GetNormalized() * fWorldHeightDiv2 * k; - - //multi-tiled render handling - if (bTileRendering) - { - vZ = vZ + (vX * (2.0f * (pSTileInfo->nGridSizeX - 1.0f - pSTileInfo->nPosX) / pSTileInfo->nGridSizeX)); - vZ = vZ - (vY * (2.0f * (pSTileInfo->nGridSizeY - 1.0f - pSTileInfo->nPosY) / pSTileInfo->nGridSizeY)); - } - - //WPos basis adjustments - if (bWPos) - { - vZ = vZ - vX; - vX *= (2.0f / fViewWidth); - - vZ = vZ + vY; - vY *= -(2.0f / fViewHeight); - } - - //multi-tiled render handling - if (bTileRendering) - { - vX *= 1.0f / pSTileInfo->nGridSizeX; - vY *= 1.0f / pSTileInfo->nGridSizeY; - } - - //creating common projection matrix for depth reconstruction - vWBasisX = mShadowTexGen * Vec4r(vX, 0.0f); - vWBasisY = mShadowTexGen * Vec4r(vY, 0.0f); - vWBasisZ = mShadowTexGen * Vec4r(vZ, 0.0f); - vCamPos = mShadowTexGen * Vec4r(cam.GetPosition(), 1.0f); -} - -void CShadowUtils::CalcLightBoundRect(const SRenderLight* pLight, const CameraViewParameters& RCam, Matrix44A& mView, Matrix44A& mProj, Vec2* pvMin, Vec2* pvMax, IRenderAuxGeom* pAuxRend) -{ - Vec3 vViewVec = Vec3(pLight->m_Origin - RCam.vOrigin); - float fDistToLS = vViewVec.GetLength(); - - if (fDistToLS <= pLight->m_fRadius) - { - //optimization when we are inside light frustum - *pvMin = Vec2(0, 0); - *pvMax = Vec2(1, 1); - return; - } - - - float fRadiusSquared = pLight->m_fRadius * pLight->m_fRadius; - float fDistToBoundPlane = fRadiusSquared / fDistToLS; - - float fQuadEdge = sqrtf(fRadiusSquared - fDistToBoundPlane * fDistToBoundPlane); - - vViewVec.SetLength(fDistToLS - fDistToBoundPlane); - - Vec3 vCenter = RCam.vOrigin + vViewVec; - - Vec3 vUp = vViewVec.Cross(RCam.vY.Cross(vViewVec)); - Vec3 vRight = vViewVec.Cross(RCam.vX.Cross(vViewVec)); - - vUp.normalize(); - vRight.normalize(); - - float fRadius = pLight->m_fRadius; - - Vec3 pBRectVertices[4] = - { - vCenter + (vUp * fQuadEdge) - (vRight * fQuadEdge), - vCenter + (vUp * fQuadEdge) + (vRight * fQuadEdge), - vCenter - (vUp * fQuadEdge) + (vRight * fQuadEdge), - vCenter - (vUp * fQuadEdge) - (vRight * fQuadEdge) - }; - - Vec3 pBBoxVertices[8] = - { - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(-fRadius, -fRadius, fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(-fRadius, fRadius, fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(fRadius, -fRadius, fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(fRadius, fRadius, fRadius)), - - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(-fRadius, -fRadius, -fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(-fRadius, fRadius, -fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(fRadius, -fRadius, -fRadius)), - Vec3(Vec3(vCenter.x, vCenter.y, vCenter.z) + Vec3(fRadius, fRadius, -fRadius)) - }; - - Matrix44A mInvView = mView.GetInverted(); - - *pvMin = Vec2(1, 1); - *pvMax = Vec2(0, 0); - - for (int i = 0; i < 4; i++) - { - if (pAuxRend != NULL) - { - pAuxRend->DrawPoint(pBRectVertices[i], RGBA8(0xff, 0xff, 0xff, 0xff), 10); - - int32 nPrevVert = (i - 1) < 0 ? 3 : (i - 1); - - pAuxRend->DrawLine(pBRectVertices[nPrevVert], RGBA8(0xff, 0xff, 0x0, 0xff), pBRectVertices[i], RGBA8(0xff, 0xff, 0x0, 0xff), 3.0f); - } - - - Vec4 vScreenPoint = Vec4(pBRectVertices[i], 1.0) * mProj; - - //projection space clamping - vScreenPoint.w = max(vScreenPoint.w, 0.00000000000001f); - - vScreenPoint.x = max(vScreenPoint.x, -(vScreenPoint.w)); - vScreenPoint.x = min(vScreenPoint.x, vScreenPoint.w); - vScreenPoint.y = max(vScreenPoint.y, -(vScreenPoint.w)); - vScreenPoint.y = min(vScreenPoint.y, vScreenPoint.w); - vScreenPoint /= vScreenPoint.w; - - Vec2 vWin; - vWin.x = (1 + vScreenPoint.x) / 2; - vWin.y = (1 + vScreenPoint.y) / 2; - - assert(vWin.x >= 0.0f && vWin.x <= 1.0f); - assert(vWin.y >= 0.0f && vWin.y <= 1.0f); - - pvMin->x = min(pvMin->x, vWin.x); - pvMin->y = min(pvMin->y, vWin.y); - pvMax->x = max(pvMax->x, vWin.x); - pvMax->y = max(pvMax->y, vWin.y); - } -} - -void CShadowUtils::GetProjectiveTexGen(const SRenderLight* pLight, int nFace, Matrix44A* mTexGen) -{ - assert(pLight != NULL); - float fOffsetX = 0.5f; - float fOffsetY = 0.5f; - Matrix44A mTexScaleBiasMat = Matrix44A(0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - fOffsetX, fOffsetY, 0.0f, 1.0f); - - Matrix44A mLightProj, mLightView; - CShadowUtils::GetCubemapFrustumForLight(pLight, nFace, pLight->m_fLightFrustumAngle * 2.f, &mLightProj, &mLightView, true); - - Matrix44 mLightViewProj = mLightView * mLightProj; - - *mTexGen = mLightViewProj * mTexScaleBiasMat; -} - -void CShadowUtils::GetCubemapFrustumForLight(const SRenderLight* pLight, int nS, float fFov, Matrix44A* pmProj, Matrix44A* pmView, bool bProjLight) -{ - Vec3 zaxis, yaxis, xaxis; - - //new cubemap calculation - float sCubeVector[6][7] = - { - {1, 0, 0, 0, 0, -1, -90},//posx - {-1, 0, 0, 0, 0, 1, 90},//negx - {0, 1, 0, -1, 0, 0, 0},//posy - {0, -1, 0, 1, 0, 0, 0},//negy - {0, 0, 1, 0, -1, 0, 0},//posz - {0, 0, -1, 0, 1, 0, 0},//negz - }; - - Vec3 vForward = Vec3(sCubeVector[nS][0], sCubeVector[nS][1], sCubeVector[nS][2]); - Vec3 vUp = Vec3(sCubeVector[nS][3], sCubeVector[nS][4], sCubeVector[nS][5]); - Vec3 vEyePt = pLight->m_Origin; - vForward = vForward + vEyePt; - - //adjust light rotation - Matrix34 mLightRot = pLight->m_ObjMatrix; - - //coord systems conversion(from orientation to shader matrix) - if (bProjLight) - { - zaxis = mLightRot.GetColumn1().GetNormalized(); - yaxis = -mLightRot.GetColumn0().GetNormalized(); - xaxis = -mLightRot.GetColumn2().GetNormalized(); - } - else - { - zaxis = mLightRot.GetColumn2().GetNormalized(); - yaxis = -mLightRot.GetColumn0().GetNormalized(); - xaxis = mLightRot.GetColumn1().GetNormalized(); - } - - (*pmView)(0, 0) = xaxis.x; - (*pmView)(0, 1) = zaxis.x; - (*pmView)(0, 2) = yaxis.x; - (*pmView)(0, 3) = 0; - (*pmView)(1, 0) = xaxis.y; - (*pmView)(1, 1) = zaxis.y; - (*pmView)(1, 2) = yaxis.y; - (*pmView)(1, 3) = 0; - (*pmView)(2, 0) = xaxis.z; - (*pmView)(2, 1) = zaxis.z; - (*pmView)(2, 2) = yaxis.z; - (*pmView)(2, 3) = 0; - (*pmView)(3, 0) = -xaxis.Dot(vEyePt); - (*pmView)(3, 1) = -zaxis.Dot(vEyePt); - (*pmView)(3, 2) = -yaxis.Dot(vEyePt); - (*pmView)(3, 3) = 1; - - float zn = max(pLight->m_fProjectorNearPlane, 0.01f); - float zf = max(pLight->m_fRadius, zn + 0.01f); - mathMatrixPerspectiveFov(pmProj, (float)DEG2RAD_R(fFov), 1.f, zn, zf); -} - -void CShadowUtils::GetCubemapFrustum(EFrustum_Type eFrustumType, ShadowMapFrustum* pFrust, int nS, Matrix44A* pmProj, Matrix44A* pmView, Matrix33* pmLightRot) -{ - float sCubeVector[6][7] = - { - {1, 0, 0, 0, 0, -1, -90},//posx - {-1, 0, 0, 0, 0, 1, 90},//negx - {0, 1, 0, -1, 0, 0, 0},//posy - {0, -1, 0, 1, 0, 0, 0},//negy - {0, 0, 1, 0, -1, 0, 0},//posz - {0, 0, -1, 0, 1, 0, 0},//negz - }; - - Vec3 vForward = Vec3(sCubeVector[nS][0], sCubeVector[nS][1], sCubeVector[nS][2]); - Vec3 vUp = Vec3(sCubeVector[nS][3], sCubeVector[nS][4], sCubeVector[nS][5]); - float fMinDist = max(pFrust->fNearDist, 0.03f); - float fMaxDist = pFrust->fFarDist; - - Vec3 vEyePt = Vec3( - pFrust->vLightSrcRelPos.x + pFrust->vProjTranslation.x, - pFrust->vLightSrcRelPos.y + pFrust->vProjTranslation.y, - pFrust->vLightSrcRelPos.z + pFrust->vProjTranslation.z - ); - Vec3 At = vEyePt; - - if (eFrustumType == FTYP_OMNILIGHTVOLUME) - { - vEyePt -= (2.0f * fMinDist) * vForward.GetNormalized(); - } - - vForward = vForward + At; - - //mathMatrixTranslation(&mLightTranslate, -vPos.x, -vPos.y, -vPos.z);2 - mathMatrixLookAt(pmView, vEyePt, vForward, vUp); - - //adjust light rotation - if (pmLightRot) - { - (*pmView) = (*pmView) * (*pmLightRot); - } - if (eFrustumType == FTYP_SHADOWOMNIPROJECTION) - { - //near plane does have big influence on the precision (depth distribution) for non linear frustums - mathMatrixPerspectiveFov(pmProj, (float)DEG2RAD_R(g_fOmniShadowFov), 1.f, fMinDist, fMaxDist); - } - else - if (eFrustumType == FTYP_OMNILIGHTVOLUME) - { - //near plane should be extremely small in order to avoid seams on between frustums - mathMatrixPerspectiveFov(pmProj, (float)DEG2RAD_R(g_fOmniLightFov), 1.f, fMinDist, fMaxDist); - } -} - -Matrix34 CShadowUtils::GetAreaLightMatrix(const SRenderLight* pLight, Vec3 vScale) -{ - // Box needs to be scaled by 2x for correct radius. - vScale *= 2.0f; - - // Add width and height to scale. - float fFOVScale = 2.16f * (max(0.001f, pLight->m_fLightFrustumAngle * 2.0f) / 180.0f); - vScale.y += pLight->m_fAreaWidth * fFOVScale; - vScale.z += pLight->m_fAreaHeight * fFOVScale; - - Matrix34 mAreaMatr; - mAreaMatr.SetIdentity(); - mAreaMatr.SetScale(vScale, pLight->m_Origin); - - // Apply rotation. - mAreaMatr = pLight->m_ObjMatrix * mAreaMatr; - - // Move box center to light center and pull it back slightly. - Vec3 vOffsetDir = vScale.y * 0.5f * pLight->m_ObjMatrix.GetColumn1().GetNormalized() + - vScale.z * 0.5f * pLight->m_ObjMatrix.GetColumn2().GetNormalized() + - 0.1f * pLight->m_ObjMatrix.GetColumn0().GetNormalized(); - - mAreaMatr.SetTranslation(pLight->m_Origin - vOffsetDir); - - return mAreaMatr; -} - -static _inline Vec3 frac(Vec3 in) -{ - Vec3 out; - out.x = in.x - (float)(int)in.x; - out.y = in.y - (float)(int)in.y; - out.z = in.z - (float)(int)in.z; - - return out; -} - -float snap_frac2(float fVal, float fSnap) -{ - float fValSnapped = fSnap * int64(fVal / fSnap); - return fValSnapped; -} - -//Right Handed -void CShadowUtils::mathMatrixLookAtSnap(Matrix44A* pMatr, const Vec3& Eye, const Vec3& At, ShadowMapFrustum* pFrust) -{ - const Vec3 vZ(0.f, 0.f, 1.f); - const Vec3 vY(0.f, 1.f, 0.f); - - Vec3 vUp; - Vec3 vEye = Eye; - Vec3 vAt = At; - - Vec3 vLightDir = (vEye - vAt); - vLightDir.Normalize(); - - if (fabsf(vLightDir.Dot(vZ)) > 0.9995f) - { - vUp = vY; - } - else - { - vUp = vZ; - } - - float fKatetSize = 1000000.0f * tan_tpl(DEG2RAD(pFrust->fFOV) * 0.5f); - - assert(pFrust->nTexSize > 0); - float fSnapXY = fKatetSize * 2.f / pFrust->nTexSize; //texture size should be valid already - - //TD - add ratios to the frustum - fSnapXY *= 2.0f; - - Vec3 zaxis = vLightDir.GetNormalized(); - Vec3 xaxis = (vUp.Cross(zaxis)).GetNormalized(); - Vec3 yaxis = zaxis.Cross(xaxis); - - (*pMatr)(0, 0) = xaxis.x; - (*pMatr)(0, 1) = yaxis.x; - (*pMatr)(0, 2) = zaxis.x; - (*pMatr)(0, 3) = 0; - (*pMatr)(1, 0) = xaxis.y; - (*pMatr)(1, 1) = yaxis.y; - (*pMatr)(1, 2) = zaxis.y; - (*pMatr)(1, 3) = 0; - (*pMatr)(2, 0) = xaxis.z; - (*pMatr)(2, 1) = yaxis.z; - (*pMatr)(2, 2) = zaxis.z; - (*pMatr)(2, 3) = 0; - (*pMatr)(3, 0) = -xaxis.Dot(vEye); - (*pMatr)(3, 1) = -yaxis.Dot(vEye); - (*pMatr)(3, 2) = -zaxis.Dot(vEye); - (*pMatr)(3, 3) = 1; - - float fTranslX = (*pMatr)(3, 0); - float fTranslY = (*pMatr)(3, 1); - - (*pMatr)(3, 0) = snap_frac2(fTranslX, fSnapXY); - (*pMatr)(3, 1) = snap_frac2(fTranslY, fSnapXY); -} - -//todo move frustum computations to the 3d engine -void CShadowUtils::GetShadowMatrixOrtho(Matrix44A& mLightProj, Matrix44A& mLightView, const Matrix44A& mViewMatrix, ShadowMapFrustum* lof, bool bViewDependent) -{ - mathMatrixPerspectiveFov(&mLightProj, (float)DEG2RAD_R(max(lof->fFOV, 0.0000001f)), max(lof->fProjRatio, 0.0001f), lof->fNearDist, lof->fFarDist); - - const Vec3 zAxis(0.f, 0.f, 1.f); - const Vec3 yAxis(0.f, 1.f, 0.f); - Vec3 Up; - Vec3 Eye = Vec3( - lof->vLightSrcRelPos.x + lof->vProjTranslation.x, - lof->vLightSrcRelPos.y + lof->vProjTranslation.y, - lof->vLightSrcRelPos.z + lof->vProjTranslation.z); - Vec3 At = Vec3(lof->vProjTranslation.x, lof->vProjTranslation.y, lof->vProjTranslation.z); - - Vec3 vLightDir = At - Eye; - vLightDir.Normalize(); - - if (bViewDependent) - { - Eye = mViewMatrix.GetTransposed().TransformPoint(Eye); - At = (mViewMatrix.GetTransposed()).TransformPoint(At); - vLightDir = (mViewMatrix.GetTransposed()).TransformVector(vLightDir); - } - - //get look-at matrix - if (CRenderer::CV_r_ShadowsGridAligned && lof->m_Flags & DLF_DIRECTIONAL) - { - mathMatrixLookAtSnap(&mLightView, Eye, At, lof); - } - else - { - if (fabsf(vLightDir.Dot(zAxis)) > 0.9995f) - { - Up = yAxis; - } - else - { - Up = zAxis; - } - - mathMatrixLookAt(&mLightView, Eye, At, Up); - } - - //we should transform coords to the view space, so shadows are oriented according to camera always - if (bViewDependent) - { - mLightView = mViewMatrix * mLightView; - } -} - -//todo move frustum computations to the 3d engine -void CShadowUtils::GetShadowMatrixForObject(Matrix44A& mLightProj, Matrix44A& mLightView, ShadowMapFrustum* lof) -{ - const AABB& aabb = lof->aabbCasters; - - if (aabb.GetRadius() < 0.001f) - { - mLightProj.SetIdentity(); - mLightView.SetIdentity(); - lof->fNearDist = 0.1f; - lof->fFarDist = 100.0f; - lof->fDepthTestBias = 0.00001f; - return; - } - - //Ortho - f32 yScale = aabb.GetRadius() * 1.11f; - f32 xScale = yScale; - f32 fNear = lof->vLightSrcRelPos.GetLength(); - f32 fFar = fNear; - fNear -= aabb.GetRadius(); - fFar += aabb.GetRadius(); - mathMatrixOrtho(&mLightProj, yScale, xScale, fNear, fFar); - const Vec3 zAxis(0.f, 0.f, 1.f); - const Vec3 yAxis(0.f, 1.f, 0.f); - Vec3 Up; - Vec3 At = aabb.GetCenter(); - Vec3 vLightDir = -lof->vLightSrcRelPos; - vLightDir.Normalize(); - - Vec3 Eye = At - lof->vLightSrcRelPos.len() * vLightDir; - - if (fabsf(vLightDir.Dot(zAxis)) > 0.9995f) - { - Up = yAxis; - } - else - { - Up = zAxis; - } - - mathMatrixLookAt(&mLightView, Eye, At, Up); - - lof->fNearDist = fNear; - lof->fFarDist = fFar; - lof->fDepthTestBias = 0.00001f; -} - -AABB CShadowUtils::GetShadowMatrixForCasterBox(Matrix44A& mLightProj, Matrix44A& mLightView, ShadowMapFrustum* lof, float fFarPlaneOffset) -{ - GetShadowMatrixForObject(mLightProj, mLightView, lof); - - AABB lightSpaceBounds = AABB::CreateTransformedAABB(Matrix34(mLightView.GetTransposed()), lof->aabbCasters); - Vec3 lightSpaceRange = lightSpaceBounds.GetSize(); - - const float fNear = -lightSpaceBounds.max.z; - const float fFar = -lightSpaceBounds.min.z + fFarPlaneOffset; - - const float yfov = atan_tpl(lightSpaceRange.y * 0.5f / fNear) * 2.f; - const float aspect = lightSpaceRange.x / lightSpaceRange.y; - - mathMatrixPerspectiveFov(&mLightProj, yfov, aspect, fNear, fFar); - - return lightSpaceBounds; -} - - -CShadowUtils::CShadowUtils() -{ -} - -CShadowUtils::~CShadowUtils() -{ -} - - -Vec2& CPoissonDiskGen::GetSample(int ind) -{ - assert(ind < m_vSamples.size() && ind >= 0); - return m_vSamples[ind]; -} - -// the size of the kernel for each entry is the index in this vector -StaticInstance> s_kernelSizeGens; -CPoissonDiskGen& CPoissonDiskGen::GetGenForKernelSize(int size) -{ - if ((int)s_kernelSizeGens.size() <= size) - { - s_kernelSizeGens.resize(size + 1); - } - - CPoissonDiskGen& pdg = s_kernelSizeGens[size]; - - if (pdg.m_vSamples.size() == 0) - { - pdg.m_vSamples.resize(size); - pdg.InitSamples(); - } - - return pdg; -} - -void CPoissonDiskGen::FreeMemory() -{ - s_kernelSizeGens.clear(); -} - -void CPoissonDiskGen::RandomPoint(CRndGen& rand, Vec2& p) -{ - //generate random point inside circle - do - { - p.x = rand.GenerateFloat() - 0.5f; - p.y = rand.GenerateFloat() - 0.5f; - } while (p.x * p.x + p.y * p.y > 0.25f); - - return; -} - -//samples distance-based sorting -struct SamplesDistaceSort -{ - bool operator()(const Vec2& samplA, const Vec2& samplB) const - { - float R2sampleA = samplA.x * samplA.x + samplA.y * samplA.y; - float R2sampleB = samplB.x * samplB.x + samplB.y * samplB.y; - - return - (R2sampleA < R2sampleB); - } -}; - -void CPoissonDiskGen::InitSamples() -{ - //Use a random generator with a fixed seed, so code changes(someone adding a new call to rnd() somehwhere) doesn't cause feature tests to fail. - CRndGen rand; - - const int nQ = 1000; - - RandomPoint(rand, m_vSamples[0]); - - for (int i = 1; i < (int)m_vSamples.size(); i++) - { - float dmax = -1.0; - - for (int c = 0; c < i * nQ; c++) - { - Vec2 curSample; - RandomPoint(rand, curSample); - - float dc = 2.0; - for (int j = 0; j < i; j++) - { - float dj = - (m_vSamples[j].x - curSample.x) * (m_vSamples[j].x - curSample.x) + - (m_vSamples[j].y - curSample.y) * (m_vSamples[j].y - curSample.y); - if (dc > dj) - { - dc = dj; - } - } - - if (dc > dmax) - { - m_vSamples[i] = curSample; - dmax = dc; - } - } - } - - for (int i = 0; i < (int)m_vSamples.size(); i++) - { - m_vSamples[i] *= 2.0f; - } - - //samples sorting - std::stable_sort(m_vSamples.begin(), m_vSamples.end(), SamplesDistaceSort()); -} - -void CShadowUtils::GetIrregKernel(float sData[][4], int nSamplesNum) -{ - CPoissonDiskGen& pdg = CPoissonDiskGen::GetGenForKernelSize(nSamplesNum); - - for (int i = 0, nIdx = 0; i < nSamplesNum; i += 2, nIdx++) - { - Vec2 vSample = pdg.GetSample(i); - sData[nIdx][0] = vSample.x; - sData[nIdx][1] = vSample.y; - vSample = pdg.GetSample(i + 1); - sData[nIdx][2] = vSample.x; - sData[nIdx][3] = vSample.y; - } -} - -ShadowMapFrustum* CShadowUtils::GetFrustum(ShadowFrustumID nFrustumID) -{ - int nLOD = 0; - const int nLightID = GetShadowLightID(nLOD, nFrustumID); - const int nThreadID = gRenDev->m_RP.m_nProcessThreadID; - const int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - - const int nDLights = gRenDev->m_RP.m_DLights[nThreadID][nCurRecLevel].size(); - - const int nFrustumIdx = nLightID; - assert((unsigned int) nFrustumIdx < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nFrustumIdx]; - const int nEndIdx = SRendItem::m_EndFrust[nThreadID][nFrustumIdx]; - - const int nSize = gRenDev->m_RP.m_SMFrustums[nThreadID][nCurRecLevel].size(); - for (int nFrIdx = nStartIdx; nFrIdx < nEndIdx && nFrIdx < nSize; ++nFrIdx) - { - ShadowMapFrustum* frustum = &gRenDev->m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nFrIdx]; - if (frustum->nShadowMapLod == nLOD) - { - return frustum; - } - } - - assert(0); - return NULL; -} - -ShadowMapFrustum& CShadowUtils::GetFirstFrustum(int nLightID) -{ - const int nThreadID = gRenDev->m_RP.m_nProcessThreadID; - const int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - const int nDLights = gRenDev->m_RP.m_DLights[nThreadID][nCurRecLevel].size(); - - const int nFrustumIdx = nLightID + nDLights; - assert((unsigned int) nFrustumIdx < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nFrustumIdx]; - - ShadowMapFrustum& firstFrustum = gRenDev->m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nStartIdx]; - return firstFrustum; -} - -const CShadowUtils::ShadowFrustumIDs* CShadowUtils::GetShadowFrustumList(uint64 nMask) -{ - // TODO: proper fix for per render object shadow light mask - return NULL; - - if (!nMask) - { - return NULL; - } - - if (!bShadowFrustumCacheValid) - { - // clear all allocated lists - for (CRenderer::ShadowFrustumListsCache::iterator it = gRenDev->m_FrustumsCache.begin(); - it != gRenDev->m_FrustumsCache.end(); ++it) - { - (it->second)->Clear(); - } - bShadowFrustumCacheValid = true; - } - - CShadowUtils::ShadowFrustumIDs* pList = stl::find_in_map(gRenDev->m_FrustumsCache, nMask, NULL); - if (!pList) - { - pList = new CShadowUtils::ShadowFrustumIDs; - } - if (pList->empty()) - { - assert(nSunLightID <= 0xFF); - // add sun index and lods encoded in higher bits - for (int i = 0; i < 8; ++i) - { - if (nMask & (uint64(1) << i)) - { - pList->Add((i << 8) | (nSunLightID & 0xFF)); - } - } - // other lights have 1 lod and index encoded in low bits - for (int i = 8; i < 64 && (uint64(1) << i) <= nMask; ++i) - { - if (nMask & (uint64(1) << i)) - { - pList->Add(i); - } - } - gRenDev->m_FrustumsCache[nMask] = pList; - } - return pList; -} - -void ShadowMapFrustum::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(pFrustumOwner); - pSizer->AddObject(pDepthTex); -} diff --git a/Code/CryEngine/RenderDll/Common/ShadowUtils.h b/Code/CryEngine/RenderDll/Common/ShadowUtils.h deleted file mode 100644 index fce023b2ee..0000000000 --- a/Code/CryEngine/RenderDll/Common/ShadowUtils.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __SHADOWUTILS_H__ -#define __SHADOWUTILS_H__ - -#define DEG2RAD_R(a) (f64(a) * (g_PI / 180.0)) -#define RAD2DEG_R(a) float((f64)(a) * (180.0 / g_PI)) - -static const float g_fOmniShadowFov = 95.0f; -static const float g_fOmniLightFov = 90.5f; - -class CRndGen; - -class CPoissonDiskGen -{ - std::vector m_vSamples; - -private: - static void RandomPoint(CRndGen& rand, Vec2& p); - void InitSamples(); - -public: - Vec2& GetSample(int ind); - - static CPoissonDiskGen& GetGenForKernelSize(int num); - static void FreeMemory(); -}; - -enum EFrustum_Type -{ - FTYP_SHADOWOMNIPROJECTION, - FTYP_SHADOWPROJECTION, - FTYP_OMNILIGHTVOLUME, - FTYP_LIGHTVOLUME, - FTYP_MAX, - FTYP_UNKNOWN -}; - -struct SRenderTileInfo; - -class CShadowUtils -{ -public: - typedef uint16 ShadowFrustumID; - typedef PodArray ShadowFrustumIDs; - -public: - static void CalcDifferentials(const CCamera& cam, float fViewWidth, float fViewHeight, float& fFragSizeX); - static void ProjectScreenToWorldExpansionBasis(const Matrix44r& mShadowTexGen, const CCamera& cam, const Vec2& vJitter, float fViewWidth, float fViewHeight, Vec4r& vWBasisX, Vec4r& vWBasisY, Vec4r& vWBasisZ, Vec4r& vCamPos, bool bWPos, SRenderTileInfo* pSTileInfo); - static void CalcScreenToWorldExpansionBasis(const CCamera& cam, const Vec2& vJitter, float fViewWidth, float fViewHeight, Vec3& vWBasisX, Vec3& vWBasisY, Vec3& vWBasisZ, bool bWPos); - - static void CalcLightBoundRect(const SRenderLight* pLight, const CameraViewParameters& RCam, Matrix44A& mView, Matrix44A& mProj, Vec2* pvMin, Vec2* pvMax, IRenderAuxGeom* pAuxRend); - static void GetProjectiveTexGen(const SRenderLight* pLight, int nFace, Matrix44A* mTexGen); - static void GetCubemapFrustumForLight(const SRenderLight* pLight, int nS, float fFov, Matrix44A* pmProj, Matrix44A* pmView, bool bProjLight); - - static void GetShadowMatrixForObject(Matrix44A& mLightProj, Matrix44A& mLightView, ShadowMapFrustum* lof); - static AABB GetShadowMatrixForCasterBox(Matrix44A& mLightProj, Matrix44A& mLightView, ShadowMapFrustum* lof, float fFarPlaneOffset = 0); - static void GetCubemapFrustum(EFrustum_Type eFrustumType, ShadowMapFrustum* pFrust, int nS, Matrix44A* pmProj, Matrix44A* pmView, Matrix33* pmLightRot = NULL); - - static Matrix34 GetAreaLightMatrix(const SRenderLight* pLight, Vec3 vScale); - - static void mathMatrixLookAtSnap(Matrix44A* pMatr, const Vec3& Eye, const Vec3& At, ShadowMapFrustum* pFrust); - static void GetShadowMatrixOrtho(Matrix44A& mLightProj, Matrix44A& mLightView, const Matrix44A& mViewMatrix, ShadowMapFrustum* lof, bool bViewDependent); - - static void GetIrregKernel(float sData[][4], int nSamplesNum); - - static ShadowMapFrustum* GetFrustum(ShadowFrustumID nFrustumID); - static ShadowMapFrustum& GetFirstFrustum(int nLightID); - - // Get list of encoded frustum ids for given mask - static const ShadowFrustumIDs* GetShadowFrustumList(uint64 nMask); - // Get light id and LOD id from encoded id in shadow frustum cache - static int32 GetShadowLightID(int32& nLod, ShadowFrustumID nFrustumID) - { - nLod = int32((nFrustumID >> 8) & 0xFF); - return int32(nFrustumID & 0xFF); - } - static void InvalidateShadowFrustumCache() - { - bShadowFrustumCacheValid = false; - } - - CShadowUtils(); - ~CShadowUtils(); - -private: - static bool bShadowFrustumCacheValid; - // Currently forced to use always ID 0 for sun (if sun present) - static const int nSunLightID = 0; -}; - -#endif diff --git a/Code/CryEngine/RenderDll/Common/Shadow_Renderer.h b/Code/CryEngine/RenderDll/Common/Shadow_Renderer.h deleted file mode 100644 index f238c5d065..0000000000 --- a/Code/CryEngine/RenderDll/Common/Shadow_Renderer.h +++ /dev/null @@ -1,602 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#if !defined(SHADOWRENDERER_H) -#define SHADOWRENDERER_H - - -#include "ShadowUtils.h" -#include -#include -#include - -#define OMNI_SIDES_NUM 6 - -// data used to compute a custom shadow frustum for near shadows -struct CustomShadowMapFrustumData -{ - AABB aabb; -}; - -struct ShadowMapFrustum -{ - enum eFrustumType // NOTE: Be careful when modifying the enum as it is used for sorting frustums in SCompareByLightIds - { - e_GsmDynamic = 0, - e_GsmDynamicDistance = 1, - e_GsmCached = 2, - e_HeightMapAO = 3, - e_Nearest = 4, - e_PerObject = 5, - - e_NumTypes - }; - - eFrustumType m_eFrustumType; - - Matrix44A mLightProjMatrix; - Matrix44A mLightViewMatrix; - - // flags - bool bUseAdditiveBlending; - bool bIncrementalUpdate; - - // if set to true - m_castersList contains all casters in light radius - // and all other members related only to single frustum projection case are undefined - bool bOmniDirectionalShadow; - uint8 nOmniFrustumMask; - uint8 nInvalidatedFrustMask[MAX_GPU_NUM]; //for each GPU - bool bBlendFrustum; - float fBlendVal; - - uint32 nShadowGenMask; - bool bIsMGPUCopy; - - bool bHWPCFCompare; - - uint8 nShadowPoolUpdateRate; - - //sampling parameters - f32 fWidthS, fWidthT; - f32 fBlurS, fBlurT; - - //fading distance per light source - float fShadowFadingDist; - - ETEX_Format m_eReqTF; - ETEX_Type m_eReqTT; - - //texture in pool - bool bUseShadowsPool; - struct ShadowMapFrustum* pPrevFrustum = nullptr; - struct ShadowMapFrustum* pFrustumOwner = nullptr; - class CTexture* pDepthTex; - - //3d engine parameters - float fFOV; - float fNearDist; - float fFarDist; - int nTexSize; - - //shadow renderer parameters - should be in separate structure - //atlas parameters - int nTextureWidth; - int nTextureHeight; - bool bUnwrapedOmniDirectional; - int nShadowMapSize; - - //packer params - uint nPackID[OMNI_SIDES_NUM]; - int packX[OMNI_SIDES_NUM]; - int packY[OMNI_SIDES_NUM]; - int packWidth[OMNI_SIDES_NUM]; - int packHeight[OMNI_SIDES_NUM]; - - int nResetID; - float fFrustrumSize; - float fProjRatio; - float fDepthTestBias; - float fDepthConstBias; - float fDepthSlopeBias; - PodArray m_castersList; - PodArray m_jobExecutedCastersList; - - CCamera FrustumPlanes[OMNI_SIDES_NUM]; - uint32 nShadowGenID[RT_COMMAND_BUF_COUNT][OMNI_SIDES_NUM]; - AABB aabbCasters; //casters bbox in world space - Vec3 vLightSrcRelPos; // relative world space - Vec3 vProjTranslation; // dst position - float fRadius; - int nUpdateFrameId; - IRenderNode* pLightOwner = nullptr; - uint32 uCastersListCheckSum; - int nShadowMapLod; // currently use as GSMLod, can be used as cubemap side, -1 means this variable is not used - - uint32 m_Flags; - - struct ShadowCacheData - { - enum eUpdateStrategy - { - // Renders the entire cached shadowmap in one pass. - // Generally used for a single frame when an event (script, level load, proximity to frustum border, etc.) requests an update of the cache. - // Will revert to one of the other methods after the update occurs. - eFullUpdate, - - // Cached shadow frustums will constantly check if updates are required due to moving objects or proximity to the frustum border. - // Has potentially very high CPU overhead because each cached shadow map frustum culls the octree each frame. - // Potentially higher GPU overhead because may render extra dynamic or distant objects each frame. - eIncrementalUpdate, - - // Updates must triggered manually via script. Most optimal solution, but requires manual setup. - eManualUpdate, - - // Updates may either be triggered manually by script or when the camera moves too close to the border of the shadow frustum - eManualOrDistanceUpdate - }; - - ShadowCacheData() { Reset(); } - - void Reset() - { - memset(mOctreePath, 0x0, sizeof(mOctreePath)); - memset(mOctreePathNodeProcessed, 0x0, sizeof(mOctreePathNodeProcessed)); - mProcessedCasters.clear(); - mProcessedTerrainCasters.clear(); - } - - static const int MAX_TRAVERSAL_PATH_LENGTH = 32; - uint8 mOctreePath[MAX_TRAVERSAL_PATH_LENGTH]; - uint8 mOctreePathNodeProcessed[MAX_TRAVERSAL_PATH_LENGTH]; - - VectorSet mProcessedCasters; - VectorSet mProcessedTerrainCasters; - }* pShadowCacheData = nullptr; - - - ShadowMapFrustum() - { - ZeroStruct(*this); - fProjRatio = 1.f; - - //initial frustum position should be outside of the visible map - vProjTranslation = Vec3(-1000.0f, -1000.0f, -1000.0f); - - bUnwrapedOmniDirectional = false; - nShadowMapSize = 0; - - nUpdateFrameId = -1000; - - pPrevFrustum = nullptr; - aabbCasters.Reset(); - } - - ShadowMapFrustum(const ShadowMapFrustum& rOther) - { - (*this) = rOther; - } - - ~ShadowMapFrustum() - { - // make sure that the renderer isn't using this shadow frustum anymore - threadID nThreadID = 0; - gEnv->pRenderer->EF_Query(EFQ_RenderThreadList, nThreadID); - gEnv->pRenderer->GetFinalizeShadowRendItemJobExecutor(nThreadID)->WaitForCompletion(); - - SAFE_DELETE(pShadowCacheData); - } - - ShadowMapFrustum& operator=(const ShadowMapFrustum& rOther) - { - m_eFrustumType = rOther.m_eFrustumType; - mLightProjMatrix = rOther.mLightProjMatrix; - mLightViewMatrix = rOther.mLightViewMatrix; - - bUseAdditiveBlending = rOther.bUseAdditiveBlending; - bOmniDirectionalShadow = rOther.bOmniDirectionalShadow; - bBlendFrustum = rOther.bBlendFrustum; - fBlendVal = rOther.fBlendVal; - bIncrementalUpdate = rOther.bIncrementalUpdate; - nOmniFrustumMask = rOther.nOmniFrustumMask; - memcpy(nInvalidatedFrustMask, rOther.nInvalidatedFrustMask, sizeof(nInvalidatedFrustMask)); - nShadowGenMask = rOther.nShadowGenMask; - - bHWPCFCompare = rOther.bHWPCFCompare; - - nShadowPoolUpdateRate = rOther.nShadowPoolUpdateRate; - - fWidthS = rOther.fWidthS; - fWidthT = rOther.fWidthT; - fBlurS = rOther.fBlurS; - fBlurT = rOther.fBlurT; - - fShadowFadingDist = rOther.fShadowFadingDist; - - m_eReqTF = rOther.m_eReqTF; - m_eReqTT = rOther.m_eReqTT; - - bUseShadowsPool = rOther.bUseShadowsPool; - - // those pointer are not owned by the shadowfrustum, so we don't need a deep copy - pFrustumOwner = rOther.pFrustumOwner; - pDepthTex = rOther.pDepthTex; - pLightOwner = rOther.pLightOwner; - - fFOV = rOther.fFOV; - fNearDist = rOther.fNearDist; - fFarDist = rOther.fFarDist; - nTexSize = rOther.nTexSize; - - nTextureWidth = rOther.nTextureWidth; - nTextureHeight = rOther.nTextureHeight; - bUnwrapedOmniDirectional = rOther.bUnwrapedOmniDirectional; - nShadowMapSize = rOther.nShadowMapSize; - - memcpy(nPackID, rOther.nPackID, sizeof(nPackID)); - memcpy(packX, rOther.packX, sizeof(packX)); - memcpy(packY, rOther.packY, sizeof(packY)); - memcpy(packWidth, rOther.packWidth, sizeof(packWidth)); - memcpy(packHeight, rOther.packHeight, sizeof(packHeight)); - - nResetID = rOther.nResetID; - fFrustrumSize = rOther.fFrustrumSize; - fProjRatio = rOther.fProjRatio; - fDepthTestBias = rOther.fDepthTestBias; - fDepthConstBias = rOther.fDepthConstBias; - fDepthSlopeBias = rOther.fDepthSlopeBias; - - m_castersList = rOther.m_castersList; - m_jobExecutedCastersList = rOther.m_jobExecutedCastersList; - - memcpy(FrustumPlanes, rOther.FrustumPlanes, sizeof(FrustumPlanes)); - memcpy(nShadowGenID, rOther.nShadowGenID, sizeof(nShadowGenID)); - - aabbCasters = rOther.aabbCasters; - vLightSrcRelPos = rOther.vLightSrcRelPos; - vProjTranslation = rOther.vProjTranslation; - fRadius = rOther.fRadius; - nUpdateFrameId = rOther.nUpdateFrameId; - - uCastersListCheckSum = rOther.uCastersListCheckSum; - nShadowMapLod = rOther.nShadowMapLod; - m_Flags = rOther.m_Flags; - - bIsMGPUCopy = rOther.bIsMGPUCopy; - if (rOther.pShadowCacheData != nullptr) - { - if (pShadowCacheData == nullptr) - { - pShadowCacheData = new ShadowCacheData(); - } - *pShadowCacheData = *rOther.pShadowCacheData; - } - else - { - SAFE_DELETE(pShadowCacheData); - } - - return *this; - } - - void GetSideViewport(int nSide, int* pViewport) - { - if (bUseShadowsPool) - { - pViewport[0] = packX[nSide]; - pViewport[1] = packY[nSide]; - pViewport[2] = packWidth[nSide]; - pViewport[3] = packHeight[nSide]; - } - else - { - //simplest cubemap 6 faces unwrap - pViewport[0] = nShadowMapSize * (nSide % 3); - pViewport[1] = nShadowMapSize * (nSide / 3); - pViewport[2] = nShadowMapSize; - pViewport[3] = nShadowMapSize; - } - } - - void GetTexOffset(int nSide, float* pOffset, float* pScale, int nShadowsPoolSizeX, int nShadowsPoolSizeY) - { - if (bUseShadowsPool) - { - pScale[0] = float(nShadowMapSize) / nShadowsPoolSizeX; //SHADOWS_POOL_SZ 1024 - pScale[1] = float(nShadowMapSize) / nShadowsPoolSizeY; - pOffset[0] = float(packX[nSide]) / nShadowsPoolSizeX; - pOffset[1] = float(packY[nSide]) / nShadowsPoolSizeY; - } - else - { - pOffset[0] = 1.0f / 3.0f * (nSide % 3); - pOffset[1] = 1.0f / 2.0f * (nSide / 3); - pScale[0] = 1.0f / 3.0f; - pScale[1] = 1.0f / 2.0f; - } - } - - void RequestUpdate() - { - for (int i = 0; i < MAX_GPU_NUM; i++) - { - nInvalidatedFrustMask[i] = 0x3F; - } - } - - bool isUpdateRequested(int nMaskNum) - { - assert(nMaskNum >= 0 && nMaskNum < MAX_GPU_NUM); - /*if (nMaskNum==-1) //request from 3dengine - { - for (int i=0; i0) - return true; - } - return false; - }*/ - - return (nInvalidatedFrustMask[nMaskNum] > 0); - } - - bool IsCached() const - { - return m_eFrustumType == e_GsmCached || m_eFrustumType == e_HeightMapAO; - } - - ILINE bool IntersectAABB(const AABB& bbox, bool* pAllIn) const - { - if (bOmniDirectionalShadow) - { - return bbox.IsOverlapSphereBounds(vLightSrcRelPos + vProjTranslation, fFarDist); - } - else - { - bool bDummy = false; - if (bBlendFrustum) - { - if (FrustumPlanes[1].IsAABBVisible_EH(bbox, pAllIn) > 0) - { - return true; - } - } - - return FrustumPlanes[0].IsAABBVisible_EH(bbox, bBlendFrustum ? &bDummy : pAllIn) > 0; - } - } - - ILINE bool IntersectSphere(const Sphere& sp, bool* pAllIn) - { - if (bOmniDirectionalShadow) - { - return Distance::Point_PointSq(sp.center, vLightSrcRelPos + vProjTranslation) < sqr(fFarDist + sp.radius); - } - else - { - uint8 res = 0; - if (bBlendFrustum) - { - res = FrustumPlanes[1].IsSphereVisible_FH(sp); - * pAllIn = (res == CULL_INCLUSION); - if (res != CULL_EXCLUSION) - { - return true; - } - } - res = FrustumPlanes[0].IsSphereVisible_FH(sp); - * pAllIn = bBlendFrustum ? false : (res == CULL_INCLUSION); - return res != CULL_EXCLUSION; - } - } - - void UnProject(float sx, float sy, float sz, float* px, float* py, float* pz, IRenderer* pRend) - { - const int shadowViewport[4] = {0, 0, 1, 1}; - - Matrix44A mIden; - mIden.SetIdentity(); - - //FIX remove float arrays - pRend->UnProject(sx, sy, sz, - px, py, pz, - (float*)&mLightViewMatrix, - (float*)&mIden, - shadowViewport); - } - - Vec3& UnProjectVertex3d(int sx, int sy, int sz, Vec3& vert, IRenderer* pRend) - { - float px; - float py; - float pz; - UnProject((float)sx, (float)sy, (float)sz, &px, &py, &pz, pRend); - vert.x = (float)px; - vert.y = (float)py; - vert.z = (float)pz; - - // pRend->DrawBall(vert,10); - - return vert; - } - - void UpdateOmniFrustums() - { - const float sCubeVector[6][7] = - { - {1, 0, 0, 0, 0, 1, -90}, //posx - {-1, 0, 0, 0, 0, 1, 90}, //negx - {0, 1, 0, 0, 0, -1, 0}, //posy - {0, -1, 0, 0, 0, 1, 0}, //negy - {0, 0, 1, 0, 1, 0, 0}, //posz - {0, 0, -1, 0, 1, 0, 0}, //negz - }; - - const Vec3 vPos = vLightSrcRelPos + vProjTranslation; - for (int nS = 0; nS < OMNI_SIDES_NUM; ++nS) - { - const Vec3 vForward = Vec3(sCubeVector[nS][0], sCubeVector[nS][1], sCubeVector[nS][2]); - const Vec3 vUp = Vec3(sCubeVector[nS][3], sCubeVector[nS][4], sCubeVector[nS][5]); - const Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[nS][6])); - const float fov = bUnwrapedOmniDirectional ? (float)DEG2RAD_R(g_fOmniShadowFov) : (float)DEG2RAD_R(90.0f); - - FrustumPlanes[nS].SetMatrix(Matrix34(matRot, vPos)); - FrustumPlanes[nS].SetFrustum(nTexSize, nTexSize, fov, fNearDist, fFarDist); - } - } - - void DrawFrustum(IRenderer* pRend, int nFrames = 1) - { - if (abs(nUpdateFrameId - pRend->GetFrameID()) > nFrames) - { - return; - } - - //if(!arrLightViewMatrix[0] && !arrLightViewMatrix[5] && !arrLightViewMatrix[10]) - //return; - - IRenderAuxGeom* pRendAux = pRend->GetIRenderAuxGeom(); - const ColorF cCascadeColors[] = { Col_Red, Col_Green, Col_Blue, Col_Yellow, Col_Magenta, Col_Cyan, Col_Black, Col_White }; - const uint nColorCount = sizeof(cCascadeColors) / sizeof(cCascadeColors[0]); - - Vec3 vert1, vert2; - ColorB c0 = cCascadeColors[nShadowMapLod % nColorCount]; - { - pRendAux->DrawLine( - UnProjectVertex3d(0, 0, 0, vert1, pRend), c0, - UnProjectVertex3d(0, 0, 1, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(1, 0, 0, vert1, pRend), c0, - UnProjectVertex3d(1, 0, 1, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(1, 1, 0, vert1, pRend), c0, - UnProjectVertex3d(1, 1, 1, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(0, 1, 0, vert1, pRend), c0, - UnProjectVertex3d(0, 1, 1, vert2, pRend), c0); - } - - for (int i = 0; i <= 1; i++) - { - pRendAux->DrawLine( - UnProjectVertex3d(0, 0, i, vert1, pRend), c0, - UnProjectVertex3d(1, 0, i, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(1, 0, i, vert1, pRend), c0, - UnProjectVertex3d(1, 1, i, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(1, 1, i, vert1, pRend), c0, - UnProjectVertex3d(0, 1, i, vert2, pRend), c0); - - pRendAux->DrawLine( - UnProjectVertex3d(0, 1, i, vert1, pRend), c0, - UnProjectVertex3d(0, 0, i, vert2, pRend), c0); - } - } - - void ResetCasterLists() - { - m_castersList.Clear(); - m_jobExecutedCastersList.Clear(); - } - - void GetMemoryUsage(ICrySizer* pSizer) const; -}; - -struct ShadowFrustumMGPUCache - : public ISyncMainWithRenderListener -{ - StaticArray m_pStaticShadowMapFrustums; - ShadowMapFrustum* m_pHeightMapAOFrustum; - - uint32 nUpdateMaskMT; - uint32 nUpdateMaskRT; - - ShadowFrustumMGPUCache() - : nUpdateMaskMT(0) - , nUpdateMaskRT(0) - { - m_pHeightMapAOFrustum = NULL; - m_pStaticShadowMapFrustums.fill(NULL); - }; - - void Init() - { - m_pHeightMapAOFrustum = new ShadowMapFrustum; - m_pHeightMapAOFrustum->pShadowCacheData = new ShadowMapFrustum::ShadowCacheData; - - for (int i = 0; i < m_pStaticShadowMapFrustums.size(); ++i) - { - m_pStaticShadowMapFrustums[i] = new ShadowMapFrustum; - m_pStaticShadowMapFrustums[i]->pShadowCacheData = new ShadowMapFrustum::ShadowCacheData; - } - - nUpdateMaskMT = nUpdateMaskRT = 0; - } - - void Release() - { - SAFE_DELETE(m_pHeightMapAOFrustum); - for (int i = 0; i < m_pStaticShadowMapFrustums.size(); ++i) - { - SAFE_DELETE(m_pStaticShadowMapFrustums[i]); - } - } - - void DeleteFromCache(IShadowCaster* pCaster) - { - for (int i = 0; i < m_pStaticShadowMapFrustums.size(); ++i) - { - ShadowMapFrustum* pFr = m_pStaticShadowMapFrustums[i]; - if (pFr) - { - pFr->m_castersList.Delete(pCaster); - pFr->m_jobExecutedCastersList.Delete(pCaster); - } - } - - if (m_pHeightMapAOFrustum) - { - m_pHeightMapAOFrustum->m_castersList.Delete(pCaster); - m_pHeightMapAOFrustum->m_jobExecutedCastersList.Delete(pCaster); - } - } - - virtual void SyncMainWithRender() - { - /** What we need here is the renderer telling the main thread to update the shadow frustum cache when all GPUs are done - * with the current frustum. - * - * So in case the main thread has done a full update (nUpdateMaskMT has bits for all GPUs set) we need to copy - * the update mask to the renderer. Note that we reset the main thread update mask in the same spot to avoid doing it in - * the next frame again. - * - * Otherwise just copy the renderer's progress back to the main thread. The main thread will automatically do a full update - * when nUpdateMaskMT reaches 0 */ - const int nFullUpdateMask = (1 << gEnv->pRenderer->GetActiveGPUCount()) - 1; - if (nUpdateMaskMT == nFullUpdateMask) - { - nUpdateMaskRT = nUpdateMaskMT; - nUpdateMaskMT = 0xFFFFFFFF; - } - else - { - nUpdateMaskMT = nUpdateMaskRT; - } - } -}; - -#endif diff --git a/Code/CryEngine/RenderDll/Common/TextMessages.cpp b/Code/CryEngine/RenderDll/Common/TextMessages.cpp deleted file mode 100644 index f318636a62..0000000000 --- a/Code/CryEngine/RenderDll/Common/TextMessages.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "TextMessages.h" - -const uint32 g_dwTextMessageMaxSizeInKB = 128; - -void CTextMessages::PushEntry_Text(const Vec3& vPos, const ColorB col, const float fFontSize, const int nDrawFlags, const char* szText) -{ - AUTO_LOCK(m_TextMessageLock); // Not thread safe without this - - assert(szText); - assert(!m_dwCurrentReadPos); // iteration should not be started - - size_t texlen = strlen(szText); - size_t size = sizeof(SText) + texlen + 1; - - if (size > 1020) - { - size = 1020; - texlen = size - sizeof(SText) - 1; - } - - size_t paddedSize = (size + 3) & ~3; - uint8* pData = PushData((uint32) paddedSize); - - if (!pData) - { - return; - } - - memcpy((char*)pData + sizeof(SText), szText, texlen); - pData[sizeof(SText) + texlen] = '\0'; - - SText& rHeader = *(SText*)pData; - - rHeader.Init((uint32) paddedSize); - rHeader.m_vPos = vPos; - rHeader.m_Color = col; - rHeader.m_fFontSize = fFontSize; - rHeader.m_nDrawFlags = nDrawFlags; -} - -void CTextMessages::Clear(bool posonly) -{ - if (!posonly) - { - m_TextMessageData.clear(); - // TODO: ideally we should not reconstruct memory - m_TextMessageData.shrink_to_fit(); - } - - m_dwCurrentReadPos = 0; -} - -const CTextMessages::CTextMessageHeader* CTextMessages::GetNextEntry() -{ - uint32 dwSize = (uint32)m_TextMessageData.size(); - - if (m_dwCurrentReadPos >= dwSize) - { - return 0; // end reached - } - const CTextMessageHeader* pHeader = (const CTextMessageHeader*)&m_TextMessageData[m_dwCurrentReadPos]; - - m_dwCurrentReadPos += pHeader->GetSize(); - - return pHeader; -} - -uint8* CTextMessages::PushData(const uint32 dwBytes) -{ - assert(dwBytes); - assert(dwBytes % 4 == 0); - - uint32 dwSize = (uint32)m_TextMessageData.size(); - - if (dwSize + dwBytes > g_dwTextMessageMaxSizeInKB * 1024) - { - return 0; - } - - m_TextMessageData.resize(dwSize + dwBytes); - - return (uint8*)&m_TextMessageData[dwSize]; -} - -uint32 CTextMessages::ComputeSizeInMemory() const -{ - return (uint32)(sizeof(*this) + m_TextMessageData.size()); -} diff --git a/Code/CryEngine/RenderDll/Common/TextMessages.h b/Code/CryEngine/RenderDll/Common/TextMessages.h deleted file mode 100644 index 69199ffcc8..0000000000 --- a/Code/CryEngine/RenderDll/Common/TextMessages.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _TEXTMESSAGES_H_ -#define _TEXTMESSAGES_H_ - -// compact buffer to store text messages for a frame and render them each frame -// (replacement for the former PodArray m_listMessages[2], cleaner/more cache friendly,less memory,faster,typesafe) -// todo: can release memory in case this is needed -class CTextMessages -{ -public: - CTextMessages() - : m_dwCurrentReadPos() {} - - class CTextMessageHeader; - - // iteration should not be started yet - // Arguments - // vPos - WorldSpace position - // szText - must not be 0 - // nDrawFlags - EDrawTextFlags - void PushEntry_Text(const Vec3& vPos, const ColorB col, const float fFontSize, const int nDrawFlags, const char* szText); - - // usually called every frame - // resets/ends iteration - void Clear(bool posonly = false); - - // todo: improve interface - // starts the iteration - // Returns - // 0 if there are no more entries - const CTextMessageHeader* GetNextEntry(); - - uint32 ComputeSizeInMemory() const; - - // - bool empty() const { return m_TextMessageData.empty(); } - - // ------------------------------------------------------------- - - struct SText; - - class CTextMessageHeader - { - public: - const SText* CastTo_Text() const { return (SText*)this; } - - uint16 GetSize() const { return m_Size; } - - protected: // --------------------------------------------- - uint16 m_Size; // including attached text - }; - - // --------------------------------------------- - - struct SText - : public CTextMessageHeader - { - void Init(const uint32 paddedSize) { assert(paddedSize < 65535); m_Size = paddedSize; } - const char* GetText() const { return (char*)this + sizeof(*this); } - - Vec3 m_vPos; - ColorB m_Color; - float m_fFontSize; - uint32 m_nDrawFlags; // EDrawTextFlags - }; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_TextMessageData); - } -private: // ------------------------------------------------------ - - // each call the former returned pointer might be invalid - // Arguments - // dwBytes >0 and dividable by 4 - // Returns - // 0 if there is not enough space - uint8* PushData(const uint32 dwBytes); - - // ------------------------------------------------------ - - std::vector m_TextMessageData; // consists of many 4 byte aligned STextMessageHeader+ZeroTermintedText - uint32 m_dwCurrentReadPos; // in bytes, !=0 interation started - - CryCriticalSection m_TextMessageLock; -}; - - -#endif // #ifndef _TEXTMESSAGES_H_ diff --git a/Code/CryEngine/RenderDll/Common/Textures/DynTexture.cpp b/Code/CryEngine/RenderDll/Common/Textures/DynTexture.cpp deleted file mode 100644 index 4f2784b1bb..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/DynTexture.cpp +++ /dev/null @@ -1,1741 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Common dynamic texture manager implementation. - - -#include "RenderDll_precompiled.h" - -//====================================================================== -// Dynamic textures -SDynTexture SDynTexture::s_Root("Root"); -uint32 SDynTexture::s_nMemoryOccupied = 0; - -uint32 SDynTexture::s_iNumTextureBytesCheckedOut; -uint32 SDynTexture::s_iNumTextureBytesCheckedIn; - -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_BC1; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_BC1; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R8G8B8A8; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R8G8B8A8; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R32F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R32F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R16G16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R16G16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R8G8B8A8S; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R8G8B8A8S; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R16G16B16A16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R16G16B16A16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R10G10B10A2; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R10G10B10A2; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R11G11B10F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R11G11B10F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R11G11B10F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R11G11B10F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_R8G8S; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_R8G8S; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R8G8S; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R8G8S; - -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2D_Shadows[SBP_MAX]; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2D_Shadows[SBP_MAX]; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_Shadows[SBP_MAX]; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_Shadows[SBP_MAX]; - -SDynTexture::TextureSet SDynTexture::s_availableTexturePool2DCustom_R16G16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePool2DCustom_R16G16F; - -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_BC1; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_BC1; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R8G8B8A8; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R8G8B8A8; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R32F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R32F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R16G16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R16G16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R8G8B8A8S; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R8G8B8A8S; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R16G16B16A16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R16G16B16A16F; -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCube_R10G10B10A2; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCube_R10G10B10A2; - -SDynTexture::TextureSet SDynTexture::s_availableTexturePoolCubeCustom_R16G16F; -SDynTexture::TextureSubset SDynTexture::s_checkedOutTexturePoolCubeCustom_R16G16F; - -int SDynTexture2::s_nMemoryOccupied[eTP_Max]; - -uint32 SDynTexture::s_SuggestedDynTexAtlasCloudsMaxsize; -uint32 SDynTexture::s_SuggestedTexAtlasSize; -uint32 SDynTexture::s_SuggestedDynTexMaxSize; -uint32 SDynTexture::s_CurDynTexAtlasCloudsMaxsize; -uint32 SDynTexture::s_CurTexAtlasSize; -uint32 SDynTexture::s_CurDynTexMaxSize; - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define SDYNTEXTURE_CPP_SECTION_1 1 -#endif - -SDynTexture::SDynTexture(const char* szSource) -{ - m_nWidth = 0; - m_nHeight = 0; - m_nReqWidth = m_nWidth; - m_nReqHeight = m_nHeight; - m_pTexture = NULL; - m_eTF = eTF_Unknown; - m_eTT = eTT_2D; - m_nTexFlags = 0; - cry_strcpy(m_sSource, szSource); - m_bLocked = false; - m_nUpdateMask = 0; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } - - m_Next = NULL; - m_Prev = NULL; - if (!s_Root.m_Next) - { - s_Root.m_Next = &s_Root; - s_Root.m_Prev = &s_Root; - } - AdjustRealSize(); -} - -SDynTexture::SDynTexture(int nWidth, int nHeight, ETEX_Format eTF, ETEX_Type eTT, int nTexFlags, const char* szSource) -{ - m_nWidth = nWidth; - m_nHeight = nHeight; - m_nReqWidth = m_nWidth; - m_nReqHeight = m_nHeight; - m_eTF = eTF; - m_eTT = eTT; - m_nTexFlags = nTexFlags | FT_USAGE_RENDERTARGET; - cry_strcpy(m_sSource, szSource); - m_bLocked = false; - m_nUpdateMask = 0; - m_pFrustumOwner = NULL; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } - - m_pTexture = NULL; - m_Next = NULL; - m_Prev = NULL; - if (!s_Root.m_Next) - { - s_Root.m_Next = &s_Root; - s_Root.m_Prev = &s_Root; - } - Link(); - - AdjustRealSize(); -} - -SDynTexture::~SDynTexture() -{ - if (m_pTexture) - { - ReleaseDynamicRT(false); - } - m_pTexture = NULL; - Unlink(); -} - -int SDynTexture::GetTextureID() -{ - return m_pTexture ? m_pTexture->GetTextureID() : 0; -} - -bool SDynTexture::FreeTextures(bool bOldOnly, int nNeedSpace) -{ - bool bFreed = false; - if (bOldOnly) - { - SDynTexture* pTX = SDynTexture::s_Root.m_Prev; - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID - 400; - while (nNeedSpace + s_nMemoryOccupied > (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - if (pTX == &SDynTexture::s_Root) - { - break; - } - SDynTexture* pNext = pTX->m_Prev; - { - // We cannot unload locked texture or texture used in current frame - // Better to increase pool size temporarily - if (pTX->m_pTexture && !pTX->m_pTexture->IsActiveRenderTarget()) - { - if (pTX->m_pTexture->m_nAccessFrameID < nFrame && pTX->m_pTexture->m_nUpdateFrameID < nFrame && !pTX->m_bLocked) - { - pTX->ReleaseDynamicRT(true); - } - } - } - pTX = pNext; - } - if (nNeedSpace + s_nMemoryOccupied < (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - return true; - } - } - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8 : &s_availableTexturePoolCube_R8G8B8A8, bOldOnly); - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_BC1 : &s_availableTexturePoolCube_BC1, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R32F : &s_availableTexturePoolCube_R32F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16F : &s_availableTexturePoolCube_R16G16F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16B16A16F : &s_availableTexturePoolCube_R16G16B16A16F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R11G11B10F : &s_availableTexturePoolCube_R11G11B10F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8S : &s_availableTexturePoolCube_R8G8S, bOldOnly); - } - - //if (!bFreed && m_eTT==eTT_2D) - //bFreed = FreeAvailableDynamicRT(nNeedSpace, &m_availableTexturePool2D_ATIDF24); - - //First pass - Free textures from the pools with the same texture types - //shadows pools - for (int nPool = SBP_D16; nPool < SBP_MAX; nPool++) - { - if (!bFreed && m_eTT == eTT_2D) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, &s_availableTexturePool2D_Shadows[nPool], bOldOnly); - } - } - for (int nPool = SBP_D16; nPool < SBP_MAX; nPool++) - { - if (!bFreed && m_eTT != eTT_2D) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, &s_availableTexturePoolCube_Shadows[nPool], bOldOnly); - } - } - - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePoolCube_R8G8B8A8 : &s_availableTexturePool2D_R8G8B8A8, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePoolCube_BC1 : &s_availableTexturePool2D_BC1, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePoolCube_R32F : &s_availableTexturePool2D_R32F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePoolCube_R16G16F : &s_availableTexturePool2D_R16G16F, bOldOnly); - } - if (!bFreed) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, m_eTT == eTT_2D ? &s_availableTexturePoolCube_R16G16B16A16F : &s_availableTexturePool2D_R16G16B16A16F, bOldOnly); - } - //if (!bFreed && m_eTT!=eTT_2D) - // bFreed = FreeAvailableDynamicRT(nNeedSpace, &m_availableTexturePool2D_ATIDF24); - - - //Second pass - Free textures from the pools with the different texture types - //shadows pools - for (int nPool = SBP_D16; nPool < SBP_MAX; nPool++) - { - if (!bFreed && m_eTT != eTT_2D) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, &s_availableTexturePool2D_Shadows[nPool], bOldOnly); - } - } - for (int nPool = SBP_D16; nPool < SBP_MAX; nPool++) - { - if (!bFreed && m_eTT == eTT_2D) - { - bFreed = FreeAvailableDynamicRT(nNeedSpace, &s_availableTexturePoolCube_Shadows[nPool], bOldOnly); - } - } - return bFreed; -} - -bool SDynTexture::Update(int nNewWidth, int nNewHeight) -{ - return gRenDev->m_pRT->RC_DynTexUpdate(this, nNewWidth, nNewHeight); -} - -void SDynTexture::AdjustRealSize() -{ - m_nWidth = m_nReqWidth; - m_nHeight = m_nReqHeight; -} - -void SDynTexture::GetImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight) -{ - nX = 0; - nY = 0; - nWidth = m_nWidth; - nHeight = m_nHeight; -} - -void SDynTexture::Apply(int nTUnit, int nTS) -{ - if (!m_pTexture) - { - Update(m_nWidth, m_nHeight); - } - if (m_pTexture) - { - m_pTexture->Apply(nTUnit, nTS); - } - gRenDev->m_cEF.m_RTRect.x = 0; - gRenDev->m_cEF.m_RTRect.y = 0; - gRenDev->m_cEF.m_RTRect.z = 1; - gRenDev->m_cEF.m_RTRect.w = 1; -} - -void SDynTexture::ShutDown() -{ - SDynTexture* pTX, * pTXNext; - for (pTX = SDynTexture::s_Root.m_Next; pTX != &SDynTexture::s_Root; pTX = pTXNext) - { - pTXNext = pTX->m_Next; - SAFE_RELEASE_FORCE(pTX); - } - SDynTexture Tex("Release"); - Tex.m_eTT = eTT_2D; - Tex.FreeTextures(false, 1024 * 1024 * 1024); - - Tex.m_eTT = eTT_Cube; - Tex.FreeTextures(false, 1024 * 1024 * 1024); -} - -bool SDynTexture::FreeAvailableDynamicRT(int nNeedSpace, TextureSet* pSet, bool bOldOnly) -{ - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - int nSpace = s_nMemoryOccupied; - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID - 400; - while (nNeedSpace + nSpace > (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - TextureSetItor itor = pSet->begin(); - while (itor != pSet->end()) - { - TextureSubset* pSubset = itor->second; - TextureSubsetItor itorss = pSubset->begin(); - while (itorss != pSubset->end()) - { - CTexture* pTex = itorss->second; - PREFAST_ASSUME(pTex); - if (!bOldOnly || (pTex->m_nAccessFrameID < nFrame && pTex->m_nUpdateFrameID < nFrame)) - { - itorss->second = NULL; - pSubset->erase(itorss); - itorss = pSubset->begin(); - nSpace -= pTex->GetDataSize(); - s_iNumTextureBytesCheckedIn -= pTex->GetDataSize(); - SAFE_RELEASE(pTex); - if (nNeedSpace + nSpace < (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - break; - } - } - else - { - itorss++; - } - } - if (pSubset->size() == 0) - { - delete pSubset; - pSet->erase(itor); - itor = pSet->begin(); - } - else - { - itor++; - } - if (nNeedSpace + nSpace < (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - break; - } - } - if (itor == pSet->end()) - { - break; - } - } - s_nMemoryOccupied = nSpace; - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - if (nNeedSpace + nSpace > (int)SDynTexture::s_CurDynTexMaxSize * 1024 * 1024) - { - return false; - } - return true; -} - -void SDynTexture::ReleaseDynamicRT(bool bForce) -{ - if (!m_pTexture) - { - return; - } - m_nUpdateMask = 0; - - // first see if the texture is in the checked out pool. - TextureSubset* pSubset; - if (m_eTF == eTF_R8G8B8A8) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8 : &s_checkedOutTexturePoolCube_R8G8B8A8; - } - else - if (m_eTF == eTF_BC1) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_BC1 : &s_checkedOutTexturePoolCube_BC1; - } - else - if (m_eTF == eTF_R32F) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R32F : &s_checkedOutTexturePoolCube_R32F; - } - else - if (m_eTF == eTF_R16F) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16F : &s_checkedOutTexturePoolCube_R16F; - } - else - if (m_eTF == eTF_R16G16F) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16F : &s_checkedOutTexturePoolCube_R16G16F; - } - else - if (m_eTF == eTF_R8G8B8A8S) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8S : &s_checkedOutTexturePoolCube_R8G8B8A8S; - } - else - if (m_eTF == eTF_R16G16B16A16F) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16B16A16F : &s_checkedOutTexturePoolCube_R16G16B16A16F; - } - else -#if defined(WIN32) || defined(APPLE) || defined(LINUX) || defined(SUPPORTS_DEFERRED_SHADING_L_BUFFERS_FORMAT) - if (m_eTF == eTF_R11G11B10F) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R11G11B10F : &s_checkedOutTexturePoolCube_R11G11B10F; - } - else -#endif - if (m_eTF == eTF_R8G8S) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8S : &s_checkedOutTexturePoolCube_R8G8S; - } - else - if (m_eTF == eTF_R10G10B10A2) - { - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R10G10B10A2 : &s_checkedOutTexturePoolCube_R10G10B10A2; - } - else - if (ConvertTexFormatToShadowsPool(m_eTF) != SBP_UNKNOWN) - { - if (m_eTT == eTT_2D) - { - pSubset = &s_checkedOutTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else if (m_eTT == eTT_Cube) - { - pSubset = &s_checkedOutTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else - { - pSubset = NULL; - assert(0); - } - } - else - { - pSubset = NULL; - assert(0); - } - - PREFAST_ASSUME(pSubset); - - TextureSubsetItor coTexture = pSubset->find(m_pTexture->GetID()); - if (coTexture != pSubset->end()) - { // if it is there, remove it. - pSubset->erase(coTexture); - s_iNumTextureBytesCheckedOut -= m_pTexture->GetDataSize(); - } - - // Don't cache too many unused textures. - if (bForce) - { - s_nMemoryOccupied -= m_pTexture->GetDataSize(); - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); -#ifndef NDEBUG - int refCount = -#endif - m_pTexture->Release(); - assert(refCount <= 0); - m_pTexture = NULL; - Unlink(); - return; - } - - TextureSet* pSet; - if (m_eTF == eTF_R8G8B8A8) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8 : &s_availableTexturePoolCube_R8G8B8A8; - } - else - if (m_eTF == eTF_BC1) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_BC1 : &s_availableTexturePoolCube_BC1; - } - else - if (m_eTF == eTF_R32F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R32F : &s_availableTexturePoolCube_R32F; - } - else - if (m_eTF == eTF_R16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16F : &s_availableTexturePoolCube_R16F; - } - else - if (m_eTF == eTF_R16G16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16F : &s_availableTexturePoolCube_R16G16F; - } - else - if (m_eTF == eTF_R8G8B8A8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8S : &s_availableTexturePoolCube_R8G8B8A8S; - } - else - if (m_eTF == eTF_R16G16B16A16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16B16A16F : &s_availableTexturePoolCube_R16G16B16A16F; - } - else - if (m_eTF == eTF_R11G11B10F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R11G11B10F : &s_availableTexturePoolCube_R11G11B10F; - } - else - if (m_eTF == eTF_R8G8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8S : &s_availableTexturePoolCube_R8G8S; - } - else - if (m_eTF == eTF_R10G10B10A2) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R10G10B10A2 : &s_availableTexturePoolCube_R10G10B10A2; - } - else - if (ConvertTexFormatToShadowsPool(m_eTF) != SBP_UNKNOWN) - { - if (m_eTT == eTT_2D) - { - pSet = &s_availableTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else if (m_eTT == eTT_Cube) - { - pSet = &s_availableTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else - { - pSet = NULL; - assert(0); - } - } - else - { - pSet = NULL; - assert(0); - } - - PREFAST_ASSUME(pSet); - - TextureSetItor subset = pSet->find(m_nWidth); - if (subset != pSet->end()) - { - subset->second->insert(TextureSubset::value_type(m_nHeight, m_pTexture)); - s_iNumTextureBytesCheckedIn += m_pTexture->GetDataSize(); - } - else - { - pSubset = new TextureSubset; - pSet->insert(TextureSet::value_type(m_nWidth, pSubset)); - pSubset->insert(TextureSubset::value_type(m_nHeight, m_pTexture)); - s_iNumTextureBytesCheckedIn += m_pTexture->GetDataSize(); - } - m_pTexture = NULL; - Unlink(); -} - -CTexture* SDynTexture::GetDynamicRT() -{ - TextureSet* pSet; - TextureSubset* pSubset; - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - if (m_eTF == eTF_R8G8B8A8) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8 : &s_availableTexturePoolCube_R8G8B8A8; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8 : &s_checkedOutTexturePoolCube_R8G8B8A8; - } - else - if (m_eTF == eTF_BC1) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_BC1 : &s_availableTexturePoolCube_BC1; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_BC1 : &s_checkedOutTexturePoolCube_BC1; - } - else - if (m_eTF == eTF_R32F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R32F : &s_availableTexturePoolCube_R32F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R32F : &s_checkedOutTexturePoolCube_R32F; - } - else - if (m_eTF == eTF_R16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16F : &s_availableTexturePoolCube_R16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16F : &s_checkedOutTexturePoolCube_R16F; - } - else - if (m_eTF == eTF_R16G16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16F : &s_availableTexturePoolCube_R16G16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16F : &s_checkedOutTexturePoolCube_R16G16F; - } - else - if (m_eTF == eTF_R8G8B8A8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8S : &s_availableTexturePoolCube_R8G8B8A8S; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8S : &s_checkedOutTexturePoolCube_R8G8B8A8S; - } - else - if (m_eTF == eTF_R16G16B16A16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16B16A16F : &s_availableTexturePoolCube_R16G16B16A16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16B16A16F : &s_checkedOutTexturePoolCube_R16G16B16A16F; - } - else - if (m_eTF == eTF_R11G11B10F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R11G11B10F : &s_availableTexturePoolCube_R11G11B10F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R11G11B10F : &s_checkedOutTexturePoolCube_R11G11B10F; - } - else - if (m_eTF == eTF_R8G8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8S : &s_availableTexturePoolCube_R8G8S; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8S : &s_checkedOutTexturePoolCube_R8G8S; - } - else - if (m_eTF == eTF_R10G10B10A2) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R10G10B10A2 : &s_availableTexturePoolCube_R10G10B10A2; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R10G10B10A2 : &s_checkedOutTexturePoolCube_R10G10B10A2; - } - else - if (ConvertTexFormatToShadowsPool(m_eTF) != SBP_UNKNOWN) - { - if (m_eTT == eTT_2D) - { - pSet = &s_availableTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - pSubset = &s_checkedOutTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else if (m_eTT == eTT_Cube) - { - pSet = &s_availableTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - pSubset = &s_checkedOutTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else - { - pSet = NULL; - pSubset = NULL; - assert(0); - } - } - else - { - pSet = NULL; - pSubset = NULL; - assert(0); - } - - PREFAST_ASSUME(pSet); - - TextureSetItor subset = pSet->find(m_nWidth); - if (subset != pSet->end()) - { - TextureSubsetItor texture = subset->second->find(m_nHeight); - if (texture != subset->second->end()) - { // found one! - // extract the texture - CTexture* pTexture = texture->second; - texture->second = NULL; - // first remove it from this set. - subset->second->erase(texture); - // now add it to the checked out texture set. - pSubset->insert(TextureSubset::value_type(pTexture->GetID(), pTexture)); - s_iNumTextureBytesCheckedOut += pTexture->GetDataSize(); - s_iNumTextureBytesCheckedIn -= pTexture->GetDataSize(); - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - return pTexture; - } - } - return NULL; -} - -CTexture* SDynTexture::CreateDynamicRT() -{ - //assert(m_eTF == eTF_A8R8G8B8 && m_eTT == eTT_2D); - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - char name[256]; - CTexture* pTexture = GetDynamicRT(); - if (pTexture) - { - return pTexture; - } - - TextureSet* pSet; - TextureSubset* pSubset; - if (m_eTF == eTF_R8G8B8A8) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8 : &s_availableTexturePoolCube_R8G8B8A8; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8 : &s_checkedOutTexturePoolCube_R8G8B8A8; - } - else - if (m_eTF == eTF_BC1) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_BC1 : &s_availableTexturePoolCube_BC1; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_BC1 : &s_checkedOutTexturePoolCube_BC1; - } - else - if (m_eTF == eTF_R32F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R32F : &s_availableTexturePoolCube_R32F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R32F : &s_checkedOutTexturePoolCube_R32F; - } - else - if (m_eTF == eTF_R16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16F : &s_availableTexturePoolCube_R16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16F : &s_checkedOutTexturePoolCube_R16F; - } - else - if (m_eTF == eTF_R16G16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16F : &s_availableTexturePoolCube_R16G16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16F : &s_checkedOutTexturePoolCube_R16G16F; - } - else - if (m_eTF == eTF_R8G8B8A8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8B8A8S : &s_availableTexturePoolCube_R8G8B8A8S; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8B8A8S : &s_checkedOutTexturePoolCube_R8G8B8A8S; - } - else - if (m_eTF == eTF_R16G16B16A16F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R16G16B16A16F : &s_availableTexturePoolCube_R16G16B16A16F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R16G16B16A16F : &s_checkedOutTexturePoolCube_R16G16B16A16F; - } - else - if (m_eTF == eTF_R11G11B10F) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R11G11B10F : &s_availableTexturePoolCube_R11G11B10F; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R11G11B10F : &s_checkedOutTexturePoolCube_R11G11B10F; - } - else - if (m_eTF == eTF_R8G8S) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R8G8S : &s_availableTexturePoolCube_R8G8S; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R8G8S : &s_checkedOutTexturePoolCube_R8G8S; - } - else - if (m_eTF == eTF_R10G10B10A2) - { - pSet = m_eTT == eTT_2D ? &s_availableTexturePool2D_R10G10B10A2 : &s_availableTexturePoolCube_R10G10B10A2; - pSubset = m_eTT == eTT_2D ? &s_checkedOutTexturePool2D_R10G10B10A2 : &s_checkedOutTexturePoolCube_R10G10B10A2; - } - else - if (ConvertTexFormatToShadowsPool(m_eTF) != SBP_UNKNOWN) - { - if (m_eTT == eTT_2D) - { - pSet = &s_availableTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - pSubset = &s_checkedOutTexturePool2D_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else if (m_eTT == eTT_Cube) - { - pSet = &s_availableTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - pSubset = &s_checkedOutTexturePoolCube_Shadows[ConvertTexFormatToShadowsPool(m_eTF)]; - } - else - { - pSet = NULL; - pSubset = NULL; - assert(0); - } - } - else - { - pSet = NULL; - pSubset = NULL; - assert(0); - } - - if (m_eTT == eTT_2D) - { - sprintf_s(name, "$Dyn_%s_2D_%s_%d", m_sSource, CTexture::NameForTextureFormat(m_eTF), gRenDev->m_TexGenID++); - } - else - { - sprintf_s(name, "$Dyn_%s_Cube_%s_%d", m_sSource, CTexture::NameForTextureFormat(m_eTF), gRenDev->m_TexGenID++); - } - - PREFAST_ASSUME(pSet); - - TextureSetItor subset = pSet->find(m_nWidth); - if (subset != pSet->end()) - { - CTexture* pNewTexture = CTexture::CreateRenderTarget(name, m_nWidth, m_nHeight, Clr_Unknown, m_eTT, m_nTexFlags, m_eTF); - pSubset->insert(TextureSubset::value_type(pNewTexture->GetID(), pNewTexture)); - s_nMemoryOccupied += pNewTexture->GetDataSize(); - s_iNumTextureBytesCheckedOut += pNewTexture->GetDataSize(); - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - return pNewTexture; - } - else - { - TextureSubset* pSSet = new TextureSubset; - pSet->insert(TextureSet::value_type(m_nWidth, pSSet)); - CTexture* pNewTexture = CTexture::CreateRenderTarget(name, m_nWidth, m_nHeight, Clr_Unknown, m_eTT, m_nTexFlags, m_eTF); -#ifndef CRY_USE_METAL - pNewTexture->Clear(ColorF(0.0f, 0.0f, 0.0f, 1.0f)); -#endif - pSubset->insert(TextureSubset::value_type(pNewTexture->GetID(), pNewTexture)); - s_nMemoryOccupied += pNewTexture->GetDataSize(); - s_iNumTextureBytesCheckedOut += pNewTexture->GetDataSize(); - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - return pNewTexture; - } -} - -void SDynTexture::ResetUpdateMask() -{ - m_nUpdateMask = 0; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } -} - -void SDynTexture::SetUpdateMask() -{ - int nFrame = gRenDev->RT_GetCurrGpuID(); - m_nUpdateMask |= 1 << nFrame; -} - -void SDynTexture::ReleaseForce() -{ - ReleaseDynamicRT(true); - delete this; -} - -bool SDynTexture::IsValid() -{ - if (!m_pTexture) - { - return false; - } - if (m_nFrameReset != gRenDev->m_nFrameReset) - { - m_nFrameReset = gRenDev->m_nFrameReset; - m_nUpdateMask = 0; - return false; - } - if (gRenDev->GetActiveGPUCount() > 1) - { - if ((gRenDev->GetFeatures() & RFT_HW_MASK) == RFT_HW_ATI) - { - uint32 nX, nY, nW, nH; - GetImageRect(nX, nY, nW, nH); - if (nW < 1024 && nH < 1024) - { - return true; - } - } - - int nFrame = gRenDev->RT_GetCurrGpuID(); - if (!((1 << nFrame) & m_nUpdateMask)) - { - return false; - } - } - return true; -} - -void SDynTexture::Tick() -{ - if (s_SuggestedDynTexMaxSize != CRenderer::CV_r_dyntexmaxsize || - s_SuggestedDynTexAtlasCloudsMaxsize != CRenderer::CV_r_dyntexatlascloudsmaxsize || - s_SuggestedTexAtlasSize != CRenderer::CV_r_texatlassize) - { - Init(); - } -} - -void SDynTexture::Init() -{ - s_SuggestedDynTexAtlasCloudsMaxsize = CRenderer::CV_r_dyntexatlascloudsmaxsize; - s_SuggestedTexAtlasSize = CRenderer::CV_r_texatlassize; - s_SuggestedDynTexMaxSize = CRenderer::CV_r_dyntexmaxsize; - - s_CurDynTexAtlasCloudsMaxsize = s_SuggestedDynTexAtlasCloudsMaxsize; - s_CurTexAtlasSize = s_SuggestedTexAtlasSize; - s_CurDynTexMaxSize = s_SuggestedDynTexMaxSize; -} - -EShadowBuffers_Pool SDynTexture::ConvertTexFormatToShadowsPool(ETEX_Format e) -{ - switch (e) - { - case (eTF_D16): - return SBP_D16; - case (eTF_D24S8): - return SBP_D24S8; - case (eTF_D32F): - case (eTF_D32FS8): - return SBP_D32FS8; - case (eTF_R16G16): - return SBP_R16G16; - - default: - break; - } - //assert( false ); - return SBP_UNKNOWN; -} - - -int SDynTexture2::GetTextureID() -{ - return m_pTexture ? m_pTexture->GetTextureID() : 0; -} - -void SDynTexture2::GetImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight) -{ - nX = 0; - nY = 0; - if (m_pTexture) - { - if (m_pTexture->GetWidth() != SDynTexture::s_CurTexAtlasSize || m_pTexture->GetHeight() != SDynTexture::s_CurTexAtlasSize) - { - UpdateAtlasSize(SDynTexture::s_CurTexAtlasSize, SDynTexture::s_CurTexAtlasSize); - } - assert (m_pTexture->GetWidth() == SDynTexture::s_CurTexAtlasSize || m_pTexture->GetHeight() == SDynTexture::s_CurTexAtlasSize); - } - nWidth = SDynTexture::s_CurTexAtlasSize; - nHeight = SDynTexture::s_CurTexAtlasSize; -} - -//==================================================================================== - -SDynTexture_Shadow SDynTexture_Shadow::s_RootShadow("RootShadow"); - -SDynTexture_Shadow::SDynTexture_Shadow(const char* szSource) - : SDynTexture(szSource) -{ - m_nUniqueID = 0; - m_NextShadow = NULL; - m_PrevShadow = NULL; - if (!s_RootShadow.m_NextShadow) - { - s_RootShadow.m_NextShadow = &s_RootShadow; - s_RootShadow.m_PrevShadow = &s_RootShadow; - } - if (this != &s_RootShadow) - { - LinkShadow(&s_RootShadow); - } -} - -SDynTexture_Shadow::SDynTexture_Shadow(int nWidth, int nHeight, ETEX_Format eTF, ETEX_Type eTT, int nTexFlags, const char* szSource) - : SDynTexture(nWidth, nHeight, eTF, eTT, nTexFlags, szSource) -{ - m_nWidth = nWidth; - m_nHeight = nHeight; - - if (gRenDev) - { - m_nUniqueID = gRenDev->m_TexGenID++; - } - else - { - m_nUniqueID = 0; - } - - m_NextShadow = NULL; - m_PrevShadow = NULL; - if (!s_RootShadow.m_NextShadow) - { - s_RootShadow.m_NextShadow = &s_RootShadow; - s_RootShadow.m_PrevShadow = &s_RootShadow; - } - if (this != &s_RootShadow) - { - LinkShadow(&s_RootShadow); - } -} - -void SDynTexture_Shadow::AdjustRealSize() -{ - if (m_eTT == eTT_2D) - { - if (m_nWidth < 256) - { - m_nWidth = 256; - } - else - if (m_nWidth > 2048) - { - m_nWidth = 2048; - } - m_nHeight = m_nWidth; - } - if (m_eTT == eTT_Cube) - { - if (m_nWidth < 256) - { - m_nWidth = 256; - } - else - if (m_nWidth > 512) - { - m_nWidth = 512; - } - m_nHeight = m_nWidth; - } -} - -SDynTexture_Shadow::~SDynTexture_Shadow() -{ - UnlinkShadow(); -} - -void SDynTexture_Shadow::RT_EntityDelete(IRenderNode* pRenderNode) -{ - // remove references to the entity - SDynTexture_Shadow* pTX, * pNext; - for (pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; pTX != &SDynTexture_Shadow::s_RootShadow; pTX = pNext) - { - pNext = pTX->m_NextShadow; - if (pTX->pLightOwner == pRenderNode) - { - delete pTX; - } - } -} - -void SDynTexture_Shadow::ShutDown() -{ - SDynTexture_Shadow* pTX, * pNext; - for (pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; pTX != &SDynTexture_Shadow::s_RootShadow; pTX = pNext) - { - pNext = pTX->m_NextShadow; - delete pTX; - } -} - -SDynTexture_Shadow* SDynTexture_Shadow::GetForFrustum(ShadowMapFrustum* pFrustum) -{ - SDynTexture_Shadow* pDynTX = NULL; - - for (SDynTexture_Shadow* pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; pTX != &SDynTexture_Shadow::s_RootShadow; pTX = pTX->m_NextShadow) - { - if (pTX->m_pFrustumOwner == pFrustum->pFrustumOwner) - { - pDynTX = pTX; - break; - } - } - - if (pDynTX) - { - if (pDynTX->m_eTF != pFrustum->m_eReqTF || pDynTX->m_eTT != pFrustum->m_eReqTT || pDynTX->pLightOwner != pFrustum->pLightOwner || - pDynTX->m_nReqWidth != pFrustum->nTextureWidth || pDynTX->m_nReqHeight != pFrustum->nTextureHeight) - { - SAFE_DELETE(pDynTX); - - //force all cubemap faces update - pFrustum->RequestUpdate(); - } - } - - //check after freeing texture - if (!pDynTX) - { - uint32_t flags = FT_USAGE_DEPTHSTENCIL | FT_STATE_CLAMP | FT_DONT_STREAM | FT_USE_HTILE; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SDYNTEXTURE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DynTexture_cpp) -#endif - pDynTX = new SDynTexture_Shadow(pFrustum->nTextureWidth, pFrustum->nTextureHeight, pFrustum->m_eReqTF, pFrustum->m_eReqTT, flags, "ShadowRT"); - CRY_ASSERT(pFrustum->nTextureWidth == pDynTX->m_nWidth && pFrustum->nTextureHeight == pDynTX->m_nHeight); - } - - pDynTX->RT_Update(pFrustum->nTextureWidth, pFrustum->nTextureHeight); - pDynTX->pLightOwner = pFrustum->pLightOwner; - pDynTX->m_pFrustumOwner = pFrustum->pFrustumOwner; - - return pDynTX; -} -//==================================================================================== - -AZStd::unique_ptr SDynTexture2::s_TexturePool[eTP_Max]; - -SDynTexture2::SDynTexture2(const char* szSource, ETexPool eTexPool) -{ - m_nWidth = 0; - m_nHeight = 0; - - m_pOwner = NULL; - -#ifndef _DEBUG - m_sSource = (char*)szSource; -#else - azstrcpy(m_sSource, strlen(szSource) + 1, szSource); -#endif - m_bLocked = false; - - m_eTexPool = eTexPool; - - m_nBlockID = ~0; - m_pAllocator = NULL; - m_Next = NULL; - m_PrevLink = NULL; - m_nUpdateMask = 0; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } - SetUpdateMask(); - - m_nFlags = 0; -} - -void SDynTexture2::SetUpdateMask() -{ - if (gRenDev) - { - int nFrame = gRenDev->RT_GetCurrGpuID(); - m_nUpdateMask |= 1 << nFrame; - } -} - -void SDynTexture2::ResetUpdateMask() -{ - m_nUpdateMask = 0; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } -} - -SDynTexture2::SDynTexture2(uint32 nWidth, uint32 nHeight, [[maybe_unused]] uint32 nTexFlags, const char* szSource, ETexPool eTexPool) -{ - m_nWidth = nWidth; - m_nHeight = nHeight; - - m_eTexPool = eTexPool; - - ETEX_Format eTF = GetPoolTexFormat(eTexPool); - - TextureSet2Itor tset = s_TexturePool[eTexPool]->find(eTF); - if (tset == s_TexturePool[eTexPool]->end()) - { - m_pOwner = new STextureSetFormat(eTF, eTexPool, FT_NOMIPS | FT_USAGE_ATLAS); - s_TexturePool[eTexPool]->insert(TextureSet2::value_type(eTF, m_pOwner)); - } - else - { - m_pOwner = tset->second; - } - - m_Next = NULL; - m_PrevLink = NULL; - m_bLocked = false; - -#ifndef _DEBUG - m_sSource = (char*)szSource; -#else - azstrcpy(m_sSource, strlen(szSource) + 1, szSource); -#endif - - m_pTexture = NULL; - m_nBlockID = ~0; - m_pAllocator = NULL; - m_nUpdateMask = 0; - if (gRenDev) - { - m_nFrameReset = gRenDev->m_nFrameReset; - } - SetUpdateMask(); - m_nFlags = 0; -} - -SDynTexture2::~SDynTexture2() -{ - Remove(); - m_bLocked = false; -} - -int SDynTexture2::GetPoolMaxSize(ETexPool eTexPool) -{ - if (eTexPool == eTP_Clouds) - { - return SDynTexture::s_SuggestedDynTexAtlasCloudsMaxsize; - } - assert(0); - return 0; -} -void SDynTexture2::SetPoolMaxSize(ETexPool eTexPool, int nSize, bool bWarn) -{ - if (eTexPool == eTP_Clouds) - { - if (bWarn) - { - Warning("Increasing maximum Clouds atlas pool to %d Mb", nSize); - } - SDynTexture::s_SuggestedDynTexAtlasCloudsMaxsize = nSize; - } - else - { - assert(0); - } -} - -const char* SDynTexture2::GetPoolName(ETexPool eTexPool) -{ - if (eTexPool == eTP_Clouds) - { - return "Clouds"; - } - - assert(0); - return 0; -} - -ETEX_Format SDynTexture2::GetPoolTexFormat(ETexPool eTexPool) -{ - if (eTexPool == eTP_Clouds) - { - return eTF_R8G8B8A8; - } - - assert(0); - return eTF_R8G8B8A8; -} - -void SDynTexture2::Init(ETexPool eTexPool) -{ - if (!s_TexturePool[eTexPool]) - { - s_TexturePool[eTexPool] = AZStd::make_unique(); - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texpreallocateatlases) - { - int nSize = CRenderer::CV_r_texatlassize; - TArray Texs; - int nMaxSize = GetPoolMaxSize(eTexPool); - const char* szName = GetPoolName(eTexPool); - nMaxSize *= 1024 * 1024; - while (true) - { - ETEX_Format eTF = GetPoolTexFormat(eTexPool); - int nNeedSpace = CTexture::TextureDataSize(nSize, nSize, 1, 1, 1, eTF); - if (nNeedSpace + s_nMemoryOccupied[eTexPool] > nMaxSize) - { - break; - } - SDynTexture2* pTex = new SDynTexture2(nSize, nSize, FT_STATE_CLAMP | FT_NOMIPS, szName, eTexPool); - pTex->Update(nSize, nSize); - Texs.AddElem(pTex); - } - for (uint32 i = 0; i < Texs.Num(); i++) - { - SDynTexture2* pTex = Texs[i]; - SAFE_DELETE(pTex); - } - } -} - -bool SDynTexture2::UpdateAtlasSize(int nNewWidth, int nNewHeight) -{ - if (!m_pOwner) - { - return false; - } - if (!m_pTexture) - { - return false; - } - if (!m_pAllocator) - { - return false; - } - if (m_pTexture->GetWidth() != nNewWidth || m_pTexture->GetHeight() != nNewHeight) - { - SDynTexture2* pDT, * pNext; - for (pDT = m_pOwner->m_pRoot; pDT; pDT = pNext) - { - pNext = pDT->m_Next; - if (pDT == this) - { - continue; - } - assert(!pDT->m_bLocked); - pDT->Remove(); - pDT->SetUpdateMask(); - } - int nBlockW = (m_nWidth + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - int nBlockH = (m_nHeight + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - m_pAllocator->RemoveBlock(m_nBlockID); - assert (m_pAllocator && m_pAllocator->GetNumUsedBlocks() == 0); - - int nW = (nNewWidth + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - int nH = (nNewHeight + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - m_pAllocator->UpdateSize(nW, nH); - m_nBlockID = m_pAllocator->AddBlock(nBlockW, nBlockH); - s_nMemoryOccupied[m_eTexPool] -= CTexture::TextureDataSize(m_pTexture->GetWidth(), m_pTexture->GetHeight(), 1, 1, 1, m_pOwner->m_eTF); - SAFE_RELEASE(m_pTexture); - - char name[256]; - sprintf_s(name, "$Dyn_2D_%s_%s_%d", CTexture::NameForTextureFormat(m_pOwner->m_eTF), GetPoolName(m_eTexPool), gRenDev->m_TexGenID++); - m_pAllocator->m_pTexture = CTexture::CreateRenderTarget(name, nNewWidth, nNewHeight, Clr_Transparent, m_pOwner->m_eTT, m_pOwner->m_nTexFlags, m_pOwner->m_eTF); - s_nMemoryOccupied[m_eTexPool] += CTexture::TextureDataSize(nNewWidth, nNewHeight, 1, 1, 1, m_pOwner->m_eTF); - m_pTexture = m_pAllocator->m_pTexture; - } - return true; -} - -bool SDynTexture2::Update(int nNewWidth, int nNewHeight) -{ - int i; - if (!m_pOwner) - { - return false; - } - bool bRecreate = false; - if (!m_pAllocator) - { - bRecreate = true; - } - int nStage = -1; - m_nAccessFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - SDynTexture2* pDT = NULL; - - if (m_nWidth != nNewWidth || m_nHeight != nNewHeight) - { - bRecreate = true; - m_nWidth = nNewWidth; - m_nHeight = nNewHeight; - } - uint32 nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - if (bRecreate) - { - int nSize = CRenderer::CV_r_texatlassize; - if (nSize <= 512) - { - nSize = 512; - } - else - if (nSize <= 1024) - { - nSize = 1024; - } - else - if (nSize > 2048) - { - nSize = 2048; - } - CRenderer::CV_r_texatlassize = nSize; - int nMaxSize = GetPoolMaxSize(m_eTexPool); - int nNeedSpace = CTexture::TextureDataSize(nSize, nSize, 1, 1, 1, m_pOwner->m_eTF); - if (nNeedSpace > nMaxSize * 1024 * 1024) - { - SetPoolMaxSize(m_eTexPool, nNeedSpace / (1024 * 1024), true); - } - - int nBlockW = (nNewWidth + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - int nBlockH = (nNewHeight + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - Remove(); - SetUpdateMask(); - - uint32 nID = ~0; - CPowerOf2BlockPacker* pPack = NULL; - for (i = 0; i < (int)m_pOwner->m_TexPools.size(); i++) - { - pPack = m_pOwner->m_TexPools[i]; - nID = pPack->AddBlock(LogBaseTwo(nBlockW), LogBaseTwo(nBlockH)); - if (nID != -1) - { - break; - } - } - if (i == m_pOwner->m_TexPools.size()) - { - nStage = 1; - nMaxSize = GetPoolMaxSize(m_eTexPool); - if (nNeedSpace + s_nMemoryOccupied[m_eTexPool] > nMaxSize * 1024 * 1024) - { - SDynTexture2* pDTBest = NULL; - SDynTexture2* pDTBestLarge = NULL; - int nError = 1000000; - uint32 nFr = INT_MAX; - uint32 nFrLarge = INT_MAX; - int n = 0; - for (pDT = m_pOwner->m_pRoot; pDT; pDT = pDT->m_Next) - { - if (pDT == this || pDT->m_bLocked) - { - continue; - } - n++; - assert (pDT->m_pAllocator && pDT->m_pTexture && pDT->m_nBlockID != -1); - if (pDT->m_nWidth == m_nWidth && pDT->m_nHeight == m_nHeight) - { - if (nFr > pDT->m_nAccessFrame) - { - nFr = pDT->m_nAccessFrame; - pDTBest = pDT; - } - } - else - if (pDT->m_nWidth >= m_nWidth && pDT->m_nHeight >= m_nHeight) - { - int nEr = pDT->m_nWidth - m_nWidth + pDT->m_nHeight - m_nHeight; - int fEr = nEr + (nFrame - pDT->m_nAccessFrame); - - if (fEr < nError) - { - nFrLarge = pDT->m_nAccessFrame; - nError = fEr; - pDTBestLarge = pDT; - } - } - } - pDT = NULL; - if (pDTBest && nFr + 1 < nFrame && pDTBest->m_nBlockID != -1) - { - nStage = 2; - pDT = pDTBest; - nID = pDT->m_nBlockID; - pPack = pDT->m_pAllocator; - pDT->m_pAllocator = NULL; - pDT->m_pTexture = NULL; - pDT->m_nBlockID = ~0; - pDT->m_nUpdateMask = 0; - pDT->SetUpdateMask(); - pDT->Unlink(); - } - else - if (pDTBestLarge && nFrLarge + 1 < nFrame) - { - nStage = 3; - pDT = pDTBestLarge; - CPowerOf2BlockPacker* pAllocator = pDT->m_pAllocator; - pDT->Remove(); - pDT->SetUpdateMask(); - nID = pAllocator->AddBlock(LogBaseTwo(nBlockW), LogBaseTwo(nBlockH)); - assert (nID != -1); - if (nID != -1) - { - pPack = pAllocator; - } - else - { - pDT = NULL; - } - } - if (!pDT) - { - nStage = 4; - // Try to find oldest texture pool - float fTime = FLT_MAX; - CPowerOf2BlockPacker* pPackBest = NULL; - for (i = 0; i < (int)m_pOwner->m_TexPools.size(); i++) - { - CPowerOf2BlockPacker* pNextPack = m_pOwner->m_TexPools[i]; - if (fTime > pNextPack->m_fLastUsed) - { - fTime = pNextPack->m_fLastUsed; - pPackBest = pNextPack; - } - } - if (!pPackBest || fTime + 0.5f > gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime) - { - nStage = 5; - // Try to find most fragmented texture pool with less number of blocks - uint32 nUsedBlocks = TEX_POOL_BLOCKSIZE * TEX_POOL_BLOCKSIZE + 1; - pPackBest = NULL; - for (i = 0; i < (int)m_pOwner->m_TexPools.size(); i++) - { - CPowerOf2BlockPacker* pNextPack = m_pOwner->m_TexPools[i]; - int nBlocks = pNextPack->GetNumUsedBlocks(); - if (nBlocks < (int)nUsedBlocks) - { - nUsedBlocks = nBlocks; - pPackBest = pNextPack; - } - } - } - if (pPackBest) - { - SDynTexture2* pNext = NULL; - for (pDT = m_pOwner->m_pRoot; pDT; pDT = pNext) - { - pNext = pDT->m_Next; - if (pDT == this || pDT->m_bLocked) - { - continue; - } - if (pDT->m_pAllocator == pPackBest) - { - pDT->Remove(); - } - } - assert (pPackBest->GetNumUsedBlocks() == 0); - pPack = pPackBest; - nID = pPack->AddBlock(LogBaseTwo(nBlockW), LogBaseTwo(nBlockH)); - pPack->m_fLastUsed = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - if (nID != -1) - { - pDT = this; - pDT->m_nUpdateMask = 0; - } - else - { - assert(0); - pDT = NULL; - } - } - else - { - nStage = 6; - assert(0); // there was no free spot in the texture pool - either the pools are too small or there are too many requests or reuse is not possible because some of them are not released when they could be - } - } - } - - if (!pDT) - { - nStage |= 0x100; - int n = (nSize + TEX_POOL_BLOCKSIZE - 1) / TEX_POOL_BLOCKSIZE; - pPack = new CPowerOf2BlockPacker(LogBaseTwo(n), LogBaseTwo(n)); - m_pOwner->m_TexPools.push_back(pPack); - nID = pPack->AddBlock(LogBaseTwo(nBlockW), LogBaseTwo(nBlockH)); - char name[256]; - sprintf_s(name, "$Dyn_2D_%s_%s_%d", CTexture::NameForTextureFormat(m_pOwner->m_eTF), GetPoolName(m_eTexPool), gRenDev->m_TexGenID++); - pPack->m_pTexture = CTexture::CreateRenderTarget(name, nSize, nSize, Clr_Transparent, m_pOwner->m_eTT, m_pOwner->m_nTexFlags, m_pOwner->m_eTF); - s_nMemoryOccupied[m_eTexPool] += nNeedSpace; - if (nID == -1) - { - assert(0); - nID = (uint32) - 2; - } - } - } - assert(nID != -1 && nID != -2); - m_nBlockID = nID; - m_pAllocator = pPack; - if (pPack) - { - m_pTexture = pPack->m_pTexture; - uint32 nX1, nX2, nY1, nY2; - pPack->GetBlockInfo(nID, nX1, nY1, nX2, nY2); - m_nX = nX1 << TEX_POOL_BLOCKLOGSIZE; - m_nY = nY1 << TEX_POOL_BLOCKLOGSIZE; - m_nWidth = (nX2 - nX1) << TEX_POOL_BLOCKLOGSIZE; - m_nHeight = (nY2 - nY1) << TEX_POOL_BLOCKLOGSIZE; - m_nUpdateMask = 0; - SetUpdateMask(); - } - } - PREFAST_ASSUME(m_pAllocator); - m_pAllocator->m_fLastUsed = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - Unlink(); - if (m_pTexture) - { - Link(); - return true; - } - return false; -} - -bool SDynTexture2::Remove() -{ - if (!m_pAllocator) - { - return false; - } - if (m_nBlockID != -1) - { - m_pAllocator->RemoveBlock(m_nBlockID); - } - m_nBlockID = ~0; - m_pTexture = NULL; - m_nUpdateMask = 0; - m_pAllocator = NULL; - Unlink(); - - return true; -} - -void SDynTexture2::Apply(int nTUnit, int nTS) -{ - if (!m_pAllocator) - { - return; - } - m_pAllocator->m_fLastUsed = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - - if (!m_pTexture) - { - Update(m_nWidth, m_nHeight); - } - if (m_pTexture) - { - m_pTexture->ApplyTexture(nTUnit, nTS); - } - gRenDev->m_cEF.m_RTRect.x = (float)m_nX / (float)m_pTexture->GetWidth(); - gRenDev->m_cEF.m_RTRect.y = (float)m_nY / (float)m_pTexture->GetHeight(); - gRenDev->m_cEF.m_RTRect.z = (float)m_nWidth / (float)m_pTexture->GetWidth(); - gRenDev->m_cEF.m_RTRect.w = (float)m_nHeight / (float)m_pTexture->GetHeight(); -} - -bool SDynTexture2::IsValid() -{ - if (!m_pTexture) - { - return false; - } - CRenderer* rd = gRenDev; - m_nAccessFrame = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - if (m_nFrameReset != rd->m_nFrameReset) - { - m_nFrameReset = rd->m_nFrameReset; - m_nUpdateMask = 0; - return false; - } - if (rd->GetActiveGPUCount() > 1) - { - if ((rd->GetFeatures() & RFT_HW_MASK) == RFT_HW_ATI) - { - uint32 nX, nY, nW, nH; - GetImageRect(nX, nY, nW, nH); - if (nW < 1024 && nH < 1024) - { - return true; - } - } - - int nFrame = rd->RT_GetCurrGpuID(); - if (!((1 << nFrame) & m_nUpdateMask)) - { - return false; - } - } - return true; -} - -void SDynTexture2::ReleaseForce() -{ - delete this; -} - -void SDynTexture2::ShutDown() -{ - uint32 i; - for (i = 0; i < eTP_Max; i++) - { - if (s_TexturePool[i]) - { - for (TextureSet2Itor it = s_TexturePool[i]->begin(); it != s_TexturePool[i]->end(); it++) - { - STextureSetFormat* pF = it->second; - PREFAST_ASSUME(pF); - SDynTexture2* pDT, *pNext; - for (pDT = pF->m_pRoot; pDT; pDT = pNext) - { - pNext = pDT->m_Next; - SAFE_RELEASE_FORCE(pDT); - } - SAFE_DELETE(pF); - } - s_TexturePool[i]->clear(); - } - } -} - -STextureSetFormat::~STextureSetFormat() -{ - uint32 i; - - for (i = 0; i < m_TexPools.size(); i++) - { - CPowerOf2BlockPacker* pP = m_TexPools[i]; - PREFAST_ASSUME(pP); - if (pP->m_pTexture) - { - int nSize = CTexture::TextureDataSize(pP->m_pTexture->GetWidth(), pP->m_pTexture->GetHeight(), 1, 1, 1, pP->m_pTexture->GetTextureDstFormat()); - SDynTexture2::s_nMemoryOccupied[m_eTexPool] = max(0, SDynTexture2::s_nMemoryOccupied[m_eTexPool] - nSize); - } - - SAFE_DELETE(pP); - } - m_TexPools.clear(); -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.cpp b/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.cpp deleted file mode 100644 index 8f30b838df..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "ITextureStreamer.h" -#include "Texture.h" - -ITextureStreamer::ITextureStreamer() -{ - m_pendingRelinks.reserve(4096); - m_pendingUnlinks.reserve(4096); - m_textures.reserve(4096); -} - -void ITextureStreamer::BeginUpdateSchedule() -{ - SyncTextureList(); - - if (CTexture::s_bStatsComputeStreamPoolWanted || CTexture::s_pStatsTexWantedLists) - { - CTexture::s_nStatsStreamPoolWanted = StatsComputeRequiredMipMemUsage(); - } - -#if !defined(_RELEASE) && !defined(NULL_RENDERER) - if (CRenderer::CV_r_TexturesStreamingDebug >= 3) - { - CTexture::OutputDebugInfo(); - } -#endif -} - -void ITextureStreamer::ApplySchedule(EApplyScheduleFlags asf) -{ - AZ_TRACE_METHOD(); - if (asf & eASF_InOut) - { - CTexture::StreamState_Update(); - } - - if (asf & eASF_Prep) - { - CTexture::StreamState_UpdatePrep(); - } -} - -void ITextureStreamer::Relink(CTexture* pTexture) -{ - m_pendingRelinks.push_back(pTexture); - pTexture->m_bInDistanceSortedList = true; -} - -void ITextureStreamer::Unlink(CTexture* pTexture) -{ - using std::swap; - - TStreamerTextureVec::iterator it = std::find(m_pendingRelinks.begin(), m_pendingRelinks.end(), pTexture); - if (it == m_pendingRelinks.end()) - { - m_pendingUnlinks.push_back(pTexture); - } - else - { - swap(*it, m_pendingRelinks.back()); - m_pendingRelinks.pop_back(); - } - - pTexture->m_bInDistanceSortedList = false; -} - -int ITextureStreamer::GetMinStreamableMip() const -{ - return CTexture::s_bStreamingFromHDD ? 0 : CRenderer::CV_r_TexturesStreamingMipClampDVD; -} - -int ITextureStreamer::GetMinStreamableMipWithSkip() const -{ - return (CTexture::s_bStreamingFromHDD ? 0 : CRenderer::CV_r_TexturesStreamingMipClampDVD); -} - -size_t ITextureStreamer::StatsComputeRequiredMipMemUsage() -{ -#ifdef STRIP_RENDER_THREAD - int nThreadList = m_nCurThreadProcess; -#else - int nThreadList = gRenDev->m_pRT->m_nCurThreadProcess; -#endif - std::vector* pLists = CTexture::s_pStatsTexWantedLists; - std::vector* pList = pLists ? &pLists[nThreadList] : NULL; - - if (pList) - { - pList->clear(); - } - - SyncTextureList(); - - TStreamerTextureVec& textures = GetTextures(); - - size_t nSizeToLoad = 0; - - TStreamerTextureVec::iterator item = textures.begin(), end = textures.end(); - for (; item != end; ++item) - { - CTexture* tp = *item; - - bool bStale = StatsWouldUnload(tp); - { - int nPersMip = tp->m_nMips - tp->m_CacheFileHeader.m_nMipsPersistent; - int nReqMip = tp->m_bForceStreamHighRes ? 0 : (bStale ? nPersMip : tp->GetRequiredMipNonVirtual()); - nReqMip = min(nReqMip, nPersMip); - - int nWantedSize = tp->StreamComputeDevDataSize(nReqMip); - - nSizeToLoad += nWantedSize; - if (nWantedSize && pList) - { - if (tp->TryAddRef()) - { - CTexture::WantedStat ws; - ws.pTex = tp; - tp->Release(); - ws.nWanted = nWantedSize; - pList->push_back(ws); - } - } - } - } - - return nSizeToLoad; -} - -void ITextureStreamer::StatsFetchTextures(std::vector& out) -{ - SyncTextureList(); - - out.reserve(out.size() + m_textures.size()); - std::copy(m_textures.begin(), m_textures.end(), std::back_inserter(out)); -} - -bool ITextureStreamer::StatsWouldUnload(const CTexture* pTexture) -{ - SThreadInfo& ti = gRenDev->m_RP.m_TI[gRenDev->m_pRT->GetThreadList()]; - const int nCurrentFarZoneRoundId = ti.m_arrZonesRoundId[MAX_PREDICTION_ZONES - 1]; - const int nCurrentNearZoneRoundId = ti.m_arrZonesRoundId[0]; - - return - (nCurrentFarZoneRoundId - pTexture->GetStreamRoundInfo(MAX_PREDICTION_ZONES - 1).nRoundUpdateId > 3) && - (nCurrentNearZoneRoundId - pTexture->GetStreamRoundInfo(0).nRoundUpdateId > 3); -} - -void ITextureStreamer::SyncTextureList() -{ - if (!m_pendingUnlinks.empty()) - { - std::sort(m_pendingUnlinks.begin(), m_pendingUnlinks.end()); - m_pendingUnlinks.resize((int)(std::unique(m_pendingUnlinks.begin(), m_pendingUnlinks.end()) - m_pendingUnlinks.begin())); - - TStreamerTextureVec::iterator it = m_textures.begin(), wrIt = it, itEnd = m_textures.end(); - for (; it != itEnd; ++it) - { - if (!std::binary_search(m_pendingUnlinks.begin(), m_pendingUnlinks.end(), *it)) - { - *wrIt++ = *it; - } - } - m_textures.erase(wrIt, itEnd); - - m_pendingUnlinks.resize(0); - } - - if (!m_pendingRelinks.empty()) - { - std::sort(m_pendingRelinks.begin(), m_pendingRelinks.end()); - m_pendingRelinks.resize((int)(std::unique(m_pendingRelinks.begin(), m_pendingRelinks.end()) - m_pendingRelinks.begin())); - memcpy(m_textures.grow_raw(m_pendingRelinks.size()), &m_pendingRelinks[0], sizeof(m_pendingRelinks[0]) * m_pendingRelinks.size()); - - m_pendingRelinks.resize(0); - } -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.h b/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.h deleted file mode 100644 index a7d087bf8e..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/ITextureStreamer.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_ITEXTURESTREAMER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_ITEXTURESTREAMER_H -#pragma once - - -struct STexStreamingInfo; -struct STexStreamPrepState; - -typedef DynArray TStreamerTextureVec; - -class ITextureStreamer -{ -public: - enum EApplyScheduleFlags - { - eASF_InOut = 1, - eASF_Prep = 2, - - eASF_Full = 3, - }; - -public: - ITextureStreamer(); - virtual ~ITextureStreamer() {} - -public: - virtual void BeginUpdateSchedule(); - virtual void ApplySchedule(EApplyScheduleFlags asf); - - virtual bool BeginPrepare(CTexture* pTexture, const char* sFilename, uint32 nFlags) = 0; - virtual void EndPrepare(STexStreamPrepState*& pState) = 0; - - virtual void Precache(CTexture* pTexture) = 0; - virtual void UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId, const int nCounter) = 0; - - virtual void OnTextureDestroy(CTexture* pTexture) = 0; - - void Relink(CTexture* pTexture); - void Unlink(CTexture* pTexture); - - virtual void FlagOutOfMemory() = 0; - virtual void Flush() = 0; - - virtual bool IsOverflowing() const = 0; - virtual float GetBias() const { return 0.0f; } - - int GetMinStreamableMip() const; - int GetMinStreamableMipWithSkip() const; - - void StatsFetchTextures(std::vector& out); - bool StatsWouldUnload(const CTexture* pTexture); - -protected: - void SyncTextureList(); - - TStreamerTextureVec& GetTextures() - { - return m_textures; - } - -private: - size_t StatsComputeRequiredMipMemUsage(); - -private: - TStreamerTextureVec m_pendingRelinks; - TStreamerTextureVec m_pendingUnlinks; - TStreamerTextureVec m_textures; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_ITEXTURESTREAMER_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.cpp b/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.cpp deleted file mode 100644 index 9415223864..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "CImage.h" -#include -#include "DDSImage.h" -#include -#include "IResourceCompilerHelper.h" - -CImageFile::CImageFile(const string& filename) - : m_FileName(filename) -{ - m_nRefCount = 0; - m_pByteImage[0] = NULL; - m_pByteImage[1] = NULL; - m_pByteImage[2] = NULL; - m_pByteImage[3] = NULL; - m_pByteImage[4] = NULL; - m_pByteImage[5] = NULL; - - m_eError = eIFE_OK; - m_eFormat = eTF_Unknown; - m_eTileMode = eTM_None; - m_NumMips = 0; - m_NumPersistentMips = 0; - m_Flags = 0; - m_ImgSize = 0; - m_Depth = 1; - m_nStartSeek = 0; - m_Sides = 1; - - m_pStreamState = NULL; -} - -CImageFile::~CImageFile() -{ - mfAbortStreaming(); - - for (int i = 0; i < 6; i++) - { - mfFree_image(i); - } -} - -void CImageFile::mfSet_dimensions(const int w, const int h) -{ - m_Width = w; - m_Height = h; -} - -void CImageFile::mfSet_error(const EImFileError error, const char* detail) -{ - m_eError = error; - if (detail) - { - TextureWarning(m_FileName.c_str(), detail); - } -} - -namespace -{ - struct DDSCallback - : public IImageFileStreamCallback - { - DDSCallback() - : ok(false) - { - } - virtual void OnImageFileStreamComplete(CImageFile* pImFile) - { - ok = pImFile != NULL; - waitEvent.Set(); - }; - CryEvent waitEvent; - volatile bool ok; - }; - - //This function return the appropriate replacement texture based on whether the source asset is missing,compiling etc and also - //takes into account whether the source asset was a cubemap,alpha texture etc. - const AZStd::string GetMissingTextureFileName(AZStd::string& inputFile, AzFramework::AssetSystem::AssetStatus status) - { - using namespace AzFramework::AssetSystem; - - CRY_ASSERT(status != AssetStatus_Compiled); - AZStd::string sFileToLoad = "EngineAssets/TextureMsg/"; - AZStd::string prefixName = ""; - //Checking status of the source asset - if (status == AssetStatus_Missing) - { - prefixName = "NotFound"; - } - else if (status == AssetStatus_Compiling || status == AssetStatus_Queued) - { - prefixName = "TextureCompiling"; - } - else if (status == AssetStatus_Failed) - { - prefixName = "RCError"; - } - else // fallback case. - { - prefixName = "NotFound"; - } - - if (inputFile.find("_ddna.") != string::npos) - { - sFileToLoad.append(prefixName + "_ddna.dds"); - } - else if (inputFile.find("_ddn.") != string::npos) - { - sFileToLoad.append(prefixName + "_ddn.dds"); - } - else if (inputFile.find("_a.") != string::npos) - { - sFileToLoad.append(prefixName + "_a.dds"); - } - else if (inputFile.find("_cm.") != string::npos) - { - sFileToLoad.append(prefixName + "_cm.dds"); - } - else if (inputFile.find("_cm_diff.") != string::npos) - { - sFileToLoad.append(prefixName + "_cm_diff.dds"); - } - else - { - sFileToLoad.append(prefixName + ".dds"); - } - - if (!gEnv->pCryPak->IsFileExist(sFileToLoad.c_str())) - { - //if missing texture is not present than we send a request to asset processor to process it - AssetStatus assetStatus = AssetStatus_Unknown; - EBUS_EVENT_RESULT(assetStatus, AzFramework::AssetSystemRequestBus, CompileAssetSync, sFileToLoad); - - if (assetStatus != AssetStatus_Compiled) - { - //if we are here ,it means we were not able to compile both the source asset as well the replacement asset - return AZStd::string(); - } - } - - return sFileToLoad; - } - - - //Textures in texturemsg,code coverage and editor folder need to be compiled immediately - bool DoesTextureRequireImmediateCompilation(const AZStd::string& fileName) - { - if (fileName.find("/texturemsg/") != string::npos || fileName.find("/codecoverage/") != string::npos || fileName.find("/editor/") != string::npos) - { - return true; - } - - return false; - } -} - -_smart_ptr CImageFile::mfLoad_file(const string& filename, const uint32 nFlags) -{ - AZStd::string sFileToLoad; - { - char buffer[512]; - IResourceCompilerHelper::GetOutputFilename(filename, buffer, sizeof(buffer)); // change filename: e.g. instead of TIF, pass DDS - sFileToLoad = buffer; - } - AZStd::string originalFile(sFileToLoad); - - bool fileIsMissing = false; - if (gEnv->pCryPak) - { - if (!gEnv->pCryPak->IsFileExist(sFileToLoad.c_str())) - { - fileIsMissing = true; - } - } - else - { - if (!gEnv->pFileIO->Exists(sFileToLoad.c_str())) - { - fileIsMissing = true; - } - } - - if (fileIsMissing) - { - using namespace AzFramework::AssetSystem; - AssetStatus status = AssetStatus_Unknown; - // if the texture has been requested with no fallback support then we must try our best to compile it asap, blocking - if (CRenderer::CV_r_texBlockOnLoad || (nFlags & FIM_NOFALLBACKS) || DoesTextureRequireImmediateCompilation(originalFile)) - { - EBUS_EVENT_RESULT(status, AzFramework::AssetSystemRequestBus, CompileAssetSync, originalFile); - } - else - { - EBUS_EVENT_RESULT(status, AzFramework::AssetSystemRequestBus, GetAssetStatus, originalFile); - } - - - if (status != AssetStatus_Compiled) - { - if (nFlags & FIM_NOFALLBACKS) // do not return a fallback image. - { - return _smart_ptr(); - } - if (status == AssetStatus_Missing) - { - TextureWarning(originalFile.c_str(), "Texture file is missing: '%s'", originalFile.c_str()); - } - else if (status == AssetStatus_Failed) - { - TextureWarning(originalFile.c_str(), "Failed to compile texture: '%s'", originalFile.c_str()); - } - sFileToLoad = GetMissingTextureFileName(originalFile, status); - if (sFileToLoad.empty()) - { - //We were not able to replace the input texture file with a substitute texture file - CryLog("No Substitute Texture found for the file : %s", originalFile.c_str()); - } - } - } - - const char* ext = PathUtil::GetExt(sFileToLoad.c_str()); - _smart_ptr pImageFile; - - // Try DDS first - if (!strcmp(ext, "dds")) - { - pImageFile = new CImageDDSFile(sFileToLoad.c_str(), nFlags); - - if (fileIsMissing) - { - // masquerade the file as the original one so if the original changes, we reload. - pImageFile->mfChange_Filename(originalFile.c_str()); - pImageFile->m_bIsImageMissing = true; - } - } - else - { -#ifndef _RELEASE - ITextureLoadHandler* pTextureHandler = nullptr; - - //suppress warning if a texture handler will be able to load this image later - if (I3DEngine* p3DEngine = gEnv->p3DEngine) - { - pTextureHandler = p3DEngine->GetTextureLoadHandlerForImage(filename.c_str()); - } - - if (!pTextureHandler) - { - TextureWarning(sFileToLoad.c_str(), "Unsupported texture extension '%s': '%s'", ext, filename.c_str()); - } -#endif - } - - if (pImageFile && pImageFile->mfGet_error() != eIFE_OK) - { - return _smart_ptr(); - } - - return pImageFile; -} - -_smart_ptr CImageFile::mfLoad_mem(const string& filename, void* data, int width, int height, ETEX_Format format, int numMips, const uint32 nFlags) -{ - _smart_ptr pImageFile = new CImageFile(filename); - - pImageFile->m_Width = width; - pImageFile->m_Height = height; - pImageFile->m_NumMips = numMips; - pImageFile->m_eFormat = format; - pImageFile->m_FileName = filename; - pImageFile->m_Flags = nFlags; - pImageFile->m_ImgSize = - CTexture::TextureDataSize(width, height, pImageFile->m_Depth, numMips, 1, format, pImageFile->m_eTileMode); - - pImageFile->m_pByteImage[0] = static_cast(data); - - if (pImageFile && pImageFile->mfGet_error() != eIFE_OK) - { - return _smart_ptr(); - } - - return pImageFile; -} - -_smart_ptr CImageFile::mfStream_File(const string& filename, const uint32 nFlags, IImageFileStreamCallback* pCallback) -{ - string sFileToLoad; - { - char buffer[512]; - IResourceCompilerHelper::GetOutputFilename(filename, buffer, sizeof(buffer)); // change filename: e.g. instead of TIF, pass DDS - sFileToLoad = buffer; - } - - const char* ext = PathUtil::GetExt(sFileToLoad); - _smart_ptr pImageFile; - - // Try DDS first - if (!strcmp(ext, "dds")) - { - CImageDDSFile* pDDS = new CImageDDSFile(sFileToLoad); - pImageFile = pDDS; - pDDS->Stream(nFlags, pCallback); - } - else - { - TextureWarning(sFileToLoad.c_str(), "Unsupported texture extension '%s'", ext); - } - - return pImageFile; -} - -void CImageFile::mfFree_image(const int nSide) -{ - SAFE_DELETE_ARRAY(m_pByteImage[nSide]); -} - -byte* CImageFile::mfGet_image(const int nSide) -{ - if (!m_pByteImage[nSide] && m_ImgSize) - { - m_pByteImage[nSide] = new byte[m_ImgSize]; - } - return m_pByteImage[nSide]; -} - -void CImageFile::mfAbortStreaming() -{ - if (m_pStreamState) - { - for (int i = 0; i < m_pStreamState->MaxStreams; ++i) - { - if (m_pStreamState->m_pStreams[i]) - { - m_pStreamState->m_pStreams[i]->Abort(); - } - } - delete m_pStreamState; - m_pStreamState = NULL; - } -} - -DDSSplitted::DDSDesc CImageFile::mfGet_DDSDesc() const -{ - return DDSSplitted::DDSDesc(); -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.h b/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.h deleted file mode 100644 index 2908b774fb..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/CImage.h +++ /dev/null @@ -1,232 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H -#pragma once - - -#include "IImage.h" - -#define SH_LITTLE_ENDIAN - -// The mask for extracting just R/G/B from an ulong or SRGBPixel -#ifdef SH_BIG_ENDIAN -# define RGB_MASK 0xffffff00 -#else -# define RGB_MASK 0x00ffffff -#endif - -/** - * An RGB pixel. - */ -struct SRGBPixel -{ - uint8 blue, green, red, alpha; - SRGBPixel() /* : red(0), green(0), blue(0), alpha(255) {} */ - { - *(unsigned int*)this = (unsigned int)~RGB_MASK; - } - SRGBPixel(int r, int g, int b) - : red(r) - , green(g) - , blue(b) - , alpha(255) {} - //bool eq (const SRGBPixel& p) const { return ((*(unsigned int *)this) & RGB_MASK) == ((*(unsigned int *)&p) & RGB_MASK); } -}; - -class CImageFile; -namespace DDSSplitted { - struct DDSDesc; -} - -struct IImageFileStreamCallback -{ - virtual void OnImageFileStreamComplete(CImageFile* pImFile) = 0; - -protected: - virtual ~IImageFileStreamCallback() {} -}; - -struct SImageFileStreamState -{ - enum - { - MaxStreams = 64 - }; - - struct Request - { - void* pOut; - size_t nOffs; - size_t nSize; - }; - - void RaiseComplete(CImageFile* pFile) - { - if (m_pCallback) - { - m_pCallback->OnImageFileStreamComplete(pFile); - m_pCallback = NULL; - } - } - - volatile int m_nPending; - uint32 m_nFlags; - IImageFileStreamCallback* m_pCallback; - IReadStreamPtr m_pStreams[MaxStreams]; - Request m_requests[MaxStreams]; -}; - -class CImageFile - : public IImageFile - , public IStreamCallback -{ -private: - CImageFile(const CImageFile&); - CImageFile& operator = (const CImageFile&); - -private: - volatile int m_nRefCount; - bool m_bIsImageMissing = false; - -protected: - int m_Width; // Width of image. - int m_Height; // Height of image. - int m_Depth; // Depth of image. - int m_Sides; // Depth of image. - - int m_ImgSize; - - int m_NumMips; - int m_NumPersistentMips; - int m_Flags; // e.g. FIM_GREYSCALE|FIM_ALPHA - int m_nStartSeek; - float m_fAvgBrightness; - ColorF m_cMinColor; - ColorF m_cMaxColor; - - union // The image data. - { - byte* m_pByteImage[6]; - SRGBPixel* m_pPixImage[6]; - }; - - EImFileError m_eError; // Last error code. - string m_FileName; // file name - - ETEX_Format m_eFormat; - ETEX_TileMode m_eTileMode; - - SImageFileStreamState* m_pStreamState; - -protected: - CImageFile(const string& filename); - - void mfSet_error(const EImFileError error, const char* detail = NULL); - void mfSet_dimensions(const int w, const int h); -public: - virtual ~CImageFile(); - - virtual int AddRef() - { - return CryInterlockedIncrement(&m_nRefCount); - } - - virtual int Release() - { - int nRef = CryInterlockedDecrement(&m_nRefCount); - if (nRef == 0) - { - delete this; - } - else if (nRef < 0) - { - assert(0); - CryFatalError("Deleting Reference Counted Object Twice"); - } - return nRef; - } - - const string& mfGet_filename() const { return m_FileName; } - void mfChange_Filename(const string& newName) - { - // used when one texture (such as the 'missing texture') is masquerading as another one until reloaded. - m_FileName = newName; - } - - int mfGet_width() const { return m_Width; } - int mfGet_height() const { return m_Height; } - int mfGet_depth() const { return m_Depth; } - int mfGet_NumSides() const { return m_Sides; } - - bool mfGet_IsImageMissing() const - { - return m_bIsImageMissing; - } - - EImFileError mfGet_error() const { return m_eError; } - - byte* mfGet_image(const int nSide); - void mfFree_image(const int nSide); - bool mfIs_image(const int nSide) const { return m_pByteImage[nSide] != NULL; } - - int mfGet_StartSeek() const { return m_nStartSeek; } - - void mfSet_ImageSize(int Size) { m_ImgSize = Size; } - int mfGet_ImageSize() const { return m_ImgSize; } - - ETEX_Format mfGetFormat() const { return m_eFormat; } - ETEX_TileMode mfGetTileMode() const { return m_eTileMode; } - - void mfSet_numMips(const int num) { m_NumMips = num; } - int mfGet_numMips() const { return m_NumMips; } - - void mfSet_numPersistentMips(const int num) { m_NumPersistentMips = num; } - int mfGet_numPersistentMips() const { return m_NumPersistentMips; } - - void mfSet_avgBrightness(const float avgBrightness) { m_fAvgBrightness = avgBrightness; } - float mfGet_avgBrightness() const { return m_fAvgBrightness; } - - void mfSet_minColor(const ColorF& minColor) { m_cMinColor = minColor; } - const ColorF& mfGet_minColor() const { return m_cMinColor; } - - void mfSet_maxColor(const ColorF& maxColor) { m_cMaxColor = maxColor; } - const ColorF& mfGet_maxColor() const { return m_cMaxColor; } - - void mfSet_Flags(const int Flags) { m_Flags |= Flags; } - int mfGet_Flags() const { return m_Flags; } - - void mfAbortStreaming(); - - virtual DDSSplitted::DDSDesc mfGet_DDSDesc() const; - -public: - /** - * Load a image from memory by assigning the image byte data directly without copying. - * - * @param filename The image filename - * @param data byte image data, caller owns this data and is responsible for cleanup. - * @param width image width - * @param height image height - * @param format image format (eTF_R8G8B8A8, eTF_PVRTC4 etc.) - * @param numMips number of mip maps - * @param nFlags image flags (e.g. FIM_GREYSCALE|FIM_ALPHA) - */ - static _smart_ptr mfLoad_mem(const string& filename, void* data, int width, int height, ETEX_Format format, int numMips, const uint32 nFlags); - static _smart_ptr mfLoad_file(const string& filename, const uint32 nFlags); - static _smart_ptr mfStream_File(const string& filename, const uint32 nFlags, IImageFileStreamCallback* pCallback); -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_CIMAGE_H - diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.cpp b/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.cpp deleted file mode 100644 index 86652af21b..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.cpp +++ /dev/null @@ -1,1143 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : DDS image file format implementation. - - -#include "RenderDll_precompiled.h" -#include "CImage.h" -#include -#include -#include "DDSImage.h" -#include "ImageExtensionHelper.h" // CImageExtensionHelper -#include "TypeInfo_impl.h" -#include "ImageExtensionHelper_info.h" -#include "StringUtils.h" -#include "ILog.h" -#include "../TextureHelpers.h" - -CImageDDSFile::CImageDDSFile(const string& filename) - : CImageFile(filename) -{ -} - -CImageDDSFile::CImageDDSFile (const string& filename, uint32 nFlags) - : CImageFile (filename) -{ - LOADING_TIME_PROFILE_SECTION; - m_pFileMemory = 0; - if (!Load(filename, nFlags) || NULL == m_pFileMemory) // load data from file - { - if (mfGet_error() == eIFE_OK) - { - if (nFlags & FIM_ALPHA) - { - mfSet_error(eIFE_BadFormat, "Texture does not have alpha channel"); // Usually requested via FT_HAS_ATTACHED_ALPHA for POM / Offset Bump Mapping - } - } - } - else - { - PostLoad(); - } -} - -bool CImageDDSFile::Stream(uint32 nFlags, IImageFileStreamCallback* pStreamCallback) -{ - const string& filename = mfGet_filename(); - - DDSSplitted::TPath adjustedFileName; - AdjustFirstFileName(nFlags, filename.c_str(), adjustedFileName); - - m_pStreamState = new SImageFileStreamState; - m_pStreamState->m_nPending = 1; - m_pStreamState->m_nFlags = nFlags; - m_pStreamState->m_pCallback = pStreamCallback; - AddRef(); - - IStreamEngine* pStreamEngine = gEnv->pSystem->GetStreamEngine(); - - StreamReadParams rp; - rp.nFlags |= IStreamEngine::FLAGS_NO_SYNC_CALLBACK; - rp.dwUserData = 0; - m_pStreamState->m_pStreams[0] = pStreamEngine->StartRead(eStreamTaskTypeTexture, adjustedFileName.c_str(), this, &rp); - - return true; -} - -DDSSplitted::DDSDesc CImageDDSFile::mfGet_DDSDesc() const -{ - DDSSplitted::DDSDesc d; - d.eFormat = m_eFormat; - d.eTileMode = m_eTileMode; - d.nBaseOffset = mfGet_StartSeek(); - d.nDepth = m_DDSHeader.dwDepth; - d.nFlags = (m_Flags & (FIM_ALPHA | FIM_SPLITTED | FIM_DX10IO)); - d.nHeight = m_DDSHeader.dwHeight; - d.nMips = m_DDSHeader.dwMipMapCount; - d.nMipsPersistent = m_NumPersistentMips; - d.nSides = m_Sides; - d.nWidth = m_DDSHeader.dwWidth; - return d; -} - -////////////////////////////////////////////////////////////////////// -bool CImageDDSFile::Load(const string& filename, uint32 nFlags) -{ - LOADING_TIME_PROFILE_SECTION; - - DDSSplitted::TPath adjustedFileName; - AdjustFirstFileName(nFlags, filename.c_str(), adjustedFileName); - - DDSSplitted::RequestInfo otherMips[64]; - size_t nOtherMips = 0; - - // Read the file into memory regardless of split or un-split Mips - DDSSplitted::FileWrapper filew(adjustedFileName.c_str(), true); - if (!LoadFromFile(filew, nFlags, otherMips, nOtherMips, 64)) - { - return false; - } - - if (nOtherMips && !DDSSplitted::LoadMipsFromRequests(otherMips, nOtherMips)) - { - AZ_Error("Render", false, "Failed to load mips for DDS asset %s", adjustedFileName.c_str()); - return false; - } - - return true; -} - -int CImageDDSFile::AdjustHeader() -{ - int nDeltaMips = 0; - - if (!(m_Flags & FIM_SUPPRESS_DOWNSCALING)) - { - int nFinalMips = min(max(m_NumPersistentMips, max(CRenderer::CV_r_texturesstreamingMinUsableMips, m_NumMips - CRenderer::CV_r_texturesstreamingSkipMips)), m_NumMips); - - nDeltaMips = m_NumMips - nFinalMips; - if (nDeltaMips > 0) - { - m_Width = max(1, m_Width >> nDeltaMips); - m_Height = max(1, m_Height >> nDeltaMips); - m_Depth = max(1, m_Depth >> nDeltaMips); - m_NumMips = nFinalMips; - } - } - - return nDeltaMips; -} - -bool CImageDDSFile::LoadFromFile(DDSSplitted::FileWrapper& file, uint32 nFlags, DDSSplitted::RequestInfo* pConts, size_t& nConts, [[maybe_unused]] size_t nContsCap) -{ - LOADING_TIME_PROFILE_SECTION; - - if (file.IsValid()) - { - const size_t fileSize = file.GetLength(); - - AZStd::intrusive_ptr pImageMemory; - - // alloc space for header - CImageExtensionHelper::DDS_FILE_DESC ddsHeader; - CImageExtensionHelper::DDS_HEADER_DXT10 ddsExtendedHeader; - - if (nFlags & FIM_ALPHA) - { - // Requested alpha image. - ddsHeader.dwMagic = MAKEFOURCC('D', 'D', 'S', ' '); - if (!(nFlags & FIM_SPLITTED)) - { - // Not split. Which means it's somewhere in this file. Go find it. - if (!DDSSplitted::SeekToAttachedImage(file)) - { - mfSet_error(eIFE_ChunkNotFound, "Failed to find attached image"); - return false; - } - } - else - { - file.ReadRaw(&ddsHeader.dwMagic, sizeof(ddsHeader.dwMagic)); - } - file.ReadRaw(&ddsHeader.header, sizeof(CImageExtensionHelper::DDS_HEADER)); - SwapEndian(ddsHeader.header); - ddsHeader.dwMagic = MAKEFOURCC('D', 'D', 'S', ' '); - } - else - { - file.ReadRaw(&ddsHeader, sizeof(CImageExtensionHelper::DDS_FILE_DESC)); - SwapEndian(ddsHeader); - } - - if (!ddsHeader.IsValid()) - { - mfSet_error(eIFE_BadFormat, "Bad DDS header"); - return false; - } - - if (ddsHeader.header.IsDX10Ext()) - { - file.ReadRaw(&ddsExtendedHeader, sizeof(CImageExtensionHelper::DDS_HEADER_DXT10)); - } - - m_nStartSeek = file.Tell(); - - if (!SetHeaderFromMemory((byte*)&ddsHeader, (byte*)&ddsExtendedHeader, nFlags)) - { - return false; - } - - // Grab a snapshot of the DDS layout before adjusting the header - DDSSplitted::DDSDesc desc; - desc.pName = m_FileName.c_str(); - desc.nWidth = m_Width; - desc.nHeight = m_Height; - desc.nDepth = m_Depth; - desc.nMips = m_NumMips; - desc.nMipsPersistent = m_NumPersistentMips; - desc.nSides = m_Sides; - desc.eFormat = m_eFormat; - desc.eTileMode = m_eTileMode; - desc.nBaseOffset = m_nStartSeek; - desc.nFlags = m_Flags; - - int nDeltaMips = AdjustHeader(); - - // If stream prepare, only allocate room for the pers mips - - int nMipsToLoad = (m_Flags & FIM_STREAM_PREPARE) - ? m_NumPersistentMips - : m_NumMips; - int nImageIgnoreMips = m_NumMips - nMipsToLoad; - int nFirstPersistentMip = m_NumMips - m_NumPersistentMips; - - auto streamer = AZ::Interface::Get(); - - size_t nImageSideSize = CTexture::TextureDataSize( - max(1, m_Width >> nImageIgnoreMips), - max(1, m_Height >> nImageIgnoreMips), - max(1, m_Depth >> nImageIgnoreMips), - nMipsToLoad, 1, m_eFormat, m_eTileMode); - size_t nImageSize = nImageSideSize * m_Sides; - pImageMemory = gEnv->pCryPak->PoolAllocMemoryBlock(nImageSize, "CImageDDSFile::LoadFromFile", - streamer->GetRecommendations().m_memoryAlignment); - - mfSet_ImageSize(nImageSideSize); - - DDSSplitted::ChunkInfo chunks[16]; - size_t numChunks = DDSSplitted::GetFilesToRead(chunks, 16, desc, nDeltaMips + nImageIgnoreMips, m_NumMips + nDeltaMips - 1); - - uint32 nDstOffset = 0; - byte* pDst = (byte*)pImageMemory->m_address.get(); - - nConts = 0; - - for (size_t chunkIdx = 0; chunkIdx < numChunks; ++chunkIdx) - { - const DDSSplitted::ChunkInfo& chunk = chunks[chunkIdx]; - - uint32 nSurfaceSize = CTexture::TextureDataSize( - max(1u, (uint32)desc.nWidth >> chunk.nMipLevel), - max(1u, (uint32)desc.nHeight >> chunk.nMipLevel), - max(1u, (uint32)desc.nDepth >> chunk.nMipLevel), - 1, 1, desc.eFormat, desc.eTileMode); - uint32 nSidePitch = nSurfaceSize + chunk.nSideDelta; - - // Only copy persistent mips now. Create continuations for any others. - - int nChunkMip = chunk.nMipLevel - nDeltaMips; - if (nChunkMip < nFirstPersistentMip) - { - string chunkFileName(chunk.fileName); - for (uint32 sideIdx = 0; sideIdx < m_Sides; ++sideIdx) - { - DDSSplitted::RequestInfo& cont = pConts[nConts++]; - cont.fileName = chunkFileName; - cont.nOffs = chunk.nOffsetInFile + sideIdx * nSidePitch; - cont.nRead = nSurfaceSize; - cont.pOut = pDst + sideIdx * nImageSideSize + nDstOffset; - } - } - else - { - for (uint32 sideIdx = 0; sideIdx < m_Sides; ++sideIdx) - { - file.Seek(chunk.nOffsetInFile + sideIdx * nSidePitch); - file.ReadRaw(pDst + sideIdx * nImageSideSize + nDstOffset, nSurfaceSize); - } - } - - nDstOffset += nSurfaceSize; - } - - m_pFileMemory = pImageMemory; - - return true; - } - - return false; -} - -void CImageDDSFile::StreamAsyncOnComplete(IReadStream* pStream, uint32 nError) -{ - assert (m_pStreamState); - - int nPending = CryInterlockedDecrement(&m_pStreamState->m_nPending); - - bool bIsComplete = false; - bool bWasSuccess = false; - - if (!nError) - { - const StreamReadParams& rp = pStream->GetParams(); - - if (rp.dwUserData == 0) - { - DDSSplitted::FileWrapper file(pStream->GetBuffer(), pStream->GetBytesRead()); - - // Initial read. - - DDSSplitted::RequestInfo otherMips[SImageFileStreamState::MaxStreams - 1]; - const size_t nOtherMipsCap = sizeof(otherMips) / sizeof(otherMips[0]); - size_t nOtherMips = 0; - - if (LoadFromFile(file, m_pStreamState->m_nFlags, otherMips, nOtherMips, nOtherMipsCap)) - { - IStreamEngine* pStreamEngine = gEnv->pSystem->GetStreamEngine(); - - if (nOtherMips) - { - // Write before starting extra tasks - m_pStreamState->m_nPending = nOtherMips; - - // Issue stream requests for additional mips - for (size_t nOtherMip = 0; nOtherMip < nOtherMips; ++nOtherMip) - { - const DDSSplitted::RequestInfo& req = otherMips[nOtherMip]; - - StreamReadParams params; - params.dwUserData = nOtherMip + 1; - -#if 0 // TODO Fix me at some point - was disabled due to issue with SPU. Should be enabled again - params.nOffset = req.nOffs; - params.nSize = req.nRead; - params.pBuffer = req.pOut; -#else - m_pStreamState->m_requests[nOtherMip + 1].nOffs = req.nOffs; - m_pStreamState->m_requests[nOtherMip + 1].nSize = req.nRead; - m_pStreamState->m_requests[nOtherMip + 1].pOut = req.pOut; -#endif - - params.nFlags |= IStreamEngine::FLAGS_NO_SYNC_CALLBACK; - AddRef(); - - m_pStreamState->m_pStreams[nOtherMip + 1] = pStreamEngine->StartRead(eStreamTaskTypeTexture, req.fileName.c_str(), this, ¶ms); - } - } - else - { - bIsComplete = true; - } - - bWasSuccess = true; - } - } - else - { -#if 1 - const char* pBase = (const char*)m_pFileMemory->m_address.get(); - const char* pEnd = pBase + m_pFileMemory->m_size; - - char* pDst = (char*)m_pStreamState->m_requests[rp.dwUserData].pOut; - char* pDstEnd = pDst + m_pStreamState->m_requests[rp.dwUserData].nSize; - const char* pSrc = reinterpret_cast(pStream->GetBuffer()) + m_pStreamState->m_requests[rp.dwUserData].nOffs; - const char* pSrcEnd = pSrc + m_pStreamState->m_requests[rp.dwUserData].nSize; - - if (pDst < pBase) - { - __debugbreak(); - } - if (pDstEnd > pEnd) - { - __debugbreak(); - } - if (pSrc < pStream->GetBuffer()) - { - __debugbreak(); - } - if (pSrcEnd > reinterpret_cast(pStream->GetBuffer()) + pStream->GetBytesRead()) - { - __debugbreak(); - } - memcpy(pDst, pSrc, m_pStreamState->m_requests[rp.dwUserData].nSize); -#endif - - if (nPending == 0) - { - // Done! - bIsComplete = true; - bWasSuccess = true; - } - } - } - else - { - bIsComplete = true; - } - - pStream->FreeTemporaryMemory(); - - if (bIsComplete) - { - if (bWasSuccess) - { - PostLoad(); - m_pStreamState->RaiseComplete(this); - } - else - { - if (nPending) - { - __debugbreak(); - } - m_pStreamState->RaiseComplete(NULL); - } - } - - Release(); -} - -bool CImageDDSFile::SetHeaderFromMemory(byte* pFileStart, byte* pFileAfterHeader, uint32 nFlags) -{ - LOADING_TIME_PROFILE_SECTION - - - CImageExtensionHelper::DDS_FILE_DESC& dds = *(CImageExtensionHelper::DDS_FILE_DESC*)pFileStart; - CImageExtensionHelper::DDS_HEADER_DXT10& ddx = *(CImageExtensionHelper::DDS_HEADER_DXT10*)pFileAfterHeader; - - SwapEndian(dds); - if (dds.header.IsDX10Ext()) - { - SwapEndian(ddx); - } - - if (!dds.IsValid()) - { - mfSet_error (eIFE_BadFormat, "Bad DDS header"); - return false; - } - - m_DDSHeader = dds.header; - m_DDSHeaderExtension = ddx; - - // check for nativeness of texture - const uint32 imageFlags = CImageExtensionHelper::GetImageFlags(&m_DDSHeader); - if (!CImageExtensionHelper::IsImageNative(imageFlags)) - { - mfSet_error(eIFE_BadFormat, "Not converted for this platform"); - return false; - } - - // setup texture properties - m_Width = m_DDSHeader.dwWidth; - m_Height = m_DDSHeader.dwHeight; - - m_Flags |= m_DDSHeader.IsDX10Ext() ? FIM_DX10IO : 0; - - m_eFormat = DDSFormats::GetFormatByDesc(m_DDSHeader.ddspf, m_DDSHeaderExtension.dxgiFormat); - if (eTF_Unknown == m_eFormat) - { - mfSet_error (eIFE_BadFormat, "Unknown DDS pixel format!"); - return false; - } - - m_eTileMode = eTM_None; - if (imageFlags & CImageExtensionHelper::EIF_Tiled) - { - switch (m_DDSHeader.bTileMode) - { - case CImageExtensionHelper::eTM_LinearPadded: - m_eTileMode = eTM_LinearPadded; - break; - - case CImageExtensionHelper::eTM_Optimal: - m_eTileMode = eTM_Optimal; - break; - } - } - - mfSet_numMips(m_DDSHeader.GetMipCount()); - m_Depth = max((uint32)1ul, (uint32)m_DDSHeader.dwDepth); - - m_Sides = 1; - if ((m_DDSHeader.dwSurfaceFlags & DDS_SURFACE_FLAGS_CUBEMAP) && (m_DDSHeader.dwCubemapFlags & DDS_CUBEMAP_ALLFACES)) - { - m_Sides = 6; - } - - if (m_DDSHeader.dwTextureStage == 'CRYF') - { - m_NumPersistentMips = m_DDSHeader.bNumPersistentMips; - } - else - { - m_NumPersistentMips = 0; - } - - m_NumPersistentMips = min(m_NumMips, max((int)DDSSplitted::etexNumLastMips, m_NumPersistentMips)); - - m_fAvgBrightness = m_DDSHeader.fAvgBrightness; - m_cMinColor = m_DDSHeader.cMinColor; - m_cMaxColor = m_DDSHeader.cMaxColor; -#ifdef NEED_ENDIAN_SWAP - SwapEndianBase(&m_fAvgBrightness); - SwapEndianBase(&m_cMinColor); - SwapEndianBase(&m_cMaxColor); -#endif - - if (DDSFormats::IsNormalMap(m_eFormat)) - { - const int nLastMipWidth = m_Width >> (m_NumMips - 1); - const int nLastMipHeight = m_Height >> (m_NumMips - 1); - if (nLastMipWidth < 4 || nLastMipHeight < 4) - { - mfSet_error (eIFE_BadFormat, "Texture has wrong number of mips"); - } - } - - bool bStreamable = (nFlags & FIM_STREAM_PREPARE) != 0; - - // Can't stream volume textures and textures without mips - if (m_eFormat == eTF_Unknown || m_Depth > 1 || m_NumMips < 2) - { - bStreamable = false; - } - - if ( - (m_Width <= DDSSplitted::etexLowerMipMaxSize || m_Height <= DDSSplitted::etexLowerMipMaxSize) || - m_NumMips <= m_NumPersistentMips || - m_NumPersistentMips == 0) - { - bStreamable = false; - } - - if (bStreamable) - { - m_Flags |= FIM_STREAM_PREPARE; - } - m_Flags |= nFlags & (FIM_SPLITTED | FIM_ALPHA); - if (imageFlags & CImageExtensionHelper::EIF_Splitted) - { - m_Flags |= FIM_SPLITTED; - } - - // set up flags - if (!(nFlags & FIM_ALPHA)) - { - if ((imageFlags & DDS_RESF1_NORMALMAP) || TextureHelpers::VerifyTexSuffix(EFTT_NORMALS, m_FileName) || DDSFormats::IsNormalMap(m_eFormat)) - { - m_Flags |= FIM_NORMALMAP; - } - } - - if (imageFlags & CImageExtensionHelper::EIF_Decal) - { - m_Flags |= FIM_DECAL; - } - if (imageFlags & CImageExtensionHelper::EIF_SRGBRead) - { - m_Flags |= FIM_SRGB_READ; - } - if (imageFlags & CImageExtensionHelper::EIF_Greyscale) - { - m_Flags |= FIM_GREYSCALE; - } -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(Textures/Image/DDSImage_cpp, provo) -#endif -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(Textures/Image/DDSImage_cpp, jasper) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(Textures/Image/DDSImage_cpp, salem) -#endif - if (imageFlags & CImageExtensionHelper::EIF_AttachedAlpha) - { - m_Flags |= FIM_HAS_ATTACHED_ALPHA; - } - if (imageFlags & CImageExtensionHelper::EIF_SupressEngineReduce) - { - m_Flags |= FIM_SUPPRESS_DOWNSCALING; - } - if (imageFlags & CImageExtensionHelper::EIF_RenormalizedTexture) - { - m_Flags |= FIM_RENORMALIZED_TEXTURE; - } - - if (m_Flags & FIM_NORMALMAP) - { - if (DDSFormats::IsSigned(m_eFormat)) - { - m_cMinColor = ColorF(0.0f, 0.0f, 0.0f, 0.0f); - m_cMaxColor = ColorF(1.0f, 1.0f, 1.0f, 1.0f); - } - else - { - m_cMinColor = ColorF(-1.0f, -1.0f, -1.0f, -1.0f); - m_cMaxColor = ColorF(1.0f, 1.0f, 1.0f, 1.0f); - - // mfSet_error(eIFE_BadFormat, "Texture has to have a signed format"); - } - } - - return true; -} - -bool CImageDDSFile::PostLoad() -{ - const byte* ptrBuffer = (const byte*)m_pFileMemory->m_address.get(); - - int nSrcSideSize = mfGet_ImageSize(); - - for (int nS = 0; nS < m_Sides; nS++) - { - mfFree_image(nS); - mfGet_image(nS); - - // stop of an allocation failed - if (m_pByteImage[nS] == NULL) - { - // free already allocated data - for (int i = 0; i < nS; ++i) - { - mfFree_image(i); - } - mfSet_ImageSize(0); - mfSet_error(eIFE_OutOfMemory, "Failed to allocate Memory"); - return false; - } - - memcpy(m_pByteImage[nS], ptrBuffer + nSrcSideSize * nS, nSrcSideSize); - } - - // We don't need file memory anymore, free it. - m_pFileMemory = 0; - - return true; -} - -void CImageDDSFile::AdjustFirstFileName(uint32& nFlags, const char* pFileName, DDSSplitted::TPath& adjustedFileName) -{ - using namespace AZ::IO; - - LOADING_TIME_PROFILE_SECTION; - - const bool bIsAttachedAlpha = (nFlags & FIM_ALPHA) != 0; - adjustedFileName = pFileName; - - if (!bIsAttachedAlpha) - { - // First file for non attached mip chain is always just .dds - return; - } - - DDSSplitted::TPath firstAttachedAlphaChunkName; - DDSSplitted::MakeName(firstAttachedAlphaChunkName, pFileName, 0, nFlags | FIM_SPLITTED); - -#if defined (RELEASE) - // In release we assume alpha is split if a .dds.a exists. This breaks loading from a .dds outside of PAKs that contains all data (non split). - if (gEnv->pCryPak->IsFileExist(firstAttachedAlphaChunkName.c_str())) - { - nFlags |= FIM_SPLITTED; - adjustedFileName = firstAttachedAlphaChunkName; - } -#else - // Otherwise we check the .dds header which always works, but is slower (two reads from .dds and .dds.a on load) - CImageExtensionHelper::DDS_FILE_DESC ddsFileDesc; - - auto streamer = AZ::Interface::Get(); - AZStd::binary_semaphore wait; - AZStd::atomic_bool success = true; - - FileRequestPtr request = streamer->Read(pFileName, &ddsFileDesc, sizeof(ddsFileDesc), sizeof(ddsFileDesc), IStreamerTypes::s_deadlineNow); - streamer->SetRequestCompleteCallback(request, [&wait, &success](FileRequestHandle request) - { - auto streamer = AZ::Interface::Get(); - success = streamer->GetRequestStatus(request) == IStreamerTypes::RequestStatus::Completed; - wait.release(); - }); - streamer->QueueRequest(AZStd::move(request)); - wait.acquire(); - - if (success) - { - const uint32 imageFlags = CImageExtensionHelper::GetImageFlags(&ddsFileDesc.header); - if ((imageFlags& CImageExtensionHelper::EIF_Splitted) != 0) - { - nFlags |= FIM_SPLITTED; - adjustedFileName = firstAttachedAlphaChunkName; - } - } -#endif -} - -////////////////////////////////////////////////////////////////////// - -#if defined(WIN32) || defined(WIN64) -byte* WriteDDS(const byte* dat, int wdt, int hgt, int dpth, const char* name, ETEX_Format eTF, int nMips, ETEX_Type eTT, bool bToMemory, int* pSize) -{ - CImageExtensionHelper::DDS_FILE_DESC fileDesc; - memset(&fileDesc, 0, sizeof(fileDesc)); - byte* pData = NULL; - CCryFile file; - int nOffs = 0; - int nSize = CTexture::TextureDataSize(wdt, hgt, dpth, nMips, 1, eTF); - - fileDesc.dwMagic = MAKEFOURCC('D', 'D', 'S', ' '); - - if (!bToMemory) - { - if (!file.Open(name, "wb")) - { - return NULL; - } - - file.Write(&fileDesc.dwMagic, sizeof(fileDesc.dwMagic)); - } - else - { - pData = new byte[sizeof(fileDesc) + nSize]; - *(DWORD*)pData = fileDesc.dwMagic; - nOffs += sizeof(fileDesc.dwMagic); - } - - fileDesc.header.dwSize = sizeof(fileDesc.header); - fileDesc.header.dwWidth = wdt; - fileDesc.header.dwHeight = hgt; - fileDesc.header.dwMipMapCount = max(1, nMips); - fileDesc.header.dwHeaderFlags = DDS_HEADER_FLAGS_TEXTURE | DDS_HEADER_FLAGS_MIPMAP; - fileDesc.header.dwSurfaceFlags = DDS_SURFACE_FLAGS_TEXTURE | DDS_SURFACE_FLAGS_MIPMAP; - fileDesc.header.dwTextureStage = 'CRYF'; - fileDesc.header.dwReserved1 = 0; - fileDesc.header.fAvgBrightness = 0.0f; - fileDesc.header.cMinColor = 0.0f; - fileDesc.header.cMaxColor = 1.0f; - int nSides = 1; - if (eTT == eTT_Cube) - { - fileDesc.header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP; - fileDesc.header.dwCubemapFlags |= DDS_CUBEMAP_ALLFACES; - nSides = 6; - } - else if (eTT == eTT_3D) - { - fileDesc.header.dwHeaderFlags |= DDS_HEADER_FLAGS_VOLUME; - } - if (eTT != eTT_3D) - { - dpth = 1; - } - fileDesc.header.dwDepth = dpth; - if (name) - { - size_t len = strlen(name); - if (len > 4) - { - if (!_stricmp(&name[len - 4], ".ddn")) - { - fileDesc.header.dwReserved1 = DDS_RESF1_NORMALMAP; - } - } - } - fileDesc.header.ddspf = DDSFormats::GetDescByFormat(eTF); - fileDesc.header.dwPitchOrLinearSize = CTexture::TextureDataSize(wdt, 1, 1, 1, 1, eTF); - if (!bToMemory) - { - file.Write(&fileDesc.header, sizeof(fileDesc.header)); - - nOffs = 0; - int nSide; - for (nSide = 0; nSide < nSides; nSide++) - { - file.Write(&dat[nOffs], nSize); - nOffs += nSize; - } - } - else - { - memcpy(&pData[nOffs], &fileDesc.header, sizeof(fileDesc.header)); - nOffs += sizeof(fileDesc.header); - - int nSide; - int nSrcOffs = 0; - for (nSide = 0; nSide < nSides; nSide++) - { - memcpy(&pData[nOffs], &dat[nSrcOffs], nSize); - nSrcOffs += nSize; - nOffs += nSize; - } - - if (pSize) - { - *pSize = nOffs; - } - return pData; - } - - return NULL; -} -#endif // #if defined(WIN32) || defined(WIN64) - -////////////////////////////////////////////////////////////////////// -namespace DDSSplitted -{ - TPath& MakeName(TPath& sOut, const char* sOriginalName, const uint32 nChunk, const uint32 nFlags) - { - sOut = sOriginalName; - - assert (nChunk < 100); - - char buffer[10]; - if ((nFlags & FIM_SPLITTED) && (nChunk > 0)) - { - buffer[0] = '.'; - if (nChunk < 10) - { - buffer[1] = '0' + nChunk; - buffer[2] = 0; - } - else - { - buffer[1] = '0' + (nChunk / 10); - buffer[2] = '0' + (nChunk % 10); - buffer[3] = 0; - } - } - else - { - buffer[0] = 0; - } - - sOut.append(buffer); - if ((nFlags & (FIM_SPLITTED | FIM_ALPHA)) == (FIM_SPLITTED | FIM_ALPHA)) - { - // additional suffix for attached alpha channel - if (buffer[0]) - { - sOut.append("a"); - } - else - { - sOut.append(".a"); - } - } - - return sOut; - } - - size_t GetFilesToRead_Split(ChunkInfo* pFiles, [[maybe_unused]] size_t nFilesCapacity, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip) - { - FUNCTION_PROFILER_RENDERER; - - assert(nStartMip <= nEndMip); - assert(desc.nFlags & FIM_SPLITTED); - - if (nEndMip > desc.nMips) - { - nEndMip = desc.nMips - 1; - } - - size_t nNumFiles = 0; - - for (uint32 mip = nStartMip; mip <= nEndMip; ++mip) - { - const int chunkNumber = (mip >= (int)(desc.nMips - desc.nMipsPersistent)) - ? 0 - : desc.nMips - mip - desc.nMipsPersistent; - - ChunkInfo& newChunk = pFiles[nNumFiles]; - MakeName(newChunk.fileName, desc.pName, chunkNumber, desc.nFlags); - - newChunk.nMipLevel = mip; - - if (chunkNumber != 0) - { - newChunk.nOffsetInFile = 0; - newChunk.nSizeInFile = 0; - newChunk.nSideDelta = 0; - } - else - { - uint32 nFirstPersistentMip = desc.nMips - desc.nMipsPersistent; - uint32 nSurfaceSize = CTexture::TextureDataSize( - max(1u, desc.nWidth >> mip), max(1u, desc.nHeight >> mip), max(1u, desc.nDepth >> mip), - 1, 1, desc.eFormat, desc.eTileMode); - uint32 nSidePitch = CTexture::TextureDataSize( - max(1u, desc.nWidth >> nFirstPersistentMip), max(1u, desc.nHeight >> nFirstPersistentMip), max(1u, desc.nDepth >> nFirstPersistentMip), - desc.nMipsPersistent, 1, desc.eFormat, desc.eTileMode); - uint32 nStartOffset = CTexture::TextureDataSize( - max(1u, desc.nWidth >> nFirstPersistentMip), max(1u, desc.nHeight >> nFirstPersistentMip), max(1u, desc.nDepth >> nFirstPersistentMip), - mip - nFirstPersistentMip, 1, desc.eFormat, desc.eTileMode); - - newChunk.nOffsetInFile = desc.nBaseOffset + nStartOffset; - newChunk.nSizeInFile = nSidePitch * (desc.nSides - 1) + nSurfaceSize; - newChunk.nSideDelta = nSidePitch - nSurfaceSize; - } - - ++nNumFiles; - } - - return nNumFiles; - } - - size_t GetFilesToRead_UnSplit(ChunkInfo* pFiles, size_t nFilesCapacity, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip) - { - FUNCTION_PROFILER_RENDERER; - - assert(nStartMip <= nEndMip); - assert(nEndMip < desc.nMips); - assert(!(desc.nFlags & FIM_SPLITTED)); - - size_t nNumFiles = 0; - - uint32 nSideStart = CTexture::TextureDataSize(desc.nWidth, desc.nHeight, desc.nDepth, nStartMip, 1, desc.eFormat, desc.eTileMode); - uint32 nSidePitch = CTexture::TextureDataSize(desc.nWidth, desc.nHeight, desc.nDepth, desc.nMips, 1, desc.eFormat, desc.eTileMode); - - for (uint32 nMip = nStartMip; nMip <= nEndMip; ++nMip) - { - uint32 nOffset = desc.nBaseOffset + nSideStart; - uint32 nSurfaceSize = CTexture::TextureDataSize( - max(1u, desc.nWidth >> nMip), - max(1u, desc.nHeight >> nMip), - max(1u, desc.nDepth >> nMip), - 1, 1, desc.eFormat, desc.eTileMode); - - if (nNumFiles < nFilesCapacity) - { - pFiles[nNumFiles].fileName = desc.pName; - pFiles[nNumFiles].nMipLevel = nMip; - pFiles[nNumFiles].nOffsetInFile = nOffset; - pFiles[nNumFiles].nSizeInFile = nSidePitch * (desc.nSides - 1) + nSurfaceSize; - pFiles[nNumFiles].nSideDelta = nSidePitch - nSurfaceSize; - } - - ++nNumFiles; - nSideStart += nSurfaceSize; - } - - return nNumFiles; - } - - size_t GetFilesToRead(ChunkInfo* pFiles, size_t nFilesCapacity, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip) - { - return (desc.nFlags & FIM_SPLITTED) - ? GetFilesToRead_Split(pFiles, nFilesCapacity, desc, nStartMip, nEndMip) - : GetFilesToRead_UnSplit(pFiles, nFilesCapacity, desc, nStartMip, nEndMip); - } - - bool SeekToAttachedImage(FileWrapper& file) - { - CImageExtensionHelper::DDS_FILE_DESC ddsFileDesc; - CImageExtensionHelper::DDS_HEADER_DXT10 ddsExtendedHeader; - - if (!file.ReadRaw(&ddsFileDesc, sizeof(ddsFileDesc))) - { - return false; - } - - SwapEndian(ddsFileDesc); - if (!ddsFileDesc.IsValid()) - { - return false; - } - - if (ddsFileDesc.header.IsDX10Ext()) - { - file.ReadRaw(&ddsExtendedHeader, sizeof(CImageExtensionHelper::DDS_HEADER_DXT10)); - } - else - { - memset(&ddsExtendedHeader, 0, sizeof(CImageExtensionHelper::DDS_HEADER_DXT10)); - } - - const uint32 imageFlags = CImageExtensionHelper::GetImageFlags(&ddsFileDesc.header); - - ETEX_Format eTF = DDSFormats::GetFormatByDesc(ddsFileDesc.header.ddspf, ddsExtendedHeader.dxgiFormat); - if (eTF_Unknown == eTF) - { - return false; - } - - ETEX_TileMode eTM = eTM_None; - if (imageFlags & CImageExtensionHelper::EIF_Tiled) - { - switch (ddsFileDesc.header.bTileMode) - { - case CImageExtensionHelper::eTM_LinearPadded: - eTM = eTM_LinearPadded; - break; - - case CImageExtensionHelper::eTM_Optimal: - eTM = eTM_Optimal; - break; - } - } - - uint32 numSlices = (imageFlags& CImageExtensionHelper::EIF_Cubemap) ? 6 : 1; - uint32 ddsSize = CTexture::TextureDataSize(ddsFileDesc.header.dwWidth, ddsFileDesc.header.dwHeight, ddsFileDesc.header.dwDepth, max(static_cast(1), ddsFileDesc.header.dwMipMapCount), numSlices, eTF, eTM); - - size_t headerEnd = file.Tell(); - - file.Seek(headerEnd + ddsSize); - - uint8 tmp[1024]; - file.ReadRaw(tmp, 1024); - - const CImageExtensionHelper::DDS_HEADER* pHdr = CImageExtensionHelper::GetAttachedImage(tmp); - if (pHdr) - { - file.Seek(headerEnd + ddsSize + ((const uint8*)pHdr - tmp)); - return true; - } - - return false; - } - - size_t LoadMipRequests(RequestInfo* pReqs, size_t nReqsCap, const DDSDesc& desc, byte* pBuffer, uint32 nStartMip, uint32 nEndMip) - { - size_t nReqs = 0; - - ChunkInfo names[16]; - size_t nNumNames = GetFilesToRead(names, 16, desc, nStartMip, nEndMip); - if (nNumNames) - { - if (nNumNames * desc.nSides > nReqsCap) - { - __debugbreak(); - } - - for (ChunkInfo* it = names, * itEnd = names + nNumNames; it != itEnd; ++it) - { - const ChunkInfo& chunk = *it; - - uint32 nSideSize = CTexture::TextureDataSize(desc.nWidth, desc.nHeight, desc.nDepth, desc.nMips, 1, desc.eFormat, desc.eTileMode); - uint32 nSideSizeToRead = CTexture::TextureDataSize( - max(1u, desc.nWidth >> chunk.nMipLevel), - max(1u, desc.nHeight >> chunk.nMipLevel), - max(1u, desc.nDepth >> chunk.nMipLevel), - 1, 1, desc.eFormat, desc.eTileMode); - - string sFileName = string(it->fileName); - - uint32 nSrcOffset = chunk.nOffsetInFile; - uint32 nDstOffset = 0; - - for (uint32 iSide = 0; iSide < desc.nSides; ++iSide) - { - pReqs[nReqs].fileName = sFileName; - pReqs[nReqs].nOffs = nSrcOffset; - pReqs[nReqs].nRead = nSideSizeToRead; - pReqs[nReqs].pOut = pBuffer + (nSideSize * iSide) + nDstOffset; - - ++nReqs; - nSrcOffset += nSideSizeToRead + chunk.nSideDelta; - } - - nDstOffset += nSideSizeToRead; - } - } - - return nReqs; - } - - bool LoadMipsFromRequests(const RequestInfo* pReqs, size_t nReqs) - { - using namespace AZ::IO; - - LOADING_TIME_PROFILE_SECTION; - auto streamer = AZ::Interface::Get(); - - struct SharedRequestData - { - IStreamer* m_streamer; - AZStd::atomic_int m_numProcessingRequests; - AZStd::atomic_bool m_succeeded = true; - AZStd::binary_semaphore m_wait; - }; - SharedRequestData sharedData; - sharedData.m_numProcessingRequests = nReqs; - sharedData.m_streamer = streamer; - - AZStd::vector requests; - requests.reserve(nReqs); - streamer->CreateRequestBatch(requests, nReqs); - - auto callback = [&sharedData](FileRequestHandle request) - { - if (sharedData.m_streamer->GetRequestStatus(request) != IStreamerTypes::RequestStatus::Completed) - { - sharedData.m_succeeded = false; - } - if (--sharedData.m_numProcessingRequests == 0) - { - sharedData.m_wait.release(); - } - }; - - // load files - for (size_t i = 0; i < nReqs; ++i) - { - const RequestInfo& req = pReqs[i]; - FileRequestPtr& request = requests[i]; - streamer->Read(request, req.fileName.c_str(), req.pOut, req.nRead, req.nRead, - IStreamerTypes::s_deadlineNow, IStreamerTypes::s_priorityMedium, req.nOffs); - streamer->SetRequestCompleteCallback(request, callback); - } - streamer->QueueRequestBatch(AZStd::move(requests)); - - // Wait for all mips to finish loading - sharedData.m_wait.acquire(); - - if (!sharedData.m_succeeded) - { - AZ_Error("Render", false ,"Couldn't read one or more mip requests during async mip load"); - return false; - } - - return true; - } - - bool LoadMips(byte* pBuffer, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip) - { - bool success = 0; - - RequestInfo reqs[64]; - size_t nReqs = LoadMipRequests(reqs, 64, desc, pBuffer, nStartMip, nEndMip); - - if (nReqs) - { - success = LoadMipsFromRequests(reqs, nReqs); - } - - return success; - } - - int GetNumLastMips([[maybe_unused]] const int nWidth, [[maybe_unused]] const int nHeight, [[maybe_unused]] const int nNumMips, [[maybe_unused]] const int nSides, [[maybe_unused]] ETEX_Format eTF, [[maybe_unused]] const uint32 nFlags) - { - return (int)DDSSplitted::etexNumLastMips; - } -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.h b/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.h deleted file mode 100644 index ec7fbf466e..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/DDSImage.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_DDSIMAGE_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_DDSIMAGE_H -#pragma once - - -#include "ImageExtensionHelper.h" -#include "CImage.h" -#include - -#include -#include -#include -#include -#include - -/** - * An ImageFile subclass for reading DDS files. - */ -namespace DDSSplitted -{ - enum - { - etexNumLastMips = 3, - etexLowerMipMaxSize = (1 << (etexNumLastMips + 2)), // + 2 means we drop all the mips that are less than 4x4(two mips: 2x2 and 1x1) - }; - - struct DDSDesc - { - DDSDesc() - { - memset(this, 0, sizeof(*this)); - } - - const char* pName; - uint32 nBaseOffset; - - uint32 nWidth; - uint32 nHeight; - uint32 nDepth; - uint32 nSides; - uint32 nMips; - uint32 nMipsPersistent; - ETEX_Format eFormat; - ETEX_TileMode eTileMode; - uint32 nFlags; - }; - - typedef CryStackStringT TPath; - - struct ChunkInfo - { - TPath fileName; - uint32 nOffsetInFile; - uint32 nSizeInFile; - uint32 nMipLevel; - uint32 nSideDelta; - }; - - struct RequestInfo - { - string fileName; - void* pOut; - uint32 nOffs; - uint32 nRead; - }; - - struct FileWrapper - { - FileWrapper(const char* fileName, bool storeInMem) - : m_bInMem(storeInMem) - , m_fileName(fileName) - , m_isValid(false) - , m_nRawLen(0) - , m_nSeek(0) - , m_pRaw(nullptr) - , m_cleanup(storeInMem) - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "DDS FileWrapper AZ Streamer"); - AZ::u64 fileSize = 0; - AZ::IO::Result result = AZ::IO::FileIOBase::GetInstance()->Size(fileName, fileSize); - m_nRawLen = (size_t)fileSize; // Cry DDS texture used 32 bits for filesize so cast here - if (result == AZ::IO::ResultCode::Success) - { - m_isValid = true; - if (m_bInMem) - { - m_pRaw = new char[m_nRawLen]; - m_nRawLen = azlossy_caster(ReadBlock(const_cast(m_pRaw), m_nRawLen, 0)); - } - } - } - - ~FileWrapper() - { - if (m_bInMem && m_cleanup && m_pRaw) - { - delete[] m_pRaw; - m_pRaw = nullptr; - } - } - FileWrapper(const void* p, size_t nLen, bool cleanupData = false) - : m_bInMem(true) - , m_pRaw((const char*)p) - , m_nRawLen(nLen) - , m_nSeek(0) - , m_cleanup(cleanupData){} - - bool IsValid() const - { - return m_bInMem - ? m_pRaw != NULL - : m_isValid; - } - - size_t GetLength() const - { - return m_nRawLen; - } - - size_t ReadRaw(void* p, size_t amount) - { - if (m_bInMem) - { - amount = min(m_nRawLen - m_nSeek, amount); - memcpy(p, m_pRaw + m_nSeek, amount); - m_nSeek += amount; - - return amount; - } - else - { - amount = min(m_nRawLen - m_nSeek, amount); - AZ::u64 amountRead = ReadBlock(p, amount, m_nSeek); - m_nSeek += (size_t)amountRead; // Cry DDS texture used 32 bits for filesize so cast here - return amountRead; - } - } - - AZ::u64 ReadBlock(void* address, AZ::u64 size, AZ::u64 offset) - { - auto streamer = AZ::Interface::Get(); - AZStd::binary_semaphore wait; - AZStd::atomic_bool success = true; - - AZ::IO::FileRequestPtr request = streamer->Read(m_fileName, address, size, size, - AZ::IO::IStreamerTypes::s_deadlineNow, AZ::IO::IStreamerTypes::s_priorityMedium, offset); - streamer->SetRequestCompleteCallback(request, [&wait, &success](AZ::IO::FileRequestHandle request) - { - auto streamer = AZ::Interface::Get(); - success = streamer->GetRequestStatus(request) == AZ::IO::IStreamerTypes::RequestStatus::Completed; - wait.release(); - }); - streamer->QueueRequest(AZStd::move(request)); - wait.acquire(); - - return success ? size : 0; - } - - void Seek(size_t offs) - { - m_nSeek = min(offs, m_nRawLen); - } - - size_t Tell() - { - return m_nSeek; - } - - bool m_bInMem; - const char* m_fileName; - - struct - { - bool m_isValid; - bool m_cleanup; - const char* m_pRaw; - size_t m_nRawLen; - size_t m_nSeek; - }; - }; - - typedef std::vector Chunks; - - TPath& MakeName(TPath& sOut, const char* sOriginalName, const uint32 nChunk, const uint32 nFlags); - - size_t GetFilesToRead(ChunkInfo* pFiles, size_t nFilesCapacity, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip); - - bool SeekToAttachedImage(FileWrapper& file); - - size_t LoadMipRequests(RequestInfo* pReqs, size_t nReqsCap, const DDSDesc& desc, byte* pBuffer, uint32 nStartMip, uint32 nEndMip); - bool LoadMipsFromRequests(const RequestInfo* pReqs, size_t nReqs); - bool LoadMips(byte* pBuffer, const DDSDesc& desc, uint32 nStartMip, uint32 nEndMip); - - int GetNumLastMips(const int nWidth, const int nHeight, const int nNumMips, const int nSides, ETEX_Format eTF, const uint32 nFlags); -}; - -class CImageDDSFile - : public CImageFile -{ - friend class CImageFile; // For constructor -public: - CImageDDSFile(const string& filename); - CImageDDSFile (const string& filename, uint32 nFlags); - - bool Stream(uint32 nFlags, IImageFileStreamCallback* pStreamCallback); - - virtual DDSSplitted::DDSDesc mfGet_DDSDesc() const; - -private: // ------------------------------------------------------------------------------ - /// Read the DDS file from the file. - bool LoadFromFile(DDSSplitted::FileWrapper& file, uint32 nFlags, DDSSplitted::RequestInfo* pConts, size_t& nConts, size_t nContsCap); - - /// Read the DDS file from the file. - bool Load(const string& filename, uint32 nFlags); - - void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); - - bool SetHeaderFromMemory(byte* pFileStart, byte* pFileAfterHeader, uint32 nFlags); - int AdjustHeader(); - - bool PostLoad(); - - void AdjustFirstFileName(uint32& nFlags, const char* pFileName, DDSSplitted::TPath& adjustedFileName); - - CImageExtensionHelper::DDS_HEADER m_DDSHeader; - CImageExtensionHelper::DDS_HEADER_DXT10 m_DDSHeaderExtension; - - AZStd::intrusive_ptr m_pFileMemory; -}; - -void WriteDDS(const byte* dat, int wdt, int hgt, int dpth, int Size, char* name, ETEX_Format eF, int NumMips, ETEX_Type eTT); - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_IMAGE_DDSIMAGE_H - - diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/JpgImage.cpp b/Code/CryEngine/RenderDll/Common/Textures/Image/JpgImage.cpp deleted file mode 100644 index d670fb6aaf..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/JpgImage.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include - -namespace ImageUtils -{ - string OutputPath(const char* filename); -} - -namespace JpgImage { - /* public domain Simple, Minimalistic JPEG writer - http://jonolick.com - * - * Quick Notes: - * Based on a javascript jpeg writer - * JPEG baseline (no JPEG progressive) - * Supports 1, 3 or 4 component input. (luminance, RGB or RGBX) - * - * Latest revisions: - * 1.52 (2012-22-11) Added support for specifying Luminance, RGB, or RGBA via comp(onents) argument (1, 3 and 4 respectively). - * 1.51 (2012-19-11) Fixed some warnings - * 1.50 (2012-18-11) MT safe. Simplified. Optimized. Reduced memory requirements. Zero allocations. No namespace polution. Approx 340 lines code. - * 1.10 (2012-16-11) compile fixes, added docs, - * changed from .h to .cpp (simpler to bootstrap), etc - * 1.00 (2012-02-02) initial release - * - * Basic usage: - * char *foo = new char[128*128*4]; // 4 component. RGBX format, where X is unused - * jo_write_jpg("foo.jpg", foo, 128, 128, 4, 90); // comp can be 1, 3, or 4. Lum, RGB, or RGBX respectively. - * - * */ - - - //#include - //#include - //#include - - static const unsigned char s_jo_ZigZag[] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63 }; - - struct joBufferedIO - { - AZ::IO::HandleType fileHandle; - int size; - char buffer[1024]; - }; - - static void jo_flushBuffer(joBufferedIO* io) - { - gEnv->pCryPak->FWrite(io->buffer, io->size, io->fileHandle); - io->size = 0; - } - - static void jo_bufferByte(joBufferedIO* io, unsigned char c) - { - io->buffer[io->size++] = c; - if (io->size == sizeof(io->buffer)) - { - jo_flushBuffer(io); - } - } - - static void jo_writeBits(joBufferedIO* fp, int& bitBuf, int& bitCnt, const unsigned short* bs) - { - - bitCnt += bs[1]; - bitBuf |= bs[0] << (24 - bitCnt); - while (bitCnt >= 8) - { - unsigned char c = (bitBuf >> 16) & 255; - jo_bufferByte(fp, c); - if (c == 255) - { - c = 0; - jo_bufferByte(fp, c); - } - bitBuf <<= 8; - bitCnt -= 8; - } - } - - static void jo_DCT(float& d0, float& d1, float& d2, float& d3, float& d4, float& d5, float& d6, float& d7) - { - float tmp0 = d0 + d7; - float tmp7 = d0 - d7; - float tmp1 = d1 + d6; - float tmp6 = d1 - d6; - float tmp2 = d2 + d5; - float tmp5 = d2 - d5; - float tmp3 = d3 + d4; - float tmp4 = d3 - d4; - - // Even part - float tmp10 = tmp0 + tmp3; // phase 2 - float tmp13 = tmp0 - tmp3; - float tmp11 = tmp1 + tmp2; - float tmp12 = tmp1 - tmp2; - - d0 = tmp10 + tmp11; // phase 3 - d4 = tmp10 - tmp11; - - float z1 = (tmp12 + tmp13) * 0.707106781f; // c4 - d2 = tmp13 + z1; // phase 5 - d6 = tmp13 - z1; - - // Odd part - tmp10 = tmp4 + tmp5; // phase 2 - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - // The rotator is modified from fig 4-8 to avoid extra negations. - float z5 = (tmp10 - tmp12) * 0.382683433f; // c6 - float z2 = tmp10 * 0.541196100f + z5; // c2-c6 - float z4 = tmp12 * 1.306562965f + z5; // c2+c6 - float z3 = tmp11 * 0.707106781f; // c4 - - float z11 = tmp7 + z3; // phase 5 - float z13 = tmp7 - z3; - - d5 = z13 + z2; // phase 6 - d3 = z13 - z2; - d1 = z11 + z4; - d7 = z11 - z4; - } - - static void jo_calcBits(int val, unsigned short bits[2]) - { - int tmp1 = val < 0 ? -val : val; - val = val < 0 ? val - 1 : val; - bits[1] = 1; - while (tmp1 >>= 1) - { - ++bits[1]; - } - bits[0] = val & ((1 << bits[1]) - 1); - } - - static int jo_processDU(joBufferedIO* fp, int& bitBuf, int& bitCnt, float* CDU, float* fdtbl, int DC, const unsigned short HTDC[256][2], const unsigned short HTAC[256][2]) - { - const unsigned short EOB[2] = { HTAC[0x00][0], HTAC[0x00][1] }; - const unsigned short M16zeroes[2] = { HTAC[0xF0][0], HTAC[0xF0][1] }; - - // DCT rows - for (int dataOff = 0; dataOff < 64; dataOff += 8) - { - jo_DCT(CDU[dataOff], CDU[dataOff + 1], CDU[dataOff + 2], CDU[dataOff + 3], CDU[dataOff + 4], CDU[dataOff + 5], CDU[dataOff + 6], CDU[dataOff + 7]); - } - // DCT columns - for (int dataOff = 0; dataOff < 8; ++dataOff) - { - jo_DCT(CDU[dataOff], CDU[dataOff + 8], CDU[dataOff + 16], CDU[dataOff + 24], CDU[dataOff + 32], CDU[dataOff + 40], CDU[dataOff + 48], CDU[dataOff + 56]); - } - // Quantize/descale/zigzag the coefficients - int DU[64]; - for (int i = 0; i < 64; ++i) - { - float v = CDU[i] * fdtbl[i]; - DU[s_jo_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f)); - } - - // Encode DC - int diff = DU[0] - DC; - if (diff == 0) - { - jo_writeBits(fp, bitBuf, bitCnt, HTDC[0]); - } - else - { - unsigned short bits[2]; - jo_calcBits(diff, bits); - jo_writeBits(fp, bitBuf, bitCnt, HTDC[bits[1]]); - jo_writeBits(fp, bitBuf, bitCnt, bits); - } - // Encode ACs - int end0pos = 63; - for (; (end0pos > 0) && (DU[end0pos] == 0); --end0pos) - { - } - // end0pos = first element in reverse order !=0 - if (end0pos == 0) - { - jo_writeBits(fp, bitBuf, bitCnt, EOB); - return DU[0]; - } - for (int i = 1; i <= end0pos; ++i) - { - int startpos = i; - for (; DU[i] == 0 && i <= end0pos; ++i) - { - } - int nrzeroes = i - startpos; - if (nrzeroes >= 16) - { - int lng = nrzeroes >> 4; - for (int nrmarker = 1; nrmarker <= lng; ++nrmarker) - { - jo_writeBits(fp, bitBuf, bitCnt, M16zeroes); - } - nrzeroes &= 15; - } - unsigned short bits[2]; - jo_calcBits(DU[i], bits); - jo_writeBits(fp, bitBuf, bitCnt, HTAC[(nrzeroes << 4) + bits[1]]); - jo_writeBits(fp, bitBuf, bitCnt, bits); - } - if (end0pos != 63) - { - jo_writeBits(fp, bitBuf, bitCnt, EOB); - } - return DU[0]; - } - - bool jo_write_jpg(const char* filename, const void* data, int width, int height, int comp, int quality) - { - // Constants that don't pollute global namespace - static const unsigned char std_dc_luminance_nrcodes[] = {0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; - static const unsigned char std_dc_luminance_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - static const unsigned char std_ac_luminance_nrcodes[] = {0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d}; - static const unsigned char std_ac_luminance_values[] = { - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa - }; - static const unsigned char std_dc_chrominance_nrcodes[] = {0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; - static const unsigned char std_dc_chrominance_values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - static const unsigned char std_ac_chrominance_nrcodes[] = {0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77}; - static const unsigned char std_ac_chrominance_values[] = { - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa - }; - // Huffman tables - static const unsigned short YDC_HT[256][2] = { - {0, 2}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {126, 7}, {254, 8}, {510, 9} - }; - static const unsigned short UVDC_HT[256][2] = { - {0, 2}, {1, 2}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {126, 7}, {254, 8}, {510, 9}, {1022, 10}, {2046, 11} - }; - static const unsigned short YAC_HT[256][2] = { - {10, 4}, {0, 2}, {1, 2}, {4, 3}, {11, 4}, {26, 5}, {120, 7}, {248, 8}, {1014, 10}, {65410, 16}, {65411, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {12, 4}, {27, 5}, {121, 7}, {502, 9}, {2038, 11}, {65412, 16}, {65413, 16}, {65414, 16}, {65415, 16}, {65416, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {28, 5}, {249, 8}, {1015, 10}, {4084, 12}, {65417, 16}, {65418, 16}, {65419, 16}, {65420, 16}, {65421, 16}, {65422, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {58, 6}, {503, 9}, {4085, 12}, {65423, 16}, {65424, 16}, {65425, 16}, {65426, 16}, {65427, 16}, {65428, 16}, {65429, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {59, 6}, {1016, 10}, {65430, 16}, {65431, 16}, {65432, 16}, {65433, 16}, {65434, 16}, {65435, 16}, {65436, 16}, {65437, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {122, 7}, {2039, 11}, {65438, 16}, {65439, 16}, {65440, 16}, {65441, 16}, {65442, 16}, {65443, 16}, {65444, 16}, {65445, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {123, 7}, {4086, 12}, {65446, 16}, {65447, 16}, {65448, 16}, {65449, 16}, {65450, 16}, {65451, 16}, {65452, 16}, {65453, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {250, 8}, {4087, 12}, {65454, 16}, {65455, 16}, {65456, 16}, {65457, 16}, {65458, 16}, {65459, 16}, {65460, 16}, {65461, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {504, 9}, {32704, 15}, {65462, 16}, {65463, 16}, {65464, 16}, {65465, 16}, {65466, 16}, {65467, 16}, {65468, 16}, {65469, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {505, 9}, {65470, 16}, {65471, 16}, {65472, 16}, {65473, 16}, {65474, 16}, {65475, 16}, {65476, 16}, {65477, 16}, {65478, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {506, 9}, {65479, 16}, {65480, 16}, {65481, 16}, {65482, 16}, {65483, 16}, {65484, 16}, {65485, 16}, {65486, 16}, {65487, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {1017, 10}, {65488, 16}, {65489, 16}, {65490, 16}, {65491, 16}, {65492, 16}, {65493, 16}, {65494, 16}, {65495, 16}, {65496, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {1018, 10}, {65497, 16}, {65498, 16}, {65499, 16}, {65500, 16}, {65501, 16}, {65502, 16}, {65503, 16}, {65504, 16}, {65505, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {2040, 11}, {65506, 16}, {65507, 16}, {65508, 16}, {65509, 16}, {65510, 16}, {65511, 16}, {65512, 16}, {65513, 16}, {65514, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {65515, 16}, {65516, 16}, {65517, 16}, {65518, 16}, {65519, 16}, {65520, 16}, {65521, 16}, {65522, 16}, {65523, 16}, {65524, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {2041, 11}, {65525, 16}, {65526, 16}, {65527, 16}, {65528, 16}, {65529, 16}, {65530, 16}, {65531, 16}, {65532, 16}, {65533, 16}, {65534, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} - }; - static const unsigned short UVAC_HT[256][2] = { - {0, 2}, {1, 2}, {4, 3}, {10, 4}, {24, 5}, {25, 5}, {56, 6}, {120, 7}, {500, 9}, {1014, 10}, {4084, 12}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {11, 4}, {57, 6}, {246, 8}, {501, 9}, {2038, 11}, {4085, 12}, {65416, 16}, {65417, 16}, {65418, 16}, {65419, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {26, 5}, {247, 8}, {1015, 10}, {4086, 12}, {32706, 15}, {65420, 16}, {65421, 16}, {65422, 16}, {65423, 16}, {65424, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {27, 5}, {248, 8}, {1016, 10}, {4087, 12}, {65425, 16}, {65426, 16}, {65427, 16}, {65428, 16}, {65429, 16}, {65430, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {58, 6}, {502, 9}, {65431, 16}, {65432, 16}, {65433, 16}, {65434, 16}, {65435, 16}, {65436, 16}, {65437, 16}, {65438, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {59, 6}, {1017, 10}, {65439, 16}, {65440, 16}, {65441, 16}, {65442, 16}, {65443, 16}, {65444, 16}, {65445, 16}, {65446, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {121, 7}, {2039, 11}, {65447, 16}, {65448, 16}, {65449, 16}, {65450, 16}, {65451, 16}, {65452, 16}, {65453, 16}, {65454, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {122, 7}, {2040, 11}, {65455, 16}, {65456, 16}, {65457, 16}, {65458, 16}, {65459, 16}, {65460, 16}, {65461, 16}, {65462, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {249, 8}, {65463, 16}, {65464, 16}, {65465, 16}, {65466, 16}, {65467, 16}, {65468, 16}, {65469, 16}, {65470, 16}, {65471, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {503, 9}, {65472, 16}, {65473, 16}, {65474, 16}, {65475, 16}, {65476, 16}, {65477, 16}, {65478, 16}, {65479, 16}, {65480, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {504, 9}, {65481, 16}, {65482, 16}, {65483, 16}, {65484, 16}, {65485, 16}, {65486, 16}, {65487, 16}, {65488, 16}, {65489, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {505, 9}, {65490, 16}, {65491, 16}, {65492, 16}, {65493, 16}, {65494, 16}, {65495, 16}, {65496, 16}, {65497, 16}, {65498, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {506, 9}, {65499, 16}, {65500, 16}, {65501, 16}, {65502, 16}, {65503, 16}, {65504, 16}, {65505, 16}, {65506, 16}, {65507, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {2041, 11}, {65508, 16}, {65509, 16}, {65510, 16}, {65511, 16}, {65512, 16}, {65513, 16}, {65514, 16}, {65515, 16}, {65516, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {16352, 14}, {65517, 16}, {65518, 16}, {65519, 16}, {65520, 16}, {65521, 16}, {65522, 16}, {65523, 16}, {65524, 16}, {65525, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, - {1018, 10}, {32707, 15}, {65526, 16}, {65527, 16}, {65528, 16}, {65529, 16}, {65530, 16}, {65531, 16}, {65532, 16}, {65533, 16}, {65534, 16}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} - }; - static const int YQT[] = {16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99}; - static const int UVQT[] = {17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}; - static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; - - if (!data || !filename || !width || !height || comp > 4 || comp < 1 || comp == 2) - { - return false; - } - - auto pCryPak = gEnv->pCryPak; - - string fullPath = ImageUtils::OutputPath(filename); - filename = fullPath.c_str(); - - AZ::IO::HandleType fileHandle = pCryPak->FOpen(filename, "wb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - quality = quality ? quality : 90; - quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; - quality = quality < 50 ? 5000 / quality : 200 - quality * 2; - - unsigned char YTable[64], UVTable[64]; - for (int i = 0; i < 64; ++i) - { - int yti = (YQT[i] * quality + 50) / 100; - YTable[s_jo_ZigZag[i]] = yti < 1 ? 1 : yti > 255 ? 255 : yti; - int uvti = (UVQT[i] * quality + 50) / 100; - UVTable[s_jo_ZigZag[i]] = uvti < 1 ? 1 : uvti > 255 ? 255 : uvti; - } - - float fdtbl_Y[64], fdtbl_UV[64]; - for (int row = 0, k = 0; row < 8; ++row) - { - for (int col = 0; col < 8; ++col, ++k) - { - fdtbl_Y[k] = 1 / (YTable [s_jo_ZigZag[k]] * aasf[row] * aasf[col]); - fdtbl_UV[k] = 1 / (UVTable[s_jo_ZigZag[k]] * aasf[row] * aasf[col]); - } - } - - // Write Headers - static const unsigned char head0[] = { 0xFF, 0xD8, 0xFF, 0xE0, 0, 0x10, 'J', 'F', 'I', 'F', 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0xFF, 0xDB, 0, 0x84, 0 }; - pCryPak->FWrite(head0, sizeof(head0), 1, fileHandle); - pCryPak->FWrite(YTable, sizeof(YTable), 1, fileHandle); - unsigned char ch = 1; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); - pCryPak->FWrite(UVTable, sizeof(UVTable), 1, fileHandle); - const unsigned char head1[] = { 0xFF, 0xC0, 0, 0x11, 8, aznumeric_caster(height >> 8), aznumeric_caster(height & 0xFF), aznumeric_caster(width >> 8), aznumeric_caster(width & 0xFF), 3, 1, 0x11, 0, 2, 0x11, 1, 3, 0x11, 1, 0xFF, 0xC4, 0x01, 0xA2, 0 }; - pCryPak->FWrite(head1, sizeof(head1), 1, fileHandle); - pCryPak->FWrite(std_dc_luminance_nrcodes + 1, sizeof(std_dc_luminance_nrcodes) - 1, 1, fileHandle); - pCryPak->FWrite(std_dc_luminance_values, sizeof(std_dc_luminance_values), 1, fileHandle); - ch = 0x10; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); // HTYACinfo - pCryPak->FWrite(std_ac_luminance_nrcodes + 1, sizeof(std_ac_luminance_nrcodes) - 1, 1, fileHandle); - pCryPak->FWrite(std_ac_luminance_values, sizeof(std_ac_luminance_values), 1, fileHandle); - ch = 1; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); // HTUDCinfo - pCryPak->FWrite(std_dc_chrominance_nrcodes + 1, sizeof(std_dc_chrominance_nrcodes) - 1, 1, fileHandle); - pCryPak->FWrite(std_dc_chrominance_values, sizeof(std_dc_chrominance_values), 1, fileHandle); - ch = 0x11; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); // HTUACinfo - pCryPak->FWrite(std_ac_chrominance_nrcodes + 1, sizeof(std_ac_chrominance_nrcodes) - 1, 1, fileHandle); - pCryPak->FWrite(std_ac_chrominance_values, sizeof(std_ac_chrominance_values), 1, fileHandle); - static const unsigned char head2[] = { 0xFF, 0xDA, 0, 0xC, 3, 1, 0, 2, 0x11, 3, 0x11, 0, 0x3F, 0 }; - pCryPak->FWrite(head2, sizeof(head2), 1, fileHandle); - - joBufferedIO io; - io.fileHandle = fileHandle; - io.size = 0; - - // Encode 8x8 macroblocks - const unsigned char* imageData = (const unsigned char*)data; - int DCY = 0, DCU = 0, DCV = 0; - int bitBuf = 0, bitCnt = 0; - int ofsG = comp > 1 ? 1 : 0, ofsB = comp > 1 ? 2 : 0; - for (int y = 0; y < height; y += 8) - { - for (int x = 0; x < width; x += 8) - { - float YDU[64], UDU[64], VDU[64]; - for (int row = y, pos = 0; row < y + 8; ++row) - { - for (int col = x; col < x + 8; ++col, ++pos) - { - int p = row * width * comp + col * comp; - if (row >= height) - { - p -= width * comp * (row + 1 - height); - } - if (col >= width) - { - p -= comp * (col + 1 - width); - } - - float r = imageData[p + 0], g = imageData[p + ofsG], b = imageData[p + ofsB]; - YDU[pos] = +0.29900f * r + 0.58700f * g + 0.11400f * b - 128; - UDU[pos] = -0.16874f * r - 0.33126f * g + 0.50000f * b; - VDU[pos] = +0.50000f * r - 0.41869f * g - 0.08131f * b; - } - } - - DCY = jo_processDU(&io, bitBuf, bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); - DCU = jo_processDU(&io, bitBuf, bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); - DCV = jo_processDU(&io, bitBuf, bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); - } - } - - // Do the bit alignment of the EOI marker - static const unsigned short fillBits[] = {0x7F, 7}; - jo_writeBits(&io, bitBuf, bitCnt, fillBits); - jo_flushBuffer(&io); - - // EOI - ch = 0xFF; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); - ch = 0xD9; - pCryPak->FWrite(&ch, sizeof(ch), fileHandle); - - pCryPak->FClose(fileHandle); - return true; - } -} // namespace JpgImage - - -////////////////////////////////////////////////////////////////////////// - -bool WriteJPG(const byte* dat, int wdt, int hgt, const char* name, int bpp, int nQuality) -{ -#if defined(AZ_PLATFORMS_APPLE_IOS) - return false; -#else - return JpgImage::jo_write_jpg(name, dat, wdt, hgt, bpp >> 3, nQuality); -#endif -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/Image/TgaImage.cpp b/Code/CryEngine/RenderDll/Common/Textures/Image/TgaImage.cpp deleted file mode 100644 index 5e1f2f3c1f..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Image/TgaImage.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include // for AZ_MAX_PATH_LEN -#include - -static AZ::IO::HandleType sFileHandle; - -namespace ImageUtils -{ - string OutputPath(const char* filename) - { - char resolvedPath[AZ_MAX_PATH_LEN]; - if (!AZ::IO::FileIOBase::GetInstance()->ResolvePath(filename, resolvedPath, AZ_MAX_PATH_LEN)) - { - return ""; - } - string fullPath(resolvedPath); - return fullPath; - } -} - -static void bwrite(unsigned char data) -{ - byte d[2]; - d[0] = data; - - gEnv->pCryPak->FWrite(d, 1, 1, sFileHandle); -} - -void wwrite(unsigned short data) -{ - unsigned char h, l; - - l = data & 0xFF; - h = data >> 8; - bwrite(l); - bwrite(h); -} - - -static void WritePixel(int depth, unsigned long a, unsigned long r, unsigned long g, unsigned long b) -{ - DWORD color16; - - switch (depth) - { - case 32: - bwrite((byte)b); // b - bwrite((byte)g); // g - bwrite((byte)r); // r - bwrite((byte)a); // a - break; - - case 24: - bwrite((byte)b); // b - bwrite((byte)g); // g - bwrite((byte)r); // r - break; - - case 16: - r >>= 3; - g >>= 3; - b >>= 3; - - r &= 0x1F; - g &= 0x1F; - b &= 0x1F; - - color16 = (r << 10) | (g << 5) | b; - - wwrite((unsigned short)color16); - break; - } -} - -static void GetPixel(const byte* data, int depth, unsigned long& a, unsigned long& r, unsigned long& g, unsigned long& b) -{ - switch (depth) - { - case 32: - r = *data++; - g = *data++; - b = *data++; - a = *data++; - break; - - case 24: - r = *data++; - g = *data++; - b = *data++; - a = 0xFF; - break; - - default: - assert(0); - break; - } -} - -bool WriteTGA(const byte* data, int width, int height, const char* filename, int src_bits_per_pixel, int dest_bits_per_pixel) -{ -#if defined(AZ_PLATFORMS_APPLE_IOS) || defined(AZ_PLATFORM_LINUX) - return false; -#else - int i; - unsigned long r, g, b, a; - - if ((sFileHandle = gEnv->pCryPak->FOpen(filename, "wb")) == AZ::IO::InvalidHandle) - { - return false; - } - - int id_length = 0; - int x_org = 0; - int y_org = 0; - int desc = 0x20; // origin is upper left - - // 32 bpp - - int cm_index = 0; - int cm_length = 0; - int cm_entry_size = 0; - int color_map_type = 0; - - int type = 2; - - bwrite(id_length); - bwrite(color_map_type); - bwrite(type); - - wwrite(cm_index); - wwrite(cm_length); - - bwrite(cm_entry_size); - - wwrite(x_org); - wwrite(y_org); - wwrite((unsigned short)width); - wwrite((unsigned short)height); - - bwrite(dest_bits_per_pixel); - - bwrite(desc); - - int hxw = height * width; - - - - const DWORD* swap = 0; - - UINT src_bytes_per_pixel = src_bits_per_pixel / 8; - - - if (src_bits_per_pixel == dest_bits_per_pixel) - { -#if defined(NEED_ENDIAN_SWAP) - byte* d = new byte [hxw * 4]; - memcpy(d, data, hxw * 4); - SwapEndian((uint32*)d, hxw); - gEnv->pCryPak->FWrite(d, hxw, src_bytes_per_pixel, sFileHandle); - SAFE_DELETE_ARRAY(d); -#else - gEnv->pCryPak->FWrite(data, hxw, src_bytes_per_pixel, sFileHandle); -#endif - } - else - { - for (i = 0; i < hxw; i++) - { - GetPixel(data, src_bits_per_pixel, a, b, g, r); - WritePixel(dest_bits_per_pixel, a, b, g, r); - data += src_bytes_per_pixel; - } - } - - gEnv->pCryPak->FClose(sFileHandle); - - SAFE_DELETE_ARRAY(swap); - return true; -#endif -} - diff --git a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.cpp b/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.cpp deleted file mode 100644 index 1650063f27..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.cpp +++ /dev/null @@ -1,887 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "PlanningTextureStreamer.h" - -#include "TextureStreamPool.h" - -#ifndef CHK_RENDTH -#define CHK_RENDTH assert(gRenDev->m_pRT->IsRenderThread()) -#endif - -CPlanningTextureStreamer::CPlanningTextureStreamer() - : m_state(S_Idle) - , m_nRTList(0) - , m_nJobList(1) - , m_nBias(0) - , m_nStreamAllocFails(0) - , m_bOverBudget(false) - , m_nPrevListSize(0) -{ - m_schedule.requestList.reserve(1024); - m_schedule.trimmableList.reserve(4096); - m_schedule.unlinkList.reserve(4096); - m_schedule.actionList.reserve(4096); - -#if defined(TEXSTRM_DEFER_UMR) - m_updateMipRequests[0].reserve(8192); - m_updateMipRequests[1].reserve(8192); -#endif - - memset(m_umrState.arrRoundIds, 0, sizeof(m_umrState.arrRoundIds)); - memset(&m_sortState, 0, sizeof(m_sortState)); -} - -void CPlanningTextureStreamer::BeginUpdateSchedule() -{ - CryAutoLock lock(m_lock); - - if (m_state != S_Idle) - { - return; - } - - ITextureStreamer::BeginUpdateSchedule(); - - TStreamerTextureVec& textures = GetTextures(); - - IF_UNLIKELY (textures.empty()) - { - return; - } - - SPlanningSortState& sortInput = m_sortState; - - sortInput.pTextures = &textures; - sortInput.nTextures = textures.size(); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texturesstreamingSuppress) - { - m_state = S_QueuedForSync; - return; - } - - std::swap(m_nJobList, m_nRTList); - - SPlanningMemoryState ms = GetMemoryState(); - - // set up the limits - const SThreadInfo& ti = gRenDev->m_RP.m_TI[gRenDev->m_pRT->GetThreadList()]; - - SPlanningScheduleState& schedule = m_schedule; - - schedule.requestList.resize(0); - schedule.trimmableList.resize(0); - schedule.unlinkList.resize(0); - schedule.actionList.resize(0); - - sortInput.nStreamLimit = ms.nStreamLimit; - for (int z = 0; z < sizeof(sortInput.arrRoundIds) / sizeof(sortInput.arrRoundIds[0]); ++z) - { - sortInput.arrRoundIds[z] = ti.m_arrZonesRoundId[z] - CRenderer::CV_r_texturesstreamingPrecacheRounds; - } - sortInput.nFrameId = ti.m_nFrameUpdateID; - sortInput.nBias = m_nBias; - -#if defined(TEXSTRM_BYTECENTRIC_MEMORY) - if (CTexture::s_bPrestreamPhase) - { - sortInput.fpMinBias = 1 << 8; - sortInput.fpMaxBias = 1 << 8; - } - else -#endif - { - sortInput.fpMinBias = -(8 << 8); - sortInput.fpMaxBias = 1 << 8; - } - - sortInput.fpMinMip = GetMinStreamableMip() << 8; - sortInput.memState = ms; - - sortInput.nBalancePoint = 0; - sortInput.nOnScreenPoint = 0; - sortInput.nPrecachedTexs = 0; - sortInput.nListSize = 0; - - sortInput.pRequestList = &schedule.requestList; - sortInput.pTrimmableList = &schedule.trimmableList; - sortInput.pUnlinkList = &schedule.unlinkList; - sortInput.pActionList = &schedule.actionList; - - SPlanningUMRState& umrState = m_umrState; - for (int i = 0; i < MAX_PREDICTION_ZONES; ++i) - { - umrState.arrRoundIds[i] = ti.m_arrZonesRoundId[i]; - } - - m_state = S_QueuedForUpdate; - - if (CRenderer::CV_r_texturesstreamingJobUpdate) - { - StartUpdateJob(); - } - else - { - Job_UpdateEntry(); - } - -#if defined(TEXSTRM_DEFER_UMR) - m_updateMipRequests[m_nRTList].resize(0); -#endif -} - -void CPlanningTextureStreamer::ApplySchedule(EApplyScheduleFlags asf) -{ - CHK_RENDTH; - - FUNCTION_PROFILER_RENDERER; - - CryAutoLock lock(m_lock); - - SyncWithJob_Locked(); - - SPlanningScheduleState& schedule = m_schedule; - - switch (m_state) - { - case S_QueuedForSchedule: - break; - - case S_QueuedForScheduleDiscard: - schedule.trimmableList.resize(0); - schedule.unlinkList.resize(0); - schedule.requestList.resize(0); - schedule.actionList.resize(0); - m_state = S_Idle; - break; - - default: - ITextureStreamer::ApplySchedule(asf); - return; - } - - TStreamerTextureVec& textures = GetTextures(); - TStreamerTextureVec& trimmable = schedule.trimmableList; - TStreamerTextureVec& unlinkList = schedule.unlinkList; - TPlanningActionVec& actions = schedule.actionList; - TPlanningTextureReqVec& requested = schedule.requestList; - - for (TPlanningActionVec::iterator it = actions.begin(), itEnd = actions.end(); it != itEnd; ++it) - { - CTexture* pTex = textures[it->nTexture]; - - switch (it->eAction) - { - case SPlanningAction::Abort: - { - if (pTex->IsStreaming()) - { - STexStreamInState* pSIS = CTexture::s_StreamInTasks.GetPtrFromIdx(pTex->m_nStreamSlot & CTexture::StreamIdxMask); - pSIS->m_bAborted = true; - } - } - break; - } - } - - ITextureStreamer::ApplySchedule(asf); - - { - bool bOverflow = m_nStreamAllocFails > 0; - m_nStreamAllocFails = 0; - - int nMaxItemsToFree = bOverflow ? 1000 : 2; - size_t nGCLimit = schedule.memState.nMemLimit; -#if !defined(CONSOLE) - nGCLimit = static_cast(static_cast(nGCLimit) * 120 / 100); -#endif - size_t nPoolSize = CTexture::s_pPoolMgr->GetReservedSize(); - CTexture::s_pPoolMgr->GarbageCollect(&nPoolSize, nGCLimit, nMaxItemsToFree); - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreamingSuppress) - { -#ifndef NULL_RENDERER - ptrdiff_t nMemFreeUpper = schedule.memState.nMemFreeUpper; - ptrdiff_t nMemFreeLower = schedule.memState.nMemFreeLower; - int nBalancePoint = schedule.nBalancePoint; - - // Everything < nBalancePoint can only be trimmed (trimmable list), everything >= nBalancePoint can be kicked - // We should be able to load everything in the requested list - - int nKickIdx = (int)textures.size() - 1; - int nNumSubmittedLoad = CTexture::s_nMipsSubmittedToStreaming; - size_t nAmtSubmittedLoad = CTexture::s_nBytesSubmittedToStreaming; - - if (!requested.empty()) - { - size_t nMaxRequestedBytes = CTexture::s_bPrestreamPhase - ? 1024 * 1024 * 1024 - : (size_t)(CRenderer::CV_r_TexturesStreamingMaxRequestedMB * 1024.f * 1024.f); - int nMaxRequestedJobs = CTexture::s_bPrestreamPhase - ? CTexture::MaxStreamTasks - : CRenderer::CV_r_TexturesStreamingMaxRequestedJobs; - - const int posponeThresholdKB = (CRenderer::CV_r_texturesstreamingPostponeMips && !CTexture::s_bStreamingFromHDD) ? (CRenderer::CV_r_texturesstreamingPostponeThresholdKB * 1024) : INT_MAX; - const int posponeThresholdMip = (CRenderer::CV_r_texturesstreamingPostponeMips) ? CRenderer::CV_r_texturesstreamingPostponeThresholdMip : 0; - const int nMinimumMip = max(posponeThresholdMip, (int)(CRenderer::CV_r_TexturesStreamingMipBias + gRenDev->m_fTexturesStreamingGlobalMipFactor)); - - if (gRenDev->m_nFlushAllPendingTextureStreamingJobs && nMaxRequestedBytes && nMaxRequestedJobs) - { - nMaxRequestedBytes = 1024 * 1024 * 1024; - nMaxRequestedJobs = 1024 * 1024; - --gRenDev->m_nFlushAllPendingTextureStreamingJobs; - } - - bool bPreStreamPhase = CTexture::s_bPrestreamPhase; - - IStreamEngine* pStreamEngine = gEnv->pSystem->GetStreamEngine(); - - pStreamEngine->BeginReadGroup(); - - for ( - int nReqIdx = 0, nReqCount = (int)requested.size(); - nReqIdx < nReqCount && - CTexture::s_StreamInTasks.GetNumFree() > 0 && - nNumSubmittedLoad < nMaxRequestedJobs && - nAmtSubmittedLoad < nMaxRequestedBytes - ; - ++nReqIdx) - { - CTexture* pTex = requested[nReqIdx].first; - IF_UNLIKELY (!pTex->m_bStreamed) - { - continue; - } - - int nTexRequestedMip = requested[nReqIdx].second; - - int nTexPersMip = pTex->m_nMips - pTex->m_CacheFileHeader.m_nMipsPersistent; - int nTexWantedMip = min(nTexRequestedMip, nTexPersMip); - int nTexAvailMip = pTex->m_nMinMipVidUploaded; - - STexMipHeader* pMH = pTex->m_pFileTexMips->m_pMipHeader; - int nSides = (pTex->m_nFlags & FT_REPLICATE_TO_ALL_SIDES) ? 1 : pTex->m_CacheFileHeader.m_nSides; - - if (!bPreStreamPhase) - { - // Don't load top mips unless the top mip is the only mip we want - const int nMipSizeLargest = pMH[nTexWantedMip].m_SideSize * nSides; - if ((nMipSizeLargest >= posponeThresholdKB || posponeThresholdMip > nTexWantedMip) && nTexWantedMip < min(nTexPersMip, nTexAvailMip - 1)) - { - ++nTexWantedMip; - } - } - else - { - if (nTexWantedMip == 0) - { - ++nTexWantedMip; - } - } - - if (nTexWantedMip < nTexAvailMip) - { - if (!(pTex->CTexture::GetFlags() & FT_COMPOSITE)) - { - if (!TryBegin_FromDisk( - pTex, nTexPersMip, nTexWantedMip, nTexAvailMip, schedule.nBias, nBalancePoint, - textures, trimmable, nMemFreeLower, nMemFreeUpper, nKickIdx, - nNumSubmittedLoad, nAmtSubmittedLoad)) - { - break; - } - } - else - { - if (!TryBegin_Composite( - pTex, nTexPersMip, nTexWantedMip, nTexAvailMip, schedule.nBias, nBalancePoint, - textures, trimmable, nMemFreeLower, nMemFreeUpper, nKickIdx, - nNumSubmittedLoad, nAmtSubmittedLoad)) - { - break; - } - } - } - } - - pStreamEngine->EndReadGroup(); - } - - CTexture::s_nStatsAllocFails = m_nStreamAllocFails; -#endif - } - else - { - for (TStreamerTextureVec::iterator it = textures.begin(), itEnd = textures.end(); it != itEnd; ++it) - { - CTexture* pTex = *it; - if (!pTex->IsStreamingInProgress()) - { - int nPersMip = pTex->GetNumMipsNonVirtual() - pTex->GetNumPersistentMips(); - if (pTex->StreamGetLoadedMip() < nPersMip) - { - pTex->StreamTrim(nPersMip); - } - } - } - } - - for (TStreamerTextureVec::const_iterator it = unlinkList.begin(), itEnd = unlinkList.end(); it != itEnd; ++it) - { - CTexture* pTexture = *it; - Unlink(pTexture); - } - - trimmable.resize(0); - unlinkList.resize(0); - requested.resize(0); - actions.resize(0); - - m_state = S_Idle; -} - -#ifndef NULL_RENDERER -bool CPlanningTextureStreamer::TryBegin_FromDisk(CTexture* pTex, uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint, - TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, - ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx, - int& nNumSubmittedLoad, size_t& nAmtSubmittedLoad) -{ - uint32 nTexActivateMip = clamp_tpl((uint32)pTex->GetRequiredMipNonVirtual(), nTexWantedMip, nTexPersMip); - int estp = CTexture::s_bStreamingFromHDD ? estpNormal : estpBelowNormal; - - if (pTex->IsStreamHighPriority()) - { - --estp; - } - - if (nTexActivateMip < nTexAvailMip) - { - // Split stream tasks so that mips needed for the working set are loaded first, then additional - // mips for caching can be loaded next time around. - nTexWantedMip = max(nTexWantedMip, nTexActivateMip); - } - - if (nTexWantedMip < nTexActivateMip) - { - // Caching additional mips - no need to request urgently. - ++estp; - } - - - ptrdiff_t nRequired = pTex->StreamComputeDevDataSize(nTexWantedMip) - pTex->StreamComputeDevDataSize(nTexAvailMip); - - STexPoolItem* pNewPoolItem = NULL; - - int nTexWantedMips = pTex->m_nMips - nTexWantedMip; - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) - // First, try and allocate an existing texture that we own - don't allow D3D textures to be made yet - pNewPoolItem = pTex->StreamGetPoolItem(nTexWantedMip, nTexWantedMips, false, false, false); - - if (!pNewPoolItem) - { - STexPool* pPrioritisePool = pTex->StreamGetPool(nTexWantedMip, pTex->m_nMips - nTexWantedMip); - - // That failed, so try and find a trimmable texture with the dimensions we want - if (TrimTexture(nBias, trimmable, pPrioritisePool)) - { - // Found a trimmable texture that matched - now wait for the next update, when it should be done - return true; - } - } -#endif - - bool bShouldStopRequesting = false; - - if (!pNewPoolItem && nRequired > nMemFreeUpper) - { - // Not enough room in the pool. Can we trim some existing textures? - ptrdiff_t nFreed = TrimTextures(nRequired - nMemFreeLower, nBias, trimmable); - nMemFreeLower += nFreed; - nMemFreeUpper += nFreed; - - if (nRequired > nMemFreeUpper) - { - ptrdiff_t nKicked = KickTextures(&textures[0], nRequired - nMemFreeLower, nBalancePoint, nKickIdx); - - nMemFreeLower += nKicked; - nMemFreeUpper += nKicked; - } - } - else - { - // The requested job may be for a force-stream-high-res texture that only has persistent mips. - // However texture kicking may have already evicted it to make room for another texture, and as such, - // streaming may now be in progress, even though it wasn't when the request was queued. - if (!pTex->IsStreaming()) - { - // There should be room in the pool, so try and start streaming. - - bool bRequestStreaming = true; - - if (!pNewPoolItem) - { - pNewPoolItem = pTex->StreamGetPoolItem(nTexWantedMip, nTexWantedMips, false); - } - - if (!pNewPoolItem) - { - bRequestStreaming = false; - } - - if (bRequestStreaming) - { - if (CTexture::StartStreaming(pTex, pNewPoolItem, nTexWantedMip, nTexAvailMip - 1, nTexActivateMip, static_cast(estp))) - { - nMemFreeUpper -= nRequired; - nMemFreeLower -= nRequired; - - ++nNumSubmittedLoad; - nAmtSubmittedLoad += nRequired; - } - - // StartStreaming takes ownership - pNewPoolItem = NULL; - } - else - { - bShouldStopRequesting = true; - } - } - } - - if (pNewPoolItem) - { - CTexture::s_pPoolMgr->ReleaseItem(pNewPoolItem); - } - - if (bShouldStopRequesting) - { - return false; - } - - return true; -} - -bool CPlanningTextureStreamer::TryBegin_Composite(CTexture* pTex, [[maybe_unused]] uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint, - TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, - ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx, - [[maybe_unused]] int& nNumSubmittedLoad, [[maybe_unused]] size_t& nAmtSubmittedLoad) -{ - - ptrdiff_t nRequired = pTex->StreamComputeDevDataSize(nTexWantedMip) - pTex->StreamComputeDevDataSize(nTexAvailMip); - - // Test source textures, to ensure they're all ready. - - DynArray& composite = pTex->m_composition; - - for (int i = 0, c = composite.size(); i != c; ++i) - { - const STexComposition& tc = composite[i]; - CTexture* p = (CTexture*)&*tc.pTexture; - if (p->StreamGetLoadedMip() > nTexWantedMip) - { - // Source isn't ready yet. Try again later. - return true; - } - } - - STexPoolItem* pNewPoolItem = NULL; - - int nTexWantedMips = pTex->m_nMips - nTexWantedMip; - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) - // First, try and allocate an existing texture that we own - don't allow D3D textures to be made yet - pNewPoolItem = pTex->StreamGetPoolItem(nTexWantedMip, nTexWantedMips, false, false, false); - - if (!pNewPoolItem) - { - STexPool* pPrioritisePool = pTex->StreamGetPool(nTexWantedMip, pTex->m_nMips - nTexWantedMip); - - // That failed, so try and find a trimmable texture with the dimensions we want - if (TrimTexture(nBias, trimmable, pPrioritisePool)) - { - // Found a trimmable texture that matched - now wait for the next update, when it should be done - return true; - } - } -#endif - - if (!pNewPoolItem && nRequired > nMemFreeUpper) - { - // Not enough room in the pool. Can we trim some existing textures? - ptrdiff_t nFreed = TrimTextures(nRequired - nMemFreeLower, nBias, trimmable); - nMemFreeLower += nFreed; - nMemFreeUpper += nFreed; - - if (nRequired > nMemFreeUpper) - { - ptrdiff_t nKicked = KickTextures(&textures[0], nRequired - nMemFreeLower, nBalancePoint, nKickIdx); - - nMemFreeLower += nKicked; - nMemFreeUpper += nKicked; - } - } - else if (!pTex->IsStreaming()) - { - // Bake! - - if (!pNewPoolItem) - { - pNewPoolItem = pTex->StreamGetPoolItem(nTexWantedMip, nTexWantedMips, false); - } - - if (pNewPoolItem) - { - for (int i = 0, c = composite.size(); i != c; ++i) - { - const STexComposition& tc = composite[i]; - CTexture* p = (CTexture*)&*tc.pTexture; - CDeviceTexture* pSrcDevTex = p->m_pDevTexture; - uint32 nSrcDevMips = p->GetNumMipsNonVirtual() - p->StreamGetLoadedMip(); - - CTexture::CopySliceChain( - pNewPoolItem->m_pDevTexture, pNewPoolItem->m_pOwner->m_nMips, tc.nDstSlice, 0, - pSrcDevTex, tc.nSrcSlice, nTexWantedMip - (pTex->m_nMips - nSrcDevMips), nSrcDevMips, - pTex->m_nMips - nTexWantedMip); - } - - // Commit! - - pTex->StreamAssignPoolItem(pNewPoolItem, nTexWantedMip); - pNewPoolItem = NULL; - } - } - - if (pNewPoolItem) - { - CTexture::s_pPoolMgr->ReleaseItem(pNewPoolItem); - } - - return true; -} -#endif - -bool CPlanningTextureStreamer::BeginPrepare(CTexture* pTexture, const char* sFilename, uint32 nFlags) -{ - CryAutoLock lock(m_lock); - - STexStreamPrepState** pState = CTexture::s_StreamPrepTasks.Allocate(); - if (pState) - { - // Initialise prep state privately, in case any concurrent prep updates are running. - STexStreamPrepState* state = new STexStreamPrepState; - state->m_pTexture = pTexture; - state->m_pImage = CImageFile::mfStream_File(sFilename, nFlags, state); - if (state->m_pImage) - { - *const_cast(pState) = state; - return true; - } - - delete state; - - CTexture::s_StreamPrepTasks.Release(pState); - } - - return false; -} - -void CPlanningTextureStreamer::EndPrepare(STexStreamPrepState*& pState) -{ - CryAutoLock lock(m_lock); - - delete pState; - pState = NULL; - - CTexture::s_StreamPrepTasks.Release(&pState); -} - -void CPlanningTextureStreamer::Precache(CTexture* pTexture) -{ - if (pTexture->IsForceStreamHighRes()) - { - for (int i = 0; i < MAX_PREDICTION_ZONES; ++i) - { - pTexture->m_streamRounds[i].nRoundUpdateId = (1 << 29) - 1; - pTexture->m_pFileTexMips->m_arrSPInfo[i].fMinMipFactor = 0; - } - if (pTexture->IsUnloaded()) - { - pTexture->StreamLoadFromCache(0); - } - } -} - -void CPlanningTextureStreamer::UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId, [[maybe_unused]] const int nCounter) -{ - CHK_RENDTH; - -#if defined(TEXSTRM_DEFER_UMR) - - SPlanningUpdateMipRequest req; - req.pTexture = pTexture; - req.fMipFactor = fMipFactor; - req.nFlags = nFlags; - req.nUpdateId = nUpdateId; - - m_updateMipRequests[m_nRTList].push_back(req); - -#else - - Job_UpdateMip(pTexture, fMipFactor, nFlags, nUpdateId); - -#endif -} - -void CPlanningTextureStreamer::OnTextureDestroy(CTexture* pTexture) -{ - if (!pTexture->IsStreamed()) - { - return; - } - - CryAutoLock lock(m_lock); - - SyncWithJob_Locked(); - - switch (m_state) - { - case S_Idle: - case S_QueuedForScheduleDiscard: - break; - - case S_QueuedForSchedule: - m_state = S_QueuedForScheduleDiscard; - break; - -#ifndef _RELEASE - default: - __debugbreak(); - break; -#endif - } - - // Remove the texture from the pending list of mip updates - using std::swap; - -#if defined(TEXSTRM_DEFER_UMR) - UpdateMipRequestVec& umrv = m_updateMipRequests[m_nRTList]; - for (int i = 0, c = umrv.size(); i != c; ) - { - SPlanningUpdateMipRequest& umr = umrv[i]; - if (umr.pTexture == pTexture) - { - swap(umrv.back(), umr); - umrv.pop_back(); - --c; - } - else - { - ++i; - } - } -#endif -} - -void CPlanningTextureStreamer::FlagOutOfMemory() -{ -#if defined(TEXSTRM_BYTECENTRIC_MEMORY) - ++m_nStreamAllocFails; -#endif -} - -void CPlanningTextureStreamer::Flush() -{ -} - -bool CPlanningTextureStreamer::IsOverflowing() const -{ - return m_bOverBudget; -} - -SPlanningMemoryState CPlanningTextureStreamer::GetMemoryState() -{ - SPlanningMemoryState ms = {0}; - - ms.nMemStreamed = CTexture::s_nStatsStreamPoolInUseMem; - - ms.nPhysicalLimit = (ptrdiff_t)CRenderer::GetTexturesStreamPoolSize() * 1024 * 1024; - - ms.nMemLimit = (ptrdiff_t)((int64)ms.nPhysicalLimit * 95 / 100); - ms.nMemFreeSlack = (ptrdiff_t)((int64)ms.nPhysicalLimit * 5 / 100); - - ms.nMemBoundStreamed = CTexture::s_nStatsStreamPoolBoundMem; - ms.nMemTemp = ms.nMemStreamed - ms.nMemBoundStreamed; - ms.nMemFreeLower = ms.nMemLimit - ms.nMemStreamed; - ms.nMemFreeUpper = (ms.nMemLimit + ms.nMemFreeSlack) - ms.nMemStreamed; - ms.nStreamLimit = ms.nMemLimit - CTexture::s_nStatsStreamPoolBoundPersMem; - - ms.nStreamMid = static_cast(ms.nStreamLimit + ms.nMemFreeSlack / 2); - ms.nStreamDelta = static_cast(m_nPrevListSize) - ms.nStreamMid; - - return ms; -} - -void CPlanningTextureStreamer::SyncWithJob_Locked() -{ - FUNCTION_PROFILER_RENDERER; - - m_jobExecutor.WaitForCompletion(); - - if (m_state == S_QueuedForSync) - { - SPlanningSortState& state = m_sortState; - TStreamerTextureVec& textures = GetTextures(); - - // Commit iteration state - - bool bOverBudget = state.nBalancePoint < state.nPrecachedTexs; - m_bOverBudget = bOverBudget; - - m_nBias = state.nBias; - m_nPrevListSize = state.nListSize; - - textures.resize(state.nTextures); - -#ifdef TEXSTRM_DEFER_UMR - SyncTextureList(); -#endif - - m_state = S_QueuedForSchedule; - } -} - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) -bool CPlanningTextureStreamer::TrimTexture(int nBias, TStreamerTextureVec& trimmable, STexPool* pPrioritise) -{ - FUNCTION_PROFILER_RENDERER; - - size_t nBestTrimmableIdx = 0; - int nMostMipsToTrim = 0; - int nBestTrimTargetMip = 0; - - for (size_t i = 0, c = trimmable.size(); i != c; ++i) - { - CTexture* pTrimTex = trimmable[i]; - - - if (pTrimTex->m_bStreamPrepared) - { - STexPool* pTrimItemPool = pTrimTex->GetStreamingInfo()->m_pPoolItem->m_pOwner; - - if (pTrimItemPool == pPrioritise) - { - int nPersMip = bsel(pTrimTex->m_bForceStreamHighRes, 0, pTrimTex->m_nMips - pTrimTex->m_CacheFileHeader.m_nMipsPersistent); - int nTrimMip = pTrimTex->m_nMinMipVidUploaded; - int nTrimTargetMip = max(0, min((int)(pTrimTex->m_fpMinMipCur + nBias) >> 8, nPersMip)); - - int nTrimMips = nTrimTargetMip - nTrimMip; - - if (nTrimMips > nMostMipsToTrim) - { - nBestTrimmableIdx = i; - nMostMipsToTrim = nTrimMips; - nBestTrimTargetMip = nTrimTargetMip; - } - } - } - } - - if (nMostMipsToTrim > 0) - { - CTexture* pTrimTex = trimmable[nBestTrimmableIdx]; - - if (pTrimTex->StreamTrim(nBestTrimTargetMip)) - { - trimmable[nBestTrimmableIdx] = trimmable.back(); - trimmable.pop_back(); - - return true; - } - } - - return false; -} -#endif - -ptrdiff_t CPlanningTextureStreamer::TrimTextures(ptrdiff_t nRequired, int nBias, TStreamerTextureVec& trimmable) -{ - FUNCTION_PROFILER_RENDERER; - - ptrdiff_t nTrimmed = 0; - - int nTrimIdx = (int)trimmable.size(); - for (; nTrimIdx > 0 && nTrimmed < nRequired; --nTrimIdx) - { - CTexture* pTrimTex = trimmable[nTrimIdx - 1]; - - if (!pTrimTex->IsUnloaded()) - { - int nPersMip = bsel(pTrimTex->m_bForceStreamHighRes, 0, pTrimTex->m_nMips - pTrimTex->m_CacheFileHeader.m_nMipsPersistent); - int nTrimMip = pTrimTex->m_nMinMipVidUploaded; - int nTrimTargetMip = max(0, min((int)(pTrimTex->m_fpMinMipCur + nBias) >> 8, nPersMip)); - ptrdiff_t nProfit = pTrimTex->StreamComputeDevDataSize(nTrimMip) - pTrimTex->StreamComputeDevDataSize(nTrimTargetMip); - - if (pTrimTex->StreamTrim(nTrimTargetMip)) - { - nTrimmed += nProfit; - } - } - } - - trimmable.resize(nTrimIdx); - - return nTrimmed; -} - -ptrdiff_t CPlanningTextureStreamer::KickTextures(CTexture** pTextures, ptrdiff_t nRequired, int nBalancePoint, int& nKickIdx) -{ - FUNCTION_PROFILER_RENDERER; - - ptrdiff_t nKicked = 0; - - SThreadInfo& ti = gRenDev->m_RP.m_TI[gRenDev->m_pRT->GetThreadList()]; - const int nCurrentFarZoneRoundId = ti.m_arrZonesRoundId[MAX_PREDICTION_ZONES - 1]; - const int nCurrentNearZoneRoundId = ti.m_arrZonesRoundId[0]; - - // If we're still lacking space, begin kicking old textures - for (; nKicked < nRequired && nKickIdx >= nBalancePoint; --nKickIdx) - { - CTexture* pKillTex = pTextures[nKickIdx]; - - if (!pKillTex->IsUnloaded()) - { - int nKillMip = pKillTex->m_nMinMipVidUploaded; - int nKillPersMip = bsel(pKillTex->m_bForceStreamHighRes, 0, pKillTex->m_nMips - pKillTex->m_CacheFileHeader.m_nMipsPersistent); - - // unload textures that are older than 4 update cycles - if (nKillPersMip > nKillMip) - { - - // How much is available? - ptrdiff_t nProfit = pKillTex->StreamComputeDevDataSize(nKillMip) - pKillTex->StreamComputeDevDataSize(nKillPersMip); - - // Begin freeing. - pKillTex->StreamTrim(nKillPersMip); - - nKicked += nProfit; - } - } - } - - return nKicked; -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.h b/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.h deleted file mode 100644 index 30a3d66c3e..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer.h +++ /dev/null @@ -1,329 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H -#pragma once - - -#include "ITextureStreamer.h" - -#include - -//#define TEXSTRM_DEFER_UMR - -ILINE int bsel(bool c, int t, int f) -{ - PREFAST_SUPPRESS_WARNING(6323) - return isel(-(int)c, f, t); -} - -struct SPlanningMemoryState -{ - ptrdiff_t nMemStreamed; - ptrdiff_t nStaticTexUsage; - ptrdiff_t nPhysicalLimit; - ptrdiff_t nTargetPhysicalLimit; - ptrdiff_t nMemLimit; - ptrdiff_t nMemFreeSlack; - ptrdiff_t nUnknownPoolUsage; - ptrdiff_t nMemBoundStreamed; - ptrdiff_t nMemBoundStreamedPers; - ptrdiff_t nMemTemp; - ptrdiff_t nMemFreeLower; - ptrdiff_t nMemFreeUpper; - ptrdiff_t nStreamLimit; - ptrdiff_t nStreamMid; - ptrdiff_t nStreamDelta; -}; - -struct SPlanningUMRState -{ - int32 arrRoundIds[MAX_PREDICTION_ZONES]; -}; - -struct SPlanningAction -{ - enum - { - Unknown, - Relink, - Abort, - }; - - SPlanningAction() - : eAction(Unknown) - { - } - - SPlanningAction(int action, size_t texture, uint8 mip = 0) - : nTexture((uint16)texture) - , nMip(mip) - , eAction((uint8)action) - { - } - - uint16 nTexture; - uint8 nMip; - uint8 eAction; -}; - -typedef DynArray > TPlanningTextureReqVec; -typedef DynArray TPlanningActionVec; - -struct SPlanningSortState -{ - // In - TStreamerTextureVec* pTextures; - size_t nStreamLimit; - int32 arrRoundIds[MAX_PREDICTION_ZONES]; - int nFrameId; - int nBias; - int fpMinBias; - int fpMaxBias; - int fpMinMip; - SPlanningMemoryState memState; - - // In/Out - size_t nTextures; - - // Out - size_t nBalancePoint; - size_t nOnScreenPoint; - size_t nPrecachedTexs; - size_t nListSize; - TPlanningTextureReqVec* pRequestList; - TStreamerTextureVec* pTrimmableList; - TStreamerTextureVec* pUnlinkList; - TPlanningActionVec* pActionList; -}; - -struct SPlanningScheduleState -{ - int nFrameId; - - int nBias; - SPlanningMemoryState memState; - - TPlanningTextureReqVec requestList; - TStreamerTextureVec trimmableList; - TStreamerTextureVec unlinkList; - TPlanningActionVec actionList; - size_t nBalancePoint; - size_t nOnScreenPoint; -}; - -struct SPlanningUpdateMipRequest -{ - CTexture* pTexture; - float fMipFactor; - int nFlags; - int nUpdateId; -}; - -struct SPlanningTextureOrderKey -{ - // 1 force stream high res - // 1 high priority - // 1 is visible - // 1 is in zone[0] - // 1 is in zone[1] - // 16 fp min mip cur, biased - CTexture* pTexture; - uint32 nKey; - - uint16 nWidth; - uint16 nHeight; - - uint8 nMips : 4; - uint8 nMipsPersistent : 4; - uint8 nCurMip; - uint8 nFormatCode; - uint8 eTF; - - uint32 nPersistentSize : 31; - uint32 bIsStreaming : 1; - - uint32 bUnloaded : 1; - uint32 nIsComposite : 1; - uint32 nStreamPrio : 3; - uint32 nSlicesMinus1 : 9; - uint32 nSlicesPotMinus1 : 9; - - enum - { - InBudgetMask = 0xffffffff ^ ((1 << 30) | (1 << 29)), - OverBudgetMask = 0xffffffff, - PackedFpBias = 0x7f00 - }; - - bool IsForceStreamHighRes() const { return (nKey & (1 << 31)) == 0; } - bool IsHighPriority() const { return (nKey & (1 << 30)) == 0; } - bool IsVisible() const { return (nKey & (1 << 29)) == 0; } - bool IsInZone(int z) const { return (nKey & (1 << (28 - z))) == 0; } - bool IsPrecached() const { return (nKey & ((1 << 31) | (1 << 28) | (1 << 27))) != ((1 << 31) | (1 << 28) | (1 << 27)); } - int GetFpMinMipCur() const { return static_cast(static_cast(nKey & 0xffff) - PackedFpBias); } - uint16 GetFpMinMipCurBiased() const { return (uint16)nKey; } - - SPlanningTextureOrderKey() {} - SPlanningTextureOrderKey(CTexture* pTex, int nFrameId, const int nZoneIds[]) - { - nKey = - (pTex->IsForceStreamHighRes() ? 0 : (1 << 31)) | - (pTex->IsStreamHighPriority() ? 0 : (1 << 30)) | - (pTex->GetAccessFrameIdNonVirtual() >= nFrameId ? 0 : (1 << 29)) | - (pTex->GetStreamRoundInfo(0).nRoundUpdateId >= nZoneIds[0] ? 0 : (1 << 28)) | - (pTex->GetStreamRoundInfo(1).nRoundUpdateId >= nZoneIds[1] ? 0 : (1 << 27)) | - static_cast(pTex->GetRequiredMipNonVirtualFP() + PackedFpBias); - - pTexture = pTex; - - nWidth = pTex->GetWidthNonVirtual(); - nHeight = pTex->GetHeightNonVirtual(); - nMips = pTex->GetNumMipsNonVirtual(); - nMipsPersistent = bsel(pTex->IsForceStreamHighRes(), pTex->GetNumMipsNonVirtual(), pTex->GetNumPersistentMips()); - nFormatCode = pTex->StreamGetFormatCode(); - - uint32 nSlices = pTex->StreamGetNumSlices(); - nSlicesMinus1 = nSlices - 1; - nSlicesPotMinus1 = (1u << (32 - (nSlices > 1 ? countLeadingZeros32(nSlices - 1) : 32))) - 1; - - nCurMip = pTex->StreamGetLoadedMip(); - eTF = pTex->GetDstFormat(); - nPersistentSize = pTex->GetPersistentSize(); - bIsStreaming = pTex->IsStreaming(); - bUnloaded = pTex->IsUnloaded(); - nStreamPrio = pTex->StreamGetPriority(); - nIsComposite = 0; - } -}; - -struct SPlanningRequestIdent -{ - SPlanningRequestIdent() {} - SPlanningRequestIdent(uint32 sortKey, int key, int mip) - : nSortKey(sortKey) - , nKey(key) - , nMip(mip) - { - } - - uint32 nSortKey; - int nKey : 27; - int nMip : 5; -}; - -class CPlanningTextureStreamer - : public ITextureStreamer -{ -public: - CPlanningTextureStreamer(); - -public: - virtual void BeginUpdateSchedule(); - virtual void ApplySchedule(EApplyScheduleFlags asf); - - virtual bool BeginPrepare(CTexture* pTexture, const char* sFilename, uint32 nFlags); - virtual void EndPrepare(STexStreamPrepState*& pState); - - virtual void Precache(CTexture* pTexture); - virtual void UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId, const int nCounter); - - virtual void OnTextureDestroy(CTexture* pTexture); - - virtual void FlagOutOfMemory(); - virtual void Flush(); - - virtual bool IsOverflowing() const; - virtual float GetBias() const { return m_nBias / 256.0f; } - -public: // Job entry points - do not call directly! - void Job_UpdateEntry(); - -private: - enum State - { - S_Idle, - S_QueuedForUpdate, - S_Updating, - S_QueuedForSync, - S_QueuedForSchedule, - S_QueuedForScheduleDiscard, - }; - - typedef DynArray UpdateMipRequestVec; - -private: - SPlanningMemoryState GetMemoryState(); - - void StartUpdateJob(); - - void Job_UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId); - void Job_Sort(); - int Job_Bias(SPlanningSortState& sortState, SPlanningTextureOrderKey* pKeys, size_t nNumPrecachedTexs, size_t nStreamLimit); - size_t Job_Plan(SPlanningSortState& sortState, const SPlanningTextureOrderKey* pKeys, size_t nTextures, size_t nNumPrecachedTexs, size_t nBalancePoint, int nMinMip, int fpSortStateBias); - void Job_InitKeys(SPlanningTextureOrderKey* pKeys, CTexture** pTexs, size_t nTextures, int nFrameId, const int nZoneIds[]); - void Job_CommitKeys(CTexture** pTextures, SPlanningTextureOrderKey* pKeys, size_t nTextures); - void Job_ConfigureSchedule(); - void SyncWithJob_Locked(); - -private: -#ifndef NULL_RENDERER - bool TryBegin_FromDisk(CTexture* pTex, uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint, - TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx, - int& nNumSubmittedLoad, size_t& nAmtSubmittedLoad); - bool TryBegin_Composite(CTexture* pTex, uint32 nTexPersMip, uint32 nTexWantedMip, uint32 nTexAvailMip, int nBias, int nBalancePoint, - TStreamerTextureVec& textures, TStreamerTextureVec& trimmable, ptrdiff_t& nMemFreeLower, ptrdiff_t& nMemFreeUpper, int& nKickIdx, - int& nNumSubmittedLoad, size_t& nAmtSubmittedLoad); -#endif - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) - bool TrimTexture(int nBias, TStreamerTextureVec& trimmable, STexPool* pPrioritise); -#endif - ptrdiff_t TrimTextures(ptrdiff_t nRequired, int nBias, TStreamerTextureVec& trimmable); - ptrdiff_t KickTextures(CTexture** pTextures, ptrdiff_t nRequired, int nBalancePoint, int& nKickIdx); - void Job_CheckEnqueueForStreaming(CTexture* pTexture, const float fMipFactor, bool bHighPriority); - -private: - CryCriticalSection m_lock; - std::vector m_keys; - int m_nRTList; - int m_nJobList; - - volatile State m_state; - - AZ::LegacyJobExecutor m_jobExecutor; - SPlanningUMRState m_umrState; - SPlanningSortState m_sortState; - -#if defined(TEXSTRM_DEFER_UMR) - UpdateMipRequestVec m_updateMipRequests[2]; -#endif - - SPlanningScheduleState m_schedule; - - int m_nBias; - int m_nStreamAllocFails; - bool m_bOverBudget; - size_t m_nPrevListSize; -}; - -struct SPlanningTextureRequestOrder -{ - bool operator () (const SPlanningRequestIdent& a, const SPlanningRequestIdent& b) const - { - return a.nSortKey < b.nSortKey; - } -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_PLANNINGTEXTURESTREAMER_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer_Jobs.cpp b/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer_Jobs.cpp deleted file mode 100644 index 40a229876d..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/PlanningTextureStreamer_Jobs.cpp +++ /dev/null @@ -1,665 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "PlanningTextureStreamer.h" - -//#define PLAN_TEXSTRM_DEBUG - -static int GetTexReqStreamSizePreClamped(const SPlanningTextureOrderKey& key, int reqMip) -{ - int nTotalSize = 0; - - uint8 nFormatCode = key.nFormatCode; - if (nFormatCode) - { - const SStreamFormatCode& code = CTexture::s_formatCodes[nFormatCode]; - - uint32 nCodeMip = reqMip + (SStreamFormatCode::MaxMips - key.nMips); - uint32 nSlices = key.nSlicesMinus1 + 1; - uint32 nPoTSlices = key.nSlicesPotMinus1 + 1; - - uint32 n1SliceSize = code.sizes[nCodeMip].size; - uint32 nFormatSlices = isel(-(int)code.sizes[nCodeMip].alignSlices, nSlices, nPoTSlices); - nTotalSize = n1SliceSize * nFormatSlices; - -#if defined(PLAN_TEXSTRM_DEBUG) && defined(TEXSTRM_STORE_DEVSIZES) - int nTotalSizeTest = key.pTexture->StreamComputeDevDataSize(reqMip); - - if (nTotalSizeTest != nTotalSize) - { - __debugbreak(); - } -#endif - } - else - { -#if defined(TEXSTRM_STORE_DEVSIZES) - nTotalSize = key.pTexture->StreamComputeDevDataSize(reqMip); -#else - nTotalSize = CDeviceTexture::TextureDataSize( - max(1, key.nWidth >> reqMip), - max(1, key.nHeight >> reqMip), - 1, - key.nMips - reqMip, - key.nSlicesMinus1 + 1, - (ETEX_Format)key.eTF); -#endif - } - - return nTotalSize - key.nPersistentSize; -} - -struct CTextureStreamSize -{ - CTextureStreamSize(int nMinMip, int nBias) - : m_nMinMip(nMinMip) - , m_nBias(nBias) - { - } - - ptrdiff_t operator () (const SPlanningTextureOrderKey& key) const - { - int numMips = key.nMips; - int numPersMips = key.nMipsPersistent; - int persMip = numMips - numPersMips; - int reqMip = min(max(static_cast(key.GetFpMinMipCur() + m_nBias) >> 8, m_nMinMip), persMip); - return GetTexReqStreamSizePreClamped(key, reqMip); - } - - int m_nMinMip; - int m_nBias; -}; - -struct CTexturePrecachedPred -{ - bool operator () (const SPlanningTextureOrderKey& key) const - { - return key.IsPrecached(); - } -}; - -struct CTextureOnScreenPred -{ - bool operator () (const SPlanningTextureOrderKey& key) const - { - return key.IsVisible(); - } -}; - -struct SPlanningTextureOrder -{ - explicit SPlanningTextureOrder(uint32 nKeyMask) - { - m_nKeyMask = nKeyMask; - } - - bool operator () (const SPlanningTextureOrderKey& a, const SPlanningTextureOrderKey& b) const - { - uint32 nMask = m_nKeyMask; - uint32 nAKeyMasked = a.nKey & nMask; - uint32 nBKeyMasked = b.nKey & nMask; - if (nAKeyMasked != nBKeyMasked) - { - return nAKeyMasked < nBKeyMasked; - } - - return a.pTexture < b.pTexture; - } - - uint32 m_nKeyMask; -}; - -template -static void QuickSelectMedianOf3(T* table, size_t a, size_t b, size_t c, const Pred& p) -{ - using std::swap; - - if (p(table[b], table[a])) - { - swap(table[b], table[a]); - } - if (p(table[c], table[b])) - { - swap(table[c], table[b]); - } - if (p(table[b], table[a])) - { - swap(table[b], table[a]); - } -} - -template -static void QuickSelectMedian(T* table, size_t a, size_t m, size_t b, const Pred& p) -{ - if ((b - a) >= 40) - { - size_t step = (b - a + 1) / 8; - QuickSelectMedianOf3(table, a, a + step, a + step * 2, p); - QuickSelectMedianOf3(table, m - step, m, m + step, p); - QuickSelectMedianOf3(table, b - step * 2, b - step, b, p); - QuickSelectMedianOf3(table, a + step, m, b - step, p); - } - else - { - QuickSelectMedianOf3(table, a, m, b, p); - } -} - -template -static T* QuickSelectSum(T* p, size_t mn, size_t mx, ptrdiff_t targetSum, const LessFunc& less, const SizeFunc& size) -{ - using std::swap; - - size_t rangeMin = mn, rangeMax = mx; - - do - { - size_t pivotIdx = rangeMin + (rangeMax - rangeMin) / 2; - QuickSelectMedian(p, rangeMin, pivotIdx, rangeMax - 1, less); - - ptrdiff_t leftSum = 0; - - // Move pivot out of the way, so it can be placed at the right location at the end - T pivotVal = p[pivotIdx]; - swap(p[rangeMax - 1], p[pivotIdx]); - - // - 1 to account for the moved pivot - size_t left = rangeMin, right = rangeMax - 1; - while (left < right) - { - // Advance left edge past all vals <= pivot - while (left < right && !less(pivotVal, p[left])) - { - leftSum += size(p[left]); - ++left; - } - - // Advance right edge past all vals >= pivot - while (right > left && !less(p[right - 1], pivotVal)) - { - --right; - } - - if (right > left) - { - // Swap the conflicting values - swap(p[left], p[right - 1]); - } - } - - // Put the pivot back - swap(p[rangeMax - 1], p[left]); - - if (leftSum >= targetSum) - { - rangeMax = left; - } - else if (leftSum < targetSum) - { - rangeMin = right; - targetSum -= leftSum; - } - - if (rangeMax - rangeMin <= 1) - { - // Handle the case where the leftSum is under budget (such as the pivot being at the far right edge of the range) - if (leftSum < targetSum) - { - ptrdiff_t pivotSize = size(p[left]); - if (leftSum + pivotSize <= targetSum) - { - ++left; - } - } - return &p[left]; - } - } - while (1); -} - -void CPlanningTextureStreamer::Job_UpdateEntry() -{ - FUNCTION_PROFILER_RENDERER; - - m_state = S_Updating; - -#ifdef TEXSTRM_DEFER_UMR - uint32 nList = m_nJobList; - UpdateMipRequestVec& umrv = m_updateMipRequests[nList]; - - for (UpdateMipRequestVec::iterator it = umrv.begin(), itEnd = umrv.end(); it != itEnd; ++it) - { - Job_UpdateMip(it->pTexture, it->fMipFactor, it->nFlags, it->nUpdateId); - } -#endif - - Job_Sort(); - Job_ConfigureSchedule(); - - m_state = S_QueuedForSync; -} - -void CPlanningTextureStreamer::StartUpdateJob() -{ - m_jobExecutor.Reset(); - m_jobExecutor.StartJob( - [this]() - { - this->Job_UpdateEntry(); - } - ); -} - -void CPlanningTextureStreamer::Job_UpdateMip(CTexture* pTexture, const float fMipFactor, const int nFlags, const int nUpdateId) -{ - assert(fMipFactor >= 0.f); - - const int nZoneId = (nFlags & FPR_SINGLE_FRAME_PRIORITY_UPDATE) ? 0 : 1; - - STexStreamingInfo* pStrmInfo = pTexture->m_pFileTexMips; - - if (pStrmInfo && fMipFactor < pStrmInfo->m_fMinMipFactor) - { - STexStreamZoneInfo& rZoneInfo = pStrmInfo->m_arrSPInfo[nZoneId]; - STexStreamRoundInfo& rRoundInfo = pTexture->m_streamRounds[nZoneId]; - - const int nCurrentRoundUpdateId = m_umrState.arrRoundIds[nZoneId]; - - if (rRoundInfo.nRoundUpdateId != nUpdateId) - { - STATIC_CHECK(MAX_PREDICTION_ZONES == 2, THIS_CODE_IS_OPTIMISED_ASSUMING_THIS_EQUALS_2); - - // reset mip factor and save the accumulated value into history and compute final mip factor - float fFinalMipFactor = fMipFactor; - int nRoundUpdateId = (int)rRoundInfo.nRoundUpdateId; - if (nRoundUpdateId >= 0 && (nRoundUpdateId > nCurrentRoundUpdateId - 2)) - { - fFinalMipFactor = min(fFinalMipFactor, rZoneInfo.fMinMipFactor); - } - - // if the min mip factor is at its default value, initialise the entire history with the new mip factor - rZoneInfo.fLastMinMipFactor = (float)fsel(rZoneInfo.fMinMipFactor - 1000000.0f, fMipFactor, rZoneInfo.fMinMipFactor); - rZoneInfo.fMinMipFactor = fMipFactor; - - // reset the high prio flags - rRoundInfo.bLastHighPriority = rRoundInfo.bHighPriority; - rRoundInfo.bHighPriority = false; - - // update round id - rRoundInfo.nRoundUpdateId = max(nUpdateId, nCurrentRoundUpdateId); - - // consider the alternate zone mip factor as well - const int nOtherZoneId = nZoneId ^ 1; - const STexStreamZoneInfo& rOtherZoneInfo = pStrmInfo->m_arrSPInfo[nOtherZoneId]; - const STexStreamRoundInfo& rOtherRoundInfo = pTexture->m_streamRounds[nOtherZoneId]; - int nOtherRoundUpdateId = (int)rOtherRoundInfo.nRoundUpdateId; - if (nOtherRoundUpdateId >= 0 && (nOtherRoundUpdateId > m_umrState.arrRoundIds[nOtherZoneId] - 2)) - { - fFinalMipFactor = min(fFinalMipFactor, rOtherZoneInfo.fLastMinMipFactor); - } - - Job_CheckEnqueueForStreaming(pTexture, fFinalMipFactor, rRoundInfo.bLastHighPriority); - } - - rZoneInfo.fMinMipFactor = min(rZoneInfo.fMinMipFactor, fMipFactor); - rRoundInfo.bHighPriority = (rRoundInfo.bHighPriority || nFlags & FPR_HIGHPRIORITY); - -#if !defined (_RELEASE) - CTexture::s_TextureUpdates += 1; -#endif - } - - // And source textures for composition - if (pTexture->CTexture::GetFlags() & FT_COMPOSITE) - { - DynArray& composition = pTexture->m_composition; - - for (int i = 0, c = composition.size(); i != c; ++i) - { - CTexture* pTexFrame = (CTexture*)&*composition[i].pTexture; - - if (pTexFrame->IsStreamed()) - { - Job_UpdateMip(pTexFrame, fMipFactor, nFlags, nUpdateId); - } - } - } -} - -int CPlanningTextureStreamer::Job_Bias(SPlanningSortState& sortState, SPlanningTextureOrderKey* pKeys, size_t nNumPrecachedTexs, size_t nStreamLimit) -{ - FUNCTION_PROFILER_RENDERER; - - int fpSortStateBias = sortState.nBias; - const int fpSortStateMinBias = sortState.fpMinBias; - const int fpSortStateMaxBias = sortState.fpMaxBias; - const int fpSortStateMinMip = sortState.fpMinMip; - - fpSortStateBias = clamp_tpl(fpSortStateBias, fpSortStateMinBias, fpSortStateMaxBias); - - int fpMipBiasLow = fpSortStateMinBias; - int fpMipBiasHigh = max(fpSortStateMinBias, fpSortStateMaxBias); - - const int nMaxBiasSteps = 8; - - for (int nBiasStep = 0; nBiasStep < nMaxBiasSteps && (fpMipBiasHigh - fpMipBiasLow) > 1; ++nBiasStep) - { - int nMipBiasTest = (fpMipBiasLow + fpMipBiasHigh) / 2; - - size_t nBiasedListStreamSize = 0; - for (size_t texIdx = 0, texCount = nNumPrecachedTexs; texIdx != texCount && nBiasedListStreamSize < nStreamLimit; ++texIdx) - { - const SPlanningTextureOrderKey& key = pKeys[texIdx]; - - int nMips = key.nMips; - int fpReqMip = max(fpSortStateMinMip, key.GetFpMinMipCur() + nMipBiasTest); - int nReqMip = min(fpReqMip >> 8, nMips - 1); - - nBiasedListStreamSize += GetTexReqStreamSizePreClamped(key, nReqMip); - } - - if (nBiasedListStreamSize < nStreamLimit) - { - fpMipBiasHigh = nMipBiasTest; - } - else - { - fpMipBiasLow = nMipBiasTest; - } - } - - int nProspBias = (fpMipBiasLow + fpMipBiasHigh) / 2; - if (abs(fpSortStateBias - nProspBias) > 8) - { - fpSortStateBias = nProspBias; - } - - return fpSortStateBias; -} - -size_t CPlanningTextureStreamer::Job_Plan(SPlanningSortState& sortState, const SPlanningTextureOrderKey* pKeys, size_t nTextures, size_t nNumPrecachedTexs, size_t nBalancePoint, int nMinMip, int fpSortStateBias) -{ - FUNCTION_PROFILER_RENDERER; - - COMPILE_TIME_ASSERT(MAX_PREDICTION_ZONES == 2); - - size_t nListSize = 0; - - enum - { - MaxRequests = 16384 - }; - SPlanningRequestIdent requests[MaxRequests]; - size_t nRequests = 0; - - for (size_t texIdx = 0, texCount = nBalancePoint; texIdx != texCount; ++texIdx) - { - const SPlanningTextureOrderKey& key = pKeys[texIdx]; - - int nMips = key.nMips; - int cachedMip = key.nCurMip; - int persMip = nMips - key.nMipsPersistent; - int cacheMip; - - if (texIdx < nNumPrecachedTexs) - { - int16 fpMinMipCur = key.GetFpMinMipCur(); - - cacheMip = max((int)(fpMinMipCur + fpSortStateBias) >> 8, nMinMip); - cacheMip = min(cacheMip, persMip); - } - else - { - cacheMip = persMip; - } - - int cacheMipSize = GetTexReqStreamSizePreClamped(key, cacheMip); - - nListSize += cacheMipSize; - - if (!key.bIsStreaming) - { - if (cacheMip > cachedMip) - { - sortState.pTrimmableList->push_back(key.pTexture); - } - else if (cachedMip > cacheMip) - { - if (nRequests < MaxRequests) - { - bool bOnlyNeedsTopMip = cacheMip == 0 && cachedMip == 1; - - uint32 nSortKey = - (!key.nIsComposite << 31) - | ((int)(cachedMip < (max(0, key.GetFpMinMipCur()) >> 8)) << 30) - | ((int)!key.IsHighPriority() << 29) - | ((int)bOnlyNeedsTopMip << 28) - | ((int)!key.IsVisible() << 27) - | ((int)(7 - key.nStreamPrio) << 19) - | ((int)!key.IsInZone(0) << 18) - | ((int)!key.IsInZone(1) << 17) - | (key.GetFpMinMipCurBiased() << 1) - ; - - requests[nRequests++] = SPlanningRequestIdent(nSortKey, (int)texIdx, cacheMip); - } - } - } - else - { - uint32 nStreamSlot = key.pTexture->m_nStreamSlot; - if (!(nStreamSlot & (CTexture::StreamOutMask | CTexture::StreamPrepMask))) - { - STexStreamInState* pStreamInState = CTexture::s_StreamInTasks.GetPtrFromIdx(nStreamSlot & CTexture::StreamIdxMask); - if (cacheMip > pStreamInState->m_nLowerUploadedMip) - { - sortState.pActionList->push_back(SPlanningAction(SPlanningAction::Abort, texIdx)); - } - } - } - } - - for (size_t texIdx = nBalancePoint, texCount = nTextures; texIdx != texCount; ++texIdx) - { - assert(nBalancePoint < nTextures); - PREFAST_ASSUME(nBalancePoint < nTextures); - const SPlanningTextureOrderKey& key = pKeys[texIdx]; - - int cachedMip = key.nCurMip; - int nMips = key.nMips; - int persMip = nMips - key.nMipsPersistent; - int16 fpMinMipCur = key.GetFpMinMipCur(); - int cacheMip = texIdx < nNumPrecachedTexs - ? max((int)(fpMinMipCur + fpSortStateBias) >> 8, nMinMip) - : persMip; - - cacheMip = min(cacheMip, persMip); - - int cacheMipSize = GetTexReqStreamSizePreClamped(key, cacheMip); - - nListSize += cacheMipSize; - - if (!key.bIsStreaming && !key.bUnloaded) - { - if (cacheMip > cachedMip) - { - sortState.pTrimmableList->push_back(key.pTexture); - } - else if (cachedMip > persMip) - { - if (nRequests < MaxRequests) // Persistent mips should always be present - needed in case stream unload occurred - { - uint32 nSortKey = - (!key.nIsComposite << 31) - | ((int)(cachedMip < (max(0, key.GetFpMinMipCur()) >> 8)) << 30) - | ((int)!key.IsHighPriority() << 29) - | ((int)!key.IsVisible() << 27) - | ((int)(7 - key.nStreamPrio) << 19) - | ((int)!key.IsInZone(0) << 18) - | ((int)!key.IsInZone(1) << 17) - | (key.GetFpMinMipCurBiased() << 1) - ; - - requests[nRequests++] = SPlanningRequestIdent(nSortKey, (int)texIdx, persMip); - } - } - else if (!key.IsPrecached() && cachedMip == persMip) - { - sortState.pUnlinkList->push_back(key.pTexture); - } - } - } - - if (nRequests > 0) - { - // TODO - only sort the part of the list that can actually be submitted this update - SPlanningTextureRequestOrder sort_op; - std::sort(&requests[0], &requests[nRequests], sort_op); - - for (size_t iRequest = 0; iRequest < nRequests; ++iRequest) - { - int nRequestMip = requests[iRequest].nMip; - sortState.pRequestList->push_back(std::make_pair(pKeys[requests[iRequest].nKey].pTexture, nRequestMip)); - } - } - - return nListSize; -} - -void CPlanningTextureStreamer::Job_Sort() -{ - FUNCTION_PROFILER_RENDERER; - - SPlanningSortState& sortState = m_sortState; - - CTexture** pTextures = &(*sortState.pTextures)[0]; - size_t nTextures = sortState.nTextures; - - int nMinMip = sortState.fpMinMip >> 8; - - size_t const nStreamLimit = sortState.nStreamLimit; - - m_keys.resize(nTextures); - SPlanningTextureOrderKey* pKeys = &m_keys[0]; - - int const nFrameId = sortState.nFrameId; - int const nZoneIds[] = { sortState.arrRoundIds[0], sortState.arrRoundIds[1] }; - Job_InitKeys(pKeys, pTextures, nTextures, nFrameId - 8, nZoneIds); - - SPlanningTextureOrderKey* pLastPrecachedKey = std::partition(pKeys, pKeys + nTextures, CTexturePrecachedPred()); - size_t nNumPrecachedTexs = std::distance(pKeys, pLastPrecachedKey); - - int fpSortStateBias = Job_Bias(sortState, pKeys, nNumPrecachedTexs, nStreamLimit); - - - SPlanningTextureOrderKey* pBalanceKey = pKeys + nNumPrecachedTexs; - if (fpSortStateBias >= 0 && nNumPrecachedTexs > 0) - { - SPlanningTextureOrder order(SPlanningTextureOrderKey::OverBudgetMask); - pBalanceKey = QuickSelectSum(pKeys, 0, nNumPrecachedTexs, nStreamLimit, order, CTextureStreamSize(nMinMip, fpSortStateBias)); - } - - size_t nBalancePoint = std::distance(pKeys, pBalanceKey); - - - - SPlanningTextureOrderKey* pFirstOffScreenKey = std::partition(pKeys, pKeys + nBalancePoint, CTextureOnScreenPred()); - size_t nOnScreenPoint = std::distance(pKeys, pFirstOffScreenKey); - - - size_t nListSize = Job_Plan(sortState, pKeys, nTextures, nNumPrecachedTexs, nBalancePoint, nMinMip, fpSortStateBias); - - - Job_CommitKeys(pTextures, pKeys, nTextures); - - sortState.nListSize = nListSize; - sortState.nBalancePoint = nBalancePoint; - sortState.nOnScreenPoint = nOnScreenPoint; - sortState.nPrecachedTexs = nNumPrecachedTexs; - sortState.nBias = fpSortStateBias; -} - -void CPlanningTextureStreamer::Job_InitKeys(SPlanningTextureOrderKey* pKeys, CTexture** pTexs, size_t nTextures, int nFrameId, const int nZoneIds[]) -{ - FUNCTION_PROFILER_RENDERER; - - for (size_t i = 0; i < nTextures; ++i) - { -#if PLANNINGTEXTURESTREAMER_JOBS_CPP_TRAIT_JOB_INITKEYS_PREFETCH - if ((i + 32) < nTextures) - { - _mm_prefetch((char*)(pTexs[i + 32]) + 0x40, 0); - } -#endif - new (&pKeys[i])SPlanningTextureOrderKey(pTexs[i], nFrameId, nZoneIds); - } -} - -void CPlanningTextureStreamer::Job_CommitKeys(CTexture** pTextures, SPlanningTextureOrderKey* pKeys, size_t nTextures) -{ - for (size_t i = 0; i < nTextures; ++i) - { - pTextures[i] = pKeys[i].pTexture; - } -} - -void CPlanningTextureStreamer::Job_CheckEnqueueForStreaming(CTexture* pTexture, const float fMipFactor, bool bHighPriority) -{ - - // calculate the new lod value - int fpMipIdSigned = pTexture->StreamCalculateMipsSignedFP(fMipFactor); - const int fpNewMip = max(0, fpMipIdSigned); - const int nNewMip = fpNewMip >> 8; - const int nMipIdSigned = fpMipIdSigned >> 8; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_TexturesStreamingDebug == 2) - { - iLog->Log("Updating mips: %s - Current: %i, Desired: %i", pTexture->m_SrcName.c_str(), pTexture->GetRequiredMipNonVirtual(), nNewMip); - } - -#if defined(ENABLE_TEXTURE_STREAM_LISTENER) - if (pTexture->GetRequiredMipNonVirtual() != nNewMip) - { - ITextureStreamListener* pListener = CTexture::s_pStreamListener; - if (pListener) - { - pListener->OnTextureWantsMip(pTexture, min(nNewMip, (int)pTexture->m_nMips)); - } - } -#endif - - // update required mip for streaming - pTexture->m_fpMinMipCur = fpMipIdSigned; - - // update high priority flag - pTexture->m_bStreamHighPriority |= bHighPriority ? 1 : 0; - -#if defined(TEXSTRM_DEFER_UMR) - __debugbreak(); -#else - pTexture->Relink(); -#endif -} - -void CPlanningTextureStreamer::Job_ConfigureSchedule() -{ - SPlanningScheduleState& schedule = m_schedule; - SPlanningSortState& sortState = m_sortState; - - schedule.nFrameId = sortState.nFrameId; - schedule.nBias = sortState.nBias; - schedule.memState = sortState.memState; - schedule.nBalancePoint = sortState.nBalancePoint; - schedule.nOnScreenPoint = sortState.nOnScreenPoint; -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.cpp b/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.cpp deleted file mode 100644 index 5dbffb30a5..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "PowerOf2BlockPacker.h" - -CPowerOf2BlockPacker::CPowerOf2BlockPacker(const uint32 dwLogWidth, const uint32 dwLogHeight) -{ - m_dwWidth = 1 << dwLogWidth; - m_dwHeight = 1 << dwLogHeight; - - m_nUsedBlocks = 0; - m_pTexture = NULL; - - m_BlockBitmap.resize(m_dwWidth * m_dwHeight, 0xffffffff); -} - -CPowerOf2BlockPacker::~CPowerOf2BlockPacker() -{ - //Clear(); - FreeContainers(); - SAFE_RELEASE(m_pTexture); -} - -void CPowerOf2BlockPacker::Clear() -{ - std::fill(m_BlockBitmap.begin(), m_BlockBitmap.end(), 0xffffffff); - m_Blocks.clear(); - m_nUsedBlocks = 0; -} - -uint32 CPowerOf2BlockPacker::GetBlockInfo(const uint32 dwBlockID, uint32& dwMinX, uint32& dwMinY, uint32& dwMaxX, uint32& dwMaxY) -{ - uint32 dwSize = (uint32)m_Blocks.size(); - - if (dwBlockID >= dwSize) - { - return 0xFFFFFFFF; // to avoid crash - } - SBlockMinMax& ref = m_Blocks[dwBlockID]; - - dwMinX = ref.m_dwMinX; - dwMinY = ref.m_dwMinY; - dwMaxX = ref.m_dwMaxX; - dwMaxY = ref.m_dwMaxY; - - if (ref.IsFree()) - { - return 0xFFFFFFFF; - } - else - { - return dwBlockID; - } -} - -void CPowerOf2BlockPacker::UpdateSize(int nW, int nH) -{ - assert(m_nUsedBlocks == 0); - - m_dwWidth = nW; - m_dwHeight = nH; - - m_nUsedBlocks = 0; - - m_BlockBitmap.resize(m_dwWidth * m_dwHeight, 0xffffffff); -} - -void CPowerOf2BlockPacker::RemoveBlock(const uint32 dwBlockID) -{ - uint32 dwSize = (uint32)m_Blocks.size(); - - assert(dwBlockID < dwSize); - if (dwBlockID >= dwSize) - { - return; // to avoid crash - } - SBlockMinMax& ref = m_Blocks[dwBlockID]; - - assert(!ref.IsFree()); - - FillRect(ref, 0xffffffff); - m_nUsedBlocks -= (ref.m_dwMaxX - ref.m_dwMinX) * (ref.m_dwMaxY - ref.m_dwMinY); - - ref.MarkFree(); -} - -uint32 CPowerOf2BlockPacker::AddBlock(const uint32 dwLogWidth, const uint32 dwLogHeight) -{ - uint32 dwLocalWidth = 1 << dwLogWidth; - uint32 dwLocalHeight = 1 << dwLogHeight; - - for (uint32 dwY = 0; dwY < m_dwHeight; dwY += dwLocalHeight) - { - for (uint32 dwX = 0; dwX < m_dwWidth; dwX += dwLocalWidth) - { - SBlockMinMax testblock; - - testblock.m_dwMinX = dwX; - testblock.m_dwMaxX = dwX + dwLocalWidth; - testblock.m_dwMinY = dwY; - testblock.m_dwMaxY = dwY + dwLocalHeight; - - if (IsFree(testblock)) - { - uint32 dwBlockID = FindFreeBlockIDOrCreateNew(); - - m_Blocks[dwBlockID] = testblock; - - FillRect(testblock, dwBlockID); - - m_nUsedBlocks += dwLocalWidth * dwLocalHeight; - - return dwBlockID; - } - } - } - - return 0xffffffff; // no space left to this block -} - - - -void CPowerOf2BlockPacker::FillRect(const SBlockMinMax& rect, uint32 dwValue) -{ - for (uint32 dwY = rect.m_dwMinY; dwY < rect.m_dwMaxY; ++dwY) - { - for (uint32 dwX = rect.m_dwMinX; dwX < rect.m_dwMaxX; ++dwX) - { - m_BlockBitmap[dwX + dwY * m_dwWidth] = dwValue; - } - } -} - -bool CPowerOf2BlockPacker::IsFree(const SBlockMinMax& rect) -{ - for (uint32 dwY = rect.m_dwMinY; dwY < rect.m_dwMaxY; ++dwY) - { - for (uint32 dwX = rect.m_dwMinX; dwX < rect.m_dwMaxX; ++dwX) - { - if (m_BlockBitmap.size() <= dwX + dwY * m_dwWidth || m_BlockBitmap[dwX + dwY * m_dwWidth] != 0xffffffff) - { - return false; - } - } - } - - return true; -} - -uint32 CPowerOf2BlockPacker::GetRandomBlock() const -{ - std::vector::const_iterator it, end = m_Blocks.end(); - - uint32 dwCnt = 0; - - for (it = m_Blocks.begin(); it != end; ++it) - { - const SBlockMinMax& ref = *it; - - if (!ref.IsFree()) - { - dwCnt++; - } - } - - if (dwCnt == 0) - { - return 0xffffffff; - } - - uint32 dwI = 0; - uint32 dwRndI = 0; - uint32 dwRnd = cry_random(0U, dwCnt - 1); - - for (it = m_Blocks.begin(); it != end; ++it, ++dwI) - { - const SBlockMinMax& ref = *it; - - if (!ref.IsFree()) - { - if (dwRndI == dwRnd) - { - return dwI; - } - - ++dwRndI; - } - } - - assert(0); - return 0xffffffff; -} - - -uint32 CPowerOf2BlockPacker::FindFreeBlockIDOrCreateNew() -{ - std::vector::const_iterator it, end = m_Blocks.end(); - uint32 dwI = 0; - - for (it = m_Blocks.begin(); it != end; ++it, ++dwI) - { - const SBlockMinMax& ref = *it; - - if (ref.IsFree()) - { - return dwI; - } - } - - m_Blocks.push_back(SBlockMinMax()); - - return (uint32)m_Blocks.size() - 1; -} - -void CPowerOf2BlockPacker::FreeContainers() -{ - Clear(); - stl::free_container(m_Blocks); - stl::free_container(m_BlockBitmap); -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.h b/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.h deleted file mode 100644 index 7c43cb92e3..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/PowerOf2BlockPacker.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_POWEROF2BLOCKPACKER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_POWEROF2BLOCKPACKER_H -#pragma once - - -#include // STL vector<> - -class CPowerOf2BlockPacker -{ -public: - CTexture* m_pTexture; - float m_fLastUsed; - -public: - // constructor - // Arguments: - // dwLogHeight - e.g. specify 5 for 32, keep is small like ~ 5 or 6, don't use pixel size - // dwLogHeight - e.g. specify 5 for 32, keep is small like ~ 5 or 6, don't use pixel size - CPowerOf2BlockPacker(const uint32 dwLogWidth = 0, const uint32 dwLogHeight = 0); - - ~CPowerOf2BlockPacker(); - - // Arguments: - // dwLogHeight - e.g. specify 5 for 32 - // dwLogHeight - e.g. specify 5 for 32 - // Returns: - // dwBlockID (to remove later), 0xffffffff if there was no free space - uint32 AddBlock(const uint32 dwLogWidth, const uint32 dwLogHeight); - - // Arguments: - // dwBlockID - as it was returned from AddBlock() - uint32 GetBlockInfo(const uint32 dwBlockID, uint32& dwMinX, uint32& dwMinY, uint32& dwMaxX, uint32& dwMaxY); - - void UpdateSize(int nW, int nH); - - // Arguments: - // dwBlockID - as it was returned from AddBlock() - void RemoveBlock(const uint32 dwBlockID); - - // used for debugging - // Return - // 0xffffffff if not block was found - uint32 GetRandomBlock() const; - - uint32 GetNumUsedBlocks() const - { - return m_nUsedBlocks; - } - - void Clear(); - - void FreeContainers(); - -private: // ---------------------------------------------------------- - - struct SBlockMinMax - { - uint32 m_dwMinX; // 0xffffffff if free, included - uint32 m_dwMinY; // not defined if free, included - uint32 m_dwMaxX; // not defined if free, not included - uint32 m_dwMaxY; // not defined if free, not included - - bool IsFree() const - { - return m_dwMinX == 0xffffffff; - } - - void MarkFree() - { - m_dwMinX = 0xffffffff; - } - - ~SBlockMinMax() - { - MarkFree(); - } - }; - - // ----------------------------------------------------------------- - - std::vector m_Blocks; // - std::vector m_BlockBitmap; // [m_dwWidth*m_dwHeight], elements are 0xffffffff if not used - uint32 m_dwWidth; // >0 - uint32 m_dwHeight; // >0 - uint32 m_nUsedBlocks; - - // ----------------------------------------------------------------- - - // - void FillRect(const SBlockMinMax& rect, uint32 dwValue); - - bool IsFree(const SBlockMinMax& rect); - - // - uint32 FindFreeBlockIDOrCreateNew(); -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_POWEROF2BLOCKPACKER_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.cpp b/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.cpp deleted file mode 100644 index 78611fa552..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "RenderDll_precompiled.h" -#include "StereoTexture.h" - -#include - -CStereoTexture::CStereoTexture(const char* szName, ETEX_Format format, int nFlags) - : CTexture(nFlags) -{ - AZStd::string leftName = szName; - AZStd::string rightName = szName; - leftName = leftName.append("_Left"); - rightName = rightName.append("_Right"); - - //Create internal textures - m_textures = AZStd::vector(STEREO_EYE_COUNT); - - //Create textures with no width or height; - //When the VideoPlaybackComponent creates those it can specify an accurate width & height - m_textures[STEREO_EYE_LEFT] = CTexture::CreateTextureObject(leftName.c_str(), 0, 0, 1, eTT_2D, nFlags, format); - m_textures[STEREO_EYE_RIGHT] = CTexture::CreateTextureObject(rightName.c_str(), 0, 0, 1, eTT_2D, nFlags, format); -} - -void CStereoTexture::Apply(int nTUnit, int nState, int nTexMatSlot, int nSUnit, SResourceView::KeyType nResViewKey, EHWShaderClass eHWSC) -{ - int eye = gRenDev->m_CurRenderEye; - if (eye < STEREO_EYE_COUNT) - { - m_textures[eye]->Apply(nTUnit, nState, nTexMatSlot, nSUnit, nResViewKey, eHWSC); - } - else - { - AZ_Assert(true, "Invalid eye provided for rendering"); - } -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.h b/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.h deleted file mode 100644 index d41250108f..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/StereoTexture.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -/* - This stereo texture does two things: - 1) Extends the base CTexture class in order to provide information about - the actual underlying textures. - 2) Stores two underlying CTextures and returns their IDs based on whether - the system is presenting to the left eye or the right eye. -*/ - -#include "Texture.h" -#include "IStereoRenderer.h" -#include "../Common/CommonRender.h" -#include - -class CStereoTexture - : public CTexture -{ -public: - CStereoTexture(const char* szName, ETEX_Format format, int nFlags); - virtual ~CStereoTexture() = default; - - //Based on which eye the renderer currently wants to use this apply - //either the left texture or the right texture - void Apply(int nTUnit, int nState = -1, int nTexMatSlot = EFTT_UNKNOWN, int nSUnit = -1, SResourceView::KeyType nResViewKey = SResourceView::DefaultView, EHWShaderClass eHWSC = eHWSC_Pixel) override; - - AZStd::vector m_textures; -}; diff --git a/Code/CryEngine/RenderDll/Common/Textures/Texture.cpp b/Code/CryEngine/RenderDll/Common/Textures/Texture.cpp deleted file mode 100644 index e210df7769..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Texture.cpp +++ /dev/null @@ -1,3457 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Common texture manager implementation. - - -#include "RenderDll_precompiled.h" -#include -#include -#include "Image/CImage.h" -#include "Image/DDSImage.h" -#include "TextureManager.h" -#include -#include "I3DEngine.h" -#include -#include "StringUtils.h" // stristr() -#include "TextureManager.h" -#include "TextureStreamPool.h" -#include "TextureHelpers.h" -#include // for AZ_MAX_PATH_LEN -#include "StereoTexture.h" -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define TEXTURE_CPP_SECTION_1 1 -#define TEXTURE_CPP_SECTION_2 2 -#define TEXTURE_CPP_SECTION_3 3 -#define TEXTURE_CPP_SECTION_4 4 -#define TEXTURE_CPP_SECTION_5 5 -#define TEXTURE_CPP_SECTION_6 6 -#define TEXTURE_CPP_SECTION_7 7 -#endif - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) -#include "../../XRenderD3D9/DriverD3D.h" // for gcpRendD3D -#endif - -#define TEXTURE_LEVEL_CACHE_PAK "dds0.pak" - -STexState CTexture::s_sDefState; -STexStageInfo CTexture::s_TexStages[MAX_TMU]; -int CTexture::s_nStreamingMode; -int CTexture::s_nStreamingUpdateMode; -bool CTexture::s_bPrecachePhase; -bool CTexture::s_bInLevelPhase = false; -bool CTexture::s_bPrestreamPhase; -int CTexture::s_nStreamingThroughput = 0; -float CTexture::s_nStreamingTotalTime = 0; -AZStd::vector CTexture::s_TexStates; -CTextureStreamPoolMgr* CTexture::s_pPoolMgr; -AZStd::set, AZ::StdLegacyAllocator> CTexture::s_vTexReloadRequests; -CryCriticalSection CTexture::s_xTexReloadLock; -#ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT -StaticInstance CTexture::s_LowResSystemCopy; -#endif - -StaticInstance CTexture::m_staticInvalidateCallbacksMutex; - -bool CTexture::m_bLoadedSystem; - -CTexture* CTexture::s_ptexMipColors_Diffuse; -CTexture* CTexture::s_ptexMipColors_Bump; -CTexture* CTexture::s_ptexFromRE[8]; -CTexture* CTexture::s_ptexShadowID[8]; -CTexture* CTexture::s_ptexShadowMask; -CTexture* CTexture::s_ptexCachedShadowMap[MAX_GSM_LODS_NUM]; -CTexture* CTexture::s_ptexNearestShadowMap; -CTexture* CTexture::s_ptexHeightMapAO[2]; -CTexture* CTexture::s_ptexHeightMapAODepth[2]; -CTexture* CTexture::s_ptexFromRE_FromContainer[2]; -CTexture* CTexture::s_ptexFromObj; -CTexture* CTexture::s_ptexSvoTree; -CTexture* CTexture::s_ptexSvoTris; -CTexture* CTexture::s_ptexSvoGlobalCM; -CTexture* CTexture::s_ptexSvoRgbs; -CTexture* CTexture::s_ptexSvoNorm; -CTexture* CTexture::s_ptexSvoOpac; -CTexture* CTexture::s_ptexFromObjCM; -CTexture* CTexture::s_ptexRT_2D; -CTexture* CTexture::s_ptexSceneNormalsMap; -CTexture* CTexture::s_ptexSceneNormalsMapMS; -CTexture* CTexture::s_ptexSceneNormalsBent; -CTexture* CTexture::s_ptexAOColorBleed; -CTexture* CTexture::s_ptexSceneDiffuse; -CTexture* CTexture::s_ptexSceneSpecular; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif -CTexture* CTexture::s_ptexAmbientLookup; - -// Post-process related textures -CTexture* CTexture::s_ptexBackBuffer; -CTexture* CTexture::s_ptexModelHudBuffer; -CTexture* CTexture::s_ptexPrevBackBuffer[2][2] = { - {NULL} -}; -CTexture* CTexture::s_ptexCached3DHud; -CTexture* CTexture::s_ptexCached3DHudScaled; -CTexture* CTexture::s_ptexBackBufferScaled[3]; -CTexture* CTexture::s_ptexBackBufferScaledTemp[2]; -CTexture* CTexture::s_ptexPrevFrameScaled; - -CTexture* CTexture::s_ptexDepthBufferQuarter; - -CTexture* CTexture::s_ptexWaterOcean; -CTexture* CTexture::s_ptexWaterVolumeTemp; -CTexture* CTexture::s_ptexWaterVolumeDDN; -CTexture* CTexture::s_ptexWaterVolumeRefl[2]; -CTexture* CTexture::s_ptexWaterCaustics[2]; -CTexture* CTexture::s_ptexWaterRipplesDDN; -CTexture* CTexture::s_ptexRainOcclusion; -CTexture* CTexture::s_ptexRainSSOcclusion[2]; - -CTexture* CTexture::s_ptexRainDropsRT[2]; - -CTexture* CTexture::s_ptexRT_ShadowPool; -CTexture* CTexture::s_ptexRT_ShadowStub; -CTexture* CTexture::s_ptexCloudsLM; - -CTexture* CTexture::s_ptexSceneTarget = NULL; -CTexture* CTexture::s_ptexSceneTargetR11G11B10F[2] = {NULL}; -CTexture* CTexture::s_ptexSceneTargetScaledR11G11B10F[4] = {NULL}; -CTexture* CTexture::s_ptexCurrSceneTarget; -CTexture* CTexture::s_ptexCurrentSceneDiffuseAccMap; -CTexture* CTexture::s_ptexSceneDiffuseAccMap; -CTexture* CTexture::s_ptexSceneSpecularAccMap; -CTexture* CTexture::s_ptexSceneDiffuseAccMapMS; -CTexture* CTexture::s_ptexSceneSpecularAccMapMS; -CTexture* CTexture::s_ptexZTarget; -CTexture* CTexture::s_ptexZTargetDownSample[4]; -CTexture* CTexture::s_ptexZTargetScaled; -CTexture* CTexture::s_ptexZTargetScaled2; -CTexture* CTexture::s_ptexHDRTarget; -CTexture* CTexture::s_ptexVelocity; -CTexture* CTexture::s_ptexVelocityTiles[3] = {NULL}; -CTexture* CTexture::s_ptexVelocityObjects[2] = {NULL}; - -CTexture* CTexture::s_ptexFurZTarget; -CTexture* CTexture::s_ptexFurLightAcc; -CTexture* CTexture::s_ptexFurPrepass; - -// Confetti Begin: David Srour -CTexture* CTexture::s_ptexGmemStenLinDepth = NULL; -// Confetti End -CTexture* CTexture::s_ptexHDRTargetPrev = NULL; -CTexture* CTexture::s_ptexHDRTargetScaled[4]; -CTexture* CTexture::s_ptexHDRTargetScaledTmp[4]; -CTexture* CTexture::s_ptexHDRTargetScaledTempRT[4]; -CTexture* CTexture::s_ptexHDRDofLayers[2]; - -CTexture* CTexture::s_ptexSceneCoCHistory[2] = {}; -CTexture* CTexture::s_ptexSceneCoC[MIN_DOF_COC_K] = {}; -CTexture* CTexture::s_ptexSceneCoCTemp = NULL; -CTexture* CTexture::s_ptexHDRTempBloom[2]; -CTexture* CTexture::s_ptexHDRFinalBloom; -CTexture* CTexture::s_ptexHDRAdaptedLuminanceCur[8]; -int CTexture::s_nCurLumTextureIndex; -CTexture* CTexture::s_ptexCurLumTexture; -CTexture* CTexture::s_ptexHDRToneMaps[NUM_HDR_TONEMAP_TEXTURES]; -CTexture* CTexture::s_ptexHDRMeasuredLuminance[MAX_GPU_NUM]; -CTexture* CTexture::s_ptexHDRMeasuredLuminanceDummy; -CTexture* CTexture::s_ptexSkyDomeMie; -CTexture* CTexture::s_ptexSkyDomeRayleigh; -CTexture* CTexture::s_ptexSkyDomeMoon; -CTexture* CTexture::s_ptexVolObj_Density; -CTexture* CTexture::s_ptexVolObj_Shadow; -CTexture* CTexture::s_ptexColorChart; -CTexture* CTexture::s_ptexSceneTargetScaled; -CTexture* CTexture::s_ptexSceneTargetScaledBlurred; -CTexture* CTexture::s_ptexStereoL = NULL; -CTexture* CTexture::s_ptexStereoR = NULL; - -CTexture* CTexture::s_ptexFlaresOcclusionRing[MAX_OCCLUSION_READBACK_TEXTURES] = {NULL}; -CTexture* CTexture::s_ptexFlaresGather = NULL; - -SEnvTexture CTexture::s_EnvCMaps[MAX_ENVCUBEMAPS]; -SEnvTexture CTexture::s_EnvTexts[MAX_ENVTEXTURES]; - -StaticInstance> CTexture::s_CustomRT_2D; - -StaticInstance> CTexture::s_ShaderTemplates(EFTT_MAX); -bool CTexture::s_ShaderTemplatesInitialized = false; - -CTexture* CTexture::s_pTexNULL = 0; - -CTexture* CTexture::s_pBackBuffer; -CTexture* CTexture::s_FrontBufferTextures[2] = { NULL }; - -CTexture* CTexture::s_ptexVolumetricFog = NULL; -CTexture* CTexture::s_ptexVolumetricFogDensityColor = NULL; -CTexture* CTexture::s_ptexVolumetricFogDensity = NULL; -CTexture* CTexture::s_ptexVolumetricClipVolumeStencil = NULL; - -#if defined(TEXSTRM_DEFERRED_UPLOAD) -ID3D11DeviceContext* CTexture::s_pStreamDeferredCtx; -#endif - -#if defined(VOLUMETRIC_FOG_SHADOWS) -CTexture* CTexture::s_ptexVolFogShadowBuf[2] = {0}; -#endif - -CTexture* CTexture::s_defaultEnvironmentProbeDummy = nullptr; - -ETEX_Format CTexture::s_eTFZ = eTF_R32F; - -//============================================================ - -SResourceView SResourceView::ShaderResourceView(ETEX_Format nFormat, int nFirstSlice, int nSliceCount, int nMostDetailedMip, int nMipCount, bool bSrgbRead, bool bMultisample) -{ - SResourceView result(0); - - result.m_Desc.eViewType = eShaderResourceView; - result.m_Desc.nFormat = nFormat; - result.m_Desc.nFirstSlice = nFirstSlice; - result.m_Desc.nSliceCount = nSliceCount; - result.m_Desc.nMostDetailedMip = nMostDetailedMip; - result.m_Desc.nMipCount = nMipCount; - result.m_Desc.bSrgbRead = bSrgbRead ? 1 : 0; - result.m_Desc.bMultisample = bMultisample ? 1 : 0; - - return result; -} - -SResourceView SResourceView::RenderTargetView(ETEX_Format nFormat, int nFirstSlice, int nSliceCount, int nMipLevel, bool bMultisample) -{ - SResourceView result(0); - - result.m_Desc.eViewType = eRenderTargetView; - result.m_Desc.nFormat = nFormat; - result.m_Desc.nFirstSlice = nFirstSlice; - result.m_Desc.nSliceCount = nSliceCount; - result.m_Desc.nMostDetailedMip = nMipLevel; - result.m_Desc.bMultisample = bMultisample ? 1 : 0; - - return result; -} - -SResourceView SResourceView::DepthStencilView(ETEX_Format nFormat, int nFirstSlice, int nSliceCount, int nMipLevel, int nFlags, bool bMultisample) -{ - SResourceView result(0); - - result.m_Desc.eViewType = eDepthStencilView; - result.m_Desc.nFormat = nFormat; - result.m_Desc.nFirstSlice = nFirstSlice; - result.m_Desc.nSliceCount = nSliceCount; - result.m_Desc.nMostDetailedMip = nMipLevel; - result.m_Desc.nFlags = nFlags; - result.m_Desc.bMultisample = bMultisample ? 1 : 0; - - return result; -} - -SResourceView SResourceView::UnorderedAccessView(ETEX_Format nFormat, int nFirstSlice, int nSliceCount, int nMipLevel, int nFlags) -{ - SResourceView result(0); - - result.m_Desc.eViewType = eUnorderedAccessView; - result.m_Desc.nFormat = nFormat; - result.m_Desc.nFirstSlice = nFirstSlice; - result.m_Desc.nSliceCount = nSliceCount; - result.m_Desc.nMostDetailedMip = nMipLevel; - result.m_Desc.nFlags = (nFlags & FT_USAGE_UAV_RWTEXTURE) ? 1 : 0; - - return result; -} - -//============================================================ - -CTexture::~CTexture() -{ - // sizes of these structures should NOT exceed L2 cache line! - // offsetof with MSVC's crt and clang produces an error -#if defined(PLATFORM_64BIT) && !(defined(AZ_PLATFORM_WINDOWS) && defined(AZ_COMPILER_CLANG)) - COMPILE_TIME_ASSERT((offsetof(CTexture, m_composition) - offsetof(CTexture, m_pFileTexMips)) <= 64); - COMPILE_TIME_ASSERT((offsetof(CTexture, m_pFileTexMips) % 64) == 0); -#endif - -#ifndef _RELEASE - if (!gRenDev->m_pRT->IsRenderThread() || gRenDev->m_pRT->IsRenderLoadingThread()) - { - __debugbreak(); - } -#endif - -#ifndef _RELEASE - if (IsStreaming()) - { - __debugbreak(); - } -#endif - - if (gRenDev && gRenDev->m_pRT) - { - gRenDev->m_pRT->RC_ReleaseDeviceTexture(this); - } - - if (m_pFileTexMips) - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - } - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - if (s_pStreamListener) - { - s_pStreamListener->OnDestroyedStreamedTexture(this); - } -#endif - -#ifndef _RELEASE - if (m_bInDistanceSortedList) - { - __debugbreak(); - } -#endif - -#ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT - s_LowResSystemCopy.erase(this); -#endif - -#if defined(USE_UNIQUE_MUTEX_PER_TEXTURE) - if (gEnv->IsEditor()) - { - // Only the editor allocated a unique mutex per texture. - delete m_invalidateCallbacksMutex; - m_invalidateCallbacksMutex = nullptr; - } -#endif -} - -void CTexture::RT_ReleaseDevice() -{ - ReleaseDeviceTexture(false); -} - -const CCryNameTSCRC& CTexture::mfGetClassName() -{ - return s_sClassName; -} - -CCryNameTSCRC CTexture::GenName(const char* name, uint32 nFlags) -{ - char buffer[AZ_MAX_PATH_LEN]; - IResourceCompilerHelper::GetOutputFilename(name, buffer, sizeof(buffer)); // change texture filename extensions to dds before we compute the crc - stack_string strName = buffer; - strName.MakeLower(); - - //'\\' in texture names causing duplication - PathUtil::ToUnixPath(strName); - - if (nFlags & FT_ALPHA) - { - strName += "_a"; - } - - return CCryNameTSCRC(strName.c_str()); -} - -class StrComp -{ -public: - bool operator () (const char* s1, const char* s2) const {return strcmp(s1, s2) < 0; } -}; - - -CTexture* CTexture::GetByID(int nID) -{ - CTexture* pTex = NULL; - - const CCryNameTSCRC& className = mfGetClassName(); - CBaseResource* pBR = CBaseResource::GetResource(className, nID, false); - if (!pBR) - { - return CTextureManager::Instance()->GetNoTexture(); - } - pTex = (CTexture*)pBR; - return pTex; -} - -CTexture* CTexture::GetByName(const char* szName, uint32 flags) -{ - CTexture* pTex = NULL; - - CCryNameTSCRC Name = GenName(szName, flags); - - CBaseResource* pBR = CBaseResource::GetResource(mfGetClassName(), Name, false); - if (!pBR) - { - return NULL; - } - pTex = (CTexture*)pBR; - return pTex; -} - -CTexture* CTexture::GetByNameCRC(CCryNameTSCRC Name) -{ - CTexture* pTex = NULL; - - CBaseResource* pBR = CBaseResource::GetResource(mfGetClassName(), Name, false); - if (!pBR) - { - return NULL; - } - pTex = (CTexture*)pBR; - return pTex; -} - -CTexture* CTexture::NewTexture(const char* name, uint32 nFlags, ETEX_Format eTFDst, bool& bFound) -{ - AZ_ASSET_NAMED_SCOPE("CTexture::NewTexture: %s", name); - - CTexture* pTex = NULL; - AZStd::string normalizedFile; - AZStd::string fileExtension; - AzFramework::StringFunc::Path::GetExtension(name, fileExtension); - if (name[0] == '$' || fileExtension.empty()) - { - //If the name starts with $ or it does not have any extension then it is one of the special texture - // that the engine requires and we would not be modifying the name - normalizedFile = name; - } - else - { - char buffer[AZ_MAX_PATH_LEN]; - IResourceCompilerHelper::GetOutputFilename(name, buffer, sizeof(buffer)); // change texture filename extensions to dds - normalizedFile = buffer; - AZStd::to_lower(normalizedFile.begin(), normalizedFile.end()); - PathUtil::ToUnixPath(normalizedFile.c_str()); - } - - CCryNameTSCRC Name = GenName(normalizedFile.c_str(), nFlags); - - CBaseResource* pBR = CBaseResource::GetResource(mfGetClassName(), Name, false); - if (!pBR) - { - //If a texture name ends in _stereo we want to create a stereo texture - const AZStd::string ending = "_stereo"; - AZStd::string fullName = normalizedFile.c_str(); - size_t nameLength = fullName.length(); - size_t endingLength = ending.length(); - if (nameLength > endingLength && fullName.compare(nameLength - endingLength, endingLength, ending) == 0) - { - pTex = new CStereoTexture(normalizedFile.c_str(), eTFDst, nFlags); - } - else - { - pTex = new CTexture(nFlags); - } - pTex->Register(mfGetClassName(), Name); - bFound = false; - pTex->m_nFlags = nFlags; - pTex->m_eTFDst = eTFDst; - pTex->m_SrcName = normalizedFile.c_str(); - } - else - { - pTex = (CTexture*)pBR; - pTex->AddRef(); - bFound = true; - } - - return pTex; -} - -void CTexture::SetDevTexture([[maybe_unused]] CDeviceTexture* pDeviceTex) -{ -#if !defined(NULL_RENDERER) - SAFE_RELEASE(m_pDevTexture); - m_pDevTexture = pDeviceTex; - if (m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - InvalidateDeviceResource(eDeviceResourceDirty); -#endif -} - -void CTexture::PostCreate() -{ - m_nUpdateFrameID = gRenDev->GetFrameID(false); - m_bPostponed = false; -} - -CTexture* CTexture::CreateTextureObject(const char* name, uint32 nWidth, uint32 nHeight, int nDepth, ETEX_Type eTT, uint32 nFlags, ETEX_Format eTF, int nCustomID) -{ - SYNCHRONOUS_LOADING_TICK(); - - bool bFound = false; - - CTexture* pTex = NewTexture(name, nFlags, eTF, bFound); - if (bFound) - { - if (!pTex->m_nWidth) - { - pTex->m_nWidth = nWidth; - } - if (!pTex->m_nHeight) - { - pTex->m_nHeight = nHeight; - } - pTex->m_nFlags |= nFlags & (FT_DONT_RELEASE | FT_USAGE_RENDERTARGET); - - return pTex; - } - pTex->m_nDepth = nDepth; - pTex->m_nWidth = nWidth; - pTex->m_nHeight = nHeight; - pTex->m_eTT = eTT; - pTex->m_eTFDst = eTF; - pTex->m_nCustomID = nCustomID; - pTex->m_SrcName = name; - - return pTex; -} - -void CTexture::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->Add(*this); - pSizer->AddObject(m_SrcName); - -#ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT - const LowResSystemCopyType::iterator& it = s_LowResSystemCopy.find(this); - if (it != CTexture::s_LowResSystemCopy.end()) - { - pSizer->AddObject((*it).second.m_lowResSystemCopy); - } -#endif - - if (m_pFileTexMips) - { - m_pFileTexMips->GetMemoryUsage(pSizer, m_nMips, m_CacheFileHeader.m_nSides); - } -} - - -CTexture* CTexture::CreateTextureArray(const char* name, ETEX_Type eType, uint32 nWidth, uint32 nHeight, uint32 nArraySize, int nMips, uint32 nFlags, ETEX_Format eTF, int nCustomID) -{ - assert(eType == eTT_2D || eType == eTT_Cube); - - if (nArraySize > 255) - { - assert(0); - return NULL; - } - - if (nMips <= 0) - { - nMips = CTexture::CalcNumMips(nWidth, nHeight); - } - - bool sRGB = (nFlags & FT_USAGE_ALLOWREADSRGB) != 0; - nFlags &= ~FT_USAGE_ALLOWREADSRGB; - - CTexture* pTex = CreateTextureObject(name, nWidth, nHeight, 1, eType, nFlags, eTF, nCustomID); - pTex->m_nWidth = nWidth; - pTex->m_nHeight = nHeight; - pTex->m_nArraySize = nArraySize; - pTex->m_nFlags |= eType == eTT_Cube ? FT_REPLICATE_TO_ALL_SIDES : 0; - - if (nFlags & FT_USAGE_RENDERTARGET) - { - bool bRes = pTex->CreateRenderTarget(eTF, Clr_Unknown); - if (!bRes) - { - pTex->m_nFlags |= FT_FAILED; - } - pTex->PostCreate(); - } - else - { - STexData td; - td.m_eTF = eTF; - td.m_nDepth = 1; - td.m_nWidth = nWidth; - td.m_nHeight = nHeight; - td.m_nMips = nMips; - td.m_nFlags = sRGB ? FIM_SRGB_READ : 0; - - bool bRes = pTex->CreateTexture(td); - if (!bRes) - { - pTex->m_nFlags |= FT_FAILED; - } - pTex->PostCreate(); - } - - pTex->m_nFlags &= ~FT_REPLICATE_TO_ALL_SIDES; - - return pTex; -} - -CTexture* CTexture::CreateRenderTarget(const char* name, uint32 nWidth, uint32 nHeight, const ColorF& cClear, ETEX_Type eTT, uint32 nFlags, ETEX_Format eTF, int nCustomID) -{ - AZ_ASSET_NAMED_SCOPE("CTexture::CreateRenderTarget: %s", name); - - CTexture* pTex = CreateTextureObject(name, nWidth, nHeight, 1, eTT, nFlags | FT_USAGE_RENDERTARGET, eTF, nCustomID); - pTex->m_nWidth = nWidth; - pTex->m_nHeight = nHeight; - pTex->m_nFlags |= nFlags; - - bool bRes = pTex->CreateRenderTarget(eTF, cClear); - if (!bRes) - { - pTex->m_nFlags |= FT_FAILED; - } - pTex->PostCreate(); - - return pTex; -} - -// Create2DTextureWithMips is similar to Create2DTexture, but it also propagates the mip argument correctly. -// The original Create2DTexture function force sets mips to 1. -// This has been separated from Create2DTexture to ensure that we preserve backwards compatibility. -bool CTexture::Create2DTextureWithMips(int nWidth, int nHeight, int nMips, [[maybe_unused]] int nFlags, const byte* pData, ETEX_Format eTFSrc, [[maybe_unused]] ETEX_Format eTFDst) -{ - if (nMips <= 0) - { - nMips = CTexture::CalcNumMips(nWidth, nHeight); - } - m_eTFSrc = eTFSrc; - m_nMips = nMips; - - STexData td; - td.m_eTF = eTFSrc; - td.m_nDepth = 1; - td.m_nWidth = nWidth; - td.m_nHeight = nHeight; - // Propagate mips correctly. (Create2DTexture always sets this to 1) - td.m_nMips = nMips; - td.m_pData[0] = pData; - - bool bRes = CreateTexture(td); - if (!bRes) - { - m_nFlags |= FT_FAILED; - } - - PostCreate(); - - return bRes; -} - -bool CTexture::Create2DTexture(int nWidth, int nHeight, int nMips, [[maybe_unused]] int nFlags, const byte* pData, ETEX_Format eTFSrc, [[maybe_unused]] ETEX_Format eTFDst) -{ - if (nMips <= 0) - { - nMips = CTexture::CalcNumMips(nWidth, nHeight); - } - m_eTFSrc = eTFSrc; - m_nMips = nMips; - - STexData td; - td.m_eTF = eTFSrc; - td.m_nDepth = 1; - td.m_nWidth = nWidth; - td.m_nHeight = nHeight; - td.m_nMips = 1; - td.m_pData[0] = pData; - - bool bRes = CreateTexture(td); - if (!bRes) - { - m_nFlags |= FT_FAILED; - } - - PostCreate(); - - return bRes; -} - -CTexture* CTexture::Create2DTexture(const char* szName, int nWidth, int nHeight, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst, bool bAsyncDevTexCreation) -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_RENDERER, g_bProfilerEnabled); - - CTexture* pTex = CreateTextureObject(szName, nWidth, nHeight, 1, eTT_2D, nFlags, eTFDst, -1); - pTex->m_bAsyncDevTexCreation = bAsyncDevTexCreation; - - pTex->Create2DTexture(nWidth, nHeight, nMips, nFlags, pData, eTFSrc, eTFDst); - - return pTex; -} - -bool CTexture::Create3DTexture(int nWidth, int nHeight, int nDepth, int nMips, [[maybe_unused]] int nFlags, const byte* pData, ETEX_Format eTFSrc, [[maybe_unused]] ETEX_Format eTFDst) -{ - m_eTFSrc = eTFSrc; - m_nMips = nMips; - - STexData td; - td.m_eTF = eTFSrc; - td.m_nWidth = nWidth; - td.m_nHeight = nHeight; - td.m_nDepth = nDepth; - td.m_nMips = nMips; - td.m_pData[0] = pData; - - bool bRes = CreateTexture(td); - if (!bRes) - { - m_nFlags |= FT_FAILED; - } - - PostCreate(); - - return bRes; -} - -CTexture* CTexture::Create3DTexture(const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst) -{ - CTexture* pTex = CreateTextureObject(szName, nWidth, nHeight, nDepth, eTT_3D, nFlags, eTFDst, -1); - - pTex->Create3DTexture(nWidth, nHeight, nDepth, nMips, nFlags, pData, eTFSrc, eTFDst); - - return pTex; -} - -CTexture* CTexture::Create2DCompositeTexture(const char* szName, int nWidth, int nHeight, int nMips, int nFlags, ETEX_Format eTFDst, const STexComposition* pCompositions, size_t nCompositions) -{ - nFlags |= FT_COMPOSITE; - nFlags &= ~FT_DONT_STREAM; - - bool bFound = false; - CTexture* pTex = NewTexture(szName, nFlags, eTFDst, bFound); - - if (!bFound) - { - pTex->m_nWidth = nWidth; - pTex->m_nHeight = nHeight; - pTex->m_nMips = nMips; - pTex->m_composition.assign(pCompositions, pCompositions + nCompositions); - - // Strip all invalid textures from the composition - - int w = 0; - for (int r = 0, c = pTex->m_composition.size(); r != c; ++r) - { - if (!pTex->m_composition[r].pTexture) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Composition %i for '%s' is missing", r, szName); - continue; - } - - if (r != w) - { - pTex->m_composition[w] = pTex->m_composition[r]; - } - ++w; - } - pTex->m_composition.resize(w); - - if (CTexture::s_bPrecachePhase) - { - pTex->m_bPostponed = true; - pTex->m_bWasUnloaded = true; - } - else - { - pTex->StreamPrepareComposition(); - } - } - - return pTex; -} - -bool CTexture::Reload() -{ - const byte* pData[6]; - int i; - bool bOK = false; - - if (IsStreamed()) - { - ReleaseDeviceTexture(false); - return ToggleStreaming(true); - } - - for (i = 0; i < 6; i++) - { - pData[i] = 0; - } - if (m_nFlags & FT_FROMIMAGE) - { - assert(!(m_nFlags & FT_USAGE_RENDERTARGET)); - bOK = LoadFromImage(m_SrcName.c_str()); // true=reloading - if (!bOK) - { - SetNoTexture(m_eTT == eTT_Cube ? CTextureManager::Instance()->GetNoTextureCM() : CTextureManager::Instance()->GetNoTexture() ); - } - } - else - if (m_nFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) - { - bOK = CreateDeviceTexture(pData); - assert(bOK); - } - - // Post Create assumes the texture loaded successfully so don't call it if that's not the case - if (bOK) - { - PostCreate(); - } - - return bOK; -} - -CTexture* CTexture::ForName(const char* name, uint32 nFlags, ETEX_Format eTFDst) -{ - SLICE_AND_SLEEP(); - AZ_ASSET_NAMED_SCOPE("CTexture::ForName: %s", name); - - bool bFound = false; - - CRY_DEFINE_ASSET_SCOPE("Texture", name); - - CTexture* pTex = NewTexture(name, nFlags, eTFDst, bFound); - if (bFound || name[0] == '$') - { - if (!bFound) - { - pTex->m_SrcName = name; - } - else - { - // switch off streaming for the same texture with the same flags except DONT_STREAM - if ((nFlags & FT_DONT_STREAM) != 0 && (pTex->GetFlags() & FT_DONT_STREAM) == 0) - { - if (!pTex->m_bPostponed) - { - pTex->ReleaseDeviceTexture(false); - } - pTex->m_nFlags |= FT_DONT_STREAM; - if (!pTex->m_bPostponed) - { - pTex->Reload(); - } - } - } - - return pTex; - } - pTex->m_SrcName = name; - -#ifndef _RELEASE - pTex->m_sAssetScopeName = gEnv->pLog->GetAssetScopeString(); -#endif - bool bPrecachePhase = CTexture::s_bPrecachePhase && !(nFlags & FT_IGNORE_PRECACHE); - - ESystemGlobalState currentGlobalState = GetISystem()->GetSystemGlobalState(); - const bool levelLoading = currentGlobalState == ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START; - - // Load textures immediately during level load since texture load - // requests during this phase are probably coming from a loading screen. - if (levelLoading || !bPrecachePhase) - { - pTex->Load(eTFDst); - } - else - { - // NOTE: attached alpha isn't detectable by flags before the header is loaded, so we do it by file-suffix - if (/*(nFlags & FT_TEX_NORMAL_MAP) &&*/ TextureHelpers::VerifyTexSuffix(EFTT_NORMALS, name) && TextureHelpers::VerifyTexSuffix(EFTT_SMOOTHNESS, name)) - { - nFlags |= FT_HAS_ATTACHED_ALPHA; - } - - pTex->m_eTFDst = eTFDst; - pTex->m_nFlags = nFlags; - pTex->m_bPostponed = true; - pTex->m_bWasUnloaded = true; - } - - return pTex; -} - -struct CompareTextures -{ - bool operator()(const CTexture* a, const CTexture* b) - { - return (azstricmp(a->GetSourceName(), b->GetSourceName()) < 0); - } -}; - -void CTexture::Precache() -{ - LOADING_TIME_PROFILE_SECTION(iSystem); - - if (!s_bPrecachePhase) - { - return; - } - if (!gRenDev) - { - return; - } - - CryLog("Requesting textures precache ..."); - - gRenDev->m_pRT->RC_PreloadTextures(); -} - -void CTexture::RT_Precache() -{ - if (gRenDev->CheckDeviceLost()) - { - return; - } - - LOADING_TIME_PROFILE_SECTION(iSystem); - AZ_TRACE_METHOD(); - - // Disable invalid file access logging if texture streaming is disabled - // If texture streaming is turned off, we will hit this on the renderthread - // and stall due to the invalid file access stalls - ICVar* sysPakLogInvalidAccess = NULL; - int pakLogFileAccess = 0; - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_texturesstreaming) - { - sysPakLogInvalidAccess = gEnv->pConsole->GetCVar("sys_PakLogInvalidFileAccess"); - if (sysPakLogInvalidAccess) - { - pakLogFileAccess = sysPakLogInvalidAccess->GetIVal(); - } - } - - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); - CryLog("-- Precaching textures..."); - iLog->UpdateLoadingScreen(0); - - std::vector TexturesForPrecaching; - std::vector TexturesForComposition; - - bool bTextureCacheExists = false; - - { - AUTO_LOCK(CBaseResource::s_cResLock); - - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - TexturesForPrecaching.reserve(pRL->m_RMap.size()); - - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp) - { - continue; - } - if (tp->CTexture::IsPostponed()) - { - if (tp->CTexture::GetFlags() & FT_COMPOSITE) - { - TexturesForComposition.push_back(tp); - } - else - { - TexturesForPrecaching.push_back(tp); - } - } - } - } - } - - // Preload all the post poned textures - { - if (!gEnv->IsEditor()) - { - CryLog("=============================== Loading textures ================================"); - } - - std::vector& Textures = TexturesForPrecaching; - std::sort(Textures.begin(), Textures.end(), CompareTextures()); - - gEnv->pSystem->GetStreamEngine()->PauseStreaming(false, 1 << eStreamTaskTypeTexture); - - for (uint32 i = 0; i < Textures.size(); i++) - { - CTexture* tp = Textures[i]; - - if (!CRenderer::CV_r_texturesstreaming || !tp->m_bStreamPrepared) - { - tp->m_bPostponed = false; - tp->Load(tp->m_eTFDst); - } - } - - while (s_StreamPrepTasks.GetNumLive()) - { - if (gRenDev->m_pRT->IsRenderThread() && !gRenDev->m_pRT->IsRenderLoadingThread()) - { - StreamState_Update(); - StreamState_UpdatePrep(); - } - else if (gRenDev->m_pRT->IsRenderLoadingThread()) - { - StreamState_UpdatePrep(); - } - - CrySleep(10); - } - - for (uint32 i = 0; i < Textures.size(); i++) - { - CTexture* tp = Textures[i]; - - if (tp->m_bStreamed && tp->m_bForceStreamHighRes) - { - tp->m_bStreamHighPriority |= 1; - tp->m_fpMinMipCur = 0; - s_pTextureStreamer->Precache(tp); - } - } - - if (!gEnv->IsEditor()) - { - CryLog("========================== Finished loading textures ============================"); - } - } - - { - std::vector& Textures = TexturesForComposition; - - for (uint32 i = 0; i < Textures.size(); i++) - { - CTexture* tp = Textures[i]; - - if (!CRenderer::CV_r_texturesstreaming || !tp->m_bStreamPrepared) - { - tp->m_bPostponed = false; - tp->StreamPrepareComposition(); - } - } - - for (uint32 i = 0; i < Textures.size(); i++) - { - CTexture* tp = Textures[i]; - - if (tp->m_bStreamed && tp->m_bForceStreamHighRes) - { - tp->m_bStreamHighPriority |= 1; - tp->m_fpMinMipCur = 0; - s_pTextureStreamer->Precache(tp); - } - } - } - - if (bTextureCacheExists) - { - //GetISystem()->GetIResourceManager()->UnloadLevelCachePak( TEXTURE_LEVEL_CACHE_PAK ); - } - - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - float dt = (t1 - t0).GetSeconds(); - CryLog("Precaching textures done in %.2f seconds", dt); - - s_bPrecachePhase = false; - - // Restore pakLogFileAccess if it was disabled during precaching - // because texture precaching was disabled - if (pakLogFileAccess) - { - sysPakLogInvalidAccess->Set(pakLogFileAccess); - } -} - -bool CTexture::Load([[maybe_unused]] ETEX_Format eTFDst) -{ - LOADING_TIME_PROFILE_SECTION_NAMED_ARGS("CTexture::Load(ETEX_Format eTFDst)", m_SrcName.c_str()); - m_bWasUnloaded = false; - m_bStreamed = false; - -#if !defined(NULL_RENDERER) - bool bFound = LoadFromImage(m_SrcName.c_str(), eTFDst); // false=not reloading -#else - bool bFound = false; -#endif - - if (!bFound) - { - SetNoTexture(m_eTT == eTT_Cube ? CTextureManager::Instance()->GetNoTextureCM() : CTextureManager::Instance()->GetNoTexture()); - } - - m_nFlags |= FT_FROMIMAGE; - PostCreate(); - - return bFound; -} - -bool CTexture::ToggleStreaming(const bool bEnable) -{ - if (!(m_nFlags & (FT_FROMIMAGE | FT_DONT_RELEASE)) || (m_nFlags & FT_DONT_STREAM)) - { - return false; - } - AbortStreamingTasks(this); - if (bEnable) - { - if (IsStreamed()) - { - return true; - } - ReleaseDeviceTexture(false); - m_bStreamed = true; - if (StreamPrepare(true)) - { - return true; - } - if (m_pFileTexMips) - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - } - m_bStreamed = false; - if (m_bNoTexture) - { - return true; - } - } - ReleaseDeviceTexture(false); - return Reload(); -} - -bool CTexture::LoadFromImage(const char* name, ETEX_Format eTFDst) -{ - LOADING_TIME_PROFILE_SECTION_ARGS(name); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texnoload) - { - if (SetNoTexture(CTextureManager::Instance()->GetNoTexture() )) - { - return true; - } - } - - string sFileName(name); - sFileName.MakeLower(); - - m_eTFDst = eTFDst; - - // try to stream-in the texture - if (CRenderer::CV_r_texturesstreaming && !(m_nFlags & FT_DONT_STREAM) && (m_eTT == eTT_2D || m_eTT == eTT_Cube)) - { - m_bStreamed = true; - if (StreamPrepare(true)) - { - assert(m_pDevTexture); - return true; - } - m_nFlags |= FT_DONT_STREAM; - m_bStreamed = false; - m_bForceStreamHighRes = false; - if (m_bNoTexture) - { - if (m_pFileTexMips) - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - m_bStreamed = false; - } - return true; - } - } - -#ifndef _RELEASE - CRY_DEFINE_ASSET_SCOPE("Texture", m_sAssetScopeName); -#endif - - if (m_bPostponed) - { - if (s_pTextureStreamer->BeginPrepare(this, sFileName, (m_nFlags & FT_ALPHA) ? FIM_ALPHA : 0)) - { - return true; - } - } - - - uint32 nImageFlags = (m_nFlags & FT_ALPHA) ? FIM_ALPHA : 0; - - if (I3DEngine* p3DEngine = gEnv->p3DEngine) - { - if (ITextureLoadHandler* pTextureHandler = p3DEngine->GetTextureLoadHandlerForImage(sFileName.c_str())) - { - STextureLoadData loadData; - loadData.m_pTexture = this; - loadData.m_nFlags = m_nFlags; - if (pTextureHandler->LoadTextureData(sFileName.c_str(), loadData)) - { - bool bHasAlphaFlag = false; - - //we must clear this or else our texture won't load properly - if ((m_nFlags & FT_ALPHA) == FT_ALPHA) - { - m_nFlags &= ~FT_ALPHA; - bHasAlphaFlag = true; - } - - _smart_ptr pImage = CImageFile::mfLoad_mem(sFileName, loadData.m_pData, loadData.m_Width, loadData.m_Height, loadData.m_Format, loadData.m_NumMips, loadData.m_nFlags); - m_bisTextureMissing = !pImage || pImage->mfGet_IsImageMissing(); - loadData.m_pData = nullptr; - bool bLoadResult = Load(&*pImage); - - if (bHasAlphaFlag) - { - m_nFlags |= FT_ALPHA; - } - - return bLoadResult; - } - SetNoTexture(CTextureManager::Instance()->GetNoTexture() ); - return true; - } - } - _smart_ptr pImage = CImageFile::mfLoad_file(sFileName, nImageFlags); - m_bisTextureMissing = !pImage || pImage->mfGet_IsImageMissing(); - return Load(pImage); -} - -bool CTexture::Load([[maybe_unused]] CImageFile* pImage) -{ -#if !defined(NULL_RENDERER) - if (!pImage || pImage->mfGetFormat() == eTF_Unknown) - { - return false; - } - - LOADING_TIME_PROFILE_SECTION_NAMED_ARGS("CTexture::Load(CImageFile* pImage)", pImage->mfGet_filename().c_str()); - - // DHX-104: If this failed previously (maybe because the DDS was being generated), we must unset the failure flag - // so it doesn't appear to have failed again. - m_nFlags &= ~FT_FAILED; - if ((m_nFlags & FT_ALPHA) && !pImage->mfIs_image(0)) - { - SetNoTexture( CTextureManager::Instance()->GetWhiteTexture() ); - return true; - } - const char* name = pImage->mfGet_filename().c_str(); - if (pImage->mfGet_Flags() & FIM_SPLITTED) // propagate splitted file flag - { - m_nFlags |= FT_SPLITTED; - } - if (pImage->mfGet_Flags() & FIM_X360_NOT_PRETILED) - { - m_nFlags |= FT_TEX_WAS_NOT_PRE_TILED; - } - if (pImage->mfGet_Flags() & FIM_NORMALMAP) - { - if (!(m_nFlags & FT_TEX_NORMAL_MAP) && !CryStringUtils::stristr(name, "_ddn")) - { - // becomes reported as editor error - gEnv->pSystem->Warning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE, - name, "Not a normal map texture attempted to be used as a normal map: %s", name); - } - } - - if (!(m_nFlags & FT_ALPHA) && !( - pImage->mfGetFormat() == eTF_BC5U || pImage->mfGetFormat() == eTF_BC5S || pImage->mfGetFormat() == eTF_BC7 || pImage->mfGetFormat() == eTF_EAC_RG11 - ) && CryStringUtils::stristr(name, "_ddn") != 0 && GetDevTexture()) // improvable code - { - // becomes reported as editor error - gEnv->pSystem->Warning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE, - name, "Wrong format '%s' for normal map texture '%s'", CTexture::GetFormatName(), name); - } - - if (pImage->mfGet_Flags() & FIM_NOTSUPPORTS_MIPS && !(m_nFlags & FT_NOMIPS)) - { - m_nFlags |= FT_FORCE_MIPS; - } - if (pImage->mfGet_Flags() & FIM_HAS_ATTACHED_ALPHA) - { - m_nFlags |= FT_HAS_ATTACHED_ALPHA; // if the image has alpha attached we store this in the CTexture - } - m_eSrcTileMode = pImage->mfGetTileMode(); - - STexData td; - td.m_nFlags = pImage->mfGet_Flags(); - td.m_pData[0] = pImage->mfGet_image(0); - td.m_nWidth = pImage->mfGet_width(); - td.m_nHeight = pImage->mfGet_height(); - td.m_nDepth = pImage->mfGet_depth(); - td.m_eTF = pImage->mfGetFormat(); - td.m_nMips = pImage->mfGet_numMips(); - td.m_fAvgBrightness = pImage->mfGet_avgBrightness(); - td.m_cMinColor = pImage->mfGet_minColor(); - td.m_cMaxColor = pImage->mfGet_maxColor(); - if ((m_nFlags & FT_NOMIPS) || td.m_nMips <= 0) - { - td.m_nMips = 1; - } - td.m_pFilePath = pImage->mfGet_filename(); - - // base range after normalization, fe. [0,1] for 8bit images, or [0,2^15] for RGBE/HDR data - if ((td.m_eTF == eTF_R9G9B9E5) || (td.m_eTF == eTF_BC6UH) || (td.m_eTF == eTF_BC6SH)) - { - td.m_cMinColor /= td.m_cMaxColor.a; - td.m_cMaxColor /= td.m_cMaxColor.a; - } - - // check if it's a cubemap - if (pImage->mfIs_image(1)) - { - for (int i = 1; i < 6; i++) - { - td.m_pData[i] = pImage->mfGet_image(i); - } - } - - bool bRes = false; - if (pImage) - { - FormatFixup(td); - bRes = CreateTexture(td); - } - - for (int i = 0; i < 6; i++) - { - if (td.m_pData[i] && td.WasReallocated(i)) - { - SAFE_DELETE_ARRAY(td.m_pData[i]); - } - } - - return bRes; -#else - SetNoTexture(CTextureManager::Instance()->GetWhiteTexture() ); - return true; -#endif -} - -bool CTexture::CreateTexture(STexData& td) -{ - m_nWidth = td.m_nWidth; - m_nHeight = td.m_nHeight; - m_nDepth = td.m_nDepth; - m_eTFSrc = td.m_eTF; - m_nMips = td.m_nMips; - m_fAvgBrightness = td.m_fAvgBrightness; - m_cMinColor = td.m_cMinColor; - m_cMaxColor = td.m_cMaxColor; - m_cClearColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - m_bUseDecalBorderCol = (td.m_nFlags & FIM_DECAL) != 0; - m_bIsSRGB = (td.m_nFlags & FIM_SRGB_READ) != 0; - - assert(m_nWidth && m_nHeight && m_nMips); - - if (td.m_pData[1] || (m_nFlags & FT_REPLICATE_TO_ALL_SIDES)) - { - m_eTT = eTT_Cube; - } - else - { - if (m_nDepth > 1 || m_eTT == eTT_3D) - { - m_eTT = eTT_3D; - } - else - { - m_eTT = eTT_2D; - } - } - - if (m_eTFDst == eTF_Unknown) - { - m_eTFDst = m_eTFSrc; - } - - if (!ImagePreprocessing(td)) - { - return false; - } - - assert(m_nWidth && m_nHeight && m_nMips); - - const int nMaxTextureSize = gRenDev->GetMaxTextureSize(); - if (nMaxTextureSize > 0) - { - if (m_nWidth > nMaxTextureSize || m_nHeight > nMaxTextureSize) - { - return false; - } - } - - const byte* pData[6]; - for (uint32 i = 0; i < 6; i++) - { - pData[i] = td.m_pData[i]; - } - - bool bRes = CreateDeviceTexture(pData); - - return bRes; -} - -ETEX_Format CTexture::FormatFixup(ETEX_Format src) -{ - switch (src) - { - case eTF_L8V8U8X8: - return eTF_R8G8B8A8S; - case eTF_B8G8R8: - return eTF_R8G8B8A8; - case eTF_L8V8U8: - return eTF_R8G8B8A8S; - case eTF_L8: - return eTF_R8G8B8A8; - case eTF_A8L8: - return eTF_R8G8B8A8; - - case eTF_B5G5R5: - return eTF_R8G8B8A8; - case eTF_B5G6R5: - return eTF_R8G8B8A8; - case eTF_B4G4R4A4: - return eTF_R8G8B8A8; - - default: - return src; - } -} - -bool CTexture::FormatFixup(STexData& td) -{ - const ETEX_Format targetFmt = FormatFixup(td.m_eTF); - - if (m_eSrcTileMode == eTM_None) - { - // Try and expand - int nSourceSize = CTexture::TextureDataSize(td.m_nWidth, td.m_nHeight, td.m_nDepth, td.m_nMips, 1, td.m_eTF); - int nTargetSize = CTexture::TextureDataSize(td.m_nWidth, td.m_nHeight, td.m_nDepth, td.m_nMips, 1, targetFmt); - - for (int nImage = 0; nImage < sizeof(td.m_pData) / sizeof(td.m_pData[0]); ++nImage) - { - if (td.m_pData[nImage]) - { - byte* pNewImage = new byte[nTargetSize]; - CTexture::ExpandMipFromFile(pNewImage, nTargetSize, td.m_pData[nImage], nSourceSize, td.m_eTF); - td.AssignData(nImage, pNewImage); - } - } - - td.m_eTF = targetFmt; - } - else - { -#ifndef _RELEASE - if (targetFmt != td.m_eTF) - { - __debugbreak(); - } -#endif - } - - return true; -} - -bool CTexture::ImagePreprocessing(STexData& td) -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_RENDERER, g_bProfilerEnabled); - -#if !defined(_RELEASE) - const char* pTexFileName = td.m_pFilePath ? td.m_pFilePath : "$Unknown"; -#endif - - const ETEX_Format eTFDst = ClosestFormatSupported(m_eTFDst); - if (eTFDst == eTF_Unknown) - { - 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; - m_nWidth = m_nHeight = m_nDepth = m_nMips = 0; - -#if !defined(_RELEASE) - TextureError(pTexFileName, "Trying to create a texture with unsupported target format %s!", NameForTextureFormat(eTFDst)); -#endif - return false; - } - - const ETEX_Format eTF = td.m_eTF; - const bool fmtConversionNeeded = eTFDst != m_eTFDst || eTF != eTFDst; - -#if !(defined(WIN32) || defined(WIN64)) || defined(OPENGL) || defined(NULL_RENDERER) - if (fmtConversionNeeded) - { - 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; - m_nWidth = m_nHeight = m_nDepth = m_nMips = 0; - -# if !defined(_RELEASE) - TextureError(pTexFileName, "Trying an image format conversion from %s to %s. This is not supported on this platform!", NameForTextureFormat(eTF), NameForTextureFormat(eTFDst)); -# endif - return false; - } -#else - const bool doProcessing = fmtConversionNeeded && (m_nFlags & FT_TEX_FONT) == 0; // we generate the font in native format - if (doProcessing) - { - m_eTFSrc = eTFDst; - m_eTFDst = eTFDst; - - const int nSrcWidth = td.m_nWidth; - const int nSrcHeight = td.m_nHeight; - - for (int i = 0; i < 6; i++) - { - const byte* pTexData = td.m_pData[i]; - if (pTexData) - { - int nOutSize = 0; - const byte* pNewData = Convert(pTexData, nSrcWidth, nSrcHeight, td.m_nMips, eTF, eTFDst, nOutSize, true); - if (pNewData) - { - td.AssignData(i, pNewData); - } - } - } - } -#endif - -#if defined(TEXTURE_GET_SYSTEM_COPY_SUPPORT) && !defined(NULL_RENDERER) - if (m_nFlags & FT_KEEP_LOWRES_SYSCOPY) - { - PrepareLowResSystemCopy(td.m_pData[0], true); - } -#endif - - return true; -} - -int CTexture::CalcNumMips(int nWidth, int nHeight) -{ - int nMips = 0; - while (nWidth || nHeight) - { - if (!nWidth) - { - nWidth = 1; - } - if (!nHeight) - { - nHeight = 1; - } - nWidth >>= 1; - nHeight >>= 1; - nMips++; - } - //For DX11 hardware, the number of mips must be between 1 and 7, inclusive - //0 is a valid result but means that D3D11 will generate a full series of mipmaps - if (nMips > 7) - { - return 7; - } - - return nMips; -} - -uint32 CTexture::TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, const ETEX_Format eTF, ETEX_TileMode eTM) -{ - if (eTF == eTF_Unknown) - { - return 0; - } - - if (eTM != eTM_None) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - - __debugbreak(); - return 0; - } - else - { - const Vec2i BlockDim = GetBlockDim(eTF); - const int nBytesPerBlock = CImageExtensionHelper::BytesPerBlock(eTF); - uint32 nSize = 0; - - while ((nWidth || nHeight || nDepth) && nMips) - { - nWidth = max(1U, nWidth); - nHeight = max(1U, nHeight); - nDepth = max(1U, nDepth); - - nSize += ((nWidth + BlockDim.x - 1) / BlockDim.x) * ((nHeight + BlockDim.y - 1) / BlockDim.y) * nDepth * nBytesPerBlock; - - nWidth >>= 1; - nHeight >>= 1; - nDepth >>= 1; - --nMips; - } - - return nSize * nSlices; - } -} - -bool CTexture::IsInPlaceFormat(const ETEX_Format fmt) -{ - switch (fmt) - { - case eTF_R8G8B8A8S: - case eTF_R8G8B8A8: - - case eTF_A8: - case eTF_R8: - case eTF_R8S: - case eTF_R16: - case eTF_R16U: - case eTF_R16G16U: - case eTF_R10G10B10A2UI: - case eTF_R16F: - case eTF_R32F: - case eTF_R8G8: - case eTF_R8G8S: - case eTF_R16G16: - case eTF_R16G16S: - case eTF_R16G16F: - case eTF_R11G11B10F: - case eTF_R10G10B10A2: - case eTF_R16G16B16A16: - case eTF_R16G16B16A16S: - case eTF_R16G16B16A16F: - case eTF_R32G32B32A32F: - - case eTF_CTX1: - case eTF_BC1: - case eTF_BC2: - case eTF_BC3: - case eTF_BC4U: - case eTF_BC4S: - case eTF_BC5U: - case eTF_BC5S: -#if defined(CRY_DDS_DX10_SUPPORT) - case eTF_BC6UH: - case eTF_BC6SH: - case eTF_BC7: - case eTF_R9G9B9E5: -#endif - case eTF_EAC_R11: - case eTF_EAC_RG11: - case eTF_ETC2: - case eTF_ETC2A: - - case eTF_B8G8R8A8: - case eTF_B8G8R8X8: -#ifdef CRY_USE_METAL - case eTF_PVRTC2: - case eTF_PVRTC4: -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case eTF_ASTC_4x4: - case eTF_ASTC_5x4: - case eTF_ASTC_5x5: - case eTF_ASTC_6x5: - case eTF_ASTC_6x6: - case eTF_ASTC_8x5: - case eTF_ASTC_8x6: - case eTF_ASTC_8x8: - case eTF_ASTC_10x5: - case eTF_ASTC_10x6: - case eTF_ASTC_10x8: - case eTF_ASTC_10x10: - case eTF_ASTC_12x10: - case eTF_ASTC_12x12: -#endif - return true; - default: - return false; - } -} - -void CTexture::ExpandMipFromFile(byte* dest, [[maybe_unused]] const int destSize, const byte* src, const int srcSize, const ETEX_Format fmt) -{ - if (IsInPlaceFormat(fmt)) - { - assert(destSize == srcSize); - if (dest != src) - { - cryMemcpy(dest, src, srcSize); - } - - return; - } - - // upload mip from file with conversions depending on format and platform specifics - switch (fmt) - { - case eTF_B8G8R8: - for (int i = srcSize / 3 - 1; i >= 0; --i) - { - dest[i * 4 + 0] = src[i * 3 + 2]; - dest[i * 4 + 1] = src[i * 3 + 1]; - dest[i * 4 + 2] = src[i * 3 + 0]; - dest[i * 4 + 3] = 255; - } - break; - case eTF_L8V8U8X8: - assert(destSize == srcSize); - if (dest != src) - { - cryMemcpy(dest, src, srcSize); - } - for (int i = srcSize / 4 - 1; i >= 0; --i) - { - dest[i * 4 + 0] = src[i * 3 + 0]; - dest[i * 4 + 1] = src[i * 3 + 1]; - dest[i * 4 + 2] = src[i * 3 + 2]; - dest[i * 4 + 3] = src[i * 3 + 3]; - } - break; - case eTF_L8V8U8: - for (int i = srcSize / 3 - 1; i >= 0; --i) - { - dest[i * 4 + 0] = src[i * 3 + 0]; - dest[i * 4 + 1] = src[i * 3 + 1]; - dest[i * 4 + 2] = src[i * 3 + 2]; - dest[i * 4 + 3] = 255; - } - break; - case eTF_L8: - for (int i = srcSize - 1; i >= 0; --i) - { - const byte bSrc = src[i]; - dest[i * 4 + 0] = bSrc; - dest[i * 4 + 1] = bSrc; - dest[i * 4 + 2] = bSrc; - dest[i * 4 + 3] = 255; - } - break; - case eTF_A8L8: - for (int i = srcSize - 1; i >= 0; i -= 2) - { - const byte bSrcL = src[i - 1]; - const byte bSrcA = src[i - 0]; - dest[i * 4 + 0] = bSrcL; - dest[i * 4 + 1] = bSrcL; - dest[i * 4 + 2] = bSrcL; - dest[i * 4 + 3] = bSrcA; - } - break; - case eTF_B5G5R5: - case eTF_B5G6R5: - case eTF_B4G4R4A4: - default: - assert(0); - } -} - -bool CTexture::Invalidate(int nNewWidth, int nNewHeight, ETEX_Format eTF) -{ - bool bRelease = false; - if (nNewWidth > 0 && nNewWidth != m_nWidth) - { - m_nWidth = nNewWidth; - bRelease = true; - } - if (nNewHeight > 0 && nNewHeight != m_nHeight) - { - m_nHeight = nNewHeight; - bRelease = true; - } - if (eTF != eTF_Unknown && eTF != m_eTFDst) - { - m_eTFDst = eTF; - bRelease = true; - } - - if (!m_pDevTexture) - { - return false; - } - - if (bRelease) - { - if (m_nFlags & FT_FORCE_MIPS) - { - m_nMips = 1; - } - - ReleaseDeviceTexture(true); - } - - return bRelease; -} - -SResourceView& CTexture::GetResourceView(const SResourceView& rvDesc) -{ - assert(m_pRenderTargetData); - - int nIndex = m_pRenderTargetData->m_ResourceViews.Find(rvDesc); - - if (nIndex < 0) - { - SResourceView* pRvDesc = m_pRenderTargetData->m_ResourceViews.AddIndex(1); - pRvDesc->m_Desc = rvDesc.m_Desc; - pRvDesc->m_pDeviceResourceView = CreateDeviceResourceView(rvDesc); - - nIndex = m_pRenderTargetData->m_ResourceViews.size() - 1; - } - - return m_pRenderTargetData->m_ResourceViews[nIndex]; -} - -D3DShaderResourceView* CTexture::GetShaderResourceView(SResourceView::KeyType resourceViewID /*= SResourceView::DefaultView*/, bool bLegacySrgbLookup /*= false*/) -{ - if ((int64)resourceViewID <= (int64)SResourceView::DefaultView) - { - void* pResult = m_pDeviceShaderResource; - - if (resourceViewID == SResourceView::DefaultViewMS && m_pRenderTargetData && m_pRenderTargetData->m_pDeviceTextureMSAA) - { - SResourceView& pMultisampledRV = GetResourceView(SResourceView::ShaderResourceView(m_eTFDst, 0, -1, 0, -1, false, true)); - pResult = pMultisampledRV.m_pDeviceResourceView; - } - - // NOTE: "m_pDeviceShaderResourceSRGB != nullptr" implies FT_USAGE_ALLOWREADSRGB - if ((resourceViewID == SResourceView::DefaultViewSRGB || bLegacySrgbLookup) && m_pDeviceShaderResourceSRGB) - { - pResult = m_pDeviceShaderResourceSRGB; - } - - return (D3DShaderResourceView*)pResult; - } - else - { - return (D3DShaderResourceView*)GetResourceView(resourceViewID).m_pDeviceResourceView; - } -} - -void CTexture::SetShaderResourceView(D3DShaderResourceView* pDeviceShaderResource, bool bMultisampled) -{ - if (bMultisampled && m_pRenderTargetData && m_pRenderTargetData->m_pDeviceTextureMSAA) - { - SResourceView& pMultisampledRV = GetResourceView(SResourceView::ShaderResourceView(m_eTFDst, 0, -1, 0, -1, false, true)); - - if (pMultisampledRV.m_pDeviceResourceView != pDeviceShaderResource) - { - pMultisampledRV.m_pDeviceResourceView = pDeviceShaderResource; - InvalidateDeviceResource(eDeviceResourceViewDirty); - } - } - else - { - if (m_pDeviceShaderResource != pDeviceShaderResource) - { - m_pDeviceShaderResource = pDeviceShaderResource; - InvalidateDeviceResource(eDeviceResourceViewDirty); - } - } -} - -D3DUnorderedAccessView* CTexture::GetDeviceUAV() -{ - const SResourceView& rvDesc = m_pRenderTargetData ? GetResourceView(SResourceView::UnorderedAccessView(m_eTFDst, 0, -1, 0, m_nFlags)) : NULL; - return (D3DUnorderedAccessView*)rvDesc.m_pDeviceResourceView; -} - -D3DDepthSurface* CTexture::GetDeviceDepthStencilSurf(int nFirstSlice, int nSliceCount) -{ - const SResourceView& rvDesc = GetResourceView(SResourceView::DepthStencilView(m_eTFDst, nFirstSlice, nSliceCount)); - return (D3DDepthSurface*)rvDesc.m_pDeviceResourceView; -} - -byte* CTexture::GetData32([[maybe_unused]] int nSide, [[maybe_unused]] int nLevel, [[maybe_unused]] byte* pDst, [[maybe_unused]] ETEX_Format eDstFormat) -{ -#if (defined(WIN32) || defined(WIN64)) && !defined(NULL_RENDERER) - CDeviceTexture* pDevTexture = GetDevTexture(); - pDevTexture->DownloadToStagingResource(D3D11CalcSubresource(nLevel, nSide, m_nMips), [&](void* pData, [[maybe_unused]] uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - if (m_eTFDst != eTF_R8G8B8A8) - { - int nOutSize = 0; - - if (m_eTFSrc == eDstFormat && pDst) - { - memcpy(pDst, pData, GetDeviceDataSize()); - } - else - { - pDst = Convert((byte*)pData, m_nWidth, m_nHeight, 1, m_eTFSrc, eDstFormat, nOutSize, true); - } - } - else - { - if (!pDst) - { - pDst = new byte[m_nWidth * m_nHeight * 4]; - } - - memcpy(pDst, pData, m_nWidth * m_nHeight * 4); - } - - return true; - }); - - return pDst; -#else - return 0; -#endif -} - -const int CTexture::GetSize(bool bIncludePool) const -{ - int nSize = sizeof(CTexture); - nSize += m_SrcName.capacity(); - if (m_pRenderTargetData) - { - nSize += sizeof(*m_pRenderTargetData); - } - if (m_pFileTexMips) - { - nSize += m_pFileTexMips->GetSize(m_nMips, m_CacheFileHeader.m_nSides); - if (bIncludePool && m_pFileTexMips->m_pPoolItem) - { - nSize += m_pFileTexMips->m_pPoolItem->GetSize(); - } - } - - return nSize; -} - -void CTexture::Init() -{ - SDynTexture::Init(); - InitStreaming(); - CTexture::s_TexStates.reserve(300); // this likes to expand, so it'd be nice if it didn't; 300 => ~6Kb, there were 171 after one level - - SDynTexture2::Init(eTP_Clouds); -} - -void CTexture::PostInit() -{ - LOADING_TIME_PROFILE_SECTION; - if (!gRenDev->IsShaderCacheGenMode()) - { - CTexture::LoadDefaultSystemTextures(); - } -} - -int __cdecl TexCallback(const VOID * arg1, const VOID * arg2) -{ - CTexture** pi1 = (CTexture**)arg1; - CTexture** pi2 = (CTexture**)arg2; - CTexture* ti1 = *pi1; - CTexture* ti2 = *pi2; - - if (ti1->GetDeviceDataSize() > ti2->GetDeviceDataSize()) - { - return -1; - } - if (ti1->GetDeviceDataSize() < ti2->GetDeviceDataSize()) - { - return 1; - } - return azstricmp(ti1->GetSourceName(), ti2->GetSourceName()); -} - -int __cdecl TexCallbackMips(const VOID * arg1, const VOID * arg2) -{ - CTexture** pi1 = (CTexture**)arg1; - CTexture** pi2 = (CTexture**)arg2; - CTexture* ti1 = *pi1; - CTexture* ti2 = *pi2; - - int nSize1, nSize2; - - nSize1 = ti1->GetActualSize(); - nSize2 = ti2->GetActualSize(); - - if (nSize1 > nSize2) - { - return -1; - } - if (nSize1 < nSize2) - { - return 1; - } - return azstricmp(ti1->GetSourceName(), ti2->GetSourceName()); -} - -void CTexture::Update() -{ - FUNCTION_PROFILER_RENDERER; - - CRenderer* rd = gRenDev; - char buf[256] = ""; - - // reload pending texture reload requests - { - AZStd::set, AZ::StdLegacyAllocator> queue; - - s_xTexReloadLock.Lock(); - s_vTexReloadRequests.swap(queue); - s_xTexReloadLock.Unlock(); - - for (auto i = queue.begin(); i != queue.end(); i++) - { - ReloadFile(*i); - } - } - - CTexture::s_bStreamingFromHDD = gEnv->pSystem->GetStreamEngine()->IsStreamDataOnHDD(); - CTexture::s_nStatsStreamPoolInUseMem = CTexture::s_pPoolMgr->GetInUseSize(); - - s_pTextureStreamer->ApplySchedule(ITextureStreamer::eASF_Full); - s_pTextureStreamer->BeginUpdateSchedule(); - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - StreamUpdateStats(); -#endif - - SDynTexture::Tick(); - - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - ResourcesMapItor itor; - - if ((s_nStreamingMode != CRenderer::CV_r_texturesstreaming) || (s_nStreamingUpdateMode != CRenderer::CV_r_texturesstreamingUpdateType)) - { - InitStreaming(); - } - - if (pRL) - { -#ifndef CONSOLE_CONST_CVAR_MODE - uint32 i; - if (CRenderer::CV_r_texlog == 2 || CRenderer::CV_r_texlog == 3 || CRenderer::CV_r_texlog == 4) - { - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - TArray Texs; - int Size = 0; - int PartSize = 0; - if (CRenderer::CV_r_texlog == 2 || CRenderer::CV_r_texlog == 3) - { - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (CRenderer::CV_r_texlog == 3 && tp->IsNoTexture()) - { - Texs.AddElem(tp); - } - else - if (CRenderer::CV_r_texlog == 2 && !tp->IsNoTexture() && tp->m_pFileTexMips) // (tp->GetFlags() & FT_FROMIMAGE)) - { - Texs.AddElem(tp); - } - } - if (CRenderer::CV_r_texlog == 3) - { - CryLogAlways("Logging to MissingTextures.txt..."); - fileHandle = fxopen("MissingTextures.txt", "w"); - } - else - { - CryLogAlways("Logging to UsedTextures.txt..."); - fileHandle = fxopen("UsedTextures.txt", "w"); - } - AZ::IO::Print(fileHandle, "*** All textures: ***\n"); - - if (Texs.Num()) - { - qsort(&Texs[0], Texs.Num(), sizeof(CTexture*), TexCallbackMips); - } - - for (i = 0; i < Texs.Num(); i++) - { - int w = Texs[i]->GetWidth(); - int h = Texs[i]->GetHeight(); - - int nTSize = Texs[i]->m_pFileTexMips->GetSize(Texs[i]->GetNumMips(), Texs[i]->GetNumSides()); - - AZ::IO::Print(fileHandle, "%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()); - //Size += Texs[i]->GetDataSize(); - Size += nTSize; - - PartSize += Texs[i]->GetDeviceDataSize(); - } - AZ::IO::Print(fileHandle, "*** Total Size: %d\n\n", Size /*, PartSize, PartSize */); - - Texs.Free(); - } - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (tp->m_nAccessFrameID == rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID) - { - Texs.AddElem(tp); - } - } - - if (fileHandle != AZ::IO::InvalidHandle) - { - gEnv->pFileIO->Close(fileHandle); - fileHandle = AZ::IO::InvalidHandle; - } - - fileHandle = fxopen("UsedTextures_Frame.txt", "w"); - - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "\n\n*** Textures used in current frame: ***\n"); - } - else - { - rd->TextToScreenColor(4, 13, 1, 1, 0, 1, "*** Textures used in current frame: ***"); - } - int nY = 17; - - if (Texs.Num()) - { - qsort(&Texs[0], Texs.Num(), sizeof(CTexture*), TexCallback); - } - - Size = 0; - for (i = 0; i < Texs.Num(); i++) - { - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "%.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()); - } - else - { - sprintf_s(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()); - rd->TextToScreenColor(4, nY, 0, 1, 0, 1, buf); - nY += 3; - } - PartSize += Texs[i]->GetDeviceDataSize(); - Size += Texs[i]->GetDataSize(); - } - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "*** Total Size: %.3fMb, Device Size: %.3fMb\n\n", Size / (1024.0f * 1024.0f), PartSize / (1024.0f * 1024.0f)); - } - else - { - sprintf_s(buf, "*** Total Size: %.3fMb, Device Size: %.3fMb", Size / (1024.0f * 1024.0f), PartSize / (1024.0f * 1024.0f)); - rd->TextToScreenColor(4, nY + 1, 0, 1, 1, 1, buf); - } - - Texs.Free(); - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (tp && !tp->IsNoTexture()) - { - Texs.AddElem(tp); - } - } - - if (fileHandle != AZ::IO::InvalidHandle) - { - gEnv->pFileIO->Close(fileHandle); - fileHandle = AZ::IO::InvalidHandle; - } - fileHandle = fxopen("UsedTextures_All.txt", "w"); - - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "\n\n*** All Existing Textures: ***\n"); - } - else - { - rd->TextToScreenColor(4, 13, 1, 1, 0, 1, "*** Textures loaded: ***"); - } - - if (Texs.Num()) - { - qsort(&Texs[0], Texs.Num(), sizeof(CTexture*), TexCallback); - } - - Size = 0; - for (i = 0; i < Texs.Num(); i++) - { - if (fileHandle != AZ::IO::InvalidHandle) - { - int w = Texs[i]->GetWidth(); - int h = Texs[i]->GetHeight(); - AZ::IO::Print(fileHandle, "%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()); - } - else - { - sprintf_s(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()); - rd->TextToScreenColor(4, nY, 0, 1, 0, 1, buf); - nY += 3; - } - Size += Texs[i]->GetDeviceDataSize(); - } - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "*** Total Size: %.3fMb\n\n", Size / (1024.0f * 1024.0f)); - } - else - { - sprintf_s(buf, "*** Total Size: %.3fMb", Size / (1024.0f * 1024.0f)); - rd->TextToScreenColor(4, nY + 1, 0, 1, 1, 1, buf); - } - - - Texs.Free(); - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (tp && !tp->IsNoTexture() && !tp->IsStreamed()) - { - Texs.AddElem(tp); - } - } - - if (fileHandle != AZ::IO::InvalidHandle) - { - gEnv->pFileIO->Close(fileHandle); - fileHandle = AZ::IO::InvalidHandle; - } - - if (CRenderer::CV_r_texlog != 4) - { - CRenderer::CV_r_texlog = 0; - } - } - else - if (CRenderer::CV_r_texlog == 1) - { - //char *str = GetTexturesStatusText(); - - TArray Texs; - //TArray TexsNM; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (tp && !tp->IsNoTexture()) - { - Texs.AddElem(tp); - //if (tp->GetFlags() & FT_TEX_NORMAL_MAP) - // TexsNM.AddElem(tp); - } - } - - if (Texs.Num()) - { - qsort(&Texs[0], Texs.Num(), sizeof(CTexture*), TexCallback); - } - - int64 AllSize = 0; - int64 Size = 0; - int64 PartSize = 0; - int64 NonStrSize = 0; - int nNoStr = 0; - int64 SizeNM = 0; - int64 SizeDynCom = 0; - int64 SizeDynAtl = 0; - int64 PartSizeNM = 0; - int nNumTex = 0; - int nNumTexNM = 0; - int nNumTexDynAtl = 0; - int nNumTexDynCom = 0; - for (i = 0; i < Texs.Num(); i++) - { - CTexture* tex = Texs[i]; - const uint32 texFlags = tex->GetFlags(); - const int texDataSize = tex->GetDataSize(); - const int texDeviceDataSize = tex->GetDeviceDataSize(); - - if (tex->GetDevTexture() && !(texFlags & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET))) - { - AllSize += texDataSize; - if (!Texs[i]->IsStreamed()) - { - NonStrSize += texDataSize; - nNoStr++; - } - } - - if (texFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) - { - if (texFlags & FT_USAGE_ATLAS) - { - ++nNumTexDynAtl; - SizeDynAtl += texDataSize; - } - else - { - ++nNumTexDynCom; - SizeDynCom += texDataSize; - } - } - else - if (0 == (texFlags & FT_TEX_NORMAL_MAP)) - { - if (!Texs[i]->IsUnloaded()) - { - ++nNumTex; - Size += texDataSize; - PartSize += texDeviceDataSize; - } - } - else - { - if (!Texs[i]->IsUnloaded()) - { - ++nNumTexNM; - SizeNM += texDataSize; - PartSizeNM += texDeviceDataSize; - } - } - } - - sprintf_s(buf, "All texture objects: %d (Size: %.3fMb), NonStreamed: %d (Size: %.3fMb)", Texs.Num(), AllSize / (1024.0 * 1024.0), nNoStr, NonStrSize / (1024.0 * 1024.0)); - rd->TextToScreenColor(4, 13, 1, 1, 0, 1, buf); - sprintf_s(buf, "All Loaded Texture Maps: %d (All MIPS: %.3fMb, Loaded MIPS: %.3fMb)", nNumTex, Size / (1024.0f * 1024.0f), PartSize / (1024.0 * 1024.0)); - rd->TextToScreenColor(4, 16, 1, 1, 0, 1, buf); - sprintf_s(buf, "All Loaded Normal Maps: %d (All MIPS: %.3fMb, Loaded MIPS: %.3fMb)", nNumTexNM, SizeNM / (1024.0 * 1024.0), PartSizeNM / (1024.0 * 1024.0)); - rd->TextToScreenColor(4, 19, 1, 1, 0, 1, buf); - sprintf_s(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)); - rd->TextToScreenColor(4, 22, 1, 1, 0, 1, buf); - - Texs.Free(); - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CTexture* tp = (CTexture*)itor->second; - if (tp && !tp->IsNoTexture() && tp->m_nAccessFrameID == rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID) - { - Texs.AddElem(tp); - } - } - - if (Texs.Num()) - { - qsort(&Texs[0], Texs.Num(), sizeof(CTexture*), TexCallback); - } - - Size = 0; - SizeDynAtl = 0; - SizeDynCom = 0; - PartSize = 0; - NonStrSize = 0; - for (i = 0; i < Texs.Num(); i++) - { - Size += Texs[i]->GetDataSize(); - if (Texs[i]->GetFlags() & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET)) - { - if (Texs[i]->GetFlags() & FT_USAGE_ATLAS) - { - SizeDynAtl += Texs[i]->GetDataSize(); - } - else - { - SizeDynCom += Texs[i]->GetDataSize(); - } - } - else - { - PartSize += Texs[i]->GetDeviceDataSize(); - } - if (!Texs[i]->IsStreamed()) - { - NonStrSize += Texs[i]->GetDataSize(); - } - } - sprintf_s(buf, "Current tex. objects: %d (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)); - rd->TextToScreenColor(4, 27, 1, 0, 0, 1, buf); - } -#endif - } -} - -void CTexture::RT_LoadingUpdate() -{ - CTexture::s_bStreamingFromHDD = gEnv->pSystem->GetStreamEngine()->IsStreamDataOnHDD(); - CTexture::s_nStatsStreamPoolInUseMem = CTexture::s_pPoolMgr->GetInUseSize(); - - ITextureStreamer::EApplyScheduleFlags asf = CTexture::s_bPrecachePhase - ? ITextureStreamer::eASF_InOut // Exclude the prep update, as it will be done by the RLT (and can be expensive) - : ITextureStreamer::eASF_Full; - - s_pTextureStreamer->ApplySchedule(asf); -} - -void CTexture::RLT_LoadingUpdate() -{ - AZ_TRACE_METHOD(); - s_pTextureStreamer->BeginUpdateSchedule(); -} - -Ang3 sDeltAngles(Ang3& Ang0, Ang3& Ang1) -{ - Ang3 out; - for (int i = 0; i < 3; i++) - { - float a0 = Ang0[i]; - a0 = (float)((360.0 / 65536) * ((int)(a0 * (65536 / 360.0)) & 65535)); // angmod - float a1 = Ang1[i]; - a1 = (float)((360.0 / 65536) * ((int)(a0 * (65536 / 360.0)) & 65535)); - out[i] = a0 - a1; - } - return out; -} - -SEnvTexture* CTexture::FindSuitableEnvTex(Vec3& Pos, Ang3& Angs, bool bMustExist, [[maybe_unused]] int RendFlags, [[maybe_unused]] bool bUseExistingREs, [[maybe_unused]] CShader* pSH, [[maybe_unused]] CShaderResources* pRes, CRenderObject* pObj, bool bReflect, IRenderElement* pRE, bool* bMustUpdate) -{ - float time0 = iTimer->GetAsyncCurTime(); - - int i; - float distO = 999999; - float adist = 999999; - int firstForUse = -1; - int firstFree = -1; - Vec3 objPos; - if (bMustUpdate) - { - *bMustUpdate = false; - } - if (!pObj) - { - bReflect = false; - } - else - { - if (bReflect) - { - Plane pl; - pRE->mfGetPlane(pl); - objPos = pl.MirrorPosition(Vec3(0, 0, 0)); - } - else - if (pRE) - { - pRE->mfCenter(objPos, pObj); - } - else - { - objPos = pObj->GetTranslation(); - } - } - float dist = 999999; - for (i = 0; i < MAX_ENVTEXTURES; i++) - { - SEnvTexture* cur = &CTexture::s_EnvTexts[i]; - if (cur->m_bReflected != bReflect) - { - continue; - } - float s = (cur->m_CamPos - Pos).GetLengthSquared(); - Ang3 angDelta = sDeltAngles(Angs, cur->m_Angle); - float a = angDelta.x * angDelta.x + angDelta.y * angDelta.y + angDelta.z * angDelta.z; - float so = 0; - if (bReflect) - { - so = (cur->m_ObjPos - objPos).GetLengthSquared(); - } - if (s <= dist && a <= adist && so <= distO) - { - dist = s; - adist = a; - distO = so; - firstForUse = i; - if (!so && !s && !a) - { - break; - } - } - if (cur->m_pTex && !cur->m_pTex->m_pTexture && firstFree < 0) - { - firstFree = i; - } - } - if (bMustExist && firstForUse >= 0) - { - return &CTexture::s_EnvTexts[firstForUse]; - } - if (bReflect) - { - dist = distO; - } - - float curTime = iTimer->GetCurrTime(); - int nUpdate = -2; - float fTimeInterval = dist * CRenderer::CV_r_envtexupdateinterval + CRenderer::CV_r_envtexupdateinterval * 0.5f; - float fDelta = curTime - CTexture::s_EnvTexts[firstForUse].m_TimeLastUpdated; - if (bMustExist) - { - nUpdate = -2; - } - else - if (dist > MAX_ENVTEXSCANDIST) - { - if (firstFree >= 0) - { - nUpdate = firstFree; - } - else - { - nUpdate = -1; - } - } - else - if (fDelta > fTimeInterval) - { - nUpdate = firstForUse; - } - if (nUpdate == -2) - { - // No need to update (Up to date) - return &CTexture::s_EnvTexts[firstForUse]; - } - if (!CTexture::s_EnvTexts[nUpdate].m_pTex) - { - return NULL; - } - if (nUpdate >= 0) - { - if (!CTexture::s_EnvTexts[nUpdate].m_pTex->m_pTexture || gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_fEnvTextUpdateTime < 0.1f) - { - int n = nUpdate; - CTexture::s_EnvTexts[n].m_TimeLastUpdated = curTime; - CTexture::s_EnvTexts[n].m_CamPos = Pos; - CTexture::s_EnvTexts[n].m_Angle = Angs; - CTexture::s_EnvTexts[n].m_ObjPos = objPos; - CTexture::s_EnvTexts[n].m_bReflected = bReflect; - if (bMustUpdate) - { - *bMustUpdate = true; - } - } - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_fEnvTextUpdateTime += iTimer->GetAsyncCurTime() - time0; - return &CTexture::s_EnvTexts[nUpdate]; - } - - dist = 0; - firstForUse = -1; - for (i = 0; i < MAX_ENVTEXTURES; i++) - { - SEnvTexture* cur = &CTexture::s_EnvTexts[i]; - if (dist < curTime - cur->m_TimeLastUpdated && !cur->m_bInprogress) - { - dist = curTime - cur->m_TimeLastUpdated; - firstForUse = i; - } - } - if (firstForUse < 0) - { - return NULL; - } - int n = firstForUse; - CTexture::s_EnvTexts[n].m_TimeLastUpdated = curTime; - CTexture::s_EnvTexts[n].m_CamPos = Pos; - CTexture::s_EnvTexts[n].m_ObjPos = objPos; - CTexture::s_EnvTexts[n].m_Angle = Angs; - CTexture::s_EnvTexts[n].m_bReflected = bReflect; - if (bMustUpdate) - { - *bMustUpdate = true; - } - - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_fEnvTextUpdateTime += iTimer->GetAsyncCurTime() - time0; - return &CTexture::s_EnvTexts[n]; -} - - -//=========================================================================== - -void CTexture::ShutDown() -{ - uint32 i; - - if (gRenDev->GetRenderType() == eRT_Null) // workaround to fix crash when quitting the dedicated server - because the textures are shared - { - return; // should be fixed soon - } - RT_FlushAllStreamingTasks(true); - - ReleaseSystemTextures(); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_releaseallresourcesonexit) - { - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - int n = 0; - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); ) - { - CTexture* pTX = (CTexture*)itor->second; - itor++; - if (!pTX) - { - continue; - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_printmemoryleaks) - { - iLog->Log("Warning: CTexture::ShutDown: Texture %s was not deleted (%d)", pTX->GetName(), pTX->GetRefCounter()); - } - SAFE_RELEASE_FORCE(pTX); - n++; - } - } - } - - if (s_ShaderTemplatesInitialized) - { - for (i = 0; i < EFTT_MAX; i++) - { - (*s_ShaderTemplates)[i].~CTexture(); - } - } - s_ShaderTemplates->Free(); - - SAFE_DELETE(s_pTexNULL); - - s_pPoolMgr->Flush(); -} - -bool CTexture::ReloadFile_Request(const char* szFileName) -{ - s_xTexReloadLock.Lock(); - s_vTexReloadRequests.insert(szFileName); - s_xTexReloadLock.Unlock(); - - return true; -} - -bool CTexture::ReloadFile(const char* szFileName) -{ - char realNameBuffer[256]; - fpConvertDOSToUnixName(realNameBuffer, szFileName); - - - bool bStatus = false; - - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - AUTO_LOCK(CBaseResource::s_cResLock); - AZStd::string normalizedFile; - AZStd::string fileExtension; - AzFramework::StringFunc::Path::GetExtension(szFileName, fileExtension); - if (szFileName[0] == '$' || fileExtension.empty()) - { - //If the name starts with $ or it does not have any extension then it is one of the special texture that the engine requires and we would not be modifying the name - normalizedFile = szFileName; - } - else - { - char buffer[AZ_MAX_PATH_LEN]; - IResourceCompilerHelper::GetOutputFilename(szFileName, buffer, sizeof(buffer)); // change texture filename extensions to dds - normalizedFile = buffer; - AZStd::to_lower(normalizedFile.begin(), normalizedFile.end()); - PathUtil::ToUnixPath(normalizedFile.c_str()); - } - - CCryNameTSCRC Name = GenName(normalizedFile.c_str()); - - ResourcesMapItor itor = pRL->m_RMap.find(Name); - if (itor != pRL->m_RMap.end()) - { - CTexture* tp = (CTexture*)itor->second; - - if (tp->Reload()) - { - bStatus = true; - } - } - - // Since we do not have the information whether the modified file was also reloaded with the FT_ALPHA flag we will try to reload that as well - Name = GenName(normalizedFile.c_str(), FT_ALPHA); - - itor = pRL->m_RMap.find(Name); - if (itor != pRL->m_RMap.end()) - { - CTexture* tp = (CTexture*)itor->second; - - if (tp->Reload()) - { - bStatus = true; - } - } - } - - return bStatus; -} - -void CTexture::ReloadTextures() -{ - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - ResourcesMapItor itor; - int nID = 0; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++, nID++) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp) - { - continue; - } - if (!(tp->m_nFlags & FT_FROMIMAGE)) - { - continue; - } - tp->Reload(); - } - } -} - -bool CTexture::SetNoTexture( const CTexture* pDefaultTexture /* = "NoTexture" entry */) -{ - if (pDefaultTexture) - { - m_pDevTexture = pDefaultTexture->m_pDevTexture; - m_pDeviceShaderResource = pDefaultTexture->m_pDeviceShaderResource; - m_eTFSrc = pDefaultTexture->GetSrcFormat(); - m_eTFDst = pDefaultTexture->GetDstFormat(); - m_nMips = pDefaultTexture->GetNumMips(); - m_nWidth = pDefaultTexture->GetWidth(); - m_nHeight = pDefaultTexture->GetHeight(); - m_nDepth = 1; - m_nDefState = pDefaultTexture->m_nDefState; - m_fAvgBrightness = 1.0f; - m_cMinColor = 0.0f; - m_cMaxColor = 1.0f; - m_cClearColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - - m_bNoTexture = true; - if (m_pFileTexMips) - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - } - m_bStreamed = false; - m_bPostponed = false; - m_nFlags |= FT_FAILED; - m_nActualSize = 0; - m_nPersistentSize = 0; - return true; - } - return false; -} - -//=========================================================================== - -void CTexture::ReleaseSystemTextures() -{ - if (s_pStatsTexWantedLists) - { - for (int i = 0; i < 2; ++i) - { - s_pStatsTexWantedLists[i].clear(); - } - } - - SAFE_RELEASE_FORCE(s_ptexRT_2D); - SAFE_RELEASE_FORCE(s_ptexCloudsLM); - - SAFE_RELEASE_FORCE(s_ptexVolumetricFog); - SAFE_RELEASE_FORCE(s_ptexVolumetricFogDensityColor); - SAFE_RELEASE_FORCE(s_ptexVolumetricFogDensity); - SAFE_RELEASE_FORCE(s_ptexVolumetricClipVolumeStencil); - - uint32 i; - for (i = 0; i < 8; i++) - { - SAFE_RELEASE_FORCE(s_ptexShadowID[i]); - } - - SAFE_RELEASE_FORCE(s_ptexFromObj); - SAFE_RELEASE_FORCE(s_ptexSvoTree); - SAFE_RELEASE_FORCE(s_ptexSvoTris); - SAFE_RELEASE_FORCE(s_ptexSvoGlobalCM); - SAFE_RELEASE_FORCE(s_ptexSvoRgbs); - SAFE_RELEASE_FORCE(s_ptexSvoNorm); - SAFE_RELEASE_FORCE(s_ptexSvoOpac); - SAFE_RELEASE_FORCE(s_ptexFromObjCM); - - SAFE_RELEASE_FORCE(s_ptexVolObj_Density); - SAFE_RELEASE_FORCE(s_ptexVolObj_Shadow); - - SAFE_RELEASE_FORCE(s_ptexColorChart); - - for (i = 0; i < MAX_ENVCUBEMAPS; i++) - { - s_EnvCMaps[i].Release(); - } - for (i = 0; i < MAX_ENVTEXTURES; i++) - { - s_EnvTexts[i].Release(); - } - - SAFE_RELEASE_FORCE(s_ptexMipColors_Diffuse); - SAFE_RELEASE_FORCE(s_ptexMipColors_Bump); - SAFE_RELEASE_FORCE(s_ptexSkyDomeMie); - SAFE_RELEASE_FORCE(s_ptexSkyDomeRayleigh); - SAFE_RELEASE_FORCE(s_ptexSkyDomeMoon); - SAFE_RELEASE_FORCE(s_ptexRT_ShadowPool); - SAFE_RELEASE_FORCE(s_ptexRT_ShadowStub); - - SAFE_RELEASE_FORCE(s_ptexSceneNormalsMapMS); - SAFE_RELEASE_FORCE(s_ptexSceneDiffuseAccMapMS); - SAFE_RELEASE_FORCE(s_ptexSceneSpecularAccMapMS); - - SAFE_RELEASE_FORCE(s_defaultEnvironmentProbeDummy); - - s_CustomRT_2D->Free(); - - s_pPoolMgr->Flush(); - - // release targets pools - SDynTexture::ShutDown(); - SDynTexture2::ShutDown(); - - ReleaseMiscTargets(); - - m_bLoadedSystem = false; -} - -void CTexture::LoadDefaultSystemTextures() -{ - LOADING_TIME_PROFILE_SECTION; -#if !defined(NULL_RENDERER) - char str[256]; - int i; - - if (!m_bLoadedSystem) - { - - - m_bLoadedSystem = true; - - // Default Template textures - int nRTFlags = FT_DONT_RELEASE | FT_DONT_STREAM | FT_STATE_CLAMP | FT_USAGE_RENDERTARGET; - s_ptexMipColors_Diffuse = CTexture::CreateTextureObject("$MipColors_Diffuse", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_MIPCOLORS_DIFFUSE); - s_ptexMipColors_Bump = CTexture::CreateTextureObject("$MipColors_Bump", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_MIPCOLORS_BUMP); - - s_ptexRT_2D = CTexture::CreateTextureObject("$RT_2D", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_RT_2D); - - s_ptexRainOcclusion = CTexture::CreateTextureObject("$RainOcclusion", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - s_ptexRainSSOcclusion[0] = CTexture::CreateTextureObject("$RainSSOcclusion0", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - s_ptexRainSSOcclusion[1] = CTexture::CreateTextureObject("$RainSSOcclusion1", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - - s_ptexFromObj = CTexture::CreateTextureObject("FromObj", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_FROMOBJ); - s_ptexSvoTree = CTexture::CreateTextureObject("SvoTree", 0, 0, 1, eTT_3D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVOTREE); - s_ptexSvoTris = CTexture::CreateTextureObject("SvoTris", 0, 0, 1, eTT_3D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVOTRIS); - s_ptexSvoGlobalCM = CTexture::CreateTextureObject("SvoGlobalCM", 0, 0, 1, eTT_Cube, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVOGLCM); - s_ptexSvoRgbs = CTexture::CreateTextureObject("SvoRgbs", 0, 0, 1, eTT_3D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVORGBS); - s_ptexSvoNorm = CTexture::CreateTextureObject("SvoNorm", 0, 0, 1, eTT_3D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVONORM); - s_ptexSvoOpac = CTexture::CreateTextureObject("SvoOpac", 0, 0, 1, eTT_3D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SVOOPAC); - s_ptexFromObjCM = CTexture::CreateTextureObject("$FromObjCM", 0, 0, 1, eTT_Cube, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_FROMOBJ_CM); - - s_ptexZTargetDownSample[0] = CTexture::CreateTextureObject("$ZTargetDownSample0", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - s_ptexZTargetDownSample[1] = CTexture::CreateTextureObject("$ZTargetDownSample1", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - s_ptexZTargetDownSample[2] = CTexture::CreateTextureObject("$ZTargetDownSample2", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - s_ptexZTargetDownSample[3] = CTexture::CreateTextureObject("$ZTargetDownSample3", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown); - - s_ptexSceneNormalsMapMS = CTexture::CreateTextureObject("$SceneNormalsMapMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_NORMALMAP_MS); - s_ptexSceneDiffuseAccMapMS = CTexture::CreateTextureObject("$SceneDiffuseAccMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_DIFFUSE_ACC_MS); - s_ptexSceneSpecularAccMapMS = CTexture::CreateTextureObject("$SceneSpecularAccMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_SPECULAR_ACC_MS); - - s_ptexSceneNormalsMapMS = CTexture::CreateTextureObject("$SceneNormalsMapMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_NORMALMAP_MS); - s_ptexSceneDiffuseAccMapMS = CTexture::CreateTextureObject("$SceneDiffuseAccMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_DIFFUSE_ACC_MS); - s_ptexSceneSpecularAccMapMS = CTexture::CreateTextureObject("$SceneSpecularAccMS", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_SPECULAR_ACC_MS); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - s_ptexRT_ShadowPool = CTexture::CreateTextureObject("$RT_ShadowPool", 0, 0, 1, eTT_2D, FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_DEPTHSTENCIL, eTF_Unknown); - s_ptexRT_ShadowStub = CTexture::CreateTextureObject("$RT_ShadowStub", 0, 0, 1, eTT_2D, FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_DEPTHSTENCIL, eTF_Unknown); - - s_ptexDepthBufferQuarter = CTexture::CreateTextureObject("$DepthBufferQuarter", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_DEPTHSTENCIL, eTF_Unknown); - - if (!s_ptexModelHudBuffer) - { - s_ptexModelHudBuffer = CTexture::CreateTextureObject("$ModelHud", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_MODELHUD); - } - - if (!s_ptexBackBuffer) - { - s_ptexSceneTarget = CTexture::CreateTextureObject("$SceneTarget", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SCENE_TARGET); - s_ptexCurrSceneTarget = s_ptexSceneTarget; - - s_ptexSceneTargetR11G11B10F[0] = CTexture::CreateTextureObject("$SceneTargetR11G11B10F_0", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexSceneTargetR11G11B10F[1] = CTexture::CreateTextureObject("$SceneTargetR11G11B10F_1", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexSceneTargetScaledR11G11B10F[0] = CTexture::CreateTextureObject("$SceneTargetScaled0R11G11B10F", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexSceneTargetScaledR11G11B10F[1] = CTexture::CreateTextureObject("$SceneTargetScaled1R11G11B10F", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexSceneTargetScaledR11G11B10F[2] = CTexture::CreateTextureObject("$SceneTargetScaled2R11G11B10F", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexSceneTargetScaledR11G11B10F[3] = CTexture::CreateTextureObject("$SceneTargetScaled3R11G11B10F", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - - s_ptexVelocity = CTexture::CreateTextureObject("$Velocity", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexVelocityTiles[0] = CTexture::CreateTextureObject("$VelocityTilesTmp0", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexVelocityTiles[1] = CTexture::CreateTextureObject("$VelocityTilesTmp1", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexVelocityTiles[2] = CTexture::CreateTextureObject("$VelocityTiles", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexVelocityObjects[0] = CTexture::CreateTextureObject("$VelocityObjects", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - if (gRenDev->m_bDualStereoSupport) - { - s_ptexVelocityObjects[1] = CTexture::CreateTextureObject("$VelocityObjects_R", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - } - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - if (gcpRendD3D && gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - s_ptexGmemStenLinDepth = CTexture::CreateTextureObject("$GmemStenLinDepth", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - } -#endif - - s_ptexBackBuffer = CTexture::CreateTextureObject("$BackBuffer", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_BACKBUFFERMAP); - - s_ptexPrevFrameScaled = CTexture::CreateTextureObject("$PrevFrameScale", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - s_ptexWaterRipplesDDN = CTexture::CreateTextureObject("$WaterRipplesDDN_0", 256, 256, 1, eTT_2D, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_FORCE_MIPS, eTF_Unknown, TO_WATERRIPPLESMAP); - - s_ptexBackBufferScaled[0] = CTexture::CreateTextureObject("$BackBufferScaled_d2", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_BACKBUFFERSCALED_D2); - s_ptexBackBufferScaled[1] = CTexture::CreateTextureObject("$BackBufferScaled_d4", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_BACKBUFFERSCALED_D4); - s_ptexBackBufferScaled[2] = CTexture::CreateTextureObject("$BackBufferScaled_d8", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_BACKBUFFERSCALED_D8); - - s_ptexBackBufferScaledTemp[0] = CTexture::CreateTextureObject("$BackBufferScaledTemp_d2", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - s_ptexBackBufferScaledTemp[1] = CTexture::CreateTextureObject("$BackBufferScaledTemp_d4", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, -1); - - s_ptexSceneNormalsMap = CTexture::CreateTextureObject("$SceneNormalsMap", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8, TO_SCENE_NORMALMAP); - s_ptexSceneNormalsBent = CTexture::CreateTextureObject("$SceneNormalsBent", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8); - s_ptexSceneDiffuse = CTexture::CreateTextureObject("$SceneDiffuse", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8); - ETEX_Format rtTextureFormat = eTF_R8G8B8A8; - - // Slimming GBuffer requires only one channel for specular due to packing of RGB values into YPbPr and - // specular components into less channels, thus saving bandwidth by not including G,B,A channels (75% saving) - if(CRenderer::CV_r_SlimGBuffer == 1) - { - rtTextureFormat = eTF_R8; - } - s_ptexSceneSpecular = CTexture::CreateTextureObject("$SceneSpecular", 0, 0, 1, eTT_2D, nRTFlags, rtTextureFormat); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - -#if defined(AZ_PLATFORM_IOS) - int nRTSceneDiffuseFlags = nRTFlags; - static ICVar* pVar = gEnv->pConsole->GetCVar("e_ShadowsClearShowMaskAtLoad"); - if (pVar && !pVar->GetIVal()) - { - nRTSceneDiffuseFlags |= FT_USAGE_MEMORYLESS; - } - s_ptexSceneDiffuseAccMap = CTexture::CreateTextureObject("$SceneDiffuseAcc", 0, 0, 1, eTT_2D, nRTSceneDiffuseFlags, eTF_R8G8B8A8, TO_SCENE_DIFFUSE_ACC); -#else - s_ptexSceneDiffuseAccMap = CTexture::CreateTextureObject("$SceneDiffuseAcc", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8, TO_SCENE_DIFFUSE_ACC); -#endif - s_ptexSceneSpecularAccMap = CTexture::CreateTextureObject("$SceneSpecularAcc", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8, TO_SCENE_SPECULAR_ACC); - s_ptexAmbientLookup = CTexture::CreateTextureObject("$AmbientLookup", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8); - s_ptexShadowMask = CTexture::CreateTextureObject("$ShadowMask", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8, TO_SHADOWMASK); - - s_ptexFlaresGather = CTexture::CreateTextureObject("$FlaresGather", 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8); - for (i = 0; i < MAX_OCCLUSION_READBACK_TEXTURES; i++) - { - azsprintf(str, "$FlaresOcclusion_%d", i); - s_ptexFlaresOcclusionRing[i] = CTexture::CreateTextureObject(str, 0, 0, 1, eTT_2D, nRTFlags, eTF_R8G8B8A8); - } - - // fixme: get texture resolution from CREWaterOcean - uint32 waterOceanMapFlags = FT_DONT_RELEASE | FT_NOMIPS | FT_USAGE_DYNAMIC | FT_DONT_STREAM; - uint32 waterVolumeTempFlags = FT_NOMIPS | FT_USAGE_DYNAMIC | FT_DONT_STREAM; -#if CRY_USE_METAL - //We are now using the GPU to copy data into this texture. As a result we need to tag this texture as MtlTextureUsageRenderTarget so that on Metal can set the appropriate Usage flag. - waterOceanMapFlags |= FT_USAGE_RENDERTARGET; - waterVolumeTempFlags |= FT_USAGE_RENDERTARGET; -#endif - s_ptexWaterOcean = CTexture::CreateTextureObject("$WaterOceanMap", 64, 64, 1, eTT_2D, waterOceanMapFlags, eTF_Unknown, TO_WATEROCEANMAP); - s_ptexWaterVolumeTemp = CTexture::CreateTextureObject("$WaterVolumeTemp", 64, 64, 1, eTT_2D, waterVolumeTempFlags, eTF_Unknown); - - s_ptexWaterVolumeDDN = CTexture::CreateTextureObject("$WaterVolumeDDN", 64, 64, 1, eTT_2D, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_FORCE_MIPS, eTF_Unknown, TO_WATERVOLUMEMAP); - s_ptexWaterVolumeRefl[0] = CTexture::CreateTextureObject("$WaterVolumeRefl", 64, 64, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_FORCE_MIPS, eTF_Unknown, TO_WATERVOLUMEREFLMAP); - s_ptexWaterVolumeRefl[1] = CTexture::CreateTextureObject("$WaterVolumeReflPrev", 64, 64, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_FORCE_MIPS, eTF_Unknown, TO_WATERVOLUMEREFLMAPPREV); - s_ptexWaterCaustics[0] = CTexture::CreateTextureObject("$WaterVolumeCaustics", 512, 512, 1, eTT_2D, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_WATERVOLUMECAUSTICSMAP); - s_ptexWaterCaustics[1] = CTexture::CreateTextureObject("$WaterVolumeCausticsTemp", 512, 512, 1, eTT_2D, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_WATERVOLUMECAUSTICSMAPTEMP); - - s_ptexRainDropsRT[0] = CTexture::CreateTextureObject("$RainDropsAccumRT_0", 512, 512, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - s_ptexRainDropsRT[1] = CTexture::CreateTextureObject("$RainDropsAccumRT_1", 512, 512, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - - if (!s_ptexZTarget) - { - //for d3d10 we cannot free it during level transition, therefore allocate once and keep it -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - // Custom Z-Target for GMEM render path - if (gcpRendD3D && gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - s_ptexZTarget = CTexture::s_ptexGmemStenLinDepth; - } - else -#endif - { - s_ptexZTarget = CTexture::CreateTextureObject("$ZTarget", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - } - } - - s_ptexFurZTarget = CTexture::CreateTextureObject("$FurZTarget", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown); - - s_ptexZTargetScaled = CTexture::CreateTextureObject("$ZTargetScaled", 0, 0, 1, eTT_2D, - FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_DOWNSCALED_ZTARGET_FOR_AO); - - s_ptexZTargetScaled2 = CTexture::CreateTextureObject("$ZTargetScaled2", 0, 0, 1, eTT_2D, - FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_QUARTER_ZTARGET_FOR_AO); - } - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - // GMEM render path uses CTexture::s_ptexSceneSpecularAccMap as the HDR Target - // It gets set in CDeferredShading::CreateDeferredMaps() - if (gcpRendD3D && !gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - s_ptexHDRTarget = CTexture::CreateTextureObject("$HDRTarget", 0, 0, 1, eTT_2D, nRTFlags, eTF_Unknown); - } -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - - // Create dummy texture object for terrain and clouds lightmap - s_ptexCloudsLM = CTexture::CreateTextureObject("$CloudsLM", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_CLOUDS_LM); - - for (i = 0; i < 8; i++) - { - azsprintf(str, "$FromRE_%d", i); - if (!s_ptexFromRE[i]) - { - s_ptexFromRE[i] = CTexture::CreateTextureObject(str, 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_FROMRE0 + i); - } - } - - for (i = 0; i < 8; i++) - { - azsprintf(str, "$ShadowID_%d", i); - s_ptexShadowID[i] = CTexture::CreateTextureObject(str, 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SHADOWID0 + i); - } - - for (i = 0; i < 2; i++) - { - azsprintf(str, "$FromRE%d_FromContainer", i); - if (!s_ptexFromRE_FromContainer[i]) - { - s_ptexFromRE_FromContainer[i] = CTexture::CreateTextureObject(str, 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_FROMRE0_FROM_CONTAINER + i); - } - } - - s_ptexVolObj_Density = CTexture::CreateTextureObject("$VolObj_Density", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_VOLOBJ_DENSITY); - s_ptexVolObj_Shadow = CTexture::CreateTextureObject("$VolObj_Shadow", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_VOLOBJ_SHADOW); - - s_ptexColorChart = CTexture::CreateTextureObject("$ColorChart", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_COLORCHART); - - s_ptexSkyDomeMie = CTexture::CreateTextureObject("$SkyDomeMie", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SKYDOME_MIE); - s_ptexSkyDomeRayleigh = CTexture::CreateTextureObject("$SkyDomeRayleigh", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SKYDOME_RAYLEIGH); - s_ptexSkyDomeMoon = CTexture::CreateTextureObject("$SkyDomeMoon", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown, TO_SKYDOME_MOON); - - for (i = 0; i < EFTT_MAX; i++) - { - ::new(&((*s_ShaderTemplates)[i]))CTexture(FT_DONT_RELEASE); - (*s_ShaderTemplates)[i].SetCustomID(EFTT_DIFFUSE + i); - (*s_ShaderTemplates)[i].SetFlags(FT_DONT_RELEASE); - } - s_ShaderTemplatesInitialized = true; - - s_pTexNULL = new CTexture(FT_DONT_RELEASE); - - s_ptexVolumetricFog = CTexture::CreateTextureObject("$VolumetricInscattering", 0, 0, 0, eTT_3D, FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_UNORDERED_ACCESS, eTF_Unknown); - s_ptexVolumetricFogDensityColor = CTexture::CreateTextureObject("$DensityColorVolume", 0, 0, 0, eTT_3D, FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_UNORDERED_ACCESS, eTF_Unknown); - s_ptexVolumetricFogDensity = CTexture::CreateTextureObject("$DensityVolume", 0, 0, 0, eTT_3D, FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_UNORDERED_ACCESS, eTF_Unknown); - s_ptexVolumetricClipVolumeStencil = CTexture::CreateTextureObject("$ClipVolumeStencilVolume", 0, 0, 0, eTT_2D, FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_DEPTHSTENCIL | FT_USAGE_RENDERTARGET, eTF_Unknown); - - // Create dummy texture object the "default environment probe". This is only used for forward rendered passes that do not currently support tiled lighting. - // This texture object is solely used for the association between the string "$DefaultEnvironmentProbe" and the enum TO_DEFAULT_ENVIRONMENT_PROBE - if (!s_defaultEnvironmentProbeDummy) - { - s_defaultEnvironmentProbeDummy = CTexture::CreateTextureObject("$DefaultEnvironmentProbe", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_Unknown, TO_DEFAULT_ENVIRONMENT_PROBE); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(Texture_cpp) -#endif - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -const char* CTexture::GetFormatName() const -{ - return NameForTextureFormat(GetDstFormat()); -} - -////////////////////////////////////////////////////////////////////////// -const char* CTexture::GetTypeName() const -{ - return NameForTextureType(GetTextureType()); -} - -////////////////////////////////////////////////////////////////////////// -void CRenderer::EF_AddRTStat(CTexture* pTex, int nFlags, int nW, int nH) -{ - SRTargetStat TS; - int nSize; - ETEX_Format eTF; - if (!pTex) - { - eTF = eTF_R8G8B8A8; - if (nW < 0) - { - nW = m_width; - } - if (nH < 0) - { - nH = m_height; - } - nSize = CTexture::TextureDataSize(nW, nH, 1, 1, 1, eTF); - TS.m_Name = "Back buffer"; - } - else - { - eTF = pTex->GetDstFormat(); - if (nW < 0) - { - nW = pTex->GetWidth(); - } - if (nH < 0) - { - nH = pTex->GetHeight(); - } - nSize = CTexture::TextureDataSize(nW, nH, 1, pTex->GetNumMips(), 1, eTF); - const char* szName = pTex->GetName(); - if (szName && szName[0] == '$') - { - TS.m_Name = string("@") + string(&szName[1]); - } - else - { - TS.m_Name = szName; - } - } - TS.m_eTF = eTF; - - if (nFlags > 0) - { - if (nFlags == 1) - { - TS.m_Name += " (Target)"; - } - else - if (nFlags == 2) - { - TS.m_Name += " (Depth)"; - nSize = nW * nH * 3; - } - else - if (nFlags == 4) - { - TS.m_Name += " (Stencil)"; - nSize = nW * nH; - } - else - if (nFlags == 3) - { - TS.m_Name += " (Target + Depth)"; - nSize += nW * nH * 3; - } - else - if (nFlags == 6) - { - TS.m_Name += " (Depth + Stencil)"; - nSize = nW * nH * 4; - } - else - if (nFlags == 5) - { - TS.m_Name += " (Target + Stencil)"; - nSize += nW * nH; - } - else - if (nFlags == 7) - { - TS.m_Name += " (Target + Depth + Stencil)"; - nSize += nW * nH * 4; - } - else - { - assert(0); - } - } - TS.m_nSize = nSize; - TS.m_nWidth = nW; - TS.m_nHeight = nH; - - m_RP.m_RTStats.push_back(TS); -} - -void CRenderer::EF_PrintRTStats(const char* szName) -{ - const int nYstep = 14; - int nY = 30; // initial Y pos - int nX = 20; // initial X pos - ColorF col = Col_Green; - Draw2dLabel((float)nX, (float)nY, 1.6f, &col.r, false, szName); - nX += 10; - nY += 25; - - col = Col_White; - int nYstart = nY; - int nSize = 0; - for (int i = 0; i < m_RP.m_RTStats.size(); i++) - { - SRTargetStat* pRT = &m_RP.m_RTStats[i]; - - 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); - nY += nYstep; - if (nY >= m_height - 25) - { - nY = nYstart; - nX += 500; - } - nSize += pRT->m_nSize; - } - col = Col_Yellow; - 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); -} - -bool CTexture::IsMSAAChanged() -{ -#if defined(NULL_RENDERER) - return false; -#else - const RenderTargetData* pRtdt = m_pRenderTargetData; - return pRtdt && (pRtdt->m_nMSAASamples != gRenDev->m_RP.m_MSAAData.Type || pRtdt->m_nMSAAQuality != gRenDev->m_RP.m_MSAAData.Quality); -#endif -} - -STexPool::~STexPool() -{ - STexPoolItemHdr* pITH = m_ItemsList.m_Next; - - while (pITH != &m_ItemsList) - { - STexPoolItemHdr* pNext = pITH->m_Next; - STexPoolItem* pIT = static_cast(pITH); - 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); - - if (pIT->m_pTex) - { - pIT->m_pTex->ReleaseDeviceTexture(true); // Try to recover in release - } - - *const_cast(&pIT->m_pOwner) = NULL; - pITH = pNext; - } -} - -const ETEX_Type CTexture::GetTextureType() const -{ - return m_eTT; -} - -void CTexture::SetTextureType(ETEX_Type type) -{ - // Only set the type if we have not loaded the file and created the device - // texture - if (!m_pDevTexture) - { - m_eTT = type; - } -} - -const int CTexture::GetTextureID() const -{ - return GetID(); -} - -#ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT - -const ColorB* CTexture::GetLowResSystemCopy(uint16& nWidth, uint16& nHeight, int** ppLowResSystemCopyAtlasId) -{ - const LowResSystemCopyType::iterator& it = s_LowResSystemCopy.find(this); - if (it != CTexture::s_LowResSystemCopy.end()) - { - nWidth = (*it).second.m_nLowResCopyWidth; - nHeight = (*it).second.m_nLowResCopyHeight; - *ppLowResSystemCopyAtlasId = &(*it).second.m_nLowResSystemCopyAtlasId; - return (*it).second.m_lowResSystemCopy.GetElements(); - } - - return NULL; -} - -void CTexture::PrepareLowResSystemCopy(const byte* pTexData, bool bTexDataHasAllMips) -{ - if (m_eTT != eTT_2D || (m_nMips <= 1 && (m_nWidth > 16 || m_nHeight > 16))) - { - return; - } - - // this function handles only compressed textures for now - if (m_eTFDst != eTF_BC3 && m_eTFDst != eTF_BC1 && m_eTFDst != eTF_BC2) - { - return; - } - - // make sure we skip non diffuse textures - if (strstr(GetName(), "_ddn") - || strstr(GetName(), "_ddna") - || strstr(GetName(), "_mask") - || strstr(GetName(), "_spec.") - || strstr(GetName(), "_gloss") - || strstr(GetName(), "_displ") - || strstr(GetName(), "characters") - || strstr(GetName(), "$") - ) - { - return; - } - - if (pTexData) - { - SLowResSystemCopy& rSysCopy = s_LowResSystemCopy[this]; - - rSysCopy.m_nLowResCopyWidth = m_nWidth; - rSysCopy.m_nLowResCopyHeight = m_nHeight; - - int nSrcOffset = 0; - int nMipId = 0; - - while ((rSysCopy.m_nLowResCopyWidth > 16 || rSysCopy.m_nLowResCopyHeight > 16 || nMipId < 2) && (rSysCopy.m_nLowResCopyWidth >= 8 && rSysCopy.m_nLowResCopyHeight >= 8)) - { - nSrcOffset += TextureDataSize(rSysCopy.m_nLowResCopyWidth, rSysCopy.m_nLowResCopyHeight, 1, 1, 1, m_eTFDst); - rSysCopy.m_nLowResCopyWidth /= 2; - rSysCopy.m_nLowResCopyHeight /= 2; - nMipId++; - } - - int nSizeDxtMip = TextureDataSize(rSysCopy.m_nLowResCopyWidth, rSysCopy.m_nLowResCopyHeight, 1, 1, 1, m_eTFDst); - int nSizeRgbaMip = TextureDataSize(rSysCopy.m_nLowResCopyWidth, rSysCopy.m_nLowResCopyHeight, 1, 1, 1, eTF_R8G8B8A8); - - rSysCopy.m_lowResSystemCopy.CheckAllocated(nSizeRgbaMip / sizeof(ColorB)); - - gRenDev->DXTDecompress(pTexData + (bTexDataHasAllMips ? nSrcOffset : 0), nSizeDxtMip, - (byte*)rSysCopy.m_lowResSystemCopy.GetElements(), rSysCopy.m_nLowResCopyWidth, rSysCopy.m_nLowResCopyHeight, 1, m_eTFDst, false, 4); - } -} - -#endif // TEXTURE_GET_SYSTEM_COPY_SUPPORT - -void CTexture::InvalidateDeviceResource(uint32 dirtyFlags) -{ - //In the editor, multiple worker threads could destroy device resource sets - //which point to this texture. We need to lock to avoid a race-condition. - AZStd::lock_guard lockGuard(*m_invalidateCallbacksMutex); - - for (const auto& cb : m_invalidateCallbacks) - { - cb.second(dirtyFlags); - } -} - -void CTexture::AddInvalidateCallback(void* listener, InvalidateCallbackType callback) -{ - //In the editor, multiple worker threads could destroy device resource sets - //which point to this texture. We need to lock to avoid a race-condition. - AZStd::lock_guard lockGuard(*m_invalidateCallbacksMutex); - - m_invalidateCallbacks.insert(AZStd::pair(listener, callback)); -} - -void CTexture::RemoveInvalidateCallbacks(void* listener) -{ - //In the editor, multiple worker threads could destroy device resource sets - //which point to this texture. We need to lock to avoid a race-condition. - AZStd::lock_guard lockGuard(*m_invalidateCallbacksMutex); - - m_invalidateCallbacks.erase(listener); -} - -void CTexture::ApplyDepthTextureState(int unit, int nFilter, bool clamp) -{ - if (s_ptexZTarget != nullptr) - { - STexState depthTextState(nFilter, clamp); - s_ptexZTarget->Apply(unit, GetTexState(depthTextState)); - } -} - -CTexture* CTexture::GetZTargetTexture() -{ - return s_ptexZTarget; -} - -int CTexture::GetTextureState(const STexState& TS) -{ - return GetTexState(TS); -} - -void CTexture::ApplyForID(int id, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit, bool useWhiteDefault) -{ - CTexture* pTex = id > 0 ? CTexture::GetByID(id) : nullptr; - if (pTex) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - else if (useWhiteDefault) - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } -} - -CTexAnim::CTexAnim() -{ - m_nRefCount = 1; - m_Rand = 0; - m_NumAnimTexs = 0; - m_bLoop = false; - m_Time = 0.0f; -} - -CTexAnim::~CTexAnim() -{ - for (uint32 i = 0; i < m_TexPics.Num(); i++) - { - ITexture* pTex = (ITexture*)m_TexPics[i]; - SAFE_RELEASE(pTex); - } - m_TexPics.Free(); -} - -void CTexAnim::AddRef() -{ - CryInterlockedIncrement(&m_nRefCount); -} - -void CTexAnim::Release() -{ - long refCnt = CryInterlockedDecrement(&m_nRefCount); - if (refCnt > 0) - { - return; - } - delete this; -} - -int CTexAnim::Size() const -{ - int nSize = sizeof(CTexAnim); - nSize += m_TexPics.GetMemoryUsage(); - return nSize; -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/Texture.h b/Code/CryEngine/RenderDll/Common/Textures/Texture.h deleted file mode 100644 index 77764fa80a..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/Texture.h +++ /dev/null @@ -1,2512 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// change file hash again - -#pragma once - - -#include -#include "../ResFile.h" -#include "PowerOf2BlockPacker.h" -#include "STLPoolAllocator.h" - -#include "ITextureStreamer.h" - -#include "TextureArrayAlloc.h" -#include "Image/DDSImage.h" - -#include "ImageExtensionHelper.h" -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define TEXTURE_H_SECTION_1 1 -#define TEXTURE_H_SECTION_2 2 -#define TEXTURE_H_SECTION_3 3 -#define TEXTURE_H_SECTION_4 4 -#define TEXTURE_H_SECTION_5 5 -#define TEXTURE_H_SECTION_6 6 -#define TEXTURE_H_SECTION_7 7 -#endif - -// Only the editor needs to use a unique mutex per texture. -// In the editor, multiple worker threads could destroy device resource sets which point to the same texture -#if defined(AZ_PLATFORM_WINDOWS) - #define USE_UNIQUE_MUTEX_PER_TEXTURE -#endif - -class CTexture; -class CImageFile; -class CTextureStreamPoolMgr; -struct SDepthTexture; - -#define TEXPOOL_LOADSIZE 6 * 1024 * 1024 -#define MAX_MIP_LEVELS (100) -#define CTEXTURE_RENDER_TARGET_USE_COUNT_NUMBER_BITS 2 - -// Custom Textures IDs -enum -{ - TO_RT_2D = 1, - - TO_FOG, - TO_FROMOBJ, - TO_SVOTREE, - TO_SVOTRIS, - TO_SVOGLCM, - TO_SVORGBS, - TO_SVONORM, - TO_SVOOPAC, - TO_FROMOBJ_CM, - - TO_SHADOWID0, - TO_SHADOWID1, - TO_SHADOWID2, - TO_SHADOWID3, - TO_SHADOWID4, - TO_SHADOWID5, - TO_SHADOWID6, - TO_SHADOWID7, - - TO_FROMRE0, - TO_FROMRE1, - - TO_FROMRE0_FROM_CONTAINER, - TO_FROMRE1_FROM_CONTAINER, - - TO_SCREENMAP, - TO_SHADOWMASK, - TO_CLOUDS_LM, - TO_BACKBUFFERMAP, - TO_PREVBACKBUFFERMAP0, - TO_PREVBACKBUFFERMAP1, - TO_MIPCOLORS_DIFFUSE, - TO_MIPCOLORS_BUMP, - - TO_DOWNSCALED_ZTARGET_FOR_AO, - TO_QUARTER_ZTARGET_FOR_AO, - TO_WATEROCEANMAP, - TO_WATERVOLUMEMAP, - - TO_WATERVOLUMEREFLMAP, - TO_WATERVOLUMEREFLMAPPREV, - TO_WATERVOLUMECAUSTICSMAP, - TO_WATERVOLUMECAUSTICSMAPTEMP, - - TO_WATERRIPPLESMAP, - - TO_VOLOBJ_DENSITY, - TO_VOLOBJ_SHADOW, - - TO_COLORCHART, - - TO_ZTARGET_MS, - - TO_SCENE_NORMALMAP, - TO_SCENE_NORMALMAP_MS, - - TO_LPV_R, - TO_LPV_G, - TO_LPV_B, - TO_RSM_NORMAL, - TO_RSM_COLOR, - TO_RSM_DEPTH, - - TO_SCENE_DIFFUSE_ACC, - TO_SCENE_SPECULAR_ACC, - TO_SCENE_DIFFUSE_ACC_MS, - TO_SCENE_SPECULAR_ACC_MS, - TO_SCENE_TEXTURES, - TO_SCENE_TARGET, - - TO_BACKBUFFERSCALED_D2, - TO_BACKBUFFERSCALED_D4, - TO_BACKBUFFERSCALED_D8, - - TO_SKYDOME_MIE, - TO_SKYDOME_RAYLEIGH, - TO_SKYDOME_MOON, - - TO_VOLFOGSHADOW_BUF, - - TO_HDR_MEASURED_LUMINANCE, - TO_MODELHUD, - - TO_DEFAULT_ENVIRONMENT_PROBE, -}; - - -#define NUM_HDR_TONEMAP_TEXTURES 4 -#define NUM_HDR_BLOOM_TEXTURES 3 -#define MIN_DOF_COC_K 6 - - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) -#define MAX_OCCLUSION_READBACK_TEXTURES 2 -#else -#define MAX_OCCLUSION_READBACK_TEXTURES 8 -#endif - -#define DYNTEXTURE_TEXCACHE_LIMIT 32 - -inline int LogBaseTwo(int iNum) -{ - int i, n; - for (i = iNum - 1, n = 0; i > 0; i >>= 1, n++) - { - ; - } - return n; -} - -enum EShadowBuffers_Pool -{ - SBP_D16, - SBP_D24S8, - SBP_D32FS8, - SBP_R16G16, - SBP_MAX, - SBP_UNKNOWN -}; - -//dx9 usages -enum ETexture_Usage -{ - eTXUSAGE_AUTOGENMIPMAP, - eTXUSAGE_DEPTHSTENCIL, - eTXUSAGE_RENDERTARGET -}; - - - -#define SHADOWS_POOL_SIZE 1024//896 //768 -#define TEX_POOL_BLOCKLOGSIZE 5 // 32 -#define TEX_POOL_BLOCKSIZE (1 << TEX_POOL_BLOCKLOGSIZE) - -struct SDynTexture_Shadow; -struct SDepthTexture; - -//====================================================================== -// Dynamic textures -struct SDynTexture - : public IDynTexture -{ - static uint32 s_nMemoryOccupied; - static SDynTexture s_Root; - - SDynTexture* m_Next; //!< - SDynTexture* m_Prev; //!< - char m_sSource[128]; //!< pointer to the given name in the constructor call - - CTexture* m_pTexture; - ETEX_Format m_eTF; - ETEX_Type m_eTT; - uint32 m_nWidth; - uint32 m_nHeight; - uint32 m_nReqWidth; - uint32 m_nReqHeight; - uint32 m_nTexFlags; - uint32 m_nFrameReset; - - - bool m_bLocked; - byte m_nUpdateMask; - - ////////////////////////////////////////////////////////////////////////// - // Shadow specific vars. - ////////////////////////////////////////////////////////////////////////// - int m_nUniqueID; - - SDynTexture_Shadow* m_NextShadow; //!< - SDynTexture_Shadow* m_PrevShadow; //!< - - ShadowMapFrustum* m_pFrustumOwner; - IRenderNode* pLightOwner; - int nObjectsRenderedCount; - ////////////////////////////////////////////////////////////////////////// - - SDynTexture(const char* szSource); - SDynTexture(int nWidth, int nHeight, ETEX_Format eTF, ETEX_Type eTT, int nTexFlags, const char* szSource); - ~SDynTexture(); - - ////////////////////////////////////////////////////////////////////////// - // Custom new/delete for pool allocator. - ////////////////////////////////////////////////////////////////////////// - ILINE void* operator new(size_t nSize); - ILINE void operator delete(void* ptr); - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - - - virtual int GetTextureID(); - virtual bool Update(int nNewWidth, int nNewHeight); - bool RT_Update(int nNewWidth, int nNewHeight); - virtual void Apply(int nTUnit, int nTS = -1); - virtual bool ClearRT(); - virtual bool SetRT(int nRT, bool bPush, struct SDepthTexture* pDepthSurf, bool bScreenVP = false); - virtual bool RT_SetRT(int nRT, int nWidth, int nHeight, bool bPush, bool bScreenVP = false); - virtual bool SetRectStates() { return true; } - virtual bool RestoreRT(int nRT, bool bPop); - virtual ITexture* GetTexture() { return (ITexture*)m_pTexture; } - virtual void Release() { delete this; } - virtual void ReleaseForce(); - virtual void SetUpdateMask(); - virtual void ResetUpdateMask(); - virtual bool IsSecondFrame() { return m_nUpdateMask == 3; } - virtual byte GetFlags() const { return 0; } - virtual void GetSubImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight) - { - nX = 0; - nY = 0; - nWidth = m_nWidth; - nHeight = m_nHeight; - } - virtual void GetImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight); - virtual int GetWidth() { return m_nWidth; } - virtual int GetHeight() { return m_nHeight; } - - void Lock() { m_bLocked = true; } - void UnLock() { m_bLocked = false; } - - virtual void AdjustRealSize(); - virtual bool IsValid(); - - _inline void UnlinkGlobal() - { - if (!m_Next || !m_Prev) - { - return; - } - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - m_Next = m_Prev = NULL; - } - _inline void LinkGlobal(SDynTexture* Before) - { - if (m_Next || m_Prev) - { - return; - } - m_Next = Before->m_Next; - Before->m_Next->m_Prev = this; - Before->m_Next = this; - m_Prev = Before; - } - virtual void Unlink() - { - UnlinkGlobal(); - } - virtual void Link() - { - LinkGlobal(&s_Root); - } - ETEX_Format GetFormat() { return m_eTF; } - bool FreeTextures(bool bOldOnly, int nNeedSpace); - - typedef AZStd::multimap, AZ::AZStdAlloc> TextureSubset; - typedef TextureSubset::iterator TextureSubsetItor; - typedef AZStd::multimap, AZ::AZStdAlloc> TextureSet; - typedef TextureSet::iterator TextureSetItor; - - static TextureSet s_availableTexturePool2D_BC1; - static TextureSubset s_checkedOutTexturePool2D_BC1; - static TextureSet s_availableTexturePool2D_R8G8B8A8; - static TextureSubset s_checkedOutTexturePool2D_R8G8B8A8; - static TextureSet s_availableTexturePool2D_R32F; - static TextureSubset s_checkedOutTexturePool2D_R32F; - static TextureSet s_availableTexturePool2D_R16F; - static TextureSubset s_checkedOutTexturePool2D_R16F; - - static TextureSet s_availableTexturePool2D_R16G16F; - static TextureSubset s_checkedOutTexturePool2D_R16G16F; - static TextureSet s_availableTexturePool2D_R8G8B8A8S; - static TextureSubset s_checkedOutTexturePool2D_R8G8B8A8S; - static TextureSet s_availableTexturePool2D_R16G16B16A16F; - static TextureSubset s_checkedOutTexturePool2D_R16G16B16A16F; - static TextureSet s_availableTexturePool2D_R10G10B10A2; - static TextureSubset s_checkedOutTexturePool2D_R10G10B10A2; - - static TextureSet s_availableTexturePool2D_R11G11B10F; - static TextureSubset s_checkedOutTexturePool2D_R11G11B10F; - static TextureSet s_availableTexturePoolCube_R11G11B10F; - static TextureSubset s_checkedOutTexturePoolCube_R11G11B10F; - static TextureSet s_availableTexturePool2D_R8G8S; - static TextureSubset s_checkedOutTexturePool2D_R8G8S; - static TextureSet s_availableTexturePoolCube_R8G8S; - static TextureSubset s_checkedOutTexturePoolCube_R8G8S; - - static TextureSet s_availableTexturePool2D_Shadows[SBP_MAX]; - static TextureSubset s_checkedOutTexturePool2D_Shadows[SBP_MAX]; - static TextureSet s_availableTexturePoolCube_Shadows[SBP_MAX]; - static TextureSubset s_checkedOutTexturePoolCube_Shadows[SBP_MAX]; - - static TextureSet s_availableTexturePool2DCustom_R16G16F; - static TextureSubset s_checkedOutTexturePool2DCustom_R16G16F; - - static TextureSet s_availableTexturePoolCube_BC1; - static TextureSubset s_checkedOutTexturePoolCube_BC1; - static TextureSet s_availableTexturePoolCube_R8G8B8A8; - static TextureSubset s_checkedOutTexturePoolCube_R8G8B8A8; - static TextureSet s_availableTexturePoolCube_R32F; - static TextureSubset s_checkedOutTexturePoolCube_R32F; - static TextureSet s_availableTexturePoolCube_R16F; - static TextureSubset s_checkedOutTexturePoolCube_R16F; - static TextureSet s_availableTexturePoolCube_R16G16F; - static TextureSubset s_checkedOutTexturePoolCube_R16G16F; - static TextureSet s_availableTexturePoolCube_R8G8B8A8S; - static TextureSubset s_checkedOutTexturePoolCube_R8G8B8A8S; - static TextureSet s_availableTexturePoolCube_R16G16B16A16F; - static TextureSubset s_checkedOutTexturePoolCube_R16G16B16A16F; - - static TextureSet s_availableTexturePoolCube_R10G10B10A2; - static TextureSubset s_checkedOutTexturePoolCube_R10G10B10A2; - - static TextureSet s_availableTexturePoolCubeCustom_R16G16F; - static TextureSubset s_checkedOutTexturePoolCubeCustom_R16G16F; - - static uint32 s_iNumTextureBytesCheckedOut; - static uint32 s_iNumTextureBytesCheckedIn; - - static uint32 s_SuggestedDynTexAtlasCloudsMaxsize; - static uint32 s_SuggestedTexAtlasSize; - static uint32 s_SuggestedDynTexMaxSize; - static uint32 s_CurDynTexAtlasCloudsMaxsize; - static uint32 s_CurTexAtlasSize; - static uint32 s_CurDynTexMaxSize; - - CTexture* CreateDynamicRT(); - CTexture* GetDynamicRT(); - void ReleaseDynamicRT(bool bForce); - - EShadowBuffers_Pool ConvertTexFormatToShadowsPool(ETEX_Format e); - - static bool FreeAvailableDynamicRT(int nNeedSpace, TextureSet* pSet, bool bOldOnly); - - static void ShutDown(); - - static void Init(); - static void Tick(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - - -typedef stl::PoolAllocatorNoMT SDynTexture_PoolAlloc; -extern SDynTexture_PoolAlloc* g_pSDynTexture_PoolAlloc; - -////////////////////////////////////////////////////////////////////////// -// Custom new/delete for pool allocator. -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -inline void* SDynTexture::operator new(size_t nSize) -{ - void* ptr = g_pSDynTexture_PoolAlloc->Allocate(); - if (ptr) - { - memset(ptr, 0, nSize); // Clear objects memory. - } - return ptr; -} -////////////////////////////////////////////////////////////////////////// -inline void SDynTexture::operator delete(void* ptr) -{ - if (ptr) - { - g_pSDynTexture_PoolAlloc->Deallocate(ptr); - } -} - - -//============================================================================== - -enum ETexPool : int -{ - eTP_Clouds, - eTP_Sprites, - - eTP_Max -}; - -struct STextureSetFormat -{ - struct SDynTexture2* m_pRoot; - ETEX_Format m_eTF; - ETexPool m_eTexPool; - ETEX_Type m_eTT; - int m_nTexFlags; - std::vector m_TexPools; - - STextureSetFormat(ETEX_Format eTF, ETexPool eTexPool, uint32 nTexFlags) - { - m_eTF = eTF; - m_eTexPool = eTexPool; - m_eTT = eTT_2D; - m_pRoot = NULL; - m_nTexFlags = nTexFlags; - } - ~STextureSetFormat(); -}; - -struct SDynTexture2 - : public IDynTexture -{ -#ifndef _DEBUG - char* m_sSource; //!< pointer to the given name in the constructor call -#else - char m_sSource[128]; //!< pointer to the given name in the constructor call -#endif - STextureSetFormat* m_pOwner; - CPowerOf2BlockPacker* m_pAllocator; - CTexture* m_pTexture; - uint32 m_nBlockID; - ETexPool m_eTexPool; - - SDynTexture2* m_Next; //!< - SDynTexture2** m_PrevLink; //!< - - void UnlinkGlobal() - { - if (m_Next) - { - m_Next->m_PrevLink = m_PrevLink; - } - if (m_PrevLink) - { - *m_PrevLink = m_Next; - } - } - void LinkGlobal(SDynTexture2*& Before) - { - if (Before) - { - Before->m_PrevLink = &m_Next; - } - m_Next = Before; - m_PrevLink = &Before; - Before = this; - } - - void Link() - { - LinkGlobal(m_pOwner->m_pRoot); - } - - void Unlink() - { - UnlinkGlobal(); - m_Next = NULL; - m_PrevLink = NULL; - } - - bool Remove(); - virtual bool IsValid(); - bool _IsValid() { return IsValid(); } - - SDynTexture2(uint32 nWidth, uint32 nHeight, uint32 nTexFlags, const char* szSource, ETexPool eTexPool); - SDynTexture2(const char* szSource, ETexPool eTexPool); - ~SDynTexture2(); - - bool UpdateAtlasSize(int nNewWidth, int nNewHeight); - void ReleaseForce(); - - virtual bool Update(int nNewWidth, int nNewHeight); - virtual void Apply(int nTUnit, int nTS = -1); - virtual bool ClearRT(); - virtual bool SetRT(int nRT, bool bPush, SDepthTexture* pDepthSurf, bool bScreenVP = false); - virtual bool SetRectStates(); - virtual bool RestoreRT(int nRT, bool bPop); - virtual ITexture* GetTexture() { return (ITexture*)m_pTexture; } - ETEX_Format GetFormat() { return m_pOwner->m_eTF; } - virtual void SetUpdateMask(); - virtual void ResetUpdateMask(); - virtual bool IsSecondFrame() { return m_nUpdateMask == 3; } - virtual byte GetFlags() const { return m_nFlags; } - virtual void SetFlags(byte flags) { m_nFlags = flags; } - - // IDynTexture implementation - virtual void Release() { delete this; } - virtual void GetSubImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight) - { - nX = m_nX; - nY = m_nY; - nWidth = m_nWidth; - nHeight = m_nHeight; - } - - virtual void GetImageRect(uint32& nX, uint32& nY, uint32& nWidth, uint32& nHeight); - virtual int GetTextureID(); - virtual void Lock() { m_bLocked = true; } - virtual void UnLock() { m_bLocked = false; } - virtual int GetWidth() { return m_nWidth; } - virtual int GetHeight() { return m_nHeight; } - - typedef std::map TextureSet2; - typedef TextureSet2::iterator TextureSet2Itor; - - static AZStd::unique_ptr s_TexturePool[eTP_Max]; - static int s_nMemoryOccupied[eTP_Max]; - - static void ShutDown(); - static void Init(ETexPool eTexPool); - - static int GetPoolMaxSize(ETexPool eTexPool); - static void SetPoolMaxSize(ETexPool eTexPool, int nSize, bool bWarn); - static const char* GetPoolName(ETexPool eTexPool); - static ETEX_Format GetPoolTexFormat(ETexPool eTexPool); - static int GetPoolTexNum(ETexPool eTexPool) - { - int nT = 0; - for (TextureSet2Itor it = s_TexturePool[eTexPool]->begin(); it != s_TexturePool[eTexPool]->end(); it++) - { - STextureSetFormat* pF = it->second; - nT += pF->m_TexPools.size(); - } - return nT; - } - - uint32 m_nX; - uint32 m_nY; - uint32 m_nWidth; - uint32 m_nHeight; - - bool m_bLocked; - byte m_nFlags; - byte m_nUpdateMask; // Crossfire odd/even frames - uint32 m_nFrameReset; - uint32 m_nAccessFrame; -}; - -////////////////////////////////////////////////////////////////////////// -// Dynamic texture for the shadow. -// This class must not contain any non static member variables, -// because SDynTexture allocated used constant size pool. -////////////////////////////////////////////////////////////////////////// -struct SDynTexture_Shadow - : public SDynTexture -{ - static SDynTexture_Shadow s_RootShadow; - - ////////////////////////////////////////////////////////////////////////// - SDynTexture_Shadow(int nWidth, int nHeight, ETEX_Format eTF, ETEX_Type eTT, int nTexFlags, const char* szSource); - SDynTexture_Shadow(const char* szSource); - ~SDynTexture_Shadow(); - - _inline void UnlinkShadow() - { - //assert(gRenDev->m_pRT->IsRenderThread()); - if (!m_NextShadow || !m_PrevShadow) - { - return; - } - m_NextShadow->m_PrevShadow = m_PrevShadow; - m_PrevShadow->m_NextShadow = m_NextShadow; - m_NextShadow = m_PrevShadow = NULL; - } - _inline void LinkShadow(SDynTexture_Shadow* Before) - { - assert(gRenDev->m_pRT->IsRenderThread()); - if (m_NextShadow || m_PrevShadow) - { - return; - } - m_NextShadow = Before->m_NextShadow; - Before->m_NextShadow->m_PrevShadow = this; - Before->m_NextShadow = this; - m_PrevShadow = Before; - } - - SDynTexture_Shadow* GetByID(int nID) - { - assert(gRenDev->m_pRT->IsRenderThread()); - SDynTexture_Shadow* pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; - for (pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; pTX != &SDynTexture_Shadow::s_RootShadow; pTX = pTX->m_NextShadow) - { - if (pTX->m_nUniqueID == nID) - { - return pTX; - } - } - return NULL; - } - static void RT_EntityDelete(IRenderNode* pRenderNode); - - virtual void Unlink() - { - assert(gRenDev->m_pRT->IsRenderThread()); - UnlinkGlobal(); - UnlinkShadow(); - } - virtual void Link() - { - assert(gRenDev->m_pRT->IsRenderThread()); - LinkGlobal(&s_Root); - LinkShadow(&s_RootShadow); - } - virtual void AdjustRealSize(); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - SDynTexture::GetMemoryUsage(pSizer); - } - - static SDynTexture_Shadow* GetForFrustum(ShadowMapFrustum* pFrustum); - - static void ShutDown(); -}; - -//========================================================================== -// Texture - -struct STexCacheFileHeader -{ - int8 m_nSides; - int8 m_nMipsPersistent; - STexCacheFileHeader() - { - m_nSides = 0; - m_nMipsPersistent = 0; - } -}; - -struct SMipData -{ -public: - byte* DataArray; // Data. - bool m_bNative : 1; - - SMipData() - : m_bNative(false) - , DataArray(NULL) - {} - ~SMipData() - { - Free(); - } - - void Free() - { - SAFE_DELETE_ARRAY(DataArray); - m_bNative = false; - } - void Init(int InSize, [[maybe_unused]] int nWidth, [[maybe_unused]] int nHeight) - { - assert(DataArray == NULL); - DataArray = new byte[InSize]; - m_bNative = false; - } -}; - -struct STexPool; -struct STexPoolItem; - -struct STexStreamRoundInfo -{ - STexStreamRoundInfo() - { - nRoundUpdateId = -1; - bHighPriority = false; - bLastHighPriority = false; - } - - int32 nRoundUpdateId : 30; - uint32 bHighPriority : 1; - uint32 bLastHighPriority : 1; -}; - -struct STexStreamZoneInfo -{ - STexStreamZoneInfo() - { - fMinMipFactor = fLastMinMipFactor = 1000000.f; - } - - float fMinMipFactor; - float fLastMinMipFactor; -}; - -struct STexMipHeader -{ - uint32 m_SideSizeWithMips : 31; - uint32 m_InPlaceStreamable : 1; - uint32 m_SideSize : 29; - uint32 m_eMediaType : 3; -#if defined(TEXSTRM_STORE_DEVSIZES) - uint32 m_DevSideSizeWithMips; -#endif - SMipData* m_Mips; - STexMipHeader() - { - m_SideSizeWithMips = 0; - m_InPlaceStreamable = 0; - m_SideSize = 0; - m_eMediaType = 0; -#if defined(TEXSTRM_STORE_DEVSIZES) - m_DevSideSizeWithMips = 0; -#endif - m_Mips = NULL; - } - ~STexMipHeader() - { - SAFE_DELETE_ARRAY(m_Mips); - } -}; - -struct STexStreamingInfo -{ - STexStreamZoneInfo m_arrSPInfo[MAX_PREDICTION_ZONES]; - - STexPoolItem* m_pPoolItem; - - uint32 m_nSrcStart; - - STexMipHeader* m_pMipHeader; - DDSSplitted::DDSDesc m_desc; - float m_fMinMipFactor; - - STexStreamingInfo(){} - STexStreamingInfo(const uint8 nMips) - { - m_pPoolItem = NULL; - // +1 to accomodate queries for the size of the texture with no mips - m_pMipHeader = new STexMipHeader[nMips + 1]; - m_nSrcStart = 0; - m_fMinMipFactor = 0.0f; - } - - ~STexStreamingInfo() - { - SAFE_DELETE_ARRAY(m_pMipHeader); - } - - void GetMemoryUsage(ICrySizer* pSizer, int nMips, int nSides) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pMipHeader, sizeof(STexMipHeader) * nMips); - for (int i = 0; i < nMips; i++) - { - pSizer->AddObject(m_pMipHeader[i].m_Mips, sizeof(SMipData) * nSides); - for (int j = 0; j < nSides; j++) - { - pSizer->AddObject(m_pMipHeader[i].m_Mips[j].DataArray, m_pMipHeader[i].m_SideSize); - } - } - } - - int GetSize(int nMips, int nSides) - { - int nSize = sizeof(*this); - for (int i = 0; i < nMips; i++) - { - nSize += sizeof(m_pMipHeader[i]); - for (int j = 0; j < nSides; j++) - { - nSize += sizeof(m_pMipHeader[i].m_Mips[j]); - if (m_pMipHeader[i].m_Mips[j].DataArray) - { - nSize += m_pMipHeader[i].m_SideSize; - } - } - } - return nSize; - } - - void* operator new ([[maybe_unused]] size_t sz, void* p){ return p; } - void operator delete ([[maybe_unused]] void* ptr, [[maybe_unused]] void* p){} - -private: - void* operator new (size_t sz); - void operator delete ([[maybe_unused]] void* ptr){__debugbreak(); } -}; - -struct STexStreamInMipState -{ - uint32 m_nSideDelta : 28; - bool m_bStreamInPlace : 1; - bool m_bExpanded : 1; - bool m_bUploaded : 1; - - STexStreamInMipState() - { - m_nSideDelta = 0; - m_bStreamInPlace = false; - m_bExpanded = false; - m_bUploaded = false; - } -}; - -struct STexStreamInState - : public IStreamCallback -{ -public: - enum - { - MaxMips = 12, - MaxStreams = MaxMips * 6, - }; - -public: - STexStreamInState(); - - void Reset(); - bool TryCommit(); - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); - -#ifdef TEXSTRM_ASYNC_TEXCOPY - void CopyMips(); -#endif - -public: - CTexture* m_pTexture; - STexPoolItem* m_pNewPoolItem; - volatile int m_nAsyncRefCount; - uint8 m_nHigherUploadedMip; - uint8 m_nLowerUploadedMip; - uint8 m_nActivateMip; - bool m_bAborted; - bool m_bValidLowMips; - volatile bool m_bAllStreamsComplete; -#if defined(TEXSTRM_COMMIT_COOLDOWN) - int m_nStallFrames; -#endif - -#ifndef _RELEASE - float m_fStartTime; -#endif -#if defined(TEXSTRM_DEFERRED_UPLOAD) - ID3D11CommandList* m_pCmdList; -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_1 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif - - IReadStreamPtr m_pStreams[MaxStreams]; - STexStreamInMipState m_mips[MaxMips]; -}; - -struct STexStreamPrepState - : IImageFileStreamCallback -{ -public: - STexStreamPrepState() - : m_bCompleted(false) - , m_bFailed(false) - , m_bNeedsFinalise(false) - { - } - - bool Commit(); - -public: // IImageFileStreamCallback Members - virtual void OnImageFileStreamComplete(CImageFile* pImFile); - -public: - _smart_ptr m_pTexture; - _smart_ptr m_pImage; - volatile bool m_bCompleted; - volatile bool m_bFailed; - volatile bool m_bNeedsFinalise; - -private: - STexStreamPrepState(const STexStreamPrepState&); - STexStreamPrepState& operator = (const STexStreamPrepState&); -}; - -#ifdef TEXSTRM_ASYNC_TEXCOPY -struct STexStreamOutState -{ -public: - void Reset(); - bool TryCommit(); - - void CopyMips(); - -public: - AZ::LegacyJobExecutor m_jobExecutor; - - CTexture* m_pTexture; - STexPoolItem* m_pNewPoolItem; - uint8 m_nStartMip; - volatile bool m_bDone; - volatile bool m_bAborted; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_2 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif -}; -#endif - -//=================================================================== - -struct SEnvTexture -{ - bool m_bInprogress; - bool m_bReady; - bool m_bWater; - bool m_bReflected; - bool m_bReserved; - int m_MaskReady; - int m_Id; - int m_TexSize; - // Result Cube-Map or 2D RT texture - SDynTexture* m_pTex; - float m_TimeLastUpdated; - Vec3 m_CamPos; - Vec3 m_ObjPos; - Ang3 m_Angle; - int m_nFrameReset; - Matrix44 m_Matrix; - //void *m_pQuery[6]; - //void *m_pRenderTargets[6]; - - // Cube maps average colors (used for RT radiosity) - int m_nFrameCreated[6]; - ColorF m_EnvColors[6]; - - SEnvTexture() - { - m_bInprogress = false; - m_bReady = false; - m_bWater = false; - m_bReflected = false; - m_bReserved = false; - m_MaskReady = 0; - m_Id = 0; - m_pTex = NULL; - m_nFrameReset = -1; - m_CamPos.Set(0.0f, 0.0f, 0.0f); - m_ObjPos.Set(0.0f, 0.0f, 0.0f); - m_Angle.Set(0.0f, 0.0f, 0.0f); - - for (int i = 0; i < 6; i++) - { - //m_pQuery[i] = NULL; - m_nFrameCreated[i] = -1; - //m_pRenderTargets[i] = NULL; - } - } - - void Release(); - void ReleaseDeviceObjects(); - void RT_SetMatrix(); -}; - - -//=============================================================================== - -struct SPixFormat -{ - // Pixel format info. - D3DFormat DeviceFormat;// Pixel format from Direct3D. - const char* Desc; // Stat: Human readable name for stats. - int8 BytesPerBlock;// Total bits per pixel. - uint8 bCanDS : 1; - uint8 bCanRT : 1; - uint8 bCanMultiSampleRT : 1; - uint8 bCanMipsAutoGen : 1; - uint8 bCanReadSRGB : 1; - uint8 bCanGather : 1; - uint8 bCanGatherCmp : 1; - uint8 bCanBlend : 1; - int16 MaxWidth; - int16 MaxHeight; - SPixFormat* Next; - - SPixFormat() - { - Init(); - } - void Init() - { - BytesPerBlock = 0; - DeviceFormat = (D3DFormat)0; - Desc = NULL; - Next = NULL; - bCanDS = false; - bCanRT = false; - bCanMultiSampleRT = false; - bCanMipsAutoGen = false; - bCanReadSRGB = false; - bCanGather = false; - bCanGatherCmp = false; - bCanBlend = false; - } - bool IsValid() const - { - if (BytesPerBlock) - { - return true; - } - return false; - } - bool CheckSupport(D3DFormat Format, const char* szDescr, ETexture_Usage eTxUsage = eTXUSAGE_AUTOGENMIPMAP); -}; - -struct SPixFormatSupport -{ - SPixFormat m_FormatA8; //8 bit alpha - SPixFormat m_FormatR8; - SPixFormat m_FormatR8S; - SPixFormat m_FormatR8G8; //16 bit - SPixFormat m_FormatR8G8S; //16 bit - SPixFormat m_FormatR8G8B8A8; //32 bit - SPixFormat m_FormatR8G8B8A8S; //32 bit - SPixFormat m_FormatR10G10B10A2; //32 bit - - SPixFormat m_FormatR16; //16 bit - SPixFormat m_FormatR16U; //16 bit - SPixFormat m_FormatR16G16U; //32 bit - SPixFormat m_FormatR10G10B10A2UI; //32 bit - SPixFormat m_FormatR16F; //16 bit - SPixFormat m_FormatR32F; //32 bit - SPixFormat m_FormatR16G16; //32 bit - SPixFormat m_FormatR16G16S; //32 bit - SPixFormat m_FormatR16G16F; //32 bit - SPixFormat m_FormatR11G11B10F; //32 bit - SPixFormat m_FormatR16G16B16A16F; //64 bit - SPixFormat m_FormatR16G16B16A16; //64 bit - SPixFormat m_FormatR16G16B16A16S; //64 bit - SPixFormat m_FormatR32G32B32A32F; //128 bit - - SPixFormat m_FormatBC1; //Compressed RGB - SPixFormat m_FormatBC2; //Compressed RGBA - SPixFormat m_FormatBC3; //Compressed RGBA - SPixFormat m_FormatBC4U; // ATI1, single channel compression, unsigned - SPixFormat m_FormatBC4S; // ATI1, single channel compression, signed - SPixFormat m_FormatBC5U; // - SPixFormat m_FormatBC5S; // - SPixFormat m_FormatBC6UH; //Compressed RGB - SPixFormat m_FormatBC6SH; //Compressed RGB - SPixFormat m_FormatBC7; //Compressed RGBA - - SPixFormat m_FormatR9G9B9E5; //Shared exponent RGB - - SPixFormat m_FormatEAC_R11; //EAC compressed single channel for mobile - SPixFormat m_FormatEAC_RG11; //EAC compressed dual channel for mobile - SPixFormat m_FormatETC2; //ETC2 compressed RGB for mobile - SPixFormat m_FormatETC2A; //ETC2a compressed RGBA for mobile - - SPixFormat m_FormatD16; //16bit fixed point depth - SPixFormat m_FormatD24S8; //24bit fixed point depth + 8bit stencil - SPixFormat m_FormatD32F; //32bit floating point depth - SPixFormat m_FormatD32FS8; //32bit floating point depth + 8bit stencil - - SPixFormat m_FormatB5G6R5; //16 bit - SPixFormat m_FormatB5G5R5; //16 bit - SPixFormat m_FormatB4G4R4A4; //16 bit - SPixFormat m_FormatB8G8R8X8; //32 bit - SPixFormat m_FormatB8G8R8A8; //32 bit - -#ifdef CRY_USE_METAL - SPixFormat m_FormatPVRTC2; //ETC2 compressed RGB for mobile - SPixFormat m_FormatPVRTC4; //ETC2a compressed RGBA for mobile -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - SPixFormat m_FormatASTC_4x4; - SPixFormat m_FormatASTC_5x4; - SPixFormat m_FormatASTC_5x5; - SPixFormat m_FormatASTC_6x5; - SPixFormat m_FormatASTC_6x6; - SPixFormat m_FormatASTC_8x5; - SPixFormat m_FormatASTC_8x6; - SPixFormat m_FormatASTC_8x8; - SPixFormat m_FormatASTC_10x5; - SPixFormat m_FormatASTC_10x6; - SPixFormat m_FormatASTC_10x8; - SPixFormat m_FormatASTC_10x10; - SPixFormat m_FormatASTC_12x10; - SPixFormat m_FormatASTC_12x12; -#endif - - SPixFormat* m_FirstPixelFormat; - - void CheckFormatSupport(); -}; - -struct STexStageInfo -{ - int m_nCurState; - CDeviceTexture* m_DevTexture; - - STexState m_State; - float m_fMipBias; -#if !defined(NULL_RENDERER) - D3DShaderResourceView* m_pCurResView; - EHWShaderClass m_eHWSC; -#endif - - STexStageInfo() - { - Flush(); - } - void Flush() - { - m_nCurState = -1; - m_State.m_nMipFilter = -1; - m_State.m_nMinFilter = -1; - m_State.m_nMagFilter = -1; - m_State.m_nAddressU = -1; - m_State.m_nAddressV = -1; - m_State.m_nAddressW = -1; - m_State.m_nAnisotropy = 0; -#if !defined(NULL_RENDERER) - m_pCurResView = NULL; - m_eHWSC = eHWSC_Pixel; -#endif - m_DevTexture = NULL; - m_fMipBias = 0.f; - } -}; - - -struct STexData -{ - const byte* m_pData[6]; - uint16 m_nWidth; - uint16 m_nHeight; - uint16 m_nDepth; -protected: - uint8 m_reallocated; -public: - ETEX_Format m_eTF; - uint8 m_nMips; - int m_nFlags; - float m_fAvgBrightness; - ColorF m_cMinColor; - ColorF m_cMaxColor; - const char* m_pFilePath; - - STexData() - { - m_pData[0] = m_pData[1] = m_pData[2] = m_pData[3] = m_pData[4] = m_pData[5] = 0; - m_nWidth = 0; - m_nHeight = 0; - m_nDepth = 1; - m_reallocated = 0; - m_eTF = eTF_Unknown; - m_nMips = 0; - m_nFlags = 0; - m_fAvgBrightness = 1.0f; - m_cMinColor = 0.0f; - m_cMaxColor = 1.0f; - m_pFilePath = 0; - } - void AssignData(unsigned int i, const byte* pNewData) - { - assert(i < 6); - if (WasReallocated(i)) - { - delete [] m_pData[i]; - } - m_pData[i] = pNewData; - SetReallocated(i); - } - bool WasReallocated(unsigned int i) const - { - return (m_reallocated & (1 << i)) != 0; - } - void SetReallocated(unsigned int i) - { - m_reallocated |= (1 << i); - } -}; - -struct SDepthTexture -{ - int nWidth; - int nHeight; - bool bBusy; - int nFrameAccess; - D3DTexture* pTarget; - D3DDepthSurface* pSurf; - CTexture* pTex; - SDepthTexture() - : nWidth(0) - , nHeight(0) - , bBusy(false) - , nFrameAccess(-1) - , pTarget(nullptr) - , pSurf(nullptr) - , pTex(nullptr) - {} - - void Release(bool bReleaseTex = false); - - ~SDepthTexture(); -}; - - -struct DirtyRECT -{ - RECT srcRect; - uint16 dstX; - uint16 dstY; -}; - - -struct SResourceView -{ - typedef uint64 KeyType; - - static const KeyType DefaultView = (KeyType) - 1LL; - static const KeyType DefaultViewMS = (KeyType) - 2LL; - static const KeyType DefaultViewSRGB = (KeyType) - 3LL; - - enum ResourceViewType - { - eShaderResourceView = 0, - eRenderTargetView, - eDepthStencilView, - eUnorderedAccessView, - - eNumResourceViews - }; - - union ResourceViewDesc - { - struct - { - uint64 eViewType : 3; - uint64 nFormat : 7; - uint64 nFirstSlice : 11; - uint64 nSliceCount : 11; - uint64 nMostDetailedMip : 4; - uint64 nMipCount : 4; - uint64 bSrgbRead : 1; - uint64 bMultisample : 1; - uint64 nFlags : 2; - uint64 nUnused : 20; - }; - - KeyType Key; - }; - - SResourceView(uint64 nKey = DefaultView) - { - COMPILE_TIME_ASSERT(sizeof(m_Desc) <= sizeof(KeyType)); - - m_Desc.Key = nKey; - m_pDeviceResourceView = NULL; - } - - static SResourceView ShaderResourceView(ETEX_Format nFormat, int nFirstSlice = 0, int nSliceCount = -1, int nMostDetailedMip = 0, int nMipCount = -1, bool bSrgbRead = false, bool bMultisample = false); - static SResourceView RenderTargetView(ETEX_Format nFormat, int nFirstSlice = 0, int nSliceCount = -1, int nMipLevel = 0, bool bMultisample = false); - static SResourceView DepthStencilView(ETEX_Format nFormat, int nFirstSlice = 0, int nSliceCount = -1, int nMipLevel = 0, int nFlags = 0, bool bMultisample = false); - static SResourceView UnorderedAccessView(ETEX_Format nFormat, int nFirstSlice = 0, int nSliceCount = -1, int nMipLevel = 0, int nFlags = 0); - - bool operator==(const SResourceView& other) const - { - return m_Desc.Key == other.m_Desc.Key; - } - - ResourceViewDesc m_Desc; - void* m_pDeviceResourceView; -}; - -// properties of the render targets ONLY -struct RenderTargetData -{ - int m_nRTSetFrameID; // last read access, compare with GetFrameID(false) - struct - { - uint8 m_nMSAASamples : 4; - uint8 m_nMSAAQuality : 4; - }; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_3 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif - TArray m_ResourceViews; - CDeviceTexture* m_pDeviceTextureMSAA; - - RenderTargetData() - { - memset(this, 0, sizeof(*this)); - m_nRTSetFrameID = -1; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_4 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif - } - ~RenderTargetData(); -}; - -////////////////////////////////////////////////////////////////////////// - -struct SStreamFormatCodeKey -{ - union - { - struct - { - uint16 nWidth; - uint16 nHeight; - ETEX_Format fmt; - uint8 nTailMips; - } s; - uint64 u; - }; - - SStreamFormatCodeKey(uint32 nWidth, uint32 nHeight, ETEX_Format fmt, uint8 nTailMips) - { - u = 0; - s.nWidth = (uint16)nWidth; - s.nHeight = (uint16)nHeight; - s.fmt = fmt; - s.nTailMips = nTailMips; - } - - friend bool operator < (const SStreamFormatCodeKey& a, const SStreamFormatCodeKey& b) - { - return a.u < b.u; - } -}; - -struct SStreamFormatSize -{ - uint32 size : 31; - uint32 alignSlices : 1; -}; - -struct SStreamFormatCode -{ - enum - { - MaxMips = 14 - }; - SStreamFormatSize sizes[MaxMips]; -}; - -////////////////////////////////////////////////////////////////////////// - -class CTexture - : public ITexture - , public CBaseResource -{ - friend struct SDynTexture; - friend struct SDynTexture2; - friend class CD3D9Renderer; - friend struct STexStreamInState; - friend struct STexStreamOutState; - friend class ITextureStreamer; - friend class CPlanningTextureStreamer; - friend struct SPlanningTextureOrder; - friend struct SPlanningTextureRequestOrder; - friend struct STexPoolItem; - friend struct CompareStreamingPrioriry; - friend struct CompareStreamingPrioriryInv; - -public: - virtual void ApplyTexture(int nTUnit, int nState = -1) override - { - Apply(nTUnit, nState); - } - - virtual void Apply(int nTUnit, int nState = -1, int nTexMatSlot = EFTT_UNKNOWN, int nSUnit = -1, SResourceView::KeyType nResViewKey = SResourceView::DefaultView, EHWShaderClass eHWSC = eHWSC_Pixel); - -private: - D3DSurface* m_pDeviceRTV; - D3DSurface* m_pDeviceRTVMS; - - CDeviceTexture* m_pDevTexture; - const SPixFormat* m_pPixelFormat; - - // Start block that should fit in one cache-line - // Reason is to minimize cache misses during texture streaming update job - // Note: This is checked COMPILE_TIME_ASSERTS in ~CTexture implementation (Texture.cpp) - - STexStreamingInfo* m_pFileTexMips; // properties of the streamable texture ONLY - - uint16 m_nWidth; - uint16 m_nHeight; - uint16 m_nDepth; - ETEX_Format m_eTFDst; - ETEX_TileMode m_eSrcTileMode; - uint8 m_nStreamFormatCode; - - uint32 m_nFlags; // e.g. FT_USAGE_DYNAMIC - - bool m_bStreamed : 1; - bool m_bStreamPrepared : 1; - bool m_bStreamRequested : 1; - bool m_bWasUnloaded : 1; - bool m_bPostponed : 1; - bool m_bForceStreamHighRes : 1; - bool m_bNeedRestoring : 1; - bool m_bNoDevTexture : 1; - - bool m_bNoTexture : 1; - bool m_bResolved : 1; - bool m_bUseMultisampledRTV : 1; // Allows switching rendering between multisampled/non-multisampled rendertarget views - bool m_bHighQualityFiltering : 1; - bool m_bCustomFormat : 1; // Allow custom texture formats - for faster texture fetches - bool m_bVertexTexture : 1; - bool m_bUseDecalBorderCol : 1; - bool m_bIsSRGB : 1; - - bool m_bAsyncDevTexCreation : 1; - bool m_bInDistanceSortedList : 1; - bool m_bCreatedInLevel : 1; - bool m_bUsedRecently : 1; - bool m_bStatTracked : 1; - bool m_bStreamHighPriority : 1; - uint8 m_renderTargetUseCount : CTEXTURE_RENDER_TARGET_USE_COUNT_NUMBER_BITS; // Not a bool because a render target can be pushed on the RTStack multiple times - - int8 m_nCustomID; - - uint8 m_nArraySize; - int8 m_nMips; - ETEX_Type m_eTT; - - ETEX_Format m_eTFSrc; - int8 m_nStreamingPriority; - int8 m_nMinMipVidUploaded; - int8 m_nMinMipVidActive; - - uint16 m_nStreamSlot; - int16 m_fpMinMipCur; - - STexCacheFileHeader m_CacheFileHeader; - uint16 m_nDefState; - - int32 m_nActualSize; - int32 m_nPersistentSize; - - int m_nAccessFrameID; // last read access, compare with GetFrameID(false) - STexStreamRoundInfo m_streamRounds[MAX_PREDICTION_ZONES]; - - // End block that should fit in one cache-line - - DynArray m_composition; - float m_fCurrentMipBias; // streaming mip fading - float m_fAvgBrightness; - ColorF m_cMinColor; - ColorF m_cMaxColor; - ColorF m_cClearColor; - - RenderTargetData* m_pRenderTargetData; - - string m_SrcName; - -#ifndef _RELEASE - string m_sAssetScopeName; -#endif - D3DShaderResourceView* m_pDeviceShaderResource; - D3DShaderResourceView* m_pDeviceShaderResourceSRGB; - - typedef AZStd::function InvalidateCallbackType; - AZStd::unordered_multimap m_invalidateCallbacks; - - AZStd::mutex* m_invalidateCallbacksMutex = nullptr; - static StaticInstance m_staticInvalidateCallbacksMutex; - - bool m_bisTextureMissing = false; - -public: - int m_nUpdateFrameID; // last write access, compare with GetFrameID(false) - -private: - -#ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT - struct SLowResSystemCopy - { - SLowResSystemCopy() - { - m_nLowResSystemCopyAtlasId = 0; - m_nLowResCopyWidth = m_nLowResCopyHeight = 0; - } - PodArray m_lowResSystemCopy; - uint16 m_nLowResCopyWidth, m_nLowResCopyHeight; - int m_nLowResSystemCopyAtlasId; - }; - typedef std::map LowResSystemCopyType; - static StaticInstance s_LowResSystemCopy; - void PrepareLowResSystemCopy(const byte* pTexData, bool bTexDataHasAllMips); - const ColorB* GetLowResSystemCopy(uint16& nWidth, uint16& nHeight, int** ppLowResSystemCopyAtlasId); -#endif - - static CCryNameTSCRC GenName(const char* name, uint32 nFlags = 0); - static CTexture* NewTexture(const char* name, uint32 nFlags, ETEX_Format eTFDst, bool& bFound); - - ETEX_Format FormatFixup(ETEX_Format src); - bool FormatFixup(STexData& td); - bool ImagePreprocessing(STexData& td); - -#ifndef _RELEASE - static void OutputDebugInfo(); -#endif - - static CCryNameTSCRC s_sClassName; - -protected: - virtual ~CTexture(); - -public: - //! Dirty flags will indicate what kind of device data was invalidated - enum EDeviceDirtyFlags - { - eDeviceResourceDirty = BIT(0), - eDeviceResourceViewDirty = BIT(1), - }; - -public: - CTexture(const uint32 nFlags) - { - m_nFlags = nFlags; - m_eTFDst = eTF_Unknown; - m_eTFSrc = eTF_Unknown; - m_nMips = 1; - m_nWidth = 0; - m_nHeight = 0; - m_eTT = eTT_2D; - m_nDepth = 1; - m_nArraySize = 1; - m_nActualSize = 0; - m_fAvgBrightness = 1.0f; - m_cMinColor = 0.0f; - m_cMaxColor = 1.0f; - m_cClearColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - m_nPersistentSize = 0; - m_fAvgBrightness = 0.0f; - - m_nUpdateFrameID = -1; - m_nAccessFrameID = -1; - m_nCustomID = -1; - m_pPixelFormat = NULL; - m_pDevTexture = NULL; - m_pDeviceRTV = NULL; - m_pDeviceRTVMS = NULL; - m_pDeviceShaderResource = NULL; - m_pDeviceShaderResourceSRGB = NULL; - - m_bAsyncDevTexCreation = false; - - m_renderTargetUseCount = 0; - m_bNeedRestoring = false; - m_bNoTexture = false; - m_bResolved = true; - m_bUseMultisampledRTV = true; - m_bHighQualityFiltering = false; - m_bCustomFormat = false; - m_eSrcTileMode = eTM_None; - - m_bPostponed = false; - m_bForceStreamHighRes = false; - m_bWasUnloaded = false; - m_bStreamed = false; - m_bStreamPrepared = false; - m_bStreamRequested = false; - m_bVertexTexture = false; - m_bUseDecalBorderCol = false; - m_bIsSRGB = false; - m_bNoDevTexture = false; - m_bInDistanceSortedList = false; - m_bCreatedInLevel = gRenDev->m_bInLevel; - m_bUsedRecently = 0; - m_bStatTracked = 0; - m_bStreamHighPriority = 0; - m_nStreamingPriority = 0; - m_nMinMipVidUploaded = MAX_MIP_LEVELS; - m_nMinMipVidActive = MAX_MIP_LEVELS; - m_nStreamSlot = InvalidStreamSlot; - m_fpMinMipCur = MAX_MIP_LEVELS << 8; - m_nStreamFormatCode = 0; - - m_nDefState = 0; - m_pFileTexMips = NULL; - m_fCurrentMipBias = 0.f; - - m_pRenderTargetData = (nFlags & FT_USAGE_RENDERTARGET) ? new RenderTargetData : NULL; - - COMPILE_TIME_ASSERT(MaxStreamTasks < 32767); - -#if defined(USE_UNIQUE_MUTEX_PER_TEXTURE) - // Only the editor needs to use a unique mutex per texture. - // In the editor, multiple worker threads could destroy device resource sets which point to the same texture - if (gEnv->IsEditor()) - { - m_invalidateCallbacksMutex = new AZStd::mutex(); - } -#endif - // If we do not need a unique mutex per texture, use the StaticInstance - if (m_invalidateCallbacksMutex == nullptr) - { - m_invalidateCallbacksMutex = &m_staticInvalidateCallbacksMutex; - } - } - - - - bool GetIsTextureMissing() const - { - return m_bisTextureMissing; - } - - // ITexture interface - virtual int AddRef() { return CBaseResource::AddRef(); } - virtual int Release() - { - if (!(m_nFlags & FT_DONT_RELEASE) || IsActiveRenderTarget()) - { - return CBaseResource::Release(); - } - - return -1; - } - virtual int ReleaseForce() - { - m_nFlags &= ~FT_DONT_RELEASE; - int nRef = 0; - while (true) - { - nRef = Release(); - if (nRef <= 0) - { - break; - } - } - return nRef; - } - - virtual const char* GetName() const { return GetSourceName(); } - virtual const int GetWidth() const { return m_nWidth; } - ILINE const int GetWidthNonVirtual() const { return m_nWidth; } - virtual const int GetHeight() const { return m_nHeight; } - ILINE const int GetHeightNonVirtual() const { return m_nHeight; } - virtual const int GetDepth() const { return m_nDepth; } - ILINE const int GetDepthNonVirtual() const { return m_nDepth; } - ILINE const int GetNumSides() const { return m_CacheFileHeader.m_nSides; } - ILINE const int8 GetNumPersistentMips() const { return m_CacheFileHeader.m_nMipsPersistent; } - ILINE const bool IsForceStreamHighRes() const { return m_bForceStreamHighRes; } - ILINE const bool IsStreamHighPriority() const { return m_bStreamHighPriority; } - virtual const int GetTextureID() const; - void SetFlags(uint32 nFlags) { m_nFlags = nFlags; } - virtual const uint32 GetFlags() const { return m_nFlags; } - ILINE const int GetNumMipsNonVirtual() const { return m_nMips; } - virtual const int GetNumMips() const { return m_nMips; } - virtual const int GetRequiredMip() const { return max(0, m_fpMinMipCur >> 8); } - ILINE const int GetRequiredMipNonVirtual() const { return max(0, m_fpMinMipCur >> 8); } - ILINE const int GetRequiredMipNonVirtualFP() const { return m_fpMinMipCur; } - virtual const ETEX_Type GetTextureType() const; - virtual void SetTextureType(ETEX_Type type); - - ILINE const int GetDefState() const { return m_nDefState; } - virtual void SetClamp(bool bEnable) - { - int nMode = bEnable ? TADDR_CLAMP : TADDR_WRAP; - SetClampingMode(nMode, nMode, nMode); - UpdateTexStates(); - } - - ILINE const bool IsTextureMissing() const { return m_bisTextureMissing; } - virtual const bool IsTextureLoaded() const { return IsLoaded(); } - virtual void PrecacheAsynchronously(float fMipFactor, int nFlags, int nUpdateId, int nCounter = 1); - virtual byte* GetData32(int nSide = 0, int nLevel = 0, byte* pDst = NULL, ETEX_Format eDstFormat = eTF_R8G8B8A8); - virtual const int GetDeviceDataSize() const { return m_nActualSize; } - virtual const int GetDataSize() const - { - if (IsStreamed()) - { - return StreamComputeDevDataSize(0); - } - return m_nActualSize; - } - virtual bool SetFilter(int nFilter) { return SetFilterMode(nFilter); } - virtual bool Clear(); - virtual bool Clear(const ColorF& color); - virtual float GetAvgBrightness() const { return m_fAvgBrightness; } - virtual void SetAvgBrightness(float fBrightness) { m_fAvgBrightness = fBrightness; } - virtual const ColorF& GetMinColor() const { return m_cMinColor; } - virtual void SetMinColor(const ColorF& cMinColor) { m_cMinColor = cMinColor; } - virtual const ColorF& GetMaxColor() const { return m_cMaxColor; } - virtual void SetMaxColor(const ColorF& cMaxColor) { m_cMaxColor = cMaxColor; } - virtual const ColorF& GetClearColor() const override { return m_cClearColor; } - virtual void SetClearColor(const ColorF& cClearColor) { m_cClearColor = cClearColor; } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const; - virtual const char* GetFormatName() const; - virtual const char* GetTypeName() const; - - virtual const bool IsShared() const - { - return CBaseResource::GetRefCounter() > 1; - } - - virtual const ETEX_Format GetTextureDstFormat() const { return m_eTFDst; } - virtual const ETEX_Format GetTextureSrcFormat() const { return m_eTFSrc; } - - virtual const bool IsParticularMipStreamed(float fMipFactor) const; - - // Internal functions - const ETEX_Format GetDstFormat() const override { return m_eTFDst; } - const ETEX_Format GetSrcFormat() const override { return m_eTFSrc; } - const ETEX_Type GetTexType() const { return m_eTT; } - const uint32 StreamGetNumSlices() const - { - switch (m_eTT) - { - case eTT_2D: - case eTT_2DArray: - return m_nArraySize; - - case eTT_Cube: - return 6 * m_nArraySize; - - default: -#ifndef _RELEASE - __debugbreak(); -#endif - return 1; - } - } - - void RT_ReleaseDevice(); - - static _inline bool IsTextureExist(const ITexture* pTex) { return pTex && pTex->GetDevTexture(); } - - const bool IsNoTexture() const { return m_bNoTexture; }; - void SetNeedRestoring() { m_bNeedRestoring = true; } - void SetWasUnload(bool bSet) { m_bWasUnloaded = bSet; } - const bool IsPartiallyLoaded() const { return m_nMinMipVidUploaded != 0; } - const bool IsUnloaded(void) const { return m_bWasUnloaded; } - void SetKeepSystemCopy(bool bKeepSystemCopy) - { - if (bKeepSystemCopy) - { - m_nFlags |= FT_KEEP_LOWRES_SYSCOPY; - } - else - { - m_nFlags &= ~FT_KEEP_LOWRES_SYSCOPY; - } - } - void SetStreamingInProgress(uint16 nStreamSlot) - { - assert (nStreamSlot == InvalidStreamSlot || m_nStreamSlot == InvalidStreamSlot); - m_nStreamSlot = nStreamSlot; - } - void SetStreamingPriority(const uint8 nPriority) { m_nStreamingPriority = nPriority; } - ILINE const STexStreamRoundInfo& GetStreamRoundInfo(int zone) const { return m_streamRounds[zone]; } - void ResetNeedRestoring() { m_bNeedRestoring = false; } - const bool IsNeedRestoring() const { return m_bNeedRestoring; } - const int StreamGetLoadedMip() const { return m_nMinMipVidUploaded; } - const uint8 StreamGetFormatCode() const { return m_nStreamFormatCode; } - const int StreamGetActiveMip() const { return m_nMinMipVidActive; } - const int StreamGetPriority() const { return m_nStreamingPriority; } - const bool IsResolved() const { return m_bResolved; } - void SetUseMultisampledRTV(bool bSet) { m_bUseMultisampledRTV = bSet; } - const bool UseMultisampledRTV() const { return m_bUseMultisampledRTV; } - const bool IsVertexTexture() const { return m_bVertexTexture; } - void SetVertexTexture(bool bEnable) { m_bVertexTexture = bEnable; } - const bool IsDynamic() const { return ((m_nFlags & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET)) != 0); } - bool IsStillUsedByGPU(); - - // Render targets can be bound for write on the render target stack multiple times at once, - // so increment and decrement when it is pushed/popped from the stack - void IncrementRenderTargetUseCount() - { - assert(m_renderTargetUseCount < (1 << CTEXTURE_RENDER_TARGET_USE_COUNT_NUMBER_BITS)); - m_renderTargetUseCount++; - } - void DecrementRenderTargetUseCount() - { - assert(m_renderTargetUseCount > 0); - m_renderTargetUseCount--; - } - - // Is this texture bound on the render target stack? - const bool IsActiveRenderTarget() const { return m_renderTargetUseCount > 0; } - - const bool IsLoaded() const { return (m_nFlags & FT_FAILED) == 0; } - ILINE const bool IsStreamed() const { return m_bStreamed; } - ILINE const bool IsInDistanceSortedList() const { return m_bInDistanceSortedList; } - bool IsPostponed() const { return m_bPostponed; } - ILINE const bool IsStreaming() const { return m_nStreamSlot != InvalidStreamSlot; } - virtual const bool IsStreamedVirtual() const { return IsStreamed(); } - virtual bool IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const; - virtual const int GetAccessFrameId() const { return m_nAccessFrameID; } - ILINE const int GetAccessFrameIdNonVirtual() const { return m_nAccessFrameID; } - void SetResolved(bool bResolved) { m_bResolved = bResolved; } - const int GetCustomID() const { return m_nCustomID; } - void SetCustomID(int nID) { m_nCustomID = nID; } - const bool UseDecalBorderCol() const { return m_bUseDecalBorderCol; } - const bool IsSRGB() const { return m_bIsSRGB; } - void SRGBRead(bool bEnable = false) { m_bIsSRGB = bEnable; } - const bool IsCustomFormat() const { return m_bCustomFormat; } - void SetCustomFormat() { m_bCustomFormat = true; } - void SetWidth(short width) { m_nWidth = width; } - void SetHeight(short height) { m_nHeight = height; } - int GetUpdateFrameID() const { return m_nUpdateFrameID; } - ILINE const int32 GetActualSize() const { return m_nActualSize; } - ILINE const int32 GetPersistentSize() const { return m_nPersistentSize; } - - ILINE void PrefetchStreamingInfo() const { PrefetchLine(m_pFileTexMips, 0); } - const STexStreamingInfo* GetStreamingInfo() const { return m_pFileTexMips; } - - virtual const bool IsStreamable() const { return IsStreamed(); } - - void Readback(AZ::u32 subresourceIndex, StagingHook callback) override; - - const bool IsStreamableNonVirtual() const { return !(m_nFlags & FT_DONT_STREAM) && !(m_eTT == eTT_3D); } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_5 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif - - bool IsFPFormat() const { return CImageExtensionHelper::IsRangeless(m_eTFDst); }; - - D3DSurface* GetDeviceRT() const { return m_pDeviceRTV; } - - CDeviceTexture* GetDevTexture() const { return m_pDevTexture; } - void SetDevTexture(CDeviceTexture* pDeviceTex); - bool IsAsyncDevTexCreation() const { return m_bAsyncDevTexCreation; } - - // note: render target should be created with FT_FORCE_MIPS flag - bool GenerateMipMaps(bool bSetOrthoProj = false, bool bUseHW = true, bool bNormalMap = false); - - D3DShaderResourceView* GetShaderResourceView(SResourceView::KeyType resourceViewID = SResourceView::DefaultView, bool bLegacySrgbLookup = false); - void SetShaderResourceView(D3DShaderResourceView* pDeviceShaderResource, bool bMultisampled = false); - - CDeviceTexture* GetDevTextureMSAA() const { return m_pRenderTargetData->m_pDeviceTextureMSAA; } - D3DUnorderedAccessView* GetDeviceUAV(); - - SResourceView& GetResourceView(const SResourceView& rvDesc); - void* CreateDeviceResourceView(const SResourceView& rvDesc); - - D3DDepthSurface* GetDeviceDepthStencilSurf(int nFirstSlice = 0, int nSliceCount = -1); -#ifndef NULL_RENDERER - D3DSurface* GetSurface(int nCMSide, int nLevel); -#endif - const SPixFormat* GetPixelFormat() const { return m_pPixelFormat; } - bool Invalidate(int nNewWidth, int nNewHeight, ETEX_Format eTF); - const char* GetSourceName() const { return m_SrcName.c_str(); } - void SetSourceName( const char* srcName) { m_SrcName = srcName; } - const int GetSize(bool bIncludePool) const; - void PostCreate(); - - ////////////////////////////////////////////////////////////////////////// - // Will notify resource's user that some data of the the resource was invalidated. - // dirtyFlags - one or more of the EDeviceDirtyFlags enum bits - void InvalidateDeviceResource(uint32 dirtyFlags); - void AddInvalidateCallback(void* listener, InvalidateCallbackType callback); - void RemoveInvalidateCallbacks(void* listener); - ////////////////////////////////////////////////////////////////////////// - -public: - //=================================================================== - // Streaming support - - // Global streaming constants - static int s_nStreamingMode; - static int s_nStreamingUpdateMode; - static int s_nStreamingThroughput; // in bytes - static float s_nStreamingTotalTime; // in secs - static bool s_bStreamDontKeepSystem; - static bool s_bPrecachePhase; - static bool s_bInLevelPhase; - static bool s_bPrestreamPhase; - static bool s_bStreamingFromHDD; - static int s_nTexturesDataBytesLoaded; - static volatile int s_nTexturesDataBytesUploaded; - static int s_nStatsAllocFails; - static bool s_bOutOfMemoryTotally; - - static volatile size_t s_nStatsStreamPoolInUseMem; // Amount of stream pool currently in use by texture streaming - static volatile size_t s_nStatsStreamPoolBoundMem; // Amount of stream pool currently bound and in use by textures (avail + non avail) - static volatile size_t s_nStatsStreamPoolBoundPersMem; // Amount of stream pool currently bound and in use by persistent texture mem (avail + non avail) - static AZStd::atomic_uint s_nStatsCurManagedNonStreamedTexMem; - static AZStd::atomic_uint s_nStatsCurDynamicTexMem; - static volatile size_t s_nStatsStreamPoolWanted; - static bool s_bStatsComputeStreamPoolWanted; - - struct WantedStat - { - _smart_ptr pTex; - uint32 nWanted; - }; - - static std::vector* s_pStatsTexWantedLists; - static AZStd::set, AZ::StdLegacyAllocator> s_vTexReloadRequests; - static CryCriticalSection s_xTexReloadLock; - - static CTextureStreamPoolMgr* s_pPoolMgr; - - static ITextureStreamer* s_pTextureStreamer; - - static CryCriticalSection s_streamFormatLock; - static SStreamFormatCode s_formatCodes[256]; - static uint32 s_nFormatCodes; - typedef std::map TStreamFormatCodeKeyMap; - static StaticInstance s_formatCodeMap; - - static const int LOW_SPEC_PC; - static const int MEDIUM_SPEC_PC; - static const int HIGH_SPEC_PC; - static const int VERYHIGH_SPEC_PC; - - enum - { - MaxStreamTasks = 512, - MaxStreamPrepTasks = 8192, - StreamOutMask = 0x8000, - StreamPrepMask = 0x4000, - StreamIdxMask = 0x4000 - 1, - InvalidStreamSlot = 0xffff, - }; - - static CTextureArrayAlloc s_StreamInTasks; - static CTextureArrayAlloc s_StreamPrepTasks; - -#ifdef TEXSTRM_ASYNC_TEXCOPY - static CTextureArrayAlloc s_StreamOutTasks; -#endif - - static volatile TIntAtomic s_nBytesSubmittedToStreaming; - static volatile TIntAtomic s_nMipsSubmittedToStreaming; - static int s_nBytesRequiredNotSubmitted; - -#if !defined (_RELEASE) - static int s_TextureUpdates; - static float s_TextureUpdatesTime; - static int s_TexturesUpdatedRendered; - static float s_TextureUpdatedRenderedTime; - static int s_StreamingRequestsCount; - static float s_StreamingRequestsTime; - static int s_nStatsCurManagedStreamedTexMemRequired; -#endif - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - static ITextureStreamListener* s_pStreamListener; -#endif - - static void Precache(); - static void RT_Precache(); - static void StreamValidateTexSize(); - static uint8 StreamComputeFormatCode(uint32 nWidth, uint32 nHeight, uint32 nMips, ETEX_Format fmt); - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - static void StreamUpdateStats(); -#endif - -#if defined(TEXSTRM_STORE_DEVSIZES) - int StreamComputeDevDataSize(int nFromMip) const - { - if (m_pFileTexMips) - { - return m_pFileTexMips->m_pMipHeader[nFromMip].m_DevSideSizeWithMips; - } - else - { - return CDeviceTexture::TextureDataSize( - max(1, m_nWidth >> nFromMip), - max(1, m_nHeight >> nFromMip), - max(1, m_nDepth >> nFromMip), - m_nMips - nFromMip, - StreamGetNumSlices(), - m_eTFDst); - } - } -#else - int StreamComputeDevDataSize(int nFromMip) const - { - return CDeviceTexture::TextureDataSize( - max(1, m_nWidth >> nFromMip), - max(1, m_nHeight >> nFromMip), - max(1, m_nDepth >> nFromMip), - m_nMips - nFromMip, - StreamGetNumSlices(), - m_eTFDst); - } -#endif - -#ifndef NULL_RENDERER - void StreamUploadMip(IReadStream* pStream, int nMip, int nBaseMipOffset, STexPoolItem* pNewPoolItem, STexStreamInMipState& mipState); - void StreamUploadMipSide( - int const iSide, int const Sides, const byte* const pRawData, int nSrcPitch, - const STexMipHeader& mh, bool const bStreamInPlace, - int const nCurMipWidth, int const nCurMipHeight, int const nMip, - CDeviceTexture* pDeviceTexture, uint32 nBaseTexWidth, uint32 nBaseTexHeight, int nBaseMipOffset); -#endif - void StreamExpandMip(const void* pRawData, int nMip, int nBaseMipOffset, int nSideDelta); - static void RT_FlushAllStreamingTasks(const bool bAbort = false); - static bool IsStreamingInProgress() { return s_StreamInTasks.GetNumLive() > 0; } - static void AbortStreamingTasks(CTexture* pTex); - static bool StartStreaming(CTexture* pTex, STexPoolItem* pNewPoolItem, const int nStartMip, const int nEndMip, const int nActivateMip, EStreamTaskPriority estp); - bool CanStreamInPlace(int nMip, STexPoolItem* pNewPoolItem); -#if defined(TEXSTRM_ASYNC_TEXCOPY) - bool CanAsyncCopy(); -#endif - void StreamCopyMipsTexToMem(int nStartMip, int nEndMip, bool bToDevice, STexPoolItem* pNewPoolItem); - static void StreamCopyMipsTexToTex(STexPoolItem* pSrcItem, int nMipSrc, STexPoolItem* pDestItem, int nMipDest, int nNumMips); // GPU-assisted platform-dependent - static void CopySliceChain(CDeviceTexture* const pDevTexture, int ownerMips, int nDstSlice, int nDstMip, CDeviceTexture* pSrcDevTex, int nSrcSlice, int nSrcMip, int nSrcMips, int nNumMips); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_6 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif -#if defined(TEXSTRM_DEFERRED_UPLOAD) - ID3D11CommandList* StreamCreateDeferred(int nStartMip, int nEndMip, STexPoolItem* pNewPoolItem, STexPoolItem* pSrcPoolItem); - void StreamApplyDeferred(ID3D11CommandList* pCmdList); -#endif - void StreamReleaseMipsData(int nStartMip, int nEndMip); - int16 StreamCalculateMipsSignedFP(float fMipFactor) const; - float StreamCalculateMipFactor(int16 nMipsSigned) const; - virtual int StreamCalculateMipsSigned(float fMipFactor) const; - virtual int GetStreamableMipNumber() const; - virtual int GetStreamableMemoryUsage(int nStartMip) const; - virtual int GetMinLoadedMip() const { return m_nMinMipVidUploaded; } - void SetMinLoadedMip(int nMinMip); - void StreamUploadMips(int nStartMip, int nEndMip, STexPoolItem* pNewPoolItem); - int StreamUnload(); - int StreamTrim(int nToMip); - void StreamActivateLod(int nMinMip); - void StreamLoadFromCache(const int nFlags); - bool StreamPrepare(bool bFromLoad); - bool StreamPrepare(CImageFile* pImage); - bool StreamPrepareComposition(); - bool StreamPrepare_Platform(); - bool StreamPrepare_Finalise(bool bFromLoad); - STexPool* StreamGetPool(int nStartMip, int nMips); - STexPoolItem* StreamGetPoolItem(int nStartMip, int nMips, bool bShouldBeCreated, bool bCreateFromMipData = false, bool bCanCreate = true, bool bForStreamOut = false); - void StreamRemoveFromPool(); - void StreamAssignPoolItem(STexPoolItem* pItem, int nMinMip); - - static void StreamState_Update(); - static void StreamState_UpdatePrep(); - - static STexStreamInState* StreamState_AllocateIn(); - static void StreamState_ReleaseIn(STexStreamInState* pState); -#ifdef TEXSTRM_ASYNC_TEXCOPY - static STexStreamOutState* StreamState_AllocateOut(); - static void StreamState_ReleaseOut(STexStreamOutState* pState); -#endif - static STexStreamingInfo* StreamState_AllocateInfo(int nMips); - static void StreamState_ReleaseInfo(CTexture* pOwnerTex, STexStreamingInfo* pInfo); - - ILINE void Relink() - { - gRenDev->m_pRT->RC_RelinkTexture(this); - } - - ILINE void Unlink() - { - gRenDev->m_pRT->RC_UnlinkTexture(this); - } - - _inline void RT_Relink() - { - if (!IsStreamed() || IsInDistanceSortedList()) - { - return; - } - - s_pTextureStreamer->Relink(this); - } - _inline void RT_Unlink() - { - if (IsInDistanceSortedList()) - { - s_pTextureStreamer->Unlink(this); - } - } - //======================================================= - - static void ApplyForID(int nTUnit, int nID, int nState, int nSUnit) - { - CTexture* pTex = GetByID(nID); - assert (pTex); - if (pTex) - { - pTex->Apply(nTUnit, nState, EFTT_UNKNOWN, nSUnit); - } - } - - static void ApplyForID(int nID, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit, bool useWhiteDefault); - - static const CCryNameTSCRC& mfGetClassName(); - static CTexture* GetByID(int nID); - static CTexture* GetByName(const char* szName, uint32 flags = 0); - static CTexture* GetByNameCRC(CCryNameTSCRC Name); - static CTexture* ForName(const char* name, uint32 nFlags, ETEX_Format eTFDst); - static CTexture* CreateTextureArray(const char* name, ETEX_Type eType, uint32 nWidth, uint32 nHeight, uint32 nArraySize, int nMips, uint32 nFlags, ETEX_Format eTF, int nCustomID = -1); - static CTexture* CreateTextureObject(const char* name, uint32 nWidth, uint32 nHeight, int nDepth, ETEX_Type eTT, uint32 nFlags, ETEX_Format eTF, int nCustomID = -1); - - // Methods exposed to external libraries - static CTexture* CreateRenderTarget(const char* name, uint32 nWidth, uint32 nHeight, const ColorF& cClear, ETEX_Type eTT, uint32 nFlags, ETEX_Format eTF, int nCustomID = -1); - static void ApplyDepthTextureState(int unit, int nFilter, bool clamp); - static CTexture* GetZTargetTexture(); - static int GetTextureState(const STexState& TS); - static uint32 TextureDataSize(uint32 nWidth, uint32 nHeight, uint32 nDepth, uint32 nMips, uint32 nSlices, const ETEX_Format eTF, ETEX_TileMode eTM = eTM_None); - - static void InitStreaming(); - static void InitStreamingDev(); - static void Init(); - static void PostInit(); - static void RT_FlushStreaming(bool bAbort); - static void ShutDown(); - - static void CreateSystemTargets(); - static void ReleaseSystemTargets(); - static void ReleaseMiscTargets(); - static void ReleaseSystemTextures(); - static void LoadDefaultSystemTextures(); - - static bool ReloadFile(const char* szFileName); - static bool ReloadFile_Request(const char* szFileName); - static void ReloadTextures(); - static CTexture* Create2DTexture(const char* szName, int nWidth, int nHeight, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst, bool bAsyncDevTexCreation = false); - static CTexture* Create3DTexture(const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst); - static CTexture* Create2DCompositeTexture(const char* szName, int nWidth, int nHeight, int nMips, int nFlags, ETEX_Format eTFDst, const STexComposition* pCompositions, size_t nCompositions); - static void Update(); - static void RT_LoadingUpdate(); - static void RLT_LoadingUpdate(); - - // Loading/creating functions - bool Load(ETEX_Format eTFDst); - bool Load(CImageFile* pImage); - bool LoadFromImage(const char* name, ETEX_Format eTFDst = eTF_Unknown); - virtual bool Reload(); - bool ToggleStreaming(const bool bEnable); - bool CreateTexture(STexData& td); - - byte* GetSubImageData32(int nX, int nY, int nW, int nH, int& nOutTexDim); - - // API depended functions - void Unbind(); - bool Resolve(int nTarget = 0, bool bUseViewportSize = false); - bool CreateDeviceTexture(const byte* pData[6]); - bool RT_CreateDeviceTexture(const byte* pData[6]); - bool CreateRenderTarget(ETEX_Format eTF, const ColorF& cClear); - void ReleaseDeviceTexture(bool bKeepLastMips, bool bFromUnload = false); - void ApplySamplerState(int nSUnit, EHWShaderClass eHWSC = eHWSC_Pixel, int nState = -1); - void ApplyTexture(int nTUnit, EHWShaderClass eHWSC = eHWSC_Pixel, SResourceView::KeyType nResViewKey = SResourceView::DefaultView); - ETEX_Format ClosestFormatSupported(ETEX_Format eTFDst); - static ETEX_Format ClosestFormatSupported(ETEX_Format eTFDst, const SPixFormat*& pPF); - void SetTexStates(); - void UpdateTexStates(); - bool SetFilterMode(int nFilter); - bool SetClampingMode(int nAddressU, int nAddressV, int nAddressW); - void UpdateTextureRegion(const uint8_t* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc); - void RT_UpdateTextureRegion(const byte* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc); - - // Create2DTextureWithMips is similar to Create2DTexture, but it also propagates the mip argument correctly. - // The original Create2DTexture function force sets mips to 1. - // This has been separated from Create2DTexture to ensure that we preserve backwards compatibility. - bool Create2DTextureWithMips(int nWidth, int nHeight, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst); - - bool Create2DTexture(int nWidth, int nHeight, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst); - bool Create3DTexture(int nWidth, int nHeight, int nDepth, int nMips, int nFlags, const byte* pData, ETEX_Format eTFSrc, ETEX_Format eTFDst); - bool SetNoTexture( const CTexture* pDefaultTexture ); - bool IsMSAAChanged(); - - static byte* Convert(const byte* srcData, int width, int height, int srcMipCount, ETEX_Format srcFormat, ETEX_Format dstFormat, int& outSize, bool bLinear); - - static void SetSamplerState(int nTS, int nSSlot, EHWShaderClass eHWSC = eHWSC_Pixel); - - // Helper functions - static bool IsFormatSupported(ETEX_Format eTFDst); - static void GenerateZMaps(); - static void DestroyZMaps(); - static void GenerateHDRMaps(); - // allocate or deallocate star maps - static void DestroyHDRMaps(); - - static void GenerateSceneMap(ETEX_Format eTF); - static void DestroySceneMap(); - static void GenerateCachedShadowMaps(); - static void DestroyCachedShadowMaps(); - static void GenerateNearestShadowMap(); - static void DestroyNearestShadowMap(); - - static ILINE Vec2i GetBlockDim(const ETEX_Format eTF) - { - return CImageExtensionHelper::GetBlockDim(eTF); - } - - static int CalcNumMips(int nWidth, int nHeight); - // upload mip data from file regarding to platform specifics - static bool IsInPlaceFormat(const ETEX_Format fmt); - static void ExpandMipFromFile(byte* dest, const int destSize, const byte* src, const int srcSize, const ETEX_Format fmt); - - static ILINE bool IsBlockCompressed(const ETEX_Format eTF) { return CImageExtensionHelper::IsBlockCompressed(eTF); } - static ILINE int BytesPerBlock(ETEX_Format eTF) { return CImageExtensionHelper::BytesPerBlock(eTF); } - static const char* NameForTextureFormat(ETEX_Format eTF) { return CImageExtensionHelper::NameForTextureFormat(eTF); } - static const char* NameForTextureType(ETEX_Type eTT) { return CImageExtensionHelper::NameForTextureType(eTT); } - static ETEX_Format TextureFormatForName(const char* str) { return CImageExtensionHelper::TextureFormatForName(str); } - static ETEX_Type TextureTypeForName(const char* str) { return CImageExtensionHelper::TextureTypeForName(str); } - static bool IsDeviceFormatTypeless(D3DFormat nFormat); - static bool IsDeviceFormatSRGBReadable(D3DFormat nFormat); - static D3DFormat DeviceFormatFromTexFormat(ETEX_Format eTF); - static ETEX_Format TexFormatFromDeviceFormat(D3DFormat nFormat); - static D3DFormat GetD3DLinFormat(D3DFormat nFormat); - static D3DFormat ConvertToDepthStencilFmt(D3DFormat nFormat); - static D3DFormat ConvertToStencilFmt(D3DFormat nFormat); - static D3DFormat ConvertToShaderResourceFmt(D3DFormat nFormat); - - static D3DFormat ConvertToSRGBFmt(D3DFormat fmt); - static D3DFormat ConvertToSignedFmt(D3DFormat fmt); - static D3DFormat ConvertToTypelessFmt(D3DFormat fmt); - - static SEnvTexture* FindSuitableEnvTex(Vec3& Pos, Ang3& Angs, bool bMustExist, int RendFlags, bool bUseExistingREs, CShader* pSH, CShaderResources* pRes, CRenderObject* pObj, bool bReflect, IRenderElement* pRE, bool* bMustUpdate); - static bool RenderEnvironmentCMHDR(int size, Vec3& Pos, TArray& vecData); - - static void DrawCubeSide(Vec3& Pos, int tex_size, int side, float fMaxDist); - static void DrawSceneToCubeSide(Vec3& Pos, int tex_size, int side); - static void GetAverageColor(SEnvTexture* cm, int nSide); - -public: - - static AZStd::vector s_TexStates; - static int GetTexState(const STexState& TS) - { - uint32 i; - - const uint32 nTexStatesSize = s_TexStates.size(); - for (i = 0; i < nTexStatesSize; i++) - { - STexState* pTS = &s_TexStates[i]; - if (*pTS == TS) - { - break; - } - } - - if (i == nTexStatesSize) - { - - s_TexStates.push_back(TS); - s_TexStates[i].PostCreate(); - } - - return i; - } - - static void ComputeRootedTexturePath(const char* sourcePath, char* destPath, size_t destPathLength); - - static bool m_bLoadedSystem; - - static STexState s_sDefState; - static STexStageInfo s_TexStages[MAX_TMU]; - static uint32 s_TexState_MipSRGBMask[MAX_TMU]; - - static ETEX_Format s_eTFZ; - - // ============================================================================== - static CTexture* s_ptexMipColors_Diffuse; - static CTexture* s_ptexMipColors_Bump; - static CTexture* s_ptexFromRE[8]; - static CTexture* s_ptexShadowID[8]; - static CTexture* s_ptexShadowMask; - static CTexture* s_ptexFromRE_FromContainer[2]; - static CTexture* s_ptexFromObj; - static CTexture* s_ptexSvoTree; - static CTexture* s_ptexSvoTris; - static CTexture* s_ptexSvoGlobalCM; - static CTexture* s_ptexSvoRgbs; - static CTexture* s_ptexSvoNorm; - static CTexture* s_ptexSvoOpac; - static CTexture* s_ptexFromObjCM; - static CTexture* s_ptexRT_2D; - static CTexture* s_ptexCachedShadowMap[MAX_GSM_LODS_NUM]; - static CTexture* s_ptexNearestShadowMap; - static CTexture* s_ptexHeightMapAO[2]; - static CTexture* s_ptexHeightMapAODepth[2]; - - static CTexture* s_ptexSceneNormalsMap; // RT with normals for deferred shading - static CTexture* s_ptexSceneNormalsMapMS; // Dummy normals target for binding multisampled rt - static CTexture* s_ptexSceneNormalsBent; - static CTexture* s_ptexAOColorBleed; - static CTexture* s_ptexSceneDiffuse; - static CTexture* s_ptexSceneSpecular; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURE_H_SECTION_7 - #include AZ_RESTRICTED_FILE(Texture_h) -#endif - static CTexture* s_ptexAmbientLookup; - - static CTexture* s_ptexBackBuffer; // back buffer copy - static CTexture* s_ptexModelHudBuffer; // used by Menu3DModelRenderer to postprocess render models - static CTexture* s_ptexPrevBackBuffer[2][2]; // previous frame back buffer copies (for left and right eye) - static CTexture* s_ptexCached3DHud; // 3d hud cached overframes - static CTexture* s_ptexCached3DHudScaled; // downsampled 3d hud cached overframes - static CTexture* s_ptexBackBufferScaled[3]; // backbuffer low-resolution/blurred version. 2x/4x/8x/16x smaller than screen - static CTexture* s_ptexBackBufferScaledTemp[2]; // backbuffer low-resolution/blurred version. 2x/4x/8x/16x smaller than screen, temp textures (used for blurring/ping-pong) - - static CTexture* s_ptexPrevFrameScaled; // 2x - - static CTexture* s_ptexDepthBufferQuarter; //Quater res depth buffer - - static CTexture* s_ptexWaterOcean; // water ocean vertex texture - static CTexture* s_ptexWaterVolumeDDN; // water volume heightmap - static CTexture* s_ptexWaterVolumeTemp; // water volume heightmap - static CTexture* s_ptexWaterRipplesDDN; // xy: wave propagation normals, z: frame t-2, w: frame t-1 - static CTexture* s_ptexWaterVolumeRefl[2]; // water volume reflections buffer - static CTexture* s_ptexWaterCaustics[2]; // caustics buffers - static CTexture* s_ptexRainOcclusion; // top-down rain occlusion - static CTexture* s_ptexRainSSOcclusion[2]; // screen-space rain occlusion accumulation - - static CTexture* s_ptexRainDropsRT[2]; - - static CTexture* s_ptexRT_ShadowPool; - static CTexture* s_ptexRT_ShadowStub; - static CTexture* s_ptexCloudsLM; - - static CTexture* s_ptexSceneTarget; // Shared rt for generic usage (refraction/srgb/diffuse accumulation/hdr motionblur/etc) - static CTexture* s_ptexCurrSceneTarget; // Pointer to current scene target, mostly for reading from destination rt - static CTexture* s_ptexSceneTargetR11G11B10F[2]; - static CTexture* s_ptexSceneTargetScaledR11G11B10F[4]; - - static CTexture* s_ptexSceneCoCHistory[2]; - - static CTexture* s_ptexCurrentSceneDiffuseAccMap; - static CTexture* s_ptexSceneDiffuseAccMap; - static CTexture* s_ptexSceneSpecularAccMap; - static CTexture* s_ptexSceneTexturesMap; - static CTexture* s_ptexSceneDiffuseAccMapMS; - static CTexture* s_ptexSceneSpecularAccMapMS; - - static CTexture* s_ptexZTarget; - - static CTexture* s_ptexZTargetDownSample[4]; - static CTexture* s_ptexZTargetScaled; - static CTexture* s_ptexZTargetScaled2; - - static CTexture* s_ptexHDRTarget; - static CTexture* s_ptexVelocityObjects[2]; // Dynamic object velocity (for left and right eye) - static CTexture* s_ptexVelocity; - static CTexture* s_ptexVelocityTiles[3]; - - // Intermediate textures used for fur rendering - static CTexture* s_ptexFurZTarget; // Z target with outermost shell stipples. s_ptexZTarget has the stipples blurred out - static CTexture* s_ptexFurLightAcc; // Lighting accumulation after deferred shading - static CTexture* s_ptexFurPrepass; // Packed diffuse, specular, and depth for shell passes - - // Confetti Begin: David Srour - // Dedicated stencil & linear depth buffer for GMEM render path. - static CTexture* s_ptexGmemStenLinDepth; - // Confetti End - - static CTexture* s_ptexHDRTargetPrev; - static CTexture* s_ptexHDRTargetScaled[4]; - static CTexture* s_ptexHDRTargetScaledTmp[4]; - static CTexture* s_ptexHDRTargetScaledTempRT[4]; - static CTexture* s_ptexHDRDofLayers[2]; - static CTexture* s_ptexSceneCoC[MIN_DOF_COC_K]; - static CTexture* s_ptexSceneCoCTemp; - static CTexture* s_ptexHDRTempBloom[2]; - static CTexture* s_ptexHDRFinalBloom; - static CTexture* s_ptexHDRAdaptedLuminanceCur[8]; - static int s_nCurLumTextureIndex; - static CTexture* s_ptexCurLumTexture; - static CTexture* s_ptexHDRToneMaps[NUM_HDR_TONEMAP_TEXTURES]; - static CTexture* s_ptexHDRMeasuredLuminance[MAX_GPU_NUM]; - static CTexture* s_ptexHDRMeasuredLuminanceDummy; - static CTexture* s_ptexSkyDomeMie; - static CTexture* s_ptexSkyDomeRayleigh; - static CTexture* s_ptexSkyDomeMoon; - - static CTexture* s_ptexSceneTargetScaled; - static CTexture* s_ptexSceneTargetScaledBlurred; - - static CTexture* s_ptexVolObj_Density; - static CTexture* s_ptexVolObj_Shadow; - - static CTexture* s_ptexColorChart; - - static CTexture* s_ptexStereoL; - static CTexture* s_ptexStereoR; - - static CTexture* s_ptexFlaresOcclusionRing[MAX_OCCLUSION_READBACK_TEXTURES]; - static CTexture* s_ptexFlaresGather; - - static CTexture* s_ptexDepthStencilRemapped; - static SEnvTexture s_EnvCMaps[MAX_ENVCUBEMAPS]; - static SEnvTexture s_EnvTexts[MAX_ENVTEXTURES]; - static StaticInstance> s_CustomRT_2D; - static StaticInstance> s_ShaderTemplates; // [Shader System TO DO] bad design - change (or shoot) - static bool s_ShaderTemplatesInitialized; - - static CTexture* s_pTexNULL; - - static CTexture* s_pBackBuffer; - static CTexture* s_FrontBufferTextures[2]; - - static CTexture* s_ptexVolumetricFog; - static CTexture* s_ptexVolumetricFogDensityColor; - static CTexture* s_ptexVolumetricFogDensity; - static CTexture* s_ptexVolumetricClipVolumeStencil; - -#if defined(VOLUMETRIC_FOG_SHADOWS) - static CTexture* s_ptexVolFogShadowBuf[2]; -#endif - -#if defined(TEXSTRM_DEFERRED_UPLOAD) - static ID3D11DeviceContext* s_pStreamDeferredCtx; -#endif - - static CTexture* s_defaultEnvironmentProbeDummy; - void* operator new(size_t sz) - { - return CryModuleMemalign(sz, std::alignment_of::value); - } - - void operator delete(void* ptr) - { - CryModuleMemalignFree(ptr); - } -} _ALIGN(128); - -//////////////////////////////////////////////////////////////// - -class CTexAnim : public ITexAnim -{ - friend class CShaderMan; - friend struct SCGTexture; - friend struct STexSamplerRT; - -public: - CTexAnim(); - ~CTexAnim(); - - AZ_DISABLE_COPY_MOVE(CTexAnim) - - void Release() override; - void AddRef() override; - - int Size() const; - -private: - int m_nRefCount; - TArray m_TexPics; - int m_Rand; - int m_NumAnimTexs; - bool m_bLoop; - float m_Time; -}; - - - -bool WriteTGA(const byte* dat, int wdt, int hgt, const char* name, int src_bits_per_pixel, int dest_bits_per_pixel); -bool WriteJPG(const byte* dat, int wdt, int hgt, const char* name, int bpp, int nQuality = 100); -#if defined(WIN32) || defined(WIN64) -byte* WriteDDS(const byte* dat, int wdt, int hgt, int dpth, const char* name, ETEX_Format eTF, int nMips, ETEX_Type eTT, bool bToMemory = false, int* nSize = NULL); -#endif diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureArrayAlloc.h b/Code/CryEngine/RenderDll/Common/Textures/TextureArrayAlloc.h deleted file mode 100644 index 040b559244..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureArrayAlloc.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREARRAYALLOC_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREARRAYALLOC_H -#pragma once - - -template -struct CTextureArrayAllocHlp -{ - typedef size_t T; -}; -template <> -struct CTextureArrayAllocHlp -{ - typedef uint8 T; -}; -template <> -struct CTextureArrayAllocHlp -{ - typedef uint16 T; -}; - -template -class CTextureArrayAlloc -{ -public: - typedef typename CTextureArrayAllocHlp < Capacity < 256, Capacity < 65536>::T TId; - -public: - CTextureArrayAlloc() - { - for (TId i = 0; i < Capacity; ++i) - { - m_freeIDs[i] = i; - } - m_numFree = Capacity; - std::make_heap(m_freeIDs, m_freeIDs + Capacity, HeapComp()); - } - - T* Allocate() - { - if (m_numFree > 0) - { - TId idx = m_freeIDs[0]; - std::pop_heap(m_freeIDs, m_freeIDs + m_numFree, HeapComp()); - --m_numFree; - return &m_arr[idx]; - } - return NULL; - } - - void Release(T* p) - { - TId idx = static_cast(std::distance(m_arr, p)); - m_freeIDs[m_numFree++] = idx; - std::push_heap(m_freeIDs, m_freeIDs + m_numFree, HeapComp()); - } - - T* GetArray() { return m_arr; } - const T* GetArray() const { return m_arr; } - - T* GetPtrFromIdx(TId idx) { return &m_arr[idx]; } - TId GetIdxFromPtr(T* p) { return static_cast(p - &m_arr[0]); } - - TId GetNumLive() const { return Capacity - m_numFree; } - TId GetNumFree() const { return m_numFree; } - -private: - struct HeapComp - { - bool operator () (TId a, TId b) const - { - return b < a; - } - }; - -private: - T m_arr[Capacity]; - TId m_freeIDs[Capacity]; - TId m_numFree; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREARRAYALLOC_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.cpp b/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.cpp deleted file mode 100644 index f5e9e120ad..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "TextureHelpers.h" -#include "TextureManager.h" -#include "StringUtils.h" - -/* ----------------------------------------------------------------------- - * These functions are used in Cry3DEngine, CrySystem, CryRenderD3D11, - * Editor, ResourceCompilerMaterial and more - */ - -////////////////////////////////////////////////////////////////////////// -namespace TextureHelpers -{ - // [Shader System TO DO] - to support data driven the following must support texture handling differently - bool VerifyTexSuffix(EEfResTextures texSlot, const char* texPath) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.suffix && (strlen(texPath) > strlen(texSemantic.suffix) && (CryStringUtils::stristr(texPath, texSemantic.suffix))); - } - - bool VerifyTexSuffix(EEfResTextures texSlot, const string& texPath) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.suffix && (texPath.size() > strlen(texSemantic.suffix) && (CryStringUtils::stristr(texPath, texSemantic.suffix))); - } - - const char* LookupTexSuffix(EEfResTextures texSlot) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.suffix; - } - - int8 LookupTexPriority(EEfResTextures texSlot) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.priority; - } - - CTexture* LookupTexDefault(EEfResTextures texSlot) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.def; - } - - // [Shader System] - To do: replace as part of data driven texture slots - CTexture* LookupTexNeutral(EEfResTextures texSlot) - { - MaterialTextureSemantic& texSemantic = CTextureManager::Instance()->GetTextureSemantic(texSlot); - return texSemantic.neutral; - } -} diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.h b/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.h deleted file mode 100644 index 63d61dbd75..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureHelpers.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __TextureHelpers_h__ -#define __TextureHelpers_h__ -#pragma once - -#include "Texture.h" - -namespace TextureHelpers -{ - ////////////////////////////////////////////////////////////////////////// - bool VerifyTexSuffix(EEfResTextures texSlot, const char* texPath); - bool VerifyTexSuffix(EEfResTextures texSlot, const string& texPath); - const char* LookupTexSuffix(EEfResTextures texSlot); - int8 LookupTexPriority(EEfResTextures texSlot); - CTexture* LookupTexDefault(EEfResTextures texSlot); - CTexture* LookupTexNeutral(EEfResTextures texSlot); -} - -#endif - diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureManager.cpp b/Code/CryEngine/RenderDll/Common/Textures/TextureManager.cpp deleted file mode 100644 index 8af1faade7..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureManager.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "RenderDll_precompiled.h" - -#include "TextureManager.h" -#include "Texture.h" -#include "ISystem.h" -#include -#include -#include - - -////////////////////////////////////////////////////////////////////////// -CTextureManager* CTextureManager::s_Instance = nullptr; -//------------------------------------------------------------------------------ -void CTextureManager::ReleaseTextureSemantics() -{ - for (int slot = 0; slot < EFTT_MAX; slot++) - { - delete[] m_TexSlotSemantics[slot].suffix; - m_TexSlotSemantics[slot].suffix = nullptr; - m_TexSlotSemantics[slot].def = nullptr; - m_TexSlotSemantics[slot].neutral = nullptr; - } -} - -void CTextureManager::ReleaseTextures() -{ - AZ_Warning("[Shaders System]", false, "Textures Manager - releasing all textures"); - - // Remove fixed default textures - for (auto& iter : m_DefaultTextures) - { - SAFE_RELEASE(iter.second); - } - m_DefaultTextures.clear(); - - // Remove fixed engine textures - for (auto& iter : m_EngineTextures) - { - SAFE_RELEASE(iter.second); - } - m_EngineTextures.clear(); - - // Remove references to static engine textures - m_StaticEngineTextureReferences.clear(); - - // Material textures should be released by releasing the materials themselves. - m_MaterialTextures.clear(); -} - -//------------------------------------------------------------------------------ -// [Shaders System] -// The following method should be enhanced to load the user defined default textures -// from an XML file data 'defaultTextures.xml' -// Sample code for the load is provided below to be followed in the future. -//------------------------------------------------------------------------------ -void CTextureManager::LoadDefaultTextures() -{ - struct TextureEntry - { - const char* szTextureName; - const char* szFileName; - uint32 flags; - }; - - // The following texture names are the name by which the texture pointers will - // be indexed. Notice that they match to the previously stored textures with - // name pattern removing 's_ptex'[Name]. Example: 's_ptexWhite' will now be 'White' - const TextureEntry texturesFromFile[] = - { - {"NoTextureCM", "EngineAssets/TextureMsg/ReplaceMeCM.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"White", "EngineAssets/Textures/White.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"Gray", "EngineAssets/Textures/Grey.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"Black", "EngineAssets/Textures/Black.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"BlackAlpha", "EngineAssets/Textures/BlackAlpha.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"BlackCM", "EngineAssets/Textures/BlackCM.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"DefaultProbeCM", "EngineAssets/Shading/defaultProbe_cm.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"FlatBump", "EngineAssets/Textures/White_ddn.dds", FT_DONT_RELEASE | FT_DONT_STREAM | FT_TEX_NORMAL_MAP }, - {"PaletteDebug", "EngineAssets/Textures/palletteInst.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"PaletteTexelsPerMeter", "EngineAssets/Textures/TexelsPerMeterGrad.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconShaderCompiling", "EngineAssets/Icons/ShaderCompiling.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconStreaming", "EngineAssets/Icons/Streaming.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconStreamingTerrainTexture", "EngineAssets/Icons/StreamingTerrain.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconNullSoundSystem", "EngineAssets/Icons/NullSoundSystem.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconNavigationProcessing", "EngineAssets/Icons/NavigationProcessing.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ShadowJitterMap", "EngineAssets/Textures/rotrandom.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"EnvironmentBRDF", "EngineAssets/Shading/environmentBRDF.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ScreenNoiseMap", "EngineAssets/Textures/JumpNoiseHighFrequency_x27y19.dds", FT_DONT_RELEASE | FT_DONT_STREAM | FT_NOMIPS }, - {"DissolveNoiseMap", "EngineAssets/Textures/noise.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"GrainFilterMap", "EngineAssets/ScreenSpace/grain_bayer_mul.dds", FT_DONT_RELEASE | FT_DONT_STREAM | FT_NOMIPS }, - {"FilmGrainMap", "EngineAssets/ScreenSpace/film_grain.dds", FT_DONT_RELEASE | FT_DONT_STREAM | FT_NOMIPS }, - {"VignettingMap", "EngineAssets/Shading/vignetting.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"AOJitter", "EngineAssets/ScreenSpace/PointsOnSphere4x4.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"AOVOJitter", "EngineAssets/ScreenSpace/PointsOnSphereVO4x4.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"NormalsFitting", "EngineAssets/ScreenSpace/NormalsFitting.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"AverageMemoryUsage", "EngineAssets/Icons/AverageMemoryUsage.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"LowMemoryUsage", "EngineAssets/Icons/LowMemoryUsage.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"HighMemoryUsage", "EngineAssets/Icons/HighMemoryUsage.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"LivePreview", "EngineAssets/Icons/LivePreview.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, -#if !defined(_RELEASE) - {"NoTexture", "EngineAssets/TextureMsg/ReplaceMe.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconTextureCompiling", "EngineAssets/TextureMsg/TextureCompiling.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconTextureCompiling_a", "EngineAssets/TextureMsg/TextureCompiling_a.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconTextureCompiling_cm", "EngineAssets/TextureMsg/TextureCompiling_cm.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconTextureCompiling_ddn", "EngineAssets/TextureMsg/TextureCompiling_ddn.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"IconTextureCompiling_ddna", "EngineAssets/TextureMsg/TextureCompiling_ddna.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"DefaultMergedDetail", "EngineAssets/Textures/GreyAlpha.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"MipMapDebug", "EngineAssets/TextureMsg/MipMapDebug.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorBlue", "EngineAssets/TextureMsg/color_Blue.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorCyan", "EngineAssets/TextureMsg/color_Cyan.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorGreen", "EngineAssets/TextureMsg/color_Green.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorPurple", "EngineAssets/TextureMsg/color_Purple.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorRed", "EngineAssets/TextureMsg/color_Red.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorWhite", "EngineAssets/TextureMsg/color_White.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorYellow", "EngineAssets/TextureMsg/color_Yellow.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorOrange", "EngineAssets/TextureMsg/color_Orange.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, - {"ColorMagenta", "EngineAssets/TextureMsg/color_Magenta.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, -#else - {"NoTexture", "EngineAssets/TextureMsg/ReplaceMeRelease.dds", FT_DONT_RELEASE | FT_DONT_STREAM }, -#endif - }; - - for (const TextureEntry& entry : texturesFromFile) - { - CTexture* pNewTexture = CTexture::ForName(entry.szFileName, entry.flags, eTF_Unknown); - if (pNewTexture) - { - CCryNameTSCRC texEntry(entry.szTextureName); - m_DefaultTextures[texEntry] = pNewTexture; - } - else - { - AZ_Assert(false, "Error - CTextureManager failed to load default texture %s", entry.szFileName); - AZ_Warning("[Shaders System]", false, "Error - CTextureManager failed to load default texture %s", entry.szFileName); - } - } - - m_texNoTexture = GetDefaultTexture("NoTexture"); - m_texNoTextureCM = GetDefaultTexture("NoTextureCM"); - m_texWhite = GetDefaultTexture("White"); - m_texBlack = GetDefaultTexture("Black"); - m_texBlackCM = GetDefaultTexture("BlackCM"); -} - -void CTextureManager::LoadMaterialTexturesSemantics() -{ - // Shaders System] - To Do - replace the following with the actual pointers - CTexture* pNoTexture = CTextureManager::Instance()->GetNoTexture(); - CTexture* pWhiteTexture = CTextureManager::Instance()->GetWhiteTexture(); - CTexture* pGrayTexture = CTextureManager::Instance()->GetDefaultTexture("Gray"); - CTexture* pFlatBumpTexture = CTextureManager::Instance()->GetDefaultTexture("FlatBump"); - - // [Shaders System] - this needs to move to shader code and be reflected, hence data driven per - // texture usage / declaration in the shader. - MaterialTextureSemantic texSlotSemantics[] = - { - // NOTE: must be in order with filled holes to allow direct lookup - MaterialTextureSemantic( EFTT_DIFFUSE, 4, pNoTexture, pWhiteTexture, "_diff" ), - MaterialTextureSemantic( EFTT_NORMALS, 2, pFlatBumpTexture, pFlatBumpTexture, "_ddn" ), - MaterialTextureSemantic( EFTT_SPECULAR, 1, pWhiteTexture, pWhiteTexture, "_spec" ), - MaterialTextureSemantic( EFTT_ENV, 0, pWhiteTexture, pWhiteTexture, "_cm" ), - MaterialTextureSemantic( EFTT_DETAIL_OVERLAY, 3, pGrayTexture, pWhiteTexture, "_detail" ), - MaterialTextureSemantic( EFTT_SECOND_SMOOTHNESS, 2, pWhiteTexture, pWhiteTexture, "" ), - MaterialTextureSemantic( EFTT_HEIGHT, 2, pWhiteTexture, pWhiteTexture, "_displ" ), - MaterialTextureSemantic( EFTT_DECAL_OVERLAY, 3, pGrayTexture, pWhiteTexture, "" ), - MaterialTextureSemantic( EFTT_SUBSURFACE, 3, pWhiteTexture, pWhiteTexture, "_sss" ), - MaterialTextureSemantic( EFTT_CUSTOM, 4, pWhiteTexture, pWhiteTexture, "" ), - MaterialTextureSemantic( EFTT_CUSTOM_SECONDARY, 2, pFlatBumpTexture, pFlatBumpTexture, "" ), - MaterialTextureSemantic( EFTT_OPACITY, 4, pWhiteTexture, pWhiteTexture, "" ), - MaterialTextureSemantic( EFTT_SMOOTHNESS, 2, pWhiteTexture, pWhiteTexture, "_ddna" ), - MaterialTextureSemantic( EFTT_EMITTANCE, 1, pWhiteTexture, pWhiteTexture, "_em" ), - MaterialTextureSemantic( EFTT_OCCLUSION, 4, pWhiteTexture, pWhiteTexture, "" ), - MaterialTextureSemantic( EFTT_SPECULAR_2, 4, pWhiteTexture, pWhiteTexture, "_spec" ), - - // This is the terminator for the name-search - MaterialTextureSemantic( EFTT_UNKNOWN, 0, CTexture::s_pTexNULL, CTexture::s_pTexNULL, "" ), - }; - - for (int i = 0; i < EFTT_MAX; i++) - { - SAFE_DELETE_ARRAY(m_TexSlotSemantics[i].suffix); // make sure we are not leaving snail marks - m_TexSlotSemantics[i] = texSlotSemantics[i]; - } -} - -void CTextureManager::CreateStaticEngineTextureReferences() -{ - struct textureReferenceEntry { - const char* textureName; - CTexture** staticTextureReference; - }; - - textureReferenceEntry staticTextureReferences[] = - { - { "$HDRTarget", &CTexture::s_ptexHDRTarget }, - { "$HDRTargetPrev", &CTexture::s_ptexHDRTargetPrev }, - // alias for shaders that use $HDR_TargetPrev see ShaderTemplate.cpp - { "$HDR_TargetPrev", &CTexture::s_ptexHDRTargetPrev }, - { "$SceneTarget", &CTexture::s_ptexSceneTarget }, - { "$CurrSceneTarget", &CTexture::s_ptexCurrSceneTarget }, - { "$SceneNormalsMapMS", &CTexture::s_ptexSceneNormalsMapMS}, - { "$SceneDiffuseAccMS", &CTexture::s_ptexSceneDiffuseAccMapMS }, - { "$SceneSpecularAccMS", &CTexture::s_ptexSceneSpecularAccMapMS }, - { "$SceneTargetR11G11B10F_0", &CTexture::s_ptexSceneTargetR11G11B10F[0] }, - { "$SceneTargetR11G11B10F_1", &CTexture::s_ptexSceneTargetR11G11B10F[1] }, - { "$SceneTargetScaled0R11G11B10F", &CTexture::s_ptexSceneTargetScaledR11G11B10F[0] }, - { "$SceneTargetScaled1R11G11B10F", &CTexture::s_ptexSceneTargetScaledR11G11B10F[1] }, - { "$SceneTargetScaled2R11G11B10F", &CTexture::s_ptexSceneTargetScaledR11G11B10F[2] }, - { "$SceneTargetScaled3R11G11B10F", &CTexture::s_ptexSceneTargetScaledR11G11B10F[3] }, - { "$SceneNormalsMap", &CTexture::s_ptexSceneNormalsMap }, - { "$SceneNormalsBent", &CTexture::s_ptexSceneNormalsBent }, - { "$SceneDiffuse", &CTexture::s_ptexSceneDiffuse }, - { "$SceneSpecular", &CTexture::s_ptexSceneSpecular }, - { "$SceneDiffuseAcc", &CTexture::s_ptexSceneDiffuseAccMap }, - { "$SceneSpecularAcc", &CTexture::s_ptexSceneSpecularAccMap }, - { "$MipColors_Diffuse", &CTexture::s_ptexMipColors_Diffuse }, - { "$MipColors_Bump", &CTexture::s_ptexMipColors_Bump }, - { "$RT_2D", &CTexture::s_ptexRT_2D }, - { "$RainOcclusion", &CTexture::s_ptexRainOcclusion }, - { "$RainSSOcclusion0", &CTexture::s_ptexRainSSOcclusion[0] }, - { "$RainSSOcclusion1", &CTexture::s_ptexRainSSOcclusion[1] }, - { "$RainDropsAccumRT_0", &CTexture::s_ptexRainDropsRT[0] }, - { "$RainDropsAccumRT_1", &CTexture::s_ptexRainDropsRT[1] }, - { "FromObj", &CTexture::s_ptexFromObj }, - { "SvoTree", &CTexture::s_ptexSvoTree }, - { "SvoTris", &CTexture::s_ptexSvoTris }, - { "SvoGlobalCM", &CTexture::s_ptexSvoGlobalCM }, - { "SvoRgbs", &CTexture::s_ptexSvoRgbs }, - { "SvoNorm", &CTexture::s_ptexSvoNorm }, - { "SvoOpac", &CTexture::s_ptexSvoOpac }, - { "$FromObjCM", &CTexture::s_ptexFromObjCM }, - { "$RT_ShadowPool", &CTexture::s_ptexRT_ShadowPool }, - { "$RT_ShadowStub", &CTexture::s_ptexRT_ShadowStub }, - { "$ModelHud", &CTexture::s_ptexModelHudBuffer }, - { "$Velocity", &CTexture::s_ptexVelocity }, - { "$VelocityTilesTmp0", &CTexture::s_ptexVelocityTiles[0] }, - { "$VelocityTilesTmp1", &CTexture::s_ptexVelocityTiles[1] }, - { "$VelocityTiles", &CTexture::s_ptexVelocityTiles[2] }, - { "$VelocityObjects", &CTexture::s_ptexVelocityObjects[0] }, - { "$VelocityObjects_R", &CTexture::s_ptexVelocityObjects[1] }, - { "$WaterRipplesDDN_0", &CTexture::s_ptexWaterRipplesDDN }, - { "$WaterOceanMap", &CTexture::s_ptexWaterOcean }, - { "$WaterVolumeTemp", &CTexture::s_ptexWaterVolumeTemp }, - { "$WaterVolumeDDN", &CTexture::s_ptexWaterVolumeDDN }, - { "$WaterVolumeRefl", &CTexture::s_ptexWaterVolumeRefl[0] }, - { "$WaterVolumeReflPrev", &CTexture::s_ptexWaterVolumeRefl[1] }, - { "$WaterVolumeCaustics", &CTexture::s_ptexWaterCaustics[0] }, - { "$WaterVolumeCausticsTemp", &CTexture::s_ptexWaterCaustics[0] }, - { "$BackBuffer", &CTexture::s_ptexBackBuffer }, - { "$PrevFrameScale", &CTexture::s_ptexPrevFrameScaled }, - { "$BackBufferScaled_d2", &CTexture::s_ptexBackBufferScaled[0] }, - { "$BackBufferScaled_d4", &CTexture::s_ptexBackBufferScaled[1] }, - { "$BackBufferScaled_d8", &CTexture::s_ptexBackBufferScaled[2] }, - { "$BackBufferScaledTemp_d2", &CTexture::s_ptexBackBufferScaledTemp[0] }, - { "$BackBufferScaledTemp_d4", &CTexture::s_ptexBackBufferScaledTemp[1] }, - { "$AmbientLookup", &CTexture::s_ptexAmbientLookup }, - { "$ShadowMask", &CTexture::s_ptexShadowMask }, - { "$FlaresGather", &CTexture::s_ptexFlaresGather }, - { "$DepthBufferQuarter", &CTexture::s_ptexDepthBufferQuarter }, - { "$ZTarget", &CTexture::s_ptexZTarget }, - { "$ZTargetDownSample0", &CTexture::s_ptexZTargetDownSample[0]}, - { "$ZTargetDownSample1", &CTexture::s_ptexZTargetDownSample[1]}, - { "$ZTargetDownSample2", &CTexture::s_ptexZTargetDownSample[2]}, - { "$ZTargetDownSample3", &CTexture::s_ptexZTargetDownSample[3]}, - { "$FurZTarget", &CTexture::s_ptexFurZTarget }, - { "$ZTargetScaled", &CTexture::s_ptexZTargetScaled }, - { "$ZTargetScaled2", &CTexture::s_ptexZTargetScaled2 }, - { "$CloudsLM", &CTexture::s_ptexCloudsLM }, - { "$VolObj_Density", &CTexture::s_ptexVolObj_Density }, - { "$VolObj_Shadow", &CTexture::s_ptexVolObj_Shadow }, - { "$ColorChart", &CTexture::s_ptexColorChart }, - { "$SkyDomeMie", &CTexture::s_ptexSkyDomeMie }, - { "$SkyDomeRayleigh", &CTexture::s_ptexSkyDomeRayleigh }, - { "$SkyDomeMoon", &CTexture::s_ptexSkyDomeMoon }, - { "$VolumetricInscattering", &CTexture::s_ptexVolumetricFog }, - { "$DensityColorVolume", &CTexture::s_ptexVolumetricFogDensityColor }, - { "$DensityVolume", &CTexture::s_ptexVolumetricFogDensity }, - { "$ClipVolumeStencilVolume", &CTexture::s_ptexVolumetricClipVolumeStencil }, - { "$DefaultEnvironmentProbe", &CTexture::s_defaultEnvironmentProbeDummy }, -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - { "$GmemStenLinDepth", &CTexture::s_ptexGmemStenLinDepth }, -#endif - }; - - for (textureReferenceEntry& entry : staticTextureReferences) - { - CCryNameTSCRC hashEntry(entry.textureName); - m_StaticEngineTextureReferences[hashEntry] = entry.staticTextureReference; - } - - char textureName[256]; - int i; - - for ( i = 0; i < MAX_OCCLUSION_READBACK_TEXTURES; i++) - { - azsprintf(textureName, "$FlaresOcclusion_%d", i); - CCryNameTSCRC hashEntry(textureName); - m_StaticEngineTextureReferences[hashEntry] = &CTexture::s_ptexFlaresOcclusionRing[i]; - } - - for (i = 0; i < AZ_ARRAY_SIZE(CTexture::s_ptexFromRE); i++) - { - azsprintf(textureName, "$FromRE_%d", i); - CCryNameTSCRC hashEntry(textureName); - m_StaticEngineTextureReferences[hashEntry] = &CTexture::s_ptexFromRE[i]; - } - - // The shader parser also accetps $FromRE as a valid alias for $FromRE_0 - m_StaticEngineTextureReferences[CCryNameTSCRC("$FromRE")] = &CTexture::s_ptexFromRE[0]; - - for (i = 0; i < 8; i++) - { - azsprintf(textureName, "$ShadowID_%d", i); - CCryNameTSCRC hashEntry(textureName); - m_StaticEngineTextureReferences[hashEntry] = &CTexture::s_ptexShadowID[i]; - } - - for (i = 0; i < 2; i++) - { - azsprintf(textureName, "$FromRE%d_FromContainer", i); - CCryNameTSCRC hashEntry(textureName); - m_StaticEngineTextureReferences[hashEntry] = &CTexture::s_ptexFromRE_FromContainer[i]; - } -} - -/* -//============================================================================== -// The following two method should be implemented in order to finish rip off the rest -// of the horrible CTexture slots management via static declarations in class CTexture! -// The first one is the initialization method for all engine textures slots and -// the second is a better candidate than LoadDefajultTextures that can replace it -// in order to have it data driven. -//------------------------------------------------------------------------------ -void CTextureManager::CreateEngineTextures() -{ - ... - Replace the code in CTexture::LoadDefaultSystemTextures() with a proper code to be - placed here. - ... -} - -void CTextureManager::LoadDefaultTexturesFromFile() -{ -#if !defined(NULL_RENDERER) - if (m_DefaultTextures.size()) - { - return; - } - - uint32 nDefaultFlags = FT_DONT_STREAM; - - XmlNodeRef root = GetISystem()->LoadXmlFromFile("EngineAssets/defaulttextures.xml"); - if (root) - { - // we loop over this twice. - // we are looping from the back to the front to make sure that the order of the assets are correct ,when we try to load them the second time. - for (int i = root->getChildCount() - 1; i >= 0; i--) - { - XmlNodeRef textureEntry = root->getChild(i); - if (!textureEntry->isTag("TextureEntry")) - { - continue; - } - - // make an ASYNC request to move it to the top of the queue: - XmlString fileName; - if (textureEntry->getAttr("FileName", fileName)) - { - EBUS_EVENT(AzFramework::AssetSystemRequestBus, GetAssetStatus, fileName.c_str(), false ); - } - } - - for (int i = 0; i < root->getChildCount(); i++) - { - XmlNodeRef entry = root->getChild(i); - if (!entry->isTag("entry")) - { - continue; - } - - if (entry->getAttr("nomips", nNoMips) && nNoMips) - - uint32 nFlags = nDefaultFlags; - - // check attributes to modify the loading flags - int nNoMips = 0; - if (entry->getAttr("nomips", nNoMips) && nNoMips) - { - nFlags |= FT_NOMIPS; - } - - // default textures should be compiled synchronously: - const char* texName = entry->getContent(); - if (!gEnv->pCryPak->IsFileExist(texName)) - { - // make a SYNC request to block until its ready. - EBUS_EVENT(AzFramework::AssetSystemRequestBus, CompileAssetSync, texName); - } - - CTexture* pTexture = CTexture::ForName(texName, nFlags, eTF_Unknown); - if (pTexture) - { - CCryNameTSCRC nameID(texName); - m_DefaultTextures[nameID] = pTexture; - } - } - } -#endif -} -*/ - diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureManager.h b/Code/CryEngine/RenderDll/Common/Textures/TextureManager.h deleted file mode 100644 index 55ac285d4d..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureManager.h +++ /dev/null @@ -1,262 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Common texture manager declarations. - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREMANAGER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREMANAGER_H -#pragma once - - -class CTexture; - -#include "CryName.h" - -//------------------------------------------------------------------------------ -// [Shaders System] - to replace CCryNameTSCRC by NameHashPair after new renderer -// integration. -//------------------------------------------------------------------------------ -struct MaterialTextureSemantic -{ - MaterialTextureSemantic(EEfResTextures texSlot, int8 pri, CTexture* defTex, CTexture* neutralTex, char const* suff) - : slot(texSlot), priority(pri), def(defTex), neutral(neutralTex) - { - suffix = new char[strlen(suff)+1]; // added one to protect from empty strings. - azstrcpy(suffix, strlen(suff) + 1, suff); - }; - - MaterialTextureSemantic& operator=(MaterialTextureSemantic& srcSemantic) - { - SAFE_DELETE_ARRAY(suffix); - - slot = srcSemantic.slot; - priority = srcSemantic.priority; - def = srcSemantic.def; - neutral = srcSemantic.neutral; - suffix = new char[strlen(srcSemantic.suffix) + 1]; // added one to protect from empty strings. - azstrcpy(suffix, strlen(srcSemantic.suffix) + 1, srcSemantic.suffix); - - return *this; - } - - MaterialTextureSemantic() - { - slot = EFTT_MAX; - def = nullptr; - neutral = nullptr; - suffix = nullptr; - }; - - ~MaterialTextureSemantic() - { - SAFE_DELETE_ARRAY(suffix); - }; - - EEfResTextures slot; - int8 priority; - CTexture* def; - CTexture* neutral; - char* suffix; -}; - -//============================================================================== -// CTextureManager is a singleton class. -// It is NOT the texture resource manager but rather holds vital textures required -// by the engine and renderer. -// These textures are the default textures (for example - missing resource, resource -// compiling...), the render engine pipeline textures such as the textures that -// are used for noise, and finally, the material 'snapshot' textures which are -// assigned just before the shader's resources are bound. -// -// Possible improvements on that are: -// 1. Move the m_EngineTextures and m_MaterialTextures to ResourceGroupManager -// that will manage the 'per frequency' resource snapshot. -// 2. Keep only pointers / refs to the resources, while the resources themselves are -// managed and held by the ResourceManager (currently carried out by CBaseResource..) -// 3. Address the default textures via enum and not strings if turns out to be a hit. -// 4. Move to use NameHashPair instead of CCryNameTSCRC for Amazon internal + allow -// s having name debug info -// -// Remarks: -// 1. The work for moving all static Cry textures to the manager is NOT complete yet and -// should be continued and include changing usage of all default 'error textures' and -// removing all static CTextures from CTexture class and stop using it as -// a static manager class. -// -//------------------------------------------------------------------------------ -class CTextureManager -{ -protected: - - CTextureManager() - { - s_Instance = nullptr; - m_texNoTexture = nullptr; - m_texNoTextureCM = nullptr; - m_texWhite = nullptr; - m_texBlack = nullptr; - m_texBlackCM = nullptr; - } - - void ReleaseResources() - { - ReleaseTextures(); - ReleaseTextureSemantics(); - } - - virtual ~CTextureManager() - { - ReleaseResources(); - } - - void ReleaseTextures(); - void ReleaseTextureSemantics(); - -public: - - void Init( bool forceInit=false ) - { - if (forceInit) - { - ReleaseResources(); - } - - // this will be carried out only if it is the first item or after force init. - if (!m_DefaultTextures.size() && !m_EngineTextures.size() && !m_MaterialTextures.size()) - { - AZ_TracePrintf("[Shaders System]", "Textures Manager - allocating default resources"); - // First load is for loading semantics but the texture slots will remain null as the default - // textures were not loaded yet. This is required as the semantics suffix will be used during - // the default texture load. - LoadMaterialTexturesSemantics(); - - // Default texture load - LoadDefaultTextures(); - CreateEngineTextures(); - - // References to legacy static textures - CreateStaticEngineTextureReferences(); - - // Second time is for attaching the loaded textures to the semantics - LoadMaterialTexturesSemantics(); - } - } - - inline static CTextureManager* Instance() - { - if (!s_Instance) - s_Instance = new CTextureManager; - - return s_Instance; - } - - inline static bool InstanceExists() - { - return s_Instance ? true : false; - } - - void Release() - { - SAFE_DELETE(s_Instance); - } - - void LoadDefaultTextures(); - void LoadMaterialTexturesSemantics(); - void CreateEngineTextures() {}; - void CreateStaticEngineTextureReferences(); - - inline MaterialTextureSemantic& GetTextureSemantic(int texSlot) - { - AZ_Assert(texSlot >= 0 && texSlot <= EFTT_MAX, "[CTextureManager::GetTextureSemantic] Slot is out of range: %d", texSlot); - //we need to correct the texSlot if by any chance there is an unexpected input value. - if (texSlot < 0 || texSlot > EFTT_MAX) - { - texSlot = EFTT_UNKNOWN; - } - return m_TexSlotSemantics[texSlot]; - } - - inline CTexture* GetDefaultTexture( const char* sTextureName) const - { - CCryNameTSCRC hashEntry(sTextureName); - auto iter = m_DefaultTextures.find(hashEntry); - return (iter != m_DefaultTextures.end() ? iter->second : nullptr); - } - - inline CTexture* GetEngineTexture( const char* sTextureName) const - { - CCryNameTSCRC hashEntry(sTextureName); - return GetEngineTexture(hashEntry); - } - - inline CTexture* GetEngineTexture( const CCryNameTSCRC& crc) const - { - auto iter = m_EngineTextures.find(crc); - return iter != m_EngineTextures.end() ? iter->second : GetStaticEngineTexture(crc); - } - - inline CTexture* GetMaterialTexture(const char* sTextureName) const - { - CCryNameTSCRC hashEntry(sTextureName); - auto iter = m_MaterialTextures.find(hashEntry); - return (iter != m_MaterialTextures.end() ? iter->second : nullptr); - } - - inline CTexture* GetNoTexture() { return m_texNoTexture; } - inline CTexture* GetNoTextureCM() { return m_texNoTextureCM; } - inline CTexture* GetWhiteTexture() { return m_texWhite; } - inline CTexture* GetBlackTexture() { return m_texBlack; } - inline CTexture* GetBlackTextureCM() { return m_texBlackCM; } - -private: - inline CTexture* GetStaticEngineTexture(const CCryNameTSCRC& crc) const - { - auto iter = m_StaticEngineTextureReferences.find(crc); - return iter != m_StaticEngineTextureReferences.end() ? *iter->second : nullptr; - } - - MaterialTextureSemantic m_TexSlotSemantics[EFTT_MAX]; // [Shaders System] - to do - replace with map - - // [Shaders System] CCryNameTSCRC should be replaced by - typedef std::map OrderedTextureMap; - typedef std::map TextureMap; - typedef std::map TextureRefMap; - - // Textures used as defaults for internal engine usage, place holders etc... - TextureMap m_DefaultTextures; - - // The following two textures are set separately since they are called often - CTexture* m_texWhite; - CTexture* m_texBlack; - CTexture* m_texBlackCM; - CTexture* m_texNoTexture; - CTexture* m_texNoTextureCM; - - // Runtime engine textures used by the various shaders and represents last - // taken 'snapshot' - TextureMap m_EngineTextures; - - // pending the move to using CTextureManager for all engine textures, - // provides access to existing static engine textures - TextureRefMap m_StaticEngineTextureReferences; - - // material 'snapshot' (most recent) textures to be used by the shader. - OrderedTextureMap m_MaterialTextures; - - // The CTextureManager is a singleton - this is its single instance - static CTextureManager* s_Instance; -}; - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTUREMANAGER_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureStreamPool.h b/Code/CryEngine/RenderDll/Common/Textures/TextureStreamPool.h deleted file mode 100644 index 2ea9169ce2..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureStreamPool.h +++ /dev/null @@ -1,307 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTURESTREAMPOOL_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTURESTREAMPOOL_H -#pragma once - - -#define TEXSTRM_USE_FREEPOOL - -struct STexPool; - -struct STexPoolItemHdr -{ - static CryCriticalSection s_sSyncLock; - - STexPoolItemHdr* m_Next; - STexPoolItemHdr* m_Prev; - STexPoolItemHdr* m_NextFree; - STexPoolItemHdr* m_PrevFree; - - STexPoolItemHdr() - : m_Next(NULL) - , m_Prev(NULL) - , m_NextFree(NULL) - , m_PrevFree(NULL) - { - } - - _inline void Unlink(); - _inline void Link(STexPoolItemHdr* Before); - _inline void UnlinkFree(); - _inline void LinkFree(STexPoolItemHdr* Before); -}; - -struct STexPoolItem - : STexPoolItemHdr -{ - STexPool* const m_pOwner; - CTexture* m_pTex; - CDeviceTexture* const m_pDevTexture; - size_t const m_nDeviceTexSize; - - uint32 m_nFreeTick; - uint8 m_nActiveLod; - - STexPoolItem (STexPool* pOwner, CDeviceTexture* pDevTexture, size_t devSize); - ~STexPoolItem(); - - bool IsFree() const { return m_NextFree != NULL; } - - int GetSize() - { - int nSize = sizeof(*this); - return nSize; - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pDevTexture); - } - bool IsStillUsedByGPU(uint32 nCurTick); -}; - -struct STexPool -{ - uint16 m_Width; - uint16 m_Height; - uint16 m_nArraySize; - D3DFormat m_eFormat; - size_t m_Size; - STexPoolItemHdr m_ItemsList; - ETEX_Type m_eTT; - uint8 m_nMips; - - int m_nItems; - int m_nItemsFree; - - ~STexPool(); - - size_t GetSize() - { - size_t nSize = sizeof(*this); - STexPoolItemHdr* pIT = m_ItemsList.m_Next; - while (pIT != &m_ItemsList) - { - nSize += static_cast(pIT)->GetSize(); - pIT = pIT->m_Next; - } - - return nSize; - } - - uint32 GetNumSlices() const - { - uint32 b = (m_eTT == eTT_Cube) ? 6 : 1; - return b * m_nArraySize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - STexPoolItemHdr* pIT = m_ItemsList.m_Next; - while (pIT != &m_ItemsList) - { - pSizer->AddObject(static_cast(pIT)); - pIT = pIT->m_Next; - } - } -}; - -class CTextureStreamPoolMgr -{ -public: - struct SFrameStats - { - SFrameStats() - { - memset(this, 0, sizeof(*this)); - } - - int nSoftCreates; - int nSoftFrees; - int nHardCreates; - int nHardFrees; - }; - - struct SPoolStats - { - int nWidth; - int nHeight; - int nMips; - uint32 nFormat; - ETEX_Type eTT; - - int nInUse; - int nFree; - - int nHardCreatesPerFrame; - int nSoftCreatesPerFrame; - }; - -public: - CTextureStreamPoolMgr(); - ~CTextureStreamPoolMgr(); - - void Flush(); - - // Fetch and reset last frame stats -#if !defined(_RELEASE) - void EnableStatsComputation(bool bCompute) { m_bComputeStats = bCompute; } - SFrameStats FetchFrameStats() - { - SFrameStats frameStats = m_frameStats; - m_frameStats = SFrameStats(); - return frameStats; - } - - void FetchPoolStats(std::vector& poolStats) - { - CryAutoLock lock(m_statsLock); - poolStats = m_poolStats; - m_poolStats.clear(); - } -#endif - - STexPool* GetPool(int nWidth, int nHeight, int nMips, int nArraySize, ETEX_Format eTF, bool bIsSRGB, ETEX_Type eTT); - - STexPoolItem* GetPoolItem(int nWidth, int nHeight, int nMips, int nArraySize, ETEX_Format eTF, bool bIsSRGB, ETEX_Type eTT, bool bShouldBeCreated, const char* sName, STextureInfo* pTI = NULL, bool bCanCreate = true, bool bWaitForIdle = true); - void ReleaseItem(STexPoolItem* pItem); - void GarbageCollect(size_t* nCurTexPoolSize, size_t nLowerPoolLimit, int nMaxItemsToFree); - - void GetMemoryUsage(ICrySizer* pSizer); - - size_t GetInUseSize() const { return m_nDeviceMemInUse; } - size_t GetReservedSize() const { return m_nDeviceMemReserved; } - -private: - union TexturePoolKey - { - struct - { - uint64 a, b; - }; - struct - { - uint16 nWidth; - uint16 nHeight; - uint32 nFormat; - uint8 nTexType; - uint8 nMips; - uint16 nArraySize; - }; - - TexturePoolKey(uint16 nWidth, uint16 nHeight, uint32 nFormat, uint8 nTexType, uint8 nMips, uint16 nArraySize) - { - memset(this, 0, sizeof(*this)); - this->nWidth = nWidth; - this->nHeight = nHeight; - this->nFormat = nFormat; - this->nTexType = nTexType; - this->nMips = nMips; - this->nArraySize = nArraySize; - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - - friend bool operator < (const TexturePoolKey& a, const TexturePoolKey& b) - { - if (a.a != b.a) - { - return a.a < b.a; - } - return a.b < b.b; - } - }; - - enum - { - MaxFreePool = 64, - }; - - typedef VectorMap TexturePoolMap; - -private: - STexPool* CreatePool(int nWidth, int nHeight, int nMips, int nArraySize, D3DFormat eTF, ETEX_Type eTT); - void FlushFree(); - -private: - volatile size_t m_nDeviceMemReserved; - volatile size_t m_nDeviceMemInUse; - -#if !defined(_RELEASE) - CryCriticalSection m_statsLock; - bool m_bComputeStats; - std::vector m_poolStats; - SFrameStats m_frameStats; -#endif - - uint32 m_nTick; - - TexturePoolMap m_TexturesPools; - STexPoolItemHdr m_FreeTexPoolItems; - -#ifdef TEXSTRM_USE_FREEPOOL - void* m_FreePool[MaxFreePool]; - size_t m_nFreePoolBegin; - size_t m_nFreePoolEnd; -#endif -}; - -_inline void STexPoolItemHdr::Unlink() -{ - if (!m_Next || !m_Prev) - { - return; - } - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - m_Next = m_Prev = NULL; -} - -_inline void STexPoolItemHdr::Link(STexPoolItemHdr* pAfter) -{ - if (m_Next || m_Prev) - { - return; - } - m_Next = pAfter->m_Next; - pAfter->m_Next->m_Prev = this; - pAfter->m_Next = this; - m_Prev = pAfter; -} - -_inline void STexPoolItemHdr::UnlinkFree() -{ - if (!m_NextFree || !m_PrevFree) - { - return; - } - m_NextFree->m_PrevFree = m_PrevFree; - m_PrevFree->m_NextFree = m_NextFree; - m_NextFree = m_PrevFree = NULL; -} -_inline void STexPoolItemHdr::LinkFree(STexPoolItemHdr* pAfter) -{ - if (m_NextFree || m_PrevFree) - { - return; - } - m_NextFree = pAfter->m_NextFree; - pAfter->m_NextFree->m_PrevFree = this; - pAfter->m_NextFree = this; - m_PrevFree = pAfter; -} - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_COMMON_TEXTURES_TEXTURESTREAMPOOL_H diff --git a/Code/CryEngine/RenderDll/Common/Textures/TextureStreaming.cpp b/Code/CryEngine/RenderDll/Common/Textures/TextureStreaming.cpp deleted file mode 100644 index fdaa862305..0000000000 --- a/Code/CryEngine/RenderDll/Common/Textures/TextureStreaming.cpp +++ /dev/null @@ -1,2081 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Common Texture Streaming manager implementation. - - -#include "RenderDll_precompiled.h" -#include "../CommonRender.h" -#include -#include "Image/DDSImage.h" -#include "StringUtils.h" // stristr() -#include "ILocalMemoryUsage.h" - -#include "TextureManager.h" -#include "TextureStreamPool.h" -#include "TextureHelpers.h" - - -#include "PlanningTextureStreamer.h" - -// checks for MT-safety of called functions -#define CHK_RENDTH assert(gRenDev->m_pRT->IsRenderThread()) -#define CHK_MAINTH assert(gRenDev->m_pRT->IsMainThread()) -#define CHK_MAINORRENDTH assert(gRenDev->m_pRT->IsMainThread() || gRenDev->m_pRT->IsRenderThread()) - -bool CTexture::s_bStreamingFromHDD = true; -CTextureArrayAlloc CTexture::s_StreamInTasks; -CTextureArrayAlloc CTexture::s_StreamPrepTasks; - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define TEXTURESTREAMING_CPP_SECTION_1 1 -#define TEXTURESTREAMING_CPP_SECTION_2 2 -#define TEXTURESTREAMING_CPP_SECTION_3 3 -#define TEXTURESTREAMING_CPP_SECTION_4 4 -#define TEXTURESTREAMING_CPP_SECTION_5 5 -#define TEXTURESTREAMING_CPP_SECTION_6 6 -#define TEXTURESTREAMING_CPP_SECTION_7 7 -#endif - -#ifdef TEXSTRM_ASYNC_TEXCOPY -CTextureArrayAlloc CTexture::s_StreamOutTasks; -#endif - -volatile TIntAtomic CTexture::s_nBytesSubmittedToStreaming = {0}; -volatile TIntAtomic CTexture::s_nMipsSubmittedToStreaming = {0}; -int CTexture::s_nBytesRequiredNotSubmitted = 0; - -#if !defined (_RELEASE) -int CTexture::s_TextureUpdates = 0; -float CTexture::s_TextureUpdatesTime = 0.0f; -int CTexture::s_TexturesUpdatedRendered = 0; -float CTexture::s_TextureUpdatedRenderedTime = 0.0f; -int CTexture::s_StreamingRequestsCount = 0; -float CTexture::s_StreamingRequestsTime = 0.0f; -#endif - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER -ITextureStreamListener* CTexture::s_pStreamListener; -#endif - -bool CTexture::s_bStreamDontKeepSystem = false; - -int CTexture::s_nTexturesDataBytesLoaded = 0; -volatile int CTexture::s_nTexturesDataBytesUploaded = 0; -int CTexture::s_nStatsAllocFails; -bool CTexture::s_bOutOfMemoryTotally; -volatile size_t CTexture::s_nStatsStreamPoolInUseMem; -volatile size_t CTexture::s_nStatsStreamPoolBoundMem; -volatile size_t CTexture::s_nStatsStreamPoolBoundPersMem; -AZStd::atomic_uint CTexture::s_nStatsCurManagedNonStreamedTexMem = {0}; -AZStd::atomic_uint CTexture::s_nStatsCurDynamicTexMem = {0}; -volatile size_t CTexture::s_nStatsStreamPoolWanted = {0}; -bool CTexture::s_bStatsComputeStreamPoolWanted = false; -std::vector* CTexture::s_pStatsTexWantedLists = NULL; - -ITextureStreamer* CTexture::s_pTextureStreamer; - -CryCriticalSection CTexture::s_streamFormatLock; -SStreamFormatCode CTexture::s_formatCodes[256]; -uint32 CTexture::s_nFormatCodes = 1; -StaticInstance CTexture::s_formatCodeMap; - -const int CTexture::LOW_SPEC_PC = 5; -const int CTexture::MEDIUM_SPEC_PC = 6; -const int CTexture::HIGH_SPEC_PC = 7; -const int CTexture::VERYHIGH_SPEC_PC = 8; - -#ifdef TEXSTRM_ASYNC_TEXCOPY -void STexStreamInState::CopyMips() -{ - FUNCTION_PROFILER_RENDERER; - - CTexture* tp = m_pTexture; - - if (!m_bAborted) - { - if (tp->m_pFileTexMips->m_pPoolItem) - { - const int nNewMipOffset = tp->m_nMinMipVidUploaded - m_nHigherUploadedMip; - const int nNumMips = tp->GetNumMipsNonVirtual() - tp->m_nMinMipVidUploaded; - - if (0) - { - } -#if TEXTURESTREAMING_CPP_TRAIT_COPYMIPS_MOVEENGINE && !defined(NULL_RENDERER) - else if (!gRenDev->m_pRT->IsRenderThread()) - { - m_copyMipsFence = CTexture::StreamCopyMipsTexToTex_MoveEngine(tp->m_pFileTexMips->m_pPoolItem, 0, m_pNewPoolItem, 0 + nNewMipOffset, nNumMips); - } -#endif - else - { - CTexture::StreamCopyMipsTexToTex(tp->m_pFileTexMips->m_pPoolItem, 0, m_pNewPoolItem, 0 + nNewMipOffset, nNumMips); - } - - m_bValidLowMips = true; - } - } - else - { - m_bValidLowMips = true; - } -} - -void STexStreamOutState::Reset() -{ - // if we have streaming error, release new pool item - if (m_pNewPoolItem) - { - CTexture::s_pPoolMgr->ReleaseItem(m_pNewPoolItem); - } - - m_pNewPoolItem = NULL; - m_pTexture = 0; - m_bDone = false; - m_bAborted = false; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif -} - -bool STexStreamOutState::TryCommit() -{ - if (m_bDone) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif - - if (!m_bAborted) - { - if (m_nStartMip < MAX_MIP_LEVELS) - { - m_pTexture->StreamAssignPoolItem(m_pNewPoolItem, m_nStartMip); - m_pNewPoolItem = NULL; - - m_pTexture->SetWasUnload(false); - } - else - { - // Stream unload - m_pTexture->ReleaseDeviceTexture(true, true); - m_pTexture->SetWasUnload(true); - } - } - - m_pTexture->SetStreamingInProgress(CTexture::InvalidStreamSlot); - m_pTexture->Release(); - m_pTexture = NULL; - - return true; - } - - return false; -} -#endif - -void CTexture::StreamReleaseMipsData(int nStartMip, int nEndMip) -{ - assert(m_pFileTexMips); - assert(nStartMip <= nEndMip); - nEndMip = min(nEndMip, m_nMips - 1); - nStartMip = min(nStartMip, nEndMip); - const int nSides = StreamGetNumSlices(); - for (int i = 0; i < nSides; i++) - { - for (int j = nStartMip; j <= nEndMip; j++) - { - m_pFileTexMips->m_pMipHeader[j].m_Mips[i].Free(); - } - } -} - -STexStreamInState::STexStreamInState() -{ - m_pNewPoolItem = NULL; -#if defined(TEXSTRM_DEFERRED_UPLOAD) - m_pCmdList = NULL; -#endif - Reset(); -} - -void STexStreamInState::Reset() -{ - if (m_pNewPoolItem) - { - CTexture::s_pPoolMgr->ReleaseItem(m_pNewPoolItem); - - m_pNewPoolItem = NULL; - } - -#if defined(TEXSTRM_DEFERRED_UPLOAD) - SAFE_RELEASE(m_pCmdList); -#endif - - for (size_t i = 0, c = m_nLowerUploadedMip - m_nHigherUploadedMip + 1; i != c; ++i) - { - m_pStreams[i] = NULL; - } - - memset(&m_pTexture, 0, (char*)(this + 1) - (char*)&m_pTexture); -} - -// streaming thread -void STexStreamInState::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError) -{ - PROFILE_FRAME(Texture_StreamAsyncOnComplete); - - CTexture* tp = m_pTexture; - - int nMip = (int)pStream->GetUserData(); - STexStreamInMipState& mipState = m_mips[nMip]; - - if (!nError && tp->m_pFileTexMips) - { -#if defined(TEXSTRM_ASYNC_UPLOAD) - tp->StreamUploadMip(pStream, nMip, m_nHigherUploadedMip, m_pNewPoolItem, mipState); - mipState.m_bUploaded = true; -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - if (!mipState.m_bStreamInPlace) - { - tp->StreamExpandMip(pStream->GetBuffer(), nMip, m_nHigherUploadedMip, mipState.m_nSideDelta); - mipState.m_bExpanded = true; - } - else - { - mipState.m_bUploaded = true; - } -#endif - - // Update the cached media type to optimise future requests - EStreamSourceMediaType eMT = pStream->GetMediaType(); - int nAbsMip = m_nHigherUploadedMip + nMip; - tp->m_pFileTexMips->m_pMipHeader[nAbsMip].m_eMediaType = eMT; - } - else - { - m_bAborted = true; - } - - pStream->FreeTemporaryMemory(); // We don't need internal stream loaded buffer anymore. - - int nChunkSize = tp->m_pFileTexMips->m_pMipHeader[nMip + m_nHigherUploadedMip].m_SideSize * tp->GetNumSides(); - CryInterlockedAdd(CTexture::s_nBytesSubmittedToStreaming.Addr(), -nChunkSize); - CryInterlockedDecrement(CTexture::s_nMipsSubmittedToStreaming.Addr()); - assert(CTexture::s_nBytesSubmittedToStreaming >= 0); - - const int nRef = CryInterlockedDecrement(&m_nAsyncRefCount); - - // Check to see if this is the last mip (and thus owns the job) - if (nRef == 0) - { - if (!m_bAborted) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif - -#if defined(TEXSTRM_DEFERRED_UPLOAD) - if (tp->m_pFileTexMips->m_pPoolItem) ///< Don't upload if the source is nullptr it'll just cause an exception - { - ID3D11CommandList* pCmdList = tp->StreamCreateDeferred(m_nHigherUploadedMip, m_nLowerUploadedMip, m_pNewPoolItem, tp->m_pFileTexMips->m_pPoolItem); - - if (pCmdList) - { - m_pCmdList = pCmdList; - m_bValidLowMips = true; - - for (int i = 0, c = m_nLowerUploadedMip - m_nHigherUploadedMip + 1; i != c; ++i) - { - m_mips[i].m_bExpanded = false; - } - - if (CTexture::s_bStreamDontKeepSystem) - { - tp->StreamReleaseMipsData(m_nHigherUploadedMip, m_nLowerUploadedMip); - } - } - } -#endif - -#if defined(TEXSTRM_ASYNC_TEXCOPY) - - if (!m_bValidLowMips && tp->CanAsyncCopy()) - { - CopyMips(); - } - -#endif - } - -#ifndef _RELEASE - // collect statistics - if (pStream->GetParams().nSize > 1024) - { - CTexture::s_nStreamingThroughput += pStream->GetParams().nSize; - } - const CTimeValue currentTime = iTimer->GetAsyncTime(); - if (currentTime - m_fStartTime > .01f) // avoid measurement errors for small textures - { - CTexture::s_nStreamingTotalTime += currentTime.GetSeconds() - m_fStartTime; - } -#endif - - m_bAllStreamsComplete = true; - } -} - -bool STexStreamInState::TryCommit() -{ - PROFILE_FRAME(Texture_StreamOnComplete_Render); - - CHK_RENDTH; - - CTexture* tp = m_pTexture; - - if (!m_bAborted) - { - STexPoolItem*& pNewPoolItem = m_pNewPoolItem; - -#if !defined(TEXSTRM_ASYNC_UPLOAD) && TEXTURESTREAMING_CPP_TRAIT_TRYCOMMIT_COPYMIPS - for (size_t i = 0, c = m_nLowerUploadedMip - m_nHigherUploadedMip + 1; i != c; ++i) - { - STexStreamInMipState& mipState = m_mips[i]; - - if (mipState.m_bExpanded) - { - mipState.m_bUploaded = true; - mipState.m_bExpanded = false; - - tp->StreamCopyMipsTexToMem(m_nHigherUploadedMip + i, m_nHigherUploadedMip + i, true, pNewPoolItem); - if (CTexture::s_bStreamDontKeepSystem) - { - tp->StreamReleaseMipsData(m_nHigherUploadedMip + i, m_nHigherUploadedMip + i); - } - } - } -#endif - -#ifdef TEXSTRM_DEFERRED_UPLOAD - if (m_pCmdList) - { - tp->StreamApplyDeferred(m_pCmdList); - m_pCmdList->Release(); - m_pCmdList = NULL; - } -#endif - -#if defined(TEXSTRM_COMMIT_COOLDOWN) - if ((m_nStallFrames++) < 4) - { - return false; - } -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif - - if (!m_bValidLowMips) - { - STexPoolItem* pCurItem = tp->m_pFileTexMips->m_pPoolItem; - - if (pCurItem) - { - // it is a sync operation anyway, so we do it in the render thread - // restore already loaded mips - const int nNumMips = pCurItem->m_pOwner->m_nMips; - const int nNewMipOffset = pNewPoolItem->m_pOwner->m_nMips - nNumMips; - CTexture::StreamCopyMipsTexToTex(pCurItem, 0, pNewPoolItem, nNewMipOffset, nNumMips); - } - else - { - m_pTexture->StreamCopyMipsTexToMem(m_pTexture->GetNumMipsNonVirtual() - m_pTexture->GetNumPersistentMips(), m_pTexture->GetNumMipsNonVirtual() - 1, true, pNewPoolItem); - - if (CTexture::s_bStreamDontKeepSystem) - { - m_pTexture->StreamReleaseMipsData(m_pTexture->GetNumMipsNonVirtual() - m_pTexture->GetNumPersistentMips(), m_pTexture->GetNumMipsNonVirtual() - 1); - } - } - - m_bValidLowMips = true; - } - - if (pNewPoolItem) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texturesstreamingmipfading) - { - tp->m_fCurrentMipBias = min(2.f, tp->m_fCurrentMipBias + float(m_nLowerUploadedMip - m_nHigherUploadedMip + 1)); - } - - // bind new texture - const int nNewNumMips = m_nHigherUploadedMip; - tp->StreamAssignPoolItem(pNewPoolItem, m_nActivateMip); - pNewPoolItem = NULL; - tp->SetWasUnload(false); - } - } - else - { - if (CTexture::s_bStreamDontKeepSystem) - { - tp->StreamReleaseMipsData(m_nHigherUploadedMip, m_nLowerUploadedMip); - } - } - - tp->SetStreamingInProgress(CTexture::InvalidStreamSlot); - - m_pTexture->Release(); - m_pTexture = NULL; - - CTexture::StreamValidateTexSize(); - - return true; -} - -bool STexStreamPrepState::Commit() -{ - _smart_ptr pNextImage; - - if (!m_bFailed) - { - if (m_pImage) - { - if (m_pTexture->IsStreamed()) - { - if (m_pTexture->StreamPrepare(&*m_pImage)) - { - m_bNeedsFinalise = true; - } - else - { - m_bCompleted = false; - - // StreamPrepare failed, so presumably the image can't be streamed. Since we only have an image assuming it was streamed, - // load it again, with all mips. - // StreamPrepare failure will mark the texture as non-streamable. - pNextImage = CImageFile::mfStream_File(m_pImage->mfGet_filename(), m_pImage->mfGet_Flags() & ~FIM_STREAM_PREPARE, this); - } - } - else - { - m_pTexture->Load(&*m_pImage); - } - } - - if (m_bNeedsFinalise) - { - if (m_pTexture->IsStreamed()) - { - m_bNeedsFinalise = !m_pTexture->StreamPrepare_Finalise(true); - } - } - } - else - { - m_pTexture->SetNoTexture( CTextureManager::Instance()->GetNoTexture() ); - } - - m_pImage = pNextImage; - - if (!m_pImage && !m_bNeedsFinalise && m_pTexture) - { - m_pTexture->PostCreate(); - } - - return !m_pImage && !m_bNeedsFinalise; -} - -void STexStreamPrepState::OnImageFileStreamComplete(CImageFile* pImFile) -{ - if (!pImFile) - { - m_pImage = NULL; - m_bFailed = true; - } - - m_bCompleted = true; -} - -int CTexture::StreamCalculateMipsSigned(float fMipFactor) const -{ - return StreamCalculateMipsSignedFP(fMipFactor) >> 8; -} - -int CTexture::GetStreamableMipNumber() const -{ - assert(IsStreamed()); - return max(0, m_nMips - m_CacheFileHeader.m_nMipsPersistent); -} - -bool CTexture::IsStreamedIn(const int nMinPrecacheRoundIds[MAX_STREAM_PREDICTION_ZONES]) const -{ - if (IsStreamed()) - { - for (int nZoneIdx = 0; nZoneIdx < MAX_STREAM_PREDICTION_ZONES; ++nZoneIdx) - { - if (m_streamRounds[nZoneIdx].nRoundUpdateId < nMinPrecacheRoundIds[nZoneIdx]) - { - return false; - } - } - - int nMinMip = s_pTextureStreamer->GetMinStreamableMipWithSkip(); - return max(GetRequiredMipNonVirtual(), nMinMip) >= CTexture::GetMinLoadedMip(); - } - return true; -} - -int CTexture::GetStreamableMemoryUsage(int nStartMip) const -{ - assert(IsStreamed()); - if (m_pFileTexMips == NULL) - { - assert(0); - return 0; - } - - return m_pFileTexMips->m_pMipHeader[nStartMip].m_SideSizeWithMips; -} - -void CTexture::SetMinLoadedMip(int nMinMip) -{ -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - if (m_nMinMipVidUploaded != nMinMip) - { - ITextureStreamListener* pListener = s_pStreamListener; - if (pListener) - { - pListener->OnTextureHasMip(this, min(nMinMip, (int)m_nMips)); - } - } -#endif - - m_nMinMipVidUploaded = nMinMip; -} - -const bool CTexture::IsParticularMipStreamed(float fMipFactor) const -{ - if (!IsStreamed()) - { - return true; - } - - bool bHighPriority = false; - if (m_pFileTexMips) - { - bHighPriority = m_bStreamHighPriority != 0; - } - int nMipClamp = (s_bStreamingFromHDD || bHighPriority) ? 0 : CRenderer::CV_r_TexturesStreamingMipClampDVD; - const int nMip = max(nMipClamp, CTexture::StreamCalculateMipsSigned(fMipFactor)); - return m_nMinMipVidUploaded <= nMip; -} - -void CTexture::PrecacheAsynchronously(float fMipFactor, int nFlags, int nUpdateId, int nCounter) -{ - if (!IsStreamed()) - { - return; // already done - } - s_pTextureStreamer->UpdateMip(this, fMipFactor, nFlags, nUpdateId, nCounter); - - // for distance streaming it's just the same as update rendering distance - StreamLoadFromCache(nFlags); -} - -void CTexture::StreamLoadFromCache([[maybe_unused]] const int Flags) -{ - if (IsUnloaded()) - { - if (!StreamPrepare(false)) - { - // ignore error for optional attached alpha channel - if (!m_bNoTexture && !(m_nFlags & FT_ALPHA) && (m_nFlags & FT_FROMIMAGE)) - { -#ifndef NDEBUG - bool bRes = -#endif - Reload(); - assert(bRes); - } - } - } -} - -bool CTexture::StreamPrepare(bool bFromLoad) -{ - CHK_MAINORRENDTH; - - if (!CRenderer::CV_r_texturesstreaming || m_nFlags & FT_DONT_STREAM) - { - return false; - } - - LOADING_TIME_PROFILE_SECTION(iSystem); - PROFILE_FRAME(Texture_StreamPrepare); - - CRY_DEFINE_ASSET_SCOPE("Texture", m_sAssetScopeName); - - // release the old texture - if (m_pDevTexture) - { - ReleaseDeviceTexture(false); - } - - if (!m_pFileTexMips) - { - if (IResourceCompilerHelper::IsSourceImageFormatSupported(m_SrcName.c_str()) && - !gEnv->pCryPak->IsFileExist(m_SrcName.c_str())) - { - m_SrcName = PathUtil::ReplaceExtension(m_SrcName, "dds"); - if (!gEnv->pCryPak->IsFileExist(m_SrcName.c_str())) - { - return false; - } - } - -#if !defined(_RELEASE) - if ((m_nFlags & FT_TEX_NORMAL_MAP) && !TextureHelpers::VerifyTexSuffix(EFTT_NORMALS, m_SrcName)) - { - FileWarning(m_SrcName.c_str(), "Normal map should have '%s' suffix in filename", TextureHelpers::LookupTexSuffix(EFTT_NORMALS)); - } -#endif - - if (m_bPostponed) - { - if (CTexture::s_pTextureStreamer->BeginPrepare(this, m_SrcName.c_str(), ((m_nFlags & FT_ALPHA) ? FIM_ALPHA : 0) | FIM_STREAM_PREPARE)) - { - return true; - } - } - - uint32 nImageFlags = FIM_STREAM_PREPARE | ((m_nFlags & FT_ALPHA) ? FIM_ALPHA : 0); - - _smart_ptr pIM(CImageFile::mfLoad_file(m_SrcName, nImageFlags)); - m_bisTextureMissing = !pIM || pIM->mfGet_IsImageMissing(); - if (!pIM || m_bisTextureMissing || !StreamPrepare(&*pIM)) - { - return false; - } - } - - return StreamPrepare_Finalise(bFromLoad); -} - -bool CTexture::StreamPrepareComposition() -{ - CHK_MAINORRENDTH; - - if (!CRenderer::CV_r_texturesstreaming || m_nFlags & FT_DONT_STREAM) - { - return false; - } - - LOADING_TIME_PROFILE_SECTION(iSystem); - PROFILE_FRAME(Texture_StreamPrepare); - - CRY_DEFINE_ASSET_SCOPE("Texture", m_sAssetScopeName); - - int nWidth = m_nWidth; - int nHeight = m_nHeight; - int nMips = m_nMips; - ETEX_Format eTF = m_eTFDst; - const STexComposition* pCompositions = &m_composition[0]; - size_t nCompositions = m_composition.size(); - - // release the old texture - if (m_pDevTexture) - { - ReleaseDeviceTexture(false); - } - - int nSides = 1; - for (size_t i = 0; i < nCompositions; ++i) - { - nSides = max(nSides, pCompositions[i].nDstSlice + 1); - } - - ETEX_Type eTT = nSides > 1 ? eTT_2DArray : eTT_2D; - ETEX_Format eTFSrc = eTF; - ETEX_Format eTFDst = eTF; - float fAvgBrightness = 1.0f; - ETEX_TileMode eTileMode = eTM_None; - - int nMipsPersistent = DDSSplitted::GetNumLastMips(nWidth, nHeight, nMips, nSides, eTFSrc, 0); - - - m_nFlags &= ~(FT_SPLITTED | FT_TEX_WAS_NOT_PRE_TILED | FT_HAS_ATTACHED_ALPHA | FT_DONT_STREAM | FT_FROMIMAGE); - - const SPixFormat* pPF = NULL; -#ifndef NULL_RENDERER - ClosestFormatSupported(eTFDst, pPF); -#endif - if (!pPF) - { - __debugbreak(); - return false; - } - - // Can't fail from this point on - commit everything. - - STexCacheFileHeader& fh = m_CacheFileHeader; - - // copy image properties - m_nWidth = nWidth; - m_nHeight = nHeight; - m_nDepth = 1; - m_nArraySize = nSides; - m_nMips = nMips; - m_eTT = eTT; - fh.m_nSides = nSides; - m_eTFSrc = eTFSrc; - m_eTFDst = eTFDst; - m_bIsSRGB = pPF->bCanReadSRGB; // OF FIXME: Probably ought to be supplied, and checked against the PF, rather than taken from the PF - assert (!m_pFileTexMips); - m_pFileTexMips = StreamState_AllocateInfo(m_nMips); - m_nStreamingPriority = 0; - SetMinLoadedMip(MAX_MIP_LEVELS); - m_nMinMipVidActive = MAX_MIP_LEVELS; - m_fCurrentMipBias = 0.0f; - m_fAvgBrightness = fAvgBrightness; - m_eSrcTileMode = eTileMode; - m_bStreamed = true; - - // allocate and fill up streaming auxiliary structures - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_Mips = new SMipData[m_CacheFileHeader.m_nSides]; - } - - for (int iSide = 0; iSide < fh.m_nSides; ++iSide) - { - int nTopMipWidth = m_nWidth; - int nTopMipHeight = m_nHeight; - - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - nTopMipWidth = Align(nTopMipWidth, vMipAlign.x); - nTopMipHeight = Align(nTopMipHeight, vMipAlign.y); - - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSize = CTexture::TextureDataSize( - max(1, nTopMipWidth >> iMip), - max(1, nTopMipHeight >> iMip), - 1, 1, 1, m_eTFDst, eTileMode); - } - } - -#if defined(TEXSTRM_STORE_DEVSIZES) - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_DevSideSizeWithMips = CDeviceTexture::TextureDataSize( - max(1, m_nWidth >> iMip), - max(1, m_nHeight >> iMip), - max(1, m_nDepth >> iMip), - m_nMips - iMip, - StreamGetNumSlices(), - m_eTFDst); - } -#endif - - for (int iMip = 0; iMip < m_nMips; iMip++) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSizeWithMips = 0; - for (int j = iMip; j < m_nMips; j++) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSizeWithMips += m_pFileTexMips->m_pMipHeader[j].m_SideSize; - } - } - - m_pPixelFormat = pPF; - fh.m_nMipsPersistent = nMipsPersistent; - - m_pFileTexMips->m_fMinMipFactor = StreamCalculateMipFactor((m_nMips - m_CacheFileHeader.m_nMipsPersistent) << 8); - m_nStreamFormatCode = StreamComputeFormatCode(m_nWidth, m_nHeight, m_nMips, m_eTFDst); - - assert (m_eTFDst != eTF_Unknown); - - StreamPrepare_Platform(); - - SetTexStates(); - PostCreate(); - - Relink(); - m_bStreamPrepared = true; - -#if !defined(NULL_RENDERER) - if (gRenDev->m_pRT->IsRenderThread() && !gRenDev->m_pRT->IsRenderLoadingThread()) - { - // create texture - assert(!m_pFileTexMips->m_pPoolItem); - assert(!IsStreaming()); - STexPoolItem* pNewPoolItem = StreamGetPoolItem(m_nMips - m_CacheFileHeader.m_nMipsPersistent, m_CacheFileHeader.m_nMipsPersistent, true); - if (pNewPoolItem) - { - int nTexWantedMip = m_nMips - m_CacheFileHeader.m_nMipsPersistent; - - // bake persistent mips - for (int i = 0, c = m_composition.size(); i != c; ++i) - { - const STexComposition& tc = m_composition[i]; - CTexture* p = (CTexture*)&*tc.pTexture; - CDeviceTexture* pSrcDevTex = p->m_pDevTexture; - uint32 nSrcDevMips = p->GetNumMipsNonVirtual() - p->StreamGetLoadedMip(); - - CTexture::CopySliceChain( - pNewPoolItem->m_pDevTexture, pNewPoolItem->m_pOwner->m_nMips, tc.nDstSlice, 0, - pSrcDevTex, tc.nSrcSlice, nTexWantedMip - (m_nMips - nSrcDevMips), nSrcDevMips, - m_nMips - nTexWantedMip); - } - - // upload mips to texture - StreamAssignPoolItem(pNewPoolItem, m_nMips - m_CacheFileHeader.m_nMipsPersistent); - StreamReleaseMipsData(0, m_nMips - 1); - SetWasUnload(false); - } - } -#endif - - return true; -} - -bool CTexture::StreamPrepare(CImageFile* pIM) -{ - if (!pIM) - { - return false; - } - - int nWidth = pIM->mfGet_width(); - int nHeight = pIM->mfGet_height(); - int nDepth = pIM->mfGet_depth(); - int nMips = pIM->mfGet_numMips(); - ETEX_Type eTT = pIM->mfGet_NumSides() == 1 ? eTT_2D : eTT_Cube; - int nSides = eTT != eTT_Cube ? 1 : 6; - ETEX_Format eTFSrc = pIM->mfGetFormat(); - ETEX_Format eTFDst = FormatFixup(eTFSrc); - const ColorF& cMinColor = pIM->mfGet_minColor(); - const ColorF& cMaxColor = pIM->mfGet_maxColor(); - ETEX_TileMode eTileMode = pIM->mfGetTileMode(); - -#ifndef _RELEASE - if (eTileMode != eTM_None) - { - if (eTFSrc != eTFDst) - { - __debugbreak(); - } - } -#endif - - int nMipsPersistent = max(pIM->mfGet_numPersistentMips(), DDSSplitted::GetNumLastMips(nWidth, nHeight, nMips, nSides, eTFSrc, (m_nFlags & FT_ALPHA) ? FIM_ALPHA : 0)); - - bool bStreamable = true; - - // Can't stream volume textures and textures without mips - if (eTFDst == eTF_Unknown || nDepth > 1 || nMips < 2) - { - bStreamable = false; - } - - if ((nWidth <= DDSSplitted::etexLowerMipMaxSize || nHeight <= DDSSplitted::etexLowerMipMaxSize) || nMips <= nMipsPersistent || nMipsPersistent == 0) - { - bStreamable = false; - } - - const SPixFormat* pPF = NULL; -#ifndef NULL_RENDERER - ClosestFormatSupported(eTFDst, pPF); -#endif - if (!pPF && !DDSFormats::IsNormalMap(eTFDst)) // special case for 3DC and CTX1 - { - assert(0); - gEnv->pLog->LogError("Failed to load texture '%s': format '%s' is not supported", m_SrcName.c_str(), NameForTextureFormat(m_eTFDst)); - bStreamable = false; - } - - if (!bStreamable) - { - if (m_pFileTexMips) - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - } - m_nFlags |= FT_DONT_STREAM; - m_bStreamed = false; - m_bStreamPrepared = false; - SetWasUnload(false); - SetStreamingInProgress(InvalidStreamSlot); - m_bStreamRequested = false; - m_bNoTexture = false; - return false; - } - - // Can't fail from this point on - commit everything. - m_nFlags &= ~(FT_SPLITTED | FT_TEX_WAS_NOT_PRE_TILED | FT_HAS_ATTACHED_ALPHA | FT_DONT_STREAM | FT_FROMIMAGE); - - STexCacheFileHeader& fh = m_CacheFileHeader; - if (pIM->mfGet_Flags() & FIM_SPLITTED) - { - m_nFlags |= FT_SPLITTED; - } - if (pIM->mfGet_Flags() & FIM_X360_NOT_PRETILED) - { - m_nFlags |= FT_TEX_WAS_NOT_PRE_TILED; - } - if (pIM->mfGet_Flags() & FIM_HAS_ATTACHED_ALPHA) - { - m_nFlags |= FT_HAS_ATTACHED_ALPHA; // if the image has alpha attached we store this in the CTexture - } - // copy image properties - m_nWidth = nWidth; - m_nHeight = nHeight; - m_nDepth = nDepth; - m_nMips = nMips; - m_eTT = eTT; - fh.m_nSides = nSides; - m_eTFSrc = eTFSrc; - m_eTFDst = eTFDst; - m_nFlags |= FT_FROMIMAGE; - m_bUseDecalBorderCol = (pIM->mfGet_Flags() & FIM_DECAL) != 0; - m_bIsSRGB = (pIM->mfGet_Flags() & FIM_SRGB_READ) != 0; - m_SrcName = pIM->mfGet_filename(); - assert (!m_pFileTexMips); - m_pFileTexMips = StreamState_AllocateInfo(m_nMips); - m_nStreamingPriority = 0; - SetMinLoadedMip(MAX_MIP_LEVELS); - m_nMinMipVidActive = MAX_MIP_LEVELS; - m_fCurrentMipBias = 0.0f; - m_cMinColor = cMinColor; - m_cMaxColor = cMaxColor; - m_cClearColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - m_eSrcTileMode = eTileMode; - m_bStreamed = true; - - // base range after normalization, fe. [0,1] for 8bit images, or [0,2^15] for RGBE/HDR data - if ((m_eTFSrc == eTF_R9G9B9E5) || (m_eTFSrc == eTF_BC6UH) || (m_eTFSrc == eTF_BC6SH)) - { - m_cMinColor /= m_cMaxColor.a; - m_cMaxColor /= m_cMaxColor.a; - } - - // allocate and fill up streaming auxiliary structures - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_Mips = new SMipData[m_CacheFileHeader.m_nSides]; - } - - m_pFileTexMips->m_desc = pIM->mfGet_DDSDesc(); - - for (int iSide = 0; iSide < fh.m_nSides; ++iSide) - { - int nTopMipWidth = m_nWidth; - int nTopMipHeight = m_nHeight; - - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - nTopMipWidth = Align(nTopMipWidth, vMipAlign.x); - nTopMipHeight = Align(nTopMipHeight, vMipAlign.y); - - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSize = CTexture::TextureDataSize( - max(1, nTopMipWidth >> iMip), - max(1, nTopMipHeight >> iMip), - 1, 1, 1, m_eTFDst, eTileMode); - } - } - -#if defined(TEXSTRM_STORE_DEVSIZES) - for (int iMip = 0; iMip < m_nMips; ++iMip) - { - m_pFileTexMips->m_pMipHeader[iMip].m_DevSideSizeWithMips = CDeviceTexture::TextureDataSize( - max(1, m_nWidth >> iMip), - max(1, m_nHeight >> iMip), - max(1, m_nDepth >> iMip), - m_nMips - iMip, - StreamGetNumSlices(), - m_eTFDst); - } -#endif - - m_pFileTexMips->m_nSrcStart = pIM->mfGet_StartSeek(); - - for (int iMip = 0; iMip < m_nMips; iMip++) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSizeWithMips = 0; - for (int j = iMip; j < m_nMips; j++) - { - m_pFileTexMips->m_pMipHeader[iMip].m_SideSizeWithMips += m_pFileTexMips->m_pMipHeader[j].m_SideSize; - } - } - - // set up pixel format and check if it's supported for - m_pPixelFormat = pPF; - if (m_pPixelFormat) - { - m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB; - } - else - { - m_bIsSRGB = false; - } - - fh.m_nMipsPersistent = nMipsPersistent; - - assert (m_eTFDst != eTF_Unknown); - - StreamPrepare_Platform(); - - SetTexStates(); - PostCreate(); - - // Always load lowest nMipsPersistent mips synchronously - byte* buf = NULL; - if (m_nMips > 1) - { - int nSyncStartMip = -1; - int nSyncEndMip = -1; - int nStartLowestM = max(0, m_nMips - m_CacheFileHeader.m_nMipsPersistent); - if (nStartLowestM < m_nMinMipVidUploaded) - { - nSyncStartMip = nStartLowestM; - nSyncEndMip = m_nMips - 1; - } - - int nOffs = 0; - assert(nSyncStartMip <= nSyncEndMip); - - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - - for (int iSide = 0; iSide < m_CacheFileHeader.m_nSides; iSide++) - { - nOffs = 0; - for (int iMip = nSyncStartMip, nMipW = max(1, m_nWidth >> iMip), nMipH = max(1, m_nHeight >> iMip); - iMip <= nSyncEndMip; - ++iMip, nMipW = max(1, nMipW >> 1), nMipH = max(1, nMipH >> 1)) - { - STexMipHeader& mh = m_pFileTexMips->m_pMipHeader[iMip]; - SMipData* mp = &mh.m_Mips[iSide]; - if (!mp->DataArray) - { - mp->Init(mh.m_SideSize, Align(nMipW, vMipAlign.x), Align(nMipH, vMipAlign.y)); - } - - if (eTileMode != eTM_None) - { - mp->m_bNative = 1; - } - - int nSrcSideSize = CTexture::TextureDataSize( - max(1, m_nWidth >> iMip), - max(1, m_nHeight >> iMip), - max(1, m_nDepth >> iMip), - 1, 1, m_eTFSrc, eTileMode); - - CTexture::s_nTexturesDataBytesLoaded += nSrcSideSize; - if (iSide == 0 || (m_nFlags & FT_REPLICATE_TO_ALL_SIDES) == 0) - { - assert(pIM->mfIs_image(iSide)); - buf = pIM->mfGet_image(iSide); - cryMemcpy(&mp->DataArray[0], &buf[nOffs], nSrcSideSize); - nOffs += nSrcSideSize; - } - else if (iSide > 0) - { - if (m_nFlags & FT_REPLICATE_TO_ALL_SIDES) - { - memcpy(&mp->DataArray[0], &mh.m_Mips[0].DataArray[0], nSrcSideSize); - } - else - { - assert(0); - } - } - else - { - assert(0); - } - } - } - } - - // store file position on DVD - { - if (m_nFlags & FT_SPLITTED) - { - for (int i = 0; i < m_nMips - m_CacheFileHeader.m_nMipsPersistent; ++i) - { - const int chunkNumber = i >= (m_nMips - m_CacheFileHeader.m_nMipsPersistent) ? 0 : m_nMips - i - m_CacheFileHeader.m_nMipsPersistent; - - DDSSplitted::TPath sLastChunkName; - DDSSplitted::MakeName(sLastChunkName, m_SrcName.c_str(), chunkNumber, FIM_SPLITTED | ((GetFlags() & FT_ALPHA) ? FIM_ALPHA : 0)); - m_pFileTexMips->m_pMipHeader[i].m_eMediaType = gEnv->pCryPak->GetFileMediaType(sLastChunkName.c_str()); - } - } - } - - m_pFileTexMips->m_fMinMipFactor = StreamCalculateMipFactor((m_nMips - m_CacheFileHeader.m_nMipsPersistent) << 8); - m_nStreamFormatCode = StreamComputeFormatCode(m_nWidth, m_nHeight, m_nMips, m_eTFDst); - - Relink(); - -#if defined(TEXTURE_GET_SYSTEM_COPY_SUPPORT) && !defined(NULL_RENDERER) - if (m_nFlags & FT_KEEP_LOWRES_SYSCOPY) - { - PrepareLowResSystemCopy(pIM->mfGet_image(0), false); - } -#endif - - return true; -} - -bool CTexture::StreamPrepare_Finalise([[maybe_unused]] bool bFromLoad) -{ - LOADING_TIME_PROFILE_SECTION; - - assert(m_pFileTexMips); - for (int iSide = 0; iSide < m_CacheFileHeader.m_nSides; ++iSide) - { - for (int iMip = m_nMips - m_CacheFileHeader.m_nMipsPersistent; iMip < m_nMips; iMip++) - { - STexMipHeader& mh = m_pFileTexMips->m_pMipHeader[iMip]; - SMipData* mp = &mh.m_Mips[iSide]; - assert(mp->DataArray); - - // If native, assume we're tiled and prepped for the device - we shouldn't need to expand. - if (!mp->m_bNative) - { - int nSrcSideSize = TextureDataSize(max(1, m_nWidth >> iMip), max(1, m_nHeight >> iMip), max(1, m_nDepth >> iMip), 1, 1, m_eTFSrc); - ExpandMipFromFile(mp->DataArray, mh.m_SideSize, mp->DataArray, nSrcSideSize, m_eTFSrc); - } - } - } - - { - // create texture - assert(!m_pFileTexMips->m_pPoolItem); - assert(!IsStreaming()); - STexPoolItem* pNewPoolItem = StreamGetPoolItem(m_nMips - m_CacheFileHeader.m_nMipsPersistent, m_CacheFileHeader.m_nMipsPersistent, true, true); - if (!pNewPoolItem) - { - gEnv->pLog->LogError("CTexture::StreamPrepare: Failed to allocate memory for persistent mip chain! Texture: '%s'", m_SrcName.c_str()); - CRY_ASSERT(false); - CTexture::s_bOutOfMemoryTotally = true; - return false; - } - - // upload mips to texture - StreamAssignPoolItem(pNewPoolItem, m_nMips - m_CacheFileHeader.m_nMipsPersistent); - StreamReleaseMipsData(0, m_nMips - 1); - SetWasUnload(false); - } - - for (int z = 0; z < MAX_PREDICTION_ZONES; z++) - { - m_streamRounds[z].nRoundUpdateId = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_arrZonesRoundId[z]; - } - m_bPostponed = false; - m_fCurrentMipBias = 0.f; - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER - if (!m_bStatTracked) - { - ITextureStreamListener* pListener = s_pStreamListener; - m_bStatTracked = 1; - if (pListener) - { - pListener->OnCreatedStreamedTexture(this, m_SrcName.c_str(), m_nMips, m_nMips - GetNumPersistentMips()); - } - } -#endif - - m_bStreamPrepared = true; - - return true; -} - -//========================================================================= -void CTexture::StreamValidateTexSize() -{ - return; -} - -uint8 CTexture::StreamComputeFormatCode(uint32 nWidth, uint32 nHeight, uint32 nMips, ETEX_Format fmt) -{ - // Must have a dimension - if (nWidth == 0) - { - return 0; - } - if (nHeight == 0) - { - return 0; - } - - // Must be PoT - if (nWidth & (nWidth - 1)) - { - return 0; - } - if (nHeight & (nHeight - 1)) - { - return 0; - } - - uint32 nMaxDim = 1 << (SStreamFormatCode::MaxMips - 1); - - // Determine how many missing tail mips there are - uint32 nFullMips = IntegerLog2(max(nWidth, nHeight)) + 1; - uint32 nTailMips = nFullMips - nMips; - - // Shift upto find aspect - while ((nWidth != nMaxDim) && (nHeight != nMaxDim)) - { - nWidth <<= 1; - nHeight <<= 1; - } - - SStreamFormatCodeKey key(nWidth, nHeight, fmt, (uint8)nTailMips); - - CryAutoLock lock(s_streamFormatLock); - TStreamFormatCodeKeyMap::iterator it = s_formatCodeMap.find(key); - if (it == s_formatCodeMap.end()) - { - if (s_nFormatCodes == 256) - { - __debugbreak(); - } - - SStreamFormatCode code; - memset(&code, 0, sizeof(code)); - for (uint32 nMip = nTailMips, nMipWidth = nWidth, nMipHeight = nHeight; nMip < SStreamFormatCode::MaxMips; ++nMip, nMipWidth = max(1u, nMipWidth >> 1), nMipHeight = max(1u, nMipHeight >> 1)) - { - uint32 nMip1Size = CDeviceTexture::TextureDataSize(nMipWidth, nMipHeight, 1, SStreamFormatCode::MaxMips - nMip, 1, fmt); - - bool bAppearsLinear = true; - bool bAppearsPoT = true; - - // Determine how the size function varies with slices. Currently only supports linear, or aligning slices to next pot - for (uint32 nSlices = 1; nSlices <= 32; ++nSlices) - { - uint32 nMipSize = CDeviceTexture::TextureDataSize(nMipWidth, nMipHeight, 1, SStreamFormatCode::MaxMips - nMip, nSlices, fmt); - - uint32 nExpectedLinearSize = nMip1Size * nSlices; - uint32 nAlignedSlices = 1u << (32 - (nSlices > 1 ? countLeadingZeros32(nSlices - 1) : 32)); - uint32 nExpectedPoTSize = nMip1Size * nAlignedSlices; - if (nExpectedLinearSize != nMipSize) - { - bAppearsLinear = false; - } - if (nExpectedPoTSize != nMipSize) - { - bAppearsPoT = false; - } - } - - // If this fires, we can't encode the size(slices) function - if (!bAppearsLinear && !bAppearsPoT) - { - __debugbreak(); - } - - code.sizes[nMip].size = nMip1Size; - code.sizes[nMip].alignSlices = !bAppearsLinear && bAppearsPoT; - } - - it = s_formatCodeMap.insert(std::make_pair(key, s_nFormatCodes)).first; - s_formatCodes[s_nFormatCodes++] = code; - } - return it->second; -} - -#ifdef ENABLE_TEXTURE_STREAM_LISTENER -void CTexture::StreamUpdateStats() -{ - ITextureStreamListener* pListener = s_pStreamListener; - if (pListener) - { - void* pBegunUsing[512]; - void* pStoppedUsing[512]; - - int nBegun = 0, nStopped = 0; - int curFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - std::vector texs; - s_pTextureStreamer->StatsFetchTextures(texs); - - for (std::vector::const_iterator it = texs.begin(), itEnd = texs.end(); it != itEnd; ++it) - { - CTexture* pTex = *it; - if (curFrame - pTex->m_nAccessFrameID <= 2) - { - // In use - if (!pTex->m_bUsedRecently) - { - pTex->m_bUsedRecently = 1; - pBegunUsing[nBegun++] = pTex; - - IF_UNLIKELY (nBegun == sizeof(pBegunUsing) / sizeof(pBegunUsing[0])) - { - pListener->OnBegunUsingTextures(pBegunUsing, nBegun); - nBegun = 0; - } - } - } - else - { - if (pTex->m_bUsedRecently) - { - pTex->m_bUsedRecently = 0; - pStoppedUsing[nStopped++] = pTex; - - IF_UNLIKELY (nStopped == sizeof(pStoppedUsing) / sizeof(pStoppedUsing[0])) - { - pListener->OnEndedUsingTextures(pStoppedUsing, nStopped); - nStopped = 0; - } - } - } - } - - if (nBegun) - { - pListener->OnBegunUsingTextures(pBegunUsing, nBegun); - } - if (nStopped) - { - pListener->OnEndedUsingTextures(pStoppedUsing, nStopped); - } - } -} -#endif - -//the format on disk must match exactly the format in memory -bool CTexture::CanStreamInPlace([[maybe_unused]] int nMip, [[maybe_unused]] STexPoolItem* pNewPoolItem) -{ -#if defined(SUPPORTS_INPLACE_TEXTURE_STREAMING) - if (CRenderer::CV_r_texturesstreamingInPlace) - { -#if TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_ETT_2D_EARLY_OUT - if (m_eTT != eTT_2D) - { - return false; - } -#endif - -#if TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_FORMATCOMPATIBLE - bool bFormatCompatible = false; - - switch (m_eTFSrc) - { - case eTF_DXT1: - case eTF_DXT3: - case eTF_DXT5: - case eTF_A8: - case eTF_R32F: - case eTF_R16G16F: - case eTF_R16G16S: - case eTF_B4G4R4A4: - case eTF_R16G16B16A16F: - case eTF_3DC: - case eTF_3DCP: - case eTF_CTX1: - case eTF_BC6UH: - case eTF_BC7: - case eTF_R9G9B9E5: - case eTF_EAC_R11: - case eTF_EAC_RG11: - case eTF_ETC2: - case eTF_ETC2A: -#ifdef CRY_USE_METAL - case eTF_PVRTC2: - case eTF_PVRTC4: -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case eTF_ASTC_4x4: - case eTF_ASTC_5x4: - case eTF_ASTC_5x5: - case eTF_ASTC_6x5: - case eTF_ASTC_6x6: - case eTF_ASTC_8x5: - case eTF_ASTC_8x6: - case eTF_ASTC_8x8: - case eTF_ASTC_10x5: - case eTF_ASTC_10x6: - case eTF_ASTC_10x8: - case eTF_ASTC_10x10: - case eTF_ASTC_12x10: - case eTF_ASTC_12x12: -#endif - bFormatCompatible = true; - break; - - default: - bFormatCompatible = false; - break; - } - - if (!bFormatCompatible) - { - return false; - } - - if (m_nFlags & FT_TEX_WAS_NOT_PRE_TILED) - { - return false; - } -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif - -#if TEXTURESTREAMING_CPP_TRAIT_CANSTREAMINPLACE_SRCTILEMODE_CHECK && !defined(NULL_RENDERER) - CDeviceTexture* pDevTex = pNewPoolItem->m_pDevTexture; - if (m_eSrcTileMode != eTM_LinearPadded || !pDevTex->IsInPool() || !m_pFileTexMips->m_pMipHeader[nMip].m_InPlaceStreamable) - { - return false; - } -#endif - - return true; - } -#endif - return false; -} - -#if defined(TEXSTRM_ASYNC_TEXCOPY) -bool CTexture::CanAsyncCopy() -{ -#if defined(TEXSTRM_CUBE_DMA_BROKEN) - return m_eTT == eTT_2D; -#else - return true; -#endif -} -#endif - -bool CTexture::StartStreaming(CTexture* pTex, STexPoolItem* pNewPoolItem, const int nStartMip, const int nEndMip, const int nActivateMip, EStreamTaskPriority estp) -{ - FUNCTION_PROFILER_RENDERER; - - CHK_RENDTH; - - if (pTex->TryAddRef() > 0) - { - if (pTex->IsStreaming()) - { - __debugbreak(); - } - - if (pTex->m_eTT != eTT_2D && pTex->m_eTT != eTT_Cube) - { - __debugbreak(); - } - - STexStreamInState* pStreamState = StreamState_AllocateIn(); - if (pStreamState) - { - DDSSplitted::ChunkInfo chunks[16]; - - DDSSplitted::DDSDesc desc = pTex->m_pFileTexMips->m_desc; - desc.pName = pTex->m_SrcName.c_str(); - - int nDeltaMips = desc.nMips - pTex->m_nMips; - - size_t nNumChunks = DDSSplitted::GetFilesToRead(chunks, 16, desc, nStartMip + nDeltaMips, nEndMip + nDeltaMips); - - StreamReadBatchParams streamRequests[STexStreamInState::MaxStreams]; - - size_t nStreamRequests = 0; - - pStreamState->m_pTexture = pTex; - - pStreamState->m_pNewPoolItem = pNewPoolItem; -#ifndef _RELEASE - pStreamState->m_fStartTime = iTimer->GetAsyncTime().GetSeconds(); -#endif - pStreamState->m_nAsyncRefCount = 0; - pStreamState->m_nHigherUploadedMip = nStartMip; - pStreamState->m_nLowerUploadedMip = nStartMip + nNumChunks - 1; - pStreamState->m_nActivateMip = nActivateMip; - - // update streaming frame ID - int nSizeToSubmit = 0; - - int nSides = pTex->GetNumSides(); - - for (DDSSplitted::ChunkInfo* it = chunks, * itEnd = chunks + nNumChunks; it != itEnd; ++it) - { - const DDSSplitted::ChunkInfo& chunk = *it; - - assert(chunk.nMipLevel >= nStartMip); - - uint32 nChunkMip = chunk.nMipLevel - nDeltaMips; - uint16 nMipIdx = nChunkMip - nStartMip; - - STexStreamInMipState& mipState = pStreamState->m_mips[nMipIdx]; - mipState.m_nSideDelta = chunk.nSideDelta; - - StreamReadParams baseParams; - baseParams.nFlags |= IStreamEngine::FLAGS_NO_SYNC_CALLBACK; - baseParams.dwUserData = nMipIdx; - baseParams.nLoadTime = 1; - baseParams.nMaxLoadTime = 4; - baseParams.ePriority = estp; - baseParams.nOffset = chunk.nOffsetInFile; - baseParams.nSize = chunk.nSizeInFile; - baseParams.nPerceptualImportance = nEndMip - nStartMip; - baseParams.eMediaType = (EStreamSourceMediaType)pTex->m_pFileTexMips->m_pMipHeader[nChunkMip].m_eMediaType; - - if (pTex->CanStreamInPlace(nChunkMip, pNewPoolItem)) - { - streamRequests[nStreamRequests].params = baseParams; - - byte* pBaseAddress = NULL; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION TEXTURESTREAMING_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(TextureStreaming_cpp) -#endif - - if (pBaseAddress) - { - streamRequests[nStreamRequests].params.pBuffer = pBaseAddress; - mipState.m_bStreamInPlace = true; - } - - streamRequests[nStreamRequests].pCallback = pStreamState; - streamRequests[nStreamRequests].szFile = chunk.fileName.c_str(); - streamRequests[nStreamRequests].tSource = eStreamTaskTypeTexture; - ++nStreamRequests; - ++pStreamState->m_nAsyncRefCount; - } - else - { - streamRequests[nStreamRequests].params = baseParams; - streamRequests[nStreamRequests].pCallback = pStreamState; - streamRequests[nStreamRequests].szFile = chunk.fileName.c_str(); - streamRequests[nStreamRequests].tSource = eStreamTaskTypeTexture; - ++nStreamRequests; - ++pStreamState->m_nAsyncRefCount; - } - - nSizeToSubmit += pTex->m_pFileTexMips->m_pMipHeader[nChunkMip].m_SideSize * nSides; - } - - AZStd::function updateTextureByteCounterAtomic = [&nSizeToSubmit]() - { - CryInterlockedAdd(s_nBytesSubmittedToStreaming.Addr(), nSizeToSubmit); - }; - - size_t nStreams = gEnv->pSystem->GetStreamEngine()->StartBatchRead(pStreamState->m_pStreams, streamRequests, nStreamRequests, &updateTextureByteCounterAtomic); - - if (nStreams) - { - pTex->SetStreamingInProgress(s_StreamInTasks.GetIdxFromPtr(pStreamState)); - - CryInterlockedAdd(s_nMipsSubmittedToStreaming.Addr(), (int)nStreams); - - return true; - } - else - { - pStreamState->m_pTexture->Release(); - pStreamState->m_pTexture = NULL; - StreamState_ReleaseIn(pStreamState); - } - } - else - { - s_pPoolMgr->ReleaseItem(pNewPoolItem); - pTex->Release(); - } - } - else - { - s_pPoolMgr->ReleaseItem(pNewPoolItem); - } - - return false; -} - -void CTexture::StreamUploadMips(int nStartMip, int nEndMip, STexPoolItem* pNewPoolItem) -{ - assert (pNewPoolItem); - CTimeValue time0 = iTimer->GetAsyncTime(); - - StreamCopyMipsTexToMem(nStartMip, nEndMip, true, pNewPoolItem); - - // Restore mips data from the device texture - if (s_bStreamDontKeepSystem && m_pFileTexMips && m_pFileTexMips->m_pPoolItem) - { - STexPoolItem* pSrcItem = m_pFileTexMips->m_pPoolItem; - int nSrcOffset = m_nMips - pSrcItem->m_pOwner->m_nMips; - int nDstOffset = m_nMips - pNewPoolItem->m_pOwner->m_nMips; - StreamCopyMipsTexToTex(pSrcItem, (nEndMip + 1) - nSrcOffset, pNewPoolItem, (nEndMip + 1) - nDstOffset, m_nMips - (nEndMip + 1)); - } - - if (s_bStreamDontKeepSystem) - { - StreamReleaseMipsData(nStartMip, nEndMip); - } - - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_fTexUploadTime += (iTimer->GetAsyncTime() - time0).GetSeconds(); -} - -void CTexture::InitStreaming() -{ - CHK_MAINORRENDTH; - - iLog->Log("Init textures management (%" PRISIZE_T " Mb of video memory is available)...", gRenDev->m_MaxTextureMemory / 1024 / 1024); - - // reset all statistics - s_nStreamingThroughput = 0; - s_nStreamingTotalTime = 0; - - InitStreamingDev(); - - if (!s_pTextureStreamer || s_nStreamingUpdateMode != CRenderer::CV_r_texturesstreamingUpdateType) - { - delete s_pTextureStreamer; - - switch (CRenderer::CV_r_texturesstreamingUpdateType) - { - default: - case 1: - s_pTextureStreamer = new CPlanningTextureStreamer(); - break; - } - - s_nStreamingUpdateMode = CRenderer::CV_r_texturesstreamingUpdateType; - } - - if (!s_pPoolMgr) - { - s_pPoolMgr = new CTextureStreamPoolMgr(); - } - - -#if !defined(CONSOLE) - if (CRenderer::CV_r_texturesstreaming) - { - int nMinTexStreamPool = 192; -#ifdef NULL_RENDERER - // Dedicated server uses CNULLRenderer, which doesn't report any available - // memory via gRenDev->m_MaxTextureMemory, so use a magic number. It's OK - // to use it here, as a dedicated server will not load textures anyway. - int nMaxTexStreamPool = 8192; -#else - int nMaxTexStreamPool = (gRenDev->m_MaxTextureMemory / 1024 / 1024); -#endif - - ICVar* pICVarTexRes = iConsole->GetCVar("sys_spec_TextureResolution"); - if (pICVarTexRes) - { - const int valTexRes = pICVarTexRes->GetIVal(); - if (valTexRes == 0) - { - // Some cards report slightly lower byte numbers than their spec in MB suggests, so we have to be conservative - // Note: On some MGPU systems the memory reported is the overall amount and not the memory available per GPU - if (gRenDev->m_MaxTextureMemory >= (size_t)2800 * 1024 * 1024) - { - pICVarTexRes->Set(VERYHIGH_SPEC_PC); - } - else if (gRenDev->m_MaxTextureMemory >= (size_t)1900 * 1024 * 1024) - { - pICVarTexRes->Set(HIGH_SPEC_PC); - } - else if (gRenDev->m_MaxTextureMemory >= (size_t)1450 * 1024 * 1024) - { - pICVarTexRes->Set(MEDIUM_SPEC_PC); - } - else - { - pICVarTexRes->Set(LOW_SPEC_PC); - } - } - else - { - pICVarTexRes->Set(valTexRes); - } - } - - AZ_WarningOnce("TextureStreaming", CRenderer::CV_r_TexturesStreamPoolSize <= (nMaxTexStreamPool * 0.75f), "Warning! You are assigning more than 75 percent of total available GPU memory to texture streaming!"); - - CRenderer::CV_r_TexturesStreamPoolSize = clamp_tpl(CRenderer::CV_r_TexturesStreamPoolSize, nMinTexStreamPool, nMaxTexStreamPool); - - // Don't skip mips in the editor so that assets can be viewed in full resolution - if (gEnv->IsEditor()) - { - CRenderer::CV_r_texturesstreamingSkipMips = 0; - } - } -#endif - - s_nStreamingMode = CRenderer::CV_r_texturesstreaming; - - s_bStreamDontKeepSystem = CRenderer::CV_r_texturesstreamingonlyvideo == 0; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texturesstreaming) - { - iLog->Log(" Enabling of textures streaming..."); - iLog->Log(" Using %d Mb of textures pool for streaming...", CRenderer::GetTexturesStreamPoolSize()); - } - else - { - iLog->Log(" Disabling of textures streaming..."); - } - - if (gRenDev->m_MaxTextureMemory <= 256 * 1024 * 1024) - { - SDynTexture::s_CurDynTexAtlasCloudsMaxsize = min(24u, SDynTexture::s_CurDynTexAtlasCloudsMaxsize); - SDynTexture::s_CurTexAtlasSize = min(128u, SDynTexture::s_CurTexAtlasSize); - SDynTexture::s_CurDynTexMaxSize = min(128u, SDynTexture::s_CurDynTexMaxSize); - } - iLog->Log(" Video textures: Atlas clouds max size: %d Mb", SDynTexture::s_CurDynTexAtlasCloudsMaxsize); - iLog->Log(" Video textures: Dynamic managed max size: %d Mb", SDynTexture::s_CurDynTexMaxSize); - - // re-init all textures - iLog->Log(" Reloading all textures..."); - { - AUTO_LOCK(CBaseResource::s_cResLock); - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - if (pRL) - { - for (ResourcesMapItor itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); ++itor) - { - CTexture* tp = (CTexture*)itor->second; - if (!tp) - { - continue; - } - tp->ToggleStreaming(CRenderer::CV_r_texturesstreaming != 0); - } - } - } - iLog->Log(" Finished reloading textures..."); - iLog->Log(" Finished initializing textures streaming..."); - - if (gEnv->pLocalMemoryUsage) - { - gEnv->pLocalMemoryUsage->DeleteGlobalData(); - } -} - -void CTexture::RT_FlushStreaming(bool bAbort) -{ - RT_FlushAllStreamingTasks(bAbort); - - // flush all pool items - s_pPoolMgr->GarbageCollect(NULL, 0, 10000000); -} - -void CTexture::RT_FlushAllStreamingTasks(const bool bAbort /* = false*/) -{ - // flush all tasks globally - AZ_TRACE_METHOD(); - CHK_RENDTH; - iLog->Log("Flushing pended textures..."); - -#ifdef TEXSTRM_ASYNC_TEXCOPY - { - for (int i = 0; i < MaxStreamTasks; ++i) - { - STexStreamOutState& os = *s_StreamOutTasks.GetPtrFromIdx(i); - if (os.m_pTexture) - { - if (bAbort) - { - os.m_bAborted = true; - } - os.m_jobExecutor.WaitForCompletion(); - } - } - } -#endif - - if (bAbort) - { - for (int i = 0; i < MaxStreamPrepTasks; ++i) - { - STexStreamPrepState*& ps = *s_StreamPrepTasks.GetPtrFromIdx(i); - if (ps) - { - _smart_ptr pFile = ps->m_pImage; - - if (pFile) - { - pFile->mfAbortStreaming(); - } - - delete ps; - ps = NULL; - s_StreamPrepTasks.Release(&ps); - } - } - } - - { - for (int i = 0; i < MaxStreamTasks; ++i) - { - STexStreamInState& ins = *s_StreamInTasks.GetPtrFromIdx(i); - if (ins.m_pTexture) - { - if (bAbort) - { - ins.m_bAborted = true; - } - - for (int m = 0; m < (ins.m_nLowerUploadedMip - ins.m_nHigherUploadedMip) + 1; ++m) - { - IReadStreamPtr pStream = ins.m_pStreams[m]; - if (pStream) - { - if (bAbort) - { - pStream->Abort(); - } - else - { - pStream->Wait(); - } - } - } - } - } - } - - StreamState_Update(); - StreamState_UpdatePrep(); - - s_pTextureStreamer->Flush(); - - assert(s_nBytesSubmittedToStreaming == 0); - iLog->Log("Finished flushing pended textures..."); -} - -void CTexture::AbortStreamingTasks(CTexture* pTex) -{ - if (pTex->m_nStreamSlot != InvalidStreamSlot) - { - CHK_RENDTH; - if (pTex->m_nStreamSlot & StreamOutMask) - { -#ifdef TEXSTRM_ASYNC_TEXCOPY - STexStreamOutState& streamState = *s_StreamOutTasks.GetPtrFromIdx(pTex->m_nStreamSlot & StreamIdxMask); - -#ifndef _RELEASE - if (streamState.m_pTexture != pTex) - { - __debugbreak(); - } -#endif - - streamState.m_bAborted = true; - if (!streamState.m_bDone) - { - streamState.m_jobExecutor.WaitForCompletion(); - } - while (!streamState.TryCommit()) - { - CrySleep(0); - } - StreamState_ReleaseOut(&streamState); -#endif - } - else if (pTex->m_nStreamSlot & StreamPrepMask) - { - STexStreamPrepState*& pStreamState = *s_StreamPrepTasks.GetPtrFromIdx(pTex->m_nStreamSlot & StreamIdxMask); - -#ifndef _RELEASE - if (pStreamState->m_pTexture != pTex) - { - __debugbreak(); - } -#endif - - delete pStreamState; - pStreamState = NULL; - s_StreamPrepTasks.Release(&pStreamState); - } - else - { - STexStreamInState& streamState = *s_StreamInTasks.GetPtrFromIdx(pTex->m_nStreamSlot & StreamIdxMask); - -#ifndef _RELEASE - if (streamState.m_pTexture != pTex) - { - __debugbreak(); - } -#endif - - streamState.m_bAborted = true; - - for (size_t i = 0, c = streamState.m_nLowerUploadedMip - streamState.m_nHigherUploadedMip + 1; i < c; ++i) - { - IReadStream* pStream = streamState.m_pStreams[i]; - if (pStream) - { - pStream->Abort(); - assert (streamState.m_pStreams[i] == NULL); - } - } - -#ifndef NDEBUG - bool bCommitted = -#endif - streamState.TryCommit(); - assert (bCommitted); - - StreamState_ReleaseIn(&streamState); - } - } -} - -void CTexture::StreamState_Update() -{ - CHK_RENDTH; - - FUNCTION_PROFILER_RENDERER; - - // Finalise and garbage collect the stream out tasks - -#ifdef TEXSTRM_ASYNC_TEXCOPY - for (size_t i = 0, c = s_StreamOutTasks.GetNumLive(); i < MaxStreamTasks && c > 0; ++i) - { - STexStreamOutState& state = *s_StreamOutTasks.GetPtrFromIdx(i); - if (state.m_pTexture) - { - if (state.TryCommit()) - { - StreamState_ReleaseOut(&state); - } - - --c; - } - } -#endif - - // Garbage collect the stream in slots - - for (size_t i = 0, c = s_StreamInTasks.GetNumLive(); i < MaxStreamTasks && c > 0; ++i) - { - STexStreamInState& state = *s_StreamInTasks.GetPtrFromIdx(i); - if (state.m_pTexture) - { - if (state.m_bAllStreamsComplete) - { - if (state.TryCommit()) - { - StreamState_ReleaseIn(&state); - } - } - else if (state.m_bAborted) - { - // An error occurred. Try and cancel all the stream tasks. - for (int mi = 0, mc = state.m_nLowerUploadedMip - state.m_nHigherUploadedMip + 1; mi != mc; ++mi) - { - IReadStream* pStream = &*state.m_pStreams[mi]; - if (pStream != NULL) - { - pStream->TryAbort(); - } - } - } - - --c; - } - } -} - -void CTexture::StreamState_UpdatePrep() -{ - FUNCTION_PROFILER_RENDERER; - LOADING_TIME_PROFILE_SECTION; - - // Garbage collect the stream prep slots - - for (size_t i = 0, c = s_StreamPrepTasks.GetNumLive(); i < MaxStreamPrepTasks && c > 0; ++i) - { - STexStreamPrepState*& pState = *s_StreamPrepTasks.GetPtrFromIdx(i); - if (pState && pState->m_bCompleted && pState->Commit()) - { - s_pTextureStreamer->EndPrepare(pState); - } - } -} - -STexStreamInState* CTexture::StreamState_AllocateIn() -{ - CHK_RENDTH; - return s_StreamInTasks.Allocate(); -} - -void CTexture::StreamState_ReleaseIn(STexStreamInState* pState) -{ - CHK_RENDTH; - - pState->Reset(); - s_StreamInTasks.Release(pState); -} - -#ifdef TEXSTRM_ASYNC_TEXCOPY -STexStreamOutState* CTexture::StreamState_AllocateOut() -{ - CHK_RENDTH; - return s_StreamOutTasks.Allocate(); -} - -void CTexture::StreamState_ReleaseOut(STexStreamOutState* pState) -{ - CHK_RENDTH; - - pState->Reset(); - s_StreamOutTasks.Release(pState); -} -#endif - -STexStreamingInfo* CTexture::StreamState_AllocateInfo(int nMips) -{ - // Temporary - will be replaced by custom allocator later. - STexStreamingInfo* pInfo = (STexStreamingInfo*)CryModuleMalloc(sizeof(STexStreamingInfo)); - new (pInfo) STexStreamingInfo(nMips); - return pInfo; -} - -void CTexture::StreamState_ReleaseInfo(CTexture* pOwnerTex, STexStreamingInfo* pInfo) -{ - // Make sure we the streamer is notified, so jobs can be synced with - s_pTextureStreamer->OnTextureDestroy(pOwnerTex); - - pInfo->~STexStreamingInfo(); - CryModuleFree(pInfo); -} diff --git a/Code/CryEngine/RenderDll/Common/TypedConstantBuffer.h b/Code/CryEngine/RenderDll/Common/TypedConstantBuffer.h deleted file mode 100644 index 00a51227cd..0000000000 --- a/Code/CryEngine/RenderDll/Common/TypedConstantBuffer.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once -#include "DevBuffer.h" - -#ifndef NULL_RENDERER -#include "DriverD3D.h" -#endif - -template -class CTypedConstantBuffer -{ - T m_hostBuffer; - AzRHI::ConstantBufferPtr m_constantBuffer; - -public: - CTypedConstantBuffer() - : m_constantBuffer(nullptr) {} - CTypedConstantBuffer(const CTypedConstantBuffer& cb) - : m_constantBuffer(nullptr) { m_hostBuffer = cb.m_hostBuffer; } - CTypedConstantBuffer(AzRHI::ConstantBufferPtr incb) - : m_constantBuffer(incb) {} - - bool IsDeviceBufferAllocated() { return m_constantBuffer != nullptr; } - AzRHI::ConstantBufferPtr GetDeviceConstantBuffer() - { - if (!m_constantBuffer) - { - CreateDeviceBuffer(); - } - return m_constantBuffer; - } - - void CreateDeviceBuffer() - { -#ifndef NULL_RENDERER - int size = sizeof(T); - AzRHI::ConstantBuffer* cb = gcpRendD3D->m_DevBufMan.CreateConstantBuffer( - "TypedConstantBuffer", - size, - AzRHI::ConstantBufferUsage::Dynamic); // TODO: this could be a good candidate for dynamic=false - m_constantBuffer.attach(cb); - CopyToDevice(); -#endif - } - - T& GetData() - { - return m_hostBuffer; - } - - void CopyToDevice() - { - m_constantBuffer->UpdateBuffer(&m_hostBuffer, sizeof(m_hostBuffer)); - } - - T* operator->() { return &m_hostBuffer; } - T& operator=(const T& hostData) - { - return m_hostBuffer = hostData; - } -}; diff --git a/Code/CryEngine/RenderDll/Common/WaterUtils.cpp b/Code/CryEngine/RenderDll/Common/WaterUtils.cpp deleted file mode 100644 index 12997d780a..0000000000 --- a/Code/CryEngine/RenderDll/Common/WaterUtils.cpp +++ /dev/null @@ -1,728 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define WATERUTILS_CPP_SECTION_1 1 -#define WATERUTILS_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION WATERUTILS_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(WaterUtils_cpp) -#endif - -#include -#include - -#define WATER_UPDATE_THREAD_NAME "WaterUpdate" - -#define g_nGridSize 64 -#define g_nGridLogSize 6 - -static float gaussian_y2; -static int gaussian_use_last = 0; - -#define m_nGridSize (int)g_nGridSize -#define m_nLogGridSize (int)g_nGridLogSize // log2(64) -#define m_fG (9.81f) - -// potential todo list: -// - vectorizing/use intrinsics -// - support for N sized grids -// - support for gpu update -// - tiled grid updates ? - -struct SWaterUpdateThreadInfo -{ - int nFrameID; - float fTime; - bool bOnlyHeight; -}; - -class CWaterSim -{ - typedef std::complex complexF; - -public: - - CWaterSim() - : m_fA(1.0f) - , m_fWorldSizeX(1.0f) - , m_fWorldSizeY(1.0f) - , m_fWorldSizeXInv(1.f) - , m_fWorldSizeYInv(1.0f) - , m_fMaxWaveSize(200.0f) - , m_fChoppyWaveScale(400.0f) - , m_nFrameID(0) - { - uint32 nSize = m_nGridSize * m_nGridSize * sizeof(complexF); - memset(&m_pFourierAmps[0], 0, nSize); - memset(&m_pHeightField[0], 0, nSize); - memset(&m_pDisplaceFieldX[0], 0, nSize); - memset(&m_pDisplaceFieldY[0], 0, nSize); - - nSize = m_nGridSize * m_nGridSize * sizeof(Vec4); - memset(m_pDisplaceGrid[0], 0, nSize); - memset(m_pDisplaceGrid[1], 0, nSize); - memset(m_pLUTK, 0, nSize); - - m_nWorkerThreadID = m_nFillThreadID = 0; - m_bQuit = false; - } - - virtual ~CWaterSim() - { - Release(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - virtual void Create(float fA, float fWorldSizeX, float fWorldSizeY) // Create/Initialize water simulation - { - m_fA = fA; - m_fWorldSizeX = fWorldSizeX; - m_fWorldSizeY = fWorldSizeY; - m_fWorldSizeXInv = 1.f / m_fWorldSizeX; - m_fWorldSizeYInv = 1.f / m_fWorldSizeY; - InitTableK(); - InitFourierAmps(); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - virtual void Release() - { - uint32 nSize = m_nGridSize * m_nGridSize * sizeof(std::complex); - memset(&m_pFourierAmps[0], 0, nSize); - memset(&m_pHeightField[0], 0, nSize); - memset(&m_pDisplaceFieldX[0], 0, nSize); - memset(&m_pDisplaceFieldY[0], 0, nSize); - - nSize = m_nGridSize * m_nGridSize * sizeof(Vec4); - memset(m_pDisplaceGrid, 0, nSize); - memset(m_pLUTK, 0, nSize); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - virtual void SaveToDisk([[maybe_unused]] const char* pszFileName) - { - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - // Returns (-1)^n - int powNeg1(int n) - { - int pow[2] = { 1, -1 }; - return pow[n & 1]; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - // gaussian random number, using box muller technique - float frand_gaussian(float m = 0.0f, float s = 1.0f) // m- mean, s - standard deviation - { - float x1, x2, w, y1; - if (gaussian_use_last) // use value from previous call - { - y1 = gaussian_y2; - gaussian_use_last = 0; - } - else - { - do - { - x1 = cry_random(-1.0f, 1.0f); - x2 = cry_random(-1.0f, 1.0f); - - w = x1 * x1 + x2 * x2; - } - while (w >= 1.0f); - - w = sqrt_fast_tpl((-2.0f * log_tpl(w)) / w); - y1 = x1 * w; - gaussian_y2 = x2 * w; - - gaussian_use_last = 1; - } - - return (m + y1 * s); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////u/////////////////////////////////////////////////////////////////// - - inline int GetGridOffset(const int& x, const int& y) const - { - return y * m_nGridSize + x; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - int GetMirrowedGridOffset(const int& x, const int& y) const - { - return GetGridOffset((m_nGridSize - x) & (m_nGridSize - 1), (m_nGridSize - y) & (m_nGridSize - 1)); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - int GetGridOffsetWrapped(const int& x, const int& y) const - { - return GetGridOffset(x & (m_nGridSize - 1), y & (m_nGridSize - 1)); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - void ComputeFFT1D(int nDir, float* pReal, float* pImag) - { - // reference: "2 Dimensional FFT" - by Paul Bourke - long nn, i, i1, j, k, i2, l, l1, l2; - float c1, c2, fReal, fImag, t1, t2, u1, u2, z; - - nn = m_nGridSize; - float fRecipNN = 1.0f / (float) nn; - - // Do the bit reversal - i2 = nn >> 1; - j = 0; - for (i = 0; i < nn - 1; ++i) - { - if (i < j) - { - fReal = pReal[i]; - fImag = pImag[i]; - pReal[i] = pReal[j]; - pImag[i] = pImag[j]; - pReal[j] = fReal; - pImag[j] = fImag; - } - - k = i2; - while (k <= j) - { - j -= k; - k >>= 1; - } - - j += k; - } - - // FFT computation - c1 = -1.0f; - c2 = 0.0f; - l2 = 1; - for (l = 0; l < m_nLogGridSize; ++l) - { - l1 = l2; - l2 <<= 1; - u1 = 1.0; - u2 = 0.0; - for (j = 0; j < l1; ++j) - { - for (i = j; i < nn; i += l2) - { - i1 = i + l1; - t1 = u1 * pReal[i1] - u2 * pImag[i1]; - t2 = u1 * pImag[i1] + u2 * pReal[i1]; - pReal[i1] = pReal[i] - t1; - pImag[i1] = pImag[i] - t2; - pReal[i] += t1; - pImag[i] += t2; - } - - z = u1 * c1 - u2 * c2; - u2 = u1 * c2 + u2 * c1; - u1 = z; - } - - c2 = sqrt_fast_tpl((1.0f - c1) * 0.5f); - - if (nDir == 1) - { - c2 = -c2; - } - - c1 = sqrt_fast_tpl((1.0f + c1) * 0.5f); - } - - // Scaling for forward transform - if (nDir == 1) - { - for (i = 0; i < nn; ++i) - { - pReal[i] *= fRecipNN; - pImag[i] *= fRecipNN; - } - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - void ComputeFFT2D(int nDir, complexF* const __restrict c) - { - // reference: "2 Dimensional FFT" - by Paul Bourke - float pReal[ m_nGridSize ]; - float pImag[ m_nGridSize ]; - - // Transform the rows - for (int y(0); y < m_nGridSize; ++y) - { - for (int x(0); x < m_nGridSize; ++x) - { - int nGridOffset = GetGridOffset(x, y); - const complexF& curC = c[ nGridOffset ]; - pReal[x] = curC.real(); - pImag[x] = curC.imag(); - } - - ComputeFFT1D(nDir, pReal, pImag); - - for (int x(0); x < m_nGridSize; ++x) - { - int nGridOffset = GetGridOffset(x, y); - c[nGridOffset] = complexF(pReal[x], pImag[x]); - } - } - - // Transform the columns - for (int x(0); x < m_nGridSize; ++x) - { - for (int y(0); y < m_nGridSize; ++y) - { - int nGridOffset = GetGridOffset(x, y); - const complexF& curC = c[ nGridOffset ]; - pReal[y] = curC.real(); - pImag[y] = curC.imag(); - } - - ComputeFFT1D(nDir, pReal, pImag); - - for (int y(0); y < m_nGridSize; ++y) - { - int nGridOffset = GetGridOffset(x, y); - c[ nGridOffset ] = complexF(pReal[y], pImag[y]); - } - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - float GetIndexToWorldX(int x) - { - static const float PI2ByWorldSizeX = (2.0f * PI) / m_fWorldSizeX; - return (float(x) - ((float)m_nGridSize / 2.0f)) * PI2ByWorldSizeX; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - float GetIndexToWorldY(int y) - { - static const float PI2ByWorldSizeY = (2.0f * PI) / m_fWorldSizeY; - return (float(y) - ((float)m_nGridSize / 2.0f)) * PI2ByWorldSizeY; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - float GetTermAngularFreq(float k) - { - // reference: "Simulating Ocean Water" - by Jerry Tessendorf (3.2) - return sqrt_fast_tpl(k * m_fG); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - // a - constant, pK - wave dir (2d), pW - wind dir (2d) - float ComputePhillipsSpec(const Vec2& pK, const Vec2& pW) const - { - float fK2 = pK.GetLength2(); - if (fK2 == 0) - { - return 0.0f; - } - - float fW2 = pW.GetLength2(); - float fL = fW2 / m_fG; - float fL2 = sqr(fL); - - // reference: "Simulating Ocean Water" - by Jerry Tessendorf (3.3) - float fPhillips = m_fA * (exp_tpl(-1.0f / (fK2 * fL2)) / sqr(fK2)) * (sqr(pK.Dot(pW)) / fK2 * fW2); - - assert(fPhillips >= 0); - - // Return Phillips spectrum - return fPhillips; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - void InitTableK() - { - for (int y(0); y < m_nGridSize; ++y) - { - float fKy = GetIndexToWorldY(y); - for (int x(0); x < m_nGridSize; ++x) - { - float fKx = GetIndexToWorldX(x); - float fKLen = sqrt_tpl(fKx * fKx + fKy * fKy); - float fAngularFreq = GetTermAngularFreq(fKLen); - m_pLUTK[GetGridOffset(x, y)] = Vec4(fKx, fKy, fKLen, fAngularFreq); - } - } - } - - // Initialize Fourier amplitudes table - void InitFourierAmps() - { - const float recipSqrt2 = 1.0f / sqrt_fast_tpl(2.0f); - - Vec2 vecWind = { cosf(0.0f), sinf(0.0f) }; // assume constant direction - vecWind = -vecWind; // meh - match with regular water animation - - for (int y(0); y < m_nGridSize; ++y) - { - for (int x(0); x < m_nGridSize; ++x) - { - complexF e(frand_gaussian(), frand_gaussian()); - int nGridOffset = GetGridOffset(x, y); - - Vec4 pLookupK = m_pLUTK[nGridOffset]; - Vec2 pK = Vec2(pLookupK.x, pLookupK.y); - - // reference: "Simulating Ocean Water" - by Jerry Tessendorf (3.4) - e *= recipSqrt2 * sqrt_fast_tpl(ComputePhillipsSpec(pK, vecWind)); - m_pFourierAmps[nGridOffset] = e; - } - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - // Update simulation - void Update(SWaterUpdateThreadInfo& pThreadInfo) - { - float fTime = pThreadInfo.fTime; - bool bOnlyHeight = pThreadInfo.bOnlyHeight; - - PROFILE_FRAME(CWaterSim::Update); - - // Optimization: only half grid is required to update, since we can use conjugate to the other half - - float fHalfY = (m_nGridSize >> 1) + 1; - for (int y(0); y < fHalfY; ++y) - { - for (int x(0); x < m_nGridSize; ++x) - { - int offset = GetGridOffset(x, y); - int offsetMirrowed = GetMirrowedGridOffset(x, y); - - Vec4 pK = m_pLUTK[offset]; - - float fKLen = pK.z; //pK.GetLength(); - float fAngularFreq = pK.w * fTime; //GetTermAngularFreq(fKLen) - - float fAngularFreqSin = 0, fAngularFreqCos = 0; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION WATERUTILS_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(WaterUtils_cpp) -#endif - sincos_tpl((f32)fAngularFreq, (f32*) &fAngularFreqSin, (f32*)&fAngularFreqCos); - - complexF ep(fAngularFreqCos, fAngularFreqSin); - complexF em = conj(ep); - - // reference: "Simulating Ocean Water" - by Jerry Tessendorf (3.4) - complexF currWaveField = m_pFourierAmps[offset] * ep + conj(m_pFourierAmps[offsetMirrowed]) * em; - - m_pHeightField[offset] = currWaveField; - if (!bOnlyHeight && fKLen) - { - m_pDisplaceFieldX[offset] = currWaveField * ((fKLen == 0) ? complexF(0) : complexF(0, (-pK.x - pK.y) / fKLen)); - m_pDisplaceFieldY[offset] = currWaveField * ((fKLen == 0) ? complexF(0) : complexF(0, -pK.y / fKLen)); - } - else - { - m_pDisplaceFieldX[offset] = 0; - m_pDisplaceFieldY[offset] = 0; - } - - // Set upper half using conjugate - if (y != fHalfY - 1) - { - m_pHeightField[offsetMirrowed] = conj(m_pHeightField[offset]); - if (!bOnlyHeight) - { - m_pDisplaceFieldX[offsetMirrowed] = conj(m_pDisplaceFieldX[offset]); - m_pDisplaceFieldY[offsetMirrowed] = conj(m_pDisplaceFieldY[offset]); - } - } - } - } - - ComputeFFT2D(-1, m_pHeightField); - if (!bOnlyHeight) - { - ComputeFFT2D(-1, m_pDisplaceFieldX); - ComputeFFT2D(-1, m_pDisplaceFieldY); - } - - for (int y(0); y < m_nGridSize; ++y) - { - for (int x(0); x < m_nGridSize; ++x) - { - int offset = GetGridOffset(x, y); - int currPowNeg1 = powNeg1(x + y); - - m_pHeightField[offset] *= currPowNeg1 * m_fMaxWaveSize; - if (!bOnlyHeight) - { - m_pDisplaceFieldX[offset] *= currPowNeg1 * m_fChoppyWaveScale; - m_pDisplaceFieldY[offset] *= currPowNeg1 * m_fChoppyWaveScale; - } - - m_pDisplaceGrid[m_nWorkerThreadID][offset] = Vec4(m_pDisplaceFieldX[offset].real(), - m_pDisplaceFieldY[offset].real(), - -m_pHeightField[offset].real(), - 0.0f); // store encoded normal ? - } - } - } - - void Update(int nFrameID, float fTime, bool bOnlyHeight) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - - m_nFillThreadID = m_nWorkerThreadID = 0; - - SWaterUpdateThreadInfo& pThreadInfo = m_pThreadInfo[m_nFillThreadID]; - pThreadInfo.nFrameID = nFrameID; - pThreadInfo.fTime = fTime; - pThreadInfo.bOnlyHeight = bOnlyHeight; - - Update(pThreadInfo); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - Vec3 GetPositionAt(int x, int y) const - { - Vec4 pPos = m_pDisplaceGrid[m_nFillThreadID][ GetGridOffsetWrapped(x, y) ]; - return Vec3(pPos.x, pPos.y, pPos.z); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////// - - float GetHeightAt(int x, int y) const - { - return m_pDisplaceGrid[m_nFillThreadID][ GetGridOffsetWrapped(x, y) ].z; - } - - Vec4* GetDisplaceGrid() - { - return m_pDisplaceGrid[m_nFillThreadID]; - } - - static CWaterSim* GetInstance() - { - static CWaterSim pInstance; - return &pInstance; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - void SpawnUpdateJob(int nFrameID, float fTime, bool bOnlyHeight, void*) - { - if (nFrameID != m_nFrameID) - { - m_nFrameID = nFrameID; - } - else - { - return; - } - - WaitForJob(); - m_jobExecutor.Reset(); - m_jobExecutor.StartJob( - [this, nFrameID, fTime, bOnlyHeight]() - { - this->Update(nFrameID, fTime, bOnlyHeight); - } - ); - } - - void WaitForJob() - { - m_jobExecutor.WaitForCompletion(); - } - -protected: - - // Double buffered displacement grid - Vec4 m_pDisplaceGrid[2][ g_nGridSize * g_nGridSize ] _ALIGN(128); - // Simulation constants - Vec4 m_pLUTK[ g_nGridSize * g_nGridSize ] _ALIGN(128); // pre-computed K table - complexF m_pFourierAmps[m_nGridSize * m_nGridSize] _ALIGN(128); // Fourier amplitudes at time 0 (aka. H0) - complexF m_pHeightField[m_nGridSize * m_nGridSize] _ALIGN(128); // Current Fourier amplitudes height field - complexF m_pDisplaceFieldX[m_nGridSize * m_nGridSize] _ALIGN(128); // Current Fourier amplitudes displace field - complexF m_pDisplaceFieldY[m_nGridSize * m_nGridSize] _ALIGN(128); // Current Fourier amplitudes displace field - - SWaterUpdateThreadInfo m_pThreadInfo[2]; - - int m_nFrameID; - uint32 m_nWorkerThreadID; - uint32 m_nFillThreadID; - CryEvent m_Event; - bool m_bQuit; - - float m_fA; // constant value - float m_fWorldSizeX; // world dimensions - float m_fWorldSizeY; // world dimensions - - float m_fWorldSizeXInv; // 1.f / world dimensions - float m_fWorldSizeYInv; // 1.f / world dimensions - - float m_fMaxWaveSize; - float m_fChoppyWaveScale; - - AZ::LegacyJobExecutor m_jobExecutor; -} _ALIGN(128); - - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CWater::Create(float fA, float fWorldSizeX, float fWorldSizeY) -{ - Release(); - m_pWaterSim = CryAlignedNew(); //::GetInstance(); - m_pWaterSim->Create(fA, fWorldSizeX, fWorldSizeY); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CWater::Release() -{ - if (m_pWaterSim) - { - m_pWaterSim->WaitForJob(); - } - - CryAlignedDelete(m_pWaterSim); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CWater::SaveToDisk([[maybe_unused]] const char* pszFileName) -{ - assert(m_pWaterSim); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// -void CWater::Update(int nFrameID, float fTime, bool bOnlyHeight, void* pRawPtr) -{ - if (m_pWaterSim) - { - m_pWaterSim->SpawnUpdateJob(nFrameID, fTime, bOnlyHeight, pRawPtr); - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -Vec3 CWater::GetPositionAt(int x, int y) const -{ - if (m_pWaterSim) - { - return m_pWaterSim->GetPositionAt(x, y); - } - - return Vec3(ZERO); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -float CWater::GetHeightAt(int x, int y) const -{ - if (m_pWaterSim) - { - return m_pWaterSim->GetHeightAt(x, y); - } - - return 0.0f; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -Vec4* CWater::GetDisplaceGrid() const -{ - if (m_pWaterSim) - { - return m_pWaterSim->GetDisplaceGrid(); - } - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -const int CWater::GetGridSize() const -{ - return g_nGridSize; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CWater::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_pWaterSim); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -CWater* WaterSimMgr() -{ - return gRenDev->m_pWaterSimMgr; -} diff --git a/Code/CryEngine/RenderDll/Common/WaterUtils.h b/Code/CryEngine/RenderDll/Common/WaterUtils.h deleted file mode 100644 index 2bc8ebd0cb..0000000000 --- a/Code/CryEngine/RenderDll/Common/WaterUtils.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __WATERUTILS_H__ -#define __WATERUTILS_H__ - -class CWaterSim; - -// todo. refactor me - should be more general - -class CWater -{ -public: - - CWater() - : m_pWaterSim(0) - { - } - - ~CWater() - { - Release(); - } - - // Create/Initialize simulation - void Create(float fA, float fWorldSizeX, float fWorldSizeY); - void Release(); - void SaveToDisk(const char* pszFileName); - - // Update water simulation - void Update(int nFrameID, float fTime, bool bOnlyHeight = false, void* pRawPtr = NULL); - - // Get water simulation data - Vec3 GetPositionAt(int x, int y) const; - float GetHeightAt(int x, int y) const; - Vec4* GetDisplaceGrid() const; - - const int GetGridSize() const; - - void GetMemoryUsage(ICrySizer* pSizer) const; - - bool NeedInit() const { return m_pWaterSim == NULL; } -private: - - CWaterSim* m_pWaterSim; -}; - -CWater* WaterSimMgr(); - -#endif diff --git a/Code/CryEngine/RenderDll/Common/tests/RenderDLLUnitTests.cpp b/Code/CryEngine/RenderDll/Common/tests/RenderDLLUnitTests.cpp deleted file mode 100644 index b78d4d6803..0000000000 --- a/Code/CryEngine/RenderDll/Common/tests/RenderDLLUnitTests.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include - -TEST(RenderDllUnitTests, TestPathUtilityHelpers) -{ - //normal cases - const char* somefile = "some.tga"; - const char* somefile_ext = somefile + 4; - const char* path_somefile = "path/some.tga"; - const char* path_somefile_ext = path_somefile + 9; - const char* path_somefile2 = "path\\some.tga"; - const char* path_somefile2_ext = path_somefile2 + 9; - - EXPECT_TRUE(fpGetExtension(somefile) == somefile_ext); //filename - EXPECT_TRUE(fpGetExtension(path_somefile) == path_somefile_ext); //path + filename - EXPECT_TRUE(fpGetExtension(path_somefile2) == path_somefile2_ext); //path + filename - - //edge cases - const char* path_somefile3 = "path\\some.tga\\some"; - const char* path_somefile4 = "path\\some.tga/some"; - const char* path_somefile5 = "path/some.tga\\some"; - - EXPECT_TRUE(fpGetExtension(path_somefile3) == nullptr); //malformed string - EXPECT_TRUE(fpGetExtension(path_somefile4) == nullptr); //malformed string - EXPECT_TRUE(fpGetExtension(path_somefile5) == nullptr); //malformed string - EXPECT_TRUE(fpGetExtension("") == nullptr); //empty string - EXPECT_TRUE(fpGetExtension(nullptr) == nullptr); //nullptr -} diff --git a/Code/CryEngine/RenderDll/Common/tests/Shaders/VertexTests.cpp b/Code/CryEngine/RenderDll/Common/tests/Shaders/VertexTests.cpp deleted file mode 100644 index f36b95c574..0000000000 --- a/Code/CryEngine/RenderDll/Common/tests/Shaders/VertexTests.cpp +++ /dev/null @@ -1,1179 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include -#include -#include -#include "Common/Shaders/Vertex.h" -#include "DriverD3D.h" - -// General vertex stream stride -int32 m_cSizeVF[eVF_Max] = -{ - 0, - - sizeof(SVF_P3F_C4B_T2F), - sizeof(SVF_P3F_C4B_T2F_T2F), - sizeof(SVF_P3S_C4B_T2S), - sizeof(SVF_P3S_C4B_T2S_T2S), - sizeof(SVF_P3S_N4B_C4B_T2S), - - sizeof(SVF_P3F_C4B_T4B_N3F2), - sizeof(SVF_TP3F_C4B_T2F), - sizeof(SVF_TP3F_T2F_T3F), - sizeof(SVF_P3F_T3F), - sizeof(SVF_P3F_T2F_T3F), - - sizeof(SVF_T2F), - sizeof(SVF_W4B_I4S), - sizeof(SVF_C4B_C4B), - sizeof(SVF_P3F_P3F_I4B), - sizeof(SVF_P3F), - - sizeof(SVF_C4B_T2S), - - sizeof(SVF_P2F_T4F_C4F), - sizeof(SVF_P2F_T4F_T4F_C4F), - - sizeof(SVF_P2S_N4B_C4B_T1F), - sizeof(SVF_P3F_C4B_T2S), - - sizeof(SVF_P2F_C4B_T2F_F4B), - sizeof(SVF_P3F_C4B), - - sizeof(SVF_P3F_C4F_T2F), //format number 23 (for testing verification) - sizeof(SVF_P3F_C4F_T2F_T3F), - sizeof(SVF_P3F_C4F_T2F_T3F_T3F), - sizeof(SVF_P3F_C4F_T2F_T1F), - sizeof(SVF_P3F_C4F_T2F_T1F_T3F), - sizeof(SVF_P3F_C4F_T2F_T1F_T3F_T3F), - sizeof(SVF_P3F_C4F_T4F_T2F), - sizeof(SVF_P3F_C4F_T4F_T2F_T3F), //30 - sizeof(SVF_P3F_C4F_T4F_T2F_T3F_T3F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F), //35 - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F), //40 - sizeof(SVF_P4F_T2F_C4F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T4F), - sizeof(SVF_P3F_C4F_T2F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T3F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T1F_T4F), //45 - sizeof(SVF_P3F_C4F_T2F_T1F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T3F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F), //50 - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F), //55 - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F), - sizeof(SVF_P4F_T2F_C4F_T4F_T4F_T4F), //60 - sizeof(SVF_P3F_C4F_T2F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T3F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T1F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T1F_T3F_T4F_T4F), //65 - sizeof(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T4F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T4F_T4F), //70 - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F_T4F), //75 - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F_T4F), - sizeof(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F_T4F), - sizeof(SVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F), -}; - -// Legacy table copied from RenderMesh.cpp -#define OOFS(t, x) ((int)offsetof(t, x)) - -SBufInfoTable m_cBufInfoTable[eVF_Max] = -{ - // { Texcoord, Color, Normal } - { - -1, -1, -1 - }, - { //eVF_P3F_C4B_T2F - OOFS(SVF_P3F_C4B_T2F, st), - OOFS(SVF_P3F_C4B_T2F, color.dcolor), - -1 - }, - - { //eVF_P3F_C4B_T2F_T2F - OOFS(SVF_P3F_C4B_T2F_T2F, st), - OOFS(SVF_P3F_C4B_T2F_T2F, color.dcolor), - -1 - }, - - - { //eVF_P3S_C4B_T2S - OOFS(SVF_P3S_C4B_T2S, st), - OOFS(SVF_P3S_C4B_T2S, color.dcolor), --1 - }, - - { //eVF_P3S_C4B_T2S_T2S - OOFS(SVF_P3S_C4B_T2S_T2S, st), - OOFS(SVF_P3S_C4B_T2S_T2S, color.dcolor), - -1 - }, - - { //eVF_P3S_N4B_C4B_T2S - OOFS(SVF_P3S_N4B_C4B_T2S, st), - OOFS(SVF_P3S_N4B_C4B_T2S, color.dcolor), - OOFS(SVF_P3S_N4B_C4B_T2S, normal) - }, - { // eVF_P3F_C4B_T4B_N3F2 - -1, - OOFS(SVF_P3F_C4B_T4B_N3F2, color.dcolor), - -1 - }, - { // eVF_TP3F_C4B_T2F - OOFS(SVF_TP3F_C4B_T2F, st), - OOFS(SVF_TP3F_C4B_T2F, color.dcolor), - -1 - }, - { // eVF_TP3F_T2F_T3F - OOFS(SVF_TP3F_T2F_T3F, st0), - -1, - -1 - }, - { // eVF_P3F_T3F - OOFS(SVF_P3F_T3F, st), - -1, - -1 - }, - { // eVF_P3F_T2F_T3F - OOFS(SVF_P3F_T2F_T3F, st0), - -1, - -1 - }, - {// eVF_T2F - OOFS(SVF_T2F, st), - -1, - -1 - }, - { -1, -1, -1 },// eVF_W4B_I4S - { -1, -1, -1 },// eVF_C4B_C4B - { -1, -1, -1 },// eVF_P3F_P3F_I4B - - { - -1, - -1, - -1 - }, - { // eVF_C4B_T2S - OOFS(SVF_C4B_T2S, st), - OOFS(SVF_C4B_T2S, color.dcolor), - -1 - }, - { // eVF_P2F_T4F_C4F - OOFS(SVF_P2F_T4F_C4F, st), - OOFS(SVF_P2F_T4F_C4F, color), - -1 - }, - { // eVF_P2F_T4F_T4F_C4F - OOFS(SVF_P2F_T4F_T4F_C4F, st), - OOFS(SVF_P2F_T4F_T4F_C4F, color), - -1 - }, - { // eVF_P2S_N4B_C4B_T1F - OOFS(SVF_P2S_N4B_C4B_T1F, z), - OOFS(SVF_P2S_N4B_C4B_T1F, color.dcolor), - OOFS(SVF_P2S_N4B_C4B_T1F, normal) - }, - { // eVF_P3F_C4B_T2S - OOFS(SVF_P3F_C4B_T2S, st), - OOFS(SVF_P3F_C4B_T2S, color.dcolor), - -1 - }, - { // SVF_P2F_C4B_T2F_F4B - OOFS(SVF_P2F_C4B_T2F_F4B, st), - OOFS(SVF_P2F_C4B_T2F_F4B, color.dcolor), - -1 - }, - { // eVF_P3F_C4B - -1, - OOFS(SVF_P3F_C4B, color.dcolor), - -1 - }, - { // eVF_P3F_C4F_T2F - OOFS(SVF_P3F_C4F_T2F, st), - OOFS(SVF_P3F_C4F_T2F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F - OOFS(SVF_P3F_C4F_T2F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F_T3F - OOFS(SVF_P3F_C4F_T2F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F - OOFS(SVF_P3F_C4F_T2F_T1F, st), - OOFS(SVF_P3F_C4F_T2F_T1F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F_T3F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F - OOFS(SVF_P3F_C4F_T4F_T2F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F_T3F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F, color), - -1 - }, - { // eVF_P4F_T2F_C4F_T4F_T4F - OOFS(SVF_P4F_T2F_C4F_T4F_T4F, st0), - OOFS(SVF_P4F_T2F_C4F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T4F - OOFS(SVF_P3F_C4F_T2F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F, color), - -1 - }, - { // eVF_P4F_T2F_C4F_T4F_T4F_T4F - OOFS(SVF_P4F_T2F_C4F_T4F_T4F_T4F, st0), - OOFS(SVF_P4F_T2F_C4F_T4F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T1F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T4F_T2F_T1F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F_T4F - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F_T4F, st0), - OOFS(SVF_P3F_C4F_T2F_T2F_T1F_T1F_T3F_T3F_T4F_T4F, color), - -1 - }, - { // eVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F - OOFS(SVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F, st0), - OOFS(SVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F, color), - -1 - }, -}; -#undef OOFS - -AZStd::vector Legacy_InitBaseStreamD3DVertexDeclaration(EVertexFormat nFormat) -{ - //======================================================================================== - // base stream declarations (stream 0) - D3D11_INPUT_ELEMENT_DESC elemPosHalf = { "POSITION", 0, DXGI_FORMAT_R16G16B16A16_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - D3D11_INPUT_ELEMENT_DESC elemTCHalf = { "TEXCOORD", 0, DXGI_FORMAT_R16G16_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - - D3D11_INPUT_ELEMENT_DESC elemPos = { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - D3D11_INPUT_ELEMENT_DESC elemPos2 = { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - D3D11_INPUT_ELEMENT_DESC elemPosTR = { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // position - D3D11_INPUT_ELEMENT_DESC elemPos2Half = { "POSITION", 0, DXGI_FORMAT_R16G16_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - D3D11_INPUT_ELEMENT_DESC elemPos1 = { "POSITION", 1, DXGI_FORMAT_R32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - - D3D11_INPUT_ELEMENT_DESC elemNormalB = { "NORMAL", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; - D3D11_INPUT_ELEMENT_DESC elemTan = { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // axis/size - D3D11_INPUT_ELEMENT_DESC elemBitan = { "TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // axis/size - D3D11_INPUT_ELEMENT_DESC elemColor = { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // diffuse - D3D11_INPUT_ELEMENT_DESC elemColorF = { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // general color - D3D11_INPUT_ELEMENT_DESC elemTC0 = { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC1 = { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC2 = { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC1_3 = { "TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC0_4 = { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC0_1 = { "TEXCOORD", 0, DXGI_FORMAT_R32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - D3D11_INPUT_ELEMENT_DESC elemTC3_4 = { "TEXCOORD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }; // texture - - AZ::Vertex::Format vertexFormat = AZ::Vertex::Format((EVertexFormat)nFormat); - AZStd::vector decl; - - uint texCoordOffset = 0; - bool hasTexCoord = vertexFormat.TryCalculateOffset(texCoordOffset, AZ::Vertex::AttributeUsage::TexCoord); - uint colorOffset = 0; - bool hasColor = vertexFormat.TryCalculateOffset(colorOffset, AZ::Vertex::AttributeUsage::Color); - uint normalOffset = 0; - bool hasNormal = vertexFormat.TryCalculateOffset(normalOffset, AZ::Vertex::AttributeUsage::Normal); - - // Position - - switch (nFormat) - { - case eVF_TP3F_C4B_T2F: - case eVF_TP3F_T2F_T3F: - decl.push_back(elemPosTR); - break; - case eVF_P3S_C4B_T2S: - case eVF_P3S_N4B_C4B_T2S: - decl.push_back(elemPosHalf); - break; - case eVF_P2S_N4B_C4B_T1F: - decl.push_back(elemPos2Half); - break; - case eVF_P2F_T4F_C4F: - decl.push_back(elemPos2); - break; - case eVF_T2F: - case eVF_C4B_T2S: - case eVF_Unknown: - break; - default: - decl.push_back(elemPos); - } - - // Normal - if (hasNormal) - { - elemNormalB.AlignedByteOffset = normalOffset; - decl.push_back(elemNormalB); - } - -#ifdef PARTICLE_MOTION_BLUR - if (nFormat == eVF_P3F_C4B_T4B_N3F2) - { - elemTC0_4.AlignedByteOffset = (int)offsetof(SVF_P3F_C4B_T4B_N3F2, prevXaxis); - elemTC0_4.SemanticIndex = 0; - decl.AddElem(elemTC0_4); - } -#endif - // eVF_P2F_T4F_C4F has special case logic below, so ignore it here - if (hasColor && nFormat != eVF_P2F_T4F_C4F) - { - elemColor.AlignedByteOffset = colorOffset; - elemColor.SemanticIndex = 0; - decl.push_back(elemColor); - } - if (nFormat == eVF_P3F_C4B_T4B_N3F2) - { -#ifdef PARTICLE_MOTION_BLUR - elemTC1_3.AlignedByteOffset = (int)offsetof(SVF_P3F_C4B_T4B_N3F2, prevPos); - elemTC1_3.SemanticIndex = 1; - decl.push_back(elemTC1_3); -#endif - elemColor.AlignedByteOffset = (int)offsetof(SVF_P3F_C4B_T4B_N3F2, st); - elemColor.SemanticIndex = 1; - decl.push_back(elemColor); - - elemTan.AlignedByteOffset = (int)offsetof(SVF_P3F_C4B_T4B_N3F2, xaxis); - decl.push_back(elemTan); - - elemBitan.AlignedByteOffset = (int)offsetof(SVF_P3F_C4B_T4B_N3F2, yaxis); - decl.push_back(elemBitan); - } - - if (nFormat == eVF_P2F_T4F_C4F) - { - elemTC0_4.AlignedByteOffset = (int)offsetof(SVF_P2F_T4F_C4F, st); - elemTC0_4.SemanticIndex = 0; - decl.push_back(elemTC0_4); - - elemColorF.AlignedByteOffset = (int)offsetof(SVF_P2F_T4F_C4F, color); - elemColorF.SemanticIndex = 0; - decl.push_back(elemColorF); - } - - //handle cases where 2D texture comes before 4F Color - if (nFormat == eVF_P4F_T2F_C4F_T4F_T4F || nFormat == eVF_P4F_T2F_C4F_T4F_T4F_T4F || nFormat == eVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F) - { - elemTC2.AlignedByteOffset = (int)offsetof(SVF_P4F_T2F_C4F_T4F_T4F, st0); - elemTC2.SemanticIndex = 0; - decl.push_back(elemTC2); - - elemColorF.AlignedByteOffset = (int)offsetof(SVF_P4F_T2F_C4F_T4F_T4F, color); - elemColorF.SemanticIndex = 0; - decl.push_back(elemColorF); - } - - if (hasTexCoord) - { - elemTC0.AlignedByteOffset = texCoordOffset; - elemTC0.SemanticIndex = 0; - switch (nFormat) - { - case eVF_P2F_T4F_C4F: - // eVF_P2F_T4F_C4F has special case logic above, so ignore it here - break; - case eVF_P3S_C4B_T2S: - case eVF_P3S_N4B_C4B_T2S: - case eVF_C4B_T2S: - case eVF_P3F_C4B_T2S: - elemTCHalf.AlignedByteOffset = texCoordOffset; - elemTCHalf.SemanticIndex = 0; - decl.push_back(elemTCHalf); - break; - case eVF_P3F_T3F: - elemTC1_3.AlignedByteOffset = texCoordOffset; - elemTC1_3.SemanticIndex = 0; - decl.push_back(elemTC1_3); - break; - case eVF_P2S_N4B_C4B_T1F: - elemTC0_1.AlignedByteOffset = texCoordOffset; - elemTC0_1.SemanticIndex = 0; - decl.push_back(elemTC0_1); - break; - case eVF_TP3F_T2F_T3F: - case eVF_P3F_T2F_T3F: - decl.push_back(elemTC0); - - //This case needs two TexCoord elements - elemTC1_3.AlignedByteOffset = texCoordOffset + 8; - elemTC1_3.SemanticIndex = 1; - decl.push_back(elemTC1_3); - break; - default: - decl.push_back(elemTC0); - } - } - if (nFormat == eVF_P2S_N4B_C4B_T1F) - { - elemPos1.AlignedByteOffset = (int)offsetof(SVF_P2S_N4B_C4B_T1F, z); - decl.push_back(elemPos1); - } - decl.shrink_to_fit(); - - return decl; -} - -bool DeclarationsAreEqual(AZStd::vector& declarationA, AZStd::vector& declarationB) -{ - if (declarationA.size() != declarationB.size()) - { - return false; - } - - for (uint i = 0; i < declarationA.size(); ++i) - { - D3D11_INPUT_ELEMENT_DESC elementDescriptionA = declarationA[i]; - D3D11_INPUT_ELEMENT_DESC elementDescriptionB = declarationB[i]; - if (elementDescriptionA.SemanticIndex != elementDescriptionB.SemanticIndex || - elementDescriptionA.Format != elementDescriptionB.Format || - elementDescriptionA.InputSlot != elementDescriptionB.InputSlot || - elementDescriptionA.AlignedByteOffset != elementDescriptionB.AlignedByteOffset || - elementDescriptionA.InputSlotClass != elementDescriptionB.InputSlotClass || - elementDescriptionA.InstanceDataStepRate != elementDescriptionB.InstanceDataStepRate || - strcmp(elementDescriptionA.SemanticName, elementDescriptionB.SemanticName) != 0) - { - return false; - } - } - return true; -} - -class VertexFormatAssertTest - : public ::testing::Test - , public UnitTest::AllocatorsBase -{ -protected: - void SetUp() override - { - UnitTest::AllocatorsBase::SetupAllocator(); - } - void TearDown() override - { - UnitTest::AllocatorsBase::TeardownAllocator(); - } -}; - -TEST_F(VertexFormatAssertTest, VertexFormatConstructor_AssertsOnInvalidInput) -{ - // The vertex format constructor should assert when an invalid vertex format enum is used - AZ_TEST_START_TRACE_SUPPRESSION; - AZ::Vertex::Format(static_cast(EVertexFormat::eVF_Max)); - AZ::Vertex::Format(static_cast(EVertexFormat::eVF_Max + 1)); - // Expect 2 asserts - AZ_TEST_STOP_TRACE_SUPPRESSION(2); -} - -class VertexFormatTest - : public ::testing::TestWithParam < int > - , public UnitTest::AllocatorsBase -{ -public: - void SetUp() override - { - UnitTest::AllocatorsBase::SetupAllocator(); - } - - void TearDown() override - { - UnitTest::AllocatorsBase::TeardownAllocator(); - } -}; - -TEST_P(VertexFormatTest, GetStride_MatchesExpected) -{ - EVertexFormat eVF = (EVertexFormat)GetParam(); - - AZ::Vertex::Format format(eVF); - uint actualSize = format.GetStride(); - uint expectedSize = m_cSizeVF[eVF]; - EXPECT_EQ(actualSize, expectedSize); -} - -TEST_P(VertexFormatTest, CalculateOffset_MatchesExpected) -{ - EVertexFormat eVF = (EVertexFormat)GetParam(); - - AZ::Vertex::Format format(eVF); - // TexCoord - uint actualOffset = 0; - bool hasOffset = format.TryCalculateOffset(actualOffset, AZ::Vertex::AttributeUsage::TexCoord); - int expectedOffset = m_cBufInfoTable[eVF].OffsTC; - if (expectedOffset >= 0) - { - EXPECT_TRUE(hasOffset); - EXPECT_EQ(actualOffset, expectedOffset); - } - else - { - EXPECT_FALSE(hasOffset); - } - - // Color - hasOffset = format.TryCalculateOffset(actualOffset, AZ::Vertex::AttributeUsage::Color); - expectedOffset = m_cBufInfoTable[eVF].OffsColor; - if (expectedOffset >= 0) - { - EXPECT_TRUE(hasOffset); - EXPECT_EQ(actualOffset, expectedOffset); - } - else - { - EXPECT_FALSE(hasOffset); - } - - // Normal - hasOffset = format.TryCalculateOffset(actualOffset, AZ::Vertex::AttributeUsage::Normal); - expectedOffset = m_cBufInfoTable[eVF].OffsNorm; - if (expectedOffset >= 0) - { - EXPECT_TRUE(hasOffset); - EXPECT_EQ(actualOffset, expectedOffset); - } - else - { - EXPECT_FALSE(hasOffset); - } -} - -TEST_F(VertexFormatTest, CalculateOffsetMultipleUVs_MatchesExpected) -{ - AZ::Vertex::Format vertexFormat(eVF_P3F_C4B_T2F_T2F); - uint offset = 0; - // The first uv set exists - EXPECT_TRUE(vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::TexCoord, 0)); - // First Texture coordinate comes after the position, which has 3 32 bit floats, and the color, which has 4 bytes - EXPECT_EQ(offset, AZ::Vertex::AttributeTypeDataTable[(int)AZ::Vertex::AttributeType::Float32_3].byteSize + AZ::Vertex::AttributeTypeDataTable[(int)AZ::Vertex::AttributeType::Byte_4].byteSize); - - // The second uv set exists - EXPECT_TRUE(vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::TexCoord, 1)); - // Second Texture coordinate comes after the position + color + the first texture coordinate - EXPECT_EQ(offset, AZ::Vertex::AttributeTypeDataTable[(int)AZ::Vertex::AttributeType::Float32_3].byteSize + AZ::Vertex::AttributeTypeDataTable[(int)AZ::Vertex::AttributeType::Byte_4].byteSize + AZ::Vertex::AttributeTypeDataTable[(int)AZ::Vertex::AttributeType::Float32_2].byteSize); - - // The third uv set does not exist - EXPECT_FALSE(vertexFormat.TryCalculateOffset(offset, AZ::Vertex::AttributeUsage::TexCoord, 2)); -} - -TEST_P(VertexFormatTest, D3DVertexDeclarations_MatchesLegacy) -{ - EVertexFormat eVF = (EVertexFormat)GetParam(); - AZStd::vector expected = Legacy_InitBaseStreamD3DVertexDeclaration(eVF); - bool matchesLegacy = true; - - //the new vertex definitions aren't legacy and never were a part of the legacy system in any way, and should be ignored for this test - //new definitions occur after entry number 22; - const unsigned int ignoredFormatsStart = aznumeric_cast(eVF_P3F_C4F_T2F); //23 - const unsigned int ignoredFormatsEnd = aznumeric_cast(eVF_P4F_T2F_C4F_T4F_T4F_T4F_T4F); //61 - if (aznumeric_cast(eVF) >= ignoredFormatsStart && aznumeric_cast(eVF) <= ignoredFormatsEnd) - { - EXPECT_TRUE(matchesLegacy); - return; - } - - // The legacy result of EF_InitD3DVertexDeclarations for the following formats are flat out wrong (it defaults to one D3D11_INPUT_ELEMENT_DESC that is a position, which is clearly not the case for any of these) - // eVF_W4B_I4S is really blendweights + indices - // eVF_C4B_C4B is really two spherical harmonic coefficients - // eVF_P3F_P3F_I4B is really two positions and an index - // eVF_P2F_T4F_T4F_C4F doesn't actually exist in the engine anymore - // ignore these cases - // Also ignore eVF_P2S_N4B_C4B_T1F: the T1F attribute has a POSITION semantic name in the legacy declaration, even though both the engine and shader treat it as a TEXCOORD (despite the fact that it is eventually used for a position) - // eVF_P3F_C4B_T2F_T2F, eVF_P3S_C4B_T2S_T2S, and eVF_P2F_C4B_T2F_F4B are all new - else if (eVF != eVF_W4B_I4S && eVF != eVF_C4B_C4B && eVF != eVF_P3F_P3F_I4B && eVF != eVF_P2F_T4F_T4F_C4F && eVF != eVF_P2S_N4B_C4B_T1F && eVF != eVF_P2F_C4B_T2F_F4B && eVF != eVF_P3F_C4B_T2F_T2F && eVF != eVF_P3S_C4B_T2S_T2S) - { - AZStd::vector actual = GetD3D11Declaration(AZ::Vertex::Format(eVF)); - matchesLegacy = DeclarationsAreEqual(actual, expected); - } - EXPECT_TRUE(matchesLegacy); -} - -TEST_P(VertexFormatTest, GetStride_4ByteAligned) -{ - EVertexFormat eVF = (EVertexFormat)GetParam(); - AZ::Vertex::Format format(eVF); - EXPECT_EQ(format.GetStride() % AZ::Vertex::VERTEX_BUFFER_ALIGNMENT, 0); -} - -class VertexFormatComparisonTest - : public ::testing::TestWithParam < int > - , public UnitTest::AllocatorsBase -{ -protected: - void SetUp() override - { - UnitTest::AllocatorsBase::SetupAllocator(); - - m_vertexFormatEnum = static_cast(GetParam()); - m_vertexFormat = AZ::Vertex::Format(m_vertexFormatEnum); - - m_nextVertexFormatEnum = static_cast((m_vertexFormatEnum + 1) % eVF_Max); - m_nextVertexFormat = AZ::Vertex::Format(m_nextVertexFormatEnum); - } - void TearDown() override - { - UnitTest::AllocatorsBase::TeardownAllocator(); - } - - EVertexFormat m_vertexFormatEnum; - AZ::Vertex::Format m_vertexFormat; - - AZ::Vertex::Format m_nextVertexFormat; - EVertexFormat m_nextVertexFormatEnum; -}; - -TEST_P(VertexFormatComparisonTest, EqualTo_SameVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat == m_vertexFormatEnum); - EXPECT_TRUE(m_vertexFormat == m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, EqualTo_NextVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat == m_nextVertexFormatEnum); - EXPECT_FALSE(m_vertexFormat == m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, EqualTo_PreviousVertexFormat_False) -{ - EXPECT_FALSE(m_nextVertexFormat == m_vertexFormatEnum); - EXPECT_FALSE(m_nextVertexFormat == m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, NotEqualTo_SameVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat != m_vertexFormatEnum); - EXPECT_FALSE(m_vertexFormat != m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, NotEqualTo_NextVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat != m_nextVertexFormatEnum); - EXPECT_TRUE(m_vertexFormat != m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, NotEqualTo_PreviousVertexFormat_True) -{ - EXPECT_TRUE(m_nextVertexFormat != m_vertexFormatEnum); - EXPECT_TRUE(m_nextVertexFormat != m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThan_SameVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat > m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThan_NextVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat > m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThan_PreviousVertexFormat_True) -{ - EXPECT_TRUE(m_nextVertexFormat > m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThanOrEqualTo_SameVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat >= m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThanOrEqualTo_NextVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat >= m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, GreaterThanOrEqualTo_PreviousVertexFormat_True) -{ - EXPECT_TRUE(m_nextVertexFormat >= m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThan_SameVertexFormat_False) -{ - EXPECT_FALSE(m_vertexFormat < m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThan_NextVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat < m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThan_PreviousVertexFormat_False) -{ - EXPECT_FALSE(m_nextVertexFormat < m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThanOrEqualTo_SameVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat <= m_vertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThanOrEqualTo_NextVertexFormat_True) -{ - EXPECT_TRUE(m_vertexFormat <= m_nextVertexFormat); -} - -TEST_P(VertexFormatComparisonTest, LessThanOrEqualTo_PreviousVertexFormat_False) -{ - EXPECT_FALSE(m_nextVertexFormat <= m_vertexFormat); -} - -TEST_P(VertexFormatTest, GetEnum_MatchesExpected) -{ - EVertexFormat eVF = static_cast(GetParam()); - AZ::Vertex::Format vertexFormat(eVF); - - EXPECT_EQ(vertexFormat.GetEnum(), eVF); -} - -TEST_F(VertexFormatTest, GetAttributeUsageCount_MatchesExpected) -{ - AZ::Vertex::Format vertexFormatP3F_C4B_T2F(eVF_P3F_C4B_T2F); - // eVF_P3F_C4B_T2F has one position, one color, one uv set, and no normal attribute - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::Position), 1); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::Color), 1); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord), 1); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::Normal), 0); - - // eVF_P3S_C4B_T2S and eVF_P3F_C4B_T2F_T2F actually have two uv sets - EXPECT_EQ(AZ::Vertex::Format(eVF_P3S_C4B_T2S_T2S).GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord), 2); - EXPECT_EQ(AZ::Vertex::Format(eVF_P3F_C4B_T2F_T2F).GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord), 2); -} - -TEST_P(VertexFormatTest, IsSupersetOf_EquivalentVertexFormat_True) -{ - EVertexFormat eVF = static_cast(GetParam()); - EXPECT_TRUE(AZ::Vertex::Format(eVF).IsSupersetOf(AZ::Vertex::Format(eVF))); -} - -TEST_F(VertexFormatTest, IsSupersetOf_TargetHasExtraUVs_OnlyTargetIsSuperset) -{ - AZ::Vertex::Format vertexFormatP3F_C4B_T2F(eVF_P3F_C4B_T2F); - AZ::Vertex::Format vertexFormatP3F_C4B_T2F_T2F(eVF_P3F_C4B_T2F_T2F); - - // eVF_P3F_C4B_T2F_T2F contains everything in eVF_P3F_C4B_T2F plus an extra uv set - EXPECT_TRUE(vertexFormatP3F_C4B_T2F_T2F.IsSupersetOf(vertexFormatP3F_C4B_T2F)); - EXPECT_FALSE(vertexFormatP3F_C4B_T2F.IsSupersetOf(vertexFormatP3F_C4B_T2F_T2F)); -} - -TEST_F(VertexFormatTest, TryGetAttributeOffsetAndType_MatchesExpected) -{ - uint expectedOffset = 0; - uint offset = 0; - AZ::Vertex::AttributeType type = AZ::Vertex::AttributeType::NumTypes; - AZ::Vertex::Format vertexFormatP3F_C4B_T2F_T2F(eVF_P3F_C4B_T2F_T2F); - - // eVF_P3F_C4B_T2F_T2F has a position at offset 0 that is a Float32_3 - EXPECT_TRUE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::Position, 0, offset, type)); - EXPECT_EQ(offset, expectedOffset); - EXPECT_EQ(type, AZ::Vertex::AttributeType::Float32_3); - expectedOffset += AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float32_3)].byteSize; - - // eVF_P3F_C4B_T2F_T2F does not have a second position - EXPECT_FALSE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::Position, 1, offset, type)); - - // eVF_P3F_C4B_T2F_T2F has a color, offset by 12 bytes, that is a Byte_4 - EXPECT_TRUE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::Color, 0, offset, type)); - EXPECT_EQ(offset, expectedOffset); - EXPECT_EQ(type, AZ::Vertex::AttributeType::Byte_4); - expectedOffset += AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Byte_4)].byteSize; - - // eVF_P3F_C4B_T2F_T2F has a TexCoord, offset by 16 bytes, that is a Float32_2 - EXPECT_TRUE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::TexCoord, 0, offset, type)); - EXPECT_EQ(offset, expectedOffset); - EXPECT_EQ(type, AZ::Vertex::AttributeType::Float32_2); - expectedOffset += AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float32_2)].byteSize; - - // eVF_P3F_C4B_T2F_T2F has a second TexCoord, offset by 24 bytes, that is a Float32_2 - EXPECT_TRUE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::TexCoord, 1, offset, type)); - EXPECT_EQ(offset, expectedOffset); - EXPECT_EQ(type, AZ::Vertex::AttributeType::Float32_2); - expectedOffset += AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float32_2)].byteSize; - - // eVF_P3F_C4B_T2F_T2F does not have a third TexCoord - EXPECT_FALSE(vertexFormatP3F_C4B_T2F_T2F.TryGetAttributeOffsetAndType(AZ::Vertex::AttributeUsage::TexCoord, 2, offset, type)); -} - -TEST_F(VertexFormatTest, GetAttributeByteLength_MatchesExpected) -{ - AZ::Vertex::Format vertexFormatP3F_C4B_T2F(eVF_P3F_C4B_T2F); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Position), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float32_3)].byteSize); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Color), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Byte_4)].byteSize); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeByteLength(AZ::Vertex::AttributeUsage::TexCoord), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float32_2)].byteSize); - EXPECT_EQ(vertexFormatP3F_C4B_T2F.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Normal), 0); - - AZ::Vertex::Format vertexFormatP3S_C4B_T2S(eVF_P3S_C4B_T2S); - EXPECT_EQ(vertexFormatP3S_C4B_T2S.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Position), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float16_4)].byteSize);// vec3f16 is backed by a CryHalf4, so 16 bit positions use Float16_4 - EXPECT_EQ(vertexFormatP3S_C4B_T2S.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Color), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Byte_4)].byteSize); - EXPECT_EQ(vertexFormatP3S_C4B_T2S.GetAttributeByteLength(AZ::Vertex::AttributeUsage::TexCoord), AZ::Vertex::AttributeTypeDataTable[static_cast(AZ::Vertex::AttributeType::Float16_2)].byteSize); - EXPECT_EQ(vertexFormatP3S_C4B_T2S.GetAttributeByteLength(AZ::Vertex::AttributeUsage::Normal), 0); -} - -TEST_F(VertexFormatTest, Has16BitFloatPosition_MatchesExpected) -{ - // Vertex formats with 16 bit positions should return true - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3S_C4B_T2S).Has16BitFloatPosition()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3S_C4B_T2S_T2S).Has16BitFloatPosition()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3S_N4B_C4B_T2S).Has16BitFloatPosition()); - - // Vertex formats with 32 bit positions should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2F).Has16BitFloatPosition()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2F_T2F).Has16BitFloatPosition()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T4B_N3F2).Has16BitFloatPosition()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_T3F).Has16BitFloatPosition()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2S).Has16BitFloatPosition()); - - // Vertex formats with no positions should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_T2F).Has16BitFloatPosition()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_W4B_I4S).Has16BitFloatPosition()); -} - -TEST_F(VertexFormatTest, Has16BitFloatTextureCoordinates_MatchesExpected) -{ - // Vertex formats with 16 bit texture coordinates should return true - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3S_C4B_T2S).Has16BitFloatTextureCoordinates()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3S_C4B_T2S_T2S).Has16BitFloatTextureCoordinates()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3F_C4B_T2S).Has16BitFloatTextureCoordinates()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_C4B_T2S).Has16BitFloatTextureCoordinates()); - - // Vertex formats with 32 bit texture coordinates should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2F).Has16BitFloatTextureCoordinates()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2F_T2F).Has16BitFloatTextureCoordinates()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_T2F).Has16BitFloatTextureCoordinates()); - - // Vertex formats with no texture coordinates should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_W4B_I4S).Has16BitFloatTextureCoordinates()); -} - -TEST_F(VertexFormatTest, Has32BitFloatTextureCoordinates_MatchesExpected) -{ - // Vertex formats with 16 bit texture coordinates should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3S_C4B_T2S).Has32BitFloatTextureCoordinates()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3S_C4B_T2S_T2S).Has32BitFloatTextureCoordinates()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_P3F_C4B_T2S).Has32BitFloatTextureCoordinates()); - EXPECT_FALSE(AZ::Vertex::Format(eVF_C4B_T2S).Has32BitFloatTextureCoordinates()); - - // Vertex formats with 32 bit texture coordinates should return true - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3F_C4B_T2F).Has32BitFloatTextureCoordinates()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_P3F_C4B_T2F_T2F).Has32BitFloatTextureCoordinates()); - EXPECT_TRUE(AZ::Vertex::Format(eVF_T2F).Has32BitFloatTextureCoordinates()); - - // Vertex formats with no texture coordinates should return false - EXPECT_FALSE(AZ::Vertex::Format(eVF_W4B_I4S).Has32BitFloatTextureCoordinates()); -} - -TEST_F(VertexFormatTest, VertFormatForComponents_StandardWithOneUVSet_eVF_P3S_C4B_T2S) -{ - // Standard vertex format - bool hasTextureCoordinate = true; - bool hasTextureCoordinate2 = false; - bool isParticle = false; - bool hasNormal = false; - EXPECT_EQ(AZ::Vertex::VertFormatForComponents(false, hasTextureCoordinate, hasTextureCoordinate2, isParticle, hasNormal), eVF_P3S_C4B_T2S); -} - -TEST_F(VertexFormatTest, VertFormatForComponents_StandardWithTwoUVSets_eVF_P3F_C4B_T2F_T2F) -{ - // Multi-uv set vertex format - bool hasTextureCoordinate = true; - bool hasTextureCoordinate2 = true; - bool isParticle = false; - bool hasNormal = false; - EXPECT_EQ(AZ::Vertex::VertFormatForComponents(false, hasTextureCoordinate, hasTextureCoordinate2, isParticle, hasNormal), eVF_P3F_C4B_T2F_T2F); -} - -TEST_F(VertexFormatTest, VertFormatForComponents_IsParticle_eVF_P3F_C4B_T4B_N3F2) -{ - // Particle vertex format - bool hasTextureCoordinate = true; - bool hasTextureCoordinate2 = false; - bool isParticle = true; - bool hasNormal = false; - EXPECT_EQ(AZ::Vertex::VertFormatForComponents(false, hasTextureCoordinate, hasTextureCoordinate2, isParticle, hasNormal), eVF_P3F_C4B_T4B_N3F2); -} - -TEST_F(VertexFormatTest, VertFormatForComponents_HasNormal_eVF_P3S_N4B_C4B_T2S) -{ - // Vertex format with normals - bool hasTextureCoordinate = true; - bool hasTextureCoordinate2 = false; - bool isParticle = false; - bool hasNormal = true; - EXPECT_EQ(AZ::Vertex::VertFormatForComponents(false, hasTextureCoordinate, hasTextureCoordinate2, isParticle, hasNormal), eVF_P3S_N4B_C4B_T2S); -} - -// Instantiate tests -// Start with 1 to skip eVF_Unknown -INSTANTIATE_TEST_CASE_P(EVertexFormatValues, VertexFormatTest, ::testing::Range(1, eVF_Max)); - -// Start with 1 to skip eVF_Unknown, up to but not including eVF_Max - 1 so we always know that the current value + 1 is within the range of valid vertex formats -INSTANTIATE_TEST_CASE_P(EVertexFormatValues, VertexFormatComparisonTest, ::testing::Range(1, eVF_Max - 1)); diff --git a/Code/CryEngine/RenderDll/RenderDll_precompiled.cpp b/Code/CryEngine/RenderDll/RenderDll_precompiled.cpp deleted file mode 100644 index 7e27221229..0000000000 --- a/Code/CryEngine/RenderDll/RenderDll_precompiled.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - diff --git a/Code/CryEngine/RenderDll/RenderDll_precompiled.h b/Code/CryEngine/RenderDll/RenderDll_precompiled.h deleted file mode 100644 index 3d5ab8c77d..0000000000 --- a/Code/CryEngine/RenderDll/RenderDll_precompiled.h +++ /dev/null @@ -1,443 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -//on mac the precompiled header is auto included in every .c and .cpp file, no include line necessary. -//.c files don't like the cpp things in here -#ifdef __cplusplus - -#include - -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include - -// All handled render elements (except common ones included in "RendElement.h") -#include -#include -#include -#include -#include -#include -#include - -#if !defined(NULL_RENDERER) -#include -#include -#endif - -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define STDAFX_H_SECTION_1 1 -#define STDAFX_H_SECTION_2 2 -#define STDAFX_H_SECTION_3 3 -#endif - -/*----------------------------------------------------------------------------- - Vector transformations. ------------------------------------------------------------------------------*/ - -_inline void TransformVector(Vec3& out, const Vec3& in, const Matrix44A& m) -{ - out.x = in.x * m(0, 0) + in.y * m(1, 0) + in.z * m(2, 0); - out.y = in.x * m(0, 1) + in.y * m(1, 1) + in.z * m(2, 1); - out.z = in.x * m(0, 2) + in.y * m(1, 2) + in.z * m(2, 2); -} - -_inline void TransformPosition(Vec3& out, const Vec3& in, const Matrix44A& m) -{ - TransformVector (out, in, m); - out += m.GetRow(3); -} - - -inline Plane TransformPlaneByUsingAdjointT(const Matrix44A& M, const Matrix44A& TA, const Plane plSrc) -{ - Vec3 newNorm; - TransformVector (newNorm, plSrc.n, TA); - newNorm.Normalize(); - - if (M.Determinant() < 0.f) - { - newNorm *= -1; - } - - Plane plane; - Vec3 p; - TransformPosition (p, plSrc.n * plSrc.d, M); - plane.Set(newNorm, p | newNorm); - - return plane; -} - -inline Matrix44 TransposeAdjoint(const Matrix44A& M) -{ - Matrix44 ta; - - ta(0, 0) = M(1, 1) * M(2, 2) - M(2, 1) * M(1, 2); - ta(1, 0) = M(2, 1) * M(0, 2) - M(0, 1) * M(2, 2); - ta(2, 0) = M(0, 1) * M(1, 2) - M(1, 1) * M(0, 2); - - ta(0, 1) = M(1, 2) * M(2, 0) - M(2, 2) * M(1, 0); - ta(1, 1) = M(2, 2) * M(0, 0) - M(0, 2) * M(2, 0); - ta(2, 1) = M(0, 2) * M(1, 0) - M(1, 2) * M(0, 0); - - ta(0, 2) = M(1, 0) * M(2, 1) - M(2, 0) * M(1, 1); - ta(1, 2) = M(2, 0) * M(0, 1) - M(0, 0) * M(2, 1); - ta(2, 2) = M(0, 0) * M(1, 1) - M(1, 0) * M(0, 1); - - ta(0, 3) = 0.f; - ta(1, 3) = 0.f; - ta(2, 3) = 0.f; - - - return ta; -} - -inline Plane TransformPlane(const Matrix44A& M, const Plane& plSrc) -{ - Matrix44 tmpTA = TransposeAdjoint(M); - return TransformPlaneByUsingAdjointT(M, tmpTA, plSrc); -} - -// Homogeneous plane transform. -inline Plane TransformPlane2(const Matrix34A& m, const Plane& src) -{ - Plane plDst; - - float v0 = src.n.x, v1 = src.n.y, v2 = src.n.z, v3 = src.d; - plDst.n.x = v0 * m(0, 0) + v1 * m(1, 0) + v2 * m(2, 0); - plDst.n.y = v0 * m(0, 1) + v1 * m(1, 1) + v2 * m(2, 1); - plDst.n.z = v0 * m(0, 2) + v1 * m(1, 2) + v2 * m(2, 2); - - plDst.d = v0 * m(0, 3) + v1 * m(1, 3) + v2 * m(2, 3) + v3; - - return plDst; -} - -// Homogeneous plane transform. -inline Plane TransformPlane2(const Matrix44A& m, const Plane& src) -{ - Plane plDst; - - float v0 = src.n.x, v1 = src.n.y, v2 = src.n.z, v3 = src.d; - plDst.n.x = v0 * m(0, 0) + v1 * m(0, 1) + v2 * m(0, 2) + v3 * m(0, 3); - plDst.n.y = v0 * m(1, 0) + v1 * m(1, 1) + v2 * m(1, 2) + v3 * m(1, 3); - plDst.n.z = v0 * m(2, 0) + v1 * m(2, 1) + v2 * m(2, 2) + v3 * m(2, 3); - - plDst.d = v0 * m(3, 0) + v1 * m(3, 1) + v2 * m(3, 2) + v3 * m(3, 3); - - return plDst; -} -inline Plane TransformPlane2_NoTrans(const Matrix44A& m, const Plane& src) -{ - Plane plDst; - TransformVector(plDst.n, src.n, m); - plDst.d = src.d; - - return plDst; -} - -inline Plane TransformPlane2Transposed(const Matrix44A& m, const Plane& src) -{ - Plane plDst; - - float v0 = src.n.x, v1 = src.n.y, v2 = src.n.z, v3 = src.d; - plDst.n.x = v0 * m(0, 0) + v1 * m(1, 0) + v2 * m(2, 0) + v3 * m(3, 0); - plDst.n.y = v0 * m(0, 1) + v1 * m(1, 1) + v2 * m(2, 1) + v3 * m(3, 1); - plDst.n.z = v0 * m(0, 2) + v1 * m(2, 1) + v2 * m(2, 2) + v3 * m(3, 2); - - plDst.d = v0 * m(0, 3) + v1 * m(1, 3) + v2 * m(2, 3) + v3 * m(3, 3); - - return plDst; -} - -//=============================================================================================== - -#define MAX_PATH_LENGTH 512 - -#if defined(LINUX) || defined(APPLE) -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION STDAFX_H_SECTION_1 - #include AZ_RESTRICTED_FILE(RenderDll_precompiled_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else //than it does already exist -inline int vsnprintf(char* buf, int size, const char* format, va_list& args) -{ - int res = azvsnprintf(buf, size, format, args); - assert(res >= 0 && res < size); // just to know if there was problems in past - buf[size - 1] = 0; - return res; -} -#endif - -#if defined(LINUX) || defined(APPLE) -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION STDAFX_H_SECTION_2 - #include AZ_RESTRICTED_FILE(RenderDll_precompiled_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else //than it does already exist -inline int snprintf(char* buf, int size, const char* format, ...) -{ - va_list arglist; - va_start(arglist, format); - int res = azvsnprintf(buf, size, format, arglist); - va_end(arglist); - return res; -} -#endif - -////////////////////////////////////////////////////////////////////////// -// Report warning to validator. -////////////////////////////////////////////////////////////////////////// -inline void Warning(const char* format, ...) PRINTF_PARAMS(1, 2); -inline void Warning(const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, 0, NULL, format, args); - } - va_end(args); -} - -////////////////////////////////////////////////////////////////////////// -// Report warning to validator. -////////////////////////////////////////////////////////////////////////// -inline void LogWarning(const char* format, ...) PRINTF_PARAMS(1, 2); -inline void LogWarning(const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, 0, NULL, format, args); - } - va_end(args); -} - -inline void LogWarningEngineOnly(const char* format, ...) PRINTF_PARAMS(1, 2); -inline void LogWarningEngineOnly(const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, VALIDATOR_FLAG_IGNORE_IN_EDITOR, NULL, format, args); - } - va_end(args); -} - -////////////////////////////////////////////////////////////////////////// -// Report warning to validator. -////////////////////////////////////////////////////////////////////////// -inline void FileWarning(const char* filename, const char* format, ...) PRINTF_PARAMS(2, 3); -inline void FileWarning(const char* filename, const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, VALIDATOR_FLAG_FILE, filename, format, args); - } - va_end(args); -} - -////////////////////////////////////////////////////////////////////////// -// Report warning to validator. -////////////////////////////////////////////////////////////////////////// -inline void TextureWarning(const char* filename, const char* format, ...) PRINTF_PARAMS(2, 3); -inline void TextureWarning(const char* filename, const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, (VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE), filename, format, args); - } - va_end(args); -} - -inline void TextureError(const char* filename, const char* format, ...) -{ - va_list args; - va_start(args, format); - if (iSystem) - { - iSystem->WarningV(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, (VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE), filename, format, args); - } - va_end(args); -} - -_inline void _SetVar(const char* szVarName, int nVal) -{ - ICVar* var = iConsole->GetCVar(szVarName); - if (var) - { - var->Set(nVal); - } - else - { - assert(0); - } -} - -// Get the sub-string starting at the last . in the string, or NULL if the string contains no dot -// Note: The returned pointer refers to a location inside the provided string, no allocation is performed -const char* fpGetExtension (const char* in); - -// Remove extension from string, including the . -// If the string has no extension, the whole string will be copied into the buffer -// Note: The out buffer must have space to store a copy of the in-string and a null-terminator -void fpStripExtension (const char* in, char* out, size_t bytes); -template -void fpStripExtension (const char* in, char (&out)[bytes]) { fpStripExtension(in, out, bytes); } - -// Adds an extension to the path, if an extension is already present the function does nothing -// The extension should include the . -// Note: The path buffer must have enough unused space to store a copy of the extension string -void fpAddExtension (char* path, const char* extension, size_t bytes); -template -void fpAddExtension (char (&path)[bytes], const char* extension) { fpAddExtension(path, extension, bytes); } - -// Converts DOS slashes to UNIX slashes -// Note: The dst buffer must have space to store a copy of src and a null-terminator -void fpConvertDOSToUnixName (char* dst, const char* src, size_t bytes); -template -void fpConvertDOSToUnixName (char (&dst)[bytes], const char* src) { fpConvertDOSToUnixName(dst, src, bytes); } - -// Converts UNIX slashes to DOS slashes -// Note: the dst buffer must have space to store a copy of src and a null-terminator -void fpConvertUnixToDosName (char* dst, const char* src, size_t bytes); -template -void fpConvertUnixToDosName (char (&dst)[bytes], const char* src) { fpConvertUnixToDosName(dst, src, bytes); } - -// Combines the path and name strings, inserting a UNIX slash as required, and stores the result into the dst buffer -// path may be NULL, in which case name will be copied into the dst buffer, and the UNIX slash is NOT inserted -// Note: the dst buffer must have space to store: a copy of name, a copy of path (if not null), a UNIX slash (if path doesn't end with one) and a null-terminator -void fpUsePath (const char* name, const char* path, char* dst, size_t bytes); -template -void fpUsePath (const char* name, const char* path, char (&dst)[bytes]) { fpUsePath(name, path, dst, bytes); } - -//========================================================================================= -// -// Normal timing. -// -#define ticks(Timer) {Timer -= CryGetTicks(); } -#define unticks(Timer) {Timer += CryGetTicks() + 34; } - -//============================================================================= - -// the int 3 call for 32-bit version for .l-generated files. -#ifdef WIN64 -#define LEX_DBG_BREAK -#else -#define LEX_DBG_BREAK DEBUG_BREAK -#endif - -#include - -#define FUNCTION_PROFILER_RENDERER FUNCTION_PROFILER_FAST(iSystem, PROFILE_RENDERER, g_bProfilerEnabled) - -#define SCOPED_RENDERER_ALLOCATION_NAME_HINT(str) - -#define SHADER_ASYNC_COMPILATION - -#if !defined(_RELEASE) -//# define DETAILED_PROFILING_MARKERS -#endif -#if defined(DETAILED_PROFILING_MARKERS) -# define DETAILED_PROFILE_MARKER(x) DETAILED_PROFILE_MARKER((x)) -#else -# define DETAILED_PROFILE_MARKER(x) (void)0 -#endif - -#define RAIN_OCC_MAP_SIZE 256 - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION STDAFX_H_SECTION_3 - #include AZ_RESTRICTED_FILE(RenderDll_precompiled_h) -#endif - -#if defined(WIN32) - -#include - -struct ScopedSetFloatExceptionMask -{ - ScopedSetFloatExceptionMask(unsigned int disable = _EM_INEXACT | _EM_UNDERFLOW | _EM_OVERFLOW | _EM_DENORMAL | _EM_INVALID) - { - _clearfp(); - _controlfp_s(&oldMask, 0, 0); - unsigned temp; - _controlfp_s(&temp, disable, _MCW_EM); - } - ~ScopedSetFloatExceptionMask() - { - _clearfp(); - unsigned temp; - _controlfp_s(&temp, oldMask, _MCW_EM); - } - unsigned oldMask; -}; - -#define SCOPED_ENABLE_FLOAT_EXCEPTIONS ScopedSetFloatExceptionMask scopedSetFloatExceptionMask(0) -#define SCOPED_DISABLE_FLOAT_EXCEPTIONS ScopedSetFloatExceptionMask scopedSetFloatExceptionMask - -#endif // defined(_MSC_VER) -#include -#endif //__cplusplus - -/*----------------------------------------------------------------------------- - The End. ------------------------------------------------------------------------------*/ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CMakeLists.txt b/Code/CryEngine/RenderDll/XRenderD3D9/CMakeLists.txt deleted file mode 100644 index d6005617b3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CMakeLists.txt +++ /dev/null @@ -1,197 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -add_subdirectory(DXGL) -add_subdirectory(DXMETAL) - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - -set(pal_tool_dirs "") -ly_get_pal_tool_dirs(pal_tool_roots ${CMAKE_CURRENT_LIST_DIR}/Platform) -foreach(include_path ${pal_tool_roots}) - list(APPEND pal_tool_dirs ${include_path}/../Common) -endforeach() - - -include(${pal_dir}/CryRender_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) -ly_add_target( - NAME CryRender.Headers HEADERONLY - NAMESPACE Legacy - FILES_CMAKE - core_renderer_header_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/core_renderer_headers_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - INCLUDE_DIRECTORIES - INTERFACE - .. - . - ${pal_dir} -) - -################################################################################ -# DX11 -################################################################################ -if(CRYRENDER_TRAIT_BUILD_DX11_SUPPORTED AND NOT LY_MONOLITHIC_GAME) # only Atom is supported in monolithic - ly_add_target( - NAME CryRenderD3D11.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - core_renderer_files.cmake - ${pal_dir}/core_renderer_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - d3d11_files.cmake - ${pal_dir}/d3d11_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/core_renderer_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - ${pal_dir}/d3d11_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - COMPILE_DEFINITIONS - PUBLIC - DIRECT3D10 - #XRENDERD3D10_EXPORTS - DO_RENDERSTATS - _RENDERER - #EXCLUDE_CINEMIZER_SDK - INCLUDE_DIRECTORIES - PUBLIC - . - ../Common - .. - ${pal_dir} - PRIVATE - ${pal_tool_dirs} - BUILD_DEPENDENCIES - PUBLIC - Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static - ) - ly_add_source_properties( - SOURCES - ../Common/Shaders/PoundPoundParser.cpp - ../Common/Renderer.cpp - ../Common/Shaders/ParserBin.cpp - ../Common/Shaders/RemoteCompiler.cpp - ../Common/Shaders/ShaderCache.cpp - ../Common/Textures/Image/DDSImage.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} - ) - - ly_add_target( - NAME CryRenderD3D11 ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} - NAMESPACE Legacy - FILES_CMAKE - d3d11_shared_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/d3d11_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - BUILD_DEPENDENCIES - PRIVATE - Legacy::CryRenderD3D11.Static - ) - - if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_add_target( - NAME CryRenderD3D11.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - d3d11_test_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/d3d11_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Legacy::CryRenderD3D11.Static - ) - ly_add_googletest( - NAME Legacy::CryRenderD3D11.Tests - ) - endif() -endif() - -################################################################################ -# DX12 -################################################################################ -if(CRYRENDER_TRAIT_BUILD_DX12_SUPPORTED AND NOT LY_MONOLITHIC_GAME) # only Atom is supported in monolithic - - ly_add_target( - NAME CryRenderD3D12.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - core_renderer_files.cmake - ${pal_dir}/core_renderer_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - d3d12_files.cmake - ${pal_dir}/d3d12_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/core_renderer_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - ${pal_dir}/d3d12_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ../Common - .. - DX12/Includes - ${pal_dir} - PRIVATE - ${pal_tool_dirs} - COMPILE_DEFINITIONS - PUBLIC - DIRECT3D10 - CRY_USE_DX12 - #XRENDERD3D10_EXPORTS - DO_RENDERSTATS - _RENDERER - #EXCLUDE_CINEMIZER_SDK - BUILD_DEPENDENCIES - PUBLIC - Legacy::CryCommon - ) - ly_add_source_properties( - SOURCES - ../Common/Shaders/RemoteCompiler.cpp - ../Common/Textures/Image/DDSImage.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} - ) - - ly_add_target( - NAME CryRenderD3D12 ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} - NAMESPACE Legacy - FILES_CMAKE - d3d12_shared_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/d3d12_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - BUILD_DEPENDENCIES - PRIVATE - Legacy::CryRenderD3D12.Static - ) - - if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_add_target( - NAME CryRenderD3D12.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - d3d12_test_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/d3d12_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Legacy::CryRenderD3D12.Static - ) - # If the OS doesn't support DX12 runtime, a CTest test run will not be added as the shared library would fail to load - if(CRYRENDER_TRAIT_RUNTIME_DX12_SUPPORTED) - ly_add_googletest( - NAME Legacy::CryRenderD3D12.Tests - ) - endif() - endif() - -endif() diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CRELensOpticsD3D.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/CRELensOpticsD3D.cpp deleted file mode 100644 index eb4b394ca2..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CRELensOpticsD3D.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "../Common/RendElements/OpticsElement.h" -#include "../Common/RendElements/RootOpticsElement.h" -#include "../Common/RendElements/FlareSoftOcclusionQuery.h" -#include "../Common/RendElements/OpticsPredef.hpp" -#include "DriverD3D.h" -#include "I3DEngine.h" - -static CSoftOcclusionManager g_SoftOcclusionManager; - -CRELensOptics::CRELensOptics(void) -{ - mfSetType(eDATA_LensOptics); - mfUpdateFlags(FCEF_TRANSFORM); -} - -CRELensOptics::~CRELensOptics(void) -{ -} - -bool CRELensOptics::mfCompile([[maybe_unused]] CParserBin& Parser, [[maybe_unused]] SParserFrame& Frame) -{ - return true; -} - -void CRELensOptics::mfPrepare(bool bCheckOverflow) -{ - if (bCheckOverflow) - { - gRenDev->FX_CheckOverflow(0, 0, this); - } - - gRenDev->m_RP.m_pRE = this; - gRenDev->m_RP.m_RendNumIndices = 0; - gRenDev->m_RP.m_RendNumVerts = 0; -} - -void CRELensOptics::ProcessGlobalAction() -{ - PROFILE_LABEL_SCOPE("Soft Occlusion Query"); - - CFlareSoftOcclusionQuery::InitGlobalResources(); - CFlareSoftOcclusionQuery::BatchReadResults(); // copy to system memory previous frame - - CShader* pShader = CShaderMan::s_ShaderSoftOcclusionQuery; - static CCryNameTSCRC sTechName("Main"); - - uint32 nPass = 0; - pShader->FXSetTechnique(sTechName); - pShader->FXBegin(&nPass, FEF_DONTSETTEXTURES); - - g_SoftOcclusionManager.ComputeVisibility(); - g_SoftOcclusionManager.GatherOcclusions(); - - pShader->FXEnd(); - - CFlareSoftOcclusionQuery::ReadbackSoftOcclQuery(); // update current frame to staging buffer - for (int i = 0, iSize(g_SoftOcclusionManager.GetSize()); i < iSize; ++i) - { - CFlareSoftOcclusionQuery* pSoftOcclusion = g_SoftOcclusionManager.GetSoftOcclusionQuery(i); - if (pSoftOcclusion == NULL) - { - continue; - } - pSoftOcclusion->UpdateCachedResults(); - } -} - -static int prevFrameID = 0; - -bool CRELensOptics::mfDraw(CShader* pShader, [[maybe_unused]] SShaderPass* pass) -{ - if (!CRenderer::CV_r_flares || !CRenderer::CV_r_PostProcess) - { - return false; - } - - CD3D9Renderer* pRD = gcpRendD3D; - CRenderObject* pObj = pRD->m_RP.m_pCurObject; - SRenderObjData* pOD = pObj->GetObjData(); - const CameraViewParameters* cam = &pRD->GetViewParameters(); - - // Basically LensOptics should be rendered in only FB_TRANSPARENT phase currently so FB_GENERAL is ignored until it's needed. - if (pRD->m_RP.m_nBatchFilter == FB_GENERAL) - { - return false; - } - - SRenderLight* pLight = pOD ? pRD->EF_GetDeferredLightByID(pOD->m_nLightID) : NULL; - RootOpticsElement* pRootElem = pLight ? (RootOpticsElement*)pLight->GetLensOpticsElement() : NULL; - - if (!pRootElem || pRootElem->GetType() != eFT_Root) - { - return false; - } - - CFlareSoftOcclusionQuery* pOcc = static_cast(pLight->m_pSoftOccQuery); - if (!pOcc) - { - return false; - } - -#if !defined(_RELEASE) - PROFILE_LABEL_SCOPE(pLight->m_sName); -#endif - - pRootElem->SetOcclusionQuery(pOcc); - pOcc->SetOccPlaneSizeRatio(pRootElem->GetOccSize()); - - RootOpticsElement::SFlareLight flareLight; - if (pLight->m_Flags & DLF_ATTACH_TO_SUN) - { - const float sunHeight = 20000.0f; - Vec3 sunDirNorm = gEnv->p3DEngine->GetSunDir(); - sunDirNorm.Normalize(); - - flareLight.m_vPos = cam->vOrigin + sunDirNorm * sunHeight; - flareLight.m_cLdrClr = gEnv->p3DEngine->GetSunAnimColor(); - flareLight.m_fRadius = sunHeight; - flareLight.m_bAttachToSun = true; - pLight->SetPosition(flareLight.m_vPos); - } - else - { - flareLight.m_vPos = pObj->GetTranslation(); - ColorF& c = pLight->m_Color; - flareLight.m_cLdrClr.Set(c.r, c.g, c.b); - flareLight.m_fRadius = pLight->m_fRadius; - flareLight.m_bAttachToSun = false; - } - - ColorF cNorm; - flareLight.m_fClrMultiplier = flareLight.m_cLdrClr.NormalizeCol(cNorm); - flareLight.m_cLdrClr = cNorm; - - flareLight.m_opticsParams = pLight->GetOpticsParams(); - - flareLight.m_fViewAngleFalloff = 1.0; - if (pLight->m_LensOpticsFrustumAngle != 0) - { - Vec3 vDirLight2Camera = (cam->vOrigin - flareLight.m_vPos).GetNormalizedFast(); - float viewCos = pLight->m_ProjMatrix.GetColumn(0).Dot(vDirLight2Camera) * 0.5f + 0.5f; - if (pLight->m_LensOpticsFrustumAngle < 255) - { - int angle = (int)((float)pLight->m_LensOpticsFrustumAngle * (360.0f / 255.0f)); - float radAngle = DEG2RAD(angle); - float halfFrustumCos = cos_tpl(radAngle * 0.5f) * 0.5f + 0.5f; - float quarterFrustumCos = cos_tpl(radAngle * 0.25f) * 0.5f + 0.5f; - if (viewCos < quarterFrustumCos) - { - flareLight.m_fViewAngleFalloff = max(1.0f - (float)((quarterFrustumCos - viewCos) / (quarterFrustumCos - halfFrustumCos)), 0.0f); - } - else - { - flareLight.m_fViewAngleFalloff = 1; - } - } - } - else - { - flareLight.m_fViewAngleFalloff = 0.0; - } - - int curFID = gRenDev->GetFrameID(false); - if (curFID != prevFrameID) - { - if (g_SoftOcclusionManager.Begin()) - { - ProcessGlobalAction(); - g_SoftOcclusionManager.End(); - } - prevFrameID = curFID; - } - - if (pRootElem->ProcessAll(pShader, flareLight)) - { - g_SoftOcclusionManager.AddSoftOcclusionQuery(pOcc, pLight->GetPosition()); - } - - pRootElem->SetOcclusionQuery(NULL); - - return true; -} - -void CRELensOptics::ClearResources() -{ - g_SoftOcclusionManager.ClearResources(); -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderD3D11.rc b/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderD3D11.rc deleted file mode 100644 index 6f4202b3ea..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderD3D11.rc +++ /dev/null @@ -1,74 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "FileDescription", "CryRenderD3D11" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Open 3D Engine" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.props b/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.props deleted file mode 100644 index 19ec66e8c3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - OPENGL;%(PreprocessorDefinitions) - $(SDKFolder)\glew\include;$(ProjectDir)..\..\..\Tools\HLSLCrossCompiler\include;%(AdditionalIncludeDirectories) - - - opengl32.lib;libHLSLcc.lib;%(AdditionalDependencies) - $(SDKFolder)GLEW\lib\win$(PlatformArchitecture);$(ProjectDir)..\..\..\Tools\HLSLCrossCompiler\lib\win$(PlatformArchitecture);%(AdditionalLibraryDirectories) - - - - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.rc b/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.rc deleted file mode 100644 index 9cbf98627e..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderGL.rc +++ /dev/null @@ -1,74 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "FileDescription", "CryRenderGL" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Open 3D Engine" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.props b/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.props deleted file mode 100644 index 8e4213cec3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - CRY_USE_OPENGL;%(PreprocessorDefinitions) - $(SolutionDir)..\SDKs\glew\include;$(SolutionDir)..\Tools\HLSLCrossCompilerMETAL\include;%(AdditionalIncludeDirectories) - - - opengl32.lib;glew32s.lib;libHLSLcc.lib;%(AdditionalDependencies) - $(SolutionDir)..\SDKs\GLEW\lib\win$(PlatformArchitecture);$(SolutionDir)..\Tools\HLSLCrossCompilerMETAL\lib\win$(PlatformArchitecture);%(AdditionalLibraryDirectories) - - - - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.rc b/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.rc deleted file mode 100644 index 69ddbaf3a3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/CryRenderMETAL.rc +++ /dev/null @@ -1,74 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Crytek GmbH" - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "FileDescription", "CryRenderGL" - VALUE "LegalCopyright", "(c) 2014 Crytek GmbH" - VALUE "ProductName", "CryENGINE SDK" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DAmbientOcclusion.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DAmbientOcclusion.cpp deleted file mode 100644 index 8e1191ed9b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DAmbientOcclusion.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : implementation of ambient occlusion related features. - - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "D3DPostProcess.h" -#include "../Common/Textures/TextureHelpers.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DAMBIENTOCCLUSION_CPP_SECTION_1 1 -#define D3DAMBIENTOCCLUSION_CPP_SECTION_2 2 -#endif - -// TODO: Unify with other deferred primitive implementation -const t_arrDeferredMeshVertBuff& CD3D9Renderer::GetDeferredUnitBoxVertexBuffer() const -{ - return m_arrDeferredVerts; -} - -const t_arrDeferredMeshIndBuff& CD3D9Renderer::GetDeferredUnitBoxIndexBuffer() const -{ - return m_arrDeferredInds; -} - -void CD3D9Renderer::CreateDeferredUnitBox(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff) -{ - SVF_P3F_C4B_T2F vert; - Vec3 vNDC; - - indBuff.clear(); - indBuff.reserve(36); - - vertBuff.clear(); - vertBuff.reserve(8); - - //Create frustum - for (int i = 0; i < 8; i++) - { - //Generate screen space frustum (CCW faces) - vNDC = Vec3((i == 0 || i == 1 || i == 4 || i == 5) ? 0.0f : 1.0f, - (i == 0 || i == 3 || i == 4 || i == 7) ? 0.0f : 1.0f, - (i == 0 || i == 1 || i == 2 || i == 3) ? 0.0f : 1.0f - ); - vert.xyz = vNDC; - vert.st = Vec2(0.0f, 0.0f); - vert.color.dcolor = -1; - vertBuff.push_back(vert); - } - - //CCW faces - uint16 nFaces[6][4] = { - {0, 1, 2, 3}, - {4, 7, 6, 5}, - {0, 3, 7, 4}, - {1, 5, 6, 2}, - {0, 4, 5, 1}, - {3, 2, 6, 7} - }; - - //init indices for triangles drawing - for (int i = 0; i < 6; i++) - { - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][1]); - indBuff.push_back((uint16) nFaces[i][2]); - - indBuff.push_back((uint16) nFaces[i][0]); - indBuff.push_back((uint16) nFaces[i][2]); - indBuff.push_back((uint16) nFaces[i][3]); - } -} - -void CD3D9Renderer::SetDepthBoundTest(float fMin, float fMax, bool bEnable) -{ - if (!m_bDeviceSupports_NVDBT) - { - return; - } - - m_bDepthBoundsEnabled = bEnable; - if (bEnable) - { - m_fDepthBoundsMin = fMin; - m_fDepthBoundsMax = fMax; -#if defined(OPENGL) && !DXGL_FULL_EMULATION - DXGLSetDepthBoundsTest(true, fMin, fMax); -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DAMBIENTOCCLUSION_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DAmbientOcclusion_cpp) -#endif - } - else // disable depth bound test - { - m_fDepthBoundsMin = 0; - m_fDepthBoundsMax = 1.0f; -#if defined(OPENGL) && !DXGL_FULL_EMULATION - DXGLSetDepthBoundsTest(false, 0.0f, 1.0f); -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DAMBIENTOCCLUSION_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DAmbientOcclusion_cpp) -#endif - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.cpp deleted file mode 100644 index 9017952b64..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "D3DColorGradingController.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include -#include - - -const int COLORCHART_SIZE = 16; -const int COLORCHART_ALIGNED_SIZE = 16; -const int COLORCHART_WIDTH = COLORCHART_SIZE * COLORCHART_SIZE; -const int COLORCHART_RENDERTARGET_WIDTH = COLORCHART_SIZE * COLORCHART_ALIGNED_SIZE; -const int COLORCHART_HEIGHT = COLORCHART_SIZE; -const uint32 COLORCHART_TEXFLAGS = FT_NOMIPS | FT_DONT_STREAM | FT_STATE_CLAMP; -const char* COLORCHART_DEF_TEX = "EngineAssets/Textures/default_cch.dds"; - -const ETEX_Format COLORCHART_FORMAT = eTF_R8G8B8A8; - -CColorGradingControllerD3D::CColorGradingControllerD3D(CD3D9Renderer* pRenderer) - : m_layers() - , m_pRenderer(pRenderer) - , m_pSlicesVB(0) - , m_pChartIdentity(0) - , m_pChartStatic(0) - , m_pChartToUse(0) -{ - assert(m_pRenderer); - m_pMergeLayers[0] = 0; - m_pMergeLayers[1] = 0; - - m_vecSlicesData.reserve(6 * COLORCHART_SIZE); -} - - -CColorGradingControllerD3D::~CColorGradingControllerD3D() -{ - ReleaseTextures(); -} - -void CColorGradingControllerD3D::ReleaseTextures() -{ - SAFE_RELEASE(m_pChartIdentity); - SAFE_RELEASE(m_pChartStatic); - SAFE_RELEASE(m_pMergeLayers[0]); - SAFE_RELEASE(m_pMergeLayers[1]); - SAFE_DELETE(m_pSlicesVB); - m_pChartToUse = 0; -} - -void CColorGradingControllerD3D::FreeMemory() -{ - stl::reconstruct(m_layers); -} - -bool CColorGradingControllerD3D::ValidateColorChart(const CTexture* pChart) const -{ - if (!CTexture::IsTextureExist(pChart)) - { - return false; - } - - if (pChart->IsNoTexture()) - { - return false; - } - - if (pChart->GetWidth() != COLORCHART_WIDTH || pChart->GetHeight() != COLORCHART_HEIGHT) - { - return false; - } - - return true; -} - - -CTexture* CColorGradingControllerD3D::LoadColorChartInt(const char* pChartFilePath) const -{ - if (!pChartFilePath || !pChartFilePath[0]) - { - return 0; - } - - // color charts don't currently support default fallbacks, so we'll force it to sync compile here if possible. - if (!gEnv->pCryPak->IsFileExist(pChartFilePath)) - { - EBUS_EVENT(AzFramework::AssetSystemRequestBus, CompileAssetSync, pChartFilePath); - } - - CTexture* pChart = (CTexture*) m_pRenderer->EF_LoadTexture(pChartFilePath, COLORCHART_TEXFLAGS); - if (!ValidateColorChart(pChart)) - { - SAFE_RELEASE(pChart); - return 0; - } - return pChart; -} - - -int CColorGradingControllerD3D::LoadColorChart(const char* pChartFilePath) const -{ - CTexture* pChart = LoadColorChartInt(pChartFilePath); - return pChart ? pChart->GetID() : -1; -} - - -int CColorGradingControllerD3D::LoadDefaultColorChart() const -{ - CTexture* pChartIdentity = LoadColorChartInt(COLORCHART_DEF_TEX); - return pChartIdentity ? pChartIdentity->GetID() : -1; -} - - -void CColorGradingControllerD3D::UnloadColorChart(int texID) const -{ - CTexture* pChart = CTexture::GetByID(texID); - SAFE_RELEASE(pChart); -} - - -void CColorGradingControllerD3D::SetLayers(const SColorChartLayer* pLayers, uint32 numLayers) -{ - gRenDev->m_pRT->RC_CGCSetLayers(this, pLayers, numLayers); -} - - -void CColorGradingControllerD3D::RT_SetLayers(const SColorChartLayer* pLayerInfo, uint32 numLayers) -{ - m_layers.reserve(numLayers); - m_layers.resize(0); - - if (numLayers) - { - float blendSum = 0; - for (size_t i = 0; i < numLayers; ++i) - { - const SColorChartLayer& l = pLayerInfo[i]; - if (l.m_texID > 0 && l.m_blendAmount > 0) - { - const CTexture* pChart = CTexture::GetByID(l.m_texID); - if (ValidateColorChart(pChart)) - { - m_layers.push_back(l); - blendSum += l.m_blendAmount; - } - } - } - - const size_t numActualLayers = m_layers.size(); - if (numActualLayers) - { - if (numActualLayers > 1) - { - float normalizeBlendAmount = (float) (1.0 / (double) blendSum); - for (size_t i = 0; i < numActualLayers; ++i) - { - m_layers[i].m_blendAmount *= normalizeBlendAmount; - } - } - else - { - m_layers[0].m_blendAmount = 1; - } - } - } -} - - -bool CColorGradingControllerD3D::InitResources() -{ - if (!m_pChartIdentity) - { - m_pChartIdentity = LoadColorChartInt(COLORCHART_DEF_TEX); - if (!m_pChartIdentity) - { - static bool bPrint = true; - if (bPrint) - { - iLog->LogError("Failed to initialize Color Grading: Default color chart is missing"); - } - bPrint = false; - return false; - } - } - - if (!m_pMergeLayers[0]) - { - m_pMergeLayers[0] = CTexture::CreateRenderTarget("ColorGradingMergeLayer0", COLORCHART_RENDERTARGET_WIDTH, COLORCHART_HEIGHT, Clr_Empty, eTT_2D, COLORCHART_TEXFLAGS, COLORCHART_FORMAT); - if (!CTexture::IsTextureExist(m_pMergeLayers[0])) - { - return false; - } - } - - if (!m_pMergeLayers[1]) - { - m_pMergeLayers[1] = CTexture::CreateRenderTarget("ColorGradingMergeLayer1", COLORCHART_RENDERTARGET_WIDTH, COLORCHART_HEIGHT, Clr_Empty, eTT_2D, COLORCHART_TEXFLAGS, COLORCHART_FORMAT); - if (!CTexture::IsTextureExist(m_pMergeLayers[1])) - { - return false; - } - } - - if (!m_pSlicesVB) - { - //assert(m_vecSlicesData.empty()); - m_vecSlicesData.resize(6 * COLORCHART_SIZE); - - const float fQuadSize = (float)COLORCHART_SIZE / COLORCHART_RENDERTARGET_WIDTH; - const float fTexCoordSize = 1.f / COLORCHART_SIZE; - for (uint32 iQuad = 0; iQuad < COLORCHART_SIZE; ++iQuad) - { - const float fQuadShift = (float)iQuad / COLORCHART_SIZE; - const float fBlue = (float)iQuad / (COLORCHART_SIZE - 1.f); - - m_vecSlicesData[iQuad * 6 + 0].xyz = Vec3(fQuadShift + fQuadSize, 1.f, 0.f); - m_vecSlicesData[iQuad * 6 + 0].st = Vec2(fQuadShift + fTexCoordSize, 1.f); - m_vecSlicesData[iQuad * 6 + 0].color.dcolor = ColorF(1.f, 1.f, fBlue).pack_argb8888(); - m_vecSlicesData[iQuad * 6 + 1].xyz = Vec3(fQuadShift + fQuadSize, 0.f, 0.f); - m_vecSlicesData[iQuad * 6 + 1].st = Vec2(fQuadShift + fTexCoordSize, 0.f); - m_vecSlicesData[iQuad * 6 + 1].color.dcolor = ColorF(1.f, 0.f, fBlue).pack_argb8888(); - m_vecSlicesData[iQuad * 6 + 2].xyz = Vec3(fQuadShift + 0.f, 1.f, 0.f); - m_vecSlicesData[iQuad * 6 + 2].st = Vec2(fQuadShift + 0.f, 1.f); - m_vecSlicesData[iQuad * 6 + 2].color.dcolor = ColorF(0.f, 1.f, fBlue).pack_argb8888(); - - m_vecSlicesData[iQuad * 6 + 3].xyz = Vec3(fQuadShift + 0.f, 1.f, 0.f); - m_vecSlicesData[iQuad * 6 + 3].st = Vec2(fQuadShift + 0.f, 1.f); - m_vecSlicesData[iQuad * 6 + 3].color.dcolor = ColorF(0.f, 1.f, fBlue).pack_argb8888(); - m_vecSlicesData[iQuad * 6 + 4].xyz = Vec3(fQuadShift + fQuadSize, 0.f, 0.f); - m_vecSlicesData[iQuad * 6 + 4].st = Vec2(fQuadShift + fTexCoordSize, 0.f); - m_vecSlicesData[iQuad * 6 + 4].color.dcolor = ColorF(1.f, 0.f, fBlue).pack_argb8888(); - m_vecSlicesData[iQuad * 6 + 5].xyz = Vec3(fQuadShift + 0.f, 0.f, 0.f); - m_vecSlicesData[iQuad * 6 + 5].st = Vec2(fQuadShift + 0.f, 0.f); - m_vecSlicesData[iQuad * 6 + 5].color.dcolor = ColorF(0.f, 0.f, fBlue).pack_argb8888(); - } - - m_pSlicesVB = new CVertexBuffer(&m_vecSlicesData[0], eVF_P3F_C4B_T2F, 6 * COLORCHART_SIZE); - } - - return true; -} - - -bool CColorGradingControllerD3D::Update(const SColorGradingMergeParams* pMergeParams) -{ - m_pChartToUse = 0; - - if (!m_pRenderer->CV_r_colorgrading_charts) - { - return true; - } - - if (m_pChartStatic) - { - m_pChartToUse = m_pChartStatic; - return true; - } - - if (!InitResources()) - { - m_pChartToUse = m_pChartIdentity; - return m_pChartToUse != 0; - } - - gRenDev->m_cEF.mfRefreshSystemShader("PostEffectsGame", CShaderMan::s_shPostEffectsGame); - - static const int texStatePntID = CTexture::GetTexState(STexState(FILTER_POINT, true)); - static const int texStateLinID = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - - const uint64 sample0 = g_HWSR_MaskBit[HWSR_SAMPLE0]; - const uint64 sample1 = g_HWSR_MaskBit[HWSR_SAMPLE1]; - const uint64 sample2 = g_HWSR_MaskBit[HWSR_SAMPLE2]; - const uint64 sample5 = g_HWSR_MaskBit[HWSR_SAMPLE5]; - - // merge layers - const size_t numLayers = m_layers.size(); - if (!numLayers) - { - m_pChartToUse = m_pChartIdentity; - } - else - { - CTexture* pNewMergeResult = m_pMergeLayers[0]; - m_pRenderer->FX_PushRenderTarget(0, pNewMergeResult, 0); - - int numMergePasses = 0; - for (size_t curLayer = 0; curLayer < numLayers; ) - { - size_t mergeLayerIdx[4] = {azlossy_caster(-1), azlossy_caster(-1), azlossy_caster(-1), azlossy_caster(-1)}; - int numLayersPerPass = 0; - - for (; curLayer < numLayers && numLayersPerPass < 4; ++curLayer) - { - if (m_layers[curLayer].m_blendAmount > 0.001f) - { - mergeLayerIdx[numLayersPerPass++] = curLayer; - } - } - - if (numLayersPerPass) - { - const uint64 nResetFlags = ~(sample0 | sample1 | sample2); - m_pRenderer->m_RP.m_FlagsShader_RT &= nResetFlags; - if ((numLayersPerPass - 1) & 1) - { - gRenDev->m_RP.m_FlagsShader_RT |= sample0; - } - if ((numLayersPerPass - 1) & 2) - { - gRenDev->m_RP.m_FlagsShader_RT |= sample1; - } - - CShader* pSh = CShaderMan::s_shPostEffectsGame; - - PROFILE_LABEL_SCOPE("MergeColorCharts"); - static CCryNameTSCRC techName("MergeColorCharts"); - SD3DPostEffectsUtils::ShBeginPass(pSh, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - Vec4 layerBlendAmount(0, 0, 0, 0); - for (int i = 0; i < numLayersPerPass; ++i) - { - const SColorChartLayer& l = m_layers[mergeLayerIdx[i]]; - CTexture* pChart = CTexture::GetByID(l.m_texID); - pChart->Apply(i, texStatePntID); - layerBlendAmount[i] = l.m_blendAmount; - } - - static CCryNameR semLayerBlendAmount("LayerBlendAmount"); - SD3DPostEffectsUtils::ShSetParamPS(semLayerBlendAmount, layerBlendAmount); - - m_pRenderer->FX_SetState(GS_NODEPTHTEST | (numMergePasses ? GS_BLSRC_ONE | GS_BLDST_ONE : 0)); - m_pRenderer->SetCullMode(R_CULL_NONE); - gcpRendD3D->DrawPrimitivesInternal(m_pSlicesVB, COLORCHART_SIZE * 6, eptTriangleList); - - SD3DPostEffectsUtils::ShEndPass(); - ++numMergePasses; - - m_pRenderer->m_RP.m_FlagsShader_RT &= nResetFlags; - } - } - - m_pChartToUse = numMergePasses ? pNewMergeResult : m_pChartIdentity; - - m_pRenderer->FX_PopRenderTarget(0); - } - - // combine merged layers with color grading stuff - if (m_pChartToUse && pMergeParams) - { - PROFILE_LABEL_SCOPE("CombineColorGradingWithColorChart"); - - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT = pMergeParams->nFlagsShaderRT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(sample1 | sample5); - - CTexture* pNewMergeResult = m_pMergeLayers[1]; - m_pRenderer->FX_PushRenderTarget(0, pNewMergeResult, 0); - m_pRenderer->FX_SetColorDontCareActions(0, true, false); - CShader* pSh = CShaderMan::s_shPostEffectsGame; - - static CCryNameTSCRC techName("CombineColorGradingWithColorChart"); - SD3DPostEffectsUtils::ShBeginPass(pSh, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - m_pChartToUse->Apply(0, texStateLinID); - - static CCryNameR pParamName0("ColorGradingParams0"); - static CCryNameR pParamName1("ColorGradingParams1"); - static CCryNameR pParamName2("ColorGradingParams2"); - static CCryNameR pParamName3("ColorGradingParams3"); - static CCryNameR pParamName4("ColorGradingParams4"); - static CCryNameR pParamMatrix("mColorGradingMatrix"); - - pSh->FXSetPSFloat(pParamName0, &pMergeParams->pLevels[0], 1); - pSh->FXSetPSFloat(pParamName1, &pMergeParams->pLevels[1], 1); - pSh->FXSetPSFloat(pParamName2, &pMergeParams->pFilterColor, 1); - pSh->FXSetPSFloat(pParamName3, &pMergeParams->pSelectiveColor[0], 1); - pSh->FXSetPSFloat(pParamName4, &pMergeParams->pSelectiveColor[1], 1); - pSh->FXSetPSFloat(pParamMatrix, &pMergeParams->pColorMatrix[0], 3); - - m_pRenderer->FX_SetState(GS_NODEPTHTEST); - m_pRenderer->SetCullMode(R_CULL_NONE); - gcpRendD3D->DrawPrimitivesInternal(m_pSlicesVB, COLORCHART_SIZE * 6, eptTriangleList); - - SD3DPostEffectsUtils::ShEndPass(); - - m_pChartToUse = pNewMergeResult; - - m_pRenderer->FX_PopRenderTarget(0); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; - } - - return m_pChartToUse != 0; -} - - -CTexture* CColorGradingControllerD3D::GetColorChart() const -{ - return m_pChartToUse; -} - - -void CColorGradingControllerD3D::DrawLayer([[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] float w, [[maybe_unused]] float h, [[maybe_unused]] CTexture* pChart, [[maybe_unused]] float blendAmount, [[maybe_unused]] const char* pLayerName) const -{ -#if !defined(_RELEASE) - CShader* pSh = CShaderMan::s_shPostEffectsGame; - - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - - // If using merged color grading with color chart disable regular color transformations in display - only need to use color chart - if (pChart && pChart->GetTexType() == eTT_3D) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - static CCryNameTSCRC techName("DisplayColorCharts"); - SD3DPostEffectsUtils::ShBeginPass(pSh, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - static const int texStateID = CTexture::GetTexState(STexState(FILTER_POINT, true)); - if (pChart) - { - pChart->Apply(0, texStateID); - } - - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_C4B_T2F* pVerts = vb.Lock(); - - pVerts[0].xyz = Vec3(x, y, 0); - pVerts[0].st = Vec2(0, 1); - - pVerts[1].xyz = Vec3(x + w, y, 0); - pVerts[1].st = Vec2(1, 1); - - pVerts[2].xyz = Vec3(x, y + h, 0); - pVerts[2].st = Vec2(0, 0); - - pVerts[3].xyz = Vec3(x + w, y + h, 0); - pVerts[3].st = Vec2(1, 0); - - vb.Unlock(); - - m_pRenderer->FX_Commit(); - m_pRenderer->FX_SetState(GS_NODEPTHTEST); - m_pRenderer->SetCullMode(R_CULL_NONE); - - vb.Bind(0); - vb.Release(); - - if (!FAILED(m_pRenderer->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - m_pRenderer->FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - SD3DPostEffectsUtils::ShEndPass(); - - float color[4] = {1, 1, 1, 1}; - m_pRenderer->Draw2dLabel(x + w + 10.0f, y, 1.35f, color, false, "%2.1f%%", blendAmount * 100.0f); - m_pRenderer->Draw2dLabel(x + w + 55.0f, y, 1.35f, color, false, "%s", pLayerName); -#endif // #if !defined(_RELEASE) -} - - -void CColorGradingControllerD3D::DrawDebugInfo() const -{ -#if !defined(_RELEASE) - if (m_pRenderer->CV_r_colorgrading_charts < 2) - { - return; - } - - TransformationMatrices backupSceneMatrices; - - m_pRenderer->Set2DMode(m_pRenderer->GetWidth(), m_pRenderer->GetHeight(), backupSceneMatrices); - - const float w = (float) COLORCHART_WIDTH; - const float h = (float) COLORCHART_HEIGHT; - - float x = 16.0f; - float y = 16.0f; - - if (!m_pChartStatic) - { - for (size_t i = 0, numLayers = m_layers.size(); i < numLayers; ++i) - { - const SColorChartLayer& l = m_layers[i]; - CTexture* pChart = CTexture::GetByID(l.m_texID); - DrawLayer(x, y, w, h, pChart, l.m_blendAmount, CryStringUtils::FindFileNameInPath(pChart->GetName())); - y += h + 4; - } - if (GetColorChart()) - { - DrawLayer(x, y, w, h, GetColorChart(), 1, "FinalChart"); - } - } - else - { - DrawLayer(x, y, w, h, m_pChartStatic, 1, CryStringUtils::FindFileNameInPath(m_pChartStatic->GetName())); - } - - m_pRenderer->RT_RenderTextMessages(); - - m_pRenderer->Unset2DMode(backupSceneMatrices); -#endif // #if !defined(_RELEASE) -} - - -bool CColorGradingControllerD3D::LoadStaticColorChart(const char* pChartFilePath) -{ - bool success = true; - - // Prevent a dangling pointer by updating the current chart if it was set to the old static chart. - bool updateCurrentChart = false; - if (m_pChartToUse == m_pChartStatic) - { - updateCurrentChart = true; - } - - SAFE_RELEASE(m_pChartStatic); - if (pChartFilePath && pChartFilePath[0] != '\0') - { - m_pChartStatic = LoadColorChartInt(pChartFilePath); - success = m_pChartStatic != 0; - } - - if (updateCurrentChart) - { - m_pChartToUse = m_pChartStatic; - } - - return success; -} - - -const CTexture* CColorGradingControllerD3D::GetStaticColorChart() const -{ - return m_pChartStatic; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.h deleted file mode 100644 index d7b9acf859..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DColorGradingController.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DCOLORGRADINGCONTROLLER_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DCOLORGRADINGCONTROLLER_H -#pragma once - -#include - - -class CD3D9Renderer; - -struct SColorGradingMergeParams -{ - Vec4 pColorMatrix[3]; - Vec4 pLevels[2]; - Vec4 pFilterColor; - Vec4 pSelectiveColor[2]; - uint64 nFlagsShaderRT; -}; - -class CColorGradingControllerD3D - : public IColorGradingControllerInt -{ -public: - // IColorGradingController interface - virtual int LoadColorChart(const char* pChartFilePath) const; - virtual int LoadDefaultColorChart() const; - virtual void UnloadColorChart(int texID) const; - - virtual void SetLayers(const SColorChartLayer* pLayers, uint32 numLayers); - -public: - // IColorGradingController internal interface - virtual void RT_SetLayers(const SColorChartLayer* pLayers, uint32 numLayers); - -public: - CColorGradingControllerD3D(CD3D9Renderer* pRenderer); - virtual ~CColorGradingControllerD3D(); - - bool Update(const SColorGradingMergeParams* pMergeParams = 0); - CTexture* GetColorChart() const; - void DrawDebugInfo() const; - - bool LoadStaticColorChart(const char* pChartFilePath); - const CTexture* GetStaticColorChart() const; - - void ReleaseTextures(); - void FreeMemory(); - -private: - typedef std::vector Layers; - -private: - bool ValidateColorChart(const CTexture* pChart) const; - CTexture* LoadColorChartInt(const char* pChartFilePath) const; - bool InitResources(); - void DrawLayer(float x, float y, float w, float h, CTexture* pChart, float blendAmount, const char* pLayerName) const; - -private: - Layers m_layers; - CD3D9Renderer* m_pRenderer; - CVertexBuffer* m_pSlicesVB; - std::vector m_vecSlicesData; - CTexture* m_pChartIdentity; - CTexture* m_pChartStatic; - CTexture* m_pChartToUse; - CTexture* m_pMergeLayers[2]; -}; - - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DCOLORGRADINGCONTROLLER_H diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.cpp deleted file mode 100644 index e62456d777..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Control D3D debug runtime output - - -#include "RenderDll_precompiled.h" -#include "D3DDebug.h" - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) - -CD3DDebug::CD3DDebug() -{ - m_pd3dDebugQueue = NULL; - m_nNumCurrBreakOnIDs = 0; -} - -CD3DDebug::~CD3DDebug() -{ - Release(); -} - -bool CD3DDebug::Init(ID3D11Device* pD3DDevice) -{ - Release(); - if (!pD3DDevice) - { - return false; - } - - if (FAILED(pD3DDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&m_pd3dDebugQueue))) - { - return false; - } - - m_pd3dDebugQueue->PushEmptyStorageFilter(); - m_pd3dDebugQueue->AddApplicationMessage(D3D11_MESSAGE_SEVERITY_INFO, "Application D3D Debug Layer initialized"); - - return true; -} - -void CD3DDebug::Release() -{ - if (m_pd3dDebugQueue) - { - m_pd3dDebugQueue->AddApplicationMessage(D3D11_MESSAGE_SEVERITY_INFO, "Application D3D Debug Layer deinitialized"); - m_pd3dDebugQueue->PopStorageFilter(); - } - - SAFE_RELEASE(m_pd3dDebugQueue); -} - -void CD3DDebug::Update(ESeverityCombination muteSeverity, const char* strMuteMsgList, const char* strBreakOnMsgList) -{ - if (!m_pd3dDebugQueue) - { - return; - } - - m_pd3dDebugQueue->ClearStorageFilter(); - - ///////////////////////// - // Severity based mute // - ///////////////////////// - D3D11_MESSAGE_SEVERITY severityList[4] = { D3D11_MESSAGE_SEVERITY_INFO }; - UINT nNumSeverities = 0; - switch (muteSeverity) - { - case ESeverity_Info: - severityList[0] = D3D11_MESSAGE_SEVERITY_INFO; - nNumSeverities = 1; - break; - case ESeverity_InfoWarning: - severityList[0] = D3D11_MESSAGE_SEVERITY_INFO; - severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING; - nNumSeverities = 2; - break; - case ESeverity_InfoWarningError: - severityList[0] = D3D11_MESSAGE_SEVERITY_INFO; - severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING; - severityList[2] = D3D11_MESSAGE_SEVERITY_ERROR; - nNumSeverities = 3; - break; - case ESeverity_All: - severityList[0] = D3D11_MESSAGE_SEVERITY_INFO; - severityList[1] = D3D11_MESSAGE_SEVERITY_WARNING; - severityList[2] = D3D11_MESSAGE_SEVERITY_ERROR; - severityList[3] = D3D11_MESSAGE_SEVERITY_CORRUPTION; - nNumSeverities = 4; - break; - } - - /////////////////// - // ID based mute // - /////////////////// - D3D11_MESSAGE_ID msgIDsList[MAX_NUM_DEBUG_MSG_IDS] = { D3D11_MESSAGE_ID_UNKNOWN }; - UINT nNumIDs = ParseIDs(strMuteMsgList, msgIDsList); - - D3D11_INFO_QUEUE_FILTER filterQueue; - ZeroStruct(filterQueue); - filterQueue.DenyList.pSeverityList = severityList; - filterQueue.DenyList.NumSeverities = nNumSeverities; - filterQueue.DenyList.pIDList = msgIDsList; - filterQueue.DenyList.NumIDs = nNumIDs; - m_pd3dDebugQueue->AddStorageFilterEntries(&filterQueue); - - //////////////////////////// - // Break on functionality // - //////////////////////////// - // First disable break for old entries - for (UINT i = 0; i < m_nNumCurrBreakOnIDs; ++i) - { - m_pd3dDebugQueue->SetBreakOnID(m_arrBreakOnIDsList[i], FALSE); - } - m_nNumCurrBreakOnIDs = 0; - - const int nVal = atoi(strBreakOnMsgList); - if (nVal == -1) - { - // Break on all errors - m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, TRUE); - m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, TRUE); - } - else - { - // Break on specified messages - m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, FALSE); - m_pd3dDebugQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, FALSE); - m_nNumCurrBreakOnIDs = ParseIDs(strBreakOnMsgList, m_arrBreakOnIDsList); - for (UINT i = 0; i < m_nNumCurrBreakOnIDs; ++i) - { - m_pd3dDebugQueue->SetBreakOnID(m_arrBreakOnIDsList[i], TRUE); - } - } -} - -UINT CD3DDebug::ParseIDs(const char* strMsgIDList, D3D11_MESSAGE_ID arrMsgList[MAX_NUM_DEBUG_MSG_IDS]) const -{ - const size_t nLen = strlen(strMsgIDList); - UINT nIDs = 0; - const char* pStart = strMsgIDList; - char* pEnd; - UINT nValID = 1; - while (nValID != 0 && nIDs < MAX_NUM_DEBUG_MSG_IDS) - { - nValID = UINT(strtol(pStart, &pEnd, 10)); - if (nValID) - { - arrMsgList[nIDs] = D3D11_MESSAGE_ID(nValID); - pStart = pEnd; - nIDs++; - } - } - - return nIDs; -} - -string CD3DDebug::GetLastMessage() -{ - string res; - - ID3D11InfoQueue* pQueue = GetDebugInfoQueue(); - if (pQueue) - { - const UINT64 numMsg = pQueue->GetNumStoredMessages(); - if (numMsg) - { - const UINT64 lastMsg = numMsg - 1; - SIZE_T msgLen = 0; - if (SUCCEEDED(pQueue->GetMessage(lastMsg, 0, &msgLen))) - { - D3D11_MESSAGE* pMsg = (D3D11_MESSAGE*) CryModuleMalloc(msgLen); - if (SUCCEEDED(pQueue->GetMessage(lastMsg, pMsg, &msgLen))) - { - const char* pFmt = 0; - switch (pMsg->Severity) - { - case D3D11_MESSAGE_SEVERITY_CORRUPTION: - pFmt = "D3D11 Corruption #%d: "; - break; - case D3D11_MESSAGE_SEVERITY_ERROR: - pFmt = "D3D11 Error #%d: "; - break; - case D3D11_MESSAGE_SEVERITY_WARNING: - pFmt = "D3D11 Warning #%d: "; - break; - case D3D11_MESSAGE_SEVERITY_INFO: - pFmt = "D3D11 Info #%d: "; - break; - } - - char buf[32]; - sprintf_s(buf, pFmt, pMsg->ID); - - res += buf; - res += pMsg->pDescription; - } - CryModuleFree(pMsg); - } - } - } - - if (res.empty()) - { - res = string("No message queued. Debug runtime might be inactive or not installed."); - } - - return res; -} - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.h deleted file mode 100644 index 29b9a2236f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDebug.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Control D3D debug runtime output - - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DDEBUG_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DDEBUG_H -#pragma once - - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) - -enum ESeverityCombination -{ - ESeverity_None = 0, - ESeverity_Info, - ESeverity_InfoWarning, - ESeverity_InfoWarningError, - ESeverity_All -}; - -enum -{ - MAX_NUM_DEBUG_MSG_IDS = 32 -}; - -class CD3DDebug -{ -public: - CD3DDebug(); - ~CD3DDebug(); - - bool Init(ID3D11Device* pD3DDevice); - void Release(); - void Update(ESeverityCombination muteSeverity, const char* strMuteMsgList, const char* strBreakOnMsgList); - - // To use D3D debug info queue outside of this class, - // you can push a copy of current settings or empty filter settings onto stack: - // m_d3dDebug.GetDebugInfoQueue()->PushCopyOfStorageFilter() or PushEmptyStorageFilter() - // .... change settings here - // or push your filter settings directly - // m_d3dDebug.GetDebugInfoQueue()->PushStorageFilter(&myFilter); - // Note that 'PopStorageFilter' should be called before next CD3DDebug::Update, - // as CD3DDebug::Update modifies filter on top of stack - ID3D11InfoQueue* GetDebugInfoQueue() - { - return m_pd3dDebugQueue; - } - - string GetLastMessage(); - -private: - ID3D11InfoQueue* m_pd3dDebugQueue; - - D3D11_MESSAGE_ID m_arrBreakOnIDsList[MAX_NUM_DEBUG_MSG_IDS]; - UINT m_nNumCurrBreakOnIDs; - - UINT ParseIDs(const char* strMsgIDList, D3D11_MESSAGE_ID arrMsgList[MAX_NUM_DEBUG_MSG_IDS]) const; -}; - -#endif // #if defined(SUPPORT_D3D_DEBUG_RUNTIME) - -#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DDEBUG_H diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredPasses.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredPasses.cpp deleted file mode 100644 index b87571928d..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredPasses.cpp +++ /dev/null @@ -1,996 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "../Common/RenderCapabilities.h" -#include "D3DPostProcess.h" -#include "../Common/ReverseDepth.h" -#include "../../Cry3DEngine/Environment/OceanEnvironmentBus.h" - -bool CD3D9Renderer::FX_DeferredCaustics() -{ - //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - bool causticsIsActive = OceanToggle::IsActive() ? OceanRequest::GetCausticsEnabled() : CRenderer::CV_r_watercaustics == 1; - if (!causticsIsActive || !CTexture::s_ptexBackBuffer || !CTexture::s_ptexSceneTarget) - { - return false; - } - - I3DEngine* pEng = gEnv->p3DEngine; - const N3DEngineCommon::SOceanInfo& OceanInfo = gRenDev->m_p3DEngineCommon.m_OceanInfo; - const I3DEngine::CausticsParams causticsParams = gEnv->p3DEngine->GetCausticsParams(); - - bool bOceanVolumeVisible = (OceanInfo.m_nOceanRenderFlags & OCR_OCEANVOLUME_VISIBLE) != 0; - if (!bOceanVolumeVisible || iszero(causticsParams.intensity)) - { - return false; - } - - uint64 nFlagsShaderRTSave = gcpRendD3D->m_RP.m_FlagsShader_RT; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Deferred caustics pass begin +++ \n"); - } - - PROFILE_LABEL_SCOPE("OCEAN_CAUSTICS"); - PROFILE_FRAME(DrawShader_DeferredCausticsPass); - - const float causticsBottomLevel = OceanInfo.m_fWaterLevel - causticsParams.depth; - const float causticsTopLevel = OceanInfo.m_fWaterLevel + causticsParams.height; - const Vec4 pCausticsParams1 = Vec4( - causticsParams.distanceAttenuation, - causticsParams.intensity, - causticsBottomLevel, - causticsTopLevel - ); - const Vec4 pCausticsParams2 = Vec4( - //pEng->GetCausticsParams().x, // Caustics Tiling - causticsParams.tiling, // Caustics Tiling - /* Following params are free for future use */ - 0.0, 0.0, 0.0 - ); - - // Caustics are done with projection from sun - hence they update too fast with regular - // sun direction. Use a smooth sun direction update instead to workaround this - PerFrameParameters& PF = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_perFrameParameters; - Vec3 pRealtimeSunDirNormalized = pEng->GetRealtimeSunDirNormalized(); - - const float fSnapDot = 0.98f; - float fDot = fabs(PF.m_CausticsSunDirection.Dot(pRealtimeSunDirNormalized)); - if (fDot < fSnapDot) - { - PF.m_CausticsSunDirection = pRealtimeSunDirNormalized; - } - - PF.m_CausticsSunDirection += (pRealtimeSunDirNormalized - PF.m_CausticsSunDirection) * 0.005f * gEnv->pTimer->GetFrameTime(); - PF.m_CausticsSunDirection.Normalize(); - - Matrix44 m_pLightView; - - Vec3 up = Vec3(0, 0, 1); - Vec3 dirZ = -PF.m_CausticsSunDirection; - Vec3 dirX = up.Cross(dirZ).GetNormalized(); - Vec3 dirY = dirZ.Cross(dirX).GetNormalized(); - - m_pLightView.SetIdentity(); - m_pLightView.SetRow(0, dirX); - m_pLightView.SetRow(1, dirY); - m_pLightView.SetRow(2, dirZ); - - float fTime = 0.125f * gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_RealTime; - - Vec4 vAnimParams = Vec4(0.06f * fTime, 0.05f * fTime, 0.1f * fTime, -0.11f * fTime); - - // Stencil pre-pass - CShader* pSH(CShaderMan::s_ShaderShadowMaskGen); - - // make box for stencil passes - t_arrDeferredMeshIndBuff arrDeferredInds; - t_arrDeferredMeshVertBuff arrDeferredVerts; - CreateDeferredUnitBox(arrDeferredInds, arrDeferredVerts); - - Vec3 vCamPos = gRenDev->GetViewParameters().vOrigin; - - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - Matrix34 mLocal; - mLocal.SetIdentity(); - - float heightAboveWater = max(0.0f, vCamPos.z - causticsTopLevel); - - float fDist = sqrtf((causticsParams.distanceAttenuation * 5.0f) * 13.333f); // Hard cut off when caustic would be attenuated to 0.2 (1/5.0f) - fDist = sqrtf(max((fDist * fDist) - (heightAboveWater * heightAboveWater), 0.0f)); - - //TODO: Adjust Z on fog density - - mLocal.SetScale(Vec3(fDist * 2, fDist * 2, causticsParams.height + causticsParams.depth)); - mLocal.SetTranslation(Vec3(vCamPos.x - fDist, vCamPos.y - fDist, OceanInfo.m_fWaterLevel - causticsParams.depth)); - - Matrix44 mLocalTransposed = mLocal.GetTransposed(); - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = mLocalTransposed * m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - - uint32 nPasses = 0; - static CCryNameTSCRC TechName0 = "DeferredShadowPass"; - pSH->FXSetTechnique(TechName0); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES); - - //allocate vertices - TempDynVB::CreateFillAndBind(&arrDeferredVerts[0], arrDeferredVerts.size(), 0); - - //allocate indices - TempDynIB16::CreateFillAndBind(&arrDeferredInds[0], arrDeferredInds.size()); - - if (RenderCapabilities::SupportsDepthClipping()) - { - FX_StencilCullPass(-1, arrDeferredVerts.size(), arrDeferredInds.size(), pSH, DS_SHADOW_CULL_PASS); - } - else - { - FX_StencilCullPass(-1, arrDeferredVerts.size(), arrDeferredInds.size(), pSH, DS_SHADOW_CULL_PASS, DS_SHADOW_CULL_PASS_FRONTFACING); - } - - pSH->FXEnd(); - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - - FX_StencilTestCurRef(true, false); - - // Deferred caustic pass - gcpRendD3D->EF_Scissor(false, 0, 0, 0, 0); - - gRenDev->m_cEF.mfRefreshSystemShader("DeferredCaustics", CShaderMan::s_ShaderDeferredCaustics); - - CShader* pShader = CShaderMan::s_ShaderDeferredCaustics; - gcpRendD3D->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3]; - - static CCryNameTSCRC pTechName = "General"; - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechName, FEF_DONTSETSTATES); - - int32 nRState = GS_NODEPTHTEST | GS_STENCIL | (GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA); - - gcpRendD3D->FX_SetState(nRState); - - static CCryNameR m_pParamAnimParams("vAnimParams"); - static CCryNameR m_pCausticsParams1Name("vCausticsParams1"); - static CCryNameR m_pCausticsParams2Name("vCausticsParams2"); - static CCryNameR m_pParamLightView("mLightView"); - pShader->FXSetPSFloat(m_pParamAnimParams, &vAnimParams, 1); - pShader->FXSetPSFloat(m_pCausticsParams1Name, &pCausticsParams1, 1); - pShader->FXSetPSFloat(m_pCausticsParams2Name, &pCausticsParams2, 1); - pShader->FXSetPSFloat(m_pParamLightView, (Vec4*) m_pLightView.GetData(), 4); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); // TODO: Use Volume - - SD3DPostEffectsUtils::ShEndPass(); - - FX_StencilTestCurRef(false); - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Deferred caustics pass end +++ \n"); - } - - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - //m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags2 = nPersFlags2Save; - - FX_ResetPipe(); - - return true; -} - -bool CD3D9Renderer::FX_DeferredWaterVolumeCaustics(const N3DEngineCommon::SCausticInfo& causticInfo) -{ - if (!CTexture::s_ptexBackBuffer || !CTexture::s_ptexSceneTarget) - { - return false; - } - - //gRenDev->m_cEF.mfRefreshSystemShader("DeferredCaustics", CShaderMan::m_ShaderDeferredCaustics); - - CShader* pShader = CShaderMan::s_ShaderDeferredCaustics; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Deferred caustics pass begin +++ \n"); - } - - PROFILE_LABEL_SCOPE("DEFERRED WATERVOLUME CAUSTICS"); - - bool bTiledDeferredShading = CRenderer::CV_r_DeferredShadingTiled >= 2; - - if (bTiledDeferredShading) - { - gcpRendD3D->FX_PushRenderTarget(0, CTexture::s_ptexSceneTargetR11G11B10F[1], NULL); - } - else - { - gcpRendD3D->FX_PushRenderTarget(0, CTexture::s_ptexSceneDiffuseAccMap, NULL); - } - - static CCryNameTSCRC pTechName = "WaterVolumeCaustics"; - - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechName, FEF_DONTSETSTATES); - - int32 nRState = GS_NODEPTHTEST; - if (!bTiledDeferredShading) - { - nRState |= GS_BLSRC_ONE | GS_BLDST_ONE; // Blend directly into light accumulation buffer - } - gcpRendD3D->FX_SetState(nRState); - - static CCryNameR m_pParamLightView("mLightView"); - pShader->FXSetPSFloat(m_pParamLightView, (Vec4*) causticInfo.m_mCausticMatr.GetData(), 4); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); - - SD3DPostEffectsUtils::ShEndPass(); - - gcpRendD3D->FX_PopRenderTarget(0); - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Deferred caustics pass end +++ \n"); - } - - FX_ResetPipe(); - - if (bTiledDeferredShading) - { - GetTiledShading().NotifyCausticsVisible(); - } - - return true; -} - -bool CD3D9Renderer::FX_DeferredRainOcclusionMap(const N3DEngineCommon::ArrOccluders& arrOccluders, const SRainParams& rainVolParams) -{ - PROFILE_LABEL_SCOPE("OCCLUSION_PASS"); - - const Matrix44& matOccTrans = rainVolParams.matOccTrans; - uint64 nFlagsShaderRTSave = m_RP.m_FlagsShader_RT; - - // Rain occlusion map generation does not work with reverse depth. - // It is OK to disable reverse depth rendering here because we render the occlusion buffer to an separate render target with its own depth buffer. - // Note that all shadow maps disable reverse depth as well, so we're following that scheme here. - uint32 persFlagSave = m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_REVERSE_DEPTH; - - Matrix44 matTrans; - static const Matrix44 matSs2Ps - (2.f, 0.f, 0.f, -1.f, - 0.f, 2.f, 0.f, -1.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); - matTrans = matSs2Ps * matOccTrans; - - // Create texture if required - if (!CTexture::IsTextureExist(CTexture::s_ptexRainOcclusion)) - { - if (!CTexture::s_ptexRainOcclusion->Create2DTexture(RAIN_OCC_MAP_SIZE, RAIN_OCC_MAP_SIZE, 1, - FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, - 0, eTF_R8G8B8A8, eTF_R8G8B8A8)) - { - return false; - } - } - - // Get temp depth buffer - SDepthTexture* pTmpDepthSurface = FX_GetDepthSurface(RAIN_OCC_MAP_SIZE, RAIN_OCC_MAP_SIZE, false); - - // Render geometry to rain occlusion map - FX_PushRenderTarget(0, CTexture::s_ptexRainOcclusion, pTmpDepthSurface); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - RT_SetViewport(0, 0, RAIN_OCC_MAP_SIZE, RAIN_OCC_MAP_SIZE); - - EF_ClearTargetsLater(FRT_CLEAR_COLOR | FRT_CLEAR_DEPTH, Clr_Neutral, Clr_FarPlane.r, 0); - - FX_SetState(GS_DEPTHFUNC_LEQUAL | GS_DEPTHWRITE); - SetCullMode(R_CULL_NONE); - - CShader* pSH = m_cEF.s_ShaderDeferredRain; - uint32 nPasses = 0; - static CCryNameTSCRC TechName("RainOcclusion"); - pSH->FXSetTechnique(TechName); - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - static CCryNameR occTransMatParamName("g_RainOcc_TransMat"); - for (N3DEngineCommon::ArrOccluders::const_iterator it = arrOccluders.begin(); - it != arrOccluders.end(); ++it) - { - if (it->m_RndMesh) - { - Matrix44A matWVP(it->m_WorldMat); - matWVP = matTrans * matWVP; - pSH->FXSetVSFloat(occTransMatParamName, (Vec4*)matWVP.GetData(), 4); - - FX_Commit(); - - static_cast(it->m_RndMesh.get())->DrawImmediately(); - } - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - FX_PopRenderTarget(0); - - RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags = persFlagSave; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_DeferredRainOcclusion() -{ - // TODO: Implement this for GMEM path - // Not yet supported. - // Only r_rain=1 and r_snow=1 supported at the moment. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - CRY_ASSERT(0); - } - - SRainParams& rainVolParams = m_p3DEngineCommon.m_RainInfo; - - if (rainVolParams.areaAABB.IsReset()) - { - return false; - } - - if (m_p3DEngineCommon.m_RainOccluders.m_bProcessed[RT_GetCurrGpuID()]) - { - return true; - } - - PROFILE_LABEL_SCOPE("DEFERRED_RAIN_OCCLUSION"); - - bool bRet = true; - const N3DEngineCommon::ArrOccluders& arrOccluders = m_p3DEngineCommon.m_RainOccluders.m_arrCurrOccluders[m_RP.m_nProcessThreadID]; - if (!arrOccluders.empty()) - { - // Render occluders to occlusion map - bRet = FX_DeferredRainOcclusionMap(arrOccluders, rainVolParams); - m_p3DEngineCommon.m_RainOccluders.m_bProcessed[RT_GetCurrGpuID()] = true; - if (bRet) - { - rainVolParams.matOccTransRender = rainVolParams.matOccTrans; - } - } - - return bRet; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_DeferredRainPreprocess() -{ - AZ_TRACE_METHOD(); - // Snow also uses the occlusion computation. - CEffectParam* pRainActive = PostEffectMgr()->GetByName("SceneRain_Active"); - if (pRainActive) - { - pRainActive->SetParam(0); - } - - CEffectParam* pSnowActive = PostEffectMgr()->GetByName("SceneSnow_Active"); - if (pSnowActive) - { - pSnowActive->SetParam(0); - } - - if ((CV_r_rain < 1 && CV_r_snow < 1) || !CV_r_PostProcess || !CTexture::s_ptexBackBuffer || !CTexture::s_ptexSceneTarget) - { - return false; - } - - SRainParams& rainVolParams = m_p3DEngineCommon.m_RainInfo; - SSnowParams& snowVolParams = m_p3DEngineCommon.m_SnowInfo; - - bool bRenderSnow = ((snowVolParams.m_fSnowAmount > 0.05f || snowVolParams.m_fFrostAmount > 0.05f) && snowVolParams.m_fRadius > 0.05f && CV_r_snow > 0); - bool bRenderRain = (rainVolParams.fAmount * CRenderer::CV_r_rainamount > 0.05f && rainVolParams.fRadius > 0.05f && CV_r_rain > 0); - - bool bRender = bRenderSnow || bRenderRain; - if (!bRender) - { - return false; - } - - bool bRet = true; - if (rainVolParams.bApplyOcclusion && ((CV_r_snow == 2 && bRenderSnow) || (CV_r_rain == 2 && bRenderRain))) - { - bRet = FX_DeferredRainOcclusion(); - } - - if (bRet && bRenderRain && pRainActive) - { - CSceneRain* pEffRain = (CSceneRain*)PostEffectMgr()->GetEffect(ePFX_SceneRain); - if (!pEffRain) - { - return false; - } - - pEffRain->m_RainVolParams = rainVolParams; - pRainActive->SetParam(1); - } - - if (bRet && bRenderSnow && pSnowActive) - { - CSceneSnow* pEffSnow = (CSceneSnow*)PostEffectMgr()->GetEffect(ePFX_SceneSnow); - if (!pEffSnow) - { - return false; - } - - pEffSnow->m_RainVolParams = rainVolParams; - pEffSnow->m_SnowVolParams = snowVolParams; - pSnowActive->SetParam(1); - } - - return bRet; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_DeferredRainGBuffer() -{ - const SRainParams& rainVolParams = m_p3DEngineCommon.m_RainInfo; - CEffectParam* pParam = PostEffectMgr()->GetByName("SceneRain_Active"); - if (pParam == 0 || pParam->GetParam() < 0.5f - || rainVolParams.fCurrentAmount < 0.05f - || rainVolParams.fRadius < 0.05f) - { - return false; - } - - const bool bUseStencilMask = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && CRenderer::CV_r_RainUseStencilMasking; - - // If GMEM path is enabled but no framebuffer fetches are supported, then neither can this pass. - // We would have to resolve which would break the GMEM path. - const bool gmemEnabled = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - if (gmemEnabled && !(RenderCapabilities::GetFrameBufferFetchCapabilities().test(RenderCapabilities::FBF_ALL_COLORS))) - { - AZ_Assert(false, "Device does not support framebuffer fetches for all color attachments. Deferred rain not supported with GMEM paths."); - return false; - } - - PROFILE_LABEL_SCOPE("DEFERRED_RAIN_GBUFFER"); - - if (CRenderer::CV_r_SlimGBuffer) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - static const int numOfDeferredStencilRainTechniques = 2; - static CCryNameTSCRC tech[numOfDeferredStencilRainTechniques] = {CCryNameTSCRC("DeferredRainGBufferStencil"), CCryNameTSCRC("DeferredRainGBufferNoDiscard")}; - static CCryNameTSCRC techDiscard = "DeferredRainGBuffer"; - static CCryNameR puddleParamName0("g_RainPuddleParams0"); - static CCryNameR puddleParamName1("g_RainPuddleParams1"); - static CCryNameR volumeParamName("g_RainVolumeParams"); - static CCryNameR colorMulParamName("g_RainColorMultipliers"); - static CCryNameR wvpParamName("g_WorldViewPos"); - static CCryNameR occTransMatParamName("g_RainOcc_TransMat"); - static CCryNameR windParamName("g_RainOcc_WindOffs"); - - - CShader* pShader = CShaderMan::s_ShaderDeferredRain; - m_cEF.mfRefreshSystemShader("DeferredRain", pShader); - - const CameraViewParameters& viewParameters = gcpRendD3D->m_RP.m_TI[m_RP.m_nProcessThreadID].m_cam.m_viewParameters; - - // Prepare for reading from stencil in shader - CTexture* pDepthBufferRT = CTexture::s_ptexZTarget; - const bool bMSAA = m_RP.m_MSAAData.Type ? true : false; - D3DDepthSurface* pZBufferOrigDSV = (ID3D11DepthStencilView*)m_DepthBufferOrigMSAA.pSurf; - m_DepthBufferOrigMSAA.pSurf = m_pZBufferReadOnlyDSV; - bool restoreStencilResourceView = false; - D3DShaderResourceView* pZTargetOrigSRV = pDepthBufferRT->GetShaderResourceView(bMSAA? SResourceView::DefaultViewMS : SResourceView::DefaultView); - - if (!gmemEnabled) // needed RTs already in GMEM - { - CTexture* pSceneSpecular = CTexture::s_ptexSceneSpecular; -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DDeferredPasses_cpp) -#endif - // TODO: Try avoiding the copy by directly accessing UAVs - PostProcessUtils().StretchRect(CTexture::s_ptexSceneNormalsMap, CTexture::s_ptexStereoL); - PostProcessUtils().StretchRect(pSceneSpecular, CTexture::s_ptexStereoR); - PostProcessUtils().StretchRect(CTexture::s_ptexSceneDiffuse, CTexture::s_ptexSceneNormalsBent); - - FX_PushRenderTarget(0, CTexture::s_ptexSceneNormalsMap, bUseStencilMask ? &m_DepthBufferOrigMSAA : NULL); - FX_PushRenderTarget(1, pSceneSpecular, NULL); - FX_PushRenderTarget(2, CTexture::s_ptexSceneDiffuse, NULL); - } - - uint64 nFlagsShaderRTSave = m_RP.m_FlagsShader_RT; - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0]); - - if (rainVolParams.bApplyOcclusion) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; // Occlusion - } - if (rainVolParams.fSplashesAmount > 0.001f && rainVolParams.fRainDropsAmount > 0.001f) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; // Splashes - } - - const int rainStencilMask = 0x40; - for (int i = bUseStencilMask ? 0 : 1; i < numOfDeferredStencilRainTechniques; ++i) - { - if (bUseStencilMask) - { - SD3DPostEffectsUtils::ShBeginPass(pShader, tech[i], FEF_DONTSETSTATES); - FX_SetState(GS_DEPTHFUNC_GREAT|GS_STENCIL); - - if (i==0) - { - FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_REPLACE), - rainStencilMask, rainStencilMask, rainStencilMask, false); - } - else - { - FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_ZERO), - rainStencilMask, rainStencilMask, rainStencilMask, false); - } - } - else - { - SD3DPostEffectsUtils::ShBeginPass(pShader, tech[i], FEF_DONTSETSTATES); - FX_SetState(GS_NODEPTHTEST); - } - - float fMaxZ = -1.f; - if (CV_r_rain_maxviewdist_deferred > viewParameters.fNear) - { - fMaxZ = (viewParameters.fFar - (viewParameters.fNear * viewParameters.fFar) / CV_r_rain_maxviewdist_deferred) / (viewParameters.fFar - viewParameters.fNear); - } - - // Global wind params - Vec3 windVec = gEnv->p3DEngine->GetGlobalWind(false); - - // Animated puddles - float fTime = m_RP.m_TI[m_RP.m_nProcessThreadID].m_RealTime * 0.333f; - const float puddleWindScale = -0.15f; - float puddleOffsX = fTime * puddleWindScale * windVec.x; - float puddleOffsY = fTime * puddleWindScale * windVec.y; - - Vec4 vPuddleParams0 = Vec4(puddleOffsX, puddleOffsY, rainVolParams.fPuddlesAmount * rainVolParams.fCurrentAmount, rainVolParams.fDiffuseDarkening); - pShader->FXSetPSFloat(puddleParamName0, &vPuddleParams0, 1); - - float invPuddleMask = clamp_tpl(1.0f - rainVolParams.fPuddlesMaskAmount, 0.0f, 1.0f); - Vec4 vPuddleParams1 = Vec4(invPuddleMask, rainVolParams.fPuddlesRippleAmount, rainVolParams.fSplashesAmount, 0.0f); - pShader->FXSetPSFloat(puddleParamName1, &vPuddleParams1, 1); - - // Volume - Vec4 vRainPosCS = Vec4(rainVolParams.vWorldPos, 1.f / max(rainVolParams.fRadius, 1e-3f)); - pShader->FXSetPSFloat(volumeParamName, &vRainPosCS, 1); - - // Global colour multiplier - float fAmount = rainVolParams.fCurrentAmount * CV_r_rainamount; - Vec4 vRainColorMultipliers = Vec4(rainVolParams.vColor, 1.f) * fAmount; - vRainColorMultipliers.w = fMaxZ > 0.f ? CV_r_rain_maxviewdist_deferred / viewParameters.fFar : 1.f; - vRainColorMultipliers.w = -10.f / vRainColorMultipliers.w; - pShader->FXSetPSFloat(colorMulParamName, &vRainColorMultipliers, 1); - - // Camera position - const Vec3& vCamPos = viewParameters.vOrigin; - Vec4 pCamPosParam = Vec4(vCamPos, 0.f); - pShader->FXSetPSFloat(wvpParamName, &pCamPosParam, 1); - - if (rainVolParams.bApplyOcclusion) - { - // Occlusion buffer matrix - pShader->FXSetPSFloat(occTransMatParamName, (Vec4*)rainVolParams.matOccTransRender.GetData(), 4); - - // Pre-calculate wind-driven occlusion sample offset - const float windOffsetScale = 15.f / (float)RAIN_OCC_MAP_SIZE; - windVec = rainVolParams.matOccTransRender.TransformVector(windVec); - windVec.x *= windOffsetScale; - windVec.y *= windOffsetScale; - - Vec4 pWindParams(windVec.x, windVec.y, 0.f, 0.f); - pShader->FXSetPSFloat(windParamName, &pWindParams, 1); - } - - if (!gmemEnabled) // can read straight from GMEM - { - SPostEffectsUtils::SetTexture(CTexture::s_ptexStereoL, 9, FILTER_POINT, 0); - SPostEffectsUtils::SetTexture(CTexture::s_ptexStereoR, 10, FILTER_POINT, 0); - SPostEffectsUtils::SetTexture(CTexture::s_ptexSceneNormalsBent, 11, FILTER_POINT, 0); - } - - // On GMEM we need to check if we have access to the depth RT or depth buffer. If not we push the depth as a texture to be sampled. - if(!gmemEnabled || gcpRendD3D->FX_GmemGetDepthStencilMode() == CD3D9Renderer::eGDSM_Texture) - { - // Bind stencil buffer - restoreStencilResourceView = true; - pDepthBufferRT->SetShaderResourceView(m_pZBufferStencilReadOnlySRV, bMSAA); - SResourceView::KeyType nBindResourceMsaa = gcpRendD3D->m_RP.m_MSAAData.Type ? SResourceView::DefaultViewMS : SResourceView::DefaultView; - pDepthBufferRT->Apply(12, CTexture::GetTexState(STexState(FILTER_POINT, true)), EFTT_UNKNOWN, -1, nBindResourceMsaa); - } - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexSceneNormalsMap->GetWidth(), CTexture::s_ptexSceneNormalsMap->GetHeight(), 1.0f); - SD3DPostEffectsUtils::ShEndPass(); - } - - // Restore original DSV/SRV - m_DepthBufferOrigMSAA.pSurf = pZBufferOrigDSV; - if (restoreStencilResourceView) - { - pDepthBufferRT->SetShaderResourceView(pZTargetOrigSRV, bMSAA); - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // no need to restore... this would break GMEM path - { - FX_PopRenderTarget(0); - FX_PopRenderTarget(1); - FX_PopRenderTarget(2); - } - - // Set persistent Rain Ripples Flag for Water Volumes and Ocean Ripple effect - m_RP.m_PersFlags2 |= RBPF2_RAINRIPPLES; - - m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_DeferredSnowLayer() -{ - const SSnowParams& snowVolParams = m_p3DEngineCommon.m_SnowInfo; - const SRainParams& rainVolParams = m_p3DEngineCommon.m_RainInfo; - CShader* pShader = CShaderMan::s_ShaderDeferredSnow; - const CameraViewParameters& cCam = gcpRendD3D->m_RP.m_TI[m_RP.m_nProcessThreadID].m_cam.m_viewParameters; - if ((CRenderer::CV_r_snow < 1) || (snowVolParams.m_fSnowAmount < 0.05f && snowVolParams.m_fFrostAmount < 0.05f && snowVolParams.m_fSurfaceFreezing < 0.05f) || snowVolParams.m_fRadius < 0.05f) - { - return false; - } - - // If GMEM path is enabled but no framebuffer fetches are supported, then neither can this pass. - // We would have to resolve which would break the GMEM path. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && !(RenderCapabilities::GetFrameBufferFetchCapabilities().test(RenderCapabilities::FBF_ALL_COLORS))) - { - AZ_Assert(false, "Device does not support framebuffer fetches for all color attachments. Deferred snow not supported with GMEM paths."); - return false; - } - - PROFILE_LABEL_SCOPE("DEFERRED_SNOW_ACCUMULATION"); - - if (CRenderer::CV_r_SlimGBuffer) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // needed RTs already in GMEM - { - // TODO: Try avoiding the copy by directly accessing UAVs - PostProcessUtils().StretchRect(CTexture::s_ptexSceneDiffuse, CTexture::s_ptexStereoL); - PostProcessUtils().StretchRect(CTexture::s_ptexSceneNormalsMap, CTexture::s_ptexBackBuffer); - PostProcessUtils().StretchRect(CTexture::s_ptexSceneSpecular, CTexture::s_ptexSceneNormalsBent); - - gcpRendD3D->FX_PushRenderTarget(0, CTexture::s_ptexSceneDiffuse, &gcpRendD3D->m_DepthBufferOrigMSAA); - gcpRendD3D->FX_PushRenderTarget(1, CTexture::s_ptexSceneNormalsMap, NULL); - gcpRendD3D->FX_PushRenderTarget(2, CTexture::s_ptexSceneSpecular, NULL); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_snow_displacement) - { - gcpRendD3D->FX_PushRenderTarget(3, CTexture::s_ptexStereoR, NULL); - } - } - else - { - //Disable this during water reflection recursion pass as the needed render targets are not in GMEM anymore. - if (SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID] > 0) - { - return false; - } - } - - - uint64 nFlagsShaderRTSave = m_RP.m_FlagsShader_RT; - - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3]; - if (IsHDRModeEnabled()) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_HDR_MODE]; - } - if (rainVolParams.bApplyOcclusion) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - static CCryNameTSCRC pTechName = "Snow"; - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechName, FEF_DONTSETSTATES); - FX_SetState(GS_NODEPTHTEST); - - // Textures - STexState sPointTexState = STexState(FILTER_POINT, true); - const int pointTexState = CTexture::GetTexState(sPointTexState); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // can read straight from GMEM - { - CTexture::s_ptexStereoL->Apply(0, pointTexState); - CTexture::s_ptexBackBuffer->Apply(1, pointTexState); - CTexture::s_ptexSceneNormalsBent->Apply(2, pointTexState); - } - - static CCryNameR paramName("g_SnowVolumeParams"); - const Vec3& vCamPos = cCam.vOrigin; - const Vec4 vSnowPosCS = Vec4(snowVolParams.m_vWorldPos, 1.f / max(snowVolParams.m_fRadius, 1e-3f)); - pShader->FXSetPSFloat(paramName, &vSnowPosCS, 1); - - static CCryNameR param1Name("g_SnowMultipliers"); - float fSnowAmount = snowVolParams.m_fSnowAmount; - float fFrostAmount = snowVolParams.m_fFrostAmount; - float fSurfaceFreezing = snowVolParams.m_fSurfaceFreezing; - Vec4 vSnowMultipliers(fSnowAmount, fFrostAmount, clamp_tpl(fSurfaceFreezing, 0.0f, 1.0f), 0); - pShader->FXSetPSFloat(param1Name, &vSnowMultipliers, 1); - - static CCryNameR param2Name("g_WorldViewPos"); - Vec4 pCamPosParam = Vec4(vCamPos, 1); - pShader->FXSetPSFloat(param2Name, &pCamPosParam, 1); - - // Sample wind at camera position - AABB box; - box.min = box.max = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_cam.m_viewParameters.vOrigin; - Vec3 windVec = gEnv->p3DEngine->GetWind(box, false); - - Vec3 windVecOcc = gEnv->p3DEngine->GetGlobalWind(false); - if (rainVolParams.bApplyOcclusion) - { - static CCryNameR param3Name("g_SnowOcc_TransMat"); - pShader->FXSetPSFloat(param3Name, (Vec4*)rainVolParams.matOccTransRender.GetData(), 3); - - // Pre-calculate wind-driven occlusion sample offset - const float windOffsetScale = 15.f / (float)RAIN_OCC_MAP_SIZE; - windVecOcc = rainVolParams.matOccTransRender.TransformVector(windVec); - windVecOcc.x *= windOffsetScale; - windVecOcc.y *= windOffsetScale; - - static CCryNameR param4Name("g_SnowOcc_WindOffs"); - Vec4 pWindParamsOcc(windVecOcc.x, windVecOcc.y, 0, 0); - pShader->FXSetPSFloat(param4Name, &pWindParamsOcc, 1); - } - - static CCryNameR param4Name("g_WindDirection"); - Vec4 pWindParams(windVec.x, windVec.y, windVecOcc.x, windVecOcc.y); - pShader->FXSetPSFloat(param4Name, &pWindParams, 1); - - short sX, sY, sWidth, sHeight; - CDeferredShading::Instance().GetScissors(snowVolParams.m_vWorldPos, snowVolParams.m_fRadius, sX, sY, sWidth, sHeight); - gcpRendD3D->EF_Scissor(true, sX, sY, sWidth, sHeight); - - // Render state - uint32 renderState = GS_STENCIL; - - gcpRendD3D->FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - BIT_STENCIL_RESERVED, BIT_STENCIL_RESERVED, 0xFFFFFFFF, true); - - gcpRendD3D->FX_SetState(renderState); - gcpRendD3D->FX_Commit(); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight(), 0, &gcpRendD3D->m_FullResRect); - SD3DPostEffectsUtils::ShEndPass(); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // no need to restore... this would break GMEM path - { - // Restore targets - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->FX_PopRenderTarget(1); - gcpRendD3D->FX_PopRenderTarget(2); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_snow_displacement) - { - gcpRendD3D->FX_PopRenderTarget(3); - } - } - - // Restore state - EF_Scissor(false, 0, 0, 0, 0); - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - gcpRendD3D->FX_Commit(); - - return true; -} - -bool CD3D9Renderer::FX_DeferredSnowDisplacement() -{ - const SSnowParams& snowVolParams = m_p3DEngineCommon.m_SnowInfo; - CShader* pShader = CShaderMan::s_ShaderDeferredSnow; - - if IsCVarConstAccess(constexpr) ((CRenderer::CV_r_snow < 1 || CRenderer::CV_r_snow_displacement < 1) || snowVolParams.m_fSnowAmount < 0.05f || snowVolParams.m_fRadius < 0.05f) - { - return false; - } - - // TODO: Implement this for GMEM path - // r_SnowDisplacement=1 not yet supported. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - CRY_ASSERT(0); - } - - PROFILE_LABEL_SCOPE("DEFERRED_SNOW_DISPLACEMENT"); - - static CCryNameR param5Name("g_CameraMatrix"); - Matrix44A matView; - matView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_cam.GetViewMatrix(); - - // Adjust the camera matrix so that the camera space will be: +y = down, +z - towards, +x - right - Vec3 zAxis = matView.GetRow(1); - matView.SetRow(1, -matView.GetRow(2)); - matView.SetRow(2, zAxis); - float z = matView.m13; - matView.m13 = -matView.m23; - matView.m23 = z; - - short sX, sY, sWidth, sHeight; - CDeferredShading::Instance().GetScissors(snowVolParams.m_vWorldPos, snowVolParams.m_fRadius, sX, sY, sWidth, sHeight); - EF_Scissor(true, sX, sY, sWidth, sHeight); - - TransformationMatrices backupSceneMatrices; - - gcpRendD3D->Set2DMode(1, 1, backupSceneMatrices); - - // Render state - uint32 renderState = GS_NODEPTHTEST | GS_STENCIL; - - gcpRendD3D->FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - BIT_STENCIL_RESERVED, BIT_STENCIL_RESERVED, 0xFFFFFFFF, true); - - gcpRendD3D->FX_SetState(renderState); - gcpRendD3D->FX_Commit(); - - { - PROFILE_LABEL_SCOPE("GENERATE_HEIGHT_MAP"); - static CCryNameTSCRC pTechNamePrepass = "ParallaxMapPrepass"; - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechNamePrepass, FEF_DONTSETSTATES); - - FX_PushRenderTarget(0, CTexture::s_ptexBackBuffer, NULL); - - pShader->FXSetPSFloat(param5Name, (Vec4*)matView.GetData(), 3); - - PostProcessUtils().SetTexture(CTexture::s_ptexStereoR, 0, FILTER_POINT); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight()); - - SD3DPostEffectsUtils::ShEndPass(); - - FX_PopRenderTarget(0); - } - - { - static CCryNameTSCRC pTechNameMin = "ParallaxMapMin"; - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechNameMin, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - - FX_PushRenderTarget(0, CTexture::s_ptexSceneDiffuseAccMap, NULL); - - PostProcessUtils().SetTexture(CTexture::s_ptexBackBuffer, 0, FILTER_POINT); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexSceneDiffuseAccMap->GetHeight()); - - SD3DPostEffectsUtils::ShEndPass(); - - FX_PopRenderTarget(0); - } - - // Copy screen to texture for displacement. - FX_ScreenStretchRect(CTexture::s_ptexHDRTarget); - - // Iteratively apply displacement to maximize quality and minimize sample count. - { - PROFILE_LABEL_SCOPE("APPLY_DISPLACEMENT"); - static CCryNameTSCRC pTechNameApply = "ParallaxMapApply"; - static CCryNameR pPassParamsName("g_DisplacementParams"); - Vec4 pPassParams(0, 0, 0, 0); - - uint64 nFlagsShaderRTSave = m_RP.m_FlagsShader_RT; - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - - // First pass. - FX_PushRenderTarget(0, CTexture::s_ptexSceneTarget, NULL); - FX_PushRenderTarget(1, CTexture::s_ptexSceneSpecularAccMap, NULL); - - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechNameApply, FEF_DONTSETSTATES); - - PostProcessUtils().SetTexture(CTexture::s_ptexHDRTarget, 0, FILTER_LINEAR); - PostProcessUtils().SetTexture(CTexture::s_ptexSceneDiffuseAccMap, 1, FILTER_LINEAR); - pPassParams.x = 1.0f; - pShader->FXSetPSFloat(pPassParamsName, &pPassParams, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - FX_PopRenderTarget(0); - FX_PopRenderTarget(1); - - // Second pass. - FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, NULL); - FX_PushRenderTarget(1, CTexture::s_ptexSceneDiffuseAccMap, NULL); - - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechNameApply, FEF_DONTSETSTATES); - - PostProcessUtils().SetTexture(CTexture::s_ptexSceneTarget, 0, FILTER_LINEAR); - PostProcessUtils().SetTexture(CTexture::s_ptexSceneSpecularAccMap, 1, FILTER_LINEAR); - pPassParams.x = 0.5f; - pShader->FXSetPSFloat(pPassParamsName, &pPassParams, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - FX_PopRenderTarget(0); - FX_PopRenderTarget(1); - - // Third pass. - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - - FX_PushRenderTarget(0, CTexture::s_ptexSceneTarget, NULL); - FX_PushRenderTarget(1, CTexture::s_ptexZTarget, NULL); - - SD3DPostEffectsUtils::ShBeginPass(pShader, pTechNameApply, FEF_DONTSETSTATES); - FX_SetState(GS_NODEPTHTEST); - - PostProcessUtils().SetTexture(CTexture::s_ptexHDRTarget, 0, FILTER_LINEAR); - PostProcessUtils().SetTexture(CTexture::s_ptexSceneDiffuseAccMap, 1, FILTER_LINEAR); - pPassParams.x = 0.25f; - pShader->FXSetPSFloat(pPassParamsName, &pPassParams, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - FX_PopRenderTarget(0); - FX_PopRenderTarget(1); - - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - } - - PostProcessUtils().CopyTextureToScreen(CTexture::s_ptexSceneTarget); - - EF_Scissor(false, 0, 0, 0, 0); - - FX_Commit(); - - FX_ResetPipe(); - - gcpRendD3D->Unset2DMode(backupSceneMatrices); - - return true; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredRender.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredRender.cpp deleted file mode 100644 index 7b8c22b9bc..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredRender.cpp +++ /dev/null @@ -1,1800 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "D3DPostProcess.h" -#include "Common/RenderCapabilities.h" -#include "../Common/Textures/TextureManager.h" -#include "GraphicsPipeline/FurPasses.h" - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DDeferredRender_cpp) -#endif - - -bool CD3D9Renderer::FX_DeferredShadowPassSetupBlend(const Matrix44& mShadowTexGen, int nFrustumNum, float maskRTWidth, float maskRTHeight) -{ - //set ScreenToWorld Expansion Basis - Vec4r vWBasisX, vWBasisY, vWBasisZ, vCamPos; - CShadowUtils::ProjectScreenToWorldExpansionBasis(mShadowTexGen, GetCamera(), Vec2(m_TemporalJitterClipSpace.x, m_TemporalJitterClipSpace.y), maskRTWidth, maskRTHeight, vWBasisX, vWBasisY, vWBasisZ, vCamPos, true, &m_RenderTileInfo); - - Matrix44A* mat = &gRenDev->m_TempMatrices[nFrustumNum][2]; - mat->SetRow4(0, Vec4r(vWBasisX.x, vWBasisY.x, vWBasisZ.x, vCamPos.x)); - mat->SetRow4(1, Vec4r(vWBasisX.y, vWBasisY.y, vWBasisZ.y, vCamPos.y)); - mat->SetRow4(2, Vec4r(vWBasisX.z, vWBasisY.z, vWBasisZ.z, vCamPos.z)); - mat->SetRow4(3, Vec4r(vWBasisX.w, vWBasisY.w, vWBasisZ.w, vCamPos.w)); - - return true; -} - -bool CD3D9Renderer::FX_DeferredShadowPassSetup(const Matrix44& mShadowTexGen, [[maybe_unused]] ShadowMapFrustum* pShadowFrustum, float maskRTWidth, float maskRTHeight, Matrix44& mScreenToShadow, bool bNearest) -{ - //set ScreenToWorld Expansion Basis - Vec4r vWBasisX, vWBasisY, vWBasisZ, vCamPos; - bool bVPosSM30 = (GetFeatures() & (RFT_HW_SM30 | RFT_HW_SM40)) != 0; - - CCamera Cam = GetCamera(); - if (bNearest && m_drawNearFov > 1.0f && m_drawNearFov < 179.0f) - { - Cam.SetFrustum(Cam.GetViewSurfaceX(), Cam.GetViewSurfaceZ(), DEG2RAD(m_drawNearFov), Cam.GetNearPlane(), Cam.GetFarPlane(), Cam.GetPixelAspectRatio()); - } - - CShadowUtils::ProjectScreenToWorldExpansionBasis(mShadowTexGen, Cam, Vec2(m_TemporalJitterClipSpace.x, m_TemporalJitterClipSpace.y), maskRTWidth, maskRTHeight, vWBasisX, vWBasisY, vWBasisZ, vCamPos, bVPosSM30, &m_RenderTileInfo); - - //TOFIX: create PB components for these params - //creating common projection matrix for depth reconstruction - - mScreenToShadow = Matrix44(vWBasisX.x, vWBasisX.y, vWBasisX.z, vWBasisX.w, - vWBasisY.x, vWBasisY.y, vWBasisY.z, vWBasisY.w, - vWBasisZ.x, vWBasisZ.y, vWBasisZ.z, vWBasisZ.w, - vCamPos.x, vCamPos.y, vCamPos.z, vCamPos.w); - - //save magnitudes separately to inrease precision - m_cEF.m_TempVecs[14].x = vWBasisX.GetLength(); - m_cEF.m_TempVecs[14].y = vWBasisY.GetLength(); - m_cEF.m_TempVecs[14].z = vWBasisZ.GetLength(); - m_cEF.m_TempVecs[14].w = 1.0f; - - //Vec4r normalization in doubles - vWBasisX /= vWBasisX.GetLength(); - vWBasisY /= vWBasisY.GetLength(); - vWBasisZ /= vWBasisZ.GetLength(); - - m_cEF.m_TempVecs[10].x = vWBasisX.x; - m_cEF.m_TempVecs[10].y = vWBasisX.y; - m_cEF.m_TempVecs[10].z = vWBasisX.z; - m_cEF.m_TempVecs[10].w = vWBasisX.w; - - m_cEF.m_TempVecs[11].x = vWBasisY.x; - m_cEF.m_TempVecs[11].y = vWBasisY.y; - m_cEF.m_TempVecs[11].z = vWBasisY.z; - m_cEF.m_TempVecs[11].w = vWBasisY.w; - - m_cEF.m_TempVecs[12].x = vWBasisZ.x; - m_cEF.m_TempVecs[12].y = vWBasisZ.y; - m_cEF.m_TempVecs[12].z = vWBasisZ.z; - m_cEF.m_TempVecs[12].w = vWBasisZ.w; - - m_cEF.m_TempVecs[13].x = CV_r_ShadowsAdaptionRangeClamp; - m_cEF.m_TempVecs[13].y = CV_r_ShadowsAdaptionSize * 250.f;//to prevent akwardy high number in cvar - m_cEF.m_TempVecs[13].z = CV_r_ShadowsAdaptionMin; - - // Particles shadow constants - if (m_RP.m_nPassGroupID == EFSLIST_TRANSP || m_RP.m_nPassGroupID == EFSLIST_HALFRES_PARTICLES) - { - m_cEF.m_TempVecs[13].x = CV_r_ShadowsParticleKernelSize; - m_cEF.m_TempVecs[13].y = CV_r_ShadowsParticleJitterAmount; - m_cEF.m_TempVecs[13].z = CV_r_ShadowsParticleAnimJitterAmount * 0.05f; - m_cEF.m_TempVecs[13].w = CV_r_ShadowsParticleNormalEffect; - } - - m_cEF.m_TempVecs[0].x = vCamPos.x; - m_cEF.m_TempVecs[0].y = vCamPos.y; - m_cEF.m_TempVecs[0].z = vCamPos.z; - m_cEF.m_TempVecs[0].w = vCamPos.w; - - return true; -} - - -HRESULT GetSampleOffsetsGaussBlur5x5Bilinear(DWORD dwD3DTexWidth, DWORD dwD3DTexHeight, Vec4* avTexCoordOffset, Vec4* avSampleWeight, FLOAT fMultiplier) -{ - float tu = 1.0f / (float)dwD3DTexWidth; - float tv = 1.0f / (float)dwD3DTexHeight; - float totalWeight = 0.0f; - Vec4 vWhite(1.f, 1.f, 1.f, 1.f); - float fWeights[6]; - - int index = 0; - for (int x = -2; x <= 2; x++, index++) - { - fWeights[index] = PostProcessUtils().GaussianDistribution2D((float)x, 0.f, 4); - } - - // compute weights for the 2x2 taps. only 9 bilinear taps are required to sample the entire area. - index = 0; - for (int y = -2; y <= 2; y += 2) - { - float tScale = (y == 2) ? fWeights[4] : (fWeights[y + 2] + fWeights[y + 3]); - float tFrac = fWeights[y + 2] / tScale; - float tOfs = ((float)y + (1.f - tFrac)) * tv; - for (int x = -2; x <= 2; x += 2, index++) - { - float sScale = (x == 2) ? fWeights[4] : (fWeights[x + 2] + fWeights[x + 3]); - float sFrac = fWeights[x + 2] / sScale; - float sOfs = ((float)x + (1.f - sFrac)) * tu; - avTexCoordOffset[index] = Vec4(sOfs, tOfs, 0, 1); - avSampleWeight[index] = vWhite * sScale * tScale; - totalWeight += sScale * tScale; - } - } - - - for (int i = 0; i < index; i++) - { - avSampleWeight[i] *= (fMultiplier / totalWeight); - } - - return S_OK; -} - -int CRenderer::FX_ApplyShadowQuality() -{ - SShaderProfile* pSP = &m_cEF.m_ShaderProfiles[eST_Shadow]; - const uint64 quality = g_HWSR_MaskBit[HWSR_QUALITY]; - const uint64 quality1 = g_HWSR_MaskBit[HWSR_QUALITY1]; - m_RP.m_FlagsShader_RT &= ~(quality | quality1); - - int nQuality = (int)pSP->GetShaderQuality(); - m_RP.m_nShaderQuality = nQuality; - switch (nQuality) - { - case eSQ_Medium: - m_RP.m_FlagsShader_RT |= quality; - break; - case eSQ_High: - m_RP.m_FlagsShader_RT |= quality1; - break; - case eSQ_VeryHigh: - m_RP.m_FlagsShader_RT |= quality; - m_RP.m_FlagsShader_RT |= quality1; - break; - } - return nQuality; -} - -void CD3D9Renderer::FX_StateRestore([[maybe_unused]] int prevState) -{ -} - -//setup pass offset -// Draw a fullscreen quad to sample the RT -//EF_Commit() is called here -////////////////////////////////////////////////////////////////////////// -// X Blur -// Draw a fullscreen quad to sample the RT -void CD3D9Renderer::FX_StencilTestCurRef(bool bEnable, [[maybe_unused]] bool bNoStencilClear, bool bStFuncEqual) -{ - if (bEnable) - { - int nStencilState = - STENC_FUNC(bStFuncEqual ? FSS_STENCFUNC_EQUAL : FSS_STENCFUNC_NOTEQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP); - - FX_SetStencilState(nStencilState, m_nStencilMaskRef, 0xFFFFFFFF, 0xFFFFFFFF); - FX_SetState(m_RP.m_CurState | GS_STENCIL); - } - else - { - } -} - -void CD3D9Renderer::FX_DeferredShadowPass([[maybe_unused]] const SRenderLight* pLight, ShadowMapFrustum* pShadowFrustum, bool bShadowPass, bool bCloudShadowPass, bool bStencilPrepass, int nLod) -{ - uint32 nPassCount = 0; - CShader* pShader = CShaderMan::s_ShaderShadowMaskGen; - static CCryNameTSCRC DeferredShadowTechName = "DeferredShadowPass"; - - D3DSetCull(eCULL_Back, true); //fs quads should not revert test.. - - if (pShadowFrustum->m_eFrustumType != ShadowMapFrustum::e_Nearest && !bCloudShadowPass) - { - if (pShadowFrustum->bUseShadowsPool || pShadowFrustum->pDepthTex == NULL) - { - return; - } - } - - if (pShadowFrustum->m_eFrustumType == ShadowMapFrustum::e_HeightMapAO) - { - return; - } - - int nShadowQuality = FX_ApplyShadowQuality(); - - ////////////////////////////////////////////////////////////////////////// - // set global shader RT flags - ////////////////////////////////////////////////////////////////////////// - - // set pass dependent RT flags - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[ HWSR_SAMPLE0 ] | g_HWSR_MaskBit[ HWSR_SAMPLE1 ] | g_HWSR_MaskBit[ HWSR_SAMPLE2 ] | g_HWSR_MaskBit[ HWSR_SAMPLE4 ] | - g_HWSR_MaskBit[HWSR_CUBEMAP0] | g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ] | g_HWSR_MaskBit[ HWSR_POINT_LIGHT ] | - g_HWSR_MaskBit[ HWSR_SHADOW_MIXED_MAP_G16R16 ] | g_HWSR_MaskBit[HWSR_SHADOW_JITTERING] | g_HWSR_MaskBit[HWSR_NEAREST]); - - if (!pShadowFrustum->bBlendFrustum) - { - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - } - - if (m_shadowJittering > 0.0f) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SHADOW_JITTERING ]; - } - - //enable hw-pcf per frustum - if (pShadowFrustum->bHWPCFCompare) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]; - } - - if (pShadowFrustum->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NEAREST]; - } - - if (bCloudShadowPass || (CV_r_ShadowsScreenSpace && bShadowPass && pShadowFrustum->nShadowMapLod == 0)) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE2 ]; - } - - ConfigShadowTexgen(0, pShadowFrustum); - if (nShadowQuality == eSQ_VeryHigh) //DX10 only - { - ConfigShadowTexgen(1, pShadowFrustum, -1, false, false); - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE1 ]; - } - - int newState = m_RP.m_CurState; - newState &= ~(GS_DEPTHWRITE | GS_BLSRC_ONE | GS_BLDST_ONE | GS_BLOP_MAX); - newState |= GS_NODEPTHTEST; - - if (pShadowFrustum->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - newState &= ~(GS_NODEPTHTEST | GS_DEPTHFUNC_MASK); - newState |= GS_DEPTHFUNC_GREAT; - } - - // In GMEM, we do our own clouds shadow blending - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr) || - (gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && !bCloudShadowPass)) - { - if (pShadowFrustum->bUseAdditiveBlending) - { - newState |= GS_BLSRC_ONE | GS_BLDST_ONE | GS_BLOP_MAX; - } - else if (bShadowPass && pShadowFrustum->bBlendFrustum) - { - newState |= GS_BLSRC_ONE | GS_BLDST_ONE; - } - } - - pShader->FXSetTechnique(DeferredShadowTechName); - pShader->FXBegin(&nPassCount, FEF_DONTSETSTATES); - - - ////////////////////////////////////////////////////////////////////////// - //Stencil cull pre-pass for GSM - ////////////////////////////////////////////////////////////////////////// - if (bStencilPrepass) - { - newState |= GS_STENCIL; - //Disable color writes - newState |= GS_COLMASK_NONE; - - FX_SetState(newState); - ////////////////////////////////////////////////////////////////////////// - - //render clip volume - Matrix44 mViewProj = pShadowFrustum->mLightViewMatrix; - Matrix44 mViewProjInv = mViewProj.GetInverted(); - gRenDev->m_TempMatrices[0][0] = mViewProjInv.GetTransposed(); - - FX_SetVStream(0, m_pUnitFrustumVB[SHAPE_SIMPLE_PROJECTOR], 0, sizeof(SVF_P3F_C4B_T2F)); - FX_SetIStream(m_pUnitFrustumIB[SHAPE_SIMPLE_PROJECTOR], 0, (kUnitObjectIndexSizeof == 2 ? Index16 : Index32)); - - if (!CV_r_ShadowsUseClipVolume || !RenderCapabilities::SupportsDepthClipping()) - { - FX_StencilCullPass(nLod, m_UnitFrustVBSize[SHAPE_SIMPLE_PROJECTOR], m_UnitFrustIBSize[SHAPE_SIMPLE_PROJECTOR], pShader, DS_STENCIL_VOLUME_CLIP, DS_STENCIL_VOLUME_CLIP_FRONTFACING); - } - else - { - FX_StencilCullPass(nLod, m_UnitFrustVBSize[SHAPE_SIMPLE_PROJECTOR], m_UnitFrustIBSize[SHAPE_SIMPLE_PROJECTOR], pShader, DS_STENCIL_VOLUME_CLIP); - } - - // camera might be outside cached frustum => do front facing pass as well - if (pShadowFrustum->IsCached()) - { - Vec4 vCamPosShadowSpace = Vec4(GetViewParameters().vOrigin, 1.f) * mViewProj; - vCamPosShadowSpace /= vCamPosShadowSpace.w; - if (abs(vCamPosShadowSpace.x) > 1.0f || abs(vCamPosShadowSpace.y) > 1.0f || vCamPosShadowSpace.z < 0 || vCamPosShadowSpace.z > 1) - { - pShader->FXBeginPass(DS_STENCIL_VOLUME_CLIP); - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - D3DSetCull(eCULL_Back); - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_ZERO) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nLod, 0xFFFFFFFF, 0xFFFF - ); - - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, m_UnitFrustVBSize[SHAPE_SIMPLE_PROJECTOR], 0, m_UnitFrustIBSize[SHAPE_SIMPLE_PROJECTOR]); - } - pShader->FXEndPass(); - } - } - - } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Shadow Pass - ////////////////////////////////////////////////////////////////////////// - - if (bShadowPass) - { - newState &= ~(GS_COLMASK_NONE | GS_STENCIL); - - // When optimizations are on, we need only the R channel. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && (CRenderer::CV_r_DeferredShadingLBuffersFmt != 2)) // A component write mask of GMEM light diffuse RT - { - newState |= GS_NOCOLMASK_R | GS_NOCOLMASK_G | GS_NOCOLMASK_B; - } - else - { - newState |= GS_NOCOLMASK_G | GS_NOCOLMASK_B | GS_NOCOLMASK_A; - } - - if (nLod != 0 && !bCloudShadowPass) - { - newState |= GS_STENCIL; - - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nLod, 0xFFFFFFFF, 0xFFFFFFFF - ); - } - - FX_SetState(newState); - - pShader->FXBeginPass(bCloudShadowPass ? DS_CLOUDS_SEPARATE : DS_SHADOW_PASS); - - const float fCustomZ = pShadowFrustum->m_eFrustumType == ShadowMapFrustum::e_Nearest ? CV_r_DrawNearZRange - 0.001f : 0.f; - PostProcessUtils().DrawFullScreenTriWPOS(0, 0, fCustomZ); - - pShader->FXEndPass(); - } - pShader->FXEnd(); -} - - -#define LOCAL_SAFE_RELEASE(buffer) \ - if (buffer) \ - { \ - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(buffer); \ - buffer = nullptr; \ - } - -bool CD3D9Renderer::CreateAuxiliaryMeshes() -{ - t_arrDeferredMeshIndBuff arrDeferredInds; - t_arrDeferredMeshVertBuff arrDeferredVerts; - - uint nProjectorMeshStep = 10; - - //projector frustum mesh - for (int i = 0; i < 3; i++) - { - uint nFrustTess = 11 + nProjectorMeshStep * i; - CDeferredRenderUtils::CreateUnitFrustumMesh(nFrustTess, nFrustTess, arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[SHAPE_PROJECTOR + i]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[SHAPE_PROJECTOR + i]); - COMPILE_TIME_ASSERT(kUnitObjectIndexSizeof == sizeof(arrDeferredInds[0])); - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, m_pUnitFrustumIB[SHAPE_PROJECTOR + i], m_pUnitFrustumVB[SHAPE_PROJECTOR + i]); - m_UnitFrustVBSize[SHAPE_PROJECTOR + i] = arrDeferredVerts.size(); - m_UnitFrustIBSize[SHAPE_PROJECTOR + i] = arrDeferredInds.size(); - } - - //clip-projector frustum mesh - for (int i = 0; i < 3; i++) - { - uint nClipFrustTess = 41 + nProjectorMeshStep * i; - CDeferredRenderUtils::CreateUnitFrustumMesh(nClipFrustTess, nClipFrustTess, arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[SHAPE_CLIP_PROJECTOR + i]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[SHAPE_CLIP_PROJECTOR + i]); - COMPILE_TIME_ASSERT(kUnitObjectIndexSizeof == sizeof(arrDeferredInds[0])); - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, m_pUnitFrustumIB[SHAPE_CLIP_PROJECTOR + i], m_pUnitFrustumVB[SHAPE_CLIP_PROJECTOR + i]); - m_UnitFrustVBSize[SHAPE_CLIP_PROJECTOR + i] = arrDeferredVerts.size(); - m_UnitFrustIBSize[SHAPE_CLIP_PROJECTOR + i] = arrDeferredInds.size(); - } - - //omni-light mesh - //Use tess3 for big lights - CDeferredRenderUtils::CreateUnitSphere(2, arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[SHAPE_SPHERE]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[SHAPE_SPHERE]); - COMPILE_TIME_ASSERT(kUnitObjectIndexSizeof == sizeof(arrDeferredInds[0])); - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, m_pUnitFrustumIB[SHAPE_SPHERE], m_pUnitFrustumVB[SHAPE_SPHERE]); - m_UnitFrustVBSize[SHAPE_SPHERE] = arrDeferredVerts.size(); - m_UnitFrustIBSize[SHAPE_SPHERE] = arrDeferredInds.size(); - - //unit box - CDeferredRenderUtils::CreateUnitBox(arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[SHAPE_BOX]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[SHAPE_BOX]); - COMPILE_TIME_ASSERT(kUnitObjectIndexSizeof == sizeof(arrDeferredInds[0])); - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, m_pUnitFrustumIB[SHAPE_BOX], m_pUnitFrustumVB[SHAPE_BOX]); - m_UnitFrustVBSize[SHAPE_BOX] = arrDeferredVerts.size(); - m_UnitFrustIBSize[SHAPE_BOX] = arrDeferredInds.size(); - - //frustum approximated with 8 vertices - CDeferredRenderUtils::CreateSimpleLightFrustumMesh(arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[SHAPE_SIMPLE_PROJECTOR]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[SHAPE_SIMPLE_PROJECTOR]); - COMPILE_TIME_ASSERT(kUnitObjectIndexSizeof == sizeof(arrDeferredInds[0])); - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, m_pUnitFrustumIB[SHAPE_SIMPLE_PROJECTOR], m_pUnitFrustumVB[SHAPE_SIMPLE_PROJECTOR]); - m_UnitFrustVBSize[SHAPE_SIMPLE_PROJECTOR] = arrDeferredVerts.size(); - m_UnitFrustIBSize[SHAPE_SIMPLE_PROJECTOR] = arrDeferredInds.size(); - - // FS quad - CDeferredRenderUtils::CreateQuad(arrDeferredInds, arrDeferredVerts); - LOCAL_SAFE_RELEASE(m_pQuadVB); - D3DBuffer* pDummyQuadIB = 0; // reusing CreateUnitVolumeMesh. - CreateUnitVolumeMesh(arrDeferredInds, arrDeferredVerts, pDummyQuadIB, m_pQuadVB); - m_nQuadVBSize = arrDeferredVerts.size(); - - return true; -} - -bool CD3D9Renderer::ReleaseAuxiliaryMeshes() -{ - for (int i = 0; i < SHAPE_MAX; i++) - { - LOCAL_SAFE_RELEASE(m_pUnitFrustumVB[i]); - LOCAL_SAFE_RELEASE(m_pUnitFrustumIB[i]); - } - - LOCAL_SAFE_RELEASE(m_pQuadVB); - m_nQuadVBSize = 0; - - return true; -} - -bool CD3D9Renderer::CreateUnitVolumeMesh(t_arrDeferredMeshIndBuff& arrDeferredInds, t_arrDeferredMeshVertBuff& arrDeferredVerts, D3DBuffer*& pUnitFrustumIB, D3DBuffer*& pUnitFrustumVB) -{ - HRESULT hr = S_OK; - - //FIX: try default pools - - D3D11_BUFFER_DESC BufDesc; - ZeroStruct(BufDesc); - D3D11_SUBRESOURCE_DATA SubResData; - ZeroStruct(SubResData); - - if (!arrDeferredVerts.empty()) - { - BufDesc.ByteWidth = arrDeferredVerts.size() * sizeof(SDeferMeshVert); - BufDesc.Usage = D3D11_USAGE_IMMUTABLE; - BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufDesc.CPUAccessFlags = 0; - BufDesc.MiscFlags = 0; - - SubResData.pSysMem = &arrDeferredVerts[0]; - SubResData.SysMemPitch = 0; - SubResData.SysMemSlicePitch = 0; - - hr = gcpRendD3D->m_DevMan.CreateD3D11Buffer(&BufDesc, &SubResData, (ID3D11Buffer**)&pUnitFrustumVB, "UnitVolumeMesh"); - assert(SUCCEEDED(hr)); - } - - if (!arrDeferredInds.empty()) - { - ZeroStruct(BufDesc); - BufDesc.ByteWidth = arrDeferredInds.size() * sizeof(arrDeferredInds[0]); - BufDesc.Usage = D3D11_USAGE_IMMUTABLE; - BufDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - BufDesc.CPUAccessFlags = 0; - BufDesc.MiscFlags = 0; - - ZeroStruct(SubResData); - SubResData.pSysMem = &arrDeferredInds[0]; - SubResData.SysMemPitch = 0; - SubResData.SysMemSlicePitch = 0; - - hr = gcpRendD3D->m_DevMan.CreateD3D11Buffer(&BufDesc, &SubResData, &pUnitFrustumIB, "UnitVolumeMesh"); - assert(SUCCEEDED(hr)); - } - - return SUCCEEDED(hr); -} - -void CD3D9Renderer::SetBackFacingStencillState(int nStencilID) -{ - int newState = m_RP.m_CurState; - - //Set LS colormask - //debug states - if IsCVarConstAccess(constexpr) (CV_r_DebugLightVolumes /*&& m_RP.m_TI.m_PersFlags2 & d3dRBPF2_ENABLESTENCILPB*/) - { - newState &= ~GS_COLMASK_NONE; - newState &= ~GS_NODEPTHTEST; - //newState |= GS_NODEPTHTEST; - newState |= GS_DEPTHWRITE; - newState |= (0xFFFFFFF0 << GS_COLMASK_SHIFT) & GS_COLMASK_MASK; - if IsCVarConstAccess(constexpr) (CV_r_DebugLightVolumes > 1) - { - newState |= GS_WIREFRAME; - } - } - else - { - // //Disable color writes - //if (CV_r_ShadowsStencilPrePass == 2) - //{ - // newState &= ~GS_COLMASK_NONE; - // newState |= GS_COLMASK_A; - //} - //else - { - newState |= GS_COLMASK_NONE; - } - - - //setup depth test and enable stencil - newState &= ~(GS_NODEPTHTEST | GS_DEPTHWRITE | GS_DEPTHFUNC_MASK); - newState |= GS_DEPTHFUNC_LEQUAL | GS_STENCIL; - } - - ////////////////////////////////////////////////////////////////////////// - //draw back faces - inc when depth fail. - ////////////////////////////////////////////////////////////////////////// - int stencilFunc = FSS_STENCFUNC_ALWAYS; - uint32 nCurrRef = 0; - if (nStencilID >= 0) - { - D3DSetCull(eCULL_Front); - - //if (nStencilID>0) - stencilFunc = m_RP.m_CurStencilCullFunc; - - FX_SetStencilState( - STENC_FUNC(stencilFunc) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nStencilID, 0xFFFFFFFF, 0xFFFF - ); - // uint32 nStencilWriteMask = 1 << nStencilID; //0..7 - // FX_SetStencilState( - // STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - // STENCOP_FAIL(FSS_STENCOP_KEEP) | - // STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - // STENCOP_PASS(FSS_STENCOP_KEEP), - // 0xFF, 0xFFFFFFFF, nStencilWriteMask - // ); - } - else if (nStencilID == -4) // set all pixels with nCurRef within clip volume to nCurRef-1 - { - stencilFunc = FSS_STENCFUNC_EQUAL; - - nCurrRef = m_nStencilMaskRef; - - FX_SetStencilState( - STENC_FUNC(stencilFunc) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_DECR) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nCurrRef, 0xFFFFFFFF, 0xFFFF - ); - - m_nStencilMaskRef--; - D3DSetCull(eCULL_Front); - } - else - { - if (nStencilID == -3) //TD: Fill stencil by values=1 for drawn volumes in order to avoid overdraw - { - stencilFunc = FSS_STENCFUNC_LEQUAL; - - m_nStencilMaskRef--; - } - else if (nStencilID == -2) - { - stencilFunc = FSS_STENCFUNC_GEQUAL; - m_nStencilMaskRef--; - } - else - { - stencilFunc = FSS_STENCFUNC_GEQUAL; - m_nStencilMaskRef++; - //m_nStencilMaskRef = m_nStencilMaskRef%STENC_MAX_REF + m_nStencilMaskRef/STENC_MAX_REF; - if (m_nStencilMaskRef > STENC_MAX_REF) - { - int sX = 0, sY = 0, sWidth = 0, sHeight = 0; - bool bScissorEnabled = EF_GetScissorState(sX, sY, sWidth, sHeight); - EF_Scissor(false, 0, 0, 0, 0); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // We must clear via full pass or else it'll kick buffers off GMEM - { - uint32 prevState = m_RP.m_CurState; - uint32 state = 0; - state |= GS_COLMASK_NONE; - state |= GS_STENCIL; - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_ZERO) | - STENCOP_ZFAIL(FSS_STENCOP_ZERO) | - STENCOP_PASS(FSS_STENCOP_ZERO), - 0, 0xFFFFFFFF, 0xFFFF); - FX_SetState(state); - SD3DPostEffectsUtils::ClearScreen(0, 0, 0, 0); - FX_SetState(prevState); - } - else - { - EF_ClearTargetsImmediately(FRT_CLEAR_STENCIL, Clr_Unused.r, 1); - } - - EF_Scissor(bScissorEnabled, sX, sY, sWidth, sHeight); - m_nStencilMaskRef = 2; - } - } - - nCurrRef = m_nStencilMaskRef; - assert(m_nStencilMaskRef > 0 && m_nStencilMaskRef <= STENC_MAX_REF); - - D3DSetCull(eCULL_Front); - FX_SetStencilState( - STENC_FUNC(stencilFunc) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nCurrRef, 0xFFFFFFFF, 0xFFFF - ); - } - - FX_SetState(newState); - FX_Commit(); -} - -void CD3D9Renderer::SetFrontFacingStencillState(int nStencilID) -{ - if (nStencilID < 0) - { - D3DSetCull(eCULL_Back); - //TD: deferred meshed should have proper front facing on dx10 - int currentStencilFunction = m_RP.m_CurStencilState & FSS_STENCFUNC_MASK; - FX_SetStencilState( - STENC_FUNC(currentStencilFunction) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_ZERO) | - STENCOP_PASS(FSS_STENCOP_KEEP), - m_nStencilMaskRef, 0xFFFFFFFF, 0xFFFF - ); - - FX_SetState(m_RP.m_CurState); - FX_Commit(); - } -} - -//This version of the function uses two different passes and clamps the back facing triangles to the far plane in the vertex shader. -//Use this when you dont have support for DepthClipEnable. Also, this setup assumes reverse depth. -void CD3D9Renderer::FX_StencilCullPass(int nStencilID, int nNumVers, int nNumInds, CShader* pShader, int backFacePass, int frontFacePass ) -{ - //Render pass for back facing triangles - pShader->FXBeginPass(backFacePass); - - //We can only check for vertexDeclaration after setting the pass. We have techniques with - //multiple passes that can use different input layout. This way we ensure we are matching against - //the correct input layout of the correct pass - if (FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - AZ_Assert(false, "Skipping the draw inside FX_StencilCullPass as the vertex declaration for shader %s pass %i failed", pShader->m_NameShader.c_str(), backFacePass); - pShader->FXEndPass(); - return; - } - SetBackFacingStencillState(nStencilID); - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nNumVers, 0, nNumInds); - pShader->FXEndPass(); - - //Render pass for front facing triangles - pShader->FXBeginPass(frontFacePass); - SetFrontFacingStencillState(nStencilID); - //skip front faces when nStencilID is specified - if (nStencilID < 0) - { - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nNumVers, 0, nNumInds); - } - pShader->FXEndPass(); - - return; -} - - -//This version of the function assumes we have support for DepthClipEnable. Assumes reverse depth. -void CD3D9Renderer::FX_StencilCullPass(int nStencilID, int nNumVers, int nNumInds, CShader* pShader, int backFacePass) -{ - //Render pass for back facing triangles - pShader->FXBeginPass(backFacePass); - - //We can only check for vertexDeclaration after setting the pass. We have techniques with - //multiple passes that can use different input layout. This way we ensure we are matching against - //the correct input layout of the correct pass - if (FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - //AZ_Assert(false, "Skipping the draw inside FX_StencilCullPass as the vertex declaration for shader %s pass %i failed", pShader->m_NameShader.c_str(), backFacePass); - pShader->FXEndPass(); - return; - } - - SetBackFacingStencillState(nStencilID); - - // Don't clip pixels beyond far clip plane - SStateRaster PreviousRS = m_StatesRS[m_nCurStateRS]; - SStateRaster NoDepthClipRS = PreviousRS; - NoDepthClipRS.Desc.DepthClipEnable = false; - SetRasterState(&NoDepthClipRS); - - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nNumVers, 0, nNumInds); - SetRasterState(&PreviousRS); - - //Render pass for front facing triangles - SetFrontFacingStencillState(nStencilID); - //skip front faces when nStencilID is specified - if (nStencilID < 0) - { - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nNumVers, 0, nNumInds); - } - pShader->FXEndPass(); - return; -} - -void CD3D9Renderer::FX_StencilFrustumCull(int nStencilID, const SRenderLight* pLight, ShadowMapFrustum* pFrustum, int nAxis) -{ - EShapeMeshType nPrimitiveID = m_RP.m_nDeferredPrimitiveID; //SHAPE_PROJECTOR; - uint32 nPassCount = 0; - CShader* pShader = CShaderMan::s_ShaderShadowMaskGen; - static CCryNameTSCRC StencilCullTechName = "DeferredShadowPass"; - - - Matrix44A mProjection = m_IdentityMatrix; - Matrix44A mView = m_IdentityMatrix; - - assert(pLight != NULL); - bool bAreaLight = (pLight->m_Flags & DLF_AREA_LIGHT) && pLight->m_fAreaWidth && pLight->m_fAreaHeight && pLight->m_fLightFrustumAngle && CRenderer::CV_r_DeferredShadingAreaLights; - - Vec3 vOffsetDir(0, 0, 0); - - //un-projection matrix calc - if (pFrustum == NULL) - { - ITexture* pLightTexture = pLight->GetLightTexture(); - if (pLight->m_fProjectorNearPlane < 0) - { - SRenderLight instLight = *pLight; - vOffsetDir = (-pLight->m_fProjectorNearPlane) * (pLight->m_ObjMatrix.GetColumn0().GetNormalized()); - instLight.SetPosition(instLight.m_Origin - vOffsetDir); - instLight.m_fRadius -= pLight->m_fProjectorNearPlane; - CShadowUtils::GetCubemapFrustumForLight(&instLight, nAxis, 160.0f, &mProjection, &mView, false); // 3.0f - offset to make sure that frustums are intersected - } - else - if ((pLight->m_Flags & DLF_PROJECT) && pLightTexture && !(pLightTexture->GetFlags() & FT_REPLICATE_TO_ALL_SIDES)) - { - //projective light - //refactor projective light - - //for light source - CShadowUtils::GetCubemapFrustumForLight(pLight, nAxis, pLight->m_fLightFrustumAngle * 2.f /*CShadowUtils::g_fOmniLightFov+3.0f*/, &mProjection, &mView, false); // 3.0f - offset to make sure that frustums are intersected - } - else //omni/area light - { - //////////////// light sphere/box processing ///////////////////////////////// - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - - float fExpensionRadius = pLight->m_fRadius * 1.08f; - - Vec3 vScale(fExpensionRadius, fExpensionRadius, fExpensionRadius); - - Matrix34 mLocal; - if (bAreaLight) - { - mLocal = CShadowUtils::GetAreaLightMatrix(pLight, vScale); - } - else if (pLight->m_Flags & DLF_DEFERRED_CUBEMAPS) - { - Matrix33 rotMat(pLight->m_ObjMatrix.GetColumn0().GetNormalized() * pLight->m_ProbeExtents.x, - pLight->m_ObjMatrix.GetColumn1().GetNormalized() * pLight->m_ProbeExtents.y, - pLight->m_ObjMatrix.GetColumn2().GetNormalized() * pLight->m_ProbeExtents.z); - mLocal = Matrix34::CreateTranslationMat(pLight->m_Origin) * rotMat * Matrix34::CreateScale(Vec3(2, 2, 2), Vec3(-1, -1, -1)); - } - else - { - mLocal.SetIdentity(); - mLocal.SetScale(vScale, pLight->m_Origin); - } - - Matrix44 mLocalTransposed = mLocal.GetTransposed(); - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = mLocalTransposed * m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - - pShader->FXSetTechnique(StencilCullTechName); - pShader->FXBegin(&nPassCount, FEF_DONTSETSTATES); - - // Vertex/index buffer - const EShapeMeshType meshType = (bAreaLight || (pLight->m_Flags & DLF_DEFERRED_CUBEMAPS)) ? SHAPE_BOX : SHAPE_SPHERE; - - FX_SetVStream(0, m_pUnitFrustumVB[meshType], 0, sizeof(SVF_P3F_C4B_T2F)); - FX_SetIStream(m_pUnitFrustumIB[meshType], 0, (kUnitObjectIndexSizeof == 2 ? Index16 : Index32)); - - if (!RenderCapabilities::SupportsDepthClipping()) - { - FX_StencilCullPass(nStencilID == -4 ? -4 : -1, m_UnitFrustVBSize[meshType], m_UnitFrustIBSize[meshType], pShader, DS_SHADOW_CULL_PASS, DS_SHADOW_CULL_PASS_FRONTFACING); - } - else - { - FX_StencilCullPass(nStencilID == -4 ? -4 : -1, m_UnitFrustVBSize[meshType], m_UnitFrustIBSize[meshType], pShader, DS_SHADOW_CULL_PASS); - } - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - - pShader->FXEnd(); - - return; - ////////////////////////////////////////////////////////////////////////// - } - } - else - { - if (!pFrustum->bOmniDirectionalShadow) - { - //temporarily disabled since mLightProjMatrix contains pre-multiplied matrix already - //pmProjection = &(pFrustum->mLightProjMatrix); - mProjection = gRenDev->m_IdentityMatrix; - mView = pFrustum->mLightViewMatrix; - } - else - { - //calc one of cubemap's frustums - Matrix33 mRot = (Matrix33(pLight->m_ObjMatrix)); - //rotation for shadow frustums is disabled - CShadowUtils::GetCubemapFrustum(FTYP_OMNILIGHTVOLUME, pFrustum, nAxis, &mProjection, &mView /*, &mRot*/); - } - } - - //matrix concanation and inversion should be computed in doubles otherwise we have precision problems with big coords on big levels - //which results to the incident frustum's discontinues for omni-lights - Matrix44r mViewProj = Matrix44r(mView) * Matrix44r(mProjection); - Matrix44A mViewProjInv = mViewProj.GetInverted(); - - gRenDev->m_TempMatrices[0][0] = mViewProjInv.GetTransposed(); - - //setup light source pos/radius - m_cEF.m_TempVecs[5] = Vec4(pLight->m_Origin, pLight->m_fRadius * 1.1f); //increase radius slightly - if (pLight->m_fProjectorNearPlane < 0) - { - m_cEF.m_TempVecs[5].x -= vOffsetDir.x; - m_cEF.m_TempVecs[5].y -= vOffsetDir.y; - m_cEF.m_TempVecs[5].z -= vOffsetDir.z; - nPrimitiveID = SHAPE_CLIP_PROJECTOR; - } - - //if (m_pUnitFrustumVB==NULL || m_pUnitFrustumIB==NULL) - // CreateUnitFrustumMesh(); - - FX_SetVStream(0, m_pUnitFrustumVB[nPrimitiveID], 0, sizeof(SVF_P3F_C4B_T2F)); - FX_SetIStream(m_pUnitFrustumIB[nPrimitiveID], 0, (kUnitObjectIndexSizeof == 2 ? Index16 : Index32)); - - pShader->FXSetTechnique(StencilCullTechName); - pShader->FXBegin(&nPassCount, FEF_DONTSETSTATES); - - if (!RenderCapabilities::SupportsDepthClipping()) - { - FX_StencilCullPass(nStencilID, m_UnitFrustVBSize[nPrimitiveID], m_UnitFrustIBSize[nPrimitiveID], pShader, DS_SHADOW_FRUSTUM_CULL_PASS, DS_SHADOW_FRUSTUM_CULL_PASS_FRONTFACING); - } - else - { - FX_StencilCullPass(nStencilID, m_UnitFrustVBSize[nPrimitiveID], m_UnitFrustIBSize[nPrimitiveID], pShader, DS_SHADOW_FRUSTUM_CULL_PASS); - } - - pShader->FXEnd(); - - return; -} - -void CD3D9Renderer::FX_StencilCullNonConvex(int nStencilID, IRenderMesh* pWaterTightMesh, const Matrix34& mWorldTM) -{ - CShader* pShader(CShaderMan::s_ShaderShadowMaskGen); - static CCryNameTSCRC TechName0 = "DeferredShadowPass"; - - CRenderMesh* pRenderMesh = static_cast(pWaterTightMesh); - pRenderMesh->CheckUpdate(0); - - const buffer_handle_t hVertexStream = pRenderMesh->GetVBStream(VSF_GENERAL); - const buffer_handle_t hIndexStream = pRenderMesh->GetIBStream(); - - if (hVertexStream != ~0u && hIndexStream != ~0u) - { - size_t nOffsI = 0; - size_t nOffsV = 0; - - D3DBuffer* pVB = gRenDev->m_DevBufMan.GetD3D(hVertexStream, &nOffsV); - D3DBuffer* pIB = gRenDev->m_DevBufMan.GetD3D(hIndexStream, &nOffsI); - - FX_SetVStream(0, pVB, nOffsV, pRenderMesh->GetStreamStride(VSF_GENERAL)); - FX_SetIStream(pIB, nOffsI, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - const bool gmemLinearizeEnabled = FX_GetEnabledGmemPath(nullptr) && FX_GmemGetDepthStencilMode() == eGDSM_RenderTarget; - { - ECull nPrevCullMode = m_RP.m_eCull; - int nPrevState = m_RP.m_CurState; - - int newState = nPrevState; - - // FX_SetStencilState(...) would cast to uint instead of int - uint8_t u8StencilID = nStencilID; - uint8_t u8InvStencilID = ~nStencilID; - - if (gmemLinearizeEnabled) - { - // This pass affects the stencil on depth fail. - // Since in GMEM we do our own stencil operations ourselves as to avoid - // resolving RTs, we need to inverse the depth test operation. - newState &= ~(GS_BLEND_MASK | GS_NODEPTHTEST | GS_DEPTHFUNC_MASK | GS_STENCIL); - newState |= GS_NOCOLMASK_R | GS_NOCOLMASK_B | GS_NOCOLMASK_A; - newState |= GS_DEPTHFUNC_GREAT; - } - else - { - newState &= ~(GS_NODEPTHTEST | GS_DEPTHWRITE | GS_DEPTHFUNC_MASK); - newState |= GS_DEPTHFUNC_LEQUAL | GS_STENCIL | GS_COLMASK_NONE; - } - - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - Matrix44 mLocalTransposed; - mLocalTransposed = mWorldTM.GetTransposed(); - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = mLocalTransposed * m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - - uint32 nPasses = 0; - pShader->FXSetTechnique(TechName0); - pShader->FXBegin(&nPasses, FEF_DONTSETSTATES); - - if (gmemLinearizeEnabled) - { - pShader->FXBeginPass(CD3D9Renderer::DS_GMEM_STENCIL_CULL_NON_CONVEX); - } - else - { - pShader->FXBeginPass(CD3D9Renderer::DS_SHADOW_CULL_PASS); - } - - if (!FAILED(FX_SetVertexDeclaration(0, pRenderMesh->_GetVertexFormat()))) - { - // Mark all pixels that might be inside volume first (z-fail on back-faces) - D3DSetCull(eCULL_Front); - if (gmemLinearizeEnabled) - { - static CCryNameR pParamName0("StencilRef"); - Vec4 StencilRefParam(0.f); - StencilRefParam.x = static_cast(u8StencilID); - CShaderMan::s_ShaderShadowMaskGen->FXSetPSFloat(pParamName0, &StencilRefParam, 1); - } - else - { - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_GEQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nStencilID, 0xFFFFFFFF, 0xFFFFFFFF - ); - } - FX_SetState(newState); - FX_Commit(); - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pRenderMesh->GetNumVerts(), 0, pRenderMesh->GetNumInds()); - } - - // Flip bits for each face - { - D3DSetCull(eCULL_None); - if (gmemLinearizeEnabled) - { - static CCryNameR pParamName0("StencilRef"); - Vec4 StencilRefParam(0.f); - StencilRefParam.x = static_cast(u8InvStencilID); - StencilRefParam.y = 1.f; - CShaderMan::s_ShaderShadowMaskGen->FXSetPSFloat(pParamName0, &StencilRefParam, 1); - FX_Commit(); - } - else - { - FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_GEQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_INVERT) | - STENCOP_PASS(FSS_STENCOP_KEEP), - ~nStencilID, 0xFFFFFFFF, 0xFFFFFFFF); - } - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pRenderMesh->GetNumVerts(), 0, pRenderMesh->GetNumInds()); - } - pShader->FXEndPass(); - - // If there's no stencil texture support we "resolve" the vis area directly to the texture. - if (!gmemLinearizeEnabled && !RenderCapabilities::SupportsStencilTextures()) - { - pShader->FXBeginPass(CD3D9Renderer::DS_STENCIL_CULL_NON_CONVEX_RESOLVE); - - { - // These values must match the ones in the shader (ResolveStencilPS) - const uint8_t BIT_STENCIL_STATIC = 0x0000007F; - const uint8_t BIT_STENCIL_INSIDE_VOLUME = 0x00000040; - - uint8_t resolvedStencil = u8InvStencilID; - - resolvedStencil = resolvedStencil & BIT_STENCIL_STATIC; - resolvedStencil = max(resolvedStencil - BIT_STENCIL_INSIDE_VOLUME, 1); - - static CCryNameR pParamName0("StencilRefResolve"); - Vec4 StencilRefParam(0.f); - StencilRefParam.x = static_cast(resolvedStencil) / 255.0; - StencilRefParam.y = 1.f; - CShaderMan::s_ShaderShadowMaskGen->FXSetPSFloat(pParamName0, &StencilRefParam, 1); - FX_Commit(); - } - - { - newState &= ~(GS_BLEND_MASK | GS_NODEPTHTEST | GS_DEPTHFUNC_MASK | GS_COLMASK_NONE); - newState |= GS_NOCOLMASK_G | GS_NOCOLMASK_B | GS_NOCOLMASK_A; - newState |= GS_DEPTHFUNC_GREAT | GS_STENCIL; - FX_SetState(newState); - } - - { - FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - ~nStencilID, 0xFFFFFFFF, 0xFFFFFFFF); - } - - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pRenderMesh->GetNumVerts(), 0, pRenderMesh->GetNumInds()); - pShader->FXEndPass(); - } - - D3DSetCull(nPrevCullMode); - FX_SetState(nPrevState); - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - - pShader->FXEnd(); - } - } -} - -void CD3D9Renderer::FX_DeferredShadowMaskGen(const TArray& shadowPoolLights) -{ - const uint64 nPrevFlagsShaderRT = m_RP.m_FlagsShader_RT; - - const int nThreadID = m_RP.m_nProcessThreadID; - const int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - const int nPreviousState = m_RP.m_CurState; - - const bool isShadowPassEnabled = IsShadowPassEnabled(); - const int nMaskWidth = GetWidth(); - const int nMaskHeight = GetHeight(); - const ColorF clearColor = ColorF (0.0f, 0.0f, 0.0f, 0.0f); - - // reset render element and current render object in pipeline - m_RP.m_pRE = 0; - m_RP.m_pCurObject = m_RP.m_pIdendityRenderObject; - m_RP.m_ObjFlags = 0; - - m_RP.m_FlagsShader_RT = 0; - m_RP.m_FlagsShader_LT = 0; - m_RP.m_FlagsShader_MD = 0; - m_RP.m_FlagsShader_MDV = 0; - - FX_ResetPipe(); - FX_Commit(); - - CTexture* pShadowMask = CTexture::s_ptexShadowMask; - - SResourceView curSliceRVDesc = SResourceView::RenderTargetView(pShadowMask->GetTextureDstFormat(), 0, 1); - SResourceView& firstSliceRV = pShadowMask->GetResourceView(curSliceRVDesc); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Avoid any resolve. We clear stencil with full screen pass. - - // Only do a clear pass if shadows are actually enabled - static const ICVar* pCVarShadows = iConsole->GetCVar("e_Shadows"); - if (m_RP.m_pSunLight && isShadowPassEnabled && pCVarShadows->GetIVal()) - { - uint32 prevState = m_RP.m_CurState; - uint32 newState = 0; - newState |= GS_COLMASK_NONE; - newState |= GS_STENCIL; - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_ZERO) | - STENCOP_ZFAIL(FSS_STENCOP_ZERO) | - STENCOP_PASS(FSS_STENCOP_ZERO), - 0, 0xFFFFFFFF, 0xFFFF); - FX_SetState(newState); - SD3DPostEffectsUtils::ClearScreen(0, 0, 0, 0); - FX_SetState(prevState); - } - else - { - return; - } - } - else - { - // set shadow mask RT and clear stencil - FX_ClearTarget(static_cast(firstSliceRV.m_pDeviceResourceView), Clr_Transparent, 0, nullptr); - FX_ClearTarget(&m_DepthBufferOrig, CLEAR_STENCIL, Clr_Unused.r, 0); - FX_PushRenderTarget(0, static_cast(firstSliceRV.m_pDeviceResourceView), &m_DepthBufferOrig); - RT_SetViewport(0, 0, nMaskWidth, nMaskHeight); - } - - int nFirstChannel = 0; - int nChannelsInUse = 0; - - // sun - if (m_RP.m_pSunLight && isShadowPassEnabled) - { - PROFILE_LABEL_SCOPE("SHADOWMASK_SUN"); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - FX_SetDepthDontCareActions(0, false, true); - } - // CONFETTI END - - FX_DeferredShadows(m_RP.m_pSunLight, nMaskWidth, nMaskHeight); - ++nFirstChannel; - ++nChannelsInUse; - } - - // point lights - if (!shadowPoolLights.empty() && isShadowPassEnabled) - { - // This code path should only be hit when used tiled shading. - // Assert just in case since multiple layers of shadow masks can't fit GMEM path. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - CRY_ASSERT(0); - } - - PROFILE_LABEL_SCOPE("SHADOWMASK_DEFERRED_LIGHTS"); - - const int nMaxChannelCount = pShadowMask->StreamGetNumSlices() * 4; - std::vector< std::vector > > lightsPerChannel; - lightsPerChannel.resize(nMaxChannelCount); - - // sort lights into layers first in order to minimize the number of required render targets - for (int i = 0; i < shadowPoolLights.size(); ++i) - { - const int nLightID = shadowPoolLights[i]; - SRenderLight* pLight = EF_GetDeferredLightByID(nLightID, eDLT_DeferredLight); - const int nFrustumIdx = m_RP.m_DLights[nThreadID][nCurRecLevel].Num() + nLightID; - - if (!pLight || !(pLight->m_Flags & DLF_CASTSHADOW_MAPS)) - { - __debugbreak(); - } - - int nStartIdx = SRendItem::m_StartFrust[nThreadID][nFrustumIdx]; - int nEndIdx = SRendItem::m_EndFrust[nThreadID][nFrustumIdx]; - - //no single frustum was allocated for this light - if (nEndIdx <= nStartIdx) - { - continue; - } - - // get light scissor rect - Vec4 pLightRect = Vec4(static_cast(pLight->m_sX), static_cast(pLight->m_sY), static_cast(pLight->m_sWidth), static_cast(pLight->m_sHeight)); - - int nChannelIndex = nFirstChannel; - while (nChannelIndex < nMaxChannelCount) - { - bool bHasOverlappingLight = false; - - float minX = pLightRect.x, maxX = pLightRect.x + pLightRect.z; - float minY = pLightRect.y, maxY = pLightRect.y + pLightRect.w; - - for (int j = 0; j < lightsPerChannel[nChannelIndex].size(); ++j) - { - const Vec4& lightRect = lightsPerChannel[nChannelIndex][j].second; - - if (maxX >= lightRect.x && minX <= lightRect.x + lightRect.z && - maxY >= lightRect.y && minY <= lightRect.y + lightRect.w) - { - bHasOverlappingLight = true; - break; - } - } - - if (!bHasOverlappingLight) - { - lightsPerChannel[nChannelIndex].push_back(std::make_pair(nLightID, pLightRect)); - nChannelsInUse = max(nChannelIndex + 1, nChannelsInUse); - break; - } - - ++nChannelIndex; - } - - if (nChannelIndex >= nMaxChannelCount) - { - m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nStartIdx].nShadowGenMask = 0; - ++nChannelsInUse; - } - } - - // now render each layer - for (int nChannel = nFirstChannel; nChannel < min(nChannelsInUse, nMaxChannelCount); ++nChannel) - { - const int nMaskIndex = nChannel / 4; - const int nMaskChannel = nChannel % 4; - - if (nChannel > 0 && nMaskChannel == 0) - { - curSliceRVDesc.m_Desc.nFirstSlice = nMaskIndex; - SResourceView& curSliceRV = pShadowMask->GetResourceView(curSliceRVDesc); - - FX_PopRenderTarget(0); - FX_PushRenderTarget(0, static_cast(curSliceRV.m_pDeviceResourceView), &m_DepthBufferOrig); - } - - for (int i = 0; i < lightsPerChannel[nChannel].size(); ++i) - { - const int nLightIndex = lightsPerChannel[nChannel][i].first; - const Vec4 lightRect = lightsPerChannel[nChannel][i].second; - - SRenderLight* pLight = EF_GetDeferredLightByID(nLightIndex, eDLT_DeferredLight); - assert(pLight); - - PROFILE_SHADER_SCOPE; - m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - ////////////////////////////////////////////////////////////////////////// - const int nFrustumIdx = m_RP.m_DLights[nThreadID][nCurRecLevel].Num() + nLightIndex; - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nFrustumIdx]; - ShadowMapFrustum& firstFrustum = m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nStartIdx]; - - const int nSides = firstFrustum.bOmniDirectionalShadow ? 6 : 1; - const bool bAreaLight = (pLight->m_Flags & DLF_AREA_LIGHT) && pLight->m_fAreaWidth && pLight->m_fAreaHeight && pLight->m_fLightFrustumAngle; - - //enable hw-pcf light - if (firstFrustum.bHWPCFCompare) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]; - } - - // determine what's more beneficial: full screen quad or light volume - bool bStencilMask = true; - bool bUseLightVolumes = false; - CDeferredShading::Instance().GetLightRenderSettings(pLight, bStencilMask, bUseLightVolumes, m_RP.m_nDeferredPrimitiveID); - - // reserve stencil values - m_nStencilMaskRef += (nSides + 1); - if (m_nStencilMaskRef > STENC_MAX_REF) - { - FX_ClearTarget(&m_DepthBufferOrig, CLEAR_STENCIL, Clr_Unused.r, 0); - m_nStencilMaskRef = nSides + 1; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - EF_Scissor(true, - static_cast(lightRect.x * m_RP.m_CurDownscaleFactor.x), - static_cast(lightRect.y * m_RP.m_CurDownscaleFactor.y), - static_cast(lightRect.z * m_RP.m_CurDownscaleFactor.x + 1), - static_cast(lightRect.w * m_RP.m_CurDownscaleFactor.y + 1)); - } - - uint32 nPersFlagsPrev = m_RP.m_TI[nThreadID].m_PersFlags; - - for (int nS = 0; nS < nSides; nS++) - { - // render light volume to stencil - { - bool bIsMirrored = (m_RP.m_TI[nThreadID].m_PersFlags & RBPF_MIRRORCULL) ? true : false; - bool bRequiresMirroring = (!(pLight->m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT))) ? true : false; - - if (bIsMirrored ^ bRequiresMirroring) // Enable mirror culling for omni-shadows, or if we are in cubemap-gen. If both, they cancel-out, so disable. - { - m_RP.m_TI[nThreadID].m_PersFlags |= RBPF_MIRRORCULL; - } - else - { - m_RP.m_TI[nThreadID].m_PersFlags &= ~RBPF_MIRRORCULL; - } - - FX_StencilFrustumCull(-2, pLight, bAreaLight ? NULL : &firstFrustum, nS); - } - - FX_StencilTestCurRef(true, true); - - if (firstFrustum.nShadowGenMask & (1 << nS)) - { - FX_ApplyShadowQuality(); - CShader* pShader = CShaderMan::s_shDeferredShading; - static CCryNameTSCRC techName = "ShadowMaskGen"; - static CCryNameTSCRC techNameVolume = "ShadowMaskGenVolume"; - - ConfigShadowTexgen(0, &firstFrustum, nS); - - if (CV_r_ShadowsScreenSpace) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE2 ]; - } - - if (bUseLightVolumes) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - SD3DPostEffectsUtils::ShBeginPass(pShader, techNameVolume, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - SD3DPostEffectsUtils::ShBeginPass(pShader, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - // comparison filtering for shadow map - STexState TS(firstFrustum.bHWPCFCompare ? FILTER_LINEAR : FILTER_POINT, true); - TS.m_bSRGBLookup = false; - TS.SetComparisonFilter(true); - - CTexture* pShadowMap = firstFrustum.bUseShadowsPool ? CTexture::s_ptexRT_ShadowPool : firstFrustum.pDepthTex; - pShadowMap->Apply(1, CTexture::GetTexState(TS), EFTT_UNKNOWN, 6); - - SD3DPostEffectsUtils::SetTexture(CTextureManager::Instance()->GetDefaultTexture("ShadowJitterMap"), 7, FILTER_POINT, 0); - - static ICVar* pVar = iConsole->GetCVar("e_ShadowsPoolSize"); - int nShadowAtlasRes = pVar->GetIVal(); - - //LRad - float kernelSize = firstFrustum.bOmniDirectionalShadow ? 2.5f : 1.5f; - const Vec4 vShadowParams(kernelSize * (float(firstFrustum.nTexSize) / nShadowAtlasRes), firstFrustum.nTexSize, 1.0 / nShadowAtlasRes, firstFrustum.fDepthConstBias); - static CCryNameR generalParamsName("g_GeneralParams"); - pShader->FXSetPSFloat(generalParamsName, &vShadowParams, 1); - - // set up shadow matrix - static CCryNameR lightProjParamName("g_mLightShadowProj"); - Matrix44A shadowMat = gRenDev->m_TempMatrices[0][0]; - const Vec4 vEye(gRenDev->GetViewParameters().vOrigin, 0.f); - Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30)); - shadowMat.m03 += vecTranslation.x; - shadowMat.m13 += vecTranslation.y; - shadowMat.m23 += vecTranslation.z; - shadowMat.m33 += vecTranslation.w; - - // pre-multiply by 1/frustrum_far_plane - (Vec4&)shadowMat.m20 *= gRenDev->m_cEF.m_TempVecs[2].x; - - //camera matrix - pShader->FXSetPSFloat(lightProjParamName, alias_cast(&shadowMat), 4); - - Vec4 vScreenScale(1.0f / nMaskWidth, 1.0f / nMaskHeight, 0.0f, 0.0f); - static CCryNameR screenScaleParamName("g_ScreenScale"); - pShader->FXSetPSFloat(screenScaleParamName, &vScreenScale, 1); - - Vec4 vLightPos(pLight->m_Origin, 0.0f); - static CCryNameR vLightPosName("g_vLightPos"); - pShader->FXSetPSFloat(vLightPosName, &vLightPos, 1); - - if (FurPasses::GetInstance().IsRenderingFur()) - { - CTexture::s_ptexFurZTarget->Apply(0, CTexture::GetTexState(STexState(FILTER_POINT, true))); - } - else - { - CTexture::s_ptexZTarget->Apply(0, CTexture::GetTexState(STexState(FILTER_POINT, true))); - } - - // color mask - uint32 newState = m_RP.m_CurState & ~(GS_COLMASK_NONE | GS_BLEND_MASK); - newState |= ~((1 << nMaskChannel % 4) << GS_COLMASK_SHIFT) & GS_COLMASK_MASK; - - if (bUseLightVolumes) - { - // shadow clip space to world space transform - Matrix44A mUnitVolumeToWorld(IDENTITY); - Vec4 vSphereAdjust(ZERO); - - if (bAreaLight) - { - const float fExpensionRadius = pLight->m_fRadius * 1.08f; - mUnitVolumeToWorld = CShadowUtils::GetAreaLightMatrix(pLight, Vec3(fExpensionRadius)).GetTransposed(); - m_RP.m_nDeferredPrimitiveID = SHAPE_BOX; - } - else - { - Matrix44A mProjection, mView; - if (firstFrustum.bOmniDirectionalShadow) - { - CShadowUtils::GetCubemapFrustum(FTYP_OMNILIGHTVOLUME, &firstFrustum, nS, &mProjection, &mView); - } - else - { - mProjection = gRenDev->m_IdentityMatrix; - mView = firstFrustum.mLightViewMatrix; - } - - Matrix44r mViewProj = Matrix44r(mView) * Matrix44r(mProjection); - mUnitVolumeToWorld = mViewProj.GetInverted(); - vSphereAdjust = Vec4(pLight->m_Origin, pLight->m_fRadius * 1.1f); - } - - newState &= ~(GS_NODEPTHTEST | GS_DEPTHWRITE); - newState |= GS_DEPTHFUNC_LEQUAL; - FX_SetState(newState); - - CDeferredShading::Instance().DrawLightVolume(m_RP.m_nDeferredPrimitiveID, mUnitVolumeToWorld, vSphereAdjust); - } - else - { - // depth state - newState &= ~GS_DEPTHWRITE; - newState |= GS_NODEPTHTEST; - FX_SetState(newState); - - m_RP.m_TI[nThreadID].m_PersFlags &= ~RBPF_MIRRORCULL; - gcpRendD3D->D3DSetCull(eCULL_Back, true); //fs quads should not revert test.. - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(nMaskWidth, nMaskHeight); - } - - SD3DPostEffectsUtils::ShEndPass(); - } - - // restore PersFlags - m_RP.m_TI[nThreadID].m_PersFlags = nPersFlagsPrev; - } // for each side - - pLight->m_ShadowChanMask = nMaskChannel; - pLight->m_ShadowMaskIndex = nMaskIndex; - - EF_Scissor(false, 0, 0, 0, 0); - - m_nStencilMaskRef += nSides; - - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ] | g_HWSR_MaskBit[HWSR_CUBEMAP0] | g_HWSR_MaskBit[HWSR_SAMPLE2]); - } // for each light - } - } - -#ifndef _RELEASE - m_RP.m_PS[nThreadID].m_NumShadowMaskChannels = (pShadowMask->StreamGetNumSlices() * 4 << 16) | (nChannelsInUse & 0xFFFF); -#endif - - gcpRendD3D->D3DSetCull(eCULL_Back, true); - - FX_SetState(nPreviousState); - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - FX_PopRenderTarget(0); - } - - m_RP.m_FlagsShader_RT = nPrevFlagsShaderRT; -} - -bool CD3D9Renderer::FX_DeferredShadows(SRenderLight* pLight, int maskRTWidth, int maskRTHeight) -{ - if (!pLight || (pLight->m_Flags & DLF_CASTSHADOW_MAPS) == 0) - { - return false; - } - - const int nThreadID = m_RP.m_nProcessThreadID; - const int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - - //set ScreenToWorld Expansion Basis - Vec3 vWBasisX, vWBasisY, vWBasisZ; - CShadowUtils::CalcScreenToWorldExpansionBasis(GetCamera(), Vec2(m_TemporalJitterClipSpace.x, m_TemporalJitterClipSpace.y), (float)maskRTWidth, (float)maskRTHeight, vWBasisX, vWBasisY, vWBasisZ, true); - m_cEF.m_TempVecs[10] = Vec4(vWBasisX, 1.0f); - m_cEF.m_TempVecs[11] = Vec4(vWBasisY, 1.0f); - m_cEF.m_TempVecs[12] = Vec4(vWBasisZ, 1.0f); - - const bool bCloudShadows = m_bCloudShadowsEnabled && m_cloudShadowTexId > 0; - const bool bCustomShadows = !m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].empty(); - - ////////////////////////////////////////////////////////////////////////// - //check for valid gsm frustums - ////////////////////////////////////////////////////////////////////////// - CRY_ASSERT(pLight->m_Id >= 0); - TArray& arrFrustums = m_RP.m_SMFrustums[nThreadID][nCurRecLevel]; - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][pLight->m_Id]; - - int nEndIdx; - for (nEndIdx = nStartIdx; nEndIdx < SRendItem::m_EndFrust[nThreadID][pLight->m_Id]; ++nEndIdx) - { - if (arrFrustums[nEndIdx].m_eFrustumType != ShadowMapFrustum::e_GsmDynamic && arrFrustums[nEndIdx].m_eFrustumType != ShadowMapFrustum::e_GsmDynamicDistance) - { - break; - } - } - - const int nCasterCount = nEndIdx - nStartIdx; - if (nCasterCount == 0 && !bCloudShadows && !bCustomShadows) - { - return false; - } - - // set shader - CShader* pSH(CShaderMan::s_ShaderShadowMaskGen); - static CCryNameR TechName("DeferredShadowPass"); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - - static ICVar* pCascadesDebugVar = iConsole->GetCVar("e_ShadowsCascadesDebug"); - bool bDebugShadowCascades = pCascadesDebugVar && pCascadesDebugVar->GetIVal() > 0; - - // We don't currently support debug cascade shadow overlay with GMEM enabled - if (bDebugShadowCascades && gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - const AZStd::string title = "Debug cascade shadow overlay"; - const AZStd::string message = AZStd::string::format("e_ShadowsCascadesDebug can not be enabled while r_EnableGMEMPath is enabled. Disable r_EnableGMEMPath to view debug shadow cascades."); - AZ_Warning("Renderer", false, "ERROR: %s\n", message.c_str()); - if (!gEnv->IsInToolMode()) - { - AZStd::vector options; - options.push_back("OK"); - AZ::NativeUI::NativeUIRequestBus::Broadcast(&AZ::NativeUI::NativeUIRequestBus::Events::DisplayBlockingDialog, title, message, options); - } - pCascadesDebugVar->Set(0); - bDebugShadowCascades = false; - } - - const bool bCascadeBlending = CV_r_ShadowsStencilPrePass == 1 && nCasterCount > 0 && arrFrustums[nStartIdx].bBlendFrustum && !bDebugShadowCascades; - if (bCascadeBlending) - { - for (int nCaster = nStartIdx + 1; nCaster < nEndIdx; nCaster++) - { - arrFrustums[nCaster].pPrevFrustum = &arrFrustums[nCaster - 1]; - } - - for (int nCaster = nStartIdx; nCaster < nEndIdx; nCaster++) - { - const bool bFirstCaster = (nCaster == nStartIdx); - const bool bLastCaster = (nCaster == nEndIdx - 1); - - const uint32 nStencilID = 2 * (nCaster - nStartIdx) + 1; - const uint32 nMaxStencilID = 2 * nCasterCount + 1; - - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_GEQUAL; - - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], false, false, true, nStencilID); // This frustum - - if (!bLastCaster) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], false, false, true, nStencilID + 1); // This frustum, not including blend region - - if (!bFirstCaster) - { - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster - 1], false, false, true, nStencilID + 1); // Mask whole prior frustum ( allow blending region ) - } - } - - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], true, false, false, !bLastCaster ? (nStencilID + 1) : nStencilID); // non-blending - - if (!bLastCaster) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], true, false, false, nStencilID); // blending - } - - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_ALWAYS; - - if (!bLastCaster) - { - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], false, false, true, nMaxStencilID); // Invalidate interior region for future rendering - } - - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[ HWSR_SAMPLE3 ]; - - if (!bFirstCaster && !bLastCaster) - { - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster - 1 ], false, false, true, nMaxStencilID); // Remove prior region - } - } - - for (int nCaster = nStartIdx; nCaster < nEndIdx; nCaster++) - { - arrFrustums[ nCaster ].pPrevFrustum = NULL; - } - } - else if IsCVarConstAccess(constexpr) (CV_r_ShadowsStencilPrePass == 1) - { - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_GEQUAL; - for (int nCaster = 0; nCaster < nCasterCount; nCaster++) - { - FX_DeferredShadowPass(pLight, &arrFrustums[ nStartIdx + nCaster ], false, false, true, nCasterCount - nCaster); - } - - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_ALWAYS; - for (int nCaster = 0; nCaster < nCasterCount; nCaster++) - { - FX_DeferredShadowPass(pLight, &arrFrustums[ nStartIdx + nCaster ], true, false, false, nCasterCount - nCaster); - } - } - else if IsCVarConstAccess(constexpr) (CV_r_ShadowsStencilPrePass == 0) - { - ////////////////////////////////////////////////////////////////////////// - //shadows passes - for (int nCaster = nStartIdx; nCaster < nEndIdx; nCaster++ /*, m_RP.m_PS[rd->m_RP.m_nProcessThreadID]. ++ */) // for non-conservative - { - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_GEQUAL; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], false, false, true, 10 - (nCaster - nStartIdx + 1)); - - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_ALWAYS; - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], true, false, false, 10 - (nCaster - nStartIdx + 1)); - } - } - else if IsCVarConstAccess(constexpr) (CV_r_ShadowsStencilPrePass == 2) - { - for (int nCaster = nStartIdx; nCaster < nEndIdx; nCaster++) - { - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_GEQUAL; - int nLod = (10 - (nCaster - nStartIdx + 1)); - - //stencil mask - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], false, false, true, nLod); - - //shadow pass - FX_DeferredShadowPass(pLight, &arrFrustums[ nCaster ], true, false, false, nLod); - } - - m_RP.m_CurStencilCullFunc = FSS_STENCFUNC_ALWAYS; - } - else - { - assert(0); - } - - // update stencil ref value, so subsequent passes will not use the same stencil values - m_nStencilMaskRef = bCascadeBlending ? 2 * nCasterCount + 1 : nCasterCount; - - ///////////////// Cascades debug mode ///////////////////////////////// - if ((pLight->m_Flags & DLF_SUN) && bDebugShadowCascades) - { - PROFILE_LABEL_SCOPE("DEBUG_SHADOWCASCADES"); - - static CCryNameTSCRC TechName2 = "DebugShadowCascades"; - static CCryNameR CascadeColorParam("DebugCascadeColor"); - - const Vec4 cascadeColors[] = - { - Vec4(1, 0, 0, 1), - Vec4(0, 1, 0, 1), - Vec4(0, 0, 1, 1), - Vec4(1, 1, 0, 1), - Vec4(1, 0, 1, 1), - Vec4(0, 1, 1, 1), - Vec4(1, 0, 0, 1), - }; - - // Draw information text for Cascade colors - float yellow[4] = {1.f, 1.f, 0.f, 1.f}; - Draw2dLabel(10.f, 30.f, 2.0f, yellow, false, - "e_ShadowsCascadesDebug"); - Draw2dLabel(40.f, 60.f, 1.5f, yellow, false, - "Cascade0: Red\n" - "Cascade1: Green\n" - "Cascade2: Blue\n" - "Cascade3: Yellow\n" - "Cascade4: Pink" - ); - - const int cascadeColorCount = sizeof(cascadeColors) / sizeof(cascadeColors[0]); - - // render into diffuse color target - CTexture* colorTarget = CTexture::s_ptexSceneDiffuse; - SDepthTexture* depthStencilTarget = &m_DepthBufferOrig; - - FX_PushRenderTarget(0, colorTarget, depthStencilTarget); - - const int oldState = m_RP.m_CurState; - int newState = oldState; - newState |= GS_STENCIL; - newState &= ~GS_COLMASK_NONE; - - FX_SetState(newState); - - for (int nCaster = 0; nCaster < nCasterCount; ++nCaster) - { - const Vec4& cascadeColor = cascadeColors[arrFrustums[nStartIdx + nCaster].nShadowMapLod % cascadeColorCount]; - - FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - nCasterCount - nCaster, 0xFFFFFFFF, 0xFFFFFFFF - ); - - // set shader - SD3DPostEffectsUtils::ShBeginPass(pSH, TechName2, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXSetPSFloat(CascadeColorParam, &cascadeColor, 1); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(colorTarget->GetWidth(), colorTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - } - - FX_SetState(oldState); - FX_PopRenderTarget(0); - } - - ////////////////////////////////////////////////////////////////////////// - //draw clouds shadow - if (bCloudShadows) - { - ShadowMapFrustum cloudsFrustum; - cloudsFrustum.bUseAdditiveBlending = true; - FX_DeferredShadowPass(pLight, &cloudsFrustum, true, true, false, 0); - } - - ////////////////////////////////////////////////////////////////////////// - { - PROFILE_LABEL_SCOPE("CUSTOM SHADOW MAPS") - - for (int32* pID = m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].begin(); pID != m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].end(); ++pID) - { - ShadowMapFrustum& curFrustum = m_RP.m_SMFrustums[nThreadID][nCurRecLevel][*pID]; - const bool bIsNearestFrustum = curFrustum.m_eFrustumType == ShadowMapFrustum::e_Nearest; - - // stencil prepass for per rendernode frustums. front AND back faces here - if (!bIsNearestFrustum) - { - FX_DeferredShadowPass(pLight, &curFrustum, false, false, true, -1); - } - - // shadow pass - FX_DeferredShadowPass(pLight, &curFrustum, true, false, false, bIsNearestFrustum ? 0 : m_nStencilMaskRef); - } - } - //////////////////////////////////////////////////////////////////////////////////////////////// - - return true; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.cpp deleted file mode 100644 index af4ca53e95..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.cpp +++ /dev/null @@ -1,5837 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "D3DPostProcess.h" -#include "../Common/Textures/TextureManager.h" -#include "../Common/Textures/TextureHelpers.h" -#include "../Common/RendElements/FlareSoftOcclusionQuery.h" -#include "../Common/ReverseDepth.h" -#include "../Common/RenderCapabilities.h" -#include "D3DTiledShading.h" - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DDEFERREDSHADING_CPP_SECTION_1 1 -#define D3DDEFERREDSHADING_CPP_SECTION_2 2 -#define D3DDEFERREDSHADING_CPP_SECTION_3 3 -#define D3DDEFERREDSHADING_CPP_SECTION_4 4 -#define D3DDEFERREDSHADING_CPP_SECTION_5 5 -#define D3DDEFERREDSHADING_CPP_SECTION_6 6 -#endif - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif -#include "GraphicsPipeline/FurPasses.h" - -#define MAX_VIS_AREAS 32 - -// MSAA potential optimizations todo: -// - long term: port all functionality to compute, including all extra effects passes. - -// About MSAA: -// - Please be careful when accessing or rendering into msaa'ed targets. When adding new techniques please make sure to test -// - For post process technique to be MSAA friendly, do either: -// - Use compute. Single pass and as efficient as gets. Context switches might be problematic, until all lighting pipeline done like this. -// - For non compute, require 2 passes. One at pixel frequency, other at sub sample frequency. -// - Reuse existing sample frequency regions on stencil via stencilread/write mask: -// - If not possible, tag pixel frequency regions using stencil + m_pMSAAMaskRT -// - Alternative poor man version, do clip in shader. - -CDeferredShading* CDeferredShading::m_pInstance = NULL; - -#define RT_LIGHTSMASK g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5] | g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ] | g_HWSR_MaskBit[HWSR_CUBEMAP0] | g_HWSR_MaskBit[HWSR_APPLY_SSDO] | g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION] -#define RT_LIGHTPASS_RESETMASK g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | g_HWSR_MaskBit[HWSR_SAMPLE5] | g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ] | g_HWSR_MaskBit[HWSR_CUBEMAP0] | g_HWSR_MaskBit[HWSR_APPLY_SSDO] | g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION] -#define RT_DEBUGMASK g_HWSR_MaskBit[HWSR_DEBUG0] | g_HWSR_MaskBit[HWSR_DEBUG1] | g_HWSR_MaskBit[HWSR_DEBUG2] | g_HWSR_MaskBit[HWSR_DEBUG3] -#define RT_TEX_PROJECT g_HWSR_MaskBit[HWSR_SAMPLE0] -#define RT_GLOBAL_CUBEMAP g_HWSR_MaskBit[HWSR_SAMPLE0] -#define RT_SPECULAR_CUBEMAP g_HWSR_MaskBit[HWSR_SAMPLE1] -#define RT_AMBIENT_LIGHT g_HWSR_MaskBit[HWSR_SAMPLE5] -#define RT_GLOBAL_CUBEMAP_IGNORE_VISAREAS g_HWSR_MaskBit[HWSR_SAMPLE4] -#define RT_AREALIGHT g_HWSR_MaskBit[HWSR_SAMPLE1] -#define RT_OVERDRAW_DEBUG g_HWSR_MaskBit[HWSR_DEBUG0] -#define RT_BOX_PROJECTION g_HWSR_MaskBit[HWSR_SAMPLE3] -#define RT_CLIPVOLUME_ID g_HWSR_MaskBit[HWSR_LIGHTVOLUME0] - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CTexPoolAtlas::Init(int nSize) -{ - m_nSize = nSize; - Clear(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CTexPoolAtlas::Clear() -{ - memset(&m_arrAllocatedBlocks[0], 0, MAX_BLOCKS * sizeof(m_arrAllocatedBlocks[0])); -#ifdef _DEBUG - m_nTotalWaste = 0; - m_arrDebugBlocks.clear(); -#endif -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CTexPoolAtlas::FreeMemory() -{ -#ifdef _DEBUG - stl::free_container(m_arrDebugBlocks); -#endif -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CTexPoolAtlas::AllocateGroup(int32* pOffsetX, int32* pOffsetY, int nSizeX, int nSizeY) -{ - int nBorder = 2; - nSizeX += nBorder << 1; - nSizeY += nBorder << 1; - - if (nSizeX > m_nSize || nSizeY > m_nSize) - { - return false; - } - - uint16 nBestX = 0; - uint16 nBestY = 0; - uint16 nBestID = 0; - uint32 nBestWaste = ~0; - - // outer loop over all relevant allocated blocks (Y dimension) - int nCurrY = 0; - for (int nCurrBlockID = 0; - m_arrAllocatedBlocks[max(nCurrBlockID - 1, 0)] > 0 && nCurrY <= m_nSize - nSizeY && nBestWaste > 0; - ++nCurrBlockID) - { - const uint32 nCurrBlock = m_arrAllocatedBlocks[nCurrBlockID]; - const uint16 nCurrBlockWidth = LOWORD(nCurrBlock); - const uint16 nCurrBlockHeight = HIWORD(nCurrBlock); - - // get max X for intersected blocks - int nCurrX = nCurrBlockWidth; - int nNextY = nCurrBlockHeight; - for (uint16 nNextBlockID = nCurrBlockID + 1; - m_arrAllocatedBlocks[nNextBlockID] > 0 && nNextY < nSizeY; - ++nNextBlockID) - { - const uint32 nNextBlock = m_arrAllocatedBlocks[nNextBlockID]; - const uint16 nNextBlockWidth = LOWORD(nNextBlock); - const uint16 nNextBlockHeight = HIWORD(nNextBlock); - nCurrX = max(nCurrX, int(nNextBlockWidth)); - nNextY += nNextBlockHeight; - } - - // can fit next to them? - if (nSizeX <= m_nSize - nCurrX) - { - // compute waste - uint32 nWaste = 0; - nNextY = nCurrY; - for (uint16 nNextBlockID = nCurrBlockID; - m_arrAllocatedBlocks[nNextBlockID] > 0 && nNextY < nCurrY + nSizeY; - ++nNextBlockID) - { - const uint32 nNextBlock = m_arrAllocatedBlocks[nNextBlockID]; - const uint16 nNextBlockWidth = LOWORD(nNextBlock); - const uint16 nNextBlockHeight = HIWORD(nNextBlock); - nWaste += (nCurrX - nNextBlockWidth) * (min(nCurrY + nSizeY, nNextY + nNextBlockHeight) - max(nCurrY, nNextY)); - nNextY += nNextBlockHeight; - } - nWaste += max(nCurrY + nSizeY - nNextY, 0) * nCurrX; - - // right spot? - if (nWaste < nBestWaste) - { - nBestX = nCurrX; - nBestY = nCurrY; - nBestID = nCurrBlockID; - nBestWaste = nWaste; - } - } - - nCurrY += nCurrBlockHeight; - } - - if ((nBestX | nBestY) || nCurrY <= m_nSize - nSizeY) - { - assert(nBestID < MAX_BLOCKS - 1); - if (nBestID >= MAX_BLOCKS - 1) - { - return false; - } - - *pOffsetX = nBestX + nBorder; - *pOffsetY = nBestY + nBorder; - - // block to be added, update block info - uint32 nBlockData = m_arrAllocatedBlocks[nBestID]; - const uint16 nReplacedHeight = HIWORD(nBlockData); - if (nSizeY < nReplacedHeight) - { - nBlockData = MAKELONG(nBlockData, nReplacedHeight - nSizeY); - // shift by 1 - for (uint16 nID = nBestID + 1; nBlockData > 0; ++nID) - { - std::swap(m_arrAllocatedBlocks[nID], nBlockData); - } - } - else if (nSizeY > nReplacedHeight) - { - uint16 nCoveredHeight = nReplacedHeight; - uint16 nBlocksToSkip = 0; - nBlockData = m_arrAllocatedBlocks[nBestID + 1]; - for (uint16 nID = nBestID + 1; nBlockData > 0; nBlockData = m_arrAllocatedBlocks[++nID]) - { - const uint16 nCurrHeight = HIWORD(nBlockData); - nCoveredHeight += nCurrHeight; - if (nSizeY >= nCoveredHeight) - { - nBlocksToSkip++; - } - else - { - m_arrAllocatedBlocks[nID] = MAKELONG(nBlockData, nCoveredHeight - nSizeY); - break; - } - } - // shift by nBlocksToSkip - uint16 nID = nBestID + nBlocksToSkip + 1; - nBlockData = m_arrAllocatedBlocks[nID]; - for (; nBlockData > 0; nBlockData = m_arrAllocatedBlocks[++nID]) - { - m_arrAllocatedBlocks[nID - nBlocksToSkip] = nBlockData; - } - } - m_arrAllocatedBlocks[nBestID] = MAKELONG(nBestX + nSizeX, nSizeY); - -#ifdef _DEBUG - if (m_arrDebugBlocks.size()) - { - m_nTotalWaste += nBestWaste; - } - _AddDebugBlock(nBestX, nBestY, nSizeX, nSizeY); -#endif - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef _DEBUG -void CTexPoolAtlas::_AddDebugBlock(int x, int y, int sizeX, int sizeY) -{ - SShadowMapBlock block; - block.m_nX1 = x; - block.m_nX2 = x + sizeX; - block.m_nY1 = y; - block.m_nY2 = y + sizeY; - assert(block.m_nX2 <= m_nSize && block.m_nY2 <= m_nSize); - for (std::vector::const_iterator it = m_arrDebugBlocks.begin(); - it != m_arrDebugBlocks.end(); it++) - { - assert(!block.Intersects(*it)); - } - m_arrDebugBlocks.push_back(block); -} - -float CTexPoolAtlas::_GetDebugUsage() const -{ - uint32 nUsed = 0; - for (std::vector::const_iterator it = m_arrDebugBlocks.begin(); - it != m_arrDebugBlocks.end(); it++) - { - nUsed += (it->m_nX2 - it->m_nX1) * (it->m_nY2 - it->m_nY1); - } - - return 100.f * nUsed / (m_nSize * m_nSize); -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SRenderLight::CalculateScissorRect() -{ - Vec3 cameraPos = gcpRendD3D->GetCamera().GetPosition(); - Vec3 vViewVec = m_Origin - cameraPos; - float fDistToLS = vViewVec.GetLength(); - - // Use max of width/height for area lights. - float fMaxRadius = m_fRadius; - - if (m_Flags & DLF_AREA_LIGHT) // Use max for area lights. - { - fMaxRadius += max(m_fAreaWidth, m_fAreaHeight); - } - else if (m_Flags & DLF_DEFERRED_CUBEMAPS) - { - fMaxRadius = m_ProbeExtents.len(); // This is not optimal for a box - } - ITexture* pLightTexture = m_pLightImage ? m_pLightImage : NULL; - bool bProjectiveLight = (m_Flags & DLF_PROJECT) && pLightTexture && !(pLightTexture->GetFlags() & FT_REPLICATE_TO_ALL_SIDES); - bool bInsideLightVolume = fDistToLS <= fMaxRadius; - if (bInsideLightVolume && !bProjectiveLight) - { - //optimization when we are inside light frustum - m_sX = 0; - m_sY = 0; - m_sWidth = gcpRendD3D->GetWidth(); - m_sHeight = gcpRendD3D->GetHeight(); - - return; - } - - // e_ScissorDebug will modify the view matrix here, so take a local copy - const Matrix44& mView = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_matView; - const Matrix44& mProj = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_matProj; - - Vec3 vCenter = m_Origin; - float fRadius = fMaxRadius; - - const int nMaxVertsToProject = 10; - int nVertsToProject = 4; - Vec3 pBRectVertices[nMaxVertsToProject]; - - Vec4 vCenterVS = Vec4(vCenter, 1) * mView; - - if (!bInsideLightVolume) - { - // Compute tangent planes - float r = fRadius; - float sq_r = r * r; - - Vec3 vLPosVS = Vec3(vCenterVS.x, vCenterVS.y, vCenterVS.z); - float lx = vLPosVS.x; - float ly = vLPosVS.y; - float lz = vLPosVS.z; - float sq_lx = lx * lx; - float sq_ly = ly * ly; - float sq_lz = lz * lz; - - // Compute left and right tangent planes to light sphere - float sqrt_d = sqrt_tpl(max(sq_r * sq_lx - (sq_lx + sq_lz) * (sq_r - sq_lz), 0.0f)); - float nx = iszero(sq_lx + sq_lz) ? 1.0f : (r * lx + sqrt_d) / (sq_lx + sq_lz); - float nz = iszero(lz) ? 1.0f : (r - nx * lx) / lz; - - Vec3 vTanLeft = Vec3(nx, 0, nz).normalized(); - - nx = iszero(sq_lx + sq_lz) ? 1.0f : (r * lx - sqrt_d) / (sq_lx + sq_lz); - nz = iszero(lz) ? 1.0f : (r - nx * lx) / lz; - Vec3 vTanRight = Vec3(nx, 0, nz).normalized(); - - pBRectVertices[0] = vLPosVS - r * vTanLeft; - pBRectVertices[1] = vLPosVS - r * vTanRight; - - // Compute top and bottom tangent planes to light sphere - sqrt_d = sqrt_tpl(max(sq_r * sq_ly - (sq_ly + sq_lz) * (sq_r - sq_lz), 0.0f)); - float ny = iszero(sq_ly + sq_lz) ? 1.0f : (r * ly - sqrt_d) / (sq_ly + sq_lz); - nz = iszero(lz) ? 1.0f : (r - ny * ly) / lz; - Vec3 vTanBottom = Vec3(0, ny, nz).normalized(); - - ny = iszero(sq_ly + sq_lz) ? 1.0f : (r * ly + sqrt_d) / (sq_ly + sq_lz); - nz = iszero(lz) ? 1.0f : (r - ny * ly) / lz; - Vec3 vTanTop = Vec3(0, ny, nz).normalized(); - - pBRectVertices[2] = vLPosVS - r * vTanTop; - pBRectVertices[3] = vLPosVS - r * vTanBottom; - } - - if (bProjectiveLight) - { - // todo: improve/simplify projective case - - Vec3 vRight = m_ObjMatrix.GetColumn2(); - Vec3 vUp = -m_ObjMatrix.GetColumn1(); - Vec3 pDirFront = m_ObjMatrix.GetColumn0(); - pDirFront.NormalizeFast(); - - // Cone radius - float fConeAngleThreshold = 0.0f; - float fConeRadiusScale = /*min(1.0f,*/ tan_tpl((m_fLightFrustumAngle + fConeAngleThreshold) * (gf_PI / 180.0f)); //); - float fConeRadius = fRadius * fConeRadiusScale; - - Vec3 pDiagA = (vUp + vRight); - float fDiagLen = 1.0f / pDiagA.GetLengthFast(); - pDiagA *= fDiagLen; - - Vec3 pDiagB = (vUp - vRight); - pDiagB *= fDiagLen; - - float fPyramidBase = sqrt_tpl(fConeRadius * fConeRadius * 2.0f); - pDirFront *= fRadius; - - Vec3 pEdgeA = (pDirFront + pDiagA * fPyramidBase); - Vec3 pEdgeA2 = (pDirFront - pDiagA * fPyramidBase); - Vec3 pEdgeB = (pDirFront + pDiagB * fPyramidBase); - Vec3 pEdgeB2 = (pDirFront - pDiagB * fPyramidBase); - - uint32 nOffset = 4; - - // Check whether the camera is inside the extended bounding sphere that contains pyramid - - // we are inside light frustum - // Put all pyramid vertices in view space - Vec4 pPosVS = Vec4(vCenter, 1) * mView; - pBRectVertices[nOffset++] = Vec3(pPosVS.x, pPosVS.y, pPosVS.z); - pPosVS = Vec4(vCenter + pEdgeA, 1) * mView; - pBRectVertices[nOffset++] = Vec3(pPosVS.x, pPosVS.y, pPosVS.z); - pPosVS = Vec4(vCenter + pEdgeB, 1) * mView; - pBRectVertices[nOffset++] = Vec3(pPosVS.x, pPosVS.y, pPosVS.z); - pPosVS = Vec4(vCenter + pEdgeA2, 1) * mView; - pBRectVertices[nOffset++] = Vec3(pPosVS.x, pPosVS.y, pPosVS.z); - pPosVS = Vec4(vCenter + pEdgeB2, 1) * mView; - pBRectVertices[nOffset++] = Vec3(pPosVS.x, pPosVS.y, pPosVS.z); - - nVertsToProject = nOffset; - } - - Vec3 vPMin = Vec3(1, 1, 999999.0f); - Vec2 vPMax = Vec2(0, 0); - Vec2 vMin = Vec2(1, 1); - Vec2 vMax = Vec2(0, 0); - - int nStart = 0; - - if (bInsideLightVolume) - { - nStart = 4; - vMin = Vec2(0, 0); - vMax = Vec2(1, 1); - } - - const ICVar* scissorDebugCVar = iConsole->GetCVar("e_ScissorDebug"); - int scissorDebugEnabled = scissorDebugCVar ? scissorDebugCVar->GetIVal() : 0; - Matrix44 invertedView; - if (scissorDebugEnabled) - { - invertedView = mView.GetInverted(); - } - - // Project all vertices - for (int i = nStart; i < nVertsToProject; i++) - { - if (scissorDebugEnabled) - { - if (gcpRendD3D->GetIRenderAuxGeom() != NULL) - { - Vec4 pVertWS = Vec4(pBRectVertices[i], 1) * invertedView; - Vec3 v = Vec3(pVertWS.x, pVertWS.y, pVertWS.z); - gcpRendD3D->GetIRenderAuxGeom()->DrawPoint(v, RGBA8(0xff, 0xff, 0xff, 0xff), 10); - - int32 nPrevVert = (i - 1) < 0 ? nVertsToProject - 1 : (i - 1); - pVertWS = Vec4(pBRectVertices[nPrevVert], 1) * invertedView; - Vec3 v2 = Vec3(pVertWS.x, pVertWS.y, pVertWS.z); - gcpRendD3D->GetIRenderAuxGeom()->DrawLine(v, RGBA8(0xff, 0xff, 0x0, 0xff), v2, RGBA8(0xff, 0xff, 0x0, 0xff), 3.0f); - } - } - - Vec4 vScreenPoint = Vec4(pBRectVertices[i], 1.0) * mProj; - - //projection space clamping - vScreenPoint.w = max(vScreenPoint.w, 0.00000000000001f); - vScreenPoint.x = max(vScreenPoint.x, -(vScreenPoint.w)); - vScreenPoint.x = min(vScreenPoint.x, vScreenPoint.w); - vScreenPoint.y = max(vScreenPoint.y, -(vScreenPoint.w)); - vScreenPoint.y = min(vScreenPoint.y, vScreenPoint.w); - - //NDC - vScreenPoint /= vScreenPoint.w; - - //output coords - //generate viewport (x=0,y=0,height=1,width=1) - Vec2 vWin; - vWin.x = (1.0f + vScreenPoint.x) * 0.5f; - vWin.y = (1.0f + vScreenPoint.y) * 0.5f; //flip coords for y axis - - // clamp to [0.0, 1.0] - vWin.x = clamp_tpl(vWin.x, 0.0f, 1.0f); - vWin.y = clamp_tpl(vWin.y, 0.0f, 1.0f); - - assert(vWin.x >= 0.0f && vWin.x <= 1.0f); - assert(vWin.y >= 0.0f && vWin.y <= 1.0f); - - if (bProjectiveLight && i >= 4) - { - // Get light pyramid screen bounds - vPMin.x = min(vPMin.x, vWin.x); - vPMin.y = min(vPMin.y, vWin.y); - vPMax.x = max(vPMax.x, vWin.x); - vPMax.y = max(vPMax.y, vWin.y); - - vPMin.z = min(vPMin.z, vScreenPoint.z); // if pyramid intersects the nearplane, the test is unreliable. (requires proper clipping) - } - else - { - // Get light sphere screen bounds - vMin.x = min(vMin.x, vWin.x); - vMin.y = min(vMin.y, vWin.y); - vMax.x = max(vMax.x, vWin.x); - vMax.y = max(vMax.y, vWin.y); - } - } - - int iWidth = gcpRendD3D->GetWidth(); - int iHeight = gcpRendD3D->GetHeight(); - float fWidth = (float)iWidth; - float fHeight = (float)iHeight; - - if (bProjectiveLight) - { - vPMin.x = (float)fsel(vPMin.z, vPMin.x, vMin.x); // Use sphere bounds if pyramid bounds are unreliable - vPMin.y = (float)fsel(vPMin.z, vPMin.y, vMin.y); - vPMax.x = (float)fsel(vPMin.z, vPMax.x, vMax.x); - vPMax.y = (float)fsel(vPMin.z, vPMax.y, vMax.y); - - // Clamp light pyramid bounds to light sphere screen bounds - vMin.x = clamp_tpl(vPMin.x, vMin.x, vMax.x); - vMin.y = clamp_tpl(vPMin.y, vMin.y, vMax.y); - vMax.x = clamp_tpl(vPMax.x, vMin.x, vMax.x); - vMax.y = clamp_tpl(vPMax.y, vMin.y, vMax.y); - } - - m_sX = (short)(vMin.x * fWidth); - m_sY = (short)((1.0f - vMax.y) * fHeight); - m_sWidth = (short)ceilf((vMax.x - vMin.x) * fWidth); - m_sHeight = (short)ceilf((vMax.y - vMin.y) * fHeight); - - // make sure we don't create a scissor rect out of bound (D3DError) - m_sWidth = (m_sX + m_sWidth) > iWidth ? iWidth - m_sX : m_sWidth; - m_sHeight = (m_sY + m_sHeight) > iHeight ? iHeight - m_sY : m_sHeight; - -#if !defined(RELEASE) - if (scissorDebugEnabled) - { - // Render 2d areas additively on screen - IRenderAuxGeom* pAuxRenderer = gEnv->pRenderer->GetIRenderAuxGeom(); - if (pAuxRenderer) - { - SAuxGeomRenderFlags oldRenderFlags = pAuxRenderer->GetRenderFlags(); - - SAuxGeomRenderFlags newRenderFlags; - newRenderFlags.SetDepthTestFlag(e_DepthTestOff); - newRenderFlags.SetAlphaBlendMode(e_AlphaAdditive); - newRenderFlags.SetMode2D3DFlag(e_Mode2D); - pAuxRenderer->SetRenderFlags(newRenderFlags); - - const float screenWidth = (float)gcpRendD3D->GetWidth(); - const float screenHeight = (float)gcpRendD3D->GetHeight(); - - // Calc resolve area - const float left = m_sX / screenWidth; - const float top = m_sY / screenHeight; - const float right = (m_sX + m_sWidth) / screenWidth; - const float bottom = (m_sY + m_sHeight) / screenHeight; - - // Render resolve area - ColorB areaColor(50, 0, 50, 255); - - if (vPMin.z < 0.0f) - { - areaColor = ColorB(0, 100, 0, 255); - } - - const uint vertexCount = 6; - const Vec3 vert[vertexCount] = { - Vec3(left, top, 0.0f), - Vec3(left, bottom, 0.0f), - Vec3(right, top, 0.0f), - Vec3(left, bottom, 0.0f), - Vec3(right, bottom, 0.0f), - Vec3(right, top, 0.0f) - }; - pAuxRenderer->DrawTriangles(vert, vertexCount, areaColor); - - // Set previous Aux render flags back again - pAuxRenderer->SetRenderFlags(oldRenderFlags); - } - } -#endif -} - -uint32 CDeferredShading::AddLight(const CDLight& pDL, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - const uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - const int32 nRecurseLevel = passInfo.GetRecursiveLevel(); - - eDeferredLightType LightType = eDLT_DeferredLight; - if (pDL.m_Flags & DLF_DEFERRED_CUBEMAPS) - { - LightType = eDLT_DeferredCubemap; - } - else if (pDL.m_Flags & DLF_AMBIENT) - { - LightType = eDLT_DeferredAmbientLight; - } - - if (pDL.GetLensOpticsElement() && !pDL.m_pSoftOccQuery) - { - CDLight* pLight = const_cast(&pDL); - - const uint8 numVisibilityFaders = 2; // For each flare type - pLight->m_pSoftOccQuery = new CFlareSoftOcclusionQuery(numVisibilityFaders); - } - - TArray& rArray = m_pLights[LightType][nThreadID][nRecurseLevel]; - - const int32 lightsNum = (int32)rArray.Num(); - int idx = -1; - - rArray.AddElem(pDL); - idx = rArray.Num() - 1; - rArray[idx].m_lightId = idx; - rArray[idx].AcquireResources(); - - IF_LIKELY (eDLT_DeferredLight == LightType) - { - rArray[idx].m_Color *= fMult; - rArray[idx].m_SpecMult *= fMult; - } - else if (eDLT_DeferredAmbientLight == LightType) - { - ColorF origCol(rArray[idx].m_Color); - rArray[idx].m_Color.lerpFloat(Col_White, origCol, fMult); - } - else if (eDLT_DeferredCubemap == LightType) - { - rArray[idx].m_fProbeAttenuation *= fMult; - } - else - { - AZ_Assert(false, "Unhandled eDeferredLightType %d", LightType); - } - - gcpRendD3D->EF_CheckLightMaterial(const_cast(&pDL), idx, passInfo, rendItemSorter); - - return idx; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -TArray& CDeferredShading::GetLights(int nThreadID, int nCurRecLevel, const eDeferredLightType eType) -{ - return m_pLights[eType][nThreadID][nCurRecLevel]; -} - -SRenderLight* CDeferredShading::GetLightByID(const uint16 nLightID, const eDeferredLightType eType) -{ - const uint32 nThreadID = gcpRendD3D->m_RP.m_nProcessThreadID; - assert(SRendItem::m_RecurseLevel[nThreadID] >= 0); - const int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - TArray& pLightsList = GetLights(nThreadID, nRecurseLevel, eType); - SRenderLight* foundIter = AZStd::find_if(pLightsList.begin(), pLightsList.end(), [&](const SRenderLight& light) {return light.m_lightId == nLightID; }); - if (foundIter != pLightsList.end()) - { - return foundIter; - } - - return nullptr; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::GetClipVolumeParams(const Vec4*& pParams, uint32& nCount) -{ - pParams = m_vClipVolumeParams; - nCount = m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel]; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -uint32 CDeferredShading::GetLightsNum(const eDeferredLightType eType) -{ - uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - assert(nRecurseLevel >= 0); - - return m_pLights[eType][nThreadID][nRecurseLevel].size(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ResetLights() -{ - uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nRecurseLevel >= 0); - - for (uint32 iLightType = 0; iLightType < eDLT_NumLightTypes; ++iLightType) - { - TArray& pLightList = m_pLights[iLightType][nThreadID][nRecurseLevel]; - - const uint32 nNumLights = pLightList.size(); - for (uint32 l = 0; l < nNumLights; ++l) - { - SRenderLight& pLight = pLightList[l]; - pLight.DropResources(); - } - - pLightList.SetUse(0); - } - m_vecGIClipVolumes[nThreadID][nRecurseLevel].resize(0); - - gcpRendD3D->GetVolumetricFog().Clear(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ResetAllLights() -{ - for (size_t i = 0; i < eDLT_NumLightTypes; ++i) - { - for (size_t j = 0; j < RT_COMMAND_BUF_COUNT; ++j) - { - for (size_t k = 0; k < MAX_REND_RECURSION_LEVELS; ++k) - { - TArray& pLightList = m_pLights[i][j][k]; - - const uint32 nNumLights = pLightList.size(); - for (uint32 l = 0; l < nNumLights; ++l) - { - SRenderLight& pLight = pLightList[l]; - pLight.DropResources(); - } - - pLightList.Free(); - } - } - } - - gcpRendD3D->GetTiledShading().Clear(); - - gcpRendD3D->GetVolumetricFog().ClearAll(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ReleaseData() -{ - // When the engine shutsdown this method gets called twice: once for when the level - // is unloaded (main thread) and once when the renderer is shutdown (render thread). - // Because m_nShadowPoolSize gets set to zero only in this method, we can use it as - // flag to indicate that we have already released the data and there is no reason - // to do so again. This avoids the assert a few lines below when the renderer is - // shutdown... - if (m_nShadowPoolSize == 0) - { - return; - } - - - ResetAllLights(); - for (uint32 iThread = 0; iThread < 2; ++iThread) - { - for (uint32 nRecurseLevel = 0; nRecurseLevel < MAX_REND_RECURSION_LEVELS; ++nRecurseLevel) - { - m_vecGIClipVolumes[iThread][nRecurseLevel].clear(); - } - } - - m_shadowPoolAlloc.SetUse(0); - stl::free_container(m_shadowPoolAlloc); - - m_blockPack->FreeContainers(); - - m_nShadowPoolSize = 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -inline uint8 CDeferredShading::AddClipVolume(const IClipVolume* pClipVolume) -{ - uint32 nThreadID = gRenDev->m_RP.m_nFillThreadID; - // Note: vis area and clip volume code is processed before EF_StartEf() in 3DEngine side - so recurse level still at -1 at beginning - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID] + 1; - - SClipVolumeData pClipVolumeData; - pClipVolumeData.nStencilRef = m_nClipVolumesCount[nThreadID][nRecurseLevel] + 1; // the first clip volume ID is reserved for outdoors - pClipVolumeData.nFlags = pClipVolume->GetClipVolumeFlags(); - pClipVolumeData.mAABB = pClipVolume->GetClipVolumeBBox(); - pClipVolume->GetClipVolumeMesh(pClipVolumeData.m_pRenderMesh, pClipVolumeData.mWorldTM); - - m_pClipVolumes[nThreadID][nRecurseLevel].push_back(pClipVolumeData); - m_nClipVolumesCount[nThreadID][nRecurseLevel]++; - - return pClipVolumeData.nStencilRef; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool CDeferredShading::SetClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) -{ - uint32 nThreadID = gRenDev->m_RP.m_nFillThreadID; - // Note: vis area and clip volume code is processed before EF_StartEf() in 3DEngine side - so recurse level still at -1 at beginning - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID] + 1; - - size_t nClipVolumeIndex = pClipVolume->GetStencilRef() - 1; // 0 is reserved for outdoor - assert(m_pClipVolumes[nThreadID][nRecurseLevel].size() > nClipVolumeIndex && - m_pClipVolumes[nThreadID][nRecurseLevel][nClipVolumeIndex].nStencilRef == pClipVolume->GetStencilRef()); - - SClipVolumeData& clipVolumeData = m_pClipVolumes[nThreadID][nRecurseLevel][nClipVolumeIndex]; - for (int i = 0; i < SClipVolumeBlendInfo::BlendPlaneCount; ++i) - { - clipVolumeData.m_BlendData.blendPlanes[i] = Vec4(blendInfo.blendPlanes[i].n, blendInfo.blendPlanes[i].d); - clipVolumeData.m_BlendData.nBlendIDs[i] = blendInfo.blendVolumes[i] ? blendInfo.blendVolumes[i]->GetStencilRef() : 0; - } - - clipVolumeData.nFlags |= IClipVolume::eClipVolumeBlend; - return true; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ResetClipVolumes() -{ - uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - // Note: vis area and clip volume code is processed before EF_StartEf() in 3DEngine side - so recurse level still at -1 at beginning - uint32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID] + 1; - - if (nRecurseLevel < MAX_REND_RECURSION_LEVELS) - { - m_pClipVolumes[nThreadID][nRecurseLevel].clear(); - m_nClipVolumesCount[nThreadID][nRecurseLevel] = 0; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ResetAllClipVolumes() -{ - for (size_t i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (size_t j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - m_pClipVolumes[i][j].clear(); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CDeferredShading::SpecularAccEnableMRT(bool bEnable) -{ - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - assert(m_pLBufferSpecularRT); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if (bEnable && !m_bSpecularState) - { - rd->FX_PushRenderTarget(1, m_pLBufferSpecularRT, NULL, -1, false, 1); - m_bSpecularState = true; - return true; - } - else if (!bEnable && m_bSpecularState) - { - m_pLBufferSpecularRT->SetResolved(true); - rd->FX_PopRenderTarget(1); - m_bSpecularState = false; - return true; - } - } - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::SetupPasses() -{ - AZ_TRACE_METHOD(); - CreateDeferredMaps(); - - m_nThreadID = gcpRendD3D->m_RP.m_nProcessThreadID; - m_nRecurseLevel = SRendItem::m_RecurseLevel[m_nThreadID]; - assert(m_nRecurseLevel >= 0); - - m_nBindResourceMsaa = gcpRendD3D->m_RP.m_MSAAData.Type ? SResourceView::DefaultViewMS : SResourceView::DefaultView; - - gcpRendD3D->m_RP.m_FlagsShader_RT &= ~(RT_LIGHTSMASK | RT_DEBUGMASK); - - m_pLBufferDiffuseRT = CTexture::s_ptexCurrentSceneDiffuseAccMap; - m_pLBufferSpecularRT = CTexture::s_ptexSceneSpecularAccMap; - m_pNormalsRT = CTexture::s_ptexSceneNormalsMap; - - if (FurPasses::GetInstance().IsRenderingFur()) - { - m_pDepthRT = CTexture::s_ptexFurZTarget; - } - else - { - m_pDepthRT = CTexture::s_ptexZTarget; - } - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pResolvedStencilRT = CTexture::s_ptexGmemStenLinDepth; - m_pDepthRT = CTexture::s_ptexGmemStenLinDepth; - } - else - { - m_pResolvedStencilRT = CTexture::s_ptexVelocity; - } - m_pDiffuseRT = CTexture::s_ptexSceneDiffuse; - m_pSpecularRT = CTexture::s_ptexSceneSpecular; - m_pMSAAMaskRT = CTexture::s_ptexBackBuffer; - - m_nTexStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - m_nTexStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - - CameraViewParameters* viewParameters = &gcpRendD3D->m_RP.m_TI[m_nThreadID].m_cam.m_viewParameters; - m_pCamFront = viewParameters->vZ; - m_pCamFront.Normalize(); - m_pCamPos = viewParameters->vOrigin; - - m_fCamFar = viewParameters->fFar; - m_fCamNear = viewParameters->fNear; - - m_fRatioWidth = (float)m_pLBufferDiffuseRT->GetWidth() / (float)CTexture::s_ptexSceneTarget->GetWidth(); - m_fRatioHeight = (float)m_pLBufferDiffuseRT->GetHeight() / (float)CTexture::s_ptexSceneTarget->GetHeight(); - - m_pView = gcpRendD3D->m_CameraMatrix; - m_pView.Transpose(); - - m_mViewProj = gcpRendD3D->m_ViewProjMatrix; - m_mViewProj.Transpose(); - - m_pViewProjI = gcpRendD3D->m_ViewProjMatrix.GetInverted(); - - gRenDev->m_cEF.mfRefreshSystemShader("DeferredShading", CShaderMan::s_shDeferredShading); - m_pShader = CShaderMan::s_shDeferredShading; - - gcpRendD3D->SetCullMode(R_CULL_BACK); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest <= 1) - { - m_nRenderState |= GS_NODEPTHTEST; - } - else - { - m_nRenderState &= ~GS_NODEPTHTEST; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDebug == 2) - { - gcpRendD3D->m_RP.m_FlagsShader_RT |= RT_OVERDRAW_DEBUG; - } - - m_nCurTargetWidth = m_pLBufferDiffuseRT->GetWidth(); - m_nCurTargetHeight = m_pLBufferDiffuseRT->GetHeight(); - - // Verify if sun present in non-deferred light list (usually fairly small list) - gcpRendD3D->m_RP.m_pSunLight = NULL; - for (uint32 i = 0; i < gcpRendD3D->m_RP.m_DLights[m_nThreadID][m_nRecurseLevel].Num(); i++) - { - SRenderLight* dl = &gcpRendD3D->m_RP.m_DLights[m_nThreadID][m_nRecurseLevel][i]; - if (dl->m_Flags & DLF_SUN) - { - gcpRendD3D->m_RP.m_pSunLight = dl; - break; - } - } - - SetupGlobalConsts(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::SetupGlobalConsts() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - //set world basis - float maskRTWidth = float(m_nCurTargetWidth); - float maskRTHeight = float(m_nCurTargetHeight); - Vec4r vWBasisX, vWBasisY, vWBasisZ, vCamPos; - Vec4 vParamValue, vMag; - CShadowUtils::ProjectScreenToWorldExpansionBasis(rd->m_IdentityMatrix, rd->GetCamera(), Vec2(rd->m_TemporalJitterClipSpace.x, rd->m_TemporalJitterClipSpace.y), maskRTWidth, maskRTHeight, vWBasisX, vWBasisY, vWBasisZ, vCamPos, true, NULL); - - vWorldBasisX = vWBasisX / rd->m_RP.m_CurDownscaleFactor.x; - vWorldBasisY = vWBasisY / rd->m_RP.m_CurDownscaleFactor.y; - vWorldBasisZ = vWBasisZ; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::FilterGBuffer() -{ - if (!CRenderer::CV_r_DeferredShadingFilterGBuffer) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - PROFILE_LABEL_SCOPE("GBUFFER_FILTER"); - - static CCryNameTSCRC tech("FilterGBuffer"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - PostProcessUtils().StretchRect(CTexture::s_ptexSceneSpecular, CTexture::s_ptexStereoR); - CTexture* pSceneSpecular = CTexture::s_ptexStereoR; -#endif - - if (CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - rd->FX_PushRenderTarget(0, CTexture::s_ptexSceneSpecular, NULL); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, tech, FEF_DONTSETSTATES); - rd->FX_SetState(GS_NODEPTHTEST); - SPostEffectsUtils::SetTexture(CTexture::s_ptexSceneNormalsMap, 0, FILTER_POINT, 0); - SPostEffectsUtils::SetTexture(pSceneSpecular, 1, FILTER_POINT, 0); - SPostEffectsUtils::SetTexture(m_pDepthRT, 2, FILTER_POINT, 0); - - // Bind sampler directly so that it works with DX11 style texture objects - ID3D11SamplerState* pSamplers[1] = { (ID3D11SamplerState*)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState }; - rd->m_DevMan.BindSampler(eHWSC_Pixel, pSamplers, 15, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneSpecular->GetWidth(), CTexture::s_ptexSceneSpecular->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - ID3D11SamplerState* pSampNull[1] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Pixel, pSampNull, 15, 1); - rd->FX_Commit(); - - rd->FX_PopRenderTarget(0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::DrawLightVolume(EShapeMeshType meshType, const Matrix44& mUnitVolumeToWorld, const Vec4& vSphereAdjust) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - float maskRTWidth = (float) m_nCurTargetWidth; - float maskRTHeight = (float) m_nCurTargetHeight; - - Vec4 vScreenScale(1.0f / maskRTWidth, 1.0f / maskRTHeight, - 0.0f, 0.0f); - - { - static CCryNameR paramName("g_ScreenScale"); - m_pShader->FXSetPSFloat(paramName, &vScreenScale, 1); - } - - { - static CCryNameR paramName("vWBasisX"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisX, 1); - } - - { - static CCryNameR paramName("vWBasisY"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisY, 1); - } - - { - static CCryNameR paramName("vWBasisZ"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisZ, 1); - } - - { - static CCryNameR paramNameVolumeToWorld("g_mUnitLightVolumeToWorld"); - m_pShader->FXSetVSFloat(paramNameVolumeToWorld, (Vec4*) mUnitVolumeToWorld.GetData(), 4); - } - - { - static CCryNameR paramNameSphereAdjust("g_vLightVolumeSphereAdjust"); - m_pShader->FXSetVSFloat(paramNameSphereAdjust, &vSphereAdjust, 1); - } - - { - static CCryNameR paramName("g_mViewProj"); - Matrix44 mViewProjMatrix = rd->m_ViewMatrix * rd->m_ProjMatrix; - m_pShader->FXSetVSFloat(paramName, (Vec4*) mViewProjMatrix.GetData(), 4); - } - - // Vertex/index buffer - rd->FX_SetVStream(0, rd->m_pUnitFrustumVB[meshType], 0, sizeof(SVF_P3F_C4B_T2F)); - rd->FX_SetIStream(rd->m_pUnitFrustumIB[meshType], 0, (rd->kUnitObjectIndexSizeof == 2 ? Index16 : Index32)); - - rd->D3DSetCull(eCULL_Back); - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - rd->FX_Commit(false); - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, rd->m_UnitFrustVBSize[meshType], 0, rd->m_UnitFrustIBSize[meshType]); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DrawDecalVolume([[maybe_unused]] const SDeferredDecal& rDecal, Matrix44A& mDecalLightProj, ECull volumeCull) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - float maskRTWidth = float(m_nCurTargetWidth); - float maskRTHeight = float(m_nCurTargetHeight); - - Vec4 vScreenScale(1.0f / maskRTWidth, 1.0f / maskRTHeight, - 0.0f, 0.0f); - - { - static CCryNameR paramName("g_ScreenScale"); - m_pShader->FXSetPSFloat(paramName, &vScreenScale, 1); - } - - { - static CCryNameR paramName("vWBasisX"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisX, 1); - } - - { - static CCryNameR paramName("vWBasisY"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisY, 1); - } - - { - static CCryNameR paramName("vWBasisZ"); - m_pShader->FXSetPSFloat(paramName, &vWorldBasisZ, 1); - } - - //////////////// light sphere processing ///////////////////////////////// - { - Matrix44 mInvDecalLightProj = mDecalLightProj.GetInverted(); - static CCryNameR paramName("g_mInvLightProj"); - m_pShader->FXSetVSFloat(paramName, alias_cast(&mInvDecalLightProj), 4); - } - - { - static CCryNameR paramName("g_mViewProj"); - m_pShader->FXSetVSFloat(paramName, alias_cast(&m_mViewProj), 4); - } - - rd->FX_SetVStream(0, rd->m_pUnitFrustumVB[SHAPE_BOX], 0, sizeof(SVF_P3F_C4B_T2F)); - rd->FX_SetIStream(rd->m_pUnitFrustumIB[SHAPE_BOX], 0, (rd->kUnitObjectIndexSizeof == 2 ? Index16 : Index32)); - - rd->D3DSetCull(volumeCull); - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - rd->FX_Commit(false); - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, rd->m_UnitFrustVBSize[SHAPE_BOX], 0, rd->m_UnitFrustIBSize[SHAPE_BOX]); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Calculates matrix that projects WS position into decal volume for texture coordinates -Matrix44A GetDecalLightProjMatrix(const SDeferredDecal& rDecal) -{ - static const float fZNear = -0.3f; - static const float fZFar = 0.5f; - - static const Matrix44A mTextureAndDepth( - 0.5f, 0.0f, 0.0f, 0.5f, - 0.0f, -0.5f, 0.0f, 0.5f, - 0.0f, 0.0f, 1.0f / (fZNear - fZFar), fZNear / (fZNear - fZFar), - 0.0f, 0.0f, 0.0f, 1.0f); - - // transform world coords to decal texture coords - Matrix44A mDecalLightProj = mTextureAndDepth * rDecal.projMatrix.GetInverted(); - return mDecalLightProj; -} - -// Calculates tangent space to world matrix -Matrix44A CalculateTSMatrix(const Vec3 vBasisX, const Vec3 vBasisY, const Vec3 vBasisZ) -{ - const Vec3 vNormX = vBasisX.GetNormalized(); - const Vec3 vNormY = vBasisY.GetNormalized(); - const Vec3 vNormZ = vBasisZ.GetNormalized(); - - // decal normal map to world transform - Matrix44A mDecalTS( - vNormX.x, vNormX.y, vNormX.z, 0, - -vNormY.x, -vNormY.y, -vNormY.z, 0, - vNormZ.x, vNormZ.y, vNormZ.z, 0, - 0, 0, 0, 1); - - return mDecalTS; -} - -// Shared function to get dynamic parameters for deferred decals -void GetDynamicDecalParams(AZStd::vector& shaderParams, float& decalAlphaMult, float& decalFalloff, float& decalDiffuseOpacity, float& emittanceMapGamma) -{ - decalAlphaMult = 1.0f; - decalFalloff = 1.0f; - emittanceMapGamma = 1.0f; - decalDiffuseOpacity = 1.0f; - - for (uint32 i = 0, si = shaderParams.size(); i < si; ++i) - { - const char* name = shaderParams[i].m_Name.c_str(); - if (azstricmp(name, "DecalAlphaMult") == 0) - { - decalAlphaMult = shaderParams[i].m_Value.m_Float; - } - else if (azstricmp(name, "DecalFalloff") == 0) - { - decalFalloff = shaderParams[i].m_Value.m_Float; - } - else if (azstricmp(name, "EmittanceMapGamma") == 0) - { - emittanceMapGamma = shaderParams[i].m_Value.m_Float; - } - else if (azstricmp(name, "DecalDiffuseOpacity") == 0) - { - decalDiffuseOpacity = shaderParams[i].m_Value.m_Float; - } - } -} - -bool CDeferredShading::DeferredDecalPass(const SDeferredDecal& rDecal, uint32 indDecal) -{ - // __________________________________________________________________________________________ - // Early out if no emissive material - - _smart_ptr pDecalMaterial = rDecal.pMaterial; - if (pDecalMaterial == NULL) - { - AZ_WarningOnce("CDeferredShading", pDecalMaterial == NULL, "Decal missing material."); - return false; - } - - SShaderItem& sItem = pDecalMaterial->GetShaderItem(0); - if (sItem.m_pShaderResources == NULL) - { - assert(0); - return false; - } - - // __________________________________________________________________________________________ - // Begin - - PROFILE_FRAME(CDeferredShading_DecalPass); - PROFILE_SHADER_SCOPE; - - gcpRendD3D->m_RP.m_FlagsShader_RT &= ~(RT_LIGHTSMASK | g_HWSR_MaskBit[HWSR_SAMPLE4]); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - bool bStencilMask = false; - bool bUseLightVolumes = true; - - rd->EF_Scissor(false, 0, 0, 1, 1); - rd->SetDepthBoundTest(0.0f, 1.0f, false); // stencil pre-passes are rop bound, using depth bounds increases even more rop cost - - // coord systems conversion (from orientation to shader matrix) - const Vec3 vBasisX = rDecal.projMatrix.GetColumn0(); - const Vec3 vBasisY = rDecal.projMatrix.GetColumn1(); - const Vec3 vBasisZ = rDecal.projMatrix.GetColumn2(); - - // __________________________________________________________________________________________ - // Textures - - CTexture* pCurTarget = CTexture::s_ptexSceneNormalsMap; - m_nCurTargetWidth = pCurTarget->GetWidth(); - m_nCurTargetHeight = pCurTarget->GetHeight(); - - const float decalSize = max(vBasisX.GetLength() * 2.0f, vBasisY.GetLength() * 2.0f); - - // We will use mipLevelFactor from diffuse texture for other textures - float mipLevelFactor = 0.0; - - ITexture* pDiffuseTex = SetTexture(sItem, EFTT_DIFFUSE, 2, rDecal.rectTexture, decalSize, mipLevelFactor, ESetTexture_Transform | ESetTexture_bSRGBLookup); - assert(pDiffuseTex != nullptr); - - int setTextureFlags = ESetTexture_HWSR | ESetTexture_AllowDefault | ESetTexture_MipFactorProvided; - SetTexture(sItem, EFTT_NORMALS, 3, rDecal.rectTexture, decalSize, mipLevelFactor, setTextureFlags); - SetTexture(sItem, EFTT_SMOOTHNESS, 4, rDecal.rectTexture, decalSize, mipLevelFactor, setTextureFlags); - SetTexture(sItem, EFTT_OPACITY, 5, rDecal.rectTexture, decalSize, mipLevelFactor, setTextureFlags); - - SD3DPostEffectsUtils::SetTexture((CTexture*)CTexture::s_ptexBackBuffer, 6, FILTER_POINT, 0); //contains copy of normals buffer - - // Need to set the depth texture if is not available as a RT - const bool needDepthTexture = !rd->FX_GetEnabledGmemPath(nullptr) || rd->FX_GmemGetDepthStencilMode() == CD3D9Renderer::eGDSM_Texture; - if (needDepthTexture) - { - m_pDepthRT->Apply(0, m_nTexStatePoint); - } - - // __________________________________________________________________________________________ - // Stencil - - rd->m_RP.m_PersFlags2 |= RBPF2_READMASK_RESERVED_STENCIL_BIT; - - //apply stencil dynamic masking - rd->FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_EQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - BIT_STENCIL_RESERVED, BIT_STENCIL_RESERVED, 0xFFFFFFFF - ); - - rd->m_RP.m_PersFlags2 &= ~RBPF2_READMASK_RESERVED_STENCIL_BIT; - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(true, false); - } - - // __________________________________________________________________________________________ - // Shader technique - - if (rDecal.fGrowAlphaRef > 0.0f) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredDecalsDebug == 1) - { - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; // disable alpha grow feature - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; // debug output - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE3]; // disable normals - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - - if (bUseLightVolumes) - { - //enable light volumes rendering - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - static CCryNameTSCRC techName("DeferredDecalVolume"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pDeferredDecalTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - // __________________________________________________________________________________________ - // Shader Params - - // Texture transforms - m_pShader->FXSetPSFloat(m_pParamTexTransforms, m_vTextureTransforms[0], 2 * EMaxTextureSlots); - - // decal normal map to world transform - Matrix44A mDecalTS = CalculateTSMatrix(vBasisX, vBasisY, vBasisZ); - m_pShader->FXSetPSFloat(m_pParamDecalTS, (Vec4*)mDecalTS.GetData(), 4); - - // transform world coords to decal texture coords - Matrix44A mDecalLightProj = GetDecalLightProjMatrix(rDecal); - m_pShader->FXSetPSFloat(m_pParamLightProjMatrix, (Vec4*)mDecalLightProj.GetData(), 4); - - // Diffuse - Vec4 vDiff = sItem.m_pShaderResources->GetColorValue(EFTT_DIFFUSE).toVec4(); - vDiff.w = sItem.m_pShaderResources->GetStrengthValue(EFTT_OPACITY) * rDecal.fAlpha; - m_pShader->FXSetPSFloat(m_pParamDecalDiffuse, &vDiff, 1); - - // Angle Attenuation - Vec4 angleAttenuation = Vec4(rDecal.angleAttenuation,0,0,0); - m_pShader->FXSetPSFloat(m_pParamDecalAngleAttenuation, &angleAttenuation, 1); - - // Specular - Vec4 vSpec = sItem.m_pShaderResources->GetColorValue(EFTT_SPECULAR).toVec4(); - vSpec.w = sItem.m_pShaderResources->GetStrengthValue(EFTT_SMOOTHNESS); - m_pShader->FXSetPSFloat(m_pParamDecalSpecular, &vSpec, 1); - - // Dynamic params - float decalAlphaMult, decalFalloff, decalDiffuseOpacity, emittanceMapGamma; - auto& shaderParams = sItem.m_pShaderResources->GetParameters(); - GetDynamicDecalParams(shaderParams, decalAlphaMult, decalFalloff, decalDiffuseOpacity, emittanceMapGamma); - - float fGrowAlphaRef = rDecal.fGrowAlphaRef; - - // Debug shader params - if (pDiffuseTex && CRenderer::CV_r_deferredDecalsDebug == 1) - { - indDecal = pDiffuseTex->GetTextureID() % 3; - - decalAlphaMult = indDecal == 0 ? 1.0f : 0.0; - decalFalloff = indDecal == 1 ? 1.0f : 0.0; - decalDiffuseOpacity = indDecal == 2 ? 1.0f : 0.0; - fGrowAlphaRef = 0.94f; // Crytek magic value - } - - Vec4 decalParams(decalAlphaMult, decalFalloff, decalDiffuseOpacity, rDecal.fGrowAlphaRef); - m_pShader->FXSetPSFloat(m_pGeneralParams, &decalParams, 1); - - - // __________________________________________________________________________________________ - // State - - int nStates = m_nRenderState; - - int disableFlags = GS_BLEND_MASK | GS_COLMASK_NONE | GS_NODEPTHTEST | GS_DEPTHFUNC_MASK; - int enableFlags = GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_DEPTHFUNC_LEQUAL | GS_COLMASK_RGB | GS_STENCIL; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredDecalsDebug == 2) - { - enableFlags |= GS_DEPTHWRITE | GS_WIREFRAME; - } - - nStates &= ~disableFlags; - nStates |= enableFlags; - - // __________________________________________________________________________________________ - // Culling - - ECull volumeCull = eCULL_Back; - - rd->EF_Scissor(false, 0, 0, 1, 1); - - const float r = fabs(vBasisX.dot(m_pCamFront)) + fabs(vBasisY.dot(m_pCamFront)) + fabs(vBasisZ.dot(m_pCamFront)); - const float s = m_pCamFront.dot(rDecal.projMatrix.GetTranslation() - m_pCamPos); - if (fabs(s) - m_fCamNear <= r) // OBB-Plane via separating axis test, to check if camera near plane intersects decal volume - { - nStates &= ~(GS_NODEPTHTEST | GS_DEPTHFUNC_MASK); - nStates |= GS_DEPTHFUNC_GREAT; - volumeCull = eCULL_Front; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredDecalsDebug == 2) - { - volumeCull = eCULL_Back; - } - - // __________________________________________________________________________________________ - // Render - - rd->FX_SetState(nStates); - - if (bUseLightVolumes) - { - DrawDecalVolume(rDecal, mDecalLightProj, volumeCull); - } - else - { - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_nCurTargetWidth, m_nCurTargetHeight); - } - - SD3DPostEffectsUtils::ShEndPass(); - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(false); - } - - return true; -} - -// This renders the emissive part of a single deferred decal. -// Only the emissive part of the light is output as the rest of the lighting has been calculated in the deferred resolve. -// Blends using SRC_ONE and DST_ONE -// Called by CD3D9Renderer::FX_DeferredDecalsEmissive -// Uses pixel shader DecalEmissivePassPS in DeferredShading.cfx -void CDeferredShading::DeferredDecalEmissivePass(const SDeferredDecal& rDecal, [[maybe_unused]] uint32 indDecal) -{ - // __________________________________________________________________________________________ - // Early out if no emissive material - - _smart_ptr pDecalMaterial = rDecal.pMaterial; - if (pDecalMaterial == NULL) - { - AZ_WarningOnce("CDeferredShading", pDecalMaterial == NULL, "Decal missing material."); - return; - } - - SShaderItem& sItem = pDecalMaterial->GetShaderItem(0); - if (sItem.m_pShaderResources == NULL) - { - assert(0); - return; - } - - if (!sItem.m_pShaderResources->IsEmissive()) - { - return; - } - - // __________________________________________________________________________________________ - // Begin - - PROFILE_FRAME(CDeferredShading_DecalEmissivePass); - PROFILE_SHADER_SCOPE; - - gcpRendD3D->m_RP.m_FlagsShader_RT &= ~(RT_LIGHTSMASK | g_HWSR_MaskBit[HWSR_SAMPLE4]); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - bool bUseLightVolumes = true; - - rd->EF_Scissor(false, 0, 0, 1, 1); - rd->SetDepthBoundTest(0.0f, 1.0f, false); - - // coord systems conversion (from orientation to shader matrix) - const Vec3 vBasisX = rDecal.projMatrix.GetColumn0(); - const Vec3 vBasisY = rDecal.projMatrix.GetColumn1(); - const Vec3 vBasisZ = rDecal.projMatrix.GetColumn2(); - - // __________________________________________________________________________________________ - // Textures - - CTexture* pCurTarget = CTexture::s_ptexHDRTarget; - m_nCurTargetWidth = pCurTarget->GetWidth(); - m_nCurTargetHeight = pCurTarget->GetHeight(); - - // Particles use the $Detail slot for emittance - EEfResTextures emittanceTextureIdx = EFTT_EMITTANCE; - const char* shaderName = sItem.m_pShader->GetName(); - if (strcmp(shaderName, "Particles") == 0) - emittanceTextureIdx = EFTT_DETAIL_OVERLAY; - - // Each texture will calculate it's own mip level factor - float dummyMipLevelFactor = 0; - const float decalSize = max(vBasisX.GetLength() * 2.0f, vBasisY.GetLength() * 2.0f); - - int setTextureFlags = ESetTexture_HWSR | ESetTexture_AllowDefault | ESetTexture_Transform; - SetTexture(sItem, emittanceTextureIdx, 3, rDecal.rectTexture, decalSize, dummyMipLevelFactor, setTextureFlags); - SetTexture(sItem, EFTT_DECAL_OVERLAY, 4, rDecal.rectTexture, decalSize, dummyMipLevelFactor, setTextureFlags); - SetTexture(sItem, EFTT_OPACITY, 5, rDecal.rectTexture, decalSize, dummyMipLevelFactor, setTextureFlags); - - SD3DPostEffectsUtils::SetTexture((CTexture*)CTexture::s_ptexZTarget, 0, FILTER_POINT, 0); // depth - SD3DPostEffectsUtils::SetTexture((CTexture*)CTexture::s_ptexBackBuffer, 6, FILTER_POINT, 0); // copy of normals - - // Need to set the depth texture if is not available as a RT - const bool needDepthTexture = !rd->FX_GetEnabledGmemPath(nullptr) || rd->FX_GmemGetDepthStencilMode() == CD3D9Renderer::eGDSM_Texture; - if (needDepthTexture) - { - m_pDepthRT->Apply(0, m_nTexStatePoint); - } - - // __________________________________________________________________________________________ - // Shader technique - - if (rDecal.fGrowAlphaRef > 0.0f) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if (bUseLightVolumes) - { - //enable light volumes rendering - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - static CCryNameTSCRC techName("DeferredDecalEmissiveVolume"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - static CCryNameTSCRC techName("DeferredDecalEmissive"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - // __________________________________________________________________________________________ - // Shader Params - - // Dynamic Params - float decalAlphaMult, decalFalloff, decalDiffuseOpacity, emittanceMapGamma; - auto& shaderParams = sItem.m_pShaderResources->GetParameters(); - GetDynamicDecalParams(shaderParams, decalAlphaMult, decalFalloff, decalDiffuseOpacity, emittanceMapGamma); - - Vec4 decalParams(decalAlphaMult, decalFalloff, emittanceMapGamma, rDecal.fGrowAlphaRef); - m_pShader->FXSetPSFloat(m_pGeneralParams, &decalParams, 1); - - // Texture transforms - m_pShader->FXSetPSFloat(m_pParamTexTransforms, m_vTextureTransforms[0], 2 * EMaxTextureSlots); - - // transform world coords to decal texture coords - Matrix44A mDecalLightProj = GetDecalLightProjMatrix(rDecal); - m_pShader->FXSetPSFloat(m_pParamLightProjMatrix, (Vec4*)mDecalLightProj.GetData(), 4); - - // decal normal map to world transform - Matrix44A mDecalTS = CalculateTSMatrix(vBasisX, vBasisY, vBasisZ); - m_pShader->FXSetPSFloat(m_pParamDecalTS, (Vec4*)mDecalTS.GetData(), 4); - - // Emissive color + intensity - Vec4 vEmissive = sItem.m_pShaderResources->GetColorValue(EFTT_EMITTANCE).toVec4(); - vEmissive.w = sItem.m_pShaderResources->GetStrengthValue(EFTT_EMITTANCE); - m_pShader->FXSetPSFloat(m_pParamDecalEmissive, &vEmissive, 1); - - // __________________________________________________________________________________________ - // State - - int nStates = m_nRenderState; - - int disableFlags = GS_NODEPTHTEST | GS_STENCIL | GS_DEPTHFUNC_MASK | GS_BLEND_MASK | GS_COLMASK_NONE; - int enableFlags = GS_DEPTHFUNC_LEQUAL | GS_COLMASK_RGB | GS_BLSRC_ONE | GS_BLDST_ONE; - - nStates &= ~disableFlags; - nStates |= enableFlags; - - // __________________________________________________________________________________________ - // Culling - - ECull volumeCull = eCULL_Back; - - rd->EF_Scissor(false, 0, 0, 1, 1); - - const float r = fabs(vBasisX.dot(m_pCamFront)) + fabs(vBasisY.dot(m_pCamFront)) + fabs(vBasisZ.dot(m_pCamFront)); - const float s = m_pCamFront.dot(rDecal.projMatrix.GetTranslation() - m_pCamPos); - if (fabs(s) - m_fCamNear <= r) // OBB-Plane via separating axis test, to check if camera near plane intersects decal volume - { - nStates &= ~(GS_NODEPTHTEST | GS_DEPTHFUNC_MASK); - nStates |= GS_DEPTHFUNC_GREAT; - volumeCull = eCULL_Front; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredDecalsDebug == 2) - { - volumeCull = eCULL_Back; - } - - // __________________________________________________________________________________________ - // Render - - rd->FX_SetState(nStates); - - if (bUseLightVolumes) - { - DrawDecalVolume(rDecal, mDecalLightProj, volumeCull); - } - else - { - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_nCurTargetWidth, m_nCurTargetHeight); - } - - SD3DPostEffectsUtils::ShEndPass(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::GetLightRenderSettings(const SRenderLight* const __restrict pDL, bool& bStencilMask, bool& bUseLightVolumes, EShapeMeshType& meshType) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - const bool bAreaLight = (pDL->m_Flags & DLF_AREA_LIGHT) && pDL->m_fAreaWidth && pDL->m_fAreaHeight && pDL->m_fLightFrustumAngle; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredshadingLightVolumes) - { - if (bAreaLight) - { - // area lights use non-uniform box volume - // need to do more complex box intersection test - float fExpensionRadius = pDL->m_fRadius * 1.08f; - Vec3 vScale(fExpensionRadius, fExpensionRadius, fExpensionRadius); - - Matrix34 mObjInv = CShadowUtils::GetAreaLightMatrix(pDL, vScale); - mObjInv.Invert(); - - // check if volumes bounding box intersects the near clipping plane - const Plane* pNearPlane(rd->GetCamera().GetFrustumPlane(FR_PLANE_NEAR)); - Vec3 pntOnNearPlane(rd->GetCamera().GetPosition() - pNearPlane->DistFromPlane(rd->GetCamera().GetPosition()) * pNearPlane->n); - Vec3 pntOnNearPlaneOS(mObjInv.TransformPoint(pntOnNearPlane)); - - Vec3 nearPlaneOS_n(mObjInv.TransformVector(pNearPlane->n)); - f32 nearPlaneOS_d(-nearPlaneOS_n.Dot(pntOnNearPlaneOS)); - - // get extreme lengths - float t(fabsf(nearPlaneOS_n.x) + fabsf(nearPlaneOS_n.y) + fabsf(nearPlaneOS_n.z)); - - float t0 = t + nearPlaneOS_d; - float t1 = -t + nearPlaneOS_d; - - if (t0 * t1 > 0.0f) - { - bUseLightVolumes = true; - } - else - { - bStencilMask = true; - } - } - else - { - const float kDLRadius = pDL->m_fRadius; - const float fSmallLightBias = 0.5f; - // the light mesh tessellation and near clipping plane require some bias when testing if inside sphere - // higher bias for low radius lights - float fSqLightRadius = kDLRadius * max(-0.1f * kDLRadius + 1.5f, 1.22f); - fSqLightRadius = max(kDLRadius + fSmallLightBias, fSqLightRadius); //always add on a minimum bias, for very small light's sake - fSqLightRadius *= fSqLightRadius; - if (fSqLightRadius < pDL->m_Origin.GetSquaredDistance(m_pCamPos)) - { - bUseLightVolumes = true; - } - else - { - bStencilMask = true; - } - } - } - - Vec4 pLightRect = Vec4(pDL->m_sX, pDL->m_sY, pDL->m_sWidth, pDL->m_sHeight); - Vec4 scaledLightRect = pLightRect * Vec4( - rRP.m_CurDownscaleFactor.x, rRP.m_CurDownscaleFactor.y, - rRP.m_CurDownscaleFactor.x, rRP.m_CurDownscaleFactor.y - ); - - float fCurTargetWidth = (float)(m_nCurTargetWidth); - float fCurTargetHeight = (float)(m_nCurTargetHeight); - - if (!iszero(CRenderer::CV_r_DeferredShadingLightLodRatio)) - { - if (CRenderer::CV_r_DeferredShadingLightStencilRatio > 0.01f) - { - const float fLightLodRatioScale = CRenderer::CV_r_DeferredShadingLightLodRatio; - float fLightArea = pLightRect.z * pLightRect.w; - float fScreenArea = fCurTargetHeight * fCurTargetWidth; - float fLightRatio = fLightLodRatioScale * (fLightArea / fScreenArea); - - const float fDrawVolumeThres = 0.005f; - if (fLightRatio < fDrawVolumeThres) - { - bUseLightVolumes = false; - } - - if (fLightRatio > 4 * CRenderer::CV_r_DeferredShadingLightStencilRatio) - { - meshType = SHAPE_PROJECTOR2; - } - else - if (fLightRatio > 2 * CRenderer::CV_r_DeferredShadingLightStencilRatio) - { - meshType = SHAPE_PROJECTOR1; - } - } - else - { - const float fLightLodRatioScale = CRenderer::CV_r_DeferredShadingLightLodRatio; - float fLightArea = pLightRect.z * pLightRect.w; - float fScreenArea = fCurTargetHeight * fCurTargetWidth; - float fLightRatio = fLightLodRatioScale * (fLightArea / fScreenArea); - - const float fDrawVolumeThres = 0.005f; - if (fLightRatio < fDrawVolumeThres) - { - bUseLightVolumes = false; - } - } - } -} - -void CDeferredShading::LightPass(const SRenderLight* const __restrict pDL, bool bForceStencilDisable /*= false*/) -{ - PROFILE_FRAME(CDeferredShading_LightPass); - PROFILE_SHADER_SCOPE; - - PROFILE_LABEL(pDL->m_sName); - - PrefetchLine(&pDL->m_Color, 0); - PrefetchLine(&pDL->m_sWidth, 0); - - // Skip non-ambient area light if support is disabled - if ((pDL->m_Flags & DLF_AREA_LIGHT) && !(pDL->m_Flags & DLF_AMBIENT) && !CRenderer::CV_r_DeferredShadingAreaLights) - { - return; - } - - gcpRendD3D->m_RP.m_FlagsShader_RT &= ~(RT_LIGHTPASS_RESETMASK | RT_CLIPVOLUME_ID); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - CD3D9Renderer::EGmemPath gmemPath = gcpRendD3D->FX_GetEnabledGmemPath(nullptr); - bool castShadowMaps = (pDL->m_Flags & DLF_CASTSHADOW_MAPS) != 0; - bool isGmemEnabled = gmemPath != CD3D9Renderer::eGT_REGULAR_PATH; - const ITexture* pLightTex = pDL->m_pLightImage ? pDL->m_pLightImage : NULL; - const bool bProj2D = (pDL->m_Flags & DLF_PROJECT) && pLightTex && !(pLightTex->GetFlags() & FT_REPLICATE_TO_ALL_SIDES); - const bool bAreaLight = (pDL->m_Flags & DLF_AREA_LIGHT) && pDL->m_fAreaWidth && pDL->m_fAreaHeight && pDL->m_fLightFrustumAngle; - - // Store light properties (color/radius, position relative to camera, rect, zbounds) - Vec4 pLightDiffuse = Vec4(pDL->m_Color.r, pDL->m_Color.g, pDL->m_Color.b, pDL->m_SpecMult); - - float fInvRadius = (pDL->m_fRadius <= 0) ? 1.0f : 1.0f / pDL->m_fRadius; - Vec4 pLightPosCS = Vec4(pDL->m_Origin - m_pCamPos, fInvRadius); - Vec4 pDepthBounds = GetLightDepthBounds(pDL, (rRP.m_TI[rRP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0); - - Vec4 scaledLightRect = Vec4( - pDL->m_sX * rRP.m_CurDownscaleFactor.x, - pDL->m_sY * rRP.m_CurDownscaleFactor.y, - pDL->m_sWidth * rRP.m_CurDownscaleFactor.x, - pDL->m_sHeight * rRP.m_CurDownscaleFactor.y - ); - - bool bUseLightVolumes = false; - bool bStencilMask = (CRenderer::CV_r_DeferredShadingStencilPrepass && (bProj2D || bAreaLight)) || CRenderer::CV_r_DebugLightVolumes || (pDL->m_fProjectorNearPlane < 0); - rRP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - GetLightRenderSettings(pDL, bStencilMask, bUseLightVolumes, rRP.m_nDeferredPrimitiveID); - - //reset stencil mask - if (bForceStencilDisable) - { - bStencilMask = false; - } - - if (pDL->m_Flags & DLF_AMBIENT) - { - rRP.m_FlagsShader_RT |= RT_AMBIENT_LIGHT; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingAreaLights) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE3]; - } - - float fAttenuationBulbSize = pDL->m_fAttenuationBulbSize; - - if (bAreaLight) - { - fAttenuationBulbSize = (pDL->m_fAreaWidth + pDL->m_fAreaHeight) * 0.25; - } - - // Adjust light intensity so that the intended brightness is reached 1 meter from the light's surface - if (!(pDL->m_Flags & DLF_AMBIENT)) - { - fAttenuationBulbSize = max(fAttenuationBulbSize, 0.001f); - - // Solve I * 1 / (1 + d/lightsize)^2 = 1 - float intensityMul = 1.0f + 1.0f / fAttenuationBulbSize; - intensityMul *= intensityMul; - pLightDiffuse.x *= intensityMul; - pLightDiffuse.y *= intensityMul; - pLightDiffuse.z *= intensityMul; - } - - // Enable light pass flags - if ((pDL->m_Flags & DLF_PROJECT)) - { - assert(!(pDL->GetDiffuseCubemap() && pDL->GetSpecularCubemap())); - rRP.m_FlagsShader_RT |= RT_TEX_PROJECT; - if (bProj2D && !bAreaLight) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ]; - } - } - - if (bAreaLight) - { - rRP.m_FlagsShader_RT |= RT_AREALIGHT; - } - - uint16 scaledX = (uint16)(scaledLightRect.x); - uint16 scaledY = (uint16)(scaledLightRect.y); - uint16 scaledWidth = (uint16)(scaledLightRect.z) + 1; - uint16 scaledHeight = (uint16)(scaledLightRect.w) + 1; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - SetupScissors(true, scaledX, scaledY, scaledWidth, scaledHeight); - } - - if (bStencilMask) - { - PROFILE_LABEL_SCOPE("STENCIL_VOLUME"); - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(false); -#endif - - rd->SetDepthBoundTest(0.0f, 1.0f, false); // stencil pre-passes are rop bound, using depth bounds increases even more rop cost - rd->FX_StencilFrustumCull(castShadowMaps ? -4 : -1, pDL, NULL, 0); - } - else - if (rd->m_bDeviceSupports_NVDBT && CRenderer::CV_r_DeferredShadingDepthBoundsTest == 1) - { - rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z, true); - } - - // todo: try out on consoles if DBT helps on light pass (on light stencil prepass is actually slower) - if (rd->m_bDeviceSupports_NVDBT && bStencilMask && CRenderer::CV_r_DeferredShadingDepthBoundsTest && CRenderer::CV_r_deferredshadingDBTstencil) - { - rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z, true); - } - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - if (bStencilMask) - { - SpecularAccEnableMRT(true); - } -#endif - - uint nNumClipVolumes = m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel]; - if (nNumClipVolumes > 0) - { - rRP.m_FlagsShader_RT |= RT_CLIPVOLUME_ID; - } - - // Directional occlusion - if (CRenderer::CV_r_ssdo) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_SSDO]; - } - - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - - if (CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - uint64 currentSample2MaskBit = rRP.m_FlagsShader_RT & g_HWSR_MaskBit[HWSR_SAMPLE2]; - if (isGmemEnabled) - { - // Signal the shader if we support independent blending - if (RenderCapabilities::SupportsIndependentBlending()) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - else - { - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - } - - if (bUseLightVolumes) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pLightVolumeTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - int nStates = m_nRenderState; - nStates &= ~(GS_BLEND_MASK); - - nStates &= ~(GS_NODEPTHTEST | GS_DEPTHFUNC_MASK); // Ensure zcull used. - nStates |= GS_DEPTHFUNC_LEQUAL; - - // For PLS we do programmable blending in the fragment shader since we need to write to the PLS struct - if (!(isGmemEnabled && RenderCapabilities::SupportsPLSExtension())) - { - if (!(pDL->m_Flags & DLF_AMBIENT)) - { - nStates |= (GS_BLSRC_ONE | GS_BLDST_ONE); - } - else - { - nStates |= (GS_BLSRC_DSTCOL | GS_BLDST_ZERO); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDebug == 2) - { - nStates &= ~GS_BLEND_MASK; - nStates |= (GS_BLSRC_ONE | GS_BLDST_ONE); - } - } - - rd->FX_SetState(nStates); - - SStateBlend currentBlendState = gcpRendD3D->m_StatesBL[gcpRendD3D->m_nCurStateBL]; - if (CD3D9Renderer::eGT_256bpp_PATH == gmemPath && RenderCapabilities::SupportsIndependentBlending()) - { - // For GMEM 256 we have 6 RTs so we need to disable blending and writing for all the non lighting RTs - SStateBlend newBlendState = currentBlendState; - newBlendState.Desc.IndependentBlendEnable = TRUE; - for (int i = 0; i < AZ_ARRAY_SIZE(newBlendState.Desc.RenderTarget); ++i) - { - newBlendState.Desc.RenderTarget[i].BlendEnable = FALSE; - newBlendState.Desc.RenderTarget[i].RenderTargetWriteMask = 0; - } - - // Enable blending for specular and diffuse light buffers - // Copy all state info from slot 0 since the engine only update that slot when calling FX_State. - newBlendState.Desc.RenderTarget[CD3D9Renderer::s_gmemRendertargetSlots[gmemPath][CD3D9Renderer::eGT_SpecularLight]] = currentBlendState.Desc.RenderTarget[0]; - newBlendState.Desc.RenderTarget[CD3D9Renderer::s_gmemRendertargetSlots[gmemPath][CD3D9Renderer::eGT_DiffuseLight]] = currentBlendState.Desc.RenderTarget[0]; - gcpRendD3D->SetBlendState(&newBlendState); - } - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(true, false); - } - - - if ((pDL->m_Flags & DLF_PROJECT)) - { - Matrix44A ProjMatrixT; - - if (bProj2D) - { - CShadowUtils::GetProjectiveTexGen(pDL, 0, &ProjMatrixT); - } - else - { - ProjMatrixT = pDL->m_ProjMatrix; - } - - // translate into camera space - ProjMatrixT.Transpose(); - const Vec4 vEye(gRenDev->GetViewParameters().vOrigin, 0.f); - Vec4 vecTranslation(vEye.Dot((Vec4&)ProjMatrixT.m00), vEye.Dot((Vec4&)ProjMatrixT.m10), vEye.Dot((Vec4&)ProjMatrixT.m20), vEye.Dot((Vec4&)ProjMatrixT.m30)); - ProjMatrixT.m03 += vecTranslation.x; - ProjMatrixT.m13 += vecTranslation.y; - ProjMatrixT.m23 += vecTranslation.z; - ProjMatrixT.m33 += vecTranslation.w; - m_pShader->FXSetPSFloat(m_pParamLightProjMatrix, (Vec4*) ProjMatrixT.GetData(), 4); - } - - { - Vec2 vLightSize = Vec2(pDL->m_fAreaWidth * 0.5f, pDL->m_fAreaHeight * 0.5f); - - float fAreaFov = pDL->m_fLightFrustumAngle * 2.0f; - if (castShadowMaps && bAreaLight) - { - fAreaFov = min(fAreaFov, 135.0f); // Shadow can only cover ~135 degree FOV without looking bad, so we clamp the FOV to hide shadow clipping. - } - const float fCosAngle = cosf(fAreaFov * (gf_PI / 360.0f)); // pre-compute on CPU. - - static CCryNameR arealightMatrixName("g_AreaLightMatrix"); - Matrix44 mAreaLightMatrix; - mAreaLightMatrix.SetRow4(0, Vec4(pDL->m_ObjMatrix.GetColumn0().GetNormalized(), 1.0f)); - mAreaLightMatrix.SetRow4(1, Vec4(pDL->m_ObjMatrix.GetColumn1().GetNormalized(), 1.0f)); - mAreaLightMatrix.SetRow4(2, Vec4(pDL->m_ObjMatrix.GetColumn2().GetNormalized(), 1.0f)); - mAreaLightMatrix.SetRow4(3, Vec4(vLightSize.x, vLightSize.y, 0, fCosAngle)); - m_pShader->FXSetPSFloat(arealightMatrixName, alias_cast(&mAreaLightMatrix), 4); - } - - m_pShader->FXSetPSFloat(m_pParamLightPos, &pLightPosCS, 1); - m_pShader->FXSetPSFloat(m_pParamLightDiffuse, &pLightDiffuse, 1); - - - uint32 stencilID = (pDL->m_nStencilRef[1] + 1) << 16 | pDL->m_nStencilRef[0] + 1; - Vec4 vAttenParams(fAttenuationBulbSize, *alias_cast(&stencilID), 0, 0); - m_pShader->FXSetPSFloat(m_pAttenParams, &vAttenParams, 1); - - // Directional occlusion - const int ssdoTexSlot = 8; - SetSSDOParameters(ssdoTexSlot); - - if (castShadowMaps) - { - static ICVar* pVar = iConsole->GetCVar("e_ShadowsPoolSize"); - int nShadowAtlasRes = pVar->GetIVal(); - - const ShadowMapFrustum& firstFrustum = CShadowUtils::GetFirstFrustum(m_nCurLighID); - //LRad - float kernelSize = firstFrustum.bOmniDirectionalShadow ? 2.5f : 1.5f; - const Vec4 vShadowParams(kernelSize * (float(firstFrustum.nTexSize) / nShadowAtlasRes), 0.0f, 0.0f, firstFrustum.fDepthConstBias); - m_pShader->FXSetPSFloat(m_pGeneralParams, &vShadowParams, 1); - - // set up shadow matrix - static CCryNameR paramName("g_mLightShadowProj"); - Matrix44A shadowMat = gRenDev->m_TempMatrices[0][0]; - const Vec4 vEye(gRenDev->GetViewParameters().vOrigin, 0.f); - Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30)); - shadowMat.m03 += vecTranslation.x; - shadowMat.m13 += vecTranslation.y; - shadowMat.m23 += vecTranslation.z; - shadowMat.m33 += vecTranslation.w; - - // pre-multiply by 1/frustrum_far_plane - (Vec4&)shadowMat.m20 *= gRenDev->m_cEF.m_TempVecs[2].x; - - //camera matrix - m_pShader->FXSetPSFloat(paramName, alias_cast(&shadowMat), 4); - } - - CTexture* pTexLightImage = (CTexture*)pLightTex; - - if (CD3D9Renderer::eGT_256bpp_PATH != gmemPath) - { - // Note: Shadows use slot 3 and slot 7 for shadow map and jitter map -#if defined(ANDROID) - m_pDepthRT->Apply(0, m_nTexStatePoint, EFTT_UNKNOWN, -2, SResourceView::DefaultView); -#else - m_pDepthRT->Apply(0, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); -#endif - m_pNormalsRT->Apply(1, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - m_pDiffuseRT->Apply(2, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - m_pSpecularRT->Apply(4, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - } - - if (!isGmemEnabled) - { - m_pMSAAMaskRT->Apply(9, m_nTexStatePoint); - - if (nNumClipVolumes > 0) - { - m_pResolvedStencilRT->Apply(11, m_nTexStatePoint); - m_pShader->FXSetPSFloat(m_pClipVolumeParams, m_vClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nNumClipVolumes + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - } - } - - if ((pDL->m_Flags & DLF_PROJECT) && pTexLightImage) - { - SD3DPostEffectsUtils::SetTexture(pTexLightImage, 5, FILTER_TRILINEAR, bProj2D ? 1 : 0); - } - - if (isGmemEnabled && nNumClipVolumes > 0) - { - m_pShader->FXSetPSFloat(m_pClipVolumeParams, m_vClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nNumClipVolumes + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - - // Global blend weight - static CCryNameR clipVolGlobalBendWeight("g_fGlobalClipVolumeBlendWeight"); - Vec4 blendWeight(CRenderer::CV_r_GMEMVisAreasBlendWeight, 0, 0, 0); - m_pShader->FXSetPSFloat(clipVolGlobalBendWeight, &blendWeight, 1); - } - - if (bUseLightVolumes) - { - gcpRendD3D->D3DSetCull(eCULL_Back); - - const Vec3 scale(pDL->m_fRadius * 1.08f); - Matrix34 mUnitVolumeToWorld = bAreaLight ? CShadowUtils::GetAreaLightMatrix(pDL, scale) : Matrix34::CreateScale(scale, pDL->m_Origin); - - DrawLightVolume(bAreaLight ? SHAPE_BOX : SHAPE_SPHERE, mUnitVolumeToWorld.GetTransposed()); - } - else - { - gcpRendD3D->D3DSetCull(eCULL_Back, true); //fs quads should not revert test.. - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight(), pDepthBounds.x); - } - - SD3DPostEffectsUtils::ShEndPass(); - - rd->SetDepthBoundTest(0.0f, 1.0f, false); - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(false); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - rd->EF_Scissor(false, 0, 0, 0, 0); - } - - // Restore blend state - if (CD3D9Renderer::eGT_256bpp_PATH == gmemPath) - { - gcpRendD3D->SetBlendState(¤tBlendState); - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE2]; - rRP.m_FlagsShader_RT |= currentSample2MaskBit; - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::RenderClipVolumesToStencil(int nClipAreaReservedStencilBit) -{ - std::vector& pClipVolumes = m_pClipVolumes[m_nThreadID][m_nRecurseLevel]; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const bool bRenderVisAreas = CRenderer::CV_r_VisAreaClipLightsPerPixel > 0; - - for (int nCurrVolume = pClipVolumes.size() - 1; nCurrVolume >= 0; --nCurrVolume) - { - const SClipVolumeData& pVolumeData = pClipVolumes[nCurrVolume]; - if (pVolumeData.m_pRenderMesh && pVolumeData.nStencilRef < MAX_DEFERRED_CLIP_VOLUMES) - { - if ((pVolumeData.nFlags & IClipVolume::eClipVolumeIsVisArea) != 0 && !bRenderVisAreas) - { - continue; - } - - assert(((pVolumeData.nStencilRef + 1) & (BIT_STENCIL_RESERVED | nClipAreaReservedStencilBit)) == 0); - const int nStencilRef = ~(pVolumeData.nStencilRef + 1) & ~(BIT_STENCIL_RESERVED | nClipAreaReservedStencilBit); - - rd->FX_StencilCullNonConvex(nStencilRef, pVolumeData.m_pRenderMesh.get(), pVolumeData.mWorldTM); - } - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::RenderPortalBlendValues(int nClipAreaReservedStencilBit) -{ - std::vector& pClipVolumes = m_pClipVolumes[m_nThreadID][m_nRecurseLevel]; - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - uint nPrevState = rd->m_RP.m_CurState; - ECull ePrevCullMode = rd->m_RP.m_eCull; - - uint nNewState = nPrevState; - nNewState &= ~(GS_COLMASK_NONE | GS_DEPTHWRITE); - nNewState |= GS_NODEPTHTEST | GS_NOCOLMASK_R | GS_NOCOLMASK_B | GS_NOCOLMASK_A; - rd->FX_SetState(nNewState); - - static CCryNameTSCRC TechName0 = "PortalBlendVal"; - SD3DPostEffectsUtils::ShBeginPass(m_pShader, TechName0, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - SD3DPostEffectsUtils::SetTexture(m_pDepthRT, 3, FILTER_POINT); - - for (int nCurrVolume = pClipVolumes.size() - 1; nCurrVolume >= 0; --nCurrVolume) - { - const SClipVolumeData& pClipVolumeData = pClipVolumes[nCurrVolume]; - if (pClipVolumeData.nStencilRef < MAX_DEFERRED_CLIP_VOLUMES && pClipVolumeData.nFlags & IClipVolume::eClipVolumeBlend) - { - const bool bRenderMesh = pClipVolumeData.m_pRenderMesh && CRenderer::CV_r_VisAreaClipLightsPerPixel > 0; - - static CCryNameR blendPlane0Param("BlendPlane0"); - Vec4 plane0ClipSpace = rd->m_ViewProjInverseMatrix * pClipVolumeData.m_BlendData.blendPlanes[0]; - m_pShader->FXSetPSFloat(blendPlane0Param, &plane0ClipSpace, 1); - - static CCryNameR blendPlane1Param("BlendPlane1"); - Vec4 plane1ClipSpace = rd->m_ViewProjInverseMatrix * pClipVolumeData.m_BlendData.blendPlanes[1]; - m_pShader->FXSetPSFloat(blendPlane1Param, &plane1ClipSpace, 1); - - static CCryNameR screenScaleParam("g_ScreenScale"); - Vec4 screenScale = Vec4(1.0f / m_pLBufferDiffuseRT->GetWidth(), 1.0f / m_pLBufferDiffuseRT->GetHeight(), 0, 0); - m_pShader->FXSetPSFloat(screenScaleParam, &screenScale, 1); - - rd->m_nStencilMaskRef = nClipAreaReservedStencilBit + pClipVolumeData.nStencilRef + 1; - rd->FX_StencilTestCurRef(true); - - static CCryNameR paramNameVolumeToWorld("g_mUnitLightVolumeToWorld"); - Matrix44 matIdentity(IDENTITY); - m_pShader->FXSetVSFloat(paramNameVolumeToWorld, (Vec4*) matIdentity.GetData(), 4); - - static CCryNameR paramNameSphereAdjust("g_vLightVolumeSphereAdjust"); - Vec4 vZero(ZERO); - m_pShader->FXSetVSFloat(paramNameSphereAdjust, &vZero, 1); - - if (bRenderMesh) - { - CRenderMesh* pRenderMesh = static_cast(pClipVolumeData.m_pRenderMesh.get()); - pRenderMesh->CheckUpdate(0); - - const buffer_handle_t hVertexStream = pRenderMesh->GetVBStream(VSF_GENERAL); - const buffer_handle_t hIndexStream = pRenderMesh->GetIBStream(); - - if (hVertexStream != ~0u && hIndexStream != ~0u) - { - size_t nOffsI = 0; - size_t nOffsV = 0; - - D3DBuffer* pVB = gRenDev->m_DevBufMan.GetD3D(hVertexStream, &nOffsV); - D3DBuffer* pIB = gRenDev->m_DevBufMan.GetD3D(hIndexStream, &nOffsI); - - rd->FX_SetVStream(0, pVB, nOffsV, pRenderMesh->GetStreamStride(VSF_GENERAL)); - rd->FX_SetIStream(pIB, nOffsI, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - if (!FAILED(rd->FX_SetVertexDeclaration(0, pRenderMesh->_GetVertexFormat()))) - { - static CCryNameR viewProjParam("g_mViewProj"); - m_pShader->FXSetVSFloat(viewProjParam, (Vec4*) rd->m_ViewProjMatrix.GetData(), 4); - - rd->D3DSetCull(eCULL_Front); - rd->FX_Commit(); - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pRenderMesh->GetNumVerts(), 0, pRenderMesh->GetNumInds()); - } - } - } - else - { - Matrix44 matQuadToClip(IDENTITY); - matQuadToClip.m00 = 2; - matQuadToClip.m30 = -1; - matQuadToClip.m11 = -2; - matQuadToClip.m31 = 1; - - static CCryNameR viewProjParam("g_mViewProj"); - m_pShader->FXSetVSFloat(viewProjParam, (Vec4*) matQuadToClip.GetData(), 4); - - rd->D3DSetCull(eCULL_Back); - rd->FX_Commit(); - SD3DPostEffectsUtils::DrawFullScreenTri(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight()); - } - } - } - - SD3DPostEffectsUtils::ShEndPass(); - - rd->D3DSetCull(ePrevCullMode); - rd->FX_SetState(nPrevState); -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::PrepareClipVolumeData(bool& bOutdoorVisible) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const bool bMSAA = false; - const bool isGmemEnabled = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - const CD3D9Renderer::EGmemDepthStencilMode gmemStencilMode = gcpRendD3D->FX_GmemGetDepthStencilMode(); - - // Reserved outdoor fragments - std::vector& pClipVolumes = m_pClipVolumes[m_nThreadID][m_nRecurseLevel]; - for (uint i = 0; i < VIS_AREAS_OUTDOOR_STENCIL_OFFSET; ++i) - { - uint32 nFlags = IClipVolume::eClipVolumeConnectedToOutdoor | IClipVolume::eClipVolumeAffectedBySun; - m_vClipVolumeParams[i] = Vec4(0, 0, 0, *alias_cast(&nFlags)); - } - - for (uint i = 0; i < pClipVolumes.size(); ++i) - { - const SClipVolumeData& pClipVolumeData = pClipVolumes[i]; - if (pClipVolumeData.nStencilRef + 1 < MAX_DEFERRED_CLIP_VOLUMES) - { - uint32 nData = (pClipVolumeData.m_BlendData.nBlendIDs[1] + 1) << 24 | (pClipVolumeData.m_BlendData.nBlendIDs[0] + 1) << 16 | pClipVolumeData.nFlags; - m_vClipVolumeParams[pClipVolumeData.nStencilRef + 1] = Vec4(0, 0, 0, *alias_cast(&nData)); - - bOutdoorVisible |= pClipVolumeData.nFlags & IClipVolume::eClipVolumeConnectedToOutdoor ? true : false; - } - } - - - if (CRenderer::CV_r_VolumetricFog != 0) - { - if (isGmemEnabled) - { - CRY_ASSERT(0); // TODO: implement volumetric fog to work with GMEM - } - rd->GetVolumetricFog().ClearVolumeStencil(); - } - - const int nClipVolumeReservedStencilBit = BIT_STENCIL_INSIDE_CLIPVOLUME; - - // Render Clip areas to stencil - if (!pClipVolumes.empty()) - { - rd->FX_ResetPipe(); - - const uint32 nPersFlags2 = rd->m_RP.m_PersFlags2; - rd->m_RP.m_PersFlags2 |= RBPF2_WRITEMASK_RESERVED_STENCIL_BIT; - - //ClipVolumes - { - PROFILE_LABEL_SCOPE("CLIPVOLUMES TO STENCIL"); - if (!isGmemEnabled) - { - if (!RenderCapabilities::SupportsStencilTextures()) - { - // Because there's no support for stencil textures we can't resolve the stencil to a texture. - // So we draw the ClipVolumes directly to the texture in the "resolve" during the PS. - rd->FX_PushRenderTarget(0, m_pResolvedStencilRT, &rd->m_DepthBufferOrigMSAA); - const ColorF clearColor((1.0f / 255.0f), 0.0f, 0.0f, 0.0f); - rd->EF_ClearTargetsImmediately(FRT_CLEAR_COLOR, clearColor); - } - else - { - rd->FX_PushRenderTarget(0, (CTexture*)NULL, &rd->m_DepthBufferOrigMSAA); - } - - rd->RT_SetViewport(0, 0, m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight()); - } - RenderClipVolumesToStencil(nClipVolumeReservedStencilBit); - if (!isGmemEnabled) - { - rd->FX_PopRenderTarget(0); - } - } - - // Portals blending and volumetric fog are not supported in GMEM path. - // Use "r_GMEMVisAreasBlendWeight" for global blending between portals. - if (!isGmemEnabled) - { - // Portal blend factors - static ICVar* pPortalsBlendCVar = iConsole->GetCVar("e_PortalsBlend"); - if (pPortalsBlendCVar->GetIVal() > 0) - { - rd->FX_PushRenderTarget(0, m_pResolvedStencilRT, &rd->m_DepthBufferOrigMSAA); - rd->RT_SetViewport(0, 0, m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight()); - RenderPortalBlendValues(nClipVolumeReservedStencilBit); - rd->FX_PopRenderTarget(0); - } - - if (CRenderer::CV_r_VolumetricFog != 0) - { - rd->GetVolumetricFog().RenderClipVolumeToVolumeStencil(nClipVolumeReservedStencilBit); - } - } - - rd->m_RP.m_PersFlags2 = nPersFlags2; - } - - rd->m_nStencilMaskRef = nClipVolumeReservedStencilBit + m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel] + 1; - - if (isGmemEnabled) - { - switch (gmemStencilMode) - { - case CD3D9Renderer::eGDSM_RenderTarget: - { - if (!RenderCapabilities::SupportsPLSExtension()) - { - PROFILE_LABEL_SCOPE("RESOLVE STENCIL"); - static CCryNameTSCRC pszResolveStencil("ResolveStencil"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shDeferredShading, pszResolveStencil, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - gcpRendD3D->FX_SetState(GS_NODEPTHTEST | GS_NOCOLMASK_R | GS_NOCOLMASK_B | GS_NOCOLMASK_A); - GetUtils().DrawQuadFS(CShaderMan::s_shDeferredShading, false, CTexture::s_ptexGmemStenLinDepth->GetWidth(), CTexture::s_ptexGmemStenLinDepth->GetHeight()); - GetUtils().ShEndPass(); - } - return; - } - case CD3D9Renderer::eGDSM_DepthStencilBuffer: - // We resolve the stencil during the depth linearization - return; - default: - // Stencil is resolved using the non gmem path. - break; - } - } - - // Need to resolve stencil because light volumes and shadow mask overwrite stencil - // If there's no support for stencil textures, then we already clipped the stencil volumes straight - // to the resolved target during the 'CLIPVOLUMES TO STENCIL' pass. - if (RenderCapabilities::SupportsStencilTextures()) - { - PROFILE_LABEL_SCOPE("RESOLVE STENCIL"); -#if defined(CRY_USE_METAL) || defined(ANDROID) - bool renderTargetWasPopped = SpecularAccEnableMRT(false); -#endif - rd->FX_PushRenderTarget(0, m_pResolvedStencilRT, NULL, -1, false, 1); - - const bool isGmemResolve = isGmemEnabled && gmemStencilMode == CD3D9Renderer::eGDSM_Texture; - // Metal Load/Store Actions - rd->FX_SetColorDontCareActions(0, isGmemResolve ? false : true, false); // For GMEM we need to preserve the Red channel because it contains the linearized depth. - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - rd->FX_SetColorDontCareActions(1, true, false); - rd->FX_SetDepthDontCareActions(1, true, true); - rd->FX_SetStencilDontCareActions(1, true, true); - - // color mask - static CCryNameTSCRC pszResolveStencil("ResolveStencil"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shDeferredShading, pszResolveStencil, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - int states = GS_NODEPTHTEST | GS_NOCOLMASK_B | GS_NOCOLMASK_A; - - // For Gmem we write into the green channel. - states |= isGmemResolve ? GS_NOCOLMASK_R : GS_NOCOLMASK_G; - rd->FX_SetState(states); - - CTexture::SetSamplerState(4, m_nTexStatePoint, eHWSC_Pixel); - rd->m_DevMan.BindSRV(eHWSC_Pixel, gcpRendD3D->m_pZBufferStencilReadOnlySRV, 4); - - GetUtils().DrawQuadFS(CShaderMan::s_shDeferredShading, false, m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight()); - GetUtils().ShEndPass(); - rd->FX_PopRenderTarget(0); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - // Do not try to re-push a render target if one was not popped above. - if (renderTargetWasPopped) - { - SpecularAccEnableMRT(true); - } -#endif - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CDeferredShading::AmbientPass(SRenderLight* pGlobalCubemap, bool& bOutdoorVisible) -{ - PROFILE_SHADER_SCOPE; - PROFILE_FRAME(CDeferredShading_AmbientPass); - PROFILE_LABEL_SCOPE("AMBIENT_PASS"); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - rd->m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - rd->D3DSetCull(eCULL_Back, true); //fs quads should not revert test.. - - const bool bMSAA = gcpRendD3D->m_RP.m_MSAAData.Type ? true : false; - - const uint64 nFlagsShaderRT = rRP.m_FlagsShader_RT; - rRP.m_FlagsShader_RT &= ~(RT_LIGHTSMASK); - - SpecularAccEnableMRT(false); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, false); // Disable depth bounds for ambient lookup. - } - const uint32 nNumClipVolumes = m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel]; - if (nNumClipVolumes) - { - rRP.m_FlagsShader_RT |= RT_CLIPVOLUME_ID; - } - else - { - bOutdoorVisible = true; - } - - // Store global cubemap color - Vec4 pLightDiffuse; - if (pGlobalCubemap) - { - pLightDiffuse = Vec4(Vec3(pGlobalCubemap->m_Color.r, pGlobalCubemap->m_Color.g, pGlobalCubemap->m_Color.b), pGlobalCubemap->m_SpecMult); - - const float fLuminance = pGlobalCubemap->m_Color.Luminance(); - if (fLuminance > 0.001f) // too dull => skip - { - rRP.m_FlagsShader_RT |= RT_GLOBAL_CUBEMAP; - // ignore specular if it's too dull - if (fLuminance * pLightDiffuse.w >= 0.005f) - { - rRP.m_FlagsShader_RT |= RT_SPECULAR_CUBEMAP; - } - - rRP.m_FlagsShader_RT |= (pGlobalCubemap->m_Flags & DLF_IGNORES_VISAREAS) ? RT_GLOBAL_CUBEMAP_IGNORE_VISAREAS : 0; - } - else - { - pGlobalCubemap = NULL; - } - } - - // Patch z-target for all platforms, we need stencil access. - CTexture* pDepthBufferRT = m_pDepthRT; - ID3D11DepthStencilView* pZBufferOrigDSV = (ID3D11DepthStencilView*) rd->m_DepthBufferOrigMSAA.pSurf; // Override depthstencil shader/depthstencil views - rd->m_DepthBufferOrigMSAA.pSurf = rd->m_pZBufferReadOnlyDSV; - ID3D11ShaderResourceView* pZTargetOrigSRV = (ID3D11ShaderResourceView*) pDepthBufferRT->GetShaderResourceView(bMSAA ? SResourceView::DefaultViewMS : SResourceView::DefaultView); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - rd->FX_PushRenderTarget(0, m_pLBufferDiffuseRT, &rd->m_DepthBufferOrigMSAA, -1, false, 1); - - SpecularAccEnableMRT(true); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - // Though the ambient pass doesn't explicitly need to use MTLLoadActionLoad for the color buffer, - // the following passes after Ambient do use rasterization blending. Only one draw call usually - // occurs for Ambient pass and many more for the following passes... hence, just set the load/store actions - // only once here. - rd->FX_SetDepthDontCareActions(0, false, true); - rd->FX_SetDepthDontCareActions(1, false, true); - - // The following can only be set if r_DeferredShadingLightVolumes==0 && r_DeferredShadingStencilPrepass == 0, otherwise stencil might need to be written to during light pass. - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_deferredshadingLightVolumes && - !CRenderer::CV_r_DeferredShadingStencilPrepass) - { - rd->FX_SetStencilDontCareActions(0, false, true); - rd->FX_SetStencilDontCareActions(1, false, true); - } - // CONFETTI END - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, true); // Enable depth bounds - discard sky - } - Vec3 vE3DParam; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_AMBIENT_GROUND_COLOR, vE3DParam); - - const Vec4 cAmbGroundColor = Vec4(vE3DParam, 0); - - Vec4 cAmbHeightParams = Vec4(gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_AMBIENT_MIN_HEIGHT), gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_AMBIENT_MAX_HEIGHT), 0, 0); - cAmbHeightParams.z = 1.0 / max(0.0001f, cAmbHeightParams.y); - - if (pGlobalCubemap && CRenderer::CV_r_ssdo) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_SSDO]; - } - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pAmbientOutdoorTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - rd->FX_SetState(GS_NODEPTHTEST); - - SD3DPostEffectsUtils::ShSetParamPS(m_pParamAmbient, Vec4(0, 0, 0, 0)); - SD3DPostEffectsUtils::ShSetParamPS(m_pParamAmbientGround, cAmbGroundColor); - SD3DPostEffectsUtils::ShSetParamPS(m_pParamAmbientHeight, cAmbHeightParams); - - if (nNumClipVolumes) - { - m_pShader->FXSetPSFloat(m_pClipVolumeParams, m_vClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nNumClipVolumes + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Global blend weight - static CCryNameR clipVolGlobalBendWeight("g_fGlobalClipVolumeBlendWeight"); - Vec4 blendWeight(CRenderer::CV_r_GMEMVisAreasBlendWeight, 0, 0, 0); - m_pShader->FXSetPSFloat(clipVolGlobalBendWeight, &blendWeight, 1); - } - } - - if (pGlobalCubemap) - { - CTexture* const texDiffuse = (CTexture*)pGlobalCubemap->GetDiffuseCubemap(); - CTexture* const texSpecular = (CTexture*)pGlobalCubemap->GetSpecularCubemap(); - CTexture* const texNoTextureCM = CTextureManager::Instance()->GetNoTextureCM(); - - SD3DPostEffectsUtils::SetTexture(texDiffuse->GetTextureType() < eTT_Cube ? texNoTextureCM : texDiffuse, 1, FILTER_BILINEAR, 1, texDiffuse->IsSRGB()); - SD3DPostEffectsUtils::SetTexture(texSpecular->GetTextureType() < eTT_Cube ? texNoTextureCM : texSpecular, 2, FILTER_TRILINEAR, 1, texSpecular->IsSRGB()); - - SD3DPostEffectsUtils::ShSetParamPS(m_pParamLightDiffuse, pLightDiffuse); - const Vec4 vCubemapParams(IntegerLog2((uint32)texSpecular->GetWidthNonVirtual()) - 2, 0, 0, 0); // Use 4x4 mip for lowest gloss values - m_pShader->FXSetPSFloat(m_pGeneralParams, &vCubemapParams, 1); - - // Directional occlusion - const int ssdoTexSlot = 8; - SetSSDOParameters(ssdoTexSlot); - } - - if (CD3D9Renderer::eGT_256bpp_PATH != gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pNormalsRT->Apply(0, m_nTexStatePoint, EFTT_UNKNOWN, -1, m_nBindResourceMsaa); - m_pSpecularRT->Apply(7, m_nTexStatePoint); - m_pDiffuseRT->Apply(11, m_nTexStatePoint); - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - pDepthBufferRT->SetShaderResourceView(rd->m_pZBufferDepthReadOnlySRV, bMSAA); // DX11 requires explicitly bind depth then stencil to have access to both depth and stencil read from shader. Formats also must match -#ifndef ANDROID - pDepthBufferRT->Apply(3, m_nTexStatePoint, EFTT_UNKNOWN, -1, m_nBindResourceMsaa); - pDepthBufferRT->SetShaderResourceView(rd->m_pZBufferStencilReadOnlySRV, bMSAA); - pDepthBufferRT->Apply(4, m_nTexStatePoint, EFTT_UNKNOWN, -1, m_nBindResourceMsaa); -#endif // !ANDROID - - m_pMSAAMaskRT->Apply(5, m_nTexStatePoint); - } - - CTextureManager::Instance()->GetDefaultTexture("EnvironmentBRDF")->Apply(10, m_nTexStateLinear); - - // this is expected by Mali drivers - // this "workaround" was suggested by the Mali team as we were getting incorrect stencil/depth tests behavior due to driver bug - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && (gRenDev->GetFeatures() & RFT_HW_ARM_MALI)) - { - int nPrevState = rRP.m_CurState; - int newState = nPrevState; - - newState &= ~(GS_BLEND_MASK | GS_NODEPTHTEST | GS_DEPTHFUNC_MASK | GS_COLMASK_NONE); - newState |= GS_COLMASK_NONE; - newState |= GS_DEPTHFUNC_GREAT; - newState |= GS_DEPTHWRITE; - rd->FX_SetState(newState); - - rd->FX_PushVP(); - rd->m_NewViewport.nX = 0; - rd->m_NewViewport.nY = 0; - rd->m_NewViewport.nWidth = 1; - rd->m_NewViewport.nHeight = 1; - rd->m_NewViewport.fMinZ = 1.0f; - rd->m_NewViewport.fMaxZ = 1.0f; - rd->m_bViewportDirty = true; - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight(), 0, &gcpRendD3D->m_FullResRect); - - rd->FX_PopVP(); - rd->FX_SetState(nPrevState); - } - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight(), 0, &gcpRendD3D->m_FullResRect); - SD3DPostEffectsUtils::ShEndPass(); - - rd->m_DepthBufferOrigMSAA.pSurf = pZBufferOrigDSV; // Restore DSV/SRV - pDepthBufferRT->SetShaderResourceView(pZTargetOrigSRV, bMSAA); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - rd->FX_PopRenderTarget(0); - } - - CTexture* const pBlack = CTextureManager::Instance()->GetBlackTexture(); - if (pBlack) - { - pBlack->Apply(3, m_nTexStatePoint); - pBlack->Apply(4, m_nTexStatePoint); - } - -#if defined(CRY_USE_METAL) || defined(ANDROID) - // we don't want to swich RT's too often for metal - // We want to keep all light RTs bound regardless of - // specular RT usage. - // This trick re-enables specular RT - SpecularAccEnableMRT(false); - SpecularAccEnableMRT(true); -#endif - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - rd->FX_SetActiveRenderTargets(); - } - - // Follow up with NVidia. Seems driver/pixel quads synchronization? Wrong behavior when reading from native stencil/depth. - // Luckily can clear stencil since vis areas/decals tag not needed from here on - if (CRenderer::CV_r_DeferredShadingAmbientSClear) - { - rd->EF_ClearTargetsImmediately(FRT_CLEAR_STENCIL, Clr_Unused.r, 1); - } - - rRP.m_FlagsShader_RT = nFlagsShaderRT; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DeferredCubemaps(const TArray& rCubemaps, const uint32 nStartIndex /* = 0 */) -{ - if (nStartIndex < rCubemaps.Num() && CRenderer::CV_r_DeferredShadingEnvProbes) - { - // apply deferred cubemaps first - PROFILE_LABEL_SCOPE("DEFERRED_CUBEMAPS"); - - for (uint32 nCurrentCubemap = nStartIndex; nCurrentCubemap < rCubemaps.Num(); ++nCurrentCubemap) - { - const SRenderLight& pDL = rCubemaps[nCurrentCubemap]; - if (pDL.m_Flags & (DLF_FAKE | DLF_VOLUMETRIC_FOG_ONLY)) - { - continue; - } - DeferredCubemapPass(&pDL); - m_nLightsProcessedCount++; - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DeferredCubemapPass(const SRenderLight* const __restrict pDL) -{ - PROFILE_SHADER_SCOPE; - PROFILE_FRAME(CDeferredShading_CubemapPass); - PROFILE_LABEL(pDL->m_sName); - - float scissorInt2Float[] = { (float)(pDL->m_sX), (float)(pDL->m_sY), (float)(pDL->m_sWidth), (float)(pDL->m_sHeight) }; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - rRP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - AZ_PUSH_DISABLE_WARNING(, "-Wconstant-logical-operand") - bool bStencilMask = CRenderer::CV_r_DeferredShadingStencilPrepass || CRenderer::CV_r_DebugLightVolumes; - AZ_POP_DISABLE_WARNING - bool bUseLightVolumes = false; - bool bHasSpecular = false; - - const uint64 nOldFlags = rRP.m_FlagsShader_RT; - - rRP.m_FlagsShader_RT &= ~(RT_CLIPVOLUME_ID | RT_LIGHTSMASK | RT_GLOBAL_CUBEMAP | RT_SPECULAR_CUBEMAP | RT_BOX_PROJECTION); - - uint nNumClipVolumes = m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel]; - rd->m_RP.m_FlagsShader_RT |= (pDL->m_Flags & DLF_BOX_PROJECTED_CM) ? RT_BOX_PROJECTION : 0; - rd->m_RP.m_FlagsShader_RT |= nNumClipVolumes > 0 ? RT_CLIPVOLUME_ID : 0; - - // Store light properties (color/radius, position relative to camera, rect, z bounds) - Vec4 pLightDiffuse = Vec4(pDL->m_Color.r, pDL->m_Color.g, pDL->m_Color.b, pDL->m_SpecMult); - - const float fInvRadius = (pDL->m_fRadius <= 0) ? 1.0f : 1.0f / pDL->m_fRadius; - const Vec4 pLightPosCS = Vec4(pDL->m_Origin - m_pCamPos, fInvRadius); - const float fAttenFalloffMax = max(pDL->GetFalloffMax(), 1e-3f); - - const bool bReverseDepth = (rRP.m_TI[rRP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - Vec4 pDepthBounds = GetLightDepthBounds(pDL, bReverseDepth); - - // avoiding LHS, comment out if we ever use different resolution for light accumulation target - Vec4 pLightRect = Vec4(scissorInt2Float[0], scissorInt2Float[1], scissorInt2Float[2], scissorInt2Float[3]); - Vec4 scaledLightRect = Vec4(pLightRect.x * rRP.m_CurDownscaleFactor.x, pLightRect.y * rRP.m_CurDownscaleFactor.y, - pLightRect.z * rRP.m_CurDownscaleFactor.x, pLightRect.w * rRP.m_CurDownscaleFactor.y); - - assert(!(pDL->m_Flags & DLF_PROJECT)); - - if (CRenderer::CV_r_DeferredShadingLightLodRatio) - { - float fLightArea = pLightRect.z * pLightRect.w; - float fScreenArea = (float) m_nCurTargetWidth * m_nCurTargetHeight; - float fLightRatio = fLightArea / fScreenArea; - - const float fMinScreenAreaRatioThreshold = 0.01f; // 1% of screen by default - - const float fDrawVolumeThres = 0.01f; - if ((fLightRatio* CRenderer::CV_r_DeferredShadingLightLodRatio) < fDrawVolumeThres) - { - //scissor + depthbound test only - bStencilMask = false; - } - } - - uint16 scaledX = (uint16)(scaledLightRect.x); - uint16 scaledY = (uint16)(scaledLightRect.y); - uint16 scaledWidth = (uint16)(scaledLightRect.z) + 1; - uint16 scaledHeight = (uint16)(scaledLightRect.w) + 1; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - SetupScissors(true, scaledX, scaledY, scaledWidth, scaledHeight); - } - - if (bStencilMask) - { -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(false); -#endif - rd->SetDepthBoundTest(0.0f, 1.0f, false); - rd->FX_StencilFrustumCull(-1, pDL, NULL, 0); - } - else - if (rd->m_bDeviceSupports_NVDBT && CRenderer::CV_r_DeferredShadingDepthBoundsTest == 1) - { - rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z, true); - } - - // todo: try out on consoles if DBT helps on light pass (on light stencil prepass is actually slower) - if (rd->m_bDeviceSupports_NVDBT && bStencilMask && CRenderer::CV_r_DeferredShadingDepthBoundsTest && CRenderer::CV_r_deferredshadingDBTstencil) - { - rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z, true); - } - - const float fFadeout = pDL->m_fProbeAttenuation; - const float fLuminance = pDL->m_Color.Luminance() * fFadeout; - - if (fLuminance * pLightDiffuse.w >= 0.03f) // if specular intensity is too low, skip it - { - rRP.m_FlagsShader_RT |= RT_SPECULAR_CUBEMAP; - bHasSpecular = true; - } - - if (CRenderer::CV_r_SlimGBuffer) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(bHasSpecular); -#endif - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_deferredshadingLightVolumes) - { - const Plane* pNearPlane(rd->GetCamera().GetFrustumPlane(FR_PLANE_NEAR)); - Vec3 n = pNearPlane->n; - Vec3 e = pDL->m_ProbeExtents; - Vec3 u0 = pDL->m_ObjMatrix.GetColumn0().GetNormalized(); - Vec3 u1 = pDL->m_ObjMatrix.GetColumn1().GetNormalized(); - Vec3 u2 = pDL->m_ObjMatrix.GetColumn2().GetNormalized(); - - // Check if OBB intersects near plane - float r = e.x * fabs(n.dot(u0)) + e.y * fabs(n.dot(u1)) + e.z * fabs(n.dot(u2)); - float s = pNearPlane->DistFromPlane(pDL->m_Origin); - bUseLightVolumes = fabs(s) > r; - } - - int MultplyState = m_nRenderState; - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // we'll do our own programmable blending in GMEM path - { - MultplyState &= ~GS_BLEND_MASK; - } - else - { - MultplyState &= ~GS_BLEND_MASK; - MultplyState |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDebug == 2) - { - // Debug mode - MultplyState &= ~GS_BLEND_MASK; - MultplyState |= (GS_BLSRC_ONE | GS_BLDST_ONE); - } - } - - if (bStencilMask) - { - MultplyState |= GS_STENCIL; - } - - MultplyState &= ~(GS_NODEPTHTEST | GS_DEPTHFUNC_MASK); // Ensure zcull used. - MultplyState |= GS_DEPTHFUNC_LEQUAL; - - // Directional occlusion - if (CRenderer::CV_r_ssdo) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_SSDO]; - } - - // Render.. - if (bUseLightVolumes) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pCubemapsVolumeTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_CUBEMAP0]; - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pCubemapsTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - rd->FX_SetState(MultplyState); - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(true, false); - } - - m_pShader->FXSetPSFloat(m_pParamLightPos, &pLightPosCS, 1); - m_pShader->FXSetPSFloat(m_pParamLightDiffuse, &pLightDiffuse, 1); - - if (CD3D9Renderer::eGT_256bpp_PATH != gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pDepthRT->Apply(0, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - m_pNormalsRT->Apply(1, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - m_pDiffuseRT->Apply(2, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - m_pSpecularRT->Apply(3, m_nTexStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - } - - static CCryNameR pszProbeOBBParams("g_mProbeOBBParams"); - Vec4 vProbeOBBParams[3]; - vProbeOBBParams[0] = Vec4(pDL->m_ObjMatrix.GetColumn0().GetNormalized(), 1 / pDL->m_ProbeExtents.x); - vProbeOBBParams[1] = Vec4(pDL->m_ObjMatrix.GetColumn1().GetNormalized(), 1 / pDL->m_ProbeExtents.y); - vProbeOBBParams[2] = Vec4(pDL->m_ObjMatrix.GetColumn2().GetNormalized(), 1 / pDL->m_ProbeExtents.z); - m_pShader->FXSetPSFloat(pszProbeOBBParams, vProbeOBBParams, 3); - - if (pDL->m_Flags & DLF_BOX_PROJECTED_CM) - { - static CCryNameR pszBoxProjectionMin("g_vBoxProjectionMin"); - static CCryNameR pszBoxProjectionMax("g_vBoxProjectionMax"); - Vec4 vBoxProjectionMin(-pDL->m_fBoxLength * 0.5f, -pDL->m_fBoxWidth * 0.5f, -pDL->m_fBoxHeight * 0.5f, 0); - Vec4 vBoxProjectionMax(pDL->m_fBoxLength * 0.5f, pDL->m_fBoxWidth * 0.5f, pDL->m_fBoxHeight * 0.5f, 0); - - m_pShader->FXSetPSFloat(pszBoxProjectionMin, &vBoxProjectionMin, 1); - m_pShader->FXSetPSFloat(pszBoxProjectionMax, &vBoxProjectionMax, 1); - } - - CTexture* texDiffuse = (CTexture*)pDL->GetDiffuseCubemap(); - CTexture* texSpecular = (CTexture*)pDL->GetSpecularCubemap(); - - // Use 4x4 mip for lowest gloss values - Vec4 vCubemapParams(IntegerLog2((uint32)texSpecular->GetWidthNonVirtual()) - 2, 0, 0, 0); - m_pShader->FXSetPSFloat(m_pGeneralParams, &vCubemapParams, 1); - SD3DPostEffectsUtils::SetTexture(texDiffuse, 5, FILTER_BILINEAR, 1, texDiffuse->IsSRGB()); - SD3DPostEffectsUtils::SetTexture(texSpecular, 6, FILTER_TRILINEAR, 1, texSpecular->IsSRGB()); - - uint32 stencilID = (pDL->m_nStencilRef[1] + 1) << 16 | pDL->m_nStencilRef[0] + 1; - const Vec4 vAttenParams(fFadeout, *alias_cast(&stencilID), 0, fAttenFalloffMax); - m_pShader->FXSetPSFloat(m_pAttenParams, &vAttenParams, 1); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pMSAAMaskRT->Apply(7, m_nTexStatePoint); - } - - // Directional occlusion - const int ssdoTexSlot = 8; - SetSSDOParameters(ssdoTexSlot); - - if (nNumClipVolumes > 0) - { - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pResolvedStencilRT->Apply(9, m_nTexStatePoint, -1, -1, -1); - } - - m_pShader->FXSetPSFloat(m_pClipVolumeParams, m_vClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nNumClipVolumes + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Global blend weight - static CCryNameR clipVolGlobalBendWeight("g_fGlobalClipVolumeBlendWeight"); - Vec4 blendWeight(CRenderer::CV_r_GMEMVisAreasBlendWeight, 0, 0, 0); - m_pShader->FXSetPSFloat(clipVolGlobalBendWeight, &blendWeight, 1); - } - } - - CTextureManager::Instance()->GetDefaultTexture("EnvironmentBRDF")->Apply(10, m_nTexStateLinear); - - // If the texture is not loaded Metal runtime will assert - if (texDiffuse->IsTextureLoaded() && (!bHasSpecular || texSpecular->IsTextureLoaded())) - { - if (bUseLightVolumes) - { - gcpRendD3D->D3DSetCull(eCULL_Back); - - Matrix33 rotMat(pDL->m_ObjMatrix.GetColumn0().GetNormalized() * pDL->m_ProbeExtents.x, - pDL->m_ObjMatrix.GetColumn1().GetNormalized() * pDL->m_ProbeExtents.y, - pDL->m_ObjMatrix.GetColumn2().GetNormalized() * pDL->m_ProbeExtents.z); - Matrix34 mUnitVolumeToWorld = Matrix34::CreateTranslationMat(pDL->m_Origin) * rotMat * Matrix34::CreateScale(Vec3(2, 2, 2), Vec3(-1, -1, -1)); - - DrawLightVolume(SHAPE_BOX, mUnitVolumeToWorld.GetTransposed()); - } - else - { - rd->D3DSetCull(eCULL_Back, true); - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight(), pDepthBounds.x); - } - } - - SD3DPostEffectsUtils::ShEndPass(); - - if (bStencilMask) - { - rd->FX_StencilTestCurRef(false); - } - else if (rd->m_bDeviceSupports_NVDBT && CRenderer::CV_r_DeferredShadingDepthBoundsTest == 1) - { - rd->SetDepthBoundTest(0.f, 1.f, false); - } - - if (rd->m_bDeviceSupports_NVDBT && bStencilMask && CRenderer::CV_r_DeferredShadingDepthBoundsTest && CRenderer::CV_r_deferredshadingDBTstencil) - { - rd->SetDepthBoundTest(0.f, 1.f, false); - } - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(true); -#endif - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - rd->EF_Scissor(false, 0, 0, 0, 0); - } - - rRP.m_FlagsShader_RT = nOldFlags; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ScreenSpaceReflectionPass() -{ - if (CRenderer::CV_r_GraphicsPipeline & 1) - { - gcpRendD3D->GetGraphicsPipeline().RenderScreenSpaceReflections(); - return; - } - if (!CRenderer::CV_r_SSReflections || !CTexture::s_ptexHDRTarget) // Sketch mode disables HDR rendering - { - return; - } - - // SSR only supported on 128bpp GMEM path - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - assert(CD3D9Renderer::eGT_128bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)); - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const uint32 nPrevPersFlags = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags; - - Matrix44 mViewProj = rd->m_ViewMatrix * rd->m_ProjMatrix; - - if (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - mViewProj = ReverseDepthHelper::Convert(mViewProj); - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_REVERSE_DEPTH; - } - - Matrix44 mViewport(0.5f, 0, 0, 0, - 0, -0.5f, 0, 0, - 0, 0, 1.0f, 0, - 0.5f, 0.5f, 0, 1.0f); - const uint32 numGPUs = rd->GetActiveGPUCount(); - - const int frameID = GetUtils().m_iFrameCounter; - Matrix44 mViewProjPrev = m_prevViewProj[max((frameID - (int)numGPUs) % MAX_GPU_NUM, 0)] * mViewport; - - PROFILE_LABEL_SCOPE("SS_REFLECTIONS"); - - const uint64 shaderFlags = rd->m_RP.m_FlagsShader_RT; - - if(CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - // Get current viewport - int prevVpX, prevVpY, prevVpWidth, prevVpHeight; - gRenDev->GetViewport(&prevVpX, &prevVpY, &prevVpWidth, &prevVpHeight); - - { - PROFILE_LABEL_SCOPE("SSR_RAYTRACE"); - - if (CRenderer::CV_r_SlimGBuffer == 1) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - CTexture* dstTex = CRenderer::CV_r_SSReflHalfRes ? CTexture::s_ptexHDRTargetScaled[0] : CTexture::s_ptexHDRTarget; - - rd->FX_PushRenderTarget(0, dstTex, NULL); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - rd->RT_SetViewport(0, 0, dstTex->GetWidth() * vDownscaleFactor.x + 0.5f, dstTex->GetHeight() * vDownscaleFactor.y + 0.5f); -#else - rd->RT_SetViewport(0, 0, dstTex->GetWidth(), dstTex->GetHeight()); -#endif - - - rd->FX_SetState(GS_NODEPTHTEST); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pReflectionTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - m_pDepthRT->Apply(0, m_nTexStatePoint); - m_pNormalsRT->Apply(1, m_nTexStateLinear); - m_pSpecularRT->Apply(2, m_nTexStateLinear); - CTexture::s_ptexZTargetScaled->Apply(3, m_nTexStatePoint); - SD3DPostEffectsUtils::SetTexture(CTexture::s_ptexHDRTargetPrev, 4, FILTER_LINEAR, TADDR_BORDER); - CTexture::s_ptexHDRMeasuredLuminance[rd->RT_GetCurrGpuID()]->Apply(5, m_nTexStatePoint); // Current luminance - - static CCryNameR param0("g_mViewProj"); - m_pShader->FXSetPSFloat(param0, (Vec4*) mViewProj.GetData(), 4); - - static CCryNameR param1("g_mViewProjPrev"); - m_pShader->FXSetPSFloat(param1, (Vec4*) mViewProjPrev.GetData(), 4); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(dstTex->GetWidth(), dstTex->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - rd->FX_PopRenderTarget(0); - } - - if (!CRenderer::CV_r_SSReflHalfRes) - { -#if defined(CRY_USE_METAL) || defined(ANDROID) - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTarget, CTexture::s_ptexHDRTargetScaled[0], false, false, false, false, SPostEffectsUtils::eDepthDownsample_None, false, &gcpRendD3D->m_HalfResRect); -#else - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTarget, CTexture::s_ptexHDRTargetScaled[0]); -#endif - } - - // Convolve sharp reflections - -#if defined(CRY_USE_METAL) || defined(ANDROID) - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - gRenDev->RT_SetScissor(true, 0, 0, CTexture::s_ptexHDRTargetScaled[1]->GetWidth() * vDownscaleFactor.x + 0.5f, CTexture::s_ptexHDRTargetScaled[1]->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTargetScaled[0], CTexture::s_ptexHDRTargetScaled[1]); - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexHDRTargetScaled[1], 1, 1.0f, 3.0f, false, 0, false, CTexture::s_ptexHDRTargetScaledTempRT[1]); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(true, 0, 0, CTexture::s_ptexHDRTargetScaled[2]->GetWidth() * vDownscaleFactor.x + 0.5f, CTexture::s_ptexHDRTargetScaled[2]->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTargetScaled[1], CTexture::s_ptexHDRTargetScaled[2]); - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexHDRTargetScaled[2], 1, 1.0f, 3.0f, false, 0, false, CTexture::s_ptexHDRTargetScaledTempRT[2]); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(true, 0, 0, CTexture::s_ptexHDRTargetScaled[3]->GetWidth() * vDownscaleFactor.x + 0.5f, CTexture::s_ptexHDRTargetScaled[3]->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTargetScaled[2], CTexture::s_ptexHDRTargetScaled[3]); - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexHDRTargetScaled[3], 1, 1.0f, 3.0f, false, 0, false, CTexture::s_ptexHDRTargetScaledTempRT[3]); - - { - PROFILE_LABEL_SCOPE("SSR_COMPOSE"); - - if (CRenderer::CV_r_SlimGBuffer == 1) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - static CCryNameTSCRC tech("SSReflection_Comp"); - - CTexture* dstTex = CTexture::s_ptexHDRTargetScaledTmp[0]; - dstTex->Unbind(); - - rd->FX_SetState(GS_NODEPTHTEST); - rd->FX_PushRenderTarget(0, dstTex, NULL); - rd->RT_SetViewport(0, 0, dstTex->GetWidth(), dstTex->GetHeight()); - - m_pSpecularRT->Apply(0, m_nTexStateLinear); - CTexture::s_ptexHDRTargetScaled[0]->Apply(1, m_nTexStateLinear); - CTexture::s_ptexHDRTargetScaled[1]->Apply(2, m_nTexStateLinear); - CTexture::s_ptexHDRTargetScaled[2]->Apply(3, m_nTexStateLinear); - CTexture::s_ptexHDRTargetScaled[3]->Apply(4, m_nTexStateLinear); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - gRenDev->RT_SetScissor(true, 0, 0, CTexture::s_ptexHDRTargetScaled[0]->GetWidth() * vDownscaleFactor.x + 0.5f, CTexture::s_ptexHDRTargetScaled[0]->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, tech, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - SD3DPostEffectsUtils::DrawFullScreenTri(dstTex->GetWidth(), dstTex->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(false, 0, 0, 0, 0); -#endif - } - - // Restore the old flags - rd->m_RP.m_FlagsShader_RT = shaderFlags; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags = nPrevPersFlags; - - if (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - uint32 depthState = ReverseDepthHelper::ConvertDepthFunc(rd->m_RP.m_CurState); - rd->FX_SetState(rd->m_RP.m_CurState, rd->m_RP.m_CurAlphaRef, depthState); - } - - rd->RT_SetViewport(prevVpX, prevVpY, prevVpWidth, prevVpHeight); - - // Array used for MGPU support - m_prevViewProj[frameID % MAX_GPU_NUM] = mViewProj; -} - -void CDeferredShading::ApplySSReflections() -{ - if (!CRenderer::CV_r_SSReflections || !CTexture::s_ptexHDRTarget) // Sketch mode disables HDR rendering - { - return; - } - - // SSR only supported on 128bpp GMEM path - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - assert(CD3D9Renderer::eGT_128bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)); - } - - CTexture* pSSRTarget = CTexture::s_ptexHDRTargetScaledTmp[0]; - - PROFILE_LABEL_SCOPE("SSR_APPLY"); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - if (CRenderer::CV_r_SlimGBuffer == 1) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - SpecularAccEnableMRT(false); - gcpRendD3D->FX_PushRenderTarget(0, m_pLBufferSpecularRT, NULL); - } - - static CCryNameTSCRC tech("ApplySSR"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, tech, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - gcpRendD3D->FX_SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - - pSSRTarget->Apply(0, m_nTexStateLinear); - m_pDepthRT->Apply(1, m_nTexStatePoint); - m_pNormalsRT->Apply(2, m_nTexStatePoint); - m_pDiffuseRT->Apply(3, m_nTexStatePoint); - m_pSpecularRT->Apply(4, m_nTexStatePoint); - - CTextureManager::Instance()->GetDefaultTexture("EnvironmentBRDF")->Apply(5, m_nTexStateLinear); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(pSSRTarget->GetWidth(), pSSRTarget->GetHeight(), 0, &gcpRendD3D->m_HalfResRect); -#else - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(pSSRTarget->GetWidth(), pSSRTarget->GetHeight()); -#endif - SD3DPostEffectsUtils::ShEndPass(); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - gcpRendD3D->FX_PopRenderTarget(0); - } - SpecularAccEnableMRT(true); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::HeightMapOcclusionPass(ShadowMapFrustum*& pHeightMapFrustum, CTexture*& pHeightMapAOScreenDepth, CTexture*& pHeightmapAO) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const int nThreadID = rd->m_RP.m_nProcessThreadID; - pHeightMapFrustum = NULL; - pHeightMapAOScreenDepth = pHeightmapAO = NULL; - - if (!CRenderer::CV_r_HeightMapAO || rd->m_RP.m_pSunLight == NULL) - { - return; - } - - // find shadow frustum for height map AO - for (int nFrustum = 0; nFrustum < rd->m_RP.m_SMFrustums[nThreadID][0].size(); ++nFrustum) - { - ShadowMapFrustum* pCurFr = &rd->m_RP.m_SMFrustums[nThreadID][0][nFrustum]; - if (pCurFr->m_eFrustumType == ShadowMapFrustum::e_HeightMapAO && pCurFr->pDepthTex) - { - rd->ConfigShadowTexgen(0, pCurFr, -1, false, false); - pHeightMapFrustum = pCurFr; - break; - } - } - - if (pHeightMapFrustum) - { - PROFILE_LABEL_SCOPE("HEIGHTMAP_OCC"); - - const int resolutionIndex = clamp_tpl(CRenderer::CV_r_HeightMapAO - 1, 0, 2); - CTexture* pDepth[] = { CTexture::s_ptexZTargetScaled2, CTexture::s_ptexZTargetScaled, m_pDepthRT }; - CTexture* pDst = CTexture::s_ptexHeightMapAO[0]; - - if (!CTexture::s_ptexHeightMapAODepth[0]->IsResolved()) - { - PROFILE_LABEL_SCOPE("GENERATE_MIPS"); - - rd->GetDeviceContext().CopySubresourceRegion( - CTexture::s_ptexHeightMapAODepth[1]->GetDevTexture()->GetBaseTexture(), 0, 0, 0, 0, - CTexture::s_ptexHeightMapAODepth[0]->GetDevTexture()->GetBaseTexture(), 0, NULL - ); - - CTexture::s_ptexHeightMapAODepth[1]->GenerateMipMaps(); - CTexture::s_ptexHeightMapAODepth[0]->SetResolved(true); - } - - // Generate occlusion - { - PROFILE_LABEL_SCOPE("GENERATE_OCCL"); - - rd->FX_PushRenderTarget(0, pDst, NULL); - - static CCryNameTSCRC tech("HeightMapAOPass"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, tech, FEF_DONTSETSTATES); - rd->FX_SetState(GS_NODEPTHTEST); - - int TsLinearWithBorder = CTexture::GetTexState(STexState(FILTER_TRILINEAR, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0xFFFFFFFF)); - - m_pNormalsRT->Apply(0, m_nTexStatePoint); - pDepth[resolutionIndex]->Apply(1, m_nTexStatePoint); - CTexture::s_ptexSceneNormalsBent->Apply(10, m_nTexStatePoint); - CTexture::s_ptexHeightMapAODepth[1]->Apply(11, TsLinearWithBorder); - - Matrix44A matHMAOTransform = gRenDev->m_TempMatrices[0][0]; - Matrix44A texToWorld = matHMAOTransform.GetInverted(); - - static CCryNameR paramNameHMAO("HMAO_Params"); - const float texelsPerMeter = CRenderer::CV_r_HeightMapAOResolution / CRenderer::CV_r_HeightMapAORange; - const bool enableMinMaxSampling = CRenderer::CV_r_HeightMapAO < 3; - Vec4 paramHMAO(CRenderer::CV_r_HeightMapAOAmount, texelsPerMeter / CTexture::s_ptexHeightMapAODepth[1]->GetWidth(), enableMinMaxSampling ? 1.0 : 0.0, 0.0f); - m_pShader->FXSetPSFloat(paramNameHMAO, ¶mHMAO, 1); - - static CCryNameR paramNameHMAO_TexToWorldT("HMAO_TexToWorldTranslation"); - Vec4 vTranslation = Vec4(texToWorld.m03, texToWorld.m13, texToWorld.m23, 0); - m_pShader->FXSetPSFloat(paramNameHMAO_TexToWorldT, &vTranslation, 1); - - static CCryNameR paramNameHMAO_TexToWorldS("HMAO_TexToWorldScale"); - Vec4 vScale = Vec4(texToWorld.m00, texToWorld.m11, texToWorld.m22, 1); - m_pShader->FXSetPSFloat(paramNameHMAO_TexToWorldS, &vScale, 1); - - static CCryNameR paramHMAO_Transform("HMAO_Transform"); - m_pShader->FXSetPSFloat(paramHMAO_Transform, (Vec4*)matHMAOTransform.GetData(), 4); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(pDst->GetWidth(), pDst->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - rd->FX_PopRenderTarget(0); - } - - // depth aware blur - { - PROFILE_LABEL_SCOPE("BLUR"); - - CShader* pSH = rd->m_cEF.s_ShaderShadowBlur; - - CTexture* tpSrc = pDst; - rd->FX_PushRenderTarget(0, CTexture::s_ptexHeightMapAO[1], NULL); - - const Vec4* pClipVolumeParams = NULL; - uint32 nClipVolumeCount = 0; - CDeferredShading::Instance().GetClipVolumeParams(pClipVolumeParams, nClipVolumeCount); - - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0]); - rd->m_RP.m_FlagsShader_RT |= nClipVolumeCount > 0 ? g_HWSR_MaskBit[HWSR_SAMPLE0] : 0; - - static CCryNameTSCRC TechName("HMAO_Blur"); - SD3DPostEffectsUtils::ShBeginPass(pSH, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - tpSrc->Apply(0, m_nTexStatePoint, -2); - pDepth[resolutionIndex]->Apply(1, m_nTexStatePoint, -2); - - if (nClipVolumeCount) - { - static CCryNameR paramClipVolumeData("HMAO_ClipVolumeData"); - pSH->FXSetPSFloat(paramClipVolumeData, pClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nClipVolumeCount + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - SD3DPostEffectsUtils::SetTexture(CDeferredShading::Instance().GetResolvedStencilRT(), 2, FILTER_POINT); - } - - rd->D3DSetCull(eCULL_Back); - rd->FX_SetState(GS_NODEPTHTEST); - - Vec4 v(0, 0, tpSrc->GetWidth(), tpSrc->GetHeight()); - static CCryNameR Param1Name("PixelOffset"); - pSH->FXSetVSFloat(Param1Name, &v, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexHeightMapAO[1]->GetWidth(), CTexture::s_ptexHeightMapAO[1]->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - - rd->FX_PopRenderTarget(0); - } - - pHeightMapAOScreenDepth = pDepth[resolutionIndex]; - pHeightmapAO = CTexture::s_ptexHeightMapAO[1]; - } -} - -////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DirectionalOcclusionPass() -{ - if (CRenderer::CV_r_GraphicsPipeline & 1) - { - gcpRendD3D->GetGraphicsPipeline().RenderScreenSpaceObscurance(); - return; - } - - AZ_TRACE_METHOD(); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - if (!CRenderer::CV_r_ssdo) - { - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - gcpRendD3D->FX_ClearTarget(CTexture::s_ptexSceneNormalsBent, Clr_Median); - } - return; - } - - // SSDO only supported on 128bpp GMEM path - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - assert(CD3D9Renderer::eGT_128bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr)); - } - - // calculate height map AO first - ShadowMapFrustum* pHeightMapFrustum = NULL; - CTexture* pHeightMapAODepth, * pHeightMapAO; - HeightMapOcclusionPass(pHeightMapFrustum, pHeightMapAODepth, pHeightMapAO); - - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2]); - CTexture* pDstSSDO = CTexture::s_ptexStereoR;// re-using stereo buffers (only full resolution 32bit non-multisampled available at this step) -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif - - const bool bLowResOutput = (CRenderer::CV_r_ssdoHalfRes == 3); - if (bLowResOutput) - { - pDstSSDO = CTexture::s_ptexBackBufferScaled[0]; - } - - rd->m_RP.m_FlagsShader_RT |= CRenderer::CV_r_ssdoHalfRes ? g_HWSR_MaskBit[HWSR_SAMPLE0] : 0; - rd->m_RP.m_FlagsShader_RT |= pHeightMapFrustum ? g_HWSR_MaskBit[HWSR_SAMPLE1] : 0; - - bool isRenderingFur = FurPasses::GetInstance().IsRenderingFur(); - rd->m_RP.m_FlagsShader_RT |= isRenderingFur ? g_HWSR_MaskBit[HWSR_SAMPLE2] : 0; - - // Extreme magnification as happening with small FOVs will cause banding issues with half-res depth - if (CRenderer::CV_r_ssdoHalfRes == 2 && RAD2DEG(rd->GetCamera().GetFov()) < 30) - { - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - PROFILE_LABEL_PUSH("DIRECTIONAL_OCC"); - - bool allowDepthBounds = !bLowResOutput; - rd->FX_PushRenderTarget(0, pDstSSDO, allowDepthBounds ? &gcpRendD3D->m_DepthBufferOrig : NULL); - rd->FX_SetColorDontCareActions(0, true, false); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, allowDepthBounds); - } - - static CCryNameTSCRC tech("DirOccPass"); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, tech, FEF_DONTSETSTATES); - - rd->FX_SetState(GS_NODEPTHTEST); - m_pNormalsRT->Apply(0, m_nTexStatePoint); - CTexture::s_ptexZTarget->Apply(1, m_nTexStatePoint); - SPostEffectsUtils::SetTexture(CTextureManager::Instance()->GetDefaultTexture("AOVOJitter"), 3, FILTER_POINT, 0); - if (bLowResOutput) - { - CTexture::s_ptexZTargetScaled2->Apply(5, m_nTexStatePoint); - } - else - { - CTexture::s_ptexZTargetScaled->Apply(5, m_nTexStatePoint); - } - - if (isRenderingFur) - { - // Bind fur Z target - difference of the two Z targets indicates a stipple that needs avoided for SSDO - CTexture::s_ptexFurZTarget->Apply(2, m_nTexStatePoint); - } - - Matrix44A matView; - matView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix(); - - // Adjust the camera matrix so that the camera space will be: +y = down, +z - towards, +x - right - Vec3 zAxis = matView.GetRow(1); - matView.SetRow(1, -matView.GetRow(2)); - matView.SetRow(2, zAxis); - float z = matView.m13; - matView.m13 = -matView.m23; - matView.m23 = z; - - float radius = CRenderer::CV_r_ssdoRadius / rd->GetViewParameters().fFar; -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetInstance()->IsActive()) - { - radius *= CSvoRenderer::GetInstance()->GetSsaoAmount(); - } -#endif - static CCryNameR paramName1("SSDOParams"); - Vec4 param1(radius * 0.5f * rd->m_ProjMatrix.m00, radius * 0.5f * rd->m_ProjMatrix.m11, - CRenderer::CV_r_ssdoRadiusMin, CRenderer::CV_r_ssdoRadiusMax); - m_pShader->FXSetPSFloat(paramName1, ¶m1, 1); - - static CCryNameR viewspaceParamName("ViewSpaceParams"); - Vec4 vViewSpaceParam(2.0f / rd->m_ProjMatrix.m00, 2.0f / rd->m_ProjMatrix.m11, -1.0f / rd->m_ProjMatrix.m00, -1.0f / rd->m_ProjMatrix.m11); - m_pShader->FXSetPSFloat(viewspaceParamName, &vViewSpaceParam, 1); - - static CCryNameR paramName2("SSDO_CameraMatrix"); - m_pShader->FXSetPSFloat(paramName2, (Vec4*)matView.GetData(), 3); - - matView.Invert(); - static CCryNameR paramName3("SSDO_CameraMatrixInv"); - m_pShader->FXSetPSFloat(paramName3, (Vec4*)matView.GetData(), 3); - - // set up height map AO - if (pHeightMapFrustum) - { - pHeightMapAODepth->Apply(11, -2); - pHeightMapAO->Apply(12, -2); - - static CCryNameR paramNameHMAO("HMAO_Params"); - Vec4 paramHMAO(CRenderer::CV_r_HeightMapAOAmount, 1.0f / pHeightMapFrustum->nTexSize, 0, 0); - m_pShader->FXSetPSFloat(paramNameHMAO, ¶mHMAO, 1); - } - -#if defined(CRY_USE_METAL) || defined(ANDROID) - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - gRenDev->RT_SetScissor(true, 0, 0, pDstSSDO->GetWidth() * vDownscaleFactor.x + 0.5f, pDstSSDO->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(pDstSSDO->GetWidth(), pDstSSDO->GetHeight(), 0);//, &gcpRendD3D->m_FullResRect); - SD3DPostEffectsUtils::ShEndPass(); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(false, 0, 0, 0, 0); -#endif - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, false); - } - - rd->FX_PopRenderTarget(0); - - if (CRenderer::CV_r_ssdo != 99) - { - CShader* pSH = rd->m_cEF.s_ShaderShadowBlur; - CTexture* tpSrc = pDstSSDO; - - const int32 nSizeX = m_pDepthRT->GetWidth(); - const int32 nSizeY = m_pDepthRT->GetHeight(); - - const int32 nSrcSizeX = tpSrc->GetWidth(); - const int32 nSrcSizeY = tpSrc->GetHeight(); - - PROFILE_LABEL_SCOPE("SSDO_BLUR"); - rd->FX_PushRenderTarget(0, CTexture::s_ptexSceneNormalsBent, NULL); - - static CCryNameTSCRC TechName("SSDO_Blur"); - SD3DPostEffectsUtils::ShBeginPass(pSH, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - tpSrc->Apply(0, m_nTexStateLinear); - CTexture::s_ptexZTarget->Apply(1, m_nTexStatePoint); - - rd->D3DSetCull(eCULL_Back); - rd->FX_SetState(GS_NODEPTHTEST); - - Vec4 v(0, 0, nSrcSizeX, nSrcSizeY); - static CCryNameR Param1Name("PixelOffset"); - pSH->FXSetVSFloat(Param1Name, &v, 1); - - v = Vec4(0.5f / (float)nSizeX, 0.5f / (float)nSizeY, 1.f / (float)nSrcSizeX, 1.f / (float)nSrcSizeY); - static CCryNameR Param2Name("BlurOffset"); - pSH->FXSetPSFloat(Param2Name, &v, 1); - - v = Vec4(2.f / nSrcSizeX, 0, 2.f / nSrcSizeY, 10.f); //w = Weight coef - static CCryNameR Param3Name("SSAO_BlurKernel"); - pSH->FXSetPSFloat(Param3Name, &v, 1); - - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexSceneNormalsBent->GetWidth(), CTexture::s_ptexSceneNormalsBent->GetHeight(), 0, &gcpRendD3D->m_FullResRect); - SD3DPostEffectsUtils::ShEndPass(); - - rd->FX_PopRenderTarget(0); - } - else // For debugging - { - PostProcessUtils().StretchRect(pDstSSDO, CTexture::s_ptexSceneNormalsBent); - } - - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2]); - - if (CRenderer::CV_r_ssdoColorBleeding) - { - // Generate low frequency scene albedo for color bleeding (convolution not gamma correct but acceptable) - PostProcessUtils().StretchRect(CTexture::s_ptexSceneDiffuse, CTexture::s_ptexBackBufferScaled[0], false, false, false, false); - PostProcessUtils().StretchRect(CTexture::s_ptexBackBufferScaled[0], CTexture::s_ptexBackBufferScaled[1]); - PostProcessUtils().StretchRect(CTexture::s_ptexBackBufferScaled[1], CTexture::s_ptexAOColorBleed); - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexAOColorBleed, 1, 1.0f, 4.0f, false, NULL, false, CTexture::s_ptexBackBufferScaled[2]); - } - - PROFILE_LABEL_POP("DIRECTIONAL_OCC"); -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DeferredSubsurfaceScattering(CTexture* tmpTex) -{ - if (CRenderer::CV_r_GraphicsPipeline & 1) - { - m_pLBufferDiffuseRT->Unbind(); - gcpRendD3D->GetGraphicsPipeline().RenderScreenSpaceSSS(tmpTex); - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if (!CTexture::s_ptexHDRTarget) // Sketch mode disables HDR rendering - { - return; - } - - PROFILE_LABEL_SCOPE("SSSSS"); - - const uint64 nFlagsShaderRT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_DEBUG0]); - - if (CRenderer::CV_r_SlimGBuffer == 1) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - static CCryNameTSCRC techBlur("SSSSS_Blur"); - static CCryNameR blurParamName("SSSBlurDir"); - static CCryNameR viewspaceParamName("ViewSpaceParams"); - Vec4 vViewSpaceParam(2.0f / rd->m_ProjMatrix.m00, 2.0f / rd->m_ProjMatrix.m11, -1.0f / rd->m_ProjMatrix.m00, -1.0f / rd->m_ProjMatrix.m11); - Vec4 vBlurParam; - - float fProjScaleX = 0.5f * rd->m_ProjMatrix.m00; - float fProjScaleY = 0.5f * rd->m_ProjMatrix.m11; - - m_pLBufferDiffuseRT->Unbind(); - m_pDepthRT->Apply(1, m_nTexStatePoint); - m_pNormalsRT->Apply(2, m_nTexStatePoint); - m_pDiffuseRT->Apply(3, m_nTexStatePoint); - m_pSpecularRT->Apply(4, m_nTexStatePoint); - - rd->FX_SetState(GS_NODEPTHTEST); - - // Selectively enables debug mode permutation if a debug parameter is non-zero. - bool bEnableDebug = false; - Vec4 vDebugParams( - (float)rd->CV_r_DeferredShadingTiledDebugDirect, - (float)rd->CV_r_DeferredShadingTiledDebugIndirect, - (float)rd->CV_r_DeferredShadingTiledDebugAccumulation, - (float)rd->CV_r_DeferredShadingTiledDebugAlbedo); - if (vDebugParams.Dot(vDebugParams) > 0.0f) // Simple check to see if anything is enabled. - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - bEnableDebug = true; - } - static CCryNameR paramDebug("LightingDebugParams"); - -#if defined (CRY_USE_METAL) - //Need to clear this texture as it can have undefined or bad data on load. - rd->FX_ClearTarget(CTexture::s_ptexSceneTargetR11G11B10F[1], Clr_Empty); -#endif - - // Horizontal pass - rd->FX_PushRenderTarget(0, CTexture::s_ptexSceneTargetR11G11B10F[1], NULL); - - tmpTex->Apply(0, m_nTexStatePoint); // Irradiance - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techBlur, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_pShader->FXSetPSFloat(viewspaceParamName, &vViewSpaceParam, 1); - vBlurParam(fProjScaleX, 0, 0, 0); - m_pShader->FXSetPSFloat(blurParamName, &vBlurParam, 1); - if (bEnableDebug) - { - CShaderMan::s_shDeferredShading->FXSetPSFloat(paramDebug, &vDebugParams, 1); - } - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - - rd->FX_SetState(GS_NODEPTHTEST | GS_BLSRC_ONE | GS_BLDST_ONE); - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - - // Vertical pass - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, NULL); - CTexture::s_ptexSceneTargetR11G11B10F[1]->Apply(0, m_nTexStatePoint); - tmpTex->Apply(5, m_nTexStatePoint); // Original irradiance - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techBlur, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_pShader->FXSetPSFloat(viewspaceParamName, &vViewSpaceParam, 1); - vBlurParam(0, fProjScaleY, 0, 0); - m_pShader->FXSetPSFloat(blurParamName, &vBlurParam, 1); - if (bEnableDebug) - { - CShaderMan::s_shDeferredShading->FXSetPSFloat(paramDebug, &vDebugParams, 1); - } - SD3DPostEffectsUtils::DrawFullScreenTri(CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - - rd->m_RP.m_FlagsShader_RT = nFlagsShaderRT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DeferredShadingPass() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - - if (rd->IsShadowPassEnabled()) - { - PROFILE_LABEL_SCOPE("SHADOWMASK"); - rd->FX_DeferredShadowMaskGen(TArray()); - } - - rd->D3DSetCull(eCULL_Back, true); //fs quads should not revert test.. - - PROFILE_LABEL_PUSH("DEFERRED_SHADING"); - - CTexture* tmpTexSSS = CTexture::s_ptexSceneTargetR11G11B10F[0]; - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - tmpTexSSS = nullptr; - } - - const uint64 nFlagsShaderRT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_APPLY_SSDO] | g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION] |RT_CLIPVOLUME_ID); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, true); - } - - bool deferredSSS = CRenderer::CV_r_DeferredShadingSSS != 0; - - // Deferred subsurface scattering - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - deferredSSS = false; // Explicitly disable deferredSSS as it's not currently supported on GMEM path - } - - bool isRenderingFur = FurPasses::GetInstance().IsRenderingFur(); - if (deferredSSS || isRenderingFur) - { - // Output diffuse accumulation if SSS is enabled or if there are render items using fur - rd->FX_PushRenderTarget(1, tmpTexSSS, nullptr); - } - - PROFILE_LABEL_PUSH("COMPOSITION"); - static CCryNameTSCRC techComposition("DeferredShadingPass"); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - rd->FX_SetDepthDontCareActions(0, false, true); - rd->FX_SetStencilDontCareActions(0, false, true); - rd->FX_SetDepthDontCareActions(1, false, true); - rd->FX_SetStencilDontCareActions(1, false, true); - // CONFETTI END - } - - if (deferredSSS || isRenderingFur) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingAreaLights) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - - const uint32 nNumClipVolumes = m_nClipVolumesCount[m_nThreadID][m_nRecurseLevel]; - if (nNumClipVolumes) - { - rd->m_RP.m_FlagsShader_RT |= RT_CLIPVOLUME_ID; - } - - // Enable sun permutation (eg: when fully inside vis areas and sun not visible/used, skip sun computation) - if (rd->m_RP.m_pSunLight) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - if (CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - - // Directional occlusion - if (CRenderer::CV_r_ssdo) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_SSDO]; - } - - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techComposition, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - rd->FX_SetState(GS_NODEPTHTEST); - if (CD3D9Renderer::eGT_256bpp_PATH != gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - m_pDiffuseRT->Apply(2, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - m_pSpecularRT->Apply(3, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - m_pNormalsRT->Apply(4, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - m_pDepthRT->Apply(5, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // Following are already in GMEM - { - m_pLBufferDiffuseRT->Apply(0, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - m_pLBufferSpecularRT->Apply(1, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - m_pResolvedStencilRT->Apply(6, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1); - } - - // Directional occlusion - const int ssdoTexSlot = 7; - SetSSDOParameters(ssdoTexSlot); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // Following are already in GMEM - { - CTexture::s_ptexShadowMask->Apply(8, m_nTexStatePoint); - m_pDepthRT->Apply(9, m_nTexStatePoint); - } - - Vec3 sunColor; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_COLOR, sunColor); - - static CCryNameR paramNameSunColor("SunColor"); - const Vec4 paramSunColor(sunColor, gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER)); - m_pShader->FXSetPSFloat(paramNameSunColor, ¶mSunColor, 1); - - if (nNumClipVolumes) - { - m_pShader->FXSetPSFloat(m_pClipVolumeParams, m_vClipVolumeParams, min((uint32)MAX_DEFERRED_CLIP_VOLUMES, nNumClipVolumes + VIS_AREAS_OUTDOOR_STENCIL_OFFSET)); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Global blend weight - static CCryNameR clipVolGlobalBendWeight("g_fGlobalClipVolumeBlendWeight"); - Vec4 blendWeight(CRenderer::CV_r_GMEMVisAreasBlendWeight, 0, 0, 0); - m_pShader->FXSetPSFloat(clipVolGlobalBendWeight, &blendWeight, 1); - } - } - - const float SunSourceDiameter = 94.0f; // atan(AngDiameterSun) * 2 * SunDistance, where AngDiameterSun=0.54deg and SunDistance=10000 - static CCryNameR arealightMatrixName("g_AreaLightMatrix"); - Matrix44 mAreaLightMatrix; - mAreaLightMatrix.SetIdentity(); - mAreaLightMatrix.SetRow4(3, Vec4(SunSourceDiameter, SunSourceDiameter, 0, 1.0f)); - m_pShader->FXSetPSFloat(arealightMatrixName, alias_cast(&mAreaLightMatrix), 4); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight(), 0, &gcpRendD3D->m_FullResRect); - SD3DPostEffectsUtils::ShEndPass(); - - PROFILE_LABEL_POP("COMPOSITION"); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, DBT_SKY_CULL_DEPTH, false); - } - - if (deferredSSS || isRenderingFur) - { - rd->FX_PopRenderTarget(1); - rd->FX_SetActiveRenderTargets(); - DeferredSubsurfaceScattering(tmpTexSSS); - } - - FurPasses::GetInstance().ExecuteObliteratePass(); - - rd->m_RP.m_FlagsShader_RT = nFlagsShaderRT; - - PROFILE_LABEL_POP("DEFERRED_SHADING"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DeferredLights(TArray& rLights, bool bCastShadows) -{ - if (rLights.Num()) - { - PROFILE_LABEL_SCOPE("DEFERRED_LIGHTS"); - - if (bCastShadows) - { - PackAllShadowFrustums(rLights, false); - } - - for (uint32 nCurrentLight = 0; nCurrentLight < rLights.Num(); ++nCurrentLight) - { - const SRenderLight& pDL = rLights[nCurrentLight]; - if (pDL.m_Flags & (DLF_FAKE | DLF_VOLUMETRIC_FOG_ONLY)) - { - continue; - } - - assert(pDL.GetSpecularCubemap() == NULL); - if (!(pDL.m_Flags & DLF_CASTSHADOW_MAPS)) - { - LightPass(&pDL); - } - - m_nLightsProcessedCount++; - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -StaticInstance CDeferredShading::m_blockPack; -TArray CDeferredShading::m_shadowPoolAlloc; - -bool CDeferredShading::PackAllShadowFrustums(TArray& arrLights, bool bPreLoop) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - const uint64 nPrevFlagsShaderRT = rd->m_RP.m_FlagsShader_RT; - - static ICVar* p_e_ShadowsPoolSize = iConsole->GetCVar("e_ShadowsPoolSize"); - const bool isGmemEnabled = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - - int nRequestedPoolSize = p_e_ShadowsPoolSize->GetIVal(); - if (m_nShadowPoolSize != nRequestedPoolSize) - { - m_blockPack->UpdateSize(nRequestedPoolSize >> TEX_POOL_BLOCKLOGSIZE, nRequestedPoolSize >> TEX_POOL_BLOCKLOGSIZE); - m_nShadowPoolSize = nRequestedPoolSize; - - // clear pool and reset allocations - m_blockPack->Clear(); - m_shadowPoolAlloc.SetUse(0); - } - - // light pass here - if (!bPreLoop) - { - for (uint nLightPacked = m_nFirstCandidateShadowPoolLight; nLightPacked < m_nCurrentShadowPoolLight; ++nLightPacked) - { - const SRenderLight& rLight = arrLights[nLightPacked]; - if (rLight.m_Flags & DLF_FAKE) - { - continue; - } - ShadowLightPasses(rLight); - } - } - - while (m_nCurrentShadowPoolLight < arrLights.Num()) //pre-loop to avoid 0.5 ms restore/resolve - { - SRenderLight& rLight = arrLights[m_nCurrentShadowPoolLight]; - if (!(rLight.m_Flags & DLF_DIRECTIONAL) && (rLight.m_Flags & DLF_CASTSHADOW_MAPS)) - { - break; - } - m_nCurrentShadowPoolLight++; - } - - if (bPreLoop && m_nCurrentShadowPoolLight < arrLights.Num()) // Shadow allocation tick, free old shadows. - { - uint32 nAllocs = m_shadowPoolAlloc.Num(); - for (uint32 i = 0; i < nAllocs; i++) - { - SShadowAllocData* pAlloc = &m_shadowPoolAlloc[i]; - uint32 currFrame = gcpRendD3D->GetFrameID(false) & 0xFF; - if (!pAlloc->isFree() && ((currFrame - pAlloc->m_frameID) > (uint)CRenderer::CV_r_ShadowPoolMaxFrames)) - { - m_blockPack->RemoveBlock(pAlloc->m_blockID); - pAlloc->Clear(); - break; //Max one delete per frame, this should spread updates across more frames - } - } - } - - // In GMEM we only pack shadows during the preloop (that happens before the deferred lighting pass) - // We don't do it during the deferred lighting pass (preloop = false) because that would cause a resolve of the lighting accumulation buffers. - bool packShadows = bPreLoop || !isGmemEnabled; - bool bShadowRendered = false; - while (m_nCurrentShadowPoolLight < arrLights.Num() && (!bPreLoop || !bShadowRendered)) - { - m_nFirstCandidateShadowPoolLight = m_nCurrentShadowPoolLight; - - // init before shadowgen - SetupPasses(); - rd->FX_ResetPipe(); - rd->EF_Scissor(false, 0, 0, 0, 0); - rd->SetDepthBoundTest(0.0f, 1.0f, false); - - { - PROFILE_LABEL_SCOPE("SHADOWMAP_POOL"); - - if (!bPreLoop && !isGmemEnabled) - { - ResolveCurrentBuffers(); - } - - while (m_nCurrentShadowPoolLight < arrLights.Num()) - { - SRenderLight& rLight = arrLights[m_nCurrentShadowPoolLight]; - - if (packShadows && !(rLight.m_Flags & (DLF_DIRECTIONAL | DLF_FAKE)) && (rLight.m_Flags & DLF_CASTSHADOW_MAPS)) - { - bool bPacked = PackToPool(m_blockPack, rLight, m_bClearPool); - m_bClearPool = !bPacked; - if (!bPacked) - { - break; - } - } - ++m_nCurrentShadowPoolLight; - bShadowRendered = true; - } - -#ifndef _RELEASE - { - uint32 nAllocs = m_shadowPoolAlloc.Num(); - for (uint32 i = 0; i < nAllocs; i++) - { - if (!m_shadowPoolAlloc[i].isFree()) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumShadowPoolFrustums++; - } - } - } -#endif - } - - if (!bPreLoop && bShadowRendered) - { - if (!isGmemEnabled) - { - RestoreCurrentBuffers(); - } - - size_t numLightsWithoutShadow = 0; - //insert light pass here - for (uint nLightPacked = m_nFirstCandidateShadowPoolLight; nLightPacked < m_nCurrentShadowPoolLight; ++nLightPacked) - { - SRenderLight& rLight = arrLights[nLightPacked]; - if ((rLight.m_Flags & (DLF_FAKE | DLF_DIRECTIONAL)) || !(rLight.m_Flags & DLF_CASTSHADOW_MAPS)) - { - continue; - } - - if (packShadows) - { - ShadowLightPasses(rLight); - } - else - { - // We are not allow to pack shadows (like in GMEM during the ligthing pass) so this light doesn't have a shadowmap. - // Remove the cast shadow flag so it get's render without shadows later. - rLight.m_Flags &= ~DLF_CASTSHADOW_MAPS; - ++numLightsWithoutShadow; - } - } - - AZ_Warning("Rendering", numLightsWithoutShadow == 0, "%d lights will be rendered without shadows because there's no more space in the shadowmap pool texture.\ - Try decreasing the number of lights casting shadows or increasing the size of the shadowmap pool (e_ShadowsPoolSize)", - numLightsWithoutShadow); - } - } - - rd->m_RP.m_FlagsShader_RT = nPrevFlagsShaderRT; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CDeferredShading::PackToPool(CPowerOf2BlockPacker* pBlockPack, SRenderLight& light, bool bClearPool) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - ////////////////////////////////////////////////////////////////////////// - int nDLights = rd->m_RP.m_DLights[m_nThreadID][m_nRecurseLevel].Num(); - - ////////////////////////////////////////////////////////////////////////// - int nFrustumIdx = light.m_lightId + nDLights; - int nStartIdx = SRendItem::m_StartFrust[m_nThreadID][nFrustumIdx]; - int nEndIdx = SRendItem::m_EndFrust[m_nThreadID][nFrustumIdx]; - - int nUpdatedThisFrame = 0; - - assert((unsigned int) nFrustumIdx < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - if ((unsigned int) nFrustumIdx >= (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)) - { - int nFrameID = gcpRendD3D->GetFrameID(false); - if (m_nWarningFrame != nFrameID) - { - Warning("CDeferredShading::ShadowLightPasses: Too many light sources used ..."); - m_nWarningFrame = nFrameID; - } - //reset castshadow flag for further processing - light.m_Flags &= ~DLF_CASTSHADOW_MAPS; - return true; - } - ////////////////////////////////////////////////////////////////////////// - - //no single frustum was allocated for this light - if (nEndIdx <= nStartIdx) - { - //reset castshadow flag for further processing - light.m_Flags &= ~DLF_CASTSHADOW_MAPS; - return true; - } - - if (m_nRecurseLevel < 0 || m_nRecurseLevel >= (int)rd->m_RP.m_SMFrustums[m_nThreadID]->Num()) - { - //reset castshadow flag for further processing - light.m_Flags &= ~DLF_CASTSHADOW_MAPS; - return true; - } - - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nStartIdx]; - - ////////////////////////////////////////////////////////////////////////// - int nBlockW = firstFrustum.nTexSize >> TEX_POOL_BLOCKLOGSIZE; - int nLogBlockW = IntegerLog2((uint32)nBlockW); - int nLogBlockH = nLogBlockW; - - bool bNeedsUpdate = false; - - if (bClearPool) - { - pBlockPack->Clear(); - m_shadowPoolAlloc.SetUse(0); - } - - uint32 currFrame = gcpRendD3D->GetFrameID(false) & 0xFF; - - uint32 lightID = light.m_nEntityId; - - assert(lightID != (uint32) - 1); - - uint SidesNum = firstFrustum.bUnwrapedOmniDirectional ? OMNI_SIDES_NUM : 1; - uint nUpdateMask = firstFrustum.bUnwrapedOmniDirectional ? 0x3F : 0x1; - - for (uint nSide = 0; nSide < SidesNum; nSide++) - { - bNeedsUpdate = false; - uint nX1, nX2, nY1, nY2; - - //Find block allocation info (alternative: store in frustum data, but this does not persist) - bool bFoundAlloc = false; -#if defined(WIN32) - int nMGPUUpdate = -1; -#endif - uint32 nAllocs = m_shadowPoolAlloc.Num(); - SShadowAllocData* pAlloc = NULL; - for (uint32 i = 0; i < nAllocs; i++) - { - pAlloc = &m_shadowPoolAlloc[i]; - - if (pAlloc->m_lightID == lightID && pAlloc->m_side == nSide) - { - bFoundAlloc = true; - break; - } - } - - if (bFoundAlloc) - { - uint32 nID = pBlockPack->GetBlockInfo(pAlloc->m_blockID, nX1, nY1, nX2, nY2); - - int nFrameCompare = (currFrame - pAlloc->m_frameID) % 256; - - if (nID == 0xFFFFFFFF) - { - bNeedsUpdate = true; - } - else - { - if (firstFrustum.nShadowPoolUpdateRate == 0) // forced update, always do this - { - bNeedsUpdate = true; - } - else if (firstFrustum.nShadowPoolUpdateRate < (uint8) nFrameCompare) - { - if (nUpdatedThisFrame < CRenderer::CV_r_ShadowPoolMaxTimeslicedUpdatesPerFrame) - { - bNeedsUpdate = true; - nUpdatedThisFrame++; - } - } -#if defined(WIN32) // AFR support - else if (rd->GetActiveGPUCount() > 1) - { - if (gRenDev->GetActiveGPUCount() > nFrameCompare) - { - bNeedsUpdate = true; - nMGPUUpdate = pAlloc->m_frameID; - } - } -#endif - } - - if (!bNeedsUpdate) - { - if (nX1 != 0xFFFFFFFF && nBlockW == (nX2 - nX1)) // ignore Y, is square - { - pBlockPack->GetBlockInfo(nID, nX1, nY1, nX2, nY2); - firstFrustum.packX[nSide] = nX1 << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packY[nSide] = nY1 << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packWidth[nSide] = (nX2 - nX1) << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packHeight[nSide] = (nY2 - nY1) << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.nShadowGenID[m_nThreadID][nSide] = 0xFFFFFFFF; // turn off shadow gen for this side - - nUpdateMask &= ~(1 << nSide); - continue; // All currently valid, skip - } - } - - if (nID != 0xFFFFFFFF && nX1 != 0xFFFFFFFF) // Valid block, realloc - { - pBlockPack->RemoveBlock(nID); - pAlloc->Clear(); - } - } - - uint32 nID = pBlockPack->AddBlock(nLogBlockW, nLogBlockH); - bool isAllocated = (nID != 0xFFFFFFFF) ? true : false; - -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumShadowPoolAllocsThisFrame++; -#endif - - if (isAllocated) - { - bNeedsUpdate = true; - - if (!bFoundAlloc) - { - pAlloc = NULL; - nAllocs = m_shadowPoolAlloc.Num(); - for (uint32 i = 0; i < nAllocs; i++) - { - if (m_shadowPoolAlloc[i].isFree()) - { - pAlloc = &m_shadowPoolAlloc[i]; - break; - } - } - - if (!pAlloc) - { - pAlloc = m_shadowPoolAlloc.AddIndex(1); - } - } - - pAlloc->m_blockID = nID; - pAlloc->m_lightID = lightID; - pAlloc->m_side = nSide; -#if defined(WIN32) - pAlloc->m_frameID = (nMGPUUpdate == -1) ? gcpRendD3D->GetFrameID(false) & 0xFF : nMGPUUpdate; -#else - pAlloc->m_frameID = gcpRendD3D->GetFrameID(false) & 0xFF; -#endif - bClearPool = true; - } - else - { -#ifndef _RELEASE // failed alloc, will thrash! - if (CRenderer::CV_r_ShadowPoolMaxFrames != 0 || CRenderer::CV_r_DeferredShadingTiled > 1) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumShadowPoolAllocsThisFrame |= 0x80000000; - } -#endif - - return false; - } - - pBlockPack->GetBlockInfo(nID, nX1, nY1, nX2, nY2); - firstFrustum.packX[nSide] = nX1 << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packY[nSide] = nY1 << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packWidth[nSide] = (nX2 - nX1) << TEX_POOL_BLOCKLOGSIZE; - firstFrustum.packHeight[nSide] = (nY2 - nY1) << TEX_POOL_BLOCKLOGSIZE; - } - - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // next step is to use these values in shadowgen - - ////////////////////////////////////////////////////////////////////////// - - if (firstFrustum.bUseShadowsPool && nUpdateMask > 0) - { - rd->FX_PrepareDepthMapsForLight(light, nFrustumIdx, bClearPool); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::ResolveCurrentBuffers() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - PROFILE_LABEL_SCOPE("FLUSH_RESOLVE"); - rd->FX_PopRenderTarget(1); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::RestoreCurrentBuffers() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->FX_PushRenderTarget(1, m_pLBufferSpecularRT, NULL, -1, false, 1); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CDeferredShading::ShadowLightPasses(const SRenderLight& light) -{ - PROFILE_SHADER_SCOPE; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - float scissorInt2Float[] = { (float)(light.m_sX), (float)(light.m_sY), (float)(light.m_sWidth), (float)(light.m_sHeight) }; - - rd->m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - int nDLights = rd->m_RP.m_DLights[m_nThreadID][m_nRecurseLevel].Num(); - - ////////////////////////////////////////////////////////////////////////// - int nFrustumIdx = light.m_lightId + nDLights; - int nStartIdx = SRendItem::m_StartFrust[m_nThreadID][nFrustumIdx]; - int nEndIdx = SRendItem::m_EndFrust[m_nThreadID][nFrustumIdx]; - - - assert((unsigned int) nFrustumIdx < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - if ((unsigned int) nFrustumIdx >= (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)) - { - //Warning("CDeferredShading::ShadowLightPasses: Too many light sources used ..."); // redundant - return false; - } - - //no single frustum was allocated for this light - if (nEndIdx <= nStartIdx) - { - return false; - } - - if (m_nRecurseLevel < 0 || m_nRecurseLevel >= (int)rd->m_RP.m_SMFrustums[m_nThreadID]->Num()) - { - return false; - } - - // Area lights are a non-uniform box, not a cone in 1 of 6 directions, so we skip clipping/stencil testing and let the light pass take care of it. - bool bAreaLight = (light.m_Flags & DLF_AREA_LIGHT) && light.m_fAreaWidth && light.m_fAreaHeight && light.m_fLightFrustumAngle && CRenderer::CV_r_DeferredShadingAreaLights; - - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nStartIdx]; - - int nSides = 1; - if (firstFrustum.bOmniDirectionalShadow && !bAreaLight) - { - nSides = 6; - } - - // omni lights with clip bounds require two stencil tests (one for the side and one for the clip bound) - const int stencilValuesPerSide = 1; - - //enable shadow mapping - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - - //enable hw-pcf per frustum - if (firstFrustum.bHWPCFCompare) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]; - } - - Vec4 pLightRect = Vec4(scissorInt2Float[0], scissorInt2Float[1], scissorInt2Float[2], scissorInt2Float[3]); - Vec4 scaledLightRect = Vec4(pLightRect.x * rd->m_RP.m_CurDownscaleFactor.x, pLightRect.y * rd->m_RP.m_CurDownscaleFactor.y, - pLightRect.z * rd->m_RP.m_CurDownscaleFactor.x, pLightRect.w * rd->m_RP.m_CurDownscaleFactor.y); - - if (!bAreaLight) - { - rd->m_nStencilMaskRef += (nSides * stencilValuesPerSide + 2); - if (rd->m_nStencilMaskRef > STENC_MAX_REF) - { - int sX = 0, sY = 0, sWidth = 0, sHeight = 0; - bool bScissorEnabled = rd->EF_GetScissorState(sX, sY, sWidth, sHeight); - rd->EF_Scissor(false, 0, 0, 0, 0); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Avoid any resolve. We clear stencil with full screen pass. - uint32 prevState = rd->m_RP.m_CurState; - uint32 newState = 0; - newState |= GS_COLMASK_NONE; - newState |= GS_STENCIL; - rd->FX_SetStencilState(STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_ZERO) | - STENCOP_ZFAIL(FSS_STENCOP_ZERO) | - STENCOP_PASS(FSS_STENCOP_ZERO), - 0, 0xFFFFFFFF, 0xFFFF); - rd->FX_SetState(newState); - SD3DPostEffectsUtils::ClearScreen(0, 0, 0, 0); - rd->FX_SetState(prevState); - } - else - { - rd->EF_ClearTargetsImmediately(FRT_CLEAR_STENCIL); - } - - rd->EF_Scissor(bScissorEnabled, sX, sY, sWidth, sHeight); - rd->m_nStencilMaskRef = nSides * stencilValuesPerSide + 1; - } - } - - uint16 scaledX = 0, scaledY = 0, scaledWidth = 0, scaledHeight = 0; - - for (int nS = 0; nS < nSides; nS++) - { - uint32 nPersFlagsPrev = rd->m_RP.m_TI[m_nThreadID].m_PersFlags; - - bool bIsMirrored = (rd->m_RP.m_TI[m_nThreadID].m_PersFlags & RBPF_MIRRORCULL) ? true : false; - bool bRequiresMirroring = (!(light.m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT))) ? true : false; - - if (bIsMirrored ^ bRequiresMirroring) // Enable mirror culling for omni-shadows, or if we are in cubemap-gen. If both, they cancel-out, so disable. - { - rd->m_RP.m_TI[m_nThreadID].m_PersFlags |= RBPF_MIRRORCULL; - } - else - { - rd->m_RP.m_TI[m_nThreadID].m_PersFlags &= ~RBPF_MIRRORCULL; - } - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(false); -#endif - - if (CRenderer::CV_r_DeferredShadingDepthBoundsTest == 1 && !bAreaLight) - { - Vec4 pDepthBounds = GetLightDepthBounds(&light, (rd->m_RP.m_TI[m_nThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0); - rd->SetDepthBoundTest(pDepthBounds.x, pDepthBounds.z, true); - } - - if (nS == 0) - { - scaledX = (uint16)(scaledLightRect.x); - scaledY = (uint16)(scaledLightRect.y); - scaledWidth = (uint16)(scaledLightRect.z) + 1; - scaledHeight = (uint16)(scaledLightRect.w) + 1; - } - - if (!bAreaLight) - { - //use current WorldProj matrix - rd->FX_StencilFrustumCull(-2, &light, &firstFrustum, nS); - - rd->SetDepthBoundTest(0, 1, false); - } - - rd->m_RP.m_TI[m_nThreadID].m_PersFlags = nPersFlagsPrev; - if (!bAreaLight) - { - rd->FX_StencilTestCurRef(true, true); - } - - SetupPasses(); - - if (!bAreaLight) - { - m_nRenderState |= GS_STENCIL; - } - -#if !defined(CRY_USE_METAL) && !defined(ANDROID) - SpecularAccEnableMRT(true); -#endif - - if (firstFrustum.nShadowGenMask & (1 << nS)) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - rd->ConfigShadowTexgen(0, &firstFrustum, nS); - - if (firstFrustum.bUseShadowsPool) - { - const int nTexFilter = firstFrustum.bHWPCFCompare ? FILTER_LINEAR : FILTER_POINT; - STexState TS; - TS.SetFilterMode(nTexFilter); - TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP); - TS.m_bSRGBLookup = false; - TS.SetComparisonFilter(true); - CTexture::s_ptexRT_ShadowPool->Apply(3, CTexture::GetTexState(TS), EFTT_UNKNOWN, 6); - // this assigned comparison sampler to correct sampler slot for shadowmapped light sources - if (!rd->UseHalfFloatRenderTargets()) - { - CTexture::SetSamplerState(CTexture::GetTexState(TS), 0, eHWSC_Pixel); - } - } - else - { - SD3DPostEffectsUtils::SetTexture(firstFrustum.pDepthTex, 3, FILTER_POINT, 0); - } - - SD3DPostEffectsUtils::SetTexture(CTextureManager::Instance()->GetDefaultTexture("ShadowJitterMap"), 7, FILTER_POINT, 0); - } - else - { - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - ////////////////////////////////////////////////////////////////////////// - - - m_nCurLighID = light.m_lightId; - - LightPass(&light, true); - - if (!bAreaLight) - { - rd->FX_StencilTestCurRef(false); - } - } - - //assign range - if (!bAreaLight) - { - rd->m_nStencilMaskRef += nSides * stencilValuesPerSide; - } - ////////////////////////////////////////////////////////////////////////// - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]); - - if (!bAreaLight) - { - m_nRenderState &= ~GS_STENCIL; - } - rd->FX_SetState(m_nRenderState); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::CreateDeferredMaps() -{ - AZ_TRACE_METHOD(); - static uint32 nPrevLBuffersFmt = CRenderer::CV_r_DeferredShadingLBuffersFmt; - if (!CTexture::s_ptexSceneNormalsMap || CTexture::s_ptexSceneNormalsMap->IsMSAAChanged() - || CTexture::s_ptexSceneNormalsMap->GetWidth() != gcpRendD3D->m_MainViewport.nWidth - || CTexture::s_ptexSceneNormalsMap->GetHeight() != gcpRendD3D->m_MainViewport.nHeight - || nPrevLBuffersFmt != CRenderer::CV_r_DeferredShadingLBuffersFmt) - { - nPrevLBuffersFmt = CRenderer::CV_r_DeferredShadingLBuffersFmt; - - int nWidth = gcpRendD3D->GetWidth(); - int nHeight = gcpRendD3D->GetHeight(); - int nMSAAUsageFlag = ((CRenderer::CV_r_msaa ? FT_USAGE_MSAA : 0)); - int nMsaaAndSrgbFlag = nMSAAUsageFlag; - - if (RenderCapabilities::SupportsTextureViews()) - { - // Currently android nor mac(GL) support srgb render targets so only add this - // flag for other platforms - nMsaaAndSrgbFlag |= FT_USAGE_ALLOWREADSRGB; - } - - // This texture is reused for SMAA... - // grab format from backbuffer - normals map doubles as a previous backbuffer target elsewhere, so it has to be the same type as the backbuffer. - ETEX_Format fmt = CTexture::s_ptexBackBuffer->GetDstFormat(); - SD3DPostEffectsUtils::CreateRenderTarget("$SceneNormalsMap", CTexture::s_ptexSceneNormalsMap, nWidth, nHeight, Clr_Unknown, true, false, fmt, TO_SCENE_NORMALMAP, nMsaaAndSrgbFlag); - SD3DPostEffectsUtils::CreateRenderTarget("$SceneNormalsBent", CTexture::s_ptexSceneNormalsBent, nWidth, nHeight, Clr_Median, true, false, eTF_R8G8B8A8); - SD3DPostEffectsUtils::CreateRenderTarget("$AOColorBleed", CTexture::s_ptexAOColorBleed, nWidth >> 3, nHeight >> 3, Clr_Unknown, true, false, eTF_R8G8B8A8); - - ETEX_Format sceneDiffuseAccTexFormat = eTF_R16G16B16A16F; - ETEX_Format sceneSpecularAccTexFormat = eTF_R16G16B16A16F; - -#if defined(OPENGL_ES) // might be no fp rendering support - if (!gcpRendD3D->UseHalfFloatRenderTargets()) - { - sceneSpecularAccTexFormat = eTF_R10G10B10A2; - sceneDiffuseAccTexFormat = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) ? eTF_R16G16B16A16 : eTF_R10G10B10A2; - } -#elif defined(WIN32) || defined(APPLE) || defined(LINUX) || defined(SUPPORTS_DEFERRED_SHADING_L_BUFFERS_FORMAT) - if (CRenderer::CV_r_DeferredShadingLBuffersFmt == 1) - { - sceneSpecularAccTexFormat = eTF_R11G11B10F; - sceneDiffuseAccTexFormat = gcpRendD3D->FX_GetEnabledGmemPath(nullptr) ? eTF_R16G16B16A16F : eTF_R11G11B10F; - } -#endif - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2 && gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - sceneDiffuseAccTexFormat = eTF_R8; - sceneSpecularAccTexFormat = eTF_R11G11B10F; -#if defined(OPENGL_ES) - if (!gcpRendD3D->UseHalfFloatRenderTargets()) - { - sceneSpecularAccTexFormat = eTF_R10G10B10A2; - } -#endif - } - - SD3DPostEffectsUtils::CreateRenderTarget("$SceneDiffuseAcc", CTexture::s_ptexSceneDiffuseAccMap, nWidth, nHeight, Clr_Transparent, true, false, - // In GMEM Paths: - // - Alpha channel is used for shadow mask - // - Used as a tmp buffer to hold normals while computing deferred decals - sceneDiffuseAccTexFormat, - TO_SCENE_DIFFUSE_ACC, nMSAAUsageFlag); - - CTexture::s_ptexCurrentSceneDiffuseAccMap = CTexture::s_ptexSceneDiffuseAccMap; - - // When the device orientation changes on mobile, we need to regenerate HDR maps before calling CreateRenderTarget. - // Otherwise, the width and height of the texture get updated before HDRPostProcess::Begin call and we never regenerate the HDR maps which results in visual artifacts. - if (CTexture::s_ptexHDRTarget && (CTexture::s_ptexHDRTarget->IsMSAAChanged() || CTexture::s_ptexHDRTarget->GetWidth() != gcpRendD3D->GetWidth() || CTexture::s_ptexHDRTarget->GetHeight() != gcpRendD3D->GetHeight())) - { - CTexture::GenerateHDRMaps(); - } - - SD3DPostEffectsUtils::CreateRenderTarget("$SceneSpecularAcc", CTexture::s_ptexSceneSpecularAccMap, nWidth, nHeight, Clr_Transparent, true, false, sceneSpecularAccTexFormat, TO_SCENE_SPECULAR_ACC, nMSAAUsageFlag); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Point s_ptexHDRTarget to s_ptexSceneSpecularAccMap for GMEM paths - CTexture::s_ptexHDRTarget = CTexture::s_ptexSceneSpecularAccMap; - - // Point m_pResolvedStencilRT to s_ptexGmemStenLinDepth for GMEM paths - m_pResolvedStencilRT = CTexture::s_ptexGmemStenLinDepth; - } - - SD3DPostEffectsUtils::CreateRenderTarget("$SceneDiffuse", CTexture::s_ptexSceneDiffuse, nWidth, nHeight, Clr_Empty, true, false, eTF_R8G8B8A8, -1, nMsaaAndSrgbFlag); - - // Slimming of GBuffer requires only one channel for specular due to packing of RGB values into YPbPr and - // specular components into less channels - ETEX_Format rtTextureFormat = eTF_R8G8B8A8; - if (CRenderer::CV_r_SlimGBuffer == 1) - { - rtTextureFormat = eTF_R8; - } - SD3DPostEffectsUtils::CreateRenderTarget("$SceneSpecular", CTexture::s_ptexSceneSpecular, nWidth, nHeight, Clr_Empty, true, false, rtTextureFormat, -1, nMsaaAndSrgbFlag); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif - - ETEX_Format fmtZScaled = gcpRendD3D->UseHalfFloatRenderTargets() ? eTF_R16G16F : eTF_R16G16U; - SD3DPostEffectsUtils::CreateRenderTarget("$ZTargetScaled", CTexture::s_ptexZTargetScaled, nWidth >> 1, nHeight >> 1, Clr_FarPlane, 1, 0, fmtZScaled, TO_DOWNSCALED_ZTARGET_FOR_AO); - SD3DPostEffectsUtils::CreateRenderTarget("$ZTargetScaled2", CTexture::s_ptexZTargetScaled2, nWidth >> 2, nHeight >> 2, Clr_FarPlane, 1, 0, fmtZScaled, TO_QUARTER_ZTARGET_FOR_AO); - - SD3DPostEffectsUtils::CreateRenderTarget("$AmbientLookup", CTexture::s_ptexAmbientLookup, 64, 1, Clr_Empty, true, false, eTF_R8G8B8A8, -1, FT_DONT_RELEASE); - SD3DPostEffectsUtils::CreateRenderTarget("$DepthBufferQuarter", CTexture::s_ptexDepthBufferQuarter, nWidth >> 2, nHeight >> 2, Clr_FarPlane, false, false, eTF_D32F, -1, FT_USAGE_DEPTHSTENCIL); - } - - // Pre-create shadow pool - IF (gcpRendD3D->m_pRT->IsRenderThread() && gEnv->p3DEngine, 1) - { - //init shadow pool size - static ICVar* p_e_ShadowsPoolSize = iConsole->GetCVar("e_ShadowsPoolSize"); - gcpRendD3D->m_nShadowPoolHeight = p_e_ShadowsPoolSize->GetIVal(); - gcpRendD3D->m_nShadowPoolWidth = gcpRendD3D->m_nShadowPoolHeight; //square atlas - - ETEX_Format eShadTF = gcpRendD3D->CV_r_shadowtexformat == 1 ? eTF_D16 : eTF_D32F; - CTexture::s_ptexRT_ShadowPool->Invalidate(gcpRendD3D->m_nShadowPoolWidth, gcpRendD3D->m_nShadowPoolHeight, eShadTF); - if (!CTexture::IsTextureExist(CTexture::s_ptexRT_ShadowPool)) - { - CTexture::s_ptexRT_ShadowPool->CreateRenderTarget(eTF_Unknown, Clr_FarPlane); - } - - CTexture::s_ptexRT_ShadowStub->Invalidate(1, 1, eShadTF); - if (!CTexture::IsTextureExist(CTexture::s_ptexRT_ShadowStub)) - { - CTexture::s_ptexRT_ShadowStub->CreateRenderTarget(eTF_Unknown, Clr_FarPlane); - } - } - - if (CRenderer::CV_r_DeferredShadingTiled > 0) - { - gcpRendD3D->GetTiledShading().CreateResources(); - } - - gcpRendD3D->GetVolumetricFog().CreateResources(); - - // shadow mask - { - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && !RenderCapabilities::SupportsPLSExtension()) - { - // Gmem only supports one shadow mask texture and it's saved on the alpha channel of the diffuse light acc texture. - CTexture::s_ptexShadowMask = CTexture::s_ptexCurrentSceneDiffuseAccMap; - } - else - { - if (CTexture::s_ptexShadowMask) - { - CTexture::s_ptexShadowMask->Invalidate(gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight(), eTF_R8G8B8A8); - } - - if (!CTexture::IsTextureExist(CTexture::s_ptexShadowMask)) - { -#if defined(CRY_USE_METAL) - const int nArraySize = 1; // iOS currently only supports one shadow mask texture -#else - const int nArraySize = (gcpRendD3D->CV_r_ShadowCastingLightsMaxCount + 3) / 4; -#endif - CTexture::s_ptexShadowMask = CTexture::CreateTextureArray("$ShadowMask", eTT_2D, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight(), nArraySize, 1, FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_R8G8B8A8, TO_SHADOWMASK); - } - } - } - - // height map AO mask - if (CRenderer::CV_r_HeightMapAO > 0) - { - const int nShift = clamp_tpl(3 - CRenderer::CV_r_HeightMapAO, 0, 2); - const int hmaoWidth = gcpRendD3D->GetWidth() >> nShift; - const int hmaoHeight = gcpRendD3D->GetHeight() >> nShift; - - for (int i = 0; i < 2; ++i) - { - if (CTexture::s_ptexHeightMapAO[i]) - { - CTexture::s_ptexHeightMapAO[i]->Invalidate(hmaoWidth, hmaoHeight, eTF_R8G8); - } - - if (!CTexture::IsTextureExist(CTexture::s_ptexHeightMapAO[i])) - { - char buf[128]; - sprintf_s(buf, "$HeightMapAO_%d", i); - - SD3DPostEffectsUtils::CreateRenderTarget(buf, CTexture::s_ptexHeightMapAO[i], hmaoWidth, hmaoHeight, Clr_Neutral, true, false, eTF_R8G8); - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DestroyDeferredMaps() -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -struct CubemapsCompare -{ - bool operator()(const SRenderLight& l0, const SRenderLight& l1) const - { - // Cubes sort by: Sort priority first, light radius, lastly by entity id (insertion order every frame is not guaranteed) - if (l0.m_nSortPriority != l1.m_nSortPriority) - { - return l0.m_nSortPriority < l1.m_nSortPriority; - } - - if (fcmp(l0.m_fRadius, l1.m_fRadius)) - { - return l0.m_nEntityId < l1.m_nEntityId; - } - - return l0.m_fRadius > l1.m_fRadius; - } -}; - -struct CubemapsCompareInv -{ - bool operator()(const SRenderLight& l0, const SRenderLight& l1) const - { - // Cubes sort by: Sort priority first, light radius, lastly by entity id (insertion order every frame is not guaranteed) - if (l0.m_nSortPriority != l1.m_nSortPriority) - { - return l0.m_nSortPriority > l1.m_nSortPriority; - } - - if (fcmp(l0.m_fRadius, l1.m_fRadius)) - { - return l0.m_nEntityId > l1.m_nEntityId; - } - - return l0.m_fRadius < l1.m_fRadius; - } -}; - -struct LightsCompare -{ - bool operator()(const SRenderLight& l0, const SRenderLight& l1) const - { - if (!(l0.m_Flags & DLF_CASTSHADOW_MAPS) && (l1.m_Flags & DLF_CASTSHADOW_MAPS)) - { - return true; - } - else - { - return false; - } - } -}; - -struct DeffDecalSort -{ - bool operator()(const SDeferredDecal& decal0, const SDeferredDecal& decal1) const - { - uint bBump0 = (decal0.nFlags & DECAL_HAS_NORMAL_MAP); - uint bBump1 = (decal1.nFlags & DECAL_HAS_NORMAL_MAP); - //bump-mapped decals first - if (bBump0 != bBump1) - { - return (bBump0 < bBump1); - } - return - (decal0.nSortOrder < decal1.nSortOrder); - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CDeferredShading::SetupGmemPath() -{ -#if !defined(NDEBUG) - bool bTiledDeferredShading = CRenderer::CV_r_DeferredShadingTiled >= 2; - assert(!bTiledDeferredShading); // NOT SUPPORTED IN GMEM PATH! -#endif - - SetupPasses(); - TArray& rDeferredLights = m_pLights[eDLT_DeferredLight][m_nThreadID][m_nRecurseLevel]; - - m_bClearPool |= CRenderer::CV_r_ShadowPoolMaxFrames == 0; - - m_nCurrentShadowPoolLight = 0; - m_nFirstCandidateShadowPoolLight = 0; - -#if !defined(_RELEASE) - CD3D9Renderer* const __restrict rd = gcpRendD3D; - rd->m_RP.m_PS[m_nThreadID].m_NumShadowPoolFrustums = 0; - rd->m_RP.m_PS[m_nThreadID].m_NumShadowPoolAllocsThisFrame = 0; - rd->m_RP.m_PS[m_nThreadID].m_NumShadowMaskChannels = 0; -#endif - - SortLigths(rDeferredLights); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLights) - { - PackAllShadowFrustums(rDeferredLights, true); - } -} -//////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::AmbientOcclusionPasses() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if (CRenderer::CV_r_DeferredShadingTiled >= 2) - { - return; - } - - PROFILE_LABEL_SCOPE("AO_APPLY"); - - SpecularAccEnableMRT(false); - - rd->EF_Scissor(false, 0, 0, 0, 0); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.f, DBT_SKY_CULL_DEPTH, true); // skip sky and near objects for SSAO/LPVs - } - SpecularAccEnableMRT(true); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DebugShadowMaskClear() -{ - // This function is only useful when shadows get turned off at run-time. - // TODO: should only clear once when shadows get turned off... not every frame! - // For GMEM, we by-pass this function completely as the RT has don't care actions set. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - return; - } - -#ifndef _RELEASE - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - static const ICVar* pCVarShadows = iConsole->GetCVar("e_Shadows"); - if ((pCVarShadows && pCVarShadows->GetIVal() == 0) || CRenderer::CV_r_ShadowPass == 0) - { - rd->FX_ClearTarget(CTexture::s_ptexBackBuffer, Clr_Transparent); - } -#endif -} - -void CDeferredShading::SortLigths(TArray& ligths) const -{ - if (CRenderer::CV_r_DeferredShadingSortLights <= 0 || ligths.size() <= 1) - { - return; - } - - int swapPos = -1; - if (CRenderer::CV_r_DeferredShadingSortLights == 2 || - CRenderer::CV_r_DeferredShadingSortLights == 3) - { - // Sort the lights so we process the ones that are packed first. - // This reduce the probability of trashing the shadowmap. - for (size_t i = 0; i < ligths.Num(); ++i) - { - const SRenderLight& light = ligths[i]; - bool isPacked = m_shadowPoolAlloc.end() != AZStd::find_if(m_shadowPoolAlloc.begin(), m_shadowPoolAlloc.end(), [&light](const SShadowAllocData& data) {return data.m_lightID == light.m_nEntityId; }); - if (isPacked) - { - ++swapPos; - if (i != swapPos) - { - AZStd::swap(ligths[i], ligths[swapPos]); - } - } - } - } - - if (CRenderer::CV_r_DeferredShadingSortLights == 1 || - CRenderer::CV_r_DeferredShadingSortLights == 3) - { - CD3D9Renderer* const __restrict rd = gcpRendD3D; - auto sortFunc = [&rd](const SRenderLight& lhs, const SRenderLight& rhs) - { - // First compare by influence area in screen area (bigger area goes first) - // If they have the same area then render the closest to the camera first - // If they are at the same distance then just use the entityId (to break the tie) - int lhsSize = lhs.m_sWidth * lhs.m_sHeight; - int rhsSize = rhs.m_sWidth * rhs.m_sHeight; - if (lhsSize == rhsSize) - { - Vec3 cameraPos = rd->GetCamera().GetPosition(); - float lhsDistance = cameraPos.GetDistance(lhs.GetPosition()); - float rhsDistance = cameraPos.GetDistance(rhs.GetPosition()); - return lhsDistance == rhsDistance ? lhs.m_nEntityId < rhs.m_nEntityId : lhsDistance < rhsDistance; - } - - return lhsSize > rhsSize; - }; - - // Sort in two halfs so we don't break the previous order. - // The first half are the lights that are already packed (if r_DeferredShadingSortLights = 3). - // The second half are the rest of the lights. - SRenderLight* firstHalfElement = swapPos < 0 ? ligths.end() : ligths.begin() + swapPos + 1; - AZStd::sort(ligths.begin(), firstHalfElement, sortFunc); - // Check if there's even a second half. - if (firstHalfElement != ligths.end()) - { - AZStd::sort(firstHalfElement, ligths.end(), sortFunc); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::Render() -{ - m_nLightsProcessedCount = 0; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - uint64 nFlagsShaderRT = rd->m_RP.m_FlagsShader_RT; - - rd->FX_ResetPipe(); - - SetupPasses(); - - // Calculate screenspace scissor bounds - CalculateLightScissorBounds(); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { -#ifndef _RELEASE - rd->m_RP.m_PS[m_nThreadID].m_NumShadowPoolFrustums = 0; - rd->m_RP.m_PS[m_nThreadID].m_NumShadowPoolAllocsThisFrame = 0; - rd->m_RP.m_PS[m_nThreadID].m_NumShadowMaskChannels = 0; -#endif - } - - TArray& rDeferredLights = m_pLights[eDLT_DeferredLight][m_nThreadID][m_nRecurseLevel]; - TArray& rDeferredCubemaps = m_pLights[eDLT_DeferredCubemap][m_nThreadID][m_nRecurseLevel]; - TArray& rDeferredAmbientLights = m_pLights[eDLT_DeferredAmbientLight][m_nThreadID][m_nRecurseLevel]; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.f, DBT_SKY_CULL_DEPTH, true); // skip sky for ambient and deferred cubemaps - } - int iTempX, iTempY, iWidth, iHeight; - rd->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - bool bOutdoorVisible = false; - PrepareClipVolumeData(bOutdoorVisible); - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - rd->FX_GmemTransition(CD3D9Renderer::eGT_POST_Z_PRE_DEFERRED); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - rd->EF_Scissor(false, 0, 0, 0, 0); - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - SortLigths(rDeferredLights); - FilterGBuffer(); - - // Generate directional occlusion information - DirectionalOcclusionPass(); - - // Generate glossy screenspace reflections - ScreenSpaceReflectionPass(); - - m_bClearPool = (CRenderer::CV_r_ShadowPoolMaxFrames > 0) ? false : true; - - m_nCurrentShadowPoolLight = 0; - m_nFirstCandidateShadowPoolLight = 0; - - PackAllShadowFrustums(rDeferredLights, true); - - rd->FX_PushRenderTarget(0, m_pLBufferDiffuseRT, &gcpRendD3D->m_DepthBufferOrigMSAA, -1, false, 1); - rd->FX_PushRenderTarget(1, m_pLBufferSpecularRT, NULL, -1, false, 1); - m_bSpecularState = true; - } - - // sort lights - if (rDeferredCubemaps.Num()) - { - if (CRenderer::CV_r_DeferredShadingTiled <= 1) - { - std::sort(rDeferredCubemaps.begin(), rDeferredCubemaps.end(), CubemapsCompare()); - } - else - { - std::sort(rDeferredCubemaps.begin(), rDeferredCubemaps.end(), CubemapsCompareInv()); - } - } - - rd->FX_SetState(GS_BLSRC_ONE | GS_BLDST_ZERO); - - - if (gRenDev->GetWireframeMode()) - { - rd->FX_ClearTarget(m_pLBufferDiffuseRT); - rd->FX_ClearTarget(m_pLBufferSpecularRT); - rd->FX_ClearTarget(&gcpRendD3D->m_DepthBufferOrigMSAA, CLEAR_STENCIL, Clr_Unused.r, 1); - rd->m_nStencilMaskRef = 1;// Stencil initialized to 1 - 0 is reserved for MSAAed samples - } - - rd->RT_SetViewport(0, 0, gRenDev->GetWidth(), gRenDev->GetHeight()); - - uint32 nCurrentDeferredCubemap = 0; - - bool bTiledDeferredShading = CRenderer::CV_r_DeferredShadingTiled >= 2; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDebug == 2) - { - gcpRendD3D->m_RP.m_FlagsShader_RT |= RT_OVERDRAW_DEBUG; - bTiledDeferredShading = false; - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_Unlit) - { - bTiledDeferredShading = false; - } - - // Currently cubemap atlas update is not working with OpenGL - remove when fixed -#if defined(OPENGL) - bTiledDeferredShading = false; -#endif //defined(OPENGL) - - // determine if we have a global cubemap in the scene - SRenderLight* pGlobalCubemap = NULL; - AZ_PUSH_DISABLE_WARNING(, "-Wconstant-logical-operand") - if (rDeferredCubemaps.Num() && CRenderer::CV_r_DeferredShadingEnvProbes) - AZ_POP_DISABLE_WARNING - { - SRenderLight& pFirstLight = rDeferredCubemaps[0]; - ITexture* pDiffuseCubeCheck = pFirstLight.GetDiffuseCubemap(); - float fRadius = pFirstLight.m_fRadius; - - if (pDiffuseCubeCheck && fRadius >= 100000.f) - { - pGlobalCubemap = &pFirstLight; - ++nCurrentDeferredCubemap; - } - } - - if (!bTiledDeferredShading) - { - if (CRenderer::CV_r_DeferredShadingAmbient && AmbientPass(pGlobalCubemap, bOutdoorVisible)) - { - m_nLightsProcessedCount++; - } - - DeferredCubemaps(rDeferredCubemaps, nCurrentDeferredCubemap); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingAmbientLights) - { - DeferredLights(rDeferredAmbientLights, false); - } - - ApplySSReflections(); // TODO: Try to merge with another pass - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, 1.0f, false); - } - - if (CRenderer::CV_r_DeferredShadingLights && !bTiledDeferredShading) - { - DeferredLights(rDeferredLights, true); - } - - // SSAO affects all light accumulation. Todo: batch into deferred shading pass. - AmbientOcclusionPasses(); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingScissor) - { - rd->EF_Scissor(false, 0, 0, 0, 0); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - rd->SetDepthBoundTest(0.0f, 1.0f, false); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_Unlit) - { - rd->FX_ClearTarget(m_pLBufferDiffuseRT, Clr_MedianHalf); - rd->FX_ClearTarget(m_pLBufferSpecularRT, Clr_Transparent); - rd->FX_ClearTarget(&gcpRendD3D->m_DepthBufferOrigMSAA, CLEAR_STENCIL, Clr_Unused.r, 0); - - } - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Commit any potential render target changes - required for deprecated platform resolves, do not remove this plz. - rd->FX_SetActiveRenderTargets(false); - - rd->FX_PopRenderTarget(0); - rd->FX_PopRenderTarget(1); - m_bSpecularState = false; - - // Water volume caustics not supported in GMEM paths - rd->FX_WaterVolumesCaustics(); - } - - if (bTiledDeferredShading) - { - gcpRendD3D->GetTiledShading().Render(rDeferredCubemaps, rDeferredAmbientLights, rDeferredLights, m_vClipVolumeParams); - - if (CRenderer::CV_r_DeferredShadingSSS) // Explicitly disabling deferred SSS has its incompatible with msaa in current stage - { - DeferredSubsurfaceScattering(CTexture::s_ptexSceneTargetR11G11B10F[0]); - } - - FurPasses::GetInstance().ExecuteObliteratePass(); - } - else - { - // GPU light culling - if (CRenderer::CV_r_DeferredShadingTiled == 1) - { - // Sort cubemaps in inverse order for tiled forward shading - std::sort(rDeferredCubemaps.begin(), rDeferredCubemaps.end(), CubemapsCompareInv()); - - gcpRendD3D->GetTiledShading().Render(rDeferredCubemaps, rDeferredAmbientLights, rDeferredLights, m_vClipVolumeParams); - } - - DeferredShadingPass(); - } - - rd->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - -#ifndef _RELEASE - if (CRenderer::CV_r_DeferredShadingDebugGBuffer) - { - DebugGBuffer(); - } -#endif - - DebugShadowMaskClear(); - - // Commit any potential render target changes - required for when shadows disabled - rd->FX_SetActiveRenderTargets(false); - - rd->m_RP.m_FlagsShader_RT = nFlagsShaderRT; - rd->m_RP.m_PersFlags2 &= ~RBPF2_WRITEMASK_RESERVED_STENCIL_BIT; - - rd->FX_ResetPipe(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::Release() -{ - DestroyDeferredMaps(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::GetScissors(const Vec3& vCenter, float fRadius, short& sX, short& sY, short& sWidth, short& sHeight) const -{ - Vec3 vViewVec = vCenter - gcpRendD3D->GetCamera().GetPosition(); - float fDistToLS = vViewVec.GetLength(); - - bool bInsideLightVolume = fDistToLS <= fRadius; - if (bInsideLightVolume) - { - sX = sY = 0; - sWidth = gcpRendD3D->GetWidth(); - sHeight = gcpRendD3D->GetHeight(); - return; - } - - Matrix44 mProj, mView; - gcpRendD3D->GetProjectionMatrix(mProj.GetData()); - gcpRendD3D->GetModelViewMatrix(mView.GetData()); - - Vec3 pBRectVertices[4]; - Vec4 vCenterVS = Vec4(vCenter, 1) * mView; - - { - // Compute tangent planes - float r = fRadius; - float sq_r = r * r; - - Vec3 vLPosVS = Vec3(vCenterVS.x, vCenterVS.y, vCenterVS.z); - float lx = vLPosVS.x; - float ly = vLPosVS.y; - float lz = vLPosVS.z; - float sq_lx = lx * lx; - float sq_ly = ly * ly; - float sq_lz = lz * lz; - - // Compute left and right tangent planes to light sphere - float sqrt_d = sqrt_tpl(max(sq_r * sq_lx - (sq_lx + sq_lz) * (sq_r - sq_lz), 0.0f)); - float nx = (r * lx + sqrt_d) / (sq_lx + sq_lz); - float nz = iszero(lz) ? 1.0f : (r - nx * lx) / lz; - - Vec3 vTanLeft = Vec3(nx, 0, nz).normalized(); - - nx = (r * lx - sqrt_d) / (sq_lx + sq_lz); - nz = iszero(lz) ? 1.0f : (r - nx * lx) / lz; - Vec3 vTanRight = Vec3(nx, 0, nz).normalized(); - - pBRectVertices[0] = vLPosVS - r * vTanLeft; - pBRectVertices[1] = vLPosVS - r * vTanRight; - - // Compute top and bottom tangent planes to light sphere - sqrt_d = sqrt_tpl(max(sq_r * sq_ly - (sq_ly + sq_lz) * (sq_r - sq_lz), 0.0f)); - float ny = (r * ly - sqrt_d) / (sq_ly + sq_lz); - nz = iszero(lz) ? 1.0f : (r - ny * ly) / lz; - Vec3 vTanBottom = Vec3(0, ny, nz).normalized(); - - ny = (r * ly + sqrt_d) / (sq_ly + sq_lz); - nz = iszero(lz) ? 1.0f : (r - ny * ly) / lz; - Vec3 vTanTop = Vec3(0, ny, nz).normalized(); - - pBRectVertices[2] = vLPosVS - r * vTanTop; - pBRectVertices[3] = vLPosVS - r * vTanBottom; - } - - Vec2 vPMin = Vec2(1, 1); - Vec2 vPMax = Vec2(0, 0); - Vec2 vMin = Vec2(1, 1); - Vec2 vMax = Vec2(0, 0); - - // Project all vertices - for (int i = 0; i < 4; i++) - { - Vec4 vScreenPoint = Vec4(pBRectVertices[i], 1.0) * mProj; - - //projection space clamping - vScreenPoint.w = max(vScreenPoint.w, 0.00000000000001f); - vScreenPoint.x = max(vScreenPoint.x, -(vScreenPoint.w)); - vScreenPoint.x = min(vScreenPoint.x, vScreenPoint.w); - vScreenPoint.y = max(vScreenPoint.y, -(vScreenPoint.w)); - vScreenPoint.y = min(vScreenPoint.y, vScreenPoint.w); - - //NDC - vScreenPoint /= vScreenPoint.w; - - //output coords - //generate viewport (x=0,y=0,height=1,width=1) - Vec2 vWin; - vWin.x = (1.0f + vScreenPoint.x) * 0.5f; - vWin.y = (1.0f + vScreenPoint.y) * 0.5f; //flip coords for y axis - - assert(vWin.x >= 0.0f && vWin.x <= 1.0f); - assert(vWin.y >= 0.0f && vWin.y <= 1.0f); - - // Get light sphere screen bounds - vMin.x = min(vMin.x, vWin.x); - vMin.y = min(vMin.y, vWin.y); - vMax.x = max(vMax.x, vWin.x); - vMax.y = max(vMax.y, vWin.y); - } - - float fWidth = (float)gcpRendD3D->GetWidth(); - float fHeight = (float)gcpRendD3D->GetHeight(); - - sX = (short)(vMin.x * fWidth); - sY = (short)((1.0f - vMax.y) * fHeight); - sWidth = (short)ceilf((vMax.x - vMin.x) * fWidth); - sHeight = (short)ceilf((vMax.y - vMin.y) * fHeight); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::SetupScissors(bool bEnable, uint16 x, uint16 y, uint16 w, uint16 h) const -{ - gcpRendD3D->EF_Scissor(bEnable, x, y, w, h); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::CalculateLightScissorBounds() -{ - // Update our light scissor bounds. - for (int lightType=0; lightType& lightArray = m_pLights[lightType][m_nThreadID][m_nRecurseLevel]; - for (uint32 nCurrentLight = 0; nCurrentLight < lightArray.Num(); ++nCurrentLight) - { - SRenderLight& light = lightArray[nCurrentLight]; - light.CalculateScissorRect(); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::Debug() -{ - uint64 nFlagsShaderRT = gcpRendD3D->m_RP.m_FlagsShader_RT; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingDebug == 2) - { - SD3DPostEffectsUtils::ShBeginPass(m_pShader, m_pDebugTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - gcpRendD3D->FX_SetState(GS_NODEPTHTEST); - m_pLBufferDiffuseRT->Apply(0, m_nTexStatePoint); - SD3DPostEffectsUtils::SetTexture( CTextureManager::Instance()->GetDefaultTexture("PaletteDebug"), 1, FILTER_LINEAR, 1); - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(m_pLBufferDiffuseRT->GetWidth(), m_pLBufferDiffuseRT->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - } - - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::DebugGBuffer() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - static CCryNameTSCRC techShadingDebug("DebugGBuffer"); - - CTexture* dstTex = CTexture::s_ptexStereoR; - - m_pDepthRT->Apply(0, m_nTexStatePoint); - m_pNormalsRT->Apply(1, m_nTexStatePoint); - m_pDiffuseRT->Apply(2, m_nTexStatePoint); - m_pSpecularRT->Apply(3, m_nTexStatePoint); - - rd->FX_SetState(GS_NODEPTHTEST); - - rd->FX_PushRenderTarget(0, dstTex, NULL); - SD3DPostEffectsUtils::ShBeginPass(m_pShader, techShadingDebug, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - static CCryNameR paramName("DebugViewMode"); - Vec4 param(CRenderer::CV_r_DeferredShadingDebugGBuffer, 0, 0, 0); - m_pShader->FXSetPSFloat(paramName, ¶m, 1); - SD3DPostEffectsUtils::DrawFullScreenTri(dstTex->GetWidth(), dstTex->GetHeight()); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CDeferredShading::SetSSDOParameters(const int texSlot) -{ - if (CRenderer::CV_r_ssdo) - { - Vec4 ssdoParams(CRenderer::CV_r_ssdoAmountDirect, CRenderer::CV_r_ssdoAmountAmbient, CRenderer::CV_r_ssdoAmountReflection, 0); - static CCryNameR ssdoParamsName("SSDOParams"); - m_pShader->FXSetPSFloat(ssdoParamsName, &ssdoParams, 1); - CTexture::s_ptexSceneNormalsBent->Apply(texSlot, m_nTexStatePoint); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// Utility function for setting up and binding textures. -// Calculates and sets texture transforms as well as mipLevel -// If the ESetTexture_MipFactorProvided flag is set, the passed in mipLevelFactor will be used -// If it isn't set, mipLevelFactor will be calculated and output for possible reuse with other textures -ITexture* CDeferredShading::SetTexture(const SShaderItem& sItem, EEfResTextures tex, int slot, const RectF texRect, float surfaceSize, float& mipLevelFactor, int flags) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - AZ_Assert(0 <= slot, "Texture slot index must be positive"); - AZ_Assert(slot < EMaxTextureSlots, "Only %d texture slots available", int(EMaxTextureSlots)); - AZ_Assert(texRect.w * texRect.h > 0.f, "Texture rect has invalid dimensions"); - - ITexture* pTexture = nullptr; - - if (SEfResTexture* pResTexture = sItem.m_pShaderResources->GetTextureResource((uint16)tex)) - { - if (pResTexture->m_Sampler.m_pITex) - { - pTexture = pResTexture->m_Sampler.m_pITex; - - // Shader HWSR_SAMPLE flag - if (flags & ESetTexture_HWSR) - { - // Asserts - const static int maxHWSRSample = HWSR_SAMPLE5; - static_assert((maxHWSRSample + 1) == HWSR_DEBUG0, "HWSR_SAMPLE5 is no longer the last HWSR_SAMPLE"); // If this assert triggers please ensure HWSR_SAMPLE5 is the last HWSR_SAMPLE - AZ_Assert(slot <= (maxHWSRSample - HWSR_SAMPLE0), "Slot index too big to set HWSR_SAMPLE"); - - // Set HWSR slot - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0 + slot]; - } - - // Texture transform - if (flags & ESetTexture_Transform) - { - // Texture matrix - Matrix44 texMatrix; - if (pResTexture->IsHasModificators()) - { - pResTexture->UpdateWithModifier(tex); - texMatrix = pResTexture->m_Ext.m_pTexModifier->m_TexMatrix; - } - else - { - texMatrix.SetIdentity(); - } - - // If mip level factor not provided, calculate it - if (!(flags & ESetTexture_MipFactorProvided)) - { - // tan(fov) * (textureSize * tiling / decalSize) * distance - // MipLevel = log2 -------------------------------------------------------- - // screenResolution * dot(viewVector, decalNormal) - - const float screenRes = (float)rd->GetWidth() * 0.5f + (float)rd->GetHeight() * 0.5f; - const float texScale = max(texMatrix.GetColumn(0).GetLength() * texRect.w, texMatrix.GetColumn(1).GetLength() * texRect.h); - mipLevelFactor = (tan(rd->GetCamera().GetFov()) * texScale) / (surfaceSize * screenRes); - } - float fMipLevel = mipLevelFactor * (float)max(pTexture->GetWidth(), pTexture->GetHeight()); - - // Set transform (don't forget to bind m_vTextureTransforms after calls to this function) - m_vTextureTransforms[slot][0] = Vec4(texRect.w * texMatrix.m00, texRect.h * texMatrix.m10, texRect.x * texMatrix.m00 + texRect.y * texMatrix.m10 + texMatrix.m30, fMipLevel); - m_vTextureTransforms[slot][1] = Vec4(texRect.w * texMatrix.m01, texRect.h * texMatrix.m11, texRect.x * texMatrix.m01 + texRect.y * texMatrix.m11 + texMatrix.m31, 0.0f); - } - else if (flags & ESetTexture_MipFactorProvided) - { - // Mip level - float fMipLevel = mipLevelFactor * (float)max(pTexture->GetWidth(), pTexture->GetHeight()); - m_vTextureTransforms[slot][0].w = fMipLevel; - } - - // Texture state - STexState texState; - texState.SetFilterMode(FILTER_TRILINEAR); - texState.m_bSRGBLookup = (flags & ESetTexture_bSRGBLookup) != 0; - texState.SetClampMode( pResTexture->m_bUTile ? TADDR_WRAP : TADDR_CLAMP, - pResTexture->m_bVTile ? TADDR_WRAP : TADDR_CLAMP, - TADDR_CLAMP); - - // Set Texture - ((CTexture*)pTexture)->Apply(slot, CTexture::GetTexState(texState)); - } - } - - // Default texture - if ((flags & ESetTexture_AllowDefault) && (pTexture == nullptr)) - { - ITexture* pTex = TextureHelpers::LookupTexDefault(tex); - SD3DPostEffectsUtils::SetTexture((CTexture*)pTex, slot, FILTER_TRILINEAR, 0); - } - - return pTexture; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -uint32 CRenderer::EF_GetDeferredLightsNum(const eDeferredLightType eLightType /*= eDLT_DeferredLight*/) -{ - return CDeferredShading::Instance().GetLightsNum(eLightType); -} - -TArray* CRenderer::EF_GetDeferredLights(const SRenderingPassInfo& passInfo, const eDeferredLightType eLightType /*= eDLT_DeferredLight*/) -{ - uint32 nThreadID = passInfo.ThreadID(); - int32 nRecurseLevel = passInfo.GetRecursiveLevel(); - -#ifndef _RELEASE - if (nRecurseLevel < 0) - { - __debugbreak(); - } -#endif - - return &CDeferredShading::Instance().GetLights(nThreadID, nRecurseLevel, eLightType); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -int CRenderer::EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) -{ - int nLightID = -1; - CDeferredShading& pDS = CDeferredShading::Instance(); - nLightID = pDS.AddLight(pLight, fMult, passInfo, rendItemSorter); - - int nThreadID = m_RP.m_nFillThreadID; - float mipFactor = (m_RP.m_TI[nThreadID].m_cam.GetPosition() - pLight.m_Origin).GetLengthSquared() / max(0.001f, pLight.m_fRadius * pLight.m_fRadius); - EF_PrecacheResource(const_cast(&pLight), mipFactor, 0.1f, FPR_STARTLOADING, gRenDev->m_RP.m_TI[nThreadID].m_arrZonesRoundId[1]); - return nLightID; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CRenderer::EF_ClearDeferredLightsList() -{ - if (CDeferredShading::IsValid()) - { - CDeferredShading::Instance().ResetLights(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CRenderer::EF_ReleaseDeferredData() -{ - if (CDeferredShading::IsValid()) - { - CDeferredShading::Instance().ReleaseData(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CRenderer::EF_ClearDeferredClipVolumesList() -{ - if (CDeferredShading::IsValid()) - { - CDeferredShading::Instance().ResetClipVolumes(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -uint8 CRenderer::EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) -{ - if (CDeferredShading::IsValid() && pClipVolume) - { - return CDeferredShading::Instance().AddClipVolume(pClipVolume); - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool CRenderer::EF_SetDeferredClipVolumeBlendData(const IClipVolume* pVolume, const SClipVolumeBlendInfo& blendInfo) -{ - if (CDeferredShading::IsValid()) - { - return CDeferredShading::Instance().SetClipVolumeBlendData(pVolume, blendInfo); - } - - return false; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -SRenderLight* CRenderer::EF_GetDeferredLightByID(const uint16 nLightID, const eDeferredLightType eLightType) -{ - return CDeferredShading::Instance().GetLightByID(nLightID, eLightType); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_DeferredRendering(bool bDebugPass, bool bUpdateRTOnly) -{ - CDeferredShading& pDS = CDeferredShading::Instance(); - - if (!CTexture::s_ptexSceneTarget) - { - pDS.Release(); - return false; - } - - if (bUpdateRTOnly) - { - pDS.CreateDeferredMaps(); - return true; - } - - if (!bDebugPass) - { - pDS.Render(); - } - else - { - pDS.Debug(); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool IsDeferredDecalsSupported() -{ - bool isSupported = true; - // For deferred decals we need to access the Normals and Linearize Depth. In GMEM both textures are bound as RT at this point. - // Check if we can access both of them to see if we support Deferred Decals. - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - RenderCapabilities::FrameBufferFetchMask capabilities = RenderCapabilities::GetFrameBufferFetchCapabilities(); - isSupported = (capabilities.test(RenderCapabilities::FBF_ALL_COLORS)) || // We can access to the Normals and Linearize depth render targets directly. - ((capabilities.test(RenderCapabilities::FBF_COLOR0)) && (capabilities.test(RenderCapabilities::FBF_DEPTH))); // Normals are in COLOR0 and with access to the Depth buffer we can linearize in the shader. - } - - return isSupported; -} - -bool CD3D9Renderer::FX_DeferredDecals() -{ - if IsCVarConstAccess(constexpr) (!CV_r_deferredDecals) - { - return false; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - uint32 nThreadID = rd->m_RP.m_nProcessThreadID; - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nRecurseLevel >= 0); - - DynArray& deferredDecals = rd->m_RP.m_DeferredDecals[nThreadID][nRecurseLevel]; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - // Want the buffer cleared or we'll just get black out - if (deferredDecals.empty()) - { - return false; - } -#endif - - if (!IsDeferredDecalsSupported()) - { - AZ_Warning("Rendering", false, "Deferred decals is not supported in the current configuration"); - return false; - } - - PROFILE_LABEL_SCOPE("DEFERRED_DECALS"); - - CDeferredShading& rDS = CDeferredShading::Instance(); - rDS.SetupPasses(); - - if (eGT_256bpp_PATH == gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && CRenderer::CV_r_DeferredShadingLBuffersFmt != 2) - { - // GMEM 256bpp path copies normals temporarily to the diffuse light buffer (rgba16) if it exists. - uint32 prevState = m_RP.m_CurState; - uint32 newState = 0; - FX_SetState(newState); - SD3DPostEffectsUtils::PrepareGmemDeferredDecals(); - FX_SetState(prevState); - } - else if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - ID3D11Texture2D* pBBRes = CTexture::s_ptexBackBuffer->GetDevTexture()->Get2DTexture(); - ID3D11Texture2D* pNMRes = NULL; - - assert(CTexture::s_ptexBackBuffer->m_pPixelFormat->DeviceFormat == CTexture::s_ptexSceneNormalsMap->m_pPixelFormat->DeviceFormat); - - if (rd->m_RP.m_MSAAData.Type > 1) //always copy when deferredDecals is not empty - { - pNMRes = (D3DTexture*)CTexture::s_ptexSceneNormalsMap->m_pRenderTargetData->m_pDeviceTextureMSAA->Get2DTexture(); - rd->GetDeviceContext().ResolveSubresource(pBBRes, 0, pNMRes, 0, (DXGI_FORMAT)CTexture::s_ptexBackBuffer->m_pPixelFormat->DeviceFormat); - } - else - { - pNMRes = CTexture::s_ptexSceneNormalsMap->GetDevTexture()->Get2DTexture(); - rd->GetDeviceContext().CopyResource(pBBRes, pNMRes); - } - } - - std::stable_sort(deferredDecals.begin(), deferredDecals.end(), DeffDecalSort()); - - //if (CV_r_deferredDecalsDebug == 0) - // rd->FX_PushRenderTarget(1, CTexture::s_ptexSceneNormalsMap, NULL); - - const uint32 nNumDecals = deferredDecals.size(); - for (uint32 d = 0; d < nNumDecals; ++d) - { - rDS.DeferredDecalPass(deferredDecals[d], d); - } - - //if (CV_r_deferredDecalsDebug == 0) - // rd->FX_PopRenderTarget(1); - - rd->SetCullMode(R_CULL_BACK); - - // Commit any potential render target changes - required for when shadows disabled - rd->FX_SetActiveRenderTargets(false); - rd->FX_ResetPipe(); - - return true; -} - -// Renders emissive part of all deferred decals -// This is called after the deferred lighting resolve since emissive -// lighting is additive in relation to diffuse and specular -// Called by CD3D9Renderer::FX_RenderForwardOpaque -bool CD3D9Renderer::FX_DeferredDecalsEmissive() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if IsCVarConstAccess(constexpr) (!CV_r_deferredDecals) - return false; - - if (!IsDeferredDecalsSupported()) - { - return false; - } - - uint32 nThreadID = rd->m_RP.m_nProcessThreadID; - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nRecurseLevel >= 0); - - DynArray& deferredDecals = rd->m_RP.m_DeferredDecals[nThreadID][nRecurseLevel]; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DDEFERREDSHADING_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(D3DDeferredShading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - // Want the buffer cleared or we'll just get black out - if (deferredDecals.empty()) - { - return false; - } -#endif - - PROFILE_LABEL_SCOPE("DEFERRED_DECALS"); - - CDeferredShading& rDS = CDeferredShading::Instance(); - - const uint32 nNumDecals = deferredDecals.size(); - for (uint32 d = 0; d < nNumDecals; ++d) - { - rDS.DeferredDecalEmissivePass(deferredDecals[d], d); - } - - rd->SetCullMode(R_CULL_BACK); - - // Commit any potential render target changes - required for when shadows disabled - rd->FX_SetActiveRenderTargets(false); - rd->FX_ResetPipe(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CREDeferredShading::mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - if (gcpRendD3D->m_bDeviceLost) - { - return 0; - } - - gcpRendD3D->FX_DeferredRendering(); - return true; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.h deleted file mode 100644 index 3837a1740c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DDeferredShading.h +++ /dev/null @@ -1,508 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DDEFERREDSHADING_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DDEFERREDSHADING_H -#pragma once -struct IVisArea; - -enum EDecalType -{ - DTYP_DARKEN, - DTYP_BRIGHTEN, - DTYP_ALPHABLEND, - DTYP_ALPHABLEND_AND_BUMP, - DTYP_ALPHABLEND_SPECULAR, - DTYP_DARKEN_LIGHTBUF, - DTYP_NUM, -}; - -#define MAX_DEFERRED_CLIP_VOLUMES 64 -// Note: 2 stencil values reserved for stencil+outdoor fragments -#define VIS_AREAS_OUTDOOR_STENCIL_OFFSET 2 - -class CTexPoolAtlas; - -struct SShadowAllocData -{ - int m_lightID; - uint16 m_blockID; - uint8 m_side; - uint8 m_frameID; - - void Clear(){ m_blockID = 0xFFFF; m_lightID = -1; m_frameID = 0; } - bool isFree() { return (m_blockID == 0xFFFF) ? true : false; } - - SShadowAllocData(){ Clear(); } - ~SShadowAllocData(){ Clear(); } -}; - -class CDeferredShading -{ -public: - - static inline bool IsValid() - { - return m_pInstance != NULL; - } - - static CDeferredShading& Instance() - { - return (*m_pInstance); - } - - void Render(); - void SetupPasses(); - void SetupGlobalConsts(); - - - // This will setup shadows and sort lights. - // It is called before Z-Pass and is used so that we don't have - // to resolve any buffers because of shadows setup during deferred passes. - void SetupGmemPath(); - - - //shadows - void ResolveCurrentBuffers(); - void RestoreCurrentBuffers(); - bool PackAllShadowFrustums(TArray& arrLights, bool bPreLoop); - void DebugShadowMaskClear(); - bool PackToPool(CPowerOf2BlockPacker* pBlockPack, SRenderLight& light, bool bClearPool); - - void FilterGBuffer(); - void AmbientOcclusionPasses(); - void PrepareClipVolumeData(bool& bOutdoorVisible); - void RenderClipVolumesToStencil(int nStencilInsideBit); - void RenderPortalBlendValues(int nStencilInsideBit); - bool AmbientPass(SRenderLight* pGlobalCubemap, bool& bOutdoorVisible); - - bool DeferredDecalPass(const SDeferredDecal& rDecal, uint32 indDecal); - void DeferredDecalEmissivePass(const SDeferredDecal& rDecal, uint32 indDecal); - bool ShadowLightPasses(const SRenderLight& light); - void DrawDecalVolume(const SDeferredDecal& rDecal, Matrix44A& mDecalLightProj, ECull volumeCull); - void DrawLightVolume(EShapeMeshType meshType, const Matrix44& mVolumeToWorld, const Vec4& vSphereAdjust = Vec4(ZERO)); - void LightPass(const SRenderLight* const __restrict pDL, bool bForceStencilDisable = false); - void DeferredCubemaps(const TArray& rCubemaps, const uint32 nStartIndex = 0); - void DeferredCubemapPass(const SRenderLight* const __restrict pDL); - void ScreenSpaceReflectionPass(); - void ApplySSReflections(); - void DirectionalOcclusionPass(); - void HeightMapOcclusionPass(ShadowMapFrustum*& pHeightMapFrustum, CTexture*& pHeightMapAOScreenDepth, CTexture*& pHeightmapAO); - void DeferredLights(TArray& rLights, bool bCastShadows); - - void DeferredSubsurfaceScattering(CTexture* tmpTex); - void DeferredShadingPass(); - - void CreateDeferredMaps(); - void DestroyDeferredMaps(); - void Release(); - void Debug(); - void DebugGBuffer(); - - //! Adds a light to the list of lights to be rendered. - //! \param pDL Light to be rendered - //! \param fMult Multiplier that will be applied to the light's intensity. For example, use this to fade out lights as they exceed distance thresholds. - //! \param passInfo Standard SRenderingPassInfo, send to EF_AddEf() - //! \param rendItemSorter Standard SRendItemSorter, send to EF_AddEf() - uint32 AddLight(const CDLight& pDL, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter); - - inline uint8 AddClipVolume(const IClipVolume* pClipVolume); - inline bool SetClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo); - - inline void ResetLights(); - inline void ResetClipVolumes(); - - // Renderer must be flushed - void ResetAllLights(); - void ResetAllClipVolumes(); - - // called in between levels to free up memory - void ReleaseData(); - - TArray& GetLights(const int nThreadID, const int nCurRecLevel, const eDeferredLightType eType = eDLT_DeferredLight); - SRenderLight* GetLightByID(const uint16 nLightID, const eDeferredLightType eType = eDLT_DeferredLight); - uint32 GetLightsNum(const eDeferredLightType eType); - void GetClipVolumeParams(const Vec4*& pParams, uint32& nCount); - CTexture* GetResolvedStencilRT() { return m_pResolvedStencilRT; } - void GetLightRenderSettings(const SRenderLight* const __restrict pDL, bool& bStencilMask, bool& bUseLightVolumes, EShapeMeshType& meshType); - - inline uint32 GetLightsCount() const - { - return m_nLightsProcessedCount; - } - - inline Vec4 GetLightDepthBounds(const SRenderLight* pDL, bool bReverseDepth) const - { - float fRadius = pDL->m_fRadius; - if (pDL->m_Flags & DLF_AREA_LIGHT) // Use max for area lights. - { - fRadius += max(pDL->m_fAreaWidth, pDL->m_fAreaHeight); - } - else if (pDL->m_Flags & DLF_DEFERRED_CUBEMAPS) - { - fRadius = pDL->m_ProbeExtents.len(); // This is not optimal for a box - } - return GetLightDepthBounds(pDL->m_Origin, fRadius, bReverseDepth); - } - - inline Vec4 GetLightDepthBounds(const Vec3& vCenter, float fRadius, bool bReverseDepth) const - { - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_DeferredShadingDepthBoundsTest) - { - return Vec4(0.0f, 0.0f, 1.0f, 1.0f); - } - - float fMinZ = 0.0f, fMaxZ = 1.0f; - float fMinW = 0.0f, fMaxW = 1.0f; - - Vec3 pBounds = m_pCamFront * fRadius; - Vec3 pMax = vCenter - pBounds; - Vec3 pMin = vCenter + pBounds; - - fMinZ = m_mViewProj.m20 * pMin.x + m_mViewProj.m21 * pMin.y + m_mViewProj.m22 * pMin.z + m_mViewProj.m23; - fMinW = m_mViewProj.m30 * pMin.x + m_mViewProj.m31 * pMin.y + m_mViewProj.m32 * pMin.z + m_mViewProj.m33; - - float fMinDivisor = (float)fsel(-fabsf(fMinW), 1.0f, fMinW); - fMinZ = (float)fsel(-fabsf(fMinW), 1.0f, fMinZ / fMinDivisor); - fMinZ = (float)fsel(fMinW, fMinZ, bReverseDepth ? 1.0f : 0.0f); - - - fMaxZ = m_mViewProj.m20 * pMax.x + m_mViewProj.m21 * pMax.y + m_mViewProj.m22 * pMax.z + m_mViewProj.m23; - fMaxW = m_mViewProj.m30 * pMax.x + m_mViewProj.m31 * pMax.y + m_mViewProj.m32 * pMax.z + m_mViewProj.m33; - float fMaxDivisor = (float)fsel(-fabsf(fMaxW), 1.0f, fMaxW); - fMaxZ = (float)fsel(-fabsf(fMaxW), 1.0f, fMaxZ / fMaxDivisor); - fMaxZ = (float)fsel(fMaxW, fMaxZ, bReverseDepth ? 1.0f : 0.0f); - - if (bReverseDepth) - { - std::swap(fMinZ, fMaxZ); - } - - fMinZ = clamp_tpl(fMinZ, 0.000001f, 1.f); - fMaxZ = clamp_tpl(fMaxZ, fMinZ, 1.f); - - return Vec4(fMinZ, max(fMinW, 0.000001f), fMaxZ, max(fMaxW, 0.000001f)); - } - - void GetScissors(const Vec3& vCenter, float fRadius, short& sX, short& sY, short& sWidth, short& sHeight) const; - void SetupScissors(bool bEnable, uint16 x, uint16 y, uint16 w, uint16 h) const; - - // Calculate the individual screen-space scissor bounds for all of our bound lights - void CalculateLightScissorBounds(); - - const Matrix44A& GetCameraProjMatrix() const { return m_mViewProj; } - - void SortLigths(TArray& ligths) const; - -private: - void SetSSDOParameters(const int texSlot); - ITexture* SetTexture(const SShaderItem& sItem, EEfResTextures tex, int slot, const RectF texRect, float surfaceSize, float& mipLevelFactor, int flags); - - // Flags used for the above SetTexture function - enum ESetTextureFlags : uint32 - { - ESetTexture_Transform = 1 << 0, // Will calculate 2 Vec3s used for transforming tex coords in the shader - ESetTexture_HWSR = 1 << 1, // Will set the HWSR_SAMPLE flag for the specified slot - ESetTexture_bSRGBLookup = 1 << 2, // Value to set on the STexState - ESetTexture_AllowDefault = 1 << 3, // Whether a default texture should be used as backup - ESetTexture_MipFactorProvided = 1 << 4, // Whether to use the mipLevelFactor provide or calculate our own and output it to the same parameter - }; - - enum - { - // Number of textures available in PostEffectsLib.cfi (_tex0 to _texF) - EMaxTextureSlots = 16, - }; - - CDeferredShading() - { - m_pShader = 0; - m_pTechName = "DeferredLightPass"; - m_pAmbientOutdoorTechName = "AmbientPass"; - m_pCubemapsTechName = "DeferredCubemapPass"; - m_pCubemapsVolumeTechName = "DeferredCubemapVolumePass"; - m_pReflectionTechName = "SSR_Raytrace"; - m_pDebugTechName = "Debug"; - m_pDeferredDecalTechName = "DeferredDecal"; - m_pLightVolumeTechName = "DeferredLightVolume"; - - m_pParamLightPos = "g_LightPos"; - m_pParamLightProjMatrix = "g_mLightProj"; - m_pGeneralParams = "g_GeneralParams"; - m_pParamLightDiffuse = "g_LightDiffuse"; - - m_pParamAmbient = "g_cDeferredAmbient"; - m_pParamAmbientGround = "g_cAmbGround"; - m_pParamAmbientHeight = "g_vAmbHeightParams"; - - m_pAttenParams = "g_vAttenParams"; - - m_pParamDecalTS = "g_mDecalTS"; - m_pParamDecalDiffuse = "g_DecalDiffuse"; - m_pParamDecalAngleAttenuation = "g_DecalAngleAttenuation"; - m_pParamDecalSpecular = "g_DecalSpecular"; - m_pParamDecalMipLevels = "g_DecalMipLevels"; - m_pParamDecalEmissive = "g_DecalEmissive"; - m_pParamTexTransforms = "g_texTransforms"; - m_pClipVolumeParams = "g_vVisAreasParams"; - - m_pLBufferDiffuseRT = CTexture::s_ptexCurrentSceneDiffuseAccMap; - m_pLBufferSpecularRT = CTexture::s_ptexSceneSpecularAccMap; - m_pNormalsRT = CTexture::s_ptexSceneNormalsMap; - m_pDepthRT = CTexture::s_ptexZTarget; - m_pMSAAMaskRT = CTexture::s_ptexBackBuffer; - m_pResolvedStencilRT = CTexture::s_ptexStereoR; - - m_pDiffuseRT = CTexture::s_ptexSceneDiffuse; - m_pSpecularRT = CTexture::s_ptexSceneSpecular; - - memset(m_vClipVolumeParams, 0, sizeof(Vec4) * (MAX_DEFERRED_CLIP_VOLUMES)); - - m_nLightsProcessedCount = 0; - - m_nCurLighID = -1; - - m_nWarningFrame = 0; - - m_bSpecularState = false; - - m_nShadowPoolSize = 0; - - for (int i = 0; i < MAX_GPU_NUM; ++i) - { - m_prevViewProj[i].SetIdentity(); - } - - m_nRenderState = GS_BLSRC_ONE | GS_BLDST_ONE; - - m_nTexStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - m_nTexStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - - m_nThreadID = 0; - m_nRecurseLevel = 0; - - m_nBindResourceMsaa = -1; - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - m_nClipVolumesCount[i][j] = 0; - m_nVisAreasGIRef[i][j] = 0; - } - } - } - - ~CDeferredShading() - { - Release(); - } - - // Allow disable mrt usage: for double zspeed and on other passes less fillrate hit - // @return - Returns true if either a push or a pop was performed in this function. Returns false if no push or pop was executed. - bool SpecularAccEnableMRT(bool bEnable); - -private: - - struct SVisAreaBlendData - { - uint8 nBlendIDs[SClipVolumeBlendInfo::BlendPlaneCount]; - Vec4 blendPlanes[SClipVolumeBlendInfo::BlendPlaneCount]; - }; - - struct SClipVolumeData - { - SClipVolumeData() - : nStencilRef(0) - , nFlags(0) - , m_pRenderMesh(NULL) - , mAABB(AABB::RESET) - , mWorldTM(IDENTITY) - { - }; - - Matrix34 mWorldTM; - AABB mAABB; - uint8 nStencilRef; - uint8 nFlags; - - _smart_ptr m_pRenderMesh; - SVisAreaBlendData m_BlendData; - }; - - // Vis areas for current view - std::vector m_pClipVolumes[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - - // The 2 is for X and Y axis. In PostEffectsLib.cfi: - // float2x4 g_texTransforms[16]; - Vec4 m_vTextureTransforms[EMaxTextureSlots][2]; - - uint32 m_nClipVolumesCount[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - uint32 m_nVisAreasGIRef[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - - struct SClipShape - { - IRenderMesh* pShape; - Matrix34 mxTransform; - SClipShape() - : pShape(NULL) - , mxTransform(Matrix34::CreateIdentity()) {} - SClipShape(IRenderMesh* _pShape, const Matrix34& _mxTransform) - : pShape(_pShape) - , mxTransform(_mxTransform) { } - }; - - // Clip volumes for GI for current view - TArray m_vecGIClipVolumes[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - - // Deferred passes common - TArray m_pLights[eDLT_NumLightTypes][RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS]; - - Vec3 m_pCamPos; - Vec3 m_pCamFront; - float m_fCamFar; - float m_fCamNear; - - float m_fRatioWidth; - float m_fRatioHeight; - - CShader* m_pShader; - CCryNameTSCRC m_pDeferredDecalTechName; - CCryNameTSCRC m_pLightVolumeTechName; - CCryNameTSCRC m_pTechName; - CCryNameTSCRC m_pAmbientOutdoorTechName; - CCryNameTSCRC m_pCubemapsTechName; - CCryNameTSCRC m_pCubemapsVolumeTechName; - CCryNameTSCRC m_pReflectionTechName; - CCryNameTSCRC m_pDebugTechName; - CCryNameR m_pParamLightPos; - CCryNameR m_pParamLightDiffuse; - CCryNameR m_pParamLightProjMatrix; - CCryNameR m_pGeneralParams; - CCryNameR m_pParamAmbient; - CCryNameR m_pParamAmbientGround; - CCryNameR m_pParamAmbientHeight; - CCryNameR m_pAttenParams; - - CCryNameR m_pParamDecalTS; - CCryNameR m_pParamDecalDiffuse; - CCryNameR m_pParamDecalAngleAttenuation; - CCryNameR m_pParamDecalSpecular; - CCryNameR m_pParamDecalMipLevels; - CCryNameR m_pParamDecalEmissive; - CCryNameR m_pParamTexTransforms; - CCryNameR m_pClipVolumeParams; - - Matrix44A m_mViewProj; - Matrix44A m_pViewProjI; - Matrix44A m_pView; - - Matrix44A m_prevViewProj[MAX_GPU_NUM]; - - Vec4 vWorldBasisX, vWorldBasisY, vWorldBasisZ; - - CTexture* m_pLBufferDiffuseRT; - CTexture* m_pLBufferSpecularRT; - - DEFINE_ALIGNED_DATA(Vec4, m_vClipVolumeParams[MAX_DEFERRED_CLIP_VOLUMES], 16); - - CTexture* m_pDiffuseRT; - CTexture* m_pSpecularRT; - CTexture* m_pNormalsRT; - CTexture* m_pDepthRT; - - CTexture* m_pMSAAMaskRT; - CTexture* m_pResolvedStencilRT; - - int m_nWarningFrame; - - int m_nRenderState; - uint32 m_nLightsProcessedCount; - - uint32 m_nTexStateLinear; - uint32 m_nTexStatePoint; - - SResourceView::KeyType m_nBindResourceMsaa; - - uint32 m_nThreadID; - int32 m_nRecurseLevel; - - uint m_nCurrentShadowPoolLight; - uint m_nFirstCandidateShadowPoolLight; - uint m_nShadowPoolSize; - bool m_bClearPool; - - bool m_bSpecularState; - int m_nCurLighID; - short m_nCurTargetWidth; - short m_nCurTargetHeight; - static CDeferredShading* m_pInstance; - - friend class CTiledShading; - - static StaticInstance m_blockPack; - static TArray m_shadowPoolAlloc; - -public: - static CDeferredShading* CreateDeferredShading() - { - m_pInstance = new CDeferredShading(); - - return m_pInstance; - } - - static void DestroyDeferredShading() - { - SAFE_DELETE(m_pInstance); - } -}; - -class CTexPoolAtlas -{ -public: - CTexPoolAtlas() - { - m_nSize = 0; -#ifdef _DEBUG - m_nTotalWaste = 0; -#endif - } - ~CTexPoolAtlas() {} - void Init(int nSize); - void Clear(); - void FreeMemory(); - bool AllocateGroup(int32* pOffsetX, int32* pOffsetY, int nSizeX, int nSizeY); - - int m_nSize; - static const int MAX_BLOCKS = 128; - uint32 m_arrAllocatedBlocks[MAX_BLOCKS]; - -#ifdef _DEBUG - uint32 m_nTotalWaste; - struct SShadowMapBlock - { - uint16 m_nX1, m_nX2, m_nY1, m_nY2; - bool Intersects(const SShadowMapBlock& b) const - { - return max(m_nX1, b.m_nX1) < min(m_nX2, b.m_nX2) - && max(m_nY1, b.m_nY1) < min(m_nY2, b.m_nY2); - } - }; - std::vector m_arrDebugBlocks; - - void _AddDebugBlock(int x, int y, int sizeX, int sizeY); - float _GetDebugUsage() const; -#endif -}; - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DFXPipeline.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DFXPipeline.cpp deleted file mode 100644 index 319a3ffe76..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DFXPipeline.cpp +++ /dev/null @@ -1,5735 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Direct3D specific FX shaders rendering pipeline. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include -#include -#include "MultiLayerAlphaBlendPass.h" -#include -#include -#include "GraphicsPipeline/FurPasses.h" - -#include "../../Cry3DEngine/Environment/OceanEnvironmentBus.h" - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif - -#include - - - -long CD3D9Renderer::FX_SetVertexDeclaration(int StreamMask, const AZ::Vertex::Format& vertexFormat) -{ - FUNCTION_PROFILER_RENDER_FLAT - HRESULT hr; - - bool bMorph = (StreamMask & VSM_MORPHBUDDY) != 0; - bool bInstanced = (StreamMask & VSM_INSTANCED) != 0; - -#if defined(FEATURE_PER_SHADER_INPUT_LAYOUT_CACHE) - SOnDemandD3DVertexDeclarationCache pDeclCache[1] = { - { NULL } - }; - // (StreamMask & (0xfe | VSM_MORPHBUDDY)) is the value of StreamMask for most cases. There are a few exceptions: - // 0xfe = 1111 1110 so the result is 0 in the case of VSM_GENERAL (1), or 0 if the mask bit is greater than 8 bits unless StreamMask happens to be VSM_MORPHBUDDY, in which case the result is again the value of StreamMask - // At the time of this comment, that means the portion of the cacheID determined by StreamMask will be the same for VSM_GENERAL as it will be for VSM_INSTANCED, or anything that may come after VSM_INSTANCED - uint64 cacheID = static_cast(StreamMask & (0xfe | VSM_MORPHBUDDY)) ^ (static_cast(vertexFormat.GetEnum()) << 32); - if (CHWShader_D3D::s_pCurInstVS) - { - pDeclCache->m_pDeclaration = CHWShader_D3D::s_pCurInstVS->GetCachedInputLayout(cacheID); - } -#else - AZ::u32 declCacheKey = vertexFormat.GetEnum(); - if (CHWShader_D3D::s_pCurInstVS) - { - declCacheKey = CHWShader_D3D::s_pCurInstVS->GenerateVertexDeclarationCacheKey(vertexFormat); - } - - SOnDemandD3DVertexDeclarationCache* pDeclCache = &m_RP.m_D3DVertexDeclarationCache[(StreamMask & 0xff) >> 1][bMorph || bInstanced][declCacheKey]; - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DFXPipeline_cpp) -#endif -#endif - - if (!pDeclCache->m_pDeclaration) - { - SOnDemandD3DVertexDeclaration Decl; - - EF_OnDemandVertexDeclaration(Decl, (StreamMask & 0xff) >> 1, vertexFormat, bMorph, bInstanced); - if (!Decl.m_Declaration.size()) - { - return S_FALSE; - } - - if (!CHWShader_D3D::s_pCurInstVS || !CHWShader_D3D::s_pCurInstVS->m_pShaderData || CHWShader_D3D::s_pCurInstVS->m_bFallback) - { - return (HRESULT)-1; - } - int nSize = CHWShader_D3D::s_pCurInstVS->m_nDataSize; - void* pVSData = CHWShader_D3D::s_pCurInstVS->m_pShaderData; - if (FAILED(hr = GetDevice().CreateInputLayout(&Decl.m_Declaration[0], Decl.m_Declaration.size(), pVSData, nSize, &pDeclCache->m_pDeclaration))) - { -#ifndef _RELEASE - iLog->LogError("Failed to create an input layout for material \"%s\".\nThe shader and the vertex formats may be incompatible.\nVertex format: \"%d\". Shader expects: \"%d\".\n\n", m_RP.m_pShaderResources->m_szMaterialName, (int)vertexFormat.GetEnum(), (int)CHWShader_D3D::s_pCurInstVS->m_vertexFormat.GetEnum()); -#endif - return hr; - } -#if defined(FEATURE_PER_SHADER_INPUT_LAYOUT_CACHE) - CHWShader_D3D::s_pCurInstVS->SetCachedInputLayout(pDeclCache->m_pDeclaration, cacheID); -#endif - } - D3DVertexDeclaration* pD3DDecl = pDeclCache->m_pDeclaration; - if (!CHWShader_D3D::s_pCurInstVS || !CHWShader_D3D::s_pCurInstPS || (CHWShader_D3D::s_pCurInstVS->m_bFallback | CHWShader_D3D::s_pCurInstPS->m_bFallback)) - { - FX_Commit(); - return E_FAIL; - } - - if (m_pLastVDeclaration != pD3DDecl) - { - // Don't set input layout on fallback shader (crashes in DX11 NV driver) - if (!CHWShader_D3D::s_pCurInstVS || CHWShader_D3D::s_pCurInstVS->m_bFallback) - { - return (HRESULT)-1; - } - m_pLastVDeclaration = pD3DDecl; - m_DevMan.BindVtxDecl(pD3DDecl); - } - - return S_OK; -} - -void CD3D9Renderer::EF_ClearTargetsImmediately(uint32 nFlags) -{ - nFlags |= FRT_CLEAR_IMMEDIATE; - - EF_ClearTargetsLater(nFlags); - - if (nFlags & FRT_CLEAR_IMMEDIATE) - { - FX_SetActiveRenderTargets(true); - } -} - -void CD3D9Renderer::EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil) -{ - nFlags |= FRT_CLEAR_IMMEDIATE; - - EF_ClearTargetsLater(nFlags, Colors, fDepth, nStencil); - - if (nFlags & FRT_CLEAR_IMMEDIATE) - { - FX_SetActiveRenderTargets(true); - } -} - -void CD3D9Renderer::EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors) -{ - nFlags |= FRT_CLEAR_IMMEDIATE; - - EF_ClearTargetsLater(nFlags, Colors); - - if (nFlags & FRT_CLEAR_IMMEDIATE) - { - FX_SetActiveRenderTargets(true); - } -} - -void CD3D9Renderer::EF_ClearTargetsImmediately(uint32 nFlags, float fDepth, uint8 nStencil) -{ - nFlags |= FRT_CLEAR_IMMEDIATE; - - EF_ClearTargetsLater(nFlags, fDepth, nStencil); - - if (nFlags & FRT_CLEAR_IMMEDIATE) - { - FX_SetActiveRenderTargets(true); - } -} - -// Clear buffers (color, depth/stencil) -void CD3D9Renderer::EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil) -{ - if (nFlags & FRT_CLEAR_FOGCOLOR) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i]) - { - m_pNewTarget[i]->m_ReqColor = m_cClearColor; - } - } - } - else if (nFlags & FRT_CLEAR_COLOR) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i] && m_pNewTarget[i]->m_pTarget) - { - m_pNewTarget[i]->m_ReqColor = Colors; - } - } - } - - if (nFlags & FRT_CLEAR_DEPTH) - { - m_pNewTarget[0]->m_fReqDepth = fDepth; - } - - if (!(nFlags & FRT_CLEAR_IMMEDIATE)) - { - m_pNewTarget[0]->m_ClearFlags = 0; - } - if ((nFlags & FRT_CLEAR_DEPTH) && m_pNewTarget[0]->m_pDepth) - { - m_pNewTarget[0]->m_ClearFlags |= CLEAR_ZBUFFER; - } - if (nFlags & FRT_CLEAR_COLOR) - { - m_pNewTarget[0]->m_ClearFlags |= CLEAR_RTARGET; - } - if (nFlags & FRT_CLEAR_COLORMASK) - { - m_pNewTarget[0]->m_ClearFlags |= FRT_CLEAR_COLORMASK; - } - - if (m_sbpp && (nFlags & FRT_CLEAR_STENCIL) && m_pNewTarget[0]->m_pDepth) - { -#ifdef SUPPORTS_MSAA - if (gcpRendD3D->m_RP.m_MSAAData.Type) - { - m_RP.m_PersFlags2 |= RBPF2_MSAA_RESTORE_SAMPLE_MASK; - } -#endif - m_pNewTarget[0]->m_ClearFlags |= CLEAR_STENCIL; - m_pNewTarget[0]->m_nReqStencil = nStencil; - } -} - -void CD3D9Renderer::EF_ClearTargetsLater(uint32 nFlags, float fDepth, uint8 nStencil) -{ - if (nFlags & FRT_CLEAR_FOGCOLOR) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i]) - { - m_pNewTarget[i]->m_ReqColor = m_cClearColor; - } - } - } - else if (nFlags & FRT_CLEAR_COLOR) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i] && m_pNewTarget[i]->m_pTex) - { - m_pNewTarget[i]->m_ReqColor = m_pNewTarget[i]->m_pTex->GetClearColor(); - } - } - } - - if (nFlags & FRT_CLEAR_DEPTH) - { - m_pNewTarget[0]->m_fReqDepth = fDepth; - } - - if (!(nFlags & FRT_CLEAR_IMMEDIATE)) - { - m_pNewTarget[0]->m_ClearFlags = 0; - } - if ((nFlags & FRT_CLEAR_DEPTH) && m_pNewTarget[0]->m_pDepth) - { - m_pNewTarget[0]->m_ClearFlags |= CLEAR_ZBUFFER; - } - if (nFlags & FRT_CLEAR_COLOR) - { - m_pNewTarget[0]->m_ClearFlags |= CLEAR_RTARGET; - } - if (nFlags & FRT_CLEAR_COLORMASK) - { - m_pNewTarget[0]->m_ClearFlags |= FRT_CLEAR_COLORMASK; - } - - if (m_sbpp && (nFlags & FRT_CLEAR_STENCIL) && m_pNewTarget[0]->m_pDepth) - { -#ifdef SUPPORTS_MSAA - if (gcpRendD3D->m_RP.m_MSAAData.Type) - { - m_RP.m_PersFlags2 |= RBPF2_MSAA_RESTORE_SAMPLE_MASK; - } -#endif - m_pNewTarget[0]->m_ClearFlags |= CLEAR_STENCIL; - m_pNewTarget[0]->m_nReqStencil = nStencil; - } -} - -void CD3D9Renderer::EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors) -{ - EF_ClearTargetsLater(nFlags, Colors, Clr_FarPlane.r, 0); - // float(m_pNewTarget[0]->m_pSurfDepth->pTex->GetClearColor().r), - // uint8(m_pNewTarget[0]->m_pSurfDepth->pTex->GetClearColor().g)); -} - -void CD3D9Renderer::EF_ClearTargetsLater(uint32 nFlags) -{ - EF_ClearTargetsLater(nFlags, Clr_FarPlane.r, 0); - // float(m_pNewTarget[0]->m_pSurfDepth->pTex->GetClearColor().r), - // uint8(m_pNewTarget[0]->m_pSurfDepth->pTex->GetClearColor().g)); -} - - -void CD3D9Renderer::FX_ClearTargetRegion(const uint32 nAdditionalStates /* = 0*/) -{ - assert(m_pRT->IsRenderThread()); - - bool clearColor = (m_pNewTarget[0]->m_ClearFlags & CLEAR_RTARGET) ? true : false; - bool clearDepth = (m_pNewTarget[0]->m_ClearFlags & CLEAR_ZBUFFER) ? true : false; - bool clearStencil = (m_pNewTarget[0]->m_ClearFlags & CLEAR_STENCIL) ? true : false; - - ColorF colorValue = Clr_Empty; - float depthValue = 1.0f; - uint8 stencilValue = 0; - const char* clearTechnique = "Clear"; - - if(clearColor) - { - colorValue = m_pNewTarget[0]->m_ReqColor; - - // Get number of render targets to clear - int numRT = 0; - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i] && m_pNewTarget[i]->m_pTarget) - { - numRT++; - break; - } - } - - // Select the technique to clear the right amount of render targets - switch(numRT) - { - case 0: - AZ_Assert(false, "No color render target bound."); - break; - case 1: - clearTechnique = "Clear"; - break; - case 2: - clearTechnique = "Clear2RT"; - break; - case 3: - clearTechnique = "Clear3RT"; - break; - case 4: - clearTechnique = "Clear4RT"; - break; - default: - AZ_Warning("Rendering", false, "More than 4 render targets bound. Only the first 4 will be cleared."); - clearTechnique = "Clear4RT"; - break; - } - } - - if(clearDepth) - { - depthValue = ::FClamp(m_pNewTarget[0]->m_fReqDepth, 0.0f, 1.0f); - } - - if(clearStencil) - { - stencilValue = m_pNewTarget[0]->m_nReqStencil; - } - - CRenderObject* pObj = m_RP.m_pCurObject; - CShader* pSHSave = m_RP.m_pShader; - SShaderTechnique* pSHT = m_RP.m_pCurTechnique; - SShaderPass* pPass = m_RP.m_pCurPass; - CShaderResources* pShRes = m_RP.m_pShaderResources; - - gRenDev->m_cEF.mfRefreshSystemShader("Common", CShaderMan::s_ShaderCommon); - - m_RP.m_PersFlags1 |= RBPF1_IN_CLEAR; - CShader* pSH = CShaderMan::s_ShaderCommon; - uint32 nPasses = 0; - pSH->FXSetTechnique(clearTechnique); - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - int nState = 0; - if (!clearColor) - { - nState |= GS_COLMASK_NONE; - } - - if (clearDepth) - { - if (!clearColor && !clearStencil) - { - // If only clearing depth then we can optimize the draw by using not-equal comparison, - // this way pixels with the same depth value as the clear value will be discarded. - nState |= GS_DEPTHFUNC_NOTEQUAL; - } - else - { - nState |= GS_DEPTHFUNC_ALWAYS; - } - nState |= GS_DEPTHWRITE; - } - else - { - nState |= GS_NODEPTHTEST; - } - - if (clearStencil) - { - int stencilState; - if (!clearColor && !clearDepth) - { - // If only clearing stencil then we can optimize the draw by using not-equal comparison, - // this way pixels with the same stencil value as the clear value will be discarded. - stencilState = - STENC_FUNC(FSS_STENCFUNC_NOTEQUAL) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_REPLACE); - } - else - { - stencilState = - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_REPLACE) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_REPLACE); - } - - const uint32 stencilMask = 0xFFFFFFFF; - - FX_SetStencilState(stencilState, stencilValue, stencilMask, stencilMask); - nState |= GS_STENCIL; - } - - m_pNewTarget[0]->m_ClearFlags = 0; - - nState |= nAdditionalStates; - - FX_SetState(nState, -1); - D3DSetCull(eCULL_None); - float fX = (float)m_CurViewport.nWidth; - float fY = (float)m_CurViewport.nHeight; - DrawQuad(-0.5f, -0.5f, fX - 0.5f, fY - 0.5f, colorValue, depthValue, fX, fY, fX, fY); - m_RP.m_PersFlags1 &= ~RBPF1_IN_CLEAR; - - m_RP.m_pCurObject = pObj; - m_RP.m_pShader = pSHSave; - m_RP.m_pCurTechnique = pSHT; - m_RP.m_pCurPass = pPass; - m_RP.m_pShaderResources = pShRes; -} - -void CD3D9Renderer::FX_SetActiveRenderTargets(bool /*bAllowDip*/) -{ - DETAILED_PROFILE_MARKER("FX_SetActiveRenderTargets"); - if (m_RP.m_PersFlags1 & RBPF1_IN_CLEAR) - { - return; - } - FUNCTION_PROFILER_RENDER_FLAT - bool bDirty = false; - if (m_nMaxRT2Commit >= 0) - { - for (int i = 0; i <= m_nMaxRT2Commit; i++) - { - if (!m_pNewTarget[i]->m_bWasSetRT) - { - m_pNewTarget[i]->m_bWasSetRT = true; - if (m_pNewTarget[i]->m_pTex) - { - m_pNewTarget[i]->m_pTex->SetResolved(false); - } - m_pCurTarget[i] = m_pNewTarget[i]->m_pTex; - bDirty = true; -#ifndef _RELEASE - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Set RT"); - if (m_pNewTarget[i]->m_pTex) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " '%s'", m_pNewTarget[i]->m_pTex->GetName()); - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " Format:%s", CTexture::NameForTextureFormat(m_pNewTarget[i]->m_pTex->m_eTFDst)); - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " Type:%s", CTexture::NameForTextureType(m_pNewTarget[i]->m_pTex->m_eTT)); - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " W/H:%d:%d\n", m_pNewTarget[i]->m_pTex->GetWidth(), m_pNewTarget[i]->m_pTex->GetHeight()); - } - else - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " 'Unknown'\n"); - } - } -#endif - CTexture* pRT = m_pNewTarget[i]->m_pTex; - if (pRT && pRT->UseMultisampledRTV()) - { - pRT->Unbind(); - } - } - } - if (!m_pNewTarget[0]->m_bWasSetD) - { - m_pNewTarget[0]->m_bWasSetD = true; - bDirty = true; - } - //m_nMaxRT2Commit = -1; - } - - if (bDirty) - { - CTexture* pRT = m_pNewTarget[0]->m_pTex; - if (pRT && pRT->UseMultisampledRTV()) - { - // Reset all texture slots which are used as RT currently - D3DShaderResourceView* pRes = NULL; - for (int i = 0; i < MAX_TMU; i++) - { - if (CTexture::s_TexStages[i].m_DevTexture == pRT->GetDevTexture()) - { - m_DevMan.BindSRV(eHWSC_Pixel, pRes, i); - CTexture::s_TexStages[i].m_DevTexture = NULL; - } - } - } - - const uint32 nMaxRT2Commit = max(m_nMaxRT2Commit + 1, 0); - - ID3D11RenderTargetView* pRTV[RT_STACK_WIDTH] = { NULL }; - uint32 nNumViews = 0; - - for (uint32 v = 0; v < nMaxRT2Commit; ++v) - { - if (m_pNewTarget[v] && m_pNewTarget[v]->m_pTarget) - { - pRTV[v] = (ID3D11RenderTargetView*)m_pNewTarget[v]->m_pTarget; - nNumViews = v + 1; - } - } - - GetDeviceContext().OMSetRenderTargets(m_pNewTarget[0]->m_pTarget == NULL ? 0 : nNumViews, pRTV, m_pNewTarget[0]->m_pDepth); - } - - if (m_nMaxRT2Commit >= 0) - { - m_nMaxRT2Commit = -1; - } - - FX_SetViewport(); - FX_ClearTargets(); -} - - -void CD3D9Renderer::FX_SetViewport() -{ - // Set current viewport - if (m_bViewportDirty) - { - m_bViewportDirty = false; - if ((m_CurViewport != m_NewViewport)) - { - m_CurViewport = m_NewViewport; - D3DViewPort Port; - Port.Width = (FLOAT)m_CurViewport.nWidth; - Port.Height = (FLOAT)m_CurViewport.nHeight; - Port.TopLeftX = (FLOAT)m_CurViewport.nX; - Port.TopLeftY = (FLOAT)m_CurViewport.nY; - Port.MinDepth = m_CurViewport.fMinZ; - Port.MaxDepth = m_CurViewport.fMaxZ; - - if (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - Port = ReverseDepthHelper::Convert(Port); - } - - GetDeviceContext().RSSetViewports(1, &Port); - } - } -} - -void CD3D9Renderer::FX_ClearTarget(D3DSurface* pView, const ColorF& cClear, const uint numRects, [[maybe_unused]] const RECT* pRects) -{ -#if !defined(EXCLUDE_RARELY_USED_R_STATS) && defined(ENABLE_PROFILING_CODE) - { - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTCleared++; - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTClearedSize += CDeviceTexture::TextureDataSize(pView, numRects, pRects); - } -#endif - -#if CRY_USE_DX12 - GetDeviceContext().ClearRectsRenderTargetView( - pView, - (const FLOAT*)&cClear, - numRects, - pRects); -#elif defined(DEVICE_SUPPORTS_D3D11_1) && D3DFXPIPELINE_CPP_TRAIT_CLEARVIEW - GetDeviceContext().ClearView( - pView, - (const FLOAT*)&cClear, - pRects, - numRects); -#else - if (!numRects) - { - GetDeviceContext().ClearRenderTargetView( - pView, - (const FLOAT*)&cClear); - - return; - } - - // TODO: implement clears in compute for DX11, gives max performance (pipeline switch cost?) - __debugbreak(); - abort(); -#endif -} - -void CD3D9Renderer::FX_ClearTarget(ITexture* tex, const ColorF& cClear, [[maybe_unused]] const uint numRects, const RECT* pRects, [[maybe_unused]] const bool bOptional) -{ - CTexture* pTex = reinterpret_cast(tex); - - // TODO: should not happen, happens in the editor currently - if (!pTex->GetDeviceRT()) - { - pTex->GetSurface(-1, 0); - } - -#if CRY_USE_DX12 - FX_ClearTarget( - pTex->GetDeviceRT(), - cClear, - numRects, - pRects); -#else - if (bOptional) - { - FX_ClearTarget( - pTex->GetDeviceRT(), - cClear, - 0U, - nullptr); - - return; - } - - // TODO: implement depth-clear as depth-only for DX11, gives max performance and probably just resets the depth-surface meta-data - int ox, oy, ow, oh; - FX_PushRenderTarget(0, pTex, nullptr); - GetViewport(&ox, &oy, &ow, &oh); - RT_SetViewport(pRects->left, pRects->top, pRects->right - pRects->left, pRects->bottom - pRects->top); - FX_SetActiveRenderTargets(); - EF_ClearTargetsLater(FRT_CLEAR_COLOR, cClear); - FX_ClearTargetRegion(); - FX_PopRenderTarget(0); - SetViewport(ox, oy, ow, oh); -#endif -} - -void CD3D9Renderer::FX_ClearTarget(ITexture* pTex, const ColorF& cClear) -{ - FX_ClearTarget( - pTex, - cClear, - 0U, - nullptr, - true); -} - -void CD3D9Renderer::FX_ClearTarget(ITexture* pTex) -{ - FX_ClearTarget( - pTex, - pTex->GetClearColor()); -} - -//==================================================================================== - -void CD3D9Renderer::FX_ClearTarget(D3DDepthSurface* pView, const int nFlags, const float cDepth, const uint8 cStencil, const uint numRects, [[maybe_unused]] const RECT* pRects) -{ -#if !defined(EXCLUDE_RARELY_USED_R_STATS) && defined(ENABLE_PROFILING_CODE) - if (nFlags) - { - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTCleared++; - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTClearedSize += CDeviceTexture::TextureDataSize(pView, numRects, pRects); - } -#endif - - assert(( - (nFlags & CLEAR_ZBUFFER ? D3D11_CLEAR_DEPTH : 0) | - (nFlags & CLEAR_STENCIL ? D3D11_CLEAR_STENCIL : 0) - ) == nFlags); - -#if CRY_USE_DX12 - GetDeviceContext().ClearRectsDepthStencilView( - pView, - nFlags, - cDepth, - cStencil, - numRects, - pRects); -#else - if (!numRects) - { - GetDeviceContext().ClearDepthStencilView( - pView, - nFlags, - cDepth, - cStencil); - - return; - } - - // TODO: implement clears in compute for DX11, gives max performance (pipeline switch cost?) - __debugbreak(); - abort(); -#endif -} - -void CD3D9Renderer::FX_ClearTarget(SDepthTexture* pTex, const int nFlags, const float cDepth, const uint8 cStencil, [[maybe_unused]] const uint numRects, const RECT* pRects, [[maybe_unused]] const bool bOptional) -{ - assert(( - (nFlags & CLEAR_ZBUFFER ? D3D11_CLEAR_DEPTH : 0) | - (nFlags & CLEAR_STENCIL ? D3D11_CLEAR_STENCIL : 0) - ) == nFlags); - -#if CRY_USE_DX12 - FX_ClearTarget( - pTex->pSurf, - nFlags, - cDepth, - cStencil, - numRects, - pRects); -#else - if (bOptional) - { - FX_ClearTarget( - static_cast(pTex->pSurf), - nFlags, - cDepth, - cStencil, - 0U, - nullptr); - - return; - } - - // TODO: implement depth-clear as depth-only for DX11, gives max performance and probably just resets the depth-surface meta-data - int ox, oy, ow, oh; - FX_PushRenderTarget(0, (D3DSurface*)nullptr, pTex); - GetViewport(&ox, &oy, &ow, &oh); - RT_SetViewport(pRects->left, pRects->top, pRects->right - pRects->left, pRects->bottom - pRects->top); - FX_SetActiveRenderTargets(); - EF_ClearTargetsLater(nFlags, Clr_Empty, cDepth, cStencil); - FX_ClearTargetRegion(); - FX_PopRenderTarget(0); - SetViewport(ox, oy, ow, oh); -#endif -} - -void CD3D9Renderer::FX_ClearTarget(SDepthTexture* pTex, const int nFlags, const float cDepth, const uint8 cStencil) -{ - FX_ClearTarget( - pTex, - nFlags, - cDepth, - cStencil, - 0U, - nullptr, - true); -} - -void CD3D9Renderer::FX_ClearTarget(SDepthTexture* pTex, const int nFlags) -{ - FX_ClearTarget( - pTex, - nFlags, - (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 0.f : 1.f, - 0U); -} - -void CD3D9Renderer::FX_ClearTarget(SDepthTexture* pTex) -{ - FX_ClearTarget( - pTex, - CLEAR_ZBUFFER | - CLEAR_STENCIL); -} - -//==================================================================================== - -void CD3D9Renderer::FX_ClearTargets() -{ - if (m_pNewTarget[0]->m_ClearFlags) - { - { - const float fClearDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 1.0f - m_pNewTarget[0]->m_fReqDepth : m_pNewTarget[0]->m_fReqDepth; - const uint8 nClearStencil = m_pNewTarget[0]->m_nReqStencil; - const int nFlags = m_pNewTarget[0]->m_ClearFlags & ~CLEAR_RTARGET; - - // TODO: ClearFlags per render-target - if ((m_pNewTarget[0]->m_pTarget != NULL) && (m_pNewTarget[0]->m_ClearFlags & CLEAR_RTARGET)) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i]->m_pTarget) - { - // NOTE: optimal value is "m_pNewTarget[0]->m_pTex->GetClearColor()" - GetDeviceContext().ClearRenderTargetView(m_pNewTarget[i]->m_pTarget, &m_pNewTarget[i]->m_ReqColor[0]); - } - } - } - - assert(( - (nFlags & FRT_CLEAR_DEPTH ? D3D11_CLEAR_DEPTH : 0) | - (nFlags & FRT_CLEAR_STENCIL ? D3D11_CLEAR_STENCIL : 0) - ) == nFlags); - - AZ_Warning("CD3D9Renderer", m_pNewTarget[0]->m_pDepth != nullptr, "FX_ClearTargets: Depth texture of target was nullptr. The depth target will not be cleared."); - if (nFlags && m_pNewTarget[0]->m_pDepth != nullptr) - { - GetDeviceContext().ClearDepthStencilView(m_pNewTarget[0]->m_pDepth, nFlags, fClearDepth, nClearStencil); - } - } - - CTexture* pRT = m_pNewTarget[0]->m_pTex; - if IsCVarConstAccess(constexpr) (CV_r_stats == 13) - { - EF_AddRTStat(pRT, m_pNewTarget[0]->m_ClearFlags, m_CurViewport.nWidth, m_CurViewport.nHeight); - } - -#if !defined(EXCLUDE_RARELY_USED_R_STATS) && defined(ENABLE_PROFILING_CODE) - { - if ((m_pNewTarget[0]->m_pTarget != NULL) && (m_pNewTarget[0]->m_ClearFlags & CLEAR_RTARGET)) - { - for (int i = 0; i < RT_STACK_WIDTH; ++i) - { - if (m_pNewTarget[i]->m_pTarget) - { - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTCleared++; - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTClearedSize += CDeviceTexture::TextureDataSize(m_pNewTarget[i]->m_pTarget); - } - } - } - - if (m_pNewTarget[0]->m_ClearFlags & (~CLEAR_RTARGET) && m_pNewTarget[0]->m_pSurfDepth != nullptr) - { - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTCleared++; - m_RP.m_PS[m_RP.m_nProcessThreadID].m_RTClearedSize += CDeviceTexture::TextureDataSize(m_pNewTarget[0]->m_pSurfDepth->pSurf); - } - } -#endif - - m_pNewTarget[0]->m_ClearFlags = 0; - } -} - -void CD3D9Renderer::FX_Commit(bool bAllowDIP) -{ - DETAILED_PROFILE_MARKER("FX_Commit"); - // Commit all changed shader parameters - if (m_RP.m_nCommitFlags & FC_GLOBAL_PARAMS) - { - CHWShader_D3D::mfCommitParamsGlobal(); - m_RP.m_nCommitFlags &= ~FC_GLOBAL_PARAMS; - } - if (m_RP.m_nCommitFlags & FC_MATERIAL_PARAMS) - { - CHWShader_D3D::UpdatePerMaterialConstantBuffer(); - m_RP.m_nCommitFlags &= ~FC_MATERIAL_PARAMS; - } - AzRHI::ConstantBufferCache::GetInstance().CommitAll(); - - // Commit all changed RT's - if (m_RP.m_nCommitFlags & FC_TARGETS) - { - FX_SetActiveRenderTargets(bAllowDIP); - m_RP.m_nCommitFlags &= ~FC_TARGETS; - } - - // Adapt viewport dimensions if changed - FX_SetViewport(); - - // Clear rendertargets if requested - FX_ClearTargets(); -} - - -// Set current geometry culling modes -void CD3D9Renderer::D3DSetCull(ECull eCull, bool bSkipMirrorCull) -{ - FUNCTION_PROFILER_RENDER_FLAT - if (eCull != eCULL_None && !bSkipMirrorCull) - { - if (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_MIRRORCULL) - { - eCull = (eCull == eCULL_Back) ? eCULL_Front : eCULL_Back; - } - } - - if (eCull == m_RP.m_eCull) - { - return; - } - - SStateRaster RS = m_StatesRS[m_nCurStateRS]; - - RS.Desc.FrontCounterClockwise = true; - - if (eCull == eCULL_None) - { - RS.Desc.CullMode = D3D11_CULL_NONE; - } - else - { - if (eCull == eCULL_Back) - { - RS.Desc.CullMode = D3D11_CULL_BACK; - } - else - { - RS.Desc.CullMode = D3D11_CULL_FRONT; - } - } - SetRasterState(&RS); - m_RP.m_eCull = eCull; -} - -uint8 g_StencilFuncLookup[8] = -{ - D3D11_COMPARISON_ALWAYS, // FSS_STENCFUNC_ALWAYS 0x0 - D3D11_COMPARISON_NEVER, // FSS_STENCFUNC_NEVER 0x1 - D3D11_COMPARISON_LESS, // FSS_STENCFUNC_LESS 0x2 - D3D11_COMPARISON_LESS_EQUAL, // FSS_STENCFUNC_LEQUAL 0x3 - D3D11_COMPARISON_GREATER, // FSS_STENCFUNC_GREATER 0x4 - D3D11_COMPARISON_GREATER_EQUAL, // FSS_STENCFUNC_GEQUAL 0x5 - D3D11_COMPARISON_EQUAL, // FSS_STENCFUNC_EQUAL 0x6 - D3D11_COMPARISON_NOT_EQUAL // FSS_STENCFUNC_NOTEQUAL 0x7 -}; - -uint8 g_StencilOpLookup[8] = -{ - D3D11_STENCIL_OP_KEEP, // FSS_STENCOP_KEEP 0x0 - D3D11_STENCIL_OP_REPLACE, // FSS_STENCOP_REPLACE 0x1 - D3D11_STENCIL_OP_INCR_SAT, // FSS_STENCOP_INCR 0x2 - D3D11_STENCIL_OP_DECR_SAT, // FSS_STENCOP_DECR 0x3 - D3D11_STENCIL_OP_ZERO, // FSS_STENCOP_ZERO 0x4 - D3D11_STENCIL_OP_INCR, // FSS_STENCOP_INCR_WRAP 0x5 - D3D11_STENCIL_OP_DECR, // FSS_STENCOP_DECR_WRAP 0x6 - D3D11_STENCIL_OP_INVERT // FSS_STENCOP_INVERT 0x7 -}; - -void CRenderer::FX_SetStencilState(int st, uint32 nStencRef, uint32 nStencMask, uint32 nStencWriteMask, bool bForceFullReadMask) -{ - FUNCTION_PROFILER_RENDER_FLAT - - PrefetchLine(g_StencilFuncLookup, 0); - - const uint32 nPersFlags2 = m_RP.m_PersFlags2; - if (!bForceFullReadMask && !(nPersFlags2 & RBPF2_READMASK_RESERVED_STENCIL_BIT)) - { - nStencMask &= ~BIT_STENCIL_RESERVED; - } - - if (nPersFlags2 & RBPF2_WRITEMASK_RESERVED_STENCIL_BIT) - { - nStencWriteMask &= ~BIT_STENCIL_RESERVED; - } - - nStencRef |= m_RP.m_CurStencilRefAndMask; - - SStateDepth DS = gcpRendD3D->m_StatesDP[gcpRendD3D->m_nCurStateDP]; - DS.Desc.StencilReadMask = nStencMask; - DS.Desc.StencilWriteMask = nStencWriteMask; - - int nCurFunc = st & FSS_STENCFUNC_MASK; - DS.Desc.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)g_StencilFuncLookup[nCurFunc]; - - int nCurOp = (st & FSS_STENCFAIL_MASK) >> FSS_STENCFAIL_SHIFT; - DS.Desc.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - - nCurOp = (st & FSS_STENCZFAIL_MASK) >> FSS_STENCZFAIL_SHIFT; - DS.Desc.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - - nCurOp = (st & FSS_STENCPASS_MASK) >> FSS_STENCPASS_SHIFT; - DS.Desc.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - - if (!(st & FSS_STENCIL_TWOSIDED)) - { - DS.Desc.BackFace = DS.Desc.FrontFace; - } - else - { - nCurFunc = (st & (FSS_STENCFUNC_MASK << FSS_CCW_SHIFT)) >> FSS_CCW_SHIFT; - DS.Desc.BackFace.StencilFunc = (D3D11_COMPARISON_FUNC)g_StencilFuncLookup[nCurFunc]; - - nCurOp = (st & (FSS_STENCFAIL_MASK << FSS_CCW_SHIFT)) >> (FSS_STENCFAIL_SHIFT + FSS_CCW_SHIFT); - DS.Desc.BackFace.StencilFailOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - - nCurOp = (st & (FSS_STENCZFAIL_MASK << FSS_CCW_SHIFT)) >> (FSS_STENCZFAIL_SHIFT + FSS_CCW_SHIFT); - DS.Desc.BackFace.StencilDepthFailOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - - nCurOp = (st & (FSS_STENCPASS_MASK << FSS_CCW_SHIFT)) >> (FSS_STENCPASS_SHIFT + FSS_CCW_SHIFT); - DS.Desc.BackFace.StencilPassOp = (D3D11_STENCIL_OP)g_StencilOpLookup[nCurOp]; - } - - m_RP.m_CurStencRef = nStencRef; - m_RP.m_CurStencMask = nStencMask; - m_RP.m_CurStencWriteMask = nStencWriteMask; - - gcpRendD3D->SetDepthState(&DS, nStencRef); - - m_RP.m_CurStencilState = st; -} - -void CD3D9Renderer::EF_Scissor(bool bEnable, int sX, int sY, int sWdt, int sHgt) -{ - m_pRT->RC_SetScissor(bEnable, sX, sY, sWdt, sHgt); -} - -void CD3D9Renderer::RT_SetScissor(bool bEnable, int sX, int sY, int sWdt, int sHgt) -{ - FUNCTION_PROFILER_RENDER_FLAT - if (!CV_r_scissor || (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN)) - { - return; - } - D3D11_RECT scRect; - if (bEnable) - { - if (sX != m_sPrevX || sY != m_sPrevY || sWdt != m_sPrevWdt || sHgt != m_sPrevHgt) - { - m_sPrevX = sX; - m_sPrevY = sY; - m_sPrevWdt = sWdt; - m_sPrevHgt = sHgt; - scRect.left = sX; - scRect.top = sY; - scRect.right = sX + sWdt; - scRect.bottom = sY + sHgt; - - GetDeviceContext().RSSetScissorRects(1, &scRect); - } - if (bEnable != m_bsPrev) - { - m_bsPrev = bEnable; - SStateRaster RS = m_StatesRS[m_nCurStateRS]; - RS.Desc.ScissorEnable = bEnable; - SetRasterState(&RS); - } - } - else - { - if (bEnable != m_bsPrev) - { - m_bsPrev = bEnable; - m_sPrevWdt = 0; - m_sPrevHgt = 0; - SStateRaster RS = m_StatesRS[m_nCurStateRS]; - RS.Desc.ScissorEnable = bEnable; - SetRasterState(&RS); - } - } -} - -bool CD3D9Renderer::EF_GetScissorState(int& sX, int& sY, int& sWdt, int& sHgt) -{ - if (!CV_r_scissor || (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN)) - { - return false; - } - - sX = m_sPrevX; - sY = m_sPrevY; - sWdt = m_sPrevWdt; - sHgt = m_sPrevHgt; - return m_bsPrev; -} - -void CD3D9Renderer::FX_FogCorrection() -{ - if (m_RP.m_nPassGroupID <= EFSLIST_DECAL) - { - uint32 uBlendFlags = m_RP.m_CurState & GS_BLEND_MASK; - switch (uBlendFlags) - { - case GS_BLSRC_ONE | GS_BLDST_ONE: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_DSTALPHA | GS_BLDST_ONE: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_DSTCOL | GS_BLDST_SRCCOL: - { - static ColorF pColGrey = ColorF(0.5f, 0.5f, 0.5f, 1.0f); - EF_SetFogColor(pColGrey); - break; - } - case GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCCOL: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_ZERO | GS_BLDST_ONEMINUSSRCCOL: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_SRCALPHA | GS_BLDST_ONE: - case GS_BLSRC_SRCALPHA_A_ZERO | GS_BLDST_ONE: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_ZERO | GS_BLDST_ONE: - EF_SetFogColor(Col_Black); - break; - case GS_BLSRC_DSTCOL | GS_BLDST_ZERO: - EF_SetFogColor(Col_White); - break; - default: - EF_SetFogColor(m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_FogColor); - break; - } - } - else - { - EF_SetFogColor(m_RP.m_TI[m_RP.m_nProcessThreadID].m_FS.m_FogColor); - } -} - -// Set current render states -void CD3D9Renderer::FX_SetState(int st, int AlphaRef, int RestoreState) -{ - FUNCTION_PROFILER_RENDER_FLAT - int Changed; - if IsCVarConstAccess(constexpr) (CV_r_measureoverdraw == 4 && (st & GS_DEPTHFUNC_MASK) == GS_DEPTHFUNC_HIZEQUAL) - { - // disable fine depth test - st |= GS_NODEPTHTEST; - } - st |= m_RP.m_StateOr; - st &= m_RP.m_StateAnd; - Changed = st ^ m_RP.m_CurState; - Changed |= RestoreState; - - // Due to the way reverse depth was implemented, we need to check if RBPF_REVERSE_DEPTH has changed and force flush the depth state if so. - uint32 changedPersFlags = m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags ^ m_RP.m_previousPersFlags; - m_RP.m_previousPersFlags = m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags; - - if (!Changed && !changedPersFlags && (AlphaRef == -1 || AlphaRef == m_RP.m_CurAlphaRef)) - { - return; - } - - //PROFILE_FRAME(State_RStates); - -#ifndef _RELEASE - m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumStateChanges++; -#endif - if (m_StatesBL.size() == 0 || m_StatesDP.size() == 0 || m_StatesRS.size() == 0) - { - SetDefaultRenderStates(); - } - SStateDepth DS = m_StatesDP[m_nCurStateDP]; - SStateBlend BS = m_StatesBL[m_nCurStateBL]; - SStateRaster RS = m_StatesRS[m_nCurStateRS]; - bool bDirtyDS = false; - bool bDirtyBS = false; - bool bDirtyRS = false; - - if ((Changed & GS_DEPTHFUNC_MASK) || (changedPersFlags & RBPF_REVERSE_DEPTH)) - { - bDirtyDS = true; - - uint32 nDepthState = st; - if (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - nDepthState = ReverseDepthHelper::ConvertDepthFunc(st); - } - - switch (nDepthState & GS_DEPTHFUNC_MASK) - { - case GS_DEPTHFUNC_HIZEQUAL: - case GS_DEPTHFUNC_EQUAL: - DS.Desc.DepthFunc = D3D11_COMPARISON_EQUAL; - break; - case GS_DEPTHFUNC_LEQUAL: - DS.Desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - break; - case GS_DEPTHFUNC_GREAT: - DS.Desc.DepthFunc = D3D11_COMPARISON_GREATER; - break; - case GS_DEPTHFUNC_LESS: - DS.Desc.DepthFunc = D3D11_COMPARISON_LESS; - break; - case GS_DEPTHFUNC_NOTEQUAL: - DS.Desc.DepthFunc = D3D11_COMPARISON_NOT_EQUAL; - break; - case GS_DEPTHFUNC_GEQUAL: - DS.Desc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; - break; - case GS_DEPTHFUNC_ALWAYS: - DS.Desc.DepthFunc = D3D11_COMPARISON_ALWAYS; - break; - } - } - if (Changed & (GS_WIREFRAME)) - { - bDirtyRS = true; - - if (st & GS_WIREFRAME) - { - RS.Desc.FillMode = D3D11_FILL_WIREFRAME; - } - else - { - RS.Desc.FillMode = D3D11_FILL_SOLID; - } - } - - if (Changed & GS_COLMASK_MASK) - { - bDirtyBS = true; - uint32 nMask = 0xfffffff0 | ((st & GS_COLMASK_MASK) >> GS_COLMASK_SHIFT); - nMask = (~nMask) & 0xf; - for (size_t i = 0; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].RenderTargetWriteMask = nMask; - } - } - - if (Changed & GS_BLEND_MASK) - { - bDirtyBS = true; - if (st & GS_BLEND_MASK) - { - if IsCVarConstAccess(constexpr) (CV_r_measureoverdraw && (m_RP.m_nRendFlags & SHDF_ALLOWHDR)) - { - st = (st & ~GS_BLEND_MASK) | (GS_BLSRC_ONE | GS_BLDST_ONE); - st &= ~GS_ALPHATEST_MASK; - } - - // todo: add separate alpha blend support for mrt - for (size_t i = 0; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].BlendEnable = TRUE; - } - - // Source factor - switch (st & GS_BLSRC_MASK) - { - case GS_BLSRC_ZERO: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ZERO; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; - break; - case GS_BLSRC_ONE: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - break; - case GS_BLSRC_DSTCOL: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_DEST_COLOR; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA; - break; - case GS_BLSRC_ONEMINUSDSTCOL: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_INV_DEST_COLOR; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; - break; - case GS_BLSRC_SRCALPHA: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - break; - case GS_BLSRC_ONEMINUSSRCALPHA: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_INV_SRC_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - break; - case GS_BLSRC_DSTALPHA: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_DEST_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA; - break; - case GS_BLSRC_ONEMINUSDSTALPHA: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_INV_DEST_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; - break; - case GS_BLSRC_ALPHASATURATE: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA_SAT; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA_SAT; - break; - case GS_BLSRC_SRCALPHA_A_ZERO: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; - break; - case GS_BLSRC_SRC1ALPHA: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC1_ALPHA; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC1_ALPHA; - break; - default: - BS.Desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - break; - } - - //Destination factor - switch (st & GS_BLDST_MASK) - { - case GS_BLDST_ZERO: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - break; - case GS_BLDST_ONE: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; - break; - case GS_BLDST_SRCCOL: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC_COLOR; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA; - break; - case GS_BLDST_ONEMINUSSRCCOL: - if (m_nHDRType == 1 && (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_HDR)) - { - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; - } - else - { - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_COLOR; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - } - break; - case GS_BLDST_SRCALPHA: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC_ALPHA; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA; - break; - case GS_BLDST_ONEMINUSSRCALPHA: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - break; - case GS_BLDST_DSTALPHA: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; - break; - case GS_BLDST_ONEMINUSDSTALPHA: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_DEST_ALPHA; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; - break; - case GS_BLDST_ONE_A_ZERO: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - break; - case GS_BLDST_ONEMINUSSRC1ALPHA: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC1_ALPHA; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC1_ALPHA; - break; - default: - BS.Desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - break; - } - - //Blending operation - D3D11_BLEND_OP blendOperation = D3D11_BLEND_OP_ADD; - D3D11_BLEND_OP blendOperationAlpha = D3D11_BLEND_OP_ADD; - switch (st & GS_BLEND_OP_MASK) - { - case GS_BLOP_MAX: - blendOperation = D3D11_BLEND_OP_MAX; - blendOperationAlpha = D3D11_BLEND_OP_MAX; - break; - case GS_BLOP_MIN: - blendOperation = D3D11_BLEND_OP_MIN; - blendOperationAlpha = D3D11_BLEND_OP_MIN; - break; - } - - //Separate blend modes for alpha - switch (st & GS_BLALPHA_MASK) - { - case GS_BLALPHA_MIN: - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blendOperationAlpha = D3D11_BLEND_OP_MIN; - break; - case GS_BLALPHA_MAX: - BS.Desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; - BS.Desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - blendOperationAlpha = D3D11_BLEND_OP_MAX; - break; - } - - // todo: add separate alpha blend support for mrt - for (size_t i = 0; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].BlendOp = blendOperation; - BS.Desc.RenderTarget[i].BlendOpAlpha = blendOperationAlpha; - } - } - else - { - // todo: add separate alpha blend support for mrt - for (size_t i = 0; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].BlendEnable = FALSE; - } - } - - // Need to disable color write to MRTs for shadow map alpha blending (not supported by all hw) - if ((m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN) && m_pNewTarget[1]) - { - bDirtyBS = true; - uint32 nMask = 0xfffffff0 | ((st & GS_COLMASK_MASK) >> GS_COLMASK_SHIFT); - nMask = (~nMask) & 0xf; - BS.Desc.RenderTarget[0].RenderTargetWriteMask = nMask; - if (st & GS_BLEND_MASK) - { - BS.Desc.IndependentBlendEnable = TRUE; - for (size_t i = 1; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].RenderTargetWriteMask = 0; - BS.Desc.RenderTarget[i].BlendEnable = FALSE; - } - } - else - { - BS.Desc.IndependentBlendEnable = FALSE; - for (size_t i = 1; i < RT_STACK_WIDTH; ++i) - { - BS.Desc.RenderTarget[i].RenderTargetWriteMask = nMask; - BS.Desc.RenderTarget[i].BlendEnable = TRUE; - } - } - } - } - - m_RP.m_depthWriteStateUsed |= (st & GS_DEPTHWRITE) != 0; - if (Changed & GS_DEPTHWRITE) - { - bDirtyDS = true; - if (st & GS_DEPTHWRITE) - { - DS.Desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - } - else - { - DS.Desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - } - } - - if (Changed & GS_NODEPTHTEST) - { - bDirtyDS = true; - if (st & GS_NODEPTHTEST) - { - DS.Desc.DepthEnable = FALSE; - } - else - { - DS.Desc.DepthEnable = TRUE; - } - } - - if (Changed & GS_STENCIL) - { - bDirtyDS = true; - if (st & GS_STENCIL) - { - DS.Desc.StencilEnable = TRUE; - } - else - { - DS.Desc.StencilEnable = FALSE; - } - } - - { - // Alpha test must be handled in shader in D3D10 API - if (((st ^ m_RP.m_CurState) & GS_ALPHATEST_MASK) || ((st & GS_ALPHATEST_MASK) && (m_RP.m_CurAlphaRef != AlphaRef && AlphaRef != -1))) - { - if (st & GS_ALPHATEST_MASK) - { - m_RP.m_CurAlphaRef = AlphaRef; - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHATEST]; - } - else - { - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_ALPHATEST]; - } - // When alpha test is turned on or off just changing m_RP.m_FlagsShader_RT doesn't work unless - // an update is triggered. Setting this flag appears to cause the correct update. - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } - } - - if (bDirtyDS) - { - SetDepthState(&DS, m_nCurStencRef); - } - if (bDirtyRS) - { - SetRasterState(&RS); - } - if (bDirtyBS) - { - SetBlendState(&BS); - } - - m_RP.m_CurState = st; -} - -void CD3D9Renderer::FX_ZState(uint32& state) -{ - assert(m_RP.m_pRootTechnique); // cannot be 0 here - - if ((m_RP.m_pRootTechnique->m_Flags & (FHF_WASZWRITE | FHF_POSITION_INVARIANT)) - && m_RP.m_nPassGroupID == EFSLIST_GENERAL - && SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID] == 0 - && CV_r_usezpass) - { - if ((m_RP.m_nBatchFilter & (FB_GENERAL | FB_MULTILAYERS)) && (m_RP.m_nRendFlags & (SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS))) - { - if (!(m_RP.m_pRootTechnique->m_Flags & FHF_POSITION_INVARIANT)) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw == 4) - { - // Hi-Z test only, fine depth test is disabled at the top of FX_SetState() - state |= GS_DEPTHFUNC_HIZEQUAL; - } - else - { - state |= GS_DEPTHFUNC_EQUAL; - } - } - state &= ~(GS_DEPTHWRITE | GS_ALPHATEST_MASK); - } - } -} - -void CD3D9Renderer::FX_HairState(uint32& nState, const SShaderPass* pPass) -{ - if ((m_RP.m_nPassGroupID == EFSLIST_GENERAL || m_RP.m_nPassGroupID == EFSLIST_TRANSP) && !(m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & (RBPF_SHADOWGEN | RBPF_ZPASS)) - && !(m_RP.m_PersFlags2 & (RBPF2_MOTIONBLURPASS))) - { - // reset quality settings. BEWARE: these are used by shadows as well - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_TILED_SHADING] | g_HWSR_MaskBit[HWSR_QUALITY1]); - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_QUALITY]; - - // force per object fog - m_RP.m_FlagsShader_RT |= (g_HWSR_MaskBit[HWSR_FOG] | g_HWSR_MaskBit[HWSR_ALPHABLEND]); - - if (CV_r_DeferredShadingTiled && CV_r_DeferredShadingTiledHairQuality > 0) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_TILED_SHADING]; - - if (CV_r_DeferredShadingTiledHairQuality > 1) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_QUALITY1]; - } - } - - if ((pPass->m_RenderState & GS_DEPTHFUNC_MASK) == GS_DEPTHFUNC_LESS) - { - nState = (nState & ~(GS_BLEND_MASK | GS_DEPTHFUNC_MASK)); - nState |= GS_DEPTHFUNC_LESS; - - if ((m_RP.m_nPassGroupID == EFSLIST_TRANSP) && (m_RP.m_pShader->m_Flags2 & EF2_DEPTH_FIXUP) && RenderCapabilities::SupportsDualSourceBlending()) - { - nState |= GS_BLSRC_SRC1ALPHA | GS_BLDST_ONEMINUSSRC1ALPHA | GS_BLALPHA_MIN; - } - else - { - nState |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - } - - if (pPass->m_RenderState & GS_DEPTHWRITE) - { - nState |= GS_DEPTHWRITE; - } - else - { - nState &= ~GS_DEPTHWRITE; - } - } - else - { - nState = (nState & ~(GS_BLEND_MASK | GS_DEPTHFUNC_MASK)); - nState |= GS_DEPTHFUNC_EQUAL /*| GS_DEPTHWRITE*/; - } - } -} - -void CD3D9Renderer::FX_CommitStates(const SShaderTechnique* pTech, const SShaderPass* pPass, bool bUseMaterialState) -{ - FUNCTION_PROFILER_RENDER_FLAT - uint32 State = 0; - int AlphaRef = pPass->m_AlphaRef == 0xff ? -1 : pPass->m_AlphaRef; - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - if (rRP.m_pCurObject->m_RState) - { - switch (rRP.m_pCurObject->m_RState & OS_TRANSPARENT) - { - case OS_ALPHA_BLEND: - State = GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - break; - case OS_ADD_BLEND: - // In HDR mode, this is equivalent to pure additive GS_BLSRC_ONE | GS_BLDST_ONE. - State = GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCCOL; - break; - case OS_MULTIPLY_BLEND: - State = GS_BLSRC_DSTCOL | GS_BLDST_SRCCOL; - break; - } - - if (rRP.m_pCurObject->m_RState & OS_NODEPTH_TEST) - { - State |= GS_NODEPTHTEST; - } - AlphaRef = 0; - } - else - { - State = pPass->m_RenderState; - } - - if (bUseMaterialState && rRP.m_MaterialStateOr != 0) - { - if (rRP.m_MaterialStateOr & GS_ALPHATEST_MASK) - { - AlphaRef = rRP.m_MaterialAlphaRef; - } - State &= ~rRP.m_MaterialStateAnd; - State |= rRP.m_MaterialStateOr; - } - - //This has higher priority than material states as for alphatested material - //it is forced to use depth writing (FX_SetResourcesState) - if (rRP.m_pCurObject->m_RState & OS_TRANSPARENT) - { - State &= ~GS_DEPTHWRITE; - } - - if (!(pTech->m_Flags & FHF_POSITION_INVARIANT) && !(pPass->m_PassFlags & SHPF_FORCEZFUNC)) - { - FX_ZState(State); - } - - if (bUseMaterialState && (rRP.m_pCurObject->m_fAlpha < 1.0f) && !rRP.m_bIgnoreObjectAlpha) - { - if (pTech && pTech->m_NameCRC == m_techShadowGen) - { - // If rendering to a shadow map: - State = (State | GS_DEPTHWRITE); - } - else - { - // If not rendering to a shadow map: - State = (State & ~(GS_BLEND_MASK | GS_DEPTHWRITE)) | (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - } - } - - State &= ~rRP.m_ForceStateAnd; - State |= rRP.m_ForceStateOr; - - if (rRP.m_pShader->m_Flags2 & EF2_HAIR) - { - FX_HairState(State, pPass); - } - else if ((m_RP.m_nPassGroupID == EFSLIST_TRANSP) && (m_RP.m_nSortGroupID == 1) && - !(rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS) && !(m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & (RBPF_SHADOWGEN | RBPF_ZPASS))) - { - State &= ~GS_BLALPHA_MASK; - - // Depth fixup for transparent geometry - if ((m_RP.m_pShader->m_Flags2 & EF2_DEPTH_FIXUP) && RenderCapabilities::SupportsDualSourceBlending()) - { - if (rRP.m_pCurObject->m_RState & OS_ALPHA_BLEND || ((State & (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA)) == (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA))) - { - State &= ~(GS_NOCOLMASK_A | GS_BLSRC_MASK | GS_BLDST_MASK); - State |= GS_BLSRC_SRC1ALPHA | GS_BLDST_ONEMINUSSRC1ALPHA; - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHABLEND] | g_HWSR_MaskBit[HWSR_DEPTHFIXUP]; - - // min blending on depth values (alpha channel) - State |= GS_BLALPHA_MIN; - } - } - } - - if ((rRP.m_PersFlags2 & RBPF2_ALLOW_DEFERREDSHADING) && (rRP.m_pShader->m_Flags & EF_SUPPORTSDEFERREDSHADING)) - { - if (rTI.m_PersFlags & RBPF_ZPASS) - { - if ((rRP.m_pShader->m_Flags & EF_DECAL)) - { - State = (State & ~(GS_BLEND_MASK | GS_DEPTHWRITE | GS_DEPTHFUNC_MASK)); - State |= GS_DEPTHFUNC_LEQUAL | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHABLEND]; - } - - // Disable alpha writes - for alpha blend case we use default alpha value as a default power factor - if (State & GS_BLEND_MASK) - { - State |= GS_COLMASK_RGB; - } - - // Disable alpha testing/depth writes if geometry had a z-prepass - if (!(rRP.m_PersFlags2 & RBPF2_ZPREPASS) && (rRP.m_RIs[0][0]->nBatchFlags & FB_ZPREPASS)) - { - State &= ~(GS_DEPTHWRITE | GS_DEPTHFUNC_MASK | GS_ALPHATEST_MASK); - State |= GS_DEPTHFUNC_EQUAL; - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_ALPHATEST]; - } - } - } - - { - const AZ::u32 VelocityMask = FOB_MOTION_BLUR | FOB_VERTEX_VELOCITY | FOB_SKINNED; - const AZ::u32 SoftwareSkinned = FOB_MOTION_BLUR | FOB_VERTEX_VELOCITY; - if ((rRP.m_ObjFlags & VelocityMask) == SoftwareSkinned && - (rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS) != 0) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_VERTEX_VELOCITY]; - } - } - - if (rRP.m_PersFlags2 & RBPF2_CUSTOM_RENDER_PASS) - { - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_customvisions == 2) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - State |= GS_BLSRC_ONE | GS_BLDST_ONE; - } - else if IsCVarConstAccess(constexpr) (CRenderer::CV_r_customvisions == 3) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - - // Ignore depth thresholding in Post3DRender - if (rRP.m_PersFlags2 & RBPF2_POST_3D_RENDERER_PASS) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - } - } - - if (m_NewViewport.fMaxZ <= 0.01f) - { - State &= ~GS_DEPTHWRITE; - } - - // Intermediate solution to disable depth testing in 3D HUD - if (rRP.m_pCurObject->m_ObjFlags & FOB_RENDER_AFTER_POSTPROCESSING) - { - State &= ~GS_DEPTHFUNC_MASK; - State |= GS_NODEPTHTEST; - } - - if (rRP.m_PersFlags2 & RBPF2_DISABLECOLORWRITES) - { - State &= ~GS_COLMASK_MASK; - State |= GS_COLMASK_NONE; - } - - FX_SetState(State, AlphaRef); - - if (State & GS_ALPHATEST_MASK) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHATEST]; - } - - int nBlend = rRP.m_CurState & (GS_BLEND_MASK & ~GS_BLALPHA_MASK); - if (nBlend) - { - //set alpha blend shader flag when the blend mode for color is set to alpha blend. - if (nBlend == (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA) - || nBlend == (GS_BLSRC_SRCALPHA | GS_BLDST_ONE) - || nBlend == (GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA) - || nBlend == (GS_BLSRC_SRCALPHA_A_ZERO | GS_BLDST_ONEMINUSSRCALPHA)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHABLEND]; - } - } - - // Enable position invariant flag to disable fast math on certain vertex shader operations that affect position calculations. - // This fixes issues with geometry that renders in both z-prepass and any other pass from having precision - // issues when executing different vertex shaders and expecting the same position output results. - if (rRP.m_RIs[0][0]->nBatchFlags & FB_ZPREPASS) - { - rRP.m_FlagsShader_MDV |= MDV_POSITION_INVARIANT; - } -} - -//===================================================================================== - -bool CD3D9Renderer::FX_GetTargetSurfaces(CTexture* pTarget, D3DSurface*& pTargSurf, [[maybe_unused]] SRTStack* pCur, int nCMSide, [[maybe_unused]] int nTarget, [[maybe_unused]] uint32 nTileCount) -{ - if (pTarget) - { - if (!CTexture::IsTextureExist(pTarget) && !pTarget->m_bNoDevTexture) - { - pTarget->CreateRenderTarget(eTF_Unknown, pTarget->GetClearColor()); - } - - if (!CTexture::IsTextureExist(pTarget)) - { - return false; - } - pTargSurf = pTarget->GetSurface(nCMSide, 0); - } - else - { - pTargSurf = NULL; - } - return true; -} - -bool CD3D9Renderer::FX_SetRenderTarget(int nTarget, void* pTargetSurf, SDepthTexture* pDepthTarget, [[maybe_unused]] uint32 nTileCount) -{ - if (nTarget >= RT_STACK_WIDTH || m_nRTStackLevel[nTarget] >= MAX_RT_STACK) - { - return false; - } - HRESULT hr = 0; - SRTStack* pCur = &m_RTStack[nTarget][m_nRTStackLevel[nTarget]]; - pCur->m_pTarget = static_cast(pTargetSurf); - pCur->m_pSurfDepth = pDepthTarget; - pCur->m_pDepth = pDepthTarget ? (D3DDepthSurface*)pDepthTarget->pSurf : NULL; - pCur->m_pTex = NULL; - -#ifdef _DEBUG - if (m_nRTStackLevel[nTarget] == 0 && nTarget == 0) - { - assert(pCur->m_pTarget == m_pBackBuffer && (pDepthTarget == nullptr || pCur->m_pDepth == m_pNativeZBuffer)); - } -#endif - - pCur->m_bNeedReleaseRT = false; - pCur->m_bWasSetRT = false; - pCur->m_bWasSetD = false; - m_pNewTarget[nTarget] = pCur; - if (nTarget == 0) - { - m_RP.m_StateOr &= ~GS_COLMASK_NONE; - } - m_nMaxRT2Commit = max(m_nMaxRT2Commit, nTarget); - m_RP.m_nCommitFlags |= FC_TARGETS; - return (hr == S_OK); -} -bool CD3D9Renderer::FX_PushRenderTarget(int nTarget, void* pTargetSurf, SDepthTexture* pDepthTarget, uint32 nTileCount) -{ - assert(m_pRT->IsRenderThread()); - if (nTarget >= RT_STACK_WIDTH || m_nRTStackLevel[nTarget] >= MAX_RT_STACK) - { - return false; - } - m_nRTStackLevel[nTarget]++; - return FX_SetRenderTarget(nTarget, pTargetSurf, pDepthTarget, nTileCount); -} - -bool CD3D9Renderer::FX_SetRenderTarget(int nTarget, CTexture* pTarget, SDepthTexture* pDepthTarget, bool bPush, int nCMSide, bool bScreenVP, uint32 nTileCount) -{ - assert(!nTarget || !pDepthTarget); - assert((unsigned int) nTarget < RT_STACK_WIDTH); - - if (pTarget && !(pTarget->GetFlags() & FT_USAGE_RENDERTARGET)) - { - CryFatalError("Attempt to bind a non-render-target texture as a render-target"); - } - - if (pTarget && pDepthTarget) - { - if (pTarget->GetWidth() > pDepthTarget->nWidth || pTarget->GetHeight() > pDepthTarget->nHeight) - { - iLog->LogError("Error: RenderTarget '%s' size:%i x %i DepthSurface size:%i x %i \n", pTarget->GetName(), pTarget->GetWidth(), pTarget->GetHeight(), pDepthTarget->nWidth, pDepthTarget->nHeight); - } - assert(pTarget->GetWidth() <= pDepthTarget->nWidth); - assert(pTarget->GetHeight() <= pDepthTarget->nHeight); - } - - if (nTarget >= RT_STACK_WIDTH || m_nRTStackLevel[nTarget] >= MAX_RT_STACK) - { - return false; - } - - SRTStack* pCur = &m_RTStack[nTarget][m_nRTStackLevel[nTarget]]; - D3DSurface* pTargSurf; - - if (pCur->m_pTex) - { - if (pCur->m_bNeedReleaseRT) - { - pCur->m_bNeedReleaseRT = false; - } - m_pNewTarget[0]->m_bWasSetRT = false; - m_pNewTarget[0]->m_pTarget = NULL; - - pCur->m_pTex->DecrementRenderTargetUseCount(); - } - - if (!pTarget) - { - pTargSurf = NULL; - } - else - { - if (!FX_GetTargetSurfaces(pTarget, pTargSurf, pCur, nCMSide, nTarget, nTileCount)) - { - return false; - } - } - - if (pTarget) - { - int nFrameID = m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameUpdateID; - if (pTarget && pTarget->m_nUpdateFrameID != nFrameID) - { - pTarget->m_nUpdateFrameID = nFrameID; - } - } - - if (!bPush && pDepthTarget && pDepthTarget->pSurf != pCur->m_pDepth) - { - //assert(pCur->m_pDepth == m_pCurDepth); - //assert(pCur->m_pDepth != m_pZBuffer); // Attempt to override default Z-buffer surface - if (pCur->m_pSurfDepth) - { - pCur->m_pSurfDepth->bBusy = false; - } - } - pCur->m_pDepth = pDepthTarget ? (D3DDepthSurface*)pDepthTarget->pSurf : NULL; - pCur->m_ClearFlags = 0; - pCur->m_pTarget = pTargSurf; - pCur->m_bNeedReleaseRT = true; - pCur->m_bWasSetRT = false; - pCur->m_bWasSetD = false; - pCur->m_bScreenVP = bScreenVP; - - if (pDepthTarget) - { - pDepthTarget->bBusy = true; - pDepthTarget->nFrameAccess = m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameUpdateID; - } - - if (pTarget) - { - pCur->m_pTex = pTarget; - } - else if (pDepthTarget) - { - pCur->m_pTex = (CTexture*)pDepthTarget->pTex; - } - else - { - pCur->m_pTex = NULL; - } - - if (pCur->m_pTex) - { - pCur->m_pTex->IncrementRenderTargetUseCount(); - } - - pCur->m_pSurfDepth = pDepthTarget; - - if (pTarget) - { - pCur->m_Width = pTarget->GetWidth(); - pCur->m_Height = pTarget->GetHeight(); - } - else - if (pDepthTarget) - { - pCur->m_Width = pDepthTarget->nWidth; - pCur->m_Height = pDepthTarget->nHeight; - } - if (!nTarget) - { - if (bScreenVP) - { - RT_SetViewport(m_MainViewport.nX, m_MainViewport.nY, m_MainViewport.nWidth, m_MainViewport.nHeight); - } - else - { - RT_SetViewport(0, 0, pCur->m_Width, pCur->m_Height); - } - } - m_pNewTarget[nTarget] = pCur; - m_nMaxRT2Commit = max(m_nMaxRT2Commit, nTarget); - m_RP.m_nCommitFlags |= FC_TARGETS; - return true; -} - -CTexture* CD3D9Renderer::FX_GetCurrentRenderTarget(int target) -{ - return m_RTStack[target][gcpRendD3D->m_nRTStackLevel[target]].m_pTex; -} - -D3DSurface* CD3D9Renderer::FX_GetCurrentRenderTargetSurface(int target) const -{ - return m_RTStack[target][gcpRendD3D->m_nRTStackLevel[target]].m_pTarget; -} - -void CD3D9Renderer::FX_SetColorDontCareActions(int const nTarget, - [[maybe_unused]] bool const loadDontCare, - [[maybe_unused]] bool const storeDontCare) -{ - assert((unsigned int) nTarget < RT_STACK_WIDTH); - - SRTStack* srt = m_pNewTarget[nTarget]; - assert(srt); - - if (srt->m_pTarget) - { - // Call appropriate extension depending on rendering platform -#ifdef CRY_USE_METAL - DXMETALSetColorDontCareActions(srt->m_pTarget, loadDontCare, storeDontCare); -#endif -#if defined(ANDROID) - DXGLSetColorDontCareActions(srt->m_pTarget, loadDontCare, storeDontCare); -#endif - } -} - -void CD3D9Renderer::FX_SetDepthDontCareActions(int const nTarget, - [[maybe_unused]] bool const loadDontCare, - [[maybe_unused]] bool const storeDontCare) -{ - assert((unsigned int) nTarget < RT_STACK_WIDTH); - - SRTStack* srt = m_pNewTarget[nTarget]; - assert(srt); - - if (srt->m_pDepth) - { - // Call appropriate extension depending on rendering platform -#ifdef CRY_USE_METAL - DXMETALSetDepthDontCareActions(srt->m_pDepth, loadDontCare, storeDontCare); -#endif -#if defined(ANDROID) - DXGLSetDepthDontCareActions(srt->m_pDepth, loadDontCare, storeDontCare); -#endif - } -} - -void CD3D9Renderer::FX_SetStencilDontCareActions(int const nTarget, - [[maybe_unused]] bool const loadDontCare, - [[maybe_unused]] bool const storeDontCare) -{ - assert((unsigned int) nTarget < RT_STACK_WIDTH); - - SRTStack* srt = m_pNewTarget[nTarget]; - assert(srt); - - if (srt->m_pDepth) - { - // Call appropriate extension depending on rendering platform -#ifdef CRY_USE_METAL - DXMETALSetStencilDontCareActions(srt->m_pDepth, loadDontCare, storeDontCare); -#endif -#if defined(ANDROID) - DXGLSetStencilDontCareActions(srt->m_pDepth, loadDontCare, storeDontCare); -#endif - } -} - -void CD3D9Renderer::FX_TogglePLS([[maybe_unused]] bool const enable) -{ -#if defined(OPENGL_ES) && !defined(DESKTOP_GLES) - DXGLTogglePLS(&GetDeviceContext(), enable); -#endif -} - -bool CD3D9Renderer::FX_PushRenderTarget(int nTarget, CTexture* pTarget, SDepthTexture* pDepthTarget, int nCMSide, bool bScreenVP, uint32 nTileCount) -{ - assert(m_pRT->IsRenderThread()); - - if (nTarget >= RT_STACK_WIDTH || m_nRTStackLevel[nTarget] == MAX_RT_STACK) - { - assert(0); - return false; - } - m_nRTStackLevel[nTarget]++; - return FX_SetRenderTarget(nTarget, pTarget, pDepthTarget, true, nCMSide, bScreenVP, nTileCount); -} - -bool CD3D9Renderer::FX_RestoreRenderTarget(int nTarget) -{ - if (nTarget >= RT_STACK_WIDTH || m_nRTStackLevel[nTarget] < 0) - { - return false; - } - - SRTStack* pCur = &m_RTStack[nTarget][m_nRTStackLevel[nTarget]]; - - SRTStack* pPrev = &m_RTStack[nTarget][m_nRTStackLevel[nTarget] + 1]; - - if (pPrev->m_bNeedReleaseRT) - { - pPrev->m_bNeedReleaseRT = false; - if (pPrev->m_pTarget && pPrev->m_pTarget == m_pNewTarget[nTarget]->m_pTarget) - { - m_pNewTarget[nTarget]->m_bWasSetRT = false; - - pPrev->m_pTarget = NULL; - m_pNewTarget[nTarget]->m_pTarget = NULL; - } - } - - if (nTarget == 0) - { - if (pPrev->m_pSurfDepth) - { - pPrev->m_pSurfDepth->bBusy = false; - pPrev->m_pSurfDepth = NULL; - } - } - if (pPrev->m_pTex) - { - pPrev->m_pTex->DecrementRenderTargetUseCount(); - pPrev->m_pTex = NULL; - } - if (!nTarget) - { - if (pCur->m_bScreenVP) - { - RT_SetViewport(m_MainViewport.nX, m_MainViewport.nY, m_MainViewport.nWidth, m_MainViewport.nHeight); - } - else - if (!m_nRTStackLevel[nTarget]) - { - RT_SetViewport(0, 0, m_backbufferWidth, m_backbufferHeight); - } - else - { - RT_SetViewport(0, 0, pCur->m_Width, pCur->m_Height); - } - } - pCur->m_bWasSetD = false; - pCur->m_bWasSetRT = false; - m_pNewTarget[nTarget] = pCur; - m_nMaxRT2Commit = max(m_nMaxRT2Commit, nTarget); - - m_RP.m_nCommitFlags |= FC_TARGETS; - return true; -} -bool CD3D9Renderer::FX_PopRenderTarget(int nTarget) -{ - assert(m_pRT->IsRenderThread()); - if (m_nRTStackLevel[nTarget] <= 0) - { - assert(0); - return false; - } - m_nRTStackLevel[nTarget]--; - return FX_RestoreRenderTarget(nTarget); -} - -////////////////////////////////////////////////////////////////////////// -// REFACTOR BEGIN: (bethelz) Move scratch depth pool into its own class. - -SDepthTexture* CD3D9Renderer::FX_GetDepthSurface(int nWidth, int nHeight, [[maybe_unused]] bool bAA, bool shaderResourceView) -{ - assert(m_pRT->IsRenderThread()); - - SDepthTexture* pSrf = NULL; - D3D11_TEXTURE2D_DESC desc; - uint32 i; - int nBestX = -1; - int nBestY = -1; - for (i = 0; i < m_TempDepths.Num(); i++) - { - pSrf = m_TempDepths[i]; - if (!pSrf->bBusy && pSrf->pSurf) - { - // verify that this texture supports binding as a shader resource if requested - pSrf->pTarget->GetDesc(&desc); - if (shaderResourceView && !(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) - { - continue; - } - if (pSrf->nWidth == nWidth && pSrf->nHeight == nHeight) - { - nBestX = i; - break; - } - if (nBestX < 0 && pSrf->nWidth == nWidth && pSrf->nHeight >= nHeight) - { - nBestX = i; - } - else - if (nBestY < 0 && pSrf->nWidth >= nWidth && pSrf->nHeight == nHeight) - { - nBestY = i; - } - } - } - if (nBestX >= 0) - { - return m_TempDepths[nBestX]; - } - if (nBestY >= 0) - { - return m_TempDepths[nBestY]; - } - - - bool allowUsingLargerRT = true; - -#if defined(CRY_OPENGL_DO_NOT_ALLOW_LARGER_RT) - allowUsingLargerRT = false; -#elif defined(SUPPORT_D3D_DEBUG_RUNTIME) - if (CV_d3d11_debugruntime) - { - allowUsingLargerRT = false; - } -#endif - - if (allowUsingLargerRT) - { - for (i = 0; i < m_TempDepths.Num(); i++) - { - pSrf = m_TempDepths[i]; - // verify that this texture supports binding as a shader resource if requested - pSrf->pTarget->GetDesc(&desc); - if (shaderResourceView && !(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) - { - continue; - } - if (pSrf->nWidth >= nWidth && pSrf->nHeight >= nHeight && !pSrf->bBusy) - { - break; - } - } - } - else - { - i = m_TempDepths.Num(); - } - - if (i == m_TempDepths.Num()) - { - pSrf = CreateDepthSurface(nWidth, nHeight, shaderResourceView); - if (pSrf != nullptr) - { - if (pSrf->pSurf != nullptr) - { - m_TempDepths.AddElem(pSrf); - } - else - { - DestroyDepthSurface(pSrf); - pSrf = nullptr; - } - } - } - - return pSrf; -} - -// Commit changes states to the hardware before drawing -bool CD3D9Renderer::FX_CommitStreams(SShaderPass* sl, bool bSetVertexDecl) -{ - FUNCTION_PROFILER_RENDER_FLAT - - //PROFILE_FRAME(Draw_Predraw); - SRenderPipeline& RESTRICT_REFERENCE rp(m_RP); - -#if ENABLE_NORMALSTREAM_SUPPORT - if (CHWShader_D3D::s_pCurInstHS) - { - rp.m_FlagsStreams_Stream |= (1 << VSF_NORMALS); - rp.m_FlagsStreams_Decl |= (1 << VSF_NORMALS); - } -#endif - - HRESULT hr; - if (bSetVertexDecl) - { - if ((m_RP.m_ObjFlags & FOB_POINT_SPRITE) && !CHWShader_D3D::s_pCurInstHS) - { - rp.m_FlagsStreams_Stream |= VSM_INSTANCED; - rp.m_FlagsStreams_Decl |= VSM_INSTANCED; - } - hr = FX_SetVertexDeclaration(rp.m_FlagsStreams_Decl, rp.m_CurVFormat); - if (FAILED(hr)) - { - return false; - } - } - - if (rp.m_pRE) - { - bool bRet = rp.m_pRE->mfPreDraw(sl); - return bRet; - } - else if (rp.m_RendNumVerts && rp.m_RendNumIndices) - { - if (rp.m_FlagsPerFlush & RBSI_EXTERN_VMEM_BUFFERS) - { - assert(rp.m_pExternalVertexBuffer); - assert(rp.m_pExternalIndexBuffer); - - // bind out external vertex/index buffer to use those directly, the client code has to set them up correctly - rp.m_pExternalVertexBuffer->Bind(0, 0, rp.m_StreamStride); - rp.m_pExternalIndexBuffer->Bind(0); - - // adjust the first index to render from as well as - // other renderer stats - rp.m_FirstIndex = rp.m_nExternalVertexBufferFirstIndex; - rp.m_FirstVertex = rp.m_nExternalVertexBufferFirstVertex; - - rp.m_PS[rp.m_nProcessThreadID].m_DynMeshUpdateBytes += rp.m_StreamStride * rp.m_RendNumVerts; - rp.m_PS[rp.m_nProcessThreadID].m_DynMeshUpdateBytes += rp.m_RendNumIndices * sizeof(short); - - // clear external video memory buffer flag - rp.m_FlagsPerFlush &= ~RBSI_EXTERN_VMEM_BUFFERS; - rp.m_nExternalVertexBufferFirstIndex = 0; - rp.m_nExternalVertexBufferFirstVertex = 0; - rp.m_pExternalVertexBuffer = NULL; - rp.m_pExternalIndexBuffer = NULL; - } - else - { - /* NOTE: - * It is extremely important that transient dynamic VBs are filled in binding order. - * In the following case, rp.m_StreamPtr.Ptr verts data should be filled PRIOR the tangents. - * This is due to underlying restrictions of certain rendering layers such as METAL. - * The METAL renderer uses a ring buffer for transient data mapped to dynamic VBs. - * To calculate the proper offsets when binding the buffers, it assumes the map/unmap - * order is following an increasing VB slots binding. - * - * If the order is switched (tangents are filled before positions), the tangent data - * will be used in the slot before the position which will result in a mismatch with - * the expected IA layout. This will either cause artifacts or nothing to be rendered. - */ - - { - TempDynVBAny::CreateFillAndBind(rp.m_StreamPtr.Ptr, rp.m_RendNumVerts, 0, rp.m_StreamStride); - rp.m_FirstVertex = 0; - rp.m_PS[rp.m_nProcessThreadID].m_DynMeshUpdateBytes += rp.m_RendNumVerts * rp.m_StreamStride; - } - - if (rp.m_FlagsStreams_Stream & VSM_TANGENTS) - { - TempDynVB::CreateFillAndBind((const SPipTangents*) rp.m_StreamPtrTang.Ptr, rp.m_RendNumVerts, VSF_TANGENTS); - rp.m_PersFlags1 |= RBPF1_USESTREAM << VSF_TANGENTS; - rp.m_PS[rp.m_nProcessThreadID].m_DynMeshUpdateBytes += rp.m_RendNumVerts * sizeof(SPipTangents); - } - else - if (rp.m_PersFlags1 & (RBPF1_USESTREAM << (VSF_TANGENTS | VSF_QTANGENTS))) - { - rp.m_PersFlags1 &= ~(RBPF1_USESTREAM << (VSF_TANGENTS | VSF_QTANGENTS)); - FX_SetVStream(1, NULL, 0, 0); - } - - { - TempDynIB16::CreateFillAndBind(rp.m_SysRendIndices, rp.m_RendNumIndices); - rp.m_FirstIndex = 0; - rp.m_PS[rp.m_nProcessThreadID].m_DynMeshUpdateBytes += rp.m_RendNumIndices * sizeof(short); - } - } - } - - return true; -} - -// Draw current indexed mesh -void CD3D9Renderer::FX_DrawIndexedMesh (const eRenderPrimitiveType nPrimType) -{ - DETAILED_PROFILE_MARKER("FX_DrawIndexedMesh"); - FX_Commit(); - - // Don't render fallback in DX11 - if (!CHWShader_D3D::s_pCurInstVS || !CHWShader_D3D::s_pCurInstPS || CHWShader_D3D::s_pCurInstVS->m_bFallback || CHWShader_D3D::s_pCurInstPS->m_bFallback) - { - return; - } - if (CHWShader_D3D::s_pCurInstGS && CHWShader_D3D::s_pCurInstGS->m_bFallback) - { - return; - } - - PROFILE_FRAME(Draw_DrawCall); - - if (nPrimType != eptHWSkinGroups) - { - eRenderPrimitiveType eType = nPrimType; - int nFirstI = m_RP.m_FirstIndex; - int nNumI = m_RP.m_RendNumIndices; -#ifdef TESSELLATION_RENDERER - if (CHWShader_D3D::s_pCurInstHS) - { - FX_SetAdjacencyOffsetBuffer(); - eType = ept3ControlPointPatchList; - } -#endif - FX_DrawIndexedPrimitive(eType, 0, 0, m_RP.m_RendNumVerts, nFirstI, nNumI); - -#if defined(ENABLE_PROFILING_CODE) -# ifdef TESSELLATION_RENDERER - m_RP.m_PS[m_RP.m_nProcessThreadID].m_nPolygonsByTypes[m_RP.m_nPassGroupDIP][EVCT_STATIC][m_RP.m_nBatchFilter == FB_Z] += (nPrimType == eptTriangleList || nPrimType == ept3ControlPointPatchList ? nNumI / 3 : nNumI - 2); -# else - m_RP.m_PS[m_RP.m_nProcessThreadID].m_nPolygonsByTypes[m_RP.m_nPassGroupDIP][EVCT_STATIC][m_RP.m_nBatchFilter == FB_Z] += (nPrimType == eptTriangleList ? nNumI / 3 : nNumI - 2); -# endif -#endif - } - else - { - CRenderChunk* pChunk = m_RP.m_pRE->mfGetMatInfo(); - if (pChunk) - { - int nNumVerts = pChunk->nNumVerts; - - int nFirstIndexId = pChunk->nFirstIndexId; - int nNumIndices = pChunk->nNumIndices; - - if (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & (RBPF_SHADOWGEN) && (gRenDev->m_RP.m_PersFlags2 & RBPF2_DISABLECOLORWRITES)) - { - _smart_ptr pMaterial = (m_RP.m_pCurObject) ? (m_RP.m_pCurObject->m_pCurrMaterial) : NULL; - ((CREMeshImpl*)m_RP.m_pRE)->m_pRenderMesh->AddShadowPassMergedChunkIndicesAndVertices(pChunk, pMaterial, nNumVerts, nNumIndices); - } - - eRenderPrimitiveType eType = eptTriangleList; - - #ifdef TESSELLATION_RENDERER - if (CHWShader_D3D::s_pCurInstHS) - { - FX_SetAdjacencyOffsetBuffer(); - eType = ept3ControlPointPatchList; - } - #endif - FX_DrawIndexedPrimitive(eType, 0, 0, nNumVerts, nFirstIndexId, nNumIndices); - - #if defined(ENABLE_PROFILING_CODE) - m_RP.m_PS[m_RP.m_nProcessThreadID].m_nPolygonsByTypes[m_RP.m_nPassGroupDIP][EVCT_SKINNED][m_RP.m_nBatchFilter == FB_Z] += (pChunk->nNumIndices / 3); - #endif - } - } -} - -//==================================================================================== - - -TArray CD3D9Renderer::s_tempObjects[2]; -TArray CD3D9Renderer::s_tempRIs; - -// Actual drawing of instances -void CD3D9Renderer::FX_DrawInstances([[maybe_unused]] CShader* ef, SShaderPass* slw, [[maybe_unused]] int nRE, uint32 nStartInst, uint32 nLastInst, uint32 nUsedAttr, [[maybe_unused]] byte* InstanceData, int nInstAttrMask, byte Attributes[], [[maybe_unused]] short dwCBufSlot) -{ - DETAILED_PROFILE_MARKER("FX_DrawInstances"); - uint32 i; - - - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - - - if (!CHWShader_D3D::s_pCurInstVS || !CHWShader_D3D::s_pCurInstPS || CHWShader_D3D::s_pCurInstVS->m_bFallback || CHWShader_D3D::s_pCurInstPS->m_bFallback) - { - return; - } - - PREFAST_SUPPRESS_WARNING(6326) - if (!nStartInst) - { - // Set the stream 3 to be per instance data and iterate once per instance - rRP.m_PersFlags1 &= ~(RBPF1_USESTREAM << 3); - if (!FX_CommitStreams(slw, false)) - { - return; - } - int StreamMask = rRP.m_FlagsStreams_Decl >> 1; - SVertexDeclaration* vd = 0; - // See if the desired vertex declaration already exists in m_CustomVD - for (i = 0; i < rRP.m_CustomVD.Num(); i++) - { - vd = rRP.m_CustomVD[i]; - if (vd->StreamMask == StreamMask && rRP.m_CurVFormat == vd->VertexFormat && vd->InstAttrMask == nInstAttrMask && vd->m_vertexShader == CHWShader_D3D::s_pCurInstVS) - { - break; - } - } - // If the vertex declaration was not found, create it - if (i == rRP.m_CustomVD.Num()) - { - vd = new SVertexDeclaration; - rRP.m_CustomVD.AddElem(vd); - vd->StreamMask = StreamMask; - vd->VertexFormat = rRP.m_CurVFormat; - vd->InstAttrMask = nInstAttrMask; - vd->m_pDeclaration = NULL; - vd->m_vertexShader = CHWShader_D3D::s_pCurInstVS; - - // Copy the base vertex format declaration - SOnDemandD3DVertexDeclaration Decl; - EF_OnDemandVertexDeclaration(Decl, StreamMask, rRP.m_CurVFormat, false, false); - - int nElementsToCopy = Decl.m_Declaration.size(); - for (i = 0; i < (uint32)nElementsToCopy; i++) - { - vd->m_Declaration.push_back(Decl.m_Declaration[i]); - } - - // Add additional D3D11_INPUT_ELEMENT_DESCs with the TEXCOORD semantic to the end of the vertex declaration to handle the per instance data - uint32 texCoordSemanticIndexOffset = rRP.m_CurVFormat.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord); - D3D11_INPUT_ELEMENT_DESC elemTC = {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 3, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}; // texture - for (i = 0; i < nUsedAttr; i++) - { - elemTC.AlignedByteOffset = i * INST_PARAM_SIZE; - elemTC.SemanticIndex = Attributes[i] + texCoordSemanticIndexOffset; - vd->m_Declaration.push_back(elemTC); - } - } - if (!vd->m_pDeclaration) - { - HRESULT hr = S_OK; - assert (CHWShader_D3D::s_pCurInstVS && CHWShader_D3D::s_pCurInstVS->m_pShaderData); - if (FAILED(hr = GetDevice().CreateInputLayout(&vd->m_Declaration[0], vd->m_Declaration.size(), CHWShader_D3D::s_pCurInstVS->m_pShaderData, CHWShader_D3D::s_pCurInstVS->m_nDataSize, &vd->m_pDeclaration))) - { - return; - } - } - if (m_pLastVDeclaration != vd->m_pDeclaration) - { - m_pLastVDeclaration = vd->m_pDeclaration; - m_DevMan.BindVtxDecl(vd->m_pDeclaration); - } - } - - int nInsts = nLastInst - nStartInst + 1; - { - //PROFILE_FRAME(Draw_ShaderIndexMesh); -#ifndef _RELEASE - char instanceLabel[64]; - if (CV_r_geominstancingdebug) - { - snprintf(instanceLabel, 63, "Instances: %d", nInsts); - PROFILE_LABEL_PUSH(instanceLabel); - } -#endif - - assert (rRP.m_pRE && rRP.m_pRE->mfGetType() == eDATA_Mesh); - FX_Commit(); - D3D11_PRIMITIVE_TOPOLOGY eTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; -#ifdef TESSELLATION_RENDERER - if (CHWShader_D3D::s_pCurInstHS) - { - FX_SetAdjacencyOffsetBuffer(); - eTopology = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; - } -#endif - SetPrimitiveTopology(eTopology); - m_DevMan.DrawIndexedInstanced(rRP.m_RendNumIndices, nInsts, ApplyIndexBufferBindOffset(rRP.m_FirstIndex), 0, 0); - -#ifndef _RELEASE - if (CV_r_geominstancingdebug) - { - PROFILE_LABEL_POP(instanceLabel); - } -#endif - -#if defined(ENABLE_PROFILING_CODE) - int nPolysPerInst = rRP.m_RendNumIndices / 3; - int nPolysAll = nPolysPerInst * nInsts; - rRP.m_PS[rRP.m_nProcessThreadID].m_nPolygons[rRP.m_nPassGroupDIP] += rRP.m_RendNumIndices / 3; - rRP.m_PS[rRP.m_nProcessThreadID].m_nDIPs[rRP.m_nPassGroupDIP] += nInsts; - rRP.m_PS[rRP.m_nProcessThreadID].m_nPolygons[rRP.m_nPassGroupDIP] += nPolysAll; - rRP.m_PS[rRP.m_nProcessThreadID].m_nInsts += nInsts; - rRP.m_PS[rRP.m_nProcessThreadID].m_nInstCalls++; -#endif - } -} - -#define MAX_HWINST_PARAMS_CONST (240 - VSCONST_INSTDATA) - -// Draw geometry instances in single DIP using HW geom. instancing (StreamSourceFreq) -void CD3D9Renderer::FX_DrawShader_InstancedHW(CShader* ef, SShaderPass* slw) -{ -#if defined(HW_INSTANCING_ENABLED) - PROFILE_FRAME(DrawShader_Instanced); - - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - // Set culling mode - if (!(rRP.m_FlagsPerFlush & RBSI_LOCKCULL)) - { - if (slw->m_eCull != -1) - { - D3DSetCull((ECull)slw->m_eCull); - } - } - - bool bProcessedAll = true; - - uint32 i; - - SCGBind bind; - byte Attributes[32]; - - rRP.m_FlagsPerFlush |= RBSI_INSTANCED; - - TempDynInstVB vb(gcpRendD3D); - - uint32 nCurInst; - byte* data = NULL; - CShaderResources* pCurRes = rRP.m_pShaderResources; - CShaderResources* pSaveRes = pCurRes; - - uint64 nRTFlags = rRP.m_FlagsShader_RT; - uint64 nSaveRTFlags = nRTFlags; - - // batch further and send everything as if it's rotated (full 3x4 matrix), even if we could - // just send position - uint64* __restrict maskBit = g_HWSR_MaskBit; - - nRTFlags |= maskBit[HWSR_INSTANCING_ATTR]; - - if IsCVarConstAccess(constexpr) (CV_r_geominstancingdebug > 1) - { - // !DEBUG0 && !DEBUG1 && DEBUG2 && DEBUG3 - nRTFlags &= ~(maskBit[HWSR_DEBUG0] | maskBit[HWSR_DEBUG1]); - nRTFlags |= (maskBit[HWSR_DEBUG2] | maskBit[HWSR_DEBUG3]); - } - - rRP.m_FlagsShader_RT = nRTFlags; - - if (CRenderer::CV_r_SlimGBuffer) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - short dwCBufSlot = 0; - - CHWShader_D3D* vp = (CHWShader_D3D*)slw->m_VShader; - CHWShader_D3D* ps = (CHWShader_D3D*)slw->m_PShader; - - // Set Pixel shader and all associated textures - // Note: Need to set pixel shader first to properly set up modifiers for vertex shader (see ShaderCore.cpp & ModificatorTC.cfi) - if (!ps->mfSet(HWSF_SETTEXTURES)) - { - rRP.m_FlagsShader_RT = nSaveRTFlags; - - rRP.m_pShaderResources = pSaveRes; - rRP.m_PersFlags1 |= RBPF1_USESTREAM << 3; - return; - } - - // Set Vertex shader - if (!vp->mfSet(HWSF_INSTANCED | HWSF_SETTEXTURES)) - { - rRP.m_FlagsShader_RT = nSaveRTFlags; - - rRP.m_pShaderResources = pSaveRes; - rRP.m_PersFlags1 |= RBPF1_USESTREAM << 3; - return; - } - - CHWShader_D3D::SHWSInstance* pVPInst = vp->m_pCurInst; - if (!pVPInst || pVPInst->m_bFallback || (ps->m_pCurInst && ps->m_pCurInst->m_bFallback)) - { - return; - } - - CHWShader_D3D* curGS = (CHWShader_D3D*)slw->m_GShader; - if (curGS) - { - curGS->mfSet(0); - curGS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindGS(nullptr, nullptr); - } - - CHWShader_D3D* pCurHS, * pCurDS; - bool bTessEnabled = FX_SetTessellationShaders(pCurHS, pCurDS, slw); - - vp->UpdatePerInstanceConstantBuffer(); - ps->UpdatePerInstanceConstantBuffer(); - - #ifdef TESSELLATION_RENDERER - CHWShader_D3D* curCS = (CHWShader_D3D*)slw->m_CShader; - if (curCS) - { - curCS->mfSetCS(0); - } - else - { - CHWShader_D3D::mfBindCS(nullptr, nullptr); - } - - if (pCurDS) - { - pCurDS->UpdatePerInstanceConstantBuffer(); - } - if (pCurHS) - { - pCurHS->UpdatePerInstanceConstantBuffer(); - } - #endif - - // VertexDeclaration of MeshInstance always starts with InstMatrix which has 3 vector4, that's why nUsedAttr is 3. - int32 nUsedAttr = 3, nInstAttrMask = 0; - pVPInst->GetInstancingAttribInfo(Attributes, nUsedAttr, nInstAttrMask); - - IRenderElement* pRE = NULL; - CRenderMesh* pRenderMesh = NULL; - - const int nLastRE = rRP.m_nLastRE; - for (int nRE = 0; nRE <= nLastRE; nRE++) - { - uint32 nRIs = rRP.m_RIs[nRE].size(); - SRendItem** rRIs = &(rRP.m_RIs[nRE][0]); - - // don't process REs that don't make the cut for instancing. - // these were batched with an instance-ready RE, so leave this to drop through into DrawBatch - if (nRIs <= (uint32)CRenderer::m_iGeomInstancingThreshold) - { - bProcessedAll = false; - continue; - } - - CShaderResources* pRes = SRendItem::mfGetRes(rRIs[0]->SortVal); - pRE = rRP.m_pRE = rRIs[0]->pElem; - rRP.m_pCurObject = rRIs[0]->pObj; - - CREMeshImpl* __restrict pMesh = (CREMeshImpl*) pRE; - - pRE->mfPrepare(false); - { - if (pCurRes != pRes) - { - rRP.m_pShaderResources = pRes; - CHWShader_D3D::UpdatePerMaterialConstantBuffer(); - - vp->UpdatePerBatchConstantBuffer(); - if (vp->m_pCurInst) - { - vp->mfSetSamplers(vp->m_pCurInst->m_pSamplers, eHWSC_Vertex); - } - ps->UpdatePerBatchConstantBuffer(); - if (ps->m_pCurInst) - { - ps->mfSetSamplers(ps->m_pCurInst->m_pSamplers, eHWSC_Pixel); - } -#ifdef TESSELLATION_RENDERER - if (pCurDS && pCurDS->m_pCurInst) - { - pCurDS->mfSetSamplers(pCurDS->m_pCurInst->m_pSamplers, eHWSC_Domain); - } -#endif - pCurRes = pRes; - } - - if (pMesh->m_pRenderMesh != pRenderMesh) - { - // Create/Update video mesh (VB management) - if (!pRE->mfCheckUpdate(rRP.m_FlagsStreams_Stream, rTI.m_nFrameUpdateID, bTessEnabled)) - { - rRP.m_FlagsShader_RT = nSaveRTFlags; - - rRP.m_pShaderResources = pSaveRes; - rRP.m_PersFlags1 |= RBPF1_USESTREAM << 3; - return; - } - - pRenderMesh = pMesh->m_pRenderMesh; - } - - { - nCurInst = 0; - - // Detects possibility of using attributes based instancing - // If number of used attributes exceed 16 we can't use attributes based instancing (switch to constant based) - int nStreamMask = rRP.m_FlagsStreams_Stream >> 1; - int nVFormat = rRP.m_CurVFormat.GetEnum(); - uint32 nCO = 0; - uint32 dwDeclarationSize = 0; - if (dwDeclarationSize + nUsedAttr - 1 > 16) - { - iLog->LogWarning("WARNING: Attributes based instancing cannot exceed 16 attributes (%s uses %d attr. + %d vertex decl.attr.)[VF: %d, SM: 0x%x]", vp->GetName(), nUsedAttr, dwDeclarationSize - 1, nVFormat, nStreamMask); - } - else - { - while ((int)nCurInst < nRIs) - { - uint32 nLastInst = nRIs - 1; - - { - uint32 nParamsPerInstAllowed = MAX_HWINST_PARAMS; - if ((nLastInst - nCurInst + 1) * nUsedAttr >= nParamsPerInstAllowed) - { - nLastInst = nCurInst + (nParamsPerInstAllowed / nUsedAttr) - 1; - } - } - { - vb.Allocate(nLastInst - nCurInst + 1, nUsedAttr * INST_PARAM_SIZE); - data = (byte*) vb.Lock(); - } - CRenderObject* curObj = rRP.m_pCurObject; - - // 3 float4 = inst Matrix - const AZ::u32 perInstanceStride = nUsedAttr * sizeof(float[4]); - - // Fill the stream 3 for per-instance data - byte* pWalkData = data; - for (i = nCurInst; i <= nLastInst; i++) - { - CRenderObject* renderObject = rRIs[nCO++]->pObj; - rRP.m_pCurObject = renderObject; - AzRHI::SIMDCopy(pWalkData, renderObject->m_II.m_Matrix.GetData(), 3); - - if (pVPInst->m_nParams_Inst >= 0) - { - SCGParamsGroup& Group = CGParamManager::s_Groups[pVPInst->m_nParams_Inst]; - vp->UpdatePerInstanceConstants(eHWSC_Vertex, Group.pParams, Group.nParams, pWalkData); - } - - pWalkData += perInstanceStride; - } - rRP.m_pCurObject = curObj; - - vb.Unlock(); - - // Set the first stream to be the indexed data and render N instances - vb.Bind(3, nUsedAttr * INST_PARAM_SIZE); - - vb.Release(); - - FX_DrawInstances(ef, slw, nRE, nCurInst, nLastInst, nUsedAttr, data, nInstAttrMask, Attributes, dwCBufSlot); - - nCurInst = nLastInst + 1; - } - } - } - } - } -#ifdef TESSELLATION_RENDERER - if (bTessEnabled) - { - CHWShader_D3D::mfBindDS(NULL, NULL); - CHWShader_D3D::mfBindHS(NULL, NULL); - } -#endif - - rRP.m_PersFlags1 |= RBPF1_USESTREAM << 3; - rRP.m_pShaderResources = pSaveRes; - rRP.m_nCommitFlags = FC_ALL; - rRP.m_FlagsShader_RT = nSaveRTFlags; - rRP.m_nNumRendPasses++; - if (!bProcessedAll) - { - FX_DrawBatches(ef, slw); - } -#else - CryFatalError("HW Instancing not supported on this platform"); -#endif -} -//#endif - -//==================================================================================== - -byte CD3D9Renderer::FX_StartQuery(SRendItem* pRI) -{ - if (!CV_r_ConditionalRendering || !(m_RP.m_nBatchFilter & (FB_Z | FB_GENERAL))) - { - return 0; - } -#if !defined(NULL_RENDERER) - if (m_RP.m_nBatchFilter & FB_Z) - { - if (m_OcclQueriesUsed >= MAX_OCCL_QUERIES) - { - return 0; - } - - assert(pRI->nOcclQuery > MAX_OCCL_QUERIES); - uint32 nQuery = m_OcclQueriesUsed; - ++m_OcclQueriesUsed; - COcclusionQuery* pQ = &m_OcclQueries[nQuery]; - if (!pQ->IsCreated()) - { - pQ->Create(); - } - pQ->BeginQuery(); - pRI->nOcclQuery = nQuery; -#ifndef _RELEASE - m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumQIssued++; -#endif - return 1; - } - else - { - if (pRI->nOcclQuery >= MAX_OCCL_QUERIES || pRI->nOcclQuery < 0) - { - return 0; - } - - COcclusionQuery* pQ = &m_OcclQueries[pRI->nOcclQuery]; -#ifndef _RELEASE - CTimeValue Time = iTimer->GetAsyncTime(); -#endif - uint32 nPixels = pQ->GetVisibleSamples(CV_r_ConditionalRendering == 2 ? false : true); -#ifndef _RELEASE - m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumQStallTime += static_cast(iTimer->GetAsyncTime().GetMilliSeconds() - Time.GetMilliSeconds()); -#endif - bool bReady = pQ->IsReady(); - if (!bReady) - { -#ifndef _RELEASE - m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumQNotReady++; -#endif - return 0; - } - if (nPixels == 0) - { -#ifndef _RELEASE - m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumQOccluded++; -#endif - return 2; - } - return 0; - } -#endif -} - -void CD3D9Renderer::FX_EndQuery(SRendItem* pRI, byte bStartQ) -{ - if (!bStartQ) - { - return; - } - - assert(pRI->nOcclQuery < MAX_OCCL_QUERIES); - COcclusionQuery* pQ = &m_OcclQueries[pRI->nOcclQuery]; - pQ->EndQuery(); -} - -void CD3D9Renderer::FX_DrawBatchesSkinned(CShader* pSh, SShaderPass* pPass, SSkinningData* pSkinningData) -{ - DETAILED_PROFILE_MARKER("FX_DrawBatchesSkinned"); - PROFILE_FRAME(DrawShader_BatchSkinned); - - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - CHWShader_D3D* pCurVS = (CHWShader_D3D*)pPass->m_VShader; - CHWShader_D3D* pCurPS = (CHWShader_D3D*)pPass->m_PShader; - - const int nThreadID = m_RP.m_nProcessThreadID; - const int bRenderLog = CRenderer::CV_r_log; - CREMeshImpl* pRE = (CREMeshImpl*) rRP.m_pRE; - CRenderObject* const pSaveObj = rRP.m_pCurObject; - - CHWShader_D3D* pCurGS = (CHWShader_D3D*)pPass->m_GShader; - - - CRenderMesh* pRenderMesh = pRE->m_pRenderMesh; - - rRP.m_nNumRendPasses++; - rRP.m_RendNumGroup = 0; - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_VERTEX_VELOCITY]; - - if (pSkinningData->nHWSkinningFlags & eHWS_Skinning_Matrix) - { - rRP.m_FlagsShader_RT |= (g_HWSR_MaskBit[HWSR_SKINNING_MATRIX]); - } - else if (pSkinningData->nHWSkinningFlags & eHWS_Skinning_DQ_Linear) - { - rRP.m_FlagsShader_RT |= (g_HWSR_MaskBit[HWSR_SKINNING_DQ_LINEAR]); - } - else - { - rRP.m_FlagsShader_RT |= (g_HWSR_MaskBit[HWSR_SKINNING_DUAL_QUAT]); - } - - bool bRes = pCurPS->mfSetPS(HWSF_SETTEXTURES); - bRes &= pCurVS->mfSetVS(0); - - CHWShader_D3D* pCurHS, *pCurDS; - bool bTessEnabled = FX_SetTessellationShaders(pCurHS, pCurDS, pPass); - - if (pCurGS) - { - bRes &= pCurGS->mfSetGS(0); - } - else - { - CHWShader_D3D::mfBindGS(NULL, NULL); - } - - const uint numObjects = rRP.m_RIs[0].Num(); - - if (!bRes) - { - goto done; - } - - if (CHWShader_D3D::s_pCurInstVS && CHWShader_D3D::s_pCurInstVS->m_bFallback) - { - goto done; - } - - // Create/Update video mesh (VB management) - if (!pRE->mfCheckUpdate(m_RP.m_FlagsStreams_Stream, rTI.m_nFrameUpdateID, bTessEnabled)) - { - goto done; - } - - if (ShouldApplyFogCorrection()) - { - FX_FogCorrection(); - } - - // Unlock all VB (if needed) and set current streams - if (!FX_CommitStreams(pPass)) - { - goto done; - } - - for (uint nObj = 0; nObj < numObjects; ++nObj) - { - CRenderObject* pObject = rRP.m_RIs[0][nObj]->pObj; - rRP.m_pCurObject = pObject; - -#ifdef DO_RENDERSTATS - if (FX_ShouldTrackStats()) - { - FX_TrackStats(pObject, pRE->m_pRenderMesh); - } -#endif - -#ifdef DO_RENDERLOG - if (bRenderLog >= 3) - { - Vec3 vPos = pObject->GetTranslation(); - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "+++ HWSkin Group Pass %d (Obj: %d [%.3f, %.3f, %.3f])\n", m_RP.m_nNumRendPasses, pObject->m_Id, vPos[0], vPos[1], vPos[2]); - } -#endif - - pCurVS->UpdatePerInstanceConstantBuffer(); - pCurPS->UpdatePerInstanceConstantBuffer(); - - if (pCurGS) - { - pCurGS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindGS(NULL, NULL); - } -#ifdef TESSELLATION_RENDERER - if (pCurDS) - { - pCurDS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindDS(NULL, NULL); - } - if (pCurHS) - { - pCurHS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindHS(NULL, NULL); - } -#endif - - AzRHI::ConstantBuffer* pBuffer[2] = { NULL }; - SRenderObjData* pOD = pObject->GetObjData(); - assert(pOD); - if (pOD) - { - SSkinningData* const skinningData = pOD->m_pSkinningData; - if (!pRE->BindRemappedSkinningData(skinningData->remapGUID)) - { - continue; - } - - pBuffer[0] = alias_cast(skinningData->pCharInstCB)->m_buffer; - -#ifdef CRY_USE_METAL - // Buffer is sometimes null... binding a null skinned VB will fail on METAL - if (!pBuffer[0]) - { - continue; - } -#endif - - // get previous data for motion blur if available - if (skinningData->pPreviousSkinningRenderData) - { - pBuffer[1] = alias_cast(skinningData->pPreviousSkinningRenderData->pCharInstCB)->m_buffer; - } - } - else - { - continue; - } - -#ifndef _RELEASE - rRP.m_PS[nThreadID].m_NumRendSkinnedObjects++; -#endif - - m_PerInstanceConstantBufferPool.SetConstantBuffer(rRP.m_RIs[0][nObj]); - - m_DevMan.BindConstantBuffer(eHWSC_Vertex, pBuffer[0], eConstantBufferShaderSlot_SkinQuat); - m_DevMan.BindConstantBuffer(eHWSC_Vertex, pBuffer[1], eConstantBufferShaderSlot_SkinQuatPrev); - { - DETAILED_PROFILE_MARKER("DrawSkinned"); - if (rRP.m_pRE) - { - rRP.m_pRE->mfDraw(pSh, pPass); - } - else - { - FX_DrawIndexedMesh(pRenderMesh ? pRenderMesh->GetPrimitiveType() : eptTriangleList); - } - } - } - -done: - - m_DevMan.BindConstantBuffer(eHWSC_Vertex, nullptr, eConstantBufferShaderSlot_SkinQuat); - m_DevMan.BindConstantBuffer(eHWSC_Vertex, nullptr, eConstantBufferShaderSlot_SkinQuatPrev); - - rRP.m_FlagsShader_MD &= ~HWMD_TEXCOORD_FLAG_MASK; - rRP.m_pCurObject = pSaveObj; - -#ifdef TESSELLATION_RENDERER - if (bTessEnabled) - { - CHWShader_D3D::mfBindDS(NULL, NULL); - CHWShader_D3D::mfBindHS(NULL, NULL); - } -#endif - rRP.m_RendNumGroup = -1; -} - -#if defined(DO_RENDERSTATS) -void CD3D9Renderer::FX_TrackStats([[maybe_unused]] CRenderObject* pObj, [[maybe_unused]] IRenderMesh* pRenderMesh) -{ -#if !defined(_RELEASE) - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - if (pObj) - { - if (IRenderNode* pRenderNode = (IRenderNode*)pObj->m_pRenderNode) - { - //Add to per node map for r_stats 6 - if (CV_r_stats == 6 || m_pDebugRenderNode || m_bCollectDrawCallsInfoPerNode) - { - IRenderer::RNDrawcallsMapNode& drawCallsInfoPerNode = rRP.m_pRNDrawCallsInfoPerNode[m_RP.m_nProcessThreadID]; - - IRenderer::RNDrawcallsMapNodeItor pItor = drawCallsInfoPerNode.find(pRenderNode); - - if (pItor != drawCallsInfoPerNode.end()) - { - SDrawCallCountInfo& pInfoDP = pItor->second; - pInfoDP.Update(pObj, pRenderMesh); - } - else - { - SDrawCallCountInfo pInfoDP; - pInfoDP.Update(pObj, pRenderMesh); - drawCallsInfoPerNode.insert(IRenderer::RNDrawcallsMapNodeItor::value_type(pRenderNode, pInfoDP)); - } - } - - //Add to per mesh map for perfHUD - if (m_bCollectDrawCallsInfo) - { - IRenderer::RNDrawcallsMapMesh& drawCallsInfoPerMesh = rRP.m_pRNDrawCallsInfoPerMesh[m_RP.m_nProcessThreadID]; - - IRenderer::RNDrawcallsMapMeshItor pItor = drawCallsInfoPerMesh.find(pRenderMesh); - - if (pItor != drawCallsInfoPerMesh.end()) - { - SDrawCallCountInfo& pInfoDP = pItor->second; - pInfoDP.Update(pObj, pRenderMesh); - } - else - { - SDrawCallCountInfo pInfoDP; - pInfoDP.Update(pObj, pRenderMesh); - drawCallsInfoPerMesh.insert(IRenderer::RNDrawcallsMapMeshItor::value_type(pRenderMesh, pInfoDP)); - } - } - } - } -#endif -} -#endif - - - -bool CD3D9Renderer::FX_SetTessellationShaders(CHWShader_D3D*& pCurHS, CHWShader_D3D*& pCurDS, const SShaderPass* pPass) -{ - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - -#ifdef TESSELLATION_RENDERER - pCurHS = (CHWShader_D3D*)pPass->m_HShader; - pCurDS = (CHWShader_D3D*)pPass->m_DShader; - - bool bTessEnabled = (pCurHS != NULL) && (pCurDS != NULL) && !(rRP.m_pCurObject->m_ObjFlags & FOB_NEAREST) && (rRP.m_pCurObject->m_ObjFlags & FOB_ALLOW_TESSELLATION); - -#ifndef MOTIONBLUR_TESSELLATION - bTessEnabled &= !(rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS); -#endif - - if (bTessEnabled && pCurHS->mfSetHS(0) && pCurDS->mfSetDS(HWSF_SETTEXTURES)) - { - if (CV_r_tessellationdebug == 1) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG1]; - } - - return true; - } - - CHWShader_D3D::mfBindHS(NULL, NULL); - CHWShader_D3D::mfBindDS(NULL, NULL); -#endif - - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NO_TESSELLATION]; - - pCurHS = NULL; - pCurDS = NULL; - - return false; -} - -#ifdef TESSELLATION_RENDERER - -void CD3D9Renderer::FX_SetAdjacencyOffsetBuffer() -{ -#ifdef MESH_TESSELLATION_RENDERER - if (m_RP.m_pRE && m_RP.m_pRE->mfGetType() == eDATA_Mesh) - { - CREMeshImpl* pMesh = (CREMeshImpl*) m_RP.m_pRE; - // this buffer contains offset HS has to apply to SV_PrimitiveID it gets from HW. we need this because - // sometimes we do not start rendering from the beginning of index buffer - // AI AndreyK: probably texture buffer has to be replayed by per-instance constant - m_DevMan.BindSRV(eHWSC_Hull, pMesh->m_tessCB.GetShaderResourceView(), 15); - } - else - { - m_DevMan.BindSRV(eHWSC_Hull, NULL, 15); - } -#endif -} - -#endif //#ifdef TESSELLATION_RENDERER - -void CD3D9Renderer::FX_DrawBatches(CShader* pSh, SShaderPass* pPass) -{ - DETAILED_PROFILE_MARKER("FX_DrawBatches"); - FUNCTION_PROFILER_RENDER_FLAT - - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - // Set culling mode - if (!((rRP.m_FlagsPerFlush & RBSI_LOCKCULL) || (m_RP.m_PersFlags2 & RBPF2_LIGHTSHAFTS))) - { - if (pPass->m_eCull != -1) - { - D3DSetCull((ECull)pPass->m_eCull); - } - } - - bool bHWSkinning = FX_SetStreamFlags(pPass); - SSkinningData* pSkinningData = NULL; - if (bHWSkinning) - { - SRenderObjData* pOD = rRP.m_pCurObject->GetObjData(); - if (!pOD || !pOD->m_pSkinningData) - { - pSkinningData = pOD->m_pSkinningData; - bHWSkinning = false; - Warning("Warning: Skinned geometry used without character instance"); - } - } - IF(bHWSkinning && (rRP.m_pCurObject->m_ObjFlags & FOB_SKINNED) && !CV_r_character_nodeform, 0) - { - FX_DrawBatchesSkinned(pSh, pPass, pSkinningData); - } - else - { - DETAILED_PROFILE_MARKER("FX_DrawBatchesStatic"); - - // Set shaders - bool bRes = true; - const int rStats = CV_r_stats; - const int rLog = CV_r_log; - - CHWShader_D3D* pCurGS = (CHWShader_D3D*)pPass->m_GShader; - - if (pCurGS) - { - bRes &= pCurGS->mfSetGS(0); - } - else - { - CHWShader_D3D::mfBindGS(NULL, NULL); - } - - CHWShader_D3D* pCurVS = (CHWShader_D3D*)pPass->m_VShader; - CHWShader_D3D* pCurPS = (CHWShader_D3D*)pPass->m_PShader; - bRes &= pCurPS->mfSetPS(HWSF_SETTEXTURES); - bRes &= pCurVS->mfSetVS(HWSF_SETTEXTURES); - - CHWShader_D3D* pCurHS, * pCurDS; - bool bTessEnabled = FX_SetTessellationShaders(pCurHS, pCurDS, pPass); - - if (bRes) - { - if (ShouldApplyFogCorrection()) - { - FX_FogCorrection(); - } - - assert(rRP.m_pRE || !rRP.m_nLastRE); - IRenderElement* pRE = rRP.m_pRE; - IRenderElement* pRESave = pRE; - CRenderObject* pSaveObj = rRP.m_pCurObject; - CShaderResources* pCurRes = rRP.m_pShaderResources; - CShaderResources* pSaveRes = pCurRes; - for (int nRE = 0; nRE <= rRP.m_nLastRE; nRE++) - { - TArray& rRIs = rRP.m_RIs[nRE]; - if (!(rRP.m_FlagsPerFlush & RBSI_INSTANCED) || rRIs.size() <= (unsigned)CRenderer::m_iGeomInstancingThreshold) - { - if (pRE) - { - // Check the material for this object and make sure that it is actually supposed to be casting a shadow. - const bool isShadowPass = m_RP.m_nPassGroupID == EFSLIST_SHADOW_GEN; - int objectMaterialID = rRIs[0]->pElem->mfGetMatId(); - if (isShadowPass && (objectMaterialID != -1)) - { - if (rRIs[0]->pObj->m_pCurrMaterial && (rRIs[0]->pObj->m_pCurrMaterial->GetSafeSubMtl(objectMaterialID)->GetFlags() & MTL_FLAG_NOSHADOW)) - { - continue; - } - } - - pRE = rRP.m_pRE = rRIs[0]->pElem; - rRP.m_pCurObject = rRIs[0]->pObj; - CShaderResources* pRes = (rRP.m_PersFlags2 & RBPF2_MATERIALLAYERPASS) ? rRP.m_pShaderResources : SRendItem::mfGetRes(rRIs[0]->SortVal); - uint32 nFrameID = rTI.m_nFrameUpdateID; - if (!pRE->mfCheckUpdate(rRP.m_FlagsStreams_Stream | 0x80000000, nFrameID, bTessEnabled)) - { - continue; - } - if (nRE || rRP.m_nNumRendPasses || pCurRes != pRes) // Only static meshes (CREMeshImpl) can use geom batching - { - rRP.m_pShaderResources = pRes; - CHWShader_D3D::UpdatePerMaterialConstantBuffer(); - - pRE->mfPrepare(false); - CREMeshImpl* pM = (CREMeshImpl*)pRE; - if (pM->m_CustomData || pCurRes != pRes) // Custom data can indicate some shader parameters are from mesh - { - pCurVS->UpdatePerBatchConstantBuffer(); - pCurPS->UpdatePerBatchConstantBuffer(); - if (pCurPS->m_pCurInst) - { - pCurPS->mfSetSamplers(pCurPS->m_pCurInst->m_pSamplers, eHWSC_Pixel); - } - if (pCurVS->m_pCurInst) - { - pCurVS->mfSetSamplers(pCurVS->m_pCurInst->m_pSamplers, eHWSC_Vertex); - } -#ifdef TESSELLATION_RENDERER - if (pCurDS && pCurDS->m_pCurInst) - { - pCurDS->mfSetSamplers(pCurDS->m_pCurInst->m_pSamplers, eHWSC_Domain); - } -#endif - pCurRes = pRes; - } - } - } - - rRP.m_nNumRendPasses++; - // Unlock all VBs (if needed) and bind current streams - if (FX_CommitStreams(pPass)) - { - uint32 nO; - const uint32 nNumRI = rRIs.Num(); - CRenderObject* pObj = NULL; - CRenderObject::SInstanceInfo* pI; -#ifdef DO_RENDERSTATS - if ((CV_r_stats == 6 || m_pDebugRenderNode || m_bCollectDrawCallsInfo)) - { - for (nO = 0; nO < nNumRI; nO++) - { - pObj = rRIs[nO]->pObj; - - IRenderElement* pElemBase = rRIs[nO]->pElem; - - if (pElemBase->mfGetType() == eDATA_Mesh) - { - CREMeshImpl* pMesh = (CREMeshImpl*)pElemBase; - IRenderMesh* pRenderMesh = pMesh ? pMesh->m_pRenderMesh : NULL; - - FX_TrackStats(pObj, pRenderMesh); - } - } - } -#endif - - for (nO = 0; nO < nNumRI; ++nO) - { - pObj = rRIs[nO]->pObj; - rRP.m_pCurObject = pObj; - pI = &pObj->m_II; - byte bStartQ = FX_StartQuery(rRIs[nO]); - if (bStartQ == 2) - { - continue; - } - -#ifdef DO_RENDERLOG - if (rLog >= 3) - { - Vec3 vPos = pObj->GetTranslation(); - Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "+++ General Pass %d (Obj: %d [%.3f, %.3f, %.3f], %.3f)\n", m_RP.m_nNumRendPasses, pObj->m_Id, vPos[0], vPos[1], vPos[2], pObj->m_fDistance); - } -#endif - - pCurVS->UpdatePerInstanceConstantBuffer(); - pCurPS->UpdatePerInstanceConstantBuffer(); - - if (pCurGS) - { - pCurGS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindGS(NULL, NULL); - } -#ifdef TESSELLATION_RENDERER - if (pCurDS) - { - pCurDS->UpdatePerInstanceConstantBuffer(); - } - if (pCurHS) - { - pCurHS->UpdatePerInstanceConstantBuffer(); - } -#endif - - AZ_Assert(rRIs[nO], "current render item is null"); - m_PerInstanceConstantBufferPool.SetConstantBuffer(rRIs[nO]); - - { - if (pRE) - { - pRE->mfDraw(pSh, pPass); - } - else - { - FX_DrawIndexedMesh(eptTriangleList); - } - } - - m_RP.m_nCommitFlags &= ~(FC_TARGETS | FC_GLOBAL_PARAMS); - FX_EndQuery(rRIs[nO], bStartQ); - } - - rRP.m_FlagsShader_MD &= ~(HWMD_TEXCOORD_FLAG_MASK); - if (pRE) - { - pRE->mfClearFlags(FCEF_PRE_DRAW_DONE); - } - } - rRP.m_pCurObject = pSaveObj; - rRP.m_pRE = pRESave; - rRP.m_pShaderResources = pSaveRes; - } - } - } -#ifdef TESSELLATION_RENDERER - if (bTessEnabled) - { - CHWShader_D3D::mfBindHS(NULL, NULL); - CHWShader_D3D::mfBindDS(NULL, NULL); - } -#endif - } - m_RP.m_nCommitFlags = FC_ALL; -} - -//============================================================================================ - -void CD3D9Renderer::FX_DrawShader_General(CShader* ef, SShaderTechnique* pTech) -{ - SShaderPass* slw; - int32 i; - - PROFILE_FRAME(DrawShader_Generic); - - - EF_Scissor(false, 0, 0, 0, 0); - - if (pTech->m_Passes.Num()) - { - slw = &pTech->m_Passes[0]; - const int nCount = pTech->m_Passes.Num(); - uint32 curPassBit = 1; - for (i = 0; i < nCount; i++, slw++, (curPassBit <<= 1)) - { - m_RP.m_pCurPass = slw; - - // Set all textures and HW TexGen modes for the current pass (ShadeLayer) - assert (slw->m_VShader && slw->m_PShader); - if (!slw->m_VShader || !slw->m_PShader || (curPassBit & m_RP.m_CurPassBitMask)) - { - continue; - } - - FX_CommitStates(pTech, slw, (slw->m_PassFlags & SHPF_NOMATSTATE) == 0); - - bool bSkinned = (m_RP.m_pCurObject->m_ObjFlags & FOB_SKINNED) && !CV_r_character_nodeform; - - bSkinned |= FX_SetStreamFlags(slw); - - if (m_RP.m_FlagsPerFlush & RBSI_INSTANCED && !bSkinned) - { - // Using HW geometry instancing approach - FX_DrawShader_InstancedHW(ef, slw); - } - else - { - FX_DrawBatches(ef, slw); - } - } - } -} - -void CD3D9Renderer::FX_DrawShader_Fur(CShader* ef, SShaderTechnique* pTech) -{ - static CCryNameTSCRC techFurZPost("FurZPost"); - FurPasses& furPasses = FurPasses::GetInstance(); - bool isFurZPost = (pTech->m_NameCRC == techFurZPost); - furPasses.SetFurShellPassPercent(isFurZPost ? 1.0f : 0.0f); - - // Fur should be rendered with an object containing a render node. - // Example of objects without render node are various effects such as light beams - // light arc that their material was set to Fur by mistake - in such case we gracefully don't render ;) - // Adding a trace warning is an option but it'll slow down the render frame quite noticeably. - if (!m_RP.m_pCurObject || !m_RP.m_pCurObject->m_pRenderNode) - return; - - static CCryNameTSCRC techFurShell("General"); - if (pTech->m_NameCRC == techFurShell) - { - PROFILE_FRAME(DrawShader_Fur); - - - EF_Scissor(false, 0, 0, 0, 0); - - int recurseLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; // Skip fur shells for recursive passes - FurPasses::RenderMode furRenderMode = furPasses.GetFurRenderingMode(); - if (pTech->m_Passes.Num() && furRenderMode != FurPasses::RenderMode::None && CV_r_FurShellPassCount > 0 && recurseLevel == 0) - { - uint64 nSavedFlags = m_RP.m_FlagsShader_RT; - uint32 nSavedStateAnd = m_RP.m_ForceStateAnd; - - furPasses.ApplyFurDebugFlags(); - - if (furRenderMode == FurPasses::RenderMode::AlphaTested) - { - m_RP.m_ForceStateAnd |= GS_BLALPHA_MASK | GS_BLEND_MASK; - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_ADDITIVE_BLENDING]; - - // Ensure that alpha testing is set up for alpha tested fur shells, even if not specified in the - // material, by forcing a minimum alpha test of 0.01. This allows fur materials that do not - // specify alpha testing to appear similar to alpha blended fur, but materials that control - // alpha testing still benefit from their settings. - FX_SetAlphaTestState(max(0.01f, m_RP.m_pShaderResources->GetAlphaRef())); - } - else if (furRenderMode == FurPasses::RenderMode::AlphaBlended) - { - // Even if the material specifies alpha testing, don't write depth for alpha blended fur shells - m_RP.m_ForceStateAnd |= GS_DEPTHWRITE; - } - - // OIT permutation flag set - MultiLayerAlphaBlendPass::GetInstance().ConfigureShaderFlags(m_RP.m_FlagsShader_RT); - - assert(pTech->m_Passes.Num() == 1); - - SShaderPass* slw = &pTech->m_Passes[0]; - m_RP.m_pCurPass = slw; - - // Set all textures and HW TexGen modes for the current pass (ShadeLayer) - assert (slw->m_VShader && slw->m_PShader); - if (slw->m_VShader && slw->m_PShader) - { - FX_CommitStates(pTech, slw, (slw->m_PassFlags & SHPF_NOMATSTATE) == 0); - - bool bSkinned = (m_RP.m_pCurObject->m_ObjFlags & FOB_SKINNED) && !CV_r_character_nodeform; - - bSkinned |= FX_SetStreamFlags(slw); - - int startShell = 1; - int endShell = CV_r_FurShellPassCount; - int numShellPasses = CV_r_FurShellPassCount; - - if ((m_RP.m_FlagsShader_RT & g_HWSR_MaskBit[HWSR_HDR_MODE]) == 0) - { - // For aux views such as the material editor, draw the base surface, as it is not captured by Z pass there - startShell = 0; - } - - if (CV_r_FurDebugOneShell > 0 && CV_r_FurDebugOneShell <= CV_r_FurShellPassCount) - { - startShell = CV_r_FurDebugOneShell; - endShell = startShell; - } - else if (IRenderNode* pRenderNode = m_RP.m_pCurObject->m_pRenderNode) - { - // Scale number of shell passes by object's distance to camera and LOD ratio - float lodRatio = pRenderNode->GetLodRatioNormalized(); - if (lodRatio > 0.0f) - { - static ICVar* pTargetSize = gEnv->pConsole->GetCVar("e_LodFaceAreaTargetSize"); - if (pTargetSize) - { - lodRatio *= pTargetSize->GetFVal(); - } - - // Not using pRenderNode->GetMaxViewDist() because we want to be able to LOD out the fur while still being able to see the object at distance - float maxDistance = CV_r_FurMaxViewDist * pRenderNode->GetViewDistanceMultiplier(); - float firstLodDistance = pRenderNode->GetFirstLodDistance(); - float lodDistance = AZ::GetClamp(firstLodDistance / lodRatio, 0.0f, maxDistance - 0.001f); - - // Distance before first LOD change (factoring in LOD ratio) uses full number of shells - // Beyond that distance, number of shells linearly decreases to 0 as distance approaches max view distance. - float distance = m_RP.m_pCurObject->m_fDistance; - float distanceRatio = (maxDistance - distance) / (maxDistance - lodDistance); - float clampedDistanceRatio = AZ::GetClamp(distanceRatio, 0.0f, 1.0f); - endShell = aznumeric_cast(endShell * clampedDistanceRatio); - numShellPasses = endShell; - } - } - - numShellPasses = AZ::GetMax(numShellPasses, 1); - for (int i = startShell; i <= endShell; ++i) - { - // Set shell distance from base surface in fur params - furPasses.SetFurShellPassPercent(static_cast(i) / numShellPasses); - - if (m_RP.m_FlagsPerFlush & RBSI_INSTANCED && !bSkinned) - { - // Using HW geometry instancing approach - FX_DrawShader_InstancedHW(ef, slw); - } - else - { - FX_DrawBatches(ef, slw); - } - } - } - - m_RP.m_ForceStateAnd = nSavedStateAnd; - m_RP.m_FlagsShader_RT = nSavedFlags; - } - } - else - { - uint64 nSavedFlags = m_RP.m_FlagsShader_RT; - static CCryNameTSCRC techFurShadow("FurShadowGen"); - if (pTech->m_NameCRC == techFurShadow) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_GPU_PARTICLE_TURBULENCE]; // Indicates fin pass - if (CV_r_FurFinShadowPass == 0 || furPasses.GetFurRenderingMode() == FurPasses::RenderMode::None) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_GPU_PARTICLE_SHADOW_PASS]; // Indicates fins should be skipped in shadow pass - } - } - - // All other techniques use the normal path - FX_DrawShader_General(ef, pTech); - m_RP.m_FlagsShader_RT = nSavedFlags; - } -} - -void CD3D9Renderer::FX_DrawDebugPasses() -{ - if (!m_RP.m_pRootTechnique || m_RP.m_pRootTechnique->m_nTechnique[TTYPE_DEBUG] < 0) - { - return; - } - - CShader* sh = m_RP.m_pShader; - SShaderTechnique* pTech = m_RP.m_pShader->m_HWTechniques[m_RP.m_pRootTechnique->m_nTechnique[TTYPE_DEBUG]]; - - PROFILE_FRAME(DrawShader_DebugPasses); - - PROFILE_LABEL_SCOPE("DEBUG_PASS"); - - int nLastRE = m_RP.m_nLastRE; - m_RP.m_nLastRE = 0; - for (int nRE = 0; nRE <= nLastRE; nRE++) - { - s_tempRIs.SetUse(0); - - m_RP.m_pRE = m_RP.m_RIs[nRE][0]->pElem; - - if (!m_RP.m_pRE) - { - continue; - } - - for (uint32 i = 0; i < m_RP.m_RIs[nRE].Num(); i++) - { - s_tempRIs.AddElem(m_RP.m_RIs[nRE][i]); - } - - if (!s_tempRIs.Num()) - { - continue; - } - - m_RP.m_pRE->mfPrepare(false); - uint32 nSaveMD = m_RP.m_FlagsShader_MD; - - TArray saveArr; - saveArr.Assign(m_RP.m_RIs[0]); - m_RP.m_RIs[0].Assign(s_tempRIs); - - CRenderObject* pSaveObject = m_RP.m_pCurObject; - m_RP.m_pCurObject = m_RP.m_RIs[0][0]->pObj; - m_RP.m_FlagsShader_MD &= ~HWMD_TEXCOORD_FLAG_MASK; - int32 nMaterialStatePrevOr = m_RP.m_MaterialStateOr; - int32 nMaterialStatePrevAnd = m_RP.m_MaterialStateAnd; - m_RP.m_MaterialStateAnd = GS_BLEND_MASK; - m_RP.m_MaterialStateOr = GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - - FX_DrawTechnique(sh, pTech); - - m_RP.m_RIs[0].Assign(saveArr); - saveArr.ClearArr(); - - m_RP.m_pCurObject = pSaveObject; - m_RP.m_pPrevObject = NULL; - m_RP.m_FlagsShader_MD = nSaveMD; - m_RP.m_MaterialStateOr = nMaterialStatePrevOr; - m_RP.m_MaterialStateAnd = nMaterialStatePrevAnd; - } - m_RP.m_nLastRE = nLastRE; -} - -// deprecated (cannot remove at this stage) - maybe can batch into FX_DrawEffectLayerPasses (?) -void CD3D9Renderer::FX_DrawMultiLayers() -{ - // Verify if current mesh has valid data for layers - CREMeshImpl* pRE = (CREMeshImpl*) m_RP.m_pRE; - if (!m_RP.m_pShader || !m_RP.m_pShaderResources || !m_RP.m_pCurObject->m_nMaterialLayers) - { - return; - } - - _smart_ptr pObjMat = m_RP.m_pCurObject->m_pCurrMaterial; - if ((SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID] > 0) || !m_RP.m_pShaderResources || !pObjMat) - { - return; - } - - if (m_RP.m_PersFlags2 & (RBPF2_CUSTOM_RENDER_PASS | RBPF2_MOTIONBLURPASS)) - { - return; - } - - CRenderChunk* pChunk = pRE->m_pChunk; - if (!pChunk) - { - assert(pChunk); - return; - } - - // Check if chunk material has layers at all - _smart_ptr pDefaultMtl = gEnv->p3DEngine->GetMaterialManager()->GetDefaultLayersMaterial(); - _smart_ptr pCurrMtl = pObjMat->GetSubMtlCount() ? pObjMat->GetSubMtl(pChunk->m_nMatID) : pObjMat; - if (!pCurrMtl || !pDefaultMtl || (pCurrMtl->GetFlags() & MTL_FLAG_NODRAW)) - { - return; - } - - uint32 nLayerCount = pDefaultMtl->GetLayerCount(); - if (!nLayerCount) - { - return; - } - - // Start multi-layers processing - PROFILE_FRAME(DrawShader_MultiLayers); - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Start Multilayers processing ***\n"); - } - - for (int nRE = 0; nRE <= m_RP.m_nLastRE; nRE++) - { - m_RP.m_pRE = m_RP.m_RIs[nRE][0]->pElem; - - // Render all layers - for (uint32 nCurrLayer(0); nCurrLayer < nLayerCount; ++nCurrLayer) - { - IMaterialLayer* pLayer = const_cast< IMaterialLayer* >(pCurrMtl->GetLayer(nCurrLayer)); - IMaterialLayer* pDefaultLayer = const_cast< IMaterialLayer* >(pDefaultMtl->GetLayer(nCurrLayer)); - bool bDefaultLayer = false; - if (!pLayer) - { - // Replace with default layer - pLayer = pDefaultLayer; - bDefaultLayer = true; - - if (!pLayer) - { - continue; - } - } - - if (!pLayer->IsEnabled() || pLayer->DoesFadeOut()) - { - continue; - } - - // Set/verify layer shader technique - SShaderItem& pCurrShaderItem = pLayer->GetShaderItem(); - CShader* pSH = static_cast(pCurrShaderItem.m_pShader); - if (!pSH || pSH->m_HWTechniques.empty()) - { - continue; - } - - SShaderTechnique* pTech = pSH->m_HWTechniques[0]; - if (!pTech) - { - continue; - } - - // Re-create render object list, based on layer properties - { - s_tempRIs.SetUse(0); - - CRenderObject* pObj = m_RP.m_pCurObject; - uint32 nObj = 0; - - for (nObj = 0; nObj < m_RP.m_RIs[nRE].Num(); nObj++) - { - pObj = m_RP.m_RIs[nRE][nObj]->pObj; - uint8 nMaterialLayers = 0; - nMaterialLayers |= ((pObj->m_nMaterialLayers & MTL_LAYER_BLEND_DYNAMICFROZEN)) ? MTL_LAYER_FROZEN : 0; - if (nMaterialLayers & (1 << nCurrLayer)) - { - s_tempRIs.AddElem(m_RP.m_RIs[nRE][nObj]); - } - } - - // nothing in render list - if (!s_tempRIs.Num()) - { - continue; - } - } - - int nSaveLastRE = m_RP.m_nLastRE; - m_RP.m_nLastRE = 0; - - TexturesResourcesMap pPrevLayerResourceTex; // A map of texture used by the shader - if (bDefaultLayer) - { // Keep layer resources and replace with resources from base shader - pPrevLayerResourceTex = ((CShaderResources*)pCurrShaderItem.m_pShaderResources)->m_TexturesResourcesMap; - ((CShaderResources*)pCurrShaderItem.m_pShaderResources)->m_TexturesResourcesMap = m_RP.m_pShaderResources->m_TexturesResourcesMap; - } - - m_RP.m_pRE->mfPrepare(false); - - // Store current rendering data - TArray pPrevRenderObjLst; - pPrevRenderObjLst.Assign(m_RP.m_RIs[0]); - CRenderObject* pPrevObject = m_RP.m_pCurObject; - CShaderResources* pPrevShaderResources = m_RP.m_pShaderResources; - CShader* pPrevSH = m_RP.m_pShader; - uint32 nPrevNumRendPasses = m_RP.m_nNumRendPasses; - uint64 nFlagsShaderRTprev = m_RP.m_FlagsShader_RT; - - SShaderTechnique* pPrevRootTech = m_RP.m_pRootTechnique; - m_RP.m_pRootTechnique = pTech; - - int nMaterialStatePrevOr = m_RP.m_MaterialStateOr; - int nMaterialStatePrevAnd = m_RP.m_MaterialStateAnd; - uint32 nFlagsShaderLTprev = m_RP.m_FlagsShader_LT; - - int nPersFlagsPrev = m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags; - int nPersFlags2Prev = m_RP.m_PersFlags2; - int nMaterialAlphaRefPrev = m_RP.m_MaterialAlphaRef; - bool bIgnoreObjectAlpha = m_RP.m_bIgnoreObjectAlpha; - m_RP.m_bIgnoreObjectAlpha = true; - - m_RP.m_pShader = pSH; - m_RP.m_RIs[0].Assign(s_tempRIs); - m_RP.m_pCurObject = m_RP.m_RIs[0][0]->pObj; - m_RP.m_pPrevObject = NULL; - m_RP.m_pShaderResources = (CShaderResources*)pCurrShaderItem.m_pShaderResources; - - // Reset light passes (need ambient) - m_RP.m_nNumRendPasses = 0; - m_RP.m_PersFlags2 |= RBPF2_MATERIALLAYERPASS; - - if ((1 << nCurrLayer) & MTL_LAYER_FROZEN) - { - m_RP.m_MaterialStateAnd = GS_BLEND_MASK | GS_ALPHATEST_MASK; - m_RP.m_MaterialStateOr = GS_BLSRC_ONE | GS_BLDST_ONE; - m_RP.m_MaterialAlphaRef = 0xff; - } - - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - - FX_DrawTechnique(pSH, pTech); - - // Restore previous rendering data - m_RP.m_RIs[0].Assign(pPrevRenderObjLst); - pPrevRenderObjLst.ClearArr(); - m_RP.m_pShader = pPrevSH; - m_RP.m_pShaderResources = pPrevShaderResources; - m_RP.m_pCurObject = pPrevObject; - m_RP.m_pPrevObject = NULL; - m_RP.m_PersFlags2 = nPersFlags2Prev; - m_RP.m_nLastRE = nSaveLastRE; - - - m_RP.m_nNumRendPasses = nPrevNumRendPasses; - - m_RP.m_FlagsShader_LT = nFlagsShaderLTprev; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags = nPersFlagsPrev; - m_RP.m_FlagsShader_RT = nFlagsShaderRTprev; - - m_RP.m_nNumRendPasses = 0; - - m_RP.m_pRootTechnique = pPrevRootTech; - m_RP.m_bIgnoreObjectAlpha = bIgnoreObjectAlpha; - m_RP.m_MaterialStateOr = nMaterialStatePrevOr; - m_RP.m_MaterialStateAnd = nMaterialStatePrevAnd; - m_RP.m_MaterialAlphaRef = nMaterialAlphaRefPrev; - - if (bDefaultLayer) - { // restore from the base layer - ((CShaderResources*)pCurrShaderItem.m_pShaderResources)->m_TexturesResourcesMap = pPrevLayerResourceTex; - } - } - } - - m_RP.m_pRE = pRE; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End Multilayers processing ***\n"); - } -} - -void CD3D9Renderer::FX_SelectTechnique(CShader* pShader, SShaderTechnique* pTech) -{ - SShaderTechniqueStat Stat; - Stat.pTech = pTech; - Stat.pShader = pShader; - if (pTech->m_Passes.Num()) - { - SShaderPass* pPass = &pTech->m_Passes[0]; - if (pPass->m_PShader && pPass->m_VShader) - { - Stat.pVS = (CHWShader_D3D*)pPass->m_VShader; - Stat.pPS = (CHWShader_D3D*)pPass->m_PShader; - Stat.pVSInst = Stat.pVS->m_pCurInst; - Stat.pPSInst = Stat.pPS->m_pCurInst; - g_SelectedTechs.push_back(Stat); - } - } -} - -void CD3D9Renderer::FX_DrawTechnique(CShader* ef, SShaderTechnique* pTech) -{ - FUNCTION_PROFILER_RENDER_FLAT - switch (ef->m_eSHDType) - { - case eSHDT_General: - FX_DrawShader_General(ef, pTech); - break; - case eSHDT_Light: - FX_DrawShader_General(ef, pTech); - break; - case eSHDT_Terrain: - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::LegacyTerrain, "FX_DrawTechnique"); - FX_DrawShader_General(ef, pTech); - } - break; - case eSHDT_Fur: - FX_DrawShader_Fur(ef, pTech); - break; - case eSHDT_CustomDraw: - case eSHDT_Sky: - if (m_RP.m_pRE) - { - EF_Scissor(false, 0, 0, 0, 0); - if (pTech && pTech->m_Passes.Num()) - { - m_RP.m_pRE->mfDraw(ef, &pTech->m_Passes[0]); - } - else - { - m_RP.m_pRE->mfDraw(ef, NULL); - } - } - break; - default: - assert(0); - } - if (m_RP.m_ObjFlags & FOB_SELECTED) - { - FX_SelectTechnique(ef, pTech); - } -} - -#if defined(HW_INSTANCING_ENABLED) -static void sDetectInstancing(CShader* pShader, [[maybe_unused]] CRenderObject* pObj) -{ - CRenderer* rd = gRenDev; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - if (!CRenderer::CV_r_geominstancing || rd->m_bUseGPUFriendlyBatching[rRP.m_nProcessThreadID] || !(pShader->m_Flags & EF_SUPPORTSINSTANCING) || CRenderer::CV_r_measureoverdraw || - // don't instance in motion blur pass or post 3d render - rRP.m_PersFlags2 & RBPF2_POST_3D_RENDERER_PASS || //rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS || - // only instance meshes - !rRP.m_pRE || rRP.m_pRE->mfGetType() != eDATA_Mesh - ) - { - rRP.m_FlagsPerFlush &= ~RBSI_INSTANCED; - return; - } - - int i = 0, nLastRE = rRP.m_nLastRE; - for (; i <= nLastRE; i++) - { - int nRIs = rRP.m_RIs[i].Num(); - - // instance even with conditional rendering - && RIs[0]->nOcclQuery<0 - if (nRIs > CRenderer::m_iGeomInstancingThreshold || (rRP.m_FlagsPerFlush & RBSI_INSTANCED)) - { - rRP.m_FlagsPerFlush |= RBSI_INSTANCED; - break; - } - } - if (i > rRP.m_nLastRE) - { - rRP.m_FlagsPerFlush &= ~RBSI_INSTANCED; - } -} -#endif - -void CD3D9Renderer::FX_SetAlphaTestState(float alphaRef) -{ - if (!(m_RP.m_PersFlags2 & RBPF2_NOALPHATEST)) - { - const int nAlphaRef = int(alphaRef * 255.0f); - - m_RP.m_MaterialAlphaRef = nAlphaRef; - m_RP.m_MaterialStateOr = GS_ALPHATEST_GEQUAL | GS_DEPTHWRITE; - m_RP.m_MaterialStateAnd = GS_ALPHATEST_MASK; - } - else - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ALPHATEST]; - } -} - -// Set/Restore shader resources overrided states -bool CD3D9Renderer::FX_SetResourcesState() -{ - FUNCTION_PROFILER_RENDER_FLAT - if (!m_RP.m_pShader) - { - return false; - } - m_RP.m_MaterialStateOr = 0; - m_RP.m_MaterialStateAnd = 0; - if (!m_RP.m_pShaderResources) - { - return true; - } - - PrefetchLine(m_RP.m_pShaderResources, 0); //Shader Resources fit in a cache line, but they're not 128-byte aligned! We are likely going - PrefetchLine(m_RP.m_pShaderResources, 124); // to cache miss on access to m_ResFlags but will hopefully avoid later ones - - if (m_RP.m_pShader->m_Flags2 & EF2_IGNORERESOURCESTATES) - { - return true; - } - - m_RP.m_ShaderTexResources[EFTT_DECAL_OVERLAY] = NULL; - - const CShaderResources* pRes = m_RP.m_pShaderResources; - const uint32 uResFlags = pRes->m_ResFlags; - if (uResFlags & MTL_FLAG_NOTINSTANCED) - { - m_RP.m_FlagsPerFlush &= ~RBSI_INSTANCED; - } - - if (uResFlags & MTL_FLAG_2SIDED) - { - D3DSetCull(eCULL_None); - m_RP.m_FlagsPerFlush |= RBSI_LOCKCULL; - } - - if (pRes->IsAlphaTested()) - { - FX_SetAlphaTestState(pRes->GetAlphaRef()); - } - - if (pRes->IsTransparent()) - { - if (!(m_RP.m_PersFlags2 & RBPF2_NOALPHABLEND)) - { - const float fOpacity = pRes->GetStrengthValue(EFTT_OPACITY); - - m_RP.m_MaterialStateAnd |= GS_DEPTHWRITE | GS_BLEND_MASK; - m_RP.m_MaterialStateOr &= ~GS_DEPTHWRITE; - if (uResFlags & MTL_FLAG_ADDITIVE) - { - m_RP.m_MaterialStateOr |= GS_BLSRC_ONE | GS_BLDST_ONE; - m_RP.m_CurGlobalColor[0] = fOpacity; - m_RP.m_CurGlobalColor[1] = fOpacity; - m_RP.m_CurGlobalColor[2] = fOpacity; - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ADDITIVE_BLENDING]; - } - else - { - m_RP.m_MaterialStateOr |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - m_RP.m_CurGlobalColor[3] = fOpacity; - } - m_RP.m_fCurOpacity = fOpacity; - } - } - { - if (pRes->m_pDeformInfo) - { - m_RP.m_FlagsShader_MDV |= pRes->m_pDeformInfo->m_eType; - } - m_RP.m_FlagsShader_MDV |= m_RP.m_pCurObject->m_nMDV | m_RP.m_pShader->m_nMDV; - if (m_RP.m_ObjFlags & FOB_OWNER_GEOMETRY) - { - m_RP.m_FlagsShader_MDV &= ~MDV_DEPTH_OFFSET; - } - } - - return true; -} - -//=================================================================================================== - -#if !defined(_RELEASE) -static void sBatchStats([[maybe_unused]] SRenderPipeline& rRP) -{ -#if defined(ENABLE_PROFILING_CODE) - SPipeStat& rPS = rRP.m_PS[rRP.m_nProcessThreadID]; - rPS.m_NumRendMaterialBatches++; - rPS.m_NumRendGeomBatches += rRP.m_nLastRE + 1; - for (int i = 0; i <= rRP.m_nLastRE; i++) - { - rPS.m_NumRendInstances += rRP.m_RIs[i].Num(); - } -#endif -} -#endif - -static void sLogFlush(const char* str, CShader* pSH, SShaderTechnique* pTech) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "%s: '%s.%s', Id:%d, ResId:%d, VF:%d\n", str, pSH->GetName(), pTech ? pTech->m_NameStr.c_str() : "Unknown", pSH->GetID(), rRP.m_pShaderResources ? rRP.m_pShaderResources->m_Id : -1, (int)rRP.m_CurVFormat.GetEnum()); - - if (rRP.m_ObjFlags & FOB_SELECTED) - { - if (rRP.m_MaterialStateOr & GS_ALPHATEST_MASK) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x), (AT) (Selected)\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags); - } - else - if (rRP.m_MaterialStateOr & GS_BLEND_MASK) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x) (AB) (Dist: %.3f) (Selected)\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags, rRP.m_pCurObject->m_fDistance); - } - else - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x), RE: 0x%x (Selected)\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags, rRP.m_pRE); - } - } - else - { - if (rRP.m_MaterialStateOr & GS_ALPHATEST_MASK) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x) (AT), Inst: %d, RE: 0x%x (Dist: %.3f)\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags, rRP.m_RIs[0].Num(), rRP.m_pRE, rRP.m_pCurObject->m_fDistance); - } - else - if (rRP.m_MaterialStateOr & GS_BLEND_MASK) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x) (AB), Inst: %d, RE: 0x%x (Dist: %.3f)\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags, rRP.m_RIs[0].Num(), rRP.m_pRE, rRP.m_pCurObject->m_fDistance); - } - else - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " %.3f, %.3f, %.3f (0x%x), Inst: %d, RE: 0x%x\n", rRP.m_pCurObject->m_II.m_Matrix(0, 3), rRP.m_pCurObject->m_II.m_Matrix(1, 3), rRP.m_pCurObject->m_II.m_Matrix(2, 3), rRP.m_pCurObject->m_ObjFlags, rRP.m_RIs[0].Num(), rRP.m_pRE); - } - } - if (rRP.m_pRE && rRP.m_pRE->mfGetType() == eDATA_Mesh) - { - CREMeshImpl* pRE = (CREMeshImpl*) rRP.m_pRE; - CRenderMesh* pRM = pRE->m_pRenderMesh; - if (pRM && pRM->m_Chunks.size() && pRM->m_sSource) - { - int nChunk = -1; - for (int i = 0; i < pRM->m_Chunks.size(); i++) - { - CRenderChunk* pCH = &pRM->m_Chunks[i]; - if (pCH->pRE == pRE) - { - nChunk = i; - break; - } - } - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], " Mesh: %s (Chunk: %d)\n", pRM->m_sSource.c_str(), nChunk); - } - } - } -} - -void CD3D9Renderer::FX_RefractionPartialResolve() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - { - SRenderObjData* ObjData = rRP.m_pCurObject->GetObjData(); - - if (ObjData) - { - uint8 screenBounds[4]; - - screenBounds[0] = ObjData->m_screenBounds[0]; - screenBounds[1] = ObjData->m_screenBounds[1]; - screenBounds[2] = ObjData->m_screenBounds[2]; - screenBounds[3] = ObjData->m_screenBounds[3]; - - float boundsI2F[] = { - (float)(screenBounds[0] << 4), (float)(screenBounds[1] << 4), - (float)(min(screenBounds[2] << 4, GetWidth())), (float)(min(screenBounds[3] << 4, GetHeight())) - }; - - if (((screenBounds[2] - screenBounds[0]) && (screenBounds[3] - screenBounds[1])) && - !((rRP.m_nCurrResolveBounds[0] == screenBounds[0]) - && (rRP.m_nCurrResolveBounds[1] == screenBounds[1]) - && (rRP.m_nCurrResolveBounds[2] == screenBounds[2]) - && (rRP.m_nCurrResolveBounds[3] == screenBounds[3]))) - { - rRP.m_nCurrResolveBounds[0] = screenBounds[0]; - rRP.m_nCurrResolveBounds[1] = screenBounds[1]; - rRP.m_nCurrResolveBounds[2] = screenBounds[2]; - rRP.m_nCurrResolveBounds[3] = screenBounds[3]; - - int boundsF2I[] = { - int(boundsI2F[0] * m_RP.m_CurDownscaleFactor.x), - int(boundsI2F[1] * m_RP.m_CurDownscaleFactor.y), - int(boundsI2F[2] * m_RP.m_CurDownscaleFactor.x), - int(boundsI2F[3] * m_RP.m_CurDownscaleFactor.y) - }; - - int currScissorX, currScissorY, currScissorW, currScissorH; - CTexture* pTarget = CTexture::s_ptexCurrSceneTarget; - - //cache RP states - Probably a bit excessive, but want to be safe - CShaderResources* currRes = rd->m_RP.m_pShaderResources; - CShader* currShader = rd->m_RP.m_pShader; - int currShaderTechnique = rd->m_RP.m_nShaderTechnique; - SShaderTechnique* currTechnique = rd->m_RP.m_pCurTechnique; - uint32 currCommitFlags = rd->m_RP.m_nCommitFlags; - uint32 currFlagsShaderBegin = rd->m_RP.m_nFlagsShaderBegin; - ECull currCull = m_RP.m_eCull; - - float currVPMinZ = rd->m_NewViewport.fMinZ; // Todo: Add to GetViewport / SetViewport - float currVPMaxZ = rd->m_NewViewport.fMaxZ; - - D3DSetCull(eCULL_None); - - bool bScissored = EF_GetScissorState(currScissorX, currScissorY, currScissorW, currScissorH); - - int newScissorX = int(boundsF2I[0]); - int newScissorY = int(boundsF2I[1]); - int newScissorW = max(0, min(int(boundsF2I[2]), GetWidth()) - newScissorX); - int newScissorH = max(0, min(int(boundsF2I[3]), GetHeight()) - newScissorY); - - EF_Scissor(true, newScissorX, newScissorY, newScissorW, newScissorH); - - FX_ScreenStretchRect(pTarget); - - EF_Scissor(bScissored, currScissorX, currScissorY, currScissorW, currScissorH); - - D3DSetCull(currCull); - - //restore RP states - rd->m_RP.m_pShaderResources = currRes; - rd->m_RP.m_pShader = currShader; - rd->m_RP.m_nShaderTechnique = currShaderTechnique; - rd->m_RP.m_pCurTechnique = currTechnique; - rd->m_RP.m_nCommitFlags = currCommitFlags | FC_MATERIAL_PARAMS; - rd->m_RP.m_nFlagsShaderBegin = currFlagsShaderBegin; - rd->m_NewViewport.fMinZ = currVPMinZ; - rd->m_NewViewport.fMaxZ = currVPMaxZ; - -#if REFRACTION_PARTIAL_RESOLVE_STATS - { - const int x1 = (screenBounds[0] << 4); - const int y1 = (screenBounds[1] << 4); - const int x2 = (screenBounds[2] << 4); - const int y2 = (screenBounds[3] << 4); - - const int resolveWidth = x2 - x1; - const int resolveHeight = y2 - y1; - const int resolvePixelCount = resolveWidth * resolveHeight; - - // Update stats - SPipeStat& pipeStat = rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID]; - pipeStat.m_refractionPartialResolveCount++; - pipeStat.m_refractionPartialResolvePixelCount += resolvePixelCount; - - const float resolveCostConversion = 18620398.0f; - - pipeStat.m_fRefractionPartialResolveEstimatedCost += ((float)resolvePixelCount / resolveCostConversion); - -#if REFRACTION_PARTIAL_RESOLVE_DEBUG_VIEWS - if (CRenderer::CV_r_RefractionPartialResolvesDebug == eRPR_DEBUG_VIEW_2D_AREA || CRenderer::CV_r_RefractionPartialResolvesDebug == eRPR_DEBUG_VIEW_2D_AREA_OVERLAY) - { - // Render 2d areas additively on screen - IRenderAuxGeom* pAuxRenderer = gEnv->pRenderer->GetIRenderAuxGeom(); - if (pAuxRenderer) - { - SAuxGeomRenderFlags oldRenderFlags = pAuxRenderer->GetRenderFlags(); - - SAuxGeomRenderFlags newRenderFlags; - newRenderFlags.SetDepthTestFlag(e_DepthTestOff); - newRenderFlags.SetAlphaBlendMode(e_AlphaAdditive); - newRenderFlags.SetMode2D3DFlag(e_Mode2D); - pAuxRenderer->SetRenderFlags(newRenderFlags); - - const float screenWidth = (float)GetWidth(); - const float screenHeight = (float)GetHeight(); - - // Calc resolve area - const float left = x1 / screenWidth; - const float top = y1 / screenHeight; - const float right = x2 / screenWidth; - const float bottom = y2 / screenHeight; - - // Render resolve area - ColorB areaColor(20, 0, 0, 255); - - if (CRenderer::CV_r_RefractionPartialResolvesDebug == eRPR_DEBUG_VIEW_2D_AREA_OVERLAY) - { - int val = (pipeStat.m_refractionPartialResolveCount) % 3; - areaColor = ColorB((val == 0) ? 0 : 128, (val == 1) ? 0 : 128, (val == 2) ? 0 : 128, 255); - } - - const uint vertexCount = 6; - const Vec3 vert[vertexCount] = { - Vec3(left, top, 0.0f), - Vec3(left, bottom, 0.0f), - Vec3(right, top, 0.0f), - Vec3(left, bottom, 0.0f), - Vec3(right, bottom, 0.0f), - Vec3(right, top, 0.0f) - }; - pAuxRenderer->DrawTriangles(vert, vertexCount, areaColor); - - // Set previous Aux render flags back again - pAuxRenderer->SetRenderFlags(oldRenderFlags); - } - } -#endif // REFRACTION_PARTIAL_RESOLVE_DEBUG_VIEWS - } -#endif // REFRACTION_PARTIAL_RESOLVE_STATS - } - } - } -} - -// Flush current render item -void CD3D9Renderer::FX_FlushShader_General() -{ - FUNCTION_PROFILER_RENDER_FLAT - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - if (!rRP.m_pRE && !rRP.m_RendNumVerts) - { - return; - } - - CShader* ef = rRP.m_pShader; - if (!ef) - { - return; - } - - const CShaderResources* rsr = rRP.m_pShaderResources; - if ((ef->m_Flags & EF_SUPPORTSDEFERREDSHADING_FULL) && (rRP.m_PersFlags2 & RBPF2_FORWARD_SHADING_PASS) && (!rsr->IsEmissive())) - { - return; - } - - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - assert(!(rTI.m_PersFlags & RBPF_SHADOWGEN)); - assert(!(rRP.m_nBatchFilter & FB_Z)); - - if (!rRP.m_sExcludeShader.empty()) - { - char nm[1024]; - azstrcpy(nm, AZ_ARRAY_SIZE(nm), ef->GetName()); - azstrlwr(nm, AZ_ARRAY_SIZE(nm)); - if (strstr(rRP.m_sExcludeShader.c_str(), nm)) - { - return; - } - } -#ifdef DO_RENDERLOG - if (rd->m_logFileHandle != AZ::IO::InvalidHandle && CV_r_log == 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "\n\n.. Start %s flush: '%s' ..\n", "General", ef->GetName()); - } -#endif - -#ifndef _RELEASE - sBatchStats(rRP); -#endif - CRenderObject* pObj = rRP.m_pCurObject; - - PROFILE_SHADER_SCOPE; - - if (rd->m_RP.m_pRE) - { - rd->m_RP.m_pRE = rd->m_RP.m_RIs[0][0]->pElem; - } - -#if defined(HW_INSTANCING_ENABLED) - sDetectInstancing(ef, pObj); -#endif - - // Techniques draw cycle... - SShaderTechnique* __restrict pTech = ef->mfGetStartTechnique(rRP.m_nShaderTechnique); - - if (pTech) - { - uint32 flags = (FB_CUSTOM_RENDER | FB_MOTIONBLUR | FB_SOFTALPHATEST | FB_WATER_REFL | FB_WATER_CAUSTIC); - - if (rRP.m_pShaderResources && !(rRP.m_nBatchFilter & flags)) - { - uint32 i; - // Update render targets if necessary - if (!(rTI.m_PersFlags & RBPF_DRAWTOTEXTURE)) - { - uint32 targetNum = rRP.m_pShaderResources->m_RTargets.Num(); - const CShaderResources* const __restrict pShaderResources = rRP.m_pShaderResources; - for (i = 0; i < targetNum; ++i) - { - SHRenderTarget* pTarg = pShaderResources->m_RTargets[i]; - if (pTarg->m_eOrder == eRO_PreDraw) - { - rd->FX_DrawToRenderTarget(ef, rRP.m_pShaderResources, pObj, pTech, pTarg, 0, rRP.m_pRE); - } - } - targetNum = pTech->m_RTargets.Num(); - for (i = 0; i < targetNum; ++i) - { - SHRenderTarget* pTarg = pTech->m_RTargets[i]; - if (pTarg->m_eOrder == eRO_PreDraw) - { - rd->FX_DrawToRenderTarget(ef, rRP.m_pShaderResources, pObj, pTech, pTarg, 0, rRP.m_pRE); - } - } - } - } - rRP.m_pRootTechnique = pTech; - - flags = (FB_MOTIONBLUR | FB_CUSTOM_RENDER | FB_SOFTALPHATEST | FB_DEBUG | FB_WATER_REFL | FB_WATER_CAUSTIC | FB_PARTICLES_THICKNESS); - - if (rRP.m_nBatchFilter & flags) - { - int nTech = -1; - if (rRP.m_nBatchFilter & FB_MOTIONBLUR) - { - nTech = TTYPE_MOTIONBLURPASS; - } - else if (rRP.m_nBatchFilter & FB_CUSTOM_RENDER) - { - nTech = TTYPE_CUSTOMRENDERPASS; - } - else if (rRP.m_nBatchFilter & FB_SOFTALPHATEST) - { - nTech = TTYPE_SOFTALPHATESTPASS; - } - else if (rRP.m_nBatchFilter & FB_WATER_REFL) - { - nTech = TTYPE_WATERREFLPASS; - } - else if (rRP.m_nBatchFilter & FB_WATER_CAUSTIC) - { - nTech = TTYPE_WATERCAUSTICPASS; - } - else if (rRP.m_nBatchFilter & FB_PARTICLES_THICKNESS) - { - nTech = TTYPE_PARTICLESTHICKNESSPASS; - } - else if (rRP.m_nBatchFilter & FB_DEBUG) - { - nTech = TTYPE_DEBUG; - } - - if (nTech >= 0 && pTech->m_nTechnique[nTech] > 0) - { - assert(pTech->m_nTechnique[nTech] < (int)ef->m_HWTechniques.Num()); - pTech = ef->m_HWTechniques[pTech->m_nTechnique[nTech]]; - } - rRP.m_nShaderTechniqueType = nTech; - } -#ifndef _RELEASE - if (CV_r_debugrendermode) - { - if (CV_r_debugrendermode & 1) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - } - if (CV_r_debugrendermode & 2) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG1]; - } - if (CV_r_debugrendermode & 4) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG2]; - } - if (CV_r_debugrendermode & 8) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG3]; - } - } -#endif - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } - - if (CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - // If the object is transparent and if the object has the UAV bound. - bool multilayerUAVBound = (rRP.m_ObjFlags & FOB_AFTER_WATER) != 0; - if (rRP.m_pShaderResources && rRP.m_pShaderResources->IsTransparent() && multilayerUAVBound) - { - MultiLayerAlphaBlendPass::GetInstance().ConfigureShaderFlags(rRP.m_FlagsShader_RT); - } - - if (!rd->FX_SetResourcesState()) - { - return; - } - - // Handle emissive materials - CShaderResources* pCurRes = rRP.m_pShaderResources; - if (pCurRes && pCurRes->IsEmissive() && !pCurRes->IsTransparent() && (rRP.m_PersFlags2 & RBPF2_HDR_FP16)) - { - rRP.m_MaterialStateAnd |= GS_BLEND_MASK; - rRP.m_MaterialStateOr = (rRP.m_MaterialStateOr & ~GS_BLEND_MASK) | (GS_BLSRC_ONE | GS_BLDST_ONE); - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ADDITIVE_BLENDING]; - } - - else if (rRP.m_ObjFlags & FOB_BENDED) - { - rRP.m_FlagsShader_MDV |= MDV_BENDING; - } - rRP.m_FlagsShader_RT |= pObj->m_nRTMask; -#ifdef TESSELLATION_RENDERER - if ((pObj->m_ObjFlags & FOB_NEAREST) || !(pObj->m_ObjFlags & FOB_ALLOW_TESSELLATION)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NO_TESSELLATION]; - } -#endif - if (!(rRP.m_PersFlags2 & RBPF2_NOSHADERFOG) && rTI.m_FS.m_bEnable && !(rRP.m_ObjFlags & FOB_NO_FOG) || !(rRP.m_PersFlags2 & RBPF2_ALLOW_DEFERREDSHADING)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_FOG]; - if (CRenderer::CV_r_VolumetricFog != 0) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_VOLUMETRIC_FOG]; - } - } - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_FOG_VOLUME_HIGH_QUALITY_SHADER]); - static ICVar* pCVarFogVolumeShadingQuality = gEnv->pConsole->GetCVar("e_FogVolumeShadingQuality"); - if (pCVarFogVolumeShadingQuality->GetIVal() > 0) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_FOG_VOLUME_HIGH_QUALITY_SHADER]; - } - - - const uint64 objFlags = rRP.m_ObjFlags; - if (objFlags & FOB_NEAREST) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NEAREST]; - } - if (SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID] == 0 && CV_r_ParticlesSoftIsec) - { - //Enable soft particle shader flag for soft particles or particles have half resolution enabled - //Note: the half res render pass is relying on the soft particle flag to test z buffer. - //I am not sure why they did this instead of just have enable z buffer test for that pass. - if ((objFlags & FOB_SOFT_PARTICLE) || (rRP.m_PersFlags2 & RBPF2_HALFRES_PARTICLES)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SOFT_PARTICLE]; - } - } - - if (ef->m_Flags2 & EF2_ALPHABLENDSHADOWS) - { - rd->FX_SetupShadowsForTransp(); - } - - if (rRP.m_pCurObject->m_RState & OS_ENVIRONMENT_CUBEMAP) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ENVIRONMENT_CUBEMAP]; - } - - if (rRP.m_pCurObject->m_RState & OS_ANIM_BLEND) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_ANIM_BLEND]; - } - if (objFlags & FOB_POINT_SPRITE) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SPRITE]; - } - - // Only enable for resources not using zpass - if (!(rRP.m_pRLD->m_nBatchFlags[rRP.m_nSortGroupID][rRP.m_nPassGroupID] & FB_Z) || (ef->m_Flags & EF_DECAL)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NOZPASS]; - } - - rRP.m_pCurTechnique = pTech; - - if ((rRP.m_nBatchFilter & (FB_MULTILAYERS | FB_DEBUG)) && !rRP.m_pReplacementShader) - { - if (rRP.m_nBatchFilter & FB_MULTILAYERS) - { - rd->FX_DrawMultiLayers(); - } - - if (rRP.m_nBatchFilter & FB_DEBUG) - { - rd->FX_DrawDebugPasses(); - } - } - else - { - rd->FX_DrawTechnique(ef, pTech); - } - }//pTech - else - if (ef->m_eSHDType == eSHDT_CustomDraw) - { - rd->FX_DrawTechnique(ef, 0); - } - -#ifdef DO_RENDERLOG - sLogFlush("Flush General", ef, pTech); -#endif -} - -void CD3D9Renderer::FX_FlushShader_ShadowGen() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - if (!rRP.m_pRE && !rRP.m_RendNumVerts) - { - return; - } - - CShader* ef = rRP.m_pShader; - if (!ef) - { - return; - } - - if (!rRP.m_sExcludeShader.empty()) - { - char nm[1024]; - azstrcpy(nm, AZ_ARRAY_SIZE(nm), ef->GetName()); - azstrlwr(nm, AZ_ARRAY_SIZE(nm)); - if (strstr(rRP.m_sExcludeShader.c_str(), nm)) - { - return; - } - } - - assert(rRP.m_TI[rRP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN); - - CRenderObject* pObj = rRP.m_pCurObject; - -#ifdef DO_RENDERLOG - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - if (CV_r_log == 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "\n\n.. Start %s flush: '%s' ..\n", "ShadowGen", ef->GetName()); - } - if (CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "\n"); - } - } -#endif - -#ifndef _RELEASE - sBatchStats(rRP); -#endif - - PROFILE_SHADER_SCOPE; - -#if defined(HW_INSTANCING_ENABLED) - sDetectInstancing(ef, pObj); -#endif - - SShaderTechnique* __restrict pTech = ef->mfGetStartTechnique(rRP.m_nShaderTechnique); - assert(pTech); - if (!pTech || pTech->m_nTechnique[TTYPE_SHADOWGEN] < 0) - { - return; - } - - rRP.m_nShaderTechniqueType = TTYPE_SHADOWGEN; - - if (rd->m_RP.m_pRE) - { - rd->m_RP.m_pRE = rd->m_RP.m_RIs[0][0]->pElem; - } - - rRP.m_pRootTechnique = pTech; - - pTech = ef->m_HWTechniques[pTech->m_nTechnique[TTYPE_SHADOWGEN]]; - - - const SRenderPipeline::ShadowInfo& shadowInfo = rd->m_RP.m_ShadowInfo; - - if (ef->m_eSHDType == eSHDT_Terrain) - { - if (shadowInfo.m_pCurShadowFrustum->m_Flags & DLF_DIRECTIONAL) - { - rd->D3DSetCull(eCULL_None); - rd->m_RP.m_FlagsPerFlush |= RBSI_LOCKCULL; - } - else - { - rd->D3DSetCull(eCULL_Front); - rd->m_RP.m_FlagsPerFlush |= RBSI_LOCKCULL; - } - } - - // RSMs -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*shadowInfo.m_pCurShadowFrustum)) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - - if (!(shadowInfo.m_pCurShadowFrustum->m_Flags & DLF_DIRECTIONAL)) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0] | g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE]; - } - - rd->D3DSetCull(eCULL_Back); - - const uint64_t objFlags = rRP.m_ObjFlags; - if (objFlags & FOB_DECAL_TEXGEN_2D) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D]; - } - } - else -#endif - if (rRP.m_PersFlags2 & (RBPF2_DRAWTOCUBE | RBPF2_DISABLECOLORWRITES)) - { - if (rRP.m_PersFlags2 & RBPF2_DISABLECOLORWRITES) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]; - } - if (rRP.m_PersFlags2 & RBPF2_DRAWTOCUBE) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - } -#ifdef TESSELLATION_RENDERER - if ((pObj->m_ObjFlags & FOB_NEAREST) || !(pObj->m_ObjFlags & FOB_ALLOW_TESSELLATION)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NO_TESSELLATION]; - } -#endif - - if (!rd->FX_SetResourcesState()) - { - return; - } - - if ((rRP.m_ObjFlags & FOB_BENDED)) - { - rRP.m_FlagsShader_MDV |= MDV_BENDING; - } - rRP.m_FlagsShader_RT |= rRP.m_pCurObject->m_nRTMask; - - if (rRP.m_ObjFlags & FOB_NEAREST) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NEAREST]; - } - - if (rRP.m_ObjFlags & FOB_DISSOLVE) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DISSOLVE]; - } - - rRP.m_pCurTechnique = pTech; - rd->FX_DrawTechnique(ef, pTech); - -#ifdef DO_RENDERLOG - sLogFlush("Flush ShadowGen", ef, pTech); -#endif -} - -void CD3D9Renderer::FX_FlushShader_ZPass() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - if (!rRP.m_pRE && !rRP.m_RendNumVerts) - { - return; - } - - CShader* ef = rRP.m_pShader; - if (!ef) - { - return; - } - - if (!rRP.m_sExcludeShader.empty()) - { - char nm[1024]; - azstrcpy(nm, AZ_ARRAY_SIZE(nm), ef->GetName()); - azstrlwr(nm, AZ_ARRAY_SIZE(nm)); - if (strstr(rRP.m_sExcludeShader.c_str(), nm)) - { - return; - } - } - - assert(!(rRP.m_TI[rRP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN)); - assert(rRP.m_nBatchFilter & (FB_Z | FB_ZPREPASS | FB_POST_3D_RENDER)); - -#ifdef DO_RENDERLOG - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - if (CV_r_log == 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "\n\n.. Start %s flush: '%s' ..\n", "ZPass", ef->GetName()); - } - else - if (CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "\n"); - } - } -#endif - - if (rd->m_RP.m_pRE) - { - rd->m_RP.m_pRE = rd->m_RP.m_RIs[0][0]->pElem; - } - -#ifndef _RELEASE - sBatchStats(rRP); -#endif - PROFILE_SHADER_SCOPE; - -#if defined(HW_INSTANCING_ENABLED) - sDetectInstancing(ef, rRP.m_pCurObject); -#endif - - // Techniques draw cycle... - SShaderTechnique* __restrict pTech = ef->mfGetStartTechnique(rRP.m_nShaderTechnique); - const uint32 nTechniqueID = (rRP.m_nBatchFilter & FB_Z) ? TTYPE_Z : TTYPE_ZPREPASS; - if (!pTech || pTech->m_nTechnique[nTechniqueID] < 0) - { - return; - } - - rRP.m_nShaderTechniqueType = nTechniqueID; - rRP.m_pRootTechnique = pTech; - - // Skip z-pass if appropriate technique does not exist - assert(pTech->m_nTechnique[nTechniqueID] < (int)ef->m_HWTechniques.Num()); - pTech = ef->m_HWTechniques[pTech->m_nTechnique[nTechniqueID]]; - - if (!rd->FX_SetResourcesState()) - { - return; - } - - rRP.m_FlagsShader_RT |= rRP.m_pCurObject->m_nRTMask; - if (rRP.m_ObjFlags & FOB_BENDED) - { - rRP.m_FlagsShader_MDV |= MDV_BENDING; - } - - if (rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS) - { - if ((rRP.m_pCurObject->m_ObjFlags & (FOB_MOTION_BLUR | FOB_HAS_PREVMATRIX)) && (rRP.m_PersFlags2 & RBPF2_NOALPHABLEND)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_MOTION_BLUR]; - } - else - { - rRP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_MOTION_BLUR]; - } - } - -#ifdef TESSELLATION_RENDERER - if ((rRP.m_pCurObject->m_ObjFlags & FOB_NEAREST) || !(rRP.m_pCurObject->m_ObjFlags & FOB_ALLOW_TESSELLATION)) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_NO_TESSELLATION]; - } -#endif - - // Set VisArea and Dynamic objects Stencil Ref - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingStencilPrepass) - { - if (rRP.m_nPassGroupID != EFSLIST_DECAL && !(rRP.m_nBatchFilter & FB_ZPREPASS)) - { - rRP.m_ForceStateOr |= GS_STENCIL; - - uint32 nStencilRef = CRenderer::CV_r_VisAreaClipLightsPerPixel ? 0 : (rd->m_RP.m_RIs[0][0]->nStencRef | BIT_STENCIL_INSIDE_CLIPVOLUME); - - // Here we check if an object can receive decals. - bool bObjectAcceptsDecals = !(rRP.m_pCurObject->m_NoDecalReceiver); - if (bObjectAcceptsDecals) - { - nStencilRef |= (!(rRP.m_pCurObject->m_ObjFlags & FOB_DYNAMIC_OBJECT) || CV_r_deferredDecalsOnDynamicObjects ? BIT_STENCIL_RESERVED : 0); - } - const int32 stencilState = STENC_FUNC(FSS_STENCFUNC_ALWAYS) | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_REPLACE); - rd->FX_SetStencilState(stencilState, nStencilRef, 0xFF, 0xFF); - } - else - { - rRP.m_ForceStateOr &= ~GS_STENCIL; - } - } - - rRP.m_pCurTechnique = pTech; - rd->FX_DrawTechnique(ef, pTech); - - rRP.m_ForceStateOr &= ~GS_STENCIL; - //reset stencil AND mask always - rRP.m_CurStencilRefAndMask = 0; - -#ifdef DO_RENDERLOG - sLogFlush("Flush ZPass", ef, pTech); -#endif -} - -//=================================================================================================== - -static int sTexLimitRes(uint32 nSrcsize, uint32 nDstSize) -{ - while (true) - { - if (nSrcsize > nDstSize) - { - nSrcsize >>= 1; - } - else - { - break; - } - } - return nSrcsize; -} - -static Matrix34 sMatrixLookAt(const Vec3& dir, const Vec3& up, float rollAngle = 0) -{ - Matrix34 M; - // LookAt transform. - Vec3 xAxis, yAxis, zAxis; - Vec3 upVector = up; - - yAxis = -dir.GetNormalized(); - - //if (zAxis.x == 0.0 && zAxis.z == 0) up.Set( -zAxis.y,0,0 ); else up.Set( 0,1.0f,0 ); - - xAxis = upVector.Cross(yAxis).GetNormalized(); - zAxis = xAxis.Cross(yAxis).GetNormalized(); - - // OpenGL kind of matrix. - M(0, 0) = xAxis.x; - M(0, 1) = yAxis.x; - M(0, 2) = zAxis.x; - M(0, 3) = 0; - - M(1, 0) = xAxis.y; - M(1, 1) = yAxis.y; - M(1, 2) = zAxis.y; - M(1, 3) = 0; - - M(2, 0) = xAxis.z; - M(2, 1) = yAxis.z; - M(2, 2) = zAxis.z; - M(2, 3) = 0; - - if (rollAngle != 0) - { - Matrix34 RollMtx; - RollMtx.SetIdentity(); - - float cossin[2]; - // sincos_tpl(rollAngle, cossin); - sincos_tpl(rollAngle, &cossin[1], &cossin[0]); - - RollMtx(0, 0) = cossin[0]; - RollMtx(0, 2) = -cossin[1]; - RollMtx(2, 0) = cossin[1]; - RollMtx(2, 2) = cossin[0]; - - // Matrix multiply. - M = RollMtx * M; - } - - return M; -} - -void TexBlurAnisotropicVertical(CTexture* pTex, int nAmount, float fScale, [[maybe_unused]] float fDistribution, [[maybe_unused]] bool bAlphaOnly) -{ - if (!pTex) - { - return; - } - - SDynTexture* tpBlurTemp = new SDynTexture(pTex->GetWidth(), pTex->GetHeight(), pTex->GetDstFormat(), eTT_2D, FT_STATE_CLAMP, "TempBlurAnisoVertRT"); - if (!tpBlurTemp) - { - return; - } - - tpBlurTemp->Update(pTex->GetWidth(), pTex->GetHeight()); - - if (!tpBlurTemp->m_pTexture) - { - SAFE_DELETE(tpBlurTemp); - return; - } - - PROFILE_SHADER_SCOPE; - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - Vec4 vWhite(1.0f, 1.0f, 1.0f, 1.0f); - - static CCryNameTSCRC pTechName("AnisotropicVertical"); - CShader* m_pCurrShader = CShaderMan::s_shPostEffects; - - uint32 nPasses; - m_pCurrShader->FXSetTechnique(pTechName); - m_pCurrShader->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_pCurrShader->FXBeginPass(0); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - // setup texture offsets, for texture sampling - float t1 = 1.0f / (float) pTex->GetHeight(); - - Vec4 pWeightsPS; - pWeightsPS.x = 0.25f * t1; - pWeightsPS.y = 0.5f * t1; - pWeightsPS.z = 0.75f * t1; - pWeightsPS.w = 1.0f * t1; - - - pWeightsPS *= -fScale; - - - STexState sTexState = STexState(FILTER_LINEAR, true); - static CCryNameR pParam0Name("blurParams0"); - - for (int p(1); p <= nAmount; ++p) - { - //Horizontal - - CShaderMan::s_shPostEffects->FXSetVSFloat(pParam0Name, &pWeightsPS, 1); - gcpRendD3D->FX_PushRenderTarget(0, tpBlurTemp->m_pTexture, NULL); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - pTex->Apply(0, CTexture::GetTexState(sTexState)); - PostProcessUtils().DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - gcpRendD3D->FX_PopRenderTarget(0); - - //Vertical - - pWeightsPS *= 2.0f; - - gcpRendD3D->FX_PushRenderTarget(0, pTex, NULL); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXSetVSFloat(pParam0Name, &pWeightsPS, 1); - tpBlurTemp->m_pTexture->Apply(0, CTexture::GetTexState(sTexState)); - PostProcessUtils().DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - gcpRendD3D->FX_PopRenderTarget(0); - } - - m_pCurrShader->FXEndPass(); - m_pCurrShader->FXEnd(); - - // Restore previous viewport - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - //release dyntexture - SAFE_DELETE(tpBlurTemp); -} - -bool CD3D9Renderer::FX_DrawToRenderTarget(CShader* pShader, CShaderResources* pRes, CRenderObject* pObj, SShaderTechnique* pTech, SHRenderTarget* pRT, int nPreprType, IRenderElement* pRE) -{ - if (!pRT) - { - return false; - } - - int nThreadList = m_pRT->GetThreadList(); - - uint32 nPrFlags = pRT->m_nFlags; - if (nPrFlags & FRT_RENDTYPE_CURSCENE) - { - return false; - } - - CRenderObject* pPrevIgn = m_RP.m_TI[nThreadList].m_pIgnoreObject; - CTexture* Tex = pRT->m_pTarget[0]; - SEnvTexture* pEnvTex = NULL; - - if (nPreprType == SPRID_SCANTEX) - { - nPrFlags |= FRT_CAMERA_REFLECTED_PLANE; - pRT->m_nFlags = nPrFlags; - } - - if (nPrFlags & FRT_RENDTYPE_CURSCENE) - { - return false; - } - - AZ_TRACE_METHOD(); - - uint32 nWidth = pRT->m_nWidth; - uint32 nHeight = pRT->m_nHeight; - - if (pRT->m_nIDInPool >= 0) - { - assert((int)CTexture::s_CustomRT_2D->Num() > pRT->m_nIDInPool); - if ((int)CTexture::s_CustomRT_2D->Num() <= pRT->m_nIDInPool) - { - return false; - } - pEnvTex = &(*CTexture::s_CustomRT_2D)[pRT->m_nIDInPool]; - - if (nWidth == -1) - { - nWidth = GetWidth(); - } - if (nHeight == -1) - { - nHeight = GetHeight(); - } - - ETEX_Format eTF = pRT->m_eTF; - // $HDR - if (eTF == eTF_R8G8B8A8 && IsHDRModeEnabled() && m_nHDRType <= 1) - { - eTF = eTF_R16G16B16A16F; - } - - // Very hi specs render reflections at half res - lower specs (and consoles) at quarter res - bool bMakeEnvironmentTexture = false; - if (OceanToggle::IsActive()) - { - float fSizeScale = 0.5f; - AZ::OceanEnvironmentBus::BroadcastResult(fSizeScale, &AZ::OceanEnvironmentBus::Events::GetReflectResolutionScale); - fSizeScale = clamp_tpl(fSizeScale, 0.0f, 1.0f); - - nWidth = sTexLimitRes(nWidth, uint32(GetWidth() * fSizeScale)); - nHeight = sTexLimitRes(nHeight, uint32(GetHeight() * fSizeScale)); - - bMakeEnvironmentTexture = (!pEnvTex->m_pTex || pEnvTex->m_pTex->GetFormat() != eTF || pEnvTex->m_pTex->GetWidth() != nWidth || pEnvTex->m_pTex->GetHeight() != nHeight); - } - else - { - float fSizeScale = (CV_r_waterreflections_quality == 5) ? 0.5f : 0.25f; - - nWidth = sTexLimitRes(nWidth, uint32(GetWidth() * fSizeScale)); - nHeight = sTexLimitRes(nHeight, uint32(GetHeight() * fSizeScale)); - - bMakeEnvironmentTexture = (!pEnvTex->m_pTex || pEnvTex->m_pTex->GetFormat() != eTF); - } - - // clamping to a reasonable texture size - if (nWidth < 32) - { - nWidth = 32; - } - if (nHeight < 32) - { - nHeight = 32; - } - - if (bMakeEnvironmentTexture) - { - char name[128]; - sprintf_s(name, "$RT_2D_%d", m_TexGenID++); - int flags = FT_NOMIPS | FT_STATE_CLAMP | FT_DONT_STREAM; - pEnvTex->m_pTex = new SDynTexture(nWidth, nHeight, eTF, eTT_2D, flags, name); - } - assert(nWidth > 0 && nWidth <= m_d3dsdBackBuffer.Width); - assert(nHeight > 0 && nHeight <= m_d3dsdBackBuffer.Height); - Tex = pEnvTex->m_pTex->m_pTexture; - } - else - if (Tex) - { - if (Tex->GetCustomID() == TO_RT_2D) - { - bool bReflect = false; - if (nPrFlags & (FRT_CAMERA_REFLECTED_PLANE | FRT_CAMERA_REFLECTED_WATERPLANE)) - { - bReflect = true; - } - Matrix33 orientation = Matrix33(GetCamera().GetMatrix()); - Ang3 Angs = CCamera::CreateAnglesYPR(orientation); - Vec3 Pos = GetCamera().GetPosition(); - bool bNeedUpdate = false; - pEnvTex = CTexture::FindSuitableEnvTex(Pos, Angs, false, -1, false, pShader, pRes, pObj, bReflect, pRE, &bNeedUpdate); - - if (!bNeedUpdate) - { - if (!pEnvTex) - { - return false; - } - if (pEnvTex->m_pTex && pEnvTex->m_pTex->m_pTexture) - { - return true; - } - } - m_RP.m_TI[nThreadList].m_pIgnoreObject = pObj; - switch (CRenderer::CV_r_envtexresolution) - { - case 0: - nWidth = 64; - break; - case 1: - nWidth = 128; - break; - case 2: - default: - nWidth = 256; - break; - case 3: - nWidth = 512; - break; - } - nHeight = nWidth; - if (!pEnvTex || !pEnvTex->m_pTex) - { - return false; - } - if (!pEnvTex->m_pTex->m_pTexture) - { - pEnvTex->m_pTex->Update(nWidth, nHeight); - } - Tex = pEnvTex->m_pTex->m_pTexture; - } - } - if (m_pRT->IsRenderThread() && Tex && Tex->IsActiveRenderTarget()) - { - return true; - } - - // always allow for non-mgpu - bool bMGPUAllowNextUpdate = gRenDev->GetActiveGPUCount() == 1; - - ETEX_Format eTF = pRT->m_eTF; - // $HDR - if (eTF == eTF_R8G8B8A8 && IsHDRModeEnabled() && m_nHDRType <= 1) - { - eTF = eTF_R16G16B16A16F; - } - if (pEnvTex && (!pEnvTex->m_pTex || pEnvTex->m_pTex->GetFormat() != eTF)) - { - SAFE_DELETE(pEnvTex->m_pTex); - char name[128]; - sprintf_s(name, "$RT_2D_%d", m_TexGenID++); - int flags = FT_NOMIPS | FT_STATE_CLAMP | FT_DONT_STREAM; - pEnvTex->m_pTex = new SDynTexture(nWidth, nHeight, eTF, eTT_2D, flags, name); - assert(nWidth > 0 && nWidth <= m_d3dsdBackBuffer.Width); - assert(nHeight > 0 && nHeight <= m_d3dsdBackBuffer.Height); - pEnvTex->m_pTex->Update(nWidth, nHeight); - } - - bool bEnableAnisotropicBlur = true; - switch (pRT->m_eUpdateType) - { - case eRTUpdate_WaterReflect: - { - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_waterreflections) - { - assert(pEnvTex != NULL); - if (pEnvTex && pEnvTex->m_pTex && pEnvTex->m_pTex->m_pTexture) - { - m_pRT->RC_ClearTarget(pEnvTex->m_pTex->m_pTexture, Clr_Empty); - } - return true; - } - - if (m_RP.m_nLastWaterFrameID == GetFrameID()) - { - // water reflection already created this frame, share it - return true; - } - - I3DEngine* eng = (I3DEngine*)gEnv->p3DEngine; - int nVisibleWaterPixelsCount = eng->GetOceanVisiblePixelsCount() / 2; // bug in occlusion query returns 2x more - int nPixRatioThreshold = (int)(GetWidth() * GetHeight() * CRenderer::CV_r_waterreflections_min_visible_pixels_update); - - static int nVisWaterPixCountPrev = nVisibleWaterPixelsCount; - - float fUpdateFactorMul = 1.0f; - float fUpdateDistanceMul = 1.0f; - if (nVisWaterPixCountPrev < nPixRatioThreshold / 4) - { - bEnableAnisotropicBlur = false; - fUpdateFactorMul = CV_r_waterreflections_minvis_updatefactormul * 10.0f; - fUpdateDistanceMul = CV_r_waterreflections_minvis_updatedistancemul * 5.0f; - } - else - if (nVisWaterPixCountPrev < nPixRatioThreshold) - { - fUpdateFactorMul = CV_r_waterreflections_minvis_updatefactormul; - fUpdateDistanceMul = CV_r_waterreflections_minvis_updatedistancemul; - } - - float fWaterUpdateFactor = CV_r_waterupdateFactor * fUpdateFactorMul; - float fWaterUpdateDistance = CV_r_waterupdateDistance * fUpdateDistanceMul; - - float fTimeUpd = min(0.3f, eng->GetDistanceToSectorWithWater()); - fTimeUpd *= fWaterUpdateFactor; - //if (fTimeUpd > 1.0f) - //fTimeUpd = 1.0f; - Vec3 camView = m_RP.m_TI[nThreadList].m_cam.m_viewParameters.ViewDir(); - Vec3 camUp = m_RP.m_TI[nThreadList].m_cam.m_viewParameters.vY; - - m_RP.m_nLastWaterFrameID = GetFrameID(); - - Vec3 camPos = GetCamera().GetPosition(); - float fDistCam = (camPos - m_RP.m_LastWaterPosUpdate).GetLength(); - float fDotView = camView * m_RP.m_LastWaterViewdirUpdate; - float fFOV = GetCamera().GetFov(); - if (m_RP.m_fLastWaterUpdate - 1.0f > m_RP.m_TI[nThreadList].m_RealTime) - { - m_RP.m_fLastWaterUpdate = m_RP.m_TI[nThreadList].m_RealTime; - } - - const float fMaxFovDiff = 0.1f; // no exact test to prevent slowly changing fov causing per frame water reflection updates - - static bool bUpdateReflection = true; - if (bMGPUAllowNextUpdate) - { - bUpdateReflection = m_RP.m_TI[nThreadList].m_RealTime - m_RP.m_fLastWaterUpdate >= fTimeUpd || fDistCam > fWaterUpdateDistance; - bUpdateReflection = bUpdateReflection || fDotView<0.9f || fabs(fFOV - m_RP.m_fLastWaterFOVUpdate)>fMaxFovDiff; - } - - if (bUpdateReflection && bMGPUAllowNextUpdate) - { - m_RP.m_fLastWaterUpdate = m_RP.m_TI[nThreadList].m_RealTime; - m_RP.m_LastWaterViewdirUpdate = camView; - m_RP.m_LastWaterUpdirUpdate = camUp; - m_RP.m_fLastWaterFOVUpdate = fFOV; - m_RP.m_LastWaterPosUpdate = camPos; - assert(pEnvTex != NULL); - pEnvTex->m_pTex->ResetUpdateMask(); - } - else - if (!bUpdateReflection) - { - assert(pEnvTex != NULL); - PREFAST_ASSUME(pEnvTex != NULL); - if (pEnvTex && pEnvTex->m_pTex && pEnvTex->m_pTex->IsValid()) - { - return true; - } - } - - assert(pEnvTex != NULL); - PREFAST_ASSUME(pEnvTex != NULL); - pEnvTex->m_pTex->SetUpdateMask(); - } - break; - } - - // Just copy current BB to the render target and exit - if (nPrFlags & FRT_RENDTYPE_COPYSCENE) - { - // Get current render target from the RT stack - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_debugrefraction) - { - FX_ScreenStretchRect(Tex); // should encode hdr format - } - else - { - assert(Tex != NULL); - m_pRT->RC_ClearTarget(Tex, Clr_Debug); - } - - return true; - } - - I3DEngine* eng = (I3DEngine*)gEnv->p3DEngine; - Matrix44A matProj, matView; - - float plane[4]; - bool bUseClipPlane = false; - bool bChangedCamera = false; - - int nPersFlags = m_RP.m_TI[nThreadList].m_PersFlags; - //int nPersFlags2 = m_RP.m_TI[nThreadList].m_PersFlags2; - - static CCamera tmp_cam_mgpu = GetCamera(); - CCamera tmp_cam = GetCamera(); - CCamera prevCamera = tmp_cam; - bool bMirror = false; - bool bOceanRefl = false; - - // Set the camera - if (nPrFlags & FRT_CAMERA_REFLECTED_WATERPLANE) - { - bOceanRefl = true; - - m_RP.m_TI[nThreadList].m_pIgnoreObject = pObj; - float fMinDist = min(SKY_BOX_SIZE * 0.5f, eng->GetDistanceToSectorWithWater()); // 16 is half of skybox size - float fMaxDist = eng->GetMaxViewDistance(); - - Vec3 vPrevPos = tmp_cam.GetPosition(); - - Plane Pl; - Pl.n = Vec3(0, 0, 1); - Pl.d = OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : eng->GetWaterLevel(); - if ((vPrevPos | Pl.n) - Pl.d < 0) - { - Pl.d = -Pl.d; - Pl.n = -Pl.n; - } - - plane[0] = Pl.n[0]; - plane[1] = Pl.n[1]; - plane[2] = Pl.n[2]; - plane[3] = -Pl.d; - - Matrix44 camMat; - GetModelViewMatrix(camMat.GetData()); - Vec3 vPrevDir = Vec3(-camMat(0, 2), -camMat(1, 2), -camMat(2, 2)); - Vec3 vPrevUp = Vec3(camMat(0, 1), camMat(1, 1), camMat(2, 1)); - Vec3 vNewDir = Pl.MirrorVector(vPrevDir); - Vec3 vNewUp = Pl.MirrorVector(vPrevUp); - float fDot = vPrevPos.Dot(Pl.n) - Pl.d; - Vec3 vNewPos = vPrevPos - Pl.n * 2.0f * fDot; - Matrix34 m = sMatrixLookAt(vNewDir, vNewUp, tmp_cam.GetAngles()[2]); - - // New position + offset along view direction - minimizes projection artefacts - m.SetTranslation(vNewPos + Vec3(vNewDir.x, vNewDir.y, 0)); - - tmp_cam.SetMatrix(m); - - assert(pEnvTex); - PREFAST_ASSUME(pEnvTex); - tmp_cam.SetFrustum((int)(pEnvTex->m_pTex->GetWidth() * tmp_cam.GetProjRatio()), pEnvTex->m_pTex->GetHeight(), tmp_cam.GetFov(), fMinDist, fMaxDist); //tmp_cam.GetFarPlane()); - - // Allow camera update - if (bMGPUAllowNextUpdate) - { - tmp_cam_mgpu = tmp_cam; - } - - SetCamera(tmp_cam_mgpu); - bChangedCamera = true; - bUseClipPlane = true; - bMirror = true; - //m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_MIRRORCULL; - } - else - if (nPrFlags & FRT_CAMERA_REFLECTED_PLANE) - { // Mirror case - m_RP.m_TI[nThreadList].m_pIgnoreObject = pObj; - float fMinDist = 0.25f; - float fMaxDist = eng->GetMaxViewDistance(); - - Vec3 vPrevPos = tmp_cam.GetPosition(); - - Plane Pl; - pRE->mfGetPlane(Pl); - //Pl.d = -Pl.d; - if (pObj) - { - Matrix44 mat = pObj->m_II.m_Matrix.GetTransposed(); - Pl = TransformPlane(mat, Pl); - } - if ((vPrevPos | Pl.n) - Pl.d < 0) - { - Pl.d = -Pl.d; - Pl.n = -Pl.n; - } - - plane[0] = Pl.n[0]; - plane[1] = Pl.n[1]; - plane[2] = Pl.n[2]; - plane[3] = -Pl.d; - - //this is the new code to calculate the reflection matrix - - Matrix44A camMat; - GetModelViewMatrix(camMat.GetData()); - Vec3 vPrevDir = Vec3(-camMat(0, 2), -camMat(1, 2), -camMat(2, 2)); - Vec3 vPrevUp = Vec3(camMat(0, 1), camMat(1, 1), camMat(2, 1)); - Vec3 vNewDir = Pl.MirrorVector(vPrevDir); - Vec3 vNewUp = Pl.MirrorVector(vPrevUp); - float fDot = vPrevPos.Dot(Pl.n) - Pl.d; - Vec3 vNewPos = vPrevPos - Pl.n * 2.0f * fDot; - Matrix34A m = sMatrixLookAt(vNewDir, vNewUp, tmp_cam.GetAngles()[2]); - m.SetTranslation(vNewPos); - tmp_cam.SetMatrix(m); - - assert(Tex); - tmp_cam.SetFrustum((int)(Tex->GetWidth() * tmp_cam.GetProjRatio()), Tex->GetHeight(), tmp_cam.GetFov(), fMinDist, fMaxDist); //tmp_cam.GetFarPlane()); - bMirror = true; - bUseClipPlane = true; - - SetCamera(tmp_cam); - bChangedCamera = true; - } - else - if (((nPrFlags & FRT_CAMERA_CURRENT) || (nPrFlags & FRT_RENDTYPE_CURSCENE)) && pRT->m_eOrder == eRO_PreDraw && !(nPrFlags & FRT_RENDTYPE_CUROBJECT)) - { - // Always restore stuff after explicitly changing... - - // get texture surface - // Get current render target from the RT stack - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_debugrefraction) - { - FX_ScreenStretchRect(Tex); // should encode hdr format - } - else - { - m_pRT->RC_ClearTarget(Tex, Clr_Debug); - } - - m_RP.m_TI[nThreadList].m_pIgnoreObject = pPrevIgn; - return true; - } - - bool bRes = true; - - m_pRT->RC_PushVP(); - m_pRT->RC_PushFog(); - m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_DRAWTOTEXTURE | RBPF_ENCODE_HDR; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[nThreadList], "*** Set RT for Water reflections ***\n"); - } - - assert(pEnvTex); - PREFAST_ASSUME(pEnvTex); - m_pRT->RC_SetEnvTexRT(pEnvTex, pRT->m_bTempDepth ? pEnvTex->m_pTex->GetWidth() : -1, pRT->m_bTempDepth ? pEnvTex->m_pTex->GetHeight() : -1, true); - m_pRT->RC_ClearTargetsImmediately(1, pRT->m_nFlags, pRT->m_ClearColor, pRT->m_fClearDepth); - - float fAnisoScale = 1.0f; - if (pRT->m_nFlags & FRT_RENDTYPE_CUROBJECT) - { - CCryNameR& nameTech = pTech->m_NameStr; - char newTech[128]; - sprintf_s(newTech, "%s_RT", nameTech.c_str()); - SShaderTechnique* pT = pShader->mfFindTechnique(newTech); - if (!pT) - { - iLog->Log("Error: CD3D9Renderer::FX_DrawToRenderTarget: Couldn't find technique '%s' in shader '%s'\n", newTech, pShader->GetName()); - } - else - { - FX_ObjectChange(pShader, pRes, pObj, pRE); - FX_Start(pShader, -1, pRes, pRE); - pRE->mfPrepare(false); - FX_DrawShader_General(pShader, pT); - } - } - else - { - if (bMirror) - { - if (bOceanRefl) - { - SetCamera(tmp_cam); - } - - m_pRT->RC_SetEnvTexMatrix(pEnvTex); - - if (bOceanRefl) - { - SetCamera(tmp_cam_mgpu); - } - } - - m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_OBLIQUE_FRUSTUM_CLIPPING | RBPF_MIRRORCAMERA; // | RBPF_MIRRORCULL; ?? - - Plane p; - p.n[0] = plane[0]; - p.n[1] = plane[1]; - p.n[2] = plane[2]; - p.d = plane[3]; // +0.25f; - fAnisoScale = plane[3]; - fAnisoScale = fabs(fabs(fAnisoScale) - GetCamera().GetPosition().z); - m_RP.m_TI[nThreadList].m_bObliqueClipPlane = true; - - // put clipplane in clipspace.. - Matrix44A mView, mProj, mCamProj, mInvCamProj; - GetModelViewMatrix(&mView(0, 0)); - GetProjectionMatrix(&mProj(0, 0)); - mCamProj = mView * mProj; - mInvCamProj = mCamProj.GetInverted(); - m_RP.m_TI[nThreadList].m_pObliqueClipPlane = TransformPlane2(mInvCamProj, p); - - int nRenderPassFlags = 0; - - if (bOceanRefl && OceanToggle::IsActive()) - { - AZ::OceanEnvironmentBus::Broadcast(&AZ::OceanEnvironmentBus::Events::ApplyReflectRenderFlags, nRenderPassFlags); - } - else - { - int nReflQuality = (bOceanRefl) ? (int)CV_r_waterreflections_quality : (int)CV_r_reflections_quality; - - // set reflection quality setting - switch (nReflQuality) - { - case 1: - case 2: - nRenderPassFlags |= SRenderingPassInfo::ENTITIES; - break; - case 3: - case 4: - case 5: - nRenderPassFlags |= SRenderingPassInfo::STATIC_OBJECTS | SRenderingPassInfo::ENTITIES; - break; - } - } - - int nRFlags = SHDF_ALLOWHDR | SHDF_NO_DRAWNEAR; - - eng->RenderSceneReflection(nRFlags, SRenderingPassInfo::CreateRecursivePassRenderingInfo(bOceanRefl ? tmp_cam_mgpu : tmp_cam, nRenderPassFlags)); - - m_RP.m_TI[nThreadList].m_bObliqueClipPlane = false; - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_OBLIQUE_FRUSTUM_CLIPPING; - } - m_pRT->RC_PopRT(0); - - bool bUseVeryHiSpecAnisotropicReflections = false; - if (OceanToggle::IsActive()) - { - bool bAnisotropicReflections = false; - if (bOceanRefl) - { - AZ::OceanEnvironmentBus::BroadcastResult(bAnisotropicReflections, &AZ::OceanEnvironmentBus::Events::GetReflectionAnisotropic); - } - else - { - bAnisotropicReflections = (int)CV_r_reflections_quality >= 4; - } - bUseVeryHiSpecAnisotropicReflections = (bAnisotropicReflections && bEnableAnisotropicBlur && Tex && Tex->GetDevTexture()); - } - else - { - int nReflQuality = (bOceanRefl) ? (int)CV_r_waterreflections_quality : (int)CV_r_reflections_quality; - bUseVeryHiSpecAnisotropicReflections = (nReflQuality >= 4 && bEnableAnisotropicBlur && Tex && Tex->GetDevTexture()); - } - - // Very Hi specs get anisotropic reflections? - if (bUseVeryHiSpecAnisotropicReflections) - { - m_pRT->RC_TexBlurAnisotropicVertical(Tex, fAnisoScale); - } - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[nThreadList], "*** End RT for Water reflections ***\n"); - } - - // todo: encode hdr format - - m_RP.m_TI[nThreadList].m_PersFlags = nPersFlags; - //m_RP.m_TI[nThreadList].m_PersFlags2 = nPersFlags2; - - if (bChangedCamera) - { - SetCamera(prevCamera); - } - - m_pRT->RC_PopVP(); - m_pRT->RC_PopFog(); - - // increase frame id to support multiple recursive draws - m_RP.m_TI[nThreadList].m_nFrameID++; - m_RP.m_TI[nThreadList].m_pIgnoreObject = pPrevIgn; - - return bRes; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DFont.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DFont.cpp deleted file mode 100644 index b81c35e9a3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DFont.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "../CryFont/FBitmap.h" -//========================================================================================= - -bool CD3D9Renderer::FontUpdateTexture(int nTexId, int nX, int nY, int USize, int VSize, byte* pData) -{ - CTexture* tp = CTexture::GetByID(nTexId); - assert (tp); - - if (tp) - { - tp->UpdateTextureRegion(pData, nX, nY, 0, USize, VSize, 0, eTF_A8); - - return true; - } - return false; -} - -bool CD3D9Renderer::FontUploadTexture(class CFBitmap* pBmp, ETEX_Format eTF) -{ - if (!pBmp) - { - return false; - } - - unsigned int* pData = new unsigned int[pBmp->GetWidth() * pBmp->GetHeight()]; - - if (!pData) - { - return false; - } - - pBmp->Get32Bpp(&pData); - - char szName[128]; - azsprintf(szName, "$AutoFont_%d", m_TexGenID++); - - // FT_DONT_RELEASE was previously set here and caused the VRAM from font textures to never be released - int iFlags = FT_TEX_FONT | FT_DONT_STREAM; - CTexture* tp = CTexture::Create2DTexture(szName, pBmp->GetWidth(), pBmp->GetHeight(), 1, iFlags, (unsigned char*)pData, eTF, eTF); - - SAFE_DELETE_ARRAY(pData); - - pBmp->SetRenderData((void*)tp); - - return true; -} - -int CD3D9Renderer::FontCreateTexture(int Width, int Height, byte* pData, ETEX_Format eTF, bool genMips, const char* textureName) -{ - if (!pData) - { - return -1; - } - - char szName[128]; - if (textureName) - { - sprintf_s(szName, "$AutoFont_%d_%s", m_TexGenID++, textureName); - } - else - { - sprintf_s(szName, "$AutoFont_%d", m_TexGenID++); - } - - // FT_DONT_RELEASE was previously set here and caused the VRAM from font textures to never be released - int iFlags = FT_TEX_FONT | FT_DONT_STREAM; - if (genMips) - { - iFlags |= FT_FORCE_MIPS; - } - CTexture* tp = CTexture::Create2DTexture(szName, Width, Height, 1, iFlags, (unsigned char*)pData, eTF, eTF); - - return tp->GetID(); -} - -void CD3D9Renderer::FontReleaseTexture(class CFBitmap* pBmp) -{ - if (!pBmp) - { - return; - } - - CTexture* tp = (CTexture*)pBmp->GetRenderData(); - - SAFE_RELEASE(tp); -} - -void CD3D9Renderer::FontSetTexture(class CFBitmap* pBmp, int nFilterMode) -{ - if (pBmp) - { - CTexture* tp = (CTexture*)pBmp->GetRenderData(); - if (tp) - { - tp->SetFilterMode(nFilterMode); - tp->Apply(0); - } - } -} - -void CD3D9Renderer::FontSetTexture(int nTexId, int nFilterMode) -{ - if (nTexId <= 0) - { - return; - } - CTexture* tp = CTexture::GetByID(nTexId); - assert (tp); - if (!tp) - { - return; - } - - tp->SetFilterMode(nFilterMode); - tp->Apply(0); - //CTexture::m_Text_NoTexture->Apply(0); -} - -int s_InFontState = 0; - -void CD3D9Renderer::FontSetRenderingState(bool overrideViewProjMatrices, TransformationMatrices& backupMatrices) -{ - assert(!s_InFontState); - assert(m_pRT->IsRenderThread()); - - // setup various d3d things that we need - FontSetState(false, GS_DEPTHFUNC_LEQUAL); - - s_InFontState++; - - if (overrideViewProjMatrices) - { - Matrix44A *m; - backupMatrices.m_projectMatrix = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj.SetIdentity(); - m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - - if (m_NewViewport.nWidth != 0 && m_NewViewport.nHeight != 0) - { - const bool bReverseDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - const float zn = bReverseDepth ? 1.0f : -1.0f; - const float zf = bReverseDepth ? -1.0f : 1.0f; - - mathMatrixOrthoOffCenter(m, 0.0f, (float)m_NewViewport.nWidth, (float)m_NewViewport.nHeight, 0.0f, zn, zf); - } - - backupMatrices.m_viewMatrix = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - } -} - -void CD3D9Renderer::FontRestoreRenderingState(bool overrideViewProjMatrices, const TransformationMatrices& restoringMatrices) -{ - assert(m_pRT->IsRenderThread()); - assert(s_InFontState == 1); - s_InFontState--; - - if (overrideViewProjMatrices) - { - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = restoringMatrices.m_viewMatrix; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj = restoringMatrices.m_projectMatrix; - } - - FontSetState(true, GS_DEPTHFUNC_LEQUAL); -} - -void CD3D9Renderer::FontSetBlending(int blendSrc, int blendDest, int baseState) -{ - assert(m_pRT->IsRenderThread()); - m_fontBlendMode = blendSrc | blendDest; - - int additionalFontStateFlags = GS_DEPTHFUNC_LEQUAL; - int alphaReference = -1; - if (eTF_R16G16F != CTexture::s_eTFZ && CTexture::s_eTFZ != eTF_R32F) - { - additionalFontStateFlags = GS_DEPTHFUNC_LEQUAL | GS_ALPHATEST_GREATER; - alphaReference = 0; - } - - FX_SetState(m_fontBlendMode | ((baseState == -1) ? additionalFontStateFlags : baseState), alphaReference); -} - -void CD3D9Renderer::FontSetState(bool bRestore, int baseState) -{ - static DWORD wireframeMode; -#if !defined(OPENGL) - static D3DCOLORVALUE color; -#endif //!defined(OPENGL) - static bool bMatColor; - static uint32 nState, nForceState; - - assert(m_pRT->IsRenderThread()); - - // grab the modes that we might need to change - if (!bRestore) - { - D3DSetCull(eCULL_None); - - nState = m_RP.m_CurState; - nForceState = m_RP.m_StateOr; - wireframeMode = m_wireframe_mode; - - EF_SetVertColor(); - - if (wireframeMode > R_SOLID_MODE) - { - SStateRaster RS = gcpRendD3D->m_StatesRS[gcpRendD3D->m_nCurStateRS]; - RS.Desc.FillMode = D3D11_FILL_SOLID; - gcpRendD3D->SetRasterState(&RS); - } - - m_RP.m_FlagsPerFlush = 0; - int additionalFontStateFlags = GS_DEPTHFUNC_LEQUAL; - int alphaReference = -1; - if (eTF_R16G16F != CTexture::s_eTFZ && CTexture::s_eTFZ != eTF_R32F) - { - additionalFontStateFlags = GS_DEPTHFUNC_LEQUAL | GS_ALPHATEST_GREATER; - alphaReference = 0; - } - - FX_SetState(m_fontBlendMode | ((baseState == -1) ? additionalFontStateFlags : baseState), alphaReference); - EF_SetColorOp(eCO_REPLACE, eCO_MODULATE, eCA_Diffuse | (eCA_Diffuse << 3), DEF_TEXARG0); - - } - else - { - if (wireframeMode == R_WIREFRAME_MODE) - { - SStateRaster RS = gcpRendD3D->m_StatesRS[gcpRendD3D->m_nCurStateRS]; - RS.Desc.FillMode = D3D11_FILL_WIREFRAME; - gcpRendD3D->SetRasterState(&RS); - } - m_RP.m_StateOr = nForceState; - - //FX_SetState(State); - } -} - -void CD3D9Renderer::DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, const PublicRenderPrimitiveType nPrimType) -{ - PROFILE_FRAME(Draw_IndexMesh_Dyn); - - if (!pBuf) - { - return; - } - if (m_bDeviceLost) - { - return; - } - - //if (CV_d3d9_forcesoftware) - // return; - if (!nVerts || (pInds && !nInds)) - { - return; - } - - m_pRT->RC_DrawDynVB(pBuf, pInds, nVerts, nInds, nPrimType); -} - -void CD3D9Renderer::DrawDynUiPrimitiveList(DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices) -{ - PROFILE_FRAME(Draw_IndexMesh_Dyn); - - if (m_bDeviceLost) - { - return; - } - - m_pRT->RC_DrawDynUiPrimitiveList(primitives, totalNumVertices, totalNumIndices); -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHDRRender.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHDRRender.cpp deleted file mode 100644 index a6faffc300..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHDRRender.cpp +++ /dev/null @@ -1,2190 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include "I3DEngine.h" -#include "../Common/Textures/TextureManager.h" -#include "../Common/ReverseDepth.h" -#include "CryCommon/FrameProfiler.h" - - -enum class ToneMapOperators : int -{ - FilmicCurveUC2 = 0, - Linear = 1, - Exponential = 2, - Reinhard = 3, - FilmicCurveALU = 4 -}; - - - -enum class Exposuretype : int -{ - Auto = 0, //Any other variations of AUTO will go here. - Manual = 1 -}; - - -// render targets info - first gather list of hdr targets, sort by size and create after -struct SRenderTargetInfo -{ - SRenderTargetInfo() - : nWidth(0) - , nHeight(0) - , cClearColor(Clr_Empty) - , Format(eTF_Unknown) - , nFlags(0) - , lplpStorage(0) - , nPitch(0) - , fPriority(0.0f) - , nCustomID(0) - {}; - - uint32 nWidth; - uint32 nHeight; - ColorF cClearColor; - ETEX_Format Format; - uint32 nFlags; - CTexture** lplpStorage; - char szName[64]; - uint32 nPitch; - float fPriority; - int32 nCustomID; -}; - -struct RenderTargetSizeSort -{ - bool operator()(const SRenderTargetInfo& drtStart, const SRenderTargetInfo& drtEnd) { return (drtStart.nPitch * drtStart.fPriority) > (drtEnd.nPitch * drtEnd.fPriority); } -}; - -class CHDRPostProcess -{ -public: - - CHDRPostProcess() - { - nTexStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - nTexStateLinearWrap = CTexture::GetTexState(STexState(FILTER_LINEAR, false)); - nTexStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - nTexStatePointWrap = CTexture::GetTexState(STexState(FILTER_POINT, false)); - m_bHiQuality = false; - m_shHDR = 0; - m_shHDRDolbyMetadataPass0 = nullptr; - m_shHDRDolbyMetadataPass1 = nullptr; - } - - ~CHDRPostProcess() - { - } - - void ScreenShot(); - - void SetShaderParams(); - - // Tone mapping steps - void HalfResDownsampleHDRTarget(); - void QuarterResDownsampleHDRTarget(); - void SceneDownsampleUsingCompute(); // for mobile, uses CS to 1/2 & 1/4 res downsample in 1 pass - void MeasureLuminance(); - void EyeAdaptation(); - void MeasureLumEyeAdaptationUsingCompute(); // uses CS to collapse measure lum and eye adap passes - void BloomGeneration(); - void ProcessLensOptics(); - void ToneMapping(); - void ToneMappingDebug(); - void CalculateDolbyDynamicMetadata(CTexture* pSunShaftsRT); - void DrawDebugViews(); - void SetExposureTypeShaderFlags(); - CCryNameTSCRC GetTonemapTechnique() const; - - void EncodeDolbyVision(CTexture* source); - - void Begin(); - void Render(); - void End(); - - void AddRenderTarget(uint32 nWidth, uint32 nHeight, const ColorF& cClear, ETEX_Format Format, float fPriority, const char* szName, CTexture** pStorage, uint32 nFlags = 0, int32 nCustomID = -1, bool bDynamicTex = 0); - bool CreateRenderTargetList(); - void ClearRenderTargetList() - { - m_pRenderTargets.clear(); - } - - static CHDRPostProcess* GetInstance() - { - static CHDRPostProcess pInstance; - return &pInstance; - } -private: - std::vector< SRenderTargetInfo > m_pRenderTargets; - CShader* m_shHDR; - CShader* m_shHDRDolbyMetadataPass0; - CShader* m_shHDRDolbyMetadataPass1; - WrappedDX11Buffer m_bufDolbyMetadataMacroReductionOutput; - WrappedDX11Buffer m_bufDolbyMetadataMinMaxMid; - int32 nTexStateLinear; - int32 nTexStateLinearWrap; - int32 nTexStatePoint; - int32 nTexStatePointWrap; - bool m_bHiQuality; -}; - - -void CHDRPostProcess::AddRenderTarget(uint32 nWidth, uint32 nHeight, const ColorF& cClear, ETEX_Format Format, float fPriority, const char* szName, CTexture** pStorage, uint32 nFlags, int32 nCustomID, [[maybe_unused]] bool bDynamicTex) -{ - SRenderTargetInfo drt; - drt.nWidth = nWidth; - drt.nHeight = nHeight; - drt.cClearColor = cClear; - drt.nFlags = FT_USAGE_RENDERTARGET | FT_DONT_STREAM | nFlags; - drt.Format = Format; - drt.fPriority = fPriority; - drt.lplpStorage = pStorage; - drt.nCustomID = nCustomID; - drt.nPitch = nWidth * CTexture::BytesPerBlock(Format); - cry_strcpy(drt.szName, szName); - m_pRenderTargets.push_back(drt); -} - - -bool CHDRPostProcess::CreateRenderTargetList() -{ - std::sort(m_pRenderTargets.begin(), m_pRenderTargets.end(), RenderTargetSizeSort()); - - for (uint32 t = 0; t < m_pRenderTargets.size(); ++t) - { - SRenderTargetInfo& drt = m_pRenderTargets[t]; - CTexture* pTex = (*drt.lplpStorage); - if (!CTexture::IsTextureExist(pTex)) - { - pTex = CTexture::CreateRenderTarget(drt.szName, drt.nWidth, drt.nHeight, drt.cClearColor, eTT_2D, drt.nFlags, drt.Format, drt.nCustomID); - - if (pTex) - { - // Following will mess up don't care resolve/restore actions since Fill() sets textures to be cleared on next draw -#if !defined(CRY_USE_METAL) && !defined(OPENGL_ES) - pTex->Clear(); -#endif - (*drt.lplpStorage) = pTex; - } - } - else - { - pTex->SetFlags(drt.nFlags); - pTex->SetWidth(drt.nWidth); - pTex->SetHeight(drt.nHeight); - pTex->CreateRenderTarget(drt.Format, drt.cClearColor); - } - } - - m_pRenderTargets.clear(); - - return S_OK; -} - - -void CTexture::GenerateHDRMaps() -{ - int i; - char szName[256]; - - CD3D9Renderer* r = gcpRendD3D; - CHDRPostProcess* pHDRPostProcess = CHDRPostProcess::GetInstance(); - - r->m_dwHDRCropWidth = r->GetWidth(); - r->m_dwHDRCropHeight = r->GetHeight(); - - pHDRPostProcess->ClearRenderTargetList(); - - ETEX_Format nHDRFormat = eTF_R16G16B16A16F; // note: for main rendertarget R11G11B10 precision/range (even with rescaling) not enough for darks vs good blooming quality - - ETEX_Format nHDRReducedFormat = r->UseHalfFloatRenderTargets() ? eTF_R11G11B10F : eTF_R10G10B10A2; - - uint32 nHDRTargetFlags = FT_DONT_RELEASE | (CRenderer::CV_r_msaa ? FT_USAGE_MSAA : 0); - uint32 nHDRTargetFlagsUAV = nHDRTargetFlags | (CRenderer::CV_r_msaa ? 0 : FT_USAGE_UNORDERED_ACCESS); // UAV required for tiled deferred shading - - // GMEM render path uses CTexture::s_ptexSceneSpecularAccMap as the HDR Target - // It gets set in CDeferredShading::CreateDeferredMaps() - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, r->UseHalfFloatRenderTargets() ? nHDRFormat : nHDRReducedFormat, 1.0f, "$HDRTarget", &s_ptexHDRTarget, nHDRTargetFlagsUAV); - } - - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, nHDRReducedFormat, 1.0f, "$HDRTargetPrev", &s_ptexHDRTargetPrev); - - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, nHDRFormat, 1.0f, "$FurLightAcc", &s_ptexFurLightAcc, FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, eTF_R32G32B32A32F, 1.0f, "$FurPrepass", &s_ptexFurPrepass, FT_DONT_RELEASE); - - // Scaled versions of the HDR scene texture - uint32 nWeight = (r->m_dwHDRCropWidth >> 1); - uint32 nHeight = (r->m_dwHDRCropHeight >> 1); - - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaled0", &s_ptexHDRTargetScaled[0], FT_DONT_RELEASE); - - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTmp0", &s_ptexHDRTargetScaledTmp[0], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTempRT0", &s_ptexHDRTargetScaledTempRT[0], FT_DONT_RELEASE); - - nWeight = (r->m_dwHDRCropWidth >> 2); - nHeight = (r->m_dwHDRCropHeight >> 2); - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaled1", &s_ptexHDRTargetScaled[1], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTmp1", &s_ptexHDRTargetScaledTmp[1], FT_DONT_RELEASE); - - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTempRT1", &s_ptexHDRTargetScaledTempRT[1], 0); - - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, eTF_R11G11B10F, 0.9f, "$HDRTempBloom0", &s_ptexHDRTempBloom[0], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, eTF_R11G11B10F, 0.9f, "$HDRTempBloom1", &s_ptexHDRTempBloom[1], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(nWeight, nHeight, Clr_Unknown, eTF_R11G11B10F, 0.9f, "$HDRFinalBloom", &s_ptexHDRFinalBloom, FT_DONT_RELEASE); - - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 3), (r->m_dwHDRCropHeight >> 3), Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaled2", &s_ptexHDRTargetScaled[2], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 3), (r->m_dwHDRCropHeight >> 3), Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTempRT2", &s_ptexHDRTargetScaledTempRT[2], FT_DONT_RELEASE); - - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 4), (r->m_dwHDRCropHeight >> 4), Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaled3", &s_ptexHDRTargetScaled[3], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 4), (r->m_dwHDRCropHeight >> 4), Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTmp3", &s_ptexHDRTargetScaledTmp[3], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 4), (r->m_dwHDRCropHeight >> 4), Clr_Unknown, nHDRFormat, 0.9f, "$HDRTargetScaledTempRT3", &s_ptexHDRTargetScaledTempRT[3], FT_DONT_RELEASE); - for (i = 0; i < 8; i++) - { - sprintf_s(szName, "$HDRAdaptedLuminanceCur_%d", i); - pHDRPostProcess->AddRenderTarget(1, 1, Clr_Unknown, eTF_R16G16F, 0.1f, szName, &s_ptexHDRAdaptedLuminanceCur[i], FT_DONT_RELEASE); - } - - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, eTF_R11G11B10F, 1.0f, "$SceneTargetR11G11B10F_0", &s_ptexSceneTargetR11G11B10F[0], nHDRTargetFlagsUAV); - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, eTF_R11G11B10F, 1.0f, "$SceneTargetR11G11B10F_1", &s_ptexSceneTargetR11G11B10F[1], nHDRTargetFlags); - - pHDRPostProcess->AddRenderTarget(r->m_dwHDRCropWidth, r->m_dwHDRCropHeight, Clr_Unknown, eTF_R8G8B8A8, 0.1f, "$Velocity", &s_ptexVelocity, FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(20, r->m_dwHDRCropHeight, Clr_Unknown, eTF_R8G8B8A8, 0.1f, "$VelocityTilesTmp0", &s_ptexVelocityTiles[0], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(20, 20, Clr_Unknown, eTF_R8G8B8A8, 0.1f, "$VelocityTilesTmp1", &s_ptexVelocityTiles[1], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(20, 20, Clr_Transparent, eTF_R8G8B8A8, 0.1f, "$VelocityTiles", &s_ptexVelocityTiles[2], FT_DONT_RELEASE); - - ETEX_Format velocityObjectRenderTargetFormat = eTF_R16G16F; - pHDRPostProcess->AddRenderTarget(r->m_dwHDRCropWidth, r->m_dwHDRCropHeight, Clr_Transparent, velocityObjectRenderTargetFormat, 0.1f, "$VelocityObjects", &s_ptexVelocityObjects[0], FT_DONT_RELEASE); - if (gRenDev->m_bDualStereoSupport) - { - pHDRPostProcess->AddRenderTarget(r->m_dwHDRCropWidth, r->m_dwHDRCropHeight, Clr_Unknown, velocityObjectRenderTargetFormat, 0.1f, "$VelocityObject_R", &s_ptexVelocityObjects[1], FT_DONT_RELEASE); - } - - pHDRPostProcess->AddRenderTarget(r->GetWidth() >> 1, r->GetHeight() >> 1, Clr_Unknown, nHDRFormat, 0.9f, "$HDRDofLayerNear", &s_ptexHDRDofLayers[0], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(r->GetWidth() >> 1, r->GetHeight() >> 1, Clr_Unknown, nHDRFormat, 0.9f, "$HDRDofLayerFar", &s_ptexHDRDofLayers[1], FT_DONT_RELEASE); -#if METAL - pHDRPostProcess->AddRenderTarget(r->GetWidth() >> 1, r->GetHeight() >> 1, Clr_Unknown, eTF_R16F, 1.0f, "$MinCoC_0_Temp", &s_ptexSceneCoCTemp, FT_DONT_RELEASE); -#else - pHDRPostProcess->AddRenderTarget(r->GetWidth() >> 1, r->GetHeight() >> 1, Clr_Unknown, eTF_R16G16F, 1.0f, "$MinCoC_0_Temp", &s_ptexSceneCoCTemp, FT_DONT_RELEASE); -#endif - - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, eTF_R16G16F, 1.0, "$CoC_History0", &s_ptexSceneCoCHistory[0], FT_DONT_RELEASE); - pHDRPostProcess->AddRenderTarget(r->GetWidth(), r->GetHeight(), Clr_Unknown, eTF_R16G16F, 1.0, "$CoC_History1", &s_ptexSceneCoCHistory[1], FT_DONT_RELEASE); - - for (i = 0; i < MIN_DOF_COC_K; i++) - { - sprintf_s(szName, "$MinCoC_%d", i); -#if METAL - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 1) / (i + 1), (r->m_dwHDRCropHeight >> 1) / (i + 1), Clr_Unknown, eTF_R16F, 0.1f, szName, &s_ptexSceneCoC[i], FT_DONT_RELEASE, -1, true); -#else - pHDRPostProcess->AddRenderTarget((r->m_dwHDRCropWidth >> 1) / (i + 1), (r->m_dwHDRCropHeight >> 1) / (i + 1), Clr_Unknown, eTF_R16G16F, 0.1f, szName, &s_ptexSceneCoC[i], FT_DONT_RELEASE, -1, true); -#endif - } - - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - /* CONFETTI: David Srour - * Used during GMEM path for linear depth & stencil resolve. - * See following link for RT format storage sizes on Apple Metal HW: - * https://developer.apple.com/library/mac/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/MetalFeatureSetTables/MetalFeatureSetTables.html - */ - ETEX_Format format = eTF_R16G16F; -#if defined(OPENGL_ES) // might be no fp rendering support - if (!gcpRendD3D->UseHalfFloatRenderTargets()) - { - format = eTF_R16G16U; - } -#endif - pHDRPostProcess->AddRenderTarget(r->m_dwHDRCropWidth, r->m_dwHDRCropHeight, Clr_Unknown, format, 0.1f, - "$GmemStenLinDepth", &s_ptexGmemStenLinDepth, FT_DONT_RELEASE, -1, true); - } - - - // Luminance rt - for (i = 0; i < NUM_HDR_TONEMAP_TEXTURES; i++) - { - int iSampleLen = 1 << (2 * i); - sprintf_s(szName, "$HDRToneMap_%d", i); - pHDRPostProcess->AddRenderTarget(iSampleLen, iSampleLen, Clr_Dark, eTF_R16G16F, 0.7f, szName, &s_ptexHDRToneMaps[i], FT_DONT_RELEASE); - } - s_ptexHDRMeasuredLuminanceDummy = CTexture::CreateTextureObject("$HDRMeasuredLum_Dummy", 0, 0, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM, eTF_R16G16F, TO_HDR_MEASURED_LUMINANCE); - for (i = 0; i < MAX_GPU_NUM; ++i) - { - sprintf_s(szName, "$HDRMeasuredLum_%d", i); - - if (CRenderer::CV_r_EnableGMEMPostProcCS) - { - pHDRPostProcess->AddRenderTarget(1, 1, Clr_Unknown, eTF_R16G16F, 0.1f, szName, &s_ptexHDRMeasuredLuminance[i], FT_DONT_RELEASE | FT_DONT_STREAM); - } - else - { - s_ptexHDRMeasuredLuminance[i] = CTexture::Create2DTexture(szName, 1, 1, 0, FT_DONT_RELEASE | FT_DONT_STREAM, NULL, eTF_R16G16F, eTF_R16G16F); - } - } - - pHDRPostProcess->CreateRenderTargetList(); - - // Create resources if necessary - todo: refactor all this shared render targets stuff, quite cumbersome atm... - PostProcessUtils().Create(); -} - - -void CTexture::DestroyHDRMaps() -{ - int i; - - SAFE_RELEASE(s_ptexHDRTarget); - - SAFE_RELEASE(s_ptexHDRTargetPrev); - SAFE_RELEASE(s_ptexHDRTargetScaled[0]); - SAFE_RELEASE(s_ptexHDRTargetScaled[1]); - SAFE_RELEASE(s_ptexHDRTargetScaled[2]); - SAFE_RELEASE(s_ptexHDRTargetScaled[3]); - - SAFE_RELEASE(s_ptexHDRTargetScaledTmp[0]); - SAFE_RELEASE(s_ptexHDRTargetScaledTempRT[0]); - - SAFE_RELEASE(s_ptexHDRTargetScaledTmp[1]); - SAFE_RELEASE(s_ptexHDRTargetScaledTmp[3]); - - SAFE_RELEASE(s_ptexHDRTargetScaledTempRT[1]); - SAFE_RELEASE(s_ptexHDRTargetScaledTempRT[2]); - SAFE_RELEASE(s_ptexHDRTargetScaledTempRT[3]); - - SAFE_RELEASE(s_ptexHDRTempBloom[0]); - SAFE_RELEASE(s_ptexHDRTempBloom[1]); - SAFE_RELEASE(s_ptexHDRFinalBloom); - - - for (i = 0; i < 8; i++) - { - SAFE_RELEASE(s_ptexHDRAdaptedLuminanceCur[i]); - } - - for (i = 0; i < NUM_HDR_TONEMAP_TEXTURES; i++) - { - SAFE_RELEASE(s_ptexHDRToneMaps[i]); - } - SAFE_RELEASE(s_ptexHDRMeasuredLuminanceDummy); - for (i = 0; i < MAX_GPU_NUM; ++i) - { - SAFE_RELEASE(s_ptexHDRMeasuredLuminance[i]); - } - - CTexture::s_ptexCurLumTexture = NULL; - - SAFE_RELEASE(s_ptexVelocity); - SAFE_RELEASE(s_ptexVelocityTiles[0]); - SAFE_RELEASE(s_ptexVelocityTiles[1]); - SAFE_RELEASE(s_ptexVelocityTiles[2]); - SAFE_RELEASE(s_ptexVelocityObjects[0]); - SAFE_RELEASE(s_ptexVelocityObjects[1]); - - SAFE_RELEASE(s_ptexHDRDofLayers[0]); - SAFE_RELEASE(s_ptexHDRDofLayers[1]); - SAFE_RELEASE(s_ptexSceneCoCTemp); - for (i = 0; i < MIN_DOF_COC_K; i++) - { - SAFE_RELEASE(s_ptexSceneCoC[i]); - } -} - - -// deprecated -void DrawQuad3D(float s0, float t0, float s1, float t1) -{ - const float fZ = 0.5f; - const float fX0 = -1.0f, fX1 = 1.0f; - const float fY0 = 1.0f, fY1 = -1.0f; - - gcpRendD3D->DrawQuad3D(Vec3(fX0, fY1, fZ), Vec3(fX1, fY1, fZ), Vec3(fX1, fY0, fZ), Vec3(fX0, fY0, fZ), Col_White, s0, t0, s1, t1); -} - - -// deprecated -void DrawFullScreenQuadTR(float xpos, float ypos, float w, float h) -{ - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_C4B_T2F* vQuad = vb.Lock(); - - const DWORD col = ~0; - const float s0 = 0; - const float s1 = 1; - const float t0 = 1; - const float t1 = 0; - - // Define the quad - vQuad[0].xyz = Vec3(xpos, ypos, 1.0f); - vQuad[0].color.dcolor = col; - vQuad[0].st = Vec2(s0, 1.0f - t0); - - vQuad[1].xyz = Vec3(xpos + w, ypos, 1.0f); - vQuad[1].color.dcolor = col; - vQuad[1].st = Vec2(s1, 1.0f - t0); - - vQuad[3].xyz = Vec3(xpos + w, ypos + h, 1.0f); - vQuad[3].color.dcolor = col; - vQuad[3].st = Vec2(s1, 1.0f - t1); - - vQuad[2].xyz = Vec3(xpos, ypos + h, 1.0f); - vQuad[2].color.dcolor = col; - vQuad[2].st = Vec2(s0, 1.0f - t1); - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - gcpRendD3D->FX_Commit(); - - if (!FAILED(gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - gcpRendD3D->FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } -} - -#define NV_CACHE_OPTS_ENABLED TRUE - - -// deprecated -bool DrawFullScreenQuad(float fLeftU, float fTopV, float fRightU, float fBottomV, bool bClampToScreenRes) -{ - CD3D9Renderer* rd = gcpRendD3D; - - rd->FX_Commit(); - - // Acquire render target width and height - int nWidth = rd->m_NewViewport.nWidth; - int nHeight = rd->m_NewViewport.nHeight; - - // Ensure that we're directly mapping texels to pixels by offset by 0.5 - // For more info see the doc page titled "Directly Mapping Texels to Pixels" - if (bClampToScreenRes) - { - nWidth = min(nWidth, rd->GetWidth()); - nHeight = min(nHeight, rd->GetHeight()); - } - - float fWidth5 = static_cast(nWidth); - float fHeight5 = static_cast(nHeight); - fWidth5 = fWidth5 - 0.5f; - fHeight5 = fHeight5 - 0.5f; - - // Draw the quad - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_TP3F_C4B_T2F* Verts = vb.Lock(); - { - fTopV = 1 - fTopV; - fBottomV = 1 - fBottomV; - Verts[0].pos = Vec4(-0.5f, -0.5f, 0.0f, 1.0f); - Verts[0].color.dcolor = ~0; - Verts[0].st = Vec2(fLeftU, fTopV); - - Verts[1].pos = Vec4(fWidth5, -0.5f, 0.0f, 1.0f); - Verts[1].color.dcolor = ~0; - Verts[1].st = Vec2(fRightU, fTopV); - - Verts[2].pos = Vec4(-0.5f, fHeight5, 0.0f, 1.0f); - Verts[2].color.dcolor = ~0; - Verts[2].st = Vec2(fLeftU, fBottomV); - - Verts[3].pos = Vec4(fWidth5, fHeight5, 0.0f, 1.0f); - Verts[3].color.dcolor = ~0; - Verts[3].st = Vec2(fRightU, fBottomV); - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - rd->FX_SetState(GS_NODEPTHTEST); - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_TP3F_C4B_T2F))) - { - rd->FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - } - - return true; -} - - -// deprecated -bool DrawFullScreenQuad(CoordRect c, bool bClampToScreenRes) -{ - return DrawFullScreenQuad(c.fLeftU, c.fTopV, c.fRightU, c.fBottomV, bClampToScreenRes); -} - - -void GetSampleOffsets_DownScale4x4(uint32 nWidth, uint32 nHeight, Vec4 avSampleOffsets[]) -{ - float tU = 1.0f / static_cast(nWidth); - float tV = 1.0f / static_cast(nHeight); - - // Sample from the 16 surrounding points. Since the center point will be in - // the exact center of 16 texels, a 0.5f offset is needed to specify a texel - // center. - int index = 0; - for (int y = 0; y < 4; y++) - { - for (int x = 0; x < 4; x++) - { - avSampleOffsets[index].x = (x - 1.5f) * tU; - avSampleOffsets[index].y = (y - 1.5f) * tV; - avSampleOffsets[index].z = 0; - avSampleOffsets[index].w = 1; - - index++; - } - } -} - - -void GetSampleOffsets_DownScale4x4Bilinear(uint32 nWidth, uint32 nHeight, Vec4 avSampleOffsets[]) -{ - float tU = 1.0f / static_cast(nWidth); - float tV = 1.0f / static_cast(nHeight); - - // Sample from the 16 surrounding points. Since bilinear filtering is being used, specific the coordinate - // exactly halfway between the current texel center (k-1.5) and the neighboring texel center (k-0.5) - - int index = 0; - for (int y = 0; y < 4; y += 2) - { - for (int x = 0; x < 4; x += 2, index++) - { - avSampleOffsets[index].x = (x - 1.f) * tU; - avSampleOffsets[index].y = (y - 1.f) * tV; - avSampleOffsets[index].z = 0; - avSampleOffsets[index].w = 1; - } - } -} - - -void GetSampleOffsets_DownScale2x2(uint32 nWidth, uint32 nHeight, Vec4 avSampleOffsets[]) -{ - float tU = 1.0f / static_cast(nWidth); - float tV = 1.0f / static_cast(nHeight); - - // Sample from the 4 surrounding points. Since the center point will be in - // the exact center of 4 texels, a 0.5f offset is needed to specify a texel - // center. - int index = 0; - for (int y = 0; y < 2; y++) - { - for (int x = 0; x < 2; x++) - { - avSampleOffsets[index].x = (x - 0.5f) * tU; - avSampleOffsets[index].y = (y - 0.5f) * tV; - avSampleOffsets[index].z = 0; - avSampleOffsets[index].w = 1; - - index++; - } - } -} - - -void CHDRPostProcess::SetShaderParams() -{ - - Vec4 vHDRSetupParams[5]; - gEnv->p3DEngine->GetHDRSetupParams(vHDRSetupParams); - - static CCryNameR szHDREyeAdaptationParam("HDREyeAdaptation"); - m_shHDR->FXSetPSFloat(szHDREyeAdaptationParam, CRenderer::CV_r_HDREyeAdaptationMode == 2 ? &vHDRSetupParams[4] : &vHDRSetupParams[3], 1); - - // RGB Film curve setup - static CCryNameR szHDRFilmCurve("HDRFilmCurve"); - - const Vec4 vHDRFilmCurve = vHDRSetupParams[0]; //* Vec4(0.22f, 0.3f, 0.01f, 1.0f); - m_shHDR->FXSetPSFloat(szHDRFilmCurve, &vHDRFilmCurve, 1); - - static CCryNameR szHDRColorBalance("HDRColorBalance"); - const Vec4 vHDRColorBalance = vHDRSetupParams[2]; - m_shHDR->FXSetPSFloat(szHDRColorBalance, &vHDRColorBalance, 1); - - static CCryNameR szHDRBloomColor("HDRBloomColor"); - const Vec4 vHDRBloomColor = vHDRSetupParams[1] * Vec4(Vec3((1.0f / 8.0f)), 1.0f); // division by 8.0f was done in shader before, remove this at some point - m_shHDR->FXSetPSFloat(szHDRBloomColor, &vHDRBloomColor, 1); - - if (CRenderer::CV_r_ToneMapExposureType == static_cast(Exposuretype::Manual)) - { - static CCryNameR tonemapParams("HDRTonemapParams"); - Vec4 v = Vec4(CRenderer::CV_r_ToneMapManualExposureValue, 0, 0, 0); - m_shHDR->FXSetPSFloat(tonemapParams, &v, 1); - } -} - - -void CHDRPostProcess::SceneDownsampleUsingCompute() -{ - CTexture* pSrcRT = CTexture::s_ptexHDRTarget; - CTexture* pDstRTs[3] = - { - CTexture::s_ptexHDRTargetScaled[0], - CTexture::s_ptexHDRTargetScaled[1], - nullptr - }; - PostProcessUtils().DownsampleUsingCompute(pSrcRT, pDstRTs); -} - - -void CHDRPostProcess::HalfResDownsampleHDRTarget() -{ - PROFILE_LABEL_SCOPE("HALFRES_DOWNSAMPLE_HDRTARGET"); - - CTexture* pSrcRT = CTexture::s_ptexHDRTarget; - CTexture* pDstRT = CTexture::s_ptexHDRTargetScaled[0]; - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(true, 0, 0, gcpRendD3D->m_HalfResRect.right, gcpRendD3D->m_HalfResRect.bottom); -#endif - - if (CRenderer::CV_r_HDRBloomQuality >= 2) - { - PostProcessUtils().DownsampleStable(pSrcRT, pDstRT, true); - } - else - { - PostProcessUtils().StretchRect(pSrcRT, pDstRT, true); - } - -#ifdef CRY_USE_METAL - gRenDev->RT_SetScissor(false, 0, 0, 0, 0); -#endif -} - - -void CHDRPostProcess::QuarterResDownsampleHDRTarget() -{ - PROFILE_LABEL_SCOPE("QUARTER_RES_DOWNSAMPLE_HDRTARGET"); - - CTexture* pSrcRT = CTexture::s_ptexHDRTargetScaled[0]; - CTexture* pDstRT = CTexture::s_ptexHDRTargetScaled[1]; - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(true, 0, 0, (gcpRendD3D->m_HalfResRect.right + 1) >> 1, (gcpRendD3D->m_HalfResRect.bottom + 1) >> 1); -#endif - - // TODO: this pass seems redundant. Can we get rid of it in non-gmem paths too? - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - PostProcessUtils().DownsampleStable(pSrcRT, pDstRT, false); - } - - // Try to merge both sunshafts mask gen with the scene downsample on GMEM mobile path - CSunShafts* pSunShaftsTech = static_cast(PostEffectMgr()->GetEffect(ePFX_SunShafts)); - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr) && - CRenderer::CV_r_sunshafts && - CRenderer::CV_r_PostProcess && - pSunShaftsTech && - pSunShaftsTech->IsVisible()) - { - // It is important that the following texture remains untouched until the sunshafts passes right - // before tonemapping. At the moment, it doesn't look like any other passes make use of the RT. - // This RT also must match what is passed later on to CSunShafts::SunShaftsGen(...) - CTexture* pSunShaftsRT = CTexture::s_ptexBackBufferScaled[1]; - pSunShaftsTech->MergedSceneDownsampleAndSunShaftsMaskGen(pSrcRT, pDstRT, pSunShaftsRT); - } - else if (CRenderer::CV_r_HDRBloomQuality >= 2) - { - PostProcessUtils().DownsampleStable(pSrcRT, pDstRT, false); - } - else if (CRenderer::CV_r_HDRBloomQuality == 1) - { - PostProcessUtils().DownsampleStable(pSrcRT, pDstRT, true); - } - else - { - PostProcessUtils().StretchRect(pSrcRT, pDstRT); - } - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(false, 0, 0, 0, 0); -#endif -} - - -void CHDRPostProcess::MeasureLuminance() -{ - PROFILE_LABEL_SCOPE("MEASURE_LUMINANCE"); - int x, y, index; - Vec4 avSampleOffsets[16]; - CD3D9Renderer* rd = gcpRendD3D; - - uint64 nFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - if (CRenderer::CV_r_SlimGBuffer == 1) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - int32 dwCurTexture = NUM_HDR_TONEMAP_TEXTURES - 1; - static CCryNameR Param1Name("SampleOffsets"); - - float tU = 1.0f / (3.0f * CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetWidth()); - float tV = 1.0f / (3.0f * CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetHeight()); - - index = 0; - for (x = -1; x <= 1; x++) - { - for (y = -1; y <= 1; y++) - { - avSampleOffsets[index].x = x * tU; - avSampleOffsets[index].y = y * tV; - avSampleOffsets[index].z = 0; - avSampleOffsets[index].w = 1; - - index++; - } - } - - uint32 nPasses; - - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRToneMaps[dwCurTexture], NULL); - - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - - - rd->FX_SetActiveRenderTargets(); - rd->RT_SetViewport(0, 0, CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetWidth(), CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetHeight()); - - if (CRenderer::CV_r_HDREyeAdaptationMode == 2) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - else - { - CTexture::s_ptexSceneNormalsMap->Apply(1, nTexStateLinear); - CTexture::s_ptexSceneDiffuse->Apply(2, nTexStateLinear); - CTexture::s_ptexSceneSpecular->Apply(3, nTexStateLinear); - } - - static CCryNameTSCRC TechName("HDRSampleLumInitial"); - m_shHDR->FXSetTechnique(TechName); - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_shHDR->FXBeginPass(0); - - CTexture::s_ptexHDRTargetScaled[1]->Apply(0, nTexStateLinear); - - - - float s1 = 1.0f / static_cast(CTexture::s_ptexHDRTargetScaled[1]->GetWidth()); - float t1 = 1.0f / static_cast(CTexture::s_ptexHDRTargetScaled[1]->GetHeight()); - - // Use rotated grid - Vec4 vSampleLumOffsets0 = Vec4(s1 * 0.95f, t1 * 0.25f, -s1 * 0.25f, t1 * 0.96f); - Vec4 vSampleLumOffsets1 = Vec4(-s1 * 0.96f, -t1 * 0.25f, s1 * 0.25f, -t1 * 0.96f); - - static CCryNameR pSampleLumOffsetsName0("SampleLumOffsets0"); - static CCryNameR pSampleLumOffsetsName1("SampleLumOffsets1"); - - m_shHDR->FXSetPSFloat(pSampleLumOffsetsName0, &vSampleLumOffsets0, 1); - m_shHDR->FXSetPSFloat(pSampleLumOffsetsName1, &vSampleLumOffsets1, 1); - - SetShaderParams(); - - bool ret = DrawFullScreenQuad(0.0f, 1.0f - 1.0f * gcpRendD3D->m_CurViewportScale.y, 1.0f * gcpRendD3D->m_CurViewportScale.x, 1.0f); - - // important that we always write out valid luminance, even if quad draw fails - if (!ret) - { - rd->FX_ClearTarget(CTexture::s_ptexHDRToneMaps[dwCurTexture], Clr_Dark); - } - - m_shHDR->FXEndPass(); - - rd->FX_PopRenderTarget(0); - - dwCurTexture--; - - // Initialize the sample offsets for the iterative luminance passes - while (dwCurTexture >= 0) - { - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRToneMaps[dwCurTexture], NULL); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - // CONFETTI END - - rd->RT_SetViewport(0, 0, CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetWidth(), CTexture::s_ptexHDRToneMaps[dwCurTexture]->GetHeight()); - - if (!dwCurTexture) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - if (dwCurTexture == 1) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - static CCryNameTSCRC TechNameLI("HDRSampleLumIterative"); - m_shHDR->FXSetTechnique(TechNameLI); - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_shHDR->FXBeginPass(0); - - GetSampleOffsets_DownScale4x4Bilinear(CTexture::s_ptexHDRToneMaps[dwCurTexture + 1]->GetWidth(), CTexture::s_ptexHDRToneMaps[dwCurTexture + 1]->GetHeight(), avSampleOffsets); - m_shHDR->FXSetPSFloat(Param1Name, avSampleOffsets, 4); - CTexture::s_ptexHDRToneMaps[dwCurTexture + 1]->Apply(0, nTexStateLinear); - - // Draw a fullscreen quad to sample the RT - ret = DrawFullScreenQuad(0.0f, 0.0f, 1.0f, 1.0f); - - // important that we always write out valid luminance, even if quad draw fails - if (!ret) - { - rd->FX_ClearTarget(CTexture::s_ptexHDRToneMaps[dwCurTexture], Clr_Dark); - } - - m_shHDR->FXEndPass(); - - rd->FX_PopRenderTarget(0); - - dwCurTexture--; - } - - gcpRendD3D->GetDeviceContext().CopyResource( - CTexture::s_ptexHDRMeasuredLuminance[gcpRendD3D->RT_GetCurrGpuID()]->GetDevTexture()->GetBaseTexture(), - CTexture::s_ptexHDRToneMaps[0]->GetDevTexture()->GetBaseTexture()); - - gRenDev->m_RP.m_FlagsShader_RT = nFlagsShader_RT; -} - -void CHDRPostProcess::EyeAdaptation() -{ - PROFILE_LABEL_SCOPE("EYEADAPTATION"); - - CD3D9Renderer* rd = gcpRendD3D; - - // Swap current & last luminance - const int32 lumMask = static_cast((sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur) / sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur[0]))) - 1; - const int32 numTextures = static_cast(max(min(gRenDev->GetActiveGPUCount(), static_cast(sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur) / sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur[0]))), 1u)); - - CTexture::s_nCurLumTextureIndex++; - - CTexture* pTexPrev = CTexture::s_ptexHDRAdaptedLuminanceCur[(CTexture::s_nCurLumTextureIndex - numTextures) & lumMask]; - CTexture* pTexCur = CTexture::s_ptexHDRAdaptedLuminanceCur[CTexture::s_nCurLumTextureIndex & lumMask]; - CTexture::s_ptexCurLumTexture = pTexCur; - CRY_ASSERT(pTexCur); - - uint32 nPasses; - static CCryNameTSCRC TechName("HDRCalculateAdaptedLum"); - m_shHDR->FXSetTechnique(TechName); - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - rd->FX_PushRenderTarget(0, pTexCur, NULL); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - // CONFETTI END - - rd->RT_SetViewport(0, 0, pTexCur->GetWidth(), pTexCur->GetHeight()); - - m_shHDR->FXBeginPass(0); - - SetShaderParams(); - - static CCryNameR Param1Name("ElapsedTime"); - - { - Vec4 elapsedTime; - elapsedTime[0] = iTimer->GetFrameTime() * numTextures; - elapsedTime[1] = 1.0f - expf(-CRenderer::CV_r_HDREyeAdaptationSpeed * elapsedTime[0]); - elapsedTime[2] = 0; - elapsedTime[3] = 0; - - if (rd->GetCamera().IsJustActivated() || rd->m_nDisableTemporalEffects > 0) - { - elapsedTime[1] = 1.0f; - elapsedTime[2] = 1.0f; - } - - m_shHDR->FXSetPSFloat(Param1Name, &elapsedTime, 1); - } - - pTexPrev->Apply(0, nTexStatePoint); - CTexture::s_ptexHDRToneMaps[0]->Apply(1, nTexStatePoint); - - // Draw a fullscreen quad to sample the RT - DrawFullScreenQuad(0.0f, 0.0f, 1.0f, 1.0f); - - - m_shHDR->FXEndPass(); - - rd->FX_PopRenderTarget(0); -} - - -void CHDRPostProcess::MeasureLumEyeAdaptationUsingCompute() -{ - PROFILE_LABEL_SCOPE("MEASURE_LUM_EYE_ADAPT_CS"); - PROFILE_SHADER_SCOPE; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - // Constants used by CS shaders - float hdrTargetWidth = static_cast(CTexture::s_ptexHDRTargetScaled[1]->GetWidth()); - float hdrTargetHeight = static_cast(CTexture::s_ptexHDRTargetScaled[1]->GetHeight()); - - int lumStartingWidth = CTexture::s_ptexHDRToneMaps[NUM_HDR_TONEMAP_TEXTURES - 1]->GetWidth(); - int lumStartingHeight = CTexture::s_ptexHDRToneMaps[NUM_HDR_TONEMAP_TEXTURES - 1]->GetHeight(); - - Vec4 vHdrTargetLumStartDims = Vec4(hdrTargetWidth, hdrTargetHeight, static_cast(lumStartingWidth), static_cast(lumStartingHeight)); - - Vec4 vGBufferDims = Vec4(static_cast(CTexture::s_ptexSceneDiffuse->GetWidth()), static_cast(CTexture::s_ptexSceneDiffuse->GetHeight()), 0, 0); - - const int lumMask = static_cast((sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur) / sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur[0]))) - 1; - const int32 numTextures = static_cast(max(min(gRenDev->GetActiveGPUCount(), static_cast(sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur) / sizeof(CTexture::s_ptexHDRAdaptedLuminanceCur[0]))), 1u)); - - static CCryNameR pParamTimeName("ElapsedTime"); - static CCryNameR pHdrTargetLumStartDimsName("HdrTargetAndLumStartingDims"); - static CCryNameR pGbufferDimsName("GBufferDims"); - - static CCryNameTSCRC pTech("MeasureLuminanceCS"); - - uint32 nPasses; - m_shHDR->FXSetTechnique(pTech); - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DShaderResourceView* pSRV[3]; - D3DUnorderedAccessView* pUAV[3]; - - // Grid dims must match in shader - const uint32 kernelGridX = 8; - const uint32 kernelGridY = 8; - - uint32 dispatchSizeX, dispatchSizeY; - - // Parallel reduction pass - m_shHDR->FXBeginPass(0); - - - m_shHDR->FXSetCSFloat(pHdrTargetLumStartDimsName, &vHdrTargetLumStartDims, 1); - m_shHDR->FXSetCSFloat(pGbufferDimsName, &vGBufferDims, 1); - - rd->FX_Commit(); - - // SRVs - pSRV[0] = (CTexture::s_ptexHDRTargetScaled[1]->GetShaderResourceView()); - pSRV[1] = (CTexture::s_ptexSceneDiffuse->GetShaderResourceView()); - pSRV[2] = (CTexture::s_ptexSceneSpecular->GetShaderResourceView()); - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRV, 0, 3); - - // UAVs - // We can reuse CTexture::s_ptexHDRToneMaps[2] (16x16) to store the last parallel reduction data (64 pixels required) - // Note that this will potentially need to be changed if NUM_HDR_TONEMAP_TEXTURES changes in the future. - pUAV[0] = (CTexture::s_ptexHDRToneMaps[2]->GetDeviceUAV()); - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 1, pUAV, NULL); - - dispatchSizeX = lumStartingWidth / kernelGridX + (lumStartingWidth % kernelGridX > 0 ? 1 : 0); - dispatchSizeY = lumStartingHeight / kernelGridY + (lumStartingHeight % kernelGridY > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - - m_shHDR->FXEndPass(); - - // Final reduction and eye adaptation pass - m_shHDR->FXBeginPass(1); - - m_shHDR->FXSetCSFloat(pHdrTargetLumStartDimsName, &vHdrTargetLumStartDims, 1); - - { - Vec4 elapsedTime; - elapsedTime[0] = iTimer->GetFrameTime() * numTextures; - elapsedTime[1] = 1.0f - expf(-CRenderer::CV_r_HDREyeAdaptationSpeed * elapsedTime[0]); - elapsedTime[2] = 0; - elapsedTime[3] = 0; - - if (rd->GetCamera().IsJustActivated() || rd->m_nDisableTemporalEffects > 0) - { - elapsedTime[1] = 1.0f; - elapsedTime[2] = 1.0f; - } - - m_shHDR->FXSetCSFloat(pParamTimeName, &elapsedTime, 1); - } - - // Swap current & last luminance - CTexture::s_nCurLumTextureIndex++; - CTexture* pTexPrev = CTexture::s_ptexHDRAdaptedLuminanceCur[(CTexture::s_nCurLumTextureIndex - numTextures) & lumMask]; - CTexture* pTexCur = CTexture::s_ptexHDRAdaptedLuminanceCur[CTexture::s_nCurLumTextureIndex & lumMask]; - CTexture::s_ptexCurLumTexture = pTexCur; - CRY_ASSERT(pTexCur); - - // SRVs - pSRV[0] = (CTexture::s_ptexHDRToneMaps[2]->GetShaderResourceView()); - pSRV[1] = (pTexPrev->GetShaderResourceView()); - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRV, 0, 2); - - // UAVs - pUAV[0] = (CTexture::s_ptexHDRMeasuredLuminance[gcpRendD3D->RT_GetCurrGpuID()]->GetDeviceUAV()); - pUAV[1] = (CTexture::s_ptexHDRToneMaps[0]->GetDeviceUAV()); - pUAV[2] = (pTexCur->GetDeviceUAV()); - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 3, pUAV, NULL); - - dispatchSizeX = lumStartingWidth / (kernelGridX * kernelGridY); - dispatchSizeY = lumStartingHeight / (kernelGridX * kernelGridY); - CRY_ASSERT(1 == dispatchSizeX && 1 == dispatchSizeY); - - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - - m_shHDR->FXEndPass(); - - rd->FX_Commit(); -} - -void CHDRPostProcess::BloomGeneration() -{ - if (CRenderer::CV_r_GraphicsPipeline & 1) - { - gcpRendD3D->GetGraphicsPipeline().RenderBloom(); - return; - } - - // Approximate function (1 - r)^4 by a sum of Gaussians: 0.0174*G(0.008,r) + 0.192*G(0.0576,r) - const float sigma1 = sqrtf(0.008f); - const float sigma2 = sqrtf(0.0576f - 0.008f); - - PROFILE_LABEL_SCOPE("BLOOM_GEN"); - - CD3D9Renderer* rd = gcpRendD3D; - static CCryNameTSCRC TechName("HDRBloomGaussian"); - static CCryNameR szHDRParam0("HDRParams0"); - - uint64 nPrevFlagsShaderRT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0]); - - int width = CTexture::s_ptexHDRFinalBloom->GetWidth(); - int height = CTexture::s_ptexHDRFinalBloom->GetHeight(); - - // Note: Just scaling the sampling offsets depending on the resolution is not very accurate but works acceptably - CRY_ASSERT(CTexture::s_ptexHDRFinalBloom->GetWidth() == CTexture::s_ptexHDRTarget->GetWidth() / 4); - float scaleW = (static_cast(width) / 400.0f) / static_cast(width); - float scaleH = (static_cast(height) / 225.0f) / static_cast(height); - int32 texFilter = (CTexture::s_ptexHDRFinalBloom->GetWidth() == 400 && CTexture::s_ptexHDRFinalBloom->GetHeight() == 225) ? nTexStatePoint : nTexStateLinear; - - rd->FX_SetState(GS_NODEPTHTEST); - rd->RT_SetViewport(0, 0, width, height); - - // Pass 1 Horizontal - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRTempBloom[1], NULL); - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - SD3DPostEffectsUtils::ShBeginPass(m_shHDR, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - Vec4 v = Vec4(scaleW, 0, 0, 0); - m_shHDR->FXSetPSFloat(szHDRParam0, &v, 1); - CTexture::s_ptexHDRTargetScaled[1]->Apply(0, texFilter); - SPostEffectsUtils::DrawFullScreenTri(width, height); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - - // Pass 1 Vertical - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRFinalBloom, NULL); - } - else - { - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRTempBloom[0], NULL); - } - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - SD3DPostEffectsUtils::ShBeginPass(m_shHDR, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - v = Vec4(0, scaleH, 0, 0); - m_shHDR->FXSetPSFloat(szHDRParam0, &v, 1); - CTexture::s_ptexHDRTempBloom[1]->Apply(0, texFilter); - SPostEffectsUtils::DrawFullScreenTri(width, height); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - - // For mobile we skip the second blur pass for performance reasons - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Pass 2 Horizontal - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRTempBloom[1], NULL); - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - SD3DPostEffectsUtils::ShBeginPass(m_shHDR, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - v = Vec4((sigma2 / sigma1) * scaleW, 0, 0, 0); - m_shHDR->FXSetPSFloat(szHDRParam0, &v, 1); - CTexture::s_ptexHDRTempBloom[0]->Apply(0, texFilter); - SPostEffectsUtils::DrawFullScreenTri(width, height); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - - // Pass 2 Vertical - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - rd->FX_PushRenderTarget(0, CTexture::s_ptexHDRFinalBloom, NULL); - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - SD3DPostEffectsUtils::ShBeginPass(m_shHDR, TechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - v = Vec4(0, (sigma2 / sigma1) * scaleH, 0, 0); - m_shHDR->FXSetPSFloat(szHDRParam0, &v, 1); - CTexture::s_ptexHDRTempBloom[1]->Apply(0, texFilter); - CTexture::s_ptexHDRTempBloom[0]->Apply(1, texFilter); - SPostEffectsUtils::DrawFullScreenTri(width, height); - SD3DPostEffectsUtils::ShEndPass(); - rd->FX_PopRenderTarget(0); - } - - rd->m_RP.m_FlagsShader_RT = nPrevFlagsShaderRT; -} - -void CHDRPostProcess::ProcessLensOptics() -{ - gcpRendD3D->m_RP.m_PersFlags2 &= ~RBPF2_LENS_OPTICS_COMPOSITE; - if (CRenderer::CV_r_flares && CRenderer::CV_r_PostProcess) - { - const uint32 nBatchMask = SRendItem::BatchFlags(EFSLIST_LENSOPTICS, gcpRendD3D->m_RP.m_pRLD); - if (nBatchMask & (FB_GENERAL | FB_TRANSPARENT)) - { - PROFILE_LABEL_SCOPE("LENS_OPTICS"); - - CTexture* pLensOpticsComposite = CTexture::s_ptexBackBufferScaledTemp[0]; - pLensOpticsComposite = CTexture::s_ptexSceneTargetR11G11B10F[0]; - - gcpRendD3D->FX_PushRenderTarget(0, pLensOpticsComposite, 0); - gcpRendD3D->FX_SetColorDontCareActions(0, false, false); - gcpRendD3D->FX_ClearTarget(pLensOpticsComposite, Clr_Transparent); - - gcpRendD3D->m_RP.m_PersFlags2 |= RBPF2_NOPOSTAA; - - GetUtils().Log(" +++ Begin lens-optics scene +++ \n"); - gcpRendD3D->FX_ProcessRenderList(EFSLIST_LENSOPTICS, FB_GENERAL); - gcpRendD3D->FX_ProcessRenderList(EFSLIST_LENSOPTICS, FB_TRANSPARENT); - gcpRendD3D->FX_ResetPipe(); - GetUtils().Log(" +++ End lens-optics scene +++ \n"); - - gcpRendD3D->FX_SetActiveRenderTargets(); - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->FX_SetActiveRenderTargets(); - } - } -} - -enum class eHDRPostProcessSRVs : int -{ - HDRInput = 0, - Luminance = 1, - Bloom = 2, - Velocity = 3, - ZTarget = 5, - VignetteMap = 7, - ColorChar = 8, - SunShafts = 9, - DolbyVisionDynamicMeta = 15 -}; - -void CHDRPostProcess::ToneMapping() -{ - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - if (!gcpRendD3D->m_pColorGradingControllerD3D) - { - return; - } - - CSunShafts* pSunShaftsTech = static_cast(PostEffectMgr()->GetEffect(ePFX_SunShafts)); - - CTexture* pSunShaftsRT = CTextureManager::Instance()->GetBlackTexture(); - if (CRenderer::CV_r_sunshafts && CRenderer::CV_r_PostProcess && pSunShaftsTech && pSunShaftsTech->IsVisible()) - { - // Create shafts mask texture - - uint32 nWidth = CTexture::s_ptexBackBufferScaled[1]->GetWidth(); - uint32 nHeight = CTexture::s_ptexBackBufferScaled[1]->GetHeight(); - pSunShaftsRT = CTexture::s_ptexBackBufferScaled[1]; - CTexture* pSunShaftsPingPongRT = CTexture::s_ptexBackBufferScaledTemp[1]; - if (rRP.m_eQuality >= eRQ_High && - !gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) // GMEM always uses the downsampled target - { - pSunShaftsRT = CTexture::s_ptexBackBufferScaled[0]; - pSunShaftsPingPongRT = CTexture::s_ptexBackBufferScaledTemp[0]; - nWidth = CTexture::s_ptexBackBufferScaled[0]->GetWidth(); - nHeight = CTexture::s_ptexBackBufferScaled[0]->GetHeight(); - } - - pSunShaftsTech->SunShaftsGen(pSunShaftsRT, pSunShaftsPingPongRT); - } - - // Update color grading - - bool bColorGrading = false; - - SColorGradingMergeParams pMergeParams; - if (CRenderer::CV_r_colorgrading && CRenderer::CV_r_colorgrading_charts) - { - CColorGrading* pColorGrad = 0; - if (!PostEffectMgr()->GetEffects().empty()) - { - pColorGrad = static_cast(PostEffectMgr()->GetEffect(ePFX_ColorGrading)); - } - - if (pColorGrad && pColorGrad->UpdateParams(pMergeParams)) - { - bColorGrading = true; - } - } - - CColorGradingControllerD3D* pCtrl = gcpRendD3D->m_pColorGradingControllerD3D; - CTexture* pTexColorChar = pCtrl ? pCtrl->GetColorChart() : 0; - - rd->RT_SetViewport(0, 0, CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight()); - - PROFILE_LABEL_SCOPE("TONEMAPPING"); - - // Enable corresponding shader variation - rRP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - if (CRenderer::CV_r_HDREyeAdaptationMode == 2) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - SetExposureTypeShaderFlags(); - - if (bColorGrading && pTexColorChar) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - if (CRenderer::CV_r_HDRDebug == 5) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - } - - const uint32 nAAMode = rd->FX_GetAntialiasingType(); - if (nAAMode & eAT_FXAA_MASK) - { - rRP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - PostProcessUtils().SetSRGBShaderFlags(); - - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetStencilDontCareActions(0, true, true); - rd->FX_SetColorDontCareActions(1, true, false); - rd->FX_SetStencilDontCareActions(1, true, true); - - - bool isAfterPostProcessBucketEmpty = SRendItem::IsListEmpty(EFSLIST_AFTER_POSTPROCESS, rd->m_RP.m_nProcessThreadID, rd->m_RP.m_pRLD); - - bool isAuxGeomEnabled = false; -#if defined(ENABLE_RENDER_AUX_GEOM) - isAuxGeomEnabled = CRenderer::CV_r_enableauxgeom == 1; -#endif - - //We may need to preserve the depth buffer in case there is something to render in the EFSLIST_AFTER_POSTPROCESS bucket. - //It could be UI in the 3d world. If the bucket is empty ignore the depth buffer as it is not needed. - //Also check if Auxgeom rendering is enabled in which case we preserve depth buffer. - if (isAfterPostProcessBucketEmpty && !isAuxGeomEnabled) - { - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetDepthDontCareActions(1, true, true); - } - else - { - rd->FX_SetDepthDontCareActions(0, false, false); - rd->FX_SetDepthDontCareActions(1, false, false); - } - - // Final bloom RT - - // Noise offset was originally defined before VS parameter: "FrameRand" - algorithm untouched from original CryEngine implementation. - // Was moved to this location because for multi-pass the noise offset needs to be the same or there will be a mismatch. - - static uint32 dwNoiseOffsetX = 0; - static uint32 dwNoiseOffsetY = 0; - dwNoiseOffsetX = (dwNoiseOffsetX + 27) & 0x3f; - dwNoiseOffsetY = (dwNoiseOffsetY + 19) & 0x3f; - - Vec4 pFrameRand( - dwNoiseOffsetX / 64.0f, - dwNoiseOffsetX / 64.0f, - cry_random(0, 1023) / 1024.0f, - cry_random(0, 1023) / 1024.0f); - - static ICVar* DolbyCvar = gEnv->pConsole->GetCVar("r_HDRDolby"); - int DolbyCvarValue = DolbyCvar ? DolbyCvar->GetIVal() : eDVM_Disabled; - - // Calculate dynamic metadata for Dolby vision if enabled. - if (DolbyCvarValue == eDVM_Vision && CRenderer::CV_r_HDRDolbyDynamicMetadata == 1) - { - CalculateDolbyDynamicMetadata(pSunShaftsRT); - } - - { - CTexture* pBloom = CTextureManager::Instance()->GetBlackTexture(); - if (CRenderer::CV_r_HDRBloom && CRenderer::CV_r_PostProcess) - { - pBloom = CTexture::s_ptexHDRFinalBloom; - } - - PREFAST_ASSUME(pBloom); - CRY_ASSERT(pBloom); - - uint32 nPasses; - static CCryNameTSCRC TechFinalName("HDRFinalPass"); - static CCryNameTSCRC TechFinalDolbyName("HDRFinalPassDolby"); - switch (DolbyCvarValue) - { - case eDVM_Disabled: - m_shHDR->FXSetTechnique(GetTonemapTechnique()); - break; - case eDVM_RGBPQ: - case eDVM_Vision: - m_shHDR->FXSetTechnique(TechFinalDolbyName); - break; - } - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_shHDR->FXBeginPass(0); - - gcpRendD3D->FX_SetState(GS_NODEPTHTEST); - - SetShaderParams(); - - // If any dolby output mode has been enabled, set required uniforms. - if (DolbyCvarValue >= eDVM_RGBPQ) - { - static CCryNameR pszHDRDolbyParam0("HDRDolbyScurveParams0"); - static CCryNameR pszHDRDolbyParam1("HDRDolbyScurveParams1"); - static CCryNameR pszHDRDolbyParam2("HDRDolbyScurveParams2"); - - Vec4 vHDRDolbyParam0(CRenderer::CV_r_HDRDolbyScurve ? 1.0f : 0.0f, CRenderer::CV_r_HDRDolbyScurveSourceMin, CRenderer::CV_r_HDRDolbyScurveSourceMid, CRenderer::CV_r_HDRDolbyScurveSourceMax); - Vec4 vHDRDolbyParam1(CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMin, CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMid, CRenderer::CV_r_HDRDolbyScurveRGBPQTargetMax, CRenderer::CV_r_HDRDolbyScurveSlope); - Vec4 vHDRDolbyParam2(CRenderer::CV_r_HDRDolbyDynamicMetadata ? 1.0f : 0.0f, 0.0f, 0.0f, CRenderer::CV_r_HDRDolbyScurveScale); - if (DolbyCvarValue == eDVM_Vision) - { - vHDRDolbyParam1.x = CRenderer::CV_r_HDRDolbyScurveVisionTargetMin; - vHDRDolbyParam1.y = CRenderer::CV_r_HDRDolbyScurveVisionTargetMid; - vHDRDolbyParam1.z = CRenderer::CV_r_HDRDolbyScurveVisionTargetMax; - } - - m_shHDR->FXSetPSFloat(pszHDRDolbyParam0, &vHDRDolbyParam0, 1); - m_shHDR->FXSetPSFloat(pszHDRDolbyParam1, &vHDRDolbyParam1, 1); - m_shHDR->FXSetPSFloat(pszHDRDolbyParam2, &vHDRDolbyParam2, 1); - } - - static CCryNameR pSunShaftsParamSName("SunShafts_SunCol"); - Vec4 pShaftsSunCol(0, 0, 0, 0); - if (pSunShaftsRT) - { - Vec4 pSunShaftsParams[2]; - pSunShaftsTech->GetSunShaftsParams(pSunShaftsParams); - Vec3 pSunColor = gEnv->p3DEngine->GetSunColor(); - pSunColor.Normalize(); - pSunColor.SetLerp(Vec3(pSunShaftsParams[0].x, pSunShaftsParams[0].y, pSunShaftsParams[0].z), pSunColor, pSunShaftsParams[1].w); - - pShaftsSunCol = Vec4(pSunColor * pSunShaftsParams[1].z, 1); - } - - m_shHDR->FXSetPSFloat(pSunShaftsParamSName, &pShaftsSunCol, 1); - - // Force commit before setting samplers - workaround for per frame samplers hardcoded/overriding sampler slots. - rd->FX_Commit(); - - CTexture::s_ptexHDRTarget->Apply(static_cast(eHDRPostProcessSRVs::HDRInput), nTexStateLinear, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - - if (CTexture::s_ptexCurLumTexture) - { - if (!gRenDev->m_CurViewportID) - { - CTexture::s_ptexCurLumTexture->Apply(static_cast(eHDRPostProcessSRVs::Luminance), nTexStateLinear /*nTexStatePoint*/); - } - else - { - CTexture::s_ptexHDRToneMaps[0]->Apply(static_cast(eHDRPostProcessSRVs::Luminance), nTexStateLinear); - } - } - - pBloom->Apply(static_cast(eHDRPostProcessSRVs::Bloom), nTexStateLinear); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - CTexture::s_ptexVelocity->Apply(static_cast(eHDRPostProcessSRVs::Velocity), nTexStatePoint); - } - else - { - CTexture::s_ptexZTarget->Apply(static_cast(eHDRPostProcessSRVs::ZTarget), nTexStatePoint); - } - - AZ_PUSH_DISABLE_WARNING(, "-Wconstant-logical-operand") - if (CRenderer::CV_r_PostProcess && CRenderer::CV_r_HDRVignetting) - AZ_POP_DISABLE_WARNING - { - CTextureManager::Instance()->GetDefaultTexture("VignettingMap")->Apply(static_cast(eHDRPostProcessSRVs::VignetteMap), nTexStateLinear); - } - else - { - CTexture* pWhite = CTextureManager::Instance()->GetWhiteTexture(); - pWhite->Apply(static_cast(eHDRPostProcessSRVs::VignetteMap), nTexStateLinear); - } - - if (pTexColorChar) - { - pTexColorChar->Apply(static_cast(eHDRPostProcessSRVs::ColorChar), nTexStateLinear); - } - - if (pSunShaftsRT) - { - pSunShaftsRT->Apply(static_cast(eHDRPostProcessSRVs::SunShafts), nTexStateLinear); - } - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight()); - } - - // Reset don't care actions for UI and other passes after post-proc pipeline - rd->FX_SetColorDontCareActions(0, false, false); -} - -void CHDRPostProcess::EncodeDolbyVision(CTexture* source) -{ - CD3D9Renderer* rd = gcpRendD3D; - int NumPasses = 2; - - for (int pass = 0; pass < NumPasses; pass++) - { - uint32 nPasses; - static CCryNameTSCRC TechFinalDolbyVisionName("HDRFinalPassDolbyVision"); - static CCryNameTSCRC TechFinalDolbyVisionNoMetadataName("HDRFinalPassDolbyVisionNoMetadata"); - - if (pass == 0) - { - m_shHDR->FXSetTechnique(TechFinalDolbyVisionName); - } - else if (pass == 1) - { - m_shHDR->FXSetTechnique(TechFinalDolbyVisionNoMetadataName); - } - - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_shHDR->FXBeginPass(0); - - gcpRendD3D->FX_SetState(GS_NODEPTHTEST); - - // Set all shader params - SetShaderParams(); - - // If any dolby output mode has been enabled, set required uniforms. - { - - static CCryNameR pszHDRDolbyParam0("HDRDolbyScurveParams0"); - static CCryNameR pszHDRDolbyParam1("HDRDolbyScurveParams1"); - static CCryNameR pszHDRDolbyParam2("HDRDolbyScurveParams2"); - - Vec4 vHDRDolbyParam0(CRenderer::CV_r_HDRDolbyScurve ? 1.0f : 0.0f, CRenderer::CV_r_HDRDolbyScurveSourceMin, CRenderer::CV_r_HDRDolbyScurveSourceMid, CRenderer::CV_r_HDRDolbyScurveSourceMax); - Vec4 vHDRDolbyParam1(CRenderer::CV_r_HDRDolbyScurveVisionTargetMin, CRenderer::CV_r_HDRDolbyScurveVisionTargetMid, CRenderer::CV_r_HDRDolbyScurveVisionTargetMax, CRenderer::CV_r_HDRDolbyScurveSlope); - Vec4 vHDRDolbyParam2(CRenderer::CV_r_HDRDolbyDynamicMetadata ? 1.0f : 0.0f, 0.0, 0.0, CRenderer::CV_r_HDRDolbyScurveScale); - - m_shHDR->FXSetPSFloat(pszHDRDolbyParam0, &vHDRDolbyParam0, 1); - m_shHDR->FXSetPSFloat(pszHDRDolbyParam1, &vHDRDolbyParam1, 1); - m_shHDR->FXSetPSFloat(pszHDRDolbyParam2, &vHDRDolbyParam2, 1); - } - - // Force commit before setting samplers - workaround for per frame samplers hardcoded/overriding sampler slots. - rd->FX_Commit(); - - SResourceView::KeyType nResourceID = SResourceView::DefaultView; - - source->Apply(static_cast(eHDRPostProcessSRVs::HDRInput), nTexStateLinear, EFTT_UNKNOWN, -1, nResourceID); - - // Provide dynamic metadata values to the shader if enabled. - if (CRenderer::CV_r_HDRDolbyDynamicMetadata == 1) - { - rd->m_DevMan.BindSRV(eHWSC_Pixel, m_bufDolbyMetadataMinMaxMid.GetShaderResourceView(), static_cast(eHDRPostProcessSRVs::DolbyVisionDynamicMeta)); - } - - { - // Dolby Vision split rendering (metadata/non-metadata). - - // * Calculate split boundaries. - // Metadata needs 128 bytes * 3 times (according to dolby 3x repeater spec). - // Every pixel stores 1 bit so at least 3072 pixels are needed to store the metadata. 4000 is a safe margin above that value. - float pixelsNeeded = 4000.0f; - float rowsNeeded = pixelsNeeded / rd->GetBackbufferWidth(); - float pixelRows = ceil(rowsNeeded); - float pixelRowsNormalized = pixelRows / rd->GetBackbufferHeight(); - - // * Draw split quad. - Vec2 srcLeftTop(0.0f, 0.0f), srcRightBottom(1.0f, 1.0f); - if (pass == 0) - { - srcRightBottom.y = pixelRowsNormalized; // Draw top half with metadata. - } - else - { - srcLeftTop.y = pixelRowsNormalized; // Draw bottom half without metadata. - } - - SD3DPostEffectsUtils::DrawQuad(-1, -1, Vec2(srcLeftTop.x, srcLeftTop.y), Vec2(srcLeftTop.x, srcRightBottom.y), Vec2(srcRightBottom.x, srcRightBottom.y), Vec2(srcRightBottom.x, srcLeftTop.y), - Vec2(srcLeftTop.x, srcLeftTop.y), Vec2(srcLeftTop.x, srcRightBottom.y), Vec2(srcRightBottom.x, srcRightBottom.y), Vec2(srcRightBottom.x, srcLeftTop.y)); - } - } -} - -CCryNameTSCRC CHDRPostProcess::GetTonemapTechnique() const -{ - ToneMapOperators toneMapTech = static_cast(CRenderer::CV_r_ToneMapTechnique); - switch(toneMapTech) - { - case ToneMapOperators::Linear: - return CCryNameTSCRC("HDRToneMapLinear"); - case ToneMapOperators::Exponential: - return CCryNameTSCRC("HDRToneMapExponential"); - case ToneMapOperators::Reinhard: - return CCryNameTSCRC("HDRToneMapReinhard"); - case ToneMapOperators::FilmicCurveALU: - return CCryNameTSCRC("HDRToneMapFilmicALU"); - case ToneMapOperators::FilmicCurveUC2: - return CCryNameTSCRC("HDRFinalPass"); - default: - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Tonemap technique not supported"); - return CCryNameTSCRC("HDRFinalPass"); - } - } -} - -void CHDRPostProcess::SetExposureTypeShaderFlags() -{ - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE5]); - Exposuretype expType = static_cast(CRenderer::CV_r_ToneMapExposureType); - switch(expType) - { - case Exposuretype::Auto: - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - return; - } - case Exposuretype::Manual: - { - //Don't need to do anything as it will default to manual. - return; - } - default: - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Exposure type not supported"); - } - } -} - -void CHDRPostProcess::ToneMappingDebug() -{ - Vec4 avSampleOffsets[4]; - PROFILE_LABEL_SCOPE("TONEMAPPINGDEBUG"); - - // Enable corresponding shader variation - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - - if (CRenderer::CV_r_HDRDebug == 1) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - } - else - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_DEBUG0]; - } - - if (CRenderer::CV_r_HDREyeAdaptationMode == 2) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - SetExposureTypeShaderFlags(); - - uint32 nPasses; - static CCryNameTSCRC techName("HDRFinalDebugPass"); - m_shHDR->FXSetTechnique(techName); - m_shHDR->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_shHDR->FXBeginPass(0); - - GetSampleOffsets_DownScale2x2(CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight(), avSampleOffsets); - static CCryNameR SampleOffsetsName("SampleOffsets"); - m_shHDR->FXSetPSFloat(SampleOffsetsName, avSampleOffsets, 4); - - SetShaderParams(); - - CTexture::s_ptexHDRTarget->Apply(0, nTexStatePoint); - CTexture::s_ptexHDRToneMaps[0]->Apply(1, nTexStateLinear); - DrawFullScreenQuad(0.0f, 0.0f, 1.0f, 1.0f); - - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_DEBUG0]; -} - - -void CHDRPostProcess::CalculateDolbyDynamicMetadata(CTexture* pSunShaftsRT) -{ - PROFILE_LABEL_SCOPE("DOLBY_DYNAMIC_META"); - CD3D9Renderer* rd = &gcpRendD3D; - - // Settings (must match shaders!) - int width = gRenDev->GetBackbufferWidth(); - int height = gRenDev->GetBackbufferHeight(); - int pass0ReductionX = 16; - int pass0ReductionY = 16; - int pass0ThreadsX = 16; - int pass0ThreadsY = 16; - int pass0StrideX = 2; - int pass0StrideY = 2; - double outWidth = width / static_cast(pass0ReductionX * pass0StrideX); - double outHeight = height / static_cast(pass0ReductionY * pass0StrideY); - double dispatchX = width / static_cast(pass0ReductionX * pass0ThreadsX * pass0StrideX); - double dispatchY = height / static_cast(pass0ReductionY * pass0ThreadsY * pass0StrideY); - dispatchX = ceil(dispatchX); - dispatchY = ceil(dispatchY); - outWidth = ceil(outWidth); - outHeight = ceil(outHeight); - - // Make sure StructuredBuffers are initialized.. - if (m_bufDolbyMetadataMacroReductionOutput.m_pBuffer == nullptr) - { - // Max resolution 4K (4096x2160) - m_bufDolbyMetadataMacroReductionOutput.Create((4096 * 2160) / (pass0ReductionX * pass0ReductionY), sizeof(float) * 4, DXGI_FORMAT_UNKNOWN, DX11BUF_STRUCTURED | DX11BUF_BIND_UAV | DX11BUF_BIND_SRV, nullptr); - m_bufDolbyMetadataMinMaxMid.Create(3, sizeof(float), DXGI_FORMAT_UNKNOWN, DX11BUF_STRUCTURED | DX11BUF_BIND_UAV | DX11BUF_BIND_SRV, nullptr); - } - - // Make sure shaders are loaded.. - if (m_shHDRDolbyMetadataPass0 == nullptr) - { - m_shHDRDolbyMetadataPass0 = gcpRendD3D->m_cEF.mfForName("HDRDolbyMetadataPass0", EF_SYSTEM); - m_shHDRDolbyMetadataPass1 = gcpRendD3D->m_cEF.mfForName("HDRDolbyMetadataPass1", EF_SYSTEM); - } - - // Shared variables. - uint32 nPasses; - Vec4 parameters[2]; - static CCryNameR Parameter0Name("Parameters0"); - static CCryNameR Parameter1Name("Parameters1"); - - // Pass 1: Macro reduction of HDR signal. (256x reduction) - parameters[0] = Vec4(0.0f, 0.0f, static_cast(width), static_cast(height)); - parameters[1] = Vec4(static_cast(outWidth), 0.0f, 0.0f, 0.0f); - m_shHDRDolbyMetadataPass0->FXSetTechnique("Default"); - m_shHDRDolbyMetadataPass0->FXBegin(&nPasses, 0); - m_shHDRDolbyMetadataPass0->FXBeginPass(0); - m_shHDRDolbyMetadataPass0->FXSetCSFloat(Parameter0Name, parameters, 1); - m_shHDRDolbyMetadataPass0->FXSetCSFloat(Parameter1Name, parameters + 1, 1); - rd->FX_Commit(); - - // Bind HDR targets in order to recreating the same HDR input signal. - CTexture::s_ptexHDRTarget->Apply(0, nTexStateLinear, EFTT_UNKNOWN, -1, SResourceView::DefaultView, eHWSC_Compute); - CTexture::s_ptexHDRToneMaps[0]->Apply(1, nTexStateLinear, EFTT_UNKNOWN, -1, SResourceView::DefaultView, eHWSC_Compute); - CTexture* pBloom = CTextureManager::Instance()->GetBlackTexture(); - if (CRenderer::CV_r_HDRBloom && CRenderer::CV_r_PostProcess) - { - pBloom = CTexture::s_ptexHDRFinalBloom; - } - pBloom->Apply(2, nTexStateLinear, EFTT_UNKNOWN, -1, SResourceView::DefaultView, eHWSC_Compute); - if (pSunShaftsRT) - { - pSunShaftsRT->Apply(9, nTexStateLinear, EFTT_UNKNOWN, -1, SResourceView::DefaultView, eHWSC_Compute); - } - - rd->m_DevMan.BindUAV(eHWSC_Compute, m_bufDolbyMetadataMacroReductionOutput.GetUnorderedAccessView(), 0, 0); - - // Execute pass 1. - rd->m_DevMan.Dispatch(static_cast(dispatchX), static_cast(dispatchY), 1); - m_shHDRDolbyMetadataPass0->FXEndPass(); - m_shHDRDolbyMetadataPass0->FXEnd(); - - // Unbind UAV. - rd->m_DevMan.BindUAV(eHWSC_Compute, nullptr, 0, 0); - rd->m_DevMan.CommitDeviceStates(); - - // Pass 2: Micro reduction. (remainder) - parameters[0] = Vec4(static_cast(outWidth * outHeight), 0.0f, 0.0f, 0.0f); - m_shHDRDolbyMetadataPass1->FXSetTechnique("Default"); - m_shHDRDolbyMetadataPass1->FXBegin(&nPasses, 0); - m_shHDRDolbyMetadataPass1->FXBeginPass(0); - m_shHDRDolbyMetadataPass1->FXSetCSFloat(Parameter0Name, parameters, 1); - rd->FX_Commit(); - - rd->m_DevMan.BindUAV(eHWSC_Compute, m_bufDolbyMetadataMinMaxMid.GetUnorderedAccessView(), 0, 0); // Unbind previous UAV. - rd->m_DevMan.BindSRV(eHWSC_Compute, m_bufDolbyMetadataMacroReductionOutput.GetShaderResourceView(), 0); - - // Execute pass 2. - rd->m_DevMan.Dispatch(1, 1, 1); - m_shHDRDolbyMetadataPass1->FXEndPass(); - m_shHDRDolbyMetadataPass1->FXEnd(); - - // Unbind UAV. - rd->m_DevMan.BindUAV(eHWSC_Compute, nullptr, 0, 0); - rd->m_DevMan.CommitDeviceStates(); -} - - -void CHDRPostProcess::DrawDebugViews() -{ - if (CRenderer::CV_r_HDRDebug != 1 && CRenderer::CV_r_HDRDebug != 3 && CRenderer::CV_r_HDRDebug != 4) - { - return; - } - - CD3D9Renderer* rd = gcpRendD3D; - uint32 nPasses = 0; - - if (CRenderer::CV_r_HDRDebug == 1) - { - // We use screen shots to create minimaps, and we don't want to - // have any debug text on minimaps. - { - ICVar* const pVar = gEnv->pConsole->GetCVar("e_ScreenShot"); - if (pVar && pVar->GetIVal() != 0) - { - return; - } - } - - STALL_PROFILER("read scene luminance") - - float fLuminance = -1; - float fIlluminance = -1; - - CDeviceTexture* pSrcDevTex = CTexture::s_ptexHDRToneMaps[0]->GetDevTexture(); - pSrcDevTex->DownloadToStagingResource(0, [&](void* pData, [[maybe_unused]] uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - CryHalf* pRawPtr = reinterpret_cast(pData); - fLuminance = CryConvertHalfToFloat(pRawPtr[0]); - fIlluminance = CryConvertHalfToFloat(pRawPtr[1]); - return true; - }); - - char str[256]; - SDrawTextInfo ti; - ti.color[1] = 0; - azsprintf(str, "Average Luminance (cd/m2): %.2f", fLuminance * RENDERER_LIGHT_UNIT_SCALE); - rd->Draw2dText(5, 35, str, ti); - azsprintf(str, "Estimated Illuminance (lux): %.1f", fIlluminance * RENDERER_LIGHT_UNIT_SCALE); - rd->Draw2dText(5, 55, str, ti); - - Vec4 vHDRSetupParams[5]; - gEnv->p3DEngine->GetHDRSetupParams(vHDRSetupParams); - - if (CRenderer::CV_r_HDREyeAdaptationMode == 2) - { - // Compute scene key and exposure in the same way as in the tone mapping shader - float sceneKey = 1.03f - 2.0f / (2.0f + log(fLuminance + 1.0f) / log(2.0f)); - float exposure = clamp_tpl(sceneKey / fLuminance, vHDRSetupParams[4].y, vHDRSetupParams[4].z); - - azsprintf(str, "Exposure: %.2f SceneKey: %.2f", exposure, sceneKey); - rd->Draw2dText(5, 75, str, ti); - } - else - { - float exposure = log(fIlluminance * RENDERER_LIGHT_UNIT_SCALE * 100.0f / 330.0f) / log(2.0f); - float sceneKey = log(fIlluminance * RENDERER_LIGHT_UNIT_SCALE + 1.0f) / log(10.0f); - float autoCompensation = (clamp_tpl(sceneKey, 0.1f, 5.2f) - 3.0f) / 2.0f * vHDRSetupParams[3].z; - float finalExposure = clamp_tpl(exposure - autoCompensation, vHDRSetupParams[3].x, vHDRSetupParams[3].y); - - azsprintf(str, "Measured EV: %.1f Auto-EC: %.1f Final EV: %.1f", exposure, autoCompensation, finalExposure); - rd->Draw2dText(5, 75, str, ti); - } - - return; - } - - rd->FX_SetState(GS_NODEPTHTEST); - int iTmpX, iTmpY, iTempWidth, iTempHeight; - rd->GetViewport(&iTmpX, &iTmpY, &iTempWidth, &iTempHeight); - - rd->EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - rd->EF_SetSrgbWrite(false); - - TransformationMatrices backupSceneMatrices; - rd->Set2DMode(1, 1, backupSceneMatrices); - - gRenDev->m_cEF.mfRefreshSystemShader("Debug", CShaderMan::s_ShaderDebug); - CShader* pSH = CShaderMan::s_ShaderDebug; - - CTexture* pSceneTargetHalfRes = CTexture::s_ptexHDRTargetScaled[0]; - CTexture::s_ptexHDRTarget->SetResolved(false); - CTexture::s_ptexHDRTarget->Resolve(); - // 1 - uint32 nPosX = 10; - rd->RT_SetViewport(nPosX, 500, 100, 100); - rd->DrawImage(0, 0, 1, 1, CTexture::s_ptexHDRTarget->GetID(), 0, 1, 1, 0, 1, 1, 1, 1); - - // 2 - rd->RT_SetViewport(nPosX += 110, 500, 100, 100); - rd->DrawImage(0, 0, 1, 1, pSceneTargetHalfRes->GetID(), 0, 1, 1, 0, 1, 1, 1, 1); - - // 3 - if (CRenderer::CV_r_HDRBloom) - { - // Bloom generation/intermediate render-targets - - // Quarter res - rd->RT_SetViewport(nPosX += 110, 500, 100, 100); - rd->DrawImage(0, 0, 1, 1, CTexture::s_ptexHDRTempBloom[0]->GetID(), 0, 1, 1, 0, 1, 1, 1, 1); - - rd->RT_SetViewport(nPosX += 110, 500, 100, 100); - rd->DrawImage(0, 0, 1, 1, CTexture::s_ptexHDRTempBloom[1]->GetID(), 0, 1, 1, 0, 1, 1, 1, 1); - - rd->RT_SetViewport(nPosX += 110, 500, 100, 100); - rd->DrawImage(0, 0, 1, 1, CTexture::s_ptexHDRFinalBloom->GetID(), 0, 1, 1, 0, 1, 1, 1, 1); - } - - nPosX = 10; - - pSH->FXSetTechnique("Debug_ShowR"); - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - CTexture::s_ptexHDRToneMaps[3]->Apply(0, nTexStatePoint); - rd->RT_SetViewport(nPosX, 610, 100, 100); - DrawFullScreenQuadTR(0.0f, 0.0f, 1.0f, 1.0f); - - if (CTexture::s_ptexHDRToneMaps[2]) - { - CTexture::s_ptexHDRToneMaps[2]->Apply(0, nTexStatePoint); - rd->RT_SetViewport(nPosX += 110, 610, 100, 100); - DrawFullScreenQuadTR(0.0f, 0.0f, 1.0f, 1.0f); - } - - if (CTexture::s_ptexHDRToneMaps[1]) - { - CTexture::s_ptexHDRToneMaps[1]->Apply(0, nTexStatePoint); - rd->RT_SetViewport(nPosX += 110, 610, 100, 100); - DrawFullScreenQuadTR(0.0f, 0.0f, 1.0f, 1.0f); - } - - if (CTexture::s_ptexHDRToneMaps[0]) - { - CTexture::s_ptexHDRToneMaps[0]->Apply(0, nTexStatePoint); - rd->RT_SetViewport(nPosX += 110, 610, 100, 100); - DrawFullScreenQuadTR(0.0f, 0.0f, 1.0f, 1.0f); - } - - if (CTexture::s_ptexCurLumTexture) - { - CTexture::s_ptexCurLumTexture->Apply(0, nTexStatePoint); - rd->RT_SetViewport(nPosX += 110, 610, 100, 100); - DrawFullScreenQuadTR(0.0f, 0.0f, 1.0f, 1.0f); - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - rd->Unset2DMode(backupSceneMatrices); - - rd->RT_SetViewport(iTmpX, iTmpY, iTempWidth, iTempHeight); - - { - char str[256]; - - SDrawTextInfo ti; - - sprintf_s(str, "HDR rendering debug"); - rd->Draw2dText(5, 310, str, ti); - } -} - - -void CHDRPostProcess::ScreenShot() -{ - if (CRenderer::CV_r_GetScreenShot == 1) - { - iLog->LogError("HDR screen shots are not yet supported on DX11!"); // TODO: D3DXSaveSurfaceToFile() - } -} - - -void CHDRPostProcess::Begin() -{ - gcpRendD3D->GetModelViewMatrix(PostProcessUtils().m_pView.GetData()); - gcpRendD3D->GetProjectionMatrix(PostProcessUtils().m_pProj.GetData()); - - // Store some commonly used per-frame data - - PostProcessUtils().m_pViewProj = PostProcessUtils().m_pView * PostProcessUtils().m_pProj; - if (gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) - { - PostProcessUtils().m_pViewProj = ReverseDepthHelper::Convert(PostProcessUtils().m_pViewProj); - } - - PostProcessUtils().m_pViewProj.Transpose(); - - m_shHDR = CShaderMan::s_shHDRPostProcess; - - if (CTexture::s_ptexHDRTarget->GetWidth() != gcpRendD3D->GetWidth() || CTexture::s_ptexHDRTarget->GetHeight() != gcpRendD3D->GetHeight()) - { - CTexture::GenerateHDRMaps(); - } - - gcpRendD3D->FX_ResetPipe(); - PostProcessUtils().SetFillModeSolid(true); -} - - -void CHDRPostProcess::End() -{ - gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_HDR; - gcpRendD3D->m_RP.m_PersFlags2 &= ~(RBPF2_HDR_FP16 | RBPF2_LIGHTSHAFTS); - - gcpRendD3D->FX_ResetPipe(); - - PostProcessUtils().SetFillModeSolid(false); - - // (re-set back-buffer): if the platform does lazy RT updates/setting there's strong possibility we run into problems when we try to resolve with no RT set - gcpRendD3D->FX_SetActiveRenderTargets(); -} - - -void CHDRPostProcess::Render() -{ - PROFILE_LABEL_SCOPE("HDR_POSTPROCESS"); - - Begin(); - - if (!gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - CRY_ASSERT(gcpRendD3D->FX_GetCurrentRenderTarget(0) == CTexture::s_ptexHDRTarget); - - gcpRendD3D->FX_SetActiveRenderTargets(); // Called explicitly to work around RT stack problems on deprecated platform - gcpRendD3D->RT_UnbindTMUs();// Avoid d3d error due to potential rtv still bound as shader input. - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->EF_ClearTargetsLater(0); - } - - // Skip hdr/post processing when rendering different camera views - if ((gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_MIRRORCULL) || (gcpRendD3D->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN)) - { - End(); - return; - } - -#if !defined(_RELEASE) || defined(WIN32) || defined(WIN64) || defined(ENABLE_LW_PROFILERS) - ScreenShot(); -#endif - - gcpRendD3D->m_RP.m_FlagsShader_RT = 0; - - gcpRendD3D->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; // enable srgb. Can save this flag, always enabled - - gcpRendD3D->FX_ApplyShaderQuality(eST_PostProcess); - m_bHiQuality = CPostEffectsMgr::CheckPostProcessQuality(eRQ_Low, eSQ_VeryHigh); - - static ICVar* DolbyCvar = gEnv->pConsole->GetCVar("r_HDRDolby"); - const int DolbyCvarValue = DolbyCvar ? DolbyCvar->GetIVal() : eDVM_Disabled; - const bool bDolbyHDRMode = DolbyCvarValue > eDVM_Disabled; - - if (CRenderer::CV_r_PostProcess) - { - CStandardGraphicsPipeline& graphicsPipeline = gcpRendD3D->GetGraphicsPipeline(); - - const bool bSolidModeEnabled = gcpRendD3D->GetWireframeMode() == R_SOLID_MODE; - const bool bDepthOfFieldEnabled = CRenderer::CV_r_dof >= 1 && bSolidModeEnabled; - const bool takingScreenShot = (gcpRendD3D->m_screenShotType != 0); - const bool bMotionBlurEnabled = CRenderer::CV_r_MotionBlur && bSolidModeEnabled && (!takingScreenShot || CRenderer::CV_r_MotionBlurScreenShot) && !CRenderer::CV_r_RenderMotionBlurAfterHDR; - - DepthOfFieldParameters depthOfFieldParameters; - - if (bDepthOfFieldEnabled) - { - CDepthOfField* depthOfField = static_cast(PostEffectMgr()->GetEffect(ePFX_eDepthOfField)); - depthOfField->UpdateParameters(); - depthOfFieldParameters = depthOfField->GetParameters(); - } - - if (CRenderer::CV_r_AntialiasingMode == eAT_TAA) - { - CRY_ASSERT_MESSAGE(CRenderer::CV_r_ToneMapExposureType==static_cast(Exposuretype::Auto), "TAA needs auto exposure"); - GetUtils().StretchRect(CTexture::s_ptexHDRTarget, CTexture::s_ptexSceneTarget); - graphicsPipeline.RenderTemporalAA(CTexture::s_ptexSceneTarget, CTexture::s_ptexHDRTarget, depthOfFieldParameters); - } - - // Rain - CSceneRain* pSceneRain = static_cast(PostEffectMgr()->GetEffect(ePFX_SceneRain)); - const SRainParams& rainInfo = gcpRendD3D->m_p3DEngineCommon.m_RainInfo; - if (pSceneRain && pSceneRain->IsActive() && rainInfo.fRainDropsAmount > 0.01f) - { - pSceneRain->Render(); - } - - // Motion blur not enabled in 256bpp GMEM paths - if (CD3D9Renderer::eGT_256bpp_PATH != gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Note: Motion blur uses s_ptexHDRTargetPrev to avoid doing another copy, so this should be right before the MB pass - PostProcessUtils().StretchRect(CTexture::s_ptexHDRTarget, CTexture::s_ptexHDRTargetPrev, false, false, false, false, SPostEffectsUtils::eDepthDownsample_None, false, &gcpRendD3D->m_FullResRect); - } - - if (bDepthOfFieldEnabled) - { - graphicsPipeline.RenderDepthOfField(); - } - - uint32 flags = SRendItem::BatchFlags(EFSLIST_TRANSP, gcpRendD3D->m_RP.m_pRLD); - if (flags & FB_TRANSPARENT_AFTER_DOF) - { - PROFILE_LABEL_SCOPE("PARTICLES AFTER DOF"); - //render (after water) transparent particles list which was set to skip Depth of Field - gcpRendD3D->FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, &gcpRendD3D->m_DepthBufferOrig); - uint32 nBatchFilter = FB_TRANSPARENT_AFTER_DOF; - gcpRendD3D->FX_ProcessRenderList(EFSLIST_TRANSP, 1, gcpRendD3D->FX_FlushShader_General, true, nBatchFilter); - gcpRendD3D->FX_PopRenderTarget(0); - } - - if (bMotionBlurEnabled) - { - // Added old pipeline render call here. This lets us do motion blur before the end of HDR processing. - - if (CRenderer::CV_r_GraphicsPipeline > 0) - { - graphicsPipeline.RenderMotionBlur(); - } - else - { - CMotionBlur* motionBlurEffect = static_cast(PostEffectMgr()->GetEffect(ePFX_eMotionBlur)); - - if (motionBlurEffect) - { - motionBlurEffect->Render(); - } - } - } - - { - CSceneSnow* pSceneSnow = static_cast(PostEffectMgr()->GetEffect(ePFX_SceneSnow)); - if (pSceneSnow->IsActiveSnow()) - { - pSceneSnow->Render(); - } - } - - //Render passes for auto exposure. Used for tonemapping or Bloom generation - if (CRenderer::CV_r_ToneMapExposureType == static_cast(Exposuretype::Auto) || CRenderer::CV_r_HDRBloom) - { - HalfResDownsampleHDRTarget(); - gcpRendD3D->SetCurDownscaleFactor(Vec2(1, 1)); - QuarterResDownsampleHDRTarget(); - - gcpRendD3D->FX_ApplyShaderQuality(eST_PostProcess); - - // Update eye adaptation - if (CRenderer::CV_r_EnableGMEMPostProcCS) - { - MeasureLumEyeAdaptationUsingCompute(); - } - else - { - MeasureLuminance(); - EyeAdaptation(); - } - } - - if (CRenderer::CV_r_HDRBloom) - { - BloomGeneration(); - } - } - - gcpRendD3D->SetCurDownscaleFactor(gcpRendD3D->m_CurViewportScale); - - bool postAAWillApplyAA = (CRenderer::CV_r_AntialiasingMode == eAT_SMAA1TX) || (CRenderer::CV_r_AntialiasingMode == eAT_FXAA); - bool shouldRenderToBackbufferNow = CRenderer::CV_r_SkipNativeUpscale && CRenderer::CV_r_SkipRenderComposites && !postAAWillApplyAA; - if (shouldRenderToBackbufferNow) - { - gcpRendD3D->RT_SetViewport(0, 0, gcpRendD3D->GetNativeWidth(), gcpRendD3D->GetNativeHeight()); - gcpRendD3D->FX_SetRenderTarget(0, gcpRendD3D->GetBackBuffer(), nullptr); - gcpRendD3D->FX_SetActiveRenderTargets(); - } - else - { - gcpRendD3D->FX_PushRenderTarget(0, SPostEffectsUtils::AcquireFinalCompositeTarget(bDolbyHDRMode), &gcpRendD3D->m_DepthBufferOrigMSAA); - } - - // Render final scene to the back buffer - if (CRenderer::CV_r_HDRDebug != 1 && CRenderer::CV_r_HDRDebug != 2) - { - ToneMapping(); - } - else - { - ToneMappingDebug(); - } - - if (CRenderer::CV_r_HDRDebug > 0) - { - DrawDebugViews(); - } - - End(); -} - - -void CD3D9Renderer::FX_HDRPostProcessing() -{ - PROFILE_FRAME(Draw_HDR_PostProcessing); - - - if (gcpRendD3D->m_bDeviceLost) - { - return; - } - - if (!CTexture::IsTextureExist(CTexture::s_ptexHDRTarget)) - { - return; - } - - CHDRPostProcess* pHDRPostProcess = CHDRPostProcess::GetInstance(); - pHDRPostProcess->Render(); - pHDRPostProcess->ProcessLensOptics(); -} - - -void CD3D9Renderer::FX_FinalComposite() -{ - CTexture* upscaleSource = SPostEffectsUtils::GetFinalCompositeTarget(); - - if (FX_GetCurrentRenderTarget(0) == upscaleSource && upscaleSource != nullptr) - { - FX_PopRenderTarget(0); - - RT_SetViewport(0, 0, m_nativeWidth, m_nativeHeight); - FX_SetRenderTarget(0, m_pBackBuffer, nullptr); - FX_SetActiveRenderTargets(); - - static ICVar* DolbyCvar = gEnv->pConsole->GetCVar("r_HDRDolby"); - int DolbyCvarValue = DolbyCvar ? DolbyCvar->GetIVal() : eDVM_Disabled; - - if (DolbyCvarValue == eDVM_Vision) - { - CHDRPostProcess::GetInstance()->EncodeDolbyVision(upscaleSource); - } - else - { - GetGraphicsPipeline().RenderFinalComposite(upscaleSource); - } - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.cpp deleted file mode 100644 index 852ada8601..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "RenderDll_precompiled.h" -#include "D3DHMDRenderer.h" -#include "DriverD3D.h" -#include -#include -#include -#include -#include // for memset - -D3DHMDRenderer::D3DHMDRenderer() : - m_eyeWidth(0), - m_eyeHeight(0), - m_renderer(nullptr), - m_stereoRenderer(nullptr), - m_framePrepared(false) -{ - memset(m_eyes, 0, sizeof(m_eyes)); -} - -D3DHMDRenderer::~D3DHMDRenderer() -{ -} - -bool D3DHMDRenderer::Initialize(CD3D9Renderer* renderer, CD3DStereoRenderer* stereoRenderer) -{ - m_renderer = renderer; - m_stereoRenderer = stereoRenderer; - m_eyeWidth = m_renderer->GetWidth(); - m_eyeHeight = m_renderer->GetHeight(); - - AZ::VR::HMDDeviceBus::TextureDesc textureDesc; - textureDesc.width = m_eyeWidth; - textureDesc.height = m_eyeHeight; - - if (!ResizeRenderTargets(textureDesc)) - { - return false; - } - - return true; -} - -void D3DHMDRenderer::Shutdown() -{ - m_stereoRenderer->SetEyeTextures(nullptr, nullptr); - FreeRenderTargets(); -} - -void D3DHMDRenderer::CalculateBackbufferResolution(int eyeWidth, int eyeHeight, int& backbufferWidth, int& backbufferHeight) -{ - backbufferWidth = eyeWidth; - backbufferHeight = eyeHeight; -} - -void D3DHMDRenderer::OnResolutionChanged() -{ - if (m_eyeWidth != m_renderer->GetWidth() || - m_eyeHeight != m_renderer->GetHeight()) - { - // The size has actually changed, re-create the internal buffers. - m_eyeWidth = m_renderer->GetWidth(); - m_eyeHeight = m_renderer->GetHeight(); - - AZ::VR::HMDDeviceBus::TextureDesc textureDesc; - textureDesc.width = m_eyeWidth; - textureDesc.height = m_eyeHeight; - - ResizeRenderTargets(textureDesc); - } -} - -void D3DHMDRenderer::RenderSocialScreen() -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DHMDRenderer_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - //Only render the social screen if we're rendering to the main viewport - if (!gcpRendD3D->m_CurrContext->m_bMainViewport) - { - return; - } - - static ICVar* socialScreen = gEnv->pConsole->GetCVar("hmd_social_screen"); - AZ::VR::HMDSocialScreen socialScreenType = static_cast(socialScreen->GetIVal()); - - switch (socialScreenType) - { - case AZ::VR::HMDSocialScreen::Off: - { - // Don't render true black in order to distinguish between a rendering error and no social screen. - GetUtils().ClearScreen(0.1f, 0.1f, 0.1f, 1.0f); - break; - } - - case AZ::VR::HMDSocialScreen::UndistortedLeftEye: - case AZ::VR::HMDSocialScreen::UndistortedRightEye: - { - bool isLeftEye = (socialScreenType == AZ::VR::HMDSocialScreen::UndistortedLeftEye); - CTexture* sourceTexture = isLeftEye ? m_stereoRenderer->GetLeftEye() : m_stereoRenderer->GetRightEye(); - GetUtils().CopyTextureToScreen(sourceTexture); - break; - } - - default: - AZ_Assert(false, "Unknown social screen type specified in HMD renderer"); - break; - } -#endif -} - -void D3DHMDRenderer::PrepareFrame() -{ - // Determine which frame texture we should be using. - AZ::u32 leftEyeIndex = 0; - AZ::u32 rightEyeIndex = 0; - EBUS_EVENT_RESULT(leftEyeIndex, AZ::VR::HMDDeviceRequestBus, GetSwapchainIndex, STEREO_EYE_LEFT); - EBUS_EVENT_RESULT(rightEyeIndex, AZ::VR::HMDDeviceRequestBus, GetSwapchainIndex, STEREO_EYE_RIGHT); - - CTexture* leftEye = m_eyes[STEREO_EYE_LEFT].textureChain[leftEyeIndex]; - CTexture* rightEye = m_eyes[STEREO_EYE_RIGHT].textureChain[rightEyeIndex]; - - m_stereoRenderer->SetEyeTextures(leftEye, rightEye); - m_framePrepared = true; - - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, PrepareFrame); -} - -void D3DHMDRenderer::SubmitFrame() -{ - AZ_Assert(m_framePrepared, "D3DHMDRenderer::PrepareFrame() must be called BEFORE SubmitFrame()"); - - AZ::VR::HMDDeviceBus::EyeTarget targets[STEREO_EYE_COUNT]; - for (uint32 eye = 0; eye < STEREO_EYE_COUNT; ++eye) - { - targets[eye].renderTarget = m_eyes[eye].deviceRenderTarget.deviceSwapTextureSet; - targets[eye].viewportPosition = m_eyes[eye].viewportPosition; - targets[eye].viewportSize = m_eyes[eye].viewportSize; - } - - // Pass the final images to the HMD for final compositing and display. - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, SubmitFrame, targets[STEREO_EYE_LEFT], targets[STEREO_EYE_RIGHT]); - - m_framePrepared = false; -} - -bool D3DHMDRenderer::ResizeRenderTargets(const AZ::VR::HMDDeviceBus::TextureDesc& textureDesc) -{ - FreeRenderTargets(); - - const char* eyeTextureNames[2] = { "$LeftEye_%d", "$RightEye_%d" }; - - // Initialize the eye textures for rendering. - ID3D11Device* d3d11Device = &m_renderer->GetDevice(); - - AZ::VR::HMDRenderTarget* renderTargets[STEREO_EYE_COUNT]; - for (int eye = 0; eye < STEREO_EYE_COUNT; ++eye) - { - renderTargets[eye] = &((&(m_eyes[eye]))->deviceRenderTarget); - } - - { - bool result = false; - EBUS_EVENT_RESULT(result, AZ::VR::HMDDeviceRequestBus, CreateRenderTargets, d3d11Device, textureDesc, STEREO_EYE_COUNT, renderTargets); - - if (!result) - { - Shutdown(); - return false; - } - } - - for (int eye = 0; eye < STEREO_EYE_COUNT; ++eye) - { - EyeRenderTarget* eyeTarget = &(m_eyes[eye]); - - // The render target was successfully created, now wrap the device target in a DX11 texture for use by the rest - // of the engine. - uint32 numTextures = eyeTarget->deviceRenderTarget.numTextures; - eyeTarget->textureChain.reserve(numTextures); - for (uint32 texID = 0; texID < numTextures; ++texID) - { - char textureName[256]; - sprintf_s(textureName, eyeTextureNames[eye], texID); - - ETEX_Format format = CTexture::TexFormatFromDeviceFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); - CTexture* eyeTexture = WrapD3DRenderTarget(static_cast(eyeTarget->deviceRenderTarget.textures[texID]), textureDesc.width, textureDesc.height, format, textureName, true); - if (eyeTexture == nullptr) - { - return false; - } - - eyeTarget->textureChain.push_back(eyeTexture); - eyeTarget->viewportPosition = Vec2i(0, 0); - eyeTarget->viewportSize = Vec2i(textureDesc.width, textureDesc.height); - } - } - - return true; -} - -void D3DHMDRenderer::FreeRenderTargets() -{ - for (uint32 eye = 0; eye < STEREO_EYE_COUNT; ++eye) - { - for (uint32 texID = 0; texID < m_eyes[eye].textureChain.size(); ++texID) - { - SAFE_RELEASE_FORCE(m_eyes[eye].textureChain[texID]); - } - - // Destroy the device render target as well. - if (m_eyes[eye].textureChain.size()) - { - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, DestroyRenderTarget, m_eyes[eye].deviceRenderTarget); - } - - m_eyes[eye].textureChain.clear(); - } -} - -CTexture* D3DHMDRenderer::WrapD3DRenderTarget(ID3D11Texture2D* d3dTexture, uint32 width, uint32 height, ETEX_Format format, const char* name, bool shaderResourceView) -{ - CTexture* texture = CTexture::CreateTextureObject(name, width, height, 1, eTT_2D, FT_DONT_STREAM | FT_USAGE_RENDERTARGET, format); - if (texture == nullptr) - { - CryLogAlways("[HMD] Unable to create texture object!"); - return nullptr; - } - - // CTexture::CreateTextureObject does not set width and height if the texture already existed - AZ_Assert(texture->GetWidth() == width, "Texture was already wrapped"); - AZ_Assert(texture->GetHeight() == height, "Texture was already wrapped"); - AZ_Assert(texture->GetDepth() == 1, "Texture was already wrapped"); - - d3dTexture->AddRef(); - CDeviceTexture* deviceTexture = new CDeviceTexture(d3dTexture); - deviceTexture->SetNoDelete(true); - - texture->SetDevTexture(deviceTexture); - texture->ClosestFormatSupported(format); - - if (shaderResourceView) - { - void* default_srv = texture->CreateDeviceResourceView(SResourceView::ShaderResourceView(format, 0, -1, 0, 1, false, false)); - if (default_srv == nullptr) - { - CryLogAlways("[HMD] Unable to create default shader resource view!"); - texture->Release(); - return nullptr; - } - texture->SetShaderResourceView(static_cast(default_srv), false); - } - - return texture; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.h deleted file mode 100644 index b5a0b49818..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHMDRenderer.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -/// -/// Abstract all rendering for any connected HMD. This renderer takes care of managing the rendering-specific portions -/// of an HMD including: render target creation and destruction, social screen rendering, and frame submission. -/// - -#include -#include - -class CD3D9Renderer; -class CD3DStereoRenderer; -class CTexture; - -class D3DHMDRenderer -{ - public: - - D3DHMDRenderer(); - ~D3DHMDRenderer(); - - /// - /// Initialize the renderer for use. This includes creating any internal render targets. - /// - /// @param hmdDevice The HMD device to use when creating render targets and submitting frames. The HMD device should remain valid - /// the entire time that this renderer is in use. - /// @param renderer The platform-specific renderer (e.g. DX11) to use for render target creation/deletion. - /// @param stereoRenderer The platform-specific stereo renderer controlling this object. see IStereoRenderer.h for more info. - /// - /// @returns If true, the renderer successfully initialized and is ready to go. - /// - bool Initialize(CD3D9Renderer* renderer, CD3DStereoRenderer* stereoRenderer); - - /// - /// Shutdown the renderer and free any associated data from it. - /// - void Shutdown(); - - /// - /// Calculate the backbuffer resolution necessary to display both eyes simultaneously to a device such as a PC monitor. - /// - /// @param eyeWidth The width (in pixels) of one eye. - /// @param eyeHeight The height (in pixels) of one eye. - /// @param backbufferWidth Calculated backbuffer width based on the eye width/height. - /// @param backbufferHeight Calculated backbuffer height based on the eye width/height. - /// - void CalculateBackbufferResolution(int eyeWidth, int eyeHeight, int& backbufferWidth, int& backbufferHeight); - - /// - /// Change the underlying buffers to match the new resolution after the renderer has resized. - /// - void OnResolutionChanged(); - - /// - /// Render the social screen to a connected display (e.g. a PC monitor). - /// - void RenderSocialScreen(); - - /// - /// Prepare the current frame for submission. This must be called before any call to SubmitFrame(). - /// - void PrepareFrame(); - - /// - /// Submit the most recently rendered frame to the connected HMD device. - /// - void SubmitFrame(); - - private: - - /// - /// Resize the internal render targets based on the texture descriptor passed in. - /// - bool ResizeRenderTargets(const AZ::VR::HMDDeviceBus::TextureDesc& textureDesc); - - /// - /// Free the internal render targets (including device targets). - /// - void FreeRenderTargets(); - - /// - /// Wrap a device render target into a CTexture object for easy access throughout the renderer. - /// - CTexture* WrapD3DRenderTarget(ID3D11Texture2D* d3dTexture, uint32 width, uint32 height, ETEX_Format format, const char* name, bool shaderResourceView); - - uint32 m_eyeWidth; ///< Current width of an eye (in pixels). - uint32 m_eyeHeight; ///< Current height of an eye (in pixels). - - CD3D9Renderer* m_renderer; ///< Platform-specific rendering device. - CD3DStereoRenderer* m_stereoRenderer; ///< Platform-specific stereo rendering device controlling this object. - - /// - /// Per-eye render target info. - /// - struct EyeRenderTarget - { - AZ::VR::HMDRenderTarget deviceRenderTarget; ///< Device-controlled swap chain for rendering to. - TArray textureChain; ///< Texture references to the internal swap chain. - - Vec2i viewportPosition; ///< Position of the per-eye viewport (in pixels). - Vec2i viewportSize; ///< Size of the per-eye viewport (in pixels). - }; - - EyeRenderTarget m_eyes[STEREO_EYE_COUNT]; ///< Device render targets to be rendered to and submitted to the HMD for display. - - bool m_framePrepared; ///< If true, PrepareFrame() and SubmitFrame() were called in the proper ordering (just for debugging purproses). -}; diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.cpp deleted file mode 100644 index 112510ff6a..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.cpp +++ /dev/null @@ -1,5307 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "CryCrc32.h" -#include "../Common/Shaders/RemoteCompiler.h" -#include "../Common/PostProcess/PostEffects.h" -#include "D3DPostProcess.h" -#include "../Common/Textures/TextureHelpers.h" -#include "../Common/Textures/TextureManager.h" -#include "../Common/Include_HLSL_CPP_Shared.h" -#include "../Common/TypedConstantBuffer.h" -#include "GraphicsPipeline/FurBendData.h" -#include "GraphicsPipeline/FurPasses.h" -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DHWSHADER_CPP_SECTION_1 1 -#define D3DHWSHADER_CPP_SECTION_2 2 -#endif - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif -#include "../Cry3DEngine/Environment/OceanEnvironmentBus.h" - -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstGS; bool CHWShader_D3D::s_bFirstGS = true; -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstHS; bool CHWShader_D3D::s_bFirstHS = true; -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstDS; bool CHWShader_D3D::s_bFirstDS = true; -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstCS; bool CHWShader_D3D::s_bFirstCS = true; -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstVS; bool CHWShader_D3D::s_bFirstVS = true; -CHWShader_D3D::SHWSInstance *CHWShader_D3D::s_pCurInstPS; bool CHWShader_D3D::s_bFirstPS = true; - -#if !defined(_RELEASE) -AZStd::unordered_set, AZStd::equal_to, AZ::StdLegacyAllocator> CHWShader_D3D::s_ErrorsLogged; -#endif - -int CHWShader_D3D::s_nActivationFailMask = 0; - -AZStd::vector g_SelectedTechs; - -bool CHWShader_D3D::s_bInitShaders = true; - -int CHWShader_D3D::s_nResetDeviceFrame = -1; -int CHWShader_D3D::s_nInstFrame = -1; - -SD3DShader* CHWShader::s_pCurPS; -SD3DShader* CHWShader::s_pCurVS; -SD3DShader* CHWShader::s_pCurGS; -SD3DShader* CHWShader::s_pCurDS; -SD3DShader* CHWShader::s_pCurHS; -SD3DShader* CHWShader::s_pCurCS; - -FXShaderCache CHWShader::m_ShaderCache; -FXShaderCacheNames CHWShader::m_ShaderCacheList; - -// REFACTOR NOTE: -// Everything in the block should be pulled into its own file once stablized back to mainline. -#pragma region ShaderConstants - -CHWShader_D3D::SCGTextures CHWShader_D3D::s_PF_Textures; // Per-frame textures -CHWShader_D3D::SCGSamplers CHWShader_D3D::s_PF_Samplers; // Per-frame samplers - -namespace -{ - alloc_info_struct* GetFreeChunk(int bytes_count, int nBufSize, PodArray& alloc_info, const char* szSource) - { - int best_i = -1; - int min_size = 10000000; - - // find best chunk - for (int i = 0; i < alloc_info.Count(); i++) - { - if (!alloc_info[i].busy) - { - if (alloc_info[i].bytes_num >= bytes_count) - { - if (alloc_info[i].bytes_num < min_size) - { - best_i = i; - min_size = alloc_info[i].bytes_num; - } - } - } - } - - if (best_i >= 0) - { // use best free chunk - alloc_info[best_i].busy = true; - alloc_info[best_i].szSource = szSource; - - int bytes_free = alloc_info[best_i].bytes_num - bytes_count; - if (bytes_free > 0) - { - // modify reused shunk - alloc_info[best_i].bytes_num = bytes_count; - - // insert another free shunk - alloc_info_struct new_chunk; - new_chunk.bytes_num = bytes_free; - new_chunk.ptr = alloc_info[best_i].ptr + alloc_info[best_i].bytes_num; - new_chunk.busy = false; - - if (best_i < alloc_info.Count() - 1) // if not last - { - alloc_info.InsertBefore(new_chunk, best_i + 1); - } - else - { - alloc_info.Add(new_chunk); - } - } - - return &alloc_info[best_i]; - } - - int res_ptr = 0; - - int piplevel = alloc_info.Count() ? (alloc_info.Last().ptr - alloc_info[0].ptr) + alloc_info.Last().bytes_num : 0; - if (piplevel + bytes_count >= nBufSize) - { - return NULL; - } - else - { - res_ptr = piplevel; - } - - // register new chunk - alloc_info_struct ai; - ai.ptr = res_ptr; - ai.szSource = szSource; - ai.bytes_num = bytes_count; - ai.busy = true; - alloc_info.Add(ai); - - return &alloc_info[alloc_info.Count() - 1]; - } - - bool ReleaseChunk(int p, PodArray& alloc_info) - { - for (int i = 0; i < alloc_info.Count(); i++) - { - if (alloc_info[i].ptr == p) - { - alloc_info[i].busy = false; - - // delete info about last unused chunks - while (alloc_info.Count() && alloc_info.Last().busy == false) - { - alloc_info.Delete(alloc_info.Count() - 1); - } - - // merge unused chunks - for (int s = 0; s < alloc_info.Count() - 1; s++) - { - assert(alloc_info[s].ptr < alloc_info[s + 1].ptr); - - if (alloc_info[s].busy == false) - { - if (alloc_info[s + 1].busy == false) - { - alloc_info[s].bytes_num += alloc_info[s + 1].bytes_num; - alloc_info.Delete(s + 1); - s--; - } - } - } - - return true; - } - } - - return false; - } -} - -DynArray CGParamManager::s_Pools; -AZStd::vector CGParamManager::s_Groups; -AZStd::vector CGParamManager::s_FreeGroups; - -SCGParamPool::SCGParamPool(int nEntries) - : m_Params(new SCGParam[nEntries], nEntries) -{ -} - -SCGParamPool::~SCGParamPool() -{ - delete[] m_Params.begin(); -} - -SCGParamsGroup SCGParamPool::Alloc(int nEntries) -{ - SCGParamsGroup Group; - - alloc_info_struct* pAI = GetFreeChunk(nEntries, m_Params.size(), m_alloc_info, "CGParam"); - if (pAI) - { - Group.nParams = nEntries; - Group.pParams = &m_Params[pAI->ptr]; - } - - return Group; -} - -bool SCGParamPool::Free(SCGParamsGroup& Group) -{ - bool bRes = ReleaseChunk((int)(Group.pParams - m_Params.begin()), m_alloc_info); - return bRes; -} - -int CGParamManager::GetParametersGroup(SParamsGroup& InGr, int nId) -{ - std::vector& InParams = nId > 1 ? InGr.Params_Inst : InGr.Params[nId]; - int32 i; - int nParams = InParams.size(); - - int nGroupSize = s_Groups.size(); - for (i = 0; i < nGroupSize; i++) - { - SCGParamsGroup& Gr = s_Groups[i]; - if (Gr.nParams != nParams) - { - continue; - } - int j; - for (j = 0; j < nParams; j++) - { - if (InParams[j] != Gr.pParams[j]) - { - break; - } - } - if (j == nParams) - { - Gr.nRefCounter++; - return i; - } - } - - SCGParamsGroup Group; - SCGParamPool* pPool = NULL; - for (i = 0; i < s_Pools.size(); i++) - { - pPool = &s_Pools[i]; - Group = pPool->Alloc(nParams); - if (Group.nParams) - { - break; - } - } - if (!Group.pParams) - { - pPool = NewPool(PARAMS_POOL_SIZE); - Group = pPool->Alloc(nParams); - } - assert(Group.pParams); - if (!Group.pParams) - { - return 0; - } - Group.nPool = i; - uint32 n = s_Groups.size(); - if (s_FreeGroups.size()) - { - n = s_FreeGroups.back(); - s_FreeGroups.pop_back(); - s_Groups[n] = Group; - } - else - { - s_Groups.push_back(Group); - } - - for (i = 0; i < nParams; i++) - { - s_Groups[n].pParams[i] = InParams[i]; - } - - return n; -} - -bool CGParamManager::FreeParametersGroup(int nIDGroup) -{ - if (nIDGroup < 0 || nIDGroup >= (int)s_Groups.size()) - { - return false; - } - SCGParamsGroup& Group = s_Groups[nIDGroup]; - Group.nRefCounter--; - if (Group.nRefCounter) - { - return true; - } - if (Group.nPool < 0 || Group.nPool >= s_Pools.size()) - { - return false; - } - SCGParamPool& Pool = s_Pools[Group.nPool]; - if (!Pool.Free(Group)) - { - return false; - } - for (int i = 0; i < Group.nParams; i++) - { - Group.pParams[i].m_Name.reset(); - SAFE_DELETE(Group.pParams[i].m_pData); - } - - Group.nParams = 0; - Group.nPool = 0; - Group.pParams = 0; - - s_FreeGroups.push_back(nIDGroup); - - return true; -} - -void CGParamManager::Init() -{ - s_FreeGroups.reserve(128); // Based on spear - s_Groups.reserve(2048); -} -void CGParamManager::Shutdown() -{ - s_FreeGroups.clear(); - s_Pools.clear(); - s_Groups.clear(); -} - -SCGParamPool* CGParamManager::NewPool(int nEntries) -{ - return new(s_Pools.grow_raw())SCGParamPool(nEntries); -} - - -DEFINE_ALIGNED_DATA(UFloat4, s_ConstantScratchBuffer[48], 16); - -namespace -{ - static inline void TransposeAndStore(UFloat4* sData, const Matrix44A& mMatrix) - { -# if defined(_CPU_SSE) - __m128 row0 = _mm_load_ps(&mMatrix.m00); - __m128 row1 = _mm_load_ps(&mMatrix.m10); - __m128 row2 = _mm_load_ps(&mMatrix.m20); - __m128 row3 = _mm_load_ps(&mMatrix.m30); - _MM_TRANSPOSE4_PS(row0, row1, row2, row3); - _mm_store_ps(&sData[0].f[0], row0); - _mm_store_ps(&sData[1].f[0], row1); - _mm_store_ps(&sData[2].f[0], row2); - _mm_store_ps(&sData[3].f[0], row3); -# else - *alias_cast(&sData[0]) = mMatrix.GetTransposed(); -# endif - } - - static inline void Store(UFloat4* sData, const Matrix44A& mMatrix) - { -# if defined(_CPU_SSE) - __m128 row0 = _mm_load_ps(&mMatrix.m00); - _mm_store_ps(&sData[0].f[0], row0); - __m128 row1 = _mm_load_ps(&mMatrix.m10); - _mm_store_ps(&sData[1].f[0], row1); - __m128 row2 = _mm_load_ps(&mMatrix.m20); - _mm_store_ps(&sData[2].f[0], row2); - __m128 row3 = _mm_load_ps(&mMatrix.m30); - _mm_store_ps(&sData[3].f[0], row3); -# else - *alias_cast(&sData[0]) = mMatrix; -# endif - } - - static inline void Store(UFloat4* sData, const Matrix34A& mMatrix) - { -# if defined(_CPU_SSE) - __m128 row0 = _mm_load_ps(&mMatrix.m00); - _mm_store_ps(&sData[0].f[0], row0); - __m128 row1 = _mm_load_ps(&mMatrix.m10); - _mm_store_ps(&sData[1].f[0], row1); - __m128 row2 = _mm_load_ps(&mMatrix.m20); - _mm_store_ps(&sData[2].f[0], row2); - _mm_store_ps(&sData[3].f[0], _mm_setr_ps(0, 0, 0, 1)); -# else - *alias_cast(&sData[0]) = mMatrix; -# endif - } - -#if defined(_CPU_SSE) - // Matrix multiplication using SSE instructions set - // IMPORTANT NOTE: much faster if matrices m1 and product are 16 bytes aligned - inline void multMatrixf_Transp2_SSE(float* product, const float* m1, const float* m2) - { - __m128 x0 = _mm_load_ss(m2); - __m128 x1 = _mm_load_ps(m1); - x0 = _mm_shuffle_ps(x0, x0, 0); - __m128 x2 = _mm_load_ss(&m2[4]); - x0 = _mm_mul_ps(x0, x1); - x2 = _mm_shuffle_ps(x2, x2, 0); - __m128 x3 = _mm_load_ps(&m1[4]); - __m128 x4 = _mm_load_ss(&m2[8]); - x2 = _mm_mul_ps(x2, x3); - x4 = _mm_shuffle_ps(x4, x4, 0); - x0 = _mm_add_ps(x0, x2); - x2 = _mm_load_ps(&m1[8]); - x4 = _mm_mul_ps(x4, x2); - __m128 x6 = _mm_load_ps(&m1[12]); - x0 = _mm_add_ps(x0, x4); - _mm_store_ps(product, x0); - x0 = _mm_load_ss(&m2[1]); - x4 = _mm_load_ss(&m2[5]); - x0 = _mm_shuffle_ps(x0, x0, 0); - x4 = _mm_shuffle_ps(x4, x4, 0); - x0 = _mm_mul_ps(x0, x1); - x4 = _mm_mul_ps(x4, x3); - __m128 x5 = _mm_load_ss(&m2[9]); - x0 = _mm_add_ps(x0, x4); - x5 = _mm_shuffle_ps(x5, x5, 0); - x5 = _mm_mul_ps(x5, x2); - x0 = _mm_add_ps(x0, x5); - _mm_store_ps(&product[4], x0); - x0 = _mm_load_ss(&m2[2]); - x4 = _mm_load_ss(&m2[6]); - x0 = _mm_shuffle_ps(x0, x0, 0); - x4 = _mm_shuffle_ps(x4, x4, 0); - x0 = _mm_mul_ps(x0, x1); - x4 = _mm_mul_ps(x4, x3); - x5 = _mm_load_ss(&m2[10]); - x0 = _mm_add_ps(x0, x4); - x5 = _mm_shuffle_ps(x5, x5, 0); - x5 = _mm_mul_ps(x5, x2); - x0 = _mm_add_ps(x0, x5); - _mm_store_ps(&product[8], x0); - x0 = _mm_load_ss(&m2[3]); - x4 = _mm_load_ss(&m2[7]); - x0 = _mm_shuffle_ps(x0, x0, 0); - x4 = _mm_shuffle_ps(x4, x4, 0); - x0 = _mm_mul_ps(x0, x1); - x4 = _mm_mul_ps(x4, x3); - x1 = _mm_load_ss(&m2[11]); - x0 = _mm_add_ps(x0, x4); - x1 = _mm_shuffle_ps(x1, x1, 0); - x1 = _mm_mul_ps(x1, x2); - x1 = _mm_add_ps(x1, x6); - x0 = _mm_add_ps(x0, x1); - _mm_store_ps(&product[12], x0); - } -#endif - - inline void multMatrixf_Transp2(float* product, const float* m1, const float* m2) - { - float temp[16]; - -#define A(row, col) m1[(col << 2) + row] -#define B(row, col) m2[(col << 2) + row] -#define P(row, col) temp[(col << 2) + row] - - int i; - for (i = 0; i < 4; i++) - { - float ai0 = A(i, 0), ai1 = A(i, 1), ai2 = A(i, 2), ai3 = A(i, 3); - P(i, 0) = ai0 * B(0, 0) + ai1 * B(0, 1) + ai2 * B(0, 2); - P(i, 1) = ai0 * B(1, 0) + ai1 * B(1, 1) + ai2 * B(1, 2); - P(i, 2) = ai0 * B(2, 0) + ai1 * B(2, 1) + ai2 * B(2, 2); - P(i, 3) = ai0 * B(3, 0) + ai1 * B(3, 1) + ai2 * B(3, 2) + ai3; - } - - cryMemcpy(product, temp, sizeof(temp)); - -#undef A -#undef B -#undef P - } - - - inline void mathMatrixMultiply_Transp2(float* pOut, const float* pM1, const float* pM2, [[maybe_unused]] int OptFlags) - { -#if defined(_CPU_SSE) - multMatrixf_Transp2_SSE(pOut, pM1, pM2); -#else - multMatrixf_Transp2(pOut, pM1, pM2); -#endif - } - - NO_INLINE void sIdentityLine(UFloat4* sData) - { - sData[0].f[0] = sData[0].f[1] = sData[0].f[2] = 0.f; - sData[0].f[3] = 1.0f; - } - NO_INLINE void sOneLine(UFloat4* sData) - { - sData[0].f[0] = sData[0].f[1] = sData[0].f[2] = 1.f; - sData[0].f[3] = 1.0f; - } - NO_INLINE void sZeroLine(UFloat4* sData) - { - sData[0].f[0] = sData[0].f[1] = sData[0].f[2] = 0.f; - sData[0].f[3] = 0.0f; - } - - NO_INLINE IRenderElement* sGetContainerRE0(IRenderElement* pRE) - { - assert(pRE); // someone assigned wrong shader - function should not be called then - - if (pRE->mfGetType() == eDATA_Mesh && ((CREMeshImpl*)pRE)->m_pRenderMesh->_GetVertexContainer()) - { - assert(((CREMeshImpl*)pRE)->m_pRenderMesh->_GetVertexContainer()->m_Chunks.size() >= 1); - return ((CREMeshImpl*)pRE)->m_pRenderMesh->_GetVertexContainer()->m_Chunks[0].pRE; - } - - return pRE; - } - - NO_INLINE void sGetTerrainBase(UFloat4* sData, CD3D9Renderer* r) - { - if (!r->m_RP.m_pRE) - { - sZeroLine(sData); - return; - } - // use render element from vertex container render mesh if available - IRenderElement* pRE = sGetContainerRE0(r->m_RP.m_pRE); - - if (pRE && pRE->GetCustomData()) - { - float* pData; - - if (SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID] <= 0) - { - pData = (float*)pRE->GetCustomData(); - } - else - { - pData = (float*)pRE->GetCustomData() + 4; - } - - sData[0].f[0] = pData[2]; - sData[0].f[1] = pData[0]; - sData[0].f[2] = pData[1]; - } - else - { - sZeroLine(sData); - } - } - - NO_INLINE void sGetTerrainLayerGen(UFloat4* sData, CD3D9Renderer* r) - { - IRenderElement* pRE = r->m_RP.m_pRE; - if (pRE && pRE->GetCustomData()) - { - float* pData = (float*)pRE->GetCustomData(); - memcpy(sData, pData, sizeof(float) * 16); - } - else - { - memset(sData, 0, sizeof(float) * 16); - } - } - - void sGetTexMatrix(UFloat4* sData, CD3D9Renderer* r, const SCGParam* ParamBind) - { - Matrix44& result = *((Matrix44*)sData); - - SHRenderTarget* renderTarget = (SHRenderTarget*)(UINT_PTR)ParamBind->m_nID; - if (!renderTarget) - { - result.SetIdentity(); - return; - } - - SEnvTexture* pEnvTex = renderTarget->GetEnv2D(); - if (!pEnvTex || !pEnvTex->m_pTex) - { - result.SetIdentity(); - return; - } - - if ((renderTarget->m_eUpdateType != eRTUpdate_WaterReflect)) - { - result = r->m_RP.m_pCurObject->m_II.m_Matrix * pEnvTex->m_Matrix; - } - else - { - result = pEnvTex->m_Matrix; - } - result.Transpose(); - } - - - - NO_INLINE void sGetScreenSize(UFloat4* sData, CD3D9Renderer* r) - { - int iTempX, iTempY, iWidth, iHeight; - r->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); -#if defined(WIN32) || defined(WIN64) - float w = (float)(iWidth > 1 ? iWidth : 1); - float h = (float)(iHeight > 1 ? iHeight : 1); -#else - float w = (float)iWidth; - float h = (float)iHeight; -#endif - sData[0].f[0] = w; - sData[0].f[1] = h; - sData[0].f[2] = 0.5f / (w / r->m_RP.m_CurDownscaleFactor.x); - sData[0].f[3] = 0.5f / (h / r->m_RP.m_CurDownscaleFactor.y); - } - - NO_INLINE void sGetIrregKernel(UFloat4* sData, CD3D9Renderer* r) - { - int nSamplesNum = 1; - switch (r->m_RP.m_nShaderQuality) - { - case eSQ_Low: - nSamplesNum = 4; - break; - case eSQ_Medium: - nSamplesNum = 8; - break; - case eSQ_High: - nSamplesNum = 16; - break; - case eSQ_VeryHigh: - nSamplesNum = 16; - break; - default: - assert(0); - } - - CShadowUtils::GetIrregKernel((float(*)[4]) & sData[0], nSamplesNum); - } - - enum class FrameType - { - Current, - Previous - }; - - NO_INLINE void sGetBendInfo(CRenderObject* const __restrict renderObject, FrameType frameType, UFloat4* sData, [[maybe_unused]] CD3D9Renderer* r) - { - Vec4 bendingInfoResult(0.0f); - SRenderObjData* objectData = renderObject->GetObjData(); - SBending* bending = nullptr; - float time = 0.0f; - - if (objectData) - { - if (frameType == FrameType::Current) - { - bending = objectData->m_pBending; - time = CRenderer::GetRealTime(); - } - else - { - bending = objectData->m_BendingPrev; - time = CRenderer::GetRealTime() - CRenderer::GetElapsedTime(); - } - } - - // Set values to zero if no bending found - eg. trees created as geom entity and not vegetation, - // these are still rendered with bending/detailbending enabled in shader - // (very ineffective but they should not appear in real levels) - if (bending) - { - bendingInfoResult = bending->GetShaderConstants(time); - } - - *(alias_cast(&sData[0])) = bendingInfoResult; - } - - NO_INLINE Vec4 sGetVolumetricFogParams(CD3D9Renderer* r) - { - Vec4 pFogParams; - - I3DEngine* pEng = gEnv->p3DEngine; - assert(pEng); - - Vec3 globalDensityParams(0, 1, 1); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_GLOBAL_DENSITY, globalDensityParams); - - float globalDensity = globalDensityParams.x; - if (!gRenDev->IsHDRModeEnabled()) - { - globalDensity *= globalDensityParams.y; - } - - Vec3 volFogHeightDensity(0, 1, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY, volFogHeightDensity); - volFogHeightDensity.y = clamp_tpl(volFogHeightDensity.y, 1e-5f, 1.0f); - - Vec3 volFogHeightDensity2(4000.0f, 0, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY2, volFogHeightDensity2); - volFogHeightDensity2.y = clamp_tpl(volFogHeightDensity2.y, 1e-5f, 1.0f); - volFogHeightDensity2.x = volFogHeightDensity2.x < volFogHeightDensity.x + 1.0f ? volFogHeightDensity.x + 1.0f : volFogHeightDensity2.x; - - const float ha = volFogHeightDensity.x; - const float hb = volFogHeightDensity2.x; - - const float da = volFogHeightDensity.y; - const float db = volFogHeightDensity2.y; - - const float ga = logf(da); - const float gb = logf(db); - - const float c = (gb - ga) / (hb - ha); - const float o = ga - c * ha; - - const float viewerHeight = r->GetViewParameters().vOrigin.z; - const float co = clamp_tpl(c * viewerHeight + o, -50.0f, 50.0f); // Avoiding FPEs at extreme ranges - - globalDensity *= 0.01f; // multiply by 1/100 to scale value editor value back to a reasonable range - - pFogParams.x = c; - pFogParams.y = 1.44269502f * globalDensity * expf(co); // log2(e) = 1.44269502 - pFogParams.z = globalDensity; - pFogParams.w = 1.0f - clamp_tpl(globalDensityParams.z, 0.0f, 1.0f); - - return pFogParams; - } - - NO_INLINE Vec4 sGetVolumetricFogRampParams() - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 vfRampParams(0, 100.0f, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_RAMP, vfRampParams); - - vfRampParams.x = vfRampParams.x < 0 ? 0 : vfRampParams.x; // start - vfRampParams.y = vfRampParams.y < vfRampParams.x + 0.1f ? vfRampParams.x + 0.1f : vfRampParams.y; // end - vfRampParams.z = clamp_tpl(vfRampParams.z, 0.0f, 1.0f); // influence - - float invRampDist = 1.0f / (vfRampParams.y - vfRampParams.x); - return Vec4(invRampDist, -vfRampParams.x * invRampDist, vfRampParams.z, -vfRampParams.z + 1.0f); - } - - NO_INLINE void sGetFogColorGradientConstants(Vec4& fogColGradColBase, Vec4& fogColGradColDelta) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 colBase = pEng->GetFogColor(); - fogColGradColBase = Vec4(colBase, 0); - - Vec3 colTop(colBase); - pEng->GetGlobalParameter(E3DPARAM_FOG_COLOR2, colTop); - fogColGradColDelta = Vec4(colTop - colBase, 0); - } - - NO_INLINE Vec4 sGetFogColorGradientParams() - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 volFogHeightDensity(0, 1, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY, volFogHeightDensity); - - Vec3 volFogHeightDensity2(4000.0f, 0, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_HEIGHT_DENSITY2, volFogHeightDensity2); - volFogHeightDensity2.x = volFogHeightDensity2.x < volFogHeightDensity.x + 1.0f ? volFogHeightDensity.x + 1.0f : volFogHeightDensity2.x; - - Vec3 gradientCtrlParams(0, 0.75f, 0.5f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG_GRADIENT_CTRL, gradientCtrlParams); - - const float colorHeightOffset = clamp_tpl(gradientCtrlParams.x, -1.0f, 1.0f); - const float radialSize = -expf((1.0f - clamp_tpl(gradientCtrlParams.y, 0.0f, 1.0f)) * 14.0f) * 1.44269502f; // log2(e) = 1.44269502; - const float radialLobe = 1.0f / clamp_tpl(gradientCtrlParams.z, 1.0f / 21.0f, 1.0f) - 1.0f; - - const float invDist = 1.0f / (volFogHeightDensity2.x - volFogHeightDensity.x); - return Vec4(invDist, -volFogHeightDensity.x * invDist - colorHeightOffset, radialSize, radialLobe); - } - - NO_INLINE Vec4 sGetFogColorGradientRadial(CD3D9Renderer* r) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 fogColorRadial(0, 0, 0); - pEng->GetGlobalParameter(E3DPARAM_FOG_RADIAL_COLOR, fogColorRadial); - - const CameraViewParameters& rc = r->GetViewParameters(); - const float invFarDist = 1.0f / rc.fFar; - - return Vec4(fogColorRadial, invFarDist); - } - - NO_INLINE Vec4 sGetVolumetricFogSamplingParams(CD3D9Renderer* r) - { - const CameraViewParameters& rc = r->GetViewParameters(); - - Vec3 volFogCtrlParams(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - const float raymarchStart = rc.fNear; - const float raymarchDistance = (volFogCtrlParams.x > raymarchStart) ? (volFogCtrlParams.x - raymarchStart) : 0.0001f; - - Vec4 params; - params.x = raymarchStart; - params.y = 1.0f / raymarchDistance; - params.z = static_cast(CTexture::s_ptexVolumetricFog ? CTexture::s_ptexVolumetricFog->GetDepth() : 0.0f); - params.w = params.z > 0.0f ? (1.0f / params.z) : 0.0f; - return params; - } - - NO_INLINE Vec4 sGetVolumetricFogDistributionParams(CD3D9Renderer* r) - { - const CameraViewParameters& rc = r->GetViewParameters(); - - Vec3 volFogCtrlParams(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - const float raymarchStart = rc.fNear; - const float raymarchDistance = (volFogCtrlParams.x > raymarchStart) ? (volFogCtrlParams.x - raymarchStart) : 0.0001f; - - Vec4 params; - params.x = raymarchStart; - params.y = raymarchDistance; - float d = static_cast(CTexture::s_ptexVolumetricFog ? CTexture::s_ptexVolumetricFog->GetDepth() : 0.0f); - params.z = d > 1.0f ? (1.0f / (d - 1.0f)) : 0.0f; - params.w = 0.0f; - return params; - } - - NO_INLINE Vec4 sGetVolumetricFogScatteringParams([[maybe_unused]] CD3D9Renderer* r) - { - Vec3 volFogScatterParams(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_SCATTERING_PARAMS, volFogScatterParams); - - Vec3 anisotropy(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY, anisotropy); - - float k = anisotropy.z; - bool bNegative = k < 0.0f ? true : false; - k = (abs(k) > 0.99999f) ? (bNegative ? -0.99999f : 0.99999f) : k; - - Vec4 params; - params.x = volFogScatterParams.x; - params.y = (volFogScatterParams.y < 0.0001f) ? 0.0001f : volFogScatterParams.y;// it ensures extinction is more than zero. - params.z = k; - params.w = 1.0f - k * k; - return params; - } - - NO_INLINE Vec4 sGetVolumetricFogScatteringBlendParams([[maybe_unused]] CD3D9Renderer* r) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 volFogCtrlParams(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - - Vec4 params; - params.x = volFogCtrlParams.y;// blend factor of two radial lobes - params.y = volFogCtrlParams.z;// blend mode of two radial lobes - params.z = 0.0f; - params.w = 0.0f; - return params; - } - - NO_INLINE Vec4 sGetVolumetricFogScatteringColor([[maybe_unused]] CD3D9Renderer* r) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 fogAlbedo(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_COLOR1, fogAlbedo); - Vec3 sunColor = pEng->GetSunColor(); - sunColor = sunColor.CompMul(fogAlbedo); - - Vec3 anisotropy(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY2, anisotropy); - - float k = anisotropy.z; - bool bNegative = k < 0.0f ? true : false; - k = (abs(k) > 0.99999f) ? (bNegative ? -0.99999f : 0.99999f) : k; - - return Vec4(sunColor, k); - } - - NO_INLINE Vec4 sGetVolumetricFogScatteringSecondaryColor([[maybe_unused]] CD3D9Renderer* r) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 fogAlbedo(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_COLOR2, fogAlbedo); - Vec3 sunColor = pEng->GetSunColor(); - sunColor = sunColor.CompMul(fogAlbedo); - - Vec3 anisotropy(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY2, anisotropy); - - float k = anisotropy.z; - bool bNegative = k < 0.0f ? true : false; - k = (abs(k) > 0.99999f) ? (bNegative ? -0.99999f : 0.99999f) : k; - - return Vec4(sunColor, 1.0f - k * k); - } - - NO_INLINE Vec4 sGetVolumetricFogHeightDensityParams(CD3D9Renderer* r) - { - Vec4 pFogParams; - - I3DEngine* pEng = gEnv->p3DEngine; - assert(pEng); - - Vec3 globalDensityParams(0, 1, 1); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_GLOBAL_DENSITY, globalDensityParams); - - float globalDensity = globalDensityParams.x; - const float clampTransmittance = globalDensityParams.y > 0.9999999f ? 1.0f : globalDensityParams.y; - const float visibility = globalDensityParams.z; - - Vec3 volFogHeightDensity(0, 1, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY, volFogHeightDensity); - volFogHeightDensity.y = clamp_tpl(volFogHeightDensity.y, 1e-5f, 1.0f); - - Vec3 volFogHeightDensity2(4000.0f, 0, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_HEIGHT_DENSITY2, volFogHeightDensity2); - volFogHeightDensity2.y = clamp_tpl(volFogHeightDensity2.y, 1e-5f, 1.0f); - volFogHeightDensity2.x = volFogHeightDensity2.x < volFogHeightDensity.x + 1.0f ? volFogHeightDensity.x + 1.0f : volFogHeightDensity2.x; - - const float ha = volFogHeightDensity.x; - const float hb = volFogHeightDensity2.x; - - const float db = volFogHeightDensity2.y; - const float da = abs(db - volFogHeightDensity.y) < 0.00001f ? volFogHeightDensity.y + 0.00001f : volFogHeightDensity.y; - - const float ga = logf(da); - const float gb = logf(db); - - const float c = (gb - ga) / (hb - ha); - const float o = ga - c * ha; - - const float viewerHeight = r->GetViewParameters().vOrigin.z; - const float co = clamp_tpl(c * viewerHeight + o, -50.0f, 50.0f); // Avoiding FPEs at extreme ranges - - globalDensity *= 0.01f; // multiply by 1/100 to scale value editor value back to a reasonable range - - pFogParams.x = c; - pFogParams.y = 1.44269502f * globalDensity * expf(co); // log2(e) = 1.44269502 - pFogParams.z = visibility; - pFogParams.w = 1.0f - clamp_tpl(clampTransmittance, 0.0f, 1.0f); - - return pFogParams; - } - - NO_INLINE Vec4 sGetVolumetricFogHeightDensityRampParams([[maybe_unused]] CD3D9Renderer* r) - { - I3DEngine* pEng = gEnv->p3DEngine; - - Vec3 vfRampParams(0, 100.0f, 0); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_RAMP, vfRampParams); - - vfRampParams.x = vfRampParams.x < 0 ? 0 : vfRampParams.x; // start - vfRampParams.y = vfRampParams.y < vfRampParams.x + 0.1f ? vfRampParams.x + 0.1f : vfRampParams.y; // end - - float t0 = 1.0f / (vfRampParams.y - vfRampParams.x); - float t1 = vfRampParams.x * t0; - - return Vec4(vfRampParams.x, vfRampParams.y, t0, t1); - } - - NO_INLINE Vec4 sGetVolumetricFogDistanceParams(CD3D9Renderer* rndr) - { - const CameraViewParameters& rc = rndr->GetViewParameters(); - float l, r, b, t, Ndist, Fdist; - rc.GetFrustumParams(&l, &r, &b, &t, &Ndist, &Fdist); - - Vec3 volFogCtrlParams(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - const float raymarchStart = rc.fNear; - const float raymarchEnd = (volFogCtrlParams.x > raymarchStart) ? volFogCtrlParams.x : raymarchStart + 0.0001f; - - float l2 = l * l; - float t2 = t * t; - float n2 = Ndist * Ndist; - Vec4 params; - params.x = raymarchEnd * (Ndist / sqrt(l2 + t2 + n2)); - params.y = raymarchEnd * (Ndist / sqrt(t2 + n2)); - params.z = raymarchEnd * (Ndist / sqrt(l2 + n2)); - params.w = raymarchEnd; - - return params; - } - - void sGetMotionBlurData(UFloat4* sData, CD3D9Renderer* r, [[maybe_unused]] const CRenderObject::SInstanceInfo& instInfo, SRenderPipeline& rRP) - { - CRenderObject* pObj = r->m_RP.m_pCurObject; - - Matrix44A mObjPrev; - if ((rRP.m_FlagsPerFlush & RBSI_CUSTOM_PREVMATRIX) == 0) - { - CMotionBlur::GetPrevObjToWorldMat(pObj, mObjPrev); - } - else - { - mObjPrev = *rRP.m_pPrevMatrix; - } - - float* pData = mObjPrev.GetData(); -#if defined(_CPU_SSE) && !defined(_DEBUG) - sData[0].m128 = _mm_load_ps(&pData[0]); - sData[1].m128 = _mm_load_ps(&pData[4]); - sData[2].m128 = _mm_load_ps(&pData[8]); -#else - sData[0].f[0] = pData[0]; - sData[0].f[1] = pData[1]; - sData[0].f[2] = pData[2]; - sData[0].f[3] = pData[3]; - sData[1].f[0] = pData[4]; - sData[1].f[1] = pData[5]; - sData[1].f[2] = pData[6]; - sData[1].f[3] = pData[7]; - sData[2].f[0] = pData[8]; - sData[2].f[1] = pData[9]; - sData[2].f[2] = pData[10]; - sData[2].f[3] = pData[11]; -#endif - } - - void sGetPrevObjWorldData(UFloat4* sData, SRenderPipeline& rRP) - { - CRenderObject* pObj = rRP.m_pCurObject; - - Matrix44A mObjPrev; - if ((rRP.m_FlagsPerFlush & RBSI_CUSTOM_PREVMATRIX) == 0) - { - FurBendData::Get().GetPrevObjToWorldMat(*pObj, mObjPrev); - } - else - { - mObjPrev = *rRP.m_pPrevMatrix; - } - - float* pData = mObjPrev.GetData(); -#if defined(_CPU_SSE) && !defined(_DEBUG) - sData[0].m128 = _mm_load_ps(&pData[0]); - sData[1].m128 = _mm_load_ps(&pData[4]); - sData[2].m128 = _mm_load_ps(&pData[8]); -#else - sData[0].f[0] = pData[0]; - sData[0].f[1] = pData[1]; - sData[0].f[2] = pData[2]; - sData[0].f[3] = pData[3]; - sData[1].f[0] = pData[4]; - sData[1].f[1] = pData[5]; - sData[1].f[2] = pData[6]; - sData[1].f[3] = pData[7]; - sData[2].f[0] = pData[8]; - sData[2].f[1] = pData[9]; - sData[2].f[2] = pData[10]; - sData[2].f[3] = pData[11]; -#endif - } - - NO_INLINE void sVisionParams(UFloat4* sData) - { - CRenderObject* pObj = gRenDev->m_RP.m_pCurObject; - SRenderObjData* pOD = pObj->GetObjData(); - if (pOD) - { - float fRecip = (1.0f / 255.0f); - - uint32 nParams(pOD->m_nHUDSilhouetteParams); - - sData[0].f[0] = float((nParams & 0xff000000) >> 24) * fRecip; - sData[0].f[1] = float((nParams & 0x00ff0000) >> 16) * fRecip; - sData[0].f[2] = float((nParams & 0x0000ff00) >> 8) * fRecip; - sData[0].f[3] = float((nParams & 0x000000ff)) * fRecip; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_customvisions == 2) - { - sData[0].f[3] = gEnv->pTimer->GetCurrTime() + ((float)(2 * pObj->m_Id) / 32768.0f); - } - } - else - { - sData[0].f[0] = 0; - sData[0].f[1] = 0; - sData[0].f[2] = 0; - sData[0].f[3] = 0; - } - } - - NO_INLINE void sFromObjSB(UFloat4* sData) - { - CRenderObject* pObj = gRenDev->m_RP.m_pCurObject; - if (pObj && (pObj->m_nTextureID > 0)) - { - CTexture* pTex = CTexture::GetByID(pObj->m_nTextureID); - - // SB == Scale & Bias - _MS_ALIGN(16) ColorF B = pTex->GetMinColor(); - _MS_ALIGN(16) ColorF S = pTex->GetMaxColor() - pTex->GetMinColor(); - - sData[0] = (const UFloat4&)B; - sData[1] = (const UFloat4&)S; - } - else - { - // SB == Scale & Bias - _MS_ALIGN(16) ColorF B = ColorF(0.0f); - _MS_ALIGN(16) ColorF S = ColorF(1.0f); - - sData[0] = (const UFloat4&)B; - sData[1] = (const UFloat4&)S; - } - } - - NO_INLINE void sVisionMtlParams(UFloat4* sData) - { - const Vec3& vCameraPos = gRenDev->GetViewParameters().vOrigin; - Vec3 vObjectPos = gRenDev->m_RP.m_pCurObject->GetTranslation(); - if (gRenDev->m_RP.m_pCurObject->m_ObjFlags & FOB_NEAREST) - { - vObjectPos += vCameraPos; // Nearest objects are rendered in camera space, so convert to world space - } - const float fRecipThermalViewDist = 1.0f; - - float heatAmount = 0.0f; - - sData[0].f[0] = heatAmount; - sData[0].f[0] *= 1.0f - min(1.0f, vObjectPos.GetSquaredDistance(vCameraPos) * fRecipThermalViewDist); - - if (gRenDev->m_RP.m_nPassGroupID == EFSLIST_TRANSP && gRenDev->m_RP.m_pCurObject->m_ObjFlags & FOB_REQUIRES_RESOLVE) - { - static void* pPrevNode = NULL; - static int prevFrame = 0; - static float fScale = 1.0f; - - sData[0].f[0] *= fScale; - - //Cache parameters for use in the next call, to provide a consistent value for an individual character - pPrevNode = gRenDev->m_RP.m_pCurObject->m_pRenderNode; - prevFrame = gRenDev->GetFrameID(true); - } - - sData[0].f[1] = sData[0].f[2] = 0.0f; - } - - NO_INLINE void sTexelsPerMeterInfo(UFloat4 *sData, uint32 texIdx) - { - sData[0].f[0] = sData[0].f[1] = sData[0].f[2] = sData[0].f[3] = 0; - CShaderResources* pRes = gRenDev->m_RP.m_pShaderResources; - SEfResTexture* pTextureRes = pRes ? pRes->GetTextureResource(texIdx) : nullptr; - - if (pTextureRes && pTextureRes->m_Sampler.m_pTex) - { - CTexture* pTexture = pTextureRes->m_Sampler.m_pTex; - - int texWidth(pTexture->GetWidth()); - int texHeight(pTexture->GetHeight()); - float ratio = 0.5f / CRenderer::CV_r_TexelsPerMeter; - sData[0].f[0] = (float)texWidth * ratio; - sData[0].f[1] = (float)texHeight * ratio; - } - } - - inline void sAppendClipSpaceAdaptation([[maybe_unused]] Matrix44A* __restrict pTransform) - { -#if defined(OPENGL) && CRY_OPENGL_MODIFY_PROJECTIONS -#if CRY_OPENGL_FLIP_Y - (*pTransform)(1, 0) = -(*pTransform)(1, 0); - (*pTransform)(1, 1) = -(*pTransform)(1, 1); - (*pTransform)(1, 2) = -(*pTransform)(1, 2); - (*pTransform)(1, 3) = -(*pTransform)(1, 3); -#endif //CRY_OPENGL_FLIP_Y - (*pTransform)(2, 0) = +2.0f * (*pTransform)(2, 0) - (*pTransform)(3, 0); - (*pTransform)(2, 1) = +2.0f * (*pTransform)(2, 1) - (*pTransform)(3, 1); - (*pTransform)(2, 2) = +2.0f * (*pTransform)(2, 2) - (*pTransform)(3, 2); - (*pTransform)(2, 3) = +2.0f * (*pTransform)(2, 3) - (*pTransform)(3, 3); -#endif //defined(OPENGL) && CRY_OPENGL_MODIFY_PROJECTIONS - } - - - NO_INLINE void sOceanMat(UFloat4* sData) - { - const CameraViewParameters& cam(gRenDev->GetViewParameters()); - - Matrix44A viewMat; - viewMat.m00 = cam.vX.x; - viewMat.m01 = cam.vY.x; - viewMat.m02 = cam.vZ.x; - viewMat.m03 = 0; - viewMat.m10 = cam.vX.y; - viewMat.m11 = cam.vY.y; - viewMat.m12 = cam.vZ.y; - viewMat.m13 = 0; - viewMat.m20 = cam.vX.z; - viewMat.m21 = cam.vY.z; - viewMat.m22 = cam.vZ.z; - viewMat.m23 = 0; - viewMat.m30 = 0; - viewMat.m31 = 0; - viewMat.m32 = 0; - viewMat.m33 = 1; - Matrix44A* pMat = alias_cast(&sData[0]); - *pMat = viewMat * gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_matProj; - *pMat = pMat->GetTransposed(); - sAppendClipSpaceAdaptation(pMat); - } - - // Filling texture dimensions and inverse dimensions to CB - NO_INLINE void sResInfo(UFloat4 *sData, int texIdx) // EFTT_DIFFUSE, EFTT_GLOSS, ... etc (but NOT EFTT_BUMP!) - { - sIdentityLine(sData); - CShaderResources *pRes = gRenDev->m_RP.m_pShaderResources; - if (!pRes) - return; - - SEfResTexture* pTextureRes = pRes->GetTextureResource(texIdx); - if (!pTextureRes) - return; - - ITexture* pTexture(pTextureRes->m_Sampler.m_pTex); - if (pTexture) - { - int texWidth(pTexture->GetWidth()); - int texHeight(pTexture->GetHeight()); - sData[0].f[0] = (float)texWidth; - sData[0].f[1] = (float)texHeight; - if (texWidth && texHeight) - { - sData[0].f[2] = 1.0f / (float)texWidth; - sData[0].f[3] = 1.0f / (float)texHeight; - } - } - } - - NO_INLINE void sTexelDensityParam(UFloat4 *sData, uint32 texIdx) - { - sIdentityLine(sData); - - CShaderResources *pRes = gRenDev->m_RP.m_pShaderResources; - if (!pRes) - return; - - SEfResTexture* pTextureRes = pRes->GetTextureResource(texIdx); - if (pTextureRes) - { - CRenderChunk* pRenderChunk = NULL; - int texWidth = 512; - int texHeight = 512; - int mipLevel = 0; - - IRenderElement *pRE = gRenDev->m_RP.m_pRE; - - if (pRE) - { - pRenderChunk = pRE->mfGetMatInfo(); - } - - CRenderObject *pCurObject = gRenDev->m_RP.m_pCurObject; - - if (pRenderChunk && pCurObject) - { - float weight = 1.0f; - - if (pRenderChunk->m_texelAreaDensity > 0.0f) - { - float scale = 1.0f; - - - float distance = pCurObject->m_fDistance * TANGENT30_2 / scale; - int screenHeight = gRenDev->GetHeight(); - - weight = pRenderChunk->m_texelAreaDensity * distance * distance * texWidth * texHeight * - pTextureRes->GetTiling(0) *pTextureRes->GetTiling(1) / (screenHeight * screenHeight); - } - - mipLevel = fastround_positive(0.5f * logf(max(weight, 1.0f)) / LN2); - } - - texWidth /= (1 << mipLevel); - texHeight /= (1 << mipLevel); - - if (texWidth == 0) - texWidth = 1; - if (texHeight == 0) - texHeight = 1; - - sData[0].f[0] = (float)texWidth; - sData[0].f[1] = (float)texHeight; - sData[0].f[2] = 1.0f / (float)texWidth; - sData[0].f[3] = 1.0f / (float)texHeight; - } - } - - NO_INLINE void sTexelDensityColor(UFloat4 *sData, uint32 texIdx) - { - sOneLine(sData); - - CShaderResources *pRes = gRenDev->m_RP.m_pShaderResources; - if (!pRes) - return; - - SEfResTexture* pTextureRes = pRes->GetTextureResource(texIdx); - if (pTextureRes) - { - if (CRenderer::CV_e_DebugTexelDensity == 2 || gcpRendD3D->CV_e_DebugTexelDensity == 4) - { - CRenderChunk *pRenderChunk = NULL; - int texWidth = 512; - int texHeight = 512; - int mipLevel = 0; - - IRenderElement *pRE = gRenDev->m_RP.m_pRE; - - if (pRE) - { - pRenderChunk = pRE->mfGetMatInfo(); - } - - CRenderObject *pCurObject = gRenDev->m_RP.m_pCurObject; - - if (pRenderChunk && pCurObject) - { - float weight = 1.0f; - - if (pRenderChunk->m_texelAreaDensity > 0.0f) - { - float scale = 1.0f; - - - float distance = pCurObject->m_fDistance * TANGENT30_2 / scale; - int screenHeight = gRenDev->GetHeight(); - - weight = pRenderChunk->m_texelAreaDensity * distance * distance * texWidth * texHeight * - pTextureRes->GetTiling(0) * pTextureRes->GetTiling(1) / (screenHeight * screenHeight); - } - - mipLevel = fastround_positive(0.5f * logf(max(weight, 1.0f)) / LN2); - } - - switch (mipLevel) - { - case 0: - sData[0].f[0] = 1.0f; sData[0].f[1] = 1.0f; sData[0].f[2] = 1.0f; break; - case 1: - sData[0].f[0] = 0.0f; sData[0].f[1] = 0.0f; sData[0].f[2] = 1.0f; break; - case 2: - sData[0].f[0] = 0.0f; sData[0].f[1] = 1.0f; sData[0].f[2] = 0.0f; break; - case 3: - sData[0].f[0] = 0.0f; sData[0].f[1] = 1.0f; sData[0].f[2] = 1.0f; break; - case 4: - sData[0].f[0] = 1.0f; sData[0].f[1] = 0.0f; sData[0].f[2] = 0.0f; break; - case 5: - sData[0].f[0] = 1.0f; sData[0].f[1] = 0.0f; sData[0].f[2] = 1.0f; break; - default: - sData[0].f[0] = 1.0f; sData[0].f[1] = 1.0f; sData[0].f[2] = 0.0f; break; - } - } - else - { - sData[0].f[0] = 1.0f; sData[0].f[1] = 1.0f; sData[0].f[2] = 1.0f; - } - } - } - - NO_INLINE void sNumInstructions(UFloat4* sData) - { - sData[0].f[0] = gRenDev->m_RP.m_NumShaderInstructions / CRenderer::CV_r_measureoverdrawscale / 256.0f; - } - - NO_INLINE void sAmbient(UFloat4* sData, SRenderPipeline& rRP, const CRenderObject::SInstanceInfo& instInfo) - { - sData[0].f[0] = instInfo.m_AmbColor[0]; - sData[0].f[1] = instInfo.m_AmbColor[1]; - sData[0].f[2] = instInfo.m_AmbColor[2]; - sData[0].f[3] = instInfo.m_AmbColor[3]; - - if (CShaderResources* pRes = rRP.m_pShaderResources) - { - if (pRes->m_ResFlags & MTL_FLAG_ADDITIVE) - { - sData[0].f[0] *= rRP.m_fCurOpacity; - sData[0].f[1] *= rRP.m_fCurOpacity; - sData[0].f[2] *= rRP.m_fCurOpacity; - } - } - } - NO_INLINE void sAmbientOpacity(CRenderObject* const renderObject, CD3D9Renderer* renderer, CShaderResources* shaderResources, UFloat4* sData, const CRenderObject::SInstanceInfo& instInfo) - { - SRenderPipeline& RESTRICT_REFERENCE rRP = renderer->m_RP; - - float opacity = shaderResources ? shaderResources->GetStrengthValue(EFTT_OPACITY) : 1.0f; - float opal = opacity * renderObject->m_fAlpha; - float s0 = instInfo.m_AmbColor[0]; - float s1 = instInfo.m_AmbColor[1]; - float s2 = instInfo.m_AmbColor[2]; - float s3 = opal;// object opacity - - if (shaderResources) - { - if (rRP.m_nShaderQuality == eSQ_Low) - { - ColorF diffuseColor = shaderResources->GetColorValue(EFTT_DIFFUSE); - s0 *= diffuseColor.r; - s1 *= diffuseColor.g; - s2 *= diffuseColor.b; - } - ColorF emissiveColor = shaderResources->GetColorValue(EFTT_EMITTANCE); - s0 += emissiveColor.r; - s1 += emissiveColor.g; - s2 += emissiveColor.b; - - if (shaderResources->m_ResFlags & MTL_FLAG_ADDITIVE) - { - s0 *= opacity; - s1 *= opacity; - s2 *= opacity; - } - } - - sData[0].f[0] = s0; - sData[0].f[1] = s1; - sData[0].f[2] = s2; - sData[0].f[3] = s3; - } - - NO_INLINE void sObjectAmbColComp(UFloat4* sData, const CRenderObject::SInstanceInfo& instInfo, const float fRenderQuality) - { - CD3D9Renderer* const __restrict r = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = r->m_RP; - CRenderObject* pObj = rRP.m_pCurObject; - sData[0].f[0] = instInfo.m_AmbColor[3]; - sData[0].f[1] = /*instInfo.m_AmbColor[3] * */ rRP.m_fCurOpacity * pObj->m_fAlpha; - - - sData[0].f[2] = 0.f; - sData[0].f[3] = fRenderQuality * (1.0f / 65535.0f); - } - - NO_INLINE void sMotionBlurInfo([[maybe_unused]] UFloat4* sData, [[maybe_unused]] SRenderPipeline& rRP) - { -#ifdef PARTICLE_MOTION_BLUR - SRenderObjData* pOD = rRP.m_pCurObject->GetObjData(); - if (pOD && pOD->m_pParticleParams) - { - if (pOD->m_pParticleParams->eFacing().Camera) - { - sData[0].f[0] = pOD->m_pParticleParams->fMotionBlurCamStretchScale; - sData[0].f[1] = pOD->m_pParticleParams->fMotionBlurStretchScale; - } - else - { - sData[0].f[0] = infosData[0].f1] = 0; - } - sData[0].f[2] = pOD->m_pParticleParams->fMotionBlurScale * 0.2f; - } -#endif - } - - NO_INLINE void sWrinklesMask(UFloat4* sData, SRenderPipeline& rRP, uint index) - { - static uint8 WrinkleMask[3] = { ECGP_PI_WrinklesMask0, ECGP_PI_WrinklesMask1, ECGP_PI_WrinklesMask2 }; - - SRenderObjData* pOD = rRP.m_pCurObject->GetObjData(); - if (pOD) - { - if (pOD->m_pShaderParams) - { - if (SShaderParam::GetValue(WrinkleMask[index], const_cast*>(pOD->m_pShaderParams), &sData[0].f[0], 4) == false) - { - sData[0].f[0] = 0.f; - sData[0].f[1] = 0.f; - sData[0].f[2] = 0.f; - sData[0].f[3] = 0.f; - } - } - else - { - sData[0].f[0] = 0.f; - sData[0].f[1] = 0.f; - sData[0].f[2] = 0.f; - sData[0].f[3] = 0.f; - } - } - } - - NO_INLINE void sAlphaTest(UFloat4* sData, const float dissolveRef) - { - SRenderPipeline& RESTRICT_REFERENCE rRP = gRenDev->m_RP; - - sData[0].f[0] = dissolveRef * (1.0f / 255.0f); - sData[0].f[1] = (rRP.m_pCurObject->m_ObjFlags & FOB_DISSOLVE_OUT) ? 1.0f : -1.0f; - sData[0].f[2] = 0.0f; - sData[0].f[3] = 0.0f; - } - - NO_INLINE void sParticleEmissiveColor(UFloat4* data, SRenderPipeline& renderPipeline) - { - if (renderPipeline.m_pShaderResources) - { - ColorF finalEmittance = renderPipeline.m_pShaderResources->GetFinalEmittance(); - data[0].f[0] = finalEmittance.r; - data[0].f[1] = finalEmittance.g; - data[0].f[2] = finalEmittance.b; - data[0].f[3] = 0.0f; - } - else - { - sZeroLine(data); - } - } - - NO_INLINE void sAvgFogVolumeContrib(UFloat4* sData) - { - CD3D9Renderer* const __restrict r = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = r->m_RP; - CRenderObject* pObj = rRP.m_pCurObject; - SRenderObjData* pOD = r->FX_GetObjData(pObj, rRP.m_nProcessThreadID); - if (!pOD || pOD->m_FogVolumeContribIdx[rRP.m_nProcessThreadID] == (uint16)-1) - { - sData[0].f[0] = sData[0].f[1] = sData[0].f[2] = 0.0f; - sData[0].f[3] = 1.0f; - return; - } - SFogVolumeData fogVolData; - ColorF& contrib = fogVolData.fogColor; - r->GetFogVolumeContribution(pOD->m_FogVolumeContribIdx[rRP.m_nProcessThreadID], fogVolData); - // Pre-multiply alpha (saves 1 instruction in pixel shader) - sData[0].f[0] = contrib.r * (1 - contrib.a); - sData[0].f[1] = contrib.g * (1 - contrib.a); - sData[0].f[2] = contrib.b * (1 - contrib.a); - sData[0].f[3] = contrib.a; - // Pass min & max of the aabb and cvar value. - sData[1].f[0] = fogVolData.avgAABBox.min.x; - sData[1].f[1] = fogVolData.avgAABBox.min.y; - sData[1].f[2] = fogVolData.avgAABBox.min.z; - static ICVar* pCVarFogVolumeShadingQuality = gEnv->pConsole->GetCVar("e_FogVolumeShadingQuality"); - - sData[1].f[3] = (pCVarFogVolumeShadingQuality->GetIVal() && fogVolData.avgAABBox.GetRadius() > 0.001f) ? 1.0f : 0.0f; - - sData[2].f[0] = fogVolData.avgAABBox.max.x; - sData[2].f[1] = fogVolData.avgAABBox.max.y; - sData[2].f[2] = fogVolData.avgAABBox.max.z; - sData[2].f[3] = (fogVolData.avgAABBox.GetRadius() > 0.001f) ? 1.0f : 0.0f; - - sData[3].f[0] = fogVolData.m_heightFallOffBasePoint.x; - sData[3].f[1] = fogVolData.m_heightFallOffBasePoint.y; - sData[3].f[2] = fogVolData.m_heightFallOffBasePoint.z; - sData[3].f[3] = fogVolData.m_densityOffset; - - sData[4].f[0] = fogVolData.m_heightFallOffDirScaled.x; - sData[4].f[1] = fogVolData.m_heightFallOffDirScaled.y; - sData[4].f[2] = fogVolData.m_heightFallOffDirScaled.z; - sData[4].f[3] = fogVolData.m_globalDensity; - - sData[5].f[0] = Overlap::Point_AABB(r->GetViewParameters().vOrigin, fogVolData.avgAABBox); - - } - - NO_INLINE void sDLightsInfo(UFloat4* sData) - { - COMPILE_TIME_ASSERT(sizeof(s_ConstantScratchBuffer) >= (sizeof(SLightVolume::SLightData) * LIGHTVOLUME_MAXLIGHTS)); - PROFILE_FRAME(DLightsInfo_UpdateCB); - - CD3D9Renderer* const __restrict r = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = r->m_RP; - SRenderObjData* pOD = r->FX_GetObjData(rRP.m_pCurObject, rRP.m_nProcessThreadID); - int nVols = 0; - if (pOD->m_LightVolumeId > 0) - { - assert((uint32)pOD->m_LightVolumeId - 1 < r->m_nNumVols); - SLightVolume::LightDataVector& lvData = r->m_pLightVols[pOD->m_LightVolumeId - 1].pData; - nVols = lvData.size(); - assert(nVols <= LIGHTVOLUME_MAXLIGHTS); - if (nVols) - { - memcpy(&sData[0], &lvData[0], sizeof(SLightVolume::SLightData) * nVols); - } - } - memset((char*)sData + sizeof(SLightVolume::SLightData) * nVols, 0, sizeof(SLightVolume::SLightData) * (LIGHTVOLUME_MAXLIGHTS - nVols)); - } - - NO_INLINE void sGetTempData(UFloat4* sData, CD3D9Renderer* r, const SCGParam* ParamBind) - { - sData[0].f[0] = r->m_cEF.m_TempVecs[ParamBind->m_nID].x; - sData[0].f[1] = r->m_cEF.m_TempVecs[ParamBind->m_nID].y; - sData[0].f[2] = r->m_cEF.m_TempVecs[ParamBind->m_nID].z; - sData[0].f[3] = r->m_cEF.m_TempVecs[ParamBind->m_nID].w; - } - - NO_INLINE void sRTRect(UFloat4* sData, CD3D9Renderer* r) - { - sData[0].f[0] = r->m_cEF.m_RTRect.x; - sData[0].f[1] = r->m_cEF.m_RTRect.y; - sData[0].f[2] = r->m_cEF.m_RTRect.z; - sData[0].f[3] = r->m_cEF.m_RTRect.w; - } - - bool sCanSet(const STexSamplerRT* pSM, CTexture* pTex) - { - assert(pTex); - if (!pTex) - { - return false; - } - if (!pSM->m_bGlobal) - { - return true; - } - CD3D9Renderer* pRD = gcpRendD3D; - if (pRD->m_pNewTarget[0] && pRD->m_pNewTarget[0]->m_pTex == pTex) - { - return false; - } - if (pRD->m_pNewTarget[1] && pRD->m_pNewTarget[1]->m_pTex == pTex) - { - return false; - } - return true; - } - - void LogParameter( - EHWShaderClass shaderClass, - const SCGParam* parameter, - AZ::u32 componentIndex = 0) - { -#ifdef DO_RENDERLOG - static const char* s_shaderClassNames[] = { "VS", "PS", "GS", "CS", "DS", "HS" }; - static const char* s_componentNames[] = { "x", "y", "z", "w" }; - - CD3D9Renderer* const __restrict r = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = r->m_RP; - if (CRenderer::CV_r_log >= 3) - { - ECGParam parameterType = ECGParam((parameter->m_eCGParamType >> (componentIndex << 3)) & 0xff); - if (parameter->m_Flags & PF_SINGLE_COMP) - { - r->Logv( - SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], - " Set %s parameter '%s:%s' (%d vectors, reg: %d)\n", - s_shaderClassNames[shaderClass], - parameter->m_Name.c_str(), - r->m_cEF.mfGetShaderParamName(parameterType), - parameter->m_RegisterCount, - parameter->m_RegisterOffset); - } - else - { - r->Logv( - SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], - " Set %s parameter '%s:%s' (%d vectors, reg: %d)\n", - s_shaderClassNames[shaderClass], - parameter->m_Name.c_str(), - r->m_cEF.mfGetShaderParamName(parameterType), - parameter->m_RegisterCount, - parameter->m_RegisterOffset, - s_componentNames[componentIndex]); - } - } -#endif - } - - void UpdateConstants( - EHWShaderClass shaderClass, - [[maybe_unused]] EConstantBufferShaderSlot shaderSlot, - const SCGParam* parameters, - AZ::u32 parameterCount, - void* outputData) - { - DETAILED_PROFILE_MARKER("mfSetParameters"); - PROFILE_FRAME(Shader_SetParams); - - if (!parameters) - { - return; - } - - CD3D9Renderer* r = gcpRendD3D; - SRenderPipeline& rRP = r->m_RP; - - for (AZ::u32 parameterIdx = 0; parameterIdx < parameterCount; parameterIdx++) - { - const SCGParam* parameter = ¶meters[parameterIdx]; - AZ::u32 registerCount = parameter->m_RegisterCount; - AZ::u32 registerOffset = parameter->m_RegisterOffset; - AZ::u32 parameterTypeFlags = (uint32)parameter->m_eCGParamType; - AZ::u32 parameterType = parameterTypeFlags & 0xFF; - - UFloat4* result = s_ConstantScratchBuffer; - - for (AZ::u32 componentIndex = 0; componentIndex < 4; componentIndex++) - { - LogParameter(shaderClass, parameter, componentIndex); - - switch (parameterType) - { - case ECGP_PB_ScreenSize: - sGetScreenSize(result, r); - break; - - case ECGP_Matr_PB_TerrainBase: - sGetTerrainBase(result, r); - break; - case ECGP_Matr_PB_TerrainLayerGen: - sGetTerrainLayerGen(result, r); - break; - - case ECGP_PB_BlendTerrainColInfo: - { - SRenderObjData* objectData = rRP.m_pCurObject->GetObjData(); - if (objectData) - { - float* pObjTmpVars = objectData->m_fTempVars; - - result[0].f[0] = pObjTmpVars[3]; // fTexOffsetX - result[0].f[1] = pObjTmpVars[4]; // fTexOffsetY - result[0].f[2] = pObjTmpVars[5]; // fTexScale - result[0].f[3] = pObjTmpVars[8]; // Obj view distance - } - } - break; - - case ECGP_Matr_PB_Temp4_0: - case ECGP_Matr_PB_Temp4_1: - case ECGP_Matr_PB_Temp4_2: - case ECGP_Matr_PB_Temp4_3: - memcpy(result, &r->m_TempMatrices[parameter->m_eCGParamType - ECGP_Matr_PB_Temp4_0][parameter->m_nID], sizeof(Matrix44)); - break; - - case ECGP_PB_FromRE: - { - IRenderElement* pRE = rRP.m_pRE; - if (!pRE || !pRE->GetCustomData()) - { - result[0].f[componentIndex] = 0; - } - else - { - result[0].f[componentIndex] = reinterpret_cast(pRE->GetCustomData())[(parameter->m_nID >> (componentIndex * 8)) & 0xff]; - } - break; - } - case ECGP_PB_FromObjSB: - sFromObjSB(result); - break; - - case ECGP_PB_GmemStencilValue: - { - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - uint32 stencilRef = CRenderer::CV_r_VisAreaClipLightsPerPixel ? 0 : (rRP.m_RIs[0][0]->nStencRef | BIT_STENCIL_INSIDE_CLIPVOLUME); - // Here we check if an object can receive decals. - bool bObjectAcceptsDecals = !(rRP.m_pCurObject->m_NoDecalReceiver); - if (bObjectAcceptsDecals) - { - stencilRef |= (!(rRP.m_pCurObject->m_ObjFlags & FOB_DYNAMIC_OBJECT) || CRenderer::CV_r_deferredDecalsOnDynamicObjects ? BIT_STENCIL_RESERVED : 0); - } - result[0].f[0] = azlossy_caster(stencilRef); - result[0].f[1] = 0.0f; - result[0].f[2] = 0.0f; - result[0].f[3] = 0.0f; - } - else - { - CRY_ASSERT_MESSAGE(false, "Warning: Trying to use GMEM Stencil attribute in a shader but GMEM is disabled. Value will not be set."); - } - break; - } - - case ECGP_PB_TempData: - sGetTempData(result, r, parameter); - break; - - case ECGP_Matr_PB_UnProjMatrix: - { - Matrix44A* pMat = alias_cast(&result[0]); - *pMat = rRP.m_TI[rRP.m_nProcessThreadID].m_matView * rRP.m_TI[rRP.m_nProcessThreadID].m_matProj; - *pMat = pMat->GetInverted(); - *pMat = pMat->GetTransposed(); - break; - } - - case ECGP_PB_DLightsInfo: - sDLightsInfo(result); - break; - - case ECGP_PB_ObjVal: - { - SRenderObjData* objectData = rRP.m_pCurObject->GetObjData(); - if (objectData) - { - result[0].f[componentIndex] = - reinterpret_cast(objectData->m_fTempVars)[(parameter->m_nID >> (componentIndex * 8)) & 0xff]; - } - } - break; - case ECGP_PB_IrregKernel: - sGetIrregKernel(result, r); - break; - case ECGP_PB_TFactor: - result[0].f[0] = r->m_RP.m_CurGlobalColor[0]; - result[0].f[1] = r->m_RP.m_CurGlobalColor[1]; - result[0].f[2] = r->m_RP.m_CurGlobalColor[2]; - result[0].f[3] = r->m_RP.m_CurGlobalColor[3]; - break; - case ECGP_PB_RTRect: - sRTRect(result, r); - break; - case ECGP_PB_Scalar: - assert(parameter->m_pData); - if (parameter->m_pData) - { - result[0].f[componentIndex] = parameter->m_pData->d.fData[componentIndex]; - } - break; - - case ECGP_PB_ClipVolumeParams: - result[0].f[0] = rRP.m_pCurObject->m_nClipVolumeStencilRef + 1.0f; - result[0].f[1] = result[0].f[2] = result[0].f[3] = 0; - break; - - /// Used by Sketch.cfx - case ECGP_PB_ResInfoDiffuse: - sResInfo(result, EFTT_DIFFUSE); - break; - case ECGP_PB_TexelDensityParam: - sTexelDensityParam(result, EFTT_DIFFUSE); - break; - case ECGP_PB_TexelDensityColor: - sTexelDensityColor(result, EFTT_DIFFUSE); - break; - case ECGP_PB_TexelsPerMeterInfo: - sTexelsPerMeterInfo(result, EFTT_DIFFUSE); - break; - ///! - - case ECGP_PB_VisionMtlParams: - sVisionMtlParams(result); - break; - - /// Water.cfx / WaterVolume.cfx - case ECGP_PB_WaterRipplesLookupParams: - if (CPostEffectsMgr* pPostEffectsMgr = PostEffectMgr()) - { - if (CWaterRipples* pWaterRipplesTech = (CWaterRipples*)pPostEffectsMgr->GetEffect(ePFX_WaterRipples)) - { - result[0].f[0] = pWaterRipplesTech->GetLookupParams().x; - result[0].f[1] = pWaterRipplesTech->GetLookupParams().y; - result[0].f[2] = pWaterRipplesTech->GetLookupParams().z; - result[0].f[3] = pWaterRipplesTech->GetLookupParams().w; - } - } - break; - ///! - - case ECGP_PB_SkinningExtraWeights: - { - if (rRP.m_pRE->mfGetType() == eDATA_Mesh && ((CREMeshImpl*)rRP.m_pRE)->m_pRenderMesh->m_extraBonesBuffer.m_numElements > 0) - { - result[0].f[0] = 1.0f; - result[0].f[1] = 1.0f; - result[0].f[2] = 1.0f; - result[0].f[3] = 1.0f; - } - else - { - result[0].f[0] = 0.0f; - result[0].f[1] = 0.0f; - result[0].f[2] = 0.0f; - result[0].f[3] = 0.0f; - } - break; - } - - case 0: - break; - - default: - assert(0); - break; - } - if (parameter->m_Flags & PF_SINGLE_COMP) - { - break; - } - - parameterTypeFlags >>= 8; - } - - AzRHI::SIMDCopy(&reinterpret_cast(outputData)[registerOffset], s_ConstantScratchBuffer, registerCount); - } - } -} - -void CHWShader_D3D::UpdatePerInstanceConstants( - EHWShaderClass shaderClass, - const SCGParam* parameters, - AZ::u32 parameterCount, - void* outputData) -{ - DETAILED_PROFILE_MARKER("UpdatePerInstanceConstants"); - - CD3D9Renderer* const __restrict r = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = r->m_RP; - CRenderObject* const __restrict pObj = rRP.m_pCurObject; - CShaderResources* shaderResources = rRP.m_pShaderResources; - - UFloat4* result = s_ConstantScratchBuffer; - AZ_Assert(pObj, "Trying to set PI parameters with NULL object"); - - // precache int to float conversions for some parameters - float objDissolveRef = (float)(pObj->m_DissolveRef); - float objRenderQuality = (float)(pObj->m_nRenderQuality); - const CRenderObject::SInstanceInfo& instanceInfo = pObj->m_II; - - for (AZ::u32 parameterIdx = 0; parameterIdx < parameterCount; parameterIdx++) - { - const SCGParam* parameter = ¶meters[parameterIdx]; - - // Not activated yet for this shader - if (parameter->m_BindingSlot < 0) - { - continue; - } - - assert(parameter->m_Flags & PF_SINGLE_COMP); - LogParameter(shaderClass, parameter); - - switch (parameter->m_eCGParamType) - { - case ECGP_SI_AmbientOpacity: - sAmbientOpacity(pObj, r, shaderResources, result, instanceInfo); - break; - case ECGP_SI_BendInfo: - sGetBendInfo(pObj, FrameType::Current, result, r); - break; - case ECGP_SI_PrevBendInfo: - sGetBendInfo(pObj, FrameType::Previous, result, r); - break; - case ECGP_SI_ObjectAmbColComp: - sObjectAmbColComp(result, instanceInfo, objRenderQuality); - break; - case ECGP_SI_AlphaTest: - sAlphaTest(result, objDissolveRef); - break; - - case ECGP_Matr_PI_Obj_T: - { - Store(result, instanceInfo.m_Matrix); - } - break; - case ECGP_Matr_PI_ViewProj: - { - mathMatrixMultiply_Transp2(&result[4].f[0], r->m_ViewProjMatrix.GetData(), instanceInfo.m_Matrix.GetData(), g_CpuFlags); - TransposeAndStore(result, *alias_cast(&result[4])); - sAppendClipSpaceAdaptation(alias_cast(&result[0])); - } - break; - case ECGP_PI_Ambient: - sAmbient(result, rRP, instanceInfo); - break; - case ECGP_PI_MotionBlurInfo: - sMotionBlurInfo(result, rRP); - break; - - case ECGP_PI_ParticleEmissiveColor: - sParticleEmissiveColor(result, rRP); - break; - - case ECGP_PI_WrinklesMask0: - sWrinklesMask(result, rRP, 0); - break; - case ECGP_PI_WrinklesMask1: - sWrinklesMask(result, rRP, 1); - break; - case ECGP_PI_WrinklesMask2: - sWrinklesMask(result, rRP, 2); - break; - - case ECGP_PI_AvgFogVolumeContrib: - sAvgFogVolumeContrib(result); - break; - // Remove ECGP_Matr_PI_Composite after we refactor Set2DMode and m_matView and m_matProj - // For now ECGP_Matr_PI_Composite is not used in 3D object rendering shaders. - case ECGP_Matr_PI_Composite: - { - const Matrix44A viewProj = rRP.m_TI[rRP.m_nProcessThreadID].m_matView * rRP.m_TI[rRP.m_nProcessThreadID].m_matProj; - TransposeAndStore(result, viewProj); - } - break; - case ECGP_PI_MotionBlurData: - sGetMotionBlurData(result, r, instanceInfo, rRP); - - break; - case ECGP_PI_PrevObjWorldMatrix: - sGetPrevObjWorldData(result, rRP); - break; - case ECGP_Matr_PI_TexMatrix: - sGetTexMatrix(result, r, parameter); - break; - case ECGP_Matr_PI_TCGMatrix: - { - SEfResTexture* pRT = rRP.m_ShaderTexResources[parameter->m_nID]; - if (pRT && pRT->m_Ext.m_pTexModifier) - { - Store(result, pRT->m_Ext.m_pTexModifier->m_TexGenMatrix); - } - else - { - Store(result, r->m_IdentityMatrix); - } - } - break; - case ECGP_PI_OSCameraPos: - { - Matrix44A* pMat1 = alias_cast(&result[4]); - Matrix44A* pMat2 = alias_cast(&result[0]); - *pMat1 = instanceInfo.m_Matrix.GetTransposed(); - *pMat2 = fabs(pMat1->Determinant()) > 1e-6 ? (*pMat1).GetInverted() : Matrix44(IDENTITY); - - // Respect Camera-Space rendering - Vec3 cameraPosObjectSpace; - Vec3 cameraPos = (rRP.m_pCurObject->m_ObjFlags & FOB_NEAREST) ? ZERO : r->GetViewParameters().vOrigin; - TransformPosition(cameraPosObjectSpace, cameraPos, *pMat2); - - result[0].f[0] = cameraPosObjectSpace.x; - result[0].f[1] = cameraPosObjectSpace.y; - result[0].f[2] = cameraPosObjectSpace.z; - result[0].f[3] = 1.f; - } - break; - case ECGP_PI_VisionParams: - sVisionParams(result); - break; - case ECGP_PI_NumInstructions: - sNumInstructions(result); - break; - case ECGP_Matr_PI_OceanMat: - sOceanMat(result); - break; - - case ECGP_PI_FurLODInfo: - { - // FurLODInfo contains LOD values for the current object to adjust fur rendering: - // x - Current object's first LOD distance - // y - Current object's max view distance - // Presently, this is used to control self-shadowing as a function of distance and LOD. - if (rRP.m_pCurObject) - { - if (IRenderNode* pRenderNode = rRP.m_pCurObject->m_pRenderNode) - { - /// Fix it! should not access the memory pointed by IRenderNode in render thread. - // Scale number of shell passes by object's distance to camera and LOD ratio - float lodRatio = pRenderNode->GetLodRatioNormalized(); - if (lodRatio > 0.0f) - { - static ICVar* pTargetSize = gEnv->pConsole->GetCVar("e_LodFaceAreaTargetSize"); - if (pTargetSize) - { - lodRatio *= pTargetSize->GetFVal(); - } - } - - float maxDistance = CD3D9Renderer::CV_r_FurMaxViewDist * pRenderNode->GetViewDistanceMultiplier(); - float lodDistance = AZ::GetClamp(pRenderNode->GetFirstLodDistance() / lodRatio, 0.0f, maxDistance); - - result[0].f[0] = lodDistance; - result[0].f[1] = maxDistance; - } - } - break; - } - - case ECGP_PI_FurParams: - { - // FurParams contains common information for fur rendering: - // x, y, z - wind direction and strength in world space, for wind bending of fur - // w - distance of current shell between base and outermost shell, in the range [0, 1] - AABB instanceBboxWorld(AABB::RESET); - Vec3 vWindWorld(ZERO); - if (rRP.m_pRE) - { - rRP.m_pRE->mfGetBBox(instanceBboxWorld.min, instanceBboxWorld.max); - instanceBboxWorld.min = instanceInfo.m_Matrix * instanceBboxWorld.min; - instanceBboxWorld.max = instanceInfo.m_Matrix * instanceBboxWorld.max; - } - if (instanceBboxWorld.IsReset()) - { - vWindWorld = gEnv->p3DEngine->GetGlobalWind(false); - } - else - { - vWindWorld = gEnv->p3DEngine->GetWind(instanceBboxWorld, false); - } - - result[0].f[0] = vWindWorld.x; - result[0].f[1] = vWindWorld.y; - result[0].f[2] = vWindWorld.z; - result[0].f[3] = FurPasses::GetInstance().GetFurShellPassPercent(); - break; - } - - default: - assert(0); - break; - } - - const AZ::u32 registerCount = parameter->m_RegisterCount; - const AZ::u32 registerOffset = parameter->m_RegisterOffset; - AzRHI::SIMDCopy(&reinterpret_cast(outputData)[registerOffset], result, registerCount); - } -} - -void CHWShader_D3D::UpdatePerInstanceConstantBuffer() -{ - if (!m_pCurInst) - { - return; - } - SHWSInstance* pInst = m_pCurInst; - if (pInst->m_nParams[1] >= 0) - { - SCGParamsGroup& Group = CGParamManager::s_Groups[pInst->m_nParams[1]]; - - void* mappedData = AzRHI::ConstantBufferCache::GetInstance().MapConstantBuffer( - m_eSHClass, eConstantBufferShaderSlot_PerInstanceLegacy, pInst->m_nMaxVecs[1]); - UpdatePerInstanceConstants(m_eSHClass, Group.pParams, Group.nParams, mappedData); - } -} - -void CHWShader_D3D::UpdatePerBatchConstantBuffer() -{ - if (!m_pCurInst) - { - return; - } - SHWSInstance* pInst = m_pCurInst; - if (pInst->m_nParams[0] >= 0) - { - SCGParamsGroup& Group = CGParamManager::s_Groups[pInst->m_nParams[0]]; - - void* mappedData = AzRHI::ConstantBufferCache::GetInstance().MapConstantBuffer( - m_eSHClass, eConstantBufferShaderSlot_PerBatch, pInst->m_nMaxVecs[0]); - UpdateConstants(m_eSHClass, eConstantBufferShaderSlot_PerBatch, Group.pParams, Group.nParams, mappedData); - } -} - -void CHWShader_D3D::UpdatePerViewConstantBuffer() -{ - CD3D9Renderer* rd = gcpRendD3D; - rd->GetGraphicsPipeline().UpdatePerViewConstantBuffer(); - rd->GetGraphicsPipeline().BindPerViewConstantBuffer(); -} - -void CD3D9Renderer::UpdatePerFrameParameters() -{ - // Per frame - hardcoded/fast - update of commonly used data - feel free to improve this - int nThreadID = m_RP.m_nFillThreadID; - uint32 nFrameID = gRenDev->m_RP.m_TI[nThreadID].m_nFrameUpdateID; - PerFrameParameters& PF = gRenDev->m_RP.m_TI[nThreadID].m_perFrameParameters; - if (PF.m_FrameID == nFrameID || SRendItem::m_RecurseLevel[nThreadID] > 0) - { - return; - } - - PF.m_FrameID = nFrameID; - - I3DEngine* p3DEngine = gEnv->p3DEngine; - if (p3DEngine == nullptr) - { - return; - } - - PF.m_WaterLevel = Vec3(OceanToggle::IsActive() ? OceanRequest::GetOceanLevel() : p3DEngine->GetWaterLevel()); - - { - // Caustics are done with projection from sun - ence they update too fast with regular - // sun direction. Use a smooth sun direction update instead to workaround this - Vec3 realtimeSunDirNormalized = p3DEngine->GetRealtimeSunDirNormalized(); - - const float snapshot = 0.98f; - float dotProduct = fabs(PF.m_CausticsSunDirection.Dot(realtimeSunDirNormalized)); - if (dotProduct < snapshot) - { - PF.m_CausticsSunDirection = realtimeSunDirNormalized; - } - - PF.m_CausticsSunDirection += (realtimeSunDirNormalized - PF.m_CausticsSunDirection) * 0.005f * gEnv->pTimer->GetFrameTime(); - PF.m_CausticsSunDirection.Normalize(); - } - - { - Vec4 hdrSetupParams[5]; - p3DEngine->GetHDRSetupParams(hdrSetupParams); - // Film curve setup - PF.m_HDRParams = Vec4( - hdrSetupParams[0].x * 6.2f, - hdrSetupParams[0].y * 0.5f, - hdrSetupParams[0].z * 0.06f, - 1.0f); - } - - { - Vec3 multiplier; - p3DEngine->GetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER, multiplier); - PF.m_SunSpecularMultiplier = multiplier.x; - } - - // Set energy indicator representing the sun intensity compared to noon. - Vec3 dayNightIndicators; - p3DEngine->GetGlobalParameter(E3DPARAM_DAY_NIGHT_INDICATOR, dayNightIndicators); - PF.m_MidDayIndicator = dayNightIndicators.y; - - p3DEngine->GetGlobalParameter(E3DPARAM_CLOUDSHADING_SUNCOLOR, PF.m_CloudShadingColorSun); - p3DEngine->GetGlobalParameter(E3DPARAM_CLOUDSHADING_SKYCOLOR, PF.m_CloudShadingColorSky); - - { - //Prevent division by Zero if there's no terrain system. - AZ::Aabb terrainAabb = AZ::Aabb::CreateFromMinMax(AZ::Vector3::CreateZero(), AZ::Vector3::CreateOne()); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); - const float heightMapSizeX = terrainAabb.GetXExtent(); - const float heightMapSizeY = terrainAabb.GetYExtent(); - - Vec3 cloudShadowOffset = m_cloudShadowSpeed * gEnv->pTimer->GetCurrTime(); - cloudShadowOffset.x -= (int)cloudShadowOffset.x; - cloudShadowOffset.y -= (int)cloudShadowOffset.y; - PF.m_CloudShadowAnimParams = Vec4(m_cloudShadowTiling / heightMapSizeX, -m_cloudShadowTiling / heightMapSizeY, cloudShadowOffset.x, -cloudShadowOffset.y); - PF.m_CloudShadowParams = Vec4(0, 0, m_cloudShadowInvert ? 1.0f : 0.0f, m_cloudShadowBrightness); - } - - { - float* projMatrix = (float*)&gcpRendD3D->m_RP.m_TI[nThreadID].m_matProj; - float scalingFactor = clamp_tpl(CRenderer::CV_r_ZFightingDepthScale, 0.1f, 1.0f); - - PF.m_DecalZFightingRemedy.x = scalingFactor; // scaling factor to pull decal in front - PF.m_DecalZFightingRemedy.y = (float)((1.0f - scalingFactor) * projMatrix[4 * 3 + 2]); // correction factor for homogeneous z after scaling is applied to xyzw { = ( 1 - v[0] ) * zMappingRageBias } - PF.m_DecalZFightingRemedy.z = clamp_tpl(CRenderer::CV_r_ZFightingExtrude, 0.0f, 1.0f); - } - - PF.m_VolumetricFogParams = sGetVolumetricFogParams(gcpRendD3D); - PF.m_VolumetricFogRampParams = sGetVolumetricFogRampParams(); - - sGetFogColorGradientConstants(PF.m_VolumetricFogColorGradientBase, PF.m_VolumetricFogColorGradientDelta); - PF.m_VolumetricFogColorGradientParams = sGetFogColorGradientParams(); - PF.m_VolumetricFogColorGradientRadial = sGetFogColorGradientRadial(gcpRendD3D); - PF.m_VolumetricFogSamplingParams = sGetVolumetricFogSamplingParams(gcpRendD3D); - PF.m_VolumetricFogDistributionParams = sGetVolumetricFogDistributionParams(gcpRendD3D); - PF.m_VolumetricFogScatteringParams = sGetVolumetricFogScatteringParams(gcpRendD3D); - PF.m_VolumetricFogScatteringBlendParams = sGetVolumetricFogScatteringBlendParams(gcpRendD3D); - PF.m_VolumetricFogScatteringColor = sGetVolumetricFogScatteringColor(gcpRendD3D); - PF.m_VolumetricFogScatteringSecondaryColor = sGetVolumetricFogScatteringSecondaryColor(gcpRendD3D); - PF.m_VolumetricFogHeightDensityParams = sGetVolumetricFogHeightDensityParams(gcpRendD3D); - PF.m_VolumetricFogHeightDensityRampParams = sGetVolumetricFogHeightDensityRampParams(gcpRendD3D); - PF.m_VolumetricFogDistanceParams = sGetVolumetricFogDistanceParams(gcpRendD3D); -} - -void CD3D9Renderer::ForceUpdateGlobalShaderParameters() -{ - UpdatePerFrameParameters(); - - gRenDev->m_pRT->EnqueueRenderCommand([this]() - { - FX_PreRender(1); - CHWShader_D3D::UpdatePerFrameResourceGroup(); - }); -} - -void CHWShader_D3D::UpdatePerFrameResourceGroup() -{ - static std::vector s_textures; - static std::vector s_samplers; - s_textures.assign(s_PF_Textures.begin(), s_PF_Textures.end()); - s_samplers.assign(s_PF_Samplers.begin(), s_PF_Samplers.end()); - mfSetTextures(s_textures, eHWSC_Pixel); - mfSetSamplers_Old(s_samplers, eHWSC_Pixel); - - const PerFrameParameters& PF = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_perFrameParameters; - CD3D9Renderer* const __restrict rd = gcpRendD3D; - rd->GetGraphicsPipeline().UpdatePerFrameConstantBuffer(PF); - rd->GetGraphicsPipeline().BindPerFrameConstantBuffer(); -} - -void CHWShader_D3D::UpdatePerMaterialConstantBuffer() -{ - DETAILED_PROFILE_MARKER("UpdatePerMaterialConstantBuffer"); - CD3D9Renderer* const __restrict rd = gcpRendD3D; - CShaderResources* const __restrict shaderResources = rd->m_RP.m_pShaderResources; - CDeviceManager& deviceManager = rd->m_DevMan; - if (shaderResources) - { - AzRHI::ConstantBuffer* constantBuffer = shaderResources->GetConstantBuffer(); - deviceManager.BindConstantBuffer(eHWSC_Vertex, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - deviceManager.BindConstantBuffer(eHWSC_Pixel, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - - if (s_pCurInstDS) - { - deviceManager.BindConstantBuffer(eHWSC_Domain, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - } - if (s_pCurInstHS) - { - deviceManager.BindConstantBuffer(eHWSC_Hull, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - } - if (s_pCurInstGS) - { - deviceManager.BindConstantBuffer(eHWSC_Geometry, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - } - if (s_pCurInstCS) - { - deviceManager.BindConstantBuffer(eHWSC_Compute, constantBuffer, eConstantBufferShaderSlot_PerMaterial); - } - } -} - -void CHWShader_D3D::mfCommitParamsGlobal() -{ - DETAILED_PROFILE_MARKER("mfCommitParamsGlobal"); - PROFILE_FRAME(CommitGlobalShaderParams); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - if (rRP.m_PersFlags2 & (RBPF2_COMMIT_PF | RBPF2_COMMIT_CM)) - { - rRP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - UpdatePerViewConstantBuffer(); - } -} - -void CHWShader_D3D::mfSetGlobalParams() -{ - AZ_TRACE_METHOD(); - DETAILED_PROFILE_MARKER("mfSetGlobalParams"); -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "--- Set global shader constants...\n"); - } -#endif - - Vec4 v; - CD3D9Renderer* r = gcpRendD3D; - - r->m_RP.m_PersFlags2 |= RBPF2_COMMIT_PF | RBPF2_COMMIT_CM; - r->m_RP.m_nCommitFlags |= FC_GLOBAL_PARAMS; -} - -void CHWShader_D3D::mfSetCameraParams() -{ - DETAILED_PROFILE_MARKER("mfSetCameraParams"); -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "--- Set camera shader constants...\n"); - } -#endif - gRenDev->m_RP.m_PersFlags2 |= RBPF2_COMMIT_PF | RBPF2_COMMIT_CM; - gRenDev->m_RP.m_nCommitFlags |= FC_GLOBAL_PARAMS; -} - -#if !defined(_RELEASE) -void CHWShader_D3D::LogSamplerTextureMismatch(const CTexture* pTex, const STexSamplerRT* pSampler, EHWShaderClass shaderClass, const char* pMaterialName) -{ - if (pTex && pSampler) - { - const CHWShader_D3D::SHWSInstance* pInst = 0; - switch (shaderClass) - { - case eHWSC_Vertex: - pInst = s_pCurInstVS; - break; - case eHWSC_Pixel: - pInst = s_pCurInstPS; - break; - case eHWSC_Geometry: - pInst = s_pCurInstGS; - break; - case eHWSC_Compute: - pInst = s_pCurInstCS; - break; - case eHWSC_Domain: - pInst = s_pCurInstDS; - break; - case eHWSC_Hull: - pInst = s_pCurInstHS; - break; - default: - break; - } - - const char* pSamplerName = "unknown"; - if (pInst) - { - const uint32 slot = pSampler->m_nTextureSlot; - for (size_t idx = 0; idx < pInst->m_pBindVars.size(); ++idx) - { - if (slot == (pInst->m_pBindVars[idx].m_RegisterOffset & 0xF) && (pInst->m_pBindVars[idx].m_RegisterOffset & SHADER_BIND_SAMPLER) != 0) - { - pSamplerName = pInst->m_pBindVars[idx].m_Name.c_str(); - break; - } - } - } - - const char* pShaderName = gcpRendD3D->m_RP.m_pShader ? gcpRendD3D->m_RP.m_pShader->GetName() : "NULL"; - const char* pTechName = gcpRendD3D->m_RP.m_pCurTechnique ? gcpRendD3D->m_RP.m_pCurTechnique->m_NameStr.c_str() : "NULL"; - const char* pSamplerTypeName = CTexture::NameForTextureType((ETEX_Type)pSampler->m_eTexType); - const char* pTexName = pTex->GetName(); - const char* pTexTypeName = pTex->GetTypeName(); - const char* pTexSurrogateMsg = pTex->IsNoTexture() ? " (texture doesn't exist!)" : ""; - - // Do not keep re-logging the same error every frame, in editor this will pop-up an error dialog (every frame), rendering it unusable (also can't save map) - const char* pMaterialNameNotNull = pMaterialName ? pMaterialName : "none"; - CCrc32 crc; - crc.Add(pShaderName); - crc.Add(pTechName); - crc.Add(pSamplerName); - crc.Add(pSamplerTypeName); - crc.Add(pTexName); - crc.Add(pTexTypeName); - crc.Add(pTexSurrogateMsg); - crc.Add(pMaterialNameNotNull); - const bool bShouldLog = s_ErrorsLogged.insert(crc.Get()).second; - if (!bShouldLog) - { - return; - } - - if (!pTex->GetIsTextureMissing()) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR_DBGBRK, "!Mismatch between texture and sampler type detected! ...\n" - "- Shader \"%s\" with technique \"%s\"\n" - "- Sampler \"%s\" is of type \"%s\"\n" - "- Texture \"%s\" is of type \"%s\"%s\n" - "- Material is \"%s\"", - pShaderName, pTechName, - pSamplerName, pSamplerTypeName, - pTexName, pTexTypeName, pTexSurrogateMsg, - pMaterialName ? pMaterialName : "none"); - } - } -} -#endif - -static EEfResTextures sSlots[] = -{ - EFTT_UNKNOWN, - - EFTT_DIFFUSE, - EFTT_NORMALS, - EFTT_HEIGHT, - EFTT_SPECULAR, - EFTT_ENV, - EFTT_SUBSURFACE, - EFTT_SMOOTHNESS, - EFTT_DECAL_OVERLAY, - EFTT_CUSTOM, - EFTT_CUSTOM_SECONDARY, - EFTT_OPACITY, - EFTT_DETAIL_OVERLAY, - EFTT_EMITTANCE, - EFTT_OCCLUSION, - EFTT_SPECULAR_2, -}; - -bool CHWShader_D3D::mfSetSamplers(const std::vector& Samplers, EHWShaderClass eSHClass) -{ - DETAILED_PROFILE_MARKER("mfSetSamplers"); - FUNCTION_PROFILER_RENDER_FLAT - //PROFILE_FRAME(Shader_SetShaderSamplers); - const uint32 nSize = Samplers.size(); - if (!nSize) - { - return true; - } - CD3D9Renderer* __restrict rd = gcpRendD3D; - - uint32 i; - const SCGSampler* pSamp = &Samplers[0]; - for (i = 0; i < nSize; i++) - { - const SCGSampler* pSM = pSamp++; - int nSUnit = pSM->m_BindingSlot; - - switch (pSM->m_eCGSamplerType) - { - case ECGS_Unknown: - break; - - case ECGS_Shadow0: - case ECGS_Shadow1: - case ECGS_Shadow2: - case ECGS_Shadow3: - case ECGS_Shadow4: - case ECGS_Shadow5: - case ECGS_Shadow6: - case ECGS_Shadow7: - { - const int nShadowMapNum = pSM->m_eCGSamplerType - ECGS_Shadow0; - //force MinFilter = Linear; MagFilter = Linear; for HW_PCF_FILTERING - STexState TS; - - TS.m_pDeviceState = NULL; - TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP); - - SShaderProfile* pSP = &gRenDev->m_cEF.m_ShaderProfiles[eST_Shadow]; - const int nShadowQuality = (int)pSP->GetShaderQuality(); - const bool bShadowsVeryHigh = nShadowQuality == eSQ_VeryHigh; - const bool bForwardShadows = (rd->m_RP.m_pShader->m_Flags2 & EF2_ALPHABLENDSHADOWS) != 0; - const bool bParticleShadow = (gRenDev->m_RP.m_FlagsShader_RT & g_HWSR_MaskBit[HWSR_PARTICLE_SHADOW]) != 0; - const bool bPCFShadow = (gRenDev->m_RP.m_FlagsShader_RT & g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE]) != 0; - - if ((!bShadowsVeryHigh || (nShadowMapNum != 0) || bForwardShadows || bParticleShadow) && bPCFShadow) - { - // non texture array case vs. texture array case - TS.SetComparisonFilter(true); - TS.SetFilterMode(FILTER_LINEAR); - } - else - { - TS.SetComparisonFilter(false); - TS.SetFilterMode(FILTER_POINT); - } - - const int texState = CTexture::GetTexState(TS); - CTexture::SetSamplerState(texState, nSUnit, eSHClass); - } - break; - - case ECGS_TrilinearClamp: - { - const static int nTStateTrilinearClamp = CTexture::GetTexState(STexState(FILTER_TRILINEAR, true)); - CTexture::SetSamplerState(nTStateTrilinearClamp, nSUnit, eSHClass); - } - break; - case ECGS_MatAnisoHighWrap: - { - CTexture::SetSamplerState(gcpRendD3D->m_nMaterialAnisoHighSampler, nSUnit, eSHClass); - } - break; - case ECGS_MatAnisoLowWrap: - { - CTexture::SetSamplerState(gcpRendD3D->m_nMaterialAnisoLowSampler, nSUnit, eSHClass); - } - break; - case ECGS_MatTrilinearWrap: - { - const static int nTStateTrilinearWrap = CTexture::GetTexState(STexState(FILTER_TRILINEAR, false)); - CTexture::SetSamplerState(nTStateTrilinearWrap, nSUnit, eSHClass); - } - break; - case ECGS_MatBilinearWrap: - { - const static int nTStateBilinearWrap = CTexture::GetTexState(STexState(FILTER_BILINEAR, false)); - CTexture::SetSamplerState(nTStateBilinearWrap, nSUnit, eSHClass); - } - break; - case ECGS_MatTrilinearClamp: - { - const static int nTStateTrilinearClamp = CTexture::GetTexState(STexState(FILTER_TRILINEAR, true)); - CTexture::SetSamplerState(nTStateTrilinearClamp, nSUnit, eSHClass); - } - break; - case ECGS_MatBilinearClamp: - { - const static int nTStateBilinearClamp = CTexture::GetTexState(STexState(FILTER_BILINEAR, true)); - CTexture::SetSamplerState(nTStateBilinearClamp, nSUnit, eSHClass); - } - break; - case ECGS_MatAnisoHighBorder: - { - CTexture::SetSamplerState(gcpRendD3D->m_nMaterialAnisoSamplerBorder, nSUnit, eSHClass); - } - break; - case ECGS_MatTrilinearBorder: - { - const static int nTStateTrilinearBorder = CTexture::GetTexState(STexState(FILTER_TRILINEAR, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0x0)); - CTexture::SetSamplerState(nTStateTrilinearBorder, nSUnit, eSHClass); - } - break; - - default: - assert(0); - break; - } - } - - return true; -} - -//------------------------------------------------------------------------------ -// This is the final texture prep and bind point to the shader, using the -// function call 'CTexture::ApplyTexture'. -// -// This method runs over the list of parsed textures and bind them to the HW stage -// Materials textures are handled the same and if do not exist they use a default. -// The rest of the textures (engine / per frame ..) are specifically handled. -// [Shader System] - this method should go data driven and have the same handling per texture. -// -// Observations: -// 1. The binding indices here are determined by ECGTexture while textures contexts -// are derived by EEfResTextures - they do NOT exactly match! -// It seems that the order can be switched without side effect - TEST! -//------------------------------------------------------------------------------ -bool CHWShader_D3D::mfSetTextures(const std::vector& Textures, EHWShaderClass eSHClass) -{ - DETAILED_PROFILE_MARKER("mfSetTextures"); - FUNCTION_PROFILER_RENDER_FLAT - - const uint32 nSize = Textures.size(); - if (!nSize) - { - return true; - } - CD3D9Renderer* __restrict rd = gcpRendD3D; - CShaderResources* __restrict pSR = rd->m_RP.m_pShaderResources; - - uint32 i; - const SCGTexture* pTexBind = &Textures[0]; - for (i = 0; i < nSize; i++) - { - int nTUnit = pTexBind->m_BindingSlot; - - // Get appropriate view for the texture to bind (can be SRGB, MipLevels etc.) - SResourceView::KeyType nResViewKey = SResourceView::DefaultView; - if (pTexBind->m_bSRGBLookup) - { - nResViewKey = SResourceView::DefaultViewSRGB; - } - - // This case handles texture names parsed from the shader that are not contextually predefined - // [Shader System] - can be used for the per material stage once the texture Id is not - // contextual anymore, hence not hard coded. - if (pTexBind->m_eCGTextureType == ECGT_Unknown) - { - CTexture* pTexture = pTexBind->GetTexture(); - if (pTexture) - { - pTexture->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - - pTexBind++; - continue; - } - - switch (pTexBind->m_eCGTextureType) - { - case ECGT_MatSlot_Diffuse: - case ECGT_MatSlot_Normals: - case ECGT_MatSlot_Specular: - case ECGT_MatSlot_Height: - case ECGT_MatSlot_SubSurface: - case ECGT_MatSlot_Smoothness: - case ECGT_MatSlot_DecalOverlay: - case ECGT_MatSlot_Custom: - case ECGT_MatSlot_CustomSecondary: - case ECGT_MatSlot_Env: - case ECGT_MatSlot_Opacity: - case ECGT_MatSlot_Detail: - case ECGT_MatSlot_Emittance: - case ECGT_MatSlot_Occlusion: - case ECGT_MatSlot_Specular2: - { - uint32 texSlot = EEfResTextures(pTexBind->m_eCGTextureType - 1); - SEfResTexture* pTextureRes = pSR ? pSR->GetTextureResource(texSlot) : nullptr; - CTexture* pTex = pTextureRes ? - pTextureRes->m_Sampler.m_pTex : - TextureHelpers::LookupTexDefault((EEfResTextures)texSlot); - - if (pTex) - { - pTex->ApplyTexture(texSlot, eSHClass, nResViewKey); - } - } - break; - - case ECGT_Shadow0: - case ECGT_Shadow1: - case ECGT_Shadow2: - case ECGT_Shadow3: - case ECGT_Shadow4: - case ECGT_Shadow5: - case ECGT_Shadow6: - case ECGT_Shadow7: - { - const int nShadowMapNum = pTexBind->m_eCGTextureType - ECGT_Shadow0; - const int nCustomID = rd->m_RP.m_ShadowCustomTexBind[nShadowMapNum]; - if (nCustomID < 0) - { - break; - } - - CTexture* tex = nCustomID ? CTexture::GetByID(nCustomID) : CTexture::s_ptexRT_ShadowStub; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_ShadowMask: - { - CTexture* tex = CTexture::IsTextureExist(CTexture::s_ptexShadowMask) - ? CTexture::s_ptexShadowMask - : CTextureManager::Instance()->GetBlackTexture(); - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_ZTarget: - { - CTexture* tex = CTexture::s_ptexZTarget; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_ZTargetMS: - { - CTexture* tex = CTexture::s_ptexZTarget; - tex->ApplyTexture(nTUnit, eSHClass, SResourceView::DefaultViewMS); - } - break; - case ECGT_ZTargetScaled: - { - CTexture* tex = CTexture::s_ptexZTargetScaled; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_ShadowMaskZTarget: - { - // Returns FurZTarget if fur rendering is present in frame, otherwise ZTarget is returned - CTexture* tex = CTexture::s_ptexZTarget; - if (FurPasses::GetInstance().IsRenderingFur()) - { - tex = CTexture::s_ptexFurZTarget; - } - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_SceneNormalsBent: - { - CTexture* tex = CTexture::s_ptexSceneNormalsBent; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_SceneNormals: - { - CTexture* tex = CTexture::s_ptexSceneNormalsMap; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_SceneDiffuse: - { - CTexture* tex = CTexture::s_ptexSceneDiffuse; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_SceneSpecular: - { - CTexture* tex = CTexture::s_ptexSceneSpecular; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_SceneDiffuseAcc: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* tex = nLightsCount ? CTexture::s_ptexSceneDiffuseAccMap : CTextureManager::Instance()->GetBlackTexture(); - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - case ECGT_SceneSpecularAcc: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* tex = nLightsCount ? CTexture::s_ptexSceneSpecularAccMap : CTextureManager::Instance()->GetBlackTexture(); - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_SceneNormalsMapMS: - { - CTexture* tex = CTexture::s_ptexSceneNormalsMapMS; - tex->ApplyTexture(nTUnit, eSHClass, SResourceView::DefaultViewMS); - } - break; - case ECGT_SceneDiffuseAccMS: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* tex = nLightsCount ? CTexture::s_ptexSceneDiffuseAccMapMS : CTextureManager::Instance()->GetBlackTexture(); - tex->ApplyTexture(nTUnit, eSHClass, SResourceView::DefaultViewMS); - } - break; - case ECGT_SceneSpecularAccMS: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* tex = nLightsCount ? CTexture::s_ptexSceneSpecularAccMapMS : CTextureManager::Instance()->GetBlackTexture(); - tex->ApplyTexture(nTUnit, eSHClass, SResourceView::DefaultViewMS); - } - break; - - case ECGT_VolumetricClipVolumeStencil: - { - CTexture* tex = CTexture::s_ptexVolumetricClipVolumeStencil; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_VolumetricFog: - { - CTexture* tex = CTexture::s_ptexVolumetricFog; - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_VolumetricFogGlobalEnvProbe0: - { - CTexture* tex = rd->GetVolumetricFog().GetGlobalEnvProbeTex0(); - tex = (tex != NULL) ? tex : CTextureManager::Instance()->GetNoTextureCM(); - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - case ECGT_VolumetricFogGlobalEnvProbe1: - { - CTexture* tex = rd->GetVolumetricFog().GetGlobalEnvProbeTex1(); - tex = (tex != NULL) ? tex : CTextureManager::Instance()->GetNoTextureCM(); - tex->ApplyTexture(nTUnit, eSHClass, nResViewKey); - } - break; - - default: - assert(0); - break; - } - - pTexBind++; - } - - return true; -} - -bool CHWShader_D3D::mfSetSamplers_Old(const std::vector& Samplers, EHWShaderClass eSHClass) -{ - DETAILED_PROFILE_MARKER("mfSetSamplers_Old"); - FUNCTION_PROFILER_RENDER_FLAT - - const uint32 nSize = Samplers.size(); - if (!nSize) - { - return true; - } - - CD3D9Renderer* __restrict rd = gcpRendD3D; - CShaderResources* __restrict pSR = rd->m_RP.m_pShaderResources; - - uint32 i; - const STexSamplerRT* pSamp = &Samplers[0]; - - // Loop counter increments moved to resolve an issue where the compiler introduced - // load hit stores by storing the counters as the last instruction in the loop then - // immediately reloading and incrementing them after the branch back to the top - for (i = 0; i < nSize; ) - { - CTexture* tx = pSamp->m_pTex; - assert(tx); - if (!tx) - { - ++pSamp; - ++i; - continue; - } - - int nTexMaterialSlot = EFTT_UNKNOWN; - const STexSamplerRT* pSM = pSamp++; - int nSUnit = pSM->m_nSamplerSlot; - int nTUnit = pSM->m_nTextureSlot; - assert(nTUnit >= 0); - int nTState = pSM->m_nTexState; - const ETEX_Type smpTexType = (ETEX_Type)pSM->m_eTexType; - - ++i; - - if (tx >= &(*CTexture::s_ShaderTemplates)[0] && tx <= &(*CTexture::s_ShaderTemplates)[EFTT_MAX - 1]) - { - nTexMaterialSlot = (int)(tx - &(*CTexture::s_ShaderTemplates)[0]); - - SEfResTexture* pTextureRes = pSR ? pSR->GetTextureResource(nTexMaterialSlot) : nullptr; - if (!pTextureRes) - { - tx = TextureHelpers::LookupTexDefault((EEfResTextures)nTexMaterialSlot); - } -#if defined(CONSOLE_CONST_CVAR_MODE) - else if constexpr (CD3D9Renderer::CV_r_TexturesDebugBandwidth > 0) -#else - else if (rd->CV_r_TexturesDebugBandwidth > 0) -#endif - { - tx = CTextureManager::Instance()->GetDefaultTexture("Gray"); - } - else - { - pSM = &pTextureRes->m_Sampler; - tx = pSM->m_pTex; - - if (nTState < 0 || !CTexture::s_TexStates[nTState].m_bActive) - { - nTState = pSM->m_nTexState; // Use material texture state - } - } - } - - IF(pSM && pSM->m_pAnimInfo, 0) - { - STexSamplerRT* pRT = (STexSamplerRT*)pSM; - pRT->Update(); - tx = pRT->m_pTex; - } - - IF(!tx || tx->GetCustomID() <= 0 && smpTexType != tx->GetTexType(), 0) - { -#if !defined(_RELEASE) - string matName = "unknown"; - - if (pSR->m_szMaterialName) - { - matName = pSR->m_szMaterialName; - } - - CRenderObject* pObj = gcpRendD3D->m_RP.m_pCurObject; - - if (pObj && pObj->m_pCurrMaterial) - { - matName.Format("%s/%s", pObj->m_pCurrMaterial->GetName(), pSR->m_szMaterialName ? pSR->m_szMaterialName : "unknown"); - } - - if (tx && !tx->IsNoTexture()) - { - LogSamplerTextureMismatch(tx, pSamp - 1, eSHClass, pSR && (nTexMaterialSlot >= 0 && nTexMaterialSlot < EFTT_UNKNOWN) ? matName : "none"); - } -#endif - tx = CTexture::s_pTexNULL; - } - - { - int nCustomID = tx->GetCustomID(); - if (nCustomID <= 0) - { - if (nTState >= 0 && nTState < CTexture::s_TexStates.size()) - { - if (tx->UseDecalBorderCol()) - { - STexState TS = CTexture::s_TexStates[nTState]; - //TS.SetFilterMode(...); // already set up - TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP); - nTState = CTexture::GetTexState(TS); - } - - if (CRenderer::CV_r_texNoAnisoAlphaTest && (rd->m_RP.m_FlagsShader_RT & g_HWSR_MaskBit[HWSR_ALPHATEST])) - { - - STexState TS = CTexture::s_TexStates[nTState]; - if (TS.m_nAnisotropy > 1) - { - TS.m_nAnisotropy = 1; - TS.SetFilterMode(FILTER_TRILINEAR); - nTState = CTexture::GetTexState(TS); - } - } - } - - tx->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - else - { - // Allow render elements to set their own samplers - IRenderElement* pRE = rd->m_RP.m_pRE; - if (pRE && pRE->mfSetSampler(nCustomID, nTUnit, nTState, nTexMaterialSlot, nSUnit)) - { - continue; - } - - switch (nCustomID) - { - case TO_FROMRE0: - case TO_FROMRE1: - { - if (rd->m_RP.m_pRE) - { - nCustomID = rd->m_RP.m_pRE->GetCustomTexBind(nCustomID - TO_FROMRE0); - } - else - { - nCustomID = rd->m_RP.m_RECustomTexBind[nCustomID - TO_FROMRE0]; - } - if (nCustomID < 0) - { - break; - } - - CTexture* pTex = CTexture::GetByID(nCustomID); - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - - case TO_FROMRE0_FROM_CONTAINER: - case TO_FROMRE1_FROM_CONTAINER: - { - // take render element from vertex container render mesh if available - IRenderElement* _pRE = sGetContainerRE0(rd->m_RP.m_pRE); - if (_pRE) - { - nCustomID = _pRE->GetCustomTexBind(nCustomID - TO_FROMRE0_FROM_CONTAINER); - } - else - { - nCustomID = rd->m_RP.m_RECustomTexBind[nCustomID - TO_FROMRE0_FROM_CONTAINER]; - } - if (nCustomID < 0) - { - break; - } - CTexture::ApplyForID(nTUnit, nCustomID, nTState, nSUnit); - } - break; - - case TO_ZTARGET_MS: - { - CTexture* pTex = CTexture::s_ptexZTarget; - assert(pTex); - if (pTex) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nTUnit, SResourceView::DefaultViewMS); - } - } - break; - - case TO_SCENE_NORMALMAP_MS: - case TO_SCENE_NORMALMAP: - { - CTexture* pTex = CTexture::s_ptexSceneNormalsMap; - if (sCanSet(pSM, pTex)) - { - if (nCustomID != TO_SCENE_NORMALMAP_MS) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView); - } - else - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nTUnit, SResourceView::DefaultViewMS); - } - } - } - break; - - case TO_SHADOWID0: - case TO_SHADOWID1: - case TO_SHADOWID2: - case TO_SHADOWID3: - case TO_SHADOWID4: - case TO_SHADOWID5: - case TO_SHADOWID6: - case TO_SHADOWID7: - { - const int nShadowMapNum = nCustomID - TO_SHADOWID0; - nCustomID = rd->m_RP.m_ShadowCustomTexBind[nShadowMapNum]; - - if (nCustomID < 0) - { - break; - } - - if (nTState >= 0 && nTState < CTexture::s_TexStates.size()) - { - //force MinFilter = Linear; MagFilter = Linear; for HW_PCF_FILTERING - STexState TS = CTexture::s_TexStates[nTState]; - TS.m_pDeviceState = NULL; - TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP); - - const bool bComparisonSampling = rd->m_RP.m_ShadowCustomComparisonSampling[nShadowMapNum]; - if (bComparisonSampling) - { - TS.SetFilterMode(FILTER_LINEAR); - TS.SetComparisonFilter(true); - } - else - { - TS.SetFilterMode(FILTER_POINT); - TS.SetComparisonFilter(false); - } - - nTState = CTexture::GetTexState(TS); - } - - CTexture* tex = CTexture::GetByID(nCustomID); - tex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - - case TO_SHADOWMASK: - { - CTexture* pTex = CTexture::IsTextureExist(CTexture::s_ptexShadowMask) - ? CTexture::s_ptexShadowMask - : CTextureManager::Instance()->GetBlackTexture(); - - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - - case TO_SCENE_DIFFUSE_ACC_MS: - case TO_SCENE_DIFFUSE_ACC: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* pTex = nLightsCount ? CTexture::s_ptexCurrentSceneDiffuseAccMap : CTextureManager::Instance()->GetBlackTexture(); - if (sCanSet(pSM, pTex)) - { - if (!(nLightsCount && nCustomID == TO_SCENE_DIFFUSE_ACC_MS)) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView); - } - else - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nTUnit, SResourceView::DefaultViewMS); - } - } - } - break; - - case TO_SCENE_SPECULAR_ACC_MS: - case TO_SCENE_SPECULAR_ACC: - { - const uint32 nLightsCount = CDeferredShading::Instance().GetLightsCount(); - CTexture* pTex = nLightsCount ? CTexture::s_ptexSceneSpecularAccMap : CTextureManager::Instance()->GetBlackTexture(); - if (sCanSet(pSM, pTex)) - { - if (!(nLightsCount && nCustomID == TO_SCENE_SPECULAR_ACC_MS)) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView); - } - else - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nTUnit, SResourceView::DefaultViewMS); - } - } - } - break; - - case TO_SCENE_TARGET: - { - CTexture* tex = CTexture::s_ptexCurrSceneTarget; - if (!tex) - { - tex = CTextureManager::Instance()->GetWhiteTexture(); - } - - tex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - - case TO_DOWNSCALED_ZTARGET_FOR_AO: - { - assert(CTexture::s_ptexZTargetScaled); - if (CTexture::s_ptexZTargetScaled) - { - CTexture::s_ptexZTargetScaled->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - } - break; - - case TO_QUARTER_ZTARGET_FOR_AO: - { - assert(CTexture::s_ptexZTargetScaled2); - if (CTexture::s_ptexZTargetScaled2) - { - CTexture::s_ptexZTargetScaled2->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - } - break; - - case TO_FROMOBJ: - { - CTexture* pTex = CTextureManager::Instance()->GetBlackTexture(); - if (rd->m_RP.m_pCurObject) - { - nCustomID = rd->m_RP.m_pCurObject->m_nTextureID; - if (nCustomID > 0) - { - pTex = CTexture::GetByID(nCustomID); - } - } - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - - case TO_FROMOBJ_CM: - { - SEfResTexture* overloadTexture = nullptr; - CTexture* pTex = CTextureManager::Instance()->GetNoTextureCM(); - if (rd->m_RP.m_pCurObject) - { - nCustomID = rd->m_RP.m_pCurObject->m_nTextureID; - if (nCustomID > 0) - { - pTex = CTexture::GetByID(nCustomID); - } - else if ((nTUnit < EFTT_MAX) && pSR && pSR->GetTextureResource(EFTT_ENV)) - { - overloadTexture = pSR->GetTextureResource(EFTT_ENV); - // Perhaps user wanted a specific cubemap instead? - // This should still be allowed even if the sampler is "TO_FROMOBJ_CM" as the - // end user can still select specific cubemaps from the material editor. - CTexture* tex = overloadTexture->m_Sampler.m_pTex; - if (tex) - { - tex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - nCustomID = -1; - } - else if (nCustomID == 0) - { - pTex = CTextureManager::Instance()->GetNoTextureCM(); - } - } - if (nCustomID >= 0) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - } - break; - - case TO_RT_2D: - { - SHRenderTarget* pRT = pSM->m_pTarget ? pSM->m_pTarget : pSamp->m_pTarget; - SEnvTexture* pEnvTex = pRT->GetEnv2D(); - //assert(pEnvTex->m_pTex); - if (pEnvTex && pEnvTex->m_pTex) - { - pEnvTex->m_pTex->Apply(nTUnit, nTState); - } - else - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState); - } - } - break; - - case TO_WATEROCEANMAP: - CTexture::s_ptexWaterOcean->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - break; - - case TO_WATERVOLUMEREFLMAP: - { - const uint32 nCurrWaterVolID = gRenDev->GetFrameID(false) % 2; - CTexture* pTex = CTexture::s_ptexWaterVolumeRefl[nCurrWaterVolID] ? CTexture::s_ptexWaterVolumeRefl[nCurrWaterVolID] : CTextureManager::Instance()->GetBlackTexture(); - pTex->Apply(nTUnit, CTexture::GetTexState(STexState(FILTER_ANISO16X, true)), nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - case TO_WATERVOLUMEREFLMAPPREV: - { - const uint32 nPrevWaterVolID = (gRenDev->GetFrameID(false) + 1) % 2; - - CTexture* pTex = CTexture::s_ptexWaterVolumeRefl[nPrevWaterVolID] ? CTexture::s_ptexWaterVolumeRefl[nPrevWaterVolID] : CTextureManager::Instance()->GetBlackTexture(); - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - case TO_WATERVOLUMECAUSTICSMAP: - { - const uint32 nCurrWaterVolID = gRenDev->GetFrameID(false) % 2; - CTexture* pTex = CTexture::s_ptexWaterCaustics[nCurrWaterVolID]; - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - case TO_WATERVOLUMECAUSTICSMAPTEMP: - { - const uint32 nPrevWaterVolID = (gRenDev->GetFrameID(false) + 1) % 2; - CTexture* pTex = CTexture::s_ptexWaterCaustics[nPrevWaterVolID]; - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - case TO_WATERVOLUMEMAP: - { - if (CTexture::s_ptexWaterVolumeDDN) - { - CEffectParam* pParam = PostEffectMgr()->GetByName("WaterVolume_Amount"); - assert(pParam && "Parameter doesn't exist"); - - // Activate puddle generation - if (pParam) - { - pParam->SetParam(1.0f); - } - - CTexture::s_ptexWaterVolumeDDN->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - else - { - CTextureManager::Instance()->GetDefaultTexture("FlatBump")->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - } - break; - - case TO_WATERRIPPLESMAP: - { - if (CTexture::s_ptexWaterRipplesDDN) - { - CTexture::s_ptexWaterRipplesDDN->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - else - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - } - break; - - case TO_BACKBUFFERSCALED_D2: - case TO_BACKBUFFERSCALED_D4: - case TO_BACKBUFFERSCALED_D8: - { - const uint32 nTargetID = nCustomID - TO_BACKBUFFERSCALED_D2; - CTexture* pTex = CTexture::s_ptexBackBufferScaled[nTargetID] ? CTexture::s_ptexBackBufferScaled[nTargetID] : CTextureManager::Instance()->GetBlackTexture(); - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - break; - - case TO_CLOUDS_LM: - { - const bool setupCloudShadows = rd->m_bShadowsEnabled && rd->m_bCloudShadowsEnabled; - if (setupCloudShadows) - { - // cloud shadow map - CTexture* pCloudShadowTex(rd->GetCloudShadowTextureId() > 0 ? CTexture::GetByID(rd->GetCloudShadowTextureId()) : CTextureManager::Instance()->GetWhiteTexture()); - assert(pCloudShadowTex); - - STexState pTexStateLinearClamp; - pTexStateLinearClamp.SetFilterMode(FILTER_LINEAR); - pTexStateLinearClamp.SetClampMode(false, false, false); - CTexture::GetTexState(pTexStateLinearClamp); - - pCloudShadowTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - else - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, SResourceView::DefaultView, eSHClass); - } - - break; - } - - case TO_MIPCOLORS_DIFFUSE: - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - break; - - case TO_BACKBUFFERMAP: - { - CTexture* pBackBufferTex = CTexture::s_ptexBackBuffer; - if (pBackBufferTex) - { - pBackBufferTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - } - break; - - case TO_HDR_MEASURED_LUMINANCE: - { - CTexture::s_ptexHDRMeasuredLuminance[gRenDev->RT_GetCurrGpuID()]->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - - case TO_VOLOBJ_DENSITY: - case TO_VOLOBJ_SHADOW: - { - bool texBound(false); - IRenderElement* _pRE(rd->m_RP.m_pRE); - if (_pRE && _pRE->mfGetType() == eDATA_VolumeObject) - { - CREVolumeObject* pVolObj((CREVolumeObject*)_pRE); - int texId(0); - if (pVolObj) - { - switch (nCustomID) - { - case TO_VOLOBJ_DENSITY: - if (pVolObj->m_pDensVol) - { - texId = pVolObj->m_pDensVol->GetTexID(); - } - break; - case TO_VOLOBJ_SHADOW: - if (pVolObj->m_pShadVol) - { - texId = pVolObj->m_pShadVol->GetTexID(); - } - break; - default: - assert(0); - break; - } - } - CTexture* pTex(texId > 0 ? CTexture::GetByID(texId) : 0); - if (pTex) - { - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - texBound = true; - } - } - if (!texBound) - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - } - - case TO_COLORCHART: - { - CColorGradingControllerD3D* pCtrl = gcpRendD3D->m_pColorGradingControllerD3D; - if (pCtrl) - { - CTexture* pTex = pCtrl->GetColorChart(); - if (pTex) - { - const static int texStateID = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - pTex->Apply(nTUnit, texStateID); - break; - } - } - CRenderer::CV_r_colorgrading_charts = 0; - CTextureManager::Instance()->GetWhiteTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - break; - } - - case TO_SKYDOME_MIE: - case TO_SKYDOME_RAYLEIGH: - { - IRenderElement* _pRE = rd->m_RP.m_pRE; - if (_pRE && _pRE->mfGetType() == eDATA_HDRSky) - { - CTexture* pTex = nCustomID == TO_SKYDOME_MIE ? ((CREHDRSky*)_pRE)->m_pSkyDomeTextureMie : ((CREHDRSky*)_pRE)->m_pSkyDomeTextureRayleigh; - if (pTex) - { - pTex->Apply(nTUnit, -1, nTexMaterialSlot, nSUnit); - break; - } - } - CTextureManager::Instance()->GetBlackTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - break; - } - - case TO_SKYDOME_MOON: - { - IRenderElement* _pRE = rd->m_RP.m_pRE; - if (_pRE && _pRE->mfGetType() == eDATA_HDRSky) - { - CREHDRSky* pHDRSky = (CREHDRSky*)_pRE; - CTexture* pMoonTex(pHDRSky->m_moonTexId > 0 ? CTexture::GetByID(pHDRSky->m_moonTexId) : 0); - if (pMoonTex) - { - const static int texStateID = CTexture::GetTexState(STexState(FILTER_BILINEAR, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0)); - pMoonTex->Apply(nTUnit, texStateID, nTexMaterialSlot, nSUnit); - break; - } - } - CTextureManager::Instance()->GetBlackTexture()->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - break; - } - - case TO_VOLFOGSHADOW_BUF: - { -#if defined(VOLUMETRIC_FOG_SHADOWS) - const bool enabled = gRenDev->m_bVolFogShadowsEnabled; - assert(enabled); - CTexture* pTex = enabled ? CTexture::s_ptexVolFogShadowBuf[0] : CTextureManager::Instance()->GetWhiteTexture(); - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - break; -#else - assert(0); - break; -#endif - } - - case TO_DEFAULT_ENVIRONMENT_PROBE: - { - // The environment probe entity render object requires that a texture that is bound to a sampler via shader declaration be overloaded in code. - // This is not supported by default, and changing the behavior generically breaks other systems that depend on this behavior. - // For the default environment probe texture declaration, we need to check if someone has tried to bind a new texture to the shader - // (which would happen either via C++ code or by overloading the environment map slot on the envcube.mtl material) - SEfResTexture* pTextureRes = pSR ? pSR->GetTextureResource(EFTT_ENV) : nullptr; - - if ((nSUnit == nTUnit) && (nTUnit < EFTT_MAX) && - pTextureRes && pTextureRes->m_Sampler.m_pTex && - pTextureRes->m_Sampler.m_pTex->GetDevTexture()) - { - SEfResTexture* overloadTexture = pTextureRes; - overloadTexture->m_Sampler.m_pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - else - { - CTexture* defaultEnvironmentProbe = CTextureManager::Instance()->GetDefaultTexture("DefaultProbeCM"); - if (defaultEnvironmentProbe) - { - defaultEnvironmentProbe->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - } - } - break; - - default: - { -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::SetSamplers(nCustomID, eSHClass, nTUnit, nTState, nTexMaterialSlot, nSUnit)) - { - break; - } -#endif - tx->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit); - } - break; - } - } - } - } - - return true; -} - -//------------------------------------------------------------------------------ -// Going over the samplers and making sure that dependent slots exist and -// represent the same texture (normals and smoothness/ -// [Shader System] - TO DO: -// 1. Seems like dependency on second smoothness is missing -// 2. Move this to be data driven based on flagged slots -//------------------------------------------------------------------------------ -bool CHWShader_D3D::mfUpdateSamplers(CShader* shader) -{ - DETAILED_PROFILE_MARKER("mfUpdateSamplers"); - FUNCTION_PROFILER_RENDER_FLAT - if (!m_pCurInst) - { - return false; - } - - SHWSInstance* pInst = m_pCurInst; - CShaderResources* pSRes = gRenDev->m_RP.m_pShaderResources; - if (!pInst->m_pSamplers.size() || !pSRes) - { - return true; - } - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - STexSamplerRT* pSamp = &pInst->m_pSamplers[0]; - - const uint32 samplerCount = pInst->m_pSamplers.size(); - bool bDiffuseSlotUpdated = false; - - if (pSRes) - { - AZStd::map UpdatedTMap; - - for (AZ::u32 i = 0; i < samplerCount; i++, pSamp++) - { - CTexture* tx = pSamp->m_pTex; - if (!tx) - { - continue; - } - - // [Shader System TO DO] - replace with proper data driven code reflected from the shaders - if (tx >= &(*CTexture::s_ShaderTemplates)[0] && tx <= &(*CTexture::s_ShaderTemplates)[EFTT_MAX - 1]) - { - int nSlot = (int)(tx - &(*CTexture::s_ShaderTemplates)[0]); - int16 replacementSlot = -1; - SEfResTexture* pTextureRes = pSRes->GetTextureResource(nSlot); - - if (pTextureRes) - { - // Default inserting and indexing - because we force some slots (Normal, Diffuse..), this - // operation might be done twice (same data). - UpdatedTMap[nSlot] = pTextureRes; - - //---------------------------------------------------------- - // Force adding samplers / textures if they indirectly assumed to be used - //---------------------------------------------------------- - // [Shader System TO DO] - replace with data driven reflection (i.e. a texture should be - // able to specify that it is driven by another texture and not hard code it) - if (nSlot == EFTT_HEIGHT || nSlot == EFTT_SMOOTHNESS) - { - replacementSlot = EFTT_NORMALS; - } - else if (nSlot == EFTT_DIFFUSE) - { // marked as updated - no need to look for replacement - bDiffuseSlotUpdated = true; - } - - // Force uploading the diffuse when the normal already exist (Really?) - if ((rTI.m_PersFlags & RBPF_ZPASS) && (nSlot == EFTT_NORMALS) && !bDiffuseSlotUpdated) - { - replacementSlot = EFTT_DIFFUSE; - } - - // Using the following block we can now drive forced slots to be data driven! - if (replacementSlot != -1) - { - SEfResTexture* replacementTexRes = pSRes->GetTextureResource(replacementSlot); - if (replacementTexRes) - { - UpdatedTMap[replacementSlot] = replacementTexRes; // inserting and indexing - } -/* [Shader System] - this is a good warning, however it will repeat every frame and drop fps. - else - { - AZ_Warning("ShadersSystem", false, "CHWShader_D3D::mfUpdateSamplers - [%s] using texture slot %d without existing forced texture %d", - pSRes->m_szMaterialName, nSlot, replacementSlot); - } -*/ - } - - } - } - } - - // Next run over all existing textures and explore if they have dynamic modulators - // which will force shader resource constants update. - bool bNeedsConstantUpdate = false; - for (auto iter = UpdatedTMap.begin(); iter != UpdatedTMap.end(); ++iter) - { - SEfResTexture* pTexture = iter->second; - - pTexture->Update(iter->first); - bNeedsConstantUpdate |= pTexture->IsNeedTexTransform(); - } - - // Rebuild shader resources - there was at least one transform modulator request - if (bNeedsConstantUpdate) - { - pSRes->Rebuild(shader); - } - } - - return true; -} - - -bool CHWShader_D3D::mfAddGlobalTexture(SCGTexture& Texture) -{ - DETAILED_PROFILE_MARKER("mfAddGlobalTexture"); - uint32 i; - if (!Texture.m_bGlobal) - { - return false; - } - for (i = 0; i < s_PF_Textures.size(); i++) - { - SCGTexture* pP = &s_PF_Textures[i]; - if (pP->m_pTexture == Texture.m_pTexture) - { - break; - } - } - if (i == s_PF_Textures.size()) - { - s_PF_Textures.push_back(Texture); - return true; - } - return false; -} - - -bool CHWShader_D3D::mfAddGlobalSampler(STexSamplerRT& Sampler) -{ - DETAILED_PROFILE_MARKER("mfAddGlobalSampler"); - uint32 i; - if (!Sampler.m_bGlobal) - { - return false; - } - for (i = 0; i < s_PF_Samplers.size(); i++) - { - STexSamplerRT* pP = &s_PF_Samplers[i]; - if (pP->m_pTex == Sampler.m_pTex) - { - break; - } - } - if (i == s_PF_Samplers.size()) - { - s_PF_Samplers.push_back(Sampler); - assert(s_PF_Samplers.size() <= MAX_PF_SAMPLERS); - return true; - } - return false; -} - - -Vec4 CHWShader_D3D::GetVolumetricFogParams() -{ - DETAILED_PROFILE_MARKER("GetVolumetricFogParams"); - return sGetVolumetricFogParams(gcpRendD3D); -} - -Vec4 CHWShader_D3D::GetVolumetricFogRampParams() -{ - DETAILED_PROFILE_MARKER("GetVolumetricFogRampParams"); - return sGetVolumetricFogRampParams(); -} - -void CHWShader_D3D::GetFogColorGradientConstants(Vec4& fogColGradColBase, Vec4& fogColGradColDelta) -{ - DETAILED_PROFILE_MARKER("GetFogColorGradientConstants"); - sGetFogColorGradientConstants(fogColGradColBase, fogColGradColDelta); -}; - -Vec4 CHWShader_D3D::GetFogColorGradientRadial() -{ - DETAILED_PROFILE_MARKER("GetFogColorGradientRadial"); - return sGetFogColorGradientRadial(gcpRendD3D); -} - -Vec4 SBending::GetShaderConstants(float realTime) const -{ - Vec4 result(ZERO); - if ((m_vBending.x * m_vBending.x + m_vBending.y * m_vBending.y) > 0.0f) - { - const Vec2& vBending = m_vBending; - Vec2 vAddBending(ZERO); - - if (m_Waves[0].m_Amp) - { - // Fast version of CShaderMan::EvalWaveForm (for bending) - const SWaveForm2& RESTRICT_REFERENCE wave0 = m_Waves[0]; - const SWaveForm2& RESTRICT_REFERENCE wave1 = m_Waves[1]; - const float* const __restrict pSinTable = gcpRendD3D->m_RP.m_tSinTable; - - int val0 = (int)((realTime * wave0.m_Freq + wave0.m_Phase) * (float)SRenderPipeline::sSinTableCount); - int val1 = (int)((realTime * wave1.m_Freq + wave1.m_Phase) * (float)SRenderPipeline::sSinTableCount); - - float sinVal0 = pSinTable[val0 & (SRenderPipeline::sSinTableCount - 1)]; - float sinVal1 = pSinTable[val1 & (SRenderPipeline::sSinTableCount - 1)]; - vAddBending.x = wave0.m_Amp * sinVal0 + wave0.m_Level; - vAddBending.y = wave1.m_Amp * sinVal1 + wave1.m_Level; - } - - result.x = vAddBending.x * 50.f + vBending.x; - result.y = vAddBending.y * 50.f + vBending.y; - result.z = vBending.GetLength() * 2.f; - result *= m_fMainBendingScale; - result.w = (vAddBending + vBending).GetLength() * 0.3f; - } - - return result; -} - -void SBending::GetShaderConstantsStatic([[maybe_unused]] float realTime, Vec4* pBendInfo) const -{ - pBendInfo[0] = Vec4(ZERO); - pBendInfo[0].x = m_Waves[0].m_Freq; - pBendInfo[0].y = m_Waves[0].m_Amp; - pBendInfo[0].z = m_Waves[1].m_Freq; - pBendInfo[0].w = m_Waves[1].m_Amp; - pBendInfo[1].x = m_vBending.x; - pBendInfo[1].y = m_vBending.y; - pBendInfo[1].z = m_vBending.GetLength(); - pBendInfo[1].w = m_fMainBendingScale; -} - -#pragma endregion everything in this block is related to shader parameters - -int SD3DShader::Release(EHWShaderClass eSHClass, int nSize) -{ - m_nRef--; - if (m_nRef) - { - return m_nRef; - } - void* pHandle = m_pHandle; - delete this; - if (!pHandle) - { - return 0; - } - if (eSHClass == eHWSC_Pixel) - { - CHWShader_D3D::s_nDevicePSDataSize -= nSize; - } - else - { - CHWShader_D3D::s_nDeviceVSDataSize -= nSize; - } - - if (eSHClass == eHWSC_Pixel) - { - return ((ID3D11PixelShader*)pHandle)->Release(); - } - else - if (eSHClass == eHWSC_Vertex) - { - return ((ID3D11VertexShader*)pHandle)->Release(); - } - else - if (eSHClass == eHWSC_Geometry) - { - return ((ID3D11GeometryShader*)pHandle)->Release(); - } - else - if (eSHClass == eHWSC_Hull) - { - return ((ID3D11HullShader*)pHandle)->Release(); - } - else - if (eSHClass == eHWSC_Compute) - { - return ((ID3D11ComputeShader*)pHandle)->Release(); - } - else - if (eSHClass == eHWSC_Domain) - { - return ((ID3D11DomainShader*)pHandle)->Release(); - } - else - { - assert(0); - return 0; - } -} - -void CHWShader_D3D::SHWSInstance::Release(SShaderDevCache* pCache, [[maybe_unused]] bool bReleaseData) -{ - if (m_nParams[0] >= 0) - { - CGParamManager::FreeParametersGroup(m_nParams[0]); - } - if (m_nParams[1] >= 0) - { - CGParamManager::FreeParametersGroup(m_nParams[1]); - } - if (m_nParams_Inst >= 0) - { - CGParamManager::FreeParametersGroup(m_nParams_Inst); - } - - int nCount = -1; - if (m_Handle.m_pShader) - { - if (m_eClass == eHWSC_Pixel) - { - SD3DShader* pPS = m_Handle.m_pShader; - if (pPS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurPS == pPS) - { - CHWShader::s_pCurPS = NULL; - } - } - } - else - if (m_eClass == eHWSC_Vertex) - { - SD3DShader* pVS = m_Handle.m_pShader; - if (pVS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurVS == pVS) - { - CHWShader::s_pCurVS = NULL; - } - } - } - else - if (m_eClass == eHWSC_Geometry) - { - SD3DShader* pGS = m_Handle.m_pShader; - if (pGS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurGS == pGS) - { - CHWShader::s_pCurGS = NULL; - } - } - } - else - if (m_eClass == eHWSC_Hull) - { - SD3DShader* pHS = m_Handle.m_pShader; - if (pHS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurHS == pHS) - { - CHWShader::s_pCurHS = NULL; - } - } - } - else - if (m_eClass == eHWSC_Compute) - { - SD3DShader* pCS = m_Handle.m_pShader; - if (pCS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurCS == pCS) - { - CHWShader::s_pCurCS = NULL; - } - } - } - else - if (m_eClass == eHWSC_Domain) - { - SD3DShader* pDS = m_Handle.m_pShader; - if (pDS) - { - nCount = m_Handle.Release(m_eClass, m_nDataSize); - if (!nCount && CHWShader::s_pCurDS == pDS) - { - CHWShader::s_pCurDS = NULL; - } - } - } - } - - if (m_pShaderData) - { - delete[] (char*)m_pShaderData; - m_pShaderData = NULL; - } - - if (!nCount && pCache && !pCache->m_DeviceShaders.empty()) - { - pCache->m_DeviceShaders.erase(m_DeviceObjectID); - } - m_Handle.m_pShader = NULL; -} - -void CHWShader_D3D::SHWSInstance::GetInstancingAttribInfo(uint8 Attributes[32], int32& nUsedAttr, int& nInstAttrMask) -{ - Attributes[0] = (byte)m_nInstMatrixID; - for (int32 i = 1; i < nUsedAttr; ++i) - { - Attributes[i] = Attributes[0] + i; - } - - nInstAttrMask = 0x7 << m_nInstMatrixID; - if (m_nParams_Inst >= 0) - { - SCGParamsGroup& Group = CGParamManager::s_Groups[m_nParams_Inst]; - uint32 nSize = Group.nParams; - for (uint32 j = 0; j < nSize; ++j) - { - SCGParam* pr = &Group.pParams[j]; - for (uint32 na = 0; na < (uint32)pr->m_RegisterCount; ++na) - { - Attributes[nUsedAttr + na] = pr->m_RegisterOffset + na; - nInstAttrMask |= 1 << Attributes[nUsedAttr + na]; - } - nUsedAttr += pr->m_RegisterCount; - } - } -} - - -void CHWShader_D3D::ShutDown() -{ - CCryNameTSCRC Name; - SResourceContainer* pRL; - - AzRHI::ConstantBufferCache::GetInstance().Reset(); - - uint32 numResourceLeaks = 0; - - // First make sure all HW and FX shaders are released - Name = CHWShader::mfGetClassName(eHWSC_Vertex); - pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CHWShader* vsh = (CHWShader*)itor->second; - if (vsh) - { - ++numResourceLeaks; - } - } - if (!pRL->m_RMap.size()) - { - pRL->m_RList.clear(); - pRL->m_AvailableIDs.clear(); - } - } - - Name = CHWShader::mfGetClassName(eHWSC_Pixel); - pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CHWShader* psh = (CHWShader*)itor->second; - if (psh) - { - ++numResourceLeaks; - } - } - if (!pRL->m_RMap.size()) - { - pRL->m_RList.clear(); - pRL->m_AvailableIDs.clear(); - } - } - - Name = CShader::mfGetClassName(); - pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CShader* sh = (CShader*)itor->second; - if (!sh->m_DerivedShaders) - { - numResourceLeaks++; - } - } - if (!pRL->m_RMap.size()) - { - pRL->m_RList.clear(); - pRL->m_AvailableIDs.clear(); - } - } - - if (numResourceLeaks > 0) - { - iLog->LogWarning("Detected shader resource leaks on shutdown"); - } - - stl::free_container(s_PF_Samplers); - - gRenDev->m_cEF.m_Bin.mfReleaseFXParams(); - - while (!m_ShaderCache.empty()) - { - SShaderCache* pC = m_ShaderCache.begin()->second; - SAFE_RELEASE(pC); - } - m_ShaderCacheList.clear(); - g_SelectedTechs.clear(); -#if !defined(_RELEASE) - s_ErrorsLogged.clear(); -#endif - CGParamManager::Shutdown(); -} - -CHWShader* CHWShader::mfForName(const char* name, const char* nameSource, uint32 CRC32, const char* szEntryFunc, EHWShaderClass eClass, TArray& SHData, FXShaderToken* pTable, uint32 dwType, CShader* pFX, uint64 nMaskGen, uint64 nMaskGenFX) -{ - // LOADING_TIME_PROFILE_SECTION(iSystem); - if (!name || !name[0]) - { - return NULL; - } - - CHWShader_D3D* pSH = NULL; - stack_string strName = name; - CCryNameTSCRC className = mfGetClassName(eClass); - stack_string AddStr; - - if (nMaskGen) - { - strName += AddStr.Format("(GL_%llx)", nMaskGen); - } - - if (pFX->m_maskGenStatic) - { - strName += AddStr.Format("(ST_%llx)", pFX->m_maskGenStatic); - } - - strName += AddStr.Format( GetShaderLanguageResourceName() ); - - CCryNameTSCRC Name = strName.c_str(); - CBaseResource* pBR = CBaseResource::GetResource(className, Name, false); - if (!pBR) - { - pSH = new CHWShader_D3D; - pSH->m_Name = strName.c_str(); - pSH->m_NameSourceFX = nameSource; - pSH->Register(className, Name); - pSH->m_EntryFunc = szEntryFunc; - pSH->mfFree(CRC32); - - // do we want to use lookup table for faster searching of shaders - if (CRenderer::CV_r_shadersuseinstancelookuptable) - { - pSH->m_bUseLookUpTable = true; - } - } - else - { - pSH = (CHWShader_D3D*)pBR; - pSH->AddRef(); - if (pSH->m_CRC32 == CRC32) - { - if (pTable && CRenderer::CV_r_shadersAllowCompilation) - { - FXShaderToken* pMap = pTable; - TArray* pData = &SHData; - pSH->mfGetCacheTokenMap(pMap, pData, pSH->m_nMaskGenShader); - } - return pSH; - } - pSH->mfFree(CRC32); - pSH->m_CRC32 = CRC32; - } - - if (CParserBin::m_bEditable) - { - if (pTable) - { - pSH->m_TokenTable = *pTable; - } - pSH->m_TokenData = SHData; - } - - pSH->m_dwShaderType = dwType; - pSH->m_eSHClass = eClass; - pSH->m_nMaskGenShader = nMaskGen; - pSH->m_nMaskGenFX = nMaskGenFX; - pSH->m_maskGenStatic = pFX->m_maskGenStatic; - pSH->m_CRC32 = CRC32; - - pSH->mfConstructFX(pTable, &SHData); - - return pSH; -} - - -void CHWShader_D3D::SetTokenFlags(uint32 nToken) -{ - switch (nToken) - { - case eT__LT_LIGHTS: - m_Flags |= HWSG_SUPPORTS_LIGHTING; - break; - case eT__LT_0_TYPE: - case eT__LT_1_TYPE: - case eT__LT_2_TYPE: - case eT__LT_3_TYPE: - m_Flags |= HWSG_SUPPORTS_MULTILIGHTS; - break; - case eT__TT_TEXCOORD_MATRIX: - case eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE: - case eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE: - case eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT: - case eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL: - case eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM: - m_Flags |= HWSG_SUPPORTS_MODIF; - break; - case eT__VT_TYPE: - m_Flags |= HWSG_SUPPORTS_VMODIF; - break; - case eT__FT_TEXTURE: - m_Flags |= HWSG_FP_EMULATION; - break; - } -} - -uint64 CHWShader_D3D::CheckToken(uint32 nToken) -{ - uint64 nMask = 0; - SShaderGen* pGen = gRenDev->m_cEF.m_pGlobalExt; - uint32 i; - for (i = 0; i < pGen->m_BitMask.Num(); i++) - { - SShaderGenBit* bit = pGen->m_BitMask[i]; - if (!bit) - { - continue; - } - - if (bit->m_dwToken == nToken) - { - nMask |= bit->m_Mask; - break; - } - } - if (!nMask) - { - SetTokenFlags(nToken); - } - - return nMask; -} - -uint64 CHWShader_D3D::CheckIfExpr_r(uint32* pTokens, uint32& nCur, uint32 nSize) -{ - uint64 nMask = 0; - - while (nCur < nSize) - { - uint32 nToken = pTokens[nCur++]; - if (nToken == eT_br_rnd_1) // check for '(' - { - uint32 tmpBuf[64]; - int n = 0; - int nD = 0; - while (true) - { - nToken = pTokens[nCur]; - if (nToken == eT_br_rnd_1) // check for '(' - { - n++; - } - else - if (nToken == eT_br_rnd_2) // check for ')' - { - if (!n) - { - tmpBuf[nD] = 0; - nCur++; - break; - } - n--; - } - else - if (nToken == 0) - { - return nMask; - } - tmpBuf[nD++] = nToken; - nCur++; - } - if (nD) - { - uint32 nC = 0; - nMask |= CheckIfExpr_r(tmpBuf, nC, nSize); - } - } - else - { - bool bNeg = false; - if (nToken == eT_excl) - { - bNeg = true; - nToken = pTokens[nCur++]; - } - nMask |= CheckToken(nToken); - } - nToken = pTokens[nCur]; - if (nToken == eT_or) - { - nCur++; - assert (pTokens[nCur] == eT_or); - if (pTokens[nCur] == eT_or) - { - nCur++; - } - } - else - if (nToken == eT_and) - { - nCur++; - assert (pTokens[nCur] == eT_and); - if (pTokens[nCur] == eT_and) - { - nCur++; - } - } - else - { - break; - } - } - return nMask; -} - -void CHWShader_D3D::mfConstructFX_Mask_RT([[maybe_unused]] FXShaderToken* Table, TArray* pSHData) -{ - assert(gRenDev->m_cEF.m_pGlobalExt); - m_nMaskAnd_RT = 0; - m_nMaskOr_RT = 0; - if (!gRenDev->m_cEF.m_pGlobalExt) - { - return; - } - SShaderGen* pGen = gRenDev->m_cEF.m_pGlobalExt; - - // Construct mask of all mask bits that are usable for this shader from precache entries. This mask is then ANDed - // with the property defines used in the shader, in other words, permutation flags prep for shader fetch will - // be AND with these masks so that only acceptable / used permutations are being fetched. - // See Runtime.ext file for the flags bits themselves. - uint64 allowedBits = 0; - if (m_dwShaderType) - { - for (uint32 i = 0; i < pGen->m_BitMask.Num(); i++) - { - SShaderGenBit* bit = pGen->m_BitMask[i]; - if (!bit) - { - continue; - } - if (bit->m_Flags & SHGF_RUNTIME) - { - allowedBits |= bit->m_Mask; - continue; - } - - uint32 j; - if (bit->m_PrecacheNames.size()) - { - for (j = 0; j < bit->m_PrecacheNames.size(); j++) - { - if (m_dwShaderType == bit->m_PrecacheNames[j]) - { - AZ_Error("Shaders", ((allowedBits & bit->m_Mask) == 0), "Two shader properties in this shader technique have the same mask which is bad. Look for mask 0x%x in Runtime.ext", bit->m_Mask); - allowedBits |= bit->m_Mask; - break; - } - } - } - } - } - else - { - allowedBits = 0xFFFFFFFFFFFFFFFF; - } - - AZ_Assert(!pSHData->empty(), "Shader data is empty"); - uint32* pTokens = &(*pSHData)[0]; - uint32 nSize = pSHData->size(); - uint32 nCur = 0; - while (nCur < nSize) - { - uint32 nTok = CParserBin::NextToken(pTokens, nCur, nSize - 1); - if (!nTok) - { - continue; - } - if (nTok >= eT_if && nTok <= eT_elif) - { - m_nMaskAnd_RT |= CheckIfExpr_r(pTokens, nCur, nSize) & allowedBits; - } - else - { - SetTokenFlags(nTok); - } - } - - mfSetDefaultRT(m_nMaskAnd_RT, m_nMaskOr_RT); -} - -void CHWShader_D3D::mfConstructFX(FXShaderToken* Table, TArray* pSHData) -{ - if (!_strnicmp(m_EntryFunc.c_str(), "Sync_", 5)) - { - m_Flags |= HWSG_SYNC; - } - - if (!pSHData->empty()) - { - mfConstructFX_Mask_RT(Table, pSHData); - } - else - { - m_nMaskAnd_RT = -1; - m_nMaskOr_RT = 0; - } - - if (Table && CRenderer::CV_r_shadersAllowCompilation) - { - FXShaderToken* pMap = Table; - TArray* pData = pSHData; - mfGetCacheTokenMap(pMap, pData, m_nMaskGenShader); // Store tokens - } -} - -bool CHWShader_D3D::mfPrecache(SShaderCombination& cmb, bool bForce, bool bFallback, bool bCompressedOnly, CShader* pSH, CShaderResources* pRes) -{ - assert(gRenDev->m_pRT->IsRenderThread()); - - bool bRes = true; - - if (!CRenderer::CV_r_shadersAllowCompilation && !bForce) - { - return bRes; - } - - uint64 AndRTMask = 0; - uint64 OrRTMask = 0; - mfSetDefaultRT(AndRTMask, OrRTMask); - SShaderCombIdent Ident; - Ident.m_RTMask = cmb.m_RTMask & AndRTMask | OrRTMask; - Ident.m_pipelineState.opaque = cmb.m_pipelineState.opaque; - Ident.m_MDVMask = cmb.m_MDVMask; - if (m_eSHClass == eHWSC_Pixel) - { - Ident.m_MDVMask = CParserBin::m_nPlatform; - } - if (m_Flags & HWSG_SUPPORTS_MULTILIGHTS) - { - Ident.m_LightMask = 1; - } - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - uint32 nFlags = HWSF_PRECACHE; - if (m_eSHClass == eHWSC_Pixel && pRes) - { - SHWSInstance* pInst = mfGetInstance(pSH, Ident, HWSF_PRECACHE_INST); - pInst->m_bFallback = bFallback; - int nResult = mfCheckActivation(pSH, pInst, HWSF_PRECACHE); - if (!nResult) - { - return bRes; - } - mfUpdateSamplers(pSH); - pInst->m_fLastAccess = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - Ident.m_MDMask = gRenDev->m_RP.m_FlagsShader_MD & ~HWMD_TEXCOORD_FLAG_MASK; - } - if (m_eSHClass == eHWSC_Pixel && gRenDev->m_RP.m_pShaderResources) - { - Ident.m_MDMask &= ~HWMD_TEXCOORD_FLAG_MASK; - } - - if (Ident.m_MDMask || bForce) - { - SHWSInstance* pInst = mfGetInstance(pSH, Ident, HWSF_PRECACHE_INST); - pInst->m_bFallback = bFallback; - pInst->m_fLastAccess = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_RealTime; - mfActivate(pSH, nFlags, NULL, NULL, bCompressedOnly); - } - - return bRes; -} - -void CHWShader_D3D::mfReset([[maybe_unused]] uint32 CRC32) -{ - DETAILED_PROFILE_MARKER("mfReset"); - for (uint32 i = 0; i < m_Insts.size(); i++) - { - m_pCurInst = m_Insts[i]; - assert(m_pCurInst); - PREFAST_ASSUME(m_pCurInst); - if (!m_pCurInst->m_bDeleted) - { - m_pCurInst->Release(m_pDevCache); - } - - delete m_pCurInst; - } - m_pCurInst = NULL; - m_Insts.clear(); - m_LookupMap.clear(); - - mfCloseCacheFile(); -} - -CHWShader_D3D::~CHWShader_D3D() -{ - mfFree(0); -} - -void CHWShader_D3D::mfInit() -{ - CGParamManager::Init(); -} - -ED3DShError CHWShader_D3D::mfFallBack(SHWSInstance*& pInst, int nStatus) -{ - // No fallback for: - // - ShadowGen pass - // - Z-prepass - // - Shadow-pass - if (CParserBin::m_nPlatform & (SF_D3D11 | SF_ORBIS | SF_JASPER | SF_GL4 | SF_GLES3 | SF_METAL)) - { - //assert(gRenDev->m_cEF.m_nCombinationsProcess >= 0); - return ED3DShError_CompilingError; - } - if ( - m_eSHClass == eHWSC_Geometry || m_eSHClass == eHWSC_Domain || m_eSHClass == eHWSC_Hull || - (gRenDev->m_RP.m_nBatchFilter & FB_Z) || (gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_SHADOWGEN) || gRenDev->m_RP.m_nPassGroupID == EFSLIST_SHADOW_PASS) - { - return ED3DShError_CompilingError; - } - if (gRenDev->m_RP.m_pShader) - { - if (gRenDev->m_RP.m_pShader->GetShaderType() == eST_HDR || gRenDev->m_RP.m_pShader->GetShaderType() == eST_PostProcess || gRenDev->m_RP.m_pShader->GetShaderType() == eST_Water || gRenDev->m_RP.m_pShader->GetShaderType() == eST_Shadow || gRenDev->m_RP.m_pShader->GetShaderType() == eST_Shadow) - { - return ED3DShError_CompilingError; - } - } - // Skip rendering if async compiling Cvar is 2 - if (CRenderer::CV_r_shadersasynccompiling == 2) - { - return ED3DShError_CompilingError; - } - - CShader* pSH = CShaderMan::s_ShaderFallback; - int nTech = 0; - if (nStatus == -1) - { - pInst->m_Handle.m_bStatus = 1; - nTech = 1; - } - else - { - nTech = 0; - assert(nStatus == 0); - } - assert(pSH); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logShaders) - { - char nameSrc[256]; - mfGetDstFileName(pInst, this, nameSrc, 256, 3); - gcpRendD3D->LogShv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Async %d: using Fallback tech '%s' instead of 0x%x '%s' shader\n", gRenDev->GetFrameID(false), pSH->m_HWTechniques[nTech]->m_NameStr.c_str(), pInst, nameSrc); - } - // Fallback - if (pSH) - { - if (gRenDev->m_RP.m_CurState & GS_DEPTHFUNC_EQUAL) - { - int nState = gRenDev->m_RP.m_CurState & ~GS_DEPTHFUNC_EQUAL; - nState |= GS_DEPTHWRITE; - gRenDev->FX_SetState(nState); - } - CHWShader_D3D* pHWSH; - if (m_eSHClass == eHWSC_Vertex) - { - pHWSH = (CHWShader_D3D*)pSH->m_HWTechniques[nTech]->m_Passes[0].m_VShader; -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - gcpRendD3D->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "---- Fallback FX VShader \"%s\"\n", pHWSH->GetName()); - } -#endif - } - else - { - pHWSH = (CHWShader_D3D*)pSH->m_HWTechniques[nTech]->m_Passes[0].m_PShader; -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - gcpRendD3D->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "---- Fallback FX PShader \"%s\"\n", pHWSH->GetName()); - } -#endif - } - - if (!pHWSH->m_Insts.size()) - { - SShaderCombination cmb; - pHWSH->mfPrecache(cmb, true, true, false, gRenDev->m_RP.m_pShader, gRenDev->m_RP.m_pShaderResources); - } - if (pHWSH->m_Insts.size()) - { - SHWSInstance* pInstF = pHWSH->m_Insts[0]; - if (!pInstF->m_Handle.m_pShader || !pInstF->m_Handle.m_pShader->m_pHandle) - { - return ED3DShError_CompilingError; - } - pInst = pInstF; - m_pCurInst = pInstF; - pInstF->m_bFallback = true; - } - else - { - return ED3DShError_CompilingError; - } - } - //if (nStatus == 0) - // return ED3DShError_Compiling; - return ED3DShError_Ok; -} - -ED3DShError CHWShader_D3D::mfIsValid_Int(SHWSInstance*& pInst, bool bFinalise) -{ - //if (_stricmp(m_EntryFunc.c_str(), "FPPS") && _stricmp(m_EntryFunc.c_str(), "FPVS") && _stricmp(m_EntryFunc.c_str(), "AuxGeomPS") && _stricmp(m_EntryFunc.c_str(), "AuxGeomVS")) - // return mfFallBack(pInst, 0); - - if (pInst->m_Handle.m_bStatus == 1) - { - return mfFallBack(pInst, -1); - } - if (pInst->m_Handle.m_bStatus == 2) - { - return ED3DShError_Fake; - } - if (pInst->m_Handle.m_pShader == NULL) - { - if (pInst->m_bAsyncActivating) - { - return mfFallBack(pInst, 0); - } - - if (!bFinalise || !pInst->m_pAsync) - { - return ED3DShError_NotCompiled; - } - - int nStatus = 0; - if (!pInst->m_bAsyncActivating) - { - nStatus = mfAsyncCompileReady(pInst); - if (nStatus == 1) - { - if (gcpRendD3D->m_cEF.m_nCombinationsProcess <= 0 || gcpRendD3D->m_cEF.m_bActivatePhase) - { - assert(pInst->m_Handle.m_pShader != NULL); - } - return ED3DShError_Ok; - } - } - return mfFallBack(pInst, nStatus); - } - return ED3DShError_Ok; -} - -struct InstContainerByHash -{ - bool operator () (const CHWShader_D3D::SHWSInstance* left, const CHWShader_D3D::SHWSInstance* right) const - { - return left->m_Ident.m_nHash < right->m_Ident.m_nHash; - } - bool operator () (const uint32 left, const CHWShader_D3D::SHWSInstance* right) const - { - return left < right->m_Ident.m_nHash; - } - bool operator () (const CHWShader_D3D::SHWSInstance* left, uint32 right) const - { - return left->m_Ident.m_nHash < right; - } -}; - - -CHWShader_D3D::SHWSInstance* CHWShader_D3D::mfGetInstance([[maybe_unused]] CShader* pSH, int nHashInstance, [[maybe_unused]] uint64 GLMask) -{ - DETAILED_PROFILE_MARKER("mfGetInstance"); - FUNCTION_PROFILER_RENDER_FLAT - InstContainer* pInstCont = &m_Insts; - if (m_bUseLookUpTable) - { - assert(nHashInstance < pInstCont->size()); - SHWSInstance* pInst = (*pInstCont)[nHashInstance]; - return pInst; - } - InstContainerIt it = std::lower_bound(pInstCont->begin(), pInstCont->end(), nHashInstance, InstContainerByHash()); - assert (it != pInstCont->end() && nHashInstance == (*it)->m_Ident.m_nHash); - - return (*it); -} - -CHWShader_D3D::SHWSInstance* CHWShader_D3D::mfGetInstance(CShader* pSH, SShaderCombIdent& Ident, uint32 nFlags) -{ - DETAILED_PROFILE_MARKER("mfGetInstance"); - FUNCTION_PROFILER_RENDER_FLAT - SHWSInstance* cgi = m_pCurInst; - if (cgi && !cgi->m_bFallback) - { - assert(cgi->m_eClass < eHWSC_Num); - - const SShaderCombIdent& other = cgi->m_Ident; - // other will have been through PostCreate, and so won't have the platform mask set anymore - if ((Ident.m_MDVMask & ~SF_PLATFORM) == other.m_MDVMask && Ident.m_RTMask == other.m_RTMask && Ident.m_GLMask == other.m_GLMask && Ident.m_FastCompare1 == other.m_FastCompare1 && Ident.m_pipelineState.opaque == other.m_pipelineState.opaque && Ident.m_STMask == other.m_STMask) - { - return cgi; - } - } - InstContainerByHash findByHash; - InstContainer* pInstCont = &m_Insts; - THWInstanceLookupMap* pInstMap = &m_LookupMap; - uint32 identHash = Ident.PostCreate(); - if (m_bUseLookUpTable) - { - uint64 uiKey = Ident.m_RTMask + Ident.m_GLMask + Ident.m_LightMask + Ident.m_MDMask + Ident.m_MDVMask + Ident.m_pipelineState.opaque + Ident.m_STMask; - - std::pair itp = pInstMap->equal_range(uiKey); - for (THWInstanceLookupMap::iterator it = itp.first; it != itp.second; ++it) - { - // use index redirection - uint32 uiIndex = it->second; - cgi = (*pInstCont)[uiIndex]; - if (cgi->m_Ident.m_nHash == identHash) - { - m_pCurInst = cgi; - return cgi; - } - } - cgi = new SHWSInstance; - cgi->m_nContIndex = pInstCont->size(); - cgi->m_vertexFormat = pSH->m_vertexFormat; - cgi->m_nCache = -1; - s_nInstFrame++; - cgi->m_Ident = Ident; - cgi->m_eClass = m_eSHClass; - pInstCont->push_back(cgi); - uint32 uiIndex = pInstCont->size() - 1; - if (nFlags & HWSF_FAKE) - { - cgi->m_Handle.SetFake(); - //mfSetHWStartProfile(nFlags); - } - - // only store index to object instead of pointer itself - // else we have lots of issues with the internal resize - // functionality of the vector itself (does some strange - // allocation stuff once above 20 000 members) - pInstMap->insert(std::pair(uiKey, uiIndex)); - } - else - { - cgi = 0; - - //int nFree = -1; - - // Find first matching shader RT bit flag combination (CRC hash identification) - InstContainerIt it = std::lower_bound(pInstCont->begin(), pInstCont->end(), identHash, findByHash); - if (it != pInstCont->end() && identHash == (*it)->m_Ident.m_nHash) - { -#ifdef _RELEASE - cgi = *it; // release - return the first matching shader permutation -#else - - // If not release, run over all matching shaders permutations and look for matching CRC hash - while (it != pInstCont->end() && identHash == (*it)->m_Ident.m_nHash) - { - const SShaderCombIdent& other = (*it)->m_Ident; - if ((Ident.m_MDVMask & ~SF_PLATFORM) == other.m_MDVMask && Ident.m_RTMask == other.m_RTMask - && Ident.m_GLMask == other.m_GLMask && Ident.m_FastCompare1 == other.m_FastCompare1 - && Ident.m_pipelineState.opaque == other.m_pipelineState.opaque && Ident.m_STMask == other.m_STMask) - { - cgi = *it; - break; - } - - // Matching CRC hash was found, but the shader permutation bits do not match - this is a CRC - // wrongly matched due to small chance of having same CRC over different bits - iLog->Log("Error: ShaderIdent hash value not unique - matching two different shader permutations with same CRC!"); - - // Move to the next iterator, hoping to have a match with the right permutation - ++it; - } - - - // No matching permutation was found: - // If a matching CRC hash was found, set the iterator to the last matching CRC on the list, - // otherwise set it to the last iterator. - if (cgi == 0) - { - --it; - } -#endif - } - - // Either the CRC was not found, or no match permutation was found - in either case create - // a new entry and insert it to the table. - if (cgi == 0) - { - cgi = new SHWSInstance; - cgi->m_nContIndex = pInstCont->size(); - cgi->m_vertexFormat = pSH->m_vertexFormat; - cgi->m_nCache = -1; - s_nInstFrame++; - cgi->m_Ident = Ident; - cgi->m_eClass = m_eSHClass; - pInstCont->insert(it, cgi); - if (nFlags & HWSF_FAKE) - { - cgi->m_Handle.SetFake(); - //mfSetHWStartProfile(nFlags); - } - } - } - m_pCurInst = cgi; - return cgi; -} - -//================================================================================= - -void CHWShader_D3D::mfSetForOverdraw(SHWSInstance* pInst, uint32 nFlags, uint64& RTMask) -{ - if (mfIsValid(pInst, false) == ED3DShError_NotCompiled) - { - mfActivate(gRenDev->m_RP.m_pShader, nFlags); - } - RTMask |= g_HWSR_MaskBit[HWSR_DEBUG0] | g_HWSR_MaskBit[HWSR_DEBUG1] | g_HWSR_MaskBit[HWSR_DEBUG2] | g_HWSR_MaskBit[HWSR_DEBUG3]; - RTMask &= m_nMaskAnd_RT; - RTMask |= m_nMaskOr_RT; - CD3D9Renderer* rd = gcpRendD3D; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw == 1 && m_eSHClass == eHWSC_Pixel) - { - rd->m_RP.m_NumShaderInstructions = pInst->m_nInstructions; - } - else - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw == 3 && m_eSHClass == eHWSC_Vertex) - { - rd->m_RP.m_NumShaderInstructions = pInst->m_nInstructions; - } - else - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw == 2 || CRenderer::CV_r_measureoverdraw == 4) - { - rd->m_RP.m_NumShaderInstructions = 30; - } -} - - -void CHWShader_D3D::ModifyLTMask(uint32& nMask) -{ - if (nMask) - { - if (!(m_Flags & (HWSG_SUPPORTS_MULTILIGHTS | HWSG_SUPPORTS_LIGHTING | HWSG_FP_EMULATION))) - { - nMask = 0; - } - else - if (!(m_Flags & HWSG_SUPPORTS_MULTILIGHTS) && (m_Flags & HWSG_SUPPORTS_LIGHTING)) - { - int nLightType = (nMask >> SLMF_LTYPE_SHIFT) & SLMF_TYPE_MASK; - if (nLightType != SLMF_PROJECTED) - { - nMask = 1; - } - } - } -} - -bool CHWShader_D3D::mfSetVS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetVS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD; - Ident.m_MDVMask = rRP.m_FlagsShader_MDV | CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - - ModifyLTMask(Ident.m_LightMask); - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw == 3) - { - mfSetForOverdraw(pInst, nFlags, Ident.m_RTMask); - pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - } - - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstVS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Vertex); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX VShader \"%s\" (%d instr), LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, PSS: 0x%llx, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_pipelineState.opaque, Ident.m_STMask); - } -#endif - if (m_nFrame != rTI.m_nFrameUpdateID) - { - m_nFrame = rTI.m_nFrameUpdateID; -#ifndef _RELEASE - rRP.m_PS[rRP.m_nProcessThreadID].m_NumVShaders++; - if (pInst->m_nInstructions > rRP.m_PS[rRP.m_nProcessThreadID].m_NumVSInstructions) - { - rRP.m_PS[rRP.m_nProcessThreadID].m_NumVSInstructions = pInst->m_nInstructions; - rRP.m_PS[rRP.m_nProcessThreadID].m_pMaxVShader = this; - rRP.m_PS[rRP.m_nProcessThreadID].m_pMaxVSInstance = pInst; - } -#endif - } - if (!(nFlags & HWSF_PRECACHE)) - { - if (s_pCurVS != pInst->m_Handle.m_pShader) - { - s_pCurVS = pInst->m_Handle.m_pShader; -#ifndef _RELEASE - rRP.m_PS[rRP.m_nProcessThreadID].m_NumVShadChanges++; -#endif - mfBind(); - } - s_pCurInstVS = pInst; - rRP.m_FlagsStreams_Decl = pInst->m_VStreamMask_Decl; - rRP.m_FlagsStreams_Stream = pInst->m_VStreamMask_Stream; - // Make sure we don't use any texture attributes except baseTC in instancing case - if (nFlags & HWSF_INSTANCED) - { - rRP.m_FlagsStreams_Decl &= ~(VSM_MORPHBUDDY); - rRP.m_FlagsStreams_Stream &= ~(VSM_MORPHBUDDY); - } - - UpdatePerBatchConstantBuffer(); - } - if (nFlags & HWSF_SETTEXTURES) - { - mfSetSamplers(pInst->m_pSamplers, m_eSHClass); - } - - s_nActivationFailMask &= ~(1 << eHWSC_Vertex); - - return true; -} - -bool CHWShader_D3D::mfSetPS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetPS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD & ~HWMD_TEXCOORD_FLAG_MASK; - Ident.m_MDVMask = CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - - ModifyLTMask(Ident.m_LightMask); - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - - // Update texture modificator flags based on active samplers state - if (nFlags & HWSF_SETTEXTURES) - { - int nResult = mfCheckActivation(rRP.m_pShader, pInst, nFlags); - if (!nResult) - { - CHWShader_D3D::s_pCurInstPS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Pixel); - return false; - } - mfUpdateSamplers(rRP.m_pShader); - if ((rRP.m_FlagsShader_MD ^ Ident.m_MDMask) & ~HWMD_TEXCOORD_FLAG_MASK) - { - pInst->m_fLastAccess = rTI.m_RealTime; - if (rd->m_nFrameSwapID != pInst->m_nUsedFrame) - { - pInst->m_nUsedFrame = rd->m_nFrameSwapID; - pInst->m_nUsed++; - } - Ident.m_MDMask = rRP.m_FlagsShader_MD & ~HWMD_TEXCOORD_FLAG_MASK; - Ident.m_MDVMask = CParserBin::m_nPlatform; - pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - } - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_measureoverdraw > 0 && CRenderer::CV_r_measureoverdraw < 5) - { - mfSetForOverdraw(pInst, nFlags, Ident.m_RTMask); - pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - } - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstPS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Pixel); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX PShader \"%s\" (%d instr) LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, PSS: 0x%llx, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask & 0x0fffffff, Ident.m_pipelineState.opaque, Ident.m_STMask); - } -#endif - - if (m_nFrame != rTI.m_nFrameUpdateID) - { - m_nFrame = rTI.m_nFrameUpdateID; -#ifndef _RELEASE - rRP.m_PS[rRP.m_nProcessThreadID].m_NumPShaders++; - if (pInst->m_nInstructions > rRP.m_PS[rRP.m_nProcessThreadID].m_NumPSInstructions) - { - rRP.m_PS[rRP.m_nProcessThreadID].m_NumPSInstructions = pInst->m_nInstructions; - rRP.m_PS[rRP.m_nProcessThreadID].m_pMaxPShader = this; - rRP.m_PS[rRP.m_nProcessThreadID].m_pMaxPSInstance = pInst; - } -#endif - } - if (!(nFlags & HWSF_PRECACHE)) - { - if (s_pCurPS != pInst->m_Handle.m_pShader) - { - s_pCurPS = pInst->m_Handle.m_pShader; -#ifndef _RELEASE - rRP.m_PS[rRP.m_nProcessThreadID].m_NumPShadChanges++; -#endif - mfBind(); - } - s_pCurInstPS = pInst; - UpdatePerBatchConstantBuffer(); - if (nFlags & HWSF_SETTEXTURES) - { - mfSetSamplers(pInst->m_pSamplers, m_eSHClass); - } - } - - s_nActivationFailMask &= ~(1 << eHWSC_Pixel); - - return true; -} - -bool CHWShader_D3D::mfSetGS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetGS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD; - Ident.m_MDVMask = rRP.m_FlagsShader_MDV | CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - - ModifyLTMask(Ident.m_LightMask); - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstGS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Geometry); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX GShader \"%s\" (%d instr), LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, PSS: 0x%llx, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_pipelineState.opaque, Ident.m_STMask); - } -#endif - - rRP.m_PersFlags2 |= s_bFirstGS * (RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - rRP.m_nCommitFlags |= s_bFirstGS * (FC_GLOBAL_PARAMS); - - s_bFirstGS = false; - s_pCurInstGS = pInst; - if (!(nFlags & HWSF_PRECACHE)) - { - mfBindGS(pInst->m_Handle.m_pShader, pInst->m_Handle.m_pShader->m_pHandle); - - UpdatePerBatchConstantBuffer(); - - if (nFlags & HWSF_SETTEXTURES) - { - mfSetSamplers(pInst->m_pSamplers, m_eSHClass); - } - } - - s_nActivationFailMask &= ~(1 << eHWSC_Geometry); - - return true; -} - -bool CHWShader_D3D::mfSetHS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetHS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD; - Ident.m_MDVMask = rRP.m_FlagsShader_MDV | CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - ModifyLTMask(Ident.m_LightMask); - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstHS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Hull); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX HShader \"%s\" (%d instr), LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, PSS: 0x%llx, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_pipelineState.opaque, Ident.m_STMask); - } -#endif - - rRP.m_PersFlags2 |= s_bFirstHS * (RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - rRP.m_nCommitFlags |= s_bFirstHS * (FC_GLOBAL_PARAMS); - - s_bFirstHS = false; - s_pCurInstHS = pInst; - if (!(nFlags & HWSF_PRECACHE)) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DHWShader_cpp) -#endif - - mfBindHS(pInst->m_Handle.m_pShader, pInst->m_Handle.m_pShader->m_pHandle); - - UpdatePerBatchConstantBuffer(); - } - - s_nActivationFailMask &= ~(1 << eHWSC_Hull); - - return true; -} - -bool CHWShader_D3D::mfSetDS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetDS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD; - Ident.m_MDVMask = rRP.m_FlagsShader_MDV | CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - - ModifyLTMask(Ident.m_LightMask); - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstDS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Domain); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX CShader \"%s\" (%d instr), LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, PSS: 0x%llx, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_pipelineState.opaque, Ident.m_STMask); - } -#endif - - rRP.m_PersFlags2 |= s_bFirstDS * (RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - rRP.m_nCommitFlags |= s_bFirstDS * (FC_GLOBAL_PARAMS); - - s_bFirstDS = false; - s_pCurInstDS = pInst; - if (!(nFlags & HWSF_PRECACHE)) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADER_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DHWShader_cpp) -#endif - - mfBindDS(pInst->m_Handle.m_pShader, pInst->m_Handle.m_pShader->m_pHandle); - - UpdatePerBatchConstantBuffer(); - } - - if (nFlags & HWSF_SETTEXTURES) - { - mfSetSamplers(pInst->m_pSamplers, m_eSHClass); - } - - s_nActivationFailMask &= ~(1 << eHWSC_Domain); - - return true; -} - -bool CHWShader_D3D::mfSetCS(int nFlags) -{ - DETAILED_PROFILE_MARKER("mfSetCS"); - - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - SThreadInfo& RESTRICT_REFERENCE rTI = rRP.m_TI[rRP.m_nProcessThreadID]; - - SShaderCombIdent Ident; - Ident.m_LightMask = rRP.m_FlagsShader_LT; - Ident.m_RTMask = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Ident.m_MDMask = rRP.m_FlagsShader_MD; - Ident.m_MDVMask = rRP.m_FlagsShader_MDV | CParserBin::m_nPlatform; - Ident.m_GLMask = m_nMaskGenShader; - Ident.m_STMask = m_maskGenStatic; - - if (Ident.m_LightMask) - { - if (!(m_Flags & (HWSG_SUPPORTS_MULTILIGHTS | HWSG_SUPPORTS_LIGHTING | HWSG_FP_EMULATION))) - { - Ident.m_LightMask = 0; - } - else - if (!(m_Flags & HWSG_SUPPORTS_MULTILIGHTS) && (m_Flags & HWSG_SUPPORTS_LIGHTING)) - { - int nLightType = (Ident.m_LightMask >> SLMF_LTYPE_SHIFT) & SLMF_TYPE_MASK; - if (nLightType != SLMF_PROJECTED) - { - Ident.m_LightMask = 1; - } - } - } - - SHWSInstance* pInst = mfGetInstance(rRP.m_pShader, Ident, nFlags); - pInst->m_fLastAccess = rTI.m_RealTime; - - if (!mfCheckActivation(rRP.m_pShader, pInst, nFlags)) - { - s_pCurInstCS = NULL; - s_nActivationFailMask |= (1 << eHWSC_Compute); - return false; - } - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - rd->Logv(SRendItem::m_RecurseLevel[rRP.m_nProcessThreadID], "--- Set FX CShader \"%s\" (%d instr), LTMask: 0x%x, GLMask: 0x%llx, RTMask: 0x%llx, MDMask: 0x%x, MDVMask: 0x%x, STMask: 0x%llx\n", GetName(), pInst->m_nInstructions, Ident.m_LightMask, Ident.m_GLMask, Ident.m_RTMask, Ident.m_MDMask, Ident.m_MDVMask, Ident.m_STMask); - } -#endif - - s_pCurInstCS = pInst; - if (!(nFlags & HWSF_PRECACHE)) - { - mfBindCS(pInst->m_Handle.m_pShader, pInst->m_Handle.m_pShader->m_pHandle); - - UpdatePerBatchConstantBuffer(); - } - - if (nFlags & HWSF_SETTEXTURES) - { - mfSetSamplers(pInst->m_pSamplers, m_eSHClass); - } - - s_nActivationFailMask = 0; // Reset entire mask since CS does not need any other shader stages - - return true; -} - -void CHWShader_D3D::mfUpdatePreprocessFlags(SShaderTechnique* pTech) -{ - DETAILED_PROFILE_MARKER("mfUpdatePreprocessFlags"); - uint32 nFlags = 0; - - for (uint32 i = 0; i < (uint32)m_Insts.size(); i++) - { - SHWSInstance* pInst = m_Insts[i]; - if (pInst->m_pSamplers.size()) - { - for (uint32 j = 0; j < (uint32)pInst->m_pSamplers.size(); j++) - { - STexSamplerRT* pSamp = &pInst->m_pSamplers[j]; - if (pSamp && pSamp->m_pTarget) - { - SHRenderTarget* pTarg = pSamp->m_pTarget; - if (pTarg->m_eOrder == eRO_PreProcess) - { - nFlags |= pTarg->m_nProcessFlags; - } - if (pTech) - { - uint32 n = 0; - for (n = 0; n < pTech->m_RTargets.Num(); n++) - { - if (pTarg == pTech->m_RTargets[n]) - { - break; - } - } - if (n == pTech->m_RTargets.Num()) - { - pTech->m_RTargets.AddElem(pTarg); - } - } - } - } - } - } - if (pTech) - { - pTech->m_RTargets.Shrink(); - pTech->m_nPreprocessFlags |= nFlags; - } -} - -AZ::u32 CHWShader_D3D::SHWSInstance::GenerateVertexDeclarationCacheKey(const AZ::Vertex::Format& vertexFormat) -{ - - // We cannot naively use the AZ::Vertex::Format CRC to cache the results of CreateInputLayout. - // CreateInputLayout compiles a fetch shader to associate the vertex format with the individual vertex shader instance. - // If the vertex shader does not reference one of the input semantics, then the fetch shader will not - AZ::u32 fetchShaderKey = ( m_uniqueNameCRC ^ vertexFormat.GetEnum() ); - - return fetchShaderKey; -} - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.h deleted file mode 100644 index 66d30e177d..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShader.h +++ /dev/null @@ -1,1177 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DHWShader_h) -#endif - -#define MERGE_SHADER_PARAMETERS 1 - -// Streams redefinitions (TEXCOORD#) -#define VSTR_COLOR1 4 //Base Stream -#define VSTR_NORMAL1 5 //Base Stream -#define VSTR_PSIZE 6 //Base particles stream -//#define VSTR_MORPHTARGETDELTA 7 // MorphTarget stream (VSF_HWSKIN_MORPHTARGET_INFO) -#define VSTR_TANGENT 8 // Tangents stream (VSF_TANGENTS) -#define VSTR_BITANGENT 9 // Tangents stream (VSF_TANGENTS) -> unused, remove -#define VSTR_BLENDWEIGHTS 10 // HWSkin stream (VSF_HWSKIN_INFO) -#define VSTR_BLENDINDICES 11 // HWSkin stream (VSF_HWSKIN_INFO) -#define VSTR_BONESPACE 12 // HWSkin stream (VSF_HWSKIN_INFO) - -#define INST_PARAM_SIZE sizeof(Vec4) - -#define MAX_PF_TEXTURES (32) -#define MAX_PF_SAMPLERS (4) - -#if defined(_CPU_SSE) -typedef __m128 VECTOR_TYPE; -#define VECTOR_CONST(x, y, z, w) { x, y, z, w } //{ w, z, y, x } -#define VECTOR_ZERO() _mm_setzero_ps() -#define VECTOR_XOR(a, b) _mm_xor_ps(a, b) -#else -union USoftVector -{ - struct - { - float x, y, z, w; - }; - uint32 u[4]; -}; - -#if defined(LINUX32) -typedef DEFINE_ALIGNED_DATA (USoftVector, VECTOR_TYPE, 8); -#else -typedef DEFINE_ALIGNED_DATA (USoftVector, VECTOR_TYPE, 16); -#endif - -#define VECTOR_CONST(x, y, z, w) { \ - { x, y, z, w } \ -} -const VECTOR_TYPE g_VectorZero = VECTOR_CONST(0.f, 0.f, 0.f, 0.f); -#define VECTOR_ZERO() (g_VectorZero) -inline VECTOR_TYPE VECTOR_XOR(const VECTOR_TYPE& a, const VECTOR_TYPE& b) -{ - VECTOR_TYPE r; - r.u[0] = a.u[0] ^ b.u[0]; - r.u[1] = a.u[1] ^ b.u[1]; - r.u[2] = a.u[2] ^ b.u[2]; - r.u[3] = a.u[3] ^ b.u[3]; - return r; -} -#endif - -union UFloat4 -{ - float f[4]; - VECTOR_TYPE m128; -}; - -namespace AzRHI{ class ConstantBuffer; } - -//============================================================================== - -int D3DXGetSHParamHandle(void* pSH, SCGBind* pParam); - -struct SParamsGroup -{ - std::vector Params[2]; - std::vector Params_Inst; -}; - -enum ED3DShError -{ - ED3DShError_NotCompiled, - ED3DShError_CompilingError, - ED3DShError_Fake, - ED3DShError_Ok, - ED3DShError_Compiling, -}; - -//==================================================================================== - -struct SCGParamsGroup -{ - uint16 nParams; - uint16 nSamplers; - uint16 nTextures; - SCGParam* pParams; - int nPool; - int nRefCounter; - SCGParamsGroup() - { - nParams = 0; - nPool = 0; - pParams = NULL; - nRefCounter = 1; - } - unsigned Size() { return sizeof(*this); } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - -#define PARAMS_POOL_SIZE 256 - -struct alloc_info_struct -{ - int ptr; - int bytes_num; - bool busy; - const char* szSource; - unsigned Size() { return sizeof(*this); } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - -struct SCGParamPool -{ -protected: - PodArray m_alloc_info; - Array m_Params; - -public: - - SCGParamPool(int nEntries = 0); - ~SCGParamPool(); - SCGParamsGroup Alloc(int nEntries); - bool Free(SCGParamsGroup& Group); - - size_t Size() - { - return sizeof(*this) + sizeOfV(m_alloc_info) + m_Params.size_mem(); - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_alloc_info); - pSizer->Add(m_Params.begin(), m_Params.size()); - } -}; - -template<> -inline bool raw_movable(const SCGParamPool&) -{ - return true; -} - -class CGParamManager -{ - friend class CHWShader_D3D; - //friend struct CHWShader_D3D::SHWSInstance; - - static AZStd::vector s_FreeGroups; - -public: - static void Init(); - static void Shutdown(); - - static SCGParamPool* NewPool(int nEntries); - static int GetParametersGroup(SParamsGroup& Gr, int nId); - static bool FreeParametersGroup(int nID); - - static AZStd::vector s_Groups; - static DynArray s_Pools; -}; - -//========================================================================================= - -struct SD3DShader -{ - int m_nRef; - void* m_pHandle; - bool m_bBound; - - SD3DShader() - { - m_nRef = 1; - m_pHandle = NULL; - m_bBound = false; - } - int AddRef() - { - return m_nRef++; - } - int Release(EHWShaderClass eSHClass, int nSize); - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -struct SD3DShaderHandle -{ - SD3DShader* m_pShader; - byte* m_pData; - int m_nData; - byte m_bStatus; - SD3DShaderHandle() - { - m_pShader = NULL; - m_bStatus = 0; - m_nData = 0; - m_pData = NULL; - } - void SetShader(SD3DShader* pShader) - { - m_bStatus = 0; - m_pShader = pShader; - } - void SetFake() - { - m_bStatus = 2; - } - void SetNonCompilable() - { - m_bStatus = 1; - } - int AddRef() - { - if (!m_pShader) - { - return 0; - } - return m_pShader->AddRef(); - } - int Release(EHWShaderClass eSHClass, int nSize) - { - if (!m_pShader) - { - return 0; - } - return m_pShader->Release(eSHClass, nSize); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_pShader); - } -}; - -struct SShaderAsyncInfo -{ - SShaderAsyncInfo* m_Next; //!< - SShaderAsyncInfo* m_Prev; //!< - inline void Unlink() - { - if (!m_Next || !m_Prev) - { - return; - } - m_Next->m_Prev = m_Prev; - m_Prev->m_Next = m_Next; - m_Next = m_Prev = NULL; - } - inline void Link(SShaderAsyncInfo* Before) - { - if (m_Next || m_Prev) - { - return; - } - m_Next = Before->m_Next; - Before->m_Next->m_Prev = this; - Before->m_Next = this; - m_Prev = Before; - } - static void FlushPendingShaders(); - -#if D3DHWSHADER_H_TRAIT_DEFINE_D3D_BLOB || defined(OPENGL) -#define LPD3DXBUFFER D3DBlob * -#define ID3DXBuffer D3DBlob -#define D3D10CreateBlob D3DCreateBlob -#endif - - int m_nHashInst; - uint64 m_RTMask; - uint32 m_LightMask; - uint32 m_MDMask; - uint32 m_MDVMask; - EHWShaderClass m_eClass; - UPipelineState m_pipelineState; - class CHWShader_D3D* m_pShader; - CShader* m_pFXShader; - - LPD3D10BLOB m_pDevShader; - LPD3D10BLOB m_pErrors; - void* m_pConstants; - string m_Name; - string m_Text; - string m_Errors; - string m_Profile; - string m_RequestLine; - string m_shaderList; - //CShaderThread *m_pThread; - AZStd::vector m_InstBindVars; - byte m_bPending; - bool m_bPendedFlush; - bool m_bPendedSamplers; - bool m_bPendedEnv; - bool m_bDeleteAfterRequest; - float m_fMinDistance; - int m_nFrame; - int m_nThread; - int m_nCombination; - - SShaderAsyncInfo() - : m_Next(nullptr) - , m_Prev(nullptr) - , m_nHashInst(-1) - , m_RTMask(0) - , m_LightMask(0) - , m_MDMask(0) - , m_MDVMask(0) - , m_eClass(eHWSC_Num) - , m_pShader(nullptr) - , m_pFXShader(nullptr) - , m_pDevShader(nullptr) - , m_pErrors(nullptr) - , m_pConstants(nullptr) - , m_bPending(true) // this flag is now used as an atomic indication that if the async shader has been compiled - , m_bPendedFlush(false) - , m_bPendedSamplers(false) - , m_bPendedEnv(false) - , m_bDeleteAfterRequest(false) - , m_fMinDistance(0.0f) - , m_nFrame(0) - , m_nThread(0) - , m_nCombination(-1) - { - } - - ~SShaderAsyncInfo(); - static volatile int s_nPendingAsyncShaders; - static SShaderAsyncInfo& PendingList(); - static SShaderAsyncInfo& PendingListT(); - static CryEvent s_RequestEv; -}; - -#ifdef SHADER_ASYNC_COMPILATION - -#include "CryThread.h" -#define SHADER_THREAD_NAME "ShaderCompile" - -class CAsyncShaderTask -{ - friend class CD3D9Renderer; // so it can instantiate us - -public: - CAsyncShaderTask(); - - static void InsertPendingShader(SShaderAsyncInfo* pAsync); - int GetThread() - { - return m_nThread; - } - int GetThreadFXC() - { - return m_nThreadFXC; - } - void SetThread(int nThread) - { - m_nThread = nThread; - m_nThreadFXC = -1; - } - void SetThreadFXC(int nThread) - { - m_nThreadFXC = nThread; - } - -private: - - void FlushPendingShaders(); - - static SShaderAsyncInfo& BuildList(); - SShaderAsyncInfo m_flush_list; - int m_nThread; - int m_nThreadFXC; - - class CShaderThread - : public CrySimpleThread<> - { - public: - CShaderThread(CAsyncShaderTask* task) - : m_task(task) - , m_quit(false) - { - CAsyncShaderTask::BuildList().m_Next = &CAsyncShaderTask::BuildList(); - CAsyncShaderTask::BuildList().m_Prev = &CAsyncShaderTask::BuildList(); - - task->m_flush_list.m_Next = &task->m_flush_list; - task->m_flush_list.m_Prev = &task->m_flush_list; - Start(); - } - - ~CShaderThread() - { - m_quit = true; - Stop(); - WaitForThread(); - } - - private: - void Run(); - - CAsyncShaderTask* m_task; - volatile bool m_quit; - }; - - CShaderThread m_thread; - - bool CompileAsyncShader(SShaderAsyncInfo* pAsync); - void SubmitAsyncRequestLine(SShaderAsyncInfo* pAsync); - bool PostCompile(SShaderAsyncInfo* pAsync); -}; -#endif - -class CHWShader_D3D - : public CHWShader -{ - friend class CD3D9Renderer; - friend class CAsyncShaderTask; - friend class CGParamManager; - friend struct SShaderAsyncInfo; - friend class CHWShader; - friend class CShaderMan; - friend struct InstContainerByHash; - friend class CREGeomCache; - friend struct SRenderStatePassD3D; - friend struct SDeviceObjectHelpers; - friend class CDeviceGraphicsCommandList; - friend class CDeviceGraphicsPSO; - friend class CDeviceGraphicsPSO_DX11; - friend class CDeviceGraphicsPSO_DX12; - friend class CGnmGraphicsPipelineState; - friend class CSceneGBufferPass; // HACK - - SShaderDevCache* m_pDevCache; - -#if !defined(_RELEASE) - static AZStd::unordered_set, AZStd::equal_to, AZ::StdLegacyAllocator> s_ErrorsLogged; // CRC32 of message, risk of collision acceptable -#endif - -#if !defined(CONSOLE) - SPreprocessTree* m_pTree; - CParserBin* m_pParser; -#endif - - struct SHWSInstance - { - friend struct SShaderAsyncInfo; - - SShaderCombIdent m_Ident; - - int m_nContIndex; - - SD3DShaderHandle m_Handle; - EHWShaderClass m_eClass; - - int m_nParams[2]; // 0: Instance independent; 1: Instance depended - - // Shader-specific data (unlike the static per frame which are shared) - std::vector m_pSamplers; - std::vector m_Samplers; - std::vector m_Textures; - std::vector m_pBindVars; - - int m_nParams_Inst; - float m_fLastAccess; - int m_nUsed; - int m_nUsedFrame; - int m_nFrameSubmit; - void* m_pShaderData; - int m_nMaxVecs[3]; - short m_nInstMatrixID; - short m_nInstIndex; - short m_nInstructions; - short m_nTempRegs; - uint16 m_VStreamMask_Stream; - uint16 m_VStreamMask_Decl; - short m_nCache; - short m_nParent; - byte m_bDeleted : 1; - byte m_bHasPMParams : 1; - byte m_bFallback : 1; - byte m_bCompressed : 1; - byte m_bAsyncActivating : 1; - byte m_bHasSendRequest : 1; - AZ::Vertex::Format m_vertexFormat; - byte m_nNumInstAttributes; - - int m_nDataSize; - int m_DeviceObjectID; - AZ::u32 m_uniqueNameCRC = 0; // CRC generated from the pattern: "Technique@EntryPoint(Permutations)" -#if defined(FEATURE_PER_SHADER_INPUT_LAYOUT_CACHE) - enum - { - NUM_CACHE = 2 - }; - ID3D11InputLayout* m_pInputLayout[NUM_CACHE]; - uint64 m_cacheID[NUM_CACHE]; -#endif - SShaderAsyncInfo* m_pAsync; - - SHWSInstance() - : m_Ident() - , m_nContIndex(0) - , m_Handle() - , m_eClass(eHWSC_Num) - , m_nParams_Inst(-1) - , m_fLastAccess(0.0f) - , m_nUsed(0) - , m_nUsedFrame(0) - , m_nFrameSubmit(0) - , m_pShaderData(nullptr) - , m_nInstMatrixID(1) - , m_nInstIndex(-1) - , m_nInstructions(0) - , m_nTempRegs(0) - , m_VStreamMask_Stream(0) - , m_VStreamMask_Decl(0) - , m_nCache(-1) - , m_nParent(-1) - , m_bDeleted(false) - , m_bHasPMParams(false) - , m_bFallback(false) - , m_bCompressed(false) - , m_bAsyncActivating(false) - , m_bHasSendRequest(false) - , m_vertexFormat(eVF_P3F_C4B_T2F) - , m_nNumInstAttributes(0) - , m_nDataSize(0) - , m_DeviceObjectID(-1) - , m_pAsync(nullptr) - { - m_nParams[0] = -1; - m_nParams[1] = -1; - m_nMaxVecs[0] = 0; - m_nMaxVecs[1] = 0; - m_nMaxVecs[2] = 0; - -#if defined(FEATURE_PER_SHADER_INPUT_LAYOUT_CACHE) - for (int i = 0; i < NUM_CACHE; ++i) - { - m_pInputLayout[i] = nullptr; - m_cacheID[i] = 0; - } -#endif - } - -#if defined(FEATURE_PER_SHADER_INPUT_LAYOUT_CACHE) - ~SHWSInstance() - { - for (uint i = 0; i < NUM_CACHE; ++i) - { - SAFE_RELEASE(m_pInputLayout[i]); - } - } - ID3D11InputLayout* GetCachedInputLayout(uint64 cacheID) - { - for (uint i = 0; i < NUM_CACHE; ++i) - { - if (cacheID == m_cacheID[i]) - { - return m_pInputLayout[i]; - } - } - return NULL; - } - void SetCachedInputLayout(ID3D11InputLayout* pInputLayout, uint64 cacheID) - { - // First try empy slot - for (uint i = 0; i < NUM_CACHE; ++i) - { - if (m_pInputLayout[i] == NULL) - { - m_pInputLayout[i] = pInputLayout; - m_cacheID[i] = cacheID; - return; - } - } - // Cache is full - look for matching InputLayout - for (uint i = 0; i < NUM_CACHE; ++i) - { - if (m_pInputLayout[i] == pInputLayout) - { - m_cacheID[i] = cacheID; - return; - } - } - // Replace first entry (cache is thrashing) - SAFE_RELEASE(m_pInputLayout[0]); - m_pInputLayout[0] = pInputLayout; - m_cacheID[0] = cacheID; - } -#endif - void Release(SShaderDevCache* pCache = NULL, bool bReleaseData = true); - void GetInstancingAttribInfo(uint8 Attributes[32], int32 & nUsedAttr, int& nInstAttrMask); - - int Size() - { - int nSize = sizeof(*this); - nSize += sizeOfV(m_pSamplers); - nSize += sizeOfV(m_pBindVars); - - return nSize; - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_Handle); - pSizer->AddObject(m_pSamplers); - pSizer->AddObject(m_pBindVars); - pSizer->AddObject(m_pShaderData, m_nDataSize); - } - - bool IsAsyncCompiling() - { - if (m_pAsync || m_bAsyncActivating) - { - return true; - } - - return false; - } - - // CreateInputLayout in D3D11 generates a unique resource depending on the vertex format and the compiled vertex shader. - // If an associated vertex shader does not reference certain vertexFormat inputs, then CreateInputLayout can return - // a result that will not work for other vertexFormat + vertex shader combinations that do reference the previously unreferenced input. - // On some platforms we must generate a key for SOnDemandD3DVertexDeclarationCache that is based both on the vertex shader binary and the vertex format layout. - AZ::u32 GenerateVertexDeclarationCacheKey(const AZ::Vertex::Format& vertexFormat); - }; - - typedef std::vector InstContainer; - typedef InstContainer::iterator InstContainerIt; - - using SCGTextures = AZStd::fixed_vector; - using SCGSamplers = AZStd::fixed_vector; - - typedef std::multimap THWInstanceLookupMap; - - THWInstanceLookupMap m_LookupMap; - bool m_bUseLookUpTable; - -public: - - SHWSInstance* m_pCurInst; - InstContainer m_Insts; - - static int m_FrameObj; - int m_nCurInstFrame; - - // Bin FX support - FXShaderToken m_TokenTable; - TArray m_TokenData; - - virtual int Size() - { - int nSize = sizeof(*this); - nSize += sizeOfVP(m_Insts); - nSize += sizeofVector(m_TokenData); - nSize += sizeOfV(m_TokenTable); - - return nSize; - } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pGlobalCache); - pSizer->AddObject(m_pDevCache); - pSizer->AddObject(m_Insts); - pSizer->AddObject(m_TokenData); - pSizer->AddObject(m_TokenTable); - } - CHWShader_D3D() - { -#if !defined(CONSOLE) - m_pTree = NULL; - m_pParser = NULL; -#endif - mfConstruct(); - } - - static void mfInit(); - void mfConstruct() - { - if (s_bInitShaders) - { - s_bInitShaders = false; - } - - m_pCurInst = NULL; - m_pDevCache = NULL; - m_nCurInstFrame = 0; - - m_dwShaderType = 0; - - m_bUseLookUpTable = false; - - } - - void mfFree(uint32 CRC32) - { -#if !defined(CONSOLE) - SAFE_DELETE(m_pTree); - SAFE_DELETE(m_pParser); -#endif - - m_Flags = 0; - mfReset(CRC32); - } - - // Binary cache support - SShaderCacheHeaderItem* mfGetCompressedItem(uint32 nFlags, int32& nSize); - SShaderCacheHeaderItem* mfGetCacheItem(uint32& nFlags, int32& nSize); - static bool mfAddCacheItem(SShaderCache* pCache, SShaderCacheHeaderItem* pItem, const byte* pData, int nLen, bool bFlush, CCryNameTSCRC Name); - - bool mfCloseCacheFile() - { - SAFE_RELEASE (m_pDevCache); - SAFE_RELEASE (m_pGlobalCache); - - return true; - } - - static byte* mfBindsToCache(SHWSInstance* pInst, std::vector* Binds, int nParams, byte* pP); - byte* mfBindsFromCache(std::vector*& Binds, int nParams, byte* pP); - - bool mfActivateCacheItem(CShader* pSH, SShaderCacheHeaderItem* pItem, uint32 nSize, uint32 nFlags); - static bool mfCreateCacheItem(SHWSInstance* pInst, std::vector& InstBinds, byte* pData, int nLen, CHWShader_D3D* pSH, bool bShaderThread); - - int mfGetParams(int Type) - { - assert(m_pCurInst); - return m_pCurInst->m_nParams[Type]; - } - - bool mfSetHWStartProfile(uint32 nFlags); - - void mfSaveCGFile(const char* scr, const char* path); - void mfOutputCompilerError(string& strErr, const char* szSrc); - static bool mfCreateShaderEnv(int nThread, SHWSInstance* pInst, LPD3D10BLOB pShader, void* pConstantTable, LPD3D10BLOB pErrorMsgs, std::vector& InstBindVars, CHWShader_D3D* pSH, bool bShaderThread, CShader* pFXShader, int nCombination, const char* src = NULL); - void mfPrintCompileInfo(SHWSInstance* pInst); - bool mfCompileHLSL_Int(CShader* pSH, char* prog_text, LPD3D10BLOB* ppShader, void** ppConstantTable, LPD3D10BLOB* ppErrorMsgs, string& strErr, std::vector& InstBindVars); - - int mfAsyncCompileReady(SHWSInstance* pInst); - bool mfRequestAsync(CShader* pSH, SHWSInstance* pInst, std::vector& InstBindVars, const char* prog_text, const char* szProfile, const char* szEntry); - - void mfSubmitRequestLine(SHWSInstance* pInst, string* pRequestLine = NULL); - LPD3D10BLOB mfCompileHLSL(CShader* pSH, char* prog_text, void** ppConstantTable, LPD3D10BLOB* ppErrorMsgs, uint32 nFlags, std::vector& InstBindVars); - bool mfUploadHW(SHWSInstance* pInst, byte* pBuf, uint32 nSize, CShader* pSH, uint32 nFlags); - bool mfUploadHW(LPD3D10BLOB pShader, SHWSInstance* pInst, CShader* pSH, uint32 nFlags); - - ED3DShError mfIsValid_Int(SHWSInstance*& pInst, bool bFinalise); - - //ILINE most common outcome - ILINE ED3DShError mfIsValid(SHWSInstance*& pInst, bool bFinalise) - { - if (pInst->m_Handle.m_pShader) - { - return ED3DShError_Ok; - } - if (pInst->m_bAsyncActivating) - { - return ED3DShError_NotCompiled; - } - - return mfIsValid_Int(pInst, bFinalise); - } - - ED3DShError mfFallBack(SHWSInstance*& pInst, int nStatus); - void mfCommitCombinations(int nFrame, int nFrameDiff); - void mfCommitCombination(SHWSInstance* pInst, int nFrame, int nFrameDiff); - void mfLogShaderCacheMiss(SHWSInstance* pInst); - void mfLogShaderRequest(SHWSInstance* pInst); - - void mfBindInstance(SHWSInstance *pInst, EHWShaderClass eHWSC) - { - m_pCurInst = pInst; - if (eHWSC == eHWSC_Vertex) - { - s_pCurInstVS = pInst; - if (s_pCurVS != pInst->m_Handle.m_pShader) - { - s_pCurVS = pInst->m_Handle.m_pShader; -#ifndef _RELEASE - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_NumVShadChanges++; -#endif - mfBind(); - } - } - else if (eHWSC == eHWSC_Pixel) - { - s_pCurInstPS = pInst; - if (s_pCurPS != pInst->m_Handle.m_pShader) - { - s_pCurPS = pInst->m_Handle.m_pShader; -#ifndef _RELEASE - gRenDev->m_RP.m_PS[gRenDev->m_RP.m_nProcessThreadID].m_NumPShadChanges++; -#endif - mfBind(); - } - } - } - - void mfBind() - { - if (mfIsValid(m_pCurInst, true) == ED3DShError_Ok) - { - if (gRenDev->m_nFrameSwapID != m_pCurInst->m_nUsedFrame) - { - m_pCurInst->m_nUsedFrame = gRenDev->m_nFrameSwapID; - m_pCurInst->m_nUsed++; - } - gcpRendD3D->m_DevMan.BindShader(m_eSHClass, (ID3D11Resource*)m_pCurInst->m_Handle.m_pShader->m_pHandle); - } - } - - static inline void mfBindGS(SD3DShader* pShader, void* pHandle) - { - if (s_pCurGS != pShader) - { - s_pCurGS = pShader; -#if !defined(_RELEASE) - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_NumGShadChanges++; -#endif - gcpRendD3D->GetDeviceContext().GSSetShader((ID3D11GeometryShader*)pHandle, NULL, 0); - } - if (!s_pCurGS) - { - s_pCurInstGS = NULL; - s_nActivationFailMask &= ~(1 << eHWSC_Geometry); - } - } - static inline void mfBindDS(SD3DShader* pShader, void* pHandle) - { - if (s_pCurDS != pShader) - { - s_pCurDS = pShader; -#if !defined(_RELEASE) - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_NumDShadChanges++; -#endif - gcpRendD3D->GetDeviceContext().DSSetShader((ID3D11DomainShader*)pHandle, NULL, 0); - } - if (!s_pCurDS) - { - s_pCurInstDS = NULL; - s_nActivationFailMask &= ~(1 << eHWSC_Domain); - } - } - static inline void mfBindHS(SD3DShader* pShader, void* pHandle) - { - if (s_pCurHS != pShader) - { - s_pCurHS = pShader; -#if !defined(_RELEASE) - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_NumHShadChanges++; -#endif - gcpRendD3D->GetDeviceContext().HSSetShader((ID3D11HullShader*)pHandle, NULL, 0); - } - if (!s_pCurHS) - { - s_pCurInstHS = NULL; - s_nActivationFailMask &= ~(1 << eHWSC_Hull); - } - } - static inline void mfBindCS(SD3DShader* pShader, void* pHandle) - { - if (s_pCurCS != pShader) - { - s_pCurCS = pShader; -#if !defined(_RELEASE) - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_NumCShadChanges++; -#endif - gcpRendD3D->GetDeviceContext().CSSetShader((ID3D11ComputeShader*)pHandle, NULL, 0); - } - if (!s_pCurCS) - { - s_pCurInstCS = NULL; - s_nActivationFailMask &= ~(1 << eHWSC_Compute); - } - } - - static void UpdatePerMaterialConstantBuffer(); - static void mfCommitParamsGlobal(); - - SCGBind* mfGetParameterBind(const CCryNameR& Name) - { - if (!m_pCurInst) - { - return NULL; - } - - std::vector& pBinds = m_pCurInst->m_pBindVars; - int i; - int nSize = pBinds.size(); - for (i = 0; i < nSize; i++) - { - if (Name == pBinds[i].m_Name) - { - return &pBinds[i]; - } - } - return NULL; - } - - static void UpdatePerInstanceConstants( - EHWShaderClass shaderClass, - const SCGParam* parameters, - AZ::u32 parameterCount, - void* outputData); - - void UpdatePerInstanceConstantBuffer(); - void UpdatePerBatchConstantBuffer(); - static void UpdatePerFrameResourceGroup(); - - inline void mfSetSamplers(const std::vector& Samplers, EHWShaderClass eHWClass) - { - mfSetSamplers_Old(Samplers, eHWClass); - if (!m_pCurInst) - { - return; - } - SHWSInstance* pInst = m_pCurInst; - mfSetSamplers(pInst->m_Samplers, eHWClass); - mfSetTextures(pInst->m_Textures, eHWClass); - } - - void mfLostDevice(SHWSInstance* pInst, byte* pBuf, int nSize) - { - pInst->m_Handle.SetFake(); - pInst->m_Handle.m_pData = new byte[nSize]; - memcpy(pInst->m_Handle.m_pData, pBuf, nSize); - pInst->m_Handle.m_nData = nSize; - } - - ILINE int mfCheckActivation(CShader* pSH, SHWSInstance*& pInst, uint32 nFlags) - { - ED3DShError eError = mfIsValid(pInst, true); - if (eError == ED3DShError_NotCompiled) - { - if (!mfActivate(pSH, nFlags)) - { - pInst = m_pCurInst; - if (gRenDev->m_cEF.m_bActivatePhase) - { - return 0; - } - if (!pInst->IsAsyncCompiling()) - { - pInst->m_Handle.SetNonCompilable(); - } - else - { - eError = mfIsValid(pInst, true); - if (eError == ED3DShError_CompilingError || pInst->m_bAsyncActivating) - { - return 0; - } - if (m_eSHClass == eHWSC_Vertex) - { - return 1; - } - else - { - return -1; - } - } - return 0; - } - if (gRenDev->m_RP.m_pCurTechnique) - { - mfUpdatePreprocessFlags(gRenDev->m_RP.m_pCurTechnique); - } - pInst = m_pCurInst; - } - else - if (eError == ED3DShError_Fake) - { - if (pInst->m_Handle.m_pData) - { - if (gRenDev && !gRenDev->CheckDeviceLost()) - { - mfUploadHW(pInst, pInst->m_Handle.m_pData, pInst->m_Handle.m_nData, pSH, nFlags); - SAFE_DELETE_ARRAY(pInst->m_Handle.m_pData); - pInst->m_Handle.m_nData = 0; - } - else - { - eError = ED3DShError_CompilingError; - } - } - } - if (eError == ED3DShError_CompilingError) - { - return 0; - } - return 1; - } - - void mfSetForOverdraw(SHWSInstance* pInst, uint32 nFlags, uint64& RTMask); - -#if !defined(_RELEASE) - static void LogSamplerTextureMismatch(const CTexture* pTex, const STexSamplerRT* pSampler, EHWShaderClass shaderClass, const char* pMaterialName); -#endif - static bool mfSetTextures(const std::vector& Textures, EHWShaderClass eHWClass); - static bool mfSetSamplers(const std::vector& Samplers, EHWShaderClass eHWClass); - static bool mfSetSamplers_Old(const std::vector& Samplers, EHWShaderClass eHWClass); - SHWSInstance* mfGetInstance(CShader* pSH, SShaderCombIdent& Ident, uint32 nFlags); - SHWSInstance* mfGetInstance(CShader* pSH, int nHashInstance, uint64 GLMask); - static void mfPrepareShaderDebugInfo(SHWSInstance* pInst, CHWShader_D3D* pSH, const char* szAsm, std::vector& InstBindVars, void* pBuffer); - void mfGetSrcFileName(char* srcName, int nSize); - static void mfGetDstFileName(SHWSInstance* pInst, CHWShader_D3D* pSH, char* dstname, int nSize, byte bType); - static void mfGenName(SHWSInstance* pInst, char* dstname, int nSize, byte bType); - void CorrectScriptEnums(CParserBin& Parser, SHWSInstance* pInst, std::vector& InstBindVars, FXShaderToken* Table); - bool ConvertBinScriptToASCII(CParserBin& Parser, SHWSInstance* pInst, std::vector& InstBindVars, FXShaderToken* Table, TArray& Scr); - void RemoveUnaffectedParameters_D3D10(CParserBin& Parser, SHWSInstance* pInst, std::vector& InstBindVars); - bool mfStoreCacheTokenMap(FXShaderToken*& Table, TArray*& pSHData, const char* szName); - void mfGetTokenMap(CResFile* pRes, SDirEntry* pDE, FXShaderToken*& Table, TArray*& pSHData); - void mfSetDefaultRT(uint64& nAndMask, uint64& nOrMask); - -public: - bool mfGetCacheTokenMap(FXShaderToken*& Table, TArray*& pSHData, uint64 nMaskGen); - bool mfGenerateScript(CShader* pSH, SHWSInstance*& pInst, std::vector& InstBindVars, uint32 nFlags, FXShaderToken* Table, TArray* pSHData, TArray& sNewScr); - bool mfActivate(CShader* pSH, uint32 nFlags, FXShaderToken* Table = NULL, TArray* pSHData = NULL, bool bCompressedOnly = false); - - void SetTokenFlags(uint32 nToken); - uint64 CheckToken(uint32 nToken); - uint64 CheckIfExpr_r(uint32* pTokens, uint32& nCur, uint32 nSize); - void mfConstructFX_Mask_RT(FXShaderToken* Table, TArray* pSHData); - void mfConstructFX(FXShaderToken* Table, TArray* pSHData); - - static bool mfAddFXSampler(SHWSInstance* pInst, SShaderFXParams& FXParams, SFXSampler* pr, const char* ParamName, SCGBind* pBind, CShader* ef, EHWShaderClass eSHClass); - static bool mfAddFXTexture(SHWSInstance* pInst, SShaderFXParams& FXParams, SFXTexture* pr, const char* ParamName, SCGBind* pBind, CShader* ef, EHWShaderClass eSHClass); - - /* - Add shader parameters during the shader parsing. A parameters can be Sampler, Texture or Constant - */ - static void mfAddFXParameter(SHWSInstance* pInst, SParamsGroup& OutParams, SShaderFXParams& FXParams, SFXParam* pr, const char* ParamName, SCGBind* pBind, CShader* ef, bool bInstParam, EHWShaderClass eSHClass); - static bool mfAddFXParameter(SHWSInstance* pInst, SParamsGroup& OutParams, SShaderFXParams& FXParams, const char* param, SCGBind* bn, bool bInstParam, EHWShaderClass eSHClass, CShader* pFXShader); - - static void mfGatherFXParameters(SHWSInstance* pInst, std::vector* InstBindVars, CHWShader_D3D* pSH, int nFlags, CShader* pFXShader); - - /* - Associates the final binding of all resources slots per shader instance. - */ - static void mfCreateBinds(SHWSInstance* pInst, void* pConstantTable, byte* pShader, int nSize); - - bool mfUpdateSamplers(CShader* shader); - static void mfPostVertexFormat(SHWSInstance * pInst, CHWShader_D3D * pHWSH, bool bCol, byte bNormal, bool bTC0, bool bTC1, bool bPSize, bool bTangent[2], bool bBitangent[2], bool bHWSkin, bool bSH[2], bool bMorphTarget, bool bMorph); - void mfUpdateFXVertexFormat(SHWSInstance* pInst, CShader* pSH); - - void ModifyLTMask(uint32& nMask); - -public: - virtual ~CHWShader_D3D(); - bool mfSetVS(int nFlags = 0); - bool mfSetPS(int nFlags = 0); - bool mfSetGS(int nFlags = 0); - bool mfSetHS(int nFlags = 0); - bool mfSetCS(int nFlags = 0); - bool mfSetDS(int nFlags = 0); - - inline bool mfSet(int nFlags = 0) - { - switch (m_eSHClass) - { - case eHWSC_Vertex: - return mfSetVS(nFlags); - case eHWSC_Pixel: - return mfSetPS(nFlags); - case eHWSC_Geometry: - return mfSetGS(nFlags); - case eHWSC_Compute: - return mfSetCS(nFlags); - case eHWSC_Hull: - return mfSetHS(nFlags); - case eHWSC_Domain: - return mfSetDS(nFlags); - } - return false; - } - - virtual bool mfAddEmptyCombination(CShader* pSH, uint64 nRT, uint64 nGL, uint32 nLT); - virtual bool mfStoreEmptyCombination(SEmptyCombination& Comb); - virtual bool mfSetV(int nFlags = 0){ return mfSet(nFlags); }; - virtual void mfReset(uint32 CRC32); - virtual const char* mfGetEntryName() { return m_EntryFunc.c_str(); } - virtual bool mfFlushCacheFile(); - virtual bool Export(SShaderSerializeContext& SC); - virtual bool mfPrecache(SShaderCombination& cmb, bool bForce, bool bFallback, bool bCompressedOnly, CShader* pSH, CShaderResources* pRes); - - // Vertex shader specific functions - virtual AZ::Vertex::Format mfVertexFormat(bool& bUseTangents, bool& bUseLM, bool& bUseHWSkin, bool& bUseVertexVelocity); - static AZ::Vertex::Format mfVertexFormat(SHWSInstance* pInst, CHWShader_D3D* pSH, LPD3D10BLOB pBuffer); - virtual void mfUpdatePreprocessFlags(SShaderTechnique* pTech); - - virtual const char* mfGetActivatedCombinations(bool bForLevel); - - static void mfSetGlobalParams(); - static void mfSetCameraParams(); - static void UpdatePerViewConstantBuffer(); - static bool mfAddGlobalTexture(SCGTexture& Texture); - static bool mfAddGlobalSampler(STexSamplerRT& Sampler); - - static void* GetVSDataForDecl(const D3D11_INPUT_ELEMENT_DESC* pDecl, int nCount, int& nDataSize); - - static void ShutDown(); - - static Vec4 GetVolumetricFogParams(); - static Vec4 GetVolumetricFogRampParams(); - static void GetFogColorGradientConstants(Vec4& fogColGradColBase, Vec4& fogColGradColDelta); - static Vec4 GetFogColorGradientRadial(); - - // Import/Export - bool ExportSamplers(SCHWShader& SHW, SShaderSerializeContext& SC); - bool ExportParams(SCHWShader& SHW, SShaderSerializeContext& SC); - - static CHWShader_D3D::SHWSInstance* s_pCurInstGS; - static CHWShader_D3D::SHWSInstance* s_pCurInstDS; - static CHWShader_D3D::SHWSInstance* s_pCurInstHS; - static CHWShader_D3D::SHWSInstance* s_pCurInstCS; - static CHWShader_D3D::SHWSInstance* s_pCurInstVS; - static CHWShader_D3D::SHWSInstance* s_pCurInstPS; - - static bool s_bFirstGS; - static bool s_bFirstDS; - static bool s_bFirstHS; - static bool s_bFirstCS; - static bool s_bFirstVS; - static bool s_bFirstPS; - - static int s_nActivationFailMask; - - static bool s_bInitShaders; - - static int s_nResetDeviceFrame; - static int s_nInstFrame; - - static int s_nDevicePSDataSize; - static int s_nDeviceVSDataSize; - - static SCGTextures s_PF_Textures; // Per frame textures (shared between all) - static SCGSamplers s_PF_Samplers; // Per-frame samplers (shared between all) - - friend struct SShaderTechniqueStat; -}; - -struct SShaderTechniqueStat -{ - SShaderTechnique* pTech; - CShader* pShader; - CHWShader_D3D* pVS; - CHWShader_D3D* pPS; - CHWShader_D3D::SHWSInstance* pVSInst; - CHWShader_D3D::SHWSInstance* pPSInst; -}; - -extern AZStd::vector g_SelectedTechs; diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShaderCompiling.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShaderCompiling.cpp deleted file mode 100644 index 89ee65bc91..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DHWShaderCompiling.cpp +++ /dev/null @@ -1,5407 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "CryCrc32.h" -#include "UnalignedBlit.h" -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DHWSHADERCOMPILING_CPP_SECTION_1 1 -#define D3DHWSHADERCOMPILING_CPP_SECTION_2 2 -#define D3DHWSHADERCOMPILING_CPP_SECTION_3 3 -#define D3DHWSHADERCOMPILING_CPP_SECTION_4 4 -#define D3DHWSHADERCOMPILING_CPP_SECTION_5 5 -#define D3DHWSHADERCOMPILING_CPP_SECTION_6 6 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif !defined(OPENGL) - #include - #include -#endif - -#ifdef CRY_USE_METAL -#import -#endif -#include "../Common/Shaders/RemoteCompiler.h" -#include "../Common/RenderCapabilities.h" - -#include - -static CryCriticalSection g_cAILock; -static SShaderAsyncInfo g_PendingList; -static SShaderAsyncInfo g_PendingListT; -#ifdef SHADER_ASYNC_COMPILATION -static SShaderAsyncInfo g_BuildList; -#endif - -SShaderAsyncInfo& SShaderAsyncInfo::PendingList() { return g_PendingList; } -SShaderAsyncInfo& SShaderAsyncInfo::PendingListT() { return g_PendingListT; } -#ifdef SHADER_ASYNC_COMPILATION -SShaderAsyncInfo& CAsyncShaderTask::BuildList() { return g_BuildList; } -#endif - -CryEvent SShaderAsyncInfo::s_RequestEv; - -int CHWShader_D3D::s_nDevicePSDataSize; -int CHWShader_D3D::s_nDeviceVSDataSize; - -class CSpinLock -{ -public: - CSpinLock() - { -#if defined (WIN32) || defined(LINUX) || defined(APPLE) || defined(IMPLEMENT_SPIN_LOCK_WITH_INTERLOCKED_COMPARE_EXCHANGE) - while (CryInterlockedCompareExchange(&s_locked, 1L, 0L) == 1L) - { - Sleep(0); - } -#endif - } - - ~CSpinLock() - { -#if defined (WIN32) - InterlockedExchange(&s_locked, 0L); -#elif defined(LINUX) || defined(APPLE) || defined(IMPLEMENT_SPIN_LOCK_WITH_INTERLOCKED_COMPARE_EXCHANGE) - while (CryInterlockedCompareExchange(&s_locked, 0L, 1L) == 0L) - { - ; - } -#endif - } - -private: - static volatile LONG s_locked; -}; - -volatile LONG CSpinLock::s_locked = 0L; - -volatile int SShaderAsyncInfo::s_nPendingAsyncShaders = 0; - -//------------------------------------------------------------------------------ -// This is the single method that is used to map a sampler and its HW slot. -// It is called when parsing a shader / loading from cache. -//------------------------------------------------------------------------------ -bool CHWShader_D3D::mfAddFXSampler(SHWSInstance* pInst, SShaderFXParams& FXParams, SFXSampler* pr, const char* ParamName, SCGBind* pBind, CShader* ef, EHWShaderClass eSHClass) -{ - assert(pBind); - if (!pBind) - { - return false; - } - - std::vector* pParams; - pParams = &pInst->m_Samplers; - uint32 nOffs = pParams->size(); - bool bRes = gRenDev->m_cEF.mfParseFXSampler(FXParams, pr, ParamName, ef, pBind->m_RegisterCount, pParams, eSHClass); - if (pParams->size() > nOffs) - { - for (uint32 i = 0; i < pParams->size() - nOffs; i++) - { - SCGSampler& p = (*pParams)[nOffs + i]; - p.m_RegisterOffset = pBind->m_RegisterOffset + i; - p.m_BindingSlot = pBind->m_BindingSlot; - p.m_Name = pBind->m_Name; - } - } - // Parameter without semantic - return bRes; -} - -//------------------------------------------------------------------------------ -// The main texture binding method. -// This is the single method that is used to map a texture and its HW slot. -// It is called when going over a shader / loading from cache. -//------------------------------------------------------------------------------ -bool CHWShader_D3D::mfAddFXTexture( - SHWSInstance* pInst, SShaderFXParams& FXParams, SFXTexture* pr, const char* ParamName, - SCGBind* pBind, CShader* ef, EHWShaderClass eSHClass) -{ - assert(pBind); - if (!pBind) - { - return false; - } - - std::vector* pParams; - pParams = &pInst->m_Textures; - uint32 nOffs = pParams->size(); - bool bRes = gRenDev->m_cEF.mfParseFXTexture(FXParams, pr, ParamName, ef, pBind->m_RegisterCount, pParams, eSHClass); - - if (pParams->size() > nOffs) - { // If the texture was added - for (uint32 i = 0; i < pParams->size() - nOffs; i++) - { - SCGTexture& p = (*pParams)[nOffs + i]; - p.m_RegisterOffset = pBind->m_RegisterOffset + i; // Offset by one and set it for this texture - p.m_BindingSlot = pBind->m_BindingSlot; // Set the passed binding slot - p.m_Name = pBind->m_Name; - } - } - // Parameter without semantic - return bRes; -} - -//------------------------------------------------------------------------------ -// This is the single method that is used to map constant parameter and its HW slot. -// It is called when parsing a shader / loading from cache. -//------------------------------------------------------------------------------ -void CHWShader_D3D::mfAddFXParameter( - [[maybe_unused]] SHWSInstance* pInst, SParamsGroup& OutParams, SShaderFXParams& FXParams, - SFXParam* pr, const char* ParamName, SCGBind* pBind, CShader* ef, bool bInstParam, EHWShaderClass eSHClass) -{ - SCGParam CGpr; - - assert(pBind); - if (!pBind) - { - return; - } - - int nComps = 0; - int nParams = pBind->m_RegisterCount; - if (!pr->m_Semantic.empty()) - { - nComps = pr->m_ComponentCount; - } - else - { - for (int i = 0; i < pr->m_ComponentCount; i++) - { - CryFixedStringT<128> cur; - pr->GetParamComp(i, cur); - if (cur.empty()) - { - break; - } - nComps++; - } - } - // Process parameters only with semantics - if (nComps && nParams) - { - std::vector* pParams; - if (bInstParam) - { - pParams = &OutParams.Params_Inst; - } - else - { - pParams = &OutParams.Params[0]; - } - uint32 nOffs = pParams->size(); - [[maybe_unused]] bool bRes = gRenDev->m_cEF.mfParseFXParameter(FXParams, pr, ParamName, ef, bInstParam, pBind->m_RegisterCount, pParams, eSHClass, false); - AZ_Assert(bRes, "Error: CHWShader_D3D::mfAddFXParameter - bRes is false"); - - if (pParams->size() > nOffs) - { - for (uint32 i = 0; i < pParams->size() - nOffs; i++) - { - //assert(pBind->m_nComponents == 1); - SCGParam& p = (*pParams)[nOffs + i]; - p.m_RegisterOffset = pBind->m_RegisterOffset + i; - p.m_BindingSlot = pBind->m_BindingSlot; - } - } - } - // Parameter without semantic -} - -struct SAliasSampler -{ - STexSamplerRT Sampler; - string NameTex; -}; - -bool CHWShader_D3D::mfAddFXParameter(SHWSInstance* pInst, SParamsGroup& OutParams, SShaderFXParams& FXParams, const char* param, SCGBind* bn, bool bInstParam, EHWShaderClass eSHClass, CShader* pFXShader) -{ - if (bn->m_RegisterOffset & SHADER_BIND_TEXTURE) - { - SFXTexture* pr = gRenDev->m_cEF.mfGetFXTexture(FXParams.m_FXTextures, param); - if (pr) - { - if (bn->m_RegisterCount < 0) - { - bn->m_RegisterCount = pr->m_nArray; - } - return true; - } - } - else - if (bn->m_RegisterOffset & SHADER_BIND_SAMPLER) - { - SFXSampler* pr = gRenDev->m_cEF.mfGetFXSampler(FXParams.m_FXSamplers, param); - if (pr) - { - if (bn->m_RegisterCount < 0) - { - bn->m_RegisterCount = pr->m_nArray; - } - return true; - } - } - else - { - SFXParam* pr = gRenDev->m_cEF.mfGetFXParameter(FXParams.m_FXParams, param); - if (pr) - { - if (bn->m_RegisterCount < 0) - { - bn->m_RegisterCount = pr->m_RegisterCount; - } - mfAddFXParameter(pInst, OutParams, FXParams, pr, param, bn, pFXShader, bInstParam, eSHClass); - return true; - } - } - return false; -} - -//================================================================================================================== - -int CGBindCallback(const VOID* arg1, const VOID* arg2) -{ - SCGBind* pi1 = (SCGBind*)arg1; - SCGBind* pi2 = (SCGBind*)arg2; - - if (pi1->m_RegisterOffset < pi2->m_RegisterOffset) - { - return -1; - } - if (pi1->m_RegisterOffset > pi2->m_RegisterOffset) - { - return 1; - } - - return 0; -} - -const char* ReflectedConstantBufferNames[eConstantBufferShaderSlot_ReflectedCount] = {"PER_BATCH", "PER_INSTANCE", "PER_MATERIAL"}; - -void CHWShader_D3D::mfCreateBinds(SHWSInstance* pInst, void* pConstantTable, [[maybe_unused]] byte* pShader, [[maybe_unused]] int nSize) -{ - uint32 i; - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*)pConstantTable; - D3D11_SHADER_DESC Desc; - pShaderReflection->GetDesc(&Desc); - ID3D11ShaderReflectionConstantBuffer* pCB = NULL; - for (uint32 n = 0; n < Desc.ConstantBuffers; n++) - { - pCB = pShaderReflection->GetConstantBufferByIndex(n); - D3D11_SHADER_BUFFER_DESC SBDesc; - pCB->GetDesc(&SBDesc); - if (SBDesc.Type == D3D11_CT_RESOURCE_BIND_INFO) - { - continue; - } - int nCB; - if (!strcmp("$Globals", SBDesc.Name)) - { - nCB = eConstantBufferShaderSlot_PerBatch; - } - else - { - for (nCB = 0; nCB < eConstantBufferShaderSlot_ReflectedCount; nCB++) - { - if (!strcmp(ReflectedConstantBufferNames[nCB], SBDesc.Name)) - { - break; - } - } - } - if (nCB >= eConstantBufferShaderSlot_ReflectedCount) // Allow having custom cbuffers in shaders - { - continue; - } - for (i = 0; i < SBDesc.Variables; i++) - { - ID3D11ShaderReflectionVariable* pCV = pCB->GetVariableByIndex(i); - ID3D11ShaderReflectionType* pVT = pCV->GetType(); - D3D11_SHADER_VARIABLE_DESC CDesc; - D3D11_SHADER_TYPE_DESC CTDesc; - pVT->GetDesc(&CTDesc); - pCV->GetDesc(&CDesc); - if (!(CDesc.uFlags & D3D10_SVF_USED)) - { - continue; - } - if (CTDesc.Class == D3D10_SVC_VECTOR || CTDesc.Class == D3D10_SVC_SCALAR || CTDesc.Class == D3D10_SVC_MATRIX_COLUMNS || CTDesc.Class == D3D10_SVC_MATRIX_ROWS) - { - SCGBind cgp; - assert(!(CDesc.StartOffset & 0xf)); - //assert(!(CDesc.Size & 0xf)); - int nReg = CDesc.StartOffset >> 4; - cgp.m_RegisterOffset = nReg; //<<2; - cgp.m_BindingSlot = nCB; - cgp.m_RegisterCount = (CDesc.Size + 15) >> 4; - cgp.m_Name = CDesc.Name; - cgp.m_Flags = CParserBin::GetCRC32(CDesc.Name); - pInst->m_pBindVars.push_back(cgp); - } - else - { - assert(false); - } - } - } - - D3D11_SHADER_INPUT_BIND_DESC IBDesc; - for (i = 0; i < Desc.BoundResources; i++) - { - ZeroStruct(IBDesc); - pShaderReflection->GetResourceBindingDesc(i, &IBDesc); - SCGBind cgp; - if (IBDesc.Type == D3D10_SIT_TEXTURE) - { - cgp.m_RegisterOffset = IBDesc.BindPoint | SHADER_BIND_TEXTURE; - } - else - if (IBDesc.Type == D3D10_SIT_SAMPLER) - { - cgp.m_RegisterOffset = IBDesc.BindPoint | SHADER_BIND_SAMPLER; - } - else - { - continue; - } - - if (IBDesc.Dimension == D3D10_SRV_DIMENSION_BUFFER) - { - continue; - } - - cgp.m_BindingSlot = IBDesc.BindPoint; - cgp.m_RegisterCount = IBDesc.BindCount; - cgp.m_Name = IBDesc.Name; - cgp.m_Flags = CParserBin::GetCRC32(IBDesc.Name); - pInst->m_pBindVars.push_back(cgp); - } -} - -void CHWShader_D3D::mfGatherFXParameters(SHWSInstance* pInst, std::vector* InstBindVars, CHWShader_D3D* pSH, int nFlags, CShader* pFXShader) -{ - // LOADING_TIME_PROFILE_SECTION(iSystem); - - std::vector& parameters = pInst->m_pBindVars; - - uint32 i, j; - SAliasSampler samps[MAX_TMU]; - int nMaxSampler = -1; - SParamsGroup Group; - SShaderFXParams& FXParams = gRenDev->m_cEF.m_Bin.mfGetFXParams(pInst->m_bFallback ? CShaderMan::s_ShaderFallback : pFXShader); - if (parameters.size()) - { - std::list skipped; - - for (i = 0; i < parameters.size(); i++) - { - SCGBind* bn = ¶meters[i]; - const char* param = bn->m_Name.c_str(); - if (!strncmp(param, "_g_", 3)) - { - continue; - } - bool bRes = mfAddFXParameter(pInst, Group, FXParams, param, bn, false, pSH->m_eSHClass, pFXShader); - if (!bRes && (bn->m_RegisterOffset & SHADER_BIND_TEXTURE)) // try to find old samplers (Without semantics) - { - skipped.push_back(i); - } - } - - bool setSamplers[256] = { false }; - bool setTextures[256] = { false }; - - for (i = 0; i < pInst->m_Samplers.size(); i++) - { - setSamplers[pInst->m_Samplers[i].m_RegisterOffset & 0xff] = true; - } - for (i = 0; i < pInst->m_Textures.size(); i++) - { - setTextures[pInst->m_Textures[i].m_RegisterOffset & 0xff] = true; - } - - while (skipped.size() > 0) - { - i = skipped.front(); - skipped.pop_front(); - - SCGBind *bn = ¶meters[i]; - const char *param = bn->m_Name.c_str(); - - { - for (j = 0; j < (uint32)FXParams.m_FXSamplersOld.size(); j++) - { - STexSamplerFX* sm = &FXParams.m_FXSamplersOld[j]; - if (!azstricmp(sm->m_szName.c_str(), param)) - { - int nSampler = bn->m_RegisterOffset & 0x7f; - if (nSampler < MAX_TMU) - { - nMaxSampler = max(nSampler, nMaxSampler); - samps[nSampler].Sampler = STexSamplerRT(*sm); - samps[nSampler].NameTex = sm->m_szTexture; - samps[nSampler].Sampler.m_nSamplerSlot = (int8)(bn->m_BindingSlot & 0xff); - samps[nSampler].Sampler.m_nTextureSlot = nSampler; - - for (int k = 0; k < parameters.size(); k++) - { - if (parameters[k].m_RegisterOffset & SHADER_BIND_TEXTURE) - { - if (!azstricmp(parameters[k].m_Name.c_str(), param)) - { - samps[nSampler].Sampler.m_nTextureSlot = (int8)parameters[k].m_BindingSlot; - } - } - } - - for (int k = 0; k < parameters.size(); k++) - { - if (parameters[k].m_RegisterOffset & SHADER_BIND_SAMPLER) - { - if (!azstricmp(parameters[k].m_Name.c_str(), param)) - { - samps[nSampler].Sampler.m_nSamplerSlot = (int8)parameters[k].m_BindingSlot; - } - } - } - - - // Texture slot occupied, search an alternative - if (setSamplers[samps[nSampler].Sampler.m_nSamplerSlot]) - { - uint32 f = 0; while (setSamplers[f]) ++f; - samps[nSampler].Sampler.m_nSamplerSlot = f; - assert(f < 16); - } - - // Sampler slot occupied, search an alternative - if (setTextures[samps[nSampler].Sampler.m_nTextureSlot]) - { - uint32 f = 0; while (setTextures[f]) ++f; - samps[nSampler].Sampler.m_nTextureSlot = f; - assert(f < 256); - } - - setTextures[samps[nSampler].Sampler.m_nTextureSlot] = true; - setSamplers[samps[nSampler].Sampler.m_nSamplerSlot] = true; - - break; - } - } - } - if (j == FXParams.m_FXSamplersOld.size()) - { - for (j = 0; j < (uint32)FXParams.m_FXSamplersOld.size(); j++) - { - STexSamplerFX* sm = &FXParams.m_FXSamplersOld[j]; - const char* src = sm->m_szName.c_str(); - char name[128]; - int n = 0; - while (src[n]) - { - if (src[n] <= 0x20 || src[n] == '[') - { - break; - } - name[n] = src[n]; - n++; - } - name[n] = 0; - if (!azstricmp(name, param)) - { - int nSampler = bn->m_RegisterOffset & 0x7f; - if (nSampler < MAX_TMU) - { - samps[nSampler].Sampler = STexSamplerRT(*sm); - samps[nSampler].NameTex = sm->m_szTexture; - samps[nSampler].Sampler.m_nSamplerSlot = (int8)(bn->m_BindingSlot & 0xff); - samps[nSampler].Sampler.m_nTextureSlot = nSampler; - - for (int k = 0; k < parameters.size(); k++) - { - if (parameters[k].m_RegisterOffset & SHADER_BIND_TEXTURE) - { - if (!azstricmp(parameters[k].m_Name.c_str(), param)) - { - samps[nSampler].Sampler.m_nTextureSlot = (int8)parameters[k].m_BindingSlot; - } - } - } - - for (int k = 0; k < parameters.size(); k++) - { - if (parameters[k].m_RegisterOffset & SHADER_BIND_SAMPLER) - { - if (!azstricmp(parameters[k].m_Name.c_str(), param)) - { - samps[nSampler].Sampler.m_nSamplerSlot = (int8)parameters[k].m_BindingSlot; - } - } - } - - // Texture slot occupied, search an alternative - if (setSamplers[samps[nSampler].Sampler.m_nSamplerSlot]) - { - uint32 f = 0; while (setSamplers[f]) ++f; - samps[nSampler].Sampler.m_nSamplerSlot = f; - assert(f < 16); - } - - // Sampler slot occupied, search an alternative - if (setTextures[samps[nSampler].Sampler.m_nTextureSlot]) - { - uint32 f = 0; while (setTextures[f]) ++f; - samps[nSampler].Sampler.m_nTextureSlot = f; - assert(f < 256); - } - - setTextures[samps[nSampler].Sampler.m_nTextureSlot] = true; - setSamplers[samps[nSampler].Sampler.m_nSamplerSlot] = true; - - for (int nS = 0; nS < bn->m_RegisterCount; nS++) - { - nMaxSampler = max(nSampler + nS, nMaxSampler); - samps[nSampler + nS].Sampler = samps[nSampler].Sampler; - samps[nSampler + nS].NameTex = sm->m_szTexture; - } - break; - } - } - } - } - } - } - } - if (nFlags != 1) - { - for (i = 0; (int)i <= nMaxSampler; i++) - { - STexSamplerRT& smp = samps[i].Sampler; - smp.m_pTex = gRenDev->m_cEF.mfParseFXTechnique_LoadShaderTexture(&smp, samps[i].NameTex.c_str(), NULL, NULL, i, eCO_NOSET, eCO_NOSET, DEF_TEXARG0, DEF_TEXARG0); - if (!smp.m_pTex) - { - continue; - } - if (smp.m_bGlobal) - { - mfAddGlobalSampler(smp); - } - else - { - pInst->m_pSamplers.push_back(smp); - } - } - } - else - { - assert(pInst->m_pAsync); - if (pInst->m_pAsync && nMaxSampler >= 0) - { - pInst->m_pAsync->m_bPendedSamplers = true; - } - } - - pInst->m_nMaxVecs[0] = pInst->m_nMaxVecs[1] = 0; - if (parameters.size()) - { - for (i = 0; i < parameters.size(); i++) - { - SCGBind* pB = ¶meters[i]; - if (pB->m_RegisterOffset & (SHADER_BIND_SAMPLER | SHADER_BIND_TEXTURE)) - { - continue; - } - if (pB->m_BindingSlot < 0 || pB->m_BindingSlot > 2) - { - continue; - } - for (j = 0; j < Group.Params[0].size(); j++) - { - SCGParam* pr = &Group.Params[0][j]; - if (pr->m_RegisterOffset == pB->m_RegisterOffset && pr->m_Name == pB->m_Name) - { - break; - } - } - if (j != Group.Params[0].size()) - { - continue; - } - if (pB->m_BindingSlot < 3) - { - pInst->m_nMaxVecs[pB->m_BindingSlot] = max(pB->m_RegisterOffset + pB->m_RegisterCount, pInst->m_nMaxVecs[pB->m_BindingSlot]); - } - } - } - if (Group.Params[0].size()) - { - for (i = 0; i < Group.Params[0].size(); i++) - { - SCGParam* pr = &Group.Params[0][i]; - - if (pr->m_Flags & PF_MATERIAL) - { - pInst->m_bHasPMParams = true; - } - } - - gRenDev->m_cEF.mfCheckObjectDependParams(Group.Params[0], Group.Params[1], pSH->m_eSHClass, pFXShader); - } - - for (i = 0; i < 2; i++) - { - if (Group.Params[i].size()) - { - for (j = 0; j < Group.Params[i].size(); j++) - { - const SCGParam* pr = &Group.Params[i][j]; - pInst->m_nMaxVecs[i] = max(pr->m_RegisterOffset + pr->m_RegisterCount, pInst->m_nMaxVecs[i]); - } - } - } -#if !defined(NDEBUG) - int nMax = AzRHI::GetConstantRegisterCountMax(pSH->m_eSHClass); - assert(pInst->m_nMaxVecs[0] < nMax); - assert(pInst->m_nMaxVecs[1] < nMax); -#endif - - if ((pInst->m_Ident.m_RTMask & g_HWSR_MaskBit[HWSR_INSTANCING_ATTR]) && pSH->m_eSHClass == eHWSC_Vertex) - { - int nNumInst = 0; - if (InstBindVars) - { - for (i = 0; i < (uint32)InstBindVars->size(); i++) - { - SCGBind& b = (*InstBindVars)[i]; - int nID = b.m_RegisterOffset; - if (!nNumInst) - { - pInst->m_nInstMatrixID = nID; - } - - SCGBind bn; - bn.m_RegisterCount = b.m_RegisterCount; - bn.m_RegisterOffset = nID; - - nNumInst++; - } - } - //assert(cgi->m_nNumInstAttributes == nNumInst); - pInst->m_nNumInstAttributes = nNumInst; - - if (Group.Params_Inst.size()) - { - qsort(&Group.Params_Inst[0], Group.Params_Inst.size(), sizeof(SCGParam), CGBindCallback); - pInst->m_nParams_Inst = CGParamManager::GetParametersGroup(Group, 2); - } - } - if (Group.Params[0].size() > 0) - { - qsort(&Group.Params[0][0], Group.Params[0].size(), sizeof(SCGParam), CGBindCallback); - pInst->m_nParams[0] = CGParamManager::GetParametersGroup(Group, 0); - } - if (Group.Params[1].size() > 0) - { - qsort(&Group.Params[1][0], Group.Params[1].size(), sizeof(SCGParam), CGBindCallback); - pInst->m_nParams[1] = CGParamManager::GetParametersGroup(Group, 1); - } -} - -// Vertex shader specific -void CHWShader_D3D::mfUpdateFXVertexFormat([[maybe_unused]] SHWSInstance* pInst, CShader* pSH) -{ - // Update global FX shader's vertex format / flags - if (pSH) - { - AZ::Vertex::Format vertexFormat = pSH->m_vertexFormat; - bool bCurrent = false; - for (uint32 i = 0; i < pSH->m_HWTechniques.Num(); i++) - { - SShaderTechnique* hw = pSH->m_HWTechniques[i]; - for (uint32 j = 0; j < hw->m_Passes.Num(); j++) - { - SShaderPass* pass = &hw->m_Passes[j]; - if (pass->m_VShader) - { - if (pass->m_VShader == this) - { - bCurrent = true; - } - bool bUseLM = false; - bool bUseTangs = false; - bool bUseHWSkin = false; - bool bUseVertexVelocity = false; - AZ::Vertex::Format currentVertexFormat = pass->m_VShader->mfVertexFormat(bUseTangs, bUseLM, bUseHWSkin, bUseVertexVelocity); - if (currentVertexFormat > vertexFormat) - { - vertexFormat = currentVertexFormat; - } - if (bUseTangs) - { - pass->m_PassFlags |= VSM_TANGENTS; - } - if (bUseHWSkin) - { - pass->m_PassFlags |= VSM_HWSKIN; - } - if (bUseVertexVelocity) - { - pass->m_PassFlags |= VSM_VERTEX_VELOCITY; - } - } - } - } - //assert (bCurrent); - pSH->m_vertexFormat = vertexFormat; - } -} - -void CHWShader_D3D::mfPostVertexFormat(SHWSInstance* pInst, [[maybe_unused]] CHWShader_D3D* pHWSH, bool bCol, byte bNormal, bool bTC0, bool bTC1, bool bPSize, bool bTangent[2], bool bBitangent[2], bool bHWSkin, [[maybe_unused]] bool bSH[2], bool bVelocity, bool bMorph) -{ - if (bBitangent[0]) - { - pInst->m_VStreamMask_Decl |= 1 << VSF_TANGENTS; - } - else - if (bTangent[0]) - { - pInst->m_VStreamMask_Decl |= 1 << VSF_QTANGENTS; - } - if (bBitangent[1]) - { - pInst->m_VStreamMask_Stream |= 1 << VSF_TANGENTS; - } - else - if (bTangent[1]) - { - pInst->m_VStreamMask_Stream |= 1 << VSF_QTANGENTS; - } - if (pInst->m_VStreamMask_Decl & (1 << VSF_TANGENTS)) - { - bNormal = false; - } - - if (bHWSkin) - { - pInst->m_VStreamMask_Decl |= VSM_HWSKIN; - pInst->m_VStreamMask_Stream |= VSM_HWSKIN; - } - - if (bVelocity) - { - pInst->m_VStreamMask_Decl |= VSM_VERTEX_VELOCITY; - pInst->m_VStreamMask_Stream |= VSM_VERTEX_VELOCITY; - } - if (bMorph) - { - pInst->m_VStreamMask_Decl |= VSM_MORPHBUDDY; - pInst->m_VStreamMask_Stream |= VSM_MORPHBUDDY; - } - - pInst->m_vertexFormat = AZ::Vertex::VertFormatForComponents(bCol, bTC0, bTC1, bPSize, bNormal != 0); -} - -AZ::Vertex::Format CHWShader_D3D::mfVertexFormat(bool& bUseTangents, bool& bUseLM, bool& bUseHWSkin, bool& bUseVertexVelocity) -{ - uint32 i; - - assert (m_eSHClass == eHWSC_Vertex); - - AZ::Vertex::Format vertexFormat(eVF_Unknown); - int nStream = 0; - for (i = 0; i < m_Insts.size(); i++) - { - SHWSInstance* pInst = m_Insts[i]; - if (pInst->m_vertexFormat > vertexFormat) - { - vertexFormat = pInst->m_vertexFormat; - } - nStream |= pInst->m_VStreamMask_Stream; - } - bUseTangents = (nStream & VSM_TANGENTS) != 0; - bUseLM = false; - bUseHWSkin = (nStream & VSM_HWSKIN) != 0; - bUseVertexVelocity = (nStream & VSM_VERTEX_VELOCITY) != 0; - return vertexFormat; -} - -AZ::Vertex::Format CHWShader_D3D::mfVertexFormat(SHWSInstance* pInst, CHWShader_D3D* pSH, LPD3D10BLOB pShader) -{ - assert (pSH->m_eSHClass == eHWSC_Vertex); - - byte bNormal = false; - bool bTangent[2] = {false, false}; - bool bBitangent[2] = {false, false}; - bool bHWSkin = false; - bool bVelocity = false; - bool bMorph = false; - bool bPSize = false; - bool bSH[2] = {false, false}; - bool bTC0 = false; - bool bTC1[2] = {false, false}; - bool bCol = false; - bool bSecCol = false; - bool bPos = false; - - size_t nSize = pShader->GetBufferSize(); - void* pData = pShader->GetBufferPointer(); - void* pShaderReflBuf; - HRESULT hr = D3DReflect(pData, nSize, IID_ID3D11ShaderReflection, &pShaderReflBuf); - assert (SUCCEEDED(hr)); - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*)pShaderReflBuf; - if (!SUCCEEDED(hr)) - { - return AZ::Vertex::Format(eVF_Unknown); - } - D3D11_SHADER_DESC Desc; - pShaderReflection->GetDesc(&Desc); - if (!Desc.InputParameters) - { - return AZ::Vertex::Format(eVF_Unknown); - } - D3D11_SIGNATURE_PARAMETER_DESC IDesc; - for (uint32 i = 0; i < Desc.InputParameters; i++) - { - pShaderReflection->GetInputParameterDesc(i, &IDesc); - //if (!IDesc.ReadWriteMask) - // continue; - if (!IDesc.SemanticName) - { - continue; - } - int nIndex; - if (!_strnicmp(IDesc.SemanticName, "POSITION", 8) -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - || !_strnicmp(IDesc.SemanticName, "SV_POSITION", 11) -#endif - ) - { - nIndex = IDesc.SemanticIndex; - if (nIndex == 0) - { - bPos = true; - } - else - if (nIndex == 3) - { - bVelocity = true; - } - else - if (nIndex == 4) - { - bHWSkin = true; - } - else - if (nIndex == 8) - { - bMorph = true; - } - else - { - assert(false); - } - } - else - if (!_strnicmp(IDesc.SemanticName, "NORMAL", 6)) - { - bNormal = true; - } - else - if (!_strnicmp(IDesc.SemanticName, "TEXCOORD", 8)) - { - nIndex = IDesc.SemanticIndex; - if (nIndex == 0) - { - bTC0 = true; - } - else - if (!(pInst->m_Ident.m_RTMask & g_HWSR_MaskBit[HWSR_INSTANCING_ATTR])) - { - if (nIndex == 1) - { - bTC1[0] = true; - if (IDesc.ReadWriteMask) - { - bTC1[1] = true; - } - } - else - if (nIndex == 8) - { - bMorph = true; - } - } - } - else - if (!_strnicmp(IDesc.SemanticName, "COLOR", 5)) - { - nIndex = IDesc.SemanticIndex; - if (nIndex == 0) - { - bCol = true; - } - else - if (nIndex == 1) - { - bSecCol = true; - } - else - { - if (nIndex == 2 || nIndex == 3) - { - bSH[0] = true; - if (IDesc.ReadWriteMask) - { - bSH[1] = true; - } - } - else - { - assert(false); - } - } - } - else - if (!azstricmp(IDesc.SemanticName, "TANGENT")) - { - bTangent[0] = true; - if (IDesc.ReadWriteMask) - { - bTangent[1] = true; - } - } - else - if (!azstricmp(IDesc.SemanticName, "BITANGENT") || !azstricmp(IDesc.SemanticName, "BINORMAL")) - { - bBitangent[0] = true; - if (IDesc.ReadWriteMask) - { - bBitangent[1] = true; - } - } - else - if (!_strnicmp(IDesc.SemanticName, "PSIZE", 5)) - { - bPSize = true; - } - else - if (!_strnicmp(IDesc.SemanticName, "BLENDWEIGHT", 11) || !_strnicmp(IDesc.SemanticName, "BLENDINDICES", 12)) - { - nIndex = IDesc.SemanticIndex; - if (nIndex == 0) - { - bHWSkin = true; - } - else - if (nIndex == 1) - { - bMorph = true; - } - else - { - assert(0); - } - } - else -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - if (!_strnicmp(IDesc.SemanticName, "SV_", 3)) -#endif - { - // SV_ are valid semantics - } - else - { - assert(0); - } - } - mfPostVertexFormat(pInst, pSH, bCol, bNormal, bTC0, bTC1[0], bPSize, bTangent, bBitangent, bHWSkin, bSH, bVelocity, bMorph); - SAFE_RELEASE(pShaderReflection); - - return pInst->m_vertexFormat; -} - -void CHWShader_D3D::mfSetDefaultRT(uint64& nAndMask, uint64& nOrMask) -{ - uint32 i, j; - SShaderGen* pGen = gRenDev->m_cEF.m_pGlobalExt; - - uint32 nBitsPlatform = 0; - if (CParserBin::m_nPlatform == SF_ORBIS) - { - nBitsPlatform |= SHGD_HW_ORBIS; - } - else - if (CParserBin::m_nPlatform == SF_D3D11) - { - nBitsPlatform |= SHGD_HW_DX11; - } - else - if (CParserBin::m_nPlatform == SF_GL4) - { - nBitsPlatform |= SHGD_HW_GL4; - } - else - if (CParserBin::m_nPlatform == SF_GLES3) - { - nBitsPlatform |= SHGD_HW_GLES3; - } - // Confetti Nicholas Baldwin: adding metal shader language support - else - if (CParserBin::m_nPlatform == SF_METAL) - { - nBitsPlatform |= SHGD_HW_METAL; - } - - // Make a mask of flags affected by this type of shader - uint32 nType = m_dwShaderType; - if (nType) - { - for (i = 0; i < pGen->m_BitMask.size(); i++) - { - SShaderGenBit* pBit = pGen->m_BitMask[i]; - if (!pBit->m_Mask) - { - continue; - } - if (nBitsPlatform & pBit->m_nDependencyReset) - { - nAndMask &= ~pBit->m_Mask; - continue; - } - for (j = 0; j < pBit->m_PrecacheNames.size(); j++) - { - if (pBit->m_PrecacheNames[j] == nType) - { - if (nBitsPlatform & pBit->m_nDependencySet) - { - nOrMask |= pBit->m_Mask; - } - break; - } - } - } - } -} - -//================================================================================================================== - -void CHWShader::mfValidateTokenData([[maybe_unused]] CResFile* pRes) -{ -#ifdef _DEBUG - if (pRes == 0) - { - return; - } - - bool bTokenValid = true; - ResDir* Dir = pRes->mfGetDirectory(); - for (unsigned int i = 0; i < Dir->size(); i++) - { - SDirEntry* pDE = &(*Dir)[i]; - if (pDE->flags & RF_RES_$TOKENS) - { - uint32 nSize = pRes->mfFileRead(pDE); - byte* pData = (byte*)pRes->mfFileGetBuf(pDE); - if (!pData) - { - bTokenValid = false; - break; - } - - uint32 nL = *(uint32*)pData; - if (CParserBin::m_bEndians) - { - SwapEndian(nL, eBigEndian); - } - - if (nL * sizeof(uint32) > nSize) - { - bTokenValid = false; - break; - } - - int nTableSize = nSize - (4 + nL * sizeof(uint32)); - if (nTableSize < 0) - { - bTokenValid = false; - break; - } - - pRes->mfCloseEntry(pDE); - } - } - - if (!bTokenValid) - { - CryFatalError("Invalid token data in shader cache file"); - } -#endif -} - -bool CHWShader_D3D::mfStoreCacheTokenMap(FXShaderToken*& Table, TArray*& pSHData, const char* szName) -{ - TArray Data; - - FXShaderTokenItor itor; - uint32 nSize = pSHData->size(); - if (CParserBin::m_bEndians) - { - uint32 nSizeEnd = nSize; - SwapEndian(nSizeEnd, eBigEndian); - Data.Copy((byte*)&nSizeEnd, sizeof(uint32)); - for (uint32 i = 0; i < nSize; i++) - { - uint32 nToken = (*pSHData)[i]; - SwapEndian(nToken, eBigEndian); - Data.Copy((byte*)&nToken, sizeof(uint32)); - } - } - else - { - Data.Copy((byte*)&nSize, sizeof(uint32)); - Data.Copy((byte*)&(*pSHData)[0], nSize * sizeof(uint32)); - } - for (itor = Table->begin(); itor != Table->end(); itor++) - { - STokenD T = *itor; - if (CParserBin::m_bEndians) - { - SwapEndian(T.Token, eBigEndian); - } - Data.Copy((byte*)&T.Token, sizeof(DWORD)); - Data.Copy((byte*)T.SToken.c_str(), T.SToken.size() + 1); - } - if (!Data.size()) - { - return false; - } - SDirEntry de; - de.Name = szName; - de.flags = RF_RES_$TOKENS; - de.size = Data.size(); - m_pGlobalCache->m_pRes[CACHE_USER]->mfFileAdd(&de); - SDirEntryOpen* pOE = m_pGlobalCache->m_pRes[CACHE_USER]->mfOpenEntry(&de); - pOE->pData = &Data[0]; - m_pGlobalCache->m_pRes[CACHE_USER]->mfFlush(); - m_pGlobalCache->m_pRes[CACHE_USER]->mfCloseEntry(&de); - - return true; -} - -void CHWShader_D3D::mfGetTokenMap(CResFile* pRes, SDirEntry* pDE, FXShaderToken*& Table, TArray*& pSHData) -{ - uint32 i; - int nSize = pRes->mfFileRead(pDE); - byte* pData = (byte*)pRes->mfFileGetBuf(pDE); - if (!pData) - { - Table = NULL; - return; - } - Table = new FXShaderToken; - pSHData = new TArray; - uint32 nL = *(uint32*)pData; - if (CParserBin::m_bEndians) - { - SwapEndian(nL, eBigEndian); - } - pSHData->resize(nL); - if (CParserBin::m_bEndians) - { - uint32* pTokens = (uint32*)&pData[4]; - for (i = 0; i < nL; i++) - { - uint32 nToken = pTokens[i]; - SwapEndian(nToken, eBigEndian); - (*pSHData)[i] = nToken; - } - } - else - { - memcpy(&(*pSHData)[0], &pData[4], nL * sizeof(uint32)); - } - pData += 4 + nL * sizeof(uint32); - nSize -= 4 + nL * sizeof(uint32); - int nOffs = 0; - - while (nOffs < nSize) - { - char* pStr = (char*)&pData[nOffs + sizeof(DWORD)]; - DWORD nToken; - LoadUnaligned(pData + nOffs, nToken); - if (CParserBin::m_bEndians) - { - SwapEndian(nToken, eBigEndian); - } - int nLen = strlen(pStr) + 1; - STokenD TD; - TD.Token = nToken; - TD.SToken = pStr; - Table->push_back(TD); - nOffs += sizeof(DWORD) + nLen; - } -} - -bool CHWShader_D3D::mfGetCacheTokenMap(FXShaderToken*& Table, TArray*& pSHData, uint64 nMaskGenFX) -{ - if (!m_pGlobalCache || !m_pGlobalCache->isValid()) - { - if (m_pGlobalCache) - { - m_pGlobalCache->Release(false); - } - m_pGlobalCache = mfInitCache(NULL, this, true, m_CRC32, true, CRenderer::CV_r_shadersasyncactivation != 0); - } - if (!m_pGlobalCache) - { - assert(false); - return false; - } - - char strName[256]; - sprintf_s(strName, "$MAP_%llx_%llx", nMaskGenFX, m_maskGenStatic); - - if (Table) - { - if (m_pGlobalCache->m_pRes[CACHE_READONLY] && m_pGlobalCache->m_pRes[CACHE_READONLY]->mfFileExist(strName)) - { - return true; - } - if (!m_pGlobalCache->m_pRes[CACHE_USER]) - { - m_pGlobalCache->Release(false); - m_pGlobalCache = mfInitCache(NULL, this, true, m_CRC32, false); - } - if (!m_pGlobalCache || !m_pGlobalCache->m_pRes[CACHE_USER]) - { - assert(false); - return false; - } - if (!m_pGlobalCache->m_pRes[CACHE_USER]->mfFileExist(strName)) - { - if (!CRenderer::CV_r_shadersAllowCompilation) - { - return false; - } - - //CryLogAlways("Storing MAP entry '%s' in shader cache file '%s'", strName, m_pGlobalCache->m_Name.c_str()); - - return mfStoreCacheTokenMap(Table, pSHData, strName); - } - return true; - } - SDirEntry* pDE = NULL; - CResFile* pRes = NULL; - for (int i = 0; i < 2; i++) - { - pRes = m_pGlobalCache->m_pRes[i]; - if (!pRes) - { - continue; - } - pDE = pRes->mfGetEntry(strName); - if (pDE) - { - break; - } - } - if (!pDE || !pRes) - { - Warning("Couldn't find tokens MAP entry '%s' in shader cache file '%s'", strName, m_pGlobalCache->m_Name.c_str()); - ASSERT_IN_SHADER(0); - return false; - } - mfGetTokenMap(pRes, pDE, Table, pSHData); - pRes->mfFileClose(pDE); - - return true; -} - -//============================================================================================================================================================== - -bool CHWShader_D3D::mfGenerateScript(CShader* pSH, SHWSInstance*& pInst, std::vector& InstBindVars, uint32 nFlags, FXShaderToken* Table, TArray* pSHData, TArray& sNewScr) -{ - - bool bTempMap = (Table == NULL); - assert((Table && pSHData) || (!Table && !pSHData)); - assert (m_pGlobalCache); - if (CParserBin::m_bEditable && !Table) // Fast path for offline shaders builder - { - Table = &m_TokenTable; - pSHData = &m_TokenData; - bTempMap = false; - } - else - { - if (m_pGlobalCache) - { - mfGetCacheTokenMap(Table, pSHData, m_nMaskGenShader); - } - if (CParserBin::m_bEditable) - { - if (bTempMap) - { - SAFE_DELETE(Table); - SAFE_DELETE(pSHData); - } - Table = &m_TokenTable; - pSHData = &m_TokenData; - bTempMap = false; - } - } - assert (Table && pSHData); - if (!Table || !pSHData) - { - return false; - } - - ShaderTokensVec NewTokens; - - uint32 eT = eT_unknown; - - switch (pInst->m_eClass) - { - case eHWSC_Vertex: - eT = eT__VS; - break; - case eHWSC_Pixel: - eT = eT__PS; - break; - case eHWSC_Geometry: - eT = eT__GS; - break; - case eHWSC_Hull: - eT = eT__HS; - break; - case eHWSC_Compute: - eT = eT__CS; - break; - case eHWSC_Domain: - eT = eT__DS; - break; - - default: - assert(0); - } - if (eT != eT_unknown) - { - CParserBin::AddDefineToken(eT, NewTokens); - } - - // Include runtime mask definitions in the script - SShaderGen* shg = gRenDev->m_cEF.m_pGlobalExt; - if (shg && pInst->m_Ident.m_RTMask) - { - for (uint32 i = 0; i < shg->m_BitMask.Num(); i++) - { - SShaderGenBit* bit = shg->m_BitMask[i]; - if (!(bit->m_Mask & pInst->m_Ident.m_RTMask)) - { - continue; - } - CParserBin::AddDefineToken(bit->m_dwToken, NewTokens); - } - } - - // Include light mask definitions in the script - if (m_Flags & HWSG_SUPPORTS_MULTILIGHTS) - { - int nLights = pInst->m_Ident.m_LightMask & 0xf; - if (nLights) - { - CParserBin::AddDefineToken(eT__LT_LIGHTS, NewTokens); - } - CParserBin::AddDefineToken(eT__LT_NUM, nLights + eT_0, NewTokens); - bool bHasProj = false; - for (int i = 0; i < 4; i++) - { - int nLightType = (pInst->m_Ident.m_LightMask >> (SLMF_LTYPE_SHIFT + i * SLMF_LTYPE_BITS)) & SLMF_TYPE_MASK; - if (nLightType == SLMF_PROJECTED) - { - bHasProj = true; - } - - CParserBin::AddDefineToken(eT__LT_0_TYPE + i, nLightType + eT_0, NewTokens); - } - if (bHasProj) - { - CParserBin::AddDefineToken(eT__LT_HASPROJ, eT_1, NewTokens); - } - } - else - if (m_Flags & HWSG_SUPPORTS_LIGHTING) - { - CParserBin::AddDefineToken(eT__LT_LIGHTS, NewTokens); - int nLightType = (pInst->m_Ident.m_LightMask >> SLMF_LTYPE_SHIFT) & SLMF_TYPE_MASK; - if (nLightType == SLMF_PROJECTED) - { - CParserBin::AddDefineToken(eT__LT_HASPROJ, eT_1, NewTokens); - } - } - - // Include modificator mask definitions in the script - if ((m_Flags & HWSG_SUPPORTS_MODIF) && pInst->m_Ident.m_MDMask) - { - const uint32 tcProjMask = HWMD_TEXCOORD_PROJ; - const uint32 tcMatrixMask = HWMD_TEXCOORD_MATRIX; - - if (pInst->m_Ident.m_MDMask & tcProjMask) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_PROJ, NewTokens); - } - if (pInst->m_Ident.m_MDMask & tcMatrixMask) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_MATRIX, NewTokens); - } - if (pInst->m_Ident.m_MDMask & HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DIFFUSE, NewTokens); - } - if (pInst->m_Ident.m_MDMask & HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE, NewTokens); - } - if (pInst->m_Ident.m_MDMask & HWMD_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_EMITTANCE_MULT, NewTokens); - } - if (pInst->m_Ident.m_MDMask & HWMD_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_DETAIL, NewTokens); - } - if (pInst->m_Ident.m_MDMask & HWMD_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM) - { - CParserBin::AddDefineToken(eT__TT_TEXCOORD_GEN_OBJECT_LINEAR_CUSTOM, NewTokens); - } - } - - // Include vertex modificator mask definitions in the script - if ((m_Flags & HWSG_SUPPORTS_VMODIF) && pInst->m_Ident.m_MDVMask) - { - int nMDV = pInst->m_Ident.m_MDVMask & 0x0fffffff; - int nType = nMDV & 0xf; - if (nType) - { - CParserBin::AddDefineToken(eT__VT_TYPE, eT_0 + nType, NewTokens); - } - if ((nMDV & MDV_BENDING) || nType == eDT_Bending) - { - CParserBin::AddDefineToken(eT__VT_BEND, eT_1, NewTokens); - if (!(nMDV & 0xf)) - { - nType = eDT_Bending; - CParserBin::AddDefineToken(eT__VT_TYPE, eT_0 + nType, NewTokens); - } - } - if (nMDV & MDV_DEPTH_OFFSET) - { - CParserBin::AddDefineToken(eT__VT_DEPTH_OFFSET, eT_1, NewTokens); - } - if (nMDV & MDV_WIND) - { - CParserBin::AddDefineToken(eT__VT_WIND, eT_1, NewTokens); - } - if (nMDV & MDV_DET_BENDING) - { - CParserBin::AddDefineToken(eT__VT_DET_BEND, eT_1, NewTokens); - } - if (nMDV & MDV_DET_BENDING_GRASS) - { - CParserBin::AddDefineToken(eT__VT_GRASS, eT_1, NewTokens); - } - if (nMDV & ~0xf) - { - CParserBin::AddDefineToken(eT__VT_TYPE_MODIF, eT_1, NewTokens); - } - } - - if (m_Flags & HWSG_FP_EMULATION) - { - //starting at LSB. 8 bits for colorop, 8 bits for alphaop, 3 bits for color arg1, 3 bits for color arg2, 1 bit for srgbwrite, 1 bit unused, 3 bits for - // alpha arg1, 3 bits for alpha arg2, 2 bits unused. - CParserBin::AddDefineToken(eT__FT0_COP, eT_0 + (pInst->m_Ident.m_LightMask & 0xff), NewTokens); - CParserBin::AddDefineToken(eT__FT0_AOP, eT_0 + ((pInst->m_Ident.m_LightMask & 0xff00) >> 8), NewTokens); - - byte CO_0 = ((pInst->m_Ident.m_LightMask & 0xff0000) >> 16) & 7; - CParserBin::AddDefineToken(eT__FT0_CARG1, eT_0 + CO_0, NewTokens); - - byte CO_1 = ((pInst->m_Ident.m_LightMask & 0xff0000) >> 19) & 7; - CParserBin::AddDefineToken(eT__FT0_CARG2, eT_0 + CO_1, NewTokens); - - byte AO_0 = ((pInst->m_Ident.m_LightMask & 0xff000000) >> 24) & 7; - CParserBin::AddDefineToken(eT__FT0_AARG1, eT_0 + AO_0, NewTokens); - - byte AO_1 = ((pInst->m_Ident.m_LightMask & 0xff000000) >> 27) & 7; - CParserBin::AddDefineToken(eT__FT0_AARG2, eT_0 + AO_1, NewTokens); - - if (CO_0 == eCA_Specular || CO_1 == eCA_Specular || AO_0 == eCA_Specular || AO_1 == eCA_Specular) - { - CParserBin::AddDefineToken(eT__FT_SPECULAR, NewTokens); - } - if (CO_0 == eCA_Diffuse || CO_1 == eCA_Diffuse || AO_0 == eCA_Diffuse || AO_1 == eCA_Diffuse) - { - CParserBin::AddDefineToken(eT__FT_DIFFUSE, NewTokens); - } - if (CO_0 == eCA_Texture || CO_1 == eCA_Texture || AO_0 == eCA_Texture || AO_1 == eCA_Texture) - { - CParserBin::AddDefineToken(eT__FT_TEXTURE, NewTokens); - } - if (CO_0 == eCA_Texture1 || (CO_1 == eCA_Texture1) || AO_0 == eCA_Texture1 || AO_1 == eCA_Texture1 - || CO_0 == eCA_Previous || (CO_1 == eCA_Previous) || AO_0 == eCA_Previous || AO_1 == eCA_Previous) - { - CParserBin::AddDefineToken(eT__FT_TEXTURE1, NewTokens); - } - if (CO_0 == eCA_Normal || CO_1 == eCA_Normal || AO_0 == eCA_Normal || AO_1 == eCA_Normal) - { - CParserBin::AddDefineToken(eT__FT_NORMAL, NewTokens); - } - if (CO_0 == eCA_Constant || (CO_1 == eCA_Constant) || AO_0 == eCA_Constant || AO_1 == eCA_Constant - || CO_0 == eCA_Previous || (CO_1 == eCA_Previous) || AO_0 == eCA_Previous || AO_1 == eCA_Previous) - { - CParserBin::AddDefineToken(eT__FT_PSIZE, NewTokens); - } - - byte toSRGB = ((pInst->m_Ident.m_LightMask & 0x400000) >> 22) & 1; - if (toSRGB) - { - CParserBin::AddDefineToken(eT__FT_SRGBWRITE, NewTokens); - } - - if (nFlags & HWSF_STOREDATA) - { - int nStreams = pInst->m_Ident.m_LightMask & 0xff; - if (nStreams & (1 << VSF_QTANGENTS)) - { - CParserBin::AddDefineToken(eT__FT_QTANGENT_STREAM, NewTokens); - } - if (nStreams & (1 << VSF_TANGENTS)) - { - CParserBin::AddDefineToken(eT__FT_TANGENT_STREAM, NewTokens); - } - if (nStreams & VSM_HWSKIN) - { - CParserBin::AddDefineToken(eT__FT_SKIN_STREAM, NewTokens); - } -#if ENABLE_NORMALSTREAM_SUPPORT - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_ORBIS || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_GLES3) - { - if (nStreams & VSM_NORMALS) - { - CParserBin::AddDefineToken(eT__FT_NORMAL, NewTokens); - } - } -#endif - if (nStreams & VSM_VERTEX_VELOCITY) - { - CParserBin::AddDefineToken(eT__FT_VERTEX_VELOCITY_STREAM, NewTokens); - } - } - } - - int nT = NewTokens.size(); - NewTokens.resize(nT + pSHData->size()); - memcpy(&NewTokens[nT], &(*pSHData)[0], pSHData->size() * sizeof(uint32)); - - CParserBin Parser(NULL, pSH); - Parser.Preprocess(1, NewTokens, Table); - CorrectScriptEnums(Parser, pInst, InstBindVars, Table); - RemoveUnaffectedParameters_D3D10(Parser, pInst, InstBindVars); - ConvertBinScriptToASCII(Parser, pInst, InstBindVars, Table, sNewScr); - - if (bTempMap) - { - SAFE_DELETE(Table); - SAFE_DELETE(pSHData); - } - - return sNewScr.Num() && sNewScr[0]; -} - -void CHWShader_D3D::RemoveUnaffectedParameters_D3D10(CParserBin& Parser, [[maybe_unused]] SHWSInstance* pInst, std::vector& InstBindVars) -{ - int nPos = Parser.FindToken(0, Parser.m_Tokens.size() - 1, eT_cbuffer); - while (nPos >= 0) - { - uint32 nName = Parser.m_Tokens[nPos + 1]; - if (nName == eT_PER_BATCH || nName == eT_PER_INSTANCE) - { - int nPosEnd = Parser.FindToken(nPos + 3, Parser.m_Tokens.size() - 1, eT_br_cv_2); - assert(nPosEnd >= 0); - int nPosN = Parser.FindToken(nPos + 1, Parser.m_Tokens.size() - 1, eT_br_cv_1); - assert(nPosN >= 0); - nPosN++; - while (nPosN < nPosEnd) - { - uint32 nT = Parser.m_Tokens[nPosN + 1]; - int nPosCode = Parser.FindToken(nPosEnd + 1, Parser.m_Tokens.size() - 1, nT); - if (nPosCode < 0) - { - assert(nPosN > 0 && nPosN < (int)Parser.m_Tokens.size()); - if (InstBindVars.size()) - { - size_t i = 0; - CCryNameR nm(Parser.GetString(nT)); - for (; i < InstBindVars.size(); i++) - { - SCGBind& b = InstBindVars[i]; - if (b.m_Name == nm) - { - break; - } - } - if (i == InstBindVars.size()) - { - Parser.m_Tokens[nPosN] = eT_comment; - } - } - else - { - Parser.m_Tokens[nPosN] = eT_comment; - } - } - nPosN = Parser.FindToken(nPosN + 2, nPosEnd, eT_semicolumn); - assert(nPosN >= 0); - nPosN++; - } - nPos = Parser.FindToken(nPosEnd + 1, Parser.m_Tokens.size() - 1, eT_cbuffer); - } - else - { - nPos = Parser.FindToken(nPos + 2, Parser.m_Tokens.size() - 1, eT_cbuffer); - } - } -} - -struct SStructData -{ - uint32 m_nName; - uint32 m_nTCs; - int m_nPos; -}; - -void CHWShader_D3D::CorrectScriptEnums(CParserBin& Parser, SHWSInstance* pInst, std::vector& InstBindVars, FXShaderToken* Table) -{ - // correct enumeration of TEXCOORD# interpolators after preprocessing - int nCur = 0; - int nSize = Parser.m_Tokens.size(); - uint32* pTokens = &Parser.m_Tokens[0]; - int nInstParam = 0; - const uint32 Toks[] = {eT_TEXCOORDN, eT_TEXCOORDN_centroid, eT_unknown}; - - std::vector SData; - uint32 i; - while (true) - { - nCur = Parser.FindToken(nCur, nSize - 1, eT_struct); - if (nCur < 0) - { - break; - } - int nLastStr = Parser.FindToken(nCur, nSize - 1, eT_br_cv_2); - assert(nLastStr >= 0); - if (nLastStr < 0) - { - break; - } - bool bNested = false; - for (i = 0; i < SData.size(); i++) - { - SStructData& Data = SData[i]; - Data.m_nPos = Parser.FindToken(nCur, nLastStr, Data.m_nName); - if (Data.m_nPos > 0) - { - bNested = true; - } - } - uint32 nName = pTokens[nCur + 1]; - int n = 0; - while (nCur < nLastStr) - { - int nTN = Parser.FindToken(nCur, nLastStr, Toks); - if (nTN < 0) - { - nCur = nLastStr + 1; - break; - } - int nNested = 0; - if (bNested) - { - for (i = 0; i < SData.size(); i++) - { - SStructData& Data = SData[i]; - if (Data.m_nPos > 0 && nTN > Data.m_nPos) - { - nNested += Data.m_nTCs; - } - } - } - assert(pTokens[nTN - 1] == eT_colon); - int nArrSize = 1; - uint32 nTokName; - if (pTokens[nTN - 2] == eT_br_sq_2) - { - nArrSize = pTokens[nTN - 3] - eT_0; - if ((unsigned int) nArrSize > 15) - { - const char* szArrSize = Parser.GetString(pTokens[nTN - 3], *Table); - nArrSize = szArrSize ? atoi(szArrSize) : 0; - } - assert(pTokens[nTN - 4] == eT_br_sq_1); - //const char *szName = Parser.GetString(pTokens[nTN-5], *Table); - nTokName = pTokens[nTN - 5]; - } - else - { - uint32 nType = pTokens[nTN - 3]; - assert(nType == eT_float || nType == eT_float2 || nType == eT_float3 || nType == eT_float4 || nType == eT_float4x4 || nType == eT_float3x4 || nType == eT_float2x4 || nType == eT_float3x3 || - nType == eT_half || nType == eT_half2 || nType == eT_half3 || nType == eT_half4 || nType == eT_half4x4 || nType == eT_half3x4 || nType == eT_half2x4 || nType == eT_half3x3); - if (nType == eT_float4x4 || nType == eT_half4x4) - { - nArrSize = 4; - } - else - if (nType == eT_float3x4 || nType == eT_float3x3 || nType == eT_half3x4 || nType == eT_half3x3) - { - nArrSize = 3; - } - else - if (nType == eT_float2x4 || nType == eT_half2x4) - { - nArrSize = 2; - } - nTokName = pTokens[nTN - 2]; - } - assert(nArrSize > 0 && nArrSize < 16); - - EToken eT = (pTokens[nTN] == eT_TEXCOORDN) ? eT_TEXCOORD0 : eT_TEXCOORD0_centroid; - - pTokens[nTN] = n + nNested + eT; - n += nArrSize; - nCur = nTN + 1; - - if (pInst->m_Ident.m_RTMask & g_HWSR_MaskBit[HWSR_INSTANCING_ATTR]) - { - const char* szName = Parser.GetString(nTokName, *Table); - if (!_strnicmp(szName, "Inst", 4)) - { - char newName[256]; - int nm = 0; - while (szName[4 + nm] > 0x20 && szName[4 + nm] != '[') - { - newName[nm] = szName[4 + nm]; - nm++; - } - newName[nm++] = 0; - - SCGBind bn; - bn.m_RegisterOffset = nInstParam; - bn.m_RegisterCount = nArrSize; - bn.m_Name = newName; - InstBindVars.push_back(bn); - - nInstParam += nArrSize; - } - } - } - SStructData SD; - SD.m_nName = nName; - SD.m_nPos = -1; - SD.m_nTCs = n; - SData.push_back(SD); - } - if (InstBindVars.size()) - { - qsort(&InstBindVars[0], InstBindVars.size(), sizeof(SCGBind), CGBindCallback); - } - pInst->m_nNumInstAttributes = nInstParam; -} - -static int sFetchInst(uint32& nCur, uint32* pTokens, [[maybe_unused]] uint32 nT, std::vector& Parameter) -{ - while (true) - { - uint32 nTok = pTokens[nCur]; - if (nTok != eT_br_rnd_1 && nTok != eT_br_rnd_2 && nTok != eT_comma) - { - break; - } - nCur++; - } - int nC = 0; - Parameter.push_back(pTokens[nCur]); - nCur++; - while (pTokens[nCur] == eT_dot) - { - nC = 2; - Parameter.push_back(pTokens[nCur]); - Parameter.push_back(pTokens[nCur + 1]); - nCur += 2; - } - return nC; -} - -namespace HWShaderD3D { - static void sCR(TArray& Text, int nLevel) - { - Text.AddElem('\n'); - for (int i = 0; i < nLevel; i++) - { - Text.AddElem(' '); - Text.AddElem(' '); - } - } -} - -bool CHWShader_D3D::ConvertBinScriptToASCII(CParserBin& Parser, [[maybe_unused]] SHWSInstance* pInst, [[maybe_unused]] std::vector& InstBindVars, FXShaderToken* Table, TArray& Text) -{ - using namespace HWShaderD3D; - uint32 i; - bool bRes = true; - - uint32* pTokens = &Parser.m_Tokens[0]; - uint32 nT = Parser.m_Tokens.size(); - int nLevel = 0; - for (i = 0; i < nT; i++) - { - uint32 nToken = pTokens[i]; - if (nToken == 0) - { - Text.Copy("\n", 1); - continue; - } - if (nToken == eT_skip) - { - i++; - continue; - } - if (nToken == eT_skip_1) - { - while (i < nT) - { - nToken = pTokens[i]; - if (nToken == eT_skip_2) - { - break; - } - i++; - } - assert(i < nT); - continue; - } - if (nToken == eT_fetchinst) - { - char str[512]; - i++; - std::vector ParamDst, ParamSrc; - TArray sParamDstFull, sParamDstName, sParamSrc; - int nDst = sFetchInst(i, &Parser.m_Tokens[0], Parser.m_Tokens.size(), ParamDst); - assert(Parser.m_Tokens[i] == eT_eq); - if (Parser.m_Tokens[i] != eT_eq) - { // Should never happen - int n = CParserBin::FindToken(i, Parser.m_Tokens.size() - 1, &Parser.m_Tokens[0], eT_semicolumn); - if (n > 0) - { - i = n + 1; - } - continue; - } - i++; - int nSrc = sFetchInst(i, &Parser.m_Tokens[0], Parser.m_Tokens.size(), ParamSrc); - CParserBin::ConvertToAscii(&ParamDst[0], ParamDst.size(), *Table, sParamDstFull); - CParserBin::ConvertToAscii(&ParamDst[nDst], 1, *Table, sParamDstName); - CParserBin::ConvertToAscii(&ParamSrc[nSrc], 1, *Table, sParamSrc); - assert(strncmp(&sParamSrc[0], "Inst", 4) == 0); - - { - sParamSrc.Free(); - CParserBin::ConvertToAscii(&ParamSrc[0], ParamSrc.size(), *Table, sParamSrc); - sprintf_s(str, "%s = %s;\n", &sParamDstFull[0], &sParamSrc[0]); - Text.Copy(str, strlen(str)); - } - while (Parser.m_Tokens[i] != eT_semicolumn) - { - i++; - } - continue; - } - const char* szStr = CParserBin::GetString(nToken, *Table, false); - assert(szStr); - if (!szStr || !szStr[0]) - { - assert(0); - bRes = CParserBin::CorrectScript(pTokens, i, nT, Text); - } - else - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined (_DEBUG) - int n = 0; - while (szStr[n]) - { - char c = szStr[n++]; - bool bASC = isascii(c); - assert(bASC); - } -#endif - if (nToken == eT_semicolumn || nToken == eT_br_cv_1) - { - if (nToken == eT_br_cv_1) - { - sCR(Text, nLevel); - nLevel++; - } - Text.Copy(szStr, strlen(szStr)); - if (nToken == eT_semicolumn) - { - if (i + 1 < nT && pTokens[i + 1] == eT_br_cv_2) - { - sCR(Text, nLevel - 1); - } - else - { - sCR(Text, nLevel); - } - } - else - if (i + 1 < nT) - { - if (pTokens[i + 1] < eT_br_rnd_1 || pTokens[i + 1] >= eT_float) - { - sCR(Text, nLevel); - } - } - } - else - { - if (i + 1 < nT) - { - if (Text.Num()) - { - char cPrev = Text[Text.Num() - 1]; - if (!SkipChar((uint8)cPrev) && !SkipChar((uint8)szStr[0])) - { - Text.AddElem(' '); - } - } - } - Text.Copy(szStr, strlen(szStr)); - if (nToken == eT_br_cv_2) - { - nLevel--; - if (i + 1 < nT && pTokens[i + 1] != eT_semicolumn) - { - sCR(Text, nLevel); - } - } - } - } - } - Text.AddElem(0); - - return bRes; -} - -void CHWShader_D3D::mfGetSrcFileName(char* srcName, int nSize) -{ - if (!srcName || nSize <= 0) - { - return; - } - if (!m_NameSourceFX.empty()) - { - cry_strcpy(srcName, nSize, m_NameSourceFX.c_str()); - return; - } - cry_strcpy(srcName, nSize, gRenDev->m_cEF.m_HWPath); - if (m_eSHClass == eHWSC_Vertex) - { - cry_strcat(srcName, nSize, "Declarations/CGVShaders/"); - } - else if (m_eSHClass == eHWSC_Pixel) - { - cry_strcat(srcName, nSize, "Declarations/CGPShaders/"); - } - else - { - cry_strcat(srcName, nSize, "Declarations/CGGShaders/"); - } - cry_strcat(srcName, nSize, GetName()); - cry_strcat(srcName, nSize, ".crycg"); -} - -void CHWShader_D3D::mfGenName(SHWSInstance* pInst, char* dstname, int nSize, byte bType) -{ - if (bType) - { - CHWShader::mfGenName(pInst->m_Ident.m_GLMask, pInst->m_Ident.m_RTMask, pInst->m_Ident.m_LightMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask, pInst->m_eClass, dstname, nSize, bType); - } - else - { - CHWShader::mfGenName(0, 0, 0, 0, 0, 0, 0, eHWSC_Num, dstname, nSize, bType); - } -} - -void CHWShader_D3D::mfGetDstFileName(SHWSInstance* pInst, CHWShader_D3D* pSH, char* dstname, int nSize, byte bType) -{ - cry_strcpy(dstname, nSize, gRenDev->m_cEF.m_ShadersCache.c_str()); - - if (pSH->m_eSHClass == eHWSC_Vertex) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGVShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGVShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGVShaders/Pending/"); - } - } - else if (pSH->m_eSHClass == eHWSC_Pixel) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGPShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGPShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGPShaders/Pending/"); - } - } - else if (GEOMETRYSHADER_SUPPORT && pSH->m_eSHClass == eHWSC_Geometry) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGGShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGGShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGGShaders/Pending/"); - } - } - else if (GEOMETRYSHADER_SUPPORT && pSH->m_eSHClass == eHWSC_Hull) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGHShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGHShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGHShaders/Pending/"); - } - } - else if (GEOMETRYSHADER_SUPPORT && pSH->m_eSHClass == eHWSC_Domain) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGDShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGDShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGDShaders/Pending/"); - } - } - else if (GEOMETRYSHADER_SUPPORT && pSH->m_eSHClass == eHWSC_Compute) - { - if (bType == 1 || bType == 4) - { - cry_strcat(dstname, nSize, "CGCShaders/Debug/"); - } - else if (bType == 0) - { - cry_strcat(dstname, nSize, "CGCShaders/"); - } - else if (bType == 2 || bType == 3) - { - cry_strcat(dstname, nSize, "CGCShaders/Pending/"); - } - } - - cry_strcat(dstname, nSize, pSH->GetName()); - - if (bType == 2) - { - cry_strcat(dstname, nSize, "_out"); - } - - if (bType == 0) - { - char* s = strchr(dstname, '('); - if (s) - { - s[0] = 0; - } - } - - char szGenName[256]; - mfGenName(pInst, szGenName, 256, bType); - - cry_strcat(dstname, nSize, szGenName); -} - -//======================================================================================================== -// Binary cache support - -SShaderCache::~SShaderCache() -{ - if (m_pStreamInfo) - { - CResFile* pRes = m_pStreamInfo->m_pRes; - if (pRes) - { - assert(pRes == m_pRes[0] || pRes == m_pRes[1]); - assert(!pRes->mfIsDirStreaming()); - //bWarn = pRes->mfIsDirStreaming(); - } - /*if (m_pStreamInfo->m_EntriesQueue.size()) - bWarn = true; - if (bWarn) - Warning("Warning: SShader`Cache::~SShaderCache(): '%s' Streaming tasks is still in progress!: %d", m_Name.c_str(), m_pStreamInfo->m_EntriesQueue.size());*/ - - m_pStreamInfo->AbortJobs(); - } - - CHWShader::m_ShaderCache.erase(m_Name); - SAFE_DELETE(m_pRes[CACHE_USER]); - SAFE_DELETE(m_pRes[CACHE_READONLY]); - SAFE_RELEASE(m_pStreamInfo); -} - -void SShaderCache::Cleanup() -{ - if (m_pRes[0]) - { - m_pRes[0]->mfDeactivate(true); - } - if (m_pRes[1]) - { - m_pRes[1]->mfDeactivate(true); - } -} - -bool SShaderCache::isValid() -{ - return ((m_pRes[CACHE_READONLY] || m_pRes[CACHE_USER]) && CParserBin::m_nPlatform == m_nPlatform); -} - -int SShaderCache::Size() -{ - int nSize = sizeof(SShaderCache); - - if (m_pRes[0]) - { - nSize += m_pRes[0]->Size(); - } - if (m_pRes[1]) - { - nSize += m_pRes[1]->Size(); - } - - return nSize; -} -int SShaderDevCache::Size() -{ - int nSize = sizeof(SShaderDevCache); - - nSize += m_DeviceShaders.size() * sizeof(SD3DShader); - - return nSize; -} - -void SShaderCache::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_pRes[0]); - pSizer->AddObject(m_pRes[1]); -} - -void SShaderDevCache::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(*this)); - pSizer->AddObject(m_DeviceShaders); -} - -SShaderDevCache* CHWShader::mfInitDevCache(const char* name, [[maybe_unused]] CHWShader* pSH) -{ - CCryNameR cryShaderName(name); - return new SShaderDevCache(cryShaderName); -} - -SShaderCacheHeaderItem* CHWShader_D3D::mfGetCompressedItem([[maybe_unused]] uint32 nFlags, int32& nSize) -{ - SHWSInstance* pInst = m_pCurInst; - char name[128]; - { - azstrcpy(name, AZ_ARRAY_SIZE(name), GetName()); - char* s = strchr(name, '('); - if (s) - { - s[0] = 0; - } - } - - CCryNameTSCRC Name = name; - FXCompressedShadersItor it = CHWShader::m_CompressedShaders.find(Name); - if (it == CHWShader::m_CompressedShaders.end()) - { - return NULL; - } - SHWActivatedShader* pAS = it->second; - assert(pAS); - if (!pAS) - { - return NULL; - } - mfGenName(pInst, name, 128, 1); - Name = name; - FXCompressedShaderRemapItor itR = pAS->m_Remap.find(Name); - if (itR == pAS->m_Remap.end()) - { - return NULL; - } - int nDevID = itR->second; - FXCompressedShaderItor itS = pAS->m_CompressedShaders.find(nDevID); - if (itS == pAS->m_CompressedShaders.end()) - { - return NULL; - } - SCompressedData& CD = itS->second; - assert(CD.m_pCompressedShader); - if (!CD.m_pCompressedShader) - { - return NULL; - } - byte* pData = new byte[CD.m_nSizeDecompressedShader]; - if (!pData) - { - return NULL; - } - pInst->m_DeviceObjectID = nDevID; - SShaderCacheHeaderItem* pIt = (SShaderCacheHeaderItem*)pData; - if (CParserBin::m_bEndians) - { - SwapEndian(*pIt, eBigEndian); - } - nSize = CD.m_nSizeDecompressedShader; - return pIt; -} - -SShaderCacheHeaderItem* CHWShader_D3D::mfGetCacheItem(uint32& nFlags, int32& nSize) -{ - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - SHWSInstance* pInst = m_pCurInst; - byte* pData = NULL; - nSize = 0; - if (!m_pGlobalCache || !m_pGlobalCache->isValid()) - { - return NULL; - } - CResFile* rf = NULL; - SDirEntry* de = NULL; - int i; - bool bAsync = false; - int n = CRenderer::CV_r_shadersAllowCompilation == 0 ? 1 : 2; - for (i = 0; i < n; i++) - { - rf = m_pGlobalCache->m_pRes[i]; - if (!rf) - { - continue; - } - char name[128]; - mfGenName(pInst, name, 128, 1); - de = rf->mfGetEntry(name, &bAsync); - if (de || bAsync) - { - break; - } - } - if (de) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 3 || CRenderer::CV_r_shadersdebug == 4) - { - iLog->Log("---Cache: LoadedFromGlobal %s': 0x%x", rf->mfGetFileName(), de->Name.get()); - } - pInst->m_nCache = i; - SShaderCacheHeaderItem* pIt = NULL; - nSize = rf->mfFileRead(de); - pInst->m_bAsyncActivating = (nSize == -1); - pData = (byte*)rf->mfFileGetBuf(de); - if (pData && nSize > 0) - { - byte* pD = new byte[nSize]; - memcpy(pD, pData, nSize); - pIt = (SShaderCacheHeaderItem*)pD; - if (CParserBin::m_bEndians) - { - SwapEndian(*pIt, eBigEndian); - } - pInst->m_DeviceObjectID = de->Name.get(); - rf->mfFileClose(de); - } - if (i == CACHE_USER) - { - nFlags |= HWSG_CACHE_USER; - } - return pIt; - } - else - { - pInst->m_bAsyncActivating = bAsync; - return NULL; - } -} - -bool CHWShader_D3D::mfAddCacheItem(SShaderCache* pCache, SShaderCacheHeaderItem* pItem, const byte* pData, int nLen, bool bFlush, CCryNameTSCRC Name) -{ - if (!pCache) - { - return false; - } - if (!pCache->m_pRes[CACHE_USER]) - { - return false; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 3 || CRenderer::CV_r_shadersdebug == 4) - { - iLog->Log("---Cache: StoredToGlobal %s': 0x%x", pCache->m_pRes[CACHE_USER]->mfGetFileName(), Name.get()); - } - - pItem->m_CRC32 = CCrc32::Compute(pData, nLen); - //CryLog("Size: %d: CRC: %x", nLen, pItem->m_CRC32); - - byte* pNew = new byte[sizeof(SShaderCacheHeaderItem) + nLen]; - SDirEntry de; - de.offset = 0; - if (CParserBin::m_bEndians) - { - SShaderCacheHeaderItem IT = *pItem; - SwapEndian(IT, eBigEndian); - memcpy(pNew, &IT, sizeof(SShaderCacheHeaderItem)); - } - else - { - memcpy(pNew, pItem, sizeof(SShaderCacheHeaderItem)); - } - memcpy(&pNew[sizeof(SShaderCacheHeaderItem)], pData, nLen); - de.Name = Name; - de.flags = RF_COMPRESS | RF_TEMPDATA; - de.size = nLen + sizeof(SShaderCacheHeaderItem); - pCache->m_pRes[CACHE_USER]->mfFileAdd(&de); - SDirEntryOpen* pOE = pCache->m_pRes[CACHE_USER]->mfOpenEntry(&de); - pOE->pData = pNew; - if (bFlush) - { - pCache->m_pRes[CACHE_USER]->mfFlush(); - } - - return true; -} - -SEmptyCombination::Combinations SEmptyCombination::s_Combinations; - -bool CHWShader_D3D::mfAddEmptyCombination([[maybe_unused]] CShader* pSH, uint64 nRT, uint64 nGL, uint32 nLT) -{ - CD3D9Renderer* rd = gcpRendD3D; - SRenderPipeline& RESTRICT_REFERENCE rRP = rd->m_RP; - - SEmptyCombination Comb; - Comb.nGLNew = m_nMaskGenShader; - Comb.nRTNew = rRP.m_FlagsShader_RT & m_nMaskAnd_RT | m_nMaskOr_RT; - Comb.nLTNew = rRP.m_FlagsShader_LT; - Comb.nGLOrg = nGL; - Comb.nRTOrg = nRT & m_nMaskAnd_RT | m_nMaskOr_RT; - Comb.nLTOrg = nLT; - Comb.nMD = rRP.m_FlagsShader_MD; - Comb.nMDV = rRP.m_FlagsShader_MDV; - Comb.nST = m_maskGenStatic; - if (m_eSHClass == eHWSC_Pixel) - { - Comb.nMD &= ~HWMD_TEXCOORD_FLAG_MASK; - Comb.nMDV = 0; - } - - Comb.pShader = this; - if (Comb.nRTNew != Comb.nRTOrg || Comb.nGLNew != Comb.nGLOrg || Comb.nLTNew != Comb.nLTOrg) - { - SEmptyCombination::s_Combinations.push_back(Comb); - } - - m_nMaskGenShader = nGL; - - return true; -} - -bool CHWShader_D3D::mfStoreEmptyCombination(SEmptyCombination& Comb) -{ - if (!m_pGlobalCache || !m_pGlobalCache->m_pRes[CACHE_USER]) - { - return false; - } - - CResFile* rf = m_pGlobalCache->m_pRes[CACHE_USER]; - char nameOrg[128]; - char nameNew[128]; - SShaderCombIdent Ident; - Ident.m_GLMask = Comb.nGLNew; - Ident.m_RTMask = Comb.nRTNew; - Ident.m_LightMask = Comb.nLTNew; - Ident.m_MDMask = Comb.nMD; - Ident.m_MDVMask = Comb.nMDV; - Ident.m_STMask = Comb.nST; - SHWSInstance* pInstNew = mfGetInstance(gRenDev->m_RP.m_pShader, Ident, 0); - mfGenName(pInstNew, nameNew, 128, 1); - SDirEntry* deNew = rf->mfGetEntry(nameNew); - //assert(deNew); - if (!deNew) - { - return false; - } - - Ident.m_GLMask = Comb.nGLOrg; - Ident.m_RTMask = Comb.nRTOrg; - Ident.m_LightMask = Comb.nLTOrg; - Ident.m_MDMask = Comb.nMD; - Ident.m_MDVMask = Comb.nMDV; - Ident.m_STMask = Comb.nST; - SHWSInstance* pInstOrg = mfGetInstance(gRenDev->m_RP.m_pShader, Ident, 0); - mfGenName(pInstOrg, nameOrg, 128, 1); - SDirEntry* deOrg = rf->mfGetEntry(nameOrg); - if (deOrg) - { - if (deOrg->offset != deNew->offset) - { - deOrg->offset = -abs(deNew->offset); - deOrg->flags |= RF_NOTSAVED; - } - return true; - } - SDirEntry de; - de.Name = CCryNameTSCRC(nameOrg); - de.flags = deNew->flags; - de.size = deNew->size; - de.offset = -abs(deNew->offset); - rf->mfFileAdd(&de); - - return true; -} - -bool CHWShader_D3D::mfFlushCacheFile() -{ - uint32 i; - - for (i = 0; i < m_Insts.size(); i++) - { - SHWSInstance* pInst = m_Insts[i]; - if (pInst->m_Handle.m_bStatus == 2) // Fake - { - pInst->m_Handle.SetShader(NULL); - } - } - return m_pGlobalCache && m_pGlobalCache->m_pRes[CACHE_USER] && m_pGlobalCache->m_pRes[CACHE_USER]->mfFlush(); -} - -struct SData -{ - CCryNameTSCRC Name; - uint32 nSizeDecomp; - uint32 nSizeComp; - //uint32 CRC; - uint16 flags; - int nOffset; - byte* pData; - byte bProcessed; - - bool operator <(const SData& o) const - { - return Name < o.Name; - } -}; -#if !defined(CONSOLE) -// Remove shader duplicates -bool CHWShader::mfOptimiseCacheFile(SShaderCache* pCache, [[maybe_unused]] bool bForce, SOptimiseStats* pStats) -{ - CResFile* pRes = pCache->m_pRes[CACHE_USER]; - pRes->mfFlush(); - ResDir* Dir = pRes->mfGetDirectory(); - uint32 i, j; -#ifdef _DEBUG - /*for (i=0; isize(); i++) - { - SDirEntry *pDE = &(*Dir)[i]; - for (j=i+1; jsize(); j++) - { - SDirEntry *pDE1 = &(*Dir)[j]; - assert(pDE->Name != pDE1->Name); - } - } - */ - mfValidateTokenData(pRes); -#endif - - std::vector Data; - bool bNeedOptimise = true; - if (pStats) - { - pStats->nEntries += Dir->size(); - } - for (i = 0; i < Dir->size(); i++) - { - SDirEntry* pDE = &(*Dir)[i]; - if (pDE->flags & RF_RES_$) - { - if (pDE->Name == CShaderMan::s_cNameHEAD) - { - continue; - } - - SData d; - d.nSizeComp = d.nSizeDecomp = 0; - d.pData = pRes->mfFileReadCompressed(pDE, d.nSizeDecomp, d.nSizeComp); - assert(d.pData && d.nSizeComp && d.nSizeDecomp); - if (!d.pData || !d.nSizeComp || !d.nSizeDecomp) - { - continue; - } - if (pStats) - { - pStats->nTokenDataSize += d.nSizeDecomp; - } - d.bProcessed = 3; - d.Name = pDE->Name; - //d.CRC = 0; - d.nOffset = 0; - d.flags = (short)pDE->flags; - Data.push_back(d); - continue; - } - SData d; - d.flags = pDE->flags; - d.nSizeComp = d.nSizeDecomp = 0; - d.pData = pRes->mfFileReadCompressed(pDE, d.nSizeDecomp, d.nSizeComp); - assert(d.pData && d.nSizeComp && d.nSizeDecomp); - if (!d.pData || !d.nSizeComp || !d.nSizeDecomp) - { - continue; - } - d.nOffset = pDE->offset; - d.bProcessed = 0; - d.Name = pDE->Name; - //d.CRC = 0; - Data.push_back(d); - pRes->mfCloseEntry(pDE); - } - //FILE *fp = NULL; - int nDevID = 0x10000000; - int nOutFiles = Data.size(); - if (bNeedOptimise) - { - for (i = 0; i < Data.size(); i++) - { - /*if (fp) - { - gEnv->pCryPak->FClose(fp); - fp = NULL; - }*/ - if (Data[i].bProcessed) - { - continue; - } - byte* pD = Data[i].pData; - Data[i].bProcessed = 1; - Data[i].nOffset = nDevID++; - int nSizeComp = Data[i].nSizeComp; - int nSizeDecomp = Data[i].nSizeDecomp; - for (j = i + 1; j < Data.size(); j++) - { - if (Data[j].bProcessed) - { - continue; - } - byte* pD1 = Data[j].pData; - if (nSizeComp != Data[j].nSizeComp || nSizeDecomp != Data[j].nSizeDecomp) - { - continue; - } - if (!memcmp(pD, pD1, nSizeComp)) - { - /*if (!fp && CRenderer::CV_r_shaderscacheoptimiselog) - { - char name[256]; - sprintf_s(name, "Optimise/%s/%s.cache", pRes->mfGetFileName(), Data[i].Name.c_str()); - fp = gEnv->pCryPak->FOpen(name, "w"); - }*/ - Data[j].nOffset = Data[i].nOffset; - Data[j].bProcessed = 2; - nOutFiles--; - //if (fp) - // gEnv->pCryPak->FPrintf(fp, "%s\n", Data[j].Name.c_str()); - } - } - } - } - /*if (fp) - { - gEnv->pCryPak->FClose(fp); - fp = NULL; - }*/ - - if (nOutFiles != Data.size() || CRenderer::CV_r_shaderscachedeterministic) - { - if (nOutFiles == Data.size()) - { - iLog->Log(" Forcing optimise for deterministic order..."); - } - - iLog->Log(" Optimising shaders resource '%s' (%" PRISIZE_T " items)...", pCache->m_Name.c_str(), Data.size() - 1); - - pRes->mfClose(); - pRes->mfOpen(RA_CREATE | (CParserBin::m_bEndians ? RA_ENDIANS : 0), &gRenDev->m_cEF.m_ResLookupDataMan[CACHE_USER]); - - float fVersion = FX_CACHE_VER; - uint32 nMinor = (int)(((float)fVersion - (float)(int)fVersion) * 10.1f); - uint32 nMajor = (int)fVersion; - - SResFileLookupData* pLookupCache = pCache->m_pRes[CACHE_USER]->GetLookupData(false, 0, 0); - CRY_ASSERT(pLookupCache != NULL); - - if (pLookupCache == NULL || pLookupCache->m_CacheMajorVer != nMajor || pLookupCache->m_CacheMinorVer != nMinor) - { - CRY_ASSERT_MESSAGE(pLookupCache == NULL, "Losing ShaderIdents by recreating lookupdata cache"); - pLookupCache = pRes->GetLookupData(true, 0, FX_CACHE_VER); - } - - pRes->mfFlush(); - - if (CRenderer::CV_r_shaderscachedeterministic) - { - std::sort(Data.begin(), Data.end()); - } - - for (i = 0; i < Data.size(); i++) - { - SData* pD = &Data[i]; - - SDirEntry de; - de.Name = pD->Name; - de.flags = pD->flags; - if (pD->bProcessed == 1) - { - de.offset = pD->nOffset; - de.flags |= RF_COMPRESS | RF_COMPRESSED; - if (pStats) - { - pStats->nSizeUncompressed += pD->nSizeDecomp; - pStats->nSizeCompressed += pD->nSizeComp; - pStats->nUniqueEntries++; - } - assert(pD->pData); - if (pD->pData) - { - de.size = pD->nSizeComp + 4; - SDirEntryOpen* pOE = pRes->mfOpenEntry(&de); - byte* pData = new byte[de.size]; - int nSize = pD->nSizeDecomp; - *(int*)pData = nSize; - memcpy(&pData[4], pD->pData, pD->nSizeComp); - de.flags |= RF_TEMPDATA; - pOE->pData = pData; - SAFE_DELETE_ARRAY(pD->pData); - } - } - else - if (pD->bProcessed != 3) - { - de.size = pD->nSizeComp + 4; - de.flags |= RF_COMPRESS; - de.offset = -pD->nOffset; - SAFE_DELETE_ARRAY(pD->pData); - } - else - { - SDirEntryOpen* pOE = pRes->mfOpenEntry(&de); - pOE->pData = pD->pData; - de.size = pD->nSizeDecomp; - } - pRes->mfFileAdd(&de); - } - } - - if (nOutFiles != Data.size()) - { - iLog->Log(" -- Removed %" PRISIZE_T " duplicated shaders", Data.size() - nOutFiles); - } - - Data.clear(); - int nSizeDir = pRes->mfFlush(true); - //int nSizeCompr = pRes->mfFlush(); - -#ifdef _DEBUG - mfValidateTokenData(pRes); -#endif - - if (pStats) - { - pStats->nDirDataSize += nSizeDir; - } - - for (i = 0; i < Data.size(); i++) - { - SData* pD = &Data[i]; - SAFE_DELETE_ARRAY(pD->pData); - } - - if (pStats) - { - CryLog(" -- Shader cache '%s' stats: Entries: %d, Unique Entries: %d, Size: %.3f Mb, Compressed Size: %.3f Mb, Token data size: %3f Mb, Directory Size: %.3f Mb", pCache->m_Name.c_str(), pStats->nEntries, pStats->nUniqueEntries, pStats->nSizeUncompressed / 1024.0f / 1024.0f, pStats->nSizeCompressed / 1024.0f / 1024.0f, pStats->nTokenDataSize / 1024.0f / 1024.0f, pStats->nDirDataSize / 1024.0f / 1024.0f); - } - - return true; -} -#endif - -int __cdecl sSort(const VOID* arg1, const VOID* arg2) -{ - SDirEntry** pi1 = (SDirEntry**)arg1; - SDirEntry** pi2 = (SDirEntry**)arg2; - SDirEntry* ti1 = *pi1; - SDirEntry* ti2 = *pi2; - if (ti1->Name < ti2->Name) - { - return -1; - } - if (ti1->Name == ti2->Name) - { - return 0; - } - return 1; -} - -bool CHWShader::_OpenCacheFile(float fVersion, SShaderCache* pCache, CHWShader* pSH, bool bCheckValid, uint32 CRC32, int nCache, CResFile* pRF, bool bReadOnly) -{ - assert(nCache == CACHE_USER || nCache == CACHE_READONLY); - - bool bValid = true; - CHWShader_D3D* pSHHW = (CHWShader_D3D*)pSH; - int nRes = pRF->mfOpen(RA_READ | (CParserBin::m_bEndians ? RA_ENDIANS : 0), &gRenDev->m_cEF.m_ResLookupDataMan[nCache], (nCache == CACHE_READONLY && pCache->m_pStreamInfo) ? pCache->m_pStreamInfo : NULL); - if (nRes == 0) - { - pRF->mfClose(); - bValid = false; - } - else - if (nRes > 0) - { - if (bValid) - { - SResFileLookupData* pLookup = pRF->GetLookupData(false, 0, 0); - if (!pLookup) - { - bValid = false; - } - else - if (bCheckValid) - { - if (fVersion && (pLookup->m_CacheMajorVer != (int)fVersion || pLookup->m_CacheMinorVer != (int)(((float)fVersion - (float)(int)fVersion) * 10.1f))) - { - bValid = false; - } - if (!bValid && (CRenderer::CV_r_shadersdebug == 2 || nCache == CACHE_READONLY)) - { - LogWarningEngineOnly("WARNING: Shader cache '%s' version mismatch (Cache: %d.%d, Expected: %.1f)", pRF->mfGetFileName(), pLookup->m_CacheMajorVer, pLookup->m_CacheMinorVer, fVersion); - } - if (pSH) - { - if (bValid && pLookup->m_CRC32 != pSHHW->m_CRC32) - { - bValid = false; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 2 && (CRenderer::CV_r_shadersdebug == 2 || nCache == CACHE_READONLY)) - { - LogWarningEngineOnly("WARNING: Shader cache '%s' CRC mismatch", pRF->mfGetFileName()); - } - } - } - } - } - - if (nCache == CACHE_USER) - { - pRF->mfClose(); - if (bValid) - { - int nAcc = CRenderer::CV_r_shadersAllowCompilation != 0 ? (RA_READ | RA_WRITE) : RA_READ; - if (!pRF->mfOpen(nAcc | (CParserBin::m_bEndians ? RA_ENDIANS : 0), &gRenDev->m_cEF.m_ResLookupDataMan[nCache])) - { - pRF->mfClose(); - bValid = false; - } - } - } - } - if (!bValid && bCheckValid) - { - if (nCache == CACHE_USER && !bReadOnly) - { - if (!pRF->mfOpen(RA_CREATE | (CParserBin::m_bEndians ? RA_ENDIANS : 0), &gRenDev->m_cEF.m_ResLookupDataMan[nCache])) - { - return false; - } - - pRF->GetLookupData(true, CRC32, FX_CACHE_VER); - if (pSHHW) - { - pRF->mfFlush(); - } - pCache->m_bNeedPrecache = true; - bValid = true; - } - else - { - SAFE_DELETE(pRF); - } - } - pCache->m_pRes[nCache] = pRF; - pCache->m_bReadOnly[nCache] = bReadOnly; - -#ifdef _DEBUG - mfValidateTokenData(pRF); -#endif - - return bValid; -} - -bool CHWShader::mfOpenCacheFile(const char* szName, float fVersion, SShaderCache* pCache, CHWShader* pSH, bool bCheckValid, uint32 CRC32, bool bReadOnly) -{ - bool bValidRO = false; - bool bValidUser = true; - // don't load the readonly cache, when shaderediting is true - if (!CRenderer::CV_r_shadersediting && !pCache->m_pRes[CACHE_READONLY]) - { - CResFile* rfRO = new CResFile(szName); - bool bRO = bReadOnly; - if (!CRenderer::CV_r_shadersAllowCompilation) - { - bRO = true; - } - bValidRO = _OpenCacheFile(fVersion, pCache, pSH, bCheckValid, CRC32, CACHE_READONLY, rfRO, bRO); - } - if (!CRenderer::CV_r_shadersAllowCompilation) - { - assert(bReadOnly); - } - if ((!bReadOnly || gRenDev->IsShaderCacheGenMode()) && !pCache->m_pRes[CACHE_USER]) - { - stack_string szUser = stack_string(gRenDev->m_cEF.m_szCachePath.c_str()) + stack_string(szName); - CResFile* rfUser = new CResFile(szUser.c_str()); - bValidUser = _OpenCacheFile(fVersion, pCache, pSH, bCheckValid, CRC32, CACHE_USER, rfUser, bReadOnly); - } - - return (bValidRO || bValidUser); -} - -SShaderCache* CHWShader::mfInitCache(const char* name, CHWShader* pSH, bool bCheckValid, uint32 CRC32, bool bReadOnly, bool bAsync) -{ - // LOADING_TIME_PROFILE_SECTION(iSystem); - - CHWShader_D3D* pSHHW = (CHWShader_D3D*)pSH; - char nameCache[256]; - - if (!CRenderer::CV_r_shadersAllowCompilation) - { - bCheckValid = false; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersediting) - { - bReadOnly = false; - } - - if (!name) - { - char namedst[256]; - pSHHW->mfGetDstFileName(pSHHW->m_pCurInst, pSHHW, namedst, 256, 0); - fpStripExtension(namedst, nameCache); - fpAddExtension(nameCache, ".fxcb"); - name = nameCache; - } - - SShaderCache* pCache = NULL; - FXShaderCacheItor it = m_ShaderCache.find(CCryNameR(name)); - if (it != m_ShaderCache.end()) - { - pCache = it->second; - pCache->AddRef(); - if (pSHHW) - { - if (bCheckValid) - { - int nCache[2] = {-1, -1}; - if (!CRenderer::CV_r_shadersAllowCompilation) - { - nCache[0] = CACHE_READONLY; - } - else - { - nCache[0] = CACHE_USER; - nCache[1] = CACHE_READONLY; - } - bool bValid; - for (int i = 0; i < 2; i++) - { - if (nCache[i] < 0 || !pCache->m_pRes[i]) - { - continue; - } - CResFile* pRF = pCache->m_pRes[i]; - SResFileLookupData* pLookup = pRF->GetLookupData(false, 0, FX_CACHE_VER); - bValid = (pLookup && pLookup->m_CRC32 == CRC32); - if (!bValid) - { - SAFE_DELETE(pCache->m_pRes[i]); - } - } - bValid = true; - if (!CRenderer::CV_r_shadersAllowCompilation && !pCache->m_pRes[CACHE_READONLY]) - { - bValid = false; - } - else - { - if (bReadOnly && (!pCache->m_pRes[CACHE_READONLY] || !pCache->m_pRes[CACHE_USER])) - { - bValid = false; - } - if (!bReadOnly && !pCache->m_pRes[CACHE_USER]) - { - bValid = false; - } - } - if (!bValid) - { - mfOpenCacheFile(name, FX_CACHE_VER, pCache, pSH, bCheckValid, CRC32, bReadOnly); - } - } - } - } - else - { - pCache = new SShaderCache; - if (bAsync) - { - pCache->m_pStreamInfo = new SResStreamInfo(pCache); - } - pCache->m_nPlatform = CParserBin::m_nPlatform; - pCache->m_Name = name; - mfOpenCacheFile(name, FX_CACHE_VER, pCache, pSH, bCheckValid, CRC32, bReadOnly); - m_ShaderCache.insert(FXShaderCacheItor::value_type(CCryNameR(name), pCache)); - } - - return pCache; -} - - -byte* CHWShader_D3D::mfBindsToCache([[maybe_unused]] SHWSInstance* pInst, std::vector* Binds, int nParams, byte* pP) -{ - int i; - for (i = 0; i < nParams; i++) - { - SCGBind* cgb = &(*Binds)[i]; - SShaderCacheHeaderItemVar* pVar = (SShaderCacheHeaderItemVar*)pP; - pVar->m_nCount = cgb->m_RegisterCount; - pVar->m_Reg = cgb->m_RegisterOffset; - if (CParserBin::m_bEndians) - { - SwapEndian(pVar->m_nCount, eBigEndian); - SwapEndian(pVar->m_Reg, eBigEndian); - } - int len = strlen(cgb->m_Name.c_str()) + 1; - memcpy(pVar->m_Name, cgb->m_Name.c_str(), len); - pP += offsetof(SShaderCacheHeaderItemVar, m_Name) + strlen(pVar->m_Name) + 1; - } - return pP; -} - -byte* CHWShader_D3D::mfBindsFromCache(std::vector*& Binds, int nParams, byte* pP) -{ - int i; - for (i = 0; i < nParams; i++) - { - if (!Binds) - { - Binds = new std::vector; - } - SCGBind cgb; - SShaderCacheHeaderItemVar* pVar = (SShaderCacheHeaderItemVar*)pP; - - short nParameters = pVar->m_nCount; - if (CParserBin::m_bEndians) - { - SwapEndian(nParameters, eBigEndian); - } - cgb.m_RegisterCount = nParameters; - - cgb.m_Name = pVar->m_Name; - - int dwBind = pVar->m_Reg; - if (CParserBin::m_bEndians) - { - SwapEndian(dwBind, eBigEndian); - } - cgb.m_RegisterOffset = dwBind; - - Binds->push_back(cgb); - pP += offsetof(SShaderCacheHeaderItemVar, m_Name) + strlen(pVar->m_Name) + 1; - } - return pP; -} - -byte* CHWShader::mfIgnoreBindsFromCache(int nParams, byte* pP) -{ - int i; - for (i = 0; i < nParams; i++) - { - SShaderCacheHeaderItemVar* pVar = (SShaderCacheHeaderItemVar*)pP; - pP += offsetof(SShaderCacheHeaderItemVar, m_Name) + strlen(pVar->m_Name) + 1; - } - return pP; -} - -bool CHWShader_D3D::mfUploadHW(SHWSInstance* pInst, byte* pBuf, uint32 nSize, CShader* pSH, uint32 nFlags) -{ - PROFILE_FRAME(Shader_mfUploadHW); - - const char* sHwShaderName = _HELP("Vertex Shader"); - if (m_eSHClass == eHWSC_Pixel) - { - sHwShaderName = _HELP("Pixel Shader"); - } - - HRESULT hr = S_OK; - if (!pInst->m_Handle.m_pShader) - { - pInst->m_Handle.SetShader(new SD3DShader); - } - - if ((m_eSHClass == eHWSC_Vertex) && (!(nFlags & HWSF_PRECACHE) || gRenDev->m_cEF.m_bActivatePhase) && !pInst->m_bFallback) - { - mfUpdateFXVertexFormat(pInst, pSH); - } - - pInst->m_nDataSize = nSize; - if (m_eSHClass == eHWSC_Pixel) - { - s_nDevicePSDataSize += nSize; - } - else - { - s_nDeviceVSDataSize += nSize; - } - - if (m_eSHClass == eHWSC_Pixel) - { - hr = gcpRendD3D->GetDevice().CreatePixelShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - if (m_eSHClass == eHWSC_Vertex) - { - hr = gcpRendD3D->GetDevice().CreateVertexShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - if (m_eSHClass == eHWSC_Geometry) - { - hr = gcpRendD3D->GetDevice().CreateGeometryShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - if (m_eSHClass == eHWSC_Hull) - { - hr = gcpRendD3D->GetDevice().CreateHullShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - if (m_eSHClass == eHWSC_Compute) - { - hr = gcpRendD3D->GetDevice().CreateComputeShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - if (m_eSHClass == eHWSC_Domain) - { - hr = gcpRendD3D->GetDevice().CreateDomainShader(alias_cast(pBuf), nSize, NULL, alias_cast(&pInst->m_Handle.m_pShader->m_pHandle)); - } - else - { - assert(0); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif - - // Assign name to Shader for enhanced debugging -#if !defined(RELEASE) && defined(WIN64) - if (pInst->m_Handle.m_pShader->m_pHandle) - { - char name[1024]; - azsprintf(name, "%s_%s(LT%x)@(RT%llx)(MD%x)(MDV%x)(GL%llx)(PSS%llx)(ST%llx)", pSH->GetName(), m_EntryFunc.c_str(), pInst->m_Ident.m_LightMask, pInst->m_Ident.m_RTMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, pInst->m_Ident.m_GLMask, pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask); - ((ID3D11DeviceChild*)pInst->m_Handle.m_pShader->m_pHandle)->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); - } -#endif - - return (hr == S_OK); -} - -bool CHWShader_D3D::mfUploadHW(LPD3D10BLOB pShader, SHWSInstance* pInst, CShader* pSH, uint32 nFlags) -{ - bool bResult = true; - if (m_eSHClass == eHWSC_Vertex && !pInst->m_bFallback) - { - mfUpdateFXVertexFormat(pInst, pSH); - } - if (pShader && !(m_Flags & HWSG_PRECACHEPHASE)) - { - DWORD* pCode = (DWORD*)pShader->GetBufferPointer(); - if (gcpRendD3D->m_cEF.m_nCombinationsProcess >= 0 && !gcpRendD3D->m_cEF.m_bActivatePhase) - { - pInst->m_Handle.SetFake(); - } - else - { - bResult = mfUploadHW(pInst, (byte*)pCode, (uint32)pShader->GetBufferSize(), pSH, nFlags); - if (m_eSHClass == eHWSC_Vertex) - { - size_t nSize = pShader->GetBufferSize(); - pInst->m_pShaderData = new byte[nSize]; - pInst->m_nDataSize = nSize; - memcpy(pInst->m_pShaderData, pCode, nSize); - pInst->m_uniqueNameCRC = AZ::Crc32(GetName()); - } - } - if (!bResult) - { - if (m_eSHClass == eHWSC_Vertex) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create vertex shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - else - if (m_eSHClass == eHWSC_Pixel) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create pixel shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - else - if (m_eSHClass == eHWSC_Geometry) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create geometry shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - else - if (m_eSHClass == eHWSC_Domain) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create domain shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - else - if (m_eSHClass == eHWSC_Hull) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create hull shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - else - if (m_eSHClass == eHWSC_Compute) - { - Warning("CHWShader_D3D::mfUploadHW: Could not create compute shader '%s'(0x%" PRIx64 ")\n", GetName(), pInst->m_Ident.m_GLMask); - } - } - } - return bResult; -} - -bool CHWShader_D3D::mfActivateCacheItem(CShader* pSH, SShaderCacheHeaderItem* pItem, uint32 nSize, uint32 nFlags) -{ - SHWSInstance* pInst = m_pCurInst; - byte* pData = (byte*)pItem; - pData += sizeof(SShaderCacheHeaderItem); - byte* pBuf = pData; - std::vector* pInstBinds = NULL; - pInst->Release(m_pDevCache, false); - pBuf = mfBindsFromCache(pInstBinds, pItem->m_nInstBinds, pBuf); - nSize -= (uint32)(pBuf - (byte*)pItem); - pInst->m_eClass = (EHWShaderClass)pItem->m_Class; - -#if !defined(_RELEASE) - if (pItem->m_nVertexFormat >= eVF_Max) - { - AZ_Warning("Graphics", false, "Existing vertex format with enum %d not legit (must be less than %d). Is the shader cache out of date? Defaulting to eVF_P3S_C4B_T2S.", pItem->m_nVertexFormat, eVF_Max); - pItem->m_nVertexFormat = eVF_P3S_C4B_T2S; - } -#endif - pInst->m_vertexFormat = AZ::Vertex::Format(gcpRendD3D->m_RP.m_vertexFormats[pItem->m_nVertexFormat]); - - pInst->m_nInstructions = pItem->m_nInstructions; - pInst->m_VStreamMask_Decl = pItem->m_StreamMask_Decl; - pInst->m_VStreamMask_Stream = pItem->m_StreamMask_Stream; - bool bResult = true; - SD3DShader* pHandle = NULL; - SShaderDevCache* pCache = m_pDevCache; - if (!(nFlags & HWSG_CACHE_USER)) - { - if (pCache) - { - FXDeviceShaderItor it = pCache->m_DeviceShaders.find(pInst->m_DeviceObjectID); - if (it != pCache->m_DeviceShaders.end()) - { - pHandle = it->second; - } - } - } - HRESULT hr = S_OK; - if (pHandle) - { - pInst->m_Handle.SetShader(pHandle); - pInst->m_Handle.AddRef(); - -#if D3DHWSHADERCOMPILING_CPP_TRAIT_VERTEX_FORMAT - if (m_eSHClass == eHWSC_Vertex) - { - ID3D10Blob* pS = NULL; - D3D10CreateBlob(nSize, (LPD3D10BLOB*)&pS); - DWORD* pBuffer = (DWORD*)pS->GetBufferPointer(); - memcpy(pBuffer, pBuf, nSize); - mfVertexFormat(pInst, this, pS); - SAFE_RELEASE(pS); - } -#endif - if ((m_eSHClass == eHWSC_Vertex) && (!(nFlags & HWSF_PRECACHE) || gRenDev->m_cEF.m_bActivatePhase) && !pInst->m_bFallback) - { - mfUpdateFXVertexFormat(pInst, pSH); - } - } - else - { - if (gcpRendD3D->m_cEF.m_nCombinationsProcess > 0 && !gcpRendD3D->m_cEF.m_bActivatePhase) - { - pInst->m_Handle.SetFake(); - } - else - { -#if D3DHWSHADERCOMPILING_CPP_TRAIT_VERTEX_FORMAT - if (m_eSHClass == eHWSC_Vertex) - { - ID3D10Blob* pS = NULL; - D3D10CreateBlob(nSize, (LPD3D10BLOB*)&pS); - DWORD* pBuffer = (DWORD*)pS->GetBufferPointer(); - memcpy(pBuffer, pBuf, nSize); - mfVertexFormat(pInst, this, pS); - SAFE_RELEASE(pS); - } -#endif - - bResult = mfUploadHW(pInst, pBuf, nSize, pSH, nFlags); - } - if (!bResult) - { - SAFE_DELETE(pInstBinds); - assert(!"Shader creation error"); - iLog->Log("WARNING: cannot create shader '%s' (FX: %s)", m_EntryFunc.c_str(), GetName()); - return true; - } - pCache->m_DeviceShaders.insert(FXDeviceShaderItor::value_type(pInst->m_DeviceObjectID, pInst->m_Handle.m_pShader)); - } - void* pConstantTable = NULL; - void* pShaderReflBuf = NULL; - hr = D3DReflect(pBuf, nSize, IID_ID3D11ShaderReflection, &pShaderReflBuf); - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*)pShaderReflBuf; - if (SUCCEEDED(hr)) - { - pConstantTable = (void*)pShaderReflection; - } - if (m_eSHClass == eHWSC_Vertex || gRenDev->IsEditorMode()) - { - pInst->m_pShaderData = new byte[nSize]; - pInst->m_nDataSize = nSize; - memcpy(pInst->m_pShaderData, pBuf, nSize); - pInst->m_uniqueNameCRC = AZ::Crc32(GetName()); - } - assert(hr == S_OK); - bResult &= (hr == S_OK); - if (pConstantTable) - { - mfCreateBinds(pInst, pConstantTable, pBuf, nSize); - } - - mfGatherFXParameters(pInst, pInstBinds, this, 0, pSH); - SAFE_DELETE(pInstBinds); - SAFE_RELEASE(pShaderReflection); - - return bResult; -} - -bool CHWShader_D3D::mfCreateCacheItem(SHWSInstance* pInst, std::vector& InstBinds, byte* pData, int nLen, CHWShader_D3D* pSH, bool bShaderThread) -{ - if (!pSH->m_pGlobalCache || !pSH->m_pGlobalCache->m_pRes[CACHE_USER]) - { - if (pSH->m_pGlobalCache) - { - pSH->m_pGlobalCache->Release(false); - } - pSH->m_pGlobalCache = mfInitCache(NULL, pSH, true, pSH->m_CRC32, false, false); - } - assert(pSH->m_pGlobalCache); - if (!pSH->m_pGlobalCache || !pSH->m_pGlobalCache->m_pRes[CACHE_USER]) - { - return false; - } - - byte* byteData = NULL; - DWORD* dwordData = NULL; - - SShaderCacheHeaderItem h; - h.m_nInstBinds = InstBinds.size(); - h.m_nInstructions = pInst->m_nInstructions; - h.m_nVertexFormat = pInst->m_vertexFormat.GetEnum(); - h.m_Class = pData ? pInst->m_eClass : 255; - h.m_StreamMask_Decl = pInst->m_VStreamMask_Decl; - h.m_StreamMask_Stream = (byte)pInst->m_VStreamMask_Stream; - int nNewSize = (h.m_nInstBinds) * sizeof(SShaderCacheHeaderItemVar) + nLen; - byte* pNewData = new byte [nNewSize]; - byte* pP = pNewData; - pP = mfBindsToCache(pInst, &InstBinds, h.m_nInstBinds, pP); - PREFAST_ASSUME(pData); - memcpy(pP, pData, nLen); - delete[] byteData; - delete[] dwordData; - pP += nLen; - char name[256]; - mfGenName(pInst, name, 256, 1); - CCryNameTSCRC nm = CCryNameTSCRC(name); - bool bRes = mfAddCacheItem(pSH->m_pGlobalCache, &h, pNewData, (int)(pP - pNewData), false, nm); - SAFE_DELETE_ARRAY(pNewData); - if (gRenDev->m_cEF.m_bActivatePhase || (!(pSH->m_Flags & HWSG_PRECACHEPHASE) && gRenDev->m_cEF.m_nCombinationsProcess <= 0)) - { - if (!gRenDev->m_cEF.m_bActivatePhase) - { - if (bShaderThread && false) - { - if (pInst->m_pAsync) - { - pInst->m_pAsync->m_bPendedFlush = true; - } - } - else - { - pSH->mfFlushCacheFile(); - } - } - azstrcpy(name, AZ_ARRAY_SIZE(name), pSH->GetName()); - char* s = strchr(name, '('); - if (s) - { - s[0] = 0; - } - if (!bShaderThread || true) - { - byte bStore = 1; - if (pSH->m_Flags & HWSG_FP_EMULATION) - { - bStore = 2; - } - SShaderCombIdent Ident = pInst->m_Ident; - ; - Ident.m_GLMask = pSH->m_nMaskGenFX; - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, name, 0, NULL, bStore); - } - } - pInst->m_nCache = CACHE_USER; - - return bRes; -} - -//============================================================================ - -void CHWShader_D3D::mfSaveCGFile(const char* scr, const char* path) -{ - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug < 1) - { - return; - } - char name[1024]; - if (path && path[0]) - { - sprintf_s(name, "%s/%s(LT%x)/(RT%llx)(MD%x)(MDV%x)(GL%llx)(PSS%llx)(ST%llx).cg", path, GetName(), m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask); - } - else - { - sprintf_s(name, "@usercache@/shaders/fxerror/%s(GL%llx)/(LT%x)(RT%llx)/(MD%x)(MDV%x)(PSS%llx)(ST%llx).cg", GetName(), m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask); - } - - AZ::IO::HandleType fileHandle; - - fileHandle = gEnv->pCryPak->FOpen(name, "w"); - if (fileHandle != AZ::IO::InvalidHandle) - { - size_t len = strlen(scr); - gEnv->pCryPak->FWrite(scr, len, fileHandle); - gEnv->pCryPak->FClose (fileHandle); - } -} - -void CHWShader_D3D::mfOutputCompilerError(string& strErr, const char* szSrc) -{ - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug) - { - AZ::IO::HandleType fileHandle = fxopen("$$err", "w"); - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::FPutS(szSrc, fileHandle); - gEnv->pFileIO->Close(fileHandle); - } - } - - string strE = strErr; - - size_t newlinePos = strE.find('\n'); - - while (newlinePos != string::npos) - { - iLog->LogError("%s", strE.substr(0, newlinePos).c_str()); - strE = strE.substr(newlinePos + 1); - newlinePos = strE.find('\n'); - } - - if (strE.size()) - { - iLog->LogError("%s", strE.c_str()); - } -} - -SShaderAsyncInfo::~SShaderAsyncInfo() -{ - { - AUTO_LOCK(g_cAILock); - Unlink(); - } - if (m_pFXShader) - { - assert(m_pFXShader->GetID() >= 0 && m_pFXShader->GetID() < MAX_REND_SHADERS); - } - SAFE_RELEASE(m_pFXShader); - SAFE_RELEASE(m_pShader); -} - -// Flush pended or processed shaders (main thread task) -void SShaderAsyncInfo::FlushPendingShaders() -{ - //assert (gRenDev->m_pRT->IsRenderThread()); - - if (!SShaderAsyncInfo::PendingList().m_Next) - { - SShaderAsyncInfo::PendingList().m_Next = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingList().m_Prev = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingListT().m_Next = &SShaderAsyncInfo::PendingListT(); - SShaderAsyncInfo::PendingListT().m_Prev = &SShaderAsyncInfo::PendingListT(); - } - - SShaderAsyncInfo* pAI, * pAINext; - { - AUTO_LOCK(g_cAILock); - for (pAI = PendingListT().m_Next; pAI != &PendingListT(); pAI = pAINext) - { - pAINext = pAI->m_Next; - pAI->Unlink(); - pAI->Link(&PendingList()); - } - } - - for (pAI = PendingList().m_Next; pAI != &PendingList(); pAI = pAINext) - { - pAINext = pAI->m_Next; - - CHWShader_D3D* pSH = pAI->m_pShader; - if (pSH) - { - CHWShader_D3D::SHWSInstance* pInst = pSH->mfGetInstance(pAI->m_pFXShader, pAI->m_nHashInst, pSH->m_nMaskGenShader); - if (pInst->m_pAsync != pAI) - { - CryFatalError("Shader instance async info doesn't match queued async info."); - } - pSH->mfAsyncCompileReady(pInst); - } - } -} -void CShader::mfFlushPendedShaders() -{ - SShaderAsyncInfo::FlushPendingShaders(); -} - -void CHWShader::mfFlushPendedShadersWait(int nMaxAllowed) -{ - if (nMaxAllowed > 0 && SShaderAsyncInfo::s_nPendingAsyncShaders < nMaxAllowed) - { - return; - } - if (CRenderer::CV_r_shadersasynccompiling > 0) - { - iLog->Log("Flushing pended shaders..."); -Start: - while (true) - { - if (SShaderAsyncInfo::s_nPendingAsyncShaders <= 0) - { - break; - } - int n = (int)iTimer->GetAsyncCurTime(); - if (!(n % 2)) - { - iLog->Update(); - } - if (!(n % 8)) - { - SShaderAsyncInfo::FlushPendingShaders(); - } - else - { - Sleep(1); - } - } - // Compile FXC shaders or next iteration of internal shaders - SShaderAsyncInfo::FlushPendingShaders(); - - if (SShaderAsyncInfo::s_nPendingAsyncShaders) - { - goto Start; - } - - iLog->Log("Finished flushing pended shaders..."); - } -} - -int CHWShader_D3D::mfAsyncCompileReady(SHWSInstance* pInst) -{ - //SHWSInstance *pInst = m_pCurInst; - //assert(pInst->m_pAsync); - if (!pInst->m_pAsync) - { - return 0; - } - - gRenDev->m_cEF.m_ShaderCacheStats.m_nNumShaderAsyncCompiles = SShaderAsyncInfo::s_nPendingAsyncShaders; - - SShaderAsyncInfo* pAsync = pInst->m_pAsync; - int nFrame = gRenDev->GetFrameID(false); - if (pAsync->m_nFrame == nFrame) - { - if (pAsync->m_fMinDistance > gRenDev->m_RP.m_fMinDistance) - { - pAsync->m_fMinDistance = gRenDev->m_RP.m_fMinDistance; - } - } - else - { - pAsync->m_fMinDistance = gRenDev->m_RP.m_fMinDistance; - pAsync->m_nFrame = nFrame; - } - - std::vector InstBindVars; - LPD3D10BLOB pShader = NULL; - void* pConstantTable = NULL; - LPD3D10BLOB pErrorMsgs = NULL; - string strErr; - char nmDst[256], nameSrc[256]; - bool bResult = true; - int nRefCount; - - SShaderTechnique* pTech = gRenDev->m_RP.m_pCurTechnique; - CShader* pSH = pAsync->m_pFXShader; - { - if (pAsync->m_bPending) - { - return 0; - } - - mfGetDstFileName(pInst, this, nmDst, 256, 3); - gEnv->pCryPak->AdjustFileName(nmDst, nameSrc, AZ_ARRAY_SIZE(nameSrc), 0); - if (pAsync->m_pFXShader && pAsync->m_pFXShader->m_HWTechniques.Num()) - { - pTech = pAsync->m_pFXShader->m_HWTechniques[0]; - } - if ((pAsync->m_pErrors && !pAsync->m_Errors.empty()) || !pAsync->m_pDevShader) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logShaders) - { - gcpRendD3D->LogShv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Async %d: **Failed to compile 0x%x '%s' shader\n", gRenDev->GetFrameID(false), pInst, nameSrc); - } - string Errors = pAsync->m_Errors; - string Text = pAsync->m_Text; - CShader* pFXShader = pAsync->m_pFXShader; - nRefCount = pFXShader ? pFXShader->GetRefCounter() : 0; - nRefCount = min(nRefCount, pAsync->m_pShader ? pAsync->m_pShader->GetRefCounter() : 0); - if (nRefCount <= 1) // Just exit if shader was deleted - { - pInst->m_pAsync = NULL; - SAFE_DELETE (pAsync); - return -1; - } - - mfOutputCompilerError(Errors, Text.c_str()); - - Warning("Couldn't compile HW shader '%s'", GetName()); - mfSaveCGFile(Text.c_str(), NULL); - - bResult = false; - } - else if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logShaders) - { - gcpRendD3D->LogShv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Async %d: Finished compiling 0x%x '%s' shader\n", gRenDev->GetFrameID(false), pInst, nameSrc); - } - pShader = pAsync->m_pDevShader; - pErrorMsgs = pAsync->m_pErrors; - pConstantTable = pAsync->m_pConstants; - strErr = pAsync->m_Errors; - InstBindVars = decltype(InstBindVars)(pAsync->m_InstBindVars.begin(), pAsync->m_InstBindVars.end()); - - if (pAsync->m_bPendedEnv) - { - bResult &= CHWShader_D3D::mfCreateShaderEnv(pAsync->m_nThread, pInst, pAsync->m_pDevShader, pAsync->m_pConstants, pAsync->m_pErrors, InstBindVars, this, false, pAsync->m_pFXShader, pAsync->m_nCombination); - assert(bResult == true); - } - - // Load samplers - if (pAsync->m_bPendedSamplers) - { - mfGatherFXParameters(pInst, &InstBindVars, this, 2, pAsync->m_pFXShader); - } - - if (pAsync->m_bPendedFlush) - { - mfFlushCacheFile(); - azstrcpy(nmDst, AZ_ARRAY_SIZE(nmDst), GetName()); - char* s = strchr(nmDst, '('); - if (s) - { - s[0] = 0; - } - SShaderCombIdent Ident = pInst->m_Ident; - Ident.m_GLMask = m_nMaskGenFX; - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, nmDst, 0); - } - - nRefCount = pAsync->m_pFXShader ? pAsync->m_pFXShader->GetRefCounter() : 0; - nRefCount = min(nRefCount, pAsync->m_pShader ? pAsync->m_pShader->GetRefCounter() : 0); - if (nRefCount <= 1) // Just exit if shader was deleted - { - pInst->m_pAsync = NULL; - SAFE_DELETE(pAsync); - return -1; - } - SAFE_DELETE (pInst->m_pAsync); - } - - if (pErrorMsgs && !strErr.empty()) - { - return -1; - } - - bResult &= mfUploadHW(pShader, pInst, pSH, 0); - SAFE_RELEASE(pShader); - - if (bResult) - { - if (pTech) - { - mfUpdatePreprocessFlags(pTech); - } - return 1; - } - return -1; -} - -bool CHWShader_D3D::mfRequestAsync(CShader* pSH, SHWSInstance* pInst, std::vector& InstBindVars, const char* prog_text, const char* szProfile, const char* szEntry) -{ -#ifdef SHADER_ASYNC_COMPILATION - char nameSrc[256], nmDst[256]; - mfGetDstFileName(pInst, this, nmDst, 256, 3); - gEnv->pCryPak->AdjustFileName(nmDst, nameSrc, AZ_ARRAY_SIZE(nameSrc), 0); - - if (!SShaderAsyncInfo::PendingList().m_Next) - { - SShaderAsyncInfo::PendingList().m_Next = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingList().m_Prev = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingListT().m_Next = &SShaderAsyncInfo::PendingListT(); - SShaderAsyncInfo::PendingListT().m_Prev = &SShaderAsyncInfo::PendingListT(); - } - - if (!m_pGlobalCache || !m_pGlobalCache->m_pRes[CACHE_USER]) - { - if (m_pGlobalCache) - { - m_pGlobalCache->Release(false); - } - m_pGlobalCache = mfInitCache(NULL, this, true, m_CRC32, false, false); - } - - pInst->m_pAsync = new SShaderAsyncInfo; - pInst->m_pAsync->m_fMinDistance = gRenDev->m_RP.m_fMinDistance; - pInst->m_pAsync->m_nFrame = gRenDev->GetFrameID(false); - pInst->m_pAsync->m_InstBindVars.assign(InstBindVars.data(), InstBindVars.data() + InstBindVars.size()); - pInst->m_pAsync->m_pShader = this; - pInst->m_pAsync->m_pShader->AddRef(); - pInst->m_pAsync->m_pFXShader = pSH; - pInst->m_pAsync->m_pFXShader->AddRef(); - pInst->m_pAsync->m_nCombination = gRenDev->m_cEF.m_nCombinationsProcess; - assert(!azstricmp(m_NameSourceFX.c_str(), pInst->m_pAsync->m_pFXShader->m_NameFile.c_str())); - if (m_bUseLookUpTable) - { - pInst->m_pAsync->m_nHashInst = pInst->m_nContIndex; - } - else - { - pInst->m_pAsync->m_nHashInst = pInst->m_Ident.m_nHash; - } - pInst->m_pAsync->m_RTMask = pInst->m_Ident.m_RTMask; - pInst->m_pAsync->m_LightMask = pInst->m_Ident.m_LightMask; - pInst->m_pAsync->m_MDMask = pInst->m_Ident.m_MDMask; - pInst->m_pAsync->m_MDVMask = pInst->m_Ident.m_MDVMask; - pInst->m_pAsync->m_pipelineState.opaque = pInst->m_Ident.m_pipelineState.opaque; - pInst->m_pAsync->m_eClass = pInst->m_eClass; - pInst->m_pAsync->m_Text = prog_text; - pInst->m_pAsync->m_Name = szEntry; - pInst->m_pAsync->m_Profile = szProfile; - - // Generate request line text to store on the shaderlist for next shader cache gen - { - char szShaderGenName[512]; - cry_strcpy(szShaderGenName, GetName()); - char* s = strchr(szShaderGenName, '('); - if (s) - { - s[0] = 0; - } - string RequestLine; - SShaderCombIdent Ident = pInst->m_Ident; - Ident.m_GLMask = m_nMaskGenFX; - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, szShaderGenName, 0, &RequestLine, false); - - pInst->m_pAsync->m_RequestLine = RequestLine; - } - - CAsyncShaderTask::InsertPendingShader(pInst->m_pAsync); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logShaders) - { - gcpRendD3D->LogShv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Async %d: Requested compiling 0x%x '%s' shader\n", gRenDev->GetFrameID(false), pInst, nameSrc); - } -#endif - return false; -} - - - -void CHWShader_D3D::mfSubmitRequestLine(SHWSInstance* pInst, string* pRequestLine) -{ - // Generate request line text. - char szShaderGenName[512]; - cry_strcpy(szShaderGenName, GetName()); - char* s = strchr(szShaderGenName, '('); - if (s) - { - s[0] = 0; - } - string RequestLine; - SShaderCombIdent Ident = pInst->m_Ident; - Ident.m_GLMask = m_nMaskGenFX; - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, szShaderGenName, 0, &RequestLine, false); - - if (pRequestLine) - { - *pRequestLine = RequestLine; - } - - if (!CRenderer::CV_r_shaderssubmitrequestline || !CRenderer::CV_r_shadersremotecompiler || pInst->m_bHasSendRequest) - { - return; - } - - // make sure we only send the request once - pInst->m_bHasSendRequest = true; - -#ifdef SHADER_ASYNC_COMPILATION - if (CRenderer::CV_r_shadersasynccompiling && !(m_Flags & HWSG_SYNC)) - { - if (!SShaderAsyncInfo::PendingList().m_Next) - { - SShaderAsyncInfo::PendingList().m_Next = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingList().m_Prev = &SShaderAsyncInfo::PendingList(); - SShaderAsyncInfo::PendingListT().m_Next = &SShaderAsyncInfo::PendingListT(); - SShaderAsyncInfo::PendingListT().m_Prev = &SShaderAsyncInfo::PendingListT(); - } - - SShaderAsyncInfo* pAsync = new SShaderAsyncInfo; - - if (pAsync) - { - pAsync->m_RequestLine = RequestLine; - pAsync->m_Text = ""; - pAsync->m_bDeleteAfterRequest = true; - - CAsyncShaderTask::InsertPendingShader(pAsync); - } - } - else -#endif - { - NRemoteCompiler::CShaderSrv::Instance().RequestLine(GetShaderListFilename().c_str(), RequestLine.c_str()); - } -} - -bool CHWShader_D3D::mfCompileHLSL_Int(CShader* pSH, char* prog_text, LPD3D10BLOB* ppShader, void** ppConstantTable, LPD3D10BLOB* ppErrorMsgs, string& strErr, std::vector& InstBindVars) -{ - HRESULT hr = S_OK; - SHWSInstance* pInst = m_pCurInst; - const char* szProfile = mfProfileString(pInst->m_eClass); - const char* pFunCCryName = m_EntryFunc.c_str(); - - bool bRes = true; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 2) - { - mfSaveCGFile(prog_text, "TestCG"); - } - if (CRenderer::CV_r_shadersasynccompiling && !(m_Flags & HWSG_SYNC)) - { - return mfRequestAsync(pSH, pInst, InstBindVars, prog_text, szProfile, pFunCCryName); - } - else - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersremotecompiler) - { - AZStd::string lsCompilerFlags = NRemoteCompiler::CShaderSrv::Instance().GetShaderCompilerFlags(pInst->m_eClass, pInst->m_Ident.m_pipelineState, pInst->m_Ident.m_MDVMask); - - string RequestLine; - mfSubmitRequestLine(pInst, &RequestLine); - - std::vector Data; - if (NRemoteCompiler::ESOK != NRemoteCompiler::CShaderSrv::Instance().Compile(Data, szProfile, prog_text, pFunCCryName, lsCompilerFlags.c_str(), RequestLine.c_str())) - { - string sErrorText; - sErrorText.reserve(Data.size()); - for (uint32 i = 0; i < Data.size(); i++) - { - sErrorText += Data[i]; - } - strErr = sErrorText; - - return false; - } - - D3D10CreateBlob(Data.size(), (LPD3D10BLOB*)ppShader); - LPD3D10BLOB pShader = (LPD3D10BLOB) * ppShader; - DWORD* pBuf = (DWORD*) pShader->GetBufferPointer(); - memcpy(pBuf, &Data[0], Data.size()); - - *ppShader = (LPD3D10BLOB)pShader; - pBuf = (DWORD*)pShader->GetBufferPointer(); - size_t nSize = pShader->GetBufferSize(); - - bool bReflect = true; - -#if !defined(CONSOLE) - if (CParserBin::PlatformIsConsole()) - { - bReflect = false; - } -#endif - - if (bReflect) - { - void* pShaderReflBuf; - hr = D3DReflect(pBuf, nSize, IID_ID3D11ShaderReflection, &pShaderReflBuf); - if (SUCCEEDED(hr)) - { - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*)pShaderReflBuf; - *ppConstantTable = (void*)pShaderReflection; - } - else - { - assert(0); - } - } - - return hr == S_OK; - } -#if defined(WIN32) || defined(WIN64) - else - { - static bool s_logOnce_WrongPlatform = false; -# if !defined(OPENGL) -# if !defined(_RELEASE) - if (!s_logOnce_WrongPlatform && !(CParserBin::m_nPlatform == SF_D3D11)) - { - s_logOnce_WrongPlatform = true; - iLog->LogError("Trying to build non DX11 shader via internal compiler which is not supported. Please use remote compiler instead!"); - } -# endif - uint32 nFlags = D3D10_SHADER_PACK_MATRIX_ROW_MAJOR | D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY; - if (CRenderer::CV_r_shadersdebug == 3) // Generate debug information and do not optimize shader for ease of debugging - { - nFlags |= D3D10_SHADER_DEBUG | D3D10_SHADER_SKIP_OPTIMIZATION; - } - else if(CRenderer::CV_r_shadersdebug == 4) // Generate debug information, but still optimize shader - { - nFlags |= D3D10_SHADER_DEBUG; - } - - hr = D3DCompile(prog_text, strlen(prog_text), GetName(), NULL, NULL, pFunCCryName, szProfile, nFlags, 0, (ID3DBlob**) ppShader, (ID3DBlob**) ppErrorMsgs); - if (FAILED(hr) || !*ppShader) - { - if (*ppErrorMsgs) - { - const char* err = (const char*)ppErrorMsgs[0]->GetBufferPointer(); - strErr += err; - } - else - { - strErr += "D3DXCompileShader failed"; - } - bRes = false; - } - else - { - void* pShaderReflBuf; - UINT* pData = (UINT*)ppShader[0]->GetBufferPointer(); - UINT nSize = (uint32)ppShader[0]->GetBufferSize(); - hr = D3DReflect(pData, nSize, IID_ID3D11ShaderReflection, &pShaderReflBuf); - if (SUCCEEDED(hr)) - { - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*)pShaderReflBuf; - *ppConstantTable = (void*)pShaderReflection; - } - else - { - assert(0); - } - } - return bRes; -# endif - } -#endif // #if defined(WIN32) || defined(WIN64) - - return false; -} - -LPD3D10BLOB CHWShader_D3D::mfCompileHLSL(CShader* pSH, char* prog_text, void** ppConstantTable, LPD3D10BLOB* ppErrorMsgs, [[maybe_unused]] uint32 nFlags, std::vector& InstBindVars) -{ - // LOADING_TIME_PROFILE_SECTION(iSystem); - - // Test adding source text to context - string strErr; - LPD3D10BLOB pCode = NULL; - if (!prog_text) - { - assert(0); - return NULL; - } - if (!CRenderer::CV_r_shadersAllowCompilation) - { - return NULL; - } - - mfCompileHLSL_Int(pSH, prog_text, &pCode, ppConstantTable, ppErrorMsgs, strErr, InstBindVars); - if (!pCode) - { - if (CRenderer::CV_r_shadersasynccompiling) - { - return NULL; - } - if (!pCode) - { - { - mfOutputCompilerError(strErr, prog_text); - - Warning("Couldn't compile HW shader '%s'", GetName()); - mfSaveCGFile(prog_text, NULL); - } - } - } - - return pCode; -} - -void CHWShader_D3D::mfPrepareShaderDebugInfo(SHWSInstance* pInst, CHWShader_D3D* pSH, const char* szAsm, std::vector& InstBindVars, void* pConstantTable) -{ - if (szAsm) - { - char* szInst = strstr((char*)szAsm, "pproximately "); - if (szInst) - { - pInst->m_nInstructions = atoi(&szInst[13]); - } - } - // Confetti Nicholas Baldwin: adding metal shader language support - if (CParserBin::m_nPlatform == SF_D3D11 || CParserBin::m_nPlatform == SF_JASPER || CParserBin::m_nPlatform == SF_GL4 || CParserBin::m_nPlatform == SF_GLES3 || CParserBin::m_nPlatform == SF_METAL) - { - ID3D11ShaderReflection* pShaderReflection = (ID3D11ShaderReflection*) pConstantTable; - - if (pShaderReflection) - { - D3D11_SHADER_DESC Desc; - pShaderReflection->GetDesc(&Desc); - - pInst->m_nInstructions = Desc.InstructionCount; - pInst->m_nTempRegs = Desc.TempRegisterCount; - } - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug) - { - char nmdst[256]; - mfGetDstFileName(pInst, pSH, nmdst, 256, 4); - - AZStd::string szName = AZStd::string::format("%s%s.fxca", gRenDev->m_cEF.m_szCachePath.c_str(), nmdst); - AZ::IO::HandleType statusdstFileHandle = gEnv->pCryPak->FOpen(szName.c_str(), "wb"); - - if (statusdstFileHandle != AZ::IO::InvalidHandle) - { - gEnv->pCryPak->FPrintf(statusdstFileHandle, "\n// %s %s\n\n", "%STARTSHADER", mfProfileString(pInst->m_eClass)); - if (pSH->m_eSHClass == eHWSC_Vertex) - { - for (uint32 i = 0; i < (uint32)InstBindVars.size(); i++) - { - SCGBind* pBind = &InstBindVars[i]; - gEnv->pCryPak->FPrintf(statusdstFileHandle, "// %s %s %d %d\n", "%%", pBind->m_Name.c_str(), pBind->m_RegisterCount, pBind->m_RegisterOffset); - } - } - gEnv->pCryPak->FPrintf(statusdstFileHandle, "%s", szAsm); - gEnv->pCryPak->FPrintf(statusdstFileHandle, "\n// %s\n", "%ENDSHADER"); - gEnv->pCryPak->FClose(statusdstFileHandle); - } - pInst->m_Handle.m_pShader = NULL; - } -} - -void CHWShader_D3D::mfPrintCompileInfo(SHWSInstance* pInst) -{ - int nConsts = 0; - int nParams = pInst->m_pBindVars.size(); - for (int i = 0; i < nParams; i++) - { - SCGBind* pB = &pInst->m_pBindVars[i]; - nConsts += pB->m_RegisterCount; - } - - char szGenName[512]; - cry_strcpy(szGenName, GetName()); - char* s = strchr(szGenName, '('); - if (s) - { - s[0] = 0; - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 2) - { - string pName; - SShaderCombIdent Ident(m_nMaskGenFX, pInst->m_Ident); - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, szGenName, 0, &pName, false); - CryLog(" Compile %s (%d instructions, %d tempregs, %d/%d constants) ... ", pName.c_str(), pInst->m_nInstructions, pInst->m_nTempRegs, nParams, nConsts); - int nSize = strlen(szGenName); - mfGenName(pInst, &szGenName[nSize], 512 - nSize, 1); - CryLog(" --- Cache entry: %s", szGenName); - } - else - { - int nSize = strlen(szGenName); - mfGenName(pInst, &szGenName[nSize], 512 - nSize, 1); - CryLog(" Compile %s (%d instructions, %d tempregs, %d/%d constants) ... ", szGenName, pInst->m_nInstructions, pInst->m_nTempRegs, nParams, nConsts); - } - - if (gRenDev->m_cEF.m_bActivated && CRenderer::CV_r_shadersdebug > 0) - { - CryLog(" Shader %s (%llx)(%x)(%x)(%x)(%llx)(%llx)(%s) wasn't compiled before preactivating phase", - GetName(), pInst->m_Ident.m_RTMask, pInst->m_Ident.m_LightMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask, mfProfileString(pInst->m_eClass)); - } -} - -bool CHWShader_D3D::mfCreateShaderEnv([[maybe_unused]] int nThread, SHWSInstance* pInst, LPD3D10BLOB pShader, void* pConstantTable, LPD3D10BLOB pErrorMsgs, std::vector& InstBindVars, CHWShader_D3D* pSH, bool bShaderThread, CShader* pFXShader, int nCombination, [[maybe_unused]] const char* src) -{ - // Create asm (.fxca) cache file - assert(pInst); - if (!pInst) - { - return false; - } - - CSpinLock lock; - - if (pInst->m_pBindVars.size()) - { - return true; - } - - if (pShader && (nCombination < 0)) - { -#if !defined(OPENGL) - ID3D10Blob* pAsm = NULL; - ID3D10Blob* pSrc = (ID3D10Blob*)pShader; - UINT* pBuf = (UINT*)pSrc->GetBufferPointer(); - D3DDisassemble(pBuf, pSrc->GetBufferSize(), 0, NULL, &pAsm); - if (pAsm) - { - char* szAsm = (char*)pAsm->GetBufferPointer(); - mfPrepareShaderDebugInfo(pInst, pSH, szAsm, InstBindVars, pConstantTable); - } - SAFE_RELEASE(pAsm); -#endif - } - //assert(!pInst->m_pBindVars); - - if (pShader) - { - bool bVF = pSH->m_eSHClass == eHWSC_Vertex; -#if !defined(CONSOLE) - if (CParserBin::PlatformIsConsole()) - { - bVF = false; - } -#endif -#if !defined(OPENGL) - if (CParserBin::m_nPlatform & (SF_GL4 | SF_GLES3)) - { - bVF = false; - } -#endif -#if defined(CRY_USE_METAL) - if (!(CParserBin::m_nPlatform & (SF_METAL))) - { - bVF = false; - } -#endif - if (bVF) - { - mfVertexFormat(pInst, pSH, pShader); - } - if (pConstantTable) - { - mfCreateBinds(pInst, pConstantTable, (byte*)pShader->GetBufferPointer(), (uint32)pShader->GetBufferSize()); - } - } - if (!(pSH->m_Flags & HWSG_PRECACHEPHASE)) - { - int nConsts = 0; - int nParams = pInst->m_pBindVars.size(); - for (int i = 0; i < nParams; i++) - { - SCGBind* pB = &pInst->m_pBindVars[i]; - nConsts += pB->m_RegisterCount; - } - if (gRenDev->m_cEF.m_nCombinationsProcess >= 0) - { - //assert(!bShaderThread); - - //if (!(gRenDev->m_cEF.m_nCombination & 0xff)) - if (!CParserBin::m_nPlatform) - { - CryLog("%d: Compile %s %s (%d out of %d) - (%d/%d constants) ... ", nThread, - mfProfileString(pInst->m_eClass), pSH->GetName(), nCombination, gRenDev->m_cEF.m_nCombinationsProcessOverall, - nParams, nConsts); - } - else - { - CryLog("%d: Compile %s %s (%d out of %d) ... ", nThread, - mfProfileString(pInst->m_eClass), pSH->GetName(), nCombination, gRenDev->m_cEF.m_nCombinationsProcessOverall); - } - } - else - { - pSH->mfPrintCompileInfo(pInst); - } - } - - mfGatherFXParameters(pInst, &InstBindVars, pSH, bShaderThread ? 1 : 0, pFXShader); - - if (pShader) - { - mfCreateCacheItem(pInst, InstBindVars, (byte*)pShader->GetBufferPointer(), (uint32)pShader->GetBufferSize(), pSH, bShaderThread); - } - else if (CRenderer::CV_r_shadersCacheUnavailableShaders) - { - // If the shader is unavailable, cache an invalid item to avoid requesting its compilation again in future executions - mfCreateCacheItem(pInst, InstBindVars, NULL, 0, pSH, bShaderThread); - } - -#if !defined (NULL_RENDERER) - ID3D11ShaderReflection* pRFL = (ID3D11ShaderReflection*)pConstantTable; - ID3D10Blob* pER = (ID3D10Blob*)pErrorMsgs; - SAFE_RELEASE(pRFL); - SAFE_RELEASE(pER); -#endif - - return true; -} - -// Compile pixel/vertex shader for the current instance properties -bool CHWShader_D3D::mfActivate(CShader* pSH, uint32 nFlags, FXShaderToken* Table, TArray* pSHData, bool bCompressedOnly) -{ - PROFILE_FRAME(Shader_HWShaderActivate); - AZ_TRACE_METHOD(); - - bool bResult = true; - SHWSInstance* pInst = m_pCurInst; - - mfLogShaderRequest(pInst); - - if (mfIsValid(pInst, true) == ED3DShError_NotCompiled) - { - //if (!(m_Flags & HWSG_PRECACHEPHASE) && !(nFlags & HWSF_NEXT)) - // mfSetHWStartProfile(nFlags); - - // We need a different source and desination for fpStripExtension - // since a call to strcpy with the same src and dst results in - // undefined behaviour - char nameCacheUnstripped[256]; - char nameCache[256]; - float t0 = gEnv->pTimer->GetAsyncCurTime(); - - mfGetDstFileName(pInst, this, nameCacheUnstripped, 256, 0); - fpStripExtension(nameCacheUnstripped, nameCache); - fpAddExtension(nameCache, ".fxcb"); - if (!m_pDevCache) - { - m_pDevCache = mfInitDevCache(nameCache, this); - } - - int32 nSize; - SShaderCacheHeaderItem* pCacheItem = mfGetCompressedItem(nFlags, nSize); - if (pCacheItem) - { - pInst->m_bCompressed = true; - } - else if (bCompressedOnly) - { - // don't activate if shader isn't found in compressed shader data - return false; - } - else - { - // if shader compiling is enabled, make sure the user folder shader caches are also available - bool bReadOnly = CRenderer::CV_r_shadersAllowCompilation == 0; - if (!m_pGlobalCache || m_pGlobalCache->m_nPlatform != CParserBin::m_nPlatform || - (!bReadOnly && !m_pGlobalCache->m_pRes[CACHE_USER])) - { - SAFE_RELEASE(m_pGlobalCache); - bool bAsync = CRenderer::CV_r_shadersasyncactivation != 0; - if (nFlags & HWSF_PRECACHE) - { - bAsync = false; - } - m_pGlobalCache = mfInitCache(nameCache, this, true, m_CRC32, bReadOnly, bAsync); - } - if (gRenDev->m_cEF.m_nCombinationsProcess >= 0 && !gRenDev->m_cEF.m_bActivatePhase) - { - mfGetDstFileName(pInst, this, nameCache, 256, 0); - fpStripExtension(nameCache, nameCache); - fpAddExtension(nameCache, ".fxcb"); - FXShaderCacheNamesItor it = m_ShaderCacheList.find(nameCache); - if (it == m_ShaderCacheList.end()) - { - m_ShaderCacheList.insert(FXShaderCacheNamesItor::value_type(nameCache, m_CRC32)); - } - } - pCacheItem = mfGetCacheItem(nFlags, nSize); - } - if (pCacheItem && pCacheItem->m_Class != 255) - { - if (Table && CRenderer::CV_r_shadersAllowCompilation) - { - mfGetCacheTokenMap(Table, pSHData, m_nMaskGenShader); - } - if (((m_Flags & HWSG_PRECACHEPHASE) || gRenDev->m_cEF.m_nCombinationsProcess >= 0) && !gRenDev->m_cEF.m_bActivatePhase) - { - byte* pData = (byte*)pCacheItem; - SAFE_DELETE_ARRAY(pData); - return true; - } - bool bRes = false; - bRes = mfActivateCacheItem(pSH, pCacheItem, nSize, nFlags); - byte* pData = (byte*)pCacheItem; - SAFE_DELETE_ARRAY(pData); - pCacheItem = NULL; - if (CRenderer::CV_r_shaderspreactivate == 2 && !gRenDev->m_cEF.m_bActivatePhase) - { - t0 = gEnv->pTimer->GetAsyncCurTime() - t0; - iLog->Log("Warning: Shader activation (%.3f ms): %s(%llx)(%x)(%x)(%x)(%llx)(%llx)(%s)...", - t0 * 1000.0f, GetName(), pInst->m_Ident.m_RTMask, pInst->m_Ident.m_LightMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, - pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask, mfProfileString(pInst->m_eClass)); - char name[256]; - azstrcpy(name, AZ_ARRAY_SIZE(name), GetName()); - char* s = strchr(name, '('); - if (s) - { - s[0] = 0; - } - string pName; - SShaderCombIdent Ident(m_nMaskGenFX, pInst->m_Ident); - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, name, 0, &pName, false); - iLog->Log("...Shader list entry: %s (%llx)", pName.c_str(), m_nMaskGenFX); - } - if (bRes) - { - return (pInst->m_Handle.m_pShader != NULL); - } - pCacheItem = NULL; - } - else - if (pCacheItem && pCacheItem->m_Class == 255) - { - byte* pData = (byte*)pCacheItem; - SAFE_DELETE_ARRAY(pData); - pCacheItem = NULL; - return false; - } - else - if (gRenDev->m_cEF.m_bActivatePhase) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug > 0) - { - iLog->Log("Warning: Shader %s(%llx)(%x)(%x)(%x)(%llx)(%llx)(%s) wasn't compiled before preactivating phase", - GetName(), pInst->m_Ident.m_RTMask, pInst->m_Ident.m_LightMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask, mfProfileString(pInst->m_eClass)); - } - byte* pData = (byte*)pCacheItem; - SAFE_DELETE_ARRAY(pData); - pCacheItem = NULL; - return false; - } - if (pCacheItem) - { - byte* pData = (byte*)pCacheItem; - SAFE_DELETE_ARRAY(pData); - pCacheItem = NULL; - } - //assert(!m_TokenData.empty()); - - TArray newScr; - - if (nFlags & HWSF_PRECACHE) - { - gRenDev->m_cEF.m_nCombinationsCompiled++; - } - - float fTime0 = iTimer->GetAsyncCurTime(); - LPD3D10BLOB pShader = NULL; - void* pConstantTable = NULL; - LPD3D10BLOB pErrorMsgs = NULL; - std::vector InstBindVars; - m_Flags |= HWSG_WASGENERATED; - - bool bScriptSuccess = false; - - if (CRenderer::CV_r_shadersAllowCompilation) - { - // MemReplay shows that 16kb should be enough memory to hold the script without having to reallocate - newScr.reserve(16 * 1024); - bScriptSuccess = mfGenerateScript(pSH, pInst, InstBindVars, nFlags, Table, pSHData, newScr); - ASSERT_IN_SHADER(bScriptSuccess); - } - - if (!pInst->m_bAsyncActivating && !bCompressedOnly) - { - // report miss in global cache to log and/or callback - mfLogShaderCacheMiss(pInst); - - // still sumit the request line when no compiling to be sure that the shadercompiler will - // compile it in the next build - if (!CRenderer::CV_r_shadersAllowCompilation) - { - mfSubmitRequestLine(pInst); - } - } - - if (!bScriptSuccess) - { - if (!pInst->m_bAsyncActivating) - { - Warning("Warning: Shader %s(%llx)(%x)(%x)(%x)(%llx)(%llx)(%s) is not existing in the cache\n", - GetName(), pInst->m_Ident.m_RTMask, pInst->m_Ident.m_LightMask, pInst->m_Ident.m_MDMask, pInst->m_Ident.m_MDVMask, pInst->m_Ident.m_pipelineState.opaque, pInst->m_Ident.m_STMask, mfProfileString(pInst->m_eClass)); - } - return false; - } - - { - PROFILE_FRAME(Shader_CompileHLSL); - pShader = mfCompileHLSL(pSH, newScr.Data(), &pConstantTable, &pErrorMsgs, nFlags, InstBindVars); - } - - gRenDev->m_cEF.m_ShaderCacheStats.m_nNumShaderAsyncCompiles = SShaderAsyncInfo::s_nPendingAsyncShaders; - - if (!pShader) - { - if (!CRenderer::CV_r_shadersAllowCompilation || pInst->IsAsyncCompiling()) - { - return false; - } - } - bResult = mfCreateShaderEnv(0, pInst, pShader, pConstantTable, pErrorMsgs, InstBindVars, this, false, pSH, gRenDev->m_cEF.m_nCombinationsProcess, newScr.Data()); - bResult &= mfUploadHW(pShader, pInst, pSH, nFlags); - SAFE_RELEASE(pShader); - - fTime0 = iTimer->GetAsyncCurTime() - fTime0; - //iLog->LogToConsole(" Time activate: %.3f", fTime0); - } - else - if (pSHData) - { - mfGetCacheTokenMap(Table, pSHData, m_nMaskGenShader); - } - - bool bSuccess = (mfIsValid(pInst, true) == ED3DShError_Ok); - - return bSuccess; -} - -////////////////////////////////////////////////////////////////////////// - -#ifdef SHADER_ASYNC_COMPILATION - -CAsyncShaderTask::CAsyncShaderTask() - : m_thread(this) -{ -} - -void CAsyncShaderTask::InsertPendingShader(SShaderAsyncInfo* pAsync) -{ - AUTO_LOCK(g_cAILock); - pAsync->Link(&BuildList()); - CryInterlockedIncrement(&SShaderAsyncInfo::s_nPendingAsyncShaders); -} - -void CAsyncShaderTask::FlushPendingShaders() -{ - SShaderAsyncInfo* pAI, * pAI2, * pAINext; - assert(m_flush_list.m_Prev == &m_flush_list && m_flush_list.m_Next == &m_flush_list); // the flush list must be empty - cleared by the shader compile thread - if (BuildList().m_Prev == &BuildList() && BuildList().m_Next == &BuildList()) - { - return; // the build list is empty, might need to do some assert here - } - { - AUTO_LOCK(g_cAILock); - for (pAI = BuildList().m_Prev; pAI != &BuildList(); pAI = pAINext) - { - pAINext = pAI->m_Prev; - pAI->Unlink(); - pAI->Link(&m_flush_list); - } - } - - // Sorting by distance - if (gRenDev->m_cEF.m_nCombinationsProcess < 0) - { - for (pAI = m_flush_list.m_Next; pAI != &m_flush_list; pAI = pAI->m_Next) - { - assert(pAI); - PREFAST_ASSUME(pAI); - pAINext = NULL; - int nFrame = pAI->m_nFrame; - float fDist = pAI->m_fMinDistance; - for (pAI2 = pAI->m_Next; pAI2 != &m_flush_list; pAI2 = pAI2->m_Next) - { - if (pAI2->m_nFrame < nFrame) - { - continue; - } - if (pAI2->m_nFrame > nFrame || pAI2->m_fMinDistance < fDist) - { - pAINext = pAI2; - nFrame = pAI2->m_nFrame; - fDist = pAI2->m_fMinDistance; - } - } - if (pAINext) - { - assert(pAI != pAINext); - SShaderAsyncInfo* pAIP0 = pAI->m_Prev; - SShaderAsyncInfo* pAIP1 = pAINext->m_Prev == pAI ? pAINext : pAINext->m_Prev; - - pAI->m_Next->m_Prev = pAI->m_Prev; - pAI->m_Prev->m_Next = pAI->m_Next; - pAI->m_Next = pAIP1->m_Next; - pAIP1->m_Next->m_Prev = pAI; - pAIP1->m_Next = pAI; - pAI->m_Prev = pAIP1; - - pAI = pAINext; - - pAI->m_Next->m_Prev = pAI->m_Prev; - pAI->m_Prev->m_Next = pAI->m_Next; - pAI->m_Next = pAIP0->m_Next; - pAIP0->m_Next->m_Prev = pAI; - pAIP0->m_Next = pAI; - pAI->m_Prev = pAIP0; - } - } - } - - for (pAI = m_flush_list.m_Next; pAI != &m_flush_list; pAI = pAINext) - { - pAINext = pAI->m_Next; - assert(pAI->m_bPending); - SubmitAsyncRequestLine(pAI); - if (pAI->m_Text.length() > 0) - { - CompileAsyncShader(pAI); - } - - CryInterlockedDecrement(&SShaderAsyncInfo::s_nPendingAsyncShaders); - { - AUTO_LOCK(g_cAILock); - - pAI->Unlink(); - pAI->m_bPending = 0; - pAI->Link(&SShaderAsyncInfo::PendingListT()); - } - - if (pAI->m_bDeleteAfterRequest) - { - SAFE_DELETE(pAI); - } - } -} - -bool CAsyncShaderTask::PostCompile(SShaderAsyncInfo* pAsync) -{ - bool bResult = true; - /*if (pAsync->m_nCombination < 0 && false) - { - CHWShader_D3D *pSH = pAsync->m_pShader; - CHWShader_D3D::SHWSInstance *pInst = pSH->mfGetInstance(pAsync->m_nOwner, pSH->m_nMaskGenShader); - bResult = CHWShader_D3D::mfCreateShaderEnv(m_nThread, pInst, pAsync->m_pDevShader, pAsync->m_pConstants, pAsync->m_pErrors, pAsync->m_InstBindVars, pSH, true, pAsync->m_pFXShader, pAsync->m_nCombination); - assert(bResult == true); - } - else*/ - { - pAsync->m_nThread = m_nThread; - pAsync->m_bPendedEnv = true; - } - return bResult; -} - -void CAsyncShaderTask::SubmitAsyncRequestLine(SShaderAsyncInfo* pAsync) -{ - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersremotecompiler) - { - if (!pAsync->m_shaderList.empty()) - { - NRemoteCompiler::CShaderSrv::Instance().RequestLine(pAsync->m_shaderList.c_str(), pAsync->m_RequestLine.c_str()); - } - else - { - NRemoteCompiler::CShaderSrv::Instance().RequestLine(GetShaderListFilename().c_str(), pAsync->m_RequestLine.c_str()); - } - } -} - -bool CAsyncShaderTask::CompileAsyncShader(SShaderAsyncInfo* pAsync) -{ -#if !(defined(MOBILE) || defined(CONSOLE)) - const bool outputShaderSourceFiles = CRenderer::CV_r_OutputShaderSourceFiles != 0; -#else - const bool outputShaderSourceFiles = false; -#endif - string shaderSourceOutputFolder; - - if ( outputShaderSourceFiles ) - { - CryFixedStringT<1024> hlslPath; - - // Create a directory for this shader type, strip the .fxcb extension from the folder name - shaderSourceOutputFolder.Format("@usercache@/%s",pAsync->m_pShader->m_pDevCache->m_Name.c_str()); - PathUtil::RemoveExtension(shaderSourceOutputFolder); - gEnv->pFileIO->CreatePath(shaderSourceOutputFolder); - - // Output both HLSL here, and GLSL/Metal below since those require the remote shader compiler to execute first - hlslPath.Format("%s/[0x%08x].hlsl",shaderSourceOutputFolder.c_str(),pAsync->m_nHashInst); - { - AZ::IO::HandleType hlslHandle; - - if ( gEnv->pFileIO->Open(hlslPath.c_str(),AZ::IO::OpenMode::ModeWrite,hlslHandle) ) - { - gEnv->pFileIO->Write(hlslHandle, pAsync->m_Text.c_str(), pAsync->m_Text.size()); - gEnv->pFileIO->Flush(hlslHandle); - gEnv->pFileIO->Close(hlslHandle); - } - } - } - - bool bResult = true; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersremotecompiler) - { - AZStd::string lsCompilerFlags = NRemoteCompiler::CShaderSrv::Instance().GetShaderCompilerFlags(pAsync->m_eClass, pAsync->m_pipelineState, pAsync->m_MDVMask); - - std::vector Data; - if (NRemoteCompiler::ESOK != NRemoteCompiler::CShaderSrv::Instance().Compile(Data, pAsync->m_Profile, pAsync->m_Text.c_str(), pAsync->m_Name.c_str(), lsCompilerFlags.c_str(), pAsync->m_RequestLine.c_str())) - { -#if !defined(NULL_RENDERER) - D3D10CreateBlob(sizeof("D3DXCompileShader failed"), (LPD3D10BLOB*)&pAsync->m_pErrors); - DWORD* pBuf = (DWORD*) pAsync->m_pErrors->GetBufferPointer(); - memcpy(pBuf, "D3DXCompileShader failed", sizeof("D3DXCompileShader failed")); -#endif - string sErrorText; - - if (!Data.empty()) - { - sErrorText.reserve(Data.size()); - for (uint32 i = 0; i < Data.size(); i++) - { - sErrorText += Data[i]; - } - } - else - { - sErrorText.assign("Unknown Error"); - } - - pAsync->m_Errors += sErrorText; - - return false; - } - - HRESULT hr = S_OK; - D3D10CreateBlob(Data.size(), (LPD3D10BLOB*) & pAsync->m_pDevShader); - LPD3D10BLOB pShader = (LPD3D10BLOB)*&pAsync->m_pDevShader; - DWORD* pBuf = (DWORD*)pShader->GetBufferPointer(); - memcpy(pBuf, &Data[0], Data.size()); - - pAsync->m_pDevShader = (LPD3D10BLOB)pShader; - pBuf = (DWORD*)pShader->GetBufferPointer(); - size_t nSize = pShader->GetBufferSize(); - - if ( outputShaderSourceFiles ) - { -#if defined(OPENGL) - CryFixedStringT<1024> glslPath; - glslPath.Format("%s/[0x%08x].glsl",shaderSourceOutputFolder.c_str(),pAsync->m_nHashInst); - { - AZ::IO::HandleType glslHandle; - if ( gEnv->pFileIO->Open(glslPath.c_str(),AZ::IO::OpenMode::ModeWrite,glslHandle) ) - { - gEnv->pFileIO->Write(glslHandle,static_cast(pBuf),nSize); - gEnv->pFileIO->Flush(glslHandle); - gEnv->pFileIO->Close(glslHandle); - } - } -#endif - -#if defined(CRY_USE_METAL) - CryFixedStringT<1024> metallibPath; - metallibPath.Format("%s/[0x%08x].metallib",shaderSourceOutputFolder.c_str(),pAsync->m_nHashInst); - { - AZ::IO::HandleType metalHandle; - if ( gEnv->pFileIO->Open(metallibPath.c_str(),AZ::IO::OpenMode::ModeWrite,metalHandle) ) - { - gEnv->pFileIO->Write(metalHandle,static_cast(pBuf),nSize); - gEnv->pFileIO->Flush(metalHandle); - gEnv->pFileIO->Close(metalHandle); - } - } -#endif - } - - bool bReflect = true; - -#if !defined(CONSOLE) - if (CParserBin::PlatformIsConsole()) - { - bReflect = false; - } -#endif -#if !defined(OPENGL) - if (CParserBin::m_nPlatform & (SF_GL4 | SF_GLES3)) - { - bReflect = false; - } -#endif -#if defined(CRY_USE_METAL) - if (!(CParserBin::m_nPlatform & (SF_METAL))) - { - bReflect = false; - } -#endif - - if (bReflect) - { - ID3D11ShaderReflection* pShaderReflection; - hr = D3DReflect(pBuf, nSize, IID_ID3D11ShaderReflection, (void**)&pShaderReflection); - if (SUCCEEDED(hr)) - { - pAsync->m_pConstants = (void*)pShaderReflection; - } - } - - if (SUCCEEDED(hr)) - { - bResult = PostCompile(pAsync); - } - else - { - pAsync->m_pDevShader = 0; - assert(0); - } - } -#if defined(WIN32) && !defined(OPENGL) - else - { - static bool s_logOnce_WrongPlatform = false; -# if !defined(_RELEASE) - if (!s_logOnce_WrongPlatform && !(CParserBin::m_nPlatform == SF_D3D11)) - { - s_logOnce_WrongPlatform = true; - iLog->LogError("Trying to build non DX11 shader via internal compiler which is not supported. Please use remote compiler instead!"); - } -# endif - uint32 nFlags = D3D10_SHADER_PACK_MATRIX_ROW_MAJOR | D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY; - if (CRenderer::CV_r_shadersdebug == 3) // Generate debug information and do not optimize shader for ease of debugging - { - nFlags |= D3D10_SHADER_DEBUG | D3D10_SHADER_SKIP_OPTIMIZATION; - } - else if(CRenderer::CV_r_shadersdebug == 4) // Generate debug information, but still optimize shader - { - nFlags |= D3D10_SHADER_DEBUG; - } - - const char* Name = pAsync->m_pShader ? pAsync->m_pShader->GetName() : "Unknown"; - HRESULT hr = S_OK; - hr = D3DCompile(pAsync->m_Text.c_str(), pAsync->m_Text.size(), Name, NULL, NULL, pAsync->m_Name.c_str(), pAsync->m_Profile.c_str(), nFlags, 0, (ID3DBlob * *) & pAsync->m_pDevShader, (ID3DBlob**) &pAsync->m_pErrors); - if (FAILED(hr) || !pAsync->m_pDevShader) - { - if (pAsync->m_pErrors) - { - const char* err = (const char*)pAsync->m_pErrors->GetBufferPointer(); - pAsync->m_Errors += err; - } - else - { - pAsync->m_Errors += "D3DXCompileShader failed"; - } - bResult = false; - } - else - { - ID3D11ShaderReflection* pShaderReflection; - UINT* pData = (UINT*)pAsync->m_pDevShader->GetBufferPointer(); - size_t nSize = pAsync->m_pDevShader->GetBufferSize(); - hr = D3DReflect(pData, nSize, IID_ID3D11ShaderReflection, (void**)&pShaderReflection); - if (SUCCEEDED(hr)) - { - pAsync->m_pConstants = (void*)pShaderReflection; - bResult = PostCompile(pAsync); - } - else - { - iLog->LogWarning("ERROR: Shader Reflection Failed!"); - assert(0); - } - } - } -#endif // #if defined(WIN32) || defined(WIN64) - return bResult; -} - -void CAsyncShaderTask::CShaderThread::Run() -{ - CryThreadSetName(-1, SHADER_THREAD_NAME); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DHWSHADERCOMPILING_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(D3DHWShaderCompiling_cpp) -#endif - - while (!m_quit) - { - m_task->FlushPendingShaders(); - if (!CRenderer::CV_r_shadersasynccompiling) - { - Sleep(250); - } - else - { - Sleep(25); - } - } -} - -#endif - -//=============================================================================================== -// Export/Import - -#ifdef SHADERS_SERIALIZING - -bool STexSamplerFX::Export(SShaderSerializeContext& SC) -{ - bool bRes = true; - - SSTexSamplerFX TS; - TS.m_nRTIdx = -1; - TS.m_nsName = SC.AddString(m_szName.c_str()); - - TS.m_nsNameTexture = SC.AddString(m_szTexture.c_str()); - - TS.m_eTexType = m_eTexType; - TS.m_nSamplerSlot = m_nSlotId; - TS.m_nTexFlags = m_nTexFlags; - if (m_nTexState > 0) - { - TS.m_bTexState = 1; - memcpy(&TS.ST, &CTexture::s_TexStates[m_nTexState], sizeof(TS.ST)); - TS.ST.m_pDeviceState = NULL; - } - - if (m_pTarget) - { - TS.m_nRTIdx = SC.FXTexRTs.Num(); - - SHRenderTarget* pRT = m_pTarget; - SSHRenderTarget RT; - RT.m_eOrder = pRT->m_eOrder; - RT.m_nProcessFlags = pRT->m_nProcessFlags; - - RT.m_nsTargetName = SC.AddString(pRT->m_TargetName.c_str()); - - RT.m_nWidth = pRT->m_nWidth; - RT.m_nHeight = pRT->m_nHeight; - RT.m_eTF = pRT->m_eTF; - RT.m_nIDInPool = pRT->m_nIDInPool; - RT.m_eUpdateType = pRT->m_eUpdateType; - RT.m_bTempDepth = pRT->m_bTempDepth; - RT.m_ClearColor = pRT->m_ClearColor; - RT.m_fClearDepth = pRT->m_fClearDepth; - RT.m_nFlags = pRT->m_nFlags; - RT.m_nFilterFlags = pRT->m_nFilterFlags; - SC.FXTexRTs.push_back(RT); - } - - //crude workaround for TArray push_back() bug a=b operator. Does not init a, breaks texState dtor for a - SSTexSamplerFX* pNewSampler = SC.FXTexSamplers.AddIndex(1); - memcpy(pNewSampler, &TS, sizeof(SSTexSamplerFX)); - - return bRes; -} -bool STexSamplerFX::Import(SShaderSerializeContext& SC, SSTexSamplerFX* pTS) -{ - bool bRes = true; - - m_szName = sString(pTS->m_nsName, SC.Strings); - m_szTexture = sString(pTS->m_nsNameTexture, SC.Strings); - - m_eTexType = pTS->m_eTexType; - m_nSlotId = pTS->m_nSamplerSlot; - m_nTexFlags = pTS->m_nTexFlags; - if (pTS->m_bTexState) - { - m_nTexState = CTexture::GetTexState(pTS->ST); - } - - if (pTS->m_nRTIdx != -1) - { - SSHRenderTarget* pRT = &SC.FXTexRTs[pTS->m_nRTIdx]; - - SHRenderTarget* pDst = new SHRenderTarget; - - pDst->m_eOrder = pRT->m_eOrder; - pDst->m_nProcessFlags = pRT->m_nProcessFlags; - pDst->m_TargetName = sString(pRT->m_nsTargetName, SC.Strings); - pDst->m_nWidth = pRT->m_nWidth; - pDst->m_nHeight = pRT->m_nHeight; - pDst->m_eTF = pRT->m_eTF; - pDst->m_nIDInPool = pRT->m_nIDInPool; - pDst->m_eUpdateType = pRT->m_eUpdateType; - pDst->m_bTempDepth = pRT->m_bTempDepth != 0; - pDst->m_ClearColor = pRT->m_ClearColor; - pDst->m_fClearDepth = pRT->m_fClearDepth; - pDst->m_nFlags = pRT->m_nFlags; - pDst->m_nFilterFlags = pRT->m_nFilterFlags; - m_pTarget = pDst; - } - - PostLoad(); - - return bRes; -} - -bool SFXParam::Export(SShaderSerializeContext& SC) -{ - bool bRes = true; - - SSFXParam PR; - PR.m_nsName = SC.AddString(m_Name.c_str()); - PR.m_nsAnnotations = SC.AddString(m_Annotations.c_str()); - PR.m_nsSemantic = SC.AddString(m_Semantic.c_str()); - PR.m_nsValues = SC.AddString(m_Values.c_str()); - - PR.m_eType = m_eType; - PR.m_nCB = m_BindingSlot; - PR.m_nComps = m_ComponentCount; - PR.m_nFlags = m_nFlags; - PR.m_nParameters = m_RegisterCount; - for ( int i=0; im_nsName, SC.Strings); - m_Annotations = sString(pPR->m_nsAnnotations, SC.Strings); - m_Semantic = sString(pPR->m_nsSemantic, SC.Strings); - m_Values = sString(pPR->m_nsValues, SC.Strings); - - m_eType = pPR->m_eType; - m_BindingSlot = pPR->m_nCB; - m_ComponentCount = pPR->m_nComps; - m_nFlags = pPR->m_nFlags; - m_RegisterCount = pPR->m_nParameters; - for ( int i=0; im_nRegister[i]; - } - - return bRes; -} - -bool SFXSampler::Export(SShaderSerializeContext& SC) -{ - bool bRes = true; - - SSFXSampler PR; - PR.m_nsName = SC.AddString(m_Name.c_str()); - PR.m_nsAnnotations = SC.AddString(m_Annotations.c_str()); - PR.m_nsSemantic = SC.AddString(m_Semantic.c_str()); - PR.m_nsValues = SC.AddString(m_Values.c_str()); - - PR.m_eType = m_eType; - PR.m_nArray = m_nArray; - PR.m_nFlags = m_nFlags; - for ( int i=0; im_nsName, SC.Strings); - m_Annotations = sString(pPR->m_nsAnnotations, SC.Strings); - m_Semantic = sString(pPR->m_nsSemantic, SC.Strings); - m_Values = sString(pPR->m_nsValues, SC.Strings); - - m_eType = pPR->m_eType; - m_nArray = pPR->m_nArray; - m_nFlags = pPR->m_nFlags; - for ( int i=0; im_nRegister[i]; - } - - return bRes; -} - -bool SFXTexture::Export(SShaderSerializeContext& SC) -{ - bool bRes = true; - - SSFXTexture PR; - PR.m_nsName = SC.AddString(m_Name.c_str()); - PR.m_nsAnnotations = SC.AddString(m_Annotations.c_str()); - PR.m_nsSemantic = SC.AddString(m_Semantic.c_str()); - PR.m_nsValues = SC.AddString(m_Values.c_str()); - - PR.m_nsNameTexture = SC.AddString(m_szTexture.c_str()); - PR.m_bSRGBLookup = m_bSRGBLookup; - PR.m_eType = m_eType; - PR.m_nArray = m_nArray; - PR.m_nFlags = m_nFlags; - for ( int i=0; im_nsName, SC.Strings); - m_Annotations = sString(pPR->m_nsAnnotations, SC.Strings); - m_Semantic = sString(pPR->m_nsSemantic, SC.Strings); - m_Values = sString(pPR->m_nsValues, SC.Strings); - - m_szTexture = sString(pPR->m_nsNameTexture, SC.Strings); - m_bSRGBLookup = pPR->m_bSRGBLookup; - m_eType = pPR->m_eType; - m_nArray = pPR->m_nArray; - m_nFlags = pPR->m_nFlags; - for ( int i=0; im_nRegister[i]; - } - - return bRes; -} - -bool CHWShader_D3D::ExportSamplers([[maybe_unused]] SCHWShader& SHW, [[maybe_unused]] SShaderSerializeContext& SC) -{ - bool bRes = true; - return bRes; -} -bool CHWShader::ImportSamplers([[maybe_unused]] SShaderSerializeContext& SC, [[maybe_unused]] SCHWShader* pSHW, [[maybe_unused]] byte*& pData, [[maybe_unused]] std::vector& Samplers) -{ - bool bRes = true; - return bRes; -} - -bool CHWShader_D3D::ExportParams(SCHWShader& SHW, [[maybe_unused]] SShaderSerializeContext& SC) -{ - bool bRes = true; - SHW.m_nParams = 0; - return bRes; -} -bool CHWShader::ImportParams([[maybe_unused]] SShaderSerializeContext& SC, [[maybe_unused]] SCHWShader* pSHW, [[maybe_unused]] byte*& pData, [[maybe_unused]] std::vector& Params) -{ - bool bRes = true; - return bRes; -} - -bool CHWShader_D3D::Export(SShaderSerializeContext& SC) -{ - bool bRes = true; - - SCHWShader SHW; - - char str[256]; - azstrcpy(str, AZ_ARRAY_SIZE(str), GetName()); - char* c = strchr(str, '('); - if (c) - { - c[0] = 0; - } - - SHW.m_nsName = SC.AddString(str); - SHW.m_nsNameSourceFX = SC.AddString(m_NameSourceFX.c_str()); - SHW.m_nsEntryFunc = SC.AddString(m_EntryFunc.c_str()); - - SHW.m_eSHClass = m_eSHClass; - SHW.m_dwShaderType = m_dwShaderType; - SHW.m_nMaskGenFX = m_nMaskGenFX; - SHW.m_nMaskGenShader = m_nMaskGenShader; - SHW.m_nMaskOr_RT = m_nMaskOr_RT; - SHW.m_nMaskAnd_RT = m_nMaskAnd_RT; - SHW.m_Flags = m_Flags; - - FXShaderToken* pMap = NULL; - TArray* pData = &m_TokenData; - bool bDeleteTokenData = false; - - SHW.m_nTokens = 0; - SHW.m_nTableEntries = 0; - - SCHWShader SHWTemp = SHW; - - SHW.Export(SC.Data); - - bRes &= ExportSamplers(SHW, SC); - bRes &= ExportParams(SHW, SC); - - if (bRes) - { - if (memcmp(&SHW, &SHWTemp, sizeof(SCHWShader))) - { - CryFatalError("Export failed"); - } - } - - if (bDeleteTokenData) - { - SAFE_DELETE(pData); - SAFE_DELETE(pMap); - } - - return bRes; -} - -CHWShader* CHWShader::Import(SShaderSerializeContext& SC, int nOffs, uint32 CRC32, CShader* pSH) -{ - if (nOffs < 0) - { - return NULL; - } - - CHWShader* pHWSH = NULL; - SCHWShader shaderHW; - shaderHW.Import(&SC.Data[nOffs]); - SCHWShader* pSHW = &shaderHW; - - const char* szName = sString(pSHW->m_nsName, SC.Strings); - const char* szNameSource = sString(pSHW->m_nsNameSourceFX, SC.Strings); - const char* szNameEntry = sString(pSHW->m_nsEntryFunc, SC.Strings); - - TArray SHData; - SHData.resize(pSHW->m_nTokens); - - FXShaderToken Table, * pTable = NULL; - Table.reserve(pSHW->m_nTableEntries); - - nOffs = 0; - - //Copy string pool, TODO separate string pool for tokens! - //TArray tokenStringPool = SC.Strings; - - // Token data is no longer in export data - See CHWShader_D3D::Export where bOutputTokens == false and disables this path - if (0) //CRenderer::CV_r_shadersAllowCompilation) - { - byte* pData = &SC.Data[nOffs + sizeof(SCHWShader)]; - - memcpy(&SHData[0], pData, pSHW->m_nTokens * sizeof(uint32)); - pData += pSHW->m_nTokens * sizeof(uint32); - - pTable = &Table; - for (uint32 i = 0; i < pSHW->m_nTableEntries; i++) - { - // string pool method - DWORD nToken = *(DWORD*)&pData[nOffs]; - nOffs += sizeof(DWORD); - uint32 nTokenStrIdx = *(DWORD*)&pData[nOffs]; - nOffs += sizeof(uint32); - - if (CParserBin::m_bEndians) - { - SwapEndian(nToken, eBigEndian); - SwapEndian(nTokenStrIdx, eBigEndian); - } - - STokenD TD; - TD.SToken = sString(nTokenStrIdx, SC.Strings); - - TD.Token = nToken; - - Table.push_back(TD); - } - pData += nOffs; - - std::vector Samplers; - ImportSamplers(SC, pSHW, pData, Samplers); - - std::vector Params; - ImportParams(SC, pSHW, pData, Params); - } - - - //static CHWShader *mfForName(const char *name, const char *nameSource, uint32 CRC32, const char *szEntryFunc, EHWShaderClass eClass, TArray& SHData, FXShaderToken *pTable, uint32 dwType, CShader *pFX, uint64 nMaskGen=0, uint64 nMaskGenFX=0); - pHWSH = CHWShader::mfForName(szName, szNameSource, CRC32, szNameEntry, pSHW->m_eSHClass, SHData, pTable, pSHW->m_dwShaderType, pSH, pSHW->m_nMaskGenShader, pSHW->m_nMaskGenFX); - - pHWSH->m_eSHClass = shaderHW.m_eSHClass; - pHWSH->m_dwShaderType = shaderHW.m_dwShaderType; - pHWSH->m_nMaskGenFX = shaderHW.m_nMaskGenFX; - pHWSH->m_nMaskGenShader = shaderHW.m_nMaskGenShader; - pHWSH->m_nMaskOr_RT = shaderHW.m_nMaskOr_RT; - pHWSH->m_nMaskAnd_RT = shaderHW.m_nMaskAnd_RT; - pHWSH->m_Flags = shaderHW.m_Flags; - - return pHWSH; -} - -#else -bool CHWShader_D3D::Export(SShaderSerializeContext& SC) -{ - return false; -} -#endif - -const char* CHWShader_D3D::mfGetActivatedCombinations([[maybe_unused]] bool bForLevel) -{ - TArray Combinations; - char* pPtr = NULL; - uint32 i; - - for (i = 0; i < m_Insts.size(); i++) - { - SHWSInstance* pInst = m_Insts[i]; - char name[256]; - azstrcpy(name, AZ_ARRAY_SIZE(name), GetName()); - char* s = strchr(name, '('); - if (s) - { - s[0] = 0; - } - string str; - SShaderCombIdent Ident(m_nMaskGenFX, pInst->m_Ident); - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, name, 0, &str, false); - assert (str.size()); - if (str.size()) - { - assert(str[0] == '<' && str[2] == '>'); - string s1; - if (str[0] == '<' && str[2] == '>') - { - s1.Format("<%d>%s", pInst->m_nUsed, &str[3]); - } - else - { - s1 = str; - } - Combinations.Copy(s1.c_str(), s1.size()); - Combinations.Copy("\n", 1); - } - } - - if (!Combinations.Num()) - { - return NULL; - } - pPtr = new char [Combinations.Num() + 1]; - memcpy(pPtr, &Combinations[0], Combinations.Num()); - pPtr[Combinations.Num()] = 0; - return pPtr; -} - -const char* CHWShader::GetCurrentShaderCombinations(bool bForLevel) -{ - TArray Combinations; - char* pPtr = NULL; - CCryNameTSCRC Name; - SResourceContainer* pRL; - - Name = CHWShader::mfGetClassName(eHWSC_Vertex); - pRL = CBaseResource::GetResourcesForClass(Name); - int nVS = 0; - int nPS = 0; - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CHWShader* vs = (CHWShader*)itor->second; - if (!vs) - { - continue; - } - const char* szCombs = vs->mfGetActivatedCombinations(bForLevel); - if (!szCombs) - { - continue; - } - Combinations.Copy(szCombs, strlen(szCombs)); - delete [] szCombs; - nVS++; - } - } - - Name = CHWShader::mfGetClassName(eHWSC_Pixel); - pRL = CBaseResource::GetResourcesForClass(Name); - if (pRL) - { - ResourcesMapItor itor; - for (itor = pRL->m_RMap.begin(); itor != pRL->m_RMap.end(); itor++) - { - CHWShader* ps = (CHWShader*)itor->second; - if (!ps) - { - continue; - } - const char* szCombs = ps->mfGetActivatedCombinations(bForLevel); - if (!szCombs) - { - continue; - } - Combinations.Copy(szCombs, strlen(szCombs)); - delete [] szCombs; - nPS++; - } - } - - if (!Combinations.Num()) - { - return NULL; - } - pPtr = new char [Combinations.Num() + 1]; - memcpy(pPtr, &Combinations[0], Combinations.Num()); - pPtr[Combinations.Num()] = 0; - return pPtr; -} - -bool CHWShader::PreactivateShaders() -{ - bool bRes = true; - - if (CRenderer::CV_r_shaderspreactivate) - { - gRenDev->m_pRT->RC_PreactivateShaders(); - } - - return bRes; -} - -void CHWShader::RT_PreactivateShaders() -{ - gRenDev->m_cEF.mfPreloadBinaryShaders(); -} - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DMeshBaker.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DMeshBaker.cpp deleted file mode 100644 index e914b9e9b5..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DMeshBaker.cpp +++ /dev/null @@ -1,925 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "IIndexedMesh.h" -#include "IShader.h" -#include "Common/RenderView.h" -#include "Common/Textures/TextureManager.h" - -class CREBaker - : public CRendElementBase -{ -private: - IRenderElement* m_pSrc; - std::vector m_pDst; - CMesh* m_pSrcMesh; - int m_nPhase; - bool m_bSmoothNormals; - const SMeshBakingMaterialParams* m_params; - int m_numParams; - -public: - CREBaker(IRenderElement* pSrc, CMesh* pSrcMesh, std::vector pDst, int nPhase, const SMeshBakingMaterialParams* params, int numParams, bool bSmoothNormals) { m_pSrc = pSrc; m_pDst = pDst; m_pSrcMesh = pSrcMesh; m_nPhase = nPhase; m_params = params; m_numParams = numParams; m_bSmoothNormals = bSmoothNormals; } - virtual ~CREBaker() { } - inline uint16 mfGetFlags(void) { return m_pSrc->mfGetFlags(); } - inline void mfSetFlags(uint16 fl) { m_pSrc->mfSetFlags(fl); } - inline void mfUpdateFlags(uint16 fl) { m_pSrc->mfUpdateFlags(fl); } - inline void mfClearFlags(uint16 fl) { m_pSrc->mfClearFlags(fl); } - inline bool mfCheckUpdate(int Flags, uint16 nFrame, bool /* unused */) { return m_pSrc->mfCheckUpdate(Flags, nFrame); } - virtual void mfPrepare(bool bCheckOverflow) { m_pSrc->mfPrepare(bCheckOverflow); gcpRendD3D->m_RP.m_CurVFormat = eVF_P3F_T2F_T3F; } - virtual CRenderChunk* mfGetMatInfo() { return m_pSrc->mfGetMatInfo(); } - virtual TRenderChunkArray* mfGetMatInfoList() { return m_pSrc->mfGetMatInfoList(); } - virtual int mfGetMatId() { return m_pSrc->mfGetMatId(); } - virtual void mfReset() { m_pSrc->mfReset(); } - virtual bool mfIsHWSkinned() { return m_pSrc->mfIsHWSkinned(); } - virtual CRendElementBase* mfCopyConstruct(void) { return m_pSrc->mfCopyConstruct(); } - virtual void mfCenter(Vec3& centr, CRenderObject* pObj) { m_pSrc->mfCenter(centr, pObj); } - virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs) { m_pSrc->mfGetBBox(vMins, vMaxs); } - virtual void mfGetPlane(Plane& pl) { m_pSrc->mfGetPlane(pl); } - virtual bool mfCompile(CParserBin& Parser, SParserFrame& Frame) { return m_pSrc->mfCompile(Parser, Frame); } - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void* mfGetPointer(ESrcPointer ePT, int* Stride, EParamType Type, ESrcPointer Dst, int Flags) { return m_pSrc->mfGetPointer(ePT, Stride, Type, Dst, Flags); } - virtual bool mfPreDraw(SShaderPass* sl) { return m_pSrc->mfPreDraw(sl); } - virtual bool mfUpdate(int Flags, bool bTessellation = false) { bool bRet = m_pSrc->mfUpdate(Flags, bTessellation); gcpRendD3D->m_RP.m_CurVFormat = eVF_P3F_T2F_T3F; return bRet; } - virtual void mfPrecache(const SShaderItem& SH) { m_pSrc->mfPrecache(SH); } - virtual void mfExport(struct SShaderSerializeContext& SC) { m_pSrc->mfExport(SC); } - virtual int Size() { return m_pSrc->Size(); } - virtual void GetMemoryUsage(ICrySizer* pSizer) const { m_pSrc->GetMemoryUsage(pSizer); } -}; - -bool CREBaker::mfDraw(CShader* ef, SShaderPass* sfm) -{ - static CCryNameR triPosName("TRI_POS"); - static CCryNameR triBiNormName("TRI_BINORM"); - static CCryNameR triTangName("TRI_TANGENT"); - static CCryNameR triUVName("TRI_UV"); - static CCryNameR triColorName("TRI_COLOR"); - static CCryNameR triZRange("ZOFFSET"); - Vec4 zRange(10.0f, 0.5f, 0.0f, 0.0f); - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - const bool bReverseDepth = (rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - - zRange.z = (float)m_nPhase - 0.5f; - - if (m_pDst.empty()) - { - CryLog("BakeMesh: Failed as pOutput is NULL in CREBaker::mfDraw\n"); - return false; - } - - for (std::vector::iterator mit = m_pDst.begin(), mend = m_pDst.end(); mit != mend; ++mit) - { - IIndexedMesh* pOutput = *mit; - if (!pOutput) - { - continue; - } - int numOutputTriangles = pOutput->GetIndexCount() / 3; - int numPositions = 0; - CMesh* pOutputMesh = pOutput->GetMesh(); - Vec3* pOutPos = pOutputMesh->GetStreamPtrAndElementCount(CMesh::POSITIONS, 0, &numPositions); - SMeshTangents* pOutTangents = pOutputMesh->GetStreamPtr(CMesh::TANGENTS, 0); - vtx_idx* pOutIndices = pOutputMesh->GetStreamPtr(CMesh::INDICES, 0); - SMeshTexCoord* pOutTexCoords = pOutputMesh->GetStreamPtr(CMesh::TEXCOORDS, 0); - - std::vector smoothedNormals; - if (m_bSmoothNormals) - { - smoothedNormals.resize(numPositions); - for (int pi = 0; pi < numPositions; pi++) - { - Vec3 p = pOutPos[pi]; - Vec3 n(ZERO); - for (int i = 0; i < numOutputTriangles; i++) - { - vtx_idx idx0 = pOutIndices[3 * i + 0]; - vtx_idx idx1 = pOutIndices[3 * i + 1]; - vtx_idx idx2 = pOutIndices[3 * i + 2]; - if (pOutPos[idx0] == p || pOutPos[idx1] == p || pOutPos[idx2] == p) - { - Vec3 faceN = (pOutPos[idx1] - pOutPos[idx0]).Cross(pOutPos[idx2] - pOutPos[idx0]); - faceN.NormalizeSafe(); - n += faceN; - } - } - if (n.NormalizeSafe() == 0.0f) - { - // Make sure we actually get a valid normal even if everything went wrong - n = pOutTangents[pi].GetN().normalize(); - } - smoothedNormals[pi] = n; - } - } - - // Allocate and fill per-stream vertex buffers - TempDynVB vb0(gcpRendD3D); - TempDynVB vb1(gcpRendD3D); - - { - vb0.Allocate(numOutputTriangles * 3); - SVF_P3F_T2F_T3F* vInputs = vb0.Lock(); - - for (int i = numOutputTriangles * 3 - 1; i >= 0; i--) - { - SVF_P3F_T2F_T3F& v = vInputs[i]; - vtx_idx idx = pOutIndices[i]; - v.st0 = pOutTexCoords[idx].GetUV(); - v.p = pOutPos[idx]; - if (m_bSmoothNormals) - { - v.st1 = smoothedNormals[idx]; - } - else - { - v.st1 = pOutTangents[idx].GetN().normalize(); - } - } - - vb0.Unlock(); - vb0.Bind(VSF_GENERAL); - } - - { - vb1.Allocate(numOutputTriangles * 3); - SPipTangents* pTangentsVB = vb1.Lock(); - - for (int i = 0; i < numOutputTriangles * 3; i++) - { - vtx_idx idx = pOutIndices[i]; - pOutTangents[idx].ExportTo(pTangentsVB[i]); - } - - vb1.Unlock(); - vb1.Bind(VSF_TANGENTS); - } - - int nStencilState = - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_REPLACE); - - uint32 State = rd->m_RP.m_CurState | GS_STENCIL; - - if (ef->m_Flags & EF_DECAL) - { - PROFILE_LABEL("DECAL"); - State = (State & ~GS_BLEND_MASK); - State |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - } - - rd->FX_SetStencilState(nStencilState, 1, 0xFFFFFFFF, 0xFFFFFFFF); - rd->FX_SetState(State); - - if (!FAILED(rd->FX_SetVertexDeclaration(VSM_GENERAL | ((1 << VSF_TANGENTS)), eVF_P3F_T2F_T3F))) - { - CMesh* pInputMesh = m_pSrcMesh; - Vec3* pInPos = pInputMesh->GetStreamPtr(CMesh::POSITIONS); - vtx_idx* pInIndices = pInputMesh->GetStreamPtr(CMesh::INDICES); - SMeshTexCoord* pInTexCoords = pInputMesh->GetStreamPtr(CMesh::TEXCOORDS); - SMeshTangents* pInTangents = pInputMesh->GetStreamPtr(CMesh::TANGENTS); - SMeshColor* pInColors = pInputMesh->GetStreamPtr(CMesh::COLORS, 0); - Matrix44* pTexMtx = NULL; - if (rd->m_RP.m_pShaderResources) - { - SEfResTexture* pTex = rd->m_RP.m_pShaderResources->GetTextureResource(EFTT_DIFFUSE); - if (pTex && pTex->IsHasModificators()) - { - SEfTexModificator* mod = pTex->m_Ext.m_pTexModifier; - pTexMtx = &mod->m_TexMatrix; - } - } - - float textureBakeLoopTimer = gEnv->pTimer->GetAsyncCurTime(); - for (int i = 0; i < rd->m_RP.m_RendNumIndices / 3; i++) - { - Vec4 triPos[3]; - Vec4 triUV[3]; - Vec4 triTangents[2][3]; - Vec4 triColor[3]; - - for (int t = 0; t < 3; t++) - { - vtx_idx idx = pInIndices[rd->m_RP.m_FirstIndex + i * 3 + t]; - triPos[t].x = pInPos[idx].x; - triPos[t].y = pInPos[idx].y; - triPos[t].z = pInPos[idx].z; - pInTexCoords[idx].GetUV(triUV[t]); - if (pTexMtx) - { - Vec4 modTex = (*pTexMtx) * Vec4(triUV[t].x, triUV[t].y, 0.0f, 1.0f); - triUV[t].x = modTex.x; - triUV[t].y = modTex.y; - } - pInTangents[idx].GetTB(triTangents[0][t], triTangents[1][t]); - if (pInColors) - { - pInColors[idx].GetRGBA(triColor[t]), triColor[t] /= 255.0f; - } - else - { - triColor[t] = Vec4(1.0f, 1.0f, 1.0f, 1.0f); - } - } - if (triPos[0] != triPos[1] && triPos[0] != triPos[2] && triPos[1] != triPos[2]) - { - for (int ss = 0; ss < pOutputMesh->GetSubSetCount(); ss++) - { - const SMeshSubset& pSubSet = pOutput->GetSubSet(ss); - if (pSubSet.nMatID < m_numParams) - { - if (m_params[pSubSet.nMatID].bIgnore) - { - continue; - } - zRange.x = m_params[pSubSet.nMatID].rayLength; - zRange.y = m_params[pSubSet.nMatID].rayIndent; - } - else - { - zRange.x = 10.0f; - zRange.y = 0.5f; - } - zRange = bReverseDepth ? Vec4(-zRange.x, -zRange.y, zRange.z, zRange.w) : zRange; - - if (i > 0) - { - CHWShader_D3D* pCurVS = (CHWShader_D3D*)sfm->m_VShader; - CHWShader_D3D* pCurPS = (CHWShader_D3D*)sfm->m_PShader; - - pCurVS->UpdatePerBatchConstantBuffer(); - pCurPS->UpdatePerBatchConstantBuffer(); - } - rd->m_RP.m_pShader->FXSetVSFloat(triPosName, triPos, 3); - rd->m_RP.m_pShader->FXSetPSFloat(triPosName, triPos, 3); - rd->m_RP.m_pShader->FXSetPSFloat(triUVName, triUV, 3); - rd->m_RP.m_pShader->FXSetPSFloat(triZRange, &zRange, 1); - rd->m_RP.m_pShader->FXSetPSFloat(triBiNormName, triTangents[0], 3); - rd->m_RP.m_pShader->FXSetPSFloat(triTangName, triTangents[1], 3); - rd->m_RP.m_pShader->FXSetPSFloat(triColorName, triColor, 3); - rd->FX_Commit(); - rd->FX_DrawPrimitive(eptTriangleList, pSubSet.nFirstIndexId, pSubSet.nNumIndices); - } - } - if ((i % 8) == 7) - { - if (!rd->m_pRT || rd->m_pRT->IsRenderThread()) - { - // Send the commands to the GPU to make sure we don't timeout the driver - rd->GetDeviceContext().Flush(); - Sleep(1); - } - } - } - - // Print a message every now and then to show we are still working. - if (gEnv->pTimer->GetAsyncCurTime() - textureBakeLoopTimer > 20.0f) - { - textureBakeLoopTimer = gEnv->pTimer->GetAsyncCurTime(); - CryLog("LoD texture baker - Loop check\n"); - } - } - - // Release buffers once finished - vb0.Release(); - vb1.Release(); - } - - return true; -} - -struct CompareRendItemMeshBaker -{ - bool operator()(const SRendItem& a, const SRendItem& b) const - { - CShader* pShaderA, * pShaderB; - CShaderResources* pResA, * pResB; - int nTech; - SRendItem::mfGet(a.SortVal, nTech, pShaderA, pResA); - SRendItem::mfGet(b.SortVal, nTech, pShaderB, pResB); - - if (pShaderA && pShaderB) - { - // sort decals to the end - if ((pShaderA->m_Flags & EF_DECAL) != (pShaderB->m_Flags & EF_DECAL)) - { - return (pShaderA->m_Flags & EF_DECAL) < (pShaderB->m_Flags & EF_DECAL); - } - } - - if (pResA && pResB) - { - if (pResA->IsTransparent() != pResB->IsTransparent()) - { - return pResA->GetStrengthValue(EFTT_OPACITY) > pResB->GetStrengthValue(EFTT_OPACITY); - } - if (pResA->IsAlphaTested() != pResB->IsAlphaTested()) - { - return pResA->GetAlphaRef() < pResB->GetAlphaRef(); - } - } - - int nNearA = (a.ObjSort & FOB_NEAREST); - int nNearB = (b.ObjSort & FOB_NEAREST); - if (nNearA != nNearB) // Sort by nearest flag - { - return nNearA > nNearB; - } - - if (a.SortVal != b.SortVal) // Sort by shaders - { - return a.SortVal < b.SortVal; - } - - if (a.pElem != b.pElem) // Sort by geometry - { - return a.pElem < b.pElem; - } - - return (a.ObjSort & 0xFFFF) < (b.ObjSort & 0xFFFF); // Sort by distance - } -}; - -static void PatchShaderItemRecurse(_smart_ptr pDst, _smart_ptr pMat) -{ - IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); - if (pMat && pDst && pMat != pMatMan->GetDefaultMaterial()) - { - SShaderItem& siSrc(pMat->GetShaderItem()); - if (siSrc.m_pShader) - { - SInputShaderResources isr(siSrc.m_pShaderResources); - SShaderItem siDst(gcpRendD3D->EF_LoadShaderItem("Illum.MeshBaker", false, 0, &isr, siSrc.m_pShader->GetGenerationMask())); - pDst->AssignShaderItem(siDst); - siDst.m_pShaderResources->UpdateConstants(siDst.m_pShader); - } - for (int i = 0; i < pMat->GetSubMtlCount(); i++) - { - _smart_ptr pSubMat = pMat->GetSubMtl(i); - PatchShaderItemRecurse(pDst->GetSubMtl(i), pSubMat); - } - } -} - -static _smart_ptr PatchMaterial(_smart_ptr pMat) -{ - IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); - _smart_ptr pResult = pMatMan->CloneMaterial(pMat); - - PatchShaderItemRecurse(pResult, pMat); - - return pResult; -} - -static void EtchAlphas(std::vector outputList, _smart_ptr pMaterial, const SMeshBakingMaterialParams* params, int numParams) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if (outputList.empty()) - { - return; - } - - for (std::vector::iterator mit = outputList.begin(), mend = outputList.end(); mit != mend; ++mit) - { - IIndexedMesh* pOutput = *mit; - if (!pOutput) - { - continue; - } - int numOutputTriangles = pOutput->GetIndexCount() / 3; - CMesh* pOutputMesh = pOutput->GetMesh(); - vtx_idx* pOutIndices = pOutputMesh->GetStreamPtr(CMesh::INDICES); - SMeshTexCoord* pOutTexCoords = pOutputMesh->GetStreamPtr(CMesh::TEXCOORDS); - - { - TempDynVB vb(gRenDev); - vb.Allocate(numOutputTriangles * 3); - SVF_P3F_T2F_T3F* vInputs = vb.Lock(); - - for (int i = 0; i < numOutputTriangles * 3; i++) - { - SVF_P3F_T2F_T3F& v = vInputs[i]; - const vtx_idx idx = pOutIndices[i]; - const Vec2 uv = pOutTexCoords[idx].GetUV(); - - v.p.x = uv.x; - v.p.y = uv.y; - v.p.z = 0.0f; - v.st0.x = v.p.x; - v.st0.y = v.p.y; - } - - vb.Unlock(); - vb.Bind(VSF_GENERAL); - vb.Release(); - } - - if (!FAILED(rd->FX_SetVertexDeclaration(VSM_GENERAL, eVF_P3F_T2F_T3F))) - { - rd->FX_Commit(); - for (int ss = 0; ss < pOutputMesh->GetSubSetCount(); ss++) - { - const SMeshSubset& pSubSet = pOutput->GetSubSet(ss); - if (pSubSet.nMatID < numParams && (params[pSubSet.nMatID].bAlphaCutout && !params[pSubSet.nMatID].bIgnore)) - { - rd->FX_DrawPrimitive(eptTriangleList, pSubSet.nFirstIndexId, pSubSet.nNumIndices); - } - } - } - } -} - -static bool Dilate(CTexture* pTex, CTexture* pOutput, int nPhase, std::vector pInputIndexedMesh, _smart_ptr pMaterial, const SMeshBakingMaterialParams* params, int numParams, SDepthTexture* pDepthStencil, const SMeshBakingInputParams* pInputParams) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - PROFILE_LABEL_SCOPE("BakeMeshDilate"); - static CCryNameR missColourName("MISSCOLOUR"); - static CCryNameR tintColourName("TINTCOLOUR"); - static CCryNameR pixSizeName("PIXSIZE"); - static CCryNameTSCRC TechName = "MeshBakerDilate"; - CShader* pSH = rd->m_cEF.mfForName("MeshBakerDilate", 0); - uint32 uvMapWidth = pTex->GetWidth(); - uint32 uvMapHeight = pTex->GetHeight(); - Vec4 pixSize = Vec4(1.0f / (float)uvMapWidth, 1.0f / (float)uvMapHeight, 0, 0); - const ColorF& inMissColour = pInputParams->dilateMagicColour; - Vec4 missColour = Vec4(inMissColour.r, inMissColour.g, inMissColour.b, inMissColour.a); - Vec4 whiteColour = Vec4(1.0f, 1.0f, 1.0f, 1.0f); - uint32 nPasses = 0; - if (!pSH) - { - CryLog("BakeMesh: Dilate shader missing\n"); - return false; - } - - bool bAlphaCutout = false; - for (int i = 0; i < numParams; i++) - { - if (params[i].bAlphaCutout && !params[i].bIgnore) - { - bAlphaCutout = (nPhase == 0); - } - } - - CTexture* pTemp = CTexture::CreateRenderTarget("MeshBaker_DilateTemp", uvMapWidth, uvMapHeight, Clr_Unknown, eTT_2D, FT_STATE_CLAMP, pTex->GetTextureDstFormat()); - int TempX, TempY, TempWidth, TempHeight; - CTexture::GetTexState(STexState(FILTER_TRILINEAR, false)); - rd->GetViewport(&TempX, &TempY, &TempWidth, &TempHeight); - rd->RT_SetViewport(0, 0, uvMapWidth, uvMapHeight); - - rd->FX_ResetPipe(); - rd->D3DSetCull(eCULL_None); - pSH->FXSetTechnique(TechName); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - - const uint32 nPassDilateWithThresholdAlpha = 0; - const uint32 nPassDilate = 1; - const uint32 nPassDilateWithZeroAlpha = 2; - const uint32 nPassGammaCorrect = 3; - const uint32 nPassNormalCorrect = 4; - const uint32 nPassPassthrough = 5; - - if (pInputParams->bDoDilationPass) - { - // Set miss colour wherever we missed - rd->FX_PushRenderTarget(0, pTex, pDepthStencil); - int nStencilState = STENC_FUNC(FSS_STENCFUNC_EQUAL) | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_KEEP); - rd->FX_SetStencilState(nStencilState, 0, 0xFFFFFFFF, 0xFFFFFFFF); - rd->FX_SetState(GS_NODEPTHTEST | GS_STENCIL); - pSH->FXBeginPass(nPassPassthrough); - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - pSH->FXSetPSFloat(tintColourName, &missColour, 1); - rd->FX_Commit(); - rd->DrawQuad(0.0f, 0.0f, 1.0f, 1.0f, ColorF(1, 1, 1, 1)); - pSH->FXEndPass(); - rd->FX_PopRenderTarget(0); - - uint32 dilatePasses = max(uvMapWidth, uvMapHeight); - - for (int p = 0; p < 2; p++) - { - if (p == 1 || (bAlphaCutout && nPhase == 0)) // If doing alpha cutout we need to dilate the alpha cutout sections first (so geometry doesn't dilate into alphaed areas) - { - for (uint32 i = 0; i < dilatePasses; i++) // Dilate as much as possible (make sure even number so result ends up in correct buffer) - { - rd->FX_PushRenderTarget(0, pTemp, pDepthStencil); - rd->FX_SetState(GS_NODEPTHTEST); - // Pass through all existing data - pSH->FXBeginPass(nPassPassthrough); - pTex->Apply(0); - rd->FX_Commit(); - pSH->FXSetPSFloat(tintColourName, &whiteColour, 1); - rd->DrawQuad(0.0f, 0.0f, 1.0f, 1.0f, ColorF(1, 1, 1, 1)); - // Dilate using stencil/magic colour to identify areas to dilate - if (nPhase == 0) - { - pSH->FXBeginPass(p ? nPassDilateWithThresholdAlpha : nPassDilateWithZeroAlpha); - } - else if (nPhase == 1) - { - pSH->FXBeginPass(p ? nPassDilate : nPassDilateWithZeroAlpha); - } - else - { - pSH->FXBeginPass(nPassDilateWithZeroAlpha); - } - pTex->Apply(0); - pSH->FXSetPSFloat(missColourName, &missColour, 1); - pSH->FXSetPSFloat(pixSizeName, &pixSize, 1); - nStencilState = STENC_FUNC(FSS_STENCFUNC_EQUAL) | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_INCR); - rd->FX_SetStencilState(nStencilState, 0, 0xFFFFFFFF, 0xFFFFFFFF); - rd->FX_SetState(GS_NODEPTHTEST | GS_STENCIL); - if (p) - { - rd->DrawQuad(0.0f, 0.0f, 1.0f, 1.0f, ColorF(1, 1, 1, 1)); - } - else - { - EtchAlphas(pInputIndexedMesh, pMaterial, params, numParams); - } - rd->FX_PopRenderTarget(0); - // ping pong - CTexture* tmp = pTex; - pTex = pTemp; - pTemp = tmp; - } - } - } - pSH->FXEndPass(); - } - else if (bAlphaCutout) - { - // not doing dilate pass but still show alpha - Vec4 zeroAlpha(1, 1, 1, 0); - rd->FX_PushRenderTarget(0, pTex, pDepthStencil); - int nStencilState = STENC_FUNC(FSS_STENCFUNC_EQUAL) | STENCOP_FAIL(FSS_STENCOP_KEEP) | STENCOP_ZFAIL(FSS_STENCOP_KEEP) | STENCOP_PASS(FSS_STENCOP_KEEP); - rd->FX_SetStencilState(nStencilState, 0, 0xFFFFFFFF, 0xFFFFFFFF); - rd->FX_SetState(GS_NODEPTHTEST | GS_STENCIL | GS_COLMASK_A); - pSH->FXBeginPass(nPassPassthrough); - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - pSH->FXSetPSFloat(tintColourName, &zeroAlpha, 1); - rd->FX_Commit(); - EtchAlphas(pInputIndexedMesh, pMaterial, params, numParams); - pSH->FXEndPass(); - rd->FX_PopRenderTarget(0); - } - rd->FX_SetState(GS_NODEPTHTEST); - if (pOutput) // Fix SRGB/Flipped normals problems - { - pSH->FXBeginPass((nPhase == 1) ? nPassNormalCorrect : nPassGammaCorrect); - rd->FX_PushRenderTarget(0, pOutput, NULL); - pTex->Apply(0); - rd->FX_Commit(); - rd->DrawQuad(0.0f, 0.0f, 1.0f, 1.0f, ColorF(1, 1, 1, 1)); - rd->FX_PopRenderTarget(0); - pSH->FXEndPass(); - } - pSH->FXEnd(); - rd->RT_SetViewport(TempX, TempY, TempWidth, TempHeight); - rd->FX_SetState(0); - rd->FX_Commit(); - rd->FX_ResetPipe(); - pTemp->Release(); - pSH->Release(); - return true; -} - -static bool IsRenderableSubObject(IStatObj* obj, int child) -{ - return obj->GetSubObject(child)->nType == STATIC_SUB_OBJECT_MESH && - obj->GetSubObject(child)->pStatObj != NULL && - obj->GetSubObject(child)->pStatObj->GetRenderMesh() != NULL; -} - -bool CD3D9Renderer::BakeMesh([[maybe_unused]] const SMeshBakingInputParams* pInputParams, [[maybe_unused]] SMeshBakingOutput* pReturnValues) -{ -#if defined(WIN64) || defined(WIN32) || defined(APPLE) || defined(LINUX) - if (gEnv->IsEditor()) - { - std::vector pRM; - std::vector<_smart_ptr > pInputMaterial; - std::vector pInputMesh; - std::vector pOutputMesh; - _smart_ptr pOutputMaterial; - int outputWidth = pInputParams->outputTextureWidth; - int outputHeight = pInputParams->outputTextureHeight; - int cachedShaderCompileCvar = CRenderer::CV_r_shadersasynccompiling; - - if (pInputParams->pInputMesh) - { - IStatObj* obj = pInputParams->pInputMesh; - if (obj->GetRenderMesh() == NULL) - { - if (obj->GetSubObjectCount() == 0) - { - CryLog("BakeMesh: Failed due to input mesh having no rendermesh and no subobjects\n"); - return false; - } - for (int i = 0; i < obj->GetSubObjectCount(); i++) - { - if (IsRenderableSubObject(obj, i)) - { - IStatObj* pObj = obj->GetSubObject(i)->pStatObj; - pRM.push_back(pObj->GetRenderMesh()); - pInputMaterial.push_back(pInputParams->pMaterial ? pInputParams->pMaterial : pObj->GetMaterial()); - pInputMesh.push_back(pObj->GetIndexedMesh(true)->GetMesh()); - } - } - } - else - { - pRM.push_back(obj->GetRenderMesh()); - pInputMaterial.push_back(pInputParams->pMaterial ? pInputParams->pMaterial : obj->GetMaterial()); - pInputMesh.push_back(obj->GetIndexedMesh(true)->GetMesh()); - } - } - - // HACK TO GET STREAMING SYSTEM TO MAKE SURE USED TEXTURES ARE STREAMED IN - gEnv->p3DEngine->ProposeContentPrecache(); - // gEnv->p3DEngine->UpdateStreaming(SRenderingPassInfo::CreateGeneralPassRenderingInfo(gEnv->pSystem->GetViewCamera())); - for (std::vector<_smart_ptr >::iterator it = pInputMaterial.begin(), end = pInputMaterial.end(); it != end; ++it) - { - float start = gEnv->pTimer->GetAsyncCurTime(); - while (true) - { - int pRoundIds[MAX_STREAM_PREDICTION_ZONES] = {0}; - (*it)->PrecacheMaterial(0.0f, NULL, true, false); - (*it)->PrecacheMaterial(0.0f, NULL, false, false); - CTexture::Update(); - gEnv->pSystem->GetStreamEngine()->Update(); - if ((*it)->IsStreamedIn(pRoundIds, NULL)) - { - break; - } - if (gEnv->pTimer->GetAsyncCurTime() - start > 5.0f) - { - LogWarning("Time out waiting for textures to stream\n"); - break; - } - } - } - - if (pRM.empty()) - { - CryLog("BakeMesh: Failed due to no inputs\n"); - return false; - } - - if (pInputParams->pCageMesh) - { - IStatObj* obj = pInputParams->pCageMesh; - - if (obj->GetRenderMesh() == NULL) - { - if (obj->GetSubObjectCount() == 0) - { - CryLog("BakeMesh: Failed due to cage mesh having no rendermesh and no subobjects\n"); - return false; - } - for (int i = 0; i < obj->GetSubObjectCount(); i++) - { - if (IsRenderableSubObject(obj, i)) - { - IStatObj* subobj = obj->GetSubObject(i)->pStatObj; - pOutputMesh.push_back(subobj->GetIndexedMesh(true)); - } - } - } - else - { - pOutputMesh.push_back(obj->GetIndexedMesh(true)); - } - pOutputMaterial = obj->GetMaterial(); - } - else - { - CryLog("BakeMesh: Failed due to no low poly cage\n"); - return false; - } - - CRenderer::CV_r_shadersasynccompiling = 0; - - std::vector<_smart_ptr > pBakeMaterial; - pBakeMaterial.reserve(pInputMaterial.size()); - for (std::vector<_smart_ptr >::iterator it = pInputMaterial.begin(), end = pInputMaterial.end(); it != end; ++it) - { - pBakeMaterial.push_back(PatchMaterial(*it)); // Replace current shader with MeshBake - } - - SDepthTexture* pTmpDepthSurface = FX_GetDepthSurface(outputWidth, outputHeight, false); - if (!pTmpDepthSurface) - { - CryLog("BakeMesh: Failed as temporary depth surface could not be created of size %dx%d\n", outputWidth, outputHeight); - CRenderer::CV_r_shadersasynccompiling = cachedShaderCompileCvar; - return false; - } - CTexture* pHighPrecisionBuffer[3], * pOutputBuffer[3]; - - PROFILE_LABEL_SCOPE("BakeMesh"); - - SRenderingPassInfo passInfo = SRenderingPassInfo::CreateGeneralPassRenderingInfo(gEnv->p3DEngine->GetRenderingCamera()); - - if (m_RP.m_pRLD == NULL) - { - const int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - m_RP.m_pRLD = &m_RP.m_pRenderViews[m_RP.m_nProcessThreadID]->m_RenderListDesc[recursiveLevel]; - } - - bool bAlphaCutout = false; - for (int i = 0; i < pInputParams->numMaterialParams; i++) - { - if (pInputParams->pMaterialParams[i].bAlphaCutout && !pInputParams->pMaterialParams[i].bIgnore) - { - bAlphaCutout = true; - } - } - - for (int nPhase = 0; nPhase < 3; nPhase++) - { - const bool bReverseDepth = !!(m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH); - ColorF Clr_Phase; - switch (nPhase) - { - case 0: - Clr_Phase = pInputParams->defaultBackgroundColour; - break; - case 1: - Clr_Phase = ColorF(0.5f, 0.5f, 1.0f, 1.0f); - break; - default: - Clr_Phase = ColorF(0.0f, 0.0f, 0.0f, 1.0f); - } - - char uniqueName[128]; - const char* suffix[3] = {"Albedo", "Normal", "Refl"}; - sprintf_s(uniqueName, sizeof(uniqueName), "MeshBaker_16Bit%s_%d%s", suffix[nPhase], pInputParams->nLodId, bAlphaCutout ? "_alpha" : ""); - pHighPrecisionBuffer[nPhase] = CTexture::CreateRenderTarget(uniqueName, outputWidth, outputHeight, Clr_Unknown, eTT_2D, FT_STATE_CLAMP, eTF_R16G16B16A16F /*, -1, 95*/); - sprintf_s(uniqueName, sizeof(uniqueName), "MeshBaker_8Bit%s_%d%s", suffix[nPhase], pInputParams->nLodId, bAlphaCutout ? "_alpha" : ""); - pOutputBuffer[nPhase] = CTexture::CreateRenderTarget(uniqueName, outputWidth, outputHeight, Clr_Unknown, eTT_2D, FT_STATE_CLAMP, eTF_R8G8B8A8 /*, -1, 95*/); - - PROFILE_LABEL_SCOPE(suffix[nPhase]); - - FX_ResetPipe(); - FX_ClearTarget(pHighPrecisionBuffer[nPhase], Clr_Phase); - FX_ClearTarget(pTmpDepthSurface, CLEAR_ZBUFFER | CLEAR_STENCIL, Clr_FarPlane_R.r, 0); - FX_PushRenderTarget(0, pHighPrecisionBuffer[nPhase], pTmpDepthSurface); - RT_SetViewport(0, 0, outputWidth, outputHeight); - - int nThreadID = m_pRT->GetThreadList(); - SRendItem::m_RecurseLevel[nThreadID]++; - FX_PreRender(3); - - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - rRP.m_pRenderFunc = FX_FlushShader_General; - rRP.m_nPassGroupID = EFSLIST_GENERAL; - rRP.m_nPassGroupDIP = rRP.m_nPassGroupID; - rRP.m_nSortGroupID = 0; - FX_StartBatching(); - rRP.m_nBatchFilter = FB_GENERAL; - - int numChunks = 0; - for (int m = 0; m < pRM.size(); m++) - { - TRenderChunkArray& chunkList = pRM[m]->GetChunks(); - numChunks += chunkList.size(); - } - - std::vector pObjs; - SRendItem* ri = new SRendItem[numChunks]; - numChunks = 0; - for (int m = 0; m < pRM.size(); m++) - { - TRenderChunkArray& chunkList = pRM[m]->GetChunks(); - - CRenderObject* pObj = aznew CRenderObject(); - pObj->Init(); - pObj->m_II.m_Matrix.SetIdentity(); - pObj->m_II.m_Matrix.SetTranslationMat(GetCamera().GetPosition()); - pObj->m_ObjFlags = 0; - pObj->m_II.m_AmbColor = Col_White; - pObj->m_nSort = 0; - pObj->m_ObjFlags |= FOB_NO_FOG | ((!pInputMesh[m]) ? FOB_SKINNED : 0); - pObj->m_pCurrMaterial = pBakeMaterial[m]; - pObjs.push_back(pObj); - for (int i = 0; i < chunkList.size(); i++) - { - CRenderChunk* pChunk = &chunkList[i]; - SShaderItem& pSH = pBakeMaterial[m]->GetShaderItem(pChunk->m_nMatID); - CShaderResources* pR = (CShaderResources*)pSH.m_pShaderResources; - CShader* __restrict pShader = (CShader*)pSH.m_pShader; - CREMesh* pRE = pChunk->pRE; - - if (pShader->m_Flags & EF_DECAL) - { - const bool bHasDiffuse = pR ? pR->TextureSlotExists((uint16)EFTT_DIFFUSE) : false; - const bool bHasNormal = pR ? pR->TextureSlotExists((uint16)EFTT_NORMALS) : false; - const bool bHasGloss = pR ? pR->TextureSlotExists((uint16)EFTT_SMOOTHNESS) : false; - - // emulate gbuffer blend masking (since we don't MRT, this won't work correctly - // in the normal pipeline) - - if (!bHasDiffuse && nPhase == 0) - { - continue; - } - if (!bHasNormal && nPhase == 1) - { - continue; - } - if (!bHasGloss && nPhase == 2) - { - continue; - } - } - - ri[numChunks].pObj = pObj; - ri[numChunks].nOcclQuery = m; // Stash in this in something that doesn't effect sorting - ri[numChunks].ObjSort = (pObj->m_ObjFlags & 0xffff0000) | pObj->m_nSort; - ri[numChunks].nBatchFlags = EF_BatchFlags(pSH, pObj, pRE, passInfo); // naughty - ri[numChunks].nStencRef = pObj->m_nClipVolumeStencilRef; - uint32 nResID = pR ? pR->m_Id : 0; - ri[numChunks].SortVal = (nResID << 18) | (pShader->mfGetID() << 6) | (pSH.m_nTechnique & 0x3f); - ri[numChunks].pElem = pRE; - numChunks++; - } - } - - std::sort(ri, ri + numChunks, CompareRendItemMeshBaker()); - - for (int i = 0; i < numChunks; i++) - { - CShader* pShader; - CShaderResources* pRes; - int nTech; - SRendItem::mfGet(ri[i].SortVal, nTech, pShader, pRes); - if (pShader) - { - int m = ri[i].nOcclQuery; - ri[i].nOcclQuery = SRendItem::kOcclQueryInvalid; - CREBaker wrappedRE(ri[i].pElem, pInputMesh[m], pOutputMesh, nPhase, pInputParams->pMaterialParams, pInputParams->numMaterialParams, pInputParams->bSmoothNormals); - ri[i].pElem = &wrappedRE; - FX_ObjectChange(pShader, pRes, ri[i].pObj, &wrappedRE); - FX_Start(pShader, nTech, pRes, &wrappedRE); - wrappedRE.mfPrepare(true); - rRP.m_RIs[0].AddElem(&ri[i]); - FX_FlushShader_General(); - } - } - - for (int i = 0; i < pObjs.size(); i++) - { - delete pObjs[i]; - } - delete[] ri; - - FX_PostRender(); - - SRendItem::m_RecurseLevel[nThreadID]--; - - FX_PopRenderTarget(0); - - Dilate(pHighPrecisionBuffer[nPhase], pOutputBuffer[nPhase], nPhase, pOutputMesh, pOutputMaterial, pInputParams->pMaterialParams, pInputParams->numMaterialParams, pTmpDepthSurface, pInputParams); - } - - for (int i = 0; i < 3; i++) - { - if (i == 2 && !pInputParams->bSaveSpecular) - { - SAFE_RELEASE(pOutputBuffer[i]); - pReturnValues->ppOuputTexture[i] = NULL; - - SAFE_RELEASE(pHighPrecisionBuffer[i]); - pReturnValues->ppIntermediateTexture[i] = NULL; - continue; - } - - pOutputBuffer[i]->GetDevTexture()->DownloadToStagingResource(0); - pReturnValues->ppOuputTexture[i] = pOutputBuffer[i]; - pReturnValues->ppIntermediateTexture[i] = pHighPrecisionBuffer[i]; - } - - CRenderer::CV_r_shadersasynccompiling = cachedShaderCompileCvar; - - return true; - } - else -#endif - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "BakeMesh: Only exists within editor\n"); - return false; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DOcclQuery.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DOcclQuery.cpp deleted file mode 100644 index db661e94a9..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DOcclQuery.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Occlusion queries unified interface implementation - - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" - -void COcclusionQuery::Create() -{ - Release(); - - // Create visibility queries - - D3DQuery* pVizQuery = NULL; - D3D11_QUERY_DESC desc; - desc.Query = D3D11_QUERY_OCCLUSION; - desc.MiscFlags = 0; - -#if !defined(NDEBUG) - HRESULT hr = -#endif - gcpRendD3D->GetDevice().CreateQuery(&desc, &pVizQuery); - assert(SUCCEEDED(hr)); - - m_nOcclusionID = (UINT_PTR) pVizQuery; - - // Prime query - BeginQuery(); - EndQuery(); -} - -void COcclusionQuery::Release() -{ - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - SAFE_RELEASE(pVizQuery); - - m_nOcclusionID = 0; - m_nDrawFrame = 0; - m_nCheckFrame = 0; - m_nVisSamples = ~0; -} - -void COcclusionQuery::BeginQuery() -{ - if (!m_nOcclusionID) - { - return; - } - - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - gcpRendD3D->GetDeviceContext().Begin(pVizQuery); -} - -void COcclusionQuery::EndQuery() -{ - if (!m_nOcclusionID) - { - return; - } - - CD3D9Renderer* rd = gcpRendD3D; - m_nDrawFrame = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - rd->GetDeviceContext().End(pVizQuery); -} - -bool COcclusionQuery::IsReady() -{ - CD3D9Renderer* rd = gcpRendD3D; - int nFrame = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - return (m_nCheckFrame == nFrame); -} - -uint32 COcclusionQuery::GetVisibleSamples(bool bAsynchronous) -{ - if (!m_nOcclusionID) - { - return ~0; - } - - CD3D9Renderer* rd = gcpRendD3D; - int nFrame = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - if (m_nCheckFrame == nFrame) - { - return m_nVisSamples; - } - - int64 nVisSamples = ~0; //query needs to be 8byte - - if (!bAsynchronous) - { - PROFILE_FRAME(COcclusionQuery::GetVisibleSamples); - - HRESULT hRes = S_FALSE; - - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - - size_t DataSize = pVizQuery->GetDataSize(); - assert(sizeof(nVisSamples) == DataSize); - while (hRes == S_FALSE) - { - hRes = rd->GetDeviceContext().GetData(pVizQuery, (void*) &nVisSamples, DataSize, 0); - } - - if (hRes == S_OK) - { - m_nCheckFrame = nFrame; - m_nVisSamples = static_cast(nVisSamples); - } - } - else - { - PROFILE_FRAME(COcclusionQuery::GetVisibleSamplesAsync); - - HRESULT hRes = S_OK; - - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - hRes = rd->GetDeviceContext().GetData(pVizQuery, (void*) &nVisSamples, pVizQuery->GetDataSize(), 0); - - if (hRes == S_OK) - { - m_nCheckFrame = nFrame; - m_nVisSamples = static_cast(nVisSamples); - } - } - return m_nVisSamples; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.cpp deleted file mode 100644 index 20f0af5a74..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.cpp +++ /dev/null @@ -1,1700 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Direct3D specific post processing special effects - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "D3DPostProcess.h" -#include -#include - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DPOSTPROCESS_CPP_SECTION_1 1 -#define D3DPOSTPROCESS_CPP_SECTION_2 2 -#endif - -enum COLORSPACES -{ - CS_sRGB0 = 0, //Most accurate sRGB curve - CS_sRGB1 = 1, //Cheap approximation - pow(col, 1/2.2) - CS_sRGB2 = 2, //cheaper approx - sqrt(col) - CS_P3D65 = 3, - CS_Rec709 = 4, - CS_Rec2020 = 5 -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -SDepthTexture* SD3DPostEffectsUtils::GetDepthSurface(CTexture* pTex) -{ - if (pTex->GetFlags() & FT_USAGE_MSAA && gRenDev->m_RP.m_MSAAData.Type) - { - return &gcpRendD3D->m_DepthBufferOrigMSAA; - } - - return &gcpRendD3D->m_DepthBufferOrig; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::ResolveRT(CTexture*& pDst, const RECT* pSrcRect) -{ - AZ_Assert(pDst, "Null texture passed in"); - if (!pDst) - { - return; - } - - int iTempX, iTempY, iWidth, iHeight; - gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - CDeviceTexture* pDstResource = pDst->GetDevTexture(); - ID3D11RenderTargetView* pOrigRT = gcpRendD3D->m_pNewTarget[0]->m_pTarget; - if (pOrigRT && pDstResource) - { - D3D11_BOX box; - ZeroStruct(box); - if (pSrcRect) - { - box.left = pSrcRect->left; - box.right = pSrcRect->right; - box.top = pSrcRect->top; - box.bottom = pSrcRect->bottom; - } - else - { - box.right = min(pDst->GetWidth(), gcpRendD3D->m_pNewTarget[0]->m_Width); - box.bottom = min(pDst->GetHeight(), gcpRendD3D->m_pNewTarget[0]->m_Height); - } - box.back = 1; - - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DPOSTPROCESS_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DPostProcess_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED - #else - ID3D11Resource* pSrcResource; - pOrigRT->GetResource(&pSrcResource); - #endif - - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_RTCopied++; - gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_RTCopiedSize += pDst->GetDeviceDataSize(); - - gcpRendD3D->GetDeviceContext().CopySubresourceRegion(pDstResource->Get2DTexture(), 0, 0, 0, 0, pSrcResource, 0, &box); - SAFE_RELEASE(pSrcResource); - } -} - -void SD3DPostEffectsUtils::SetSRGBShaderFlags() -{ - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SRGB0] | g_HWSR_MaskBit[HWSR_SRGB1] | g_HWSR_MaskBit[HWSR_SRGB2]); - switch(CRenderer::CV_r_ColorSpace) - { - case COLORSPACES::CS_sRGB0: - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SRGB0]; - break; - } - case COLORSPACES::CS_sRGB1: - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SRGB1]; - break; - } - case COLORSPACES::CS_sRGB2: - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SRGB2]; - break; - } - case COLORSPACES::CS_P3D65: - { - //todo: Needs support - } - case COLORSPACES::CS_Rec709: - { - //todo: Add support for Rec709 related shader flags to allow control over color space conversion from c++ code - } - case COLORSPACES::CS_Rec2020: - { - //todo: Add support for Rec2020 related shader flags to allow control over color space conversion from c++ code - } - default: - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "Color space not supported"); - } - } -} - -void SD3DPostEffectsUtils::CopyTextureToScreen(CTexture*& pSrc, const RECT* pSrcRegion, const int filterMode, bool sRGBLookup) -{ - CRenderer* rd = gRenDev; - uint64 saveFlagsShader_RT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE3]; - if (sRGBLookup && !pSrc->IsSRGB() && !RenderCapabilities::SupportsTextureViews()) - { - //Force SRGB conversion in the shader because the platform doesn't support texture views - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE3]; - SetSRGBShaderFlags(); - } - static CCryNameTSCRC pRestoreTechName("TextureToTexture"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pRestoreTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - gRenDev->FX_SetState(GS_NODEPTHTEST); - PostProcessUtils().SetTexture(pSrc, 0, filterMode >= 0 ? filterMode : FILTER_POINT, 1, sRGBLookup); - PostProcessUtils().DrawFullScreenTri(pSrc->GetWidth(), pSrc->GetHeight(), 0, pSrcRegion); - PostProcessUtils().ShEndPass(); - rd->m_RP.m_FlagsShader_RT = saveFlagsShader_RT; -} - -void SD3DPostEffectsUtils::CopyScreenToTexture(CTexture*& pDst, const RECT* pSrcRegion) -{ - int iTempX, iTempY, iWidth, iHeight; - gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - CTexture* source = gcpRendD3D->FX_GetCurrentRenderTarget(0); - if (source) - { - if (source->GetDstFormat() == pDst->GetDstFormat()) - { - ResolveRT(pDst, pSrcRegion); - } - else - { - StretchRect(source, pDst, false, false, false, false, SPostEffectsUtils::eDepthDownsample_None, false, pSrcRegion); - } - } - else - { - CDeviceTexture* dstResource = pDst->GetDevTexture(); - ID3D11RenderTargetView* sourceRT = gcpRendD3D->FX_GetCurrentRenderTargetSurface(0); - if (sourceRT) - { - D3D11_RENDER_TARGET_VIEW_DESC backbufferDesc; - sourceRT->GetDesc(&backbufferDesc); - const D3DFormat dstFmt = CTexture::DeviceFormatFromTexFormat(pDst->GetDstFormat()); - const D3DFormat srcFmt = backbufferDesc.Format; - - if (dstFmt == srcFmt) - { - ID3D11Resource* srcResource; - sourceRT->GetResource(&srcResource); - - ID3D11Texture2D* srcTex2D = static_cast(srcResource); - D3D11_TEXTURE2D_DESC srcTex2desc; - srcTex2D->GetDesc(&srcTex2desc); - - if (pSrcRegion) - { - D3D11_BOX box = { 0 }; - box.left = pSrcRegion->left; - box.right = pSrcRegion->right; - box.top = pSrcRegion->top; - box.bottom = pSrcRegion->bottom; - box.front = 0; - box.back = 1; - gcpRendD3D->GetDeviceContext().CopySubresourceRegion(dstResource->Get2DTexture(), 0, 0, 0, 0, srcResource, 0, &box); - } - else - { - gcpRendD3D->GetDeviceContext().CopySubresourceRegion(dstResource->Get2DTexture(), 0, 0, 0, 0, srcResource, 0, NULL); - } - } - else - { - AZ_Assert(false, "Pixel formats differ"); - } - } - else - { - AZ_Assert(false, "No source texture present"); - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::StretchRect(CTexture* pSrc, CTexture*& pDst, bool bClearAlpha, bool bDecodeSrcRGBK, bool bEncodeDstRGBK, bool bBigDownsample, EDepthDownsample depthDownsample, bool bBindMultisampled, const RECT* srcRegion) -{ - if (!pSrc || !pDst) - { - return; - } - - PROFILE_LABEL_SCOPE("STRETCHRECT"); - PROFILE_SHADER_SCOPE; - - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | - g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5] | g_HWSR_MaskBit[HWSR_REVERSE_DEPTH]); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - bool bResample = 0; - - if (pSrc->GetWidth() != pDst->GetWidth() || pSrc->GetHeight() != pDst->GetHeight()) - { - bResample = 1; - } - - const D3DFormat dstFmt = CTexture::DeviceFormatFromTexFormat(pDst->GetDstFormat()); - const D3DFormat srcFmt = CTexture::DeviceFormatFromTexFormat(pSrc->GetDstFormat()); - - bool destinationBaseTextureExists = pDst->GetDevTexture() && pDst->GetDevTexture()->GetBaseTexture(); - AZ_Error("Rendering", destinationBaseTextureExists, "'%s' used as destination texture in call to SD3DPostProcessUtils::StretchRect, but it does not have a valid device texture.", pDst->GetName()); - bool sourceBaseTextureExists = pSrc->GetDevTexture() && pSrc->GetDevTexture()->GetBaseTexture(); - AZ_Error("Rendering", sourceBaseTextureExists, "'%s' used as source texture in call to SD3DPostProcessUtils::StretchRect, but it does not have a valid device texture.", pSrc->GetName()); - - if (bResample == false && gRenDev->m_RP.m_FlagsShader_RT == 0 && dstFmt == srcFmt) - { - if (sourceBaseTextureExists && destinationBaseTextureExists) - { - gcpRendD3D->GetDeviceContext().CopyResource(pDst->GetDevTexture()->GetBaseTexture(), pSrc->GetDevTexture()->GetBaseTexture()); - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; - } - return; - } - - gcpRendD3D->FX_PushRenderTarget(0, pDst, NULL); - - gcpRendD3D->FX_SetColorDontCareActions(0, true, false); - gcpRendD3D->FX_SetDepthDontCareActions(0, true, true); - gcpRendD3D->FX_SetStencilDontCareActions(0, true, true); - - gcpRendD3D->FX_SetActiveRenderTargets(); - gcpRendD3D->RT_SetViewport(0, 0, pDst->GetWidth(), pDst->GetHeight()); - - bool bEnableRTSample0 = bBindMultisampled; - - if (bEnableRTSample0) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if (bClearAlpha) // clear alpha to 0 - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - if (bDecodeSrcRGBK) // decode RGBK src texture - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - if (depthDownsample != eDepthDownsample_None) // take minimum/maximum depth from the 4 samples - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - if (depthDownsample == eDepthDownsample_Min) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_REVERSE_DEPTH]; - } - } - if (bEncodeDstRGBK) // encode RGBK dst texture - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - static CCryNameTSCRC pTechTexToTex("TextureToTexture"); - static CCryNameTSCRC pTechTexToTexResampled("TextureToTextureResampled"); - ShBeginPass(CShaderMan::s_shPostEffects, bResample ? pTechTexToTexResampled : pTechTexToTex, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - // Get sample size ratio (based on empirical "best look" approach) - - // Set samples position - //float s1 = fSampleSize / (float) pSrc->GetWidth(); // 2.0 better results on lower res images resizing - //float t1 = fSampleSize / (float) pSrc->GetHeight(); - - CTexture* pOffsetTex = bBigDownsample ? pDst : pSrc; - - float s1 = 0.5f / (float) pOffsetTex->GetWidth(); // 2.0 better results on lower res images resizing - float t1 = 0.5f / (float) pOffsetTex->GetHeight(); - - Vec4 pParams0, pParams1; - - if (bBigDownsample) - { - // Use rotated grid + middle sample (~quincunx) - pParams0 = Vec4(s1 * 0.96f, t1 * 0.25f, -s1 * 0.25f, t1 * 0.96f); - pParams1 = Vec4(-s1 * 0.96f, -t1 * 0.25f, s1 * 0.25f, -t1 * 0.96f); - } - else - { - // Use box filtering (faster - can skip bilinear filtering, only 4 taps) - pParams0 = Vec4(-s1, -t1, s1, -t1); - pParams1 = Vec4(s1, t1, -s1, t1); - } - - static CCryNameR pParam0Name("texToTexParams0"); - static CCryNameR pParam1Name("texToTexParams1"); - - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - - int nFilter = bResample ? FILTER_LINEAR : FILTER_POINT; - pSrc->Apply(0, CTexture::GetTexState(STexState(nFilter, true)), EFTT_UNKNOWN, -1, - (bBindMultisampled && gRenDev->m_RP.m_MSAAData.Type) ? SResourceView::DefaultViewMS : SResourceView::DefaultView); // bind as msaa target (if valid) - - DrawFullScreenTri(pDst->GetWidth(), pDst->GetHeight(), 0, srcRegion); - - ShEndPass(); - - // Restore previous viewport - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; -} - -void SD3DPostEffectsUtils::SwapRedBlue([[maybe_unused]] CTexture* pSrc, [[maybe_unused]] CTexture* pDst) -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DPOSTPROCESS_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DPostProcess_cpp) -#endif -} - -void SD3DPostEffectsUtils::DownsampleDepth(CTexture* pSrc, CTexture* pDst, bool bFromSingleChannel) -{ - PROFILE_LABEL_SCOPE("DOWNSAMPLE_DEPTH"); - PROFILE_SHADER_SCOPE; - - if (!pDst) - { - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - uint64 nSaveFlagsShader_RT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - // Get current viewport - int prevVPX, prevVPY, prevVPWidth, prevVPHeight; - rd->GetViewport(&prevVPX, &prevVPY, &prevVPWidth, &prevVPHeight); - - bool bUseDeviceDepth = (pSrc == NULL); - - rd->FX_PushRenderTarget(0, pDst, NULL); - - // Metal Load/Store Actions - rd->FX_SetColorDontCareActions(0, true, false); - rd->FX_SetDepthDontCareActions(0, true, true); - rd->FX_SetStencilDontCareActions(0, true, true); - - int dstWidth = pDst->GetWidth(); - int dstHeight = pDst->GetHeight(); - rd->RT_SetViewport(0, 0, dstWidth, dstHeight); - - if (bUseDeviceDepth) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if (bFromSingleChannel) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - static CCryNameTSCRC pTech("DownsampleDepth"); - ShBeginPass(CShaderMan::s_shPostEffects, pTech, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - rd->FX_SetState(GS_NODEPTHTEST); - - int srcWidth = bUseDeviceDepth ? rd->GetWidth() : pSrc->GetWidth(); - int srcHeight = bUseDeviceDepth ? rd->GetHeight() : pSrc->GetHeight(); - - if (bUseDeviceDepth) - { - rd->m_DevMan.BindSRV(eHWSC_Pixel, &rd->m_pZBufferDepthReadOnlySRV, 0, 1); - } - else - { - SetTexture(pSrc, 0, FILTER_POINT, 1); - } - -#if defined(CRY_USE_METAL) || defined(ANDROID) - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - gRenDev->RT_SetScissor(true, 0, 0, pDst->GetWidth() * vDownscaleFactor.x + 0.5f, pDst->GetHeight() * vDownscaleFactor.y + 0.5f); -#endif - - if (GetShaderLanguage() == eSL_GLES3_0) - { - // There's a bug in Qualcomm OpenGL ES 3.0 drivers that cause the device - // shader compiler to crash if we use "textureSize" in the shader to get the texture dimensions. - Vec4 texSize = Vec4(srcWidth, srcHeight, 0, 0); - static CCryNameR texSizeParam("DownsampleDepth_DepthTex_Dimensions"); - CShaderMan::s_shPostEffects->FXSetPSFloat(texSizeParam, &texSize, 1); - } - - RECT source = { 0, 0, pDst->GetWidth(), pDst->GetHeight() }; - //Round up to even to handle uneven dimensions - dstWidth = (dstWidth + 1) & ~1; - dstHeight = (dstHeight + 1) & ~1; - DrawFullScreenTri(dstWidth, dstHeight, 0.f, &source); - -#if defined(CRY_USE_METAL) || defined(ANDROID) - gRenDev->RT_SetScissor(false, 0, 0, 0, 0); -#endif - - ShEndPass(); - - if (bUseDeviceDepth) - { - D3DShaderResourceView* pNullSRV[1] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Pixel, pNullSRV, 0, 1); - - rd->FX_Commit(); - } - - // Restore previous viewport - rd->FX_PopRenderTarget(0); - rd->RT_SetViewport(prevVPX, prevVPY, prevVPWidth, prevVPHeight); - - rd->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// -void SD3DPostEffectsUtils::DownsampleDepthUsingCompute(CTexture* pSrc, CTexture** pDstArr, bool bFromSingleChannel) -{ - PROFILE_LABEL_SCOPE("DOWNSAMPLE_DEPTHCS"); - PROFILE_SHADER_SCOPE; - - if (!pDstArr || !pDstArr[0]) - { - return; - } - - CTexture* pDst = pDstArr[0]; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - uint64 saveFlagsShader_RT = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - bool useDeviceDepth = (pSrc == NULL); - - rd->RT_SetViewport(0, 0, pDst->GetWidth(), pDst->GetHeight()); - - if (useDeviceDepth) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if (bFromSingleChannel) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - static CCryNameTSCRC pTech("DownsampleDepthCS"); - ShBeginPass(CShaderMan::s_shPostEffects, pTech, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - rd->FX_SetState(GS_NODEPTHTEST); - - int srcWidth = useDeviceDepth ? rd->GetWidth() : pSrc->GetWidth(); - int srcHeight = useDeviceDepth ? rd->GetHeight() : pSrc->GetHeight(); - - if (useDeviceDepth) - { - rd->m_DevMan.BindSRV(eHWSC_Compute, &rd->m_pZBufferDepthReadOnlySRV, 0, 1); - } - else - { - D3DShaderResourceView* pShaderResrouce[1] = { - (pSrc->GetShaderResourceView()), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pShaderResrouce, 0, 1); - } - - static CCryNameR paramSrcSize("SrcTexSizeAndCount"); - Vec4 vParamSrcSize(srcWidth, srcHeight, 2, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSrcSize, &vParamSrcSize, 1); - rd->FX_Commit(); - - D3DUnorderedAccessView* UAVs[2] = { - (pDstArr[0]->GetDeviceUAV()), - (pDstArr[1]->GetDeviceUAV()), - }; - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 2, UAVs, NULL); - - uint32 dispatchSizeX = srcWidth / 8 + (srcWidth % 8 > 0 ? 1 : 0); - uint32 dispatchSizeY = srcHeight / 8 + (srcHeight % 8 > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - ShEndPass(); - rd->m_RP.m_FlagsShader_RT = saveFlagsShader_RT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void SD3DPostEffectsUtils::DownsampleUsingCompute(CTexture* pSrc, CTexture** pDstArr) -{ - AZ_Assert(pSrc && pDstArr[0], "Null textures passed in"); - - const int maxIterations = 3; - - int numIters = 1; - D3DUnorderedAccessView* pUAV[maxIterations]; - pUAV[0] = (pDstArr[0]->GetDeviceUAV()); - - for (int i = 1; i < maxIterations; i++) - { - if (pDstArr[i]) - { - numIters++; - pUAV[i] = (pDstArr[i]->GetDeviceUAV()); - } - else - { - // Need to bind a UAV or Metal will complain... even if not written to. - pUAV[i] = pUAV[0]; - break; - } - } - - PROFILE_LABEL_SCOPE("DOWNSAMPLE_SCENE_CS"); - PROFILE_SHADER_SCOPE; - - CTexture* pSrcRT = pSrc; - - static CCryNameTSCRC pTech("TextureToTextureCS"); - ShBeginPass(CShaderMan::s_shPostEffects, pTech, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - int srcWidth = pSrcRT->GetWidth(); - int srcHeight = pSrcRT->GetHeight(); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - D3DShaderResourceView* pSRV = (pSrcRT->GetShaderResourceView()); - rd->m_DevMan.BindSRV(eHWSC_Compute, &pSRV, 0, 1); - - static CCryNameR param("gNumIterations"); - Vec4 vParam(numIters, 0, 0, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(param, &vParam, 1); - rd->FX_Commit(); - - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 3, pUAV, NULL); - - // Grid dims must match in shader - const uint32 kernelGridX = 8; - const uint32 kernelGridY = 8; - - uint32 dispatchSizeX = srcWidth / kernelGridX + (srcWidth % kernelGridX > 0 ? 1 : 0); - uint32 dispatchSizeY = srcHeight / kernelGridY + (srcHeight % kernelGridY > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - ShEndPass(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::Downsample(CTexture* pSrc, CTexture* pDst, int nSrcW, int nSrcH, int nDstW, int nDstH, EFilterType eFilter, bool bSetTarget) -{ - if (!pSrc) - { - return; - } - - PROFILE_LABEL_SCOPE("DOWNSAMPLE"); - PROFILE_SHADER_SCOPE; - - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2]); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - if (bSetTarget) - { - gcpRendD3D->FX_PushRenderTarget(0, pDst, NULL); - } - gcpRendD3D->RT_SetViewport(0, 0, nDstW, nDstH); - - // Currently only exact multiples supported - Vec2 vSamples(float(nSrcW) / nDstW, float(nSrcH) / nDstH); - const Vec2 vSampleSize(1.f / nSrcW, 1.f / nSrcH); - const Vec2 vPixelSize(1.f / nDstW, 1.f / nDstH); - // Adjust UV space if source rect smaller than texture - const float fClippedRatioX = float(nSrcW) / pSrc->GetWidth(); - const float fClippedRatioY = float(nSrcH) / pSrc->GetHeight(); - - // Base kernel size in pixels - float fBaseKernelSize = 1.f; - // How many lines of border samples to skip - float fBorderSamplesToSkip = 0.f; - - switch (eFilter) - { - default: - case FilterType_Box: - fBaseKernelSize = 1.f; - fBorderSamplesToSkip = 0.f; - break; - case FilterType_Tent: - fBaseKernelSize = 2.f; - fBorderSamplesToSkip = 0.f; - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - break; - case FilterType_Gauss: - // The base kernel for Gaussian filter is 3x3 pixels [-1.5 .. 1.5] - // Samples on the borders are ignored due to small contribution - // so the actual kernel size is N*3 - 2 where N is number of samples per pixel - fBaseKernelSize = 3.f; - fBorderSamplesToSkip = 1.f; - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - break; - case FilterType_Lanczos: - fBaseKernelSize = 3.f; - fBorderSamplesToSkip = 0.f; - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - break; - } - - // Kernel position step - const Vec2 vSampleStep(1.f / vSamples.x, 1.f / vSamples.y); - // The actual kernel radius in pixels - const Vec2 vKernelRadius = 0.5f * Vec2(fBaseKernelSize, fBaseKernelSize) - fBorderSamplesToSkip * vSampleStep; - - // UV offset from pixel center to first (top-left) sample - const Vec2 vFirstSampleOffset(0.5f * vSampleSize.x - vKernelRadius.x * vPixelSize.x, - 0.5f * vSampleSize.y - vKernelRadius.y * vPixelSize.y); - // Kernel position of first (top-left) sample - const Vec2 vFirstSamplePos = -vKernelRadius + 0.5f * vSampleStep; - - static CCryNameTSCRC pTechName("TextureToTextureResampleFilter"); - ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - const Vec4 pParams0(vKernelRadius.x, vKernelRadius.y, fClippedRatioX, fClippedRatioY); - const Vec4 pParams1(vSampleSize.x, vSampleSize.y, vFirstSampleOffset.x, vFirstSampleOffset.y); - const Vec4 pParams2(vSampleStep.x, vSampleStep.y, vFirstSamplePos.x, vFirstSamplePos.y); - - static CCryNameR pParam0Name("texToTexParams0"); - static CCryNameR pParam1Name("texToTexParams1"); - static CCryNameR pParam2Name("texToTexParams2"); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam2Name, &pParams2, 1); - - SetTexture(pSrc, 0, FILTER_NONE); - - DrawFullScreenTri(nDstW, nDstH); - - ShEndPass(); - - // Restore previous viewport - if (bSetTarget) - { - gcpRendD3D->FX_PopRenderTarget(0); - } - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::DownsampleStable(CTexture* pSrcRT, CTexture* pDstRT, bool bKillFireflies) -{ - PROFILE_LABEL_SCOPE("DOWNSAMPLE_STABLE"); - - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - gcpRendD3D->FX_PushRenderTarget(0, pDstRT, NULL); - gcpRendD3D->RT_SetViewport(0, 0, pDstRT->GetWidth(), pDstRT->GetHeight()); - - gcpRendD3D->FX_SetColorDontCareActions(0, true, false); - gcpRendD3D->FX_SetDepthDontCareActions(0, true, true); - gcpRendD3D->FX_SetStencilDontCareActions(0, true, true); - - if (bKillFireflies) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - static CCryNameTSCRC techName("DownsampleStable"); - ShBeginPass(CShaderMan::s_shPostEffects, techName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gcpRendD3D->FX_SetState(GS_NODEPTHTEST); - pSrcRT->Apply(0, CTexture::GetTexState(STexState(FILTER_LINEAR, true))); - - DrawFullScreenTri(pDstRT->GetWidth(), pDstRT->GetHeight()); - - ShEndPass(); - - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::TexBlurIterative(CTexture* pTex, int nIterationsMul, bool bDilate, CTexture* pBlurTmp) -{ - if (!pTex) - { - return; - } - - SDynTexture* tpBlurTemp = 0; - - if (!pBlurTmp) - { - tpBlurTemp = new SDynTexture(pTex->GetWidth(), pTex->GetHeight(), pTex->GetDstFormat(), eTT_2D, FT_STATE_CLAMP | FT_USAGE_RENDERTARGET, "TempBlurRT"); - if (tpBlurTemp) - { - tpBlurTemp->Update(pTex->GetWidth(), pTex->GetHeight()); - } - - if (!tpBlurTemp || !tpBlurTemp->m_pTexture) - { - SAFE_DELETE(tpBlurTemp); - return; - } - } - - PROFILE_LABEL_SCOPE("TEXBLUR_16TAPS"); - PROFILE_SHADER_SCOPE; - - CTexture* pTempRT = pBlurTmp ? pBlurTmp : tpBlurTemp->m_pTexture; - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - // Iterative blur (aka Kawase): 4 taps, 16 taps, 64 taps, 256 taps, etc - uint64 nFlagsShaderRT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1]); - - //// Dilate - use 2 passes, horizontal+vertical - //if( bDilate ) - //{ - // gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - // nIterationsMul = 1; - //} - - for (int i = 1; i <= nIterationsMul; ++i) - { - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // 1st iteration (4 taps) - - gcpRendD3D->FX_PushRenderTarget(0, pTempRT, NULL); - gcpRendD3D->FX_SetActiveRenderTargets(false);// Avoiding invalid d3d error (due to deferred rt setup, when ping-pong'ing between RTs we can bump into RTs still bound when binding it as a SRV) - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - // only regular gaussian blur supporting masking - static CCryNameTSCRC pTechName("Blur4Taps"); - - uint32 nPasses; - CShaderMan::s_shPostEffects->FXSetTechnique(pTechName); - CShaderMan::s_shPostEffects->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - // setup texture offsets, for texture sampling - // Get sample size ratio (based on empirical "best look" approach) - float fSampleSize = 1.0f * ((float) i);//((float)pTex->GetWidth()/(float)pTex->GetWidth()) * 0.5f; - - // Set samples position - float s1 = fSampleSize / (float) pTex->GetWidth(); // 2.0 better results on lower res images resizing - float t1 = fSampleSize / (float) pTex->GetHeight(); - - // Use rotated grid - Vec4 pParams0 = Vec4(s1 * 0.96f, t1 * 0.25f, -s1 * 0.25f, t1 * 0.96f);//Vec4(-s1, -t1, s1, -t1); - Vec4 pParams1 = Vec4(-s1 * 0.96f, -t1 * 0.25f, s1 * 0.25f, -t1 * 0.96f);//Vec4(s1, t1, -s1, t1); - - static CCryNameR pParam0Name("texToTexParams0"); - static CCryNameR pParam1Name("texToTexParams1"); - - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - - CShaderMan::s_shPostEffects->FXBeginPass(0); - - SetTexture(pTex, 0, FILTER_LINEAR); - - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - CShaderMan::s_shPostEffects->FXEnd(); - - gcpRendD3D->FX_PopRenderTarget(0); - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // 2nd iteration (4 x 4 taps) - if (bDilate) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - - gcpRendD3D->FX_PushRenderTarget(0, pTex, NULL); - gcpRendD3D->FX_SetActiveRenderTargets(false);// Avoiding invalid d3d error (due to deferred rt setup, when ping-pong'ing between RTs we can bump into RTs still bound when binding it as a SRV) - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXSetTechnique(pTechName); - CShaderMan::s_shPostEffects->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - // increase kernel size for second iteration - fSampleSize = 2.0 * ((float) i); - // Set samples position - s1 = fSampleSize / (float) pTex->GetWidth(); // 2.0 better results on lower res images resizing - t1 = fSampleSize / (float) pTex->GetHeight(); - - // Use rotated grid - pParams0 = Vec4(s1 * 0.96f, t1 * 0.25f, -s1 * 0.25f, t1 * 0.96f);//Vec4(-s1, -t1, s1, -t1); - pParams1 = Vec4(-s1 * 0.96f, -t1 * 0.25f, s1 * 0.25f, -t1 * 0.96f);//Vec4(s1, t1, -s1, t1); - - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - - CShaderMan::s_shPostEffects->FXBeginPass(0); - - SetTexture(pTempRT, 0, FILTER_LINEAR); - - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - CShaderMan::s_shPostEffects->FXEnd(); - - gcpRendD3D->FX_PopRenderTarget(0); - } - - gRenDev->m_RP.m_FlagsShader_RT = nFlagsShaderRT; - - // Restore previous viewport - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - SAFE_DELETE(tpBlurTemp); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::TexBlurDirectional(CTexture* pTex, const Vec2& vDir, int nIterationsMul, CTexture* pBlurTmp) -{ - if (!pTex) - { - return; - } - - SDynTexture* tpBlurTemp = 0; - if (!pBlurTmp) - { - tpBlurTemp = new SDynTexture(pTex->GetWidth(), pTex->GetHeight(), pTex->GetDstFormat(), eTT_2D, FT_STATE_CLAMP | FT_USAGE_RENDERTARGET, "TempBlurRT"); - if (tpBlurTemp) - { - tpBlurTemp->Update(pTex->GetWidth(), pTex->GetHeight()); - } - - if (!tpBlurTemp || !tpBlurTemp->m_pTexture) - { - SAFE_DELETE(tpBlurTemp); - return; - } - } - - PROFILE_LABEL_SCOPE("TEXBLUR_DIRECTIONAL"); - PROFILE_SHADER_SCOPE; - - CTexture* pTempRT = pBlurTmp; - if (!pBlurTmp) - { - pTempRT = tpBlurTemp->m_pTexture; - } - - static CCryNameTSCRC pTechName("BlurDirectional"); - static CCryNameR pParam0Name("texToTexParams0"); - static CCryNameR pParam1Name("texToTexParams1"); - static CCryNameR pParam2Name("texToTexParams2"); - static CCryNameR pParam3Name("texToTexParams3"); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - // Iterative directional blur: 1 iter: 8 taps, 64 taps, 2 iter: 512 taps, 4096 taps... - float fSampleScale = 1.0f; - for (int i = nIterationsMul; i >= 1; --i) - { - // 1st iteration (4 taps) - - gcpRendD3D->FX_PushRenderTarget(0, pTempRT, NULL); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - uint32 nPasses; - CShaderMan::s_shPostEffects->FXSetTechnique(pTechName); - CShaderMan::s_shPostEffects->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - float fSampleSize = fSampleScale; - - // Set samples position - float s1 = fSampleSize / (float) pTex->GetWidth(); // 2.0 better results on lower res images resizing - float t1 = fSampleSize / (float) pTex->GetHeight(); - Vec2 vBlurDir; - vBlurDir.x = s1 * vDir.x; - vBlurDir.y = t1 * vDir.y; - - // Use rotated grid - Vec4 pParams0 = Vec4(-vBlurDir.x * 4.0f, -vBlurDir.y * 4.0f, -vBlurDir.x * 3.0f, -vBlurDir.y * 3.0f); - Vec4 pParams1 = Vec4(-vBlurDir.x * 2.0f, -vBlurDir.y * 2.0f, -vBlurDir.x, -vBlurDir.y); - Vec4 pParams2 = Vec4(vBlurDir.x * 2.0f, vBlurDir.y * 2.0f, vBlurDir.x, vBlurDir.y); - Vec4 pParams3 = Vec4(vBlurDir.x * 4.0f, vBlurDir.y * 4.0f, vBlurDir.x * 3.0f, vBlurDir.y * 3.0f); - - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam2Name, &pParams2, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam3Name, &pParams3, 1); - - CShaderMan::s_shPostEffects->FXBeginPass(0); - - SetTexture(pTex, 0, FILTER_LINEAR, TADDR_BORDER); - SetTexture(CTextureManager::Instance()->GetDefaultTexture("ScreenNoiseMap"), 1, FILTER_POINT, 0); - - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - CShaderMan::s_shPostEffects->FXEnd(); - - gcpRendD3D->FX_PopRenderTarget(0); - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // 2nd iteration (4 x 4 taps) - - gcpRendD3D->FX_PushRenderTarget(0, pTex, NULL); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXSetTechnique(pTechName); - CShaderMan::s_shPostEffects->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - fSampleScale *= 0.75f; - - fSampleSize = fSampleScale; - s1 = fSampleSize / (float) pTex->GetWidth(); // 2.0 better results on lower res images resizing - t1 = fSampleSize / (float) pTex->GetHeight(); - vBlurDir.x = vDir.x * s1; - vBlurDir.y = vDir.y * t1; - - pParams0 = Vec4(-vBlurDir.x * 4.0f, -vBlurDir.y * 4.0f, -vBlurDir.x * 3.0f, -vBlurDir.y * 3.0f); - pParams1 = Vec4(-vBlurDir.x * 2.0f, -vBlurDir.y * 2.0f, -vBlurDir.x, -vBlurDir.y); - pParams2 = Vec4(vBlurDir.x, vBlurDir.y, vBlurDir.x * 2.0f, vBlurDir.y * 2.0f); - pParams3 = Vec4(vBlurDir.x * 3.0f, vBlurDir.y * 3.0f, vBlurDir.x * 4.0f, vBlurDir.y * 4.0f); - - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam2Name, &pParams2, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam3Name, &pParams3, 1); - - CShaderMan::s_shPostEffects->FXBeginPass(0); - - SetTexture(pTempRT, 0, FILTER_LINEAR, TADDR_BORDER); - SetTexture(CTextureManager::Instance()->GetDefaultTexture("ScreenNoiseMap"), 1, FILTER_POINT, 0); - - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - CShaderMan::s_shPostEffects->FXEnd(); - - gcpRendD3D->FX_PopRenderTarget(0); - - fSampleScale *= 0.5f; - } - - // Restore previous viewport - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - SAFE_DELETE(tpBlurTemp); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::TexBlurGaussian(CTexture* pTex, [[maybe_unused]] int nAmount, float fScale, float fDistribution, bool bAlphaOnly, CTexture* pMask, bool bSRGB, CTexture* pBlurTmp) -{ - if (!pTex) - { - return; - } - - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2]); - - PROFILE_LABEL_SCOPE("TEXBLUR_GAUSSIAN"); - - if (bSRGB) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - CTexture* pTempRT = pBlurTmp; - SDynTexture* tpBlurTemp = 0; - if (!pBlurTmp) - { - tpBlurTemp = new SDynTexture(pTex->GetWidth(), pTex->GetHeight(), pTex->GetDstFormat(), eTT_2D, FT_STATE_CLAMP | FT_USAGE_RENDERTARGET, "TempBlurRT"); - if (tpBlurTemp) - { - tpBlurTemp->Update(pTex->GetWidth(), pTex->GetHeight()); - } - - if (!tpBlurTemp || !tpBlurTemp->m_pTexture) - { - SAFE_DELETE(tpBlurTemp); - return; - } - - pTempRT = tpBlurTemp->m_pTexture; - } - - PROFILE_SHADER_SCOPE; - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - Vec4 vWhite(1.0f, 1.0f, 1.0f, 1.0f); - - // TODO: Make test with Martin's idea about the horizontal blur pass with vertical offset. - - // only regular gaussian blur supporting masking - static CCryNameTSCRC pTechName("GaussBlurBilinear"); - static CCryNameTSCRC pTechNameMasked("MaskedGaussBlurBilinear"); - static CCryNameTSCRC pTechName1("GaussAlphaBlur"); - - //ShBeginPass(CShaderMan::m_shPostEffects, , FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - uint32 nPasses; - CShaderMan::s_shPostEffects->FXSetTechnique((!bAlphaOnly) ? ((pMask) ? pTechNameMasked : pTechName) : pTechName1); - CShaderMan::s_shPostEffects->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_NODEPTHTEST); - - // setup texture offsets, for texture sampling - float s1 = 1.0f / (float) pTex->GetWidth(); - float t1 = 1.0f / (float) pTex->GetHeight(); - - // Horizontal/Vertical pass params - const int nSamples = 16; - int nHalfSamples = (nSamples >> 1); - - Vec4 pHParams[32], pVParams[32], pWeightsPS[32]; - float pWeights[32], fWeightSum = 0; - - memset(pWeights, 0, sizeof(pWeights)); - - int s; - for (s = 0; s < nSamples; ++s) - { - if (fDistribution != 0.0f) - { - pWeights[s] = GaussianDistribution1D(s - nHalfSamples, fDistribution); - } - else - { - pWeights[s] = 0.0f; - } - fWeightSum += pWeights[s]; - } - - // normalize weights - for (s = 0; s < nSamples; ++s) - { - pWeights[s] /= fWeightSum; - } - - // set bilinear offsets - for (s = 0; s < nHalfSamples; ++s) - { - float off_a = pWeights[s * 2]; - float off_b = ((s * 2 + 1) <= nSamples - 1) ? pWeights[s * 2 + 1] : 0; - float a_plus_b = (off_a + off_b); - if (a_plus_b == 0) - { - a_plus_b = 1.0f; - } - float offset = off_b / a_plus_b; - - pWeights[s] = off_a + off_b; - pWeights[s] *= fScale; - pWeightsPS[s] = vWhite * pWeights[s]; - - float fCurrOffset = (float) s * 2 + offset - nHalfSamples; - pHParams[s] = Vec4(s1 * fCurrOffset, 0, 0, 0); - pVParams[s] = Vec4(0, t1 * fCurrOffset, 0, 0); - } - - - STexState sTexState = STexState(FILTER_LINEAR, true); - static CCryNameR clampTCName("clampTC"); - static CCryNameR pParam0Name("psWeights"); - static CCryNameR pParam1Name("PI_psOffsets"); - - Vec4 clampTC(0.0f, 1.0f, 0.0f, 1.0f); - if (pTex->GetWidth() == gcpRendD3D->GetWidth() && pTex->GetHeight() == gcpRendD3D->GetHeight()) - { - // clamp manually in shader since texture clamp won't apply for smaller viewport - clampTC = Vec4(0.0f, gRenDev->m_RP.m_CurDownscaleFactor.x, 0.0f, gRenDev->m_RP.m_CurDownscaleFactor.y); - } - - //SetTexture(pTex, 0, FILTER_LINEAR); - CShaderMan::s_shPostEffects->FXSetPSFloat(clampTCName, &clampTC, 1); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, pWeightsPS, nHalfSamples); - - //for(int p(1); p<= nAmount; ++p) - { - //Horizontal - - - gcpRendD3D->FX_PushRenderTarget(0, pTempRT, NULL); - gcpRendD3D->FX_SetActiveRenderTargets(false);// Avoiding invalid d3d error (due to deferred rt setup, when ping-pong'ing between RTs we can bump into RTs still bound when binding it as a SRV) - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - // !force updating constants per-pass! (dx10..) - CShaderMan::s_shPostEffects->FXBeginPass(0); - - pTex->Apply(0, CTexture::GetTexState(sTexState)); - if (pMask) - { - pMask->Apply(1, CTexture::GetTexState(sTexState)); - } - CShaderMan::s_shPostEffects->FXSetVSFloat(pParam1Name, pHParams, nHalfSamples); - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - - gcpRendD3D->FX_PopRenderTarget(0); - - //Vertical - gcpRendD3D->FX_PushRenderTarget(0, pTex, NULL); - gcpRendD3D->FX_SetActiveRenderTargets(false);// Avoiding invalid d3d error (due to deferred rt setup, when ping-pong'ing between RTs we can bump into RTs still bound when binding it as a SRV) - gcpRendD3D->RT_SetViewport(0, 0, pTex->GetWidth(), pTex->GetHeight()); - - // !force updating constants per-pass! (dx10..) - CShaderMan::s_shPostEffects->FXBeginPass(0); - - CShaderMan::s_shPostEffects->FXSetVSFloat(pParam1Name, pVParams, nHalfSamples); - pTempRT->Apply(0, CTexture::GetTexState(sTexState)); - if (pMask) - { - pMask->Apply(1, CTexture::GetTexState(sTexState)); - } - DrawFullScreenTri(pTex->GetWidth(), pTex->GetHeight()); - - CShaderMan::s_shPostEffects->FXEndPass(); - - gcpRendD3D->FX_PopRenderTarget(0); - } - - CShaderMan::s_shPostEffects->FXEnd(); - - // ShEndPass( ); - - // Restore previous viewport - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - //release dyntexture - SAFE_DELETE(tpBlurTemp); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::BeginStencilPrePass(const bool bAddToStencil, const bool bDebug, const bool bResetStencil, const uint8 nStencilRefReset) -{ - if (!bAddToStencil && !bResetStencil) - { - gcpRendD3D->m_nStencilMaskRef++; - } - - if (gcpRendD3D->m_nStencilMaskRef > STENC_MAX_REF) - { - gcpRendD3D->EF_ClearTargetsImmediately(FRT_CLEAR_STENCIL); - gcpRendD3D->m_nStencilMaskRef = 1; - } - - gcpRendD3D->FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_REPLACE) | - STENCOP_ZFAIL(FSS_STENCOP_REPLACE) | - STENCOP_PASS(FSS_STENCOP_REPLACE), - bResetStencil ? nStencilRefReset : gcpRendD3D->m_nStencilMaskRef, 0xFFFFFFFF, 0xFFFF - ); - - gcpRendD3D->FX_SetState(GS_STENCIL | GS_NODEPTHTEST | (!bDebug ? GS_COLMASK_NONE : 0)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::EndStencilPrePass() -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::SetupStencilStates(int32 nStFunc) -{ - if (nStFunc < 0) - { - return; - } - - gcpRendD3D->FX_SetStencilState( - STENC_FUNC(nStFunc) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_PASS(FSS_STENCOP_KEEP), - gcpRendD3D->m_nStencilMaskRef, 0xFFFFFFFF, 0xFFFFFFFF); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::SetFillModeSolid(bool bEnable) -{ - if (bEnable) - { - if (gcpRendD3D->GetWireframeMode() > R_SOLID_MODE) - { - SStateRaster RS = gcpRendD3D->m_StatesRS[gcpRendD3D->m_nCurStateRS]; - RS.Desc.FillMode = D3D11_FILL_SOLID; - gcpRendD3D->SetRasterState(&RS); - } - } - else - { - if (gcpRendD3D->GetWireframeMode() == R_WIREFRAME_MODE) - { - SStateRaster RS = gcpRendD3D->m_StatesRS[gcpRendD3D->m_nCurStateRS]; - RS.Desc.FillMode = D3D11_FILL_WIREFRAME; - gcpRendD3D->SetRasterState(&RS); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void SD3DPostEffectsUtils::DrawQuadFS(CShader* pShader, bool bOutputCamVec, int nWidth, int nHeight, float x0, float y0, float x1, float y1, float z) -{ - const Vec4 cQuadConst(1.0f / (float) nWidth, 1.0f / (float) nHeight, z, 1.0f); - pShader->FXSetVSFloat(m_pQuadParams, &cQuadConst, 1); - - const Vec4 cQuadPosConst(x0, y0, x1, y1); - pShader->FXSetVSFloat(m_pQuadPosParams, &cQuadPosConst, 1); - - if (bOutputCamVec) - { - UpdateFrustumCorners(); - const Vec4 vLT(m_vLT, 1.0f); - pShader->FXSetVSFloat(m_pFrustumLTParams, &vLT, 1); - const Vec4 vLB(m_vLB, 1.0f); - pShader->FXSetVSFloat(m_pFrustumLBParams, &vLB, 1); - const Vec4 vRT(m_vRT, 1.0f); - pShader->FXSetVSFloat(m_pFrustumRTParams, &vRT, 1); - const Vec4 vRB(m_vRB, 1.0f); - pShader->FXSetVSFloat(m_pFrustumRBParams, &vRB, 1); - } - - gcpRendD3D->FX_Commit(); - if (!FAILED(gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - gcpRendD3D->FX_SetVStream(0, gcpRendD3D->m_pQuadVB, 0, sizeof(SVF_P3F_C4B_T2F)); - gcpRendD3D->FX_DrawPrimitive(eptTriangleStrip, 0, gcpRendD3D->m_nQuadVBSize); - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_PostProcessScene(bool bEnable) -{ - AZ_TRACE_METHOD(); - if (!gcpRendD3D) - { - return false; - } - - if (bEnable) - { - PostProcessUtils().Create(); - } - else - if (!CRenderer::CV_r_PostProcess && CTexture::s_ptexBackBuffer) - { - PostProcessUtils().Release(); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::GetReprojectionMatrix(Matrix44A& matReproj, - const Matrix44A& matView, - const Matrix44A& matProj, - const Matrix44A& matPrevView, - const Matrix44A& matPrevProj, - float fFarPlane) const -{ - // Current camera screen-space to projection-space - const Matrix44A matSc2Pc - (2.f, 0.f, -1.f, 0.f, - 0.f, 2.f, -1.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f / fFarPlane); - - // Current camera view-space to projection-space - const Matrix44A matVc2Pc - (matProj.m00, 0.f, 0.f, 0.f, - 0.f, matProj.m11, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); - - // Current camera projection-space to world-space - const Matrix44A matPc2Wc = (matVc2Pc * matView).GetInverted(); - - // Previous camera view-space to projection-space - const Matrix44A matVp2Pp - (matPrevProj.m00, 0.f, 0.f, 0.f, - 0.f, matPrevProj.m11, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); - - // Previous camera world-space to projection-space - const Matrix44A matWp2Pp = matVp2Pp * matPrevView; - - // Previous camera projection-space to texture-space - const Matrix44A matPp2Tp - (0.5f, 0.f, 0.5f, 0.f, - 0.f, 0.5f, 0.5f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); - - // Final reprojection matrix (from current camera screen-space to previous camera texture-space) - matReproj = matPp2Tp * matWp2Pp * matPc2Wc * matSc2Pc; -} - -void CD3D9Renderer::UpdatePreviousFrameMatrices() -{ - PreviousFrameMatrixSet& matrices = m_PreviousFrameMatrixSets[m_CurViewportID][m_CurRenderEye]; - - matrices.m_WorldViewPosition = GetViewParameters().vOrigin; - matrices.m_ViewMatrix = m_CameraMatrix; - matrices.m_ViewNoTranslateMatrix = m_CameraZeroMatrix[m_RP.m_nProcessThreadID]; - matrices.m_ProjMatrix = m_ProjNoJitterMatrix; - - // Use next frame jitter so that motion vector calculation is stable with jitter. While it would - // be best to remove jitter entirely, the shaders are already computing the clip space position of - // the current fragment with jitter, so this a pragmatic compromise. - SubpixelJitter::Sample sample = SubpixelJitter::EvaluateSample(SPostEffectsUtils::m_iFrameCounter + 1, (SubpixelJitter::Pattern)CV_r_AntialiasingTAAJitterPattern); - - Vec2 subpixelOffsetClipSpace; - subpixelOffsetClipSpace.x = ((sample.m_subpixelOffset.x * 2.0) / (float)m_width) / m_RP.m_CurDownscaleFactor.x; - subpixelOffsetClipSpace.y = ((sample.m_subpixelOffset.y * 2.0) / (float)m_height) / m_RP.m_CurDownscaleFactor.y; - - matrices.m_ProjMatrix.m20 += subpixelOffsetClipSpace.x; - matrices.m_ProjMatrix.m21 += subpixelOffsetClipSpace.y; - - matrices.m_ViewProjMatrix = m_ViewProjNoJitterMatrix; - matrices.m_ViewProjNoTranslateMatrix = m_CameraZeroMatrix[m_RP.m_nProcessThreadID] * matrices.m_ProjMatrix; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -void CPostEffectsMgr::Begin() -{ - PostProcessUtils().Log("### POST-PROCESSING BEGINS ### "); - PostProcessUtils().m_pTimer = gEnv->pTimer; - static EShaderQuality nPrevShaderQuality = eSQ_Low; - static ERenderQuality nPrevRenderQuality = eRQ_Low; - - EShaderQuality nShaderQuality = (EShaderQuality) gcpRendD3D->EF_GetShaderQuality(eST_PostProcess); - ERenderQuality nRenderQuality = gRenDev->m_RP.m_eQuality; - if (nPrevShaderQuality != nShaderQuality || nPrevRenderQuality != nRenderQuality) - { - CPostEffectsMgr::Reset(true); - nPrevShaderQuality = nShaderQuality; - nPrevRenderQuality = nRenderQuality; - } - - gcpRendD3D->ResetToDefault(); - - SPostEffectsUtils::m_pCurDepthSurface = &gcpRendD3D->m_DepthBufferOrig; - - gcpRendD3D->RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight()); - - SPostEffectsUtils::m_fWaterLevel = gRenDev->m_p3DEngineCommon.m_OceanInfo.m_fWaterLevel; - - PostProcessUtils().SetFillModeSolid(true); - PostProcessUtils().UpdateOverscanBorderAspectRatio(); -} - -void CPostEffectsMgr::End() -{ - gcpRendD3D->RT_SetViewport(PostProcessUtils().m_pScreenRect.left, PostProcessUtils().m_pScreenRect.top, PostProcessUtils().m_pScreenRect.right, PostProcessUtils().m_pScreenRect.bottom); - - gcpRendD3D->FX_ResetPipe(); - - PostProcessUtils().SetFillModeSolid(false); - - const uint32 nThreadID = gRenDev->m_RP.m_nProcessThreadID; -#if !defined(NDEBUG) - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0); -#endif - - gcpRendD3D->UpdatePreviousFrameMatrices(); - - const int kFloatMaxContinousInt = 0x1000000; // 2^24 - const bool bStereo = gcpRendD3D->GetS3DRend().IsStereoEnabled(); - if (!bStereo || (bStereo && gRenDev->m_CurRenderEye == STEREO_EYE_RIGHT)) - { - SPostEffectsUtils::m_iFrameCounter = (SPostEffectsUtils::m_iFrameCounter + 1) % kFloatMaxContinousInt; - } - - PostProcessUtils().Log("### POST-PROCESSING ENDS ### "); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CREPostProcess:: mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - CPostEffectsMgr* pPostMgr = PostEffectMgr(); - IF (!gcpRendD3D || !CRenderer::CV_r_PostProcess || pPostMgr->GetEffects().empty() || gcpRendD3D->GetWireframeMode() > R_SOLID_MODE, 0) - { - return 0; - } - - // Skip hdr/post processing when rendering different camera views - if ((gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_MIRRORCULL) || (gcpRendD3D->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN)) - { - return 0; - } - - if (gcpRendD3D->m_bDeviceLost) - { - return 0; - } - - IF (!CShaderMan::s_shPostEffects, 0) - { - return 0; - } - - IF (!CTexture::IsTextureExist(CTexture::s_ptexBackBuffer), 0) - { - return 0; - } - - IF (!CTexture::IsTextureExist(CTexture::s_ptexSceneTarget), 0) - { - return 0; - } - - PROFILE_LABEL_SCOPE("POST EFFECTS"); - - pPostMgr->Begin(); - - gcpRendD3D->FX_ApplyShaderQuality(eST_PostProcess); - - for (CPostEffectItor pItor = pPostMgr->GetEffects().begin(), pItorEnd = pPostMgr->GetEffects().end(); pItor != pItorEnd; ++pItor) - { - CPostEffect* pCurrEffect = (*pItor); - if (pCurrEffect->GetRenderFlags() & PSP_REQUIRES_UPDATE) - { - pCurrEffect->Update(); - } - } - -#ifndef _RELEASE - CPostEffectDebugVec& activeEffects = pPostMgr->GetActiveEffectsDebug(); - CPostEffectDebugVec& activeParams = pPostMgr->GetActiveEffectsParamsDebug(); -#endif - - AZStd::vector effectsToRender; - for (CPostEffectItor pItor = pPostMgr->GetEffects().begin(), pItorEnd = pPostMgr->GetEffects().end(); pItor != pItorEnd; ++pItor) - { - CPostEffect* effectToPreprocess = (*pItor); - if (effectToPreprocess->Preprocess()) - { - effectsToRender.push_back(effectToPreprocess); - } - } - - for (auto effectIter = effectsToRender.begin(); effectIter != effectsToRender.end(); ++effectIter) - { - CPostEffect* currentEffect = (*effectIter); - uint32 nRenderFlags = currentEffect->GetRenderFlags(); - if (nRenderFlags & PSP_UPDATE_BACKBUFFER) - { - PostProcessUtils().CopyScreenToTexture(CTexture::s_ptexBackBuffer); - } - if (nRenderFlags & PSP_UPDATE_SCENE_SPECULAR) - { - bool optimizeRT = CRenderer::CV_r_SlimGBuffer == 1; - // When optimization is on, we use a single channel format texture for specular. This copy requires full RGBA so use normal map render target instead. - PostProcessUtils().CopyScreenToTexture(optimizeRT ? CTexture::s_ptexSceneNormalsMap : CTexture::s_ptexSceneSpecular); - - } -# ifndef _RELEASE - SPostEffectsDebugInfo* pDebugInfo = NULL; - for (uint32 i = 0, nNumEffects = activeEffects.size(); i < nNumEffects; ++i) - { - pDebugInfo = &activeEffects[i]; - if (pDebugInfo && pDebugInfo->pEffect == currentEffect) - { - pDebugInfo->fTimeOut = POSTSEFFECTS_DEBUGINFO_TIMEOUT; - break; - } - pDebugInfo = NULL; - } - if (pDebugInfo == NULL) - { - activeEffects.push_back(SPostEffectsDebugInfo(currentEffect)); - } -#endif - if (CRenderer::CV_r_SkipNativeUpscale > 0 && AZStd::next(effectIter) == effectsToRender.end()) - { - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->RT_SetViewport(0,0, gcpRendD3D->GetNativeWidth(), gcpRendD3D->GetNativeHeight()); - gcpRendD3D->FX_SetRenderTarget(0, gcpRendD3D->GetBackBuffer(), &gcpRendD3D->m_DepthBufferOrigMSAA); - gcpRendD3D->FX_SetActiveRenderTargets(); - } - currentEffect->Render(); - } - -# ifndef _RELEASE - if (CRenderer::CV_r_AntialiasingModeDebug > 0) - { - float mx = CTexture::s_ptexBackBuffer->GetWidth() >> 1, my = CTexture::s_ptexBackBuffer->GetHeight() >> 1; - AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero(); - AzFramework::InputSystemCursorRequestBus::EventResult(systemCursorPositionNormalized, - AzFramework::InputDeviceMouse::Id, - &AzFramework::InputSystemCursorRequests::GetSystemCursorPositionNormalized); - mx = systemCursorPositionNormalized.GetX() * gEnv->pRenderer->GetWidth(); - my = systemCursorPositionNormalized.GetY() * gEnv->pRenderer->GetHeight(); - - PostProcessUtils().CopyScreenToTexture(CTexture::s_ptexBackBuffer); - static CCryNameTSCRC pszTechName("DebugPostAA"); - GetUtils().ShBeginPass(CShaderMan::s_shPostAA, pszTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - gcpRendD3D->SetCullMode(R_CULL_NONE); - gcpRendD3D->FX_SetState(GS_NODEPTHTEST); - const Vec4 vDebugParams(mx, my, 1.f, max(1.0f, (float) CRenderer::CV_r_AntialiasingModeDebug)); - static CCryNameR pszDebugParams("vDebugParams"); - CShaderMan::s_shPostAA->FXSetPSFloat(pszDebugParams, &vDebugParams, 1); - GetUtils().SetTexture(CTexture::s_ptexBackBuffer, 0, FILTER_POINT); - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexBackBuffer->GetWidth(), CTexture::s_ptexBackBuffer->GetHeight()); - GetUtils().ShEndPass(); - } - - if (!activeEffects.empty() && CRenderer::CV_r_PostProcess >= 2) // Debug output for active post effects - { - SDrawTextInfo pDrawTexInfo; - if (CRenderer::CV_r_PostProcess >= 2) - { - int nPosY = 20; - pDrawTexInfo.color[0] = pDrawTexInfo.color[2] = 0.0f; - pDrawTexInfo.color[1] = 1.0f; - gcpRendD3D->Draw2dText(30, nPosY += 15, "Active post effects:", pDrawTexInfo); - - pDrawTexInfo.color[0] = pDrawTexInfo.color[1] = pDrawTexInfo.color[2] = 1.0f; - for (uint32 i = 0, nNumEffects = activeEffects.size(); i < nNumEffects; ++i) - { - SPostEffectsDebugInfo& debugInfo = activeEffects[i]; - if (debugInfo.fTimeOut > 0.0f) - { - gcpRendD3D->Draw2dText(30, nPosY += 10, debugInfo.pEffect->GetName(), pDrawTexInfo); - } - debugInfo.fTimeOut -= gEnv->pTimer->GetFrameTime(); - } - } - - if (CRenderer::CV_r_PostProcess == 3) - { - StringEffectMap* pEffectsParamsUpdated = pPostMgr->GetDebugParamsUsedInFrame(); - if (pEffectsParamsUpdated) - { - if (!pEffectsParamsUpdated->empty()) - { - StringEffectMapItor pEnd = pEffectsParamsUpdated->end(); - for (StringEffectMapItor pItor = pEffectsParamsUpdated->begin(); pItor != pEnd; ++pItor) - { - SPostEffectsDebugInfo* pDebugInfo = NULL; - for (uint32 p = 0, nNumParams = activeParams.size(); p < nNumParams; ++p) - { - pDebugInfo = &activeParams[p]; - if (pDebugInfo && pDebugInfo->szParamName == (pItor->first)) - { - pDebugInfo->fTimeOut = POSTSEFFECTS_DEBUGINFO_TIMEOUT; - break; - } - pDebugInfo = NULL; - } - if (pDebugInfo == NULL) - { - activeParams.push_back(SPostEffectsDebugInfo((pItor->first), (pItor->second != 0) ? pItor->second->GetParam() : 0.0f)); - } - } - pEffectsParamsUpdated->clear(); - } - - int nPosX = 250, nPosY = 5; - pDrawTexInfo.color[0] = pDrawTexInfo.color[2] = 0.0f; - pDrawTexInfo.color[1] = 1.0f; - gcpRendD3D->Draw2dText(nPosX, nPosY += 15, "Frame parameters:", pDrawTexInfo); - - pDrawTexInfo.color[0] = pDrawTexInfo.color[1] = pDrawTexInfo.color[2] = 1.0f; - for (uint32 p = 0, nNumParams = activeParams.size(); p < nNumParams; ++p) - { - SPostEffectsDebugInfo& debugInfo = activeParams[p]; - if (debugInfo.fTimeOut > 0.0f) - { - char pNameAndValue[128]; - sprintf_s(pNameAndValue, "%s: %.4f\n", debugInfo.szParamName.c_str(), debugInfo.fParamVal); - gcpRendD3D->Draw2dText(nPosX, nPosY += 10, pNameAndValue, pDrawTexInfo); - } - debugInfo.fTimeOut -= gEnv->pTimer->GetFrameTime(); - } - } - } - } -#endif - - pPostMgr->End(); - - return 1; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.h deleted file mode 100644 index e15b551ee3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DPostProcess.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _D3DPOSTPROCESS_H_ -#define _D3DPOSTPROCESS_H_ - -#include "../Common/PostProcess/PostEffects.h" - -struct SD3DPostEffectsUtils - : public SPostEffectsUtils -{ - // friend class CD3D9Renderer; - -public: - - enum EFilterType - { - FilterType_Box, - FilterType_Tent, - FilterType_Gauss, - FilterType_Lanczos, - }; - - virtual void CopyTextureToScreen(CTexture*& pSrc, const RECT* srcRegion = NULL, const int filterMode = -1, bool sRGBLookup = false); - virtual void CopyScreenToTexture(CTexture*& pDst, const RECT* srcRegion = NULL); - virtual void StretchRect(CTexture* pSrc, CTexture*& pDst, bool bClearAlpha = false, bool bDecodeSrcRGBK = false, bool bEncodeDstRGBK = false, bool bBigDownsample = false, EDepthDownsample depthDownsampleMode = eDepthDownsample_None, bool bBindMultisampled = false, const RECT* srcRegion = NULL); - void SwapRedBlue(CTexture* pSrc, CTexture* pDst); - virtual void TexBlurIterative(CTexture* pTex, int nIterationsMul = 1, bool bDilate = false, CTexture* pBlurTmp = 0); // 2 terations minimum (src => temp => src) - virtual void TexBlurGaussian(CTexture* pTex, int nAmount, float fScale, float fDistribution, bool bAlphaOnly, CTexture* pMask = 0, bool bSRGB = false, CTexture* pBlurTmp = 0); - virtual void TexBlurDirectional(CTexture* pTex, const Vec2& vDir, int nIterationsMul = 1, CTexture* pBlurTmp = 0); // 2 terations minimum (src => temp => src) - virtual void DrawQuadFS(CShader* pShader, bool bOutputCamVec, int nWidth, int nHeight, float x0 = 0, float y0 = 0, float x1 = 1, float y1 = 1, float z = 0); - - // Begins drawing a stencil pre-pass mask - void BeginStencilPrePass(const bool bAddToStencil = false, const bool bDebug = false, const bool bResetStencil = false, const uint8 nStencilRefReset = 0); - // Ends drawing a stencil pre-pass mask - void EndStencilPrePass(); - // Setup render states for passes using stencil masks - void SetupStencilStates(int32 nStFunc); - - // Override fill mode (wireframe/point) with solid mode - void SetFillModeSolid(bool bEnable); - - // Downsample source to target using specified filter - // If bSetTarget is not set then destination target is ignored and currently set render target is used instead - void Downsample(CTexture* pSrc, CTexture* pDst, int nSrcW, int nSrcH, int nDstW, int nDstH, EFilterType eFilter = FilterType_Box, bool bSetTarget = true); - - // Downsample to half resolution while minimizing temporal aliasing (useful for bloom) - void DownsampleStable(CTexture* pSrcRT, CTexture* pDstRT, bool bKillFireflies = false); - - void DownsampleDepth(CTexture* pSrc, CTexture* pDst, bool bFromSingleChannel); - // Downsample using compute shader - void DownsampleDepthUsingCompute(CTexture* pSrc, CTexture** pDstArr, bool bFromSingleChannel); - - // Downsamples color N amount of times in one pass using 2x2 box filtering - // Max N is 3. pDstArr has to be an array of 3. Nullptrs ok for elements > 0. - void DownsampleUsingCompute(CTexture* pSrc, CTexture** pDstArr); - - CTexture* GetBackBufferTexture(); - - SDepthTexture* GetDepthSurface(CTexture* pTex); - void ResolveRT(CTexture*& pDst, const RECT* pSrcRect); - void SetSRGBShaderFlags(); - - //////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////// - - static SD3DPostEffectsUtils& GetInstance() - { - static SD3DPostEffectsUtils m_pInstance; - return m_pInstance; - } - - -private: - - - SD3DPostEffectsUtils() - { - m_pQuadParams = "g_vQuadParams"; - m_pQuadPosParams = "g_vQuadPosParams"; - m_pFrustumLTParams = "g_vViewFrustumLT"; - m_pFrustumLBParams = "g_vViewFrustumLB"; - m_pFrustumRTParams = "g_vViewFrustumRT"; - m_pFrustumRBParams = "g_vViewFrustumRB"; - } - - virtual ~SD3DPostEffectsUtils() - { - } - -private: - - CCryNameR m_pQuadParams; - CCryNameR m_pQuadPosParams; - CCryNameR m_pFrustumLTParams; - CCryNameR m_pFrustumLBParams; - CCryNameR m_pFrustumRTParams; - CCryNameR m_pFrustumRBParams; -}; - -// to be removed -#define GetUtils() SD3DPostEffectsUtils::GetInstance() - -#define PostProcessUtils() SD3DPostEffectsUtils::GetInstance() - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRECloud.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRECloud.cpp deleted file mode 100644 index 7c2faeeb8f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRECloud.cpp +++ /dev/null @@ -1,976 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "DriverD3D.h" -#include "I3DEngine.h" - -//======================================================================= - -extern CTexture* gTexture; - -void CRECloud::IlluminateCloud(Vec3 vLightPos, [[maybe_unused]] Vec3 vObjPos, ColorF cLightColor, ColorF cAmbColor, bool bReset) -{ - CryFatalError("Not implemented on D3D11+"); - - int iOldVP[4]; - - CD3D9Renderer* rd = gcpRendD3D; - int nShadeRes = m_siShadeResolution; - nShadeRes = 256; - - rd->GetViewport(&iOldVP[0], &iOldVP[1], &iOldVP[2], &iOldVP[3]); - - Matrix44A origMatView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - Matrix44A origMatProj = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - rd->RT_SetViewport(0, 0, nShadeRes, nShadeRes); - - Vec3 vDir = vLightPos; - vDir.Normalize(); - - if (bReset) - { - m_lightDirections.clear(); - } - m_lightDirections.push_back(vDir); - - vLightPos *= (1.1f * m_boundingBox.GetRadius()); - vLightPos += m_boundingBox.GetCenter(); - - CameraViewParameters cam; - - Vec3 vUp(0, 0, 1); - cam.LookAt(vLightPos, m_boundingBox.GetCenter(), vUp); - - SortParticles(cam.ViewDir(), vLightPos, eSort_AWAY); - - float DistToCntr = (m_boundingBox.GetCenter() - vLightPos) * cam.ViewDir(); - - float fNearDist = DistToCntr - m_boundingBox.GetRadius(); - float fFarDist = DistToCntr + m_boundingBox.GetRadius(); - - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - cam.GetModelviewMatrix((float*)m); - - mathMatrixOrthoOffCenter(&rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj, -m_boundingBox.GetRadius(), m_boundingBox.GetRadius(), -m_boundingBox.GetRadius(), m_boundingBox.GetRadius(), fNearDist, fFarDist); - - - rd->SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - rd->SetSrgbWrite(false); - rd->FX_SetState(GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST | GS_ALPHATEST_GREATER, 0); - rd->D3DSetCull(eCULL_None); - - CRenderObject* pObj = rd->m_RP.m_pCurObject; - CShader* pSH = rd->m_RP.m_pShader; - SShaderTechnique* pSHT = rd->m_RP.m_pCurTechnique; - SShaderPass* pPass = rd->m_RP.m_pCurPass; - CShaderResources* pShRes = rd->m_RP.m_pShaderResources; - - if (pShRes) - { - SEfResTexture* pTextureRes = pShRes->GetTextureResource(EFTT_DIFFUSE); - if (pTextureRes) - { - m_pTexParticle = pTextureRes->m_Sampler.m_pTex; - } - } - if (m_pTexParticle) - { - m_pTexParticle->Apply(0); - } - else - { - AZ_Warning("Shaders System", false, "Error: missing diffuse texture for clouds in CRECloud::IlluminateCloud"); - } - - rd->FX_SetFPMode(); - - rd->EF_ClearTargetsLater(FRT_CLEAR, Clr_White, Clr_FarPlane.r, 0); - rd->FX_Commit(); - - float fPixelsPerLength = (float)nShadeRes / (2.0f * m_boundingBox.GetRadius()); - - // the solid angle over which we will sample forward-scattered light. - float fSolidAngle = 0.09f; - int i; - int nParts = m_particles.size(); - for (i = 0; i < nParts; i++) - { - SCloudParticle* p = m_particles[i]; - Vec3 vParticlePos = p->GetPosition(); - - Vec3 vOffset = vLightPos - vParticlePos; - - float fDistance = fabs(cam.ViewDir() * vOffset) - fNearDist; - - float fArea = fSolidAngle * fDistance * fDistance; - int iPixelDim = (int)(sqrtf(fArea) * fPixelsPerLength); - //iPixelDim = 1; - int iNumPixels = iPixelDim * iPixelDim; - if (iNumPixels < 1) - { - iNumPixels = 1; - iPixelDim = 1; - } - - // the scale factor to convert the read back pixel colors to an average illumination of the area. - float fColorScaleFactor = fSolidAngle / (iNumPixels * 255.0f); - - unsigned char* ds = new unsigned char[4 * iNumPixels]; - unsigned char* c = ds; - - Vec3 vWinPos; - - // find the position in the buffer to which the particle position projects. - rd->ProjectToScreen(vParticlePos.x, vParticlePos.y, vParticlePos.z, &vWinPos.x, &vWinPos.y, &vWinPos.z); - vWinPos.x /= 100.0f / rd->m_NewViewport.nWidth; - vWinPos.y /= 100.0f / rd->m_NewViewport.nHeight; - - // offset the projected window position by half the size of the readback region. - vWinPos.x -= 0.5f * iPixelDim; - if (vWinPos.x < 0) - { - vWinPos.x = 0; - } - vWinPos.y = (vWinPos.y - 0.5f * iPixelDim); - if (vWinPos.y < 0) - { - vWinPos.y = 0; - } - - // scattering coefficient vector. - //m_sfScatterFactor = m_sfAlbedo * 80 * (1.0f/(4.0f*(float)M_PI)); - ColorF vScatter = ColorF(m_sfScatterFactor, m_sfScatterFactor, m_sfScatterFactor, 1); - - // add up the read back pixels (only need one component -- its grayscale) - int iSum = 0; - int nTest = 0; - for (int k = 0; k < 4 * iNumPixels; k += 4) - { - PREFAST_SUPPRESS_WARNING(6001) // ds/c is unintialized, all this code is unused, unmaintained and should be entirely removed - iSum += c[k]; - nTest += 255; - } - delete [] c; - - ColorF vScatteredAmount = ColorF(iSum * fColorScaleFactor, iSum * fColorScaleFactor, iSum * fColorScaleFactor, 1 - m_sfTransparency); - vScatteredAmount *= vScatter; - - ColorF vColor = vScatteredAmount; - float fScat = (float)iSum / (float)nTest; - fScat = powf(fScat, 3); - //vColor = ColorF(fScat); - - vColor *= cLightColor; - vColor.a = 1 - m_sfTransparency; - - //ColorF Amb = ColorF(0.1f, 0.1f, 0.1f, 1.0f); - if (bReset) - { - p->SetBaseColor(cAmbColor); - p->ClearLitColors(); - p->AddLitColor(vColor); - } - else - { - p->AddLitColor(vColor); - } - - vScatteredAmount *= 1.5f; - - // clamp the color - vScatteredAmount.clamp(); - vScatteredAmount.a = 1 - m_sfTransparency; - - Vec3 vPos = vParticlePos; - Vec3 x = cam.vX * p->GetRadiusX(); - Vec3 y = cam.vY * p->GetRadiusY(); - rd->DrawQuad3D(vPos - y - x, vPos - y + x, vPos + y + x, vPos + y - x, vScatteredAmount, p->m_vUV[0].x, p->m_vUV[0].y, p->m_vUV[1].x, p->m_vUV[1].y); - } - - rd->FX_PopRenderTarget(0); - assert(0); - rd->m_RP.m_pCurObject = pObj; - rd->m_RP.m_pShader = pSH; - rd->m_RP.m_pCurTechnique = pSHT; - rd->m_RP.m_pCurPass = pPass; - - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - rd->RT_SetViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]); -} - -void CRECloud::DisplayWithoutImpostor(const CameraViewParameters& camera) -{ - CD3D9Renderer* rd = gcpRendD3D; - assert(rd->m_pRT->IsRenderThread()); - - int nThreadID = rd->m_RP.m_nProcessThreadID; - - // copy the current camera - CameraViewParameters cam(camera); - - Vec3 vUp(0, 0, 1); - - Vec3 vParticlePlane = cam.vX % cam.vY; - Vec3 vParticleX = (vUp % vParticlePlane).GetNormalized(); - Vec3 vParticleY = (vParticleX % vParticlePlane).GetNormalized(); - - float fCosAngleSinceLastSort = m_vLastSortViewDir * rd->GetViewParameters().ViewDir(); - - float fSquareDistanceSinceLastSort = (rd->GetViewParameters().vOrigin - m_vLastSortCamPos).GetLengthSquared(); - - if (fCosAngleSinceLastSort < m_sfSortAngleErrorTolerance || fSquareDistanceSinceLastSort > m_sfSortSquareDistanceTolerance) - { - Vec3 vSortPos = -cam.ViewDir(); - vSortPos *= (1.1f * m_boundingBox.GetRadius()); - - // sort the particles from back to front wrt the camera position. - SortParticles(cam.ViewDir(), vSortPos, eSort_TOWARD); - - m_vLastSortViewDir = rd->GetViewParameters().ViewDir(); - m_vLastSortCamPos = rd->GetViewParameters().vOrigin; - } - - ColorF color; - Vec3 eyeDir; - - int nParts = m_particles.size(); - int nStartPart = 0; - - if (nParts == 0) - { - return; - } - - int nCurParts; - - CRenderObject* pObj = rd->m_RP.m_pCurObject; - CShader* pSH = rd->m_RP.m_pShader; - SShaderTechnique* pSHT = rd->m_RP.m_pCurTechnique; - SShaderPass* pPass = rd->m_RP.m_pCurPass; - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - Vec3 vPos = pRE->GetPosition(); - - uint32 nPasses; - if (SRendItem::m_RecurseLevel[nThreadID] > 0) - { - static CCryNameTSCRC techName("Cloud_Recursive"); - pSH->FXSetTechnique(techName); - } - else - { - static CCryNameTSCRC techName("Cloud"); - pSH->FXSetTechnique(techName); - } - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - CShaderResources* pShRes = rd->m_RP.m_pShaderResources; - if (pShRes) - { - SEfResTexture* pTextureRes = pShRes->GetTextureResource(EFTT_DIFFUSE); - if (pTextureRes) - m_pTexParticle = pTextureRes->m_Sampler.m_pTex; - } - if (m_pTexParticle) - { - m_pTexParticle->Apply(0); - } - else - { - AZ_Warning("ShadersSystem", false, "Error: missing diffuse texture for clouds in CRECloud::DisplayWithoutImpostor"); - } - - /* - // set depth texture for soft clipping of cloud particle against scene geometry - if(0 != CTexture::s_ptexZTarget) - { - STexState depthTextState( FILTER_POINT, true ); - CTexture::s_ptexZTarget->Apply( 1, CTexture::GetTexState(depthTextState) ); - } - */ - rd->FX_SetState(GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST | GS_ALPHATEST_GREATER, 0); - //rd->FX_SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST | GS_ALPHATEST_GREATER, 0); - rd->D3DSetCull(eCULL_None); - - if (SRendItem::m_RecurseLevel[nThreadID] > 0) - { - rd->m_cEF.m_RTRect = Vec4(0, 0, 1, 1); - } - - if (SRendItem::m_RecurseLevel[nThreadID] > 0) - { - Vec4 vCloudColorScale(m_fCloudColorScale, 0, 0, 0); - static CCryNameR g_CloudColorScaleName("g_CloudColorScale"); - pSH->FXSetPSFloat(g_CloudColorScaleName, &vCloudColorScale, 1); - } - - rd->FX_Commit(); - - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - while (nStartPart < nParts) - { - nCurParts = nParts - nStartPart; - if (nCurParts > 32768) - { - nCurParts = 32768; - } - - TempDynVB vb(gcpRendD3D); - vb.Allocate(nCurParts * 4); - SVF_P3F_C4B_T2F* pDst = vb.Lock(); - - TempDynIB16 ib(gcpRendD3D); - ib.Allocate(nCurParts * 6); - uint16* pDstInds = ib.Lock(); - - // get various run-time parameters to determine cloud shading - Vec3 sunDir(gEnv->p3DEngine->GetSunDir().GetNormalized()); - - ColorF cloudSpec, cloudDiff; - GetIllumParams(cloudSpec, cloudDiff); - - I3DEngine* p3DEngine(gEnv->p3DEngine); - assert(0 != p3DEngine); - - Vec3 cloudShadingMultipliers; - p3DEngine->GetGlobalParameter(E3DPARAM_CLOUDSHADING_MULTIPLIERS, cloudShadingMultipliers); - - Vec3 brightColor(cloudShadingMultipliers.x* p3DEngine->GetSunColor().CompMul(Vec3(cloudSpec.r, cloudSpec.g, cloudSpec.b))); - - Vec3 negCamFrontDir(-cam.ViewDir()); - - m_fCloudColorScale = 1.0f; - - // compute m_fCloudColorScale for HDR rendering - { - if (brightColor.x > m_fCloudColorScale) - { - m_fCloudColorScale = brightColor.x; - } - if (brightColor.y > m_fCloudColorScale) - { - m_fCloudColorScale = brightColor.y; - } - if (brightColor.z > m_fCloudColorScale) - { - m_fCloudColorScale = brightColor.z; - } - - // normalize color - brightColor /= m_fCloudColorScale; - } - - // render cloud particles - for (int i = 0; i < nCurParts; i++) - { - SCloudParticle* p = m_particles[i + nStartPart]; - - // draw the particle as a textured billboard. - int nInd = i * 4; - SVF_P3F_C4B_T2F* pQuad = &pDst[nInd]; - Vec3 pos = p->GetPosition() * m_fScale + vPos; - Vec3 x = vParticleX * p->GetRadiusX() * m_fScale; - Vec3 y = vParticleY * p->GetRadiusY() * m_fScale; - //ColorB cb = color; - //uint32 cd = cb.pack_argb8888(); - - // determine shade for each vertex of the billboard - float f0 = sunDir.Dot(Vec3(-y - x).GetNormalized()) * 0.5f + 0.5f; - float f1 = sunDir.Dot(Vec3(-y + x).GetNormalized()) * 0.5f + 0.5f; - float f2 = sunDir.Dot(Vec3(y + x).GetNormalized()) * 0.5f + 0.5f; - float f3 = sunDir.Dot(Vec3(y - x).GetNormalized()) * 0.5f + 0.5f; - - Vec3 eye0(cam.vOrigin - (pos - y - x)); - eye0 = (eye0.GetLengthSquared() < 1e-4f) ? negCamFrontDir : eye0.GetNormalized(); - Vec3 eye1(cam.vOrigin - (pos - y + x)); - eye1 = (eye1.GetLengthSquared() < 1e-4f) ? negCamFrontDir : eye1.GetNormalized(); - Vec3 eye2(cam.vOrigin - (pos + y + x)); - eye2 = (eye2.GetLengthSquared() < 1e-4f) ? negCamFrontDir : eye2.GetNormalized(); - Vec3 eye3(cam.vOrigin - (pos + y - x)); - eye3 = (eye3.GetLengthSquared() < 1e-4f) ? negCamFrontDir : eye3.GetNormalized(); - f0 *= sunDir.Dot(eye0) * 0.25f + 0.75f; - f1 *= sunDir.Dot(eye1) * 0.25f + 0.75f; - f2 *= sunDir.Dot(eye2) * 0.25f + 0.75f; - f3 *= sunDir.Dot(eye3) * 0.25f + 0.75f; - - //float heightScaleTop( ( p->GetPosition().z + x.z + y.z - minHeight ) / totalHeight ); - //float heightScaleBottom( ( p->GetPosition().z - x.z - y.z - minHeight ) / totalHeight ); - float heightScaleTop(1); - float heightScaleBottom(1); - - // compute finale shading values - f0 = clamp_tpl(f0 * heightScaleBottom, 0.0f, 1.0f); - f1 = clamp_tpl(f1 * heightScaleBottom, 0.0f, 1.0f); - f2 = clamp_tpl(f2 * heightScaleTop, 0.0f, 1.0f); - f3 = clamp_tpl(f3 * heightScaleTop, 0.0f, 1.0f); - - // blend between dark and bright cloud color based on shading value - Vec3 c0(f0 * (brightColor)); - Vec3 c1(f1 * (brightColor)); - Vec3 c2(f2 * (brightColor)); - Vec3 c3(f3 * (brightColor)); - float transp(pRE->m_fCurTransparency); - - // write billboard vertices - ColorF col0(c0.x, c0.y, c0.z, transp); - col0.clamp(); - pQuad[0].xyz = pos - y - x; - pQuad[0].color.dcolor = ColorB(col0).pack_argb8888(); - pQuad[0].st = Vec2(p->m_vUV[0].x, p->m_vUV[0].y); - - ColorF col1(c1.x, c1.y, c1.z, transp); - col1.clamp(); - pQuad[1].xyz = pos - y + x; - pQuad[1].color.dcolor = ColorB(col1).pack_argb8888(); - pQuad[1].st = Vec2(p->m_vUV[1].x, p->m_vUV[0].y); - - ColorF col2(c2.x, c2.y, c2.z, transp); - col2.clamp(); - pQuad[2].xyz = pos + y + x; - pQuad[2].color.dcolor = ColorB(col2).pack_argb8888(); - pQuad[2].st = Vec2(p->m_vUV[1].x, p->m_vUV[1].y); - - ColorF col3(c3.x, c3.y, c3.z, transp); - col3.clamp(); - pQuad[3].xyz = pos + y - x; - pQuad[3].color.dcolor = ColorB(col3).pack_argb8888(); - pQuad[3].st = Vec2(p->m_vUV[0].x, p->m_vUV[1].y); - - uint16* pInds = &pDstInds[i * 6]; - pInds[0] = nInd; - pInds[1] = nInd + 1; - pInds[2] = nInd + 2; - - pInds[3] = nInd; - pInds[4] = nInd + 2; - pInds[5] = nInd + 3; - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - ib.Unlock(); - ib.Bind(); - ib.Release(); - - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, nCurParts * 4, 0, nCurParts * 6); - - nStartPart += nCurParts; - } - } - - rd->m_RP.m_pCurObject = pObj; - rd->m_RP.m_pShader = pSH; - rd->m_RP.m_pCurTechnique = pSHT; - rd->m_RP.m_pCurPass = pPass; -} - -bool CRECloud::GenerateCloudImposter(CShader* pShader, CShaderResources* pRes, CRenderObject* pObject) -{ - CD3D9Renderer* r = gcpRendD3D; - r->FX_PreRender(1); - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_DRAWTOTEXTURE; - r->m_RP.m_pRE = NULL; - r->m_RP.m_pShader = pShader; - r->m_RP.m_pShaderResources = pRes; - r->m_RP.m_pCurObject = pObject; - r->m_RP.m_RendNumVerts = 0; - r->m_RP.m_RendNumIndices = 0; - mfPrepare(false); - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_DRAWTOTEXTURE; - r->FX_PostRender(); - - return true; -} - -bool CRECloud::UpdateImposter(CRenderObject* pObj) -{ - CD3D9Renderer* rd = gcpRendD3D; - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - - if (!pRE->PrepareForUpdate()) - { - if (!CRenderer::CV_r_cloudsupdatealways && pRE->m_nFrameReset == rd->m_nFrameReset) - { - return true; - } - } - - PROFILE_FRAME(Imposter_CloudUpdate); - - pRE->m_nFrameReset = rd->m_nFrameReset; - int nLogX = pRE->m_nLogResolutionX; - int nLogY = pRE->m_nLogResolutionY; - int iResX = 1 << nLogX; - int iResY = 1 << nLogY; - while (iResX > SDynTexture::s_CurTexAtlasSize) - { - nLogX--; - iResX = 1 << nLogX; - } - while (iResY > SDynTexture::s_CurTexAtlasSize) - { - nLogY--; - iResY = 1 << nLogY; - } - - int iOldVP[4]; - rd->GetViewport(&iOldVP[0], &iOldVP[1], &iOldVP[2], &iOldVP[3]); - - Matrix44A origMatView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - Matrix44A origMatProj = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - rd->RT_SetViewport(0, 0, iResX, iResY); -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumCloudImpostersUpdates++; -#endif - - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - pRE->m_LastViewParameters.GetModelviewMatrix((float*)m); - - m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - //pRE->m_LastCamera.GetProjectionMatrix(*m); - mathMatrixPerspectiveOffCenter(m, pRE->m_LastViewParameters.fWL, pRE->m_LastViewParameters.fWR, pRE->m_LastViewParameters.fWB, - pRE->m_LastViewParameters.fWT, pRE->m_LastViewParameters.fNear, pRE->m_LastViewParameters.fFar); - - IDynTexture** pDT; - if (!pRE->m_bSplit) - { - if (!pRE->m_bScreenImposter) - { - pDT = &pRE->m_pTexture; - } - else - { - pDT = &pRE->m_pScreenTexture; - } - if (!*pDT) - { - *pDT = new SDynTexture2(iResX, iResY, FT_STATE_CLAMP, "CloudImposter", eTP_Clouds); - } - - if (*pDT) - { - SDepthTexture* pDepth = &gcpRendD3D->m_DepthBufferOrig; - uint32 nX1, nY1, nW1, nH1; - (*pDT)->Update(iResX, iResY); - (*pDT)->GetImageRect(nX1, nY1, nW1, nH1); -#if defined(OPENGL_ES) - // OpenGLES needs the color texture size to match the depth texture - pDepth = nW1 != static_cast(rd->m_d3dsdBackBuffer.Width) || nH1 != static_cast(rd->m_d3dsdBackBuffer.Height) ? nullptr : pDepth; -#else - pDepth = nW1 > static_cast(rd->m_d3dsdBackBuffer.Width) || nH1 > static_cast(rd->m_d3dsdBackBuffer.Height) ? nullptr : pDepth; -#endif // defined(OPENGL_ES) - - if (!pDepth) - { - pDepth = rd->FX_GetDepthSurface(nW1, nH1, false); - } - (*pDT)->ClearRT(); - (*pDT)->SetRT(0, true, pDepth); - gTexture = (CTexture*)(*pDT)->GetTexture(); - - uint32 nX, nY, nW, nH; - (*pDT)->GetSubImageRect(nX, nY, nW, nH); - if (pRE->m_bScreenImposter) - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_cloudsdebug != 2) - { - rd->LogStrv(SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID], "Generating screen '%s' - %s (%d, %d, %d, %d) (%d)\n", gTexture->GetName(), (*pDT)->IsSecondFrame() ? "Second" : "First", nX, nY, nW, nH, gRenDev->GetFrameID(false)); - } - } - else - { - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_cloudsdebug != 1) - { - rd->LogStrv(SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID], "Generating '%s' - %s (%d, %d, %d, %d) (%d)\n", gTexture->GetName(), (*pDT)->IsSecondFrame() ? "Second" : "First", nX, nY, nW, nH, gRenDev->GetFrameID(false)); - } - } - - int nSize = iResX * iResY * 4; - pRE->m_MemUpdated += nSize / 1024; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_CloudImpostersSizeUpdate += nSize; - DisplayWithoutImpostor(pRE->m_LastViewParameters); - (*pDT)->SetUpdateMask(); - (*pDT)->RestoreRT(0, true); - } - } - rd->RT_SetViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]); - - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - - return true; -} - -bool CRECloud::mfDisplay(bool bDisplayFrontOfSplit) -{ - CD3D9Renderer* rd = gcpRendD3D; - CRenderObject* pObj = rd->m_RP.m_pCurObject; - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - Vec3 vPos = pRE->m_vPos; - CShader* pSH = rd->m_RP.m_pShader; - SShaderTechnique* pSHT = rd->m_RP.m_pCurTechnique; - SShaderPass* pPass = rd->m_RP.m_pCurPass; -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumCloudImpostersDraw++; -#endif - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_cloudsdebug == 2 && pRE->m_bScreenImposter) - { - return true; - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_cloudsdebug == 1 && !pRE->m_bScreenImposter) - { - return true; - } - - uint32 nPersFlags2 = rd->m_RP.m_PersFlags2; - rd->m_RP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - - uint32 nPasses; - - float fAlpha = pObj->m_fAlpha; - ColorF col(1, 1, 1, fAlpha); - - if (SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] > 0) - { - DisplayWithoutImpostor(rd->GetViewParameters()); - return true; - } - - // if (!pRE->m_pTexture || (bDisplayFrontOfSplit && !pRE->m_pFrontTexture)) - // Warning("WARNING: CRECloud::mfDisplay: missing texture!"); - // else - // { - // IDynTexture *pDT; - // if (bDisplayFrontOfSplit) - // pDT = pRE->m_pFrontTexture; - // else - // pDT = pRE->m_pTexture; - //CTexture::m_Text_NoTexture->Apply(0); - // pDT->Apply(0); - // } - - IDynTexture* pDT; - - if (!pRE->m_bScreenImposter) - { - pDT = pRE->m_pTexture; - } - else - { - pDT = pRE->m_pScreenTexture; - } - - float fOffsetU = 0, fOffsetV = 0; - if (pDT && (!bDisplayFrontOfSplit || (bDisplayFrontOfSplit && pRE->m_pFrontTexture))) - { - pDT->Apply(0); - - fOffsetU = 0.5f / (float) pDT->GetWidth(); - fOffsetV = 0.5f / (float) pDT->GetHeight(); - } - - // set depth texture for soft clipping of cloud against scene geometry - if (0 != CTexture::s_ptexZTarget) - { - STexState depthTextState(FILTER_POINT, true); - CTexture::s_ptexZTarget->Apply(1, CTexture::GetTexState(depthTextState)); - } - - int State = GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA | GS_ALPHATEST_GREATER; - - if (pRE->m_bSplit) - { - if (!bDisplayFrontOfSplit) - { - State |= GS_DEPTHWRITE; - } - else - { - State |= GS_NODEPTHTEST; - } - } - - - // Martin test - for clouds particle soft clipping against terrain - // State |= GS_NODEPTHTEST; - - // Added for Sun-rays to work with clouds: - // - force depth writing so that sun-rays interact with clouds. - // - also make sure we don't make any depth test (it's already done in pixel shader) so that no alpha test artifacts are visible - //State |= GS_DEPTHWRITE | GS_DEPTHFUNC_NOTEQUAL; - - rd->FX_SetState(State, 0); - - Vec3 x, y, z; - - Vec4 vCloudColorScale(m_fCloudColorScale, 0, 0, 0); - - if (!pRE->m_bScreenImposter) - { - z = vPos - pRE->m_LastViewParameters.vOrigin; - z.Normalize(); - x = (z ^ pRE->m_LastViewParameters.vY); - x.Normalize(); - x *= pRE->m_fRadiusX; - y = (x ^ z); - y.Normalize(); - y *= pRE->m_fRadiusY; - - - - const CameraViewParameters& cam = rd->GetViewParameters(); - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - cam.GetModelviewMatrix((float*)m); - m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - mathMatrixPerspectiveOffCenter(m, cam.fWL, cam.fWR, cam.fWB, cam.fWT, cam.fNear, cam.fFar); - - if (SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] <= 0) - { - const SRenderTileInfo* rti = rd->GetRenderTileInfo(); - if (rti->nGridSizeX > 1.f || rti->nGridSizeY > 1.f) - { // shift and scale viewport - m->m00 *= rti->nGridSizeX; - m->m11 *= rti->nGridSizeY; - m->m20 = (rti->nGridSizeX - 1.f) - rti->nPosX * 2.0f; - m->m21 = -((rti->nGridSizeY - 1.f) - rti->nPosY * 2.0f); - } - } - - rd->D3DSetCull(eCULL_None); - static CCryNameTSCRC techName("Cloud_Imposter"); - pSH->FXSetTechnique(techName); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - static CCryNameR g_CloudColorScaleName("g_CloudColorScale"); - pSH->FXSetPSFloat(g_CloudColorScaleName, &vCloudColorScale, 1); - - Vec3 lPos; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_POS, lPos); - Vec4 lightningPosition(lPos.x, lPos.y, lPos.z, 0.0f); - static CCryNameR LightningPosName("LightningPos"); - pSH->FXSetVSFloat(LightningPosName, &lightningPosition, 1); - - Vec3 lCol; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_COLOR, lCol); - Vec3 lSize; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_SIZE, lSize); - Vec4 lightningColorSize(lCol.x, lCol.y, lCol.z, lSize.x * 0.01f); - static CCryNameR LightningColSizeName("LightningColSize"); - pSH->FXSetVSFloat(LightningColSizeName, &lightningColorSize, 1); - - rd->m_RP.m_nCommitFlags |= FC_MATERIAL_PARAMS; - rd->FX_Commit(); - - rd->DrawQuad3D(pRE->m_vQuadCorners[0] + vPos, - pRE->m_vQuadCorners[1] + vPos, - pRE->m_vQuadCorners[2] + vPos, - pRE->m_vQuadCorners[3] + vPos, col, 0 + fOffsetU, 1 - fOffsetV, 1 - fOffsetU, 0 + fOffsetV); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 4) - { - rd->FX_SetState(GS_NODEPTHTEST); - SAuxGeomRenderFlags auxFlags; - auxFlags.SetDepthTestFlag(e_DepthTestOff); - rd->GetIRenderAuxGeom()->SetRenderFlags(auxFlags); - rd->GetIRenderAuxGeom()->DrawAABB(AABB(pRE->m_WorldSpaceBV.GetMin(), pRE->m_WorldSpaceBV.GetMax()), false, Col_White, eBBD_Faceted); - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 2) - { - Vec3 v[4]; - v[0] = vPos - y - x; - v[1] = vPos - y + x; - v[2] = vPos + y + x; - v[3] = vPos + y - x; - vtx_idx inds[6]; - inds[0] = 0; - inds[1] = 1; - inds[2] = 2; - inds[3] = 0; - inds[4] = 2; - inds[5] = 3; - - SAuxGeomRenderFlags auxFlags; - auxFlags.SetFillMode(e_FillModeWireframe); - auxFlags.SetDepthTestFlag(e_DepthTestOn); - rd->GetIRenderAuxGeom()->SetRenderFlags(auxFlags); - rd->GetIRenderAuxGeom()->DrawTriangles(v, 4, inds, 6, Col_Green); - } - } - else - { - x = pRE->m_LastViewParameters.vX; - x *= 0.5f * (pRE->m_LastViewParameters.fWR - pRE->m_LastViewParameters.fWL); - y = pRE->m_LastViewParameters.vY; - y *= 0.5f * (pRE->m_LastViewParameters.fWT - pRE->m_LastViewParameters.fWB); - z = -pRE->m_LastViewParameters.vZ; - z *= pRE->m_LastViewParameters.fNear; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 4) - { - rd->GetIRenderAuxGeom()->DrawAABB(AABB(pRE->m_WorldSpaceBV.GetMin(), pRE->m_WorldSpaceBV.GetMax()), false, Col_Red, eBBD_Faceted); - } - - // draw a polygon with this texture... - Matrix44A origMatProj = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - mathMatrixOrthoOffCenterLH(m, -1, 1, -1, 1, -1, 1); - if (SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] <= 0) - { - const SRenderTileInfo* rti = rd->GetRenderTileInfo(); - if (rti->nGridSizeX > 1.f || rti->nGridSizeY > 1.f) - { // shift and scale viewport - m->m00 *= rti->nGridSizeX; - m->m11 *= rti->nGridSizeY; - m->m30 = -((rti->nGridSizeX - 1.f) - rti->nPosX * 2.0f); - m->m31 = ((rti->nGridSizeY - 1.f) - rti->nPosY * 2.0f); - } - } - - Matrix44A origMatView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - - pSH->FXSetTechnique("Cloud_ScreenImposter"); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - float fNear = pRE->m_fNear; - float fFar = pRE->m_fFar; - if (fNear < 0 || fNear > 1) - { - fNear = 0.92f; - } - if (fFar < 0 || fFar > 1) - { - fFar = 0.999f; - } - float fZ = (fNear + fFar) * 0.5f; - - Vec4 pos(pRE->GetPosition(), 1); - static CCryNameR vCloudWSPosName("vCloudWSPos"); - pSH->FXSetVSFloat(vCloudWSPosName, &pos, 1); - static CCryNameR g_CloudColorScaleName("g_CloudColorScale"); - pSH->FXSetPSFloat(g_CloudColorScaleName, &vCloudColorScale, 1); - - Vec3 lPos; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_POS, lPos); - Vec4 lightningPosition(lPos.x, lPos.y, lPos.z, col.a); - static CCryNameR LightningPosName("LightningPos"); - pSH->FXSetVSFloat(LightningPosName, &lightningPosition, 1); - - Vec3 lCol; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_COLOR, lCol); - Vec3 lSize; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_SIZE, lSize); - Vec4 lightningColorSize(lCol.x, lCol.y, lCol.z, lSize.x * 0.01f); - static CCryNameR LightningColSizeName("LightningColSize"); - pSH->FXSetVSFloat(LightningColSizeName, &lightningColorSize, 1); - - { - TempDynVB vb(gRenDev); - vb.Allocate(4); - SVF_P3F_T2F_T3F* vQuad = vb.Lock(); - - Vec3 vCoords[8]; - gcpRendD3D->GetViewParameters().CalcVerts(vCoords); - Vec3 vRT = vCoords[4] - vCoords[0]; - Vec3 vLT = vCoords[5] - vCoords[1]; - Vec3 vLB = vCoords[6] - vCoords[2]; - Vec3 vRB = vCoords[7] - vCoords[3]; - - vQuad[0].p.x = -1; - vQuad[0].p.y = -1; - vQuad[0].p.z = fZ; - vQuad[0].st0[0] = 0; - vQuad[0].st0[1] = 1; - vQuad[0].st1 = vLB; - - vQuad[1].p.x = 1; - vQuad[1].p.y = -1; - vQuad[1].p.z = fZ; - vQuad[1].st0[0] = 1; - vQuad[1].st0[1] = 1; - vQuad[1].st1 = vRB; - - vQuad[3].p.x = 1; - vQuad[3].p.y = 1; - vQuad[3].p.z = fZ; - vQuad[3].st0[0] = 1; - vQuad[3].st0[1] = 0; - vQuad[3].st1 = vRT; - - vQuad[2].p.x = -1; - vQuad[2].p.y = 1; - vQuad[2].p.z = fZ; - vQuad[2].st0[0] = 0; - vQuad[2].st0[1] = 0; - vQuad[2].st1 = vLT; - - vb.Unlock(); - vb.Bind(0); - - - rd->m_RP.m_nCommitFlags |= FC_MATERIAL_PARAMS; - rd->FX_Commit(); - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_T2F_T3F))) - { - rd->FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - vb.Release(); - } - - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - rd->m_RP.m_PersFlags2 = nPersFlags2; - - rd->m_RP.m_pCurObject = pObj; - rd->m_RP.m_pShader = pSH; - rd->m_RP.m_pCurTechnique = pSHT; - rd->m_RP.m_pCurPass = pPass; - - return true; -} - -bool CRECloud::mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* pPass) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_impostersdraw) - { - return true; - } - - CD3D9Renderer* rd = gcpRendD3D; - CRenderObject* pObj = rd->m_RP.m_pCurObject; - CREImposter* pRE = (CREImposter*)pObj->GetRE(); - - mfDisplay(false); - - if (pRE->IsSplit()) - { - // now display the front half of the split impostor. - mfDisplay(true); - } - - return true; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DREImposter.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DREImposter.cpp deleted file mode 100644 index 51c328b19f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DREImposter.cpp +++ /dev/null @@ -1,741 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "DriverD3D.h" -#include "I3DEngine.h" - -//======================================================================= - -CTexture* gTexture; - -int IntersectRayAABB(Vec3 p, Vec3 d, SMinMaxBox a, Vec3& q); - - -static void GetEdgeNo(const uint32 dwEdgeNo, uint32& dwA, uint32& dwB) -{ - switch (dwEdgeNo) - { - case 0: - dwA = 0; - dwB = 1; - break; - case 1: - dwA = 2; - dwB = 3; - break; - case 2: - dwA = 4; - dwB = 5; - break; - case 3: - dwA = 6; - dwB = 7; - break; - - case 4: - dwA = 0; - dwB = 2; - break; - case 5: - dwA = 4; - dwB = 6; - break; - case 6: - dwA = 5; - dwB = 7; - break; - case 7: - dwA = 1; - dwB = 3; - break; - - case 8: - dwA = 0; - dwB = 4; - break; - case 9: - dwA = 2; - dwB = 6; - break; - case 10: - dwA = 3; - dwB = 7; - break; - case 11: - dwA = 1; - dwB = 5; - break; - - default: - assert(0); - } -} - - - -bool CREImposter::PrepareForUpdate() -{ - CD3D9Renderer* rd = gcpRendD3D; - CameraViewParameters cam = rd->GetViewParameters(); - int i; - - if (SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] > 0) - { - return false; - } - - - float fMinX, fMaxX, fMinY, fMaxY; - uint32 dwBestEdge = 0xffffffff; // favor the last edge we found - float fBestArea = FLT_MAX; - - Vec3 vCenter = GetPosition(); - Vec3 vEye = vCenter - cam.vOrigin; - float fDistance = vEye.GetLength(); - vEye /= fDistance; - - int32 D3DVP[4]; - rd->GetViewport(&D3DVP[0], &D3DVP[1], &D3DVP[2], &D3DVP[3]); - - Vec3 vProjPos[9]; - Vec3 vUnProjPos[9]; - for (i = 0; i < 8; i++) - { - if (i & 1) - { - vUnProjPos[i].x = m_WorldSpaceBV.GetMax().x; - } - else - { - vUnProjPos[i].x = m_WorldSpaceBV.GetMin().x; - } - - if (i & 2) - { - vUnProjPos[i].y = m_WorldSpaceBV.GetMax().y; - } - else - { - vUnProjPos[i].y = m_WorldSpaceBV.GetMin().y; - } - - if (i & 4) - { - vUnProjPos[i].z = m_WorldSpaceBV.GetMax().z; - } - else - { - vUnProjPos[i].z = m_WorldSpaceBV.GetMin().z; - } - } - - vUnProjPos[8] = vCenter; - /* - // test - rd->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - rd->GetIRenderAuxGeom()->DrawAABB(AABB(m_WorldSpaceBV.GetMin(),m_WorldSpaceBV.GetMax()),false,ColorB(0,255,255,255),eBBD_Faceted); - */ - - CameraViewParameters tempCam; - Matrix44A viewMat, projMat; - - tempCam.fNear = cam.fNear; - tempCam.fFar = cam.fFar; - - mathMatrixPerspectiveOffCenter(&projMat, -1, 1, 1, -1, tempCam.fNear, tempCam.fFar); - - float fOldEdgeArea = -FLT_MAX; - - // try to find minimal enclosing rectangle assuming the best projection frustum must be aligned to a AABB edge - for (uint32 dwEdge = 0; dwEdge < 13; ++dwEdge) // 12 edges and iteration no 13 processes the best again - { - uint32 dwEdgeA, dwEdgeB; - - if (dwEdge == 12 && fBestArea > fOldEdgeArea * 0.98f) // not a lot better than old axis then keep old axis (to avoid jittering) - { - dwBestEdge = m_nLastBestEdge; - } - - if (dwEdge == 12) - { - GetEdgeNo(dwBestEdge, dwEdgeA, dwEdgeB); // the best again - } - else - { - GetEdgeNo(dwEdge, dwEdgeA, dwEdgeB); // edge no dwEdge - } - Vec3 vEdge[2] = { vUnProjPos[dwEdgeA], vUnProjPos[dwEdgeB]}; - /* - if(dwEdge==12) - { - // axis that allows smallest enclosing rectangle - rd->GetIRenderAuxGeom()->DrawLine( vEdge[0],ColorB(0,0,255,255),vEdge[1],ColorB(0,255,255,255),10.0f); - } - */ - - Vec3 vR = vEdge[0] - vEdge[1]; - Vec3 vU = (vEdge[0] - cam.vOrigin) ^ vR; - - tempCam.LookAt(cam.vOrigin, vCenter, vU); - tempCam.GetModelviewMatrix(viewMat.GetData()); - mathVec3ProjectArray((Vec3*)&vProjPos[0].x, sizeof(Vec3), (Vec3*)&vUnProjPos[0].x, sizeof(Vec3), D3DVP, &projMat, &viewMat, &rd->m_IdentityMatrix, 9, g_CpuFlags); - - // Calculate 2D extents - fMinX = fMinY = FLT_MAX; - fMaxX = fMaxY = -FLT_MAX; - for (i = 0; i < 8; i++) - { - if (fMinX > vProjPos[i].x) - { - fMinX = vProjPos[i].x; - } - if (fMinY > vProjPos[i].y) - { - fMinY = vProjPos[i].y; - } - - if (fMaxX < vProjPos[i].x) - { - fMaxX = vProjPos[i].x; - } - if (fMaxY < vProjPos[i].y) - { - fMaxY = vProjPos[i].y; - } - } - - float fArea = (fMaxX - fMinX) * (fMaxY - fMinY); - - if (dwEdge == m_nLastBestEdge) - { - fOldEdgeArea = fArea; - } - - if (fArea < fBestArea) - { - dwBestEdge = dwEdge; - fBestArea = fArea; - } - } - - /* - // low precision - jitters - // LB, RB, RT, LT - vProjPos[0] = Vec3(fMinX, fMinY, vProjPos[8].z); - vProjPos[1] = Vec3(fMaxX, fMinY, vProjPos[8].z); - vProjPos[2] = Vec3(fMaxX, fMaxY, vProjPos[8].z); - vProjPos[3] = Vec3(fMinX, fMaxY, vProjPos[8].z); - // Unproject back to the world with new z-value - mathVec3UnprojectArray((Vec3 *)&vUnProjPos[0].x, sizeof(Vec3), (Vec3 *)&vProjPos[0].x, sizeof(Vec3), D3DVP, &projMat, &viewMat, &sIdentityMatrix, 4, g_CpuFlags); - */ - // high precision - no jitter - float fCamZ = (tempCam.vOrigin - vCenter).Dot(tempCam.ViewDir()); - float f = -fCamZ / tempCam.fNear; - vUnProjPos[0] = tempCam.CamToWorld(Vec3((fMinX / D3DVP[2] * 2.0f - 1.0f) * f, (fMinY / D3DVP[3] * 2.0f - 1.0f) * f, fCamZ)); - vUnProjPos[1] = tempCam.CamToWorld(Vec3((fMaxX / D3DVP[2] * 2.0f - 1.0f) * f, (fMinY / D3DVP[3] * 2.0f - 1.0f) * f, fCamZ)); - vUnProjPos[2] = tempCam.CamToWorld(Vec3((fMaxX / D3DVP[2] * 2.0f - 1.0f) * f, (fMaxY / D3DVP[3] * 2.0f - 1.0f) * f, fCamZ)); - vUnProjPos[3] = tempCam.CamToWorld(Vec3((fMinX / D3DVP[2] * 2.0f - 1.0f) * f, (fMaxY / D3DVP[3] * 2.0f - 1.0f) * f, fCamZ)); - - - - // test - // rd->GetIRenderAuxGeom()->SetRenderFlags(SAuxGeomRenderFlags()); - // rd->GetIRenderAuxGeom()->DrawPolyline(vUnProjPos,4,true,ColorB(0,0,255,0),20); - - m_vPos = vCenter; - Vec3 vProjCenter = (vUnProjPos[0] + vUnProjPos[1] + vUnProjPos[2] + vUnProjPos[3]) / 4.0f; - Vec3 vDif = vProjCenter - vCenter; - float fDerivX = vDif * tempCam.vX; - float fDerivY = vDif * tempCam.vY; - - float fRadius = m_WorldSpaceBV.GetRadius(); - Vec3 vRight = vUnProjPos[0] - vUnProjPos[1]; - Vec3 vUp = vUnProjPos[0] - vUnProjPos[2]; - float fRadiusX = vRight.len() / 2 + fabsf(fDerivX); - float fRadiusY = vUp.len() / 2 + fabsf(fDerivY); - - Vec3 vNearest; - IntersectRayAABB(cam.vOrigin, vEye, m_WorldSpaceBV, vNearest); - Vec4 v4Nearest = Vec4(vNearest, 1); - Vec4 v4Far = Vec4(vNearest + vEye * fRadius * 2, 1); - Vec4 v4ZRange = Vec4(0, 0, 0, 0); - Vec4 v4Column2 = rd->m_ViewProjMatrix.GetColumn4(2); - Vec4 v4Column3 = rd->m_ViewProjMatrix.GetColumn4(3); - - bool bScreen = false; - - float fZ = v4Nearest.Dot(v4Column2); - float fW = v4Nearest.Dot(v4Column3); - - float fNewNear = m_fNear; - float fNewFar = m_fFar; - if (fabs(fW) < 0.001f) // to avoid division by 0 (near the object Screen is used and the value doesn't matter anyway) - { - fNewNear = 0.0f; - bScreen = true; - } - else - { - fNewNear = 0.999f * fZ / fW; - } - - fZ = v4Far.Dot(v4Column2); - fW = v4Far.Dot(v4Column3); - - if (fabs(fW) < 0.001f) // to avoid division by 0 (near the object Screen is used and the value doesn't matter anyway) - { - fNewFar = 1.0f; - bScreen = true; - } - else - { - fNewFar = fZ / fW; - } - - float fCamRadiusX = sqrtf(cam.fWR * cam.fWR + cam.fNear * cam.fNear); - float fCamRadiusY = sqrtf(cam.fWT * cam.fWT + cam.fNear * cam.fNear); - - float fWidth = cam.fWR - cam.fWL; - float fHeight = cam.fWT - cam.fWB; - - if (!bScreen) - { - bScreen = (fRadiusX * cam.fNear / fDistance >= fWidth || fRadiusY * cam.fNear / fDistance >= fHeight || (fDistance - fRadiusX <= fCamRadiusX) || (fDistance - fRadiusY <= fCamRadiusY)); - } - - IDynTexture* pDT = bScreen ? m_pScreenTexture : m_pTexture; - SDynTexture2* pDT2 = (SDynTexture2*)pDT; - - - float fRequiredResX = 1024; - float fRequiredResY = 512; - - float fTexScale = CRenderer::CV_r_imposterratio > 0.1f ? 1.0f / CRenderer::CV_r_imposterratio : 1.0f / 0.1f; - - if (!bScreen) // outside cloud - { - assert(D3DVP[0] == 0 && D3DVP[1] == 0); // otherwise the following lines don't make sense - - float fRadPixelX = (fMaxX - fMinX) * 2; // for some reason *2 is needed, most likely /near (*4) is the correct - float fRadPixelY = (fMaxY - fMinY) * 2; - - fRequiredResX = min(fRequiredResX, max(16.0f, fRadPixelX)); - fRequiredResY = min(fRequiredResY, max(16.0f, fRadPixelY)); - } - - int nRequiredLogXRes = LogBaseTwo((int)(fRequiredResX * fTexScale)); - int nRequiredLogYRes = LogBaseTwo((int)(fRequiredResY * fTexScale)); - - if (IsImposterValid(cam, fRadiusX, fRadiusY, fCamRadiusX, fCamRadiusY, nRequiredLogXRes, nRequiredLogYRes, dwBestEdge)) - { - if (!pDT2 || !pDT2->_IsValid()) - { - return true; - } - - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_cloudsupdatealways) - { - return false; - } - } - if (pDT2) - { - pDT2->ResetUpdateMask(); - } - - bool bPostpone = false; - int nCurFrame = rd->GetFrameID(false); - if (gRenDev->GetActiveGPUCount() == 1) - { - if (!CRenderer::CV_r_cloudsupdatealways && !bScreen && !m_bScreenImposter && pDT && pDT->GetTexture() && m_fRadiusX && m_fRadiusY) - { - if (m_MemUpdated > CRenderer::CV_r_impostersupdateperframe) - { - bPostpone = true; - } - if (m_PrevMemPostponed) - { - int nDeltaFrames = m_PrevMemPostponed / CRenderer::CV_r_impostersupdateperframe; - if (nCurFrame - m_FrameUpdate > nDeltaFrames) - { - bPostpone = false; - } - } - if (bPostpone) - { - m_MemPostponed += (1 << nRequiredLogXRes) * (1 << nRequiredLogYRes) * 4 / 1024; - return false; - } - } - } - m_FrameUpdate = nCurFrame; - m_fNear = fNewNear; - m_fFar = fNewFar; - - Matrix44A M; - - - m_LastViewParameters = cam; - m_vLastSunDir = gEnv->p3DEngine->GetSunDir().GetNormalized(); - - m_nLogResolutionX = nRequiredLogXRes; - m_nLogResolutionY = nRequiredLogYRes; - - if (!bScreen) - { // outside cloud - // m_LastCamera.TightlyFitToSphere(cam.vOrigin, vU, m_vPos, fRadiusX, fRadiusY); - - m_LastViewParameters = tempCam; - /* - float DistToCntr = (m_vPos-cam.vOrigin) | m_LastCamera.ViewDir(); - - // are the following 2 lines correct ? - m_LastCamera.fNear = DistToCntr-fRadiusX; - m_LastCamera.fFar = DistToCntr+fRadiusX; - */ - - assert(D3DVP[0] == 0 && D3DVP[1] == 0); // otherwise the following lines don't make sense - - // float fRadX = max(-fMinX/D3DVP[2]*2.0f+1.0f,fMaxX/D3DVP[2]*2.0f-1.0f); - // float fRadY = max(-fMinY/D3DVP[3]*2.0f+1.0f,fMaxY/D3DVP[3]*2.0f-1.0f); - m_LastViewParameters.fWL = (fMinX / D3DVP[2] * 2 - 1); - m_LastViewParameters.fWR = (fMaxX / D3DVP[2] * 2 - 1); - m_LastViewParameters.fWT = (fMaxY / D3DVP[3] * 2 - 1); - m_LastViewParameters.fWB = (fMinY / D3DVP[3] * 2 - 1); - - m_fRadiusX = 0.5f * (m_LastViewParameters.fWR - m_LastViewParameters.fWL) * fDistance / m_LastViewParameters.fNear; - m_fRadiusY = 0.5f * (m_LastViewParameters.fWT - m_LastViewParameters.fWB) * fDistance / m_LastViewParameters.fNear; - - m_vQuadCorners[0] = vUnProjPos[0] - m_vPos; - m_vQuadCorners[1] = vUnProjPos[1] - m_vPos; - m_vQuadCorners[2] = vUnProjPos[2] - m_vPos; - m_vQuadCorners[3] = vUnProjPos[3] - m_vPos; - m_nLastBestEdge = dwBestEdge; - - m_bScreenImposter = false; - // store points used in later error estimation - m_vNearPoint = -m_LastViewParameters.vZ * m_LastViewParameters.fNear + m_LastViewParameters.vOrigin; - m_vFarPoint = -m_LastViewParameters.vZ * m_LastViewParameters.fFar + m_LastViewParameters.vOrigin; - } - else - { // inside cloud - //m_LastCamera.fFar = m_LastCamera.fNear + 3 * fRadius; - m_bScreenImposter = true; - } - - return true; -} - -bool CREImposter::UpdateImposter() -{ - if (!PrepareForUpdate()) - { - return true; - } - - //PrepareForUpdate(); - - PROFILE_FRAME(Imposter_Update); - - CD3D9Renderer* rd = gcpRendD3D; - - int iResX = 1 << m_nLogResolutionX; - int iResY = 1 << m_nLogResolutionY; - - rd->FX_SetState(GS_DEPTHWRITE); - - int iOldVP[4]; - rd->GetViewport(&iOldVP[0], &iOldVP[1], &iOldVP[2], &iOldVP[3]); - - IDynTexture** pDT; //, *pDTDepth; - if (!m_bSplit) - { - if (!m_bScreenImposter) - { - pDT = &m_pTexture; - } - else - { - pDT = &m_pScreenTexture; - } - - if (!*pDT) - { - *pDT = new SDynTexture2(iResX, iResY, FT_STATE_CLAMP, "Imposter", eTP_Clouds); - } - - //if (!m_pTextureDepth) - // m_pTextureDepth = new SDynTexture2(iResX, iResY, eTF_G16R16F, eTT_2D, FT_STATE_CLAMP, "ImposterDepth"); -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumImpostersUpdates++; -#endif - if (*pDT) // && m_pTextureDepth) - { - //pDTDepth = m_pTextureDepth; - (*pDT)->Update(iResX, iResY); - CTexture* pT = (CTexture*)(*pDT)->GetTexture(); - int nSize = pT->GetDataSize(); - m_MemUpdated += nSize / 1024; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ImpostersSizeUpdate += nSize; - //pDTDepth->Update(iResX, iResY); - //ColorF col = ColorF(0,0,0,0); - //pDT->m_pTexture->Fill(col); - //pDTDepth->m_pTexture->Fill(Col_White); - SDepthTexture* pDepth = rd->FX_GetDepthSurface(iResX, iResY, false); - (*pDT)->ClearRT(); - (*pDT)->SetRT(0, true, pDepth); - //rd->FX_PushRenderTarget(1, pDTDepth->m_pTexture, NULL); - gTexture = pT; - rd->FX_ClearTarget(pDepth); - float fYFov, fXFov, fAspect, fNearest, fFar; - m_LastViewParameters.GetPerspectiveParams(&fYFov, &fXFov, &fAspect, &fNearest, &fFar); - CCamera EngCam; - CCamera OldCam = rd->GetCamera(); - int nW = iResX; - int nH = iResY; - //fXFov = DEG2RAD(fXFov); - fYFov = DEG2RAD(fYFov); - fXFov = DEG2RAD(fXFov); - if (m_bScreenImposter) - { - nW = rd->GetWidth(); - nH = rd->GetHeight(); - fXFov = EngCam.GetFov(); - } - Matrix34 matr; - matr = Matrix34::CreateFromVectors(m_LastViewParameters.vX, -m_LastViewParameters.vZ, m_LastViewParameters.vY, m_LastViewParameters.vOrigin); - EngCam.SetMatrix(matr); - EngCam.SetFrustum(nW, nH, fXFov, fNearest, fFar); - //rd->SetCamera(EngCam); - //m_LastCamera.fFar += 100; - rd->m_TranspOrigCameraProjMatrix = rd->m_ViewProjMatrix.GetTransposed(); - rd->ApplyViewParameters(m_LastViewParameters); - - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - rd->Logv(SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID], " +++ Start Imposter scene +++ \n"); - } - - int nFL = rd->m_RP.m_PersFlags2; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_IMPOSTERGEN; - rd->m_RP.m_PersFlags2 |= RBPF2_NOALPHABLEND | RBPF2_NOALPHATEST; - rd->m_RP.m_StateAnd &= ~(GS_BLEND_MASK | GS_ALPHATEST_MASK); - - assert(!"GetI3DEngine()->RenderImposterContent() does not exist"); - //gEnv->p3DEngine->RenderImposterContent(this, EngCam); - rd->m_RP.m_PersFlags2 = nFL; - - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - rd->Logv(SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID], " +++ End Imposter scene +++ \n"); - } - - if (rd->m_logFileHandle != AZ::IO::InvalidHandle) - { - rd->Logv(SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID], " +++ Postprocess Imposter +++ \n"); - } - - (*pDT)->RestoreRT(0, true); - //rd->FX_PopRenderTarget(1); - - rd->SetCamera(OldCam); - } - } - rd->RT_SetViewport(iOldVP[0], iOldVP[1], iOldVP[2], iOldVP[3]); - - return true; -} - -bool CREImposter::Display(bool bDisplayFrontOfSplit) -{ - if (SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID] > 0) - { - return false; - } - - //return true; - CD3D9Renderer* rd = gcpRendD3D; - CShader* pSH = rd->m_RP.m_pShader; - SShaderTechnique* pSHT = rd->m_RP.m_pCurTechnique; - SShaderPass* pPass = rd->m_RP.m_pCurPass; -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumImpostersDraw++; -#endif - Vec3 vPos = m_vPos; - - uint32 nPasses = 0; - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - STexState sTexStatePoint = STexState(FILTER_POINT, true); - STexState sTexStateLinear = STexState(FILTER_LINEAR, true); - if (!m_pTexture || (bDisplayFrontOfSplit && !m_pFrontTexture)) - { - Warning("WRANING: CREImposter::mfDisplay: missing texture!"); - } - else - { - IDynTexture* pDT; - if (bDisplayFrontOfSplit) - { - pDT = m_pFrontTexture; - } - else - { - pDT = m_pTexture; - - pDT->Apply(0, CTexture::GetTexState(sTexStateLinear)); - pDT->Apply(1, CTexture::GetTexState(sTexStatePoint)); - } - - //pDT = m_pTextureDepth; - //pDT->Apply(1); - } - - int State = m_State; //GS_BLSRC_ONE | GS_BLDST_ONEMINUSSRCALPHA | GS_ALPHATEST_GREATER0; - if (m_bSplit) - { - if (!bDisplayFrontOfSplit) - { - State |= GS_DEPTHWRITE; - } - else - { - State |= GS_NODEPTHTEST; - } - } - rd->FX_SetState(State, m_AlphaRef); - if (CRenderer::CV_r_usezpass && CTexture::s_ptexZTarget) - { - rd->FX_PushRenderTarget(1, CTexture::s_ptexZTarget, NULL); - } - - Vec3 x, y, z; - - if (!m_bScreenImposter) - { - z = vPos - m_LastViewParameters.vOrigin; - z.Normalize(); - x = (z ^ m_LastViewParameters.vY); - x.Normalize(); - x *= m_fRadiusX; - y = (x ^ z); - y.Normalize(); - y *= m_fRadiusY; - - const CameraViewParameters& cam = rd->GetViewParameters(); - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - cam.GetModelviewMatrix((float*)m); - m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - mathMatrixPerspectiveOffCenter(m, cam.fWL, cam.fWR, cam.fWB, cam.fWT, cam.fNear, cam.fFar); - - rd->D3DSetCull(eCULL_None); - pSH->FXBeginPass(0); - - rd->DrawQuad3D(vPos - y - x, vPos - y + x, vPos + y + x, vPos + y - x, Col_White, 0, 1, 1, 0); - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 4) - { - rd->GetIRenderAuxGeom()->DrawAABB(AABB(m_WorldSpaceBV.GetMin(), m_WorldSpaceBV.GetMax()), false, Col_White, eBBD_Faceted); - } - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 2) - { - ColorB col = Col_Yellow; //ColorB(colR<<4, colG<<4, colB<<4, 255); - Vec3 v[4]; - v[0] = vPos - y - x; - v[1] = vPos - y + x; - v[2] = vPos + y + x; - v[3] = vPos + y - x; - vtx_idx inds[6]; - inds[0] = 0; - inds[1] = 1; - inds[2] = 2; - inds[3] = 0; - inds[4] = 2; - inds[5] = 3; - - SAuxGeomRenderFlags auxFlags; - auxFlags.SetFillMode(e_FillModeWireframe); - auxFlags.SetDepthTestFlag(e_DepthTestOn); - rd->GetIRenderAuxGeom()->SetRenderFlags(auxFlags); - rd->GetIRenderAuxGeom()->DrawTriangles(v, 4, inds, 6, col); - } - } - else - { - x = m_LastViewParameters.vX; - x *= 0.5f * (m_LastViewParameters.fWR - m_LastViewParameters.fWL); - y = m_LastViewParameters.vY; - y *= 0.5f * (m_LastViewParameters.fWT - m_LastViewParameters.fWB); - z = -m_LastViewParameters.vZ; - z *= m_LastViewParameters.fNear; - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_impostersdraw & 4) - { - rd->GetIRenderAuxGeom()->DrawAABB(AABB(m_WorldSpaceBV.GetMin(), m_WorldSpaceBV.GetMax()), false, Col_Red, eBBD_Faceted); - } - // draw a polygon with this texture... - Matrix44A origMatProj = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - mathMatrixOrthoOffCenter(&rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj, -1, 1, -1, 1, -1, 1); - - Matrix44A origMatView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - pSH->FXBeginPass(0); - - rd->DrawQuad3D(Vec3(-1, -1, 0), Vec3(1, -1, 0), Vec3(1, 1, 0), Vec3(-1, 1, 0), Col_White, 0, 1, 1, 0); - - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - if (CRenderer::CV_r_usezpass && CTexture::s_ptexZTarget) - { - rd->FX_PopRenderTarget(1); - } - - rd->m_RP.m_pShader = pSH; - rd->m_RP.m_pCurTechnique = pSHT; - rd->m_RP.m_pCurPass = pPass; - - return true; -} - -bool CREImposter::mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* pPass) -{ - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_impostersdraw) - { - return true; - } - - Display(false); - - if (IsSplit()) - { - // display contained instances -- first opaque, then transparent. - /*InstanceIterator ii; - for (ii = containedOpaqueInstances.begin(); ii != containedOpaqueInstances.end(); ++ii) - FAIL_RETURN((*ii)->Display()); - for (ii = containedTransparentInstances.begin(); ii != containedTransparentInstances.end(); ++ii) - FAIL_RETURN((*ii)->Display());*/ - - // now display the front half of the split impostor. - Display(true); - } - return true; -} - -////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline.cpp deleted file mode 100644 index 37fb0e1880..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline.cpp +++ /dev/null @@ -1,6675 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Direct3D rendering pipeline. - - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include -#include -#include - -#include "RenderBus.h" -#include "D3DPostProcess.h" -#include "D3DStereo.h" -#include "D3DHWShader.h" -#include "D3DTiledShading.h" -#include -#include "Shaders/CShader.h" -#include "Shaders/RemoteCompiler.h" -#include "ReverseDepth.h" -#include "MultiLayerAlphaBlendPass.h" -#include "Textures/TextureManager.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DRENDPIPELINE_CPP_SECTION_1 1 -#define D3DRENDPIPELINE_CPP_SECTION_2 2 -#define D3DRENDPIPELINE_CPP_SECTION_3 3 -#define D3DRENDPIPELINE_CPP_SECTION_4 4 -#define D3DRENDPIPELINE_CPP_SECTION_5 5 -#endif - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif -#include "RenderCapabilities.h" -#include -#include "GraphicsPipeline/Common/GraphicsPipelinePass.h" -#include "Common/RenderView.h" -#include "GraphicsPipeline/FurBendData.h" -#include "GraphicsPipeline/FurPasses.h" - -#include -#include "MathConversion.h" - -#include -#include - -extern SHWOccZBuffer HWZBuffer; - -const static int BEFORE_WATER = 0; -const static int AFTER_WATER = 1; - -const int CD3D9Renderer::s_gmemRendertargetSlots[eGT_PathCount][eGT_RenderTargetCount] = -{ -// { eGT_Diffuse, eGT_Specular, eGT_Normals, eGT_DepthStencil, eGT_DiffuseLight, eGT_SpecularLight, eGT_VelocityBuffer } - { -1, -1, -1, -1, -1, -1, -1 }, // eGT_REGULAR_PATH - { 1, 2, 5, 3, 4, 0, -1 }, // eGT_256bpp_PATH - { 1, 2, 0, 3, 1, 0, 4 } // eGT_128bpp_PATH -}; - -//============================================================================================ -// Shaders rendering -//============================================================================================ - -//============================================================================================ -// Init Shaders rendering -void CD3D9Renderer::EF_InitWaveTables() -{ - int i; - - //Init wave Tables - for (i = 0; i < SRenderPipeline::sSinTableCount; i++) - { - float f = (float)i; - - m_RP.m_tSinTable[i] = sin_tpl(f * (360.0f / (float)SRenderPipeline::sSinTableCount) * (float)M_PI / 180.0f); - } -} - -static DXGI_FORMAT AttributeTypeDXGIFormatTable[(unsigned int)AZ::Vertex::AttributeType::NumTypes] = -{ - DXGI_FORMAT::DXGI_FORMAT_R16_FLOAT, //Float16_1" - DXGI_FORMAT::DXGI_FORMAT_R16G16_FLOAT, //Float16_2" - DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_FLOAT, //Float16_4" - - DXGI_FORMAT::DXGI_FORMAT_R32_FLOAT, //Float32_1" - DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT, //Float32_2" - DXGI_FORMAT::DXGI_FORMAT_R32G32B32_FLOAT, //Float32_3" - DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_FLOAT, //Float32_4" - - DXGI_FORMAT::DXGI_FORMAT_R8_UNORM, //Byte_1" - DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM, //Byte_2" - DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM, //Byte_4" - - DXGI_FORMAT::DXGI_FORMAT_R16_TYPELESS, //Short_1" - DXGI_FORMAT::DXGI_FORMAT_R16G16_TYPELESS, //Short_2" - DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_TYPELESS, //Short_4" - - DXGI_FORMAT::DXGI_FORMAT_R16_UINT, //UInt16_1" - DXGI_FORMAT::DXGI_FORMAT_R16G16_UINT, //UInt16_2" - DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_UINT, //UInt16_4" - - DXGI_FORMAT::DXGI_FORMAT_R32_UINT, //UInt32_1" - DXGI_FORMAT::DXGI_FORMAT_R32G32_UINT, //UInt32_2" - DXGI_FORMAT::DXGI_FORMAT_R32G32B32_UINT, //UInt32_3" - DXGI_FORMAT::DXGI_FORMAT_R32G32B32A32_UINT //UInt32_4" -}; - -AZStd::vector GetD3D11Declaration(const AZ::Vertex::Format& vertexFormat) -{ - AZStd::vector declaration; - uint offset = 0; - // semanticIndices is a vector of zeros that will be incremented for each attribute that shares a usage/semantic name - uint semanticIndices[(uint)AZ::Vertex::AttributeUsage::NumUsages] = { 0 }; - - uint32 attributeCount = 0; - const uint8* vertexAttributes = vertexFormat.GetAttributes(attributeCount); - for (uint ii = 0; ii < attributeCount; ++ii) - { - const uint8 attribute = vertexAttributes[ii]; - - D3D11_INPUT_ELEMENT_DESC elementDescription; - AZ::Vertex::AttributeUsage attributeUsage = AZ::Vertex::Attribute::GetUsage(attribute); - AZ::Vertex::AttributeType attributeType = AZ::Vertex::Attribute::GetType(attribute); - // TEXCOORD semantic name used for Tangents and BiTangents. - if (attributeUsage == AZ::Vertex::AttributeUsage::Tangent || attributeUsage == AZ::Vertex::AttributeUsage::BiTangent) - { - attributeUsage = AZ::Vertex::AttributeUsage::TexCoord; - } - elementDescription.SemanticName = AZ::Vertex::Attribute::GetSemanticName(attribute).c_str(); - - // Get the number of inputs with this usage up to this point, then increment that number - elementDescription.SemanticIndex = semanticIndices[(uint)attributeUsage]; - semanticIndices[(uint)attributeUsage]++; - - elementDescription.Format = AttributeTypeDXGIFormatTable[(uint)attributeType]; - - elementDescription.AlignedByteOffset = offset; - offset += AZ::Vertex::Attribute::GetByteLength(attribute); - - elementDescription.InputSlot = 0; - elementDescription.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - elementDescription.InstanceDataStepRate = 0; - declaration.push_back(elementDescription); - } - declaration.shrink_to_fit(); - return declaration; -} - -// build vertex declarations on demand (for programmable pipeline) -void CD3D9Renderer::EF_OnDemandVertexDeclaration(SOnDemandD3DVertexDeclaration& out, - const int nStreamMask, const AZ::Vertex::Format& vertexFormat, const bool bMorph, const bool bInstanced) -{ - uint32 j; - - AZStd::vector& declarationElements = m_RP.m_D3DVertexDeclarations[vertexFormat.GetEnum()].m_Declaration; - - if (bInstanced) - { - // Create instanced vertex declaration - for (j = 0; j Log("Direct3D texture streaming log file '%s' opened", "Direct3DLogStreaming.txt"); - char time[128]; - char date[128]; - - azstrtime(time); - azstrdate(date); - - AZ::IO::Print(m_logFileStrHandle, "\n==========================================\n"); - AZ::IO::Print(m_logFileStrHandle, "Direct3D Textures streaming Log file opened: %s (%s)\n", date, time); - AZ::IO::Print(m_logFileStrHandle, "==========================================\n"); - } - } - - m_RP.m_MaxVerts = 16384; - m_RP.m_MaxTris = 16384 * 3; - - iLog->Log("Allocate render buffer for particles (%d verts, %d tris)...", m_RP.m_MaxVerts, m_RP.m_MaxTris); - - int n = 0; - - int nSizeV = sizeof(SVF_P3F_C4B_T4B_N3F2);//this is the vertex format used for particles - - n += nSizeV * m_RP.m_MaxVerts + 32; - - n += sizeof(SPipTangents) * m_RP.m_MaxVerts + 32; - - //m_RP.mRendIndices; - n += sizeof(uint16) * 3 * m_RP.m_MaxTris + 32; - - { - byte* buf = new byte[n]; - m_RP.m_SizeSysArray = n; - m_RP.m_SysArray = buf; - if (!buf) - { - iConsole->Exit("Can't allocate buffers for RB"); - } - - memset(buf, 0, n); - - m_RP.m_StreamPtr.Ptr = sAlign0x20(buf); - buf += sizeof(SVF_P3F_C4B_T4B_N3F2) * m_RP.m_MaxVerts + 32; - - m_RP.m_StreamPtrTang.Ptr = sAlign0x20(buf); - buf += sizeof(SPipTangents) * m_RP.m_MaxVerts + 32; - - m_RP.m_RendIndices = (uint16*)sAlign0x20(buf); - m_RP.m_SysRendIndices = m_RP.m_RendIndices; - buf += sizeof(uint16) * 3 * m_RP.m_MaxTris + 32; - } - - EF_Restore(); - - EF_InitWaveTables(); - EF_InitD3DVertexDeclarations(); - CHWShader_D3D::mfInit(); - - { - for (int i = 0; i < RT_COMMAND_BUF_COUNT; i++) - { - for (int j = 0; j < MAX_RECURSION_LEVELS; j++) - { - m_RP.m_DLights[i][j].Reserve(MAX_LIGHTS_NUM); - } - } - } - - // Init RenderObjects - { - m_RP.m_nNumObjectsInPool = SRenderPipeline::sNumObjectsInPool; - - if (m_RP.m_ObjectsPool != nullptr) - { - for (int j = 0; j < (int)(m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT); j++) - { - CRenderObject* pRendObj = &m_RP.m_ObjectsPool[j]; - pRendObj->~CRenderObject(); - } - CryModuleMemalignFree(m_RP.m_ObjectsPool); - } - - // we use a plain allocation and placement new here to garantee the alignment, when using array new, the compiler can store it's size and break the alignment - m_RP.m_ObjectsPool = (CRenderObject*)CryModuleMemalign(sizeof(CRenderObject) * (m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT), 16); - for (int j = 0; j < (int)(m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT); j++) - { - new(&m_RP.m_ObjectsPool[j])CRenderObject(); - } - - CRenderObject** arrPrefill = (CRenderObject**)(alloca(m_RP.m_nNumObjectsInPool * sizeof(CRenderObject*))); - for (int j = 0; j < RT_COMMAND_BUF_COUNT; j++) - { - for (int k = 0; k < m_RP.m_nNumObjectsInPool; ++k) - { - arrPrefill[k] = &m_RP.m_ObjectsPool[j * m_RP.m_nNumObjectsInPool + k]; - } - - m_RP.m_TempObjects[j].PrefillContainer(arrPrefill, m_RP.m_nNumObjectsInPool); - m_RP.m_TempObjects[j].resize(0); - } - } - // Init identity RenderObject - SAFE_DELETE(m_RP.m_pIdendityRenderObject); - m_RP.m_pIdendityRenderObject = aznew CRenderObject(); - m_RP.m_pIdendityRenderObject->Init(); - m_RP.m_pIdendityRenderObject->m_II.m_AmbColor = Col_White; - m_RP.m_pIdendityRenderObject->m_II.m_Matrix.SetIdentity(); - m_RP.m_pIdendityRenderObject->m_RState = 0; - m_RP.m_pIdendityRenderObject->m_ObjFlags |= FOB_RENDERER_IDENDITY_OBJECT; - - // create hdr element - m_RP.m_pREHDR = (CREHDRProcess*)EF_CreateRE(eDATA_HDRProcess); - // create deferred shading element - m_RP.m_pREDeferredShading = (CREDeferredShading*)EF_CreateRE(eDATA_DeferredShading); - - // Create post process render element - m_RP.m_pREPostProcess = (CREPostProcess*)EF_CreateRE(eDATA_PostProcess); - - // Initialize posteffects manager - if (!m_pPostProcessMgr) - { - m_pPostProcessMgr = new CPostEffectsMgr; - m_pPostProcessMgr->Init(); - } - - if (!m_pWaterSimMgr) - { - m_pWaterSimMgr = new CWater; - } - - //SDynTexture::CreateShadowPool(); - - m_RP.m_fLastWaterFOVUpdate = 0; - m_RP.m_LastWaterViewdirUpdate = Vec3(0, 0, 0); - m_RP.m_LastWaterUpdirUpdate = Vec3(0, 0, 0); - m_RP.m_LastWaterPosUpdate = Vec3(0, 0, 0); - m_RP.m_fLastWaterUpdate = 0; - m_RP.m_nLastWaterFrameID = 0; - m_RP.m_nCommitFlags = FC_ALL; - - m_nMaterialAnisoHighSampler = CTexture::GetTexState(STexState(FILTER_ANISO16X, false)); - m_nMaterialAnisoLowSampler = CTexture::GetTexState(STexState(FILTER_ANISO4X, false)); - m_nMaterialAnisoSamplerBorder = CTexture::GetTexState(STexState(FILTER_ANISO16X, TADDR_BORDER, TADDR_BORDER, TADDR_BORDER, 0x0)); - - CDeferredShading::CreateDeferredShading(); - - if (m_pStereoRenderer) - { - m_pStereoRenderer->CreateResources(); - m_pStereoRenderer->Update(); - } - - MultiLayerAlphaBlendPass::InstallInstance(); - FurPasses::InstallInstance(); - - // Initialize occlusion data - InvalidateCoverageBufferData(); - - AZ_Assert(m_pBackBuffer == m_pBackBuffers[CD3D9Renderer::GetCurrentBackBufferIndex(m_pSwapChain)], "Swap chain was not properly swapped"); - - GetDeviceContext().OMSetRenderTargets(1, &m_pBackBuffer, m_pNativeZBuffer); - - ResetToDefault(); - - m_shaderPipelineInitialized = true; -} - -// Invalidate shaders pipeline -void CD3D9Renderer::FX_Invalidate() -{ - for (int i = 0; i < SRenderPipeline::nNumParticleVertexIndexBuffer; ++i) - { - SAFE_DELETE(m_RP.m_pParticleVertexBuffer[i]); - SAFE_DELETE(m_RP.m_pParticleIndexBuffer[i]); - } -} - -void CD3D9Renderer::FX_UnbindStreamSource(D3DBuffer* buffer) -{ - IF (!buffer, 0) - { - return; - } - - for (int i = 0; i < MAX_STREAMS; i++) - { - IF (m_RP.m_VertexStreams[i].pStream == buffer, 0) - { - ID3D11Buffer* pNullBuffer = NULL; - uint32 zeroStrideOffset = 0; - m_DevMan.BindVB(i, 1, &pNullBuffer, &zeroStrideOffset, &zeroStrideOffset); - m_RP.m_VertexStreams[i].pStream = NULL; - } - } - IF (m_RP.m_pIndexStream == buffer, 0) - { - m_DevMan.BindIB(NULL, 0, DXGI_FORMAT_R16_UINT); - m_RP.m_pIndexStream = NULL; - } - - // commit state changes a second time to really unbind right now, not during the next DrawXXX or Commit - m_DevMan.CommitDeviceStates(); -} - -// Restore shaders pipeline -void CD3D9Renderer::EF_Restore() -{ - if (!m_RP.m_MaxTris) - { - return; - } - - FX_Invalidate(); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - m_ComputeVerticesJobExecutors[i].WaitForCompletion(); - } - - // preallocate video memory buffer for particles when using the job system - for (int i = 0; i < SRenderPipeline::nNumParticleVertexIndexBuffer; ++i) - { - m_RP.m_pParticleVertexBuffer[i] = new FencedVB(CV_r_ParticleVerticePoolSize, sizeof(SVF_P3F_C4B_T4B_N3F2)); - m_RP.m_pParticleIndexBuffer[i] = new FencedIB(CV_r_ParticleVerticePoolSize * 3, sizeof(uint16)); - - m_RP.m_pParticleVertexVideoMemoryBase[i] = NULL; - m_RP.m_pParticleindexVideoMemoryBase[i] = NULL; - - m_RP.m_nParticleVertexOffset[i] = 0; - m_RP.m_nParticleIndexOffset[i] = 0; - - m_RP.m_nParticleVertexBufferAvailableMemory = CV_r_ParticleVerticePoolSize * sizeof(SVF_P3F_C4B_T4B_N3F2); - m_RP.m_nParticleIndexBufferAvailableMemory = CV_r_ParticleVerticePoolSize * 3 * sizeof(uint16); - } -} - -void CD3D9Renderer::OnRendererFreeResources(int flags) -{ - // If texture resources are about to be freed by the renderer - if (flags & FRR_TEXTURES) - { - // Release the occlusion readback textures before CTexture::Shutdown is called - for (size_t idx = 0; idx < s_numOcclusionReadbackTextures; idx++) - { - m_occlusionData[idx].Destroy(); - } - } -} - -// Shutdown shaders pipeline -void CD3D9Renderer::FX_PipelineShutdown(bool bFastShutdown) -{ - if (!m_shaderPipelineInitialized) - { - return; - } - - uint32 i, j, n; - - FX_Invalidate(); - - MultiLayerAlphaBlendPass::ReleaseInstance(); - FurPasses::ReleaseInstance(); - - SAFE_DELETE_ARRAY(m_RP.m_SysArray); - m_RP.m_SysVertexPool[0].Free(); - m_RP.m_SysIndexPool[0].Free(); -#if !defined(STRIP_RENDER_THREAD) - m_RP.m_SysVertexPool[1].Free(); - m_RP.m_SysIndexPool[1].Free(); -#endif - for (int index=0; indexRelease(true); - } - CREClientPoly::m_PolysStorage[n][j].Free(); - } - } - - SAFE_RELEASE(m_RP.m_pREHDR); - SAFE_RELEASE(m_RP.m_pREDeferredShading); - SAFE_RELEASE(m_RP.m_pREPostProcess); - SAFE_DELETE(m_pPostProcessMgr); - SAFE_DELETE(m_pWaterSimMgr); - - for (size_t idx = 0; idx < s_numOcclusionReadbackTextures; idx++) - { - m_occlusionData[idx].Destroy(); - } - - //if (m_pStereoRenderer) - // m_pStereoRenderer->ReleaseResources(); - -#if defined(ENABLE_RENDER_AUX_GEOM) - if (m_pRenderAuxGeomD3D) - { - m_pRenderAuxGeomD3D->ReleaseShader(); - } -#endif - - if (!bFastShutdown) - { - CHWShader_D3D::ShutDown(); - } - - m_RP.m_pCurTechnique = 0; - - if (m_RP.m_ObjectsPool != nullptr) - { - for (int objIdx = 0; objIdx < (int)(m_RP.m_nNumObjectsInPool * RT_COMMAND_BUF_COUNT); objIdx++) - { - CRenderObject* pRendObj = &m_RP.m_ObjectsPool[objIdx]; - pRendObj->~CRenderObject(); - } - CryModuleMemalignFree(m_RP.m_ObjectsPool); - } - m_RP.m_ObjectsPool = NULL; - for (int k = 0; k < RT_COMMAND_BUF_COUNT; ++k) - { - m_RP.m_TempObjects[k].clear(); - } - - m_DevMan.SetBlendState(nullptr, nullptr, 0); - m_DevMan.SetRasterState(nullptr); - m_DevMan.SetDepthStencilState(nullptr, 0); - - for (i = 0; i < m_StatesDP.Num(); ++i) - { - SAFE_RELEASE(m_StatesDP[i].pState); - } - for (i = 0; i < m_StatesRS.Num(); ++i) - { - SAFE_RELEASE(m_StatesRS[i].pState); - } - for (i = 0; i < m_StatesBL.Num(); ++i) - { - SAFE_RELEASE(m_StatesBL[i].pState); - } - m_StatesBL.Free(); - m_StatesRS.Free(); - m_StatesDP.Free(); - m_nCurStateRS = ~0U; - m_nCurStateDP = ~0U; - m_nCurStateBL = ~0U; - - CDeferredShading::DestroyDeferredShading(); - - for (unsigned int a = 0; a < m_OcclQueries.size(); a++) - { - m_OcclQueries[a].Release(); - } - - m_shaderPipelineInitialized = false; -} - -void CD3D9Renderer::FX_ResetPipe() -{ - int i; - - FX_SetState(GS_NODEPTHTEST); - D3DSetCull(eCULL_None); - m_RP.m_FlagsStreams_Decl = 0; - m_RP.m_FlagsStreams_Stream = 0; - m_RP.m_FlagsPerFlush = 0; - m_RP.m_FlagsShader_RT = 0; - m_RP.m_FlagsShader_MD = 0; - m_RP.m_FlagsShader_MDV = 0; - m_RP.m_FlagsShader_LT = 0; - m_RP.m_nCommitFlags = FC_ALL; - m_RP.m_PersFlags2 |= RBPF2_COMMIT_PF | RBPF2_COMMIT_CM; - - m_RP.m_nDeferredPrimitiveID = SHAPE_PROJECTOR; - - HRESULT h = FX_SetIStream(NULL, 0, Index16); - - EF_Scissor(false, 0, 0, 0, 0); - m_RP.m_pShader = NULL; - m_RP.m_pCurTechnique = NULL; - for (i = 1; i < VSF_NUM; i++) - { - if (m_RP.m_PersFlags1 & (RBPF1_USESTREAM << i)) - { - m_RP.m_PersFlags1 &= ~(RBPF1_USESTREAM << i); - h = FX_SetVStream(i, NULL, 0, 0); - } - } - - CHWShader_D3D::mfSetGlobalParams(); -} - -void DrawFullScreenQuad(float fLeftU, float fTopV, float fRightU, float fBottomV); - - -//========================================================================== -// Calculate current scene node matrices -void CD3D9Renderer::EF_SetCameraInfo() -{ - m_pRT->RC_SetCamera(); -} - -void CD3D9Renderer::RT_SetCameraInfo() -{ - GetModelViewMatrix(&m_ViewMatrix(0, 0)); - m_CameraMatrix = m_ViewMatrix; - - GetProjectionMatrix(&m_ProjMatrix(0, 0)); - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if (pShaderThreadInfo->m_PersFlags & RBPF_OBLIQUE_FRUSTUM_CLIPPING) - { - Matrix44A mObliqueProjMatrix; - mObliqueProjMatrix.SetIdentity(); - - mObliqueProjMatrix.m02 = pShaderThreadInfo->m_pObliqueClipPlane.n[0]; - mObliqueProjMatrix.m12 = pShaderThreadInfo->m_pObliqueClipPlane.n[1]; - mObliqueProjMatrix.m22 = pShaderThreadInfo->m_pObliqueClipPlane.n[2]; - mObliqueProjMatrix.m32 = pShaderThreadInfo->m_pObliqueClipPlane.d; - - m_ProjMatrix = m_ProjMatrix * mObliqueProjMatrix; - } - - bool bApplySubpixelShift = !(m_RP.m_PersFlags2 & RBPF2_NOPOSTAA); - bApplySubpixelShift &= !(pShaderThreadInfo->m_PersFlags & (RBPF_DRAWTOTEXTURE | RBPF_SHADOWGEN)); - - m_ProjNoJitterMatrix = m_ProjMatrix; - m_ViewProjNoJitterMatrix = m_CameraMatrix * m_ProjMatrix; - - if (bApplySubpixelShift) - { - m_ProjMatrix.m20 += m_TemporalJitterClipSpace.x; - m_ProjMatrix.m21 += m_TemporalJitterClipSpace.y; - } - - m_ViewProjMatrix = m_CameraMatrix * m_ProjMatrix; - m_ViewProjNoTranslateMatrix = m_CameraZeroMatrix[m_RP.m_nProcessThreadID] * m_ProjMatrix; - - // specialized matrix inversion for enhanced precision - Matrix44_tpl mProjInv; - if (mathMatrixPerspectiveFovInverse(&mProjInv, &m_ProjMatrix)) - { - Matrix44_tpl mViewInv; - mathMatrixLookAtInverse(&mViewInv, &m_CameraMatrix); - m_ViewProjInverseMatrix = mProjInv * mViewInv; - } - else - { - m_ViewProjInverseMatrix = m_ViewProjMatrix.GetInverted(); - } - - if (m_RP.m_ObjFlags & FOB_NEAREST) - { - m_CameraMatrixNearest = m_CameraMatrix; - } - - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - m_RP.m_ObjFlags = 0; - - m_NewViewport.fMinZ = pShaderThreadInfo->m_cam.GetZRangeMin(); - m_NewViewport.fMaxZ = pShaderThreadInfo->m_cam.GetZRangeMax(); - m_bViewportDirty = true; - - CHWShader_D3D::mfSetCameraParams(); -} - -/* - Applies the correct HMD tracking pose to the camera. This is done - on the render thread to ensure that we are rendering with the most - up to date poses. -*/ -void CD3D9Renderer::RT_SetStereoCamera() -{ - int threadId = m_RP.m_nProcessThreadID; - - if (m_pStereoRenderer->IsRenderingToHMD()) - { - CCamera camera = m_RP.m_TI[threadId].m_cam; - - const AZ::VR::TrackingState* trackingState = nullptr; - EBUS_EVENT_RESULT(trackingState, AZ::VR::HMDDeviceRequestBus, GetTrackingState); - if (trackingState) - { - const Vec3 position = camera.GetEntityPos(); - Quat rotation = camera.GetEntityRotation(); - - const Vec3 trackedPosition = rotation * AZVec3ToLYVec3(trackingState->pose.position); - rotation = rotation * AZQuaternionToLYQuaternion(trackingState->pose.orientation); - - Matrix34 camMat = Matrix34(rotation); - camMat.SetTranslation(position + trackedPosition); - - AZ::VR::PerEyeCameraInfo cameraInfo; - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, GetPerEyeCameraInfo, static_cast(gRenDev->m_CurRenderEye), camera.GetNearPlane(), camera.GetFarPlane(), cameraInfo); - - const float asymmetricHorizontalTranslation = cameraInfo.frustumPlane.horizontalDistance * camera.GetNearPlane(); - const float asymmetricVerticalTranslation = cameraInfo.frustumPlane.verticalDistance * camera.GetNearPlane(); - - const Vec3 eyeOffset = AZVec3ToLYVec3(cameraInfo.eyeOffset); - - const Matrix34 stereoMat = Matrix34::CreateTranslationMat(eyeOffset); - camera.SetMatrix(camMat * stereoMat); - camera.SetFrustum(1, 1, cameraInfo.fov, camera.GetNearPlane(), camera.GetFarPlane(), 1.0f / cameraInfo.aspectRatio); - camera.SetAsymmetry(asymmetricHorizontalTranslation, asymmetricHorizontalTranslation, asymmetricVerticalTranslation, asymmetricVerticalTranslation); - - SetCamera(camera); - } - else - { - AZ_Warning("VR", false, "Failed to set stereo camera: No tracking state") - } - } -} - -// Set object transform for fixed pipeline shader -void CD3D9Renderer::FX_SetObjectTransform(CRenderObject* obj, [[maybe_unused]] CShader* pSH, [[maybe_unused]] int nTransFlags) -{ - assert(m_pRT->IsRenderThread()); - - m_ViewMatrix = (Matrix44A(obj->m_II.m_Matrix).GetTransposed() * m_CameraMatrix); - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - pShaderThreadInfo->m_matView = m_ViewMatrix; -} - - -//============================================================================== -// Shader Pipeline -//======================================================================= - -void CD3D9Renderer::EF_SetFogColor(const ColorF& Color) -{ - const int nThreadID = m_pRT->GetThreadList(); - - m_uLastBlendFlagsPassGroup = PackBlendModeAndPassGroup(); - - m_RP.m_TI[nThreadID].m_FS.m_CurColor = Color; -} - -// Set current texture color op modes (used in fixed pipeline shaders) -void CD3D9Renderer::SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa) -{ - if (m_bDeviceLost) - { - return; - } - - // Check for the presence of a D3D device - assert(m_Device); - - m_pRT->RC_SetColorOp(eCo, eAo, eCa, eAa); -} - -void CD3D9Renderer::EF_SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa) -{ - const int nThreadID = m_pRT->GetThreadList(); - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[nThreadID]); - - if (eCo != 255 && pShaderThreadInfo->m_eCurColorOp != eCo) - { - pShaderThreadInfo->m_eCurColorOp = eCo; - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } - if (eAo != 255 && pShaderThreadInfo->m_eCurAlphaOp != eAo) - { - pShaderThreadInfo->m_eCurAlphaOp = eAo; - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } - if (eCa != 255 && pShaderThreadInfo->m_eCurColorArg != eCa) - { - pShaderThreadInfo->m_eCurColorArg = eCa; - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } - if (eAa != 255 && pShaderThreadInfo->m_eCurAlphaArg != eAa) - { - pShaderThreadInfo->m_eCurAlphaArg = eAa; - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } -} - -// Set whether fixed pipeline shaders should convert linear color space to sRGB on write -void CD3D9Renderer::SetSrgbWrite(bool srgbWrite) -{ - if (m_bDeviceLost) - { - return; - } - - // Check for the presence of a D3D device - assert(m_Device); - - m_pRT->RC_SetSrgbWrite(srgbWrite); -} - -void CD3D9Renderer::EF_SetSrgbWrite(bool sRGBWrite) -{ - const int nThreadID = m_pRT->GetThreadList(); - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[nThreadID]); - - if (pShaderThreadInfo->m_sRGBWrite != sRGBWrite) - { - pShaderThreadInfo->m_sRGBWrite = sRGBWrite; - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - } -} - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DRENDPIPELINE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DRendPipeline_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -// -void CD3D9Renderer::CopyFramebufferDX11(CTexture* pDst, ID3D11Resource* pSrcResource, D3DFormat srcFormat) -{ - // Simulated texture copy to overcome the format dismatch issue for texture-blit. - // TODO: use partial update. - CShader* pShader = CShaderMan::s_shPostEffects; - static CCryNameTSCRC techName("TextureToTexture"); - pShader->FXSetTechnique(techName); - - // Try get the pointer to the actual backbuffer - ID3D11Texture2D* pBackBufferTex = (ID3D11Texture2D*)pSrcResource; - - // create the shader res view on the fly - D3DShaderResourceView* shaderResView; // released at the end of this func - D3D11_SHADER_RESOURCE_VIEW_DESC svDesc; - ZeroStruct(svDesc); - svDesc.Format = srcFormat; - svDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - svDesc.Texture2D.MipLevels = 1; - svDesc.Texture2D.MostDetailedMip = 0; - HRESULT hr; - if (!SUCCEEDED(hr = GetDevice().CreateShaderResourceView(pBackBufferTex, &svDesc, &shaderResView))) - { - iLog->LogError("Creating shader resource view has failed. Code: %d", hr); - } - - // render - uint32 nPasses = 0; - pShader->FXBegin(&nPasses, FEF_DONTSETTEXTURES); - FX_PushRenderTarget(0, pDst, NULL); - ID3D11RenderTargetView* pNullRTV = NULL; - GetDeviceContext().OMSetRenderTargets(1, &pNullRTV, NULL); - pShader->FXBeginPass(0); - FX_SetState(GS_NODEPTHTEST); - - // Set shader resource - m_DevMan.BindSRV(eHWSC_Pixel, shaderResView, 0); - - // Set sampler state: - int tsIdx = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); // get the sampler state cache line index - ID3D11SamplerState* linearSampler = static_cast (CTexture::s_TexStates[tsIdx].m_pDeviceState); - m_DevMan.BindSampler(eHWSC_Pixel, &linearSampler, 0, 1); - SPostEffectsUtils::DrawFullScreenTri(pDst->GetWidth(), pDst->GetHeight()); - // unbind backbuffer: - D3DShaderResourceView* pNullSTV = NULL; - m_DevMan.BindSRV(eHWSC_Pixel, pNullSTV, 0); - CTexture::s_TexStages[0].m_DevTexture = NULL; - - pShader->FXEndPass(); - FX_PopRenderTarget(0); - pShader->FXEnd(); - - GetDeviceContext(); // explicit flush as temp target gets released in next line - SAFE_RELEASE(shaderResView); -} -#endif - -// This function must be refactored post C3 -void CD3D9Renderer::FX_ScreenStretchRect(CTexture* pDst, CTexture* pHDRSrc) -{ - PROFILE_LABEL_SCOPE("SCREEN_STRETCH_RECT"); - if (CTexture::IsTextureExist(pDst)) - { - int iTempX, iTempY, iWidth, iHeight; - gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - uint64 nPrevFlagsShaderRT = gRenDev->m_RP.m_FlagsShader_RT; - gRenDev->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - - { - // update scene target before using it for water rendering - CDeviceTexture* pDstResource = pDst->GetDevTexture(); - ID3D11RenderTargetView* pOrigRT = m_pNewTarget[0]->m_pTarget; - ID3D11Resource* pSrcResource; - - // This is a subrect to subrect copy with no resolving or stretching - D3D11_BOX box; - ZeroStruct(box); - box.right = pDst->GetWidth(); - box.bottom = pDst->GetHeight(); - box.back = 1; - - //Allow for scissoring to happen - int sX, sY, sWdt, sHgt; - if (EF_GetScissorState(sX, sY, sWdt, sHgt)) - { - box.left = sX; - box.right = sX + sWdt; - box.top = sY; - box.bottom = sY + sHgt; - - // Align the RECT boundaries to GPU memory layout - box.left = box.left & 0xfffffff8; - box.top = box.top & 0xfffffff8; - box.right = min((int)((box.right + 8) & 0xfffffff8), iWidth); - box.bottom = min((int)((box.bottom + 8) & 0xfffffff8), iHeight); - } - - D3D11_RENDER_TARGET_VIEW_DESC backbufferDesc; - if (pOrigRT) - { - pOrigRT->GetResource(&pSrcResource); - pOrigRT->GetDesc(&backbufferDesc); - if (backbufferDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS || pHDRSrc) - { - // No API side for ResolveSubresourceRegion from MS target to non-ms. Need to perform custom resolve step - if ((CTexture::s_ptexSceneTarget && (CTexture::s_ptexHDRTarget || pHDRSrc) && CTexture::s_ptexCurrentSceneDiffuseAccMap)) - { - if (backbufferDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS) - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - CTexture* pHDRTarget = pHDRSrc ? pHDRSrc : CTexture::s_ptexHDRTarget; - pHDRTarget->SetResolved(true); - - FX_PushRenderTarget(0, pDst, 0); - FX_SetActiveRenderTargets(); - - RT_SetViewport(0, 0, pDst->GetWidth(), pDst->GetHeight()); - - static CCryNameTSCRC pTechName("TextureToTexture"); - SPostEffectsUtils::ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - FX_SetState(GS_NODEPTHTEST); - - pHDRTarget->Apply(0, CTexture::GetTexState(STexState(FILTER_POINT, true)), EFTT_UNKNOWN, -1, m_RP.m_MSAAData.Type ? SResourceView::DefaultViewMS : SResourceView::DefaultView); - - SPostEffectsUtils::DrawFullScreenTri(pDst->GetWidth(), pDst->GetHeight()); - SPostEffectsUtils::ShEndPass(); - - // Restore previous viewport - FX_PopRenderTarget(0); - RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - pHDRTarget->SetResolved(false); - } - else - { - GetDeviceContext().ResolveSubresource(pDstResource->Get2DTexture(), 0, pSrcResource, 0, backbufferDesc.Format); - } - } - else - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DRENDPIPELINE_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DRendPipeline_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - // Check if the format match (or the copysubregionresource call would fail) - const D3DFormat dstFmt = CTexture::DeviceFormatFromTexFormat(pDst->GetDstFormat()); - const D3DFormat srcFmt = backbufferDesc.Format; - if (dstFmt == srcFmt) - { -# if !defined(_RELEASE) - D3D11_RESOURCE_DIMENSION type; - pSrcResource->GetType(&type); - if (type != D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - __debugbreak(); - } -#endif - ID3D11Texture2D* pSrcTex2D = (ID3D11Texture2D*)pSrcResource; - D3D11_TEXTURE2D_DESC srcTex2desc; - pSrcTex2D->GetDesc(&srcTex2desc); - - box.left = min(box.left, srcTex2desc.Width); - box.right = min(box.right, srcTex2desc.Width); - box.top = min(box.top, srcTex2desc.Height); - box.bottom = min(box.bottom, srcTex2desc.Height); - - GetDeviceContext().CopySubresourceRegion(pDstResource->Get2DTexture(), 0, box.left, box.top, 0, pSrcResource, 0, &box); - } - else - { - // deal with format mismatch case: - EF_Scissor(false, 0, 0, 0, 0); // TODO: optimize. dont use full screen pass. - CopyFramebufferDX11(pDst, pSrcResource, backbufferDesc.Format); - EF_Scissor(true, sX, sY, sWdt, sHgt); - } -#endif - } -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DRENDPIPELINE_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DRendPipeline_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - SAFE_RELEASE(pSrcResource); -#endif - } - } - - gRenDev->m_RP.m_FlagsShader_RT = nPrevFlagsShaderRT; - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_SkinRendering(bool bEnable) -{ - if (bEnable) - { - FX_ScreenStretchRect(CTexture::s_ptexCurrentSceneDiffuseAccMap, CTexture::s_ptexHDRTarget); - - RT_SetViewport(0, 0, CTexture::s_ptexSceneTarget->GetWidth(), CTexture::s_ptexSceneTarget->GetHeight()); - } - else - { - FX_ResetPipe(); - gcpRendD3D->RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight()); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::FX_ProcessSkinRenderLists(int nList, void(* RenderFunc)(), bool bLighting) -{ - // Forward SSS completely disabled, except for the character editor where we just do a simple forward pass - if (m_RP.m_PersFlags2 & RBPF2_ALLOW_DEFERREDSHADING) - { - return; - } - - const int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - const bool bUseDeferredSkin = ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0) && CV_r_DeferredShadingDebug != 2 && CV_r_measureoverdraw == 0; - - //if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && nR <= 1) && CV_r_DeferredShadingDebug != 2) - { - uint32 nBatchMask = SRendItem::BatchFlags(nList, m_RP.m_pRLD); - if (nBatchMask & FB_SKIN) - { -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Begin skin pass ***\n"); - } -#endif - - { - PROFILE_LABEL_SCOPE("SKIN_GEN_PASS"); - - if (bUseDeferredSkin) - { - m_RP.m_PersFlags2 |= RBPF2_SKIN; - } - - FX_ProcessRenderList(nList, BEFORE_WATER, RenderFunc, bLighting); - FX_ProcessRenderList(nList, AFTER_WATER , RenderFunc, bLighting); - - if (bUseDeferredSkin) - { - m_RP.m_PersFlags2 &= ~RBPF2_SKIN; - } - } - - if (bUseDeferredSkin) - { - PROFILE_LABEL_SCOPE("SKIN_APPLY_PASS"); - - FX_SkinRendering(true); - - FX_ProcessRenderList(nList, BEFORE_WATER, RenderFunc, bLighting); - FX_ProcessRenderList(nList, AFTER_WATER , RenderFunc, bLighting); - - FX_SkinRendering(false); - } - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End skin pass ***\n"); - } -#endif - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::FX_ProcessEyeOverlayRenderLists(int nList, void(* RenderFunc)(), bool bLighting) -{ - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0) - { - int iTempX, iTempY, iWidth, iHeight; - gcpRendD3D->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - PROFILE_LABEL_SCOPE("EYE_OVERLAY"); - - SDepthTexture* pCurrDepthBuffer = (gRenDev->m_RP.m_MSAAData.Type) ? &gcpRendD3D->m_DepthBufferOrigMSAA : &gcpRendD3D->m_DepthBufferOrig; - - FX_PushRenderTarget(0, CTexture::s_ptexSceneDiffuse, pCurrDepthBuffer); - - FX_ProcessRenderList(nList, BEFORE_WATER, RenderFunc, bLighting); - FX_ProcessRenderList(nList, AFTER_WATER , RenderFunc, bLighting); - - FX_PopRenderTarget(0); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::FX_ProcessHalfResParticlesRenderList(int nList, void(* RenderFunc)(), bool bLighting) -{ - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0) - { - const int nums = m_RP.m_pRLD->m_nStartRI[1][nList]; - if (m_RP.m_pRLD->m_nEndRI[1][nList] - nums > 0) - { - CRenderView::CurrentRenderView()->GetRenderItems(1, nList); - const bool bAlphaBased = CV_r_ParticlesHalfResBlendMode == 0; - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Begin half res transparent pass ***\n"); - } -#endif - - CTexture* pHalfResTarget = CTexture::s_ptexHDRTargetScaled[CV_r_ParticlesHalfResAmount]; - assert(CTexture::IsTextureExist(pHalfResTarget)); - if (CTexture::IsTextureExist(pHalfResTarget)) - { - const int nHalfWidth = pHalfResTarget->GetWidth(); - const int nHalfHeight = pHalfResTarget->GetHeight(); - - PROFILE_LABEL_SCOPE("TRANSP_HALF_RES_PASS"); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - FX_PushRenderTarget(0, pHalfResTarget, NULL); - FX_SetColorDontCareActions(0); - FX_ClearTarget(pHalfResTarget, Clr_Empty); - RT_SetViewport(0, 0, nHalfWidth, nHalfHeight); - - m_RP.m_PersFlags2 |= RBPF2_HALFRES_PARTICLES; - const uint32 nOldForceStateAnd = m_RP.m_ForceStateAnd; - const uint32 nOldForceStateOr = m_RP.m_ForceStateOr; - m_RP.m_ForceStateOr = GS_NODEPTHTEST; - if (bAlphaBased) - { - m_RP.m_ForceStateAnd = GS_BLSRC_SRCALPHA; - m_RP.m_ForceStateOr |= GS_BLSRC_SRCALPHA_A_ZERO; - } - FX_ProcessRenderList(nList, AFTER_WATER, RenderFunc, bLighting); - m_RP.m_ForceStateAnd = nOldForceStateAnd; - m_RP.m_ForceStateOr = nOldForceStateOr; - m_RP.m_PersFlags2 &= ~RBPF2_HALFRES_PARTICLES; - -#if defined(CRY_USE_METAL) - //In metal Clear calls are cached until a draw call is made. If nothing is rendered do a manual clear - if (m_RP.m_RendNumVerts == 0) - { - FX_Commit(); - FX_ClearTargetRegion(); - } -#endif - - FX_PopRenderTarget(0); - - { - PROFILE_LABEL_SCOPE("UPSAMPLE_PASS"); - CTexture* pHalfResSrc = pHalfResTarget; - CTexture* pZTarget = CTexture::s_ptexZTarget; - CTexture* pZTargetScaled = CV_r_ParticlesHalfResAmount > 0 ? CTexture::s_ptexZTargetScaled2 : CTexture::s_ptexZTargetScaled; - - uint32 nStates = GS_NODEPTHTEST | GS_COLMASK_RGB; - if (bAlphaBased) - { - nStates |= GS_BLSRC_ONE | GS_BLDST_SRCALPHA; - } - else - { - nStates |= GS_BLSRC_ONE | GS_BLDST_ONE; - } - - RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - static const CCryNameTSCRC pTechNameNearestDepth("NearestDepthUpsample"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pTechNameNearestDepth, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - static CCryNameR pParam0Name("texToTexParams0"); - Vec4 vParam0(pZTarget->GetWidth(), pZTarget->GetHeight(), pZTargetScaled->GetWidth(), pZTargetScaled->GetHeight()); - CShaderMan::s_shPostEffects->FXSetPSFloat(pParam0Name, &vParam0, 1); - - PostProcessUtils().SetTexture(pHalfResSrc, 1, FILTER_LINEAR); - PostProcessUtils().SetTexture(pZTarget, 2, FILTER_POINT); - PostProcessUtils().SetTexture(pZTargetScaled, 3, FILTER_POINT); - - FX_SetState(nStates); - PostProcessUtils().DrawFullScreenTri(m_width, m_height); - - PostProcessUtils().ShEndPass(); - } - } - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End half res transparent pass ***\n"); - } -#endif - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Checks if we need to enable velocity pass. -bool CD3D9Renderer::IsVelocityPassEnabled() const -{ - bool takingScreenShot = (m_screenShotType != 0); - bool bUseMotionVectors = (CV_r_MotionBlur || (FX_GetAntialiasingType() & eAT_TEMPORAL_MASK) != 0) && CV_r_MotionVectors && (!takingScreenShot || CV_r_MotionBlurScreenShot); - return bUseMotionVectors && CV_r_MotionBlurGBufferVelocity; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Output g-buffer -bool CD3D9Renderer::FX_ZScene(bool bEnable, bool bClearZBuffer, bool bRenderNormalsOnly, bool bZPrePass) -{ - AZ_TRACE_METHOD(); - - uint32 nDiffuseTargetID = 1; - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if (bEnable) - { - pShaderThreadInfo->m_PersFlags |= RBPF_ZPASS; - - int nStates = GS_DEPTHWRITE; - FX_SetState(nStates); - - const int nWidth = m_MainViewport.nWidth; - const int nHeight = m_MainViewport.nHeight; - if (bClearZBuffer) - { - const float clearDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 0.f : 1.f; - const uint clearStencil = 1; - RECT rect = { 0, 0, nWidth, nHeight }; - - // Stencil initialized to 1 - 0 is reserved for MSAAed samples - FX_ClearTarget(&m_DepthBufferOrigMSAA, CLEAR_ZBUFFER | CLEAR_STENCIL, clearDepth, clearStencil, 1, &rect, true); - m_nStencilMaskRef = 1; - } - - m_RP.m_PersFlags2 |= RBPF2_NOALPHABLEND | (bZPrePass ? (RBPF2_ZPREPASS | RBPF2_DISABLECOLORWRITES) : RBPF2_NOALPHATEST); - m_RP.m_StateAnd &= ~(GS_BLEND_MASK | GS_ALPHATEST_MASK); - m_RP.m_StateAnd |= bZPrePass ? GS_ALPHATEST_MASK : 0; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Start Z scene +++ \n"); - } - - // RTs resolves/restores occur in CD3D9Renderer::FX_GmemTransition(...) - if (FX_GetEnabledGmemPath(nullptr)) - { - if (IsVelocityPassEnabled() && FX_GetEnabledGmemPath(nullptr) == CD3D9Renderer::eGT_128bpp_PATH ) - { - m_RP.m_PersFlags2 |= RBPF2_MOTIONBLURPASS; - } - return true; - } - - if (!CTexture::s_ptexZTarget - || CTexture::s_ptexZTarget->IsMSAAChanged() - || CTexture::s_ptexZTarget->GetDstFormat() != CTexture::s_eTFZ - || CTexture::s_ptexZTarget->GetWidth() != nWidth - || CTexture::s_ptexZTarget->GetHeight() != nHeight) - { - FX_Commit(); // Flush to unset the Z target before regenerating - CTexture::GenerateZMaps(); - } - - bool bClearRT = false; - bClearRT |= CV_r_wireframe != 0; - bClearRT |= !bRenderNormalsOnly; - static ICVar* skyBoxCVar = gEnv->pConsole->GetCVar("e_SkyBox"); - bClearRT |= skyBoxCVar->GetIVal() == 0; - bClearRT |= m_clearBackground; - if (bClearRT) - { - EF_ClearTargetsLater(FRT_CLEAR_COLOR); - // If we don't have a skybox do a clear of the scene normal map. When - // we have a sky box every texel in the normal map is rendered to. - // But when the sky box is disabled then it is possible that left over - // data remains in the normal texture from previous passes and this - // causes rendering artifacts. The check for bClearZBuffer is used to - // make sure we clear the normal map only once and not twice per frame. - if (bClearZBuffer) - { - FX_ClearTarget(CTexture::s_ptexSceneNormalsMap); - } - } - FX_PushRenderTarget(0, CTexture::s_ptexSceneNormalsMap, &m_DepthBufferOrigMSAA, -1, true); - - // CONFETTI BEGIN: David Srour - // Note that the GBUFFER cannot have don't care actions or - // it'll break deferred decals & other similar passes. - FX_SetColorDontCareActions(0, false, false); - // CONFETTI END - -#ifndef CRY_USE_METAL - if (!bZPrePass) -#endif - { - FX_PushRenderTarget(nDiffuseTargetID, CTexture::s_ptexSceneDiffuse, NULL); - - CTexture* pSceneSpecular = CTexture::s_ptexSceneSpecular; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DRENDPIPELINE_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DRendPipeline_cpp) -#endif - FX_PushRenderTarget(nDiffuseTargetID + 1, pSceneSpecular, NULL); - - - FX_SetColorDontCareActions(nDiffuseTargetID, false, false); - FX_SetColorDontCareActions(nDiffuseTargetID + 1, false, false); - - if (IsVelocityPassEnabled()) - { - m_RP.m_PersFlags2 |= RBPF2_MOTIONBLURPASS; - FX_PushRenderTarget(nDiffuseTargetID + 2, GetUtils().GetVelocityObjectRT(), NULL); - } - } - - RT_SetViewport(0, 0, nWidth, nHeight); - - FX_SetActiveRenderTargets(); - } - else if (pShaderThreadInfo->m_PersFlags & RBPF_ZPASS) - { - pShaderThreadInfo->m_PersFlags &= ~RBPF_ZPASS; - - m_RP.m_PersFlags2 &= ~(RBPF2_NOALPHABLEND | RBPF2_NOALPHATEST | RBPF2_ZPREPASS | RBPF2_DISABLECOLORWRITES); - m_RP.m_StateAnd |= (GS_BLEND_MASK | GS_ALPHATEST_MASK); - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ End Z scene +++ \n"); - } - - // RTs resolves/restores occur in CD3D9Renderer::FX_GmemTransition(...) - if (FX_GetEnabledGmemPath(nullptr)) - { - return true; - } - - FX_PopRenderTarget(0); - -#ifndef CRY_USE_METAL - if (!bZPrePass) -#endif - { - FX_PopRenderTarget(nDiffuseTargetID); - FX_PopRenderTarget(nDiffuseTargetID + 1); - if (m_RP.m_PersFlags2 & RBPF2_MOTIONBLURPASS) - { - FX_PopRenderTarget(nDiffuseTargetID + 2); - m_RP.m_PersFlags2 &= ~RBPF2_MOTIONBLURPASS; - } - } - if (bRenderNormalsOnly) - { - CTexture::s_ptexZTarget->Resolve(); - } - } - else - { - if (!CV_r_usezpass) - { - CTexture::DestroyZMaps(); - } - } - - return true; -} - -void CD3D9Renderer::FX_GmemTransition([[maybe_unused]] const EGmemTransitions transition) -{ -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - /* Resources used during the GMEM render paths: - * - * CTexture::s_ptexSceneNormalsMap // 32 bits - * CTexture::s_ptexSceneDiffuse // 32 bits - * CTexture::s_ptexSceneSpecular // 32 bits - * CTexture::s_ptexGmemStenLinDepth // 32 bits - * CTexture::s_ptexCurrentSceneDiffuseAccMap // 64 bits - * CTexture::s_ptexSceneSpecularAccMap // 64 bits - */ - - if (SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID] != 0) - { - return; - } - - CTexture* gmemSceneTarget = CTexture::s_ptexSceneSpecularAccMap; - - int const currentGmemPath = FX_GetEnabledGmemPath(nullptr); - assert(FX_GetEnabledGmemPath(nullptr)); - - // COMMON FUNCTIONS /////////////////////////////////////////////////////////////////////////// - auto UnbindGmemRts = [this](int const startRT, int const endRT) - { - assert(startRT >= 0 && - endRT >= 0 && - startRT <= 5 && - endRT <= 5 && - startRT <= endRT); - - for (auto rt = startRT; rt <= endRT; rt++) - { - FX_PopRenderTarget(rt); - } - }; - - auto BindGBufferRts = [this, gmemSceneTarget](int currentGmemPath, int* outVelocityRT, int* outDepthStencilRT, bool forceLoad = false) - { - /* Bind RTs - * - * 256bpp: - * (0) Specular L-Buffer (used as scene-target during GMEM sections) - * (1) Diffuse - * (2) Spec - * (3) Stencil / Linear Depth - * (4) Diffuse L-Buffer - * (5) Normals - * - * 128bpp: - * (0) Normals - * (1) Diffuse - * (2) Spec - * (3) Stencil / Linear Depth - */ - const int invalidRT = -1; - const int defaultDepthRT = 3; - const int maxGmemRTCount = 6; - - int velocityBufferRT = invalidRT; - int depthStencilRT = defaultDepthRT; - AZStd::vector dontCareColorLoad; - AZStd::vector dontCareColorSave; - AZStd::vector dontCareDepthStencilLoad = { false, false }; - AZStd::vector dontCareDepthStencilSave = { false, false }; - - dontCareColorLoad.reserve(maxGmemRTCount); - dontCareColorSave.reserve(maxGmemRTCount); - if (eGT_256bpp_PATH == currentGmemPath) - { - FX_PushRenderTarget(0, gmemSceneTarget, &m_DepthBufferOrigMSAA, -1, true); - FX_PushRenderTarget(1, CTexture::s_ptexSceneDiffuse, NULL); - FX_PushRenderTarget(2, CTexture::s_ptexSceneSpecular, NULL); - FX_PushRenderTarget(3, CTexture::s_ptexGmemStenLinDepth, NULL); - FX_PushRenderTarget(4, CTexture::s_ptexCurrentSceneDiffuseAccMap, NULL); - FX_PushRenderTarget(5, CTexture::s_ptexSceneNormalsMap, NULL); - - dontCareColorLoad = { true, true, true, true, true, true }; - dontCareColorSave = { false, true, true, false, true, true }; - } - else if (eGT_128bpp_PATH == currentGmemPath) - { - FX_PushRenderTarget(0, CTexture::s_ptexSceneNormalsMap, &m_DepthBufferOrigMSAA, -1, true); - FX_PushRenderTarget(1, CTexture::s_ptexSceneDiffuse, NULL); - FX_PushRenderTarget(2, CTexture::s_ptexSceneSpecular, NULL); - - dontCareColorLoad = { true, true, true, true }; - dontCareColorSave = { false, false, false, false }; - - if (IsVelocityPassEnabled()) - { - if (RenderCapabilities::SupportsRenderTargets(s_gmemLargeRTCount)) - { - dontCareColorLoad.resize(5); - dontCareColorSave.resize(5); - depthStencilRT = 3; - velocityBufferRT = 4; - } - else - { - depthStencilRT = -1; - velocityBufferRT = 3; - } - } - - if (velocityBufferRT != invalidRT) - { - FX_PushRenderTarget(velocityBufferRT, GetUtils().GetVelocityObjectRT(), NULL); - dontCareColorLoad[velocityBufferRT] = true; - dontCareColorSave[velocityBufferRT] = false; - } - - if (depthStencilRT != invalidRT) - { - FX_PushRenderTarget(depthStencilRT, CTexture::s_ptexGmemStenLinDepth, NULL); - dontCareColorLoad[depthStencilRT] = true; - dontCareColorSave[depthStencilRT] = false; - } - } - - if (forceLoad) - { - std::fill(dontCareColorLoad.begin(), dontCareColorLoad.end(), false); - std::fill(dontCareDepthStencilLoad.begin(), dontCareDepthStencilLoad.end(), false); - } - - for (int i = 0; i < dontCareColorLoad.size(); ++i) - { - FX_SetColorDontCareActions(i, dontCareColorLoad[i], dontCareColorSave[i]); - } - - FX_SetDepthDontCareActions(0, dontCareDepthStencilLoad[0], dontCareDepthStencilSave[0]); - FX_SetStencilDontCareActions(0, dontCareDepthStencilLoad[1], dontCareDepthStencilSave[1]); - - if (outVelocityRT) - { - *outVelocityRT = velocityBufferRT; - } - - if (outDepthStencilRT) - { - *outDepthStencilRT = depthStencilRT; - } - }; - - auto ProcessPassesThatDontFitGMEM = [this](bool const linearizeDepth, bool const downsampleDepth, bool const deferredPasses) - { - if (linearizeDepth) - { - FX_LinearizeDepth(CTexture::s_ptexGmemStenLinDepth); - } - - if (downsampleDepth) - { - GetUtils().DownsampleDepth(CTexture::s_ptexGmemStenLinDepth, CTexture::s_ptexZTargetScaled, true); - GetUtils().DownsampleDepth(CTexture::s_ptexZTargetScaled, CTexture::s_ptexZTargetScaled2, true); - static ICVar* checkOcclusion = gEnv->pConsole->GetCVar("e_CheckOcclusion"); - if(checkOcclusion->GetIVal()) - { - //Downsample to the occlusion buffer dimensions - GetUtils().DownsampleDepth(CTexture::s_ptexZTargetScaled2, m_occlusionData[m_occlusionBufferIndex].m_zTargetReadback, true); - } - } - - if (deferredPasses) - { - CDeferredShading::Instance().DirectionalOcclusionPass(); - CDeferredShading::Instance().ScreenSpaceReflectionPass(); - } - }; - - auto ResetGMEMDontCareActions = [this](int const endRT) - { - assert(endRT >= 0); - - for (auto rt = 0; rt <= endRT; rt++) - { - FX_SetColorDontCareActions(rt, false, false); - } - - FX_SetDepthDontCareActions(0, false, false); - FX_SetStencilDontCareActions(0, false, false); - }; - - /////////////////////////////////////////////////////////////////////////////////////////////// - - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - switch (transition) - { - case eGT_PRE_Z: - { - // Setup deferred renderer's lights and shadows for GMEM path - assert(CDeferredShading::IsValid()); - if (IsShadowPassEnabled()) - { - CDeferredShading::Instance().SetupGmemPath(); - } - - RT_SetViewport(0, 0, m_MainViewport.nWidth, m_MainViewport.nHeight); - int velocityRT, depthStencilRT; - BindGBufferRts(currentGmemPath, &velocityRT, &depthStencilRT); - - // Clear depth stencil - EF_ClearTargetsImmediately(FRT_CLEAR_DEPTH | FRT_CLEAR_STENCIL, 1.0f, 1); - m_nStencilMaskRef = 1; - - // Custom clear GMEM G-Buffer if requested - if (depthStencilRT >= 0) - { - if (CRenderer::CV_r_ClearGMEMGBuffer == 1) - { - PROFILE_LABEL_SCOPE("GMEM G-BUFFER CLEAR"); - FX_SetState(GS_NODEPTHTEST | GS_COLMASK_RGB | GS_BLSRC_ONE | GS_BLDST_ZERO); - RT_SetViewport(0, 0, m_MainViewport.nWidth, m_MainViewport.nHeight); - PostProcessUtils().ClearGmemGBuffer(); - } - else if (CRenderer::CV_r_ClearGMEMGBuffer == 2) - { - //Linear depth is set to be cleared to 1.0f. x (linear depth) = 1, y(stencil id) = 0. - FX_SetColorDontCareActions(depthStencilRT, false, false); - FX_ClearTarget(CTexture::s_ptexGmemStenLinDepth, ColorF(1.000f, 0.000f, 0.000f)); - - if (velocityRT > 0) - { - // Clear out the velocity buffer to half2(1.0, 1.0) - FX_SetColorDontCareActions(velocityRT, false, false); - FX_ClearTarget(GetUtils().GetVelocityObjectRT(), Clr_White); - } - } - } - - break; - } - case eGT_POST_GBUFFER: - { - if (FX_GmemGetDepthStencilMode() == eGDSM_Texture) - { - // Since we can't fetch the depth/stencil from the buffer we need to linearize it now. - // The linearized depth is used by the deferred decal, snow and rain passes. - // This will flush the Gbuffer out. - int renderTargetsToUnbind = IsVelocityPassEnabled() && RenderCapabilities::SupportsRenderTargets(s_gmemLargeRTCount) ? 4 : 3; - UnbindGmemRts(0, renderTargetsToUnbind); - ProcessPassesThatDontFitGMEM(true, true, false); - BindGBufferRts(currentGmemPath, nullptr, nullptr, true); - } - break; - } - case eGT_POST_Z_PRE_DEFERRED: - { - /* Resolve RTs for 128bpp path. - * - * Bind RTs - * 128bpp: - * (0) Specular L-Buffer (used as scene-target during GMEM sections) - * (1) Diffuse L-Buffer - */ - if (eGT_128bpp_PATH == currentGmemPath) - { - int renderTargetsToUnbind = IsVelocityPassEnabled() && RenderCapabilities::SupportsRenderTargets(s_gmemLargeRTCount) ? 4 : 3; - - ResetGMEMDontCareActions(renderTargetsToUnbind); - UnbindGmemRts(0, renderTargetsToUnbind); - - EGmemDepthStencilMode depthStencilMode = FX_GmemGetDepthStencilMode(); - ProcessPassesThatDontFitGMEM(depthStencilMode == eGDSM_DepthStencilBuffer, depthStencilMode != eGDSM_Texture, true); - - // Bind RTs - FX_PushRenderTarget(s_gmemRendertargetSlots[currentGmemPath][eGT_SpecularLight], gmemSceneTarget, &m_DepthBufferOrigMSAA, -1, true); - FX_SetColorDontCareActions(s_gmemRendertargetSlots[currentGmemPath][eGT_SpecularLight], true, false); - - // Don't push more than 1 RT if using PLS extension - if (!RenderCapabilities::SupportsPLSExtension()) - { - FX_PushRenderTarget(s_gmemRendertargetSlots[currentGmemPath][eGT_DiffuseLight], CTexture::s_ptexCurrentSceneDiffuseAccMap, NULL); - FX_SetColorDontCareActions(s_gmemRendertargetSlots[currentGmemPath][eGT_DiffuseLight], true, false); - } - else - { - FX_TogglePLS(true); - } - - FX_SetDepthDontCareActions(0, false, false); - FX_SetStencilDontCareActions(0, false, false); - } - break; - } - case eGT_POST_DEFERRED_PRE_FORWARD: - { - ResetGMEMDontCareActions(eGT_256bpp_PATH == currentGmemPath ? 5 : 1); - - // Unbind all but the scene target - // Scene target already bound if using PLS... just need to toggle PLS off - if (RenderCapabilities::SupportsPLSExtension()) - { - FX_TogglePLS(false); - } - else - { - UnbindGmemRts(1, eGT_256bpp_PATH == currentGmemPath ? 5 : 1); - } - - if (eGT_256bpp_PATH == currentGmemPath) - { - ProcessPassesThatDontFitGMEM(false, true, false); - } - break; - } - case eGT_POST_AW_TRANS_PRE_POSTFX: - { - // Unbind scene target - UnbindGmemRts(0, 0); - - // TODO: Behavior for HDR/PostFX passes - break; - } - default: - CRY_ASSERT(0); - break; - } - - FX_SetActiveRenderTargets(); -#endif -} - -CD3D9Renderer::EGmemPath CD3D9Renderer::FX_GetEnabledGmemPath(CD3D9Renderer::EGmemPathState* const gmemPathStateOut) const -{ - // Using local statics since this check should only be done once per run-time - static EGmemPath enabledPath = eGT_REGULAR_PATH; - static EGmemPathState gmemState = eGT_OK; - -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - static bool enabledGmemPathAlreadyChecked = false; - - if (!enabledGmemPathAlreadyChecked) - { - switch (CRenderer::CV_r_EnableGMEMPath) - { - case eGT_REGULAR_PATH: - break; - case eGT_256bpp_PATH: - { - // Does device support this path? - if (!RenderCapabilities::Supports256bppGmemPath()) - { - gmemState = eGT_DEV_UNSUPPORTED; - - // Check if device supports 128bpp path instead - if (RenderCapabilities::Supports128bppGmemPath()) - { - enabledPath = eGT_128bpp_PATH; - } - } - // Check for unsupported rendering features on this path otherwise - else if (CRenderer::CV_r_ssdo || CRenderer::CV_r_SSReflections || - CRenderer::CV_r_MotionBlur > 0 || (FX_GetAntialiasingType() & eAT_TEMPORAL_MASK) != 0) - { - // Force 128bpp path - gmemState = eGT_FEATURES_UNSUPPORTED; - enabledPath = eGT_128bpp_PATH; - } - else - { - enabledPath = eGT_256bpp_PATH; - } - break; - } - case eGT_128bpp_PATH: - { - // Does device support this path? - if (!RenderCapabilities::Supports128bppGmemPath()) - { - gmemState = eGT_DEV_UNSUPPORTED; - } - else - { - enabledPath = eGT_128bpp_PATH; - } - break; - } - default: - CRY_ASSERT(0); - break; - } - - enabledGmemPathAlreadyChecked = true; - } -#endif - - if (gmemPathStateOut) - { - *gmemPathStateOut = gmemState; - } - - return enabledPath; -} - -CD3D9Renderer::EGmemDepthStencilMode CD3D9Renderer::FX_GmemGetDepthStencilMode() const -{ - if (m_gmemDepthStencilMode == eGDSM_Invalid) - { - switch (FX_GetEnabledGmemPath(nullptr)) - { - case eGT_256bpp_PATH: - m_gmemDepthStencilMode = eGDSM_RenderTarget; - break; - case eGT_128bpp_PATH: - { - bool hasEnoughRTs = true; -#if defined(OPENGL_ES) || defined(CRY_USE_METAL) - hasEnoughRTs &= RenderCapabilities::SupportsRenderTargets(s_gmemLargeRTCount); -#endif - if (IsVelocityPassEnabled() && !hasEnoughRTs) - { - m_gmemDepthStencilMode = RenderCapabilities::GetFrameBufferFetchCapabilities().test(RenderCapabilities::FBF_DEPTH) ? eGDSM_DepthStencilBuffer : eGDSM_Texture; - } - else - { - m_gmemDepthStencilMode = eGDSM_RenderTarget; - } - break; - } - default: - m_gmemDepthStencilMode = eGDSM_Texture; - break; - } - } - - return m_gmemDepthStencilMode; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::FX_RenderForwardOpaque(void(* RenderFunc)(), const bool bLighting, [[maybe_unused]] const bool bAllowDeferred) -{ - if (FX_GetEnabledGmemPath(nullptr)) - { -#ifdef SUPPORTS_MSAA - // Not supported in GMEM path - CRY_ASSERT(0); -#endif - } - - // Note: MSAA for deferred lighting requires extra pass using per-sample frequency for tagged undersampled regions - // for future: this could be avoided (while maintaining current architecture), by using MRT output then a composite step - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if (!FX_GetEnabledGmemPath(nullptr)) // Can't reclear buffers during GMEM path - { - if IsCVarConstAccess(constexpr) (CV_r_measureoverdraw == 4) - { - SetClearColor(Vec3_Zero); - EF_ClearTargetsLater(FRT_CLEAR_COLOR, Clr_Empty); - } - } - - PROFILE_LABEL_SCOPE("OPAQUE_PASSES"); - - m_RP.m_depthWriteStateUsed = false; - - const bool bShadowGenSpritePasses = (pShaderThreadInfo->m_PersFlags & (RBPF_SHADOWGEN)) != 0; - - if ((m_RP.m_PersFlags2 & RBPF2_ALLOW_DEFERREDSHADING) && !bShadowGenSpritePasses && recursiveLevel == 0 && !m_wireframe_mode) - { - m_RP.m_PersFlags2 |= RBPF2_FORWARD_SHADING_PASS; - } - - if (!FX_GetEnabledGmemPath(nullptr)) - { - // This unbinds/binds new RTs which isn't supported in GMEM path. - // TODO: rework FX_ProcessEyeOverlayRenderLists() for GMEM - if (!bShadowGenSpritePasses) - { - // Note: Eye overlay writes to diffuse color buffer for eye shader reading - PROFILE_PS_TIME_SCOPE(fTimeDIPs[EFSLIST_EYE_OVERLAY]); - FX_ProcessEyeOverlayRenderLists(EFSLIST_EYE_OVERLAY, RenderFunc, bLighting); - } - } - - { - PROFILE_LABEL_SCOPE("GENERAL"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_GENERAL], !bShadowGenSpritePasses); - - GetTiledShading().BindForwardShadingResources(NULL); - - FX_ProcessRenderList(EFSLIST_GENERAL, BEFORE_WATER, RenderFunc, bLighting); - FX_ProcessRenderList(EFSLIST_GENERAL, AFTER_WATER , RenderFunc, bLighting); - - GetTiledShading().UnbindForwardShadingResources(); - } - - { - PROFILE_LABEL_SCOPE("FORWARD_DECALS"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_DECAL], !bShadowGenSpritePasses); - - FX_ProcessRenderList(EFSLIST_DECAL, BEFORE_WATER, RenderFunc, bLighting); - FX_ProcessRenderList(EFSLIST_DECAL, AFTER_WATER , RenderFunc, bLighting); - } - - { - PROFILE_LABEL_SCOPE("DEFERRED_EMISSIVE_DECALS"); - FX_DeferredDecalsEmissive(); - } - - if (!FX_GetEnabledGmemPath(nullptr)) // not supported in GMEM path as it resolves buffers - { - if (!bShadowGenSpritePasses) - { - // Note: Do not swap render order with decals it breaks light acc buffer. - // - PC could actually work via accumulation into light acc target - { - PROFILE_PS_TIME_SCOPE(fTimeDIPs[EFSLIST_SKIN]); - FX_ProcessSkinRenderLists(EFSLIST_SKIN, RenderFunc, bLighting); - } - } - } - - if (CRenderer::CV_r_FurFinPass != 0) - { - FurPasses::GetInstance().ExecuteFinPass(); - } - - if (m_RP.m_depthWriteStateUsed && !FX_GetEnabledGmemPath(nullptr)) - { - // If any forward opaque passes wrote depth, recapture linear depth for upcoming passes such as fog - FX_LinearizeDepth(CTexture::s_ptexZTarget); - } - - m_RP.m_PersFlags2 &= ~RBPF2_FORWARD_SHADING_PASS; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_RenderFog() -{ - PROFILE_PS_TIME_SCOPE(fTimeDIPsDeferredLayers); - - FX_ResetPipe(); - FX_FogScene(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -inline static float expf_s(float arg) -{ - return expf(clamp_tpl(arg, -80.0f, 80.0f)); -} - -inline static float MaxChannel(const Vec4& col) -{ - return max(max(col.x, col.y), col.z); -} - -bool CD3D9Renderer::FX_FogScene() -{ - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Fog scene +++ \n"); - } - m_RP.m_PersFlags2 &= ~(RBPF2_NOSHADERFOG); - - FX_SetVStream(3, NULL, 0, 0); - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if (pShaderThreadInfo->m_FS.m_bEnable && CV_r_usezpass) - { - PROFILE_SHADER_SCOPE; - PROFILE_LABEL_SCOPE("FOG_GLOBAL"); - - int x = 0, y = 0, width = GetWidth(), height = GetHeight(); - - m_pNewTarget[0]->m_ClearFlags = 0; - RT_SetViewport(x, y, width, height); - - CShader* pSH = CShaderMan::s_shHDRPostProcess; - - float modelMatrix[16]; - float projMatrix[16]; - int viewport[4] = { x, y, width, height }; - GetModelViewMatrix(modelMatrix); - GetProjectionMatrix(projMatrix); - - Vec3 vFarPlaneVerts[4]; - const float fFar = (pShaderThreadInfo->m_PersFlags & RBPF_REVERSE_DEPTH) ? 0.0f : 1.0f; - UnProject(width, height, fFar, &vFarPlaneVerts[0].x, &vFarPlaneVerts[0].y, &vFarPlaneVerts[0].z, modelMatrix, projMatrix, viewport); - UnProject(0, height, fFar, &vFarPlaneVerts[1].x, &vFarPlaneVerts[1].y, &vFarPlaneVerts[1].z, modelMatrix, projMatrix, viewport); - UnProject(0, 0, fFar, &vFarPlaneVerts[2].x, &vFarPlaneVerts[2].y, &vFarPlaneVerts[2].z, modelMatrix, projMatrix, viewport); - UnProject(width, 0, fFar, &vFarPlaneVerts[3].x, &vFarPlaneVerts[3].y, &vFarPlaneVerts[3].z, modelMatrix, projMatrix, viewport); - - const float camZFar = GetCamera().GetFarPlane(); - const Vec3 camPos = GetCamera().GetPosition(); - const Vec3 camDir = GetCamera().GetViewdir(); - - const Vec3 vRT = vFarPlaneVerts[0] - camPos; - const Vec3 vLT = vFarPlaneVerts[1] - camPos; - const Vec3 vLB = vFarPlaneVerts[2] - camPos; - const Vec3 vRB = vFarPlaneVerts[3] - camPos; - - const uint64 nFlagsShaderRTSave = m_RP.m_FlagsShader_RT; - - ////////////////////////////////////////////////////////////////////////// - -#if defined(VOLUMETRIC_FOG_SHADOWS) - const bool renderFogShadow = m_bVolFogShadowsEnabled && (CV_r_VolumetricFog == 0); - - Vec4 volFogShadowRange; - { - Vec3 volFogShadowRangeP; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_RANGE, volFogShadowRangeP); - volFogShadowRangeP.x = clamp_tpl(volFogShadowRangeP.x, 0.01f, 1.0f); - volFogShadowRange = Vec4(volFogShadowRangeP.x, 1.0f / volFogShadowRangeP.x, 0, 0); - } - - if (renderFogShadow) - { - // Recreate render targets if quality was changed - bool halfRes = (CV_r_FogShadows == 1), quarterRes = (CV_r_FogShadows == 2); - if ((halfRes && CTexture::s_ptexVolFogShadowBuf[0]->GetWidth() != GetWidth() / 2) || - (quarterRes && CTexture::s_ptexVolFogShadowBuf[0]->GetWidth() != GetWidth() / 4)) - { - uint32 width2 = GetWidth() / (halfRes ? 2 : 4); - uint32 height2 = GetHeight() / (halfRes ? 2 : 4); - for (uint32 i = 0; i < 2; ++i) - { - ETEX_Format fmt = CTexture::s_ptexVolFogShadowBuf[i]->GetDstFormat(); - CTexture::s_ptexVolFogShadowBuf[i]->Invalidate(width2, height2, fmt); - CTexture::s_ptexVolFogShadowBuf[i]->CreateRenderTarget(fmt, Clr_Transparent); - } - } - - - int oldWidth, oldHeight; - { - int dummy0, dummy1; - GetViewport(&dummy0, &dummy1, &oldWidth, &oldHeight); - } - - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_T3F* pQuad = vb.Lock(); - - pQuad[0].p = Vec3(-1, -1, 0); - pQuad[0].st = vLB; - - pQuad[1].p = Vec3(1, -1, 0); - pQuad[1].st = vRB; - - pQuad[2].p = Vec3(-1, 1, 0); - pQuad[2].st = vLT; - - pQuad[3].p = Vec3(1, 1, 0); - pQuad[3].st = vRT; - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - ////////////////////////////////////////////////////////////////////////// - // interleave pass - { - FX_SetupShadowsForFog(); - - FX_PushRenderTarget(0, CTexture::s_ptexVolFogShadowBuf[0], 0); - RT_SetViewport(0, 0, CTexture::s_ptexVolFogShadowBuf[0]->GetWidth(), CTexture::s_ptexVolFogShadowBuf[0]->GetHeight()); - - const bool renderFogCloudShadow = m_bVolFogCloudShadowsEnabled; - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE5]; - if (renderFogCloudShadow) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - static CCryNameTSCRC TechName0("FogPassVolShadowsInterleavePass"); - static CCryNameTSCRC TechName1("MultiGSMShadowedFog"); - pSH->FXSetTechnique(CRenderer::CV_r_FogShadowsMode == 1 ? TechName1 : TechName0); - - uint32 nPasses; - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - static CCryNameR volFogShadowRangeN("volFogShadowRange"); - pSH->FXSetPSFloat(volFogShadowRangeN, &volFogShadowRange, 1); - - FX_Commit(); - - const uint32 nRS = GS_NODEPTHTEST; - FX_SetState(nRS); - D3DSetCull(eCULL_None); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - - FX_PopRenderTarget(0); - m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - } - - ////////////////////////////////////////////////////////////////////////// - // gather pass - { - static CCryNameTSCRC TechName("FogPassVolShadowsGatherPass"); - static CCryNameR volFogShadowBufSampleOffsetsN("volFogShadowBufSampleOffsets"); - static const int texStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - - Vec4 sampleOffsets[8]; - - // horizontal - { - FX_PushRenderTarget(0, CTexture::s_ptexVolFogShadowBuf[1], 0); - RT_SetViewport(0, 0, CTexture::s_ptexVolFogShadowBuf[1]->GetWidth(), CTexture::s_ptexVolFogShadowBuf[1]->GetHeight()); - - pSH->FXSetTechnique(TechName); - - uint32 nPasses; - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - CTexture::s_ptexVolFogShadowBuf[0]->Apply(0, texStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - - const float tU = 1.0f / (float)CTexture::s_ptexVolFogShadowBuf[0]->GetWidth(); - for (int x2 = -4, index = 0; x2 < 4; ++x2, ++index) - { - sampleOffsets[index] = Vec4(x2 * tU, 0, 0, 1); - } - - pSH->FXSetPSFloat(volFogShadowBufSampleOffsetsN, sampleOffsets, 8); - - FX_Commit(); - - const uint32 nRS = GS_NODEPTHTEST; - FX_SetState(nRS); - D3DSetCull(eCULL_None); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - - FX_PopRenderTarget(0); - } - - // vertical - { - FX_PushRenderTarget(0, CTexture::s_ptexVolFogShadowBuf[0], 0); - RT_SetViewport(0, 0, CTexture::s_ptexVolFogShadowBuf[0]->GetWidth(), CTexture::s_ptexVolFogShadowBuf[0]->GetHeight()); - - uint32 nPasses; - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - CTexture::s_ptexVolFogShadowBuf[1]->Apply(0, texStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - - const float tV = 1.0f / (float)CTexture::s_ptexVolFogShadowBuf[1]->GetHeight(); - for (int y2 = -4, index = 0; y2 < 4; ++y2, ++index) - { - sampleOffsets[index] = Vec4(0, y2 * tV, 0, 1); - } - - pSH->FXSetPSFloat(volFogShadowBufSampleOffsetsN, sampleOffsets, 8); - - FX_Commit(); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - - FX_PopRenderTarget(0); - } - } - - RT_SetViewport(0, 0, oldWidth, oldHeight); - } -#endif // #if defined(VOLUMETRIC_FOG_SHADOWS) - - ////////////////////////////////////////////////////////////////////////// - - if (m_RP.m_PersFlags2 & RBPF2_HDR_FP16) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_HDR_MODE]; - } - - float fogDepth = 0.0f; - if (CV_r_FogDepthTest != 0.0f && CV_r_VolumetricFog == 0) - { - if (CV_r_FogDepthTest < 0.0f) - { - Vec4 fogColGradColBase(0, 0, 0, 0), fogColGradColDelta(0, 0, 0, 0); - CHWShader_D3D::GetFogColorGradientConstants(fogColGradColBase, fogColGradColDelta); - - const Vec4 fogColGradRadial = CHWShader_D3D::GetFogColorGradientRadial(); - - const float fogColorIntensityBase = MaxChannel(fogColGradColBase); - const float fogColorIntensityTop = MaxChannel(fogColGradColBase + fogColGradColDelta); - const float fogColorIntensityRadial = MaxChannel(fogColGradRadial); - const float fogColorIntensity = max(fogColorIntensityBase, fogColorIntensityTop) + fogColorIntensityRadial; - - const float threshold = -CV_r_FogDepthTest; - - const Vec4 volFogParams = CHWShader_D3D::GetVolumetricFogParams(); - const Vec4 volFogRampParams = CHWShader_D3D::GetVolumetricFogRampParams(); - - const float atmosphereScale = volFogParams.x; - const float volFogHeightDensityAtViewer = volFogParams.y; - const float finalClamp = 1.0f - volFogParams.w; - - Vec3 lookDir = vRT; - if (lookDir.z * atmosphereScale < vLT.z * atmosphereScale) - { - lookDir = vLT; - } - if (lookDir.z * atmosphereScale < vLB.z * atmosphereScale) - { - lookDir = vLB; - } - if (lookDir.z * atmosphereScale < vRB.z * atmosphereScale) - { - lookDir = vRB; - } - - lookDir.Normalize(); - const float viewDirAdj = lookDir.Dot(camDir); - - float depth = camZFar * 0.5f; - float step = depth * 0.5f; - uint32 numSteps = 16; - - while (numSteps) - { - Vec3 cameraToWorldPos = lookDir * depth; - - float fogInt = 1.0f; - - const float t = atmosphereScale * cameraToWorldPos.z; - const float slopeThreshold = 0.01f; - if (fabsf(t) > slopeThreshold) - { - fogInt *= (expf_s(t) - 1.0f) / t; - } - - const float l = depth; // length(cameraToWorldPos); - const float u = l * volFogHeightDensityAtViewer; - fogInt = fogInt * u; - - float f = clamp_tpl(expf_s(0.69314719f * -fogInt), 0.0f, 1.0f); - - float r = clamp_tpl(l * volFogRampParams.x + volFogRampParams.y, 0.0f, 1.0f); - r = r * (2.0f - r); - r = r * volFogRampParams.z + volFogRampParams.w; - - f = (1.0f - f) * r; - assert(f >= 0.0f && f <= 1.0f); - - f = min(f, finalClamp); - f *= fogColorIntensity; - - if (f > threshold) - { - depth -= step; - } - else - { - fogDepth = depth * viewDirAdj; - depth += step; - } - step *= 0.5f; - - --numSteps; - } - } - else - { - fogDepth = CV_r_FogDepthTest; - } - } - - m_fogCullDistance = fogDepth; - - int nSUnitZTarget = -2; // FogPassPS doesn't need a sampler for ZTarget. - - const bool useFogDepthTest = fogDepth >= 0.01f; - uint32 nFlags = FEF_DONTSETTEXTURES | FEF_DONTSETSTATES; - -#if defined(VOLUMETRIC_FOG_SHADOWS) - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - if (renderFogShadow) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } -#endif - - if (CV_r_VolumetricFog != 0) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_VOLUMETRIC_FOG]; - nFlags &= ~FEF_DONTSETTEXTURES; - } - - static CCryNameTSCRC TechName("FogPass"); - pSH->FXSetTechnique(TechName); - - uint32 nPasses; - pSH->FXBegin(&nPasses, nFlags); - pSH->FXBeginPass(0); - - STexState TexStatePoint = STexState(FILTER_POINT, true); - - CTexture* depthRT = CTexture::s_ptexZTarget; - - if (FX_GetEnabledGmemPath(nullptr)) - { - depthRT = CTexture::s_ptexGmemStenLinDepth; - } - - depthRT->Apply(0, CTexture::GetTexState(TexStatePoint), EFTT_UNKNOWN, nSUnitZTarget, m_RP.m_MSAAData.Type ? SResourceView::DefaultViewMS : SResourceView::DefaultView); // bind as msaa target (if valid) - -#if defined(VOLUMETRIC_FOG_SHADOWS) - if (renderFogShadow) - { - static int texStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - CTexture::s_ptexVolFogShadowBuf[0]->Apply(2, texStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - } -#endif - -#if defined(FEATURE_SVO_GI) - // bind SVO atmosphere - { - static CCryNameR sSVO_AirTextureScale("SVO_AirTextureScale"); - Vec4 vSVO_AirTextureScale(0, 0, 0, 0); - pSH->FXSetPSFloat(sSVO_AirTextureScale, &vSVO_AirTextureScale, 1); - } -#endif - - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_T3F* Verts = vb.Lock(); - - const Matrix44A& projMat = pShaderThreadInfo->m_matProj; - float clipZ = 0; - if (useFogDepthTest) - { - // projMat.m23 is -1 or 1 depending on whether we use a RH or LH coord system - // done in favor of an if check to make homogeneous divide by fogDepth (which is always positive) work - clipZ = projMat.m23 * fogDepth * projMat.m22 + projMat.m32; - clipZ /= fogDepth; - clipZ = clamp_tpl(clipZ, 0.f, 1.f); - } - - Verts[0].p = Vec3(-1, -1, clipZ); - Verts[0].st = vLB; - - Verts[1].p = Vec3(1, -1, clipZ); - Verts[1].st = vRB; - - Verts[2].p = Vec3(-1, 1, clipZ); - Verts[2].st = vLT; - - Verts[3].p = Vec3(1, 1, clipZ); - Verts[3].st = vRT; - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - -#if defined(VOLUMETRIC_FOG_SHADOWS) - if (renderFogShadow) - { - Vec3 volFogShadowDarkeningP; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_DARKENING, volFogShadowDarkeningP); - - Vec4 volFogShadowDarkening(volFogShadowDarkeningP, 0); - static CCryNameR volFogShadowDarkeningN("volFogShadowDarkening"); - pSH->FXSetPSFloat(volFogShadowDarkeningN, &volFogShadowDarkening, 1); - - const float aSun = (1.0f - clamp_tpl(volFogShadowDarkeningP.y, 0.0f, 1.0f)) * 1.0f; - const float bSun = 1.0f - aSun; - const float aAmb = (1.0f - clamp_tpl(volFogShadowDarkeningP.z, 0.0f, 1.0f)) * 0.4f; - const float bAmb = 1.0f - aAmb; - - Vec4 volFogShadowDarkeningSunAmb(aSun, bSun, aAmb, bAmb); - static CCryNameR volFogShadowDarkeningSunAmbN("volFogShadowDarkeningSunAmb"); - pSH->FXSetPSFloat(volFogShadowDarkeningSunAmbN, &volFogShadowDarkeningSunAmb, 1); - - static CCryNameR volFogShadowRangeN("volFogShadowRange"); - pSH->FXSetPSFloat(volFogShadowRangeN, &volFogShadowRange, 1); - - Vec4 sampleOffsets[5]; - { - const float tU = 1.0f / (float)CTexture::s_ptexVolFogShadowBuf[0]->GetWidth(); - const float tV = 1.0f / (float)CTexture::s_ptexVolFogShadowBuf[0]->GetHeight(); - - sampleOffsets[0] = Vec4(0, 0, 0, 0); - sampleOffsets[1] = Vec4(0, -tV, 0, 0); - sampleOffsets[2] = Vec4(-tU, 0, 0, 0); - sampleOffsets[3] = Vec4(tU, 0, 0, 0); - sampleOffsets[4] = Vec4(0, tU, 0, 0); - } - static CCryNameR volFogShadowBufSampleOffsetsN("volFogShadowBufSampleOffsets"); - pSH->FXSetPSFloat(volFogShadowBufSampleOffsetsN, sampleOffsets, 5); - } -#endif - - FX_Commit(); - - // using GS_BLDST_SRCALPHA because GS_BLDST_ONEMINUSSRCALPHA causes banding artifact when alpha value is very low. - uint32 nRS = GS_BLSRC_ONE | GS_BLDST_SRCALPHA | (useFogDepthTest ? GS_DEPTHFUNC_LEQUAL : GS_NODEPTHTEST); - - // Draw a fullscreen quad to sample the RT - FX_SetState(nRS); - D3DSetCull(eCULL_None); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - - ////////////////////////////////////////////////////////////////////////// - - Vec3 lCol; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_COLOR, lCol); - - bool useFogPassWithLightning(lCol.x > 1e-4f || lCol.y > 1e-4f || lCol.z > 1e-4f); - if (useFogPassWithLightning) - { - static CCryNameTSCRC TechNameAlt("FogPassWithLightning"); - if (pSH->FXSetTechnique(TechNameAlt)) - { - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - Vec3 lPos; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_POS, lPos); - Vec4 lightningPosition(lPos.x, lPos.y, lPos.z, 0.0f); - static CCryNameR Param1Name("LightningPos"); - pSH->FXSetPSFloat(Param1Name, &lightningPosition, 1); - - Vec3 lSize; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKY_HIGHLIGHT_SIZE, lSize); - Vec4 lightningColorSize(lCol.x, lCol.y, lCol.z, lSize.x * 0.01f); - static CCryNameR Param2Name("LightningColSize"); - pSH->FXSetPSFloat(Param2Name, &lightningColorSize, 1); - - FX_Commit(); - - FX_SetState(GS_NODEPTHTEST | GS_BLSRC_ONE | GS_BLDST_ONE); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - } - } - - ////////////////////////////////////////////////////////////////////////// - - m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SnapVector(Vec3& vVector, const float fSnapRange) -{ - Vec3 vSnapped = vVector / fSnapRange; - vSnapped.Set(floor_tpl(vSnapped.x), floor_tpl(vSnapped.y), floor_tpl(vSnapped.z)); - vSnapped *= fSnapRange; - vVector = vSnapped; -} - -void CD3D9Renderer::FX_WaterVolumesCausticsPreprocess(N3DEngineCommon::SCausticInfo& causticInfo) -{ - PROFILE_LABEL_SCOPE("PREPROCESS"); - - AZ_Assert((SRendItem::BatchFlags(EFSLIST_WATER, m_RP.m_pRLD) & FB_WATER_CAUSTIC) == 0, "Water volume found in the wrong render list"); - - const uint32 waterRenderList = EFSLIST_REFRACTIVE_SURFACE; - const int32 waterSortGroup = 0; - - const int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - // Pre-process water ripples - if (!recursiveLevel && (m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS)) - { - FX_ResetPipe(); - CWaterRipples* pWaterRipples = (CWaterRipples*)PostEffectMgr()->GetEffect(ePFX_WaterRipples); - CEffectParam* pParam = PostEffectMgr()->GetByName("WaterRipples_Amount"); - pParam->SetParam(1.0f); - if (pWaterRipples->Preprocess()) // Preprocess here will clear the list and skip the one in FX_RenderWater. - { - m_RP.m_PersFlags2 |= RBPF2_WATERRIPPLES; - gcpRendD3D->FX_ResetPipe(); - - TransformationMatrices backupSceneMatrices; - gcpRendD3D->Set2DMode(1, 1, backupSceneMatrices); - - pWaterRipples->Render(); - - gcpRendD3D->Unset2DMode(backupSceneMatrices); - - gcpRendD3D->FX_ResetPipe(); - - FX_Commit(); - } - } - - PostProcessUtils().Log(" +++ Begin watervolume caustics preprocessing +++ \n"); - - const float fMaxDistance = CRenderer::CV_r_watervolumecausticsmaxdistance; - CCamera origCam = GetCamera(); - - float fWidth = CTexture::s_ptexWaterCaustics[0]->GetWidth(); - float fHeight = CTexture::s_ptexWaterCaustics[0]->GetHeight(); - - Vec3 vDir = gRenDev->GetViewParameters().ViewDir(); - Vec3 vPos = gRenDev->GetViewParameters().vOrigin; - - const float fOffsetDist = fMaxDistance * 0.25f; - vPos += Vec3(vDir.x * fOffsetDist, vDir.y * fOffsetDist, 0.0f); // Offset in viewing direction to maximimze view distance. - - // Snap to avoid some aliasing. - const float fSnapRange = CRenderer::CV_r_watervolumecausticssnapfactor; - if (fSnapRange > 0.05f) // don't bother snapping if the value is low. - { - SnapVector(vPos, fSnapRange); - } - - Vec3 vEye = vPos + Vec3(0.0f, 0.0f, 10.0f); - - // Create the matrices. - Matrix44A mOrthoMatr; - Matrix44A mViewMatr; - mOrthoMatr.SetIdentity(); - mViewMatr.SetIdentity(); - mathMatrixOrtho(&mOrthoMatr, fMaxDistance, fMaxDistance, 0.25f, 100.0f); - mathMatrixLookAt(&mViewMatr, vEye, vPos, Vec3(0, 1, 0)); - - // Push the matrices. - Matrix44A origMatView = pShaderThreadInfo->m_matView; - Matrix44A origMatProj = pShaderThreadInfo->m_matProj; - - Matrix44A* m = &pShaderThreadInfo->m_matProj; - m->SetIdentity(); - *m = mOrthoMatr; - - m = &pShaderThreadInfo->m_matView; - m->SetIdentity(); - *m = mViewMatr; - - // Store for projection onto the scene. - causticInfo.m_mCausticMatr = mViewMatr * mOrthoMatr; - causticInfo.m_mCausticMatr.Transpose(); - - pShaderThreadInfo->m_PersFlags |= RBPF_DRAWTOTEXTURE; - - FX_ClearTarget(CTexture::s_ptexWaterCaustics[0], Clr_Transparent); - FX_PushRenderTarget(0, CTexture::s_ptexWaterCaustics[0], 0); - RT_SetViewport(0, 0, (int)fWidth, (int)fHeight); - - FX_PreRender(3); - - m_RP.m_pRenderFunc = FX_FlushShader_General; - m_RP.m_nPassGroupID = waterRenderList; - m_RP.m_nPassGroupDIP = waterRenderList; - - PROFILE_DIPS_START; - - m_RP.m_nSortGroupID = waterSortGroup; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][waterRenderList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][waterRenderList], FB_WATER_CAUSTIC); - - PROFILE_DIPS_END(waterRenderList); - - FX_PopRenderTarget(0); - - FX_PostRender(); - - pShaderThreadInfo->m_matView = origMatView; - pShaderThreadInfo->m_matProj = origMatProj; - - FX_ResetPipe(); - RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight()); - - pShaderThreadInfo->m_PersFlags &= ~RBPF_DRAWTOTEXTURE; - - FX_Commit(); - - PostProcessUtils().Log(" +++ End watervolume caustics preprocessing +++ \n"); -} - -bool CD3D9Renderer::FX_WaterVolumesCausticsUpdateGrid(N3DEngineCommon::SCausticInfo& causticInfo) -{ - // 16 bit index limit, can only do max 256x256 grid. - // could use hardware tessellation to reduce memory and increase tessellation amount for higher precision. - const uint32 nCausticMeshWidth = clamp_tpl(CRenderer::CV_r_watervolumecausticsdensity, 16, 255); - const uint32 nCausticMeshHeight = clamp_tpl(CRenderer::CV_r_watervolumecausticsdensity, 16, 255); - - // Update the grid mesh if required. - if ((!causticInfo.m_pCausticQuadMesh || causticInfo.m_nCausticMeshWidth != nCausticMeshWidth || causticInfo.m_nCausticMeshHeight != nCausticMeshHeight)) - { - // Make sure we aren't recreating the mesh. - causticInfo.m_pCausticQuadMesh = NULL; - - const uint32 nCausticVertexCount = (nCausticMeshWidth + 1) * (nCausticMeshHeight + 1); - const uint32 nCausticIndexCount = (nCausticMeshWidth * nCausticMeshHeight) * 6; - - // Store the new resolution and vertex/index counts. - causticInfo.m_nCausticMeshWidth = nCausticMeshWidth; - causticInfo.m_nCausticMeshHeight = nCausticMeshHeight; - causticInfo.m_nVertexCount = nCausticVertexCount; - causticInfo.m_nIndexCount = nCausticIndexCount; - - // Reciprocal for scaling. - float fRecipW = 1.0f / (float)nCausticMeshWidth; - float fRecipH = 1.0f / (float)nCausticMeshHeight; - - // Buffers. - SVF_P3F_C4B_T2F* pCausticQuads = new SVF_P3F_C4B_T2F[nCausticVertexCount]; - vtx_idx* pCausticIndices = new vtx_idx[nCausticIndexCount]; - - // Fill vertex buffer. - for (uint32 y = 0; y <= nCausticMeshHeight; ++y) - { - for (uint32 x = 0; x <= nCausticMeshWidth; ++x) - { - pCausticQuads[y * (nCausticMeshWidth + 1) + x].xyz = Vec3(((float)x) * fRecipW, ((float)y) * fRecipH, 0.0f); - } - } - - // Fill index buffer. - for (uint32 y = 0; y < nCausticMeshHeight; ++y) - { - for (uint32 x = 0; x < nCausticMeshWidth; ++x) - { - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6] = y * (nCausticMeshWidth + 1) + x; - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6 + 1] = y * (nCausticMeshWidth + 1) + x + 1; - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6 + 2] = (y + 1) * (nCausticMeshWidth + 1) + x + 1; - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6 + 3] = (y + 1) * (nCausticMeshWidth + 1) + x + 1; - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6 + 4] = (y + 1) * (nCausticMeshWidth + 1) + x; - pCausticIndices[(y * (nCausticMeshWidth) + x) * 6 + 5] = y * (nCausticMeshWidth + 1) + x; - } - } - - // Create the mesh. - causticInfo.m_pCausticQuadMesh = gRenDev->CreateRenderMeshInitialized(pCausticQuads, nCausticVertexCount, eVF_P3F_C4B_T2F, pCausticIndices, nCausticIndexCount, prtTriangleList, "WaterCausticMesh", "WaterCausticMesh"); - - // Delete the temporary buffers. - delete[] pCausticQuads; - delete[] pCausticIndices; - } - - // If we created the mesh, return true. - if (causticInfo.m_pCausticQuadMesh) - { - return true; - } - - return false; -} - -void CD3D9Renderer::FX_WaterVolumesCaustics() -{ - uint64 nPrevFlagsShaderRT = gRenDev->m_RP.m_FlagsShader_RT; - - const uint32 waterRenderList = EFSLIST_REFRACTIVE_SURFACE; - const int32 waterSortGroup = 0; - - uint32 nBatchMask = SRendItem::BatchFlags(waterRenderList, m_RP.m_pRLD); - - bool isEmpty = SRendItem::IsListEmpty(waterRenderList, m_RP.m_nProcessThreadID, m_RP.m_pRLD) && SRendItem::IsListEmpty(EFSLIST_WATER_VOLUMES, m_RP.m_nProcessThreadID, m_RP.m_pRLD); - - // Check if there are any water volumes that have caustics enabled - if (!isEmpty) - { - auto& RESTRICT_REFERENCE RI = CRenderView::CurrentRenderView()->GetRenderItems(waterSortGroup, waterRenderList); - - int endRI = m_RP.m_pRLD->m_nEndRI[waterSortGroup][waterRenderList]; - int curRI = m_RP.m_pRLD->m_nStartRI[waterSortGroup][waterRenderList]; - - isEmpty = true; - - while (curRI < endRI) - { - IRenderElement* pRE = RI[curRI++].pElem; - if (pRE->mfGetType() == eDATA_WaterVolume && ((CREWaterVolume*)pRE)->m_pParams && ((CREWaterVolume*)pRE)->m_pParams->m_caustics == true) - { - isEmpty = false; - break; - } - } - } - - // Pre-process refraction - // @NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - if (!isEmpty && (nBatchMask & FB_WATER_CAUSTIC) && CTexture::IsTextureExist(CTexture::s_ptexWaterCaustics[0]) && CTexture::IsTextureExist(CTexture::s_ptexWaterCaustics[1]) - && CRenderer::CV_r_watercaustics && CRenderer::CV_r_watervolumecaustics) - { - PROFILE_LABEL_SCOPE("WATERVOLUME_CAUSTICS"); - - // Caustics info. - N3DEngineCommon::SCausticInfo& causticInfo = gcpRendD3D->m_p3DEngineCommon.m_CausticInfo; - - - // Preprocess (render all visible volumes to caustic gbuffer) - FX_WaterVolumesCausticsPreprocess(causticInfo); - - gRenDev->m_cEF.mfRefreshSystemShader("DeferredCaustics", CShaderMan::s_ShaderDeferredCaustics); - - // Dilate the gbuffer. - static CCryNameTSCRC pTechNameDilate("WaterCausticsInfoDilate"); - - { - PROFILE_LABEL_SCOPE("DILATION"); - - PostProcessUtils().Log(" +++ Begin watervolume caustics dilation +++ \n"); - } - - FX_Commit(); - gcpRendD3D->FX_SetActiveRenderTargets(false); - FX_PushRenderTarget(0, CTexture::s_ptexWaterCaustics[1], NULL); - RT_SetViewport(0, 0, CTexture::s_ptexWaterCaustics[1]->GetWidth(), CTexture::s_ptexWaterCaustics[1]->GetHeight()); - - TransformationMatrices backupSceneMatrices; - Set2DMode(1, 1, backupSceneMatrices); - - PostProcessUtils().ShBeginPass(CShaderMan::s_ShaderDeferredCaustics, pTechNameDilate, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - FX_SetState(GS_NODEPTHTEST); - - PostProcessUtils().SetTexture(CTexture::s_ptexWaterCaustics[0], 0); - PostProcessUtils().DrawFullScreenTri(CTexture::s_ptexWaterCaustics[1]->GetWidth(), CTexture::s_ptexWaterCaustics[1]->GetHeight()); - PostProcessUtils().ShEndPass(); - FX_PopRenderTarget(0); - - PostProcessUtils().Log(" +++ End watervolume caustics dilation +++ \n"); - - - // Super blur for alpha to mask edges of volumes. - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexWaterCaustics[1], 1, 1.0, 10.0, true, 0, false, CTexture::s_ptexWaterCaustics[0]); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - //////////////////////////////////////////////// - // Procedural caustic generation - - // Generate the caustics map using the grid mesh. - // for future: - // - merge this somehow with shadow gen for correct projection/intersection with geometry (and lighting) - can use shadow map for position reconstruction of world around volume and project caustic geometry to it. - // - try hardware tessellation to increase quality and reduce memory (perhaps do projection per volume instead of as a single pass, that way it's basically screen-space) - if (FX_WaterVolumesCausticsUpdateGrid(causticInfo)) // returns true if the mesh is valid - { - static CCryNameTSCRC pTechNameCaustics("WaterCausticsGen"); - PROFILE_LABEL_SCOPE("CAUSTICS_GEN"); - PostProcessUtils().Log(" +++ Begin watervolume caustics generation +++ \n"); - - FX_PushRenderTarget(0, CTexture::s_ptexWaterCaustics[0], NULL); - FX_SetActiveRenderTargets(false);// Avoiding invalid d3d error (due to deferred rt setup, when ping-pong'ing between RTs we can bump into RTs still bound when binding it as a SRV) - RT_SetViewport(0, 0, CTexture::s_ptexWaterCaustics[0]->GetWidth(), CTexture::s_ptexWaterCaustics[0]->GetHeight()); - - PostProcessUtils().ShBeginPass(CShaderMan::s_ShaderDeferredCaustics, pTechNameCaustics, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - FX_SetState(GS_NODEPTHTEST | GS_NOCOLMASK_R | GS_NOCOLMASK_G | GS_NOCOLMASK_A); - - // Set vertex textures. - CTexture::s_ptexWaterCaustics[1]->SetVertexTexture(true); - PostProcessUtils().SetTexture(CTexture::s_ptexWaterCaustics[1], 0, FILTER_TRILINEAR); - - FX_Commit(); - // Render the grid mesh. - if (!FAILED(gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - size_t voffset(0); - size_t ioffset(0); - CRenderMesh* pCausticQuadMesh = static_cast(causticInfo.m_pCausticQuadMesh.get()); - pCausticQuadMesh->CheckUpdate(0); - D3DBuffer* pVB = gcpRendD3D->m_DevBufMan.GetD3D(pCausticQuadMesh->GetVBStream(VSF_GENERAL), &voffset); - D3DBuffer* pIB = gcpRendD3D->m_DevBufMan.GetD3D(pCausticQuadMesh->GetIBStream(), &ioffset); - FX_SetVStream(0, pVB, voffset, pCausticQuadMesh->GetStreamStride(VSF_GENERAL)); - FX_SetIStream(pIB, ioffset, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, causticInfo.m_nVertexCount, 0, causticInfo.m_nIndexCount); - } - - PostProcessUtils().ShEndPass(); - - // Unset vertex textures. - CTexture::s_ptexWaterCaustics[1]->SetVertexTexture(false); - - - FX_PopRenderTarget(0); - RT_SetViewport(0, 0, iWidth, iHeight); - - RT_UnbindTMUs();// Avoid d3d error due to rtv (s_ptexWaterCaustics[0]) still bound as shader input. - - // Smooth out any inconsistencies in the caustic map (pixels, etc). - PostProcessUtils().TexBlurGaussian(CTexture::s_ptexWaterCaustics[0], 1, 1.0, 1.0, false, NULL, false, CTexture::s_ptexWaterCaustics[1]); - - PostProcessUtils().Log(" +++ End watervolume caustics generation +++ \n"); - - FX_DeferredWaterVolumeCaustics(causticInfo); - } - - Unset2DMode(backupSceneMatrices); - } - - gRenDev->m_RP.m_FlagsShader_RT = nPrevFlagsShaderRT; -} - -void CD3D9Renderer::FX_WaterVolumesPreprocess() -{ - AZ_Assert((SRendItem::BatchFlags(EFSLIST_WATER, m_RP.m_pRLD) & FB_WATER_REFL) == 0, "Water volume found in the wrong render list"); - - const uint32 waterRenderList = EFSLIST_REFRACTIVE_SURFACE; - const int32 waterSortGroup = 0; - - uint32 nBatchMask = SRendItem::BatchFlags(waterRenderList, m_RP.m_pRLD); - if ((nBatchMask & FB_WATER_REFL) && CTexture::IsTextureExist(CTexture::s_ptexWaterVolumeRefl[0])) - { - PROFILE_LABEL_SCOPE("WATER_PREPROCESS"); - const uint32 nCurrWaterVolID = gRenDev->GetFrameID(false) % 2; - - CTexture* pCurrWaterVolRefl = CTexture::s_ptexWaterVolumeRefl[nCurrWaterVolID]; - - PostProcessUtils().Log(" +++ Begin water volumes preprocessing +++ \n"); - - bool bRgbkSrc = false; - - int nWidth = int(pCurrWaterVolRefl->GetWidth() * m_RP.m_CurDownscaleFactor.x); - int nHeight = int(pCurrWaterVolRefl->GetHeight() * m_RP.m_CurDownscaleFactor.y); - - PostProcessUtils().StretchRect(CTexture::s_ptexCurrSceneTarget, CTexture::s_ptexHDRTargetPrev, false, bRgbkSrc, false, false, SPostEffectsUtils::eDepthDownsample_None, false, &gcpRendD3D->m_FullResRect); - - RECT rect = { 0, pCurrWaterVolRefl->GetHeight() - nHeight, nWidth, nHeight }; - FX_ClearTarget(pCurrWaterVolRefl, Clr_Transparent, 1, &rect, true); - FX_PushRenderTarget(0, pCurrWaterVolRefl, 0); - RT_SetViewport(0, pCurrWaterVolRefl->GetHeight() - nHeight, nWidth, nHeight); - - FX_PreRender(3); - - m_RP.m_pRenderFunc = FX_FlushShader_General; - m_RP.m_nPassGroupID = waterRenderList; - m_RP.m_nPassGroupDIP = waterRenderList; - - PROFILE_DIPS_START; - - m_RP.m_nSortGroupID = waterSortGroup; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][waterRenderList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][waterRenderList], FB_WATER_REFL); - - PROFILE_DIPS_END(waterRenderList); - - FX_PostRender(); - - FX_PopRenderTarget(0); - - pCurrWaterVolRefl->GenerateMipMaps(); - - FX_ResetPipe(); - - RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight()); - - PostProcessUtils().Log(" +++ End water volumes preprocessing +++ \n"); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_RenderWater(void(* RenderFunc)()) -{ - PROFILE_LABEL_SCOPE("WATER"); - -#if defined(ENABLE_FRAME_PROFILER) - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); -#endif - - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_WATER_VOLUMES], !(pShaderThreadInfo->m_PersFlags & (RBPF_SHADOWGEN))); - const int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - - if (!recursiveLevel) - { - // Pre-process refraction - const bool isEmpty = SRendItem::IsListEmpty(EFSLIST_REFRACTIVE_SURFACE, m_RP.m_nProcessThreadID, m_RP.m_pRLD) && SRendItem::IsListEmpty(EFSLIST_WATER, m_RP.m_nProcessThreadID, m_RP.m_pRLD) && SRendItem::IsListEmpty(EFSLIST_WATER_VOLUMES, m_RP.m_nProcessThreadID, m_RP.m_pRLD); - if (!isEmpty && CTexture::IsTextureExist(CTexture::s_ptexCurrSceneTarget)) - { - if IsCVarConstAccess(constexpr) (!CRenderer::CV_r_debugrefraction) - { - FX_ScreenStretchRect(CTexture::s_ptexCurrSceneTarget); - } - else - { -#if defined(CRY_USE_METAL) - // On metal we have to submit a draw call in order for a clear to take effect. - // Doing the commit/clear target region will produce the needed draw call for the clear. - FX_PushRenderTarget(0, CTexture::s_ptexCurrSceneTarget, nullptr); - FX_SetColorDontCareActions(0); - CTexture::s_ptexCurrSceneTarget->Clear(ColorF(1, 0, 0, 1)); - RT_SetViewport(0, 0, CTexture::s_ptexCurrSceneTarget->GetWidth(), CTexture::s_ptexCurrSceneTarget->GetHeight()); - FX_Commit(); - FX_ClearTargetRegion(); - FX_PopRenderTarget(0); -#else - CTexture::s_ptexCurrSceneTarget->Clear(ColorF(1, 0, 0, 1)); -#endif - } - } - - // Pre-process rain ripples - if (!isEmpty && (m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS)) - { - FX_ResetPipe(); - CWaterRipples* pWaterRipples = (CWaterRipples*)PostEffectMgr()->GetEffect(ePFX_WaterRipples); - CEffectParam* pParam = PostEffectMgr()->GetByName("WaterRipples_Amount"); - pParam->SetParam(1.0f); - if (pWaterRipples->Preprocess()) - { - m_RP.m_PersFlags2 |= RBPF2_WATERRIPPLES; - gcpRendD3D->FX_ResetPipe(); - - TransformationMatrices backupSceneMatrices; - - gcpRendD3D->Set2DMode(1, 1, backupSceneMatrices); - - pWaterRipples->Render(); - - gcpRendD3D->Unset2DMode(backupSceneMatrices); - - gcpRendD3D->FX_ResetPipe(); - - FX_Commit(); - } - } - } - - FX_WaterVolumesPreprocess(); - - FX_ProcessRenderList(EFSLIST_WATER, BEFORE_WATER, RenderFunc, false); - - // We render opaque refractive surface, before the after water objects. - // Because they are in EFSLIST_REFRACTIVE_SURFACE, they don't have sorting issues - // with EFSLIST_WATER objects. - { - PROFILE_LABEL_SCOPE("REFRACTIVE_SURFACE"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_REFRACTIVE_SURFACE], !(pShaderThreadInfo->m_PersFlags & (RBPF_SHADOWGEN))); - FX_ProcessRenderList(EFSLIST_REFRACTIVE_SURFACE, BEFORE_WATER, RenderFunc, false); - } - - FX_ProcessRenderList(EFSLIST_WATER, AFTER_WATER , RenderFunc, false); - - m_RP.m_PersFlags2 &= ~(RBPF2_WATERRIPPLES | RBPF2_RAINRIPPLES); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_LinearizeDepth(CTexture* ptexZ) -{ - { - PROFILE_LABEL_SCOPE("LINEARIZE_DEPTH"); - - -#ifdef SUPPORTS_MSAA - if (FX_GetMSAAMode()) - { - FX_MSAASampleFreqStencilSetup(MSAA_SAMPLEFREQ_PASS); - } -#endif - SDepthTexture* depthBuffer = nullptr; - if (FX_GetEnabledGmemPath(nullptr)) - { - switch (FX_GmemGetDepthStencilMode()) - { - case eGDSM_RenderTarget: - AZ_Assert(false, "Depth is already linearized in the render target"); - return; - case eGDSM_DepthStencilBuffer: - depthBuffer = &m_DepthBufferOrigMSAA; - break; - default: - break; - } - } - - FX_PushRenderTarget(0, ptexZ, depthBuffer); - - static const CCryNameTSCRC pTechName("LinearizeDepth"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - FX_SetState(GS_NODEPTHTEST); - - m_DevMan.BindSRV(eHWSC_Pixel, &m_pZBufferDepthReadOnlySRV, 15, 1); - - RECT rect; - rect.left = rect.top = 0; - rect.right = LONG(ptexZ->GetWidth() * m_RP.m_CurDownscaleFactor.x); - rect.bottom = LONG(ptexZ->GetHeight() * m_RP.m_CurDownscaleFactor.y); - - PostProcessUtils().DrawFullScreenTri(ptexZ->GetWidth(), ptexZ->GetHeight(), 0, &rect); - - D3DShaderResourceView* pNullSRV[1] = { NULL }; - m_DevMan.BindSRV(eHWSC_Pixel, pNullSRV, 15, 1); - - PostProcessUtils().ShEndPass(); - - FX_PopRenderTarget(0); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Depth Fixup is two-stage pass technique to fix the linear depth buffer to include -// additional depth that was not register in the opaque pass, i.e., transparency objects. -// This pass will initialize the buffer to default set value to be compared when finalizing. -void CD3D9Renderer::FX_DepthFixupPrepare() -{ - PROFILE_LABEL_SCOPE("PREPARE_DEPTH_FIXUP"); - - // Merge linear depth with depth values written for transparent objects - FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, NULL); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - FX_SetDepthDontCareActions(0, false, true); - FX_SetStencilDontCareActions(0, false, true); - // CONFETTI END - - RT_SetViewport(0, 0, CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight()); - static const CCryNameTSCRC pTechName("TranspDepthFixupPrepare"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - FX_SetState(GS_NODEPTHTEST | GS_BLSRC_ZERO | GS_BLDST_ONE | GS_BLALPHA_MAX); - PostProcessUtils().DrawFullScreenTri(CTexture::s_ptexHDRTarget->GetWidth(), CTexture::s_ptexHDRTarget->GetHeight()); - PostProcessUtils().ShEndPass(); - FX_PopRenderTarget(0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Depth Fixup is two-stage pass technique to fix the linear depth buffer to include -// additional depth that was not register in the opaque pass, i.e., transparency objects. -// This method will run the pass that will write the pixels with non default value. -void CD3D9Renderer::FX_DepthFixupMerge() -{ - PROFILE_LABEL_SCOPE("MERGE_DEPTH"); - - // Merge linear depth with depth values written for transparent objects - FX_PushRenderTarget(0, CTexture::s_ptexZTarget, NULL); - - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - FX_SetDepthDontCareActions(0, false, true); - FX_SetStencilDontCareActions(0, false, true); - // CONFETTI END - - RT_SetViewport(0, 0, CTexture::s_ptexZTarget->GetWidth(), CTexture::s_ptexZTarget->GetHeight()); - static const CCryNameTSCRC pTechName("TranspDepthFixupMerge"); - PostProcessUtils().ShBeginPass(CShaderMan::s_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - PostProcessUtils().SetTexture(CTexture::s_ptexHDRTarget, 0, FILTER_POINT); - FX_SetState(GS_NODEPTHTEST | GS_BLSRC_ONE | GS_BLDST_ONE | GS_BLOP_MIN); - PostProcessUtils().DrawFullScreenTri(CTexture::s_ptexZTarget->GetWidth(), CTexture::s_ptexZTarget->GetHeight()); - PostProcessUtils().ShEndPass(); - FX_PopRenderTarget(0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_SRGBConversion() -{ - PROFILE_LABEL_SCOPE("SRGB CONVERSION"); - CRY_ASSERT(gcpRendD3D->FX_GetCurrentRenderTarget(0) == CTexture::s_ptexHDRTarget); - gcpRendD3D->FX_PopRenderTarget(0); - CTexture* targetText = GetUtils().AcquireFinalCompositeTarget(false); - gcpRendD3D->RT_SetViewport(0, 0, targetText->GetWidth(), targetText->GetHeight()); - gcpRendD3D->FX_PushRenderTarget(0, targetText, NULL); - GetUtils().CopyTextureToScreen(CTexture::s_ptexHDRTarget, nullptr, -1, true); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CD3D9Renderer::FX_HDRScene(bool bEnableHDR, bool bClear) -{ - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if (bEnableHDR) - { - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ Start HDR scene +++ \n"); - } - - if (!CTexture::s_ptexHDRTarget || CTexture::s_ptexHDRTarget->IsMSAAChanged() || CTexture::s_ptexHDRTarget->GetWidth() != GetWidth() || CTexture::s_ptexHDRTarget->GetHeight() != GetHeight()) - { - CTexture::GenerateHDRMaps(); - } - - bool bEmpty = SRendItem::IsListEmpty(EFSLIST_HDRPOSTPROCESS, m_RP.m_nProcessThreadID, m_RP.m_pRLD); - if (bEmpty) - { - return false; - } - - if (!FX_GetEnabledGmemPath(nullptr)) // GMEM buffers are already bound - { - if (bClear || (pShaderThreadInfo->m_PersFlags & RBPF_MIRRORCULL) || (m_RP.m_nRendFlags & SHDF_CUBEMAPGEN)) - { - FX_ClearTarget(CTexture::s_ptexHDRTarget); - FX_ClearTarget(&m_DepthBufferOrigMSAA); - } - - FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, &m_DepthBufferOrigMSAA, -1, true); - } - pShaderThreadInfo->m_PersFlags |= RBPF_HDR; - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], " +++ End HDR scene +++ \n"); - } - } - return true; -} - -// Draw overlay geometry in wireframe mode -void CD3D9Renderer::FX_DrawWire() -{ - float fColor = 1.f; - int nState = GS_WIREFRAME; - - if IsCVarConstAccess(constexpr) (CV_r_showlines == 1) - { - nState |= GS_NODEPTHTEST; - } - - if IsCVarConstAccess(constexpr) (CV_r_showlines == 3) - { - if (!gcpRendD3D->m_RP.m_pRE || !gcpRendD3D->m_RP.m_pRE->GetCustomData()) - { - return; // draw only terrain - } - nState |= GS_BLSRC_DSTCOL | GS_BLDST_ONE; - fColor = .25f; - } - - gcpRendD3D->FX_SetState(nState); - gcpRendD3D->SetMaterialColor(fColor, fColor, fColor, 1.f); - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - gcpRendD3D->EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, (eCA_Texture | (eCA_Constant << 3)), (eCA_Texture | (eCA_Constant << 3))); - gcpRendD3D->EF_SetSrgbWrite(false); - CRenderObject* pObj = gcpRendD3D->m_RP.m_pCurObject; - gcpRendD3D->FX_SetFPMode(); - gcpRendD3D->m_RP.m_pCurObject = pObj; - - uint32 i; - if (gcpRendD3D->m_RP.m_pCurPass) - { - for (int nRE = 0; nRE <= gcpRendD3D->m_RP.m_nLastRE; nRE++) - { - gcpRendD3D->m_RP.m_pRE = gcpRendD3D->m_RP.m_RIs[nRE][0]->pElem; - if (gcpRendD3D->m_RP.m_pRE) - { - EDataType t = gcpRendD3D->m_RP.m_pRE->mfGetType(); - if (t != eDATA_Mesh && t != eDATA_Terrain && t != eDATA_ClientPoly) - { - continue; - } - gcpRendD3D->m_RP.m_pRE->mfPrepare(false); - gcpRendD3D->m_RP.m_pRE->mfCheckUpdate(0, gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - } - - CHWShader_D3D* curVS = (CHWShader_D3D*)gcpRendD3D->m_RP.m_pCurPass->m_VShader; - for (i = 0; i < gcpRendD3D->m_RP.m_RIs[nRE].Num(); i++) - { - SRendItem* pRI = gcpRendD3D->m_RP.m_RIs[nRE][i]; - gcpRendD3D->FX_SetObjectTransform(pRI->pObj, NULL, pRI->pObj->m_ObjFlags); - curVS->UpdatePerInstanceConstantBuffer(); - gcpRendD3D->FX_Commit(); - gcpRendD3D->FX_DrawRE(gcpRendD3D->m_RP.m_pShader, NULL); - } - } - } -} - -// Draw geometry normal vectors -void CD3D9Renderer::FX_DrawNormals() -{ - - float len = CRenderer::CV_r_normalslength; - int StrVrt, StrTan, StrNorm; - - for (int nRE = 0; nRE <= gcpRendD3D->m_RP.m_nLastRE; nRE++) - { - gcpRendD3D->m_RP.m_pRE = gcpRendD3D->m_RP.m_RIs[nRE][0]->pElem; - if (gcpRendD3D->m_RP.m_pRE) - { - if (nRE) - { - gcpRendD3D->m_RP.m_pRE->mfPrepare(false); - } - gcpRendD3D->m_RP.m_pRE->mfCheckUpdate(-1, gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - } - - const byte* verts = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Vert, &StrVrt, eType_FLOAT, eSrcPointer_Vert, FGP_SRC | FGP_REAL); - const byte* normals = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Normal, &StrNorm, eType_FLOAT, eSrcPointer_Normal, FGP_SRC | FGP_REAL); - const byte* tangents = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Tangent, &StrTan, eType_FLOAT, eSrcPointer_Tangent, FGP_SRC | FGP_REAL); - - verts = ((INT_PTR)verts > 256 && StrVrt >= sizeof(Vec3)) ? verts : 0; - normals = ((INT_PTR)normals > 256 && StrNorm >= sizeof(SPipNormal)) ? normals : 0; - tangents = ((INT_PTR)tangents > 256 && (StrTan == sizeof(SPipQTangents) || StrTan == sizeof(SPipTangents))) ? tangents : 0; - - if (verts && (normals || tangents)) - { - gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); - gcpRendD3D->EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - gcpRendD3D->EF_SetSrgbWrite(false); - gcpRendD3D->FX_SetFPMode(); - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - int nStateFlags = 0; - if (gcpRendD3D->m_wireframe_mode == R_SOLID_MODE) - { - nStateFlags = GS_DEPTHWRITE; - } - if IsCVarConstAccess(constexpr) (CV_r_shownormals == 2) - { - nStateFlags = GS_NODEPTHTEST; - } - gcpRendD3D->FX_SetState(nStateFlags); - gcpRendD3D->D3DSetCull(eCULL_None); - - //gcpRendD3D->GetDevice().SetVertexShader(NULL); - - // We must limit number of vertices, because TempDynVB (see code below) - // uses transient pool that has *limited* size. See DevBuffer.cpp for details. - // Note that one source vertex produces *two* buffer vertices (endpoints of - // a normal vector). - const size_t maxBufferSize = (size_t)NextPower2(gRenDev->CV_r_transient_pool_size) << 20; - const size_t maxVertexCount = maxBufferSize / (2 * sizeof(SVF_P3F_C4B_T2F)); - const int numVerts = (int)(AZStd::GetMin)((size_t)gcpRendD3D->m_RP.m_RendNumVerts, maxVertexCount); - - TempDynVB vb(gcpRendD3D); - vb.Allocate(numVerts * 2); - SVF_P3F_C4B_T2F* Verts = vb.Lock(); - - uint32 col0 = 0x000000ff; - uint32 col1 = 0x00ffffff; - - const bool bHasNormals = (normals != 0); - - for (int v = 0; v < numVerts; v++, verts += StrVrt, normals += StrNorm, tangents += StrTan) - { - const float* const fverts = (const float*)verts; - - Vec3 vNorm; - if (bHasNormals) - { - vNorm = ((const SPipNormal*)normals)->GetN(); - } - else if (StrTan == sizeof(SPipQTangents)) - { - vNorm = ((const SPipQTangents*)tangents)->GetN(); - } - else - { - vNorm = ((const SPipTangents*)tangents)->GetN(); - } - vNorm.Normalize(); - - Verts[v * 2].xyz = Vec3(fverts[0], fverts[1], fverts[2]); - Verts[v * 2].color.dcolor = col0; - - Verts[v * 2 + 1].xyz = Vec3(fverts[0] + vNorm[0] * len, fverts[1] + vNorm[1] * len, fverts[2] + vNorm[2] * len); - Verts[v * 2 + 1].color.dcolor = col1; - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (gcpRendD3D->m_RP.m_pCurPass) - { - CHWShader_D3D* curVS = (CHWShader_D3D*)gcpRendD3D->m_RP.m_pCurPass->m_VShader; - for (uint32 i = 0; i < gcpRendD3D->m_RP.m_RIs[nRE].Num(); i++) - { - SRendItem* pRI = gcpRendD3D->m_RP.m_RIs[nRE][i]; - gcpRendD3D->FX_SetObjectTransform(pRI->pObj, NULL, pRI->pObj->m_ObjFlags); - curVS->UpdatePerInstanceConstantBuffer(); - gcpRendD3D->FX_Commit(); - - gcpRendD3D->FX_DrawPrimitive(eptLineList, 0, numVerts * 2); - } - } - - gcpRendD3D->m_RP.m_VertexStreams[0].pStream = NULL; - } - } -} - -// Draw geometry tangent vectors -void CD3D9Renderer::FX_DrawTangents() -{ - - float len = CRenderer::CV_r_normalslength; - - for (int nRE = 0; nRE <= gcpRendD3D->m_RP.m_nLastRE; nRE++) - { - gcpRendD3D->m_RP.m_pRE = gcpRendD3D->m_RP.m_RIs[nRE][0]->pElem; - if (gcpRendD3D->m_RP.m_pRE) - { - if (nRE) - { - gcpRendD3D->m_RP.m_pRE->mfPrepare(false); - } - gcpRendD3D->m_RP.m_pRE->mfCheckUpdate(-1, gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - } - - int StrVrt, StrTan; - const int flags = (CRenderer::CV_r_showtangents == 1) - ? FGP_SRC | FGP_REAL - : FGP_REAL; - - const byte* verts = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Vert, &StrVrt, eType_FLOAT, eSrcPointer_Vert, flags); - const byte* tangents = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Tangent, &StrTan, eType_FLOAT, eSrcPointer_Tangent, FGP_SRC | FGP_REAL); - - verts = ((INT_PTR)verts > 256 && StrVrt >= sizeof(Vec3)) ? verts : 0; - tangents = ((INT_PTR)tangents > 256 && (StrTan == sizeof(SPipQTangents) || StrTan == sizeof(SPipTangents))) ? tangents : 0; - - if (verts && tangents) - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - gcpRendD3D->EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - gcpRendD3D->EF_SetSrgbWrite(false); - int nStateFlags = 0; - if (gcpRendD3D->m_wireframe_mode == R_SOLID_MODE) - { - nStateFlags = GS_DEPTHWRITE; - } - if IsCVarConstAccess(constexpr) (CV_r_shownormals == 2) - { - nStateFlags = GS_NODEPTHTEST; - } - gcpRendD3D->FX_SetState(nStateFlags); - gcpRendD3D->D3DSetCull(eCULL_None); - gcpRendD3D->FX_SetFPMode(); - gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); - - // We must limit number of vertices, because TempDynVB (see code below) - // uses transient pool that has *limited* size. See DevBuffer.cpp for details. - // Note that one source vertex produces *six* buffer vertices (three tangent space - // vectors, two vertices per vector). - const size_t maxBufferSize = (size_t)NextPower2(gRenDev->CV_r_transient_pool_size) << 20; - const size_t maxVertexCount = maxBufferSize / (6 * sizeof(SVF_P3F_C4B_T2F)); - const int numVerts = (int)(AZStd::GetMin)((size_t)gcpRendD3D->m_RP.m_RendNumVerts, maxVertexCount); - - TempDynVB vb(gcpRendD3D); - vb.Allocate(numVerts * 6); - SVF_P3F_C4B_T2F* Verts = vb.Lock(); - - for (int v = 0; v < numVerts; v++, verts += StrVrt, tangents += StrTan) - { - uint32 col0 = 0xffff0000; - uint32 col1 = 0xffffffff; - const Vec3& vPos = *(const Vec3*)verts; - Vec3 vTan, vBiTan, vNorm; - - if (StrTan == sizeof(SPipQTangents)) - { - const Quat q = ((const SPipQTangents*)tangents)->GetQ(); - vTan = q.GetColumn0(); - vBiTan = q.GetColumn1(); - vNorm = ((const SPipQTangents*)tangents)->GetN(); - } - else - { - ((const SPipTangents*)tangents)->GetTBN(vTan, vBiTan, vNorm); - } - - Verts[v * 6 + 0].xyz = vPos; - Verts[v * 6 + 0].color.dcolor = col0; - - Verts[v * 6 + 1].xyz = Vec3(vPos[0] + vTan[0] * len, vPos[1] + vTan[1] * len, vPos[2] + vTan[2] * len); - Verts[v * 6 + 1].color.dcolor = col1; - - col0 = 0x0000ff00; - col1 = 0x00ffffff; - - Verts[v * 6 + 2].xyz = vPos; - Verts[v * 6 + 2].color.dcolor = col0; - - Verts[v * 6 + 3].xyz = Vec3(vPos[0] + vBiTan[0] * len, vPos[1] + vBiTan[1] * len, vPos[2] + vBiTan[2] * len); - Verts[v * 6 + 3].color.dcolor = col1; - - col0 = 0x000000ff; - col1 = 0x00ffffff; - - Verts[v * 6 + 4].xyz = vPos; - Verts[v * 6 + 4].color.dcolor = col0; - - Verts[v * 6 + 5].xyz = Vec3(vPos[0] + vNorm[0] * len, vPos[1] + vNorm[1] * len, vPos[2] + vNorm[2] * len); - Verts[v * 6 + 5].color.dcolor = col1; - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (gcpRendD3D->m_RP.m_pCurPass) - { - CHWShader_D3D* curVS = (CHWShader_D3D*)gcpRendD3D->m_RP.m_pCurPass->m_VShader; - for (uint32 i = 0; i < gcpRendD3D->m_RP.m_RIs[nRE].Num(); i++) - { - SRendItem* pRI = gcpRendD3D->m_RP.m_RIs[nRE][i]; - gcpRendD3D->FX_SetObjectTransform(pRI->pObj, NULL, pRI->pObj->m_ObjFlags); - curVS->UpdatePerInstanceConstantBuffer(); - gcpRendD3D->FX_Commit(); - - gcpRendD3D->FX_DrawPrimitive(eptLineList, 0, numVerts * 6); - } - } - - gcpRendD3D->m_RP.m_VertexStreams[0].pStream = NULL; - } - } -} - -void CD3D9Renderer::FX_DrawFurBending() -{ - float len = CRenderer::CV_r_normalslength; - for (int nRE = 0; nRE <= gcpRendD3D->m_RP.m_nLastRE; nRE++) - { - gcpRendD3D->m_RP.m_pRE = gcpRendD3D->m_RP.m_RIs[nRE][0]->pElem; - if (gcpRendD3D->m_RP.m_pRE) - { - if (nRE) - { - gcpRendD3D->m_RP.m_pRE->mfPrepare(false); - } - gcpRendD3D->m_RP.m_pRE->mfCheckUpdate(-1, gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_nFrameUpdateID); - } - - int StrVrt, StrNorm, StrTan, StrCol; - - const byte* verts = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Vert, &StrVrt, eType_FLOAT, eSrcPointer_Vert, FGP_SRC | FGP_REAL); - const byte* normals = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Normal, &StrNorm, eType_FLOAT, eSrcPointer_Normal, FGP_SRC | FGP_REAL); - const byte* tangents = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Tangent, &StrTan, eType_FLOAT, eSrcPointer_Tangent, FGP_SRC | FGP_REAL); - const byte* colors = (const byte*)gcpRendD3D->EF_GetPointer(eSrcPointer_Color, &StrCol, eType_FLOAT, eSrcPointer_Color, FGP_SRC | FGP_REAL); - - verts = ((INT_PTR)verts > 256 && StrVrt >= sizeof(Vec3)) ? verts : 0; - normals = ((INT_PTR)normals > 256 && StrNorm >= sizeof(SPipNormal)) ? normals : 0; - tangents = ((INT_PTR)tangents > 256 && (StrTan == sizeof(SPipQTangents) || StrTan == sizeof(SPipTangents))) ? tangents : 0; - colors = ((INT_PTR)colors > 256 && StrCol >= sizeof(UCol)) ? colors : 0; - - if (verts && (normals || tangents) && colors) - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - gcpRendD3D->EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - gcpRendD3D->EF_SetSrgbWrite(false); - int nStateFlags = 0; - if (gcpRendD3D->m_wireframe_mode == R_SOLID_MODE) - { - nStateFlags = GS_DEPTHWRITE; - } - if (CV_r_FurShowBending == 2) - { - nStateFlags = GS_NODEPTHTEST; - } - gcpRendD3D->FX_SetState(nStateFlags); - gcpRendD3D->D3DSetCull(eCULL_None); - gcpRendD3D->FX_SetFPMode(); - gcpRendD3D->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); - - // We must limit number of vertices, because TempDynVB (see code below) - // uses transient pool that has *limited* size. See DevBuffer.cpp for details. - // Note that one source vertex produces *four* buffer vertices. - const uint32 c_vertsPerPrimitive = 4; - const size_t maxBufferSize = (size_t)NextPower2(gRenDev->CV_r_transient_pool_size) << 20; - const size_t maxVertexCount = maxBufferSize / (c_vertsPerPrimitive * sizeof(SVF_P3F_C4B_T2F)); - const int numVerts = (int)(std::min)((size_t)gcpRendD3D->m_RP.m_RendNumVerts, maxVertexCount); - - TempDynVB vb(gcpRendD3D); - vb.Allocate(numVerts * c_vertsPerPrimitive); - SVF_P3F_C4B_T2F* Verts = vb.Lock(); - - uint32 col0 = 0xffff0000; - uint32 col1 = 0xff00ff00; - uint32 col2 = 0xff0000ff; - - const bool bHasNormals = (normals != 0); - - for (int v = 0; v < numVerts; v++, verts += StrVrt, normals += StrNorm, colors += StrCol) - { - Vec3 vPos = *(const Vec3*)verts; - Vec3 vNorm; - if (bHasNormals) - { - vNorm = ((const SPipNormal*)normals)->GetN(); - } - else if (StrTan == sizeof(SPipQTangents)) - { - vNorm = ((const SPipQTangents*)tangents)->GetN(); - } - else - { - vNorm = ((const SPipTangents*)tangents)->GetN(); - } - vNorm.Normalize(); - - UCol color = *(const UCol*)colors; - Vec3 vColor(color.r / 255.0f * 2 - 1, color.b / 255.0f * 2 - 1, color.g / 255.0f * 2 - 1); - vColor.Normalize(); - - float furLength = len * color.a / 255.0f; - - Verts[v * c_vertsPerPrimitive + 0].xyz = vPos; - Verts[v * c_vertsPerPrimitive + 0].color.dcolor = col0; - - Verts[v * c_vertsPerPrimitive + 1].xyz = vPos + vNorm * furLength; - Verts[v * c_vertsPerPrimitive + 1].color.dcolor = col1; - - Verts[v * c_vertsPerPrimitive + 2].xyz = vPos + vNorm * furLength; - Verts[v * c_vertsPerPrimitive + 2].color.dcolor = col1; - - Verts[v * c_vertsPerPrimitive + 3].xyz = vPos + vColor * furLength; - Verts[v * c_vertsPerPrimitive + 3].color.dcolor = col2; - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (gcpRendD3D->m_RP.m_pCurPass) - { - CHWShader_D3D* curVS = (CHWShader_D3D*)gcpRendD3D->m_RP.m_pCurPass->m_VShader; - for (uint32 i = 0; i < gcpRendD3D->m_RP.m_RIs[nRE].Num(); i++) - { - SRendItem* pRI = gcpRendD3D->m_RP.m_RIs[nRE][i]; - gcpRendD3D->FX_SetObjectTransform(pRI->pObj, NULL, pRI->pObj->m_ObjFlags); - curVS->UpdatePerInstanceConstantBuffer(); - gcpRendD3D->FX_Commit(); - - gcpRendD3D->FX_DrawPrimitive(eptLineList, 0, numVerts * c_vertsPerPrimitive); - } - } - - gcpRendD3D->m_RP.m_VertexStreams[0].pStream = NULL; - } - } -} - -// Draw light sources in debug mode -// Draw debug geometry/info -void CD3D9Renderer::EF_DrawDebugTools(SViewport& VP, const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - if IsCVarConstAccess(constexpr) (CV_r_showlines) - { - EF_ProcessRenderLists(FX_DrawWire, 0, VP, passInfo, false); - } - - if IsCVarConstAccess(constexpr) (CV_r_shownormals) - { - EF_ProcessRenderLists(FX_DrawNormals, 0, VP, passInfo, false); - } - - if IsCVarConstAccess(constexpr) (CV_r_showtangents) - { - EF_ProcessRenderLists(FX_DrawTangents, 0, VP, passInfo, false); - } - - if (CV_r_FurShowBending) - { - m_RP.m_pRenderFunc = FX_DrawFurBending; - FX_ProcessRenderList(FurPasses::GetInstance().GetFurRenderList(), FB_FUR, false /*bSetRenderFunc*/); - } -} - -#if !defined(_RELEASE) -static int __cdecl TimeProfCallback(const VOID * arg1, const VOID * arg2) -{ - SProfInfo* pi1 = (SProfInfo*)arg1; - SProfInfo* pi2 = (SProfInfo*)arg2; - if (pi1->pTechnique->m_fProfileTime > pi2->pTechnique->m_fProfileTime) - { - return -1; - } - if (pi1->pTechnique->m_fProfileTime < pi2->pTechnique->m_fProfileTime) - { - return 1; - } - return 0; -} - -static int __cdecl Compare_SProfInfo(const VOID * arg1, const VOID * arg2) -{ - SProfInfo* pi1 = (SProfInfo*)arg1; - SProfInfo* pi2 = (SProfInfo*)arg2; - -#if defined(CONSOLE_CONST_CVAR_MODE) - if constexpr (CRenderer::CV_r_ProfileShadersGroupByName == 1) -#else - if (gRenDev->CV_r_ProfileShadersGroupByName == 1) -#endif - { - char str1[128]; - char str2[128]; - - sprintf_s(str1, sizeof(str1), "%s.%s", pi1->pShader->GetName(), pi1->pTechnique->m_NameStr.c_str()); - sprintf_s(str2, sizeof(str2), "%s.%s", pi2->pShader->GetName(), pi2->pTechnique->m_NameStr.c_str()); - - return azstricmp(str1, str2); - } -#if defined(CONSOLE_CONST_CVAR_MODE) - else if constexpr (CRenderer::CV_r_ProfileShadersGroupByName == 2) -#else - else if (gRenDev->CV_r_ProfileShadersGroupByName == 2) -#endif - { - return azstricmp(pi1->pTechnique->m_NameStr.c_str(), pi2->pTechnique->m_NameStr.c_str()); - } - - if (pi1->pTechnique > pi2->pTechnique) - { - return -1; - } - if (pi1->pTechnique < pi2->pTechnique) - { - return 1; - } - - return 0; -} -#endif - -struct STimeStorage -{ - float fNumPolys; - float fNumDips; - double fTime; - float fItems; - uint32 nUsedFrameId; - STimeStorage() - { - fNumPolys = 0; - fNumDips = 0; - fTime = 0; - fItems = 0; - nUsedFrameId = 0; - } -}; - - -// Print shaders profile info on the screen -void CD3D9Renderer::EF_PrintProfileInfo() -{ -#ifndef _RELEASE -#if defined(ENABLE_PROFILING_CODE) - TextToScreenColor(1, 14, 0, 2, 0, 1, "Instances: %d, MatBatches: %d, GeomBatches: %d, DrawCalls: %d, Text: %d, Stat: %d, PShad: %d, VShad: %d", m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumRendInstances, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumRendMaterialBatches, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumRendGeomBatches, GetCurrentNumberOfDrawCalls(), m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumTextChanges, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumStateChanges, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumPShadChanges, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumVShadChanges); -#endif - TextToScreenColor(1, 17, 0, 2, 0, 1, "VShad: %d, PShad: %d, Text: %d", m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumVShaders, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumPShaders, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumTextures); - TextToScreenColor(1, 20, 0, 2, 0, 1, "Preprocess: %8.02f ms, OccmOut. queries: %8.02f ms", m_RP.m_PS[m_RP.m_nProcessThreadID].m_fPreprocessTime * 1000.f, m_RP.m_PS[m_RP.m_nProcessThreadID].m_fOcclusionTime * 1000.f); - TextToScreenColor(1, 23, 0, 2, 0, 1, "Skinning: %8.02f ms (Skinned Objects: %d)", m_RP.m_PS[m_RP.m_nProcessThreadID].m_fSkinningTime * 1000.f, m_RP.m_PS[m_RP.m_nProcessThreadID].m_NumRendSkinnedObjects); - - // TODO: implement CV_r_profileDIPs=2 mode - draw only one triangle per draw call - // merge items with same grouping factor into single item - if (m_RP.m_Profile.Num()) - { - qsort(&m_RP.m_Profile[0], m_RP.m_Profile.Num(), sizeof(SProfInfo), Compare_SProfInfo); - - for (uint32 i = 0; (i + 1) < m_RP.m_Profile.Num(); i++) - { - if (!Compare_SProfInfo(&m_RP.m_Profile[i], &m_RP.m_Profile[i + 1])) - { - m_RP.m_Profile[i].Time += m_RP.m_Profile[i + 1].Time; - m_RP.m_Profile[i].m_nItems++; - m_RP.m_Profile[i].NumPolys += m_RP.m_Profile[i + 1].NumPolys; - m_RP.m_Profile[i].NumDips += m_RP.m_Profile[i + 1].NumDips; - m_RP.m_Profile.DelElem(i + 1); - i--; - } - } - } - - // smooth values over time - if (CV_r_ProfileShadersSmooth && (CV_r_ProfileShadersGroupByName == 1 || CV_r_ProfileShadersGroupByName == 2)) - { - typedef std::map > TimeStorageMap; - static TimeStorageMap timeStorageMap; - - char strName[128] = ""; - - for (uint32 i = 0; i < m_RP.m_Profile.Num(); i++) - { - SProfInfo* pi1 = &m_RP.m_Profile[i]; - - if (CV_r_ProfileShadersGroupByName == 1) - { - azsnprintf(strName, sizeof(strName), "%s.%s", pi1->pShader->GetName(), pi1->pTechnique->m_NameStr.c_str()); - } - else - { - cry_strcpy(strName, pi1->pTechnique->m_NameStr.c_str()); - } - - STimeStorage* pTimeStorage = stl::find_in_map(timeStorageMap, CONST_TEMP_STRING(strName), NULL); - if (!pTimeStorage) - { - pTimeStorage = timeStorageMap[strName] = new STimeStorage(); - } - - float fSmooth = CV_r_ProfileShadersSmooth; - m_RP.m_Profile[i].pTechnique->m_fProfileTime = pTimeStorage->fTime = (m_RP.m_Profile[i].Time + pTimeStorage->fTime * fSmooth) / (fSmooth + 1.f); - m_RP.m_Profile[i].m_nItems = (int)(pTimeStorage->fItems = ((float)m_RP.m_Profile[i].m_nItems + pTimeStorage->fItems * fSmooth) / (fSmooth + 1.f)); - m_RP.m_Profile[i].NumDips = (int)(pTimeStorage->fNumDips = ((float)m_RP.m_Profile[i].NumDips + pTimeStorage->fNumDips * fSmooth) / (fSmooth + 1.f)); - m_RP.m_Profile[i].NumPolys = (int)(pTimeStorage->fNumPolys = ((float)m_RP.m_Profile[i].NumPolys + pTimeStorage->fNumPolys * fSmooth) / (fSmooth + 1.f)); - pTimeStorage->nUsedFrameId = GetFrameID(false); - } - - // fade items not used in this frame, delete not important items - TimeStorageMap::iterator next; - for (TimeStorageMap::iterator it = timeStorageMap.begin(); it != timeStorageMap.end(); it = next) - { - next = it; - next++; - STimeStorage* pTimeStorage = (STimeStorage*)(it->second); - if (pTimeStorage->nUsedFrameId != GetFrameID(false)) - { - float fSmooth = CV_r_ProfileShadersSmooth; - pTimeStorage->fTime = (0 + pTimeStorage->fTime * fSmooth) / (fSmooth + 1.f); - pTimeStorage->fItems = (0 + pTimeStorage->fItems * fSmooth) / (fSmooth + 1.f); - pTimeStorage->fNumDips = (0 + pTimeStorage->fNumDips * fSmooth) / (fSmooth + 1.f); - pTimeStorage->fNumPolys = (0 + pTimeStorage->fNumPolys * fSmooth) / (fSmooth + 1.f); - - if (pTimeStorage->fTime < 0.0001f) - { - timeStorageMap.erase(it); - delete pTimeStorage; - } - } - } - } - else - { - for (uint32 i = 0; i < m_RP.m_Profile.Num(); i++) - { - m_RP.m_Profile[i].pTechnique->m_fProfileTime = - (float)(m_RP.m_Profile[i].Time + m_RP.m_Profile[i].pTechnique->m_fProfileTime * (float)CV_r_ProfileShadersSmooth) / ((float)CV_r_ProfileShadersSmooth + 1); - } - } - - const uint32 nMaxLines = 18; - - // sort by final smoothed time - if (m_RP.m_Profile.Num()) - { - qsort(&m_RP.m_Profile[0], m_RP.m_Profile.Num(), sizeof(SProfInfo), TimeProfCallback); - } - - float fTimeAll = 0; - - // print - for (uint32 nLine = 0; nLine < m_RP.m_Profile.Num(); nLine++) - { - float fProfTime = m_RP.m_Profile[nLine].pTechnique->m_fProfileTime * 1000.f; - - fTimeAll += fProfTime; - - if (nLine >= nMaxLines) - { - continue; - } - - if (CV_r_ProfileShadersGroupByName == 1) - { // no RT flags - TextToScreenColor(4, (27 + (nLine * 3)), 1, 0, 0, 1, "%8.2f ms, %6d tris, %4d DIPs, '%s.%s', %d item(s)", - fProfTime, - m_RP.m_Profile[nLine].NumPolys, - m_RP.m_Profile[nLine].NumDips, - m_RP.m_Profile[nLine].pShader->GetName(), - m_RP.m_Profile[nLine].pTechnique->m_NameStr.c_str(), - m_RP.m_Profile[nLine].m_nItems + 1); - } - else if (CV_r_ProfileShadersGroupByName == 2) - { // only Technique name - no RT flag, no shader name - TextToScreenColor(4, (27 + (nLine * 3)), 1, 0, 0, 1, "%8.2f ms, %6d tris, %4d DIPs, '%s', %d item(s)", - fProfTime, - m_RP.m_Profile[nLine].NumPolys, - m_RP.m_Profile[nLine].NumDips, - m_RP.m_Profile[nLine].pTechnique->m_NameStr.c_str(), - m_RP.m_Profile[nLine].m_nItems + 1); - } - else - { // with RT flags and all names - TextToScreenColor(4, (27 + (nLine * 3)), 1, 0, 0, 1, "%8.2f ms, %6d tris, %4d DIPs, '%s.%s(0x%x)', %d item(s)", - fProfTime, - m_RP.m_Profile[nLine].NumPolys, - m_RP.m_Profile[nLine].NumDips, - m_RP.m_Profile[nLine].pShader->GetName(), - m_RP.m_Profile[nLine].pTechnique->m_NameStr.c_str(), - m_RP.m_Profile[nLine].pShader->m_nMaskGenFX, - m_RP.m_Profile[nLine].m_nItems + 1); - } - } - - TextToScreenColor(1, (28 + (nMaxLines * 3)), 0, 2, 0, 1, "Total unique items: %8d", m_RP.m_Profile.Num()); - TextToScreenColor(1, (31 + (nMaxLines * 3)), 0, 2, 0, 1, "Total flush time: %8.2f ms", fTimeAll); - TextToScreenColor(1, (34 + (nMaxLines * 3)), 0, 2, 0, 1, "Total scene rendering time (MT): %8.2f ms", m_RP.m_PS[m_RP.m_nProcessThreadID].m_fSceneTimeMT); - TextToScreenColor(1, (34 + (nMaxLines * 3)), 0, 2, 0, 1, "Total scene rendering time (RT): %8.2f ms", m_RP.m_PS[m_RP.m_nProcessThreadID].m_fRenderTime); -#endif -} - - -struct SPreprocess -{ - int m_nPreprocess; - int m_Num; - CRenderObject* m_pObject; - int m_nTech; - CShader* m_Shader; - CShaderResources* m_pRes; - IRenderElement* m_RE; -}; - -struct Compare2 -{ - bool operator()(const SPreprocess& a, const SPreprocess& b) const - { - return a.m_nPreprocess < b.m_nPreprocess; - } -}; - -// Current scene preprocess operations (Rendering to RT, screen effects initializing, ...) -int CD3D9Renderer::EF_Preprocess(SRendItem* ri, uint32 nums, uint32 nume, RenderFunc pRenderFunc, [[maybe_unused]] const SRenderingPassInfo& passInfo) PREFAST_SUPPRESS_WARNING(6262) -{ - AZ_TRACE_METHOD(); - - uint32 i, j; - CShader* Shader; - CShaderResources* Res; - CRenderObject* pObject; - int nTech; - - SPreprocess Procs[512]; - uint32 nProcs = 0; - - CTimeValue time0 = iTimer->GetAsyncTime(); - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID], "*** Start preprocess frame ***\n"); - } - - int nReturn = 0; - - for (i = nums; i < nume; i++) - { - if (nProcs >= 512) - { - break; - } - SRendItem::mfGet(ri[i].SortVal, nTech, Shader, Res); - pObject = ri[i].pObj; - if (!(ri[i].nBatchFlags & FSPR_MASK)) - { - break; - } - nReturn++; - if (nTech < 0) - { - nTech = 0; - } - if (nTech < (int)Shader->m_HWTechniques.Num()) - { - for (j = SPRID_FIRST; j < 32; j++) - { - uint32 nMask = 1 << j; - if (nMask >= FSPR_MAX || nMask > (ri[i].nBatchFlags & FSPR_MASK)) - { - break; - } - if (nMask & ri[i].nBatchFlags) - { - Procs[nProcs].m_nPreprocess = j; - Procs[nProcs].m_Num = i; - Procs[nProcs].m_Shader = Shader; - Procs[nProcs].m_pRes = Res; - Procs[nProcs].m_RE = ri[i].pElem; - Procs[nProcs].m_pObject = pObject; - Procs[nProcs].m_nTech = nTech; - nProcs++; - } - } - } - } - if (!nProcs) - { - return 0; - } - std::sort(&Procs[0], &Procs[nProcs], Compare2()); - - if (pRenderFunc != FX_FlushShader_General) - { - return nReturn; - } - - bool bRes = true; - for (i = 0; i < nProcs; i++) - { - SPreprocess* pr = &Procs[i]; - if (!pr->m_Shader) - { - continue; - } - switch (pr->m_nPreprocess) - { - case SPRID_SCANTEX: - case SPRID_SCANTEXWATER: - if (!(m_RP.m_TI[m_RP.m_nFillThreadID].m_PersFlags & RBPF_DRAWTOTEXTURE)) - { - CRenderObject* pObj = pr->m_pObject; - int nT = pr->m_nTech; - if (nT < 0) - { - nT = 0; - } - SShaderTechnique* pTech = pr->m_Shader->m_HWTechniques[nT]; - CShaderResources* pRes = pr->m_pRes; - for (j = 0; j < pTech->m_RTargets.Num(); j++) - { - SHRenderTarget* pTarg = pTech->m_RTargets[j]; - if (pTarg->m_eOrder == eRO_PreProcess) - { - bRes &= FX_DrawToRenderTarget(pr->m_Shader, pRes, pObj, pTech, pTarg, pr->m_nPreprocess, pr->m_RE); - } - } - if (pRes) - { - for (j = 0; j < pRes->m_RTargets.Num(); j++) - { - SHRenderTarget* pTarg = pRes->m_RTargets[j]; - if (pTarg->m_eOrder == eRO_PreProcess) - { - bRes &= FX_DrawToRenderTarget(pr->m_Shader, pRes, pObj, pTech, pTarg, pr->m_nPreprocess, pr->m_RE); - } - } - } - } - break; - - case SPRID_CUSTOMTEXTURE: - if (!(m_RP.m_TI[m_RP.m_nFillThreadID].m_PersFlags & RBPF_DRAWTOTEXTURE)) - { - CRenderObject* pObj = pr->m_pObject; - int nT = pr->m_nTech; - if (nT < 0) - { - nT = 0; - } - SShaderTechnique* pTech = pr->m_Shader->m_HWTechniques[nT]; - CShaderResources* pRes = pr->m_pRes; - for (j = 0; j < pRes->m_RTargets.Num(); j++) - { - SHRenderTarget* pTarg = pRes->m_RTargets[j]; - if (pTarg->m_eOrder == eRO_PreProcess) - { - bRes &= FX_DrawToRenderTarget(pr->m_Shader, pRes, pObj, pTech, pTarg, pr->m_nPreprocess, pr->m_RE); - } - } - } - break; - case SPRID_GENCLOUDS: - break; - - default: - assert(0); - } - } - - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nFillThreadID], "*** End preprocess frame ***\n"); - } - - m_RP.m_PS[m_RP.m_nFillThreadID].m_fPreprocessTime += iTimer->GetAsyncTime().GetDifferenceInSeconds(time0); - - return nReturn; -} - - -void CD3D9Renderer::EF_EndEf2D([[maybe_unused]] const bool bSort) -{ -} - -//======================================================================================================== - -bool CRenderer::FX_TryToMerge(CRenderObject* pObjN, CRenderObject* pObjO, IRenderElement* pRE, bool bResIdentical) -{ -#if !defined(_RELEASE) - if (!CV_r_Batching) - { - return false; - } -#endif - - if ((pRE == nullptr) || pRE->mfGetType() != eDATA_Mesh) - { - return false; - } - -#if defined(FEATURE_SVO_GI) - if (m_RP.m_nPassGroupID == EFSLIST_VOXELIZE) - { - return false; - } -#endif - if (!bResIdentical || pRE != m_RP.m_pRE) - { - if (m_RP.m_nLastRE + 1 >= MAX_REND_GEOMS_IN_BATCH) - { - return false; - } - if ((pObjN->m_ObjFlags ^ pObjO->m_ObjFlags) & FOB_MASK_AFFECTS_MERGING_GEOM) - { - return false; - } - if ((pObjN->m_ObjFlags | pObjO->m_ObjFlags) & (FOB_SKINNED | FOB_DECAL_TEXGEN_2D | FOB_REQUIRES_RESOLVE | FOB_DISSOLVE | FOB_LIGHTVOLUME)) - { - return false; - } - - if (pObjN->m_nClipVolumeStencilRef != pObjO->m_nClipVolumeStencilRef) - { - return false; - } - - /* Confetti: David Srour - * Following is important as well. - * As an example... if 2 glass material objects use "nearest_cubemap" - * textures, the chosen texture might be picked differently depending on the - * camera position within the scene -- this'll cause jarring popping as the - * camera moves. This issue was observed on iOS. - */ - if (pObjN->m_nTextureID != pObjO->m_nTextureID) - { - return false; - } - - m_RP.m_RIs[++m_RP.m_nLastRE].SetUse(0); - m_RP.m_pRE = pRE; - return true; - } - - // Batching/Instancing case - if ((pObjN->m_ObjFlags ^ pObjO->m_ObjFlags) & FOB_MASK_AFFECTS_MERGING) - { - return false; - } - - if ((pObjN->m_ObjFlags | pObjO->m_ObjFlags) & (FOB_REQUIRES_RESOLVE | FOB_LIGHTVOLUME)) - { - return false; - } - - if (pObjN->m_nMaterialLayers != pObjO->m_nMaterialLayers) - { - return false; - } - - if (pObjN->m_nTextureID != pObjO->m_nTextureID) - { - return false; - } - - if (pObjN->m_nClipVolumeStencilRef != pObjO->m_nClipVolumeStencilRef) - { - return false; - } - - m_RP.m_ObjFlags |= pObjN->m_ObjFlags & FOB_SELECTED; - m_RP.m_fMinDistance = min(pObjN->m_fDistance, m_RP.m_fMinDistance); - - return true; -} - -// Note: When adding/removing batch flags/techniques, make sure to update sDescList / sBatchList -static const char* sDescList[] = -{ - "NULL", - "Preprocess", - "General", - "ShadowGen", - "Decal", - "WaterVolume", - "Transparent", - "Water", - "HDRPostProcess", - "AfterHDRPostProcess", - "PostProcess", - "AfterPostProcess", - "ShadowPass", - "DeferredPreprocess", - "Skin", - "HalfResParticles", - "ParticlesThickness", - "LensOptics", - "Voxelize", - "EyeOverlay", - "FogVolume", - "GPUParticleCollisionCubemap", - "RefractiveSurface", -}; - -static const char* sBatchList[] = -{ - "FB_GENERAL", - "FB_TRANSPARENT", - "FB_SKIN", - "FB_Z", - "FB_FUR", - "FB_ZPREPASS", - "FB_PREPROCESS", - "FB_MOTIONBLUR", - "FB_POST_3D_RENDER", - "FB_MULTILAYERS", - "NULL" - "FB_CUSTOM_RENDER", - "FB_SOFTALPHATEST", - "FB_LAYER_EFFECT", - "FB_WATER_REFL", - "FB_WATER_CAUSTIC", - "FB_DEBUG", - "FB_PARTICLES_THICKNESS", - "FB_TRANSPARENT_AFTER_DOF", - "FB_EYE_OVERLAY" -}; - -// Init states before rendering of the scene -void CD3D9Renderer::FX_PreRender(int Stage) -{ - uint32 i; - - if (Stage & 1) - { // Before preprocess - m_RP.m_pSunLight = NULL; - - m_RP.m_Flags = 0; - m_RP.m_pPrevObject = NULL; - - RT_SetCameraInfo(); - - for (i = 0; i < m_RP.m_DLights[m_RP.m_nProcessThreadID][SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]].Num(); i++) - { - SRenderLight* dl = &m_RP.m_DLights[m_RP.m_nProcessThreadID][SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]][i]; - if (dl->m_Flags & DLF_FAKE) - { - continue; - } - - if (dl->m_Flags & DLF_SUN) - { - m_RP.m_pSunLight = dl; - } - } - } - - CHWShader_D3D::mfSetGlobalParams(); - m_RP.m_nCommitFlags = FC_ALL; - FX_PushVP(); -} - -// Restore states after rendering of the scene -void CD3D9Renderer::FX_PostRender() -{ - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - //FrameProfiler f("CD3D9Renderer:EF_PostRender", iSystem ); - FX_ObjectChange(NULL, NULL, m_RP.m_pIdendityRenderObject, NULL); - m_RP.m_pRE = NULL; - - FX_ResetPipe(); - FX_PopVP(); - - m_RP.m_nCurrResolveBounds[0] = m_RP.m_nCurrResolveBounds[1] = m_RP.m_nCurrResolveBounds[2] = m_RP.m_nCurrResolveBounds[3] = 0; - m_RP.m_FlagsShader_MD = 0; - m_RP.m_FlagsShader_MDV = 0; - m_RP.m_FlagsShader_LT = 0; - m_RP.m_pCurObject = m_RP.m_pIdendityRenderObject; - - pShaderThreadInfo->m_PersFlags |= RBPF_FP_DIRTY; - m_RP.m_nCommitFlags = FC_ALL; -} - -// Object changing handling (skinning, shadow maps updating, initial states setting, ...) -bool CD3D9Renderer::FX_ObjectChange(CShader* Shader, [[maybe_unused]] CShaderResources* Res, CRenderObject* obj, [[maybe_unused]] IRenderElement* pRE) -{ - FUNCTION_PROFILER_RENDER_FLAT - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - if ((pShaderThreadInfo->m_PersFlags & RBPF_SHADOWGEN)) - { - const bool bNearObjOnly = m_RP.m_ShadowInfo.m_pCurShadowFrustum->m_eFrustumType == ShadowMapFrustum::e_Nearest; - if (bNearObjOnly && !(obj->m_ObjFlags & FOB_NEAREST)) - { - return false; - } - } - - if ((obj->m_ObjFlags & FOB_NEAREST) && CV_r_nodrawnear) - { - return false; - } - - if (Shader) - { - if (pShaderThreadInfo->m_pIgnoreObject && pShaderThreadInfo->m_pIgnoreObject->m_pRenderNode == obj->m_pRenderNode) - { - return false; - } - } - - if (obj == m_RP.m_pPrevObject) - { - return true; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_RefractionPartialResolves == 2) - { - if (m_RP.m_pCurObject == NULL || obj->m_pRenderNode == NULL || obj->m_pRenderNode != m_RP.m_pCurObject->m_pRenderNode) - { - m_RP.m_nCurrResolveBounds[0] = m_RP.m_nCurrResolveBounds[1] = m_RP.m_nCurrResolveBounds[2] = m_RP.m_nCurrResolveBounds[3] = 0; - } - } - - m_RP.m_pCurObject = obj; - - int flags = 0; - if (obj != m_RP.m_pIdendityRenderObject) // Non-default object - { - if (obj->m_ObjFlags & FOB_NEAREST) - { - flags |= RBF_NEAREST; - } - - if ((flags ^ m_RP.m_Flags) & RBF_NEAREST) - { - UpdateNearestChange(flags); - } - } - else - { - HandleDefaultObject(); - } - - const uint32 nPerfFlagsExcludeMask = (RBPF_SHADOWGEN | RBPF_ZPASS); - const uint32 nPerfFlags2ExcludeMask = (RBPF2_MOTIONBLURPASS | RBPF2_CUSTOM_RENDER_PASS); - - if ((m_RP.m_nPassGroupID == EFSLIST_TRANSP) - && (obj->m_ObjFlags & FOB_REQUIRES_RESOLVE) - && !(pShaderThreadInfo->m_PersFlags & nPerfFlagsExcludeMask) - && !(m_RP.m_PersFlags2 & nPerfFlags2ExcludeMask)) - { - if IsCVarConstAccess(constexpr) (bool(CRenderer::CV_r_RefractionPartialResolves)) - { - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - if (!recursiveLevel) - { - gcpRendD3D->FX_RefractionPartialResolve(); - } - } - } - - m_RP.m_fMinDistance = obj->m_fDistance; - m_RP.m_pPrevObject = obj; - m_RP.m_CurPassBitMask = 0; - - return true; -} - -void CD3D9Renderer::UpdateNearestChange(int flags) -{ - const int nProcessThread = m_RP.m_nProcessThreadID; - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[nProcessThread]); - - const ShadowMapFrustum* pCurFrustum = m_RP.m_ShadowInfo.m_pCurShadowFrustum; - const bool bNearObjOnly = pCurFrustum && (pCurFrustum->m_eFrustumType == ShadowMapFrustum::e_Nearest) && (m_RP.m_pCurObject->m_ObjFlags & FOB_NEAREST); - if (bNearObjOnly && (pShaderThreadInfo->m_PersFlags & RBPF_SHADOWGEN)) //add additional flag - { - //set per-object camera view - Matrix44A& mPrj = pShaderThreadInfo->m_matProj; - Matrix44A& mView = pShaderThreadInfo->m_matView; - ShadowMapFrustum& curFrust = *m_RP.m_ShadowInfo.m_pCurShadowFrustum; - - mPrj = curFrust.mLightProjMatrix; - mView = curFrust.mLightViewMatrix; - - EF_SetCameraInfo(); - } - - if (!(pShaderThreadInfo->m_PersFlags & RBPF_SHADOWGEN) && (m_drawNearFov > 0.0f)) - { - if (flags & RBF_NEAREST) - { - CCamera Cam = pShaderThreadInfo->m_cam; - m_RP.m_PrevCamera = Cam; - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[nProcessThread], "*** Prepare nearest Z range ***\n"); - } - // set nice fov for weapons - - float fFov = Cam.GetFov(); - if (m_drawNearFov > 1.0f && m_drawNearFov < 179.0f) - { - fFov = DEG2RAD(m_drawNearFov); - } - - float fNearRatio = DRAW_NEAREST_MIN / Cam.GetNearPlane(); - Cam.SetAsymmetry(Cam.GetAsymL() * fNearRatio, Cam.GetAsymR() * fNearRatio, Cam.GetAsymB() * fNearRatio, Cam.GetAsymT() * fNearRatio); - Cam.SetFrustum(Cam.GetViewSurfaceX(), Cam.GetViewSurfaceZ(), fFov, DRAW_NEAREST_MIN, CV_r_DrawNearFarPlane, Cam.GetPixelAspectRatio()); - - SetCamera(Cam); - m_NewViewport.fMaxZ = CV_r_DrawNearZRange; - m_RP.m_Flags |= RBF_NEAREST; - } - else - { - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[nProcessThread], "*** Restore Z range ***\n"); - } - - SetCamera(m_RP.m_PrevCamera); - m_NewViewport.fMaxZ = m_RP.m_PrevCamera.GetZRangeMax(); - m_RP.m_Flags &= ~RBF_NEAREST; - } - - m_bViewportDirty = true; - } - m_RP.m_nCurrResolveBounds[0] = m_RP.m_nCurrResolveBounds[1] = m_RP.m_nCurrResolveBounds[2] = m_RP.m_nCurrResolveBounds[3] = 0; -} - -void CD3D9Renderer::HandleDefaultObject() -{ - if (m_RP.m_Flags & (RBF_NEAREST)) - { - if (m_logFileHandle != AZ::IO::InvalidHandle) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Restore Z range/camera ***\n"); - } - SetCamera(m_RP.m_PrevCamera); - m_NewViewport.fMaxZ = 1.0f; - m_bViewportDirty = true; - m_RP.m_Flags &= ~(RBF_NEAREST); - } - m_ViewMatrix = m_CameraMatrix; - // Restore transform - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - pShaderThreadInfo->m_matView = m_CameraMatrix; -} - -//================================================================================= -// Check buffer overflow during geometry batching -void CRenderer::FX_CheckOverflow(int nVerts, int nInds, IRenderElement* re, int* nNewVerts, int* nNewInds) -{ - if (nNewVerts) - { - *nNewVerts = nVerts; - } - if (nNewInds) - { - *nNewInds = nInds; - } - - if (m_RP.m_pRE || (m_RP.m_RendNumVerts + nVerts >= m_RP.m_MaxVerts || m_RP.m_RendNumIndices + nInds >= m_RP.m_MaxTris * 3)) - { - m_RP.m_pRenderFunc(); - if (nVerts >= m_RP.m_MaxVerts) - { - // iLog->Log("CD3D9Renderer::EF_CheckOverflow: numVerts >= MAX (%d > %d)\n", nVerts, m_RP.m_MaxVerts); - assert(nNewVerts); - *nNewVerts = m_RP.m_MaxVerts; - } - if (nInds >= m_RP.m_MaxTris * 3) - { - // iLog->Log("CD3D9Renderer::EF_CheckOverflow: numIndices >= MAX (%d > %d)\n", nInds, m_RP.m_MaxTris*3); - assert(nNewInds); - *nNewInds = m_RP.m_MaxTris * 3; - } - FX_Start(m_RP.m_pShader, m_RP.m_nShaderTechnique, m_RP.m_pShaderResources, re); - FX_StartMerging(); - } -} - -// Start of the new shader pipeline (3D pipeline version) -void CRenderer::FX_Start(CShader* ef, int nTech, CShaderResources* Res, [[maybe_unused]] IRenderElement* re) -{ - FUNCTION_PROFILER_RENDER_FLAT - assert(ef); - - PrefetchLine(&m_RP.m_pCurObject, 64); - PrefetchLine(&m_RP.m_Frame, 0); - - if (!ef) // should not be 0, check to prevent crash - { - return; - } - - PrefetchLine(&ef->m_vertexFormat, 0); - - m_RP.m_nNumRendPasses = 0; - m_RP.m_FirstIndex = 0; - m_RP.m_FirstVertex = 0; - m_RP.m_RendNumIndices = 0; - m_RP.m_RendNumVerts = 0; - m_RP.m_RendNumGroup = -1; - m_RP.m_pShader = ef; - m_RP.m_nShaderTechnique = nTech; - m_RP.m_nShaderTechniqueType = -1; - m_RP.m_pShaderResources = Res; - m_RP.m_FlagsPerFlush = 0; - - m_RP.m_FlagsStreams_Decl = 0; - m_RP.m_FlagsStreams_Stream = 0; - m_RP.m_FlagsShader_RT = 0; - m_RP.m_FlagsShader_MD = 0; - m_RP.m_FlagsShader_MDV = 0; - - const uint64 hdrMode = g_HWSR_MaskBit[HWSR_HDR_MODE]; - const uint64 sample0 = g_HWSR_MaskBit[HWSR_SAMPLE0]; - const uint64 sample1 = g_HWSR_MaskBit[HWSR_SAMPLE1]; - const uint64 sample4 = g_HWSR_MaskBit[HWSR_SAMPLE4]; - const uint64 tiled = g_HWSR_MaskBit[HWSR_TILED_SHADING]; - - FX_ApplyShaderQuality(ef->m_eShaderType); - - const uint32 nPersFlags2 = m_RP.m_PersFlags2; - if ((nPersFlags2 & RBPF2_HDR_FP16) && !(m_RP.m_nBatchFilter & (FB_Z))) - { - m_RP.m_FlagsShader_RT |= hdrMode; // deprecated: redundant flag, will be dropped (rendering always HDR) - } - static const uint32 nPFlags2Mask = (RBPF2_WATERRIPPLES | RBPF2_RAINRIPPLES | RBPF2_SKIN); - if (nPersFlags2 & nPFlags2Mask) - { - if (nPersFlags2 & RBPF2_SKIN) - { - m_RP.m_FlagsShader_RT |= sample0; - } - else - if ((nPersFlags2 & (RBPF2_WATERRIPPLES | RBPF2_RAINRIPPLES)) && ef->m_eShaderType == eST_Water) - { - m_RP.m_FlagsShader_RT |= (nPersFlags2 & RBPF2_WATERRIPPLES) ? sample4 : 0; - m_RP.m_FlagsShader_RT |= (nPersFlags2 & RBPF2_RAINRIPPLES) ? g_HWSR_MaskBit[HWSR_OCEAN_PARTICLE] : 0; - } - } - - // Set shader flag for tiled forward shading - if (CV_r_DeferredShadingTiled > 0) - { - m_RP.m_FlagsShader_RT |= tiled; - } - if (CRenderer::CV_r_SlimGBuffer) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - if (pShaderThreadInfo->m_PersFlags & RBPF_REVERSE_DEPTH) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_REVERSE_DEPTH]; - } - - m_RP.m_fCurOpacity = 1.0f; - m_RP.m_CurVFormat = ef->m_vertexFormat; - m_RP.m_ObjFlags = m_RP.m_pCurObject->m_ObjFlags; - m_RP.m_RIs[0].SetUse(0); - m_RP.m_nLastRE = 0; - - - m_RP.m_pRE = NULL; - m_RP.m_Frame++; -} - -//============================================================================================== - -static void sBatchFilter(uint32 nFilter, char* sFilt) -{ - STATIC_ASSERT((1 << ((sizeof(sBatchList) / sizeof(sBatchList[0])) - 1) <= FB_MASK), "Batch techniques/flags list mismatch"); - -AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option") - sFilt[0] = 0; - int n = 0; - for (int i = 0; i < sizeof(sBatchList) / sizeof(sBatchList[0]); i++) - { - if (nFilter & (1 << i)) - { - if (n) - { - strcat(sFilt, "|"); - } - strcat(sFilt, sBatchList[i]); - n++; - } - } -AZ_POP_DISABLE_WARNING -} - -void CD3D9Renderer::FX_StartBatching() -{ - m_RP.m_nCommitFlags = FC_ALL; -} - -void CD3D9Renderer::FX_ProcessBatchesList(int nums, int nume, uint32 nBatchFilter, uint32 nBatchExcludeFilter) -{ - PROFILE_FRAME(ProcessBatchesList); - - if (nume - nums == 0) - { - return; - } - SRenderPipeline& RESTRICT_REFERENCE rRP = m_RP; - int nList = rRP.m_nPassGroupID; - int nAW = rRP.m_nSortGroupID; - int nThreadID = rRP.m_nProcessThreadID; - - auto& RESTRICT_REFERENCE RI = CRenderView::CurrentRenderView()->GetRenderItems(nAW, nList); - assert(nums < RI.size()); - assert(nume <= RI.size()); - - - rRP.m_nBatchFilter = nBatchFilter; - - // make sure all all jobs which are computing particle vertices/indices - // have finished and their vertex/index buffers are unlocked - // before starting rendering of those - if (rRP.m_nPassGroupID == EFSLIST_TRANSP || rRP.m_nPassGroupID == EFSLIST_HALFRES_PARTICLES || rRP.m_nPassGroupID == EFSLIST_PARTICLES_THICKNESS) - { - m_ComputeVerticesJobExecutors[m_RP.m_nProcessThreadID].WaitForCompletion(); - UnLockParticleVideoMemory(gRenDev->m_nPoolIndexRT % SRenderPipeline::nNumParticleVertexIndexBuffer); - } - -#ifdef DO_RENDERLOG - STATIC_ASSERT(((sizeof(sDescList) / sizeof(sDescList[0])) == EFSLIST_NUM), "Batch techniques/flags list mismatch"); - - if (CV_r_log) - { - char sFilt[256]; - sBatchFilter(nBatchFilter, sFilt); - Logv(SRendItem::m_RecurseLevel[nThreadID], "\n*** Start batch list %s (Filter: %s) (%s) ***\n", sDescList[nList], sFilt, nAW ? "After water" : "Before water"); - } -#endif - - uint32 prevSortVal = -1; - CShader* pShader = NULL; - CShaderResources* pCurRes = NULL; - CRenderObject* pCurObject = NULL; - CShader* pCurShader = NULL; - int nTech; - - for (int i = nums; i < nume; i++) - { - SRendItem& ri = RI[i]; - if (!(ri.nBatchFlags & nBatchFilter)) - { - continue; - } - if (ri.nBatchFlags & nBatchExcludeFilter) - { - continue; - } - - CRenderObject* pObject = ri.pObj; - IRenderElement* pRE = ri.pElem; - bool bChangedShader = false; - bool bResIdentical = true; - if (prevSortVal != ri.SortVal) - { - CShaderResources* pRes; - SRendItem::mfGet(ri.SortVal, nTech, pShader, pRes); - if (pShader != pCurShader || !pRes || !pCurRes || pRes->m_IdGroup != pCurRes->m_IdGroup || (pObject->m_ObjFlags & (FOB_SKINNED | FOB_DECAL))) // Additional check for materials batching - { - bChangedShader = true; - } - bResIdentical = (pRes == pCurRes); - pCurRes = pRes; - prevSortVal = ri.SortVal; - } - if (!bChangedShader && FX_TryToMerge(pObject, pCurObject, pRE, bResIdentical)) - { - rRP.m_RIs[rRP.m_nLastRE].AddElem(&ri); - continue; - } - // when not doing main pass rendering, need to flush the shader for each data part since the external VMEM buffers are laid out only for the main pass - if (pObject && pObject != pCurObject || (m_RP.m_FlagsPerFlush & RBSI_EXTERN_VMEM_BUFFERS)) - { - if (pCurShader) - { - rRP.m_pRenderFunc(); - pCurShader = NULL; - bChangedShader = true; - } - if (!FX_ObjectChange(pShader, pCurRes, pObject, pRE)) - { - prevSortVal = ~0; - continue; - } - pCurObject = pObject; - } - - if (bChangedShader) - { - if (pCurShader) - { - rRP.m_pRenderFunc(); - } - - pCurShader = pShader; - FX_Start(pShader, nTech, pCurRes, pRE); - } - - if (pRE) - { - pRE->mfPrepare(true); - } - - if (rRP.m_RIs[0].size() == 0) - { - rRP.m_RIs[0].AddElem(&ri); - } - } - if (pCurShader) - { - rRP.m_pRenderFunc(); - } - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End batch list ***\n\n"); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Only do expensive DX12 resource set building for PC DX12 -#if defined(CRY_USE_DX12) -void CD3D9Renderer::PerFrameValidateResourceSets() -{ - AZ_TRACE_METHOD(); - int dirtyCount = CDeviceResourceSet::GetGlobalDirtyCount(); - if (dirtyCount != 0) - { - // Goes thou the list of all known resources and check if any of them needs to be re build. - ////////////////////////////////////////////////////////////////////////// - for (unsigned int i = 0; i < CShader::s_ShaderResources_known.Num(); i++) - { - CShaderResources* pSR = CShader::s_ShaderResources_known[i]; - if (pSR && pSR->m_pCompiledResourceSet) - { - if (pSR->m_pCompiledResourceSet->IsDirty()) - { - pSR->m_pCompiledResourceSet->Build(); - } - } - } - if (dirtyCount == CDeviceResourceSet::GetGlobalDirtyCount()) - { - CDeviceResourceSet::ResetGlobalDirtyCount(); - } - } -} -#endif - -void CD3D9Renderer::FX_ProcessRenderList(int nums, int nume, int nList, int nAfterWater, void(* RenderFunc)(), bool bLighting, - uint32 nBatchFilter, uint32 nBatchExcludeFilter) -{ - if (nume - nums < 1) - { - return; - } - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - const bool bTranspPass = (nList == EFSLIST_TRANSP) || (nList == EFSLIST_HALFRES_PARTICLES); - if (bTranspPass && !CV_r_TransparentPasses) - { - return; - } - - Matrix44A origMatView = pShaderThreadInfo->m_matView; - Matrix44A origMatProj = pShaderThreadInfo->m_matProj; - - m_RP.m_pRenderFunc = RenderFunc; - - m_RP.m_pCurObject = m_RP.m_pIdendityRenderObject; - m_RP.m_pPrevObject = m_RP.m_pCurObject; - - FX_PreRender(3); - - int nPrevGroup = m_RP.m_nPassGroupID; - int nPrevGroup2 = m_RP.m_nPassGroupDIP; - int nPrevSortGroupID = m_RP.m_nSortGroupID; - - m_RP.m_nPassGroupID = nList; - m_RP.m_nPassGroupDIP = nList; - m_RP.m_nSortGroupID = nAfterWater; - - FX_ProcessBatchesList(nums, nume, nBatchFilter, nBatchExcludeFilter); - - if (bLighting) - { - FX_ProcessPostGroups(nums, nume); - } - - FX_PostRender(); - - pShaderThreadInfo->m_matView = origMatView; - pShaderThreadInfo->m_matProj = origMatProj; - - m_RP.m_nPassGroupID = nPrevGroup; - m_RP.m_nPassGroupDIP = nPrevGroup2; - m_RP.m_nSortGroupID = nPrevSortGroupID; -} - -void CD3D9Renderer::FX_ProcessRenderList(int nList, uint32 nBatchFilter, bool bSetRenderFunc /* = true */) -{ - FX_PreRender(3); - - if (bSetRenderFunc) - { - m_RP.m_pRenderFunc = FX_FlushShader_General; - } - m_RP.m_nPassGroupID = nList; - m_RP.m_nPassGroupDIP = nList; - - //PROFILE_DIPS_START; - - m_RP.m_nSortGroupID = 0; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][nList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][nList], nBatchFilter); - - m_RP.m_nSortGroupID = 1; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][nList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][nList], nBatchFilter); - - //PROFILE_DIPS_END(nList); - - FX_PostRender(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - -void CD3D9Renderer::FX_ProcessZPassRender_List(ERenderListID list, uint32 filter = FB_Z) -{ - m_RP.m_nPassGroupID = list; - m_RP.m_nPassGroupDIP = list; - - m_RP.m_nSortGroupID = 0; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][list], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][list], filter); - m_RP.m_nSortGroupID = 1; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][list], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][list], filter); -} - -void CD3D9Renderer::FX_ProcessZPassRenderLists() -{ - PROFILE_LABEL_SCOPE("ZPASS"); - - if (SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID] > 0) - { - return; - } - - uint32 bfGeneral = SRendItem::BatchFlags(EFSLIST_GENERAL, m_RP.m_pRLD); - uint32 bfSkin = SRendItem::BatchFlags(EFSLIST_SKIN, m_RP.m_pRLD); - uint32 bfTransp = SRendItem::BatchFlags(EFSLIST_TRANSP, m_RP.m_pRLD); - uint32 bfDecal = SRendItem::BatchFlags(EFSLIST_DECAL, m_RP.m_pRLD); - bfGeneral |= FB_Z; - - - if ((bfGeneral | bfSkin | bfTransp | bfDecal) & FB_Z) - { -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Start z-pass ***\n"); - } -#endif - - FX_PreRender(3); - - m_RP.m_pRenderFunc = FX_FlushShader_ZPass; - const bool isGmemEnabled = FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - bool bClearZBuffer = !(m_RP.m_nRendFlags & SHDF_DO_NOT_CLEAR_Z_BUFFER); - - // For GMEM paths, depth/stencil clear gets set in CD3D9Renderer::FX_GmemTransition(...). - bClearZBuffer &= !isGmemEnabled; - - // For GMEM paths, velocity RT clear gets set in CD3D9Renderer::FX_GmemTransition(...). - if (!FX_GetEnabledGmemPath(nullptr) && UseHalfFloatRenderTargets()) - { - FX_ClearTarget(GetUtils().GetVelocityObjectRT(), Clr_White); - } - - if (CRenderer::CV_r_usezpass == 2) - { - if (bfGeneral & FB_ZPREPASS) - { - PROFILE_LABEL_SCOPE("ZPREPASS"); - - // Clear z target to prevent issues during reprojection. - // Following would resolve GMEM paths. - if (!FX_GetEnabledGmemPath(nullptr)) - { - FX_ClearTarget(CTexture::s_ptexZTarget, Clr_White); - } - - FX_ZScene(true, bClearZBuffer, false, true); - - FX_ProcessZPassRender_List(EFSLIST_GENERAL, FB_ZPREPASS); - - FX_ZScene(false, false, false, true); - bClearZBuffer = false; - } - } - - { - PROFILE_LABEL_SCOPE("GBUFFER"); - - FX_ZScene(true, bClearZBuffer); - - if (bfGeneral & FB_Z) - { - PROFILE_LABEL_SCOPE("GENERAL"); - FX_ProcessZPassRender_List(EFSLIST_GENERAL); - } - if (bfSkin & FB_Z) - { - PROFILE_LABEL_SCOPE("SKIN"); - FX_ProcessZPassRender_List(EFSLIST_SKIN); - } - if (bfTransp & FB_Z) - { - PROFILE_LABEL_SCOPE("TRANSPARENT"); - FX_ProcessZPassRender_List(EFSLIST_TRANSP); - } - - // PC special case: render terrain/decals/roads normals separately - disable mrt rendering, on consoles we always use single rt for output - FX_ZScene(false, false); - FX_ZScene(true, false, true); - - m_RP.m_PersFlags2 &= ~RBPF2_NOALPHABLEND; - m_RP.m_StateAnd |= GS_BLEND_MASK; - - if (bfDecal & FB_Z) - { - PROFILE_LABEL_SCOPE("DECALS"); - FX_ProcessZPassRender_List(EFSLIST_DECAL); - } - - FX_ZScene(false, false, true); - } - - if (isGmemEnabled) - { - FX_GmemTransition(eGT_POST_GBUFFER); - } - - // For some GMEM paths, the depth gets linearized right away during z-pass. - // Depth downsampling gets done during transitions in CD3D9Renderer::FX_GmemTransition(...). - if (!isGmemEnabled) - { - // Reset current object so we don't end up with RBF_NEAREST states in FX_LinearizeDepth - FX_ObjectChange(NULL, NULL, m_RP.m_pIdendityRenderObject, NULL); - - FX_LinearizeDepth(CTexture::s_ptexZTarget); - - if (!CRenderer::CV_r_EnableComputeDownSampling) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DRENDPIPELINE_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DRendPipeline_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - GetUtils().DownsampleDepth(CTexture::s_ptexZTarget, CTexture::s_ptexZTargetScaled, true); -#endif - GetUtils().DownsampleDepth(CTexture::s_ptexZTargetScaled, CTexture::s_ptexZTargetScaled2, false); - } - else - { - CTexture* UAVArr[2] = - { - CTexture::s_ptexZTargetScaled, - CTexture::s_ptexZTargetScaled2 - }; - GetUtils().DownsampleDepthUsingCompute(CTexture::s_ptexZTarget, UAVArr, false); - } - } - - FurPasses::GetInstance().ExecuteZPostPass(); - - FX_ZScene(true, false, true); - m_RP.m_PersFlags2 &= ~RBPF2_NOALPHABLEND; - m_RP.m_StateAnd |= GS_BLEND_MASK; - - FX_PostRender(); - RT_SetViewport(0, 0, GetWidth(), GetHeight()); - - if (m_RP.m_PersFlags2 & RBPF2_ALLOW_DEFERREDSHADING) - { - m_bDeferredDecals = FX_DeferredDecals(); - } - - m_RP.m_PersFlags2 |= RBPF2_NOALPHABLEND; - m_RP.m_StateAnd &= ~GS_BLEND_MASK; - - FX_ZScene(false, false, true); - - FX_ZTargetReadBack(); - - m_RP.m_pRenderFunc = FX_FlushShader_General; - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End z-pass ***\n"); - } -#endif - } -} - -////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_ProcessThicknessRenderLists() -{ - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0 && 0) // Thickness pass disabled temporarily - { - uint32 nBatchMask = SRendItem::BatchFlags(EFSLIST_TRANSP, m_RP.m_pRLD); - if (nBatchMask & FB_PARTICLES_THICKNESS) - { - PROFILE_LABEL_SCOPE("PARTICLES_THICKNESS_PASS"); - - CTexture* pThicknessTarget = CTexture::s_ptexBackBufferScaled[1]; - const uint32 nWidthRT = pThicknessTarget->GetWidth(); - const uint32 nHeightRT = pThicknessTarget->GetHeight(); - - FX_PreRender(3); - - // Get current viewport - int iTempX, iTempY, iWidth, iHeight; - GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - FX_ClearTarget(pThicknessTarget, Clr_Median); - FX_PushRenderTarget(0, pThicknessTarget, NULL); - RT_SetViewport(0, 0, nWidthRT, nHeightRT); - - m_RP.m_nPassGroupID = EFSLIST_TRANSP; - m_RP.m_nPassGroupDIP = EFSLIST_TRANSP; - - m_RP.m_nSortGroupID = 0; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][EFSLIST_TRANSP], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][EFSLIST_TRANSP], FB_PARTICLES_THICKNESS); - - m_RP.m_nSortGroupID = 1; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][EFSLIST_TRANSP], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][EFSLIST_TRANSP], FB_PARTICLES_THICKNESS); - - FX_PopRenderTarget(0); - - PostProcessUtils().TexBlurGaussian(pThicknessTarget, 1, 1, 1.0f, false); - FX_SetActiveRenderTargets(); - RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - FX_PostRender(); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::FX_ProcessSoftAlphaTestRenderLists() -{ - int32 nList = EFSLIST_GENERAL; - - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0) - { -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** Begin soft alpha test pass ***\n"); - } -#endif - - uint32 nBatchMask = SRendItem::BatchFlags(nList, m_RP.m_pRLD); - if (nBatchMask & FB_SOFTALPHATEST) - { - m_RP.m_PersFlags2 |= RBPF2_NOALPHATEST; - - FX_PreRender(3); - - m_RP.m_nPassGroupID = nList; - m_RP.m_nPassGroupDIP = nList; - - m_RP.m_nSortGroupID = 0; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][nList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][nList], FB_SOFTALPHATEST); - m_RP.m_nSortGroupID = 1; - FX_ProcessBatchesList(m_RP.m_pRLD->m_nStartRI[m_RP.m_nSortGroupID][nList], m_RP.m_pRLD->m_nEndRI[m_RP.m_nSortGroupID][nList], FB_SOFTALPHATEST); - - FX_PostRender(); - - m_RP.m_PersFlags2 &= ~RBPF2_NOALPHATEST; - } - -#ifdef DO_RENDERLOG - if (CV_r_log) - { - Logv(SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID], "*** End soft alpha test pass ***\n"); - } -#endif - } -} - - -void CD3D9Renderer::FX_ProcessPostRenderLists(uint32 nBatchFilter) -{ - int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - - if ((m_RP.m_nRendFlags & SHDF_ALLOWPOSTPROCESS) && recursiveLevel <= 0) - { - uint32 nBatchMask = SRendItem::BatchFlags(EFSLIST_GENERAL, m_RP.m_pRLD) | SRendItem::BatchFlags(EFSLIST_TRANSP, m_RP.m_pRLD); - nBatchMask |= SRendItem::BatchFlags(EFSLIST_DECAL, m_RP.m_pRLD); - nBatchMask |= SRendItem::BatchFlags(EFSLIST_SKIN, m_RP.m_pRLD); - if (nBatchMask & nBatchFilter) - { - if (nBatchFilter == FB_CUSTOM_RENDER || nBatchFilter == FB_POST_3D_RENDER) - { - FX_CustomRenderScene(true); - } - - FX_ProcessRenderList(EFSLIST_GENERAL, nBatchFilter); - FX_ProcessRenderList(EFSLIST_SKIN, nBatchFilter); - - if (nBatchFilter != FB_MOTIONBLUR) - { - FX_ProcessRenderList(EFSLIST_DECAL, nBatchFilter); - } - - FX_ProcessRenderList(EFSLIST_TRANSP, nBatchFilter); - - if (nBatchFilter == FB_CUSTOM_RENDER || nBatchFilter == FB_POST_3D_RENDER) - { - FX_CustomRenderScene(false); - } - } - } -} - -void CD3D9Renderer::FX_ProcessPostGroups(int nums, int nume) -{ - const uint32 nPrevPersFlags2 = m_RP.m_PersFlags2; - m_RP.m_PersFlags2 &= ~RBPF2_FORWARD_SHADING_PASS; - - uint32 nBatchMask = m_RP.m_pRLD->m_nBatchFlags[m_RP.m_nSortGroupID][m_RP.m_nPassGroupID]; - AZ_PUSH_DISABLE_WARNING(, "-Wconstant-logical-operand") - if (nBatchMask & FB_MULTILAYERS && CV_r_usemateriallayers) - AZ_POP_DISABLE_WARNING - { - FX_ProcessBatchesList(nums, nume, FB_MULTILAYERS); - } - if (0 != (nBatchMask & FB_DEBUG)) - { - FX_ProcessBatchesList(nums, nume, FB_DEBUG); - } - - m_RP.m_PersFlags2 = nPrevPersFlags2; -} - - -void CD3D9Renderer::FX_ApplyThreadState(SThreadInfo& TI, SThreadInfo* pOldTI) -{ - if (pOldTI) - { - *pOldTI = m_RP.m_TI[m_RP.m_nProcessThreadID]; - } - - m_RP.m_TI[m_RP.m_nProcessThreadID] = TI; -} - -CD3D9Renderer::OcclusionReadbackData::~OcclusionReadbackData() -{ - Destroy(); -} - -void CD3D9Renderer::OcclusionReadbackData::Destroy() -{ - azfree(m_occlusionReadbackBuffer); - m_occlusionReadbackBuffer = nullptr; -} -void CD3D9Renderer::OcclusionReadbackData::Reset(bool reverseDepth) -{ - m_occlusionReadbackViewProj.SetIdentity(); - - if (!m_occlusionReadbackBuffer) - { - m_occlusionReadbackBuffer = static_cast(azmalloc(CD3D9Renderer::s_occlusionBufferNumElements * sizeof(float), 16)); - } - std::fill(m_occlusionReadbackBuffer, m_occlusionReadbackBuffer + CD3D9Renderer::s_occlusionBufferNumElements, (reverseDepth) ? 0.0f : 1.0f); -} - -void CD3D9Renderer::InvalidateCoverageBufferData() -{ - static const char* occlusionDataTextureName[s_numOcclusionReadbackTextures] = { - "$ZTargetReadBack0", - "$ZTargetReadBack1", - "$ZTargetReadBack2" - }; - - static_assert(s_numOcclusionReadbackTextures == 3, "Change the initialization of occlusionDataTextureName if you change s_numOcclusionReadbackTextures!"); - - for (size_t i = 0; i < s_numOcclusionReadbackTextures; i++) - { - m_occlusionData[i].SetupOcclusionData(occlusionDataTextureName[i]); - } - m_cpuOcclusionReadIndex = 0; - m_occlusionBufferIndex = 0; -} - -void CD3D9Renderer::CPUOcclusionData::SetupOcclusionData(const char* textureName) -{ - m_occlusionDataState = CPUOcclusionData::OcclusionDataState::OcclusionDataInvalid; - m_occlusionViewProj.SetIdentity(); - - // Note: The macro Clr_FarPlane_R expects the variable name bReverseDepth to determine the clear value - const bool bReverseDepth = CRenderer::CV_r_ReverseDepth > 0 ? true : false; - if (!m_zTargetReadback) - { - unsigned int flags = FT_DONT_STREAM | FT_DONT_RELEASE | FT_STAGE_READBACK; - m_zTargetReadback = CTexture::CreateTextureObject(textureName, s_occlusionBufferWidth, s_occlusionBufferHeight, 1, eTT_2D, flags, eTF_Unknown); - //CPU reading code expects it to be 32 bit float. Changing this to 16bit would require "16bit to 32bitfloat" conversion in FX_ZTargetReadBackOnCPU. - m_zTargetReadback->CreateRenderTarget(eTF_R32F, Clr_FarPlane_R); - } - - m_occlusionReadbackData.Reset(bReverseDepth); -} - -void CD3D9Renderer::CPUOcclusionData::Destroy() -{ - SAFE_RELEASE(m_zTargetReadback); - m_occlusionReadbackData.Destroy(); -} - -int CD3D9Renderer::GetOcclusionBuffer(uint16* pOutOcclBuffer, Matrix44* pmCamBuffer) -{ - AZ_Assert(m_cpuOcclusionReadIndex < s_numOcclusionReadbackTextures, "m_cpuOcclusionReadIndex (%u) out of range (%u)", m_cpuOcclusionReadIndex.load(), s_numOcclusionReadbackTextures); - const CPUOcclusionData& occlusionData = m_occlusionData[m_cpuOcclusionReadIndex]; - - // Do not perform occlusion checks if our data is not ready or has been invalidated - if (occlusionData.m_occlusionDataState == CPUOcclusionData::OcclusionDataState::OcclusionDataInvalid) - { - return 0; - } - - const OcclusionReadbackData& readbackData = occlusionData.m_occlusionReadbackData; - - // Copy the data that was prepared by the render thread for use with the Coverage Buffer system - memcpy(pOutOcclBuffer, readbackData.m_occlusionReadbackBuffer, s_occlusionBufferNumElements * sizeof(float)); - - *pmCamBuffer = readbackData.m_occlusionReadbackViewProj; - - return 1; -} - -bool IsDepthReadbackOcclusionEnabled() -{ - static ICVar* pCVCheckOcclusion = gEnv->pConsole->GetCVar("e_CheckOcclusion"); - static ICVar* pCVStatObjBufferRenderTasks = gEnv->pConsole->GetCVar("e_StatObjBufferRenderTasks"); - static ICVar* pCVCoverageBufferReproj = gEnv->pConsole->GetCVar("e_CoverageBufferReproj"); - if ((pCVCheckOcclusion && pCVCheckOcclusion->GetIVal() == 0) || - (pCVStatObjBufferRenderTasks && pCVStatObjBufferRenderTasks->GetIVal() == 0) || - (pCVCoverageBufferReproj && pCVCoverageBufferReproj->GetIVal() == 4)) - { - return false; - } - - return true; -} - -void CD3D9Renderer::UpdateOcclusionDataForCPU() -{ - const bool bReverseDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - - // Copy to CPU accessible memory - m_occlusionData[m_occlusionBufferIndex].m_zTargetReadback->GetDevTexture()->DownloadToStagingResource(0); - - Matrix44 mCurView, mCurProj; - mCurView.SetIdentity(); - mCurProj.SetIdentity(); - GetModelViewMatrix(reinterpret_cast(&mCurView)); - GetProjectionMatrix(reinterpret_cast(&mCurProj)); - - if (bReverseDepth) - { - mCurProj = ReverseDepthHelper::Convert(mCurProj); - } - - m_occlusionData[m_occlusionBufferIndex].m_occlusionViewProj = mCurView * mCurProj; - m_occlusionData[m_occlusionBufferIndex].m_occlusionDataState = CPUOcclusionData::OcclusionDataState::OcclusionDataOnGPU; - - m_occlusionBufferIndex = (m_occlusionBufferIndex + 1) % s_numOcclusionReadbackTextures; -} - -void CD3D9Renderer::FX_ZTargetReadBackOnCPU() -{ - PROFILE_LABEL_SCOPE("DEPTH READBACK CPU"); - PROFILE_FRAME(FX_ZTargetReadBackOnCPU); - - if (!IsDepthReadbackOcclusionEnabled() || (SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID] > 0)) - { - return; - } - - const bool isGmemEnabled = FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - if (isGmemEnabled) - { - //Since FX_ZTargetReadBack can not be run for gmem path we update the - //occlusion data for m_occlusionData here. - UpdateOcclusionDataForCPU(); - } - - static ICVar* pCVCoverageBufferLatency = gEnv->pConsole->GetCVar("e_CoverageBufferNumberFramesLatency"); - int latency = pCVCoverageBufferLatency->GetIVal(); - - // Readback index for the depth buffer in our ring buffer - AZ::u8 occlusionReadbackIndex = 0; - static_assert(s_numOcclusionReadbackTextures <= 3, "Maximum of 3 occlusion readback textures currently supported"); - switch (latency) - { - case 0: - // Do not perform any CPU readback - return; - break; - - case 1: - // Readback the depth buffer that was written to this frame (CPU will stall on GPU, useful for debugging) - occlusionReadbackIndex = (m_occlusionBufferIndex + 2) % s_numOcclusionReadbackTextures; - break; - - case 2: - // Readback previous frame. - occlusionReadbackIndex = (m_occlusionBufferIndex + 1) % s_numOcclusionReadbackTextures; - break; - - case 3: - // Readback oldest frame - occlusionReadbackIndex = m_occlusionBufferIndex; - break; - } - CPUOcclusionData& occlusionData = m_occlusionData[occlusionReadbackIndex]; - - // Do not perform readback if our occlusion data is not ready to be read back - if (occlusionData.m_occlusionDataState != CPUOcclusionData::OcclusionDataState::OcclusionDataOnGPU) - { - return; - } - - const bool bUseNativeDepth = CRenderer::CV_r_CBufferUseNativeDepth && !gEnv->IsEditor(); - const bool bReverseDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - - int nCameraID = -1; - - // In stereo rendering, we want the coverage buffer to be a merge of both rendered eyes. Otherwise one eye may - // cull out the geometry visible be the other eye. - bool mergePreviousBuffer = (GetS3DRend().GetStatus() == IStereoRenderer::Status::kRenderingSecondEye); - - // Read data from the prepared frame - occlusionData.m_zTargetReadback->GetDevTexture()->AccessCurrStagingResource(0, false, [=, &nCameraID](void* pData, [[maybe_unused]] uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - float* pDepths = reinterpret_cast(pData); - const CameraViewParameters& rc = GetViewParameters(); - float zn = rc.fNear; - float zf = rc.fFar; - const float ProjRatioX = zf / (zf - zn); - const float ProjRatioY = zn / (zn - zf); - - OcclusionReadbackData& readbackData = m_occlusionData[occlusionReadbackIndex].m_occlusionReadbackData; - readbackData.m_occlusionReadbackViewProj = m_occlusionData[occlusionReadbackIndex].m_occlusionViewProj; - float* readBuffer = readbackData.m_occlusionReadbackBuffer; - - if (bUseNativeDepth) - { - float x = floorf(pDepths[0] * 0.5f); // Decode the ID from the first pixel - readBuffer[0] = pDepths[0] - (x * 2.0f); - nCameraID = (int)(x); - - for (uint32 idx = 1; idx < s_occlusionBufferNumElements; idx++) - { - const float fDepthVal = bReverseDepth ? 1.0f - pDepths[idx] : pDepths[idx]; - if (mergePreviousBuffer) - { - if (readBuffer[idx] == FLT_EPSILON) - { - readBuffer[idx] = max(fDepthVal, FLT_EPSILON); - } - else - { - float maxDepth = max(fDepthVal, readBuffer[idx]); - readBuffer[idx] = max(maxDepth, FLT_EPSILON); - } - } - else - { - readBuffer[idx] = max(fDepthVal, FLT_EPSILON); - } - } - } - else - { - for (uint32 idx = 0; idx < s_occlusionBufferNumElements; idx++) - { - if (!mergePreviousBuffer) - { - readBuffer[idx] = max(ProjRatioY / max(pDepths[idx], FLT_EPSILON) + ProjRatioX, FLT_EPSILON); - } - else - { - if (readBuffer[idx] == FLT_EPSILON) - { - readBuffer[idx] = max(ProjRatioY / max(pDepths[idx], FLT_EPSILON) + ProjRatioX, FLT_EPSILON); - } - else - { - float newDepth = ProjRatioY / max(pDepths[idx], FLT_EPSILON) + ProjRatioX; - float maxDepth = max(newDepth, readBuffer[idx]); - readBuffer[idx] = max(maxDepth, FLT_EPSILON); - } - } - } - } - - return true; - }); - - occlusionData.m_occlusionDataState = CPUOcclusionData::OcclusionDataState::OcclusionDataOnCPU; - m_cpuOcclusionReadIndex = occlusionReadbackIndex; -} - -void CD3D9Renderer::FX_ZTargetReadBack() -{ - PROFILE_LABEL_SCOPE("DEPTH READBACK GPU"); - PROFILE_FRAME(FX_ZTargetReadBack); - - //Check for gmem as this code runs after gbuffer breaking gmem path. Besides we can just use - //downsampled linearized depth for occlusion. - const bool isGmemEnabled = FX_GetEnabledGmemPath(nullptr) != CD3D9Renderer::eGT_REGULAR_PATH; - - if (!IsDepthReadbackOcclusionEnabled() || isGmemEnabled) - { - return; - } - - const bool bUseNativeDepth = CRenderer::CV_r_CBufferUseNativeDepth && !gEnv->IsEditor(); - const bool bReverseDepth = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - int sourceWidth = CTexture::s_ptexZTarget->GetWidth(); - int sourceHeight = CTexture::s_ptexZTarget->GetHeight(); - - if (sourceWidth != m_occlusionSourceSizeX || sourceHeight != m_occlusionSourceSizeY) - { - m_occlusionSourceSizeX = sourceWidth; - m_occlusionSourceSizeY = sourceHeight; - - int downSampleX = max(0, 1 + IntegerLog2((uint16)((m_occlusionSourceSizeX * m_RP.m_CurDownscaleFactor.x) / s_occlusionBufferWidth))); - int downSampleY = max(0, 1 + IntegerLog2((uint16)((m_occlusionSourceSizeY * m_RP.m_CurDownscaleFactor.y) / s_occlusionBufferHeight))); - m_numOcclusionDownsampleStages = min(4, max(downSampleX, downSampleY)); - - const uint32 nFlags = FT_DONT_STREAM | FT_DONT_RELEASE | FT_STAGE_READBACK; - for (int downsampleStage = 0; downsampleStage < m_numOcclusionDownsampleStages; downsampleStage++) - { - const int width = s_occlusionBufferWidth << (m_numOcclusionDownsampleStages - downsampleStage - 1); - const int height = s_occlusionBufferHeight << (m_numOcclusionDownsampleStages - downsampleStage - 1); - - if (CTexture::s_ptexZTargetDownSample[downsampleStage]) - { - CTexture::s_ptexZTargetDownSample[downsampleStage]->m_nFlags = nFlags; - CTexture::s_ptexZTargetDownSample[downsampleStage]->m_nWidth = width; - CTexture::s_ptexZTargetDownSample[downsampleStage]->m_nHeight = height; - - CTexture::s_ptexZTargetDownSample[downsampleStage]->CreateRenderTarget(CTexture::s_eTFZ, Clr_FarPlane_R); - } - else - { - assert(CTexture::s_ptexZTargetDownSample[downsampleStage]); - } - } - - InvalidateCoverageBufferData(); - } - - // downsample on GPU - RECT srcRect; - srcRect.top = srcRect.left = 0; - srcRect.right = LONG(CTexture::s_ptexZTargetDownSample[0]->GetWidth() * m_RP.m_CurDownscaleFactor.x); - srcRect.bottom = LONG(CTexture::s_ptexZTargetDownSample[0]->GetHeight() * m_RP.m_CurDownscaleFactor.y); - - RECT* srcRegion = &srcRect; - - bool bMSAA = m_RP.m_MSAAData.Type ? true : false; - - D3DShaderResourceView* pZTargetOrigSRV = (D3DShaderResourceView*) CTexture::s_ptexZTarget->GetShaderResourceView(bMSAA ? SResourceView::DefaultViewMS : SResourceView::DefaultView); - if (bUseNativeDepth) - { - CTexture::s_ptexZTarget->SetShaderResourceView(m_pZBufferDepthReadOnlySRV, bMSAA); // Read native depth, rather than linear. TODO: Check me, this may be slow on ATI MSAA - - int vpX, vpY, vpWidth, vpHeight; - GetViewport(&vpX, &vpY, &vpWidth, &vpHeight); - - srcRect.right = LONG(srcRect.right * vpWidth / float(m_width)); - srcRect.bottom = LONG(srcRect.bottom * vpHeight / float(m_height)); - } - else - { - bMSAA = false; - } - - CTexture* pSrc = CTexture::s_ptexZTarget; - CTexture* pDst = CTexture::s_ptexZTarget; - - bool bUseMSAA = bMSAA; - const SPostEffectsUtils::EDepthDownsample downsampleMode = (bUseNativeDepth && bReverseDepth) - ? SPostEffectsUtils::eDepthDownsample_Min - : SPostEffectsUtils::eDepthDownsample_Max; - - for (int i = 0; i < m_numOcclusionDownsampleStages; i++) - { - pDst = CTexture::s_ptexZTargetDownSample[i]; - GetUtils().StretchRect(pSrc, pDst, false, false, false, false, downsampleMode, false, srcRegion); - pSrc = pDst; - srcRegion = NULL; - bUseMSAA = false; - } - - pSrc = pDst; - pDst = m_occlusionData[m_occlusionBufferIndex].m_zTargetReadback; - PostProcessUtils().StretchRect(pSrc, pDst, false, false, false, false, downsampleMode); - - // Blend ID into top left pixel of readback buffer - gcpRendD3D->FX_PushRenderTarget(0, pDst, NULL); - gcpRendD3D->RT_SetViewport(0, 0, 1, 1); - - CShader* pSH = CShaderMan::s_ShaderCommon; - uint32 nPasses = 0; - pSH->FXSetTechnique("ClearUniform"); - pSH->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - static CCryNameR pClearParams("vClearParam"); - m_RP.m_nZOcclusionBufferID = ((m_RP.m_nZOcclusionBufferID + 1) < CULLER_MAX_CAMS) ? (m_RP.m_nZOcclusionBufferID + 1) : 0; - Vec4 vFrameID = Vec4((float)(m_RP.m_nZOcclusionBufferID * 2.0f), 0, 0, 0); - pSH->FXSetPSFloat(pClearParams, &vFrameID, 1); - - FX_SetState(GS_NODEPTHTEST | GS_BLSRC_ONE | GS_BLDST_ONE); - D3DSetCull(eCULL_None); - float fX = (float)m_CurViewport.nWidth; - float fY = (float)m_CurViewport.nHeight; - ColorF col = Col_Black; - DrawQuad(-0.5f, -0.5f, fX - 0.5f, fY - 0.5f, col, 1.0f, fX, fY, fX, fY); - - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->RT_SetViewport(0, 0, GetWidth(), GetHeight()); - - if (bUseNativeDepth) - { - CTexture::s_ptexZTarget->SetShaderResourceView(pZTargetOrigSRV, bMSAA); - } - - UpdateOcclusionDataForCPU(); -} - -void CD3D9Renderer::FX_UpdateCharCBs() -{ - PROFILE_FRAME(FX_UpdateCharCBs); - AZ_TRACE_METHOD(); - unsigned poolId = (m_nPoolIndexRT) % 3; - for (size_t boneType = 0; boneType < eBoneType_Count; ++boneType) - { - for (util::list* iter = m_CharCBActiveList[boneType][poolId].next; iter != &m_CharCBActiveList[boneType][poolId]; iter = iter->next) - { - SCharInstCB* cb = iter->item<&SCharInstCB::list>(); - if (cb->updated) - { - continue; - } - SSkinningData* pSkinningData = cb->m_pSD; - - // make sure all sync jobs filling the buffers have finished - if (pSkinningData->pAsyncJobExecutor) - { - PROFILE_FRAME(FX_UpdateCharCBs_ASYNC_WAIT); - pSkinningData->pAsyncJobExecutor->WaitForCompletion(); - } - - if (pSkinningData->nHWSkinningFlags & eHWS_Skinning_Matrix) - { - AZ_Assert(boneType == eBoneType_Matrix, "Skinning type is Matrix but bone type is not."); - cb->m_buffer->UpdateBuffer(pSkinningData->pBoneMatrices, pSkinningData->nNumBones * sizeof(Matrix34)); - } - else - { - AZ_Assert(boneType == eBoneType_DualQuat, "Copying DualQuat buffer but bone type is not DualQuat."); - cb->m_buffer->UpdateBuffer(pSkinningData->pBoneQuatsS, pSkinningData->nNumBones * sizeof(DualQuat)); - } - - cb->updated = true; - } - } - // free a buffer each frame if we have an over-comittment of more than 75% compared - // to our last 2 frames of rendering - { - int committed = CryInterlockedCompareExchange((LONG*)&m_CharCBAllocated, 0, 0); - int totalRequested = m_CharCBFrameRequired[poolId] + m_CharCBFrameRequired[(poolId - 1) % 3]; - WriteLock _lock(m_lockCharCB); - - for (size_t boneType = 0; boneType < eBoneType_Count; ++boneType) - { - if (totalRequested * 4 > committed * 3 && m_CharCBFreeList[boneType].empty() == false) - { - delete m_CharCBFreeList[boneType].prev->item<&SCharInstCB::list>(); - CryInterlockedDecrement(&m_CharCBAllocated); - break; - } - } - } -} - -void* CD3D9Renderer::FX_AllocateCharInstCB(SSkinningData* pSkinningData, uint32 frameId) -{ - PROFILE_FRAME(FX_AllocateCharInstCB); - SCharInstCB* cb = NULL; - - size_t boneType = eBoneType_DualQuat; - size_t boneSize = sizeof(DualQuat); - - if (pSkinningData->nHWSkinningFlags & eHWS_Skinning_Matrix) - { - boneType = eBoneType_Matrix; - boneSize = sizeof(Matrix34); - } - - { - WriteLock _lock(m_lockCharCB); - if (m_CharCBFreeList[boneType].empty() == false) - { - cb = m_CharCBFreeList[boneType].next->item<& SCharInstCB::list>(); - cb->list.erase(); - } - } - if (cb == NULL) - { - cb = new SCharInstCB(); - cb->m_buffer = gcpRendD3D->m_DevBufMan.CreateConstantBuffer( - "SkinningBones", - 768 * boneSize, - AzRHI::ConstantBufferUsage::Static); - CryInterlockedIncrement(&m_CharCBAllocated); - } - cb->updated = false; - cb->m_pSD = pSkinningData; - { - WriteLock _lock(m_lockCharCB); - cb->list.relink_tail(&m_CharCBActiveList[boneType][frameId % 3]); - } - CryInterlockedIncrement(&m_CharCBFrameRequired[frameId % 3]); - return cb; -} - -void CD3D9Renderer::FX_ClearCharInstCB(uint32 frameId) -{ - PROFILE_FRAME(FX_ClearCharInstCB); - uint32 poolId = frameId % 3; - WriteLock _lock(m_lockCharCB); - m_CharCBFrameRequired[poolId] = 0; - - for (size_t boneType = 0; boneType < eBoneType_Count; ++boneType) - { - m_CharCBFreeList[boneType].splice_tail(&m_CharCBActiveList[boneType][poolId]); - } -} - -// Render thread only scene rendering -void CD3D9Renderer::RT_RenderScene(int nFlags, SThreadInfo& TI, void(* RenderFunc)()) -{ - // We first ensure that CRenderer::CV_r_EnableGMEMPath is only used for iOS or Android. Required - // for when running in the editor and selecting the ios or android .cfg file settings. Only need - // to worry about this in non-release builds as the default value is 0 and the editor is not built - // in release builds. -#if (!defined (ANDROID) && !defined(IOS)) - CRenderer::CV_r_EnableGMEMPath = 0; -#endif - // We first ensure that CRenderer::r_EnableComputeDownSampling is only used for iOS Metal -#if (!defined (CRY_USE_METAL) || !defined(IOS)) - CRenderer::CV_r_EnableComputeDownSampling = 0; -#endif - - int const nCurrentRecurseLvl = SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID]; - - PROFILE_LABEL_SCOPE(nCurrentRecurseLvl == 0 ? "SCENE" : "SCENE_REC"); - - gcpRendD3D->SetCurDownscaleFactor(gcpRendD3D->m_CurViewportScale); - - // Skip scene rendering when device is lost - if (m_bDeviceLost) - { - return; - } - - SThreadInfo* const pShaderThreadInfo = &(m_RP.m_TI[m_RP.m_nProcessThreadID]); - - //////////////////////////////////////////////// - // to non-thread safe remaing work for *::Render functions - { - PROFILE_FRAME(WaitForRendItems); - m_finalizeRendItemsJobExecutor[m_RP.m_nProcessThreadID].WaitForCompletion(); - m_finalizeShadowRendItemsJobExecutor[m_RP.m_nProcessThreadID].WaitForCompletion(); - } - - CRenderMesh::FinalizeRendItems(m_RP.m_nProcessThreadID); - CMotionBlur::InsertNewElements(); - FurBendData::Get().InsertNewElements(); - - { - PROFILE_LABEL_SCOPE("UpdateModifiedMeshes"); - CRenderMesh::UpdateModified(); - } - - // Once per frame, notify that the start of the render thread scene rendering has begun. - if (nCurrentRecurseLvl == 0) - { - AZ::RenderThreadEventsBus::Broadcast(&AZ::RenderThreadEventsBus::Events::OnRenderThreadRenderSceneBegin); - } - - //////////////////////////////////////////////// -#ifdef CRY_INTEGRATE_DX12 - GetGraphicsPipeline().Prepare(); - - // Make sure all dirty device resource sets are rebuild. - PerFrameValidateResourceSets(); -#endif - //////////////////////////////////////////////// - - const int recursiveLevel = SRendItem::m_RecurseLevel[m_RP.m_nProcessThreadID]; - const int currentFrameId = GetFrameID(false); - CRenderView& currentView = *m_RP.m_pRenderViews[m_RP.m_nProcessThreadID]; - - // set to use RenderList Description - m_RP.m_pRLD = &m_RP.m_pRenderViews[m_RP.m_nProcessThreadID]->m_RenderListDesc[recursiveLevel]; - - CTimeValue Time = iTimer->GetAsyncTime(); - - if (!recursiveLevel) - { - m_MainViewport.nX = 0; - m_MainViewport.nY = 0; - m_MainViewport.nWidth = m_width; - m_MainViewport.nHeight = m_height; - } - - // invalidate object pointers - m_RP.m_pCurObject = m_RP.m_pPrevObject = m_RP.m_pIdendityRenderObject; - - RT_UpdateLightVolumes(nFlags, recursiveLevel); - - // Wait for shadow jobs before building constant buffers. - { - PROFILE_FRAME(WaitForShadowRendItems); - m_finalizeShadowRendItemsJobExecutor[m_RP.m_nProcessThreadID].WaitForCompletion(); - } - - // Precompile constant buffers for the frame. - { - GetPerInstanceConstantBufferPool().Update(currentView, TI.m_RealTime); - - FX_UpdateCharCBs(); - - CHWShader_D3D::UpdatePerFrameResourceGroup(); - } - - // - // Process Shadow Maps - // - if (!recursiveLevel && !(nFlags & SHDF_ZPASS_ONLY)) - { - if (nFlags & SHDF_NO_SHADOWGEN) - { - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_NO_SHADOWGEN; - } - else - { - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_NO_SHADOWGEN; - } - - PROFILE_LABEL_SCOPE("SHADOWMAP PASSES"); - PROFILE_PS_TIME_SCOPE(fTimeDIPs[EFSLIST_SHADOW_GEN]); - EF_PrepareAllDepthMaps(); - } - - if (FX_GetEnabledGmemPath(nullptr)) - { - FX_GmemTransition(eGT_PRE_Z); - } - - int nSaveDrawNear = CV_r_nodrawnear; - int nSaveStreamSync = CV_r_texturesstreamingsync; - if (nFlags & SHDF_NO_DRAWNEAR) - { - CV_r_nodrawnear = 1; - } - if (nFlags & SHDF_STREAM_SYNC) - { - CV_r_texturesstreamingsync = 1; - } - - m_bDeferredDecals = false; - uint32 nSaveRendFlags = m_RP.m_nRendFlags; - m_RP.m_nRendFlags = nFlags; - FX_ApplyThreadState(TI, &m_RP.m_OldTI[recursiveLevel]); - - // - // VR Tracking updates - // - - if (m_pStereoRenderer->IsRenderingToHMD()) - { - if (gRenDev->m_CurRenderEye == STEREO_EYE_LEFT) - { - /* - Update tracking states for VR: - For OpenVR we need to tell the compositor (SteamVR) to retrieve up to date tracking info. - This is a blocking call that will only return when the compositor allows us - Calling this here allows the GPU work submitted above to get a head start while - we wait for the compositor to free us. - - This only need to be done once per frame but must be done on the render thread. - This cannot be done on the main thread or a job/side thread or else it will - cause tracking to de-sync from rendering causing all frames to render with out - of date tracking. Updating tracking here significantly reduces GPU bubbles. - - For Oculus, PSVR etc this is still the best place to request a tracking - update in a multi-threaded scenario. It ensures that any prediction will be done - for this frame that we want to render rather than the next frame. - */ - RT_UpdateTrackingStates(); - } - - /* - After tracking has updated we want to override the camera with the - correct tracking information. If this is the Right eye's pass we don't - need to update tracking info but we do need to set the correct camera. - */ - RT_SetStereoCamera(); - } - - bool bHDRRendering = (nFlags & SHDF_ALLOWHDR) && IsHDRModeEnabled(); - //The HDR pass is in charge of doing the SRGB conversion. Since is - //disabled, we need to push a render target to do the SRGB conversion before the post process. - bool doSRGBConversionCopy = !IsHDRModeEnabled() && (m_RP.m_nRendFlags & SHDF_ALLOWHDR) && - !recursiveLevel && !m_wireframe_mode && - !FX_GetEnabledGmemPath(nullptr); - - if (!recursiveLevel && bHDRRendering) - { - m_RP.m_bUseHDR = true; - if (FX_HDRScene(m_RP.m_bUseHDR, false)) - { - m_RP.m_PersFlags2 |= RBPF2_HDR_FP16; - } - } - else - { - m_RP.m_bUseHDR = false; - FX_HDRScene(false); - - if ((pShaderThreadInfo->m_PersFlags & RBPF_DRAWTOTEXTURE) && bHDRRendering) - { - m_RP.m_PersFlags2 |= RBPF2_HDR_FP16; - } - else - { - m_RP.m_PersFlags2 &= ~RBPF2_HDR_FP16; - } - } - - if (doSRGBConversionCopy) - { - FX_PushRenderTarget(0, CTexture::s_ptexHDRTarget, &m_DepthBufferOrigMSAA, -1, true); - } - - // Prepare post processing - bool bAllowPostProcess = (nFlags & SHDF_ALLOWPOSTPROCESS) && !recursiveLevel && (CV_r_PostProcess) && !CV_r_measureoverdraw && - !(pShaderThreadInfo->m_PersFlags & (RBPF_SHADOWGEN)); - - bool bAllowSubpixelShift = bAllowPostProcess - && (gcpRendD3D->FX_GetAntialiasingType() & eAT_JITTER_MASK) - && (!gEnv->IsEditing() || CRenderer::CV_r_AntialiasingModeEditor) - && (GetWireframeMode() == R_SOLID_MODE) - && (CRenderer::CV_r_DeferredShadingDebugGBuffer == 0); - - m_TemporalJitterClipSpace = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - m_TemporalJitterMipBias = 0.0f; - if (bAllowSubpixelShift) - { - SubpixelJitter::Sample sample = SubpixelJitter::EvaluateSample(SPostEffectsUtils::m_iFrameCounter, (SubpixelJitter::Pattern)CV_r_AntialiasingTAAJitterPattern); - - m_TemporalJitterClipSpace.x = ((sample.m_subpixelOffset.x * 2.0) / (float)m_width) / m_RP.m_CurDownscaleFactor.x; - m_TemporalJitterClipSpace.y = ((sample.m_subpixelOffset.y * 2.0) / (float)m_height) / m_RP.m_CurDownscaleFactor.y; - m_TemporalJitterClipSpace.z = sample.m_subpixelOffset.x; - m_TemporalJitterClipSpace.w = sample.m_subpixelOffset.y; - - if IsCVarConstAccess(constexpr) (CV_r_AntialiasingTAAUseJitterMipBias) - { - m_TemporalJitterMipBias = sample.m_mipBias; - } - } - - FX_PostProcessScene(bAllowPostProcess); - bool bAllowDeferred = (nFlags & SHDF_ZPASS) && !recursiveLevel && !CV_r_measureoverdraw; - if (bAllowDeferred) - { - PROFILE_PS_TIME_SCOPE(fTimeDIPs[EFSLIST_DEFERRED_PREPROCESS]); - m_RP.m_PersFlags2 |= RBPF2_ALLOW_DEFERREDSHADING; - FX_DeferredRendering(false, true); - } - else - { - m_RP.m_PersFlags2 &= ~RBPF2_ALLOW_DEFERREDSHADING; - } - - { - if (!recursiveLevel && (nFlags & SHDF_ALLOWHDR)) - { - ETEX_Format eTF = (m_RP.m_bUseHDR && m_nHDRType == 1) ? eTF_R16G16B16A16F : eTF_R8G8B8A8; - int nW = gcpRendD3D->GetWidth(); //m_d3dsdBackBuffem.Width; - int nH = gcpRendD3D->GetHeight(); //m_d3dsdBackBuffem.Height; - if (!CTexture::s_ptexSceneTarget || CTexture::s_ptexSceneTarget->GetDstFormat() != eTF || CTexture::s_ptexSceneTarget->GetWidth() != nW || CTexture::s_ptexSceneTarget->GetHeight() != nH) - { - CTexture::GenerateSceneMap(eTF); - } - } - } - - if ((nFlags & SHDF_ALLOWPOSTPROCESS) && !recursiveLevel) - { - FX_DeferredRainPreprocess(); - } - - if (!(nFlags & SHDF_ZPASS_ONLY)) - { - bool bLighting = (pShaderThreadInfo->m_PersFlags & RBPF_SHADOWGEN) == 0; - if (!nFlags) - { - bLighting = false; - } - - if ((nFlags & (SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS)) && CV_r_usezpass) - { - PROFILE_PS_TIME_SCOPE(fTimeDIPsZ); - FX_ProcessZPassRenderLists(); - - FX_DeferredRainGBuffer(); - FX_DeferredSnowLayer(); - - const bool takingScreenShot = (m_screenShotType != 0); - const bool bMotionVectorsEnabled = (CRenderer::CV_r_MotionBlur > 1 || (gRenDev->FX_GetAntialiasingType() & eAT_TEMPORAL_MASK) != 0) && CRenderer::CV_r_MotionVectors && (!takingScreenShot || CRenderer::CV_r_MotionBlurScreenShot); - if (bMotionVectorsEnabled) - { - CMotionBlur* motionBlur = static_cast(PostEffectMgr()->GetEffect(ePFX_eMotionBlur)); - motionBlur->RenderObjectsVelocity(); - } - - // Restore per-batch sorting after zpass finished - if (m_bUseGPUFriendlyBatching[m_RP.m_nProcessThreadID] && CRenderer::CV_r_ZPassDepthSorting) - { - for (int i = 0; i < MAX_LIST_ORDER; ++i) - { - EF_SortRenderList(EFSLIST_GENERAL, i, m_RP.m_pRLD, m_RP.m_nProcessThreadID, false); - } - } - } - -#if defined(FEATURE_SVO_GI) - if ((gEnv->pConsole->GetCVar("e_GI")->GetIVal()) && (nFlags & SHDF_ALLOWHDR) && !recursiveLevel && CSvoRenderer::GetInstance()) - { - PROFILE_LABEL_SCOPE("SVOGI"); - CSvoRenderer::GetInstance()->Lock(); - CSvoRenderer::GetInstance()->UpdateCompute(); - CSvoRenderer::GetInstance()->UpdateRender(); - CSvoRenderer::GetInstance()->Unlock(); - } -#endif - - bool bEmpty = SRendItem::IsListEmpty(EFSLIST_GENERAL, m_RP.m_nProcessThreadID, m_RP.m_pRLD); - bEmpty &= SRendItem::IsListEmpty(EFSLIST_DEFERRED_PREPROCESS, m_RP.m_nProcessThreadID, m_RP.m_pRLD); - if (!recursiveLevel && !bEmpty && pShaderThreadInfo->m_FS.m_bEnable && CV_r_usezpass) - { - m_RP.m_PersFlags2 |= RBPF2_NOSHADERFOG; - } - - if (bAllowDeferred && !bEmpty) - { - PROFILE_LABEL_SCOPE("DEFERRED_LIGHTING"); - PROFILE_PS_TIME_SCOPE(fTimeDIPs[EFSLIST_DEFERRED_PREPROCESS]); - - FX_ProcessRenderList(EFSLIST_DEFERRED_PREPROCESS, BEFORE_WATER, RenderFunc, false); // Sorted list without preprocess of all deferred related passes and screen shaders - FX_ProcessRenderList(EFSLIST_DEFERRED_PREPROCESS, AFTER_WATER , RenderFunc, false); // Sorted list without preprocess of all deferred related passes and screen shaders - } - - if (FX_GetEnabledGmemPath(nullptr)) - { - FX_GmemTransition(eGT_POST_DEFERRED_PRE_FORWARD); - } - - if (nCurrentRecurseLvl == 0 && FurPasses::GetInstance().GetFurRenderingMode() == FurPasses::RenderMode::AlphaTested) - { - // If using alpha tested fur, perform shell prepass before forward opaque - FurPasses::GetInstance().ExecuteShellPrepass(); - } - - FX_RenderForwardOpaque(RenderFunc, bLighting, bAllowDeferred); - - FX_ProcessThicknessRenderLists(); - - const bool bDeferredScenePasses = (nFlags & SHDF_ALLOWPOSTPROCESS) && !recursiveLevel && !bEmpty; - if (bDeferredScenePasses) - { - FX_ResetPipe(); - - FX_DeferredCaustics(); - } - - const bool bShadowGenSpritePasses = (pShaderThreadInfo->m_PersFlags & (RBPF_SHADOWGEN)) != 0; - - //Include this profile segment in the summary information for the quick GPU profiling display - { - PROFILE_LABEL_SCOPE(nCurrentRecurseLvl == 0 ? "TRANSPARENT_PASSES" : "TRANSPARENT_PASSES_REC"); - - if (!FX_GetEnabledGmemPath(nullptr) && bAllowDeferred && bDeferredScenePasses) - { - // make sure all all jobs which are computing particle vertices/indices - // have finished and their vertex/index buffers are unlocked - // before starting rendering of those - m_ComputeVerticesJobExecutors[m_RP.m_nProcessThreadID].WaitForCompletion(); - UnLockParticleVideoMemory(gRenDev->m_nPoolIndexRT % SRenderPipeline::nNumParticleVertexIndexBuffer); - - - PROFILE_LABEL_SCOPE("VOLUMETRIC FOG"); - - GetVolumetricFog().RenderVolumetricsToVolume(RenderFunc); - GetVolumetricFog().RenderVolumetricFog(); - } - - if (bDeferredScenePasses && CV_r_measureoverdraw != 4) - { - FX_RenderFog(); - } - - if (nCurrentRecurseLvl == 0 && FurPasses::GetInstance().GetFurRenderingMode() == FurPasses::RenderMode::AlphaBlended) - { - // If using alpha blended fur, perform shell prepass after fog passes so that fog can influence fur shading - FurPasses::GetInstance().ExecuteShellPrepass(); - } - - { - PROFILE_LABEL_SCOPE("TRANSPARENT_BW"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_TRANSP], !bShadowGenSpritePasses); - - GetTiledShading().BindForwardShadingResources(NULL); - - FX_ProcessRenderList(EFSLIST_TRANSP, BEFORE_WATER, RenderFunc, bLighting); // Unsorted list - - // Highest quality we need to render twice for accuracy under water.\ - // So we render first, here, all the transparent fragments that are under water. - // The fragments above water that are rendered here will be discarded when we render the refractive water surface later in the pipeline. - // This has a huge cost, need optimization. - if (nFlags & SHDF_ALLOW_WATER) - { - const ICVar* renderTransparentUnderWaterCVar = iConsole->GetCVar("e_RenderTransparentUnderWater"); - int renderTransparentUnderWater = renderTransparentUnderWaterCVar ? renderTransparentUnderWaterCVar->GetIVal() : 0; - if (renderTransparentUnderWater == 1) - { - FX_ProcessRenderList(EFSLIST_TRANSP, AFTER_WATER, RenderFunc, bLighting); // Unsorted list - } - } - - GetTiledShading().UnbindForwardShadingResources(); - } - - if (nFlags & SHDF_ALLOW_WATER) - { - { - PROFILE_LABEL_SCOPE("WATER_VOLUME"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_WATER_VOLUMES], !bShadowGenSpritePasses); - FX_ProcessRenderList(EFSLIST_WATER_VOLUMES, BEFORE_WATER, RenderFunc, false); // Sorted list without preprocess - } - - FX_RenderWater(RenderFunc); - } - - { - PROFILE_LABEL_SCOPE("TRANSPARENT_AW"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_TRANSP], !bShadowGenSpritePasses); - - if (bAllowPostProcess && CV_r_TranspDepthFixup) - { - FX_DepthFixupPrepare(); - } - - GetTiledShading().BindForwardShadingResources(NULL); - - MultiLayerAlphaBlendPass::GetInstance().SetLayerCount(CD3D9Renderer::CV_r_AlphaBlendLayerCount); - MultiLayerAlphaBlendPass::GetInstance().BindResources(); - - //draw after water transparent list. exclude objects which skip depth of field (only particles enabled this option, but it - //could be applied to any transparent object later) - uint32 nBatchExcludeFilter = 0; - if (m_RP.m_bUseHDR) - { - nBatchExcludeFilter = FB_TRANSPARENT_AFTER_DOF; - } - FX_ProcessRenderList(EFSLIST_TRANSP, AFTER_WATER, RenderFunc, true, FB_GENERAL, nBatchExcludeFilter); - - MultiLayerAlphaBlendPass::GetInstance().UnBindResources(); - GetTiledShading().UnbindForwardShadingResources(); - - MultiLayerAlphaBlendPass::GetInstance().Resolve(*this); - - if (bAllowPostProcess && CV_r_TranspDepthFixup) - { - FX_DepthFixupMerge(); - } - } - - FX_ProcessHalfResParticlesRenderList(EFSLIST_HALFRES_PARTICLES, RenderFunc, bLighting); - - if (nFlags & SHDF_ALLOW_WATER) - { - PROFILE_LABEL_SCOPE("WATER_VOLUME"); - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_WATER_VOLUMES], !bShadowGenSpritePasses); - FX_ProcessRenderList(EFSLIST_WATER_VOLUMES, AFTER_WATER, RenderFunc, false); - } - - // insert fence which is used on consoles to prevent overwriting VideoMemory - InsertParticleVideoMemoryFence(gRenDev->m_nPoolIndexRT % SRenderPipeline::nNumParticleVertexIndexBuffer); - } - -#if defined(ENABLE_ART_RT_TIME_ESTIMATE) - m_RP.m_PS[m_RP.m_nProcessThreadID].m_actualRenderTimeMinusPost += iTimer->GetAsyncTime().GetDifferenceInSeconds(Time); -#endif - - PROFILE_PS_TIME_SCOPE_COND(fTimeDIPs[EFSLIST_POSTPROCESS], !bShadowGenSpritePasses); - - if (bAllowDeferred && !recursiveLevel) - { - FX_DeferredSnowDisplacement(); - } - - if (FX_GetEnabledGmemPath(nullptr)) - { - FX_GmemTransition(eGT_POST_AW_TRANS_PRE_POSTFX); - } - - if (!recursiveLevel) - { - gcpRendD3D->m_RP.m_PersFlags1 &= ~RBPF1_SKIP_AFTER_POST_PROCESS; - - FX_ProcessRenderList(EFSLIST_HDRPOSTPROCESS, BEFORE_WATER, RenderFunc, false); // Sorted list without preprocess of all fog passes and screen shaders - FX_ProcessRenderList(EFSLIST_HDRPOSTPROCESS, AFTER_WATER , RenderFunc, false); // Sorted list without preprocess of all fog passes and screen shaders - if (doSRGBConversionCopy) - { - //The HDR pass is in charge of doing the SRGB conversion but it's disabled. - FX_SRGBConversion(); - } - FX_ProcessRenderList(EFSLIST_AFTER_HDRPOSTPROCESS, BEFORE_WATER, RenderFunc, false); // for specific cases where rendering after tone mapping is needed - FX_ProcessRenderList(EFSLIST_AFTER_HDRPOSTPROCESS, AFTER_WATER , RenderFunc, false); - FX_ProcessRenderList(EFSLIST_POSTPROCESS, BEFORE_WATER, RenderFunc, false); // Sorted list without preprocess of all fog passes and screen shaders - FX_ProcessRenderList(EFSLIST_POSTPROCESS, AFTER_WATER , RenderFunc, false); // Sorted list without preprocess of all fog passes and screen shaders - -#if defined(CRY_USE_METAL) || defined(ANDROID) - // If need upscale do it here. - { - const Vec2& vDownscaleFactor = gcpRendD3D->m_RP.m_CurDownscaleFactor; - - bool bDoUpscale = (vDownscaleFactor.x < .999999f) || (vDownscaleFactor.y < .999999f); - - if (bDoUpscale) - { - PROFILE_LABEL_SCOPE("RT_UPSCALE"); - CTexture* pCurrRT = CTexture::s_ptexSceneDiffuse; - GetUtils().CopyScreenToTexture(pCurrRT); - - // copy osm-guaided viewport rect. It will be destroyed soon. - RECT rcSrcRegion = gcpRendD3D->m_FullResRect; - // Since now we render to a full RT. - gcpRendD3D->SetCurDownscaleFactor(Vec2(1, 1)); - gcpRendD3D->RT_SetViewport(0, 0, gcpRendD3D->GetWidth(), gcpRendD3D->GetHeight()); - - SD3DPostEffectsUtils::GetInstance().CopyTextureToScreen(pCurrRT, &rcSrcRegion, FILTER_BILINEAR); - } - } -#endif - bool bDrawAfterPostProcess = !(gcpRendD3D->m_RP.m_PersFlags1 & RBPF1_SKIP_AFTER_POST_PROCESS); - - RT_SetViewport(0, 0, GetWidth(), GetHeight()); - - if (bDrawAfterPostProcess) - { - PROFILE_LABEL_SCOPE("AFTER_POSTPROCESS"); // for specific cases where rendering after all post effects is needed - FX_ProcessRenderList(EFSLIST_AFTER_POSTPROCESS, BEFORE_WATER, RenderFunc, false); - FX_ProcessRenderList(EFSLIST_AFTER_POSTPROCESS, AFTER_WATER , RenderFunc, false); - } - - gcpRendD3D->m_RP.m_PersFlags2 &= ~RBPF2_NOPOSTAA; - - if IsCVarConstAccess(constexpr) (CV_r_DeferredShadingDebug && bAllowDeferred) - { - FX_DeferredRendering(true); - } - } - } - else - { - FX_ProcessRenderList(EFSLIST_GENERAL, BEFORE_WATER, RenderFunc, true); // Sorted list without preprocess - FX_ProcessRenderList(EFSLIST_DECAL, BEFORE_WATER, RenderFunc, true); // Sorted list without preprocess - FX_ProcessRenderList(EFSLIST_WATER_VOLUMES, BEFORE_WATER, RenderFunc, false); // Sorted list without preprocess - - FX_ProcessRenderList(EFSLIST_GENERAL, AFTER_WATER, RenderFunc, true); // Sorted list without preprocess - FX_ProcessRenderList(EFSLIST_DECAL, AFTER_WATER, RenderFunc, true); // Sorted list without preprocess - FX_ProcessRenderList(EFSLIST_WATER_VOLUMES, AFTER_WATER, RenderFunc, false); // Sorted list without preprocess - } - - // Readback the downsampled z-buffer to the CPU for use by the Coverage Buffer system next frame. - // This is performed at the end of the frame in order to help prevent a CPU/GPU sync point. - FX_ZTargetReadBackOnCPU(); - - FX_ApplyThreadState(m_RP.m_OldTI[recursiveLevel], NULL); - - m_RP.m_PS[m_RP.m_nProcessThreadID].m_fRenderTime += iTimer->GetAsyncTime().GetDifferenceInSeconds(Time); - - m_RP.m_nRendFlags = nSaveRendFlags; - CV_r_nodrawnear = nSaveDrawNear; - CV_r_texturesstreamingsync = nSaveStreamSync; -} - -//====================================================================================================== -// Process all render item lists (can be called recursively) -void CD3D9Renderer::EF_ProcessRenderLists(RenderFunc pRenderFunc, int nFlags, [[maybe_unused]] SViewport& VP, const SRenderingPassInfo& passInfo, bool bSync3DEngineJobs) -{ - AZ_TRACE_METHOD(); - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = passInfo.ThreadID(); - int nR = passInfo.GetRecursiveLevel(); -#ifndef _RELEASE - if (nR < 0) - { - __debugbreak(); - } -#endif - - bool bIsMultiThreadedRenderer = false; - EF_Query(EFQ_RenderMultithreaded, bIsMultiThreadedRenderer); - if (!nR) - { - if (bSync3DEngineJobs) - { - // wait for all RendItems which need preprocession - // note: the PopCompletionFence here indicates that no new jobs for preprocessing are spawned - // note: must be called before EndSpawningGeneratingRendItemJobs! in all constellations, else a race condition can uncoalesce the underlying memory - AZ::LegacyJobExecutor* pJobExecutor = gEnv->pRenderer->GetGenerateRendItemJobExecutorPreProcess(); - if (pJobExecutor->IsRunning()) - { - pJobExecutor->PopCompletionFence(); - } - pJobExecutor->WaitForCompletion(); - - // we need to prepare the render item lists here when we are using the editor(which doesn't have MT rendering) - if (!bIsMultiThreadedRenderer) - { - if (m_generateRendItemJobExecutor.IsRunning()) - { - m_generateRendItemJobExecutor.PopCompletionFence(); - } - - if (m_generateShadowRendItemJobExecutor.IsRunning()) - { - m_generateShadowRendItemJobExecutor.PopCompletionFence(); - } - - //////////////////////////////////////////////// - // wait till all SRendItems for this frame have finished preparing - m_finalizeRendItemsJobExecutor[m_RP.m_nProcessThreadID].WaitForCompletion(); - m_finalizeShadowRendItemsJobExecutor[m_RP.m_nProcessThreadID].WaitForCompletion(); - gRenDev->GetGenerateRendItemJobExecutor()->ClearPostJob(); // clear post job to prevent invoking it twice when no MT Rendering is enabled, but recursive rendering is used - } - } - - assert(nThreadID == m_RP.m_nFillThreadID); // make sure this is main thread - assert(nThreadID < RT_COMMAND_BUF_COUNT); - if ((nFlags & SHDF_ALLOWPOSTPROCESS)) - { - SRenderListDesc tmpRLD; - int nPreProcessLists[] = { EFSLIST_PREPROCESS, EFSLIST_WATER, EFSLIST_WATER_VOLUMES }; - for (int i = 0; i < 3; ++i) - { - int nList = nPreProcessLists[i]; - FinalizeRendItems_ReorderRendItemList(0, nList, nThreadID); - FinalizeRendItems_ReorderRendItemList(1, nList, nThreadID); - - // make sure the memory is continous before sorting - auto& RESTRICT_REFERENCE renderItems = CRenderView::CurrentFillView()->GetRenderItems(0, nList); - renderItems.CoalesceMemory(); - - tmpRLD.m_nStartRI[0][nList] = 0; - tmpRLD.m_nEndRI[0][nList] = renderItems.size(); - tmpRLD.m_nBatchFlags[0][nList] = passInfo.GetRenderView()->GetBatchFlags(0, 0, nList); - EF_SortRenderList(nList, 0, &tmpRLD, nThreadID, (CRenderer::CV_r_ZPassDepthSorting != 0)); - } - - int nums = tmpRLD.m_nStartRI[0][EFSLIST_PREPROCESS]; - int nume = tmpRLD.m_nEndRI[0][EFSLIST_PREPROCESS]; - - // Perform pre-process operations for the current frame - auto& RESTRICT_REFERENCE postProcessRenderItems = CRenderView::CurrentFillView()->GetRenderItems(0, EFSLIST_PREPROCESS); - - if (nume - nums > 0 && postProcessRenderItems[nums].nBatchFlags & FSPR_MASK) - { - nums += EF_Preprocess(&postProcessRenderItems[0], nums, nume, pRenderFunc, passInfo); - } - } - } - - // since we need to sync earlier if we don't have multithreaded rendering - // we need to finalize the rend items again in a possible recursive pass - if (!bIsMultiThreadedRenderer && nR) - { - m_generateRendItemJobExecutor.WaitForCompletion(); - m_finalizeRendItemsJobExecutor[nThreadID].PushCompletionFence(); - CRenderer::FinalizeRendItems(nThreadID); - } - m_pRT->RC_RenderScene(nFlags, pRenderFunc); -} - -void CD3D9Renderer::EF_RenderScene(int nFlags, SViewport& VP, const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - int nThreadID = passInfo.ThreadID(); - - CTimeValue time0 = iTimer->GetAsyncTime(); -#ifndef _RELEASE - int nRecurseLevel = passInfo.GetRecursiveLevel(); - if (nRecurseLevel < 0) - { - __debugbreak(); - } - if (CV_r_excludeshader->GetString()[0] != '0') - { - char nm[256]; - azstrcpy(nm, AZ_ARRAY_SIZE(nm), CV_r_excludeshader->GetString()); - azstrlwr(nm, AZ_ARRAY_SIZE(nm)); - m_RP.m_sExcludeShader = nm; - } - else -#endif - m_RP.m_sExcludeShader = ""; - - if (nFlags & SHDF_ALLOWPOSTPROCESS && gRenDev->m_CurRenderEye == 0) - { - EF_AddClientPolys(passInfo); - } - - EF_ProcessRenderLists(FX_FlushShader_General, nFlags, VP, passInfo, true); - - EF_DrawDebugTools(VP, passInfo); - - m_RP.m_PS[nThreadID].m_fSceneTimeMT += iTimer->GetAsyncTime().GetDifferenceInSeconds(time0); -} - - -// Process all render item lists -void CD3D9Renderer::EF_EndEf3D(const int nFlags, const int nPrecacheUpdateIdSlow, const int nPrecacheUpdateIdFast, const SRenderingPassInfo& passInfo) -{ - AZ_TRACE_METHOD(); - ASSERT_IS_MAIN_THREAD(m_pRT) - int nThreadID = m_RP.m_nFillThreadID; - - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nRecurseLevel >= 0); - if (nRecurseLevel < 0) - { - iLog->Log("Error: CRenderer::EF_EndEf3D without CRenderer::EF_StartEf"); - return; - } - - m_RP.m_TI[m_RP.m_nFillThreadID].m_arrZonesRoundId[0] = max(m_RP.m_TI[m_RP.m_nFillThreadID].m_arrZonesRoundId[0], nPrecacheUpdateIdFast); - m_RP.m_TI[m_RP.m_nFillThreadID].m_arrZonesRoundId[1] = max(m_RP.m_TI[m_RP.m_nFillThreadID].m_arrZonesRoundId[1], nPrecacheUpdateIdSlow); - - m_p3DEngineCommon.Update(nThreadID); - - if IsCVarConstAccess(constexpr) (CV_r_nodrawshaders == 1) - { - EF_ClearTargetsLater(FRT_CLEAR, Clr_Transparent); - if (SRendItem::m_RecurseLevel[nThreadID] == 0) - { - - if(m_generateRendItemPreProcessJobExecutor.IsRunning()) - { - m_generateRendItemPreProcessJobExecutor.PopCompletionFence(); - } - - bool bIsMultiThreadedRenderer = false; - gEnv->pRenderer->EF_Query(EFQ_RenderMultithreaded, bIsMultiThreadedRenderer); - // Because of EndSpawningGeneratingRendItemJobs we need to skip this one while in multi-threaded renderer. - if (!bIsMultiThreadedRenderer && m_generateRendItemJobExecutor.IsRunning()) - { - m_generateRendItemJobExecutor.PopCompletionFence(); - } - - // The m_generateShadowRendItemJobExecutor was started in EF_PrepareShadowGenRenderList, need to end it. - if (m_generateShadowRendItemJobExecutor.IsRunning()) - { - m_generateShadowRendItemJobExecutor.PopCompletionFence(); - } - } - SRendItem::m_RecurseLevel[nThreadID]--; - return; - } - - int nAsyncShaders = CV_r_shadersasynccompiling; - if (nFlags & SHDF_NOASYNC) - { - AZ_Assert(gRenDev->m_pRT->IsRenderThread(), "EF_EndEf3D: SHDF_NOASYNC may only be used with r_multithreading disabled. This is because the render thread modifies r_shadersasynccompiling and can lead to race conditions."); - CV_r_shadersasynccompiling = 0; - } - - if (SRendItem::m_RecurseLevel[nThreadID] == 0 && !(nFlags & (SHDF_ZPASS_ONLY | SHDF_NO_SHADOWGEN))) //|SHDF_ALLOWPOSTPROCESS - { - PrepareShadowGenForFrustumNonJobs(nFlags); - } - - if (GetS3DRend().IsStereoEnabled()) - { - GetS3DRend().ProcessScene(nFlags, passInfo); - } - else - { - EF_Scene3D(m_MainRTViewport, nFlags, passInfo); - } - - //deferredDecals.SetUse(0); - bool bIsMultiThreadedRenderer = false; - EF_Query(EFQ_RenderMultithreaded, bIsMultiThreadedRenderer); - if (bIsMultiThreadedRenderer && SRendItem::m_RecurseLevel[nThreadID] == 0 && !(nFlags & (SHDF_ZPASS_ONLY | SHDF_NO_SHADOWGEN))) //|SHDF_ALLOWPOSTPROCESS - { - m_generateShadowRendItemJobExecutor.PopCompletionFence(); - } - - SRendItem::m_RecurseLevel[nThreadID]--; - - // Do not restore this variable unless this condition is valid, otherwise it can cause a race condition. - // This variable is accessed and modified from both the render and main thread, so it is only valid to touch this variable on this thread when r_multithreaded=0 - if (nFlags & SHDF_NOASYNC) - { - CV_r_shadersasynccompiling = nAsyncShaders; - } -} - -void CD3D9Renderer::EF_InvokeShadowMapRenderJobs([[maybe_unused]] const int nFlags) -{ - int nThreadID = m_RP.m_nFillThreadID; - if (SRendItem::m_RecurseLevel[nThreadID] == 0) - { - EF_PrepareShadowGenRenderList(); - } -} - -void CD3D9Renderer::EF_Scene3D(SViewport& VP, int nFlags, const SRenderingPassInfo& passInfo) -{ - ASSERT_IS_MAIN_THREAD(m_pRT) - AZ_TRACE_METHOD(); - int nThreadID = m_RP.m_nFillThreadID; - assert(nThreadID >= 0 && nThreadID < RT_COMMAND_BUF_COUNT); - - int recursiveLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(recursiveLevel >= 0 && recursiveLevel < MAX_REND_RECURSION_LEVELS); - - if (!recursiveLevel && m_pStereoRenderer->GetStatus() != IStereoRenderer::Status::kRenderingSecondEye && !CV_r_measureoverdraw) - { - bool bAllowDeferred = (nFlags & SHDF_ZPASS) != 0; - if (bAllowDeferred) - { - gRenDev->m_cEF.mfRefreshSystemShader("DeferredShading", CShaderMan::s_shDeferredShading); - - SShaderItem shItem(CShaderMan::s_shDeferredShading); - CRenderObject* pObj = EF_GetObject_Temp(passInfo.ThreadID()); - if (pObj) - { - pObj->m_II.m_Matrix.SetIdentity(); - EF_AddEf(m_RP.m_pREDeferredShading, shItem, pObj, passInfo, EFSLIST_DEFERRED_PREPROCESS, 0, SRendItemSorter::CreateDeferredPreProcessRendItemSorter(passInfo, SRendItemSorter::eDeferredShadingPass)); - } - } - - if ((nFlags & SHDF_ALLOWHDR) && IsHDRModeEnabled()) - { - SShaderItem shItem(CShaderMan::s_shHDRPostProcess); - CRenderObject* pObj = EF_GetObject_Temp(passInfo.ThreadID()); - if (pObj) - { - pObj->m_II.m_Matrix.SetIdentity(); - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - EF_AddEf(m_RP.m_pREHDR, shItem, pObj, passInfo, EFSLIST_HDRPOSTPROCESS, 0, rendItemSorter); - } - } - - bool bAllowPostProcess = (nFlags & SHDF_ALLOWPOSTPROCESS) && (CV_r_PostProcess); - bAllowPostProcess &= (m_RP.m_TI[nThreadID].m_PersFlags & RBPF_MIRRORCULL) == 0; - if (bAllowPostProcess) - { - SShaderItem shItem(CShaderMan::s_shPostEffects); - CRenderObject* pObj = EF_GetObject_Temp(passInfo.ThreadID()); - if (pObj) - { - pObj->m_II.m_Matrix.SetIdentity(); - SRendItemSorter rendItemSorter = SRendItemSorter::CreateRendItemSorter(passInfo); - EF_AddEf(m_RP.m_pREPostProcess, shItem, pObj, passInfo, EFSLIST_POSTPROCESS, 0, rendItemSorter); - } - } - } - - // Update per-frame params - UpdatePerFrameParameters(); - - EF_RenderScene(nFlags, VP, passInfo); - - //Re-apply stereo camera here just so that all rendering is done based off of the correct camera instead of - //whatever the camera is currently set to - if (gcpRendD3D->GetIStereoRenderer()->IsRenderingToHMD()) - { - gcpRendD3D->RT_SetStereoCamera(); - } - - if (!passInfo.IsRecursivePass()) - { - //Draw these Debug systems as part of the scene so that they render properly in VR - -#ifdef ENABLE_RENDER_AUX_GEOM -#ifndef _RELEASE - - //Draws all aux geometry - GetIRenderAuxGeom()->Flush(); - - //Actually flushes and clears out aux geometry buffers - //We need to do this so that geometry is re-processed for VR. - //This is because the aux geometry buffers overwrite themselves - //as they draw. By clearing them out it means we can just re-process - //that geometry for the 2nd eye and not draw a mangled vertex buffer. - GetIRenderAuxGeom()->Process(); -#endif //_RELEASE -#endif //ENABLE_RENDER_AUX_GEOM - - //Only render the UI Canvas and the Console on the main window - //If we're not in the editor, don't bother to check viewport - if (!gEnv->IsEditor() || m_CurrContext->m_bMainViewport) - { - EBUS_EVENT(AZ::RenderNotificationsBus, OnScene3DEnd); - } - - // For VR rendering, RenderTextMessages need to be called in EF_Scene3D to render into both eyes, - // Some 2D rendering calls such as console rendering were moved from CSystem::RenderEnd or EndFrame into EF_Scene3D to work with it. - // In this case we have to RenderTextMessage immediately instead of push RenderTextMessage to render thread. - // EF_RenderTextMessages will render text messages into actual draw2d commands. - // For the remaining 2D renderings that are still called at the end of frame(such as C3DEngine::DisplayInfo in CSystem::RenderEnd), - // they are called after the TextMessage have already been rendered, so they will be eventually rendered 2 frames later. - // This is not an ideal situation and we should find a better way to handle it later. - EF_RenderTextMessages(); - } -} - -void CD3D9Renderer::RT_PrepareStereo(int mode, int output) -{ - m_pStereoRenderer->PrepareStereo((EStereoMode)mode, (EStereoOutput)output); -} - -void CD3D9Renderer::RT_CopyToStereoTex(int channel) -{ - m_pStereoRenderer->CopyToStereo(channel); -} - -void CD3D9Renderer::RT_UpdateTrackingStates() -{ - if (m_pStereoRenderer->IsRenderingToHMD()) - { - // Only allow tracking info to update once per frame - // Do not allow recursion "frame" ID otherwise we will update tracking for both the water reflection pass as well as the main scene pass - static int lastFrameId = 0; - int frameId = GetFrameID(false); - if (lastFrameId != frameId) - { - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, UpdateTrackingStates); - lastFrameId = frameId; - } - } -} - -void CD3D9Renderer::RT_DisplayStereo() -{ - m_pStereoRenderer->DisplayStereo(); -} - -void CD3D9Renderer::EnablePipelineProfiler([[maybe_unused]] bool bEnable) -{ -#if defined(ENABLE_PROFILING_GPU_TIMERS) - if (m_pPipelineProfiler) - { - m_pPipelineProfiler->SetEnabled(bEnable); - } -#endif -} - -//======================================================================================================== diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline_Jobs.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline_Jobs.cpp deleted file mode 100644 index 403335b021..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRendPipeline_Jobs.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include -#include -#include - -#include "../Common/PostProcess/PostProcessUtils.h" -#include "D3DPostProcess.h" -#include "D3DStereo.h" -#include "D3DHWShader.h" - -#include "Common/RenderView.h" - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::RegisterFinalizeShadowJobs(int nThreadID) -{ - // Init post job - // legacy job priority: JobManager::eLowPriority - m_generateShadowRendItemJobExecutor.SetPostJob( - m_finalizeShadowRendItemsJobExecutor[nThreadID], - [this, nThreadID] - { - this->FinalizeShadowRendItems(nThreadID); - } - ); - m_generateShadowRendItemJobExecutor.PushCompletionFence(); - - m_finalizeShadowRendItemsJobExecutor[nThreadID].PushCompletionFence(); -} - -/////////////////////////////////////////////////////////////////////////////// -// sort SRendItem lists -void CD3D9Renderer::EF_SortRenderList(int nList, int nAW, SRenderListDesc* pRLD, int nThread, bool bUseDist) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - int nStart = pRLD->m_nStartRI[nAW][nList]; - int nEnd = pRLD->m_nEndRI[nAW][nList]; - int n = nEnd - nStart; - - if (!n) - { - return; - } - - auto& renderItems = CRenderView::GetRenderViewForThread(nThread)->GetRenderItems(nAW, nList); - switch (nList) - { - case EFSLIST_PREPROCESS: - { - PROFILE_FRAME(State_SortingPre); - SRendItem::mfSortPreprocess(&renderItems[nStart], n); - } - break; - - case EFSLIST_DEFERRED_PREPROCESS: - case EFSLIST_HDRPOSTPROCESS: - case EFSLIST_POSTPROCESS: - case EFSLIST_FOG_VOLUME: - break; - - case EFSLIST_WATER_VOLUMES: - case EFSLIST_REFRACTIVE_SURFACE: - case EFSLIST_TRANSP: - case EFSLIST_WATER: - case EFSLIST_HALFRES_PARTICLES: - case EFSLIST_LENSOPTICS: - case EFSLIST_EYE_OVERLAY: - { - PROFILE_FRAME(State_SortingDist); - SRendItem::mfSortByDist(&renderItems[nStart], n, false); - } - break; - case EFSLIST_DECAL: - { - PROFILE_FRAME(State_SortingDecals); - SRendItem::mfSortByDist(&renderItems[nStart], n, true); - } - break; - - case EFSLIST_GENERAL: - case EFSLIST_SKIN: - { - if (bUseDist && m_bUseGPUFriendlyBatching[nThread]) - { - PROFILE_FRAME(State_SortingZPass); - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_ZPassDepthSorting == 1) - { - SRendItem::mfSortForZPass(&renderItems[nStart], n); - } - else if IsCVarConstAccess(constexpr) (CRenderer::CV_r_ZPassDepthSorting == 2) - { - SRendItem::mfSortByDist(&renderItems[nStart], n, false, true); - } - } - else - { - PROFILE_FRAME(State_SortingLight); - SRendItem::mfSortByLight(&renderItems[nStart], n, true, false, false); - } - } - break; - - case EFSLIST_AFTER_POSTPROCESS: - case EFSLIST_AFTER_HDRPOSTPROCESS: - { - PROFILE_FRAME(State_SortingLight); - SRendItem::mfSortByLight(&renderItems[nStart], n, true, false, nList == EFSLIST_DECAL); - } - break; - case EFSLIST_GPU_PARTICLE_CUBEMAP_COLLISION: - break; - - default: - AZ_Assert(0, "Not handled"); - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::EF_SortRenderLists(SRenderListDesc* pRLD, int nThreadID, bool bUseDist, bool bUseJobSystem) -{ - PROFILE_FRAME(Sort_Lists); - - int i, j; - for (j = 0; j < MAX_LIST_ORDER; j++) - { - for (i = 1; i < EFSLIST_NUM; i++) - { - // EFSLIST_SHADOW_GEN is handled in Shadow Pass - // EFSLIST_PREPROCESS, EFSLIST_WATER, EFSLIST_WATER_VOLUMES are handled in EF_ProcessRenderLists - if (i == EFSLIST_SHADOW_GEN || i == EFSLIST_PREPROCESS || i == EFSLIST_WATER || i == EFSLIST_WATER_VOLUMES) - { - continue; - } - if (bUseJobSystem) - { - int nStart = pRLD->m_nStartRI[j][i]; - int nEnd = pRLD->m_nEndRI[j][i]; - - if ((nEnd - nStart) > 0) - { - // legacy job priority: JobManager::eHighPriority - m_finalizeRendItemsJobExecutor[nThreadID].StartJob( - [this, i, j, pRLD, nThreadID, bUseDist] - { - this->EF_SortRenderList(i, j, pRLD, nThreadID, bUseDist); - } - ); - } - } - else - { - EF_SortRenderList(i, j, pRLD, nThreadID, bUseDist); - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::BeginSpawningGeneratingRendItemJobs(int nThreadID) -{ - AZ_TRACE_METHOD(); - - // Register post job - // legacy job priority: JobManager::eHighPriority - m_generateRendItemJobExecutor.SetPostJob( - m_finalizeRendItemsJobExecutor[nThreadID], - [this, nThreadID] - { - this->FinalizeRendItems(nThreadID); - } - ); - - // Push completion fences accross all groups to prevent false (race-condition) reports of "completion" before all jobs are started. These are then popped after we are done starting jobs. - // there will be decreased again after the main thread has passed all job creating parts - m_generateRendItemPreProcessJobExecutor.PushCompletionFence(); - m_generateRendItemJobExecutor.PushCompletionFence(); - m_finalizeRendItemsJobExecutor[nThreadID].PushCompletionFence(); -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::BeginSpawningShadowGeneratingRendItemJobs(int nThreadID) -{ - RegisterFinalizeShadowJobs(nThreadID); -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::EndSpawningGeneratingRendItemJobs() -{ - m_generateRendItemJobExecutor.PopCompletionFence(); -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeRendItems(int nThreadID) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - FinalizeRendItems_ReorderRendItems(nThreadID); - FinalizeRendItems_SortRenderLists(nThreadID); - - m_finalizeRendItemsJobExecutor[nThreadID].PopCompletionFence(); -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeShadowRendItems(int nThreadID) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - FinalizeRendItems_ReorderShadowRendItems(nThreadID); - FinalizeRendItems_FindShadowFrustums(nThreadID); - - m_finalizeShadowRendItemsJobExecutor[nThreadID].PopCompletionFence(); -} - - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeRendItems_ReorderRendItems(int nThreadID) -{ - //////////////////////////////////////////////// - // reoder item lists by their recursive pass - for (int j = 0; j < MAX_LIST_ORDER; j++) - { - for (int i = 0; i < EFSLIST_NUM; i++) - { - // shadows don't need sorting, and PREPROCESS is sorted in mainthread - if (i == EFSLIST_SHADOW_GEN || i == EFSLIST_PREPROCESS || i == EFSLIST_WATER || i == EFSLIST_WATER_VOLUMES) - { - continue; - } - - FinalizeRendItems_ReorderRendItemList(j, i, nThreadID); - } - } -} - -void CRenderer::FinalizeRendItems_ReorderRendItemList(int nAW, int nList, int nThreadID) -{ - CRenderView* pRenderView = gRenDev->GetRenderViewForThread(nThreadID); - SRenderListDesc* __restrict pGeneralPassRLD = &pRenderView->m_RenderListDesc[0]; - SRenderListDesc* __restrict pRecursivePassRLD = &pRenderView->m_RenderListDesc[1]; - - auto& rRendItems = pRenderView->GetRenderItems(nAW, nList); - - size_t nRendItemsSize = rRendItems.size(); - if (nRendItemsSize) - { - std::sort(&rRendItems[0], &rRendItems[0] + nRendItemsSize, SCompareByOnlyStableFlagsOctreeID()); - } - - pGeneralPassRLD->m_nStartRI[nAW][nList] = 0; - pGeneralPassRLD->m_nEndRI[nAW][nList] = 0; - pRecursivePassRLD->m_nStartRI[nAW][nList] = 0; - pRecursivePassRLD->m_nEndRI[nAW][nList] = 0; - - for (size_t i = 0; i < nRendItemsSize; ++i) - { - if (rRendItems[i].rendItemSorter.IsRecursivePass()) - { - pGeneralPassRLD->m_nEndRI[nAW][nList] = i; - pRecursivePassRLD->m_nStartRI[nAW][nList] = i; - break; - } - } - - if (pRecursivePassRLD->m_nStartRI[nAW][nList]) - { - pRecursivePassRLD->m_nEndRI[nAW][nList] = nRendItemsSize; - } - else - { - pGeneralPassRLD->m_nEndRI[nAW][nList] = nRendItemsSize; - } - pGeneralPassRLD->m_nBatchFlags[nAW][nList] = pRenderView->GetBatchFlags(0, nAW, nList); - pRecursivePassRLD->m_nBatchFlags[nAW][nList] = pRenderView->GetBatchFlags(1, nAW, nList); - - AZ_Assert(pGeneralPassRLD->m_nEndRI[nAW][nList] - pGeneralPassRLD->m_nStartRI[nAW][nList] >= 0, "EndRI has to be bigger than StartRI"); - AZ_Assert(pRecursivePassRLD->m_nEndRI[nAW][nList] - pRecursivePassRLD->m_nStartRI[nAW][nList] >= 0, "EndRI has to be bigger than StartRI"); -} - -/////////////////////////////////////////////////////////////////////////////// -void CRenderer::FinalizeRendItems_SortRenderLists(int nThreadID) -{ - //////////////////////////////////////////////// - // do the actual sorting - CRenderView* pRenderView = m_RP.m_pRenderViews[nThreadID].get(); - for (int k = 0; k < 2; k++) - { - SRenderListDesc* pCurRLD = &pRenderView->m_RenderListDesc[k]; - static_cast(this)->EF_SortRenderLists(pCurRLD, nThreadID, (CRenderer::CV_r_ZPassDepthSorting != 0), true); - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::InvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - for (int i = 0; i < pCurFrustum->m_jobExecutedCastersList.Count(); ++i) - { - IShadowCaster* pEnt = pCurFrustum->m_jobExecutedCastersList[i]; - - //TOFIX reactivate OmniDirectionalShadow - if (pCurFrustum->bOmniDirectionalShadow) - { - AABB aabb; - pEnt->FillBBox(aabb); - //!!! Reactivate proper camera - bool bVis = passInfo.GetCamera().IsAABBVisible_F(aabb); - if (!bVis) - { - continue; - } - } - - if ((pCurFrustum->m_Flags & DLF_DIFFUSEOCCLUSION) && pEnt->HasOcclusionmap(0, pCurFrustum->pLightOwner)) - { - continue; - } - - // all not yet to jobs ported types need to be processed by mainthread - gEnv->p3DEngine->RenderRenderNode_ShadowPass(pEnt, passInfo, gRenDev->GetGenerateShadowRendItemJobExecutor()); - } -} - -/////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::StartInvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo) -{ - // legacy job priority: JobManager::eLowPriority - gRenDev->GetGenerateShadowRendItemJobExecutor()->StartJob( - [this, pCurFrustum, passInfo] - { - this->InvokeShadowMapRenderJobs(pCurFrustum, passInfo); - } - ); -} - -/////////////////////////////////////////////////////////////////////////////// -void CD3D9Renderer::WaitForParticleBuffer(threadID nThreadId) -{ - FUNCTION_PROFILER_LEGACYONLY(gEnv->pSystem, PROFILE_PARTICLE) - AZ_TRACE_METHOD(); - SRenderPipeline& rp = gRenDev->m_RP; - - if (rp.m_pParticleVertexBuffer[nThreadId]) - { - rp.m_pParticleVertexBuffer[nThreadId]->WaitForFence(); - } - if (rp.m_pParticleIndexBuffer[nThreadId]) - { - rp.m_pParticleIndexBuffer[nThreadId]->WaitForFence(); - } -} -/////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.cpp deleted file mode 100644 index 73b6127021..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.cpp +++ /dev/null @@ -1,1909 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "D3DRenderAuxGeom.h" -#include - -#if defined(ENABLE_RENDER_AUX_GEOM) - -const float c_clipThres(0.1f); - -enum EAuxGeomBufferSizes -{ - e_auxGeomVBSize = 0xffff, - e_auxGeomIBSize = e_auxGeomVBSize * 2 * 3 -}; - - - -struct SAuxObjVertex -{ - SAuxObjVertex() - { - } - - SAuxObjVertex(const Vec3& pos, const Vec3& normal) - : m_pos(pos) - , m_normal(normal) - { - } - - Vec3 m_pos; - Vec3 m_normal; -}; - - -typedef std::vector< SAuxObjVertex > AuxObjVertexBuffer; -typedef std::vector< uint16 > AuxObjIndexBuffer; - - -CRenderAuxGeomD3D::CRenderAuxGeomD3D(CD3D9Renderer& renderer) - : m_renderer(renderer) - , m_pAuxGeomVB(0) - , m_pAuxGeomIB(0) - , m_pCurVB(0) - , m_pCurIB(0) - , m_auxGeomSBM() - , m_wndXRes(0) - , m_wndYRes(0) - , m_aspect(1.0f) - , m_aspectInv(1.0f) - , m_matrices() - , m_curPrimType(CAuxGeomCB::e_PrimTypeInvalid) - , m_curPointSize(1) - , m_curTransMatrixIdx(-1) - , m_pAuxGeomShader(0) - , m_curDrawInFrontMode(e_DrawInFrontOff) - , m_auxSortedPushBuffer() - , m_pCurCBRawData(0) - , m_auxGeomCBCol() - , CV_r_auxGeom(1) -{ - REGISTER_CVAR2("r_auxGeom", &CV_r_auxGeom, 1, VF_NULL, ""); -} - - -CRenderAuxGeomD3D::~CRenderAuxGeomD3D() -{ - //SAFE_RELEASE(m_pAuxGeomShader); - // m_pAuxGeomShader released by CShaderMan ??? - //delete m_pAuxGeomShader; - //m_pAuxGeomShader = 0; -} - - -void CRenderAuxGeomD3D::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject((char*)this - 16, sizeof(*this) + 16); // adjust for new operator - pSizer->AddObject(m_auxSortedPushBuffer); - pSizer->AddObject(m_auxGeomCBCol); -} - - -void CRenderAuxGeomD3D::ReleaseDeviceObjects() -{ - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pAuxGeomVB); - m_pAuxGeomVB = nullptr; - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pAuxGeomIB); - m_pAuxGeomIB = nullptr; - - for (uint32 i(0); i < e_auxObjNumLOD; ++i) - { - m_sphereObj[ i ].Release(); - m_diskObj[ i ].Release(); - m_quadObj[ i ].Release(); - m_coneObj[ i ].Release(); - m_cylinderObj[ i ].Release(); - } -} - -int CRenderAuxGeomD3D::GetDeviceDataSize() -{ - int nSize = 0; - - nSize += _VertBufferSize(m_pAuxGeomVB); - nSize += _IndexBufferSize(m_pAuxGeomIB); - - for (uint32 i = 0; i < e_auxObjNumLOD; ++i) - { - nSize += m_sphereObj[i].GetDeviceDataSize(); - nSize += m_diskObj[i].GetDeviceDataSize(); - nSize += m_quadObj[i].GetDeviceDataSize(); - nSize += m_coneObj[i].GetDeviceDataSize(); - nSize += m_cylinderObj[i].GetDeviceDataSize(); - } - return nSize; -} - - -// function to generate a sphere mesh -static void CreateSphere(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib, float radius, unsigned int rings, unsigned int sections) -{ - // calc required number of vertices/indices/triangles to build a sphere for the given parameters - uint32 numVertices((rings - 1) * (sections + 1) + 2); - uint32 numTriangles((rings - 2) * sections * 2 + 2 * sections); - uint32 numIndices(numTriangles * 3); - - // setup buffers - vb.clear(); - vb.reserve(numVertices); - - ib.clear(); - ib.reserve(numIndices); - - // 1st pole vertex - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.0f, radius), Vec3(0.0f, 0.0f, 1.0f))); - - // calculate "inner" vertices - float sectionSlice(DEG2RAD(360.0f / (float) sections)); - float ringSlice(DEG2RAD(180.0f / (float) rings)); - - for (uint32 a(1); a < rings; ++a) - { - float w(sinf(a * ringSlice)); - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice) * w; - v.y = radius * sinf(i * sectionSlice) * w; - v.z = radius * cosf(a * ringSlice); - vb.push_back(SAuxObjVertex(v, v.GetNormalized())); - } - } - - // 2nd vertex of pole (for end cap) - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.0f, -radius), Vec3(0.0f, 0.0f, 1.0f))); - - // build "inner" faces - for (uint32 a(0); a < rings - 2; ++a) - { - for (uint32 i(0); i < sections; ++i) - { - ib.push_back((uint16) (1 + a * (sections + 1) + i + 1)); - ib.push_back((uint16) (1 + a * (sections + 1) + i)); - ib.push_back((uint16) (1 + (a + 1) * (sections + 1) + i + 1)); - - ib.push_back((uint16) (1 + (a + 1) * (sections + 1) + i)); - ib.push_back((uint16) (1 + (a + 1) * (sections + 1) + i + 1)); - ib.push_back((uint16) (1 + a * (sections + 1) + i)); - } - } - - // build faces for end caps (to connect "inner" vertices with poles) - for (uint32 i(0); i < sections; ++i) - { - ib.push_back((uint16) (1 + (0) * (sections + 1) + i)); - ib.push_back((uint16) (1 + (0) * (sections + 1) + i + 1)); - ib.push_back((uint16) 0); - } - - for (uint32 i(0); i < sections; ++i) - { - ib.push_back((uint16) (1 + (rings - 2) * (sections + 1) + i + 1)); - ib.push_back((uint16) (1 + (rings - 2) * (sections + 1) + i)); - ib.push_back((uint16) ((rings - 1) * (sections + 1) + 1)); - } -} - -// function to generate a disk mesh -static void CreateDisk(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib, float radius, unsigned int sections) -{ - // calc required number of vertices/indices/triangles to build a disk for the given parameters - uint32 numVertices = (sections + 1) * 2; - uint32 numTriangles = sections * 2; - uint32 numIndices = numTriangles * 3; - - // setup buffers - vb.clear(); - vb.reserve(numVertices); - - ib.clear(); - ib.reserve(numIndices); - - Vec3 yUp = Vec3(0.0f, 1.0f, 0.0f); - Vec3 yDown = Vec3(0.0f, -1.0f, 0.0f); - - // center vertex - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.0f, 0.0f), yUp)); - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.0f, 0.0f), yDown)); - - // create circle around it - float sectionSlice(DEG2RAD(360.0f / (float)sections)); - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = 0.0f; - v.z = radius * sinf(i * sectionSlice); - vb.push_back(SAuxObjVertex(v, yUp)); - vb.push_back(SAuxObjVertex(v, yDown)); - } - - // build faces - for (uint16 i = 0; i < numTriangles; i += 2) - { - // top face - ib.push_back(0); - ib.push_back(2 + i + 2); - ib.push_back(2 + i); - - // bottom face - ib.push_back(1); - ib.push_back(3 + i); - ib.push_back(3 + i + 2); - } -} - -// function to generate a quad mesh on the x z plane -static void CreateQuad(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib, float width, float height) -{ - // Calc required number of vertices/indices/triangles to build a quad for the given parameters - uint32 numVertices = 4 * 2; // 4 corners * 2 sides - uint32 numTriangles = 2 * 2; // 2 triangles * 2 sides - uint32 numIndices = numTriangles * 3; - - float halfWidth = width * 0.5f; - float halfHeight = height * 0.5f; - - // setup buffers - vb.clear(); - vb.reserve(numVertices); - - ib.clear(); - ib.reserve(numIndices); - - Vec3 yUp = Vec3(0.0f, 1.0f, 0.0f); - Vec3 yDown = Vec3(0.0f, -1.0f, 0.0f); - - // top faces - vb.push_back(SAuxObjVertex(Vec3(-halfWidth, 0.0f, halfHeight), yUp)); - vb.push_back(SAuxObjVertex(Vec3( halfWidth, 0.0f, halfHeight), yUp)); - vb.push_back(SAuxObjVertex(Vec3(-halfWidth, 0.0f, -halfHeight), yUp)); - vb.push_back(SAuxObjVertex(Vec3( halfWidth, 0.0f, -halfHeight), yUp)); - - ib.insert(ib.end(), {1, 2, 0, 3, 2, 1}); - - // bottom faces - vb.push_back(SAuxObjVertex(Vec3(-halfWidth, 0.0f, halfHeight), yDown)); - vb.push_back(SAuxObjVertex(Vec3( halfWidth, 0.0f, halfHeight), yDown)); - vb.push_back(SAuxObjVertex(Vec3(-halfWidth, 0.0f, -halfHeight), yDown)); - vb.push_back(SAuxObjVertex(Vec3( halfWidth, 0.0f, -halfHeight), yDown)); - - ib.insert(ib.end(), { 4, 6, 5, 5, 6, 7 }); -} - -// function to generate a cone mesh -static void CreateCone(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib, float radius, float height, unsigned int sections) -{ - // calc required number of vertices/indices/triangles to build a cone for the given parameters - uint32 numVertices(2 * (sections + 1) + 2); - uint32 numTriangles(2 * sections); - uint32 numIndices(numTriangles * 3); - - // setup buffers - vb.clear(); - vb.reserve(numVertices); - - ib.clear(); - ib.reserve(numIndices); - - // center vertex - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, -1.0f, 0.0f))); - - // create circle around it - float sectionSlice(DEG2RAD(360.0f / (float) sections)); - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = 0.0f; - v.z = radius * sinf(i * sectionSlice); - vb.push_back(SAuxObjVertex(v, Vec3(0.0f, -1.0f, 0.0f))); - } - - // build faces for end cap - for (uint16 i(0); i < sections; ++i) - { - ib.push_back(0); - ib.push_back(1 + i); - ib.push_back(1 + i + 1); - } - - // top - vb.push_back(SAuxObjVertex(Vec3(0.0f, height, 0.0f), Vec3(0.0f, 1.0f, 0.0f))); - - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = 0.0f; - v.z = radius * sinf(i * sectionSlice); - - Vec3 v1; - v1.x = radius * cosf(i * sectionSlice + 0.01f); - v1.y = 0.0f; - v1.z = radius * sinf(i * sectionSlice + 0.01f); - - Vec3 d(v1 - v); - Vec3 d1(Vec3(0.0, height, 0.0f) - v); - - Vec3 n((d1.Cross(d)).normalized()); - vb.push_back(SAuxObjVertex(v, n)); - } - - // build faces - for (uint16 i(0); i < sections; ++i) - { - ib.push_back(sections + 2); - ib.push_back(sections + 3 + i + 1); - ib.push_back(sections + 3 + i); - } -} - - -// function to generate a cylinder mesh -static void CreateCylinder(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib, float radius, float height, unsigned int sections) -{ - // calc required number of vertices/indices/triangles to build a cylinder for the given parameters - uint32 numVertices(4 * (sections + 1) + 2); - uint32 numTriangles(4 * sections); - uint32 numIndices(numTriangles * 3); - - // setup buffers - vb.clear(); - vb.reserve(numVertices); - - ib.clear(); - ib.reserve(numIndices); - - float sectionSlice(DEG2RAD(360.0f / (float) sections)); - - // bottom cap - { - // center bottom vertex - vb.push_back(SAuxObjVertex(Vec3(0.0f, -0.5f * height, 0.0f), Vec3(0.0f, -1.0f, 0.0f))); - - // create circle around it - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = -0.5f * height; - v.z = radius * sinf(i * sectionSlice); - vb.push_back(SAuxObjVertex(v, Vec3(0.0f, -1.0f, 0.0f))); - } - - // build faces - for (uint16 i(0); i < sections; ++i) - { - ib.push_back(0); - ib.push_back(1 + i); - ib.push_back(1 + i + 1); - } - } - - // side - { - int vIdx(vb.size()); - - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = -0.5f * height; - v.z = radius * sinf(i * sectionSlice); - - Vec3 n(v.normalized()); - vb.push_back(SAuxObjVertex(v, n)); - vb.push_back(SAuxObjVertex(Vec3(v.x, -v.y, v.z), n)); - } - - // build faces - for (uint16 i(0); i < sections; ++i, vIdx += 2) - { - ib.push_back(vIdx); - ib.push_back(vIdx + 1); - ib.push_back(vIdx + 2); - - ib.push_back(vIdx + 1); - ib.push_back(vIdx + 3); - ib.push_back(vIdx + 2); - } - } - - // top cap - { - int vIdx(vb.size()); - - // center top vertex - vb.push_back(SAuxObjVertex(Vec3(0.0f, 0.5f * height, 0.0f), Vec3(0.0f, 1.0f, 0.0f))); - - // create circle around it - for (uint32 i(0); i <= sections; ++i) - { - Vec3 v; - v.x = radius * cosf(i * sectionSlice); - v.y = 0.5f * height; - v.z = radius * sinf(i * sectionSlice); - vb.push_back(SAuxObjVertex(v, Vec3(0.0f, 1.0f, 0.0f))); - } - - // build faces - for (uint16 i(0); i < sections; ++i) - { - ib.push_back(vIdx); - ib.push_back(vIdx + 1 + i + 1); - ib.push_back(vIdx + 1 + i); - } - } -} - - -// Functor to generate a sphere mesh. To be used with generalized CreateMesh function. -struct SSphereMeshCreateFunc -{ - SSphereMeshCreateFunc(float radius, unsigned int rings, unsigned int sections) - : m_radius(radius) - , m_rings(rings) - , m_sections(sections) - { - } - - void CreateMesh(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib) - { - CreateSphere(vb, ib, m_radius, m_rings, m_sections); - } - - float m_radius; - unsigned int m_rings; - unsigned int m_sections; -}; - -// Functor to generate a disk mesh. To be used with generalized CreateMesh function. -struct SDiskMeshCreateFunc -{ - SDiskMeshCreateFunc(float radius, unsigned int rings) - : m_radius(radius) - , m_rings(rings) - { - } - - void CreateMesh(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib) - { - CreateDisk(vb, ib, m_radius, m_rings); - } - - float m_radius; - unsigned int m_rings; -}; - -// Functor to generate a quad mesh. To be used with generalized CreateMesh function. -struct SQuadMeshCreateFunc -{ - SQuadMeshCreateFunc(float width, float height) - : m_width(width) - , m_height(height) - { - } - - void CreateMesh(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib) - { - CreateQuad(vb, ib, m_width, m_height); - } - - float m_width; - float m_height; -}; - - - -// Functor to generate a cone mesh. To be used with generalized CreateMesh function. -struct SConeMeshCreateFunc -{ - SConeMeshCreateFunc(float radius, float height, unsigned int sections) - : m_radius(radius) - , m_height(height) - , m_sections(sections) - { - } - - void CreateMesh(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib) - { - CreateCone(vb, ib, m_radius, m_height, m_sections); - } - - float m_radius; - float m_height; - unsigned int m_sections; -}; - - -// Functor to generate a cylinder mesh. To be used with generalized CreateMesh function. -struct SCylinderMeshCreateFunc -{ - SCylinderMeshCreateFunc(float radius, float height, unsigned int sections) - : m_radius(radius) - , m_height(height) - , m_sections(sections) - { - } - - void CreateMesh(AuxObjVertexBuffer& vb, AuxObjIndexBuffer& ib) - { - CreateCylinder(vb, ib, m_radius, m_height, m_sections); - } - - float m_radius; - float m_height; - unsigned int m_sections; -}; - - -// Generalized CreateMesh function to create any mesh via passed-in functor. -// The functor needs to provide a CreateMesh function which accepts an -// AuxObjVertexBuffer and AuxObjIndexBuffer to stored the resulting mesh. -template< typename TMeshFunc > -HRESULT CRenderAuxGeomD3D::CreateMesh(SDrawObjMesh& mesh, TMeshFunc meshFunc) -{ - // create mesh - std::vector< SAuxObjVertex > vb; - std::vector< uint16 > ib; - meshFunc.CreateMesh(vb, ib); - - // create vertex buffer and copy data - HRESULT hr(S_OK); - D3D11_BUFFER_DESC BufDescV; - ZeroStruct(BufDescV); - BufDescV.ByteWidth = vb.size() * sizeof(SAuxObjVertex); - BufDescV.Usage = D3D11_USAGE_DEFAULT; - BufDescV.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufDescV.CPUAccessFlags = 0; - BufDescV.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA InitData; - InitData.pSysMem = &vb[0]; - InitData.SysMemPitch = 0; - InitData.SysMemSlicePitch = 0; - if (FAILED(hr = m_renderer.m_DevMan.CreateD3D11Buffer(&BufDescV, &InitData, &mesh.m_pVB, "AuxGeometryMesh"))) - { - assert(SUCCEEDED(hr)); - return(hr); - } - - D3D11_BUFFER_DESC BufDescI; - ZeroStruct(BufDescI); - BufDescI.ByteWidth = ib.size() * sizeof(uint16); - BufDescI.Usage = D3D11_USAGE_DEFAULT; - BufDescI.BindFlags = D3D11_BIND_INDEX_BUFFER; - BufDescI.CPUAccessFlags = 0; - BufDescI.MiscFlags = 0; - - InitData.pSysMem = &ib[0]; - InitData.SysMemPitch = 0; - InitData.SysMemSlicePitch = 0; - if (FAILED(hr = m_renderer.m_DevMan.CreateD3D11Buffer(&BufDescI, &InitData, &mesh.m_pIB, "AuxGeometryMesh"))) - { - assert(SUCCEEDED(hr)); - return(hr); - } - - // write mesh info - mesh.m_numVertices = vb.size(); - mesh.m_numFaces = ib.size() / 3; - - return(hr); -} - -HRESULT CRenderAuxGeomD3D::RestoreDeviceObjects() -{ - HRESULT hr(S_OK); - - // recreate vertex buffer - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pAuxGeomVB); - m_pAuxGeomVB = nullptr; - - D3D11_BUFFER_DESC BufDescV; - ZeroStruct(BufDescV); - BufDescV.ByteWidth = e_auxGeomVBSize * sizeof(SAuxVertex); -#if defined(CRY_USE_METAL) - //Direct access memory is faster on metal as it only needs one CPU->GPU copy whereas the - //dynamic memory (for vertex buffers) will do a CPU->GPU and then a GPU->GPU copy. - BufDescV.Usage = D3D11_USAGE_DIRECT_ACCESS; -#else - BufDescV.Usage = D3D11_USAGE_DYNAMIC; -#endif - BufDescV.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufDescV.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - BufDescV.MiscFlags = 0; - - if (FAILED(hr = m_renderer.m_DevMan.CreateD3D11Buffer(&BufDescV, 0, &m_pAuxGeomVB, "AuxGeometry"))) - { - assert(0); - return(hr); - } - - // recreate index buffer - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pAuxGeomIB); - m_pAuxGeomIB = nullptr; - - D3D11_BUFFER_DESC BufDescI; - ZeroStruct(BufDescI); - BufDescI.ByteWidth = e_auxGeomIBSize * sizeof(uint16); -#if defined(CRY_USE_METAL) - //Direct access memory is faster on metal as it only needs one CPU->GPU copy whereas the - //dynamic memory (for index buffers) will do a CPU->GPU and then a GPU->GPU copy. - BufDescI.Usage = D3D11_USAGE_DIRECT_ACCESS; -#else - BufDescI.Usage = D3D11_USAGE_DYNAMIC; -#endif - BufDescI.BindFlags = D3D11_BIND_INDEX_BUFFER; - BufDescI.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - BufDescI.MiscFlags = 0; - if (FAILED(hr = m_renderer.m_DevMan.CreateD3D11Buffer(&BufDescI, 0, &m_pAuxGeomIB, "AuxGeometry"))) - { - assert(0); - return(hr); - } - - // recreate aux objects - for (uint32 i(0); i < e_auxObjNumLOD; ++i) - { - m_sphereObj[ i ].Release(); - if (FAILED(hr = CreateMesh(m_sphereObj[ i ], SSphereMeshCreateFunc(1.0f, 9 + 4 * i, 9 + 4 * i)))) - { - return(hr); - } - - m_diskObj[i].Release(); - if (FAILED(hr = CreateMesh(m_diskObj[ i ], SDiskMeshCreateFunc(1.0f, 9 + 4 * i)))) - { - return(hr); - } - - m_quadObj[i].Release(); - if (FAILED(hr = CreateMesh(m_quadObj[i], SQuadMeshCreateFunc(1.0f, 1.0f)))) - { - return(hr); - } - - m_coneObj[ i ].Release(); - if (FAILED(hr = CreateMesh(m_coneObj[ i ], SConeMeshCreateFunc(1.0f, 1.0f, 10 + i * 6)))) - { - return(hr); - } - - m_cylinderObj[ i ].Release(); - if (FAILED(hr = CreateMesh(m_cylinderObj[ i ], SCylinderMeshCreateFunc(1.0f, 1.0f, 10 + i * 6)))) - { - return(hr); - } - } - return(hr); -} - - -void CRenderAuxGeomD3D::DrawAuxPrimitives(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd, const CAuxGeomCB::EPrimType& primType) -{ - assert(CAuxGeomCB::e_PtList == primType || CAuxGeomCB::e_LineList == primType || CAuxGeomCB::e_TriList == primType); - - HRESULT hr(S_OK); - - // bind vertex and index streams and set vertex declaration - bool streamsBound = BindStreams(m_auxGeomPrimitiveVertexFormat, m_pAuxGeomVB, m_pAuxGeomIB); - - // get aux vertex buffer - const CAuxGeomCB::AuxVertexBuffer& auxVertexBuffer(GetAuxVertexBuffer()); - - // determine flags for prim type - uint32 d3dNumPrimDivider; - eRenderPrimitiveType ePrimType; - - DetermineAuxPrimitveFlags(d3dNumPrimDivider, ePrimType, primType); - - // helpers for DP call - uint32 initialVBLockOffset(m_auxGeomSBM.m_curVBIndex); - uint32 numVerticesWrittenToVB(0); - - m_renderer.FX_Commit(); - - // process each entry - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(itBegin); it != itEnd; ++it) - { - // get current push buffer entry - const CAuxGeomCB::SAuxPushBufferEntry* curPBEntry(*it); - - // number of vertices to copy - uint32 verticesToCopy(curPBEntry->m_numVertices); - uint32 verticesCopied(0); - - // stream vertex data - while (verticesToCopy > 0) - { - // number of vertices which fit into current vb - uint32 maxVerticesInThisBatch(e_auxGeomVBSize - m_auxGeomSBM.m_curVBIndex); - - // round down to previous multiple of "d3dNumPrimDivider" - maxVerticesInThisBatch -= maxVerticesInThisBatch % d3dNumPrimDivider; - - // still enough space to feed data in the current vb - if (maxVerticesInThisBatch > 0) - { - // compute amount of vertices to move in this batch - uint32 toCopy(verticesToCopy > maxVerticesInThisBatch ? maxVerticesInThisBatch : verticesToCopy); - - // get pointer to vertex buffer - SAuxVertex* pVertices(0); - // determine lock flags - D3D11_MAP mapFlags(D3D11_MAP_WRITE_NO_OVERWRITE); - if (false != m_auxGeomSBM.m_discardVB) - { - m_auxGeomSBM.m_discardVB = false; - mapFlags = D3D11_MAP_WRITE_DISCARD; - } - - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (FAILED(hr = m_renderer.GetDeviceContext().Map(m_pAuxGeomVB, 0, mapFlags, 0, &mappedResource))) - { - assert(0); - iLog->Log("ERROR: CD3DRenderAuxGeom::DrawAuxPrimitives() - Vertex buffer could not be locked!"); - return; - } - pVertices = (SAuxVertex*)mappedResource.pData; - pVertices += m_auxGeomSBM.m_curVBIndex; - - // move vertex data - // cppcheck-suppress nullPointer - memcpy(pVertices, &auxVertexBuffer[ curPBEntry->m_vertexOffs + verticesCopied ], toCopy * sizeof(SAuxVertex)); - - // unlock vb - m_renderer.GetDeviceContext().Unmap(m_pAuxGeomVB, 0); - // update accumulators and buffer indices - verticesCopied += toCopy; - verticesToCopy -= toCopy; - - m_auxGeomSBM.m_curVBIndex += toCopy; - numVerticesWrittenToVB += toCopy; - } - else - { - // not enough space in vb for (remainder of) current push buffer entry - if (numVerticesWrittenToVB > 0) - { - // commit batch - assert(0 == numVerticesWrittenToVB % d3dNumPrimDivider); - if (streamsBound) - { - m_renderer.FX_DrawPrimitive(ePrimType, initialVBLockOffset, numVerticesWrittenToVB); - } - } - - // request a DISCARD lock of vb in the next run - m_auxGeomSBM.DiscardVB(); - initialVBLockOffset = m_auxGeomSBM.m_curVBIndex; - numVerticesWrittenToVB = 0; - } - } - } - - if (numVerticesWrittenToVB > 0) - { - // commit batch - assert(0 == numVerticesWrittenToVB % d3dNumPrimDivider); - - if (streamsBound) - { - m_renderer.FX_DrawPrimitive(ePrimType, initialVBLockOffset, numVerticesWrittenToVB); - } - } -} - - -void CRenderAuxGeomD3D::DrawAuxIndexedPrimitives(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd, const CAuxGeomCB::EPrimType& primType) -{ - assert(CAuxGeomCB::e_LineListInd == primType || CAuxGeomCB::e_TriListInd == primType); - - HRESULT hr(S_OK); - - // bind vertex and index streams and set vertex declaration - bool streamsBound = BindStreams(eVF_P3F_C4B_T2F, m_pAuxGeomVB, m_pAuxGeomIB); - - // get aux vertex and index buffer - const CAuxGeomCB::AuxVertexBuffer& auxVertexBuffer(GetAuxVertexBuffer()); - const CAuxGeomCB::AuxIndexBuffer& auxIndexBuffer(GetAuxIndexBuffer()); - - // determine flags for prim type - uint32 d3dNumPrimDivider; - eRenderPrimitiveType ePrimType; - DetermineAuxPrimitveFlags(d3dNumPrimDivider, ePrimType, primType); - - // helpers for DP call - uint32 initialVBLockOffset(m_auxGeomSBM.m_curVBIndex); - uint32 numVerticesWrittenToVB(0); - uint32 initialIBLockOffset(m_auxGeomSBM.m_curIBIndex); - uint32 numIndicesWrittenToIB(0); - - m_renderer.FX_Commit(); - - // process each entry - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(itBegin); it != itEnd; ) - { - // get current push buffer entry - const CAuxGeomCB::SAuxPushBufferEntry* curPBEntry(*it); - - // process a push buffer entry if it can fit at all (otherwise silently skip it) - if (e_auxGeomVBSize >= curPBEntry->m_numVertices && e_auxGeomIBSize >= curPBEntry->m_numIndices) - { - // check if push buffer still fits into current buffer - if (e_auxGeomVBSize >= m_auxGeomSBM.m_curVBIndex + curPBEntry->m_numVertices && e_auxGeomIBSize >= m_auxGeomSBM.m_curIBIndex + curPBEntry->m_numIndices) - { - // determine lock vb flags - - // get pointer to vertex buffer - SAuxVertex* pVertices(0); - D3D11_MAP mp (D3D11_MAP_WRITE_NO_OVERWRITE); - if (false != m_auxGeomSBM.m_discardVB) - { - m_auxGeomSBM.m_discardVB = false; - mp = D3D11_MAP_WRITE_DISCARD; - } - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (FAILED(hr = m_renderer.GetDeviceContext().Map(m_pAuxGeomVB, 0, mp, 0, &mappedResource))) - { - assert(0); - iLog->Log("ERROR: CD3DRenderAuxGeom::DrawAuxIndexedPrimitives() - Vertex buffer could not be locked!"); - return; - } - pVertices = (SAuxVertex*)mappedResource.pData; - pVertices += m_auxGeomSBM.m_curVBIndex; - - // move vertex data of this entry - // cppcheck-suppress nullPointer - memcpy(pVertices, &auxVertexBuffer[ curPBEntry->m_vertexOffs ], curPBEntry->m_numVertices * sizeof(SAuxVertex)); - - // unlock vb - m_renderer.GetDeviceContext().Unmap(m_pAuxGeomVB, 0); - - // get pointer to index buffer - uint16* pIndices(0); - mp = D3D11_MAP_WRITE_NO_OVERWRITE; - if (false != m_auxGeomSBM.m_discardIB) - { - m_auxGeomSBM.m_discardIB = false; - mp = D3D11_MAP_WRITE_DISCARD; - } - - if (FAILED(hr = m_renderer.GetDeviceContext().Map(m_pAuxGeomIB, 0, mp, 0, &mappedResource))) - { - assert(0); - iLog->Log("ERROR: CD3DRenderAuxGeom::DrawAuxIndexedPrimitives() - Index buffer could not be locked!"); - - m_renderer.GetDeviceContext().Unmap(m_pAuxGeomVB, 0); - return; - } - pIndices = (uint16*)mappedResource.pData; - pIndices += m_auxGeomSBM.m_curIBIndex; - - // move index data of this entry (modify indices to match VB insert location) - for (uint32 i(0); i < curPBEntry->m_numIndices; ++i) - { - // cppcheck-suppress nullPointer - pIndices[ i ] = numVerticesWrittenToVB + auxIndexBuffer[ curPBEntry->m_indexOffs + i ]; - } - - // unlock ib - m_renderer.GetDeviceContext().Unmap(m_pAuxGeomIB, 0); - - // update buffer indices - m_auxGeomSBM.m_curVBIndex += curPBEntry->m_numVertices; - m_auxGeomSBM.m_curIBIndex += curPBEntry->m_numIndices; - - numVerticesWrittenToVB += curPBEntry->m_numVertices; - numIndicesWrittenToIB += curPBEntry->m_numIndices; - - // advance to next push puffer entry - ++it; - } - else - { - // push buffer entry currently doesn't fit, will be processed in the next iteration when buffers got flushed - if (numVerticesWrittenToVB > 0 && numIndicesWrittenToIB > 0) - { - // commit batch - assert(0 == numIndicesWrittenToIB % d3dNumPrimDivider); - if (streamsBound) - { - m_renderer.FX_DrawIndexedPrimitive(ePrimType, initialVBLockOffset, 0, numVerticesWrittenToVB, initialIBLockOffset, numIndicesWrittenToIB); - } - } - - // request a DISCARD lock / don't advance iterator! - m_auxGeomSBM.DiscardVB(); - initialVBLockOffset = m_auxGeomSBM.m_curVBIndex; - numVerticesWrittenToVB = 0; - - m_auxGeomSBM.DiscardIB(); - initialIBLockOffset = m_auxGeomSBM.m_curIBIndex; - numIndicesWrittenToIB = 0; - } - } - else - { - // push buffer entry too big for dedicated vb/ib buffer - // advance to next push puffer entry - assert(0); - iLog->Log("ERROR: CD3DRenderAuxGeom::DrawAuxIndexedPrimitives() - Auxiliary geometry too big to render!"); - ++it; - } - } - - if (numVerticesWrittenToVB > 0 && numIndicesWrittenToIB > 0) - { - // commit batch - assert(0 == numIndicesWrittenToIB % d3dNumPrimDivider); - if (streamsBound) - { - m_renderer.FX_DrawIndexedPrimitive(ePrimType, initialVBLockOffset, 0, numVerticesWrittenToVB, initialIBLockOffset, numIndicesWrittenToIB); - } - } -} - - -void CRenderAuxGeomD3D::DrawAuxObjects(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd) -{ - CAuxGeomCB::EAuxDrawObjType objType(CAuxGeomCB::GetAuxObjType((*itBegin)->m_renderFlags)); - - // get draw params buffer - const CAuxGeomCB::AuxDrawObjParamBuffer& auxDrawObjParamBuffer(GetAuxDrawObjParamBuffer()); - - // process each entry - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(itBegin); it != itEnd; ++it) - { - // get current push buffer entry - const CAuxGeomCB::SAuxPushBufferEntry* curPBEntry(*it); - - // assert than all objects in this batch are of same type - assert(CAuxGeomCB::GetAuxObjType(curPBEntry->m_renderFlags) == objType); - - uint32 drawParamOffs(0); - if (curPBEntry->GetDrawParamOffs(drawParamOffs)) - { - // get draw params - const CAuxGeomCB::SAuxDrawObjParams& drawParams(auxDrawObjParamBuffer[ drawParamOffs ]); - - // Prepare d3d world space matrix in draw param structure - // Attention: in d3d terms matWorld is actually matWorld^T - Matrix44A matWorld; - matWorld.SetIdentity(); - memcpy(&matWorld, &drawParams.m_matWorld, sizeof(drawParams.m_matWorld)); - - // set transformation matrices - static CCryNameR matWorldViewProjName("matWorldViewProj"); - if (m_curDrawInFrontMode == e_DrawInFrontOn) - { - Matrix44A matScale(Matrix44A(Matrix34::CreateScale(Vec3(0.999f, 0.999f, 0.999f)))); - - Matrix44A matWorldViewScaleProjT; - matWorldViewScaleProjT = (GetCurrentView() * matScale); - matWorldViewScaleProjT = matWorldViewScaleProjT * GetCurrentProj(); - - matWorldViewScaleProjT = matWorldViewScaleProjT.GetTransposed(); - matWorldViewScaleProjT = matWorldViewScaleProjT * matWorld; - m_pAuxGeomShader->FXSetVSFloat(matWorldViewProjName, alias_cast(&matWorldViewScaleProjT), 4); - } - else - { - Matrix44A matWorldViewProjT; - matWorldViewProjT = m_matrices.m_pCurTransMat->GetTransposed(); - matWorldViewProjT = matWorldViewProjT * matWorld; - m_pAuxGeomShader->FXSetVSFloat(matWorldViewProjName, alias_cast(&matWorldViewProjT), 4); - } - - // set color - ColorF col(drawParams.m_color); - Vec4 colVec(col.b, col.g, col.r, col.a); // need to flip r/b as drawParams.m_color was originally argb - static CCryNameR auxGeomObjColorName("auxGeomObjColor"); - m_pAuxGeomShader->FXSetVSFloat(auxGeomObjColorName, &colVec, 1); - - // set shading flag - Vec4 shadingVec(drawParams.m_shaded ? 0.4f : 0, drawParams.m_shaded ? 0.6f : 1, 0, 0); - static CCryNameR auxGeomObjShadingName("auxGeomObjShading"); - m_pAuxGeomShader->FXSetVSFloat(auxGeomObjShadingName, &shadingVec, 1); - - // set light vector (rotate back into local space) - Matrix33 matWorldInv(drawParams.m_matWorldRotation.GetInverted()); - Vec3 lightLocalSpace(matWorldInv * Vec3(0.5773f, 0.5773f, 0.5773f)); - - // normalize light vector (matWorld could contain non-uniform scaling) - lightLocalSpace.Normalize(); - Vec4 lightVec(lightLocalSpace.x, lightLocalSpace.y, lightLocalSpace.z, 0.0f); - static CCryNameR globalLightLocalName("globalLightLocal"); - m_pAuxGeomShader->FXSetVSFloat(globalLightLocalName, &lightVec, 1); - - // LOD calculation - Matrix44A matWorldT; - matWorldT = matWorld.GetTransposed(); - - Vec4 objCenterWorld; - Vec3 nullVec(0.0f, 0.0f, 0.0f); - mathVec3TransformF(&objCenterWorld, &nullVec, &matWorldT); - Vec4 objOuterRightWorld(objCenterWorld + (Vec4(GetCurrentView().m00, GetCurrentView().m10, GetCurrentView().m20, 0.0f) * drawParams.m_size)); - - Vec4 v0, v1; - - Vec3 objCenterWorldVec(objCenterWorld.x, objCenterWorld.y, objCenterWorld.z); - Vec3 objOuterRightWorldVec(objOuterRightWorld.x, objOuterRightWorld.y, objOuterRightWorld.z); - mathVec3TransformF(&v0, &objCenterWorldVec, m_matrices.m_pCurTransMat); - mathVec3TransformF(&v1, &objOuterRightWorldVec, m_matrices.m_pCurTransMat); - - float scale; - assert(fabs(v0.w - v0.w) < 1e-4); - if (fabs(v0.w) < 1e-2) - { - scale = 0.5f; - } - else - { - scale = ((v1.x - v0.x) / v0.w) * (float) max(m_wndXRes, m_wndYRes) / 500.0f; - } - - // map scale to detail level - uint32 lodLevel((uint32) ((scale / 0.5f) * (e_auxObjNumLOD - 1))); - if (lodLevel >= e_auxObjNumLOD) - { - lodLevel = e_auxObjNumLOD - 1; - } - - // get appropriate mesh - assert(lodLevel >= 0 && lodLevel < e_auxObjNumLOD); - SDrawObjMesh* pMesh(0); - switch (objType) - { - case CAuxGeomCB::eDOT_Sphere: - default: - { - pMesh = &m_sphereObj[ lodLevel ]; - break; - } - case CAuxGeomCB::eDOT_Disk: - { - pMesh = &m_diskObj[ lodLevel ]; - break; - } - case CAuxGeomCB::eDOT_Quad: - { - pMesh = &m_quadObj[lodLevel]; - break; - } - case CAuxGeomCB::eDOT_Cone: - { - pMesh = &m_coneObj[ lodLevel ]; - break; - } - case CAuxGeomCB::eDOT_Cylinder: - { - pMesh = &m_cylinderObj[ lodLevel ]; - break; - } - } - assert(0 != pMesh); - - // bind vertex and index streams and set vertex declaration - if (BindStreams(m_auxGeomObjectVertexFormat, pMesh->m_pVB, pMesh->m_pIB)) - { - m_renderer.FX_Commit(); - - // draw mesh - m_renderer.FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pMesh->m_numVertices, 0, pMesh->m_numFaces * 3); - } - } - else - { - assert(0); // GetDrawParamOffs( ... ) failed -- corrupt data in push buffer? - } - } -} - -static inline Vec3 IntersectLinePlane(const Vec3& o, const Vec3& d, const Plane& p, float& t) -{ - t = -((p.n | o) + (p.d + c_clipThres)) / (p.n | d); - return(o + d * t); -} - -// maps floating point channels (0.f to 1.f range) to DWORD -#define DWORD_COLORVALUE(r, g, b, a) \ - DWORD( \ - (((DWORD)((a) * 255.f) & 0xff) << 24) | \ - (((DWORD)((r) * 255.f) & 0xff) << 16) | \ - (((DWORD)((g) * 255.f) & 0xff) << 8) | \ - (((DWORD)((b) * 255.f) & 0xff) << 0)) - -static inline DWORD ClipColor(const DWORD& c0, const DWORD& c1, float t) -{ - // convert D3D DWORD color storage (ARGB) to custom ColorF storage (ColorB uses ABGR!) - const float f = 1.0f / 255.0f; - ColorF v0( - f * (float)(unsigned char)(c0 >> 16), - f * (float)(unsigned char)(c0 >> 8), - f * (float)(unsigned char)(c0 >> 0), - f * (float)(unsigned char)(c0 >> 24)); - ColorF v1( - f * (float)(unsigned char)(c1 >> 16), - f * (float)(unsigned char)(c1 >> 8), - f * (float)(unsigned char)(c1 >> 0), - f * (float)(unsigned char)(c1 >> 24)); - ColorF vRes(v0 + (v1 - v0) * t); - return(DWORD_COLORVALUE(vRes.r, vRes.g, vRes.b, vRes.a)); -} - -static bool ClipLine(Vec3* v, DWORD* c) -{ - // get near plane to perform clipping - Plane nearPlane(*gRenDev->GetCamera().GetFrustumPlane(FR_PLANE_NEAR)); - - // get clipping flags - bool bV0Behind(-((nearPlane.n | v[ 0 ]) + nearPlane.d) < c_clipThres); - bool bV1Behind(-((nearPlane.n | v[ 1 ]) + nearPlane.d) < c_clipThres); - - // proceed only if both are not behind near clipping plane - if (false == bV0Behind || false == bV1Behind) - { - if (false == bV0Behind && false == bV1Behind) - { - // no clipping needed - return(true); - } - - // define line to be clipped - Vec3 p(v[ 0 ]); - Vec3 d(v[ 1 ] - v[ 0 ]); - - // get clipped position - float t; - v[ 0 ] = (false == bV0Behind) ? v[ 0 ] : IntersectLinePlane(p, d, nearPlane, t); - v[ 1 ] = (false == bV1Behind) ? v[ 1 ] : IntersectLinePlane(p, d, nearPlane, t); - - // get clipped colors - c[ 0 ] = (false == bV0Behind) ? c[ 0 ] : ClipColor(c[ 0 ], c[ 1 ], t); - c[ 1 ] = (false == bV1Behind) ? c[ 1 ] : ClipColor(c[ 0 ], c[ 1 ], t); - - return(true); - } - else - { - return(false); - } -} - - -static float ComputeConstantScale(const Vec3& v, const Matrix44A& matView, const Matrix44A& matProj, const uint32 wndXRes) -{ - Vec4 vCam0; - mathVec3TransformF(&vCam0, &v, &matView); - - Vec4 vCam1(vCam0); - vCam1.x += 1.0f; - - const float a = vCam0.y * matProj.m10 + vCam0.z * matProj.m20 + matProj.m30; - const float b = vCam0.y * matProj.m13 + vCam0.z * matProj.m23 + matProj.m33; - - float c0((vCam0.x * matProj.m00 + a) / (vCam0.x * matProj.m03 + b)); - float c1((vCam1.x * matProj.m00 + a) / (vCam1.x * matProj.m03 + b)); - - float s = (float)wndXRes * (c1 - c0); - - const float epsilon = 0.001f; - return (fabsf(s) >= epsilon) ? 1.0f / s : 1.0f / epsilon; -} - - -void CRenderAuxGeomD3D::PrepareThickLines3D(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd) -{ - const CAuxGeomCB::AuxVertexBuffer& auxVertexBuffer(GetAuxVertexBuffer()); - - // process each entry - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(itBegin); it != itEnd; ++it) - { - // get current push buffer entry - const CAuxGeomCB::SAuxPushBufferEntry* curPBEntry(*it); - - uint32 offset(curPBEntry->m_vertexOffs); - for (uint32 i(0); i < curPBEntry->m_numVertices / 6; ++i, offset += 6) - { - // get line vertices and thickness parameter - const float* aTmp0 = (const float*) &(auxVertexBuffer[ offset + 0 ].xyz.x); - const float* aTmp1 = (const float*) &(auxVertexBuffer[ offset + 1 ].xyz.x); - const Vec3 v[ 2 ] = - { - Vec3(aTmp0[0], aTmp0[1], aTmp0[2]), - Vec3(aTmp1[0], aTmp1[1], aTmp1[2]) - }; - DWORD col[ 2 ] = - { - auxVertexBuffer[ offset + 0 ].color.dcolor, - auxVertexBuffer[ offset + 1 ].color.dcolor - }; - float thickness(auxVertexBuffer[ offset + 2 ].xyz.x); - - bool skipLine(false); - Vec4 vf[ 4 ]; - - if (false == IsOrthoMode()) // regular, 3d projected geometry - { - skipLine = !ClipLine((Vec3*)v, col); - if (false == skipLine) - { - // compute depth corrected thickness of line end points - float thicknessV0(0.5f * thickness * ComputeConstantScale(v[ 0 ], GetCurrentView(), GetCurrentProj(), m_wndXRes)); - float thicknessV1(0.5f * thickness * ComputeConstantScale(v[ 1 ], GetCurrentView(), GetCurrentProj(), m_wndXRes)); - - // compute camera space line delta - Vec4 vt[ 2 ]; - mathVec3TransformF(&vt[ 0 ], &v[ 0 ], &GetCurrentView()); - mathVec3TransformF(&vt[ 1 ], &v[ 1 ], &GetCurrentView()); - vt[0].z = (float) fsel(-vt[0].z - c_clipThres, vt[0].z, -c_clipThres); - vt[1].z = (float) fsel(-vt[1].z - c_clipThres, vt[1].z, -c_clipThres); - Vec4 tmp(vt[ 1 ] / vt[ 1 ].z - vt[ 0 ] / vt[ 0 ].z); - Vec2 delta(tmp.x, tmp.y); - - // create screen space normal of line delta - Vec2 normalVec(-delta.y, delta.x); - mathVec2NormalizeF(&normalVec, &normalVec); - Vec2 normal(normalVec.x, normalVec.y); - - Vec2 n[ 2 ]; - n[ 0 ] = normal * thicknessV0; - n[ 1 ] = normal * thicknessV1; - - // compute final world space vertices of thick line - Vec4 vertices[4] = - { - Vec4(vt[ 0 ].x + n[ 0 ].x, vt[ 0 ].y + n[ 0 ].y, vt[ 0 ].z, vt[ 0 ].w), - Vec4(vt[ 1 ].x + n[ 1 ].x, vt[ 1 ].y + n[ 1 ].y, vt[ 1 ].z, vt[ 1 ].w), - Vec4(vt[ 1 ].x - n[ 1 ].x, vt[ 1 ].y - n[ 1 ].y, vt[ 1 ].z, vt[ 1 ].w), - Vec4(vt[ 0 ].x - n[ 0 ].x, vt[ 0 ].y - n[ 0 ].y, vt[ 0 ].z, vt[ 0 ].w) - }; - mathVec4TransformF(&vf[ 0 ], &vertices[0], &GetCurrentViewInv()); - mathVec4TransformF(&vf[ 1 ], &vertices[1], &GetCurrentViewInv()); - mathVec4TransformF(&vf[ 2 ], &vertices[2], &GetCurrentViewInv()); - mathVec4TransformF(&vf[ 3 ], &vertices[3], &GetCurrentViewInv()); - } - } - else // orthogonal projected geometry - { - // compute depth corrected thickness of line end points - float thicknessV0(0.5f * thickness * ComputeConstantScale(v[ 0 ], GetCurrentView(), GetCurrentProj(), m_wndXRes)); - float thicknessV1(0.5f * thickness * ComputeConstantScale(v[ 1 ], GetCurrentView(), GetCurrentProj(), m_wndXRes)); - - // compute line delta - Vec2 delta(v[ 1 ] - v[ 0 ]); - - // create normal of line delta - Vec2 normalVec(-delta.y, delta.x); - mathVec2NormalizeF(&normalVec, &normalVec); - Vec2 normal(normalVec.x, normalVec.y); - - Vec2 n[ 2 ]; - n[ 0 ] = normal * thicknessV0 * 2.0f; - n[ 1 ] = normal * thicknessV1 * 2.0f; - - // compute final world space vertices of thick line - vf[ 0 ] = Vec4(v[ 0 ].x + n[ 0 ].x, v[ 0 ].y + n[ 0 ].y, v[ 0 ].z, 1.0f); - vf[ 1 ] = Vec4(v[ 1 ].x + n[ 1 ].x, v[ 1 ].y + n[ 1 ].y, v[ 1 ].z, 1.0f); - vf[ 2 ] = Vec4(v[ 1 ].x - n[ 1 ].x, v[ 1 ].y - n[ 1 ].y, v[ 1 ].z, 1.0f); - vf[ 3 ] = Vec4(v[ 0 ].x - n[ 0 ].x, v[ 0 ].y - n[ 0 ].y, v[ 0 ].z, 1.0f); - } - - SAuxVertex* pVertices(const_cast(&auxVertexBuffer[ offset ])); - if (false == skipLine) - { - // copy data to vertex buffer - pVertices[ 0 ].xyz = Vec3(vf[ 0 ].x, vf[ 0 ].y, vf[ 0 ].z); - pVertices[ 0 ].color.dcolor = col[ 0 ]; - pVertices[ 1 ].xyz = Vec3(vf[ 1 ].x, vf[ 1 ].y, vf[ 1 ].z); - pVertices[ 1 ].color.dcolor = col[ 1 ]; - pVertices[ 2 ].xyz = Vec3(vf[ 2 ].x, vf[ 2 ].y, vf[ 2 ].z); - pVertices[ 2 ].color.dcolor = col[ 1 ]; - pVertices[ 3 ].xyz = Vec3(vf[ 0 ].x, vf[ 0 ].y, vf[ 0 ].z); - pVertices[ 3 ].color.dcolor = col[ 0 ]; - pVertices[ 4 ].xyz = Vec3(vf[ 2 ].x, vf[ 2 ].y, vf[ 2 ].z); - pVertices[ 4 ].color.dcolor = col[ 1 ]; - pVertices[ 5 ].xyz = Vec3(vf[ 3 ].x, vf[ 3 ].y, vf[ 3 ].z); - pVertices[ 5 ].color.dcolor = col[ 0 ]; - } - else - { - // invalidate parameter data of thick line stored in vertex buffer - // (generates two black degenerated triangles at (0,0,0)) - memset(pVertices, 0, sizeof(SAuxVertex) * 6); - } - } - } -} - - -void CRenderAuxGeomD3D::PrepareThickLines2D(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd) -{ - const CAuxGeomCB::AuxVertexBuffer& auxVertexBuffer(GetAuxVertexBuffer()); - - // process each entry - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(itBegin); it != itEnd; ++it) - { - // get current push buffer entry - const CAuxGeomCB::SAuxPushBufferEntry* curPBEntry(*it); - - uint32 offset(curPBEntry->m_vertexOffs); - for (uint32 i(0); i < curPBEntry->m_numVertices / 6; ++i, offset += 6) - { - // get line vertices and thickness parameter - const float* aTmp0 = (const float*) &(auxVertexBuffer[ offset + 0 ].xyz.x); - const float* aTmp1 = (const float*) &(auxVertexBuffer[ offset + 1 ].xyz.x); - const Vec3 v[ 2 ] = - { - Vec3(aTmp0[0], aTmp0[1], aTmp0[2]), - Vec3(aTmp1[0], aTmp1[1], aTmp1[2]) - }; - const DWORD col[ 2 ] = - { - auxVertexBuffer[ offset + 0 ].color.dcolor, - auxVertexBuffer[ offset + 1 ].color.dcolor - }; - float thickness(auxVertexBuffer[ offset + 2 ].xyz.x); - - // get line delta and aspect ratio corrected normal - Vec3 delta(v[ 1 ] - v[ 0 ]); - Vec3 normalVec(-delta.y * m_aspectInv, delta.x * m_aspect, 0.0f); - - // normalize and scale to line thickness - mathVec3NormalizeF(&normalVec, &normalVec); - Vec3 normal(normalVec.x, normalVec.y, normalVec.z); - normal *= thickness * 0.001f; - - // compute final 2D vertices of thick line in normalized device space - Vec3 vf[ 4 ]; - vf[ 0 ] = v[ 0 ] + normal; - vf[ 1 ] = v[ 1 ] + normal; - vf[ 2 ] = v[ 1 ] - normal; - vf[ 3 ] = v[ 0 ] - normal; - - // copy data to vertex buffer - SAuxVertex* pVertices(const_cast(&auxVertexBuffer[ offset ])); - pVertices[ 0 ].xyz = Vec3(vf[ 0 ].x, vf[ 0 ].y, vf[ 0 ].z); - pVertices[ 0 ].color.dcolor = col[ 0 ]; - pVertices[ 1 ].xyz = Vec3(vf[ 1 ].x, vf[ 1 ].y, vf[ 1 ].z); - pVertices[ 1 ].color.dcolor = col[ 1 ]; - pVertices[ 2 ].xyz = Vec3(vf[ 2 ].x, vf[ 2 ].y, vf[ 2 ].z); - pVertices[ 2 ].color.dcolor = col[ 1 ]; - pVertices[ 3 ].xyz = Vec3(vf[ 0 ].x, vf[ 0 ].y, vf[ 0 ].z); - pVertices[ 3 ].color.dcolor = col[ 0 ]; - pVertices[ 4 ].xyz = Vec3(vf[ 2 ].x, vf[ 2 ].y, vf[ 2 ].z); - pVertices[ 4 ].color.dcolor = col[ 1 ]; - pVertices[ 5 ].xyz = Vec3(vf[ 3 ].x, vf[ 3 ].y, vf[ 3 ].z); - pVertices[ 5 ].color.dcolor = col[ 0 ]; - } - } -} - - -void CRenderAuxGeomD3D::PrepareRendering() -{ - // update transformation matrices - m_matrices.UpdateMatrices(m_renderer); - - // get current window resultion and update aspect ratios - m_wndXRes = m_renderer.GetWidth(); - m_wndYRes = m_renderer.GetHeight(); - - m_aspect = 1.0f; - m_aspectInv = 1.0f; - if (m_wndXRes > 0 && m_wndYRes > 0) - { - m_aspect = (float) m_wndXRes / (float) m_wndYRes; - m_aspectInv = 1.0f / m_aspect; - } - - // reset DrawInFront mode - m_curDrawInFrontMode = e_DrawInFrontOff; - - // reset stream buffer manager - m_auxGeomSBM.Reset(); - - // reset current VB/IB - m_pCurVB = 0; - m_pCurIB = 0; - - // reset current prim type - m_curPrimType = CAuxGeomCB::e_PrimTypeInvalid; - - // set vertex format - //m_renderer.m_RP.m_CurVFormat = m_auxGeomVertexFormat; -} - - -bool CRenderAuxGeomD3D::BindStreams(const AZ::Vertex::Format& newVertexFormat, D3DBuffer* pNewVB, D3DBuffer* pNewIB) -{ - // set vertex declaration - if (FAILED(m_renderer.FX_SetVertexDeclaration(0, newVertexFormat))) - { - return false; - } - - // bind streams - HRESULT hr = S_OK; - if (m_pCurVB != pNewVB) - { - hr = m_renderer.FX_SetVStream(0, pNewVB, 0, newVertexFormat.GetStride()); - m_pCurVB = pNewVB; - } - if (m_pCurIB != pNewIB) - { - hr = m_renderer.FX_SetIStream(pNewIB, 0, Index16); - m_pCurIB = pNewIB; - } - - return SUCCEEDED(hr); -} - - -void CRenderAuxGeomD3D::SetShader(const SAuxGeomRenderFlags& renderFlags) -{ - if (0 == m_pAuxGeomShader) - { - // allow invalid file access for this shader because it shouldn't be used in the final build anyway - CDebugAllowFileAccess ignoreInvalidFileAccess; - m_pAuxGeomShader = m_renderer.m_cEF.mfForName("AuxGeom", EF_SYSTEM); - assert(0 != m_pAuxGeomShader); - } - - if (0 != m_pAuxGeomShader) - { - bool dirty(0 != (m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_PersFlags & RBPF_FP_DIRTY)); - if (false != dirty) - { - // NOTE: dirty flags are either set when setting EF_ColorOp in AdjustRenderStates - m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_FP_DIRTY; - m_renderer.m_RP.m_pCurObject = m_renderer.m_RP.m_pIdendityRenderObject; - m_renderer.m_RP.m_FlagsShader_LT = m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_eCurColorOp | (m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_eCurAlphaOp << 8) | - (m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_eCurColorArg << 16) | (m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_eCurAlphaArg << 24); - } - - EAuxGeomPublicRenderflags_DrawInFrontMode newDrawInFrontMode(renderFlags.GetDrawInFrontMode()); - CAuxGeomCB::EPrimType newPrimType(CAuxGeomCB::GetPrimType(renderFlags)); - - if (false != dirty || m_pAuxGeomShader != m_renderer.m_RP.m_pShader || m_curDrawInFrontMode != newDrawInFrontMode || m_curPrimType != newPrimType) - { - if (CAuxGeomCB::e_Obj != newPrimType) - { - static CCryNameTSCRC techName("AuxGeometry"); - m_pAuxGeomShader->FXSetTechnique(techName); - m_pAuxGeomShader->FXBegin(&m_renderer.m_RP.m_nNumRendPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_pAuxGeomShader->FXBeginPass(0); - m_renderer.m_RP.m_CurVFormat = m_auxGeomPrimitiveVertexFormat; - - static CCryNameR matViewProjName("matViewProj"); - if (e_DrawInFrontOn == renderFlags.GetDrawInFrontMode() && e_Mode3D == renderFlags.GetMode2D3DFlag()) - { - Matrix44A matScale(Matrix44(Matrix34::CreateScale(Vec3(0.999f, 0.999f, 0.999f)))); - - Matrix44A matViewScaleProjT; - matViewScaleProjT = GetCurrentView() * matScale; - matViewScaleProjT = matViewScaleProjT * GetCurrentProj(); - matViewScaleProjT = matViewScaleProjT.GetTransposed(); - m_pAuxGeomShader->FXSetVSFloat(matViewProjName, alias_cast(&matViewScaleProjT), 4); - m_curDrawInFrontMode = e_DrawInFrontOn; - } - else - { - Matrix44A matViewProjT = m_matrices.m_pCurTransMat->GetTransposed(); - m_pAuxGeomShader->FXSetVSFloat(matViewProjName, alias_cast(&matViewProjT), 4); - m_curDrawInFrontMode = e_DrawInFrontOff; - } - } - else - { - static CCryNameTSCRC techName("AuxGeometryObj"); - m_pAuxGeomShader->FXSetTechnique(techName); - m_pAuxGeomShader->FXBegin(&m_renderer.m_RP.m_nNumRendPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - m_pAuxGeomShader->FXBeginPass(0); - m_renderer.m_RP.m_CurVFormat = m_auxGeomObjectVertexFormat; - - if (e_DrawInFrontOn == renderFlags.GetDrawInFrontMode() && e_Mode3D == renderFlags.GetMode2D3DFlag()) - { - m_curDrawInFrontMode = e_DrawInFrontOn; - } - else - { - m_curDrawInFrontMode = e_DrawInFrontOff; - } - } - m_curPrimType = newPrimType; - } - } - else - { - m_renderer.FX_SetFPMode(); - } -} - - -void CRenderAuxGeomD3D::AdjustRenderStates(const SAuxGeomRenderFlags& renderFlags) -{ - // init current render states mask - uint32 curRenderStates(0); - - // mode 2D/3D -- set new transformation matrix - const Matrix44A* pNewTransMat(&GetCurrentTrans3D()); - if (e_Mode2D == renderFlags.GetMode2D3DFlag()) - { - pNewTransMat = &GetCurrentTrans2D(); - } - if (m_matrices.m_pCurTransMat != pNewTransMat) - { - m_matrices.m_pCurTransMat = pNewTransMat; - - m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matProj = *pNewTransMat; - } - - // set alpha blending mode - switch (renderFlags.GetAlphaBlendMode()) - { - case e_AlphaAdditive: - { - curRenderStates |= GS_BLSRC_ONE | GS_BLDST_ONE; - break; - } - case e_AlphaBlended: - { - curRenderStates |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - break; - } - case e_AlphaNone: - default: - { - break; - } - } - - // set fill mode - switch (renderFlags.GetFillMode()) - { - case e_FillModeWireframe: - { - curRenderStates |= GS_WIREFRAME; - break; - } - case e_FillModeSolid: - default: - { - break; - } - } - - // set cull mode - switch (renderFlags.GetCullMode()) - { - case e_CullModeNone: - { - m_renderer.SetCullMode(R_CULL_NONE); - break; - } - case e_CullModeFront: - { - m_renderer.SetCullMode(R_CULL_FRONT); - break; - } - case e_CullModeBack: - default: - { - m_renderer.SetCullMode(R_CULL_BACK); - break; - } - } - - // set depth write mode - switch (renderFlags.GetDepthWriteFlag()) - { - case e_DepthWriteOff: - { - break; - } - case e_DepthWriteOn: - default: - { - curRenderStates |= GS_DEPTHWRITE; - break; - } - } - - // set depth test mode - switch (renderFlags.GetDepthTestFlag()) - { - case e_DepthTestOff: - { - curRenderStates |= GS_NODEPTHTEST; - break; - } - case e_DepthTestOn: - default: - { - break; - } - } - - // set point size - uint8 newPointSize(m_curPointSize); - if (CAuxGeomCB::e_PtList == CAuxGeomCB::GetPrimType(renderFlags)) - { - newPointSize = CAuxGeomCB::GetPointSize(renderFlags); - } - else - { - newPointSize = 1; - } - - if (newPointSize != m_curPointSize) - { - assert(newPointSize > 0); - assert(0); - m_curPointSize = newPointSize; - } - - // apply states - m_renderer.FX_SetState(curRenderStates); - - // set color operations - m_renderer.EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - m_renderer.EF_SetSrgbWrite(false); -} - - -void CRenderAuxGeomD3D::RT_Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset) -{ - if (!CV_r_auxGeom) - { - return; - } - - PROFILE_LABEL_SCOPE("AuxGeom"); - - // should only be called from render thread - assert(m_renderer.m_pRT->IsRenderThread()); - - assert(data.m_pData); - - if (begin < end) - { - m_pCurCBRawData = data.m_pData; - - Matrix44A origMatProj = m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matProj; - Matrix44A origMatView = m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matView; - - if (false == m_renderer.IsDeviceLost()) - { - // prepare rendering - PrepareRendering(); - - // get push buffer to process all submitted auxiliary geometries - m_pCurCBRawData->GetSortedPushBuffer(begin, end, m_auxSortedPushBuffer); - - // process push buffer - for (CAuxGeomCB::AuxSortedPushBuffer::const_iterator it(m_auxSortedPushBuffer.begin()), itEnd(m_auxSortedPushBuffer.end()); it != itEnd; ) - { - // mark current push buffer position - CAuxGeomCB::AuxSortedPushBuffer::const_iterator itCur(it); - - // get current render flags - const SAuxGeomRenderFlags& curRenderFlags((*itCur)->m_renderFlags); - m_curTransMatrixIdx = (*itCur)->m_transMatrixIdx; - - // get prim type - CAuxGeomCB::EPrimType primType(CAuxGeomCB::GetPrimType(curRenderFlags)); - - // find all entries sharing the same render flags - while (true) - { - ++it; - if ((it == itEnd) || ((*it)->m_renderFlags != curRenderFlags) || ((*it)->m_transMatrixIdx != m_curTransMatrixIdx)) - { - break; - } - } - - // Adjust render states based on current render flags and m_curTransMatrixIdx - AdjustRenderStates(curRenderFlags); - // Force the constant buffer to update the camera info - AdjustRenderStates() may have changed the projection matrix. - m_renderer.RT_SetCameraInfo(); - - // prepare thick lines - if (CAuxGeomCB::e_TriList == primType && false != CAuxGeomCB::IsThickLine(curRenderFlags)) - { - if (e_Mode3D == curRenderFlags.GetMode2D3DFlag()) - { - PrepareThickLines3D(itCur, it); - } - else - { - PrepareThickLines2D(itCur, it); - } - } - - // set appropriate shader - SetShader(curRenderFlags); - - // draw push buffer entries - switch (primType) - { - case CAuxGeomCB::e_PtList: - case CAuxGeomCB::e_LineList: - case CAuxGeomCB::e_TriList: - { - DrawAuxPrimitives(itCur, it, primType); - } - break; - case CAuxGeomCB::e_LineListInd: - case CAuxGeomCB::e_TriListInd: - { - DrawAuxIndexedPrimitives(itCur, it, primType); - } - break; - case CAuxGeomCB::e_Obj: - default: - { - DrawAuxObjects(itCur, it); - } - break; - } - } - } - - m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matProj = origMatProj; - m_renderer.m_RP.m_TI[m_renderer.m_RP.m_nProcessThreadID].m_matView = origMatView; - - m_pCurCBRawData = 0; - m_curTransMatrixIdx = 0; - } - - if (reset) - { - FlushTextMessages(data.m_pData->m_TextMessages, true); - data.m_pData->SetUsed(false); - } -} - - -void CRenderAuxGeomD3D::Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset) -{ - m_renderer.m_pRT->RC_AuxFlush(this, data, begin, end, reset); -} - -void CRenderAuxGeomD3D::FlushTextMessages(CTextMessages& tMessages, bool reset) -{ - gRenDev->RenderTextMessages(tMessages); - tMessages.Clear(!reset); -} - - -void CRenderAuxGeomD3D::SetOrthoMode(bool enable, Matrix44A* pMatrix) -{ - GetRenderAuxGeom()->SetOrthoMode(enable, pMatrix); -} - - -const Matrix44A& CRenderAuxGeomD3D::GetCurrentView() const -{ - return IsOrthoMode() ? gRenDev->m_IdentityMatrix : m_matrices.m_matView; -} - - -const Matrix44A& CRenderAuxGeomD3D::GetCurrentViewInv() const -{ - return IsOrthoMode() ? gRenDev->m_IdentityMatrix : m_matrices.m_matViewInv; -} - - -const Matrix44A& CRenderAuxGeomD3D::GetCurrentProj() const -{ - return IsOrthoMode() ? GetAuxOrthoMatrix(m_curTransMatrixIdx) : m_matrices.m_matProj; -} - - -const Matrix44A& CRenderAuxGeomD3D::GetCurrentTrans3D() const -{ - return IsOrthoMode() ? GetAuxOrthoMatrix(m_curTransMatrixIdx) : m_matrices.m_matTrans3D; -} - - -const Matrix44A& CRenderAuxGeomD3D::GetCurrentTrans2D() const -{ - return m_matrices.m_matTrans2D; -} - - -bool CRenderAuxGeomD3D::IsOrthoMode() const -{ - return m_curTransMatrixIdx != -1; -} - - -void CRenderAuxGeomD3D::SMatrices::UpdateMatrices(CD3D9Renderer& renderer) -{ - renderer.GetModelViewMatrix(&m_matView.m00); - renderer.GetProjectionMatrix(&m_matProj.m00); - - m_matViewInv = m_matView.GetInverted(); - m_matTrans3D = m_matView * m_matProj; - - m_pCurTransMat = 0; -} - - -void CRenderAuxGeomD3D::FreeMemory() -{ - m_auxGeomCBCol.FreeMemory(); - - stl::free_container(m_auxSortedPushBuffer); -} - -void CRenderAuxGeomD3D::Process() -{ - m_auxGeomCBCol.Process(); -} - -CAuxGeomCB* CRenderAuxGeomD3D::GetRenderAuxGeom(void* jobID) -{ - return m_auxGeomCBCol.Get(this, jobID); -} - - -inline const CAuxGeomCB::AuxVertexBuffer& CRenderAuxGeomD3D::GetAuxVertexBuffer() const -{ - assert(m_pCurCBRawData); - return m_pCurCBRawData->m_auxVertexBuffer; -} - - -inline const CAuxGeomCB::AuxIndexBuffer& CRenderAuxGeomD3D::GetAuxIndexBuffer() const -{ - assert(m_pCurCBRawData); - return m_pCurCBRawData->m_auxIndexBuffer; -} - - -inline const CAuxGeomCB::AuxDrawObjParamBuffer& CRenderAuxGeomD3D::GetAuxDrawObjParamBuffer() const -{ - assert(m_pCurCBRawData); - return m_pCurCBRawData->m_auxDrawObjParamBuffer; -} - - -inline const Matrix44A& CRenderAuxGeomD3D::GetAuxOrthoMatrix(int idx) const -{ - assert(m_pCurCBRawData && idx >= 0 && idx < (int)m_pCurCBRawData->m_auxOrthoMatrices.size()); - return m_pCurCBRawData->m_auxOrthoMatrices[idx]; -} - -void CRenderAuxGeomD3D::SDrawObjMesh::Release() -{ - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pVB); - m_pVB = nullptr; - - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(m_pIB); - m_pIB = nullptr; - - m_numVertices = 0; - m_numFaces = 0; -} - -#endif // #if defined(ENABLE_RENDER_AUX_GEOM) diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.h deleted file mode 100644 index 74d30a6ed2..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderAuxGeom.h +++ /dev/null @@ -1,483 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DRENDERAUXGEOM_H -#define CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_D3DRENDERAUXGEOM_H -#pragma once - - - -#include - -#if defined(ENABLE_RENDER_AUX_GEOM) - -class CD3D9Renderer; -class ICrySizer; - - -class CRenderAuxGeomD3D - : public IRenderAuxGeomImpl -{ -public: - virtual void Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset = false); - virtual void RT_Flush(SAuxGeomCBRawDataPackaged& data, size_t begin, size_t end, bool reset = false); - - virtual void FlushTextMessages(CTextMessages& tMessages, bool reset); - - void Process(); - -public: - static CRenderAuxGeomD3D* Create(CD3D9Renderer& renderer) - { - return(new CRenderAuxGeomD3D(renderer)); - } - -public: - ~CRenderAuxGeomD3D(); - - void FreeMemory(); - - CAuxGeomCB* GetRenderAuxGeom(void* jobID = 0); - int GetDeviceDataSize(); - void ReleaseDeviceObjects(); - HRESULT RestoreDeviceObjects(); - void SetOrthoMode(bool enable, Matrix44A* pMatrix = 0); - void GetMemoryUsage(ICrySizer* pSizer) const; - void ReleaseShader() { SAFE_RELEASE_FORCE(m_pAuxGeomShader); } - - void* operator new(size_t s) - { - uint8* p = (uint8*) CryModuleMalloc(s + 16 + 8); - memset(p, 0, s + 16 + 8); - uint8* pRet = (uint8*) ((size_t) (p + 16 + 8) & ~0xF); - ((uint8**) pRet)[-1] = p; - return pRet; - } - - void operator delete(void* p) - { - CryModuleFree(((uint8**)p)[-1]); - } - -private: - struct SStreamBufferManager - { - public: - SStreamBufferManager(); - void Reset(); - void DiscardVB(); - void DiscardIB(); - - public: - bool m_discardVB; - uint32 m_curVBIndex; - bool m_discardIB; - uint32 m_curIBIndex; - }; - - struct SDrawObjMesh - { - SDrawObjMesh() - : m_numVertices(0) - , m_numFaces(0) - , m_pVB(0) - , m_pIB(0) - { - } - - ~SDrawObjMesh() - { - Release(); - } - - void Release(); - - int GetDeviceDataSize() - { - int nSize = 0; - nSize += _VertBufferSize(m_pVB); - nSize += _IndexBufferSize(m_pIB); - - return nSize; - } - - uint32 m_numVertices; - uint32 m_numFaces; - D3DBuffer* m_pVB; - D3DBuffer* m_pIB; - }; - - enum EAuxObjNumLOD - { - e_auxObjNumLOD = 5 - }; - - struct SMatrices - { - SMatrices() - : m_pCurTransMat(0) - { - m_matView.SetIdentity(); - m_matViewInv.SetIdentity(); - m_matProj.SetIdentity(); - m_matTrans3D.SetIdentity(); - - m_matTrans2D = Matrix44A(2, 0, 0, 0, - 0, -2, 0, 0, - 0, 0, 1, 0, - -1, 1, 0, 1); - } - - void UpdateMatrices(CD3D9Renderer& renderer); - - Matrix44A m_matView; - Matrix44A m_matViewInv; - Matrix44A m_matProj; - Matrix44A m_matTrans3D; - Matrix44A m_matTrans2D; - const Matrix44A* m_pCurTransMat; - }; - - class CAuxGeomCBCollector - { - class SThread; - - typedef std::map AUXThreadMap; - typedef std::vector AUXThreads; - typedef std::vector AUXJobs; - - - class SThread - { - typedef std::map AUXJobMap; - - CAuxGeomCB* m_cbCurrent; - AUXJobMap m_auxJobMap; - - mutable CryRWLock m_rwlLocal; - - public: - SThread() - : m_cbCurrent() {} - - CAuxGeomCB* Get(IRenderAuxGeomImpl* pRenderAuxGeomImpl, void* jobID, threadID tid) - { - if (jobID == 0 && m_cbCurrent) - { - return m_cbCurrent; - } - - m_rwlLocal.RLock(); - - AUXJobMap::const_iterator it = m_auxJobMap.find(jobID); - CAuxGeomCB* pAuxGeomCB = m_auxJobMap.end() != it ? it->second : 0; - - m_rwlLocal.RUnlock(); - - if (!pAuxGeomCB) - { - threadID mainThreadID, renderThreadID; - - gRenDev->GetThreadIDs(mainThreadID, renderThreadID); - - if (tid == renderThreadID) - { - pAuxGeomCB = new CAuxGeomCB(pRenderAuxGeomImpl); - } - else if (tid == mainThreadID) - { - pAuxGeomCB = new CAuxGeomCBMainThread(pRenderAuxGeomImpl); - } - else - { - pAuxGeomCB = new CAuxGeomCBWorkerThread(pRenderAuxGeomImpl); - } - - m_rwlLocal.WLock(); - m_auxJobMap.insert(AUXJobMap::value_type(jobID, pAuxGeomCB)); - m_rwlLocal.WUnlock(); - } - - return pAuxGeomCB; - } - - ~SThread() - { - for (AUXJobMap::iterator cbit = m_auxJobMap.begin(); cbit != m_auxJobMap.end(); ++cbit) - { - delete cbit->second; - } - } - - void Process(AUXJobs& auxJobs) - { - m_rwlLocal.RLock(); - - for (SThread::AUXJobMap::const_iterator job = m_auxJobMap.begin(); job != m_auxJobMap.end(); ++job) - { - auxJobs.push_back(job->second); - } - - m_rwlLocal.RUnlock(); - } - - void FreeMemory() - { - m_rwlLocal.WLock(); - for (AUXJobMap::const_iterator job = m_auxJobMap.begin(); job != m_auxJobMap.end(); ++job) - { - // MUST BE called after final CAuxGeomCB::Commit() - // adding data (issuing render commands) is not thread safe !!! - job->second->FreeMemory(); - } - m_rwlLocal.WUnlock(); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - m_rwlLocal.RLock(); - for (AUXJobMap::const_iterator job = m_auxJobMap.begin(); job != m_auxJobMap.end(); ++job) - { - // MUST BE called after final CAuxGeomCB::Commit() - // adding data (issuing render commands) is not thread safe !!! - job->second->GetMemoryUsage(pSizer); - } - m_rwlLocal.RUnlock(); - } - }; - - - AUXThreadMap m_auxThreadMap; - AUXThreads m_tmpThreads; - AUXJobs m_tmpJobs; - - - mutable CryRWLock m_rwGlobal; - - public: - ~CAuxGeomCBCollector() - { - for (AUXThreadMap::iterator cbit = m_auxThreadMap.begin(); cbit != m_auxThreadMap.end(); ++cbit) - { - delete cbit->second; - } - } - - CAuxGeomCB* Get(IRenderAuxGeomImpl* pRenderAuxGeomImpl, void* jobID) - { - threadID tid = CryGetCurrentThreadId(); - - m_rwGlobal.RLock(); - - AUXThreadMap::const_iterator it = m_auxThreadMap.find(tid); - SThread* auxThread = m_auxThreadMap.end() != it ? it->second : 0; - - m_rwGlobal.RUnlock(); - - if (!auxThread) - { - auxThread = new SThread; - - m_rwGlobal.WLock(); - m_auxThreadMap.insert(AUXThreadMap::value_type(tid, auxThread)); - m_rwGlobal.WUnlock(); - } - - return auxThread->Get(pRenderAuxGeomImpl, jobID, tid); - } - - void FreeMemory() - { - m_rwGlobal.WLock(); - for (AUXThreadMap::const_iterator cbit = m_auxThreadMap.begin(); cbit != m_auxThreadMap.end(); ++cbit) - { - cbit->second->FreeMemory(); - } - m_rwGlobal.WUnlock(); - } - - void Process() - { - m_rwGlobal.RLock(); - for (AUXThreadMap::const_iterator it = m_auxThreadMap.begin(); it != m_auxThreadMap.end(); ++it) - { - m_tmpThreads.push_back(it->second); - } - m_rwGlobal.RUnlock(); - - for (AUXThreads::iterator it = m_tmpThreads.begin(); it != m_tmpThreads.end(); ++it) - { - (*it)->Process(m_tmpJobs); - } - - for (AUXJobs::iterator job = m_tmpJobs.begin(); job != m_tmpJobs.end(); ++job) - { - (*job)->Process(); - } - - m_tmpThreads.clear(); - m_tmpJobs.clear(); - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - m_rwGlobal.RLock(); - for (AUXThreadMap::const_iterator it = m_auxThreadMap.begin(); it != m_auxThreadMap.end(); ++it) - { - it->second->GetMemoryUsage(pSizer); - } - m_rwGlobal.RUnlock(); - } - }; - -private: - CRenderAuxGeomD3D(CD3D9Renderer& renderer); - void DetermineAuxPrimitveFlags(uint32& d3dNumPrimDivider, eRenderPrimitiveType& d3dPrim, CAuxGeomCB::EPrimType primType) const; - void DrawAuxPrimitives(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd, const CAuxGeomCB::EPrimType& primType); - void DrawAuxIndexedPrimitives(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd, const CAuxGeomCB::EPrimType& primType); - void DrawAuxObjects(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd); - - void PrepareThickLines2D(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd); - void PrepareThickLines3D(CAuxGeomCB::AuxSortedPushBuffer::const_iterator itBegin, CAuxGeomCB::AuxSortedPushBuffer::const_iterator itEnd); - - void PrepareRendering(); - void SetShader(const SAuxGeomRenderFlags& renderFlags); - void AdjustRenderStates(const SAuxGeomRenderFlags& renderFlags); - bool BindStreams(const AZ::Vertex::Format& newVertexFormat, ID3D11Buffer* pNewVB, ID3D11Buffer* pNewIB); - - template< typename TMeshFunc > - HRESULT CreateMesh(SDrawObjMesh& mesh, TMeshFunc meshFunc); - - const Matrix44A& GetCurrentView() const; - const Matrix44A& GetCurrentViewInv() const; - const Matrix44A& GetCurrentProj() const; - const Matrix44A& GetCurrentTrans3D() const; - const Matrix44A& GetCurrentTrans2D() const; - - bool IsOrthoMode() const; - - const CAuxGeomCB::AuxVertexBuffer& GetAuxVertexBuffer() const; - const CAuxGeomCB::AuxIndexBuffer& GetAuxIndexBuffer() const; - const CAuxGeomCB::AuxDrawObjParamBuffer& GetAuxDrawObjParamBuffer() const; - const Matrix44A& GetAuxOrthoMatrix(int idx) const; - -private: - CD3D9Renderer& m_renderer; - - D3DBuffer* m_pAuxGeomVB; - D3DBuffer* m_pAuxGeomIB; - - D3DBuffer* m_pCurVB; - D3DBuffer* m_pCurIB; - - SStreamBufferManager m_auxGeomSBM; - - uint32 m_wndXRes; - uint32 m_wndYRes; - float m_aspect; - float m_aspectInv; - - SMatrices m_matrices; - - CAuxGeomCB::EPrimType m_curPrimType; - - uint8 m_curPointSize; - - int m_curTransMatrixIdx; - - CShader* m_pAuxGeomShader; - EAuxGeomPublicRenderflags_DrawInFrontMode m_curDrawInFrontMode; - - CAuxGeomCB::AuxSortedPushBuffer m_auxSortedPushBuffer; - const CAuxGeomCB::SAuxGeomCBRawData* m_pCurCBRawData; - CAuxGeomCBCollector m_auxGeomCBCol; - - int CV_r_auxGeom; - - SDrawObjMesh m_sphereObj[ e_auxObjNumLOD ]; - SDrawObjMesh m_diskObj[ e_auxObjNumLOD ]; - SDrawObjMesh m_quadObj[ e_auxObjNumLOD ]; - SDrawObjMesh m_coneObj[ e_auxObjNumLOD ]; - SDrawObjMesh m_cylinderObj[ e_auxObjNumLOD ]; - - AZ::Vertex::Format m_auxGeomPrimitiveVertexFormat = eVF_P3F_C4B_T2F; - AZ::Vertex::Format m_auxGeomObjectVertexFormat = eVF_P3F_T3F; -}; - - -inline -CRenderAuxGeomD3D::SStreamBufferManager::SStreamBufferManager() - : m_discardVB(true) - , m_curVBIndex(0) - , m_discardIB(true) - , m_curIBIndex(0) -{ -} - - -inline void -CRenderAuxGeomD3D::SStreamBufferManager::Reset() -{ - m_discardVB = true; - m_curVBIndex = 0; - m_discardIB = true; - m_curIBIndex = 0; -} - - -inline void -CRenderAuxGeomD3D::SStreamBufferManager::DiscardVB() -{ - m_discardVB = true; - m_curVBIndex = 0; -} - - -inline void -CRenderAuxGeomD3D::SStreamBufferManager::DiscardIB() -{ - m_discardIB = true; - m_curIBIndex = 0; -} - -inline void CRenderAuxGeomD3D::DetermineAuxPrimitveFlags(uint32& d3dNumPrimDivider, eRenderPrimitiveType& ePrimType, CAuxGeomCB::EPrimType primType) const -{ - switch (primType) - { - case CAuxGeomCB::e_PtList: - { - d3dNumPrimDivider = 1; - ePrimType = eptPointList; - break; - } - case CAuxGeomCB::e_LineList: - case CAuxGeomCB::e_LineListInd: - { - d3dNumPrimDivider = 2; - ePrimType = eptLineList; - break; - } - case CAuxGeomCB::e_TriList: - case CAuxGeomCB::e_TriListInd: - default: - { - d3dNumPrimDivider = 3; - ePrimType = eptTriangleList; - break; - } - } -} - -#endif // #if defined(ENABLE_RENDER_AUX_GEOM) - -#endif // D3D_RENDER_AUX_GEOM_H diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderRE.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderRE.cpp deleted file mode 100644 index b04d0fbb01..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderRE.cpp +++ /dev/null @@ -1,2466 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "../Common/RendElements/Stars.h" -#include "I3DEngine.h" -#include "../Common/PostProcess/PostProcessUtils.h" -#include "../Common/PostProcess/PostEffects.h" -#include "D3DPostProcess.h" -#include "../Common/Renderer.h" -#include "../Common/Textures/TextureManager.h" -#include - - -//======================================================================= - -bool CRESky::mfDraw(CShader* ef, SShaderPass* sfm) -{ - CD3D9Renderer* rd = gcpRendD3D; - -#if !defined(_RELEASE) - if (ef->m_eShaderType != eST_Sky) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Incorrect shader set for sky"); - return false; - } -#endif - - if (!rd->m_RP.m_pShaderResources || !rd->m_RP.m_pShaderResources->m_pSky) - { - return false; - } - - // pass 0 - skybox - SSkyInfo* pSky = rd->m_RP.m_pShaderResources->m_pSky; - if (!pSky->m_SkyBox[0]) - { - return false; - } - - float v(gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SKYBOX_MULTIPLIER)); - rd->SetMaterialColor(v, v, v, m_fAlpha); - - if (!sfm) - { - ef->FXSetTechnique(CCryNameTSCRC((uint32)0)); - } - - - uint32 nPasses = 0; - ef->FXBegin(&nPasses, FEF_DONTSETTEXTURES); - //ef->FXBegin(&nPasses, 0 ); - if (!nPasses) - { - return false; - } - ef->FXBeginPass(0); - - rd->FX_PushVP(); - rd->m_NewViewport.fMinZ = 1.0f; - rd->m_NewViewport.fMaxZ = 1.0f; - rd->m_bViewportDirty = true; - - STexState pTexState; - pTexState.SetFilterMode(FILTER_LINEAR); - pTexState.SetClampMode(1, 1, 1); - - int texStateID = CTexture::GetTexState(pTexState); - - const float fSkyBoxSize = SKY_BOX_SIZE; - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - if (rd->m_RP.m_nBatchFilter & FB_Z) - { - CTextureManager::Instance()->GetBlackTexture()->Apply(0, texStateID); - { // top - SVF_P3F_C4B_T2F data[] = - { - {Vec3(+fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(-fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(+fSkyBoxSize, +fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(-fSkyBoxSize, +fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 0)} - }; - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 4, eptTriangleStrip); - } - { // nesw - SVF_P3F_C4B_T2F data[] = - { - { Vec3(-fSkyBoxSize, -fSkyBoxSize, +fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(+fSkyBoxSize, -fSkyBoxSize, +fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(+fSkyBoxSize, -fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(+fSkyBoxSize, +fSkyBoxSize, +fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(+fSkyBoxSize, +fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(-fSkyBoxSize, +fSkyBoxSize, +fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(-fSkyBoxSize, +fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, +fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - }; - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 10, eptTriangleStrip); - } - { // b - SVF_P3F_C4B_T2F data[] = - { - {Vec3(+fSkyBoxSize, -fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(-fSkyBoxSize, -fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(+fSkyBoxSize, +fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)}, - {Vec3(-fSkyBoxSize, +fSkyBoxSize, -fSkyBoxSize), { - {0} - }, Vec2(0, 0)} - }; - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 4, eptTriangleStrip); - } - } - else - { - { // top - SVF_P3F_C4B_T2F data[] = - { - {Vec3(fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1, 1.f - 1)}, - {Vec3(-fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 1.f - 1)}, - {Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1, 1.f - 0)}, - {Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0, 1.f - 0)} - }; - - ((CTexture*)(pSky->m_SkyBox[2]))->Apply(0, texStateID); - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 4, eptTriangleStrip); - } - - Vec3 camera = iSystem->GetViewCamera().GetPosition(); - camera.z = max(0.f, camera.z); - - float fWaterCamDiff = max(0.f, camera.z - m_fTerrainWaterLevel); - - float fMaxDist = gEnv->p3DEngine->GetMaxViewDistance() / 1024.f; - float P = (fWaterCamDiff) / 128 + max(0.f, (fWaterCamDiff) * 0.03f / fMaxDist); - - P *= m_fSkyBoxStretching; - - float D = (fWaterCamDiff) / 10.0f * fSkyBoxSize / 124.0f - /*P*/ 0 + 8; - - D = max(0.f, D); - - if (m_fTerrainWaterLevel > camera.z && SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] == 0) - { - P = (fWaterCamDiff); - D = (fWaterCamDiff); - } - - float fTexOffset; - fTexOffset = 1.0f / max(pSky->m_SkyBox[1]->GetHeight(), 1); - { // s - SVF_P3F_C4B_T2F data[] = - { - { Vec3(-fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1.0, 1.f - 1.0) }, - { Vec3(fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0.0, 1.f - 1.0) }, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -P), { - {0} - }, Vec2(1.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(fSkyBoxSize, -fSkyBoxSize, -P), { - {0} - }, Vec2(0.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -D), { - {0} - }, Vec2(1.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(fSkyBoxSize, -fSkyBoxSize, -D), { - {0} - }, Vec2(0.0, 1.f - 0.5 - fTexOffset) } - }; - - ((CTexture*)(pSky->m_SkyBox[1]))->Apply(0, texStateID); - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 6, eptTriangleStrip); - } - { // e - SVF_P3F_C4B_T2F data[] = - { - { Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1.0, 1.f - 0.0) }, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0.0, 1.f - 0.0) }, - { Vec3(-fSkyBoxSize, fSkyBoxSize, -P), { - {0} - }, Vec2(1.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -P), { - {0} - }, Vec2(0.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(-fSkyBoxSize, fSkyBoxSize, -D), { - {0} - }, Vec2(1.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(-fSkyBoxSize, -fSkyBoxSize, -D), { - {0} - }, Vec2(0.0, 1.f - 0.5f + fTexOffset) } - }; - - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 6, eptTriangleStrip); - } - - fTexOffset = 1.0f / max(pSky->m_SkyBox[0]->GetHeight(), 1); - { // n - SVF_P3F_C4B_T2F data[] = - { - { Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1.0, 1.f - 1.0) }, - { Vec3(-fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0.0, 1.f - 1.0) }, - { Vec3(fSkyBoxSize, fSkyBoxSize, -P), { - {0} - }, Vec2(1.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(-fSkyBoxSize, fSkyBoxSize, -P), { - {0} - }, Vec2(0.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(fSkyBoxSize, fSkyBoxSize, -D), { - {0} - }, Vec2(1.0, 1.f - 0.5 - fTexOffset) }, - { Vec3(-fSkyBoxSize, fSkyBoxSize, -D), { - {0} - }, Vec2(0.0, 1.f - 0.5 - fTexOffset) } - }; - - ((CTexture*)(pSky->m_SkyBox[0]))->Apply(0, texStateID); - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 6, eptTriangleStrip); - } - { // w - SVF_P3F_C4B_T2F data[] = - { - { Vec3(fSkyBoxSize, -fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(1.0, 1.f - 0.0) }, - { Vec3(fSkyBoxSize, fSkyBoxSize, fSkyBoxSize), { - {0} - }, Vec2(0.0, 1.f - 0.0) }, - { Vec3(fSkyBoxSize, -fSkyBoxSize, -P), { - {0} - }, Vec2(1.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(fSkyBoxSize, fSkyBoxSize, -P), { - {0} - }, Vec2(0.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(fSkyBoxSize, -fSkyBoxSize, -D), { - {0} - }, Vec2(1.0, 1.f - 0.5f + fTexOffset) }, - { Vec3(fSkyBoxSize, fSkyBoxSize, -D), { - {0} - }, Vec2(0.0, 1.f - 0.5f + fTexOffset) } - }; - CVertexBuffer vertexBuffer(data, eVF_P3F_C4B_T2F); - rd->DrawPrimitivesInternal(&vertexBuffer, 6, eptTriangleStrip); - } - } - - rd->FX_PopVP(); - rd->FX_ResetPipe(); - - return true; -} - -static void FillSkyTextureData(CTexture* pTexture, const void* pData, const uint32 width, const uint32 height, [[maybe_unused]] const uint32 pitch) -{ - assert(pTexture && pTexture->GetWidth() == width && pTexture->GetHeight() == height); - CDeviceTexture* pDevTex = pTexture->GetDevTexture(); - assert(pDevTex); - - if (!pDevTex) - { - return; - } - - gcpRendD3D->GetDeviceContext().UpdateSubresource(pDevTex->Get2DTexture(), 0, 0, pData, sizeof(CryHalf4) * width, sizeof(CryHalf4) * width * height); -} - -bool CREHDRSky::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - CD3D9Renderer* rd(gcpRendD3D); - -#if !defined(_RELEASE) - if (ef->m_eShaderType != eST_Sky) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Incorrect shader set for sky"); - return false; - } -#endif - - - if (!rd->m_RP.m_pShaderResources || !rd->m_RP.m_pShaderResources->m_pSky) - { - return false; - } - SSkyInfo* pSky(rd->m_RP.m_pShaderResources->m_pSky); - if (!pSky->m_SkyBox[0]) - { - return false; - } - - assert(m_pRenderParams); - if (!m_pRenderParams) - { - return false; - } - - assert(m_pRenderParams->m_pSkyDomeMesh.get()); - if (!m_pRenderParams->m_pSkyDomeMesh) - { - return false; - } - - bool isNotZPass = (rd->m_RP.m_nBatchFilter & FB_Z) == 0; - if (isNotZPass) - { - // re-create sky dome textures if necessary - bool forceTextureUpdate(false); - if (!CTexture::IsTextureExist(m_pSkyDomeTextureMie) || !CTexture::IsTextureExist(m_pSkyDomeTextureRayleigh)) - { - GenerateSkyDomeTextures(SSkyLightRenderParams::skyDomeTextureWidth, SSkyLightRenderParams::skyDomeTextureHeight); - forceTextureUpdate = true; - } - - // dyn tex data lost due to device reset? - if (m_frameReset != rd->m_nFrameReset) - { - forceTextureUpdate = true; - m_frameReset = rd->m_nFrameReset; - } - - // update sky dome texture if new data is available - if (m_skyDomeTextureLastTimeStamp != m_pRenderParams->m_skyDomeTextureTimeStamp || forceTextureUpdate) - { - FillSkyTextureData(m_pSkyDomeTextureMie, m_pRenderParams->m_pSkyDomeTextureDataMie, SSkyLightRenderParams::skyDomeTextureWidth, SSkyLightRenderParams::skyDomeTextureHeight, m_pRenderParams->m_skyDomeTexturePitch); - FillSkyTextureData(m_pSkyDomeTextureRayleigh, m_pRenderParams->m_pSkyDomeTextureDataRayleigh, SSkyLightRenderParams::skyDomeTextureWidth, SSkyLightRenderParams::skyDomeTextureHeight, m_pRenderParams->m_skyDomeTexturePitch); - - // update time stamp of last update - m_skyDomeTextureLastTimeStamp = m_pRenderParams->m_skyDomeTextureTimeStamp; - } - } - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (!nPasses) - { - return false; - } - ef->FXBeginPass(0); - - I3DEngine* p3DEngine(gEnv->p3DEngine); - - rd->FX_PushVP(); - rd->m_NewViewport.fMinZ = 1.0f; - rd->m_NewViewport.fMaxZ = 1.0f; - rd->m_bViewportDirty = true; - - if (isNotZPass) - { - // shader constants -- set sky dome texture and texel size - assert(m_pSkyDomeTextureMie && m_pSkyDomeTextureMie->GetWidth() == SSkyLightRenderParams::skyDomeTextureWidth && m_pSkyDomeTextureMie->GetHeight() == SSkyLightRenderParams::skyDomeTextureHeight); - assert(m_pSkyDomeTextureRayleigh && m_pSkyDomeTextureRayleigh->GetWidth() == SSkyLightRenderParams::skyDomeTextureWidth && m_pSkyDomeTextureRayleigh->GetHeight() == SSkyLightRenderParams::skyDomeTextureHeight); - Vec4 skyDomeTexSizeVec((float) SSkyLightRenderParams::skyDomeTextureWidth, (float) SSkyLightRenderParams::skyDomeTextureHeight, 0.0f, 0.0f); - static CCryNameR Param1Name("SkyDome_TextureSize"); - ef->FXSetPSFloat(Param1Name, &skyDomeTexSizeVec, 1); - Vec4 skyDomeTexelSizeVec(1.0f / (float) SSkyLightRenderParams::skyDomeTextureWidth, 1.0f / (float) SSkyLightRenderParams::skyDomeTextureHeight, 0.0f, 0.0f); - static CCryNameR Param2Name("SkyDome_TexelSize"); - ef->FXSetPSFloat(Param2Name, &skyDomeTexelSizeVec, 1); - - // shader constants -- phase function constants - static CCryNameR Param3Name("SkyDome_PartialMieInScatteringConst"); - static CCryNameR Param4Name("SkyDome_PartialRayleighInScatteringConst"); - static CCryNameR Param5Name("SkyDome_SunDirection"); - static CCryNameR Param6Name("SkyDome_PhaseFunctionConstants"); - ef->FXSetPSFloat(Param3Name, &m_pRenderParams->m_partialMieInScatteringConst, 1); - ef->FXSetPSFloat(Param4Name, &m_pRenderParams->m_partialRayleighInScatteringConst, 1); - ef->FXSetPSFloat(Param5Name, &m_pRenderParams->m_sunDirection, 1); - ef->FXSetPSFloat(Param6Name, &m_pRenderParams->m_phaseFunctionConsts, 1); - - // shader constants -- night sky relevant constants - Vec3 nightSkyHorizonCol; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_HORIZON_COLOR, nightSkyHorizonCol); - Vec3 nightSkyZenithCol; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_ZENITH_COLOR, nightSkyZenithCol); - float nightSkyZenithColShift(p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_ZENITH_SHIFT)); - const float minNightSkyZenithGradient(-0.1f); - - static CCryNameR Param7Name("SkyDome_NightSkyColBase"); - static CCryNameR Param8Name("SkyDome_NightSkyColDelta"); - static CCryNameR Param9Name("SkyDome_NightSkyZenithColShift"); - - Vec4 nsColBase(nightSkyHorizonCol, 0); - ef->FXSetPSFloat(Param7Name, &nsColBase, 1); - Vec4 nsColDelta(nightSkyZenithCol - nightSkyHorizonCol, 0); - ef->FXSetPSFloat(Param8Name, &nsColDelta, 1); - Vec4 nsZenithColShift(1.0f / (nightSkyZenithColShift - minNightSkyZenithGradient), -minNightSkyZenithGradient / (nightSkyZenithColShift - minNightSkyZenithGradient), 0, 0); - ef->FXSetPSFloat(Param9Name, &nsZenithColShift, 1); - - CREHDRSky::SetCommonMoonParams(ef, true); - - Vec3 nightMoonColor; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_COLOR, nightMoonColor); - Vec4 nsMoonColor(nightMoonColor, 0); - static CCryNameR Param11Name("SkyDome_NightMoonColor"); - ef->FXSetPSFloat(Param11Name, &nsMoonColor, 1); - - Vec3 nightMoonInnerCoronaColor; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_INNERCORONA_COLOR, nightMoonInnerCoronaColor); - float nightMoonInnerCoronaScale(1.0f + 1000.0f * p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_INNERCORONA_SCALE)); - Vec4 nsMoonInnerCoronaColorScale(nightMoonInnerCoronaColor, nightMoonInnerCoronaScale); - static CCryNameR Param12Name("SkyDome_NightMoonInnerCoronaColorScale"); - ef->FXSetPSFloat(Param12Name, &nsMoonInnerCoronaColorScale, 1); - - Vec3 nightMoonOuterCoronaColor; - p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_OUTERCORONA_COLOR, nightMoonOuterCoronaColor); - float nightMoonOuterCoronaScale(1.0f + 1000.0f * p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_MOON_OUTERCORONA_SCALE)); - Vec4 nsMoonOuterCoronaColorScale(nightMoonOuterCoronaColor, nightMoonOuterCoronaScale); - static CCryNameR Param13Name("SkyDome_NightMoonOuterCoronaColorScale"); - ef->FXSetPSFloat(Param13Name, &nsMoonOuterCoronaColorScale, 1); - } - - HRESULT hr(S_OK); - - // commit all render changes - - // David S. workaround for Mali driver's bug - if (isNotZPass && (gRenDev->GetFeatures() & RFT_HW_ARM_MALI)) - { - uint32 newState = rd->m_RP.m_CurState; - newState |= GS_STENCIL; - rd->FX_SetStencilState( - STENC_FUNC(FSS_STENCFUNC_ALWAYS) | - STENCOP_FAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP) | - STENCOP_ZFAIL(FSS_STENCOP_KEEP), - 1, 0xFFFFFFFF, 0xFFFFFFFF); - rd->FX_SetState(newState); - } - - rd->FX_Commit(); - - // set vertex declaration and streams of sky dome - CRenderMesh* pSkyDomeMesh = static_cast(m_pRenderParams->m_pSkyDomeMesh.get()); - hr = rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); - if (!FAILED(hr)) - { - // set vertex and index buffer - pSkyDomeMesh->CheckUpdate(0); - size_t vbOffset(0); - size_t ibOffset(0); - D3DBuffer* pVB = rd->m_DevBufMan.GetD3D(pSkyDomeMesh->GetVBStream(VSF_GENERAL), &vbOffset); - D3DBuffer* pIB = rd->m_DevBufMan.GetD3D(pSkyDomeMesh->GetIBStream(), &ibOffset); - assert(pVB); - assert(pIB); - if (!pVB || !pIB) - { - return false; - } - - hr = rd->FX_SetVStream(0, pVB, vbOffset, pSkyDomeMesh->GetStreamStride(VSF_GENERAL)); - hr = rd->FX_SetIStream(pIB, ibOffset, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - // draw sky dome - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, pSkyDomeMesh->GetNumVerts(), 0, pSkyDomeMesh->GetNumInds()); - } - - ef->FXEndPass(); - ef->FXEnd(); - - if (m_pStars) - { - m_pStars->Render(m_moonTexId > 0 ? true : false); - } - - rd->FX_PopVP(); - - gcpRendD3D->FX_ResetPipe(); - - return true; -} - -void CStars::Render(bool bUseMoon) -{ - CD3D9Renderer* rd(gcpRendD3D); - - I3DEngine* p3DEngine(gEnv->p3DEngine); - float starIntensity(p3DEngine->GetGlobalParameter(E3DPARAM_NIGHSKY_STAR_INTENSITY)); - - if (m_pStarMesh && m_pShader && rd->m_RP.m_nPassGroupID == EFSLIST_GENERAL && (rd->m_RP.m_nBatchFilter & FB_GENERAL) && starIntensity > 1e-3f) - { - ////////////////////////////////////////////////////////////////////////// - // set shader - - static CCryNameTSCRC shaderTech("Stars"); - m_pShader->FXSetTechnique(shaderTech); - uint32 nPasses(0); - m_pShader->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - if (!nPasses) - { - return; - } - m_pShader->FXBeginPass(0); - - ////////////////////////////////////////////////////////////////////////// - // setup params - - int vpX(0), vpY(0), vpWidth(0), vpHeight(0); - rd->GetViewport(&vpX, &vpY, &vpWidth, &vpHeight); - const float size = 5.0f * min(1.f, min(vpWidth / 1280.f, vpHeight / 720.f)); - float flickerTime(gEnv->pTimer->GetCurrTime()); - static CCryNameR vspnStarSize("StarSize"); - Vec4 paramStarSize(size / (float)vpWidth, size / (float)vpHeight, 0, flickerTime * 0.5f); - m_pShader->FXSetVSFloat(vspnStarSize, ¶mStarSize, 1); - - static CCryNameR pspnStarIntensity("StarIntensity"); - Vec4 paramStarIntensity(starIntensity* min(1.f, size), 0, 0, 0); - m_pShader->FXSetPSFloat(pspnStarIntensity, ¶mStarIntensity, 1); - - CREHDRSky::SetCommonMoonParams(m_pShader, bUseMoon); - - ////////////////////////////////////////////////////////////////////////// - // commit & draw - - int32 nRenderState = GS_BLSRC_ONE | GS_BLDST_ONE; - - rd->FX_SetState(nRenderState); - - rd->FX_Commit(); - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3S_C4B_T2S))) - { - size_t offset(0); - //void* pVB(m_pStarVB->GetStream(VSF_GENERAL, &offset)); - //rd->FX_SetVStream(0, pVB, offset, m_VertexSize[m_pStarVB->m_vertexformat]); - CRenderMesh* pStarMesh = static_cast(m_pStarMesh.get()); - pStarMesh->CheckUpdate(0); - D3DBuffer* pVB = rd->m_DevBufMan.GetD3D(pStarMesh->GetVBStream(VSF_GENERAL), &offset); - rd->FX_SetVStream(0, pVB, offset, pStarMesh->GetStreamStride(VSF_GENERAL)); - rd->FX_SetIStream(0, 0, Index16); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - rd->FX_DrawPrimitive(eptTriangleList, 0, 6 * m_numStars); - } - - m_pShader->FXEndPass(); - m_pShader->FXEnd(); - } -} - -bool CREFogVolume::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - CD3D9Renderer* rd(gcpRendD3D); - -#if !defined(_RELEASE) - if (ef->m_eShaderType != eST_PostProcess) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Incorrect shader set for fog volume"); - return false; - } -#endif - - // shader technique is multi-pass but it doesn't need to be rendered twice. - if (rd->m_RP.m_nNumRendPasses > 1) - { - return false; - } - - // rendered to volume texture - if (CD3D9Renderer::CV_r_VolumetricFog != 0 && rd->m_RP.m_nPassGroupID == EFSLIST_FOG_VOLUME) - { - // calculate depth bounds of FogVolume. - // reusing light depth bounds code from CDeferredShading::GetLightDepthBounds(). - // This is not optimal for a box. - Matrix34 temp = m_matWSInv.GetInverted(); - AABB aabbInObj(1.0f); - AABB aabbInWS = AABB::CreateTransformedAABB(temp, aabbInObj); - float fRadius = aabbInWS.GetRadius(); - Vec3 cameraFront = rd->GetViewParameters().vZ; - cameraFront.Normalize(); - Vec3 pBounds = cameraFront * fRadius; - Vec3 pMax = m_center - pBounds; - Vec3 pMin = m_center + pBounds; - float fMinW, fMaxW; - fMaxW = rd->GetViewParameters().WorldToCamZ(pMax); - fMinW = rd->GetViewParameters().WorldToCamZ(pMin); - fMinW = max(-fMinW, 0.000001f); - fMaxW = max(-fMaxW, 0.000001f); - - - // don't render when FogVolume is out of volume texture. - Vec3 volumetricFogRaymarchEnd; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volumetricFogRaymarchEnd); - if (fMinW > volumetricFogRaymarchEnd.x) - { - return false; - } - - PROFILE_LABEL_SCOPE("FOG_VOLUME"); - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (0 == nPasses) - { - assert(0); - return(false); - } - - uint64 nFlagsShaderRTSave = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - if (m_affectsThisAreaOnly) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - // set volumetric fog injection pass - ef->FXBeginPass(1); - - if (m_viewerInsideVolume) - { - rd->SetCullMode(R_CULL_FRONT); - } - else - { - rd->SetCullMode(R_CULL_BACK); - } - rd->FX_SetState(GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST); - - // set vs constants - static CCryNameR invObjSpaceMatrixName("invObjSpaceMatrix"); - ef->FXSetVSFloat(invObjSpaceMatrixName, (const Vec4*) &m_matWSInv.m00, 3); - ef->FXSetPSFloat(invObjSpaceMatrixName, (const Vec4*) &m_matWSInv.m00, 3); - - const Vec4 cEyePosVec(m_eyePosInWS, !m_viewerInsideVolume ? 1 : 0); - static CCryNameR eyePosInWSName("eyePosInWS"); - ef->FXSetVSFloat(eyePosInWSName, &cEyePosVec, 1); - - const Vec4 cNearCutoffVec(m_nearCutoff, m_nearCutoff, m_nearCutoff, m_nearCutoff); - static CCryNameR nearCutoffName("nearCutoff"); - ef->FXSetVSFloat(nearCutoffName, &cNearCutoffVec, 1); - - // set ps constants - const Vec4 cFogColVec(m_fogColor.r, m_fogColor.g, m_fogColor.b, 0); - static CCryNameR fogColorName("fogColor"); - ef->FXSetPSFloat(fogColorName, &cFogColVec, 1); - - float globalDensity = m_globalDensity * 0.1f;// scale density to volumetric fog. - const Vec4 cGlobalDensityVec(globalDensity, 1.44269502f * globalDensity, m_noiseElapsedTime, 0); - static CCryNameR globalDensityName("globalDensity"); - ef->FXSetPSFloat(globalDensityName, &cGlobalDensityVec, 1); - - const Vec4 cDensityOffsetVec(m_densityOffset, m_densityOffset, m_densityOffset, m_densityOffset); - static CCryNameR densityOffsetName("densityOffset"); - ef->FXSetPSFloat(densityOffsetName, &cDensityOffsetVec, 1); - - uint32 nData = m_stencilRef + 1;// first ref value is reserved, see CDeferredShading::PrepareClipVolumeData function. - const Vec4 cHeigthFallOffBasePointVec(m_heightFallOffBasePoint, *alias_cast(&nData)); - static CCryNameR heightFallOffBasePointName("heightFallOffBasePoint"); - ef->FXSetPSFloat(heightFallOffBasePointName, &cHeigthFallOffBasePointVec, 1); - - const Vec4 cHeightFallOffDirScaledVec(m_heightFallOffDirScaled * 0.015625f, 0); // scale fall off ramp to volumetric fog. - static CCryNameR heightFallOffDirScaledName("heightFallOffDirScaled"); - ef->FXSetPSFloat(heightFallOffDirScaledName, &cHeightFallOffDirScaledVec, 1); - - const Vec4 cOutsideSoftEdgesLerpVec(m_softEdgesLerp.x, m_softEdgesLerp.y, 0, 0); - static CCryNameR outsideSoftEdgesLerpName("outsideSoftEdgesLerp"); - ef->FXSetPSFloat(outsideSoftEdgesLerpName, &cOutsideSoftEdgesLerpVec, 1); - - const Vec4 cEyePosInWSVec(m_eyePosInWS, 0); - ef->FXSetPSFloat(eyePosInWSName, &cEyePosInWSVec, 1); - - const Vec4 cEyePosInOSVec(m_eyePosInOS, 0); - static CCryNameR eyePosInOSName("eyePosInOS"); - ef->FXSetPSFloat(eyePosInOSName, &cEyePosInOSVec, 1); - - const Vec4 cEyePosInOSx2Vec(2.0f * m_eyePosInOS, 0); - static CCryNameR eyePosInOSx2Name("eyePosInOSx2"); - ef->FXSetPSFloat(eyePosInOSx2Name, &cEyePosInOSx2Vec, 1); - - float softEdgeLerp = (m_softEdgesLerp.x > 0.0f) ? m_softEdgesLerp.x : 0.0001f; - const Vec4 cFogVolumePos(m_center, 1.0f / softEdgeLerp); - static CCryNameR fogVolumePosName("fogVolumePos"); - ef->FXSetPSFloat(fogVolumePosName, &cFogVolumePos, 1); - - float rampDist = m_rampParams.y - m_rampParams.x; - rampDist = rampDist < 0.1f ? 0.1f : rampDist; - float invRampDist = 1.0f / rampDist; - const Vec4 cRampParams(invRampDist, -m_rampParams.x* invRampDist, m_rampParams.z, -m_rampParams.z + 1.0f); - static CCryNameR rampParamsName("rampParams"); - ef->FXSetPSFloat(rampParamsName, &cRampParams, 1); - - const float normalizeFactor = (1.0f / (1.0f + 0.5f)); - const Vec4 cWindOffset(m_windOffset.x, m_windOffset.y, m_windOffset.z, m_noiseScale* normalizeFactor); - static CCryNameR windOffsetName("windOffset"); - ef->FXSetPSFloat(windOffsetName, &cWindOffset, 1); - - const Vec4 cNoiseFreq(m_noiseFreq.x, m_noiseFreq.y, m_noiseFreq.z, m_noiseOffset); - static CCryNameR noiseFreqName("noiseFreq"); - ef->FXSetPSFloat(noiseFreqName, &cNoiseFreq, 1); - - // find minimum and maximum affected slices - const int slicesPerInstance = 28; - const int depthMaxCount = CTexture::s_ptexVolumetricFogDensity->GetDepth(); - static CCryNameR sliceBounds("sliceBounds"); - Vec4 vSliceBounds(fMinW, fMaxW, slicesPerInstance, 0.0f); - ef->FXSetGSFloat(sliceBounds, &vSliceBounds, 1); - - // commit all render changes - rd->FX_Commit(); - - // set vertex declaration and streams of skydome - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - // define bounding box geometry - const uint32 c_numBBVertices(8); - SVF_P3F_C4B_T2F bbVertices[ c_numBBVertices ] = - { - { Vec3(m_localAABB.min.x, m_localAABB.min.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.max.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.max.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.min.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.min.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.max.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.max.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.min.y, m_localAABB.max.z) } - }; - - const uint32 c_numBBIndices(36); - static const uint16 bbIndices[ c_numBBIndices ] = - { - 0, 1, 2, 0, 2, 3, - 7, 6, 5, 7, 5, 4, - 3, 2, 6, 3, 6, 7, - 4, 5, 1, 4, 1, 0, - 1, 5, 6, 1, 6, 2, - 4, 0, 3, 4, 3, 7 - }; - - // copy vertices into dynamic VB - TempDynVB::CreateFillAndBind(bbVertices, c_numBBVertices, 0); - - // copy indices into dynamic IB - TempDynIB16::CreateFillAndBind(bbIndices, c_numBBIndices); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - // use instanced draw for rendering multiple slices at once - int instanceCount = (depthMaxCount / slicesPerInstance) + ((depthMaxCount % slicesPerInstance) != 0 ? 1 : 0); - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, instanceCount, 0, c_numBBIndices, true); - } - - ef->FXEndPass(); - ef->FXEnd(); - - rd->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - - return true; - } - - PROFILE_LABEL_SCOPE("FOG_VOLUME"); - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (0 == nPasses) - { - assert(0); - return(false); - } - ef->FXBeginPass(0); - - if (m_viewerInsideVolume) - { - rd->SetCullMode(R_CULL_FRONT); - int nState = GS_COLMASK_RGB | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - nState |= m_nearCutoff ? 0 : GS_NODEPTHTEST; - rd->FX_SetState(nState); - } - else - { - rd->SetCullMode(R_CULL_BACK); - rd->FX_SetState(GS_COLMASK_RGB | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - } - - // set vs constants - static CCryNameR invObjSpaceMatrixName("invObjSpaceMatrix"); - ef->FXSetVSFloat(invObjSpaceMatrixName, (const Vec4*) &m_matWSInv.m00, 3); - - const Vec4 cEyePosVec(m_eyePosInWS, !m_viewerInsideVolume ? 1 : 0); - static CCryNameR eyePosInWSName("eyePosInWS"); - ef->FXSetVSFloat(eyePosInWSName, &cEyePosVec, 1); - - const Vec4 cEyePosInOSVec(m_eyePosInOS, 0); - static CCryNameR eyePosInOSName("eyePosInOS"); - ef->FXSetVSFloat(eyePosInOSName, &cEyePosInOSVec, 1); - - const Vec4 cNearCutoffVec(m_nearCutoff, m_nearCutoff, m_nearCutoff, m_nearCutoff); - static CCryNameR nearCutoffName("nearCutoff"); - ef->FXSetVSFloat(nearCutoffName, &cNearCutoffVec, 1); - - // set ps constants - const Vec4 cFogColVec(m_fogColor.r, m_fogColor.g, m_fogColor.b, 0); - static CCryNameR fogColorName("fogColor"); - ef->FXSetPSFloat(fogColorName, &cFogColVec, 1); - - const Vec4 cGlobalDensityVec(m_globalDensity, 1.44269502f * m_globalDensity, 0, 0); - static CCryNameR globalDensityName("globalDensity"); - ef->FXSetPSFloat(globalDensityName, &cGlobalDensityVec, 1); - - const Vec4 cDensityOffsetVec(m_densityOffset, m_densityOffset, m_densityOffset, m_densityOffset); - static CCryNameR densityOffsetName("densityOffset"); - ef->FXSetPSFloat(densityOffsetName, &cDensityOffsetVec, 1); - - const Vec4 cHeigthFallOffBasePointVec(m_heightFallOffBasePoint, 0); - static CCryNameR heightFallOffBasePointName("heightFallOffBasePoint"); - ef->FXSetPSFloat(heightFallOffBasePointName, &cHeigthFallOffBasePointVec, 1); - - const Vec4 cHeightFallOffDirScaledVec(m_heightFallOffDirScaled, 0); - static CCryNameR heightFallOffDirScaledName("heightFallOffDirScaled"); - ef->FXSetPSFloat(heightFallOffDirScaledName, &cHeightFallOffDirScaledVec, 1); - - const Vec4 cOutsideSoftEdgesLerpVec(m_softEdgesLerp.x, m_softEdgesLerp.y, 0, 0); - static CCryNameR outsideSoftEdgesLerpName("outsideSoftEdgesLerp"); - ef->FXSetPSFloat(outsideSoftEdgesLerpName, &cOutsideSoftEdgesLerpVec, 1); - - const Vec4 cEyePosInWSVec(m_eyePosInWS, 0); - ef->FXSetPSFloat(eyePosInWSName, &cEyePosInWSVec, 1); - - const Vec4 cEyePosInOSx2Vec(2.0f * m_eyePosInOS, 0); - static CCryNameR eyePosInOSx2Name("eyePosInOSx2"); - ef->FXSetPSFloat(eyePosInOSx2Name, &cEyePosInOSx2Vec, 1); - - // commit all render changes - rd->FX_Commit(); - - // set vertex declaration and streams of skydome - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - // define bounding box geometry - const uint32 c_numBBVertices(8); - SVF_P3F_C4B_T2F bbVertices[ c_numBBVertices ] = - { - { Vec3(m_localAABB.min.x, m_localAABB.min.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.max.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.max.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.min.y, m_localAABB.min.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.min.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.min.x, m_localAABB.max.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.max.y, m_localAABB.max.z) }, - { Vec3(m_localAABB.max.x, m_localAABB.min.y, m_localAABB.max.z) } - }; - - const uint32 c_numBBIndices(36); - static const uint16 bbIndices[ c_numBBIndices ] = - { - 0, 1, 2, 0, 2, 3, - 7, 6, 5, 7, 5, 4, - 3, 2, 6, 3, 6, 7, - 4, 5, 1, 4, 1, 0, - 1, 5, 6, 1, 6, 2, - 4, 0, 3, 4, 3, 7 - }; - - // copy vertices into dynamic VB - TempDynVB::CreateFillAndBind(bbVertices, c_numBBVertices, 0); - - // copy indices into dynamic IB - TempDynIB16::CreateFillAndBind(bbIndices, c_numBBIndices); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - // draw skydome - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, c_numBBVertices, 0, c_numBBIndices); - } - - ef->FXEndPass(); - ef->FXEnd(); - - return(true); -} - -bool CREVolumeObject::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - CD3D9Renderer* rd(gcpRendD3D); - I3DEngine* p3DEngine(gEnv->p3DEngine); - - uint32 nFlagsPS2 = rd->m_RP.m_PersFlags2; - rd->m_RP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (!nPasses) - { - return false; - } - - ef->FXBeginPass(0); - - if (m_nearPlaneIntersectsVolume) - { - rd->SetCullMode(R_CULL_FRONT); - rd->FX_SetState(GS_COLMASK_RGB | GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - } - else - { - rd->SetCullMode(R_CULL_BACK); - rd->FX_SetState(GS_COLMASK_RGB | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - } - - // set vs constants - static CCryNameR invObjSpaceMatrixName("invObjSpaceMatrix"); - ef->FXSetVSFloat(invObjSpaceMatrixName, (const Vec4*) &m_matInv.m00, 3); - - const Vec4 cEyePosVec(m_eyePosInWS, 0); - static CCryNameR eyePosInWSName("eyePosInWS"); - ef->FXSetVSFloat(eyePosInWSName, &cEyePosVec, 1); - - const Vec4 cViewerOutsideVec(!m_viewerInsideVolume ? 1 : 0, m_nearPlaneIntersectsVolume ? 1 : 0, 0, 0); - static CCryNameR viewerIsOutsideName("viewerIsOutside"); - ef->FXSetVSFloat(viewerIsOutsideName, &cViewerOutsideVec, 1); - - const Vec4 cEyePosInOSVec(m_eyePosInOS, 0); - static CCryNameR eyePosInOSName("eyePosInOS"); - ef->FXSetVSFloat(eyePosInOSName, &cEyePosInOSVec, 1); - - // set ps constants - const Vec4 cEyePosInWSVec(m_eyePosInWS, 0); - ef->FXSetPSFloat(eyePosInWSName, &cEyePosInWSVec, 1); - - ColorF specColor(1, 1, 1, 1); - ColorF diffColor(1, 1, 1, 1); - - CShaderResources* pRes(rd->m_RP.m_pShaderResources); - if (pRes && pRes->HasLMConstants()) - { - specColor = pRes->GetColorValue(EFTT_SPECULAR); - diffColor = pRes->GetColorValue(EFTT_DIFFUSE); - } - - Vec3 cloudShadingMultipliers; - p3DEngine->GetGlobalParameter(E3DPARAM_CLOUDSHADING_MULTIPLIERS, cloudShadingMultipliers); - - Vec3 brightColor(p3DEngine->GetSunColor() * cloudShadingMultipliers.x); - brightColor = brightColor.CompMul(Vec3(specColor.r, specColor.g, specColor.b)); - - { - static CCryNameR darkColorName("darkColor"); - const Vec4 data(0, 0, 0, m_alpha); - ef->FXSetPSFloat(darkColorName, &data, 1); - } - { - static CCryNameR brightColorName("brightColor"); - const Vec4 data(brightColor, m_alpha); - ef->FXSetPSFloat(brightColorName, &data, 1); - } - - const Vec4 cVolumeTraceStartPlane(m_volumeTraceStartPlane.n, m_volumeTraceStartPlane.d); - static CCryNameR volumeTraceStartPlaneName("volumeTraceStartPlane"); - ef->FXSetPSFloat(volumeTraceStartPlaneName, &cVolumeTraceStartPlane, 1); - - const Vec4 cScaleConsts(m_scale, 0, 0, 0); - static CCryNameR scaleConstsName("scaleConsts"); - ef->FXSetPSFloat(scaleConstsName, &cScaleConsts, 1); - - // TODO: optimize shader and remove need to pass inv obj space matrix - ef->FXSetPSFloat(invObjSpaceMatrixName, (const Vec4*) &m_matInv.m00, 3); - - - // commit all render changes - rd->FX_Commit(); - - // set vertex declaration and streams - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F))) - { - CRenderMesh* pHullMesh = static_cast(m_pHullMesh.get()); - - // set vertex and index buffer - pHullMesh->CheckUpdate(0); - size_t vbOffset(0); - size_t ibOffset(0); - D3DBuffer* pVB = rd->m_DevBufMan.GetD3D(pHullMesh->GetVBStream(VSF_GENERAL), &vbOffset); - D3DBuffer* pIB = rd->m_DevBufMan.GetD3D(pHullMesh->GetIBStream(), &ibOffset); - assert(pVB); - assert(pIB); - if (!pVB || !pIB) - { - return false; - } - - HRESULT hr(S_OK); - hr = rd->FX_SetVStream(0, pVB, vbOffset, pHullMesh->GetStreamStride(VSF_GENERAL)); - hr = rd->FX_SetIStream(pIB, ibOffset, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - rd->FX_DrawIndexedPrimitive(pHullMesh->GetPrimitiveType(), 0, 0, pHullMesh->GetNumVerts(), 0, pHullMesh->GetNumInds()); - } - - ef->FXEndPass(); - ef->FXEnd(); - - rd->FX_ResetPipe(); - rd->m_RP.m_PersFlags2 = nFlagsPS2; - - return true; -} - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) -bool CREPrismObject::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (!nPasses) - { - return false; - } - - ef->FXBeginPass(0); - - // commit all render changes - // rd->FX_Commit(); - - static SVF_P3F_C4B_T2F pScreenQuad[] = - { - { Vec3(0, 0, 0), { - {0} - }, Vec2(0, 0) }, - { Vec3(0, 1, 0), { - {0} - }, Vec2(0, 1) }, - { Vec3(1, 0, 0), { - {0} - }, Vec2(1, 0) }, - { Vec3(1, 1, 0), { - {0} - }, Vec2(1, 1) }, - }; - - pScreenQuad[0].xyz = Vec3(0, 0, 0); - pScreenQuad[1].xyz = Vec3(0, 1, 0); - pScreenQuad[2].xyz = Vec3(1, 0, 0); - pScreenQuad[3].xyz = Vec3(1, 1, 0); - - CVertexBuffer strip(pScreenQuad, eVF_P3F_C4B_T2F); - gcpRendD3D->DrawPrimitivesInternal(&strip, 4, eptTriangleStrip); - - ef->FXEndPass(); - ef->FXEnd(); - - return true; -} -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - - -bool CREWaterVolume::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - assert(m_pParams); - if (!m_pParams) - { - return false; - } - - CD3D9Renderer* rd(gcpRendD3D); - - IF (ef->m_eShaderType != eST_Water, 0) - { -#if !defined(_RELEASE) - // CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_ERROR, "Incorrect shader set for water / water fog volume"); -#endif - return false; - } - - //@NOTE: CV_r_watercaustics will be removed when the infinite ocean component feature toggle is removed. - bool bCaustics = CRenderer::CV_r_watercaustics && - CRenderer::CV_r_watervolumecaustics && - m_pParams->m_caustics && - (-m_pParams->m_fogPlane.d >= 1.0f); // unfortunately packing to RG8 limits us to heights over 1 meter, so we just disable if volume goes below. - - // Don't render caustics pass unless needed. - if ((rd->m_RP.m_nBatchFilter & FB_WATER_CAUSTIC) && !bCaustics) - { - return false; - } - - uint64 nFlagsShaderRTSave = gcpRendD3D->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE5]); - const bool renderFogShadowWater = (CRenderer::CV_r_FogShadowsWater > 0) && (m_pParams->m_fogShadowing > 0.01f); - - Vec4 volFogShadowRange(0, 0, clamp_tpl(m_pParams->m_fogShadowing, 0.0f, 1.0f), 1.0f - clamp_tpl(m_pParams->m_fogShadowing, 0.0f, 1.0f)); -#if defined(VOLUMETRIC_FOG_SHADOWS) - const bool renderFogShadow = gcpRendD3D->m_bVolFogShadowsEnabled; - { - Vec3 volFogShadowRangeP; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_RANGE, volFogShadowRangeP); - volFogShadowRangeP.x = clamp_tpl(volFogShadowRangeP.x, 0.01f, 1.0f); - volFogShadowRange.x = volFogShadowRangeP.x; - volFogShadowRange.y = volFogShadowRangeP.y; - } - - if (renderFogShadow) - { - gcpRendD3D->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - if (!renderFogShadowWater) // set up forward shadows in case they will not be set up below - { - rd->FX_SetupShadowsForTransp(); - } - -#endif - - if (renderFogShadowWater) - { - rd->FX_SetupShadowsForTransp(); - gcpRendD3D->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - Matrix44A origMatProj; - Matrix44A origMatView; - - origMatProj.SetIdentity(); - origMatView.SetIdentity(); - - if (!m_drawWaterSurface && m_pParams->m_viewerInsideVolume) - { - // set projection matrix for full screen quad - origMatProj = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - Matrix44A* m = &rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj; - mathMatrixOrthoOffCenterLH(m, -1, 1, -1, 1, -1, 1); - if (SRendItem::m_RecurseLevel[rd->m_RP.m_nProcessThreadID] <= 0) - { - const SRenderTileInfo* rti = rd->GetRenderTileInfo(); - if (rti->nGridSizeX > 1.f || rti->nGridSizeY > 1.f) - { // shift and scale viewport - m->m00 *= rti->nGridSizeX; - m->m11 *= rti->nGridSizeY; - m->m30 = -((rti->nGridSizeX - 1.f) - rti->nPosX * 2.0f); - m->m31 = ((rti->nGridSizeY - 1.f) - rti->nPosY * 2.0f); - } - } - - // set view matrix to identity - origMatView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - } - - // render - uint32 nPasses(0); - ef->FXBegin(&nPasses, 0); - if (0 == nPasses) - { - // reset matrices - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - return false; - } - ef->FXBeginPass(0); - - // set ps constants - if (!m_drawWaterSurface || m_drawFastPath && !m_pParams->m_viewerInsideVolume) - { - if (!m_pOceanParams) - { - // fog color & density - const Vec3 col = m_pParams->m_fogColorAffectedBySun ? m_pParams->m_fogColor.CompMul(gEnv->p3DEngine->GetSunColor()) : m_pParams->m_fogColor; - const Vec4 fogColorDensity(col, 1.44269502f * m_pParams->m_fogDensity); // log2(e) = 1.44269502 - static CCryNameR Param1Name("cFogColorDensity"); - ef->FXSetPSFloat(Param1Name, &fogColorDensity, 1); - } - else - { - // fog color & density - Vec4 fogColorDensity(m_pOceanParams->m_fogColor.CompMul(gEnv->p3DEngine->GetSunColor()), 1.44269502f * m_pOceanParams->m_fogDensity); // log2(e) = 1.44269502 - static CCryNameR Param1Name("cFogColorDensity"); - ef->FXSetPSFloat(Param1Name, &fogColorDensity, 1); - - // fog color shallow & water level - Vec4 fogColorShallowWaterLevel(m_pOceanParams->m_fogColorShallow.CompMul(gEnv->p3DEngine->GetSunColor()), -m_pParams->m_fogPlane.d); - static CCryNameR Param2Name("cFogColorShallowWaterLevel"); - ef->FXSetPSFloat(Param2Name, &fogColorShallowWaterLevel, 1); - - if (m_pParams->m_viewerInsideVolume) - { - // under water in-scattering constant term = exp2( -fogDensity * ( waterLevel - cameraPos.z) ) - float c(expf(-m_pOceanParams->m_fogDensity * (-m_pParams->m_fogPlane.d - rd->GetCamera().GetPosition().z))); - Vec4 underWaterInScatterConst(c, 0, 0, 0); - static CCryNameR Param3Name("cUnderWaterInScatterConst"); - ef->FXSetPSFloat(Param3Name, &underWaterInScatterConst, 1); - } - } - - Vec4 fogPlane(m_pParams->m_fogPlane.n.x, m_pParams->m_fogPlane.n.y, m_pParams->m_fogPlane.n.z, m_pParams->m_fogPlane.d); - static CCryNameR Param4Name("cFogPlane"); - ef->FXSetPSFloat(Param4Name, &fogPlane, 1); - - if (m_pParams->m_viewerInsideVolume) - { - Vec4 perpDist(m_pParams->m_fogPlane | rd->GetViewParameters().vOrigin, 0, 0, 0); - static CCryNameR Param5Name("cPerpDist"); - ef->FXSetPSFloat(Param5Name, &perpDist, 1); - } - } - - // Disable fog when inside volume or when not using fast path - could assign custom RT flag for this instead - if (m_drawFastPath && m_pParams->m_viewerInsideVolume || !m_drawFastPath && m_drawWaterSurface) - { - // fog color & density - const Vec4 fogColorDensity(0, 0, 0, 0); - static CCryNameR Param1Name("cFogColorDensity"); - ef->FXSetPSFloat(Param1Name, &fogColorDensity, 1); - } - - { - static CCryNameR pszParamBBoxMin("vBBoxMin"); - static CCryNameR pszParamBBoxMax("vBBoxMax"); - const Vec4 vBBoxMin(m_pParams->m_WSBBox.min, 1.0f); - const Vec4 vBBoxMax(m_pParams->m_WSBBox.max, 1.0f); - ef->FXSetPSFloat(pszParamBBoxMin, &vBBoxMin, 1); - ef->FXSetPSFloat(pszParamBBoxMax, &vBBoxMax, 1); - } - - // set vs constants - Vec4 viewerColorToWaterPlane(m_pParams->m_viewerCloseToWaterPlane && m_pParams->m_viewerCloseToWaterVolume ? 0.0f : 1.0f, - m_pParams->m_viewerCloseToWaterVolume ? 2.0f * 2.0f : 0.0f, - 0.0f, - 0.0f); - static CCryNameR Param6Name("cViewerColorToWaterPlane"); - ef->FXSetVSFloat(Param6Name, &viewerColorToWaterPlane, 1); - - if (bCaustics) - { - Vec4 pCausticsParams = Vec4(0.0f /* Not used */, m_pParams->m_causticIntensity, m_pParams->m_causticTiling, m_pParams->m_causticHeight); - - static CCryNameR m_pCausticParams("vCausticParams"); - ef->FXSetPSFloat(m_pCausticParams, &pCausticsParams, 1); - } - - static CCryNameR volFogShadowRangeN("volFogShadowRange"); - ef->FXSetPSFloat(volFogShadowRangeN, &volFogShadowRange, 1); - - if (renderFogShadowWater) - { - //set world basis - float maskRTWidth = float(rd->GetWidth()); - float maskRTHeight = float(rd->GetHeight()); - - Vec4 vScreenScale(1.0f / maskRTWidth, 1.0f / maskRTHeight, 0.0f, 0.0f); - - Vec4r vWBasisX, vWBasisY, vWBasisZ, vCamPos; - Vec4 vParamValue, vMag; - CShadowUtils::ProjectScreenToWorldExpansionBasis(rd->m_IdentityMatrix, rd->GetCamera(), Vec2(rd->m_TemporalJitterClipSpace.x, rd->m_TemporalJitterClipSpace.y), maskRTWidth, maskRTHeight, vWBasisX, vWBasisY, vWBasisZ, vCamPos, true, NULL); - - Vec4 vWorldBasisX = vWBasisX; - Vec4 vWorldBasisY = vWBasisY; - Vec4 vWorldBasisZ = vWBasisZ; - Vec4 vCameraPos = vCamPos; - - static CCryNameR m_pScreenScale("ScreenScale"); - static CCryNameR m_pCamPos("vCamPos"); - static CCryNameR m_pWBasisX("vWBasisX"); - static CCryNameR m_pWBasisY("vWBasisY"); - static CCryNameR m_pWBasisZ("vWBasisZ"); - - ef->FXSetPSFloat(m_pScreenScale, &vScreenScale, 1); - ef->FXSetPSFloat(m_pCamPos, &vCameraPos, 1); - ef->FXSetPSFloat(m_pWBasisX, &vWorldBasisX, 1); - ef->FXSetPSFloat(m_pWBasisY, &vWorldBasisY, 1); - ef->FXSetPSFloat(m_pWBasisZ, &vWorldBasisZ, 1); - } - -#if defined(VOLUMETRIC_FOG_SHADOWS) - if (renderFogShadow) - { - Vec3 volFogShadowDarkeningP; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG_SHADOW_DARKENING, volFogShadowDarkeningP); - - Vec4 volFogShadowDarkening(volFogShadowDarkeningP, 0); - static CCryNameR volFogShadowDarkeningN("volFogShadowDarkening"); - ef->FXSetPSFloat(volFogShadowDarkeningN, &volFogShadowDarkening, 1); - - const float aSun = (1.0f - clamp_tpl(volFogShadowDarkeningP.y, 0.0f, 1.0f)) * 1.0f; - const float bSun = 1.0f - aSun; - const float aAmb = (1.0f - clamp_tpl(volFogShadowDarkeningP.z, 0.0f, 1.0f)) * 0.4f; - const float bAmb = 1.0f - aAmb; - - Vec4 volFogShadowDarkeningSunAmb(aSun, bSun, aAmb, bAmb); - static CCryNameR volFogShadowDarkeningSunAmbN("volFogShadowDarkeningSunAmb"); - ef->FXSetPSFloat(volFogShadowDarkeningSunAmbN, &volFogShadowDarkeningSunAmb, 1); - } -#endif - - if (m_drawWaterSurface || !m_pParams->m_viewerInsideVolume) - { - // copy vertices into dynamic VB - TempDynVB::CreateFillAndBind(m_pParams->m_pVertices, m_pParams->m_numVertices, 0); - - // copy indices into dynamic IB - TempDynIB16::CreateFillAndBind(m_pParams->m_pIndices, m_pParams->m_numIndices); - - // set vertex declaration - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - // commit all render changes - rd->FX_Commit(); - - // draw - eRenderPrimitiveType eType = eptTriangleList; - if (CHWShader_D3D::s_pCurInstHS) - { - eType = ept3ControlPointPatchList; - } - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - rd->FX_DrawIndexedPrimitive(eType, 0, 0, m_pParams->m_numVertices, 0, m_pParams->m_numIndices); - } - } - else - { - // copy vertices into dynamic VB - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_T3F* pVB = vb.Lock(); - - Vec3 coords[8]; - rd->GetViewParameters().CalcVerts(coords); - - pVB[0].p.x = -1; - pVB[0].p.y = 1; - pVB[0].p.z = 0.5f; - pVB[0].st = coords[5] - coords[1]; - - pVB[1].p.x = 1; - pVB[1].p.y = 1; - pVB[1].p.z = 0.5f; - pVB[1].st = coords[4] - coords[0]; - - pVB[2].p.x = -1; - pVB[2].p.y = -1; - pVB[2].p.z = 0.5f; - pVB[2].st = coords[6] - coords[2]; - - pVB[3].p.x = 1; - pVB[3].p.y = -1; - pVB[3].p.z = 0.5f; - pVB[3].st = coords[7] - coords[3]; - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - // set vertex declaration - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - // commit all render changes - rd->FX_Commit(); - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - rd->FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - // reset matrices - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matView = origMatView; - rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_matProj = origMatProj; - } - - ef->FXEndPass(); - ef->FXEnd(); - - gcpRendD3D->m_RP.m_FlagsShader_RT = nFlagsShaderRTSave; - - return true; -} - -void CREWaterOcean::Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof) -{ - if (!nVerticesCount || !pVertices || !nIndicesCount || !pIndices || (nIndexSizeof != 2 && nIndexSizeof != 4)) - { - return; - } - - ReleaseOcean(); - - m_nVerticesCount = nVerticesCount; - m_nIndicesCount = nIndicesCount; - m_nIndexSizeof = nIndexSizeof; - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Create vertex buffer - ////////////////////////////////////////////////////////////////////////////////////////////////// - { - D3DBuffer* pVertexBuffer = 0; - D3D11_BUFFER_DESC BufDesc; - - uint32 size = nVerticesCount * sizeof(SVF_P3F_C4B_T2F); - BufDesc.ByteWidth = size; - BufDesc.Usage = D3D11_USAGE_DEFAULT; - BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - BufDesc.CPUAccessFlags = 0; - BufDesc.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA pInitData; - pInitData.pSysMem = pVertices; - pInitData.SysMemPitch = 0; - pInitData.SysMemSlicePitch = 0; - - gcpRendD3D->m_DevMan.CreateD3D11Buffer(&BufDesc, &pInitData, &pVertexBuffer, "OceanMesh"); - m_pVertices = pVertexBuffer; - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Create index buffer - ////////////////////////////////////////////////////////////////////////////////////////////////// - { - D3DBuffer* pIndexBuffer = 0; - const uint32 size = nIndicesCount * m_nIndexSizeof; - - D3D11_BUFFER_DESC BufDesc; - BufDesc.ByteWidth = size; - BufDesc.Usage = D3D11_USAGE_DEFAULT; - BufDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - BufDesc.CPUAccessFlags = 0; - BufDesc.MiscFlags = 0; - - D3D11_SUBRESOURCE_DATA pInitData; - pInitData.pSysMem = pIndices; - pInitData.SysMemPitch = 0; - pInitData.SysMemSlicePitch = 0; - - gcpRendD3D->m_DevMan.CreateD3D11Buffer(&BufDesc, &pInitData, &pIndexBuffer, "OceanMesh"); - m_pIndices = pIndexBuffer; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CREWaterOcean::FrameUpdate() -{ - static bool bInitialize = true; - if (bInitialize) - { - WaterSimMgr()->Create(1.0, 1.0f, 1.0f); - bInitialize = false; - } - - const int nGridSize = 64; - - // Update Vertex Texture - if (!CTexture::IsTextureExist(CTexture::s_ptexWaterOcean)) - { - CTexture::s_ptexWaterOcean->Create2DTexture(nGridSize, nGridSize, 1, - FT_DONT_RELEASE | FT_NOMIPS | FT_STAGE_UPLOAD, - 0, eTF_R32G32B32A32F, eTF_R32G32B32A32F); - } - - CTexture* pTexture = CTexture::s_ptexWaterOcean; - - // Copy data.. - if (CTexture::IsTextureExist(pTexture)) - { - Vec4* pDispGrid = WaterSimMgr()->GetDisplaceGrid(); - if (pDispGrid == nullptr) - { - return; - } - - const auto oceanData = gEnv->p3DEngine->GetOceanAnimationParams(); - const float fUpdateTime = 0.125f * gEnv->pTimer->GetCurrTime() * oceanData.fWavesSpeed; - int nFrameID = gRenDev->GetFrameID(); - void* pRawPtr = NULL; - WaterSimMgr()->Update(nFrameID, fUpdateTime, false, pRawPtr); - - uint32 width = nGridSize; - uint32 height = nGridSize; - - STALL_PROFILER("update subresource") - CDeviceTexture * pDevTex = pTexture->GetDevTexture(); - pDevTex->UploadFromStagingResource(0, [=](void* pData, [[maybe_unused]] uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - cryMemcpy(pData, pDispGrid, 4 * width * height * sizeof(f32)); - return true; - }); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CREWaterOcean::ReleaseOcean() -{ - ID3D11Buffer* pVertices = (ID3D11Buffer*)m_pVertices; - ID3D11Buffer* pIndices = (ID3D11Buffer*)m_pIndices; - - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(pVertices); - m_pVertices = nullptr; - gcpRendD3D->m_DevMan.ReleaseD3D11Buffer(pIndices); - m_pIndices = nullptr; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool CREWaterOcean::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - if (!m_nVerticesCount || !m_nIndicesCount || !m_pVertices || !m_pIndices) - { - return false; - } - - CD3D9Renderer* rd(gcpRendD3D); - - if (CTexture::s_ptexWaterOcean) - { - CTexture::s_ptexWaterOcean->SetFilterMode(FILTER_LINEAR); - CTexture::s_ptexWaterOcean->SetClampingMode(0, 0, 1); - CTexture::s_ptexWaterOcean->UpdateTexStates(); - } - - if (CTexture::s_ptexWaterRipplesDDN) - { - CTexture::s_ptexWaterRipplesDDN->SetVertexTexture(true); - CTexture::s_ptexWaterRipplesDDN->SetFilterMode(FILTER_LINEAR); - CTexture::s_ptexWaterRipplesDDN->SetClampingMode(0, 0, 1); - CTexture::s_ptexWaterRipplesDDN->UpdateTexStates(); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////// - - uint64 nFlagsShaderRTprev = rd->m_RP.m_FlagsShader_RT; - - uint32 nFlagsPF2prev = rd->m_RP.m_PersFlags2; - rd->m_RP.m_PersFlags2 &= ~(RBPF2_COMMIT_PF | RBPF2_COMMIT_CM); - - // render - uint32 nPasses(0); - - - // set streams - HRESULT hr(S_OK); - - STexStageInfo pPrevTexState0 = CTexture::s_TexStages[0]; - STexStageInfo pPrevTexState1 = CTexture::s_TexStages[1]; - - STexState pState(FILTER_BILINEAR, false); - const int texStateID(CTexture::GetTexState(pState)); - - - N3DEngineCommon::SOceanInfo& OceanInfo = gRenDev->m_p3DEngineCommon.m_OceanInfo; - - uint32 nPrevStateOr = rd->m_RP.m_StateOr; - uint32 nPrevStateAnd = rd->m_RP.m_StateAnd; - - ef->FXSetTechnique("Water"); - ef->FXBegin(&nPasses, 0); - - if (0 == nPasses) - { - return false; - } - - if (gRenDev->GetViewParameters().vOrigin.z > OceanInfo.m_fWaterLevel) - { - rd->m_RP.m_StateAnd |= GS_DEPTHFUNC_MASK; - rd->m_RP.m_StateOr |= GS_DEPTHWRITE | GS_DEPTHFUNC_LEQUAL; - } - - ef->FXBeginPass(0); - - if (CTexture::s_ptexWaterOcean) - { - CTexture::s_ptexWaterOcean->SetVertexTexture(true); - CTexture::s_ptexWaterOcean->Apply(0, texStateID); - CTexture::s_ptexWaterOcean->SetVertexTexture(false); - } - - if (CTexture::s_ptexWaterRipplesDDN) - { - CTexture::s_ptexWaterRipplesDDN->SetVertexTexture(true); - CTexture::s_ptexWaterRipplesDDN->Apply(1, texStateID); - CTexture::s_ptexWaterRipplesDDN->SetVertexTexture(false); - } - - hr = rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F); - if (!FAILED(hr)) - { - // commit all render changes - rd->FX_Commit(); - - hr = rd->FX_SetVStream(0, m_pVertices, 0, sizeof(SVF_P3F_C4B_T2F)); - hr = rd->FX_SetIStream(m_pIndices, 0, (m_nIndexSizeof == 2 ? Index16 : Index32)); - - eRenderPrimitiveType eType = rd->m_bUseWaterTessHW ? eptTriangleList : eptTriangleStrip; -#ifdef WATER_TESSELLATION_RENDERER - if (CHWShader_D3D::s_pCurInstHS) - { - eType = ept3ControlPointPatchList; - } -#endif - - rd->GetPerInstanceConstantBufferPool().SetConstantBuffer(rd->m_RP.m_RIs[0][0]); - - rd->FX_DrawIndexedPrimitive(eType, 0, 0, m_nVerticesCount, 0, m_nIndicesCount); - } - - ef->FXEndPass(); - ef->FXEnd(); - - rd->m_RP.m_StateOr = nPrevStateOr; - rd->m_RP.m_StateAnd = nPrevStateAnd; - - CTexture::s_TexStages[0] = pPrevTexState0; - CTexture::s_TexStages[1] = pPrevTexState1; - - gcpRendD3D->FX_ResetPipe(); - - rd->m_RP.m_FlagsShader_RT = nFlagsShaderRTprev; - rd->m_RP.m_PersFlags2 = nFlagsPF2prev; - - return true; -} - -//========================================================================================= - -CREOcclusionQuery::~CREOcclusionQuery() -{ - mfReset(); -} - -void CREOcclusionQuery::mfReset() -{ - ID3D11Query* pVizQuery = (ID3D11Query*)m_nOcclusionID; - SAFE_RELEASE(pVizQuery); - - m_nOcclusionID = 0; - m_nDrawFrame = 0; - m_nCheckFrame = 0; - m_nVisSamples = 0; - m_bSucceeded = false; -} - -uint32 CREOcclusionQuery::m_nQueriesPerFrameCounter = 0; -uint32 CREOcclusionQuery::m_nReadResultNowCounter = 0; -uint32 CREOcclusionQuery::m_nReadResultTryCounter = 0; - -bool CREOcclusionQuery::mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - PROFILE_FRAME(CREOcclusionQuery::mfDraw); - - CD3D9Renderer* r = gcpRendD3D; - - gRenDev->m_cEF.mfRefreshSystemShader("OcclusionTest", CShaderMan::s_ShaderOcclTest); - - CShader* pSh = CShaderMan::s_ShaderOcclTest; - if (!pSh || pSh->m_HWTechniques.empty()) - { - return false; - } - - if (!(r->m_Features & RFT_OCCLUSIONTEST)) - { // If not supported - m_nVisSamples = r->GetWidth() * r->GetHeight(); - return true; - } - - - if (!m_nOcclusionID) - { - HRESULT hr; - ID3D11Query* pVizQuery = NULL; - D3D11_QUERY_DESC qdesc; - qdesc.MiscFlags = 0; //D3D11_QUERY_MISC_PREDICATEHINT; - qdesc.Query = D3D11_QUERY_OCCLUSION; - hr = r->GetDevice().CreateQuery(&qdesc, &pVizQuery); - if (pVizQuery) - { - m_nOcclusionID = (UINT_PTR)pVizQuery; - } - } - - - if (!m_nDrawFrame) // only allow queries update, if finished already with previous query - { // draw test box - if (m_nOcclusionID) - { - D3DQuery* pVizQuery = (D3DQuery*)m_nOcclusionID; - r->GetDeviceContext().Begin(pVizQuery); - - const t_arrDeferredMeshIndBuff& arrDeferredInds = r->GetDeferredUnitBoxIndexBuffer(); - const t_arrDeferredMeshVertBuff& arrDeferredVerts = r->GetDeferredUnitBoxVertexBuffer(); - - //allocate vertices - TempDynVB::CreateFillAndBind(&arrDeferredVerts[0], arrDeferredVerts.size(), 0); - - //allocate indices - TempDynIB16::CreateFillAndBind(&arrDeferredInds[0], arrDeferredInds.size()); - - Matrix44A origMatView = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_matView; - Matrix34 mat; - mat.SetIdentity(); - mat.SetScale(m_vBoxMax - m_vBoxMin, m_vBoxMin); - - const Matrix44 cTransPosed = Matrix44(mat).GetTransposed(); - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_matView = cTransPosed * r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_matView; - - uint32 nPasses; - pSh->FXSetTechnique("General"); - pSh->FXBegin(&nPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - pSh->FXBeginPass(0); - - int nPersFlagsSave = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags; - int nObjFlagsSave = r->m_RP.m_ObjFlags; - CRenderObject* pCurObjectSave = r->m_RP.m_pCurObject; - CShader* pShaderSave = r->m_RP.m_pShader; - SShaderTechnique* pCurTechniqueSave = r->m_RP.m_pCurTechnique; - - if (r->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F) == S_OK) - { - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_FP_DIRTY; - r->m_RP.m_pCurObject = r->m_RP.m_pIdendityRenderObject; - r->m_RP.m_pShader = pSh; - r->m_RP.m_pCurTechnique = pSh->m_HWTechniques[0]; - r->FX_SetState(GS_COLMASK_NONE | GS_DEPTHFUNC_LEQUAL); - r->SetCullMode(R_CULL_NONE); - - r->FX_Commit(); - - r->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, arrDeferredVerts.size(), 0, arrDeferredInds.size()); - } - - pSh->FXEndPass(); - pSh->FXEnd(); - - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_matView = origMatView; - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags = nPersFlagsSave; - r->m_RP.m_ObjFlags = nObjFlagsSave; - r->m_RP.m_pCurObject = pCurObjectSave; - r->m_RP.m_pShader = pShaderSave; - r->m_RP.m_pCurTechnique = pCurTechniqueSave; - - r->GetDeviceContext().End(pVizQuery); - - CREOcclusionQuery::m_nQueriesPerFrameCounter++; - m_nDrawFrame = 1; - } - - m_bSucceeded = false; - // m_nDrawFrame = nFrame; - } - - return true; -} - -bool CREOcclusionQuery::mfReadResult_Now() -{ - int nFrame = gcpRendD3D->GetFrameID(); - - ID3D11Query* pVizQuery = (ID3D11Query*)m_nOcclusionID; - if (pVizQuery) - { - HRESULT hRes = S_FALSE; - while (hRes == S_FALSE) - { - hRes = gcpRendD3D->GetDeviceContext().GetData(pVizQuery, (void*) &m_nVisSamples, sizeof(uint64), 0); - } - - if (hRes == S_OK) - { - m_nDrawFrame = 0; - m_nCheckFrame = nFrame; - } - } - - m_nReadResultNowCounter++; - - m_bSucceeded = (m_nCheckFrame == nFrame); - return m_bSucceeded; -} - -bool CREOcclusionQuery::mfReadResult_Try(uint32 nDefaultNumSamples) -{ - return gRenDev->m_pRT->RC_OC_ReadResult_Try(nDefaultNumSamples, this); -} -bool CREOcclusionQuery::RT_ReadResult_Try([[maybe_unused]] uint32 nDefaultNumSamples) -{ - PROFILE_FRAME(CREOcclusionQuery::mfReadResult_Try); - - int nFrame = gcpRendD3D->GetFrameID(); - - ID3D11Query* pVizQuery = (ID3D11Query*)m_nOcclusionID; - if (pVizQuery) - { - HRESULT hRes = S_FALSE; - hRes = gcpRendD3D->GetDeviceContext().GetData(pVizQuery, (void*) &m_nVisSamples, sizeof(uint64), D3D11_ASYNC_GETDATA_DONOTFLUSH); - - if (hRes == S_OK) - { - m_nDrawFrame = 0; - m_nCheckFrame = nFrame; - } - } - - m_nReadResultTryCounter++; - -#ifdef DO_RENDERLOG - if (!m_nVisSamples) - { - if (CRenderer::CV_r_log) - { - gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "OcclusionQuery: Water is not visible\n"); - } - } - else - { - if (CRenderer::CV_r_log) - { - gRenDev->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "OcclusionQuery: Water is visible (%d samples)\n", m_nVisSamples); - } - } -#endif - - m_bSucceeded = (m_nCheckFrame == nFrame); - return m_bSucceeded; -} - -//=================================================================================== - -void CRenderMesh::DrawImmediately() -{ - CD3D9Renderer* rd = gcpRendD3D; - - HRESULT hr = rd->FX_SetVertexDeclaration(0, _GetVertexFormat()); - - if (FAILED(hr)) - { - CRY_ASSERT(!"CRenderMesh::DrawImmediately failed"); - return; - } - - // set vertex and index buffer - CheckUpdate(0); - - size_t vbOffset(0); - size_t ibOffset(0); - D3DBuffer* pVB = rd->m_DevBufMan.GetD3D(GetVBStream(VSF_GENERAL), &vbOffset); - D3DBuffer* pIB = rd->m_DevBufMan.GetD3D(GetIBStream(), &ibOffset); - assert(pVB); - assert(pIB); - - if (!pVB || !pIB) - { - assert(!"CRenderMesh::DrawImmediately failed"); - return; - } - - hr = rd->FX_SetVStream(0, pVB, vbOffset, GetStreamStride(VSF_GENERAL)); - hr = rd->FX_SetIStream(pIB, ibOffset, (sizeof(vtx_idx) == 2 ? Index16 : Index32)); - - // draw indexed mesh - rd->FX_DrawIndexedPrimitive(GetPrimitiveType(), 0, 0, GetNumVerts(), 0, GetNumInds()); -} - -//========================================================================================= - -bool CREHDRProcess::mfDraw([[maybe_unused]] CShader* ef, [[maybe_unused]] SShaderPass* sfm) -{ - CD3D9Renderer* rd = gcpRendD3D; - if (!(rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_HDR)) - { - return false; - } - assert(rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_PersFlags & RBPF_HDR || rd->m_RP.m_CurState & GS_WIREFRAME); - - rd->FX_HDRPostProcessing(); - return true; -} - -bool CREBeam::mfDraw(CShader* ef, [[maybe_unused]] SShaderPass* sl) -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DRenderRE_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - CD3D9Renderer* rd = gcpRendD3D; - int nThreadID = rd->m_RP.m_nProcessThreadID; - - if (SRendItem::m_RecurseLevel[nThreadID] != 0) - { - return false; - } - - PROFILE_LABEL_SCOPE("LIGHT BEAM"); - - STexState pState(FILTER_BILINEAR, true); - const int texStateID(CTexture::GetTexState(pState)); - - STexState pStatePoint(FILTER_POINT, true); - const int texStateIDPoint(CTexture::GetTexState(pStatePoint)); - - bool bViewerInsideCone = false; - - CTexture* pLowResRT = CTexture::s_ptexZTargetScaled2; // CTexture::s_ptexBackBufferScaled[1]; - CTexture* pLowResRTDepth = CTexture::s_ptexDepthBufferQuarter; - - SDepthTexture D3dDepthSurface; - SDepthTexture* pCurrDepthSurf = NULL; - -#if D3DRENDERRE_CPP_TRAIT_MFDRAW_SETDEPTHSURF // Depth surface nastiness - if (CTexture::IsTextureExist(pLowResRTDepth)) - { - D3dDepthSurface.nWidth = pLowResRTDepth->GetWidth(); - D3dDepthSurface.nHeight = pLowResRTDepth->GetHeight(); - D3dDepthSurface.nFrameAccess = -1; - D3dDepthSurface.bBusy = false; - - D3dDepthSurface.pTex = pLowResRTDepth; - D3dDepthSurface.pSurf = pLowResRTDepth->GetDeviceDepthStencilSurf(); - D3dDepthSurface.pTarget = pLowResRTDepth->GetDevTexture()->Get2DTexture(); - - pCurrDepthSurf = &D3dDepthSurface; - } -#endif - - CRenderObject* pObj = rd->m_RP.m_pCurObject; - SRenderObjData* pOD = pObj->GetObjData(); - uint16 nLightID = pOD->m_nLightID; - SRenderLight* pDL = rd->EF_GetDeferredLightByID(nLightID); - - bool bCastsShadows = ((pDL->m_Flags & (DLF_CASTSHADOW_MAPS | DLF_PROJECT)) == (DLF_CASTSHADOW_MAPS | DLF_PROJECT)) ? true : false; - - const CRenderObject::SInstanceInfo& rInstInfo = pObj->m_II; - - Matrix34A objMatInv = rInstInfo.m_Matrix.GetInverted(); - - Matrix44A mLightProj, mLightView; - CShadowUtils::GetCubemapFrustumForLight(pDL, 0, pDL->m_fLightFrustumAngle * 2.f, &mLightProj, &mLightView, true); - - Matrix44 projMat = mLightView * mLightProj; - - const CameraViewParameters& RCam = gRenDev->GetViewParameters(); - - float fLightAngle = pDL->m_fLightFrustumAngle; - float fAngleCoeff = 1.0f / tan_tpl((90.0f - fLightAngle) * gf_PI / 180.0f); - float fNear = pDL->m_fProjectorNearPlane; - float fFar = pDL->m_fRadius; - Vec3 vLightPos = pDL->m_Origin; - Vec3 vAxis = rInstInfo.m_Matrix.GetColumn0(); - - float fSin, fCos; - sincos_tpl(fLightAngle * gf_PI / 180.0f, &fSin, &fCos); - - Vec4 vLightParams = Vec4(fFar, fAngleCoeff, fNear, fFar); - Vec4 vSphereParams = Vec4(vLightPos, fFar); - Vec4 vConeParams = Vec4(vAxis, fCos); - Vec4 pLightPos = Vec4(vLightPos, 1.0f); - Vec4 cLightDiffuse = Vec4(pDL->m_Color.r, pDL->m_Color.g, pDL->m_Color.b, pDL->m_SpecMult); - - Vec3 vEye = RCam.vOrigin; - - Vec3 vCoords[9]; // Evaluate campos to near plane verts as a sphere. - RCam.CalcVerts(vCoords); - vCoords[4] = vEye; - AABB camExtents(vCoords, 5); - - float fRadius = camExtents.GetRadius(); - Vec3 vCentre = camExtents.GetCenter(); - - float fCosSq = fCos * fCos; - - Vec3 vVertToSphere = vCentre - vLightPos; - Vec3 d = vVertToSphere + vAxis * (fRadius / fSin); - float dSq = d.dot(d); - float e = d.dot(vAxis); - float eSq = e * e; - - if ((e > 0.0f) && (eSq >= (dSq * fCosSq))) - { - dSq = vVertToSphere.dot(vVertToSphere); - e = vVertToSphere.dot(vAxis); - - if ((e < (fFar + fRadius)) && (e > (fNear - fRadius))) // test capping planes - { - bViewerInsideCone = true; - } - } - - Vec4 cEyePosVec(vEye, !bViewerInsideCone ? 1 : 0); - - Vec4 vShadowCoords = Vec4(0.0f, 0.0f, 1.0f, 1.0f); - - CTexture* shadowTexture = nullptr; - CTexture* projectedTexture = nullptr; - - if (bCastsShadows) - { - const ShadowMapFrustum& shadowFrustum = CShadowUtils::GetFirstFrustum(nLightID); - - if (shadowFrustum.bUseShadowsPool) - { - shadowTexture = CTexture::s_ptexRT_ShadowPool; - float width = CTexture::s_ptexRT_ShadowPool->GetWidth(); - float height = CTexture::s_ptexRT_ShadowPool->GetHeight(); - vShadowCoords = Vec4(shadowFrustum.packX[0] / width, shadowFrustum.packY[0] / height, shadowFrustum.packWidth[0] / width, shadowFrustum.packHeight[0] / height); - } - } - - if (pDL->m_pLightImage) - { - projectedTexture = (CTexture*)pDL->m_pLightImage; - } - - Vec4 sampleOffsets[5]; - { - const float tU = 1.0f / (float)pLowResRT->GetWidth(); - const float tV = 1.0f / (float)pLowResRT->GetHeight(); - - sampleOffsets[0] = Vec4(0, 0, 0, 0); - sampleOffsets[1] = Vec4(0, -tV, tU, tV); - sampleOffsets[2] = Vec4(-tU, 0, -tU, tV); - sampleOffsets[3] = Vec4(tU, 0, tU, -tV); - sampleOffsets[4] = Vec4(0, tV, -tU, -tV); - } - - Vec4 vMisc = Vec4(1.0f / (float)gcpRendD3D->m_nShadowPoolWidth, 1.0f / (float)gcpRendD3D->m_nShadowPoolHeight, 0.0f, 0.0f); - - const int ZPass = 2; // passes can be buggy, use manual ordering - const int VolumetricPass = 1; - const int FinalPass = 0; - - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3]); - - if (bCastsShadows) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - //Setup geometry - const int nNumSides = BEAM_RE_CONE_SIDES; - const uint32 c_numBBVertices(nNumSides * 2 + 2); - SVF_P3F_C4B_T2F bbVertices[c_numBBVertices]; - - const uint32 c_numBBIndices((nNumSides) * 6 * 2); - uint16 bbIndices[c_numBBIndices]; - - SetupGeometry(&bbVertices[0], &bbIndices[0], fAngleCoeff, fNear, fFar); - - // copy vertices into dynamic VB - TempDynVB::CreateFillAndBind(bbVertices, c_numBBVertices, 0); - - // copy indices into dynamic IB - TempDynIB16::CreateFillAndBind(bbIndices, c_numBBIndices); - - uint32 nPasses = 0; - ef->FXBegin(&nPasses, FEF_DONTSETSTATES); - - assert(nPasses == (ZPass + 1)); - - int nStartPass = (bViewerInsideCone || !pCurrDepthSurf) ? VolumetricPass : ZPass; - - for (int nCurPass = nStartPass; nCurPass > -1; nCurPass--) - { - ef->FXBeginPass(nCurPass); - - //set world basis - float maskRTWidthL = pLowResRT->GetWidth(); - float maskRTHeightL = pLowResRT->GetHeight(); - float maskRTWidthH = rd->GetWidth(); - float maskRTHeightH = rd->GetHeight(); - Vec4 vScreenScale(1.0f / maskRTWidthL, 1.0f / maskRTHeightL, 1.0f / maskRTWidthH, 1.0f / maskRTHeightH); - - if (nCurPass == nStartPass && pLowResRT) - { - rd->FX_PushRenderTarget(0, pLowResRT, pCurrDepthSurf, -1, false, 1); - rd->FX_SetColorDontCareActions(0, false, false); //Check gmem path for performance when using this pass. - rd->FX_ClearTarget(pLowResRT, Clr_Transparent); - rd->FX_ClearTarget(pCurrDepthSurf, CLEAR_ZBUFFER); - - } - - uint32 nState = (nCurPass == FinalPass) ? (GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA) : 0; - - if (bViewerInsideCone) - { - rd->SetCullMode(R_CULL_FRONT); - } - else - { - rd->SetCullMode(R_CULL_BACK); - } - - if (bViewerInsideCone || !pCurrDepthSurf) - { - nState |= GS_NODEPTHTEST; - } - else - { - nState |= (nCurPass == ZPass) ? (GS_DEPTHWRITE | GS_COLMASK_NONE) : 0; - } - - rd->FX_SetState(nState); - - // set vs constants - if (nCurPass == VolumetricPass) - { - ef->FXSetVSFloat(m_eyePosInWSName, &cEyePosVec, 1); - - ef->FXSetPSFloat(m_eyePosInWSName, &cEyePosVec, 1); - ef->FXSetPSFloat(m_projMatrixName, (const Vec4*)&projMat.m00, 4); - ef->FXSetPSFloat(m_shadowCoordsName, (const Vec4*)&vShadowCoords, 1); - ef->FXSetPSFloat(m_lightParamsName, &vLightParams, 1); - ef->FXSetPSFloat(m_sphereParamsName, &vSphereParams, 1); - ef->FXSetPSFloat(m_coneParamsName, &vConeParams, 1); - ef->FXSetPSFloat(m_lightPosName, &pLightPos, 1); - ef->FXSetPSFloat(m_miscOffsetsName, &vMisc, 1); - } - else if (nCurPass == FinalPass) - { - ef->FXSetPSFloat(m_sampleOffsetsName, &sampleOffsets[0], 5); - } - - ef->FXSetPSFloat(m_lightDiffuseName, &cLightDiffuse, 1); - ef->FXSetPSFloat(m_screenScaleName, &vScreenScale, 1); - - if (nCurPass == FinalPass && pLowResRT) - { - pLowResRT->Apply(7, texStateID); - } - if (projectedTexture) - { - projectedTexture->Apply(5, texStateID); - } - if (bCastsShadows && shadowTexture) - { - shadowTexture->Apply(6, texStateID); // bilinear is a hack, but looks better - } - //pShadowTex->Apply(6, texStateIDPoint); - - rd->m_RP.m_nCommitFlags |= FC_MATERIAL_PARAMS; - - // commit all render changes - rd->FX_Commit(); - - // set vertex declaration and streams of skydome - if (!FAILED(rd->FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - // draw skydome - rd->FX_DrawIndexedPrimitive(eptTriangleList, 0, 0, c_numBBVertices, 0, c_numBBIndices); - } - - if ((nCurPass == VolumetricPass) && pLowResRT) - { - rd->FX_PopRenderTarget(0); - } - } - return true; -#endif -} - -bool CREGameEffect::mfDraw(CShader* ef, SShaderPass* sfm) -{ - CRY_ASSERT_MESSAGE(gRenDev->m_pRT->IsRenderThread(), "Trying to render from wrong thread"); - CRY_ASSERT(ef); - CRY_ASSERT(sfm); - - if (m_pImpl) - { -#ifndef _RELEASE - _smart_ptr pMaterial = (gRenDev->m_RP.m_pCurObject) ? (gRenDev->m_RP.m_pCurObject->m_pCurrMaterial) : NULL; - const char* pEffectName = (pMaterial) ? (PathUtil::GetFileName(pMaterial->GetName())) : "GameEffectRenderElement"; - PROFILE_LABEL_SCOPE(pEffectName); -#endif - - uint32 passCount = 0; - bool successFlag = true; - - // Begin drawing - ef->FXBegin(&passCount, 0); - if (passCount > 0) - { - // Begin pass - ef->FXBeginPass(0); - - // Draw element - successFlag = m_pImpl->mfDraw(ef, sfm, gRenDev->m_RP.m_pCurObject); - - // End pass - ef->FXEndPass(); - } - // End drawing - ef->FXEnd(); - - return successFlag; - } - return false; -} - -#if defined(USE_GEOM_CACHES) - -// Each call of CREGeomCache::mfDraw render *all* meshes that share the same material in the geom cache. See CGeomCacheRenderNode::Render -bool CREGeomCache::mfDraw(CShader* ef, SShaderPass* sfm) -{ - PROFILE_FRAME(CREGeomCache::mfDraw); - - const uint numMeshes = m_meshRenderData.size(); - CD3D9Renderer* const pRenderer = gcpRendD3D; - - SRenderPipeline& rRP = pRenderer->m_RP; - SThreadInfo& threadInfo = rRP.m_TI[rRP.m_nProcessThreadID]; - - CRenderObject* const pRenderObject = rRP.m_pCurObject; - Matrix34A matrix = pRenderObject->m_II.m_Matrix; - CHWShader_D3D* const pCurVS = (CHWShader_D3D*)sfm->m_VShader; - - const bool bIsShadowPass = (threadInfo.m_PersFlags & RBPF_SHADOWGEN) != 0; - const CCamera& camera = bIsShadowPass ? rRP.m_ShadowInfo.m_pCurShadowFrustum->FrustumPlanes[rRP.m_ShadowInfo.m_nOmniLightSide] : gRenDev->GetCamera(); - - Matrix44A prevMatrix; - - CMotionBlur::GetPrevObjToWorldMat(rRP.m_pCurObject, prevMatrix); - - const uint64 oldFlagsShader_RT = rRP.m_FlagsShader_RT; - uint64 flagsShader_RT = rRP.m_FlagsShader_RT; - const int oldFlagsPerFlush = rRP.m_FlagsPerFlush; - bool bResetVertexDecl = false; - - for (uint nMesh = 0; nMesh < numMeshes; ++nMesh) - { - const SMeshRenderData& meshData = m_meshRenderData[nMesh]; - - CRenderMesh* const pRenderMesh = static_cast(meshData.m_pRenderMesh.get()); - const uint numInstances = meshData.m_instances.size(); - - if (pRenderMesh && numInstances > 0) - { - PROFILE_LABEL_SHADER(pRenderMesh->GetSourceName() ? pRenderMesh->GetSourceName() : "Unknown mesh-resource name"); - - const CRenderMesh* const pVertexContainer = pRenderMesh->_GetVertexContainer(); - - if (!pVertexContainer->_HasVBStream(VSF_GENERAL) || !pRenderMesh->_HasIBStream()) - { - // Should never happen. Video buffer is missing - continue; - } - - const bool bHasVelocityStream = pRenderMesh->_HasVBStream(VSF_VERTEX_VELOCITY); - const bool bIsMotionBlurPass = (rRP.m_PersFlags2 & RBPF2_MOTIONBLURPASS) != 0; - - pRenderMesh->BindStreamsToRenderPipeline(); - - rRP.m_RendNumVerts = pRenderMesh->GetNumVerts(); - - if (ef->m_HWTechniques.Num() && pRenderMesh->CanRender()) - { - const TRenderChunkArray& chunks = pRenderMesh->GetChunks(); - const uint numChunks = chunks.size(); - - for (uint i = 0; i < numChunks; ++i) - { - const CRenderChunk& chunk = chunks[i]; - if (chunk.m_nMatID != m_materialId) - { - continue; - } - - rRP.m_FirstIndex = chunk.nFirstIndexId; - rRP.m_RendNumIndices = chunk.nNumIndices; - -#if defined(HW_INSTANCING_ENABLED) && D3DRENDERRE_CPP_TRAIT_MFDRAW_USEINSTANCING - const bool bUseInstancing = (CRenderer::CV_r_geominstancing != 0) && (numInstances > CRenderer::CV_r_GeomCacheInstanceThreshold); -#else - const bool bUseInstancing = false; -#endif - - TempDynInstVB instVB(gcpRendD3D); - uint numInstancesToDraw = 0; - byte* __restrict pInstanceMatricesVB = NULL; - - // Note: Geom cache instancing is a horrible mess at the moment, because it re-uses - // FX_DrawInstances which supports both constant based and attribute based instancing - // and all platforms. - // - // This only sets up the data structures for D3D11 attribute based - // instancing. Need to clean this up later and ideally use constant based instancing. - - const uint64 lastFlagsShader_RT = rRP.m_FlagsShader_RT; - rRP.m_FlagsShader_RT = flagsShader_RT | (bUseInstancing ? g_HWSR_MaskBit[HWSR_INSTANCING_ATTR] : 0); - if (lastFlagsShader_RT != rRP.m_FlagsShader_RT) - { - pCurVS->mfSet(bUseInstancing ? HWSF_INSTANCED : 0); - } - - CHWShader_D3D::SHWSInstance* pVPInst = pCurVS->m_pCurInst; - int32 nUsedAttr = 3, nInstAttrMask = 0; - byte Attributes[32]; - - if (bUseInstancing) - { - pVPInst->GetInstancingAttribInfo(Attributes, nUsedAttr, nInstAttrMask); - instVB.Allocate(numInstances, nUsedAttr * INST_PARAM_SIZE); - pInstanceMatricesVB = (byte*)(instVB.Lock()); - } - - const uint32 nStride = nUsedAttr * sizeof(float[4]); - - // Fill the stream 3 for per-instance data - byte* pWalkData = pInstanceMatricesVB; - for (uint nInstance = 0; nInstance < numInstances; ++nInstance) - { - const SMeshInstance& instance = meshData.m_instances[nInstance]; - - Matrix34A pieceMatrix = matrix * instance.m_matrix; - - AABB pieceWorldAABB; - pieceWorldAABB.SetTransformedAABB(pieceMatrix, instance.m_aabb); - if (!camera.IsAABBVisible_F(pieceWorldAABB)) - { - continue; - } - - // Needs to be in this scope, because it's used by FX_DrawIndexedMesh - Matrix44A prevPieceMatrix = prevMatrix * instance.m_prevMatrix; - - if (bIsMotionBlurPass) - { - const float fThreshold = 0.01f; - if (bUseInstancing || (rRP.m_nBatchFilter & FB_Z) || !Matrix34::IsEquivalent(pieceMatrix, Matrix34(prevPieceMatrix), fThreshold) || bHasVelocityStream) - { - rRP.m_FlagsPerFlush |= RBSI_CUSTOM_PREVMATRIX; - rRP.m_pPrevMatrix = &prevPieceMatrix; - } - else - { - // Don't draw pieces without any motion in motion blur pass - continue; - } - } - - if (!bUseInstancing) - { - pRenderer->GetPerInstanceConstantBufferPool().UpdateConstantBuffer([&](void* mappedData) - { - *reinterpret_cast(mappedData) = pieceMatrix; - }, threadInfo.m_RealTime); - - pRenderObject->m_II.m_Matrix = pieceMatrix; - pCurVS->UpdatePerInstanceConstantBuffer(); - - // Check if instancing messed with vertex declaration - if (bResetVertexDecl) - { - pRenderer->FX_SetVertexDeclaration(rRP.m_FlagsStreams_Decl, rRP.m_CurVFormat); - bResetVertexDecl = false; - } - - pRenderer->FX_DrawIndexedMesh(pRenderMesh->GetPrimitiveType()); - } - else - { - *reinterpret_cast(pWalkData) = pieceMatrix; - - if (pVPInst->m_nParams_Inst >= 0) - { - SCGParamsGroup& Group = CGParamManager::s_Groups[pVPInst->m_nParams_Inst]; - pCurVS->UpdatePerInstanceConstants(eHWSC_Vertex, Group.pParams, Group.nParams, pWalkData); - } - - pWalkData += nStride; - ++numInstancesToDraw; - } - } - - if (bUseInstancing) - { - instVB.Unlock(); - instVB.Bind(3, nUsedAttr * INST_PARAM_SIZE); - instVB.Release(); - - pCurVS->UpdatePerInstanceConstantBuffer(); - pRenderer->FX_DrawInstances(ef, sfm, 0, 0, numInstancesToDraw - 1, nUsedAttr, pInstanceMatricesVB, nInstAttrMask, Attributes, 0); - bResetVertexDecl = true; - } - } - } - } - } - - // Reset matrix to original value for cases when render object gets reused - pRenderObject->m_II.m_Matrix = matrix; - rRP.m_FlagsShader_RT = oldFlagsShader_RT; - rRP.m_FlagsPerFlush = oldFlagsPerFlush; - - return true; -} - -#endif - - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderThread.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderThread.cpp deleted file mode 100644 index ee3939f665..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DRenderThread.cpp +++ /dev/null @@ -1,712 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" - -#include "D3DStereo.h" - -#include "../Common/Textures/TextureManager.h" - -//======================================================================= - -bool CD3D9Renderer::RT_CreateDevice() -{ - LOADING_TIME_PROFILE_SECTION; - -#if (defined(WIN32) || defined(WIN64)) && !defined(SUPPORT_DEVICE_INFO) - if (!m_bShaderCacheGen && !SetWindow(m_width, m_height, m_bFullScreen, m_hWnd)) - { - return false; - } -#endif - - return SetRes(); -} - -void CD3D9Renderer::RT_ReleaseVBStream(void* pVB, [[maybe_unused]] int nStream) -{ - D3DBuffer* pBuf = (D3DBuffer*)pVB; - SAFE_RELEASE(pBuf); -} -void CD3D9Renderer::RT_ReleaseCB(void* pVCB) -{ - AzRHI::ConstantBuffer* pCB = (AzRHI::ConstantBuffer*)pVCB; - SAFE_RELEASE(pCB); -} - -void CD3D9Renderer::RT_ClearTarget(ITexture* tex, const ColorF& color) -{ - CTexture* pTex = reinterpret_cast(tex); - if (pTex->GetFlags() & FT_USAGE_DEPTHSTENCIL) - { - D3DDepthSurface* pSurf = reinterpret_cast(pTex->GetDeviceDepthStencilSurf()); - if (!pSurf) - { - return; - } - - // NOTE: normalized depth in color.r and unnormalized stencil in color.g - GetDeviceContext().ClearDepthStencilView(pSurf, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, color.r, (uint8)color.g); - } - else - { - D3DSurface* pSurf = pTex->GetSurface(0, 0); - if (!pSurf) - { - return; - } - - GetDeviceContext().ClearRenderTargetView(pSurf, (float*)&color); - } -} - -void CD3D9Renderer::RT_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType) -{ - FX_SetFPMode(); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - // Create the temp buffer after we try to set the vertex declaration otherwise - // if that fails we won't call FX_DrawPrimitive that on a platform level - // cleans up some of the memory stuff that the TempDynVB creates - TempDynVB::CreateFillAndBind(pBuf, nVerts, 0); - if (pInds) - { - TempDynIB16::CreateFillAndBind(pInds, nInds); - FX_DrawIndexedPrimitive(GetInternalPrimitiveType(nPrimType), 0, 0, nVerts, 0, nInds); - } - else - { - FX_DrawPrimitive(GetInternalPrimitiveType(nPrimType), 0, nVerts); - } - } -} - -void CD3D9Renderer::RT_DrawDynVBUI(SVF_P2F_C4B_T2F_F4B* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType) -{ - FX_SetUIMode(); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P2F_C4B_T2F_F4B))) - { - // Create the temp buffer after we try to set the vertex declaration otherwise - // if that fails we won't call FX_DrawPrimitive that on a platform level - // cleans up some of the memory stuff that the TempDynVB creates - TempDynVB::CreateFillAndBind(pBuf, nVerts, 0); - if (pInds) - { - TempDynIB16::CreateFillAndBind(pInds, nInds); - FX_DrawIndexedPrimitive(GetInternalPrimitiveType(nPrimType), 0, 0, nVerts, 0, nInds); - } - else - { - FX_DrawPrimitive(GetInternalPrimitiveType(nPrimType), 0, nVerts); - } - } -} - -void CD3D9Renderer::RT_Draw2dImageInternal(C2dImage* images, uint32 numImages, bool stereoLeftEye) -{ - SetCullMode(R_CULL_DISABLE); - - float maxParallax = 0; - float screenDist = 0; - - if (GetS3DRend().IsStereoEnabled()) - { - maxParallax = GetS3DRend().GetMaxSeparationScene(); - screenDist = GetS3DRend().GetZeroParallaxPlaneDist(); - } - - // Flush the current viewports. - // The GetViewport call below uses either m_MainRTViewport or m_NewViewport, then the image scaling code - // (ScaleCoordX/ScaleCoordY) uses m_CurViewport, so this could lead to different viewport settings being used unless we flush. - FX_SetViewport(); - - // Set orthographic projection - Matrix44A origMatProj = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - Matrix44A* m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - int vx, vy, vw, vh; - GetViewport(&vx, &vy, &vw, &vh); - mathMatrixOrthoOffCenterLH(m, (float)vx, (float)vw, (float)vh, (float)vy, 0.0f, 1.0f); - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - - // Create dynamic geometry - TempDynVB vb(gcpRendD3D); - vb.Allocate(numImages * 4); - SVF_P3F_C4B_T2F* vQuad = vb.Lock(); - - for (uint32 i = 0; i < numImages; ++i) - { - C2dImage& img = images[i]; - uint32 baseIdx = i * 4; - - float parallax = 0; - if (img.stereoDepth > 0) - { - parallax = 800 * maxParallax * (1 - screenDist / img.stereoDepth); - } - - float xpos = (float)ScaleCoordX(img.xpos + parallax * (stereoLeftEye ? -1 : 1)); - float w = (float)ScaleCoordX(img.w); - float ypos = (float)ScaleCoordY(img.ypos); - float h = (float)ScaleCoordY(img.h); - - if (img.angle != 0) - { - float xsub = (float)(xpos + w / 2.0f); - float ysub = (float)(ypos + h / 2.0f); - - float x, y, x1, y1; - float mcos = cos_tpl(DEG2RAD(img.angle)); - float msin = sin_tpl(DEG2RAD(img.angle)); - - x = xpos - xsub; - y = ypos - ysub; - x1 = x * mcos - y * msin; - y1 = x * msin + y * mcos; - x1 += xsub; - y1 += ysub; - vQuad[baseIdx].xyz.x = x1; - vQuad[baseIdx].xyz.y = y1; - - x = xpos + w - xsub; - y = ypos - ysub; - x1 = x * mcos - y * msin; - y1 = x * msin + y * mcos; - x1 += xsub; - y1 += ysub; - vQuad[baseIdx + 1].xyz.x = x1;//xpos + fw; - vQuad[baseIdx + 1].xyz.y = y1;// fy; - - x = xpos + w - xsub; - y = ypos + h - ysub; - x1 = x * mcos - y * msin; - y1 = x * msin + y * mcos; - x1 += xsub; - y1 += ysub; - vQuad[baseIdx + 3].xyz.x = x1;//xpos + fw; - vQuad[baseIdx + 3].xyz.y = y1;//fy + fh; - - x = xpos - xsub; - y = ypos + h - ysub; - x1 = x * mcos - y * msin; - y1 = x * msin + y * mcos; - x1 += xsub; - y1 += ysub; - vQuad[baseIdx + 2].xyz.x = x1;//xpos; - vQuad[baseIdx + 2].xyz.y = y1;//fy + fh; - } - else - { - vQuad[baseIdx].xyz.x = xpos; - vQuad[baseIdx].xyz.y = ypos; - - vQuad[baseIdx + 1].xyz.x = xpos + w; - vQuad[baseIdx + 1].xyz.y = ypos; - - vQuad[baseIdx + 2].xyz.x = xpos; - vQuad[baseIdx + 2].xyz.y = ypos + h; - - vQuad[baseIdx + 3].xyz.x = xpos + w; - vQuad[baseIdx + 3].xyz.y = ypos + h; - } - - vQuad[baseIdx + 0].st = Vec2(img.s0, 1.0f - img.t0); - vQuad[baseIdx + 1].st = Vec2(img.s1, 1.0f - img.t0); - vQuad[baseIdx + 2].st = Vec2(img.s0, 1.0f - img.t1); - vQuad[baseIdx + 3].st = Vec2(img.s1, 1.0f - img.t1); - - for (int j = 0; j < 4; ++j) - { - vQuad[baseIdx + j].color.dcolor = img.col; - vQuad[baseIdx + j].xyz.z = img.z; - } - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - CTexture* prevTex = NULL; - EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - EF_SetSrgbWrite(false); - FX_SetFPMode(); - - if (FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj = origMatProj; - return; - } - - - int nState = m_bDraw2dImageStretchMode ? CTexture::GetTexState(STexState(FILTER_TRILINEAR, true)) : CTexture::GetTexState(STexState(FILTER_POINT, true)); - - // Draw quads - for (uint32 i = 0; i < numImages; ++i) - { - C2dImage& img = images[i]; - - if (img.pTex != prevTex) - { - prevTex = img.pTex; - if (img.pTex) - { - img.pTex->Apply(0, nState); - EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - EF_SetSrgbWrite(false); - } - else - { - EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, (eCA_Diffuse | (eCA_Diffuse << 3)), (eCA_Diffuse | (eCA_Diffuse << 3))); - EF_SetSrgbWrite(false); - } - - FX_SetFPMode(); - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DRenderThread_cpp) -#endif - } - - FX_DrawPrimitive(eptTriangleStrip, i * 4, 4); - } - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj = origMatProj; -} - -void CD3D9Renderer::RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, const bool asciiMultiLine, const STextDrawContext& ctx) const -{ - SetProfileMarker("DRAWSTRINGU", CRenderer::ESPM_PUSH); - - pFont->RenderCallback(x, y, z, pStr, asciiMultiLine, ctx); - - SetProfileMarker("DRAWSTRINGU", CRenderer::ESPM_POP); -} - -void CD3D9Renderer::RT_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround) -{ - if (m_bDeviceLost) - { - return; - } - - int i; - int st; - - EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, eCA_Texture | (eCA_Diffuse << 3), eCA_Texture | (eCA_Diffuse << 3)); - EF_SetSrgbWrite(false); - - st = GS_NODEPTHTEST; - if (flags & 1) - { - st |= GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA; - } - FX_SetState(st); - CTextureManager::Instance()->GetWhiteTexture()->Apply(0); - - DWORD c = D3DRGBA(col.r, col.g, col.b, col.a); - - if (fGround >= 0) - { - TempDynVB vb(gcpRendD3D); - vb.Allocate(nump * 2); - SVF_P3F_C4B_T2F* vQuad = vb.Lock(); - - for (i = 0; i < nump; i++) - { - vQuad[i * 2 + 0].xyz.x = v[i][0]; - vQuad[i * 2 + 0].xyz.y = fGround; - vQuad[i * 2 + 0].xyz.z = 0; - vQuad[i * 2 + 0].color.dcolor = c; - vQuad[i * 2 + 0].st = Vec2(0.0f, 0.0f); - vQuad[i * 2 + 1].xyz = v[i]; - vQuad[i * 2 + 1].color.dcolor = c; - vQuad[i * 2 + 1].st = Vec2(0.0f, 0.0f); - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - FX_SetFPMode(); - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - FX_DrawPrimitive(eptLineList, 0, nump * 2); - } - } - else - { - TempDynVB vb(gcpRendD3D); - vb.Allocate(nump); - SVF_P3F_C4B_T2F* vQuad = vb.Lock(); - - for (i = 0; i < nump; i++) - { - vQuad[i].xyz = v[i]; - vQuad[i].color.dcolor = c; - vQuad[i].st = Vec2(0, 0); - } - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - FX_SetFPMode(); - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_C4B_T2F))) - { - FX_DrawPrimitive(eptLineStrip, 0, nump); - } - } -} - -void CD3D9Renderer::RT_Draw2dImageStretchMode(bool bStretch) -{ - m_bDraw2dImageStretchMode = bStretch; -} - -void CD3D9Renderer::RT_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z) -{ - C2dImage img(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z, 0); - - SetProfileMarker("DRAW2DIMAGE", CRenderer::ESPM_PUSH); - - if (GetS3DRend().IsStereoEnabled()) - { - GetS3DRend().BeginRenderingTo(STEREO_EYE_LEFT); - RT_Draw2dImageInternal(&img, 1, true); - GetS3DRend().EndRenderingTo(STEREO_EYE_LEFT); - - GetS3DRend().BeginRenderingTo(STEREO_EYE_RIGHT); - RT_Draw2dImageInternal(&img, 1, false); - GetS3DRend().EndRenderingTo(STEREO_EYE_RIGHT); - } - else - { - RT_Draw2dImageInternal(&img, 1); - } - - SetProfileMarker("DRAW2DIMAGE", CRenderer::ESPM_POP); -} - -void CD3D9Renderer::RT_Push2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z, float stereoDepth) -{ - m_2dImages.Add(C2dImage(xpos, ypos, w, h, pTexture, s0, t0, s1, t1, angle, col, z, stereoDepth)); -} - -void CD3D9Renderer::RT_Draw2dImageList() -{ - if (m_2dImages.empty()) - { - return; - } - - SetProfileMarker("DRAW2DIMAGELIST", CRenderer::ESPM_PUSH); - - if (GetS3DRend().IsStereoEnabled()) - { - GetS3DRend().BeginRenderingTo(STEREO_EYE_LEFT); - RT_Draw2dImageInternal(m_2dImages.Data(), m_2dImages.size(), true); - GetS3DRend().EndRenderingTo(STEREO_EYE_LEFT); - - GetS3DRend().BeginRenderingTo(STEREO_EYE_RIGHT); - RT_Draw2dImageInternal(m_2dImages.Data(), m_2dImages.size(), false); - GetS3DRend().EndRenderingTo(STEREO_EYE_RIGHT); - } - else - { - RT_Draw2dImageInternal(m_2dImages.Data(), m_2dImages.size()); - } - - SetProfileMarker("DRAW2DIMAGELIST", CRenderer::ESPM_POP); - - m_2dImages.resize(0); -} - -void CD3D9Renderer::RT_PushRenderTarget(int nTarget, CTexture* pTex, SDepthTexture* pDepth, int nS) -{ - FX_PushRenderTarget(nTarget, pTex, pDepth, nS); -} - -void CD3D9Renderer::RT_PopRenderTarget(int nTarget) -{ - FX_PopRenderTarget(nTarget); -} - -void CD3D9Renderer::RT_Init() -{ - EF_Init(); -} - -void CD3D9Renderer::RT_CreateResource(SResourceAsync* pRes) -{ - if (pRes->eClassName == eRCN_Texture) - { - CTexture* pTex = NULL; - - if (pRes->nTexId) - { // only create device texture - pTex = CTexture::GetByID(pRes->nTexId); - const byte* arrData[6] = { pRes->pData, 0, 0, 0, 0, 0 }; - pTex->CreateDeviceTexture(arrData); - } - else - { // create full texture - char* pName = pRes->Name; - char szName[128]; - if (!pName) - { - sprintf_s(szName, "$AutoDownloadAsync_%d", m_TexGenID++); - pName = szName; - } - pTex = CTexture::Create2DTexture(pName, pRes->nWidth, pRes->nHeight, pRes->nMips, pRes->nTexFlags, pRes->pData, (ETEX_Format)pRes->nFormat, (ETEX_Format)pRes->nFormat); - } - - SAFE_DELETE_ARRAY(pRes->pData); - pRes->pResource = pTex; - pRes->nReady = (CTexture::IsTextureExist(pTex)); - } - else - { - assert(0); - } - - delete pRes; -} -void CD3D9Renderer::RT_ReleaseResource(SResourceAsync* pRes) -{ - if (pRes->eClassName == eRCN_Texture) - { - CTexture* pTex = (CTexture*)pRes->pResource; - pTex->Release(); - } - else - { - assert(0); - } - - delete pRes; -} - -void CD3D9Renderer::RT_UnbindTMUs() -{ - D3DShaderResourceView* pTex[MAX_TMU] = {NULL}; - for (uint32 i = 0; i < MAX_TMU; ++i) - { - CTexture::s_TexStages[i].m_DevTexture = NULL; - } - m_DevMan.BindSRV(eHWSC_Vertex, pTex, 0, MAX_TMU); - m_DevMan.BindSRV(eHWSC_Geometry, pTex, 0, MAX_TMU); - m_DevMan.BindSRV(eHWSC_Domain, pTex, 0, MAX_TMU); - m_DevMan.BindSRV(eHWSC_Hull, pTex, 0, MAX_TMU); - m_DevMan.BindSRV(eHWSC_Compute, pTex, 0, MAX_TMU); - m_DevMan.BindSRV(eHWSC_Pixel, pTex, 0, MAX_TMU); - - m_DevMan.CommitDeviceStates(); -} - -void CD3D9Renderer::RT_UnbindResources() -{ - for (AZ::u32 shaderClass = 0; shaderClass < eHWSC_Num; ++shaderClass) - { - for (AZ::u32 shaderSlot = 0; shaderSlot < eConstantBufferShaderSlot_Count; ++shaderSlot) - { - m_DevMan.BindConstantBuffer(EHWShaderClass(shaderClass), nullptr, shaderSlot); - } - } - - D3DBuffer* pBuffers[16] = { 0 }; - UINT StrideOffset[16] = { 0 }; - - m_DevMan.BindIB(NULL, 0, DXGI_FORMAT_R16_UINT); - m_RP.m_pIndexStream = NULL; - - m_DevMan.BindVB(0, 16, pBuffers, StrideOffset, StrideOffset); - m_RP.m_VertexStreams[0].pStream = NULL; - - m_DevMan.BindVtxDecl(NULL); - m_pLastVDeclaration = NULL; - - m_DevMan.BindShader(eHWSC_Pixel, NULL); - m_DevMan.BindShader(eHWSC_Vertex, NULL); - m_DevMan.BindShader(eHWSC_Geometry, NULL); - m_DevMan.BindShader(eHWSC_Domain, NULL); - m_DevMan.BindShader(eHWSC_Hull, NULL); - m_DevMan.BindShader(eHWSC_Compute, NULL); - - CHWShader::s_pCurPS = nullptr; - CHWShader::s_pCurVS = nullptr; - CHWShader::s_pCurGS = nullptr; - CHWShader::s_pCurDS = nullptr; - CHWShader::s_pCurHS = nullptr; - CHWShader::s_pCurCS = nullptr; - - m_DevMan.CommitDeviceStates(); -} - -void CD3D9Renderer::RT_ReleaseRenderResources() -{ - GetGraphicsPipeline().Shutdown(); - - m_cEF.mfReleasePreactivatedShaderData(); - m_cEF.m_Bin.InvalidateCache(); - //m_cEF.m_Bin.m_BinPaths.clear(); - ForceFlushRTCommands(); - - for (uint i = 0; i < CLightStyle::s_LStyles.Num(); i++) - { - delete CLightStyle::s_LStyles[i]; - } - CLightStyle::s_LStyles.Free(); - - FX_PipelineShutdown(); - ID3D11RenderTargetView* pRTV[RT_STACK_WIDTH] = { NULL }; - GetDeviceContext().OMSetRenderTargets(RT_STACK_WIDTH, pRTV, NULL); - m_nMaxRT2Commit = -1; -} -void CD3D9Renderer::RT_CreateRenderResources() -{ - EF_Init(); - - if (m_pPostProcessMgr) - { - m_pPostProcessMgr->CreateResources(); - } - - GetGraphicsPipeline().Init(); -} - -void CD3D9Renderer::RT_PrecacheDefaultShaders() -{ - SShaderCombination cmb; - m_cEF.s_ShaderStereo->mfPrecache(cmb, true, true, NULL); - - cmb.m_RTMask |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - cmb.m_RTMask |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - cmb.m_RTMask |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - m_cEF.s_ShaderVideo->mfPrecache(cmb, true, true, nullptr); -} - -void CD3D9Renderer::RT_ResetGlass() -{ -} - -void CD3D9Renderer::SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode) -{ - m_pRT->RC_SetRendererCVar(pCVar, pArgText, bSilentMode); -} - -void CD3D9Renderer::RT_SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode) -{ - if (pCVar) - { - pCVar->Set(pArgText); - - if (!bSilentMode) - { - if (gEnv->IsEditor()) - { - gEnv->pLog->LogWithType(ILog::eInputResponse, "%s = %s (Renderer CVar)", pCVar->GetName(), pCVar->GetString()); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " $3%s = $6%s $5(Renderer CVar)", pCVar->GetName(), pCVar->GetString()); - } - } - } -} - -void CD3D9Renderer::RT_PostLevelLoading() -{ - CRenderer::RT_PostLevelLoading(); - - // Clear our the shadow mask texture in case the level we are loading does not - // have any shadow casters. If we don't clear out the mask then whatever was - // previous in the mask, including a previously loaded level, will be used and - // incorrect shadows will be drawn. - FX_ClearShadowMaskTexture(); -} - -void CD3D9Renderer::StartLoadtimePlayback(ILoadtimeCallback* pCallback) -{ - // make sure we can't access loading mode twice! - if (m_pRT->m_pLoadtimeCallback) - { - return; - } - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Renderer); - - if (pCallback) - { - FlushRTCommands(true, true, true); - - m_pRT->m_pLoadtimeCallback = pCallback; - SetViewport(0, 0, GetOverlayWidth(), GetOverlayHeight()); - m_pRT->RC_StartVideoThread(); - - if (m_pRT->IsMultithreaded()) - { - // wait until render thread has fully processed the start of the video - // to reduce the congestion on the IO reading (make sure nothing else - // beats the video to actually start reading something from the DVD) - while (m_pRT->m_eVideoThreadMode != SRenderThread::eVTM_Active) - { - m_pRT->FlushAndWait(); - AZStd::this_thread::yield(); - } - } - } -} - -void CD3D9Renderer::StopLoadtimePlayback() -{ - if (m_pRT->m_pLoadtimeCallback) - { - LOADING_TIME_PROFILE_SECTION; - - FlushRTCommands(true, true, true); - - m_pRT->RC_StopVideoThread(); - - if (m_pRT->IsMultithreaded()) - { - // wait until render thread has fully processed the shutdown of the loading thread - while (m_pRT->m_eVideoThreadMode != SRenderThread::eVTM_Disabled) - { - m_pRT->FlushAndWait(); - AZStd::this_thread::yield(); - } - } - - m_pRT->m_pLoadtimeCallback = nullptr; - - m_pRT->RC_BeginFrame(); - -#if !defined(STRIP_RENDER_THREAD) - // Blit the accumulated commands from the renderloading thread into the current fill command queue - // : Currently hacked into the RC_UpdateMaterialConstants command - if (m_pRT->m_CommandsLoading.size()) - { - void* buf = m_pRT->m_Commands[m_pRT->m_nCurThreadFill].Grow(m_pRT->m_CommandsLoading.size()); - memcpy(buf, &m_pRT->m_CommandsLoading[0], m_pRT->m_CommandsLoading.size()); - m_pRT->m_CommandsLoading.Free(); - } -#endif // !defined(STRIP_RENDER_THREAD) - } -} - -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DShaders.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DShaders.cpp deleted file mode 100644 index f5b7868030..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DShaders.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "Shaders/CShader.h" -#include "DevBuffer.h" -#include "RenderCapabilities.h" -#include -#include -#include -#include - -//================================================================================== - -bool CShader::FXSetTechnique(const CCryNameTSCRC& Name) -{ - assert (gRenDev->m_pRT->IsRenderThread()); - - uint32 i; - SShaderTechnique* pTech = NULL; - for (i = 0; i < m_HWTechniques.Num(); i++) - { - pTech = m_HWTechniques[i]; - if (pTech && Name == pTech->m_NameCRC) - { - break; - } - } - - CRenderer* rd = gRenDev; - - if (i == m_HWTechniques.Num()) - { // not found and not set - rd->m_RP.m_nShaderTechnique = -1; - rd->m_RP.m_pCurTechnique = NULL; - return false; - } - - rd->m_RP.m_pShader = this; - rd->m_RP.m_nShaderTechnique = i; - rd->m_RP.m_pCurTechnique = m_HWTechniques[i]; - - return true; -} - -bool CShader::FXSetCSFloat(const CCryNameR& NameParam, const Vec4 fParams[], int nParams) -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique) - { - return false; - } - SShaderPass* pPass = rd->m_RP.m_pCurPass; - if (!pPass) - { - return false; - } - CHWShader_D3D* curCS = (CHWShader_D3D*)pPass->m_CShader; - if (!curCS) - { - return false; - } - SCGBind* pBind = curCS->mfGetParameterBind(NameParam); - if (!pBind) - { - return false; - } - - const AZ::u32 registerCountMax = curCS->m_pCurInst->m_nMaxVecs[pBind->m_BindingSlot]; - AzRHI::ConstantBufferCache::GetInstance().WriteConstants(eHWSC_Compute, pBind, fParams, nParams, registerCountMax); - return true; -} - -bool CShader::FXSetCSFloat(const char* NameParam, const Vec4 fParams[], int nParams) -{ - return FXSetCSFloat(CCryNameR(NameParam), fParams, nParams); -} - -bool CShader::FXSetPSFloat(const CCryNameR& NameParam, const Vec4* fParams, int nParams) -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique) - { - return false; - } - SShaderPass* pPass = rd->m_RP.m_pCurPass; - if (!pPass) - { - return false; - } - CHWShader_D3D* curPS = (CHWShader_D3D*)pPass->m_PShader; - if (!curPS) - { - return false; - } - SCGBind* pBind = curPS->mfGetParameterBind(NameParam); - if (!pBind) - { - return false; - } - - const AZ::u32 registerCountMax = curPS->m_pCurInst->m_nMaxVecs[pBind->m_BindingSlot]; - AzRHI::ConstantBufferCache::GetInstance().WriteConstants(eHWSC_Pixel, pBind, fParams, nParams, registerCountMax); - return true; -} - -bool CShader::FXSetPSFloat(const char* NameParam, const Vec4* fParams, int nParams) -{ - return FXSetPSFloat(CCryNameR(NameParam), fParams, nParams); -} - -bool CShader::FXSetVSFloat(const CCryNameR& NameParam, const Vec4* fParams, int nParams) -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique) - { - return false; - } - SShaderPass* pPass = rd->m_RP.m_pCurPass; - if (!pPass) - { - return false; - } - CHWShader_D3D* curVS = (CHWShader_D3D*)pPass->m_VShader; - if (!curVS) - { - return false; - } - SCGBind* pBind = curVS->mfGetParameterBind(NameParam); - if (!pBind) - { - return false; - } - - const AZ::u32 registerCountMax = curVS->m_pCurInst->m_nMaxVecs[pBind->m_BindingSlot]; - AzRHI::ConstantBufferCache::GetInstance().WriteConstants(eHWSC_Vertex, pBind, fParams, nParams, registerCountMax); - return true; -} - -bool CShader::FXSetVSFloat(const char* NameParam, const Vec4* fParams, int nParams) -{ - return FXSetVSFloat(CCryNameR(NameParam), fParams, nParams); -} - -bool CShader::FXSetGSFloat(const CCryNameR& NameParam, const Vec4* fParams, int nParams) -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique) - { - return false; - } - SShaderPass* pPass = rd->m_RP.m_pCurPass; - if (!pPass) - { - return false; - } - CHWShader_D3D* curGS = (CHWShader_D3D*)pPass->m_GShader; - if (!curGS) - { - return false; - } - SCGBind* pBind = curGS->mfGetParameterBind(NameParam); - if (!pBind) - { - return false; - } - - const AZ::u32 registerCountMax = curGS->m_pCurInst->m_nMaxVecs[pBind->m_BindingSlot]; - AzRHI::ConstantBufferCache::GetInstance().WriteConstants(eHWSC_Geometry, pBind, fParams, nParams, registerCountMax); - return true; -} - -bool CShader::FXSetGSFloat(const char* NameParam, const Vec4* fParams, int nParams) -{ - return FXSetGSFloat(CCryNameR(NameParam), fParams, nParams); -} - -bool CShader::FXBegin(uint32* uiPassCount, uint32 nFlags) -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique || !rd->m_RP.m_pCurTechnique->m_Passes.Num()) - { - return false; - } - *uiPassCount = rd->m_RP.m_pCurTechnique->m_Passes.Num(); - rd->m_RP.m_nFlagsShaderBegin = nFlags; - rd->m_RP.m_pCurPass = &rd->m_RP.m_pCurTechnique->m_Passes[0]; - return true; -} - -bool CShader::FXBeginPass(uint32 uiPass) -{ - FUNCTION_PROFILER_RENDER_FLAT - CD3D9Renderer* rd = gcpRendD3D; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique || uiPass >= rd->m_RP.m_pCurTechnique->m_Passes.Num()) - { - return false; - } - rd->m_RP.m_pCurPass = &rd->m_RP.m_pCurTechnique->m_Passes[uiPass]; - SShaderPass* pPass = rd->m_RP.m_pCurPass; - //assert (pPass->m_VShader && pPass->m_PShader); - //if (!pPass->m_VShader || !pPass->m_PShader) - // return false; - CHWShader_D3D* curVS = (CHWShader_D3D*)pPass->m_VShader; - CHWShader_D3D* curPS = (CHWShader_D3D*)pPass->m_PShader; - CHWShader_D3D* curGS = (CHWShader_D3D*)pPass->m_GShader; - CHWShader_D3D* curCS = (CHWShader_D3D*)pPass->m_CShader; - - bool bResult = true; - - // Set Pixel-shader and all associated textures - if (curPS) - { - if (rd->m_RP.m_nFlagsShaderBegin & FEF_DONTSETTEXTURES) - { - bResult &= curPS->mfSet(0); - } - else - { - bResult &= curPS->mfSet(HWSF_SETTEXTURES); - } - curPS->UpdatePerInstanceConstantBuffer(); - } - // Set Vertex-shader - if (curVS) - { - // Allow vertex shaders to bind textures. - // Some existing vertex shaders do try to read textures, for example the shader function GetVolumetricFogAnalyticalColor - if (rd->m_RP.m_nFlagsShaderBegin & FEF_DONTSETTEXTURES) - { - bResult &= curVS->mfSet(0); - } - else - { - bResult &= curVS->mfSet(HWSF_SETTEXTURES); - } - - curVS->UpdatePerInstanceConstantBuffer(); - } - - // Set Geometry-shader - if (curGS) - { - if (rd->m_RP.m_nFlagsShaderBegin & FEF_DONTSETTEXTURES) - { - bResult &= curGS->mfSet(0); - } - else - { - bResult &= curGS->mfSet(HWSF_SETTEXTURES); - } - - curGS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindGS(NULL, NULL); - } - - // Set Compute-shader - if (curCS) - { - if (rd->m_RP.m_nFlagsShaderBegin & FEF_DONTSETTEXTURES) - { - bResult &= curCS->mfSet(0); - } - else - { - bResult &= curCS->mfSet(HWSF_SETTEXTURES); - } - curCS->UpdatePerInstanceConstantBuffer(); - } - else - { - CHWShader_D3D::mfBindCS(NULL, NULL); - } - - if (!(rd->m_RP.m_nFlagsShaderBegin & FEF_DONTSETSTATES)) - { - rd->FX_SetState(pPass->m_RenderState); - if (pPass->m_eCull != -1) - { - rd->D3DSetCull((ECull)pPass->m_eCull); - } - } - - return bResult; -} - -bool CShader::FXEndPass() -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique || !rd->m_RP.m_pCurTechnique->m_Passes.Num()) - { - return false; - } - rd->m_RP.m_pCurPass = NULL; - return true; -} - -bool CShader::FXEnd() -{ - CRenderer* rd = gRenDev; - if (!rd->m_RP.m_pShader || !rd->m_RP.m_pCurTechnique) - { - return false; - } - return true; -} - -bool CShader::FXCommit([[maybe_unused]] const uint32 nFlags) -{ - gcpRendD3D->FX_Commit(); - - return true; -} - - -void* CHWShader_D3D::GetVSDataForDecl(const D3D11_INPUT_ELEMENT_DESC* pDecl, int nCount, int& nDataSize) -{ - nDataSize = 0; - CShader* pSh = CShaderMan::s_ShaderFPEmu; - if (!pSh || !pSh->m_HWTechniques.Num() || !nCount) - { - return NULL; - } - uint32 i, j; - - SShaderTechnique* pTech = NULL; - for (i = 0; i < pSh->m_HWTechniques.Num(); i++) - { - if (!azstricmp(pSh->m_HWTechniques[i]->m_NameStr.c_str(), "InputLayout")) - { - pTech = pSh->m_HWTechniques[i]; - break; - } - } - if (!pTech || !pTech->m_Passes.Num()) - { - return NULL; - } - SShaderPass& Pass = pTech->m_Passes[0]; - CHWShader_D3D* pVS = (CHWShader_D3D*)Pass.m_VShader; - if (!pVS) - { - return NULL; - } - - uint32 nMask = 0; - //m_RP.m_FlagsShader_LT = m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorOp[0] | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaOp[0] << 8) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg[0] << 16) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg[0] << 24); - - for (i = 0; i < nCount; i++) - { - const D3D11_INPUT_ELEMENT_DESC& Desc = pDecl[i]; - if (Desc.InputSlot != 0) - { - nMask |= 1 << Desc.InputSlot; - if (nMask & VSM_TANGENTS) - { - for (j = 0; j < nCount; j++) - { - const D3D11_INPUT_ELEMENT_DESC& Desc2 = pDecl[j]; - if (!strcmp(Desc2.SemanticName, "BITANGENT") || !strcmp(Desc2.SemanticName, "BINORMAL")) - { - nMask |= (1 << VSF_QTANGENTS); - break; - } - } - } - } - else - if (!strcmp(Desc.SemanticName, "POSITION")) - { - if (Desc.Format == DXGI_FORMAT_R32G32_FLOAT) - { - nMask |= 0 << 8; - } - else - if (Desc.Format == DXGI_FORMAT_R32G32B32_FLOAT) - { - nMask |= 1 << 8; - } - else - if (Desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT || Desc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT) - { - nMask |= 2 << 8; - } - else - { - assert(0); - } - } - else - if (!strcmp(Desc.SemanticName, "TEXCOORD")) - { - int nShift = 0; - if (Desc.SemanticIndex == 0) - { - nMask |= eCA_Texture << 16; - nShift = 10; - if (Desc.Format == DXGI_FORMAT_R32G32_FLOAT || Desc.Format == DXGI_FORMAT_R16G16_FLOAT) - { - nMask |= 0 << nShift; - } - else - if (Desc.Format == DXGI_FORMAT_R32G32B32_FLOAT) - { - nMask |= 1 << nShift; - } - else - if (Desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT || Desc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT) - { - nMask |= 2 << nShift; - } - else - { - assert(0); - } - } - else - if (Desc.SemanticIndex == 1) - { - if (nMask & (eCA_Constant << 19)) - { - // PSIZE and TEX1 used together - nMask &= ~(0x7 << 19); - nMask |= eCA_Previous << 19; - } - else - { - nMask |= eCA_Texture1 << 19; - } - } - else - { - assert(0); - } - } - else - if (!strcmp(Desc.SemanticName, "COLOR")) - { - int nShift = 0; - if (Desc.SemanticIndex == 0) - { - nMask |= eCA_Diffuse << 24; - nShift = 12; - if (Desc.Format == DXGI_FORMAT_R32G32B32_FLOAT) - { - nMask |= 1 << nShift; - } - else - if (Desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM || Desc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT) - { - nMask |= 2 << nShift; - } - else - { - assert(0); - } - } - else - if (Desc.SemanticIndex == 1) - { - nMask |= eCA_Specular << 27; - } - else - { - assert(0); - } - } - else - if (!strcmp(Desc.SemanticName, "NORMAL")) - { - if (Desc.SemanticIndex == 0) - { - nMask |= eCA_Normal << 27; - } - else - { - assert(0); - } - //assert (Desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM); - } - else - if (!strcmp(Desc.SemanticName, "PSIZE")) - { - if (Desc.SemanticIndex == 0) - { - if (nMask & (eCA_Texture1 << 19)) - { - // PSIZE and TEX1 used together - nMask &= ~(0x7 << 19); - nMask |= eCA_Previous << 19; - } - else - { - nMask |= eCA_Constant << 19; - } - } - else - { - assert(0); - } - assert (Desc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT); - } - else - { - assert(0); - } - } - - SShaderCombIdent Ident; - Ident.m_LightMask = nMask; - Ident.m_RTMask = 0; - Ident.m_MDMask = 0; - Ident.m_MDVMask = 0; - Ident.m_GLMask = 0; - Ident.m_STMask = 0; - - SHWSInstance* pI = pVS->m_pCurInst; - - uint32 nFlags = HWSF_STOREDATA; - SHWSInstance* pInst = pVS->mfGetInstance(pSh, Ident, nFlags); - if (!pVS->mfCheckActivation(pSh, pInst, nFlags)) - { - pVS->m_pCurInst = pI; - return NULL; - } - pVS->m_pCurInst = pI; - - nDataSize = pInst->m_nDataSize; - return pInst->m_pShaderData; -} - -//=================================================================================== - -void CRenderer::RefreshSystemShaders() -{ - // make sure all system shaders are properly refreshed during loading! -#if defined(FEATURE_SVO_GI) - gRenDev->m_cEF.mfRefreshSystemShader("Total_Illumination", CShaderMan::s_ShaderSVOGI); -#endif - gRenDev->m_cEF.mfRefreshSystemShader("Common", CShaderMan::s_ShaderCommon); - gRenDev->m_cEF.mfRefreshSystemShader("Debug", CShaderMan::s_ShaderDebug); - gRenDev->m_cEF.mfRefreshSystemShader("DeferredCaustics", CShaderMan::s_ShaderDeferredCaustics); - gRenDev->m_cEF.mfRefreshSystemShader("DeferredRain", CShaderMan::s_ShaderDeferredRain); - gRenDev->m_cEF.mfRefreshSystemShader("DeferredSnow", CShaderMan::s_ShaderDeferredSnow); - gRenDev->m_cEF.mfRefreshSystemShader("DeferredShading", CShaderMan::s_shDeferredShading); - gRenDev->m_cEF.mfRefreshSystemShader("DepthOfField", CShaderMan::s_shPostDepthOfField); - gRenDev->m_cEF.mfRefreshSystemShader("DXTCompress", CShaderMan::s_ShaderDXTCompress); - gRenDev->m_cEF.mfRefreshSystemShader("LensOptics", CShaderMan::s_ShaderLensOptics); - gRenDev->m_cEF.mfRefreshSystemShader("SoftOcclusionQuery", CShaderMan::s_ShaderSoftOcclusionQuery); - gRenDev->m_cEF.mfRefreshSystemShader("MotionBlur", CShaderMan::s_shPostMotionBlur); - gRenDev->m_cEF.mfRefreshSystemShader("OcclusionTest", CShaderMan::s_ShaderOcclTest); - gRenDev->m_cEF.mfRefreshSystemShader("PostEffectsGame", CShaderMan::s_shPostEffectsGame); - gRenDev->m_cEF.mfRefreshSystemShader("ShadowBlur", CShaderMan::s_ShaderShadowBlur); - gRenDev->m_cEF.mfRefreshSystemShader("Stereo", CShaderMan::s_ShaderStereo); - gRenDev->m_cEF.mfRefreshSystemShader("Sunshafts", CShaderMan::s_shPostSunShafts); - gRenDev->m_cEF.mfRefreshSystemShader("Fur", CShaderMan::s_ShaderFur); -} - -bool CD3D9Renderer::FX_SetFPMode() -{ - assert (gRenDev->m_pRT->IsRenderThread()); - - if (!(m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_FP_DIRTY) && CShaderMan::s_ShaderFPEmu == m_RP.m_pShader) - { - return true; - } - if (m_bDeviceLost) - { - return false; - } - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_FP_DIRTY; - m_RP.m_pCurObject = m_RP.m_pIdendityRenderObject; - CShader* pSh = CShaderMan::s_ShaderFPEmu; - if (!pSh || !pSh->m_HWTechniques.Num()) - { - return false; - } - m_RP.m_FlagsShader_LT = m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorOp | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaOp << 8) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg << 16) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg << 24); - m_RP.m_FlagsShader_LT |= (m_RP.m_TI[m_RP.m_nProcessThreadID].m_sRGBWrite ? 1 : 0) << 22; - - if (CTexture::s_TexStages[0].m_DevTexture && CTexture::s_TexStages[0].m_DevTexture->IsCube()) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - else - { - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - - m_RP.m_pShader = pSh; - m_RP.m_pCurTechnique = pSh->m_HWTechniques[0]; - - bool bRes = pSh->FXBegin(&m_RP.m_nNumRendPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - if (!bRes) - { - return false; - } - bRes = pSh->FXBeginPass(0); - FX_Commit(); - return bRes; -} - -bool CD3D9Renderer::FX_SetUIMode() -{ - assert (gRenDev->m_pRT->IsRenderThread()); - - if (!(m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags & RBPF_FP_DIRTY) && CShaderMan::s_ShaderUI == m_RP.m_pShader) - { - return true; - } - if (m_bDeviceLost) - { - return false; - } - m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags &= ~RBPF_FP_DIRTY; - m_RP.m_pCurObject = m_RP.m_pIdendityRenderObject; - CShader* pSh = CShaderMan::s_ShaderUI; - if (!pSh || !pSh->m_HWTechniques.Num()) - { - return false; - } - m_RP.m_FlagsShader_LT = m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorOp | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaOp << 8) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg << 16) | (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg << 24); - m_RP.m_FlagsShader_LT |= (m_RP.m_TI[m_RP.m_nProcessThreadID].m_sRGBWrite ? 1 : 0) << 22; - - if (CTexture::s_TexStages[0].m_DevTexture && CTexture::s_TexStages[0].m_DevTexture->IsCube()) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - else - { - m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - - m_RP.m_pShader = pSh; - m_RP.m_pCurTechnique = pSh->m_HWTechniques[0]; - - bool bRes = pSh->FXBegin(&m_RP.m_nNumRendPasses, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - if (!bRes) - { - return false; - } - bRes = pSh->FXBeginPass(0); - FX_Commit(); - return bRes; -} - -void CShaderMan::mfCheckObjectDependParams(std::vector& PNoObj, std::vector& PObj, [[maybe_unused]] EHWShaderClass eSH, [[maybe_unused]] CShader* pFXShader) -{ - if (!PNoObj.size()) - { - return; - } - uint32 i; - for (i = 0; i < PNoObj.size(); i++) - { - SCGParam* prNoObj = &PNoObj[i]; - if ((prNoObj->m_eCGParamType & 0xff) == ECGP_PM_Tweakable) - { - int nType = prNoObj->m_eCGParamType & 0xff; - prNoObj->m_eCGParamType = (ECGParam)nType; - } - - if (prNoObj->m_Flags & PF_INSTANCE) - { - PObj.push_back(PNoObj[i]); - PNoObj.erase(PNoObj.begin() + i); - i--; - } - else - if (prNoObj->m_Flags & PF_MATERIAL) - { - PNoObj.erase(PNoObj.begin() + i); - i--; - } - } - if (PObj.size()) - { - int n = -1; - for (i = 0; i < PObj.size(); i++) - { - if (PObj[i].m_eCGParamType == ECGP_Matr_PI_ViewProj) - { - n = i; - break; - } - } - if (n > 0) - { - SCGParam pr = PObj[n]; - PObj[n] = PObj[0]; - PObj[0] = pr; - } - } -} - -bool CShaderMan::mfPreactivate2(CResFileLookupDataMan& LevelLookup, - const AZStd::string& pathPerLevel, const AZStd::string& pathGlobal, - bool bVS, bool bPersistent) -{ - bool bRes = true; - - AZStd::string allFilesPath = pathPerLevel + "/*.*"; - - AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(allFilesPath.c_str()); - if (!handle) - { - return bRes; - } - - do - { - if (handle.m_filename.front() == '.') - { - continue; - } - - AZStd::string fileInfoPerLevel = AZStd::string::format("%s/%.*s", pathPerLevel.c_str(), aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - AZStd::string fileInfoGlobal = AZStd::string::format("%s/%.*s", pathGlobal.c_str(), aznumeric_cast(handle.m_filename.size()), handle.m_filename.data()); - - if((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - bRes &= mfPreactivate2(LevelLookup, fileInfoPerLevel, fileInfoGlobal, bVS, bPersistent); - continue; - } - CResFile* pRes = new CResFile(fileInfoPerLevel.c_str()); - int bR = pRes ? pRes->mfOpen(RA_READ, &LevelLookup) : 0; - if (!bR) - { - Warning("ShaderCache rejected (damaged?) file %s: %s", fileInfoPerLevel.c_str(), pRes->mfGetError() ? pRes->mfGetError() : ""); - bRes = false; - SAFE_DELETE(pRes); - continue; - } - - SResFileLookupData* pLookupGlobal = gRenDev->m_cEF.m_ResLookupDataMan[CACHE_READONLY].GetData(fileInfoGlobal.c_str()); - if (!pLookupGlobal) - { - SAFE_DELETE(pRes); - continue; - } - SResFileLookupData* pLookupLevel = NULL; - if (!bPersistent) - { - CCryNameTSCRC name = LevelLookup.AdjustName(pRes->mfGetFileName()); - pLookupLevel = LevelLookup.GetData(name); - } - else - { - // Startup cache - const char* szName = pRes->mfGetFileName(); - CCryNameTSCRC name; - if (_strnicmp(szName, "ShaderCache/", 12) == 0) - { - stack_string sName = stack_string(g_shaderCache) + stack_string(&szName[12]); - name = sName.c_str(); - } - else if (_strnicmp(szName, g_shaderCache, 14) == 0) - { - name = LevelLookup.AdjustName(pRes->mfGetFileName()); - } - else - { - Warning("Wrong virtual directory in ShaderCacheStartup.pak"); - SAFE_DELETE(pRes); - continue; - } - pLookupLevel = LevelLookup.GetData(name); - } - if (!pLookupLevel) - { - SAFE_DELETE(pRes); - continue; - } - if (pLookupLevel->m_CacheMajorVer != pLookupGlobal->m_CacheMajorVer || pLookupLevel->m_CacheMinorVer != pLookupGlobal->m_CacheMinorVer || pLookupLevel->m_CRC32 != pLookupGlobal->m_CRC32) - { - SAFE_DELETE(pRes); - continue; - } - const char* s = fileInfoPerLevel.c_str(); - const uint32 nLen = strlen(s); - int nStart = -1; - int nEnd = -1; - bool bPC = false; - for (uint32 i = 0; i < nLen; i++) - { - uint32 n = nLen - i - 1; - char c = s[n]; - if (c == '.') - { - nEnd = n; - } - else - if (!bPC) - { - if (c == '@' || c == '/') - { - bPC = true; - } - } - else - if (c == '/') - { - nStart = n + 1; - break; - } - } - if (nStart < 0 || nEnd < 0) - { - SAFE_DELETE(pRes); - continue; - } - char str[128]; - memcpy(str, &s[nStart], nEnd - nStart); - str[nEnd - nStart] = 0; - CCryNameTSCRC Name = str; - FXCompressedShadersItor it = CHWShader::m_CompressedShaders.find(Name); - SHWActivatedShader* pAS = NULL; - if (it == CHWShader::m_CompressedShaders.end()) - { - pAS = new SHWActivatedShader; - pAS->m_bPersistent = bPersistent; - CHWShader::m_CompressedShaders.insert(FXCompressedShadersItor::value_type(Name, pAS)); - } - else - { - pAS = it->second; - } - ResDir* pDir = pRes->mfGetDirectory(); - for (uint32 i = 0; i < pDir->size(); i++) - { - SDirEntry& DE = (*pDir)[i]; - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_shadersdebug == 3 || CRenderer::CV_r_shadersdebug == 4) - { - iLog->Log("---Cache: PreactivateForLevel %s': 0x%x", pRes->mfGetFileName(), DE.Name.get()); - } - - FXCompressedShaderRemapItor itR = pAS->m_Remap.find(DE.Name); - uint32 nIDDev = DE.Name.get(); - assert(DE.offset > 0); - if (itR == pAS->m_Remap.end()) - { - pAS->m_Remap.insert(FXCompressedShaderRemapItor::value_type(DE.Name, nIDDev)); - itR = pAS->m_Remap.find(DE.Name); - } - FXCompressedShaderItor itS = pAS->m_CompressedShaders.find(itR->second); - if (itS == pAS->m_CompressedShaders.end()) - { - uint32 nSizeCompressed; - uint32 nSizeDecompressed; - byte* pDataCompressed = pRes->mfFileReadCompressed(&DE, nSizeDecompressed, nSizeCompressed); - if (!pDataCompressed) - { - SAFE_DELETE_ARRAY(pDataCompressed); - bRes = false; - continue; - } - - // only store compressed data - don't store token data for example because this is not compressed - if (nSizeCompressed == nSizeDecompressed) - { - SAFE_DELETE_ARRAY(pDataCompressed); - continue; - } - - if (nSizeCompressed > std::numeric_limits::max() || nSizeDecompressed > std::numeric_limits::max()) - { - CryFatalError("size of shader %s (compressed: %u, decompressed: %u) is too big to be stored in uint32", pRes->mfGetFileName(), (uint)nSizeCompressed, (uint)nSizeDecompressed); - SAFE_DELETE_ARRAY(pDataCompressed); - bRes = false; - continue; - } - - SCompressedData CD; - CD.m_nSizeCompressedShader = nSizeCompressed; - CD.m_nSizeDecompressedShader = nSizeDecompressed; - CD.m_pCompressedShader = pDataCompressed; - assert (CD.m_nSizeCompressedShader != CD.m_nSizeDecompressedShader); - - /*byte *pData = new byte[CD.m_nSizeDecompressedShader+1]; - pData[CD.m_nSizeDecompressedShader] = 0xaa; - Decodem(CD.m_pCompressedShader, pData, CD.m_nSizeCompressedShader); - assert(pData[CD.m_nSizeDecompressedShader] == 0xaa); - SShaderCacheHeaderItem *pIt = (SShaderCacheHeaderItem *)pData; - if (CParserBin::m_bEndians) - SwapEndian(*pIt, eBigEndian); - SAFE_DELETE_ARRAY(pData);*/ - - pAS->m_CompressedShaders.insert(FXCompressedShaderItor::value_type(nIDDev, CD)); - } - else - { -#ifdef _DEBUG - uint32 nSizeCompressed; - uint32 nSizeDecompressed; - byte* pDataCompressed = pRes->mfFileReadCompressed(&DE, nSizeDecompressed, nSizeCompressed); - assert(nSizeCompressed < 65536 && nSizeDecompressed < 65536); - assert(pDataCompressed); - if (pDataCompressed) - { - SCompressedData& CD1 = itS->second; - assert(CD1.m_nSizeCompressedShader == nSizeCompressed); - SAFE_DELETE_ARRAY(pDataCompressed); - } -#endif - } - } - SAFE_DELETE(pRes); - } while (handle = gEnv->pCryPak->FindNext(handle)); - - gEnv->pCryPak->FindClose (handle); - - return bRes; -} - -int SHWActivatedShader::Size() -{ - int nSize = sizeof(SHWActivatedShader); - nSize += sizeOfMap(m_CompressedShaders); - nSize += sizeOfMapS(m_Remap); - - return nSize; -} - -void SHWActivatedShader::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(this, sizeof(SHWActivatedShader)); - pSizer->AddObject(m_CompressedShaders); - pSizer->AddObject(m_Remap); -} - -SHWActivatedShader::~SHWActivatedShader() -{ - FXCompressedShaderItor it; - for (it = m_CompressedShaders.begin(); it != m_CompressedShaders.end(); ++it) - { - SCompressedData& Data = it->second; - SAFE_DELETE_ARRAY(Data.m_pCompressedShader); - } - m_CompressedShaders.clear(); - m_Remap.clear(); -} -bool CShaderMan::mfReleasePreactivatedShaderData() -{ - FXCompressedShadersItor it; - std::vector DelStuff; - for (it = CHWShader::m_CompressedShaders.begin(); it != CHWShader::m_CompressedShaders.end(); ++it) - { - SHWActivatedShader* pAS = it->second; - if (pAS && !pAS->m_bPersistent) - { - SAFE_DELETE(pAS); - DelStuff.push_back(it->first); - } - } - uint32 i; - for (i = 0; i < DelStuff.size(); i++) - { - CHWShader::m_CompressedShaders.erase(DelStuff[i]); - } - return true; -} - -bool CShaderMan::mfPreactivateShaders2( - [[maybe_unused]] const char* szPak, const char* szPath, bool bPersistent, [[maybe_unused]] const char* szBindRoot) -{ - mfReleasePreactivatedShaderData(); - - bool bRes = true; - - // Get shader platform name and make it lower - AZStd::string shaderLanguageName = GetShaderLanguageName(); - AZStd::to_lower(shaderLanguageName.begin(), shaderLanguageName.end()); - - const AZStd::string pathPerLevel = AZStd::string::format( "%s%s/", szPath, shaderLanguageName.c_str()); - - CResFileLookupDataMan LevelLookup; - bool bLoaded = LevelLookup.LoadData((pathPerLevel + "lookupdata.bin").c_str(), CParserBin::m_bEndians, true); - if (bLoaded) - { - - const char* cgcShaders = "cgcshaders"; - const char* cgdShaders = "cgdshaders"; - const char* cggShaders = "cggshaders"; - const char* cghShaders = "cghshaders"; - const char* cgpShaders = "cgpshaders"; - const char* cgvShaders = "cgvshaders"; - - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cgcShaders, pathPerLevel + cgcShaders, false, bPersistent); - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cgdShaders, pathPerLevel + cgdShaders, false, bPersistent); - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cggShaders, pathPerLevel + cggShaders, false, bPersistent); - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cghShaders, pathPerLevel + cghShaders, false, bPersistent); - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cgpShaders, pathPerLevel + cgpShaders, false, bPersistent); - bRes &= mfPreactivate2(LevelLookup, pathPerLevel + cgvShaders, pathPerLevel + cgvShaders, true, bPersistent); - } - - return bRes; -} - - -void CHWShader_D3D::mfLogShaderCacheMiss(SHWSInstance* pInst) -{ - CShaderMan& Man = gRenDev->m_cEF; - - // update the stats - Man.m_ShaderCacheStats.m_nGlobalShaderCacheMisses++; - - // don't do anything else if CVar is disabled and no callback is registered - if (CRenderer::CV_r_shaderslogcachemisses == 0 && Man.m_ShaderCacheMissCallback == 0) - { - return; - } - - char nameCache[256]; - azstrcpy(nameCache, AZ_ARRAY_SIZE(nameCache), GetName()); - char* s = strchr(nameCache, '('); - if (s) - { - s[0] = 0; - } - string sNew; - SShaderCombIdent Ident = pInst->m_Ident; - Ident.m_GLMask = m_nMaskGenFX; - gRenDev->m_cEF.mfInsertNewCombination(Ident, pInst->m_eClass, nameCache, 0, &sNew, 0); - - if (CRenderer::CV_r_shaderslogcachemisses > 1 && !gRenDev->m_bShaderCacheGen && !gEnv->IsEditor()) - { - CryWarning(VALIDATOR_MODULE_RENDERER, VALIDATOR_WARNING, "[SHADERS] GCM Global Cache Miss: %s\n", sNew.c_str()); - } - - string sEntry; - - sEntry = "["; - sEntry += GetShaderListFilename().c_str(); - sEntry += "]"; - sEntry += sNew; - - CCryNameTSCRC cryName(sEntry); - - // do we already contain this entry (vec is sorted so lower bound gives us already the good position to insert) - CShaderMan::ShaderCacheMissesVec::iterator it = std::lower_bound(Man.m_ShaderCacheMisses.begin(), Man.m_ShaderCacheMisses.end(), cryName); - if (it == Man.m_ShaderCacheMisses.end() || cryName != (*it)) - { - Man.m_ShaderCacheMisses.insert(it, cryName); - - if (CRenderer::CV_r_shaderslogcachemisses) - { - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - gEnv->pFileIO->Open(Man.m_ShaderCacheMissPath.c_str(), AZ::IO::OpenMode::ModeAppend | AZ::IO::OpenMode::ModeUpdate, fileHandle); - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "%s\n", sEntry.c_str()); - gEnv->pFileIO->Close(fileHandle); - } - } - - // call callback if provided to inform client about misses - if (Man.m_ShaderCacheMissCallback) - { - (*Man.m_ShaderCacheMissCallback)(sEntry.c_str()); - } - } -} - -void CHWShader_D3D::mfLogShaderRequest([[maybe_unused]] SHWSInstance* pInst) -{ -#if !defined(_RELEASE) - IF (CRenderer::CV_r_shaderssubmitrequestline > 1, 0) - { - mfSubmitRequestLine(pInst); - } -#endif -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DShadows.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DShadows.cpp deleted file mode 100644 index f5ff24f46b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DShadows.cpp +++ /dev/null @@ -1,2004 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : shadows support. - - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include -#include "../Common/Shadow_Renderer.h" -#include "../Common/ReverseDepth.h" -#include "D3DPostProcess.h" - -#include "I3DEngine.h" - -#include "GraphicsPipeline/Common/GraphicsPipelinePass.h" - -#include "Common/RenderView.h" - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(D3DShadows_cpp) -#endif - -namespace -{ - CryCriticalSection g_cDynTexLock; -} - -void CD3D9Renderer::EF_PrepareShadowGenRenderList() -{ - AZ_TRACE_METHOD(); - int nThreadID = m_RP.m_nFillThreadID; - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - int NumDynLights = m_RP.m_DLights[nThreadID][nCurRecLevel].Num(); - - //TFIX nCurRecLevel+1 is incorrect - TArray& arrDeferLights = CDeferredShading::Instance().GetLights(nThreadID, nCurRecLevel); - - RegisterFinalizeShadowJobs(nThreadID); - - if (NumDynLights <= 0 && arrDeferLights.Num() <= 0) - { - return; - } - - for (int nLightID = 0; nLightID < NumDynLights; nLightID++) - { - SRenderLight* pLight = &m_RP.m_DLights[nThreadID][nCurRecLevel][nLightID]; - EF_PrepareShadowGenForLight(pLight, nLightID); - } - - for (uint32 nDeferLightID = 0; nDeferLightID < arrDeferLights.Num(); nDeferLightID++) - { - SRenderLight* pLight = &arrDeferLights[nDeferLightID]; - EF_PrepareShadowGenForLight(pLight, (NumDynLights + nDeferLightID)); - } - - // add custom frustums - { - ShadowMapFrustum* arrCustomFrustums; - int nFrustumCount; - gEnv->p3DEngine->GetCustomShadowMapFrustums(arrCustomFrustums, nFrustumCount); - - for (uint32 i = 0; i < nFrustumCount; ++i) - { - if (PrepareShadowGenForFrustum(&arrCustomFrustums[i], NULL, 0, i)) - { - SRenderPipeline::SShadowFrustumToRender* pToRender = m_RP.SShadowFrustumToRenderList[nThreadID].AddIndex(1); - pToRender->pFrustum = &arrCustomFrustums[i]; - pToRender->nRecursiveLevel = nCurRecLevel; - pToRender->nLightID = 0; - pToRender->pLight = NULL; - } - } - } -} - -bool CD3D9Renderer::EF_PrepareShadowGenForLight(SRenderLight* pLight, int nLightID) -{ - assert((unsigned int) nLightID < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - if ((unsigned int) nLightID >= (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)) - { - //Warning("CRenderer::EF_PrepareShadowGenForLight: Too many light sources used ..."); // redundant - return false; - } - int nThreadID = m_RP.m_nFillThreadID; - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - if (!(pLight->m_Flags & DLF_CASTSHADOW_MAPS)) - { - return false; - } - - const int nLightFrustumBaseID = nLightID * MAX_SHADOWMAP_LOD; - - ShadowMapFrustum** ppSMFrustumList = pLight->m_pShadowMapFrustums; - if (!ppSMFrustumList) - { - return false; - } - - - int32 nCurLOD = 0; - - for (int nCaster = 0; *ppSMFrustumList && nCaster != MAX_GSM_LODS_NUM; ++ppSMFrustumList, ++nCaster) - { - //use pools - if (CV_r_UseShadowsPool && pLight->m_Flags & DLF_DEFERRED_LIGHT) - { - (*ppSMFrustumList)->bUseShadowsPool = true; - } - else - { - (*ppSMFrustumList)->bUseShadowsPool = false; - } - - if (PrepareShadowGenForFrustum(*ppSMFrustumList, pLight, nLightFrustumBaseID, nCurLOD)) - { - SRenderPipeline::SShadowFrustumToRender* pToRender = m_RP.SShadowFrustumToRenderList[nThreadID].AddIndex(1); - pToRender->pFrustum = (*ppSMFrustumList); - pToRender->nRecursiveLevel = nCurRecLevel; - pToRender->nLightID = nLightID; - pToRender->pLight = pLight; - nCurLOD++; - } - } - - return true; -} - -bool CD3D9Renderer::PrepareShadowGenForFrustum(ShadowMapFrustum* pCurFrustum, SRenderLight* pLight, [[maybe_unused]] int nLightFrustumBaseID, [[maybe_unused]] int nLOD) -{ - int nThreadID = m_RP.m_nFillThreadID; - assert(SRendItem::m_RecurseLevel[nThreadID] == 0); - - PROFILE_FRAME(PrepareShadowGenForFrustum); - - //validate shadow frustum - assert(pCurFrustum); - if (!pCurFrustum) - { - return false; - } - if (pCurFrustum->m_castersList.IsEmpty() && pCurFrustum->m_jobExecutedCastersList.IsEmpty() && - !pCurFrustum->IsCached() && pCurFrustum->m_eFrustumType != ShadowMapFrustum::e_GsmDynamicDistance) - { - return false; - } - if (pCurFrustum->IsCached() && pCurFrustum->nTexSize == 0) - { - return false; - } - ////////////////////////////////////////////////////////////////////////// - - //regenerate on reset device - if (pCurFrustum->nResetID != m_nFrameReset) - { - pCurFrustum->nResetID = m_nFrameReset; - pCurFrustum->RequestUpdate(); - } - - int nShadowGenGPU = 0; - - if (GetActiveGPUCount() > 1 && CV_r_ShadowGenMode == 1) - { - //TOFIx: make m_nFrameSwapID - double buffered - nShadowGenGPU = gRenDev->RT_GetCurrGpuID(); - - pCurFrustum->nOmniFrustumMask = 0x3F; - //in case there was switch on the fly - regenerate all faces - if (pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] > 0) - { - pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] = 0x3F; - } - } - - - - bool bNotNeedUpdate = false; - if (pCurFrustum->bOmniDirectionalShadow) - { - bNotNeedUpdate = !(pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] & pCurFrustum->nOmniFrustumMask); - } - else - { - bNotNeedUpdate = !pCurFrustum->isUpdateRequested(nShadowGenGPU); - } - - if (bNotNeedUpdate && !pCurFrustum->bUseShadowsPool) - { - memset(pCurFrustum->nShadowGenID[nThreadID], 0xFF, sizeof(pCurFrustum->nShadowGenID[nThreadID])); - return pCurFrustum->nShadowGenMask != 0; - } - - - if (pCurFrustum->bUseShadowsPool) - { - pCurFrustum->nShadowPoolUpdateRate = min((uint32)CRenderer::CV_r_ShadowPoolMaxFrames, (uint32)pCurFrustum->nShadowPoolUpdateRate); - if (!bNotNeedUpdate) - { - pCurFrustum->nShadowPoolUpdateRate >>= 2; - } - } - - ////////////////////////////////////////////////////////////////////////// - // update is requested - we should generate new shadow map - ////////////////////////////////////////////////////////////////////////// - //force unwrap frustum - if (pCurFrustum->bOmniDirectionalShadow) - { - pCurFrustum->bUnwrapedOmniDirectional = true; - } - else - { - pCurFrustum->bUnwrapedOmniDirectional = false; - } - - ETEX_Type eTT = (pCurFrustum->bOmniDirectionalShadow && !pCurFrustum->bUnwrapedOmniDirectional) ? eTT_Cube : eTT_2D; - - ////////////////////////////////////////////////////////////////////////// - //recalculate LOF rendering params - ////////////////////////////////////////////////////////////////////////// - - //calc texture resolution and frustum resolution - pCurFrustum->nTexSize = max(pCurFrustum->nTexSize, 32); - pCurFrustum->nTextureWidth = pCurFrustum->nTexSize; - pCurFrustum->nTextureHeight = pCurFrustum->nTexSize; - pCurFrustum->nShadowMapSize = pCurFrustum->nTexSize; - - if (pCurFrustum->bUnwrapedOmniDirectional) - { - pCurFrustum->nTextureWidth = pCurFrustum->nTexSize * 3; - pCurFrustum->nTextureHeight = pCurFrustum->nTexSize * 2; - } - - ////////////////////////////////////////////////////////////////////////// - //Select shadow buffers format - ////////////////////////////////////////////////////////////////////////// - ETEX_Format eTF = eTF_D32F; - if (pCurFrustum->IsCached()) - { - eTF = CV_r_ShadowsCacheFormat == 0 ? eTF_D32F : eTF_D16; - } - else if IsCVarConstAccess(constexpr) (CV_r_shadowtexformat == 0) - { - eTF = eTF_D32F; - } - else if IsCVarConstAccess(constexpr) (CV_r_shadowtexformat == 1) - { - eTF = eTF_D16; - } - else - { - eTF = eTF_D24S8; - } - - if (pCurFrustum->bOmniDirectionalShadow && !(pCurFrustum->bUnwrapedOmniDirectional)) - { - pCurFrustum->bHWPCFCompare = false; - } - else - { - const bool bSun = pLight && (pLight->m_Flags & DLF_SUN) != 0; - pCurFrustum->bHWPCFCompare = !bSun || (CV_r_ShadowsPCFiltering != 0); - } - //assign requested texture format - pCurFrustum->m_eReqTF = eTF; - pCurFrustum->m_eReqTT = eTT; - - //assign owners - pCurFrustum->pFrustumOwner = pCurFrustum; - - //actual view camera position - Vec3 vCamOrigin = iSystem->GetViewCamera().GetPosition(); - - CCamera tmpCamera; - - int nSides = 1; - if (pCurFrustum->bOmniDirectionalShadow) - { - nSides = OMNI_SIDES_NUM; - } - - // Static shadow map might not have any active casters, so don't reset nShadowGenMask every frame - if (!pCurFrustum->IsCached()) - { - pCurFrustum->nShadowGenMask = pCurFrustum->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance ? 1 : 0; - } - Matrix44 m; - - for (int nS = 0; nS < nSides; nS++) - { - //update check for shadow frustums - if (pCurFrustum->bOmniDirectionalShadow && !pCurFrustum->bUseShadowsPool) - { - if (!((pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] & pCurFrustum->nOmniFrustumMask) & (1 << nS))) - { - continue; - } - else - { - pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] &= ~(1 << nS); - } - } - else - { - pCurFrustum->nInvalidatedFrustMask[nShadowGenGPU] = 0; - } - - ////////////////////////////////////////////////////////////////////////// - // Calc frustum CCamera for current frustum - ////////////////////////////////////////////////////////////////////////// - if (!pCurFrustum->bOmniDirectionalShadow) - { - if (pCurFrustum->m_Flags & (DLF_PROJECT | DLF_AREA_LIGHT)) - { - SRenderLight instLight = *pLight; - if (pLight->m_Flags & DLF_AREA_LIGHT) - { - // Pull the shadow frustum back to encompas the area of the light source. - float fMaxSize = max(pLight->m_fAreaWidth, pLight->m_fAreaHeight); - float fScale = fMaxSize / max(tanf(DEG2RAD(pLight->m_fLightFrustumAngle)), 0.0001f); - - Vec3 vOffsetDir = fScale * pLight->m_ObjMatrix.GetColumn0().GetNormalized(); - instLight.SetPosition(instLight.m_Origin - vOffsetDir); - instLight.m_fProjectorNearPlane = fScale; - } - - // Frustum angle is clamped to prevent projection matrix problems. - // We clamp here because area lights and non-shadow casting lights can cast 180 degree light. - CShadowUtils::GetCubemapFrustumForLight(&instLight, 0, min(2 * pLight->m_fLightFrustumAngle, 175.0f), &(pCurFrustum->mLightProjMatrix), &(pCurFrustum->mLightViewMatrix), false); - } - else - { - if (pCurFrustum->m_eFrustumType == ShadowMapFrustum::e_PerObject) - { - AABB lsBounds = CShadowUtils::GetShadowMatrixForCasterBox(pCurFrustum->mLightProjMatrix, pCurFrustum->mLightViewMatrix, pCurFrustum, 20.f); - - // normalize filter filter kernel size to dimensions of light space bounding box - pCurFrustum->fWidthS *= pCurFrustum->nTextureWidth / (lsBounds.max.x - lsBounds.min.x); - pCurFrustum->fWidthT *= pCurFrustum->nTextureHeight / (lsBounds.max.y - lsBounds.min.y); - } - else if (pCurFrustum->m_eFrustumType != ShadowMapFrustum::e_HeightMapAO) - { - CShadowUtils::GetShadowMatrixOrtho(pCurFrustum->mLightProjMatrix, pCurFrustum->mLightViewMatrix, m_CameraMatrix, pCurFrustum, false); - } - } - - //Pre-multiply matrices - Matrix44 mViewProj = Matrix44(pCurFrustum->mLightViewMatrix) * Matrix44(pCurFrustum->mLightProjMatrix); - pCurFrustum->mLightViewMatrix = mViewProj; - pCurFrustum->mLightProjMatrix.SetIdentity(); - - tmpCamera = gEnv->p3DEngine->GetRenderingCamera(); - } - else - { - tmpCamera = pCurFrustum->FrustumPlanes[nS]; - } - - - ////////////////////////////////////////////////////////////////////////// - // Invoke IRenderNode::Render Jobs - ////////////////////////////////////////////////////////////////////////// - uint32 nShadowGenID = m_nShadowGenId[nThreadID]; - m_nShadowGenId[nThreadID] += 1; - - pCurFrustum->nShadowGenID[nThreadID][nS] = nShadowGenID; - - uint32 nRenderingFlags = SRenderingPassInfo::DEFAULT_FLAGS; - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*pCurFrustum)) - { - // we need correct diffuse texture for every chunk - nRenderingFlags |= SRenderingPassInfo::DISABLE_RENDER_CHUNK_MERGE; - } -#endif - // create a matching rendering pass info for shadows - SRenderingPassInfo passInfo = SRenderingPassInfo::CreateShadowPassRenderingInfo(tmpCamera, pCurFrustum->m_Flags, pCurFrustum->nShadowMapLod, - pCurFrustum->IsCached(), pCurFrustum->bIsMGPUCopy, &pCurFrustum->nShadowGenMask, nS, nShadowGenID, nRenderingFlags); - - StartInvokeShadowMapRenderJobs(pCurFrustum, passInfo); - }//nSides - - return true; -} - -//----------------------------------------------------------------------------- -void CD3D9Renderer::PrepareShadowGenForFrustumNonJobs([[maybe_unused]] const int nFlags) -{ - int nThreadID = m_RP.m_nFillThreadID; -#if !defined(NDEBUG) - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); -#endif - - CCamera tmpCamera; - - for (int i = 0; i < m_RP.SShadowFrustumToRenderList[nThreadID].size(); ++i) - { - SRenderPipeline::SShadowFrustumToRender& rFrustumToRender = m_RP.SShadowFrustumToRenderList[nThreadID][i]; - ShadowMapFrustum* pCurFrustum = rFrustumToRender.pFrustum; - - int nSides = pCurFrustum->bOmniDirectionalShadow ? OMNI_SIDES_NUM : 1; - - for (int nS = 0; nS < nSides; nS++) - { - if (pCurFrustum->nShadowGenID[nThreadID][nS] == 0xFFFFFFFF) - { - continue; - } - - ////////////////////////////////////////////////////////////////////////// - // Calc frustum CCamera for current frustum - ////////////////////////////////////////////////////////////////////////// - if (!pCurFrustum->bOmniDirectionalShadow) - { - tmpCamera = gEnv->p3DEngine->GetRenderingCamera(); - } - else - { - tmpCamera = pCurFrustum->FrustumPlanes[nS]; - } - ////////////////////////////////////////////////////////////////////////// - // Invoke IRenderNode::Render - ////////////////////////////////////////////////////////////////////////// - - - uint32 nRenderingFlags = SRenderingPassInfo::DEFAULT_FLAGS; - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*pCurFrustum)) - { - // we need correct diffuse texture for every chunk - nRenderingFlags |= SRenderingPassInfo::DISABLE_RENDER_CHUNK_MERGE; - } -#endif - - // create a matching rendering pass info for shadows - SRenderingPassInfo passInfo = SRenderingPassInfo::CreateShadowPassRenderingInfo(tmpCamera, pCurFrustum->m_Flags, pCurFrustum->nShadowMapLod, - pCurFrustum->IsCached(), pCurFrustum->bIsMGPUCopy, &pCurFrustum->nShadowGenMask, nS, pCurFrustum->nShadowGenID[nThreadID][nS], nRenderingFlags); - - for (int casterIdx = 0; casterIdx < pCurFrustum->m_castersList.Count(); ++casterIdx) - { - IShadowCaster* pEnt = pCurFrustum->m_castersList[casterIdx]; - - //TOFIX reactivate OmniDirectionalShadow - if (pCurFrustum->bOmniDirectionalShadow) - { - AABB aabb = pEnt->GetBBoxVirtual(); - //!!! Reactivate proper camera - bool bVis = tmpCamera.IsAABBVisible_F(aabb); - if (!bVis) - { - continue; - } - } - - if ((pCurFrustum->m_Flags & DLF_DIFFUSEOCCLUSION) && pEnt->HasOcclusionmap(0, pCurFrustum->pLightOwner)) - { - continue; - } - - gEnv->p3DEngine->RenderRenderNode_ShadowPass(pEnt, passInfo, NULL); - } - } - } -} - -//----------------------------------------------------------------------------- -// Name: GetTextureRect() -// Desc: Get the dimensions of the texture -//----------------------------------------------------------------------------- -HRESULT GetTextureRect(CTexture* pTexture, RECT* pRect) -{ - pRect->left = 0; - pRect->top = 0; - pRect->right = pTexture->GetWidth(); - pRect->bottom = pTexture->GetHeight(); - - return S_OK; -} - -void CD3D9Renderer::OnEntityDeleted(IRenderNode* pRenderNode) -{ - m_pRT->RC_EntityDelete(pRenderNode); -} - -void _DrawText(ISystem* pSystem, int x, int y, const float fScale, const char* format, ...) -PRINTF_PARAMS(5, 6); - -void _DrawText([[maybe_unused]] ISystem* pSystem, int x, int y, const float fScale, const char* format, ...) -{ - char buffer[512]; - va_list args; - va_start(args, format); - vsprintf_s(buffer, format, args); - va_end(args); - - float color[4] = {0, 1, 0, 1}; - gEnv->pRenderer->Draw2dLabel((float)x, (float)y, fScale, color, false, buffer); -} - -void CD3D9Renderer::DrawAllShadowsOnTheScreen() -{ - float width = 800; - float height = 600; - - TransformationMatrices backupSceneMatrices; - - Set2DMode(static_cast(width), static_cast(height), backupSceneMatrices); - - EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - EF_SetSrgbWrite(false); - - int nMaxCount = 16; - - float fArrDim = max(4.f, sqrtf((float)nMaxCount)); - float fPicDimX = width / fArrDim; - float fPicDimY = height / fArrDim; - int nShadowId = 0; - SDynTexture_Shadow* pTX = SDynTexture_Shadow::s_RootShadow.m_NextShadow; - for (float x = 0; nShadowId < nMaxCount && x < width - 10; x += fPicDimX) - { - for (float y = 0; nShadowId < nMaxCount && y < height - 10; y += fPicDimY) - { - static ICVar* pVar = iConsole->GetCVar("e_ShadowsDebug"); - if (pVar && pVar->GetIVal() == 1) - { - while (pTX->m_pTexture && (pTX->m_pTexture->m_nAccessFrameID + 2) < GetFrameID(false) && pTX != &SDynTexture_Shadow::s_RootShadow) - { - pTX = pTX->m_NextShadow; - } - } - - if (pTX == &SDynTexture_Shadow::s_RootShadow) - { - break; - } - - if (pTX->m_pTexture && pTX->pLightOwner) - { - CTexture* tp = pTX->m_pTexture; - if (tp) - { - int nSavedAccessFrameID = pTX->m_pTexture->m_nAccessFrameID; - - - SetState(/*GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | */ GS_NODEPTHTEST); - if (tp->GetTextureType() == eTT_2D) - { - //Draw2dImage(x, y, fPicDimX-1, fPicDimY-1, tp->GetID(), 0,1,1,0,180); - - // set shader - CShader* pSH(CShaderMan::s_ShaderShadowMaskGen); - - uint32 nPasses = 0; - static CCryNameTSCRC TechName = "DebugShadowMap"; - pSH->FXSetTechnique(TechName); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - pSH->FXBeginPass(0); - - Matrix44A origMatProj = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - Matrix44A* m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - mathMatrixOrthoOffCenterLH(m, 0.0f, (float)width, (float)height, 0.0f, -1e30f, 1e30f); - m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - - SetState(GS_NODEPTHTEST); - STexState ts(FILTER_LINEAR, false); - ts.m_nAnisotropy = 1; - tp->Apply(0, CTexture::GetTexState(ts)); - D3DSetCull(eCULL_None); - - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_T3F* vQuad = vb.Lock(); - - vQuad[0].p = Vec3(x, y, 1); - vQuad[0].st = Vec3(0, 1, 1); - //vQuad[0].color.dcolor = (uint32)-1; - vQuad[1].p = Vec3(x + fPicDimX - 1, y, 1); - vQuad[1].st = Vec3(1, 1, 1); - //vQuad[1].color.dcolor = (uint32)-1; - vQuad[3].p = Vec3(x + fPicDimX - 1, y + fPicDimY - 1, 1); - vQuad[3].st = Vec3(1, 0, 1); - //vQuad[3].color.dcolor = (uint32)-1; - vQuad[2].p = Vec3(x, y + fPicDimY - 1, 1); - vQuad[2].st = Vec3(0, 0, 1); - //vQuad[2].color.dcolor = (uint32)-1; - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_Commit(); - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj = origMatProj; - } - else - { - // set shader - CShader* pSH(CShaderMan::s_ShaderShadowMaskGen); - - uint32 nPasses = 0; - static CCryNameTSCRC TechName = "DebugCubeMap"; - pSH->FXSetTechnique(TechName); - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES | FEF_DONTSETTEXTURES); - pSH->FXBeginPass(0); - - float fSizeX = fPicDimX / 3; - float fSizeY = fPicDimY / 2; - float fx = ScaleCoordX(x); - fSizeX = ScaleCoordX(fSizeX); - float fy = ScaleCoordY(y); - fSizeY = ScaleCoordY(fSizeY); - float fOffsX[] = {fx, fx + fSizeX, fx + fSizeX * 2, fx, fx + fSizeX, fx + fSizeX * 2}; - float fOffsY[] = {fy, fy, fy, fy + fSizeY, fy + fSizeY, fy + fSizeY}; - Vec3 vTC0[] = {Vec3(1, 1, 1), Vec3(-1, 1, -1), Vec3(-1, 1, -1), Vec3(-1, -1, 1), Vec3(-1, 1, 1), Vec3(1, 1, -1)}; - Vec3 vTC1[] = {Vec3(1, 1, -1), Vec3(-1, 1, 1), Vec3(1, 1, -1), Vec3(1, -1, 1), Vec3(1, 1, 1), Vec3(-1, 1, -1)}; - Vec3 vTC2[] = {Vec3(1, -1, -1), Vec3(-1, -1, 1), Vec3(1, 1, 1), Vec3(1, -1, -1), Vec3(1, -1, 1), Vec3(-1, -1, -1)}; - Vec3 vTC3[] = {Vec3(1, -1, 1), Vec3(-1, -1, -1), Vec3(-1, 1, 1), Vec3(-1, -1, -1), Vec3(-1, -1, 1), Vec3(1, -1, -1)}; - - Matrix44A origMatProj = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - Matrix44A origMatView = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - Matrix44A* m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj; - mathMatrixOrthoOffCenterLH(m, 0.0f, (float)m_width, (float)m_height, 0.0f, -1e30f, 1e30f); - m = &m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView.SetIdentity(); - - SetState(GS_NODEPTHTEST); - STexState ts(FILTER_LINEAR, false); - ts.m_nAnisotropy = 1; - tp->Apply(0, CTexture::GetTexState(ts)); - - D3DSetCull(eCULL_None); - - for (int i = 0; i < 6; i++) - { - TempDynVB vb(gcpRendD3D); - vb.Allocate(4); - SVF_P3F_T3F* vQuad = vb.Lock(); - - vQuad[0].p = Vec3(fOffsX[i], fOffsY[i], 1); - vQuad[0].st = vTC0[i]; - //vQuad[0].color.dcolor = (uint32)-1; - vQuad[1].p = Vec3(fOffsX[i] + fSizeX - 1, fOffsY[i], 1); - vQuad[1].st = vTC1[i]; - //vQuad[1].color.dcolor = (uint32)-1; - vQuad[3].p = Vec3(fOffsX[i] + fSizeX - 1, fOffsY[i] + fSizeY - 1, 1); - vQuad[3].st = vTC2[i]; - //vQuad[3].color.dcolor = (uint32)-1; - vQuad[2].p = Vec3(fOffsX[i], fOffsY[i] + fSizeY - 1, 1); - vQuad[2].st = vTC3[i]; - //vQuad[2].color.dcolor = (uint32)-1; - - vb.Unlock(); - vb.Bind(0); - vb.Release(); - - if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F))) - { - FX_Commit(); - FX_DrawPrimitive(eptTriangleStrip, 0, 4); - } - } - - pSH->FXEndPass(); - pSH->FXEnd(); - - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView = origMatView; - m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj = origMatProj; - } - - pTX->m_pTexture->m_nAccessFrameID = nSavedAccessFrameID; - ILightSource* pLS = (ILightSource*)pTX->pLightOwner; - - _DrawText(iSystem, (int)(x / width * 800.f), (int)(y / height * 600.f), 1.0f, "%s \n %d %d-%d %d x%d", - pTX->m_pTexture->GetSourceName(), - pTX->m_nUniqueID, - pTX->m_pTexture ? pTX->m_pTexture->m_nUpdateFrameID : 0, - pTX->m_pTexture ? pTX->m_pTexture->m_nAccessFrameID : 0, - pTX->nObjectsRenderedCount, - pTX->m_nWidth); - - if (pLS->GetLightProperties().m_sName) - { - _DrawText(iSystem, (int)(x / width * 800.f), (int)(y / height * 600.f) + 32, 1.0f, "%s", pLS->GetLightProperties().m_sName); - } - } - } - pTX = pTX->m_NextShadow; - } - } - - Unset2DMode(backupSceneMatrices); -} - -Vec3 UnProject(ShadowMapFrustum* pFr, Vec3 vPoint) -{ - const int shadowViewport[4] = {0, 0, 1, 1}; - - Vec3 vRes(0, 0, 0); - gRenDev->UnProject(vPoint.x, vPoint.y, vPoint.z, - &vRes.x, &vRes.y, &vRes.z, - (float*)&pFr->mLightViewMatrix, - (float*)&pFr->mLightProjMatrix, - shadowViewport); - - return vRes; -} - -////////////////////////////////////////////////////////////////////////// - -namespace -{ - struct CompareRSMRendItem - { - bool operator()(const SRendItem& a, const SRendItem& b) const - { - // Decal objects should be rendered last - int nDecalA = (a.ObjSort & FOB_DECAL_MASK); - int nDecalB = (b.ObjSort & FOB_DECAL_MASK); - if ((nDecalA == 0) != (nDecalB == 0)) // Sort by decal flag - { - return nDecalA < nDecalB; - } - - if (nDecalA && nDecalB) - { - // decal sorting - uint32 objSortA_Low(a.ObjSort & 0xFFFF); - uint32 objSortA_High(a.ObjSort & ~0xFFFF); - uint32 objSortB_Low(b.ObjSort & 0xFFFF); - uint32 objSortB_High(b.ObjSort & ~0xFFFF); - - if (objSortA_Low != objSortB_Low) - { - return objSortA_Low < objSortB_Low; - } - - if (a.SortVal != b.SortVal) - { - return a.SortVal < b.SortVal; - } - - return objSortA_High < objSortB_High; - } - else - { - // usual sorting - if (a.SortVal != b.SortVal) // Sort by shaders - { - return a.SortVal < b.SortVal; - } - - if (a.pElem != b.pElem) // Sort by geometry - { - return a.pElem < b.pElem; - } - - return a.ObjSort < b.ObjSort; - } - } - }; -} - -bool CD3D9Renderer::PrepareDepthMap(ShadowMapFrustum* lof, int nLightFrustumID, bool bClearPool) -{ - int nThreadList = m_RP.m_nProcessThreadID; - assert(lof); - if (!lof) - { - return false; - } - - //select shadowgen gpu - int nShadowGenGPU = 0; - if (GetActiveGPUCount() > 1 && CV_r_ShadowGenMode == 1) - { - //TOFIx: make m_nFrameSwapID - double buffered - nShadowGenGPU = gRenDev->RT_GetCurrGpuID(); - } - - if (GetActiveGPUCount() > 1 && lof->IsCached()) - { - ShadowFrustumMGPUCache* pFrustumCache = GetShadowFrustumMGPUCache(); - pFrustumCache->nUpdateMaskRT &= ~(1 << gRenDev->RT_GetCurrGpuID()); - } - - // Save previous camera - int vX, vY, vWidth, vHeight; - GetViewport(&vX, &vY, &vWidth, &vHeight); - Matrix44 camMatr = m_CameraMatrix; - - // Setup matrices - Matrix44A origMatView = m_RP.m_TI[nThreadList].m_matView; - Matrix44A origMatProj = m_RP.m_TI[nThreadList].m_matProj; - - Matrix44A* m = &m_RP.m_TI[nThreadList].m_matProj; - m->SetIdentity(); - m = &m_RP.m_TI[nThreadList].m_matView; - m->SetIdentity(); - - lof->mLightProjMatrix.SetIdentity(); - - ////////////////////////////////////////////////////////////////////////// - // Assign RTs - ////////////////////////////////////////////////////////////////////////// - bool bTextureFromDynPool = false; - - if (lof->bUseShadowsPool) - { - lof->nTextureWidth = m_nShadowPoolWidth; - lof->nTextureHeight = m_nShadowPoolHeight; - - //current eTF should be stored in the shadow frustum - ETEX_Format ePoolTF = lof->m_eReqTF; - CTexture::s_ptexRT_ShadowPool->Invalidate(m_nShadowPoolWidth, m_nShadowPoolHeight, ePoolTF); - - if (!CTexture::IsTextureExist(CTexture::s_ptexRT_ShadowPool)) - { -#if !defined(_RELEASE) && !defined(WIN32) && !defined(WIN64) - __debugbreak(); // don't want any realloc on consoles -#endif - CTexture::s_ptexRT_ShadowPool->CreateRenderTarget(eTF_Unknown, Clr_FarPlane); - } - - lof->pDepthTex = CTexture::s_ptexRT_ShadowPool; - } - else - { - if (lof->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - CTexture* pTX = CTexture::s_ptexNearestShadowMap; - if (!CTexture::IsTextureExist(pTX)) - { - pTX->CreateRenderTarget(lof->m_eReqTF, Clr_FarPlane); - } - lof->pDepthTex = pTX; - - lof->fWidthS *= lof->nTextureWidth / (float)pTX->GetWidth(); - lof->fWidthT *= lof->nTextureHeight / (float)pTX->GetHeight(); - - lof->nTextureWidth = pTX->GetWidth(); - lof->nTextureHeight = pTX->GetHeight(); - } - - else if (lof->IsCached()) - { - if (lof->m_eFrustumType != ShadowMapFrustum::e_HeightMapAO) - { - assert(CV_r_ShadowsCache > 0 && CV_r_ShadowsCache <= MAX_GSM_LODS_NUM); - const int nStaticMapIndex = clamp_tpl(lof->nShadowMapLod - (CV_r_ShadowsCache - 1), 0, MAX_GSM_LODS_NUM - 1); - lof->pDepthTex = CTexture::s_ptexCachedShadowMap[nStaticMapIndex]; - } - else - { - lof->pDepthTex = CTexture::s_ptexHeightMapAODepth[0]; - } - } - else if (lof->m_eFrustumType != ShadowMapFrustum::e_GsmDynamicDistance) - { - bTextureFromDynPool = true; - SDynTexture_Shadow* pDynTX = SDynTexture_Shadow::GetForFrustum(lof); - lof->pDepthTex = pDynTX->m_pTexture; - } - } - - if (CTexture::IsTextureExist(lof->pDepthTex)) - { - int nSides = 1; - if (lof->bOmniDirectionalShadow) - { - nSides = OMNI_SIDES_NUM; - } - - int sideIndex; - int nFirstShadowGenRI, nLastShadowGenRI; - - int nOldScissor = CV_r_scissor; - int old_CV_r_nodrawnear = CV_r_nodrawnear; - int nPersFlags = m_RP.m_TI[nThreadList].m_PersFlags; - int nPersFlags2 = m_RP.m_PersFlags2; - int nStateAnd = m_RP.m_StateAnd; - m_RP.m_TI[nThreadList].m_PersFlags &= ~(RBPF_HDR | RBPF_MIRRORCULL); // In a mirrorcull pass (i.e. cubemap gen), remove mirrorculling for shadow gen (omni shadows should re-enable it later on) - m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_SHADOWGEN; - - if (!(lof->m_Flags & DLF_DIRECTIONAL)) - { - m_RP.m_PersFlags2 |= RBPF2_DRAWTOCUBE; - } - - //hack remove texkill for eTF_DF24 and eTF_D24S8 - if (lof->m_eReqTF == eTF_R32F || lof->m_eReqTF == eTF_R16G16F || lof->m_eReqTF == eTF_R16F || lof->m_eReqTF == eTF_R16G16B16A16F || - lof->m_eReqTF == eTF_D16 || lof->m_eReqTF == eTF_D24S8 || lof->m_eReqTF == eTF_D32F || lof->m_eReqTF == eTF_D32FS8) - { - m_RP.m_PersFlags2 |= RBPF2_NOALPHABLEND; - m_RP.m_StateAnd &= ~GS_BLEND_MASK; - } - - if (lof->m_eReqTF == eTF_R32F || lof->m_eReqTF == eTF_R16G16F || lof->m_eReqTF == eTF_R16F || lof->m_eReqTF == eTF_R16G16B16A16F) - { - m_RP.m_PersFlags2 |= RBPF2_NOALPHATEST; - m_RP.m_StateAnd &= ~GS_ALPHATEST_MASK; - } - CCamera saveCam = GetCamera(); - Vec3 vPos = lof->vLightSrcRelPos + lof->vProjTranslation; - - SDepthTexture depthTarget; - ZeroStruct(depthTarget); - - for (sideIndex = 0; sideIndex < nSides; sideIndex++) - { - if (nLightFrustumID >= 0)//skip for custom fustum - { - ////////////////////////////////////////////////////////////////////////// - //compute shadow recursive level - ////////////////////////////////////////////////////////////////////////// - const int nThreadID = m_RP.m_nProcessThreadID; - const int nShadowRecur = lof->nShadowGenID[nThreadID][sideIndex]; - - if (nShadowRecur == 0xFFFFFFFF) - { - continue; - } - - assert(nShadowRecur >= 0 && nShadowRecur < MAX_SHADOWMAP_FRUSTUMS); - - assert(nThreadID >= 0 && nThreadID < 2); - nFirstShadowGenRI = SRendItem::m_ShadowsStartRI[nThreadID][nShadowRecur]; - nLastShadowGenRI = SRendItem::m_ShadowsEndRI[nThreadID][nShadowRecur]; - const bool bClearRequired = lof->IsCached() && !lof->bIncrementalUpdate; - // If there's something to render, sort by lights. - if (nLastShadowGenRI - nFirstShadowGenRI > 0) - { - auto& renderItems = CRenderView::CurrentRenderView()->GetRenderItems(SG_SORT_GROUP, EFSLIST_SHADOW_GEN); - SRendItem* pFirst = &renderItems[nFirstShadowGenRI]; - SRendItem::mfSortByLight(pFirst, nLastShadowGenRI - nFirstShadowGenRI, true, false, false); - } - else if (!bClearRequired) - { - // Nothing to render and there's no need to clear, so we can just continue. - continue; - } - } - - depthTarget.nWidth = lof->nTextureWidth; - depthTarget.nHeight = lof->nTextureHeight; - depthTarget.nFrameAccess = -1; - depthTarget.bBusy = false; - depthTarget.pTex = lof->pDepthTex; - depthTarget.pTarget = lof->pDepthTex->GetDevTexture()->Get2DTexture(); - depthTarget.pSurf = lof->bOmniDirectionalShadow && !(lof->bUnwrapedOmniDirectional) - ? static_cast(lof->pDepthTex->GetDeviceDepthStencilSurf(sideIndex, 1)) - : static_cast(lof->pDepthTex->GetDeviceDepthStencilSurf()); - - CCamera tmpCamera; - if (!lof->bOmniDirectionalShadow) - { - *m = lof->mLightViewMatrix; - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_REVERSE_DEPTH; - - uint32 depthState = ReverseDepthHelper::ConvertDepthFunc(m_RP.m_CurState); - FX_SetState(m_RP.m_CurState, m_RP.m_CurAlphaRef, depthState); - -#if defined(FEATURE_SVO_GI) - if (!(lof->m_Flags & DLF_DIRECTIONAL) && CSvoRenderer::GetRsmColorMap(*lof)) - { - m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_MIRRORCULL; - } -#endif - } - else - { - const Matrix34& m34 = lof->FrustumPlanes[sideIndex].GetMatrix(); - CameraViewParameters c; - c.Perspective(tmpCamera.GetFov(), tmpCamera.GetProjRatio(), tmpCamera.GetNearPlane(), tmpCamera.GetFarPlane()); - Vec3 vEyeC = tmpCamera.GetPosition(); - Vec3 vAtC = vEyeC + Vec3(m34(0, 1), m34(1, 1), m34(2, 1)); - Vec3 vUpC = Vec3(m34(0, 2), m34(1, 2), m34(2, 2)); - c.LookAt(vEyeC, vAtC, vUpC); - ApplyViewParameters(c); - CShadowUtils::GetCubemapFrustum(FTYP_SHADOWOMNIPROJECTION, lof, sideIndex, &m_RP.m_TI[nThreadList].m_matProj, &m_RP.m_TI[nThreadList].m_matView, NULL); - - //enable back facing for omni lights for now - m_RP.m_TI[nThreadList].m_PersFlags |= RBPF_MIRRORCULL; - if (lof->m_Flags & DLF_AREA_LIGHT) - { - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_MIRRORCULL; - } - -#if defined(FEATURE_SVO_GI) - if (!(lof->m_Flags & DLF_DIRECTIONAL) && CSvoRenderer::GetRsmColorMap(*lof)) - { - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_MIRRORCULL; - } -#endif - } - - EF_SetCameraInfo(); - - //assign for shader's parameters - SRenderPipeline::ShadowInfo& shadowInfo = m_RP.m_ShadowInfo; - shadowInfo.m_pCurShadowFrustum = lof; - shadowInfo.m_nOmniLightSide = sideIndex; - shadowInfo.vViewerPos = saveCam.GetPosition(); - - { - CStandardGraphicsPipeline::ShadowParameters shadowParams; - shadowParams.m_ShadowFrustum = lof; - shadowParams.m_OmniLightSideIndex = sideIndex; - shadowParams.m_ViewerPos = shadowInfo.vViewerPos; - GetGraphicsPipeline().UpdatePerShadowConstantBuffer(shadowParams); - - AzRHI::ConstantBuffer* perShadow = GetGraphicsPipeline().GetPerShadowConstantBuffer().get(); - m_DevMan.BindConstantBuffer(eHWSC_Vertex, perShadow, eConstantBufferShaderSlot_PerPass); - m_DevMan.BindConstantBuffer(eHWSC_Pixel, perShadow, eConstantBufferShaderSlot_PerPass); - m_DevMan.BindConstantBuffer(eHWSC_Geometry, perShadow, eConstantBufferShaderSlot_PerPass); - m_DevMan.BindConstantBuffer(eHWSC_Hull, perShadow, eConstantBufferShaderSlot_PerPass); - m_DevMan.BindConstantBuffer(eHWSC_Domain, perShadow, eConstantBufferShaderSlot_PerPass); - m_DevMan.BindConstantBuffer(eHWSC_Compute, perShadow, eConstantBufferShaderSlot_PerPass); - } - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*lof, true) && CSvoRenderer::GetRsmNormlMap(*lof, true)) - { - FX_PushRenderTarget(0, CSvoRenderer::GetInstance()->GetRsmColorMap(*lof), &depthTarget, lof->m_eReqTT == eTT_Cube ? sideIndex : -1); - FX_PushRenderTarget(1, CSvoRenderer::GetInstance()->GetRsmNormlMap(*lof), NULL, lof->m_eReqTT == eTT_Cube ? sideIndex : -1); - } - else -#endif - { - FX_PushRenderTarget(0, nullptr, &depthTarget, lof->m_eReqTT == eTT_Cube ? sideIndex : -1); - FX_SetColorDontCareActions(0, true, true); - } - - //SDW-GEN_REND_PATH - ////////////////////////////////////////////////////////////////////////// - // clear frame buffer after RT push - ////////////////////////////////////////////////////////////////////////// - if (!lof->bIncrementalUpdate) - { - uint32_t clearFlags = 0; - - const bool bReverseDepth = (m_RP.m_TI[nThreadList].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - - if (lof->bUseShadowsPool) - { - if (bClearPool) - { - const RECT rect = { lof->packX[sideIndex], lof->packY[sideIndex], lof->packX[sideIndex] + lof->packWidth[sideIndex], lof->packY[sideIndex] + lof->packHeight[sideIndex] }; - - FX_ClearTarget(&depthTarget, CLEAR_ZBUFFER, Clr_FarPlane_R.r, 0, 1, &rect, false); - clearFlags |= CLEAR_ZBUFFER; - } - } - else - { -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*lof, true) && CSvoRenderer::GetRsmNormlMap(*lof, true)) - { - FX_ClearTarget(CSvoRenderer::GetInstance()->GetRsmColorMap(*lof), Clr_Transparent); - FX_ClearTarget(CSvoRenderer::GetInstance()->GetRsmNormlMap(*lof), Clr_Transparent); - clearFlags |= CLEAR_RTARGET; - } -#endif - FX_ClearTarget(&depthTarget, CLEAR_ZBUFFER | CLEAR_STENCIL, Clr_FarPlane_R.r, 0); - clearFlags |= CLEAR_ZBUFFER | CLEAR_STENCIL; -#if defined(CRY_USE_METAL) - //Clear calls are cached until a draw call is made. If there is nothing in the caster list no draw calls will be made. - //Hence make a draw call to clear the render targets. - if (lof->m_castersList.IsEmpty() && lof->m_jobExecutedCastersList.IsEmpty()) - { - FX_Commit(); - FX_ClearTargetRegion(); - } -#endif - } - - m_pNewTarget[0]->m_ClearFlags = 0; - - FX_SetColorDontCareActions(0, !(clearFlags & CLEAR_RTARGET), false); - FX_SetColorDontCareActions(1, !(clearFlags & CLEAR_RTARGET), false); - FX_SetColorDontCareActions(2, !(clearFlags & CLEAR_RTARGET), false); -#if !defined(OPENGL_ES) // some drivers don't play well with the following - FX_SetStencilDontCareActions(0, !(clearFlags & CLEAR_STENCIL), true); - FX_SetStencilDontCareActions(1, !(clearFlags & CLEAR_STENCIL), true); - FX_SetStencilDontCareActions(2, !(clearFlags & CLEAR_STENCIL), true); -#endif - } - else - { - // CONFETTI BEGIN: David Srour - // Metal Load/Store Actions - FX_SetColorDontCareActions(0, true, true); - FX_SetStencilDontCareActions(0, true, true); - FX_SetColorDontCareActions(1, true, true); - FX_SetStencilDontCareActions(1, true, true); - FX_SetColorDontCareActions(2, true, true); - FX_SetStencilDontCareActions(2, true, true); - // CONFETTI END - } - - //set proper side-viewport - if (lof->bUnwrapedOmniDirectional || lof->bUseShadowsPool) - { - int arrViewport[4]; - lof->GetSideViewport(sideIndex, arrViewport); - RT_SetViewport(arrViewport[0], arrViewport[1], arrViewport[2], arrViewport[3]); - } - - FX_Commit(true); - -#if defined(FEATURE_SVO_GI) - if (!CSvoRenderer::GetRsmColorMap(*lof)) -#endif - { - FX_SetState(GS_COLMASK_NONE, -1); - m_RP.m_PersFlags2 |= RBPF2_DISABLECOLORWRITES; - m_RP.m_StateOr |= GS_COLMASK_NONE; - } - - if (lof->fDepthSlopeBias > 0.0f && (lof->m_Flags & DLF_DIRECTIONAL)) - { - float fShadowsBias = CV_r_ShadowsBias; - float fShadowsSlopeScaleBias = lof->fDepthSlopeBias; - - //adjust nearest slope fer nearest custom frustum - if (lof->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - fShadowsSlopeScaleBias *= 7.0f; - } - - SStateRaster CurRS = m_StatesRS[m_nCurStateRS]; - CurRS.Desc.DepthBias = 0; - CurRS.Desc.DepthBiasClamp = fShadowsBias * 20; - CurRS.Desc.SlopeScaledDepthBias = fShadowsSlopeScaleBias; - SetRasterState(&CurRS); - } - - - if (!(lof->m_Flags & DLF_LIGHT_BEAM)) - { - D3DSetCull(eCULL_None); - } - else - { - D3DSetCull(eCULL_Back); - m_RP.m_PersFlags2 |= RBPF2_LIGHTSHAFTS; - } - - if (nLightFrustumID < 0) - { - FX_ProcessRenderList(EFSLIST_GENERAL, 0, FX_FlushShader_ShadowGen, false); - FX_ProcessRenderList(EFSLIST_GENERAL, 1, FX_FlushShader_ShadowGen, false); - } - else - if (!lof->m_castersList.IsEmpty() || !lof->m_jobExecutedCastersList.IsEmpty()) - { - FX_ProcessRenderList(nFirstShadowGenRI, - nLastShadowGenRI, - EFSLIST_SHADOW_GEN, 0, FX_FlushShader_ShadowGen, false); - } - - FX_PopRenderTarget(0); - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetRsmColorMap(*lof) && CSvoRenderer::GetRsmNormlMap(*lof)) - { - FX_PopRenderTarget(1); - } -#endif - - m_RP.m_PersFlags2 &= ~RBPF2_DISABLECOLORWRITES; - m_RP.m_StateOr &= ~GS_COLMASK_NONE; - if (CV_r_ShadowsBias > 0.0f) - { - SStateRaster CurRS = m_StatesRS[m_nCurStateRS]; - CurRS.Desc.DepthBias = 0; - CurRS.Desc.DepthBiasClamp = 0; - CurRS.Desc.SlopeScaledDepthBias = 0; - SetRasterState(&CurRS); - } - } - - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_SHADOWGEN; - SetCamera(saveCam); - if (lof->m_eReqTT == eTT_Cube) - { - lof->mLightViewMatrix.SetIdentity(); - lof->mLightViewMatrix.SetTranslation(vPos); - lof->mLightViewMatrix.Transpose(); - } - - if (!(lof->m_Flags & DLF_DIRECTIONAL)) - { - m_RP.m_PersFlags2 &= ~RBPF2_DRAWTOCUBE; - } - - m_RP.m_TI[nThreadList].m_PersFlags &= ~RBPF_MIRRORCULL; - m_RP.m_PersFlags2 &= ~RBPF2_LIGHTSHAFTS; - - CV_r_nodrawnear = old_CV_r_nodrawnear; - CV_r_scissor = nOldScissor; - - m_RP.m_TI[nThreadList].m_PersFlags = nPersFlags; - m_RP.m_PersFlags2 = nPersFlags2; - m_RP.m_StateAnd = nStateAnd; - - EF_Scissor(false, 0, 0, 0, 0); - } - else if (bTextureFromDynPool) - { - iLog->Log("Error: cannot create depth texture for frustum '%d' (skipping)", lof->nShadowMapLod); - } - - m_RP.m_TI[nThreadList].m_matView = origMatView; - m_RP.m_TI[nThreadList].m_matProj = origMatProj; - m_CameraMatrix = camMatr; - EF_SetCameraInfo(); - RT_SetViewport(vX, vY, vWidth, vHeight); - - return true; -} - -void CD3D9Renderer::ConfigShadowTexgen(int Num, ShadowMapFrustum* pFr, int nFrustNum, [[maybe_unused]] bool bScreenToLocalBasis, bool bUseComparisonSampling) -{ - Matrix44A shadowMat, mTexScaleBiasMat, mLightView, mLightProj, mLightViewProj; - bool bGSM = false; - - //check for successful PrepareDepthMap - if (!pFr->pDepthTex && !pFr->bUseShadowsPool) - { - return; - } - - float fOffsetX = 0.5f; - float fOffsetY = 0.5f; - const Matrix44A mClipToTexSpace = Matrix44(0.5f, 0.0f, 0.0f, 0.0f, - 0.0f, -0.5f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - fOffsetX, fOffsetY, 0.0f, 1.0f); - - mTexScaleBiasMat = mClipToTexSpace; - - if ((pFr->bOmniDirectionalShadow || pFr->bUseShadowsPool) && nFrustNum > -1) - { - if (!pFr->bOmniDirectionalShadow) - { - mLightView = pFr->mLightViewMatrix; - mLightProj.SetIdentity(); - } - else - { - CShadowUtils::GetCubemapFrustum(FTYP_SHADOWOMNIPROJECTION, pFr, nFrustNum, &mLightProj, &mLightView); - } - - float arrOffs[2]; - float arrScale[2]; - pFr->GetTexOffset(nFrustNum, arrOffs, arrScale, m_nShadowPoolWidth, m_nShadowPoolHeight); - - //calculate crop matrix for frustum - //TD: investigate proper half-texel offset with mCropView - Matrix44 mCropView(arrScale[0], 0.0f, 0.0f, 0.0f, - 0.0f, arrScale[1], 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - arrOffs[0], arrOffs[1], 0.0f, 1.0f); - - // multiply the projection matrix with it - mTexScaleBiasMat = mTexScaleBiasMat * mCropView; - - //constants for gsm atlas - m_cEF.m_TempVecs[6].x = arrOffs[0]; - m_cEF.m_TempVecs[6].y = arrOffs[1]; - } - else - { - mLightView = pFr->mLightViewMatrix; - - if (pFr->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance) - { - Matrix44 mCropView(IDENTITY); - mCropView.m00 = (float)pFr->packWidth[0] / pFr->pDepthTex->GetWidth(); - mCropView.m11 = (float)pFr->packHeight[0] / pFr->pDepthTex->GetHeight(); - mCropView.m30 = (float)pFr->packX[0] / pFr->pDepthTex->GetWidth(); - mCropView.m31 = (float)pFr->packY[0] / pFr->pDepthTex->GetHeight(); - - mTexScaleBiasMat = mTexScaleBiasMat * mCropView; - } - - mLightProj.SetIdentity(); - bGSM = true; - } - - mLightViewProj = mLightView * mLightProj; - shadowMat = mLightViewProj * mTexScaleBiasMat; - - //set shadow matrix - gRenDev->m_TempMatrices[Num][0] = shadowMat.GetTransposed(); - m_cEF.m_TempVecs[5] = Vec4(mLightViewProj.m30, mLightViewProj.m31, mLightViewProj.m32, 1); - - ////////////////////////////////////////////////////////////////////////// - // Deferred shadow pass setup - ////////////////////////////////////////////////////////////////////////// - Matrix44 mScreenToShadow; - int vpX, vpY, vpWidth, vpHeight; - GetViewport(&vpX, &vpY, &vpWidth, &vpHeight); - FX_DeferredShadowPassSetup(gRenDev->m_TempMatrices[Num][0], pFr, (float)vpWidth, (float)vpHeight, - mScreenToShadow, pFr->m_eFrustumType == ShadowMapFrustum::e_Nearest); - -#if defined(VOLUMETRIC_FOG_SHADOWS) - //use cur TexGen for homogeneous position reconstruction - if (bScreenToLocalBasis && CRenderer::CV_r_FogShadowsMode == 1) - { - Matrix44A mLocalScale; - mLocalScale.SetIdentity(); - gRenDev->m_TempMatrices[Num][0] = mScreenToShadow.GetTransposed(); - float fScreenScale = (CV_r_FogShadows == 2) ? 4.0f : 2.0f; - mLocalScale.m00 = fScreenScale; - mLocalScale.m11 = fScreenScale; - gRenDev->m_TempMatrices[Num][0] = gRenDev->m_TempMatrices[Num][0] * mLocalScale; - } -#endif - - gRenDev->m_TempMatrices[Num][2].m33 = 0.0f; - if (bGSM && pFr->bBlendFrustum) - { - const float fBlendVal = pFr->fBlendVal; - - m_cEF.m_TempVecs[15][0] = fBlendVal; - m_cEF.m_TempVecs[15][1] = 1.0f / (1.0f - fBlendVal); - m_cEF.m_TempVecs[15][2] = 0.0f; - m_cEF.m_TempVecs[15][3] = 0.0f; - - m_cEF.m_TempVecs[6] = Vec4(1.f, 1.f, 0.f, 0.f); - if (pFr->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance) - { - m_cEF.m_TempVecs[6].x = pFr->pDepthTex->GetWidth() / float(pFr->packWidth[0]); - m_cEF.m_TempVecs[6].y = pFr->pDepthTex->GetHeight() / float(pFr->packHeight[0]); - m_cEF.m_TempVecs[6].z = -pFr->packX[0] / float(pFr->packWidth[0]); - m_cEF.m_TempVecs[6].w = -pFr->packY[0] / float(pFr->packHeight[0]); - } - - const ShadowMapFrustum* pPrevFr = pFr->pPrevFrustum; - if (pPrevFr) - { - Matrix44A mLightViewPrev = pPrevFr->mLightViewMatrix; - Matrix44A shadowMatPrev = mLightViewPrev * mClipToTexSpace; // NOTE: no sub-rect here as blending code assumes full [0-1] UV range; - - FX_DeferredShadowPassSetupBlend(shadowMatPrev.GetTransposed(), Num, (float)vpWidth, (float)vpHeight); - - m_cEF.m_TempVecs[2][2] = 1.f / (pPrevFr->fFarDist); - - float fBlendValPrev = pPrevFr->fBlendVal; - - m_cEF.m_TempVecs[15][2] = fBlendValPrev; - m_cEF.m_TempVecs[15][3] = 1.0f / (1.0f - fBlendValPrev); - } - } - - Matrix33 mRotMatrix(mLightView); - mRotMatrix.OrthonormalizeFast(); - gRenDev->m_TempMatrices[0][1] = Matrix44(mRotMatrix).GetTransposed(); - - if (Num >= 0) - { - if (!pFr->pDepthTex && !pFr->bUseShadowsPool) - { - Warning("Warning: CD3D9Renderer::ConfigShadowTexgen: pFr->depth_tex_id not set"); - } - else - { - int nID = 0; - int nIDBlured = 0; - if (pFr->bUseShadowsPool) - { - nID = CTexture::s_ptexRT_ShadowPool->GetID(); - } - else - if (pFr->pDepthTex != NULL) - { - nID = pFr->pDepthTex->GetID(); - } - - m_RP.m_ShadowCustomTexBind[Num * 2 + 0] = nID; - m_RP.m_ShadowCustomTexBind[Num * 2 + 1] = nIDBlured; - m_RP.m_ShadowCustomComparisonSampling[Num * 2 + 0] = bUseComparisonSampling; - - m_cEF.m_TempVecs[8][0] = pFr->fShadowFadingDist; - - assert(Num < 4); - if (pFr->bHWPCFCompare) - { - if (pFr->m_Flags & DLF_DIRECTIONAL) - { - //linear case + constant offset - m_cEF.m_TempVecs[1][Num] = pFr->fDepthConstBias; - if (pFr->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - m_cEF.m_TempVecs[1][Num] *= 3.0f; - } - } - else - if (pFr->m_Flags & DLF_PROJECT) - { - //non-linear case - m_cEF.m_TempVecs[1][Num] = pFr->fDepthConstBias; - } - else - { - m_cEF.m_TempVecs[1][Num] = pFr->fDepthConstBias; - } - } - else - { - //linear case - m_cEF.m_TempVecs[1][Num] = pFr->fDepthTestBias; - } - - m_cEF.m_TempVecs[2][Num] = 1.f / (pFr->fFarDist); - m_cEF.m_TempVecs[9][Num] = 1.f / pFr->nTexSize; - m_cEF.m_TempVecs[3][Num] = 0.0f; - - float fShadowJitter = m_shadowJittering; - - if (pFr->m_Flags & DLF_DIRECTIONAL) - { - float fFilteredArea = fShadowJitter * (pFr->fWidthS + pFr->fBlurS); - - if (pFr->m_eFrustumType == ShadowMapFrustum::e_Nearest) - { - fFilteredArea *= 0.1f; - } - - m_cEF.m_TempVecs[4].x = fFilteredArea; - m_cEF.m_TempVecs[4].y = fFilteredArea; - } - else - { - fShadowJitter = 2.0; - m_cEF.m_TempVecs[4].x = fShadowJitter; - ; - m_cEF.m_TempVecs[4].y = fShadowJitter; - - if (pFr->bOmniDirectionalShadow) - { - m_cEF.m_TempVecs[4].x *= 1.0f / 3.0f; - m_cEF.m_TempVecs[4].y *= 1.0f / 2.0f; - } - } - } - } -} - -//============================================================================================================= -void CD3D9Renderer::FX_SetupForwardShadows(bool bUseShaderPermutations) -{ - const int FORWARD_SHADOWS_CASCADE0_SINGLE_TAP = 0x10; - const int FORWARD_SHADOWS_CLOUD_SHADOWS = 0x20; - - const int nThreadID = m_RP.m_nProcessThreadID; - const int nSunFrustumID = 0; - - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nSunFrustumID]; - const int nEndIdx = SRendItem::m_EndFrust[nThreadID][nSunFrustumID]; - - if (bUseShaderPermutations) - { - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | - g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ]); - } - - uint32 nCascadeMask = 0; - for (int a = nStartIdx, cascadeCount = 0; a < nEndIdx && cascadeCount < 4; ++a) - { - ShadowMapFrustum* pFr = &m_RP.m_SMFrustums[nThreadID][nSunFrustumID][a]; - nCascadeMask |= 0x1 << a; - - ConfigShadowTexgen(cascadeCount, pFr, -1, true); - - if (bUseShaderPermutations) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0 + cascadeCount]; - } - - ++cascadeCount; - } - - // only do full pcf filtering on nearest shadow cascade - if (nCascadeMask > 0 && m_RP.m_SMFrustums[nThreadID][nSunFrustumID][nStartIdx].nShadowMapLod != 0) - { - nCascadeMask |= FORWARD_SHADOWS_CASCADE0_SINGLE_TAP; - } - - if (m_bCloudShadowsEnabled && m_cloudShadowTexId > 0) - { - nCascadeMask |= FORWARD_SHADOWS_CLOUD_SHADOWS; - - if (bUseShaderPermutations) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ]; - } - } - - // store cascade mask in m_TempVecs[4].z - *alias_cast(&m_cEF.m_TempVecs[4].z) = nCascadeMask; -} - -void CD3D9Renderer::FX_SetupShadowsForTransp() -{ - PROFILE_FRAME(SetupShadowsForTransp); - - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_POINT_LIGHT] | g_HWSR_MaskBit[HWSR_SHADOW_MIXED_MAP_G16R16]); - - - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_PARTICLE_SHADOW]; - - if (m_shadowJittering > 0.0f) - { - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SHADOW_JITTERING]; - } - - // Always use PCF for shadows for transparent - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[ HWSR_HW_PCF_COMPARE ]; - - FX_SetupForwardShadows(true); -} - -void CD3D9Renderer::FX_SetupShadowsForFog() -{ - PROFILE_FRAME(FX_SetupShadowsForFog); - - m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_POINT_LIGHT] | g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE] | g_HWSR_MaskBit[HWSR_SHADOW_JITTERING] | - g_HWSR_MaskBit[HWSR_SHADOW_MIXED_MAP_G16R16]); - - m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE] | g_HWSR_MaskBit[HWSR_PARTICLE_SHADOW]; - - FX_SetupForwardShadows(); -} - - -bool CD3D9Renderer::FX_PrepareDepthMapsForLight(const SRenderLight& rLight, int nLightID, bool bClearPool) -{ - int nThreadID = m_RP.m_nProcessThreadID; - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - - if ((m_RP.m_TI[nThreadID].m_PersFlags & RBPF_NO_SHADOWGEN) != 0) - { - return false; - } - - //render all valid shadow frustums - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nLightID]; - const int nEndIdx = SRendItem::m_EndFrust[nThreadID][nLightID]; - if (nStartIdx == nEndIdx) - { - return false; - } - - AZ_Assert((nEndIdx - nStartIdx) <= MAX_GSM_LODS_NUM, "Number of shadow frustums is more than max GSM LODs supported."); - - bool processedAtLeastOneShadow = false; - - for (int nFrustIdx = nEndIdx - 1; nFrustIdx >= nStartIdx; --nFrustIdx) - { - ShadowMapFrustum* pCurFrustum = &m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nFrustIdx]; - - int nLightFrustumID = nLightID * MAX_SHADOWMAP_LOD + (nFrustIdx - nStartIdx); - if (!pCurFrustum) - { - continue; - } - - if (pCurFrustum->m_eReqTT == eTT_1D || pCurFrustum->m_eReqTF == eTF_Unknown) - { - // looks like unitialized shadow frustum for 1 frame - some mt issue - continue; - } - - const bool bSun = (rLight.m_Flags & DLF_SUN) != 0; - - // Per-object shadows are added to the "custom" shadow list in CRenderer::FinalizeRendItems_FindShadowFrustums. - // Do not render them twice. - if (pCurFrustum->m_eFrustumType != ShadowMapFrustum::e_PerObject) - { -#ifndef _RELEASE - char frustumLabel[64]; - - if (bSun) - { - const int nShadowRecur = pCurFrustum->nShadowGenID[nThreadID][0]; - const int nRendItemCount = nShadowRecur != 0xFFFFFFFF ? (SRendItem::m_ShadowsEndRI[nThreadID][nShadowRecur] - SRendItem::m_ShadowsStartRI[nThreadID][nShadowRecur]) : 0; - - const char* frustumTextSun[] = - { - "GSM FRUSTUM %i", - "GSM DISTANCE FRUSTUM %i", - "GSM CACHED FRUSTUM %i", - "HEIGHT MAP AO FRUSTUM %i", - "NEAREST FRUSTUM", - "UNKNOWN" - }; - - frustumLabel[0] = 0; - - if (!pCurFrustum->IsCached() || nRendItemCount > 0) - { - sprintf_s(frustumLabel, frustumTextSun[pCurFrustum->m_eFrustumType], m_RP.m_SMFrustums[nThreadID][nCurRecLevel][nFrustIdx].nShadowMapLod); - } - } - else - { - sprintf_s(frustumLabel, "FRUSTUM %i", nFrustIdx - nStartIdx); - } - - if (frustumLabel[0]) - { - PROFILE_LABEL_PUSH(frustumLabel); - } -#endif - // merge cached shadow maps and corresponding dynamic shadow maps. - if (bSun && pCurFrustum->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance) - { - assert(0 <= nStartIdx && nStartIdx <= nEndIdx && nEndIdx <= m_RP.m_SMFrustums[nThreadID][nCurRecLevel].size()); - auto pBegin = m_RP.m_SMFrustums[nThreadID][nCurRecLevel].Data() + nStartIdx; - auto pEnd = m_RP.m_SMFrustums[nThreadID][nCurRecLevel].Data() + nEndIdx; - auto pCachedFrustum = std::find_if(pBegin, pEnd, - [=](ShadowMapFrustum& fr) - { - return fr.nShadowMapLod == pCurFrustum->nShadowMapLod && fr.m_eFrustumType == ShadowMapFrustum::e_GsmCached; - }); - - pCurFrustum->pDepthTex = NULL; - if (pCachedFrustum != pEnd) - { - FX_MergeShadowMaps(pCurFrustum, pCachedFrustum); - processedAtLeastOneShadow = true; - } - } - - if (PrepareDepthMap(pCurFrustum, nLightFrustumID, bClearPool)) - { - bClearPool = false; - processedAtLeastOneShadow = true; - } - -#ifndef _RELEASE - if (frustumLabel[0]) - { - PROFILE_LABEL_POP(frustumLabel); - } -#endif - } - } - - return processedAtLeastOneShadow; -} - -void CD3D9Renderer::EF_PrepareCustomShadowMaps() -{ - int nThreadID = m_RP.m_nProcessThreadID; - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - - if ((m_RP.m_TI[nThreadID].m_PersFlags & RBPF_NO_SHADOWGEN) != 0) - { - return; - } - - int NumDynLights = m_RP.m_DLights[nThreadID][nCurRecLevel].Num(); - - TArray& arrDeferLights = CDeferredShading::Instance().GetLights(nThreadID, nCurRecLevel); - - if (NumDynLights <= 0 && arrDeferLights.Num() <= 0) - { - return; - } - - // Find AABB of all nearest objects. Compute once for all lights as this can be slow - AABB aabbCasters(AABB::RESET); - m_RP.m_arrCustomShadowMapFrustumData[nThreadID].CoalesceMemory(); - size_t shadowMapArraySize = m_RP.m_arrCustomShadowMapFrustumData[nThreadID].size(); - for (size_t i = 0; i < shadowMapArraySize; ++i) - { - aabbCasters.Add(m_RP.m_arrCustomShadowMapFrustumData[nThreadID][i].aabb); - } - - // AABBs are added in world space but without camera position applied - aabbCasters.min += GetCamera().GetPosition(); - aabbCasters.max += GetCamera().GetPosition(); - - // add nearest frustum if it has been set up - for (int nLightID = 0; nLightID < NumDynLights; nLightID++) - { - SRenderLight* pLight = &m_RP.m_DLights[nThreadID][nCurRecLevel][nLightID]; - - if (!(pLight->m_Flags & DLF_CASTSHADOW_MAPS)) - { - continue; - } - - //shadows for nearest objects - if (CV_r_DrawNearShadows && pLight->m_Flags & DLF_DIRECTIONAL) - { - int nStartIdx = SRendItem::m_StartFrust[nThreadID][nLightID]; - TArray& arrFrustums = m_RP.m_SMFrustums[nThreadID][nCurRecLevel]; - if (!arrFrustums.empty() && nStartIdx >= 0 && nStartIdx < arrFrustums.size()) - { - ////////////////////////////////////////////////////////////////////////// - //prepare custom frustums for sun - if (!m_RP.m_arrCustomShadowMapFrustumData[nThreadID].empty()) - { - //copy sun frustum - ShadowMapFrustum* pCustomFrustum = arrFrustums.AddIndex(1); - ShadowMapFrustum* pSunFrustum = &arrFrustums[nStartIdx]; - memcpy(pCustomFrustum, pSunFrustum, sizeof(ShadowMapFrustum)); - - const int nFrustumIndex = arrFrustums.Num() - 1; - m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].Add(nFrustumIndex); - - pCustomFrustum->m_eFrustumType = ShadowMapFrustum::e_Nearest; - pCustomFrustum->bUseShadowsPool = false; - pCustomFrustum->bUseAdditiveBlending = true; - pCustomFrustum->fShadowFadingDist = 1.0f; - pCustomFrustum->fDepthConstBias = 0.0001f; - - Matrix44A& mPrj = pCustomFrustum->mLightProjMatrix; - Matrix44A& mView = pCustomFrustum->mLightViewMatrix; - pCustomFrustum->aabbCasters = aabbCasters; - CShadowUtils::GetShadowMatrixForObject(mPrj, mView, pCustomFrustum); - pCustomFrustum->mLightViewMatrix = pCustomFrustum->mLightViewMatrix * pCustomFrustum->mLightProjMatrix; - } - ////////////////////////////////////////////////////////////////////////// - } - } - } - - // prepare depth maps for all custom frustums - for (int32* pID = m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].begin(); pID != m_RP.m_SMCustomFrustumIDs[nThreadID][nCurRecLevel].end(); ++pID) - { - ShadowMapFrustum& curFrustum = m_RP.m_SMFrustums[nThreadID][nCurRecLevel][*pID]; - PrepareDepthMap(&curFrustum, curFrustum.m_eFrustumType == ShadowMapFrustum::e_Nearest ? -1 : *pID, true); - } -} - -void CD3D9Renderer::EF_PrepareAllDepthMaps() -{ - int nThreadID = m_RP.m_nProcessThreadID; - int nCurRecLevel = SRendItem::m_RecurseLevel[nThreadID]; - assert(nCurRecLevel >= 0); - - int NumDynLights = m_RP.m_DLights[nThreadID][nCurRecLevel].Num(); - - TArray& arrDeferLights = CDeferredShading::Instance().GetLights(nThreadID, nCurRecLevel); - - if (NumDynLights <= 0 && arrDeferLights.Num() <= 0) - { - return; - } - - bool haveShadows = false; - for (int nLightID = 0; nLightID < NumDynLights; nLightID++) - { - SRenderLight* pLight = &m_RP.m_DLights[nThreadID][SRendItem::m_RecurseLevel[nThreadID]][nLightID]; - - if (!(pLight->m_Flags & DLF_CASTSHADOW_MAPS)) - { - continue; - } - - haveShadows |= FX_PrepareDepthMapsForLight(*pLight, nLightID); - } - - if (!haveShadows && m_clearShadowMaskTexture) - { - FX_ClearShadowMaskTexture(); - m_clearShadowMaskTexture = false; - } - else - { - m_clearShadowMaskTexture = true; - } - - ////////////////////////////////////////////////////////////////////////// - if IsCVarConstAccess(constexpr) (!CV_r_UseShadowsPool) - { - for (uint32 nDeferLightID = 0; nDeferLightID < arrDeferLights.Num(); nDeferLightID++) - { - SRenderLight* pLight = &arrDeferLights[nDeferLightID]; - if (!(pLight->m_Flags & DLF_CASTSHADOW_MAPS)) - { - continue; - } - - int nDeferLightIdx = nDeferLightID + NumDynLights; - assert((unsigned int) nDeferLightIdx < (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)); - if ((unsigned int) nDeferLightIdx >= (MAX_REND_LIGHTS + MAX_DEFERRED_LIGHTS)) - { - Warning("CD3D9Renderer::EF_PrepareAllDepthMaps: Too many light sources used ..."); - return; - } - - FX_PrepareDepthMapsForLight(*pLight, nDeferLightIdx); - } - } - - // prepare custom depth maps - { - PROFILE_LABEL_SCOPE("CUSTOM MAPS"); - const uint64 nPrevRTFlags = m_RP.m_FlagsShader_RT; - uint32 nPrefRendFlags = m_RP.m_nRendFlags; - m_RP.m_nRendFlags = 0; - - EF_PrepareCustomShadowMaps(); - - m_RP.m_nRendFlags = nPrefRendFlags; - m_RP.m_FlagsShader_RT = nPrevRTFlags; - } -} - -void CD3D9Renderer::FX_MergeShadowMaps(ShadowMapFrustum* pDst, const ShadowMapFrustum* pSrc) -{ - if (!pDst || !pSrc) - { - return; - } - AZ_TRACE_METHOD(); - - CRY_ASSERT(pSrc->m_eFrustumType == ShadowMapFrustum::e_GsmCached); - CRY_ASSERT(pDst->m_eFrustumType == ShadowMapFrustum::e_GsmDynamicDistance); - CRY_ASSERT(pDst->nShadowMapLod == pSrc->nShadowMapLod); - - const int nThreadID = m_RP.m_nProcessThreadID; - const int nShadowRecur = pDst->nShadowGenID[nThreadID][0]; - const int nRendItemCount = nShadowRecur != 0xFFFFFFFF ? (SRendItem::m_ShadowsEndRI[nThreadID][nShadowRecur] - SRendItem::m_ShadowsStartRI[nThreadID][nShadowRecur]) : 0; - - // get crop rectangle for projection - Matrix44r mReproj = Matrix44r(pDst->mLightViewMatrix).GetInverted() * Matrix44r(pSrc->mLightViewMatrix); - Vec4r srcClipPosTL = Vec4r(-1, -1, 0, 1) * mReproj; - srcClipPosTL /= srcClipPosTL.w; - - const float fSnap = 2.0f / pSrc->pDepthTex->GetWidth(); - Vec4 crop = Vec4( - crop.x = fSnap * int(srcClipPosTL.x / fSnap), - crop.y = fSnap * int(srcClipPosTL.y / fSnap), - crop.z = 2.0f * pDst->nTextureWidth / float(pSrc->nTextureWidth), - crop.w = 2.0f * pDst->nTextureHeight / float(pSrc->nTextureHeight) - ); - - Matrix44 cropMatrix(IDENTITY); - cropMatrix.m00 = 2.f / crop.z; - cropMatrix.m11 = 2.f / crop.w; - cropMatrix.m30 = -(1.0f + cropMatrix.m00 * crop.x); - cropMatrix.m31 = -(1.0f + cropMatrix.m11 * crop.y); - - const bool bOutsideFrustum = abs(crop.x) > 1.0f || abs(crop.x + crop.z) > 1.0f || abs(crop.y) > 1.0f || abs(crop.y + crop.w) > 1.0f; - const bool bEmptyCachedFrustum = pSrc->nShadowGenMask == 0; - const bool bRequireCopy = bOutsideFrustum || bEmptyCachedFrustum || nRendItemCount > 0; - - pDst->pDepthTex = NULL; - pDst->bIncrementalUpdate = true; - pDst->mLightViewMatrix = pSrc->mLightViewMatrix * cropMatrix; - - // do we need to merge static shadows into the dynamic shadow map? - if (bRequireCopy) - { - - SDynTexture_Shadow* pDynTex = SDynTexture_Shadow::GetForFrustum(pDst); - pDst->pDepthTex = pDynTex->m_pTexture; - - SDepthTexture depthSurface; - - depthSurface.nWidth = pDst->nTextureWidth; - depthSurface.nHeight = pDst->nTextureHeight; - depthSurface.nFrameAccess = -1; - depthSurface.bBusy = false; - depthSurface.pTex = pDst->pDepthTex; - depthSurface.pSurf = pDst->pDepthTex->GetDeviceDepthStencilSurf(); - depthSurface.pTarget = pDst->pDepthTex->GetDevTexture()->Get2DTexture(); - - if (bEmptyCachedFrustum) - { - gcpRendD3D->FX_ClearTarget(&depthSurface, CLEAR_ZBUFFER | CLEAR_STENCIL, Clr_FarPlane.r, 0); - } - else - { - uint64 nSaveFlagsShader_RT = gRenDev->m_RP.m_FlagsShader_RT; - - int iTempX, iTempY, iWidth, iHeight; - gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight); - - gcpRendD3D->FX_PushRenderTarget(0, (CTexture*)NULL, &depthSurface); - gcpRendD3D->FX_SetActiveRenderTargets(); - gcpRendD3D->RT_SetViewport(0, 0, pDst->pDepthTex->GetWidth(), pDst->pDepthTex->GetHeight()); - - FX_SetStencilDontCareActions(0, true, true); - - static CCryNameTSCRC pTechCopyShadowMap("ReprojectShadowMap"); - SPostEffectsUtils::ShBeginPass(CShaderMan::s_ShaderShadowMaskGen, pTechCopyShadowMap, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - gRenDev->FX_SetState(GS_DEPTHWRITE | GS_DEPTHFUNC_NOTEQUAL); - - Matrix44 mReprojDstToSrc = pDst->mLightViewMatrix.GetInverted() * pSrc->mLightViewMatrix; - - static CCryNameR paramReprojMatDstToSrc("g_mReprojDstToSrc"); - CShaderMan::s_ShaderShadowMaskGen->FXSetPSFloat(paramReprojMatDstToSrc, (Vec4*) mReprojDstToSrc.GetData(), 4); - - Matrix44 mReprojSrcToDst = pSrc->mLightViewMatrix.GetInverted() * pDst->mLightViewMatrix; - static CCryNameR paramReprojMatSrcToDst("g_mReprojSrcToDst"); - CShaderMan::s_ShaderShadowMaskGen->FXSetPSFloat(paramReprojMatSrcToDst, (Vec4*) mReprojSrcToDst.GetData(), 4); - - pSrc->pDepthTex->Apply(0, CTexture::GetTexState(STexState(FILTER_POINT, true))); - - SPostEffectsUtils::DrawFullScreenTri(depthSurface.nWidth, depthSurface.nHeight); - SPostEffectsUtils::ShEndPass(); - - gcpRendD3D->FX_PopRenderTarget(0); - gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight); - - gRenDev->m_RP.m_FlagsShader_RT = nSaveFlagsShader_RT; - } - - pDst->packWidth[0] = pDst->nTextureWidth; - pDst->packHeight[0] = pDst->nTextureHeight; - - pDst->packX[0] = pDst->packY[0] = 0; - } - else - { - pDst->packX[0] = int((crop.x * 0.5f + 0.5f) * pSrc->pDepthTex->GetWidth() + 0.5f); - pDst->packY[0] = int((-(crop.y + crop.w) * 0.5f + 0.5f) * pSrc->pDepthTex->GetHeight() + 0.5f); - pDst->packWidth[0] = pDst->nTextureWidth; - pDst->packHeight[0] = pDst->nTextureHeight; - - pDst->pDepthTex = pSrc->pDepthTex; - pDst->nTexSize = pSrc->nTexSize; - pDst->nTextureWidth = pSrc->nTextureWidth; - pDst->nTextureHeight = pSrc->nTextureHeight; - } - - pDst->fNearDist = pSrc->fNearDist; - pDst->fFarDist = pSrc->fFarDist; - pDst->fDepthConstBias = pSrc->fDepthConstBias; - pDst->fDepthTestBias = pSrc->fDepthTestBias; - pDst->fDepthSlopeBias = pSrc->fDepthSlopeBias; -} - -void CD3D9Renderer::FX_ClearShadowMaskTexture() -{ - const int arraySize = CTexture::s_ptexShadowMask->StreamGetNumSlices(); - SResourceView curSliceRVDesc = SResourceView::RenderTargetView(CTexture::s_ptexShadowMask->GetTextureDstFormat(), 0, 1); - for (int i = 0; i < arraySize; ++i) - { - curSliceRVDesc.m_Desc.nFirstSlice = i; - SResourceView& firstSliceRV = CTexture::s_ptexShadowMask->GetResourceView(curSliceRVDesc); - -#if defined(CRY_USE_METAL) - static ICVar* pVar = iConsole->GetCVar("e_ShadowsClearShowMaskAtLoad"); - if (pVar && pVar->GetIVal()) - { - FX_ClearTarget(static_cast(firstSliceRV.m_pDeviceResourceView), Clr_Transparent, 0, nullptr); - - // On metal we have to submit a draw call in order for a clear to take affect. - // Doing the commit/clear target region will produce the needed draw call for the clear. - FX_PushRenderTarget(0, static_cast(firstSliceRV.m_pDeviceResourceView), nullptr); - - RT_SetViewport(0, 0, CTexture::s_ptexShadowMask->GetWidth(), CTexture::s_ptexShadowMask->GetHeight()); - FX_Commit(); - FX_ClearTargetRegion(); - FX_PopRenderTarget(0); - } -#else - FX_ClearTarget(static_cast(firstSliceRV.m_pDeviceResourceView), Clr_Transparent, 0, nullptr); -#endif - } -} - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.cpp deleted file mode 100644 index 0997a10e59..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#include "D3DStereo.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include "D3DHMDRenderer.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DSTEREO_CPP_SECTION_1 1 -#define D3DSTEREO_CPP_SECTION_2 2 -#endif - -#include - -CD3DStereoRenderer::CD3DStereoRenderer(CD3D9Renderer& renderer, EStereoDevice device) - : m_renderer(renderer) - , m_device(device) - , m_deviceState(STEREO_DEVSTATE_UNSUPPORTED_DEVICE) - , m_mode(STEREO_MODE_NO_STEREO) - , m_output(STEREO_OUTPUT_STANDARD) - , m_driver(DRIVER_UNKNOWN) - , m_pLeftTex(nullptr) - , m_pRightTex(nullptr) - , m_nvStereoHandle(nullptr) - , m_nvStereoStrength(0.0f) - , m_nvStereoActivated(0) - , m_renderStatus(IStereoRenderer::Status::kIdle) - , m_frontBufWidth(0) - , m_frontBufHeight(0) - , m_stereoStrength(0.0f) - , m_zeroParallaxPlaneDist(0.25f) - , m_maxSeparationScene(0.0f) - , m_nearGeoScale(0.0f) - , m_gammaAdjustment(0) - , m_screenSize(0.0f) - , m_resourcesPatched(false) - , m_needClearLeft(true) - , m_needClearRight(true) - , m_hmdRenderer(nullptr) -{ - if (device == STEREO_DEVICE_DEFAULT) - { - SelectDefaultDevice(); - } -} - - -CD3DStereoRenderer::~CD3DStereoRenderer() -{ - Shutdown(); -} - - -void CD3DStereoRenderer::SelectDefaultDevice() -{ - EStereoDevice device = STEREO_DEVICE_NONE; - -#if D3DSTEREO_CPP_TRAIT_SELECTDEFAULTDEVICE_STEREODEVICEDRIVER - device = STEREO_DEVICE_DRIVER; -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSTEREO_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DStereo_cpp) -#elif AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) - device = STEREO_DEVICE_FRAMECOMP; -#endif - - m_device = device; -} - - -void CD3DStereoRenderer::InitDeviceBeforeD3D() -{ - LOADING_TIME_PROFILE_SECTION; - - if (m_device == STEREO_DEVICE_NONE) - { - return; - } - - bool success = true; - m_deviceState = STEREO_DEVSTATE_UNSUPPORTED_DEVICE; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSTEREO_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DStereo_cpp) -#endif - - if (success) - { - m_deviceState = STEREO_DEVSTATE_OK; - } - else - { - iLog->LogError("Failed to create stereo device"); - m_device = STEREO_DEVICE_NONE; - } -} - - -void CD3DStereoRenderer::InitDeviceAfterD3D() -{ - LOADING_TIME_PROFILE_SECTION; - - // Note: Resources will be created in EF_Init, so no need to create them here - AZ::StereoRendererRequestBus::Handler::BusConnect(); -} - - -void CD3DStereoRenderer::CreateResources() -{ - m_SourceSizeParamName = CCryNameR("SourceSize"); - - if (!CTexture::s_ptexStereoL || !CTexture::s_ptexStereoR) - { - CreateIntermediateBuffers(); - } -} - - -void CD3DStereoRenderer::CreateIntermediateBuffers() -{ - SAFE_RELEASE(CTexture::s_ptexStereoL); - SAFE_RELEASE(CTexture::s_ptexStereoR); - - int nWidth = m_renderer.GetWidth(); - int nHeight = m_renderer.GetHeight(); - - uint32 nFlags = FT_DONT_STREAM | FT_USAGE_RENDERTARGET; - - CTexture::s_ptexStereoL = CTexture::CreateRenderTarget("$StereoL", nWidth, nHeight, Clr_Empty, eTT_2D, nFlags, eTF_R8G8B8A8); - CTexture::s_ptexStereoR = CTexture::CreateRenderTarget("$StereoR", nWidth, nHeight, Clr_Empty, eTT_2D, nFlags, eTF_R8G8B8A8); -} - -void CD3DStereoRenderer::Shutdown() -{ - AZ::StereoRendererRequestBus::Handler::BusDisconnect(); - - ReleaseResources(); - - ShutdownHmdRenderer(); -} - - -void CD3DStereoRenderer::ReleaseResources() -{ - if (m_device == STEREO_DEVICE_NONE) - { - return; - } - - SAFE_RELEASE(CTexture::s_ptexStereoL); - SAFE_RELEASE(CTexture::s_ptexStereoR); -} - - -bool CD3DStereoRenderer::EnableStereo() -{ - if (!m_hmdRenderer) - { - return InitializeHmdRenderer(); - } - - return true; -} - - -void CD3DStereoRenderer::DisableStereo() -{ - m_gammaAdjustment = 0; - - ShutdownHmdRenderer(); -} - - -void CD3DStereoRenderer::ChangeOutputFormat() -{ - m_frontBufWidth = 0; - m_frontBufHeight = 0; -} - - -bool CD3DStereoRenderer::InitializeHmdRenderer() -{ - assert(m_hmdRenderer == nullptr); - - if (AZ::VR::HMDDeviceRequestBus::GetTotalNumOfEventHandlers() <= 0) - { - return false; - } - - m_hmdRenderer = new D3DHMDRenderer(); - - if (m_hmdRenderer != nullptr) - { - if (!m_hmdRenderer->Initialize(&m_renderer, this)) - { - SAFE_DELETE(m_hmdRenderer); - return false; - } - } - return (m_hmdRenderer != nullptr); -} - - -void CD3DStereoRenderer::ShutdownHmdRenderer() -{ - if (m_hmdRenderer != NULL) - { - m_hmdRenderer->Shutdown(); - SAFE_DELETE(m_hmdRenderer); - } -} - - -void CD3DStereoRenderer::PrepareStereo(EStereoMode mode, EStereoOutput output) -{ - if (m_mode != mode || m_output != output) - { - m_renderer.ForceFlushRTCommands(); - - if (m_mode != mode) - { - m_mode = mode; - m_output = output; - - if (mode != STEREO_MODE_NO_STEREO) - { - EnableStereo(); - ChangeOutputFormat(); - } - } - else if (m_output != output) - { - m_output = output; - - if (IsStereoEnabled()) - { - ChangeOutputFormat(); - } - } - } - - if (IsStereoEnabled()) - { - // VR FIX ME - // These code was written for 3D TV stereo, not for VR. - // VR EyeDist concept is the half distance between the eyes, it can be different for 3D TV with reprojection - - // Update stereo parameters - m_stereoStrength = CRenderer::CV_r_StereoStrength; - m_maxSeparationScene = CRenderer::CV_r_StereoEyeDist; - m_zeroParallaxPlaneDist = CRenderer::CV_r_StereoScreenDist; - m_nearGeoScale = CRenderer::CV_r_StereoNearGeoScale; - m_gammaAdjustment = CRenderer::CV_r_StereoGammaAdjustment; - - float screenDiagonal = GetScreenDiagonalInInches(); - if (screenDiagonal > 0.0f) // override CVar if we can determine the correct maximum separation - { - float aspect = 9.0f / 16.0f; - float horizontal = screenDiagonal / sqrtf(1.0f + aspect * aspect); - float typicalEyeSeperation = 2.5f; // In inches - m_maxSeparationScene = min(typicalEyeSeperation / horizontal, m_maxSeparationScene); // Get bleeding at edges so limit to CVar - } - - // Apply stereo strength - m_maxSeparationScene *= m_stereoStrength; - - if (m_hmdRenderer != NULL) - { - m_hmdRenderer->PrepareFrame(); - } - } -} - - -void CD3DStereoRenderer::HandleNVControl() -{ -} - - -void CD3DStereoRenderer::SetEyeTextures(CTexture* leftTex, CTexture* rightTex) -{ - m_pLeftTex = leftTex; - m_pRightTex = rightTex; -} - - -void CD3DStereoRenderer::Update() -{ - if (m_device != STEREO_DEVICE_NONE) - { - m_renderer.m_pRT->RC_PrepareStereo(CRenderer::CV_r_StereoMode, CRenderer::CV_r_StereoOutput); - } - else - { - static int prevMode = 0; - if (CRenderer::CV_r_StereoMode != prevMode) - { - LogWarning("No stereo device enabled, ignoring stereo mode"); - prevMode = CRenderer::CV_r_StereoMode; - } - } -} - - -CCamera CD3DStereoRenderer::PrepareCamera(EStereoEye nEye, const CCamera& currentCamera, [[maybe_unused]] const SRenderingPassInfo& passInfo) -{ - CCamera cam = currentCamera; - - if (IsRenderingToHMD()) - { - AZ::VR::PerEyeCameraInfo cameraInfo; - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, GetPerEyeCameraInfo, nEye, cam.GetNearPlane(), cam.GetFarPlane(), cameraInfo); - - const float asymmetricHorizontalTranslation = cameraInfo.frustumPlane.horizontalDistance * cam.GetNearPlane(); - const float asymmetricVerticalTranslation = cameraInfo.frustumPlane.verticalDistance * cam.GetNearPlane(); - - Matrix34 stereoMat = Matrix34::CreateTranslationMat(AZVec3ToLYVec3(cameraInfo.eyeOffset)); - cam.SetMatrix(cam.GetMatrix() * stereoMat); - cam.SetFrustum(1, 1, cameraInfo.fov, cam.GetNearPlane(), cam.GetFarPlane(), 1.0f / cameraInfo.aspectRatio); - cam.SetAsymmetry(asymmetricHorizontalTranslation, asymmetricHorizontalTranslation, asymmetricVerticalTranslation, asymmetricVerticalTranslation); - } - else - { - float fNear = cam.GetNearPlane(); - float screenDist = CRenderer::CV_r_StereoScreenDist; - float z = 99999.0f; // Point which is far away - - // standard 3D TV stereo projection parameters - float wT = tanf(cam.GetFov() * 0.5f) * fNear; - float wR = wT * cam.GetProjRatio(), wL = -wR; - float p00 = 2 * fNear / (wR - wL); - float p02 = (wL + wR) / (wL - wR); - - // Compute required camera shift, so that a distant point gets the desired maximum separation - const float maxSeparation = CRenderer::CV_r_StereoEyeDist; - const float camOffset = (maxSeparation - p02) / (p00 / z - p00 / screenDist); - float frustumShift = camOffset * (fNear / screenDist); - //frustumShift *= (nEye == STEREO_EYE_LEFT ? 1 : -1); // Support postive and negative parallax for non-VR stereo - - Matrix34 stereoMat = Matrix34::CreateTranslationMat(Vec3(nEye == STEREO_EYE_LEFT ? -camOffset : camOffset, 0, 0)); - cam.SetMatrix(cam.GetMatrix() * stereoMat); - cam.SetAsymmetry(frustumShift, frustumShift, 0, 0); - } - - return cam; -} - - -void CD3DStereoRenderer::ProcessScene(int sceneFlags, const SRenderingPassInfo& passInfo) -{ - int nThreadID = passInfo.ThreadID(); - - //for recursive rendering (e.g. rendering to ocean reflection texture), stereo is not needed - //We also don't need stereo rendering if we're not rendering on the main viewport (don't check if main viewport when in the launcher) - if (CRenderer::CV_r_StereoMode == STEREO_MODE_DUAL_RENDERING && SRendItem::m_RecurseLevel[nThreadID] < 1 - && (!gEnv->IsEditor() || gcpRendD3D->m_CurrContext->m_bMainViewport)) - { - CCamera cam = m_renderer.m_RP.m_TI[nThreadID].m_cam; - - // Left eye - { - m_renderStatus = IStereoRenderer::Status::kRenderingFirstEye; - m_renderer.m_pRT->RC_SetStereoEye(STEREO_EYE_LEFT); - m_renderer.PushProfileMarker("LEFT_EYE"); - - CCamera camL = PrepareCamera(STEREO_EYE_LEFT, cam, passInfo); - m_renderer.SetCamera(camL); - - CD3DStereoRenderer::RenderScene(sceneFlags, passInfo); - - CopyToStereoFromMainThread(STEREO_EYE_LEFT); - m_renderer.PopProfileMarker("LEFT_EYE"); - } - - // Right eye - { - m_renderStatus = IStereoRenderer::Status::kRenderingSecondEye; - m_renderer.m_pRT->RC_SetStereoEye(STEREO_EYE_RIGHT); - m_renderer.PushProfileMarker("RIGHT_EYE"); - - CCamera camR = PrepareCamera(STEREO_EYE_RIGHT, cam, passInfo); - m_renderer.SetCamera(camR); - - CD3DStereoRenderer::RenderScene(sceneFlags | SHDF_NO_SHADOWGEN, passInfo); - CopyToStereoFromMainThread(STEREO_EYE_RIGHT); - - m_renderer.PopProfileMarker("RIGHT_EYE"); - } - - m_renderStatus = IStereoRenderer::Status::kIdle; - } - else - { - if (CRenderer::CV_r_StereoMode != STEREO_MODE_DUAL_RENDERING) - { - m_renderer.m_pRT->RC_SetStereoEye(0); - } - - CD3DStereoRenderer::RenderScene(sceneFlags, passInfo); - } -} - - -void CD3DStereoRenderer::CopyToStereo(int channel) -{ - assert(IsRenderThread()); - - PROFILE_LABEL_SCOPE("COPY_TO_STEREO"); - - CTexture* pTex; - - if (channel == STEREO_EYE_LEFT) - { - pTex = GetLeftEye(); - m_needClearLeft = false; - } - else - { - pTex = GetRightEye(); - m_needClearRight = false; - } - - if (pTex == NULL) - { - return; - } - - GetUtils().CopyScreenToTexture(pTex); - - CTexture* finalCompositeSource = GetUtils().GetFinalCompositeTarget(); - if (gcpRendD3D->FX_GetCurrentRenderTarget(0) == finalCompositeSource && finalCompositeSource != nullptr) - { - gcpRendD3D->FX_PopRenderTarget(0); - } -} - - -void CD3DStereoRenderer::DisplayStereo() -{ - assert(IsRenderThread()); - - if (!IsStereoEnabled() || m_renderer.m_bDeviceLost) // When unloading level, m_bDeviceLost is set to 2 - { - return; - } - - if (m_hmdRenderer != NULL) - { - m_hmdRenderer->RenderSocialScreen(); - m_hmdRenderer->SubmitFrame(); - return; - } - - ResolveStereoBuffers(); - m_needClearLeft = true; - m_needClearRight = true; - - m_renderer.m_cEF.mfRefreshSystemShader("Stereo", CShaderMan::s_ShaderStereo); - - PROFILE_LABEL_SCOPE("DISPLAY_STEREO"); - - // TODO: Fix this properly - if (!gEnv->IsEditor()) - { - m_renderer.RT_SetViewport(0, 0, m_renderer.GetBackbufferWidth(), m_renderer.GetBackbufferHeight()); - } - - if (m_renderer.m_pSecondBackBuffer != 0) - { - m_renderer.FX_PushRenderTarget(1, m_renderer.m_pSecondBackBuffer, NULL); - m_renderer.RT_SetViewport(0, 0, m_renderer.m_NewViewport.nWidth, m_renderer.m_NewViewport.nHeight); - } - - CShader* pSH = m_renderer.m_cEF.s_ShaderStereo; - SelectShaderTechnique(); - - uint32 nPasses = 0; - pSH->FXBegin(&nPasses, FEF_DONTSETSTATES); - pSH->FXBeginPass(0); - - m_renderer.FX_SetState(GS_NODEPTHTEST); - - int width = m_renderer.GetWidth(); - int height = m_renderer.GetHeight(); - - Vec4 pParams = Vec4((float) width, (float) height, 0, 0); - CShaderMan::s_shPostEffects->FXSetPSFloat(m_SourceSizeParamName, &pParams, 1); - - GetUtils().SetTexture(!CRenderer::CV_r_StereoFlipEyes ? GetLeftEye() : GetRightEye(), 0, FILTER_LINEAR); - GetUtils().SetTexture(!CRenderer::CV_r_StereoFlipEyes ? GetRightEye() : GetLeftEye(), 1, FILTER_LINEAR); - - GetUtils().DrawFullScreenTri(width, height); - - pSH->FXEndPass(); - pSH->FXEnd(); - - if (m_renderer.m_pSecondBackBuffer != 0) - { - m_renderer.FX_PopRenderTarget(1); - } -} - - -void CD3DStereoRenderer::BeginRenderingMRT(bool disableClear) -{ - if (!IsStereoEnabled()) - { - return; - } - - if (disableClear) - { - m_needClearLeft = false; - m_needClearRight = false; - } - - PushRenderTargets(); -} - - -void CD3DStereoRenderer::EndRenderingMRT(bool bResolve) -{ - if (!IsStereoEnabled()) - { - return; - } - - PopRenderTargets(bResolve); -} - - -void CD3DStereoRenderer::TakeScreenshot(const char path[]) -{ - stack_string pathL(path); - stack_string pathR(path); - - pathL.insert(pathL.find('.'), "_L"); - pathR.insert(pathR.find('.'), "_R"); - - ((CD3D9Renderer*) gRenDev)->CaptureFrameBufferToFile(pathL.c_str(), GetLeftEye()); - ((CD3D9Renderer*) gRenDev)->CaptureFrameBufferToFile(pathR.c_str(), GetRightEye()); -} - - -void CD3DStereoRenderer::ResolveStereoBuffers() -{ -} - -IStereoRenderer::Status ConvertFromEyeToStatus(const EStereoEye eye) -{ - if (eye == STEREO_EYE_LEFT) - { - return IStereoRenderer::Status::kRenderingFirstEye; - } - else if (eye == STEREO_EYE_RIGHT) - { - return IStereoRenderer::Status::kRenderingSecondEye; - } - - return IStereoRenderer::Status::kIdle; -} - -void CD3DStereoRenderer::BeginRenderingTo(EStereoEye eye) -{ - m_renderStatus = ConvertFromEyeToStatus(eye); - - if (eye == STEREO_EYE_LEFT) - { - gRenDev->SetProfileMarker("LEFT_EYE", CRenderer::ESPM_PUSH); - if (m_needClearLeft) - { - m_renderer.FX_ClearTarget(GetLeftEye(), Clr_Transparent); - m_needClearLeft = false; - } - m_renderer.FX_PushRenderTarget(0, GetLeftEye(), &m_renderer.m_DepthBufferOrig); - } - else - { - gRenDev->SetProfileMarker("RIGHT_EYE", CRenderer::ESPM_PUSH); - if (m_needClearRight) - { - m_renderer.FX_ClearTarget(GetRightEye(), Clr_Transparent); - m_needClearRight = false; - } - m_renderer.FX_PushRenderTarget(0, GetRightEye(), &m_renderer.m_DepthBufferOrig); - } - - m_renderer.FX_SetActiveRenderTargets(); - - if (eye == STEREO_EYE_LEFT) - { - GetLeftEye()->SetResolved(true); - } - else - { - GetRightEye()->SetResolved(true); - } -} - - -void CD3DStereoRenderer::EndRenderingTo(EStereoEye eye) -{ - if (eye == STEREO_EYE_LEFT) - { - gRenDev->SetProfileMarker("LEFT_EYE", CRenderer::ESPM_POP); - GetLeftEye()->SetResolved(true); - m_renderer.FX_PopRenderTarget(0); - } - else - { - gRenDev->SetProfileMarker("RIGHT_EYE", CRenderer::ESPM_POP); - GetRightEye()->SetResolved(true); - m_renderer.FX_PopRenderTarget(0); - } -} - - -void CD3DStereoRenderer::SelectShaderTechnique() -{ - gRenDev->m_cEF.mfRefreshSystemShader("Stereo", CShaderMan::s_ShaderStereo); - - CShader* pSH = m_renderer.m_cEF.s_ShaderStereo; - - if (m_device == STEREO_DEVICE_FRAMECOMP) - { - switch (GetStereoOutput()) - { - case STEREO_OUTPUT_CHECKERBOARD: - pSH->FXSetTechnique("Checkerboard"); - break; - case STEREO_OUTPUT_SIDE_BY_SIDE: - pSH->FXSetTechnique("SideBySide"); - break; - case STEREO_OUTPUT_LINE_BY_LINE: - pSH->FXSetTechnique("LineByLine"); - break; - #ifndef _RELEASE - case STEREO_OUTPUT_ANAGLYPH: - pSH->FXSetTechnique("Anaglyph"); - break; - #endif - default: - pSH->FXSetTechnique("Emulation"); - } - } - else if (IsDriver(DRIVER_NV)) - { - pSH->FXSetTechnique("NV3DVision"); - } - else if (m_device == STEREO_DEVICE_DUALHEAD) - { - switch (GetStereoOutput()) - { - case STEREO_OUTPUT_STANDARD: - pSH->FXSetTechnique("DualHead"); - break; - case STEREO_OUTPUT_IZ3D: - pSH->FXSetTechnique("IZ3D"); - break; - default: - pSH->FXSetTechnique("Emulation"); - } - } - else - { - pSH->FXSetTechnique("Emulation"); - } -} - - -void CD3DStereoRenderer::RenderScene(int sceneFlags, const SRenderingPassInfo& passInfo) -{ - m_renderer.EF_Scene3D(m_renderer.m_MainRTViewport, sceneFlags, passInfo); -} - - -bool CD3DStereoRenderer::IsRenderThread() const -{ - return m_renderer.m_pRT->IsRenderThread(); -} - - -void CD3DStereoRenderer::CopyToStereoFromMainThread(int channel) -{ - m_renderer.m_pRT->RC_CopyToStereoTex(channel); -} - - -void CD3DStereoRenderer::PushRenderTargets() -{ - if (m_needClearLeft) - { - m_needClearLeft = false; - m_renderer.FX_ClearTarget(GetLeftEye(), Clr_Transparent); - } - - if (m_needClearRight) - { - m_needClearRight = false; - m_renderer.FX_ClearTarget(GetRightEye(), Clr_Transparent); - } - - m_renderer.FX_PushRenderTarget(0, GetLeftEye(), &m_renderer.m_DepthBufferOrig); - m_renderer.FX_PushRenderTarget(1, GetRightEye(), NULL); - - m_renderer.RT_SetViewport(0, 0, GetLeftEye()->GetWidth(), GetLeftEye()->GetHeight()); - - m_renderer.FX_SetActiveRenderTargets(); -} - - -void CD3DStereoRenderer::PopRenderTargets([[maybe_unused]] bool bResolve) -{ - m_renderer.FX_PopRenderTarget(1); - m_renderer.FX_PopRenderTarget(0); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// IStereoRenderer Interface -//////////////////////////////////////////////////////////////////////////////////////////////////// - -EStereoDevice CD3DStereoRenderer::GetDevice() -{ - return m_device; -} - - -EStereoDeviceState CD3DStereoRenderer::GetDeviceState() -{ - return m_deviceState; -} - - -void CD3DStereoRenderer::GetInfo(EStereoDevice* device, EStereoMode* mode, EStereoOutput* output, EStereoDeviceState* state) const -{ - if (device) - { - *device = m_device; - } - if (mode) - { - *mode = m_mode; - } - if (output) - { - *output = m_output; - } - if (state) - { - *state = m_deviceState; - } -} - - -bool CD3DStereoRenderer::GetStereoEnabled() -{ - return IsStereoEnabled(); -} - - -float CD3DStereoRenderer::GetStereoStrength() -{ - return m_stereoStrength; -} - - -float CD3DStereoRenderer::GetMaxSeparationScene(bool half) -{ - return m_maxSeparationScene * (half ? 0.5f : 1.0f); -} - - -float CD3DStereoRenderer::GetZeroParallaxPlaneDist() -{ - return m_zeroParallaxPlaneDist; -} - - -void CD3DStereoRenderer::GetNVControlValues(bool& stereoActivated, float& stereoStrength) -{ - stereoActivated = m_nvStereoActivated != 0; - stereoStrength = m_nvStereoStrength; -} - - -void CD3DStereoRenderer::ReleaseBuffers() -{ -} - -void CD3DStereoRenderer::OnResolutionChanged() -{ - // StereoL and StereoR buffers are used as temporary buffers in other passes and always required - CreateIntermediateBuffers(); - - if (m_device == STEREO_DEVICE_NONE) - { - return; - } - - if (m_hmdRenderer != NULL) - { - m_hmdRenderer->OnResolutionChanged(); - } -} - - -void CD3DStereoRenderer::CalculateBackbufferResolution(int eyeWidth, int eyeHeight, int& backbufferWidth, int& backbufferHeight) -{ - if (m_hmdRenderer != NULL) - { - m_hmdRenderer->CalculateBackbufferResolution(eyeWidth, eyeHeight, backbufferWidth, backbufferHeight); - } - else - { - switch (m_output) - { - case STEREO_OUTPUT_SIDE_BY_SIDE: - backbufferWidth = eyeWidth * 2; - backbufferHeight = eyeHeight; - break; - case STEREO_OUTPUT_ABOVE_AND_BELOW: - backbufferWidth = eyeWidth; - backbufferHeight = eyeHeight * 2; - break; - default: - backbufferWidth = eyeWidth; - backbufferHeight = eyeHeight; - break; - } - } -} - - -void CD3DStereoRenderer::OnHmdDeviceChanged() -{ - if (m_hmdRenderer) - { - ShutdownHmdRenderer(); - InitializeHmdRenderer(); - } -} - -bool CD3DStereoRenderer::IsRenderingToHMD() -{ - bool valid = false; - if (m_hmdRenderer) - { - // If the renderer is valid, make sure that we're actually supposed to be rendering to the HMD. - - EStereoDevice device = STEREO_DEVICE_NONE; - EStereoMode mode = STEREO_MODE_NO_STEREO; - EStereoOutput output = STEREO_OUTPUT_STANDARD; - - GetInfo(&device, &mode, &output, nullptr); - - const bool hmdSelected = (output == STEREO_OUTPUT_HMD); - if (hmdSelected) - { - // Make sure the mode and device are set to use the HMD. - valid = (mode == STEREO_MODE_DUAL_RENDERING); - } - } - - return valid; -} - - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.h deleted file mode 100644 index 60af061806..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DStereo.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef STEREORENDERER_H -#define STEREORENDERER_H - -#pragma once - -#include "IStereoRenderer.h" - -class CD3D9Renderer; -class D3DHMDRenderer; - -class CD3DStereoRenderer - : public IStereoRenderer -{ -public: - CD3DStereoRenderer(CD3D9Renderer& renderer, EStereoDevice device); - virtual ~CD3DStereoRenderer(); - - void InitDeviceBeforeD3D(); - void InitDeviceAfterD3D(); - void Shutdown(); - float GetScreenDiagonalInInches() const { return m_screenSize; } - void SetScreenDiagonalInInches(float size) { m_screenSize = size; } - - void CreateResources(); - void ReleaseResources(); - - bool IsStereoEnabled() const { return m_device != STEREO_DEVICE_NONE && m_mode != STEREO_MODE_NO_STEREO; } - - void PrepareStereo(EStereoMode mode, EStereoOutput output); - - EStereoDevice GetStereoDevice() const { return m_device; } - EStereoMode GetStereoMode() const { return m_mode; } - EStereoOutput GetStereoOutput() const { return m_output; } - - CTexture* GetLeftEye() { return m_pLeftTex == NULL ? CTexture::s_ptexStereoL : m_pLeftTex; } - CTexture* GetRightEye() { return m_pRightTex == NULL ? CTexture::s_ptexStereoR : m_pRightTex; } - - void SetEyeTextures(CTexture* leftTex, CTexture* rightTex); - - void Update(); - void ProcessScene(int sceneFlags, const SRenderingPassInfo& passInfo); - void ReleaseBuffers(); - void OnResolutionChanged() override; - void CalculateBackbufferResolution(int eyeWidth, int eyeHeight, int& backbufferWidth, int& backbufferHeight); - - void CopyToStereo(int channel); - void DisplayStereo(); - - void BeginRenderingMRT(bool disableClear); - void EndRenderingMRT(bool bResolve = true); - - void ResolveStereoBuffers(); - - void BeginRenderingTo(EStereoEye eye); - void EndRenderingTo(EStereoEye eye); - - void TakeScreenshot(const char path[]); - - float GetNearGeoShift() { return m_zeroParallaxPlaneDist; } - float GetNearGeoScale() { return m_nearGeoScale; } - float GetGammaAdjustment() { return m_gammaAdjustment; } - -public: - // IStereoRenderer Interface - virtual EStereoDevice GetDevice(); - virtual EStereoDeviceState GetDeviceState(); - virtual void GetInfo(EStereoDevice* device, EStereoMode* mode, EStereoOutput* output, EStereoDeviceState* state) const; - - virtual bool GetStereoEnabled(); - virtual float GetStereoStrength(); - virtual float GetMaxSeparationScene(bool half = true); - virtual float GetZeroParallaxPlaneDist(); - virtual void GetNVControlValues(bool& stereoEnabled, float& stereoStrength); - - virtual void OnHmdDeviceChanged(); - Status GetStatus() const override { return m_renderStatus; } - virtual bool IsRenderingToHMD() override; - -private: - enum DriverType - { - DRIVER_UNKNOWN = 0, - DRIVER_NV = 1, - DRIVER_AMD = 2 - }; - - CD3D9Renderer& m_renderer; - - EStereoDevice m_device; - EStereoDeviceState m_deviceState; - EStereoMode m_mode; - EStereoOutput m_output; - - DriverType m_driver; - - CTexture* m_pLeftTex; - CTexture* m_pRightTex; - - void* m_nvStereoHandle; - float m_nvStereoStrength; - uint8 m_nvStereoActivated; - - EStereoEye m_curEye; - IStereoRenderer::Status m_renderStatus; - CCryNameR m_SourceSizeParamName; - - uint32 m_frontBufWidth, m_frontBufHeight; - - float m_stereoStrength; - float m_zeroParallaxPlaneDist; - float m_maxSeparationScene; - float m_nearGeoScale; - float m_gammaAdjustment; - float m_screenSize; - - bool m_resourcesPatched; - bool m_needClearLeft; - bool m_needClearRight; - - D3DHMDRenderer* m_hmdRenderer; - -private: - void SelectDefaultDevice(); - - void CreateIntermediateBuffers(); - - bool EnableStereo(); - void DisableStereo(); - void ChangeOutputFormat(); - void HandleNVControl(); - bool InitializeHmdRenderer(); - void ShutdownHmdRenderer(); - - void RenderScene(int sceneFlags, const SRenderingPassInfo& passInfo); - - void SelectShaderTechnique(); - - bool IsRenderThread() const; - void CopyToStereoFromMainThread(int channel); - - void PushRenderTargets(); - void PopRenderTargets(bool bResolve); - - CCamera PrepareCamera(EStereoEye nEye, const CCamera& currentCamera, const SRenderingPassInfo& passInfo); - - bool IsDriver(DriverType driver) { return m_device == STEREO_DEVICE_DRIVER && m_driver == driver; } -}; - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DSystem.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DSystem.cpp deleted file mode 100644 index 15058c878e..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DSystem.cpp +++ /dev/null @@ -1,2975 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "UnicodeFunctions.h" -#include "DriverD3D.h" -#include "WindowsUtils.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DSYSTEM_CPP_SECTION_1 1 -#define D3DSYSTEM_CPP_SECTION_2 2 -#define D3DSYSTEM_CPP_SECTION_3 3 -#define D3DSYSTEM_CPP_SECTION_4 4 -#define D3DSYSTEM_CPP_SECTION_5 5 -#define D3DSYSTEM_CPP_SECTION_6 6 -#define D3DSYSTEM_CPP_SECTION_7 7 -#define D3DSYSTEM_CPP_SECTION_8 8 -#define D3DSYSTEM_CPP_SECTION_9 9 -#define D3DSYSTEM_CPP_SECTION_10 10 -#define D3DSYSTEM_CPP_SECTION_11 11 -#define D3DSYSTEM_CPP_SECTION_12 12 -#define D3DSYSTEM_CPP_SECTION_13 13 -#define D3DSYSTEM_CPP_SECTION_14 14 -#define D3DSYSTEM_CPP_SECTION_15 15 -#define D3DSYSTEM_CPP_SECTION_16 16 -#define D3DSYSTEM_CPP_SECTION_17 17 -#define D3DSYSTEM_CPP_SECTION_18 18 -#define D3DSYSTEM_CPP_SECTION_19 19 -#define D3DSYSTEM_CPP_SECTION_20 20 -#define D3DSYSTEM_CPP_SECTION_21 21 -#define D3DSYSTEM_CPP_SECTION_22 22 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - - -#include "D3DStereo.h" -#include "D3DPostProcess.h" -#include "NullD3D11Device.h" - -#if defined(WIN32) - -// CryTek undefs some defines from WinBase.h...so let's redefine them here - #ifdef UNICODE - #define RegisterClass RegisterClassW - #define LoadLibrary LoadLibraryW - #else - #define RegisterClass RegisterClassA - #define LoadLibrary LoadLibraryA - #endif // !UNICODE -#endif // defined(WIN32) - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - -#include "../Common/RenderCapabilities.h" -#include - -#ifdef WIN32 -// Count monitors helper -static BOOL CALLBACK CountConnectedMonitors([[maybe_unused]] HMONITOR hMonitor, [[maybe_unused]] HDC hDC, [[maybe_unused]] LPRECT pRect, LPARAM opaque) -{ - uint* count = reinterpret_cast(opaque); - (*count)++; - return TRUE; -} - -#endif - -void CD3D9Renderer::DisplaySplash() -{ -#ifdef WIN32 - if (IsEditorMode()) - { - return; - } - - HBITMAP hImage = (HBITMAP)LoadImage(GetModuleHandle(0), "splash.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); - - if (hImage != INVALID_HANDLE_VALUE) - { - RECT rect; - HDC hDC = GetDC(m_hWnd); - HDC hDCBitmap = CreateCompatibleDC(hDC); - BITMAP bm; - - GetClientRect(m_hWnd, &rect); - GetObjectA(hImage, sizeof(bm), &bm); - SelectObject(hDCBitmap, hImage); - - - - // BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hDCBitmap, 0, 0, SRCCOPY); - - RECT Rect; - GetWindowRect(m_hWnd, &Rect); - StretchBlt(hDC, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top, hDCBitmap, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); - - DeleteObject(hImage); - DeleteDC(hDCBitmap); - } -#endif -} - -//===================================================================================== - -bool CD3D9Renderer::SetCurrentContext(WIN_HWND hWnd) -{ - uint32 i; - - for (i = 0; i < m_RContexts.Num(); i++) - { - if (m_RContexts[i]->m_hWnd == hWnd) - { - break; - } - } - if (i == m_RContexts.Num()) - { - return false; - } - - if (m_CurrContext == m_RContexts[i]) - { - return true; - } - - m_CurrContext = m_RContexts[i]; - - CHWShader::s_pCurVS = NULL; - CHWShader::s_pCurPS = NULL; - - return true; -} - -bool CD3D9Renderer::CreateContext(WIN_HWND hWnd, [[maybe_unused]] bool bAllowMSAA, int SSX, int SSY) -{ - LOADING_TIME_PROFILE_SECTION; - uint32 i; - - for (i = 0; i < m_RContexts.Num(); i++) - { - if (m_RContexts[i]->m_hWnd == hWnd) - { - break; - } - } - if (i != m_RContexts.Num()) - { - return true; - } - SD3DContext* pContext = new SD3DContext; - pContext->m_hWnd = (HWND)hWnd; - pContext->m_X = 0; - pContext->m_Y = 0; - pContext->m_Width = m_width; - pContext->m_Height = m_height; - pContext->m_pSwapChain = 0; - pContext->m_pBackBuffer = 0; - pContext->m_nViewportWidth = aznumeric_cast(aznumeric_cast(m_width) / (m_CurrContext ? m_CurrContext->m_fPixelScaleX : 1.0f)); - pContext->m_nViewportHeight = aznumeric_cast(aznumeric_cast(m_height) / (m_CurrContext ? m_CurrContext->m_fPixelScaleY : 1.0f)); - pContext->m_fPixelScaleX = aznumeric_cast(std::max(1, SSX)); - pContext->m_fPixelScaleY = aznumeric_cast(std::max(1, SSY)); - pContext->m_bMainViewport = !gEnv->IsEditor(); - m_CurrContext = pContext; - m_RContexts.AddElem(pContext); - - return true; -} - -bool CD3D9Renderer::DeleteContext(WIN_HWND hWnd) -{ - uint32 i, j; - - for (i = 0; i < m_RContexts.Num(); i++) - { - if (m_RContexts[i]->m_hWnd == hWnd) - { - break; - } - } - if (i == m_RContexts.Num()) - { - return false; - } - if (m_CurrContext == m_RContexts[i]) - { - for (j = 0; j < m_RContexts.Num(); j++) - { - if (m_RContexts[j]->m_hWnd != hWnd) - { - m_CurrContext = m_RContexts[j]; - break; - } - } - if (j == m_RContexts.Num()) - { - m_CurrContext = NULL; - } - - if (!m_CurrContext) - { - m_width = 0; - m_height = 0; - } - else if (m_CurrContext->m_Width != m_width || m_CurrContext->m_Height != m_height) - { - m_width = m_CurrContext->m_Width; - m_height = m_CurrContext->m_Height; - } - } - for (unsigned int b = 0; b < m_RContexts[i]->m_pBackBuffers.size(); ++b) - { - SAFE_RELEASE(m_RContexts[i]->m_pBackBuffers[b]); - } - SAFE_RELEASE(m_RContexts[i]->m_pSwapChain); - delete m_RContexts[i]; - m_RContexts.Remove(i, 1); - - return true; -} - -void CD3D9Renderer::MakeMainContextActive() -{ - if (m_RContexts.empty() || m_CurrContext == m_RContexts[0]) - { - return; - } - - m_CurrContext = m_RContexts[0]; - - CHWShader::s_pCurVS = NULL; - CHWShader::s_pCurPS = NULL; -} - -bool CD3D9Renderer::CreateMSAADepthBuffer() -{ - HRESULT hr = S_OK; - if (CV_r_msaa) - { - if (m_RP.m_MSAAData.Type != CV_r_msaa_samples || m_RP.m_MSAAData.Quality != CV_r_msaa_quality) - { - SAFE_RELEASE(m_RP.m_MSAAData.m_pZBuffer); - SAFE_RELEASE(m_RP.m_MSAAData.m_pDepthTex); - } - m_RP.m_MSAAData.Type = CV_r_msaa_samples; - m_RP.m_MSAAData.Quality = CV_r_msaa_quality; - if (m_RP.m_MSAAData.Type > 1 && !m_RP.m_MSAAData.m_pZBuffer) - { - // Create depth stencil texture - D3D11_TEXTURE2D_DESC descDepth; - ZeroStruct(descDepth); - descDepth.Width = m_width; - descDepth.Height = m_height; - descDepth.MipLevels = 1; - descDepth.ArraySize = 1; - descDepth.Format = m_ZFormat; - descDepth.SampleDesc.Count = m_RP.m_MSAAData.Type; - descDepth.SampleDesc.Quality = m_RP.m_MSAAData.Quality; - descDepth.Usage = D3D11_USAGE_DEFAULT; - descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; // bind-able as shader resource view - descDepth.CPUAccessFlags = 0; - descDepth.MiscFlags = 0; - - const float clearDepth = CRenderer::CV_r_ReverseDepth ? 0.f : 1.f; - const uint clearStencil = 1; - const FLOAT clearValues[4] = { clearDepth, FLOAT(clearStencil) }; - - hr = m_DevMan.CreateD3D11Texture2D(&descDepth, clearValues, NULL, &m_RP.m_MSAAData.m_pDepthTex, "MSAADepthBuffer"); - if (FAILED(hr)) - { - return false; - } - - m_DepthBufferOrigMSAA.pTex = nullptr; - m_DepthBufferOrigMSAA.pTarget = m_RP.m_MSAAData.m_pDepthTex; - m_DepthBufferOrigMSAA.pSurf = m_RP.m_MSAAData.m_pZBuffer; - - // Create the depth stencil view - D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; - ZeroStruct(descDSV); - descDSV.Format = CTexture::ConvertToDepthStencilFmt(descDepth.Format); - descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; - hr = GetDevice().CreateDepthStencilView(m_RP.m_MSAAData.m_pDepthTex, &descDSV, &m_RP.m_MSAAData.m_pZBuffer); - if (FAILED(hr)) - { - return false; - } - m_DepthBufferOrigMSAA.pSurf = m_RP.m_MSAAData.m_pZBuffer; - m_RP.m_MSAAData.m_pZBuffer->AddRef(); - } - } - else - { - m_RP.m_MSAAData.Type = 0; - m_RP.m_MSAAData.Quality = 0; - - SAFE_RELEASE(m_RP.m_MSAAData.m_pZBuffer); - SAFE_RELEASE(m_RP.m_MSAAData.m_pDepthTex); - - SAFE_RELEASE(m_DepthBufferOrigMSAA.pSurf); - m_DepthBufferOrigMSAA.pTex = nullptr; - m_DepthBufferOrigMSAA.pSurf = m_pZBuffer; - m_DepthBufferOrigMSAA.pTarget = m_pZTexture; - m_pZBuffer->AddRef(); - } - return (hr == S_OK); -} - -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) -static void UserOverrideDXGIOutputFS(DeviceInfo& devInfo, int outputIndex, int defaultX, int defaultY, int& outputX, int& outputY) -{ - outputX = defaultX; - outputY = defaultY; - - // This is not an ideal solution. Just for development or careful use. - // The FS output override might be incompatible with output originally set up in device info. - // As such selected resolutions might not be directly supported but currently won't fall back properly. -# if (defined(WIN32) || defined(WIN64)) - if (outputIndex > 0) - { - bool success = false; - - IDXGIOutput* pOutput = 0; - if (SUCCEEDED(devInfo.Adapter()->EnumOutputs(outputIndex, &pOutput)) && pOutput) - { - DXGI_OUTPUT_DESC outputDesc; - if (SUCCEEDED(pOutput->GetDesc(&outputDesc))) - { - MONITORINFO monitorInfo; - monitorInfo.cbSize = sizeof(monitorInfo); - if (GetMonitorInfo(outputDesc.Monitor, &monitorInfo)) - { - outputX = monitorInfo.rcMonitor.left; - outputY = monitorInfo.rcMonitor.top; - success = true; - } - } - } - SAFE_RELEASE(pOutput); - - if (!success) - { - CryLogAlways("Failed to resolve DXGI display for override index %d. Falling back to preferred or primary display.", outputIndex); - } - } -# endif -} -#endif - -bool CD3D9Renderer::ChangeResolution(int nNewWidth, int nNewHeight, int nNewColDepth, [[maybe_unused]] int nNewRefreshHZ, bool bFullScreen, bool bForceReset) -{ - if (m_bDeviceLost) - { - return true; - } - -#if !defined(_RELEASE) && (defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX)) - if (m_pRT && !m_pRT->IsRenderThread()) - { - __debugbreak(); - } -#endif - - iLog->Log("Changing resolution..."); - - const int nPrevWidth = m_width; - const int nPrevHeight = m_height; - const int nPrevColorDepth = m_cbpp; - const bool bPrevFullScreen = m_bFullScreen; - if (nNewColDepth < 24) - { - nNewColDepth = 16; - } - else - { - nNewColDepth = 32; - } - bool bNeedReset = bForceReset || nNewColDepth != nPrevColorDepth || bFullScreen != bPrevFullScreen || nNewWidth != nPrevWidth || nNewHeight != nPrevHeight; -#if !defined(SUPPORT_DEVICE_INFO) - bNeedReset |= m_VSync != CV_r_vsync; -#endif - -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - bNeedReset |= m_overrideRefreshRate != CV_r_overrideRefreshRate || m_overrideScanlineOrder != CV_r_overrideScanlineOrder; -#endif - - GetS3DRend().ReleaseBuffers(); - DeleteContext(m_hWnd); - - // Save the new dimensions - m_width = nNewWidth; - m_height = nNewHeight; - m_cbpp = nNewColDepth; - m_bFullScreen = bFullScreen; -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - m_overrideRefreshRate = CV_r_overrideRefreshRate; - m_overrideScanlineOrder = CV_r_overrideScanlineOrder; -#endif - if (!IsEditorMode()) - { - m_VSync = CV_r_vsync; - } - else - { - m_VSync = 0; - } -#if defined(SUPPORT_DEVICE_INFO) - m_devInfo.SyncInterval() = m_VSync ? 1 : 0; -#endif - - if (bFullScreen && nNewColDepth == 16) - { - m_zbpp = 16; - m_sbpp = 0; - } - - RestoreGamma(); - - bool bFullscreenWindow = false; -#if defined(WIN32) || defined(WIN64) - bFullscreenWindow = CV_r_FullscreenWindow && CV_r_FullscreenWindow->GetIVal() != 0; -#endif - - if (IsEditorMode() && !bForceReset) - { - nNewWidth = m_deskwidth; - nNewHeight = m_deskheight; - } - if (bNeedReset) - { -#if defined(SUPPORT_DEVICE_INFO) -#if defined(WIN32) - // disable floating point exceptions due to driver bug when switching to fullscreen - SCOPED_DISABLE_FLOAT_EXCEPTIONS; -#endif - m_devInfo.SwapChainDesc().Windowed = !bFullScreen; - m_devInfo.SwapChainDesc().BufferDesc.Width = m_backbufferWidth; - m_devInfo.SwapChainDesc().BufferDesc.Height = m_backbufferHeight; - - m_devInfo.SnapSettings(); - - int swapChainWidth = m_devInfo.SwapChainDesc().BufferDesc.Width; - int swapChainHeight = m_devInfo.SwapChainDesc().BufferDesc.Height; - if (m_backbufferWidth != swapChainWidth || m_backbufferHeight != swapChainHeight) - { - if (m_nativeWidth == m_backbufferWidth) - { - if (m_width == m_nativeWidth) - { - m_width = swapChainWidth; - if (m_CVWidth) - { - m_CVWidth->Set(swapChainWidth); - } - } - m_nativeWidth = swapChainWidth; - } - m_backbufferWidth = swapChainWidth; - - if (m_nativeHeight == m_backbufferHeight) - { - if (m_height == m_nativeHeight) - { - m_height = swapChainHeight; - if (m_CVHeight) - { - m_CVHeight->Set(swapChainHeight); - } - } - m_nativeHeight = swapChainHeight; - } - m_backbufferHeight = swapChainHeight; - } - - ID3D11DepthStencilView* pDSV = 0; - ID3D11RenderTargetView* pRTVs[8] = {0}; - GetDeviceContext().OMSetRenderTargets(8, pRTVs, pDSV); - m_DepthBufferOrig.Release(); - m_DepthBufferOrigMSAA.Release(); - m_DepthBufferNative.Release(); - - AdjustWindowForChange(); - - -# if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - UserOverrideDisplayProperties(m_devInfo.SwapChainDesc().BufferDesc); -# endif - m_pSwapChain->SetFullscreenState(bFullScreen, 0); - m_pSwapChain->ResizeTarget(&m_devInfo.SwapChainDesc().BufferDesc); - m_devInfo.ResizeDXGIBuffers(); - - OnD3D11PostCreateDevice(m_devInfo.Device()); -#endif - m_FullResRect.right = m_width; - m_FullResRect.bottom = m_height; - -#if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) || defined(CREATE_DEVICE_ON_MAIN_THREAD) - m_pRT->RC_SetViewport(0, 0, m_width, m_height); -#else - RT_SetViewport(0, 0, m_width, m_height); -#endif -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - m_MainViewport.nX = 0; - m_MainViewport.nY = 0; - m_MainViewport.nWidth = m_width; - m_MainViewport.nHeight = m_height; - m_MainRTViewport.nX = 0; - m_MainRTViewport.nY = 0; - m_MainRTViewport.nWidth = m_width; - m_MainRTViewport.nHeight = m_height; - } - - AdjustWindowForChange(); - - GetS3DRend().OnResolutionChanged(); - -#ifdef WIN32 - SetWindowText(m_hWnd, m_WinTitle); - iLog->Log(" Window resolution: %dx%dx%d (%s)", m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, nNewColDepth, bFullScreen ? "Fullscreen" : "Windowed"); - iLog->Log(" Render resolution: %dx%d)", m_width, m_height); -#endif - - CreateMSAADepthBuffer(); - - CreateContext(m_hWnd, CV_r_msaa != 0); - - ICryFont* pCryFont = gEnv->pCryFont; - if (pCryFont) - { - pCryFont->GetFont("default"); - } - - PostDeviceReset(); - - return true; -} - -void CD3D9Renderer::PostDeviceReset() -{ - m_bDeviceLost = 0; - if (m_bFullScreen) - { - SetGamma(CV_r_gamma + m_fDeltaGamma, CV_r_brightness, CV_r_contrast, true); - } - FX_ResetPipe(); - CHWShader::s_pCurVS = NULL; - CHWShader::s_pCurPS = NULL; - - for (int i = 0; i < MAX_TMU; i++) - { - CTexture::s_TexStages[i].m_DevTexture = NULL; - } - m_nFrameReset++; -} - - -//----------------------------------------------------------------------------- -// Name: CD3D9Renderer::AdjustWindowForChange() -// Desc: Prepare the window for a possible change between windowed mode and -// fullscreen mode. This function is virtual and thus can be overridden -// to provide different behavior, such as switching to an entirely -// different window for fullscreen mode (as in the MFC sample apps). -//----------------------------------------------------------------------------- -HRESULT CD3D9Renderer::AdjustWindowForChange() -{ -#if defined(WIN32) - if (IsEditorMode()) - { - return S_OK; - } - -#if defined(OPENGL) - const DXGI_SWAP_CHAIN_DESC& swapChainDesc(m_devInfo.SwapChainDesc()); - - DXGI_MODE_DESC modeDesc; - modeDesc.Width = m_backbufferWidth; - modeDesc.Height = m_backbufferHeight; - modeDesc.RefreshRate = swapChainDesc.BufferDesc.RefreshRate; - modeDesc.Format = swapChainDesc.BufferDesc.Format; - modeDesc.ScanlineOrdering = swapChainDesc.BufferDesc.ScanlineOrdering; - modeDesc.Scaling = swapChainDesc.BufferDesc.Scaling; - - HRESULT result = m_pSwapChain->ResizeTarget(&modeDesc); - if (FAILED(result)) - { - return result; - } -#elif defined(WIN32) - bool bFullscreenWindow = false; - - bFullscreenWindow = CV_r_FullscreenWindow && CV_r_FullscreenWindow->GetIVal() != 0; - - if (!m_bFullScreen && !bFullscreenWindow) - { - // Set windowed-mode style - SetWindowLongW(m_hWnd, GWL_STYLE, m_dwWindowStyle); - } - else - { - // Set fullscreen-mode style - SetWindowLongW(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); - } - - if (m_bFullScreen) - { - int x = m_prefMonX; - int y = m_prefMonY; -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) - UserOverrideDXGIOutputFS(m_devInfo, CV_r_overrideDXGIOutputFS, m_prefMonX, m_prefMonY, x, y); -#endif - const int wdt = m_backbufferWidth; - const int hgt = m_backbufferHeight; - SetWindowPos(m_hWnd, HWND_TOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW); - } - else if (bFullscreenWindow) - { - const int x = m_prefMonX + (m_prefMonWidth - m_backbufferWidth) / 2; - const int y = m_prefMonY + (m_prefMonHeight - m_backbufferHeight) / 2; - const int wdt = m_backbufferWidth; - const int hgt = m_backbufferHeight; - SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW); - } - else - { - RECT wndrect; - SetRect(&wndrect, 0, 0, m_backbufferWidth, m_backbufferHeight); - AdjustWindowRectEx(&wndrect, m_dwWindowStyle, FALSE, WS_EX_APPWINDOW); - - const int wdt = wndrect.right - wndrect.left; - const int hgt = wndrect.bottom - wndrect.top; - - const int x = m_prefMonX + (m_prefMonWidth - wdt) / 2; - const int y = m_prefMonY + (m_prefMonHeight - hgt) / 2; - - SetWindowPos(m_hWnd, HWND_NOTOPMOST, x, y, wdt, hgt, SWP_SHOWWINDOW); - } - #endif - - //set viewport to ensure we have a valid one, even when doing chainloading - // and playing a video before going ingame - m_MainViewport.nX = 0; - m_MainViewport.nY = 0; - m_MainViewport.nWidth = m_width; - m_MainViewport.nHeight = m_height; - m_MainRTViewport.nX = 0; - m_MainRTViewport.nY = 0; - m_MainRTViewport.nWidth = m_width; - m_MainRTViewport.nHeight = m_height; - - m_FullResRect.right = m_width; - m_FullResRect.bottom = m_height; - - m_pRT->RC_SetViewport(0, 0, m_width, m_height); - #endif - - return S_OK; -} - -#if defined(SUPPORT_DEVICE_INFO) -bool compareDXGIMODEDESC(const DXGI_MODE_DESC& lhs, const DXGI_MODE_DESC& rhs) -{ - if (lhs.Width != rhs.Width) - { - return lhs.Width < rhs.Width; - } - return lhs.Height < rhs.Height; -} -#endif - -int CD3D9Renderer::EnumDisplayFormats([[maybe_unused]] SDispFormat* formats) -{ -#if defined(WIN32) || defined(WIN64) || defined(OPENGL) - -#if defined(SUPPORT_DEVICE_INFO) - - unsigned int numModes = 0; - if (m_devInfo.Output()) - { - if (SUCCEEDED(m_devInfo.Output()->GetDisplayModeList(m_devInfo.SwapChainDesc().BufferDesc.Format, 0, &numModes, 0)) && numModes) - { - std::vector dispModes(numModes); - if (SUCCEEDED(m_devInfo.Output()->GetDisplayModeList(m_devInfo.SwapChainDesc().BufferDesc.Format, 0, &numModes, &dispModes[0])) && numModes) - { - std::sort(dispModes.begin(), dispModes.end(), compareDXGIMODEDESC); - - unsigned int numUniqueModes = 0; - unsigned int prevWidth = 0; - unsigned int prevHeight = 0; - for (unsigned int i = 0; i < numModes; ++i) - { - if (prevWidth != dispModes[i].Width || prevHeight != dispModes[i].Height) - { - if (formats) - { - formats[numUniqueModes].m_Width = dispModes[i].Width; - formats[numUniqueModes].m_Height = dispModes[i].Height; - formats[numUniqueModes].m_BPP = CTexture::BytesPerBlock(CTexture::TexFormatFromDeviceFormat(dispModes[i].Format)) * 8; - } - - prevWidth = dispModes[i].Width; - prevHeight = dispModes[i].Height; - ++numUniqueModes; - } - } - - numModes = numUniqueModes; - } - } - } - - return numModes; - -#endif - -#else - return 0; -#endif -} - -bool CD3D9Renderer::ChangeDisplay([[maybe_unused]] unsigned int width, [[maybe_unused]] unsigned int height, [[maybe_unused]] unsigned int cbpp) -{ - return false; -} - - -void CD3D9Renderer::UnSetRes() -{ - m_Features |= RFT_SUPPORTZBIAS; - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) - m_d3dDebug.Release(); -#endif -} - -void CD3D9Renderer::DestroyWindow(void) -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(OPENGL) // Scrubber safe exclusion -#else - SAFE_RELEASE(m_DeviceContext); -#endif - - SAFE_RELEASE(m_Device); - -#if defined(CRY_USE_METAL) - DXGLDestroyMetalWindow(m_hWnd); -#elif defined(WIN32) - if (gEnv && gEnv->pSystem) - { - if (m_registeredWindoWHandler) - { - gEnv->pSystem->UnregisterWindowMessageHandler(this); - } - m_registeredWindoWHandler = false; - } - if (m_hWnd) - { - ::DestroyWindow(m_hWnd); - m_hWnd = NULL; - } - if (m_hWnd2) - { - ::DestroyWindow(m_hWnd2); - m_hWnd2 = NULL; - } - if (m_hIconBig) - { - ::DestroyIcon(m_hIconBig); - m_hIconBig = NULL; - } - if (m_hIconSmall) - { - ::DestroyIcon(m_hIconSmall); - m_hIconSmall = NULL; - } -#elif defined(OPENGL) - DXGLDestroyWindow(m_hWnd); -#endif -} - -struct CD3D9Renderer::gammaramp_t -{ - uint16 red[256]; - uint16 green[256]; - uint16 blue[256]; -}; - -static CD3D9Renderer::gammaramp_t orgGamma; - -static BOOL g_doGamma = false; - - -void CD3D9Renderer::RestoreGamma(void) -{ - if (!(GetFeatures() & RFT_HWGAMMA)) - { - return; - } - - if (CV_r_nohwgamma && m_nLastNoHWGamma) - { - return; - } - - m_nLastNoHWGamma = CV_r_nohwgamma; - m_fLastGamma = 1.0f; - m_fLastBrightness = 0.5f; - m_fLastContrast = 0.5f; - - //iLog->Log("...RestoreGamma"); - -#if defined(WIN32) - if (!g_doGamma) - { - return; - } - - g_doGamma = false; - - m_hWndDesktop = GetDesktopWindow(); - - if (HDC dc = GetDC(m_hWndDesktop)) - { - SetDeviceGammaRamp(dc, &orgGamma); - ReleaseDC(m_hWndDesktop, dc); - } -#endif -} - -void CD3D9Renderer::GetDeviceGamma() -{ -#if defined(WIN32) - if (g_doGamma) - { - return; - } - - m_hWndDesktop = GetDesktopWindow(); - - if (HDC dc = GetDC(m_hWndDesktop)) - { - g_doGamma = true; - - if (!GetDeviceGammaRamp(dc, &orgGamma)) - { - for (uint16 i = 0; i < 256; i++) - { - orgGamma.red [i] = i * 0x101; - orgGamma.green[i] = i * 0x101; - orgGamma.blue [i] = i * 0x101; - } - } - - ReleaseDC(m_hWndDesktop, dc); - } -#endif -} - -void CD3D9Renderer::SetDeviceGamma([[maybe_unused]] gammaramp_t* gamma) -{ - if (!(GetFeatures() & RFT_HWGAMMA)) - { - return; - } - - if IsCVarConstAccess(constexpr) (bool(CV_r_nohwgamma)) - { - return; - } - -#if defined(WIN32) - if (!g_doGamma) - { - return; - } - - m_hWndDesktop = GetDesktopWindow(); // TODO: DesktopWindow - does not represent actual output window thus gamma affects all desktop monitors !!! - - if (HDC dc = GetDC(m_hWndDesktop)) - { - g_doGamma = true; - // INFO!!! - very strange: in the same time - // GetDeviceGammaRamp -> TRUE - // SetDeviceGammaRamp -> FALSE but WORKS!!! - // at least for desktop window DC... be careful - SetDeviceGammaRamp(dc, gamma); - ReleaseDC(m_hWndDesktop, dc); - } -#endif -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void CD3D9Renderer::SetGamma(float fGamma, float fBrightness, float fContrast, bool bForce) -{ - // Early out if HW gamma is disabled (same early out as SetDeviceGamma) - if IsCVarConstAccess(constexpr) (bool(CV_r_nohwgamma)) - { - // Restore default if HW gamma was previously enabled - if (m_nLastNoHWGamma == 0) - { - RestoreGamma(); - } - return; - } - - if (m_pStereoRenderer) // Function can be called on shutdown - { - fGamma += GetS3DRend().GetGammaAdjustment(); - } - - fGamma = CLAMP(fGamma, 0.4f, 1.6f); - - if (!bForce && m_fLastGamma == fGamma && m_fLastBrightness == fBrightness && m_fLastContrast == fContrast && m_nLastNoHWGamma == CV_r_nohwgamma) - { - return; - } - - GetDeviceGamma(); - - gammaramp_t gamma; - - float fInvGamma = 1.f / fGamma; - - float fAdd = (fBrightness - 0.5f) * 0.5f - fContrast * 0.5f + 0.25f; - float fMul = fContrast + 0.5f; - - for (int i = 0; i < 256; i++) - { - float pfInput[3]; - - pfInput[0] = (float)(orgGamma.red [i] >> 8) / 255.f; - pfInput[1] = (float)(orgGamma.green[i] >> 8) / 255.f; - pfInput[2] = (float)(orgGamma.blue [i] >> 8) / 255.f; - - pfInput[0] = pow_tpl(pfInput[0], fInvGamma) * fMul + fAdd; - pfInput[1] = pow_tpl(pfInput[1], fInvGamma) * fMul + fAdd; - pfInput[2] = pow_tpl(pfInput[2], fInvGamma) * fMul + fAdd; - - gamma.red [i] = CLAMP(int_round(pfInput[0] * 65535.f), 0, 65535); - gamma.green[i] = CLAMP(int_round(pfInput[1] * 65535.f), 0, 65535); - gamma.blue [i] = CLAMP(int_round(pfInput[2] * 65535.f), 0, 65535); - } - - SetDeviceGamma(&gamma); - - m_nLastNoHWGamma = CV_r_nohwgamma; - m_fLastGamma = fGamma; - m_fLastBrightness = fBrightness; - m_fLastContrast = fContrast; -} - -bool CD3D9Renderer::SetGammaDelta(const float fGamma) -{ - m_fDeltaGamma = fGamma; - SetGamma(CV_r_gamma + fGamma, CV_r_brightness, CV_r_contrast, false); - return true; -} - -SDepthTexture::~SDepthTexture() -{ -} - -void SDepthTexture::Release(bool bReleaseTex) -{ - SAFE_RELEASE(pSurf); - if (bReleaseTex && pTarget) - { - gcpRendD3D->m_DevMan.ReleaseD3D11Texture2D(static_cast(pTarget)); - pTex = nullptr; - } -} - - -void CD3D9Renderer::ShutDownFast() -{ - // Flush RT command buffer - ForceFlushRTCommands(); - CHWShader::mfFlushPendedShadersWait(-1); - FX_PipelineShutdown(true); - //CBaseResource::ShutDown(); - memset(&CTexture::s_TexStages[0], 0, sizeof(CTexture::s_TexStages)); - for (uint32 i = 0; i < CTexture::s_TexStates.size(); i++) - { - memset(&CTexture::s_TexStates[i], 0, sizeof(STexState)); - } - SAFE_DELETE(m_pRT); - -#if defined(OPENGL) -#if !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - if (CV_r_multithreaded) - { - DXGLReleaseContext(m_devInfo.Device()); - } -#endif //!DXGL_FULL_EMULATION - m_devInfo.Release(); -#endif //defined(OPENGL) -} - -void CD3D9Renderer::RT_ShutDown(uint32 nFlags) -{ - m_volumetricFog.DestroyResources(true); - - SAFE_DELETE(m_pColorGradingControllerD3D); - SAFE_DELETE(m_pPostProcessMgr); - SAFE_DELETE(m_pWaterSimMgr); - SAFE_DELETE(m_pStereoRenderer); - SAFE_DELETE(m_pPipelineProfiler); - - m_PerInstanceConstantBufferPool.Shutdown(); - - for (size_t bt = 0; bt < eBoneType_Count; ++bt) - { - for (size_t i = 0; i < 3; ++i) - { - while (m_CharCBActiveList[bt][i].next != &m_CharCBActiveList[bt][i]) - { - delete m_CharCBActiveList[bt][i].next->item<&SCharInstCB::list>(); - } - } - while (m_CharCBFreeList[bt].next != &m_CharCBFreeList[bt]) - { - delete m_CharCBFreeList[bt].next->item<&SCharInstCB::list>(); - } - } - - CHWShader::mfFlushPendedShadersWait(-1); - if (nFlags == FRR_ALL) - { - memset(&CTexture::s_TexStages[0], 0, sizeof(CTexture::s_TexStages)); - CTexture::s_TexStates.clear(); - FreeResources(FRR_ALL); - } - - FX_PipelineShutdown(); - -#if defined(SUPPORT_DEVICE_INFO) - //m_devInfo.Release(); -# if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - m_pRT->m_kDXGLDeviceContextHandle.Set(NULL, !CV_r_multithreaded); - m_pRT->m_kDXGLContextHandle.Set(NULL); -# endif //if defined(OPENGL) && !DXGL_FULL_EMULATION -#endif - - - SAFE_RELEASE(m_pZBufferReadOnlyDSV); - SAFE_RELEASE(m_pZBufferDepthReadOnlySRV); - SAFE_RELEASE(m_pZBufferStencilReadOnlySRV); - - SAFE_DELETE(m_GraphicsPipeline); - -#if defined(ENABLE_RENDER_AUX_GEOM) - SAFE_DELETE(m_pRenderAuxGeomD3D); -#endif - m_DepthBufferOrig.pSurf = NULL; - m_DepthBufferOrig.pTex = NULL; - m_DepthBufferOrigMSAA.pSurf = NULL; - m_DepthBufferOrigMSAA.pTex = NULL; - m_DepthBufferNative.pSurf = NULL; - m_DepthBufferNative.pTex = NULL; -} - -void CD3D9Renderer::ShutDown(bool bReInit) -{ - m_bInShutdown = true; - - // Force Flush RT command buffer - ForceFlushRTCommands(); - PreShutDown(); - CWaterRipples::ReleasePhysCallbacks(); - if (m_pRT) - { - m_pRT->RC_ShutDown(bReInit ? (FRR_SHADERS | FRR_TEXTURES | FRR_REINITHW) : FRR_ALL); - } - - //CBaseResource::ShutDown(); - ForceFlushRTCommands(); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - ////////////////////////////////////////////////////////////////////////// - // Clear globals. - ////////////////////////////////////////////////////////////////////////// - - STLALLOCATOR_CLEANUP - - SAFE_DELETE(m_pRT); - -#if defined(OPENGL) -#if !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - if (CV_r_multithreaded) - { - DXGLReleaseContext(&GetDevice()); - } -#endif //!DXGL_FULL_EMULATION - m_devInfo.Release(); -#endif //defined(OPENGL) - - if (!bReInit) - { - iLog = NULL; - //iConsole = NULL; - iTimer = NULL; - iSystem = NULL; - } - - EnableGPUTimers2(false); - AllowGPUTimers2(false); - -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - DXGLFinalize(); -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION - - PostShutDown(); -} - -#ifdef WIN32 -LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam) -{ - KBDLLHOOKSTRUCT* pkbhs = (KBDLLHOOKSTRUCT*) lParam; - switch (nCode) - { - case HC_ACTION: - { - if (pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN) - { - return 1; // Disable ALT+ESC - } - } - default: - break; - } - return CallNextHookEx (0, nCode, wParam, lParam); -} -#endif - -HWND CD3D9Renderer::CreateWindowCallback() -{ - gcpRendD3D->SetWindow(gcpRendD3D->GetBackbufferWidth(), gcpRendD3D->GetBackbufferHeight(), gcpRendD3D->m_bFullScreen, gcpRendD3D->m_hWnd); - - return gcpRendD3D->m_hWnd; -} - -bool CD3D9Renderer::SetWindow([[maybe_unused]] int width, [[maybe_unused]] int height, [[maybe_unused]] bool fullscreen, [[maybe_unused]] WIN_HWND hWnd) -{ - LOADING_TIME_PROFILE_SECTION; - -#if D3DSYSTEM_CPP_TRAIT_SETWINDOW_REGISTERWINDOWMESSAGEHANDLER - iSystem->RegisterWindowMessageHandler(this); - m_registeredWindoWHandler = true; -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_22 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(CRY_USE_METAL) - if (gcpRendD3D->m_hWnd == 0) - { - DXGLCreateMetalWindow(m_WinTitle, width, height, fullscreen, &m_hWnd); - } -#elif defined(WIN32) - DWORD style, exstyle; - int x, y, wdt, hgt; - - if (width < 640) - { - width = 640; - } - if (height < 480) - { - height = 480; - } - - m_dwWindowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; - - // Do not allow the user to resize the window - m_dwWindowStyle &= ~WS_MAXIMIZEBOX; - m_dwWindowStyle &= ~WS_THICKFRAME; - - bool bFullscreenWindow = false; -#if defined(WIN32) || defined(WIN64) - bFullscreenWindow = CV_r_FullscreenWindow && CV_r_FullscreenWindow->GetIVal() != 0; -#endif - - if (fullscreen || bFullscreenWindow) - { - exstyle = bFullscreenWindow ? WS_EX_APPWINDOW : WS_EX_TOPMOST; - style = WS_POPUP | WS_VISIBLE; - x = m_prefMonX + (m_prefMonWidth - width) / 2; - y = m_prefMonY + (m_prefMonHeight - height) / 2; - wdt = width; - hgt = height; - } - else - { - exstyle = WS_EX_APPWINDOW; - style = m_dwWindowStyle; - - RECT wndrect; - SetRect(&wndrect, 0, 0, width, height); - AdjustWindowRectEx(&wndrect, style, FALSE, exstyle); - - wdt = wndrect.right - wndrect.left; - hgt = wndrect.bottom - wndrect.top; - - x = m_prefMonX + (m_prefMonWidth - wdt) / 2; - y = m_prefMonY + (m_prefMonHeight - hgt) / 2; - } - - if (IsEditorMode()) - { -#if defined(UNICODE) || defined(_UNICODE) -#error Review this, probably should be wide if Editor also has UNICODE support (or maybe moved into Editor) -#endif - m_dwWindowStyle = WS_OVERLAPPED; - style = m_dwWindowStyle; - exstyle = 0; - x = y = 0; - wdt = 100; - hgt = 100; - - WNDCLASSA wc; - memset(&wc, 0, sizeof(WNDCLASSA)); - wc.style = CS_OWNDC; - wc.lpfnWndProc = DefWindowProcA; - wc.hInstance = m_hInst; - wc.lpszClassName = "D3DDeviceWindowClassForSandbox"; - if (!RegisterClassA(&wc)) - { - CryFatalError("Cannot Register Window Class %s", wc.lpszClassName); - return false; - } - m_hWnd = CreateWindowExA(exstyle, wc.lpszClassName, m_WinTitle, style, x, y, wdt, hgt, NULL, NULL, m_hInst, NULL); - ShowWindow(m_hWnd, SW_HIDE); - } - else - { - if (!hWnd) - { - LPCWSTR pClassName = L"CryENGINE"; - - // Load default icon if we have nothing yet - if (m_hIconBig == NULL) - { - SetWindowIcon("textures/default_icon.dds"); - } - - // Moved from Game DLL - WNDCLASSEXW wc; - memset(&wc, 0, sizeof(WNDCLASSEXW)); - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wc.lpfnWndProc = (WNDPROC)GetISystem()->GetRootWindowMessageHandler(); - wc.hInstance = m_hInst; - wc.hIcon = m_hIconBig; - wc.hIconSm = m_hIconSmall; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wc.lpszClassName = pClassName; - if (!RegisterClassExW(&wc)) - { - CryFatalError("Cannot Register Launcher Window Class"); - return false; - } - - wstring wideTitle = Unicode::Convert(m_WinTitle); - - m_hWnd = CreateWindowExW(exstyle, pClassName, wideTitle.c_str(), style, x, y, wdt, hgt, NULL, NULL, m_hInst, NULL); - if (m_hWnd && !IsWindowUnicode(m_hWnd)) - { - CryFatalError("Expected an UNICODE window for launcher"); - return false; - } - - // Create second window for stereo (multi-head device) - if (GetS3DRend().GetStereoDevice() == STEREO_DEVICE_DUALHEAD && fullscreen) - { - m_hWnd2 = CreateWindowExW(exstyle, pClassName, wideTitle.c_str(), style, x, y, wdt, hgt, m_hWnd, NULL, m_hInst, NULL); - } - else - { - m_hWnd2 = 0; - } - - EnableCloseButton(m_hWnd, false); - - if (fullscreen && (!gEnv->pSystem->IsDevMode() && CV_r_enableAltTab == 0)) - { - SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0); - } - } - else - { - m_hWnd = (HWND)hWnd; - } - - ShowWindow(m_hWnd, SW_SHOWNORMAL); - SetFocus(m_hWnd); - SetForegroundWindow(m_hWnd); - } - - if (!m_hWnd) - { - iConsole->Exit("Couldn't create window\n"); - } -#elif defined(OPENGL) - return DXGLCreateWindow(m_WinTitle, width, height, fullscreen, &m_hWnd); -#else - return false; -#endif //WIN32 - return true; -} - -bool CD3D9Renderer::SetWindowIcon([[maybe_unused]] const char* path) -{ -#ifdef WIN32 - if (IsEditorMode()) - { - return false; - } - - if (azstricmp(path, m_iconPath.c_str()) == 0) - { - return true; - } - - HICON hIconBig = CreateResourceFromTexture(this, path, eResourceType_IconBig); - if (hIconBig) - { - if (m_hWnd) - { - SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); - } - if (m_hWnd2) - { - SendMessage(m_hWnd2, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); - } - if (m_hIconBig) - { - ::DestroyIcon(m_hIconBig); - } - m_hIconBig = hIconBig; - m_iconPath = path; - } - - // Note: Also set the small icon manually. - // Even though the big icon will also affect the small icon, the re-scaling done by GDI has aliasing problems. - // Just grabbing a smaller MIP from the texture (if possible) will solve this. - HICON hIconSmall = CreateResourceFromTexture(this, path, eResourceType_IconSmall); - if (hIconSmall) - { - if (m_hWnd) - { - SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall); - } - if (m_hWnd) - { - SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall); - } - if (m_hIconSmall) - { - ::DestroyIcon(m_hIconSmall); - } - m_hIconSmall = hIconSmall; - } - - return hIconBig != NULL; -#else - return false; -#endif -} - -#define QUALITY_VAR(name) \ - static void OnQShaderChange_Shader##name(ICVar * pVar) \ - { \ - int iQuality = eSQ_Low; \ - if (gRenDev->GetFeatures() & (RFT_HW_SM2X | RFT_HW_SM30)) { \ - iQuality = CLAMP(pVar->GetIVal(), 0, eSQ_Max); } \ - gRenDev->EF_SetShaderQuality(eST_##name, (EShaderQuality)iQuality); \ - } - -QUALITY_VAR(General) -QUALITY_VAR(Metal) -QUALITY_VAR(Glass) -QUALITY_VAR(Ice) -QUALITY_VAR(Shadow) -QUALITY_VAR(Water) -QUALITY_VAR(FX) -QUALITY_VAR(PostProcess) -QUALITY_VAR(HDR) -QUALITY_VAR(Sky) - -#undef QUALITY_VAR - -static void OnQShaderChange_Renderer(ICVar* pVar) -{ - int iQuality = eRQ_Low; - - if (gRenDev->GetFeatures() & (RFT_HW_SM2X | RFT_HW_SM30)) - { - iQuality = CLAMP(pVar->GetIVal(), 0, eSQ_Max); - } - else - { - pVar->ForceSet("0"); - } - - gRenDev->m_RP.m_eQuality = (ERenderQuality)iQuality; -} - - -static void Command_Quality(IConsoleCmdArgs* Cmd) -{ - bool bLog = false; - bool bSet = false; - - int iQuality = -1; - - if (Cmd->GetArgCount() == 2) - { - iQuality = CLAMP(atoi(Cmd->GetArg(1)), eSQ_Low, eSQ_VeryHigh); - bSet = true; - } - else - { - bLog = true; - } - - if (bLog) - { - iLog->LogWithType(IMiniLog::eInputResponse, " "); - } - if (bLog) - { - iLog->LogWithType(IMiniLog::eInputResponse, "Current quality settings (0=low/1=med/2=high/3=very high):"); - } - -#define QUALITY_VAR(name) if (bLog) {iLog->LogWithType(IMiniLog::eInputResponse, " $3q_"#name " = $6%d", gEnv->pConsole->GetCVar("q_"#name)->GetIVal()); } \ - if (bSet) { gEnv->pConsole->GetCVar("q_"#name)->Set(iQuality); } - - QUALITY_VAR(ShaderGeneral) - QUALITY_VAR(ShaderMetal) - QUALITY_VAR(ShaderGlass) - QUALITY_VAR(ShaderVegetation) - QUALITY_VAR(ShaderIce) - QUALITY_VAR(ShaderTerrain) - QUALITY_VAR(ShaderShadow) - QUALITY_VAR(ShaderWater) - QUALITY_VAR(ShaderFX) - QUALITY_VAR(ShaderPostProcess) - QUALITY_VAR(ShaderHDR) - QUALITY_VAR(ShaderSky) - QUALITY_VAR(Renderer) - -#undef QUALITY_VAR - - if (bSet) - { - iLog->LogWithType(IMiniLog::eInputResponse, "Set quality to %d", iQuality); - } -} - -const char* sGetSQuality(const char* szName) -{ - ICVar* pVar = iConsole->GetCVar(szName); - assert(pVar); - if (!pVar) - { - return "Unknown"; - } - int iQ = pVar->GetIVal(); - switch (iQ) - { - case eSQ_Low: - return "Low"; - case eSQ_Medium: - return "Medium"; - case eSQ_High: - return "High"; - case eSQ_VeryHigh: - return "VeryHigh"; - default: - return "Unknown"; - } -} - -static void Command_ColorGradingChartImage(IConsoleCmdArgs* pCmd) -{ - CColorGradingControllerD3D* pCtrl = gcpRendD3D->m_pColorGradingControllerD3D; - if (pCmd && pCtrl) - { - const int numArgs = pCmd->GetArgCount(); - if (numArgs == 1) - { - const CTexture* pChart = pCtrl->GetStaticColorChart(); - if (pChart) - { - iLog->Log("current static chart is \"%s\"", pChart->GetName()); - } - else - { - iLog->Log("no static chart loaded"); - } - } - else if (numArgs == 2) - { - const char* pArg = pCmd->GetArg(1); - if (pArg && pArg[0]) - { - if (pArg[0] == '0' && !pArg[1]) - { - pCtrl->LoadStaticColorChart(0); - iLog->Log("static chart reset"); - } - else - { - if (pCtrl->LoadStaticColorChart(pArg)) - { - iLog->Log("\"%s\" loaded successfully", pArg); - } - else - { - iLog->Log("failed to load \"%s\"", pArg); - } - } - } - } - } -} - -WIN_HWND CD3D9Renderer::Init([[maybe_unused]] int x, [[maybe_unused]] int y, int width, int height, unsigned int cbpp, int zbpp, int sbits, bool fullscreen, bool isEditor, WIN_HINSTANCE hinst, WIN_HWND Glhwnd, [[maybe_unused]] bool bReInit, [[maybe_unused]] const SCustomRenderInitArgs* pCustomArgs, bool bShaderCacheGen) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!iSystem || !iLog) - { - AZ_Error("CD3D9Renderer::Init", iSystem, "Renderer initialization failed because iSystem was null."); - AZ_Error("CD3D9Renderer::Init", iLog, "Renderer initialization failed because iLog was null."); - return 0; - } - - iLog->Log("Initializing Direct3D and creating game window:"); - INDENT_LOG_DURING_SCOPE(); - - m_CVWidth = iConsole->GetCVar("r_Width"); - m_CVHeight = iConsole->GetCVar("r_Height"); - m_CVFullScreen = iConsole->GetCVar("r_Fullscreen"); - m_CVDisplayInfo = iConsole->GetCVar("r_DisplayInfo"); - m_CVColorBits = iConsole->GetCVar("r_ColorBits"); - - bool bNativeResolution; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(IOS) - bNativeResolution = true; -#elif defined(ANDROID) - bNativeResolution = true; -#elif defined(WIN32) || defined(WIN64) - CV_r_FullscreenWindow = iConsole->GetCVar("r_FullscreenWindow"); - m_fullscreenWindow = CV_r_FullscreenWindow && CV_r_FullscreenWindow->GetIVal(); - CV_r_FullscreenNativeRes = iConsole->GetCVar("r_FullscreenNativeRes"); - bNativeResolution = CV_r_FullscreenNativeRes && CV_r_FullscreenNativeRes->GetIVal() != 0 && (fullscreen || m_fullscreenWindow); - - { - RECT rcDesk; - GetWindowRect(GetDesktopWindow(), &rcDesk); - - m_prefMonX = rcDesk.left; - m_prefMonY = rcDesk.top; - m_prefMonWidth = rcDesk.right - rcDesk.left; - m_prefMonHeight = rcDesk.bottom - rcDesk.top; - } - { - RECT rc; - HDC hdc = GetDC(NULL); - GetClipBox(hdc, &rc); - ReleaseDC(NULL, hdc); - m_deskwidth = rc.right - rc.left; - m_deskheight = rc.bottom - rc.top; - } -#else - bNativeResolution = false; -#endif - -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - DXGLInitialize(CV_r_multithreaded ? 4 : 0); -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION - -#ifdef D3DX_SDK_VERSION - iLog->Log("D3DX_SDK_VERSION = %d", D3DX_SDK_VERSION); -#else - iLog->Log("D3DX_SDK_VERSION = "); -#endif - - iLog->Log ("Direct3D driver is creating..."); - iLog->Log ("Crytek Direct3D driver version %4.2f (%s <%s>)", VERSION_D3D, __DATE__, __TIME__); - - auto projectName = AZ::Utils::GetProjectName(); - cry_strcpy(m_WinTitle, projectName.c_str()); - - iLog->Log ("Creating window called '%s' (%dx%d)", m_WinTitle, width, height); - - m_hInst = (HINSTANCE)(TRUNCATE_PTR)hinst; - - m_bEditor = isEditor; - if (isEditor) - { - fullscreen = false; - } - - m_bShaderCacheGen = bShaderCacheGen; - - m_cbpp = cbpp; - m_zbpp = zbpp; - m_sbpp = sbits; - m_bFullScreen = fullscreen; - - CalculateResolutions(width, height, bNativeResolution, &m_width, &m_height, &m_nativeWidth, &m_nativeHeight, &m_backbufferWidth, &m_backbufferHeight); - - // only create device if we are not in shader cache generation mode - if (!m_bShaderCacheGen) - { - // call init stereo before device is created! - m_pStereoRenderer->InitDeviceBeforeD3D(); - - while (true) - { - m_hWnd = (HWND)Glhwnd; - - // Creates Device here. - bool bRes = m_pRT->RC_CreateDevice(); - if (!bRes) - { - ShutDown(true); - return 0; - } - - - break; - } - -# if defined(SUPPORT_DEVICE_INFO) - iLog->Log(" ****** D3D11 CryRender Stats ******"); - iLog->Log(" Driver description: %S", m_devInfo.AdapterDesc().Description); - - switch (m_devInfo.FeatureLevel()) - { - case D3D_FEATURE_LEVEL_9_1: - iLog->Log(" Feature level: DirectX 9.1"); - break; - case D3D_FEATURE_LEVEL_9_2: - iLog->Log(" Feature level: DirectX 9.2"); - break; - case D3D_FEATURE_LEVEL_9_3: - iLog->Log(" Feature level: DirectX 9.3"); - break; - case D3D_FEATURE_LEVEL_10_0: - iLog->Log(" Feature level: DirectX 10.0"); - break; - case D3D_FEATURE_LEVEL_10_1: - iLog->Log(" Feature level: DirectX 10.1"); - break; - case D3D_FEATURE_LEVEL_11_0: - iLog->Log(" Feature level: DirectX 11.0"); - break; - } - if (m_devInfo.DriverType() == D3D_DRIVER_TYPE_HARDWARE) - { - iLog->Log(" Rasterizer: Hardware"); - } - else if (m_devInfo.DriverType() == D3D_DRIVER_TYPE_REFERENCE) - { - iLog->Log(" Rasterizer: Reference"); - } - else if (m_devInfo.DriverType() == D3D_DRIVER_TYPE_SOFTWARE) - { - iLog->Log(" Rasterizer: Software"); - } - -# endif - iLog->Log(" Current Resolution: %dx%dx%d %s", CRenderer::m_width, CRenderer::m_height, CRenderer::m_cbpp, m_bFullScreen ? "Full Screen" : "Windowed"); - iLog->Log(" HDR Rendering: %s", m_nHDRType == 1 ? "FP16" : m_nHDRType == 2 ? "MRT" : "Disabled"); - iLog->Log(" MRT HDR Rendering: %s", (m_bDeviceSupportsFP16Separate) ? "Enabled" : "Disabled"); - iLog->Log(" Occlusion queries: %s", (m_Features & RFT_OCCLUSIONTEST) ? "Supported" : "Not supported"); - iLog->Log(" Geometry instancing: %s", (m_bDeviceSupportsInstancing) ? "Supported" : "Not supported"); - iLog->Log(" Vertex textures: %s", (m_bDeviceSupportsVertexTexture) ? "Supported" : "Not supported"); - iLog->Log(" R32F rendertarget: %s", (m_bDeviceSupportsR32FRendertarget) ? "Supported" : "Not supported"); - iLog->Log(" NormalMaps compression : %s", m_hwTexFormatSupport.m_FormatBC5U.IsValid() ? "Supported" : "Not supported"); - iLog->Log(" Gamma control: %s", (m_Features & RFT_HWGAMMA) ? "Hardware" : "Software"); - iLog->Log(" Vertex Shaders version %d.%d", 4, 0); - iLog->Log(" Pixel Shaders version %d.%d", 4, 0); - - CRenderer::ChangeGeomInstancingThreshold(); // to get log printout and to set the internal value (vendor dependent) - - m_Features |= RFT_HW_SM20 | RFT_HW_SM2X | RFT_HW_SM30; - - // Force the Z targets to be 16-bit float - if (!m_bDeviceSupportsR32FRendertarget) - { - CTexture::s_eTFZ = eTF_R16F; - } - if (!gcpRendD3D->UseHalfFloatRenderTargets()) - { - CTexture::s_eTFZ = eTF_R16U; - } - - // Note: Not rolling this into the if statement above in case s_eTFZ is set to R16F on initialization - if (CTexture::s_eTFZ != eTF_R32F) - { - CRenderer::CV_r_CBufferUseNativeDepth = 0; //0=disable - } - - if (!m_bDeviceSupportsInstancing) - { - _SetVar("r_GeomInstancing", 0); - } - - const char* str = NULL; - if (m_Features & RFT_HW_SM50) - { - str = "SM.5.0"; - } - else if (m_Features & RFT_HW_SM40) - { - str = "SM.4.0"; - } - else - { - assert(0); - } - iLog->Log(" Shader model usage: '%s'", str); - } - else - { - // force certain features during shader cache gen mode - m_Features |= RFT_HW_SM20 | RFT_HW_SM2X | RFT_HW_SM30; - - m_bDeviceSupportsFP16Filter = true; - -#if defined(ENABLE_NULL_D3D11DEVICE) - m_Device = new NullD3D11Device; - D3DDeviceContext* pContext = NULL; -#if defined(DEVICE_SUPPORTS_D3D11_3) - GetDevice().GetImmediateContext3(&pContext); -#elif defined(DEVICE_SUPPORTS_D3D11_2) - GetDevice().GetImmediateContext2(&pContext); -#elif defined(DEVICE_SUPPORTS_D3D11_1) - GetDevice().GetImmediateContext1(&pContext); -#else - GetDevice().GetImmediateContext(&pContext); -#endif - m_DeviceContext = pContext; -#endif - } - - iLog->Log(" *****************************************"); - iLog->Log(" "); - - iLog->Log("Init Shaders"); - - // if (!(GetFeatures() & (RFT_HW_PS2X | RFT_HW_PS30))) - // SetShaderQuality(eST_All, eSQ_Low); - - // Quality console variables -------------------------------------- - -#define QUALITY_VAR(name) { ICVar* pVar = iConsole->Register("q_Shader"#name, &m_cEF.m_ShaderProfiles[(int)eST_##name].m_iShaderProfileQuality, 1, \ - 0, CVARHELP("Defines the shader quality of "#name "\nUsage: q_Shader"#name " 0=low/1=med/2=high/3=very high (default)"), OnQShaderChange_Shader##name); \ - OnQShaderChange_Shader##name(pVar); \ - iLog->Log(" %s shader quality: %s", #name, sGetSQuality("q_Shader"#name)); } // clamp for lowspec - - QUALITY_VAR(General); - QUALITY_VAR(Metal); - QUALITY_VAR(Glass); - QUALITY_VAR(Ice); - QUALITY_VAR(Shadow); - QUALITY_VAR(Water); - QUALITY_VAR(FX); - QUALITY_VAR(PostProcess); - QUALITY_VAR(HDR); - QUALITY_VAR(Sky); - - -#undef QUALITY_VAR - - ICVar* pVar = REGISTER_INT_CB("q_Renderer", 3, 0, "Defines the quality of Renderer\nUsage: q_Renderer 0=low/1=med/2=high/3=very high (default)", OnQShaderChange_Renderer); - OnQShaderChange_Renderer(pVar); // clamp for lowspec, report renderer current value - iLog->Log("Render quality: %s", sGetSQuality("q_Renderer")); - - REGISTER_COMMAND("q_Quality", &Command_Quality, 0, - "If called with a parameter it sets the quality of all q_.. variables\n" - "otherwise it prints their current state\n" - "Usage: q_Quality [0=low/1=med/2=high/3=very high]"); - - REGISTER_COMMAND("r_ColorGradingChartImage", &Command_ColorGradingChartImage, 0, - "If called with a parameter it loads a color chart image. This image will overwrite\n" - " the dynamic color chart blending result and be used during post processing instead.\n" - "If called with no parameter it displays the name of the previously loaded chart.\n" - "To reset a previously loaded chart call r_ColorGradingChartImage 0.\n" - "Usage: r_ColorGradingChartImage [path of color chart image/reset]"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - -#if defined(OPENGL) && !DXGL_FULL_EMULATION && !defined(CRY_USE_METAL) - if (!m_pRT->IsRenderThread()) - { - DXGLUnbindDeviceContext(&GetDeviceContext(), !CV_r_multithreaded); - } -#endif //defined(OPENGL) && !DXGL_FULL_EMULATION - - if (!bShaderCacheGen) - { - m_pRT->RC_Init(); - } - - if (!g_shaderGeneralHeap) - { - g_shaderGeneralHeap = CryGetIMemoryManager()->CreateGeneralExpandingMemoryHeap(4 * 1024 * 1024, 0, "Shader General"); - } - - m_cEF.mfInit(); - - CWaterRipples::CreatePhysCallbacks(); - - if (!IsEditorMode() && !IsShaderCacheGenMode()) - { - m_pRT->RC_PrecacheDefaultShaders(); - } - - //PostInit(); - -#if defined(WIN32) - // Initialize the set of connected monitors - HandleMessage(0, WM_DEVICECHANGE, 0, 0, 0); - m_bDisplayChanged = false; -#endif - - m_bInitialized = true; - - // Cry_memcheck(); - - if (!bShaderCacheGen) - { - } - - // Success, return the window handle - return (m_hWnd); -} - -//============================================================================= - -int CD3D9Renderer::EnumAAFormats([[maybe_unused]] SAAFormat* formats) -{ -#if defined(SUPPORT_DEVICE_INFO) - - int numFormats = 0; - - for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++i) - { - unsigned int maxQuality; - if (SUCCEEDED(m_devInfo.Device()->CheckMultisampleQualityLevels(m_devInfo.SwapChainDesc().BufferDesc.Format, i, &maxQuality)) && maxQuality > 0) - { - if (formats) - { - formats[numFormats].nSamples = i; - formats[numFormats].nQuality = 0; - formats[numFormats].szDescr[0] = 0; - } - - ++numFormats; - } - } - - return numFormats; - -#else // #if defined(SUPPORT_DEVICE_INFO) - - return 0; - -#endif -} - -int CD3D9Renderer::GetAAFormat(TArray& Formats) -{ - int nNums = EnumAAFormats(NULL); - if (nNums > 0) - { - Formats.resize(nNums); - EnumAAFormats(&Formats[0]); - } - - for (unsigned int i = 0; i < Formats.Num(); i++) - { - if (CV_r_msaa_samples == Formats[i].nSamples && CV_r_msaa_quality == Formats[i].nQuality) - { - return (int) i; - } - } - - return -1; -} - -bool CD3D9Renderer::CheckMSAAChange() -{ - bool bChanged = false; - if (CV_r_msaa != m_MSAA || (CV_r_msaa && (m_MSAA_quality != CV_r_msaa_quality || m_MSAA_samples != CV_r_msaa_samples))) - { - if (CV_r_msaa && (m_hwTexFormatSupport.m_FormatR16G16B16A16.bCanMultiSampleRT || m_hwTexFormatSupport.m_FormatR16G16.bCanMultiSampleRT)) - { - CTexture::s_eTFZ = eTF_R32F; - TArray Formats; - int nNum = GetAAFormat(Formats); - if (nNum < 0) - { - iLog->Log(" MSAA: Requested mode not supported\n"); - _SetVar("r_MSAA", 0); - m_MSAA = 0; - } - else - { - iLog->Log(" MSAA: Enabled %d samples (quality level %d)", Formats[nNum].nSamples, Formats[nNum].nQuality); - if (Formats[nNum].nQuality != m_MSAA_quality || Formats[nNum].nSamples != m_MSAA_samples) - { - bChanged = true; - _SetVar("r_MSAA_quality", Formats[nNum].nQuality); - _SetVar("r_MSAA_samples", Formats[nNum].nSamples); - } - else - if (!m_MSAA) - { - bChanged = true; - } - } - } - else - { - CTexture::s_eTFZ = eTF_R32F; - bChanged = true; - iLog->Log(" MSAA: Disabled"); - } - m_MSAA = CV_r_msaa; - m_MSAA_quality = CV_r_msaa_quality; - m_MSAA_samples = CV_r_msaa_samples; - } - - return bChanged; -} - -bool CD3D9Renderer::CheckSSAAChange() -{ - const int width = m_CVWidth ? m_CVWidth->GetIVal() : m_width; - const int height = m_CVHeight ? m_CVHeight->GetIVal() : m_height; - int numSSAASamples = 1; - if (width > 0 && height > 0) - { - const int maxSamples = min(m_MaxTextureSize / width, m_MaxTextureSize / height); - numSSAASamples = clamp_tpl(CV_r_Supersampling, 1, maxSamples); - } - if (m_numSSAASamples != numSSAASamples) - { - m_numSSAASamples = numSSAASamples; - return true; - } - return false; -} - -//========================================================================== -bool CD3D9Renderer::SetRes() -{ - LOADING_TIME_PROFILE_SECTION; - ChangeLog(); - - m_pixelAspectRatio = 1.0f; - - /////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_8 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(IOS) || defined(ANDROID) - m_bFullScreen = true; - - if (!m_devInfo.CreateDevice(false, m_width, m_height, m_backbufferWidth, m_backbufferHeight, m_zbpp, OnD3D11CreateDevice, CreateWindowCallback)) - { - return false; - } - m_devInfo.SyncInterval() = m_VSync ? 1 : 0; - - OnD3D11PostCreateDevice(m_devInfo.Device()); - - AdjustWindowForChange(); - - CreateContext(m_hWnd); -#elif defined(WIN32) || defined(APPLE) || defined(LINUX) - - UnSetRes(); - - int width = m_width; - int height = m_height; - if (IsEditorMode()) - { - // Note: Editor is a special case, m_backbufferWidth needs to be the same as m_width - width = m_deskwidth; - height = m_deskheight; - } - - // DirectX9 and DirectX10 device creating -#if defined(SUPPORT_DEVICE_INFO) - if (m_devInfo.CreateDevice(!m_bFullScreen, width, height, m_backbufferWidth, m_backbufferHeight, m_zbpp, OnD3D11CreateDevice, CreateWindowCallback)) - { - m_devInfo.SyncInterval() = m_VSync ? 1 : 0; - } - else - { - return false; - } - - OnD3D11PostCreateDevice(m_devInfo.Device()); -#endif - - AdjustWindowForChange(); - - CreateContext(m_hWnd); - -#else - #error UNKNOWN RENDER DEVICE PLATFORM -#endif - - m_DevBufMan.Init(); - - m_pStereoRenderer->InitDeviceAfterD3D(); - - return true; -} - - -bool SPixFormat::CheckSupport(D3DFormat Format, const char* szDescr, [[maybe_unused]] ETexture_Usage eTxUsage) -{ - bool bRes = true; - CD3D9Renderer* rd = gcpRendD3D; - - UINT nOptions; - HRESULT hr = gcpRendD3D->GetDevice().CheckFormatSupport(Format, &nOptions); - if (SUCCEEDED(hr)) - { - if (nOptions & (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE)) - { - bool canReadSRGB = CTexture::IsDeviceFormatSRGBReadable(Format); - - // TODO: check if need to allow other compressed formats to stay here formats here too? - // Adding PVRTC format here improved the picture on iOS device. - - bool bCanMips = true; - - Init(); - DeviceFormat = Format; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_9 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - MaxWidth = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; - MaxHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; -#endif - Desc = szDescr; - BytesPerBlock = CTexture::BytesPerBlock(CTexture::TexFormatFromDeviceFormat(Format)); - - bCanDS = (nOptions & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0; - bCanRT = (nOptions & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0; - bCanMultiSampleRT = (nOptions & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0; - bCanMips = (nOptions & D3D11_FORMAT_SUPPORT_MIP) != 0; - bCanMipsAutoGen = (nOptions & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0; - bCanGather = (nOptions & D3D11_FORMAT_SUPPORT_SHADER_GATHER) != 0; - bCanGatherCmp = (nOptions & D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON) != 0; - bCanBlend = (nOptions & D3D11_FORMAT_SUPPORT_BLENDABLE) != 0; - bCanReadSRGB = canReadSRGB; - - if (bCanDS || bCanRT || bCanGather || bCanBlend || bCanReadSRGB || bCanMips) - { - iLog->Log(" %s%s%s%s%s%s%s%s%s%s", - szDescr, - bCanMips ? ", mips" : "", - bCanMipsAutoGen ? " (autogen)" : "", - bCanReadSRGB ? ", sRGB" : "", - bCanBlend ? ", blend" : "", - bCanDS ? ", DS" : "", - bCanRT ? ", RT" : "", - bCanMultiSampleRT ? " (multi-sampled)" : "", - bCanGather ? ", gather" : "", - bCanGatherCmp ? " (comparable)" : "" - ); - } - else - { - iLog->Log(" %s", szDescr); - } - - Next = rd->m_hwTexFormatSupport.m_FirstPixelFormat; - rd->m_hwTexFormatSupport.m_FirstPixelFormat = this; - } - else - { - bRes = false; - } - } - else - { - bRes = false; - } - - return bRes; -} - -void SPixFormatSupport::CheckFormatSupport() -{ - iLog->Log("Using pixel texture formats:"); - - m_FirstPixelFormat = NULL; - - m_FormatR8G8B8A8S.CheckSupport(DXGI_FORMAT_R8G8B8A8_SNORM, "R8G8B8A8S"); - m_FormatR8G8B8A8.CheckSupport(DXGI_FORMAT_R8G8B8A8_UNORM, "R8G8B8A8"); - - //m_FormatR1.CheckSupport(DXGI_FORMAT_R1_UNORM, "R1"); - m_FormatA8.CheckSupport(DXGI_FORMAT_A8_UNORM, "A8"); - m_FormatR8.CheckSupport(DXGI_FORMAT_R8_UNORM, "R8"); - m_FormatR8S.CheckSupport(DXGI_FORMAT_R8_SNORM, "R8S"); - m_FormatR16.CheckSupport(DXGI_FORMAT_R16_UNORM, "R16"); - m_FormatR16U.CheckSupport(DXGI_FORMAT_R16_UINT, "R16U"); - m_FormatR16G16U.CheckSupport(DXGI_FORMAT_R16G16_UINT, "R16G16U"); - m_FormatR10G10B10A2UI.CheckSupport(DXGI_FORMAT_R10G10B10A2_UINT, "R10G10B10A2UI"); - m_FormatR16F.CheckSupport(DXGI_FORMAT_R16_FLOAT, "R16F"); - m_FormatR32F.CheckSupport(DXGI_FORMAT_R32_FLOAT, "R32F"); - m_FormatR8G8.CheckSupport(DXGI_FORMAT_R8G8_UNORM, "R8G8"); - m_FormatR8G8S.CheckSupport(DXGI_FORMAT_R8G8_SNORM, "R8G8S"); - m_FormatR16G16.CheckSupport(DXGI_FORMAT_R16G16_UNORM, "R16G16"); - m_FormatR16G16S.CheckSupport(DXGI_FORMAT_R16G16_SNORM, "R16G16S"); - m_FormatR16G16F.CheckSupport(DXGI_FORMAT_R16G16_FLOAT, "R16G16F"); - m_FormatR11G11B10F.CheckSupport(DXGI_FORMAT_R11G11B10_FLOAT, "R11G11B10F"); - m_FormatR10G10B10A2.CheckSupport(DXGI_FORMAT_R10G10B10A2_UNORM, "R10G10B10A2"); - m_FormatR16G16B16A16.CheckSupport(DXGI_FORMAT_R16G16B16A16_UNORM, "R16G16B16A16"); - m_FormatR16G16B16A16S.CheckSupport(DXGI_FORMAT_R16G16B16A16_SNORM, "R16G16B16A16S"); - m_FormatR16G16B16A16F.CheckSupport(DXGI_FORMAT_R16G16B16A16_FLOAT, "R16G16B16A16F"); - m_FormatR32G32B32A32F.CheckSupport(DXGI_FORMAT_R32G32B32A32_FLOAT, "R32G32B32A32F"); - - m_FormatBC1.CheckSupport(DXGI_FORMAT_BC1_UNORM, "BC1"); - m_FormatBC2.CheckSupport(DXGI_FORMAT_BC2_UNORM, "BC2"); - m_FormatBC3.CheckSupport(DXGI_FORMAT_BC3_UNORM, "BC3"); - m_FormatBC4U.CheckSupport(DXGI_FORMAT_BC4_UNORM, "BC4"); - m_FormatBC4S.CheckSupport(DXGI_FORMAT_BC4_SNORM, "BC4S"); - m_FormatBC5U.CheckSupport(DXGI_FORMAT_BC5_UNORM, "BC5"); - m_FormatBC5S.CheckSupport(DXGI_FORMAT_BC5_SNORM, "BC5S"); - m_FormatBC6UH.CheckSupport(DXGI_FORMAT_BC6H_UF16, "BC6UH"); - m_FormatBC6SH.CheckSupport(DXGI_FORMAT_BC6H_SF16, "BC6SH"); - m_FormatBC7.CheckSupport(DXGI_FORMAT_BC7_UNORM, "BC7"); - m_FormatR9G9B9E5.CheckSupport(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, "R9G9B9E5"); - - // Depth formats -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_10 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - m_FormatD32FS8.CheckSupport(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, "R32FX8T"); - m_FormatD32F.CheckSupport(DXGI_FORMAT_R32_TYPELESS, "R32T"); - m_FormatD24S8.CheckSupport(DXGI_FORMAT_R24G8_TYPELESS, "R24G8T"); - m_FormatD16.CheckSupport(DXGI_FORMAT_R16_TYPELESS, "R16T"); -#endif - - m_FormatB5G6R5.CheckSupport(DXGI_FORMAT_B5G6R5_UNORM, "B5G6R5"); - m_FormatB5G5R5.CheckSupport(DXGI_FORMAT_B5G5R5A1_UNORM, "B5G5R5"); - // m_FormatB4G4R4A4.CheckSupport(DXGI_FORMAT_B4G4R4A4_UNORM, "B4G4R4A4"); - - m_FormatB8G8R8A8.CheckSupport(DXGI_FORMAT_B8G8R8A8_UNORM, "B8G8R8A8"); - m_FormatB8G8R8X8.CheckSupport(DXGI_FORMAT_B8G8R8X8_UNORM, "B8G8R8X8"); - -#if defined(OPENGL) - m_FormatEAC_R11.CheckSupport(DXGI_FORMAT_EAC_R11_UNORM, "EAC_R11"); - m_FormatEAC_RG11.CheckSupport(DXGI_FORMAT_EAC_RG11_UNORM, "EAC_RG11"); - m_FormatETC2.CheckSupport(DXGI_FORMAT_ETC2_UNORM, "ETC2"); - m_FormatETC2A.CheckSupport(DXGI_FORMAT_ETC2A_UNORM, "ETC2A"); -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - m_FormatPVRTC2.CheckSupport(DXGI_FORMAT_PVRTC2_UNORM, "PVRTC2"); - m_FormatPVRTC4.CheckSupport(DXGI_FORMAT_PVRTC4_UNORM, "PVRTC4"); -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - m_FormatASTC_4x4.CheckSupport(DXGI_FORMAT_ASTC_4x4_UNORM, "ASTC_4x4"); - m_FormatASTC_5x4.CheckSupport(DXGI_FORMAT_ASTC_5x4_UNORM, "ASTC_5x4"); - m_FormatASTC_5x5.CheckSupport(DXGI_FORMAT_ASTC_5x5_UNORM, "ASTC_5x5"); - m_FormatASTC_6x5.CheckSupport(DXGI_FORMAT_ASTC_6x5_UNORM, "ASTC_6x5"); - m_FormatASTC_6x6.CheckSupport(DXGI_FORMAT_ASTC_6x6_UNORM, "ASTC_6x6"); - m_FormatASTC_8x5.CheckSupport(DXGI_FORMAT_ASTC_8x5_UNORM, "ASTC_8x5"); - m_FormatASTC_8x6.CheckSupport(DXGI_FORMAT_ASTC_8x6_UNORM, "ASTC_8x6"); - m_FormatASTC_8x8.CheckSupport(DXGI_FORMAT_ASTC_8x8_UNORM, "ASTC_8x8"); - m_FormatASTC_10x5.CheckSupport(DXGI_FORMAT_ASTC_10x5_UNORM, "ASTC_10x5"); - m_FormatASTC_10x6.CheckSupport(DXGI_FORMAT_ASTC_10x6_UNORM, "ASTC_10x6"); - m_FormatASTC_10x8.CheckSupport(DXGI_FORMAT_ASTC_10x8_UNORM, "ASTC_10x8"); - m_FormatASTC_10x10.CheckSupport(DXGI_FORMAT_ASTC_10x10_UNORM, "ASTC_10x10"); - m_FormatASTC_12x10.CheckSupport(DXGI_FORMAT_ASTC_12x10_UNORM, "ASTC_12x10"); - m_FormatASTC_12x12.CheckSupport(DXGI_FORMAT_ASTC_12x12_UNORM, "ASTC_12x12"); -#endif -} - -void CD3D9Renderer::GetVideoMemoryUsageStats(size_t& vidMemUsedThisFrame, size_t& vidMemUsedRecently, bool bGetPoolsSizes) -{ - if (bGetPoolsSizes) - { - vidMemUsedThisFrame = vidMemUsedRecently = (GetTexturesStreamPoolSize() + CV_r_rendertargetpoolsize) * 1024 * 1024; - } - else - { - assert(!"CD3D9Renderer::GetVideoMemoryUsageStats() not implemented for this platform yet!"); - vidMemUsedThisFrame = vidMemUsedRecently = 0; - } -} - -//=========================================================================================== - -HRESULT CALLBACK CD3D9Renderer::OnD3D11CreateDevice(D3DDevice* pd3dDevice) -{ - LOADING_TIME_PROFILE_SECTION; - CD3D9Renderer* rd = gcpRendD3D; - rd->m_Device = pd3dDevice; - -#if defined(SUPPORT_DEVICE_INFO) - rd->m_DeviceContext = rd->m_devInfo.Context(); -#endif - rd->m_Features |= RFT_OCCLUSIONQUERY | RFT_ALLOWANISOTROPIC | RFT_HW_SM20 | RFT_HW_SM2X | RFT_HW_SM30 | RFT_HW_SM40 | RFT_HW_SM50; - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) - rd->m_d3dDebug.Init(pd3dDevice); - rd->m_d3dDebug.Update(ESeverityCombination(CV_d3d11_debugMuteSeverity->GetIVal()), CV_d3d11_debugMuteMsgID->GetString(), CV_d3d11_debugBreakOnMsgID->GetString()); - rd->m_bUpdateD3DDebug = false; -#endif - -#if defined(SUPPORT_DEVICE_INFO) - rd->BindContextToThread(CryGetCurrentThreadId()); - - LARGE_INTEGER driverVersion; - driverVersion.LowPart = 0; - driverVersion.HighPart = 0; - rd->m_devInfo.Adapter()->CheckInterfaceSupport(__uuidof(ID3D10Device), &driverVersion); - iLog->Log ("D3D Adapter: Description: %ls", rd->m_devInfo.AdapterDesc().Description); - iLog->Log ("D3D Adapter: Driver version (UMD): %d.%02d.%02d.%04d", HIWORD(driverVersion.u.HighPart), LOWORD(driverVersion.u.HighPart), HIWORD(driverVersion.u.LowPart), LOWORD(driverVersion.u.LowPart)); - iLog->Log ("D3D Adapter: VendorId = 0x%.4X", rd->m_devInfo.AdapterDesc().VendorId); - iLog->Log ("D3D Adapter: DeviceId = 0x%.4X", rd->m_devInfo.AdapterDesc().DeviceId); - iLog->Log ("D3D Adapter: SubSysId = 0x%.8X", rd->m_devInfo.AdapterDesc().SubSysId); - iLog->Log ("D3D Adapter: Revision = %i", rd->m_devInfo.AdapterDesc().Revision); - - // Vendor-specific initializations and workarounds for driver bugs. - { - const DXGI_ADAPTER_DESC1& adapterDesc = rd->m_devInfo.AdapterDesc(); - - rd->m_adapterDescription = AZStd::string::format("%ls", adapterDesc.Description); - - if (adapterDesc.VendorId == RenderCapabilities::s_gpuVendorIdAMD) - { - rd->m_Features |= RFT_HW_ATI; - iLog->Log ("D3D Detected: AMD video card"); - } - else if (adapterDesc.VendorId == RenderCapabilities::s_gpuVendorIdNVIDIA) - { - rd->m_Features |= RFT_HW_NVIDIA; - iLog->Log ("D3D Detected: NVIDIA video card"); - } - else if (adapterDesc.VendorId == RenderCapabilities::s_gpuVendorIdQualcomm) - { - rd->m_Features |= RFT_HW_QUALCOMM; - iLog->Log ("D3D Detected: Qualcomm video card"); - } - else if (rd->m_devInfo.AdapterDesc().VendorId == RenderCapabilities::s_gpuVendorIdIntel) - { - rd->m_Features |= RFT_HW_INTEL; - iLog->Log ("D3D Detected: intel video card"); - } - else if (rd->m_devInfo.AdapterDesc().VendorId == RenderCapabilities::s_gpuVendorIdARM) - { - rd->m_Features |= RFT_HW_ARM_MALI; - iLog->Log ("D3D Detected: ARM (MALI) video card"); - } - -#if defined(OPENGL) && !defined(CRY_USE_METAL) - DXGLInitializeIHVSpecifix(); -#endif - } - - rd->m_nGPUs = min(rd->m_nGPUs, (uint32)MAX_GPU_NUM); -#endif - - CryLogAlways("Active GPUs: %i", rd->m_nGPUs); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_11 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - rd->m_NumResourceSlots = D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT; - rd->m_NumSamplerSlots = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; - rd->m_MaxAnisotropyLevel = min(D3D11_REQ_MAXANISOTROPY, CRenderer::CV_r_texmaxanisotropy); -#endif - -#if defined(WIN32) || defined(WIN64) - HWND hWndDesktop = GetDesktopWindow(); - HDC dc = GetDC(hWndDesktop); - uint16 gamma[3][256]; - if (GetDeviceGammaRamp(dc, gamma)) - { - rd->m_Features |= RFT_HWGAMMA; - } - ReleaseDC(hWndDesktop, dc); -#endif - - // For safety, lots of drivers don't handle tiny texture sizes too tell. -#if defined(SUPPORT_DEVICE_INFO) && !defined(CRY_USE_METAL) - rd->m_MaxTextureMemory = rd->m_devInfo.AdapterDesc().DedicatedVideoMemory; -#else - rd->m_MaxTextureMemory = 256 * 1024 * 1024; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_12 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#elif defined(IOS) - rd->m_MaxTextureMemory = 1024 * 1024 * 1024; -#endif -#endif - if (CRenderer::CV_r_TexturesStreamPoolSize <= 0) - { - CRenderer::CV_r_TexturesStreamPoolSize = (int)(rd->m_MaxTextureMemory / 1024.0f / 1024.0f * 0.75f); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_13 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - rd->m_MaxTextureSize = D3D11_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION; - rd->m_bDeviceSupportsInstancing = true; -#endif - - rd->m_bDeviceSupportsVertexTexture = (rd->m_Features & RFT_HW_SM30); - if (rd->m_bDeviceSupportsVertexTexture != 0) - { - rd->m_Features |= RFT_HW_VERTEXTEXTURES; - } - -#if defined(CRY_USE_METAL) || (defined(OPENGL_ES)) - // METAL Supports R32 RTs but it doesn't support blending for it. Cryengine uses blending to fix up depth. - // Disable R32 RT for metal for now. - // Qualcomm's OpenGL ES 3.0 driver does not support R32F render targets. Disabling for all OpenGL ES 3.0 versions for the time being. - // When bound as a render target, we get this error: - // W/Adreno-ES20(12623): : GL_INVALID_OPERATION - - //R32 depth render targets are showing instability on Mali GPUs. For stability reasons we are forcing R16 render targets across all Android devices. - rd->m_bDeviceSupportsR32FRendertarget = false; -#else - rd->m_bDeviceSupportsR32FRendertarget = true; -#endif - -#if defined(CRY_USE_METAL) || defined(OPENGL) - D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS computeShadersSupport; - HRESULT result = rd->GetDevice().CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &computeShadersSupport, sizeof(computeShadersSupport)); - if (result == S_OK && computeShadersSupport.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x == TRUE) - { - rd->m_Features |= RFT_COMPUTE_SHADERS; - } -#else - rd->m_Features |= RFT_COMPUTE_SHADERS; -#endif - - if (RenderCapabilities::SupportsStructuredBuffer(EShaderStage_Vertex)) - { - rd->m_Features |= RFT_HW_VERTEX_STRUCTUREDBUF; - } - -#if defined(DIRECT3D10) && !defined(OPENGL_ES) && !defined(CRY_USE_METAL) - rd->m_bDeviceSupportsGeometryShaders = (rd->m_Features & RFT_HW_SM40) != 0; -#else - rd->m_bDeviceSupportsGeometryShaders = false; -#endif - -#if defined(DIRECT3D10) && !defined(OPENGL) && !defined(CRY_USE_METAL) - rd->m_bDeviceSupportsTessellation = (rd->m_Features & RFT_HW_SM50) != 0; -#else - rd->m_bDeviceSupportsTessellation = false; -#endif - - rd->m_Features |= RFT_OCCLUSIONTEST; - - rd->m_bUseWaterTessHW = CV_r_WaterTessellationHW != 0 && rd->m_bDeviceSupportsTessellation; - - PREFAST_SUPPRESS_WARNING(6326); //not a constant vs constant comparison on Win32/Win64 - rd->m_bUseSilhouettePOM = CV_r_SilhouettePOM != 0; - rd->m_bUseSpecularAntialiasing = CV_r_SpecularAntialiasing != 0; - CV_r_DeferredShadingAmbientSClear = !(rd->m_Features & RFT_HW_NVIDIA) ? 0 : CV_r_DeferredShadingAmbientSClear; - - // Handle the texture formats we need. - { - // Find the needed texture formats. - rd->m_hwTexFormatSupport.CheckFormatSupport(); - - rd->m_bDeviceSupportsFP16Separate = false; - rd->m_bDeviceSupportsFP16Filter = true; - -#ifdef CRY_USE_METAL - rd->m_FormatPVRTC2.CheckSupport(DXGI_FORMAT_PVRTC2_UNORM, "PVRTC2"); - rd->m_FormatPVRTC4.CheckSupport(DXGI_FORMAT_PVRTC4_UNORM, "PVRTC4"); -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - rd->m_FormatASTC_4x4.CheckSupport(DXGI_FORMAT_ASTC_4x4_UNORM, "ASTC_4x4"); - rd->m_FormatASTC_5x4.CheckSupport(DXGI_FORMAT_ASTC_5x4_UNORM, "ASTC_5x4"); - rd->m_FormatASTC_5x5.CheckSupport(DXGI_FORMAT_ASTC_5x5_UNORM, "ASTC_5x5"); - rd->m_FormatASTC_6x5.CheckSupport(DXGI_FORMAT_ASTC_6x5_UNORM, "ASTC_6x5"); - rd->m_FormatASTC_6x6.CheckSupport(DXGI_FORMAT_ASTC_6x6_UNORM, "ASTC_6x6"); - rd->m_FormatASTC_8x5.CheckSupport(DXGI_FORMAT_ASTC_8x5_UNORM, "ASTC_8x5"); - rd->m_FormatASTC_8x6.CheckSupport(DXGI_FORMAT_ASTC_8x6_UNORM, "ASTC_8x6"); - rd->m_FormatASTC_8x8.CheckSupport(DXGI_FORMAT_ASTC_8x8_UNORM, "ASTC_8x8"); - rd->m_FormatASTC_10x5.CheckSupport(DXGI_FORMAT_ASTC_10x5_UNORM, "ASTC_10x5"); - rd->m_FormatASTC_10x6.CheckSupport(DXGI_FORMAT_ASTC_10x6_UNORM, "ASTC_10x6"); - rd->m_FormatASTC_10x8.CheckSupport(DXGI_FORMAT_ASTC_10x8_UNORM, "ASTC_10x8"); - rd->m_FormatASTC_10x10.CheckSupport(DXGI_FORMAT_ASTC_10x10_UNORM, "ASTC_10x10"); - rd->m_FormatASTC_12x10.CheckSupport(DXGI_FORMAT_ASTC_12x10_UNORM, "ASTC_12x10"); - rd->m_FormatASTC_12x12.CheckSupport(DXGI_FORMAT_ASTC_12x12_UNORM, "ASTC_12x12"); -#endif - - if (rd->m_hwTexFormatSupport.m_FormatBC1.IsValid() || rd->m_hwTexFormatSupport.m_FormatBC2.IsValid() || rd->m_hwTexFormatSupport.m_FormatBC3.IsValid()) - { - rd->m_Features |= RFT_COMPRESSTEXTURE; - } - } - - rd->m_Features |= RFT_HW_HDR; - - rd->m_nHDRType = 1; - - rd->m_FullResRect.right = rd->m_width; - rd->m_FullResRect.bottom = rd->m_height; - -#if defined(WIN32) || defined(WIN64) || defined(APPLE) || defined(LINUX) || defined(CREATE_DEVICE_ON_MAIN_THREAD) - rd->m_pRT->RC_SetViewport(0, 0, rd->m_width, rd->m_height); -#else - rd->RT_SetViewport(0, 0, rd->m_width, rd->m_height); -#endif - rd->m_MainViewport.nX = 0; - rd->m_MainViewport.nY = 0; - rd->m_MainViewport.nWidth = rd->m_width; - rd->m_MainViewport.nHeight = rd->m_height; - - return S_OK; -} - -HRESULT CALLBACK CD3D9Renderer::OnD3D11PostCreateDevice(D3DDevice* pd3dDevice) -{ - LOADING_TIME_PROFILE_SECTION; - CD3D9Renderer* rd = gcpRendD3D; - HRESULT hr; - -#if defined(SUPPORT_DEVICE_INFO) - rd->BindContextToThread(CryGetCurrentThreadId()); - rd->m_DeviceContext = rd->m_devInfo.Context(); - - rd->m_pBackBuffer = rd->m_devInfo.BackbufferRTV(); - rd->m_pBackBuffers = rd->m_devInfo.BackbufferRTVs(); - rd->m_pSwapChain = rd->m_devInfo.SwapChain(); - rd->m_pCurrentBackBufferIndex = rd->GetCurrentBackBufferIndex(rd->m_pSwapChain); -#endif - - void* pBackBuf; - hr = rd->m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &pBackBuf); - if (FAILED(hr)) - { - return hr; - } - ID3D11Texture2D* pBackBuffer = (ID3D11Texture2D*)pBackBuf; - D3D11_TEXTURE2D_DESC backBufferSurfaceDesc; - pBackBuffer->GetDesc(&backBufferSurfaceDesc); - ZeroMemory(&rd->m_d3dsdBackBuffer, sizeof(DXGI_SURFACE_DESC)); - rd->m_d3dsdBackBuffer.Width = (UINT) backBufferSurfaceDesc.Width; - rd->m_d3dsdBackBuffer.Height = (UINT) backBufferSurfaceDesc.Height; -#if defined(SUPPORT_DEVICE_INFO) - rd->m_d3dsdBackBuffer.Format = backBufferSurfaceDesc.Format; - rd->m_d3dsdBackBuffer.SampleDesc = backBufferSurfaceDesc.SampleDesc; - rd->m_ZFormat = rd->m_devInfo.AutoDepthStencilFmt(); -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_14 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - SAFE_RELEASE(pBackBuffer); - - if (FAILED(hr)) - { - return hr; - } - - // Collect depth stencil parameters - D3D11_TEXTURE2D_DESC dsTextureDesc; - dsTextureDesc.MipLevels = 1; - dsTextureDesc.ArraySize = 1; - dsTextureDesc.Format = rd->m_ZFormat; - dsTextureDesc.SampleDesc = rd->m_d3dsdBackBuffer.SampleDesc; - dsTextureDesc.Usage = D3D11_USAGE_DEFAULT; - dsTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; - dsTextureDesc.CPUAccessFlags = 0; - dsTextureDesc.MiscFlags = 0; - D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc; - dsViewDesc.Format = CTexture::ConvertToDepthStencilFmt(dsTextureDesc.Format); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_15 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - dsViewDesc.Flags = 0; -#endif - dsViewDesc.ViewDimension = dsTextureDesc.SampleDesc.Count > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; - dsViewDesc.Texture2D.MipSlice = 0; - - const float clearDepth = CRenderer::CV_r_ReverseDepth ? 0.f : 1.f; - const uint clearStencil = 1; - const FLOAT clearValues[4] = { clearDepth, FLOAT(clearStencil) }; - - int nDepthBufferWidth = rd->IsEditorMode() ? rd->m_d3dsdBackBuffer.Width : rd->m_width; - int nDepthBufferHeight = rd->IsEditorMode() ? rd->m_d3dsdBackBuffer.Height : rd->m_height; - - // Create the depth stencil buffer for scene rendering - SAFE_RELEASE(rd->m_pZTexture); - SAFE_RELEASE(rd->m_pZBuffer); - dsTextureDesc.Width = nDepthBufferWidth; - dsTextureDesc.Height = nDepthBufferHeight; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_16 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - hr = rd->m_DevMan.CreateD3D11Texture2D(&dsTextureDesc, clearValues, NULL, &rd->m_pZTexture, "DepthBuffer"); - if (FAILED(hr)) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_17 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - return hr; - } - hr = rd->GetDevice().CreateDepthStencilView(rd->m_pZTexture, &dsViewDesc, &rd->m_pZBuffer); - if (FAILED(hr)) - { - return hr; - } - rd->GetDeviceContext().ClearDepthStencilView(rd->m_pZBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, clearDepth, clearStencil); - - // Create the native resolution depth stencil buffer for overlay rendering if needed - SAFE_RELEASE(rd->m_pNativeZTexture); - SAFE_RELEASE(rd->m_pNativeZBuffer); - if (!rd->IsEditorMode() && (gcpRendD3D->GetOverlayWidth() != dsTextureDesc.Width || gcpRendD3D->GetOverlayHeight() != dsTextureDesc.Height)) - { - dsTextureDesc.Width = gcpRendD3D->GetOverlayWidth(); - dsTextureDesc.Height = gcpRendD3D->GetOverlayHeight(); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_18 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif - hr = rd->m_DevMan.CreateD3D11Texture2D(&dsTextureDesc, clearValues, NULL, &rd->m_pNativeZTexture, "DepthBuffer"); - if (FAILED(hr)) - { - return hr; - } - hr = rd->GetDevice().CreateDepthStencilView(rd->m_pNativeZTexture, &dsViewDesc, &rd->m_pNativeZBuffer); - if (FAILED(hr)) - { - return hr; - } - rd->GetDeviceContext().ClearDepthStencilView(rd->m_pNativeZBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, clearDepth, clearStencil); - } - else - { - rd->m_pNativeZTexture = rd->m_pZTexture; - rd->m_pNativeZBuffer = rd->m_pZBuffer; - rd->m_pNativeZTexture->AddRef(); - rd->m_pNativeZBuffer->AddRef(); - } - rd->m_DepthBufferOrig.pTex = nullptr; - rd->m_DepthBufferOrig.pTarget = rd->m_pZTexture; - rd->m_DepthBufferOrig.pSurf = rd->m_pZBuffer; - rd->m_pZBuffer->AddRef(); - - rd->m_DepthBufferOrigMSAA.pTex = nullptr; - rd->m_DepthBufferOrigMSAA.pTarget = rd->m_pZTexture; - rd->m_DepthBufferOrigMSAA.pSurf = rd->m_pZBuffer; - rd->m_pZBuffer->AddRef(); - - rd->m_DepthBufferNative.pTex = nullptr; - rd->m_DepthBufferNative.pTarget = rd->m_pNativeZTexture; - rd->m_DepthBufferNative.pSurf = rd->m_pNativeZBuffer; - rd->m_pNativeZBuffer->AddRef(); - - rd->m_nRTStackLevel[0] = 0; - if (rd->m_d3dsdBackBuffer.Width == rd->m_nativeWidth && rd->m_d3dsdBackBuffer.Height == rd->m_nativeHeight) - { - rd->m_RTStack[0][0].m_pDepth = rd->m_pNativeZBuffer; - rd->m_RTStack[0][0].m_pSurfDepth = &rd->m_DepthBufferNative; - } - else - { - rd->m_RTStack[0][0].m_pDepth = NULL; - rd->m_RTStack[0][0].m_pSurfDepth = NULL; - } - rd->m_RTStack[0][0].m_pTarget = rd->m_pBackBuffer; - rd->m_RTStack[0][0].m_Width = rd->m_d3dsdBackBuffer.Width; - rd->m_RTStack[0][0].m_Height = rd->m_d3dsdBackBuffer.Height; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_19 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - rd->m_RTStack[0][0].m_bScreenVP = false; -#endif - rd->m_RTStack[0][0].m_bWasSetRT = false; - rd->m_RTStack[0][0].m_bWasSetD = false; - rd->m_nMaxRT2Commit = 0; - rd->m_pNewTarget[0] = &rd->m_RTStack[0][0]; - rd->FX_SetActiveRenderTargets(); - - for (int i = 0; i < RT_STACK_WIDTH; i++) - { - rd->m_pNewTarget[i] = &rd->m_RTStack[i][0]; - rd->m_pCurTarget[i] = rd->m_pNewTarget[0]->m_pTex; - } - - rd->m_DepthBufferOrig.nWidth = nDepthBufferWidth; - rd->m_DepthBufferOrig.nHeight = nDepthBufferHeight; - rd->m_DepthBufferOrig.bBusy = true; - rd->m_DepthBufferOrig.nFrameAccess = -2; - - rd->m_DepthBufferOrigMSAA.nWidth = nDepthBufferWidth; - rd->m_DepthBufferOrigMSAA.nHeight = nDepthBufferHeight; - rd->m_DepthBufferOrigMSAA.bBusy = true; - rd->m_DepthBufferOrigMSAA.nFrameAccess = -2; - - rd->m_DepthBufferNative.nWidth = rd->m_nativeWidth; - rd->m_DepthBufferNative.nHeight = rd->m_nativeHeight; - rd->m_DepthBufferNative.bBusy = true; - rd->m_DepthBufferNative.nFrameAccess = -2; - - SAFE_RELEASE(rd->m_RP.m_MSAAData.m_pDepthTex); - SAFE_RELEASE(rd->m_RP.m_MSAAData.m_pZBuffer); - - rd->CreateMSAADepthBuffer(); - - // Create shader bindable depthstencil buffer view and shader resource view. Ideally would be unified into regular texture creation - requires big refactoring - SAFE_RELEASE(rd->m_pZBufferReadOnlyDSV); - SAFE_RELEASE(rd->m_pZBufferDepthReadOnlySRV); - SAFE_RELEASE(rd->m_pZBufferStencilReadOnlySRV); - D3DTexture* pDepthStencil = rd->m_DepthBufferOrigMSAA.pTarget; - D3D11_TEXTURE2D_DESC descDepthStencil; - pDepthStencil->GetDesc(&descDepthStencil); - -#if defined(SUPPORT_DEVICE_INFO) - if (rd->DevInfo().FeatureLevel() >= D3D_FEATURE_LEVEL_11_0) // Read-only depth-stencil supported on 11.0 feature level and above, leave NULL otherwise resulting in no testing -#endif //defined(SUPPORT_DEVICE_INFO) - { - D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; - ZeroStruct(descDSV); - descDSV.Format = CTexture::ConvertToDepthStencilFmt(descDepthStencil.Format); - descDSV.Flags = D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL; - descDSV.ViewDimension = (descDepthStencil.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; - descDSV.Texture2D.MipSlice = 0; - hr = rd->GetDevice().CreateDepthStencilView(pDepthStencil, &descDSV, &rd->m_pZBufferReadOnlyDSV); - assert(SUCCEEDED(hr)); - } - - D3DFormat nDepthStencilFormatTypeless = descDepthStencil.Format; - if (!CTexture::IsDeviceFormatTypeless(nDepthStencilFormatTypeless)) - { - nDepthStencilFormatTypeless = CTexture::ConvertToTypelessFmt(nDepthStencilFormatTypeless); - } - - D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; - ZeroStruct(SRVDesc); - SRVDesc.Format = CTexture::ConvertToShaderResourceFmt(nDepthStencilFormatTypeless); - SRVDesc.ViewDimension = (descDepthStencil.SampleDesc.Count > 1) ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D; - SRVDesc.Texture2D.MipLevels = 1; - hr = rd->GetDevice().CreateShaderResourceView(pDepthStencil, &SRVDesc, &rd->m_pZBufferDepthReadOnlySRV); - assert(SUCCEEDED(hr)); - - if (RenderCapabilities::SupportsStencilTextures()) - { - SRVDesc.Format = CTexture::ConvertToStencilFmt(nDepthStencilFormatTypeless); - hr = rd->GetDevice().CreateShaderResourceView(pDepthStencil, &SRVDesc, &rd->m_pZBufferStencilReadOnlySRV); - assert(SUCCEEDED(hr)); - } - -#if !defined(_RELEASE) -#if defined(WIN32) -#define D3DSYSTEM_CPP_USE_PRIVATEDATA -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_20 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#endif - -#if defined(D3DSYSTEM_CPP_USE_PRIVATEDATA) - if (rd->m_pZTexture) - { - AZStd::string dsvName("$MainDepthStencil"); - rd->m_pZTexture->SetPrivateData(WKPDID_D3DDebugObjectName, dsvName.length(), dsvName.c_str()); - } - - if (rd->m_pZBuffer) - { - AZStd::string srvName("[DSV] $MainDepthStencil"); - rd->m_pZBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, srvName.length(), srvName.c_str()); - } - - if (rd->m_pZBufferReadOnlyDSV) - { - AZStd::string srvName("[DSV] $MainDepthStencil - Read Only"); - rd->m_pZBufferReadOnlyDSV->SetPrivateData(WKPDID_D3DDebugObjectName, srvName.length(), srvName.c_str()); - } - - if (rd->m_pZBufferDepthReadOnlySRV) - { - AZStd::string srvName("[SRV] $MainDepthStencil - Depth Read Only"); - rd->m_pZBufferDepthReadOnlySRV->SetPrivateData(WKPDID_D3DDebugObjectName, srvName.length(), srvName.c_str()); - } - - if (rd->m_pZBufferStencilReadOnlySRV) - { - AZStd::string srvName("[SRV] $MainDepthStencil - Stencil Read Only"); - rd->m_pZBufferStencilReadOnlySRV->SetPrivateData(WKPDID_D3DDebugObjectName, srvName.length(), srvName.c_str()); - } -#endif - - rd->ReleaseAuxiliaryMeshes(); - rd->CreateAuxiliaryMeshes(); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DSYSTEM_CPP_SECTION_21 - #include AZ_RESTRICTED_FILE(D3DSystem_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - D3D11_QUERY_DESC QDesc; - QDesc.Query = D3D11_QUERY_EVENT; - QDesc.MiscFlags = 0; - for (int i = 0; i < 2; ++i) - { - hr = pd3dDevice->CreateQuery(&QDesc, &rd->m_pQuery[i]); - assert(hr == S_OK && rd->m_pQuery[i]); - rd->GetDeviceContext().End(rd->m_pQuery[i]); - } -#endif - rd->EF_Restore(); - - rd->m_bDeviceLost = 0; - rd->m_pLastVDeclaration = NULL; - -#if defined(ENABLE_RENDER_AUX_GEOM) - if (rd->m_pRenderAuxGeomD3D && FAILED(hr = rd->m_pRenderAuxGeomD3D->RestoreDeviceObjects())) - { - return hr; - } -#endif - - CHWShader_D3D::mfSetGlobalParams(); - - if (rd->m_OcclQueries.capacity()) - { - for (int a = 0; a < MAX_OCCL_QUERIES; a++) - { - rd->m_OcclQueries[a].Release(); - } - } - - { - LOADING_TIME_PROFILE_SECTION_NAMED("CD3D9Renderer::OnD3D10PostCreateDevice(): m_OcclQueries"); - rd->m_OcclQueries.Reserve(MAX_OCCL_QUERIES); - // Lazy initialization on Android due to limited number of queries that we can create. - // TODO Linux - This was crashing on Ubuntu, investigate -#if !defined(AZ_PLATFORM_ANDROID) && !defined(AZ_PLATFORM_LINUX) - for (int a = 0; a < MAX_OCCL_QUERIES; a++) - { - rd->m_OcclQueries[a].Create(); - } -#endif - } - - - return S_OK; -} - -#if defined(WIN32) -// Renderer looks for multi-monitor setup changes and fullscreen key combination -bool CD3D9Renderer::HandleMessage([[maybe_unused]] HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, [[maybe_unused]] LRESULT* pResult) -{ - switch (message) - { - case WM_DISPLAYCHANGE: - case WM_DEVICECHANGE: - { - // Count the number of connected display devices - bool bHaveMonitorsChanged = true; - uint connectedMonitors = 0; - EnumDisplayMonitors(NULL, NULL, CountConnectedMonitors, reinterpret_cast(&connectedMonitors)); - - // Check for changes - if (connectedMonitors > m_nConnectedMonitors) - { - iSystem->GetILog()->LogAlways("[Renderer] A display device has been connected to the system"); - } - else if (connectedMonitors < m_nConnectedMonitors) - { - iSystem->GetILog()->LogAlways("[Renderer] A display device has been disconnected from the system"); - } - else - { - bHaveMonitorsChanged = false; - } - - // Update state - m_nConnectedMonitors = connectedMonitors; - m_bDisplayChanged = bHaveMonitorsChanged; - } - break; - - case WM_SYSKEYDOWN: - { - const bool bAlt = (lParam & (1 << 29)) != 0; - if (wParam == VK_RETURN && bAlt) // ALT+ENTER - { - ICVar* pVar = iConsole->GetCVar("r_fullscreen"); - if (pVar) - { - int fullscreen = pVar->GetIVal(); - pVar->Set((int)(fullscreen == 0)); // Toggle CVar - } - } - } - break; - } - return false; -} -#endif // defined(WIN32) - -#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) -static const char* GetScanlineOrderNaming(DXGI_MODE_SCANLINE_ORDER v) -{ - switch (v) - { - case DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE: - return "progressive"; - case DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST: - return "interlaced (upper field first)"; - case DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST: - return "interlaced (lower field first)"; - default: - return "unspecified"; - } -} - -void UserOverrideDisplayProperties(DXGI_MODE_DESC& desc) -{ - if (gRenDev->m_CVFullScreen->GetIVal()) - { - if (gRenDev->CV_r_overrideRefreshRate > 0) - { - DXGI_RATIONAL& refreshRate = desc.RefreshRate; - if (refreshRate.Denominator) - { - gEnv->pLog->Log("Overriding refresh rate to %.2f Hz (was %.2f Hz).", (float)gRenDev->CV_r_overrideRefreshRate, (float)refreshRate.Numerator / (float)refreshRate.Denominator); - } - else - { - gEnv->pLog->Log("Overriding refresh rate to %.2f Hz (was undefined).", (float)gRenDev->CV_r_overrideRefreshRate); - } - refreshRate.Numerator = (unsigned int) (gRenDev->CV_r_overrideRefreshRate * 1000.0f); - refreshRate.Denominator = 1000; - } - - if (gRenDev->CV_r_overrideScanlineOrder > 0) - { - DXGI_MODE_SCANLINE_ORDER old = desc.ScanlineOrdering; - DXGI_MODE_SCANLINE_ORDER& so = desc.ScanlineOrdering; - switch (gRenDev->CV_r_overrideScanlineOrder) - { - case 2: - so = DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST; - break; - case 3: - so = DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST; - break; - default: - so = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; - break; - } - gEnv->pLog->Log("Overriding scanline order to %s (was %s).", GetScanlineOrderNaming(so), GetScanlineOrderNaming(old)); - } - } -} -#endif - - -#include "DeviceInfo.inl" - - -void EnableCloseButton([[maybe_unused]] void* hWnd, [[maybe_unused]] bool enabled) -{ -#if defined(WIN32) || defined(WIN64) - if (hWnd) - { - HMENU hMenu = GetSystemMenu((HWND) hWnd, FALSE); - if (hMenu) - { - const unsigned int flags = enabled ? MF_ENABLED : (MF_DISABLED | MF_GRAYED); - EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | flags); - } - } -#endif -} - -#if defined(SUPPORT_D3D_DEBUG_RUNTIME) -string D3DDebug_GetLastMessage() -{ - return gcpRendD3D->m_d3dDebug.GetLastMessage(); -} -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexture.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexture.cpp deleted file mode 100644 index 2e674b89bc..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexture.cpp +++ /dev/null @@ -1,5253 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Direct3D specific texture manager implementation. - - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "StringUtils.h" -#include -#include "BitFiddling.h" // ConvertBlock3DcToDXT5() -#include "D3DStereo.h" -#include "../Common/PostProcess/PostProcessUtils.h" -#include "D3DPostProcess.h" -#include "../Common/Textures/TextureHelpers.h" -#include "../Common/Textures/TextureManager.h" -#include "../Common/RenderCapabilities.h" -#include -#include - -#undef min -#undef max -//=============================================================================== -namespace { - void SetShaderResourceViewDesc(const SResourceView& rv, uint32 texType, D3DFormat format, int arraySize, uint32 nSliceCount, D3D11_SHADER_RESOURCE_VIEW_DESC& desc) - { - const uint nMipCount = rv.m_Desc.nMipCount == SResourceView().m_Desc.nMipCount ? (uint) - 1 : (uint)rv.m_Desc.nMipCount; - ZeroStruct(desc); - desc.Format = CTexture::ConvertToShaderResourceFmt(format); - if (rv.m_Desc.bSrgbRead) - { - desc.Format = CTexture::ConvertToSRGBFmt(desc.Format); - } - switch (texType) - { - case eTT_1D: - if (arraySize > 1) - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - desc.Texture1DArray.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.Texture1DArray.MipLevels = nMipCount; - desc.Texture1DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - desc.Texture1DArray.ArraySize = nSliceCount; - } - else - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - desc.Texture1D.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.Texture1D.MipLevels = nMipCount; - } - break; - case eTT_2D: - if (arraySize > 1) - { - if (rv.m_Desc.bMultisample) - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - desc.Texture2DMSArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - desc.Texture2DMSArray.ArraySize = nSliceCount; - } - else - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - desc.Texture2DArray.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.Texture2DArray.MipLevels = nMipCount; - desc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - desc.Texture2DArray.ArraySize = nSliceCount; - } - } - else - { - if (rv.m_Desc.bMultisample) - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - } - else - { - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - desc.Texture2D.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.Texture2D.MipLevels = nMipCount; - } - } - break; - case eTT_3D: - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - desc.Texture3D.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.Texture3D.MipLevels = nMipCount; - break; - case eTT_Cube: - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - desc.TextureCube.MostDetailedMip = rv.m_Desc.nMostDetailedMip; - desc.TextureCube.MipLevels = nMipCount; - break; - } - } - - void SetRenderTargetViewDesc(const SResourceView& rv, uint32 texType, D3DFormat format, int arraySize, uint32 nSliceCount, D3D11_RENDER_TARGET_VIEW_DESC& rtvDesc) - { - ZeroStruct(rtvDesc); - rtvDesc.Format = format; - - switch (texType) - { - case eTT_1D: - if (arraySize > 1) - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; - rtvDesc.Texture1DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - rtvDesc.Texture1DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - rtvDesc.Texture1DArray.ArraySize = nSliceCount; - } - else - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - rtvDesc.Texture1D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - break; - case eTT_2D: - if (arraySize > 1) - { - if (rv.m_Desc.bMultisample) - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - rtvDesc.Texture2DMSArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - rtvDesc.Texture2DMSArray.ArraySize = nSliceCount; - } - else - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - rtvDesc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - rtvDesc.Texture2DArray.ArraySize = nSliceCount; - } - } - else - { - if (rv.m_Desc.bMultisample) - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - } - else - { - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - } - break; - case eTT_3D: - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = rv.m_Desc.nMostDetailedMip; - rtvDesc.Texture3D.FirstWSlice = rv.m_Desc.nFirstSlice; - rtvDesc.Texture3D.WSize = nSliceCount; - break; - case eTT_Cube: - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - rtvDesc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - rtvDesc.Texture2DArray.ArraySize = nSliceCount; - break; - } - } - - void SetDepthStencilViewDesc(const SResourceView& rv, uint32 texType, D3DFormat format, int arraySize, uint32 nSliceCount, D3D11_DEPTH_STENCIL_VIEW_DESC& dsvDesc) - { - ZeroStruct(dsvDesc); - dsvDesc.Format = (DXGI_FORMAT)CTexture::ConvertToDepthStencilFmt(format); - - switch (texType) - { - case eTT_1D: - if (arraySize > 1) - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; - dsvDesc.Texture1DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - dsvDesc.Texture1DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - dsvDesc.Texture1DArray.ArraySize = nSliceCount; - } - else - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; - dsvDesc.Texture1D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - break; - case eTT_2D: - if (arraySize > 1) - { - if (rv.m_Desc.bMultisample) - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; - dsvDesc.Texture2DMSArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - dsvDesc.Texture2DMSArray.ArraySize = nSliceCount; - } - else - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Texture2DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - dsvDesc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - dsvDesc.Texture2DArray.ArraySize = nSliceCount; - } - } - else - { - if (rv.m_Desc.bMultisample) - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; - } - else - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - } - break; - case eTT_Cube: - { - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Texture2DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - dsvDesc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - dsvDesc.Texture2DArray.ArraySize = nSliceCount; - } - break; - } - } - - void SetUnorderedAccessViewDesc(const SResourceView& rv, uint32 texType, D3DFormat format, int arraySize, uint32 nSliceCount, D3D11_UNORDERED_ACCESS_VIEW_DESC& desc) - { - ZeroStruct(desc); - desc.Format = format; - - switch (texType) - { - case eTT_1D: - if (arraySize > 1) - { - desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY; - desc.Texture1DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - desc.Texture1DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - desc.Texture1DArray.ArraySize = nSliceCount; - } - else - { - desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D; - desc.Texture1D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - break; - case eTT_2D: - if (arraySize > 1) - { - AZ_Assert(rv.m_Desc.bMultisample == 0, "No MSAA in UAV Array"); - desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; - desc.Texture2DArray.MipSlice = rv.m_Desc.nMostDetailedMip; - desc.Texture2DArray.FirstArraySlice = rv.m_Desc.nFirstSlice; - desc.Texture2DArray.ArraySize = nSliceCount; - } - else - { - AZ_Assert(rv.m_Desc.bMultisample == 0, "No MSAA in UAV"); - desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipSlice = rv.m_Desc.nMostDetailedMip; - } - break; - case eTT_3D: - desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; - desc.Texture3D.MipSlice = rv.m_Desc.nMostDetailedMip; - desc.Texture3D.FirstWSlice = rv.m_Desc.nFirstSlice; - desc.Texture3D.WSize = nSliceCount; - break; - } - } -} - -RenderTargetData::~RenderTargetData() -{ - CDeviceTexture* pTexMSAA = (CDeviceTexture*)m_pDeviceTextureMSAA; - SAFE_RELEASE(pTexMSAA); - - for (size_t i = 0; i < m_ResourceViews.size(); ++i) - { - const SResourceView& rv = m_ResourceViews[i]; - switch (rv.m_Desc.eViewType) - { - case SResourceView::eShaderResourceView: - { - D3DShaderResourceView* pView = static_cast(rv.m_pDeviceResourceView); - SAFE_RELEASE(pView); - break; - } - case SResourceView::eRenderTargetView: - { - D3DSurface* pView = static_cast(rv.m_pDeviceResourceView); - SAFE_RELEASE(pView); - break; - } - case SResourceView::eDepthStencilView: - { - D3DDepthSurface* pView = static_cast(rv.m_pDeviceResourceView); - SAFE_RELEASE(pView); - break; - } - case SResourceView::eUnorderedAccessView: - { - D3DUnorderedAccessView* pView = static_cast(rv.m_pDeviceResourceView); - SAFE_RELEASE(pView); - break; - } - default: - assert(false); - } - } -} -//=============================================================================== - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DTEXTURE_CPP_SECTION_1 1 -#define D3DTEXTURE_CPP_SECTION_2 2 -#define D3DTEXTURE_CPP_SECTION_3 3 -#define D3DTEXTURE_CPP_SECTION_4 4 -#define D3DTEXTURE_CPP_SECTION_5 5 -#define D3DTEXTURE_CPP_SECTION_6 6 -#define D3DTEXTURE_CPP_SECTION_7 7 -#define D3DTEXTURE_CPP_SECTION_8 8 -#define D3DTEXTURE_CPP_SECTION_9 9 -#define D3DTEXTURE_CPP_SECTION_10 10 -#define D3DTEXTURE_CPP_SECTION_11 11 -#define D3DTEXTURE_CPP_SECTION_12 12 -#define D3DTEXTURE_CPP_SECTION_13 13 -#define D3DTEXTURE_CPP_SECTION_14 14 -#endif - -#if defined(TEXTURE_GET_SYSTEM_COPY_SUPPORT) -byte* CTexture::Convert(const byte* sourceData, int nWidth, int nHeight, int sourceMipCount, ETEX_Format eTFSrc, ETEX_Format eTFDst, int& nOutSize, [[maybe_unused]] bool bLinear) -{ - nOutSize = 0; - - DXGI_FORMAT DeviceFormatSRC = (DXGI_FORMAT)DeviceFormatFromTexFormat(eTFSrc); - DXGI_FORMAT DeviceFormatDST = (DXGI_FORMAT)DeviceFormatFromTexFormat(eTFDst); - - if (DeviceFormatSRC == DXGI_FORMAT_UNKNOWN || DeviceFormatDST == DXGI_FORMAT_UNKNOWN || nWidth <= 0 || nHeight <= 0) - { - AZ_Assert(false, "Invalid parameters to CTexture::Convert"); - return nullptr; - } - - if (sourceMipCount <= 0) - { - sourceMipCount = 1; - } - - int outputSize = 0; - byte* outputData = nullptr; - - if (eTFSrc == eTF_BC5U && eTFDst == eTF_BC3) - { - int w = nWidth; - int h = nHeight; - - outputSize = CTexture::TextureDataSize(w, h, 1, sourceMipCount, 1, eTF_BC3); - outputData = new byte[outputSize]; - - int nOffsDST = 0; - int nOffsSRC = 0; - for (int mip = 0; mip < sourceMipCount; mip++) - { - if (w <= 0) - { - w = 1; - } - if (h <= 0) - { - h = 1; - } - - const void* outSrc = &sourceData[nOffsSRC]; - DWORD outSize = CTexture::TextureDataSize(w, h, 1, 1, 1, eTFDst); - - nOffsSRC += CTexture::TextureDataSize(w, h, 1, 1, 1, eTFSrc); - - { - const byte* src = (const byte*)outSrc; - - for (uint32 n = 0; n < outSize / 16; n++) // for each block - { - const uint8* srcDataBlock = &src[n * 16]; - uint8* outputDataBlock = &outputData[nOffsDST + n * 16]; - ConvertBlock3DcToDXT5(outputDataBlock, srcDataBlock); - } - - nOffsDST += outSize; - } - - w >>= 1; - h >>= 1; - } - nOutSize = outputSize; - return outputData; - } - - outputSize = CTexture::TextureDataSize(nWidth, nHeight, 1, sourceMipCount, 1, eTFSrc); - outputData = new byte[outputSize]; - memcpy(outputData, sourceData, outputSize); - nOutSize = outputSize; - return outputData; -} -#endif //#if defined(WIN32) || defined(WIN64) - -D3DSurface* CTexture::GetSurface(int nCMSide, int nLevel) -{ - if (!m_pDevTexture) - { - return NULL; - } - - if (IsDeviceFormatTypeless(m_pPixelFormat->DeviceFormat)) - { - iLog->Log("Error: CTexture::GetSurface: typeless formats can't be specified for RTVs, failed to create surface for the texture %s", GetSourceName()); - return NULL; - } - - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - - HRESULT hr = S_OK; - D3DSurface* pTargSurf = m_pDeviceRTV; - const bool bUseMultisampledRTV = ((m_nFlags & FT_USAGE_MSAA) && m_bUseMultisampledRTV) != 0; - if (bUseMultisampledRTV) - { - pTargSurf = m_pDeviceRTVMS; - } - - if (!pTargSurf) - { - int nMipLevel = 0; - int nSlice = 0; - int nSliceCount = -1; - - if (m_eTT == eTT_Cube) - { - nMipLevel = (m_nFlags & FT_FORCE_MIPS) ? min((int)(m_nMips - 1), nLevel) : 0; - nSlice = nCMSide; - nSliceCount = 1; - } - pTargSurf = (D3DSurface*) CreateDeviceResourceView(SResourceView::RenderTargetView(m_eTFDst, nSlice, nSliceCount, nMipLevel, bUseMultisampledRTV)); - - if (bUseMultisampledRTV) - { - m_pDeviceRTVMS = pTargSurf; - } - else - { - m_pDeviceRTV = pTargSurf; - } - } - assert(hr == S_OK); - - if (FAILED(hr)) - { - pTargSurf = NULL; - } - - return pTargSurf; -} - - -void CTexture::Readback(AZ::u32 subresourceIndex, StagingHook callback) -{ - if (m_pDevTexture) - { - m_pDevTexture->DownloadToStagingResource(subresourceIndex, callback); - } -} - -//=============================================================================== - -bool CTexture::IsDeviceFormatTypeless(D3DFormat nFormat) -{ - switch (nFormat) - { - //128 bits - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32_TYPELESS: - - //64 bits - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - - //32 bits - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - - //16 bits - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R16_TYPELESS: - - //8 bits - case DXGI_FORMAT_R8_TYPELESS: - - //block formats - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC5_TYPELESS: - -#if defined(OPENGL) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ETC2_TYPELESS: - case DXGI_FORMAT_ETC2A_TYPELESS: - case DXGI_FORMAT_EAC_R11_TYPELESS: - case DXGI_FORMAT_EAC_RG11_TYPELESS: -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - case DXGI_FORMAT_BC6H_TYPELESS: -#endif - case DXGI_FORMAT_BC7_TYPELESS: - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_TYPELESS: - case DXGI_FORMAT_PVRTC4_TYPELESS: -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_TYPELESS: - case DXGI_FORMAT_ASTC_5x4_TYPELESS: - case DXGI_FORMAT_ASTC_5x5_TYPELESS: - case DXGI_FORMAT_ASTC_6x5_TYPELESS: - case DXGI_FORMAT_ASTC_6x6_TYPELESS: - case DXGI_FORMAT_ASTC_8x5_TYPELESS: - case DXGI_FORMAT_ASTC_8x6_TYPELESS: - case DXGI_FORMAT_ASTC_8x8_TYPELESS: - case DXGI_FORMAT_ASTC_10x5_TYPELESS: - case DXGI_FORMAT_ASTC_10x6_TYPELESS: - case DXGI_FORMAT_ASTC_10x8_TYPELESS: - case DXGI_FORMAT_ASTC_10x10_TYPELESS: - case DXGI_FORMAT_ASTC_12x10_TYPELESS: - case DXGI_FORMAT_ASTC_12x12_TYPELESS: -#endif - return true; - - default: - break; - } - - return false; -} - -bool CTexture::IsDeviceFormatSRGBReadable(D3DFormat nFormat) -{ - switch (nFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - return true; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return true; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return true; - - case DXGI_FORMAT_BC1_UNORM: - return true; - case DXGI_FORMAT_BC2_UNORM: - return true; - case DXGI_FORMAT_BC3_UNORM: - return true; - case DXGI_FORMAT_BC7_UNORM: - return true; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ETC2_UNORM: - return true; - case DXGI_FORMAT_ETC2A_UNORM: - return true; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_UNORM: - return true; - case DXGI_FORMAT_PVRTC4_UNORM: - return true; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_UNORM: - return true; - case DXGI_FORMAT_ASTC_5x4_UNORM: - return true; - case DXGI_FORMAT_ASTC_5x5_UNORM: - return true; - case DXGI_FORMAT_ASTC_6x5_UNORM: - return true; - case DXGI_FORMAT_ASTC_6x6_UNORM: - return true; - case DXGI_FORMAT_ASTC_8x5_UNORM: - return true; - case DXGI_FORMAT_ASTC_8x6_UNORM: - return true; - case DXGI_FORMAT_ASTC_8x8_UNORM: - return true; - case DXGI_FORMAT_ASTC_10x5_UNORM: - return true; - case DXGI_FORMAT_ASTC_10x6_UNORM: - return true; - case DXGI_FORMAT_ASTC_10x8_UNORM: - return true; - case DXGI_FORMAT_ASTC_10x10_UNORM: - return true; - case DXGI_FORMAT_ASTC_12x10_UNORM: - return true; - case DXGI_FORMAT_ASTC_12x12_UNORM: - return true; -#endif - - default: - break; - } - - return false; -} - -// this function is valid for FT_USAGE_DEPTHSTENCIL textures only -D3DFormat CTexture::DeviceFormatFromTexFormat(ETEX_Format eTF) -{ - switch (eTF) - { - case eTF_R8G8B8A8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case eTF_R8G8B8A8S: - return DXGI_FORMAT_R8G8B8A8_SNORM; - - case eTF_A8: - return DXGI_FORMAT_A8_UNORM; - case eTF_R8: - return DXGI_FORMAT_R8_UNORM; - case eTF_R8S: - return DXGI_FORMAT_R8_SNORM; - case eTF_R16: - return DXGI_FORMAT_R16_UNORM; - case eTF_R16U: - return DXGI_FORMAT_R16_UINT; - case eTF_R16G16U: - return DXGI_FORMAT_R16G16_UINT; - case eTF_R10G10B10A2UI: - return DXGI_FORMAT_R10G10B10A2_UINT; - case eTF_R16F: - return DXGI_FORMAT_R16_FLOAT; - case eTF_R32F: - return DXGI_FORMAT_R32_FLOAT; - case eTF_R8G8: - return DXGI_FORMAT_R8G8_UNORM; - case eTF_R8G8S: - return DXGI_FORMAT_R8G8_SNORM; - case eTF_R16G16: - return DXGI_FORMAT_R16G16_UNORM; - case eTF_R16G16S: - return DXGI_FORMAT_R16G16_SNORM; - case eTF_R16G16F: - return DXGI_FORMAT_R16G16_FLOAT; - case eTF_R11G11B10F: - return DXGI_FORMAT_R11G11B10_FLOAT; - case eTF_R10G10B10A2: - return DXGI_FORMAT_R10G10B10A2_UNORM; - case eTF_R16G16B16A16: - return DXGI_FORMAT_R16G16B16A16_UNORM; - case eTF_R16G16B16A16S: - return DXGI_FORMAT_R16G16B16A16_SNORM; - case eTF_R16G16B16A16F: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case eTF_R32G32B32A32F: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - - case eTF_BC1: - return DXGI_FORMAT_BC1_UNORM; - case eTF_BC2: - return DXGI_FORMAT_BC2_UNORM; - case eTF_BC3: - return DXGI_FORMAT_BC3_UNORM; - case eTF_BC4U: - return DXGI_FORMAT_BC4_UNORM; - case eTF_BC4S: - return DXGI_FORMAT_BC4_SNORM; - case eTF_BC5U: - return DXGI_FORMAT_BC5_UNORM; - case eTF_BC5S: - return DXGI_FORMAT_BC5_SNORM; - case eTF_BC6UH: - return DXGI_FORMAT_BC6H_UF16; - case eTF_BC6SH: - return DXGI_FORMAT_BC6H_SF16; - case eTF_BC7: - return DXGI_FORMAT_BC7_UNORM; - case eTF_R9G9B9E5: - return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - - // hardware depth buffers - case eTF_D16: - return DXGI_FORMAT_D16_UNORM; - case eTF_D24S8: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - case eTF_D32F: - return DXGI_FORMAT_D32_FLOAT; - case eTF_D32FS8: - return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - - // only available as hardware format under DX11.1 with DXGI 1.2 - case eTF_B5G6R5: - return DXGI_FORMAT_B5G6R5_UNORM; - case eTF_B5G5R5: - return DXGI_FORMAT_B5G5R5A1_UNORM; - // case eTF_B4G4R4A4: return DXGI_FORMAT_B4G4R4A4_UNORM; - case eTF_B4G4R4A4: - return DXGI_FORMAT_UNKNOWN; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - // only available as hardware format under OpenGL - case eTF_EAC_R11: - return DXGI_FORMAT_EAC_R11_UNORM; - case eTF_EAC_RG11: - return DXGI_FORMAT_EAC_RG11_UNORM; - case eTF_ETC2: - return DXGI_FORMAT_ETC2_UNORM; - case eTF_ETC2A: - return DXGI_FORMAT_ETC2A_UNORM; -#endif //defined(OPENGL) -#ifdef CRY_USE_METAL - case eTF_PVRTC2: - return DXGI_FORMAT_PVRTC2_UNORM; - case eTF_PVRTC4: - return DXGI_FORMAT_PVRTC4_UNORM; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case eTF_ASTC_4x4: - return DXGI_FORMAT_ASTC_4x4_UNORM; - case eTF_ASTC_5x4: - return DXGI_FORMAT_ASTC_5x4_UNORM; - case eTF_ASTC_5x5: - return DXGI_FORMAT_ASTC_5x5_UNORM; - case eTF_ASTC_6x5: - return DXGI_FORMAT_ASTC_6x5_UNORM; - case eTF_ASTC_6x6: - return DXGI_FORMAT_ASTC_6x6_UNORM; - case eTF_ASTC_8x5: - return DXGI_FORMAT_ASTC_8x5_UNORM; - case eTF_ASTC_8x6: - return DXGI_FORMAT_ASTC_8x6_UNORM; - case eTF_ASTC_8x8: - return DXGI_FORMAT_ASTC_8x8_UNORM; - case eTF_ASTC_10x5: - return DXGI_FORMAT_ASTC_10x5_UNORM; - case eTF_ASTC_10x6: - return DXGI_FORMAT_ASTC_10x6_UNORM; - case eTF_ASTC_10x8: - return DXGI_FORMAT_ASTC_10x8_UNORM; - case eTF_ASTC_10x10: - return DXGI_FORMAT_ASTC_10x10_UNORM; - case eTF_ASTC_12x10: - return DXGI_FORMAT_ASTC_12x10_UNORM; - case eTF_ASTC_12x12: - return DXGI_FORMAT_ASTC_12x12_UNORM; -#endif - - // only available as hardware format under DX9 - case eTF_A8L8: - return DXGI_FORMAT_UNKNOWN; - case eTF_L8: - return DXGI_FORMAT_UNKNOWN; - case eTF_L8V8U8: - return DXGI_FORMAT_UNKNOWN; - case eTF_B8G8R8: - return DXGI_FORMAT_UNKNOWN; - case eTF_L8V8U8X8: - return DXGI_FORMAT_UNKNOWN; - case eTF_B8G8R8X8: - return DXGI_FORMAT_B8G8R8X8_UNORM; - case eTF_B8G8R8A8: - return DXGI_FORMAT_B8G8R8A8_UNORM; - } - - return DXGI_FORMAT_UNKNOWN; -} - -D3DFormat CTexture::GetD3DLinFormat(D3DFormat nFormat) -{ - return nFormat; -} - -D3DFormat CTexture::ConvertToSRGBFmt(D3DFormat fmt) -{ - switch (fmt) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - - case DXGI_FORMAT_BC1_UNORM: - return DXGI_FORMAT_BC1_UNORM_SRGB; - case DXGI_FORMAT_BC2_UNORM: - return DXGI_FORMAT_BC2_UNORM_SRGB; - case DXGI_FORMAT_BC3_UNORM: - return DXGI_FORMAT_BC3_UNORM_SRGB; - case DXGI_FORMAT_BC7_UNORM: - return DXGI_FORMAT_BC7_UNORM_SRGB; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ETC2_UNORM: - return DXGI_FORMAT_ETC2_UNORM_SRGB; - case DXGI_FORMAT_ETC2A_UNORM: - return DXGI_FORMAT_ETC2A_UNORM_SRGB; - case DXGI_FORMAT_EAC_RG11_UNORM: - return DXGI_FORMAT_EAC_RG11_UNORM; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_UNORM: - return DXGI_FORMAT_PVRTC2_UNORM_SRGB; - case DXGI_FORMAT_PVRTC4_UNORM: - return DXGI_FORMAT_PVRTC4_UNORM_SRGB; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_UNORM: - return DXGI_FORMAT_ASTC_4x4_UNORM_SRGB; - case DXGI_FORMAT_ASTC_5x4_UNORM: - return DXGI_FORMAT_ASTC_5x4_UNORM_SRGB; - case DXGI_FORMAT_ASTC_5x5_UNORM: - return DXGI_FORMAT_ASTC_5x5_UNORM_SRGB; - case DXGI_FORMAT_ASTC_6x5_UNORM: - return DXGI_FORMAT_ASTC_6x5_UNORM_SRGB; - case DXGI_FORMAT_ASTC_6x6_UNORM: - return DXGI_FORMAT_ASTC_6x6_UNORM_SRGB; - case DXGI_FORMAT_ASTC_8x5_UNORM: - return DXGI_FORMAT_ASTC_8x5_UNORM_SRGB; - case DXGI_FORMAT_ASTC_8x6_UNORM: - return DXGI_FORMAT_ASTC_8x6_UNORM_SRGB; - case DXGI_FORMAT_ASTC_8x8_UNORM: - return DXGI_FORMAT_ASTC_8x8_UNORM_SRGB; - case DXGI_FORMAT_ASTC_10x5_UNORM: - return DXGI_FORMAT_ASTC_10x5_UNORM_SRGB; - case DXGI_FORMAT_ASTC_10x6_UNORM: - return DXGI_FORMAT_ASTC_10x6_UNORM_SRGB; - case DXGI_FORMAT_ASTC_10x8_UNORM: - return DXGI_FORMAT_ASTC_10x8_UNORM_SRGB; - case DXGI_FORMAT_ASTC_10x10_UNORM: - return DXGI_FORMAT_ASTC_10x10_UNORM_SRGB; - case DXGI_FORMAT_ASTC_12x10_UNORM: - return DXGI_FORMAT_ASTC_12x10_UNORM_SRGB; - case DXGI_FORMAT_ASTC_12x12_UNORM: - return DXGI_FORMAT_ASTC_12x12_UNORM_SRGB; - case DXGI_FORMAT_R8_UNORM: - return DXGI_FORMAT_R8_UNORM; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; -#endif - case DXGI_FORMAT_R10G10B10A2_UNORM: - return DXGI_FORMAT_R10G10B10A2_UNORM; - // AntonK: we don't need sRGB space for fp formats, because there is enough precision - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case DXGI_FORMAT_R11G11B10_FLOAT: - return DXGI_FORMAT_R11G11B10_FLOAT; - // There is no SRGB format for BC4 - case DXGI_FORMAT_BC4_SNORM: - return DXGI_FORMAT_BC4_SNORM; - case DXGI_FORMAT_BC4_UNORM: - return DXGI_FORMAT_BC4_UNORM; - default: - assert(0); - } - - return fmt; -} - -D3DFormat CTexture::ConvertToSignedFmt(D3DFormat fmt) -{ - switch (fmt) - { - case DXGI_FORMAT_R8_UNORM: - return DXGI_FORMAT_R8_SNORM; - case DXGI_FORMAT_R8G8_UNORM: - return DXGI_FORMAT_R8G8_SNORM; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return DXGI_FORMAT_R8G8B8A8_SNORM; - case DXGI_FORMAT_R16_UNORM: - return DXGI_FORMAT_R16_SNORM; - case DXGI_FORMAT_R16G16_UNORM: - return DXGI_FORMAT_R16G16_SNORM; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return DXGI_FORMAT_R16G16B16A16_SNORM; - case DXGI_FORMAT_BC4_UNORM: - return DXGI_FORMAT_BC4_SNORM; - case DXGI_FORMAT_BC5_UNORM: - return DXGI_FORMAT_BC5_SNORM; - case DXGI_FORMAT_BC6H_UF16: - return DXGI_FORMAT_BC6H_SF16; - - case DXGI_FORMAT_R32G32B32A32_UINT: - return DXGI_FORMAT_R32G32B32A32_SINT; - case DXGI_FORMAT_R32G32B32_UINT: - return DXGI_FORMAT_R32G32B32_SINT; - case DXGI_FORMAT_R16G16B16A16_UINT: - return DXGI_FORMAT_R16G16B16A16_SINT; - case DXGI_FORMAT_R32G32_UINT: - return DXGI_FORMAT_R32G32_SINT; - case DXGI_FORMAT_R8G8B8A8_UINT: - return DXGI_FORMAT_R8G8B8A8_SINT; - case DXGI_FORMAT_R16G16_UINT: - return DXGI_FORMAT_R16G16_SINT; - case DXGI_FORMAT_R32_UINT: - return DXGI_FORMAT_R32_SINT; - case DXGI_FORMAT_R8G8_UINT: - return DXGI_FORMAT_R8G8_SINT; - case DXGI_FORMAT_R16_UINT: - return DXGI_FORMAT_R16_SINT; - case DXGI_FORMAT_R8_UINT: - return DXGI_FORMAT_R8_SINT; - - default: - assert(0); - } - - return fmt; -} - -ETEX_Format CTexture::TexFormatFromDeviceFormat(D3DFormat nFormat) -{ - switch (nFormat) - { - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_SNORM: - return eTF_R8G8B8A8S; - - case DXGI_FORMAT_A8_UNORM: - return eTF_A8; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - return eTF_R8; - case DXGI_FORMAT_R8_SNORM: - return eTF_R8S; - case DXGI_FORMAT_R16_UNORM: - return eTF_R16; - case DXGI_FORMAT_R16_UINT: - return eTF_R16U; - case DXGI_FORMAT_R16G16_UINT: - return eTF_R16G16U; - case DXGI_FORMAT_R10G10B10A2_UINT: - return eTF_R10G10B10A2UI; - case DXGI_FORMAT_R16_FLOAT: - return eTF_R16F; - case DXGI_FORMAT_R16_TYPELESS: - return eTF_R16F; - case DXGI_FORMAT_R32_FLOAT: - return eTF_R32F; - case DXGI_FORMAT_R32_TYPELESS: - return eTF_R32F; - case DXGI_FORMAT_R8G8_UNORM: - return eTF_R8G8; - case DXGI_FORMAT_R8G8_SNORM: - return eTF_R8G8S; - case DXGI_FORMAT_R16G16_UNORM: - return eTF_R16G16; - case DXGI_FORMAT_R16G16_SNORM: - return eTF_R16G16S; - case DXGI_FORMAT_R16G16_FLOAT: - return eTF_R16G16F; - case DXGI_FORMAT_R11G11B10_FLOAT: - return eTF_R11G11B10F; - case DXGI_FORMAT_R10G10B10A2_UNORM: - return eTF_R10G10B10A2; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - return eTF_R10G10B10A2; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return eTF_R16G16B16A16; - case DXGI_FORMAT_R16G16B16A16_SNORM: - return eTF_R16G16B16A16S; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return eTF_R16G16B16A16F; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return eTF_R16G16B16A16F; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return eTF_R32G32B32A32F; - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return eTF_R32G32B32A32F; - - case DXGI_FORMAT_BC1_TYPELESS: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return eTF_BC1; - case DXGI_FORMAT_BC2_TYPELESS: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return eTF_BC2; - case DXGI_FORMAT_BC3_TYPELESS: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return eTF_BC3; - case DXGI_FORMAT_BC4_TYPELESS: - return eTF_BC4U; - case DXGI_FORMAT_BC4_UNORM: - return eTF_BC4U; - case DXGI_FORMAT_BC4_SNORM: - return eTF_BC4S; - case DXGI_FORMAT_BC5_TYPELESS: - return eTF_BC5U; - case DXGI_FORMAT_BC5_UNORM: - return eTF_BC5U; - case DXGI_FORMAT_BC5_SNORM: - return eTF_BC5S; - case DXGI_FORMAT_BC6H_UF16: - return eTF_BC6UH; - case DXGI_FORMAT_BC6H_SF16: - return eTF_BC6SH; - case DXGI_FORMAT_BC7_TYPELESS: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return eTF_BC7; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - return eTF_R9G9B9E5; - - // hardware depth buffers - case DXGI_FORMAT_D16_UNORM: - return eTF_D16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return eTF_D24S8; - case DXGI_FORMAT_D32_FLOAT: - return eTF_D32F; - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - return eTF_D32FS8; - - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - return eTF_D24S8; - case DXGI_FORMAT_R24G8_TYPELESS: - return eTF_D24S8; - case DXGI_FORMAT_R32G8X24_TYPELESS: - return eTF_D32FS8; - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - return eTF_D32FS8; - - // only available as hardware format under DX11.1 with DXGI 1.2 - case DXGI_FORMAT_B5G6R5_UNORM: - return eTF_B5G6R5; - case DXGI_FORMAT_B5G5R5A1_UNORM: - return eTF_B5G5R5; - // case DXGI_FORMAT_B4G4R4A4_UNORM: return eTF_B4G4R4A4; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - // only available as hardware format under OpenGL - case DXGI_FORMAT_EAC_R11_UNORM: - case DXGI_FORMAT_EAC_R11_TYPELESS: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_RG11_UNORM: - case DXGI_FORMAT_EAC_RG11_TYPELESS: - return eTF_EAC_RG11; - case DXGI_FORMAT_ETC2_UNORM: - case DXGI_FORMAT_ETC2_UNORM_SRGB: - case DXGI_FORMAT_ETC2_TYPELESS: - return eTF_ETC2; - case DXGI_FORMAT_ETC2A_UNORM: - case DXGI_FORMAT_ETC2A_UNORM_SRGB: - case DXGI_FORMAT_ETC2A_TYPELESS: - return eTF_ETC2A; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_TYPELESS: - case DXGI_FORMAT_PVRTC2_UNORM: - case DXGI_FORMAT_PVRTC2_UNORM_SRGB: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC4_TYPELESS: - case DXGI_FORMAT_PVRTC4_UNORM: - case DXGI_FORMAT_PVRTC4_UNORM_SRGB: - return eTF_PVRTC4; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_TYPELESS: - case DXGI_FORMAT_ASTC_4x4_UNORM: - case DXGI_FORMAT_ASTC_4x4_UNORM_SRGB: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_5x4_TYPELESS: - case DXGI_FORMAT_ASTC_5x4_UNORM: - case DXGI_FORMAT_ASTC_5x4_UNORM_SRGB: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x5_TYPELESS: - case DXGI_FORMAT_ASTC_5x5_UNORM: - case DXGI_FORMAT_ASTC_5x5_UNORM_SRGB: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_6x5_TYPELESS: - case DXGI_FORMAT_ASTC_6x5_UNORM: - case DXGI_FORMAT_ASTC_6x5_UNORM_SRGB: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x6_TYPELESS: - case DXGI_FORMAT_ASTC_6x6_UNORM: - case DXGI_FORMAT_ASTC_6x6_UNORM_SRGB: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_8x5_TYPELESS: - case DXGI_FORMAT_ASTC_8x5_UNORM: - case DXGI_FORMAT_ASTC_8x5_UNORM_SRGB: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x6_TYPELESS: - case DXGI_FORMAT_ASTC_8x6_UNORM: - case DXGI_FORMAT_ASTC_8x6_UNORM_SRGB: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x8_TYPELESS: - case DXGI_FORMAT_ASTC_8x8_UNORM: - case DXGI_FORMAT_ASTC_8x8_UNORM_SRGB: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_10x5_TYPELESS: - case DXGI_FORMAT_ASTC_10x5_UNORM: - case DXGI_FORMAT_ASTC_10x5_UNORM_SRGB: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x6_TYPELESS: - case DXGI_FORMAT_ASTC_10x6_UNORM: - case DXGI_FORMAT_ASTC_10x6_UNORM_SRGB: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x8_TYPELESS: - case DXGI_FORMAT_ASTC_10x8_UNORM: - case DXGI_FORMAT_ASTC_10x8_UNORM_SRGB: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x10_TYPELESS: - case DXGI_FORMAT_ASTC_10x10_UNORM: - case DXGI_FORMAT_ASTC_10x10_UNORM_SRGB: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_12x10_TYPELESS: - case DXGI_FORMAT_ASTC_12x10_UNORM: - case DXGI_FORMAT_ASTC_12x10_UNORM_SRGB: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x12_TYPELESS: - case DXGI_FORMAT_ASTC_12x12_UNORM: - case DXGI_FORMAT_ASTC_12x12_UNORM_SRGB: - return eTF_ASTC_12x12; -#endif - - // only available as hardware format under DX9 - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return eTF_B8G8R8X8; - - default: - assert(0); - } - - return eTF_Unknown; -} - -// this function is valid for FT_USAGE_DEPTHSTENCIL textures only -D3DFormat CTexture::ConvertToDepthStencilFmt(D3DFormat nFormat) -{ - switch (nFormat) - { - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_D16_UNORM; - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_D32_FLOAT; - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - - // Don't assert if they pass in a valid depth format... - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - return nFormat; - - default: - assert(nFormat == DXGI_FORMAT_D16_UNORM || nFormat == DXGI_FORMAT_D24_UNORM_S8_UINT || nFormat == DXGI_FORMAT_D32_FLOAT || nFormat == DXGI_FORMAT_D32_FLOAT_S8X24_UINT); - } - - return nFormat; -} - -D3DFormat CTexture::ConvertToStencilFmt(D3DFormat nFormat) -{ - switch (nFormat) - { - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_X24_TYPELESS_G8_UINT; - - default: - assert(nFormat == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || nFormat == DXGI_FORMAT_X24_TYPELESS_G8_UINT); - } - - return nFormat; -} - -D3DFormat CTexture::ConvertToShaderResourceFmt(D3DFormat nFormat) -{ - //handle special cases - switch (nFormat) - { - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_R16_UNORM; - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_FLOAT; - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - // case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - - default: - break; //pass through - } - - return nFormat; -} - -D3DFormat CTexture::ConvertToTypelessFmt(D3DFormat fmt) -{ - switch (fmt) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; - case DXGI_FORMAT_R8G8B8A8_SNORM: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; - case DXGI_FORMAT_R8G8B8A8_UINT: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; - case DXGI_FORMAT_R8G8B8A8_SINT: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - return DXGI_FORMAT_B8G8R8A8_TYPELESS; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return DXGI_FORMAT_B8G8R8A8_TYPELESS; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return DXGI_FORMAT_B8G8R8X8_TYPELESS; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return DXGI_FORMAT_B8G8R8X8_TYPELESS; - - case DXGI_FORMAT_R8_UNORM: - return DXGI_FORMAT_R8_TYPELESS; - case DXGI_FORMAT_R8_SNORM: - return DXGI_FORMAT_R8_TYPELESS; - case DXGI_FORMAT_R8_UINT: - return DXGI_FORMAT_R8_TYPELESS; - case DXGI_FORMAT_R8_SINT: - return DXGI_FORMAT_R8_TYPELESS; - - case DXGI_FORMAT_R16_UNORM: - return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_R16_SNORM: - return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_R16_FLOAT: - return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_R16_UINT: - return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_R16_SINT: - return DXGI_FORMAT_R16_TYPELESS; - - case DXGI_FORMAT_R32_FLOAT: - return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_R32_UINT: - return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_R32_SINT: - return DXGI_FORMAT_R32_TYPELESS; - - case DXGI_FORMAT_R8G8_UNORM: - return DXGI_FORMAT_R8G8_TYPELESS; - case DXGI_FORMAT_R8G8_SNORM: - return DXGI_FORMAT_R8G8_TYPELESS; - case DXGI_FORMAT_R8G8_UINT: - return DXGI_FORMAT_R8G8_TYPELESS; - case DXGI_FORMAT_R8G8_SINT: - return DXGI_FORMAT_R8G8_TYPELESS; - - case DXGI_FORMAT_R16G16_FLOAT: - return DXGI_FORMAT_R16G16_TYPELESS; - case DXGI_FORMAT_R16G16_UNORM: - return DXGI_FORMAT_R16G16_TYPELESS; - case DXGI_FORMAT_R16G16_SNORM: - return DXGI_FORMAT_R16G16_TYPELESS; - case DXGI_FORMAT_R16G16_UINT: - return DXGI_FORMAT_R16G16_TYPELESS; - case DXGI_FORMAT_R16G16_SINT: - return DXGI_FORMAT_R16G16_TYPELESS; - - case DXGI_FORMAT_R32G32_FLOAT: - return DXGI_FORMAT_R32G32_TYPELESS; - case DXGI_FORMAT_R32G32_UINT: - return DXGI_FORMAT_R32G32_TYPELESS; - case DXGI_FORMAT_R32G32_SINT: - return DXGI_FORMAT_R32G32_TYPELESS; - - case DXGI_FORMAT_R32G32B32_FLOAT: - return DXGI_FORMAT_R32G32B32_TYPELESS; - case DXGI_FORMAT_R32G32B32_UINT: - return DXGI_FORMAT_R32G32B32_TYPELESS; - case DXGI_FORMAT_R32G32B32_SINT: - return DXGI_FORMAT_R32G32B32_TYPELESS; - - case DXGI_FORMAT_R10G10B10A2_UNORM: - return DXGI_FORMAT_R10G10B10A2_TYPELESS; - case DXGI_FORMAT_R10G10B10A2_UINT: - return DXGI_FORMAT_R10G10B10A2_TYPELESS; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; - case DXGI_FORMAT_R16G16B16A16_SNORM: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; - case DXGI_FORMAT_R16G16B16A16_UINT: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; - case DXGI_FORMAT_R16G16B16A16_SINT: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return DXGI_FORMAT_R32G32B32A32_TYPELESS; - case DXGI_FORMAT_R32G32B32A32_UINT: - return DXGI_FORMAT_R32G32B32A32_TYPELESS; - case DXGI_FORMAT_R32G32B32A32_SINT: - return DXGI_FORMAT_R32G32B32A32_TYPELESS; - - case DXGI_FORMAT_BC1_UNORM: - return DXGI_FORMAT_BC1_TYPELESS; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return DXGI_FORMAT_BC1_TYPELESS; - - case DXGI_FORMAT_BC2_UNORM: - return DXGI_FORMAT_BC2_TYPELESS; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return DXGI_FORMAT_BC2_TYPELESS; - - case DXGI_FORMAT_BC3_UNORM: - return DXGI_FORMAT_BC3_TYPELESS; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return DXGI_FORMAT_BC3_TYPELESS; - - case DXGI_FORMAT_BC4_UNORM: - return DXGI_FORMAT_BC4_TYPELESS; - case DXGI_FORMAT_BC4_SNORM: - return DXGI_FORMAT_BC4_TYPELESS; - - case DXGI_FORMAT_BC5_UNORM: - return DXGI_FORMAT_BC5_TYPELESS; - case DXGI_FORMAT_BC5_SNORM: - return DXGI_FORMAT_BC5_TYPELESS; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - case DXGI_FORMAT_BC6H_UF16: - return DXGI_FORMAT_BC6H_TYPELESS; - case DXGI_FORMAT_BC6H_SF16: - return DXGI_FORMAT_BC6H_TYPELESS; -#endif - case DXGI_FORMAT_BC7_UNORM: - return DXGI_FORMAT_BC7_TYPELESS; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return DXGI_FORMAT_BC7_TYPELESS; - -#if defined(OPENGL) && !defined(CRY_USE_METAL) - case DXGI_FORMAT_EAC_R11_UNORM: - return DXGI_FORMAT_EAC_R11_TYPELESS; - case DXGI_FORMAT_EAC_R11_SNORM: - return DXGI_FORMAT_EAC_R11_TYPELESS; - case DXGI_FORMAT_EAC_RG11_UNORM: - return DXGI_FORMAT_EAC_RG11_TYPELESS; - case DXGI_FORMAT_EAC_RG11_SNORM: - return DXGI_FORMAT_EAC_RG11_TYPELESS; - case DXGI_FORMAT_ETC2_UNORM: - return DXGI_FORMAT_ETC2_TYPELESS; - case DXGI_FORMAT_ETC2_UNORM_SRGB: - return DXGI_FORMAT_ETC2_TYPELESS; - case DXGI_FORMAT_ETC2A_UNORM: - return DXGI_FORMAT_ETC2A_TYPELESS; - case DXGI_FORMAT_ETC2A_UNORM_SRGB: - return DXGI_FORMAT_ETC2A_TYPELESS; -#endif //defined(OPENGL) - - case DXGI_FORMAT_D16_UNORM: - return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return DXGI_FORMAT_R24G8_TYPELESS; - case DXGI_FORMAT_D32_FLOAT: - return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - return DXGI_FORMAT_R32G8X24_TYPELESS; - - // todo: add missing formats if they found required - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_UNORM: - case DXGI_FORMAT_PVRTC2_UNORM_SRGB: - return DXGI_FORMAT_PVRTC2_TYPELESS; - - case DXGI_FORMAT_PVRTC4_UNORM: - case DXGI_FORMAT_PVRTC4_UNORM_SRGB: - return DXGI_FORMAT_PVRTC4_TYPELESS; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_UNORM: - case DXGI_FORMAT_ASTC_4x4_UNORM_SRGB: - return DXGI_FORMAT_ASTC_4x4_TYPELESS; - - case DXGI_FORMAT_ASTC_5x4_UNORM: - case DXGI_FORMAT_ASTC_5x4_UNORM_SRGB: - return DXGI_FORMAT_ASTC_5x4_TYPELESS; - - case DXGI_FORMAT_ASTC_5x5_UNORM: - case DXGI_FORMAT_ASTC_5x5_UNORM_SRGB: - return DXGI_FORMAT_ASTC_5x5_TYPELESS; - - case DXGI_FORMAT_ASTC_6x5_UNORM: - case DXGI_FORMAT_ASTC_6x5_UNORM_SRGB: - return DXGI_FORMAT_ASTC_6x5_TYPELESS; - - case DXGI_FORMAT_ASTC_6x6_UNORM: - case DXGI_FORMAT_ASTC_6x6_UNORM_SRGB: - return DXGI_FORMAT_ASTC_6x6_TYPELESS; - - case DXGI_FORMAT_ASTC_8x5_UNORM: - case DXGI_FORMAT_ASTC_8x5_UNORM_SRGB: - return DXGI_FORMAT_ASTC_8x5_TYPELESS; - - case DXGI_FORMAT_ASTC_8x6_UNORM: - case DXGI_FORMAT_ASTC_8x6_UNORM_SRGB: - return DXGI_FORMAT_ASTC_8x6_TYPELESS; - - case DXGI_FORMAT_ASTC_8x8_UNORM: - case DXGI_FORMAT_ASTC_8x8_UNORM_SRGB: - return DXGI_FORMAT_ASTC_8x8_TYPELESS; - - case DXGI_FORMAT_ASTC_10x5_UNORM: - case DXGI_FORMAT_ASTC_10x5_UNORM_SRGB: - return DXGI_FORMAT_ASTC_10x5_TYPELESS; - - case DXGI_FORMAT_ASTC_10x6_UNORM: - case DXGI_FORMAT_ASTC_10x6_UNORM_SRGB: - return DXGI_FORMAT_ASTC_10x6_TYPELESS; - - case DXGI_FORMAT_ASTC_10x8_UNORM: - case DXGI_FORMAT_ASTC_10x8_UNORM_SRGB: - return DXGI_FORMAT_ASTC_10x8_TYPELESS; - - case DXGI_FORMAT_ASTC_10x10_UNORM: - case DXGI_FORMAT_ASTC_10x10_UNORM_SRGB: - return DXGI_FORMAT_ASTC_10x10_TYPELESS; - - case DXGI_FORMAT_ASTC_12x10_UNORM: - case DXGI_FORMAT_ASTC_12x10_UNORM_SRGB: - return DXGI_FORMAT_ASTC_12x10_TYPELESS; - - case DXGI_FORMAT_ASTC_12x12_UNORM: - case DXGI_FORMAT_ASTC_12x12_UNORM_SRGB: - return DXGI_FORMAT_ASTC_12x12_TYPELESS; - -#endif - - // No conversion on floating point format. - case DXGI_FORMAT_R11G11B10_FLOAT: - return DXGI_FORMAT_R11G11B10_FLOAT; - - default: - assert(0); - } - - return fmt; -} - -bool CTexture::IsFormatSupported(ETEX_Format eTFDst) -{ - const SPixFormatSupport* rd = &gcpRendD3D->m_hwTexFormatSupport; - - int D3DFmt = DeviceFormatFromTexFormat(eTFDst); - if (!D3DFmt) - { - return false; - } - SPixFormat* pFmt; - for (pFmt = rd->m_FirstPixelFormat; pFmt; pFmt = pFmt->Next) - { - if (pFmt->DeviceFormat == D3DFmt && pFmt->IsValid()) - { - return true; - } - } - return false; -} - -ETEX_Format CTexture::ClosestFormatSupported(ETEX_Format eTFDst) -{ - return ClosestFormatSupported(eTFDst, m_pPixelFormat); -} - -ETEX_Format CTexture::ClosestFormatSupported(ETEX_Format eTFDst, const SPixFormat*& pPF) -{ - const SPixFormatSupport* rd = &gcpRendD3D->m_hwTexFormatSupport; - - switch (eTFDst) - { - case eTF_R8G8B8A8S: - if (rd->m_FormatR8G8B8A8S.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8S; - return eTF_R8G8B8A8S; - } - return eTF_Unknown; - case eTF_R8G8B8A8: - if (rd->m_FormatR8G8B8A8.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8; - return eTF_R8G8B8A8; - } - return eTF_Unknown; - - case eTF_B5G5R5: - if (rd->m_FormatB5G5R5.IsValid()) - { - pPF = &rd->m_FormatB5G5R5; - return eTF_B5G5R5; - } - case eTF_B5G6R5: - if (rd->m_FormatB5G6R5.IsValid()) - { - pPF = &rd->m_FormatB5G6R5; - return eTF_B5G6R5; - } - - case eTF_B8G8R8X8: - if (rd->m_FormatB8G8R8X8.IsValid()) - { - pPF = &rd->m_FormatB8G8R8X8; - return eTF_B8G8R8X8; - } - return eTF_Unknown; - case eTF_B4G4R4A4: - if (rd->m_FormatB4G4R4A4.IsValid()) - { - pPF = &rd->m_FormatB4G4R4A4; - return eTF_B4G4R4A4; - } - case eTF_B8G8R8A8: - if (rd->m_FormatB8G8R8A8.IsValid()) - { - pPF = &rd->m_FormatB8G8R8A8; - return eTF_B8G8R8A8; - } - return eTF_Unknown; - - case eTF_A8: - if (rd->m_FormatA8.IsValid()) - { - pPF = &rd->m_FormatA8; - return eTF_A8; - } - return eTF_Unknown; - - - case eTF_R8: - if (rd->m_FormatR8.IsValid()) - { - pPF = &rd->m_FormatR8; - return eTF_R8; - } - return eTF_Unknown; - - case eTF_R8S: - if (rd->m_FormatR8S.IsValid()) - { - pPF = &rd->m_FormatR8S; - return eTF_R8S; - } - return eTF_Unknown; - - case eTF_R16: - if (rd->m_FormatR16.IsValid()) - { - pPF = &rd->m_FormatR16; - return eTF_R16; - } - if (rd->m_FormatR16G16.IsValid()) - { - pPF = &rd->m_FormatR16G16; - return eTF_R16G16; - } - return eTF_Unknown; - - case eTF_R16U: - if (rd->m_FormatR16U.IsValid()) - { - pPF = &rd->m_FormatR16U; - return eTF_R16U; - } - return eTF_Unknown; - - case eTF_R16G16U: - if (rd->m_FormatR16G16U.IsValid()) - { - pPF = &rd->m_FormatR16G16U; - return eTF_R16G16U; - } - return eTF_Unknown; - - case eTF_R10G10B10A2UI: - if (rd->m_FormatR10G10B10A2UI.IsValid()) - { - pPF = &rd->m_FormatR10G10B10A2UI; - return eTF_R10G10B10A2UI; - } - return eTF_Unknown; - - case eTF_R16F: - if (rd->m_FormatR16F.IsValid()) - { - pPF = &rd->m_FormatR16F; - return eTF_R16F; - } - if (rd->m_FormatR16G16F.IsValid()) - { - pPF = &rd->m_FormatR16G16F; - return eTF_R16G16F; - } - return eTF_Unknown; - - case eTF_R32F: - if (rd->m_FormatR32F.IsValid()) - { - pPF = &rd->m_FormatR32F; - return eTF_R32F; - } - if (rd->m_FormatR16G16F.IsValid()) - { - pPF = &rd->m_FormatR16G16F; - return eTF_R16G16F; - } - return eTF_Unknown; - - case eTF_R8G8: - if (rd->m_FormatR8G8.IsValid()) - { - pPF = &rd->m_FormatR8G8; - return eTF_R8G8; - } - return eTF_Unknown; - - case eTF_R8G8S: - if (rd->m_FormatR8G8S.IsValid()) - { - pPF = &rd->m_FormatR8G8S; - return eTF_R8G8S; - } - return eTF_Unknown; - - case eTF_R16G16: - if (rd->m_FormatR16G16.IsValid()) - { - pPF = &rd->m_FormatR16G16; - return eTF_R16G16; - } - return eTF_Unknown; - - case eTF_R16G16S: - if (rd->m_FormatR16G16S.IsValid()) - { - pPF = &rd->m_FormatR16G16S; - return eTF_R16G16S; - } - return eTF_Unknown; - - case eTF_R16G16F: - if (rd->m_FormatR16G16F.IsValid()) - { - pPF = &rd->m_FormatR16G16F; - return eTF_R16G16F; - } - return eTF_Unknown; - - case eTF_R11G11B10F: - if (rd->m_FormatR11G11B10F.IsValid()) - { - pPF = &rd->m_FormatR11G11B10F; - return eTF_R11G11B10F; - } - return eTF_Unknown; - - case eTF_R10G10B10A2: - if (rd->m_FormatR10G10B10A2.IsValid()) - { - pPF = &rd->m_FormatR10G10B10A2; - return eTF_R10G10B10A2; - } - return eTF_Unknown; - - case eTF_R16G16B16A16: - if (rd->m_FormatR16G16B16A16.IsValid()) - { - pPF = &rd->m_FormatR16G16B16A16; - return eTF_R16G16B16A16; - } - return eTF_Unknown; - - case eTF_R16G16B16A16S: - if (rd->m_FormatR16G16B16A16S.IsValid()) - { - pPF = &rd->m_FormatR16G16B16A16S; - return eTF_R16G16B16A16S; - } - return eTF_Unknown; - - case eTF_R16G16B16A16F: - if (rd->m_FormatR16G16B16A16F.IsValid()) - { - pPF = &rd->m_FormatR16G16B16A16F; - return eTF_R16G16B16A16F; - } - return eTF_Unknown; - - case eTF_R32G32B32A32F: - if (rd->m_FormatR32G32B32A32F.IsValid()) - { - pPF = &rd->m_FormatR32G32B32A32F; - return eTF_R32G32B32A32F; - } - return eTF_Unknown; - - case eTF_BC1: - if (rd->m_FormatBC1.IsValid()) - { - pPF = &rd->m_FormatBC1; - return eTF_BC1; - } - if (rd->m_FormatR8G8B8A8.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8; - return eTF_R8G8B8A8; - } - return eTF_Unknown; - - case eTF_BC2: - if (rd->m_FormatBC2.IsValid()) - { - pPF = &rd->m_FormatBC2; - return eTF_BC2; - } - if (rd->m_FormatR8G8B8A8.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8; - return eTF_R8G8B8A8; - } - return eTF_Unknown; - - case eTF_BC3: - if (rd->m_FormatBC3.IsValid()) - { - pPF = &rd->m_FormatBC3; - return eTF_BC3; - } - if (rd->m_FormatR8G8B8A8.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8; - return eTF_R8G8B8A8; - } - return eTF_Unknown; - - case eTF_BC4U: - if (rd->m_FormatBC4U.IsValid()) - { - pPF = &rd->m_FormatBC4U; - return eTF_BC4U; - } - if (rd->m_FormatR8.IsValid()) - { - pPF = &rd->m_FormatR8; - return eTF_R8; - } - return eTF_Unknown; - - case eTF_BC4S: - if (rd->m_FormatBC4S.IsValid()) - { - pPF = &rd->m_FormatBC4S; - return eTF_BC4S; - } - if (rd->m_FormatR8S.IsValid()) - { - pPF = &rd->m_FormatR8S; - return eTF_R8S; - } - return eTF_Unknown; - - case eTF_BC5U: - if (rd->m_FormatBC5U.IsValid()) - { - pPF = &rd->m_FormatBC5U; - return eTF_BC5U; - } - if (rd->m_FormatR8G8.IsValid()) - { - pPF = &rd->m_FormatR8G8; - return eTF_R8G8; - } - return eTF_Unknown; - - case eTF_BC5S: - if (rd->m_FormatBC5S.IsValid()) - { - pPF = &rd->m_FormatBC5S; - return eTF_BC5S; - } - if (rd->m_FormatR8G8S.IsValid()) - { - pPF = &rd->m_FormatR8G8S; - return eTF_R8G8S; - } - return eTF_Unknown; - - case eTF_BC6UH: - if (rd->m_FormatBC6UH.IsValid()) - { - pPF = &rd->m_FormatBC6UH; - return eTF_BC6UH; - } - if (rd->m_FormatR16F.IsValid()) - { - pPF = &rd->m_FormatR16F; - return eTF_R16F; - } - return eTF_Unknown; - - case eTF_BC6SH: - if (rd->m_FormatBC6SH.IsValid()) - { - pPF = &rd->m_FormatBC6SH; - return eTF_BC6SH; - } - if (rd->m_FormatR16F.IsValid()) - { - pPF = &rd->m_FormatR16F; - return eTF_R16F; - } - return eTF_Unknown; - - case eTF_BC7: - if (rd->m_FormatBC7.IsValid()) - { - pPF = &rd->m_FormatBC7; - return eTF_BC7; - } - if (rd->m_FormatR8G8B8A8.IsValid()) - { - pPF = &rd->m_FormatR8G8B8A8; - return eTF_R8G8B8A8; - } - return eTF_Unknown; - - case eTF_R9G9B9E5: - if (rd->m_FormatR9G9B9E5.IsValid()) - { - pPF = &rd->m_FormatR9G9B9E5; - return eTF_R9G9B9E5; - } - if (rd->m_FormatR16G16B16A16F.IsValid()) - { - pPF = &rd->m_FormatR16G16B16A16F; - return eTF_R16G16B16A16F; - } - return eTF_Unknown; - - case eTF_D16: - if (rd->m_FormatD16.IsValid()) - { - pPF = &rd->m_FormatD16; - return eTF_D16; - } - case eTF_D24S8: - if (rd->m_FormatD24S8.IsValid()) - { - pPF = &rd->m_FormatD24S8; - return eTF_D24S8; - } - case eTF_D32F: - if (rd->m_FormatD32F.IsValid()) - { - pPF = &rd->m_FormatD32F; - return eTF_D32F; - } - case eTF_D32FS8: - if (rd->m_FormatD32FS8.IsValid()) - { - pPF = &rd->m_FormatD32FS8; - return eTF_D32FS8; - } - return eTF_Unknown; - - case eTF_EAC_R11: - if (rd->m_FormatEAC_R11.IsValid()) - { - pPF = &rd->m_FormatEAC_R11; - return eTF_EAC_R11; - } - return eTF_Unknown; - - case eTF_EAC_RG11: - if (rd->m_FormatEAC_RG11.IsValid()) - { - pPF = &rd->m_FormatEAC_RG11; - return eTF_EAC_RG11; - } - return eTF_Unknown; - - case eTF_ETC2: - if (rd->m_FormatETC2.IsValid()) - { - pPF = &rd->m_FormatETC2; - return eTF_ETC2; - } - return eTF_Unknown; - - case eTF_ETC2A: - if (rd->m_FormatETC2A.IsValid()) - { - pPF = &rd->m_FormatETC2A; - return eTF_ETC2A; - } - return eTF_Unknown; - -#ifdef CRY_USE_METAL - case eTF_PVRTC2: - if (rd->m_FormatPVRTC2.IsValid()) - { - pPF = &rd->m_FormatPVRTC2; - return eTF_PVRTC2; - } - return eTF_Unknown; - - case eTF_PVRTC4: - if (rd->m_FormatPVRTC4.IsValid()) - { - pPF = &rd->m_FormatPVRTC4; - return eTF_PVRTC4; - } - return eTF_Unknown; -#endif -#if defined(ANDROID) || defined(CRY_USE_METAL) - case eTF_ASTC_4x4: - if (rd->m_FormatASTC_4x4.IsValid()) - { - pPF = &rd->m_FormatASTC_4x4; - return eTF_ASTC_4x4; - } - return eTF_Unknown; - - case eTF_ASTC_5x4: - if (rd->m_FormatASTC_5x4.IsValid()) - { - pPF = &rd->m_FormatASTC_5x4; - return eTF_ASTC_5x4; - } - return eTF_Unknown; - - case eTF_ASTC_5x5: - if (rd->m_FormatASTC_5x5.IsValid()) - { - pPF = &rd->m_FormatASTC_5x5; - return eTF_ASTC_5x5; - } - return eTF_Unknown; - - case eTF_ASTC_6x5: - if (rd->m_FormatASTC_6x5.IsValid()) - { - pPF = &rd->m_FormatASTC_6x5; - return eTF_ASTC_6x5; - } - return eTF_Unknown; - - case eTF_ASTC_6x6: - if (rd->m_FormatASTC_6x6.IsValid()) - { - pPF = &rd->m_FormatASTC_6x6; - return eTF_ASTC_6x6; - } - return eTF_Unknown; - - case eTF_ASTC_8x5: - if (rd->m_FormatASTC_8x5.IsValid()) - { - pPF = &rd->m_FormatASTC_8x5; - return eTF_ASTC_8x5; - } - return eTF_Unknown; - - case eTF_ASTC_8x6: - if (rd->m_FormatASTC_8x6.IsValid()) - { - pPF = &rd->m_FormatASTC_8x6; - return eTF_ASTC_8x6; - } - return eTF_Unknown; - - case eTF_ASTC_8x8: - if (rd->m_FormatASTC_8x8.IsValid()) - { - pPF = &rd->m_FormatASTC_8x8; - return eTF_ASTC_8x8; - } - return eTF_Unknown; - - case eTF_ASTC_10x5: - if (rd->m_FormatASTC_10x5.IsValid()) - { - pPF = &rd->m_FormatASTC_10x5; - return eTF_ASTC_10x5; - } - return eTF_Unknown; - - case eTF_ASTC_10x6: - if (rd->m_FormatASTC_10x6.IsValid()) - { - pPF = &rd->m_FormatASTC_10x6; - return eTF_ASTC_10x6; - } - return eTF_Unknown; - - case eTF_ASTC_10x8: - if (rd->m_FormatASTC_10x8.IsValid()) - { - pPF = &rd->m_FormatASTC_10x8; - return eTF_ASTC_10x8; - } - return eTF_Unknown; - - case eTF_ASTC_10x10: - if (rd->m_FormatASTC_10x10.IsValid()) - { - pPF = &rd->m_FormatASTC_10x10; - return eTF_ASTC_10x10; - } - return eTF_Unknown; - - case eTF_ASTC_12x10: - if (rd->m_FormatASTC_12x10.IsValid()) - { - pPF = &rd->m_FormatASTC_12x10; - return eTF_ASTC_12x10; - } - return eTF_Unknown; - - case eTF_ASTC_12x12: - if (rd->m_FormatASTC_12x12.IsValid()) - { - pPF = &rd->m_FormatASTC_12x12; - return eTF_ASTC_12x12; - } - return eTF_Unknown; -#endif - - default: - assert(0); - } - return eTF_Unknown; -} - -//=============================================================================== - -bool CTexture::CreateRenderTarget(ETEX_Format eTF, const ColorF& cClear) -{ - if (eTF == eTF_Unknown) - { - eTF = m_eTFDst; - } - if (eTF == eTF_Unknown) - { - return false; - } - const byte* pData[6] = { NULL }; - - ETEX_Format eTFDst = ClosestFormatSupported(eTF); - if (eTF != eTFDst) - { - return false; - } - m_eTFDst = eTF; - m_nFlags |= FT_USAGE_RENDERTARGET; - m_cClearColor = cClear; - bool bRes = CreateDeviceTexture(pData); - PostCreate(); - - // Assign name to RT for enhanced debugging -#if !defined(_RELEASE) -#if defined(WIN32) -#define D3DTEXTURE_CPP_USE_PRIVATEDATA -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif -#endif - -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (bRes) - { - m_pDevTexture->GetBaseTexture()->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(m_SrcName.c_str()), m_SrcName.c_str()); - } -#endif - - return bRes; -} - -// Resolve anti-aliased RT to the texture -bool CTexture::Resolve([[maybe_unused]] int nTarget, [[maybe_unused]] bool bUseViewportSize) -{ - if (m_bResolved) - { - return true; - } - - m_bResolved = true; - if (!(m_nFlags & FT_USAGE_MSAA)) - { - return true; - } - - assert ((m_nFlags & FT_USAGE_RENDERTARGET) && (m_nFlags & FT_USAGE_MSAA) && m_pDeviceShaderResource && m_pDevTexture && m_pRenderTargetData->m_pDeviceTextureMSAA); - CDeviceTexture* pDestSurf = GetDevTexture(); - CDeviceTexture* pSrcSurf = GetDevTextureMSAA(); - - assert(pSrcSurf != NULL); - assert(pDestSurf != NULL); - - gcpRendD3D->GetDeviceContext().ResolveSubresource(pDestSurf->Get2DTexture(), 0, pSrcSurf->Get2DTexture(), 0, (DXGI_FORMAT)m_pPixelFormat->DeviceFormat); - return true; -} - -bool CTexture::CreateDeviceTexture(const byte* pData[6]) -{ - if (!m_pPixelFormat) - { -#if !defined(NDEBUG) - ETEX_Format eTF = -#endif - ClosestFormatSupported(m_eTFDst); - assert(eTF != eTF_Unknown); - assert(eTF == m_eTFDst); - } - assert(m_pPixelFormat); - if (!m_pPixelFormat) - { - return false; - } - - if (gRenDev->m_pRT->RC_CreateDeviceTexture(this, pData)) - { - // Assign name to Texture for enhanced debugging -#if !defined(RELEASE) -#if defined (WIN64) - m_pDevTexture->GetBaseTexture()->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(m_SrcName.c_str()), m_SrcName.c_str()); -#elif defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif -#endif - - return true; - } - - return false; -} - -void CTexture::Unbind() -{ - if (m_pDeviceShaderResource) - { - gcpRendD3D->m_DevMan.UnbindSRV(m_pDeviceShaderResource); - } - - CDeviceTexture* pDevTex = m_pDevTexture; - - if (pDevTex) - { - pDevTex->Unbind(); - } -} - -bool CTexture::RT_CreateDeviceTexture(const byte* pData[6]) -{ - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - AZ_ASSET_ATTACH_TO_SCOPE(this); - - HRESULT hr; - - int32 nESRAMOffset = -1; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - //if we have any device owned resources allocated, we must sync with render thread - if (m_pDevTexture) - { - ReleaseDeviceTexture(false); - } - else - { - SAFE_DELETE(m_pRenderTargetData); - } - - CD3D9Renderer* r = gcpRendD3D; - int nWdt = m_nWidth; - int nHgt = m_nHeight; - int nDepth = m_nDepth; - int nMips = m_nMips; - AZ_Assert(nWdt > 0 && nHgt > 0 && nMips > 0, "Attempting to create a device texture '%s' with height:%d, width:%d, and mip levels:%d. All three must be > 0", GetSourceName(), nHgt, nWdt, nMips); - - #ifdef CRY_USE_METAL - bool isMetalCompressedTextureFormat = GetBlockDim(m_eTFSrc) != Vec2i(1); - #else - bool isMetalCompressedTextureFormat = false; - #endif - - bool allowReinterpretingColorSpace = !isMetalCompressedTextureFormat && RenderCapabilities::SupportsTextureViews(); - - byte* pTemp = NULL; - - CDeviceManager* pDevMan = &r->m_DevMan; - - bool resetSRGB = true; - - if (m_nFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_UNORDERED_ACCESS)) - { - m_pRenderTargetData = new RenderTargetData(); - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) - #endif - } - - uint32 nArraySize = m_nArraySize; - - if (m_eTT == eTT_2D) - { - STextureInfo TI; - D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat; - - //nMips = 1; - DXGI_FORMAT nFormatOrig = D3DFmt; - - resetSRGB = false; - - m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0; - - if (m_bIsSRGB) - { - D3DFmt = ConvertToSRGBFmt(D3DFmt); - } - - // must use typeless format to allow runtime casting - if (m_nFlags & FT_USAGE_ALLOWREADSRGB && allowReinterpretingColorSpace) - { - D3DFmt = ConvertToTypelessFmt(D3DFmt); - } - - uint32 nUsage = 0; - if (m_nFlags & FT_USAGE_DEPTHSTENCIL) - { - nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL; - } - if (m_nFlags & FT_USAGE_RENDERTARGET) - { - nUsage |= CDeviceManager::USAGE_RENDER_TARGET; - } - - #if defined(AZ_PLATFORM_IOS) - if (m_nFlags & FT_USAGE_MEMORYLESS) - { - nUsage |= CDeviceManager::USAGE_MEMORYLESS; - } - #endif - - if (m_nFlags & FT_USAGE_DYNAMIC) - { - nUsage |= CDeviceManager::USAGE_DYNAMIC; - } - if (m_nFlags & FT_STAGE_READBACK) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_READ; - } - if (m_nFlags & FT_STAGE_UPLOAD) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_WRITE; - } - if (m_nFlags & FT_USAGE_UNORDERED_ACCESS -#if defined(SUPPORT_DEVICE_INFO) - && r->DevInfo().FeatureLevel() >= D3D_FEATURE_LEVEL_11_0 -#endif //defined(SUPPORT_DEVICE_INFO) - ) - { - nUsage |= CDeviceManager::USAGE_UNORDERED_ACCESS; - } - if ((m_nFlags & (FT_DONT_RELEASE | FT_DONT_STREAM)) == (FT_DONT_RELEASE | FT_DONT_STREAM)) - { - nUsage |= CDeviceManager::USAGE_ETERNAL; - } - if (m_nFlags & FT_USAGE_UAV_RWTEXTURE) - { - nUsage |= CDeviceManager::USAGE_UAV_RWTEXTURE; - } - - if (m_nFlags & FT_FORCE_MIPS) - { - nUsage |= CDeviceManager::USAGE_AUTOGENMIPS; - if (nMips <= 1) - { - m_nMips = nMips = max(1, CTexture::CalcNumMips(nWdt, nHgt) - 2); - } - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_14 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - if (m_nFlags & FT_USAGE_MSAA) - { - m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type; - m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality; - - TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples; - TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality; - hr = pDevMan->Create2DTexture(m_SrcName, nWdt, nHgt, nMips, nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI); - - AZ_Assert(SUCCEEDED(hr), "Call to Create2DTexture failed for '%s'.", GetSourceName()); - m_bResolved = false; - - TI.m_nMSAASamples = 1; - TI.m_nMSAAQuality = 0; - } - - if (pData[0]) - { - { - STextureInfoData InitData[20]; - int w = nWdt; - int h = nHgt; - int nOffset = 0; - const byte* src = pData[0]; - for (int i = 0; i < nMips; i++) - { - if (!w && !h) - { - break; - } - if (!w) - { - w = 1; - } - if (!h) - { - h = 1; - } - - int nSize = TextureDataSize(w, h, 1, 1, 1, m_eTFSrc, m_eSrcTileMode); - InitData[i].pSysMem = &src[nOffset]; - if (m_eSrcTileMode == eTM_None) - { - const Vec2i BlockDim = GetBlockDim(m_eTFSrc); - if (BlockDim == Vec2i(1)) - { - InitData[i].SysMemPitch = TextureDataSize(w, 1, 1, 1, 1, m_eTFSrc, eTM_None); - } - else - { - int blockSize = CImageExtensionHelper::BytesPerBlock(m_eTFSrc); - InitData[i].SysMemPitch = (w + BlockDim.x - 1) / BlockDim.x * blockSize; - } - - //ignored - InitData[i].SysMemSlicePitch = nSize; - InitData[i].SysMemTileMode = eTM_None; - } - else - { - InitData[i].SysMemPitch = 0; - InitData[i].SysMemSlicePitch = 0; - InitData[i].SysMemTileMode = m_eSrcTileMode; - } - - w >>= 1; - h >>= 1; - nOffset += nSize; - } - - TI.m_pData = InitData; - - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->Create2DTexture(m_SrcName, nWdt, nHgt, nMips, nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - } - else // no texture data so just make an empty texture - { - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) - #endif - - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->Create2DTexture(m_SrcName, nWdt, nHgt, nMips, nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI, false, nESRAMOffset); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - - if (FAILED(hr)) - { - AZ_Assert(0, "Call to Create2DTexture failed for '%s'.", GetSourceName()); - return false; - } - - // Restore format - if (m_nFlags & FT_USAGE_ALLOWREADSRGB) - { - D3DFmt = nFormatOrig; - } - - ////////////////////////////////////////////////////////////////////////// - m_pDeviceShaderResource = static_cast (CreateDeviceResourceView(SResourceView::ShaderResourceView(m_eTFDst, 0, -1, 0, nMips, m_bIsSRGB, false))); - - m_nMinMipVidActive = 0; - - if (m_nFlags & FT_USAGE_ALLOWREADSRGB && allowReinterpretingColorSpace) - { - m_pDeviceShaderResourceSRGB = static_cast (CreateDeviceResourceView(SResourceView::ShaderResourceView(m_eTFDst, 0, -1, 0, nMips, true, false))); - } - } - else if (m_eTT == eTT_Cube) - { - STextureInfo TI; - D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat; - uint32 nUsage = 0; - if (m_nFlags & FT_USAGE_DEPTHSTENCIL) - { - nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL; - } - if (m_nFlags & FT_USAGE_RENDERTARGET) - { - nUsage |= CDeviceManager::USAGE_RENDER_TARGET; - } - -#if defined(AZ_PLATFORM_IOS) - if (m_nFlags & FT_USAGE_MEMORYLESS) - { - nUsage |= CDeviceManager::USAGE_MEMORYLESS; - } -#endif - - if (m_nFlags & FT_USAGE_DYNAMIC) - { - nUsage |= CDeviceManager::USAGE_DYNAMIC; - } - if (m_nFlags & FT_STAGE_READBACK) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_READ; - } - if (m_nFlags & FT_STAGE_UPLOAD) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_WRITE; - } - if ((m_nFlags & (FT_DONT_RELEASE | FT_DONT_STREAM)) == (FT_DONT_RELEASE | FT_DONT_STREAM)) - { - nUsage |= CDeviceManager::USAGE_ETERNAL; - } - - if (m_nFlags & FT_FORCE_MIPS) - { - nUsage |= CDeviceManager::USAGE_AUTOGENMIPS; - if (nMips <= 1) - { - m_nMips = nMips = max(1, CTexture::CalcNumMips(nWdt, nHgt) - 2); - } - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_14 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - if (m_nFlags & FT_USAGE_MSAA) - { - m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type; - m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality; - - TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples; - TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality; - hr = pDevMan->CreateCubeTexture(m_SrcName, nWdt, nMips, m_nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI); - - AZ_Assert(SUCCEEDED(hr), "Call to CreateCubeTexuture failed for '%s'.", GetSourceName()); - m_bResolved = false; - - TI.m_nMSAASamples = 1; - TI.m_nMSAAQuality = 0; - } - DXGI_FORMAT nFormatOrig = D3DFmt; - DXGI_FORMAT nFormatSRGB = D3DFmt; - - resetSRGB = false; - - { - m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0; - - if ((m_bIsSRGB || m_nFlags & FT_USAGE_ALLOWREADSRGB)) - { - nFormatSRGB = ConvertToSRGBFmt(D3DFmt); - } - - if (m_bIsSRGB) - { - D3DFmt = nFormatSRGB; - } - - // must use typeless format to allow runtime casting - if (m_nFlags & FT_USAGE_ALLOWREADSRGB) - { - D3DFmt = ConvertToTypelessFmt(D3DFmt); - } - } - - if (pData[0]) - { - AZ_Assert(m_nArraySize == 1, "There is no implementation for tex array data."); - - STextureInfoData InitData[g_nD3D10MaxSupportedSubres]; - - for (int nSide = 0; nSide < 6; nSide++) - { - int w = nWdt; - int h = nHgt; - int nOffset = 0; - const byte* src = (!(m_nFlags & FT_REPLICATE_TO_ALL_SIDES)) ? pData[nSide] : pData[0]; - - for (int i = 0; i < nMips; i++) - { - if (!w && !h) - { - break; - } - if (!w) - { - w = 1; - } - if (!h) - { - h = 1; - } - - int nSubresInd = nSide * nMips + i; - int nSize = TextureDataSize(w, h, 1, 1, 1, m_eTFSrc, m_eSrcTileMode); - - InitData[nSubresInd].pSysMem = &src[nOffset]; - - if (m_eSrcTileMode == eTM_None) - { - InitData[nSubresInd].SysMemPitch = TextureDataSize(w, 1, 1, 1, 1, m_eTFSrc, eTM_None); - - //ignored - InitData[nSubresInd].SysMemSlicePitch = nSize; - InitData[nSubresInd].SysMemTileMode = eTM_None; - } - else - { - InitData[nSubresInd].SysMemPitch = 0; - InitData[nSubresInd].SysMemSlicePitch = 0; - InitData[nSubresInd].SysMemTileMode = m_eSrcTileMode; - } - - w >>= 1; - h >>= 1; - nOffset += nSize; - } - } - - TI.m_pData = InitData; - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->CreateCubeTexture(m_SrcName, nWdt, nMips, m_nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - else - { - //hr = gcpRendD3D->GetDevice().CreateTexture2D(&Desc, 0, 0); // validates parameters - //assert(hr == S_FALSE); - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->CreateCubeTexture(m_SrcName, nWdt, nMips, m_nArraySize, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - if (FAILED(hr)) - { - AZ_Assert(0, "Call to CreateCubeTexture failed for '%s'.", GetSourceName()); - return false; - } - - if (m_nFlags & FT_USAGE_ALLOWREADSRGB) - { - D3DFmt = nFormatOrig; - } - - D3DCubeTexture* pID3DTexture = m_pDevTexture->GetCubeTexture(); - - D3DShaderResourceView* pRes = NULL; - D3D11_SHADER_RESOURCE_VIEW_DESC ResDesc; - ZeroStruct(ResDesc); - ResDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt(D3DFmt); - - if (m_nArraySize > 1) - { - ResDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; - ResDesc.TextureCubeArray.MipLevels = nMips; - ResDesc.TextureCubeArray.First2DArrayFace = 0; - ResDesc.TextureCubeArray.NumCubes = m_nArraySize; - - // Create the multi-slice shader resource view - hr = gcpRendD3D->GetDevice().CreateShaderResourceView(pID3DTexture, &ResDesc, &pRes); - if (FAILED(hr)) - { - AZ_Assert(0, "Call to CreateShaderResourceView failed for '%s'.", GetSourceName()); - return false; - } - m_pDeviceShaderResource = pRes; - m_nMinMipVidActive = 0; - } - else - { - ResDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - ResDesc.TextureCube.MipLevels = nMips; - ResDesc.TextureCube.MostDetailedMip = 0; - hr = gcpRendD3D->GetDevice().CreateShaderResourceView(pID3DTexture, &ResDesc, &pRes); - if (FAILED(hr)) - { - AZ_Assert(0, "Call to CreateShaderResourceView failed for '%s'.", GetSourceName()); - return false; - } - m_pDeviceShaderResource = pRes; - m_nMinMipVidActive = 0; - - if (m_nFlags & FT_USAGE_ALLOWREADSRGB) - { - ResDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt(nFormatSRGB); - - D3DShaderResourceView* pSRGBRes = NULL; - hr = gcpRendD3D->GetDevice().CreateShaderResourceView(pID3DTexture, &ResDesc, &pSRGBRes); - if (FAILED(hr)) - { - AZ_Assert(0, "Call to CreateShaderResourceView failed for '%s'.", GetSourceName()); - return false; - } - //assign shader resource views - m_pDeviceShaderResourceSRGB = pSRGBRes; - } - } - } - else if (m_eTT == eTT_3D) - { - STextureInfo TI; - D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat; - - uint32 nUsage = 0; - if (m_nFlags & FT_USAGE_DEPTHSTENCIL) - { - nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL; - } - if (m_nFlags & FT_USAGE_RENDERTARGET) - { - nUsage |= CDeviceManager::USAGE_RENDER_TARGET; - } - -#if defined(AZ_PLATFORM_IOS) - if (m_nFlags & FT_USAGE_MEMORYLESS) - { - nUsage |= CDeviceManager::USAGE_MEMORYLESS; - } -#endif - - if (m_nFlags & FT_USAGE_DYNAMIC) - { - nUsage |= CDeviceManager::USAGE_DYNAMIC; - } - if ((m_nFlags & (FT_DONT_RELEASE | FT_DONT_STREAM)) == (FT_DONT_RELEASE | FT_DONT_STREAM)) - { - nUsage |= CDeviceManager::USAGE_ETERNAL; - } - if (m_nFlags & FT_STAGE_READBACK) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_READ; - } - if (m_nFlags & FT_STAGE_UPLOAD) - { - nUsage |= CDeviceManager::USAGE_STAGE_ACCESS | CDeviceManager::USAGE_CPU_WRITE; - } - if (m_nFlags & FT_USAGE_UNORDERED_ACCESS -#if defined(SUPPORT_DEVICE_INFO) - && r->DevInfo().FeatureLevel() >= D3D_FEATURE_LEVEL_11_0 -#endif //defined(SUPPORT_DEVICE_INFO) - ) - { - nUsage |= CDeviceManager::USAGE_UNORDERED_ACCESS; - } - if (m_nFlags & FT_USAGE_UAV_RWTEXTURE) - { - nUsage |= CDeviceManager::USAGE_UAV_RWTEXTURE; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_14 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - if (m_nFlags & FT_USAGE_MSAA) - { - m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type; - m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality; - - TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples; - TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality; - hr = pDevMan->CreateVolumeTexture(m_SrcName, nWdt, nHgt, m_nDepth, nMips, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI); - - AZ_Assert(SUCCEEDED(hr), "Call to CreateVolumeTexture failed for '%s'.", GetSourceName()); - m_bResolved = false; - - TI.m_nMSAASamples = 1; - TI.m_nMSAAQuality = 0; - } - if (pData[0]) - { - STextureInfoData InitData[15]; - - int w = nWdt; - int h = nHgt; - int d = nDepth; - int nOffset = 0; - const byte* src = pData[0]; - - for (int i = 0; i < nMips; i++) - { - if (!w && !h && !d) - { - break; - } - if (!w) - { - w = 1; - } - if (!h) - { - h = 1; - } - if (!d) - { - d = 1; - } - - int nSliceSize = TextureDataSize(w, h, 1, 1, 1, m_eTFSrc); - int nMipSize = TextureDataSize(w, h, d, 1, 1, m_eTFSrc); - InitData[i].pSysMem = &src[nOffset]; - InitData[i].SysMemPitch = TextureDataSize(w, 1, 1, 1, 1, m_eTFSrc); - - //ignored - InitData[i].SysMemSlicePitch = nSliceSize; - InitData[i].SysMemTileMode = eTM_None; - - w >>= 1; - h >>= 1; - d >>= 1; - - nOffset += nMipSize; - } - - TI.m_pData = InitData; - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->CreateVolumeTexture(m_SrcName, nWdt, nHgt, nDepth, nMips, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - else - { - //hr = gcpRendD3D->GetDevice().CreateTexture2D(&Desc, 0, 0); // validates parameters - //assert(hr == S_FALSE); - SAFE_RELEASE(m_pDevTexture); - hr = pDevMan->CreateVolumeTexture(m_SrcName, nWdt, nHgt, nDepth, nMips, nUsage, m_cClearColor, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI); - if (!FAILED(hr) && m_pDevTexture) - { - m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE)); - } - } - if (SUCCEEDED(hr)) - { - PREFAST_ASSUME(m_pDevTexture); - - m_pDeviceShaderResource = static_cast (CreateDeviceResourceView(SResourceView::ShaderResourceView(m_eTFDst))); - m_nMinMipVidActive = 0; - } - else - { - AZ_Assert(0, "Call to CreateVolumeTexture failed for '%s'.", GetSourceName()); - return false; - } - } - else - { - AZ_Assert(0, "Texture type not supported for this function."); - return false; - } - - SetTexStates(); - - AZ_Assert(!IsStreamed(), "IsStreamed must be false."); - if (m_pDevTexture) - { - m_nActualSize = m_nPersistentSize = m_pDevTexture->GetDeviceSize(); - if (m_nFlags & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET)) - { - CTexture::s_nStatsCurDynamicTexMem += m_nActualSize; - } - else - { - CTexture::s_nStatsCurManagedNonStreamedTexMem += m_nActualSize; - } - } - - // Notify that resource is dirty - InvalidateDeviceResource(eDeviceResourceDirty | eDeviceResourceViewDirty); - -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (m_pDevTexture) - { - m_pDevTexture->GetBaseTexture()->SetPrivateData(WKPDID_D3DDebugObjectName, m_SrcName.length(), m_SrcName.c_str()); - } -#endif - - if (!pData[0]) - { - return true; - } - - - if (resetSRGB) - { - m_bIsSRGB = false; - } - - SetWasUnload(false); - - SAFE_DELETE_ARRAY(pTemp); - return true; -} - -void CTexture::ReleaseDeviceTexture(bool bKeepLastMips, bool bFromUnload) -{ - PROFILE_FRAME(CTexture_ReleaseDeviceTexture); - AZ_TRACE_METHOD(); - - if (!gcpRendD3D->m_pRT->IsRenderThread()) - { - if (!gcpRendD3D->m_pRT->IsMainThread()) - { - CryFatalError("Texture is deleted from non-main and non-render thread, which causes command buffer corruption!"); - } - - // Push to render thread to process - gcpRendD3D->m_pRT->RC_ReleaseDeviceTexture(this); - return; - } - - Unbind(); - - if (!bFromUnload) - { - AbortStreamingTasks(this); - } - - if (s_pTextureStreamer) - { - s_pTextureStreamer->OnTextureDestroy(this); - } - - SAFE_DELETE(m_pRenderTargetData); - - if (!m_bNoTexture) - { - CDeviceTexture* pTex = m_pDevTexture; - - D3DShaderResourceView* pSRVSRGB = m_pDeviceShaderResourceSRGB; - SAFE_RELEASE(pSRVSRGB); - m_pDeviceShaderResourceSRGB = NULL; - - D3DShaderResourceView* pSRV = m_pDeviceShaderResource; - SAFE_RELEASE(pSRV); - m_pDeviceShaderResource = 0; - - D3DSurface* pRTV = m_pDeviceRTV; - SAFE_RELEASE(pRTV); - m_pDeviceRTV = NULL; - - D3DSurface* pRTVMS = m_pDeviceRTVMS; - SAFE_RELEASE(pRTVMS); - m_pDeviceRTVMS = NULL; - - if (!m_pFileTexMips || !m_pFileTexMips->m_pPoolItem) - { - if (IsStreamed()) - { - SAFE_DELETE(pTex); // for manually created textures - } - else - { - SAFE_RELEASE(pTex); - } - } - - m_pDevTexture = NULL; - - // otherwise it's already taken into account in the m_pFileTexMips->m_pPoolItem's dtor - if (!m_pFileTexMips || !m_pFileTexMips->m_pPoolItem) - { - if (IsDynamic()) - { - assert(CTexture::s_nStatsCurDynamicTexMem >= m_nActualSize); - CTexture::s_nStatsCurDynamicTexMem -= m_nActualSize; - } - else if (!IsStreamed()) - { - assert(CTexture::s_nStatsCurManagedNonStreamedTexMem >= m_nActualSize); - CTexture::s_nStatsCurManagedNonStreamedTexMem -= m_nActualSize; - } - } - if (m_pFileTexMips) - { - m_bStreamPrepared = false; - StreamRemoveFromPool(); - if (bKeepLastMips) - { - const int nLastMipsStart = m_nMips - m_CacheFileHeader.m_nMipsPersistent; - int nSides = StreamGetNumSlices(); - for (int nS = 0; nS < nSides; nS++) - { - for (int i = 0; i < nLastMipsStart; i++) - { - SMipData* mp = &m_pFileTexMips->m_pMipHeader[i].m_Mips[nS]; - mp->Free(); - } - } - } - else - { - Unlink(); - StreamState_ReleaseInfo(this, m_pFileTexMips); - m_pFileTexMips = NULL; - m_bStreamed = false; - SetStreamingInProgress(InvalidStreamSlot); - m_bStreamRequested = false; - } - } - m_nActualSize = 0; - m_nPersistentSize = 0; - } - else - { - m_pDevTexture = NULL; - m_pDeviceRTV = NULL; - m_pDeviceShaderResource = NULL; - m_pDeviceShaderResourceSRGB = NULL; - } - m_bNoTexture = false; -} - -void* CTexture::CreateDeviceResourceView(const SResourceView& rv) -{ - const SPixFormat* pPixFormat = NULL; - if (ClosestFormatSupported((ETEX_Format)rv.m_Desc.nFormat, pPixFormat) == eTF_Unknown) - { - return NULL; - } - - HRESULT hr = E_FAIL; - void* pResult = NULL; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_8 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - // DX expects -1 for selecting all mip maps/slices. max count throws an exception - const uint nSliceCount = rv.m_Desc.nSliceCount == SResourceView().m_Desc.nSliceCount ? (uint) - 1 : (uint)rv.m_Desc.nSliceCount; -#endif - - if (!m_pDevTexture) - { - return nullptr; - } - - D3DTexture* pTex = m_pDevTexture->Get2DTexture(); - - switch (rv.m_Desc.eViewType) - { - case SResourceView::eShaderResourceView: - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - SetShaderResourceViewDesc(rv, m_eTT, pPixFormat->DeviceFormat, m_nArraySize, nSliceCount, srvDesc); - if (rv.m_Desc.bMultisample && m_eTT == eTT_2D) - { - pTex = m_pRenderTargetData->m_pDeviceTextureMSAA->Get2DTexture(); - } - D3DShaderResourceView* pSRV = NULL; - hr = gcpRendD3D->GetDevice().CreateShaderResourceView(pTex, &srvDesc, &pSRV); - pResult = pSRV; - -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (pSRV) - { - AZStd::string srvName = AZStd::string::format("[SRV] %s", m_SrcName.c_str()); - pSRV->SetPrivateData(WKPDID_D3DDebugObjectName, srvName.length(), srvName.c_str()); - } -#endif - - } - break; - case SResourceView::eRenderTargetView: - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - SetRenderTargetViewDesc(rv, m_eTT, pPixFormat->DeviceFormat, m_nArraySize, nSliceCount, rtvDesc); - if (rv.m_Desc.bMultisample && m_eTT == eTT_2D) - { - pTex = m_pRenderTargetData->m_pDeviceTextureMSAA->Get2DTexture(); - } - D3DSurface* pRTV = NULL; - hr = gcpRendD3D->GetDevice().CreateRenderTargetView(pTex, &rtvDesc, &pRTV); - pResult = pRTV; - -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (pRTV) - { - AZStd::string rtvName = AZStd::string::format("[RTV] %s", m_SrcName.c_str()); - pRTV->SetPrivateData(WKPDID_D3DDebugObjectName, rtvName.length(), rtvName.c_str()); - } -#endif - } - break; - case SResourceView::eDepthStencilView: - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - SetDepthStencilViewDesc(rv, m_eTT, pPixFormat->DeviceFormat, m_nArraySize, nSliceCount, dsvDesc); - - dsvDesc.Flags = rv.m_Desc.nFlags; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_9 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - D3DDepthSurface* pDSV = NULL; - hr = gcpRendD3D->GetDevice().CreateDepthStencilView(pTex, &dsvDesc, &pDSV); - pResult = pDSV; - -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (pDSV) - { - AZStd::string dsvName = AZStd::string::format("[DSV] %s", m_SrcName.c_str()); - pDSV->SetPrivateData(WKPDID_D3DDebugObjectName, dsvName.length(), dsvName.c_str()); - } -#endif - } - break; - case SResourceView::eUnorderedAccessView: - { - D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - - SetUnorderedAccessViewDesc(rv, m_eTT, pPixFormat->DeviceFormat, m_nArraySize, nSliceCount, uavDesc); - - if (rv.m_Desc.nFlags & 0x1) // typed UAV loads are only allowed for single-component 32-bit element types - { - uavDesc.Format = DXGI_FORMAT_R32_UINT; - } - - D3DUnorderedAccessView* pUAV = NULL; - hr = gcpRendD3D->GetDevice().CreateUnorderedAccessView(pTex, &uavDesc, &pUAV); - - pResult = pUAV; -#if defined(D3DTEXTURE_CPP_USE_PRIVATEDATA) - if (pUAV) - { - AZStd::string uavName = AZStd::string::format("[UAV] %s", m_SrcName.c_str()); - pUAV->SetPrivateData(WKPDID_D3DDebugObjectName, uavName.length(), uavName.c_str()); - } -#endif - } - break; - } - - if (FAILED(hr)) - { - CRY_ASSERT(0); - return NULL; - } - - return pResult; -} - -void CTexture::SetTexStates() -{ - STexState s; - - const bool noMipFiltering = m_nMips <= 1 && !(m_nFlags & FT_FORCE_MIPS); - s.m_nMinFilter = FILTER_LINEAR; - s.m_nMagFilter = FILTER_LINEAR; - s.m_nMipFilter = noMipFiltering ? FILTER_NONE : FILTER_LINEAR; - - const int addrMode = (m_nFlags & FT_STATE_CLAMP || m_eTT == eTT_Cube) ? TADDR_CLAMP : TADDR_WRAP; - s.SetClampMode(addrMode, addrMode, addrMode); - - m_nDefState = (uint16)CTexture::GetTexState(s); -} - -static uint32 sAddressMode(int nAddress) -{ - IF (nAddress < 0, 0) - { - nAddress = TADDR_WRAP; - } - - switch (nAddress) - { - case TADDR_WRAP: - return D3D11_TEXTURE_ADDRESS_WRAP; - case TADDR_CLAMP: - return D3D11_TEXTURE_ADDRESS_CLAMP; - case TADDR_BORDER: - return D3D11_TEXTURE_ADDRESS_BORDER; - case TADDR_MIRROR: - return D3D11_TEXTURE_ADDRESS_MIRROR; - default: - assert(0); - return D3D11_TEXTURE_ADDRESS_WRAP; - } -} - -void STexState::SetComparisonFilter(bool bEnable) -{ - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - SAFE_RELEASE(pSamp); - m_pDeviceState = NULL; - } - m_bComparison = bEnable; -} - -bool STexState::SetClampMode(int nAddressU, int nAddressV, int nAddressW) -{ - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - SAFE_RELEASE(pSamp); - m_pDeviceState = NULL; - } - - m_nAddressU = sAddressMode(nAddressU); - m_nAddressV = sAddressMode(nAddressV); - m_nAddressW = sAddressMode(nAddressW); - return true; -} - -bool STexState::SetFilterMode(int nFilter) -{ - IF (nFilter < 0, 0) - { - nFilter = FILTER_TRILINEAR; - } - - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - SAFE_RELEASE(pSamp); - m_pDeviceState = NULL; - } - - switch (nFilter) - { - case FILTER_POINT: - case FILTER_NONE: - m_nMinFilter = FILTER_POINT; - m_nMagFilter = FILTER_POINT; - m_nMipFilter = FILTER_NONE; - m_nAnisotropy = 1; - break; - case FILTER_LINEAR: - m_nMinFilter = FILTER_LINEAR; - m_nMagFilter = FILTER_LINEAR; - m_nMipFilter = FILTER_NONE; - m_nAnisotropy = 1; - break; - case FILTER_BILINEAR: - m_nMinFilter = FILTER_LINEAR; - m_nMagFilter = FILTER_LINEAR; - m_nMipFilter = FILTER_POINT; - m_nAnisotropy = 1; - break; - case FILTER_TRILINEAR: - m_nMinFilter = FILTER_LINEAR; - m_nMagFilter = FILTER_LINEAR; - m_nMipFilter = FILTER_LINEAR; - m_nAnisotropy = 1; - break; - case FILTER_ANISO2X: - case FILTER_ANISO4X: - case FILTER_ANISO8X: - case FILTER_ANISO16X: - m_nMinFilter = nFilter; - m_nMagFilter = nFilter; - m_nMipFilter = nFilter; - if (nFilter == FILTER_ANISO2X) - { - m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 2); - } - else - if (nFilter == FILTER_ANISO4X) - { - m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 4); - } - else - if (nFilter == FILTER_ANISO8X) - { - m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 8); - } - else - if (nFilter == FILTER_ANISO16X) - { - m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 16); - } - break; - default: - assert(0); - return false; - } - return true; -} - -void STexState::SetBorderColor(DWORD dwColor) -{ - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - SAFE_RELEASE(pSamp); - m_pDeviceState = NULL; - } - - m_dwBorderColor = dwColor; -} - -void STexState::PostCreate() -{ - if (m_pDeviceState) - { - return; - } - - D3D11_SAMPLER_DESC Desc; - ZeroStruct(Desc); - D3DSamplerState* pSamp = NULL; - // AddressMode of 0 is INVALIDARG - Desc.AddressU = m_nAddressU ? (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressU : D3D11_TEXTURE_ADDRESS_WRAP; - Desc.AddressV = m_nAddressV ? (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressV : D3D11_TEXTURE_ADDRESS_WRAP; - Desc.AddressW = m_nAddressW ? (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressW : D3D11_TEXTURE_ADDRESS_WRAP; - ColorF col((uint32)m_dwBorderColor); - Desc.BorderColor[0] = col.r; - Desc.BorderColor[1] = col.g; - Desc.BorderColor[2] = col.b; - Desc.BorderColor[3] = col.a; - if (m_bComparison) - { - Desc.ComparisonFunc = D3D11_COMPARISON_LESS; - } - else - { - Desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - } - - Desc.MaxAnisotropy = 1; - Desc.MinLOD = 0; - if (m_nMipFilter == FILTER_NONE) - { - Desc.MaxLOD = 0.0f; - } - else - { - Desc.MaxLOD = 100.0f; - } - - Desc.MipLODBias = m_MipBias; - - if (m_bComparison) - { - if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && m_nMipFilter == FILTER_LINEAR || m_nMinFilter == FILTER_TRILINEAR || m_nMagFilter == FILTER_TRILINEAR) - { - Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; - } - else - if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT) || m_nMinFilter == FILTER_BILINEAR || m_nMagFilter == FILTER_BILINEAR) - { - Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; - } - else - if (m_nMinFilter == FILTER_POINT && m_nMagFilter == FILTER_POINT && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT)) - { - Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT; - } - else - if (m_nMinFilter >= FILTER_ANISO2X && m_nMagFilter >= FILTER_ANISO2X && m_nMipFilter >= FILTER_ANISO2X) - { - Desc.Filter = D3D11_FILTER_COMPARISON_ANISOTROPIC; - Desc.MaxAnisotropy = m_nAnisotropy; - } - } - else - { - if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && m_nMipFilter == FILTER_LINEAR || m_nMinFilter == FILTER_TRILINEAR || m_nMagFilter == FILTER_TRILINEAR) - { - Desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - } - else - if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT) || m_nMinFilter == FILTER_BILINEAR || m_nMagFilter == FILTER_BILINEAR) - { - Desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; - } - else - if (m_nMinFilter == FILTER_POINT && m_nMagFilter == FILTER_POINT && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT)) - { - Desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - } - else - if (m_nMinFilter >= FILTER_ANISO2X && m_nMagFilter >= FILTER_ANISO2X && m_nMipFilter >= FILTER_ANISO2X) - { - Desc.Filter = D3D11_FILTER_ANISOTROPIC; - Desc.MaxAnisotropy = m_nAnisotropy; - } - else - { - assert(0); - } - } - - HRESULT hr = gcpRendD3D->GetDevice().CreateSamplerState(&Desc, &pSamp); - if (SUCCEEDED(hr)) - { - m_pDeviceState = pSamp; - } - else - { - assert(0); - } -} - -void STexState::Destroy() -{ - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - SAFE_RELEASE(pSamp); - m_pDeviceState = NULL; - } -} - -void STexState::Init(const STexState& src) -{ - memcpy(this, &src, sizeof(src)); - if (m_pDeviceState) - { - D3DSamplerState* pSamp = (D3DSamplerState*)m_pDeviceState; - pSamp->AddRef(); - } -} - -bool CTexture::SetClampingMode(int nAddressU, int nAddressV, int nAddressW) -{ - return s_sDefState.SetClampMode(nAddressU, nAddressV, nAddressW); -} - -bool CTexture::SetFilterMode(int nFilter) -{ - return s_sDefState.SetFilterMode(nFilter); -} - -void CTexture::UpdateTexStates() -{ - m_nDefState = (uint16)CTexture::GetTexState(s_sDefState); -} - -void CTexture::SetSamplerState(int nTS, int nSUnit, EHWShaderClass eHWSC) -{ - FUNCTION_PROFILER_RENDER_FLAT - assert(gcpRendD3D->m_pRT->IsRenderThread()); - - STexState* pTS = &s_TexStates[nTS]; - D3DSamplerState* pSamp = (D3DSamplerState*)pTS->m_pDeviceState; - - assert(pSamp); - - if (pSamp) - { - if (eHWSC == eHWSC_Pixel) - { - gcpRendD3D->m_DevMan.BindSampler(eHWSC_Pixel, &pSamp, nSUnit, 1); - } - else - if (eHWSC == eHWSC_Domain) - { - gcpRendD3D->m_DevMan.BindSampler(eHWSC_Domain, &pSamp, nSUnit, 1); - } - else - if (eHWSC == eHWSC_Vertex) - { - gcpRendD3D->m_DevMan.BindSampler(eHWSC_Vertex, &pSamp, nSUnit, 1); - } - else - if (eHWSC == eHWSC_Compute) - { - gcpRendD3D->m_DevMan.BindSampler(eHWSC_Compute, &pSamp, nSUnit, 1); - } - else - if (eHWSC == eHWSC_Geometry) - { - gcpRendD3D->m_DevMan.BindSampler(eHWSC_Geometry, &pSamp, nSUnit, 1); - } - else - { - assert(0); - } - } -} - -void CTexture::ApplySamplerState(int nSUnit, EHWShaderClass eHWSC, int nState) -{ - FUNCTION_PROFILER_RENDER_FLAT - - uint32 nTSSel = Isel32(nState, (int32)m_nDefState); - assert(nTSSel >= 0 && nTSSel < s_TexStates.size()); - - CDeviceTexture* pDevTex = m_pDevTexture; - - // avoiding L2 cache misses from usage from up ahead - PrefetchLine(pDevTex, 0); - - assert(nSUnit >= 0 && nSUnit < 16); - assert((nSUnit >= 0 || nSUnit == -2) && nSUnit < gcpRendD3D->m_NumSamplerSlots); - - CD3D9Renderer *const __restrict rd = gcpRendD3D; - const int nFrameID = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - if (IsVertexTexture()) - eHWSC = eHWSC_Vertex; - - SetSamplerState(nTSSel, nSUnit, eHWSC); -} - -//------------------------------------------------------------------------------ -// Given a texture and a binding slot, this is the method that actually refreshes -// the texture resource, validates it and finally binds it to the HW stage. -void CTexture::ApplyTexture(int nTUnit, EHWShaderClass eHWSC, SResourceView::KeyType nResViewKey) -{ - FUNCTION_PROFILER_RENDER_FLAT - - STexStageInfo *TexStages = s_TexStages; - CDeviceTexture* pDevTex = m_pDevTexture; - - // avoiding L2 cache misses from usage from up ahead - PrefetchLine(pDevTex, 0); - - assert(nTUnit >= 0 && nTUnit < gcpRendD3D->m_NumResourceSlots); - - CD3D9Renderer *const __restrict rd = gcpRendD3D; - const int nFrameID = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - if (IsStreamed() && !m_bPostponed) - { - bool bIsUnloaded = IsUnloaded(); - - assert(m_pFileTexMips); - if (bIsUnloaded || !m_bStreamPrepared || IsPartiallyLoaded()) - { - PROFILE_FRAME(Texture_Precache); - if (!CRenderer::CV_r_texturesstreaming || !m_bStreamPrepared || bIsUnloaded) - { - if (bIsUnloaded) - StreamLoadFromCache(0); - else - Load(m_eTFDst); - - pDevTex = m_pDevTexture; - } - } - } - - IF(this != CTexture::s_pTexNULL && (!pDevTex || !pDevTex->GetBaseTexture()), 0) - { - // apply black by default - CTexture* pBlackTexture = CTextureManager::Instance()->GetBlackTexture(); - if (m_eTT != eTT_Cube && pBlackTexture) - { - pBlackTexture->ApplyTexture(nTUnit, eHWSC, nResViewKey); - } - else - { - pBlackTexture = CTextureManager::Instance()->GetBlackTextureCM(); - if (m_eTT == eTT_Cube && pBlackTexture) - { - pBlackTexture->ApplyTexture(nTUnit, eHWSC, nResViewKey); - } - } - return; - } - - // Resolve multisampled RT to texture - if (!m_bResolved) - { - Resolve(); - } - - bool bStreamed = IsStreamed(); - if (m_nAccessFrameID != nFrameID) - { - m_nAccessFrameID = nFrameID; - -#if !defined(_RELEASE) - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextures++; - if (m_nFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_DynTexturesSize += m_nActualSize; - } - else - { - if (bStreamed) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamVidSize += m_nActualSize; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamSysSize += StreamComputeDevDataSize(0); - } - else - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesSysMemSize += m_nActualSize; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesVidMemSize += m_nActualSize; - } - } -#endif - - // mip map fade in - if (bStreamed) - { - const float fCurrentMipBias = m_fCurrentMipBias; - if (fabsf(fCurrentMipBias) > 0.26667f) - { - // one mip per half a second - m_fCurrentMipBias -= 0.26667f * fCurrentMipBias; - - gcpRendD3D->GetDeviceContext().SetResourceMinLOD(pDevTex->Get2DTexture(), m_fCurrentMipBias + (float)m_nMinMipVidUploaded); - } - else if (fCurrentMipBias != 0.f) - { - m_fCurrentMipBias = 0.f; - } - } - } - - if (IsVertexTexture()) - eHWSC = eHWSC_Vertex; - - const bool bUnnorderedAcessView = SResourceView(nResViewKey).m_Desc.eViewType == SResourceView::eUnorderedAccessView; - - D3DShaderResourceView* pResView = GetShaderResourceView(nResViewKey); - - if (pDevTex == TexStages[nTUnit].m_DevTexture && pResView == TexStages[nTUnit].m_pCurResView && eHWSC == TexStages[nTUnit].m_eHWSC) - return; - - TexStages[nTUnit].m_pCurResView = pResView; - TexStages[nTUnit].m_eHWSC = eHWSC; - - // This must get re-factored post C3. - // This check is ultra-buggy, render targets setup is deferred until last moment might not be matching this check at all. Also very wrong for MRTs - - if (rd->m_pCurTarget[0] == this) - { - //assert(rd->m_pCurTarget[0]->m_pDeviceRTV); - rd->m_pNewTarget[0]->m_bWasSetRT = false; - rd->GetDeviceContext().OMSetRenderTargets(1, &rd->m_pNewTarget[0]->m_pTarget, rd->m_pNewTarget[0]->m_pDepth); - } - - TexStages[nTUnit].m_DevTexture = pDevTex; - -#if !defined(_RELEASE) - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextChanges++; -#endif - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - if (IsNoTexture()) - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\" (Not found)\n", nTUnit, m_SrcName.c_str()); - } - else - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\"\n", nTUnit, m_SrcName.c_str()); - } - } -#endif - - { -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3 && int64(nResViewKey) >= 0) - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): Shader Resource View: %ul \n", nResViewKey); - } -#endif - - if (bUnnorderedAcessView) - { - // todo: - // - add support for pixel shader side via OMSetRenderTargetsAndUnorderedAccessViews - // - DX11.1 very likely API will be similar to CSSetUnorderedAccessViews, but for all stages - D3DUnorderedAccessView *pUAV = (D3DUnorderedAccessView*)pResView; - rd->GetDeviceContext().CSSetUnorderedAccessViews(nTUnit, 1, &pUAV, NULL); - return; - } - - { - if (IsVertexTexture()) - eHWSC = eHWSC_Vertex; - - if (eHWSC == eHWSC_Pixel) - { - rd->m_DevMan.BindSRV(eHWSC_Pixel, pResView, nTUnit); - } - else if (eHWSC == eHWSC_Vertex) - { - rd->m_DevMan.BindSRV(eHWSC_Vertex, pResView, nTUnit); - } - else if (eHWSC == eHWSC_Domain) - { - rd->m_DevMan.BindSRV(eHWSC_Domain, pResView, nTUnit); - } - else if (eHWSC == eHWSC_Compute) - { - rd->m_DevMan.BindSRV(eHWSC_Compute, pResView, nTUnit); - } - else - { - assert(0); - } - } - } -} - -void CTexture::Apply(int nTUnit, int nState, int nTexMatSlot, int nSUnit, SResourceView::KeyType nResViewKey, EHWShaderClass eHWSC) -{ - FUNCTION_PROFILER_RENDER_FLAT - assert(nTUnit >= 0); - - uint32 nTSSel = Isel32(nState, (int32)m_nDefState); - assert(nTSSel >= 0 && nTSSel < s_TexStates.size()); - -#if defined(OPENGL) - // Due to driver issues on MALI gpus only point filtering is allowed for 32 bit float textures. - // If another filtering is used the sampler returns black. - if ((gcpRendD3D->m_Features | RFT_HW_ARM_MALI) && - (m_eTFDst == eTF_R32F || m_eTFDst == eTF_R32G32B32A32F) && - (s_TexStates[nTSSel].m_nMagFilter != FILTER_POINT || s_TexStates[nTSSel].m_nMinFilter != FILTER_POINT)) - { - STexState newState = s_TexStates[nTSSel]; - newState.SetFilterMode(FILTER_POINT); - nTSSel = CTexture::GetTexState(newState); - AZ_WarningOnce("Texture", false, "The current device only supports point filtering for full float textures. Forcing filtering for texture in slot %d", nTUnit); - } -#endif // defined(OPENGL) - - STexStageInfo* TexStages = s_TexStages; - - CDeviceTexture* pDevTex = m_pDevTexture; - - // avoiding L2 cache misses from usage from up ahead - PrefetchLine(pDevTex, 0); - - if (nSUnit >= -1) - { - nSUnit = Isel32(nSUnit, nTUnit); - } - - assert(nTUnit >= 0 && nTUnit < gcpRendD3D->m_NumResourceSlots); - assert((nSUnit >= 0 || nSUnit == -2) && nSUnit < gcpRendD3D->m_NumSamplerSlots); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const int nFrameID = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID; - - if (IsStreamed() && !m_bPostponed) - { - bool bIsUnloaded = IsUnloaded(); - - assert(m_pFileTexMips); - if (bIsUnloaded || !m_bStreamPrepared || IsPartiallyLoaded()) - { - PROFILE_FRAME(Texture_Precache); - if (!CRenderer::CV_r_texturesstreaming || !m_bStreamPrepared || bIsUnloaded) - { - if (bIsUnloaded) - { - StreamLoadFromCache(0); - } - else - { - Load(m_eTFDst); - } - - pDevTex = m_pDevTexture; - } - } - - if (nTexMatSlot != EFTT_UNKNOWN) - { - m_nStreamingPriority = max((int8)m_nStreamingPriority, TextureHelpers::LookupTexPriority((EEfResTextures)nTexMatSlot)); - } - } - - IF (this != CTexture::s_pTexNULL && (!pDevTex || !pDevTex->GetBaseTexture()), 0) - { - // apply black by default - if (m_eTT != eTT_Cube && CTextureManager::Instance()->GetBlackTexture() && this != CTextureManager::Instance()->GetBlackTexture()) - { - CTextureManager::Instance()->GetBlackTexture()->Apply(nTUnit, nState, nTexMatSlot, nSUnit, nResViewKey); - } - else if (m_eTT == eTT_Cube && CTextureManager::Instance()->GetBlackTextureCM() && this != CTextureManager::Instance()->GetBlackTextureCM()) - { - CTextureManager::Instance()->GetBlackTextureCM()->Apply(nTUnit, nState, nTexMatSlot, nSUnit, nResViewKey); - } - return; - } - - // Resolve multisampled RT to texture - if (!m_bResolved) - { - Resolve(); - } - bool bStreamed = IsStreamed(); - if (m_nAccessFrameID != nFrameID) - { - m_nAccessFrameID = nFrameID; - -#if !defined(_RELEASE) - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextures++; - if (m_nFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_DynTexturesSize += m_nActualSize; - } - else - { - if (bStreamed) - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamVidSize += m_nActualSize; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamSysSize += StreamComputeDevDataSize(0); - } - else - { - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesSysMemSize += m_nActualSize; - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesVidMemSize += m_nActualSize; - } - } -#endif - - // mip map fade in - if (bStreamed) - { - const float fCurrentMipBias = m_fCurrentMipBias; - if (fabsf(fCurrentMipBias) > 0.26667f) - { - // one mip per half a second - m_fCurrentMipBias -= 0.26667f * fCurrentMipBias; -#if defined(CRY_USE_METAL) - //For metal, the lodminclamp is set once at initialization for the mtlsamplerstate. The mtlSamplerDescriptor's properties - //are only used during mtlSamplerState object creation; once created the behaviour of a sampler state object is - //fixed and cannot be changed. Hence we modify the descriptor with minlod and recreate the sampler state. - STexState* pTS = &s_TexStates[nTSSel]; - D3DSamplerState* pSamp = (D3DSamplerState*)pTS->m_pDeviceState; - pSamp->SetLodMinClamp(m_fCurrentMipBias + static_cast(m_nMinMipVidUploaded)); -#else - gcpRendD3D->GetDeviceContext().SetResourceMinLOD(pDevTex->Get2DTexture(), m_fCurrentMipBias + static_cast(m_nMinMipVidUploaded)); -#endif - } - else if (fCurrentMipBias != 0.f) - { - m_fCurrentMipBias = 0.f; - } - } - } - - if (IsVertexTexture()) - { - eHWSC = eHWSC_Vertex; - } - - const bool bUnnorderedAcessView = SResourceView(nResViewKey).m_Desc.eViewType == SResourceView::eUnorderedAccessView; - if (!bUnnorderedAcessView && nSUnit >= 0) - { - SetSamplerState(nTSSel, nSUnit, eHWSC); - } - - D3DShaderResourceView* pResView = GetShaderResourceView(nResViewKey, s_TexStates[nTSSel].m_bSRGBLookup); - - if (pDevTex == TexStages[nTUnit].m_DevTexture && pResView == TexStages[nTUnit].m_pCurResView && eHWSC == TexStages[nTUnit].m_eHWSC) - { - return; - } - - TexStages[nTUnit].m_pCurResView = pResView; - TexStages[nTUnit].m_eHWSC = eHWSC; - // This must get re-factored post C3. - // - This check is ultra-buggy, render targets setup is deferred until last moment might not be matching this check at all. Also very wrong for MRTs - - if (rd->m_pCurTarget[0] == this) - { - //assert(rd->m_pCurTarget[0]->m_pDeviceRTV); - rd->m_pNewTarget[0]->m_bWasSetRT = false; - rd->GetDeviceContext().OMSetRenderTargets(1, &rd->m_pNewTarget[0]->m_pTarget, rd->m_pNewTarget[0]->m_pDepth); - } - - TexStages[nTUnit].m_DevTexture = pDevTex; - -#if !defined(_RELEASE) - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextChanges++; -#endif - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3) - { - if (IsNoTexture()) - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\" (Not found)\n", nTUnit, m_SrcName.c_str()); - } - else - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\"\n", nTUnit, m_SrcName.c_str()); - } - } -#endif - - { -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log >= 3 && int64(nResViewKey) >= 0) - { - rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): Shader Resource View: %ul \n", nResViewKey); - } -#endif - - if (bUnnorderedAcessView) - { - // todo: - // - add support for pixel shader side via OMSetRenderTargetsAndUnorderedAccessViews - // - DX11.1 very likely API will be similar to CSSetUnorderedAccessViews, but for all stages - D3DUnorderedAccessView* pUAV = (D3DUnorderedAccessView*)pResView; - rd->GetDeviceContext().CSSetUnorderedAccessViews(nTUnit, 1, &pUAV, NULL); - return; - } - - { - if (IsVertexTexture()) - { - eHWSC = eHWSC_Vertex; - } - - if (eHWSC == eHWSC_Pixel) - { - rd->m_DevMan.BindSRV(eHWSC_Pixel, pResView, nTUnit); - } - else - if (eHWSC == eHWSC_Vertex) - { - rd->m_DevMan.BindSRV(eHWSC_Vertex, pResView, nTUnit); - } - else - if (eHWSC == eHWSC_Domain) - { - rd->m_DevMan.BindSRV(eHWSC_Domain, pResView, nTUnit); - } - else - if (eHWSC == eHWSC_Compute) - { - rd->m_DevMan.BindSRV(eHWSC_Compute, pResView, nTUnit); - } - else - if (eHWSC == eHWSC_Geometry) - { - rd->m_DevMan.BindSRV(eHWSC_Geometry, pResView, nTUnit); - } - else - { - assert(0); - } - } - } -} - -void CTexture::UpdateTextureRegion(const uint8_t* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc) -{ - gRenDev->m_pRT->RC_UpdateTextureRegion(this, data, nX, nY, nZ, USize, VSize, ZSize, eTFSrc); -} - -void CTexture::RT_UpdateTextureRegion(const byte* data, int nX, int nY, int nZ, int USize, int VSize, int ZSize, ETEX_Format eTFSrc) -{ - PROFILE_FRAME(UpdateTextureRegion); - - if (m_eTT != eTT_2D && m_eTT != eTT_3D) - { - assert(0); - return; - } - - HRESULT hr = S_OK; - CDeviceTexture* pDevTexture = GetDevTexture(); - assert(pDevTexture); - if (!pDevTexture) - { - return; - } - - bool bDone = false; - D3D11_BOX rc = {aznumeric_caster(nX), aznumeric_caster(nY), 0, aznumeric_caster(nX + USize), aznumeric_caster(nY + VSize), 1}; - if (m_eTT == eTT_2D) - { - if (GetBlockDim(m_eTFDst) == Vec2i(1)) - { - int nBPPSrc = CTexture::BytesPerBlock(eTFSrc); - int nBPPDst = CTexture::BytesPerBlock(m_eTFDst); - if (nBPPSrc == nBPPDst) - { - int nRowPitch = CTexture::TextureDataSize(USize, 1, 1, 1, 1, eTFSrc); - const int nSlicePitch = CTexture::TextureDataSize(USize, VSize, 1, 1, 1, eTFSrc); - gcpRendD3D->GetDeviceContext().UpdateSubresource(pDevTexture->Get2DTexture(), 0, &rc, data, nRowPitch, nSlicePitch); - bDone = true; - } - else - { - assert(0); - bDone = true; - } - } - } - else if (m_eTT == eTT_3D) - { - rc.front = nZ; - rc.back = nZ + ZSize; - - int nBPPSrc = CTexture::BytesPerBlock(eTFSrc); - int nBPPDst = CTexture::BytesPerBlock(m_eTFDst); - if (nBPPSrc == nBPPDst) - { - if (m_nFlags & FT_USAGE_DYNAMIC) - { - D3DVolumeTexture* pDT = pDevTexture->GetVolumeTexture(); - int cZ, cY; - for (cZ = nZ; cZ < ZSize; cZ++) - { - D3D11_MAPPED_SUBRESOURCE lrct; - uint32 nLockFlags = D3D11_MAP_WRITE_DISCARD; - uint32 nSubRes = D3D11CalcSubresource(0, cZ, 1); - - hr = gcpRendD3D->GetDeviceContext().Map(pDT, nSubRes, (D3D11_MAP)nLockFlags, 0, &lrct); - assert(hr == S_OK); - - byte* pDst = ((byte*)lrct.pData) + nX * 4 + nY * lrct.RowPitch; - for (cY = 0; cY < VSize; cY++) - { - cryMemcpy(pDst, data, USize * 4); - data += USize * 4; - pDst += lrct.RowPitch; - } - gcpRendD3D->GetDeviceContext().Unmap(pDT, nSubRes); - } - } - else - { - int U = USize; - int V = VSize; - int Z = ZSize; - for (int i = 0; i < m_nMips; i++) - { - if (!U) - { - U = 1; - } - if (!V) - { - V = 1; - } - if (!Z) - { - Z = 1; - } - - int nRowPitch = CTexture::TextureDataSize(U, 1, 1, 1, 1, eTFSrc); - int nDepthPitch = m_eTT == eTT_3D ? CTexture::TextureDataSize(U, V, 1, 1, 1, eTFSrc) : 0; - - gcpRendD3D->GetDeviceContext().UpdateSubresource(pDevTexture->GetBaseTexture(), i, &rc, data, nRowPitch, nDepthPitch); - bDone = true; - - data += nDepthPitch * Z; - - U >>= 1; - V >>= 1; - Z >>= 1; - - rc.front >>= 1; - rc.left >>= 1; - rc.top >>= 1; - - rc.back = max(rc.front + 1, rc.back >> 1); - rc.right = max(rc.left + 4, rc.right >> 1); - rc.bottom = max(rc.top + 4, rc.bottom >> 1); - } - } - } - else if ((eTFSrc == eTF_B8G8R8A8 || eTFSrc == eTF_B8G8R8X8) && (m_eTFDst == eTF_B5G6R5)) - { - assert(0); - bDone = true; - } - } - - if (!bDone) - { - D3D11_BOX box; - ZeroStruct(box); - box.right = USize; - box.bottom = VSize; - box.back = 1; - const int nPitch = CTexture::TextureDataSize(USize, 1, 1, 1, 1, eTFSrc); - const int nSlicePitch = CTexture::TextureDataSize(USize, VSize, 1, 1, 1, eTFSrc); - gcpRendD3D->GetDeviceContext().UpdateSubresource(pDevTexture->Get2DTexture(), 0, &box, data, nPitch, nSlicePitch); - } -} - -bool CTexture::Clear() -{ - if (!(m_nFlags & FT_USAGE_RENDERTARGET)) - return false; - - gRenDev->m_pRT->RC_ClearTarget(this, m_cClearColor); - return true; -} - -bool CTexture::Clear(const ColorF& color) -{ - if (!(m_nFlags & FT_USAGE_RENDERTARGET)) - { - return false; - } - - gRenDev->m_pRT->RC_ClearTarget(this, color); - return true; -} - -void SEnvTexture::Release() -{ - ReleaseDeviceObjects(); - SAFE_DELETE(m_pTex); -} - -void SEnvTexture::RT_SetMatrix() -{ - Matrix44A matView, matProj; - gRenDev->GetModelViewMatrix(matView.GetData()); - gRenDev->GetProjectionMatrix(matProj.GetData()); - - float fWidth = m_pTex ? (float)m_pTex->GetWidth() : 1; - float fHeight = m_pTex ? (float)m_pTex->GetHeight() : 1; - - Matrix44A matScaleBias(0.5f, 0, 0, 0, - 0, -0.5f, 0, 0, - 0, 0, 0.5f, 0, - // texel alignment - also push up y axis reflection up a bit - 0.5f + 0.5f / fWidth, 0.5f + 1.0f / fHeight, 0.5f, 1.0f); - - Matrix44A m = matProj * matScaleBias; - Matrix44A mm = matView * m; - m_Matrix = mm; -} - -void SEnvTexture::ReleaseDeviceObjects() -{ - //if (m_pTex) - // m_pTex->ReleaseDynamicRT(true); -} - -bool CTexture::RenderEnvironmentCMHDR([[maybe_unused]] int size, [[maybe_unused]] Vec3& Pos, [[maybe_unused]] TArray& vecData) -{ -#if !defined(CONSOLE) - - iLog->Log("Start generating a cubemap..."); - - vecData.SetUse(0); - - int vX, vY, vWidth, vHeight; - gRenDev->GetViewport(&vX, &vY, &vWidth, &vHeight); - - const int nOldWidth = gRenDev->GetCurrentContextViewportWidth(); - const int nOldHeight = gRenDev->GetCurrentContextViewportHeight(); - gRenDev->ChangeViewport(0, 0, size, size); - - int nPFlags = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags; - - CTexture* ptexGenEnvironmentCM = CTexture::Create2DTexture("$GenEnvironmentCM", size, size, 0, FT_DONT_STREAM, 0, eTF_R16G16B16A16F, eTF_R16G16B16A16F); - if (!ptexGenEnvironmentCM || !ptexGenEnvironmentCM->GetDevTexture()) - { - iLog->Log("Failed generating a cubemap: out of video memory"); - gRenDev->ChangeViewport(0, 0, nOldWidth, nOldHeight); - - SAFE_RELEASE(ptexGenEnvironmentCM); - return false; - } - - // Disable/set cvars that can affect cube map generation. This is thread unsafe (we assume editor will not run in mt mode), no other way around at this time - // - coverage buffer unreliable for multiple views - // - custom view distance ratios - - ICVar* pCoverageBufferCV = gEnv->pConsole->GetCVar("e_CoverageBuffer"); - const int32 nCoverageBuffer = pCoverageBufferCV ? pCoverageBufferCV->GetIVal() : 0; - if (pCoverageBufferCV) - { - pCoverageBufferCV->Set(0); - } - - ICVar* pStatObjBufferRenderTasksCV = gEnv->pConsole->GetCVar("e_StatObjBufferRenderTasks"); - const int32 nStatObjBufferRenderTasks = pStatObjBufferRenderTasksCV ? pStatObjBufferRenderTasksCV->GetIVal() : 0; - if (pStatObjBufferRenderTasksCV) - { - pStatObjBufferRenderTasksCV->Set(0); - } - - ICVar* pViewDistRatioCV = gEnv->pConsole->GetCVar("e_ViewDistRatio"); - const float fOldViewDistRatio = pViewDistRatioCV ? pViewDistRatioCV->GetFVal() : 1.f; - if (pViewDistRatioCV) - { - pViewDistRatioCV->Set(10000.f); - } - - ICVar* pViewDistRatioVegetationCV = gEnv->pConsole->GetCVar("e_ViewDistRatioVegetation"); - const float fOldViewDistRatioVegetation = pViewDistRatioVegetationCV ? pViewDistRatioVegetationCV->GetFVal() : 100.f; - if (pViewDistRatioVegetationCV) - { - pViewDistRatioVegetationCV->Set(10000.f); - } - - ICVar* pLodRatioCV = gEnv->pConsole->GetCVar("e_LodRatio"); - const float fOldLodRatio = pLodRatioCV ? pLodRatioCV->GetFVal() : 1.f; - if (pLodRatioCV) - { - pLodRatioCV->Set(1000.f); - } - - Vec3 oldSunDir, oldSunStr, oldSunRGB; - float oldSkyKm, oldSkyKr, oldSkyG; - if (CRenderer::CV_r_HideSunInCubemaps) - { - gEnv->p3DEngine->GetSkyLightParameters(oldSunDir, oldSunStr, oldSkyKm, oldSkyKr, oldSkyG, oldSunRGB); - gEnv->p3DEngine->SetSkyLightParameters(oldSunDir, oldSunStr, oldSkyKm, oldSkyKr, 1.0f, oldSunRGB, true); // Hide sun disc - } - - const int32 nFlaresCV = CRenderer::CV_r_flares; - CRenderer::CV_r_flares = 0; - - ICVar* pSSDOHalfResCV = gEnv->pConsole->GetCVar("r_ssdoHalfRes"); - const int nOldSSDOHalfRes = pSSDOHalfResCV ? pSSDOHalfResCV->GetIVal() : 1; - if (pSSDOHalfResCV) - { - pSSDOHalfResCV->Set(0); - } - - ICVar* pDynamicGI = gEnv->pConsole->GetCVar("e_GI"); - const int oldDynamicGIValue = pDynamicGI ? pDynamicGI->GetIVal() : 1; - if (pDynamicGI) - { - pDynamicGI->Set(0); - } - - const int nDesktopWidth = gcpRendD3D->m_deskwidth; - const int nDesktopHeight = gcpRendD3D->m_deskheight; - gcpRendD3D->m_deskwidth = gcpRendD3D->m_deskheight = size; - - gcpRendD3D->EnableSwapBuffers(false); - for (int nSide = 0; nSide < 6; nSide++) - { - gcpRendD3D->BeginFrame(); - gcpRendD3D->SetViewport(0, 0, size, size); - - gcpRendD3D->SetWidth(size); - gcpRendD3D->SetHeight(size); - - gcpRendD3D->EF_ClearTargetsLater(FRT_CLEAR, Clr_Transparent); - - DrawSceneToCubeSide(Pos, size, nSide); - - // Transfer to sysmem - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = size; - srcBox.top = 0; - srcBox.bottom = size; - srcBox.front = 0; - srcBox.back = 1; - - CDeviceTexture* pDevTextureSrc = CTexture::s_ptexHDRTarget->GetDevTexture(); - CDeviceTexture* pDevTextureDst = ptexGenEnvironmentCM->GetDevTexture(); - - gcpRendD3D->GetDeviceContext().CopySubresourceRegion(pDevTextureDst->Get2DTexture(), 0, 0, 0, 0, pDevTextureSrc->Get2DTexture(), 0, &srcBox); - - CDeviceTexture* pDstDevTex = ptexGenEnvironmentCM->GetDevTexture(); - pDstDevTex->DownloadToStagingResource(0, [&](void* pData, [[maybe_unused]] uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - unsigned short* pTarg = (unsigned short*)pData; - const uint32 nLineStride = CTexture::TextureDataSize(size, 1, 1, 1, 1, eTF_R16G16B16A16F) / sizeof(unsigned short); - - // Copy vertically flipped image - for (uint32 nLine = 0; nLine < size; ++nLine) - { - vecData.Copy(&pTarg[((size - 1) - nLine) * nLineStride], nLineStride); - } - - return true; - }); - - gcpRendD3D->EndFrame(); - } - - SAFE_RELEASE(ptexGenEnvironmentCM); - - // Restore previous states - - gcpRendD3D->m_deskwidth = nDesktopWidth; - gcpRendD3D->m_deskheight = nDesktopHeight; - gRenDev->ChangeViewport(0, 0, nOldWidth, nOldHeight); - - gcpRendD3D->EnableSwapBuffers(true); - gcpRendD3D->SetWidth(vWidth); - gcpRendD3D->SetHeight(vHeight); - gcpRendD3D->RT_SetViewport(vX, vY, vWidth, vHeight); - gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags = nPFlags; - gcpRendD3D->ResetToDefault(); - - if (pCoverageBufferCV) - { - pCoverageBufferCV->Set(nCoverageBuffer); - } - - if (pStatObjBufferRenderTasksCV) - { - pStatObjBufferRenderTasksCV->Set(nStatObjBufferRenderTasks); - } - - if (pViewDistRatioCV) - { - pViewDistRatioCV->Set(fOldViewDistRatio); - } - - if (pViewDistRatioVegetationCV) - { - pViewDistRatioVegetationCV->Set(fOldViewDistRatioVegetation); - } - - if (pLodRatioCV) - { - pLodRatioCV->Set(fOldLodRatio); - } - - if (CRenderer::CV_r_HideSunInCubemaps) - { - gEnv->p3DEngine->SetSkyLightParameters(oldSunDir, oldSunStr, oldSkyKm, oldSkyKr, oldSkyG, oldSunRGB, true); - } - - CRenderer::CV_r_flares = nFlaresCV; - - if (pSSDOHalfResCV) - { - pSSDOHalfResCV->Set(nOldSSDOHalfRes); - } - - if (pDynamicGI) - { - pDynamicGI->Set(oldDynamicGIValue); - } - - iLog->Log("Successfully finished generating a cubemap. The cubemap is being compressed in the background and will update automatically when done."); -#endif - - return true; -} - -////////////////////////////////////////////////////////////////////////// - -void CTexture::DrawSceneToCubeSide(Vec3& Pos, int tex_size, int side) -{ - const float sCubeVector[6][7] = - { - { 1, 0, 0, 0, 0, 1, -90}, //posx - {-1, 0, 0, 0, 0, 1, 90}, //negx - { 0, 1, 0, 0, 0, -1, 0}, //posy - { 0, -1, 0, 0, 0, 1, 0}, //negy - { 0, 0, 1, 0, 1, 0, 0}, //posz - { 0, 0, -1, 0, 1, 0, 0}, //negz - }; - - if (!iSystem) - { - return; - } - - CRenderer* r = gRenDev; - CCamera prevCamera = r->GetCamera(); - - I3DEngine* eng = gEnv->p3DEngine; - - Vec3 vForward = Vec3(sCubeVector[side][0], sCubeVector[side][1], sCubeVector[side][2]); - Vec3 vUp = Vec3(sCubeVector[side][3], sCubeVector[side][4], sCubeVector[side][5]); - - Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[side][6])); - Matrix34 mFinal = Matrix34(matRot, Pos); - - // Use current viewport camera's near/far to capture what is shown in the editor - const CCamera& viewCamera = gEnv->pSystem->GetViewCamera(); - const float captureNear = viewCamera.GetNearPlane(); - const float captureFar = viewCamera.GetFarPlane(); - const float captureFOV = DEG2RAD(90.0f); - - CCamera captureCamera; - captureCamera.SetMatrix(mFinal); - captureCamera.SetFrustum(tex_size, tex_size, captureFOV, captureNear, captureFar); - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log) - { - r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. DrawSceneToCubeSide .. (DrawCubeSide %d)\n", side); - } -#endif - - eng->RenderWorld(SHDF_CUBEMAPGEN | SHDF_ALLOWPOSTPROCESS | SHDF_ALLOWHDR | SHDF_ZPASS | SHDF_NOASYNC | SHDF_STREAM_SYNC, SRenderingPassInfo::CreateGeneralPassRenderingInfo(captureCamera, (SRenderingPassInfo::DEFAULT_FLAGS | SRenderingPassInfo::CUBEMAP_GEN)), __FUNCTION__); - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log) - { - r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. End DrawSceneToCubeSide .. (DrawCubeSide %d)\n", side); - } -#endif - - r->SetCamera(prevCamera); -} - -////////////////////////////////////////////////////////////////////////// - -void CTexture::DrawCubeSide(Vec3& Pos, int tex_size, int side, float fMaxDist) -{ - const float sCubeVector[6][7] = - { - { 1, 0, 0, 0, 0, 1, -90}, //posx - {-1, 0, 0, 0, 0, 1, 90}, //negx - { 0, -1, 0, 0, 0, 1, 0}, //posy - { 0, 1, 0, 0, 0, -1, 0}, //negy - { 0, 0, 1, 0, 1, 0, 0}, //posz - { 0, 0, -1, 0, 1, 0, 0}, //negz - }; - - if (!iSystem) - { - return; - } - - CRenderer* r = gRenDev; - CCamera prevCamera = r->GetCamera(); - CCamera tmpCamera = prevCamera; - - I3DEngine* eng = gEnv->p3DEngine; - float fMinDist = 0.25f; - - Vec3 vForward = Vec3(sCubeVector[side][0], sCubeVector[side][1], sCubeVector[side][2]); - Vec3 vUp = Vec3(sCubeVector[side][3], sCubeVector[side][4], sCubeVector[side][5]); - Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[side][6])); - - // magic orientation we use in engine - Matrix33 matScale = Matrix33::CreateScale(Vec3(1, -1, 1)); - matRot = matScale * matRot; - - tmpCamera.SetMatrix(Matrix34(matRot, Pos)); - tmpCamera.SetFrustum(tex_size, tex_size, 90.0f * gf_PI / 180.0f, fMinDist, fMaxDist); - int nPersFlags = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags; - int nPersFlags2 = r->m_RP.m_PersFlags2; - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags |= /*RBPF_MIRRORCAMERA | */ RBPF_MIRRORCULL | RBPF_DRAWTOTEXTURE | RBPF_ENCODE_HDR; - int nOldZ = CRenderer::CV_r_usezpass; - CRenderer::CV_r_usezpass = 0; - - r->RT_SetViewport(0, 0, tex_size, tex_size); - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log) - { - r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. DrawLowDetail .. (DrawCubeSide %d)\n", side); - } -#endif - - eng->RenderWorld(SHDF_ALLOWHDR | SHDF_NOASYNC | SHDF_STREAM_SYNC, SRenderingPassInfo::CreateGeneralPassRenderingInfo(tmpCamera), __FUNCTION__); - -#ifdef DO_RENDERLOG - if (CRenderer::CV_r_log) - { - r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. End DrawLowDetail .. (DrawCubeSide %d)\n", side); - } -#endif - - r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags = nPersFlags; - r->m_RP.m_PersFlags2 = nPersFlags2; - r->SetCamera(prevCamera); - CRenderer::CV_r_usezpass = nOldZ; -} - -bool CTexture::GenerateMipMaps(bool bSetOrthoProj, bool bUseHW, bool bNormalMap) -{ - if (!(GetFlags() & FT_FORCE_MIPS) - || bSetOrthoProj || !bUseHW || bNormalMap) //todo: implement - { - return false; - } - - PROFILE_LABEL_SCOPE("GENERATE_MIPS"); - PROFILE_SHADER_SCOPE; - - CDeviceTexture* pTex = GetDevTexture(); - if (!pTex) - { - return false; - } - - D3D11_TEXTURE2D_DESC pDesc; - pTex->Get2DTexture()->GetDesc(&pDesc); - - // all d3d11 devices support autogenmipmaps - if (m_pRenderTargetData) - { - gcpRendD3D->GetDeviceContext().GenerateMips(m_pDeviceShaderResource); - } - - return true; -} - -void CTexture::DestroyZMaps() -{ - //SAFE_RELEASE(s_ptexZTarget); -} - -void CTexture::GenerateZMaps() -{ - if (gcpRendD3D->FX_GetEnabledGmemPath(nullptr)) - { - // Custom Z-Target for GMEM render path should already be set - assert(s_ptexZTarget == CTexture::s_ptexGmemStenLinDepth); - return; - } - - int nWidth = gcpRendD3D->m_MainViewport.nWidth; //m_d3dsdBackBuffer.Width; - int nHeight = gcpRendD3D->m_MainViewport.nHeight; //m_d3dsdBackBuffer.Height; - ETEX_Format eTFZ = CTexture::s_eTFZ; - uint32 nFlags = FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_DONT_RELEASE; - if (CRenderer::CV_r_msaa) - { - nFlags |= FT_USAGE_MSAA; - } - if (!s_ptexZTarget) - { - s_ptexZTarget = CreateRenderTarget("$ZTarget", nWidth, nHeight, Clr_White, eTT_2D, nFlags, eTFZ); - s_ptexFurZTarget = CreateRenderTarget("$FurZTarget", nWidth, nHeight, Clr_White, eTT_2D, nFlags, eTFZ); - } - else - { - s_ptexZTarget->m_nFlags = nFlags; - s_ptexZTarget->m_nWidth = nWidth; - s_ptexZTarget->m_nHeight = nHeight; - s_ptexZTarget->CreateRenderTarget(eTFZ, Clr_White); - - s_ptexFurZTarget->m_nFlags = nFlags; - s_ptexFurZTarget->m_nWidth = nWidth; - s_ptexFurZTarget->m_nHeight = nHeight; - s_ptexFurZTarget->CreateRenderTarget(eTFZ, Clr_White); - } -} - -void CTexture::DestroySceneMap() -{ - //SAFE_RELEASE(s_ptexSceneTarget); -} - -void CTexture::GenerateSceneMap(ETEX_Format eTF) -{ - const int32 nWidth = gcpRendD3D->GetWidth(); - const int32 nHeight = gcpRendD3D->GetHeight(); - uint32 nFlags = FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_USAGE_UNORDERED_ACCESS; - nFlags |= FT_USAGE_UNORDERED_ACCESS; - - if (!s_ptexSceneTarget) - { - s_ptexSceneTarget = CreateRenderTarget("$SceneTarget", nWidth, nHeight, Clr_Empty, eTT_2D, nFlags, eTF, TO_SCENE_TARGET); - } - else - { - s_ptexSceneTarget->m_nFlags = nFlags; - s_ptexSceneTarget->m_nWidth = nWidth; - s_ptexSceneTarget->m_nHeight = nHeight; - s_ptexSceneTarget->CreateRenderTarget(eTF, Clr_Empty); - } - - nFlags &= ~(FT_USAGE_MSAA | FT_USAGE_UNORDERED_ACCESS); - - // This RT used for all post processes passes and shadow mask (group 0) as well - ETEX_Format backbufferFormat; - - static ICVar* DolbyCvar = gEnv->pConsole->GetCVar("r_HDRDolby"); - - if (DolbyCvar->GetIVal() == 1) - { - backbufferFormat = eTF_R10G10B10A2; - } - else - { - backbufferFormat = eTF_R8G8B8A8; - } - - // This RT used for all post processes passes and shadow mask (group 0) as well - if (!CTexture::IsTextureExist(s_ptexBackBuffer)) - { - s_ptexBackBuffer = CreateRenderTarget("$BackBuffer", nWidth, nHeight, Clr_Transparent, eTT_2D, nFlags, backbufferFormat, TO_BACKBUFFERMAP); - } - else - { - s_ptexBackBuffer->m_nFlags = nFlags; - s_ptexBackBuffer->m_nWidth = nWidth; - s_ptexBackBuffer->m_nHeight = nHeight; - s_ptexBackBuffer->CreateRenderTarget(backbufferFormat, Clr_Transparent); - } - - nFlags &= ~(FT_USAGE_MSAA | FT_USAGE_UNORDERED_ACCESS); - - // This RT can be used by the Render3DModelMgr if the buffer needs to be persistent - if (CRenderer::CV_r_UsePersistentRTForModelHUD > 0) - { - if (!CTexture::IsTextureExist(s_ptexModelHudBuffer)) - { - s_ptexModelHudBuffer = CreateRenderTarget("$ModelHUD", nWidth, nHeight, Clr_Transparent, eTT_2D, nFlags, eTF_R8G8B8A8, TO_BACKBUFFERMAP); - } - else - { - s_ptexModelHudBuffer->m_nFlags = nFlags; - s_ptexModelHudBuffer->m_nWidth = nWidth; - s_ptexModelHudBuffer->m_nHeight = nHeight; - s_ptexModelHudBuffer->CreateRenderTarget(eTF_R8G8B8A8, Clr_Transparent); - } - } -} - -void CTexture::GenerateCachedShadowMaps() -{ - StaticArray nResolutions = gRenDev->GetCachedShadowsResolution(); - - // parse shadow resolutions from cvar - { - int nCurPos = 0; - int nCurRes = 0; - - string strResolutions = gEnv->pConsole->GetCVar("r_ShadowsCacheResolutions")->GetString(); - string strCurRes = strResolutions.Tokenize(" ,;-\t", nCurPos); - - if (!strCurRes.empty()) - { - nResolutions.fill(0); - - while (!strCurRes.empty()) - { - int nRes = atoi(strCurRes.c_str()); - nResolutions[nCurRes] = clamp_tpl(nRes, 0, 16384); - - strCurRes = strResolutions.Tokenize(" ,;-\t", nCurPos); - ++nCurRes; - } - - gRenDev->SetCachedShadowsResolution(nResolutions); - } - } - - const ETEX_Format texFormat = gEnv->pConsole->GetCVar("r_ShadowsCacheFormat")->GetIVal() == 0 ? eTF_D32F : eTF_D16; - const int cachedShadowsStart = clamp_tpl(CRenderer::CV_r_ShadowsCache, 0, MAX_GSM_LODS_NUM - 1); - - int gsmCascadeCount = gEnv->pSystem->GetConfigSpec() == CONFIG_LOW_SPEC ? 4 : 5; - if (ICVar* pGsmLodsVar = gEnv->pConsole->GetCVar("e_GsmLodsNum")) - { - gsmCascadeCount = pGsmLodsVar->GetIVal(); - } - const int cachedCascadesCount = cachedShadowsStart > 0 ? clamp_tpl(gsmCascadeCount - cachedShadowsStart + 1, 0, MAX_GSM_LODS_NUM) : 0; - - for (int i = 0; i < MAX_GSM_LODS_NUM; ++i) - { - CTexture*& pTx = s_ptexCachedShadowMap[i]; - - if (!pTx) - { - char szName[32]; - sprintf_s(szName, "CachedShadowMap_%d", i); - - uint32 flags = FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_DEPTHSTENCIL | FT_USE_HTILE; - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_13 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) - #endif - pTx = CTexture::CreateTextureObject(szName, nResolutions[i], nResolutions[i], 1, eTT_2D, flags, texFormat); - } - - pTx->Invalidate(nResolutions[i], nResolutions[i], texFormat); - - // delete existing texture in case it's not needed anymore - if (CTexture::IsTextureExist(pTx) && nResolutions[i] == 0) - { - pTx->ReleaseDeviceTexture(false); - } - - // allocate texture directly for all cached cascades - if (!CTexture::IsTextureExist(pTx) && nResolutions[i] > 0 && i < cachedCascadesCount) - { - CryLog("Allocating shadow map cache %d x %d: %.2f MB", nResolutions[i], nResolutions[i], sqr(nResolutions[i]) * CTexture::BytesPerBlock(texFormat) / (1024.f * 1024.f)); - pTx->CreateRenderTarget(texFormat, Clr_FarPlane); - } - } - - // height map AO - if (CRenderer::CV_r_HeightMapAO) - { - const int nTexRes = (int)clamp_tpl(CRenderer::CV_r_HeightMapAOResolution, 0.f, 16384.f); - - if (!s_ptexHeightMapAODepth[0]) - { - s_ptexHeightMapAODepth[0] = CTexture::CreateTextureObject("HeightMapAO_Depth_0", nTexRes, nTexRes, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_DEPTHSTENCIL | FT_USE_HTILE, eTF_D16); - s_ptexHeightMapAODepth[1] = CTexture::CreateTextureObject("HeightMapAO_Depth_1", nTexRes, nTexRes, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_FORCE_MIPS, eTF_R16); - } - - s_ptexHeightMapAODepth[0]->Invalidate(nTexRes, nTexRes, eTF_D16); - s_ptexHeightMapAODepth[1]->Invalidate(nTexRes, nTexRes, eTF_R16); - - if (!CTexture::IsTextureExist(s_ptexHeightMapAODepth[0]) && nTexRes > 0) - { - s_ptexHeightMapAODepth[0]->CreateRenderTarget(eTF_D16, Clr_FarPlane); - s_ptexHeightMapAODepth[1]->CreateRenderTarget(eTF_R16, Clr_FarPlane); - } - } - - if (ShadowFrustumMGPUCache* pShadowMGPUCache = gRenDev->GetShadowFrustumMGPUCache()) - { - pShadowMGPUCache->nUpdateMaskRT = 0; - pShadowMGPUCache->nUpdateMaskMT = 0; - } -} - -void CTexture::DestroyCachedShadowMaps() -{ - for (int i = 0; i < MAX_GSM_LODS_NUM; ++i) - { - SAFE_RELEASE_FORCE(s_ptexCachedShadowMap[i]); - } - - SAFE_RELEASE_FORCE(s_ptexHeightMapAO[0]); - SAFE_RELEASE_FORCE(s_ptexHeightMapAO[1]); -} - -void CTexture::GenerateNearestShadowMap() -{ - const int texResolution = CRenderer::CV_r_ShadowsNearestMapResolution; - const ETEX_Format texFormat = eTF_D32F; - s_ptexNearestShadowMap = CTexture::CreateTextureObject("NearestShadowMap", texResolution, texResolution, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_DEPTHSTENCIL | FT_USE_HTILE, texFormat); -} - -void CTexture::DestroyNearestShadowMap() -{ - if (s_ptexNearestShadowMap) - { - SAFE_RELEASE_FORCE(s_ptexNearestShadowMap); - } -} - -bool SDynTexture::RT_Update(int nNewWidth, int nNewHeight) -{ - AZ_Assert(gRenDev->m_pRT->IsRenderThread(), ("Error - Cannot call SDynTexture::RT_Update from any thread that is not the primary render thread!")); - - Unlink(); - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - if (nNewWidth != m_nReqWidth || nNewHeight != m_nReqHeight) - { - if (m_pTexture) - { - ReleaseDynamicRT(false); - } - m_pTexture = NULL; - - m_nReqWidth = nNewWidth; - m_nReqHeight = nNewHeight; - - AdjustRealSize(); - } - - if (!m_pTexture) - { - int nNeedSpace = CTexture::TextureDataSize(m_nWidth, m_nHeight, 1, 1, 1, m_eTF); - if (m_eTT == eTT_Cube) - { - nNeedSpace *= 6; - } - SDynTexture* pTX = SDynTexture::s_Root.m_Prev; - const uint32 maxDynamicTextureMemory = SDynTexture::s_CurDynTexMaxSize * 1024u * 1024u; - if (nNeedSpace + s_nMemoryOccupied > maxDynamicTextureMemory) - { - // Commit any render target binds/unbinds in case they are still waiting to be set or unset in a shadow state - gcpRendD3D->FX_SetActiveRenderTargets(); - - m_pTexture = GetDynamicRT(); - if (!m_pTexture) - { - bool bFreed = FreeTextures(true, nNeedSpace); - if (!bFreed) - { - bFreed = FreeTextures(false, nNeedSpace); - } - - if (!bFreed) - { - pTX = SDynTexture::s_Root.m_Next; - int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_nFrameUpdateID - 1; - while (nNeedSpace + s_nMemoryOccupied > maxDynamicTextureMemory) - { - if (pTX == &SDynTexture::s_Root) - { - static int nThrash; - if (nThrash != nFrame) - { - nThrash = nFrame; - iLog->Log("Error: Dynamic textures thrashing (try to increase texture pool size - r_DynTexMaxSize)..."); - } - break; - } - SDynTexture* pNext = pTX->m_Next; - // We cannot unload locked texture or texture used in current frame - // Better to increase pool size temporarily - if (pTX->m_pTexture && !pTX->m_pTexture->IsActiveRenderTarget()) - { - if (pTX->m_pTexture->m_nAccessFrameID < nFrame && pTX->m_pTexture->m_nUpdateFrameID < nFrame && !pTX->m_bLocked) - { - pTX->ReleaseDynamicRT(true); - } - } - pTX = pNext; - } - } - } - } - } - if (!m_pTexture) - { - m_pTexture = CreateDynamicRT(); - } - - assert(s_iNumTextureBytesCheckedOut + s_iNumTextureBytesCheckedIn == s_nMemoryOccupied); - - if (m_pTexture) - { - Link(); - return true; - } - return false; -} - -bool SDynTexture::RT_SetRT(int nRT, int nWidth, int nHeight, bool bPush, bool bScreenVP) -{ - Update(m_nWidth, m_nHeight); - - SDepthTexture* pDepthSurf = nWidth > 0 ? gcpRendD3D->FX_GetDepthSurface(nWidth, nHeight, false) : &gcpRendD3D->m_DepthBufferOrig; - - assert(m_pTexture); - if (m_pTexture) - { - if (bPush) - { - return gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf, -1, bScreenVP); - } - else - { - return gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf, false, -1, bScreenVP); - } - } - return false; -} - -bool SDynTexture::SetRT(int nRT, bool bPush, SDepthTexture* pDepthSurf, bool bScreenVP) -{ - Update(m_nWidth, m_nHeight); - - assert(m_pTexture); - if (m_pTexture) - { - if (bPush) - { - return gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf, -1, bScreenVP); - } - else - { - return gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf, false, -1, bScreenVP); - } - } - return false; -} - -bool SDynTexture::RestoreRT(int nRT, bool bPop) -{ - if (bPop) - { - return gcpRendD3D->FX_PopRenderTarget(nRT); - } - else - { - return gcpRendD3D->FX_RestoreRenderTarget(nRT); - } -} - -bool SDynTexture::ClearRT() -{ - gcpRendD3D->FX_ClearTarget(m_pTexture); - return true; -} - -bool SDynTexture2::ClearRT() -{ - gcpRendD3D->FX_ClearTarget(m_pTexture); - return true; -} - -bool SDynTexture2::SetRT(int nRT, bool bPush, SDepthTexture* pDepthSurf, [[maybe_unused]] bool bScreenVP) -{ - Update(m_nWidth, m_nHeight); - - assert(m_pTexture); - if (m_pTexture) - { - bool bRes = false; - if (bPush) - { - bRes = gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf); - } - else - { - bRes = gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf); - } - SetRectStates(); - gcpRendD3D->FX_Commit(); - } - return false; -} - -bool SDynTexture2::SetRectStates() -{ - assert(m_pTexture); - gcpRendD3D->RT_SetViewport(m_nX, m_nY, m_nWidth, m_nHeight); - gcpRendD3D->EF_Scissor(true, m_nX, m_nY, m_nWidth, m_nHeight); - return true; -} - -bool SDynTexture2::RestoreRT(int nRT, bool bPop) -{ - bool bRes = false; - gcpRendD3D->EF_Scissor(false, m_nX, m_nY, m_nWidth, m_nHeight); - if (bPop) - { - bRes = gcpRendD3D->FX_PopRenderTarget(nRT); - } - else - { - bRes = gcpRendD3D->FX_RestoreRenderTarget(nRT); - } - gcpRendD3D->FX_Commit(); - - return bRes; -} - -void _DrawText(ISystem* pSystem, int x, int y, const float fScale, const char* format, ...); - -#if !defined(_RELEASE) -static int __cdecl RTCallback(const VOID* arg1, const VOID* arg2) -{ - CTexture* p1 = *(CTexture**)arg1; - CTexture* p2 = *(CTexture**)arg2; - - // show big textures first - int nSize1 = p1->GetDataSize(); - int nSize2 = p2->GetDataSize(); - if (nSize1 > nSize2) - { - return -1; - } - else if (nSize2 > nSize1) - { - return 1; - } - - return strcmp(p1->GetName(), p2->GetName()); -} -#endif - -void CD3D9Renderer::DrawAllDynTextures([[maybe_unused]] const char* szFilter, [[maybe_unused]] const bool bLogNames, [[maybe_unused]] const bool bOnlyIfUsedThisFrame) -{ -#ifndef _RELEASE - SDynTexture2::TextureSet2Itor itor; - char name[256]; //, nm[256]; - cry_strcpy(name, szFilter); - azstrlwr(name, AZ_ARRAY_SIZE(name)); - TArray UsedRT; - int nMaxCount = CV_r_ShowDynTexturesMaxCount; - - float width = 800; - float height = 600; - float fArrDim = max(1.f, sqrtf((float)nMaxCount)); - float fPicDimX = width / fArrDim; - float fPicDimY = height / fArrDim; - float x = 0; - float y = 0; - - TransformationMatrices backupSceneMatrices; - - Set2DMode(static_cast(width), static_cast(height), backupSceneMatrices); - - EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); - EF_SetSrgbWrite(false); - if (name[0] == '*' && !name[1]) - { - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - ResourcesMapItor it; - for (it = pRL->m_RMap.begin(); it != pRL->m_RMap.end(); it++) - { - CTexture* tp = (CTexture*)it->second; - if (tp && !tp->IsNoTexture()) - { - if ((tp->GetFlags() & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) && tp->GetDevTexture()) - { - UsedRT.AddElem(tp); - } - } - } - } - else - { - SResourceContainer* pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName()); - ResourcesMapItor it; - for (it = pRL->m_RMap.begin(); it != pRL->m_RMap.end(); it++) - { - CTexture* tp = (CTexture*)it->second; - if (!tp || tp->IsNoTexture()) - { - continue; - } - if ((tp->GetFlags() & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) && tp->GetDevTexture()) - { - char nameBuffer[128]; - cry_strcpy(nameBuffer, tp->GetName()); - azstrlwr(nameBuffer, AZ_ARRAY_SIZE(nameBuffer)); - if (CryStringUtils::MatchWildcard(nameBuffer, name)) - { - UsedRT.AddElem(tp); - } - } - } - } - if (UsedRT.Num() > 1) - { - qsort(&UsedRT[0], UsedRT.Num(), sizeof(CTexture*), RTCallback); - } - fPicDimX = width / fArrDim; - fPicDimY = height / fArrDim; - x = 0; - y = 0; - for (uint32 i = 0; i < UsedRT.Num(); i++) - { - SetState(GS_NODEPTHTEST); - CTexture* tp = UsedRT[i]; - int nSavedAccessFrameID = tp->m_nAccessFrameID; - - if (bOnlyIfUsedThisFrame) - { - if (tp->m_nUpdateFrameID < m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameUpdateID - 2) - { - continue; - } - } - - if (tp->GetTextureType() == eTT_2D) - { - Draw2dImage(x, y, fPicDimX - 2, fPicDimY - 2, tp->GetID(), 0, 1, 1, 0, 0); - } - - tp->m_nAccessFrameID = nSavedAccessFrameID; - - const char* pTexName = tp->GetName(); - char nameBuffer[128]; - memset(nameBuffer, 0, sizeof nameBuffer); - for (int iStr = 0, jStr = 0; pTexName[iStr] && jStr < sizeof nameBuffer - 1; ++iStr) - { - if (pTexName[iStr] == '$') - { - nameBuffer[jStr] = '$'; - nameBuffer[jStr + 1] = '$'; - jStr += 2; - } - else - { - nameBuffer[jStr] = pTexName[iStr]; - ++jStr; - } - } - nameBuffer[sizeof nameBuffer - 1] = 0; - pTexName = nameBuffer; - - int32 nPosX = (int32)ScaleCoordX(x); - int32 nPosY = (int32)ScaleCoordY(y); - _DrawText(iSystem, nPosX, nPosY, 1.0f, "%8s", pTexName); - _DrawText(iSystem, nPosX, nPosY += 10, 1.0f, "%d-%d", tp->m_nUpdateFrameID, tp->m_nAccessFrameID); - _DrawText(iSystem, nPosX, nPosY += 10, 1.0f, "%dx%d", tp->GetWidth(), tp->GetHeight()); - - if (bLogNames) - { - iLog->Log("Mem:%d %dx%d Type:%s Format:%s (%s)", - tp->GetDeviceDataSize(), tp->GetWidth(), tp->GetHeight(), tp->NameForTextureType(tp->GetTextureType()), tp->NameForTextureFormat(tp->GetDstFormat()), tp->GetName()); - } - - x += fPicDimX; - if (x >= width - 10) - { - x = 0; - y += fPicDimY; - } - } - - Unset2DMode(backupSceneMatrices); - - RT_RenderTextMessages(); -#endif -} - -void CTexture::ReleaseSystemTargets() -{ - CTexture::DestroyHDRMaps(); - CTexture::DestroySceneMap(); - CTexture::DestroyCachedShadowMaps(); - CTexture::DestroyNearestShadowMap(); - - if (CDeferredShading::Instance().IsValid()) - { - CDeferredShading::Instance().DestroyDeferredMaps(); - } - - PostProcessUtils().Release(); - - SAFE_RELEASE_FORCE(s_ptexWaterOcean); - SAFE_RELEASE_FORCE(s_ptexWaterVolumeTemp); - SAFE_RELEASE_FORCE(s_ptexWaterRipplesDDN); - - SAFE_RELEASE_FORCE(s_ptexSceneNormalsMap); - SAFE_RELEASE_FORCE(s_ptexSceneNormalsBent); - SAFE_RELEASE_FORCE(s_ptexAOColorBleed); - SAFE_RELEASE_FORCE(s_ptexSceneDiffuse); - SAFE_RELEASE_FORCE(s_ptexSceneSpecular); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_10 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - SAFE_RELEASE_FORCE(s_ptexSceneDiffuseAccMap); - SAFE_RELEASE_FORCE(s_ptexSceneSpecularAccMap); - SAFE_RELEASE_FORCE(s_ptexBackBuffer); - SAFE_RELEASE_FORCE(s_ptexSceneTarget); - SAFE_RELEASE_FORCE(s_ptexZTargetScaled); - SAFE_RELEASE_FORCE(s_ptexZTargetScaled2); - SAFE_RELEASE_FORCE(s_ptexAmbientLookup); - SAFE_RELEASE_FORCE(s_ptexDepthBufferQuarter); - - gcpRendD3D->m_bSystemTargetsInit = 0; -} - -void CTexture::ReleaseMiscTargets() -{ - if (gcpRendD3D->m_pColorGradingControllerD3D) - { - gcpRendD3D->m_pColorGradingControllerD3D->ReleaseTextures(); - } -} - -void CTexture::CreateSystemTargets() -{ - if (!gcpRendD3D->m_bSystemTargetsInit) - { - - - gcpRendD3D->m_bSystemTargetsInit = 1; - - ETEX_Format eTF = (gcpRendD3D->m_RP.m_bUseHDR && gcpRendD3D->m_nHDRType == 1) ? eTF_R16G16B16A16F : eTF_R8G8B8A8; - - // Create HDR targets - CTexture::GenerateHDRMaps(); - - // Create scene targets - CTexture::GenerateSceneMap(eTF); - - // Create ZTarget - CTexture::GenerateZMaps(); - - // Allocate cached shadow maps if required - CTexture::GenerateCachedShadowMaps(); - - // Allocate the nearest shadow map if required - CTexture::GenerateNearestShadowMap(); - - // Create deferred lighting targets - if (CDeferredShading::Instance().IsValid()) - { - CDeferredShading::Instance().CreateDeferredMaps(); - } - - if (CRenderer::CV_r_DeferredShadingTiled > 0) - { - gcpRendD3D->GetTiledShading().CreateResources(); - } - - gcpRendD3D->GetVolumetricFog().CreateResources(); - - // Create post effects targets - PostProcessUtils().Create(); - } -} - -void CTexture::CopySliceChain(CDeviceTexture* const pDevTexture, int ownerMips, int nDstSlice, int nDstMip, CDeviceTexture* pSrcDevTex, int nSrcSlice, int nSrcMip, int nSrcMips, int nNumMips) -{ - assert(pSrcDevTex && pDevTexture); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_11 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - - D3DBaseTexture* pDstResource = pDevTexture->GetBaseTexture(); - D3DBaseTexture* pSrcResource = pSrcDevTex->GetBaseTexture(); - -#ifndef _RELEASE - if (!pDstResource) - { - __debugbreak(); - } - if (!pSrcResource) - { - __debugbreak(); - } -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURE_CPP_SECTION_12 - #include AZ_RESTRICTED_FILE(D3DTexture_cpp) -#endif - assert(nSrcMip >= 0 && nDstMip >= 0); - for (int i = 0; i < nNumMips; ++i) - { - #if defined(DEVICE_SUPPORTS_D3D11_1) - gcpRendD3D->GetDeviceContext().CopySubresourceRegion1( - pDstResource, - D3D11CalcSubresource(nDstMip + i, nDstSlice, ownerMips), - 0, 0, 0, - pSrcResource, - D3D11CalcSubresource(nSrcMip + i, nSrcSlice, nSrcMips), - NULL, - D3D11_COPY_NO_OVERWRITE); - #else - gcpRendD3D->GetDeviceContext().CopySubresourceRegion( - pDstResource, - D3D11CalcSubresource(nDstMip + i, nDstSlice, ownerMips), - 0, 0, 0, - pSrcResource, - D3D11CalcSubresource(nSrcMip + i, nSrcSlice, nSrcMips), - NULL); - #endif - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTextureStreamPool.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DTextureStreamPool.cpp deleted file mode 100644 index 015eebc8d5..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTextureStreamPool.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "../Common/Textures/TextureStreamPool.h" - -#include "DriverD3D.h" - -#if !defined(CHK_RENDTH) -# define CHK_RENDTH assert(gRenDev->m_pRT->IsRenderThread()) -#endif -#if !defined(CHK_MAINTH) -# define CHK_MAINTH assert(gRenDev->m_pRT->IsMainThread()) -#endif -#if !defined(CHK_MAINORRENDTH) -# define CHK_MAINORRENDTH assert(gRenDev->m_pRT->IsMainThread() || gRenDev->m_pRT->IsRenderThread()) -#endif - -CryCriticalSection STexPoolItemHdr::s_sSyncLock; - -bool STexPoolItem::IsStillUsedByGPU(uint32 nTick) -{ - CDeviceTexture* pDeviceTexture = m_pDevTexture; - if (pDeviceTexture) - { - CHK_MAINORRENDTH; - } - return (nTick - m_nFreeTick) < 4; -} - -STexPoolItem::STexPoolItem (STexPool* pOwner, CDeviceTexture* pDevTexture, size_t devSize) - : m_pOwner(pOwner) - , m_pTex(NULL) - , m_pDevTexture(pDevTexture) - , m_nDeviceTexSize(devSize) - , m_nFreeTick(0) - , m_nActiveLod(0) -{ - assert (pDevTexture); - ++pOwner->m_nItems; -} - -STexPoolItem::~STexPoolItem() -{ - assert (m_pDevTexture); - if (m_pOwner) - { - --m_pOwner->m_nItems; - if (IsFree()) - { - --m_pOwner->m_nItemsFree; - } - } - Unlink(); - UnlinkFree(); - - m_pDevTexture->Unbind(); - m_pDevTexture->Release(); -} - -CTextureStreamPoolMgr::CTextureStreamPoolMgr() -{ - m_FreeTexPoolItems.m_NextFree = &m_FreeTexPoolItems; - m_FreeTexPoolItems.m_PrevFree = &m_FreeTexPoolItems; - - m_nDeviceMemReserved = 0; - m_nDeviceMemInUse = 0; - -#ifdef TEXSTRM_USE_FREEPOOL - m_nFreePoolBegin = 0; - m_nFreePoolEnd = 0; -#endif - - m_nTick = 0; - -#if !defined(_RELEASE) - m_bComputeStats = false; -#endif -} - -CTextureStreamPoolMgr::~CTextureStreamPoolMgr() -{ - Flush(); -} - -void CTextureStreamPoolMgr::Flush() -{ - AUTO_LOCK(STexPoolItem::s_sSyncLock); - - FlushFree(); - - // Free pools first, as that will attempt to remove streamed textures in release, which will end up - // in the free list. - - for (TexturePoolMap::iterator it = m_TexturesPools.begin(), itEnd = m_TexturesPools.end(); it != itEnd; ++it) - { - SAFE_DELETE(it->second); - } - stl::free_container(m_TexturesPools); - - // Now nuke the free items. - - FlushFree(); -#ifdef TEXSTRM_USE_FREEPOOL - while (m_nFreePoolBegin != m_nFreePoolEnd) - { - assert (m_nFreePoolEnd < sizeof(m_FreePool) / sizeof(m_FreePool[0])); - void* p = m_FreePool[m_nFreePoolBegin]; - m_nFreePoolBegin = (m_nFreePoolBegin + 1) % MaxFreePool; - ::operator delete(p); - } -#endif -} - -STexPool* CTextureStreamPoolMgr::GetPool(int nWidth, int nHeight, int nMips, int nArraySize, ETEX_Format eTF, bool bIsSRGB, ETEX_Type eTT) -{ - D3DFormat d3dFmt = CTexture::DeviceFormatFromTexFormat(eTF); - if (bIsSRGB) - { - d3dFmt = CTexture::ConvertToSRGBFmt(d3dFmt); - } - - TexturePoolKey poolKey((uint16)nWidth, (uint16)nHeight, d3dFmt, (uint8)eTT, (uint8)nMips, (uint16)nArraySize); - - TexturePoolMap::iterator it = m_TexturesPools.find(poolKey); - if (it != m_TexturesPools.end()) - { - return it->second; - } - - return NULL; -} - -STexPoolItem* CTextureStreamPoolMgr::GetPoolItem(int nWidth, int nHeight, int nMips, int nArraySize, ETEX_Format eTF, bool bIsSRGB, ETEX_Type eTT, bool bShouldBeCreated, const char* sName, STextureInfo* pTI, bool bCanCreate, bool bWaitForIdle) -{ - D3DFormat d3dFmt = CTexture::DeviceFormatFromTexFormat(eTF); - if (bIsSRGB) - { - d3dFmt = CTexture::ConvertToSRGBFmt(d3dFmt); - } - - STexPool* pPool = CreatePool(nWidth, nHeight, nMips, nArraySize, d3dFmt, eTT); - if (!pPool) - { - return NULL; - } - - AUTO_LOCK(STexPoolItem::s_sSyncLock); - - STexPoolItemHdr* pITH = &m_FreeTexPoolItems; - STexPoolItem* pIT = static_cast(pITH); - - bool bFoundACoolingMatch = false; - -#ifndef TSP_GC_ALL_ITEMS - - if (!pTI) - { - pITH = m_FreeTexPoolItems.m_PrevFree; - pIT = static_cast(pITH); - - // Try to find empty item in the pool - while (pITH != &m_FreeTexPoolItems) - { - if (pIT->m_pOwner == pPool) - { - if (!bWaitForIdle || !pIT->IsStillUsedByGPU(m_nTick)) - { - break; - } - - bFoundACoolingMatch = true; - } - - pITH = pITH->m_PrevFree; - pIT = static_cast(pITH); - } - } - -#endif - - if (pITH != &m_FreeTexPoolItems) - { - pIT->UnlinkFree(); -#if defined(DO_RENDERLOG) - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logTexStreaming == 2) - { - gRenDev->LogStrv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Remove from FreePool '%s', [%d x %d], Size: %d\n", sName, pIT->m_pOwner->m_Width, pIT->m_pOwner->m_Height, pIT->m_pOwner->m_Size); - } -#endif - -#if !defined(_RELEASE) - ++m_frameStats.nSoftCreates; -#endif - - --pIT->m_pOwner->m_nItemsFree; - } - else - { - if (!bCanCreate) - { - return NULL; - } - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) - if (bFoundACoolingMatch) - { - // Really, really, don't want to create a texture if one will be available soon - if (!bShouldBeCreated) - { - return NULL; - } - } -#endif - - // Create API texture for the item in DEFAULT pool - const char* poolTextureName = "StreamingTexturePool"; - - HRESULT h = S_OK; - CDeviceTexture* pDevTex = NULL; - if (eTT != eTT_Cube) - { - h = gcpRendD3D->m_DevMan.Create2DTexture(poolTextureName, nWidth, nHeight, nMips, nArraySize, STREAMED_TEXTURE_USAGE, Clr_Transparent, d3dFmt, D3DPOOL_DEFAULT, &pDevTex, pTI, bShouldBeCreated); - } - else - { - h = gcpRendD3D->m_DevMan.CreateCubeTexture(poolTextureName, nWidth, nMips, 1, STREAMED_TEXTURE_USAGE, Clr_Transparent, d3dFmt, D3DPOOL_DEFAULT, &pDevTex, pTI, bShouldBeCreated); - } - if (FAILED(h) || !pDevTex) - { - return NULL; - } - -#ifdef TEXSTRM_USE_FREEPOOL - if (m_nFreePoolBegin != m_nFreePoolEnd) - { - assert (m_nFreePoolBegin < (sizeof(m_FreePool) / sizeof(m_FreePool[0]))); - - void* p = m_FreePool[m_nFreePoolBegin]; - m_nFreePoolBegin = (m_nFreePoolBegin + 1) % MaxFreePool; - pIT = new (p) STexPoolItem(pPool, pDevTex, pPool->m_Size); - } - else -#endif - { - pIT = new STexPoolItem(pPool, pDevTex, pPool->m_Size); - } - - pIT->Link(&pPool->m_ItemsList); - CryInterlockedAddSize(&m_nDeviceMemReserved, (ptrdiff_t)pPool->m_Size); - -#if !defined(_RELEASE) - ++m_frameStats.nHardCreates; -#endif - } - - CryInterlockedAddSize(&m_nDeviceMemInUse, (ptrdiff_t)pIT->m_nDeviceTexSize); - - return pIT; -} - -void CTextureStreamPoolMgr::ReleaseItem(STexPoolItem* pItem) -{ - assert(!pItem->m_NextFree); - -#ifdef DO_RENDERLOG - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_logTexStreaming == 2) - { - const char* name = pItem->m_pTex ? pItem->m_pTex->GetSourceName() : ""; - gRenDev->LogStrv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Add to FreePool '%s', [%d x %d], Size: %d\n", name, pItem->m_pOwner->m_Width, pItem->m_pOwner->m_Height, pItem->m_pOwner->m_Size); - } -#endif - - CryInterlockedAddSize(&m_nDeviceMemInUse, -(ptrdiff_t)pItem->m_nDeviceTexSize); - - pItem->m_pTex = NULL; - pItem->m_nFreeTick = m_nTick; - pItem->LinkFree(&m_FreeTexPoolItems); - - ++pItem->m_pOwner->m_nItemsFree; - -#if !defined(_RELEASE) - ++m_frameStats.nSoftFrees; -#endif -} - -STexPool* CTextureStreamPoolMgr::CreatePool(int nWidth, int nHeight, int nMips, int nArraySize, D3DFormat eTF, ETEX_Type eTT) -{ - STexPool* pPool = NULL; - - TexturePoolKey poolKey((uint16)nWidth, (uint16)nHeight, eTF, (uint8)eTT, (uint8)nMips, (uint16)nArraySize); - - TexturePoolMap::iterator it = m_TexturesPools.find(poolKey); - if (it == m_TexturesPools.end()) - { - // Create new pool - pPool = new STexPool; - pPool->m_eTT = eTT; - pPool->m_eFormat = eTF; - pPool->m_Width = nWidth; - pPool->m_Height = nHeight; - pPool->m_nArraySize = nArraySize; - pPool->m_nMips = nMips; - pPool->m_Size = CDeviceTexture::TextureDataSize(nWidth, nHeight, 1, nMips, nArraySize * (eTT == eTT_Cube ? 6 : 1), CTexture::TexFormatFromDeviceFormat(eTF)); - - pPool->m_nItems = 0; - pPool->m_nItemsFree = 0; - - pPool->m_ItemsList.m_Next = &pPool->m_ItemsList; - pPool->m_ItemsList.m_Prev = &pPool->m_ItemsList; - - it = m_TexturesPools.insert(std::make_pair(poolKey, pPool)).first; - } - - return it->second; -} - -void CTextureStreamPoolMgr::FlushFree() -{ - STexPoolItemHdr* pITH = m_FreeTexPoolItems.m_PrevFree; - while (pITH != &m_FreeTexPoolItems) - { - STexPoolItemHdr* pITHNext = pITH->m_PrevFree; - STexPoolItem* pIT = static_cast(pITH); - - assert (!pIT->m_pTex); - CryInterlockedAddSize(&m_nDeviceMemReserved, -(ptrdiff_t)pIT->m_nDeviceTexSize); - -#ifdef TEXSTRM_USE_FREEPOOL - unsigned int nFreePoolSize = (m_nFreePoolEnd - m_nFreePoolBegin) % MaxFreePool; - if (nFreePoolSize < MaxFreePool - 1) // -1 to avoid needing a separate count - { - pIT->~STexPoolItem(); - m_FreePool[m_nFreePoolEnd] = pIT; - m_nFreePoolEnd = (m_nFreePoolEnd + 1) % MaxFreePool; - } - else -#endif - { - delete pIT; - } - - pITH = pITHNext; - } -} - -void CTextureStreamPoolMgr::GarbageCollect(size_t* nCurTexPoolSize, size_t nLowerPoolLimit, int nMaxItemsToFree) -{ - size_t nSize = nCurTexPoolSize ? *nCurTexPoolSize : 1024 * 1024 * 1024; - ptrdiff_t nFreed = 0; - - AUTO_LOCK(STexPoolItem::s_sSyncLock); - - STexPoolItemHdr* pITH = m_FreeTexPoolItems.m_PrevFree; - while (pITH != &m_FreeTexPoolItems) - { - STexPoolItemHdr* pITHNext = pITH->m_PrevFree; - - STexPoolItem* pIT = static_cast(pITH); - - if (!pIT->m_pTex) - { - pITH = pITHNext; - continue; - } - -#if defined(TEXSTRM_TEXTURECENTRIC_MEMORY) - if (pIT->m_pOwner->m_nItemsFree > 20 || pIT->m_pOwner->m_Width > 64 || pIT->m_pOwner->m_Height > 64) -#endif - { - if (!pIT->IsStillUsedByGPU(m_nTick)) - { - nSize -= pIT->m_nDeviceTexSize; - nFreed += (ptrdiff_t)pIT->m_nDeviceTexSize; - -#ifdef TEXSTRM_USE_FREEPOOL - unsigned int nFreePoolSize = (m_nFreePoolEnd - m_nFreePoolBegin) % MaxFreePool; - if (nFreePoolSize < MaxFreePool - 1) // -1 to avoid needing a separate count - { - pIT->~STexPoolItem(); - m_FreePool[m_nFreePoolEnd] = pIT; - m_nFreePoolEnd = (m_nFreePoolEnd + 1) % MaxFreePool; - } - else -#endif - { - delete pIT; - } - - --nMaxItemsToFree; - -#if !defined(_RELEASE) - ++m_frameStats.nHardFrees; -#endif - } - } - - pITH = pITHNext; - - // we release all textures immediately on consoles -#ifndef TSP_GC_ALL_ITEMS - if (nMaxItemsToFree <= 0 || nSize < nLowerPoolLimit) - { - break; - } -#endif - } - - CryInterlockedAddSize(&m_nDeviceMemReserved, -nFreed); - - CTexture::StreamValidateTexSize(); - - if (nCurTexPoolSize) - { - *nCurTexPoolSize = nSize; - } - -#if !defined(_RELEASE) - if (m_bComputeStats) - { - CryAutoLock lock(m_statsLock); - - m_poolStats.clear(); - - for (TexturePoolMap::iterator it = m_TexturesPools.begin(), itEnd = m_TexturesPools.end(); it != itEnd; ++it) - { - STexPool* pPool = it->second; - SPoolStats ps; - ps.nWidth = pPool->m_Width; - ps.nHeight = pPool->m_Height; - ps.nMips = pPool->m_nMips; - ps.nFormat = pPool->m_eFormat; - ps.eTT = pPool->m_eTT; - - ps.nInUse = pPool->m_nItems - pPool->m_nItemsFree; - ps.nFree = pPool->m_nItemsFree; - ps.nHardCreatesPerFrame = 0; - ps.nSoftCreatesPerFrame = 0; - - m_poolStats.push_back(ps); - } - } -#endif - - ++m_nTick; -} - -void CTextureStreamPoolMgr::GetMemoryUsage(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "Texture Pools"); - pSizer->AddObject(m_TexturesPools); -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexturesStreaming.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexturesStreaming.cpp deleted file mode 100644 index 53a62e3f45..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTexturesStreaming.cpp +++ /dev/null @@ -1,986 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DriverD3D.h" -#include "StringUtils.h" -#include - -#include "../Common/Textures/TextureStreamPool.h" - -// checks for MT-safety of called functions -#define D3D_CHK_RENDTH assert(gcpRendD3D->m_pRT->IsRenderThread()) -#define D3D_CHK_MAINTH assert(gcpRendD3D->m_pRT->IsMainThread()) -#define D3D_CHK_MAINORRENDTH assert(gRenDev->m_pRT->IsMainThread() || gRenDev->m_pRT->IsRenderThread()) - -void CTexture::InitStreamingDev() -{ - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DTEXTURESSTREAMING_CPP_SECTION_1 1 -#define D3DTEXTURESSTREAMING_CPP_SECTION_2 2 -#define D3DTEXTURESSTREAMING_CPP_SECTION_3 3 -#define D3DTEXTURESSTREAMING_CPP_SECTION_4 4 -#define D3DTEXTURESSTREAMING_CPP_SECTION_5 5 -#define D3DTEXTURESSTREAMING_CPP_SECTION_6 6 -#define D3DTEXTURESSTREAMING_CPP_SECTION_7 7 -#endif - -#if defined(TEXSTRM_DEFERRED_UPLOAD) - if (CRenderer::CV_r_texturesstreamingDeferred) - { - if (!s_pStreamDeferredCtx) - { - gcpRendD3D->GetDevice().CreateDeferredContext(0, &s_pStreamDeferredCtx); - } - } -#endif -} - -bool CTexture::IsStillUsedByGPU() -{ - CDeviceTexture* pDeviceTexture = m_pDevTexture; - if (pDeviceTexture) - { - D3D_CHK_RENDTH; - } - return false; -} - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - -bool CTexture::StreamPrepare_Platform() -{ - return true; -} - -#endif - - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif - -void CTexture::StreamExpandMip(const void* vpRawData, int nMip, int nBaseMipOffset, int nSideDelta) -{ - FUNCTION_PROFILER_RENDERER; - - const uint32 nCurMipWidth = (m_nWidth >> (nMip + nBaseMipOffset)); - const uint32 nCurMipHeight = (m_nHeight >> (nMip + nBaseMipOffset)); - - const STexMipHeader& mh = m_pFileTexMips->m_pMipHeader[nBaseMipOffset + nMip]; - - const byte* pRawData = (const byte*)vpRawData; - - const int nSides = StreamGetNumSlices(); - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - - const int nSrcSurfaceSize = CTexture::TextureDataSize(nCurMipWidth, nCurMipHeight, 1, 1, 1, m_eTFSrc, m_eSrcTileMode); - const int nSrcSidePitch = nSrcSurfaceSize + nSideDelta; - - if (mh.m_Mips && mh.m_SideSize > 0) - { - for (int iSide = 0; iSide < nSides; ++iSide) - { - SMipData* mp = &mh.m_Mips[iSide]; - if (mp) - { - if (!mp->DataArray) - { - mp->Init(mh.m_SideSize, Align(max(1, m_nWidth >> nMip), vMipAlign.x), Align(max(1, m_nHeight >> nMip), vMipAlign.y)); - } - - const byte* pRawSideData = pRawData + nSrcSidePitch * iSide; - CTexture::ExpandMipFromFile(&mp->DataArray[0], mh.m_SideSize, pRawSideData, nSrcSurfaceSize, m_eTFSrc); - } - } - } -} - -#ifdef TEXSTRM_ASYNC_TEXCOPY -void STexStreamOutState::CopyMips() -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - CTexture* tp = m_pTexture; - - if (m_nStartMip < MAX_MIP_LEVELS) - { - const int nOldMipOffset = m_nStartMip - tp->m_nMinMipVidUploaded; - const int nNumMips = tp->GetNumMipsNonVirtual() - m_nStartMip; -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - CTexture::StreamCopyMipsTexToTex(tp->m_pFileTexMips->m_pPoolItem, 0 + nOldMipOffset, m_pNewPoolItem, 0, nNumMips); -#endif - } - else - { - // Stream unload case - pull persistent mips into local memory - tp->StreamCopyMipsTexToMem(tp->m_nMips - tp->m_CacheFileHeader.m_nMipsPersistent, tp->m_nMips - 1, false, NULL); - } - - m_bDone = true; -} -#endif - -int CTexture::StreamTrim(int nToMip) -{ - FUNCTION_PROFILER_RENDERER; - D3D_CHK_RENDTH; - - if (IsUnloaded() || !IsStreamed() || IsStreaming()) - { - return 0; - } - - // clamp mip level - nToMip = max(0, min(nToMip, m_nMips - m_CacheFileHeader.m_nMipsPersistent)); - - if (m_nMinMipVidUploaded >= nToMip) - { - return 0; - } - - int nFreeSize = StreamComputeDevDataSize(m_nMinMipVidUploaded) - StreamComputeDevDataSize(nToMip); - -#ifndef _RELEASE - if (CRenderer::CV_r_TexturesStreamingDebug == 2) - { - iLog->Log("Shrinking texture: %s - From mip: %i, To mip: %i", m_SrcName.c_str(), m_nMinMipVidUploaded, GetRequiredMipNonVirtual()); - } -#endif - - STexPoolItem* pNewPoolItem = StreamGetPoolItem(nToMip, m_nMips - nToMip, false, false, true, true); - assert(pNewPoolItem != m_pFileTexMips->m_pPoolItem); - if (pNewPoolItem) - { - const int nOldMipOffset = nToMip - m_nMinMipVidUploaded; - const int nNumMips = GetNumMipsNonVirtual() - nToMip; - -#ifdef TEXSTRM_ASYNC_TEXCOPY - - bool bCopying = false; - - if (CanAsyncCopy() && (TryAddRef() > 0)) - { - STexStreamOutState* pStreamState = StreamState_AllocateOut(); - if (pStreamState) - { - pStreamState->m_nStartMip = nToMip; - pStreamState->m_pNewPoolItem = pNewPoolItem; - pStreamState->m_pTexture = this; - - SetStreamingInProgress(StreamOutMask | (uint8)s_StreamOutTasks.GetIdxFromPtr(pStreamState)); - - pStreamState->m_jobExecutor.StartJob([pStreamState]() - { - pStreamState->CopyMips(); - }); - - bCopying = true; - -#ifdef DO_RENDERLOG - if (gRenDev->m_logFileStrHandle != AZ::IO::InvalidHandle) - { - gRenDev->LogStrv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Async Start SetLod '%s', Lods: [%d-%d], Time: %.3f\n", m_SrcName.c_str(), nToMip, m_nMips - 1, iTimer->GetAsyncCurTime()); - } -#endif - } - else - { - Release(); - } - } - - if (!bCopying) -#endif - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif - // it is a sync operation anyway, so we do it in the render thread - CTexture::StreamCopyMipsTexToTex(m_pFileTexMips->m_pPoolItem, 0 + nOldMipOffset, pNewPoolItem, 0, nNumMips); - StreamAssignPoolItem(pNewPoolItem, nToMip); - } - } - else - { - s_pTextureStreamer->FlagOutOfMemory(); - } - - return nFreeSize; -} - - -int CTexture::StreamUnload() -{ - D3D_CHK_RENDTH; - - if (IsUnloaded() || !IsStreamed() || !CRenderer::CV_r_texturesstreaming) - { - return 0; - } - - AbortStreamingTasks(this); - assert(!IsStreaming()); - - int nDevSize = m_nActualSize; - -#ifdef TEXSTRM_ASYNC_TEXCOPY - bool bCopying = false; - - if (CanAsyncCopy() && (TryAddRef() > 0)) - { - STexStreamOutState* pStreamState = StreamState_AllocateOut(); - if (pStreamState) - { - pStreamState->m_pTexture = this; - pStreamState->m_nStartMip = MAX_MIP_LEVELS; - - SetStreamingInProgress(StreamOutMask | (uint8)s_StreamOutTasks.GetIdxFromPtr(pStreamState)); - - pStreamState->m_jobExecutor.StartJob([pStreamState]() - { - pStreamState->CopyMips(); - }); - - bCopying = true; - } - else - { - Release(); - } - } - - if (!bCopying) -#endif - { - // copy old mips to system memory - StreamCopyMipsTexToMem(m_nMips - m_CacheFileHeader.m_nMipsPersistent, m_nMips - 1, false, NULL); - ReleaseDeviceTexture(true); - SetWasUnload(true); - } - -#ifndef _RELEASE - if (CRenderer::CV_r_TexturesStreamingDebug == 2) - { - iLog->Log("Unloading unused texture: %s", m_SrcName.c_str()); - } -#endif - - return nDevSize; -} - -void CTexture::StreamActivateLod(int nMinMip) -{ - FUNCTION_PROFILER_RENDERER; - - STexPoolItem* pItem = m_pFileTexMips->m_pPoolItem; - STexPool* pPool = pItem->m_pOwner; - int nMipOffset = m_nMips - pPool->m_nMips; - int nDevMip = min((int)pPool->m_nMips - 1, max(0, nMinMip - nMipOffset)); - - if (pItem->m_nActiveLod != nDevMip) - { - pItem->m_nActiveLod = nDevMip; - - //D3DDevice* dv = gcpRendD3D->GetD3DDevice(); - //gcpRendD3D->GetDeviceContext().SetResourceMinLOD(m_pDevTexture->GetBaseTexture(), (FLOAT)nDevMip); - } - - m_nMinMipVidActive = nMinMip; -} - -void CTexture::StreamCopyMipsTexToMem(int nStartMip, int nEndMip, bool bToDevice, STexPoolItem* pNewPoolItem) -{ - PROFILE_FRAME(Texture_StreamUpload); - - CD3D9Renderer* r = gcpRendD3D; - CDeviceManager* pDevMan = &r->m_DevMan; - HRESULT h = S_OK; - nEndMip = min(nEndMip + 1, (int)m_nMips) - 1;//+1 -1 needed as the compare is <= - STexMipHeader* mh = m_pFileTexMips->m_pMipHeader; - - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - - const int nOldMinMipVidUploaded = m_nMinMipVidUploaded; - - if (bToDevice && !pNewPoolItem) - { - SetMinLoadedMip(nStartMip); - } - - D3DFormat fmt = DeviceFormatFromTexFormat(GetDstFormat()); - if (m_bIsSRGB) - { - fmt = ConvertToSRGBFmt(fmt); - } - - CDeviceTexture* pDevTexture = m_pDevTexture; - uint32 nTexMips = m_nMips; - if (m_pFileTexMips->m_pPoolItem) - { - assert(m_pFileTexMips->m_pPoolItem->m_pDevTexture); - assert(pDevTexture == m_pFileTexMips->m_pPoolItem->m_pDevTexture); - nTexMips = m_pFileTexMips->m_pPoolItem->m_pOwner->m_nMips; - } - if (bToDevice && pNewPoolItem) - { - assert(pNewPoolItem->m_pDevTexture); - pDevTexture = pNewPoolItem->m_pDevTexture; - nTexMips = pNewPoolItem->m_pOwner->m_nMips; - } - - if (!pDevTexture) - { - if (m_eTT != eTT_Cube) - { - h = pDevMan->Create2DTexture(m_SrcName, m_nWidth, m_nHeight, m_nMips, m_nArraySize, STREAMED_TEXTURE_USAGE, m_cClearColor, fmt, (D3DPOOL)0, &pDevTexture); - } - else - { - h = pDevMan->CreateCubeTexture(m_SrcName, m_nWidth, m_nMips, 1, STREAMED_TEXTURE_USAGE, m_cClearColor, fmt, (D3DPOOL)0, &pDevTexture); - } - assert(h == S_OK); - - // If a pool item was provided, it would have a valid dev texture, so we shouldn't have ended up here.. - assert (!bToDevice || !pNewPoolItem); - SetDevTexture(pDevTexture); - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_texturesstreamingnoupload && bToDevice) - { - return; - } - - const int nMipOffset = m_nMips - nTexMips; - const int32 nSides = StreamGetNumSlices(); - - D3DBaseTexture* pID3DTexture = pDevTexture->GetBaseTexture(); - - int SizeToLoad = 0; - for (int32 iSide = 0; iSide < nSides; ++iSide) - { - const int32 iSideLockIndex = m_eTT != eTT_Cube ? -1 : iSide; - for (int nLod = nStartMip; nLod <= nEndMip; nLod++) - { - SMipData* mp = &mh[nLod].m_Mips[iSide]; - int nMipW = m_nWidth >> nLod; - int nMipH = m_nHeight >> nLod; - - if (bToDevice && !mp->DataArray && s_bStreamDontKeepSystem) // we have this mip already loaded - { - continue; - } - - const int nDevTexMip = nLod - nMipOffset; - - if (bToDevice) - { - if (mp->DataArray) - { - CryInterlockedAdd(&CTexture::s_nTexturesDataBytesUploaded, mh[nLod].m_SideSize); - const int nRowPitch = CTexture::TextureDataSize(nMipW, 1, 1, 1, 1, m_eTFDst); - const int nSlicePitch = CTexture::TextureDataSize(nMipW, nMipH, 1, 1, 1, m_eTFDst); - STALL_PROFILER("update texture"); - { - gcpRendD3D->GetDeviceContext().UpdateSubresource(pID3DTexture, D3D11CalcSubresource(nDevTexMip, iSide, nTexMips), NULL, &mp->DataArray[0], nRowPitch, nSlicePitch); - } - } - else - { - assert(0); - } - } - else - { - const int nMipSize = mh[nLod].m_SideSize; - mp->Init(nMipSize, nMipW, nMipH); - const int nRowPitch = CTexture::TextureDataSize(nMipW, 1, 1, 1, 1, m_eTFDst); - const int nRows = nMipSize / nRowPitch; - assert(nMipSize % nRowPitch == 0); - - STALL_PROFILER("update texture"); - pDevTexture->DownloadToStagingResource(D3D11CalcSubresource(nDevTexMip, iSide, nTexMips), [&](void* pData, uint32 rowPitch, [[maybe_unused]] uint32 slicePitch) - { - for (int iRow = 0; iRow < nRows; ++iRow) - { - memcpy(&mp->DataArray[iRow * nRowPitch], (byte*)pData + rowPitch * iRow, nRowPitch); - } - return true; - }); - // mark as native - mp->m_bNative = true; - } - SizeToLoad += m_pFileTexMips->m_pMipHeader[nLod].m_SideSize; - - if (s_bStreamDontKeepSystem && bToDevice) - { - mp->Free(); - } - } - } -#ifdef DO_RENDERLOG - if (gRenDev->m_logFileStrHandle != AZ::IO::InvalidHandle) - { - gRenDev->LogStrv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "Uploading mips '%s'. (%d[%d]), Size: %d, Time: %.3f\n", m_SrcName.c_str(), nStartMip, m_nMips, SizeToLoad, iTimer->GetAsyncCurTime()); - } -#endif -} - -#if defined(TEXSTRM_DEFERRED_UPLOAD) - -ID3D11CommandList* CTexture::StreamCreateDeferred(int nStartMip, int nEndMip, STexPoolItem* pNewPoolItem, STexPoolItem* pSrcPoolItem) -{ - PROFILE_FRAME(Texture_StreamCreateDeferred); - - if ((pNewPoolItem == nullptr) || (pSrcPoolItem == nullptr)) - { - AZ_Warning("CTexture", false, "CTexture::StreamCreateDeferred called with pNewPoolItem = %p and pSrcPoolItem = %p, command list will not be created", pNewPoolItem, pSrcPoolItem); - return nullptr; - } - - ID3D11CommandList* pCmdList = nullptr; - - if (CTexture::s_pStreamDeferredCtx) - { - nEndMip = min(nEndMip + 1, (int)m_nMips) - 1;//+1 -1 needed as the compare is <= - STexMipHeader* mh = m_pFileTexMips->m_pMipHeader; - - const int nOldMinMipVidUploaded = m_nMinMipVidUploaded; - - D3DFormat fmt = DeviceFormatFromTexFormat(GetDstFormat()); - if (m_bIsSRGB) - { - fmt = ConvertToSRGBFmt(fmt); - } - - CDeviceTexture* pDevTexture = pNewPoolItem->m_pDevTexture; - uint32 nTexMips = pNewPoolItem->m_pOwner->m_nMips; - - const int nMipOffset = m_nMips - nTexMips; - const int32 nSides = StreamGetNumSlices(); - - const Vec2i vMipAlign = GetBlockDim(m_eTFSrc); - - D3DBaseTexture* pID3DTexture = pDevTexture->GetBaseTexture(); - - int SizeToLoad = 0; - for (int32 iSide = 0; iSide < nSides; ++iSide) - { - const int32 iSideLockIndex = m_eTT != eTT_Cube ? -1 : iSide; - for (int nLod = nStartMip; nLod <= nEndMip; nLod++) - { - SMipData* mp = &mh[nLod].m_Mips[iSide]; - - if (mp->DataArray) - { - const int nDevTexMip = nLod - nMipOffset; - - CryInterlockedAdd(&CTexture::s_nTexturesDataBytesUploaded, mh[nLod].m_SideSize); - const int nUSize = Align(max(1, m_nWidth >> nLod), vMipAlign.x); - const int nVSize = Align(max(1, m_nHeight >> nLod), vMipAlign.y); - const int nRowPitch = CTexture::TextureDataSize(nUSize, 1, 1, 1, 1, m_eTFDst); - const int nSlicePitch = CTexture::TextureDataSize(nUSize, nVSize, 1, 1, 1, m_eTFDst); - STALL_PROFILER("update texture"); - { - s_pStreamDeferredCtx->UpdateSubresource(pID3DTexture, D3D11CalcSubresource(nDevTexMip, iSide, nTexMips), NULL, &mp->DataArray[0], nRowPitch, nSlicePitch); - } - - SizeToLoad += m_pFileTexMips->m_pMipHeader[nLod].m_SideSize; - - if (s_bStreamDontKeepSystem) - { - mp->Free(); - } - } - } - } - - int nMipsSrc = pSrcPoolItem->m_pOwner->m_nMips; - int nMipsDst = pNewPoolItem->m_pOwner->m_nMips; - int nMipSrcOffset = m_nMips - nMipsSrc; - int nMipDstOffset = m_nMips - nMipsDst; - - for (int32 iSide = 0; iSide < nSides; ++iSide) - { - for (int i = nEndMip + 1; i < m_nMips; ++i) - { - s_pStreamDeferredCtx->CopySubresourceRegion( - pID3DTexture, - D3D11CalcSubresource(i - nMipDstOffset, iSide, nMipsDst), - 0, 0, 0, pSrcPoolItem->m_pDevTexture->GetBaseTexture(), - D3D11CalcSubresource(i - nMipSrcOffset, iSide, nMipsSrc), - NULL); - } - } - - s_pStreamDeferredCtx->FinishCommandList(FALSE, &pCmdList); - } - - return pCmdList; -} - -void CTexture::StreamApplyDeferred(ID3D11CommandList* pCmdList) -{ - FUNCTION_PROFILER_RENDERER; - gcpRendD3D->GetDeviceContext().ExecuteCommandList(pCmdList, TRUE); -} - -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif - -// Just remove item from the texture object and keep Item in Pool list for future use -// This function doesn't release API texture -void CTexture::StreamRemoveFromPool() -{ - D3D_CHK_MAINORRENDTH; - - if (!m_pFileTexMips || !m_pFileTexMips->m_pPoolItem) - { - return; - } - - AUTO_LOCK(STexPoolItem::s_sSyncLock); - - SAFE_RELEASE(*alias_cast(&m_pDeviceShaderResource)); - - ptrdiff_t nSize = (ptrdiff_t)m_nActualSize; - ptrdiff_t nPersSize = (ptrdiff_t)m_nPersistentSize; - - s_pPoolMgr->ReleaseItem(m_pFileTexMips->m_pPoolItem); - - m_pFileTexMips->m_pPoolItem = NULL; - m_nActualSize = 0; - m_nPersistentSize = 0; - m_pDevTexture = NULL; - - SetMinLoadedMip(MAX_MIP_LEVELS); - m_nMinMipVidActive = MAX_MIP_LEVELS; - - CryInterlockedAddSize(&s_nStatsStreamPoolBoundMem, -nSize); - CryInterlockedAddSize(&s_nStatsStreamPoolBoundPersMem, -nPersSize); -} - -void CTexture::StreamAssignPoolItem(STexPoolItem* pItem, int nMinMip) -{ - FUNCTION_PROFILER_RENDERER; - - assert (!pItem->IsFree()); - STexPool* pItemOwner = pItem->m_pOwner; - - if (m_pFileTexMips->m_pPoolItem == pItem) - { - assert(m_nActualSize == m_pFileTexMips->m_pPoolItem->m_pOwner->m_Size); - assert(m_pFileTexMips->m_pPoolItem->m_pTex == this); - assert(m_pDevTexture == m_pFileTexMips->m_pPoolItem->m_pDevTexture); - return; - } - - if (m_pFileTexMips->m_pPoolItem == NULL) - { - if (m_pDevTexture) - { - __debugbreak(); - } - } - - int nPersMip = m_nMips - m_CacheFileHeader.m_nMipsPersistent; - size_t nPersSize = StreamComputeDevDataSize(nPersMip); - - // Assign a new pool item - { - AUTO_LOCK(STexPoolItem::s_sSyncLock); - StreamRemoveFromPool(); - - m_pFileTexMips->m_pPoolItem = pItem; - m_nActualSize = pItemOwner->m_Size; - m_nPersistentSize = nPersSize; - pItem->m_pTex = this; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif - - SAFE_RELEASE(m_pDevTexture); - m_pDevTexture = pItem->m_pDevTexture; - - D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; - ZeroStruct(SRVDesc); - SRVDesc.Format = DeviceFormatFromTexFormat(GetDstFormat()); - if (m_bIsSRGB) - { - SRVDesc.Format = CTexture::ConvertToSRGBFmt(SRVDesc.Format); - } - - - // Recreate shader resource view - if (m_eTT == eTT_2D) - { - SRVDesc.Texture2D.MipLevels = -1; - SRVDesc.Texture2D.MostDetailedMip = 0; - SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - } - else if (m_eTT == eTT_2DArray) - { - SRVDesc.Texture2DArray.MipLevels = -1; - SRVDesc.Texture2DArray.MostDetailedMip = 0; - SRVDesc.Texture2DArray.FirstArraySlice = 0; - SRVDesc.Texture2DArray.ArraySize = m_nArraySize; - SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - } - else - { - SRVDesc.TextureCube.MipLevels = -1; - SRVDesc.TextureCube.MostDetailedMip = 0; - SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - } - - if (m_pDeviceShaderResource) - { - D3DShaderResourceView* pSRV = m_pDeviceShaderResource; - pSRV->Release(); - m_pDeviceShaderResource = NULL; - } - - D3DShaderResourceView* pNewResourceView = NULL; -#if !defined(NDEBUG) - HRESULT hr = -#endif - gcpRendD3D->GetDevice().CreateShaderResourceView(pItem->m_pDevTexture->GetBaseTexture(), &SRVDesc, &pNewResourceView); - assert(hr == S_OK); - - SetShaderResourceView(pNewResourceView, false); - SetMinLoadedMip(m_nMips - pItemOwner->m_nMips); - StreamActivateLod(nMinMip); - - CryInterlockedAddSize(&s_nStatsStreamPoolBoundMem, (ptrdiff_t)pItem->m_nDeviceTexSize); - CryInterlockedAddSize(&s_nStatsStreamPoolBoundPersMem, (ptrdiff_t)nPersSize); -} - -STexPool* CTexture::StreamGetPool(int nStartMip, int nMips) -{ - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - int uSize = Align(max(1, m_nWidth >> nStartMip), vMipAlign.x); - int vSize = Align(max(1, m_nHeight >> nStartMip), vMipAlign.y); - - return s_pPoolMgr->GetPool(uSize, vSize, nMips, m_nArraySize, m_eTFDst, m_bIsSRGB, m_eTT); -} - -STexPoolItem* CTexture::StreamGetPoolItem(int nStartMip, int nMips, bool bShouldBeCreated, bool bCreateFromMipData, bool bCanCreate, bool bForStreamOut) -{ - FUNCTION_PROFILER_RENDERER; - - if (!m_pFileTexMips) - { - return NULL; - } - - assert (nStartMip < m_nMips); - assert(!IsStreaming()); - - SCOPED_RENDERER_ALLOCATION_NAME_HINT(GetSourceName()); - - const Vec2i vMipAlign = CTexture::GetBlockDim(m_eTFDst); - int uSize = Align(max(1, m_nWidth >> nStartMip), vMipAlign.x); - int vSize = Align(max(1, m_nHeight >> nStartMip), vMipAlign.y); - int nArraySize = m_nArraySize; - ETEX_Type texType = m_eTT; - - if (m_pFileTexMips->m_pPoolItem && m_pFileTexMips->m_pPoolItem->m_pOwner) - { - STexPoolItem* pPoolItem = m_pFileTexMips->m_pPoolItem; - if (pPoolItem->m_pOwner->m_nMips == nMips && - pPoolItem->m_pOwner->m_Width == uSize && - pPoolItem->m_pOwner->m_Height == vSize && - pPoolItem->m_pOwner->m_nArraySize == nArraySize) - { - return NULL; - } - } - - STextureInfo ti; - std::vector srti; - STextureInfo* pTI = NULL; - - if (bCreateFromMipData) - { - uint32 nSlices = StreamGetNumSlices(); - - ti.m_nMSAAQuality = 0; - ti.m_nMSAASamples = 1; - srti.resize(nSlices * nMips); - ti.m_pData = &srti[0]; - - for (int nSide = 0; nSide < nSlices; ++nSide) - { - for (int nMip = nStartMip, nEndMip = nStartMip + nMips; nMip != nEndMip; ++nMip) - { - int nSRIdx = nSide * nMips + (nMip - nStartMip); - STexMipHeader& mmh = m_pFileTexMips->m_pMipHeader[nMip]; - SMipData& md = mmh.m_Mips[nSide]; - - if (md.m_bNative) - { - ti.m_pData[nSRIdx].pSysMem = md.DataArray; - ti.m_pData[nSRIdx].SysMemPitch = 0; - ti.m_pData[nSRIdx].SysMemSlicePitch = 0; - ti.m_pData[nSRIdx].SysMemTileMode = m_eSrcTileMode; - } - else - { - int nMipW = Align(max(1, m_nWidth >> nMip), vMipAlign.x); - int nPitch = 0; - const int BlockDim = vMipAlign.x; - if (BlockDim > 1) - { - int blockSize = BytesPerBlock(m_eTFDst); - nPitch = (nMipW + BlockDim - 1) / BlockDim * blockSize; - } - else - { - nPitch = TextureDataSize(nMipW, 1, 1, 1, 1, m_eTFSrc); - } - - ti.m_pData[nSRIdx].pSysMem = md.DataArray; - ti.m_pData[nSRIdx].SysMemPitch = nPitch; - ti.m_pData[nSRIdx].SysMemSlicePitch = 0; - ti.m_pData[nSRIdx].SysMemTileMode = eTM_None; - } - } - } - - pTI = &ti; - } - - bool bGPIMustWaitForIdle = true; - - // For end of C3, preserve existing (idle wait) console behaviour - bGPIMustWaitForIdle = !bForStreamOut; - - STexPoolItem* pItem = s_pPoolMgr->GetPoolItem(uSize, vSize, nMips, nArraySize, GetDstFormat(), m_bIsSRGB, texType, bShouldBeCreated, m_SrcName.c_str(), pTI, bCanCreate, bGPIMustWaitForIdle); - if (pItem) - { - return pItem; - } - - s_pTextureStreamer->FlagOutOfMemory(); - return NULL; -} - -void CTexture::StreamCopyMipsTexToTex(STexPoolItem* pSrcItem, int nMipSrc, STexPoolItem* pDestItem, int nMipDest, int nNumMips) -{ - D3D_CHK_RENDTH; - - uint32 nSides = pDestItem->m_pOwner->GetNumSlices(); - - for (uint32 iSide = 0; iSide < nSides; ++iSide) - { - CopySliceChain(pDestItem->m_pDevTexture, pDestItem->m_pOwner->m_nMips, iSide, nMipDest, pSrcItem->m_pDevTexture, iSide, nMipSrc, pSrcItem->m_pOwner->m_nMips, nNumMips); - } -} - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTEXTURESSTREAMING_CPP_SECTION_7 - #include AZ_RESTRICTED_FILE(D3DTexturesStreaming_cpp) -#endif - -// Debug routines ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _RELEASE -struct StreamDebugSortFunc -{ - bool operator()(const CTexture* p1, const CTexture* p2) const - { - if (!p1) - { - return true; - } - if (!p2) - { - return false; - } - if (p1->GetActualSize() != p2->GetActualSize()) - { - return p1->GetActualSize() < p2->GetActualSize(); - } - return p1 < p2; - } -}; - -struct StreamDebugSortWantedFunc -{ - bool operator()(const CTexture* p1, const CTexture* p2) const - { - int nP1ReqMip = p1->GetRequiredMipNonVirtual(); - int nP1Size = p1->StreamComputeDevDataSize(nP1ReqMip); - - int nP2ReqMip = p2->GetRequiredMipNonVirtual(); - int nP2Size = p2->StreamComputeDevDataSize(nP2ReqMip); - - if (nP1Size != nP2Size) - { - return nP1Size < nP2Size; - } - - return p1 < p2; - } -}; - -void CTexture::OutputDebugInfo() -{ - CD3D9Renderer* r = gcpRendD3D; - - int nX = 40; - int nY = 30; - - if (CRenderer::CV_r_TexturesStreamingDebugDumpIntoLog) - { - Vec3i vCamPos = iSystem->GetViewCamera().GetPosition(); - CryLogAlways("===================== Dumping textures streaming debug info for camera position (%d, %d, %d) =====================", vCamPos.x, vCamPos.y, vCamPos.z); - } - - char szText[512]; - sprintf_s(szText, "Size(MB) | WantedSize | MipFactor | HighPriority | #Mips(Desired/Current/Actual) | RoundID Normal/Fast | RecentlyUsed | Name"); - r->WriteXY(nX, nY, 1.f, 1.f, 1, 1, 0, 1, szText); - if (CRenderer::CV_r_TexturesStreamingDebugDumpIntoLog) - { - CryLogAlways(szText); - } - - std::vector texSorted; - s_pTextureStreamer->StatsFetchTextures(texSorted); - - const char* const sTexFilter = CRenderer::CV_r_TexturesStreamingDebugfilter->GetString(); - const bool bNameFilter = sTexFilter != 0 && strlen(sTexFilter) > 1; - - if (!texSorted.empty()) - { - switch (CRenderer::CV_r_TexturesStreamingDebug) - { - case 4: - std::stable_sort(&texSorted[0], &texSorted[0] + texSorted.size(), StreamDebugSortFunc()); - break; - - case 5: - std::reverse(texSorted.begin(), texSorted.end()); - break; - - case 6: - std::stable_sort(&texSorted[0], &texSorted[0] + texSorted.size(), StreamDebugSortWantedFunc()); - break; - } - } - - SThreadInfo& ti = gRenDev->m_RP.m_TI[gRenDev->m_pRT->GetThreadList()]; - - for (int i = (int)texSorted.size() - 1, nTexNum = 0; i >= 0; --i) - { - CTexture* tp = texSorted[i]; - if (tp == NULL) - { - continue; - } - // name filter - if (bNameFilter && !strstr(tp->m_SrcName.c_str(), sTexFilter)) - { - continue; - } - if (tp->m_nActualSize / 1024 < CRenderer::CV_r_TexturesStreamingDebugMinSize) - { - continue; - } - - ColorF color = (tp->m_nActualSize / 1024 >= CRenderer::CV_r_TexturesStreamingDebugMinSize * 2) ? Col_Red : Col_Green; - - // compute final mip factor - bool bHighPriority = false; - float fFinalMipFactor = pow(99.99f, 2.f); - for (int z = 0; z < MAX_PREDICTION_ZONES; z++) - { - if (tp->m_pFileTexMips && (int)tp->m_streamRounds[z].nRoundUpdateId > gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nProcessThreadID].m_arrZonesRoundId[z] - 2) - { - fFinalMipFactor = min(fFinalMipFactor, tp->m_pFileTexMips->m_arrSPInfo[z].fLastMinMipFactor); - bHighPriority |= tp->m_streamRounds[z].bLastHighPriority; - } - } - - // how many times used in area around - assert(tp->m_pFileTexMips); - - int nMipIdSigned = tp->StreamCalculateMipsSigned(fFinalMipFactor); - - if (nMipIdSigned > CRenderer::CV_r_TexturesStreamingDebugMinMip) - { - continue; - } - - int nPersMip = tp->m_nMips - tp->m_CacheFileHeader.m_nMipsPersistent; - int nMipReq = min(tp->GetRequiredMipNonVirtual(), nPersMip); - const int nWantedSize = tp->StreamComputeDevDataSize(nMipReq); - - assert(tp->m_pFileTexMips); - PREFAST_ASSUME(tp->m_pFileTexMips); - sprintf_s(szText, "%.2f | %.2f |%6.2f | %1d | %2d/%d/%d | %i/%i | %i | %s", - (float)tp->m_nActualSize / (1024 * 1024.0f), - (float)nWantedSize / (1024 * 1024.0f), - sqrtf(fFinalMipFactor), - (int)bHighPriority, - tp->GetNumMipsNonVirtual() - nMipIdSigned, tp->GetNumMipsNonVirtual() - tp->m_nMinMipVidUploaded, tp->GetNumMipsNonVirtual(), - tp->m_streamRounds[0].nRoundUpdateId, tp->m_streamRounds[MAX_PREDICTION_ZONES - 1].nRoundUpdateId, - tp->m_nAccessFrameID >= (int)ti.m_nFrameUpdateID - 8, - tp->m_SrcName.c_str()); - - r->WriteXY(nX, nY + (nTexNum + 1) * 10, 1.f, 1.f, color.r, color.g, color.b, 1, szText); - if (CRenderer::CV_r_TexturesStreamingDebugDumpIntoLog) - { - CryLogAlways(szText); - } - - ++nTexNum; - if (nTexNum > 50 && !CRenderer::CV_r_TexturesStreamingDebugDumpIntoLog) - { - break; - } - } - - if (CRenderer::CV_r_TexturesStreamingDebugDumpIntoLog) - { - CryLogAlways("=============================================================================================================="); - } - - if (ICVar* pCVar = gEnv->pConsole->GetCVar("r_TexturesStreamingDebugDumpIntoLog")) - { - pCVar->Set(0); - } -} -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.cpp deleted file mode 100644 index 1e590742e2..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.cpp +++ /dev/null @@ -1,1196 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "D3DTiledShading.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include "D3DVolumetricFog.h" -#include "GraphicsPipeline/FurPasses.h" - -#include "../Common/Textures/TextureManager.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define D3DTILEDSHADING_CPP_SECTION_1 1 -#define D3DTILEDSHADING_CPP_SECTION_2 2 -#define D3DTILEDSHADING_CPP_SECTION_3 3 -#endif - -#if defined(FEATURE_SVO_GI) -#include "D3D_SVO.h" -#endif - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -const uint32 AtlasArrayDim = 64; -const uint32 SpotTexSize = 512; -const uint32 DiffuseProbeSize = 32; -const uint32 SpecProbeSize = 256; -const uint32 ShadowSampleCount = 16; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// The following structs and constants have to match the shader code -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -const uint32 MaxNumTileLights = 255; -const uint32 LightTileSizeX = 8; -const uint32 LightTileSizeY = 8; -const uint32 MaxNumClipVolumes = MAX_DEFERRED_CLIP_VOLUMES; - - -struct STiledLightCullInfo -{ - uint32 volumeType; - uint32 PADDING0; - Vec2 depthBounds; - Vec4 posRad; - Vec4 volumeParams0; - Vec4 volumeParams1; - Vec4 volumeParams2; -}; // 80 bytes - -struct STiledClipVolumeInfo -{ - float data; -}; - -enum ETiledVolumeTypes -{ - tlVolumeSphere = 1, - tlVolumeCone = 2, - tlVolumeOBB = 3, - tlVolumeSun = 4, -}; - -enum ETiledLightTypes -{ - tlTypeProbe = 1, - tlTypeAmbientPoint = 2, - tlTypeAmbientProjector = 3, - tlTypeAmbientArea = 4, - tlTypeRegularPoint = 5, - tlTypeRegularProjector = 6, - tlTypeRegularPointFace = 7, - tlTypeRegularArea = 8, - tlTypeSun = 9, -}; - -// Sun area light parameters (same as in standard deferred shading) -const float SunDistance = 10000.0f; -const float SunSourceDiameter = 94.0f; // atan(AngDiameterSun) * 2 * SunDistance, where AngDiameterSun=0.54deg - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -namespace -{ - STiledLightCullInfo g_tileLightsCull[MaxNumTileLights]; - STiledLightShadeInfo g_tileLightsShade[MaxNumTileLights]; -} - -CTiledShading::CTiledShading() -{ - // 16 byte alignment is important for performance on nVidia cards - STATIC_ASSERT(sizeof(STiledLightCullInfo) % 16 == 0, "STiledLightCullInfo should be 16 byte aligned for GPU performance"); - STATIC_ASSERT(sizeof(STiledLightShadeInfo) % 16 == 0, "STiledLightShadeInfo should be 16 byte aligned for GPU performance"); - - m_dispatchSizeX = 0; - m_dispatchSizeY = 0; - - m_nTexStateCompare = 0xFFFFFFFF; - - m_numAtlasUpdates = 0; - m_numSkippedLights = 0; - - m_arrShadowCastingLights.Reserve(16); - - m_bApplyCaustics = false; -} - - -void CTiledShading::CreateResources() -{ - uint32 dispatchSizeX = gRenDev->GetWidth() / LightTileSizeX + (gRenDev->GetWidth() % LightTileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = gRenDev->GetHeight() / LightTileSizeY + (gRenDev->GetHeight() % LightTileSizeY > 0 ? 1 : 0); - - if (m_dispatchSizeX == dispatchSizeX && m_dispatchSizeY == dispatchSizeY) - { - assert(m_lightCullInfoBuf.m_pBuffer && m_specularProbeAtlas.texArray); - return; - } - else - { - DestroyResources(false); - } - - m_dispatchSizeX = dispatchSizeX; - m_dispatchSizeY = dispatchSizeY; - - if (!m_lightCullInfoBuf.m_pBuffer) - { - m_lightCullInfoBuf.Create(MaxNumTileLights, sizeof(STiledLightCullInfo), DXGI_FORMAT_UNKNOWN, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_LightShadeInfoBuf.m_pBuffer) - { - m_LightShadeInfoBuf.Create(MaxNumTileLights, sizeof(STiledLightShadeInfo), DXGI_FORMAT_UNKNOWN, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_tileLightIndexBuf.m_pBuffer) - { - PREFAST_SUPPRESS_WARNING(6326) - DXGI_FORMAT format = MaxNumTileLights < 256 ? DXGI_FORMAT_R8_UINT : DXGI_FORMAT_R16_UINT; - PREFAST_SUPPRESS_WARNING(6326) - uint32 stride = MaxNumTileLights < 256 ? sizeof(char) : sizeof(short); - - m_tileLightIndexBuf.Create(dispatchSizeX * dispatchSizeY * MaxNumTileLights, stride, format, DX11BUF_BIND_SRV | DX11BUF_BIND_UAV, NULL); - } - - if (!m_clipVolumeInfoBuf.m_pBuffer) - { - m_clipVolumeInfoBuf.Create(MaxNumClipVolumes, sizeof(STiledClipVolumeInfo), DXGI_FORMAT_UNKNOWN, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_specularProbeAtlas.texArray) - { - ETEX_Format specProbeAtlasFormat = eTF_BC6UH; -#if defined(AZ_PLATFORM_MAC) - specProbeAtlasFormat = eTF_R9G9B9E5; -#endif - m_specularProbeAtlas.texArray = CTexture::CreateTextureArray("$TiledSpecProbeTexArr", eTT_Cube, SpecProbeSize, SpecProbeSize, AtlasArrayDim, IntegerLog2(SpecProbeSize) - 1, 0, specProbeAtlasFormat); - m_specularProbeAtlas.items.resize(AtlasArrayDim); - - if (m_specularProbeAtlas.texArray->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate specular probe texture atlas"); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTILEDSHADING_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DTiledShading_cpp) -#endif - } - - if (!m_diffuseProbeAtlas.texArray) - { - ETEX_Format diffuseProbeAtlasFormat = eTF_BC6UH; -#if defined(AZ_PLATFORM_MAC) - diffuseProbeAtlasFormat = eTF_R9G9B9E5; -#endif - m_diffuseProbeAtlas.texArray = CTexture::CreateTextureArray("$TiledDiffuseProbeTexArr", eTT_Cube, DiffuseProbeSize, DiffuseProbeSize, AtlasArrayDim, 1, 0, diffuseProbeAtlasFormat); - m_diffuseProbeAtlas.items.resize(AtlasArrayDim); - - if (m_diffuseProbeAtlas.texArray->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate diffuse probe texture atlas"); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTILEDSHADING_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(D3DTiledShading_cpp) -#endif - } - - if (!m_spotTexAtlas.texArray) - { - // Note: BC4 has 4x4 as lowest mipmap - m_spotTexAtlas.texArray = CTexture::CreateTextureArray("$TiledSpotTexArr", eTT_2D, SpotTexSize, SpotTexSize, AtlasArrayDim, IntegerLog2(SpotTexSize) - 1, 0, eTF_BC4U); - m_spotTexAtlas.items.resize(AtlasArrayDim); - - if (m_spotTexAtlas.texArray->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate spot texture atlas"); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DTILEDSHADING_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(D3DTiledShading_cpp) -#endif - } - - STexState ts1(FILTER_LINEAR, true); - ts1.SetComparisonFilter(true); - m_nTexStateCompare = CTexture::GetTexState(ts1); -} - - -void CTiledShading::DestroyResources(bool destroyResolutionIndependentResources) -{ - m_dispatchSizeX = 0; - m_dispatchSizeY = 0; - - m_lightCullInfoBuf.Release(); - m_LightShadeInfoBuf.Release(); - m_tileLightIndexBuf.Release(); - m_clipVolumeInfoBuf.Release(); - - if (destroyResolutionIndependentResources) - { - m_specularProbeAtlas.items.clear(); - m_diffuseProbeAtlas.items.clear(); - m_spotTexAtlas.items.clear(); - - SAFE_RELEASE_FORCE(m_specularProbeAtlas.texArray); - SAFE_RELEASE_FORCE(m_diffuseProbeAtlas.texArray); - SAFE_RELEASE_FORCE(m_spotTexAtlas.texArray); - } -} - - -void CTiledShading::Clear() -{ - for (uint32 i = 0, si = m_specularProbeAtlas.items.size(); i < si; ++i) - { - m_specularProbeAtlas.items[i] = AtlasItem(); - } - for (uint32 i = 0, si = m_diffuseProbeAtlas.items.size(); i < si; ++i) - { - m_diffuseProbeAtlas.items[i] = AtlasItem(); - } - for (uint32 i = 0, si = m_spotTexAtlas.items.size(); i < si; ++i) - { - m_spotTexAtlas.items[i] = AtlasItem(); - } - - m_numAtlasUpdates = 0; - m_numSkippedLights = 0; -} - - -int CTiledShading::InsertTexture(CTexture* texture, TextureAtlas& atlas, int arrayIndex) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - const int frameID = rd->GetFrameID(false); - - if (texture == NULL) - { - return -1; - } - - // Make sure the texture is loaded already - if (texture->GetWidthNonVirtual() == 0 && texture->GetHeightNonVirtual() == 0) - { - return -1; - } - - bool isEditor = gEnv->IsEditor(); - - // Check if texture is already in atlas - for (uint32 i = 0, si = atlas.items.size(); i < si; ++i) - { - if (atlas.items[i].texture == texture) - { - bool textureUpToDate = !isEditor ? true : (texture->GetUpdateFrameID() == abs(atlas.items[i].updateFrameID) || texture->GetUpdateFrameID() == 0); - - if (textureUpToDate) - { - if (atlas.items[i].invalid) - { - // Texture was processed before and is invalid - return -1; - } - else - { - atlas.items[i].accessFrameID = frameID; - return (int)i; - } - } - } - } - - // Find least recently used entry in atlas - if (arrayIndex < 0) - { - uint32 minIndex = 0, minValue = 0xFFFFFFFF; - for (int i = 0, si = atlas.items.size(); i < si; ++i) - { - uint32 accessFrameID = atlas.items[i].accessFrameID; - if (accessFrameID < minValue) - { - minValue = accessFrameID; - minIndex = i; - } - } - - arrayIndex = minIndex; - } - - atlas.items[arrayIndex].texture = texture; - atlas.items[arrayIndex].accessFrameID = frameID; - atlas.items[arrayIndex].updateFrameID = texture->GetUpdateFrameID(); - atlas.items[arrayIndex].invalid = false; - - if (texture->GetIsTextureMissing()) - { - //if Texture is missing than do not do error checking - return -1; - } - - // Check if texture is valid - if (!texture->IsLoaded() || - texture->GetWidthNonVirtual() < atlas.texArray->GetWidthNonVirtual() || - texture->GetWidthNonVirtual() != texture->GetHeightNonVirtual() || - texture->GetPixelFormat() != atlas.texArray->GetPixelFormat() || - (texture->IsStreamed() && texture->IsPartiallyLoaded())) - { - atlas.items[arrayIndex].invalid = true; - - if (!texture->IsLoaded()) - { - iLog->LogError("TiledShading: Texture not found: %s", texture->GetName()); - } - else if (texture->IsStreamed() && texture->IsPartiallyLoaded()) - { - iLog->LogError("TiledShading: Texture not fully streamed so impossible to add: %s (W:%i H:%i F:%s)", - texture->GetName(), texture->GetWidth(), texture->GetHeight(), texture->GetFormatName()); - } - else if (texture->GetPixelFormat() != atlas.texArray->GetPixelFormat()) - { - iLog->LogError("TiledShading: Unsupported texture format: %s (W:%i H:%i F:%s), it has to be equal to the tile-atlas (F:%s), please change the texture's preset by re-exporting with CryTif", - texture->GetName(), texture->GetWidth(), texture->GetHeight(), texture->GetFormatName(), atlas.texArray->GetFormatName()); - } - else - { - iLog->LogError("TiledShading: Unsupported texture properties: %s (W:%i H:%i F:%s)", - texture->GetName(), texture->GetWidth(), texture->GetHeight(), texture->GetFormatName()); - } - return -1; - } - - // Update atlas - uint32 numSrcMips = (uint32)texture->GetNumMipsNonVirtual(); - uint32 numDstMips = (uint32)atlas.texArray->GetNumMipsNonVirtual(); - uint32 firstSrcMip = IntegerLog2((uint32)texture->GetWidthNonVirtual() / atlas.texArray->GetWidthNonVirtual()); - uint32 numFaces = atlas.texArray->GetTexType() == eTT_Cube ? 6 : 1; - - CDeviceTexture* pTexArrayDevTex = atlas.texArray->GetDevTexture(); - - //ASSERT_DEVICE_TEXTURE_IS_FIXED(pTexArrayDevTex); - - for (uint32 i = 0; i < numDstMips; ++i) - { - for (uint32 j = 0; j < numFaces; ++j) - { - rd->GetDeviceContext().CopySubresourceRegion( - pTexArrayDevTex->GetBaseTexture(), D3D11CalcSubresource(i, arrayIndex * numFaces + j, numDstMips), 0, 0, 0, - texture->GetDevTexture()->GetBaseTexture(), D3D11CalcSubresource(i + firstSrcMip, j, numSrcMips), NULL); - } - } - - ++m_numAtlasUpdates; - - return arrayIndex; -} - - -AABB RotateAABB(const AABB& aabb, const Matrix33& mat) -{ - Matrix33 matAbs; - matAbs.m00 = fabs_tpl(mat.m00); - matAbs.m01 = fabs_tpl(mat.m01); - matAbs.m02 = fabs_tpl(mat.m02); - matAbs.m10 = fabs_tpl(mat.m10); - matAbs.m11 = fabs_tpl(mat.m11); - matAbs.m12 = fabs_tpl(mat.m12); - matAbs.m20 = fabs_tpl(mat.m20); - matAbs.m21 = fabs_tpl(mat.m21); - matAbs.m22 = fabs_tpl(mat.m22); - - Vec3 sz = ((aabb.max - aabb.min) * 0.5f) * matAbs; - Vec3 pos = ((aabb.max + aabb.min) * 0.5f) * mat; - - return AABB(pos - sz, pos + sz); -} - -void CTiledShading::PrepareEnvironmentProbes(bool& shouldAdd, SRenderLight& renderLight, STiledLightCullInfo& lightCullInfo, STiledLightShadeInfo& lightShadeInfo, Matrix44A& matView, const float invCameraFar, const Vec4& posVS) -{ - lightCullInfo.volumeType = tlVolumeOBB; - lightShadeInfo.lightType = tlTypeProbe; - lightShadeInfo.resIndex = 0xFFFFFFFF; - - const float uniformAttenuation = renderLight.m_fProbeAttenuation; - const float edgeFalloffSmoothness = max(renderLight.GetFalloffMax(), 0.001f); - lightShadeInfo.attenuationParams = Vec2(uniformAttenuation, edgeFalloffSmoothness); - - AABB aabb = RotateAABB(AABB(-renderLight.m_ProbeExtents, renderLight.m_ProbeExtents), Matrix33(renderLight.m_ObjMatrix)); - aabb = RotateAABB(aabb, Matrix33(matView)); - lightCullInfo.depthBounds = Vec2(posVS.z + aabb.min.z, posVS.z + aabb.max.z) * invCameraFar; - - const Vec4 u0 = Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized(), 0) * matView; - const Vec4 u1 = Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized(), 0) * matView; - const Vec4 u2 = Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized(), 0) * matView; - lightCullInfo.volumeParams0 = Vec4(u0.x, u0.y, u0.z, renderLight.m_ProbeExtents.x); - lightCullInfo.volumeParams1 = Vec4(u1.x, u1.y, u1.z, renderLight.m_ProbeExtents.y); - lightCullInfo.volumeParams2 = Vec4(u2.x, u2.y, u2.z, renderLight.m_ProbeExtents.z); - - lightShadeInfo.projectorMatrix.SetRow4(0, Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized() / renderLight.m_ProbeExtents.x, 0)); - lightShadeInfo.projectorMatrix.SetRow4(1, Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized() / renderLight.m_ProbeExtents.y, 0)); - lightShadeInfo.projectorMatrix.SetRow4(2, Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized() / renderLight.m_ProbeExtents.z, 0)); - - Vec3 boxProxyMin(-1000000, -1000000, -1000000); - Vec3 boxProxyMax(1000000, 1000000, 1000000); - - if (renderLight.m_Flags & DLF_BOX_PROJECTED_CM) - { - boxProxyMin = Vec3(-renderLight.m_fBoxLength * 0.5f, -renderLight.m_fBoxWidth * 0.5f, -renderLight.m_fBoxHeight * 0.5f); - boxProxyMax = Vec3(renderLight.m_fBoxLength * 0.5f, renderLight.m_fBoxWidth * 0.5f, renderLight.m_fBoxHeight * 0.5f); - } - - lightShadeInfo.shadowMatrix.SetRow4(0, Vec4(boxProxyMin, 0)); - lightShadeInfo.shadowMatrix.SetRow4(1, Vec4(boxProxyMax, 0)); - - const int arrayIndex = InsertTexture((CTexture*)renderLight.GetSpecularCubemap(), m_specularProbeAtlas, -1); - if (arrayIndex >= 0) - { - if (InsertTexture((CTexture*)renderLight.GetDiffuseCubemap(), m_diffuseProbeAtlas, arrayIndex) >= 0) - { - lightShadeInfo.resIndex = arrayIndex; - } - else - { - shouldAdd = false; // Skip light - } - } - else - { - shouldAdd = false; // Skip light - } -} - -void CTiledShading::PrepareRegularAndAmbientLights(bool& shouldAdd, SRenderLight& renderLight, STiledLightCullInfo& lightCullInfo, STiledLightShadeInfo& lightShadeInfo, Matrix44A& matView, const float invCameraFar, const Vec4& posVS, - const bool ambientLight, CD3D9Renderer* const __restrict rd, const bool areaLightRect, const uint32 lightIdx, const uint32 firstShadowLight, const uint32 curShadowPoolLight, const int nThreadID, const int nRecurseLevel, uint32& numTileLights) -{ - const float sqrt_2 = 1.414214f; // Scale for cone so that it's base encloses a pyramid base - - lightCullInfo.volumeType = tlVolumeSphere; - lightShadeInfo.lightType = ambientLight ? tlTypeAmbientPoint : tlTypeRegularPoint; - - if (!ambientLight) - { - lightShadeInfo.attenuationParams.x = max(lightShadeInfo.attenuationParams.x, 0.001f); - - // Adjust light intensity so that the intended brightness is reached 1 meter from the light's surface - // Solve I * 1 / (1 + d/lightsize)^2 = 1 - float intensityMul = 1.0f + 1.0f / lightShadeInfo.attenuationParams.x; - intensityMul *= intensityMul; - lightShadeInfo.color.x *= intensityMul; - lightShadeInfo.color.y *= intensityMul; - lightShadeInfo.color.z *= intensityMul; - } - - // Handle projectors - if (renderLight.m_Flags & DLF_PROJECT) - { - lightCullInfo.volumeType = tlVolumeCone; - lightShadeInfo.lightType = ambientLight ? tlTypeAmbientProjector : tlTypeRegularProjector; - lightShadeInfo.resIndex = 0xFFFFFFFF; - - int arrayIndex = InsertTexture((CTexture*)renderLight.m_pLightImage, m_spotTexAtlas, -1); - if (arrayIndex >= 0) - { - lightShadeInfo.resIndex = (uint32)arrayIndex; - } - else - { - shouldAdd = false; // Skip light - return; - } - // Prevent culling errors for frustums with large FOVs by slightly enlarging the frustum - const float frustumAngleDelta = renderLight.m_fLightFrustumAngle > 50 ? 7.5f : 0.0f; - - Matrix34 objMat = renderLight.m_ObjMatrix; - objMat.m03 = objMat.m13 = objMat.m23 = 0; // Remove translation - const Vec3 lightDir = objMat * Vec3(-1, 0, 0); - lightCullInfo.volumeParams0 = Vec4(lightDir.x, lightDir.y, lightDir.z, 0) * matView; - lightCullInfo.volumeParams0.w = renderLight.m_fRadius * tanf(DEG2RAD(min(renderLight.m_fLightFrustumAngle + frustumAngleDelta, 89.9f))) * sqrt_2; - - const Vec3 coneTip = Vec3(lightCullInfo.posRad.x, lightCullInfo.posRad.y, lightCullInfo.posRad.z); - const Vec3 coneDir = Vec3(-lightCullInfo.volumeParams0.x, -lightCullInfo.volumeParams0.y, -lightCullInfo.volumeParams0.z); - const AABB coneBounds = AABB::CreateAABBfromCone(Cone(coneTip, coneDir, renderLight.m_fRadius, lightCullInfo.volumeParams0.w)); - lightCullInfo.depthBounds = Vec2(coneBounds.min.z, coneBounds.max.z) * invCameraFar; - - lightShadeInfo.dirCosAngle = Vec4(lightDir.GetNormalized(), cosf(DEG2RAD(min(renderLight.m_fLightFrustumAngle + frustumAngleDelta, 89.9f)))); - - Matrix44A projMatT; - CShadowUtils::GetProjectiveTexGen(&renderLight, 0, &projMatT); - - // Translate into camera space - projMatT.Transpose(); - const Vec4 vEye(rd->GetViewParameters().vOrigin, 0.0f); - const Vec4 vecTranslation(vEye.Dot((Vec4&)projMatT.m00), vEye.Dot((Vec4&)projMatT.m10), vEye.Dot((Vec4&)projMatT.m20), vEye.Dot((Vec4&)projMatT.m30)); - projMatT.m03 += vecTranslation.x; - projMatT.m13 += vecTranslation.y; - projMatT.m23 += vecTranslation.z; - projMatT.m33 += vecTranslation.w; - - lightShadeInfo.projectorMatrix = projMatT; - } - - // Handle rectangular area lights - if (areaLightRect) - { - lightCullInfo.volumeType = tlVolumeOBB; - lightShadeInfo.lightType = ambientLight ? tlTypeAmbientArea : tlTypeRegularArea; - - const float expensionRadius = renderLight.m_fRadius * 1.08f; - const Matrix34 areaLightMat = CShadowUtils::GetAreaLightMatrix(&renderLight, Vec3(expensionRadius, expensionRadius, expensionRadius)); - - const Vec4 u0 = Vec4(areaLightMat.GetColumn0().GetNormalized(), 0) * matView; - const Vec4 u1 = Vec4(areaLightMat.GetColumn1().GetNormalized(), 0) * matView; - const Vec4 u2 = Vec4(areaLightMat.GetColumn2().GetNormalized(), 0) * matView; - lightCullInfo.volumeParams0 = Vec4(u0.x, u0.y, u0.z, areaLightMat.GetColumn0().GetLength() * 0.5f); - lightCullInfo.volumeParams1 = Vec4(u1.x, u1.y, u1.z, areaLightMat.GetColumn1().GetLength() * 0.5f); - lightCullInfo.volumeParams2 = Vec4(u2.x, u2.y, u2.z, areaLightMat.GetColumn2().GetLength() * 0.5f); - - const float volumeExtent = renderLight.m_fRadius + max(renderLight.m_fAreaWidth, renderLight.m_fAreaHeight); - lightCullInfo.depthBounds = Vec2(posVS.z - volumeExtent, posVS.z + volumeExtent) * invCameraFar; - - float areaFov = renderLight.m_fLightFrustumAngle * 2.0f; - if (renderLight.m_Flags & DLF_CASTSHADOW_MAPS) - { - areaFov = min(areaFov, 135.0f); // Shadow can only cover ~135 degree FOV without looking bad, so we clamp the FOV to hide shadow clipping - } - const float cosAngle = cosf(areaFov * (gf_PI / 360.0f)); - - Matrix44 areaLightParams; - areaLightParams.SetRow4(0, Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(1, Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(2, Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(3, Vec4(renderLight.m_fAreaWidth * 0.5f, renderLight.m_fAreaHeight * 0.5f, 0, cosAngle)); - - lightShadeInfo.projectorMatrix = areaLightParams; - } - - // Handle shadow casters - if (!ambientLight && lightIdx >= firstShadowLight && lightIdx < curShadowPoolLight) - { - const int numDLights = rd->m_RP.m_DLights[nThreadID][nRecurseLevel].size(); - const int frustumIdx = renderLight.m_lightId + numDLights; - const int startIdx = SRendItem::m_StartFrust[nThreadID][frustumIdx]; - const int endIdx = SRendItem::m_EndFrust[nThreadID][frustumIdx]; - - if (endIdx > startIdx && nRecurseLevel < (int)rd->m_RP.m_SMFrustums[nThreadID]->size()) - { - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[nThreadID][nRecurseLevel][startIdx]; - assert(firstFrustum.bUseShadowsPool); - - const int numSides = firstFrustum.bOmniDirectionalShadow ? 6 : 1; - const float kernelSize = firstFrustum.bOmniDirectionalShadow ? 2.5f : 1.5f; - - if (numTileLights + numSides > MaxNumTileLights) - { - shouldAdd = false; // Skip light - return; - } - static ICVar* pShadowAtlasResCVar = iConsole->GetCVar("e_ShadowsPoolSize"); - const Vec2 shadowParams = Vec2(kernelSize * ((float)firstFrustum.nTexSize / (float)pShadowAtlasResCVar->GetIVal()), firstFrustum.fDepthConstBias); - - static const Vec3 cubeDirs[6] = { Vec3(-1, 0, 0), Vec3(1, 0, 0), Vec3(0, -1, 0), Vec3(0, 1, 0), Vec3(0, 0, -1), Vec3(0, 0, 1) }; - - for (int side = 0; side < numSides; ++side) - { - rd->ConfigShadowTexgen(0, &firstFrustum, side); - Matrix44A shadowMat = rd->m_TempMatrices[0][0]; - - // Translate into camera space - const Vec4 vEye(rd->GetViewParameters().vOrigin, 0.0f); - const Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30)); - shadowMat.m03 += vecTranslation.x; - shadowMat.m13 += vecTranslation.y; - shadowMat.m23 += vecTranslation.z; - shadowMat.m33 += vecTranslation.w; - - // Pre-multiply by inverse frustum far plane distance - (Vec4&)shadowMat.m20 *= rd->m_cEF.m_TempVecs[2].x; - - Vec4 spotParamsVS = Vec4(cubeDirs[side].x, cubeDirs[side].y, cubeDirs[side].z, 0) * matView; - - // slightly enlarge the frustum to prevent culling errors - spotParamsVS.w = renderLight.m_fRadius * tanf(DEG2RAD(45.0f + 14.5f)) * sqrt_2; - - const Vec3 coneTip(lightCullInfo.posRad.x, lightCullInfo.posRad.y, lightCullInfo.posRad.z); - const Vec3 coneDir(-spotParamsVS.x, -spotParamsVS.y, -spotParamsVS.z); - const AABB coneBounds = AABB::CreateAABBfromCone(Cone(coneTip, coneDir, renderLight.m_fRadius, spotParamsVS.w)); - const Vec2 depthBoundsVS = Vec2(coneBounds.min.z, coneBounds.max.z) * invCameraFar; - const Vec2 sideShadowParams = (firstFrustum.nShadowGenMask & (1 << side)) ? shadowParams : Vec2(ZERO); - - if (side == 0) - { - lightShadeInfo.shadowParams = sideShadowParams; - lightShadeInfo.shadowMatrix = shadowMat; - lightShadeInfo.shadowChannelIndex = Vec4( - renderLight.m_ShadowChanMask % 4 == 0, - renderLight.m_ShadowChanMask % 4 == 1, - renderLight.m_ShadowChanMask % 4 == 2, - renderLight.m_ShadowChanMask % 4 == 3 - ); - lightShadeInfo.shadowMaskIndex = renderLight.m_ShadowMaskIndex; - - if (numSides > 1) - { - lightCullInfo.volumeType = tlVolumeCone; - lightShadeInfo.lightType = tlTypeRegularPointFace; - lightShadeInfo.resIndex = side; - lightCullInfo.volumeParams0 = spotParamsVS; - lightCullInfo.depthBounds = depthBoundsVS; - } - } - else - { - // Split point light - ++numTileLights; - g_tileLightsCull[numTileLights] = lightCullInfo; - g_tileLightsShade[numTileLights] = lightShadeInfo; - g_tileLightsShade[numTileLights].shadowParams = sideShadowParams; - g_tileLightsShade[numTileLights].shadowMatrix = shadowMat; - g_tileLightsShade[numTileLights].resIndex = side; - g_tileLightsCull[numTileLights].volumeParams0 = spotParamsVS; - g_tileLightsCull[numTileLights].depthBounds = depthBoundsVS; - } - } - } - } -} - -void CTiledShading::PrepareLightList(TArray& envProbes, TArray& ambientLights, TArray& defLights) -{ - AZ_TRACE_METHOD(); - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - const float invCameraFar = 1.0f / rd->GetViewParameters().fFar; - - // Prepare view matrix with flipped z-axis - Matrix44A matView = rd->m_ViewMatrix; - matView.m02 *= -1; - matView.m12 *= -1; - matView.m22 *= -1; - matView.m32 *= -1; - - const int nThreadID = rd->m_RP.m_nProcessThreadID; - const int nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - const uint32 firstShadowLight = CDeferredShading::Instance().m_nFirstCandidateShadowPoolLight; - const uint32 curShadowPoolLight = CDeferredShading::Instance().m_nCurrentShadowPoolLight; - - uint32 numTileLights = 0; - uint32 numRenderLights = 0; - uint32 numValidRenderLights = 0; - - // Reset lights - ZeroMemory(g_tileLightsCull, sizeof(STiledLightCullInfo) * MaxNumTileLights); - ZeroMemory(g_tileLightsShade, sizeof(STiledLightShadeInfo) * MaxNumTileLights); - - TArray* lightLists[3] = { - CRenderer::CV_r_DeferredShadingEnvProbes ? &envProbes : NULL, - CRenderer::CV_r_DeferredShadingAmbientLights ? &ambientLights : NULL, - CRenderer::CV_r_DeferredShadingLights ? &defLights : NULL - }; - - for (uint32 lightListIdx = 0; lightListIdx < 3; ++lightListIdx) - { - if (lightLists[lightListIdx] == NULL) - { - continue; - } - - for (uint32 lightIdx = 0, lightListSize = lightLists[lightListIdx]->size(); lightIdx < lightListSize; ++lightIdx) - { - SRenderLight& renderLight = (*lightLists[lightListIdx])[lightIdx]; - STiledLightCullInfo& lightCullInfo = g_tileLightsCull[numTileLights]; - STiledLightShadeInfo& lightShadeInfo = g_tileLightsShade[numTileLights]; - - if (renderLight.m_Flags & (DLF_FAKE | DLF_VOLUMETRIC_FOG_ONLY)) - { - continue; - } - - // Skip non-ambient area light if support is disabled - if ((renderLight.m_Flags & DLF_AREA_LIGHT) && !(renderLight.m_Flags & DLF_AMBIENT) && !CRenderer::CV_r_DeferredShadingAreaLights) - { - continue; - } - - ++numRenderLights; - - if (numTileLights == MaxNumTileLights) - { - continue; // Skip light - } - // Setup standard parameters - const bool areaLightRect = (renderLight.m_Flags & DLF_AREA_LIGHT) && renderLight.m_fAreaWidth && renderLight.m_fAreaHeight && renderLight.m_fLightFrustumAngle; - const float volumeSize = (lightListIdx == 0) ? renderLight.m_ProbeExtents.len() : renderLight.m_fRadius; - const Vec3 pos = renderLight.GetPosition(); - const Vec3 worldViewPos = rd->GetViewParameters().vOrigin; - lightShadeInfo.posRad = Vec4(pos.x - worldViewPos.x, pos.y - worldViewPos.y, pos.z - worldViewPos.z, volumeSize); - const Vec4 posVS = Vec4(pos, 1) * matView; - lightCullInfo.posRad = Vec4(posVS.x, posVS.y, posVS.z, volumeSize); - lightShadeInfo.attenuationParams = Vec2(areaLightRect ? (renderLight.m_fAreaWidth + renderLight.m_fAreaHeight) * 0.25f : renderLight.m_fAttenuationBulbSize, renderLight.m_fAreaHeight * 0.5f); - lightCullInfo.depthBounds = Vec2(posVS.z - volumeSize, posVS.z + volumeSize) * invCameraFar; - lightShadeInfo.color = Vec4( - renderLight.m_Color.r, - renderLight.m_Color.g, - renderLight.m_Color.b, - renderLight.m_SpecMult); - lightShadeInfo.resIndex = 0; - lightShadeInfo.shadowParams = Vec2(0, 0); - lightShadeInfo.stencilID0 = renderLight.m_nStencilRef[0] + 1; - lightShadeInfo.stencilID1 = renderLight.m_nStencilRef[1] + 1; - - bool shouldAdd = true; - - // Environment probes - if (lightListIdx == 0) - { - PrepareEnvironmentProbes(shouldAdd, renderLight, lightCullInfo, lightShadeInfo, matView, invCameraFar, posVS); - } - // Regular and ambient lights - else - { - const bool ambientLight = (lightListIdx == 1); - PrepareRegularAndAmbientLights(shouldAdd, renderLight, lightCullInfo, lightShadeInfo, matView, invCameraFar, posVS, - ambientLight, rd, areaLightRect, lightIdx, firstShadowLight, curShadowPoolLight, nThreadID, nRecurseLevel, numTileLights); - } - - if (shouldAdd) - { - // Add current light - ++numTileLights; - ++numValidRenderLights; - } - } - } - - // Invalidate last light in case it got skipped - if (numTileLights < MaxNumTileLights) - { - ZeroMemory(&g_tileLightsCull[numTileLights], sizeof(STiledLightCullInfo)); - ZeroMemory(&g_tileLightsShade[numTileLights], sizeof(STiledLightShadeInfo)); - } - - m_numSkippedLights = numRenderLights - numValidRenderLights; - - // Add sun - if (rd->m_RP.m_pSunLight) - { - if (numTileLights < MaxNumTileLights) - { - STiledLightCullInfo& lightCullInfo = g_tileLightsCull[numTileLights]; - STiledLightShadeInfo& lightShadeInfo = g_tileLightsShade[numTileLights]; - - lightCullInfo.volumeType = tlVolumeSun; - lightCullInfo.depthBounds = Vec2(-100000, 100000); - lightCullInfo.posRad = Vec4(0, 0, 0, 100000); - - lightShadeInfo.lightType = tlTypeSun; - lightShadeInfo.attenuationParams = Vec2(SunSourceDiameter, SunSourceDiameter); - lightShadeInfo.shadowParams = Vec2(1, 0); - lightShadeInfo.shadowMaskIndex = 0; - lightShadeInfo.shadowChannelIndex = Vec4(1, 0, 0, 0); - lightShadeInfo.stencilID0 = lightShadeInfo.stencilID1 = 0; - - Vec3 sunColor; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_COLOR, sunColor); - lightShadeInfo.color = Vec4(sunColor.x, sunColor.y, sunColor.z, gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER)); - - ++numTileLights; - } - else - { - m_numSkippedLights += 1; - } - } - -#ifndef _RELEASE - rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTiledShadingSkippedLights = m_numSkippedLights; -#endif - - // Update light buffer - m_lightCullInfoBuf.UpdateBufferContent(g_tileLightsCull, sizeof(STiledLightCullInfo) * MaxNumTileLights); - m_LightShadeInfoBuf.UpdateBufferContent(g_tileLightsShade, sizeof(STiledLightShadeInfo) * MaxNumTileLights); - - - rd->GetVolumetricFog().PrepareLightList(lightLists[0], lightLists[1], lightLists[2], firstShadowLight, curShadowPoolLight); -} - -void CTiledShading::PrepareShadowCastersList(TArray& defLights) -{ - uint32 firstShadowLight = CDeferredShading::Instance().m_nFirstCandidateShadowPoolLight; - uint32 curShadowPoolLight = CDeferredShading::Instance().m_nCurrentShadowPoolLight; - - m_arrShadowCastingLights.SetUse(0); - - for (int lightIdx = firstShadowLight; lightIdx < curShadowPoolLight; ++lightIdx) - { - const SRenderLight& light = defLights[lightIdx]; - if (light.m_Flags & DLF_CASTSHADOW_MAPS) - { - m_arrShadowCastingLights.Add(light.m_lightId); - } - } -} - -void CTiledShading::PrepareClipVolumeList(Vec4* clipVolumeParams) -{ - STiledClipVolumeInfo clipVolumeInfo[MaxNumClipVolumes]; - for (uint32 volumeIndex = 0; volumeIndex < MaxNumClipVolumes; ++volumeIndex) - { - clipVolumeInfo[volumeIndex].data = clipVolumeParams[volumeIndex].w; - } - - m_clipVolumeInfoBuf.UpdateBufferContent(clipVolumeInfo, sizeof(STiledClipVolumeInfo) * MaxNumClipVolumes); -} - -void CTiledShading::Render(TArray& envProbes, TArray& ambientLights, TArray& defLights, Vec4* clipVolumeParams) -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - if (!CTexture::s_ptexHDRTarget) // Sketch mode - { - return; - } - - // Temporary hack until tiled shading has proper MSAA support - if (CRenderer::CV_r_DeferredShadingTiled == 2 && CRenderer::CV_r_msaa) - { - CRenderer::CV_r_DeferredShadingTiled = 1; - } - - // Generate shadow mask. Note that in tiled forward only mode the shadow mask is generated in CDeferredShading::DeferredShadingPass() - if (CRenderer::CV_r_DeferredShadingTiled > 1) - { - PROFILE_LABEL_SCOPE("SHADOWMASK"); - - PrepareShadowCastersList(defLights); - rd->FX_DeferredShadowMaskGen(m_arrShadowCastingLights); - - rd->FX_SetActiveRenderTargets(false); - } - - PROFILE_LABEL_SCOPE("TILED_SHADING"); - - PrepareClipVolumeList(clipVolumeParams); - - PrepareLightList(envProbes, ambientLights, defLights); - - // Make sure HDR target is not bound as RT any more - rd->FX_PushRenderTarget(0, CTexture::s_ptexSceneSpecularAccMap, NULL); - - uint64 nPrevRTFlags = rd->m_RP.m_FlagsShader_RT; - rd->m_RP.m_FlagsShader_RT &= ~(g_HWSR_MaskBit[HWSR_SAMPLE0] | g_HWSR_MaskBit[HWSR_SAMPLE1] | g_HWSR_MaskBit[HWSR_SAMPLE2] | g_HWSR_MaskBit[HWSR_SAMPLE3] | g_HWSR_MaskBit[HWSR_SAMPLE4] | g_HWSR_MaskBit[HWSR_SAMPLE5] | g_HWSR_MaskBit[HWSR_DEBUG0] | g_HWSR_MaskBit[HWSR_APPLY_SSDO]); - - if (CRenderer::CV_r_DeferredShadingTiled > 1) // Tiled deferred - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - if (CRenderer::CV_r_DeferredShadingTiled == 4) // Light coverage visualization - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - if (CRenderer::CV_r_ssdoColorBleeding) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - if (CRenderer::CV_r_SSReflections) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE3]; - } - - bool isRenderingFur = FurPasses::GetInstance().IsRenderingFur(); - if (CRenderer::CV_r_DeferredShadingSSS || isRenderingFur) - { - // Output diffuse accumulation if SSS is enabled or if there are render items using fur - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingAreaLights > 0) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - if (CRenderer::CV_r_ApplyToonShading > 0) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_TOON_SHADING]; - } - - if (CRenderer::CV_r_ssdo) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_APPLY_SSDO]; - } - - if (CRenderer::CV_r_SlimGBuffer) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SLIM_GBUFFER]; - } - - if IsCVarConstAccess(constexpr) (CRenderer::CV_r_DeferredShadingLBuffersFmt == 2) - { - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEFERRED_RENDER_TARGET_OPTIMIZATION]; - } -#if defined(FEATURE_SVO_GI) - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_CUBEMAP0]; - rd->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D]; - - if (CSvoRenderer::GetInstance()->IsActive()) - { - int nModeGI = CSvoRenderer::GetInstance()->GetIntegratioMode(); - - if (nModeGI == 0 && gEnv->pConsole->GetCVar("e_svoTI_UseLightProbes")->GetIVal()) - { // AO modulates diffuse and specular - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - } - else if (nModeGI <= 1) - { // GI replaces diffuse and modulates specular - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D]; - } - else if (nModeGI == 2) - { // GI replaces diffuse and specular - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_CUBEMAP0]; - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DECAL_TEXGEN_2D]; - } - } -#endif - - // Selectively enables debug mode permutation if a debug parameter is non-zero. - bool bDebugEnabled = false; - Vec4 vDebugParams( - (float)rd->CV_r_DeferredShadingTiledDebugDirect, - (float)rd->CV_r_DeferredShadingTiledDebugIndirect, - (float)rd->CV_r_DeferredShadingTiledDebugAccumulation, - (float)rd->CV_r_DeferredShadingTiledDebugAlbedo); - if (vDebugParams.Dot(vDebugParams) > 0.0f) // Simple check to see if anything is enabled. - { - bDebugEnabled = true; - rd->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - } - - static CCryNameTSCRC techTiledShading("TiledDeferredShading"); - - uint32 nScreenWidth = rd->GetWidth(); - uint32 nScreenHeight = rd->GetHeight(); - uint32 dispatchSizeX = nScreenWidth / LightTileSizeX + (nScreenWidth % LightTileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = nScreenHeight / LightTileSizeY + (nScreenHeight % LightTileSizeY > 0 ? 1 : 0); - - const bool shaderAvailable = SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, techTiledShading, FEF_DONTSETSTATES); - if (shaderAvailable) // Temporary workaround for a shader cache issue - { - D3DShaderResourceView* pTiledBaseRes[8] = { - m_LightShadeInfoBuf.GetShaderResourceView(), - m_specularProbeAtlas.texArray->GetShaderResourceView(), - m_diffuseProbeAtlas.texArray->GetShaderResourceView(), - m_spotTexAtlas.texArray->GetShaderResourceView(), - CTexture::s_ptexRT_ShadowPool->GetShaderResourceView(), - CTextureManager::Instance()->GetDefaultTexture("ShadowJitterMap")->GetShaderResourceView(), - m_lightCullInfoBuf.GetShaderResourceView(), - m_clipVolumeInfoBuf.GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pTiledBaseRes, 16, 8); - - CTexture* texClipVolumeIndex = CTexture::s_ptexVelocity; - CTexture* pTexCaustics = m_bApplyCaustics ? CTexture::s_ptexSceneTargetR11G11B10F[1] : CTextureManager::Instance()->GetBlackTexture(); - - CTexture* ptexGiDiff = CTextureManager::Instance()->GetBlackTexture(); - CTexture* ptexGiSpec = CTextureManager::Instance()->GetBlackTexture(); - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetInstance()->IsActive() && CSvoRenderer::GetInstance()->GetSpecularFinRT()) - { - ptexGiDiff = (CTexture*)CSvoRenderer::GetInstance()->GetDiffuseFinRT(); - ptexGiSpec = (CTexture*)CSvoRenderer::GetInstance()->GetSpecularFinRT(); - } -#endif - - CTexture* ptexDepth = CTexture::s_ptexZTarget; - if (isRenderingFur) - { - ptexDepth = CTexture::s_ptexFurZTarget; - } - - D3DShaderResourceView* pDeferredShadingRes[13] = { - ptexDepth->GetShaderResourceView(), - CTexture::s_ptexSceneNormalsMap->GetShaderResourceView(), - CTexture::s_ptexSceneSpecular->GetShaderResourceView(), - CTexture::s_ptexSceneDiffuse->GetShaderResourceView(), - CTexture::s_ptexShadowMask->GetShaderResourceView(), - CTexture::s_ptexSceneNormalsBent->GetShaderResourceView(), - CTexture::s_ptexHDRTargetScaledTmp[0]->GetShaderResourceView(), - CTextureManager::Instance()->GetDefaultTexture("EnvironmentBRDF")->GetShaderResourceView(), - texClipVolumeIndex->GetShaderResourceView(), - CTexture::s_ptexAOColorBleed->GetShaderResourceView(), - ptexGiDiff->GetShaderResourceView(), - ptexGiSpec->GetShaderResourceView(), - pTexCaustics->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pDeferredShadingRes, 0, 13); - - if (bDebugEnabled) - { - static CCryNameR paramDebug("LightingDebugParams"); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramDebug, &vDebugParams, 1); - } - - static CCryNameR paramProj("ProjParams"); - Vec4 vParamProj(rd->m_ProjMatrix.m00, rd->m_ProjMatrix.m11, rd->m_ProjMatrix.m20, rd->m_ProjMatrix.m21); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramProj, &vParamProj, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - Vec3 worldViewPos = rd->GetViewParameters().vOrigin; - static CCryNameR paramWorldViewPos("WorldViewPos"); - Vec4 vParamWorldViewPos(worldViewPos.x, worldViewPos.y, worldViewPos.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramWorldViewPos, &vParamWorldViewPos, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - Vec3 sunDir = gEnv->p3DEngine->GetSunDirNormalized(); - static CCryNameR paramSunDir("SunDir"); - Vec4 vParamSunDir(sunDir.x, sunDir.y, sunDir.z, SunDistance); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSunDir, &vParamSunDir, 1); - - Vec3 sunColor; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_COLOR, sunColor); - static CCryNameR paramSunColor("SunColor"); - Vec4 vParamSunColor(sunColor.x, sunColor.y, sunColor.z, gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_SPECULAR_MULTIPLIER)); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSunColor, &vParamSunColor, 1); - - static CCryNameR paramSSDO("SSDOParams"); - Vec4 vParamSSDO(CRenderer::CV_r_ssdoAmountDirect, CRenderer::CV_r_ssdoAmountAmbient, CRenderer::CV_r_ssdoAmountReflection, 0); - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetInstance()->IsActive()) - { - vParamSSDO *= CSvoRenderer::GetInstance()->GetSsaoAmount(); - } -#endif - - Vec4 vParamSSDONull(0, 0, 0, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSSDO, CRenderer::CV_r_ssdo ? &vParamSSDO : &vParamSSDONull, 1); - - rd->FX_Commit(); - - ID3D11UnorderedAccessView* pUAV[3] = { - m_tileLightIndexBuf.GetUnorderedAccessView(), - CTexture::s_ptexHDRTarget->GetDeviceUAV(), - CTexture::s_ptexSceneTargetR11G11B10F[0]->GetDeviceUAV(), - }; - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 3, pUAV, NULL); - - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - SD3DPostEffectsUtils::ShEndPass(); - } - - ID3D11UnorderedAccessView* pUAVNull[3] = { NULL }; - rd->GetDeviceContext().CSSetUnorderedAccessViews(0, 3, pUAVNull, NULL); - - D3DShaderResourceView* pSRVNull[13] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 0, 13); - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 16, 8); - - rd->FX_PopRenderTarget(0); - - rd->m_RP.m_FlagsShader_RT = nPrevRTFlags; - - // Output debug information - if (CRenderer::CV_r_DeferredShadingTiled == 3) - { - rd->Draw2dLabel(20, 60, 2.0f, Col_Blue, false, "Tiled Shading Debug"); - rd->Draw2dLabel(20, 95, 1.7f, m_numSkippedLights > 0 ? Col_Red : Col_Blue, false, "Skipped Lights: %i", m_numSkippedLights); - rd->Draw2dLabel(20, 120, 1.7f, Col_Blue, false, "Atlas Updates: %i", m_numAtlasUpdates); - } - - m_bApplyCaustics = false; // Reset flag -} - -void CTiledShading::BindForwardShadingResources(CShader*, EHWShaderClass shaderType) -{ - if (!CRenderer::CV_r_DeferredShadingTiled || !m_dispatchSizeX || !m_dispatchSizeY) - { - return; - } - AZ_TRACE_METHOD(); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - CTexture* ptexGiDiff = CTextureManager::Instance()->GetBlackTexture(); - CTexture* ptexGiSpec = CTextureManager::Instance()->GetBlackTexture(); - CTexture* ptexRsmCol = NULL; - CTexture* ptexRsmNor = NULL; - -#if defined(FEATURE_SVO_GI) - if (CSvoRenderer::GetInstance()->IsActive() && CSvoRenderer::GetInstance()->GetSpecularFinRT()) - { - ptexGiDiff = (CTexture*)CSvoRenderer::GetInstance()->GetDiffuseFinRT(); - ptexGiSpec = (CTexture*)CSvoRenderer::GetInstance()->GetSpecularFinRT(); - ptexRsmCol = (CTexture*)CSvoRenderer::GetInstance()->GetRsmPoolCol(); - ptexRsmNor = (CTexture*)CSvoRenderer::GetInstance()->GetRsmPoolNor(); - } -#endif - - D3DShaderResourceView* pTiledBaseRes[12] = { - m_LightShadeInfoBuf.GetShaderResourceView(), - m_specularProbeAtlas.texArray->GetShaderResourceView(), - m_diffuseProbeAtlas.texArray->GetShaderResourceView(), - m_spotTexAtlas.texArray->GetShaderResourceView(), - CTexture::s_ptexRT_ShadowPool->GetShaderResourceView(), - CTextureManager::Instance()->GetDefaultTexture("ShadowJitterMap")->GetShaderResourceView(), - m_tileLightIndexBuf.GetShaderResourceView(), - m_clipVolumeInfoBuf.GetShaderResourceView(), - ptexGiDiff->GetShaderResourceView(), - ptexGiSpec->GetShaderResourceView(), - ptexRsmCol ? ptexRsmCol->GetShaderResourceView() : NULL, - ptexRsmNor ? ptexRsmNor->GetShaderResourceView() : NULL, - }; - - rd->m_DevMan.BindSRV(shaderType, pTiledBaseRes, 16, 12); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateCompare].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(shaderType, pSamplers, 14, 1); -} - - -void CTiledShading::UnbindForwardShadingResources(EHWShaderClass shaderType) -{ - if (!CRenderer::CV_r_DeferredShadingTiled) - { - return; - } - AZ_TRACE_METHOD(); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - D3DShaderResourceView* pNullViews[12] = { NULL }; - rd->m_DevMan.BindSRV(shaderType, pNullViews, 16, 12); - - D3DSamplerState* pNullSamplers[1] = { NULL }; - rd->m_DevMan.BindSampler(shaderType, pNullSamplers, 14, 1); -} - -struct STiledLightShadeInfo* CTiledShading::GetTiledLightShadeInfo() -{ - return &g_tileLightsShade[0]; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.h deleted file mode 100644 index 03b6f3be03..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DTiledShading.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _D3DTILEDSHADING_H_ -#define _D3DTILEDSHADING_H_ - -struct STiledLightCullInfo; -class CD3D9Renderer; - -struct STiledLightShadeInfo -{ - uint32 lightType; - uint32 resIndex; - uint32 shadowMaskIndex; - uint16 stencilID0; - uint16 stencilID1; - Vec4 posRad; - Vec4 dirCosAngle; - Vec2 attenuationParams; - Vec2 shadowParams; - Vec4 color; - Vec4 shadowChannelIndex; - Matrix44 projectorMatrix; - Matrix44 shadowMatrix; -}; // 256 bytes - -class CTiledShading -{ -protected: - struct AtlasItem - { - ITexture* texture; - int updateFrameID; - int accessFrameID; - bool invalid; - - AtlasItem() - : texture(NULL) - , updateFrameID(-1) - , accessFrameID(0) - , invalid(false) {} - }; - - struct TextureAtlas - { - CTexture* texArray; - std::vector items; - - TextureAtlas() - : texArray(NULL) {} - }; - -public: - CTiledShading(); - - void CreateResources(); - void DestroyResources(bool destroyResolutionIndependentResources); - void Clear(); - - void Render(TArray& envProbes, TArray& ambientLights, TArray& defLights, Vec4* clipVolumeParams); - - void BindForwardShadingResources(CShader* pShader, EHWShaderClass shType = eHWSC_Pixel); - void UnbindForwardShadingResources(EHWShaderClass shType = eHWSC_Pixel); - - STiledLightShadeInfo* GetTiledLightShadeInfo(); - - int InsertTextureToSpecularProbeAtlas(CTexture* texture, int arrayIndex) {return InsertTexture(texture, m_specularProbeAtlas, arrayIndex); } - int InsertTextureToDiffuseProbeAtlas(CTexture* texture, int arrayIndex) {return InsertTexture(texture, m_diffuseProbeAtlas, arrayIndex); } - int InsertTextureToSpotTexAtlas(CTexture* texture, int arrayIndex) {return InsertTexture(texture, m_spotTexAtlas, arrayIndex); } - - void NotifyCausticsVisible() { m_bApplyCaustics = true; } - -protected: - int InsertTexture(CTexture* texture, TextureAtlas& atlas, int arrayIndex); - void PrepareLightList(TArray& envProbes, TArray& ambientLights, TArray& defLights); - void PrepareEnvironmentProbes(bool& shouldAdd, SRenderLight& renderLight, STiledLightCullInfo& lightCullInfo, STiledLightShadeInfo& lightShadeInfo, Matrix44A& matView, const float invCameraFar, const Vec4& posVS); - void PrepareRegularAndAmbientLights(bool& shouldAdd, SRenderLight& renderLight, STiledLightCullInfo& lightCullInfo, STiledLightShadeInfo& lightShadeInfo, Matrix44A& matView, const float invCameraFar, const Vec4& posVS, - const bool ambientLight, CD3D9Renderer* const __restrict rd, const bool areaLightRect, const uint32 lightIdx, const uint32 firstShadowLight,const uint32 curShadowPoolLight, const int nThreadID, const int nRecurseLevel, - uint32& numTileLights); - - void PrepareShadowCastersList(TArray& defLights); - void PrepareClipVolumeList(Vec4* clipVolumeParams); - -protected: - uint32 m_dispatchSizeX, m_dispatchSizeY; - - WrappedDX11Buffer m_lightCullInfoBuf; - WrappedDX11Buffer m_LightShadeInfoBuf; - WrappedDX11Buffer m_tileLightIndexBuf; - - WrappedDX11Buffer m_clipVolumeInfoBuf; - - TextureAtlas m_specularProbeAtlas; - TextureAtlas m_diffuseProbeAtlas; - TextureAtlas m_spotTexAtlas; - - uint32 m_nTexStateTriLinear; - uint32 m_nTexStateCompare; - - uint32 m_numSkippedLights; - uint32 m_numAtlasUpdates; - - TArray m_arrShadowCastingLights; - - bool m_bApplyCaustics; -}; - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.cpp deleted file mode 100644 index bd4e32e62b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.cpp +++ /dev/null @@ -1,3055 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "D3DVolumetricFog.h" -#include "DriverD3D.h" -#include "D3DPostProcess.h" -#include "CREFogVolume.h" - - -#define ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define D3DVOLUMETRICFOG_CPP_SECTION_1 1 -#endif - -namespace vfInternal -{ - static const uint32 MaxNumTileLights = 255; - - static const uint32 MaxNumFogVolumes = 64; - - static const float ThresholdLengthGlobalProbe = 1.732f * (1000.0f * 0.5f); - - enum EVolumeVolumeTypes - { - tlVolumeSphere = 1, - tlVolumeCone = 2, - tlVolumeOBB = 3, - tlVolumeSun = 4, - }; - - enum EVolumeLightTypes - { - tlTypeProbe = 1, - tlTypeAmbientPoint = 2, - tlTypeAmbientProjector = 3, - tlTypeAmbientArea = 4, - tlTypeRegularPoint = 5, - tlTypeRegularProjector = 6, - tlTypeRegularPointFace = 7, - tlTypeRegularArea = 8, - tlTypeSun = 9, - }; - - struct SVolumeLightCullInfo - { - uint32 volumeType; - uint32 miscFlag; - Vec2 depthBounds; - Vec4 posRad; - Vec4 volumeParams0; - Vec4 volumeParams1; - Vec4 volumeParams2; - }; // 80 bytes - - struct SVolumeLightShadeInfo - { - uint32 lightType; - uint32 resIndex; - uint32 shadowMaskIndex; - uint16 stencilID0; - uint16 stencilID1; - Vec4 posRad; - Vec2 attenuationParams; - Vec2 shadowParams; - Vec4 color; - Vec4 shadowChannelIndex; - Matrix44 projectorMatrix; - Matrix44 shadowMatrix; - }; // 208 bytes - - struct SFogVolumeCullInfo - { - Vec4 posRad; - Vec4 volumeParams0; - Vec4 volumeParams1; - Vec4 volumeParams2; - }; - - struct SFogVolumeInjectInfo - { - uint32 miscFlag; // 1: volumeType, 8: stencilRef, 1: affectThisAreaOnly, 22: reserved - Vec3 fogColor; - - float globalDensity; - Vec3 fogVolumePos; - - Vec3 heightFalloffBasePoint; - float invSoftEdgeLerp; - - Vec3 heightFallOffDirScaled; - float densityOffset; - - Vec4 rampParams; - - Vec3 windOffset; - float noiseElapsedTime; - - Vec3 noiseSpatialFrequency; - float noiseScale; - - Vec3 eyePosInOS; - float noiseOffset; - - Matrix34 worldToObjMatrix; - }; - - int GetVolumeTexDepth() - { - int d = CRenderer::CV_r_VolumetricFogTexDepth; - d = (d < 4) ? 4 : d; - #if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION D3DVOLUMETRICFOG_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(D3DVolumetricFog_cpp) - #endif - - #if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED - #else - d = (d > 255) ? 255 : d;// this limitation due to the limitation of CTexture::CreateTextureArray. - #endif - int f = d % 4; - d = (f > 0) ? d - f : d;// depth should be the multiples of 4. - return d; - } - - int GetVolumeTexSize(int size, int scale) - { - scale = max(scale, 2); - return (size / scale) + ((size % scale) > 0 ? 1 : 0); - } - - AABB RotateAABB(const AABB& aabb, const Matrix33& mat) - { - Matrix33 matAbs; - matAbs.m00 = fabs_tpl(mat.m00); - matAbs.m01 = fabs_tpl(mat.m01); - matAbs.m02 = fabs_tpl(mat.m02); - matAbs.m10 = fabs_tpl(mat.m10); - matAbs.m11 = fabs_tpl(mat.m11); - matAbs.m12 = fabs_tpl(mat.m12); - matAbs.m20 = fabs_tpl(mat.m20); - matAbs.m21 = fabs_tpl(mat.m21); - matAbs.m22 = fabs_tpl(mat.m22); - - Vec3 sz = ((aabb.max - aabb.min) * 0.5f) * matAbs; - Vec3 pos = ((aabb.max + aabb.min) * 0.5f) * mat; - - return AABB(pos - sz, pos + sz); - } -} - - -CVolumetricFog::CVolumetricFog() -{ - STATIC_ASSERT(MaxFrameNum >= MAX_GPU_NUM, "MaxFrameNum must be more than or equal to MAX_GPU_NUM."); - - for (int i = 0; i < MaxFrameNum; ++i) - { - m_viewProj[i].SetIdentity(); - } - - m_InscatteringVolume = NULL; - m_fogInscatteringVolume[0] = NULL; - m_fogInscatteringVolume[1] = NULL; - m_MaxDepth = NULL; - m_MaxDepthTemp = NULL; - m_ClipVolumeDSVArray = NULL; - m_fogDensityVolume[0] = NULL; - m_fogDensityVolume[1] = NULL; - for (int i = 0; i < 3; ++i) - { - m_downscaledShadow[i] = NULL; - } - m_downscaledShadowTemp = NULL; - m_globalEnvProveTex0 = NULL; - m_globalEnvProveTex1 = NULL; - - m_nTexStateTriLinear = -1; - m_nTexStateCompare = -1; - m_nTexStatePoint = -1; - m_Cleared = MaxFrameNum; - m_Destroyed = MaxFrameNum; - m_numTileLights = 0; - m_numFogVolumes = 0; - m_frameID = -1; - m_tick = 0; - m_ReverseDepthMode = 1; - m_raymarchDistance = 0.0f; - m_globalEnvProbeParam0 = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - m_globalEnvProbeParam1 = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - for (int k = 0; k < MaxNumFogVolumeType; ++k) - { - m_fogVolumeInfoArray[i][j][k].Reserve(vfInternal::MaxNumFogVolumes); - } - } - } -} - -void CVolumetricFog::CreateResources() -{ - static const ICVar* pCVarVolumetricFog = NULL; - if (!pCVarVolumetricFog) - { - pCVarVolumetricFog = gEnv->pConsole->GetCVar("e_VolumetricFog"); - } - - if (!pCVarVolumetricFog || pCVarVolumetricFog->GetIVal() == 0) - { - return; - } - - // downscaled shadow maps - ETEX_Format shadowFormat = eTF_D32F; - static const ICVar* pCVarShadowMaxTexRes = NULL; - if (!pCVarShadowMaxTexRes) - { - pCVarShadowMaxTexRes = gEnv->pConsole->GetCVar("e_ShadowsMaxTexRes"); - } - int widthShadowMap = 0; - int widthShadowMapTemp = 0; - if (pCVarShadowMaxTexRes) - { - widthShadowMapTemp = max(pCVarShadowMaxTexRes->GetIVal(), 32);//this restriction is same as it in CD3D9Renderer::PrepareShadowGenForFrustum. - switch (CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio) - { - case 0: - widthShadowMapTemp /= 4; - widthShadowMap = widthShadowMapTemp; - break; - case 1: - widthShadowMapTemp /= 4; - widthShadowMap = widthShadowMapTemp / 2; - break; - case 2: - widthShadowMapTemp /= 4; - widthShadowMap = widthShadowMapTemp / 4; - break; - default: - widthShadowMapTemp /= 4; - widthShadowMap = widthShadowMapTemp / 4; - break; - } - } - - // view frustum aligned volume texture - int width = vfInternal::GetVolumeTexSize(gRenDev->GetWidth(), CRenderer::CV_r_VolumetricFogTexScale); - int height = vfInternal::GetVolumeTexSize(gRenDev->GetHeight(), CRenderer::CV_r_VolumetricFogTexScale); - int depth = vfInternal::GetVolumeTexDepth(); -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - ETEX_Format fmt = eTF_R16G16B16A16F; -#else - ETEX_Format fmt = eTF_R11G11B10F; -#endif - ETEX_Format fmtDensityColor = eTF_R11G11B10F; - ETEX_Format fmtDensity = eTF_R16F; - - - bool validVolumeTexture = m_InscatteringVolume - && (m_InscatteringVolume->GetWidth() == width) - && (m_InscatteringVolume->GetHeight() == height) - && (m_InscatteringVolume->GetDepth() == depth) - && (m_InscatteringVolume->GetDstFormat() == fmt) - && CTexture::s_ptexVolumetricFogDensityColor - && (CTexture::s_ptexVolumetricFogDensityColor->GetDstFormat() == fmtDensityColor); - - bool validDownscaledShadowMaps = (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 0 && !m_downscaledShadow[0]) - || (CRenderer::CV_r_VolumetricFogDownscaledSunShadow != 0 - && m_downscaledShadow[0] && m_downscaledShadow[0]->GetWidth() == widthShadowMap - && m_downscaledShadow[0]->GetDstFormat() == shadowFormat - && ((CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 1 && !m_downscaledShadow[2]) - || (CRenderer::CV_r_VolumetricFogDownscaledSunShadow != 1 && m_downscaledShadow[2]))); - - if (validVolumeTexture && validDownscaledShadowMaps) - { - return; - } - else - { - DestroyResources(false); - } - - STexState ts0(FILTER_TRILINEAR, true); - STexState ts1(FILTER_BILINEAR, true); - STexState ts2(FILTER_POINT, true); - ts1.SetComparisonFilter(true); - m_nTexStateTriLinear = CTexture::GetTexState(ts0); - m_nTexStateCompare = CTexture::GetTexState(ts1); - m_nTexStatePoint = CTexture::GetTexState(ts2); - - - uint32 commonFlags = FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM; - - assert(!m_InscatteringVolume); - if (!m_InscatteringVolume) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - //ETEX_Format format = eTF_R8G8B8A8; - //uint32 flags = FT_NOMIPS | FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_UNORDERED_ACCESS | FT_USAGE_UAV_RWTEXTURE; - ETEX_Format format = fmt; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - m_InscatteringVolume = CTexture::CreateTextureObject("$InscatteringVolume", w, h, d, eTT_3D, flags, format); - const byte* pData[6] = {NULL}; - m_InscatteringVolume->CreateDeviceTexture(pData); - - if (m_InscatteringVolume->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - - { - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - - assert(CTexture::s_ptexVolumetricFog); - if (CTexture::s_ptexVolumetricFog) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = eTF_R16G16B16A16F; - if (!CTexture::s_ptexVolumetricFog->Create3DTexture(w, h, d, 1, flags, NULL, format, format)) - { - CryFatalError("Couldn't allocate texture."); - } - } - } - - { - const char* tname[2] = - { - "$FogInscatteringVolume0", - "$FogInscatteringVolume1", - }; - - for (int i = 0; i < 2; ++i) - { - assert(!m_fogInscatteringVolume[i]); - if (!m_fogInscatteringVolume[i]) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = fmt; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - m_fogInscatteringVolume[i] = CTexture::CreateTextureObject(tname[i], w, h, d, eTT_3D, flags, format); - const byte* pData[6] = {NULL}; - m_fogInscatteringVolume[i]->CreateDeviceTexture(pData); - - if (m_fogInscatteringVolume[i]->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - } - } - - assert(!m_MaxDepth); - if (!m_MaxDepth) - { - const int32 w = width; - const int32 h = height; - ETEX_Format format = eTF_R16F; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - m_MaxDepth = CTexture::CreateTextureObject("$MaxDepth", w, h, 1, eTT_2D, flags, format); - const byte* pData[6] = {NULL}; - m_MaxDepth->CreateDeviceTexture(pData); - - if (m_MaxDepth->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - - assert(!m_MaxDepthTemp); - if (!m_MaxDepthTemp) - { - const int32 w = width << 1; - const int32 h = CTexture::s_ptexZTargetScaled->GetHeight() >> 1; - ETEX_Format format = eTF_R16F; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - m_MaxDepthTemp = CTexture::CreateTextureObject("$MaxDepthTemp", w, h, 1, eTT_2D, flags, format); - const byte* pData[6] = {NULL}; - m_MaxDepthTemp->CreateDeviceTexture(pData); - - if (m_MaxDepthTemp->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - - assert(!m_ClipVolumeDSVArray); - if (!m_ClipVolumeDSVArray) - { - typedef D3DDepthSurface* DSVPTR; - m_ClipVolumeDSVArray = new DSVPTR[depth]; - for (int i = 0; i < depth; ++i) - { - m_ClipVolumeDSVArray[i] = NULL; - } - } - - assert(CTexture::s_ptexVolumetricClipVolumeStencil); - if (CTexture::s_ptexVolumetricClipVolumeStencil) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = eTF_D24S8; - uint32 flags = commonFlags | FT_USAGE_DEPTHSTENCIL | FT_USAGE_RENDERTARGET; - CTexture* ptex = CTexture::CreateTextureArray("$ClipVolumeStencilVolume", eTT_2D, w, h, d, 1, flags, format); - - // texture name has to exactly match the name of CTexture::s_ptexVolumetricClipVolumeStencil. - if (CTexture::s_ptexVolumetricClipVolumeStencil != ptex || CTexture::s_ptexVolumetricClipVolumeStencil->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate volumetric clip volume stencil texture."); - } - - // This is the code for working around that stencil readable shader resource view can't be created directly. - D3DShaderResourceView* pSRV = CTexture::s_ptexVolumetricClipVolumeStencil->GetShaderResourceView(); - pSRV->Release(); - D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; - ZeroStruct(SRVDesc); - SRVDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - D3DTexture* pID3DTexture = CTexture::s_ptexVolumetricClipVolumeStencil->GetDevTexture()->Get2DTexture(); - SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - SRVDesc.Texture2DArray.FirstArraySlice = 0; - SRVDesc.Texture2DArray.ArraySize = d; - SRVDesc.Texture2DArray.MipLevels = 1; - SRVDesc.Texture2DArray.MostDetailedMip = 0; - HRESULT hr = gcpRendD3D->GetDevice().CreateShaderResourceView(pID3DTexture, &SRVDesc, &pSRV); - assert(SUCCEEDED(hr)); - CTexture::s_ptexVolumetricClipVolumeStencil->SetShaderResourceView(pSRV); - - // Separate DSVs need to be created because of performance issue of drawing to single DSV array. - ID3D11DepthStencilView* pDSV; - D3D11_DEPTH_STENCIL_VIEW_DESC DsvDesc; - ZeroStruct(DsvDesc); - DsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - DsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - DsvDesc.Texture2DArray.ArraySize = 1; - DsvDesc.Texture2DArray.MipSlice = 0; - for (int i = 0; i < d; ++i) - { - DsvDesc.Texture2DArray.FirstArraySlice = i; - pDSV = NULL; - hr = gcpRendD3D->GetDevice().CreateDepthStencilView(pID3DTexture, &DsvDesc, &pDSV); - assert(SUCCEEDED(hr)); - m_ClipVolumeDSVArray[i] = pDSV; - } - } - - assert(CTexture::s_ptexVolumetricFogDensityColor); - if (CTexture::s_ptexVolumetricFogDensityColor) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = fmtDensityColor; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS | FT_USAGE_RENDERTARGET; - - CTexture::s_ptexVolumetricFogDensityColor->Invalidate(w, h, format); - - if (!CTexture::s_ptexVolumetricFogDensityColor->Create3DTexture(w, h, d, 1, flags, NULL, format, format)) - { - CryFatalError("Couldn't allocate texture."); - } - } - - assert(CTexture::s_ptexVolumetricFogDensity); - if (CTexture::s_ptexVolumetricFogDensity) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = fmtDensity; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS | FT_USAGE_RENDERTARGET; - - CTexture::s_ptexVolumetricFogDensity->Invalidate(w, h, format); - - if (!CTexture::s_ptexVolumetricFogDensity->Create3DTexture(w, h, d, 1, flags, NULL, format, format)) - { - CryFatalError("Couldn't allocate texture."); - } - } - -#ifndef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - { - const char* tname[2] = - { - "$FogDensityVolume0", - "$FogDensityVolume1", - }; - - for (int i = 0; i < 2; ++i) - { - assert(!m_fogDensityVolume[i]); - if (!m_fogDensityVolume[i]) - { - const int32 w = width; - const int32 h = height; - const int32 d = depth; - ETEX_Format format = fmtDensity; - uint32 flags = commonFlags | FT_USAGE_UNORDERED_ACCESS; - m_fogDensityVolume[i] = CTexture::CreateTextureObject(tname[i], w, h, d, eTT_3D, flags, format); - m_fogDensityVolume[i]->CreateRenderTarget(format); - - if (m_fogDensityVolume[i]->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - } - } -#endif - - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadow != 0) - { - const char* tname[3] = - { - "$DownscaledShadowMaps0", - "$DownscaledShadowMaps1", - "$DownscaledShadowMaps2", - }; - - int count = (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 1) ? 2 : 3; - for (int i = 0; i < count; ++i) - { - assert(!m_downscaledShadow[i]); - if (!m_downscaledShadow[i]) - { - uint32 flags = commonFlags | FT_USAGE_DEPTHSTENCIL | FT_USAGE_RENDERTARGET; - - m_downscaledShadow[i] = CTexture::Create2DTexture(tname[i], widthShadowMap, widthShadowMap, 1, flags, NULL, shadowFormat, shadowFormat); - } - - if (!m_downscaledShadow[i] || m_downscaledShadow[i]->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio != 0) - { - assert(!m_downscaledShadowTemp); - if (!m_downscaledShadowTemp) - { - uint32 flags = commonFlags | FT_USAGE_DEPTHSTENCIL | FT_USAGE_RENDERTARGET; - - m_downscaledShadowTemp = CTexture::Create2DTexture("$DownscaledShadowMapsTemp", widthShadowMapTemp, widthShadowMapTemp, 1, flags, NULL, shadowFormat, shadowFormat); - } - - if (!m_downscaledShadowTemp || m_downscaledShadowTemp->GetFlags() & FT_FAILED) - { - CryFatalError("Couldn't allocate texture."); - } - } - } - - if (!m_lightCullInfoBuf.m_pBuffer) - { - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - uint32 stride = sizeof(vfInternal::SVolumeLightCullInfo); - m_lightCullInfoBuf.Create(vfInternal::MaxNumTileLights, stride, format, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_LightShadeInfoBuf.m_pBuffer) - { - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - uint32 stride = sizeof(vfInternal::SVolumeLightShadeInfo); - m_LightShadeInfoBuf.Create(vfInternal::MaxNumTileLights, stride, format, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_lightGridBuf.m_pBuffer) - { - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - const uint32 dispatchSizeX = (width / tileSizeX) + (width % tileSizeX > 0 ? 1 : 0); - const uint32 dispatchSizeY = (height / tileSizeY) + (height % tileSizeY > 0 ? 1 : 0); - const uint32 dispatchSizeZ = (depth / tileSizeZ) + (depth % tileSizeZ > 0 ? 1 : 0); - DXGI_FORMAT format = DXGI_FORMAT_R8_UINT; - uint32 stride = sizeof(char); - m_lightGridBuf.Create(dispatchSizeX * dispatchSizeY * dispatchSizeZ * vfInternal::MaxNumTileLights, stride, format, DX11BUF_BIND_SRV | DX11BUF_BIND_UAV, NULL); - } - - if (!m_lightCountBuf.m_pBuffer) - { - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - const uint32 dispatchSizeX = (width / tileSizeX) + (width % tileSizeX > 0 ? 1 : 0); - const uint32 dispatchSizeY = (height / tileSizeY) + (height % tileSizeY > 0 ? 1 : 0); - const uint32 dispatchSizeZ = (depth / tileSizeZ) + (depth % tileSizeZ > 0 ? 1 : 0); - DXGI_FORMAT format = DXGI_FORMAT_R8_UINT; - uint32 stride = sizeof(char); - m_lightCountBuf.Create(dispatchSizeX * dispatchSizeY * dispatchSizeZ, stride, format, DX11BUF_BIND_SRV | DX11BUF_BIND_UAV, NULL); - } - - if (!m_fogVolumeCullInfoBuf.m_pBuffer) - { - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - uint32 stride = sizeof(vfInternal::SFogVolumeCullInfo); - m_fogVolumeCullInfoBuf.Create(vfInternal::MaxNumFogVolumes, stride, format, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } - - if (!m_fogVolumeInjectInfoBuf.m_pBuffer) - { - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - uint32 stride = sizeof(vfInternal::SFogVolumeInjectInfo); - m_fogVolumeInjectInfoBuf.Create(vfInternal::MaxNumFogVolumes, stride, format, DX11BUF_DYNAMIC | DX11BUF_STRUCTURED | DX11BUF_BIND_SRV, NULL); - } -} - -void CVolumetricFog::DestroyResources(bool destroyResolutionIndependentResources) -{ - assert((m_ClipVolumeDSVArray && m_InscatteringVolume) || !(m_ClipVolumeDSVArray || m_InscatteringVolume)); - if (m_ClipVolumeDSVArray && m_InscatteringVolume) - { - int depth = m_InscatteringVolume->GetDepth(); - for (int i = 0; i < depth; ++i) - { - if (m_ClipVolumeDSVArray[i]) - { - ((ID3D11DepthStencilView*)m_ClipVolumeDSVArray[i])->Release(); - } - } - delete [] m_ClipVolumeDSVArray; - m_ClipVolumeDSVArray = NULL; - } - - SAFE_RELEASE_FORCE(m_InscatteringVolume); - SAFE_RELEASE_FORCE(m_fogInscatteringVolume[0]); - SAFE_RELEASE_FORCE(m_fogInscatteringVolume[1]); - SAFE_RELEASE_FORCE(m_MaxDepth); - SAFE_RELEASE_FORCE(m_MaxDepthTemp); - SAFE_RELEASE_FORCE(m_fogDensityVolume[0]); - SAFE_RELEASE_FORCE(m_fogDensityVolume[1]); - for (int i = 0; i < 3; ++i) - { - SAFE_RELEASE_FORCE(m_downscaledShadow[i]); - } - SAFE_RELEASE_FORCE(m_downscaledShadowTemp); - - m_lightCullInfoBuf.Release(); - m_LightShadeInfoBuf.Release(); - m_lightGridBuf.Release(); - m_lightCountBuf.Release(); - - for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - for (int k = 0; k < MaxNumFogVolumeType; ++k) - { - m_fogVolumeInfoArray[i][j][k].clear(); - } - } - } - - m_fogVolumeCullInfoBuf.Release(); - m_fogVolumeInjectInfoBuf.Release(); - - if (destroyResolutionIndependentResources) - { - if (CTexture::s_ptexVolumetricFog) - { - CTexture::s_ptexVolumetricFog->ReleaseDeviceTexture(false); - } - if (CTexture::s_ptexVolumetricClipVolumeStencil) - { - CTexture::s_ptexVolumetricClipVolumeStencil->ReleaseDeviceTexture(false); - } - if (CTexture::s_ptexVolumetricFogDensityColor) - { - CTexture::s_ptexVolumetricFogDensityColor->ReleaseDeviceTexture(false); - } - if (CTexture::s_ptexVolumetricFogDensity) - { - CTexture::s_ptexVolumetricFogDensity->ReleaseDeviceTexture(false); - } - } - - m_Cleared = MaxFrameNum; - m_Destroyed = MaxFrameNum; - m_ReverseDepthMode = CRenderer::CV_r_ReverseDepth; -} - -void CVolumetricFog::Clear() -{ - ClearFogVolumes(); -} - -void CVolumetricFog::ClearAll() -{ - Clear(); - - m_globalEnvProbeParam0 = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - m_globalEnvProbeParam1 = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - - // ClearAll() is called during shutdown and post level unload - // when we should not be rendering volumetric fog. - SAFE_RELEASE(m_globalEnvProveTex0); - SAFE_RELEASE(m_globalEnvProveTex1); - - ClearAllFogVolumes(); - m_Cleared = MaxFrameNum; -} - -void CVolumetricFog::PrepareLightList(TArray* envProbes, TArray* ambientLights, TArray* defLights, uint32 firstShadowLight, uint32 curShadowPoolLight) -{ - const ICVar* pCVarVolumetricFog = gEnv->pConsole->GetCVar("e_VolumetricFog"); - if (!pCVarVolumetricFog || pCVarVolumetricFog->GetIVal() == 0) - { - return; - } - - if (!IsViable()) - { - return; - } - - AZ_TRACE_METHOD(); - CD3D9Renderer* const __restrict rd = gcpRendD3D; - CTiledShading& tdsh = rd->GetTiledShading(); - - // Prepare view matrix with flipped z-axis - Matrix44A matView = rd->m_ViewMatrix; - matView.m02 *= -1; - matView.m12 *= -1; - matView.m22 *= -1; - matView.m32 *= -1; - - int nThreadID = rd->m_RP.m_nProcessThreadID; - int nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - uint32 numTileLights = 0; - uint32 numRenderLights = 0; - uint32 numValidRenderLights = 0; - CTexture* texGlobalEnvProbe0 = NULL; - CTexture* texGlobalEnvProbe1 = NULL; - Vec3 colorGlobalEnvProbe0(0.0f, 0.0f, 0.0f); - Vec3 colorGlobalEnvProbe1(0.0f, 0.0f, 0.0f); - float attenuationGlobalEnvProbe0 = 0.0f; - float attenuationGlobalEnvProbe1 = 0.0f; - float maxSizeGlobalEnvProbe0 = 0.0f; - float maxSizeGlobalEnvProbe1 = 0.0f; - - vfInternal::SVolumeLightCullInfo tileLightsCull[vfInternal::MaxNumTileLights]; - vfInternal::SVolumeLightShadeInfo tileLightsShade[vfInternal::MaxNumTileLights]; - - // Reset lights - ZeroMemory(tileLightsCull, sizeof(vfInternal::SVolumeLightCullInfo) * vfInternal::MaxNumTileLights); - ZeroMemory(tileLightsShade, sizeof(vfInternal::SVolumeLightShadeInfo) * vfInternal::MaxNumTileLights); - - TArray* lightLists[3] = { - CRenderer::CV_r_DeferredShadingEnvProbes ? envProbes : NULL, - CRenderer::CV_r_DeferredShadingAmbientLights ? ambientLights : NULL, - CRenderer::CV_r_DeferredShadingLights ? defLights : NULL, - }; - - const bool areaLights = CRenderer::CV_r_DeferredShadingAreaLights > 0; //convert from int to bool - const float minBulbSize = max(0.001f, min(2.0f, CRenderer::CV_r_VolumetricFogMinimumLightBulbSize));// limit the minimum bulb size to reduce the light flicker. - - for (uint32 lightListIdx = 0; lightListIdx < 3; ++lightListIdx) - { - if (lightLists[lightListIdx] == NULL) - { - continue; - } - - for (uint32 lightIdx = 0, lightListSize = lightLists[lightListIdx]->size(); lightIdx < lightListSize; ++lightIdx) - { - SRenderLight& renderLight = (*lightLists[lightListIdx])[lightIdx]; - vfInternal::SVolumeLightCullInfo& lightCullInfo = tileLightsCull[numTileLights]; - vfInternal::SVolumeLightShadeInfo& lightShadeInfo = tileLightsShade[numTileLights]; - - if ((renderLight.m_Flags & DLF_FAKE) || !(renderLight.m_Flags & DLF_VOLUMETRIC_FOG)) - { - continue; - } - - // Skip non-ambient area light if support is disabled - if ((renderLight.m_Flags & DLF_AREA_LIGHT) && !(renderLight.m_Flags & DLF_AMBIENT) && !areaLights) - { - continue; - } - - ++numRenderLights; - - if (numTileLights == vfInternal::MaxNumTileLights) - { - continue; // Skip light - } - // Setup standard parameters - bool areaLightRect = (renderLight.m_Flags & DLF_AREA_LIGHT) && renderLight.m_fAreaWidth && renderLight.m_fAreaHeight && renderLight.m_fLightFrustumAngle; - float volumeSize = (lightListIdx == 0) ? renderLight.m_ProbeExtents.len() : renderLight.m_fRadius; - Vec3 pos = renderLight.GetPosition(); - Vec3 worldViewPos = rd->GetViewParameters().vOrigin; - lightShadeInfo.posRad = Vec4(pos.x - worldViewPos.x, pos.y - worldViewPos.y, pos.z - worldViewPos.z, volumeSize); - Vec4 posVS = Vec4(pos, 1) * matView; - lightCullInfo.posRad = Vec4(posVS.x, posVS.y, posVS.z, volumeSize); - lightShadeInfo.attenuationParams = Vec2(areaLightRect ? (renderLight.m_fAreaWidth + renderLight.m_fAreaHeight) * 0.25f : renderLight.m_fAttenuationBulbSize, renderLight.m_fAreaHeight * 0.5f); - lightCullInfo.depthBounds = Vec2(posVS.z - volumeSize, posVS.z + volumeSize); - lightShadeInfo.color = Vec4(renderLight.m_Color.r, - renderLight.m_Color.g, - renderLight.m_Color.b, - renderLight.m_fFogRadialLobe); - lightShadeInfo.resIndex = 0; - lightShadeInfo.shadowParams = Vec2(0, 0); - lightShadeInfo.stencilID0 = renderLight.m_nStencilRef[0] + 1; - lightShadeInfo.stencilID1 = renderLight.m_nStencilRef[1] + 1; - - // Environment probes - if (lightListIdx == 0) - { - lightCullInfo.volumeType = vfInternal::tlVolumeOBB; - lightShadeInfo.lightType = vfInternal::tlTypeProbe; - lightShadeInfo.resIndex = 0xFFFFFFFF; - lightShadeInfo.attenuationParams.x = renderLight.m_fProbeAttenuation; - // assigning value isn't needed because AttenuationFalloffMax is hard-coded in VolumeLighting.cfi to mitigate sharp transition between probes. - //lightShadeInfo.attenuationParams.y = max( renderLight.GetFalloffMax(), 0.001f ); - lightCullInfo.miscFlag = 0; - - AABB aabb = vfInternal::RotateAABB(AABB(-renderLight.m_ProbeExtents, renderLight.m_ProbeExtents), Matrix33(renderLight.m_ObjMatrix)); - aabb = vfInternal::RotateAABB(aabb, Matrix33(matView)); - lightCullInfo.depthBounds = Vec2(posVS.z + aabb.min.z, posVS.z + aabb.max.z); - - Vec4 u0 = Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized(), 0) * matView; - Vec4 u1 = Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized(), 0) * matView; - Vec4 u2 = Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized(), 0) * matView; - lightCullInfo.volumeParams0 = Vec4(u0.x, u0.y, u0.z, renderLight.m_ProbeExtents.x); - lightCullInfo.volumeParams1 = Vec4(u1.x, u1.y, u1.z, renderLight.m_ProbeExtents.y); - lightCullInfo.volumeParams2 = Vec4(u2.x, u2.y, u2.z, renderLight.m_ProbeExtents.z); - - lightShadeInfo.projectorMatrix.SetRow4(0, Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized() / renderLight.m_ProbeExtents.x, 0)); - lightShadeInfo.projectorMatrix.SetRow4(1, Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized() / renderLight.m_ProbeExtents.y, 0)); - lightShadeInfo.projectorMatrix.SetRow4(2, Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized() / renderLight.m_ProbeExtents.z, 0)); - - Vec3 boxProxyMin(-1000000, -1000000, -1000000); - Vec3 boxProxyMax(1000000, 1000000, 1000000); - - if (renderLight.m_Flags & DLF_BOX_PROJECTED_CM) - { - boxProxyMin = Vec3(-renderLight.m_fBoxLength * 0.5f, -renderLight.m_fBoxWidth * 0.5f, -renderLight.m_fBoxHeight * 0.5f); - boxProxyMax = Vec3(renderLight.m_fBoxLength * 0.5f, renderLight.m_fBoxWidth * 0.5f, renderLight.m_fBoxHeight * 0.5f); - } - - lightShadeInfo.shadowMatrix.SetRow4(0, Vec4(boxProxyMin, 0)); - lightShadeInfo.shadowMatrix.SetRow4(1, Vec4(boxProxyMax, 0)); - - int arrayIndex = tdsh.InsertTextureToSpecularProbeAtlas((CTexture*)renderLight.GetSpecularCubemap(), -1); - if (arrayIndex >= 0) - { - if (tdsh.InsertTextureToDiffuseProbeAtlas((CTexture*)renderLight.GetDiffuseCubemap(), arrayIndex) >= 0) - { - lightShadeInfo.resIndex = arrayIndex; - } - else - { - continue; // Skip light - } - } - else - { - continue; // Skip light - } - // Determine the global env probe for lighting analytical volumetric fog if we have it in the scene. - // Enough big(more than 1000 meters), the biggest and the second biggest including camera position are selected. - if (volumeSize >= vfInternal::ThresholdLengthGlobalProbe && - (volumeSize > maxSizeGlobalEnvProbe0 || volumeSize > maxSizeGlobalEnvProbe1)) - { - Vec3 vLightPos = renderLight.GetPosition(); - Vec3 vCenterRel = worldViewPos - vLightPos; - if (vCenterRel.dot(vCenterRel) <= volumeSize * volumeSize) - { - Vec3 vCenterOBBSpace; - vCenterOBBSpace.x = renderLight.m_ObjMatrix.GetColumn0().GetNormalized().dot(vCenterRel); - vCenterOBBSpace.y = renderLight.m_ObjMatrix.GetColumn1().GetNormalized().dot(vCenterRel); - vCenterOBBSpace.z = renderLight.m_ObjMatrix.GetColumn2().GetNormalized().dot(vCenterRel); - - // Check if camera position is within probe OBB - Vec3 vProbeExtents = renderLight.m_ProbeExtents; - if (fabs(vCenterOBBSpace.x) < vProbeExtents.x && fabs(vCenterOBBSpace.y) < vProbeExtents.y && fabs(vCenterOBBSpace.z) < vProbeExtents.z) - { - Vec3 probePos; - probePos.x = vCenterOBBSpace.x / vProbeExtents.x; - probePos.y = vCenterOBBSpace.y / vProbeExtents.y; - probePos.z = vCenterOBBSpace.z / vProbeExtents.z; - Vec3 pos2 = probePos.CompMul(probePos); - Vec3 t; - t.x = sqrt(1.0f - 0.5f * pos2.y - 0.5f * pos2.z + 0.333f * pos2.y * pos2.z); - t.y = sqrt(1.0f - 0.5f * pos2.z - 0.5f * pos2.x + 0.333f * pos2.z * pos2.x); - t.z = sqrt(1.0f - 0.5f * pos2.x - 0.5f * pos2.y + 0.333f * pos2.x * pos2.y); - probePos = probePos.CompMul(t); - float falloff = max(0.0f, min(1.0f, 1.0f + probePos.Dot(-probePos))); - const static float AttenuationFalloffMax = 0.2f; - falloff = min(1.0f, falloff / max(renderLight.GetFalloffMax(), AttenuationFalloffMax)); - - // This globalEnvProbe stuff has not been tested since the introduction of m_fProbeAttenuation - // because the feature is dead at this time; CVolumetricFog::Clear() gets called before m_globalEnvProbeParam0/1 - // and m_globalEnvProveTex0/1 are copied to the GPU. I updated the code to use m_fProbeAttenuation as best I could, - // but can't be certain that the final result will be correct if/when globalEnvProbe functionality is restored. (9/21/2017) - - float attenuation = falloff * falloff * (3.0f - 2.0f * falloff) * renderLight.m_fProbeAttenuation; - - if (renderLight.m_fProbeAttenuation > 0) - { - if (volumeSize > maxSizeGlobalEnvProbe0) - { - maxSizeGlobalEnvProbe1 = maxSizeGlobalEnvProbe0; - texGlobalEnvProbe1 = texGlobalEnvProbe0; - colorGlobalEnvProbe1 = colorGlobalEnvProbe0; - attenuationGlobalEnvProbe1 = attenuationGlobalEnvProbe0; - - maxSizeGlobalEnvProbe0 = volumeSize; - texGlobalEnvProbe0 = (CTexture*)renderLight.GetDiffuseCubemap(); - colorGlobalEnvProbe0 = Vec3(lightShadeInfo.color); - attenuationGlobalEnvProbe0 = attenuation; - } - else if (volumeSize > maxSizeGlobalEnvProbe1) - { - maxSizeGlobalEnvProbe1 = volumeSize; - texGlobalEnvProbe1 = (CTexture*)renderLight.GetDiffuseCubemap(); - colorGlobalEnvProbe1 = Vec3(lightShadeInfo.color); - attenuationGlobalEnvProbe1 = attenuation; - } - } - } - } - } - } - // Regular and ambient lights - else - { - const float sqrt_2 = 1.414214f; // Scale for cone so that it's base encloses a pyramid base - - const bool ambientLight = (lightListIdx == 1); - - lightCullInfo.volumeType = vfInternal::tlVolumeSphere; - lightShadeInfo.lightType = ambientLight ? vfInternal::tlTypeAmbientPoint : vfInternal::tlTypeRegularPoint; - lightCullInfo.miscFlag = 0; - - if (!ambientLight) - { - lightShadeInfo.attenuationParams.x = max(lightShadeInfo.attenuationParams.x, minBulbSize); - - // Adjust light intensity so that the intended brightness is reached 1 meter from the light's surface - // Solve I * 1 / (1 + d/lightsize)^2 = 1 - float intensityMul = 1.0f + 1.0f / lightShadeInfo.attenuationParams.x; - intensityMul *= intensityMul; - lightShadeInfo.color.x *= intensityMul; - lightShadeInfo.color.y *= intensityMul; - lightShadeInfo.color.z *= intensityMul; - } - - // Handle projectors - if (renderLight.m_Flags & DLF_PROJECT) - { - lightCullInfo.volumeType = vfInternal::tlVolumeCone; - lightShadeInfo.lightType = ambientLight ? vfInternal::tlTypeAmbientProjector : vfInternal::tlTypeRegularProjector; - lightShadeInfo.resIndex = 0xFFFFFFFF; - lightCullInfo.miscFlag = 0; - - int arrayIndex = tdsh.InsertTextureToSpotTexAtlas((CTexture*)renderLight.m_pLightImage, -1); - if (arrayIndex >= 0) - { - lightShadeInfo.resIndex = (uint32)arrayIndex; - } - else - { - continue; // Skip light - } - // Prevent culling errors for frustums with large FOVs by slightly enlarging the frustum - const float frustumAngleDelta = renderLight.m_fLightFrustumAngle > 50 ? 7.5f : 0.0f; - - Matrix34 objMat = renderLight.m_ObjMatrix; - objMat.m03 = objMat.m13 = objMat.m23 = 0; // Remove translation - Vec3 lightDir = objMat * Vec3(-1, 0, 0); - lightCullInfo.volumeParams0 = Vec4(lightDir.x, lightDir.y, lightDir.z, 0) * matView; - lightCullInfo.volumeParams0.w = renderLight.m_fRadius * tanf(DEG2RAD(min(renderLight.m_fLightFrustumAngle + frustumAngleDelta, 89.9f))) * sqrt_2; - - Vec3 coneTip = Vec3(lightCullInfo.posRad.x, lightCullInfo.posRad.y, lightCullInfo.posRad.z); - Vec3 coneDir = Vec3(-lightCullInfo.volumeParams0.x, -lightCullInfo.volumeParams0.y, -lightCullInfo.volumeParams0.z); - AABB coneBounds = AABB::CreateAABBfromCone(Cone(coneTip, coneDir, renderLight.m_fRadius, lightCullInfo.volumeParams0.w)); - lightCullInfo.depthBounds = Vec2(coneBounds.min.z, coneBounds.max.z); - - Matrix44A projMatT; - CShadowUtils::GetProjectiveTexGen(&renderLight, 0, &projMatT); - - // Translate into camera space - projMatT.Transpose(); - const Vec4 vEye(rd->GetViewParameters().vOrigin, 0.0f); - Vec4 vecTranslation(vEye.Dot((Vec4&)projMatT.m00), vEye.Dot((Vec4&)projMatT.m10), vEye.Dot((Vec4&)projMatT.m20), vEye.Dot((Vec4&)projMatT.m30)); - projMatT.m03 += vecTranslation.x; - projMatT.m13 += vecTranslation.y; - projMatT.m23 += vecTranslation.z; - projMatT.m33 += vecTranslation.w; - - lightShadeInfo.projectorMatrix = projMatT; - } - - // Handle rectangular area lights - if (areaLightRect) - { - lightCullInfo.volumeType = vfInternal::tlVolumeOBB; - lightShadeInfo.lightType = ambientLight ? vfInternal::tlTypeAmbientArea : vfInternal::tlTypeRegularArea; - lightCullInfo.miscFlag = 0; - - float expensionRadius = renderLight.m_fRadius * 1.08f; - Vec3 scale(expensionRadius, expensionRadius, expensionRadius); - Matrix34 areaLightMat = CShadowUtils::GetAreaLightMatrix(&renderLight, scale); - - Vec4 u0 = Vec4(areaLightMat.GetColumn0().GetNormalized(), 0) * matView; - Vec4 u1 = Vec4(areaLightMat.GetColumn1().GetNormalized(), 0) * matView; - Vec4 u2 = Vec4(areaLightMat.GetColumn2().GetNormalized(), 0) * matView; - lightCullInfo.volumeParams0 = Vec4(u0.x, u0.y, u0.z, areaLightMat.GetColumn0().GetLength() * 0.5f); - lightCullInfo.volumeParams1 = Vec4(u1.x, u1.y, u1.z, areaLightMat.GetColumn1().GetLength() * 0.5f); - lightCullInfo.volumeParams2 = Vec4(u2.x, u2.y, u2.z, areaLightMat.GetColumn2().GetLength() * 0.5f); - - float volumeExtent = renderLight.m_fRadius + max(renderLight.m_fAreaWidth, renderLight.m_fAreaHeight); - lightCullInfo.depthBounds = Vec2(posVS.z - volumeExtent, posVS.z + volumeExtent); - - float areaFov = renderLight.m_fLightFrustumAngle * 2.0f; - if (renderLight.m_Flags & DLF_CASTSHADOW_MAPS) - { - areaFov = min(areaFov, 135.0f); // Shadow can only cover ~135 degree FOV without looking bad, so we clamp the FOV to hide shadow clipping - } - const float cosAngle = cosf(areaFov * (gf_PI / 360.0f)); - - Matrix44 areaLightParams; - areaLightParams.SetRow4(0, Vec4(renderLight.m_ObjMatrix.GetColumn0().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(1, Vec4(renderLight.m_ObjMatrix.GetColumn1().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(2, Vec4(renderLight.m_ObjMatrix.GetColumn2().GetNormalized(), 1.0f)); - areaLightParams.SetRow4(3, Vec4(renderLight.m_fAreaWidth * 0.5f, renderLight.m_fAreaHeight * 0.5f, 0, cosAngle)); - - lightShadeInfo.projectorMatrix = areaLightParams; - } - - // Handle shadow casters - if (!ambientLight && lightIdx >= firstShadowLight && lightIdx < curShadowPoolLight) - { - int numDLights = rd->m_RP.m_DLights[nThreadID][nRecurseLevel].size(); - int frustumIdx = lightIdx + numDLights; - int startIdx = SRendItem::m_StartFrust[nThreadID][frustumIdx]; - int endIdx = SRendItem::m_EndFrust[nThreadID][frustumIdx]; - - if (endIdx > startIdx && nRecurseLevel < (int)rd->m_RP.m_SMFrustums[nThreadID]->size()) - { - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[nThreadID][nRecurseLevel][startIdx]; - assert (firstFrustum.bUseShadowsPool); - - int numSides = firstFrustum.bOmniDirectionalShadow ? 6 : 1; - float kernelSize = firstFrustum.bOmniDirectionalShadow ? 2.5f : 1.5f; - - if (numTileLights + numSides > vfInternal::MaxNumTileLights) - { - continue; // Skip light - } - static ICVar* pShadowAtlasResCVar = iConsole->GetCVar("e_ShadowsPoolSize"); - const Vec2 shadowParams = Vec2(kernelSize * ((float)firstFrustum.nTexSize / (float)pShadowAtlasResCVar->GetIVal()), firstFrustum.fDepthConstBias); - - const Vec3 cubeDirs[6] = { Vec3(-1, 0, 0), Vec3(1, 0, 0), Vec3(0, -1, 0), Vec3(0, 1, 0), Vec3(0, 0, -1), Vec3(0, 0, 1) }; - - for (int side = 0; side < numSides; ++side) - { - rd->ConfigShadowTexgen(0, &firstFrustum, side); - Matrix44A shadowMat = rd->m_TempMatrices[0][0]; - - // Translate into camera space - const Vec4 vEye(rd->GetViewParameters().vOrigin, 0.0f); - Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30)); - shadowMat.m03 += vecTranslation.x; - shadowMat.m13 += vecTranslation.y; - shadowMat.m23 += vecTranslation.z; - shadowMat.m33 += vecTranslation.w; - - // Pre-multiply by inverse frustum far plane distance - (Vec4&)shadowMat.m20 *= rd->m_cEF.m_TempVecs[2].x; - - Vec3 cubeDir = cubeDirs[side]; - Vec4 spotParamsVS = Vec4(cubeDir.x, cubeDir.y, cubeDir.z, 0) * matView; - - // slightly enlarge the frustum to prevent culling errors - spotParamsVS.w = renderLight.m_fRadius * tanf(DEG2RAD(45.0f + 14.5f)) * sqrt_2; - - Vec3 coneTip = Vec3(lightCullInfo.posRad.x, lightCullInfo.posRad.y, lightCullInfo.posRad.z); - Vec3 coneDir = Vec3(-spotParamsVS.x, -spotParamsVS.y, -spotParamsVS.z); - AABB coneBounds = AABB::CreateAABBfromCone(Cone(coneTip, coneDir, renderLight.m_fRadius, spotParamsVS.w)); - Vec2 depthBoundsVS = Vec2(coneBounds.min.z, coneBounds.max.z); - Vec2 sideShadowParams = (firstFrustum.nShadowGenMask & (1 << side)) ? shadowParams : Vec2(ZERO); - - if (side == 0) - { - lightShadeInfo.shadowParams = sideShadowParams; - lightShadeInfo.shadowMatrix = shadowMat; - lightShadeInfo.shadowChannelIndex = Vec4( - renderLight.m_ShadowChanMask % 4 == 0, - renderLight.m_ShadowChanMask % 4 == 1, - renderLight.m_ShadowChanMask % 4 == 2, - renderLight.m_ShadowChanMask % 4 == 3 - ); - lightShadeInfo.shadowMaskIndex = renderLight.m_ShadowMaskIndex; - - if (numSides > 1) - { - lightCullInfo.volumeType = vfInternal::tlVolumeCone; - lightShadeInfo.lightType = vfInternal::tlTypeRegularPointFace; - lightShadeInfo.resIndex = side; - lightCullInfo.volumeParams0 = spotParamsVS; - lightCullInfo.depthBounds = depthBoundsVS; - lightCullInfo.miscFlag = 0; - } - } - else - { - // Split point light - ++numTileLights; - tileLightsCull[numTileLights] = lightCullInfo; - tileLightsShade[numTileLights] = lightShadeInfo; - tileLightsShade[numTileLights].shadowParams = sideShadowParams; - tileLightsShade[numTileLights].shadowMatrix = shadowMat; - tileLightsShade[numTileLights].resIndex = side; - tileLightsCull[numTileLights].volumeParams0 = spotParamsVS; - tileLightsCull[numTileLights].depthBounds = depthBoundsVS; - } - } - } - } - } - - // Add current light - ++numTileLights; - ++numValidRenderLights; - } - } - - // Invalidate last light in case it got skipped - if (numTileLights < vfInternal::MaxNumTileLights) - { - ZeroMemory(&tileLightsCull[numTileLights], sizeof(vfInternal::SVolumeLightCullInfo)); - ZeroMemory(&tileLightsShade[numTileLights], sizeof(vfInternal::SVolumeLightShadeInfo)); - } - - // Update light buffer - m_lightCullInfoBuf.UpdateBufferContent(tileLightsCull, sizeof(vfInternal::SVolumeLightCullInfo) * vfInternal::MaxNumTileLights); - m_LightShadeInfoBuf.UpdateBufferContent(tileLightsShade, sizeof(vfInternal::SVolumeLightShadeInfo) * vfInternal::MaxNumTileLights); - - m_numTileLights = numTileLights; - - // Update global env probes for analytical volumetric fog - { - I3DEngine* pEng = gEnv->p3DEngine; - Vec3 fogAlbedo(0.0f, 0.0f, 0.0f); - pEng->GetGlobalParameter(E3DPARAM_VOLFOG2_COLOR, fogAlbedo); - colorGlobalEnvProbe0 = colorGlobalEnvProbe0.CompMul(fogAlbedo); - colorGlobalEnvProbe1 = colorGlobalEnvProbe1.CompMul(fogAlbedo); - m_globalEnvProbeParam0 = Vec4(colorGlobalEnvProbe0, attenuationGlobalEnvProbe0); - m_globalEnvProbeParam1 = Vec4(colorGlobalEnvProbe1, attenuationGlobalEnvProbe1); - - SAFE_RELEASE(m_globalEnvProveTex0); - SAFE_RELEASE(m_globalEnvProveTex1); - if (texGlobalEnvProbe0) - { - m_globalEnvProveTex0 = texGlobalEnvProbe0; - m_globalEnvProveTex0->AddRef(); - } - if (texGlobalEnvProbe1) - { - m_globalEnvProveTex1 = texGlobalEnvProbe1; - m_globalEnvProveTex1->AddRef(); - } - } -} - -void CVolumetricFog::RenderVolumetricsToVolume(void (* RenderFunc)()) -{ - if (!IsViable()) - { - return; - } - - AZ_TRACE_METHOD(); - - static const ICVar* pCVarFogVolumeInject = NULL; - if (!pCVarFogVolumeInject) - { - pCVarFogVolumeInject = gEnv->pConsole->GetCVar("e_FogVolumesTiledInjection"); - } - bool bFogVolumeInjection = (pCVarFogVolumeInject && pCVarFogVolumeInject->GetIVal() != 0); - - UpdateFrame(); - - RenderDownscaledShadowmap(); - - BuildLightListGrid(); - - RenderDownscaledDepth(); - - { - PROFILE_LABEL_SCOPE("INJECT_PARTICIPATING_MEDIA"); - - if (bFogVolumeInjection) - { - PrepareFogVolumeList(); - InjectFogDensity(); - } - else - { - InjectExponentialHeightFog(); - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - - // store state - int oldX, oldY; - int oldWidth, oldHeight; - rd->GetViewport(&oldX, &oldY, &oldWidth, &oldHeight); - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - - if (!bFogVolumeInjection) - { - // clear s_ptexVolumetricFogDensityColor. - rd->FX_ClearTarget(CTexture::s_ptexVolumetricFogDensityColor, Clr_Transparent); - } - - rd->FX_PushRenderTarget(0, CTexture::s_ptexVolumetricFogDensityColor, NULL); - rd->FX_PushRenderTarget(1, CTexture::s_ptexVolumetricFogDensity, NULL); - rd->FX_SetActiveRenderTargets(false); - - // Set the viewport. - int targetWidth = CTexture::s_ptexVolumetricFogDensity->GetWidth(); - int targetHeight = CTexture::s_ptexVolumetricFogDensity->GetHeight(); - rd->RT_SetViewport(0, 0, targetWidth, targetHeight); - - // overwrite pipeline state. - const uint32 nOldForceStateAnd = rp.m_ForceStateAnd; - const uint32 nOldForceStateOr = rp.m_ForceStateOr; - rp.m_ForceStateAnd = GS_BLSRC_MASK | GS_BLDST_MASK | GS_DEPTHFUNC_MASK | GS_DEPTHWRITE | GS_NODEPTHTEST; - rp.m_ForceStateOr |= GS_BLSRC_ONE | GS_BLDST_ONE | GS_NODEPTHTEST; - - // inject fog density and fog albedo into volume texture. - rd->FX_ProcessRenderList(EFSLIST_FOG_VOLUME, 0, RenderFunc, false); - rd->FX_ProcessRenderList(EFSLIST_FOG_VOLUME, 1, RenderFunc, false); - - rd->FX_PopRenderTarget(0); - rd->FX_PopRenderTarget(1); - rd->FX_SetActiveRenderTargets(false); - - // restore pipeline state. - rp.m_ForceStateAnd = nOldForceStateAnd; - rp.m_ForceStateOr = nOldForceStateOr; - rd->RT_SetViewport(oldX, oldY, oldWidth, oldHeight); - rp.m_FlagsShader_RT = prevShaderRtFlags; - rd->FX_Commit(); - } -} - -void CVolumetricFog::RenderVolumetricFog() -{ - if (!IsViable()) - { - return; - } - - PROFILE_LABEL_SCOPE("RENDER_VOLUMETRIC_FOG"); - - InjectInscatteringLight(); - - const int VolumetricFogBlurInscattering = 1; - if constexpr (VolumetricFogBlurInscattering > 0) - { - int maxBlurCount = VolumetricFogBlurInscattering; - maxBlurCount = maxBlurCount <= 4 ? maxBlurCount : 4; - for (int count = 0; count < maxBlurCount; ++count) - { -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - BlurInscatterVolume(); -#else - BlurDensityVolume(); - BlurInscatterVolume(); -#endif - } - } - - ReprojectVolume(); - - RaymarchVolumetricFog(); -} - -float CVolumetricFog::GetDepthIndex(float linearDepth) const -{ - const float raymarchStart = gcpRendD3D->GetViewParameters().fNear; - Vec3 volFogCtrlParams(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volFogCtrlParams); - const float raymarchDistance = (volFogCtrlParams.x > raymarchStart) ? (volFogCtrlParams.x - raymarchStart) : 0.0001f; - float d = powf(((linearDepth - raymarchStart) / raymarchDistance), (1.0f / 2.0f)); - float maxIndex = static_cast(CTexture::s_ptexVolumetricFog ? CTexture::s_ptexVolumetricFog->GetDepth() : 1.0f); - d = (0.5f - d) / maxIndex + d; - return d; -} - -bool CVolumetricFog::IsEnableInFrame() const -{ - bool v = CRenderer::CV_r_DeferredShadingTiled > 0 - && CRenderer::CV_r_DeferredShadingTiled < 4 - && CRenderer::CV_r_usezpass != 0 - && CRenderer::CV_r_Unlit == 0 - && CRenderer::CV_r_DeferredShadingDebug != 2 - && CRenderer::CV_r_measureoverdraw == 0; - - return v; -} - -void CVolumetricFog::PushFogVolume(CREFogVolume* pFogVolume, const SRenderingPassInfo& passInfo) -{ - assert(pFogVolume != NULL); - if (pFogVolume == NULL) - { - return; - } - - const uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - const uint32 nRecurseLevel = passInfo.GetRecursiveLevel(); - const uint32 nVolumeType = pFogVolume->m_volumeType; - - TArray& array = m_fogVolumeInfoArray[nThreadID][nRecurseLevel][nVolumeType]; - - if (array.size() >= vfInternal::MaxNumFogVolumes) - { - // TODO: show skipped FogVolume number on the screen. - return; - } - - SFogVolumeInfo temp; - temp.m_center = pFogVolume->m_center; - temp.m_viewerInsideVolume = pFogVolume->m_viewerInsideVolume; - temp.m_affectsThisAreaOnly = pFogVolume->m_affectsThisAreaOnly; - temp.m_stencilRef = pFogVolume->m_stencilRef; - temp.m_volumeType = pFogVolume->m_volumeType; - temp.m_localAABB = pFogVolume->m_localAABB; - temp.m_matWSInv = pFogVolume->m_matWSInv; - temp.m_fogColor = pFogVolume->m_fogColor; - temp.m_globalDensity = pFogVolume->m_globalDensity; - temp.m_densityOffset = pFogVolume->m_densityOffset; - temp.m_softEdgesLerp = pFogVolume->m_softEdgesLerp; - temp.m_heightFallOffDirScaled = pFogVolume->m_heightFallOffDirScaled; - temp.m_heightFallOffBasePoint = pFogVolume->m_heightFallOffBasePoint; - temp.m_eyePosInOS = pFogVolume->m_eyePosInOS; - temp.m_rampParams = pFogVolume->m_rampParams; - temp.m_windOffset = pFogVolume->m_windOffset; - temp.m_noiseScale = pFogVolume->m_noiseScale; - temp.m_noiseFreq = pFogVolume->m_noiseFreq; - temp.m_noiseOffset = pFogVolume->m_noiseOffset; - temp.m_noiseElapsedTime = pFogVolume->m_noiseElapsedTime; - temp.m_scale = pFogVolume->m_scale; - - array.Add(temp); -} - -void CVolumetricFog::ClearFogVolumes() -{ - const uint32 nThreadID = gcpRendD3D->m_RP.m_nFillThreadID; - int32 nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - if (0 <= nRecurseLevel && nRecurseLevel < MAX_REND_RECURSION_LEVELS) - { - for (uint32 i = 0; i < MaxNumFogVolumeType; ++i) - { - m_fogVolumeInfoArray[nThreadID][nRecurseLevel][i].SetUse(0); - } - } -} - -void CVolumetricFog::ClearAllFogVolumes() -{ - for (int32 i = 0; i < RT_COMMAND_BUF_COUNT; ++i) - { - for (int32 j = 0; j < MAX_REND_RECURSION_LEVELS; ++j) - { - for (uint32 k = 0; k < MaxNumFogVolumeType; ++k) - { - m_fogVolumeInfoArray[i][j][k].Free(); - } - } - } -} - -void CVolumetricFog::UpdateFrame() -{ - int frameID = gcpRendD3D->GetFrameID(false); - if (m_frameID != frameID) - { - CD3D9Renderer* const __restrict rd = gcpRendD3D; - Matrix44 mViewProj = rd->m_ViewMatrix * rd->m_ProjMatrix; - Matrix44& mViewport = SD3DPostEffectsUtils::GetInstance().m_pScaleBias; - - ++m_tick; - m_frameID = frameID; - m_viewProj[m_tick % MaxFrameNum] = mViewProj * mViewport; - } -} - -bool CVolumetricFog::IsViable() const -{ - int nThreadID = gcpRendD3D->m_RP.m_nProcessThreadID; - int nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - bool v = CD3D9Renderer::CV_r_VolumetricFog != 0 // IsEnableInFrame() and e_VolumetricFog are accumulated. - && gcpRendD3D->m_RP.m_TI[nThreadID].m_FS.m_bEnable - && nRecurseLevel == 0; - - return v; -} - -void CVolumetricFog::InjectInscatteringLight() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - SRenderPipeline& rp(rd->m_RP); - const int nThreadID = rp.m_nProcessThreadID; - - // store state - const int32 prevState = rp.m_CurState; - const uint32 prevStateAnd = rp.m_StateAnd; - const uint32 prevStateOr = rp.m_StateOr; - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - const int prevPersFlags = rp.m_TI[nThreadID].m_PersFlags; - - - const uint32 nScreenWidth = m_InscatteringVolume->GetWidth(); - const uint32 nScreenHeight = m_InscatteringVolume->GetHeight(); - const uint32 volumeDepth = m_InscatteringVolume->GetDepth(); - - // calculate fog density and accumulate in-scattering lighting along view ray. - //PROFILE_LABEL_SCOPE( "INJECT_VOLUMETRIC_FOG_INSCATTERING" ); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 8, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 16, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - // We are bypassing various texture shadow state caches by directly hitting the device manager for clearing texture slots here. - // CTexture::Apply can cache textures into CTexture::s_TexStages, which are not invalidated by the device manager and can lead CTexture to falsely believe - // a texture is still bound to the device when it has been cleared. - rd->RT_UnbindTMUs(); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - - rd->FX_SetupShadowsForFog(); - - const int nStaticShadowMapSlot = 3; - SetupStaticShadowMap(nStaticShadowMapSlot); - - rd->GetTiledShading().BindForwardShadingResources(NULL, eHWSC_Compute); - - //// set debug flag - //if(CRenderer::CV_r_VolumetricFogDebug == 1) - //{ - // rp.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG0]; - //} - //else if(CRenderer::CV_r_VolumetricFogDebug == 2) - //{ - // rp.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG1]; - //} - //else if(CRenderer::CV_r_VolumetricFogDebug == 3) - //{ - // rp.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG2]; - //} - //else if(CRenderer::CV_r_VolumetricFogDebug == 4) - //{ - // rp.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_DEBUG3]; - //} - - // set sampling quality - const uint64 quality = g_HWSR_MaskBit[HWSR_SAMPLE4]; - const uint64 quality1 = g_HWSR_MaskBit[HWSR_SAMPLE5]; - rp.m_FlagsShader_RT &= ~(quality | quality1); - switch (CRenderer::CV_r_VolumetricFogSample) - { - case 1: - rp.m_FlagsShader_RT |= quality; - break; - case 2: - rp.m_FlagsShader_RT |= quality1; - break; - default: - break; - } - - // set shadow quality - const uint64 shadowQuality = g_HWSR_MaskBit[HWSR_LIGHTVOLUME0]; - const uint64 shadowQuality1 = g_HWSR_MaskBit[HWSR_LIGHTVOLUME1]; - rp.m_FlagsShader_RT &= ~(shadowQuality | shadowQuality1); - switch (CRenderer::CV_r_VolumetricFogShadow) - { - case 1: - rp.m_FlagsShader_RT |= shadowQuality; - break; - case 2: - rp.m_FlagsShader_RT |= shadowQuality1; - break; - case 3: - rp.m_FlagsShader_RT |= shadowQuality | shadowQuality1; - break; - default: - break; - } - - // set downscaled sun shadow maps - const uint64 shadowMode0 = g_HWSR_MaskBit[HWSR_SAMPLE0]; - const uint64 shadowMode1 = g_HWSR_MaskBit[HWSR_SAMPLE1]; - rp.m_FlagsShader_RT &= ~(shadowMode0 | shadowMode1); - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 1) - { - // replace first and second cascades - rp.m_FlagsShader_RT |= (CRenderer::CV_r_ShadowsCache > 0) ? shadowMode0 | shadowMode1 : shadowMode0; - } - else if (CRenderer::CV_r_VolumetricFogDownscaledSunShadow != 0) - { - // replace first, second, and third cascades - rp.m_FlagsShader_RT |= shadowMode1; - } - - static CCryNameTSCRC shaderName("InjectVolumetricInscattering"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - m_InscatteringVolume->GetDeviceUAV(), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadow != 0) - { - D3DShaderResourceView* pDSMs[3] = { - m_downscaledShadow[0]->GetShaderResourceView(), - m_downscaledShadow[1]->GetShaderResourceView(), - m_downscaledShadow[2] ? m_downscaledShadow[2]->GetShaderResourceView() : NULL, - }; - int count = (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 1) ? 2 : 3; - rd->m_DevMan.BindSRV(eHWSC_Compute, pDSMs, 5, count); - } - -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - D3DShaderResourceView* pSRVs[7] = { - m_lightGridBuf.GetShaderResourceView(), - m_lightCountBuf.GetShaderResourceView(), - m_MaxDepth->GetShaderResourceView(), - CTexture::s_ptexVolumetricClipVolumeStencil->GetShaderResourceView(), - m_LightShadeInfoBuf.GetShaderResourceView(), - CTexture::s_ptexVolumetricFogDensityColor->GetShaderResourceView(), - CTexture::s_ptexVolumetricFogDensity->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 8, 7); -#else - D3DShaderResourceView* pSRVs[6] = { - m_lightGridBuf.GetShaderResourceView(), - m_lightCountBuf.GetShaderResourceView(), - m_MaxDepth->GetShaderResourceView(), - CTexture::s_ptexVolumetricClipVolumeStencil->GetShaderResourceView(), - m_LightShadeInfoBuf.GetShaderResourceView(), - CTexture::s_ptexVolumetricFogDensityColor->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 8, 6); -#endif - - //D3DSamplerState *pSamplers[2] = { - // (D3DSamplerState *)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - // (D3DSamplerState *)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - //}; - //rd->m_DevMan.BindSampler( eHWSC_Compute, pSamplers, 0, 2 ); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - float octave = (CRenderer::CV_r_VolumetricFogReprojectionBlendFactor > 0.0f) ? -1.7f : 0.0f; - Vec3 sunDir = gEnv->p3DEngine->GetSunDirNormalized(); - static CCryNameR paramSunDir("SunDir"); - Vec4 vParamSunDir(sunDir.x, sunDir.y, sunDir.z, octave); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSunDir, &vParamSunDir, 1); - - Vec3 sunColor; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_SUN_COLOR, sunColor); - static CCryNameR paramSunColor("SunColor"); - Vec4 vParamSunColor(sunColor.x, sunColor.y, sunColor.z, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramSunColor, &vParamSunColor, 1); - - Vec3 fogAlbedoColor; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_COLOR, fogAlbedoColor); - static CCryNameR paramFogColor("ExponentialHeightFogColor"); - Vec4 vParamFogColor(fogAlbedoColor.x, fogAlbedoColor.y, fogAlbedoColor.z, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFogColor, &vParamFogColor, 1); - - Vec3 scatteringParam; - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_SCATTERING_PARAMS, scatteringParam); - static CCryNameR paramInjectInscattering("InjectInscatteringParams"); - float k = scatteringParam.z; - bool bNegative = k < 0.0f ? true : false; - k = (abs(k) > 0.99999f) ? (bNegative ? -0.99999f : 0.99999f) : k; - Vec4 vParamInjectInscattering(k, 1.0f - k * k, 0.0f, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramInjectInscattering, &vParamInjectInscattering, 1); - - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - static CCryNameR paramDispatchSize("DispatchSize"); - Vec4 vParamDispatchSize((float)dispatchSizeX, (float)dispatchSizeY, (float)dispatchSizeZ, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramDispatchSize, &vParamDispatchSize, 1); - - rd->FX_Commit(); - - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - - rd->GetTiledShading().UnbindForwardShadingResources(eHWSC_Compute); - - - //D3DUAV* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - D3DShaderResourceView* pSRVNull[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 0, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 8, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 16, 8); - - // We are bypassing various texture shadow state caches by directly hitting the device manager for clearing texture slots here. - // CTexture::Apply can cache textures into CTexture::s_TexStages, which are not invalidated by the device manager and can lead CTexture to falsely believe - // a texture is still bound to the device when it has been cleared. - rd->RT_UnbindTMUs(); - - // restore state - rp.m_StateAnd = prevStateAnd; - rp.m_StateOr = prevStateOr; - rd->SetState(prevState); - rp.m_TI[nThreadID].m_PersFlags = prevPersFlags; - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::BuildLightListGrid() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - SRenderPipeline& rp(rd->m_RP); - const int nThreadID = rp.m_nProcessThreadID; - - // store state - const int32 prevState = rp.m_CurState; - const uint32 prevStateAnd = rp.m_StateAnd; - const uint32 prevStateOr = rp.m_StateOr; - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - const int prevPersFlags = rp.m_TI[nThreadID].m_PersFlags; - - - const uint32 nScreenWidth = m_InscatteringVolume->GetWidth(); - const uint32 nScreenHeight = m_InscatteringVolume->GetHeight(); - const uint32 volumeDepth = m_InscatteringVolume->GetDepth(); - - // calculate fog density and accumulate in-scattering lighting along view ray. - //PROFILE_LABEL_SCOPE( "BUILD_VOLUMETRIC_FOG_CLUSTERED_LIGHT_GRID" ); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 16, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - - - static CCryNameTSCRC shaderName("BuildLightListGrid"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[2] = { - m_lightGridBuf.GetUnorderedAccessView(), - m_lightCountBuf.GetUnorderedAccessView(), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 2); - - D3DShaderResourceView* pSRV[1] = { - m_lightCullInfoBuf.GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRV, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - static CCryNameR paramProj("ProjParams"); - Vec4 vParamProj(rd->m_ProjMatrix.m00, rd->m_ProjMatrix.m11, rd->m_ProjMatrix.m20, rd->m_ProjMatrix.m21); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramProj, &vParamProj, 1); - - uint32 numTileLights = m_numTileLights; - - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - static CCryNameR paramDispatchSize("DispatchSize"); - Vec4 vParamDispatchSize((float)dispatchSizeX, (float)dispatchSizeY, (float)dispatchSizeZ, (float)numTileLights); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramDispatchSize, &vParamDispatchSize, 1); - - rd->FX_Commit(); - - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - - - //D3DUAV* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - D3DShaderResourceView* pSRVNull[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 0, 1); - - //D3DSamplerState* pSampNull[2] = { NULL }; - //rd->m_DevMan.BindSampler( eHWSC_Compute, pSampNull, 0, 2 ); - - // restore state - rp.m_StateAnd = prevStateAnd; - rp.m_StateOr = prevStateOr; - rd->SetState(prevState); - rp.m_TI[nThreadID].m_PersFlags = prevPersFlags; - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); -} - -void CVolumetricFog::RaymarchVolumetricFog() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - // Unbind the VolumetricFog SRV (used in the recursive pass). It gets - // implicitly unbound when used as a UAV. Without explicitly calling - // Unbind(), it may not get re-bound as an SRV for future shaders. - CTexture::s_ptexVolumetricFog->Unbind(); - - // store state - SRenderPipeline& rp(rd->m_RP); - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - - const uint32 nScreenWidth = CTexture::s_ptexVolumetricFogDensity->GetWidth(); - const uint32 nScreenHeight = CTexture::s_ptexVolumetricFogDensity->GetHeight(); - const uint32 volumeDepth = CTexture::s_ptexVolumetricFogDensity->GetDepth(); - - //PROFILE_LABEL_SCOPE( "RAYMARCH_VOLUMETRIC_FOG" ); - - // accumulate in-scattering lighting along view ray. - static CCryNameTSCRC shaderName("RaymarchVolumetricFog"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - CTexture::s_ptexVolumetricFog->GetDeviceUAV(), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - D3DShaderResourceView* pSRVs[1] = { - (GetInscatterTex()->GetShaderResourceView()), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 1); -#else - D3DShaderResourceView* pSRVs[2] = { - (GetInscatterTex()->GetShaderResourceView()), - (GetDensityTex()->GetShaderResourceView()), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 2); -#endif - - //D3DSamplerState *pSamplers[2] = { - // (D3DSamplerState *)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - // (D3DSamplerState *)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - //}; - //rd->m_DevMan.BindSampler( eHWSC_Compute, pSamplers, 0, 2 ); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - - SD3DPostEffectsUtils::ShEndPass(); - - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - D3DShaderResourceView* pSRVNull[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 0, 2); - - D3DSamplerState* pSampNull[2] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 2); - - // restore state - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::BlurInscatterVolume() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - const uint32 nScreenWidth = m_InscatteringVolume->GetWidth(); - const uint32 nScreenHeight = m_InscatteringVolume->GetHeight(); - const uint32 volumeDepth = m_InscatteringVolume->GetDepth(); - - // blur inscattering volume texture for removing jittering noise. - //PROFILE_LABEL_SCOPE( "VOLUMETRIC_FOG_BLUR" ); - - { - static CCryNameTSCRC shaderNameHorizontal("BlurHorizontalInscatteringVolume"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderNameHorizontal, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(GetInscatterTex()->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[2] = { - m_InscatteringVolume->GetShaderResourceView(), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 2); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - const uint32 tileSizeZ = 1; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - } - - { - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - } - - { - static CCryNameTSCRC shaderNameVertical("BlurVerticalInscatteringVolume"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderNameVertical, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(m_InscatteringVolume->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[2] = { - (GetInscatterTex()->GetShaderResourceView()), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 2); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - const uint32 tileSizeZ = 1; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - } - - D3DUnorderedAccessView* pUAVNull4[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull4, NULL, 0, 4); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DSamplerState* pSampNull[2] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 2); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::BlurDensityVolume() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - const uint32 nScreenWidth = CTexture::s_ptexVolumetricFogDensity->GetWidth(); - const uint32 nScreenHeight = CTexture::s_ptexVolumetricFogDensity->GetHeight(); - const uint32 volumeDepth = CTexture::s_ptexVolumetricFogDensity->GetDepth(); - - // blur density volume texture for removing jitter noise. - //PROFILE_LABEL_SCOPE( "VOLUMETRIC_FOG_BLUR_DENSITY" ); - - { - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - } - - { - static CCryNameTSCRC shaderNameHorizontal("BlurHorizontalDensityVolume"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderNameHorizontal, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(GetDensityTex()->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[2] = { - CTexture::s_ptexVolumetricFogDensity->GetShaderResourceView(), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 2); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - const uint32 tileSizeZ = 1; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - } - - { - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - } - - { - static CCryNameTSCRC shaderNameVertical("BlurVerticalDensityVolume"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderNameVertical, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(CTexture::s_ptexVolumetricFogDensity->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[2] = { - (GetDensityTex()->GetShaderResourceView()), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 2); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, 0.0f, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - const uint32 tileSizeZ = 1; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - } - - D3DUnorderedAccessView* pUAVNull4[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull4, NULL, 0, 4); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DSamplerState* pSampNull[2] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 2); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::ReprojectVolume() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - // store state - SRenderPipeline& rp(rd->m_RP); - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - - const uint32 nScreenWidth = m_InscatteringVolume->GetWidth(); - const uint32 nScreenHeight = m_InscatteringVolume->GetHeight(); - const uint32 volumeDepth = m_InscatteringVolume->GetDepth(); - - //PROFILE_LABEL_SCOPE( "REPROJECT_VOLUMETRIC_FOG" ); - - - // no reprojection in cleared frames - if (m_Cleared > 0) - { -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - rd->GetDeviceContext().CopyResource(GetPrevInscatterTex()->GetDevTexture()->GetVolumeTexture(), - m_InscatteringVolume->GetDevTexture()->GetVolumeTexture()); -#else - rd->GetDeviceContext().CopyResource(GetPrevInscatterTex()->GetDevTexture()->GetVolumeTexture(), - m_InscatteringVolume->GetDevTexture()->GetVolumeTexture()); - rd->GetDeviceContext().CopyResource(GetPrevDensityTex()->GetDevTexture()->GetVolumeTexture(), - CTexture::s_ptexVolumetricFogDensity->GetDevTexture()->GetVolumeTexture()); -#endif - } - - - { - // set reprojection mode - if (CRenderer::CV_r_VolumetricFogReprojectionMode != 0) - { - rp.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - // accumulate in-scattering lighting along view ray. - static CCryNameTSCRC shaderName("ReprojectVolumetricFog"); - bool valid = SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - -#ifdef ENABLE_VOLFOG_TEX_FORMAT_RGBA16F - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(GetInscatterTex()->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[3] = { - m_InscatteringVolume->GetShaderResourceView(), - (GetPrevInscatterTex()->GetShaderResourceView()), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 3); -#else - D3DUnorderedAccessView* pUAVs[2] = { - static_cast(GetInscatterTex()->GetDeviceUAV()), - static_cast(GetDensityTex()->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 2); - - D3DShaderResourceView* pSRVs[5] = { - m_InscatteringVolume->GetShaderResourceView(), - (GetPrevInscatterTex()->GetShaderResourceView()), - CTexture::s_ptexVolumetricFogDensity->GetShaderResourceView(), - (GetPrevDensityTex()->GetShaderResourceView()), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 5); -#endif - - D3DSamplerState* pSamplers[2] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 2); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - float reprojectionFactor = max(0.0f, min(1.0f, CRenderer::CV_r_VolumetricFogReprojectionBlendFactor)); - - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float yfov, xfov, aspect, ndist, fdist; - rc.GetPerspectiveParams(&yfov, &xfov, &aspect, &ndist, &fdist); - static CCryNameR paramNameScreenInfo("ScreenInfo"); - Vec4 screenInfo(ndist, fdist, reprojectionFactor, (float)volumeDepth); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramNameScreenInfo, &screenInfo, 1); - - static CCryNameR param1("PrevViewProjMatrix"); - Vec4* temp = (Vec4*)m_viewProj[max(m_tick - (int32)rd->GetActiveGPUCount(), 0) % MaxFrameNum].GetData(); - CShaderMan::s_shDeferredShading->FXSetCSFloat(param1, temp, 4); - - rd->FX_Commit(); - - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - - if (valid) - { - m_Cleared = (m_Cleared > 0) ? (m_Cleared - 1) : 0; - } - } - - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - D3DShaderResourceView* pSRVNull[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVNull, 0, 5); - - D3DSamplerState* pSampNull[2] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 2); - - // restore state - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -CTexture* CVolumetricFog::GetInscatterTex() const -{ - return ((m_tick / gcpRendD3D->GetActiveGPUCount()) & 0x1) ? m_fogInscatteringVolume[0] : m_fogInscatteringVolume[1]; -} - -CTexture* CVolumetricFog::GetPrevInscatterTex() const -{ - return ((m_tick / gcpRendD3D->GetActiveGPUCount()) & 0x1) ? m_fogInscatteringVolume[1] : m_fogInscatteringVolume[0]; -} - -CTexture* CVolumetricFog::GetDensityTex() const -{ - return ((m_tick / gcpRendD3D->GetActiveGPUCount()) & 0x1) ? m_fogDensityVolume[0] : m_fogDensityVolume[1]; -} - -CTexture* CVolumetricFog::GetPrevDensityTex() const -{ - return ((m_tick / gcpRendD3D->GetActiveGPUCount()) & 0x1) ? m_fogDensityVolume[1] : m_fogDensityVolume[0]; -} - -void CVolumetricFog::RenderDownscaledDepth() -{ - //PROFILE_LABEL_SCOPE( "VOLUMETRIC_FOG_DOWNSCALED_DEPTH" ); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - { - static CCryNameTSCRC shaderName("StoreDownscaledMaxDepthHorizontal"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(m_MaxDepthTemp->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[1] = { - CTexture::s_ptexZTargetScaled->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 1); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - int nScreenWidth = m_MaxDepthTemp->GetWidth(); - int nScreenHeight = m_MaxDepthTemp->GetHeight(); - int nSrcTexWidth = CTexture::s_ptexZTargetScaled->GetWidth(); - - static CCryNameR paramDispatchParams("maxDepthDispatchParams"); - float destW = (float)nScreenWidth; - float srcW = (float)nSrcTexWidth; - Vec4 vParamDispatchParams((srcW / destW), (destW / srcW), 0.0f, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramDispatchParams, &vParamDispatchParams, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - - SD3DPostEffectsUtils::ShEndPass(); - } - - { - D3DShaderResourceView* pNullViews[1] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 1); - - D3DUnorderedAccessView* pUAVNull[1] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 1); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - } - - { - static CCryNameTSCRC shaderName("StoreDownscaledMaxDepthVertical"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(m_MaxDepth->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DShaderResourceView* pSRVs[1] = { - m_MaxDepthTemp->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 0, 1); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - int nScreenWidth = m_MaxDepth->GetWidth(); - int nScreenHeight = m_MaxDepth->GetHeight(); - int nSrcTexWidth = m_MaxDepthTemp->GetWidth(); - - static CCryNameR paramDispatchParams("maxDepthDispatchParams"); - float destW = (float)nScreenWidth; - float srcW = (float)nSrcTexWidth; - Vec4 vParamDispatchParams((srcW / destW), (destW / srcW), 0.0f, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramDispatchParams, &vParamDispatchParams, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 8; - const uint32 tileSizeY = 8; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, 1); - - SD3DPostEffectsUtils::ShEndPass(); - } - - { - D3DUnorderedAccessView* pUAVNull[1] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 1); - - D3DShaderResourceView* pNullViews[1] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 1); - - D3DSamplerState* pSampNull[1] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 1); - } -} - -void CVolumetricFog::ClearVolumeStencil() -{ - if (!IsViable()) - { - return; - } - - PROFILE_LABEL_SCOPE("VOLUMETRIC_FOG_CLEAR_VOLUME_STENCIL"); - gcpRendD3D->FX_ClearTarget((D3DDepthSurface*)CTexture::s_ptexVolumetricClipVolumeStencil->GetDeviceDepthStencilSurf(), CLEAR_STENCIL, Clr_Unused.r, 0); -} - -void CVolumetricFog::RenderClipVolumeToVolumeStencil(int nClipAreaReservedStencilBit) -{ - if (!IsViable()) - { - return; - } - - PROFILE_LABEL_SCOPE("VOLUMETRIC_FOG_CLIPVOLUMES TO STENCIL"); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - const bool bReverseDepth = (rp.m_TI[rp.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) != 0; - - int oldX, oldY; - int oldWidth, oldHeight; - rd->GetViewport(&oldX, &oldY, &oldWidth, &oldHeight); - - // FOB_POINT_SPRITE prevents CD3D9Renderer::FX_SetVertexDeclaration function working correctly. - uint64 objFlags = rp.m_ObjFlags; - rp.m_ObjFlags &= ~FOB_POINT_SPRITE; - - int targetWidth = CTexture::s_ptexVolumetricClipVolumeStencil->GetWidth(); - int targetHeight = CTexture::s_ptexVolumetricClipVolumeStencil->GetHeight(); - rd->RT_SetViewport(0, 0, targetWidth, targetHeight); - - SDepthTexture D3dDepthSurface; - D3dDepthSurface.nWidth = targetWidth; - D3dDepthSurface.nHeight = targetHeight; - D3dDepthSurface.pSurf = nullptr; - D3dDepthSurface.pTex = nullptr; - D3dDepthSurface.pTarget = CTexture::s_ptexVolumetricClipVolumeStencil->GetDevTexture()->Get2DTexture(); - - int maxDepthCount = m_InscatteringVolume->GetDepth(); - float a = 0.0f; - float b = 0.0f; - bool valid = true; - float d = (rp.m_TI[rp.m_nProcessThreadID].m_PersFlags & RBPF_REVERSE_DEPTH) ? 1.0f : 0.0f; - float raymarchDistance = gRenDev->m_cEF.m_PF.m_VolumetricFogDistanceParams.w; - - if (m_Destroyed > 0) - { - float fFar = rd->GetViewParameters().fFar; - float fNear = rd->GetViewParameters().fNear; - a = fFar / (fFar - fNear); - b = fNear * -a; - - // store values to observe the change. - m_ReverseDepthMode = CRenderer::CV_r_ReverseDepth; - m_raymarchDistance = raymarchDistance; - - rd->FX_ClearTarget((D3DDepthSurface*)CTexture::s_ptexVolumetricClipVolumeStencil->GetDeviceDepthStencilSurf(), CLEAR_ZBUFFER, Clr_FarPlane_R.r, 0); - } - - for (int i = 0; i < maxDepthCount; ++i) - { - // set separate DSV. - D3dDepthSurface.pSurf = (D3DDepthSurface*)m_ClipVolumeDSVArray[i]; - rd->FX_PushRenderTarget(0, (CTexture*)NULL, &D3dDepthSurface); - - // clear depth when it's needed. - if (m_Destroyed > 0) - { - // write jittering depth. - static CCryNameTSCRC shaderName("StoreJitteringDepthToClipVolumeDepth"); - bool result = GetUtils().ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - - valid = valid && result; - - rd->FX_SetState(GS_DEPTHWRITE); - - static CCryNameR paramDepth("ParamDepth"); - Vec4 vParamDepth((float)i, b, a, d); - CShaderMan::s_shDeferredShading->FXSetPSFloat(paramDepth, &vParamDepth, 1); - - GetUtils().DrawFullScreenTri(targetWidth, targetHeight); - - GetUtils().ShEndPass(); - } - - CDeferredShading& pDS = CDeferredShading::Instance(); - pDS.RenderClipVolumesToStencil(nClipAreaReservedStencilBit); - - rd->FX_PopRenderTarget(0); - } - - if (valid) - { - m_Destroyed = (m_Destroyed > 0) ? (m_Destroyed - 1) : 0; - - if (m_ReverseDepthMode != CRenderer::CV_r_ReverseDepth - || (0.2f < abs(m_raymarchDistance - raymarchDistance))) - { - // rewrite the depth if needed. - m_Destroyed = MaxFrameNum; - } - } - - rd->RT_SetViewport(oldX, oldY, oldWidth, oldHeight); - rp.m_ObjFlags = objFlags; -} - -void CVolumetricFog::InjectExponentialHeightFog() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - const int nThreadID = rp.m_nProcessThreadID; - - // store state - const int32 prevState = rp.m_CurState; - const uint32 prevStateAnd = rp.m_StateAnd; - const uint32 prevStateOr = rp.m_StateOr; - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - const int prevPersFlags = rp.m_TI[nThreadID].m_PersFlags; - - - // inject atmospheric fog into density volume texture. - { - const uint32 nScreenWidth = CTexture::s_ptexVolumetricFogDensity->GetWidth(); - const uint32 nScreenHeight = CTexture::s_ptexVolumetricFogDensity->GetHeight(); - const uint32 volumeDepth = CTexture::s_ptexVolumetricFogDensity->GetDepth(); - - //PROFILE_LABEL_SCOPE( "INJECT_ATMOSPHERIC_FOG" ); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - - - rd->GetTiledShading().BindForwardShadingResources(NULL, eHWSC_Compute); - - CShader* pShader = CShaderMan::s_shDeferredShading; - - static CCryNameTSCRC shaderName("InjectExponentialHeightFog"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[1] = { - static_cast(CTexture::s_ptexVolumetricFogDensity->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 1); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSamplers, 0, 1); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - pShader->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - pShader->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - pShader->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - pShader->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - static CCryNameR paramInjectExponentialHeightFogParams("InjectExponentialHeightFogParams"); - Vec4 vInjectExponentialHeightFogParams((float)volumeDepth, 0.0f, 0.0f, 0.0f); - pShader->FXSetCSFloat(paramInjectExponentialHeightFogParams, &vInjectExponentialHeightFogParams, 1); - - rd->FX_Commit(); - - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - - rd->GetTiledShading().UnbindForwardShadingResources(eHWSC_Compute); - } - - - D3DUnorderedAccessView* pUAVNull4[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull4, NULL, 0, 4); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - - D3DSamplerState* pSampNull[2] = { NULL }; - rd->m_DevMan.BindSampler(eHWSC_Compute, pSampNull, 0, 2); - - // restore state - rp.m_StateAnd = prevStateAnd; - rp.m_StateOr = prevStateOr; - rd->SetState(prevState); - rp.m_TI[nThreadID].m_PersFlags = prevPersFlags; - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::PrepareFogVolumeList() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - int nThreadID = rd->m_RP.m_nProcessThreadID; - int nRecurseLevel = SRendItem::m_RecurseLevel[nThreadID]; - - // Prepare view matrix with flipped z-axis - Matrix44A matView = rd->m_ViewMatrix; - matView.m02 *= -1; - matView.m12 *= -1; - matView.m22 *= -1; - matView.m32 *= -1; - - vfInternal::SFogVolumeCullInfo cullInfoArray[vfInternal::MaxNumFogVolumes]; - vfInternal::SFogVolumeInjectInfo injectInfoArray[vfInternal::MaxNumFogVolumes]; - uint32 numFogVol = 0; - - Vec3 volumetricFogRaymarchEnd(0.0f, 0.0f, 0.0f); - gEnv->p3DEngine->GetGlobalParameter(E3DPARAM_VOLFOG2_CTRL_PARAMS, volumetricFogRaymarchEnd); - Vec3 cameraFront = rd->GetViewParameters().vZ; - cameraFront.Normalize(); - - Vec3 worldViewPos = rd->GetViewParameters().vOrigin; - AABB aabbInObj(1.0f); - - for (uint32 type = 0; type < MaxNumFogVolumeType; ++type) - { - TArray& srcArray = m_fogVolumeInfoArray[nThreadID][nRecurseLevel][type]; - uint num = srcArray.Num(); - for (uint32 i = 0; i < num; ++i) - { - SFogVolumeInfo& fvol = srcArray[i]; - - // calculate depth bounds of FogVolume. - // reusing light depth bounds code from CDeferredShading::GetLightDepthBounds(). - // This is not optimal for a box. - Matrix34 temp = fvol.m_matWSInv.GetInverted(); - AABB aabbInWS = AABB::CreateTransformedAABB(temp, aabbInObj); - float fRadius = aabbInWS.GetRadius(); - Vec3 pBounds = cameraFront * fRadius; - Vec3 pMin = fvol.m_center + pBounds; - float fMinW = rd->GetViewParameters().WorldToCamZ(pMin); - fMinW = max(-fMinW, 0.000001f); - - // not needed to be injected when FogVolume is out of volume texture. - if (fMinW > volumetricFogRaymarchEnd.x) - { - continue; - } - - vfInternal::SFogVolumeCullInfo& cullInfo = cullInfoArray[numFogVol]; - vfInternal::SFogVolumeInjectInfo& injectInfo = injectInfoArray[numFogVol]; - - Vec4 posVS = Vec4(fvol.m_center, 1) * matView; - cullInfo.posRad = Vec4(posVS.x, posVS.y, posVS.z, fRadius); - - Vec4 u0 = Vec4(temp.GetColumn0().GetNormalized(), 0) * matView; - Vec4 u1 = Vec4(temp.GetColumn1().GetNormalized(), 0) * matView; - Vec4 u2 = Vec4(temp.GetColumn2().GetNormalized(), 0) * matView; - Vec3 size = fvol.m_scale.CompMul(fvol.m_localAABB.GetSize() * 0.5f); - cullInfo.volumeParams0 = Vec4(u0.x, u0.y, u0.z, size.x); - cullInfo.volumeParams1 = Vec4(u1.x, u1.y, u1.z, size.y); - cullInfo.volumeParams2 = Vec4(u2.x, u2.y, u2.z, size.z); - - uint32 nData = fvol.m_stencilRef + 1;// first ref value is reserved, see CDeferredShading::PrepareClipVolumeData function. - injectInfo.miscFlag = fvol.m_volumeType | ((nData & 0xFF) << 1) | (fvol.m_affectsThisAreaOnly << 9); - - injectInfo.fogColor.x = fvol.m_fogColor.r; - injectInfo.fogColor.y = fvol.m_fogColor.g; - injectInfo.fogColor.z = fvol.m_fogColor.b; - - float globalDensity = fvol.m_globalDensity * 0.1f;// scale density to volumetric fog. - injectInfo.globalDensity = globalDensity; - - injectInfo.fogVolumePos = fvol.m_center; - - injectInfo.heightFalloffBasePoint = fvol.m_heightFallOffBasePoint; - - float softEdgeLerp = (fvol.m_softEdgesLerp.x > 0.0f) ? fvol.m_softEdgesLerp.x : 0.0001f; - injectInfo.invSoftEdgeLerp = 1.0f / softEdgeLerp; - - const Vec3 cHeightFallOffDirScaledVec(fvol.m_heightFallOffDirScaled * 0.015625f); // scale fall off ramp to volumetric fog. - injectInfo.heightFallOffDirScaled = cHeightFallOffDirScaledVec; - - injectInfo.densityOffset = fvol.m_densityOffset; - - float rampDist = fvol.m_rampParams.y - fvol.m_rampParams.x; - rampDist = rampDist < 0.1f ? 0.1f : rampDist; - float invRampDist = 1.0f / rampDist; - const Vec4 cRampParams(invRampDist, -fvol.m_rampParams.x * invRampDist, fvol.m_rampParams.z, -fvol.m_rampParams.z + 1.0f); - injectInfo.rampParams = cRampParams; - - injectInfo.windOffset = fvol.m_windOffset; - - injectInfo.noiseElapsedTime = fvol.m_noiseElapsedTime; - - injectInfo.noiseSpatialFrequency = fvol.m_noiseFreq; - - const float normalizeFactor = (1.0f / (1.0f + 0.5f)); - injectInfo.noiseScale = fvol.m_noiseScale * normalizeFactor; - - injectInfo.eyePosInOS = fvol.m_eyePosInOS; - - injectInfo.noiseOffset = fvol.m_noiseOffset; - - injectInfo.worldToObjMatrix = fvol.m_matWSInv; - - ++numFogVol; - } - } - - m_numFogVolumes = numFogVol; - - m_fogVolumeCullInfoBuf.UpdateBufferContent(cullInfoArray, sizeof(vfInternal::SFogVolumeCullInfo) * vfInternal::MaxNumFogVolumes); - m_fogVolumeInjectInfoBuf.UpdateBufferContent(injectInfoArray, sizeof(vfInternal::SFogVolumeInjectInfo) * vfInternal::MaxNumFogVolumes); -} - -void CVolumetricFog::InjectFogDensity() -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - const int nThreadID = rp.m_nProcessThreadID; - - // store state - const int32 prevState = rp.m_CurState; - const uint32 prevStateAnd = rp.m_StateAnd; - const uint32 prevStateOr = rp.m_StateOr; - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - const int prevPersFlags = rp.m_TI[nThreadID].m_PersFlags; - - { - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 8, 8); - - D3DUnorderedAccessView* pUAVNull[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull, NULL, 0, 4); - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); - } - - // inject the density of atmospheric fog and FogVolume into volume texture. - { - rd->GetTiledShading().BindForwardShadingResources(NULL, eHWSC_Compute); - - const uint32 nScreenWidth = CTexture::s_ptexVolumetricFogDensity->GetWidth(); - const uint32 nScreenHeight = CTexture::s_ptexVolumetricFogDensity->GetHeight(); - const uint32 volumeDepth = CTexture::s_ptexVolumetricFogDensity->GetDepth(); - - //PROFILE_LABEL_SCOPE( "INJECT_FOG_DENSITY" ); - - static CCryNameTSCRC shaderName("InjectFogDensity"); - SD3DPostEffectsUtils::ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETSTATES); - - D3DUnorderedAccessView* pUAVs[2] = { - (CTexture::s_ptexVolumetricFogDensity->GetDeviceUAV()), - (CTexture::s_ptexVolumetricFogDensityColor->GetDeviceUAV()), - }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVs, NULL, 0, 2); - - D3DShaderResourceView* pSRVs[3] = { - m_fogVolumeInjectInfoBuf.GetShaderResourceView(), - m_fogVolumeCullInfoBuf.GetShaderResourceView(), - m_MaxDepth->GetShaderResourceView(), - }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pSRVs, 8, 3); - - //D3DSamplerState *pSamplers[1] = { - // (D3DSamplerState *)CTexture::s_TexStates[m_nTexStateTriLinear].m_pDeviceState, - // //(D3DSamplerState *)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - //}; - //rd->m_DevMan.BindSampler( eHWSC_Compute, pSamplers, 0, 1 ); - - static CCryNameR paramScreenSize("ScreenSize"); - float fScreenWidth = (float)nScreenWidth; - float fScreenHeight = (float)nScreenHeight; - Vec4 vParamScreenSize(fScreenWidth, fScreenHeight, 1.0f / fScreenWidth, 1.0f / fScreenHeight); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramScreenSize, &vParamScreenSize, 1); - - SD3DPostEffectsUtils::UpdateFrustumCorners(); - static CCryNameR paramFrustumTL("FrustumTL"); - Vec4 vParamFrustumTL(SD3DPostEffectsUtils::m_vLT.x, SD3DPostEffectsUtils::m_vLT.y, SD3DPostEffectsUtils::m_vLT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTL, &vParamFrustumTL, 1); - static CCryNameR paramFrustumTR("FrustumTR"); - Vec4 vParamFrustumTR(SD3DPostEffectsUtils::m_vRT.x, SD3DPostEffectsUtils::m_vRT.y, SD3DPostEffectsUtils::m_vRT.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumTR, &vParamFrustumTR, 1); - static CCryNameR paramFrustumBL("FrustumBL"); - Vec4 vParamFrustumBL(SD3DPostEffectsUtils::m_vLB.x, SD3DPostEffectsUtils::m_vLB.y, SD3DPostEffectsUtils::m_vLB.z, 0); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramFrustumBL, &vParamFrustumBL, 1); - - float octave = (CRenderer::CV_r_VolumetricFogReprojectionBlendFactor > 0.0f) ? -1.7f : 0.0f; - static CCryNameR paramInjectExponentialHeightFogParams("InjectFogDensityParams"); - Vec4 vInjectExponentialHeightFogParams((float)volumeDepth, (float)m_numFogVolumes, octave, 0.0f); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramInjectExponentialHeightFogParams, &vInjectExponentialHeightFogParams, 1); - - static CCryNameR paramProj("ProjParams"); - Vec4 vParamProj(rd->m_ProjMatrix.m00, rd->m_ProjMatrix.m11, rd->m_ProjMatrix.m20, rd->m_ProjMatrix.m21); - CShaderMan::s_shDeferredShading->FXSetCSFloat(paramProj, &vParamProj, 1); - - const uint32 tileSizeX = 4; - const uint32 tileSizeY = 4; - const uint32 tileSizeZ = 4; - uint32 dispatchSizeX = (nScreenWidth / tileSizeX) + (nScreenWidth % tileSizeX > 0 ? 1 : 0); - uint32 dispatchSizeY = (nScreenHeight / tileSizeY) + (nScreenHeight % tileSizeY > 0 ? 1 : 0); - uint32 dispatchSizeZ = (volumeDepth / tileSizeZ) + (volumeDepth % tileSizeZ > 0 ? 1 : 0); - - rd->FX_Commit(); - - rd->m_DevMan.Dispatch(dispatchSizeX, dispatchSizeY, dispatchSizeZ); - - SD3DPostEffectsUtils::ShEndPass(); - - rd->GetTiledShading().UnbindForwardShadingResources(eHWSC_Compute); - } - - - D3DUnorderedAccessView* pUAVNull4[4] = { NULL }; - rd->m_DevMan.BindUAV(eHWSC_Compute, pUAVNull4, NULL, 0, 4); - - D3DShaderResourceView* pNullViews[8] = { NULL }; - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 0, 8); - rd->m_DevMan.BindSRV(eHWSC_Compute, pNullViews, 8, 8); - - //D3DSamplerState* pSampNull[2] = { NULL }; - //rd->m_DevMan.BindSampler( eHWSC_Compute, pSampNull, 0, 2 ); - - // restore state - rp.m_StateAnd = prevStateAnd; - rp.m_StateOr = prevStateOr; - rd->SetState(prevState); - rp.m_TI[nThreadID].m_PersFlags = prevPersFlags; - rp.m_FlagsShader_RT = prevShaderRtFlags; - - rd->FX_Commit(); - rd->m_DevMan.CommitDeviceStates(); -} - -void CVolumetricFog::RenderDownscaledShadowmap() -{ - if (!gcpRendD3D->m_bShadowsEnabled) - { - return; - } - - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 0) - { - return; - } - - //PROFILE_LABEL_SCOPE("DOWNSCALE_SHADOWMAP"); - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - - // store state - int oldX, oldY; - int oldWidth, oldHeight; - rd->GetViewport(&oldX, &oldY, &oldWidth, &oldHeight); - const uint64 prevShaderRtFlags = rp.m_FlagsShader_RT; - - rd->FX_SetupShadowsForFog(); - - SDepthTexture D3dDepthSurface; - static const int texStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - int count = (CRenderer::CV_r_VolumetricFogDownscaledSunShadow == 1) ? 2 : 3; - - for (int i = 0; i < count; ++i) - { - { - const uint64 lv0 = g_HWSR_MaskBit[HWSR_LIGHTVOLUME0]; - const uint64 lv1 = g_HWSR_MaskBit[HWSR_LIGHTVOLUME1]; - rp.m_FlagsShader_RT &= ~(lv0 | lv1); - switch (i) - { - case 0: - rp.m_FlagsShader_RT |= lv0; - break; - case 1: - rp.m_FlagsShader_RT |= lv1; - break; - case 2: - rp.m_FlagsShader_RT |= lv0 | lv1; - break; - default: - break; - } - - CTexture* target = NULL; - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio == 0) - { - target = m_downscaledShadow[i]; - } - else - { - target = m_downscaledShadowTemp; - } - - int targetWidth = target->GetWidth(); - int targetHeight = target->GetHeight(); - - D3dDepthSurface.nWidth = targetWidth; - D3dDepthSurface.nHeight = targetHeight; - D3dDepthSurface.pTex = target; - D3dDepthSurface.pSurf = (D3DDepthSurface*)target->GetDeviceDepthStencilSurf(); - D3dDepthSurface.pTarget = target->GetDevTexture()->Get2DTexture(); - rd->FX_PushRenderTarget(0, (CTexture*)NULL, &D3dDepthSurface); - rd->FX_SetActiveRenderTargets(); - - rd->FX_SetState(GS_COLMASK_NONE | GS_DEPTHWRITE | GS_DEPTHFUNC_NOTEQUAL); - - static CCryNameTSCRC shaderName("RenderDownscaledShadowMap"); - GetUtils().ShBeginPass(CShaderMan::s_shDeferredShading, shaderName, FEF_DONTSETSTATES); - - D3DSamplerState* pSamplers[1] = { - (D3DSamplerState*)CTexture::s_TexStates[m_nTexStatePoint].m_pDeviceState, - }; - rd->m_DevMan.BindSampler(eHWSC_Pixel, pSamplers, 0, 1); - - GetUtils().DrawFullScreenTri(targetWidth, targetHeight); - - GetUtils().ShEndPass(); - - rd->FX_PopRenderTarget(0); - - rp.m_FlagsShader_RT = prevShaderRtFlags; - } - - // additional downscale pass - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio != 0) - { - CTexture* source = m_downscaledShadowTemp; - CTexture* target = m_downscaledShadow[i]; - - int targetWidth = target->GetWidth(); - int targetHeight = target->GetHeight(); - - D3dDepthSurface.nWidth = targetWidth; - D3dDepthSurface.nHeight = targetHeight; - D3dDepthSurface.pTex = target; - D3dDepthSurface.pSurf = target->GetDeviceDepthStencilSurf(); - D3dDepthSurface.pTarget = target->GetDevTexture()->Get2DTexture(); - - rd->FX_PushRenderTarget(0, (CTexture*)NULL, &D3dDepthSurface); - rd->FX_SetActiveRenderTargets(); - - rd->FX_SetState(GS_COLMASK_NONE | GS_DEPTHWRITE | GS_DEPTHFUNC_NOTEQUAL); - - static CCryNameTSCRC shaderName0("DownscaleShadowMap2"); - static CCryNameTSCRC shaderName1("DownscaleShadowMap4"); - if (CRenderer::CV_r_VolumetricFogDownscaledSunShadowRatio == 1) - { - GetUtils().ShBeginPass(CShaderMan::s_shDeferredShading, shaderName0, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - else - { - GetUtils().ShBeginPass(CShaderMan::s_shDeferredShading, shaderName1, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES); - } - - source->Apply(0, texStatePoint, EFTT_UNKNOWN, -1, SResourceView::DefaultView); - - GetUtils().DrawFullScreenTri(targetWidth, targetHeight); - - GetUtils().ShEndPass(); - - rd->FX_PopRenderTarget(0); - } - } - - // restore pipeline state. - rd->RT_SetViewport(oldX, oldY, oldWidth, oldHeight); - rp.m_FlagsShader_RT = prevShaderRtFlags; - rd->FX_Commit(); -} - -void CVolumetricFog::SetupStaticShadowMap(int nSlot) const -{ - CD3D9Renderer* const __restrict rd = gcpRendD3D; - SRenderPipeline& rp(rd->m_RP); - const int nThreadID = rp.m_nProcessThreadID; - - const int nSunFrustumID = 0; - const int nStartIdx = SRendItem::m_StartFrust[nThreadID][nSunFrustumID]; - const int nEndIdx = SRendItem::m_EndFrust[nThreadID][nSunFrustumID]; - - for (int i = nStartIdx; i < nEndIdx; ++i) - { - ShadowMapFrustum& fr = rp.m_SMFrustums[nThreadID][nSunFrustumID][i]; - if (fr.m_eFrustumType == ShadowMapFrustum::e_GsmCached) - { - rd->ConfigShadowTexgen(nSlot, &fr, -1, true); - break; - } - } -} - diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.h deleted file mode 100644 index b09a918172..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3DVolumetricFog.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -/* A short note on MultiGPU: - Without knowing for sure if textures are copied between GPUs, the only 'correct' solution would be to have 2 * NUM_GPUs copies of rendertargets - This would use too much memory though, so we keep one copy and swap it once every NUM_GPUs frames.This will work correctly if copy between GPUs - is disabled. In case copies are performed though, every second frame the re-projection matrix will be off by a frame. -*/ -#ifndef _D3DVOLUMETRICFOG_H_ -#define _D3DVOLUMETRICFOG_H_ - - -class CVolumetricFog -{ -public: - CVolumetricFog(); - - void CreateResources(); - void DestroyResources(bool destroyResolutionIndependentResources); - void Clear(); - void ClearAll(); - - void PrepareLightList(TArray* envProbes, TArray* ambientLights, TArray* defLights, uint32 firstShadowLight, uint32 curShadowPoolLight); - - void RenderVolumetricsToVolume(void (* RenderFunc)()); - void RenderVolumetricFog(); - - void ClearVolumeStencil(); - void RenderClipVolumeToVolumeStencil(int nClipAreaReservedStencilBit); - - float GetDepthIndex(float linearDepth) const; - bool IsEnableInFrame() const; - const Vec4& GetGlobalEnvProbeShaderParam0() const {return m_globalEnvProbeParam0; } - const Vec4& GetGlobalEnvProbeShaderParam1() const {return m_globalEnvProbeParam1; } - CTexture* GetGlobalEnvProbeTex0() const {return m_globalEnvProveTex0; } - CTexture* GetGlobalEnvProbeTex1() const {return m_globalEnvProveTex1; } - - void PushFogVolume(class CREFogVolume* pFogVolume, const SRenderingPassInfo& passInfo); - -private: - static const uint32 MaxFrameNum = 4; - static const uint32 MaxNumFogVolumeType = 2; - - struct SFogVolumeInfo - { - Vec3 m_center; - uint32 m_viewerInsideVolume : 1; - uint32 m_affectsThisAreaOnly : 1; - uint32 m_stencilRef : 8; - uint32 m_volumeType : 1; - uint32 m_reserved : 21; - AABB m_localAABB; - Matrix34 m_matWSInv; - float m_globalDensity; - float m_densityOffset; - Vec2 m_softEdgesLerp; - ColorF m_fogColor; - Vec3 m_heightFallOffDirScaled; - Vec3 m_heightFallOffBasePoint; - Vec3 m_eyePosInOS; - Vec3 m_rampParams; - Vec3 m_windOffset; - float m_noiseScale; - Vec3 m_noiseFreq; - float m_noiseOffset; - float m_noiseElapsedTime; - Vec3 m_scale; - }; - - void ClearFogVolumes(); - void ClearAllFogVolumes(); - void UpdateFrame(); - bool IsViable() const; - void InjectInscatteringLight(); - void BuildLightListGrid(); - void RaymarchVolumetricFog(); - void BlurInscatterVolume(); - void BlurDensityVolume(); - void ReprojectVolume(); - CTexture* GetInscatterTex() const; - CTexture* GetPrevInscatterTex() const; - CTexture* GetDensityTex() const; - CTexture* GetPrevDensityTex() const; - void RenderDownscaledDepth(); - void InjectExponentialHeightFog(); - void PrepareFogVolumeList(); - void InjectFogDensity(); - void RenderDownscaledShadowmap(); - void SetupStaticShadowMap(int nSlot) const; - -private: - Matrix44A m_viewProj[MaxFrameNum]; - CTexture* m_InscatteringVolume; - CTexture* m_fogInscatteringVolume[2]; - CTexture* m_MaxDepth; - CTexture* m_MaxDepthTemp; - D3DDepthSurface** m_ClipVolumeDSVArray; - CTexture* m_fogDensityVolume[2]; - CTexture* m_downscaledShadow[3]; - CTexture* m_downscaledShadowTemp; - CTexture* m_globalEnvProveTex0; - CTexture* m_globalEnvProveTex1; - - int m_nTexStateTriLinear; - int m_nTexStateCompare; - int m_nTexStatePoint; - int32 m_Cleared; - int32 m_Destroyed; - uint32 m_numTileLights; - uint32 m_numFogVolumes; - int32 m_frameID; - int32 m_tick; - int32 m_ReverseDepthMode; - float m_raymarchDistance; - Vec4 m_globalEnvProbeParam0; - Vec4 m_globalEnvProbeParam1; - - WrappedDX11Buffer m_lightCullInfoBuf; - WrappedDX11Buffer m_LightShadeInfoBuf; - WrappedDX11Buffer m_lightGridBuf; - WrappedDX11Buffer m_lightCountBuf; - WrappedDX11Buffer m_fogVolumeCullInfoBuf; - WrappedDX11Buffer m_fogVolumeInjectInfoBuf; - - TArray m_fogVolumeInfoArray[RT_COMMAND_BUF_COUNT][MAX_REND_RECURSION_LEVELS][MaxNumFogVolumeType]; -}; - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.cpp deleted file mode 100644 index 7d49132125..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.cpp +++ /dev/null @@ -1,1705 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" - -#if defined(FEATURE_SVO_GI) - -#include "DriverD3D.h" -#include "I3DEngine.h" -#include "D3DPostProcess.h" -#include "D3D_SVO.h" -#include "D3DTiledShading.h" -#include "../Common/Include_HLSL_CPP_Shared.h" -#include "../Common/TypedConstantBuffer.h" -#include "../Common/Textures/TextureManager.h" - -#include - - -CSvoRenderer* CSvoRenderer::s_pInstance = 0; - -CSvoRenderer::CSvoRenderer() -{ - m_pRT_AIR_MIN = - m_pRT_AIR_MAX = - m_pRT_AIR_SHAD = - m_pRT_NID_0 = NULL; - - m_nTexStateTrilinear = CTexture::GetTexState(STexState(FILTER_TRILINEAR, true)); - m_nTexStateLinear = CTexture::GetTexState(STexState(FILTER_LINEAR, true)); - m_nTexStatePoint = CTexture::GetTexState(STexState(FILTER_POINT, true)); - m_nTexStateLinearWrap = CTexture::GetTexState(STexState(FILTER_LINEAR, false)); - - m_pNoiseTex = nullptr; - m_pRsmNormlMap = m_pRsmColorMap = 0; - m_pRsmPoolNor = m_pRsmPoolCol = 0; - - m_pShader = nullptr; - - ZeroStruct(m_arrNodesForUpdate); - ZeroStruct(m_nCurPropagationPassID); - - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::RegisterMutex, &m_renderMutex); -} - -void SSvoTargetsSet::Release() -{ - SAFE_RELEASE(pRT_RGB_DEM_MIN_0); - SAFE_RELEASE(pRT_ALD_DEM_MIN_0); - SAFE_RELEASE(pRT_RGB_DEM_MAX_0); - SAFE_RELEASE(pRT_ALD_DEM_MAX_0); - SAFE_RELEASE(pRT_RGB_DEM_MIN_1); - SAFE_RELEASE(pRT_ALD_DEM_MIN_1); - SAFE_RELEASE(pRT_RGB_DEM_MAX_1); - SAFE_RELEASE(pRT_ALD_DEM_MAX_1); - SAFE_RELEASE(pRT_FIN_OUT_0); - SAFE_RELEASE(pRT_FIN_OUT_1); - SAFE_RELEASE(pRT_ALD_0); - SAFE_RELEASE(pRT_ALD_1); - SAFE_RELEASE(pRT_RGB_0); - SAFE_RELEASE(pRT_RGB_1); -} - -CSvoRenderer::~CSvoRenderer() -{ - m_tsDiff.Release(); - m_tsSpec.Release(); - - SAFE_RELEASE(m_pRT_AIR_MIN); - SAFE_RELEASE(m_pRT_AIR_MAX); - SAFE_RELEASE(m_pRT_AIR_SHAD); - SAFE_RELEASE(m_pRT_NID_0); - SAFE_RELEASE(m_pRsmColorMap); - SAFE_RELEASE(m_pRsmNormlMap); - SAFE_RELEASE(m_pRsmPoolCol); - SAFE_RELEASE(m_pRsmPoolNor); - SVOGILegacyRequestBus::Broadcast(&SVOGILegacyRequests::UnregisterMutex); -} - -CSvoRenderer* CSvoRenderer::GetInstance(bool bCheckAlloce) -{ - if (!s_pInstance && bCheckAlloce) - { - s_pInstance = new CSvoRenderer(); - } - - return s_pInstance; -} - -void CSvoRenderer::Release() -{ - SAFE_DELETE(s_pInstance); -} - -void CSvoRenderer::UpdateCompute() -{ - if (!IsActive()) - { - return; - } - - UpdatePassConstantBuffer(); - - static int nTI_Compute_FrameId = -1; - if (nTI_Compute_FrameId == gRenDev->GetFrameID(false)) - { - return; - } - nTI_Compute_FrameId = gRenDev->GetFrameID(false); - - gEnv->p3DEngine->GetSvoStaticTextures(m_texInfo, &m_arrLightsStatic, &m_arrLightsDynamic); - if (m_texInfo.pTexTree == nullptr) - { - return; - } - - - if (!m_pShader) - { - gcpRendD3D->m_cEF.mfRefreshSystemShader("Total_Illumination", m_pShader); - } - - m_nodesForStaticUpdate.Clear(); - m_nodesForDynamicUpdate.Clear(); - - - if (GetIntegratioMode()) - { - gEnv->p3DEngine->GetSvoBricksForUpdate(m_arrNodeInfo, false); - - for (int n = 0; n < m_arrNodeInfo.Count(); n++) - { - m_nodesForStaticUpdate.Add(m_arrNodeInfo[n]); - } - - m_arrNodeInfo.Clear(); - } - - if (GetIntegratioMode()) - { - gEnv->p3DEngine->GetSvoBricksForUpdate(m_arrNodeInfo, true); - - for (int n = 0; n < m_arrNodeInfo.Count(); n++) - { - m_nodesForDynamicUpdate.Add(m_arrNodeInfo[n]); - } - - m_arrNodeInfo.Clear(); - } - - { - // get UAV access - vp_RGB0.Init(m_texInfo.pTexRgb0); - vp_RGB1.Init(m_texInfo.pTexRgb1); - vp_DYNL.Init(m_texInfo.pTexDynl); - vp_RGB2.Init(m_texInfo.pTexRgb2); - vp_RGB3.Init(m_texInfo.pTexRgb3); - vp_NORM.Init(m_texInfo.pTexNorm); - vp_ALDI.Init(m_texInfo.pTexAldi); - vp_OPAC.Init(m_texInfo.pTexOpac); - } - - if (!IsActive() || !m_texInfo.bSvoReady || !GetIntegratioMode()) - { - return; - } - - // force sync shaders compiling - int nPrevAsync = CRenderer::CV_r_shadersasynccompiling; - CRenderer::CV_r_shadersasynccompiling = 0; - - // clear pass - { - PROFILE_LABEL_SCOPE("TI_INJECT_CLEAR"); - - for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); ) - { - ExecuteComputeShader(m_pShader, "ComputeClearBricks", eCS_ClearBricks, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate); - } - } - - { - PROFILE_LABEL_SCOPE("TI_INJECT_LIGHT"); - - for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); ) - { - ExecuteComputeShader(m_pShader, "ComputeDirectStaticLighting", eCS_InjectStaticLights, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate); - } - } - - if (gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()) - { - if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() > 1) - { - PROFILE_LABEL_SCOPE("TI_INJECT_REFL0"); - - m_nCurPropagationPassID = 0; - for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); ) - { - ExecuteComputeShader(m_pShader, "ComputePropagateLighting", eCS_PropagateLighting_1to2, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate); - } - } - - if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() > 2) - { - PROFILE_LABEL_SCOPE("TI_INJECT_REFL1"); - - m_nCurPropagationPassID++; - for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForStaticUpdate.Count(); ) - { - ExecuteComputeShader(m_pShader, "ComputePropagateLighting", eCS_PropagateLighting_2to3, &nNodesForUpdateStartIndex, 0, m_nodesForStaticUpdate); - } - } - } - - static int nLightsDynamicCountPrevFrame = 0; - - if ((m_arrLightsDynamic.Count() || nLightsDynamicCountPrevFrame)) - { - PROFILE_LABEL_SCOPE("TI_INJECT_DYNL"); - - // TODO: cull not affected nodes - - for (int nNodesForUpdateStartIndex = 0; nNodesForUpdateStartIndex < m_nodesForDynamicUpdate.Count(); ) - { - ExecuteComputeShader(m_pShader, "ComputeDirectDynamicLighting", eCS_InjectDynamicLights, &nNodesForUpdateStartIndex, 0, m_nodesForDynamicUpdate); - } - } - - nLightsDynamicCountPrevFrame = m_arrLightsDynamic.Count(); - - CRenderer::CV_r_shadersasynccompiling = nPrevAsync; - -} - -void CSvoRenderer::ExecuteComputeShader(CShader* pSH, const char* szTechFinalName, EComputeStages eRenderStage, int* pnNodesForUpdateStartIndex, [[maybe_unused]] int nObjPassId, PodArray& arrNodesForUpdate) -{ - - FUNCTION_PROFILER_RENDERER; - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - SetShaderFlags(true, false); - - SD3DPostEffectsUtils::ShBeginPass(pSH, szTechFinalName, FEF_DONTSETSTATES); - - if (!gRenDev->m_RP.m_pShader) - { - gEnv->pLog->LogWarning("%s: Technique not found: %s", __FUNC__, szTechFinalName); - (*pnNodesForUpdateStartIndex) += 1000; - return; - } - - { - static CCryNameR param("SVO_PropagationPass"); - Vec4 value((float)(m_nCurPropagationPassID), 0, 0, 0); - m_pShader->FXSetCSFloat(param, (Vec4*)&value, 1); - } - - { - static CCryNameR parameterName6("SVO_FrameIdByte"); - Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4); - if (rd->GetActiveGPUCount() > 1) - { - ttt.x = 0; - } - m_pShader->FXSetCSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - static CCryNameR parameterName6("SVO_CamPos"); - Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0); - m_pShader->FXSetCSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - Matrix44A mViewProj; - mViewProj = gcpRendD3D->m_ViewProjMatrix; - mViewProj.Transpose(); - - static CCryNameR paramName("g_mViewProj"); - m_pShader->FXSetCSFloat(paramName, alias_cast(&mViewProj), 4); - - static CCryNameR paramNamePrev("g_mViewProjPrev"); - m_pShader->FXSetPSFloat(paramNamePrev, alias_cast(&m_matViewProjPrev), 4); - } - - { - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - float zn = rc.fNear; - float zf = rc.fFar; - float hfov = gcpRendD3D->GetCamera().GetHorizontalFov(); - Vec4 f; - f[0] = zf / (zf - zn); - f[1] = zn / (zn - zf); - f[2] = 1.0f / hfov; - f[3] = 1.0f; - static CCryNameR paramName("SVO_ProjRatio"); - m_pShader->FXSetCSFloat(paramName, alias_cast(&f), 1); - } - - // setup SVO textures - - ID3D11DeviceContext* pDeviceCtx = &gcpRendD3D->GetDeviceContext(); - UINT UAVInitialCounts = 0; - - if (eRenderStage == eCS_InjectStaticLights) - { - SetupLightSources(m_arrLightsStatic, m_pShader, false); - SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate); - - // update RGB1 - pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &vp_RGB0.pUAV, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_NORM.pUAV, &UAVInitialCounts); - - if (vp_DYNL.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_DYNL.pUAV, &UAVInitialCounts); - } - - SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 0); - - SetupRsmSun(eHWSC_Compute); - } - else if (eRenderStage == eCS_InjectDynamicLights) - { - BindTiledLights(m_arrLightsDynamic, eHWSC_Compute); - SetupLightSources(m_arrLightsDynamic, m_pShader, false); - SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate); - - // update RGB - pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &vp_RGB0.pUAV, &UAVInitialCounts); - - if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 1) - { - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts); - } - if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 2) - { - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB2.pUAV, &UAVInitialCounts); - } - if (gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() == 3) - { - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB3.pUAV, &UAVInitialCounts); - } - - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_DYNL.pUAV, &UAVInitialCounts); - - SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 0); - if (!m_pNoiseTex) - { - m_pNoiseTex = CTextureManager::Instance()->GetDefaultTexture("DissolveNoiseMap"); - } - m_pNoiseTex->Apply(15, m_nTexStateLinearWrap, -1, -1, -1, eHWSC_Compute); - - SetupRsmSun(eHWSC_Compute); - } - else if (eRenderStage == eCS_PropagateLighting_1to2) - { - SetupLightSources(m_arrLightsStatic, m_pShader, false); - SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate); - - // update RGB2 - if (vp_RGB0.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_RGB0.pUAV, &UAVInitialCounts); - } - SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 1); // input - if (vp_RGB2.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB2.pUAV, &UAVInitialCounts); - } - if (vp_ALDI.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_ALDI.pUAV, &UAVInitialCounts); - } - if (vp_DYNL.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_DYNL.pUAV, &UAVInitialCounts); - } - } - else if (eRenderStage == eCS_PropagateLighting_2to3) - { - SetupLightSources(m_arrLightsStatic, m_pShader, false); - SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate); - - // update RGB3 - if (vp_RGB0.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_RGB0.pUAV, &UAVInitialCounts); - } - SetupSvoTexturesForRead(m_texInfo, eHWSC_Compute, 2); // input - if (vp_RGB3.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB3.pUAV, &UAVInitialCounts); - } - if (vp_ALDI.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_ALDI.pUAV, &UAVInitialCounts); - } - if (vp_DYNL.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_DYNL.pUAV, &UAVInitialCounts); - } - } - else if (eRenderStage == eCS_ClearBricks) - { - SetupNodesForUpdate(*pnNodesForUpdateStartIndex, arrNodesForUpdate); - - if (vp_RGB3.pUAV) - { - pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &vp_RGB3.pUAV, &UAVInitialCounts); - } - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &vp_RGB1.pUAV, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &vp_RGB2.pUAV, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &vp_ALDI.pUAV, &UAVInitialCounts); - } - - { - rd->FX_Commit(); - - uint32 nDispatchSizeX = 128; - uint32 nDispatchSizeY = 16; - -#ifdef CINEBOX_APP - pDeviceCtx->Dispatch(nDispatchSizeX, nDispatchSizeY, 1); -#else - rd->m_DevMan.Dispatch(nDispatchSizeX, nDispatchSizeY, 1); -#endif - - SD3DPostEffectsUtils::ShEndPass(); - } - - D3DUnorderedAccessView* pUAVNULL = NULL; - - pDeviceCtx->CSSetUnorderedAccessViews(7, 1, &pUAVNULL, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(6, 1, &pUAVNULL, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(5, 1, &pUAVNULL, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(2, 1, &pUAVNULL, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(1, 1, &pUAVNULL, &UAVInitialCounts); - pDeviceCtx->CSSetUnorderedAccessViews(0, 1, &pUAVNULL, &UAVInitialCounts); - - CTexture::GetByID(vp_RGB0.nTexId)->Unbind(); - CTexture::GetByID(vp_RGB1.nTexId)->Unbind(); - CTexture::GetByID(vp_DYNL.nTexId)->Unbind(); - CTexture::GetByID(vp_RGB2.nTexId)->Unbind(); - CTexture::GetByID(vp_RGB3.nTexId)->Unbind(); - CTexture::GetByID(vp_NORM.nTexId)->Unbind(); - CTexture::GetByID(vp_ALDI.nTexId)->Unbind(); - CTexture::GetByID(vp_OPAC.nTexId)->Unbind(); - - gcpRendD3D->GetTiledShading().UnbindForwardShadingResources(eHWSC_Compute); - - pSH->FXEnd(); - -} - -CTexture* CSvoRenderer::GetGBuffer(int nId) // simplify branch compatibility -{ - CTexture* pRes; - - if (nId == 0) - { - pRes = CTexture::s_ptexSceneDiffuse; - } - else if (nId == 1) - { - pRes = CTexture::s_ptexSceneNormalsMap; - } - else if (nId == 2) - { - pRes = CTexture::s_ptexSceneSpecular; - } - else - { - pRes = 0; - } - - return pRes; -} - -void CSvoRenderer::ConeTracePass(SSvoTargetsSet* pTS) -{ - CheckAllocateRT(pTS == &m_tsSpec); - - if (!IsActive() || !m_pShader) - { - return; - } - - const char* szTechFinalName = "ConeTracePass"; - - if (m_texInfo.bSvoFreeze) - { - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->FX_PushRenderTarget(0, pTS->pRT_ALD_0, NULL); - rd->FX_PushRenderTarget(1, pTS->pRT_RGB_0, NULL); - - if (m_texInfo.pTexTree) - { - SetShaderFlags(pTS == &m_tsDiff); - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES /*| FEF_DONTSETSTATES*/); - - { - Matrix44A matView; - matView = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix(); - Vec3 zAxis = matView.GetRow(1); - matView.SetRow(1, -matView.GetRow(2)); - matView.SetRow(2, zAxis); - float z = matView.m13; - matView.m13 = -matView.m23; - matView.m23 = z; - - SetupRsmSun(eHWSC_Pixel); - - static int nReprojFrameId = -1; - if ((pTS == &m_tsDiff) && nReprojFrameId != rd->GetFrameID(false)) - { - nReprojFrameId = rd->GetFrameID(false); - - Matrix44A matProj; - const CCamera& cam = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_cam; - mathMatrixPerspectiveFov(&matProj, cam.GetFov(), cam.GetProjRatio(), cam.GetNearPlane(), cam.GetFarPlane()); - static Matrix44A matPrevView = matView; - static Matrix44A matPrevProj = matProj; - rd->GetReprojectionMatrix(m_matReproj, matView, matProj, matPrevView, matPrevProj, cam.GetFarPlane()); - matPrevView = matView; - matPrevProj = matProj; - } - - { - static CCryNameR parameterName5("SVO_ReprojectionMatrix"); - m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3); - } - - { - static CCryNameR parameterName6("SVO_FrameIdByte"); - Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4); - if (rd->GetActiveGPUCount() > 1) - { - ttt.x = 0; - } - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - static CCryNameR parameterName6("SVO_CamPos"); - Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - Matrix44A mViewProj; - mViewProj = gcpRendD3D->m_ViewProjMatrix; - mViewProj.Transpose(); - - static CCryNameR paramName("g_mViewProj"); - m_pShader->FXSetPSFloat(paramName, alias_cast(&mViewProj), 4); - - static CCryNameR paramNamePrev("g_mViewProjPrev"); - m_pShader->FXSetPSFloat(paramNamePrev, alias_cast(&m_matViewProjPrev), 4); - } - - { - float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width); - float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height); - static CCryNameR parameterName6("SVO_TargetResScale"); - static int nPrevWidth = 0; - Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(), - (float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1))); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1); - } - - { - Matrix44A matView2; - matView2 = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix(); - Vec3 zAxis2 = matView2.GetRow(1); - matView2.SetRow(1, -matView2.GetRow(2)); - matView2.SetRow(2, zAxis2); - float z2 = matView2.m13; - matView2.m13 = -matView2.m23; - matView2.m23 = z2; - static CCryNameR paramName2("TI_CameraMatrix"); - m_pShader->FXSetPSFloat(paramName2, (Vec4*)matView2.GetData(), 3); - } - - { - Vec3 pvViewFrust[8]; - const CameraViewParameters& rc = gcpRendD3D->GetViewParameters(); - rc.CalcVerts(pvViewFrust); - - static CCryNameR parameterName0("SVO_FrustumVerticesCam0"); - static CCryNameR parameterName1("SVO_FrustumVerticesCam1"); - static CCryNameR parameterName2("SVO_FrustumVerticesCam2"); - static CCryNameR parameterName3("SVO_FrustumVerticesCam3"); - Vec4 ttt0(pvViewFrust[4] - rc.vOrigin, 0); - Vec4 ttt1(pvViewFrust[5] - rc.vOrigin, 0); - Vec4 ttt2(pvViewFrust[6] - rc.vOrigin, 0); - Vec4 ttt3(pvViewFrust[7] - rc.vOrigin, 0); - m_pShader->FXSetPSFloat(parameterName0, (Vec4*)&ttt0, 1); - m_pShader->FXSetPSFloat(parameterName1, (Vec4*)&ttt1, 1); - m_pShader->FXSetPSFloat(parameterName2, (Vec4*)&ttt2, 1); - m_pShader->FXSetPSFloat(parameterName3, (Vec4*)&ttt3, 1); - } - - - if (pTS->pRT_ALD_1 && pTS->pRT_ALD_1) - { - static int nPrevWidth = 0; - if (nPrevWidth != (pTS->pRT_ALD_1->GetWidth())) - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(10, m_nTexStateLinear); - CTextureManager::Instance()->GetWhiteTexture()->Apply(11, m_nTexStateLinear); - nPrevWidth = pTS->pRT_ALD_1->GetWidth(); - } - else - { - pTS->pRT_ALD_1->Apply(10, m_nTexStateLinear); - pTS->pRT_RGB_1->Apply(11, m_nTexStateLinear); - } - } - } - - rd->FX_SetState(GS_NODEPTHTEST); - - SetupSvoTexturesForRead(m_texInfo, eHWSC_Pixel, (gEnv->pConsole->GetCVar("e_svoTI_Active")->GetIVal() ? gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal() : 0), 0, 0); - - CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint); - - { - GetGBuffer(1)->Apply(5, m_nTexStatePoint); - - GetGBuffer(2)->Apply(7, m_nTexStatePoint); - - GetGBuffer(0)->Apply(14, m_nTexStatePoint); - } - - if (!GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && m_arrLightsDynamic.Count()) - { - BindTiledLights(m_arrLightsDynamic, eHWSC_Pixel); - SetupLightSources(m_arrLightsDynamic, m_pShader, true); - } - - { - const bool setupCloudShadows = rd->m_bShadowsEnabled && rd->m_bCloudShadowsEnabled; - if (setupCloudShadows) - { - // cloud shadow map - CTexture* pCloudShadowTex(rd->GetCloudShadowTextureId() > 0 ? CTexture::GetByID(rd->GetCloudShadowTextureId()) : CTextureManager::Instance()->GetWhiteTexture()); - assert(pCloudShadowTex); - - STexState pTexStateLinearClamp; - pTexStateLinearClamp.SetFilterMode(FILTER_LINEAR); - pTexStateLinearClamp.SetClampMode(false, false, false); - CTexture::GetTexState(pTexStateLinearClamp); - - pCloudShadowTex->Apply(15, m_nTexStateLinearWrap); - } - else - { - CTextureManager::Instance()->GetWhiteTexture()->Apply(15, m_nTexStateLinearWrap); - } - } - - rd->FX_Commit(); - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight()); - - gcpRendD3D->GetTiledShading().UnbindForwardShadingResources(eHWSC_Pixel); - - SD3DPostEffectsUtils::ShEndPass(); - } - - rd->FX_PopRenderTarget(0); - rd->FX_PopRenderTarget(1); -} - -void CSvoRenderer::DrawPonts(PodArray& arrVerts) -{ - SPostEffectsUtils::UpdateFrustumCorners(); - - CVertexBuffer strip(arrVerts.GetElements(), eVF_P3F_C4B_T2F); - - gRenDev->DrawPrimitivesInternal(&strip, arrVerts.Count(), eptPointList); -} - -void CSvoRenderer::UpdateRender() -{ - int nPrevAsync = CRenderer::CV_r_shadersasynccompiling; - if (gEnv->IsEditor()) - { - CRenderer::CV_r_shadersasynccompiling = 0; - } - - { - PROFILE_LABEL_SCOPE("TI_GEN_DIFF"); - - ConeTracePass(&m_tsDiff); - } - if (GetIntegratioMode() == 2) - { - PROFILE_LABEL_SCOPE("TI_GEN_SPEC"); - - ConeTracePass(&m_tsSpec); - } - - { - PROFILE_LABEL_SCOPE("TI_DEMOSAIC_DIFF"); - - DemosaicPass(&m_tsDiff); - } - if (GetIntegratioMode() == 2) - { - PROFILE_LABEL_SCOPE("TI_DEMOSAIC_SPEC"); - - DemosaicPass(&m_tsSpec); - } - - { - PROFILE_LABEL_SCOPE("TI_UPSCALE_DIFF"); - - UpScalePass(&m_tsDiff); - } - if (GetIntegratioMode() == 2) - { - PROFILE_LABEL_SCOPE("TI_UPSCALE_SPEC"); - - UpScalePass(&m_tsSpec); - } - - { - m_matViewProjPrev = gcpRendD3D->m_ViewProjMatrix; - m_matViewProjPrev.Transpose(); - } - - if (gEnv->IsEditor()) - { - CRenderer::CV_r_shadersasynccompiling = nPrevAsync; - } -} - -void CSvoRenderer::DemosaicPass(SSvoTargetsSet* pTS) -{ - const char* szTechFinalName = "DemosaicPass"; - - if (!IsActive() || !m_pShader) - { - return; - } - - if (m_texInfo.bSvoFreeze) - { - return; - } - - { // SVO - if (!pTS->pRT_ALD_0 || !pTS->pRT_ALD_0) - { - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->FX_PushRenderTarget(0, pTS->pRT_RGB_DEM_MIN_0, NULL, -1, false, 1); - rd->FX_PushRenderTarget(1, pTS->pRT_ALD_DEM_MIN_0, NULL, -1, false, 1); - rd->FX_PushRenderTarget(2, pTS->pRT_RGB_DEM_MAX_0, NULL, -1, false, 1); - rd->FX_PushRenderTarget(3, pTS->pRT_ALD_DEM_MAX_0, NULL, -1, false, 1); - - if (m_texInfo.pTexTree) - { - SetShaderFlags(pTS == &m_tsDiff); - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES); - - rd->FX_SetState(GS_NODEPTHTEST); - - CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint); - - GetGBuffer(1)->Apply(5, m_nTexStatePoint); - - GetGBuffer(2)->Apply(7, m_nTexStatePoint); - - GetGBuffer(0)->Apply(14, m_nTexStatePoint); - - { - static CCryNameR parameterName5("SVO_ReprojectionMatrix"); - m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3); - } - - { - float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width); - float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height); - static CCryNameR parameterName6("SVO_TargetResScale"); - static int nPrevWidth = 0; - Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(), - (float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1))); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1); - } - - { - static CCryNameR parameterName6("SVO_FrameIdByte"); - Vec4 ttt((float)(rd->GetFrameID(false) & 255), (float)rd->GetFrameID(false), 3, 4); - if (rd->GetActiveGPUCount() > 1) - { - ttt.x = 0; - } - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - static CCryNameR parameterName6("SVO_CamPos"); - Vec4 ttt(gEnv->pSystem->GetViewCamera().GetPosition(), 0); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - Matrix44A mViewProj; - mViewProj = gcpRendD3D->m_ViewProjMatrix; - mViewProj.Transpose(); - - static CCryNameR paramName("g_mViewProj"); - m_pShader->FXSetPSFloat(paramName, alias_cast(&mViewProj), 4); - - static CCryNameR paramNamePrev("g_mViewProjPrev"); - m_pShader->FXSetPSFloat(paramNamePrev, alias_cast(&m_matViewProjPrev), 4); - } - - { - Matrix44A matView; - matView = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_cam.GetViewMatrix(); - Vec3 zAxis = matView.GetRow(1); - matView.SetRow(1, -matView.GetRow(2)); - matView.SetRow(2, zAxis); - float z = matView.m13; - matView.m13 = -matView.m23; - matView.m23 = z; - static CCryNameR paramName2("TI_CameraMatrix"); - m_pShader->FXSetPSFloat(paramName2, (Vec4*)matView.GetData(), 3); - } - - pTS->pRT_ALD_0->Apply(10, m_nTexStateLinear); - pTS->pRT_RGB_0->Apply(11, m_nTexStateLinear); - - pTS->pRT_RGB_DEM_MIN_1->Apply(0, m_nTexStateLinear); - pTS->pRT_ALD_DEM_MIN_1->Apply(1, m_nTexStateLinear); - pTS->pRT_RGB_DEM_MAX_1->Apply(2, m_nTexStateLinear); - pTS->pRT_ALD_DEM_MAX_1->Apply(3, m_nTexStateLinear); - - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight()); - - SD3DPostEffectsUtils::ShEndPass(); - } - - rd->FX_PopRenderTarget(0); - rd->FX_PopRenderTarget(1); - rd->FX_PopRenderTarget(2); - rd->FX_PopRenderTarget(3); - } -} - -void CSvoRenderer::SetupLightSources(PodArray& lightsTI, CShader* pShader, bool bPS) -{ - const int nLightGroupsNum = 2; - - static CCryNameR paramNamesLightPos[nLightGroupsNum] = - { - CCryNameR("SVO_LightPos0"), - CCryNameR("SVO_LightPos1"), - }; - static CCryNameR paramNamesLightDir[nLightGroupsNum] = - { - CCryNameR("SVO_LightDir0"), - CCryNameR("SVO_LightDir1"), - }; - static CCryNameR paramNamesLightCol[nLightGroupsNum] = - { - CCryNameR("SVO_LightCol0"), - CCryNameR("SVO_LightCol1"), - }; - - for (int g = 0; g < nLightGroupsNum; g++) - { - Vec4 LightPos[4]; - Vec4 LightDir[4]; - Vec4 LightCol[4]; - - for (int x = 0; x < 4; x++) - { - int nId = g * 4 + x; - - LightPos[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vPosR : Vec4(0, 0, 0, 0); - LightDir[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vDirF : Vec4(0, 0, 0, 0); - LightCol[x] = (nId < lightsTI.Count()) ? lightsTI[nId].vCol : Vec4(0, 0, 0, 0); - } - - if (bPS) - { - pShader->FXSetPSFloat(paramNamesLightPos[g], alias_cast(&LightPos[0][0]), 4); - pShader->FXSetPSFloat(paramNamesLightDir[g], alias_cast(&LightDir[0][0]), 4); - pShader->FXSetPSFloat(paramNamesLightCol[g], alias_cast(&LightCol[0][0]), 4); - } - else - { // CS - pShader->FXSetCSFloat(paramNamesLightPos[g], alias_cast(&LightPos[0][0]), 4); - pShader->FXSetCSFloat(paramNamesLightDir[g], alias_cast(&LightDir[0][0]), 4); - pShader->FXSetCSFloat(paramNamesLightCol[g], alias_cast(&LightCol[0][0]), 4); - } - } -} - -void CSvoRenderer::SetupNodesForUpdate(int& nNodesForUpdateStartIndex, PodArray& arrNodesForUpdate) -{ - static CCryNameR paramNames[SVO_MAX_NODE_GROUPS] = - { - CCryNameR("SVO_NodesForUpdate0"), - CCryNameR("SVO_NodesForUpdate1"), - CCryNameR("SVO_NodesForUpdate2"), - CCryNameR("SVO_NodesForUpdate3"), - }; - - for (int g = 0; g < SVO_MAX_NODE_GROUPS; g++) - { - float matVal[4][4]; - - for (int x = 0; x < 4; x++) - { - for (int y = 0; y < 4; y++) - { - int nId = nNodesForUpdateStartIndex + g * 16 + x * 4 + y; - matVal[x][y] = 0.1f + ((nId < arrNodesForUpdate.Count()) ? arrNodesForUpdate[nId].nAtlasOffset : -2); - } - } - - m_pShader->FXSetCSFloat(paramNames[g], alias_cast(&matVal[0][0]), 4); - } - - nNodesForUpdateStartIndex += 4 * 4 * SVO_MAX_NODE_GROUPS; // 128 -} - -void CSvoRenderer::SetupSvoTexturesForRead(I3DEngine::SSvoStaticTexInfo& texInfo, EHWShaderClass eShaderClass, int nStage, int nStageOpa, int nStageNorm) -{ - ((CTexture*)texInfo.pTexTree)->Apply(0, m_nTexStatePoint, -1, -1, -1, eShaderClass); - - CTextureManager::Instance()->GetBlackTexture()->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass); - - - if (nStage == 0) - { - CTexture::GetByID(vp_RGB0.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - else if (nStage == 1) - { - CTexture::GetByID(vp_RGB1.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - else if (nStage == 2) - { - CTexture::GetByID(vp_RGB2.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - else if (nStage == 3) - { - CTexture::GetByID(vp_RGB3.nTexId)->Apply(1, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - - if (nStageNorm == 0) - { - CTexture::GetByID(vp_NORM.nTexId)->Apply(2, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - - - if (nStageOpa == 0) - { - ((CTexture*)texInfo.pTexOpac)->Apply(3, m_nTexStateLinear, -1, -1, -1, eShaderClass); - } - - - if (texInfo.pGlobalSpecCM) - { - ((CTexture*)texInfo.pGlobalSpecCM)->Apply(6, m_nTexStateTrilinear, -1, -1, -1, eShaderClass); - } - -} - -void CSvoRenderer::CheckAllocateRT(bool bSpecPass) -{ - int nWidth = gcpRendD3D->GetWidth(); - int nHeight = gcpRendD3D->GetHeight(); - - int nResScaleBase = 2; - int nInW = (nWidth / nResScaleBase); - int nInH = (nHeight / nResScaleBase); - - if (!bSpecPass) - { - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_ALD"); - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_ALD"); - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_RGB"); - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_RGB"); - - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_ALD"); - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_ALD"); - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_RGB"); - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_RGB"); - - - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_RGB_MIN"); - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_ALD_MIN"); - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_RGB_MAX"); - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_DIFF_FIN_ALD_MAX"); - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_RGB_MIN"); - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_ALD_MIN"); - CheckCreateUpdateRT(m_tsDiff.pRT_RGB_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_RGB_MAX"); - CheckCreateUpdateRT(m_tsDiff.pRT_ALD_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_DIFF_FIN_ALD_MAX"); - - CheckCreateUpdateRT(m_tsDiff.pRT_FIN_OUT_0, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_FIN_DIFF_OUT"); - CheckCreateUpdateRT(m_tsDiff.pRT_FIN_OUT_1, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_FIN_DIFF_OUT"); - - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_RGB_MIN"); - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MIN_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_ALD_MIN"); - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_RGB_MAX"); - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MAX_0, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_SPEC_FIN_ALD_MAX"); - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_RGB_MIN"); - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MIN_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_ALD_MIN"); - CheckCreateUpdateRT(m_tsSpec.pRT_RGB_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_RGB_MAX"); - CheckCreateUpdateRT(m_tsSpec.pRT_ALD_DEM_MAX_1, nInW, nInH, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_SPEC_FIN_ALD_MAX"); - - CheckCreateUpdateRT(m_tsSpec.pRT_FIN_OUT_0, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SVO_FIN_SPEC_OUT"); - CheckCreateUpdateRT(m_tsSpec.pRT_FIN_OUT_1, nWidth, nHeight, eTF_R16G16B16A16F, eTT_2D, FT_STATE_CLAMP, "SV1_FIN_SPEC_OUT"); - - // swap ping-pong RT - std::swap(m_tsDiff.pRT_ALD_0, m_tsDiff.pRT_ALD_1); - std::swap(m_tsDiff.pRT_RGB_0, m_tsDiff.pRT_RGB_1); - std::swap(m_tsDiff.pRT_RGB_DEM_MIN_0, m_tsDiff.pRT_RGB_DEM_MIN_1); - std::swap(m_tsDiff.pRT_ALD_DEM_MIN_0, m_tsDiff.pRT_ALD_DEM_MIN_1); - std::swap(m_tsDiff.pRT_RGB_DEM_MAX_0, m_tsDiff.pRT_RGB_DEM_MAX_1); - std::swap(m_tsDiff.pRT_ALD_DEM_MAX_0, m_tsDiff.pRT_ALD_DEM_MAX_1); - std::swap(m_tsDiff.pRT_FIN_OUT_0, m_tsDiff.pRT_FIN_OUT_1); - - std::swap(m_tsSpec.pRT_ALD_0, m_tsSpec.pRT_ALD_1); - std::swap(m_tsSpec.pRT_RGB_0, m_tsSpec.pRT_RGB_1); - std::swap(m_tsSpec.pRT_RGB_DEM_MIN_0, m_tsSpec.pRT_RGB_DEM_MIN_1); - std::swap(m_tsSpec.pRT_ALD_DEM_MIN_0, m_tsSpec.pRT_ALD_DEM_MIN_1); - std::swap(m_tsSpec.pRT_RGB_DEM_MAX_0, m_tsSpec.pRT_RGB_DEM_MAX_1); - std::swap(m_tsSpec.pRT_ALD_DEM_MAX_0, m_tsSpec.pRT_ALD_DEM_MAX_1); - std::swap(m_tsSpec.pRT_FIN_OUT_0, m_tsSpec.pRT_FIN_OUT_1); - } -} - -bool CSvoRenderer::IsShaderItemUsedForVoxelization(SShaderItem& rShaderItem, [[maybe_unused]] IRenderNode* pRN) -{ - CShader* pS = (CShader*)rShaderItem.m_pShader; - - // skip some objects marked by level designer - // if(pRN && pRN->IsRenderNode() && pRN->GetIntegrationType()) - // return false; - - // skip transparent meshes except decals - // if((pR->Opacity() != 1.f) && !(pS->GetFlags()&EF_DECAL)) - // return false; - - // skip windows - if (pS && pS->GetShaderType() == eST_Glass) - { - return false; - } - - // skip water - if (pS && pS->GetShaderType() == eST_Water) - { - return false; - } - - return true; -} - -namespace -{ - const float ACTIVATION_MODE_DISABLED = -1.0f; - - float GetActivationModeAsFloat() - { - auto* instance = CSvoRenderer::GetInstance(); - - float modeAsFloat = ACTIVATION_MODE_DISABLED; - int32 modeAsInt = instance->GetIntegratioMode(); - - if (instance->IsActive()) - { - if (modeAsInt == 0 && gEnv->pConsole->GetCVar("e_svoTI_UseLightProbes")->GetIVal()) - { // AO modulates diffuse and specular - modeAsFloat = 0.0f; - } - else if (modeAsInt <= 1) - { // GI replaces diffuse and modulates specular - modeAsFloat = 1.0f; - } - else if (modeAsInt == 2) - { // GI replaces diffuse and specular - modeAsFloat = 2.0f; - } - } - - return modeAsFloat; - } -} - -void CSvoRenderer::UpdatePassConstantBuffer() -{ - CSvoRenderer* svoRenderer = CSvoRenderer::GetInstance(); - - CTypedConstantBuffer cb(m_PassConstantBuffer); - - // SvoParams4 is used by forward tiled shaders even if GI is disabled, it contains info about GI mode and also is GI active or not - cb->PerPass_SvoParams4 = Vec4(0.0f, -1.0f, 0.0f, 0.0f); - - if (svoRenderer) - { - AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); - AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); - const float terrainSizeX = terrainAabb.GetXExtent(); - - cb->PerPass_SvoTreeSettings0 = Vec4( - (float)terrainSizeX, - gEnv->pConsole->GetCVar("e_svoMinNodeSize")->GetFVal(), - (float)svoRenderer->m_texInfo.nBrickSize, - 128.f); - - cb->PerPass_SvoTreeSettings1 = Vec4( - gEnv->pConsole->GetCVar("e_svoMaxNodeSize")->GetFVal(), - 0.0f, - 0.0f, - 0.0f); - cb->PerPass_SvoParams0 = Vec4( - 1.0f, - 0.0f, - 0.0f, - 0.0f); - - cb->PerPass_SvoParams1 = Vec4( - 1.f / (gEnv->pConsole->GetCVar("e_svoTI_DiffuseConeWidth")->GetFVal() + 0.00001f), - gEnv->pConsole->GetCVar("e_svoTI_ConeMaxLength")->GetFVal(), - 0.0f, - (svoRenderer->m_texInfo.bSvoReady && gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal()) ? 1.0f : 0.0f); - - cb->PerPass_SvoParams2 = Vec4( - gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal(), - 0.0f, - gEnv->pConsole->GetCVar("e_svoTI_Saturation")->GetFVal(), - 0.0f); - - cb->PerPass_SvoParams3 = Vec4( - 1.0f, - 0.0f, - 0.0f, - (svoRenderer->m_texInfo.bSvoReady && gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetIVal()) ? 1.0f : 0.0f); - - - { - cb->PerPass_SvoParams4.x = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetRed")->GetFVal(); - cb->PerPass_SvoParams4.y = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetGreen")->GetFVal(); - cb->PerPass_SvoParams4.z = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBlue")->GetFVal(); - cb->PerPass_SvoParams4.w = gEnv->pConsole->GetCVar("e_svoTI_AmbientOffsetBias")->GetFVal(); - } - - cb->PerPass_SvoParams5 = Vec4( - 0.0f, - 0.0f, - gEnv->pConsole->GetCVar("e_svoTI_NumberOfBounces")->GetFVal() - 1.f, - svoRenderer->m_texInfo.fGlobalSpecCM_Mult); - - cb->PerPass_SvoParams6 = Vec4( - 1.0f, - gEnv->IsEditing() ? 0 : (gEnv->pConsole->GetCVar("e_svoTemporalFilteringMinDistance")->GetFVal() / gcpRendD3D->GetViewParameters().fFar), - 0.0f, - 0.0f); - } - - m_PassConstantBuffer = cb.GetDeviceConstantBuffer(); - cb.CopyToDevice(); - - auto& devManager = gcpRendD3D->m_DevMan; - devManager.BindConstantBuffer(eHWSC_Compute, m_PassConstantBuffer.get(), eConstantBufferShaderSlot_PerPass); - devManager.BindConstantBuffer(eHWSC_Pixel, m_PassConstantBuffer.get(), eConstantBufferShaderSlot_PerPass); -} - -Vec4 CSvoRenderer::GetDisabledPerFrameShaderParameters() -{ - Vec4 params; - params.x = 0.0f; - params.y = ACTIVATION_MODE_DISABLED; - params.z = 0.0f; - params.z = 0.0f; - return params; -} - -Vec4 CSvoRenderer::GetPerFrameShaderParameters() const -{ - Vec4 params; - params.x = 1.f; - params.y = GetActivationModeAsFloat(); - params.z = 0.0f; - params.w = 0.0f; - return params; -} - -void CSvoRenderer::DebugDrawStats(const RPProfilerStats* pBasicStats, float& ypos, const float ystep, float xposms) -{ - ColorF color = Col_Yellow; - const EDrawTextFlags txtFlags = (EDrawTextFlags)(eDrawText_2D | eDrawText_800x600 | eDrawText_FixedSize | eDrawText_Monospace); - -#define SVO_Draw2dLabel(labelName) \ - gRenDev->Draw2dLabel(60, ypos += ystep, 2, &color.r, false, (const char*)(((const char*)(#labelName)) + 10)); \ - if (pBasicStats[labelName].gpuTimeMax > 0.01) { \ - gRenDev->Draw2dLabelEx(xposms, ypos, 2, color, txtFlags, "%5.2f Aver=%5.2f Max=%5.2f", \ - pBasicStats[labelName].gpuTime, pBasicStats[labelName].gpuTimeSmoothed, pBasicStats[labelName].gpuTimeMax); } \ - else{ \ - gRenDev->Draw2dLabelEx(xposms, ypos, 2, color, txtFlags, "%5.2f", pBasicStats[labelName].gpuTime); } \ - - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_CLEAR); - SVO_Draw2dLabel(eRPPSTATS_TI_VOXELIZE); - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_AIR); - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_LIGHT); - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_REFL0); - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_REFL1); - SVO_Draw2dLabel(eRPPSTATS_TI_INJECT_DYNL); - SVO_Draw2dLabel(eRPPSTATS_TI_NID_DIFF); - SVO_Draw2dLabel(eRPPSTATS_TI_GEN_DIFF); - SVO_Draw2dLabel(eRPPSTATS_TI_GEN_SPEC); - SVO_Draw2dLabel(eRPPSTATS_TI_GEN_AIR); - SVO_Draw2dLabel(eRPPSTATS_TI_DEMOSAIC_DIFF); - SVO_Draw2dLabel(eRPPSTATS_TI_DEMOSAIC_SPEC); - SVO_Draw2dLabel(eRPPSTATS_TI_UPSCALE_DIFF); - SVO_Draw2dLabel(eRPPSTATS_TI_UPSCALE_SPEC); -} - -void CSvoRenderer::SetShaderFlags(bool bDiffuseMode, bool bPixelShader) -{ - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE0]; - } - - if (m_texInfo.pGlobalSpecCM && GetIntegratioMode()) // use global env CM - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE1]; - } - else - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE1]; - - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE2]; - } - - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE3]; - } - - if (bDiffuseMode) // diffuse or specular rendering - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - else - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE4]; - } - - if (GetIntegratioMode()) // ignore colors and normals for AO only mode - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - else - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_SAMPLE5]; - } - - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_HW_PCF_COMPARE]; - } - - if (bPixelShader && !GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()) // read sun light and shadow map during final cone tracing - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ]; - } - else - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_LIGHT_TEX_PROJ]; - } - - if (bPixelShader && !GetIntegratioMode() && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && m_arrLightsDynamic.Count()) // read sun light and shadow map during final cone tracing - { - gRenDev->m_RP.m_FlagsShader_RT |= g_HWSR_MaskBit[HWSR_POINT_LIGHT]; - } - else - { - gRenDev->m_RP.m_FlagsShader_RT &= ~g_HWSR_MaskBit[HWSR_POINT_LIGHT]; - } -} - -int CSvoRenderer::GetIntegratioMode() -{ - return gEnv->pConsole->GetCVar("e_svoTI_IntegrationMode")->GetIVal(); -} - -bool CSvoRenderer::IsActive() -{ - static ICVar* e_GI = gEnv->pConsole->GetCVar("e_GI"); - static ICVar* e_svoTI_Active = gEnv->pConsole->GetCVar("e_svoTi_Active"); - - //Unable to find cvars, clearly can't be active. - if (!e_GI || !e_svoTI_Active) - { - return false; - } - - return e_GI->GetIVal() && CSvoRenderer::s_pInstance && e_svoTI_Active->GetIVal(); -} - -bool CSvoRenderer::SetSamplers(int nCustomID, EHWShaderClass eSHClass, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit) -{ - CSvoRenderer* pSR = CSvoRenderer::GetInstance(); - - if (!pSR) - { - return false; - } - - switch (nCustomID) - { - case TO_SVOTREE: - case TO_SVOTRIS: - case TO_SVOGLCM: - case TO_SVORGBS: - case TO_SVONORM: - case TO_SVOOPAC: - { - CTexture* pTex = CTextureManager::Instance()->GetBlackTexture(); - - if (pSR->m_texInfo.pTexTree) - { - if (nCustomID == TO_SVOTREE) - { - nCustomID = pSR->m_texInfo.pTexTree->GetTextureID(); - } - if (nCustomID == TO_SVORGBS) - { - if (pSR->m_texInfo.pTexRgb0) - { - nCustomID = pSR->m_texInfo.pTexRgb0->GetTextureID(); - } - } - if (nCustomID == TO_SVONORM) - { - nCustomID = pSR->m_texInfo.pTexNorm->GetTextureID(); - } - if (nCustomID == TO_SVOOPAC) - { - nCustomID = pSR->m_texInfo.pTexOpac->GetTextureID(); - } - - if (nCustomID > 0) - { - pTex = CTexture::GetByID(nCustomID); - } - } - - pTex->Apply(nTUnit, nTState, nTexMaterialSlot, nSUnit, -1, eSHClass); - - return true; - } - } - - return false; -} - -CTexture* CSvoRenderer::GetDiffuseFinRT() -{ - return m_tsDiff.pRT_FIN_OUT_0; -} - -CTexture* CSvoRenderer::GetSpecularFinRT() -{ - return m_tsSpec.pRT_FIN_OUT_0; -} - -void CSvoRenderer::UpScalePass(SSvoTargetsSet* pTS) -{ - - const char* szTechFinalName = "UpScalePass"; - - if (!IsActive() || !m_pShader) - { - return; - } - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - rd->FX_PushRenderTarget(0, pTS->pRT_FIN_OUT_0, NULL, -1, false, 1); - - SetShaderFlags(pTS == &m_tsDiff); - - SD3DPostEffectsUtils::ShBeginPass(m_pShader, szTechFinalName, FEF_DONTSETTEXTURES); - - if (!gRenDev->m_RP.m_pShader) - { - gEnv->pLog->LogWarning("Error: %s: Technique not found: %s", __FUNC__, szTechFinalName); - rd->FX_PopRenderTarget(0); - return; - } - - CTexture::s_ptexZTarget->Apply(4, m_nTexStatePoint); - GetGBuffer(1)->Apply(5, m_nTexStatePoint); - GetGBuffer(2)->Apply(7, m_nTexStatePoint); - GetGBuffer(0)->Apply(14, m_nTexStatePoint); - - pTS->pRT_ALD_DEM_MIN_0->Apply(10, m_nTexStatePoint); - pTS->pRT_RGB_DEM_MIN_0->Apply(11, m_nTexStatePoint); - pTS->pRT_ALD_DEM_MAX_0->Apply(12, m_nTexStatePoint); - pTS->pRT_RGB_DEM_MAX_0->Apply(13, m_nTexStatePoint); - - pTS->pRT_FIN_OUT_1->Apply(9, m_nTexStatePoint); - - if (pTS == &m_tsSpec && m_tsDiff.pRT_FIN_OUT_0) - { - m_tsDiff.pRT_FIN_OUT_0->Apply(15, m_nTexStatePoint); - } - else - { - CTextureManager::Instance()->GetBlackTexture()->Apply(15, m_nTexStatePoint); - } - - { - static CCryNameR parameterName6("SVO_SrcPixSize"); - Vec4 ttt(0, 0, 0, 0); - ttt.x = 1.f / float(pTS->pRT_ALD_DEM_MIN_0->GetWidth()); - ttt.y = 1.f / float(pTS->pRT_ALD_DEM_MIN_0->GetHeight()); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - } - - { - static CCryNameR parameterName5("SVO_ReprojectionMatrix"); - m_pShader->FXSetPSFloat(parameterName5, (Vec4*)m_matReproj.GetData(), 3); - } - - { - float fSizeRatioW = float(rd->GetWidth() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Width); - float fSizeRatioH = float(rd->GetHeight() / rd->m_RTStack[0][rd->m_nRTStackLevel[0]].m_Height); - static CCryNameR parameterName6("SVO_TargetResScale"); - static int nPrevWidth = 0; - Vec4 ttt(fSizeRatioW, fSizeRatioH, gEnv->pConsole->GetCVar("e_svoTemporalFilteringBase")->GetFVal(), - (float)(nPrevWidth != (pTS->pRT_ALD_0->GetWidth() + 1) || (rd->m_RP.m_nRendFlags & SHDF_CUBEMAPGEN) || (rd->GetActiveGPUCount() > 1))); - m_pShader->FXSetPSFloat(parameterName6, (Vec4*)&ttt, 1); - nPrevWidth = (pTS->pRT_ALD_0->GetWidth() + 1); - } - - { - Matrix44A mViewProj; - mViewProj = gcpRendD3D->m_ViewProjMatrix; - mViewProj.Transpose(); - - static CCryNameR paramName("g_mViewProj"); - m_pShader->FXSetPSFloat(paramName, alias_cast(&mViewProj), 4); - - static CCryNameR paramNamePrev("g_mViewProjPrev"); - m_pShader->FXSetPSFloat(paramNamePrev, alias_cast(&m_matViewProjPrev), 4); - } - - SD3DPostEffectsUtils::DrawFullScreenTriWPOS(CTexture::s_ptexCurrentSceneDiffuseAccMap->GetWidth(), CTexture::s_ptexCurrentSceneDiffuseAccMap->GetHeight()); - - SD3DPostEffectsUtils::ShEndPass(); - - rd->FX_PopRenderTarget(0); -} - -void CSvoRenderer::SetupRsmSun(const EHWShaderClass eShClass) -{ - - CD3D9Renderer* const __restrict rd = gcpRendD3D; - - int nLightID = 0; - - threadID m_nThreadID = gcpRendD3D->m_RP.m_nProcessThreadID; - int m_nRecurseLevel = SRendItem::m_RecurseLevel[m_nThreadID]; - - int nFrustumIdx = nLightID;// + nDLights; - - int nStartIdx = SRendItem::m_StartFrust[m_nThreadID][nFrustumIdx]; - int nEndIdx = SRendItem::m_EndFrust[m_nThreadID][nFrustumIdx]; - - static CCryNameR lightProjParamName("SVO_RsmSunShadowProj"); - static CCryNameR rsmSunColParameterName("SVO_RsmSunCol"); - static CCryNameR rsmSunDirParameterName("SVO_RsmSunDir"); - Matrix44A shadowMat; - shadowMat.SetIdentity(); - - int nFrIdx = 0; - for (nFrIdx = nStartIdx; nFrIdx < nEndIdx; nFrIdx++) - { - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx]; - if (firstFrustum.nShadowMapLod == 2) - { - break; - } - } - - if ((nEndIdx > nFrIdx) && GetRsmColorMap(rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx])) - { - ShadowMapFrustum& firstFrustum = rd->m_RP.m_SMFrustums[m_nThreadID][m_nRecurseLevel][nFrIdx]; - rd->ConfigShadowTexgen(0, &firstFrustum, 0); - - if (firstFrustum.bUseShadowsPool) - { - STexState TS; - TS.SetFilterMode(FILTER_POINT); - TS.SetClampMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP); - TS.m_bSRGBLookup = false; - CTexture::s_ptexRT_ShadowPool->Apply(12, CTexture::GetTexState(TS), EFTT_UNKNOWN, -1, -1, eShClass); - } - else - { - firstFrustum.pDepthTex->Apply(12, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - GetRsmColorMap(firstFrustum)->Apply(13, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - GetRsmNormlMap(firstFrustum)->Apply(9, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - } - - // set up shadow matrix - shadowMat = gRenDev->m_TempMatrices[0][0]; - const Vec4 vEye(gRenDev->GetViewParameters().vOrigin, 0.f); - Vec4 vecTranslation(vEye.Dot((Vec4&)shadowMat.m00), vEye.Dot((Vec4&)shadowMat.m10), vEye.Dot((Vec4&)shadowMat.m20), vEye.Dot((Vec4&)shadowMat.m30)); - shadowMat.m03 += vecTranslation.x; - shadowMat.m13 += vecTranslation.y; - shadowMat.m23 += vecTranslation.z; - shadowMat.m33 += vecTranslation.w; - (Vec4&)shadowMat.m20 *= gRenDev->m_cEF.m_TempVecs[2].x; - SetShaderFloat(eShClass, lightProjParamName, alias_cast(&shadowMat), 4); - - Vec4 ttt(gEnv->p3DEngine->GetSunColor(), gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()); - SetShaderFloat(eShClass, rsmSunColParameterName, (Vec4*)&ttt, 1); - Vec4 ttt2(gEnv->p3DEngine->GetSunDirNormalized(), 0); - SetShaderFloat(eShClass, rsmSunDirParameterName, (Vec4*)&ttt2, 1); - } - else - { - CTextureManager::Instance()->GetBlackTexture()->Apply(12, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - CTextureManager::Instance()->GetBlackTexture()->Apply(13, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - CTextureManager::Instance()->GetBlackTexture()->Apply(9, m_nTexStatePoint, EFTT_UNKNOWN, -1, -1, eShClass); - SetShaderFloat(eShClass, lightProjParamName, alias_cast(&shadowMat), 4); - - Vec4 ttt(0, 0, 0, 0); - SetShaderFloat(eShClass, rsmSunColParameterName, (Vec4*)&ttt, 1); - Vec4 ttt2(0, 0, 0, 0); - SetShaderFloat(eShClass, rsmSunDirParameterName, (Vec4*)&ttt2, 1); - } -} - -ISvoRenderer* CD3D9Renderer::GetISvoRenderer() -{ - return CSvoRenderer::GetInstance(true); -} - -void CSvoRenderer::SetShaderFloat(const EHWShaderClass eShClass, const CCryNameR& NameParam, const Vec4* fParams, int nParams) -{ - if (eShClass == eHWSC_Pixel) - { - m_pShader->FXSetPSFloat(NameParam, fParams, nParams); - } - else if (eShClass == eHWSC_Compute) - { - m_pShader->FXSetCSFloat(NameParam, fParams, nParams); - } - else if (eShClass == eHWSC_Vertex) - { - m_pShader->FXSetVSFloat(NameParam, fParams, nParams); - } -} - -void CSvoRenderer::BindTiledLights(PodArray& lightsTI, EHWShaderClass shaderType) -{ - gcpRendD3D->GetTiledShading().BindForwardShadingResources(NULL, shaderType); - - STiledLightShadeInfo* tiledLightShadeInfo = gcpRendD3D->GetTiledShading().GetTiledLightShadeInfo(); - - for (int l = 0; l < lightsTI.Count(); l++) - { - I3DEngine::SLightTI& svoLight = lightsTI[l]; - - if (!svoLight.vDirF.w) - { - continue; - } - - const int tlTypeRegularProjector = 6; - - Vec4 worldViewPos = Vec4(gcpRendD3D->GetViewParameters().vOrigin, 0); - - for (uint32 lightIdx = 0; lightIdx <= 255 && tiledLightShadeInfo[lightIdx].posRad != Vec4(0, 0, 0, 0); ++lightIdx) - { - if ((tiledLightShadeInfo[lightIdx].lightType == tlTypeRegularProjector) && svoLight.vPosR.IsEquivalent(tiledLightShadeInfo[lightIdx].posRad + worldViewPos, .5f)) - { - if (svoLight.vCol.w > 0) - { - svoLight.vCol.w = ((float)lightIdx + 100); - } - else - { - svoLight.vCol.w = -((float)lightIdx + 100); - } - } - } - } -} - -CTexture* CSvoRenderer::GetRsmColorMap(ShadowMapFrustum& rFr, bool bCheckUpdate) -{ - if (IsActive() && (rFr.nShadowMapLod == 2) && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()) - { - if (bCheckUpdate) - { - CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmColorMap, rFr.nShadowMapSize, rFr.nShadowMapSize, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_SUN_RSM_COLOR"); - } - - return CSvoRenderer::GetInstance()->m_pRsmColorMap; - } - - if (IsActive() && rFr.bUseShadowsPool && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && rFr.m_Flags & DLF_USE_FOR_SVOGI) - { - if (bCheckUpdate) - { - CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmPoolCol, gcpRendD3D->m_nShadowPoolWidth, gcpRendD3D->m_nShadowPoolHeight, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_PRJ_RSM_COLOR"); - } - - return CSvoRenderer::GetInstance()->m_pRsmPoolCol; - } - - return NULL; -} - -CTexture* CSvoRenderer::GetRsmNormlMap(ShadowMapFrustum& rFr, bool bCheckUpdate) -{ - if (IsActive() && (rFr.nShadowMapLod == 2) && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal()) - { - if (bCheckUpdate) - { - CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmNormlMap, rFr.nShadowMapSize, rFr.nShadowMapSize, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_SUN_RSM_NORMAL"); - } - - return CSvoRenderer::GetInstance()->m_pRsmNormlMap; - } - - if (IsActive() && rFr.bUseShadowsPool && gEnv->pConsole->GetCVar("e_svoTI_InjectionMultiplier")->GetFVal() && rFr.m_Flags & DLF_USE_FOR_SVOGI) - { - if (bCheckUpdate) - { - CSvoRenderer::GetInstance()->CheckCreateUpdateRT(CSvoRenderer::GetInstance()->m_pRsmPoolNor, gcpRendD3D->m_nShadowPoolWidth, gcpRendD3D->m_nShadowPoolHeight, eTF_R8G8B8A8, eTT_2D, FT_STATE_CLAMP, "SVO_PRJ_RSM_NORMAL"); - } - - return CSvoRenderer::GetInstance()->m_pRsmPoolNor; - } - - return NULL; -} - -void CSvoRenderer::CheckCreateUpdateRT(CTexture*& pTex, int nWidth, int nHeight, ETEX_Format eTF, [[maybe_unused]] ETEX_Type eTT, [[maybe_unused]] int nTexFlags, const char* szName) -{ - if ((!pTex) || (pTex->GetWidth() != nWidth) || (pTex->GetHeight() != nHeight) || (pTex->GetTextureDstFormat() != eTF)) - { - SAFE_RELEASE(pTex); - - char szNameEx[256] = ""; - sprintf_s(szNameEx, "%s_%d_%d", szName, nWidth, nHeight); // workaround for RT management bug - - SD3DPostEffectsUtils::CreateRenderTarget(szNameEx, pTex, nWidth, nHeight, Clr_Unknown, false, false, eTF); - - //iLog->Log("Realloc RT %dx%d, %s, %s", nWidth, nHeight, CTexture::NameForTextureFormat(eTF), szName); - } -} - - -void CSvoRenderer::SVoxPool::Init(ITexture* _pTex) -{ - CTexture* pTex = (CTexture*)_pTex; - - if (pTex) - { - pUAV = (D3DUnorderedAccessView*)((CTexture*)pTex)->GetDeviceUAV(); - nTexId = pTex->GetTextureID(); - } -} -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.h b/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.h deleted file mode 100644 index d23ab95ced..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/D3D_SVO.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __D3D_SVO__H__ -#define __D3D_SVO__H__ - -#if defined(FEATURE_SVO_GI) - -struct SSvoTargetsSet -{ - SSvoTargetsSet() { ZeroStruct(*this); } - void Release(); - - CTexture - // tracing targets - *pRT_RGB_0, *pRT_ALD_0, - *pRT_RGB_1, *pRT_ALD_1, - // de-mosaic targets - *pRT_RGB_DEM_MIN_0, *pRT_ALD_DEM_MIN_0, - *pRT_RGB_DEM_MAX_0, *pRT_ALD_DEM_MAX_0, - *pRT_RGB_DEM_MIN_1, *pRT_ALD_DEM_MIN_1, - *pRT_RGB_DEM_MAX_1, *pRT_ALD_DEM_MAX_1, - // output - *pRT_FIN_OUT_0, - *pRT_FIN_OUT_1; -}; - -class CSvoRenderer - : public ISvoRenderer -{ -public: - static Vec4 GetDisabledPerFrameShaderParameters(); - static CSvoRenderer* GetInstance(bool bCheckAlloce = false); - - void Release(); - static bool IsActive(); - void UpdateCompute(); - void UpdateRender(); - int GetIntegratioMode(); - - Vec4 GetPerFrameShaderParameters() const; - - void DebugDrawStats(const RPProfilerStats* pBasicStats, float& ypos, const float ystep, float xposms); - static bool SetSamplers(int nCustomID, EHWShaderClass eSHClass, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit); - - CTexture* GetDiffuseFinRT(); - CTexture* GetSpecularFinRT(); - static CTexture* GetRsmColorMap(ShadowMapFrustum& rFr, bool bCheckUpdate = false); - static CTexture* GetRsmNormlMap(ShadowMapFrustum& rFr, bool bCheckUpdate = false); - float GetSsaoAmount() { return IsActive() ? gEnv->pConsole->GetCVar("e_svoTI_SSAOAmount")->GetFVal() : 1.f; } - CTexture* GetRsmPoolCol() { return IsActive() ? m_pRsmPoolCol : NULL; } - CTexture* GetRsmPoolNor() { return IsActive() ? m_pRsmPoolNor : NULL; } - - void Lock() { m_renderMutex.lock(); } - void Unlock() { m_renderMutex.unlock(); } - -protected: - - CSvoRenderer(); - virtual ~CSvoRenderer(); - bool IsShaderItemUsedForVoxelization(SShaderItem& rShaderItem, IRenderNode* pRN); - static CTexture* GetGBuffer(int nId); - void UpScalePass(SSvoTargetsSet* pTS); - void DemosaicPass(SSvoTargetsSet* pTS); - void ConeTracePass(SSvoTargetsSet* pTS); - void SetupRsmSun(const EHWShaderClass eShClass); - void SetShaderFloat(const EHWShaderClass eShClass, const CCryNameR& NameParam, const Vec4* fParams, int nParams); - void CheckCreateUpdateRT(CTexture*& pTex, int nWidth, int nHeight, ETEX_Format eTF, ETEX_Type eTT, int nTexFlags, const char* szName); - - enum EComputeStages - { - eCS_ClearBricks, - eCS_InjectDynamicLights, - eCS_InjectStaticLights, - eCS_PropagateLighting_1to2, - eCS_PropagateLighting_2to3, - }; - - void ExecuteComputeShader(CShader* pSH, const char* szTechFinalName, EComputeStages etiStage, int* nNodesForUpdateStartIndex, int nObjPassId, PodArray& arrNodesForUpdate); - void SetShaderFlags(bool bDiffuseMode = true, bool bPixelShader = true); - void SetupSvoTexturesForRead(I3DEngine::SSvoStaticTexInfo& texInfo, EHWShaderClass eShaderClass, int nStage, int nStageOpa = 0, int nStageNorm = 0); - void SetupNodesForUpdate(int& nNodesForUpdateStartIndex, PodArray& arrNodesForUpdate); - void CheckAllocateRT(bool bSpecPass); - void SetupLightSources(PodArray& lightsTI, CShader* pShader, bool bPS); - void BindTiledLights(PodArray& lightsTI, EHWShaderClass shaderType); - void DrawPonts(PodArray& arrVerts); - - void UpdatePassConstantBuffer(); - - SSvoTargetsSet m_tsDiff, m_tsSpec; - - CTexture - *m_pRT_NID_0, - *m_pRT_AIR_MIN, - *m_pRT_AIR_MAX, - *m_pRT_AIR_SHAD; - - int m_nTexStateTrilinear, m_nTexStateLinear, m_nTexStatePoint, m_nTexStateLinearWrap; - Matrix44A m_matReproj; - Matrix44A m_matViewProjPrev; - CShader* m_pShader; - CTexture* m_pNoiseTex; - CTexture* m_pRsmColorMap; - CTexture* m_pRsmNormlMap; - CTexture* m_pRsmPoolCol; - CTexture* m_pRsmPoolNor; - AzRHI::ConstantBufferPtr m_PassConstantBuffer; - - struct SVoxPool - { - SVoxPool() { nTexId = 0; pUAV = 0; } - void Init(ITexture* pTex); - int nTexId; - ID3D11UnorderedAccessView* pUAV; - }; - - SVoxPool vp_OPAC; - SVoxPool vp_RGB0; - SVoxPool vp_RGB1; - SVoxPool vp_DYNL; - SVoxPool vp_RGB2; - SVoxPool vp_RGB3; - SVoxPool vp_NORM; - SVoxPool vp_ALDI; - - PodArray m_nodesForStaticUpdate; - PodArray m_nodesForDynamicUpdate; - PodArray m_arrLightsStatic; - PodArray m_arrLightsDynamic; - static const int SVO_MAX_NODE_GROUPS = 4; - float m_arrNodesForUpdate[SVO_MAX_NODE_GROUPS][4][4]; - int m_nCurPropagationPassID; - I3DEngine::SSvoStaticTexInfo m_texInfo; - static CSvoRenderer* s_pInstance; - PodArray m_arrNodeInfo; - AZStd::mutex m_renderMutex; - -}; -#endif -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX/RenderCapabilities.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX/RenderCapabilities.cpp deleted file mode 100644 index e4d91a49d4..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX/RenderCapabilities.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include "..\Common\RenderCapabilities.h" - -namespace RenderCapabilities -{ - bool SupportsTextureViews() - { - return true; - } - - bool SupportsStencilTextures() - { - return true; - } - - bool SupportsPLSExtension() - { - return false; - } - - FrameBufferFetchMask GetFrameBufferFetchCapabilities() - { - return FrameBufferFetchMask(); - } - - bool SupportsDepthClipping() - { - return true; - } - - bool SupportsDualSourceBlending() - { - return true; - } - - bool SupportsStructuredBuffer([[maybe_unused]] EShaderStage stage) - { - return true; - } - - bool SupportsIndependentBlending() - { - return true; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX/Tests/test_Main.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX/Tests/test_Main.cpp deleted file mode 100644 index 3d54c26e4c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX/Tests/test_Main.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "RenderDll_precompiled.h" -#include -#include -#include -#include -#include -namespace -{ - class RenderDllTestEnvironment final - : public AZ::Test::ITestEnvironment - , UnitTest::TraceBusRedirector // provides AZ_TEST_START_TRACE_SUPPRESSION - { - public: - AZ_TEST_CLASS_ALLOCATOR(RenderDllTestEnvironment); - - protected: - void SetupEnvironment() override - { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - } - - void TeardownEnvironment() override - { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - private: - }; -} -AZ_UNIT_TEST_HOOK(new RenderDllTestEnvironment); diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.cpp deleted file mode 100644 index 451ba86161..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "RenderDll_precompiled.h" -#include "DX12AsyncCommandQueue.hpp" -#include "DX12CommandList.hpp" -#include "DriverD3D.h" - -#include - -#define TRACK_RENDERTREAD_WAIT_TIME SScopedExecutionTimeTracker renderThreadWaitTimeTracker(gcpRendD3D->m_fTimeWaitForGPU[gcpRendD3D->m_RP.m_nProcessThreadID]); - -struct SScopedExecutionTimeTracker -{ - SScopedExecutionTimeTracker(float& var) - : trackerVariable(var) - , startTime(iTimer ? iTimer->GetAsyncTime() : 0.0f) - {} - - ~SScopedExecutionTimeTracker() - { - trackerVariable += iTimer ? iTimer->GetAsyncTime().GetDifferenceInSeconds(startTime) : 0.0f; - } - - float& trackerVariable; - CTimeValue startTime; -}; - -namespace DX12 -{ - void AsyncCommandQueue::SExecuteCommandlist::Process(const STaskArgs& args) - { - AZ_TRACE_METHOD_NAME("CommandQueue ExecuteCommandLists"); - args.pCommandQueue->ExecuteCommandLists(1, &pCommandList); - } - - void AsyncCommandQueue::SResetCommandlist::Process([[maybe_unused]] const STaskArgs& args) - { - AZ_TRACE_METHOD_NAME("CommandList Reset"); - pCommandList->Reset(); - } - - void AsyncCommandQueue::SSignalFence::Process(const STaskArgs& args) - { - AZ_TRACE_METHOD_NAME("Fence Signal"); - args.pCommandQueue->Signal(pFence, FenceValue); - } - - void AsyncCommandQueue::SWaitForFence::Process(const STaskArgs& args) - { - AZ_TRACE_METHOD_NAME("Fence Wait"); - args.pCommandQueue->Wait(pFence, FenceValue); - } - - void AsyncCommandQueue::SWaitForFences::Process(const STaskArgs& args) - { - AZ_TRACE_METHOD_NAME("Fence MultiWait"); - if (FenceValues[CMDQUEUE_COPY ]) - { - args.pCommandQueue->Wait(pFences[CMDQUEUE_COPY ], FenceValues[CMDQUEUE_COPY ]); - } - if (FenceValues[CMDQUEUE_GRAPHICS]) - { - args.pCommandQueue->Wait(pFences[CMDQUEUE_GRAPHICS], FenceValues[CMDQUEUE_GRAPHICS]); - } - } - - AsyncCommandQueue::AsyncCommandQueue() - : m_pCmdListPool(NULL) - , m_QueuedFramesCounter(0) - , m_bStopRequested(false) - { - } - - AsyncCommandQueue::~AsyncCommandQueue() - { - SignalStop(); - Flush(); - - GetISystem()->GetIThreadManager()->JoinThread(this, eJM_Join); - } - - void AsyncCommandQueue::Init(CommandListPool* pCommandListPool) - { - m_pCmdListPool = pCommandListPool; - m_QueuedFramesCounter = 0; - m_QueuedTasksCounter = 0; - m_bStopRequested = false; - - GetISystem()->GetIThreadManager()->SpawnThread(this, "DX12 AsyncCommandQueue"); - } - - - void AsyncCommandQueue::ExecuteCommandLists(UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists) - { - for (int i = 0; i < NumCommandLists; ++i) - { - SSubmissionTask task; - ZeroStruct(task); - - task.type = eTT_ExecuteCommandList; - task.Data.ExecuteCommandList.pCommandList = ppCommandLists[i]; - - AddTask(task); - } - } - - void AsyncCommandQueue::ResetCommandList(CommandList* pCommandList) - { - SSubmissionTask task; - ZeroStruct(task); - - task.type = eTT_ResetCommandList; - task.Data.ResetCommandList.pCommandList = pCommandList; - - AddTask(task); - } - - void AsyncCommandQueue::Signal(ID3D12Fence* pFence, const UINT64 FenceValue) - { - SSubmissionTask task; - ZeroStruct(task); - - task.type = eTT_SignalFence; - task.Data.SignalFence.pFence = pFence; - task.Data.SignalFence.FenceValue = FenceValue; - - AddTask(task); - } - - void AsyncCommandQueue::Wait(ID3D12Fence* pFence, const UINT64 FenceValue) - { - SSubmissionTask task; - ZeroStruct(task); - - task.type = eTT_WaitForFence; - task.Data.WaitForFence.pFence = pFence; - task.Data.WaitForFence.FenceValue = FenceValue; - - AddTask(task); - } - - void AsyncCommandQueue::Wait(ID3D12Fence** pFences, const UINT64 (&FenceValues)[CMDQUEUE_NUM]) - { - SSubmissionTask task; - ZeroStruct(task); - - task.type = eTT_WaitForFences; - task.Data.WaitForFences.pFences = pFences; - task.Data.WaitForFences.FenceValues[CMDQUEUE_COPY ] = FenceValues[CMDQUEUE_COPY ]; - task.Data.WaitForFences.FenceValues[CMDQUEUE_GRAPHICS] = FenceValues[CMDQUEUE_GRAPHICS]; - - AddTask(task); - } - - void AsyncCommandQueue::Flush(UINT64 lowerBoundFenceValue) - { - TRACK_RENDERTREAD_WAIT_TIME - - if (lowerBoundFenceValue != (~0ULL)) - { - while (m_QueuedTasksCounter > 0) - { - if (lowerBoundFenceValue <= m_pCmdListPool->GetLastCompletedFenceValue()) - { - break; - } - - Sleep(0); - } - } - else - { - while (m_QueuedTasksCounter > 0) - { - Sleep(0); - } - } - } - - void AsyncCommandQueue::ThreadEntry() - { - EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), "AsyncCommandQueue"); - - while (!m_bStopRequested) - { - SSubmissionTask task; - STaskArgs taskArgs = { m_pCmdListPool->GetD3D12CommandQueue(), &m_QueuedFramesCounter }; - - if (m_TaskQueue.dequeue(task)) - { - switch (task.type) - { - case eTT_ExecuteCommandList: - task.Process(taskArgs); - break; - case eTT_ResetCommandList: - task.Process(taskArgs); - break; - case eTT_SignalFence: - task.Process(taskArgs); - break; - case eTT_WaitForFence: - task.Process(taskArgs); - break; - case eTT_WaitForFences: - task.Process(taskArgs); - break; - } - - CryInterlockedDecrement(&m_QueuedTasksCounter); - } - else - { - Sleep(0); - } - } - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.hpp deleted file mode 100644 index 3ae99bb987..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12AsyncCommandQueue.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "DX12/Includes/concqueue.hpp" -#include "DX12Base.hpp" -#include "DX12/API/DX12CommandListFence.hpp" - -struct IDXGISwapChain3; - -namespace DX12 -{ - class CommandListPool; - - class AsyncCommandQueue : public IThread - { - public: - AsyncCommandQueue(); - ~AsyncCommandQueue(); - - template - static bool IsSynchronous() - { - return CRenderer::CV_r_D3D12SubmissionThread == 0; - } - - void Init(CommandListPool* pCommandListPool); - void Flush(UINT64 lowerBoundFenceValue = ~0ULL); - void SignalStop() { m_bStopRequested = true; } - - void ResetCommandList(CommandList* pCommandList); - void ExecuteCommandLists(UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists); - void Signal(ID3D12Fence* pFence, const UINT64 Value); - void Wait(ID3D12Fence* pFence, const UINT64 Value); - void Wait(ID3D12Fence** pFences, const UINT64 (&Values)[CMDQUEUE_NUM]); - - private: - enum eTaskType - { - eTT_ExecuteCommandList, - eTT_ResetCommandList, - eTT_SignalFence, - eTT_WaitForFence, - eTT_WaitForFences - }; - - struct STaskArgs - { - ID3D12CommandQueue* pCommandQueue; - volatile int* QueueFramesCounter; - }; - - struct SExecuteCommandlist - { - ID3D12CommandList* pCommandList; - - void Process(const STaskArgs& args); - }; - - struct SResetCommandlist - { - CommandList* pCommandList; - - void Process(const STaskArgs& args); - }; - - struct SSignalFence - { - ID3D12Fence* pFence; - UINT64 FenceValue; - - void Process(const STaskArgs& args); - }; - - struct SWaitForFence - { - ID3D12Fence* pFence; - UINT64 FenceValue; - - void Process(const STaskArgs& args); - }; - - struct SWaitForFences - { - ID3D12Fence** pFences; - UINT64 FenceValues[CMDQUEUE_NUM]; - - void Process(const STaskArgs& args); - }; - - struct SSubmissionTask - { - eTaskType type; - - union - { - SSignalFence SignalFence; - SWaitForFence WaitForFence; - SWaitForFences WaitForFences; - SExecuteCommandlist ExecuteCommandList; - SResetCommandlist ResetCommandList; - } Data; - - template - void Process(const STaskArgs& args) - { - TaskType* pTask = reinterpret_cast(&Data); - pTask->Process(args); - } - }; - - template - void AddTask(SSubmissionTask& task) - { - if (CRenderer::CV_r_D3D12SubmissionThread) - { - CryInterlockedIncrement(&m_QueuedTasksCounter); - m_TaskQueue.enqueue(task); - } - else - { - Flush(); - STaskArgs taskArgs = { m_pCmdListPool->GetD3D12CommandQueue(), &m_QueuedFramesCounter }; - task.Process(taskArgs); - } - } - - void ThreadEntry() override; - - volatile int m_QueuedFramesCounter; - volatile int m_QueuedTasksCounter; - volatile bool m_bStopRequested; - - CommandListPool* m_pCmdListPool; - ConcQueue m_TaskQueue; - }; -}; diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.cpp deleted file mode 100644 index fcfc01cdc3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12Base.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12BASE_CPP_SECTION_1 1 -#endif - -int g_nPrintDX12 = 0; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12BASE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12Base_cpp) -#endif - -namespace DX12 -{ - //--------------------------------------------------------------------------------------------------------------------- - UINT GetDXGIFormatSize(DXGI_FORMAT format) - { - switch (format) - { - case DXGI_FORMAT_UNKNOWN: - return 0; - - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - return 16; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - return 12; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - return 8; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - return 4; - - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_B4G4R4A4_UNORM: - return 2; - - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - return 1; - } - - DX12_NOT_IMPLEMENTED; - return 0; - } - - //--------------------------------------------------------------------------------------------------------------------- - D3D12_CLEAR_VALUE GetDXGIFormatClearValue(DXGI_FORMAT format, bool depth) - { - D3D12_CLEAR_VALUE clearValue; - - clearValue.Color[0] = 0.0f; - clearValue.Color[1] = 0.0f; - clearValue.Color[2] = 0.0f; - clearValue.Color[3] = 0.0f; - - switch (format) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - format = DXGI_FORMAT_R32G32B32A32_FLOAT; - break; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - format = DXGI_FORMAT_R32G32B32_FLOAT; - break; - - case DXGI_FORMAT_R32_TYPELESS: - format = depth ? DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_R32_FLOAT; - break; - - case DXGI_FORMAT_R16G16_TYPELESS: - format = DXGI_FORMAT_R16G16_FLOAT; - break; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - format = DXGI_FORMAT_R16G16B16A16_FLOAT; - break; - - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - format = DXGI_FORMAT_R32G32_FLOAT; - break; - case DXGI_FORMAT_R32G8X24_TYPELESS: - format = depth ? DXGI_FORMAT_D32_FLOAT_S8X24_UINT : DXGI_FORMAT_R32G32_FLOAT; - break; - - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - format = DXGI_FORMAT_D24_UNORM_S8_UINT; - break; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - format = DXGI_FORMAT_R10G10B10A2_UNORM; - break; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - format = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - - case DXGI_FORMAT_R8G8_TYPELESS: - format = DXGI_FORMAT_R8G8_UNORM; - break; - - case DXGI_FORMAT_R16_TYPELESS: - format = depth ? DXGI_FORMAT_D16_UNORM : DXGI_FORMAT_R16_FLOAT; - break; - - case DXGI_FORMAT_R8_TYPELESS: - format = DXGI_FORMAT_R8_UNORM; - break; - } - - clearValue.Format = format; - return clearValue; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - //--------------------------------------------------------------------------------------------------------------------- - DeviceObject::DeviceObject(Device* device) - : AzRHI::ReferenceCounted() - , m_Device(device) - , m_IsInitialized(false) - { - } - - //--------------------------------------------------------------------------------------------------------------------- - DeviceObject::~DeviceObject() - { - DX12_LOG("DX12 object destroyed: %p", this); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.hpp deleted file mode 100644 index 7045e989cf..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Base.hpp +++ /dev/null @@ -1,212 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12BASE_HPP_SECTION_1 1 -#endif - -#ifndef NDEBUG - -#define DX12_FUNC_LOG do { \ - if (g_nPrintDX12) \ - { CryLog("DX12 function call: %s", __FUNC__); } \ -} while (0); - -#define DX12_LOG(...) do { \ -if (g_nPrintDX12) \ - { CryLog("DX12 Log: " __VA_ARGS__); } \ -} while (0) -#define DX12_ERROR(...) do { CryLog("DX12 Error: " __VA_ARGS__); } while (0) -#define DX12_ASSERT(cond, ...) \ - do { if (!(cond)) { DX12_ERROR(__VA_ARGS__); CRY_ASSERT(0); __debugbreak(); } } while(0) - -#else -#define DX12_FUNC_LOG do { } while (0); -#define DX12_LOG(...) do { } while (0) -#define DX12_ERROR(...) do { } while (0) -#define DX12_ASSERT(cond, ...) -#endif - -#define DX12_NOT_IMPLEMENTED DX12_ASSERT(0, "Not implemented!"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12BASE_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12Base_hpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - #include - #include - #include - - #include - #include - #include - - using IDX12Unknown = IUnknown; -#endif - -#include - -#include "../Includes/fasthash.inl" -#include "../Includes/concqueue.hpp" - -#include - -#include - -extern int g_nPrintDX12; - -#ifndef IID_GRAPHICS_PPV_ARGS -#define IID_GRAPHICS_PPV_ARGS(ppType) IID_PPV_ARGS(ppType) -#endif - -#define DX12_STATS -#define DX12_GPU_VIRTUAL_ADDRESS_NULL 0ULL -#define INVALID_CPU_DESCRIPTOR_HANDLE CD3DX12_CPU_DESCRIPTOR_HANDLE(D3D12_DEFAULT) -#define INVALID_GPU_DESCRIPTOR_HANDLE CD3DX12_GPU_DESCRIPTOR_HANDLE(D3D12_DEFAULT) - -namespace DX12 -{ - class CommandList; - class CommandListPool; - class DescriptorHeap; - class Device; - class GraphicsPipelineState; - class PipelineStateCache; - class Resource; - class ResourceView; - - template - using SmartPtr = _smart_ptr; - - template - static T* PassAddRef(T* ptr) - { - if (ptr) - { - ptr->AddRef(); - } - - return ptr; - } - - template - static T* PassAddRef(const _smart_ptr& ptr) - { - if (ptr) - { - ptr.get()->AddRef(); - } - - return ptr.get(); - } - - typedef uint32_t THash; - template - inline THash ComputeSmallHash(const void* data, UINT seed = 666) - { - return fasthash::fasthash32(data, seed); - } - - UINT GetDXGIFormatSize(DXGI_FORMAT format); - D3D12_CLEAR_VALUE GetDXGIFormatClearValue(DXGI_FORMAT format, bool depth); - - inline bool IsDXGIFormatCompressed(DXGI_FORMAT format) - { - return - (format >= DXGI_FORMAT_BC1_TYPELESS && format <= DXGI_FORMAT_BC5_SNORM) || - (format >= DXGI_FORMAT_BC6H_TYPELESS && format <= DXGI_FORMAT_BC7_UNORM_SRGB); - } - - inline bool IsDXGIFormatCompressed4bpp(DXGI_FORMAT format) - { - return - (format >= DXGI_FORMAT_BC1_TYPELESS && format <= DXGI_FORMAT_BC1_UNORM_SRGB) || - (format >= DXGI_FORMAT_BC4_TYPELESS && format <= DXGI_FORMAT_BC4_SNORM); - } - - inline bool IsDXGIFormatCompressed8bpp(DXGI_FORMAT format) - { - return - (format >= DXGI_FORMAT_BC2_TYPELESS && format <= DXGI_FORMAT_BC3_UNORM_SRGB) || - (format >= DXGI_FORMAT_BC5_TYPELESS && format <= DXGI_FORMAT_BC5_SNORM) || - (format >= DXGI_FORMAT_BC6H_TYPELESS && format <= DXGI_FORMAT_BC7_UNORM_SRGB); - } - - class DeviceObject : public AzRHI::ReferenceCounted - { - public: - inline Device* GetDevice() const - { - return m_Device; - } - - inline bool IsInitialized() const - { - return m_IsInitialized; - } - - protected: - DeviceObject(Device* device); - virtual ~DeviceObject(); - - DeviceObject(DeviceObject&& r) - : AzRHI::ReferenceCounted(std::move(r)) - , m_IsInitialized(std::move(r.m_IsInitialized)) - , m_Device(std::move(r.m_Device)) - {} - - DeviceObject& operator=(DeviceObject&& r) - { - AzRHI::ReferenceCounted::operator=(std::move(r)); - - m_IsInitialized = std::move(r.m_IsInitialized); - m_Device = std::move(r.m_Device); - - return *this; - } - - inline void SetDevice(Device* device) - { - m_Device = device; - } - - inline void IsInitialized(bool is) - { - m_IsInitialized = is; - } - - private: - Device* m_Device; - bool m_IsInitialized; - }; - - static const UINT CONSTANT_BUFFER_ELEMENT_SIZE = 16U; - - enum CommandMode - { - CommandModeCompute = 0, - CommandModeGraphics, - CommandModeCount - }; -} - -#include "DX12Device.hpp" diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.cpp deleted file mode 100644 index 3e854fb048..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.cpp +++ /dev/null @@ -1,1321 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12CommandList.hpp" -#include "DX12Resource.hpp" -#include "DX12View.hpp" -#include "DX12SamplerState.hpp" -#include "DX12/GI/CCryDX12SwapChain.hpp" -#include "AzCore/Debug/EventTraceDrillerBus.h" - -namespace DX12 -{ - namespace EventTrace - { - const AZStd::thread_id GpuDetailThreadId{ (size_t)2 }; - const char* GpuDetailName = "GPU Detail"; - const char* GpuDetailCategory = "GPU"; - } - - const char* StateToString(D3D12_RESOURCE_STATES state) - { - static int buf = 0; - static char str[2][512]; - static char *ret; - - ret = str[buf ^= 1]; - *ret = '\0'; - - if (!state) - { - azstrcat(ret, AZStd::size(str[0]), " Common/Present"); - return ret; - } - - if ((state & D3D12_RESOURCE_STATE_GENERIC_READ) == D3D12_RESOURCE_STATE_GENERIC_READ) - { - azstrcat(ret, AZStd::size(str[0]), " Generic Read"); - return ret; - } - - if (state & D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER) - { - azstrcat(ret, AZStd::size(str[0]), " V/C Buffer"); - } - if (state & D3D12_RESOURCE_STATE_INDEX_BUFFER) - { - azstrcat(ret, AZStd::size(str[0]), " I Buffer"); - } - if (state & D3D12_RESOURCE_STATE_RENDER_TARGET) - { - azstrcat(ret, AZStd::size(str[0]), " RT"); - } - if (state & D3D12_RESOURCE_STATE_UNORDERED_ACCESS) - { - azstrcat(ret, AZStd::size(str[0]), " UA"); - } - if (state & D3D12_RESOURCE_STATE_DEPTH_WRITE) - { - azstrcat(ret, AZStd::size(str[0]), " DepthW"); - } - if (state & D3D12_RESOURCE_STATE_DEPTH_READ) - { - azstrcat(ret, AZStd::size(str[0]), " DepthR"); - } - if (state & D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE) - { - azstrcat(ret, AZStd::size(str[0]), " NoPixelR"); - } - if (state & D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) - { - azstrcat(ret, AZStd::size(str[0]), " PixelR"); - } - if (state & D3D12_RESOURCE_STATE_STREAM_OUT) - { - azstrcat(ret, AZStd::size(str[0]), " Stream Out"); - } - if (state & D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT) - { - azstrcat(ret, AZStd::size(str[0]), " Indirect Arg"); - } - if (state & D3D12_RESOURCE_STATE_COPY_DEST) - { - azstrcat(ret, AZStd::size(str[0]), " CopyD"); - } - if (state & D3D12_RESOURCE_STATE_COPY_SOURCE) - { - azstrcat(ret, AZStd::size(str[0]), " CopyS"); - } - if (state & D3D12_RESOURCE_STATE_RESOLVE_DEST) - { - azstrcat(ret, AZStd::size(str[0]), " ResolveD"); - } - if (state & D3D12_RESOURCE_STATE_RESOLVE_SOURCE) - { - azstrcat(ret, AZStd::size(str[0]), " ResolveS"); - } - - return ret; - } - - CommandList::CommandList(CommandListPool& pool) - : DeviceObject(pool.GetDevice()) - , m_rPool(pool) - , m_pCmdQueue{} - , m_pCmdAllocator{} - , m_CommandList{} - , m_pD3D12Device{} - , m_CurrentNumRTVs{} - , m_CurrentNumVertexBuffers{} - , m_CurrentFenceValue{} - , m_eListType(pool.GetD3D12QueueType()) - , m_State(CLSTATE_FREE) - , m_nodeMask{} -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - , m_Timers{ *GetDevice() } -#endif - , m_DescriptorHeaps - { - { - GetDevice()->GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024) - }, - { - GetDevice()->GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1024) - }, - { - GetDevice()->GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1024) - }, - { - GetDevice()->GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1024) - } - } - { - ResetStateTracking(CommandModeCompute); - ResetStateTracking(CommandModeGraphics); - } - - CommandList::~CommandList() - { - } - - bool CommandList::Init(UINT64 currentFenceValue) - { - m_State = CLSTATE_STARTED; - m_Commands = 0; - m_CurrentPipelineState = nullptr; - m_CurrentRootSignature[DX12::CommandModeCompute] = m_CurrentRootSignature[DX12::CommandModeGraphics] = nullptr; - m_pDSV = nullptr; - m_CurrentNumRTVs = 0; - m_CurrentNumVertexBuffers = 0; - - m_CurrentFenceValue = currentFenceValue; - ZeroMemory(m_UsedFenceValues, sizeof(m_UsedFenceValues)); - - m_pD3D12Device = GetDevice()->GetD3D12Device(); - - for (D3D12_DESCRIPTOR_HEAP_TYPE eType = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; eType < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; eType = D3D12_DESCRIPTOR_HEAP_TYPE(eType + 1)) - { - m_DescriptorHeaps[eType].Reset(); - } - - if (!IsInitialized()) - { - m_pCmdQueue = m_rPool.GetD3D12CommandQueue(); - - D3D12_COMMAND_LIST_TYPE eCmdListType = m_pCmdQueue->GetDesc().Type; - - ID3D12CommandAllocator* pCmdAllocator = nullptr; - if (S_OK != m_pD3D12Device->CreateCommandAllocator(eCmdListType, IID_GRAPHICS_PPV_ARGS(&pCmdAllocator))) - { - DX12_ERROR("Could not create command allocator!"); - return false; - } - - m_pCmdAllocator = pCmdAllocator; - pCmdAllocator->Release(); - - ID3D12GraphicsCommandList* pCmdList = nullptr; - if (S_OK != m_pD3D12Device->CreateCommandList(m_nodeMask, eCmdListType, m_pCmdAllocator, nullptr, IID_GRAPHICS_PPV_ARGS(&pCmdList))) - { - DX12_ERROR("Could not create command list"); - return false; - } - - m_CommandList = pCmdList; - pCmdList->Release(); - -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - m_Timers.Init(TimerCountMax); -#endif - - IsInitialized(true); - } - -#ifdef DX12_STATS - m_NumWaitsGPU = 0; - m_NumWaitsCPU = 0; -#endif // DX12_STATS - - return true; - } - - void CommandList::Begin() - { -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - m_Timers.Begin(); - m_TimerHandle = m_Timers.BeginTimer(*this, "CommandList"); -#endif - } - - void CommandList::End() - { - { - DX12_COMMANDLIST_TIMER("End"); - FlushBarriers(); - } - - if (IsUtilized()) - { -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - m_Timers.EndTimer(*this, m_TimerHandle); - m_Timers.End(*this); -#endif - -#ifndef NDEBUG - HRESULT res = -#endif - m_CommandList->Close(); - DX12_ASSERT(res == S_OK, "Could not close command list!"); - } - - m_State = CLSTATE_COMPLETED; - } - - void CommandList::Schedule() - { - if (m_State < CLSTATE_SCHEDULED) - { - m_State = CLSTATE_SCHEDULED; - } - } - - void CommandList::Submit() - { - if (IsUtilized()) - { - // Inject a Wait() into the CommandQueue prior to executing it to wait for all required resources being available either readable or writable -#ifdef DX12_IN_ORDER_SUBMISSION - m_UsedFenceValues[CMDTYPE_ANY][CMDQUEUE_COPY ] = std::max(m_UsedFenceValues[CMDTYPE_READ][CMDQUEUE_COPY ], m_UsedFenceValues[CMDTYPE_WRITE][CMDQUEUE_COPY ]); - m_UsedFenceValues[CMDTYPE_ANY][CMDQUEUE_GRAPHICS] = std::max(m_UsedFenceValues[CMDTYPE_READ][CMDQUEUE_GRAPHICS], m_UsedFenceValues[CMDTYPE_WRITE][CMDQUEUE_GRAPHICS]); -#else - MaxFenceValue(m_UsedFenceValues[CMDTYPE_ANY][CMDQUEUE_COPY ], std::max(m_UsedFenceValues[CMDTYPE_READ][CMDQUEUE_COPY ], m_UsedFenceValues[CMDTYPE_WRITE][CMDQUEUE_COPY ])); - MaxFenceValue(m_UsedFenceValues[CMDTYPE_ANY][CMDQUEUE_GRAPHICS], std::max(m_UsedFenceValues[CMDTYPE_READ][CMDQUEUE_GRAPHICS], m_UsedFenceValues[CMDTYPE_WRITE][CMDQUEUE_GRAPHICS])); -#endif - - m_rPool.WaitForFenceOnGPU(m_UsedFenceValues[CMDTYPE_ANY]); - - // Then inject the Execute() which is possibly blocked by the Wait() - ID3D12CommandList* ppCommandLists[] = { GetD3D12CommandList() }; - m_rPool.GetAsyncCommandQueue().ExecuteCommandLists(1, ppCommandLists); // TODO: allow to submit multiple command-lists in one go - } - - // Inject the signal of the utilized fence to unblock code which picked up the fence of the command-list (even if it doesn't have contents) - m_rPool.SetSubmittedFenceValue(SignalFenceOnGPU()); - m_State = CLSTATE_SUBMITTED; - } - - void CommandList::Clear() - { - m_State = CLSTATE_CLEARING; - FlushBarriers(); - m_rPool.GetAsyncCommandQueue().ResetCommandList(this); - } - - void CommandList::SubmitTimers() - { -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - m_Timers.ReadbackTimers(); - - for (const Timer& timer : m_Timers.GetTimers()) - { - EBUS_QUEUE_EVENT(AZ::Debug::EventTraceDrillerBus, RecordSlice, timer.m_Name, EventTrace::GpuDetailCategory, EventTrace::GpuDetailThreadId, timer.m_Timestamp, timer.m_Duration); - } -#endif - } - - bool CommandList::Reset() - { - if (IsUtilized()) - { - SubmitTimers(); - - HRESULT ret = 0; - - // reset the allocator before the list re-occupies it, otherwise the whole state of the allocator starts leaking - if (m_pCmdAllocator) - { - ret = m_pCmdAllocator->Reset(); - } - // make the list re-occupy this allocator, reseting the list will _not_ reset the allocator - if (m_CommandList) - { - ret = m_CommandList->Reset(m_pCmdAllocator, NULL); - } - } - - m_State = CLSTATE_FREE; - m_Commands = 0; - return true; - } - - void CommandList::ResetStateTracking(CommandMode commandMode) - { - memset(&m_CurrentRootParameters[commandMode], ~0, sizeof(m_CurrentRootParameters[commandMode])); - } - - void CommandList::SetPipelineState(const PipelineState* pso) - { - if (m_CurrentPipelineState != pso) - { - m_CurrentPipelineState = pso; - - DX12_COMMANDLIST_TIMER_DETAIL("SetPipelineState"); - m_CommandList->SetPipelineState(pso->GetD3D12PipelineState()); - m_Commands += CLCOUNT_SETIO; - } - } - - void CommandList::SetRootSignature(CommandMode commandMode, const RootSignature* rootSignature) - { - if (m_CurrentRootSignature[commandMode] != rootSignature) - { - m_CurrentRootSignature[commandMode] = rootSignature; - - if (rootSignature) - { - ResetStateTracking(commandMode); - DX12_COMMANDLIST_TIMER_DETAIL("SetRootSignature"); - switch (commandMode) - { - case CommandModeGraphics: - m_CommandList->SetGraphicsRootSignature(rootSignature->GetD3D12RootSignature()); - break; - - case CommandModeCompute: - m_CommandList->SetComputeRootSignature(rootSignature->GetD3D12RootSignature()); - break; - } - m_Commands += CLCOUNT_SETIO; - } - } - } - - bool CommandList::IsFull(size_t numResources, size_t numSamplers, size_t numRendertargets, size_t numDepthStencils) const - { - return - (GetResourceHeap().GetCursor() + numResources >= GetResourceHeap().GetCapacity()) || - (GetSamplerHeap().GetCursor() + numSamplers >= GetSamplerHeap().GetCapacity()) || - (GetRenderTargetHeap().GetCursor() + numRendertargets >= GetRenderTargetHeap().GetCapacity()) || - (GetDepthStencilHeap().GetCursor() + numDepthStencils >= GetDepthStencilHeap().GetCapacity()); - } - - void CommandList::SetDescriptorTable(CommandMode commandMode, UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor) - { - if (m_CurrentRootParameters[commandMode][RootParameterIndex].descriptorHandle.ptr != BaseDescriptor.ptr) - { - DX12_ASSERT(RootParameterIndex < RootParameterCountMax, "Too many root parameters"); - m_CurrentRootParameters[commandMode][RootParameterIndex].descriptorHandle = BaseDescriptor; - - switch (commandMode) - { - case CommandModeGraphics: - m_CommandList->SetGraphicsRootDescriptorTable(RootParameterIndex, BaseDescriptor); - break; - - case CommandModeCompute: - m_CommandList->SetComputeRootDescriptorTable(RootParameterIndex, BaseDescriptor); - break; - } - m_Commands += CLCOUNT_SETIO; - } - } - - void CommandList::SetConstantBufferView(CommandMode commandMode, UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) - { - if (m_CurrentRootParameters[commandMode][RootParameterIndex].gpuAddress != BufferLocation) - { - DX12_ASSERT(RootParameterIndex < RootParameterCountMax, "Too many root parameters"); - m_CurrentRootParameters[commandMode][RootParameterIndex].gpuAddress = BufferLocation; - switch (commandMode) - { - case CommandModeGraphics: - m_CommandList->SetGraphicsRootConstantBufferView(RootParameterIndex, BufferLocation); - break; - - case CommandModeCompute: - m_CommandList->SetComputeRootConstantBufferView(RootParameterIndex, BufferLocation); - break; - } - m_Commands += CLCOUNT_SETIO; - } - } - - void CommandList::Set32BitConstants(CommandMode commandMode, UINT RootParameterIndex, UINT Num32BitValuesToSet, const void* pSrcData, UINT DestOffsetIn32BitValues) - { - switch (commandMode) - { - case CommandModeGraphics: - m_CommandList->SetGraphicsRoot32BitConstants(RootParameterIndex, Num32BitValuesToSet, pSrcData, DestOffsetIn32BitValues); - break; - - case CommandModeCompute: - m_CommandList->SetComputeRoot32BitConstants(RootParameterIndex, Num32BitValuesToSet, pSrcData, DestOffsetIn32BitValues); - break; - } - m_Commands += CLCOUNT_SETIO; - } - - void CommandList::SetDescriptorTables(CommandMode commandMode, D3D12_DESCRIPTOR_HEAP_TYPE eType) - { - DX12_ASSERT(m_CurrentRootSignature[commandMode]); - - const PipelineLayout& layout = m_CurrentRootSignature[commandMode]->GetPipelineLayout(); - for (AZ::u32 rootParameterIdx = 0, tableIdx = 0; rootParameterIdx < layout.m_NumRootParameters; ++rootParameterIdx) - { - const CD3DX12_ROOT_PARAMETER& rootParameter = layout.m_RootParameters[rootParameterIdx]; - - if (rootParameter.ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) - { - continue; - } - - if (layout.m_DescriptorTables[tableIdx].m_Type == eType) - { - switch (commandMode) - { - case CommandModeCompute: - m_CommandList->SetComputeRootDescriptorTable(rootParameterIdx, m_DescriptorHeaps[eType].GetHandleOffsetGPU(layout.m_DescriptorTables[tableIdx].m_Offset)); - break; - - case CommandModeGraphics: - m_CommandList->SetGraphicsRootDescriptorTable(rootParameterIdx, m_DescriptorHeaps[eType].GetHandleOffsetGPU(layout.m_DescriptorTables[tableIdx].m_Offset)); - break; - } - m_Commands += CLCOUNT_SETIO; - } - - ++tableIdx; - } - } - - void CommandList::BindDepthStencilView(const ResourceView& dsv) - { - Resource& resource = dsv.GetDX12Resource(); - const D3D12_CPU_DESCRIPTOR_HANDLE handle = GetDepthStencilHeap().GetHandleOffsetCPU(0); - - if (INVALID_CPU_DESCRIPTOR_HANDLE != dsv.GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, handle, dsv.GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - } - else - { - m_pD3D12Device->CreateDepthStencilView(resource.GetD3D12Resource(), dsv.HasDesc() ? &(dsv.GetDSVDesc()) : NULL, handle); - } - - if (dsv.GetDSVDesc().Flags & D3D12_DSV_FLAG_READ_ONLY_DEPTH) - { - TrackResourceDRVUsage(resource); - } - else - { - TrackResourceDSVUsage(resource); - } - } - - void CommandList::PresentRenderTargetView(SwapChain* pDX12SwapChain) - { - QueueTransitionBarrier(pDX12SwapChain->GetCurrentBackBuffer(), D3D12_RESOURCE_STATE_PRESENT); - } - - void CommandList::BindRenderTargetView(const ResourceView& renderTargetView) - { - Resource& resource = renderTargetView.GetDX12Resource(); - - const D3D12_CPU_DESCRIPTOR_HANDLE handle = GetRenderTargetHeap().GetHandleOffsetCPU(0); - if (INVALID_CPU_DESCRIPTOR_HANDLE != renderTargetView.GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, handle, renderTargetView.GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - } - else - { - m_pD3D12Device->CreateRenderTargetView(resource.GetD3D12Resource(), renderTargetView.HasDesc() ? &(renderTargetView.GetRTVDesc()) : NULL, handle); - } - - TrackResourceRTVUsage(resource); - } - - void CommandList::WriteUnorderedAccessDescriptor(const ResourceView* resourceView, INT descriptorOffset) - { - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = GetResourceHeap().GetHandleOffsetCPU(descriptorOffset); - - if (resourceView) - { - Resource& resource = resourceView->GetDX12Resource(); - - if (INVALID_CPU_DESCRIPTOR_HANDLE != resourceView->GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, resourceView->GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - else - { - m_pD3D12Device->CreateUnorderedAccessView(resource.GetD3D12Resource(), nullptr, resourceView->HasDesc() ? &(resourceView->GetUAVDesc()) : NULL, dstHandle); - } - - TrackResourceUAVUsage(resource); - } - else - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, GetDevice()->GetNullUnorderedAccessView(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - } - - void CommandList::WriteShaderResourceDescriptor(const ResourceView* resourceView, INT descriptorOffset) - { - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = GetResourceHeap().GetHandleOffsetCPU(descriptorOffset); - - if (resourceView) - { - Resource& resource = resourceView->GetDX12Resource(); - DX12_ASSERT(resource.GetD3D12Resource(), "No resource to create SRV from!"); - - if (INVALID_CPU_DESCRIPTOR_HANDLE != resourceView->GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, resourceView->GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - else - { - m_pD3D12Device->CreateShaderResourceView(resource.GetD3D12Resource(), &resourceView->GetSRVDesc(), dstHandle); - } - - TrackResourceSRVUsage(resource); - } - else - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, GetDevice()->GetNullShaderResourceView(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - } - - void CommandList::WriteConstantBufferDescriptor(const ResourceView* resourceView, INT descriptorOffset, UINT byteOffset, UINT byteCount) - { - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = GetResourceHeap().GetHandleOffsetCPU(descriptorOffset); - - if (resourceView) - { - if (INVALID_CPU_DESCRIPTOR_HANDLE != resourceView->GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, resourceView->GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - } - else - { - D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc; - cbvDesc = resourceView->GetCBVDesc(); - cbvDesc.BufferLocation += byteOffset; - cbvDesc.SizeInBytes = byteCount ? byteCount : cbvDesc.SizeInBytes - byteOffset; - DX12_ASSERT(byteCount < D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * DX12::CONSTANT_BUFFER_ELEMENT_SIZE, "exceeded allowed size of constant buffer"); - m_pD3D12Device->CreateConstantBufferView(&cbvDesc, dstHandle); - } - - TrackResourceCBVUsage(resourceView->GetDX12Resource()); - } - else - { - D3D12_CONSTANT_BUFFER_VIEW_DESC desc = {}; - m_pD3D12Device->CreateConstantBufferView(&desc, dstHandle); - } - } - - void CommandList::WriteSamplerStateDescriptor(const SamplerState* state, INT descriptorOffset) - { - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = GetSamplerHeap().GetHandleOffsetCPU(descriptorOffset); - - if (state) - { - if (INVALID_CPU_DESCRIPTOR_HANDLE != state->GetDescriptorHandle()) - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, state->GetDescriptorHandle(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - } - else - { - m_pD3D12Device->CreateSampler(&state->GetSamplerDesc(), dstHandle); - } - } - else - { - m_pD3D12Device->CopyDescriptorsSimple(1, dstHandle, GetDevice()->GetNullSampler(), D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - } - } - - void CommandList::SetResourceAndSamplerStateHeaps() - { - DX12_COMMANDLIST_TIMER_DETAIL("SetResourceAndSamplerStateHeaps"); - ID3D12DescriptorHeap* heaps[] = - { - GetResourceHeap().GetDescriptorHeap()->GetD3D12DescriptorHeap(), - GetSamplerHeap().GetDescriptorHeap()->GetD3D12DescriptorHeap() - }; - - m_CommandList->SetDescriptorHeaps(2, heaps); - m_Commands += CLCOUNT_SETIO; - } - - void CommandList::BindAndSetOutputViews(INT numRTVs, const ResourceView** rtv, const ResourceView* dsv) - { - DX12_COMMANDLIST_TIMER_DETAIL("BindAndSetOutputViews"); - if (dsv) - { - BindDepthStencilView(*dsv); - GetDepthStencilHeap().IncrementCursor(); - } - - m_pDSV = dsv; - - for (INT i = 0; i < numRTVs; ++i) - { - BindRenderTargetView(*rtv[i]); - GetRenderTargetHeap().IncrementCursor(); - - m_pRTV[i] = rtv[i]; - } - - m_CurrentNumRTVs = numRTVs; - - D3D12_CPU_DESCRIPTOR_HANDLE RTVDescriptors[] = { GetRenderTargetHeap().GetHandleOffsetCPU(-numRTVs) }; - D3D12_CPU_DESCRIPTOR_HANDLE DSVDescriptors[] = { GetDepthStencilHeap().GetHandleOffsetCPU(-1) }; - - m_CommandList->OMSetRenderTargets(numRTVs, numRTVs ? RTVDescriptors : NULL, true, dsv ? DSVDescriptors : NULL); - m_Commands += CLCOUNT_SETIO; - } - - bool CommandList::IsUsedByOutputViews(const Resource& res) const - { - if (m_pDSV && (&m_pDSV->GetDX12Resource() == &res)) - { - return true; - } - - for (INT i = 0, n = m_CurrentNumRTVs; i < n; ++i) - { - if (m_pRTV[i] && (&m_pRTV[i]->GetDX12Resource() == &res)) - { - return true; - } - } - - return false; - } - - void CommandList::BindVertexBufferView(const ResourceView& view, INT offset, const TRange& bindRange, UINT bindStride, D3D12_VERTEX_BUFFER_VIEW (&heap)[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]) - { - Resource& resource = view.GetDX12Resource(); - - D3D12_VERTEX_BUFFER_VIEW& vbvDesc = heap[offset]; - vbvDesc = view.GetVBVDesc(); - vbvDesc.BufferLocation += bindRange.start; - vbvDesc.SizeInBytes = bindRange.Length() > 0 ? bindRange.Length() : vbvDesc.SizeInBytes - bindRange.start; - vbvDesc.StrideInBytes = bindStride; - - TrackResourceVBVUsage(resource); - } - - void CommandList::ClearVertexBufferHeap(UINT num) - { - memset(m_VertexBufferHeap, 0, std::max(num, m_CurrentNumVertexBuffers) * sizeof(m_VertexBufferHeap[0])); - } - - void CommandList::SetVertexBufferHeap(UINT num) - { - m_CommandList->IASetVertexBuffers(0, std::max(num, m_CurrentNumVertexBuffers), m_VertexBufferHeap); - m_Commands += CLCOUNT_SETIO; - - m_CurrentNumVertexBuffers = num; - } - - void CommandList::BindAndSetIndexBufferView(const ResourceView& view, DXGI_FORMAT format, UINT offset) - { - Resource& resource = view.GetDX12Resource(); - - D3D12_INDEX_BUFFER_VIEW ibvDesc; - ibvDesc = view.GetIBVDesc(); - ibvDesc.BufferLocation += offset; - ibvDesc.SizeInBytes = ibvDesc.SizeInBytes - offset; - ibvDesc.Format = (format == DXGI_FORMAT_UNKNOWN ? resource.GetDesc().Format : format); - - TrackResourceIBVUsage(resource); - - m_CommandList->IASetIndexBuffer(&ibvDesc); - m_Commands += CLCOUNT_SETIO; - } - - void CommandList::ClearDepthStencilView(const ResourceView& view, D3D12_CLEAR_FLAGS clearFlags, float depthValue, UINT stencilValue, UINT NumRects, const D3D12_RECT* pRect) - { - DX12_ASSERT(INVALID_CPU_DESCRIPTOR_HANDLE != view.GetDescriptorHandle(), "View has no descriptor handle, that is not allowed!"); - DX12_COMMANDLIST_TIMER_DETAIL("ClearDepthStencilView"); - - Resource& resource = view.GetDX12Resource(); - - TrackResourceDSVUsage(resource); - FlushBarriers(); - - m_CommandList->ClearDepthStencilView(view.GetDescriptorHandle(), clearFlags, depthValue, stencilValue, NumRects, pRect); - m_Commands += CLCOUNT_CLEAR; - } - - void CommandList::ClearRenderTargetView(const ResourceView& inputView, const FLOAT rgba[4], UINT NumRects, const D3D12_RECT* pRect) - { - DX12_ASSERT(INVALID_CPU_DESCRIPTOR_HANDLE != inputView.GetDescriptorHandle(), "View has no descriptor handle, that is not allowed!"); - DX12_COMMANDLIST_TIMER_DETAIL("ClearRenderTargetView"); - - TrackResourceRTVUsage(inputView.GetDX12Resource()); - FlushBarriers(); - - m_CommandList->ClearRenderTargetView(inputView.GetDescriptorHandle(), rgba, NumRects, pRect); - m_Commands += CLCOUNT_CLEAR; - } - - void CommandList::ClearUnorderedAccessView(const ResourceView& view, const UINT rgba[4], UINT NumRects, const D3D12_RECT* pRect) - { - DX12_ASSERT(INVALID_CPU_DESCRIPTOR_HANDLE != view.GetDescriptorHandle(), "View has no descriptor handle, that is not allowed!"); - DX12_COMMANDLIST_TIMER_DETAIL("ClearUnorderedAccessView"); - - TrackResourceUAVUsage(view.GetDX12Resource()); - FlushBarriers(); - - m_CommandList->ClearUnorderedAccessViewUint(GetResourceHeap().GetHandleGPUFromCPU(view.GetDescriptorHandle()), view.GetDescriptorHandle(), view.GetD3D12Resource(), rgba, NumRects, pRect); - m_Commands += CLCOUNT_CLEAR; - } - - void CommandList::ClearUnorderedAccessView(const ResourceView& view, const FLOAT rgba[4], UINT NumRects, const D3D12_RECT* pRect) - { - DX12_ASSERT(INVALID_CPU_DESCRIPTOR_HANDLE != view.GetDescriptorHandle(), "View has no descriptor handle, that is not allowed!"); - DX12_COMMANDLIST_TIMER_DETAIL("ClearUnorderedAccessView"); - - TrackResourceUAVUsage(view.GetDX12Resource()); - FlushBarriers(); - - m_CommandList->ClearUnorderedAccessViewFloat(GetResourceHeap().GetHandleGPUFromCPU(view.GetDescriptorHandle()), view.GetDescriptorHandle(), view.GetD3D12Resource(), rgba, NumRects, pRect); - m_Commands += CLCOUNT_CLEAR; - } - - void CommandList::ClearView(const ResourceView& view, const FLOAT rgba[4], UINT NumRects, const D3D12_RECT* pRect) - { - DX12_ASSERT(INVALID_CPU_DESCRIPTOR_HANDLE != view.GetDescriptorHandle(), "View has no descriptor handle, that is not allowed!"); - - switch (view.GetType()) - { - case EVT_UnorderedAccessView: - ClearUnorderedAccessView(view, rgba, NumRects, pRect); - break; - - case EVT_DepthStencilView: // Optional implementation under DX11.1 - ClearDepthStencilView(view, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, FLOAT(rgba[0]), UINT(rgba[1]), NumRects, pRect); - break; - - case EVT_RenderTargetView: - ClearRenderTargetView(view, rgba, NumRects, pRect); - break; - - case EVT_ShaderResourceView: - case EVT_ConstantBufferView: - case EVT_VertexBufferView: - default: - DX12_ASSERT(0, "Unsupported resource-type for input!"); - break; - } - } - - void CommandList::CopyResource(Resource& dstResource, Resource& srcResource) - { - if (srcResource.InitHasBeenDeferred()) - { - srcResource.TryStagingUpload(this); - } - - DX12_COMMANDLIST_TIMER_DETAIL("CopyResource"); - MaxResourceFenceValue(dstResource, CMDTYPE_ANY); - MaxResourceFenceValue(srcResource, CMDTYPE_WRITE); - - QueueTransitionBarrier(dstResource, D3D12_RESOURCE_STATE_COPY_DEST); - QueueTransitionBarrier(srcResource, D3D12_RESOURCE_STATE_COPY_SOURCE); - FlushBarriers(); - - DX12_ASSERT(srcResource.GetDesc().Dimension == dstResource.GetDesc().Dimension, "Can't copy resources of different dimension"); - m_CommandList->CopyResource(dstResource.GetD3D12Resource(), srcResource.GetD3D12Resource()); - m_Commands += CLCOUNT_COPY; - - SetResourceFenceValue(dstResource, m_CurrentFenceValue, CMDTYPE_WRITE); - SetResourceFenceValue(srcResource, m_CurrentFenceValue, CMDTYPE_READ); - } - - void CommandList::CopySubresource(Resource& dstResource, UINT dstSubResource, UINT x, UINT y, UINT z, Resource& srcResource, UINT srcSubResource, const D3D12_BOX* srcBox) - { - if (srcResource.InitHasBeenDeferred()) - { - srcResource.TryStagingUpload(this); - } - - DX12_COMMANDLIST_TIMER_DETAIL("CopySubresource"); - MaxResourceFenceValue(dstResource, CMDTYPE_ANY); - MaxResourceFenceValue(srcResource, CMDTYPE_WRITE); - - // TODO: if we know early that the resource(s) will be DEST and SOURCE we can begin the barrier early and end it here - QueueTransitionBarrier(dstResource, D3D12_RESOURCE_STATE_COPY_DEST); - QueueTransitionBarrier(srcResource, D3D12_RESOURCE_STATE_COPY_SOURCE); - FlushBarriers(); - - if (srcResource.GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && dstResource.GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - UINT64 offset = 0; - UINT64 length = srcResource.GetDesc().Width; - - if (srcBox) - { - length = srcBox->right - srcBox->left; - offset = srcBox->left; - } - - m_CommandList->CopyBufferRegion(dstResource.GetD3D12Resource(), x, srcResource.GetD3D12Resource(), offset, length); - m_Commands += CLCOUNT_COPY; - } - else if (srcResource.GetDesc().Dimension != D3D12_RESOURCE_DIMENSION_BUFFER && dstResource.GetDesc().Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) - { - CD3DX12_TEXTURE_COPY_LOCATION src(srcResource.GetD3D12Resource(), srcSubResource); - CD3DX12_TEXTURE_COPY_LOCATION dst(dstResource.GetD3D12Resource(), dstSubResource); - - m_CommandList->CopyTextureRegion(&dst, x, y, z, &src, srcBox); - m_Commands += CLCOUNT_COPY; - } - else if (dstResource.GetDesc().Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) - { - // If this assert trips, you may need to increase MAX_SUBRESOURCES. Just be wary of growing the stack too much. - AZ_Assert(dstSubResource < CCryDX12DeviceContext::MAX_SUBRESOURCES, "Too many sub resources: (sub ID %d requested, %d allowed)", dstSubResource, CCryDX12DeviceContext::MAX_SUBRESOURCES); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[CCryDX12DeviceContext::MAX_SUBRESOURCES]; - - // From our "regular" resource, get the offset and description information for the subresource so we can copy the correct - // part of the buffer resource. We need to get Layouts for subresource 0 through dstSubResource so that the offset is set - // correctly. If we just get the Layout for dstSubResource, it will have an offset of 0. - GetDevice()->GetD3D12Device()->GetCopyableFootprints(&dstResource.GetDesc(), 0, dstSubResource + 1, 0, layouts, nullptr, nullptr, nullptr); - - CD3DX12_TEXTURE_COPY_LOCATION src(srcResource.GetD3D12Resource(), layouts[dstSubResource]); - CD3DX12_TEXTURE_COPY_LOCATION dst(dstResource.GetD3D12Resource(), dstSubResource); - - m_CommandList->CopyTextureRegion(&dst, x, y, z, &src, srcBox); - m_Commands += CLCOUNT_COPY; - } - else if (srcResource.GetDesc().Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) - { - // If this assert trips, you may need to increase MAX_SUBRESOURCES. Just be wary of growing the stack too much. - AZ_Assert(dstSubResource < CCryDX12DeviceContext::MAX_SUBRESOURCES, "Too many sub resources: (sub ID %d requested, %d allowed)", dstSubResource, CCryDX12DeviceContext::MAX_SUBRESOURCES); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[CCryDX12DeviceContext::MAX_SUBRESOURCES]; - - // From our "regular" resource, get the offset and description information for the subresource so we can copy the correct - // part of the buffer resource. We need to get Layouts for subresource 0 through dstSubResource so that the offset is set - // correctly. If we just get the Layout for dstSubResource, it will have an offset of 0. - GetDevice()->GetD3D12Device()->GetCopyableFootprints(&srcResource.GetDesc(), 0, srcSubResource + 1, 0, layouts, nullptr, nullptr, nullptr); - - CD3DX12_TEXTURE_COPY_LOCATION src(srcResource.GetD3D12Resource(), srcSubResource); - CD3DX12_TEXTURE_COPY_LOCATION dst(dstResource.GetD3D12Resource(), layouts[srcSubResource]); - - m_CommandList->CopyTextureRegion(&dst, x, y, z, &src, srcBox); - m_Commands += CLCOUNT_COPY; - } - - SetResourceFenceValue(dstResource, m_CurrentFenceValue, CMDTYPE_WRITE); - SetResourceFenceValue(srcResource, m_CurrentFenceValue, CMDTYPE_READ); - } - - void CommandList::UpdateSubresourceRegion(Resource& resource, UINT subResource, const D3D12_BOX* box, const void* data, UINT rowPitch, UINT slicePitch) - { - if (resource.InitHasBeenDeferred()) - { - resource.TryStagingUpload(this); - } - - DX12_COMMANDLIST_TIMER_DETAIL("UpdateSubresourceRegion"); - MaxResourceFenceValue(resource, CMDTYPE_ANY); - - ID3D12Resource* res12 = resource.GetD3D12Resource(); - const D3D12_RESOURCE_DESC& desc = resource.GetDesc(); - - // Determine temporary upload buffer size (mostly only pow2-alignment of textures) - UINT64 uploadBufferSize; - D3D12_RESOURCE_DESC uploadDesc = desc; - - uploadDesc.Width = box ? box->right - box->left : uploadDesc.Width; - uploadDesc.Height = box ? box->bottom - box->top : uploadDesc.Height; - - GetDevice()->GetD3D12Device()->GetCopyableFootprints(&uploadDesc, subResource, 1, 0, nullptr, nullptr, nullptr, &uploadBufferSize); - - DX12_ASSERT((desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER) || (box == nullptr), "Box used for buffer update, that's not supported!"); - DX12_ASSERT((desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) || (slicePitch != 0), "Slice-pitch is missing for UpdateSubresourceRegion(), this is a required parameter!"); - ID3D12Resource* uploadBuffer; - - D3D12_SUBRESOURCE_DATA subData; - ZeroMemory(&subData, sizeof(D3D12_SUBRESOURCE_DATA)); - subData.pData = data; - subData.RowPitch = rowPitch; - subData.SlicePitch = slicePitch; - assert(subData.pData != nullptr); - - ResourceStates resourceStates; - const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_UPLOAD); - const CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize); - if (S_OK != GetDevice()->CreateOrReuseCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_GRAPHICS_PPV_ARGS(&uploadBuffer), - resourceStates)) - { - DX12_ERROR("Could not create intermediate upload buffer!"); - return; - } - - // If it is reused resource, we have to transition the recycled state to new state - AZ_Assert(resourceStates.m_AnnouncedState == -1, "Recycled resource should not be in split state"); - QueueTransitionBarrier(uploadBuffer, resourceStates.m_CurrentState, D3D12_RESOURCE_STATE_GENERIC_READ); - QueueTransitionBarrier(resource, D3D12_RESOURCE_STATE_COPY_DEST); - FlushBarriers(); - - ::UpdateSubresources<1>(m_CommandList, res12, uploadBuffer, 0, subResource, 1, &subData, box); - m_Commands += CLCOUNT_COPY; - - SetResourceFenceValue(resource, m_CurrentFenceValue, CMDTYPE_WRITE); - - uploadBuffer->SetName(L"UpdateSubresourceRegion"); - GetDevice()->ReleaseLater(uploadBuffer, D3D12_RESOURCE_STATE_GENERIC_READ, static_cast(-1)); - } - - void CommandList::UpdateSubresources(Resource& resource, UINT64 uploadBufferSize, UINT subResources, D3D12_SUBRESOURCE_DATA* subResourceData) - { - if (resource.InitHasBeenDeferred()) - { - resource.TryStagingUpload(this); - } - - DX12_COMMANDLIST_TIMER_DETAIL("UpdateSubresources"); - MaxResourceFenceValue(resource, CMDTYPE_ANY); - - ID3D12Resource* res12 = resource.GetD3D12Resource(); - ID3D12Resource* uploadBuffer = NULL; - ResourceStates resourceStates; - const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_UPLOAD); - const CD3DX12_RESOURCE_DESC resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize); - if (S_OK != GetDevice()->CreateOrReuseCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_GRAPHICS_PPV_ARGS(&uploadBuffer), - resourceStates)) - { - DX12_ERROR("Could not create intermediate upload buffer!"); - } - - // If it is reused resource, we have to transition the recycled state to new state - AZ_Assert(resourceStates.m_AnnouncedState == -1, "Recycled resource should not be in split state"); - QueueTransitionBarrier(uploadBuffer, resourceStates.m_CurrentState, D3D12_RESOURCE_STATE_GENERIC_READ); - QueueTransitionBarrier(resource, D3D12_RESOURCE_STATE_COPY_DEST); - FlushBarriers(); - - ::UpdateSubresources(m_CommandList, res12, uploadBuffer, 0, 0, subResources, subResourceData, nullptr); - m_Commands += CLCOUNT_COPY; - - SetResourceFenceValue(resource, m_CurrentFenceValue, CMDTYPE_WRITE); - - uploadBuffer->SetName(L"UpdateSubresources"); - GetDevice()->ReleaseLater(uploadBuffer, D3D12_RESOURCE_STATE_GENERIC_READ, static_cast(-1)); - } - - void CommandList::DiscardResource(Resource& resource, const D3D12_DISCARD_REGION* pRegion) - { - DX12_COMMANDLIST_TIMER_DETAIL("DiscardResource"); - FlushBarriers(); - MaxResourceFenceValue(resource, CMDTYPE_ANY); - - m_CommandList->DiscardResource(resource.GetD3D12Resource(), pRegion); - m_Commands += CLCOUNT_DISCARD; - } - - void CommandList::QueueTransitionBarrier(Resource& resource, D3D12_RESOURCE_STATES finalState) - { - if (resource.IsOffCard()) - { - if (finalState != D3D12_RESOURCE_STATE_COMMON) - { - finalState = resource.GetRequiredResourceState(); - } - } - - D3D12_RESOURCE_STATES currentState = resource.GetCurrentState(); - D3D12_RESOURCE_STATES announcedState = resource.GetAnnouncedState(); - bool bFinishedSplit = false; - - // Finish a split barrier. - if (announcedState != static_cast(-1)) - { - m_Commands += CLCOUNT_BARRIER; - - //AZ_Printf("DX12", "QueueTransitionBarrier: Split END %p %s -> %s", resource.GetD3D12Resource(), StateToString(currentState), StateToString(announcedState)); - - D3D12_RESOURCE_TRANSITION_BARRIER transition; - transition.pResource = resource.GetD3D12Resource(); - transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - transition.StateBefore = currentState; - transition.StateAfter = announcedState; - m_BarrierCache.EnqueueTransition(m_CommandList, D3D12_RESOURCE_BARRIER_FLAG_END_ONLY, transition); - - resource.SetAnnouncedState(static_cast(-1)); - currentState = announcedState; - resource.SetCurrentState(currentState); - bFinishedSplit = true; - } - - // Now check if we still need to transition to final state. - if (currentState != finalState) - { - //AZ_Printf("DX12", "QueueTransitionBarrier: Transition %p %s -> %s", resource.GetD3D12Resource(), StateToString(currentState), StateToString(finalState)); - - m_Commands += CLCOUNT_BARRIER; - - D3D12_RESOURCE_TRANSITION_BARRIER transition; - transition.pResource = resource.GetD3D12Resource(); - transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - transition.StateBefore = currentState; - transition.StateAfter = finalState; - m_BarrierCache.EnqueueTransition(m_CommandList, D3D12_RESOURCE_BARRIER_FLAG_NONE, transition); - - resource.SetCurrentState(finalState); - } - - // Only need UAV barrier if we didn't do a split transition here. - else if (finalState == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && !bFinishedSplit) - { - QueueUAVBarrier(resource); - } - } - - - void CommandList::QueueTransitionBarrierBegin(Resource& resource, D3D12_RESOURCE_STATES finalState) - { - if (resource.IsOffCard()) - { - if (finalState != D3D12_RESOURCE_STATE_COMMON) - { - finalState = resource.GetRequiredResourceState(); - } - } - - if (resource.GetAnnouncedState() != static_cast(-1)) - { - QueueTransitionBarrier(resource, resource.GetAnnouncedState()); - } - - D3D12_RESOURCE_STATES stateInitial = resource.GetCurrentState(); - D3D12_RESOURCE_STATES stateAnnounced = resource.GetAnnouncedState(); - - if (stateInitial != finalState && stateAnnounced != finalState) - { - m_Commands += CLCOUNT_BARRIER; - - //AZ_Printf("DX12", "QueueTransitionBarrierBegin: Split Barrier BEGIN %p %s -> %s", resource.GetD3D12Resource(), StateToString(stateInitial), StateToString(finalState)); - - D3D12_RESOURCE_TRANSITION_BARRIER transition; - transition.pResource = resource.GetD3D12Resource(); - transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - transition.StateBefore = stateInitial; - transition.StateAfter = finalState; - - m_BarrierCache.EnqueueTransition(m_CommandList, D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY, transition); - - resource.SetAnnouncedState(finalState); - } - } - - void CommandList::QueueUAVBarrier(Resource& resource) - { - m_Commands += CLCOUNT_BARRIER; - - m_BarrierCache.EnqueueUAV(m_CommandList, resource); - } - - void CommandList::FlushBarriers() - { - if (m_BarrierCache.IsFlushNeeded()) - { - DX12_COMMANDLIST_TIMER_DETAIL("FlushBarriers"); - m_BarrierCache.Flush(m_CommandList); - } - } - - void CommandList::QueueTransitionBarrier(ID3D12Resource* resource, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter) - { - if (stateBefore == stateAfter) - return; - - D3D12_RESOURCE_TRANSITION_BARRIER transition; - transition.pResource = resource; - transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - transition.StateBefore = stateBefore; - transition.StateAfter = stateAfter; - - m_BarrierCache.EnqueueTransition(m_CommandList, D3D12_RESOURCE_BARRIER_FLAG_NONE, transition); - } - - CommandListPool::CommandListPool(Device* device, CommandListFenceSet& rCmdFence, int nPoolFenceId) - : m_pDevice(device) - , m_rCmdFences(rCmdFence) - , m_nPoolFenceId(nPoolFenceId) - { -#ifdef DX12_STATS - m_PeakNumCommandListsAllocated = 0; - m_PeakNumCommandListsInFlight = 0; - m_NumWaitsGPU = 0; - m_NumWaitsCPU = 0; -#endif // DX12_STATS - } - - CommandListPool::~CommandListPool() - { - } - - bool CommandListPool::Init(D3D12_COMMAND_LIST_TYPE eType) - { - if (!m_pCmdQueue) - { - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.Type = m_ePoolType = eType; - queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; - queueDesc.NodeMask = 0; // One GPU? - - ID3D12CommandQueue* pCmdQueue = NULL; - if (S_OK != m_pDevice->GetD3D12Device()->CreateCommandQueue(&queueDesc, IID_GRAPHICS_PPV_ARGS(&pCmdQueue))) - { - DX12_ERROR("Could not create command queue"); - return false; - } - - m_pCmdQueue = pCmdQueue; - pCmdQueue->Release(); - - EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, EventTrace::GpuDetailThreadId, EventTrace::GpuDetailName); - } - - m_AsyncCommandQueue.Init(this); - -#ifdef DX12_STATS - m_PeakNumCommandListsAllocated = 0; - m_PeakNumCommandListsInFlight = 0; -#endif // DX12_STATS - - return true; - } - - void CommandListPool::ScheduleCommandLists() - { - // Remove finished command-lists from the head of the live-list - while (m_LiveCommandLists.size()) - { - SmartPtr pCmdList = m_LiveCommandLists.front(); - - // free -> complete -> submitted -> finished -> clearing -> free - if (pCmdList->IsFinished() && !pCmdList->IsClearing()) - { - m_LiveCommandLists.pop_front(); - m_BusyCommandLists.push_back(pCmdList); - - pCmdList->Clear(); - } - else - { - break; - } - } - - // Submit completed but not yet submitted command-lists from the head of the live-list - for (uint32 t = 0; t < m_LiveCommandLists.size(); ++t) - { - SmartPtr pCmdList = m_LiveCommandLists[t]; - - if (pCmdList->IsScheduled() && !pCmdList->IsSubmitted()) - { - pCmdList->Submit(); - } - - if (!pCmdList->IsSubmitted()) - { - break; - } - } - - // Remove cleared/deallocated command-lists from the head of the busy-list - while (m_BusyCommandLists.size()) - { - SmartPtr pCmdList = m_BusyCommandLists.front(); - - // free -> complete -> submitted -> finished -> clearing -> free - if (pCmdList->IsFree()) - { - m_BusyCommandLists.pop_front(); - m_FreeCommandLists.push_back(pCmdList); - } - else - { - break; - } - } - } - - void CommandListPool::CreateOrReuseCommandList(SmartPtr& result) - { - if (m_FreeCommandLists.empty()) - { - result = new CommandList(*this); - } - else - { - result = m_FreeCommandLists.front(); - - m_FreeCommandLists.pop_front(); - } - - // Increment fence value on allocation, this has the effect that - // acquired CommandLists need to be submitted in-order to prevent - // dead-locking - SetCurrentFenceValue(GetCurrentFenceValue() + 1); - - result->Init(GetCurrentFenceValue()); - m_LiveCommandLists.push_back(result); - -#ifdef DX12_STATS - m_PeakNumCommandListsAllocated = std::max(m_PeakNumCommandListsAllocated, m_LiveCommandLists.size() + m_BusyCommandLists.size() + m_FreeCommandLists.size()); - m_PeakNumCommandListsInFlight = std::max(m_PeakNumCommandListsInFlight, m_LiveCommandLists.size()); -#endif // DX12_STATS - } - - void CommandListPool::AcquireCommandList(SmartPtr& result) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - ScheduleCommandLists(); - - CreateOrReuseCommandList(result); - } - - void CommandListPool::ForfeitCommandList(SmartPtr& result, bool bWait) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - SmartPtr pWaitable = result; - - DX12_ASSERT(result->IsCompleted(), "It's not possible to forfeit an unclosed command list!"); - result->Schedule(); - result = nullptr; - - ScheduleCommandLists(); - - if (bWait) - { - pWaitable->WaitForFinishOnCPU(); - } - } - - void CommandListPool::AcquireCommandLists(uint32 numCLs, SmartPtr* results) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - ScheduleCommandLists(); - - for (uint32 i = 0; i < numCLs; ++i) - { - CreateOrReuseCommandList(results[i]); - } - } - - void CommandListPool::ForfeitCommandLists(uint32 numCLs, SmartPtr* results, bool bWait) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - SmartPtr pWaitable = results[numCLs - 1]; - - for (uint32 i = 0; i < numCLs; ++i) - { - DX12_ASSERT(results[i]->IsCompleted(), "It's not possible to forfeit an unclosed command list!"); - results[i]->Schedule(); - results[i] = nullptr; - } - - ScheduleCommandLists(); - - if (bWait) - { - pWaitable->WaitForFinishOnCPU(); - } - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.hpp deleted file mode 100644 index 7a36d78341..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandList.hpp +++ /dev/null @@ -1,641 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12CommandListFence.hpp" -#include "DX12PSO.hpp" -#include "DX12DescriptorHeap.hpp" -#include "DX12QueryHeap.hpp" -#include "DX12View.hpp" -#include "DX12SamplerState.hpp" -#include "DX12AsyncCommandQueue.hpp" -#include "DX12Resource.hpp" -#include "DX12ResourceBarrierCache.h" -#include "DX12TimerHeap.h" - -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12COMMANDLIST_HPP_SECTION_1 1 -#endif - -namespace DX12 -{ - class CommandList; - - class CommandListPool - { - public: - CommandListPool(Device* device, CommandListFenceSet& rCmdFence, int nPoolFenceId); - ~CommandListPool(); - - bool Init(D3D12_COMMAND_LIST_TYPE eType = D3D12_COMMAND_LIST_TYPE_DIRECT); - void AcquireCommandList(SmartPtr & result); - void ForfeitCommandList(SmartPtr & result, bool bWait = false); - void AcquireCommandLists(uint32 numCLs, SmartPtr * results); - void ForfeitCommandLists(uint32 numCLs, SmartPtr * results, bool bWait = false); - - inline ID3D12CommandQueue* GetD3D12CommandQueue() const - { - return m_pCmdQueue; - } - - inline D3D12_COMMAND_LIST_TYPE GetD3D12QueueType() const - { - return m_ePoolType; - } - - inline DX12::AsyncCommandQueue& GetAsyncCommandQueue() - { - return m_AsyncCommandQueue; - } - - inline Device* GetDevice() const - { - return m_pDevice; - } - - inline CommandListFenceSet& GetFences() - { - return m_rCmdFences; - } - - inline ID3D12Fence** GetD3D12Fences() const - { - return m_rCmdFences.GetD3D12Fences(); - } - - inline ID3D12Fence* GetD3D12Fence() const - { - return m_rCmdFences.GetD3D12Fence(m_nPoolFenceId); - } - - inline int GetFenceID() const - { - return m_nPoolFenceId; - } - - inline void SetSubmittedFenceValue(const UINT64 fenceValue) - { - return m_rCmdFences.SetSubmittedValue(fenceValue, m_nPoolFenceId); - } - - inline UINT64 GetSubmittedFenceValue() const - { - return m_rCmdFences.GetSubmittedValue(m_nPoolFenceId); - } - - private: - inline void SetCurrentFenceValue(const UINT64 fenceValue) - { - return m_rCmdFences.SetCurrentValue(fenceValue, m_nPoolFenceId); - } - - public: - inline UINT64 GetLastCompletedFenceValue() const - { - return m_rCmdFences.GetLastCompletedFenceValue(m_nPoolFenceId); - } - - inline UINT64 GetCurrentFenceValue() const - { - return m_rCmdFences.GetCurrentValue(m_nPoolFenceId); - } - - inline void WaitForFenceOnGPU(const std::atomic (&fenceValues)[CMDQUEUE_NUM]) - { - // The pool which waits for the fence can be omitted (in-order-execution) - UINT64 fenceValuesMasked[CMDQUEUE_NUM]; - - fenceValuesMasked[CMDQUEUE_COPY ] = fenceValues[CMDQUEUE_COPY ]; - fenceValuesMasked[CMDQUEUE_GRAPHICS] = fenceValues[CMDQUEUE_GRAPHICS]; - fenceValuesMasked[m_nPoolFenceId ] = 0; - - if (!m_rCmdFences.IsCompleted(fenceValuesMasked)) - { - DX12_LOG("Waiting for GPU fences (type: %d) [%d,%d] -> [%d,%d]", - m_nPoolFenceId, - m_rCmdFences.GetD3D12Fence(CMDQUEUE_COPY)->GetCompletedValue(), - m_rCmdFences.GetD3D12Fence(CMDQUEUE_GRAPHICS)->GetCompletedValue(), - static_cast(fenceValues[CMDQUEUE_COPY ]), - static_cast(fenceValues[CMDQUEUE_GRAPHICS])); -#ifdef DX12_STATS - m_NumWaitsGPU += 2; -#endif // DX12_STATS - - m_AsyncCommandQueue.Wait(m_rCmdFences.GetD3D12Fences(), fenceValuesMasked); - } - } - - inline void WaitForFenceOnGPU(const UINT64 fenceValue, const int id) - { - if (!m_rCmdFences.IsCompleted(fenceValue, id)) - { - DX12_LOG("Waiting for GPU fence %d -> %d", m_rCmdFences.GetD3D12Fence(id)->GetCompletedValue(), fenceValue); - -#ifdef DX12_STATS - m_NumWaitsGPU++; -#endif // DX12_STATS - - m_AsyncCommandQueue.Wait(m_rCmdFences.GetD3D12Fence(id), fenceValue); - } - } - - inline void WaitForFenceOnGPU(const UINT64 fenceValue) - { - return WaitForFenceOnGPU(fenceValue, m_nPoolFenceId); - } - - inline void WaitForFenceOnCPU(const std::atomic (&fenceValues)[CMDQUEUE_NUM]) const - { - AZ_TRACE_METHOD(); - UINT64 fenceValuesCopied[CMDQUEUE_NUM]; - - fenceValuesCopied[CMDQUEUE_COPY ] = fenceValues[CMDQUEUE_COPY ]; - fenceValuesCopied[CMDQUEUE_GRAPHICS] = fenceValues[CMDQUEUE_GRAPHICS]; - - if (!m_rCmdFences.IsCompleted(fenceValuesCopied)) - { -#ifdef DX12_STATS - m_NumWaitsCPU += 2; -#endif // DX12_STATS - - m_rCmdFences.WaitForFence(fenceValuesCopied); - } - } - - inline void WaitForFenceOnCPU(const UINT64 fenceValue, const int id) const - { - if (!m_rCmdFences.IsCompleted(fenceValue, id)) - { -#ifdef DX12_STATS - m_NumWaitsCPU++; -#endif // DX12_STATS - - m_rCmdFences.WaitForFence(fenceValue, id); - } - } - - inline void WaitForFenceOnCPU(const UINT64 fenceValue) const - { - return WaitForFenceOnCPU(fenceValue, m_nPoolFenceId); - } - - inline bool IsCompleted(const std::atomic (&fenceValues)[CMDQUEUE_NUM]) const - { - // The pool which checks for the fence can be omitted (in-order-execution) - UINT64 fenceValuesMasked[CMDQUEUE_NUM]; - - fenceValuesMasked[CMDQUEUE_COPY ] = fenceValues[CMDQUEUE_COPY ]; - fenceValuesMasked[CMDQUEUE_GRAPHICS] = fenceValues[CMDQUEUE_GRAPHICS]; - fenceValuesMasked[m_nPoolFenceId ] = 0; - - return m_rCmdFences.IsCompleted(fenceValuesMasked); - } - - inline bool IsCompleted(const UINT64 fenceValue, const int id) const - { - return m_rCmdFences.IsCompleted(fenceValue, id); - } - - inline bool IsCompleted(const UINT64 fenceValue) const - { - return IsCompleted(fenceValue, m_nPoolFenceId); - } - - private: - void ScheduleCommandLists(); - void CreateOrReuseCommandList(SmartPtr & result); - - Device* m_pDevice; - CommandListFenceSet& m_rCmdFences; - int m_nPoolFenceId; - D3D12_COMMAND_LIST_TYPE m_ePoolType; - - typedef std::deque> TCommandLists; - TCommandLists m_LiveCommandLists; - TCommandLists m_BusyCommandLists; - TCommandLists m_FreeCommandLists; - - SmartPtr m_pCmdQueue; - DX12::AsyncCommandQueue m_AsyncCommandQueue; - -#ifdef DX12_STATS - size_t m_NumWaitsGPU; - mutable size_t m_NumWaitsCPU; - size_t m_PeakNumCommandListsAllocated; - size_t m_PeakNumCommandListsInFlight; -#endif // DX12_STATS - }; - - class CommandList - : public DeviceObject - { - friend class CommandListPool; - - public: - virtual ~CommandList(); - - bool Init(UINT64 currentFenceValue); - bool Reset(); - - inline ID3D12GraphicsCommandList* GetD3D12CommandList() const - { - return m_CommandList; - } - inline D3D12_COMMAND_LIST_TYPE GetD3D12ListType() const - { - return m_eListType; - } - inline ID3D12CommandAllocator* GetD3D12CommandAllocator() const - { - return m_pCmdAllocator; - } - inline ID3D12CommandQueue* GetD3D12CommandQueue() const - { - return m_pCmdQueue; - } - inline CommandListPool& GetCommandListPool() const - { - return m_rPool; - } - - // Stage 1 - inline bool IsFree() const - { - return m_State == CLSTATE_FREE; - } - - // Stage 2 - void Begin(); - inline bool IsUtilized() const - { -#define CLCOUNT_DRAW 1 -#define CLCOUNT_DISPATCH 1 -#define CLCOUNT_COPY 1 -#define CLCOUNT_CLEAR 1 -#define CLCOUNT_DISCARD 1 -#define CLCOUNT_BARRIER 1 -#define CLCOUNT_QUERY 1 -#define CLCOUNT_QUERY_TIMESTAMP 0 -#define CLCOUNT_RESOLVE 1 -#define CLCOUNT_SETIO 0 -#define CLCOUNT_SETSTATE 0 - - return m_Commands > 0; - } - - void End(); - inline bool IsCompleted() const - { - return m_State >= CLSTATE_COMPLETED; - } - - void Schedule(); - inline bool IsScheduled() const - { - return m_State == CLSTATE_SCHEDULED; - } - - // Stage 3 - UINT64 SignalFenceOnGPU() - { - DX12_LOG("Signaling fence value on GPU (%d) : %d", m_rPool.GetFenceID(), m_CurrentFenceValue); - m_rPool.GetAsyncCommandQueue().Signal(m_rPool.GetD3D12Fence(), m_CurrentFenceValue); - return m_CurrentFenceValue; - } - - UINT64 SignalFenceOnCPU() - { - DX12_LOG("Signaling fence value on CPU: %d", m_CurrentFenceValue); - m_rPool.GetD3D12Fence()->Signal(m_CurrentFenceValue); - return m_CurrentFenceValue; - } - - void Submit(); - inline bool IsSubmitted() const - { - return m_State >= CLSTATE_SUBMITTED; - } - - // Stage 4 - void WaitForFinishOnGPU() - { - DX12_ASSERT(m_State == CLSTATE_SUBMITTED, "GPU fence waits for itself to be complete: deadlock imminent!"); - m_rPool.WaitForFenceOnGPU(m_CurrentFenceValue); - } - - void WaitForFinishOnCPU() const - { - DX12_ASSERT(m_State == CLSTATE_SUBMITTED, "CPU fence waits for itself to be complete: deadlock imminent!"); - m_rPool.WaitForFenceOnCPU(m_CurrentFenceValue); - } - - inline bool IsFinished() const - { - if ((m_State == CLSTATE_SUBMITTED) && m_rPool.IsCompleted(m_CurrentFenceValue)) - { - m_State = CLSTATE_FINISHED; - } - - return m_State == CLSTATE_FINISHED; - } - - inline UINT64 GetCurrentFenceValue() const - { - return m_CurrentFenceValue; - } - - // Stage 5 - void Clear(); - inline bool IsClearing() const - { - return m_State == CLSTATE_CLEARING; - } - - void SetPipelineState(const PipelineState* pso); - void SetRootSignature(CommandMode commandMode, const RootSignature* rootSignature); - - void QueueUAVBarrier(Resource& resource); - - void QueueTransitionBarrier(Resource& resource, D3D12_RESOURCE_STATES desiredState); - - void QueueTransitionBarrierBegin(Resource& resource, D3D12_RESOURCE_STATES desiredState); - - void FlushBarriers(); - - // Collect the highest fenceValues of all given Resource to wait before the command-list is finally submitted - inline void MaxResourceFenceValue(Resource& resource, const int type) - { - resource.MaxFenceValues(m_UsedFenceValues, type); - } - - // Mark resource with desired fence value, returns the previous fence value - inline UINT64 SetResourceFenceValue(Resource& resource, const UINT64 fenceValue, const int type) const - { - return resource.SetFenceValue(fenceValue, m_rPool.GetFenceID(), type); - } - - inline void TrackResourceUsage(Resource& resource, D3D12_RESOURCE_STATES stateUsage, int cmdBlocker = CMDTYPE_WRITE, int cmdUsage = CMDTYPE_READ) - { - resource.TryStagingUpload(this); - MaxResourceFenceValue(resource, cmdBlocker); - QueueTransitionBarrier(resource, stateUsage); - SetResourceFenceValue(resource, m_CurrentFenceValue, cmdUsage); - } - - inline void TrackResourceIBVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_INDEX_BUFFER, CMDTYPE_WRITE, CMDTYPE_READ); } - inline void TrackResourceVBVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, CMDTYPE_WRITE, CMDTYPE_READ); } - inline void TrackResourceCBVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, CMDTYPE_WRITE, CMDTYPE_READ); } - inline void TrackResourceSRVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | GetPreserveFlags(resource), CMDTYPE_WRITE, CMDTYPE_READ); } - inline void TrackResourceUAVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS | GetPreserveFlags(resource), CMDTYPE_ANY, CMDTYPE_ANY); } - inline void TrackResourceDSVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_DEPTH_WRITE | GetPreserveFlags(resource), CMDTYPE_ANY, CMDTYPE_WRITE); } - inline void TrackResourceDRVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_DEPTH_READ | GetPreserveFlags(resource), CMDTYPE_WRITE, CMDTYPE_READ); } - inline void TrackResourceRTVUsage(Resource& resource) { TrackResourceUsage(resource, D3D12_RESOURCE_STATE_RENDER_TARGET | GetPreserveFlags(resource), CMDTYPE_ANY, CMDTYPE_WRITE); } - - bool IsFull(size_t numResources, size_t numSamplers, size_t numRendertargets, size_t numDepthStencils) const; - bool IsUsedByOutputViews(const Resource& res) const; - - inline void IncrementInputCursors(size_t numResources, size_t numSamplers) - { - GetResourceHeap().IncrementCursor(numResources); - GetSamplerHeap().IncrementCursor(numSamplers); - } - - inline void IncrementOutputCursors() - { - GetRenderTargetHeap().IncrementCursor(m_CurrentNumRTVs); - if (m_pDSV) - { - GetDepthStencilHeap().IncrementCursor(); - } - } - - void WriteShaderResourceDescriptor(const ResourceView* resourceView, INT descriptorOffset); - void WriteUnorderedAccessDescriptor(const ResourceView* resourceView, INT descriptorOffset); - void WriteConstantBufferDescriptor(const ResourceView* resourceView, INT descriptorOffset, UINT byteOffset, UINT byteCount); - void WriteSamplerStateDescriptor(const SamplerState* state, INT descriptorOffset); - - void BindVertexBufferView(const ResourceView&view, INT offset, const TRange&bindRange, UINT bindStride, D3D12_VERTEX_BUFFER_VIEW (&heap)[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]); - inline void BindVertexBufferView(const ResourceView& view, INT offset, const TRange& bindRange, UINT bindStride) - { - BindVertexBufferView(view, offset, bindRange, bindStride, m_VertexBufferHeap); - } - - void SetConstantBufferView(CommandMode commandMode, UINT RootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS BufferLocation); - void Set32BitConstants(CommandMode commandMode, UINT RootParameterIndex, UINT Num32BitValuesToSet, const void* pSrcData, UINT DestOffsetIn32BitValues); - void SetDescriptorTable(CommandMode commandMode, UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor); - - void SetDescriptorTables(CommandMode commandMode, D3D12_DESCRIPTOR_HEAP_TYPE eType); - - void ClearVertexBufferHeap(UINT num); - void SetVertexBufferHeap(UINT num); - void BindAndSetIndexBufferView(const ResourceView& view, DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN, UINT offset = 0); - - void SetResourceAndSamplerStateHeaps(); - void BindAndSetOutputViews(INT numRTVs, const ResourceView** rtv, const ResourceView* dsv); - - void ClearDepthStencilView(const ResourceView& view, D3D12_CLEAR_FLAGS clearFlags, float depthValue, UINT stencilValue, UINT NumRects = 0U, const D3D12_RECT* pRect = nullptr); - void ClearRenderTargetView(const ResourceView& view, const FLOAT rgba[4], UINT NumRects = 0U, const D3D12_RECT* pRect = nullptr); - void ClearUnorderedAccessView(const ResourceView& view, const UINT rgba[4], UINT NumRects = 0U, const D3D12_RECT* pRect = nullptr); - void ClearUnorderedAccessView(const ResourceView& view, const FLOAT rgba[4], UINT NumRects = 0U, const D3D12_RECT* pRect = nullptr); - void ClearView(const ResourceView& view, const FLOAT rgba[4], UINT NumRects = 0U, const D3D12_RECT* pRect = nullptr); - - void CopyResource(Resource& pDstResource, Resource& pSrcResource); - void CopySubresource(Resource& pDestResource, UINT destSubResource, UINT x, UINT y, UINT z, Resource& pSrcResource, UINT srcSubResource, const D3D12_BOX* srcBox); - void UpdateSubresourceRegion(Resource& resource, UINT subResource, const D3D12_BOX* box, const void* data, UINT rowPitch, UINT depthPitch); - void UpdateSubresources(Resource& rResource, UINT64 uploadBufferSize, UINT subResources, D3D12_SUBRESOURCE_DATA* subResourceData); - void DiscardResource(Resource& resource, const D3D12_DISCARD_REGION* pRegion); - - void PresentRenderTargetView(SwapChain* pDX12SwapChain); - - inline void DrawInstanced(UINT vertexCountPerInstance, UINT instanceCount, UINT startVertexLocation, UINT startInstanceLocation) - { - DX12_COMMANDLIST_TIMER_DETAIL("DrawInstanced"); -#ifdef DX12_STATS - m_NumDraws++; -#endif // DX12_STATS - - FlushBarriers(); - m_CommandList->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation); - m_Commands += CLCOUNT_DRAW; - } - - inline void DrawIndexedInstanced(UINT indexCountPerInstance, UINT instanceCount, UINT startIndexLocation, UINT baseVertexLocation, UINT startInstanceLocation) - { - DX12_COMMANDLIST_TIMER_DETAIL("DrawIndexedInstanced"); -#ifdef DX12_STATS - m_NumDraws++; -#endif // DX12_STATS - - FlushBarriers(); - m_CommandList->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation); - m_Commands += CLCOUNT_DRAW; - } - - inline void Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) - { - DX12_COMMANDLIST_TIMER_DETAIL("Dispatch"); -#ifdef DX12_STATS - m_NumDraws++; -#endif // DX12_STATS - - FlushBarriers(); - m_CommandList->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - m_Commands += CLCOUNT_DISPATCH; - } - - inline void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY topo) - { - m_CommandList->IASetPrimitiveTopology(topo); - m_Commands += CLCOUNT_SETIO; - } - - inline void SetViewports(UINT NumViewports, const D3D12_VIEWPORT* pViewports) - { - m_CommandList->RSSetViewports(NumViewports, pViewports); - m_Commands += CLCOUNT_SETSTATE; - } - - inline void SetScissorRects(UINT NumRects, const D3D12_RECT* pRects) - { - m_CommandList->RSSetScissorRects(NumRects, pRects); - m_Commands += CLCOUNT_SETSTATE; - } - - inline void SetStencilRef(UINT Ref) - { - m_CommandList->OMSetStencilRef(Ref); - m_Commands += CLCOUNT_SETSTATE; - } - - inline void BeginQuery(QueryHeap& queryHeap, D3D12_QUERY_TYPE Type, UINT Index) - { - m_CommandList->BeginQuery(queryHeap.GetD3D12QueryHeap(), Type, Index); - m_Commands += Type == D3D12_QUERY_TYPE_TIMESTAMP ? CLCOUNT_QUERY_TIMESTAMP : CLCOUNT_QUERY; - } - - inline void EndQuery(QueryHeap& queryHeap, D3D12_QUERY_TYPE Type, UINT Index) - { - m_CommandList->EndQuery(queryHeap.GetD3D12QueryHeap(), Type, Index); - m_Commands += Type == D3D12_QUERY_TYPE_TIMESTAMP ? CLCOUNT_QUERY_TIMESTAMP : CLCOUNT_QUERY; - } - - inline void ResolveQueryData(QueryHeap& queryHeap, D3D12_QUERY_TYPE Type, - _In_ UINT StartIndex, - _In_ UINT NumQueries, - _In_ ID3D12Resource* pDestinationBuffer, - _In_ UINT64 AlignedDestinationBufferOffset) - { - m_CommandList->ResolveQueryData(queryHeap.GetD3D12QueryHeap(), Type, StartIndex, NumQueries, pDestinationBuffer, AlignedDestinationBufferOffset); - m_Commands += CLCOUNT_RESOLVE; - } - - private: - CommandList(CommandListPool& pPool); - CommandListPool& m_rPool; - - void ResetStateTracking(CommandMode commandMode); - void BindDepthStencilView(const ResourceView& dsv); - void BindRenderTargetView(const ResourceView& rtv); - - D3D12_RESOURCE_STATES GetPreserveFlags([[maybe_unused]] Resource& resource) - { - D3D12_RESOURCE_STATES preserveFlags = D3D12_RESOURCE_STATES(0U); -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12COMMANDLIST_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12CommandList_hpp) -#endif - return preserveFlags; - } - - void QueueTransitionBarrier(ID3D12Resource* resource, D3D12_RESOURCE_STATES stateBefore, D3D12_RESOURCE_STATES stateAfter); - void SubmitTimers(); - - ID3D12Device* m_pD3D12Device; - SmartPtr m_CommandList; - SmartPtr m_pCmdAllocator; - SmartPtr m_pCmdQueue; - std::atomic m_UsedFenceValues[CMDTYPE_NUM][CMDQUEUE_NUM]; - - ResourceBarrierCache m_BarrierCache; - - // Only used by IsUsedByOutputViews() - const ResourceView* m_pDSV; - const ResourceView* m_pRTV[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; - INT m_CurrentNumRTVs; - - UINT64 m_CurrentFenceValue; - D3D12_COMMAND_LIST_TYPE m_eListType; - - DescriptorBlock m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; - - inline DescriptorBlock& GetResourceHeap () { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]; } - inline DescriptorBlock& GetSamplerHeap () { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]; } - inline DescriptorBlock& GetRenderTargetHeap() { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_RTV]; } - inline DescriptorBlock& GetDepthStencilHeap() { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_DSV]; } - - inline const DescriptorBlock& GetResourceHeap () const { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]; } - inline const DescriptorBlock& GetSamplerHeap () const { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]; } - inline const DescriptorBlock& GetRenderTargetHeap() const { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_RTV]; } - inline const DescriptorBlock& GetDepthStencilHeap() const { return m_DescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_DSV]; } - - UINT m_CurrentNumVertexBuffers; - D3D12_VERTEX_BUFFER_VIEW m_VertexBufferHeap[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - - static const AZ::u32 RootParameterCountMax = 16; - struct RootParameter - { - union - { - D3D12_GPU_VIRTUAL_ADDRESS gpuAddress; - D3D12_GPU_DESCRIPTOR_HANDLE descriptorHandle; - }; - }; - - RootParameter m_CurrentRootParameters[CommandModeCount][RootParameterCountMax]; - const PipelineState* m_CurrentPipelineState; - const RootSignature* m_CurrentRootSignature[CommandModeCount]; - - UINT m_Commands; - mutable enum - { - CLSTATE_FREE, - CLSTATE_STARTED, - CLSTATE_UTILIZED, - CLSTATE_COMPLETED, - CLSTATE_SCHEDULED, - CLSTATE_SUBMITTED, - CLSTATE_FINISHED, - CLSTATE_CLEARING - } - m_State; - - UINT m_nodeMask; - -#ifdef DX12_STATS - size_t m_NumDraws; - size_t m_NumWaitsGPU; - size_t m_NumWaitsCPU; -#endif // DX12_STATS - -#if DX12_GPU_PROFILE_MODE != DX12_GPU_PROFILE_MODE_OFF - TimerHeap m_Timers; - TimerHandle m_TimerHandle; - static const AZ::u32 TimerCountMax = 2048; -#endif - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.cpp deleted file mode 100644 index ec1e384a9a..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12CommandListFence.hpp" -#include "DriverD3D.h" - -#define TRACK_RENDERTREAD_WAIT_TIME SScopedExecutionTimeTracker renderThreadWaitTimeTracker(gcpRendD3D->m_fTimeWaitForGPU[gcpRendD3D->m_RP.m_nProcessThreadID]); - -struct SScopedExecutionTimeTracker -{ - SScopedExecutionTimeTracker(float& var) - : trackerVariable(var) - , startTime(iTimer->GetAsyncTime()) - {} - - ~SScopedExecutionTimeTracker() - { - trackerVariable += iTimer->GetAsyncTime().GetDifferenceInSeconds(startTime); - } - - float& trackerVariable; - CTimeValue startTime; -}; - -namespace DX12 -{ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - CommandListFence::CommandListFence(Device* device) - : m_pDevice(device) - , m_LastCompletedValue(0) - , m_CurrentValue(0) - { - } - - //--------------------------------------------------------------------------------------------------------------------- - CommandListFence::~CommandListFence() - { - m_pFence->Release(); - CloseHandle(m_FenceEvent); - } - - //--------------------------------------------------------------------------------------------------------------------- - bool CommandListFence::Init() - { - ID3D12Fence* fence = NULL; - if (S_OK != m_pDevice->GetD3D12Device()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(&fence))) - { - DX12_ERROR("Could not create fence object!"); - return false; - } - - m_pFence = fence; - m_pFence->Signal(m_LastCompletedValue); - m_FenceEvent = CreateEventEx(NULL, FALSE, FALSE, EVENT_ALL_ACCESS); - - return true; - } - - void CommandListFence::WaitForFence(AZ::u64 fenceValue) - { - if (!IsCompleted(fenceValue)) - { - DX12_LOG("Waiting CPU for fence %d -> %d", m_pFence->GetCompletedValue(), fenceValue); - { - TRACK_RENDERTREAD_WAIT_TIME - - m_pFence->SetEventOnCompletion(fenceValue, m_FenceEvent); - - WaitForSingleObject(m_FenceEvent, INFINITE); - } - DX12_LOG("Completed fence value: %d", m_pFence->GetCompletedValue()); - - AdvanceCompletion(); - } - } - - //--------------------------------------------------------------------------------------------------------------------- - CommandListFenceSet::CommandListFenceSet(Device* device) - : m_pDevice(device) - { - m_LastCompletedValues[CMDQUEUE_COPY ] = - m_LastCompletedValues[CMDQUEUE_GRAPHICS] = 0; - m_SubmittedValues[CMDQUEUE_COPY] = - m_SubmittedValues[CMDQUEUE_GRAPHICS] = 0; - m_CurrentValues[CMDQUEUE_COPY ] = - m_CurrentValues[CMDQUEUE_GRAPHICS] = 0; - } - - //--------------------------------------------------------------------------------------------------------------------- - CommandListFenceSet::~CommandListFenceSet() - { - for (int i = 0; i < CMDQUEUE_NUM; ++i) - { - m_pFences[i]->Release(); - - CloseHandle(m_FenceEvents[i]); - } - } - - //--------------------------------------------------------------------------------------------------------------------- - bool CommandListFenceSet::Init() - { - for (int i = 0; i < CMDQUEUE_NUM; ++i) - { - ID3D12Fence* fence = NULL; - if (S_OK != m_pDevice->GetD3D12Device()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_GRAPHICS_PPV_ARGS(&fence))) - { - DX12_ERROR("Could not create fence object!"); - return false; - } - - m_pFences[i] = fence; - m_pFences[i]->Signal(m_LastCompletedValues[i]); - m_FenceEvents[i] = CreateEventEx(NULL, FALSE, FALSE, EVENT_ALL_ACCESS); - } - - return true; - } - - void CommandListFenceSet::WaitForFence(const AZ::u64 fenceValue, const int id) const - { - DX12_LOG("Waiting CPU for fence %d -> %d", m_pFences[id]->GetCompletedValue(), fenceValue); - - { - TRACK_RENDERTREAD_WAIT_TIME - - m_pFences[id]->SetEventOnCompletion(fenceValue, m_FenceEvents[id]); - - WaitForSingleObject(m_FenceEvents[id], INFINITE); - } - - DX12_LOG("Completed fence value: %d", m_pFences[id]->GetCompletedValue()); - - AdvanceCompletion(id); - } - - void CommandListFenceSet::WaitForFence(const AZ::u64 (&fenceValues)[CMDQUEUE_NUM]) const - { - // TODO: the pool which waits for the fence can be omitted (in-order-execution) - DX12_LOG("Waiting for GPU fences [%d,%d] -> [%d,%d]", - m_pFences[CMDQUEUE_COPY ]->GetCompletedValue(), - m_pFences[CMDQUEUE_GRAPHICS]->GetCompletedValue(), - fenceValues[CMDQUEUE_COPY ], - fenceValues[CMDQUEUE_GRAPHICS]); - - { - TRACK_RENDERTREAD_WAIT_TIME - - // NOTE: event does ONLY trigger when the value has been set (it'll lock when trying with 0) - int numObjects = 0; - for (int id = 0; id < CMDQUEUE_NUM; ++id) - { - if (fenceValues[id] && (m_LastCompletedValues[id] < fenceValues[id])) - { - m_pFences[id]->SetEventOnCompletion(fenceValues[id], m_FenceEvents[numObjects++]); - } - } - - WaitForMultipleObjects(numObjects, m_FenceEvents, true, INFINITE); - } - - DX12_LOG("Completed GPU fences [%d,%d]", - m_pFences[CMDQUEUE_COPY ]->GetCompletedValue(), - m_pFences[CMDQUEUE_GRAPHICS]->GetCompletedValue()); - - AdvanceCompletion(); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.hpp deleted file mode 100644 index cbf796ea5b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12CommandListFence.hpp +++ /dev/null @@ -1,274 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#define CMDQUEUE_GRAPHICS 0 -#define CMDQUEUE_COPY 1 -#define CMDQUEUE_NUM 2 - -#define CMDTYPE_READ 0 -#define CMDTYPE_WRITE 1 -#define CMDTYPE_ANY 2 -#define CMDTYPE_NUM 3 - -#include "DX12Device.hpp" - -namespace std -{ - inline AZ::u64 (& max(const AZ::u64 (&a)[CMDQUEUE_NUM], const AZ::u64 (&b)[CMDQUEUE_NUM], AZ::u64 (&c)[CMDQUEUE_NUM]))[CMDQUEUE_NUM] - { - c[CMDQUEUE_COPY ] = max(a[CMDQUEUE_COPY ], b[CMDQUEUE_COPY ]); - c[CMDQUEUE_GRAPHICS] = max(a[CMDQUEUE_GRAPHICS], b[CMDQUEUE_GRAPHICS]); - - return c; - } -} - -namespace DX12 -{ - inline AZ::u64 MaxFenceValue(std::atomic& a, const AZ::u64& b) - { - AZ::u64 utilizedValue = b; - AZ::u64 previousValue = a; - while (previousValue < utilizedValue && - !a.compare_exchange_weak(previousValue, utilizedValue)) - { - ; - } - - return previousValue; - } - - inline AZ::u64 (& MaxFenceValues(const std::atomic (&a)[CMDQUEUE_NUM], const std::atomic (&b)[CMDQUEUE_NUM], AZ::u64 (&c)[CMDQUEUE_NUM]))[CMDQUEUE_NUM] - { - c[CMDQUEUE_COPY ] = std::max(a[CMDQUEUE_COPY ], b[CMDQUEUE_COPY ]); - c[CMDQUEUE_GRAPHICS] = std::max(a[CMDQUEUE_GRAPHICS], b[CMDQUEUE_GRAPHICS]); - - return c; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - class CommandListFence - { - public: - CommandListFence(Device* device); - ~CommandListFence(); - - bool Init(); - - inline ID3D12Fence* GetFence() const - { - return m_pFence; - } - - inline AZ::u64 GetCurrentValue() const - { - return m_CurrentValue; - } - - inline void SetCurrentValue(AZ::u64 fenceValue) - { -#ifdef DX12_IN_ORDER_ACQUIRATION - DX12_ASSERT(m_CurrentValue <= fenceValue, "Setting new fence value which is older than the current!"); - // We do not allow smaller fences being submitted, and fences always submit in-order, no max() neccessary - m_CurrentValue = fenceValue; -#else - // CLs may submit in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_CurrentValue, fenceValue); -#endif // !NDEBUG - } - - inline bool IsCompleted(AZ::u64 fenceValue) const - { - // Check against last known completed value first to avoid unnecessary fence read - return - (m_LastCompletedValue >= fenceValue) || (AdvanceCompletion() >= fenceValue); - } - - void WaitForFence(AZ::u64 fenceValue); - - inline AZ::u64 AdvanceCompletion() const - { - // Check current completed fence - AZ::u64 currentCompletedValue = m_pFence->GetCompletedValue(); - - if (m_LastCompletedValue < currentCompletedValue) - { - DX12_LOG("Completed fence value(s): %d to %d", m_LastCompletedValue + 1, currentCompletedValue); - } - -#ifdef DX12_IN_ORDER_TERMINATION - DX12_ASSERT(m_LastCompletedValue <= currentCompletedValue, "Getting new fence value which is older than the last!"); - // We do not allow smaller fences being submitted, and fences always complete in-order, no max() neccessary - m_LastCompletedValue = currentCompletedValue; -#else - // CLs may terminate in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_LastCompletedValue, currentCompletedValue); -#endif // !NDEBUG - - return currentCompletedValue; - } - - inline AZ::u64 GetLastCompletedFenceValue() const - { - return m_LastCompletedValue; - } - - private: - Device* m_pDevice; - ID3D12Fence* m_pFence; - HANDLE m_FenceEvent; - - std::atomic m_CurrentValue; - mutable std::atomic m_LastCompletedValue; - }; - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - class CommandListFenceSet - { - public: - CommandListFenceSet(Device* device); - ~CommandListFenceSet(); - - bool Init(); - - inline ID3D12Fence** GetD3D12Fences() - { - return m_pFences; - } - - inline ID3D12Fence* GetD3D12Fence(const int id) const - { - return m_pFences[id]; - } - - inline AZ::u64 GetSubmittedValue(const int id) const - { - return m_SubmittedValues[id]; - } - - inline void SetSubmittedValue(const AZ::u64 fenceValue, const int id) - { -#ifdef DX12_IN_ORDER_SUBMISSION - DX12_ASSERT(m_SubmittedValues[id] <= fenceValue, "Setting new fence value which is older than the submitted!"); - // We do not allow smaller fences being submitted, and fences always submit in-order, no max() neccessary - m_SubmittedValues[id] = fenceValue; -#else - // CLs may submit in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_SubmittedValues[id], fenceValue); -#endif // !NDEBUG - } - - inline AZ::u64 GetCurrentValue(const int id) const - { - return m_CurrentValues[id]; - } - - inline void GetCurrentValues(AZ::u64 (&fenceValues)[CMDQUEUE_NUM]) const - { - fenceValues[CMDQUEUE_COPY ] = m_CurrentValues[CMDQUEUE_COPY ]; - fenceValues[CMDQUEUE_GRAPHICS] = m_CurrentValues[CMDQUEUE_GRAPHICS]; - } - - inline const std::atomic (& GetCurrentValues() const)[CMDQUEUE_NUM] - { - return m_CurrentValues; - } - - // thread-save - inline void SetCurrentValue(const AZ::u64 fenceValue, const int id) - { -#ifdef DX12_IN_ORDER_ACQUIRATION - DX12_ASSERT(m_CurrentValues[id] <= fenceValue, "Setting new fence value which is older than the current!"); - // We do not allow smaller fences being submitted, and fences always submit in-order, no max() neccessary - m_CurrentValues[id] = fenceValue; -#else - // CLs may submit in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_CurrentValues[id], fenceValue); -#endif // !NDEBUG - } - - inline bool IsCompleted(const AZ::u64 fenceValue, const int id) const - { - // Check against last known completed value first to avoid unnecessary fence read - return - (m_LastCompletedValues[id] >= fenceValue) || (AdvanceCompletion(id) >= fenceValue); - } - - inline bool IsCompleted(const AZ::u64 (&fenceValues)[CMDQUEUE_NUM]) const - { - // Check against last known completed value first to avoid unnecessary fence read - return - // TODO: return mask of completed fences so we don't check all three of them all the time - ((m_LastCompletedValues[CMDQUEUE_COPY ] >= fenceValues[CMDQUEUE_COPY ]) || (AdvanceCompletion(CMDQUEUE_COPY) >= fenceValues[CMDQUEUE_COPY ])) & - ((m_LastCompletedValues[CMDQUEUE_GRAPHICS] >= fenceValues[CMDQUEUE_GRAPHICS]) || (AdvanceCompletion(CMDQUEUE_GRAPHICS) >= fenceValues[CMDQUEUE_GRAPHICS])); - } - - void WaitForFence(const AZ::u64 fenceValue, const int id) const; - void WaitForFence(const AZ::u64 (&fenceValues)[CMDQUEUE_NUM]) const; - - inline AZ::u64 AdvanceCompletion(const int id) const - { - // Check current completed fence - AZ::u64 currentCompletedValue = m_pFences[id]->GetCompletedValue(); - - if (m_LastCompletedValues[id] < currentCompletedValue) - { - DX12_LOG("Completed fence value(s): %d to %d", m_LastCompletedValues[id] + 1, currentCompletedValue); - } - -#ifdef DX12_IN_ORDER_TERMINATION - DX12_ASSERT(m_LastCompletedValues[id] <= currentCompletedValue, "Getting new fence value which is older than the last!"); - // We do not allow smaller fences being submitted, and fences always complete in-order, no max() neccessary - m_LastCompletedValues[id] = currentCompletedValue; -#else - // CLs may terminate in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_LastCompletedValues[id], currentCompletedValue); -#endif // !NDEBUG - - return currentCompletedValue; - } - - inline void AdvanceCompletion() const - { - AdvanceCompletion(CMDQUEUE_COPY); - AdvanceCompletion(CMDQUEUE_GRAPHICS); - } - - inline AZ::u64 GetLastCompletedFenceValue(const int id) const - { - return m_LastCompletedValues[id]; - } - - inline void GetLastCompletedFenceValues(AZ::u64 (&fenceValues)[CMDQUEUE_NUM]) const - { - fenceValues[CMDQUEUE_COPY ] = m_LastCompletedValues[CMDQUEUE_COPY ]; - fenceValues[CMDQUEUE_GRAPHICS] = m_LastCompletedValues[CMDQUEUE_GRAPHICS]; - } - - private: - Device* m_pDevice; - ID3D12Fence* m_pFences[CMDQUEUE_NUM]; - HANDLE m_FenceEvents[CMDQUEUE_NUM]; - - // Maximum fence-value of all command-lists currently in flight (allocated, running or free) - std::atomic m_CurrentValues[CMDQUEUE_NUM]; - // Maximum fence-value of all command-lists passed to the driver (running only) - std::atomic m_SubmittedValues[CMDQUEUE_NUM]; - - // Maximum fence-value of all command-lists executed by the driver (free only) - mutable std::atomic m_LastCompletedValues[CMDQUEUE_NUM]; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.cpp deleted file mode 100644 index e9be718781..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12DescriptorHeap.hpp" - -namespace DX12 -{ - DescriptorHeap::DescriptorHeap(Device* device) - : DeviceObject(device) - { - } - - DescriptorHeap::~DescriptorHeap() - { - } - - bool DescriptorHeap::Init(const D3D12_DESCRIPTOR_HEAP_DESC& desc) - { - if (!IsInitialized()) - { - ID3D12DescriptorHeap* heap; - GetDevice()->GetD3D12Device()->CreateDescriptorHeap(&desc, IID_GRAPHICS_PPV_ARGS(&heap)); - - m_pDescriptorHeap = heap; - heap->Release(); - - m_Desc12 = m_pDescriptorHeap->GetDesc(); - m_HeapStartCPU = m_pDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); - m_HeapStartGPU = m_pDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); - m_DescSize = GetDevice()->GetD3D12Device()->GetDescriptorHandleIncrementSize(m_Desc12.Type); - - IsInitialized(true); - } - - Reset(); - return true; - } - - DescriptorBlock::DescriptorBlock(const SDescriptorBlock& block) - { - m_pDescriptorHeap = reinterpret_cast(block.pBuffer); - m_BlockStart = block.offset; - m_Capacity = block.size; - m_Cursor = 0; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.hpp deleted file mode 100644 index 1da4c2a64d..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12DescriptorHeap.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12Base.hpp" - -struct SDescriptorBlock; - -namespace DX12 -{ - struct Cursor - { - Cursor() : m_Cursor(0) {} - - inline void SetCursor(AZ::u32 value) { m_Cursor = value; } - inline AZ::u32 GetCursor() const { return m_Cursor; } - inline void IncrementCursor(AZ::u32 step = 1) { m_Cursor += step; } - inline void Reset() { m_Cursor = 0; } - - AZ::u32 m_Cursor; - }; - - class DescriptorHeap - : public DeviceObject - , public Cursor - { - public: - DescriptorHeap(Device* device); - virtual ~DescriptorHeap(); - - bool Init(const D3D12_DESCRIPTOR_HEAP_DESC& desc); - - inline ID3D12DescriptorHeap* GetD3D12DescriptorHeap() const - { - return m_pDescriptorHeap; - } - - inline AZ::u32 GetDescriptorSize() const - { - return m_DescSize; - } - - inline AZ::u32 GetCapacity() const - { - return m_Desc12.NumDescriptors; - } - - inline CD3DX12_CPU_DESCRIPTOR_HANDLE GetHandleOffsetCPU(INT offset) const - { - return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_HeapStartCPU, m_Cursor + offset, m_DescSize); - } - - inline CD3DX12_CPU_DESCRIPTOR_HANDLE GetHandleOffsetCPU_R(INT offset) const - { - return CD3DX12_CPU_DESCRIPTOR_HANDLE(m_HeapStartCPU, offset, m_DescSize); - } - - inline CD3DX12_GPU_DESCRIPTOR_HANDLE GetHandleOffsetGPU(INT offset) const - { - return CD3DX12_GPU_DESCRIPTOR_HANDLE(m_HeapStartGPU, m_Cursor + offset, m_DescSize); - } - - inline CD3DX12_GPU_DESCRIPTOR_HANDLE GetHandleOffsetGPU_R(INT offset) const - { - return CD3DX12_GPU_DESCRIPTOR_HANDLE(m_HeapStartGPU, offset, m_DescSize); - } - - inline D3D12_GPU_DESCRIPTOR_HANDLE GetHandleGPUFromCPU(D3D12_CPU_DESCRIPTOR_HANDLE handle) const - { - AZ_Assert(GetHandleOffsetCPU(0).ptr <= handle.ptr && handle.ptr < GetHandleOffsetCPU(GetCapacity()).ptr, "Out of bounds"); - D3D12_GPU_DESCRIPTOR_HANDLE rebase; - rebase.ptr = m_HeapStartGPU.ptr + handle.ptr - m_HeapStartCPU.ptr; - return rebase; - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetHandleCPUFromGPU(D3D12_GPU_DESCRIPTOR_HANDLE handle) const - { - AZ_Assert(GetHandleOffsetGPU(0).ptr <= handle.ptr && handle.ptr < GetHandleOffsetGPU(GetCapacity()).ptr, "Out of bounds"); - D3D12_CPU_DESCRIPTOR_HANDLE rebase; - rebase.ptr = m_HeapStartCPU.ptr + handle.ptr - m_HeapStartGPU.ptr; - return rebase; - } - - inline INT GetOffsetFromCPUHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle) - { - return static_cast((handle.ptr - m_HeapStartCPU.ptr) / m_DescSize); - } - - private: - SmartPtr m_pDescriptorHeap; - D3D12_DESCRIPTOR_HEAP_DESC m_Desc12; - D3D12_CPU_DESCRIPTOR_HANDLE m_HeapStartCPU; - D3D12_GPU_DESCRIPTOR_HANDLE m_HeapStartGPU; - AZ::u32 m_DescSize; - }; - - class DescriptorBlock : public Cursor - { - public: - DescriptorBlock() - : m_BlockStart(0) - , m_Capacity(0) - {} - - DescriptorBlock(DescriptorHeap* pHeap, AZ::u32 cursor, AZ::u32 capacity) - : m_pDescriptorHeap(pHeap) - , m_BlockStart(cursor) - , m_Capacity(capacity) - { - AZ_Assert(cursor + capacity <= pHeap->GetCapacity(), "Out of bounds"); - } - - DescriptorBlock(const SDescriptorBlock& block); - - inline DescriptorHeap* GetDescriptorHeap() const - { - return m_pDescriptorHeap.get(); - } - - inline AZ::u32 GetDescriptorSize() const - { - return m_pDescriptorHeap->GetDescriptorSize(); - } - - inline AZ::u32 GetCapacity() const - { - return m_Capacity; - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetHandleOffsetCPU(INT offset) const - { - AZ_Assert((offset < 0) || (m_Cursor + offset < m_Capacity), "Out of bounds"); - return m_pDescriptorHeap->GetHandleOffsetCPU_R(static_cast(m_BlockStart + m_Cursor) + offset); - } - - inline D3D12_GPU_DESCRIPTOR_HANDLE GetHandleOffsetGPU(INT offset) const - { - AZ_Assert((offset < 0) || (m_Cursor + offset < m_Capacity), "Out of bounds"); - return m_pDescriptorHeap->GetHandleOffsetGPU_R(static_cast(m_BlockStart + m_Cursor) + offset); - } - - inline D3D12_GPU_DESCRIPTOR_HANDLE GetHandleGPUFromCPU(D3D12_CPU_DESCRIPTOR_HANDLE handle) const - { - AZ_Assert(m_pDescriptorHeap->GetHandleOffsetCPU(m_BlockStart).ptr <= handle.ptr && handle.ptr < m_pDescriptorHeap->GetHandleOffsetCPU(m_BlockStart + GetCapacity()).ptr, "Out of bounds"); - return m_pDescriptorHeap->GetHandleGPUFromCPU(handle); - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetHandleCPUFromGPU(D3D12_GPU_DESCRIPTOR_HANDLE handle) const - { - AZ_Assert(m_pDescriptorHeap->GetHandleOffsetGPU(m_BlockStart).ptr <= handle.ptr && handle.ptr < m_pDescriptorHeap->GetHandleOffsetGPU(m_BlockStart + GetCapacity()).ptr, "Out of bounds"); - return m_pDescriptorHeap->GetHandleCPUFromGPU(handle); - } - - inline AZ::u32 GetStartOffset() const { return m_BlockStart; } - - private: - SmartPtr m_pDescriptorHeap; - AZ::u32 m_BlockStart; - AZ::u32 m_Capacity; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.cpp deleted file mode 100644 index 811cf712a9..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12Device.hpp" -#include "DX12Resource.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12DEVICE_CPP_SECTION_1 1 - #define DX12DEVICE_CPP_SECTION_2 2 - #define DX12DEVICE_CPP_SECTION_3 3 - #define DX12DEVICE_CPP_SECTION_4 4 -#endif - -#define DX12_GLOBALHEAP_RESOURCES (1 << D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) -#define DX12_GLOBALHEAP_SAMPLERS (1 << D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) -#define DX12_GLOBALHEAP_TYPES DX12_GLOBALHEAP_RESOURCES - -namespace DX12 -{ - Device* Device::Create(IDXGIAdapter* pAdapter, D3D_FEATURE_LEVEL* pFeatureLevel) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12DEVICE_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(DX12Device_cpp) -#endif - - ID3D12Device* pDevice12 = NULL; - - if (CRenderer::CV_r_EnableDebugLayer) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12DEVICE_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(DX12Device_cpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - ID3D12Debug* debugInterface = nullptr; - if (SUCCEEDED(D3D12GetDebugInterface(IID_GRAPHICS_PPV_ARGS(&debugInterface)))) - { - debugInterface->EnableDebugLayer(); - } -// ID3D12Debug1 is only available after windows 10 anniversary update or windows sdk 14393 -#ifdef __ID3D12Debug1_INTERFACE_DEFINED__ - ID3D12Debug1* debugInterface1; - if (SUCCEEDED(debugInterface->QueryInterface(IID_GRAPHICS_PPV_ARGS(&debugInterface1)))) - { - debugInterface1->SetEnableGPUBasedValidation(true); - } -#endif -#endif // defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - } - - D3D_FEATURE_LEVEL level; - HRESULT hr; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12DEVICE_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(DX12Device_cpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - hr = - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_12_1, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_12_0, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - // (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_11_3, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - // (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_11_2, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_11_1, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_11_0, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_10_1, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_10_0, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_9_3, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_9_2, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) || - (D3D12CreateDevice(pAdapter, level = D3D_FEATURE_LEVEL_9_1, IID_GRAPHICS_PPV_ARGS(&pDevice12)) == S_OK) ? S_OK : S_FALSE; -#endif - if (hr != S_OK) - { - DX12_ASSERT(0, "Failed to create D3D12 Device!"); - return NULL; - } - - if (pFeatureLevel) - { - *pFeatureLevel = level; - } - - Device* result = new Device(pDevice12); - pDevice12->Release(); - - return DX12::PassAddRef(result); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - Device::Device(ID3D12Device* d3d12Device) - : m_Device(d3d12Device) - , m_SamplerCache(this) - , m_ShaderResourceDescriptorCache(this) - , m_UnorderedAccessDescriptorCache(this) - , m_DepthStencilDescriptorCache(this) - , m_RenderTargetDescriptorCache(this) -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12DEVICE_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12Device_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - , m_GlobalDescriptorHeaps - { - { this }, - { this }, - { this }, - { this } - } -#endif - , m_FrameCounter(0) - , m_CalibratedCpuTimestamp{} - , m_CalibratedCpuTimestampFrequency{} - , m_CalibratedGpuTimestamp{} - , m_CalibratedGpuTimestampFrequency{} - , m_NullSRV{} - , m_NullUAV{} - , m_NullSampler{} - { - // These objects are reference counted, but didn't heap allocate them. We assume ownership. - { - m_SamplerCache.AddRef(); - m_ShaderResourceDescriptorCache.AddRef(); - m_UnorderedAccessDescriptorCache.AddRef(); - m_DepthStencilDescriptorCache.AddRef(); - m_RenderTargetDescriptorCache.AddRef(); - - for (AZ::u32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; ++i) - { - m_GlobalDescriptorHeaps[i].AddRef(); - } - } - - m_PipelineStateCache.Init(this); - m_RootSignatureCache.Init(this); - - // init sampler cache - { - D3D12_DESCRIPTOR_HEAP_DESC desc; - ZeroStruct(desc); - - desc.NumDescriptors = 2048; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - m_SamplerCache.Init(desc); - } - - // init shader resource descriptor cache - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = 65535; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - m_ShaderResourceDescriptorCache.Init(desc); - } - - // init unordered access descriptor cache - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = 4096; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - m_UnorderedAccessDescriptorCache.Init(desc); - } - - // init depth stencil descriptor cache - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = 256; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - m_DepthStencilDescriptorCache.Init(desc); - } - - // init render target descriptor cache - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = 1024; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - m_RenderTargetDescriptorCache.Init(desc); - } - - // init global descriptor heaps - - static AZ::u32 globalHeapSizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES] = - { - 1000000, // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV - 1024, // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER - 256, // D3D12_DESCRIPTOR_HEAP_TYPE_RTV - 256 // D3D12_DESCRIPTOR_HEAP_TYPE_DSV - }; - - for (D3D12_DESCRIPTOR_HEAP_TYPE eType = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; eType < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; eType = D3D12_DESCRIPTOR_HEAP_TYPE(eType + 1)) - { - if (DX12_GLOBALHEAP_TYPES & (1 << eType)) - { - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = globalHeapSizes[eType]; - desc.Type = eType; - desc.Flags = (eType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV || eType == D3D12_DESCRIPTOR_HEAP_TYPE_DSV ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE); - - m_GlobalDescriptorHeaps[eType].Init(desc); - } - } - - D3D12_SHADER_RESOURCE_VIEW_DESC SRVDesc = {}; - SRVDesc.Format = DXGI_FORMAT_R32_UINT; - SRVDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - SRVDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; - m_NullSRV = CacheShaderResourceView(&SRVDesc, nullptr); - - D3D12_UNORDERED_ACCESS_VIEW_DESC UAVDesc = {}; - UAVDesc.Format = DXGI_FORMAT_R32_UINT; - UAVDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; - m_NullUAV = CacheUnorderedAccessView(&UAVDesc, nullptr); - - D3D12_SAMPLER_DESC SamplerDesc = {}; - SamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - SamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - SamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; - SamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; - SamplerDesc.Filter = D3D12_FILTER_COMPARISON_ANISOTROPIC; - m_NullSampler = CacheSampler(&SamplerDesc); - } - - Device::~Device() - { - // Fee all resources in the m_ReleaseHeap and m_RecycleHeap - FlushReleaseHeap(ResourceReleasePolicy::Immediate); - } - - D3D12_CPU_DESCRIPTOR_HANDLE Device::CacheSampler(const D3D12_SAMPLER_DESC* pDesc) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - DX12_ASSERT(m_SamplerCache.GetCursor() < m_SamplerCache.GetCapacity()); - - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = m_SamplerCache.GetHandleOffsetCPU(0); - GetD3D12Device()->CreateSampler(pDesc, dstHandle); - m_SamplerCache.IncrementCursor(); - - return dstHandle; - } - - D3D12_CPU_DESCRIPTOR_HANDLE Device::CacheShaderResourceView(const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D12Resource* pResource) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - bool useCached = false; - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle; - if (m_DescriptorPools[DescriptorPoolSRV].size()) - { - auto it = m_DescriptorPools[DescriptorPoolSRV].front(); - if (m_FrameCounter > (it.first + AllowedGPUFramesLatency)) - { - useCached = true; - m_DescriptorPools[DescriptorPoolSRV].pop_front(); - dstHandle = m_ShaderResourceDescriptorCache.GetHandleOffsetCPU_R(it.second); - } - } - if(!useCached) - { - DX12_ASSERT(m_ShaderResourceDescriptorCache.GetCursor() < m_ShaderResourceDescriptorCache.GetCapacity()); - dstHandle = m_ShaderResourceDescriptorCache.GetHandleOffsetCPU(0); - m_ShaderResourceDescriptorCache.IncrementCursor(); - } - - GetD3D12Device()->CreateShaderResourceView(pResource, pDesc, dstHandle); - - - return dstHandle; - } - - D3D12_CPU_DESCRIPTOR_HANDLE Device::CacheUnorderedAccessView(const D3D12_UNORDERED_ACCESS_VIEW_DESC* pDesc, ID3D12Resource* pResource) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - bool useCached = false; - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle; - if (m_DescriptorPools[DescriptorPoolUAV].size()) - { - auto it = m_DescriptorPools[DescriptorPoolUAV].front(); - if (m_FrameCounter > (it.first + AllowedGPUFramesLatency)) - { - useCached = true; - m_DescriptorPools[DescriptorPoolUAV].pop_front(); - dstHandle = m_UnorderedAccessDescriptorCache.GetHandleOffsetCPU_R(it.second); - } - } - if (!useCached) - { - DX12_ASSERT(m_UnorderedAccessDescriptorCache.GetCursor() < m_UnorderedAccessDescriptorCache.GetCapacity()); - dstHandle = m_UnorderedAccessDescriptorCache.GetHandleOffsetCPU(0); - m_UnorderedAccessDescriptorCache.IncrementCursor(); - } - GetD3D12Device()->CreateUnorderedAccessView(pResource, nullptr, pDesc, dstHandle); - - return dstHandle; - } - - D3D12_CPU_DESCRIPTOR_HANDLE Device::CacheDepthStencilView(const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, ID3D12Resource* pResource) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - DX12_ASSERT(m_DepthStencilDescriptorCache.GetCursor() < m_DepthStencilDescriptorCache.GetCapacity()); - - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = m_DepthStencilDescriptorCache.GetHandleOffsetCPU(0); - GetD3D12Device()->CreateDepthStencilView(pResource, pDesc, dstHandle); - m_DepthStencilDescriptorCache.IncrementCursor(); - - return dstHandle; - } - - D3D12_CPU_DESCRIPTOR_HANDLE Device::CacheRenderTargetView(const D3D12_RENDER_TARGET_VIEW_DESC* pDesc, ID3D12Resource* pResource) - { - static CryCriticalSectionNonRecursive csThreadSafeScope; - CryAutoLock lThreadSafeScope(csThreadSafeScope); - - DX12_ASSERT(m_RenderTargetDescriptorCache.GetCursor() < m_RenderTargetDescriptorCache.GetCapacity()); - - D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = m_RenderTargetDescriptorCache.GetHandleOffsetCPU(0); - GetD3D12Device()->CreateRenderTargetView(pResource, pDesc, dstHandle); - m_RenderTargetDescriptorCache.IncrementCursor(); - - return dstHandle; - } - - void Device::RecycleDescriptorHandle(DescriptorPoolType poolType, D3D12_CPU_DESCRIPTOR_HANDLE handle) - { - AZ::u32 offset; - switch (poolType) - { - case DescriptorPoolSRV: - offset = m_ShaderResourceDescriptorCache.GetOffsetFromCPUHandle(handle); - break; - case DescriptorPoolUAV: - offset = m_UnorderedAccessDescriptorCache.GetOffsetFromCPUHandle(handle); - break; - default: - AZ_Assert(0, "DescriptorPoolType not supported!"); - } - - m_DescriptorPools[poolType].push_back(AZStd::pair(m_FrameCounter, offset)); - } - - void Device::FinishFrame() - { - m_FrameCounter++; - } - - HRESULT STDMETHODCALLTYPE Device::CreateOrReuseCommittedResource( - _In_ const D3D12_HEAP_PROPERTIES* pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, - _In_ const D3D12_RESOURCE_DESC* pResourceDesc, - D3D12_RESOURCE_STATES InitialResourceState, - _In_opt_ const D3D12_CLEAR_VALUE* pOptimizedClearValue, - REFIID riidResource, - _COM_Outptr_opt_ void** ppvResource, - ResourceStates& resourceStates) - { - AZ_TRACE_METHOD(); - - struct - { - D3D12_HEAP_FLAGS sHeapFlags; - D3D12_HEAP_PROPERTIES sHeapProperties; - D3D12_RESOURCE_DESC sResourceDesc; - } - hashableBlob; - - hashableBlob.sHeapProperties = *pHeapProperties; - hashableBlob.sResourceDesc = *pResourceDesc; - hashableBlob.sHeapFlags = HeapFlags; - - // Clear spaces from alignment of members - void* ptr1 = ((char*)&hashableBlob.sResourceDesc.Dimension) + sizeof(hashableBlob.sResourceDesc.Dimension); - ZeroMemory(ptr1, offsetof(D3D12_RESOURCE_DESC, Alignment) - sizeof(hashableBlob.sResourceDesc.Dimension)); - void* ptr2 = ((char*)&hashableBlob.sResourceDesc.Flags) + sizeof(hashableBlob.sResourceDesc.Flags); - ZeroMemory(ptr2, sizeof(hashableBlob.sResourceDesc) - offsetof(D3D12_RESOURCE_DESC, Flags) - sizeof(hashableBlob.sResourceDesc.Flags)); - - THash hHash = ComputeSmallHash(&hashableBlob); - - auto result = m_RecycleHeap.find(hHash); - if (result != m_RecycleHeap.end()) - { - if (ppvResource) - { - *ppvResource = result->second.resource; - resourceStates = result->second.resourceStates; - m_RecycleHeap.erase(result); - } - - return S_OK; - } - - auto res = GetD3D12Device()->CreateCommittedResource( - pHeapProperties, HeapFlags, pResourceDesc, InitialResourceState, - pOptimizedClearValue, riidResource, ppvResource); - resourceStates.m_CurrentState = InitialResourceState; - resourceStates.m_AnnouncedState = static_cast(-1); - - return res; - } - - void Device::FlushReleaseHeap(ResourceReleasePolicy releasePolicy) - { - const AZ::u32 RESOURCE_RECYCLE_LATENCY = 8; - const AZ::u32 RESOURCE_RELEASE_LATENCY = 32; - { - auto it = m_ReleaseHeap.begin(); - while (it != m_ReleaseHeap.end()) - { - AZ::u32 resourceFrameNumber = it->second.frameNumber; - if (m_FrameCounter > (resourceFrameNumber + RESOURCE_RECYCLE_LATENCY) || releasePolicy == ResourceReleasePolicy::Immediate) - { - m_RecycleHeap.insert(*it); - it = m_ReleaseHeap.erase(it); - } - else - { - it++; - } - } - } - { - auto it = m_RecycleHeap.begin(); - while (it != m_RecycleHeap.end()) - { - AZ::u32 resourceFrameNumber = it->second.frameNumber; - if (m_FrameCounter > (resourceFrameNumber + RESOURCE_RELEASE_LATENCY) || releasePolicy == ResourceReleasePolicy::Immediate) - { - it->second.resource->Release(); - it = m_RecycleHeap.erase(it); - } - else - { - it++; - } - } - } - } - - void Device::ReleaseLater(ID3D12Resource* object, D3D12_RESOURCE_STATES currentState, D3D12_RESOURCE_STATES announcedState) - { - if (object) - { - struct - { - D3D12_HEAP_FLAGS sHeapFlags; - D3D12_HEAP_PROPERTIES sHeapProperties; - D3D12_RESOURCE_DESC sResourceDesc; - } - hashableBlob; - - object->GetHeapProperties(&hashableBlob.sHeapProperties, &hashableBlob.sHeapFlags); - hashableBlob.sResourceDesc = object->GetDesc(); - // When creating a committed resource, D3D12_HEAP_FLAGS must not have either D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES, - // D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES, nor D3D12_HEAP_FLAG_DENY_BUFFERS set. These flags will be set automatically - // to correspond with the committed resource type. - hashableBlob.sHeapFlags = D3D12_HEAP_FLAGS(hashableBlob.sHeapFlags & ~(D3D12_HEAP_FLAG_DENY_BUFFERS + D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES + D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES)); - - // Clear spaces from alignment of members - void* ptr1 = ((char*)&hashableBlob.sResourceDesc.Dimension) + sizeof(hashableBlob.sResourceDesc.Dimension); - ZeroMemory(ptr1, offsetof(D3D12_RESOURCE_DESC, Alignment) - sizeof(hashableBlob.sResourceDesc.Dimension)); - void* ptr2 = ((char*)&hashableBlob.sResourceDesc.Flags) + sizeof(hashableBlob.sResourceDesc.Flags); - ZeroMemory(ptr2, sizeof(hashableBlob.sResourceDesc) - offsetof(D3D12_RESOURCE_DESC, Flags) - sizeof(hashableBlob.sResourceDesc.Flags)); - - ReleaseInfo releaseInfo; - - THash hash = ComputeSmallHash(&hashableBlob); - - releaseInfo.resource = object; - releaseInfo.resourceStates.m_CurrentState = currentState; - releaseInfo.resourceStates.m_AnnouncedState = announcedState; - releaseInfo.frameNumber = m_FrameCounter; - - m_ReleaseHeap.insert(AZStd::make_pair(hash, std::move(releaseInfo))); - } - } - - DescriptorBlock Device::GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE eType, AZ::u32 size) - { - if (DX12_GLOBALHEAP_TYPES & (1 << eType)) - { - AZ_Assert(m_GlobalDescriptorHeaps[eType].GetCapacity() - m_GlobalDescriptorHeaps[eType].GetCursor() >= size, "Exceeded capacity"); - DescriptorBlock result(&m_GlobalDescriptorHeaps[eType], m_GlobalDescriptorHeaps[eType].GetCursor(), size); - m_GlobalDescriptorHeaps[eType].IncrementCursor(size); - return result; - } - - DescriptorHeap* pResourceHeap = DX12::PassAddRef(new DescriptorHeap(this)); - - D3D12_DESCRIPTOR_HEAP_DESC desc = {}; - desc.NumDescriptors = size; - desc.Type = eType; - desc.Flags = (eType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV || eType == D3D12_DESCRIPTOR_HEAP_TYPE_DSV ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE); - pResourceHeap->Init(desc); - - DescriptorBlock result(pResourceHeap, pResourceHeap->GetCursor(), size); - pResourceHeap->Release(); - return result; - } - - void Device::CalibrateClocks(ID3D12CommandQueue* presentQueue) - { - presentQueue->GetClockCalibration(&m_CalibratedGpuTimestamp, &m_CalibratedCpuTimestamp); - presentQueue->GetTimestampFrequency(&m_CalibratedGpuTimestampFrequency); - - QueryPerformanceFrequency((LARGE_INTEGER*)&m_CalibratedCpuTimestampFrequency); - } - - AZ::u64 Device::MakeCpuTimestamp(AZ::u64 gpuTimestamp) const - { - INT64 timestampDelta = ((INT64)gpuTimestamp - (INT64)m_CalibratedGpuTimestamp); - INT64 calibratedTimestampDelta = (timestampDelta * (INT64)m_CalibratedCpuTimestampFrequency) / (INT64)m_CalibratedGpuTimestampFrequency; - return m_CalibratedCpuTimestamp + calibratedTimestampDelta; - } - - AZ::u64 Device::MakeCpuTimestampMicroseconds(AZ::u64 gpuTimestamp) const - { - return (MakeCpuTimestamp(gpuTimestamp) * 1000) / (m_CalibratedCpuTimestampFrequency / 1000); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.hpp deleted file mode 100644 index fb6f67e5a2..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.hpp +++ /dev/null @@ -1,166 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12CommandList.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12DEVICE_HPP_SECTION_1 1 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12DEVICE_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12Device_hpp) -#else - #include -#endif -#include "DX12/API/DX12PSO.hpp" - -#include - -namespace DX12 -{ - enum DescriptorPoolType - { - DescriptorPoolSRV, - DescriptorPoolUAV, - DescriptorPoolNum - }; - class Device : public AzRHI::ReferenceCounted - { - public: - enum class ResourceReleasePolicy - { - Immediate, - Deferred - }; - - static Device* Create(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL* pFeatureLevel); - virtual ~Device(); - - inline ID3D12Device* GetD3D12Device() const - { - return m_Device; - } - - inline PipelineStateCache& GetPSOCache() - { - return m_PipelineStateCache; - } - - inline const PipelineStateCache& GetPSOCache() const - { - return m_PipelineStateCache; - } - - inline RootSignatureCache& GetRootSignatureCache() - { - return m_RootSignatureCache; - } - - inline const RootSignatureCache& GetRootSignatureCache() const - { - return m_RootSignatureCache; - } - - DescriptorBlock GetGlobalDescriptorBlock(D3D12_DESCRIPTOR_HEAP_TYPE eType, AZ::u32 size); - - D3D12_CPU_DESCRIPTOR_HANDLE CacheSampler(const D3D12_SAMPLER_DESC* pDesc); - D3D12_CPU_DESCRIPTOR_HANDLE CacheShaderResourceView(const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D12Resource* pResource); - D3D12_CPU_DESCRIPTOR_HANDLE CacheUnorderedAccessView(const D3D12_UNORDERED_ACCESS_VIEW_DESC* pDesc, ID3D12Resource* pResource); - D3D12_CPU_DESCRIPTOR_HANDLE CacheDepthStencilView(const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, ID3D12Resource* pResource); - D3D12_CPU_DESCRIPTOR_HANDLE CacheRenderTargetView(const D3D12_RENDER_TARGET_VIEW_DESC* pDesc, ID3D12Resource* pResource); - - void RecycleDescriptorHandle(DescriptorPoolType poolType, D3D12_CPU_DESCRIPTOR_HANDLE handle); - - HRESULT STDMETHODCALLTYPE CreateOrReuseCommittedResource( - _In_ const D3D12_HEAP_PROPERTIES* pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, - _In_ const D3D12_RESOURCE_DESC* pResourceDesc, - D3D12_RESOURCE_STATES InitialResourceState, - _In_opt_ const D3D12_CLEAR_VALUE* pOptimizedClearValue, - REFIID riidResource, - _COM_Outptr_opt_ void** ppvResource, - ResourceStates& resourceStates); - - void FlushReleaseHeap(ResourceReleasePolicy releasePolicy); - void ReleaseLater(ID3D12Resource* pObject, D3D12_RESOURCE_STATES currentState, D3D12_RESOURCE_STATES announcedState); - - void FinishFrame(); - void CalibrateClocks(ID3D12CommandQueue* presentQueue); - - AZ::u64 MakeCpuTimestamp(AZ::u64 gpuTimestamp) const; - AZ::u64 MakeCpuTimestampMicroseconds(AZ::u64 gpuTimestamp) const; - - inline AZ::u64 GetGpuTimestampFrequency() const - { - return m_CalibratedGpuTimestampFrequency; - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetNullShaderResourceView() const - { - return m_NullSRV; - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetNullUnorderedAccessView() const - { - return m_NullUAV; - } - - inline D3D12_CPU_DESCRIPTOR_HANDLE GetNullSampler() const - { - return m_NullSampler; - } - - private: - Device(ID3D12Device* d3d12Device); - - SmartPtr m_Device; - - PipelineStateCache m_PipelineStateCache; - RootSignatureCache m_RootSignatureCache; - - DescriptorHeap m_SamplerCache; - DescriptorHeap m_ShaderResourceDescriptorCache; - DescriptorHeap m_UnorderedAccessDescriptorCache; - DescriptorHeap m_DepthStencilDescriptorCache; - DescriptorHeap m_RenderTargetDescriptorCache; - DescriptorHeap m_GlobalDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; - - D3D12_CPU_DESCRIPTOR_HANDLE m_NullSRV; - D3D12_CPU_DESCRIPTOR_HANDLE m_NullUAV; - D3D12_CPU_DESCRIPTOR_HANDLE m_NullSampler; - - // Free pool of descriptor handler offset - AZStd::list> m_DescriptorPools[DescriptorPoolNum]; - - struct ReleaseInfo - { - ID3D12Resource* resource; - ResourceStates resourceStates; - AZ::s32 frameNumber; - }; - - AZStd::unordered_multimap m_ReleaseHeap; - AZStd::unordered_multimap m_RecycleHeap; - - AZ::u32 m_FrameCounter; - const AZ::u32 AllowedGPUFramesLatency = 5; - - AZ::u64 m_CalibratedGpuTimestampFrequency; - AZ::u64 m_CalibratedGpuTimestamp; - AZ::u64 m_CalibratedCpuTimestampFrequency; - AZ::u64 m_CalibratedCpuTimestamp; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.cpp deleted file mode 100644 index b451ee218e..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12PSO.hpp" -#include "DX12Device.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define DX12PSO_CPP_SECTION_1 1 -#define DX12PSO_CPP_SECTION_2 2 -#define DX12PSO_CPP_SECTION_3 3 -#define DX12PSO_CPP_SECTION_4 4 -#define DX12PSO_CPP_SECTION_5 5 -#define DX12PSO_CPP_SECTION_6 6 -#endif - -namespace DX12 -{ - bool PipelineState::Init(const RootSignature* rootSignature, ID3D12PipelineState* pipelineState) - { - m_RootSignature = rootSignature; - m_PipelineState = pipelineState; - - return true; - } - - bool GraphicsPipelineState::Init(const InitParams& params) - { - AZ_TRACE_METHOD(); - m_Desc = params.desc; - m_Desc.pRootSignature = params.rootSignature->GetD3D12RootSignature(); - - ID3D12PipelineState* pipelineState12 = nullptr; - HRESULT result = GetDevice()->GetD3D12Device()->CreateGraphicsPipelineState(&m_Desc, IID_GRAPHICS_PPV_ARGS(&pipelineState12)); - - if (result != S_OK) - { - DX12_ERROR("Could not create graphics pipeline state!"); - return false; - } - - PipelineState::Init(params.rootSignature, pipelineState12); - pipelineState12->Release(); - - return true; - } - - bool GraphicsPipelineState::Init(const InitParams& params, ID3D12PipelineState* pipelineState) - { - AZ_TRACE_METHOD(); - m_Desc = params.desc; - m_Desc.pRootSignature = params.rootSignature->GetD3D12RootSignature(); - - return PipelineState::Init(params.rootSignature, pipelineState); - } - - bool ComputePipelineState::Init(const InitParams& params) - { - AZ_TRACE_METHOD(); - m_Desc = params.desc; - m_Desc.pRootSignature = params.rootSignature->GetD3D12RootSignature(); - - ID3D12PipelineState* pipelineState12 = nullptr; - HRESULT result = GetDevice()->GetD3D12Device()->CreateComputePipelineState(&m_Desc, IID_GRAPHICS_PPV_ARGS(&pipelineState12)); - - if (FAILED(result)) - { - DX12_ERROR("Could not create graphics pipeline state!"); - return false; - } - - PipelineState::Init(params.rootSignature, pipelineState12); - pipelineState12->Release(); - - return true; - } - - bool ComputePipelineState::Init(const InitParams& params, ID3D12PipelineState* pipelineState) - { - AZ_TRACE_METHOD(); - m_Desc = params.desc; - m_Desc.pRootSignature = params.rootSignature->GetD3D12RootSignature(); - - return PipelineState::Init(params.rootSignature, pipelineState); - } - - PipelineStateCache::PipelineStateCache() - : m_Device(nullptr) - { - } - - PipelineStateCache::~PipelineStateCache() - { - } - - bool PipelineStateCache::Init(Device* device) - { - m_Device = device; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_6 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif - - return true; - } - - GraphicsPipelineState* PipelineStateCache::AcquirePipelineState(const GraphicsPipelineState::InitParams& params) - { - // LSB cleared marks graphics pipeline states, in case graphics and compute hashes collide - THash hash = (~1) & params.hash; - - auto iter = m_Cache.find(hash); - - if (iter != m_Cache.end()) - { - return static_cast(iter->second.get()); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_2 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif - DX12::GraphicsPipelineState* result = new DX12::GraphicsPipelineState(m_Device); - - if (!result->Init(params)) - { - DX12_ERROR("Could not create PSO!"); - return nullptr; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_3 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif - - m_Cache[hash] = result; - - return result; - } - - ComputePipelineState* PipelineStateCache::AcquirePipelineState(const ComputePipelineState::InitParams& params) - { - // LSB filled marks compute pipeline states, in case graphics and compute hashes collide - THash hash = (1) | params.hash; - - auto iter = m_Cache.find(hash); - if (iter != m_Cache.end()) - { - return static_cast(iter->second.get()); - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_4 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif - - ComputePipelineState* result = new ComputePipelineState(m_Device); - if (!result->Init(params)) - { - DX12_ERROR("Could not create PSO!"); - return nullptr; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_5 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif - - m_Cache[hash] = result; - return result; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12PSO_cpp) -#endif -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.hpp deleted file mode 100644 index db6f566631..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12PSO.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12RootSignature.hpp" -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define DX12PSO_H_SECTION_1 1 -#define DX12PSO_H_SECTION_2 2 -#endif - -namespace DX12 -{ - class PipelineState : public DeviceObject - { - public: - PipelineState(Device* device) : DeviceObject(device) {} - ~PipelineState() {} - - bool Init(const RootSignature* rootSignature, ID3D12PipelineState* pipelineState); - - THash GetHash() const - { - return m_Hash; - } - - ID3D12PipelineState* GetD3D12PipelineState() const - { - return m_PipelineState; - } - - private: - THash m_Hash = 0; - SmartPtr m_PipelineState; - const RootSignature* m_RootSignature = nullptr; - }; - - class GraphicsPipelineState : public PipelineState - { - public: - GraphicsPipelineState(Device* device) : PipelineState(device) {} - ~GraphicsPipelineState() {} - - struct InitParams - { - const RootSignature* rootSignature; - D3D12_GRAPHICS_PIPELINE_STATE_DESC desc; - AZ::u32 hash; - }; - - bool Init(const InitParams& params); - bool Init(const InitParams& params, ID3D12PipelineState* pipelineState); - - inline D3D12_GRAPHICS_PIPELINE_STATE_DESC& GetDesc() - { - return m_Desc; - } - - inline const D3D12_GRAPHICS_PIPELINE_STATE_DESC& GetDesc() const - { - return m_Desc; - } - - private: - D3D12_GRAPHICS_PIPELINE_STATE_DESC m_Desc; - }; - - class ComputePipelineState : public PipelineState - { - public: - ComputePipelineState(Device* device) : PipelineState(device) {} - ~ComputePipelineState() {} - - struct InitParams - { - const RootSignature* rootSignature; - D3D12_COMPUTE_PIPELINE_STATE_DESC desc; - AZ::u32 hash; - }; - - bool Init(const InitParams& params); - bool Init(const InitParams& params, ID3D12PipelineState* pipelineState); - - inline D3D12_COMPUTE_PIPELINE_STATE_DESC& GetDesc() - { - return m_Desc; - } - - inline const D3D12_COMPUTE_PIPELINE_STATE_DESC& GetDesc() const - { - return m_Desc; - } - - private: - D3D12_COMPUTE_PIPELINE_STATE_DESC m_Desc; - }; - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_H_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12PSO_h) -#endif - - class PipelineStateCache - { - public: - PipelineStateCache(); - ~PipelineStateCache(); - - bool Init(Device* device); - - GraphicsPipelineState* AcquirePipelineState(const GraphicsPipelineState::InitParams& params); - ComputePipelineState* AcquirePipelineState(const ComputePipelineState::InitParams& params); - - private: - Device* m_Device; - AZStd::unordered_map> m_Cache; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12PSO_H_SECTION_2 - #include AZ_RESTRICTED_FILE(DX12PSO_h) -#endif - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.cpp deleted file mode 100644 index d7754de09c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12QueryHeap.hpp" - -namespace DX12 -{ - QueryHeap::QueryHeap(Device* device) - : DeviceObject(device) - { - } - - QueryHeap::~QueryHeap() - { - } - - bool QueryHeap::Init(Device* device, const D3D12_QUERY_HEAP_DESC& desc) - { - if (!IsInitialized()) - { - SetDevice(device); - - ID3D12QueryHeap* heap; - GetDevice()->GetD3D12Device()->CreateQueryHeap(&desc, IID_GRAPHICS_PPV_ARGS(&heap)); - - m_QueryHeap = heap; - heap->Release(); - - m_Desc12 = desc; - - IsInitialized(true); - } - - Reset(); - return true; - } - - void QueryHeap::Reset() - { - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.hpp deleted file mode 100644 index 6fea3fcb38..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12QueryHeap.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12Base.hpp" - -namespace DX12 -{ - class QueryHeap : public DeviceObject - { - public: - QueryHeap(Device* device); - virtual ~QueryHeap(); - - bool Init(Device* device, const D3D12_QUERY_HEAP_DESC& desc); - void Reset(); - - ID3D12QueryHeap* GetD3D12QueryHeap() const { return /*PassAddRef*/ (m_QueryHeap); } - - UINT GetType() const { return m_Desc12.Type; } - UINT GetCapacity() const { return m_Desc12.Count; } - - private: - SmartPtr m_QueryHeap; - D3D12_QUERY_HEAP_DESC m_Desc12; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.cpp deleted file mode 100644 index b9e2df8cb7..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12Resource.hpp" -#include "DX12Device.hpp" - -namespace DX12 -{ - Resource::Resource(Device* pDevice) - : DeviceObject(pDevice) - , m_HeapType(D3D12_HEAP_TYPE_DEFAULT) - , m_GPUVirtualAddress(DX12_GPU_VIRTUAL_ADDRESS_NULL) - , m_pD3D12Resource(nullptr) - , m_States(D3D12_RESOURCE_STATE_COMMON, static_cast(-1)) - , m_pSwapChainOwner(NULL) - { - memset(&m_FenceValues, 0, sizeof(m_FenceValues)); - } - - Resource::Resource(Resource&& r) - : DeviceObject(std::move(r)) - , m_HeapType(std::move(r.m_HeapType)) - , m_GPUVirtualAddress(std::move(r.m_GPUVirtualAddress)) - , m_pD3D12Resource(std::move(r.m_pD3D12Resource)) - , m_States(std::move(r.m_States)) - , m_InitialData(std::move(r.m_InitialData)) - , m_pSwapChainOwner(std::move(r.m_pSwapChainOwner)) - { - memcpy(&m_FenceValues, &r.m_FenceValues, sizeof(m_FenceValues)); - - r.m_pD3D12Resource = nullptr; - r.m_pSwapChainOwner = nullptr; - } - - Resource& Resource::operator=(Resource&& r) - { - DeviceObject::operator=(std::move(r)); - - m_HeapType = std::move(r.m_HeapType); - m_GPUVirtualAddress = std::move(r.m_GPUVirtualAddress); - m_pD3D12Resource = std::move(r.m_pD3D12Resource); - m_States = std::move(r.m_States); - m_InitialData = std::move(r.m_InitialData); - m_pSwapChainOwner = std::move(r.m_pSwapChainOwner); - - memcpy(&m_FenceValues, &r.m_FenceValues, sizeof(m_FenceValues)); - - r.m_pD3D12Resource = nullptr; - r.m_pSwapChainOwner = nullptr; - - return *this; - } - - Resource::~Resource() - { - m_pD3D12Resource->AddRef(); - - GetDevice()->ReleaseLater(m_pD3D12Resource, GetCurrentState(), GetAnnouncedState()); - } - - UINT64 Resource::GetRequiredUploadSize(UINT FirstSubresource, UINT NumSubresources) const - { - UINT64 Size; - GetDevice()->GetD3D12Device()->GetCopyableFootprints(&m_Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &Size); - return Size; - } - - bool Resource::IsUsed(CommandListPool& commandListPool, const int type) - { - return !commandListPool.IsCompleted(m_FenceValues[type]); - } - - void Resource::WaitForUnused(CommandListPool& commandListPool, const int type) - { - commandListPool.WaitForFenceOnCPU(m_FenceValues[type]); - } - - bool Resource::Init(ID3D12Resource* pResource, D3D12_RESOURCE_STATES eInitialState, const D3D12_RESOURCE_DESC& desc) - { - m_pD3D12Resource = pResource; - m_Desc = desc; - - D3D12_HEAP_PROPERTIES sHeap; - - if (m_pD3D12Resource->GetHeapProperties(&sHeap, nullptr) == S_OK) - { - m_HeapType = sHeap.Type; - - if (m_HeapType == D3D12_HEAP_TYPE_UPLOAD) - { - SetCurrentState(D3D12_RESOURCE_STATE_GENERIC_READ); - } - else if (m_HeapType == D3D12_HEAP_TYPE_READBACK) - { - SetCurrentState(D3D12_RESOURCE_STATE_COPY_DEST); - } - else - { - SetCurrentState(eInitialState); - } - } - - if (pResource && desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - m_GPUVirtualAddress = m_pD3D12Resource->GetGPUVirtualAddress(); - } - - m_pSwapChainOwner = NULL; - - return true; - } - - void Resource::TryStagingUpload(CommandList* commandList) - { - if (m_InitialData) - { - DX12_LOG("Uploading initial data"); - DX12_ASSERT(!IsUsed(commandList->GetCommandListPool()), "Resource is used prior to initialization!"); - - AZStd::unique_ptr initialData = AZStd::move(m_InitialData); - - commandList->UpdateSubresources(*this, - initialData->m_UploadSize, - static_cast(initialData->m_SubResourceData.size()), - &(initialData->m_SubResourceData[0])); - } - } - - Resource::InitialData* Resource::GetOrCreateInitialData() - { - if (!m_InitialData) - { - m_InitialData.reset(new InitialData()); - } - - return m_InitialData.get(); - } - - void Resource::MapDiscard(CommandList* pCmdList) - { - m_pD3D12Resource->AddRef(); - - GetDevice()->ReleaseLater(m_pD3D12Resource, GetCurrentState(), GetAnnouncedState()); - - D3D12_RESOURCE_STATES usage = D3D12_RESOURCE_STATE_GENERIC_READ; - D3D12_HEAP_TYPE heapType = D3D12_HEAP_TYPE_UPLOAD; - ID3D12Resource* resource = NULL; - - ResourceStates resourceStates; - const CD3DX12_HEAP_PROPERTIES heapProperties(heapType); - if (S_OK != GetDevice()->CreateOrReuseCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES, - &m_Desc, - usage, - NULL, - IID_GRAPHICS_PPV_ARGS(&resource), - resourceStates - )) - { - DX12_ASSERT(0, "Could not create buffer resource!"); - return; - } - - m_pD3D12Resource = resource; - - resource->Release(); - - if (m_pD3D12Resource && m_Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - m_GPUVirtualAddress = m_pD3D12Resource->GetGPUVirtualAddress(); - } - - SetCurrentState(usage); - SetAnnouncedState(static_cast(-1)); - - // If it is reused resource, we have to transition the state to new state - if(m_States != resourceStates) - pCmdList->QueueTransitionBarrier(*this, resourceStates.m_CurrentState); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.hpp deleted file mode 100644 index 416c0f1cd3..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Resource.hpp +++ /dev/null @@ -1,250 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __DX12RESOURCE__ -#define __DX12RESOURCE__ - -#include "DX12Base.hpp" -#include "DX12/API/DX12CommandListFence.hpp" - -#include - -namespace DX12 -{ - class CommandList; - class SwapChain; - - struct ResourceStates - { - ResourceStates() - :m_CurrentState(static_cast(-1)), - m_AnnouncedState(static_cast(-1)) - {} - ResourceStates(D3D12_RESOURCE_STATES currentState, D3D12_RESOURCE_STATES announcedState) - :m_CurrentState(currentState), - m_AnnouncedState(announcedState) - {} - - bool operator ==(const ResourceStates& states) const - { - return m_CurrentState == states.m_CurrentState && m_AnnouncedState == states.m_AnnouncedState; - } - bool operator !=(const ResourceStates& states) const - { - return !(*this == states); - } - D3D12_RESOURCE_STATES m_CurrentState; - D3D12_RESOURCE_STATES m_AnnouncedState; - }; - - class Resource : public DeviceObject - { - public: - Resource(Device* pDevice); - virtual ~Resource(); - - Resource(Resource&& r); - Resource& operator=(Resource&& r); - - void TryStagingUpload(CommandList* pCmdList); - bool Init(ID3D12Resource* pResource, D3D12_RESOURCE_STATES eInitialState, const D3D12_RESOURCE_DESC& desc); - bool Init(ID3D12Resource* pResource, D3D12_RESOURCE_STATES eInitialState) - { - return Init(pResource, eInitialState, pResource->GetDesc()); - } - - // Initialization of contents - struct InitialData - { - std::vector m_SubResourceData{}; - UINT64 m_Size{0}; - UINT64 m_UploadSize{0}; - }; - - InitialData* GetOrCreateInitialData(); - - inline bool InitHasBeenDeferred() const - { - return m_InitialData != nullptr; - } - - // Swap-chain associativity - inline void SetDX12SwapChain(SwapChain* pOwner) - { - m_pSwapChainOwner = pOwner; - } - - inline SwapChain* GetDX12SwapChain() const - { - return m_pSwapChainOwner; - } - - inline bool IsBackBuffer() const - { - return m_pSwapChainOwner != NULL; - } - - inline bool IsOffCard() const - { - return m_HeapType == D3D12_HEAP_TYPE_READBACK || m_HeapType == D3D12_HEAP_TYPE_UPLOAD; - } - - inline D3D12_RESOURCE_STATES GetRequiredResourceState() const - { - return m_HeapType == D3D12_HEAP_TYPE_READBACK ? D3D12_RESOURCE_STATE_COPY_DEST : D3D12_RESOURCE_STATE_GENERIC_READ; - } - - inline bool IsTarget() const - { - return !!(GetCurrentState() & (D3D12_RESOURCE_STATE_RENDER_TARGET | D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_DEPTH_WRITE)); - } - - inline bool IsGeneric() const - { - return !!(GetCurrentState() & (D3D12_RESOURCE_STATE_UNORDERED_ACCESS | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); - } - - inline D3D12_RESOURCE_DESC& GetDesc() - { - return m_Desc; - } - - inline const D3D12_RESOURCE_DESC& GetDesc() const - { - return m_Desc; - } - - UINT64 GetRequiredUploadSize(UINT FirstSubresource, UINT NumSubresources) const; - - inline ID3D12Resource* GetD3D12Resource() const - { - return m_pD3D12Resource; - } - inline D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress() const - { - return m_GPUVirtualAddress; - } - - // Get current known resource barrier state - inline D3D12_RESOURCE_STATES GetCurrentState() const - { - return m_States.m_CurrentState; - } - - inline D3D12_RESOURCE_STATES GetAnnouncedState() const - { - return m_States.m_AnnouncedState; - } - - inline void SetCurrentState(D3D12_RESOURCE_STATES state) - { - m_States.m_CurrentState = state; - } - - inline void SetAnnouncedState(D3D12_RESOURCE_STATES state) - { - m_States.m_AnnouncedState = state; - } - - UINT64 SetFenceValue(UINT64 fenceValue, const int id, const int type) - { - // Check submitted completed fence - UINT64 previousValue = m_FenceValues[type][id]; - -#define DX12_FREETHREADED_RESOURCES -#ifndef DX12_FREETHREADED_RESOURCES - m_FenceValues[type][id] = (previousValue > fenceValue ? previousValue : fenceValue); - - if (type == CMDTYPE_ANY) - { - m_FenceValues[CMDTYPE_READ ][id] = - m_FenceValues[CMDTYPE_WRITE][id] = - m_FenceValues[CMDTYPE_ANY][id]; - } - else - { - m_FenceValues[CMDTYPE_ANY ][id] = std::max( - m_FenceValues[CMDTYPE_READ ][id], - m_FenceValues[CMDTYPE_WRITE][id]); - } -#else - // CLs may submit in any order. Is it higher than last known completed fence? If so, update it! - MaxFenceValue(m_FenceValues[type][id], fenceValue); - - if (type == CMDTYPE_ANY) - { - MaxFenceValue(m_FenceValues[CMDTYPE_READ ][id], m_FenceValues[CMDTYPE_ANY][id]); - MaxFenceValue(m_FenceValues[CMDTYPE_WRITE][id], m_FenceValues[CMDTYPE_ANY][id]); - } - else - { - MaxFenceValue(m_FenceValues[CMDTYPE_ANY ][id], std::max(m_FenceValues[CMDTYPE_READ][id], m_FenceValues[CMDTYPE_WRITE][id])); - } -#endif // !NDEBUG - - return previousValue; - } - - inline UINT64 GetFenceValue(const int id, const int type) - { - return m_FenceValues[type][id]; - } - - inline const std::atomic (& GetFenceValues(const int type))[CMDQUEUE_NUM] - { - return m_FenceValues[type]; - } - - inline void MaxFenceValues(std::atomic (&rFenceValues)[CMDTYPE_NUM][CMDQUEUE_NUM], const int type) - { - if ((type == CMDTYPE_READ) || (type == CMDTYPE_ANY)) - { - MaxFenceValue(rFenceValues[CMDTYPE_READ ][CMDQUEUE_COPY ], m_FenceValues[CMDTYPE_READ ][CMDQUEUE_COPY ]); - MaxFenceValue(rFenceValues[CMDTYPE_READ ][CMDQUEUE_GRAPHICS], m_FenceValues[CMDTYPE_READ ][CMDQUEUE_GRAPHICS]); - } - - if ((type == CMDTYPE_WRITE) || (type == CMDTYPE_ANY)) - { - MaxFenceValue(rFenceValues[CMDTYPE_WRITE][CMDQUEUE_COPY ], m_FenceValues[CMDTYPE_WRITE][CMDQUEUE_COPY ]); - MaxFenceValue(rFenceValues[CMDTYPE_WRITE][CMDQUEUE_GRAPHICS], m_FenceValues[CMDTYPE_WRITE][CMDQUEUE_GRAPHICS]); - } - } - - bool IsUsed(CommandListPool& pCmdListPool, const int type = CMDTYPE_ANY); - void WaitForUnused(CommandListPool& pCmdListPool, const int type = CMDTYPE_ANY); - - void MapDiscard(CommandList* pCmdList); - - protected: - friend class CommandList; - - void DiscardInitialData(); - - // Never changes after construction - D3D12_RESOURCE_DESC m_Desc; - D3D12_HEAP_TYPE m_HeapType; - D3D12_GPU_VIRTUAL_ADDRESS m_GPUVirtualAddress; - SmartPtr m_pD3D12Resource; // can be replaced by MAP_DISCARD, which is deprecated - - SwapChain* m_pSwapChainOwner; - - // Potentially changes on every resource-use - ResourceStates m_States; - mutable std::atomic m_FenceValues[CMDTYPE_NUM][CMDQUEUE_NUM]; - - // Used when using the resource the first time - AZStd::unique_ptr m_InitialData; - }; -} - -#endif // __DX12RESOURCE__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.cpp deleted file mode 100644 index 61d506256b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12ResourceBarrierCache.h" - -namespace DX12 -{ - const char* BarrierFlagsToString(D3D12_RESOURCE_BARRIER_FLAGS flags) - { - if (flags & D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY) - { - return "BEGIN_ONLY"; - } - else if (flags & D3D12_RESOURCE_BARRIER_FLAG_END_ONLY) - { - return "END_ONLY"; - } - - return "NONE"; - } - - void ResourceBarrierCache::EnqueueTransition( - ID3D12GraphicsCommandList* commandList, - const D3D12_RESOURCE_BARRIER_FLAGS flags, - const D3D12_RESOURCE_TRANSITION_BARRIER& transition) - { - bool bFoundChain = false; - - for (TransitionChainRoot& chain : m_TransitionChains) - { - if (chain.resource == transition.pResource) - { - TransitionNode& prevNode = m_TransitionNodes[chain.tailIdx]; - - // We can collapse split barriers right here if we find them. We know the previous - // barrier must be a BEGIN_ONLY because we've seen this resource before. Therefore - // we assert that they match and simply remove the split. This simplifies the flattening - // process later on. - if (flags == D3D12_RESOURCE_BARRIER_FLAG_END_ONLY) - { - D3D12_RESOURCE_BARRIER& prevBarrier = m_TransitionBarriers[prevNode.barrierIdx]; - - AZ_Assert( - prevBarrier.Flags == D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY && - prevBarrier.Transition.StateBefore == transition.StateBefore && - prevBarrier.Transition.StateAfter == transition.StateAfter, - "Split barrier not properly closed"); - - prevBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - return; - } - - TransitionNode self; - self.barrierIdx = AZ::u8(m_TransitionBarriers.size()); - self.selfIdx = AZ::u8(m_TransitionNodes.size()); - self.nextIdx = InvalidNodeIndex; - prevNode.nextIdx = self.selfIdx; - - m_TransitionNodes.push_back(self); - - // Reset the tail of the list to the new node. - chain.tailIdx = self.selfIdx; - - bFoundChain = true; - break; - } - } - - if (!bFoundChain) - { - TransitionNode self; - self.barrierIdx = AZ::u8(m_TransitionBarriers.size()); - self.selfIdx = AZ::u8(m_TransitionNodes.size()); - self.nextIdx = InvalidNodeIndex; - m_TransitionNodes.push_back(self); - - TransitionChainRoot root; - root.resource = transition.pResource; - root.tailIdx = self.selfIdx; - root.headIdx = self.selfIdx; - m_TransitionChains.push_back(root); - } - - m_TransitionBarriers.emplace_back(); - - D3D12_RESOURCE_BARRIER& barrier = m_TransitionBarriers.back(); - barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - barrier.Flags = flags; - barrier.Transition = transition; - - TryCapacityFlush(commandList); - } - - void ResourceBarrierCache::EnqueueUAV(ID3D12GraphicsCommandList* commandList, Resource& resource) - { - m_Barriers.emplace_back(); - - D3D12_RESOURCE_BARRIER& barrierDesc = m_Barriers.back(); - barrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - barrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - barrierDesc.UAV.pResource = resource.GetD3D12Resource(); - - TryCapacityFlush(commandList); - } - - void ResourceBarrierCache::Flush(ID3D12GraphicsCommandList* commandList) - { - AZ_TRACE_METHOD(); - for (TransitionChainRoot& chain : m_TransitionChains) - { - TransitionNode* node = &m_TransitionNodes[chain.headIdx]; - - m_Barriers.emplace_back(); - D3D12_RESOURCE_BARRIER* pendingBarrier = &m_Barriers.back(); - *pendingBarrier = m_TransitionBarriers[node->barrierIdx]; - - while (node->nextIdx != InvalidNodeIndex) - { - node = &m_TransitionNodes[node->nextIdx]; - D3D12_RESOURCE_BARRIER& nextBarrier = m_TransitionBarriers[node->barrierIdx]; - - bool bFlattenable = - nextBarrier.Flags == D3D12_RESOURCE_BARRIER_FLAG_NONE && - pendingBarrier->Flags == D3D12_RESOURCE_BARRIER_FLAG_NONE; - - // If we can flatten, we don't need to emit a new barrier, we just fix up the pending one. - if (bFlattenable) - { - pendingBarrier->Transition.StateAfter = nextBarrier.Transition.StateAfter; - } - else - { - // Emit current barrier and reset. - m_Barriers.emplace_back(); - pendingBarrier = &m_Barriers.back(); - *pendingBarrier = nextBarrier; - } - } - - // Remove barrier if it ended up as a noop. - if (pendingBarrier->Transition.StateBefore == pendingBarrier->Transition.StateAfter) - { - m_Barriers.pop_back(); - } - } - - if (m_Barriers.size()) - { - commandList->ResourceBarrier((UINT)m_Barriers.size(), m_Barriers.data()); - m_Barriers.clear(); - } - - m_TransitionBarriers.clear(); - m_TransitionChains.clear(); - m_TransitionNodes.clear(); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.h b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.h deleted file mode 100644 index fe27758657..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12ResourceBarrierCache.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12Base.hpp" -#include - -namespace DX12 -{ - class ResourceBarrierCache - { - public: - ResourceBarrierCache() - { - m_Barriers.reserve(BarrierCountMax); - m_TransitionChains.reserve(BarrierCountMax); - m_TransitionNodes.reserve(BarrierCountMax); - m_TransitionBarriers.reserve(BarrierCountMax); - } - - void EnqueueTransition(ID3D12GraphicsCommandList* commandList, const D3D12_RESOURCE_BARRIER_FLAGS flags, const D3D12_RESOURCE_TRANSITION_BARRIER& barrier); - void EnqueueUAV(ID3D12GraphicsCommandList* commandList, Resource& resource); - void Flush(ID3D12GraphicsCommandList* commandList); - - inline bool IsFlushNeeded() const - { - return m_TransitionBarriers.size() || m_Barriers.size(); - } - - private: - static const AZ::u32 BarrierCountMax = 32; - static const AZ::u8 InvalidNodeIndex = -1; - - struct TransitionNode - { - AZ::u8 selfIdx; - AZ::u8 nextIdx; - AZ::u8 barrierIdx; - }; - - struct TransitionChainRoot - { - ID3D12Resource* resource; - AZ::u8 headIdx; - AZ::u8 tailIdx; - }; - - inline void TryCapacityFlush(ID3D12GraphicsCommandList* commandList) - { - if (AZ::u32(m_Barriers.size() + m_TransitionBarriers.size()) >= BarrierCountMax) - { - Flush(commandList); - } - } - - AZStd::vector m_TransitionChains; - AZStd::vector m_TransitionNodes; - AZStd::vector m_TransitionBarriers; - AZStd::vector m_Barriers; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.cpp deleted file mode 100644 index dd7daa4036..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.cpp +++ /dev/null @@ -1,627 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12RootSignature.hpp" - -#define DX12_DESCRIPTORTABLE_MERGERANGES_CBV 1 -#define DX12_DESCRIPTORTABLE_MERGERANGES_SRV 2 -#define DX12_DESCRIPTORTABLE_MERGERANGES_UAV 4 -#define DX12_DESCRIPTORTABLE_MERGERANGES_SMP 8 -#define DX12_DESCRIPTORTABLE_MERGERANGES_ALL (DX12_DESCRIPTORTABLE_MERGERANGES_SRV | DX12_DESCRIPTORTABLE_MERGERANGES_UAV | DX12_DESCRIPTORTABLE_MERGERANGES_SMP) -#define DX12_DESCRIPTORTABLE_MERGERANGES_MODE DX12_DESCRIPTORTABLE_MERGERANGES_ALL - -namespace DX12 -{ - PipelineLayout::PipelineLayout() - { - Clear(); - } - - void PipelineLayout::Build(Shader* vs, Shader* hs, Shader* ds, Shader* gs, Shader* ps) - { - Clear(); - - Shader* shaders[] = { ps, vs, hs, ds, gs }; - EShaderStage shaderStages[] = { ESS_Pixel, ESS_Vertex, ESS_Hull, ESS_Domain, ESS_Geometry }; - - for (size_t stageIdx = 0; stageIdx < AZ_ARRAY_SIZE(shaders); ++stageIdx) - { - if (shaders[stageIdx]) - { - AZ::u32 parameterCount = m_NumRootParameters; - AppendRootConstantBuffers(shaders[stageIdx], shaderStages[stageIdx]); - if (parameterCount != m_NumRootParameters) - { - m_ShaderStageAccess |= BIT(shaderStages[stageIdx]); - } - } - } - - for (size_t stageIdx = 0; stageIdx < AZ_ARRAY_SIZE(shaders); ++stageIdx) - { - if (shaders[stageIdx]) - { - AZ::u32 parameterCount = m_NumRootParameters; - AppendDescriptorTables(shaders[stageIdx], shaderStages[stageIdx]); - if (parameterCount != m_NumRootParameters) - { - m_ShaderStageAccess |= BIT(shaderStages[stageIdx]); - } - } - } - } - - void PipelineLayout::Build(Shader* cs) - { - Clear(); - - if (cs) - { - AppendRootConstantBuffers(cs, ESS_Compute); - AppendDescriptorTables(cs, ESS_Compute); - m_ShaderStageAccess |= ESS_Compute; - } - } - - void PipelineLayout::Clear() - { - m_ConstantViews.clear(); - m_TableResources.clear(); - m_Samplers.clear(); - - m_DescRangeCursor = 0; - m_NumDescriptors = 0; - m_NumDynamicSamplers = 0; - m_NumDescriptorTables = 0; - m_NumRootParameters = 0; - m_NumStaticSamplers = 0; - - m_ShaderStageAccess = ESS_None; - } - - void PipelineLayout::MakeDescriptorTable( - AZ::u32 rangeCursorEnd, - AZ::u32& rangeCursorBegin, - AZ::u32 offsetEnd, - AZ::u32& offsetBegin, - D3D12_DESCRIPTOR_HEAP_TYPE eHeap, - D3D12_SHADER_VISIBILITY visibility) - { - const AZ::u32 numRanges = rangeCursorEnd - rangeCursorBegin; - if (numRanges > 0) - { - PipelineLayout::DescriptorTableInfo tableInfo; - tableInfo.m_Type = eHeap; - tableInfo.m_Offset = offsetBegin; - m_DescriptorTables[m_NumDescriptorTables++] = tableInfo; - - // Setup the configuration of the root signature entry (a descriptor table range in this case) - m_RootParameters[m_NumRootParameters++].InitAsDescriptorTable(numRanges, m_DescRanges + rangeCursorBegin, visibility); - - rangeCursorBegin = rangeCursorEnd; - offsetBegin = offsetEnd; - } - } - - static D3D12_SHADER_VISIBILITY ToShaderVisibility(EShaderStage stage) - { - static const D3D12_SHADER_VISIBILITY visibility[] = - { - D3D12_SHADER_VISIBILITY_VERTEX, - D3D12_SHADER_VISIBILITY_HULL, - D3D12_SHADER_VISIBILITY_DOMAIN, - D3D12_SHADER_VISIBILITY_GEOMETRY, - D3D12_SHADER_VISIBILITY_PIXEL, - D3D12_SHADER_VISIBILITY_ALL - }; - - return visibility[stage]; - } - - static bool IsRootConstantBuffer(const ReflectedBindingRange& range) - { - return !range.m_bUsed || range.m_Count == 1; - } - - void PipelineLayout::AppendRootConstantBuffers(Shader* shader, EShaderStage shaderStage) - { - const D3D12_SHADER_VISIBILITY visibility = ToShaderVisibility(shaderStage); - - const ReflectedBindings& bindings = shader->GetReflectedBindings(); - - if (bindings.m_ConstantBuffers.m_DescriptorCount) - { - auto& ranges = bindings.m_ConstantBuffers.m_Ranges; - for (size_t rangeIdx = 0; rangeIdx < ranges.size(); ++rangeIdx) - { - const ReflectedBindingRange range = ranges[rangeIdx]; - - AZ::u32 rangeBegin = range.m_ShaderRegister; - AZ::u32 rangeEnd = range.m_ShaderRegister + range.m_Count; - - if (!IsRootConstantBuffer(range)) - { - continue; - } - - if (range.m_bShared) - { - bool bFound = false; - - // only pick up the first occurrence - for (const ConstantBufferLayoutBinding& binding : m_ConstantViews) - { - if (binding.ShaderSlot == rangeBegin) - { - bFound = true; - break; - } - } - - if (!bFound) - { - ConstantBufferLayoutBinding constant; - constant.ShaderStage = shaderStage; - constant.ShaderSlot = rangeBegin; - constant.RootParameterIndex = m_NumRootParameters; - m_ConstantViews.push_back(constant); - - m_RootParameters[m_NumRootParameters++].InitAsConstantBufferView(rangeBegin, 0, D3D12_SHADER_VISIBILITY_ALL); - } - } - else if (!range.m_bUsed) - { - // Setup the configuration of the root signature entry (a constant dummy CBV in this case) - for (AZ::u32 rootParameterIdx = rangeBegin; rootParameterIdx < rangeEnd; ++rootParameterIdx) - { - m_RootParameters[m_NumRootParameters++].InitAsConstantBufferView(rootParameterIdx, 0, visibility); - } - } - else - { - ConstantBufferLayoutBinding constant; - constant.ShaderStage = shaderStage; - constant.ShaderSlot = rangeBegin; - constant.RootParameterIndex = m_NumRootParameters; - m_ConstantViews.push_back(constant); - - m_RootParameters[m_NumRootParameters++].InitAsConstantBufferView(rangeBegin, 0, visibility); - } - } - } - } - - void PipelineLayout::AppendDescriptorTables(Shader* pShader, EShaderStage shaderStage) - { - const D3D12_SHADER_VISIBILITY visibility = ToShaderVisibility(shaderStage); - - const ReflectedBindings& bindings = pShader->GetReflectedBindings(); - - AZ::u32 rangeCursorBegin = m_DescRangeCursor; - AZ::u32 rangeCursorEnd = m_DescRangeCursor; - AZ::u32 descriptorBegin = m_NumDescriptors; - AZ::u32 descriptorEnd = m_NumDescriptors; - - if (bindings.m_ConstantBuffers.m_DescriptorCount) - { - auto& ranges = bindings.m_ConstantBuffers.m_Ranges; - for (size_t rangeIdx = 0; rangeIdx < ranges.size(); ++rangeIdx) - { - const ReflectedBindingRange range = ranges[rangeIdx]; - - AZ::u32 rangeBegin = range.m_ShaderRegister; - AZ::u32 rangeEnd = range.m_ShaderRegister + range.m_Count; - - if (IsRootConstantBuffer(range)) - { - continue; - } - - // Setup the configuration of the descriptor table range (a number of CBVs in this case) - m_DescRanges[rangeCursorEnd++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, range.m_Count, range.m_ShaderRegister); - - for (size_t shaderRegister = rangeBegin; shaderRegister < rangeEnd; ++shaderRegister) - { - ResourceLayoutBinding bindingLayout; - ZeroStruct(bindingLayout); - - bindingLayout.ViewType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; - bindingLayout.ShaderStage = shaderStage; - bindingLayout.ShaderSlot = shaderRegister; - -#ifdef GFX_DEBUG - bindingLayout.DescriptorOffset = descriptorEnd; -#endif - - m_TableResources.push_back(bindingLayout); - ++descriptorEnd; - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_CBV)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - } - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_SRV)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - - if (bindings.m_InputResources.m_DescriptorCount) - { - auto& ranges = bindings.m_InputResources.m_Ranges; - for (size_t rangeIdx = 0; rangeIdx < ranges.size(); ++rangeIdx) - { - const ReflectedBindingRange range = ranges[rangeIdx]; - AZ::u32 rangeBegin = range.m_ShaderRegister; - AZ::u32 rangeEnd = range.m_ShaderRegister + range.m_Count; - - if (!range.m_bUsed) - { - // Setup the configuration of the root signature entry (a constant dummy SRV in this case) - for (AZ::u32 rootParameterIdx = rangeBegin; rootParameterIdx < rangeEnd; ++rootParameterIdx) - { - m_RootParameters[m_NumRootParameters++].InitAsShaderResourceView(rootParameterIdx, 0, visibility); - } - - continue; - } - - // Setup the configuration of the descriptor table range (a number of SRVs in this case) - m_DescRanges[rangeCursorEnd++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, range.m_Count, range.m_ShaderRegister); - - for (size_t shaderRegister = rangeBegin; shaderRegister < rangeEnd; ++shaderRegister) - { - ResourceLayoutBinding bindingLayout; - ZeroStruct(bindingLayout); - - bindingLayout.ViewType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - bindingLayout.ShaderStage = shaderStage; - bindingLayout.ShaderSlot = shaderRegister; -#ifdef GFX_DEBUG - bindingLayout.DescriptorOffset = descriptorEnd; -#endif - m_TableResources.push_back(bindingLayout); - ++descriptorEnd; - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_SRV)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - } - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_UAV)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - - if (bindings.m_OutputResources.m_DescriptorCount) - { - auto& ranges = bindings.m_OutputResources.m_Ranges; - for (size_t rangeIdx = 0; rangeIdx < ranges.size(); ++rangeIdx) - { - const ReflectedBindingRange range = ranges[rangeIdx]; - AZ::u32 rangeBegin = range.m_ShaderRegister; - AZ::u32 rangeEnd = range.m_ShaderRegister + range.m_Count; - - if (!range.m_bUsed) - { - // Setup the configuration of the root signature entry (a constant dummy UAV in this case) - for (AZ::u32 rootParameterIdx = rangeBegin; rootParameterIdx < rangeEnd; ++rootParameterIdx) - { - m_RootParameters[m_NumRootParameters++].InitAsUnorderedAccessView(rootParameterIdx, 0, visibility); - } - - continue; - } - - // Setup the configuration of the descriptor table range (a number of UAVs in this case) - m_DescRanges[rangeCursorEnd++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_UAV, range.m_Count, range.m_ShaderRegister); - - for (size_t shaderRegister = rangeBegin; shaderRegister < rangeEnd; ++shaderRegister) - { - ResourceLayoutBinding bindingLayout; - ZeroStruct(bindingLayout); - - bindingLayout.ViewType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - bindingLayout.ShaderStage = shaderStage; - bindingLayout.ShaderSlot = shaderRegister; -#ifdef GFX_DEBUG - bindingLayout.DescriptorOffset = descriptorEnd; -#endif - m_TableResources.push_back(bindingLayout); - ++descriptorEnd; - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_UAV)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - } - } - - if constexpr (DX12_DESCRIPTORTABLE_MERGERANGES_MODE != 0) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, descriptorEnd, descriptorBegin, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, visibility); - } - - m_NumDescriptors = descriptorEnd; - - AZ::u32 lastSamplers = m_NumDynamicSamplers; - AZ::u32 currentSamplers = m_NumDynamicSamplers; - - if (bindings.m_Samplers.m_DescriptorCount) - { - auto& ranges = bindings.m_Samplers.m_Ranges; - for (size_t rangeIdx = 0; rangeIdx < ranges.size(); ++rangeIdx) - { - const ReflectedBindingRange range = ranges[rangeIdx]; - AZ::u32 rangeBegin = range.m_ShaderRegister; - AZ::u32 rangeEnd = range.m_ShaderRegister + range.m_Count; - - if (!range.m_bUsed) - { - // Setup the configuration of the root signature entry (a constant dummy UAV in this case) - for (AZ::u32 rootParameterIdx = rangeBegin; rootParameterIdx < rangeEnd; ++rootParameterIdx) - { - __debugbreak(); - // m_StaticSamplers[m_NumStaticSamplers++].Init(rj, 0, ..., static_cast((stage + 1) % (D3D12_SHADER_VISIBILITY_PIXEL + 1))); - } - - continue; - } - - // Setup the configuration of the descriptor table range (a number of Samplers in this case) - m_DescRanges[rangeCursorEnd++].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, range.m_Count, range.m_ShaderRegister); - - for (size_t shaderRegister = rangeBegin; shaderRegister < rangeEnd; ++shaderRegister) - { - ResourceLayoutBinding bindingLayout; - ZeroStruct(bindingLayout); - - bindingLayout.ViewType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; - bindingLayout.ShaderStage = shaderStage; - bindingLayout.ShaderSlot = shaderRegister; -#ifdef GFX_DEBUG - bindingLayout.DescriptorOffset = currentSamplers; -#endif - m_Samplers.push_back(bindingLayout); - ++currentSamplers; - } - - if constexpr (!(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_SMP)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, currentSamplers, lastSamplers, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, visibility); - } - } - } - - if constexpr (bool(DX12_DESCRIPTORTABLE_MERGERANGES_MODE & DX12_DESCRIPTORTABLE_MERGERANGES_SMP)) - { - MakeDescriptorTable(rangeCursorEnd, rangeCursorBegin, currentSamplers, lastSamplers, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, visibility); - } - - m_NumDynamicSamplers = currentSamplers; - m_DescRangeCursor = rangeCursorEnd; - } - - void PipelineLayout::DebugPrint() const - { - DX12_LOG("Root Signature:"); - for (AZ::u32 p = 0, r = 0; p < m_NumRootParameters; ++p) - { - DX12_LOG(" %s: %c [%2d to %2d] -> %s [%2d to %2d]", - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL ? "Every shader stage" : - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX ? "Vertex shader stage" : - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL ? "Hull shader stage" : - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN ? "Domain shader stage" : - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY ? "Geometry shader stage" : - m_RootParameters[p].ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL ? "Pixel shader stage" : "Unknown shader stage", - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && m_RootParameters[p].DescriptorTable.pDescriptorRanges->RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV ? 'C' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && m_RootParameters[p].DescriptorTable.pDescriptorRanges->RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV ? 'T' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && m_RootParameters[p].DescriptorTable.pDescriptorRanges->RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV ? 'U' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && m_RootParameters[p].DescriptorTable.pDescriptorRanges->RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER ? 'S' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV ? 'c' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV ? 't' : - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV ? 'u' : '?', - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ? m_RootParameters[p].DescriptorTable.pDescriptorRanges->BaseShaderRegister : m_RootParameters[p].Descriptor.ShaderRegister, - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ? m_RootParameters[p].DescriptorTable.pDescriptorRanges->BaseShaderRegister + m_RootParameters[p].DescriptorTable.pDescriptorRanges->NumDescriptors : 1, - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ? "descriptor table" : - m_RootParameters[p].ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS ? "descriptor" : "32bit constant", - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ? m_DescriptorTables[r].m_Offset : -1, - m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE ? m_DescriptorTables[r].m_Offset + m_RootParameters[p].DescriptorTable.pDescriptorRanges->NumDescriptors : -1); - - r += m_RootParameters[p].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - } - } - - RootSignature::RootSignature(Device* device) - : DeviceObject(device) - , m_nodeMask(0) - { - } - - RootSignature::~RootSignature() - { - } - - bool RootSignature::Init(const ComputeInitParams& params) - { - m_PipelineLayout.Build(params.m_ComputeShader); - return Init(CommandModeCompute); - } - - bool RootSignature::Init(const GraphicsInitParams& params) - { - m_PipelineLayout.Build( - params.m_VertexShader, - params.m_HullShader , - params.m_DomainShader, - params.m_GeometryShader, - params.m_PixelShader); - - return Init(CommandModeGraphics); - } - - bool RootSignature::Init(PipelineLayout& pipelineLayout, CommandMode commandType) - { - m_PipelineLayout = pipelineLayout; - return Init(commandType); - } - - bool RootSignature::Init(CommandMode commandType) - { - ID3D12RootSignature* rootSign = NULL; - CD3DX12_ROOT_SIGNATURE_DESC descRootSignature; - - if (commandType == CommandModeGraphics) - { - D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - flags |= (m_PipelineLayout.m_ShaderStageAccess & BIT(ESS_Vertex)) == 0 ? D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS : D3D12_ROOT_SIGNATURE_FLAG_NONE; - flags |= (m_PipelineLayout.m_ShaderStageAccess & BIT(ESS_Hull)) == 0 ? D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS : D3D12_ROOT_SIGNATURE_FLAG_NONE; - flags |= (m_PipelineLayout.m_ShaderStageAccess & BIT(ESS_Domain)) == 0 ? D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS : D3D12_ROOT_SIGNATURE_FLAG_NONE; - flags |= (m_PipelineLayout.m_ShaderStageAccess & BIT(ESS_Geometry)) == 0 ? D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS : D3D12_ROOT_SIGNATURE_FLAG_NONE; - flags |= (m_PipelineLayout.m_ShaderStageAccess & BIT(ESS_Pixel)) == 0 ? D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS : D3D12_ROOT_SIGNATURE_FLAG_NONE; - - descRootSignature.Init( - m_PipelineLayout.m_NumRootParameters, - m_PipelineLayout.m_RootParameters, - m_PipelineLayout.m_NumStaticSamplers, - m_PipelineLayout.m_StaticSamplers, - flags); - } - else - { - descRootSignature.Init( - m_PipelineLayout.m_NumRootParameters, - m_PipelineLayout.m_RootParameters, - 0, NULL, - D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | - D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS); - } - - { - ID3DBlob* pOutBlob = NULL; - ID3DBlob* pErrorBlob = NULL; - - if (S_OK != D3D12SerializeRootSignature(&descRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, &pOutBlob, &pErrorBlob)) - { - DX12_ERROR("Could not serialize root signature!"); - return false; - } - - if (S_OK != GetDevice()->GetD3D12Device()->CreateRootSignature(m_nodeMask, pOutBlob->GetBufferPointer(), pOutBlob->GetBufferSize(), IID_GRAPHICS_PPV_ARGS(&rootSign))) - { - DX12_ERROR("Could not create root signature!"); - return false; - } - - if (pOutBlob) - { - pOutBlob->Release(); - } - - if (pErrorBlob) - { - pErrorBlob->Release(); - } - } - - m_pRootSignature = rootSign; - rootSign->Release(); - return true; - } - - RootSignatureCache::RootSignatureCache() - { - } - - RootSignatureCache::~RootSignatureCache() - { - } - - bool RootSignatureCache::Init(Device* device) - { - m_pDevice = device; - return true; - } - - static const THash ComputeBit = 1; - - RootSignature* RootSignatureCache::AcquireRootSignature(const RootSignature::GraphicsInitParams& params) - { - struct HashKey - { - AZ::u32 vs; - AZ::u32 hs; - AZ::u32 ds; - AZ::u32 gs; - AZ::u32 ps; - } hashKey; - - hashKey.vs = params.m_VertexShader ? params.m_VertexShader->GetReflectedBindingHash() : 0; - hashKey.hs = params.m_HullShader ? params.m_HullShader->GetReflectedBindingHash() : 0; - hashKey.ds = params.m_DomainShader ? params.m_DomainShader->GetReflectedBindingHash() : 0; - hashKey.gs = params.m_GeometryShader ? params.m_GeometryShader->GetReflectedBindingHash() : 0; - hashKey.ps = params.m_PixelShader ? params.m_PixelShader->GetReflectedBindingHash() : 0; - - // LSB filled marks compute pipeline states, in case graphics and compute hashes collide - THash hash = ~ComputeBit & ComputeSmallHash(&hashKey); - { - auto iter = m_RootSignatureMap.find(hash); - if (iter != m_RootSignatureMap.end()) - { - return iter->second.get(); - } - } - - RootSignature* result = new RootSignature(m_pDevice); - if (!result->Init(params)) - { - DX12_ERROR("Could not create root signature!"); - return nullptr; - } - - m_RootSignatureMap[hash] = result; - return result; - } - - RootSignature* RootSignatureCache::AcquireRootSignature(const RootSignature::ComputeInitParams& params) - { - THash hash = ComputeBit | params.m_ComputeShader->GetReflectedBindingHash(); - { - auto iter = m_RootSignatureMap.find(hash); - if (iter != m_RootSignatureMap.end()) - { - return iter->second; - } - } - - RootSignature* result = new RootSignature(m_pDevice); - if (!result->Init(params)) - { - DX12_ERROR("Could not create root signature!"); - return nullptr; - } - - m_RootSignatureMap[hash] = result; - return result; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.hpp deleted file mode 100644 index 9747d7eb45..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12RootSignature.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __DX12ROOTSIGNATURE__ -#define __DX12ROOTSIGNATURE__ - -#include "DX12Shader.hpp" -#include - -namespace DX12 -{ - // Map of all pairs to descriptor-tables offsets (the CBV+SRV+UAV/SMP index is the offset) - struct ResourceLayoutBinding - { - D3D12_DESCRIPTOR_RANGE_TYPE ViewType; - EShaderStage ShaderStage; - uint8_t ShaderSlot; -#ifdef GFX_DEBUG - uint8_t DescriptorOffset; -#endif // !NDEBUG - }; - - struct ConstantBufferLayoutBinding - { - EShaderStage ShaderStage; - uint8_t ShaderSlot; - uint8_t RootParameterIndex; - }; - - struct PipelineLayout - { - std::vector m_ConstantViews; - std::vector m_TableResources; - std::vector m_Samplers; - - AZ::u32 m_ShaderStageAccess; - - // Memory holding all descriptor-ranges which will be added to the root-signature (basically a heap) - CD3DX12_DESCRIPTOR_RANGE m_DescRanges[256]; - AZ::u32 m_DescRangeCursor; - - // Consecutive list of all root-parameter descriptions of all types (points to m_DescRanges) - CD3DX12_ROOT_PARAMETER m_RootParameters[256]; - AZ::u32 m_NumRootParameters; - - // Static samplers, directly embedded in the shaders once PSO is created with correspondig root signature - D3D12_STATIC_SAMPLER_DESC m_StaticSamplers[16]; - AZ::u32 m_NumStaticSamplers; - - // Consecutive list of all descriptor-tables which are in the root-signature (without holes) - struct DescriptorTableInfo - { - D3D12_DESCRIPTOR_HEAP_TYPE m_Type; - AZ::u32 m_Offset; - }; - - DescriptorTableInfo m_DescriptorTables[256]; - AZ::u32 m_NumDescriptorTables; - - // Total number of resources bound to all shader stages (CBV+SRV+UAV) - size_t m_NumDescriptors; - - // Total number of samplers bound to all shader stages - size_t m_NumDynamicSamplers; - - PipelineLayout(); - - void Build(Shader* vs, Shader* hs, Shader* ds, Shader* gs, Shader* ps); - void Build(Shader* cs); - - void Clear(); - void DebugPrint() const; - - private: - void AppendDescriptorTables(Shader* pShader, EShaderStage eStage); - void AppendRootConstantBuffers(Shader* pShader, EShaderStage eStage); - void MakeDescriptorTable(AZ::u32 currentRangeCursor, AZ::u32& lastRangeCursor, AZ::u32 currentOffset, AZ::u32& lastOffset, D3D12_DESCRIPTOR_HEAP_TYPE eHeap, D3D12_SHADER_VISIBILITY eVisibility); - }; - - class RootSignature - : public DeviceObject - { - public: - struct GraphicsInitParams - { - Shader* m_VertexShader; - Shader* m_HullShader; - Shader* m_DomainShader; - Shader* m_GeometryShader; - Shader* m_PixelShader; - }; - - struct ComputeInitParams - { - Shader* m_ComputeShader; - }; - - RootSignature(Device* device); - ~RootSignature(); - - bool Init(const GraphicsInitParams& params); - bool Init(const ComputeInitParams& params); - bool Init(PipelineLayout& resourceMappings, CommandMode commandType); - - inline THash GetHash() const - { - return m_Hash; - } - - inline const PipelineLayout& GetPipelineLayout() const - { - return m_PipelineLayout; - } - - inline ID3D12RootSignature* GetD3D12RootSignature() const - { - return /*PassAddRef*/ (m_pRootSignature); - } - - private: - bool Init(CommandMode commandType); - - PipelineLayout m_PipelineLayout; - SmartPtr m_pRootSignature; - AZ::u32 m_nodeMask; - THash m_Hash; - }; - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - class RootSignatureCache - { - public: - RootSignatureCache(); - ~RootSignatureCache(); - - bool Init(Device* device); - - RootSignature* AcquireRootSignature(const RootSignature::ComputeInitParams& params); - RootSignature* AcquireRootSignature(const RootSignature::GraphicsInitParams& params); - - private: - Device* m_pDevice; - - AZStd::unordered_map> m_RootSignatureMap; - }; -} - -#endif // __DX12ROOTSIGNATURE__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.cpp deleted file mode 100644 index 82a176fe6a..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12SamplerState.hpp" - -namespace DX12 -{ - //--------------------------------------------------------------------------------------------------------------------- - SamplerState::SamplerState() - : AzRHI::ReferenceCounted() - , m_DescriptorHandle(INVALID_CPU_DESCRIPTOR_HANDLE) - { - // clear before use - memset(&m_unSamplerDesc, 0, sizeof(m_unSamplerDesc)); - } - - //--------------------------------------------------------------------------------------------------------------------- - SamplerState::~SamplerState() - { - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.hpp deleted file mode 100644 index af11c2b9db..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SamplerState.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12Base.hpp" - -namespace DX12 -{ - class SamplerState : public AzRHI::ReferenceCounted - { - public: - SamplerState(); - virtual ~SamplerState(); - - D3D12_SAMPLER_DESC& GetSamplerDesc() - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)); - return m_unSamplerDesc; - } - const D3D12_SAMPLER_DESC& GetSamplerDesc() const - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)); - return m_unSamplerDesc; - } - - void SetDescriptorHandle(const D3D12_CPU_DESCRIPTOR_HANDLE& descriptorHandle) { m_DescriptorHandle = descriptorHandle; } - D3D12_CPU_DESCRIPTOR_HANDLE GetDescriptorHandle() const { return m_DescriptorHandle; } - - private: - D3D12_CPU_DESCRIPTOR_HANDLE m_DescriptorHandle; - - union - { - D3D12_SAMPLER_DESC m_unSamplerDesc; - }; - }; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.cpp deleted file mode 100644 index 2ee987c52f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12Shader.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define DX12SHADER_CPP_SECTION_1 1 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12SHADER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12Shader_cpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - #include - #include -#endif - -namespace DX12 -{ - namespace - { - AZ::u32 MakeHashFromDesc(const D3D11_SHADER_DESC& desc11) - { - // Don't hash pointers. Hashing pointers will make the hash inconsistent between multiple app runs. Making it consistent allows the objects to be serialized to disk and reloaded - // on subsequent runs. - D3D11_SHADER_DESC noPointers = desc11; - noPointers.Creator = nullptr; - return DX12::ComputeSmallHash(&noPointers); - } - - AZ::u32 MakeHashFromBindings(ReflectedBindings& bindings) - { - const ReflectedBindingRangeList* lists[] = - { - &bindings.m_ConstantBuffers, - &bindings.m_InputResources, - &bindings.m_OutputResources, - &bindings.m_Samplers - }; - - AZ::Crc32 hash = 0; - - for (AZ::u32 i = 0; i < AZ_ARRAY_SIZE(lists); ++i) - { - const ReflectedBindingRangeList& list = *lists[i]; - if (list.m_DescriptorCount) - { - hash.Add(&i, sizeof(AZ::u32)); - hash.Add(list.m_Ranges.data(), list.m_Ranges.size() * sizeof(ReflectedBindingRange)); - } - } - - return hash; - } - - void AppendResourceToRanges( - ReflectedBindingRangeList& bindings, - AZ::u8 shaderRegister, - AZ::u8 count, - AZ::u8 type, - AZ::u8 dimension, - bool bUsed = true, - bool bShared = false, - bool bMergeable = true) - { - AZ::u32 rangeIdx = 0; - AZ::u32 rangeCount = bindings.m_Ranges.size(); - - // Attempts to merge a resource into an existing range. We can do this if - // the resource is marked as mergeable, and it's not shared across different - // shader stages. - bool bMerged = false; - - if (bMergeable && !bShared) - { - for (; rangeIdx < rangeCount; ++rangeIdx) - { - ReflectedBindingRange& r = bindings.m_Ranges[rangeIdx]; - if (r.m_bMergeable || r.m_bShared || (r.m_bUsed != bUsed)) - { - continue; // Non-Mergeable - } - - // Can we join new range with an existing one? - if (r.m_ShaderRegister + r.m_Count == shaderRegister) - { -#ifdef GFX_DEBUG - for (size_t j = 0; j < count; ++j) - { - r.m_Types[r.m_Count + j] = type; - r.m_Dimensions[r.m_Count + j] = dimension; - } -#endif - - r.m_Count += count; - bMerged = true; - break; - } - } - } - - if (!bMerged) - { - bindings.m_Ranges.push_back(ReflectedBindingRange(shaderRegister, count, type, dimension, bUsed, bShared, bMergeable)); - } - - bindings.m_DescriptorCount += count; - } - } - - Shader::Shader(Device* device) - : DeviceObject(device) - {} - - Shader::~Shader() - {} - - Shader* Shader::CreateFromD3D11(Device* device, const D3D12_SHADER_BYTECODE& byteCode) - { - ID3D11ShaderReflection* shaderReflection = NULL; - - // Reflect shader internals - if (S_OK != D3DReflect(byteCode.pShaderBytecode, byteCode.BytecodeLength, IID_ID3D11ShaderReflection, (void**)&shaderReflection)) - { - DX12_ASSERT(0, "Could not do a shader reflection!"); - return NULL; - } - - D3D11_SHADER_DESC desc11; - shaderReflection->GetDesc(&desc11); - - Shader* result = DX12::PassAddRef(new Shader(device)); - result->m_Bytecode = byteCode; - result->m_hash = MakeHashFromDesc(desc11); - - for (UINT i = 0; i < desc11.BoundResources; ++i) - { - D3D11_SHADER_INPUT_BIND_DESC bindDesc11; - shaderReflection->GetResourceBindingDesc(i, &bindDesc11); - - bool bBindPointUsed = true; - bool bBindingSharable = - bindDesc11.BindPoint == eConstantBufferShaderSlot_PerMaterial || - bindDesc11.BindPoint == eConstantBufferShaderSlot_PerPass || - bindDesc11.BindPoint == eConstantBufferShaderSlot_PerView || - bindDesc11.BindPoint == eConstantBufferShaderSlot_PerFrame; - - bool bBindingMergeable = bindDesc11.BindPoint > eConstantBufferShaderSlot_PerInstanceLegacy; - - switch (bindDesc11.Type) - { - case D3D10_SIT_CBUFFER: - DX12_ASSERT(bindDesc11.BindCount == 1, "Arrays of ConstantBuffers are not allowed!"); - - if (bindDesc11.BindCount == 1) - { - ID3D11ShaderReflectionConstantBuffer* constantBuffer = shaderReflection->GetConstantBufferByName(bindDesc11.Name); - D3D11_SHADER_BUFFER_DESC constantBufferDesc; - UINT variableUsedCount = 0; - - constantBuffer->GetDesc(&constantBufferDesc); - for (UINT j = 0; j < constantBufferDesc.Variables; j++) - { - ID3D11ShaderReflectionVariable* variable = constantBuffer->GetVariableByIndex(j); - D3D11_SHADER_VARIABLE_DESC variableDesc; - variable->GetDesc(&variableDesc); - - variableUsedCount += (variableDesc.uFlags & D3D10_SVF_USED); - } - - bBindPointUsed = (variableUsedCount > 0); - } - - // We need separate descriptor tables for dynamic CB's - AppendResourceToRanges( - result->m_Bindings.m_ConstantBuffers, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension), - bBindPointUsed, - bBindingSharable, - bBindingMergeable); - break; - - // ID3D12Device::CreateGraphicsPipelineState: SRV or UAV root descriptors can only be Raw or Structured buffers. - case D3D10_SIT_TEXTURE: - case D3D10_SIT_TBUFFER: - AppendResourceToRanges( - result->m_Bindings.m_InputResources, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension)); - break; - case D3D11_SIT_STRUCTURED: - case D3D11_SIT_BYTEADDRESS: - AppendResourceToRanges( - result->m_Bindings.m_InputResources, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension), - bBindPointUsed); - break; - - case D3D11_SIT_UAV_RWTYPED: - AppendResourceToRanges( - result->m_Bindings.m_OutputResources, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension)); - break; - case D3D11_SIT_UAV_RWSTRUCTURED: - case D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER: - case D3D11_SIT_UAV_RWBYTEADDRESS: - case D3D11_SIT_UAV_APPEND_STRUCTURED: - case D3D11_SIT_UAV_CONSUME_STRUCTURED: - AppendResourceToRanges(result->m_Bindings.m_OutputResources, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension), - bBindPointUsed); - break; - - case D3D10_SIT_SAMPLER: - DX12_ASSERT(bindDesc11.BindCount == 1, "Arrays of SamplerStates are not allowed!"); - AppendResourceToRanges( - result->m_Bindings.m_Samplers, - bindDesc11.BindPoint, - bindDesc11.BindCount, - static_cast(bindDesc11.Type), - static_cast(bindDesc11.Dimension)); - break; - } - } - - result->m_BindingHash = MakeHashFromBindings(result->m_Bindings); - return result; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.hpp deleted file mode 100644 index 9f501ebad7..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Shader.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __DX12SHADER__ -#define __DX12SHADER__ - -#include "DX12Base.hpp" - -namespace DX12 -{ - enum EShaderStage : int8 - { - // Graphics pipeline - ESS_Vertex, - ESS_Hull, - ESS_Domain, - ESS_Geometry, - ESS_Pixel, - - // Compute pipeline - ESS_Compute, - - // Complete pipeline - ESS_All = ESS_Compute, - - ESS_LastWithoutCompute = ESS_Compute, - ESS_Num = ESS_Compute + 1, - ESS_None = -1, - ESS_First = ESS_Vertex - }; - - struct ReflectedBindingRange - { - AZ::u8 m_ShaderRegister; - AZ::u8 m_Count; - - // Whether the bind point is actually used in the shader. Ideally, this is compiled out, but in order to support - // lower tier hardware we have to define a root parameter and bind a null descriptor for it. - AZ::u8 m_bUsed : 1; - - // Shared bindings are marked as visible across all shader stages. Practically, this means the binding - // is not merged and will be de-duplicated when the final layout is built. Candidates for sharing are constant - // buffers that are accessed by every stage and have a well-defined layout across all stages. - AZ::u8 m_bShared : 1; - - // We currently merge any range where the layout contents aren't reflected by the shader. Practically, - // this means that any constant buffer that's reflected gets placed into a root constant buffer parameter. - AZ::u8 m_bMergeable : 1; - -#ifdef GFX_DEBUG - AZ::u8 m_Types[56]; - AZ::u8 m_Dimensions[56]; -#endif - - ReflectedBindingRange() - : m_ShaderRegister(0) - , m_Count(0) - , m_bUsed(true) - , m_bShared(false) - , m_bMergeable(true) - {} - - ReflectedBindingRange( - AZ::u8 shaderRegister, - AZ::u8 count, - [[maybe_unused]] AZ::u8 type, - [[maybe_unused]] AZ::u8 dimension, - bool bUsed, - bool bShared, - bool bMergeable) - : m_ShaderRegister(shaderRegister) - , m_Count(count) - , m_bUsed(bUsed) - , m_bShared(bShared) - , m_bMergeable(bMergeable) - { -#ifdef GFX_DEBUG - for (AZ::u32 i = 0; i < count; ++i) - { - m_Types[i] = type; - m_Dimensions[i] = dimension; - } -#endif - } - }; - - struct ReflectedBindingRangeList - { - std::vector m_Ranges; - AZ::u32 m_DescriptorCount; - - ReflectedBindingRangeList() - : m_DescriptorCount(0) - {} - }; - - //////////////////////////////////////////////////////////////////////////// - - struct ReflectedBindings - { - ReflectedBindingRangeList m_ConstantBuffers; // CBV - ReflectedBindingRangeList m_InputResources; // SRV - ReflectedBindingRangeList m_OutputResources; // UAV - ReflectedBindingRangeList m_Samplers; // SMP - }; - - //////////////////////////////////////////////////////////////////////////// - - class Shader : public DeviceObject - { - public: - // Create new shader using DX11 reflection interface - static Shader* CreateFromD3D11(Device* device, const D3D12_SHADER_BYTECODE& byteCode); - - Shader(Device* device); - - const AZ::Crc32 GetHash() const - { - return m_hash; - } - - const ReflectedBindings& GetReflectedBindings() const - { - return m_Bindings; - } - - const AZ::u32 GetReflectedBindingHash() const - { - return m_BindingHash; - } - - protected: - virtual ~Shader(); - - private: - - D3D12_SHADER_BYTECODE m_Bytecode; - ReflectedBindings m_Bindings; - AZ::u32 m_BindingHash = 0; - AZ::Crc32 m_hash; - }; -} - -#endif // __DX12SHADER__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.cpp deleted file mode 100644 index a025eff446..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12SwapChain.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define DX12SWAPCHAIN_CPP_SECTION_1 1 -#endif - -namespace DX12 -{ - SwapChain* SwapChain::Create( - CommandList* commandList, - IDXGIFactory1* pFactory, - DXGI_SWAP_CHAIN_DESC* pDesc) - { - IDXGISwapChain* dxgiSwapChain = NULL; - IDXGISwapChain3* dxgiSwapChain3 = NULL; - ID3D12CommandQueue* commandQueue = commandList->GetD3D12CommandQueue(); - - // If discard isn't implemented/supported/fails, try the newer swap-types - // - flip_discard is win 10 - // - flip_sequentially is win 8 - HRESULT hr; - if (pDesc->SwapEffect == DXGI_SWAP_EFFECT_DISCARD) - { -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION DX12SWAPCHAIN_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(DX12SwapChain_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - pDesc->SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; -#endif - pDesc->BufferCount = std::max(2U, pDesc->BufferCount); - hr = pFactory->CreateSwapChain(commandQueue, pDesc, &dxgiSwapChain); - } - else if (pDesc->SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL) - { - pDesc->SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - pDesc->BufferCount = std::max(2U, pDesc->BufferCount); - hr = pFactory->CreateSwapChain(commandQueue, pDesc, &dxgiSwapChain); - } - else - { - hr = pFactory->CreateSwapChain(commandQueue, pDesc, &dxgiSwapChain); - } - - if (hr == S_OK && dxgiSwapChain) - { - hr = dxgiSwapChain->QueryInterface(IID_PPV_ARGS(&dxgiSwapChain3)); - dxgiSwapChain->Release(); - - if (hr == S_OK && dxgiSwapChain3) - { - return DX12::PassAddRef(new SwapChain(commandList, dxgiSwapChain3, pDesc)); - } - } - - return nullptr; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - SwapChain::SwapChain(CommandList* commandList, IDXGISwapChain3* dxgiSwapChain, DXGI_SWAP_CHAIN_DESC* pDesc) - : AzRHI::ReferenceCounted() - , m_CommandList(commandList) - , m_AsyncQueue(commandList->GetCommandListPool().GetAsyncCommandQueue()) - { - if (pDesc) - { - m_Desc = *pDesc; - } - else - { - dxgiSwapChain->GetDesc(&m_Desc); - } - - m_NativeSwapChain = dxgiSwapChain; - dxgiSwapChain->Release(); - } - - SwapChain::~SwapChain() - { - ForfeitBuffers(); - - m_NativeSwapChain->Release(); - } - - HRESULT SwapChain::Present(AZ::u32 SyncInterval, AZ::u32 Flags) - { - m_AsyncQueue.Flush(); - - HRESULT hr = m_NativeSwapChain->Present(SyncInterval, Flags); - return hr; - } - - void SwapChain::AcquireBuffers(AZStd::vector&& buffers) - { - AZ_Assert(m_BackBuffers.empty(), "must forfeit buffers before assigning"); - - m_BackBuffers = std::move(buffers); - m_BackBufferViews.reserve(buffers.size()); - for (Resource* buffer : m_BackBuffers) - { - m_BackBufferViews.emplace_back(); - m_BackBufferViews.back().Init(*buffer, EVT_RenderTargetView); - } - } - - void SwapChain::ForfeitBuffers() - { - AZ_TRACE_METHOD(); - m_BackBuffers.clear(); - m_BackBufferViews.clear(); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.hpp deleted file mode 100644 index 04e2611f53..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12SwapChain.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __DX12SWAPCHAIN__ -#define __DX12SWAPCHAIN__ - -#include "DX12Base.hpp" -#include "DX12CommandList.hpp" -#include "DX12AsyncCommandQueue.hpp" - -#include - -class CCryDX12SwapChain; - -namespace DX12 -{ - class SwapChain : public AzRHI::ReferenceCounted - { - public: - static SwapChain* Create(CommandList* pDevice, IDXGIFactory1* factory, DXGI_SWAP_CHAIN_DESC* pDesc); - - protected: - SwapChain(CommandList* pDevice, IDXGISwapChain3* dxgiSwapChain, DXGI_SWAP_CHAIN_DESC* pDesc); - - virtual ~SwapChain(); - - public: - inline IDXGISwapChain3* GetDXGISwapChain() const - { - return m_NativeSwapChain; - } - - inline Resource& GetBackBuffer(AZ::u32 index) - { - Resource* resource = m_BackBuffers[index]; - AZ_Assert(resource, "null backbuffer"); - return *resource; - } - inline Resource& GetCurrentBackBuffer() - { - Resource* resource = m_BackBuffers[m_NativeSwapChain->GetCurrentBackBufferIndex()]; - AZ_Assert(resource, "Resource is null"); - return *resource; - } - - inline ResourceView& GetBackBufferView(AZ::u32 index) - { - return m_BackBufferViews[index]; - } - - inline ResourceView& GetCurrentBackBufferView() - { - return m_BackBufferViews[m_NativeSwapChain->GetCurrentBackBufferIndex()]; - } - - inline AZ::u32 GetCurrentBackBufferIndex() const - { - return m_NativeSwapChain->GetCurrentBackBufferIndex(); - } - - inline const DXGI_SWAP_CHAIN_DESC& GetDesc() const - { - return m_Desc; - } - - HRESULT Present(AZ::u32 SyncInterval, AZ::u32 Flags); - - private: - friend class ::CCryDX12SwapChain; - void AcquireBuffers(AZStd::vector&& resource); - void ForfeitBuffers(); - - AsyncCommandQueue& m_AsyncQueue; - CommandList* m_CommandList; - - DXGI_SWAP_CHAIN_DESC m_Desc; - - SmartPtr m_NativeSwapChain; - - AZStd::vector m_BackBuffers; - AZStd::vector m_BackBufferViews; - }; -} - -#endif // __DX12SWAPCHAIN__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.cpp deleted file mode 100644 index 47b8e81b83..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12TimerHeap.h" -#include "DX12CommandList.hpp" - -namespace DX12 -{ - TimerHeap::TimerHeap(Device& device) - : m_TimerCountMax{} - , m_TimestampDownloadBuffer{} - , m_TimestampHeap{ &device } - {} - - void TimerHeap::Init(AZ::u32 timerCountMax) - { - Shutdown(); - - D3D12_QUERY_HEAP_DESC m_Desc; - m_Desc.NodeMask = 1; - m_Desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; - m_Desc.Count = timerCountMax * 2; - - Device& device = *m_TimestampHeap.GetDevice(); - - m_TimerCountMax = timerCountMax; - m_TimestampHeap.Init(m_TimestampHeap.GetDevice(), m_Desc); - - ID3D12Resource* resource = nullptr; - const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_READBACK); - const CD3DX12_RESOURCE_DESC timestampHeapBuffer = CD3DX12_RESOURCE_DESC::Buffer(sizeof(UINT64) * m_TimestampHeap.GetCapacity()); - if (S_OK != device.GetD3D12Device()->CreateCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - ×tampHeapBuffer, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_GRAPHICS_PPV_ARGS(&resource))) - { - DX12_ERROR("Could not create intermediate timestamp download buffer!"); - } - - m_TimestampDownloadBuffer.attach(resource); - m_Timers.reserve(timerCountMax); - } - - void TimerHeap::Shutdown() - { - m_TimestampHeap.Reset(); - m_TimestampDownloadBuffer.reset(); - m_Timers.clear(); - m_TimerCountMax = 0; - } - - void TimerHeap::Begin() - { - m_Timers.clear(); - } - - void TimerHeap::End(CommandList& commandList) - { - commandList.ResolveQueryData(m_TimestampHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, m_TimestampHeap.GetCapacity(), m_TimestampDownloadBuffer, 0); - } - - TimerHandle TimerHeap::BeginTimer(CommandList& commandList, const char* name) - { - if (m_Timers.size() < m_TimerCountMax) - { - TimerHandle handle = TimerHandle(m_Timers.size()); - - m_Timers.emplace_back(); - - Timer& timer = m_Timers.back(); - timer.m_Name = name; - timer.m_Duration = 0; - timer.m_Timestamp = 0; - - commandList.EndQuery(m_TimestampHeap, D3D12_QUERY_TYPE_TIMESTAMP, handle * 2); - return handle; - } - - return TimerHandle(-1); - } - - void TimerHeap::EndTimer(CommandList& commandList, TimerHandle handle) - { - if (handle != TimerHandle(-1)) - { - commandList.EndQuery(m_TimestampHeap, D3D12_QUERY_TYPE_TIMESTAMP, handle * 2 + 1); - } - } - - void TimerHeap::ReadbackTimers() - { - AZ::u64* timestamps = nullptr; - const D3D12_RANGE readRange = { 0, sizeof(UINT64) * m_TimestampHeap.GetCapacity() }; - m_TimestampDownloadBuffer->Map(0, &readRange, (void**)×tamps); - - Device& device = *m_TimestampHeap.GetDevice(); - - for (AZ::u64 i = 0; i < m_Timers.size(); ++i) - { - AZ::u64 timestampBegin = device.MakeCpuTimestampMicroseconds(timestamps[i * 2]); - AZ::u64 timestampEnd = device.MakeCpuTimestampMicroseconds(timestamps[i * 2 + 1]); - - m_Timers[i].m_Timestamp = timestampBegin; - m_Timers[i].m_Duration = AZ::u32(timestampEnd - timestampBegin); - } - - m_TimestampDownloadBuffer->Unmap(0, nullptr); - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.h b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.h deleted file mode 100644 index 095f47e241..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12TimerHeap.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "DX12QueryHeap.hpp" - -#include - -#define DX12_GPU_PROFILE_MODE_OFF 0 // Turn off profiling -#define DX12_GPU_PROFILE_MODE_BASIC 1 // Profiles command list lifetime -#define DX12_GPU_PROFILE_MODE_DETAIL 2 // Profiles draw call state changes -#define DX12_GPU_PROFILE_MODE DX12_GPU_PROFILE_MODE_OFF - -namespace DX12 -{ - struct Timer - { - const char* m_Name; - AZ::u64 m_Timestamp; - AZ::u32 m_Duration; - }; - - class CommandList; - - using TimerHandle = AZ::u32; - - class TimerHeap - { - public: - TimerHeap(Device& device); - - void Init(AZ::u32 timerCountMax); - void Shutdown(); - - void Begin(); - void End(CommandList& commandList); - - TimerHandle BeginTimer(CommandList& commandList, const char* name); - void EndTimer(CommandList& commandList, TimerHandle handle); - - void ReadbackTimers(); - - const AZStd::vector& GetTimers() const - { - return m_Timers; - } - - private: - QueryHeap m_TimestampHeap; - SmartPtr m_TimestampDownloadBuffer; - AZStd::vector m_Timers; - AZ::u32 m_TimerCountMax; - }; - - class ScopedTimer - { - public: - ScopedTimer(TimerHeap& timers, CommandList& commandList, const char* name) - : m_Timers(timers) - , m_CommandList(commandList) - { - m_Handle = timers.BeginTimer(commandList, name); - } - - ~ScopedTimer() - { - m_Timers.EndTimer(m_CommandList, m_Handle); - } - - private: - TimerHeap& m_Timers; - CommandList& m_CommandList; - TimerHandle m_Handle; - }; -} - - // Conditionally disable timing at compile-time based on profile policy -#if DX12_GPU_PROFILE_MODE == DX12_GPU_PROFILE_MODE_DETAIL -#define DX12_COMMANDLIST_TIMER(name) DX12::ScopedTimer timer__(m_Timers, *this, name); -#define DX12_COMMANDLIST_TIMER_DETAIL(name) DX12_COMMANDLIST_TIMER(name) -#elif DX12_GPU_PROFILE_MODE == DX12_GPU_PROFILE_MODE_BASIC -#define DX12_COMMANDLIST_TIMER(name) DX12::ScopedTimer timer__(m_Timers, *this, name); -#define DX12_COMMANDLIST_TIMER_DETAIL(name) -#else -#define DX12_COMMANDLIST_TIMER(name) -#define DX12_COMMANDLIST_TIMER_DETAIL(name) -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.cpp deleted file mode 100644 index ecf2a3ad2f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "DX12View.hpp" -#include "DX12Resource.hpp" -#include "DX12SwapChain.hpp" - -namespace DX12 -{ - //--------------------------------------------------------------------------------------------------------------------- - ResourceView::ResourceView() - : AzRHI::ReferenceCounted() - , m_pResource(nullptr) - , m_DescriptorHandle(INVALID_CPU_DESCRIPTOR_HANDLE) - , m_Type(EVT_Unknown) - , m_HasDesc(true) - , m_Size(0) - { - // clear before use - memset(&m_unDSVDesc, 0, sizeof(m_unDSVDesc)); - memset(&m_unRTVDesc, 0, sizeof(m_unRTVDesc)); - memset(&m_unVBVDesc, 0, sizeof(m_unVBVDesc)); - memset(&m_unCBVDesc, 0, sizeof(m_unCBVDesc)); - memset(&m_unSRVDesc, 0, sizeof(m_unSRVDesc)); - memset(&m_unUAVDesc, 0, sizeof(m_unUAVDesc)); - } - - ResourceView::ResourceView(ResourceView&& v) - : m_pResource(std::move(v.m_pResource)) - , m_DescriptorHandle(std::move(v.m_DescriptorHandle)) - , m_Type(std::move(v.m_Type)) - , m_HasDesc(std::move(v.m_HasDesc)) - , m_Size(std::move(v.m_Size)) - { - m_unDSVDesc = std::move(v.m_unDSVDesc); - m_unRTVDesc = std::move(v.m_unRTVDesc); - m_unVBVDesc = std::move(v.m_unVBVDesc); - m_unCBVDesc = std::move(v.m_unCBVDesc); - m_unSRVDesc = std::move(v.m_unSRVDesc); - m_unUAVDesc = std::move(v.m_unUAVDesc); - - v.m_pResource = nullptr; - v.m_DescriptorHandle = INVALID_CPU_DESCRIPTOR_HANDLE; - } - - ResourceView& ResourceView::operator=(ResourceView&& v) - { - m_pResource = std::move(v.m_pResource); - m_DescriptorHandle = std::move(v.m_DescriptorHandle); - m_Type = std::move(v.m_Type); - m_HasDesc = std::move(v.m_HasDesc); - m_Size = std::move(v.m_Size); - - m_unDSVDesc = std::move(v.m_unDSVDesc); - m_unRTVDesc = std::move(v.m_unRTVDesc); - m_unVBVDesc = std::move(v.m_unVBVDesc); - m_unCBVDesc = std::move(v.m_unCBVDesc); - m_unSRVDesc = std::move(v.m_unSRVDesc); - m_unUAVDesc = std::move(v.m_unUAVDesc); - - v.m_pResource = nullptr; - v.m_DescriptorHandle = INVALID_CPU_DESCRIPTOR_HANDLE; - - return *this; - } - - //--------------------------------------------------------------------------------------------------------------------- - ResourceView::~ResourceView() - { - } - - //--------------------------------------------------------------------------------------------------------------------- - //template - ID3D12Resource* ResourceView::GetD3D12Resource() const - { - return m_pResource->GetD3D12Resource(); - } - - //--------------------------------------------------------------------------------------------------------------------- - bool ResourceView::Init(Resource& resource, EViewType type, UINT64 size) - { - DX12_ASSERT(type != EVT_Unknown); - const D3D12_RESOURCE_DESC& desc = resource.GetDesc(); - - m_pResource = &resource; - m_Type = type; - m_Size = size; - - switch (type) - { - case EVT_VertexBufferView: - m_unVBVDesc.BufferLocation = resource.GetGPUVirtualAddress(); - m_unVBVDesc.SizeInBytes = static_cast(m_Size); - break; - - case EVT_IndexBufferView: - m_unIBVDesc.BufferLocation = resource.GetGPUVirtualAddress(); - m_unIBVDesc.SizeInBytes = static_cast(m_Size); - break; - - case EVT_ConstantBufferView: - // Align to 256 bytes as required by DX12 - m_Size = (m_Size + 255) & ~255; - - m_unCBVDesc.BufferLocation = resource.GetGPUVirtualAddress(); - m_unCBVDesc.SizeInBytes = static_cast(m_Size); - break; - - // The *View descriptions have all the same structure and identical enums - case EVT_ShaderResourceView: - case EVT_UnorderedAccessView: - case EVT_DepthStencilView: - case EVT_RenderTargetView: - m_unSRVDesc.Format = desc.Format; - - switch (desc.Dimension) - { - case D3D12_RESOURCE_DIMENSION_BUFFER: - m_unSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; - break; - case D3D12_RESOURCE_DIMENSION_TEXTURE1D: - m_unSRVDesc.ViewDimension = desc.DepthOrArraySize <= 1 ? D3D12_SRV_DIMENSION_TEXTURE1D : D3D12_SRV_DIMENSION_TEXTURE1DARRAY; - break; - case D3D12_RESOURCE_DIMENSION_TEXTURE2D: - m_unSRVDesc.ViewDimension = desc.DepthOrArraySize <= 1 ? (desc.SampleDesc.Count <= 1 ? D3D12_SRV_DIMENSION_TEXTURE2D : D3D12_SRV_DIMENSION_TEXTURE2DMS) : (desc.SampleDesc.Count <= 1 ? D3D12_SRV_DIMENSION_TEXTURE2DARRAY : D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY); - break; - case D3D12_RESOURCE_DIMENSION_TEXTURE3D: - m_unSRVDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; - break; - - default: - DX12_NOT_IMPLEMENTED; - break; - } - break; - } - - return true; - } -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.hpp deleted file mode 100644 index 26547dce73..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12View.hpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __DX12VIEW__ -#define __DX12VIEW__ - -#include "DX12Base.hpp" - -namespace DX12 -{ - class SwapChain; - - enum EViewType - { - EVT_Unknown = 0, - EVT_VertexBufferView, - EVT_IndexBufferView, - EVT_ConstantBufferView, - EVT_ShaderResourceView, - EVT_UnorderedAccessView, - EVT_DepthStencilView, - EVT_RenderTargetView - }; - - class ResourceView - : public AzRHI::ReferenceCounted - { - public: - ResourceView(); - virtual ~ResourceView(); - - ResourceView(ResourceView&& r); - ResourceView& operator=(ResourceView&& r); - - bool Init(Resource& resource, EViewType type, UINT64 size = 0); - - //template - ID3D12Resource* GetD3D12Resource() const; - - ILINE Resource& GetDX12Resource() const - { - return *m_pResource; - } - - ILINE void SetType(EViewType evt) - { - m_Type = evt; - } - ILINE EViewType GetType() const - { - return m_Type; - } - - ILINE void HasDesc(bool has) - { - m_HasDesc = has; - } - ILINE bool HasDesc() const - { - return m_HasDesc; - } - - ILINE void SetSize(UINT64 size) - { - m_Size = size; - } - ILINE UINT64 GetSize() const - { - return m_Size; - } - - ILINE D3D12_DEPTH_STENCIL_VIEW_DESC& GetDSVDesc() - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)); - return m_unDSVDesc; - } - ILINE const D3D12_DEPTH_STENCIL_VIEW_DESC& GetDSVDesc() const - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)); - return m_unDSVDesc; - } - - ILINE D3D12_RENDER_TARGET_VIEW_DESC& GetRTVDesc() - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)); - return m_unRTVDesc; - } - ILINE const D3D12_RENDER_TARGET_VIEW_DESC& GetRTVDesc() const - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)); - return m_unRTVDesc; - } - - ILINE D3D12_VERTEX_BUFFER_VIEW& GetVBVDesc() - { - // DX12_ASSERT(m_pResource && true); - return m_unVBVDesc; - } - ILINE const D3D12_VERTEX_BUFFER_VIEW& GetVBVDesc() const - { - // DX12_ASSERT(m_pResource && true); - return m_unVBVDesc; - } - - ILINE D3D12_INDEX_BUFFER_VIEW& GetIBVDesc() - { - // DX12_ASSERT(m_pResource && true); - return m_unIBVDesc; - } - ILINE const D3D12_INDEX_BUFFER_VIEW& GetIBVDesc() const - { - // DX12_ASSERT(m_pResource && true); - return m_unIBVDesc; - } - - ILINE D3D12_CONSTANT_BUFFER_VIEW_DESC& GetCBVDesc() - { - // DX12_ASSERT(m_pResource && true); - return m_unCBVDesc; - } - ILINE const D3D12_CONSTANT_BUFFER_VIEW_DESC& GetCBVDesc() const - { - // DX12_ASSERT(m_pResource && true); - return m_unCBVDesc; - } - - ILINE D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDesc() - { - // DX12_ASSERT(m_pResource && true); - return m_unSRVDesc; - } - ILINE const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDesc() const - { - // DX12_ASSERT(m_pResource && true); - return m_unSRVDesc; - } - - ILINE D3D12_UNORDERED_ACCESS_VIEW_DESC& GetUAVDesc() - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)); - return m_unUAVDesc; - } - ILINE const D3D12_UNORDERED_ACCESS_VIEW_DESC& GetUAVDesc() const - { - // DX12_ASSERT(m_pResource && (m_pResource->GetDesc().Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)); - return m_unUAVDesc; - } - - ILINE void SetDescriptorHandle(const D3D12_CPU_DESCRIPTOR_HANDLE& descriptorHandle) - { - m_DescriptorHandle = descriptorHandle; - } - ILINE D3D12_CPU_DESCRIPTOR_HANDLE GetDescriptorHandle() const - { - return m_DescriptorHandle; - } - - private: - Resource* m_pResource; - EViewType m_Type; - D3D12_CPU_DESCRIPTOR_HANDLE m_DescriptorHandle; - - union - { - D3D12_VERTEX_BUFFER_VIEW m_unVBVDesc; - D3D12_INDEX_BUFFER_VIEW m_unIBVDesc; - D3D12_CONSTANT_BUFFER_VIEW_DESC m_unCBVDesc; - D3D12_SHADER_RESOURCE_VIEW_DESC m_unSRVDesc; - D3D12_UNORDERED_ACCESS_VIEW_DESC m_unUAVDesc; - D3D12_DEPTH_STENCIL_VIEW_DESC m_unDSVDesc; - D3D12_RENDER_TARGET_VIEW_DESC m_unRTVDesc; - }; - - // Some views can be created without descriptor (DSV) - bool m_HasDesc; - - // View size in bytes - UINT64 m_Size; - }; -} - -#endif // __DX12VIEW__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.cpp deleted file mode 100644 index ae48152e2c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CCryDX12Object.hpp" diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.hpp deleted file mode 100644 index ab61c5647f..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CCryDX12Object.hpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __CCRYDX12OBJECT__ -#define __CCRYDX12OBJECT__ - -#include "API/DX12Base.hpp" - -#define DX12_BASE_OBJECT(DerivedType, InterfaceType) \ - typedef DerivedType Class; \ - typedef DX12::SmartPtr Ptr; \ - typedef DX12::SmartPtr ConstPtr; \ - typedef InterfaceType Super; \ - typedef InterfaceType Interface; \ - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) \ - { \ - if (riid == __uuidof(Super)) \ - { \ - if (ppvObject) \ - { \ - *reinterpret_cast(ppvObject) = static_cast(this); \ - static_cast(this)->AddRef(); \ - } \ - return S_OK; \ - } \ - return E_NOINTERFACE; \ - } \ - -#define DX12_OBJECT(DerivedType, SuperType) \ - typedef DerivedType Class; \ - typedef DX12::SmartPtr Ptr; \ - typedef DX12::SmartPtr ConstPtr; \ - typedef SuperType Super; \ - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) \ - { \ - if (riid == __uuidof(DerivedType)) \ - { \ - if (ppvObject) \ - { \ - *reinterpret_cast(ppvObject) = static_cast(this); \ - static_cast(this)->AddRef(); \ - } \ - return S_OK; \ - } \ - return Super::QueryInterface(riid, ppvObject); \ - } \ - -#include "CryDX12Guid.hpp" - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class CCryDX12Buffer; -class CCryDX12DepthStencilView; -class CCryDX12Device; -class CCryDX12DeviceContext; -class CCryDX12MemoryManager; -class CCryDX12Query; -class CCryDX12RenderTargetView; -class CCryDX12SamplerState; -class CCryDX12Shader; -class CCryDX12ShaderResourceView; -class CCryDX12SwapChain; -class CCryDX12Texture1D; -class CCryDX12Texture2D; -class CCryDX12Texture3D; -class CCryDX12UnorderedAccessView; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template -class CCryDX12Object - : public T -{ -public: - DX12_BASE_OBJECT(CCryDX12Object, T); - - CCryDX12Object() - : m_RefCount(0) - { - } - - virtual ~CCryDX12Object() - { - DX12_LOG("CCryDX12 object destroyed: %p", this); - } - - #pragma region /* IUnknown implementation */ - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return CryInterlockedIncrement(&m_RefCount); - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - ULONG RefCount = CryInterlockedDecrement(&m_RefCount); - if (!RefCount) - { - delete this; - return 0; - } - - return RefCount; - } - - #pragma endregion - -private: - int m_RefCount; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template -class CCryDX12GIObject - : public T -{ -public: - DX12_BASE_OBJECT(CCryDX12GIObject, T); - - CCryDX12GIObject() - : m_RefCount(0) - { - } - - virtual ~CCryDX12GIObject() - { - } - - #pragma region /* IUnknown implementation */ - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return CryInterlockedIncrement(&m_RefCount); - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - ULONG RefCount = CryInterlockedDecrement(&m_RefCount); - if (!RefCount) - { - delete this; - return 0; - } - - return RefCount; - } - - #pragma endregion - - #pragma region /* IDXGIObject implementation */ - - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - [[maybe_unused]] _In_ REFGUID Name, - [[maybe_unused]] UINT DataSize, - [[maybe_unused]] _In_reads_bytes_(DataSize) const void* pData) - { - return -1; - } - - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - [[maybe_unused]] _In_ REFGUID Name, - [[maybe_unused]] _In_ const IUnknown* pUnknown) - { - return -1; - } - - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - [[maybe_unused]] _In_ REFGUID Name, - [[maybe_unused]] _Inout_ UINT* pDataSize, - [[maybe_unused]] _Out_writes_bytes_(*pDataSize) void* pData) - { - return -1; - } - - virtual HRESULT STDMETHODCALLTYPE GetParent( - [[maybe_unused]] _In_ REFIID riid, - [[maybe_unused]] _Out_ void** ppParent) - { - return -1; - } - - #pragma endregion - -private: - int m_RefCount; -}; - -#endif // __CCRYDX12OBJECT__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.cpp deleted file mode 100644 index 2a4125265c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CryDX12.hpp" - -#include "GI/CCryDX12GIFactory.hpp" -#include "Device/CCryDX12Device.hpp" -#include "Device/CCryDX12DeviceContext.hpp" - -HRESULT WINAPI DX12CreateDXGIFactory1([[maybe_unused]] REFIID riid, void** ppFactory) -{ - *ppFactory = CCryDX12GIFactory::Create(); - return *ppFactory ? 0 : -1; -} - -HRESULT WINAPI DX12CreateDevice( - IDXGIAdapter* pAdapter, - [[maybe_unused]] D3D_DRIVER_TYPE DriverType, - [[maybe_unused]] HMODULE Software, - [[maybe_unused]] UINT Flags, - [[maybe_unused]] CONST D3D_FEATURE_LEVEL* pFeatureLevels, - [[maybe_unused]] UINT FeatureLevels, - [[maybe_unused]] UINT SDKVersion, - ID3D11Device** ppDevice, - D3D_FEATURE_LEVEL* pFeatureLevel, - ID3D11DeviceContext** ppImmediateContext) -{ - *ppDevice = CCryDX12Device::Create(pAdapter, pFeatureLevel); - - if (!*ppDevice) - { - return -1; - } - - (*ppDevice)->GetImmediateContext(ppImmediateContext); - - if (!*ppImmediateContext) - { - return -1; - } - - return 0; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.hpp deleted file mode 100644 index 679b1ea3e4..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#include "CryDX12Legacy.hpp" - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#include "API/DX12Base.hpp" -#include "API/DX12PSO.hpp" -#include "Misc/SCryDX11PipelineState.hpp" - -#include "XRenderD3D9/DX12/GI/CCryDX12GIFactory.hpp" -#include "XRenderD3D9/DX12/GI/CCryDX12SwapChain.hpp" -#include "XRenderD3D9/DX12/Device/CCryDX12Device.hpp" -#include "XRenderD3D9/DX12/Device/CCryDX12DeviceContext.hpp" -typedef IDXGIDevice1 DXGIDevice; -typedef IDXGIAdapter1 DXGIAdapter; -typedef CCryDX12GIFactory DXGIFactory; -typedef IDXGIOutput DXGIOutput; -typedef CCryDX12SwapChain DXGISwapChain; -typedef CCryDX12Device D3DDevice; -typedef CCryDX12DeviceContext D3DDeviceContext; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -HRESULT WINAPI DX12CreateDXGIFactory1(REFIID riid, void** ppFactory); - -HRESULT WINAPI DX12CreateDevice( - IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - ID3D11Device** ppDevice, - D3D_FEATURE_LEVEL* pFeatureLevel, - ID3D11DeviceContext** ppImmediateContext); diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Base.h b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Base.h deleted file mode 100644 index 16828a9627..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Base.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Guid.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Guid.hpp deleted file mode 100644 index 70fb9b3b23..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Guid.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define CRYDX12GUID_HPP_SECTION_1 1 -#endif - -#define DX12_DEFINE_TYPE_GUID(_CLASS, _TYPE, X) \ - _CLASS __declspec(uuid(X)) _TYPE; - -DX12_DEFINE_TYPE_GUID(class, CCryDX12GIAdapter, "59e4cc3a-87bb-4b7b-a1e3-06787231384a"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12GIFactory, "af688514-87ba-4c1c-9927-5a349ede6d74"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12GIOutput, "038b29e3-2d4b-49c0-a726-494675697b76"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12SwapChain, "d9e49be8-2651-4bc7-bfaa-303cb964a76e"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Device, "f9c01631-d950-444c-a480-68bbb85fb28c"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12DeviceContext, "23ec965a-a01c-4862-b8b8-f53cf8cd7dcc"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Texture1D, "dd8eb017-6cdb-4790-a767-52817c222d57"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Texture2D, "4dff2102-e08a-497e-b519-1c07124b36b3"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Texture3D, "003527af-f60d-4d93-b5d8-6370964e7692"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12DepthStencilView, "4fdfce9f-c7c9-44e7-99c5-64c24e5ed31a"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12RenderTargetView, "8b1d7ea0-0313-4eaa-8ddb-6e25b7eb7a7c"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12UnorderedAccessView, "ce7c421a-b6a5-42b2-a8cd-7a34bf23426b"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12ShaderResourceView, "b4639da3-fc4e-4907-942a-dae7e86e9eeb"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Query, "3dd1b810-4a04-4719-bb8b-14f5936479f9"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12BlendState, "3bb119a1-5c56-4251-8fbf-c874d5d3f101"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12RasterizerState, "4c3c2198-2011-4dbd-a310-7dabca10e55d"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12DepthStencilState, "f28f8fb4-e55d-4f98-88ed-fa3aab12be7b"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12InputLayout, "3b74fa4e-c2b6-4167-a014-bf2f91f16ddd"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Buffer, "06b2a225-e1aa-4509-b5da-f0fd1d846ba6"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12Shader, "7052b765-cc86-42e8-b116-36dc3bf4cfee"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12SamplerState, "a841545b-c5a6-4481-9383-a46ec1c2c380"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12EventQuery, "0d8f741f-4051-4935-a50d-58353f825e45"); -DX12_DEFINE_TYPE_GUID(class, CCryDX12ResourceQuery, "6f1c2c43-3da7-489a-b1df-0c27362addbe"); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYDX12GUID_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(CryDX12Guid_hpp) -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Legacy.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Legacy.hpp deleted file mode 100644 index 9f570c386c..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/CryDX12Legacy.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if defined(WIN32) - #include - #include - #include - #include - #include -#endif - -#if !defined(D3D_OK) -#define D3D_OK 0 -#endif - -#if !defined(S_OK) -#define S_OK 0 -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.cpp deleted file mode 100644 index ce8d70ee70..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.cpp +++ /dev/null @@ -1,781 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CCryDX12Device.hpp" - -#include "CCryDX12DeviceContext.hpp" - -#include "DX12/Resource/Misc/CCryDX12Buffer.hpp" -#include "DX12/Resource/Misc/CCryDX12InputLayout.hpp" -#include "DX12/Resource/Misc/CCryDX12Query.hpp" -#include "DX12/Resource/Misc/CCryDX12Shader.hpp" - -#include "DX12/Resource/State/CCryDX12BlendState.hpp" -#include "DX12/Resource/State/CCryDX12DepthStencilState.hpp" -#include "DX12/Resource/State/CCryDX12RasterizerState.hpp" -#include "DX12/Resource/State/CCryDX12SamplerState.hpp" - -#include "DX12/Resource/Texture/CCryDX12Texture1D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture2D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture3D.hpp" - -#include "DX12/Resource/View/CCryDX12DepthStencilView.hpp" -#include "DX12/Resource/View/CCryDX12RenderTargetView.hpp" -#include "DX12/Resource/View/CCryDX12ShaderResourceView.hpp" -#include "DX12/Resource/View/CCryDX12UnorderedAccessView.hpp" - -CCryDX12Device* CCryDX12Device::Create(IDXGIAdapter* pAdapter, D3D_FEATURE_LEVEL* pFeatureLevel) -{ - DX12::SmartPtr device; - device.attach(DX12::Device::Create(pAdapter, pFeatureLevel)); - - if (!device) - { - DX12_ERROR("Could not create DX12 Device!"); - return NULL; - } - - return DX12::PassAddRef(new CCryDX12Device(device)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CCryDX12Device::CCryDX12Device(DX12::Device* device) - : Super() - , m_pDevice(device) -{ - DX12_FUNC_LOG - m_pContext.attach(CCryDX12DeviceContext::Create(this)); -} - -CCryDX12Device::~CCryDX12Device() -{ - DX12_FUNC_LOG -} - -#pragma region /* ID3D11Device implementation */ - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateBuffer( - _In_ const D3D11_BUFFER_DESC* pDesc, - _In_opt_ const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Buffer** ppBuffer) -{ - AZ_TRACE_METHOD(); - *ppBuffer = CCryDX12Buffer::Create(this, pDesc, pInitialData); - return *ppBuffer ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture1D( - _In_ const D3D11_TEXTURE1D_DESC* pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture1D** ppTexture1D) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppTexture1D = CCryDX12Texture1D::Create(this, nullptr, pDesc, pInitialData); - return *ppTexture1D ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture2D( - _In_ const D3D11_TEXTURE2D_DESC* pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture2D** ppTexture2D) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppTexture2D = CCryDX12Texture2D::Create(this, nullptr, pDesc, pInitialData); - return *ppTexture2D ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture3D( - _In_ const D3D11_TEXTURE3D_DESC* pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture3D** ppTexture3D) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppTexture3D = CCryDX12Texture3D::Create(this, nullptr, pDesc, pInitialData); - return *ppTexture3D ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateShaderResourceView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, - _Out_opt_ ID3D11ShaderResourceView** ppSRView) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppSRView = NULL; - - if (CCryDX12ShaderResourceView* pResult = CCryDX12ShaderResourceView::Create(this, pResource, pDesc)) - { - auto descriptorHandle = GetDX12Device()->CacheShaderResourceView(&pResult->GetDX12View().GetSRVDesc(), DX12_EXTRACT_D3D12RESOURCE(pResource)); - pResult->GetDX12View().SetDescriptorHandle(descriptorHandle); - - if (INVALID_CPU_DESCRIPTOR_HANDLE == descriptorHandle) - { - SAFE_RELEASE(pResult); - } - - *ppSRView = pResult; - } - - return *ppSRView ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateUnorderedAccessView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, - _Out_opt_ ID3D11UnorderedAccessView** ppUAView) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppUAView = NULL; - - if (CCryDX12UnorderedAccessView* pResult = CCryDX12UnorderedAccessView::Create(this, pResource, pDesc)) - { - auto descriptorHandle = GetDX12Device()->CacheUnorderedAccessView(&pResult->GetDX12View().GetUAVDesc(), DX12_EXTRACT_D3D12RESOURCE(pResource)); - pResult->GetDX12View().SetDescriptorHandle(descriptorHandle); - - if (INVALID_CPU_DESCRIPTOR_HANDLE == descriptorHandle) - { - SAFE_RELEASE(pResult); - } - - *ppUAView = pResult; - } - - return *ppUAView ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateRenderTargetView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, - _Out_opt_ ID3D11RenderTargetView** ppRTView) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppRTView = NULL; - - if (CCryDX12RenderTargetView* pResult = CCryDX12RenderTargetView::Create(this, pResource, pDesc)) - { - auto descriptorHandle = GetDX12Device()->CacheRenderTargetView(&pResult->GetDX12View().GetRTVDesc(), DX12_EXTRACT_D3D12RESOURCE(pResource)); - pResult->GetDX12View().SetDescriptorHandle(descriptorHandle); - - if (INVALID_CPU_DESCRIPTOR_HANDLE == descriptorHandle) - { - SAFE_RELEASE(pResult); - } - - *ppRTView = pResult; - } - - return *ppRTView ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDepthStencilView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, - _Out_opt_ ID3D11DepthStencilView** ppDSView) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - * ppDSView = NULL; - - if (CCryDX12DepthStencilView* pResult = CCryDX12DepthStencilView::Create(this, pResource, pDesc)) - { - auto descriptorHandle = GetDX12Device()->CacheDepthStencilView(&pResult->GetDX12View().GetDSVDesc(), DX12_EXTRACT_D3D12RESOURCE(pResource)); - pResult->GetDX12View().SetDescriptorHandle(descriptorHandle); - - if (INVALID_CPU_DESCRIPTOR_HANDLE == descriptorHandle) - { - SAFE_RELEASE(pResult); - } - - *ppDSView = pResult; - } - - return *ppDSView ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateInputLayout( - _In_reads_(NumElements) const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, - _In_range_(0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT) UINT NumElements, - _In_ const void* pShaderBytecodeWithInputSignature, - _In_ SIZE_T BytecodeLength, - _Out_opt_ ID3D11InputLayout** ppInputLayout) -{ - DX12_FUNC_LOG - * ppInputLayout = CCryDX12InputLayout::Create(this, pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength); - return *ppInputLayout ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateVertexShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11VertexShader** ppVertexShader) -{ - DX12_FUNC_LOG - * ppVertexShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppVertexShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateGeometryShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11GeometryShader** ppGeometryShader) -{ - DX12_FUNC_LOG - * ppGeometryShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppGeometryShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateGeometryShaderWithStreamOutput( - [[maybe_unused]] _In_ const void* pShaderBytecode, - [[maybe_unused]] _In_ SIZE_T BytecodeLength, - [[maybe_unused]] _In_reads_opt_(NumEntries) const D3D11_SO_DECLARATION_ENTRY* pSODeclaration, - [[maybe_unused]] _In_range_(0, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT) UINT NumEntries, - [[maybe_unused]] _In_reads_opt_(NumStrides) const UINT* pBufferStrides, - [[maybe_unused]] _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumStrides, - [[maybe_unused]] _In_ UINT RasterizedStream, - [[maybe_unused]] _In_opt_ ID3D11ClassLinkage* pClassLinkage, - [[maybe_unused]] _Out_opt_ ID3D11GeometryShader** ppGeometryShader) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreatePixelShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11PixelShader** ppPixelShader) -{ - DX12_FUNC_LOG - * ppPixelShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppPixelShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateHullShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11HullShader** ppHullShader) -{ - DX12_FUNC_LOG - * ppHullShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppHullShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDomainShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11DomainShader** ppDomainShader) -{ - DX12_FUNC_LOG - * ppDomainShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppDomainShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateComputeShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11ComputeShader** ppComputeShader) -{ - DX12_FUNC_LOG - * ppComputeShader = reinterpret_cast(CCryDX12Shader::Create(this, pShaderBytecode, BytecodeLength, pClassLinkage)); - return *ppComputeShader ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateClassLinkage( - [[maybe_unused]] _Out_ ID3D11ClassLinkage** ppLinkage) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateBlendState( - _In_ const D3D11_BLEND_DESC* pBlendStateDesc, - _Out_opt_ ID3D11BlendState** ppBlendState) -{ - DX12_FUNC_LOG - * ppBlendState = CCryDX12BlendState::Create(pBlendStateDesc); - return *ppBlendState ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDepthStencilState( - _In_ const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, - _Out_opt_ ID3D11DepthStencilState** ppDepthStencilState) -{ - DX12_FUNC_LOG - * ppDepthStencilState = CCryDX12DepthStencilState::Create(pDepthStencilDesc); - return *ppDepthStencilState ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateRasterizerState( - _In_ const D3D11_RASTERIZER_DESC* pRasterizerDesc, - _Out_opt_ ID3D11RasterizerState** ppRasterizerState) -{ - DX12_FUNC_LOG - * ppRasterizerState = CCryDX12RasterizerState::Create(pRasterizerDesc); - return *ppRasterizerState ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateSamplerState( - _In_ const D3D11_SAMPLER_DESC* pSamplerDesc, - _Out_opt_ ID3D11SamplerState** ppSamplerState) -{ - DX12_FUNC_LOG - * ppSamplerState = NULL; - - if (CCryDX12SamplerState* pResult = CCryDX12SamplerState::Create(pSamplerDesc)) - { - auto descriptorHandle = GetDX12Device()->CacheSampler(&pResult->GetDX12SamplerState().GetSamplerDesc()); - pResult->GetDX12SamplerState().SetDescriptorHandle(descriptorHandle); - - if (INVALID_CPU_DESCRIPTOR_HANDLE == descriptorHandle) - { - SAFE_RELEASE(pResult); - } - - *ppSamplerState = pResult; - } - - return *ppSamplerState ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateQuery( - _In_ const D3D11_QUERY_DESC* pQueryDesc, - _Out_opt_ ID3D11Query** ppQuery) -{ - *ppQuery = CCryDX12Query::Create(GetD3D12Device(), pQueryDesc); - return *ppQuery ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreatePredicate( - [[maybe_unused]] _In_ const D3D11_QUERY_DESC* pPredicateDesc, - [[maybe_unused]] _Out_opt_ ID3D11Predicate** ppPredicate) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateCounter( - [[maybe_unused]] _In_ const D3D11_COUNTER_DESC* pCounterDesc, - [[maybe_unused]] _Out_opt_ ID3D11Counter** ppCounter) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDeferredContext( - [[maybe_unused]] UINT ContextFlags, - [[maybe_unused]] _Out_opt_ ID3D11DeviceContext** ppDeferredContext) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::OpenSharedResource( - [[maybe_unused]] _In_ HANDLE hResource, - [[maybe_unused]] _In_ REFIID ReturnedInterface, - [[maybe_unused]] _Out_opt_ void** ppResource) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CheckFormatSupport( - _In_ DXGI_FORMAT Format, - _Out_ UINT* pFormatSupport) -{ - DX12_FUNC_LOG - D3D12_FEATURE_DATA_FORMAT_SUPPORT data; - data.Format = Format; - - if (S_OK != m_pDevice->GetD3D12Device()->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(D3D12_FEATURE_DATA_FORMAT_SUPPORT))) - { - return S_FALSE; - } - - *pFormatSupport = data.Support1; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CheckMultisampleQualityLevels( - [[maybe_unused]] _In_ DXGI_FORMAT Format, - [[maybe_unused]] _In_ UINT SampleCount, - [[maybe_unused]] _Out_ UINT* pNumQualityLevels) -{ - DX12_FUNC_LOG - return -1; -} - -void STDMETHODCALLTYPE CCryDX12Device::CheckCounterInfo( - [[maybe_unused]] _Out_ D3D11_COUNTER_INFO* pCounterInfo) -{ - DX12_FUNC_LOG -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CheckCounter( - [[maybe_unused]] _In_ const D3D11_COUNTER_DESC* pDesc, - [[maybe_unused]] _Out_ D3D11_COUNTER_TYPE* pType, - [[maybe_unused]] _Out_ UINT* pActiveCounters, - [[maybe_unused]] _Out_writes_opt_(*pNameLength) LPSTR szName, - [[maybe_unused]] _Inout_opt_ UINT* pNameLength, - [[maybe_unused]] _Out_writes_opt_(*pUnitsLength) LPSTR szUnits, - [[maybe_unused]] _Inout_opt_ UINT* pUnitsLength, - [[maybe_unused]] _Out_writes_opt_(*pDescriptionLength) LPSTR szDescription, - [[maybe_unused]] _Inout_opt_ UINT* pDescriptionLength) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CheckFeatureSupport( - D3D11_FEATURE Feature, - _Out_writes_bytes_(FeatureSupportDataSize) void* pFeatureSupportData, - [[maybe_unused]] UINT FeatureSupportDataSize) -{ - DX12_FUNC_LOG - - switch (Feature) - { - case D3D11_FEATURE_D3D11_OPTIONS2: - { - D3D11_FEATURE_DATA_D3D11_OPTIONS2* dx11FeatureDataOptions2 = static_cast(pFeatureSupportData); - HRESULT result; - - D3D12_FEATURE_DATA_D3D12_OPTIONS dx12FeatureDataOptions; - result = m_pDevice->GetD3D12Device()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &dx12FeatureDataOptions, sizeof(dx12FeatureDataOptions)); - if (result == S_OK) - { - dx11FeatureDataOptions2->PSSpecifiedStencilRefSupported = dx12FeatureDataOptions.PSSpecifiedStencilRefSupported; - dx11FeatureDataOptions2->TypedUAVLoadAdditionalFormats = dx12FeatureDataOptions.TypedUAVLoadAdditionalFormats; - dx11FeatureDataOptions2->ROVsSupported = dx12FeatureDataOptions.ROVsSupported; - dx11FeatureDataOptions2->MapOnDefaultTextures = true; // Assumed true in DX12 - dx11FeatureDataOptions2->StandardSwizzle = dx12FeatureDataOptions.StandardSwizzle64KBSupported; - - switch (dx12FeatureDataOptions.ConservativeRasterizationTier) - { - case D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED: - dx11FeatureDataOptions2->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; - break; - case D3D12_CONSERVATIVE_RASTERIZATION_TIER_1: - dx11FeatureDataOptions2->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_TIER_1; - break; - case D3D12_CONSERVATIVE_RASTERIZATION_TIER_2: - dx11FeatureDataOptions2->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_TIER_2; - break; - case D3D12_CONSERVATIVE_RASTERIZATION_TIER_3: - dx11FeatureDataOptions2->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_TIER_3; - break; - } - - switch (dx12FeatureDataOptions.TiledResourcesTier) - { - case D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED: - dx11FeatureDataOptions2->TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED; - break; - case D3D12_TILED_RESOURCES_TIER_1: - dx11FeatureDataOptions2->TiledResourcesTier = D3D11_TILED_RESOURCES_TIER_1; - break; - case D3D12_TILED_RESOURCES_TIER_2: - dx11FeatureDataOptions2->TiledResourcesTier = D3D11_TILED_RESOURCES_TIER_2; - break; - case D3D12_TILED_RESOURCES_TIER_3: - dx11FeatureDataOptions2->TiledResourcesTier = D3D11_TILED_RESOURCES_TIER_3; - break; - } - } - else - { - return E_INVALIDARG; - } - - - D3D12_FEATURE_DATA_ARCHITECTURE dx12FeatureDataArchitecture; - dx12FeatureDataArchitecture.NodeIndex = 0; - result = m_pDevice->GetD3D12Device()->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &dx12FeatureDataArchitecture, sizeof(dx12FeatureDataArchitecture)); - if (result == S_OK) - { - dx11FeatureDataOptions2->UnifiedMemoryArchitecture = dx12FeatureDataArchitecture.UMA; - } - else - { - return E_INVALIDARG; - } - - break; - } - default: - AZ_Assert(false, "No conversion to DX12 has been written for this feature support check."); - return E_INVALIDARG; - } - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::GetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _Inout_ UINT* pDataSize, - [[maybe_unused]] _Out_writes_bytes_opt_(*pDataSize) void* pData) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::SetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_ UINT DataSize, - [[maybe_unused]] _In_reads_bytes_opt_(DataSize) const void* pData) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::SetPrivateDataInterface( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_opt_ const IUnknown* pData) -{ - DX12_FUNC_LOG - return -1; -} - -D3D_FEATURE_LEVEL STDMETHODCALLTYPE CCryDX12Device::GetFeatureLevel() -{ - DX12_FUNC_LOG - return D3D_FEATURE_LEVEL_11_1; -} - -UINT STDMETHODCALLTYPE CCryDX12Device::GetCreationFlags() -{ - DX12_FUNC_LOG - return 0; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::GetDeviceRemovedReason() -{ - DX12_FUNC_LOG - return -1; -} - -void STDMETHODCALLTYPE CCryDX12Device::GetImmediateContext( - _Out_ ID3D11DeviceContext** ppImmediateContext) -{ - DX12_FUNC_LOG - if (ppImmediateContext) - { - *ppImmediateContext = m_pContext; - (*ppImmediateContext)->AddRef(); - } -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::SetExceptionMode( - [[maybe_unused]] UINT RaiseFlags) -{ - DX12_FUNC_LOG - return -1; -} - -UINT STDMETHODCALLTYPE CCryDX12Device::GetExceptionMode() -{ - DX12_FUNC_LOG - return 0; -} - -#pragma endregion - -#pragma region /* ID3D11Device1 implementation */ - -void STDMETHODCALLTYPE CCryDX12Device::GetImmediateContext1( - _Out_ ID3D11DeviceContext1** ppImmediateContext) -{ - DX12_FUNC_LOG - - if (ppImmediateContext) - { - *ppImmediateContext = m_pContext; - (*ppImmediateContext)->AddRef(); - } -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDeferredContext1( - [[maybe_unused]] UINT ContextFlags, - /* [annotation] */ - [[maybe_unused]] _COM_Outptr_opt_ ID3D11DeviceContext1** ppDeferredContext) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateBlendState1( - /* [annotation] */ - [[maybe_unused]] _In_ const D3D11_BLEND_DESC1* pBlendStateDesc, - /* [annotation] */ - [[maybe_unused]] _COM_Outptr_opt_ ID3D11BlendState1** ppBlendState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateRasterizerState1( - /* [annotation] */ - [[maybe_unused]] _In_ const D3D11_RASTERIZER_DESC1* pRasterizerDesc, - /* [annotation] */ - [[maybe_unused]] _COM_Outptr_opt_ ID3D11RasterizerState1** ppRasterizerState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateDeviceContextState( - [[maybe_unused]] UINT Flags, - /* [annotation] */ - [[maybe_unused]] _In_reads_(FeatureLevels) const D3D_FEATURE_LEVEL* pFeatureLevels, - [[maybe_unused]] UINT FeatureLevels, - [[maybe_unused]] UINT SDKVersion, - [[maybe_unused]] REFIID EmulatedInterface, - /* [annotation] */ - [[maybe_unused]] _Out_opt_ D3D_FEATURE_LEVEL* pChosenFeatureLevel, - /* [annotation] */ - [[maybe_unused]] _Out_opt_ ID3DDeviceContextState** ppContextState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::OpenSharedResource1( - /* [annotation] */ - [[maybe_unused]] _In_ HANDLE hResource, - /* [annotation] */ - [[maybe_unused]] _In_ REFIID returnedInterface, - /* [annotation] */ - [[maybe_unused]] _COM_Outptr_ void** ppResource) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::OpenSharedResourceByName( - /* [annotation] */ - [[maybe_unused]] _In_ LPCWSTR lpName, - /* [annotation] */ - [[maybe_unused]] _In_ DWORD dwDesiredAccess, - /* [annotation] */ - [[maybe_unused]] _In_ REFIID returnedInterface, - /* [annotation] */ - [[maybe_unused]] _COM_Outptr_ void** ppResource) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -#pragma endregion - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture1D( - _In_ const D3D11_TEXTURE1D_DESC* pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture1D** ppTexture1D) -{ - DX12_FUNC_LOG - * ppTexture1D = CCryDX12Texture1D::Create(this, cClearValue, pDesc, pInitialData); - return *ppTexture1D ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture2D( - _In_ const D3D11_TEXTURE2D_DESC* pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture2D** ppTexture2D) -{ - DX12_FUNC_LOG - * ppTexture2D = CCryDX12Texture2D::Create(this, cClearValue, pDesc, pInitialData); - return *ppTexture2D ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateTexture3D( - _In_ const D3D11_TEXTURE3D_DESC* pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels)) const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Texture3D** ppTexture3D) -{ - DX12_FUNC_LOG - * ppTexture3D = CCryDX12Texture3D::Create(this, cClearValue, pDesc, pInitialData); - return *ppTexture3D ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::CreateStagingResource( - _In_ ID3D11Resource* pInputResource, - _Out_ ID3D11Resource** ppStagingResource, - _In_ BOOL Upload) -{ - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pInputResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - - D3D12_RESOURCE_DESC resourceDesc = rResource.GetDesc(); - UINT64 requiredSize; - UINT numSubResources = resourceDesc.MipLevels * (resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? 1 : resourceDesc.DepthOrArraySize); - GetD3D12Device()->GetCopyableFootprints(&resourceDesc, 0, numSubResources, 0, nullptr, nullptr, nullptr, &requiredSize); - - D3D12_RESOURCE_STATES initialState = Upload ? D3D12_RESOURCE_STATE_GENERIC_READ : D3D12_RESOURCE_STATE_COPY_DEST; - D3D12_HEAP_TYPE heapType = Upload ? D3D12_HEAP_TYPE_UPLOAD : D3D12_HEAP_TYPE_READBACK; - - ID3D12Resource* stagingResource = NULL; - const CD3DX12_HEAP_PROPERTIES heapProperties(heapType); - const CD3DX12_RESOURCE_DESC resourceBuffer = CD3DX12_RESOURCE_DESC::Buffer(requiredSize); - HRESULT result = GetDX12Device()->GetD3D12Device()->CreateCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - &resourceBuffer, - initialState, - nullptr, - IID_GRAPHICS_PPV_ARGS(&stagingResource)); - - if (result == S_OK && stagingResource != nullptr) - { - *ppStagingResource = CCryDX12Buffer::Create(this, stagingResource, initialState); - stagingResource->Release(); - - return S_OK; - } - - return result; -} - -HRESULT STDMETHODCALLTYPE CCryDX12Device::ReleaseStagingResource( - _In_ ID3D11Resource* pStagingResource) -{ - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pStagingResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - ID3D12Resource* d3d12Resource = rResource.GetD3D12Resource(); - - d3d12Resource->AddRef(); - d3d12Resource->SetName(L"StagingResource"); - GetDX12Device()->ReleaseLater(d3d12Resource, rResource.GetCurrentState(), rResource.GetAnnouncedState()); - - pStagingResource->Release(); - return S_OK; -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.hpp deleted file mode 100644 index 0ee5393c5b..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12Device.hpp +++ /dev/null @@ -1,341 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __CCRYDX12DEVICE__ -#define __CCRYDX12DEVICE__ - -#include "DX12/CCryDX12Object.hpp" -#include "DX12/API/DX12Device.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define CCRYDX12DEVICE_HPP_SECTION_1 1 - #define CCRYDX12DEVICE_HPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CCRYDX12DEVICE_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(CCryDX12Device_hpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - using ICCryDX12Device = ID3D11Device1; -#endif - -class CCryDX12Device - : public CCryDX12Object -{ -public: - DX12_OBJECT(CCryDX12Device, CCryDX12Object); - - static CCryDX12Device* Create(IDXGIAdapter* pAdapter, D3D_FEATURE_LEVEL* pFeatureLevel); - - CCryDX12Device(DX12::Device* device); - - virtual ~CCryDX12Device(); - - DX12::Device* GetDX12Device() const { return m_pDevice; } - - ID3D12Device* GetD3D12Device() const { return m_pDevice->GetD3D12Device(); } - - CCryDX12DeviceContext* GetDeviceContext() const { return m_pContext; } - - #pragma region /* ID3D11Device implementation */ - - virtual HRESULT STDMETHODCALLTYPE CreateBuffer( - _In_ const D3D11_BUFFER_DESC* pDesc, - _In_opt_ const D3D11_SUBRESOURCE_DATA* pInitialData, - _Out_opt_ ID3D11Buffer** ppBuffer) final; - - virtual HRESULT STDMETHODCALLTYPE CreateTexture1D( - _In_ const D3D11_TEXTURE1D_DESC * pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture1D * *ppTexture1D) final; - - virtual HRESULT STDMETHODCALLTYPE CreateTexture2D( - _In_ const D3D11_TEXTURE2D_DESC * pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture2D * *ppTexture2D) final; - - virtual HRESULT STDMETHODCALLTYPE CreateTexture3D( - _In_ const D3D11_TEXTURE3D_DESC * pDesc, - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture3D * *ppTexture3D) final; - - virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, - _Out_opt_ ID3D11ShaderResourceView** ppSRView) final; - - virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, - _Out_opt_ ID3D11UnorderedAccessView** ppUAView) final; - - virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, - _Out_opt_ ID3D11RenderTargetView** ppRTView) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView( - _In_ ID3D11Resource* pResource, - _In_opt_ const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, - _Out_opt_ ID3D11DepthStencilView** ppDepthStencilView) final; - - virtual HRESULT STDMETHODCALLTYPE CreateInputLayout( - _In_reads_(NumElements) const D3D11_INPUT_ELEMENT_DESC * pInputElementDescs, - _In_range_(0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT) UINT NumElements, - _In_ const void* pShaderBytecodeWithInputSignature, - _In_ SIZE_T BytecodeLength, - _Out_opt_ ID3D11InputLayout * *ppInputLayout) final; - - virtual HRESULT STDMETHODCALLTYPE CreateVertexShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11VertexShader** ppVertexShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateGeometryShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11GeometryShader** ppGeometryShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_reads_opt_(NumEntries) const D3D11_SO_DECLARATION_ENTRY * pSODeclaration, - _In_range_(0, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT) UINT NumEntries, - _In_reads_opt_(NumStrides) const UINT * pBufferStrides, - _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumStrides, - _In_ UINT RasterizedStream, - _In_opt_ ID3D11ClassLinkage * pClassLinkage, - _Out_opt_ ID3D11GeometryShader * *ppGeometryShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreatePixelShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11PixelShader** ppPixelShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateHullShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11HullShader** ppHullShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDomainShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11DomainShader** ppDomainShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateComputeShader( - _In_ const void* pShaderBytecode, - _In_ SIZE_T BytecodeLength, - _In_opt_ ID3D11ClassLinkage* pClassLinkage, - _Out_opt_ ID3D11ComputeShader** ppComputeShader) final; - - virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage( - _Out_ ID3D11ClassLinkage** ppLinkage) final; - - virtual HRESULT STDMETHODCALLTYPE CreateBlendState( - _In_ const D3D11_BLEND_DESC* pBlendStateDesc, - _Out_opt_ ID3D11BlendState** ppBlendState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState( - _In_ const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, - _Out_opt_ ID3D11DepthStencilState** ppDepthStencilState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState( - _In_ const D3D11_RASTERIZER_DESC* pRasterizerDesc, - _Out_opt_ ID3D11RasterizerState** ppRasterizerState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateSamplerState( - _In_ const D3D11_SAMPLER_DESC* pSamplerDesc, - _Out_opt_ ID3D11SamplerState** ppSamplerState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateQuery( - _In_ const D3D11_QUERY_DESC* pQueryDesc, - _Out_opt_ ID3D11Query** ppQuery) final; - - virtual HRESULT STDMETHODCALLTYPE CreatePredicate( - _In_ const D3D11_QUERY_DESC* pPredicateDesc, - _Out_opt_ ID3D11Predicate** ppPredicate) final; - - virtual HRESULT STDMETHODCALLTYPE CreateCounter( - _In_ const D3D11_COUNTER_DESC* pCounterDesc, - _Out_opt_ ID3D11Counter** ppCounter) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext( - UINT ContextFlags, - _Out_opt_ ID3D11DeviceContext** ppDeferredContext) final; - - virtual HRESULT STDMETHODCALLTYPE OpenSharedResource( - _In_ HANDLE hResource, - _In_ REFIID ReturnedInterface, - _Out_opt_ void** ppResource) final; - - virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport( - _In_ DXGI_FORMAT Format, - _Out_ UINT* pFormatSupport) final; - - virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( - _In_ DXGI_FORMAT Format, - _In_ UINT SampleCount, - _Out_ UINT* pNumQualityLevels) final; - - virtual void STDMETHODCALLTYPE CheckCounterInfo( - _Out_ D3D11_COUNTER_INFO* pCounterInfo) final; - - virtual HRESULT STDMETHODCALLTYPE CheckCounter( - _In_ const D3D11_COUNTER_DESC* pDesc, - _Out_ D3D11_COUNTER_TYPE* pType, - _Out_ UINT* pActiveCounters, - _Out_writes_opt_(*pNameLength) LPSTR szName, - _Inout_opt_ UINT* pNameLength, - _Out_writes_opt_(*pUnitsLength) LPSTR szUnits, - _Inout_opt_ UINT* pUnitsLength, - _Out_writes_opt_(*pDescriptionLength) LPSTR szDescription, - _Inout_opt_ UINT* pDescriptionLength) final; - - virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport( - D3D11_FEATURE Feature, - _Out_writes_bytes_(FeatureSupportDataSize) void* pFeatureSupportData, - UINT FeatureSupportDataSize) final; - - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - _In_ REFGUID guid, - _Inout_ UINT* pDataSize, - _Out_writes_bytes_opt_(*pDataSize) void* pData) final; - - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - _In_ REFGUID guid, - _In_ UINT DataSize, - _In_reads_bytes_opt_(DataSize) const void* pData) final; - - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - _In_ REFGUID guid, - _In_opt_ const IUnknown* pData) final; - - virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel() final; - - virtual UINT STDMETHODCALLTYPE GetCreationFlags() final; - - virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason() final; - - virtual void STDMETHODCALLTYPE GetImmediateContext( - _Out_ ID3D11DeviceContext** ppImmediateContext) final; - - virtual HRESULT STDMETHODCALLTYPE SetExceptionMode( - UINT RaiseFlags) final; - - virtual UINT STDMETHODCALLTYPE GetExceptionMode() final; - - #pragma endregion - - #pragma region /* ID3D11Device1 implementation */ - - virtual void STDMETHODCALLTYPE GetImmediateContext1( - /* [annotation] */ - _Outptr_ ID3D11DeviceContext1** ppImmediateContext) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext1( - UINT ContextFlags, - /* [annotation] */ - _COM_Outptr_opt_ ID3D11DeviceContext1** ppDeferredContext) final; - - virtual HRESULT STDMETHODCALLTYPE CreateBlendState1( - /* [annotation] */ - _In_ const D3D11_BLEND_DESC1* pBlendStateDesc, - /* [annotation] */ - _COM_Outptr_opt_ ID3D11BlendState1** ppBlendState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState1( - /* [annotation] */ - _In_ const D3D11_RASTERIZER_DESC1* pRasterizerDesc, - /* [annotation] */ - _COM_Outptr_opt_ ID3D11RasterizerState1** ppRasterizerState) final; - - virtual HRESULT STDMETHODCALLTYPE CreateDeviceContextState( - UINT Flags, - /* [annotation] */ - _In_reads_(FeatureLevels) const D3D_FEATURE_LEVEL * pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - REFIID EmulatedInterface, - /* [annotation] */ - _Out_opt_ D3D_FEATURE_LEVEL * pChosenFeatureLevel, - /* [annotation] */ - _Out_opt_ ID3DDeviceContextState * *ppContextState) final; - - virtual HRESULT STDMETHODCALLTYPE OpenSharedResource1( - /* [annotation] */ - _In_ HANDLE hResource, - /* [annotation] */ - _In_ REFIID returnedInterface, - /* [annotation] */ - _COM_Outptr_ void** ppResource) final; - - virtual HRESULT STDMETHODCALLTYPE OpenSharedResourceByName( - /* [annotation] */ - _In_ LPCWSTR lpName, - /* [annotation] */ - _In_ DWORD dwDesiredAccess, - /* [annotation] */ - _In_ REFIID returnedInterface, - /* [annotation] */ - _COM_Outptr_ void** ppResource) final; - - #pragma endregion - - HRESULT STDMETHODCALLTYPE CreateTexture1D( - _In_ const D3D11_TEXTURE1D_DESC * pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture1D * *ppTexture1D); - - HRESULT STDMETHODCALLTYPE CreateTexture2D( - _In_ const D3D11_TEXTURE2D_DESC * pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels * pDesc->ArraySize)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture2D * *ppTexture2D); - - HRESULT STDMETHODCALLTYPE CreateTexture3D( - _In_ const D3D11_TEXTURE3D_DESC * pDesc, - _In_ const FLOAT cClearValue[4], - _In_reads_opt_(_Inexpressible_(pDesc->MipLevels)) const D3D11_SUBRESOURCE_DATA * pInitialData, - _Out_opt_ ID3D11Texture3D * *ppTexture3D); - - HRESULT STDMETHODCALLTYPE CreateStagingResource( - _In_ ID3D11Resource* pInputResource, - _Out_ ID3D11Resource** ppStagingResource, - _In_ BOOL Upload); - - HRESULT STDMETHODCALLTYPE ReleaseStagingResource( - _In_ ID3D11Resource* pStagingResource); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CCRYDX12DEVICE_HPP_SECTION_2 - #include AZ_RESTRICTED_FILE(CCryDX12Device_hpp) -#endif - -private: - DX12::SmartPtr m_pDevice; - - DX12::SmartPtr m_pContext; -}; - -#endif // __CCRYDX12DEVICE__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.cpp deleted file mode 100644 index 6e0b4c51ec..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" - -EXTERN_C const GUID DECLSPEC_SELECTANY WKPDID_D3DDebugClearValue = { 0x01234567, 0x0123, 0x0123, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } }; diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.hpp deleted file mode 100644 index a35cfd4df6..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceChild.hpp +++ /dev/null @@ -1,192 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __CCRYDX12DEVICECHILD__ -#define __CCRYDX12DEVICECHILD__ - -#include "DX12/CCryDX12Object.hpp" - -DEFINE_GUID(WKPDID_D3DDebugObjectName, 0x429b8c22, 0x9188, 0x4b0c, 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00); -DEFINE_GUID(WKPDID_D3DDebugObjectNameW, 0x4cca5fd8, 0x921f, 0x42c8, 0x85, 0x66, 0x70, 0xca, 0xf2, 0xa9, 0xb7, 0x41); -DEFINE_GUID(WKPDID_D3DDebugClearValue, 0x01234567, 0x0123, 0x0123, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01); - -// Specialize std::hash -namespace std { - template<> - struct hash - { - size_t operator()(const GUID& guid) const /*noexcept*/ - { - // RPC_STATUS status; - // return UuidHash((UUID*)&guid, &status); - - const uint64_t* p = reinterpret_cast(&guid); - std::hash hash; - return hash(p[0]) ^ hash(p[1]); - } - }; -} - -template -class CCryDX12DeviceChild - : public CCryDX12Object -{ -public: - DX12_OBJECT(CCryDX12DeviceChild, CCryDX12Object); - - virtual ~CCryDX12DeviceChild() - { - } - -#if !defined(RELEASE) - std::string GetName() - { - UINT len = 512; - char str[512] = "-"; - - GetPrivateData(WKPDID_D3DDebugObjectName, &len, str); - - return str; - } - - HRESULT STDMETHODCALLTYPE GetPrivateCustomData( - _In_ REFGUID guid, - _Inout_ UINT* pDataSize, - _Out_writes_bytes_opt_(*pDataSize) void* pData) - { - TDatas::iterator elm = m_Data.find(guid); - if (elm != m_Data.end()) - { - void* Blob = (*elm).second.second; - UINT nCopied = std::min(*pDataSize, (*elm).second.first); - - *pDataSize = nCopied; - if (pData) - { - memcpy(pData, Blob, nCopied); - } - - return S_OK; - } - - return E_FAIL; - } - - HRESULT STDMETHODCALLTYPE SetPrivateCustomData( - _In_ REFGUID guid, - _In_ UINT DataSize, - _In_reads_bytes_opt_(DataSize) const void* pData) - { - TDatas::iterator elm = m_Data.find(guid); - if (elm != m_Data.end()) - { - CryModuleFree((*elm).second.second); - } - - if (pData) - { - void* Blob = CryModuleMalloc(DataSize); - m_Data[guid] = std::make_pair(DataSize, Blob); - memcpy(Blob, pData, DataSize); - } - else - { - m_Data.erase(elm); - } - - return S_OK; - } -#endif - - #pragma region /* ID3D11DeviceChild implementation */ - - virtual void STDMETHODCALLTYPE GetDevice( - _Out_ ID3D11Device** ppDevice) - { - *ppDevice = m_Device; - } - - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _Inout_ UINT* pDataSize, - [[maybe_unused]] _Out_writes_bytes_opt_(*pDataSize) void* pData) - { -#if !defined(RELEASE) - if (m_pChild) - { - return m_pChild->GetPrivateData(guid, pDataSize, pData); - } - - return GetPrivateCustomData(guid, pDataSize, pData); -#else - return E_FAIL; -#endif - } - - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_ UINT DataSize, - [[maybe_unused]] _In_reads_bytes_opt_(DataSize) const void* pData) - { -#if !defined(RELEASE) - if (m_pChild) - { - return m_pChild->SetPrivateData(guid, DataSize, pData); - } - - return SetPrivateCustomData(guid, DataSize, pData); -#else - return E_FAIL; -#endif - } - - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_opt_ const IUnknown* pData) - { -#if !defined(RELEASE) - if (m_pChild) - { - return m_pChild->SetPrivateDataInterface(guid, pData); - } -#endif - - return E_FAIL; - } - - #pragma endregion - - CCryDX12Device* GetDevice() - { - return m_Device; - } - -protected: - CCryDX12DeviceChild(CCryDX12Device* pDevice, [[maybe_unused]] ID3D12DeviceChild* pChild) - { - m_Device = pDevice; -#if !defined(RELEASE) - m_pChild = pChild; -#endif - } - -private: - CCryDX12Device* m_Device; -#if !defined(RELEASE) - typedef std::unordered_map > TDatas; - TDatas m_Data; - ID3D12DeviceChild* m_pChild; -#endif -}; - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.cpp deleted file mode 100644 index 0215635619..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.cpp +++ /dev/null @@ -1,3074 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CCryDX12DeviceContext.hpp" -#include "CCryDX12Device.hpp" - -#include "DX12/Resource/CCryDX12Resource.hpp" - -#include "DX12/Resource/Misc/CCryDX12Buffer.hpp" -#include "DX12/Resource/Misc/CCryDX12Shader.hpp" -#include "DX12/Resource/Misc/CCryDX12Query.hpp" - -#include "DX12/Resource/State/CCryDX12SamplerState.hpp" - -#include "DX12/Resource/Texture/CCryDX12Texture1D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture2D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture3D.hpp" - -#include "DX12/Resource/View/CCryDX12DepthStencilView.hpp" -#include "DX12/Resource/View/CCryDX12RenderTargetView.hpp" -#include "DX12/Resource/View/CCryDX12ShaderResourceView.hpp" -#include "DX12/Resource/View/CCryDX12UnorderedAccessView.hpp" - -#include "DX12/API/DX12Device.hpp" - -#define DX12_SUBMISSION_UNBOUND 3 // never commit, only when the heaps overflow, or on present -#define DX12_SUBMISSION_PERPSO 2 // commit whenever the PSO changes -#define DX12_SUBMISSION_PERDRAW 1 // commit whenever a new draw is requested -#define DX12_SUBMISSION_SYNC 0 // commit always and wait as well - -#define DX12_SUBMISSION_MODE DX12_SUBMISSION_UNBOUND - -CCryDX12DeviceContext* CCryDX12DeviceContext::Create(CCryDX12Device* pDeviced) -{ - return DX12::PassAddRef(new CCryDX12DeviceContext(pDeviced)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CCryDX12DeviceContext::CCryDX12DeviceContext(CCryDX12Device* pDevice) - : Super() - , m_pDevice(pDevice) - , m_pDX12Device(pDevice->GetDX12Device()) - , m_CmdFenceSet(pDevice->GetDX12Device()) - , m_DirectListPool(pDevice->GetDX12Device(), m_CmdFenceSet, CMDQUEUE_GRAPHICS) - , m_CopyListPool(pDevice->GetDX12Device(), m_CmdFenceSet, CMDQUEUE_COPY) - , m_TimestampHeap(pDevice->GetDX12Device()) - , m_PipelineHeap(pDevice->GetDX12Device()) - , m_OcclusionHeap(pDevice->GetDX12Device()) - , m_CurrentRootSignature{} - , m_CurrentPSO{} - , m_OutstandingQueries{} - , m_TimestampIndex{} - , m_OcclusionIndex{} - , m_bInCopyRegion{} -{ - DX12_FUNC_LOG - - // Timer query heap - { - D3D12_QUERY_HEAP_DESC desc = {}; - desc.Count = 1024; - desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; - - m_TimestampHeap.Init(m_pDX12Device, desc); - } - - // Occlusion query heap - { - D3D12_QUERY_HEAP_DESC desc = {}; - desc.Count = 64; - desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION; - - m_OcclusionHeap.Init(m_pDX12Device, desc); - } - - // Pipeline query heap - { - D3D12_QUERY_HEAP_DESC desc = {}; - desc.Count = 16; - desc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS; - - m_PipelineHeap.Init(m_pDX12Device, desc); - } - - const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_READBACK); - const CD3DX12_RESOURCE_DESC timestampHeapBuffer = CD3DX12_RESOURCE_DESC::Buffer(sizeof(UINT64) * m_TimestampHeap.GetCapacity()); - if(S_OK != m_pDX12Device->GetD3D12Device()->CreateCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - ×tampHeapBuffer, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_GRAPHICS_PPV_ARGS(&m_TimestampDownloadBuffer))) - { - DX12_ERROR("Could not create intermediate timestamp download buffer!"); - } - - const CD3DX12_RESOURCE_DESC occlusionHeapBuffer = CD3DX12_RESOURCE_DESC::Buffer(sizeof(UINT64) * m_OcclusionHeap.GetCapacity()); - if (S_OK != m_pDX12Device->GetD3D12Device()->CreateCommittedResource( - &heapProperties, - D3D12_HEAP_FLAG_NONE, - &occlusionHeapBuffer, - D3D12_RESOURCE_STATE_COPY_DEST, - nullptr, - IID_GRAPHICS_PPV_ARGS(&m_OcclusionDownloadBuffer))) - { - DX12_ERROR("Could not create intermediate occlusion download buffer!"); - } - - m_pSamplerHeap = NULL; - m_pResourceHeap = NULL; - m_bCurrentNative = false; - m_nResDynOffset = 0; - m_nFrame = 0; - m_nStencilRef = -1; - - m_TimestampMemory = nullptr; - m_OcclusionMemory = nullptr; - m_TimestampMapValid = false; - m_OcclusionMapValid = false; - - m_CmdFenceSet.Init(); - - m_DirectListPool.Init(); - m_CopyListPool.Init(D3D12_COMMAND_LIST_TYPE_COPY); - - m_DirectListPool.AcquireCommandList(m_DirectCommandList); - m_CopyListPool.AcquireCommandList(m_CopyCommandList); - - m_DirectCommandList->Begin(); - m_DirectCommandList->SetResourceAndSamplerStateHeaps(); - - m_CopyCommandList->Begin(); - - m_pDX12Device->CalibrateClocks(m_DirectCommandList->GetD3D12CommandQueue()); -} - -CCryDX12DeviceContext::~CCryDX12DeviceContext() -{ - DX12_FUNC_LOG - - D3D12_RANGE sNoWrite = { 0, 0 }; - if (m_TimestampMemory) - { - m_TimestampDownloadBuffer->Unmap(0, &sNoWrite); - } - if (m_OcclusionMemory) - { - m_OcclusionDownloadBuffer->Unmap(0, &sNoWrite); - } - - m_TimestampDownloadBuffer->Release(); - m_OcclusionDownloadBuffer->Release(); -} - -bool CCryDX12DeviceContext::PreparePSO(DX12::CommandMode commandMode) -{ - DX12::Device* device = m_pDevice->GetDX12Device(); - - auto& state = m_PipelineState[commandMode]; - const DX12::RootSignature* newRootSignature = m_CurrentRootSignature[commandMode]; - const DX12::PipelineState* newPipelineState = m_CurrentPSO; - - bool bForceFlush = false; - - if (state.m_StateFlags & EPSPB_PipelineState) - { - if (commandMode == DX12::CommandModeGraphics) - { - DX12::RootSignature::GraphicsInitParams rootSignatureParams; - state.MakeInitParams(rootSignatureParams); - newRootSignature = device->GetRootSignatureCache().AcquireRootSignature(rootSignatureParams); - - DX12::GraphicsPipelineState::InitParams psoParams; - psoParams.rootSignature = newRootSignature; - state.MakeInitParams(psoParams); - newPipelineState = device->GetPSOCache().AcquirePipelineState(psoParams); - } - else - { - DX12::RootSignature::ComputeInitParams rootSignatureParams; - state.MakeInitParams(rootSignatureParams); - newRootSignature = device->GetRootSignatureCache().AcquireRootSignature(rootSignatureParams); - - DX12::ComputePipelineState::InitParams psoParams; - psoParams.rootSignature = newRootSignature; - state.MakeInitParams(psoParams); - newPipelineState = device->GetPSOCache().AcquirePipelineState(psoParams); - } - - if (!newPipelineState) - { - return false; - } - - if constexpr (DX12_SUBMISSION_MODE == DX12_SUBMISSION_PERPSO) - { - if (m_OutstandingQueries == 0) - { - bForceFlush = true; - } - } - } - - // check for overflow and submit early - if (bForceFlush || m_DirectCommandList->IsFull( - /* 256, */ newRootSignature->GetPipelineLayout().m_NumDescriptors, - /* 16, */ newRootSignature->GetPipelineLayout().m_NumDynamicSamplers, - /* 8, */ state.OutputMerger.NumRenderTargets.Get(), - /* 1, */ state.OutputMerger.DepthStencilView ? 1 : 0)) - { - const bool bWait = false; - SubmitDirectCommands(bWait); - -#ifdef DX12_STATS - m_NumCommandListOverflows++; -#endif // DX12_STATS - - ResetCachedState(); - } - - if (state.m_StateFlags & EPSPB_PipelineState) - { - if (newPipelineState != m_CurrentPSO) - { -#ifdef DX12_STATS - m_NumPSOs += 1; -#endif - m_DirectCommandList->SetPipelineState(newPipelineState); - m_CurrentPSO = newPipelineState; - } - - if (newRootSignature != m_CurrentRootSignature[commandMode]) - { -#ifdef DX12_STATS - m_NumRootSignatures += 1; -#endif - m_DirectCommandList->SetRootSignature(commandMode, newRootSignature); - m_CurrentRootSignature[commandMode] = newRootSignature; - state.m_StateFlags |= EPSPB_InputResources; - } - } - - return true; -} - -void CCryDX12DeviceContext::PrepareGraphicsFF() -{ - auto& state = m_PipelineState[DX12::CommandModeGraphics]; - const UINT& stateFlags = state.m_StateFlags; - - if (stateFlags & EPSPB_IndexBuffer & (state.InputAssembler.IndexBuffer ? ~0 : 0)) - { - AZ_Assert(state.InputAssembler.IndexBuffer, "IndexBuffer is required by the Draw but has not been set!"); - m_DirectCommandList->BindAndSetIndexBufferView(state.InputAssembler.IndexBuffer->GetDX12View(), state.InputAssembler.IndexBufferFormat.Get(), state.InputAssembler.IndexBufferOffset.Get()); - } - - if (stateFlags & EPSPB_PrimitiveTopology) - { - m_DirectCommandList->SetPrimitiveTopology(static_cast (state.InputAssembler.PrimitiveTopology.Get())); - } - - if (stateFlags & EPSPB_VertexBuffers) - { - m_DirectCommandList->ClearVertexBufferHeap(state.InputAssembler.NumVertexBuffers.Get()); - - for (UINT i = 0, S = state.InputAssembler.NumVertexBuffers.Get(); i < S; ++i) - { - CCryDX12Buffer* buffer = state.InputAssembler.VertexBuffers.Get(i); - - if (buffer) - { - TRange bindRange = TRange (state.InputAssembler.Offsets.Get(i), state.InputAssembler.Offsets.Get(i)); - UINT bindStride = state.InputAssembler.Strides.Get(i); - AZ_Assert(buffer, "VertexBuffer is required by the PSO but has not been set!"); - m_DirectCommandList->BindVertexBufferView(buffer->GetDX12View(), i, bindRange, bindStride); - } - } - - m_DirectCommandList->SetVertexBufferHeap(state.InputAssembler.NumVertexBuffers.Get()); - } - - if (stateFlags & EPSPB_Viewports) - { - UINT numScissors = state.Rasterizer.ScissorEnabled.Get() ? state.Rasterizer.NumScissors.Get() : 0; - if (state.Rasterizer.NumViewports.Get() >= numScissors) - { - D3D12_VIEWPORT viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - D3D12_RECT scissors[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - - for (UINT i = 0, S = state.Rasterizer.NumViewports.Get(); i < S; ++i) - { - const D3D11_VIEWPORT& v = state.Rasterizer.Viewports.Get(i); - viewports[i].TopLeftX = v.TopLeftX; - viewports[i].TopLeftY = v.TopLeftY; - viewports[i].Width = v.Width; - viewports[i].Height = v.Height; - viewports[i].MinDepth = v.MinDepth; - viewports[i].MaxDepth = v.MaxDepth; - - if (i < numScissors) - { - const D3D11_RECT& s = state.Rasterizer.Scissors.Get(i); - - scissors[i].bottom = s.bottom; - scissors[i].left = s.left; - scissors[i].right = s.right; - scissors[i].top = s.top; - } - else - { - scissors[i].top = static_cast(v.TopLeftY); - scissors[i].left = static_cast(v.TopLeftX); - scissors[i].right = static_cast(v.TopLeftX + v.Width); - scissors[i].bottom = static_cast(v.TopLeftY + v.Height); - } - } - - m_DirectCommandList->SetViewports(state.Rasterizer.NumViewports.Get(), viewports); - m_DirectCommandList->SetScissorRects(state.Rasterizer.NumViewports.Get(), scissors); - } - else - { - // This should not happen, ever! - DX12_NOT_IMPLEMENTED; - } - } - - if (stateFlags & EPSPB_StencilRef) - { - m_DirectCommandList->SetStencilRef(state.OutputMerger.StencilRef.Get()); - } - - if (stateFlags & EPSPB_OutputResources) - { - BindOutputViews(); - } -} - -bool CCryDX12DeviceContext::PrepareGraphicsState() -{ - if (!m_PipelineState[DX12::CommandModeGraphics].AreShadersBound() || m_PipelineState[DX12::CommandModeGraphics].InputAssembler.InputLayout.m_Value == NULL) - { - return false; - } - - if (!PreparePSO(DX12::CommandModeGraphics)) - { - return false; - } - - PrepareGraphicsFF(); - BindResources(DX12::CommandModeGraphics); - - m_PipelineState[DX12::CommandModeGraphics].m_StateFlags = 0; - return true; -} - -bool CCryDX12DeviceContext::PrepareComputeState() -{ - if (!m_PipelineState[DX12::CommandModeCompute].AreShadersBound()) - { - return false; - } - - if (!PreparePSO(DX12::CommandModeCompute)) - { - return false; - } - - BindResources(DX12::CommandModeCompute); - - m_PipelineState[DX12::CommandModeCompute].m_StateFlags = 0; - return true; -} - -void CCryDX12DeviceContext::BindResources(DX12::CommandMode commandMode) -{ - const auto& state = m_PipelineState[commandMode]; - const auto stateFlags = state.m_StateFlags; - - if ((stateFlags & EPSPB_InputResources) == 0) - { - return; - } - DX12_ASSERT(stateFlags & (BIT(EPSP_ConstantBuffers) | BIT(EPSP_Resources) | BIT(EPSP_Samplers)), "Redundant BindResources() called without state-changes"); - - const DX12::PipelineLayout& layout = m_CurrentRootSignature[commandMode]->GetPipelineLayout(); - AZ::u32 resourceDescriptorOffset = 0; - AZ::u32 samplerDescriptorOffset = 0; - - if (stateFlags & (EPSPB_ConstantBuffers | EPSPB_Resources)) - { - for (const DX12::ResourceLayoutBinding& resourceBinding : layout.m_TableResources) - { - auto& stage = state.Stages[resourceBinding.ShaderStage]; - - switch (resourceBinding.ViewType) - { - case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: - { - CCryDX12Buffer* buffer = stage.ConstantBufferViews.Get(resourceBinding.ShaderSlot); - TRange bindRange = stage.ConstBufferBindRange.Get(resourceBinding.ShaderSlot); - DX12_ASSERT(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "ConstantBuffer offset has shifted: resource mapping invalid!"); - m_DirectCommandList->WriteConstantBufferDescriptor(buffer ? &buffer->GetDX12View() : nullptr, resourceDescriptorOffset++, bindRange.start, bindRange.Length()); - break; - } - case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: - { - CCryDX12ShaderResourceView* resource = stage.ShaderResourceViews.Get(resourceBinding.ShaderSlot); - DX12_ASSERT(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "ShaderResourceView offset has shifted: resource mapping invalid!"); - m_DirectCommandList->WriteShaderResourceDescriptor(resource ? &resource->GetDX12View() : nullptr, resourceDescriptorOffset++); - break; - } - case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: - { - CCryDX12UnorderedAccessView* resource = stage.UnorderedAccessViews.Get(resourceBinding.ShaderSlot); - DX12_ASSERT(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "UnorderedAccessView offset has shifted: resource mapping invalid!"); - m_DirectCommandList->WriteUnorderedAccessDescriptor(resource ? &resource->GetDX12View() : nullptr, resourceDescriptorOffset++); - break; - } - } - } - - if (stateFlags & EPSPB_ConstantBuffers) - { - for (const DX12::ConstantBufferLayoutBinding& constantBufferBinding : layout.m_ConstantViews) - { - auto& stage = state.Stages[constantBufferBinding.ShaderStage]; - - CCryDX12Buffer* buffer = stage.ConstantBufferViews.Get(constantBufferBinding.ShaderSlot); - TRange bindRange = stage.ConstBufferBindRange.Get(constantBufferBinding.ShaderSlot); - - D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = { 0ull }; - if (buffer) - { - gpuAddress = buffer->GetDX12View().GetCBVDesc().BufferLocation + bindRange.start; - } - m_DirectCommandList->SetConstantBufferView(commandMode, constantBufferBinding.RootParameterIndex, gpuAddress); - } - } - } - - // Bind samplers - if (stateFlags & EPSPB_Samplers) - { - for (const DX12::ResourceLayoutBinding& samplerBinding : layout.m_Samplers) - { - const DX12::EShaderStage i = samplerBinding.ShaderStage; - DX12_ASSERT(samplerBinding.ViewType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, ""); - { - CCryDX12SamplerState* sampler = state.Stages[i].SamplerState.Get(samplerBinding.ShaderSlot); - DX12_ASSERT(samplerDescriptorOffset == samplerBinding.DescriptorOffset, "Sampler offset has shifted: resource mapping invalid!"); - m_DirectCommandList->WriteSamplerStateDescriptor(sampler ? &sampler->GetDX12SamplerState() : nullptr, samplerDescriptorOffset++); - } - } - } - - if (stateFlags & (BIT(EPSP_ConstantBuffers) | BIT(EPSP_Resources))) - { - m_DirectCommandList->SetDescriptorTables(commandMode, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - m_DirectCommandList->IncrementInputCursors(layout.m_NumDescriptors, 0); - } - - if (stateFlags & (BIT(EPSP_Samplers))) - { - m_DirectCommandList->SetDescriptorTables(commandMode, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - m_DirectCommandList->IncrementInputCursors(0, layout.m_NumDynamicSamplers); - } -} - -void CCryDX12DeviceContext::BindOutputViews() -{ - const DX12::ResourceView* dsv = NULL; - const DX12::ResourceView* rtv[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; - size_t numRTVs = 0; - - auto& outputMerger = m_PipelineState[DX12::CommandModeGraphics].OutputMerger; - - // Get current depth stencil views - { - CCryDX12DepthStencilView* view = outputMerger.DepthStencilView; - if (view) - { - dsv = &view->GetDX12View(); - } - } - - // Get current render target views - for (UINT i = 0, S = outputMerger.NumRenderTargets.Get(); i < S; ++i) - { - CCryDX12RenderTargetView* view = outputMerger.RenderTargetViews.Get(i); - if (view) - { - rtv[numRTVs++] = &view->GetDX12View(); - } - } - - m_DirectCommandList->BindAndSetOutputViews(numRTVs, rtv, dsv); -#ifdef DX12_STATS - m_NumberSettingOutputViews++; -#endif -} - -namespace DX12 -{ - const char* StateToString(D3D12_RESOURCE_STATES state); -} - -void CCryDX12DeviceContext::DebugPrintResources(DX12::CommandMode commandMode) -{ - const DX12::PipelineLayout& layout = m_CurrentRootSignature[commandMode]->GetPipelineLayout(); - - DX12_LOG("Resource Heap Descriptor Tables:"); - - auto& state = m_PipelineState[commandMode]; -#ifdef GFX_DEBUG - UINT resourceDescriptorOffset = 0; - UINT samplerDescriptorOffset = 0; -#endif - - // Bind constant buffers - for (const DX12::ResourceLayoutBinding& resourceBinding : layout.m_TableResources) - { - const DX12::EShaderStage i = resourceBinding.ShaderStage; - if (resourceBinding.ViewType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV) - { - auto bindRange = state.Stages[i].ConstBufferBindRange.Get(resourceBinding.ShaderSlot); -#ifdef GFX_DEBUG - CCryDX12Buffer* buffer = state.Stages[i].ConstantBufferViews.Get(resourceBinding.ShaderSlot); - AZ_Assert(buffer, "ConstantBuffer is required by the PSO but has not been set!"); - AZ_Assert(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "ConstantBuffer offset has shifted: resource mapping invalid!"); -#endif - DX12_LOG(" %s: C %2d -> %2d %s [%s]", - i == DX12::ESS_Compute ? "Every shader stage" : - i == DX12::ESS_Vertex ? "Vertex shader stage" : - i == DX12::ESS_Hull ? "Hull shader stage" : - i == DX12::ESS_Domain ? "Domain shader stage" : - i == DX12::ESS_Geometry ? "Geometry shader stage" : - i == DX12::ESS_Pixel ? "Pixel shader stage" : "Unknown shader stage", - resourceBinding.ShaderSlot, - resourceDescriptorOffset++, - buffer ? buffer->GetName().c_str() : "nullptr", - buffer ? DX12::StateToString(buffer->GetDX12Resource().GetCurrentState()) : "-"); - } - else if (resourceBinding.ViewType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV) - { -#ifdef GFX_DEBUG - CCryDX12ShaderResourceView* resource = state.Stages[i].ShaderResourceViews.Get(resourceBinding.ShaderSlot); - AZ_Assert(resource, "ShaderResourceView is required by the PSO but has not been set!"); - AZ_Assert(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "ShaderResourceView offset has shifted: resource mapping invalid!"); -#endif - DX12_LOG(" %s: T %2d -> %2d %s [%s]", - i == DX12::ESS_Compute ? "Every shader stage" : - i == DX12::ESS_Vertex ? "Vertex shader stage" : - i == DX12::ESS_Hull ? "Hull shader stage" : - i == DX12::ESS_Domain ? "Domain shader stage" : - i == DX12::ESS_Geometry ? "Geometry shader stage" : - i == DX12::ESS_Pixel ? "Pixel shader stage" : "Unknown shader stage", - resourceBinding.ShaderSlot, - resourceDescriptorOffset++, - resource ? resource->GetResourceName().c_str() : "nullptr", - resource ? DX12::StateToString(resource->GetDX12Resource().GetCurrentState()) : "-"); - } - else if (resourceBinding.ViewType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV) - { -#ifdef GFX_DEBUG - CCryDX12UnorderedAccessView* resource = state.Stages[i].UnorderedAccessViews.Get(resourceBinding.ShaderSlot); - AZ_Assert(resource, "UnorderedAccessView is required by the PSO but has not been set!"); - AZ_Assert(resourceDescriptorOffset == resourceBinding.DescriptorOffset, "UnorderedAccessView offset has shifted: resource mapping invalid!"); -#endif - DX12_LOG(" %s: U %2d -> %2d %s [%s]", - i == DX12::ESS_Compute ? "Every shader stage" : - i == DX12::ESS_Vertex ? "Vertex shader stage" : - i == DX12::ESS_Hull ? "Hull shader stage" : - i == DX12::ESS_Domain ? "Domain shader stage" : - i == DX12::ESS_Geometry ? "Geometry shader stage" : - i == DX12::ESS_Pixel ? "Pixel shader stage" : "Unknown shader stage", - resourceBinding.ShaderSlot, - resourceDescriptorOffset++, - resource ? resource->GetResourceName().c_str() : "nullptr", - resource ? DX12::StateToString(resource->GetDX12Resource().GetCurrentState()) : "-"); - } - } - - // Bind samplers - for (const DX12::ResourceLayoutBinding& samplerBinding : layout.m_Samplers) - { - const DX12::EShaderStage i = samplerBinding.ShaderStage; - AZ_Assert(samplerBinding.ViewType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, ""); - { -#ifdef GFX_DEBUG - CCryDX12SamplerState* sampler = state.Stages[i].SamplerState.Get(samplerBinding.ShaderSlot); - AZ_Assert(sampler, "Sampler is required by the PSO but has not been set!"); - AZ_Assert(samplerDescriptorOffset == samplerBinding.DescriptorOffset, "Sampler offset has shifted: resource mapping invalid!"); -#endif - DX12_LOG(" %s: S %2d -> %2d", - i == DX12::ESS_Compute ? "Every shader stage" : - i == DX12::ESS_Vertex ? "Vertex shader stage" : - i == DX12::ESS_Hull ? "Hull shader stage" : - i == DX12::ESS_Domain ? "Domain shader stage" : - i == DX12::ESS_Geometry ? "Geometry shader stage" : - i == DX12::ESS_Pixel ? "Pixel shader stage" : "Unknown shader stage", - samplerBinding.ShaderSlot, - samplerDescriptorOffset++); - } - } -} - -void CCryDX12DeviceContext::CeaseDirectCommandQueue(bool wait) -{ - AZ_TRACE_METHOD(); - AZ_Assert(m_DirectCommandList != nullptr, "CommandList hasn't been allocated!"); - AZ_Assert(m_OutstandingQueries == 0, "Flushing command list with outstanding queries!"); - - m_DirectCommandList->End(); - m_DirectListPool.ForfeitCommandList(m_DirectCommandList, wait); -} - -void CCryDX12DeviceContext::ResumeDirectCommandQueue() -{ - AZ_TRACE_METHOD(); - AZ_Assert(m_DirectCommandList == nullptr, "CommandList hasn't been submitted!"); - m_DirectListPool.AcquireCommandList(m_DirectCommandList); - - m_DirectCommandList->Begin(); - m_DirectCommandList->SetResourceAndSamplerStateHeaps(); - - ResetCachedState(); -} - -void CCryDX12DeviceContext::CeaseCopyCommandQueue(bool wait) -{ - AZ_TRACE_METHOD(); - AZ_Assert(m_CopyCommandList != nullptr, "CommandList hasn't been allocated!"); - - m_CopyCommandList->End(); - m_CopyListPool.ForfeitCommandList(m_CopyCommandList, wait); -} - -void CCryDX12DeviceContext::ResumeCopyCommandQueue() -{ - AZ_TRACE_METHOD(); - AZ_Assert(m_CopyCommandList == nullptr, "CommandList hasn't been submitted!"); - m_CopyListPool.AcquireCommandList(m_CopyCommandList); - - m_CopyCommandList->Begin(); -} - -void CCryDX12DeviceContext::CeaseAllCommandQueues(bool wait) -{ - AZ_TRACE_METHOD(); - CeaseDirectCommandQueue(wait); - CeaseCopyCommandQueue(wait); -} - -void CCryDX12DeviceContext::ResumeAllCommandQueues() -{ - AZ_TRACE_METHOD(); - ResumeDirectCommandQueue(); - ResumeCopyCommandQueue(); -} - -void CCryDX12DeviceContext::SubmitDirectCommands(bool wait) -{ - if (m_DirectCommandList->IsUtilized()) - { - AZ_TRACE_METHOD(); - CeaseDirectCommandQueue(wait); - ResumeDirectCommandQueue(); - } -} - -void CCryDX12DeviceContext::SubmitCopyCommands(bool wait) -{ - if (m_CopyCommandList->IsUtilized()) - { - AZ_TRACE_METHOD(); - CeaseCopyCommandQueue(wait); - ResumeCopyCommandQueue(); - } -} - -void CCryDX12DeviceContext::SubmitDirectCommands(bool wait, const UINT64 fenceValue) -{ - if (m_DirectCommandList->IsUtilized() && (m_CmdFenceSet.GetCurrentValue(CMDQUEUE_GRAPHICS) == fenceValue)) - { -#ifdef DX12_STATS - m_NumCommandListSplits++; -#endif // DX12_STATS - - SubmitDirectCommands(wait); - } -} - -void CCryDX12DeviceContext::SubmitCopyCommands(bool wait, const UINT64 fenceValue) -{ - if (m_CopyCommandList->IsUtilized() && (m_CmdFenceSet.GetCurrentValue(CMDQUEUE_COPY) == fenceValue)) - { -#ifdef DX12_STATS - m_NumCommandListSplits++; -#endif // DX12_STATS - - SubmitCopyCommands(wait); - } -} - -void CCryDX12DeviceContext::SubmitAllCommands(bool bWaitForGpu) -{ - SubmitAllCommands(bWaitForGpu, m_CmdFenceSet.GetCurrentValues()); -} - -void CCryDX12DeviceContext::SubmitAllCommands(bool wait, const UINT64 (&fenceValues)[CMDQUEUE_NUM]) -{ - SubmitDirectCommands(wait, fenceValues[CMDQUEUE_GRAPHICS]); - SubmitCopyCommands(wait, fenceValues[CMDQUEUE_COPY]); -} - - -void CCryDX12DeviceContext::SubmitAllCommands(bool wait, const UINT64(&fenceValues)[CMDQUEUE_NUM], int fenceId) -{ - AZ::u64 fenceValuesMasked[CMDQUEUE_NUM]; - fenceValuesMasked[CMDQUEUE_GRAPHICS] = fenceValues[CMDQUEUE_GRAPHICS]; - fenceValuesMasked[CMDQUEUE_COPY] = fenceValues[CMDQUEUE_COPY]; - fenceValuesMasked[fenceId] = 0; - - SubmitDirectCommands(wait, fenceValuesMasked[CMDQUEUE_GRAPHICS]); - SubmitCopyCommands(wait, fenceValuesMasked[CMDQUEUE_COPY]); -} - -void CCryDX12DeviceContext::SubmitAllCommands(bool wait, const std::atomic(&fenceValues)[CMDQUEUE_NUM]) -{ - SubmitDirectCommands(wait, fenceValues[CMDQUEUE_GRAPHICS]); - SubmitCopyCommands(wait, fenceValues[CMDQUEUE_COPY]); -} - -void CCryDX12DeviceContext::SubmitAllCommands(bool wait, const std::atomic(&fenceValues)[CMDQUEUE_NUM], int fenceId) -{ - AZ::u64 fenceValuesMasked[CMDQUEUE_NUM]; - fenceValuesMasked[CMDQUEUE_GRAPHICS] = fenceValues[CMDQUEUE_GRAPHICS]; - fenceValuesMasked[CMDQUEUE_COPY] = fenceValues[CMDQUEUE_COPY]; - fenceValuesMasked[fenceId] = 0; - - SubmitDirectCommands(wait, fenceValuesMasked[CMDQUEUE_GRAPHICS]); - SubmitCopyCommands(wait, fenceValuesMasked[CMDQUEUE_COPY]); -} - -void CCryDX12DeviceContext::Finish(DX12::SwapChain* pDX12SwapChain) -{ - AZ_TRACE_METHOD(); - m_DirectCommandList->PresentRenderTargetView(pDX12SwapChain); - - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, m_CmdFenceSet.GetCurrentValues()); - - // Release resource after pass fence and FRAME_FENCE_LATENCY later - m_pDX12Device->FlushReleaseHeap(DX12::Device::ResourceReleasePolicy::Deferred); - - m_pDX12Device->FinishFrame(); - m_pDX12Device->CalibrateClocks(m_DirectListPool.GetD3D12CommandQueue()); - -#ifdef DX12_STATS - m_NumMapDiscardSkips = 0; - m_NumMapDiscards = 0; - - m_NumCommandListOverflows = 0; - m_NumCommandListSplits = 0; - m_NumPSOs = 0; - m_NumRootSignatures = 0; - m_NumberSettingOutputViews = 0; -#endif // DX12_STATS -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -UINT CCryDX12DeviceContext::TimestampIndex([[maybe_unused]] DX12::CommandList* pCmdList) -{ - UINT index = m_TimestampIndex; - m_TimestampIndex = (m_TimestampIndex + 1) % m_TimestampHeap.GetCapacity(); - return index; -} - -ID3D12Resource* CCryDX12DeviceContext::QueryTimestamp(DX12::CommandList* pCmdList, UINT index) -{ - pCmdList->EndQuery(m_TimestampHeap, D3D12_QUERY_TYPE_TIMESTAMP, index); - - m_TimestampMapValid = false; - if (m_TimestampMemory) - { - const D3D12_RANGE sNoWrite = { 0, 0 }; - m_TimestampDownloadBuffer->Unmap(0, &sNoWrite); - m_TimestampMemory = nullptr; - } - - return m_TimestampDownloadBuffer; -} - -void CCryDX12DeviceContext::ResolveTimestamp(DX12::CommandList* pCmdList, UINT index, void* mem) -{ - if (mem) - { - if (!m_TimestampMapValid) - { - if (m_TimestampMemory) - { - const D3D12_RANGE sNoWrite = { 0, 0 }; - m_TimestampDownloadBuffer->Unmap(0, &sNoWrite); - m_TimestampMemory = nullptr; - } - - pCmdList->ResolveQueryData(m_TimestampHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, m_TimestampHeap.GetCapacity(), m_TimestampDownloadBuffer, 0); - - // Resources on D3D12_HEAP_TYPE_READBACK heaps do not support persistent map. - const D3D12_RANGE sFullRead = { 0, sizeof(UINT64) * m_TimestampHeap.GetCapacity() }; - m_TimestampDownloadBuffer->Map(0, &sFullRead, &m_TimestampMemory); - m_TimestampMapValid = true; - } - - memcpy(mem, (char*)m_TimestampMemory + index * 8, 8); - } -} - -UINT64 CCryDX12DeviceContext::MakeCpuTimestamp(UINT64 gpuTimestamp) const -{ - return m_pDX12Device->MakeCpuTimestamp(gpuTimestamp); -} - -UINT64 CCryDX12DeviceContext::MakeCpuTimestampMicroseconds(UINT64 gpuTimestamp) const -{ - return m_pDX12Device->MakeCpuTimestampMicroseconds(gpuTimestamp); -} - -UINT CCryDX12DeviceContext::OcclusionIndex(DX12::CommandList* pCmdList, bool counter) -{ - UINT index = m_OcclusionIndex; - m_OcclusionIndex = (m_OcclusionIndex + 1) % m_OcclusionHeap.GetCapacity(); - pCmdList->BeginQuery(m_OcclusionHeap, counter ? D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION, index); - return index; -} - -ID3D12Resource* CCryDX12DeviceContext::QueryOcclusion(DX12::CommandList* pCmdList, UINT index, bool counter) -{ - pCmdList->EndQuery(m_OcclusionHeap, counter ? D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION, index); - - m_OcclusionMapValid = false; - if (m_OcclusionMemory) - { - const D3D12_RANGE sNoWrite = { 0, 0 }; - m_OcclusionDownloadBuffer->Unmap(0, &sNoWrite); - m_OcclusionMemory = nullptr; - } - - return m_OcclusionDownloadBuffer; -} - -void CCryDX12DeviceContext::ResolveOcclusion(DX12::CommandList* pCmdList, UINT index, void* mem) -{ - if (mem) - { - if (!m_OcclusionMapValid) - { - if (m_OcclusionMemory) - { - const D3D12_RANGE sNoWrite = { 0, 0 }; - m_OcclusionDownloadBuffer->Unmap(0, &sNoWrite); - m_OcclusionMemory = nullptr; - } - - pCmdList->ResolveQueryData(m_OcclusionHeap, D3D12_QUERY_TYPE_OCCLUSION, 0, m_OcclusionHeap.GetCapacity(), m_OcclusionDownloadBuffer, 0); - - // Resources on D3D12_HEAP_TYPE_READBACK heaps do not support persistent map. - const D3D12_RANGE sFullRead = { 0, sizeof(UINT64) * m_OcclusionHeap.GetCapacity() }; - m_OcclusionDownloadBuffer->Map(0, &sFullRead, &m_OcclusionMemory); - m_OcclusionMapValid = true; - } - - memcpy(mem, (char*)m_OcclusionMemory + index * 8, 8); - } -} - -void CCryDX12DeviceContext::WaitForIdle() -{ - DX12::CommandListFence fence(m_pDX12Device); - fence.Init(); - - m_DirectListPool.GetD3D12CommandQueue()->Signal(fence.GetFence(), 1); - - fence.WaitForFence(1); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma region /* ID3D11DeviceChild implementation */ - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GetDevice( - [[maybe_unused]] _Out_ ID3D11Device** ppDevice) -{ - DX12_FUNC_LOG -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::GetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _Inout_ UINT* pDataSize, - [[maybe_unused]] _Out_writes_bytes_opt_(*pDataSize) void* pData) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::SetPrivateData( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_ UINT DataSize, - [[maybe_unused]] _In_reads_bytes_opt_(DataSize) const void* pData) -{ - DX12_FUNC_LOG - return -1; -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::SetPrivateDataInterface( - [[maybe_unused]] _In_ REFGUID guid, - [[maybe_unused]] _In_opt_ const IUnknown* pData) -{ - DX12_FUNC_LOG - return -1; -} - -#pragma endregion - -#pragma region /* ID3D11DeviceContext implementation */ - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - VSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Pixel].ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSSetShader( - _In_opt_ ID3D11PixelShader* pPixelShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Pixel].Shader.Set(reinterpret_cast(pPixelShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Pixel].SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSSetShader( - _In_opt_ ID3D11VertexShader* pVertexShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Vertex].Shader.Set(reinterpret_cast(pVertexShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawIndexed( - _In_ UINT IndexCount, - _In_ UINT StartIndexLocation, - _In_ INT BaseVertexLocation) -{ - DX12_FUNC_LOG - - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - - if (PrepareGraphicsState()) - { - m_DirectCommandList->DrawIndexedInstanced(IndexCount, 1, StartIndexLocation, BaseVertexLocation, 0); -#ifdef AZ_DEBUG_BUILD - m_PipelineState[DX12::CommandModeGraphics].DebugPrint(); -#endif - if constexpr (DX12_SUBMISSION_MODE <= DX12_SUBMISSION_PERDRAW) - { - if (m_OutstandingQueries == 0) - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::Draw( - _In_ UINT VertexCount, - _In_ UINT StartVertexLocation) -{ - DX12_FUNC_LOG - - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - - if (PrepareGraphicsState()) - { - m_DirectCommandList->DrawInstanced(VertexCount, 1, StartVertexLocation, 0); -#ifdef AZ_DEBUG_BUILD - m_PipelineState[DX12::CommandModeGraphics].DebugPrint(); -#endif - if constexpr (DX12_SUBMISSION_MODE <= DX12_SUBMISSION_PERDRAW) - { - if (m_OutstandingQueries == 0) - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } - } -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::Map( - _In_ ID3D11Resource* pResource, - _In_ UINT Subresource, - _In_ D3D11_MAP MapType, - [[maybe_unused]] _In_ UINT MapFlags, - _Out_ D3D11_MAPPED_SUBRESOURCE* pMappedResource) -{ - DX12_FUNC_LOG - - ZeroMemory(pMappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE)); - - DX12_LOG(" Mapping resource: %p (%d)", pResource, Subresource); - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pResource); - DX12::Resource& resource = dx12Resource->GetDX12Resource(); - - if (!resource.IsOffCard()) - { - return S_FALSE; - } - - switch (MapType) - { - case D3D11_MAP_READ: - // Ensure the command-list using the resource is executed - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, resource.GetFenceValues(CMDTYPE_WRITE)); - - // Block the CPU-thread until the resource is safe to map - resource.WaitForUnused(m_DirectListPool, CMDTYPE_WRITE); - break; - case D3D11_MAP_WRITE: - case D3D11_MAP_READ_WRITE: - // Ensure the command-list using the resource is executed - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, resource.GetFenceValues(CMDTYPE_ANY)); - - // Block the CPU-thread until the resource is safe to map - resource.WaitForUnused(m_DirectListPool, CMDTYPE_ANY); - break; - case D3D11_MAP_WRITE_DISCARD: - DX12_LOG("Using D3D11_MAP_WRITE_DISCARD on old ID3D12Resource: %p", DX12_EXTRACT_D3D12RESOURCE(pResource)); - -#ifdef DX12_STATS - m_NumMapDiscardSkips += !resource.IsUsed(m_DirectListPool); - m_NumMapDiscards++; -#endif // DX12_STATS - - // If the resource is not currently used, we do not need to discard the memory - if (resource.IsUsed(m_DirectListPool)) - { - dx12Resource->MapDiscard(m_DirectCommandList); - } - - DX12_LOG("New ID3D12Resource: %p", DX12_EXTRACT_D3D12RESOURCE(pResource)); - break; - case D3D11_MAP_WRITE_NO_OVERWRITE: - break; - default: - break; - } - - static D3D12_RANGE sRg[] = - { - { 0, 0 }, // It is valid to specify the CPU won't read any data by passing a range where End is less than or equal to Begin - { 0, 0 } // It is valid to specify the CPU didn't write any data by passing a range where End is less than or equal to Begin. - }; - - static D3D12_RANGE* pRanges[] = - { - nullptr, // D3D11_MAP_READ = 1, - nullptr, // D3D11_MAP_WRITE = 2, - nullptr, // D3D11_MAP_READ_WRITE = 3, - &sRg[0], // D3D11_MAP_WRITE_DISCARD = 4, - &sRg[0], // D3D11_MAP_WRITE_NO_OVERWRITE = 5 - }; - AZ_Assert((MapType - 1) < AZ_ARRAY_SIZE(pRanges), "Invalid map type"); - - AZ_Assert(!D3D12IsLayoutOpaque(resource.GetDesc().Layout), "Opaque layouts are unmappable until 12.2!"); - HRESULT hr = dx12Resource->GetD3D12Resource()->Map(Subresource, pRanges[MapType - 1], &(pMappedResource->pData)); - - if (S_OK != hr) - { - AZ_Assert(0, "Could not map resource!"); - return hr; - } - - return S_OK; -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::Unmap( - _In_ ID3D11Resource* pResource, - _In_ UINT Subresource) -{ - DX12_FUNC_LOG - - DX12_LOG("Unmapping resource: %p (%d)", pResource, Subresource); - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pResource); - - // NOTE: Don't know MapType, can't optimize writeRange! - - AZ_Assert(!D3D12IsLayoutOpaque(dx12Resource->GetDX12Resource().GetDesc().Layout), "Opaque layouts are unmappable until 12.2!"); - dx12Resource->GetD3D12Resource()->Unmap(Subresource, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - PSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IASetInputLayout( - _In_opt_ ID3D11InputLayout* pInputLayout) -{ - DX12_FUNC_LOG - - m_PipelineState[DX12::CommandModeGraphics].InputAssembler.InputLayout.Set(reinterpret_cast(pInputLayout)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IASetVertexBuffers( - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppVertexBuffers, - _In_reads_opt_(NumBuffers) const UINT* pStrides, - _In_reads_opt_(NumBuffers) const UINT* pOffsets) -{ - DX12_FUNC_LOG - - auto& inputAssembler = m_PipelineState[DX12::CommandModeGraphics].InputAssembler; - for (UINT i = StartSlot, S = StartSlot + NumBuffers; i < S; ++i, ++ppVertexBuffers, ++pStrides, ++pOffsets) - { - CCryDX12Buffer* vb = reinterpret_cast(*ppVertexBuffers); - - inputAssembler.Strides.Set(i, *pStrides); - inputAssembler.Offsets.Set(i, *pOffsets); - if (inputAssembler.VertexBuffers.Set(i, vb) && vb) - { - vb->BeginResourceStateTransition(m_DirectCommandList.get(), D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); - } - } - - UINT numVertexBuffers = 0; - for (UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) - { - if (inputAssembler.VertexBuffers.Get(i)) - { - numVertexBuffers = i + 1; - } - } - - inputAssembler.NumVertexBuffers.Set(numVertexBuffers); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IASetIndexBuffer( - _In_opt_ ID3D11Buffer* pIndexBuffer, - _In_ DXGI_FORMAT Format, - _In_ UINT Offset) -{ - DX12_FUNC_LOG - - auto& inputAssembler = m_PipelineState[DX12::CommandModeGraphics].InputAssembler; - CCryDX12Buffer* ib = reinterpret_cast(pIndexBuffer); - - inputAssembler.IndexBufferFormat.Set(Format); - inputAssembler.IndexBufferOffset.Set(Offset); - if (inputAssembler.IndexBuffer.Set(ib) && ib) - { - ib->BeginResourceStateTransition(m_DirectCommandList.get(), D3D12_RESOURCE_STATE_INDEX_BUFFER); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawIndexedInstanced( - _In_ UINT IndexCountPerInstance, - _In_ UINT InstanceCount, - _In_ UINT StartIndexLocation, - _In_ INT BaseVertexLocation, - _In_ UINT StartInstanceLocation) -{ - DX12_FUNC_LOG - - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - - if (PrepareGraphicsState()) - { - m_DirectCommandList->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); -#ifdef AZ_DEBUG_BUILD - m_PipelineState[DX12::CommandModeGraphics].DebugPrint(); -#endif - if constexpr (DX12_SUBMISSION_MODE <= DX12_SUBMISSION_PERDRAW) - { - if (m_OutstandingQueries == 0) - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawInstanced( - _In_ UINT VertexCountPerInstance, - _In_ UINT InstanceCount, - _In_ UINT StartVertexLocation, - _In_ UINT StartInstanceLocation) -{ - DX12_FUNC_LOG - - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - - if (PrepareGraphicsState()) - { - m_DirectCommandList->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); -#ifdef AZ_DEBUG_BUILD - m_PipelineState[DX12::CommandModeGraphics].DebugPrint(); -#endif - if constexpr (DX12_SUBMISSION_MODE <= DX12_SUBMISSION_PERDRAW) - { - if (m_OutstandingQueries == 0) - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - GSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSSetShader( - _In_opt_ ID3D11GeometryShader* pShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Geometry].Shader.Set(reinterpret_cast(pShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IASetPrimitiveTopology( - _In_ D3D11_PRIMITIVE_TOPOLOGY Topology) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].InputAssembler.PrimitiveTopology.Set(Topology); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Vertex].ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Vertex].SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::Begin( - _In_ ID3D11Asynchronous* pAsync) -{ - DX12_FUNC_LOG - auto pQuery = reinterpret_cast(pAsync); - - D3D11_QUERY_DESC desc; - pQuery->GetDesc(&desc); - - if (desc.Query == D3D11_QUERY_EVENT) - { - return; - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP_DISJOINT) - { - return; - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP) - { - return; - } - else if (desc.Query == D3D11_QUERY_OCCLUSION || desc.Query == D3D11_QUERY_OCCLUSION_PREDICATE) - { - auto pOcclusionQuery = reinterpret_cast(pAsync); - pOcclusionQuery->SetFenceValue(m_CmdFenceSet.GetCurrentValue(CMDQUEUE_GRAPHICS)); - pOcclusionQuery->SetQueryIndex(OcclusionIndex(m_DirectCommandList, desc.Query == D3D11_QUERY_OCCLUSION)); - ++m_OutstandingQueries; - } - else - { - __debugbreak(); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::End( - _In_ ID3D11Asynchronous* pAsync) -{ - DX12_FUNC_LOG - auto pQuery = reinterpret_cast(pAsync); - - D3D11_QUERY_DESC desc; - pQuery->GetDesc(&desc); - - if (desc.Query == D3D11_QUERY_EVENT) - { - // Record fence of commands prior to this point - auto pEventQuery = reinterpret_cast(pAsync); - pEventQuery->SetFenceValue(InsertFence()); - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP_DISJOINT) - { - return; - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP) - { - // Record fence of commands following at this point - auto pTimestampQuery = reinterpret_cast(pAsync); - pTimestampQuery->SetFenceValue(InsertFence()); - pTimestampQuery->SetQueryIndex(TimestampIndex(m_DirectCommandList)); - pTimestampQuery->SetQueryResource(QueryTimestamp(m_DirectCommandList, pTimestampQuery->GetQueryIndex())); - } - else if (desc.Query == D3D11_QUERY_OCCLUSION) - { - auto pOcclusionQuery = reinterpret_cast(pAsync); - pOcclusionQuery->SetFenceValue(InsertFence()); - pOcclusionQuery->SetQueryResource(QueryOcclusion(m_DirectCommandList, pOcclusionQuery->GetQueryIndex(), desc.Query == D3D11_QUERY_OCCLUSION)); - - AZ_Assert(m_OutstandingQueries != 0, "End without a Start"); - --m_OutstandingQueries; - } - else // || desc.Query == D3D11_QUERY_OCCLUSION_PREDICATE) - { - __debugbreak(); - } -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::GetData( - _In_ ID3D11Asynchronous* pAsync, - _Out_writes_bytes_opt_(DataSize) void* pData, - [[maybe_unused]] _In_ UINT DataSize, - _In_ UINT GetDataFlags) -{ - DX12_FUNC_LOG - auto pQuery = reinterpret_cast(pAsync); - - D3D11_QUERY_DESC desc; - pQuery->GetDesc(&desc); - - if (desc.Query == D3D11_QUERY_EVENT) - { - AZ_Assert(DataSize >= sizeof(BOOL), "Invalid data size"); - - auto pEventQuery = reinterpret_cast(pAsync); - bool bComplete = TestForFence(pEventQuery->GetFenceValue()) == S_OK; - - if (!bComplete && !(GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH)) - { - // Ensure the command-list issuing the query is executed - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, pEventQuery->GetFenceValue()); - FlushToFence(pEventQuery->GetFenceValue()); - } - - *reinterpret_cast(pData) = bComplete; - return bComplete ? S_OK : S_FALSE; - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP_DISJOINT) - { - AZ_Assert(DataSize >= sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), "Invalid data size"); - D3D11_QUERY_DATA_TIMESTAMP_DISJOINT sData; - - // D3D12 WARNING: ID3D12CommandQueue::ID3D12CommandQueue::GetTimestampFrequency: Use - // ID3D12Device::SetStablePowerstate for reliable timestamp queries [ EXECUTION WARNING #736: UNSTABLE_POWER_STATE] - sData.Disjoint = FALSE; - sData.Frequency = m_pDX12Device->GetGpuTimestampFrequency(); - - *reinterpret_cast(pData) = sData; - - return S_OK; - } - else if (desc.Query == D3D11_QUERY_TIMESTAMP) - { - AZ_Assert(DataSize >= sizeof(UINT64), "Invalid data size"); - - auto pTimestampQuery = reinterpret_cast(pAsync); - bool bComplete = TestForFence(pTimestampQuery->GetFenceValue()) == S_OK; - - if (!bComplete && !(GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH)) - { - // Ensure the command-list issuing the timestamp is executed - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, pTimestampQuery->GetFenceValue()); - FlushToFence(pTimestampQuery->GetFenceValue()); - } - - // Since we do FlushToFence if not completed, it will be completed now. - ResolveTimestamp(m_DirectCommandList, pTimestampQuery->GetQueryIndex(), pData); - - return S_OK; - } - else if (desc.Query == D3D11_QUERY_OCCLUSION) - { - AZ_Assert(DataSize >= sizeof(UINT64), "Invalid data size"); - - auto pOcclusionQuery = reinterpret_cast(pAsync); - bool bComplete = TestForFence(pOcclusionQuery->GetFenceValue()) == S_OK; - - if (!bComplete && !(GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH)) - { - // Ensure the command-list issuing the query is executed - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, pOcclusionQuery->GetFenceValue()); - FlushToFence(pOcclusionQuery->GetFenceValue()); - } - - if (bComplete) - { - ResolveOcclusion(m_DirectCommandList, pOcclusionQuery->GetQueryIndex(), pData); - } - - return (bComplete) ? S_OK : S_FALSE; - } - else // || desc.Query == D3D11_QUERY_OCCLUSION_PREDICATE - { - __debugbreak(); - } - - return S_OK; -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::SetPredication( - [[maybe_unused]] _In_opt_ ID3D11Predicate* pPredicate, - [[maybe_unused]] _In_ BOOL PredicateValue) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - auto& geometry = m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Geometry]; - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (geometry.ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - auto& geometry = m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Geometry]; - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - geometry.SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -static void ValidateSwapChain([[maybe_unused]] CCryDX12RenderTargetView& rtv) -{ -#if defined(DEBUG) - if (DX12::SwapChain* swapChain = rtv.GetDX12Resource().GetDX12SwapChain()) - { - AZ_Assert(swapChain->GetCurrentBackBuffer().GetD3D12Resource() == rtv.GetDX12Resource().GetD3D12Resource(), "invalid swap chain buffer"); - } -#endif -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMSetRenderTargets( - _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11RenderTargetView* const* ppRenderTargetViews, - _In_opt_ ID3D11DepthStencilView* pDepthStencilView) -{ - DX12_FUNC_LOG - auto& outputMerger = m_PipelineState[DX12::CommandModeGraphics].OutputMerger; - - outputMerger.NumRenderTargets.Set(NumViews); - for (UINT i = 0; i < NumViews; ++i) - { - CCryDX12RenderTargetView* rtv = reinterpret_cast(ppRenderTargetViews[i]); - if (outputMerger.RenderTargetViews.Set(i, rtv)) - { - if (!rtv) - { - outputMerger.RTVFormats.Set(i, DXGI_FORMAT_UNKNOWN); - continue; - } - - ValidateSwapChain(*rtv); - - DX12_LOG("Setting render target: %p (%d)", rtv, i); - - // TODO: this might not be the earliest moment when it is known that the resource is used as render-target - D3D11_RENDER_TARGET_VIEW_DESC desc; - rtv->GetDesc(&desc); - rtv->BeginResourceStateTransition(m_DirectCommandList.get()); - - outputMerger.RTVFormats.Set(i, desc.Format); - } - } - - for (UINT i = NumViews; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) - { - outputMerger.RenderTargetViews.Set(i, nullptr); - outputMerger.RTVFormats.Set(i, DXGI_FORMAT_UNKNOWN); - } - - { - CCryDX12DepthStencilView* dsv = reinterpret_cast(pDepthStencilView); - if (outputMerger.DepthStencilView.Set(dsv)) - { - if (!dsv) - { - outputMerger.DSVFormat.Set(DXGI_FORMAT_UNKNOWN); - return; - } - - DX12_LOG("Setting depth stencil view: %p", dsv); - - // TODO: this might not be the earliest moment when it is known that the resource is used as depth-stencil - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - dsv->GetDesc(&desc); - dsv->BeginResourceStateTransition(m_DirectCommandList.get()); - - outputMerger.DSVFormat.Set(desc.Format); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( - _In_ UINT NumRTVs, - [[maybe_unused]] _In_reads_opt_(NumRTVs) ID3D11RenderTargetView* const* ppRenderTargetViews, - [[maybe_unused]] _In_opt_ ID3D11DepthStencilView* pDepthStencilView, - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - 1) UINT UAVStartSlot, - _In_ UINT NumUAVs, - _In_reads_opt_(NumUAVs) ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - [[maybe_unused]] _In_reads_opt_(NumUAVs) const UINT* pUAVInitialCounts) -{ - DX12_FUNC_LOG - if (NumRTVs > 0 && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - DX12_NOT_IMPLEMENTED //@TODO: Only the Unordered Access View portion of this function is implemented. - } - - auto& graphicsStage = m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Pixel]; - for (UINT i = UAVStartSlot, S = UAVStartSlot + NumUAVs; i < S; ++i, ++ppUnorderedAccessViews) - { - CCryDX12UnorderedAccessView* uav = reinterpret_cast(*ppUnorderedAccessViews); - if (graphicsStage.UnorderedAccessViews.Set(i, uav) && uav) - { - uav->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMSetBlendState( - _In_opt_ ID3D11BlendState* pBlendState, - [[maybe_unused]] _In_opt_ const FLOAT BlendFactor[4], - _In_ UINT SampleMask) -{ - DX12_FUNC_LOG - - auto& outputMerger = m_PipelineState[DX12::CommandModeGraphics].OutputMerger; - outputMerger.BlendState.Set(reinterpret_cast(pBlendState)); - outputMerger.SampleMask.Set(SampleMask); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMSetDepthStencilState( - _In_opt_ ID3D11DepthStencilState* pDepthStencilState, - _In_ UINT StencilRef) -{ - DX12_FUNC_LOG - - auto& state = m_PipelineState[DX12::CommandModeGraphics]; - state.Rasterizer.DepthStencilState.Set(reinterpret_cast(pDepthStencilState)); - state.OutputMerger.StencilRef.Set(StencilRef); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::SOSetTargets( - [[maybe_unused]] _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, - [[maybe_unused]] _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppSOTargets, - [[maybe_unused]] _In_reads_opt_(NumBuffers) const UINT* pOffsets) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawAuto() -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawIndexedInstancedIndirect( - [[maybe_unused]] _In_ ID3D11Buffer* pBufferForArgs, - [[maybe_unused]] _In_ UINT AlignedByteOffsetForArgs) -{ - DX12_FUNC_LOG - DX12_ASSERT(false, "unimplemented"); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DrawInstancedIndirect( - [[maybe_unused]] _In_ ID3D11Buffer* pBufferForArgs, - [[maybe_unused]] _In_ UINT AlignedByteOffsetForArgs) -{ - DX12_FUNC_LOG - DX12_ASSERT(false, "unimplemented"); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::Dispatch( - _In_ UINT ThreadGroupCountX, - _In_ UINT ThreadGroupCountY, - _In_ UINT ThreadGroupCountZ) -{ - DX12_FUNC_LOG - - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - - if (PrepareComputeState()) - { - m_DirectCommandList->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); -#ifdef AZ_DEBUG_BUILD - m_PipelineState[DX12::CommandModeCompute].DebugPrint(); -#endif - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DispatchIndirect( - [[maybe_unused]] _In_ ID3D11Buffer* pBufferForArgs, - [[maybe_unused]] _In_ UINT AlignedByteOffsetForArgs) -{ - DX12_FUNC_LOG - DX12_ASSERT(false, "unimplemented"); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSSetState( - _In_opt_ ID3D11RasterizerState* pRasterizerState) -{ - DX12_FUNC_LOG - - auto& rasterizer = m_PipelineState[DX12::CommandModeGraphics].Rasterizer; - rasterizer.RasterizerState.Set(reinterpret_cast(pRasterizerState)); - if (pRasterizerState) - { - const D3D11_RASTERIZER_DESC& d3d11Desc = rasterizer.RasterizerState->GetD3D11RasterizerDesc(); - rasterizer.ScissorEnabled.Set(d3d11Desc.ScissorEnable); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSSetViewports( - _In_range_(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, - _In_reads_opt_(NumViewports) const D3D11_VIEWPORT* pViewports) -{ - DX12_FUNC_LOG - - auto& rasterizer = m_PipelineState[DX12::CommandModeGraphics].Rasterizer; - rasterizer.NumViewports.Set(NumViewports); - if (NumViewports) - { - for (UINT i = 0; i < NumViewports; ++i, ++pViewports) - { - rasterizer.Viewports.Set(i, *pViewports); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSSetScissorRects( - _In_range_(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - - auto& rasterizer = m_PipelineState[DX12::CommandModeGraphics].Rasterizer; - rasterizer.NumScissors.Set(NumRects); - if (NumRects) - { - for (UINT i = 0; i < NumRects; ++i, ++pRects) - { - rasterizer.Scissors.Set(i, *pRects); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CopySubresourceRegion( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_ UINT DstX, - _In_ UINT DstY, - _In_ UINT DstZ, - _In_ ID3D11Resource* pSrcResource, - _In_ UINT SrcSubresource, - _In_opt_ const D3D11_BOX* pSrcBox) -{ - DX12_FUNC_LOG - - CopySubresourceRegion1( - pDstResource, - DstSubresource, - DstX, - DstY, - DstZ, - pSrcResource, - SrcSubresource, - pSrcBox, - 0); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CopyResource( - _In_ ID3D11Resource* pDstResource, - _In_ ID3D11Resource* pSrcResource) -{ - DX12_FUNC_LOG - - CopyResource1( - pDstResource, - pSrcResource, - 0); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::UploadResource( - _In_ ICryDX12Resource* pDstResource, - _In_ const D3D11_SUBRESOURCE_DATA* pInitialData, - _In_ size_t numInitialData) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - - DX12::Resource& dstResource = pDstResource->GetDX12Resource(); - DX12::Resource::InitialData* id = dstResource.GetOrCreateInitialData(); - - - D3D12_RESOURCE_DESC desc = dstResource.GetDesc(); - const UINT maxSubResource = 64; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[maxSubResource]; - UINT nRows[maxSubResource]; - UINT64 rowSizes[maxSubResource]; - CRY_ASSERT(numInitialData <= maxSubResource); - - dstResource.GetDevice()->GetD3D12Device()->GetCopyableFootprints(&desc, 0, numInitialData, 0, layouts, nRows, rowSizes, &id->m_UploadSize); - - id->m_SubResourceData.resize(numInitialData); - - //Manually compute id->m_Size. This number is used to figure out the size of the intermediate CPU/GPU buffer into which the texture data is copied. - //The reason for doing this manually is because pTotalBytes (set by GetCopyableFootprints) is not completely accurate. For some reason it - //seems like it doesnt take into account the 256 byte alignment padding of the last mip of a texture. Hence manually calculating the size - //using the pNumRows (in this case nRows) and pRowSizeInBytes (in this case rowSizes). - UINT64 totalBufferSize = 0; - - for (UINT i = 0; i < numInitialData; ++i) - { - D3D12_SUBRESOURCE_DATA initialDestData; - - initialDestData.RowPitch = pInitialData[i].SysMemPitch; - initialDestData.SlicePitch = pInitialData[i].SysMemSlicePitch; - - UINT64 slicePitchSize = 0; - slicePitchSize = pInitialData[i].SysMemSlicePitch * desc.DepthOrArraySize; // Exact size of the texture data. No padding. - //TODO: pInitialData[i].SysMemSlicePitch can be 0 if the texture loading code doesnt set it. Fix this. For now we just query the GPU for the size (which is padded and wastes memory). - if (slicePitchSize == 0) - { - slicePitchSize = dstResource.GetRequiredUploadSize(i, 1); - } - - BYTE* destMemory = new uint8_t[slicePitchSize]; - UINT gpuSlicePitchSize = layouts[i].Footprint.RowPitch * nRows[i]; - D3D12_MEMCPY_DEST destData = { destMemory, layouts[i].Footprint.RowPitch, gpuSlicePitchSize }; - - const BYTE* pSrc = static_cast (pInitialData[i].pSysMem); - - for (UINT z = 0; z < layouts[i].Footprint.Depth; ++z) - { - BYTE* pDestSlice = static_cast (destData.pData) + pInitialData[i].SysMemSlicePitch * z; - const BYTE* pSrcSlice = pSrc + pInitialData[i].SysMemSlicePitch * z; - for (UINT y = 0; y < nRows[i]; ++y) - { - memcpy(pDestSlice + pInitialData[i].SysMemPitch * y, - pSrcSlice + pInitialData[i].SysMemPitch * y, - pInitialData[i].SysMemPitch); - } - } - initialDestData.pData = destMemory; - id->m_SubResourceData[i] = initialDestData; - totalBufferSize += gpuSlicePitchSize; - } - id->m_Size = totalBufferSize; - UploadResource(&dstResource, id); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::UploadResource( - [[maybe_unused]] _In_ DX12::Resource* pDstResource, - [[maybe_unused]] _In_ const DX12::Resource::InitialData* pSrcData) -{ - DX12_FUNC_LOG - - // TODO: This needs to be thread-safe - // pDstResource->InitDeferred(m_pGraphicsCmdList); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::UpdateSubresource( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_opt_ const D3D11_BOX* pDstBox, - _In_ const void* pSrcData, - _In_ UINT SrcRowPitch, - _In_ UINT SrcDepthPitch) -{ - DX12_FUNC_LOG - - UpdateSubresource1( - pDstResource, - DstSubresource, - pDstBox, - pSrcData, - SrcRowPitch, - SrcDepthPitch, - 0); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CopyStructureCount( - [[maybe_unused]] _In_ ID3D11Buffer* pDstBuffer, - [[maybe_unused]] _In_ UINT DstAlignedByteOffset, - [[maybe_unused]] _In_ ID3D11UnorderedAccessView* pSrcView) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearRenderTargetView( - _In_ ID3D11RenderTargetView* pRenderTargetView, - _In_ const FLOAT ColorRGBA[4]) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pRenderTargetView); - CCryDX12RenderTargetView* rtv = reinterpret_cast(pRenderTargetView); - DX12_LOG("Clearing render target view: %p %s", pRenderTargetView, rtv->GetResourceName().c_str()); - - ValidateSwapChain(*rtv); - m_DirectCommandList->ClearRenderTargetView(*view, ColorRGBA); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearUnorderedAccessViewUint( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const UINT Values[4]) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pUnorderedAccessView); -#ifndef NDEBUG - CCryDX12UnorderedAccessView* uav = reinterpret_cast(pUnorderedAccessView); - DX12_LOG("Clearing unordered access view [int]: %p %s", pUnorderedAccessView, uav->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearUnorderedAccessView(*view, Values); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearUnorderedAccessViewFloat( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const FLOAT Values[4]) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pUnorderedAccessView); -#ifndef NDEBUG - CCryDX12UnorderedAccessView* uav = reinterpret_cast(pUnorderedAccessView); - DX12_LOG("Clearing unordered access view [float]: %p %s", pUnorderedAccessView, uav->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearUnorderedAccessView(*view, Values); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearDepthStencilView( - _In_ ID3D11DepthStencilView* pDepthStencilView, - _In_ UINT ClearFlags, // DX11 and DX12 clear flags are identical - _In_ FLOAT Depth, - _In_ UINT8 Stencil) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pDepthStencilView); -#ifndef NDEBUG - CCryDX12DepthStencilView* dsv = reinterpret_cast(pDepthStencilView); - DX12_LOG("Clearing depth stencil view: %p %s", pDepthStencilView, dsv->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearDepthStencilView(*view, D3D12_CLEAR_FLAGS(ClearFlags), Depth, Stencil); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GenerateMips( - [[maybe_unused]] _In_ ID3D11ShaderResourceView* pShaderResourceView) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::SetResourceMinLOD( - [[maybe_unused]] _In_ ID3D11Resource* pResource, - [[maybe_unused]] FLOAT MinLOD) -{ - DX12_FUNC_LOG -} - -FLOAT STDMETHODCALLTYPE CCryDX12DeviceContext::GetResourceMinLOD( - [[maybe_unused]] _In_ ID3D11Resource* pResource) -{ - DX12_FUNC_LOG - return 0.0f; -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ResolveSubresource( - [[maybe_unused]] _In_ ID3D11Resource* pDstResource, - [[maybe_unused]] _In_ UINT DstSubresource, - [[maybe_unused]] _In_ ID3D11Resource* pSrcResource, - [[maybe_unused]] _In_ UINT SrcSubresource, - [[maybe_unused]] _In_ DXGI_FORMAT Format) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Hull].ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSSetShader( - _In_opt_ ID3D11HullShader* pHullShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Hull].Shader.Set(reinterpret_cast(pHullShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Hull].SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - HSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Domain].ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSSetShader( - _In_opt_ ID3D11DomainShader* pDomainShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Domain].Shader.Set(reinterpret_cast(pDomainShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - m_PipelineState[DX12::CommandModeGraphics].Stages[DX12::ESS_Domain].SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - DSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView* const* ppShaderResourceViews) -{ - DX12_FUNC_LOG - auto& compute = m_PipelineState[DX12::CommandModeCompute].Stages[DX12::ESS_Compute]; - for (UINT i = StartSlot, S = StartSlot + NumViews; i < S; ++i, ++ppShaderResourceViews) - { - CCryDX12ShaderResourceView* srv = reinterpret_cast(*ppShaderResourceViews); - if (compute.ShaderResourceViews.Set(i, srv) && srv) - { - srv->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSSetUnorderedAccessViews( - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - StartSlot) UINT NumUAVs, - _In_reads_opt_(NumUAVs) ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - [[maybe_unused]] _In_reads_opt_(NumUAVs) const UINT* pUAVInitialCounts) -{ - DX12_FUNC_LOG - auto& compute = m_PipelineState[DX12::CommandModeCompute].Stages[DX12::ESS_Compute]; - for (UINT i = StartSlot, S = StartSlot + NumUAVs; i < S; ++i, ++ppUnorderedAccessViews) - { - CCryDX12UnorderedAccessView* uav = reinterpret_cast(*ppUnorderedAccessViews); - if (compute.UnorderedAccessViews.Set(i, uav) && uav) - { - uav->BeginResourceStateTransition(m_DirectCommandList.get()); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSSetShader( - _In_opt_ ID3D11ComputeShader* pComputeShader, - [[maybe_unused]] _In_reads_opt_(NumClassInstances) ID3D11ClassInstance* const* ppClassInstances, - [[maybe_unused]] UINT NumClassInstances) -{ - DX12_FUNC_LOG - m_PipelineState[DX12::CommandModeCompute].Stages[DX12::ESS_Compute].Shader.Set(reinterpret_cast(pComputeShader)); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState* const* ppSamplers) -{ - DX12_FUNC_LOG - for (UINT i = StartSlot, S = StartSlot + NumSamplers; i < S; ++i, ++ppSamplers) - { - m_PipelineState[DX12::CommandModeCompute].Stages[DX12::ESS_Compute].SamplerState.Set(i, reinterpret_cast(*ppSamplers)); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer* const* ppConstantBuffers) -{ - CSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, NULL, NULL); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSGetShader( - [[maybe_unused]] _Out_ ID3D11PixelShader** ppPixelShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSGetShader( - [[maybe_unused]] _Out_ ID3D11VertexShader** ppVertexShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::PSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IAGetInputLayout( - _Out_ ID3D11InputLayout** ppInputLayout) -{ - DX12_FUNC_LOG - *ppInputLayout = m_PipelineState[DX12::CommandModeGraphics].InputAssembler.InputLayout; - if (*ppInputLayout) - { - (*ppInputLayout)->AddRef(); - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IAGetVertexBuffers( - [[maybe_unused]] _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppVertexBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) UINT* pStrides, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) UINT* pOffsets) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IAGetIndexBuffer( - _Out_opt_ ID3D11Buffer** pIndexBuffer, - _Out_opt_ DXGI_FORMAT* Format, - _Out_opt_ UINT* Offset) -{ - DX12_FUNC_LOG - auto& inputAssembler = m_PipelineState[DX12::CommandModeGraphics].InputAssembler; - * pIndexBuffer = inputAssembler.IndexBuffer; - if (*pIndexBuffer) - { - (*pIndexBuffer)->AddRef(); - } - - *Format = inputAssembler.IndexBufferFormat.Get(); - *Offset = inputAssembler.IndexBufferOffset.Get(); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSGetShader( - [[maybe_unused]] _Out_ ID3D11GeometryShader** ppGeometryShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::IAGetPrimitiveTopology( - _Out_ D3D11_PRIMITIVE_TOPOLOGY* pTopology) -{ - DX12_FUNC_LOG - *pTopology = m_PipelineState[DX12::CommandModeGraphics].InputAssembler.PrimitiveTopology.Get(); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::VSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GetPredication( - [[maybe_unused]] _Out_opt_ ID3D11Predicate** ppPredicate, - [[maybe_unused]] _Out_opt_ BOOL* pPredicateValue) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::GSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMGetRenderTargets( - [[maybe_unused]] _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11RenderTargetView** ppRenderTargetViews, - [[maybe_unused]] _Out_opt_ ID3D11DepthStencilView** ppDepthStencilView) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews( - [[maybe_unused]] _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumRTVs, - [[maybe_unused]] _Out_writes_opt_(NumRTVs) ID3D11RenderTargetView** ppRenderTargetViews, - [[maybe_unused]] _Out_opt_ ID3D11DepthStencilView** ppDepthStencilView, - [[maybe_unused]] _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1) UINT UAVStartSlot, - [[maybe_unused]] _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - UAVStartSlot) UINT NumUAVs, - [[maybe_unused]] _Out_writes_opt_(NumUAVs) ID3D11UnorderedAccessView** ppUnorderedAccessViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMGetBlendState( - [[maybe_unused]] _Out_opt_ ID3D11BlendState** ppBlendState, - [[maybe_unused]] _Out_opt_ FLOAT BlendFactor[4], - [[maybe_unused]] _Out_opt_ UINT* pSampleMask) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::OMGetDepthStencilState( - [[maybe_unused]] _Out_opt_ ID3D11DepthStencilState** ppDepthStencilState, - [[maybe_unused]] _Out_opt_ UINT* pStencilRef) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::SOGetTargets( - [[maybe_unused]] _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppSOTargets) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSGetState( - [[maybe_unused]] _Out_ ID3D11RasterizerState** ppRasterizerState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSGetViewports( - [[maybe_unused]] _Inout_ UINT* pNumViewports, - [[maybe_unused]] _Out_writes_opt_(*pNumViewports) D3D11_VIEWPORT* pViewports) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::RSGetScissorRects( - [[maybe_unused]] _Inout_ UINT* pNumRects, - [[maybe_unused]] _Out_writes_opt_(*pNumRects) D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSGetShader( - [[maybe_unused]] _Out_ ID3D11HullShader** ppHullShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::HSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSGetShader( - [[maybe_unused]] _Out_ ID3D11DomainShader** ppDomainShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::DSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSGetShaderResources( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - [[maybe_unused]] _Out_writes_opt_(NumViews) ID3D11ShaderResourceView** ppShaderResourceViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSGetUnorderedAccessViews( - [[maybe_unused]] _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot) UINT NumUAVs, - [[maybe_unused]] _Out_writes_opt_(NumUAVs) ID3D11UnorderedAccessView** ppUnorderedAccessViews) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSGetShader( - [[maybe_unused]] _Out_ ID3D11ComputeShader** ppComputeShader, - [[maybe_unused]] _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - [[maybe_unused]] _Inout_opt_ UINT* pNumClassInstances) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSGetSamplers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - [[maybe_unused]] _Out_writes_opt_(NumSamplers) ID3D11SamplerState** ppSamplers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CSGetConstantBuffers( - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - [[maybe_unused]] _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - [[maybe_unused]] _Out_writes_opt_(NumBuffers) ID3D11Buffer** ppConstantBuffers) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearState() -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::Flush() -{ - DX12_FUNC_LOG - - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, m_CmdFenceSet.GetCurrentValues()); -} - -D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE CCryDX12DeviceContext::GetType() -{ - DX12_FUNC_LOG - return D3D11_DEVICE_CONTEXT_IMMEDIATE; -} - -UINT STDMETHODCALLTYPE CCryDX12DeviceContext::GetContextFlags() -{ - DX12_FUNC_LOG - return 0; -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ExecuteCommandList( - [[maybe_unused]] _In_ ID3D11CommandList* pCommandList, - [[maybe_unused]] _In_ BOOL RestoreContextState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::FinishCommandList( - [[maybe_unused]] BOOL RestoreDeferredContextState, - [[maybe_unused]] _Out_opt_ ID3D11CommandList** ppCommandList) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED - return E_FAIL; -} - -#pragma endregion - -#pragma region /* D3D 11.1 specific functions */ - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CopySubresourceRegion1( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_ UINT DstX, - _In_ UINT DstY, - _In_ UINT DstZ, - _In_ ID3D11Resource* pSrcResource, - _In_ UINT SrcSubresource, - _In_opt_ const D3D11_BOX* pSrcBox, - _In_ UINT CopyFlags) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dstDX12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pDstResource); - ICryDX12Resource* srcDX12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pSrcResource); - DX12::Resource& dstResource = dstDX12Resource->GetDX12Resource(); - DX12::Resource& srcResource = srcDX12Resource->GetDX12Resource(); - - // TODO: copy command on the swap chain are special (can't execute on any other queue), make an API for that - const bool bDirect = !m_bInCopyRegion; - - DX12::CommandListPool& rCmdListPool = bDirect ? m_DirectListPool : m_CopyListPool; - DX12::CommandList* pCmdList = bDirect ? m_DirectCommandList : m_CopyCommandList; - - // TODO: move into the command-list function - UINT64 maxFenceValues[CMDQUEUE_NUM]; - switch (CopyFlags) - { - case D3D11_COPY_NO_OVERWRITE: - // If the resource is currently used, the flag lied! - AZ_Assert(!dstResource.IsUsed(rCmdListPool), "Destination resource is in use for non-discard copy!"); - - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, - srcResource.GetFenceValues(CMDTYPE_WRITE), - rCmdListPool.GetFenceID()); - break; - default: - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, DX12::MaxFenceValues( - srcResource.GetFenceValues(CMDTYPE_WRITE), - dstResource.GetFenceValues(CMDTYPE_ANY), - maxFenceValues), - rCmdListPool.GetFenceID()); - - // Block the GPU-thread until the resource is safe to be updated (unlike Map() we stage the copy and don't need to block the CPU) - break; - } - - D3D12_BOX box; - if (pSrcBox) - { - box.top = pSrcBox->top; - box.bottom = pSrcBox->bottom; - box.left = pSrcBox->left; - box.right = pSrcBox->right; - box.front = pSrcBox->front; - box.back = pSrcBox->back; - } - - // TODO: copy from active render-target should be more elegant - if (m_DirectCommandList->IsUsedByOutputViews(srcResource) || - m_DirectCommandList->IsUsedByOutputViews(dstResource)) - { - // Make the render-targets rebind, so the resource-barrier is closed - m_PipelineState[DX12::CommandModeGraphics].m_StateFlags |= EPSPB_OutputResources; - } - - AZ_Assert(dstResource.GetDX12SwapChain() == nullptr, "Can't copy to swap chain buffer"); - pCmdList->CopySubresource(dstResource, DstSubresource, DstX, DstY, DstZ, srcResource, SrcSubresource, pSrcBox ? &box : NULL); - - if constexpr (DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC) - { - if (!bDirect) - { - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - else - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::CopyResource1( - _In_ ID3D11Resource* pDstResource, - _In_ ID3D11Resource* pSrcResource, - _In_ UINT CopyFlags) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - - ICryDX12Resource* dstDX12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pDstResource); - ICryDX12Resource* srcDX12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pSrcResource); - DX12::Resource& dstResource = dstDX12Resource->GetDX12Resource(); - DX12::Resource& srcResource = srcDX12Resource->GetDX12Resource(); - - const bool bDirect = !m_bInCopyRegion; - DX12::CommandListPool& rCmdListPool = bDirect ? m_DirectListPool : m_CopyListPool; - DX12::CommandList* pCmdList = bDirect ? m_DirectCommandList : m_CopyCommandList; - - // TODO: move into the command-list function - UINT64 maxFenceValues[CMDQUEUE_NUM]; - switch (CopyFlags) - { - case D3D11_COPY_NO_OVERWRITE: - // If the resource is currently used, the flag lied! - AZ_Assert(!dstResource.IsUsed(rCmdListPool), "Destination resource is in use for non-discard copy!"); - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, - srcResource.GetFenceValues(CMDTYPE_WRITE), - rCmdListPool.GetFenceID()); - break; - default: - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, DX12::MaxFenceValues( - srcResource.GetFenceValues(CMDTYPE_WRITE), - dstResource.GetFenceValues(CMDTYPE_ANY), - maxFenceValues), - rCmdListPool.GetFenceID()); - - // Block the GPU-thread until the resource is safe to be updated (unlike Map() we stage the update and don't need to block the CPU) - break; - } - - // TODO: copy from active render-target should be more elegant - if (m_DirectCommandList->IsUsedByOutputViews(srcResource) || - m_DirectCommandList->IsUsedByOutputViews(dstResource)) - { - // Make the render-targets rebind, so the resource-barrier is closed - m_PipelineState[DX12::CommandModeGraphics].m_StateFlags |= EPSPB_OutputResources; - } - - AZ_Assert(dstResource.GetDX12SwapChain() == nullptr, "Can't copy to swap chain buffer"); - pCmdList->CopyResource(dstResource, srcResource); - if constexpr (DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC) - { - if (!bDirect) - { - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - else - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::UpdateSubresource1( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_opt_ const D3D11_BOX* pDstBox, - _In_ const void* pSrcData, - _In_ UINT SrcRowPitch, - _In_ UINT SrcDepthPitch, - _In_ UINT CopyFlags) -{ - DX12_FUNC_LOG - AZ_TRACE_METHOD(); - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pDstResource); - DX12::Resource& resource = dx12Resource->GetDX12Resource(); - - // TODO: copy command on the swap chain are special (can't execute on any other queue), make an API for that - const bool bDirect = !m_bInCopyRegion; - - DX12::CommandListPool& rCmdListPool = bDirect ? m_DirectListPool : m_CopyListPool; - DX12::CommandList* pCmdList = bDirect ? m_DirectCommandList : m_CopyCommandList; - - // TODO: move into the command-list function - switch (CopyFlags) - { - case D3D11_COPY_NO_OVERWRITE: - // If the resource is currently used, the flag lied! - AZ_Assert(!resource.IsUsed(rCmdListPool), "Destination resource is in use for non-discard copy!"); - break; - default: - SubmitAllCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, resource.GetFenceValues(CMDTYPE_ANY), rCmdListPool.GetFenceID()); - - // Block the GPU-thread until the resource is safe to be updated (unlike Map() we stage the update and don't need to block the CPU) - break; - } - - D3D12_BOX box; - if (pDstBox) - { - box.top = pDstBox->top; - box.bottom = pDstBox->bottom; - box.left = pDstBox->left; - box.right = pDstBox->right; - box.front = pDstBox->front; - box.back = pDstBox->back; - } - - // TODO: copy from active render-target should be more elegant - if (m_DirectCommandList->IsUsedByOutputViews(resource)) - { - // Make the render-targets rebind, so the resource-barrier is closed - m_PipelineState[DX12::CommandModeGraphics].m_StateFlags |= EPSPB_OutputResources; - } - - AZ_Assert(resource.GetDX12SwapChain() == nullptr, "Can't copy to swap chain buffer"); - pCmdList->UpdateSubresourceRegion(resource, DstSubresource, pDstBox ? &box : NULL, pSrcData, SrcRowPitch, SrcDepthPitch); - - if constexpr (DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC) - { - if (!bDirect) - { - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - else - { - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); - } - } -} - -void CCryDX12DeviceContext::DiscardResource(ID3D11Resource* pResource) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pResource); - DX12::Resource& resource = dx12Resource->GetDX12Resource(); - - // Ensure the command-list using the resource is executed - SubmitDirectCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC, - resource.GetFenceValue(CMDQUEUE_GRAPHICS, CMDTYPE_ANY) - ); - - m_CopyCommandList->DiscardResource(resource, nullptr); - SubmitCopyCommands(DX12_SUBMISSION_MODE == DX12_SUBMISSION_SYNC); -} - -void CCryDX12DeviceContext::DiscardView([[maybe_unused]] ID3D11View* pResourceView) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::VSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Vertex, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeGraphics); -} - -void CCryDX12DeviceContext::HSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Hull, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeGraphics); -} - -void CCryDX12DeviceContext::DSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Domain, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeGraphics); -} - -void CCryDX12DeviceContext::GSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Geometry, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeGraphics); -} - -void CCryDX12DeviceContext::PSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Pixel, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeGraphics); -} - -void CCryDX12DeviceContext::CSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) -{ - DX12_FUNC_LOG - SetConstantBuffers1(DX12::ESS_Compute, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants, DX12::CommandModeCompute); -} - -void CCryDX12DeviceContext::SetConstantBuffers1( - DX12::EShaderStage shaderStage, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants, - DX12::CommandMode commandMode) -{ - auto& stage = m_PipelineState[commandMode].Stages[shaderStage]; - for (UINT i = StartSlot, S = StartSlot + NumBuffers, j = 0; i < S; ++i, ++ppConstantBuffers, ++j) - { - CCryDX12Buffer* cb = reinterpret_cast(*ppConstantBuffers); - - TRange < UINT > bindRange; - if (pFirstConstant) - { - bindRange.start = pFirstConstant[j] * DX12::CONSTANT_BUFFER_ELEMENT_SIZE; - bindRange.end = bindRange.start + pNumConstants[j] * DX12::CONSTANT_BUFFER_ELEMENT_SIZE; - } - - stage.ConstBufferBindRange.Set(i, bindRange); - if (stage.ConstantBufferViews.Set(i, cb) && cb) - { - cb->BeginResourceStateTransition(m_DirectCommandList, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER); - } - } -} - -void CCryDX12DeviceContext::VSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::HSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::DSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::GSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::PSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::CSGetConstantBuffers1([[maybe_unused]] UINT StartSlot, [[maybe_unused]] UINT NumBuffers, [[maybe_unused]] ID3D11Buffer** ppConstantBuffers, [[maybe_unused]] UINT* pFirstConstant, [[maybe_unused]] UINT* pNumConstants) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::SwapDeviceContextState([[maybe_unused]] ID3DDeviceContextState* pState, [[maybe_unused]] ID3DDeviceContextState** ppPreviousState) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void CCryDX12DeviceContext::ClearView(ID3D11View* pView, const FLOAT Color[4], const D3D11_RECT* pRect, UINT NumRects) -{ - DX12_FUNC_LOG - DX12_LOG("Clearing view: %p", pView); - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pView); - - m_DirectCommandList->ClearView(*view, Color, NumRects, pRect); -} - -void CCryDX12DeviceContext::DiscardView1([[maybe_unused]] ID3D11View* pResourceView, [[maybe_unused]] const D3D11_RECT* pRects, [[maybe_unused]] UINT NumRects) -{ - DX12_FUNC_LOG - DX12_NOT_IMPLEMENTED -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearRectsRenderTargetView( - _In_ ID3D11RenderTargetView* pRenderTargetView, - _In_ const FLOAT ColorRGBA[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pRenderTargetView); -#ifndef NDEBUG - CCryDX12RenderTargetView* rtv = reinterpret_cast(pRenderTargetView); - DX12_LOG("Clearing render target view: %p %s", pRenderTargetView, rtv->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearRenderTargetView(*view, ColorRGBA, NumRects, pRects); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearRectsUnorderedAccessViewUint( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const UINT Values[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pUnorderedAccessView); -#ifndef NDEBUG - CCryDX12UnorderedAccessView* uav = reinterpret_cast(pUnorderedAccessView); - DX12_LOG("Clearing unordered access view [int]: %p %s", pUnorderedAccessView, uav->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearUnorderedAccessView(*view, Values, NumRects, pRects); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearRectsUnorderedAccessViewFloat( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const FLOAT Values[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pUnorderedAccessView); -#ifndef NDEBUG - CCryDX12UnorderedAccessView* uav = reinterpret_cast(pUnorderedAccessView); - DX12_LOG("Clearing unordered access view [float]: %p %s", pUnorderedAccessView, uav->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearUnorderedAccessView(*view, Values, NumRects, pRects); -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::ClearRectsDepthStencilView( - _In_ ID3D11DepthStencilView* pDepthStencilView, - _In_ UINT ClearFlags, // DX11 and DX12 clear flags are identical - _In_ FLOAT Depth, - _In_ UINT8 Stencil, - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT* pRects) -{ - DX12_FUNC_LOG - - DX12::ResourceView* view = DX12_EXTRACT_DX12VIEW(pDepthStencilView); -#ifndef NDEBUG - CCryDX12DepthStencilView* dsv = reinterpret_cast(pDepthStencilView); - DX12_LOG("Clearing depth stencil view: %p %s", pDepthStencilView, dsv->GetResourceName().c_str()); -#endif - - m_DirectCommandList->ClearDepthStencilView(*view, D3D12_CLEAR_FLAGS(ClearFlags), Depth, Stencil, NumRects, pRects); -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::CopyStagingResource( - _In_ ID3D11Resource* pStagingResource, - _In_ ID3D11Resource* pSourceResource, - _In_ UINT SubResource, - _In_ BOOL Upload) -{ - DX12_FUNC_LOG - - if (Upload) - { - CopySubresourceRegion1(pSourceResource, SubResource, 0, 0, 0, pStagingResource, 0, nullptr, D3D11_COPY_NO_OVERWRITE); - } - else - { - CopySubresourceRegion1(pStagingResource, 0, 0, 0, 0, pSourceResource, SubResource, nullptr, D3D11_COPY_NO_OVERWRITE); - } - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::MapStagingResource( - _In_ ID3D11Resource* pTextureResource, - _In_ ID3D11Resource* pStagingResource, - _In_ UINT SubResource, - _In_ BOOL Upload, - _Out_ void** ppStagingMemory, - _Out_ uint32* pRowPitch) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pStagingResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - - ICryDX12Resource* dx12TextureResource = DX12_EXTRACT_ICRYDX12RESOURCE(pTextureResource); - DX12::Resource& rTextureResource = dx12TextureResource->GetDX12Resource(); - - // If this assert trips, you may need to increase MAX_SUBRESOURCES. Just be wary of growing the stack too much. - AZ_Assert(SubResource < MAX_SUBRESOURCES, "Too many sub resources: (sub ID %d requested, %d allowed)", SubResource, MAX_SUBRESOURCES); - D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[MAX_SUBRESOURCES]; - - // From our source texture resource, get the offset and description information for all the subresources up through the one we're trying - // to map. Our staging resource will contain a buffer large enough for *all* the subresources, so we need to get the correct offset - // into this buffer. If we just get the Layout for the one SubResource, it will come back with an offset of 0, which is incorrect. - GetDevice()->GetD3D12Device()->GetCopyableFootprints(&rTextureResource.GetDesc(), 0, SubResource + 1, 0, layouts, nullptr, nullptr, nullptr); - - const D3D12_RANGE sNoRead = { 0, 0 }; // It is valid to specify the CPU won't read any data by passing a range where End is less than or equal to Begin - const D3D12_RANGE sFullRead = { 0, rResource.GetRequiredUploadSize(0, 1) }; // Our buffer only has 1 subresource, so get the full size of it to map. - - HRESULT result = rResource.GetD3D12Resource()->Map(0, Upload ? &sNoRead : &sFullRead, ppStagingMemory); - - // Map() will return a pointer to the start of our buffer. Adjust the pointer to the offset of the desired mapped subresource within the buffer. - *ppStagingMemory = *reinterpret_cast(ppStagingMemory) + layouts[SubResource].Offset; - - *pRowPitch = layouts[SubResource].Footprint.RowPitch; - - return result; -} - -void STDMETHODCALLTYPE CCryDX12DeviceContext::UnmapStagingResource( - _In_ ID3D11Resource* pStagingResource, - _In_ BOOL Upload) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pStagingResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - - const D3D12_RANGE sNoWrite = { 0, 0 }; // It is valid to specify the CPU didn't write any data by passing a range where End is less than or equal to Begin. - const D3D12_RANGE sFullWrite = { 0, rResource.GetRequiredUploadSize(0, 1) }; - - rResource.GetD3D12Resource()->Unmap(0, Upload ? &sFullWrite : &sNoWrite); -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::TestStagingResource( - _In_ ID3D11Resource* pStagingResource) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pStagingResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - - return - TestForFence(rResource.GetFenceValue(CMDQUEUE_GRAPHICS, CMDTYPE_ANY)) && - TestForFence(rResource.GetFenceValue(CMDQUEUE_COPY, CMDTYPE_ANY)); -} - -HRESULT STDMETHODCALLTYPE CCryDX12DeviceContext::WaitStagingResource( - _In_ ID3D11Resource* pStagingResource) -{ - DX12_FUNC_LOG - - ICryDX12Resource* dx12Resource = DX12_EXTRACT_ICRYDX12RESOURCE(pStagingResource); - DX12::Resource& rResource = dx12Resource->GetDX12Resource(); - - if (rResource.GetFenceValue(CMDQUEUE_GRAPHICS, CMDTYPE_WRITE) == m_DirectListPool.GetCurrentFenceValue()) - { - SubmitDirectCommands(false); - } - - if (rResource.GetFenceValue(CMDQUEUE_COPY, CMDTYPE_WRITE) == m_CopyListPool.GetCurrentFenceValue()) - { - SubmitCopyCommands(false); - } - - rResource.WaitForUnused(m_DirectListPool, CMDTYPE_ANY); - rResource.WaitForUnused(m_CopyListPool, CMDTYPE_ANY); - - return S_OK; -} - -void CCryDX12DeviceContext::ResetCachedState() -{ - m_PipelineState[DX12::CommandModeGraphics].Invalidate(); - m_PipelineState[DX12::CommandModeCompute].Invalidate(); - - m_CurrentPSO = nullptr; - m_CurrentRootSignature[DX12::CommandModeGraphics] = m_CurrentRootSignature[DX12::CommandModeCompute] = nullptr; -} - -#pragma endregion diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.hpp deleted file mode 100644 index d58a577f25..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Device/CCryDX12DeviceContext.hpp +++ /dev/null @@ -1,899 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __CCRYDX12DEVICECONTEXT__ -#define __CCRYDX12DEVICECONTEXT__ - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define CCRYDX12DEVICECONTEXT_HPP_SECTION_1 1 - #define CCRYDX12DEVICECONTEXT_HPP_SECTION_2 2 -#endif - -#include "DX12/CCryDX12Object.hpp" -#include "DX12/Misc/SCryDX11PipelineState.hpp" - -#include "DX12/API/DX12Base.hpp" -#include "DX12/API/DX12CommandList.hpp" - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CCRYDX12DEVICECONTEXT_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(CCryDX12DeviceContext_hpp) -#endif - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - using ICCryDX12DeviceContext = ID3D11DeviceContext1; -#endif - -class CCryDX12Device; - -class CCryDX12DeviceContext - : public CCryDX12Object -{ - friend class CDeviceManager; - friend class CDeviceObjectFactory; - -public: - DX12_OBJECT(CCryDX12DeviceContext, CCryDX12Object); - - static CCryDX12DeviceContext* Create(CCryDX12Device* pDevice); - - CCryDX12DeviceContext(CCryDX12Device* pDevice); - - virtual ~CCryDX12DeviceContext(); - - ILINE void CeaseCoreCommandList(uint32 nPoolId) - { - if (nPoolId == CMDQUEUE_GRAPHICS) - { - CeaseDirectCommandQueue(false); - } - else if (nPoolId == CMDQUEUE_COPY) - { - CeaseCopyCommandQueue(false); - } - } - - ILINE void ResumeCoreCommandList(uint32 nPoolId) - { - if (nPoolId == CMDQUEUE_GRAPHICS) - { - ResumeDirectCommandQueue(); - } - else if (nPoolId == CMDQUEUE_COPY) - { - ResumeCopyCommandQueue(); - } - } - - ILINE DX12::CommandListPool& GetCoreCommandListPool(int nPoolId) - { - if (nPoolId == CMDQUEUE_GRAPHICS) - { - return m_DirectListPool; - } - else if (nPoolId == CMDQUEUE_COPY) - { - return m_CopyListPool; - } - - __debugbreak(); - abort(); - } - - ILINE DX12::CommandListPool& GetCoreGraphicsCommandListPool() - { - return m_DirectListPool; - } - - ILINE DX12::CommandList* GetCoreGraphicsCommandList() const - { - return m_DirectCommandList; - } - - ILINE CCryDX12Device* GetDevice() const - { - return m_pDevice; - } - - ILINE ID3D12Device* GetD3D12Device() const - { - return m_pDevice->GetD3D12Device(); - } - - void Finish(DX12::SwapChain* pDX12SwapChain); - - #pragma region /* ID3D11DeviceChild implementation */ - - virtual void STDMETHODCALLTYPE GetDevice( - _Out_ ID3D11Device** ppDevice) final; - - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - _In_ REFGUID guid, - _Inout_ UINT* pDataSize, - _Out_writes_bytes_opt_(*pDataSize) void* pData) final; - - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - _In_ REFGUID guid, - _In_ UINT DataSize, - _In_reads_bytes_opt_(DataSize) const void* pData) final; - - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - _In_ REFGUID guid, - _In_opt_ const IUnknown* pData) final; - - #pragma endregion - - #pragma region /* ID3D11DeviceContext implementation */ - - virtual void STDMETHODCALLTYPE VSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE PSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE PSSetShader( - _In_opt_ ID3D11PixelShader * pPixelShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE PSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE VSSetShader( - _In_opt_ ID3D11VertexShader * pVertexShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE DrawIndexed( - _In_ UINT IndexCount, - _In_ UINT StartIndexLocation, - _In_ INT BaseVertexLocation) final; - - virtual void STDMETHODCALLTYPE Draw( - _In_ UINT VertexCount, - _In_ UINT StartVertexLocation) final; - - virtual HRESULT STDMETHODCALLTYPE Map( - _In_ ID3D11Resource* pResource, - _In_ UINT Subresource, - _In_ D3D11_MAP MapType, - _In_ UINT MapFlags, - _Out_ D3D11_MAPPED_SUBRESOURCE* pMappedResource) final; - - virtual void STDMETHODCALLTYPE Unmap( - _In_ ID3D11Resource* pResource, - _In_ UINT Subresource) final; - - virtual void STDMETHODCALLTYPE PSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE IASetInputLayout( - _In_opt_ ID3D11InputLayout* pInputLayout) final; - - virtual void STDMETHODCALLTYPE IASetVertexBuffers( - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppVertexBuffers, - _In_reads_opt_(NumBuffers) const UINT * pStrides, - _In_reads_opt_(NumBuffers) const UINT * pOffsets) final; - - virtual void STDMETHODCALLTYPE IASetIndexBuffer( - _In_opt_ ID3D11Buffer* pIndexBuffer, - _In_ DXGI_FORMAT Format, - _In_ UINT Offset) final; - - virtual void STDMETHODCALLTYPE DrawIndexedInstanced( - _In_ UINT IndexCountPerInstance, - _In_ UINT InstanceCount, - _In_ UINT StartIndexLocation, - _In_ INT BaseVertexLocation, - _In_ UINT StartInstanceLocation) final; - - virtual void STDMETHODCALLTYPE DrawInstanced( - _In_ UINT VertexCountPerInstance, - _In_ UINT InstanceCount, - _In_ UINT StartVertexLocation, - _In_ UINT StartInstanceLocation) final; - - virtual void STDMETHODCALLTYPE GSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE GSSetShader( - _In_opt_ ID3D11GeometryShader * pShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE IASetPrimitiveTopology( - _In_ D3D11_PRIMITIVE_TOPOLOGY Topology) final; - - virtual void STDMETHODCALLTYPE VSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE VSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE Begin( - _In_ ID3D11Asynchronous* pAsync) final; - - virtual void STDMETHODCALLTYPE End( - _In_ ID3D11Asynchronous* pAsync) final; - - virtual HRESULT STDMETHODCALLTYPE GetData( - _In_ ID3D11Asynchronous * pAsync, - _Out_writes_bytes_opt_(DataSize) void* pData, - _In_ UINT DataSize, - _In_ UINT GetDataFlags) final; - - virtual void STDMETHODCALLTYPE SetPredication( - _In_opt_ ID3D11Predicate* pPredicate, - _In_ BOOL PredicateValue) final; - - virtual void STDMETHODCALLTYPE GSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE GSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE OMSetRenderTargets( - _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11RenderTargetView * const* ppRenderTargetViews, - _In_opt_ ID3D11DepthStencilView * pDepthStencilView) final; - - virtual void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( - _In_ UINT NumRTVs, - _In_reads_opt_(NumRTVs) ID3D11RenderTargetView * const* ppRenderTargetViews, - _In_opt_ ID3D11DepthStencilView * pDepthStencilView, - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - 1) UINT UAVStartSlot, - _In_ UINT NumUAVs, - _In_reads_opt_(NumUAVs) ID3D11UnorderedAccessView * const* ppUnorderedAccessViews, - _In_reads_opt_(NumUAVs) const UINT * pUAVInitialCounts) final; - - virtual void STDMETHODCALLTYPE OMSetBlendState( - _In_opt_ ID3D11BlendState* pBlendState, - _In_opt_ const FLOAT BlendFactor[4], - _In_ UINT SampleMask) final; - - virtual void STDMETHODCALLTYPE OMSetDepthStencilState( - _In_opt_ ID3D11DepthStencilState* pDepthStencilState, - _In_ UINT StencilRef) final; - - virtual void STDMETHODCALLTYPE SOSetTargets( - _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppSOTargets, - _In_reads_opt_(NumBuffers) const UINT * pOffsets) final; - - virtual void STDMETHODCALLTYPE DrawAuto() final; - - virtual void STDMETHODCALLTYPE DrawIndexedInstancedIndirect( - _In_ ID3D11Buffer* pBufferForArgs, - _In_ UINT AlignedByteOffsetForArgs) final; - - virtual void STDMETHODCALLTYPE DrawInstancedIndirect( - _In_ ID3D11Buffer* pBufferForArgs, - _In_ UINT AlignedByteOffsetForArgs) final; - - virtual void STDMETHODCALLTYPE Dispatch( - _In_ UINT ThreadGroupCountX, - _In_ UINT ThreadGroupCountY, - _In_ UINT ThreadGroupCountZ) final; - - virtual void STDMETHODCALLTYPE DispatchIndirect( - _In_ ID3D11Buffer* pBufferForArgs, - _In_ UINT AlignedByteOffsetForArgs) final; - - virtual void STDMETHODCALLTYPE RSSetState( - _In_opt_ ID3D11RasterizerState* pRasterizerState) final; - - virtual void STDMETHODCALLTYPE RSSetViewports( - _In_range_(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumViewports, - _In_reads_opt_(NumViewports) const D3D11_VIEWPORT * pViewports) final; - - virtual void STDMETHODCALLTYPE RSSetScissorRects( - _In_range_(0, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE) UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT * pRects) final; - - virtual void STDMETHODCALLTYPE CopySubresourceRegion( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_ UINT DstX, - _In_ UINT DstY, - _In_ UINT DstZ, - _In_ ID3D11Resource* pSrcResource, - _In_ UINT SrcSubresource, - _In_opt_ const D3D11_BOX* pSrcBox) final; - - virtual void STDMETHODCALLTYPE CopyResource( - _In_ ID3D11Resource* pDstResource, - _In_ ID3D11Resource* pSrcResource) final; - - virtual void STDMETHODCALLTYPE UpdateSubresource( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_opt_ const D3D11_BOX* pDstBox, - _In_ const void* pSrcData, - _In_ UINT SrcRowPitch, - _In_ UINT SrcDepthPitch) final; - - virtual void STDMETHODCALLTYPE CopyStructureCount( - _In_ ID3D11Buffer* pDstBuffer, - _In_ UINT DstAlignedByteOffset, - _In_ ID3D11UnorderedAccessView* pSrcView) final; - - virtual void STDMETHODCALLTYPE ClearRenderTargetView( - _In_ ID3D11RenderTargetView* pRenderTargetView, - _In_ const FLOAT ColorRGBA[4]) final; - - virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewUint( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const UINT Values[4]) final; - - virtual void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat( - _In_ ID3D11UnorderedAccessView* pUnorderedAccessView, - _In_ const FLOAT Values[4]) final; - - virtual void STDMETHODCALLTYPE ClearDepthStencilView( - _In_ ID3D11DepthStencilView* pDepthStencilView, - _In_ UINT ClearFlags, - _In_ FLOAT Depth, - _In_ UINT8 Stencil) final; - - virtual void STDMETHODCALLTYPE GenerateMips( - _In_ ID3D11ShaderResourceView* pShaderResourceView) final; - - virtual void STDMETHODCALLTYPE SetResourceMinLOD( - _In_ ID3D11Resource* pResource, - FLOAT MinLOD) final; - - virtual FLOAT STDMETHODCALLTYPE GetResourceMinLOD( - _In_ ID3D11Resource* pResource) final; - - virtual void STDMETHODCALLTYPE ResolveSubresource( - _In_ ID3D11Resource* pDstResource, - _In_ UINT DstSubresource, - _In_ ID3D11Resource* pSrcResource, - _In_ UINT SrcSubresource, - _In_ DXGI_FORMAT Format) final; - - virtual void STDMETHODCALLTYPE HSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE HSSetShader( - _In_opt_ ID3D11HullShader * pHullShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE HSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE HSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE DSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE DSSetShader( - _In_opt_ ID3D11DomainShader * pDomainShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE DSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE DSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE CSSetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _In_reads_opt_(NumViews) ID3D11ShaderResourceView * const* ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE CSSetUnorderedAccessViews( - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_1_UAV_SLOT_COUNT - StartSlot) UINT NumUAVs, - _In_reads_opt_(NumUAVs) ID3D11UnorderedAccessView * const* ppUnorderedAccessViews, - _In_reads_opt_(NumUAVs) const UINT * pUAVInitialCounts) final; - - virtual void STDMETHODCALLTYPE CSSetShader( - _In_opt_ ID3D11ComputeShader * pComputeShader, - _In_reads_opt_(NumClassInstances) ID3D11ClassInstance * const* ppClassInstances, - UINT NumClassInstances) final; - - virtual void STDMETHODCALLTYPE CSSetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _In_reads_opt_(NumSamplers) ID3D11SamplerState * const* ppSamplers) final; - - virtual void STDMETHODCALLTYPE CSSetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _In_reads_opt_(NumBuffers) ID3D11Buffer * const* ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE VSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE PSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE PSGetShader( - _Out_ ID3D11PixelShader** ppPixelShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE PSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE VSGetShader( - _Out_ ID3D11VertexShader** ppVertexShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE PSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE IAGetInputLayout( - _Out_ ID3D11InputLayout** ppInputLayout) final; - - virtual void STDMETHODCALLTYPE IAGetVertexBuffers( - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppVertexBuffers, - _Out_writes_opt_(NumBuffers) UINT * pStrides, - _Out_writes_opt_(NumBuffers) UINT * pOffsets) final; - - virtual void STDMETHODCALLTYPE IAGetIndexBuffer( - _Out_opt_ ID3D11Buffer** pIndexBuffer, - _Out_opt_ DXGI_FORMAT* Format, - _Out_opt_ UINT* Offset) final; - - virtual void STDMETHODCALLTYPE GSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE GSGetShader( - _Out_ ID3D11GeometryShader** ppGeometryShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE IAGetPrimitiveTopology( - _Out_ D3D11_PRIMITIVE_TOPOLOGY* pTopology) final; - - virtual void STDMETHODCALLTYPE VSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE VSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE GetPredication( - _Out_opt_ ID3D11Predicate** ppPredicate, - _Out_opt_ BOOL* pPredicateValue) final; - - virtual void STDMETHODCALLTYPE GSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE GSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE OMGetRenderTargets( - _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11RenderTargetView * *ppRenderTargetViews, - _Out_opt_ ID3D11DepthStencilView * *ppDepthStencilView) final; - - virtual void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( - _In_range_(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT) UINT NumRTVs, - _Out_writes_opt_(NumRTVs) ID3D11RenderTargetView * *ppRenderTargetViews, - _Out_opt_ ID3D11DepthStencilView * *ppDepthStencilView, - _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1) UINT UAVStartSlot, - _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - UAVStartSlot) UINT NumUAVs, - _Out_writes_opt_(NumUAVs) ID3D11UnorderedAccessView * *ppUnorderedAccessViews) final; - - virtual void STDMETHODCALLTYPE OMGetBlendState( - _Out_opt_ ID3D11BlendState * *ppBlendState, - _Out_opt_ FLOAT BlendFactor[4], - _Out_opt_ UINT * pSampleMask) final; - - virtual void STDMETHODCALLTYPE OMGetDepthStencilState( - _Out_opt_ ID3D11DepthStencilState** ppDepthStencilState, - _Out_opt_ UINT* pStencilRef) final; - - virtual void STDMETHODCALLTYPE SOGetTargets( - _In_range_(0, D3D11_SO_BUFFER_SLOT_COUNT) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppSOTargets) final; - - virtual void STDMETHODCALLTYPE RSGetState( - _Out_ ID3D11RasterizerState** ppRasterizerState) final; - - virtual void STDMETHODCALLTYPE RSGetViewports( - _Inout_ UINT* pNumViewports, - _Out_writes_opt_(*pNumViewports) D3D11_VIEWPORT* pViewports) final; - - virtual void STDMETHODCALLTYPE RSGetScissorRects( - _Inout_ UINT* pNumRects, - _Out_writes_opt_(*pNumRects) D3D11_RECT* pRects) final; - - virtual void STDMETHODCALLTYPE HSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE HSGetShader( - _Out_ ID3D11HullShader** ppHullShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE HSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE HSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE DSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE DSGetShader( - _Out_ ID3D11DomainShader** ppDomainShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE DSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE DSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE CSGetShaderResources( - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT - StartSlot) UINT NumViews, - _Out_writes_opt_(NumViews) ID3D11ShaderResourceView * *ppShaderResourceViews) final; - - virtual void STDMETHODCALLTYPE CSGetUnorderedAccessViews( - _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_PS_CS_UAV_REGISTER_COUNT - StartSlot) UINT NumUAVs, - _Out_writes_opt_(NumUAVs) ID3D11UnorderedAccessView * *ppUnorderedAccessViews) final; - - virtual void STDMETHODCALLTYPE CSGetShader( - _Out_ ID3D11ComputeShader** ppComputeShader, - _Out_writes_opt_(*pNumClassInstances) ID3D11ClassInstance** ppClassInstances, - _Inout_opt_ UINT* pNumClassInstances) final; - - virtual void STDMETHODCALLTYPE CSGetSamplers( - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT - StartSlot) UINT NumSamplers, - _Out_writes_opt_(NumSamplers) ID3D11SamplerState * *ppSamplers) final; - - virtual void STDMETHODCALLTYPE CSGetConstantBuffers( - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) UINT StartSlot, - _In_range_(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - StartSlot) UINT NumBuffers, - _Out_writes_opt_(NumBuffers) ID3D11Buffer * *ppConstantBuffers) final; - - virtual void STDMETHODCALLTYPE ClearState() final; - - virtual void STDMETHODCALLTYPE Flush() final; - - virtual D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType() final; - - virtual UINT STDMETHODCALLTYPE GetContextFlags() final; - - virtual void STDMETHODCALLTYPE ExecuteCommandList( - _In_ ID3D11CommandList* pCommandList, - BOOL RestoreContextState) final; - - virtual HRESULT STDMETHODCALLTYPE FinishCommandList( - _In_ BOOL RestoreDeferredContextState, - _Out_opt_ ID3D11CommandList** ppCommandList) final; - - #pragma endregion - - #pragma region /* D3D 11.1 specific functions */ - - virtual void STDMETHODCALLTYPE CopySubresourceRegion1(ID3D11Resource* pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, ID3D11Resource* pSrcResource, UINT SrcSubresource, const D3D11_BOX* pSrcBox, UINT CopyFlags) final; - virtual void STDMETHODCALLTYPE CopyResource1(ID3D11Resource* pDstResource, ID3D11Resource* pSrcResource, UINT CopyFlags) final; - virtual void STDMETHODCALLTYPE UpdateSubresource1(ID3D11Resource* pDstResource, UINT DstSubresource, const D3D11_BOX* pDstBox, const void* pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch, UINT CopyFlags) final; - virtual void STDMETHODCALLTYPE DiscardResource(ID3D11Resource* pResource) final; - virtual void STDMETHODCALLTYPE DiscardView(ID3D11View* pResourceView) final; - - virtual void STDMETHODCALLTYPE VSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE HSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE DSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE GSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE PSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE CSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) final; - - virtual void STDMETHODCALLTYPE VSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE HSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE DSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE GSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE PSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - virtual void STDMETHODCALLTYPE CSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) final; - - virtual void STDMETHODCALLTYPE SwapDeviceContextState(ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState) final; - virtual void STDMETHODCALLTYPE ClearView(ID3D11View* pView, const FLOAT Color[4], const D3D11_RECT* pRect, UINT NumRects) final; - virtual void STDMETHODCALLTYPE DiscardView1(ID3D11View* pResourceView, const D3D11_RECT* pRects, UINT NumRects) final; - - #pragma endregion - - virtual void STDMETHODCALLTYPE ClearRectsRenderTargetView( - _In_ ID3D11RenderTargetView * pRenderTargetView, - _In_ const FLOAT ColorRGBA[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT * pRects); - - virtual void STDMETHODCALLTYPE ClearRectsUnorderedAccessViewUint( - _In_ ID3D11UnorderedAccessView * pUnorderedAccessView, - _In_ const UINT Values[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT * pRects); - - virtual void STDMETHODCALLTYPE ClearRectsUnorderedAccessViewFloat( - _In_ ID3D11UnorderedAccessView * pUnorderedAccessView, - _In_ const FLOAT Values[4], - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT * pRects); - - virtual void STDMETHODCALLTYPE ClearRectsDepthStencilView( - _In_ ID3D11DepthStencilView * pDepthStencilView, - _In_ UINT ClearFlags, - _In_ FLOAT Depth, - _In_ UINT8 Stencil, - _In_ UINT NumRects, - _In_reads_opt_(NumRects) const D3D11_RECT * pRects); - - HRESULT STDMETHODCALLTYPE CopyStagingResource( - _In_ ID3D11Resource* pStagingResource, - _In_ ID3D11Resource* pSourceResource, - _In_ UINT SubResource, - _In_ BOOL Upload); - - HRESULT STDMETHODCALLTYPE TestStagingResource( - _In_ ID3D11Resource* pStagingResource); - - HRESULT STDMETHODCALLTYPE WaitStagingResource( - _In_ ID3D11Resource* pStagingResource); - - HRESULT STDMETHODCALLTYPE MapStagingResource( - _In_ ID3D11Resource* pTextureResource, - _In_ ID3D11Resource* pStagingResource, - _In_ UINT SubResource, - _In_ BOOL Upload, - _Out_ void** ppStagingMemory, - _Out_ uint32* pRowPitch); - - void STDMETHODCALLTYPE UnmapStagingResource( - _In_ ID3D11Resource* pStagingResource, - _In_ BOOL Upload); - - void STDMETHODCALLTYPE UploadResource( - _In_ ICryDX12Resource* pDstResource, - _In_ const D3D11_SUBRESOURCE_DATA* pInitialData, - _In_ size_t numInitialData); - - void STDMETHODCALLTYPE UploadResource( - _In_ DX12::Resource* pDstResource, - _In_ const DX12::Resource::InitialData* pSrcData); - - ILINE UINT64 InsertFence() - { - return m_CmdFenceSet.GetCurrentValue(CMDQUEUE_GRAPHICS) - !m_DirectCommandList->IsUtilized(); - } - - ILINE HRESULT FlushToFence(UINT64 fenceValue) - { - m_DirectListPool.GetAsyncCommandQueue().Flush(fenceValue); - return S_OK; - } - - ILINE HRESULT TestForFence(UINT64 fenceValue) - { - return m_CmdFenceSet.IsCompleted(fenceValue, CMDQUEUE_GRAPHICS) ? S_OK : S_FALSE; - } - - ILINE HRESULT WaitForFence(UINT64 fenceValue) - { - m_CmdFenceSet.WaitForFence(fenceValue, CMDQUEUE_GRAPHICS); - return S_OK; - } - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CCRYDX12DEVICECONTEXT_HPP_SECTION_2 - #include AZ_RESTRICTED_FILE(CCryDX12DeviceContext_hpp) -#endif - - void WaitForIdle(); - - void ResetCachedState(); - - void PushMarker(const char* name) - { - ::PIXBeginEvent(m_DirectCommandList->GetD3D12CommandList(), 0, name); - } - - void PopMarker() - { - ::PIXEndEvent(m_DirectCommandList->GetD3D12CommandList()); - } - - UINT64 MakeCpuTimestamp(UINT64 gpuTimestamp) const; - UINT64 MakeCpuTimestampMicroseconds(UINT64 gpuTimestamp) const; - - void BeginCopyRegion() - { - m_bInCopyRegion = true; - } - - void EndCopyRegion() - { - m_bInCopyRegion = false; - } - - void SubmitAllCommands(bool wait); - - UINT TimestampIndex(DX12::CommandList* pCmdList); - ID3D12Resource* QueryTimestamp(DX12::CommandList* pCmdList, UINT index); - void ResolveTimestamp(DX12::CommandList* pCmdList, UINT index, void* mem); - - UINT OcclusionIndex(DX12::CommandList* pCmdList, bool counter); - ID3D12Resource* QueryOcclusion(DX12::CommandList* pCmdList, UINT index, bool counter); - void ResolveOcclusion(DX12::CommandList* pCmdList, UINT index, void* mem); - - // This is a somewhat arbitrary number that affects stack usage for methods that get subresource descriptors. - static constexpr int MAX_SUBRESOURCES = 64; - -private: - bool PreparePSO(DX12::CommandMode commandMode); - void PrepareGraphicsFF(); - - bool PrepareGraphicsState(); - bool PrepareComputeState(); - - void CeaseDirectCommandQueue(bool wait); - void ResumeDirectCommandQueue(); - void CeaseCopyCommandQueue(bool wait); - void ResumeCopyCommandQueue(); - void CeaseAllCommandQueues(bool wait); - void ResumeAllCommandQueues(); - - void SubmitDirectCommands(bool wait); - void SubmitDirectCommands(bool wait, const UINT64 fenceValue); - void SubmitCopyCommands(bool wait); - void SubmitCopyCommands(bool wait, const UINT64 fenceValue); - void SubmitAllCommands(bool wait, const UINT64(&fenceValues)[CMDQUEUE_NUM]); - void SubmitAllCommands(bool wait, const UINT64(&fenceValues)[CMDQUEUE_NUM], int fenceId); - void SubmitAllCommands(bool wait, const std::atomic(&fenceValues)[CMDQUEUE_NUM]); - void SubmitAllCommands(bool wait, const std::atomic(&fenceValues)[CMDQUEUE_NUM], int fenceId); - - void BindResources(DX12::CommandMode commandMode); - void BindOutputViews(); - - void DebugPrintResources(DX12::CommandMode commandMode); - - void SetConstantBuffers1( - DX12::EShaderStage shaderStage, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants, - DX12::CommandMode commandMode); - - bool m_bInCopyRegion; - - CCryDX12Device* m_pDevice; - DX12::Device* m_pDX12Device; - - DX12::CommandListFenceSet m_CmdFenceSet; - - DX12::CommandListPool m_DirectListPool; - DX12::CommandListPool m_CopyListPool; - - DX12::SmartPtr m_DirectCommandList; - DX12::SmartPtr m_CopyCommandList; - - const DX12::PipelineState* m_CurrentPSO; - const DX12::RootSignature* m_CurrentRootSignature[DX12::CommandModeCount]; - SCryDX11PipelineState m_PipelineState[DX12::CommandModeCount]; - - UINT m_OutstandingQueries; - - ID3D12Resource* m_TimestampDownloadBuffer; - ID3D12Resource* m_OcclusionDownloadBuffer; - UINT m_TimestampIndex; - UINT m_OcclusionIndex; - void* m_TimestampMemory; - void* m_OcclusionMemory; - bool m_TimestampMapValid; - bool m_OcclusionMapValid; - DX12::DescriptorHeap* m_pResourceHeap; - DX12::DescriptorHeap* m_pSamplerHeap; - bool m_bCurrentNative; - int m_nResDynOffset; - int m_nFrame; - uint32 m_nStencilRef; - - DX12::QueryHeap m_TimestampHeap; - DX12::QueryHeap m_OcclusionHeap; - DX12::QueryHeap m_PipelineHeap; - -#ifdef DX12_STATS - size_t m_NumMapDiscardSkips; - size_t m_NumMapDiscards; - - size_t m_NumCommandListOverflows; - size_t m_NumCommandListSplits; - size_t m_NumPSOs; - size_t m_NumRootSignatures; - size_t m_NumberSettingOutputViews; -#endif // DX12_STATS -}; - -#endif // __CCRYDX12DEVICECONTEXT__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.cpp deleted file mode 100644 index 9069b43c03..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CCryDX12GIFactory.hpp" -#include "CCryDX12SwapChain.hpp" - -#include "DX12/Device/CCryDX12Device.hpp" -#include "DX12/Device/CCryDX12DeviceContext.hpp" - -#include "DX12/API/DX12SwapChain.hpp" - -CCryDX12GIFactory* CCryDX12GIFactory::Create() -{ - IDXGIFactory1* pDXGIFactory1 = NULL; - - if (S_OK != CreateDXGIFactory1(IID_PPV_ARGS(&pDXGIFactory1))) - { - DX12_ASSERT("Failed to create underlying DXGI factory!"); - return NULL; - } - - return DX12::PassAddRef(new CCryDX12GIFactory(pDXGIFactory1)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CCryDX12GIFactory::CCryDX12GIFactory(IDXGIFactory1* pDXGIFactory1) - : Super() - , m_pDXGIFactory1(pDXGIFactory1) -{ - DX12_FUNC_LOG -} - -CCryDX12GIFactory::~CCryDX12GIFactory() -{ - DX12_FUNC_LOG -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::EnumAdapters(UINT Adapter, _Out_ IDXGIAdapter** ppAdapter) -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->EnumAdapters(Adapter, ppAdapter); -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::MakeWindowAssociation(HWND WindowHandle, UINT Flags) -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->MakeWindowAssociation(WindowHandle, Flags); -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::GetWindowAssociation(_Out_ HWND* pWindowHandle) -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->GetWindowAssociation(pWindowHandle); -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::CreateSwapChain(_In_ IUnknown* pDevice, _In_ DXGI_SWAP_CHAIN_DESC* pDesc, _Out_ IDXGISwapChain** ppSwapChain) -{ - DX12_FUNC_LOG - * ppSwapChain = CCryDX12SwapChain::Create(static_cast(pDevice), m_pDXGIFactory1, pDesc); - return ppSwapChain ? S_OK : E_FAIL; -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::CreateSoftwareAdapter(HMODULE Module, _Out_ IDXGIAdapter** ppAdapter) -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->CreateSoftwareAdapter(Module, ppAdapter); -} - -HRESULT STDMETHODCALLTYPE CCryDX12GIFactory::EnumAdapters1(UINT Adapter, _Out_ IDXGIAdapter1** ppAdapter) -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->EnumAdapters1(Adapter, ppAdapter); -} - -BOOL STDMETHODCALLTYPE CCryDX12GIFactory::IsCurrent() -{ - DX12_FUNC_LOG - return m_pDXGIFactory1->IsCurrent(); -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.hpp deleted file mode 100644 index 3e81400a35..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12GIFactory.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#pragma once -#ifndef __CCRYDX12GIFACTORY__ -#define __CCRYDX12GIFACTORY__ - -#include "DX12/CCryDX12Object.hpp" - -#if defined(AZ_RESTRICTED_PLATFORM) - #undef AZ_RESTRICTED_SECTION - #define CCRYDX12GIFACTORY_HPP_SECTION_1 1 -#endif - -class CCryDX12GIFactory - : public CCryDX12GIObject -{ -public: - DX12_OBJECT(CCryDX12GIFactory, CCryDX12GIObject); - - static CCryDX12GIFactory* Create(); - - virtual ~CCryDX12GIFactory(); - - IDXGIFactory1* GetDXGIFactory() const { return m_pDXGIFactory1; } - - #pragma region /* IDXGIFactory implementation */ - - virtual HRESULT STDMETHODCALLTYPE EnumAdapters( - UINT Adapter, - _Out_ IDXGIAdapter** ppAdapter) final; - - virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( - HWND WindowHandle, - UINT Flags) final; - - virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( - _Out_ HWND* pWindowHandle) final; - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - _In_ IUnknown* pDevice, - _In_ DXGI_SWAP_CHAIN_DESC* pDesc, - _Out_ IDXGISwapChain** ppSwapChain) final; - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CCRYDX12GIFACTORY_HPP_SECTION_1 - #include AZ_RESTRICTED_FILE(CCryDX12GIFactory_hpp) -#endif - - virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( - HMODULE Module, - _Out_ IDXGIAdapter** ppAdapter) final; - - #pragma endregion - - #pragma region /* IDXGIFactory1 implementation */ - - virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( - UINT Adapter, - _Out_ IDXGIAdapter1** ppAdapter) final; - - virtual BOOL STDMETHODCALLTYPE IsCurrent() final; - - #pragma endregion - -protected: - CCryDX12GIFactory(IDXGIFactory1* pDXGIFactory1); - -private: - DX12::SmartPtr m_pDXGIFactory1; -}; - -#endif // __CRYDX12GIFACTORY__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.cpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.cpp deleted file mode 100644 index 671dc9d70e..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#include "RenderDll_precompiled.h" -#include "CCryDX12SwapChain.hpp" - -#include "DX12/Device/CCryDX12Device.hpp" -#include "DX12/Device/CCryDX12DeviceContext.hpp" -#include "DX12/Resource/CCryDX12Resource.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture1D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture2D.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture3D.hpp" - -#include "DX12/API/DX12Device.hpp" -#include "DX12/API/DX12SwapChain.hpp" -#include "DX12/API/DX12Resource.hpp" -#include "Dx12/API/DX12AsyncCommandQueue.hpp" - -#include - -#ifdef WIN32 -#include -#pragma comment(lib, "dwmapi.lib") -#endif - -static const char* s_globalVsyncName = "V-Sync"; -static const char* s_globalEmptyCategory = ""; - -static void RecordVSyncInstantEvent() -{ -#ifdef WIN32 - DWM_TIMING_INFO timingInfo = { sizeof(DWM_TIMING_INFO) }; - HRESULT hr = DwmGetCompositionTimingInfo(NULL, &timingInfo); - if (SUCCEEDED(hr)) - { - UINT64 frequency; - QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); - UINT64 vsyncMicroSeconds = (timingInfo.qpcVBlank * 1000) / (frequency / 1000); - EBUS_QUEUE_EVENT(AZ::Debug::EventTraceDrillerBus, RecordInstantGlobal, s_globalVsyncName, s_globalEmptyCategory, (AZ::u64)vsyncMicroSeconds); - } -#endif -} - - -CCryDX12SwapChain* CCryDX12SwapChain::Create(CCryDX12Device* device, IDXGIFactory1* factory, DXGI_SWAP_CHAIN_DESC* pDesc) -{ - CCryDX12DeviceContext* deviceContext = device->GetDeviceContext(); - DX12::SwapChain* swapChain = DX12::SwapChain::Create(deviceContext->GetCoreGraphicsCommandList(), factory, pDesc); - - return DX12::PassAddRef(new CCryDX12SwapChain(device, swapChain)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CCryDX12SwapChain::CCryDX12SwapChain(CCryDX12Device* device, DX12::SwapChain* swapChain) - : Super() - , m_Device(device) - , m_SwapChain(swapChain) -{ - DX12_FUNC_LOG - AcquireBuffers(); -} - -CCryDX12SwapChain::~CCryDX12SwapChain() -{ - DX12_FUNC_LOG - ForfeitBuffers(); - - SAFE_RELEASE(m_SwapChain); -} - -void CCryDX12SwapChain::AcquireBuffers() -{ - const DXGI_SWAP_CHAIN_DESC& desc = m_SwapChain->GetDesc(); - IDXGISwapChain* swapChain = m_SwapChain->GetDXGISwapChain(); - - AZStd::vector resources; - m_BackBuffers.reserve(desc.BufferCount); - resources.reserve(desc.BufferCount); - - for (int i = 0; i < desc.BufferCount; ++i) - { - ID3D12Resource* resource12 = NULL; - if (S_OK == swapChain->GetBuffer(i, IID_GRAPHICS_PPV_ARGS(&resource12))) - { - m_BackBuffers.emplace_back(); - m_BackBuffers.back().attach(CCryDX12Texture2D::Create(GetDevice(), this, resource12)); - resources.emplace_back(&m_BackBuffers.back()->GetDX12Resource()); - resource12->Release(); - } - } - - m_SwapChain->AcquireBuffers(std::move(resources)); -} - -void CCryDX12SwapChain::ForfeitBuffers() -{ - m_SwapChain->ForfeitBuffers(); - m_BackBuffers.clear(); -} - -/* IDXGIDeviceSubObject implementation */ - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetDevice( - _In_ REFIID riid, - _Out_ void** ppDevice) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetDevice(riid, ppDevice); -} - -/* IDXGISwapChain implementation */ - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::Present( - UINT SyncInterval, - UINT Flags) -{ - AZ_TRACE_METHOD(); - DX12_FUNC_LOG - - m_Device->GetDeviceContext()->Finish(m_SwapChain); - - DX12_LOG("------------------------------------------------ PRESENT ------------------------------------------------"); - HRESULT hr = m_SwapChain->Present(SyncInterval, Flags); - RecordVSyncInstantEvent(); - return hr; -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetBuffer( - UINT Buffer, - _In_ REFIID riid, - _Out_ void** ppSurface) -{ - DX12_FUNC_LOG - if (riid == __uuidof(ID3D11Texture2D)) - { - AZ_Assert(Buffer < m_BackBuffers.size(), "Invalid buffer index"); - CCryDX12Texture2D* texture = m_BackBuffers[Buffer]; - texture->AddRef(); - *ppSurface = texture; - } - else - { - DX12_ASSERT(0, "Not implemented!"); - return -1; - } - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::SetFullscreenState( - BOOL Fullscreen, - _In_opt_ IDXGIOutput* pTarget) -{ - DX12_FUNC_LOG - m_Device->GetDeviceContext()->SubmitAllCommands(true); - return m_SwapChain->GetDXGISwapChain()->SetFullscreenState(Fullscreen, pTarget); -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetFullscreenState( - _Out_opt_ BOOL* pFullscreen, - _Out_opt_ IDXGIOutput** ppTarget) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetFullscreenState(pFullscreen, ppTarget); -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetDesc( - _Out_ DXGI_SWAP_CHAIN_DESC* pDesc) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetDesc(pDesc); -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::ResizeBuffers( - UINT BufferCount, - UINT Width, - UINT Height, - DXGI_FORMAT NewFormat, - UINT SwapChainFlags) -{ - DX12_FUNC_LOG - - ID3D11RenderTargetView* views[8] = {}; - m_Device->GetDeviceContext()->OMSetRenderTargets(8, views, nullptr); - - m_Device->GetDeviceContext()->SubmitAllCommands(true); - - m_Device->GetDeviceContext()->WaitForIdle(); - - ForfeitBuffers(); - - m_Device->GetDX12Device()->FlushReleaseHeap(DX12::Device::ResourceReleasePolicy::Immediate); - - HRESULT res = m_SwapChain->GetDXGISwapChain()->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); - if (res == S_OK) - { - AcquireBuffers(); - } - - return res; -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::ResizeTarget( - _In_ const DXGI_MODE_DESC* pNewTargetParameters) -{ - DX12_FUNC_LOG - - ID3D11RenderTargetView* views[8] = {}; - m_Device->GetDeviceContext()->OMSetRenderTargets(8, views, nullptr); - - m_Device->GetDeviceContext()->SubmitAllCommands(true); - - m_Device->GetDeviceContext()->WaitForIdle(); - - ForfeitBuffers(); - - HRESULT hr = m_SwapChain->GetDXGISwapChain()->ResizeTarget(pNewTargetParameters); - return hr; -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetContainingOutput( - _Out_ IDXGIOutput** ppOutput) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetContainingOutput(ppOutput); -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetFrameStatistics( - _Out_ DXGI_FRAME_STATISTICS* pStats) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetFrameStatistics(pStats); -} - -HRESULT STDMETHODCALLTYPE CCryDX12SwapChain::GetLastPresentCount( - _Out_ UINT* pLastPresentCount) -{ - DX12_FUNC_LOG - return m_SwapChain->GetDXGISwapChain()->GetLastPresentCount(pLastPresentCount); -} - -/* IDXGISwapChain1 implementation */ - -/* IDXGISwapChain2 implementation */ - -/* IDXGISwapChain3 implementation */ - -UINT STDMETHODCALLTYPE CCryDX12SwapChain::GetCurrentBackBufferIndex( - void) -{ - DX12_FUNC_LOG - return m_SwapChain->GetCurrentBackBufferIndex(); -} diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.hpp deleted file mode 100644 index 5b5c0b3290..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/GI/CCryDX12SwapChain.hpp +++ /dev/null @@ -1,308 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#ifndef __CCRYDX12GISWAPCHAIN__ -#define __CCRYDX12GISWAPCHAIN__ - -#include "DX12/CCryDX12Object.hpp" -#include "DX12/Resource/Texture/CCryDX12Texture2D.hpp" - -#include "DX12/API/DX12SwapChain.hpp" - -#include - -class CCryDX12SwapChain - : public CCryDX12GIObject -{ -public: - DX12_OBJECT(CCryDX12SwapChain, CCryDX12GIObject); - - static CCryDX12SwapChain* Create(CCryDX12Device* pDevice, IDXGIFactory1* factory, DXGI_SWAP_CHAIN_DESC* pDesc); - - virtual ~CCryDX12SwapChain(); - - ILINE CCryDX12Device* GetDevice() const - { - return m_Device; - } - - ILINE IDXGISwapChain3* GetDXGISwapChain() const - { - return m_SwapChain->GetDXGISwapChain(); - } - - ILINE DX12::SwapChain* GetDX12SwapChain() - { - return m_SwapChain; - } - - #pragma region /* IDXGIDeviceSubObject implementation */ - - virtual HRESULT STDMETHODCALLTYPE GetDevice( - _In_ REFIID riid, - _Out_ void** ppDevice) final; - - #pragma endregion - - #pragma region /* IDXGISwapChain implementation */ - - virtual HRESULT STDMETHODCALLTYPE Present( - UINT SyncInterval, - UINT Flags) final; - - virtual HRESULT STDMETHODCALLTYPE GetBuffer( - UINT Buffer, - _In_ REFIID riid, - _Out_ void** ppSurface) final; - - virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( - BOOL Fullscreen, - _In_opt_ IDXGIOutput* pTarget) final; - - virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( - _Out_opt_ BOOL* pFullscreen, - _Out_opt_ IDXGIOutput** ppTarget) final; - - virtual HRESULT STDMETHODCALLTYPE GetDesc( - _Out_ DXGI_SWAP_CHAIN_DESC* pDesc) final; - - virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( - UINT BufferCount, - UINT Width, - UINT Height, - DXGI_FORMAT NewFormat, - UINT SwapChainFlags) final; - - virtual HRESULT STDMETHODCALLTYPE ResizeTarget( - _In_ const DXGI_MODE_DESC* pNewTargetParameters) final; - - virtual HRESULT STDMETHODCALLTYPE GetContainingOutput( - _Out_ IDXGIOutput** ppOutput) final; - - virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( - _Out_ DXGI_FRAME_STATISTICS* pStats) final; - - virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( - _Out_ UINT* pLastPresentCount) final; - - #pragma endregion - - #pragma region /* IDXGISwapChain1 implementation */ - - virtual HRESULT STDMETHODCALLTYPE GetDesc1( - /* [annotation][out] */ - [[maybe_unused]] _Out_ DXGI_SWAP_CHAIN_DESC1* pDesc) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetFullscreenDesc( - /* [annotation][out] */ - [[maybe_unused]] _Out_ DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pDesc) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetHwnd( - /* [annotation][out] */ - [[maybe_unused]] _Out_ HWND* pHwnd) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetCoreWindow( - /* [annotation][in] */ - [[maybe_unused]] _In_ REFIID refiid, - /* [annotation][out] */ - [[maybe_unused]] _COM_Outptr_ void** ppUnk) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE Present1( - [[maybe_unused]] /* [in] */ UINT SyncInterval, - [[maybe_unused]] /* [in] */ UINT PresentFlags, - /* [annotation][in] */ - [[maybe_unused]] _In_ const DXGI_PRESENT_PARAMETERS* pPresentParameters) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual BOOL STDMETHODCALLTYPE IsTemporaryMonoSupported() final - { - DX12_NOT_IMPLEMENTED - return FALSE; - } - - virtual HRESULT STDMETHODCALLTYPE GetRestrictToOutput( - /* [annotation][out] */ - [[maybe_unused]] _Out_ IDXGIOutput** ppRestrictToOutput) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor( - /* [annotation][in] */ - [[maybe_unused]] _In_ const DXGI_RGBA* pColor) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor( - /* [annotation][out] */ - [[maybe_unused]] _Out_ DXGI_RGBA* pColor) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE SetRotation( - /* [annotation][in] */ - [[maybe_unused]] _In_ DXGI_MODE_ROTATION Rotation) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetRotation( - /* [annotation][out] */ - [[maybe_unused]] _Out_ DXGI_MODE_ROTATION* pRotation) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - #pragma endregion - - #pragma region /* IDXGISwapChain2 implementation */ - - virtual HRESULT STDMETHODCALLTYPE SetSourceSize( - [[maybe_unused]] UINT Width, - [[maybe_unused]] UINT Height) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetSourceSize( - /* [annotation][out] */ - [[maybe_unused]] _Out_ UINT* pWidth, - /* [annotation][out] */ - [[maybe_unused]] _Out_ UINT* pHeight) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( - UINT MaxLatency) final - { - return m_SwapChain->GetDXGISwapChain()->SetMaximumFrameLatency(MaxLatency); - } - - virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( - /* [annotation][out] */ - [[maybe_unused]] _Out_ UINT* pMaxLatency) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HANDLE STDMETHODCALLTYPE GetFrameLatencyWaitableObject() final - { - return m_SwapChain->GetDXGISwapChain()->GetFrameLatencyWaitableObject(); - } - - virtual HRESULT STDMETHODCALLTYPE SetMatrixTransform( - [[maybe_unused]] const DXGI_MATRIX_3X2_F* pMatrix) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE GetMatrixTransform( - /* [annotation][out] */ - [[maybe_unused]] _Out_ DXGI_MATRIX_3X2_F* pMatrix) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - #pragma endregion - - #pragma region /* IDXGISwapChain3 implementation */ - - virtual UINT STDMETHODCALLTYPE GetCurrentBackBufferIndex() final; - - virtual HRESULT STDMETHODCALLTYPE CheckColorSpaceSupport( - /* [annotation][in] */ - [[maybe_unused]] _In_ DXGI_COLOR_SPACE_TYPE ColorSpace, - /* [annotation][out] */ - [[maybe_unused]] _Out_ UINT* pColorSpaceSupport) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE SetColorSpace1( - /* [annotation][in] */ - [[maybe_unused]] _In_ DXGI_COLOR_SPACE_TYPE ColorSpace) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE ResizeBuffers1( - /* [annotation][in] */ - [[maybe_unused]] _In_ UINT BufferCount, - /* [annotation][in] */ - [[maybe_unused]] _In_ UINT Width, - /* [annotation][in] */ - [[maybe_unused]] _In_ UINT Height, - /* [annotation][in] */ - [[maybe_unused]] _In_ DXGI_FORMAT Format, - /* [annotation][in] */ - [[maybe_unused]] _In_ UINT SwapChainFlags, - /* [annotation][in] */ - [[maybe_unused]] _In_reads_(BufferCount) const UINT* pCreationNodeMask, - /* [annotation][in] */ - [[maybe_unused]] _In_reads_(BufferCount) IUnknown* const* ppPresentQueue) final - { - DX12_NOT_IMPLEMENTED - return S_OK; - } - - #pragma endregion - -protected: - CCryDX12SwapChain(CCryDX12Device* pDevice, DX12::SwapChain* pSwapChain); - -private: - void AcquireBuffers(); - void ForfeitBuffers(); - - CCryDX12Device* m_Device; - - DX12::SwapChain* m_SwapChain; - AZStd::vector> m_BackBuffers; -}; - -#endif // __CCRYDX12GISWAPCHAIN__ diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpmc-bounded.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpmc-bounded.hpp deleted file mode 100644 index f051a0abd6..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpmc-bounded.hpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// This is free and unencumbered software released into the public domain. - -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. - -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// For more information, please refer to - -// Implementation of Dmitry Vyukov's MPMC algorithm -// http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue - - -#ifndef __MPMC_BOUNDED_QUEUE_INCLUDED__ -#define __MPMC_BOUNDED_QUEUE_INCLUDED__ - -#include -#include - -namespace concqueue -{ - template - class mpmc_bounded_queue_t - { - public: - - mpmc_bounded_queue_t(size_t size) - : _size(size) - , _mask(size - 1) - , _buffer(reinterpret_cast(new aligned_node_t[_size])) - , _head_seq(0) - , _tail_seq(0) - { - // make sure it's a power of 2 - assert((_size != 0) && ((_size & (~_size + 1)) == _size)); - - // populate the sequence initial values - for (size_t i = 0; i < _size; ++i) - { - _buffer[i].seq.store(i, std::memory_order_relaxed); - } - } - - ~mpmc_bounded_queue_t() - { - delete[] _buffer; - } - - bool enqueue(const T& data) - { - // _head_seq only wraps at MAX(_head_seq) instead we use a mask to convert the sequence to an array index - // this is why the ring buffer must be a size which is a power of 2. this also allows the sequence to double as a ticket/lock. - size_t head_seq = _head_seq.load(std::memory_order_relaxed); - - for (;; ) - { - node_t* node = &_buffer[head_seq & _mask]; - size_t node_seq = node->seq.load(std::memory_order_acquire); - intptr_t dif = (intptr_t)node_seq - (intptr_t)head_seq; - - // if seq and head_seq are the same then it means this slot is empty - if (dif == 0) - { - // claim our spot by moving head - // if head isn't the same as we last checked then that means someone beat us to the punch - // weak compare is faster, but can return spurious results - // which in this instance is OK, because it's in the loop - if (_head_seq.compare_exchange_weak(head_seq, head_seq + 1, std::memory_order_relaxed)) - { - // set the data - node->data = data; - // increment the sequence so that the tail knows it's accessible - node->seq.store(head_seq + 1, std::memory_order_release); - return true; - } - } - else if (dif < 0) - { - // if seq is less than head seq then it means this slot is full and therefore the buffer is full - return false; - } - else - { - // under normal circumstances this branch should never be taken - head_seq = _head_seq.load(std::memory_order_relaxed); - } - } - - // never taken - return false; - } - - bool dequeue(T& data) - { - size_t tail_seq = _tail_seq.load(std::memory_order_relaxed); - - for (;; ) - { - node_t* node = &_buffer[tail_seq & _mask]; - size_t node_seq = node->seq.load(std::memory_order_acquire); - intptr_t dif = (intptr_t)node_seq - (intptr_t)(tail_seq + 1); - - // if seq and head_seq are the same then it means this slot is empty - if (dif == 0) - { - // claim our spot by moving head - // if head isn't the same as we last checked then that means someone beat us to the punch - // weak compare is faster, but can return spurious results - // which in this instance is OK, because it's in the loop - if (_tail_seq.compare_exchange_weak(tail_seq, tail_seq + 1, std::memory_order_relaxed)) - { - // set the output - data = node->data; - // set the sequence to what the head sequence should be next time around - node->seq.store(tail_seq + _mask + 1, std::memory_order_release); - return true; - } - } - else if (dif < 0) - { - // if seq is less than head seq then it means this slot is full and therefore the buffer is full - return false; - } - else - { - // under normal circumstances this branch should never be taken - tail_seq = _tail_seq.load(std::memory_order_relaxed); - } - } - - // never taken - return false; - } - - private: - - struct node_t - { - T data; - std::atomic seq; - }; - - typedef typename std::aligned_storage::value>::type aligned_node_t; - typedef char cache_line_pad_t[64]; // it's either 32 or 64 so 64 is good enough - - cache_line_pad_t _pad0; - const size_t _size; - const size_t _mask; - node_t* const _buffer; - cache_line_pad_t _pad1; - std::atomic _head_seq; - cache_line_pad_t _pad2; - std::atomic _tail_seq; - cache_line_pad_t _pad3; - - mpmc_bounded_queue_t(const mpmc_bounded_queue_t&) {} - void operator=(const mpmc_bounded_queue_t&) {} - }; -} - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpsc.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpsc.hpp deleted file mode 100644 index d36700440a..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-mpsc.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// This is free and unencumbered software released into the public domain. - -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. - -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// For more information, please refer to - -// C++ implementation of Dmitry Vyukov's non-intrusive lock free unbound MPSC queue -// http://www.1024cores.net/home/lock-free-algorithms/queues/non-intrusive-mpsc-node-based-queue - -#ifndef __MPSC_BOUNDED_QUEUE_INCLUDED__ -#define __MPSC_BOUNDED_QUEUE_INCLUDED__ - -#include -#include - -namespace concqueue -{ - template - class mpsc_queue_t - { - public: - - mpsc_queue_t() - : _head(reinterpret_cast(new buffer_node_aligned_t)) - , _tail(_head.load(std::memory_order_relaxed)) - { - buffer_node_t* front = _head.load(std::memory_order_relaxed); - front->next.store(NULL, std::memory_order_relaxed); - } - - ~mpsc_queue_t() - { - T output; - while (this->dequeue(output)) - { - } - buffer_node_t* front = _head.load(std::memory_order_relaxed); - delete front; - } - - bool enqueue(const T& input) - { - buffer_node_t* node = reinterpret_cast(new buffer_node_aligned_t); - node->data = input; - node->next.store(NULL, std::memory_order_relaxed); - - buffer_node_t* prev_head = _head.exchange(node, std::memory_order_acq_rel); - prev_head->next.store(node, std::memory_order_release); - return true; - } - - bool dequeue(T& output) - { - buffer_node_t* tail = _tail.load(std::memory_order_relaxed); - buffer_node_t* next = tail->next.load(std::memory_order_acquire); - - if (next == NULL) - { - return false; - } - - output = next->data; - _tail.store(next, std::memory_order_release); - delete tail; - return true; - } - - - private: - - struct buffer_node_t - { - T data; - std::atomic next; - }; - - typedef typename std::aligned_storage::value>::type buffer_node_aligned_t; - - std::atomic _head; - std::atomic _tail; - - mpsc_queue_t(const mpsc_queue_t&) {} - void operator=(const mpsc_queue_t&) {} - }; -} - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc-bounded.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc-bounded.hpp deleted file mode 100644 index 77ac6ad0c5..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc-bounded.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// This is free and unencumbered software released into the public domain. - -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. - -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// For more information, please refer to - -// Note: -// A combination of the algorithms described by the circular buffers -// documentation found in the Linux kernel, and the bounded MPMC queue -// by Dmitry Vyukov[1]. Implemented in pure C++11. Should work across -// most CPU architectures. -// -// [1] http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue - -#ifndef __SPSC_BOUNDED_QUEUE_INCLUDED__ -#define __SPSC_BOUNDED_QUEUE_INCLUDED__ - -#include -#include - -namespace concqueue -{ - template - class spsc_bounded_queue_t - { - public: - - spsc_bounded_queue_t(size_t size) - : _size(size) - , _mask(size - 1) - , _buffer(reinterpret_cast(new aligned_t[_size + 1])) // need one extra element for a guard - , _head(0) - , _tail(0) - { - // make sure it's a power of 2 - assert((_size != 0) && ((_size & (~_size + 1)) == _size)); - } - - ~spsc_bounded_queue_t() - { - delete[] _buffer; - } - - bool enqueue(T& input) - { - const size_t head = _head.load(std::memory_order_relaxed); - - if (((_tail.load(std::memory_order_acquire) - (head + 1)) & _mask) >= 1) - { - _buffer[head & _mask] = input; - _head.store(head + 1, std::memory_order_release); - return true; - } - return false; - } - - bool dequeue(T& output) - { - const size_t tail = _tail.load(std::memory_order_relaxed); - - if (((_head.load(std::memory_order_acquire) - tail) & _mask) >= 1) - { - output = _buffer[_tail & _mask]; - _tail.store(tail + 1, std::memory_order_release); - return true; - } - return false; - } - - - private: - - typedef typename std::aligned_storage::value>::type aligned_t; - typedef char cache_line_pad_t[64]; - - cache_line_pad_t _pad0; - const size_t _size; - const size_t _mask; - T* const _buffer; - - cache_line_pad_t _pad1; - std::atomic _head; - - cache_line_pad_t _pad2; - std::atomic _tail; - - spsc_bounded_queue_t(const spsc_bounded_queue_t&) {} - void operator=(const spsc_bounded_queue_t&) {} - }; -} - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc.hpp deleted file mode 100644 index 880b53f084..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue-spsc.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// This is free and unencumbered software released into the public domain. - -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. - -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// For more information, please refer to - - -// non-intrusive lock free unbounded SPSC queue -// the algorithm was taken from the blog post below, and converted to C++11 -// http://cbloomrants.blogspot.com/2009/02/02-26-09-low-level-threading-part-51.html - -#ifndef __SPSC_QUEUE_INCLUDED__ -#define __SPSC_QUEUE_INCLUDED__ - -#include - -namespace concqueue -{ - template - class spsc_queue_t - { - public: - - spsc_queue_t() - : _head(reinterpret_cast(new node_aligned_t)) - , _tail(_head) - { - _head->next = NULL; - } - - ~spsc_queue_t() - { - T output; - while (this->dequeue(output)) - { - } - delete _head; - } - - bool enqueue(const T& input) - { - node_t* node = reinterpret_cast(new node_aligned_t); - node->data = input; - node->next = NULL; - - std::atomic_thread_fence(std::memory_order_acq_rel); - _head->next = node; - _head = node; - return true; - } - - bool dequeue(T& output) - { - std::atomic_thread_fence(std::memory_order_consume); - if (!_tail->next) - { - return false; - } - - output = _tail->next->data; - std::atomic_thread_fence(std::memory_order_acq_rel); - _back = _tail; - _tail = _back->next; - - delete _back; - return true; - } - - - private: - - struct node_t - { - node_t* next; - T data; - }; - - typedef typename std::aligned_storage::value>::type node_aligned_t; - - node_t* _head; - char _cache_line[64]; - node_t* _tail; - node_t* _back; - - spsc_queue_t(const spsc_queue_t&) {} - void operator=(const spsc_queue_t&) {} - }; -} - -#endif diff --git a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue.hpp b/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue.hpp deleted file mode 100644 index be39e36bd9..0000000000 --- a/Code/CryEngine/RenderDll/XRenderD3D9/DX12/Includes/concqueue.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or -* a third party where indicated. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef __CONC_QUEUE_INCLUDED__ -#define __CONC_QUEUE_INCLUDED__ - -#include "concqueue-mpmc-bounded.hpp" -#include "concqueue-mpsc.hpp" -#include "concqueue-spsc.hpp" -#include "concqueue-spsc-bounded.hpp" - -#define BoundMPMC concqueue::mpmc_bounded_queue_t -#define BoundSPSC concqueue::spsc_bounded_queue_t -#define UnboundMPSC concqueue::mpsc_queue_t -#define UnboundSPSC concqueue::spsc_queue_t - -template